| 1 | {{/* agents — GET /agents, the tokens that let a program drive this |
| 2 | person's decks. |
| 3 | |
| 4 | The share page's screen, for the share page's reason: a credential |
| 5 | that is shown once has to be shown well. Four things in the order |
| 6 | they matter — the token that was just minted, what a token can do, |
| 7 | the agents that already exist with the one button that turns each |
| 8 | of them off, and the form that makes another. |
| 9 | |
| 10 | The new token is a callout plus a read-only field rather than a |
| 11 | line of prose, because the whole job of this screen at that moment |
| 12 | is "select this and copy it", and a field is what a browser lets |
| 13 | you select cleanly with no script at all. */}} |
| 14 | {{define "content"}} |
| 15 | {{template "page-header" dict "Title" .Title}} |
| 16 | |
| 17 | {{if .NewToken}} |
| 18 | <div rst-box> |
| 19 | {{template "callout" dict "Tone" "warning" "Title" .NewTitle "Body" .NewHint}} |
| 20 | {{/* Hand-written rather than {{template "field-text"}} for one |
| 21 | attribute: readonly, which that partial's contract does not |
| 22 | carry. The markup is field-text's own, attribute for attribute, |
| 23 | so the control still looks and reads like every other field on |
| 24 | every other screen — share.html says the same thing, and the day |
| 25 | readonly joins the partial both become one-line calls again. */}} |
| 26 | <div rst-field> |
| 27 | <label rst-field-label for="agent-token">{{.NewLabel}}</label> |
| 28 | <input rst-input id="agent-token" name="agent-token" type="text" value="{{.NewToken}}" |
| 29 | readonly aria-describedby="agent-token-hint"> |
| 30 | <small rst-field-hint id="agent-token-hint">{{.CopyHint}}</small> |
| 31 | </div> |
| 32 | {{if .NewPrincipal}}<p><strong>{{.NewPrincipal}}</strong></p>{{end}} |
| 33 | <p class="rst-mono">{{.NewUse}}</p> |
| 34 | </div> |
| 35 | {{end}} |
| 36 | |
| 37 | <div rst-box> |
| 38 | <p>{{.Lead}}</p> |
| 39 | </div> |
| 40 | |
| 41 | {{template "callout" dict "Tone" "warning" "Title" .WarningTitle "Body" .Warning}} |
| 42 | |
| 43 | {{if .Agents}} |
| 44 | <div rst-list> |
| 45 | {{range .Agents}} |
| 46 | <div rst-row> |
| 47 | <span rst-row-main> |
| 48 | {{.Principal}} |
| 49 | <small rst-row-sub>{{.Created}}</small> |
| 50 | </span> |
| 51 | {{template "status-pill" dict "Tone" .StatusTone "Label" .StatusLabel}} |
| 52 | {{if not .Revoked}} |
| 53 | {{/* aria-label, because "Revoke" repeated down a list does not say |
| 54 | which agent it revokes — list-row-action's ActionAria rule, |
| 55 | applied to a hand-written row. */}} |
| 56 | <form method="post" action="{{.RevokeHref}}"> |
| 57 | <button rst-btn="ghost" class="rst-danger" type="submit" |
| 58 | aria-label="{{.RevokeAria}}">{{.RevokeLabel}}</button> |
| 59 | </form> |
| 60 | {{end}} |
| 61 | </div> |
| 62 | {{end}} |
| 63 | </div> |
| 64 | {{else}} |
| 65 | <div rst-box> |
| 66 | {{template "empty-state" dict "Title" .EmptyTitle "Body" .EmptyBody}} |
| 67 | </div> |
| 68 | {{end}} |
| 69 | |
| 70 | <div rst-box> |
| 71 | <form method="post" action="{{.Action}}" rst-form> |
| 72 | {{template "field-text" dict |
| 73 | "Name" "name" "Label" .NameLabel "Hint" .NameHint |
| 74 | "Value" .NameValue "Required" true |
| 75 | "Error" (index .Errors "Name")}} |
| 76 | {{template "form-foot" dict "Submit" .CreateLabel}} |
| 77 | </form> |
| 78 | </div> |
| 79 | {{end}} |
| 80 | |