Skip to content

Commit bc5bf6e

Browse files
mzxchandraclaude
andcommitted
feat(workspace): workflow location bar above the canvas in the Build view
With org-project-view on, the canvas gets a breadcrumb bar (Workflows, its folders, the workflow) whose crumbs return to the Workflows index at that folder, plus a Search resources action that opens the search modal. Replaces the sidebar tree's job of showing where the open workflow lives. Flag off: unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent d00e347 commit bc5bf6e

2 files changed

Lines changed: 62 additions & 1 deletion

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use client'
2+
3+
import { Search } from '@sim/emcn/icons'
4+
import { useParams, useRouter } from 'next/navigation'
5+
import {
6+
breadcrumbFolderChain,
7+
folderBreadcrumbItems,
8+
} from '@/app/workspace/[workspaceId]/components/folders'
9+
import { ResourceHeader } from '@/app/workspace/[workspaceId]/components/resource/components/resource-header'
10+
import { useFeatureFlag } from '@/app/workspace/[workspaceId]/providers/feature-flags-provider'
11+
import { useFolderMap } from '@/hooks/queries/folders'
12+
import { useWorkflowMap } from '@/hooks/queries/workflows'
13+
import { useSearchModalStore } from '@/stores/modals/search/store'
14+
15+
/** Keeps the open workflow identifiable when Build uses section-level navigation. */
16+
export function WorkflowLocationBar() {
17+
const enabled = useFeatureFlag('org-project-view')
18+
return enabled ? <WorkflowLocationBarContent /> : null
19+
}
20+
21+
function WorkflowLocationBarContent() {
22+
const { workspaceId, workflowId } = useParams<{ workspaceId: string; workflowId: string }>()
23+
const router = useRouter()
24+
const { data: workflows } = useWorkflowMap(workspaceId)
25+
const { data: folders } = useFolderMap(workspaceId)
26+
const openSearch = useSearchModalStore((state) => state.open)
27+
const workflow = workflows?.[workflowId]
28+
const ancestors = breadcrumbFolderChain(
29+
workflow?.folderId,
30+
new Map(Object.values(folders ?? {}).map((folder) => [folder.id, folder]))
31+
)
32+
const breadcrumbs = folderBreadcrumbItems({
33+
rootLabel: 'Workflows',
34+
breadcrumbs: ancestors,
35+
onNavigate: (folderId) => {
36+
const query = folderId ? `?folderId=${encodeURIComponent(folderId)}` : ''
37+
router.push(`/workspace/${workspaceId}/w${query}`)
38+
},
39+
trailing: [{ label: workflow?.name ?? 'Workflow', onClick: openSearch }],
40+
})
41+
42+
return (
43+
<div className='shrink-0'>
44+
<ResourceHeader
45+
breadcrumbs={breadcrumbs}
46+
actions={[
47+
{
48+
id: 'search-resources',
49+
text: 'Search resources',
50+
icon: Search,
51+
onSelect: openSearch,
52+
},
53+
]}
54+
/>
55+
</div>
56+
)
57+
}
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { ErrorBoundary } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/error'
2+
import { WorkflowLocationBar } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-location-bar'
23

34
export default function WorkflowLayout({ children }: { children: React.ReactNode }) {
45
return (
56
<main className='flex h-full flex-1 flex-col overflow-hidden'>
6-
<ErrorBoundary>{children}</ErrorBoundary>
7+
<WorkflowLocationBar />
8+
<div className='relative min-h-0 flex-1 overflow-hidden'>
9+
<ErrorBoundary>{children}</ErrorBoundary>
10+
</div>
711
</main>
812
)
913
}

0 commit comments

Comments
 (0)