Skip to content

Commit 1666511

Browse files
committed
improvement(platform): consolidate one shared local preview
1 parent a824d10 commit 1666511

146 files changed

Lines changed: 3983 additions & 851 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.agents/skills/implement-platform/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ Start in the Sim checkout containing the requested product work. Read the [Platf
1212
2. **Resolve design intent.** For Paper-backed work, use `$sim-paper-design` to locate the live Shared or Platform master and the product states that use it. Exclude Marcus. Preserve the key and theme roles. Treat artboard sizes as reference measurements. For code-first changes, follow the latest explicit product direction and inspect the rendered route. Identify any source you could not verify. Update the Paper canvas when the request includes Paper changes.
1313
3. **Choose or change the owner.** Start with the behavior. An action, navigation row, value picker, or disclosure has an existing keyboard and pointer contract. Different interactions may share visual roles while retaining different semantics. Use the existing family and named props for a change in size, intent, icon, or content. Toolbar choices use ChoiceMenu, as Home's period does; Select/SelectField belong to forms and settings. Compare the rendered trigger, not just its variant name. Put unique anatomy and its CSS together in `_components/<component>/<component>.tsx` and `<component>.module.css`. Match an existing semantic rhythm, such as Home's ActivityRow, for a custom composition. Keep page files free of styling. Only EMCN owns the appearance of its controls. Use Base UI there for complex keyboard, floating, and dismissal behavior.
1414
4. **Trace the full change.** On a second independent feature use, promote the original implementation and migrate both callers. For consolidation, compare semantics, map every consumer to its replacement, then remove the obsolete implementation, export, variant styles, and unused registrations. For deletion, also check menus, preferences, fixture data, workbench references, and tests that existed only for the removed feature. Preserve unrelated consumers and historical Paper evidence. Before adding a shared visual variant, name at least two independent real consumers. A single feature composes the existing primitives in its local owner; a label, icon, data value or responsive arrangement does not justify another variant. Keep the public API small enough to understand at the call site. Edit the source or compiler for generated foundations and recipes.
15-
5. **Verify where people use it.** Run the design audit and applicable checks from the README. Render the changed product route with empty, full, stress, and fixture-off data as relevant. Check both themes, widths between artboards, long content, text scaling, keyboard, and pointer states. Compare shared controls in their actual consumers. Check the actual scroll edge and the open popup when space is tight. For shell, panel, or desktop work, exercise the real Electron renderer. For substantial implementations and consolidations, use an independent agent during design or implementation and for a final review of the changed owners and routes. Provide the working localhost route for visual review.
15+
5. **Verify where people use it.** Run the design audit and applicable checks from the README. Render the changed product route with empty, full, stress, and fixture-off data as relevant. Check both themes, widths between artboards, long content, text scaling, keyboard, and pointer states. Compare shared controls in their actual consumers. Check the actual scroll edge and the open popup when space is tight. For shell, panel, or desktop work, exercise the real Electron renderer. For substantial implementations and consolidations, use an independent agent during design or implementation and for a final review of the changed owners and routes. Reuse the single review server at localhost:3125. Check its process working directory and branch before starting a server or moving work. Separate task worktrees do not update that preview until reconciled into its checkout. Provide the working route for visual review.
1616
6. **Keep decisions durable.** Follow the contract’s maintenance guidance when an approved correction changes a shared rule. Record feature-specific decisions with their feature. For sustained work, keep a task checkpoint with the code revision, verified states, evidence, and outstanding work. Include the branch or PR, checkpoint path, and localhost route in a handoff. On resumption, compare the checkpoint with the current branch, working tree, and relevant live sources before acting.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.actions {
2+
display: flex;
3+
flex-wrap: wrap;
4+
align-items: center;
5+
gap: var(--ui-action-gap);
6+
}

‎apps/sim/app/o/[organizationId]/_redesign/integrations/slack-search-actions.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
import Link from 'next/link'
44
import { slackSearchOnboardingPath } from '@/lib/slack-search/onboarding'
5+
import styles from '@/app/o/[organizationId]/_redesign/integrations/slack-search-actions.module.css'
56
import {
67
useRetrySlackSearchOnboarding,
78
useSlackSearchOnboarding,
89
} from '@/hooks/queries/slack-search-onboarding'
9-
import styles from '@/platform/app/(shell)/integrations/_components/integrations-page/integrations-page.module.css'
1010
import { Button, InlineNotice } from '@/platform/design-system/components'
1111

1212
interface SlackSearchActionsProps {
@@ -24,15 +24,15 @@ export function SlackSearchActions({ organizationId, token, userId }: SlackSearc
2424
return status.error ? <InlineNotice intent='danger' message={status.error.message} /> : null
2525
if (!('organizationId' in data) || data.organizationId !== organizationId)
2626
return (
27-
<div className={styles.handoff}>
27+
<div className={styles.actions}>
2828
<Button render={<Link href={slackSearchOnboardingPath(token)} />}>
2929
Finish Slack setup
3030
</Button>
3131
</div>
3232
)
3333
const retried = data.status === 'retried' || retry.isSuccess
3434
return (
35-
<div className={styles.handoff}>
35+
<div className={styles.actions}>
3636
{!retried &&
3737
(data.status === 'ready' ? (
3838
<Button
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import type { ComponentType } from 'react'
2+
import {
3+
Database,
4+
Download,
5+
File,
6+
FolderPlus,
7+
Library,
8+
Plus,
9+
RefreshCw,
10+
Table,
11+
Upload,
12+
} from '@sim/emcn/icons'
13+
import { FOLDERED_RESOURCE_HEADERS } from '@/app/workspace/[workspaceId]/components/folders/foldered-resources'
14+
import type { ChromeActionSpec } from '@/app/workspace/[workspaceId]/components/resource/components/resource-chrome-fallback'
15+
import type { ResourceColumn } from '@/app/workspace/[workspaceId]/components/resource/resource'
16+
17+
interface ListChrome {
18+
title: string
19+
icon: ComponentType<{ className?: string }>
20+
columns: readonly ResourceColumn[]
21+
actions: readonly ChromeActionSpec[]
22+
searchPlaceholder: string
23+
hasSort: boolean
24+
hasFilter: boolean
25+
}
26+
27+
/** The original list chrome used for loading and for fixture rendering of a workspace page. */
28+
export const RESOURCE_LIST_CHROME = {
29+
tables: {
30+
title: FOLDERED_RESOURCE_HEADERS.table.rootLabel,
31+
icon: Table,
32+
columns: [
33+
{ id: 'name', header: 'Name' },
34+
{ id: 'columns', header: 'Columns' },
35+
{ id: 'rows', header: 'Rows' },
36+
{ id: 'created', header: 'Created' },
37+
{ id: 'owner', header: 'Owner' },
38+
{ id: 'updated', header: 'Last Updated' },
39+
],
40+
actions: [
41+
{ text: 'Import CSV', icon: Upload },
42+
{ text: 'New folder', icon: FolderPlus },
43+
{ text: 'New table', icon: Plus, variant: 'primary' },
44+
],
45+
searchPlaceholder: 'Search tables...',
46+
hasSort: true,
47+
hasFilter: true,
48+
},
49+
files: {
50+
title: FOLDERED_RESOURCE_HEADERS.file.rootLabel,
51+
icon: File,
52+
columns: [
53+
{ id: 'name', header: 'Name', widthMultiplier: 1.15 },
54+
{ id: 'size', header: 'Size', widthMultiplier: 0.85 },
55+
{ id: 'type', header: 'Type', widthMultiplier: 1.0 },
56+
{ id: 'created', header: 'Created' },
57+
{ id: 'owner', header: 'Owner' },
58+
{ id: 'updated', header: 'Last Updated' },
59+
],
60+
actions: [
61+
{ text: 'Upload', icon: Upload },
62+
{ text: 'New folder', icon: FolderPlus },
63+
{ text: 'New file', icon: Plus, variant: 'primary' },
64+
],
65+
searchPlaceholder: 'Search files...',
66+
hasSort: true,
67+
hasFilter: true,
68+
},
69+
knowledge: {
70+
title: FOLDERED_RESOURCE_HEADERS.knowledge_base.rootLabel,
71+
icon: Database,
72+
columns: [
73+
{ id: 'name', header: 'Name' },
74+
{ id: 'documents', header: 'Documents', widthMultiplier: 0.6 },
75+
{ id: 'tokens', header: 'Tokens', widthMultiplier: 0.6 },
76+
{ id: 'connectors', header: 'Connectors', widthMultiplier: 0.7 },
77+
{ id: 'created', header: 'Created' },
78+
{ id: 'owner', header: 'Owner' },
79+
{ id: 'updated', header: 'Last Updated' },
80+
],
81+
actions: [
82+
{ text: 'New folder', icon: FolderPlus },
83+
{ text: 'New base', icon: Plus, variant: 'primary' },
84+
],
85+
searchPlaceholder: 'Search knowledge bases...',
86+
hasSort: true,
87+
hasFilter: true,
88+
},
89+
logs: {
90+
title: 'Logs',
91+
icon: Library,
92+
columns: [
93+
{ id: 'workflow', header: 'Workflow' },
94+
{ id: 'date', header: 'Date' },
95+
{ id: 'status', header: 'Status' },
96+
{ id: 'cost', header: 'Cost' },
97+
{ id: 'trigger', header: 'Trigger' },
98+
{ id: 'duration', header: 'Duration' },
99+
],
100+
actions: [
101+
{ text: 'Export', icon: Download },
102+
{ text: 'Refresh', icon: RefreshCw },
103+
{ text: 'Logs', active: true },
104+
{ text: 'Dashboard' },
105+
],
106+
searchPlaceholder: 'Search logs...',
107+
hasSort: true,
108+
hasFilter: true,
109+
},
110+
} as const satisfies Record<string, ListChrome>
Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,8 @@
11
'use client'
22

3-
import { File as FilesIcon, FolderPlus, Plus, Upload } from '@sim/emcn'
4-
import {
5-
type ChromeActionSpec,
6-
ResourceChromeFallback,
7-
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-chrome-fallback'
8-
9-
const COLUMNS = [
10-
{ id: 'name', header: 'Name', widthMultiplier: 1.15 },
11-
{ id: 'size', header: 'Size', widthMultiplier: 0.85 },
12-
{ id: 'type', header: 'Type', widthMultiplier: 1.0 },
13-
{ id: 'created', header: 'Created' },
14-
{ id: 'owner', header: 'Owner' },
15-
{ id: 'updated', header: 'Last Updated' },
16-
]
17-
18-
const ACTIONS: ChromeActionSpec[] = [
19-
{ text: 'Upload', icon: Upload },
20-
{ text: 'New folder', icon: FolderPlus },
21-
{ text: 'New file', icon: Plus, variant: 'primary' },
22-
]
3+
import { ResourceChromeFallback } from '@/app/workspace/[workspaceId]/components/resource/components/resource-chrome-fallback'
4+
import { RESOURCE_LIST_CHROME } from '@/app/workspace/[workspaceId]/components/resource/list-chrome'
235

246
export default function FilesLoading() {
25-
return (
26-
<ResourceChromeFallback
27-
icon={FilesIcon}
28-
title='Files'
29-
columns={COLUMNS}
30-
actions={ACTIONS}
31-
searchPlaceholder='Search files...'
32-
hasSort
33-
hasFilter
34-
/>
35-
)
7+
return <ResourceChromeFallback {...RESOURCE_LIST_CHROME.files} />
368
}
Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,8 @@
11
'use client'
22

3-
import { Database, FolderPlus, Plus } from '@sim/emcn/icons'
4-
import { FOLDERED_RESOURCE_HEADERS } from '@/app/workspace/[workspaceId]/components/folders/foldered-resources'
5-
import {
6-
type ChromeActionSpec,
7-
ResourceChromeFallback,
8-
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-chrome-fallback'
9-
10-
const KNOWLEDGE_HEADER = FOLDERED_RESOURCE_HEADERS.knowledge_base
11-
12-
const COLUMNS = [
13-
{ id: 'name', header: 'Name' },
14-
{ id: 'documents', header: 'Documents', widthMultiplier: 0.6 },
15-
{ id: 'tokens', header: 'Tokens', widthMultiplier: 0.6 },
16-
{ id: 'connectors', header: 'Connectors', widthMultiplier: 0.7 },
17-
{ id: 'created', header: 'Created' },
18-
{ id: 'owner', header: 'Owner' },
19-
{ id: 'updated', header: 'Last Updated' },
20-
]
21-
22-
const ACTIONS: ChromeActionSpec[] = [
23-
{ text: 'New folder', icon: FolderPlus },
24-
{ text: 'New base', icon: Plus, variant: 'primary' },
25-
]
3+
import { ResourceChromeFallback } from '@/app/workspace/[workspaceId]/components/resource/components/resource-chrome-fallback'
4+
import { RESOURCE_LIST_CHROME } from '@/app/workspace/[workspaceId]/components/resource/list-chrome'
265

276
export default function KnowledgeLoading() {
28-
return (
29-
<ResourceChromeFallback
30-
icon={Database}
31-
title={KNOWLEDGE_HEADER.rootLabel}
32-
columns={COLUMNS}
33-
actions={ACTIONS}
34-
searchPlaceholder='Search knowledge bases...'
35-
hasSort
36-
hasFilter
37-
/>
38-
)
7+
return <ResourceChromeFallback {...RESOURCE_LIST_CHROME.knowledge} />
398
}
Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,8 @@
11
'use client'
22

3-
import { Library, RefreshCw } from '@sim/emcn'
4-
import { Download } from '@sim/emcn/icons'
5-
import {
6-
type ChromeActionSpec,
7-
ResourceChromeFallback,
8-
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-chrome-fallback'
9-
10-
const COLUMNS = [
11-
{ id: 'workflow', header: 'Workflow' },
12-
{ id: 'date', header: 'Date' },
13-
{ id: 'status', header: 'Status' },
14-
{ id: 'cost', header: 'Cost' },
15-
{ id: 'trigger', header: 'Trigger' },
16-
{ id: 'duration', header: 'Duration' },
17-
]
18-
19-
const ACTIONS: ChromeActionSpec[] = [
20-
{ text: 'Export', icon: Download },
21-
{ text: 'Refresh', icon: RefreshCw },
22-
{ text: 'Logs', active: true },
23-
{ text: 'Dashboard' },
24-
]
3+
import { ResourceChromeFallback } from '@/app/workspace/[workspaceId]/components/resource/components/resource-chrome-fallback'
4+
import { RESOURCE_LIST_CHROME } from '@/app/workspace/[workspaceId]/components/resource/list-chrome'
255

266
export default function LogsLoading() {
27-
return (
28-
<ResourceChromeFallback
29-
icon={Library}
30-
title='Logs'
31-
columns={COLUMNS}
32-
actions={ACTIONS}
33-
searchPlaceholder='Search logs...'
34-
hasSort
35-
hasFilter
36-
/>
37-
)
7+
return <ResourceChromeFallback {...RESOURCE_LIST_CHROME.logs} />
388
}
Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,8 @@
11
'use client'
22

3-
import { Plus, Upload } from '@sim/emcn'
4-
import { FolderPlus, Table as TableIcon } from '@sim/emcn/icons'
5-
import {
6-
type ChromeActionSpec,
7-
ResourceChromeFallback,
8-
} from '@/app/workspace/[workspaceId]/components/resource/components/resource-chrome-fallback'
9-
10-
const COLUMNS = [
11-
{ id: 'name', header: 'Name' },
12-
{ id: 'columns', header: 'Columns' },
13-
{ id: 'rows', header: 'Rows' },
14-
{ id: 'created', header: 'Created' },
15-
{ id: 'owner', header: 'Owner' },
16-
{ id: 'updated', header: 'Last Updated' },
17-
]
18-
19-
const ACTIONS: ChromeActionSpec[] = [
20-
{ text: 'Import CSV', icon: Upload },
21-
{ text: 'New folder', icon: FolderPlus },
22-
{ text: 'New table', icon: Plus, variant: 'primary' },
23-
]
3+
import { ResourceChromeFallback } from '@/app/workspace/[workspaceId]/components/resource/components/resource-chrome-fallback'
4+
import { RESOURCE_LIST_CHROME } from '@/app/workspace/[workspaceId]/components/resource/list-chrome'
245

256
export default function TablesLoading() {
26-
return (
27-
<ResourceChromeFallback
28-
icon={TableIcon}
29-
title='Tables'
30-
columns={COLUMNS}
31-
actions={ACTIONS}
32-
searchPlaceholder='Search tables...'
33-
hasSort
34-
hasFilter
35-
/>
36-
)
7+
return <ResourceChromeFallback {...RESOURCE_LIST_CHROME.tables} />
378
}

‎apps/sim/package.json‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
},
1010
"scripts": {
1111
"dev": "bun run build:cli-runtime && bun run dev:cache:cap && next dev --port 3000",
12-
"dev:platform": "cd platform && next dev --webpack --port 3100",
13-
"build:platform": "cd platform && next build --webpack",
12+
"build:workspace-preview": "vite build --config workspace-preview/vite.config.ts",
13+
"dev:platform": "bun run build:workspace-preview && cd platform && next dev --webpack --port 3125",
14+
"build:platform": "bun run build:workspace-preview && cd platform && next build --webpack",
1415
"type-check:platform": "cd platform && next typegen && tsc --noEmit",
1516
"test:platform:desktop": "playwright test --config platform/checks/desktop/playwright.config.ts",
1617
"test:platform:e2e": "playwright test --config platform/checks/playwright.config.ts",
1718
"test:platform:live": "playwright test --config platform/checks/live/playwright.config.ts",
18-
"start:platform": "cd platform && next start --port 3100",
19+
"start:platform": "cd platform && next start --port 3125",
1920
"dev:capped": "bun run build:cli-runtime && bun run dev:cache:cap && NODE_OPTIONS='--max-old-space-size=4096' next dev --port 3000",
2021
"dev:cache:cap": "bun run ../../scripts/prune-turbopack-cache.ts",
2122
"dev:clean": "rm -rf .next/dev/cache",
@@ -347,6 +348,7 @@
347348
"tinyrainbow": "3.2.0",
348349
"tw-animate-css": "^1.4.0",
349350
"typescript": "^7.0.2",
351+
"vite": "8.3.5",
350352
"vitest": "^5.0.4"
351353
}
352354
}

0 commit comments

Comments
 (0)