mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-28 16:02:47 +00:00
fix: hold the session read-only while it moves into a fork
An edit in the session's preview during a move saves a draft in the workspace being left, after the move listed what it brings, at any of its awaits. The session now reads as read-only for the whole move, so the preview shows its items without an editor until the move ends. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
cdd6fb2ca7
commit
6912a9546c
@@ -785,6 +785,9 @@ export class AIChatManager implements ChatViewHost {
|
||||
/** Use, Plan or Build. A session keeps its own: the runtime seeds it from the session record
|
||||
* and stores each change through `onWorkModeChanged`. */
|
||||
workMode = $state<AIWorkMode>(AIWorkMode.BUILD)
|
||||
/** The session is moving into a fork. Its editors stay closed meanwhile: an edit would save a
|
||||
* draft in the workspace being left, after the move listed what it brings along. */
|
||||
moving = $state(false)
|
||||
onWorkModeChanged: ((mode: AIWorkMode) => void) | undefined = undefined
|
||||
workModesAvailable = $derived(this.isSessionChat && supportsPlanMode(this.mode))
|
||||
/** Use is the only mode: the workspace is protected, or the user's role builds nothing in it. */
|
||||
|
||||
@@ -541,6 +541,7 @@
|
||||
return
|
||||
}
|
||||
moving = true
|
||||
if (runtime) runtime.manager.moving = true
|
||||
const releaseAutoResume = runtime?.manager.holdAutoResume()
|
||||
// Bracketed like a turn, so another tab on this session cannot send while its drafts
|
||||
// move, then re-reads the session (its new workspace, the model note) once it ends.
|
||||
@@ -614,6 +615,7 @@
|
||||
sendUserToast(`Session moved to ${req.targetName}`)
|
||||
} finally {
|
||||
moving = false
|
||||
if (runtime) runtime.manager.moving = false
|
||||
releaseAutoResume?.()
|
||||
if (chatId)
|
||||
localRunEnded(session.id, runtime?.manager.historyManager.getCurrentChatId() ?? chatId)
|
||||
|
||||
@@ -42,7 +42,7 @@ export function useSessionReadOnly(workspace: () => string | undefined) {
|
||||
}
|
||||
|
||||
/** The session chat whose work mode the session UI follows. */
|
||||
type WorkModeHost = { readonly workMode: AIWorkMode }
|
||||
type WorkModeHost = { readonly workMode: AIWorkMode; readonly moving?: boolean }
|
||||
|
||||
/**
|
||||
* What the session UI may offer in `workspace`. Its editors save drafts, so it reads
|
||||
@@ -51,7 +51,7 @@ type WorkModeHost = { readonly workMode: AIWorkMode }
|
||||
* resolves: hiding every editor from a developer while `whoami` is in flight is the worse
|
||||
* mistake, and the server refuses an operator anyway. A session held in Use opens no editor: one
|
||||
* in a protected workspace, one whose role builds nothing there, or one whose chat is in Use
|
||||
* mode — the chat `chat` returns, else the `aiChatManager` context's.
|
||||
* mode — the chat `chat` returns, else the `aiChatManager` context's — and one moving into a fork.
|
||||
* Reads context and registers an effect: call during component initialisation.
|
||||
*/
|
||||
export function useSessionPermissions(
|
||||
@@ -62,10 +62,12 @@ export function useSessionPermissions(
|
||||
const rights = useEditRights(workspace)
|
||||
const user = useActingUser(workspace)
|
||||
const protectedWorkspace = useSessionReadOnly(workspace)
|
||||
const host = $derived(chat?.() ?? contextChat)
|
||||
const readOnly = $derived(
|
||||
protectedWorkspace.current ||
|
||||
!buildsAnything(rights.capabilities) ||
|
||||
(chat?.() ?? contextChat)?.workMode === AIWorkMode.USE
|
||||
host?.workMode === AIWorkMode.USE ||
|
||||
!!host?.moving
|
||||
)
|
||||
const workspaces = fromStore(userWorkspaces)
|
||||
const entry = $derived(workspaces.current.find((w) => w.id === workspace()))
|
||||
|
||||
Reference in New Issue
Block a user