fix: guests stop at the launched-by-me job grant; canonical app paths at the mint and discovery; the toggle ends on the stored value

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BayTppRCstWX6qTf3LMco5
This commit is contained in:
Ruben Fiszel
2026-09-04 09:07:39 +02:00
co-authored by Claude Fable 5.1
parent fbcb0728f7
commit 2b4631cedc
7 changed files with 82 additions and 26 deletions
@@ -112,7 +112,7 @@
let guestLoading = $state(false)
const guestPerPage = 50
async function loadGuestPage(nextPage: number) {
async function loadGuestPage(nextPage: number): Promise<boolean> {
guestLoading = true
try {
const res = await UserService.listGuests({ page: nextPage, perPage: guestPerPage })
@@ -121,8 +121,10 @@
? res
: { usage: res.usage, guests: [...guestList.guests, ...res.guests] }
guestHasMore = res.guests.length === guestPerPage
return true
} catch (e) {
sendUserToast(`Failed to load guests: ${e}`, true)
return false
} finally {
guestLoading = false
}
@@ -14,24 +14,30 @@
hasMore: boolean
loading: boolean
onLoadMore: () => void
/** The instance switch was written; the caller re-reads usage and resolves once
* the toggle may show the stored value again. */
onInstanceSwitch: () => Promise<void>
/** The instance switch was written; the caller re-reads usage and says whether
* that read succeeded, so the toggle can show what is actually stored. */
onInstanceSwitch: () => Promise<boolean>
}
let { usage, guests, hasMore, loading, onLoadMore, onInstanceSwitch }: Props = $props()
const loadMoreSize = 50
// One write at a time, and the toggle shows the stored value again after either
// outcome: a refused write must not leave it showing the click.
// One write at a time, and the toggle always ends on what is stored: the reloaded
// value when the reload succeeds, else the write's outcome.
let switchPending = $state(false)
let switchOn = $state(usage.instance_enabled)
$effect(() => {
switchOn = usage.instance_enabled
})
async function setInstanceSwitch(enabled: boolean) {
switchPending = true
let written = false
try {
await SettingService.setGlobal({
key: 'guest_access_disabled',
requestBody: { value: !enabled }
})
written = true
sendUserToast(
enabled
? 'Guests can sign in again where a workspace allows them'
@@ -40,7 +46,10 @@
} catch (e) {
sendUserToast(`Could not change the instance guest switch: ${e}`, true)
}
await onInstanceSwitch()
const reloaded = await onInstanceSwitch()
if (!reloaded) {
switchOn = written ? enabled : usage.instance_enabled
}
switchPending = false
}
// A capped instance refuses the next stranger as soon as the allowance is used up.
@@ -59,7 +68,7 @@
<div class="flex flex-row gap-2 items-center mb-4">
{#key usage}
<Toggle
checked={usage.instance_enabled}
bind:checked={switchOn}
disabled={switchPending}
on:change={(e) => setInstanceSwitch(e.detail)}
options={{