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:
@@ -50,7 +50,10 @@
|
|||||||
|
|
||||||
// Invite (create) modal --------------------------------------------------
|
// Invite (create) modal --------------------------------------------------
|
||||||
let inviteOpen = $state(false);
|
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: '',
|
username: '',
|
||||||
email: '',
|
email: '',
|
||||||
instance_role: 'admin'
|
instance_role: 'admin'
|
||||||
@@ -449,6 +452,12 @@
|
|||||||
</label>
|
</label>
|
||||||
<fieldset class="field">
|
<fieldset class="field">
|
||||||
<legend>Role</legend>
|
<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">
|
<label class="radio">
|
||||||
<input type="radio" bind:group={inviteForm.instance_role} value="admin" />
|
<input type="radio" bind:group={inviteForm.instance_role} value="admin" />
|
||||||
<span>Admin — can manage users, scripts, and all apps.</span>
|
<span>Admin — can manage users, scripts, and all apps.</span>
|
||||||
@@ -457,9 +466,9 @@
|
|||||||
<input type="radio" bind:group={inviteForm.instance_role} value="member" />
|
<input type="radio" bind:group={inviteForm.instance_role} value="member" />
|
||||||
<span>Member — only sees apps they're added to.</span>
|
<span>Member — only sees apps they're added to.</span>
|
||||||
</label>
|
</label>
|
||||||
<small>
|
{#if me?.instance_role !== 'owner'}
|
||||||
Owners can't be created here — promote via Edit after creation.
|
<small>Owners can't be created here — promote via Edit after creation.</small>
|
||||||
</small>
|
{/if}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{#if inviteError}
|
{#if inviteError}
|
||||||
<div class="error">{inviteError}</div>
|
<div class="error">{inviteError}</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user