mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-11 00:06:06 +00:00
fix(frontend): scope raw-app, flow and script editors to the session workspace (#10015)
* fix(frontend): scope raw-app/flow/script editors to the session workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): scope flow and script editor operations to the session workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): scope flow preview, inline-script creation and datatable schema to the session workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review — thread session workspace through flow resource pickers, script fetch, preview cancel/recording and path collision check Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Claude review — pass session workspace to preview FlowStatusViewer and align FlowChatManager guards Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Pi review — show acting workspace in script-not-found message and fetch picked script from it in EditorBar Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 2 — thread session workspace into flow step test, raw-app inline runnable, inline editor toolbars and MCP OAuth path Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 3 — thread session workspace into dynamic-input helpers and the flow-preview argument side panel (history/saved-inputs/captures) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 4 — thread session workspace into nested flow/script drawers, flow chat inputs and the flow input side tabs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 5 — thread session workspace into script-module fork/reload and key the raw-app schema cache by workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 6 — key the DB manager schema cache by acting workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): address Codex review round 7 — thread session workspace into resource-valued arg pickers and the editor variable/resource helper drawers Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(frontend): scope the flow asset explorer's ResourceEditorDrawer to the acting workspace Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: thread acting workspace through flow asset explore controls Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: thread acting workspace through SQL REPL, secret args, helper forms, S3 inputs, saved inputs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9ad6927231
commit
c000bbca28
@@ -223,6 +223,11 @@
|
||||
// built by the pipeline page from the resolved graph. Absent outside the
|
||||
// pipeline editor — the check still runs, just without suppression.
|
||||
schemaContractContext?: SchemaContractGraphContext
|
||||
// Workspace to scope this editor's calls to. Defaults to the nav
|
||||
// `$workspaceStore`; an AI-session live editor passes the session's
|
||||
// acting workspace (a fork) so tests, captures and toolbar lookups hit
|
||||
// the right workspace instead of the nav one.
|
||||
workspaceOverride?: string
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -266,9 +271,12 @@
|
||||
onTestJob,
|
||||
initialTestPanelCollapsed = false,
|
||||
sessionOpen = undefined,
|
||||
schemaContractContext = undefined
|
||||
schemaContractContext = undefined,
|
||||
workspaceOverride = undefined
|
||||
}: Props = $props()
|
||||
|
||||
let opWs = $derived(workspaceOverride ?? $workspaceStore)
|
||||
|
||||
$effect(() => {
|
||||
onTestStateChange?.(testIsLoading)
|
||||
})
|
||||
@@ -596,7 +604,7 @@
|
||||
let inferAssetsRes = resource([() => lang, () => code, () => code], () => inferAssets(lang, code))
|
||||
let preparedSqlQueries = usePreparedAssetSqlQueries(
|
||||
() => inferAssetsRes.current?.sql_queries,
|
||||
() => $workspaceStore
|
||||
() => opWs
|
||||
)
|
||||
// Asset-parse validity for the editor badge. `undefined` while loading (so
|
||||
// the badge doesn't flicker red); only an explicit parser error counts as
|
||||
@@ -648,7 +656,7 @@
|
||||
let contractCheckSeq = 0
|
||||
watch([() => inferAssetsRes.current, () => schemaContractContext], () => {
|
||||
const res = inferAssetsRes.current
|
||||
const workspace = $workspaceStore
|
||||
const workspace = opWs
|
||||
const seq = ++contractCheckSeq
|
||||
if (!workspace || !res || res.status === 'error') {
|
||||
contractMarkers = []
|
||||
@@ -837,7 +845,7 @@
|
||||
? { _ENTRYPOINT_OVERRIDE: 'preprocessor', ...(args ?? {}) }
|
||||
: (args ?? {})
|
||||
const testSchema = activeModuleTab !== null ? testPanelSchema : schema
|
||||
const testArgs = await processSecretArgs(rawTestArgs, testSchema)
|
||||
const testArgs = await processSecretArgs(rawTestArgs, testSchema, opWs)
|
||||
if (showPsCommonParams) {
|
||||
for (const [k, v] of Object.entries(psCommonParams)) {
|
||||
if (v !== undefined && v !== false && v !== '') {
|
||||
@@ -908,7 +916,7 @@
|
||||
async function loadPastTests(): Promise<void> {
|
||||
pastPreviewsRequest?.cancel()
|
||||
const req = JobService.listCompletedJobs({
|
||||
workspace: $workspaceStore!,
|
||||
workspace: opWs!,
|
||||
jobKinds: 'preview',
|
||||
createdBy: $userStore?.username,
|
||||
scriptPathExact: path,
|
||||
@@ -1210,12 +1218,12 @@
|
||||
dapClient = getDAPClient(dapServerUrl)
|
||||
|
||||
// Fetch contextual variables (WM_WORKSPACE, WM_TOKEN, etc.) from backend
|
||||
const env = await fetchContextualVariables($workspaceStore ?? '')
|
||||
const env = await fetchContextualVariables(opWs ?? '')
|
||||
|
||||
// Sign the debug request (creates audit log entry)
|
||||
let signedPayload
|
||||
try {
|
||||
signedPayload = await signDebugRequest($workspaceStore ?? '', code ?? '', lang ?? 'python3')
|
||||
signedPayload = await signDebugRequest(opWs ?? '', code ?? '', lang ?? 'python3')
|
||||
debugSessionJobId = signedPayload.job_id
|
||||
} catch (signError) {
|
||||
sendUserToast(getDebugErrorMessage(signError), true)
|
||||
@@ -1435,11 +1443,11 @@
|
||||
// what's there" affordance, not a user action. Skipped when a test is
|
||||
// already running so a live job's stream is never clobbered.
|
||||
async function loadLastRunIntoTestPanel(): Promise<void> {
|
||||
if (!path || !$workspaceStore) return
|
||||
if (!path || !opWs) return
|
||||
if (testIsLoading || testJob !== undefined) return
|
||||
try {
|
||||
const jobs = await JobService.listCompletedJobs({
|
||||
workspace: $workspaceStore,
|
||||
workspace: opWs,
|
||||
scriptPathExact: path,
|
||||
hasNullParent: true,
|
||||
perPage: 1,
|
||||
@@ -1471,7 +1479,7 @@
|
||||
|
||||
let token: string | undefined
|
||||
try {
|
||||
token = await signMultiplayerRequest($workspaceStore ?? '')
|
||||
token = await signMultiplayerRequest(opWs ?? '')
|
||||
} catch (e) {
|
||||
console.error('Failed to sign multiplayer request:', e)
|
||||
sendUserToast('Failed to authorize multiplayer session', true)
|
||||
@@ -1486,7 +1494,7 @@
|
||||
|
||||
wsProvider = new WebsocketProvider(
|
||||
buildWsUrl('/ws_mp/'),
|
||||
$workspaceStore + '/' + (path ?? 'no-room-name'),
|
||||
opWs + '/' + (path ?? 'no-room-name'),
|
||||
ydoc,
|
||||
{ connect: false, params: { token } }
|
||||
)
|
||||
@@ -1554,7 +1562,7 @@
|
||||
let url = new URL(window.location.toString().split('#')[0])
|
||||
url.search = ''
|
||||
return (
|
||||
`${url}?collab=1&workspace=${encodeURIComponent($workspaceStore ?? '')}&lang=${encodeURIComponent(lang ?? '')}` +
|
||||
`${url}?collab=1&workspace=${encodeURIComponent(opWs ?? '')}&lang=${encodeURIComponent(lang ?? '')}` +
|
||||
(edit ? '' : `&path=${path}`)
|
||||
)
|
||||
}
|
||||
@@ -1725,6 +1733,7 @@
|
||||
|
||||
<JobLoader
|
||||
noCode={true}
|
||||
workspaceOverride={opWs}
|
||||
bind:scriptProgress
|
||||
bind:this={jobLoader}
|
||||
bind:isLoading={testIsLoading}
|
||||
@@ -1760,6 +1769,7 @@
|
||||
<div class="flex justify-between space-x-2">
|
||||
{#if args}
|
||||
<EditorBar
|
||||
workspace={opWs}
|
||||
scriptPath={edit ? path : undefined}
|
||||
on:toggleCollabMode={() => {
|
||||
if (wsProvider?.shouldConnect) {
|
||||
@@ -1978,7 +1988,7 @@
|
||||
it visually pinned to the top edge without
|
||||
relying on cross-browser overflow behaviour. -->
|
||||
<div class="relative h-full pt-9 flex flex-col">
|
||||
{#if testJob?.id && testJob.type === 'CompletedJob' && $workspaceStore}
|
||||
{#if testJob?.id && testJob.type === 'CompletedJob' && opWs}
|
||||
<!-- Right-side affordances when we're displaying a *completed*
|
||||
job (either the user just ran a test, or the on-mount
|
||||
last-run loader populated the panel). The job-id link
|
||||
@@ -1989,7 +1999,7 @@
|
||||
<div class="absolute top-1 right-2 z-10 flex items-center gap-2">
|
||||
<a
|
||||
class="text-3xs text-blue-600 hover:underline font-mono"
|
||||
href={`${base}/run/${testJob.id}?workspace=${$workspaceStore}`}
|
||||
href={`${base}/run/${testJob.id}?workspace=${opWs}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="Open this run"
|
||||
@@ -1997,7 +2007,7 @@
|
||||
{testJob.id.slice(0, 8)}… ↗
|
||||
</a>
|
||||
<DispatchEventsButton
|
||||
workspace={testJob.workspace_id ?? $workspaceStore}
|
||||
workspace={testJob.workspace_id ?? opWs}
|
||||
jobId={testJob.id}
|
||||
/>
|
||||
</div>
|
||||
@@ -2142,6 +2152,7 @@
|
||||
>
|
||||
{#key argsRender}
|
||||
<SchemaForm
|
||||
workspace={opWs}
|
||||
helperScript={{
|
||||
source: 'inline',
|
||||
code,
|
||||
@@ -2211,6 +2222,7 @@
|
||||
{#key argsRender}
|
||||
{#if activeModuleTab !== null}
|
||||
<SchemaForm
|
||||
workspace={opWs}
|
||||
helperScript={{
|
||||
source: 'inline',
|
||||
code: editorCode,
|
||||
@@ -2227,6 +2239,7 @@
|
||||
/>
|
||||
{:else}
|
||||
<SchemaForm
|
||||
workspace={opWs}
|
||||
helperScript={{
|
||||
source: 'inline',
|
||||
code,
|
||||
@@ -2331,6 +2344,7 @@
|
||||
<div class="h-full p-2">
|
||||
<CaptureTable
|
||||
bind:this={captureTable}
|
||||
workspace={opWs}
|
||||
{hasPreprocessor}
|
||||
canHavePreprocessor={canHavePreprocessor(lang)}
|
||||
isFlow={false}
|
||||
@@ -2649,7 +2663,7 @@
|
||||
client={dapClient}
|
||||
currentFrameId={currentDebugFrameId}
|
||||
onClose={() => (showDebugConsole = false)}
|
||||
workspace={$workspaceStore}
|
||||
workspace={opWs}
|
||||
jobId={debugSessionJobId ?? undefined}
|
||||
/>
|
||||
</Pane>
|
||||
|
||||
Reference in New Issue
Block a user