Skip to content

Commit 285e035

Browse files
committed
refactor(resources): give table-view the layout the other three units have
An audit of all four units against each other found one real divergence and a pile of small ones, all in table-view. file-view, log-view and knowledge-view are already uniform: `<unit>.tsx` + `index.ts` + `components/<child>/` + `utils/` (+ `hooks/`), absolute imports, tests colocated with what they test. table-view was flat — fifteen entries at the unit root, `cells/` and `headers/` as sibling groups rather than children of `components/`, three test files at the root, and relative imports throughout, which the repo bans everywhere else. Nothing about that was load-bearing. This moves the files and rewrites the specifiers; the only non-import lines in the diff are five type-only import members biome reflowed. Behaviour is unchanged by construction, and page and panel keep mounting the same components they did. cells/, headers/ -> components/ data-row, select-pill, ... -> components/<name>/<name>.tsx + index.ts utils.ts, values.ts, -> utils/selection.ts, utils/values.ts, constants.ts utils/constants.ts *.test.ts -> beside their subject What this does NOT fix, and deliberately: table-view still has no `TableView`. It exports 72 symbols and no view, because a table has no read-only surface yet — everything that draws a grid today also writes one, and the shell that does both reads useRouter and the permission context. Splitting it is a real refactor, not a move, and it is the one thing standing between `table` and the same axes the other three are mounted against. The barrel and the rule now say so plainly instead of implying uniformity that was not there. Also corrects three docs that claimed `knowledge` and `log` had no canonical view. They both do; only `table` does not.
1 parent 5a1af8f commit 285e035

30 files changed

Lines changed: 131 additions & 58 deletions

.claude/rules/sim-resource-views.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,30 @@ apps/sim/resources/ # kinds.ts · source.ts · grants.ts · h
3737
apps/sim/components/resources/<unit>/ # 'use client' — THE view, one per resource
3838
```
3939

40-
A resource kind with no canonical view yet (`table`, `knowledge`, `log`) is simply **absent** from `CANONICAL_UNITS` in the check. That is the correct state for an unmigrated kind. Do not add a flag, a shim, or a placeholder entry for it.
40+
Every unit has the same layout, so moving between them costs nothing:
41+
42+
```
43+
<unit>/
44+
├── <unit>.tsx # THE view — the only component the barrel mounts
45+
├── index.ts # the barrel; the only entry point consumers use
46+
├── components/<child>/ # <child>.tsx + index.ts, one folder per child
47+
├── hooks/<name>.ts # optional; tests colocated
48+
├── utils/<name>.ts # pure helpers; tests colocated
49+
└── types.ts # optional; shared types the whole unit reads
50+
```
51+
52+
Imports **inside** a unit are absolute (`@/components/resources/<unit>/...`) like
53+
everywhere else in the app. The one exception is a folder's own `index.ts`
54+
naming its siblings, which stays relative (`./<child>`) — it is describing its
55+
own directory, not reaching across the app.
56+
57+
`table-view` is the one unit with no `<unit>.tsx`, and deliberately so: a table
58+
has no read-only surface yet, because everything that draws a grid today also
59+
writes one. It is absent from `CANONICAL_UNITS`' view list for exactly that
60+
reason, and carries the layout above so a future `TableView` lands in the shape
61+
the other three already have.
62+
63+
A resource kind with no canonical view yet — `table` alone today — is simply **absent** from the view list in `CANONICAL_UNITS`. That is the correct state for an unmigrated kind. Do not add a flag, a shim, or a placeholder entry for it.
4164

4265
## Consume: construct the axes, then mount
4366

.cursor/rules/sim-resource-views.mdc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ apps/sim/resources/ # kinds/source/grants/host — pure TS, N
2727
apps/sim/components/resources/<unit>/ # 'use client' — THE view, one per resource
2828
```
2929

30-
A kind with no canonical view yet (`table`, `knowledge`, `log`, `schedule`) is simply absent from the check's `CANONICAL_UNITS`. Do not add a flag, shim, or placeholder for it.
30+
A kind with no canonical view yet `table` alone today — is simply absent from the view list in the checks `CANONICAL_UNITS`. Do not add a flag, shim, or placeholder for it.
3131

3232
## Consume: construct, then mount
3333

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ Views are mounted against exactly **three axes**, defined in `apps/sim/resources
425425
- `grants` — what this viewer may do: `{ write, run }`. Replaces `canEdit`, `canRun`, `canAdmin`, `disableEdit/Insert/Delete`.
426426
- `host` — who owns the URL, the router, the document frame: `'page' | 'panel' | 'public'`. Replaces `embedded`. `hostOwnsUrl(host)` is the one place the "embedded views do not write nuqs keys" rule lives.
427427

428-
There is no fourth axis; agent streaming is one optional prop on `FileView`. Consumers CONSTRUCT the axes and MOUNT the view — never wrap it in a passthrough, never reach past its barrel, never reimplement its UI because it lacks a seam (add the seam), never import `@/app/workspace/[workspaceId]/**` from an anonymous surface (`app/f/**`, `app/(interfaces)/**`), and never read `useRouter`/`useParams`/`useQueryState`/`useUserPermissionsContext` inside a unit. A kind with no canonical view yet (`knowledge`, `log`) is simply absent from the check's `CANONICAL_UNITS` — no flag, shim, or placeholder.
428+
There is no fourth axis; agent streaming is one optional prop on `FileView`. Consumers CONSTRUCT the axes and MOUNT the view — never wrap it in a passthrough, never reach past its barrel, never reimplement its UI because it lacks a seam (add the seam), never import `@/app/workspace/[workspaceId]/**` from an anonymous surface (`app/f/**`, `app/(interfaces)/**`), and never read `useRouter`/`useParams`/`useQueryState`/`useUserPermissionsContext` inside a unit. A kind with no canonical view yet `table` alone today — is simply absent from the view list in the check's `CANONICAL_UNITS` — no flag, shim, or placeholder. Every unit has the same layout (`<unit>.tsx` · `index.ts` · `components/<child>/` · `hooks/` · `utils/` · `types.ts`), so moving between them costs nothing.
429429

430430
Enforced by `bun run check:resources` (strict: `check:resources:strict`), which ratchets counters for wrappers, imports past a barrel, cross-tree imports, unsanctioned props, token-as-`workspaceId`, and context leaks. Escape hatches — reason mandatory, on the line directly above: `// boundary-resource-wrapper:`, `// boundary-resource-internal:`, `// boundary-resource-tree:`, `// boundary-resource-prop:`. Full rules in `.claude/rules/sim-resource-views.md`.
431431

apps/sim/components/resources/table-view/cells/cell-content.tsx renamed to apps/sim/components/resources/table-view/components/cells/cell-content.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
'use client'
22

33
import type { ReactNode } from 'react'
4+
import {
5+
CellRender,
6+
resolveCellRender,
7+
} from '@/components/resources/table-view/components/cells/cell-render'
8+
import type { DisplayColumn } from '@/components/resources/table-view/types'
49
import type { RowExecutionMetadata } from '@/lib/table'
5-
import type { DisplayColumn } from '../types'
6-
import { CellRender, resolveCellRender } from './cell-render'
710

811
interface CellContentProps {
912
value: unknown

apps/sim/components/resources/table-view/cell-formatting.test.ts renamed to apps/sim/components/resources/table-view/components/cells/cell-formatting.test.ts

File renamed without changes.

apps/sim/components/resources/table-view/cells/cell-render.test.ts renamed to apps/sim/components/resources/table-view/components/cells/cell-render.test.ts

File renamed without changes.

apps/sim/components/resources/table-view/cells/cell-render.tsx renamed to apps/sim/components/resources/table-view/components/cells/cell-render.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@ import { useEffect, useRef, useState } from 'react'
55
import { Badge, Checkbox, cn, Tooltip } from '@sim/emcn'
66
import { parse } from 'tldts'
77
import { StatusBadge } from '@/components/execution-status'
8+
import {
9+
SimResourceCell,
10+
type SimResourceType,
11+
} from '@/components/resources/table-view/components/cells/sim-resource-cell'
12+
import {
13+
resolveSelectOptions,
14+
SelectPill,
15+
} from '@/components/resources/table-view/components/select-pill'
16+
import type { DisplayColumn } from '@/components/resources/table-view/types'
17+
import { storageToDisplay } from '@/components/resources/table-view/utils/values'
818
import { faviconUrl } from '@/lib/core/utils/favicon'
919
import type { RowExecutionMetadata, SelectOption } from '@/lib/table'
1020
import { columnTypeOf } from '@/lib/table/column-types'
11-
import { resolveSelectOptions, SelectPill } from '../select-pill'
12-
import type { DisplayColumn } from '../types'
13-
import { storageToDisplay } from '../values'
14-
import { SimResourceCell, type SimResourceType } from './sim-resource-cell'
1521

1622
export type CellRenderKind =
1723
// Workflow-output cells

apps/sim/components/resources/table-view/cells/index.ts renamed to apps/sim/components/resources/table-view/components/cells/index.ts

File renamed without changes.

apps/sim/components/resources/table-view/cells/sim-resource-cell.tsx renamed to apps/sim/components/resources/table-view/components/cells/sim-resource-cell.tsx

File renamed without changes.

apps/sim/components/resources/table-view/data-row.tsx renamed to apps/sim/components/resources/table-view/components/data-row/data-row.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@
33
import React, { type ReactNode } from 'react'
44
import { Button, Checkbox, cn, handleKeyboardActivation } from '@sim/emcn'
55
import { PlayOutline, Square } from '@sim/emcn/icons'
6-
import type { ActiveDispatch } from '@/lib/api/contracts/tables'
7-
import type { TableRow as TableRowType, WorkflowGroup } from '@/lib/table'
8-
import { getUnmetGroupDeps } from '@/lib/table/deps'
9-
import { CellContent } from './cells'
6+
import { CellContent } from '@/components/resources/table-view/components/cells'
7+
import type { DisplayColumn } from '@/components/resources/table-view/types'
108
import {
119
CELL,
1210
CELL_CHECKBOX,
1311
CELL_CONTENT,
1412
SELECTION_OVERLAY,
1513
SELECTION_TINT_BG,
16-
} from './constants'
17-
import type { DisplayColumn } from './types'
18-
import { type NormalizedSelection, resolveCellExec } from './utils'
14+
} from '@/components/resources/table-view/utils/constants'
15+
import {
16+
type NormalizedSelection,
17+
resolveCellExec,
18+
} from '@/components/resources/table-view/utils/selection'
19+
import type { ActiveDispatch } from '@/lib/api/contracts/tables'
20+
import type { TableRow as TableRowType, WorkflowGroup } from '@/lib/table'
21+
import { getUnmetGroupDeps } from '@/lib/table/deps'
1922

2023
export interface DataRowProps {
2124
row: TableRowType

0 commit comments

Comments
 (0)