Files
mcias/web/templates/fragments/pgcreds_form.html
Kyle Isom b2f2f04646 UI: pgcreds create button; show logged-in user
* web/templates/pgcreds.html: New Credentials card is now always
  rendered; Add Credentials toggle button reveals the create form
  (hidden by default). Shows a message when all system accounts
  already have credentials. Previously the card was hidden when
  UncredentialedAccounts was empty.
* internal/ui/ui.go: added ActorName string field to PageData;
  added actorName(r) helper resolving username from JWT claims
  via DB lookup, returns empty string if unauthenticated.
* internal/ui/handlers_*.go: all full-page PageData constructors
  now pass ActorName: u.actorName(r).
* web/templates/base.html: nav bar renders actor username as a
  muted label before the Logout button when logged in.
* web/static/style.css: added .nav-actor rule (muted grey, 0.85rem).
2026-03-12 11:38:57 -07:00

95 lines
4.2 KiB
HTML

{{define "pgcreds_form"}}
<div id="pgcreds-section">
{{if .PGCred}}
<dl style="display:grid;grid-template-columns:140px 1fr;gap:.5rem .75rem;font-size:.9rem;margin-bottom:1rem">
<dt class="text-muted">Host</dt><dd>{{.PGCred.PGHost}}:{{.PGCred.PGPort}}</dd>
<dt class="text-muted">Database</dt><dd>{{.PGCred.PGDatabase}}</dd>
<dt class="text-muted">Username</dt><dd>{{.PGCred.PGUsername}}</dd>
<dt class="text-muted">Password</dt><dd><em class="text-muted">stored (not shown)</em></dd>
<dt class="text-muted">Updated</dt><dd class="text-small">{{formatTime .PGCred.UpdatedAt}}</dd>
</dl>
{{else}}
<p class="text-muted text-small" style="margin-bottom:1rem">No credentials stored.</p>
{{end}}
{{/* Any admin can add or update credentials; creator of the first set becomes owner */}}
<details style="margin-bottom:1rem">
<summary class="text-small" style="cursor:pointer;color:var(--color-text-muted)">
{{if .PGCred}}Update credentials{{else}}Add new credentials{{end}}
</summary>
<form hx-put="/accounts/{{.Account.UUID}}/pgcreds"
hx-target="#pgcreds-section" hx-swap="outerHTML"
style="margin-top:.75rem">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:.5rem;margin-bottom:.5rem">
<input class="form-control" type="text" name="host" placeholder="Host" required
{{if .PGCred}}value="{{.PGCred.PGHost}}"{{end}}>
<input class="form-control" type="number" name="port" placeholder="Port (5432)"
min="1" max="65535"
{{if .PGCred}}value="{{.PGCred.PGPort}}"{{end}}>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:.5rem;margin-bottom:.5rem">
<input class="form-control" type="text" name="database" placeholder="Database" required
{{if .PGCred}}value="{{.PGCred.PGDatabase}}"{{end}}>
<input class="form-control" type="text" name="username" placeholder="Username" required
{{if .PGCred}}value="{{.PGCred.PGUsername}}"{{end}}>
</div>
<input class="form-control" type="password" name="password"
placeholder="Password (required)" required
style="margin-bottom:.5rem">
<button class="btn btn-sm btn-secondary" type="submit">Save Credentials</button>
</form>
</details>
{{/* Access grants section — shown whenever credentials exist */}}
{{if .PGCred}}
<div style="margin-top:1.25rem">
<h3 style="font-size:.9rem;font-weight:600;margin-bottom:.5rem">Access Grants</h3>
{{if .PGCredGrants}}
<table class="table table-sm" style="font-size:.85rem">
<thead>
<tr>
<th>User</th>
<th>Granted</th>
{{if isPGCredOwner $.ActorID $.PGCred}}<th></th>{{end}}
</tr>
</thead>
<tbody>
{{range .PGCredGrants}}
<tr>
<td>{{.GranteeName}}</td>
<td class="text-small text-muted">{{formatTime .GrantedAt}}</td>
{{if isPGCredOwner $.ActorID $.PGCred}}
<td>
<button class="btn btn-sm btn-danger"
hx-delete="/accounts/{{$.Account.UUID}}/pgcreds/access/{{.GranteeUUID}}"
hx-target="#pgcreds-section" hx-swap="outerHTML"
hx-confirm="Revoke access for {{.GranteeName}}?">Revoke</button>
</td>
{{end}}
</tr>
{{end}}
</tbody>
</table>
{{else}}
<p class="text-muted text-small">No access grants.</p>
{{end}}
{{/* Grant form — owner only */}}
{{if and (isPGCredOwner .ActorID .PGCred) .GrantableAccounts}}
<form hx-post="/accounts/{{.Account.UUID}}/pgcreds/access"
hx-target="#pgcreds-section" hx-swap="outerHTML"
style="margin-top:.75rem;display:flex;gap:.5rem;align-items:center">
<select class="form-control" name="grantee_uuid" required style="flex:1">
<option value="">— select account to grant —</option>
{{range .GrantableAccounts}}
<option value="{{.UUID}}">{{.Username}} ({{.AccountType}})</option>
{{end}}
</select>
<button class="btn btn-sm btn-secondary" type="submit">Grant Access</button>
</form>
{{end}}
</div>
{{end}}
</div>
{{end}}