fix(frontend): runs-table actions target the job's workspace

The "Show run details", "Go to script page" and "Go to flow page" dropdown
actions in RunsTable, plus the "Path" link in the job detail field config,
navigated with no workspace (or via flowPathToHref, which uses the active
workspace). In the cross-workspace runs view that sent the user to the wrong
workspace / a not-found screen.

Resolve the selected job once and target job.workspace_id (fallback
$workspaceStore) for all three actions; in JobDetailFieldConfig use the
passed workspaceId for non-hub scripts/flows while leaving hub links
(workspace-independent) untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Diego Imbert
2026-06-01 20:54:24 +02:00
parent 73d7e1d922
commit 7fd2c29996
2 changed files with 20 additions and 9 deletions
@@ -287,10 +287,17 @@ export const fieldConfigs: Record<JobField, FieldConfig> = {
field: 'script_path',
label: 'Path',
getValue: (job) => job.script_path || null,
getHref: (job, _workspaceId) => {
getHref: (job, workspaceId) => {
if (!job.script_path) return null
const isScript = job.job_kind === 'script'
return isScript ? `/scripts/get/${job.script_hash}` : flowPathToHref(job.script_path)
// Hub scripts/flows live outside any workspace; everything else must
// target the job's workspace (passed in as workspaceId), not the active.
if (job.script_path.startsWith('hub/')) {
return isScript ? `/scripts/get/${job.script_hash}` : flowPathToHref(job.script_path)
}
return isScript
? `/scripts/get/${job.script_hash}?workspace=${workspaceId}`
: `/flows/get/${job.script_path}?workspace=${workspaceId}`
}
},
@@ -259,27 +259,31 @@
let cancellable = selectedIdsPossibleActions.cancellableJobIds.length
const actions: DropdownMenuProps['items'] = []
if (selectedIds.length === 1) {
actions.push({
label: 'Show run details',
icon: ExternalLinkIcon,
onClick: () => goto(`/run/${selectedIds[0]}`)
})
const job = flatJobs?.find(
(jobOrDate) => jobOrDate.type === 'job' && jobOrDate.job.id === selectedIds[0]
)
// Jobs in the runs table can belong to a workspace other than the active
// one, so target the job's own workspace (not the active one).
const jobWorkspace =
(job?.type === 'job' ? job.job.workspace_id : undefined) ?? $workspaceStore
actions.push({
label: 'Show run details',
icon: ExternalLinkIcon,
onClick: () => goto(`/run/${selectedIds[0]}?workspace=${jobWorkspace}`)
})
if (job?.type === 'job') {
if (job.job.job_kind === 'script') {
actions.push({
label: 'Go to script page',
icon: Code2Icon,
onClick: () => goto(`/scripts/get/${job.job.script_hash}`)
onClick: () => goto(`/scripts/get/${job.job.script_hash}?workspace=${jobWorkspace}`)
})
}
if (job.job.job_kind === 'flow') {
actions.push({
label: 'Go to flow page',
icon: BarsStaggered,
onClick: () => goto(`/flows/get/${job.job.script_path}`)
onClick: () => goto(`/flows/get/${job.job.script_path}?workspace=${jobWorkspace}`)
})
}
}