Skip to content

Commit 4ab2cec

Browse files
committed
feat(platform): hold design-pending workspace tabs behind a platform-preview flag
Dashboard, Issues, Changelog and Tests were held back by a hard-coded `hidden` in WORKSPACE_TABS. They are now `preview` tabs behind one runtime feature flag, `platform-preview` (global, off by default, PLATFORM_PREVIEW off AppConfig), resolved with the organization surface so server pages and client code read the same answer. isWorkspaceTabShown is the one question every entry point asks: the tab bar, each held page (which now answers not found while its tab is not shown, not only when its rollout flag is off), the chat panel's + picker, @ mentions and dashboard resource links, and the run and version snapshots' return into Tests, which decide on the client from the workspace layout's tab flags so those pages stay light.
1 parent 299a1ef commit 4ab2cec

24 files changed

Lines changed: 142 additions & 87 deletions

File tree

‎apps/sim/app/(product)/_components/destinations.test.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ function organization({
8383
'mothership-plan-mode': false,
8484
'mothership-memory-spaces': false,
8585
projects: false,
86+
'platform-preview': false,
8687
},
8788
settingsSections: [],
8889
}

‎apps/sim/app/(product)/o/[organizationId]/search/_components/search-surface/live-search-route.dom.test.tsx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ const NARROW_MEMBER_SURFACE = {
101101
'mothership-plan-mode': false,
102102
'mothership-memory-spaces': false,
103103
projects: false,
104+
'platform-preview': false,
104105
},
105106
settingsSections: [],
106107
} satisfies PlatformOrganization

‎apps/sim/app/(product)/workspace/[workspaceId]/changelog/[entryId]/page.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ export default async function Page({
2929
if (!entry) notFound()
3030
return <ChangelogDetails entry={entry} back={back} />
3131
}
32-
const [{ readWorkspaceTabFlag }, { LiveRelease }] = await Promise.all([
32+
const [{ readWorkspaceTabShown }, { LiveRelease }] = await Promise.all([
3333
import('@/platform/lib/data/workspace-tab-flags'),
3434
import(
3535
'@/app/(product)/workspace/[workspaceId]/changelog/_components/live-release/live-release'
3636
),
3737
])
38-
if (!(await readWorkspaceTabFlag('changelog'))) notFound()
38+
if (!(await readWorkspaceTabShown('changelog'))) notFound()
3939
return <LiveRelease workspaceId={workspaceId} releaseId={id} back={back} />
4040
}

‎apps/sim/app/(product)/workspace/[workspaceId]/changelog/page.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ export default async function Page({
2525
if (!data) notFound()
2626
return <ChangelogRoute data={data} />
2727
}
28-
const [{ readWorkspaceTabFlag }, { LiveChangelog }] = await Promise.all([
28+
const [{ readWorkspaceTabShown }, { LiveChangelog }] = await Promise.all([
2929
import('@/platform/lib/data/workspace-tab-flags'),
3030
import(
3131
'@/app/(product)/workspace/[workspaceId]/changelog/_components/live-changelog/live-changelog'
3232
),
3333
])
34-
if (!(await readWorkspaceTabFlag('changelog'))) notFound()
34+
if (!(await readWorkspaceTabShown('changelog'))) notFound()
3535
return <LiveChangelog workspaceId={workspaceId} />
3636
}

‎apps/sim/app/(product)/workspace/[workspaceId]/dashboards/page.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ export default async function Page({
2525
if (!data) notFound()
2626
return <DashboardRoute data={data} />
2727
}
28-
const [{ readWorkspaceTabFlag }, { LiveDashboard }] = await Promise.all([
28+
const [{ readWorkspaceTabShown }, { LiveDashboard }] = await Promise.all([
2929
import('@/platform/lib/data/workspace-tab-flags'),
3030
import('@/app/(product)/_components/workspace/dashboards/live-dashboard/live-dashboard'),
3131
])
32-
if (!(await readWorkspaceTabFlag('dashboards'))) notFound()
32+
if (!(await readWorkspaceTabShown('dashboards'))) notFound()
3333
return <LiveDashboard workspaceId={workspaceId} />
3434
}

‎apps/sim/app/(product)/workspace/[workspaceId]/tests/[name]/page.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ export default async function Page({
1313
params: Promise<{ workspaceId: string; name: string }>
1414
}) {
1515
if (resolvePlatformMode() !== 'live') notFound()
16-
const [{ workspaceId, name }, { readWorkspaceTabFlag }, { TestDetails }] = await Promise.all([
16+
const [{ workspaceId, name }, { readWorkspaceTabShown }, { TestDetails }] = await Promise.all([
1717
params,
1818
import('@/platform/lib/data/workspace-tab-flags'),
1919
import('@/app/(product)/workspace/[workspaceId]/tests/_components/test-details/test-details'),
2020
])
21-
if (!(await readWorkspaceTabFlag('workflow-tests'))) notFound()
21+
if (!(await readWorkspaceTabShown('tests'))) notFound()
2222
return <TestDetails key={name} workspaceId={workspaceId} name={decodeURIComponent(name)} />
2323
}

‎apps/sim/app/(product)/workspace/[workspaceId]/tests/page.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ export const dynamic = 'force-dynamic'
99

1010
export default async function Page({ params }: { params: Promise<{ workspaceId: string }> }) {
1111
if (resolvePlatformMode() !== 'live') notFound()
12-
const [{ workspaceId }, { readWorkspaceTabFlag }, { TestList }] = await Promise.all([
12+
const [{ workspaceId }, { readWorkspaceTabShown }, { TestList }] = await Promise.all([
1313
params,
1414
import('@/platform/lib/data/workspace-tab-flags'),
1515
import('@/app/(product)/workspace/[workspaceId]/tests/_components/test-list/test-list'),
1616
])
17-
if (!(await readWorkspaceTabFlag('workflow-tests'))) notFound()
17+
if (!(await readWorkspaceTabShown('tests'))) notFound()
1818
return <TestList workspaceId={workspaceId} />
1919
}

‎apps/sim/app/(product)/workspace/[workspaceId]/workflows/[workflowId]/versions/[version]/page.tsx‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { workspacePath } from '@/lib/navigation/paths'
44
import { resolvePlatformMode } from '@/platform/lib/data/mode'
55
import { platformHref } from '@/platform/lib/navigation'
66
import type { ProductPageProps } from '@/platform/lib/route-props'
7-
import { isWorkspaceTabHidden } from '@/platform/lib/workspace-navigation'
87
import { readTestReturn } from '@/platform/shared/test-return'
98

109
export const metadata: Metadata = { title: 'Workflow version' }
@@ -31,14 +30,13 @@ export default async function Page({
3130
])
3231
if (!/^[1-9]\d*$/.test(version)) notFound()
3332
const search = { get: (key: string) => (typeof query[key] === 'string' ? query[key] : null) }
34-
// The Tests tab is held back by design, so a run never returns into it.
35-
const test = isWorkspaceTabHidden('tests') ? null : readTestReturn(query)
33+
const test = readTestReturn(query)
3634
return (
3735
<VersionSnapshot
3836
workspaceId={workspaceId}
3937
workflowId={workflowId}
4038
version={Number(version)}
41-
back={
39+
testBack={
4240
test
4341
? {
4442
href: platformHref(
@@ -47,14 +45,15 @@ export default async function Page({
4745
),
4846
label: test,
4947
}
50-
: {
51-
href: platformHref(
52-
workspacePath(workspaceId, `workflows/${encodeURIComponent(workflowId)}`),
53-
search
54-
),
55-
label: 'Workflow',
56-
}
48+
: undefined
5749
}
50+
back={{
51+
href: platformHref(
52+
workspacePath(workspaceId, `workflows/${encodeURIComponent(workflowId)}`),
53+
search
54+
),
55+
label: 'Workflow',
56+
}}
5857
/>
5958
)
6059
}

‎apps/sim/app/(product)/workspace/[workspaceId]/workflows/_components/run-snapshot/run-snapshot.tsx‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ import { useQueryStates } from 'nuqs'
1010
import { DirectoryHeading } from '@/app/(product)/_components/resource-directory/resource-directory'
1111
import { DetailSplit } from '@/app/(product)/_components/workspace/detail-split/detail-split'
1212
import { WorkflowPreview } from '@/app/(product)/_components/workspace/workflows/canvas/workflow-preview/workflow-preview'
13+
import { useWorkspaceTabFlags } from '@/app/(product)/_components/workspace/workspace-session/workspace-session'
1314
import styles from '@/app/(product)/workspace/[workspaceId]/workflows/_components/run-snapshot/run-snapshot.module.css'
1415
import { SnapshotBlock } from '@/app/(product)/workspace/[workspaceId]/workflows/_components/snapshot-block/snapshot-block'
1516
import { useRunSnapshot } from '@/platform/lib/data/logs'
17+
import { isWorkspaceTabShown } from '@/platform/lib/workspace-navigation'
1618
import { runSnapshotParams, serializeRunSnapshot } from '@/platform/lib/workspace-views'
1719

1820
/** The block types that run another workflow, whose child run legacy's snapshot opens. */
@@ -32,6 +34,8 @@ interface RunSnapshotProps {
3234
workspaceId: string
3335
executionId: string
3436
back: { href: string; label: string }
37+
/** Where a run a test opened returns instead, while the Tests tab is shown. */
38+
testBack?: { href: string; label: string }
3539
}
3640

3741
/**
@@ -41,7 +45,8 @@ interface RunSnapshotProps {
4145
* opens the child workflow it ran, frozen as this run ran it, with a trail back to its parents; the
4246
* drill path lives in the URL.
4347
*/
44-
export function RunSnapshot({ workspaceId, executionId, back }: RunSnapshotProps) {
48+
export function RunSnapshot({ workspaceId, executionId, back, testBack }: RunSnapshotProps) {
49+
const testsShown = isWorkspaceTabShown('tests', useWorkspaceTabFlags())
4550
const snapshot = useRunSnapshot(workspaceId, executionId)
4651
const pathname = usePathname()
4752
const search = useSearchParams()
@@ -82,7 +87,7 @@ export function RunSnapshot({ workspaceId, executionId, back }: RunSnapshotProps
8287
return (
8388
<DetailSplit
8489
read={snapshot.read}
85-
back={back}
90+
back={testBack && testsShown ? testBack : back}
8691
actions={
8792
childHref && (
8893
<Button variant='secondary' size='compact' render={<Link href={childHref} />}>

‎apps/sim/app/(product)/workspace/[workspaceId]/workflows/_components/run-snapshot/version-snapshot.tsx‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,35 @@ import { DirectoryHeading } from '@/app/(product)/_components/resource-directory
55
import { DetailSplit } from '@/app/(product)/_components/workspace/detail-split/detail-split'
66
import { WorkflowPreview } from '@/app/(product)/_components/workspace/workflows/canvas/workflow-preview/workflow-preview'
77
import type { WorkspaceRead } from '@/app/(product)/_components/workspace/workspace-session/model'
8+
import { useWorkspaceTabFlags } from '@/app/(product)/_components/workspace/workspace-session/workspace-session'
89
import styles from '@/app/(product)/workspace/[workspaceId]/workflows/_components/run-snapshot/run-snapshot.module.css'
910
import { SnapshotBlock } from '@/app/(product)/workspace/[workspaceId]/workflows/_components/snapshot-block/snapshot-block'
1011
import { useDeploymentVersionState } from '@/platform/lib/data/workflow-deploy'
1112
import { useWorkflowMap } from '@/platform/lib/data/workflows'
13+
import { isWorkspaceTabShown } from '@/platform/lib/workspace-navigation'
1214

1315
interface VersionSnapshotProps {
1416
workspaceId: string
1517
workflowId: string
1618
version: number
1719
back: { href: string; label: string }
20+
/** Where a version a test ran against returns instead, while the Tests tab is shown. */
21+
testBack?: { href: string; label: string }
1822
}
1923

2024
/**
2125
* One deployed version of a workflow on a read-only canvas, as legacy's version preview shows it:
2226
* the version a test ran against, however the workflow has changed since. Choosing a block shows
2327
* the fields this version saved for it beside the canvas.
2428
*/
25-
export function VersionSnapshot({ workspaceId, workflowId, version, back }: VersionSnapshotProps) {
29+
export function VersionSnapshot({
30+
workspaceId,
31+
workflowId,
32+
version,
33+
back,
34+
testBack,
35+
}: VersionSnapshotProps) {
36+
const testsShown = isWorkspaceTabShown('tests', useWorkspaceTabFlags())
2637
const state = useDeploymentVersionState(workflowId, version)
2738
const workflows = useWorkflowMap(workspaceId)
2839
const [selectedBlockId, setSelectedBlockId] = useState<string | null>(null)
@@ -40,7 +51,7 @@ export function VersionSnapshot({ workspaceId, workflowId, version, back }: Vers
4051
return (
4152
<DetailSplit
4253
read={read}
43-
back={back}
54+
back={testBack && testsShown ? testBack : back}
4455
label={title}
4556
railKind='inspector'
4657
railLabel='Selected block'

0 commit comments

Comments
 (0)