diff --git a/frontend/src/lib/components/AutosaveIndicator.svelte b/frontend/src/lib/components/AutosaveIndicator.svelte index 42608781fd..46e79382fe 100644 --- a/frontend/src/lib/components/AutosaveIndicator.svelte +++ b/frontend/src/lib/components/AutosaveIndicator.svelte @@ -1,6 +1,6 @@
+ {#if hintLabel} + + {#key hintFlashKey} + + {/key} + {/if} {#snippet trigger()} -
+
{#if syncState === 'saving' || syncState === 'pending'} {:else} - + {/if}
{/snippet} @@ -124,6 +212,21 @@ All changes are saved as a draft on the server. The draft is per-user — your teammates' editors keep their own.

+ {#if othersDraftsCount > 0} +
+

+ Other users are working on this {kindLabel}. +

+ +
+ {/if} {#if showResetAction}
- {/snippet} + {/snippet}
{#if label} - {label} + {label} {/if} -
\ No newline at end of file + + + diff --git a/frontend/src/lib/components/FlowBuilder.svelte b/frontend/src/lib/components/FlowBuilder.svelte index c3be99558c..2ea61f3c18 100644 --- a/frontend/src/lib/components/FlowBuilder.svelte +++ b/frontend/src/lib/components/FlowBuilder.svelte @@ -125,6 +125,9 @@ onHistoryRestore, onNavigate, onResetToDeployed, + loadedFromDraft = false, + othersDraftsCount = 0, + onOpenOthersDrafts, onTestJob }: FlowBuilderProps = $props() @@ -1088,6 +1091,9 @@ path={liveEditorDraftStoragePath} draftOnly={newFlow} {onResetToDeployed} + {loadedFromDraft} + {othersDraftsCount} + {onOpenOthersDrafts} /> {/if} diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index a6c891689a..e042b1fbf2 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -130,7 +130,10 @@ disableAi, initialTestPanelCollapsed = false, initialPathChosen = false, - onResetToDeployed + onResetToDeployed, + loadedFromDraft = false, + othersDraftsCount = 0, + onOpenOthersDrafts }: ScriptBuilderProps = $props() export function getInitialAndModifiedValues(): SavedAndModifiedValue { @@ -1894,6 +1897,9 @@ path={userDraftPath} draftOnly={(savedScript as any)?.no_deployed === true} {onResetToDeployed} + {loadedFromDraft} + {othersDraftsCount} + {onOpenOthersDrafts} /> {/if} diff --git a/frontend/src/lib/components/apps/editor/AppEditor.svelte b/frontend/src/lib/components/apps/editor/AppEditor.svelte index ce6ac233a2..335126f8ec 100644 --- a/frontend/src/lib/components/apps/editor/AppEditor.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditor.svelte @@ -79,7 +79,10 @@ gotoFn = (path: string, opt?: Record) => window.history.pushState(null, '', path), onSavedNewAppPath, onNavigate, - onResetToDeployed + onResetToDeployed, + loadedFromDraft = false, + othersDraftsCount = 0, + onOpenOthersDrafts }: AppEditorProps = $props() migrateApp(untrack(() => app)) @@ -883,6 +886,9 @@ {newApp} userDraftPath={appDraftPath} {onResetToDeployed} + {loadedFromDraft} + {othersDraftsCount} + {onOpenOthersDrafts} on:restore {policy} {fromHub} diff --git a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte index aaba4826a2..974446c6c5 100644 --- a/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte +++ b/frontend/src/lib/components/apps/editor/AppEditorHeader.svelte @@ -109,6 +109,11 @@ // Threaded to the `AutosaveIndicator` popover so its "Reset to // deployed" button can do the same thing the load-time toast offers. onResetToDeployed?: () => void | Promise + // See ScriptBuilderProps — same semantics for the app editor's + // indicator. + loadedFromDraft?: boolean + othersDraftsCount?: number + onOpenOthersDrafts?: () => void } let { @@ -131,7 +136,10 @@ onHideRightPanel, onHideBottomPanel, onNavigate = undefined, - onResetToDeployed + onResetToDeployed, + loadedFromDraft = false, + othersDraftsCount = 0, + onOpenOthersDrafts }: Props = $props() /** Mirror of the path the user is editing in the pen popover. Initialized @@ -950,6 +958,9 @@ path={userDraftPath} draftOnly={newApp} {onResetToDeployed} + {loadedFromDraft} + {othersDraftsCount} + {onOpenOthersDrafts} /> {/if} diff --git a/frontend/src/lib/components/apps/types.ts b/frontend/src/lib/components/apps/types.ts index 532cd5a481..8eef469472 100644 --- a/frontend/src/lib/components/apps/types.ts +++ b/frontend/src/lib/components/apps/types.ts @@ -167,6 +167,11 @@ export interface AppEditorProps { // popover so its "Reset to deployed" button can do the same thing // the load-time toast offers. onResetToDeployed?: () => void | Promise + // See ScriptBuilderProps — same semantics for the app editor's + // indicator. Threaded through AppEditorHeader. + loadedFromDraft?: boolean + othersDraftsCount?: number + onOpenOthersDrafts?: () => void } export type App = { diff --git a/frontend/src/lib/components/common/confirmationModal/DraftEditorModals.svelte b/frontend/src/lib/components/common/confirmationModal/DraftEditorModals.svelte index ed86138afc..56e3aed285 100644 --- a/frontend/src/lib/components/common/confirmationModal/DraftEditorModals.svelte +++ b/frontend/src/lib/components/common/confirmationModal/DraftEditorModals.svelte @@ -30,6 +30,10 @@ editPathFor: (forkedPath: string) => string onLoadFromServer: () => void | Promise getLocalDraft: () => unknown + /** Bindable open-flag for the OtherUsersDraftsModal. The route owns + * the state (so the AutosaveIndicator popover button can flip it on) + * and binds it here. */ + othersModalOpen: boolean /** Defaults to true; set to false to suppress both modals. */ enabled?: boolean } @@ -42,6 +46,7 @@ editPathFor, onLoadFromServer, getLocalDraft, + othersModalOpen = $bindable(), enabled = true }: Props = $props() @@ -61,6 +66,7 @@ currentUserUsername={$userStore?.username} {otherDraftsUsers} {editPathFor} + bind:isOpen={othersModalOpen} /> {/key} {/if} diff --git a/frontend/src/lib/components/common/confirmationModal/OtherUsersDraftsModal.svelte b/frontend/src/lib/components/common/confirmationModal/OtherUsersDraftsModal.svelte index 34de1723f8..369e9b6c76 100644 --- a/frontend/src/lib/components/common/confirmationModal/OtherUsersDraftsModal.svelte +++ b/frontend/src/lib/components/common/confirmationModal/OtherUsersDraftsModal.svelte @@ -1,15 +1,15 @@