fix(dashboard): F-U-018 allow owners to invite owners directly

The invite-user modal offered only admin/member radios. Owner could
only be granted by editing an existing user — asymmetric with
editRoleOptions which lets owners assign owner directly. The original
intention was preventing the first-owner footgun but the asymmetry
was confusing.

Show the Owner radio only when me?.instance_role === 'owner'. The
help text ("Owners can't be created here — promote via Edit") still
shows for non-owner admins so the friction is preserved where it
matters.

AUDIT.md anchor: F-U-018.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-07 21:06:02 +02:00
parent 73d3befb06
commit cd0cd8464c

View File

@@ -50,7 +50,10 @@
// Invite (create) modal --------------------------------------------------
let inviteOpen = $state(false);
let inviteForm = $state<{ username: string; email: string; instance_role: 'admin' | 'member' }>({
// F-U-018: Owner is selectable for the bootstrap case (owners can
// always create more owners; the asymmetry with editRoleOptions
// was unnecessary friction).
let inviteForm = $state<{ username: string; email: string; instance_role: InstanceRole }>({
username: '',
email: '',
instance_role: 'admin'
@@ -449,6 +452,12 @@
</label>
<fieldset class="field">
<legend>Role</legend>
{#if me?.instance_role === 'owner'}
<label class="radio">
<input type="radio" bind:group={inviteForm.instance_role} value="owner" />
<span>Owner — full instance control (irrevocable except by another owner).</span>
</label>
{/if}
<label class="radio">
<input type="radio" bind:group={inviteForm.instance_role} value="admin" />
<span>Admin — can manage users, scripts, and all apps.</span>
@@ -457,9 +466,9 @@
<input type="radio" bind:group={inviteForm.instance_role} value="member" />
<span>Member — only sees apps they're added to.</span>
</label>
<small>
Owners can't be created here — promote via Edit after creation.
</small>
{#if me?.instance_role !== 'owner'}
<small>Owners can't be created here — promote via Edit after creation.</small>
{/if}
</fieldset>
{#if inviteError}
<div class="error">{inviteError}</div>