@marktiderman/genesis-studio 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/standalone.css +1 -1
- package/package.json +24 -11
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/DataStudio.tsx","../src/router.ts","../src/values.ts","../src/lib/csv.ts","../src/lib/query-state.ts","../src/lib/relations.ts","../src/record/RecordForm.tsx","../src/lib/form-schema.ts","../src/lib/form-config.ts","../src/record/RelationPicker.tsx","../src/record/RecordPanel.tsx","../src/toolbar/Toolbar.tsx","../src/workspace/ViewsPanel.tsx","../src/grid/cells.tsx","../src/views/KanbanView.tsx","../src/views/CalendarView.tsx","../src/views/fields.ts","../src/toolbar/ImportDialog.tsx","../src/toolbar/BulkEdit.tsx","../src/sheet/SheetView.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { keepPreviousData, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { ChevronLeft, ChevronRight, Database, History, Lock, PencilLine, Plus, Table2, Trash2, Undo2, X } from \"lucide-react\";\nimport { GenesisProvider, type BaseRecord, type DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport {\n encodeRecordKey,\n isDataWriteError,\n keyFields,\n type AuditEntry,\n type FieldSchema,\n type ResourceSchema,\n type ResourceSummary,\n} from \"@marktiderman/genesis-core/schema\";\nimport { useSavedViews } from \"@marktiderman/genesis-ui/data\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"@marktiderman/genesis-ui/dialog\";\nimport { Alert, AlertDescription, AlertTitle } from \"@marktiderman/genesis-ui/alert\";\nimport { cn } from \"@marktiderman/genesis-ui/utils\";\nimport { useHistoryRouter, type StudioLocation, type StudioRouter } from \"./router\";\nimport { choicesFor, displayText, editText, fieldLabel, parseDraft } from \"./values\";\nimport { exportCsv, downloadText } from \"./lib/csv\";\nimport { formatFilters, formatSorts, parseFilters, parseSorts } from \"./lib/query-state\";\nimport { usePageLinkLabels } from \"./lib/relations\";\nimport { RecordForm } from \"./record/RecordForm\";\nimport { RecordPanel } from \"./record/RecordPanel\";\nimport { ExportButton, FilterBuilder, GroupPicker, HideFields, NewRowButton, SearchBox, SortBuilder, ViewFieldPicker } from \"./toolbar/Toolbar\";\nimport { TableTabs, ViewsPanel } from \"./workspace/ViewsPanel\";\nimport { CellValue } from \"./grid/cells\";\nimport { KanbanView } from \"./views/KanbanView\";\nimport { CalendarView } from \"./views/CalendarView\";\nimport { boardFields, dateFields } from \"./views/fields\";\nimport { ImportDialog } from \"./toolbar/ImportDialog\";\nimport { BulkEditDialog } from \"./toolbar/BulkEdit\";\nimport { gridFields, SheetView } from \"./sheet/SheetView\";\nimport type { StudioFormConfig } from \"./lib/form-config\";\n\ntype Row = Record<string, unknown>;\n\n/** One entry in the session's activity panel. */\nexport interface StudioActivity {\n id: string;\n at: Date;\n resource: string;\n field: string;\n /** The record's key, as shown to the user. */\n record: string;\n outcome: \"saved\" | \"not_saved\";\n /** What was attempted. Default `update`. */\n action?: \"update\" | \"create\" | \"delete\";\n message: string;\n /** Present when the edit committed with an audit entry from the `table` sink. */\n audit?: AuditEntry;\n /**\n * A bulk write's audit entries, one per row. A single entry holds them all,\n * so its Undo reaches every row however many there were.\n */\n audits?: AuditEntry[];\n /** True once this change has been undone. */\n undone?: boolean;\n}\n\nexport interface DataStudioProps {\n /**\n * Where the data comes from: the studio handler's client\n * (`createStudioProvider` from `@marktiderman/genesis-studio-server/client`)\n * or any Genesis `DataProvider` that implements `describe` and\n * `listResources`.\n */\n provider: DataProvider;\n /**\n * URL state, from the app's router (see `createSearchParamsRouter`).\n * Default: the page's own query string, through the History API.\n */\n router?: StudioRouter;\n /** Shown in place of the studio while nobody is signed in. */\n signIn?: ReactNode;\n /**\n * Changes when the signed-in user does (their id, say). The studio drops\n * everything it loaded for the previous user and asks again. Not needed\n * with a provider that reports its session (`createSupabaseStudioProvider`).\n */\n sessionKey?: string | number | null;\n /** Heading above the table list. Default \"Data\"; `null` for none (the app's own page header names it). */\n title?: string | null;\n /**\n * `card` (default): the studio draws its own frame. `plain`: no frame, so\n * it sits flush inside an app's layout, under its own header and nav,\n * like any other page of the app.\n */\n variant?: \"card\" | \"plain\";\n /** Rows per page. Default 50. */\n perPage?: number;\n /**\n * Record-form layout per resource (`schema.table`): sections, and fields\n * shown only when a condition holds. Code first; see `StudioFormConfig`.\n */\n forms?: Readonly<Record<string, StudioFormConfig>>;\n className?: string;\n}\n\nconst PER_PAGE = 50;\nconst SEARCH_DEBOUNCE_MS = 300;\n\nfunction isUnauthenticated(error: unknown): boolean {\n return isDataWriteError(error) && error.outcome === \"unauthenticated\";\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * The Data Studio: a sidebar of the tables this user may see, and a sheet of\n * the selected one where a cell is edited in place. Every edit carries the\n * version it was read at, so a stale edit is refused rather than saved over\n * someone else's, and the outcome — saved with its audit entry, or not saved\n * and why — is shown on screen.\n *\n * It renders inside its own `GenesisProvider`, so it works whether or not\n * the app already has one.\n *\n * @stability Experimental\n */\nexport function DataStudio(props: DataStudioProps) {\n const historyRouter = useHistoryRouter();\n const router = props.router ?? historyRouter;\n // A provider that knows who is signed in (the Supabase one) keys the\n // studio's data to that user, so the app needn't pass a sessionKey.\n const session = (props.provider as { session?: StudioSessionSource }).session;\n const [sessionUser, setSessionUser] = useState<string | null>(null);\n useEffect(() => session?.subscribe(setSessionUser), [session]);\n const sessionKey = props.sessionKey !== undefined ? props.sessionKey : session ? sessionUser : null;\n return (\n <GenesisProvider provider={props.provider}>\n {/* The scope standalone.css resets, for apps without Tailwind. */}\n <div data-genesis-studio=\"\">\n <StudioWorkspace {...props} router={router} sessionKey={sessionKey} />\n </div>\n </GenesisProvider>\n );\n}\n\n/** A provider's report of who is signed in (see `createSupabaseStudioProvider`). */\nexport interface StudioSessionSource {\n subscribe(listener: (userId: string | null) => void): () => void;\n}\n\nfunction StudioWorkspace({\n provider,\n router,\n signIn,\n sessionKey = null,\n title = \"Data\",\n variant = \"card\",\n perPage = PER_PAGE,\n forms,\n className,\n}: DataStudioProps & { router: StudioRouter }) {\n const queryClient = useQueryClient();\n const [activity, setActivity] = useState<StudioActivity[]>([]);\n // The provider whose token was refused. Signing in again, even as the same\n // user, gives a new provider (a new token), which ends the signed-out state.\n const [refusedProvider, setRefusedProvider] = useState<DataProvider | null>(null);\n const signedOut = refusedProvider !== null && refusedProvider === provider;\n const providerRef = useRef(provider);\n providerRef.current = provider;\n const setSignedOut = useCallback((value: boolean) => setRefusedProvider(value ? providerRef.current : null), []);\n\n // A new user sees nothing the previous one loaded.\n useEffect(() => {\n setRefusedProvider(null);\n setActivity([]);\n void queryClient.resetQueries({ queryKey: [\"genesis-studio\"] });\n }, [sessionKey, queryClient]);\n\n const resources = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"resources\"],\n queryFn: () => {\n if (!provider.listResources) throw new Error(\"This data provider can't list its resources.\");\n return provider.listResources();\n },\n retry: (count, error) => !isUnauthenticated(error) && count < 2,\n });\n\n useEffect(() => {\n if (isUnauthenticated(resources.error)) setSignedOut(true);\n }, [resources.error]);\n\n // The same user signed in again: ask again with the new token. Declared\n // after the queries, so their fetchers already use the new provider.\n useEffect(() => {\n if (refusedProvider && refusedProvider !== provider) {\n setRefusedProvider(null);\n void queryClient.resetQueries({ queryKey: [\"genesis-studio\", sessionKey] });\n }\n }, [provider, refusedProvider, queryClient, sessionKey]);\n\n /**\n * Undo a bulk write row by row, each a compensating write with its own audit\n * entry. Rows that can't be undone stay on the entry, so Undo can be retried.\n */\n // Entries with an undo in flight, so a second click or Ctrl+Z can't resend it.\n const undoing = useRef(new Set<string>());\n\n const undoAll = useCallback(\n async (entry: StudioActivity, audits: AuditEntry[]) => {\n const left: AuditEntry[] = [];\n let firstError: unknown;\n for (const audit of audits) {\n try {\n await provider.undo!(entry.resource, { auditId: audit.id });\n } catch (error) {\n left.push(audit);\n firstError ??= error;\n }\n }\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey] });\n const done = audits.length - left.length;\n setActivity((prev) => {\n const updated = prev.map((e) => (e.id === entry.id ? (left.length ? { ...e, audits: left } : { ...e, undone: true }) : e));\n const now = new Date();\n const added: StudioActivity[] = [];\n if (left.length) {\n added.push({ id: `${now.getTime()}-undo-failed`, at: now, resource: entry.resource, field: entry.field, record: `${left.length} rows`, outcome: \"not_saved\", message: `${left.length} of ${audits.length} rows weren't undone: ${errorText(firstError)}` });\n }\n if (done) {\n added.push({ id: `${now.getTime()}-undo`, at: now, resource: entry.resource, field: entry.field, record: `${done} rows`, outcome: \"saved\", action: \"update\", message: \"Undone, each row with its own audit entry.\" });\n }\n return [...added, ...updated].slice(0, 50);\n });\n },\n [provider, queryClient, sessionKey],\n );\n\n const undoOne = useCallback(\n async (entry: StudioActivity) => {\n if (entry.audits?.length) return undoAll(entry, entry.audits);\n try {\n const result = await provider.undo!(entry.resource, { auditId: entry.audit!.id });\n setActivity((prev) => prev.map((e) => (e.id === entry.id ? { ...e, undone: true } : e)));\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey] });\n setActivity((prev) =>\n [\n {\n id: `${Date.now()}-undo`,\n at: new Date(),\n resource: entry.resource,\n field: entry.field,\n record: entry.record,\n outcome: \"saved\" as const,\n action: \"update\" as const,\n message: \"Undone, with its own audit entry.\",\n ...(result.audit ? { audit: result.audit, undone: true } : {}),\n },\n ...prev,\n ].slice(0, 50),\n );\n } catch (error) {\n setActivity((prev) =>\n [\n {\n id: `${Date.now()}-undo-failed`,\n at: new Date(),\n resource: entry.resource,\n field: entry.field,\n record: entry.record,\n outcome: \"not_saved\" as const,\n message: errorText(error),\n },\n ...prev,\n ].slice(0, 50),\n );\n }\n },\n [provider, queryClient, sessionKey, undoAll],\n );\n\n /**\n * Undo a change from its audit entry: a compensating write, itself\n * audited, that the server refuses if the row has moved on since.\n */\n const undo = useCallback(\n async (entry: StudioActivity) => {\n if (!provider.undo || entry.undone || undoing.current.has(entry.id)) return;\n if (!entry.audit && !entry.audits?.length) return;\n undoing.current.add(entry.id);\n try {\n await undoOne(entry);\n } finally {\n undoing.current.delete(entry.id);\n }\n },\n [provider, undoOne],\n );\n\n const record = useCallback((entry: Omit<StudioActivity, \"id\" | \"at\">) => {\n setActivity((prev) =>\n [{ ...entry, id: `${Date.now()}-${Math.random().toString(36).slice(2)}`, at: new Date() }, ...prev].slice(0, 50),\n );\n }, []);\n\n if (signedOut) {\n return (\n <div className={cn(\"flex min-h-[320px] items-center justify-center p-6\", className)} data-testid=\"studio-sign-in\">\n {signIn ?? <p className=\"text-sm text-muted-foreground\">Sign in to use the studio.</p>}\n </div>\n );\n }\n\n const selected = router.location.resource;\n const list = resources.data ?? [];\n\n return (\n <div className={cn(\"w-full space-y-3\", className)}>\n <div className={variant === \"card\" ? \"overflow-hidden rounded-lg border bg-background\" : \"min-w-0\"} data-testid=\"studio\" data-variant={variant}>\n {(title !== null || resources.isLoading || resources.isError) && (\n <div className={cn(\"flex items-center gap-2\", variant === \"card\" ? \"border-b px-3 py-2\" : \"pb-3\")}>\n {title !== null &&\n (variant === \"card\" ? (\n <>\n <Database className=\"h-4 w-4 text-muted-foreground\" aria-hidden />\n <span className=\"text-sm font-semibold\">{title}</span>\n </>\n ) : (\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n ))}\n {resources.isLoading && <span className=\"text-xs text-muted-foreground\">Loading tables…</span>}\n {resources.isError && (\n <span role=\"alert\" className=\"text-xs text-destructive\">\n {errorText(resources.error)}\n </span>\n )}\n </div>\n )}\n <TableTabs resources={list} selected={selected} onSelect={(resource) => router.navigate({ resource })} variant={variant} />\n <main className=\"min-w-0\" data-testid=\"studio-main\">\n {selected ? (\n <Sheet\n key={selected}\n provider={provider}\n resource={selected}\n sessionKey={sessionKey}\n router={router}\n perPage={perPage}\n onActivity={record}\n onSignedOut={() => setSignedOut(true)}\n formConfig={forms?.[selected]}\n onUndoLatest={() => {\n const latest = activity.find((e) => e.resource === selected && e.outcome === \"saved\" && ((e.audit && e.audit.action !== \"run\") || e.audits?.length) && !e.undone);\n if (latest) void undo(latest);\n }}\n />\n ) : (\n <div\n className=\"flex min-h-[320px] flex-col items-center justify-center gap-2 p-8 text-center text-muted-foreground\"\n data-testid=\"studio-empty\"\n >\n <Table2 className=\"h-6 w-6\" aria-hidden />\n <p className=\"text-sm\">{list.length ? \"Pick a table to open it.\" : \"No tables to show yet.\"}</p>\n </div>\n )}\n </main>\n </div>\n <ActivityPanel entries={activity} onUndo={provider.undo ? (entry) => void undo(entry) : undefined} />\n </div>\n );\n}\n\nfunction Sheet({\n provider,\n resource,\n sessionKey,\n router,\n perPage,\n onActivity,\n onSignedOut,\n formConfig,\n onUndoLatest,\n}: {\n provider: DataProvider;\n resource: string;\n sessionKey: string | number | null;\n router: StudioRouter;\n perPage: number;\n onActivity: (entry: Omit<StudioActivity, \"id\" | \"at\">) => void;\n onSignedOut: () => void;\n formConfig?: StudioFormConfig;\n onUndoLatest: () => void;\n}) {\n const queryClient = useQueryClient();\n const { location } = router;\n const page = location.page ?? 1;\n const sorts = useMemo(() => parseSorts(location.sort), [location.sort]);\n const filters = useMemo(() => parseFilters(location.filters), [location.filters]);\n const search = location.search ?? \"\";\n const group = location.group;\n const [creating, setCreating] = useState(false);\n const [exporting, setExporting] = useState<number | null>(null);\n const [notice, setNotice] = useState<string | null>(null);\n // Bumped to remount the page after a saved view sets column visibility.\n const [viewEpoch, setViewEpoch] = useState(0);\n const [bulkIds, setBulkIds] = useState<string[] | null>(null);\n const view = location.view ?? \"table\";\n const sheetView = view === \"sheet\";\n const savedViews = useSavedViews(`genesis-studio:views:${resource}`);\n const hiddenKey = `genesis-studio:hidden:${resource}`;\n const [hidden, setHiddenState] = useState<Set<string>>(() => {\n try {\n const stored = JSON.parse(localStorage.getItem(hiddenKey) ?? \"[]\");\n return new Set(Array.isArray(stored) ? stored.filter((x): x is string => typeof x === \"string\") : []);\n } catch {\n return new Set();\n }\n });\n const setHidden = useCallback(\n (next: Set<string>) => {\n setHiddenState(next);\n try {\n localStorage.setItem(hiddenKey, JSON.stringify([...next]));\n } catch {\n // Hidden fields are a convenience; the grid works without storage.\n }\n },\n [hiddenKey],\n );\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [searchDraft, setSearchDraft] = useState(location.search ?? \"\");\n\n const schemaQuery = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"describe\", resource],\n queryFn: () => {\n if (!provider.describe) throw new Error(\"This data provider can't describe its resources.\");\n return provider.describe(resource);\n },\n retry: false,\n });\n const schema = schemaQuery.data;\n const capabilities = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"capabilities\", resource],\n enabled: Boolean(provider.capabilities),\n retry: false,\n queryFn: () => provider.capabilities!(resource),\n }).data;\n\n // Grouping sorts by the group field first, so each group is contiguous.\n const effectiveSorts = useMemo(\n () => (group ? [{ field: group, order: \"asc\" as const }, ...sorts.filter((s) => s.field !== group)] : sorts),\n [group, sorts],\n );\n const listKey = useMemo(\n () => [\"genesis-studio\", sessionKey, \"list\", resource, page, perPage, location.sort ?? \"\", search, location.filters ?? \"\", group ?? \"\"],\n [sessionKey, resource, page, perPage, location.sort, search, location.filters, group],\n );\n const keyed = Boolean(schema && keyFields(schema).length > 0);\n const boardChoices = schema ? boardFields(schema) : [];\n const dateChoices = schema ? dateFields(schema) : [];\n const keyedView = (view === \"kanban\" || view === \"calendar\") && keyed;\n const viewChoices = view === \"kanban\" ? boardChoices : view === \"calendar\" ? dateChoices : [];\n const viewField = viewChoices.find((f) => f.name === location.by) ?? viewChoices[0];\n const altView = keyedView && viewField ? view : null;\n const listQuery = useQuery({\n queryKey: listKey,\n // A board or calendar makes its own requests; the grid's page isn't needed then.\n enabled: Boolean(schema) && !altView,\n placeholderData: keepPreviousData,\n retry: false,\n queryFn: () =>\n provider.getList<BaseRecord>(resource, {\n pagination: { page, perPage },\n sort: effectiveSorts[0],\n sorts: effectiveSorts,\n filters,\n search: search ? { query: search, fields: [] } : undefined,\n }),\n });\n\n const failure = schemaQuery.error ?? listQuery.error;\n useEffect(() => {\n if (isUnauthenticated(failure)) onSignedOut();\n }, [failure, onSignedOut]);\n\n // Debounce search into the URL; typing replaces rather than pushes history.\n const searchTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n useEffect(() => () => clearTimeout(searchTimer.current), []);\n const navigate = useCallback(\n (patch: Partial<StudioLocation>, replace = false) => router.navigate({ ...location, resource, ...patch }, { replace }),\n [router, location, resource],\n );\n\n const rows = (listQuery.data?.data ?? []) as Row[];\n const keys = useMemo(() => {\n const map = new Map<Row, string>();\n rows.forEach((row, index) => map.set(row, schema && keyed ? String(encodeRecordKey(schema, row)) : `row-${index}`));\n return map;\n }, [rows, schema, keyed]);\n const linkLabels = usePageLinkLabels(provider, sessionKey, schema?.fields ?? [], rows);\n\n const replaceRow = useCallback(\n (oldRow: Row, next: Row) => {\n queryClient.setQueryData(listKey, (prev: { data: Row[]; total: number } | undefined) =>\n prev ? { ...prev, data: prev.data.map((r) => (r === oldRow ? next : r)) } : prev,\n );\n },\n [queryClient, listKey],\n );\n const refresh = useCallback(() => {\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey, \"list\", resource] });\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey, \"history\", resource] });\n }, [queryClient, sessionKey, resource]);\n\n const openRecord = useCallback(\n (target: string, id: string) =>\n target === resource ? navigate({ record: id }) : router.navigate({ resource: target, record: id }),\n [navigate, router, resource],\n );\n\n // Stable while the schema is, so a background refetch doesn't reset the\n // new-row form under the user's typing.\n const createFields = useMemo(() => new Set(schema?.createFields ?? []), [schema]);\n const fieldsForCreate = useMemo(() => schema?.fields.filter((f) => createFields.has(f.name)) ?? [], [schema, createFields]);\n // A selection belongs to the rows on screen: a new page, filter, search or\n // sort starts with none, so a bulk action never reaches rows out of view.\n // (Declared before the early returns below, as every hook must be.)\n const listIdentity = JSON.stringify(listKey);\n useEffect(() => {\n setSelected(new Set());\n }, [listIdentity]);\n\n async function runExport() {\n if (!schema) return;\n setExporting(0);\n setNotice(null);\n try {\n const { csv, rows: count, truncated } = await exportCsv({\n provider,\n resource,\n fields: schema.fields,\n sorts: effectiveSorts,\n filters,\n search,\n onProgress: setExporting,\n });\n downloadText(`${resource}.csv`, csv);\n setNotice(\n truncated\n ? `Exported the first ${count.toLocaleString()} matching rows. Narrow the list to export the rest.`\n : `Exported ${count.toLocaleString()} rows.`,\n );\n } catch (error) {\n setNotice(`Export failed: ${errorText(error)}`);\n } finally {\n setExporting(null);\n }\n }\n\n async function create(values: Record<string, unknown>) {\n if (!schema) return;\n try {\n const result = await provider.create<BaseRecord>(resource, { data: values as never });\n setCreating(false);\n refresh();\n const id = String(encodeRecordKey(schema, result.data as Row));\n onActivity({ resource, field: \"\", record: id, outcome: \"saved\", action: \"create\", message: result.audit ? \"Added, with its audit entry.\" : \"Added.\", ...(result.audit ? { audit: result.audit } : {}) });\n navigate({ record: id });\n } catch (error) {\n if (isUnauthenticated(error)) onSignedOut();\n onActivity({ resource, field: \"\", record: \"new row\", outcome: \"not_saved\", action: \"create\", message: errorText(error) });\n throw error;\n }\n }\n\n if (schemaQuery.isError && !isUnauthenticated(schemaQuery.error)) {\n return (\n <Alert variant=\"destructive\" data-testid=\"studio-describe-error\">\n <AlertTitle>Couldn't open {resource}</AlertTitle>\n <AlertDescription>{errorText(schemaQuery.error)}</AlertDescription>\n </Alert>\n );\n }\n\n const editable = schema?.fields.filter((f) => f.permissions?.update).length ?? 0;\n\n const gridView = !altView;\n const pageCount = Math.max(1, Math.ceil((listQuery.data?.total ?? 0) / perPage));\n const total = listQuery.data?.total ?? 0;\n const selectable = Boolean(schema && keyed && ((schema.access.update && provider.updateMany) || (schema.access.delete && provider.deleteMany)));\n const toggleSelect = (id: string) =>\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n const pageIds = rows.map((r) => keys.get(r) ?? \"\");\n const toggleAll = () =>\n setSelected((prev) => (pageIds.every((id) => prev.has(id)) ? new Set() : new Set(pageIds)));\n const canAdd = Boolean(schema?.access.create);\n\n async function deleteSelected() {\n if (!schema) return;\n const ids = [...selected];\n const chosen = rows.filter((r) => ids.includes(keys.get(r) ?? \"\"));\n // Never act on fewer rows than were confirmed.\n if (chosen.length !== ids.length) {\n setSelected(new Set());\n setNotice(\"Some selected rows aren't on this page any more. Select the rows again.\");\n return;\n }\n if (!window.confirm(`Delete ${ids.length} record${ids.length === 1 ? \"\" : \"s\"}? All of them go, or none do.`)) return;\n let result;\n try {\n result = await provider.deleteMany!(resource, {\n items: chosen.map((r) => ({ id: encodeRecordKey(schema, r), expectedVersion: versionOf(schema, r) })),\n });\n } catch (error) {\n if (isUnauthenticated(error)) onSignedOut();\n refresh();\n const message = `Nothing was deleted: ${errorText(error)}`;\n setNotice(message);\n onActivity({ resource, field: \"\", record: `${ids.length} rows`, outcome: \"not_saved\", action: \"delete\", message });\n return;\n }\n refresh();\n setSelected(new Set());\n if (result.ok) {\n setNotice(`Deleted ${result.count} records in one transaction.`);\n // One entry holds every row's audit, so one Undo reaches them all.\n onActivity({\n resource,\n field: \"\",\n record: `${result.count} rows`,\n outcome: \"saved\",\n action: \"delete\",\n message: \"Deleted, each row audited.\",\n ...(result.audit?.length ? { audits: result.audit } : {}),\n });\n } else {\n const message = `Nothing was deleted: ${(result.failures ?? []).length} of ${ids.length} records couldn't be (${result.failures?.[0]?.message ?? \"\"}).`;\n setNotice(message);\n onActivity({ resource, field: \"\", record: `${ids.length} rows`, outcome: \"not_saved\", action: \"delete\", message });\n }\n }\n\n const gridFor = (items: Row[], firstRowNumber: number, label?: string, withFooter = true) =>\n schema && (\n <SheetView\n provider={provider}\n schema={schema}\n rows={items}\n keys={keys}\n linkLabels={linkLabels}\n hidden={hidden}\n label={label}\n firstRowNumber={firstRowNumber}\n {...(selectable ? { selected, onToggleSelect: toggleSelect, onToggleAll: toggleAll } : {})}\n onOpenRecord={keyed ? (id) => navigate({ record: id }) : undefined}\n footer={\n withFooter && canAdd ? (\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-sm text-muted-foreground hover:bg-muted/40 hover:text-foreground\"\n onClick={() => setCreating(true)}\n data-testid=\"studio-add-record\"\n >\n <Plus className=\"h-3.5 w-3.5\" aria-hidden />\n Add a record\n </button>\n ) : undefined\n }\n onSaved={(updates) => {\n if (updates.length === 1) replaceRow(updates[0]!.old, updates[0]!.next);\n else refresh();\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey, \"record\", resource] });\n const fieldsOf = (audit?: AuditEntry) => Object.keys(audit?.after ?? {}).filter((f) => f !== schema.version?.field);\n if (updates.length === 1) {\n const u = updates[0]!;\n onActivity({\n resource,\n field: fieldsOf(u.audit).join(\", \"),\n record: keys.get(u.old) ?? \"\",\n outcome: \"saved\",\n message: u.audit ? \"Saved, with its audit entry.\" : \"Saved.\",\n ...(u.audit ? { audit: u.audit } : {}),\n });\n } else {\n // A multi-row paste is one bulk write: one entry, one Undo for every row.\n const audits = updates.flatMap((u) => (u.audit ? [u.audit] : []));\n onActivity({\n resource,\n field: [...new Set(audits.flatMap(fieldsOf))].join(\", \"),\n record: `${updates.length} rows`,\n outcome: \"saved\",\n message: audits.length ? \"Saved, each row audited.\" : \"Saved.\",\n ...(audits.length ? { audits } : {}),\n });\n }\n }}\n onFailed={(message) => {\n refresh();\n onActivity({ resource, field: \"\", record: \"\", outcome: \"not_saved\", message });\n }}\n onUndo={onUndoLatest}\n onNotice={setNotice}\n />\n );\n\n return (\n <div className=\"flex min-h-[480px] flex-col md:flex-row\" data-testid=\"studio-sheet\">\n {schema && (\n <ViewsPanel\n view={altView ?? \"grid\"}\n available={{ grid: true, kanban: keyed && boardChoices.length > 0, calendar: keyed && dateChoices.length > 0 }}\n onChange={(next) => navigate({ view: next === \"grid\" ? undefined : next, by: undefined, month: undefined, record: undefined })}\n saved={savedViews.savedViews}\n onDelete={savedViews.deleteView}\n onSave={(name) =>\n savedViews.saveView(name, {\n sort: location.sort ?? null,\n search: location.search ?? null,\n filters: location.filters ?? null,\n group: location.group ?? null,\n view: location.view ?? null,\n by: location.by ?? null,\n hidden: [...hidden],\n })\n }\n onLoad={(item) => {\n const view = savedViews.loadViewFilters(item.id) ?? {};\n if (Array.isArray(view.hidden)) setHidden(new Set(view.hidden.filter((x): x is string => typeof x === \"string\")));\n const str = (v: unknown) => (typeof v === \"string\" ? v : undefined);\n const nextView = str(view.view);\n setSearchDraft(str(view.search) ?? \"\");\n router.navigate({\n resource,\n sort: str(view.sort),\n search: str(view.search),\n filters: str(view.filters),\n group: str(view.group),\n view: nextView === \"kanban\" || nextView === \"calendar\" ? nextView : undefined,\n by: str(view.by),\n });\n }}\n />\n )}\n <div className=\"min-w-0 flex-1 space-y-2 p-2 md:p-3\">\n {schema && !schema.access.update && (\n <p className=\"flex items-center gap-1.5 text-xs text-muted-foreground\" data-testid=\"studio-read-only\">\n <Lock className=\"h-3.5 w-3.5\" aria-hidden />\n Read-only: {(schema.access.reason ?? \"you can view this table but not edit it.\").replace(/^Read-only: /, \"\")}\n </p>\n )}\n {schema && (\n <div className=\"flex flex-wrap items-center gap-1\" data-testid=\"studio-toolbar\">\n {selected.size === 0 && gridView && <HideFields fields={gridFields(schema)} hidden={hidden} onChange={setHidden} />}\n {selected.size === 0 && (capabilities?.filterOperators?.length ?? 1) > 0 && (\n <FilterBuilder fields={schema.fields} filters={filters} onChange={(next) => navigate({ filters: formatFilters(next), page: 1 })} />\n )}\n {selected.size === 0 && gridView && <GroupPicker fields={schema.fields} group={group} onChange={(next) => navigate({ group: next, page: 1 })} />}\n {selected.size === 0 && capabilities?.sort !== false && (\n <SortBuilder fields={schema.fields} sorts={sorts} onChange={(next) => navigate({ sort: formatSorts(next), page: 1 })} />\n )}\n {altView && viewField && (\n <ViewFieldPicker\n label={altView === \"kanban\" ? \"Columns by\" : \"Dates by\"}\n fields={viewChoices}\n value={viewField.name}\n onChange={(by) => navigate({ by })}\n />\n )}\n {selected.size > 0 && (\n <span className=\"flex items-center gap-1 rounded-md bg-muted px-2 text-sm\" data-testid=\"studio-selection\">\n {selected.size} selected\n {schema.access.update && provider.updateMany && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" testID=\"studio-bulk-set\" onClick={() => setBulkIds([...selected])}>\n <PencilLine className=\"mr-1 h-3.5 w-3.5\" aria-hidden />\n Set a field…\n </Button>\n )}\n {schema.access.delete && provider.deleteMany && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"text-destructive\" testID=\"studio-bulk-delete\" onClick={() => void deleteSelected()}>\n <Trash2 className=\"mr-1 h-3.5 w-3.5\" aria-hidden />\n Delete\n </Button>\n )}\n <button type=\"button\" aria-label=\"Clear the selection\" className=\"rounded p-0.5 hover:bg-background\" onClick={() => setSelected(new Set())}>\n <X className=\"h-3.5 w-3.5\" aria-hidden />\n </button>\n </span>\n )}\n <span className=\"ml-auto flex items-center gap-1\">\n <SearchBox\n value={searchDraft}\n onChange={(text) => {\n setSearchDraft(text);\n clearTimeout(searchTimer.current);\n searchTimer.current = setTimeout(() => navigate({ search: text || undefined, page: 1 }, true), SEARCH_DEBOUNCE_MS);\n }}\n />\n <ExportButton onExport={() => void runExport()} busy={exporting !== null} progress={exporting ?? 0} />\n {schema.access.create !== undefined && (\n <ImportDialog\n provider={provider}\n schema={schema}\n onImported={(count) => {\n refresh();\n setNotice(`Imported ${count.toLocaleString()} rows in one transaction.`);\n onActivity({ resource, field: \"\", record: `${count} rows`, outcome: \"saved\", action: \"create\", message: \"Imported, each row audited.\" });\n }}\n />\n )}\n {schema.access.create !== undefined && (\n <NewRowButton allowed={canAdd} reason={schema.access.reasons?.create} onClick={() => setCreating(true)} />\n )}\n </span>\n </div>\n )}\n {notice && (\n <p className=\"text-xs text-muted-foreground\" role=\"status\" data-testid=\"studio-notice\">\n {notice}\n </p>\n )}\n {schema && altView === \"kanban\" && viewField && (\n <KanbanView\n key={`${viewField.name}|${location.filters ?? \"\"}|${search}|${location.sort ?? \"\"}`}\n provider={provider}\n schema={schema}\n sessionKey={sessionKey}\n field={viewField}\n filters={filters}\n sorts={sorts}\n search={search}\n onOpenRecord={(id) => navigate({ record: id })}\n onMoved={(record, audit) => {\n refresh();\n onActivity({ resource, field: viewField.name, record, outcome: \"saved\", message: audit ? \"Moved, with its audit entry.\" : \"Moved.\", ...(audit ? { audit } : {}) });\n }}\n onFailed={(record, message) => {\n refresh();\n onActivity({ resource, field: viewField.name, record, outcome: \"not_saved\", message });\n }}\n onSignedOut={onSignedOut}\n />\n )}\n {schema && altView === \"calendar\" && viewField && (\n <CalendarView\n provider={provider}\n schema={schema}\n sessionKey={sessionKey}\n field={viewField}\n month={location.month}\n onMonthChange={(month) => navigate({ month })}\n filters={filters}\n sorts={sorts}\n search={search}\n onOpenRecord={(id) => navigate({ record: id })}\n onSignedOut={onSignedOut}\n />\n )}\n {gridView && (\n <div className=\"space-y-3\" data-testid=\"studio-grid\">\n {(schemaQuery.isLoading || listQuery.isLoading) && <p className=\"px-1 py-6 text-sm text-muted-foreground\">Loading…</p>}\n {listQuery.isError && !isUnauthenticated(listQuery.error) && (\n <Alert variant=\"destructive\">\n <AlertTitle>Couldn't load the records</AlertTitle>\n <AlertDescription>\n {errorText(listQuery.error)}{\" \"}\n <button type=\"button\" className=\"underline\" onClick={() => void listQuery.refetch()}>\n Try again\n </button>\n </AlertDescription>\n </Alert>\n )}\n {schema && listQuery.data && !group && gridFor(rows, (page - 1) * perPage + 1)}\n {schema && listQuery.data && group && (\n <div className=\"space-y-4\" data-testid=\"studio-groups\">\n {groupRows(rows, group).map(([value, groupItems]) => {\n const field = schema.fields.find((f) => f.name === group);\n return (\n <section key={value ?? \"__none\"} data-testid=\"studio-group-section\" className=\"space-y-1\">\n <h3 className=\"flex items-center gap-2 text-sm\">\n <span className=\"text-muted-foreground\">{field ? fieldLabel(field) : group}</span>\n {value === null ? (\n <span className=\"text-muted-foreground\">Empty</span>\n ) : field ? (\n <CellValue field={field} value={value} />\n ) : (\n value\n )}\n <span className=\"text-xs text-muted-foreground\">{groupItems.length}</span>\n </h3>\n {gridFor(groupItems, rows.indexOf(groupItems[0]!) + (page - 1) * perPage + 1, `${schema.label ?? resource}: ${value ?? \"empty\"}`, false)}\n </section>\n );\n })}\n </div>\n )}\n {listQuery.data && (\n <div className=\"flex items-center gap-2 px-1 text-xs text-muted-foreground\" data-testid=\"studio-footer\">\n <span>\n {total.toLocaleString()} record{total === 1 ? \"\" : \"s\"}\n </span>\n {pageCount > 1 && (\n <span className=\"ml-auto flex items-center gap-1\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={page <= 1} onClick={() => navigate({ page: page - 1 })} aria-label=\"Previous page\">\n <ChevronLeft className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n Page {page} of {pageCount}\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={page >= pageCount} onClick={() => navigate({ page: page + 1 })} aria-label=\"Next page\">\n <ChevronRight className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n </span>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n {schema && location.record && (\n <RecordPanel\n provider={provider}\n sessionKey={sessionKey}\n schema={schema}\n id={location.record}\n onClose={() => navigate({ record: undefined })}\n onOpenRecord={openRecord}\n formConfig={formConfig}\n onUndone={(audit) => {\n refresh();\n onActivity({ resource, field: \"\", record: location.record!, outcome: \"saved\", message: \"Undone, with its own audit entry.\", ...(audit ? { audit, undone: true } : {}) });\n }}\n onSaved={(row, audit) => {\n refresh();\n onActivity({ resource, field: Object.keys(audit?.after ?? {}).join(\", \"), record: location.record!, outcome: \"saved\", message: audit ? \"Saved, with its audit entry.\" : \"Saved.\", ...(audit ? { audit } : {}) });\n void row;\n }}\n onActionRan={(action, row, audit) => {\n refresh();\n onActivity({\n resource,\n field: \"\",\n record: location.record!,\n outcome: \"saved\",\n message: `${action.label}: done${row ? \"\" : \", and the row is gone\"}${audit ? \", with its audit entry\" : \"\"}.`,\n ...(audit ? { audit } : {}),\n });\n }}\n onDeleted={(audit) => {\n refresh();\n onActivity({ resource, field: \"\", record: location.record!, outcome: \"saved\", action: \"delete\", message: audit ? \"Deleted, with its audit entry.\" : \"Deleted.\", ...(audit ? { audit } : {}) });\n }}\n onFailed={(action, message) =>\n onActivity({ resource, field: \"\", record: location.record!, outcome: \"not_saved\", action: action === \"delete\" ? \"delete\" : \"update\", message })\n }\n />\n )}\n {schema && bulkIds && (\n <BulkEditDialog\n schema={schema}\n count={bulkIds.length}\n open\n onOpenChange={(open) => !open && setBulkIds(null)}\n onApply={async (data) => {\n const chosen = rows.filter((r) => bulkIds.includes(keys.get(r) ?? \"\"));\n if (chosen.length !== bulkIds.length) {\n throw new Error(\"Some selected rows aren't on this page any more. Select the rows again.\");\n }\n const result = await provider.updateMany!(resource, {\n changes: chosen.map((r) => ({ id: encodeRecordKey(schema, r), data, expectedVersion: versionOf(schema, r) })),\n });\n refresh();\n if (result.ok) {\n setNotice(`Saved ${result.count} rows in one transaction.`);\n onActivity({\n resource,\n field: Object.keys(data).join(\", \"),\n record: `${result.count} rows`,\n outcome: \"saved\",\n message: \"Saved, each row audited.\",\n ...(result.audit?.length ? { audits: result.audit } : {}),\n });\n }\n return result;\n }}\n />\n )}\n {schema && (\n <Dialog open={creating} onOpenChange={setCreating}>\n <DialogContent className=\"max-h-[85vh] overflow-y-auto sm:max-w-lg\" data-testid=\"studio-create-dialog\">\n <DialogHeader>\n <DialogTitle>New {schema.label ?? resource} row</DialogTitle>\n <DialogDescription>Only fields you may set are shown. The new row is audited.</DialogDescription>\n </DialogHeader>\n <RecordForm\n provider={provider}\n sessionKey={sessionKey}\n mode=\"create\"\n fields={fieldsForCreate}\n editable={createFields}\n onSubmit={create}\n submitLabel=\"Add row\"\n onCancel={() => setCreating(false)}\n config={formConfig}\n />\n </DialogContent>\n </Dialog>\n )}\n </div>\n );\n}\n\nfunction versionOf(schema: ResourceSchema, row: Row): string | null {\n const field = schema.version?.field;\n return field && row[field] != null ? String(row[field]) : null;\n}\n\nconst NO_ACTIONS = {\n update: async () => {\n throw new Error(\"Not available here.\");\n },\n remove: async () => {\n throw new Error(\"Not available here.\");\n },\n refetch: () => {},\n};\n\n/** Rows of one page split by a field's value, in the order they arrived. */\nfunction groupRows(items: Row[], field: string): Array<[string | null, Row[]]> {\n const groups = new Map<string | null, Row[]>();\n for (const item of items) {\n const value = displayText(item[field]);\n if (!groups.has(value)) groups.set(value, []);\n groups.get(value)!.push(item);\n }\n return [...groups.entries()];\n}\n\nfunction schemaSubtitle(schema: ResourceSchema | undefined, editable: number): string | undefined {\n if (!schema) return undefined;\n const parts = [schema.name];\n if (schema.access.update) parts.push(`${editable} of ${schema.fields.length} fields editable`);\n if (schema.version) parts.push(`edits checked against ${schema.version.field}`);\n return parts.join(\" · \");\n}\n\nconst OUTCOME_LABEL = {\n update: { saved: \"Saved\", not_saved: \"Not saved\" },\n create: { saved: \"Added\", not_saved: \"Not added\" },\n delete: { saved: \"Deleted\", not_saved: \"Not deleted\" },\n} as const;\n\nfunction ActivityPanel({ entries, onUndo }: { entries: StudioActivity[]; onUndo?: (entry: StudioActivity) => void }) {\n return (\n <details aria-label=\"This session's edits\" className=\"group rounded-lg border bg-card\" data-testid=\"studio-activity\">\n <summary className=\"flex cursor-pointer list-none items-center gap-2 px-3 py-2 text-sm font-medium group-open:border-b\">\n <History className=\"h-4 w-4 text-muted-foreground\" aria-hidden />\n This session's edits\n {entries.length > 0 && <span className=\"text-xs font-normal text-muted-foreground\">{entries.length}</span>}\n {entries[0] && (\n <span className={cn(\"ml-2 truncate text-xs font-normal\", entries[0].outcome === \"saved\" ? \"text-muted-foreground\" : \"text-destructive\")}>\n {entries[0].message}\n </span>\n )}\n </summary>\n {entries.length === 0 ? (\n <p className=\"px-3 py-3 text-xs text-muted-foreground\">\n Click a cell to edit it. Each save is checked against the latest version of the row, and audited.\n </p>\n ) : (\n <ol className=\"divide-y\" aria-live=\"polite\">\n {entries.map((entry) => (\n <li key={entry.id} className=\"px-3 py-2 text-xs\" data-testid={`studio-activity-${entry.outcome}`}>\n <div className=\"flex flex-wrap items-baseline gap-x-2\">\n <span className={entry.outcome === \"saved\" ? \"font-medium text-foreground\" : \"font-medium text-destructive\"}>\n {OUTCOME_LABEL[entry.action ?? \"update\"][entry.outcome]}\n </span>\n <span className=\"text-muted-foreground\">\n {[entry.resource, entry.field, entry.record].filter(Boolean).join(\" · \")}\n </span>\n <time className=\"ml-auto text-muted-foreground\" dateTime={entry.at.toISOString()}>\n {entry.at.toLocaleTimeString()}\n </time>\n {onUndo && entry.outcome === \"saved\" && ((entry.audit && entry.audit.action !== \"run\") || entry.audits?.length) && !entry.undone && (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[11px] text-muted-foreground hover:bg-muted hover:text-foreground\"\n onClick={() => onUndo(entry)}\n data-testid=\"studio-activity-undo\"\n >\n <Undo2 className=\"h-3 w-3\" aria-hidden />\n {entry.audits?.length ? `Undo all ${entry.audits.length}` : \"Undo\"}\n </button>\n )}\n </div>\n <p className=\"mt-0.5 text-muted-foreground\">{entry.message}</p>\n {entry.audit && <AuditLine audit={entry.audit} />}\n </li>\n ))}\n </ol>\n )}\n </details>\n );\n}\n\nfunction AuditLine({ audit }: { audit: AuditEntry }) {\n const changes = Object.keys(audit.after ?? {}).map((field) => ({\n field,\n before: displayText(audit.before?.[field]) ?? \"—\",\n after: displayText(audit.after?.[field]) ?? \"—\",\n }));\n return (\n <div className=\"mt-1 rounded bg-muted/50 px-2 py-1 font-mono text-[11px]\" data-testid=\"studio-audit-entry\">\n <div className=\"text-muted-foreground\">\n audit {audit.id.slice(0, 8)} · {audit.occurredAt} · by {audit.actor ?? \"unknown\"}\n </div>\n {changes.map((c) => (\n <div key={c.field}>\n {c.field}: {c.before} → {c.after}\n </div>\n ))}\n </div>\n );\n}\n","// ---------------------------------------------------------------------------\n// Routing and URL state come from the host app (DATA-STUDIO.md decision 23).\n//\n// The studio never touches `window.location` itself. It reads a\n// `StudioLocation` and asks for a new one; the adapter decides how that maps\n// onto the app's router, so a link to \"clients, page 3, sorted by name\" is a\n// plain URL the app already knows how to serve.\n// ---------------------------------------------------------------------------\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\n\n/** Everything the studio keeps in the URL. */\nexport interface StudioLocation {\n /** `schema.table`, e.g. `public.clients`. */\n resource?: string;\n /** 1-based. */\n page?: number;\n /** `field:asc` or `field:desc`; several, comma-separated, sort by each in turn. */\n sort?: string;\n search?: string;\n /** Filters, as a JSON array of `[field, operator, value?]`. */\n filters?: string;\n /** Group rows by this field. */\n group?: string;\n /** The open record's id (`encodeRecordKey`), for a copyable link to it. */\n record?: string;\n /** `sheet`, `kanban` or `calendar`; the table otherwise. */\n view?: StudioView;\n /** For `kanban` and `calendar`: the field that places each row. */\n by?: string;\n /** For `calendar`: the month shown, `YYYY-MM`. */\n month?: string;\n}\n\n/** The views other than the table. */\nexport type StudioView = \"sheet\" | \"kanban\" | \"calendar\";\nconst VIEWS: readonly string[] = [\"sheet\", \"kanban\", \"calendar\"];\n\nexport interface StudioNavigateOptions {\n /** Replace the current history entry instead of pushing one (e.g. while typing a search). */\n replace?: boolean;\n}\n\nexport interface StudioRouter {\n location: StudioLocation;\n navigate(next: StudioLocation, options?: StudioNavigateOptions): void;\n}\n\n/** Query parameter names. Short, and namespaced enough not to collide with an app's own. */\nconst PARAM = {\n resource: \"table\",\n page: \"page\",\n sort: \"sort\",\n search: \"q\",\n filters: \"filter\",\n group: \"group\",\n record: \"record\",\n view: \"view\",\n by: \"by\",\n month: \"month\",\n} as const;\n\nexport function locationFromSearchParams(params: URLSearchParams): StudioLocation {\n const page = Number(params.get(PARAM.page));\n return {\n ...(params.get(PARAM.resource) ? { resource: params.get(PARAM.resource)! } : {}),\n ...(Number.isInteger(page) && page > 1 ? { page } : {}),\n ...(params.get(PARAM.sort) ? { sort: params.get(PARAM.sort)! } : {}),\n ...(params.get(PARAM.search) ? { search: params.get(PARAM.search)! } : {}),\n ...(params.get(PARAM.filters) ? { filters: params.get(PARAM.filters)! } : {}),\n ...(params.get(PARAM.group) ? { group: params.get(PARAM.group)! } : {}),\n ...(params.get(PARAM.record) ? { record: params.get(PARAM.record)! } : {}),\n ...(VIEWS.includes(params.get(PARAM.view) ?? \"\") ? { view: params.get(PARAM.view) as StudioView } : {}),\n ...(params.get(PARAM.by) ? { by: params.get(PARAM.by)! } : {}),\n ...(/^\\d{4}-\\d{2}$/.test(params.get(PARAM.month) ?? \"\") ? { month: params.get(PARAM.month)! } : {}),\n };\n}\n\n/**\n * The studio's location as query parameters, keeping every parameter in\n * `base` that isn't the studio's own.\n */\nexport function searchParamsFromLocation(location: StudioLocation, base?: URLSearchParams): URLSearchParams {\n const params = new URLSearchParams(base);\n for (const name of Object.values(PARAM)) params.delete(name);\n if (location.resource) params.set(PARAM.resource, location.resource);\n if (location.page && location.page > 1) params.set(PARAM.page, String(location.page));\n if (location.sort) params.set(PARAM.sort, location.sort);\n if (location.search) params.set(PARAM.search, location.search);\n if (location.filters) params.set(PARAM.filters, location.filters);\n if (location.group) params.set(PARAM.group, location.group);\n if (location.record) params.set(PARAM.record, location.record);\n if (location.view) params.set(PARAM.view, location.view);\n if (location.by) params.set(PARAM.by, location.by);\n if (location.month) params.set(PARAM.month, location.month);\n return params;\n}\n\n/**\n * An adapter over any router that exposes search params with a setter —\n * React Router's `useSearchParams`, or Next.js's `useSearchParams` plus\n * `router.replace`/`push`.\n *\n * @example React Router\n * const [params, setParams] = useSearchParams();\n * const router = createSearchParamsRouter(params, (next, { replace }) => setParams(next, { replace }));\n */\nexport function createSearchParamsRouter(\n params: URLSearchParams,\n setParams: (next: URLSearchParams, options: { replace: boolean }) => void,\n): StudioRouter {\n return {\n location: locationFromSearchParams(params),\n navigate: (next, options) => setParams(searchParamsFromLocation(next, params), { replace: options?.replace ?? false }),\n };\n}\n\n/**\n * For an app with no router: keeps the studio's state in the current page's\n * query string through the History API.\n */\nexport function useHistoryRouter(): StudioRouter {\n const read = () =>\n typeof window === \"undefined\" ? {} : locationFromSearchParams(new URLSearchParams(window.location.search));\n const [location, setLocation] = useState<StudioLocation>(read);\n\n useEffect(() => {\n const onPop = () => setLocation(read());\n window.addEventListener(\"popstate\", onPop);\n return () => window.removeEventListener(\"popstate\", onPop);\n }, []);\n\n const navigate = useCallback((next: StudioLocation, options?: StudioNavigateOptions) => {\n const params = searchParamsFromLocation(next, new URLSearchParams(window.location.search));\n const query = params.toString();\n const url = `${window.location.pathname}${query ? `?${query}` : \"\"}${window.location.hash}`;\n if (options?.replace) window.history.replaceState(window.history.state, \"\", url);\n else window.history.pushState(window.history.state, \"\", url);\n setLocation(next);\n }, []);\n\n return useMemo(() => ({ location, navigate }), [location, navigate]);\n}\n\n/** A router held in memory, for tests and embedded previews. */\nexport function useMemoryRouter(initial: StudioLocation = {}): StudioRouter {\n const [location, setLocation] = useState<StudioLocation>(initial);\n const navigate = useCallback((next: StudioLocation) => setLocation(next), []);\n return useMemo(() => ({ location, navigate }), [location, navigate]);\n}\n","// How a stored value is shown, edited, and sent back. Postgres parses what\n// comes back (the handler casts every value to the column's type), so the\n// studio only decides what text the user sees and what \"empty\" means.\n\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\n\n/** The text a cell starts editing from. JSON is edited as JSON text. */\nexport function editText(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/** The text a cell shows, or `null` for an empty cell. */\nexport function displayText(value: unknown): string | null {\n if (value === null || value === undefined) return null;\n return editText(value);\n}\n\n/**\n * The value to save for what the user typed. An emptied cell becomes `null`\n * when the field accepts null, and the empty string otherwise.\n */\nexport function parseDraft(field: FieldSchema, draft: string): unknown {\n if (draft === \"\" && field.nullable) return null;\n return draft;\n}\n\n/** The choices for a select-style cell, or `undefined` for free text. */\nexport function choicesFor(field: FieldSchema): string[] | undefined {\n if (field.enumValues) return [...field.enumValues];\n if (field.type === \"boolean\") return [\"true\", \"false\"];\n return undefined;\n}\n\n/** What a person calls a field: its contract label, or its name. */\nexport function fieldLabel(field: FieldSchema): string {\n return field.label ?? field.name;\n}\n","// CSV moved to genesis-core (./csv) so ResourceView's export and the importers share it.\nexport { csvField, exportCsv, parseCsv, toCsv, type ExportOptions } from \"@marktiderman/genesis-core/csv\";\n\n/** Hand the browser a file to save. */\nexport function downloadText(filename: string, text: string, type = \"text/csv;charset=utf-8\"): void {\n const url = URL.createObjectURL(new Blob([text], { type }));\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n link.remove();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\n","// The list's search, sorts, filters and grouping, read from and written to\n// the URL so every view is a link.\n\nimport type { FilterParam, SortParam } from \"@marktiderman/genesis-core/provider\";\nimport type { FieldSchema, FilterOperator } from \"@marktiderman/genesis-core/schema\";\n\nexport function parseSorts(sort: string | undefined): SortParam[] {\n if (!sort) return [];\n return sort\n .split(\",\")\n .map((part) => {\n const at = part.lastIndexOf(\":\");\n const field = at > 0 ? part.slice(0, at) : part;\n return { field, order: part.slice(at + 1) === \"desc\" ? (\"desc\" as const) : (\"asc\" as const) };\n })\n .filter((s) => s.field);\n}\n\nexport function formatSorts(sorts: SortParam[]): string | undefined {\n return sorts.length ? sorts.map((s) => `${s.field}:${s.order}`).join(\",\") : undefined;\n}\n\ntype Encoded = [string, FilterOperator, unknown?];\n\nexport function parseFilters(raw: string | undefined): FilterParam[] {\n if (!raw) return [];\n try {\n const list = JSON.parse(raw) as Encoded[];\n if (!Array.isArray(list)) return [];\n return list\n .filter((f) => Array.isArray(f) && typeof f[0] === \"string\" && typeof f[1] === \"string\")\n .map(([field, operator, value]) =>\n operator === \"is_null\" || operator === \"is_not_null\"\n ? ({ field, operator } as FilterParam)\n : ({ field, operator, value } as FilterParam),\n );\n } catch {\n return [];\n }\n}\n\nexport function formatFilters(filters: FilterParam[]): string | undefined {\n if (!filters.length) return undefined;\n return JSON.stringify(filters.map((f) => (\"value\" in f ? [f.field, f.operator, f.value] : [f.field, f.operator])));\n}\n\n/** Operators that make sense for a field, by its storage type. */\nexport function operatorsFor(field: FieldSchema): FilterOperator[] {\n if (field.array) return [\"is_null\", \"is_not_null\"];\n if (field.enumValues || field.type === \"boolean\") return [\"eq\", \"neq\", \"is_null\", \"is_not_null\"];\n if (field.type === \"number\" || field.type === \"datetime\") {\n return [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\", \"is_null\", \"is_not_null\"];\n }\n if (field.type === \"json\") return [\"contains\", \"is_null\", \"is_not_null\"];\n return [\"contains\", \"eq\", \"neq\", \"is_null\", \"is_not_null\"];\n}\n\nexport const OPERATOR_LABEL: Record<FilterOperator, string> = {\n eq: \"is\",\n neq: \"is not\",\n gt: \"is after / more than\",\n gte: \"is on or after / at least\",\n lt: \"is before / less than\",\n lte: \"is on or before / at most\",\n contains: \"contains\",\n in: \"is any of\",\n between: \"is between\",\n is_null: \"is empty\",\n is_not_null: \"is not empty\",\n};\n\nexport function needsValue(operator: FilterOperator): boolean {\n return operator !== \"is_null\" && operator !== \"is_not_null\";\n}\n","// Following links between resources: labels for foreign-key cells (batched,\n// one query per linked resource per page) and the target's schema.\n\nimport { useQueries, useQuery } from \"@tanstack/react-query\";\nimport type { BaseRecord, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport { keyFields, type FieldSchema, type ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { displayText } from \"../values\";\n\nexport function useSchema(provider: DataProvider, sessionKey: unknown, resource: string | undefined) {\n return useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"describe\", resource],\n enabled: Boolean(resource && provider.describe),\n retry: false,\n queryFn: () => provider.describe!(resource!),\n });\n}\n\n/** The single key field of a resource, or null for a composite key. */\nexport function singleKey(schema: ResourceSchema | undefined): string | null {\n if (!schema) return null;\n const fields = keyFields(schema);\n return fields.length === 1 ? fields[0]! : null;\n}\n\n/**\n * Labels for every link field on a page of rows: field → (id → the target\n * row's `labelField`). One query per linked resource, never one per cell.\n * Ids the user can't see stay unlabelled.\n */\nexport function usePageLinkLabels(\n provider: DataProvider,\n sessionKey: unknown,\n fields: readonly FieldSchema[],\n rows: readonly Record<string, unknown>[],\n): Map<string, Map<string, string>> {\n const links = fields.filter((f) => f.references);\n const schemas = useQueries({\n queries: links.map((f) => ({\n queryKey: [\"genesis-studio\", sessionKey, \"describe\", f.references!.resource],\n enabled: Boolean(provider.describe),\n retry: false,\n queryFn: () => provider.describe!(f.references!.resource),\n })),\n });\n const labels = useQueries({\n queries: links.map((f, i) => {\n const ids = [...new Set(rows.map((r) => r[f.name]).filter((v) => v !== null && v !== undefined).map(String))].sort();\n const labelField = schemas[i]?.data?.labelField;\n return {\n queryKey: [\"genesis-studio\", sessionKey, \"labels\", f.references!.resource, f.references!.field, ids],\n enabled: Boolean(schemas[i]?.data && ids.length),\n staleTime: 60_000,\n retry: false,\n queryFn: async () => {\n const result = await provider.getList<BaseRecord>(f.references!.resource, {\n pagination: { page: 1, perPage: Math.min(200, ids.length) },\n filters: [{ field: f.references!.field, operator: \"in\" as const, value: ids }],\n });\n return new Map(\n (result.data as Record<string, unknown>[]).map((row) => [\n String(row[f.references!.field]),\n displayText(row[labelField ?? f.references!.field]) ?? String(row[f.references!.field]),\n ]),\n );\n },\n };\n }),\n });\n const out = new Map<string, Map<string, string>>();\n links.forEach((f, i) => out.set(f.name, labels[i]?.data ?? new Map()));\n return out;\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { Controller, useForm, type Resolver } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport type { DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Checkbox } from \"@marktiderman/genesis-ui/checkbox\";\nimport { Input } from \"@marktiderman/genesis-ui/input\";\nimport { Label } from \"@marktiderman/genesis-ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@marktiderman/genesis-ui/select\";\nimport { Textarea } from \"@marktiderman/genesis-ui/textarea\";\nimport { formSchema, fromFormValue, isRequired, toFormValues, type FormValues } from \"../lib/form-schema\";\nimport { sectionFields, type StudioFormConfig } from \"../lib/form-config\";\nimport { choicesFor, fieldLabel } from \"../values\";\nimport { RelationPicker } from \"./RelationPicker\";\n\nconst NONE = \"__genesis_none__\";\n\nexport interface RecordFormProps {\n provider: DataProvider;\n sessionKey: unknown;\n mode: \"create\" | \"edit\";\n /** Every field to show, in order. */\n fields: readonly FieldSchema[];\n /** Fields the user may change; the rest show read-only with their reason. */\n editable: ReadonlySet<string>;\n /** The row being edited, or defaults for a new one. */\n row?: Record<string, unknown>;\n /** Called with only the fields that changed (edit) or were filled in (create). */\n onSubmit: (values: Record<string, unknown>) => Promise<void>;\n submitLabel: string;\n onCancel?: () => void;\n /** Sections and conditional fields for this resource. */\n config?: StudioFormConfig;\n}\n\n/**\n * A form built from the schema: one control per field by its widget hint,\n * validation from the schema (required, numbers, dates, enums, JSON), and\n * read-only fields shown with the reason they can't be changed.\n */\nexport function RecordForm({ provider, sessionKey, mode, fields, editable, row, onSubmit, submitLabel, onCancel, config }: RecordFormProps) {\n const writable = useMemo(() => fields.filter((f) => editable.has(f.name)), [fields, editable]);\n const sections = useMemo(() => sectionFields(fields, config), [fields, config]);\n // The schema is built at runtime from the fields, so its inferred type is\n // only known to be FormValues by construction.\n // Only the fields a condition currently shows are validated: a hidden\n // required field can't block the save (and is left out of it).\n const resolver = useMemo<Resolver<FormValues>>(\n () => (values, context, options) => {\n const shown = writable.filter((f) => {\n const rule = config?.visibleWhen?.[f.name];\n return rule ? rule(values as Record<string, unknown>) : true;\n });\n const validate = zodResolver(formSchema(shown, mode) as never) as unknown as Resolver<FormValues>;\n return validate(values, context, options);\n },\n [writable, mode, config],\n );\n const defaults = useMemo(() => toFormValues(fields, row), [fields, row]);\n const form = useForm<FormValues>({ resolver, defaultValues: defaults });\n const [error, setError] = useState<string | null>(null);\n const values = form.watch();\n const isVisible = (name: string) => {\n const rule = config?.visibleWhen?.[name];\n return rule ? rule(values as Record<string, unknown>) : true;\n };\n\n // A save (or someone else's change) brings a new row: start from it.\n useEffect(() => {\n form.reset(defaults);\n }, [defaults, form]);\n\n const submit = form.handleSubmit(async (values) => {\n setError(null);\n const out: Record<string, unknown> = {};\n for (const field of writable) {\n // A field the config hides is left out of the save.\n if (!isVisible(field.name)) continue;\n const value = values[field.name];\n if (value === undefined) continue;\n if (mode === \"edit\" && value === defaults[field.name]) continue;\n if (mode === \"create\" && value === \"\" && !isRequired(field, mode)) continue;\n out[field.name] = fromFormValue(field, value);\n }\n if (mode === \"edit\" && Object.keys(out).length === 0) return;\n try {\n await onSubmit(out);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n });\n\n return (\n <form onSubmit={submit} className=\"space-y-4\" noValidate data-testid={`studio-record-form-${mode}`}>\n {sections.map((section) => (\n <fieldset key={section.title ?? \"fields\"} className=\"space-y-4\">\n {section.title && <legend className=\"mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">{section.title}</legend>}\n {section.fields.filter((field) => isVisible(field.name)).map((field) => {\n const id = `studio-field-${field.name}`;\n const canEdit = editable.has(field.name);\n const fieldError = form.formState.errors[field.name]?.message;\n const required = canEdit && isRequired(field, mode);\n const choices = choicesFor(field);\n return (\n <div key={field.name} className=\"space-y-1.5\">\n <Label htmlFor={id} className=\"flex items-baseline gap-1.5\">\n <span title={field.label ? field.name : undefined}>{fieldLabel(field)}</span>\n {required && <span className=\"text-destructive\" aria-hidden>*</span>}\n <span className=\"ml-auto font-mono text-[10px] font-normal text-muted-foreground\">{field.dbType}</span>\n </Label>\n <Controller\n control={form.control}\n name={field.name}\n render={({ field: control }) => {\n const disabled = !canEdit || form.formState.isSubmitting;\n if (field.references) {\n return (\n <RelationPicker\n id={id}\n provider={provider}\n sessionKey={sessionKey}\n field={field}\n value={String(control.value ?? \"\")}\n onChange={control.onChange}\n disabled={disabled}\n />\n );\n }\n if (field.type === \"boolean\" && !field.nullable) {\n return (\n <div className=\"flex h-9 items-center\">\n <Checkbox id={id} checked={control.value === true} onCheckedChange={(v) => control.onChange(v === true)} disabled={disabled} />\n </div>\n );\n }\n if (choices) {\n return (\n <Select\n value={control.value === \"\" ? NONE : String(control.value)}\n onValueChange={(v) => control.onChange(v === NONE ? \"\" : v)}\n disabled={disabled}\n >\n <SelectTrigger id={id} aria-invalid={fieldError ? true : undefined}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {(field.nullable || mode === \"create\") && <SelectItem value={NONE}>—</SelectItem>}\n {choices.map((c) => (\n <SelectItem key={c} value={c}>\n {c}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n }\n if (field.widget === \"textarea\") {\n return (\n <Textarea\n id={id}\n rows={4}\n className=\"font-mono text-xs\"\n value={String(control.value ?? \"\")}\n onChange={control.onChange}\n onBlur={control.onBlur}\n disabled={disabled}\n aria-invalid={fieldError ? true : undefined}\n />\n );\n }\n return (\n <Input\n id={id}\n type={field.widget === \"date\" ? \"date\" : \"text\"}\n inputMode={field.type === \"number\" ? \"decimal\" : undefined}\n value={String(control.value ?? \"\")}\n onChange={control.onChange}\n onBlur={control.onBlur}\n disabled={disabled}\n aria-invalid={fieldError ? true : undefined}\n />\n );\n }}\n />\n {fieldError ? (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {String(fieldError)}\n </p>\n ) : !canEdit && field.permissions?.reason ? (\n <p className=\"text-xs text-muted-foreground\">{field.permissions.reason}</p>\n ) : field.description ? (\n <p className=\"text-xs text-muted-foreground\">{field.description}</p>\n ) : null}\n </div>\n );\n })}\n </fieldset>\n ))}\n {error && (\n <p role=\"alert\" className=\"rounded-md border border-destructive/40 bg-destructive/5 p-2 text-sm text-destructive\" data-testid=\"studio-form-error\">\n {error}\n </p>\n )}\n {writable.length > 0 && (\n <div className=\"flex justify-end gap-2\">\n {onCancel && (\n <Button type=\"button\" variant=\"outline\" onClick={onCancel}>\n Cancel\n </Button>\n )}\n <Button type=\"submit\" disabled={form.formState.isSubmitting} testID={`studio-${mode}-submit`}>\n {form.formState.isSubmitting ? \"Saving…\" : submitLabel}\n </Button>\n </div>\n )}\n </form>\n );\n}\n","// Validation built from the schema (DATA-STUDIO.md P1, \"forms built from the\n// schema\"): required from NOT NULL without a default, enum labels, numbers,\n// dates and JSON. The database still has the last word on CHECK constraints\n// and domains; its reason comes back as the save's error.\n\nimport { z } from \"zod\";\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\nimport { choicesFor, editText } from \"../values\";\n\nexport type FormValues = Record<string, string | boolean>;\n\n/** Fields that need a value: NOT NULL and, on a new row, no default. */\nexport function isRequired(field: FieldSchema, mode: \"create\" | \"edit\"): boolean {\n if (field.nullable || field.generated) return false;\n return mode === \"edit\" || !field.hasDefault;\n}\n\nconst NUMBER = /^-?(\\d+\\.?\\d*|\\.\\d+)(e[-+]?\\d+)?$/i;\nconst DATE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction textRule(field: FieldSchema, required: boolean) {\n const choices = choicesFor(field);\n return z.string().superRefine((value, ctx) => {\n if (value === \"\") {\n if (required) ctx.addIssue({ code: \"custom\", message: \"Required.\" });\n return;\n }\n if (field.type === \"number\" && !NUMBER.test(value.trim())) ctx.addIssue({ code: \"custom\", message: \"Enter a number.\" });\n if (field.widget === \"date\" && !DATE.test(value)) ctx.addIssue({ code: \"custom\", message: \"Enter a date (YYYY-MM-DD).\" });\n if (choices && field.type !== \"boolean\" && !choices.includes(value)) {\n ctx.addIssue({ code: \"custom\", message: `Choose one of: ${choices.join(\", \")}.` });\n }\n if (field.type === \"json\") {\n try {\n JSON.parse(value);\n } catch {\n ctx.addIssue({ code: \"custom\", message: \"Enter valid JSON.\" });\n }\n }\n });\n}\n\nexport function formSchema(fields: readonly FieldSchema[], mode: \"create\" | \"edit\") {\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const field of fields) {\n const required = isRequired(field, mode);\n shape[field.name] = field.type === \"boolean\" && !field.nullable ? z.boolean() : textRule(field, required);\n }\n return z.object(shape);\n}\n\n/** A row's values as form values: booleans stay booleans, everything else is text. */\nexport function toFormValues(fields: readonly FieldSchema[], row: Record<string, unknown> | undefined): FormValues {\n const out: FormValues = {};\n for (const field of fields) {\n const value = row?.[field.name];\n out[field.name] = field.type === \"boolean\" && !field.nullable ? value === true || value === \"true\" : editText(value);\n }\n return out;\n}\n\n/** A form value as the value to save. An emptied field is null where null is allowed. */\nexport function fromFormValue(field: FieldSchema, value: string | boolean): unknown {\n if (typeof value === \"boolean\") return value;\n if (value === \"\") return field.nullable ? null : \"\";\n return value;\n}\n","// Code-first form layout (DATA-STUDIO.md P2, \"conditional fields and\n// sections, declared in code config first\").\n\n/** How one resource's record form is laid out. */\nexport interface StudioFormConfig {\n /** Fields grouped under headings, in order. Fields in no section follow, under \"Other\". */\n sections?: { title: string; fields: string[] }[];\n /**\n * Show a field only when this returns true for the form's current values,\n * e.g. `{ cancel_reason: (v) => v.status === \"cancelled\" }`. A hidden field\n * is left out of the save.\n */\n visibleWhen?: Record<string, (values: Record<string, unknown>) => boolean>;\n}\n\nexport interface FormSection<F> {\n title: string | null;\n fields: F[];\n}\n\n/** Split fields into the configured sections, keeping each field once. */\nexport function sectionFields<F extends { name: string }>(fields: readonly F[], config: StudioFormConfig | undefined): FormSection<F>[] {\n if (!config?.sections?.length) return [{ title: null, fields: [...fields] }];\n const byName = new Map(fields.map((f) => [f.name, f]));\n const used = new Set<string>();\n const out: FormSection<F>[] = [];\n for (const section of config.sections) {\n const list = section.fields.map((n) => byName.get(n)).filter((f): f is F => Boolean(f) && !used.has(f!.name));\n list.forEach((f) => used.add(f.name));\n if (list.length) out.push({ title: section.title, fields: list });\n }\n const rest = fields.filter((f) => !used.has(f.name));\n if (rest.length) out.push({ title: \"Other\", fields: rest });\n return out;\n}\n","import { useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ChevronsUpDown, X } from \"lucide-react\";\nimport type { BaseRecord, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@marktiderman/genesis-ui/popover\";\nimport { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from \"@marktiderman/genesis-ui/command\";\nimport { useSchema } from \"../lib/relations\";\nimport { displayText } from \"../values\";\n\nexport interface RelationPickerProps {\n provider: DataProvider;\n sessionKey: unknown;\n field: FieldSchema;\n /** The linked row's key, as text (\"\" for none). */\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n id?: string;\n}\n\n/**\n * Pick a linked row by searching the target resource on the server, so it\n * works for a table of any size; shows each row by its label field.\n */\nexport function RelationPicker({ provider, sessionKey, field, value, onChange, disabled, id }: RelationPickerProps) {\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState(\"\");\n const target = field.references!.resource;\n const targetField = field.references!.field;\n const schema = useSchema(provider, sessionKey, target);\n const labelField = schema.data?.labelField ?? targetField;\n\n const options = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"pick\", target, search],\n enabled: open && Boolean(schema.data),\n retry: false,\n queryFn: () =>\n provider.getList<BaseRecord>(target, {\n pagination: { page: 1, perPage: 20 },\n ...(search ? { search: { query: search, fields: [] } } : {}),\n }),\n });\n const current = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"labels\", target, targetField, [value]],\n enabled: Boolean(value && schema.data),\n retry: false,\n queryFn: async () => {\n const result = await provider.getList<BaseRecord>(target, {\n pagination: { page: 1, perPage: 1 },\n filters: [{ field: targetField, operator: \"eq\", value }],\n });\n const row = result.data[0] as Record<string, unknown> | undefined;\n return new Map(row ? [[value, displayText(row[labelField]) ?? value]] : []);\n },\n });\n const label = value ? (current.data?.get(value) ?? value) : \"—\";\n\n return (\n <div className=\"flex items-center gap-1\">\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n id={id}\n type=\"button\"\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n disabled={disabled}\n className=\"h-9 w-full justify-between font-normal\"\n testID={`studio-picker-${field.name}`}\n >\n <span className=\"truncate\">{label}</span>\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" aria-hidden />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-72 p-0\" align=\"start\">\n <Command shouldFilter={false}>\n <CommandInput placeholder={`Search ${target}…`} value={search} onValueChange={setSearch} />\n <CommandList>\n <CommandEmpty>{options.isLoading ? \"Searching…\" : \"No matches you can see.\"}</CommandEmpty>\n {(options.data?.data as Record<string, unknown>[] | undefined)?.map((row) => {\n const key = String(row[targetField]);\n return (\n <CommandItem\n key={key}\n value={key}\n onSelect={() => {\n onChange(key);\n setOpen(false);\n }}\n >\n <span className=\"truncate\">{displayText(row[labelField]) ?? key}</span>\n <span className=\"ml-auto pl-2 font-mono text-[10px] text-muted-foreground\">{key}</span>\n </CommandItem>\n );\n })}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n {value && field.nullable && !disabled && (\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"h-9 w-9\" aria-label={`Clear ${field.name}`} onClick={() => onChange(\"\")}>\n <X className=\"h-4 w-4\" aria-hidden />\n </Button>\n )}\n </div>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { ExternalLink, Link2, Play, Trash2 } from \"lucide-react\";\nimport type { BaseRecord, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport {\n encodeRecordKey,\n isDataWriteError,\n type AuditEntry,\n type ResourceRelation,\n type ResourceSchema,\n type RowAction,\n} from \"@marktiderman/genesis-core/schema\";\nimport { Textarea } from \"@marktiderman/genesis-ui/textarea\";\nimport { Alert, AlertDescription, AlertTitle } from \"@marktiderman/genesis-ui/alert\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@marktiderman/genesis-ui/alert-dialog\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from \"@marktiderman/genesis-ui/sheet\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@marktiderman/genesis-ui/tabs\";\nimport { singleKey, useSchema } from \"../lib/relations\";\nimport { displayText } from \"../values\";\nimport { RecordForm } from \"./RecordForm\";\nimport type { StudioFormConfig } from \"../lib/form-config\";\n\nexport interface RecordPanelProps {\n provider: DataProvider;\n sessionKey: unknown;\n schema: ResourceSchema;\n /** The record's id (`encodeRecordKey`). */\n id: string;\n onClose: () => void;\n /** Open another record (a related one), in its own table. */\n onOpenRecord: (resource: string, id: string) => void;\n onSaved: (row: Record<string, unknown>, audit?: AuditEntry) => void;\n onDeleted: (audit?: AuditEntry) => void;\n onFailed: (action: string, message: string) => void;\n /** A change from the History tab was undone. */\n onUndone?: (audit?: AuditEntry) => void;\n /** Sections and conditional fields for the form. */\n formConfig?: StudioFormConfig;\n /** A row action ran; `row` is null when it removed the row. */\n onActionRan?: (action: RowAction, row: Record<string, unknown> | null, audit?: AuditEntry) => void;\n}\n\nfunction versionOf(schema: ResourceSchema, row: Record<string, unknown> | undefined): string | null {\n const field = schema.version?.field;\n if (!field || !row || row[field] == null) return null;\n return String(row[field]);\n}\n\n/**\n * One record, in a side panel: its fields as a form, the records it links to\n * and from, and its audit history. The URL names it, so the link copies.\n */\nexport function RecordPanel(props: RecordPanelProps) {\n const { provider, sessionKey, schema, id } = props;\n const queryClient = useQueryClient();\n const recordKey = [\"genesis-studio\", sessionKey, \"record\", schema.name, id];\n const record = useQuery({\n queryKey: recordKey,\n retry: false,\n queryFn: async () => (await provider.getOne<BaseRecord>(schema.name, { id })).data as Record<string, unknown>,\n });\n const [conflict, setConflict] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n const row = record.data;\n const title = row ? (displayText(row[schema.labelField ?? \"\"]) ?? id) : id;\n const editable = useMemo(() => new Set(schema.fields.filter((f) => f.permissions?.update).map((f) => f.name)), [schema]);\n const relations = schema.relations ?? [];\n\n async function save(values: Record<string, unknown>) {\n setConflict(null);\n try {\n const result = await provider.update<BaseRecord>(schema.name, { id, data: values as never, expectedVersion: versionOf(schema, row) });\n queryClient.setQueryData(recordKey, result.data);\n props.onSaved(result.data as Record<string, unknown>, result.audit);\n } catch (error) {\n if (isDataWriteError(error) && error.outcome === \"conflict\") {\n setConflict(error.message);\n if (error.current) {\n queryClient.setQueryData(recordKey, {\n ...row,\n ...error.current,\n ...(schema.version ? { [schema.version.field]: error.currentVersion ?? null } : {}),\n });\n } else {\n void record.refetch();\n }\n }\n props.onFailed(\"update\", error instanceof Error ? error.message : String(error));\n throw error;\n }\n }\n\n async function remove() {\n try {\n const result = await provider.deleteOne(schema.name, { id, expectedVersion: versionOf(schema, row) });\n props.onDeleted(result.audit);\n props.onClose();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n setConflict(message);\n props.onFailed(\"delete\", message);\n void record.refetch();\n }\n }\n\n const [running, setRunning] = useState<string | null>(null);\n const [actionError, setActionError] = useState<{ label: string; message: string } | null>(null);\n const [confirming, setConfirming] = useState<RowAction | null>(null);\n async function runAction(action: RowAction) {\n setConflict(null);\n setActionError(null);\n setRunning(action.name);\n try {\n const result = await provider.runAction!(schema.name, { id, action: action.name, expectedVersion: versionOf(schema, row) });\n props.onActionRan?.(action, result.data, result.audit);\n if (result.data) queryClient.setQueryData(recordKey, result.data);\n else props.onClose();\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey, \"history\", schema.name, id] });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n setActionError({ label: action.label, message: message.replace(/^Not (saved|run): /, \"\") });\n props.onFailed(`action:${action.name}`, message);\n void record.refetch();\n } finally {\n setRunning(null);\n }\n }\n const actions = provider.runAction ? (schema.actions ?? []) : [];\n\n async function copyLink() {\n try {\n await navigator.clipboard.writeText(window.location.href);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n } catch {\n setCopied(false);\n }\n }\n\n return (\n <Sheet open onOpenChange={(open) => !open && props.onClose()}>\n <SheetContent className=\"w-full overflow-y-auto sm:max-w-xl\" data-testid=\"studio-record-panel\">\n <SheetHeader>\n <SheetTitle className=\"truncate pr-8\">{title}</SheetTitle>\n <SheetDescription>\n {schema.label ?? schema.name} · <span className=\"font-mono text-xs\">{id}</span>\n </SheetDescription>\n </SheetHeader>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={copyLink} testID=\"studio-copy-link\">\n <Link2 className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n {copied ? \"Link copied\" : \"Copy link\"}\n </Button>\n {schema.access.delete ? (\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" testID=\"studio-delete\">\n <Trash2 className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n Delete\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete {title}?</AlertDialogTitle>\n <AlertDialogDescription>\n The deletion is audited. It only goes through if nobody has changed the row since you opened it.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Keep it</AlertDialogCancel>\n <AlertDialogAction onClick={() => void remove()} data-testid=\"studio-delete-confirm\">\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n ) : (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled title={schema.access.reasons?.delete}>\n <Trash2 className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n Delete\n </Button>\n )}\n {actions.map((action) => (\n <Button\n key={action.name}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={!row || running !== null}\n title={action.description}\n onClick={() => (action.confirm ? setConfirming(action) : void runAction(action))}\n testID={`studio-action-${action.name}`}\n >\n <Play className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n {running === action.name ? `${action.label}…` : action.label}\n </Button>\n ))}\n </div>\n <AlertDialog open={confirming !== null} onOpenChange={(open) => !open && setConfirming(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{confirming?.confirm}</AlertDialogTitle>\n <AlertDialogDescription>\n {confirming?.description ? `${confirming.description} ` : \"\"}It runs on this row as you see it now, and is audited.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => {\n const action = confirming;\n setConfirming(null);\n if (action) void runAction(action);\n }}\n data-testid=\"studio-action-confirm\"\n >\n {confirming?.label}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {actionError && (\n <Alert variant=\"destructive\" className=\"mt-3\" data-testid=\"studio-action-error\">\n <AlertTitle>{actionError.label} didn't run</AlertTitle>\n <AlertDescription>{actionError.message} Nothing was changed.</AlertDescription>\n </Alert>\n )}\n {conflict && (\n <Alert variant=\"destructive\" className=\"mt-3\" data-testid=\"studio-record-conflict\">\n <AlertTitle>Not saved</AlertTitle>\n <AlertDescription>{conflict} The form now shows the row as it is.</AlertDescription>\n </Alert>\n )}\n\n {record.isError ? (\n <Alert variant=\"destructive\" className=\"mt-4\">\n <AlertTitle>Couldn't open this record</AlertTitle>\n <AlertDescription>{record.error instanceof Error ? record.error.message : String(record.error)}</AlertDescription>\n </Alert>\n ) : (\n <Tabs defaultValue=\"details\" className=\"mt-4\">\n <TabsList>\n <TabsTrigger value=\"details\">Details</TabsTrigger>\n {relations.length > 0 && <TabsTrigger value=\"related\">Related ({relations.length})</TabsTrigger>}\n <TabsTrigger value=\"history\" disabled={!schema.access.history} title={schema.access.reasons?.history}>\n History\n </TabsTrigger>\n {schema.access.comment !== undefined && provider.comments && (\n <TabsTrigger value=\"comments\" disabled={!schema.access.comment} title={schema.access.reasons?.comment}>\n Comments\n </TabsTrigger>\n )}\n </TabsList>\n <TabsContent value=\"details\" className=\"pt-2\">\n {row ? (\n <RecordForm\n provider={provider}\n sessionKey={sessionKey}\n mode=\"edit\"\n fields={schema.fields}\n editable={editable}\n row={row}\n onSubmit={save}\n submitLabel=\"Save changes\"\n config={props.formConfig}\n />\n ) : (\n <p className=\"text-sm text-muted-foreground\">Loading…</p>\n )}\n </TabsContent>\n {relations.length > 0 && (\n <TabsContent value=\"related\" className=\"space-y-5 pt-2\">\n {row &&\n relations.map((relation) => (\n <RelatedSection\n key={`${relation.kind}:${relation.resource}:${relation.field}`}\n provider={provider}\n sessionKey={sessionKey}\n schema={schema}\n row={row}\n relation={relation}\n onOpenRecord={props.onOpenRecord}\n />\n ))}\n </TabsContent>\n )}\n {schema.access.history && (\n <TabsContent value=\"history\" className=\"pt-2\">\n <History\n provider={provider}\n sessionKey={sessionKey}\n resource={schema.name}\n id={id}\n onUndone={(audit) => {\n void record.refetch();\n props.onUndone?.(audit);\n }}\n />\n </TabsContent>\n )}\n {schema.access.comment && provider.comments && (\n <TabsContent value=\"comments\" className=\"pt-2\">\n <Comments provider={provider} sessionKey={sessionKey} resource={schema.name} id={id} />\n </TabsContent>\n )}\n </Tabs>\n )}\n </SheetContent>\n </Sheet>\n );\n}\n\nfunction RelatedSection({\n provider,\n sessionKey,\n schema,\n row,\n relation,\n onOpenRecord,\n}: {\n provider: DataProvider;\n sessionKey: unknown;\n schema: ResourceSchema;\n row: Record<string, unknown>;\n relation: ResourceRelation;\n onOpenRecord: (resource: string, id: string) => void;\n}) {\n const target = useSchema(provider, sessionKey, relation.resource);\n const ownKey = singleKey(schema);\n const query = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"related\", schema.name, relation.kind, relation.resource, relation.field, row[ownKey ?? \"\"]],\n enabled: Boolean(target.data),\n retry: false,\n queryFn: async (): Promise<Record<string, unknown>[]> => {\n const targetKey = singleKey(target.data);\n if (relation.kind === \"one\") {\n const value = row[relation.field];\n if (value == null || !targetKey) return [];\n const r = await provider.getList<BaseRecord>(relation.resource, {\n pagination: { page: 1, perPage: 1 },\n filters: [{ field: targetKey, operator: \"eq\", value: String(value) }],\n });\n return r.data as Record<string, unknown>[];\n }\n const self = row[ownKey ?? \"\"];\n if (self == null) return [];\n if (relation.kind === \"many\") {\n const r = await provider.getList<BaseRecord>(relation.resource, {\n pagination: { page: 1, perPage: 25 },\n filters: [{ field: relation.field, operator: \"eq\", value: String(self) }],\n });\n return r.data as Record<string, unknown>[];\n }\n // through: the junction's rows for this record, then the rows they point at.\n const links = await provider.getList<BaseRecord>(relation.through!.resource, {\n pagination: { page: 1, perPage: 100 },\n filters: [{ field: relation.field, operator: \"eq\", value: String(self) }],\n });\n const ids = (links.data as Record<string, unknown>[]).map((l) => String(l[relation.through!.otherField]));\n if (!ids.length || !targetKey) return [];\n const r = await provider.getList<BaseRecord>(relation.resource, {\n pagination: { page: 1, perPage: Math.min(100, ids.length) },\n filters: [{ field: targetKey, operator: \"in\", value: ids }],\n });\n return r.data as Record<string, unknown>[];\n },\n });\n const heading = `${target.data?.label ?? relation.resource}${\n relation.kind === \"one\" ? ` (via ${relation.field})` : relation.kind === \"through\" ? ` (via ${relation.through!.resource})` : \"\"\n }`;\n const labelField = target.data?.labelField;\n\n return (\n <section data-testid={`studio-related-${relation.resource}`}>\n <h3 className=\"mb-1.5 text-sm font-semibold\">{heading}</h3>\n {query.isLoading ? (\n <p className=\"text-xs text-muted-foreground\">Loading…</p>\n ) : !query.data?.length ? (\n <p className=\"text-xs text-muted-foreground\">None you can see.</p>\n ) : (\n <ul className=\"divide-y rounded-md border\">\n {query.data.map((related, index) => {\n const relatedId = target.data ? String(encodeRecordKey(target.data, related)) : String(index);\n return (\n <li key={relatedId}>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-sm hover:bg-muted\"\n onClick={() => onOpenRecord(relation.resource, relatedId)}\n >\n <span className=\"truncate\">{displayText(related[labelField ?? \"\"]) ?? relatedId}</span>\n <ExternalLink className=\"ml-auto h-3.5 w-3.5 shrink-0 text-muted-foreground\" aria-hidden />\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </section>\n );\n}\n\nfunction History({\n provider,\n sessionKey,\n resource,\n id,\n onUndone,\n}: {\n provider: DataProvider;\n sessionKey: unknown;\n resource: string;\n id: string;\n onUndone: (audit?: AuditEntry) => void;\n}) {\n const [undoError, setUndoError] = useState<string | null>(null);\n const history = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"history\", resource, id],\n enabled: Boolean(provider.history),\n retry: false,\n queryFn: () => provider.history!(resource, { id }),\n });\n if (history.isLoading) return <p className=\"text-xs text-muted-foreground\">Loading…</p>;\n if (history.isError) {\n return (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {history.error instanceof Error ? history.error.message : String(history.error)}\n </p>\n );\n }\n if (!history.data?.length) return <p className=\"text-xs text-muted-foreground\">No audited changes yet.</p>;\n async function undo(entry: AuditEntry) {\n setUndoError(null);\n try {\n const result = await provider.undo!(resource, { auditId: entry.id });\n void history.refetch();\n onUndone(result.audit);\n } catch (error) {\n setUndoError(error instanceof Error ? error.message : String(error));\n }\n }\n\n return (\n <>\n {undoError && (\n <p role=\"alert\" className=\"mb-2 text-xs text-destructive\" data-testid=\"studio-undo-error\">\n {undoError}\n </p>\n )}\n <ol className=\"space-y-2\" data-testid=\"studio-history\">\n {history.data.map((entry) => {\n const fields = [...new Set([...Object.keys(entry.before ?? {}), ...Object.keys(entry.after ?? {})])];\n return (\n <li key={entry.id} className=\"rounded-md border p-2 text-xs\">\n <div className=\"flex flex-wrap items-baseline gap-x-2\">\n <span className=\"font-medium capitalize\">{entry.action === \"run\" ? `Ran ${entry.rowAction ?? \"an action\"}` : entry.action}</span>\n <span className=\"text-muted-foreground\">by {entry.actor ?? \"unknown\"}</span>\n <time className=\"ml-auto text-muted-foreground\">{entry.occurredAt}</time>\n {provider.undo && entry.action !== \"run\" && (\n <button\n type=\"button\"\n className=\"rounded px-1.5 py-0.5 text-[11px] text-muted-foreground hover:bg-muted hover:text-foreground\"\n onClick={() => void undo(entry)}\n title=\"Put this change back. Refused if the row has changed since.\"\n data-testid=\"studio-history-undo\"\n >\n Undo\n </button>\n )}\n </div>\n <div className=\"mt-1 font-mono text-[11px]\">\n {fields.map((field) => (\n <div key={field}>\n {field}: {displayText(entry.before?.[field]) ?? \"—\"} → {displayText(entry.after?.[field]) ?? \"—\"}\n </div>\n ))}\n </div>\n </li>\n );\n })}\n </ol>\n </>\n );\n}\n\nfunction Comments({\n provider,\n sessionKey,\n resource,\n id,\n}: {\n provider: DataProvider;\n sessionKey: unknown;\n resource: string;\n id: string;\n}) {\n const queryClient = useQueryClient();\n const key = [\"genesis-studio\", sessionKey, \"comments\", resource, id];\n const comments = useQuery({ queryKey: key, retry: false, queryFn: () => provider.comments!(resource, { id }) });\n const [draft, setDraft] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function post() {\n if (!draft.trim() || !provider.addComment) return;\n setBusy(true);\n setError(null);\n try {\n await provider.addComment(resource, { id, body: draft });\n setDraft(\"\");\n await queryClient.invalidateQueries({ queryKey: key });\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <div className=\"space-y-3\" data-testid=\"studio-comments\">\n {comments.isLoading ? (\n <p className=\"text-xs text-muted-foreground\">Loading…</p>\n ) : comments.isError ? (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {comments.error instanceof Error ? comments.error.message : String(comments.error)}\n </p>\n ) : !comments.data?.length ? (\n <p className=\"text-xs text-muted-foreground\">No comments yet.</p>\n ) : (\n <ol className=\"space-y-2\">\n {comments.data.map((c) => (\n <li key={c.id} className=\"rounded-md border p-2 text-sm\">\n <div className=\"flex items-baseline gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{c.author}</span>\n <time className=\"ml-auto\">{c.createdAt}</time>\n </div>\n <p className=\"mt-1 whitespace-pre-wrap break-words\">{c.body}</p>\n </li>\n ))}\n </ol>\n )}\n {provider.addComment && (\n <form\n className=\"space-y-2\"\n onSubmit={(e) => {\n e.preventDefault();\n void post();\n }}\n >\n <Textarea\n aria-label=\"New comment\"\n value={draft}\n maxLength={10000}\n onChange={(e) => setDraft(e.target.value)}\n placeholder=\"Add a comment…\"\n rows={3}\n />\n {error && (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {error}\n </p>\n )}\n <div className=\"flex justify-end\">\n <Button type=\"submit\" size=\"sm\" disabled={busy || !draft.trim()} testID=\"studio-comment-post\">\n {busy ? \"Posting…\" : \"Comment\"}\n </Button>\n </div>\n </form>\n )}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { ArrowDownUp, Download, EyeOff, Filter, Group, Plus, Search, X } from \"lucide-react\";\nimport type { FilterParam, SortParam } from \"@marktiderman/genesis-core/provider\";\nimport type { FieldSchema, FilterOperator } from \"@marktiderman/genesis-core/schema\";\nimport { Badge } from \"@marktiderman/genesis-ui/badge\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Input } from \"@marktiderman/genesis-ui/input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@marktiderman/genesis-ui/popover\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@marktiderman/genesis-ui/select\";\nimport { needsValue, OPERATOR_LABEL, operatorsFor } from \"../lib/query-state\";\nimport { choicesFor, fieldLabel } from \"../values\";\n\nconst NONE = \"__genesis_none__\";\n\ninterface FilterDraft {\n field: string;\n operator: FilterOperator;\n value: string;\n}\n\nfunction toDraft(f: FilterParam): FilterDraft {\n return { field: f.field, operator: f.operator, value: \"value\" in f && f.value != null ? String(f.value) : \"\" };\n}\n\nfunction fromDraft(d: FilterDraft): FilterParam {\n return needsValue(d.operator)\n ? ({ field: d.field, operator: d.operator, value: d.value } as FilterParam)\n : ({ field: d.field, operator: d.operator } as FilterParam);\n}\n\n/** Filters by field, with the operators that fit each field's type. */\nexport function FilterBuilder({\n fields,\n filters,\n onChange,\n}: {\n fields: readonly FieldSchema[];\n filters: FilterParam[];\n onChange: (filters: FilterParam[]) => void;\n}) {\n const [open, setOpen] = useState(false);\n const [drafts, setDrafts] = useState<FilterDraft[]>(filters.map(toDraft));\n const filterable = fields.filter((f) => !f.array);\n const update = (i: number, patch: Partial<FilterDraft>) =>\n setDrafts((prev) => prev.map((d, j) => (j === i ? { ...d, ...patch } : d)));\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (next) setDrafts(filters.map(toDraft));\n }}\n >\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" testID=\"studio-filter\" className={`px-2 ${filters.length ? \"bg-success/15\" : \"\"}`}>\n <Filter className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n Filter\n {filters.length > 0 && <Badge className=\"ml-1.5 h-4 px-1.5 text-[10px]\">{filters.length}</Badge>}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-[min(36rem,calc(100vw-2rem))] space-y-2\">\n {drafts.length === 0 && <p className=\"text-xs text-muted-foreground\">No filters. Every row you can see is listed.</p>}\n {drafts.map((d, i) => {\n const field = filterable.find((f) => f.name === d.field);\n const operators = field ? operatorsFor(field) : [];\n const choices = field ? choicesFor(field) : undefined;\n return (\n <div key={i} className=\"flex flex-wrap items-center gap-1.5\" data-testid=\"studio-filter-row\">\n <Select value={d.field} onValueChange={(v) => update(i, { field: v, operator: operatorsFor(filterable.find((f) => f.name === v)!)[0]!, value: \"\" })}>\n <SelectTrigger className=\"h-8 w-36 text-xs\" aria-label=\"Field\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {filterable.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={d.operator} onValueChange={(v) => update(i, { operator: v as FilterOperator })}>\n <SelectTrigger className=\"h-8 w-40 text-xs\" aria-label=\"Operator\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {operators.map((op) => (\n <SelectItem key={op} value={op}>\n {OPERATOR_LABEL[op]}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {needsValue(d.operator) &&\n (choices ? (\n <Select value={d.value || NONE} onValueChange={(v) => update(i, { value: v === NONE ? \"\" : v })}>\n <SelectTrigger className=\"h-8 w-36 text-xs\" aria-label=\"Value\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>—</SelectItem>\n {choices.map((c) => (\n <SelectItem key={c} value={c}>\n {c}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <Input\n className=\"h-8 w-36 text-xs\"\n aria-label=\"Value\"\n type={field?.widget === \"date\" ? \"date\" : \"text\"}\n value={d.value}\n onChange={(e) => update(i, { value: e.target.value })}\n />\n ))}\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" aria-label=\"Remove filter\" onClick={() => setDrafts((p) => p.filter((_, j) => j !== i))}>\n <X className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n </div>\n );\n })}\n <div className=\"flex justify-between gap-2 pt-1\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={filterable.length === 0}\n onClick={() => {\n const first = filterable[0]!;\n setDrafts((p) => [...p, { field: first.name, operator: operatorsFor(first)[0]!, value: \"\" }]);\n }}\n >\n <Plus className=\"mr-1 h-3.5 w-3.5\" aria-hidden />\n Add filter\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n testID=\"studio-filter-apply\"\n onClick={() => {\n onChange(drafts.filter((d) => !needsValue(d.operator) || d.value !== \"\").map(fromDraft));\n setOpen(false);\n }}\n >\n Apply\n </Button>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\n/** Sort by several fields, first one first. */\nexport function SortBuilder({\n fields,\n sorts,\n onChange,\n}: {\n fields: readonly FieldSchema[];\n sorts: SortParam[];\n onChange: (sorts: SortParam[]) => void;\n}) {\n const sortable = fields.filter((f) => !f.array);\n const unused = sortable.filter((f) => !sorts.some((s) => s.field === f.name));\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" testID=\"studio-sort\" className={`px-2 ${sorts.length ? \"bg-warning/20\" : \"\"}`}>\n <ArrowDownUp className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n Sort\n {sorts.length > 0 && <Badge className=\"ml-1.5 h-4 px-1.5 text-[10px]\">{sorts.length}</Badge>}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-80 space-y-2\">\n {sorts.length === 0 && <p className=\"text-xs text-muted-foreground\">Rows are in key order.</p>}\n {sorts.map((s, i) => (\n <div key={s.field} className=\"flex items-center gap-1.5\" data-testid=\"studio-sort-row\">\n <span className=\"w-5 text-right text-xs text-muted-foreground\">{i + 1}</span>\n <span className=\"flex-1 truncate text-sm\">{s.field}</span>\n <Select value={s.order} onValueChange={(v) => onChange(sorts.map((x, j) => (j === i ? { ...x, order: v as \"asc\" | \"desc\" } : x)))}>\n <SelectTrigger className=\"h-8 w-28 text-xs\" aria-label={`Direction for ${s.field}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"asc\">Ascending</SelectItem>\n <SelectItem value=\"desc\">Descending</SelectItem>\n </SelectContent>\n </Select>\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" aria-label={`Stop sorting by ${s.field}`} onClick={() => onChange(sorts.filter((_, j) => j !== i))}>\n <X className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n </div>\n ))}\n {unused.length > 0 && sorts.length < 5 && (\n <Select value={NONE} onValueChange={(v) => v !== NONE && onChange([...sorts, { field: v, order: \"asc\" }])}>\n <SelectTrigger className=\"h-8 text-xs\" aria-label=\"Add a sort field\">\n <SelectValue placeholder=\"Add a sort field\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE} disabled>\n Add a sort field…\n </SelectItem>\n {unused.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n\n/** Group rows by a field with few distinct values. */\nexport function GroupPicker({\n fields,\n group,\n onChange,\n}: {\n fields: readonly FieldSchema[];\n group: string | undefined;\n onChange: (group: string | undefined) => void;\n}) {\n const groupable = fields.filter((f) => !f.array && f.type !== \"json\");\n return (\n <Select value={group ?? NONE} onValueChange={(v) => onChange(v === NONE ? undefined : v)}>\n <SelectTrigger className={`h-8 w-auto gap-1.5 border-0 text-sm shadow-none hover:bg-muted ${group ? \"bg-info/15\" : \"\"}`} aria-label=\"Group by\" data-testid=\"studio-group\">\n <Group className=\"h-3.5 w-3.5\" aria-hidden />\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>Group</SelectItem>\n {groupable.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n Group by {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\nexport function ExportButton({ onExport, busy, progress }: { onExport: () => void; busy: boolean; progress: number }) {\n return (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onExport} disabled={busy} testID=\"studio-export\" aria-label=\"Export CSV\" title=\"Export CSV\">\n <Download className=\"h-3.5 w-3.5\" aria-hidden />\n {busy && <span className=\"ml-1.5\">{progress}</span>}\n </Button>\n );\n}\n\nexport function NewRowButton({ allowed, reason, onClick }: { allowed: boolean; reason?: string; onClick: () => void }) {\n return (\n <Button type=\"button\" size=\"sm\" onClick={onClick} disabled={!allowed} title={allowed ? undefined : reason} testID=\"studio-new-row\">\n <Plus className=\"mr-1 h-3.5 w-3.5\" aria-hidden />\n Add record\n </Button>\n );\n}\n\nexport type ViewKind = \"table\" | \"sheet\" | \"kanban\" | \"calendar\";\nconst VIEW_LABEL: Record<ViewKind, string> = { table: \"Table\", sheet: \"Sheet\", kanban: \"Board\", calendar: \"Calendar\" };\nconst VIEW_UNAVAILABLE: Partial<Record<ViewKind, string>> = {\n kanban: \"A board needs a field with a fixed set of values, like an enum.\",\n calendar: \"A calendar needs a date or timestamp field.\",\n};\n\n/** Switch between the table, the spreadsheet grid, a board and a calendar. */\nexport function ViewSwitch({\n view,\n onChange,\n available = { table: true, sheet: true },\n}: {\n view: ViewKind;\n onChange: (view: ViewKind) => void;\n /** Views this table can show. A board and a calendar each need a fitting field. */\n available?: Partial<Record<ViewKind, boolean>>;\n}) {\n return (\n <div role=\"group\" aria-label=\"View\" className=\"inline-flex rounded-md border p-0.5\" data-testid=\"studio-view-switch\">\n {([\"table\", \"sheet\", \"kanban\", \"calendar\"] as const)\n .filter((v) => v === \"table\" || v === \"sheet\" || available[v] !== undefined)\n .map((v) => (\n <button\n key={v}\n type=\"button\"\n aria-pressed={view === v}\n disabled={available[v] === false}\n title={available[v] === false ? VIEW_UNAVAILABLE[v] : undefined}\n onClick={() => onChange(v)}\n className={`rounded px-2 py-1 text-xs disabled:opacity-40 ${view === v ? \"bg-accent text-accent-foreground\" : \"text-muted-foreground hover:text-foreground\"}`}\n >\n {VIEW_LABEL[v]}\n </button>\n ))}\n </div>\n );\n}\n\n/** Which field lays out the board or the calendar. */\nexport function ViewFieldPicker({\n label,\n fields,\n value,\n onChange,\n}: {\n label: string;\n fields: readonly FieldSchema[];\n value: string;\n onChange: (field: string) => void;\n}) {\n return (\n <Select value={value} onValueChange={onChange}>\n <SelectTrigger className=\"h-9 w-auto gap-1.5 text-sm\" aria-label={label} data-testid=\"studio-view-field\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {fields.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {label} {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\n/** Which fields the grid shows. */\nexport function HideFields({\n fields,\n hidden,\n onChange,\n}: {\n fields: readonly FieldSchema[];\n hidden: ReadonlySet<string>;\n onChange: (hidden: Set<string>) => void;\n}) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"px-2\" testID=\"studio-hide-fields\">\n <EyeOff className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n {hidden.size ? `${hidden.size} hidden field${hidden.size === 1 ? \"\" : \"s\"}` : \"Hide fields\"}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-64 space-y-1 p-2\">\n {fields.map((f) => (\n <label key={f.name} className=\"flex cursor-pointer items-center gap-2 rounded px-2 py-1 text-sm hover:bg-muted\">\n <input\n type=\"checkbox\"\n className=\"h-3.5 w-3.5\"\n checked={!hidden.has(f.name)}\n onChange={() => {\n const next = new Set(hidden);\n if (next.has(f.name)) next.delete(f.name);\n else next.add(f.name);\n onChange(next);\n }}\n />\n <span className=\"truncate\">{fieldLabel(f)}</span>\n </label>\n ))}\n {hidden.size > 0 && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"w-full\" onClick={() => onChange(new Set())}>\n Show all\n </Button>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n\n/** Search every text field, as you type. */\nexport function SearchBox({ value, onChange }: { value: string; onChange: (value: string) => void }) {\n return (\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" aria-hidden />\n <Input\n type=\"search\"\n aria-label=\"Search\"\n placeholder=\"Search\"\n className=\"h-8 w-36 pl-7 text-sm\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n data-testid=\"studio-search\"\n />\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@marktiderman/genesis-ui/popover\";\nimport { Bookmark, CalendarDays, ChevronDown, Columns3, Lock, Plus, Search, Table2, X } from \"lucide-react\";\nimport type { SavedViewItem } from \"@marktiderman/genesis-ui/data\";\nimport { cn } from \"@marktiderman/genesis-ui/utils\";\n\nexport type StudioViewKind = \"grid\" | \"kanban\" | \"calendar\";\n\nconst VIEWS: { kind: StudioViewKind; label: string; icon: typeof Table2; unavailable: string }[] = [\n { kind: \"grid\", label: \"Grid\", icon: Table2, unavailable: \"\" },\n { kind: \"kanban\", label: \"Board\", icon: Columns3, unavailable: \"A board needs a field with a fixed set of values, like a status.\" },\n { kind: \"calendar\", label: \"Calendar\", icon: CalendarDays, unavailable: \"A calendar needs a date field.\" },\n];\n\n/** The left column: how to look at this table, and the views you've saved. */\nexport function ViewsPanel({\n view,\n available,\n onChange,\n saved,\n onLoad,\n onDelete,\n onSave,\n}: {\n view: StudioViewKind;\n available: Record<StudioViewKind, boolean>;\n onChange: (view: StudioViewKind) => void;\n saved: SavedViewItem[];\n onLoad: (view: SavedViewItem) => void;\n onDelete: (id: string) => void;\n onSave: (name: string) => void;\n}) {\n const [naming, setNaming] = useState(false);\n const [name, setName] = useState(\"\");\n return (\n <nav\n aria-label=\"Views\"\n className=\"flex shrink-0 flex-row gap-1 overflow-x-auto border-b p-2 text-sm md:w-40 md:flex-col md:overflow-visible md:border-b-0 md:border-r\"\n data-testid=\"studio-views\"\n >\n <p className=\"hidden px-2 pb-1 text-xs text-muted-foreground md:block\">Views</p>\n {VIEWS.map(({ kind, label, icon: Icon, unavailable }) => (\n <button\n key={kind}\n type=\"button\"\n aria-pressed={view === kind}\n disabled={!available[kind]}\n title={available[kind] ? undefined : unavailable}\n onClick={() => onChange(kind)}\n data-testid={`studio-view-${kind}`}\n className={cn(\n \"flex shrink-0 items-center gap-2 rounded-md px-2 py-1.5 text-left disabled:opacity-40\",\n view === kind ? \"bg-accent font-medium text-accent-foreground\" : \"text-muted-foreground hover:bg-muted hover:text-foreground\",\n )}\n >\n <Icon className=\"h-4 w-4\" aria-hidden />\n {label}\n </button>\n ))}\n {saved.length > 0 && <p className=\"hidden px-2 pb-1 pt-3 text-xs text-muted-foreground md:block\">Saved</p>}\n {saved.map((item) => (\n <span key={item.id} className=\"group flex shrink-0 items-center rounded-md hover:bg-muted\">\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 items-center gap-2 px-2 py-1.5 text-left text-muted-foreground hover:text-foreground\"\n onClick={() => onLoad(item)}\n data-testid=\"studio-saved-view\"\n >\n <Bookmark className=\"h-4 w-4 shrink-0\" aria-hidden />\n <span className=\"truncate\">{item.name}</span>\n </button>\n <button\n type=\"button\"\n aria-label={`Delete view ${item.name}`}\n className=\"mr-1 rounded p-0.5 text-muted-foreground opacity-0 hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100\"\n onClick={() => onDelete(item.id)}\n >\n <X className=\"h-3 w-3\" aria-hidden />\n </button>\n </span>\n ))}\n {naming ? (\n <form\n className=\"flex shrink-0 items-center gap-1 px-1 pt-1\"\n onSubmit={(e) => {\n e.preventDefault();\n if (!name.trim()) return;\n onSave(name.trim());\n setName(\"\");\n setNaming(false);\n }}\n >\n <input\n autoFocus\n aria-label=\"View name\"\n placeholder=\"View name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n onKeyDown={(e) => e.key === \"Escape\" && setNaming(false)}\n className=\"h-7 w-full min-w-24 rounded border bg-background px-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </form>\n ) : (\n <button\n type=\"button\"\n className=\"flex shrink-0 items-center gap-2 rounded-md px-2 py-1.5 text-left text-muted-foreground hover:bg-muted hover:text-foreground md:mt-2\"\n onClick={() => setNaming(true)}\n data-testid=\"studio-save-view\"\n >\n <Plus className=\"h-4 w-4\" aria-hidden />\n Save view\n </button>\n )}\n </nav>\n );\n}\n\n/** Table tabs across the top, as Airtable shows a base's tables. */\nexport function TableTabs({\n resources,\n selected,\n onSelect,\n variant = \"card\",\n}: {\n resources: { name: string; label?: string; access: { update: boolean; reason?: string } }[];\n selected?: string;\n onSelect: (resource: string) => void;\n /** `plain` draws underlined tabs on the page instead of a tinted band. */\n variant?: \"card\" | \"plain\";\n}) {\n const picker = resources.length > PICKER_AFTER && <AllTables resources={resources} selected={selected} onSelect={onSelect} />;\n if (variant === \"plain\") {\n return (\n <div className=\"flex items-end border-b\">\n <nav aria-label=\"Tables\" className=\"flex min-w-0 flex-1 gap-1 overflow-x-auto\" data-testid=\"studio-sidebar\">\n {resources.map((r) => {\n const active = r.name === selected;\n return (\n <button\n key={r.name}\n type=\"button\"\n onClick={() => onSelect(r.name)}\n aria-current={active ? \"page\" : undefined}\n title={r.access.update ? r.name : `${r.name}: ${r.access.reason ?? \"read-only\"}`}\n data-testid={`studio-table-${r.name}`}\n className={cn(\n \"-mb-px flex shrink-0 items-center gap-1.5 border-b-2 px-3 py-2 text-sm\",\n active ? \"border-primary font-medium text-foreground\" : \"border-transparent text-muted-foreground hover:text-foreground\",\n )}\n >\n {r.label ?? r.name}\n {!r.access.update && <Lock className=\"h-3 w-3 text-muted-foreground\" aria-label=\"Read-only\" />}\n </button>\n );\n })}\n </nav>\n {picker}\n </div>\n );\n }\n return (\n <div className=\"flex items-end bg-primary/10 pr-2\">\n <nav aria-label=\"Tables\" className=\"flex min-w-0 flex-1 gap-0.5 overflow-x-auto px-2 pt-1.5\" data-testid=\"studio-sidebar\">\n {resources.map((r) => {\n const active = r.name === selected;\n return (\n <button\n key={r.name}\n type=\"button\"\n onClick={() => onSelect(r.name)}\n aria-current={active ? \"page\" : undefined}\n title={r.access.update ? r.name : `${r.name}: ${r.access.reason ?? \"read-only\"}`}\n data-testid={`studio-table-${r.name}`}\n className={cn(\n \"flex shrink-0 items-center gap-1.5 rounded-t-md px-3 py-1.5 text-sm\",\n active ? \"bg-background font-medium text-foreground\" : \"text-foreground/70 hover:bg-background/60 hover:text-foreground\",\n )}\n >\n {r.label ?? r.name}\n {!r.access.update && <Lock className=\"h-3 w-3 text-muted-foreground\" aria-label=\"Read-only\" />}\n </button>\n );\n })}\n </nav>\n {picker}\n </div>\n );\n}\n\n/** Past this many tables, a searchable list sits at the end of the tabs. */\nconst PICKER_AFTER = 8;\n\nfunction AllTables({\n resources,\n selected,\n onSelect,\n}: {\n resources: { name: string; label?: string; access: { update: boolean } }[];\n selected?: string;\n onSelect: (resource: string) => void;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const q = query.trim().toLowerCase();\n const shown = resources.filter((r) => !q || (r.label ?? r.name).toLowerCase().includes(q) || r.name.toLowerCase().includes(q));\n return (\n <Popover open={open} onOpenChange={(next) => { setOpen(next); if (!next) setQuery(\"\"); }}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"mb-1 ml-1 flex shrink-0 items-center gap-1 rounded-md px-2 py-1 text-sm text-muted-foreground hover:bg-muted hover:text-foreground\"\n data-testid=\"studio-all-tables\"\n >\n All tables ({resources.length})\n <ChevronDown className=\"h-3.5 w-3.5\" aria-hidden />\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-72 p-1\">\n <div className=\"relative p-1\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" aria-hidden />\n <input\n autoFocus\n aria-label=\"Find a table\"\n placeholder=\"Find a table\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && shown[0]) {\n onSelect(shown[0].name);\n setOpen(false);\n }\n }}\n className=\"h-8 w-full rounded border bg-background pl-7 pr-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </div>\n <ul className=\"max-h-72 overflow-y-auto\" aria-label=\"Tables\">\n {shown.map((r) => (\n <li key={r.name}>\n <button\n type=\"button\"\n aria-current={r.name === selected ? \"page\" : undefined}\n className={cn(\n \"flex w-full items-center justify-between gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-muted\",\n r.name === selected && \"bg-accent text-accent-foreground\",\n )}\n onClick={() => {\n onSelect(r.name);\n setOpen(false);\n }}\n >\n <span className=\"truncate\">{r.label ?? r.name}</span>\n {!r.access.update && <Lock className=\"h-3 w-3 shrink-0 text-muted-foreground\" aria-label=\"Read-only\" />}\n </button>\n </li>\n ))}\n {shown.length === 0 && <li className=\"px-2 py-1.5 text-sm text-muted-foreground\">No table matches.</li>}\n </ul>\n </PopoverContent>\n </Popover>\n );\n}\n\n\n","// How a value looks in the grid: choices as colored pills, yes/no as a\n// check, links as chips, numbers right-aligned. Editing and copying always\n// use the plain text (`editText`), so what you see never changes what you save.\n\nimport type { ReactNode } from \"react\";\nimport {\n Braces,\n Calendar,\n Check,\n CircleChevronDown,\n Clock,\n Hash,\n KeyRound,\n Link2,\n List,\n SquareCheck,\n Type,\n} from \"lucide-react\";\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\nimport { cn } from \"@marktiderman/genesis-ui/utils\";\nimport { displayText } from \"../values\";\n\n/** An icon for the field's type, as Airtable shows in each column header. */\nexport function FieldIcon({ field, isKey }: { field: FieldSchema; isKey?: boolean }) {\n const className = \"h-3.5 w-3.5\";\n if (isKey) return <KeyRound className={className} />;\n if (field.array) return <List className={className} />;\n if (field.references) return <Link2 className={className} />;\n if (field.enumValues) return <CircleChevronDown className={className} />;\n switch (field.type) {\n case \"number\":\n return <Hash className={className} />;\n case \"boolean\":\n return <SquareCheck className={className} />;\n case \"json\":\n return <Braces className={className} />;\n case \"datetime\":\n return field.dbType === \"date\" || field.widget === \"date\" ? <Calendar className={className} /> : <Clock className={className} />;\n default:\n return <Type className={className} />;\n }\n}\n\n/** Tints from the design system's palette, one per choice. */\nconst PILL_TINTS = [\n \"bg-info/20\",\n \"bg-chart-2/25\",\n \"bg-chart-4/30\",\n \"bg-chart-1/20\",\n \"bg-chart-5/25\",\n \"bg-chart-3/20\",\n \"bg-primary/15\",\n];\nconst POSITIVE = /^(active|paid|done|shipped|published|complete(d)?|approved|open|live|yes|true)$/i;\nconst PENDING = /^(draft|pending|paused|review|in[ _-]?progress|waiting|scheduled|new)$/i;\nconst NEGATIVE = /^(archived|cancel(l)?ed|closed|rejected|failed|deleted|inactive|no|false)$/i;\n\n/** A choice's tint: status-like words get their meaning's color, others a stable one by position. */\nexport function pillTint(value: string, choices: readonly string[] = []): string {\n if (POSITIVE.test(value)) return \"bg-success/20\";\n if (PENDING.test(value)) return \"bg-warning/25\";\n if (NEGATIVE.test(value)) return \"bg-muted\";\n const at = choices.indexOf(value);\n const index = at >= 0 ? at : [...value].reduce((h, ch) => (h * 31 + ch.charCodeAt(0)) >>> 0, 7);\n return PILL_TINTS[index % PILL_TINTS.length]!;\n}\n\nexport function Pill({ value, tint, className }: { value: string; tint: string; className?: string }) {\n return (\n <span className={cn(\"inline-flex max-w-full items-center truncate rounded-full px-2 py-0.5 text-xs text-foreground\", tint, className)}>\n {value}\n </span>\n );\n}\n\n/** A Postgres timestamp, shortened to the minute for the grid. The full value is still what's edited. */\nfunction shortTimestamp(text: string): string {\n const m = /^(\\d{4}-\\d{2}-\\d{2})[ T](\\d{2}:\\d{2})/.exec(text);\n return m ? `${m[1]} ${m[2]}` : text;\n}\n\n/** The cell's display. `linkLabel` is the linked row's name, when one is known. */\nexport function CellValue({ field, value, linkLabel }: { field: FieldSchema; value: unknown; linkLabel?: string }): ReactNode {\n const text = displayText(value);\n if (text === null || text === \"\") return null;\n if (field.type === \"boolean\" && !field.array) {\n return value === true || text === \"true\" ? (\n <span className=\"inline-flex h-4 w-4 items-center justify-center rounded bg-success/20\" aria-label=\"Yes\">\n <Check className=\"h-3 w-3\" aria-hidden />\n </span>\n ) : (\n <span className=\"inline-block h-4 w-4 rounded border\" aria-label=\"No\" />\n );\n }\n if (field.enumValues && !field.array) return <Pill value={text} tint={pillTint(text, field.enumValues)} />;\n if (field.references) {\n return (\n <span className=\"inline-flex max-w-full items-center gap-1 truncate rounded bg-info/15 px-1.5 py-0.5 text-xs text-foreground\" title={text}>\n {linkLabel ?? text}\n </span>\n );\n }\n if (field.array && Array.isArray(value)) {\n return (\n <span className=\"flex gap-1 overflow-hidden\">\n {value.map((item, i) => (\n <Pill key={i} value={displayText(item) ?? \"\"} tint=\"bg-muted\" />\n ))}\n </span>\n );\n }\n if (field.type === \"datetime\" && !(field.dbType === \"date\" || field.widget === \"date\")) {\n return <span title={text}>{shortTimestamp(text)}</span>;\n }\n if (field.type === \"json\") return <span className=\"font-mono text-xs\">{text}</span>;\n return <>{text}</>;\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useQueries } from \"@tanstack/react-query\";\nimport type { BaseRecord, DataProvider, FilterParam, SortParam } from \"@marktiderman/genesis-core/provider\";\nimport { encodeRecordKey, isDataWriteError, type AuditEntry, type FieldSchema, type ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { KanbanBoard, type KanbanColumn } from \"@marktiderman/genesis-ui/data\";\nimport { choicesFor, displayText, fieldLabel } from \"../values\";\n\ntype Row = Record<string, unknown>;\n\n/** Cards per column page. */\nexport const KANBAN_PAGE = 50;\nconst NONE = \"__genesis_none__\";\n\nexport interface KanbanViewProps {\n provider: DataProvider;\n schema: ResourceSchema;\n sessionKey: string | number | null;\n /** The field whose value is each card's column. */\n field: FieldSchema;\n filters: FilterParam[];\n sorts: SortParam[];\n search: string;\n onOpenRecord: (id: string) => void;\n onMoved: (record: string, audit?: AuditEntry) => void;\n onFailed: (record: string, message: string) => void;\n onSignedOut: () => void;\n}\n\nfunction versionOf(schema: ResourceSchema, row: Row): string | null {\n const field = schema.version?.field;\n return field && row[field] != null ? String(row[field]) : null;\n}\n\n/**\n * A board of the table's rows, one column per value of `field`. Each column\n * is paged on its own (50 cards, then \"Load more\"), with the same filters,\n * search and sort as the table. Moving a card is a version-checked update of\n * `field`, so a card someone else just changed is refused, not overwritten.\n */\nexport function KanbanView({\n provider,\n schema,\n sessionKey,\n field,\n filters,\n sorts,\n search,\n onOpenRecord,\n onMoved,\n onFailed,\n onSignedOut,\n}: KanbanViewProps) {\n const values = useMemo(() => [...(choicesFor(field) ?? []), ...(field.nullable ? [NONE] : [])], [field]);\n const [pages, setPages] = useState<Record<string, number>>({});\n const [moving, setMoving] = useState<string | null>(null);\n const filterKey = JSON.stringify(filters);\n const sortKey = JSON.stringify(sorts);\n\n const specs = values.flatMap((value) =>\n Array.from({ length: pages[value] ?? 1 }, (_, i) => ({ value, page: i + 1 })),\n );\n const results = useQueries({\n queries: specs.map(({ value, page }) => ({\n queryKey: [\"genesis-studio\", sessionKey, \"list\", schema.name, \"kanban\", field.name, value, page, filterKey, search, sortKey],\n retry: false,\n queryFn: () =>\n provider.getList<BaseRecord>(schema.name, {\n pagination: { page, perPage: KANBAN_PAGE },\n sort: sorts[0],\n sorts,\n filters: [\n ...filters.filter((f) => f.field !== field.name),\n value === NONE\n ? ({ field: field.name, operator: \"is_null\" } as FilterParam)\n : ({ field: field.name, operator: \"eq\", value } as FilterParam),\n ],\n search: search ? { query: search, fields: [] } : undefined,\n }),\n })),\n });\n\n const failure = results.find((r) => r.error)?.error;\n const signedOut = Boolean(failure && isDataWriteError(failure) && failure.outcome === \"unauthenticated\");\n useEffect(() => {\n if (signedOut) onSignedOut();\n }, [signedOut, onSignedOut]);\n // A filter on the board's own field is replaced by each column's value.\n const ownFilter = filters.some((f) => f.field === field.name);\n\n const columns: KanbanColumn<Row>[] = values.map((value) => {\n const mine = specs.map((s, i) => ({ s, r: results[i]! })).filter(({ s }) => s.value === value);\n return {\n key: value,\n label: value === NONE ? \"No value\" : value,\n items: mine.flatMap(({ r }) => (r.data?.data ?? []) as Row[]),\n ...(mine[0]?.r.data ? { total: mine[0].r.data.total } : {}),\n };\n });\n\n const labelField = schema.labelField;\n // A card's subtitle: the next two fields a person would read, not keys,\n // links, ids or the version.\n const keyNames = new Set(typeof schema.key === \"string\" ? [schema.key] : schema.key);\n const extra = schema.fields\n .filter(\n (f) =>\n f.name !== labelField &&\n f.name !== field.name &&\n f.name !== schema.version?.field &&\n !keyNames.has(f.name) &&\n !f.references &&\n !f.array &&\n f.type !== \"json\" &&\n f.dbType !== \"uuid\",\n )\n .slice(0, 2);\n const canMove = Boolean(field.permissions?.update && schema.version);\n\n async function move(row: Row, to: string) {\n const id = String(encodeRecordKey(schema, row));\n setMoving(id);\n try {\n const result = await provider.update<BaseRecord>(schema.name, {\n id,\n data: { [field.name]: to === NONE ? null : to },\n expectedVersion: versionOf(schema, row),\n });\n onMoved(id, result.audit);\n } catch (error) {\n if (isDataWriteError(error) && error.outcome === \"unauthenticated\") onSignedOut();\n onFailed(id, error instanceof Error ? error.message : String(error));\n throw error;\n } finally {\n setMoving(null);\n }\n }\n\n return (\n <div className=\"space-y-2\" data-testid=\"studio-kanban\">\n {ownFilter && (\n <p className=\"text-xs text-muted-foreground\">Your filter on {field.name} is set aside here: each column shows one of its values.</p>\n )}\n {failure && !signedOut && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {failure instanceof Error ? failure.message : String(failure)}\n </p>\n )}\n <div>\n <KanbanBoard<Row>\n className=\"grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] md:grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] lg:grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] xl:grid-cols-[repeat(auto-fill,minmax(15rem,1fr))]\"\n columns={columns}\n getKey={(row) => String(encodeRecordKey(schema, row))}\n getItemLabel={(row) => displayText(labelField ? row[labelField] : undefined) ?? String(encodeRecordKey(schema, row))}\n onMoveItem={canMove ? move : undefined}\n emptyMessage=\"No rows\"\n renderCard={(row) => {\n const id = String(encodeRecordKey(schema, row));\n return (\n <button\n type=\"button\"\n onClick={() => onOpenRecord(id)}\n aria-busy={moving === id || undefined}\n className=\"w-full rounded-lg border bg-card p-3 pr-8 text-left text-sm shadow-sm hover:border-primary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n data-testid=\"studio-kanban-card\"\n >\n <span className=\"block truncate font-medium\">{displayText(labelField ? row[labelField] : undefined) ?? id}</span>\n {extra.map((f) => (\n <span key={f.name} className=\"block truncate text-xs text-muted-foreground\">\n {fieldLabel(f)}: {displayText(row[f.name]) ?? \"—\"}\n </span>\n ))}\n </button>\n );\n }}\n renderColumnFooter={(column) =>\n column.total !== undefined && column.total > column.items.length ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setPages((p) => ({ ...p, [column.key]: (p[column.key] ?? 1) + 1 }))}\n >\n Load more ({(column.total - column.items.length).toLocaleString()} left)\n </Button>\n ) : null\n }\n />\n </div>\n {!canMove && (\n <p className=\"text-xs text-muted-foreground\">\n {field.permissions?.reason ?? `Cards can't be moved: ${field.name} can't be edited here.`}\n </p>\n )}\n </div>\n );\n}\n","import { useEffect, useMemo } from \"react\";\nimport { keepPreviousData, useQuery } from \"@tanstack/react-query\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport type { BaseRecord, DataProvider, FilterParam, SortParam } from \"@marktiderman/genesis-core/provider\";\nimport { encodeRecordKey, isDataWriteError, type FieldSchema, type ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { cn } from \"@marktiderman/genesis-ui/utils\";\nimport { displayText, fieldLabel } from \"../values\";\nimport { currentMonth, dayKey, isDateOnly, localDay, monthBounds, shiftMonth } from \"./fields\";\n\ntype Row = Record<string, unknown>;\n\n/** Most rows one month shows. Past this, the view says so and asks for a filter. */\nexport const CALENDAR_CAP = 200;\nconst WEEKDAYS = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"];\n\nexport interface CalendarViewProps {\n provider: DataProvider;\n schema: ResourceSchema;\n sessionKey: string | number | null;\n /** The date or timestamp field that places each row. */\n field: FieldSchema;\n /** `YYYY-MM`; this month when absent. */\n month: string | undefined;\n onMonthChange: (month: string) => void;\n filters: FilterParam[];\n sorts: SortParam[];\n search: string;\n onOpenRecord: (id: string) => void;\n onSignedOut: () => void;\n}\n\n/** The weeks of a month, Monday first, each day as `YYYY-MM-DD` or null outside the month. */\nfunction weeksOf(month: string): (string | null)[][] {\n const [y, m] = month.split(\"-\").map(Number) as [number, number];\n const first = new Date(y, m - 1, 1);\n const days = new Date(y, m, 0).getDate();\n const lead = (first.getDay() + 6) % 7;\n const cells: (string | null)[] = [\n ...Array.from({ length: lead }, () => null),\n ...Array.from({ length: days }, (_, i) => dayKey(new Date(y, m - 1, i + 1))),\n ];\n while (cells.length % 7) cells.push(null);\n return Array.from({ length: cells.length / 7 }, (_, w) => cells.slice(w * 7, w * 7 + 7));\n}\n\n/**\n * A month of the table's rows, placed by a date field. One request per\n * month (a `gte`/`lt` range on the field, with the table's filters, search\n * and sort), up to 200 rows. A timestamp shows on the day it falls in the\n * viewer's time zone.\n */\nexport function CalendarView({\n provider,\n schema,\n sessionKey,\n field,\n month: monthProp,\n onMonthChange,\n filters,\n sorts,\n search,\n onOpenRecord,\n onSignedOut,\n}: CalendarViewProps) {\n const month = monthProp ?? currentMonth();\n const dateOnly = isDateOnly(field);\n const { from, to } = monthBounds(month, field);\n const query = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"list\", schema.name, \"calendar\", field.name, month, JSON.stringify(filters), search, JSON.stringify(sorts)],\n placeholderData: keepPreviousData,\n retry: false,\n queryFn: () =>\n provider.getList<BaseRecord>(schema.name, {\n pagination: { page: 1, perPage: CALENDAR_CAP },\n sort: sorts[0] ?? { field: field.name, order: \"asc\" },\n sorts: sorts.length ? sorts : [{ field: field.name, order: \"asc\" }],\n filters: [\n ...filters,\n { field: field.name, operator: \"gte\", value: from } as FilterParam,\n { field: field.name, operator: \"lt\", value: to } as FilterParam,\n ],\n search: search ? { query: search, fields: [] } : undefined,\n }),\n });\n const signedOut = isDataWriteError(query.error) && query.error.outcome === \"unauthenticated\";\n useEffect(() => {\n if (signedOut) onSignedOut();\n }, [signedOut, onSignedOut]);\n\n const rows = (query.data?.data ?? []) as Row[];\n const byDay = useMemo(() => {\n const map = new Map<string, Row[]>();\n for (const row of rows) {\n const day = localDay(row[field.name], dateOnly);\n if (!day) continue;\n map.set(day, [...(map.get(day) ?? []), row]);\n }\n return map;\n }, [rows, field.name, dateOnly]);\n const total = query.data?.total ?? 0;\n const today = dayKey(new Date());\n const title = new Date(`${month}-01T00:00:00`).toLocaleDateString(undefined, { month: \"long\", year: \"numeric\" });\n const labelField = schema.labelField;\n\n return (\n <div className=\"space-y-2\" data-testid=\"studio-calendar\">\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"icon\" className=\"h-8 w-8\" aria-label=\"Previous month\" onClick={() => onMonthChange(shiftMonth(month, -1))}>\n <ChevronLeft className=\"h-4 w-4\" aria-hidden />\n </Button>\n <Button type=\"button\" variant=\"outline\" size=\"icon\" className=\"h-8 w-8\" aria-label=\"Next month\" onClick={() => onMonthChange(shiftMonth(month, 1))}>\n <ChevronRight className=\"h-4 w-4\" aria-hidden />\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => onMonthChange(currentMonth())}>\n Today\n </Button>\n <h3 className=\"text-sm font-semibold\" aria-live=\"polite\">\n {title}\n </h3>\n <span className=\"text-xs text-muted-foreground\">by {fieldLabel(field)}</span>\n </div>\n {total > rows.length && (\n <p role=\"status\" className=\"text-xs text-muted-foreground\" data-testid=\"studio-calendar-capped\">\n Showing the first {rows.length.toLocaleString()} of {total.toLocaleString()} rows this month. Filter the table to see the rest.\n </p>\n )}\n {query.isError && !signedOut && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {query.error instanceof Error ? query.error.message : String(query.error)}\n </p>\n )}\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[42rem] table-fixed border-collapse text-sm\">\n <caption className=\"sr-only\">\n {schema.label ?? schema.name} by {fieldLabel(field)}, {title}\n </caption>\n <thead>\n <tr>\n {WEEKDAYS.map((d) => (\n <th key={d} scope=\"col\" className=\"py-1 text-left text-xs font-medium text-muted-foreground\">\n {d}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {weeksOf(month).map((week, w) => (\n <tr key={w}>\n {week.map((day, d) => (\n <td\n key={day ?? `pad-${w}-${d}`}\n className={cn(\"h-28 border align-top\", !day && \"bg-muted/30\")}\n data-day={day ?? undefined}\n >\n {day && (\n <div className=\"flex h-full flex-col gap-0.5 p-1\">\n <span className={cn(\"text-xs\", day === today ? \"font-bold text-primary\" : \"text-muted-foreground\")}>\n {Number(day.slice(8))}\n </span>\n <ul className=\"max-h-24 space-y-0.5 overflow-y-auto\">\n {(byDay.get(day) ?? []).map((row) => {\n const id = String(encodeRecordKey(schema, row));\n return (\n <li key={id}>\n <button\n type=\"button\"\n className=\"w-full truncate rounded bg-primary/10 px-1.5 py-0.5 text-left text-xs hover:bg-primary/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n onClick={() => onOpenRecord(id)}\n data-testid=\"studio-calendar-item\"\n >\n {displayText(labelField ? row[labelField] : undefined) ?? id}\n </button>\n </li>\n );\n })}\n </ul>\n </div>\n )}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n","// Which fields can lay out a board or a calendar, and reading the dates the\n// handler sends (Postgres text, e.g. `2026-10-19 09:30:00.123456+00`).\n\nimport type { FieldSchema, ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { choicesFor } from \"../values\";\n\n/** Fields with a fixed set of values: an enum, or a yes/no. */\nexport function boardFields(schema: ResourceSchema): FieldSchema[] {\n return schema.fields.filter((f) => !f.array && Boolean(choicesFor(f)));\n}\n\n/** Date and timestamp fields. */\nexport function dateFields(schema: ResourceSchema): FieldSchema[] {\n return schema.fields.filter((f) => !f.array && f.type === \"datetime\" && !/^time( |$)|interval/.test(f.dbType ?? \"\"));\n}\n\n/** True for a `date` column: no time, no zone. */\nexport function isDateOnly(field: FieldSchema): boolean {\n return field.dbType === \"date\" || field.widget === \"date\";\n}\n\nconst DB_DATE = /^(\\d{4}-\\d{2}-\\d{2})(?:[ T](\\d{2}:\\d{2}(?::\\d{2})?)(\\.\\d+)?)?\\s*(Z|[+-]\\d{2}(?::?\\d{2})?)?$/;\n\n/**\n * The local calendar day (`YYYY-MM-DD`) a stored value falls on, or null.\n * A `date` is that day wherever you are; a timestamp is placed on the day it\n * is in the viewer's time zone.\n */\nexport function localDay(value: unknown, dateOnly: boolean): string | null {\n if (typeof value !== \"string\") return null;\n const m = DB_DATE.exec(value.trim());\n if (!m) return null;\n if (dateOnly || !m[2]) return m[1]!;\n let zone = m[4] ?? \"\";\n if (/^[+-]\\d{2}$/.test(zone)) zone += \":00\";\n else if (/^[+-]\\d{4}$/.test(zone)) zone = `${zone.slice(0, 3)}:${zone.slice(3)}`;\n const time = m[2].length === 5 ? `${m[2]}:00` : m[2];\n const ms = m[3] ? m[3].slice(0, 4).padEnd(4, \"0\") : \"\";\n const date = new Date(`${m[1]}T${time}${ms}${zone}`);\n if (Number.isNaN(date.getTime())) return null;\n return dayKey(date);\n}\n\nexport function dayKey(date: Date): string {\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n}\n\n/** True for a timestamp that names an instant (`timestamptz`), not a wall-clock time. */\nexport function isZoned(field: FieldSchema): boolean {\n return !isDateOnly(field) && (field.dbType === undefined || /with time zone|timestamptz/.test(field.dbType));\n}\n\n/**\n * The bounds of a month, as filter values for this field: `[start, nextStart)`.\n * An instant is bounded by the viewer's midnights; a date or wall-clock\n * timestamp by the calendar days themselves.\n */\nexport function monthBounds(month: string, field: FieldSchema): { from: string; to: string } {\n const [y, m] = month.split(\"-\").map(Number) as [number, number];\n const start = new Date(y, m - 1, 1);\n const next = new Date(y, m, 1);\n return isZoned(field)\n ? { from: start.toISOString(), to: next.toISOString() }\n : { from: dayKey(start), to: dayKey(next) };\n}\n\nexport function currentMonth(now = new Date()): string {\n return dayKey(now).slice(0, 7);\n}\n\nexport function shiftMonth(month: string, by: number): string {\n const [y, m] = month.split(\"-\").map(Number) as [number, number];\n return currentMonth(new Date(y, m - 1 + by, 1));\n}\n","import { useMemo, useState } from \"react\";\nimport { Upload } from \"lucide-react\";\nimport type { BulkResult, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport type { ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"@marktiderman/genesis-ui/dialog\";\nimport { Label } from \"@marktiderman/genesis-ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@marktiderman/genesis-ui/select\";\nimport { parseCsv } from \"../lib/csv\";\nimport { fieldLabel } from \"../values\";\n\nconst SKIP = \"__genesis_skip__\";\n\nexport interface ImportDialogProps {\n provider: DataProvider;\n schema: ResourceSchema;\n onImported: (count: number) => void;\n}\n\n/**\n * CSV import (DATA-STUDIO.md P2): map the file's columns to fields, check\n * every row against the database with a dry run, then add them all in one\n * transaction. Nothing is coerced or dropped: a value that won't convert is\n * listed, with the database's reason, before anything is kept.\n */\nexport function ImportDialog({ provider, schema, onImported }: ImportDialogProps) {\n const [open, setOpen] = useState(false);\n const [file, setFile] = useState<{ name: string; header: string[]; rows: string[][] } | null>(null);\n const [mapping, setMapping] = useState<Record<number, string>>({});\n const [check, setCheck] = useState<BulkResult | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const targets = useMemo(() => schema.fields.filter((f) => schema.createFields?.includes(f.name)), [schema]);\n const allowed = Boolean(schema.access.create && provider.importRows);\n\n async function readFile(input: File) {\n const parsed = parseCsv(await input.text());\n setFile({ name: input.name, ...parsed });\n // Match columns to fields by name, case-insensitively.\n const auto: Record<number, string> = {};\n parsed.header.forEach((h, i) => {\n const field = targets.find((f) => f.name.toLowerCase() === h.toLowerCase());\n if (field) auto[i] = field.name;\n });\n setMapping(auto);\n setCheck(null);\n setError(null);\n }\n\n function rowsToSend() {\n if (!file) return [];\n return file.rows.map((cells) => {\n const row: Record<string, unknown> = {};\n for (const [index, field] of Object.entries(mapping)) {\n if (field === SKIP) continue;\n const value = cells[Number(index)] ?? \"\";\n // An empty cell leaves the field to its default (or null).\n if (value !== \"\") row[field] = value;\n }\n return row;\n });\n }\n\n async function run(dryRun: boolean) {\n setBusy(true);\n setError(null);\n try {\n const result = await provider.importRows!(schema.name, { rows: rowsToSend(), dryRun });\n if (dryRun) setCheck(result);\n else if (result.ok) {\n onImported(result.count);\n setOpen(false);\n setFile(null);\n setCheck(null);\n } else setCheck(result);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(false);\n }\n }\n\n const mapped = Object.values(mapping).filter((f) => f && f !== SKIP).length;\n\n return (\n <>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setOpen(true)}\n disabled={!allowed}\n title={allowed ? \"Import CSV\" : schema.access.reasons?.create ?? \"This data provider can't import.\"}\n testID=\"studio-import\"\n aria-label=\"Import CSV\"\n >\n <Upload className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent className=\"max-h-[85vh] overflow-y-auto sm:max-w-2xl\" data-testid=\"studio-import-dialog\">\n <DialogHeader>\n <DialogTitle>Import into {schema.label ?? schema.name}</DialogTitle>\n <DialogDescription>\n Every row is checked against the database first. The import then adds all of them in one transaction, or none.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"studio-import-file\">CSV file, with a header row</Label>\n <input\n id=\"studio-import-file\"\n type=\"file\"\n accept=\".csv,text/csv\"\n className=\"block w-full text-sm\"\n onChange={(e) => e.target.files?.[0] && void readFile(e.target.files[0])}\n data-testid=\"studio-import-file\"\n />\n </div>\n {file && (\n <>\n <p className=\"text-xs text-muted-foreground\">\n {file.name}: {file.rows.length} rows, {file.header.length} columns.\n </p>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {file.header.map((column, i) => (\n <div key={`${column}-${i}`} className=\"flex items-center gap-2\">\n <span className=\"w-32 truncate font-mono text-xs\" title={column}>\n {column || `(column ${i + 1})`}\n </span>\n <Select value={mapping[i] ?? SKIP} onValueChange={(v) => {\n setMapping((m) => ({ ...m, [i]: v }));\n // A new mapping hasn't been checked: run the dry run again before importing.\n setCheck(null);\n }}>\n <SelectTrigger className=\"h-8 flex-1 text-xs\" aria-label={`Field for ${column}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={SKIP}>Skip this column</SelectItem>\n {targets.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ))}\n </div>\n {check && (\n <div className=\"rounded-md border p-3 text-sm\" role=\"status\" data-testid=\"studio-import-check\">\n {check.ok ? (\n <p>All {check.count} rows are ready to import.</p>\n ) : (\n <>\n <p className=\"font-medium text-destructive\">\n {(check.failures ?? []).length} of {file.rows.length} rows won't import. Nothing was changed.\n </p>\n <ul className=\"mt-2 max-h-48 space-y-1 overflow-y-auto font-mono text-xs\">\n {(check.failures ?? []).map((f) => (\n <li key={f.index}>\n Row {f.index + 2}: {f.message}\n </li>\n ))}\n </ul>\n </>\n )}\n </div>\n )}\n {error && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {error}\n </p>\n )}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"outline\" disabled={busy || mapped === 0} onClick={() => void run(true)} testID=\"studio-import-check-button\">\n {busy ? \"Checking…\" : \"Check rows\"}\n </Button>\n <Button type=\"button\" disabled={busy || !check?.ok} onClick={() => void run(false)} testID=\"studio-import-commit\">\n Import {check?.ok ? check.count : \"\"} rows\n </Button>\n </div>\n </>\n )}\n </div>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","import { useState } from \"react\";\nimport type { BulkResult } from \"@marktiderman/genesis-core/provider\";\nimport type { ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"@marktiderman/genesis-ui/dialog\";\nimport { Input } from \"@marktiderman/genesis-ui/input\";\nimport { Label } from \"@marktiderman/genesis-ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@marktiderman/genesis-ui/select\";\nimport { choicesFor, parseDraft, fieldLabel } from \"../values\";\n\nexport interface BulkEditDialogProps {\n schema: ResourceSchema;\n count: number;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Apply `data` to every selected row, in one transaction. */\n onApply: (data: Record<string, unknown>) => Promise<BulkResult>;\n}\n\n/** Set one field on every selected row: all of them change, or none do. */\nexport function BulkEditDialog({ schema, count, open, onOpenChange, onApply }: BulkEditDialogProps) {\n const fields = schema.fields.filter((f) => f.permissions?.update && !f.references);\n const [field, setField] = useState(fields[0]?.name ?? \"\");\n const [value, setValue] = useState(\"\");\n const [result, setResult] = useState<BulkResult | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const target = fields.find((f) => f.name === field);\n const choices = target ? choicesFor(target) : undefined;\n\n async function apply() {\n if (!target) return;\n setBusy(true);\n setError(null);\n try {\n const outcome = await onApply({ [target.name]: parseDraft(target, value) });\n if (outcome.ok) onOpenChange(false);\n else setResult(outcome);\n } catch (e) {\n setError(`Nothing was changed: ${e instanceof Error ? e.message : String(e)}`);\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n onOpenChange(next);\n if (!next) setResult(null);\n }}\n >\n <DialogContent className=\"sm:max-w-md\" data-testid=\"studio-bulk-edit\">\n <DialogHeader>\n <DialogTitle>\n Set a field on {count} row{count === 1 ? \"\" : \"s\"}\n </DialogTitle>\n <DialogDescription>Each row is checked against the version you see. All of them change, or none do.</DialogDescription>\n </DialogHeader>\n <div className=\"space-y-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"studio-bulk-field\">Field</Label>\n <Select value={field} onValueChange={(v) => { setField(v); setValue(\"\"); setError(null); }}>\n <SelectTrigger id=\"studio-bulk-field\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {fields.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"studio-bulk-value\">New value</Label>\n {choices ? (\n <Select value={value} onValueChange={(v) => { setValue(v); setError(null); }}>\n <SelectTrigger id=\"studio-bulk-value\">\n <SelectValue placeholder=\"Choose…\" />\n </SelectTrigger>\n <SelectContent>\n {choices.map((c) => (\n <SelectItem key={c} value={c}>\n {c}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <Input id=\"studio-bulk-value\" value={value} onChange={(e) => { setValue(e.target.value); setError(null); }} />\n )}\n </div>\n {error && (\n <p role=\"alert\" className=\"rounded-md border border-destructive/40 p-2 text-sm text-destructive\" data-testid=\"studio-bulk-error\">\n {error}\n </p>\n )}\n {result && !result.ok && (\n <div role=\"alert\" className=\"rounded-md border border-destructive/40 p-2 text-sm text-destructive\">\n Nothing was changed: {(result.failures ?? []).length} row(s) failed.\n <ul className=\"mt-1 list-disc pl-5 text-xs\">\n {(result.failures ?? []).slice(0, 10).map((f) => (\n <li key={f.index}>{f.message}</li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)}>\n Cancel\n </Button>\n <Button type=\"button\" disabled={busy || !target} onClick={() => void apply()} testID=\"studio-bulk-apply\">\n {busy ? \"Saving…\" : `Set on ${count} row${count === 1 ? \"\" : \"s\"}`}\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n","import { useMemo, type ReactNode } from \"react\";\nimport { Maximize2 } from \"lucide-react\";\nimport type { BaseRecord, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport { encodeRecordKey, isDataWriteError, keyFields, type AuditEntry, type ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { SheetCommitError, SheetGrid, type SheetCellChange, type SheetGridColumn } from \"@marktiderman/genesis-ui/sheet-grid\";\nimport { choicesFor, editText, fieldLabel, parseDraft } from \"../values\";\nimport { CellValue, FieldIcon } from \"../grid/cells\";\n\ntype Row = Record<string, unknown>;\n\n/** Fields in grid order: the field that names a row first, as Airtable's primary field, then the table's order. */\nexport function gridFields(schema: ResourceSchema) {\n const primary = schema.fields.find((f) => f.name === schema.labelField);\n return primary ? [primary, ...schema.fields.filter((f) => f !== primary)] : [...schema.fields];\n}\n\nexport interface SheetViewProps {\n provider: DataProvider;\n schema: ResourceSchema;\n rows: Row[];\n keys: Map<Row, string>;\n linkLabels: Map<string, Map<string, string>>;\n /** Saved rows, to put back in the list. */\n onSaved: (updates: { old: Row; next: Row; audit?: AuditEntry }[]) => void;\n onFailed: (message: string) => void;\n onUndo: () => void;\n onNotice: (message: string) => void;\n /** Fields not shown. */\n hidden?: ReadonlySet<string>;\n /** Selected row ids, and how to change them. Without these, no checkboxes. */\n selected?: ReadonlySet<string>;\n onToggleSelect?: (id: string) => void;\n onToggleAll?: () => void;\n /** Open a row in the record pop-up. */\n onOpenRecord?: (id: string) => void;\n /** The number shown for the first row (pages after the first start later). */\n firstRowNumber?: number;\n /** Under the last row, e.g. \"Add a record\". */\n footer?: ReactNode;\n height?: number;\n /** Accessible name; defaults to the table's label. */\n label?: string;\n}\n\n/**\n * The spreadsheet view of a table (DATA-STUDIO.md P2). A paste across rows\n * is saved in ONE transaction through `updateMany`: every row changes, at\n * the version it was read, or none does, and the failing cells are marked.\n */\nexport function SheetView({\n provider,\n schema,\n rows,\n keys,\n linkLabels,\n onSaved,\n onFailed,\n onUndo,\n onNotice,\n hidden,\n selected,\n onToggleSelect,\n onToggleAll,\n onOpenRecord,\n firstRowNumber = 1,\n footer,\n height,\n label,\n}: SheetViewProps) {\n const versionField = schema.version?.field;\n const keyNames = useMemo(() => new Set(keyFields(schema)), [schema]);\n const columns = useMemo<SheetGridColumn<Row>[]>(\n () =>\n gridFields(schema).filter((field) => !hidden?.has(field.name)).map((field, index) => {\n const labels = linkLabels.get(field.name);\n return {\n key: field.name,\n header: fieldLabel(field),\n icon: <FieldIcon field={field} isKey={keyNames.has(field.name)} />,\n // The first column names the row, so it gets more room.\n width: index === 0 && field.name === schema.labelField ? 220 : field.type === \"json\" ? 220 : field.type === \"boolean\" ? 110 : 170,\n ...(field.type === \"number\" && !field.enumValues ? { align: \"end\" as const } : {}),\n getText: (row: Row) => editText(row[field.name]),\n render: (row: Row) => (\n <CellValue field={field} value={row[field.name]} linkLabel={labels?.get(String(row[field.name]))} />\n ),\n // Links are edited in the record form, with a picker.\n editable: Boolean(field.permissions?.update) && !field.references,\n readOnlyReason: field.references && field.permissions?.update ? \"Edit links in the record's form.\" : field.permissions?.reason,\n ...(choicesFor(field) ? { options: choicesFor(field) } : {}),\n };\n }),\n [schema, linkLabels, hidden, keyNames],\n );\n const selectable = Boolean(selected && onToggleSelect);\n const allSelected = selectable && rows.length > 0 && rows.every((row) => selected!.has(keys.get(row) ?? \"\"));\n\n async function commit(changes: SheetCellChange<Row>[]) {\n // One update per row, with every cell that changed in it.\n const byRow = new Map<string, { row: Row; data: Record<string, unknown> }>();\n for (const change of changes) {\n const field = schema.fields.find((f) => f.name === change.column)!;\n const entry = byRow.get(change.rowKey) ?? { row: change.row, data: {} };\n entry.data[change.column] = parseDraft(field, change.value);\n byRow.set(change.rowKey, entry);\n }\n const items = [...byRow.entries()];\n const expected = (row: Row) => (versionField ? (row[versionField] == null ? null : String(row[versionField])) : null);\n try {\n if (items.length === 1) {\n const [, { row, data }] = items[0]!;\n const result = await provider.update<BaseRecord>(schema.name, { id: encodeRecordKey(schema, row), data: data as never, expectedVersion: expected(row) });\n onSaved([{ old: row, next: result.data as Row, ...(result.audit ? { audit: result.audit } : {}) }]);\n return;\n }\n if (!provider.updateMany) throw new Error(\"This data provider can't save several rows at once.\");\n const result = await provider.updateMany(schema.name, {\n changes: items.map(([, { row, data }]) => ({ id: encodeRecordKey(schema, row), data, expectedVersion: expected(row) })),\n });\n if (!result.ok) {\n const failures = result.failures ?? [];\n const cells = failures.flatMap((f) => {\n const [rowKey, { data }] = items[f.index]!;\n return Object.keys(data).map((column) => ({ rowKey, column, message: f.message }));\n });\n const message = `Nothing was saved: ${failures.length} of ${items.length} rows failed. Fix the marked cells and paste again.`;\n onFailed(message);\n throw new SheetCommitError(message, cells);\n }\n // The bulk result carries audit entries, not rows: reload the page.\n onSaved(\n items.map(([, { row, data }], i) => ({\n old: row,\n next: { ...row, ...data },\n ...(result.audit?.[i] ? { audit: result.audit[i] } : {}),\n })),\n );\n onNotice(`Saved ${result.count} rows in one transaction.`);\n } catch (error) {\n if (error instanceof SheetCommitError) throw error;\n const message = isDataWriteError(error) || error instanceof Error ? error.message : String(error);\n onFailed(message);\n throw error;\n }\n }\n\n return (\n <SheetGrid<Row>\n label={label ?? `${schema.label ?? schema.name} sheet`}\n rows={rows}\n columns={columns}\n getKey={(row) => keys.get(row) ?? \"\"}\n onCommit={commit}\n onUndo={onUndo}\n onSkipped={(count) => onNotice(`${count} read-only cell${count === 1 ? \" was\" : \"s were\"} left as they were.`)}\n height={height ?? Math.min(640, Math.max(160, (rows.length + 2) * 32 + 4))}\n className=\"rounded-md\"\n empty=\"No records match.\"\n footer={footer}\n rowHeader={{\n width: selectable ? 84 : 64,\n header: selectable ? (\n <input\n type=\"checkbox\"\n aria-label=\"Select every row on this page\"\n className=\"h-3.5 w-3.5\"\n checked={allSelected}\n onChange={() => onToggleAll?.()}\n />\n ) : null,\n render: (row, index) => {\n const id = keys.get(row) ?? \"\";\n return (\n <span className=\"flex w-full items-center gap-1.5\">\n {selectable && (\n <input\n type=\"checkbox\"\n aria-label={`Select row ${firstRowNumber + index}`}\n className=\"h-3.5 w-3.5\"\n checked={selected!.has(id)}\n onChange={() => onToggleSelect!(id)}\n data-testid=\"studio-row-select\"\n />\n )}\n <span className=\"min-w-[1.5rem] tabular-nums\">{firstRowNumber + index}</span>\n {onOpenRecord && id && (\n <button\n type=\"button\"\n className=\"ml-auto rounded p-0.5 text-muted-foreground opacity-0 hover:bg-background hover:text-foreground focus-visible:opacity-100 group-hover/row:opacity-100\"\n aria-label={`Open row ${firstRowNumber + index}`}\n title=\"Open record\"\n onClick={() => onOpenRecord(id)}\n data-testid=\"studio-open-record\"\n >\n <Maximize2 className=\"h-3 w-3\" aria-hidden />\n </button>\n )}\n </span>\n );\n },\n }}\n />\n );\n}\n"],"mappings":"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","names":["useCallback","useEffect","useMemo","useState","keepPreviousData","useQuery","useQueryClient","ChevronLeft","ChevronRight","History","Lock","Plus","Table2","Trash2","X","encodeRecordKey","isDataWriteError","keyFields","Button","Dialog","DialogContent","DialogDescription","DialogHeader","DialogTitle","Alert","AlertDescription","AlertTitle","cn","useEffect","useMemo","useState","Button","useState","useQuery","useState","useQuery","jsx","jsxs","useMemo","values","useState","useEffect","Button","useMemo","useState","useQuery","Textarea","Button","jsx","jsxs","useQuery","useState","useMemo","Button","r","Textarea","useState","X","Button","Input","Popover","PopoverContent","PopoverTrigger","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","jsx","jsxs","NONE","useState","Popover","PopoverTrigger","Button","PopoverContent","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Input","X","jsxs","Select","jsx","SelectTrigger","SelectValue","SelectContent","SelectItem","Popover","PopoverTrigger","Button","PopoverContent","Input","useState","Popover","PopoverContent","PopoverTrigger","Plus","Search","X","jsx","jsxs","VIEWS","Link2","cn","Fragment","jsx","Link2","cn","useEffect","useMemo","useState","useQueries","encodeRecordKey","isDataWriteError","Button","jsx","jsxs","NONE","versionOf","useMemo","useState","useQueries","isDataWriteError","useEffect","encodeRecordKey","Button","useEffect","useMemo","useQuery","encodeRecordKey","isDataWriteError","Button","cn","jsx","jsxs","useQuery","isDataWriteError","useEffect","useMemo","Button","cn","encodeRecordKey","useMemo","useState","Button","Label","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","Fragment","jsx","jsxs","useState","useMemo","Button","Label","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","useState","Button","Dialog","DialogContent","DialogDescription","DialogHeader","DialogTitle","Input","Label","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","jsx","jsxs","useState","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","Label","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Input","Button","useMemo","encodeRecordKey","isDataWriteError","keyFields","jsx","jsxs","useMemo","keyFields","result","encodeRecordKey","isDataWriteError","Fragment","jsx","jsxs","isDataWriteError","useState","useEffect","useQueryClient","useCallback","useQuery","cn","Sheet","Table2","useMemo","keyFields","keepPreviousData","encodeRecordKey","Alert","AlertTitle","AlertDescription","versionOf","Plus","view","Lock","Button","Trash2","X","ChevronLeft","ChevronRight","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","jsxs","jsx","History","cn"]}
|
|
1
|
+
{"version":3,"sources":["../src/DataStudio.tsx","../src/router.ts","../src/values.ts","../src/lib/csv.ts","../src/lib/query-state.ts","../src/lib/relations.ts","../src/record/RecordForm.tsx","../src/lib/form-schema.ts","../src/lib/form-config.ts","../src/record/RelationPicker.tsx","../src/record/RecordPanel.tsx","../src/toolbar/Toolbar.tsx","../src/workspace/ViewsPanel.tsx","../src/grid/cells.tsx","../src/views/KanbanView.tsx","../src/views/CalendarView.tsx","../src/views/fields.ts","../src/toolbar/ImportDialog.tsx","../src/toolbar/BulkEdit.tsx","../src/sheet/SheetView.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { keepPreviousData, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { ChevronLeft, ChevronRight, Database, History, Lock, PencilLine, Plus, Table2, Trash2, Undo2, X } from \"lucide-react\";\nimport { GenesisProvider, type BaseRecord, type DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport {\n encodeRecordKey,\n isDataWriteError,\n keyFields,\n type AuditEntry,\n type FieldSchema,\n type ResourceSchema,\n type ResourceSummary,\n} from \"@marktiderman/genesis-core/schema\";\nimport { useSavedViews } from \"@marktiderman/genesis-ui/data\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"@marktiderman/genesis-ui/dialog\";\nimport { Alert, AlertDescription, AlertTitle } from \"@marktiderman/genesis-ui/alert\";\nimport { cn } from \"@marktiderman/genesis-ui/utils\";\nimport { useHistoryRouter, type StudioLocation, type StudioRouter } from \"./router\";\nimport { choicesFor, displayText, editText, fieldLabel, parseDraft } from \"./values\";\nimport { exportCsv, downloadText } from \"./lib/csv\";\nimport { formatFilters, formatSorts, parseFilters, parseSorts } from \"./lib/query-state\";\nimport { usePageLinkLabels } from \"./lib/relations\";\nimport { RecordForm } from \"./record/RecordForm\";\nimport { RecordPanel } from \"./record/RecordPanel\";\nimport { ExportButton, FilterBuilder, GroupPicker, HideFields, NewRowButton, SearchBox, SortBuilder, ViewFieldPicker } from \"./toolbar/Toolbar\";\nimport { TableTabs, ViewsPanel } from \"./workspace/ViewsPanel\";\nimport { CellValue } from \"./grid/cells\";\nimport { KanbanView } from \"./views/KanbanView\";\nimport { CalendarView } from \"./views/CalendarView\";\nimport { boardFields, dateFields } from \"./views/fields\";\nimport { ImportDialog } from \"./toolbar/ImportDialog\";\nimport { BulkEditDialog } from \"./toolbar/BulkEdit\";\nimport { gridFields, SheetView } from \"./sheet/SheetView\";\nimport type { StudioFormConfig } from \"./lib/form-config\";\n\ntype Row = Record<string, unknown>;\n\n/** One entry in the session's activity panel. */\nexport interface StudioActivity {\n id: string;\n at: Date;\n resource: string;\n field: string;\n /** The record's key, as shown to the user. */\n record: string;\n outcome: \"saved\" | \"not_saved\";\n /** What was attempted. Default `update`. */\n action?: \"update\" | \"create\" | \"delete\";\n message: string;\n /** Present when the edit committed with an audit entry from the `table` sink. */\n audit?: AuditEntry;\n /**\n * A bulk write's audit entries, one per row. A single entry holds them all,\n * so its Undo reaches every row however many there were.\n */\n audits?: AuditEntry[];\n /** True once this change has been undone. */\n undone?: boolean;\n}\n\nexport interface DataStudioProps {\n /**\n * Where the data comes from: the studio handler's client\n * (`createStudioProvider` from `@marktiderman/genesis-studio-server/client`)\n * or any Genesis `DataProvider` that implements `describe` and\n * `listResources`.\n */\n provider: DataProvider;\n /**\n * URL state, from the app's router (see `createSearchParamsRouter`).\n * Default: the page's own query string, through the History API.\n */\n router?: StudioRouter;\n /** Shown in place of the studio while nobody is signed in. */\n signIn?: ReactNode;\n /**\n * Changes when the signed-in user does (their id, say). The studio drops\n * everything it loaded for the previous user and asks again. Not needed\n * with a provider that reports its session (`createSupabaseStudioProvider`).\n */\n sessionKey?: string | number | null;\n /** Heading above the table list. Default \"Data\"; `null` for none (the app's own page header names it). */\n title?: string | null;\n /**\n * `card` (default): the studio draws its own frame. `plain`: no frame, so\n * it sits flush inside an app's layout, under its own header and nav,\n * like any other page of the app.\n */\n variant?: \"card\" | \"plain\";\n /** Rows per page. Default 50. */\n perPage?: number;\n /**\n * Record-form layout per resource (`schema.table`): sections, and fields\n * shown only when a condition holds. Code first; see `StudioFormConfig`.\n */\n forms?: Readonly<Record<string, StudioFormConfig>>;\n className?: string;\n}\n\nconst PER_PAGE = 50;\nconst SEARCH_DEBOUNCE_MS = 300;\n\nfunction isUnauthenticated(error: unknown): boolean {\n return isDataWriteError(error) && error.outcome === \"unauthenticated\";\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * The Data Studio: a sidebar of the tables this user may see, and a sheet of\n * the selected one where a cell is edited in place. Every edit carries the\n * version it was read at, so a stale edit is refused rather than saved over\n * someone else's, and the outcome — saved with its audit entry, or not saved\n * and why — is shown on screen.\n *\n * It renders inside its own `GenesisProvider`, so it works whether or not\n * the app already has one.\n *\n * @stability Experimental\n */\nexport function DataStudio(props: DataStudioProps) {\n const historyRouter = useHistoryRouter();\n const router = props.router ?? historyRouter;\n // A provider that knows who is signed in (the Supabase one) keys the\n // studio's data to that user, so the app needn't pass a sessionKey.\n const session = (props.provider as { session?: StudioSessionSource }).session;\n const [sessionUser, setSessionUser] = useState<string | null>(null);\n useEffect(() => session?.subscribe(setSessionUser), [session]);\n const sessionKey = props.sessionKey !== undefined ? props.sessionKey : session ? sessionUser : null;\n return (\n <GenesisProvider provider={props.provider}>\n {/* The scope standalone.css resets, for apps without Tailwind. */}\n <div data-genesis-studio=\"\">\n <StudioWorkspace {...props} router={router} sessionKey={sessionKey} />\n </div>\n </GenesisProvider>\n );\n}\n\n/** A provider's report of who is signed in (see `createSupabaseStudioProvider`). */\nexport interface StudioSessionSource {\n subscribe(listener: (userId: string | null) => void): () => void;\n}\n\nfunction StudioWorkspace({\n provider,\n router,\n signIn,\n sessionKey = null,\n title = \"Data\",\n variant = \"card\",\n perPage = PER_PAGE,\n forms,\n className,\n}: DataStudioProps & { router: StudioRouter }) {\n const queryClient = useQueryClient();\n const [activity, setActivity] = useState<StudioActivity[]>([]);\n // The provider whose token was refused. Signing in again, even as the same\n // user, gives a new provider (a new token), which ends the signed-out state.\n const [refusedProvider, setRefusedProvider] = useState<DataProvider | null>(null);\n const signedOut = refusedProvider !== null && refusedProvider === provider;\n const providerRef = useRef(provider);\n providerRef.current = provider;\n const setSignedOut = useCallback((value: boolean) => setRefusedProvider(value ? providerRef.current : null), []);\n\n // A new user sees nothing the previous one loaded.\n useEffect(() => {\n setRefusedProvider(null);\n setActivity([]);\n void queryClient.resetQueries({ queryKey: [\"genesis-studio\"] });\n }, [sessionKey, queryClient]);\n\n const resources = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"resources\"],\n queryFn: () => {\n if (!provider.listResources) throw new Error(\"This data provider can't list its resources.\");\n return provider.listResources();\n },\n retry: (count, error) => !isUnauthenticated(error) && count < 2,\n });\n\n useEffect(() => {\n if (isUnauthenticated(resources.error)) setSignedOut(true);\n }, [resources.error]);\n\n // The same user signed in again: ask again with the new token. Declared\n // after the queries, so their fetchers already use the new provider.\n useEffect(() => {\n if (refusedProvider && refusedProvider !== provider) {\n setRefusedProvider(null);\n void queryClient.resetQueries({ queryKey: [\"genesis-studio\", sessionKey] });\n }\n }, [provider, refusedProvider, queryClient, sessionKey]);\n\n /**\n * Undo a bulk write row by row, each a compensating write with its own audit\n * entry. Rows that can't be undone stay on the entry, so Undo can be retried.\n */\n // Entries with an undo in flight, so a second click or Ctrl+Z can't resend it.\n const undoing = useRef(new Set<string>());\n\n const undoAll = useCallback(\n async (entry: StudioActivity, audits: AuditEntry[]) => {\n const left: AuditEntry[] = [];\n let firstError: unknown;\n for (const audit of audits) {\n try {\n await provider.undo!(entry.resource, { auditId: audit.id });\n } catch (error) {\n left.push(audit);\n firstError ??= error;\n }\n }\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey] });\n const done = audits.length - left.length;\n setActivity((prev) => {\n const updated = prev.map((e) => (e.id === entry.id ? (left.length ? { ...e, audits: left } : { ...e, undone: true }) : e));\n const now = new Date();\n const added: StudioActivity[] = [];\n if (left.length) {\n added.push({ id: `${now.getTime()}-undo-failed`, at: now, resource: entry.resource, field: entry.field, record: `${left.length} rows`, outcome: \"not_saved\", message: `${left.length} of ${audits.length} rows weren't undone: ${errorText(firstError)}` });\n }\n if (done) {\n added.push({ id: `${now.getTime()}-undo`, at: now, resource: entry.resource, field: entry.field, record: `${done} rows`, outcome: \"saved\", action: \"update\", message: \"Undone, each row with its own audit entry.\" });\n }\n return [...added, ...updated].slice(0, 50);\n });\n },\n [provider, queryClient, sessionKey],\n );\n\n const undoOne = useCallback(\n async (entry: StudioActivity) => {\n if (entry.audits?.length) return undoAll(entry, entry.audits);\n try {\n const result = await provider.undo!(entry.resource, { auditId: entry.audit!.id });\n setActivity((prev) => prev.map((e) => (e.id === entry.id ? { ...e, undone: true } : e)));\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey] });\n setActivity((prev) =>\n [\n {\n id: `${Date.now()}-undo`,\n at: new Date(),\n resource: entry.resource,\n field: entry.field,\n record: entry.record,\n outcome: \"saved\" as const,\n action: \"update\" as const,\n message: \"Undone, with its own audit entry.\",\n ...(result.audit ? { audit: result.audit, undone: true } : {}),\n },\n ...prev,\n ].slice(0, 50),\n );\n } catch (error) {\n setActivity((prev) =>\n [\n {\n id: `${Date.now()}-undo-failed`,\n at: new Date(),\n resource: entry.resource,\n field: entry.field,\n record: entry.record,\n outcome: \"not_saved\" as const,\n message: errorText(error),\n },\n ...prev,\n ].slice(0, 50),\n );\n }\n },\n [provider, queryClient, sessionKey, undoAll],\n );\n\n /**\n * Undo a change from its audit entry: a compensating write, itself\n * audited, that the server refuses if the row has moved on since.\n */\n const undo = useCallback(\n async (entry: StudioActivity) => {\n if (!provider.undo || entry.undone || undoing.current.has(entry.id)) return;\n if (!entry.audit && !entry.audits?.length) return;\n undoing.current.add(entry.id);\n try {\n await undoOne(entry);\n } finally {\n undoing.current.delete(entry.id);\n }\n },\n [provider, undoOne],\n );\n\n const record = useCallback((entry: Omit<StudioActivity, \"id\" | \"at\">) => {\n setActivity((prev) =>\n [{ ...entry, id: `${Date.now()}-${Math.random().toString(36).slice(2)}`, at: new Date() }, ...prev].slice(0, 50),\n );\n }, []);\n\n if (signedOut) {\n return (\n <div className={cn(\"flex min-h-[320px] items-center justify-center p-6\", className)} data-testid=\"studio-sign-in\">\n {signIn ?? <p className=\"text-sm text-muted-foreground\">Sign in to use the studio.</p>}\n </div>\n );\n }\n\n const selected = router.location.resource;\n const list = resources.data ?? [];\n\n return (\n <div className={cn(\"w-full space-y-3\", className)}>\n <div className={variant === \"card\" ? \"overflow-hidden rounded-lg border bg-background\" : \"min-w-0\"} data-testid=\"studio\" data-variant={variant}>\n {(title !== null || resources.isLoading || resources.isError) && (\n <div className={cn(\"flex items-center gap-2\", variant === \"card\" ? \"border-b px-3 py-2\" : \"pb-3\")}>\n {title !== null &&\n (variant === \"card\" ? (\n <>\n <Database className=\"h-4 w-4 text-muted-foreground\" aria-hidden />\n <span className=\"text-sm font-semibold\">{title}</span>\n </>\n ) : (\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n ))}\n {resources.isLoading && <span className=\"text-xs text-muted-foreground\">Loading tables…</span>}\n {resources.isError && (\n <span role=\"alert\" className=\"text-xs text-destructive\">\n {errorText(resources.error)}\n </span>\n )}\n </div>\n )}\n <TableTabs resources={list} selected={selected} onSelect={(resource) => router.navigate({ resource })} variant={variant} />\n {/* Not <main>: the studio sits inside the app's own main landmark. */}\n <div className=\"min-w-0\" data-testid=\"studio-main\">\n {selected ? (\n <Sheet\n key={selected}\n provider={provider}\n resource={selected}\n sessionKey={sessionKey}\n router={router}\n perPage={perPage}\n onActivity={record}\n onSignedOut={() => setSignedOut(true)}\n formConfig={forms?.[selected]}\n onUndoLatest={() => {\n const latest = activity.find((e) => e.resource === selected && e.outcome === \"saved\" && ((e.audit && e.audit.action !== \"run\") || e.audits?.length) && !e.undone);\n if (latest) void undo(latest);\n }}\n />\n ) : (\n <div\n className=\"flex min-h-[320px] flex-col items-center justify-center gap-2 p-8 text-center text-muted-foreground\"\n data-testid=\"studio-empty\"\n >\n <Table2 className=\"h-6 w-6\" aria-hidden />\n <p className=\"text-sm\">{list.length ? \"Pick a table to open it.\" : \"No tables to show yet.\"}</p>\n </div>\n )}\n </div>\n </div>\n <ActivityPanel entries={activity} onUndo={provider.undo ? (entry) => void undo(entry) : undefined} />\n </div>\n );\n}\n\nfunction Sheet({\n provider,\n resource,\n sessionKey,\n router,\n perPage,\n onActivity,\n onSignedOut,\n formConfig,\n onUndoLatest,\n}: {\n provider: DataProvider;\n resource: string;\n sessionKey: string | number | null;\n router: StudioRouter;\n perPage: number;\n onActivity: (entry: Omit<StudioActivity, \"id\" | \"at\">) => void;\n onSignedOut: () => void;\n formConfig?: StudioFormConfig;\n onUndoLatest: () => void;\n}) {\n const queryClient = useQueryClient();\n const { location } = router;\n const page = location.page ?? 1;\n const sorts = useMemo(() => parseSorts(location.sort), [location.sort]);\n const filters = useMemo(() => parseFilters(location.filters), [location.filters]);\n const search = location.search ?? \"\";\n const group = location.group;\n const [creating, setCreating] = useState(false);\n const [exporting, setExporting] = useState<number | null>(null);\n const [notice, setNotice] = useState<string | null>(null);\n // Bumped to remount the page after a saved view sets column visibility.\n const [viewEpoch, setViewEpoch] = useState(0);\n const [bulkIds, setBulkIds] = useState<string[] | null>(null);\n const view = location.view ?? \"table\";\n const sheetView = view === \"sheet\";\n const savedViews = useSavedViews(`genesis-studio:views:${resource}`);\n const hiddenKey = `genesis-studio:hidden:${resource}`;\n const [hidden, setHiddenState] = useState<Set<string>>(() => {\n try {\n const stored = JSON.parse(localStorage.getItem(hiddenKey) ?? \"[]\");\n return new Set(Array.isArray(stored) ? stored.filter((x): x is string => typeof x === \"string\") : []);\n } catch {\n return new Set();\n }\n });\n const setHidden = useCallback(\n (next: Set<string>) => {\n setHiddenState(next);\n try {\n localStorage.setItem(hiddenKey, JSON.stringify([...next]));\n } catch {\n // Hidden fields are a convenience; the grid works without storage.\n }\n },\n [hiddenKey],\n );\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [searchDraft, setSearchDraft] = useState(location.search ?? \"\");\n\n const schemaQuery = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"describe\", resource],\n queryFn: () => {\n if (!provider.describe) throw new Error(\"This data provider can't describe its resources.\");\n return provider.describe(resource);\n },\n retry: false,\n });\n const schema = schemaQuery.data;\n const capabilities = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"capabilities\", resource],\n enabled: Boolean(provider.capabilities),\n retry: false,\n queryFn: () => provider.capabilities!(resource),\n }).data;\n\n // Grouping sorts by the group field first, so each group is contiguous.\n const effectiveSorts = useMemo(\n () => (group ? [{ field: group, order: \"asc\" as const }, ...sorts.filter((s) => s.field !== group)] : sorts),\n [group, sorts],\n );\n const listKey = useMemo(\n () => [\"genesis-studio\", sessionKey, \"list\", resource, page, perPage, location.sort ?? \"\", search, location.filters ?? \"\", group ?? \"\"],\n [sessionKey, resource, page, perPage, location.sort, search, location.filters, group],\n );\n const keyed = Boolean(schema && keyFields(schema).length > 0);\n const boardChoices = schema ? boardFields(schema) : [];\n const dateChoices = schema ? dateFields(schema) : [];\n const keyedView = (view === \"kanban\" || view === \"calendar\") && keyed;\n const viewChoices = view === \"kanban\" ? boardChoices : view === \"calendar\" ? dateChoices : [];\n const viewField = viewChoices.find((f) => f.name === location.by) ?? viewChoices[0];\n const altView = keyedView && viewField ? view : null;\n const listQuery = useQuery({\n queryKey: listKey,\n // A board or calendar makes its own requests; the grid's page isn't needed then.\n enabled: Boolean(schema) && !altView,\n placeholderData: keepPreviousData,\n retry: false,\n queryFn: () =>\n provider.getList<BaseRecord>(resource, {\n pagination: { page, perPage },\n sort: effectiveSorts[0],\n sorts: effectiveSorts,\n filters,\n search: search ? { query: search, fields: [] } : undefined,\n }),\n });\n\n const failure = schemaQuery.error ?? listQuery.error;\n useEffect(() => {\n if (isUnauthenticated(failure)) onSignedOut();\n }, [failure, onSignedOut]);\n\n // Debounce search into the URL; typing replaces rather than pushes history.\n const searchTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n useEffect(() => () => clearTimeout(searchTimer.current), []);\n const navigate = useCallback(\n (patch: Partial<StudioLocation>, replace = false) => router.navigate({ ...location, resource, ...patch }, { replace }),\n [router, location, resource],\n );\n\n const rows = (listQuery.data?.data ?? []) as Row[];\n const keys = useMemo(() => {\n const map = new Map<Row, string>();\n rows.forEach((row, index) => map.set(row, schema && keyed ? String(encodeRecordKey(schema, row)) : `row-${index}`));\n return map;\n }, [rows, schema, keyed]);\n const linkLabels = usePageLinkLabels(provider, sessionKey, schema?.fields ?? [], rows);\n\n const replaceRow = useCallback(\n (oldRow: Row, next: Row) => {\n queryClient.setQueryData(listKey, (prev: { data: Row[]; total: number } | undefined) =>\n prev ? { ...prev, data: prev.data.map((r) => (r === oldRow ? next : r)) } : prev,\n );\n },\n [queryClient, listKey],\n );\n const refresh = useCallback(() => {\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey, \"list\", resource] });\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey, \"history\", resource] });\n }, [queryClient, sessionKey, resource]);\n\n const openRecord = useCallback(\n (target: string, id: string) =>\n target === resource ? navigate({ record: id }) : router.navigate({ resource: target, record: id }),\n [navigate, router, resource],\n );\n\n // Stable while the schema is, so a background refetch doesn't reset the\n // new-row form under the user's typing.\n const createFields = useMemo(() => new Set(schema?.createFields ?? []), [schema]);\n const fieldsForCreate = useMemo(() => schema?.fields.filter((f) => createFields.has(f.name)) ?? [], [schema, createFields]);\n // A selection belongs to the rows on screen: a new page, filter, search or\n // sort starts with none, so a bulk action never reaches rows out of view.\n // (Declared before the early returns below, as every hook must be.)\n const listIdentity = JSON.stringify(listKey);\n useEffect(() => {\n setSelected(new Set());\n }, [listIdentity]);\n\n async function runExport() {\n if (!schema) return;\n setExporting(0);\n setNotice(null);\n try {\n const { csv, rows: count, truncated } = await exportCsv({\n provider,\n resource,\n fields: schema.fields,\n sorts: effectiveSorts,\n filters,\n search,\n onProgress: setExporting,\n });\n downloadText(`${resource}.csv`, csv);\n setNotice(\n truncated\n ? `Exported the first ${count.toLocaleString()} matching rows. Narrow the list to export the rest.`\n : `Exported ${count.toLocaleString()} rows.`,\n );\n } catch (error) {\n setNotice(`Export failed: ${errorText(error)}`);\n } finally {\n setExporting(null);\n }\n }\n\n async function create(values: Record<string, unknown>) {\n if (!schema) return;\n try {\n const result = await provider.create<BaseRecord>(resource, { data: values as never });\n setCreating(false);\n refresh();\n const id = String(encodeRecordKey(schema, result.data as Row));\n onActivity({ resource, field: \"\", record: id, outcome: \"saved\", action: \"create\", message: result.audit ? \"Added, with its audit entry.\" : \"Added.\", ...(result.audit ? { audit: result.audit } : {}) });\n navigate({ record: id });\n } catch (error) {\n if (isUnauthenticated(error)) onSignedOut();\n onActivity({ resource, field: \"\", record: \"new row\", outcome: \"not_saved\", action: \"create\", message: errorText(error) });\n throw error;\n }\n }\n\n if (schemaQuery.isError && !isUnauthenticated(schemaQuery.error)) {\n return (\n <Alert variant=\"destructive\" data-testid=\"studio-describe-error\">\n <AlertTitle>Couldn't open {resource}</AlertTitle>\n <AlertDescription>{errorText(schemaQuery.error)}</AlertDescription>\n </Alert>\n );\n }\n\n const editable = schema?.fields.filter((f) => f.permissions?.update).length ?? 0;\n\n const gridView = !altView;\n const pageCount = Math.max(1, Math.ceil((listQuery.data?.total ?? 0) / perPage));\n const total = listQuery.data?.total ?? 0;\n const selectable = Boolean(schema && keyed && ((schema.access.update && provider.updateMany) || (schema.access.delete && provider.deleteMany)));\n const toggleSelect = (id: string) =>\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n const pageIds = rows.map((r) => keys.get(r) ?? \"\");\n const toggleAll = () =>\n setSelected((prev) => (pageIds.every((id) => prev.has(id)) ? new Set() : new Set(pageIds)));\n const canAdd = Boolean(schema?.access.create);\n\n async function deleteSelected() {\n if (!schema) return;\n const ids = [...selected];\n const chosen = rows.filter((r) => ids.includes(keys.get(r) ?? \"\"));\n // Never act on fewer rows than were confirmed.\n if (chosen.length !== ids.length) {\n setSelected(new Set());\n setNotice(\"Some selected rows aren't on this page any more. Select the rows again.\");\n return;\n }\n if (!window.confirm(`Delete ${ids.length} record${ids.length === 1 ? \"\" : \"s\"}? All of them go, or none do.`)) return;\n let result;\n try {\n result = await provider.deleteMany!(resource, {\n items: chosen.map((r) => ({ id: encodeRecordKey(schema, r), expectedVersion: versionOf(schema, r) })),\n });\n } catch (error) {\n if (isUnauthenticated(error)) onSignedOut();\n refresh();\n const message = `Nothing was deleted: ${errorText(error)}`;\n setNotice(message);\n onActivity({ resource, field: \"\", record: `${ids.length} rows`, outcome: \"not_saved\", action: \"delete\", message });\n return;\n }\n refresh();\n setSelected(new Set());\n if (result.ok) {\n setNotice(`Deleted ${result.count} records in one transaction.`);\n // One entry holds every row's audit, so one Undo reaches them all.\n onActivity({\n resource,\n field: \"\",\n record: `${result.count} rows`,\n outcome: \"saved\",\n action: \"delete\",\n message: \"Deleted, each row audited.\",\n ...(result.audit?.length ? { audits: result.audit } : {}),\n });\n } else {\n const message = `Nothing was deleted: ${(result.failures ?? []).length} of ${ids.length} records couldn't be (${result.failures?.[0]?.message ?? \"\"}).`;\n setNotice(message);\n onActivity({ resource, field: \"\", record: `${ids.length} rows`, outcome: \"not_saved\", action: \"delete\", message });\n }\n }\n\n const gridFor = (items: Row[], firstRowNumber: number, label?: string, withFooter = true) =>\n schema && (\n <SheetView\n provider={provider}\n schema={schema}\n rows={items}\n keys={keys}\n linkLabels={linkLabels}\n hidden={hidden}\n label={label}\n firstRowNumber={firstRowNumber}\n {...(selectable ? { selected, onToggleSelect: toggleSelect, onToggleAll: toggleAll } : {})}\n onOpenRecord={keyed ? (id) => navigate({ record: id }) : undefined}\n footer={\n withFooter && canAdd ? (\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-sm text-muted-foreground hover:bg-muted/40 hover:text-foreground\"\n onClick={() => setCreating(true)}\n data-testid=\"studio-add-record\"\n >\n <Plus className=\"h-3.5 w-3.5\" aria-hidden />\n Add a record\n </button>\n ) : undefined\n }\n onSaved={(updates) => {\n if (updates.length === 1) replaceRow(updates[0]!.old, updates[0]!.next);\n else refresh();\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey, \"record\", resource] });\n const fieldsOf = (audit?: AuditEntry) => Object.keys(audit?.after ?? {}).filter((f) => f !== schema.version?.field);\n if (updates.length === 1) {\n const u = updates[0]!;\n onActivity({\n resource,\n field: fieldsOf(u.audit).join(\", \"),\n record: keys.get(u.old) ?? \"\",\n outcome: \"saved\",\n message: u.audit ? \"Saved, with its audit entry.\" : \"Saved.\",\n ...(u.audit ? { audit: u.audit } : {}),\n });\n } else {\n // A multi-row paste is one bulk write: one entry, one Undo for every row.\n const audits = updates.flatMap((u) => (u.audit ? [u.audit] : []));\n onActivity({\n resource,\n field: [...new Set(audits.flatMap(fieldsOf))].join(\", \"),\n record: `${updates.length} rows`,\n outcome: \"saved\",\n message: audits.length ? \"Saved, each row audited.\" : \"Saved.\",\n ...(audits.length ? { audits } : {}),\n });\n }\n }}\n onFailed={(message) => {\n refresh();\n onActivity({ resource, field: \"\", record: \"\", outcome: \"not_saved\", message });\n }}\n onUndo={onUndoLatest}\n onNotice={setNotice}\n />\n );\n\n return (\n <div className=\"flex min-h-[480px] flex-col md:flex-row\" data-testid=\"studio-sheet\">\n {schema && (\n <ViewsPanel\n view={altView ?? \"grid\"}\n available={{ grid: true, kanban: keyed && boardChoices.length > 0, calendar: keyed && dateChoices.length > 0 }}\n onChange={(next) => navigate({ view: next === \"grid\" ? undefined : next, by: undefined, month: undefined, record: undefined })}\n saved={savedViews.savedViews}\n onDelete={savedViews.deleteView}\n onSave={(name) =>\n savedViews.saveView(name, {\n sort: location.sort ?? null,\n search: location.search ?? null,\n filters: location.filters ?? null,\n group: location.group ?? null,\n view: location.view ?? null,\n by: location.by ?? null,\n hidden: [...hidden],\n })\n }\n onLoad={(item) => {\n const view = savedViews.loadViewFilters(item.id) ?? {};\n if (Array.isArray(view.hidden)) setHidden(new Set(view.hidden.filter((x): x is string => typeof x === \"string\")));\n const str = (v: unknown) => (typeof v === \"string\" ? v : undefined);\n const nextView = str(view.view);\n setSearchDraft(str(view.search) ?? \"\");\n router.navigate({\n resource,\n sort: str(view.sort),\n search: str(view.search),\n filters: str(view.filters),\n group: str(view.group),\n view: nextView === \"kanban\" || nextView === \"calendar\" ? nextView : undefined,\n by: str(view.by),\n });\n }}\n />\n )}\n <div className=\"min-w-0 flex-1 space-y-2 p-2 md:p-3\">\n {schema && !schema.access.update && (\n <p className=\"flex items-center gap-1.5 text-xs text-muted-foreground\" data-testid=\"studio-read-only\">\n <Lock className=\"h-3.5 w-3.5\" aria-hidden />\n Read-only: {(schema.access.reason ?? \"you can view this table but not edit it.\").replace(/^Read-only: /, \"\")}\n </p>\n )}\n {schema && (\n <div className=\"flex flex-wrap items-center gap-1\" data-testid=\"studio-toolbar\">\n {selected.size === 0 && gridView && <HideFields fields={gridFields(schema)} hidden={hidden} onChange={setHidden} />}\n {selected.size === 0 && (capabilities?.filterOperators?.length ?? 1) > 0 && (\n <FilterBuilder fields={schema.fields} filters={filters} onChange={(next) => navigate({ filters: formatFilters(next), page: 1 })} />\n )}\n {selected.size === 0 && gridView && <GroupPicker fields={schema.fields} group={group} onChange={(next) => navigate({ group: next, page: 1 })} />}\n {selected.size === 0 && capabilities?.sort !== false && (\n <SortBuilder fields={schema.fields} sorts={sorts} onChange={(next) => navigate({ sort: formatSorts(next), page: 1 })} />\n )}\n {altView && viewField && (\n <ViewFieldPicker\n label={altView === \"kanban\" ? \"Columns by\" : \"Dates by\"}\n fields={viewChoices}\n value={viewField.name}\n onChange={(by) => navigate({ by })}\n />\n )}\n {selected.size > 0 && (\n <span className=\"flex items-center gap-1 rounded-md bg-muted px-2 text-sm\" data-testid=\"studio-selection\">\n {selected.size} selected\n {schema.access.update && provider.updateMany && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" testID=\"studio-bulk-set\" onClick={() => setBulkIds([...selected])}>\n <PencilLine className=\"mr-1 h-3.5 w-3.5\" aria-hidden />\n Set a field…\n </Button>\n )}\n {schema.access.delete && provider.deleteMany && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"text-destructive\" testID=\"studio-bulk-delete\" onClick={() => void deleteSelected()}>\n <Trash2 className=\"mr-1 h-3.5 w-3.5\" aria-hidden />\n Delete\n </Button>\n )}\n <button type=\"button\" aria-label=\"Clear the selection\" className=\"rounded p-0.5 hover:bg-background\" onClick={() => setSelected(new Set())}>\n <X className=\"h-3.5 w-3.5\" aria-hidden />\n </button>\n </span>\n )}\n <span className=\"ml-auto flex items-center gap-1\">\n <SearchBox\n value={searchDraft}\n onChange={(text) => {\n setSearchDraft(text);\n clearTimeout(searchTimer.current);\n searchTimer.current = setTimeout(() => navigate({ search: text || undefined, page: 1 }, true), SEARCH_DEBOUNCE_MS);\n }}\n />\n <ExportButton onExport={() => void runExport()} busy={exporting !== null} progress={exporting ?? 0} />\n {schema.access.create !== undefined && (\n <ImportDialog\n provider={provider}\n schema={schema}\n onImported={(count) => {\n refresh();\n setNotice(`Imported ${count.toLocaleString()} rows in one transaction.`);\n onActivity({ resource, field: \"\", record: `${count} rows`, outcome: \"saved\", action: \"create\", message: \"Imported, each row audited.\" });\n }}\n />\n )}\n {schema.access.create !== undefined && (\n <NewRowButton allowed={canAdd} reason={schema.access.reasons?.create} onClick={() => setCreating(true)} />\n )}\n </span>\n </div>\n )}\n {notice && (\n <p className=\"text-xs text-muted-foreground\" role=\"status\" data-testid=\"studio-notice\">\n {notice}\n </p>\n )}\n {schema && altView === \"kanban\" && viewField && (\n <KanbanView\n key={`${viewField.name}|${location.filters ?? \"\"}|${search}|${location.sort ?? \"\"}`}\n provider={provider}\n schema={schema}\n sessionKey={sessionKey}\n field={viewField}\n filters={filters}\n sorts={sorts}\n search={search}\n onOpenRecord={(id) => navigate({ record: id })}\n onMoved={(record, audit) => {\n refresh();\n onActivity({ resource, field: viewField.name, record, outcome: \"saved\", message: audit ? \"Moved, with its audit entry.\" : \"Moved.\", ...(audit ? { audit } : {}) });\n }}\n onFailed={(record, message) => {\n refresh();\n onActivity({ resource, field: viewField.name, record, outcome: \"not_saved\", message });\n }}\n onSignedOut={onSignedOut}\n />\n )}\n {schema && altView === \"calendar\" && viewField && (\n <CalendarView\n provider={provider}\n schema={schema}\n sessionKey={sessionKey}\n field={viewField}\n month={location.month}\n onMonthChange={(month) => navigate({ month })}\n filters={filters}\n sorts={sorts}\n search={search}\n onOpenRecord={(id) => navigate({ record: id })}\n onSignedOut={onSignedOut}\n />\n )}\n {gridView && (\n <div className=\"space-y-3\" data-testid=\"studio-grid\">\n {(schemaQuery.isLoading || listQuery.isLoading) && <p className=\"px-1 py-6 text-sm text-muted-foreground\">Loading…</p>}\n {listQuery.isError && !isUnauthenticated(listQuery.error) && (\n <Alert variant=\"destructive\">\n <AlertTitle>Couldn't load the records</AlertTitle>\n <AlertDescription>\n {errorText(listQuery.error)}{\" \"}\n <button type=\"button\" className=\"underline\" onClick={() => void listQuery.refetch()}>\n Try again\n </button>\n </AlertDescription>\n </Alert>\n )}\n {schema && listQuery.data && !group && gridFor(rows, (page - 1) * perPage + 1)}\n {schema && listQuery.data && group && (\n <div className=\"space-y-4\" data-testid=\"studio-groups\">\n {groupRows(rows, group).map(([value, groupItems]) => {\n const field = schema.fields.find((f) => f.name === group);\n return (\n <section key={value ?? \"__none\"} data-testid=\"studio-group-section\" className=\"space-y-1\">\n <h3 className=\"flex items-center gap-2 text-sm\">\n <span className=\"text-muted-foreground\">{field ? fieldLabel(field) : group}</span>\n {value === null ? (\n <span className=\"text-muted-foreground\">Empty</span>\n ) : field ? (\n <CellValue field={field} value={value} />\n ) : (\n value\n )}\n <span className=\"text-xs text-muted-foreground\">{groupItems.length}</span>\n </h3>\n {gridFor(groupItems, rows.indexOf(groupItems[0]!) + (page - 1) * perPage + 1, `${schema.label ?? resource}: ${value ?? \"empty\"}`, false)}\n </section>\n );\n })}\n </div>\n )}\n {listQuery.data && (\n <div className=\"flex items-center gap-2 px-1 text-xs text-muted-foreground\" data-testid=\"studio-footer\">\n <span>\n {total.toLocaleString()} record{total === 1 ? \"\" : \"s\"}\n </span>\n {pageCount > 1 && (\n <span className=\"ml-auto flex items-center gap-1\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={page <= 1} onClick={() => navigate({ page: page - 1 })} aria-label=\"Previous page\">\n <ChevronLeft className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n Page {page} of {pageCount}\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={page >= pageCount} onClick={() => navigate({ page: page + 1 })} aria-label=\"Next page\">\n <ChevronRight className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n </span>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n {schema && location.record && (\n <RecordPanel\n provider={provider}\n sessionKey={sessionKey}\n schema={schema}\n id={location.record}\n onClose={() => navigate({ record: undefined })}\n onOpenRecord={openRecord}\n formConfig={formConfig}\n onUndone={(audit) => {\n refresh();\n onActivity({ resource, field: \"\", record: location.record!, outcome: \"saved\", message: \"Undone, with its own audit entry.\", ...(audit ? { audit, undone: true } : {}) });\n }}\n onSaved={(row, audit) => {\n refresh();\n onActivity({ resource, field: Object.keys(audit?.after ?? {}).join(\", \"), record: location.record!, outcome: \"saved\", message: audit ? \"Saved, with its audit entry.\" : \"Saved.\", ...(audit ? { audit } : {}) });\n void row;\n }}\n onActionRan={(action, row, audit) => {\n refresh();\n onActivity({\n resource,\n field: \"\",\n record: location.record!,\n outcome: \"saved\",\n message: `${action.label}: done${row ? \"\" : \", and the row is gone\"}${audit ? \", with its audit entry\" : \"\"}.`,\n ...(audit ? { audit } : {}),\n });\n }}\n onDeleted={(audit) => {\n refresh();\n onActivity({ resource, field: \"\", record: location.record!, outcome: \"saved\", action: \"delete\", message: audit ? \"Deleted, with its audit entry.\" : \"Deleted.\", ...(audit ? { audit } : {}) });\n }}\n onFailed={(action, message) =>\n onActivity({ resource, field: \"\", record: location.record!, outcome: \"not_saved\", action: action === \"delete\" ? \"delete\" : \"update\", message })\n }\n />\n )}\n {schema && bulkIds && (\n <BulkEditDialog\n schema={schema}\n count={bulkIds.length}\n open\n onOpenChange={(open) => !open && setBulkIds(null)}\n onApply={async (data) => {\n const chosen = rows.filter((r) => bulkIds.includes(keys.get(r) ?? \"\"));\n if (chosen.length !== bulkIds.length) {\n throw new Error(\"Some selected rows aren't on this page any more. Select the rows again.\");\n }\n const result = await provider.updateMany!(resource, {\n changes: chosen.map((r) => ({ id: encodeRecordKey(schema, r), data, expectedVersion: versionOf(schema, r) })),\n });\n refresh();\n if (result.ok) {\n setNotice(`Saved ${result.count} rows in one transaction.`);\n onActivity({\n resource,\n field: Object.keys(data).join(\", \"),\n record: `${result.count} rows`,\n outcome: \"saved\",\n message: \"Saved, each row audited.\",\n ...(result.audit?.length ? { audits: result.audit } : {}),\n });\n }\n return result;\n }}\n />\n )}\n {schema && (\n <Dialog open={creating} onOpenChange={setCreating}>\n <DialogContent className=\"max-h-[85vh] overflow-y-auto sm:max-w-lg\" data-testid=\"studio-create-dialog\">\n <DialogHeader>\n <DialogTitle>New {schema.label ?? resource} row</DialogTitle>\n <DialogDescription>Only fields you may set are shown. The new row is audited.</DialogDescription>\n </DialogHeader>\n <RecordForm\n provider={provider}\n sessionKey={sessionKey}\n mode=\"create\"\n fields={fieldsForCreate}\n editable={createFields}\n onSubmit={create}\n submitLabel=\"Add row\"\n onCancel={() => setCreating(false)}\n config={formConfig}\n />\n </DialogContent>\n </Dialog>\n )}\n </div>\n );\n}\n\nfunction versionOf(schema: ResourceSchema, row: Row): string | null {\n const field = schema.version?.field;\n return field && row[field] != null ? String(row[field]) : null;\n}\n\nconst NO_ACTIONS = {\n update: async () => {\n throw new Error(\"Not available here.\");\n },\n remove: async () => {\n throw new Error(\"Not available here.\");\n },\n refetch: () => {},\n};\n\n/** Rows of one page split by a field's value, in the order they arrived. */\nfunction groupRows(items: Row[], field: string): Array<[string | null, Row[]]> {\n const groups = new Map<string | null, Row[]>();\n for (const item of items) {\n const value = displayText(item[field]);\n if (!groups.has(value)) groups.set(value, []);\n groups.get(value)!.push(item);\n }\n return [...groups.entries()];\n}\n\nfunction schemaSubtitle(schema: ResourceSchema | undefined, editable: number): string | undefined {\n if (!schema) return undefined;\n const parts = [schema.name];\n if (schema.access.update) parts.push(`${editable} of ${schema.fields.length} fields editable`);\n if (schema.version) parts.push(`edits checked against ${schema.version.field}`);\n return parts.join(\" · \");\n}\n\nconst OUTCOME_LABEL = {\n update: { saved: \"Saved\", not_saved: \"Not saved\" },\n create: { saved: \"Added\", not_saved: \"Not added\" },\n delete: { saved: \"Deleted\", not_saved: \"Not deleted\" },\n} as const;\n\nfunction ActivityPanel({ entries, onUndo }: { entries: StudioActivity[]; onUndo?: (entry: StudioActivity) => void }) {\n return (\n <details aria-label=\"This session's edits\" className=\"group rounded-lg border bg-card\" data-testid=\"studio-activity\">\n <summary className=\"flex cursor-pointer list-none items-center gap-2 px-3 py-2 text-sm font-medium group-open:border-b\">\n <History className=\"h-4 w-4 text-muted-foreground\" aria-hidden />\n This session's edits\n {entries.length > 0 && <span className=\"text-xs font-normal text-muted-foreground\">{entries.length}</span>}\n {entries[0] && (\n <span className={cn(\"ml-2 truncate text-xs font-normal\", entries[0].outcome === \"saved\" ? \"text-muted-foreground\" : \"text-destructive\")}>\n {entries[0].message}\n </span>\n )}\n </summary>\n {entries.length === 0 ? (\n <p className=\"px-3 py-3 text-xs text-muted-foreground\">\n Click a cell to edit it. Each save is checked against the latest version of the row, and audited.\n </p>\n ) : (\n <ol className=\"divide-y\" aria-live=\"polite\">\n {entries.map((entry) => (\n <li key={entry.id} className=\"px-3 py-2 text-xs\" data-testid={`studio-activity-${entry.outcome}`}>\n <div className=\"flex flex-wrap items-baseline gap-x-2\">\n <span className={entry.outcome === \"saved\" ? \"font-medium text-foreground\" : \"font-medium text-destructive\"}>\n {OUTCOME_LABEL[entry.action ?? \"update\"][entry.outcome]}\n </span>\n <span className=\"text-muted-foreground\">\n {[entry.resource, entry.field, entry.record].filter(Boolean).join(\" · \")}\n </span>\n <time className=\"ml-auto text-muted-foreground\" dateTime={entry.at.toISOString()}>\n {entry.at.toLocaleTimeString()}\n </time>\n {onUndo && entry.outcome === \"saved\" && ((entry.audit && entry.audit.action !== \"run\") || entry.audits?.length) && !entry.undone && (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[11px] text-muted-foreground hover:bg-muted hover:text-foreground\"\n onClick={() => onUndo(entry)}\n data-testid=\"studio-activity-undo\"\n >\n <Undo2 className=\"h-3 w-3\" aria-hidden />\n {entry.audits?.length ? `Undo all ${entry.audits.length}` : \"Undo\"}\n </button>\n )}\n </div>\n <p className=\"mt-0.5 text-muted-foreground\">{entry.message}</p>\n {entry.audit && <AuditLine audit={entry.audit} />}\n </li>\n ))}\n </ol>\n )}\n </details>\n );\n}\n\nfunction AuditLine({ audit }: { audit: AuditEntry }) {\n const changes = Object.keys(audit.after ?? {}).map((field) => ({\n field,\n before: displayText(audit.before?.[field]) ?? \"—\",\n after: displayText(audit.after?.[field]) ?? \"—\",\n }));\n return (\n <div className=\"mt-1 rounded bg-muted/50 px-2 py-1 font-mono text-[11px]\" data-testid=\"studio-audit-entry\">\n <div className=\"text-muted-foreground\">\n audit {audit.id.slice(0, 8)} · {audit.occurredAt} · by {audit.actor ?? \"unknown\"}\n </div>\n {changes.map((c) => (\n <div key={c.field}>\n {c.field}: {c.before} → {c.after}\n </div>\n ))}\n </div>\n );\n}\n","// ---------------------------------------------------------------------------\n// Routing and URL state come from the host app (DATA-STUDIO.md decision 23).\n//\n// The studio never touches `window.location` itself. It reads a\n// `StudioLocation` and asks for a new one; the adapter decides how that maps\n// onto the app's router, so a link to \"clients, page 3, sorted by name\" is a\n// plain URL the app already knows how to serve.\n// ---------------------------------------------------------------------------\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\n\n/** Everything the studio keeps in the URL. */\nexport interface StudioLocation {\n /** `schema.table`, e.g. `public.clients`. */\n resource?: string;\n /** 1-based. */\n page?: number;\n /** `field:asc` or `field:desc`; several, comma-separated, sort by each in turn. */\n sort?: string;\n search?: string;\n /** Filters, as a JSON array of `[field, operator, value?]`. */\n filters?: string;\n /** Group rows by this field. */\n group?: string;\n /** The open record's id (`encodeRecordKey`), for a copyable link to it. */\n record?: string;\n /** `sheet`, `kanban` or `calendar`; the table otherwise. */\n view?: StudioView;\n /** For `kanban` and `calendar`: the field that places each row. */\n by?: string;\n /** For `calendar`: the month shown, `YYYY-MM`. */\n month?: string;\n}\n\n/** The views other than the table. */\nexport type StudioView = \"sheet\" | \"kanban\" | \"calendar\";\nconst VIEWS: readonly string[] = [\"sheet\", \"kanban\", \"calendar\"];\n\nexport interface StudioNavigateOptions {\n /** Replace the current history entry instead of pushing one (e.g. while typing a search). */\n replace?: boolean;\n}\n\nexport interface StudioRouter {\n location: StudioLocation;\n navigate(next: StudioLocation, options?: StudioNavigateOptions): void;\n}\n\n/** Query parameter names. Short, and namespaced enough not to collide with an app's own. */\nconst PARAM = {\n resource: \"table\",\n page: \"page\",\n sort: \"sort\",\n search: \"q\",\n filters: \"filter\",\n group: \"group\",\n record: \"record\",\n view: \"view\",\n by: \"by\",\n month: \"month\",\n} as const;\n\nexport function locationFromSearchParams(params: URLSearchParams): StudioLocation {\n const page = Number(params.get(PARAM.page));\n return {\n ...(params.get(PARAM.resource) ? { resource: params.get(PARAM.resource)! } : {}),\n ...(Number.isInteger(page) && page > 1 ? { page } : {}),\n ...(params.get(PARAM.sort) ? { sort: params.get(PARAM.sort)! } : {}),\n ...(params.get(PARAM.search) ? { search: params.get(PARAM.search)! } : {}),\n ...(params.get(PARAM.filters) ? { filters: params.get(PARAM.filters)! } : {}),\n ...(params.get(PARAM.group) ? { group: params.get(PARAM.group)! } : {}),\n ...(params.get(PARAM.record) ? { record: params.get(PARAM.record)! } : {}),\n ...(VIEWS.includes(params.get(PARAM.view) ?? \"\") ? { view: params.get(PARAM.view) as StudioView } : {}),\n ...(params.get(PARAM.by) ? { by: params.get(PARAM.by)! } : {}),\n ...(/^\\d{4}-\\d{2}$/.test(params.get(PARAM.month) ?? \"\") ? { month: params.get(PARAM.month)! } : {}),\n };\n}\n\n/**\n * The studio's location as query parameters, keeping every parameter in\n * `base` that isn't the studio's own.\n */\nexport function searchParamsFromLocation(location: StudioLocation, base?: URLSearchParams): URLSearchParams {\n const params = new URLSearchParams(base);\n for (const name of Object.values(PARAM)) params.delete(name);\n if (location.resource) params.set(PARAM.resource, location.resource);\n if (location.page && location.page > 1) params.set(PARAM.page, String(location.page));\n if (location.sort) params.set(PARAM.sort, location.sort);\n if (location.search) params.set(PARAM.search, location.search);\n if (location.filters) params.set(PARAM.filters, location.filters);\n if (location.group) params.set(PARAM.group, location.group);\n if (location.record) params.set(PARAM.record, location.record);\n if (location.view) params.set(PARAM.view, location.view);\n if (location.by) params.set(PARAM.by, location.by);\n if (location.month) params.set(PARAM.month, location.month);\n return params;\n}\n\n/**\n * An adapter over any router that exposes search params with a setter —\n * React Router's `useSearchParams`, or Next.js's `useSearchParams` plus\n * `router.replace`/`push`.\n *\n * @example React Router\n * const [params, setParams] = useSearchParams();\n * const router = createSearchParamsRouter(params, (next, { replace }) => setParams(next, { replace }));\n */\nexport function createSearchParamsRouter(\n params: URLSearchParams,\n setParams: (next: URLSearchParams, options: { replace: boolean }) => void,\n): StudioRouter {\n return {\n location: locationFromSearchParams(params),\n navigate: (next, options) => setParams(searchParamsFromLocation(next, params), { replace: options?.replace ?? false }),\n };\n}\n\n/**\n * For an app with no router: keeps the studio's state in the current page's\n * query string through the History API.\n */\nexport function useHistoryRouter(): StudioRouter {\n const read = () =>\n typeof window === \"undefined\" ? {} : locationFromSearchParams(new URLSearchParams(window.location.search));\n const [location, setLocation] = useState<StudioLocation>(read);\n\n useEffect(() => {\n const onPop = () => setLocation(read());\n window.addEventListener(\"popstate\", onPop);\n return () => window.removeEventListener(\"popstate\", onPop);\n }, []);\n\n const navigate = useCallback((next: StudioLocation, options?: StudioNavigateOptions) => {\n const params = searchParamsFromLocation(next, new URLSearchParams(window.location.search));\n const query = params.toString();\n const url = `${window.location.pathname}${query ? `?${query}` : \"\"}${window.location.hash}`;\n if (options?.replace) window.history.replaceState(window.history.state, \"\", url);\n else window.history.pushState(window.history.state, \"\", url);\n setLocation(next);\n }, []);\n\n return useMemo(() => ({ location, navigate }), [location, navigate]);\n}\n\n/** A router held in memory, for tests and embedded previews. */\nexport function useMemoryRouter(initial: StudioLocation = {}): StudioRouter {\n const [location, setLocation] = useState<StudioLocation>(initial);\n const navigate = useCallback((next: StudioLocation) => setLocation(next), []);\n return useMemo(() => ({ location, navigate }), [location, navigate]);\n}\n","// How a stored value is shown, edited, and sent back. Postgres parses what\n// comes back (the handler casts every value to the column's type), so the\n// studio only decides what text the user sees and what \"empty\" means.\n\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\n\n/** The text a cell starts editing from. JSON is edited as JSON text. */\nexport function editText(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/** The text a cell shows, or `null` for an empty cell. */\nexport function displayText(value: unknown): string | null {\n if (value === null || value === undefined) return null;\n return editText(value);\n}\n\n/**\n * The value to save for what the user typed. An emptied cell becomes `null`\n * when the field accepts null, and the empty string otherwise.\n */\nexport function parseDraft(field: FieldSchema, draft: string): unknown {\n if (draft === \"\" && field.nullable) return null;\n return draft;\n}\n\n/** The choices for a select-style cell, or `undefined` for free text. */\nexport function choicesFor(field: FieldSchema): string[] | undefined {\n if (field.enumValues) return [...field.enumValues];\n if (field.type === \"boolean\") return [\"true\", \"false\"];\n return undefined;\n}\n\n/** What a person calls a field: its contract label, or its name. */\nexport function fieldLabel(field: FieldSchema): string {\n return field.label ?? field.name;\n}\n","// CSV moved to genesis-core (./csv) so ResourceView's export and the importers share it.\nexport { csvField, exportCsv, parseCsv, toCsv, type ExportOptions } from \"@marktiderman/genesis-core/csv\";\n\n/** Hand the browser a file to save. */\nexport function downloadText(filename: string, text: string, type = \"text/csv;charset=utf-8\"): void {\n const url = URL.createObjectURL(new Blob([text], { type }));\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n link.remove();\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\n","// The list's search, sorts, filters and grouping, read from and written to\n// the URL so every view is a link.\n\nimport type { FilterParam, SortParam } from \"@marktiderman/genesis-core/provider\";\nimport type { FieldSchema, FilterOperator } from \"@marktiderman/genesis-core/schema\";\n\nexport function parseSorts(sort: string | undefined): SortParam[] {\n if (!sort) return [];\n return sort\n .split(\",\")\n .map((part) => {\n const at = part.lastIndexOf(\":\");\n const field = at > 0 ? part.slice(0, at) : part;\n return { field, order: part.slice(at + 1) === \"desc\" ? (\"desc\" as const) : (\"asc\" as const) };\n })\n .filter((s) => s.field);\n}\n\nexport function formatSorts(sorts: SortParam[]): string | undefined {\n return sorts.length ? sorts.map((s) => `${s.field}:${s.order}`).join(\",\") : undefined;\n}\n\ntype Encoded = [string, FilterOperator, unknown?];\n\nexport function parseFilters(raw: string | undefined): FilterParam[] {\n if (!raw) return [];\n try {\n const list = JSON.parse(raw) as Encoded[];\n if (!Array.isArray(list)) return [];\n return list\n .filter((f) => Array.isArray(f) && typeof f[0] === \"string\" && typeof f[1] === \"string\")\n .map(([field, operator, value]) =>\n operator === \"is_null\" || operator === \"is_not_null\"\n ? ({ field, operator } as FilterParam)\n : ({ field, operator, value } as FilterParam),\n );\n } catch {\n return [];\n }\n}\n\nexport function formatFilters(filters: FilterParam[]): string | undefined {\n if (!filters.length) return undefined;\n return JSON.stringify(filters.map((f) => (\"value\" in f ? [f.field, f.operator, f.value] : [f.field, f.operator])));\n}\n\n/** Operators that make sense for a field, by its storage type. */\nexport function operatorsFor(field: FieldSchema): FilterOperator[] {\n if (field.array) return [\"is_null\", \"is_not_null\"];\n if (field.enumValues || field.type === \"boolean\") return [\"eq\", \"neq\", \"is_null\", \"is_not_null\"];\n if (field.type === \"number\" || field.type === \"datetime\") {\n return [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\", \"is_null\", \"is_not_null\"];\n }\n if (field.type === \"json\") return [\"contains\", \"is_null\", \"is_not_null\"];\n return [\"contains\", \"eq\", \"neq\", \"is_null\", \"is_not_null\"];\n}\n\nexport const OPERATOR_LABEL: Record<FilterOperator, string> = {\n eq: \"is\",\n neq: \"is not\",\n gt: \"is after / more than\",\n gte: \"is on or after / at least\",\n lt: \"is before / less than\",\n lte: \"is on or before / at most\",\n contains: \"contains\",\n in: \"is any of\",\n between: \"is between\",\n is_null: \"is empty\",\n is_not_null: \"is not empty\",\n};\n\nexport function needsValue(operator: FilterOperator): boolean {\n return operator !== \"is_null\" && operator !== \"is_not_null\";\n}\n","// Following links between resources: labels for foreign-key cells (batched,\n// one query per linked resource per page) and the target's schema.\n\nimport { useQueries, useQuery } from \"@tanstack/react-query\";\nimport type { BaseRecord, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport { keyFields, type FieldSchema, type ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { displayText } from \"../values\";\n\nexport function useSchema(provider: DataProvider, sessionKey: unknown, resource: string | undefined) {\n return useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"describe\", resource],\n enabled: Boolean(resource && provider.describe),\n retry: false,\n queryFn: () => provider.describe!(resource!),\n });\n}\n\n/** The single key field of a resource, or null for a composite key. */\nexport function singleKey(schema: ResourceSchema | undefined): string | null {\n if (!schema) return null;\n const fields = keyFields(schema);\n return fields.length === 1 ? fields[0]! : null;\n}\n\n/**\n * Labels for every link field on a page of rows: field → (id → the target\n * row's `labelField`). One query per linked resource, never one per cell.\n * Ids the user can't see stay unlabelled.\n */\nexport function usePageLinkLabels(\n provider: DataProvider,\n sessionKey: unknown,\n fields: readonly FieldSchema[],\n rows: readonly Record<string, unknown>[],\n): Map<string, Map<string, string>> {\n const links = fields.filter((f) => f.references);\n const schemas = useQueries({\n queries: links.map((f) => ({\n queryKey: [\"genesis-studio\", sessionKey, \"describe\", f.references!.resource],\n enabled: Boolean(provider.describe),\n retry: false,\n queryFn: () => provider.describe!(f.references!.resource),\n })),\n });\n const labels = useQueries({\n queries: links.map((f, i) => {\n const ids = [...new Set(rows.map((r) => r[f.name]).filter((v) => v !== null && v !== undefined).map(String))].sort();\n const labelField = schemas[i]?.data?.labelField;\n return {\n queryKey: [\"genesis-studio\", sessionKey, \"labels\", f.references!.resource, f.references!.field, ids],\n enabled: Boolean(schemas[i]?.data && ids.length),\n staleTime: 60_000,\n retry: false,\n queryFn: async () => {\n const result = await provider.getList<BaseRecord>(f.references!.resource, {\n pagination: { page: 1, perPage: Math.min(200, ids.length) },\n filters: [{ field: f.references!.field, operator: \"in\" as const, value: ids }],\n });\n return new Map(\n (result.data as Record<string, unknown>[]).map((row) => [\n String(row[f.references!.field]),\n displayText(row[labelField ?? f.references!.field]) ?? String(row[f.references!.field]),\n ]),\n );\n },\n };\n }),\n });\n const out = new Map<string, Map<string, string>>();\n links.forEach((f, i) => out.set(f.name, labels[i]?.data ?? new Map()));\n return out;\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { Controller, useForm, type Resolver } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport type { DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Checkbox } from \"@marktiderman/genesis-ui/checkbox\";\nimport { Input } from \"@marktiderman/genesis-ui/input\";\nimport { Label } from \"@marktiderman/genesis-ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@marktiderman/genesis-ui/select\";\nimport { Textarea } from \"@marktiderman/genesis-ui/textarea\";\nimport { formSchema, fromFormValue, isRequired, toFormValues, type FormValues } from \"../lib/form-schema\";\nimport { sectionFields, type StudioFormConfig } from \"../lib/form-config\";\nimport { choicesFor, fieldLabel } from \"../values\";\nimport { RelationPicker } from \"./RelationPicker\";\n\nconst NONE = \"__genesis_none__\";\n\nexport interface RecordFormProps {\n provider: DataProvider;\n sessionKey: unknown;\n mode: \"create\" | \"edit\";\n /** Every field to show, in order. */\n fields: readonly FieldSchema[];\n /** Fields the user may change; the rest show read-only with their reason. */\n editable: ReadonlySet<string>;\n /** The row being edited, or defaults for a new one. */\n row?: Record<string, unknown>;\n /** Called with only the fields that changed (edit) or were filled in (create). */\n onSubmit: (values: Record<string, unknown>) => Promise<void>;\n submitLabel: string;\n onCancel?: () => void;\n /** Sections and conditional fields for this resource. */\n config?: StudioFormConfig;\n}\n\n/**\n * A form built from the schema: one control per field by its widget hint,\n * validation from the schema (required, numbers, dates, enums, JSON), and\n * read-only fields shown with the reason they can't be changed.\n */\nexport function RecordForm({ provider, sessionKey, mode, fields, editable, row, onSubmit, submitLabel, onCancel, config }: RecordFormProps) {\n const writable = useMemo(() => fields.filter((f) => editable.has(f.name)), [fields, editable]);\n const sections = useMemo(() => sectionFields(fields, config), [fields, config]);\n // The schema is built at runtime from the fields, so its inferred type is\n // only known to be FormValues by construction.\n // Only the fields a condition currently shows are validated: a hidden\n // required field can't block the save (and is left out of it).\n const resolver = useMemo<Resolver<FormValues>>(\n () => (values, context, options) => {\n const shown = writable.filter((f) => {\n const rule = config?.visibleWhen?.[f.name];\n return rule ? rule(values as Record<string, unknown>) : true;\n });\n const validate = zodResolver(formSchema(shown, mode) as never) as unknown as Resolver<FormValues>;\n return validate(values, context, options);\n },\n [writable, mode, config],\n );\n const defaults = useMemo(() => toFormValues(fields, row), [fields, row]);\n const form = useForm<FormValues>({ resolver, defaultValues: defaults });\n const [error, setError] = useState<string | null>(null);\n const values = form.watch();\n const isVisible = (name: string) => {\n const rule = config?.visibleWhen?.[name];\n return rule ? rule(values as Record<string, unknown>) : true;\n };\n\n // A save (or someone else's change) brings a new row: start from it.\n useEffect(() => {\n form.reset(defaults);\n }, [defaults, form]);\n\n const submit = form.handleSubmit(async (values) => {\n setError(null);\n const out: Record<string, unknown> = {};\n for (const field of writable) {\n // A field the config hides is left out of the save.\n if (!isVisible(field.name)) continue;\n const value = values[field.name];\n if (value === undefined) continue;\n if (mode === \"edit\" && value === defaults[field.name]) continue;\n if (mode === \"create\" && value === \"\" && !isRequired(field, mode)) continue;\n out[field.name] = fromFormValue(field, value);\n }\n if (mode === \"edit\" && Object.keys(out).length === 0) return;\n try {\n await onSubmit(out);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n });\n\n return (\n <form onSubmit={submit} className=\"space-y-4\" noValidate data-testid={`studio-record-form-${mode}`}>\n {sections.map((section) => (\n <fieldset key={section.title ?? \"fields\"} className=\"space-y-4\">\n {section.title && <legend className=\"mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground\">{section.title}</legend>}\n {section.fields.filter((field) => isVisible(field.name)).map((field) => {\n const id = `studio-field-${field.name}`;\n const canEdit = editable.has(field.name);\n const fieldError = form.formState.errors[field.name]?.message;\n const required = canEdit && isRequired(field, mode);\n const choices = choicesFor(field);\n return (\n <div key={field.name} className=\"space-y-1.5\">\n <Label htmlFor={id} className=\"flex items-baseline gap-1.5\">\n <span title={field.label ? field.name : undefined}>{fieldLabel(field)}</span>\n {required && <span className=\"text-destructive\" aria-hidden>*</span>}\n <span className=\"ml-auto font-mono text-[10px] font-normal text-muted-foreground\">{field.dbType}</span>\n </Label>\n <Controller\n control={form.control}\n name={field.name}\n render={({ field: control }) => {\n const disabled = !canEdit || form.formState.isSubmitting;\n if (field.references) {\n return (\n <RelationPicker\n id={id}\n provider={provider}\n sessionKey={sessionKey}\n field={field}\n value={String(control.value ?? \"\")}\n onChange={control.onChange}\n disabled={disabled}\n />\n );\n }\n if (field.type === \"boolean\" && !field.nullable) {\n return (\n <div className=\"flex h-9 items-center\">\n <Checkbox id={id} checked={control.value === true} onCheckedChange={(v) => control.onChange(v === true)} disabled={disabled} />\n </div>\n );\n }\n if (choices) {\n return (\n <Select\n value={control.value === \"\" ? NONE : String(control.value)}\n onValueChange={(v) => control.onChange(v === NONE ? \"\" : v)}\n disabled={disabled}\n >\n <SelectTrigger id={id} aria-invalid={fieldError ? true : undefined}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {(field.nullable || mode === \"create\") && <SelectItem value={NONE}>—</SelectItem>}\n {choices.map((c) => (\n <SelectItem key={c} value={c}>\n {c}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n }\n if (field.widget === \"textarea\") {\n return (\n <Textarea\n id={id}\n rows={4}\n className=\"font-mono text-xs\"\n value={String(control.value ?? \"\")}\n onChange={control.onChange}\n onBlur={control.onBlur}\n disabled={disabled}\n aria-invalid={fieldError ? true : undefined}\n />\n );\n }\n return (\n <Input\n id={id}\n type={field.widget === \"date\" ? \"date\" : \"text\"}\n inputMode={field.type === \"number\" ? \"decimal\" : undefined}\n value={String(control.value ?? \"\")}\n onChange={control.onChange}\n onBlur={control.onBlur}\n disabled={disabled}\n aria-invalid={fieldError ? true : undefined}\n />\n );\n }}\n />\n {fieldError ? (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {String(fieldError)}\n </p>\n ) : !canEdit && field.permissions?.reason ? (\n <p className=\"text-xs text-muted-foreground\">{field.permissions.reason}</p>\n ) : field.description ? (\n <p className=\"text-xs text-muted-foreground\">{field.description}</p>\n ) : null}\n </div>\n );\n })}\n </fieldset>\n ))}\n {error && (\n <p role=\"alert\" className=\"rounded-md border border-destructive/40 bg-destructive/5 p-2 text-sm text-destructive\" data-testid=\"studio-form-error\">\n {error}\n </p>\n )}\n {writable.length > 0 && (\n <div className=\"flex justify-end gap-2\">\n {onCancel && (\n <Button type=\"button\" variant=\"outline\" onClick={onCancel}>\n Cancel\n </Button>\n )}\n <Button type=\"submit\" disabled={form.formState.isSubmitting} testID={`studio-${mode}-submit`}>\n {form.formState.isSubmitting ? \"Saving…\" : submitLabel}\n </Button>\n </div>\n )}\n </form>\n );\n}\n","// Validation built from the schema (DATA-STUDIO.md P1, \"forms built from the\n// schema\"): required from NOT NULL without a default, enum labels, numbers,\n// dates and JSON. The database still has the last word on CHECK constraints\n// and domains; its reason comes back as the save's error.\n\nimport { z } from \"zod\";\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\nimport { choicesFor, editText } from \"../values\";\n\nexport type FormValues = Record<string, string | boolean>;\n\n/** Fields that need a value: NOT NULL and, on a new row, no default. */\nexport function isRequired(field: FieldSchema, mode: \"create\" | \"edit\"): boolean {\n if (field.nullable || field.generated) return false;\n return mode === \"edit\" || !field.hasDefault;\n}\n\nconst NUMBER = /^-?(\\d+\\.?\\d*|\\.\\d+)(e[-+]?\\d+)?$/i;\nconst DATE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction textRule(field: FieldSchema, required: boolean) {\n const choices = choicesFor(field);\n return z.string().superRefine((value, ctx) => {\n if (value === \"\") {\n if (required) ctx.addIssue({ code: \"custom\", message: \"Required.\" });\n return;\n }\n if (field.type === \"number\" && !NUMBER.test(value.trim())) ctx.addIssue({ code: \"custom\", message: \"Enter a number.\" });\n if (field.widget === \"date\" && !DATE.test(value)) ctx.addIssue({ code: \"custom\", message: \"Enter a date (YYYY-MM-DD).\" });\n if (choices && field.type !== \"boolean\" && !choices.includes(value)) {\n ctx.addIssue({ code: \"custom\", message: `Choose one of: ${choices.join(\", \")}.` });\n }\n if (field.type === \"json\") {\n try {\n JSON.parse(value);\n } catch {\n ctx.addIssue({ code: \"custom\", message: \"Enter valid JSON.\" });\n }\n }\n });\n}\n\nexport function formSchema(fields: readonly FieldSchema[], mode: \"create\" | \"edit\") {\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const field of fields) {\n const required = isRequired(field, mode);\n shape[field.name] = field.type === \"boolean\" && !field.nullable ? z.boolean() : textRule(field, required);\n }\n return z.object(shape);\n}\n\n/** A row's values as form values: booleans stay booleans, everything else is text. */\nexport function toFormValues(fields: readonly FieldSchema[], row: Record<string, unknown> | undefined): FormValues {\n const out: FormValues = {};\n for (const field of fields) {\n const value = row?.[field.name];\n out[field.name] = field.type === \"boolean\" && !field.nullable ? value === true || value === \"true\" : editText(value);\n }\n return out;\n}\n\n/** A form value as the value to save. An emptied field is null where null is allowed. */\nexport function fromFormValue(field: FieldSchema, value: string | boolean): unknown {\n if (typeof value === \"boolean\") return value;\n if (value === \"\") return field.nullable ? null : \"\";\n return value;\n}\n","// Code-first form layout (DATA-STUDIO.md P2, \"conditional fields and\n// sections, declared in code config first\").\n\n/** How one resource's record form is laid out. */\nexport interface StudioFormConfig {\n /** Fields grouped under headings, in order. Fields in no section follow, under \"Other\". */\n sections?: { title: string; fields: string[] }[];\n /**\n * Show a field only when this returns true for the form's current values,\n * e.g. `{ cancel_reason: (v) => v.status === \"cancelled\" }`. A hidden field\n * is left out of the save.\n */\n visibleWhen?: Record<string, (values: Record<string, unknown>) => boolean>;\n}\n\nexport interface FormSection<F> {\n title: string | null;\n fields: F[];\n}\n\n/** Split fields into the configured sections, keeping each field once. */\nexport function sectionFields<F extends { name: string }>(fields: readonly F[], config: StudioFormConfig | undefined): FormSection<F>[] {\n if (!config?.sections?.length) return [{ title: null, fields: [...fields] }];\n const byName = new Map(fields.map((f) => [f.name, f]));\n const used = new Set<string>();\n const out: FormSection<F>[] = [];\n for (const section of config.sections) {\n const list = section.fields.map((n) => byName.get(n)).filter((f): f is F => Boolean(f) && !used.has(f!.name));\n list.forEach((f) => used.add(f.name));\n if (list.length) out.push({ title: section.title, fields: list });\n }\n const rest = fields.filter((f) => !used.has(f.name));\n if (rest.length) out.push({ title: \"Other\", fields: rest });\n return out;\n}\n","import { useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ChevronsUpDown, X } from \"lucide-react\";\nimport type { BaseRecord, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@marktiderman/genesis-ui/popover\";\nimport { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from \"@marktiderman/genesis-ui/command\";\nimport { useSchema } from \"../lib/relations\";\nimport { displayText } from \"../values\";\n\nexport interface RelationPickerProps {\n provider: DataProvider;\n sessionKey: unknown;\n field: FieldSchema;\n /** The linked row's key, as text (\"\" for none). */\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n id?: string;\n}\n\n/**\n * Pick a linked row by searching the target resource on the server, so it\n * works for a table of any size; shows each row by its label field.\n */\nexport function RelationPicker({ provider, sessionKey, field, value, onChange, disabled, id }: RelationPickerProps) {\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState(\"\");\n const target = field.references!.resource;\n const targetField = field.references!.field;\n const schema = useSchema(provider, sessionKey, target);\n const labelField = schema.data?.labelField ?? targetField;\n\n const options = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"pick\", target, search],\n enabled: open && Boolean(schema.data),\n retry: false,\n queryFn: () =>\n provider.getList<BaseRecord>(target, {\n pagination: { page: 1, perPage: 20 },\n ...(search ? { search: { query: search, fields: [] } } : {}),\n }),\n });\n const current = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"labels\", target, targetField, [value]],\n enabled: Boolean(value && schema.data),\n retry: false,\n queryFn: async () => {\n const result = await provider.getList<BaseRecord>(target, {\n pagination: { page: 1, perPage: 1 },\n filters: [{ field: targetField, operator: \"eq\", value }],\n });\n const row = result.data[0] as Record<string, unknown> | undefined;\n return new Map(row ? [[value, displayText(row[labelField]) ?? value]] : []);\n },\n });\n const label = value ? (current.data?.get(value) ?? value) : \"—\";\n\n return (\n <div className=\"flex items-center gap-1\">\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n id={id}\n type=\"button\"\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n disabled={disabled}\n className=\"h-9 w-full justify-between font-normal\"\n testID={`studio-picker-${field.name}`}\n >\n <span className=\"truncate\">{label}</span>\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" aria-hidden />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-72 p-0\" align=\"start\">\n <Command shouldFilter={false}>\n <CommandInput placeholder={`Search ${target}…`} value={search} onValueChange={setSearch} />\n <CommandList>\n <CommandEmpty>{options.isLoading ? \"Searching…\" : \"No matches you can see.\"}</CommandEmpty>\n {(options.data?.data as Record<string, unknown>[] | undefined)?.map((row) => {\n const key = String(row[targetField]);\n return (\n <CommandItem\n key={key}\n value={key}\n onSelect={() => {\n onChange(key);\n setOpen(false);\n }}\n >\n <span className=\"truncate\">{displayText(row[labelField]) ?? key}</span>\n <span className=\"ml-auto pl-2 font-mono text-[10px] text-muted-foreground\">{key}</span>\n </CommandItem>\n );\n })}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n {value && field.nullable && !disabled && (\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"h-9 w-9\" aria-label={`Clear ${field.name}`} onClick={() => onChange(\"\")}>\n <X className=\"h-4 w-4\" aria-hidden />\n </Button>\n )}\n </div>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { ExternalLink, Link2, Play, Trash2 } from \"lucide-react\";\nimport type { BaseRecord, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport {\n encodeRecordKey,\n isDataWriteError,\n type AuditEntry,\n type ResourceRelation,\n type ResourceSchema,\n type RowAction,\n} from \"@marktiderman/genesis-core/schema\";\nimport { Textarea } from \"@marktiderman/genesis-ui/textarea\";\nimport { Alert, AlertDescription, AlertTitle } from \"@marktiderman/genesis-ui/alert\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from \"@marktiderman/genesis-ui/alert-dialog\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from \"@marktiderman/genesis-ui/sheet\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@marktiderman/genesis-ui/tabs\";\nimport { singleKey, useSchema } from \"../lib/relations\";\nimport { displayText } from \"../values\";\nimport { RecordForm } from \"./RecordForm\";\nimport type { StudioFormConfig } from \"../lib/form-config\";\n\nexport interface RecordPanelProps {\n provider: DataProvider;\n sessionKey: unknown;\n schema: ResourceSchema;\n /** The record's id (`encodeRecordKey`). */\n id: string;\n onClose: () => void;\n /** Open another record (a related one), in its own table. */\n onOpenRecord: (resource: string, id: string) => void;\n onSaved: (row: Record<string, unknown>, audit?: AuditEntry) => void;\n onDeleted: (audit?: AuditEntry) => void;\n onFailed: (action: string, message: string) => void;\n /** A change from the History tab was undone. */\n onUndone?: (audit?: AuditEntry) => void;\n /** Sections and conditional fields for the form. */\n formConfig?: StudioFormConfig;\n /** A row action ran; `row` is null when it removed the row. */\n onActionRan?: (action: RowAction, row: Record<string, unknown> | null, audit?: AuditEntry) => void;\n}\n\nfunction versionOf(schema: ResourceSchema, row: Record<string, unknown> | undefined): string | null {\n const field = schema.version?.field;\n if (!field || !row || row[field] == null) return null;\n return String(row[field]);\n}\n\n/**\n * One record, in a side panel: its fields as a form, the records it links to\n * and from, and its audit history. The URL names it, so the link copies.\n */\nexport function RecordPanel(props: RecordPanelProps) {\n const { provider, sessionKey, schema, id } = props;\n const queryClient = useQueryClient();\n const recordKey = [\"genesis-studio\", sessionKey, \"record\", schema.name, id];\n const record = useQuery({\n queryKey: recordKey,\n retry: false,\n queryFn: async () => (await provider.getOne<BaseRecord>(schema.name, { id })).data as Record<string, unknown>,\n });\n const [conflict, setConflict] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n const row = record.data;\n const title = row ? (displayText(row[schema.labelField ?? \"\"]) ?? id) : id;\n const editable = useMemo(() => new Set(schema.fields.filter((f) => f.permissions?.update).map((f) => f.name)), [schema]);\n const relations = schema.relations ?? [];\n\n async function save(values: Record<string, unknown>) {\n setConflict(null);\n try {\n const result = await provider.update<BaseRecord>(schema.name, { id, data: values as never, expectedVersion: versionOf(schema, row) });\n queryClient.setQueryData(recordKey, result.data);\n props.onSaved(result.data as Record<string, unknown>, result.audit);\n } catch (error) {\n if (isDataWriteError(error) && error.outcome === \"conflict\") {\n setConflict(error.message);\n if (error.current) {\n queryClient.setQueryData(recordKey, {\n ...row,\n ...error.current,\n ...(schema.version ? { [schema.version.field]: error.currentVersion ?? null } : {}),\n });\n } else {\n void record.refetch();\n }\n }\n props.onFailed(\"update\", error instanceof Error ? error.message : String(error));\n throw error;\n }\n }\n\n async function remove() {\n try {\n const result = await provider.deleteOne(schema.name, { id, expectedVersion: versionOf(schema, row) });\n props.onDeleted(result.audit);\n props.onClose();\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n setConflict(message);\n props.onFailed(\"delete\", message);\n void record.refetch();\n }\n }\n\n const [running, setRunning] = useState<string | null>(null);\n const [actionError, setActionError] = useState<{ label: string; message: string } | null>(null);\n const [confirming, setConfirming] = useState<RowAction | null>(null);\n async function runAction(action: RowAction) {\n setConflict(null);\n setActionError(null);\n setRunning(action.name);\n try {\n const result = await provider.runAction!(schema.name, { id, action: action.name, expectedVersion: versionOf(schema, row) });\n props.onActionRan?.(action, result.data, result.audit);\n if (result.data) queryClient.setQueryData(recordKey, result.data);\n else props.onClose();\n void queryClient.invalidateQueries({ queryKey: [\"genesis-studio\", sessionKey, \"history\", schema.name, id] });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n setActionError({ label: action.label, message: message.replace(/^Not (saved|run): /, \"\") });\n props.onFailed(`action:${action.name}`, message);\n void record.refetch();\n } finally {\n setRunning(null);\n }\n }\n const actions = provider.runAction ? (schema.actions ?? []) : [];\n\n async function copyLink() {\n try {\n await navigator.clipboard.writeText(window.location.href);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n } catch {\n setCopied(false);\n }\n }\n\n return (\n <Sheet open onOpenChange={(open) => !open && props.onClose()}>\n <SheetContent className=\"w-full overflow-y-auto sm:max-w-xl\" data-testid=\"studio-record-panel\">\n <SheetHeader>\n <SheetTitle className=\"truncate pr-8\">{title}</SheetTitle>\n <SheetDescription>\n {schema.label ?? schema.name} · <span className=\"font-mono text-xs\">{id}</span>\n </SheetDescription>\n </SheetHeader>\n <div className=\"mt-3 flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={copyLink} testID=\"studio-copy-link\">\n <Link2 className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n {copied ? \"Link copied\" : \"Copy link\"}\n </Button>\n {schema.access.delete ? (\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" testID=\"studio-delete\">\n <Trash2 className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n Delete\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete {title}?</AlertDialogTitle>\n <AlertDialogDescription>\n The deletion is audited. It only goes through if nobody has changed the row since you opened it.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Keep it</AlertDialogCancel>\n <AlertDialogAction onClick={() => void remove()} data-testid=\"studio-delete-confirm\">\n Delete\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n ) : (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled title={schema.access.reasons?.delete}>\n <Trash2 className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n Delete\n </Button>\n )}\n {actions.map((action) => (\n <Button\n key={action.name}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={!row || running !== null}\n title={action.description}\n onClick={() => (action.confirm ? setConfirming(action) : void runAction(action))}\n testID={`studio-action-${action.name}`}\n >\n <Play className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n {running === action.name ? `${action.label}…` : action.label}\n </Button>\n ))}\n </div>\n <AlertDialog open={confirming !== null} onOpenChange={(open) => !open && setConfirming(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{confirming?.confirm}</AlertDialogTitle>\n <AlertDialogDescription>\n {confirming?.description ? `${confirming.description} ` : \"\"}It runs on this row as you see it now, and is audited.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={() => {\n const action = confirming;\n setConfirming(null);\n if (action) void runAction(action);\n }}\n data-testid=\"studio-action-confirm\"\n >\n {confirming?.label}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {actionError && (\n <Alert variant=\"destructive\" className=\"mt-3\" data-testid=\"studio-action-error\">\n <AlertTitle>{actionError.label} didn't run</AlertTitle>\n <AlertDescription>{actionError.message} Nothing was changed.</AlertDescription>\n </Alert>\n )}\n {conflict && (\n <Alert variant=\"destructive\" className=\"mt-3\" data-testid=\"studio-record-conflict\">\n <AlertTitle>Not saved</AlertTitle>\n <AlertDescription>{conflict} The form now shows the row as it is.</AlertDescription>\n </Alert>\n )}\n\n {record.isError ? (\n <Alert variant=\"destructive\" className=\"mt-4\">\n <AlertTitle>Couldn't open this record</AlertTitle>\n <AlertDescription>{record.error instanceof Error ? record.error.message : String(record.error)}</AlertDescription>\n </Alert>\n ) : (\n <Tabs defaultValue=\"details\" className=\"mt-4\">\n <TabsList>\n <TabsTrigger value=\"details\">Details</TabsTrigger>\n {relations.length > 0 && <TabsTrigger value=\"related\">Related ({relations.length})</TabsTrigger>}\n <TabsTrigger value=\"history\" disabled={!schema.access.history} title={schema.access.reasons?.history}>\n History\n </TabsTrigger>\n {schema.access.comment !== undefined && provider.comments && (\n <TabsTrigger value=\"comments\" disabled={!schema.access.comment} title={schema.access.reasons?.comment}>\n Comments\n </TabsTrigger>\n )}\n </TabsList>\n <TabsContent value=\"details\" className=\"pt-2\">\n {row ? (\n <RecordForm\n provider={provider}\n sessionKey={sessionKey}\n mode=\"edit\"\n fields={schema.fields}\n editable={editable}\n row={row}\n onSubmit={save}\n submitLabel=\"Save changes\"\n config={props.formConfig}\n />\n ) : (\n <p className=\"text-sm text-muted-foreground\">Loading…</p>\n )}\n </TabsContent>\n {relations.length > 0 && (\n <TabsContent value=\"related\" className=\"space-y-5 pt-2\">\n {row &&\n relations.map((relation) => (\n <RelatedSection\n key={`${relation.kind}:${relation.resource}:${relation.field}`}\n provider={provider}\n sessionKey={sessionKey}\n schema={schema}\n row={row}\n relation={relation}\n onOpenRecord={props.onOpenRecord}\n />\n ))}\n </TabsContent>\n )}\n {schema.access.history && (\n <TabsContent value=\"history\" className=\"pt-2\">\n <History\n provider={provider}\n sessionKey={sessionKey}\n resource={schema.name}\n id={id}\n onUndone={(audit) => {\n void record.refetch();\n props.onUndone?.(audit);\n }}\n />\n </TabsContent>\n )}\n {schema.access.comment && provider.comments && (\n <TabsContent value=\"comments\" className=\"pt-2\">\n <Comments provider={provider} sessionKey={sessionKey} resource={schema.name} id={id} />\n </TabsContent>\n )}\n </Tabs>\n )}\n </SheetContent>\n </Sheet>\n );\n}\n\nfunction RelatedSection({\n provider,\n sessionKey,\n schema,\n row,\n relation,\n onOpenRecord,\n}: {\n provider: DataProvider;\n sessionKey: unknown;\n schema: ResourceSchema;\n row: Record<string, unknown>;\n relation: ResourceRelation;\n onOpenRecord: (resource: string, id: string) => void;\n}) {\n const target = useSchema(provider, sessionKey, relation.resource);\n const ownKey = singleKey(schema);\n const query = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"related\", schema.name, relation.kind, relation.resource, relation.field, row[ownKey ?? \"\"]],\n enabled: Boolean(target.data),\n retry: false,\n queryFn: async (): Promise<Record<string, unknown>[]> => {\n const targetKey = singleKey(target.data);\n if (relation.kind === \"one\") {\n const value = row[relation.field];\n if (value == null || !targetKey) return [];\n const r = await provider.getList<BaseRecord>(relation.resource, {\n pagination: { page: 1, perPage: 1 },\n filters: [{ field: targetKey, operator: \"eq\", value: String(value) }],\n });\n return r.data as Record<string, unknown>[];\n }\n const self = row[ownKey ?? \"\"];\n if (self == null) return [];\n if (relation.kind === \"many\") {\n const r = await provider.getList<BaseRecord>(relation.resource, {\n pagination: { page: 1, perPage: 25 },\n filters: [{ field: relation.field, operator: \"eq\", value: String(self) }],\n });\n return r.data as Record<string, unknown>[];\n }\n // through: the junction's rows for this record, then the rows they point at.\n const links = await provider.getList<BaseRecord>(relation.through!.resource, {\n pagination: { page: 1, perPage: 100 },\n filters: [{ field: relation.field, operator: \"eq\", value: String(self) }],\n });\n const ids = (links.data as Record<string, unknown>[]).map((l) => String(l[relation.through!.otherField]));\n if (!ids.length || !targetKey) return [];\n const r = await provider.getList<BaseRecord>(relation.resource, {\n pagination: { page: 1, perPage: Math.min(100, ids.length) },\n filters: [{ field: targetKey, operator: \"in\", value: ids }],\n });\n return r.data as Record<string, unknown>[];\n },\n });\n const heading = `${target.data?.label ?? relation.resource}${\n relation.kind === \"one\" ? ` (via ${relation.field})` : relation.kind === \"through\" ? ` (via ${relation.through!.resource})` : \"\"\n }`;\n const labelField = target.data?.labelField;\n\n return (\n <section data-testid={`studio-related-${relation.resource}`}>\n <h3 className=\"mb-1.5 text-sm font-semibold\">{heading}</h3>\n {query.isLoading ? (\n <p className=\"text-xs text-muted-foreground\">Loading…</p>\n ) : !query.data?.length ? (\n <p className=\"text-xs text-muted-foreground\">None you can see.</p>\n ) : (\n <ul className=\"divide-y rounded-md border\">\n {query.data.map((related, index) => {\n const relatedId = target.data ? String(encodeRecordKey(target.data, related)) : String(index);\n return (\n <li key={relatedId}>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-sm hover:bg-muted\"\n onClick={() => onOpenRecord(relation.resource, relatedId)}\n >\n <span className=\"truncate\">{displayText(related[labelField ?? \"\"]) ?? relatedId}</span>\n <ExternalLink className=\"ml-auto h-3.5 w-3.5 shrink-0 text-muted-foreground\" aria-hidden />\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </section>\n );\n}\n\nfunction History({\n provider,\n sessionKey,\n resource,\n id,\n onUndone,\n}: {\n provider: DataProvider;\n sessionKey: unknown;\n resource: string;\n id: string;\n onUndone: (audit?: AuditEntry) => void;\n}) {\n const [undoError, setUndoError] = useState<string | null>(null);\n const history = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"history\", resource, id],\n enabled: Boolean(provider.history),\n retry: false,\n queryFn: () => provider.history!(resource, { id }),\n });\n if (history.isLoading) return <p className=\"text-xs text-muted-foreground\">Loading…</p>;\n if (history.isError) {\n return (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {history.error instanceof Error ? history.error.message : String(history.error)}\n </p>\n );\n }\n if (!history.data?.length) return <p className=\"text-xs text-muted-foreground\">No audited changes yet.</p>;\n async function undo(entry: AuditEntry) {\n setUndoError(null);\n try {\n const result = await provider.undo!(resource, { auditId: entry.id });\n void history.refetch();\n onUndone(result.audit);\n } catch (error) {\n setUndoError(error instanceof Error ? error.message : String(error));\n }\n }\n\n return (\n <>\n {undoError && (\n <p role=\"alert\" className=\"mb-2 text-xs text-destructive\" data-testid=\"studio-undo-error\">\n {undoError}\n </p>\n )}\n <ol className=\"space-y-2\" data-testid=\"studio-history\">\n {history.data.map((entry) => {\n const fields = [...new Set([...Object.keys(entry.before ?? {}), ...Object.keys(entry.after ?? {})])];\n return (\n <li key={entry.id} className=\"rounded-md border p-2 text-xs\">\n <div className=\"flex flex-wrap items-baseline gap-x-2\">\n <span className=\"font-medium capitalize\">{entry.action === \"run\" ? `Ran ${entry.rowAction ?? \"an action\"}` : entry.action}</span>\n <span className=\"text-muted-foreground\">by {entry.actor ?? \"unknown\"}</span>\n <time className=\"ml-auto text-muted-foreground\">{entry.occurredAt}</time>\n {provider.undo && entry.action !== \"run\" && (\n <button\n type=\"button\"\n className=\"rounded px-1.5 py-0.5 text-[11px] text-muted-foreground hover:bg-muted hover:text-foreground\"\n onClick={() => void undo(entry)}\n title=\"Put this change back. Refused if the row has changed since.\"\n data-testid=\"studio-history-undo\"\n >\n Undo\n </button>\n )}\n </div>\n <div className=\"mt-1 font-mono text-[11px]\">\n {fields.map((field) => (\n <div key={field}>\n {field}: {displayText(entry.before?.[field]) ?? \"—\"} → {displayText(entry.after?.[field]) ?? \"—\"}\n </div>\n ))}\n </div>\n </li>\n );\n })}\n </ol>\n </>\n );\n}\n\nfunction Comments({\n provider,\n sessionKey,\n resource,\n id,\n}: {\n provider: DataProvider;\n sessionKey: unknown;\n resource: string;\n id: string;\n}) {\n const queryClient = useQueryClient();\n const key = [\"genesis-studio\", sessionKey, \"comments\", resource, id];\n const comments = useQuery({ queryKey: key, retry: false, queryFn: () => provider.comments!(resource, { id }) });\n const [draft, setDraft] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function post() {\n if (!draft.trim() || !provider.addComment) return;\n setBusy(true);\n setError(null);\n try {\n await provider.addComment(resource, { id, body: draft });\n setDraft(\"\");\n await queryClient.invalidateQueries({ queryKey: key });\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <div className=\"space-y-3\" data-testid=\"studio-comments\">\n {comments.isLoading ? (\n <p className=\"text-xs text-muted-foreground\">Loading…</p>\n ) : comments.isError ? (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {comments.error instanceof Error ? comments.error.message : String(comments.error)}\n </p>\n ) : !comments.data?.length ? (\n <p className=\"text-xs text-muted-foreground\">No comments yet.</p>\n ) : (\n <ol className=\"space-y-2\">\n {comments.data.map((c) => (\n <li key={c.id} className=\"rounded-md border p-2 text-sm\">\n <div className=\"flex items-baseline gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{c.author}</span>\n <time className=\"ml-auto\">{c.createdAt}</time>\n </div>\n <p className=\"mt-1 whitespace-pre-wrap break-words\">{c.body}</p>\n </li>\n ))}\n </ol>\n )}\n {provider.addComment && (\n <form\n className=\"space-y-2\"\n onSubmit={(e) => {\n e.preventDefault();\n void post();\n }}\n >\n <Textarea\n aria-label=\"New comment\"\n value={draft}\n maxLength={10000}\n onChange={(e) => setDraft(e.target.value)}\n placeholder=\"Add a comment…\"\n rows={3}\n />\n {error && (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n {error}\n </p>\n )}\n <div className=\"flex justify-end\">\n <Button type=\"submit\" size=\"sm\" disabled={busy || !draft.trim()} testID=\"studio-comment-post\">\n {busy ? \"Posting…\" : \"Comment\"}\n </Button>\n </div>\n </form>\n )}\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { ArrowDownUp, Download, EyeOff, Filter, Group, Plus, Search, X } from \"lucide-react\";\nimport type { FilterParam, SortParam } from \"@marktiderman/genesis-core/provider\";\nimport type { FieldSchema, FilterOperator } from \"@marktiderman/genesis-core/schema\";\nimport { Badge } from \"@marktiderman/genesis-ui/badge\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Input } from \"@marktiderman/genesis-ui/input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@marktiderman/genesis-ui/popover\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@marktiderman/genesis-ui/select\";\nimport { needsValue, OPERATOR_LABEL, operatorsFor } from \"../lib/query-state\";\nimport { choicesFor, fieldLabel } from \"../values\";\n\nconst NONE = \"__genesis_none__\";\n\ninterface FilterDraft {\n field: string;\n operator: FilterOperator;\n value: string;\n}\n\nfunction toDraft(f: FilterParam): FilterDraft {\n return { field: f.field, operator: f.operator, value: \"value\" in f && f.value != null ? String(f.value) : \"\" };\n}\n\nfunction fromDraft(d: FilterDraft): FilterParam {\n return needsValue(d.operator)\n ? ({ field: d.field, operator: d.operator, value: d.value } as FilterParam)\n : ({ field: d.field, operator: d.operator } as FilterParam);\n}\n\n/** Filters by field, with the operators that fit each field's type. */\nexport function FilterBuilder({\n fields,\n filters,\n onChange,\n}: {\n fields: readonly FieldSchema[];\n filters: FilterParam[];\n onChange: (filters: FilterParam[]) => void;\n}) {\n const [open, setOpen] = useState(false);\n const [drafts, setDrafts] = useState<FilterDraft[]>(filters.map(toDraft));\n const filterable = fields.filter((f) => !f.array);\n const update = (i: number, patch: Partial<FilterDraft>) =>\n setDrafts((prev) => prev.map((d, j) => (j === i ? { ...d, ...patch } : d)));\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (next) setDrafts(filters.map(toDraft));\n }}\n >\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" testID=\"studio-filter\" className={`px-2 ${filters.length ? \"bg-success/15\" : \"\"}`}>\n <Filter className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n Filter\n {filters.length > 0 && <Badge className=\"ml-1.5 h-4 px-1.5 text-[10px]\">{filters.length}</Badge>}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-[min(36rem,calc(100vw-2rem))] space-y-2\">\n {drafts.length === 0 && <p className=\"text-xs text-muted-foreground\">No filters. Every row you can see is listed.</p>}\n {drafts.map((d, i) => {\n const field = filterable.find((f) => f.name === d.field);\n const operators = field ? operatorsFor(field) : [];\n const choices = field ? choicesFor(field) : undefined;\n return (\n <div key={i} className=\"flex flex-wrap items-center gap-1.5\" data-testid=\"studio-filter-row\">\n <Select value={d.field} onValueChange={(v) => update(i, { field: v, operator: operatorsFor(filterable.find((f) => f.name === v)!)[0]!, value: \"\" })}>\n <SelectTrigger className=\"h-8 w-36 text-xs\" aria-label=\"Field\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {filterable.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select value={d.operator} onValueChange={(v) => update(i, { operator: v as FilterOperator })}>\n <SelectTrigger className=\"h-8 w-40 text-xs\" aria-label=\"Operator\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {operators.map((op) => (\n <SelectItem key={op} value={op}>\n {OPERATOR_LABEL[op]}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {needsValue(d.operator) &&\n (choices ? (\n <Select value={d.value || NONE} onValueChange={(v) => update(i, { value: v === NONE ? \"\" : v })}>\n <SelectTrigger className=\"h-8 w-36 text-xs\" aria-label=\"Value\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>—</SelectItem>\n {choices.map((c) => (\n <SelectItem key={c} value={c}>\n {c}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <Input\n className=\"h-8 w-36 text-xs\"\n aria-label=\"Value\"\n type={field?.widget === \"date\" ? \"date\" : \"text\"}\n value={d.value}\n onChange={(e) => update(i, { value: e.target.value })}\n />\n ))}\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" aria-label=\"Remove filter\" onClick={() => setDrafts((p) => p.filter((_, j) => j !== i))}>\n <X className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n </div>\n );\n })}\n <div className=\"flex justify-between gap-2 pt-1\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={filterable.length === 0}\n onClick={() => {\n const first = filterable[0]!;\n setDrafts((p) => [...p, { field: first.name, operator: operatorsFor(first)[0]!, value: \"\" }]);\n }}\n >\n <Plus className=\"mr-1 h-3.5 w-3.5\" aria-hidden />\n Add filter\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n testID=\"studio-filter-apply\"\n onClick={() => {\n onChange(drafts.filter((d) => !needsValue(d.operator) || d.value !== \"\").map(fromDraft));\n setOpen(false);\n }}\n >\n Apply\n </Button>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\n/** Sort by several fields, first one first. */\nexport function SortBuilder({\n fields,\n sorts,\n onChange,\n}: {\n fields: readonly FieldSchema[];\n sorts: SortParam[];\n onChange: (sorts: SortParam[]) => void;\n}) {\n const sortable = fields.filter((f) => !f.array);\n const unused = sortable.filter((f) => !sorts.some((s) => s.field === f.name));\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" testID=\"studio-sort\" className={`px-2 ${sorts.length ? \"bg-warning/20\" : \"\"}`}>\n <ArrowDownUp className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n Sort\n {sorts.length > 0 && <Badge className=\"ml-1.5 h-4 px-1.5 text-[10px]\">{sorts.length}</Badge>}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-80 space-y-2\">\n {sorts.length === 0 && <p className=\"text-xs text-muted-foreground\">Rows are in key order.</p>}\n {sorts.map((s, i) => (\n <div key={s.field} className=\"flex items-center gap-1.5\" data-testid=\"studio-sort-row\">\n <span className=\"w-5 text-right text-xs text-muted-foreground\">{i + 1}</span>\n <span className=\"flex-1 truncate text-sm\">{s.field}</span>\n <Select value={s.order} onValueChange={(v) => onChange(sorts.map((x, j) => (j === i ? { ...x, order: v as \"asc\" | \"desc\" } : x)))}>\n <SelectTrigger className=\"h-8 w-28 text-xs\" aria-label={`Direction for ${s.field}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"asc\">Ascending</SelectItem>\n <SelectItem value=\"desc\">Descending</SelectItem>\n </SelectContent>\n </Select>\n <Button type=\"button\" variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" aria-label={`Stop sorting by ${s.field}`} onClick={() => onChange(sorts.filter((_, j) => j !== i))}>\n <X className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n </div>\n ))}\n {unused.length > 0 && sorts.length < 5 && (\n <Select value={NONE} onValueChange={(v) => v !== NONE && onChange([...sorts, { field: v, order: \"asc\" }])}>\n <SelectTrigger className=\"h-8 text-xs\" aria-label=\"Add a sort field\">\n <SelectValue placeholder=\"Add a sort field\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE} disabled>\n Add a sort field…\n </SelectItem>\n {unused.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n\n/** Group rows by a field with few distinct values. */\nexport function GroupPicker({\n fields,\n group,\n onChange,\n}: {\n fields: readonly FieldSchema[];\n group: string | undefined;\n onChange: (group: string | undefined) => void;\n}) {\n const groupable = fields.filter((f) => !f.array && f.type !== \"json\");\n return (\n <Select value={group ?? NONE} onValueChange={(v) => onChange(v === NONE ? undefined : v)}>\n <SelectTrigger className={`h-8 w-auto gap-1.5 border-0 text-sm shadow-none hover:bg-muted ${group ? \"bg-info/15\" : \"\"}`} aria-label=\"Group by\" data-testid=\"studio-group\">\n <Group className=\"h-3.5 w-3.5\" aria-hidden />\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>Group</SelectItem>\n {groupable.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n Group by {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\nexport function ExportButton({ onExport, busy, progress }: { onExport: () => void; busy: boolean; progress: number }) {\n return (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onExport} disabled={busy} testID=\"studio-export\" aria-label=\"Export CSV\" title=\"Export CSV\">\n <Download className=\"h-3.5 w-3.5\" aria-hidden />\n {busy && <span className=\"ml-1.5\">{progress}</span>}\n </Button>\n );\n}\n\nexport function NewRowButton({ allowed, reason, onClick }: { allowed: boolean; reason?: string; onClick: () => void }) {\n return (\n <Button type=\"button\" size=\"sm\" onClick={onClick} disabled={!allowed} title={allowed ? undefined : reason} testID=\"studio-new-row\">\n <Plus className=\"mr-1 h-3.5 w-3.5\" aria-hidden />\n Add record\n </Button>\n );\n}\n\nexport type ViewKind = \"table\" | \"sheet\" | \"kanban\" | \"calendar\";\nconst VIEW_LABEL: Record<ViewKind, string> = { table: \"Table\", sheet: \"Sheet\", kanban: \"Board\", calendar: \"Calendar\" };\nconst VIEW_UNAVAILABLE: Partial<Record<ViewKind, string>> = {\n kanban: \"A board needs a field with a fixed set of values, like an enum.\",\n calendar: \"A calendar needs a date or timestamp field.\",\n};\n\n/** Switch between the table, the spreadsheet grid, a board and a calendar. */\nexport function ViewSwitch({\n view,\n onChange,\n available = { table: true, sheet: true },\n}: {\n view: ViewKind;\n onChange: (view: ViewKind) => void;\n /** Views this table can show. A board and a calendar each need a fitting field. */\n available?: Partial<Record<ViewKind, boolean>>;\n}) {\n return (\n <div role=\"group\" aria-label=\"View\" className=\"inline-flex rounded-md border p-0.5\" data-testid=\"studio-view-switch\">\n {([\"table\", \"sheet\", \"kanban\", \"calendar\"] as const)\n .filter((v) => v === \"table\" || v === \"sheet\" || available[v] !== undefined)\n .map((v) => (\n <button\n key={v}\n type=\"button\"\n aria-pressed={view === v}\n disabled={available[v] === false}\n title={available[v] === false ? VIEW_UNAVAILABLE[v] : undefined}\n onClick={() => onChange(v)}\n className={`rounded px-2 py-1 text-xs disabled:opacity-40 ${view === v ? \"bg-accent text-accent-foreground\" : \"text-muted-foreground hover:text-foreground\"}`}\n >\n {VIEW_LABEL[v]}\n </button>\n ))}\n </div>\n );\n}\n\n/** Which field lays out the board or the calendar. */\nexport function ViewFieldPicker({\n label,\n fields,\n value,\n onChange,\n}: {\n label: string;\n fields: readonly FieldSchema[];\n value: string;\n onChange: (field: string) => void;\n}) {\n return (\n <Select value={value} onValueChange={onChange}>\n <SelectTrigger className=\"h-9 w-auto gap-1.5 text-sm\" aria-label={label} data-testid=\"studio-view-field\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {fields.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {label} {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\n/** Which fields the grid shows. */\nexport function HideFields({\n fields,\n hidden,\n onChange,\n}: {\n fields: readonly FieldSchema[];\n hidden: ReadonlySet<string>;\n onChange: (hidden: Set<string>) => void;\n}) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"px-2\" testID=\"studio-hide-fields\">\n <EyeOff className=\"mr-1.5 h-3.5 w-3.5\" aria-hidden />\n {hidden.size ? `${hidden.size} hidden field${hidden.size === 1 ? \"\" : \"s\"}` : \"Hide fields\"}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-64 space-y-1 p-2\">\n {fields.map((f) => (\n <label key={f.name} className=\"flex cursor-pointer items-center gap-2 rounded px-2 py-1 text-sm hover:bg-muted\">\n <input\n type=\"checkbox\"\n className=\"h-3.5 w-3.5\"\n checked={!hidden.has(f.name)}\n onChange={() => {\n const next = new Set(hidden);\n if (next.has(f.name)) next.delete(f.name);\n else next.add(f.name);\n onChange(next);\n }}\n />\n <span className=\"truncate\">{fieldLabel(f)}</span>\n </label>\n ))}\n {hidden.size > 0 && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" className=\"w-full\" onClick={() => onChange(new Set())}>\n Show all\n </Button>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n\n/** Search every text field, as you type. */\nexport function SearchBox({ value, onChange }: { value: string; onChange: (value: string) => void }) {\n return (\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" aria-hidden />\n <Input\n type=\"search\"\n aria-label=\"Search\"\n placeholder=\"Search\"\n className=\"h-8 w-36 pl-7 text-sm\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n data-testid=\"studio-search\"\n />\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@marktiderman/genesis-ui/popover\";\nimport { Bookmark, CalendarDays, ChevronDown, Columns3, Lock, Plus, Search, Table2, X } from \"lucide-react\";\nimport type { SavedViewItem } from \"@marktiderman/genesis-ui/data\";\nimport { cn } from \"@marktiderman/genesis-ui/utils\";\n\nexport type StudioViewKind = \"grid\" | \"kanban\" | \"calendar\";\n\nconst VIEWS: { kind: StudioViewKind; label: string; icon: typeof Table2; unavailable: string }[] = [\n { kind: \"grid\", label: \"Grid\", icon: Table2, unavailable: \"\" },\n { kind: \"kanban\", label: \"Board\", icon: Columns3, unavailable: \"A board needs a field with a fixed set of values, like a status.\" },\n { kind: \"calendar\", label: \"Calendar\", icon: CalendarDays, unavailable: \"A calendar needs a date field.\" },\n];\n\n/** The left column: how to look at this table, and the views you've saved. */\nexport function ViewsPanel({\n view,\n available,\n onChange,\n saved,\n onLoad,\n onDelete,\n onSave,\n}: {\n view: StudioViewKind;\n available: Record<StudioViewKind, boolean>;\n onChange: (view: StudioViewKind) => void;\n saved: SavedViewItem[];\n onLoad: (view: SavedViewItem) => void;\n onDelete: (id: string) => void;\n onSave: (name: string) => void;\n}) {\n const [naming, setNaming] = useState(false);\n const [name, setName] = useState(\"\");\n return (\n <nav\n aria-label=\"Views\"\n className=\"flex shrink-0 flex-row gap-1 overflow-x-auto border-b p-2 text-sm md:w-40 md:flex-col md:overflow-visible md:border-b-0 md:border-r\"\n data-testid=\"studio-views\"\n >\n <p className=\"hidden px-2 pb-1 text-xs text-muted-foreground md:block\">Views</p>\n {VIEWS.map(({ kind, label, icon: Icon, unavailable }) => (\n <button\n key={kind}\n type=\"button\"\n aria-pressed={view === kind}\n disabled={!available[kind]}\n title={available[kind] ? undefined : unavailable}\n onClick={() => onChange(kind)}\n data-testid={`studio-view-${kind}`}\n className={cn(\n \"flex shrink-0 items-center gap-2 rounded-md px-2 py-1.5 text-left disabled:opacity-40\",\n view === kind ? \"bg-accent font-medium text-accent-foreground\" : \"text-muted-foreground hover:bg-muted hover:text-foreground\",\n )}\n >\n <Icon className=\"h-4 w-4\" aria-hidden />\n {label}\n </button>\n ))}\n {saved.length > 0 && <p className=\"hidden px-2 pb-1 pt-3 text-xs text-muted-foreground md:block\">Saved</p>}\n {saved.map((item) => (\n <span key={item.id} className=\"group flex shrink-0 items-center rounded-md hover:bg-muted\">\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 items-center gap-2 px-2 py-1.5 text-left text-muted-foreground hover:text-foreground\"\n onClick={() => onLoad(item)}\n data-testid=\"studio-saved-view\"\n >\n <Bookmark className=\"h-4 w-4 shrink-0\" aria-hidden />\n <span className=\"truncate\">{item.name}</span>\n </button>\n <button\n type=\"button\"\n aria-label={`Delete view ${item.name}`}\n className=\"mr-1 rounded p-0.5 text-muted-foreground opacity-0 hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100\"\n onClick={() => onDelete(item.id)}\n >\n <X className=\"h-3 w-3\" aria-hidden />\n </button>\n </span>\n ))}\n {naming ? (\n <form\n className=\"flex shrink-0 items-center gap-1 px-1 pt-1\"\n onSubmit={(e) => {\n e.preventDefault();\n if (!name.trim()) return;\n onSave(name.trim());\n setName(\"\");\n setNaming(false);\n }}\n >\n <input\n autoFocus\n aria-label=\"View name\"\n placeholder=\"View name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n onKeyDown={(e) => e.key === \"Escape\" && setNaming(false)}\n className=\"h-7 w-full min-w-24 rounded border bg-background px-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </form>\n ) : (\n <button\n type=\"button\"\n className=\"flex shrink-0 items-center gap-2 rounded-md px-2 py-1.5 text-left text-muted-foreground hover:bg-muted hover:text-foreground md:mt-2\"\n onClick={() => setNaming(true)}\n data-testid=\"studio-save-view\"\n >\n <Plus className=\"h-4 w-4\" aria-hidden />\n Save view\n </button>\n )}\n </nav>\n );\n}\n\n/** Table tabs across the top, as Airtable shows a base's tables. */\nexport function TableTabs({\n resources,\n selected,\n onSelect,\n variant = \"card\",\n}: {\n resources: { name: string; label?: string; access: { update: boolean; reason?: string } }[];\n selected?: string;\n onSelect: (resource: string) => void;\n /** `plain` draws underlined tabs on the page instead of a tinted band. */\n variant?: \"card\" | \"plain\";\n}) {\n const picker = resources.length > PICKER_AFTER && <AllTables resources={resources} selected={selected} onSelect={onSelect} />;\n if (variant === \"plain\") {\n return (\n <div className=\"flex items-end border-b\">\n <nav aria-label=\"Tables\" className=\"flex min-w-0 flex-1 gap-1 overflow-x-auto\" data-testid=\"studio-sidebar\">\n {resources.map((r) => {\n const active = r.name === selected;\n return (\n <button\n key={r.name}\n type=\"button\"\n onClick={() => onSelect(r.name)}\n aria-current={active ? \"page\" : undefined}\n title={r.access.update ? r.name : `${r.name}: ${r.access.reason ?? \"read-only\"}`}\n data-testid={`studio-table-${r.name}`}\n className={cn(\n \"-mb-px flex shrink-0 items-center gap-1.5 border-b-2 px-3 py-2 text-sm\",\n active ? \"border-primary font-medium text-foreground\" : \"border-transparent text-muted-foreground hover:text-foreground\",\n )}\n >\n {r.label ?? r.name}\n {!r.access.update && <Lock className=\"h-3 w-3 text-muted-foreground\" aria-label=\"Read-only\" />}\n </button>\n );\n })}\n </nav>\n {picker}\n </div>\n );\n }\n return (\n <div className=\"flex items-end bg-primary/10 pr-2\">\n <nav aria-label=\"Tables\" className=\"flex min-w-0 flex-1 gap-0.5 overflow-x-auto px-2 pt-1.5\" data-testid=\"studio-sidebar\">\n {resources.map((r) => {\n const active = r.name === selected;\n return (\n <button\n key={r.name}\n type=\"button\"\n onClick={() => onSelect(r.name)}\n aria-current={active ? \"page\" : undefined}\n title={r.access.update ? r.name : `${r.name}: ${r.access.reason ?? \"read-only\"}`}\n data-testid={`studio-table-${r.name}`}\n className={cn(\n \"flex shrink-0 items-center gap-1.5 rounded-t-md px-3 py-1.5 text-sm\",\n active ? \"bg-background font-medium text-foreground\" : \"text-foreground/70 hover:bg-background/60 hover:text-foreground\",\n )}\n >\n {r.label ?? r.name}\n {!r.access.update && <Lock className=\"h-3 w-3 text-muted-foreground\" aria-label=\"Read-only\" />}\n </button>\n );\n })}\n </nav>\n {picker}\n </div>\n );\n}\n\n/** Past this many tables, a searchable list sits at the end of the tabs. */\nconst PICKER_AFTER = 8;\n\nfunction AllTables({\n resources,\n selected,\n onSelect,\n}: {\n resources: { name: string; label?: string; access: { update: boolean } }[];\n selected?: string;\n onSelect: (resource: string) => void;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const q = query.trim().toLowerCase();\n const shown = resources.filter((r) => !q || (r.label ?? r.name).toLowerCase().includes(q) || r.name.toLowerCase().includes(q));\n return (\n <Popover open={open} onOpenChange={(next) => { setOpen(next); if (!next) setQuery(\"\"); }}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"mb-1 ml-1 flex shrink-0 items-center gap-1 rounded-md px-2 py-1 text-sm text-muted-foreground hover:bg-muted hover:text-foreground\"\n data-testid=\"studio-all-tables\"\n >\n All tables ({resources.length})\n <ChevronDown className=\"h-3.5 w-3.5\" aria-hidden />\n </button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-72 p-1\">\n <div className=\"relative p-1\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" aria-hidden />\n <input\n autoFocus\n aria-label=\"Find a table\"\n placeholder=\"Find a table\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && shown[0]) {\n onSelect(shown[0].name);\n setOpen(false);\n }\n }}\n className=\"h-8 w-full rounded border bg-background pl-7 pr-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </div>\n <ul className=\"max-h-72 overflow-y-auto\" aria-label=\"Tables\">\n {shown.map((r) => (\n <li key={r.name}>\n <button\n type=\"button\"\n aria-current={r.name === selected ? \"page\" : undefined}\n className={cn(\n \"flex w-full items-center justify-between gap-2 rounded px-2 py-1.5 text-left text-sm hover:bg-muted\",\n r.name === selected && \"bg-accent text-accent-foreground\",\n )}\n onClick={() => {\n onSelect(r.name);\n setOpen(false);\n }}\n >\n <span className=\"truncate\">{r.label ?? r.name}</span>\n {!r.access.update && <Lock className=\"h-3 w-3 shrink-0 text-muted-foreground\" aria-label=\"Read-only\" />}\n </button>\n </li>\n ))}\n {shown.length === 0 && <li className=\"px-2 py-1.5 text-sm text-muted-foreground\">No table matches.</li>}\n </ul>\n </PopoverContent>\n </Popover>\n );\n}\n\n\n","// How a value looks in the grid: choices as colored pills, yes/no as a\n// check, links as chips, numbers right-aligned. Editing and copying always\n// use the plain text (`editText`), so what you see never changes what you save.\n\nimport type { ReactNode } from \"react\";\nimport {\n Braces,\n Calendar,\n Check,\n CircleChevronDown,\n Clock,\n Hash,\n KeyRound,\n Link2,\n List,\n SquareCheck,\n Type,\n} from \"lucide-react\";\nimport type { FieldSchema } from \"@marktiderman/genesis-core/schema\";\nimport { cn } from \"@marktiderman/genesis-ui/utils\";\nimport { displayText } from \"../values\";\n\n/** An icon for the field's type, as Airtable shows in each column header. */\nexport function FieldIcon({ field, isKey }: { field: FieldSchema; isKey?: boolean }) {\n const className = \"h-3.5 w-3.5\";\n if (isKey) return <KeyRound className={className} />;\n if (field.array) return <List className={className} />;\n if (field.references) return <Link2 className={className} />;\n if (field.enumValues) return <CircleChevronDown className={className} />;\n switch (field.type) {\n case \"number\":\n return <Hash className={className} />;\n case \"boolean\":\n return <SquareCheck className={className} />;\n case \"json\":\n return <Braces className={className} />;\n case \"datetime\":\n return field.dbType === \"date\" || field.widget === \"date\" ? <Calendar className={className} /> : <Clock className={className} />;\n default:\n return <Type className={className} />;\n }\n}\n\n/** Tints from the design system's palette, one per choice. */\nconst PILL_TINTS = [\n \"bg-info/20\",\n \"bg-chart-2/25\",\n \"bg-chart-4/30\",\n \"bg-chart-1/20\",\n \"bg-chart-5/25\",\n \"bg-chart-3/20\",\n \"bg-primary/15\",\n];\nconst POSITIVE = /^(active|paid|done|shipped|published|complete(d)?|approved|open|live|yes|true)$/i;\nconst PENDING = /^(draft|pending|paused|review|in[ _-]?progress|waiting|scheduled|new)$/i;\nconst NEGATIVE = /^(archived|cancel(l)?ed|closed|rejected|failed|deleted|inactive|no|false)$/i;\n\n/** A choice's tint: status-like words get their meaning's color, others a stable one by position. */\nexport function pillTint(value: string, choices: readonly string[] = []): string {\n if (POSITIVE.test(value)) return \"bg-success/20\";\n if (PENDING.test(value)) return \"bg-warning/25\";\n if (NEGATIVE.test(value)) return \"bg-muted\";\n const at = choices.indexOf(value);\n const index = at >= 0 ? at : [...value].reduce((h, ch) => (h * 31 + ch.charCodeAt(0)) >>> 0, 7);\n return PILL_TINTS[index % PILL_TINTS.length]!;\n}\n\nexport function Pill({ value, tint, className }: { value: string; tint: string; className?: string }) {\n return (\n <span className={cn(\"inline-flex max-w-full items-center truncate rounded-full px-2 py-0.5 text-xs text-foreground\", tint, className)}>\n {value}\n </span>\n );\n}\n\n/** A Postgres timestamp, shortened to the minute for the grid. The full value is still what's edited. */\nfunction shortTimestamp(text: string): string {\n const m = /^(\\d{4}-\\d{2}-\\d{2})[ T](\\d{2}:\\d{2})/.exec(text);\n return m ? `${m[1]} ${m[2]}` : text;\n}\n\n/** The cell's display. `linkLabel` is the linked row's name, when one is known. */\nexport function CellValue({ field, value, linkLabel }: { field: FieldSchema; value: unknown; linkLabel?: string }): ReactNode {\n const text = displayText(value);\n if (text === null || text === \"\") return null;\n if (field.type === \"boolean\" && !field.array) {\n return value === true || text === \"true\" ? (\n <span className=\"inline-flex h-4 w-4 items-center justify-center rounded bg-success/20\" aria-label=\"Yes\">\n <Check className=\"h-3 w-3\" aria-hidden />\n </span>\n ) : (\n <span className=\"inline-block h-4 w-4 rounded border\" aria-label=\"No\" />\n );\n }\n if (field.enumValues && !field.array) return <Pill value={text} tint={pillTint(text, field.enumValues)} />;\n if (field.references) {\n return (\n <span className=\"inline-flex max-w-full items-center gap-1 truncate rounded bg-info/15 px-1.5 py-0.5 text-xs text-foreground\" title={text}>\n {linkLabel ?? text}\n </span>\n );\n }\n if (field.array && Array.isArray(value)) {\n return (\n <span className=\"flex gap-1 overflow-hidden\">\n {value.map((item, i) => (\n <Pill key={i} value={displayText(item) ?? \"\"} tint=\"bg-muted\" />\n ))}\n </span>\n );\n }\n if (field.type === \"datetime\" && !(field.dbType === \"date\" || field.widget === \"date\")) {\n return <span title={text}>{shortTimestamp(text)}</span>;\n }\n if (field.type === \"json\") return <span className=\"font-mono text-xs\">{text}</span>;\n return <>{text}</>;\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useQueries } from \"@tanstack/react-query\";\nimport type { BaseRecord, DataProvider, FilterParam, SortParam } from \"@marktiderman/genesis-core/provider\";\nimport { encodeRecordKey, isDataWriteError, type AuditEntry, type FieldSchema, type ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { KanbanBoard, type KanbanColumn } from \"@marktiderman/genesis-ui/data\";\nimport { choicesFor, displayText, fieldLabel } from \"../values\";\n\ntype Row = Record<string, unknown>;\n\n/** Cards per column page. */\nexport const KANBAN_PAGE = 50;\nconst NONE = \"__genesis_none__\";\n\nexport interface KanbanViewProps {\n provider: DataProvider;\n schema: ResourceSchema;\n sessionKey: string | number | null;\n /** The field whose value is each card's column. */\n field: FieldSchema;\n filters: FilterParam[];\n sorts: SortParam[];\n search: string;\n onOpenRecord: (id: string) => void;\n onMoved: (record: string, audit?: AuditEntry) => void;\n onFailed: (record: string, message: string) => void;\n onSignedOut: () => void;\n}\n\nfunction versionOf(schema: ResourceSchema, row: Row): string | null {\n const field = schema.version?.field;\n return field && row[field] != null ? String(row[field]) : null;\n}\n\n/**\n * A board of the table's rows, one column per value of `field`. Each column\n * is paged on its own (50 cards, then \"Load more\"), with the same filters,\n * search and sort as the table. Moving a card is a version-checked update of\n * `field`, so a card someone else just changed is refused, not overwritten.\n */\nexport function KanbanView({\n provider,\n schema,\n sessionKey,\n field,\n filters,\n sorts,\n search,\n onOpenRecord,\n onMoved,\n onFailed,\n onSignedOut,\n}: KanbanViewProps) {\n const values = useMemo(() => [...(choicesFor(field) ?? []), ...(field.nullable ? [NONE] : [])], [field]);\n const [pages, setPages] = useState<Record<string, number>>({});\n const [moving, setMoving] = useState<string | null>(null);\n const filterKey = JSON.stringify(filters);\n const sortKey = JSON.stringify(sorts);\n\n const specs = values.flatMap((value) =>\n Array.from({ length: pages[value] ?? 1 }, (_, i) => ({ value, page: i + 1 })),\n );\n const results = useQueries({\n queries: specs.map(({ value, page }) => ({\n queryKey: [\"genesis-studio\", sessionKey, \"list\", schema.name, \"kanban\", field.name, value, page, filterKey, search, sortKey],\n retry: false,\n queryFn: () =>\n provider.getList<BaseRecord>(schema.name, {\n pagination: { page, perPage: KANBAN_PAGE },\n sort: sorts[0],\n sorts,\n filters: [\n ...filters.filter((f) => f.field !== field.name),\n value === NONE\n ? ({ field: field.name, operator: \"is_null\" } as FilterParam)\n : ({ field: field.name, operator: \"eq\", value } as FilterParam),\n ],\n search: search ? { query: search, fields: [] } : undefined,\n }),\n })),\n });\n\n const failure = results.find((r) => r.error)?.error;\n const signedOut = Boolean(failure && isDataWriteError(failure) && failure.outcome === \"unauthenticated\");\n useEffect(() => {\n if (signedOut) onSignedOut();\n }, [signedOut, onSignedOut]);\n // A filter on the board's own field is replaced by each column's value.\n const ownFilter = filters.some((f) => f.field === field.name);\n\n const columns: KanbanColumn<Row>[] = values.map((value) => {\n const mine = specs.map((s, i) => ({ s, r: results[i]! })).filter(({ s }) => s.value === value);\n return {\n key: value,\n label: value === NONE ? \"No value\" : value,\n items: mine.flatMap(({ r }) => (r.data?.data ?? []) as Row[]),\n ...(mine[0]?.r.data ? { total: mine[0].r.data.total } : {}),\n };\n });\n\n const labelField = schema.labelField;\n // A card's subtitle: the next two fields a person would read, not keys,\n // links, ids or the version.\n const keyNames = new Set(typeof schema.key === \"string\" ? [schema.key] : schema.key);\n const extra = schema.fields\n .filter(\n (f) =>\n f.name !== labelField &&\n f.name !== field.name &&\n f.name !== schema.version?.field &&\n !keyNames.has(f.name) &&\n !f.references &&\n !f.array &&\n f.type !== \"json\" &&\n f.dbType !== \"uuid\",\n )\n .slice(0, 2);\n const canMove = Boolean(field.permissions?.update && schema.version);\n\n async function move(row: Row, to: string) {\n const id = String(encodeRecordKey(schema, row));\n setMoving(id);\n try {\n const result = await provider.update<BaseRecord>(schema.name, {\n id,\n data: { [field.name]: to === NONE ? null : to },\n expectedVersion: versionOf(schema, row),\n });\n onMoved(id, result.audit);\n } catch (error) {\n if (isDataWriteError(error) && error.outcome === \"unauthenticated\") onSignedOut();\n onFailed(id, error instanceof Error ? error.message : String(error));\n throw error;\n } finally {\n setMoving(null);\n }\n }\n\n return (\n <div className=\"space-y-2\" data-testid=\"studio-kanban\">\n {ownFilter && (\n <p className=\"text-xs text-muted-foreground\">Your filter on {field.name} is set aside here: each column shows one of its values.</p>\n )}\n {failure && !signedOut && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {failure instanceof Error ? failure.message : String(failure)}\n </p>\n )}\n <div>\n <KanbanBoard<Row>\n className=\"grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] md:grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] lg:grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] xl:grid-cols-[repeat(auto-fill,minmax(15rem,1fr))]\"\n columns={columns}\n getKey={(row) => String(encodeRecordKey(schema, row))}\n getItemLabel={(row) => displayText(labelField ? row[labelField] : undefined) ?? String(encodeRecordKey(schema, row))}\n onMoveItem={canMove ? move : undefined}\n emptyMessage=\"No rows\"\n renderCard={(row) => {\n const id = String(encodeRecordKey(schema, row));\n return (\n <button\n type=\"button\"\n onClick={() => onOpenRecord(id)}\n aria-busy={moving === id || undefined}\n className=\"w-full rounded-lg border bg-card p-3 pr-8 text-left text-sm shadow-sm hover:border-primary/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n data-testid=\"studio-kanban-card\"\n >\n <span className=\"block truncate font-medium\">{displayText(labelField ? row[labelField] : undefined) ?? id}</span>\n {extra.map((f) => (\n <span key={f.name} className=\"block truncate text-xs text-muted-foreground\">\n {fieldLabel(f)}: {displayText(row[f.name]) ?? \"—\"}\n </span>\n ))}\n </button>\n );\n }}\n renderColumnFooter={(column) =>\n column.total !== undefined && column.total > column.items.length ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setPages((p) => ({ ...p, [column.key]: (p[column.key] ?? 1) + 1 }))}\n >\n Load more ({(column.total - column.items.length).toLocaleString()} left)\n </Button>\n ) : null\n }\n />\n </div>\n {!canMove && (\n <p className=\"text-xs text-muted-foreground\">\n {field.permissions?.reason ?? `Cards can't be moved: ${field.name} can't be edited here.`}\n </p>\n )}\n </div>\n );\n}\n","import { useEffect, useMemo } from \"react\";\nimport { keepPreviousData, useQuery } from \"@tanstack/react-query\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport type { BaseRecord, DataProvider, FilterParam, SortParam } from \"@marktiderman/genesis-core/provider\";\nimport { encodeRecordKey, isDataWriteError, type FieldSchema, type ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { cn } from \"@marktiderman/genesis-ui/utils\";\nimport { displayText, fieldLabel } from \"../values\";\nimport { currentMonth, dayKey, isDateOnly, localDay, monthBounds, shiftMonth } from \"./fields\";\n\ntype Row = Record<string, unknown>;\n\n/** Most rows one month shows. Past this, the view says so and asks for a filter. */\nexport const CALENDAR_CAP = 200;\nconst WEEKDAYS = [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"];\n\nexport interface CalendarViewProps {\n provider: DataProvider;\n schema: ResourceSchema;\n sessionKey: string | number | null;\n /** The date or timestamp field that places each row. */\n field: FieldSchema;\n /** `YYYY-MM`; this month when absent. */\n month: string | undefined;\n onMonthChange: (month: string) => void;\n filters: FilterParam[];\n sorts: SortParam[];\n search: string;\n onOpenRecord: (id: string) => void;\n onSignedOut: () => void;\n}\n\n/** The weeks of a month, Monday first, each day as `YYYY-MM-DD` or null outside the month. */\nfunction weeksOf(month: string): (string | null)[][] {\n const [y, m] = month.split(\"-\").map(Number) as [number, number];\n const first = new Date(y, m - 1, 1);\n const days = new Date(y, m, 0).getDate();\n const lead = (first.getDay() + 6) % 7;\n const cells: (string | null)[] = [\n ...Array.from({ length: lead }, () => null),\n ...Array.from({ length: days }, (_, i) => dayKey(new Date(y, m - 1, i + 1))),\n ];\n while (cells.length % 7) cells.push(null);\n return Array.from({ length: cells.length / 7 }, (_, w) => cells.slice(w * 7, w * 7 + 7));\n}\n\n/**\n * A month of the table's rows, placed by a date field. One request per\n * month (a `gte`/`lt` range on the field, with the table's filters, search\n * and sort), up to 200 rows. A timestamp shows on the day it falls in the\n * viewer's time zone.\n */\nexport function CalendarView({\n provider,\n schema,\n sessionKey,\n field,\n month: monthProp,\n onMonthChange,\n filters,\n sorts,\n search,\n onOpenRecord,\n onSignedOut,\n}: CalendarViewProps) {\n const month = monthProp ?? currentMonth();\n const dateOnly = isDateOnly(field);\n const { from, to } = monthBounds(month, field);\n const query = useQuery({\n queryKey: [\"genesis-studio\", sessionKey, \"list\", schema.name, \"calendar\", field.name, month, JSON.stringify(filters), search, JSON.stringify(sorts)],\n placeholderData: keepPreviousData,\n retry: false,\n queryFn: () =>\n provider.getList<BaseRecord>(schema.name, {\n pagination: { page: 1, perPage: CALENDAR_CAP },\n sort: sorts[0] ?? { field: field.name, order: \"asc\" },\n sorts: sorts.length ? sorts : [{ field: field.name, order: \"asc\" }],\n filters: [\n ...filters,\n { field: field.name, operator: \"gte\", value: from } as FilterParam,\n { field: field.name, operator: \"lt\", value: to } as FilterParam,\n ],\n search: search ? { query: search, fields: [] } : undefined,\n }),\n });\n const signedOut = isDataWriteError(query.error) && query.error.outcome === \"unauthenticated\";\n useEffect(() => {\n if (signedOut) onSignedOut();\n }, [signedOut, onSignedOut]);\n\n const rows = (query.data?.data ?? []) as Row[];\n const byDay = useMemo(() => {\n const map = new Map<string, Row[]>();\n for (const row of rows) {\n const day = localDay(row[field.name], dateOnly);\n if (!day) continue;\n map.set(day, [...(map.get(day) ?? []), row]);\n }\n return map;\n }, [rows, field.name, dateOnly]);\n const total = query.data?.total ?? 0;\n const today = dayKey(new Date());\n const title = new Date(`${month}-01T00:00:00`).toLocaleDateString(undefined, { month: \"long\", year: \"numeric\" });\n const labelField = schema.labelField;\n\n return (\n <div className=\"space-y-2\" data-testid=\"studio-calendar\">\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"icon\" className=\"h-8 w-8\" aria-label=\"Previous month\" onClick={() => onMonthChange(shiftMonth(month, -1))}>\n <ChevronLeft className=\"h-4 w-4\" aria-hidden />\n </Button>\n <Button type=\"button\" variant=\"outline\" size=\"icon\" className=\"h-8 w-8\" aria-label=\"Next month\" onClick={() => onMonthChange(shiftMonth(month, 1))}>\n <ChevronRight className=\"h-4 w-4\" aria-hidden />\n </Button>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => onMonthChange(currentMonth())}>\n Today\n </Button>\n <h3 className=\"text-sm font-semibold\" aria-live=\"polite\">\n {title}\n </h3>\n <span className=\"text-xs text-muted-foreground\">by {fieldLabel(field)}</span>\n </div>\n {total > rows.length && (\n <p role=\"status\" className=\"text-xs text-muted-foreground\" data-testid=\"studio-calendar-capped\">\n Showing the first {rows.length.toLocaleString()} of {total.toLocaleString()} rows this month. Filter the table to see the rest.\n </p>\n )}\n {query.isError && !signedOut && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {query.error instanceof Error ? query.error.message : String(query.error)}\n </p>\n )}\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[42rem] table-fixed border-collapse text-sm\">\n <caption className=\"sr-only\">\n {schema.label ?? schema.name} by {fieldLabel(field)}, {title}\n </caption>\n <thead>\n <tr>\n {WEEKDAYS.map((d) => (\n <th key={d} scope=\"col\" className=\"py-1 text-left text-xs font-medium text-muted-foreground\">\n {d}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {weeksOf(month).map((week, w) => (\n <tr key={w}>\n {week.map((day, d) => (\n <td\n key={day ?? `pad-${w}-${d}`}\n className={cn(\"h-28 border align-top\", !day && \"bg-muted/30\")}\n data-day={day ?? undefined}\n >\n {day && (\n <div className=\"flex h-full flex-col gap-0.5 p-1\">\n <span className={cn(\"text-xs\", day === today ? \"font-bold text-primary\" : \"text-muted-foreground\")}>\n {Number(day.slice(8))}\n </span>\n <ul className=\"max-h-24 space-y-0.5 overflow-y-auto\">\n {(byDay.get(day) ?? []).map((row) => {\n const id = String(encodeRecordKey(schema, row));\n return (\n <li key={id}>\n <button\n type=\"button\"\n className=\"w-full truncate rounded bg-primary/10 px-1.5 py-0.5 text-left text-xs hover:bg-primary/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n onClick={() => onOpenRecord(id)}\n data-testid=\"studio-calendar-item\"\n >\n {displayText(labelField ? row[labelField] : undefined) ?? id}\n </button>\n </li>\n );\n })}\n </ul>\n </div>\n )}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n","// Which fields can lay out a board or a calendar, and reading the dates the\n// handler sends (Postgres text, e.g. `2026-10-19 09:30:00.123456+00`).\n\nimport type { FieldSchema, ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { choicesFor } from \"../values\";\n\n/** Fields with a fixed set of values: an enum, or a yes/no. */\nexport function boardFields(schema: ResourceSchema): FieldSchema[] {\n return schema.fields.filter((f) => !f.array && Boolean(choicesFor(f)));\n}\n\n/** Date and timestamp fields. */\nexport function dateFields(schema: ResourceSchema): FieldSchema[] {\n return schema.fields.filter((f) => !f.array && f.type === \"datetime\" && !/^time( |$)|interval/.test(f.dbType ?? \"\"));\n}\n\n/** True for a `date` column: no time, no zone. */\nexport function isDateOnly(field: FieldSchema): boolean {\n return field.dbType === \"date\" || field.widget === \"date\";\n}\n\nconst DB_DATE = /^(\\d{4}-\\d{2}-\\d{2})(?:[ T](\\d{2}:\\d{2}(?::\\d{2})?)(\\.\\d+)?)?\\s*(Z|[+-]\\d{2}(?::?\\d{2})?)?$/;\n\n/**\n * The local calendar day (`YYYY-MM-DD`) a stored value falls on, or null.\n * A `date` is that day wherever you are; a timestamp is placed on the day it\n * is in the viewer's time zone.\n */\nexport function localDay(value: unknown, dateOnly: boolean): string | null {\n if (typeof value !== \"string\") return null;\n const m = DB_DATE.exec(value.trim());\n if (!m) return null;\n if (dateOnly || !m[2]) return m[1]!;\n let zone = m[4] ?? \"\";\n if (/^[+-]\\d{2}$/.test(zone)) zone += \":00\";\n else if (/^[+-]\\d{4}$/.test(zone)) zone = `${zone.slice(0, 3)}:${zone.slice(3)}`;\n const time = m[2].length === 5 ? `${m[2]}:00` : m[2];\n const ms = m[3] ? m[3].slice(0, 4).padEnd(4, \"0\") : \"\";\n const date = new Date(`${m[1]}T${time}${ms}${zone}`);\n if (Number.isNaN(date.getTime())) return null;\n return dayKey(date);\n}\n\nexport function dayKey(date: Date): string {\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n}\n\n/** True for a timestamp that names an instant (`timestamptz`), not a wall-clock time. */\nexport function isZoned(field: FieldSchema): boolean {\n return !isDateOnly(field) && (field.dbType === undefined || /with time zone|timestamptz/.test(field.dbType));\n}\n\n/**\n * The bounds of a month, as filter values for this field: `[start, nextStart)`.\n * An instant is bounded by the viewer's midnights; a date or wall-clock\n * timestamp by the calendar days themselves.\n */\nexport function monthBounds(month: string, field: FieldSchema): { from: string; to: string } {\n const [y, m] = month.split(\"-\").map(Number) as [number, number];\n const start = new Date(y, m - 1, 1);\n const next = new Date(y, m, 1);\n return isZoned(field)\n ? { from: start.toISOString(), to: next.toISOString() }\n : { from: dayKey(start), to: dayKey(next) };\n}\n\nexport function currentMonth(now = new Date()): string {\n return dayKey(now).slice(0, 7);\n}\n\nexport function shiftMonth(month: string, by: number): string {\n const [y, m] = month.split(\"-\").map(Number) as [number, number];\n return currentMonth(new Date(y, m - 1 + by, 1));\n}\n","import { useMemo, useState } from \"react\";\nimport { Upload } from \"lucide-react\";\nimport type { BulkResult, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport type { ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"@marktiderman/genesis-ui/dialog\";\nimport { Label } from \"@marktiderman/genesis-ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@marktiderman/genesis-ui/select\";\nimport { parseCsv } from \"../lib/csv\";\nimport { fieldLabel } from \"../values\";\n\nconst SKIP = \"__genesis_skip__\";\n\nexport interface ImportDialogProps {\n provider: DataProvider;\n schema: ResourceSchema;\n onImported: (count: number) => void;\n}\n\n/**\n * CSV import (DATA-STUDIO.md P2): map the file's columns to fields, check\n * every row against the database with a dry run, then add them all in one\n * transaction. Nothing is coerced or dropped: a value that won't convert is\n * listed, with the database's reason, before anything is kept.\n */\nexport function ImportDialog({ provider, schema, onImported }: ImportDialogProps) {\n const [open, setOpen] = useState(false);\n const [file, setFile] = useState<{ name: string; header: string[]; rows: string[][] } | null>(null);\n const [mapping, setMapping] = useState<Record<number, string>>({});\n const [check, setCheck] = useState<BulkResult | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const targets = useMemo(() => schema.fields.filter((f) => schema.createFields?.includes(f.name)), [schema]);\n const allowed = Boolean(schema.access.create && provider.importRows);\n\n async function readFile(input: File) {\n const parsed = parseCsv(await input.text());\n setFile({ name: input.name, ...parsed });\n // Match columns to fields by name, case-insensitively.\n const auto: Record<number, string> = {};\n parsed.header.forEach((h, i) => {\n const field = targets.find((f) => f.name.toLowerCase() === h.toLowerCase());\n if (field) auto[i] = field.name;\n });\n setMapping(auto);\n setCheck(null);\n setError(null);\n }\n\n function rowsToSend() {\n if (!file) return [];\n return file.rows.map((cells) => {\n const row: Record<string, unknown> = {};\n for (const [index, field] of Object.entries(mapping)) {\n if (field === SKIP) continue;\n const value = cells[Number(index)] ?? \"\";\n // An empty cell leaves the field to its default (or null).\n if (value !== \"\") row[field] = value;\n }\n return row;\n });\n }\n\n async function run(dryRun: boolean) {\n setBusy(true);\n setError(null);\n try {\n const result = await provider.importRows!(schema.name, { rows: rowsToSend(), dryRun });\n if (dryRun) setCheck(result);\n else if (result.ok) {\n onImported(result.count);\n setOpen(false);\n setFile(null);\n setCheck(null);\n } else setCheck(result);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(false);\n }\n }\n\n const mapped = Object.values(mapping).filter((f) => f && f !== SKIP).length;\n\n return (\n <>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setOpen(true)}\n disabled={!allowed}\n title={allowed ? \"Import CSV\" : schema.access.reasons?.create ?? \"This data provider can't import.\"}\n testID=\"studio-import\"\n aria-label=\"Import CSV\"\n >\n <Upload className=\"h-3.5 w-3.5\" aria-hidden />\n </Button>\n <Dialog open={open} onOpenChange={setOpen}>\n <DialogContent className=\"max-h-[85vh] overflow-y-auto sm:max-w-2xl\" data-testid=\"studio-import-dialog\">\n <DialogHeader>\n <DialogTitle>Import into {schema.label ?? schema.name}</DialogTitle>\n <DialogDescription>\n Every row is checked against the database first. The import then adds all of them in one transaction, or none.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"studio-import-file\">CSV file, with a header row</Label>\n <input\n id=\"studio-import-file\"\n type=\"file\"\n accept=\".csv,text/csv\"\n className=\"block w-full text-sm\"\n onChange={(e) => e.target.files?.[0] && void readFile(e.target.files[0])}\n data-testid=\"studio-import-file\"\n />\n </div>\n {file && (\n <>\n <p className=\"text-xs text-muted-foreground\">\n {file.name}: {file.rows.length} rows, {file.header.length} columns.\n </p>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {file.header.map((column, i) => (\n <div key={`${column}-${i}`} className=\"flex items-center gap-2\">\n <span className=\"w-32 truncate font-mono text-xs\" title={column}>\n {column || `(column ${i + 1})`}\n </span>\n <Select value={mapping[i] ?? SKIP} onValueChange={(v) => {\n setMapping((m) => ({ ...m, [i]: v }));\n // A new mapping hasn't been checked: run the dry run again before importing.\n setCheck(null);\n }}>\n <SelectTrigger className=\"h-8 flex-1 text-xs\" aria-label={`Field for ${column}`}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={SKIP}>Skip this column</SelectItem>\n {targets.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ))}\n </div>\n {check && (\n <div className=\"rounded-md border p-3 text-sm\" role=\"status\" data-testid=\"studio-import-check\">\n {check.ok ? (\n <p>All {check.count} rows are ready to import.</p>\n ) : (\n <>\n <p className=\"font-medium text-destructive\">\n {(check.failures ?? []).length} of {file.rows.length} rows won't import. Nothing was changed.\n </p>\n <ul className=\"mt-2 max-h-48 space-y-1 overflow-y-auto font-mono text-xs\">\n {(check.failures ?? []).map((f) => (\n <li key={f.index}>\n Row {f.index + 2}: {f.message}\n </li>\n ))}\n </ul>\n </>\n )}\n </div>\n )}\n {error && (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {error}\n </p>\n )}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"outline\" disabled={busy || mapped === 0} onClick={() => void run(true)} testID=\"studio-import-check-button\">\n {busy ? \"Checking…\" : \"Check rows\"}\n </Button>\n <Button type=\"button\" disabled={busy || !check?.ok} onClick={() => void run(false)} testID=\"studio-import-commit\">\n Import {check?.ok ? check.count : \"\"} rows\n </Button>\n </div>\n </>\n )}\n </div>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","import { useState } from \"react\";\nimport type { BulkResult } from \"@marktiderman/genesis-core/provider\";\nimport type { ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { Button } from \"@marktiderman/genesis-ui/button\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"@marktiderman/genesis-ui/dialog\";\nimport { Input } from \"@marktiderman/genesis-ui/input\";\nimport { Label } from \"@marktiderman/genesis-ui/label\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@marktiderman/genesis-ui/select\";\nimport { choicesFor, parseDraft, fieldLabel } from \"../values\";\n\nexport interface BulkEditDialogProps {\n schema: ResourceSchema;\n count: number;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Apply `data` to every selected row, in one transaction. */\n onApply: (data: Record<string, unknown>) => Promise<BulkResult>;\n}\n\n/** Set one field on every selected row: all of them change, or none do. */\nexport function BulkEditDialog({ schema, count, open, onOpenChange, onApply }: BulkEditDialogProps) {\n const fields = schema.fields.filter((f) => f.permissions?.update && !f.references);\n const [field, setField] = useState(fields[0]?.name ?? \"\");\n const [value, setValue] = useState(\"\");\n const [result, setResult] = useState<BulkResult | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const target = fields.find((f) => f.name === field);\n const choices = target ? choicesFor(target) : undefined;\n\n async function apply() {\n if (!target) return;\n setBusy(true);\n setError(null);\n try {\n const outcome = await onApply({ [target.name]: parseDraft(target, value) });\n if (outcome.ok) onOpenChange(false);\n else setResult(outcome);\n } catch (e) {\n setError(`Nothing was changed: ${e instanceof Error ? e.message : String(e)}`);\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n onOpenChange(next);\n if (!next) setResult(null);\n }}\n >\n <DialogContent className=\"sm:max-w-md\" data-testid=\"studio-bulk-edit\">\n <DialogHeader>\n <DialogTitle>\n Set a field on {count} row{count === 1 ? \"\" : \"s\"}\n </DialogTitle>\n <DialogDescription>Each row is checked against the version you see. All of them change, or none do.</DialogDescription>\n </DialogHeader>\n <div className=\"space-y-3\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"studio-bulk-field\">Field</Label>\n <Select value={field} onValueChange={(v) => { setField(v); setValue(\"\"); setError(null); }}>\n <SelectTrigger id=\"studio-bulk-field\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {fields.map((f) => (\n <SelectItem key={f.name} value={f.name}>\n {fieldLabel(f)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"studio-bulk-value\">New value</Label>\n {choices ? (\n <Select value={value} onValueChange={(v) => { setValue(v); setError(null); }}>\n <SelectTrigger id=\"studio-bulk-value\">\n <SelectValue placeholder=\"Choose…\" />\n </SelectTrigger>\n <SelectContent>\n {choices.map((c) => (\n <SelectItem key={c} value={c}>\n {c}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : (\n <Input id=\"studio-bulk-value\" value={value} onChange={(e) => { setValue(e.target.value); setError(null); }} />\n )}\n </div>\n {error && (\n <p role=\"alert\" className=\"rounded-md border border-destructive/40 p-2 text-sm text-destructive\" data-testid=\"studio-bulk-error\">\n {error}\n </p>\n )}\n {result && !result.ok && (\n <div role=\"alert\" className=\"rounded-md border border-destructive/40 p-2 text-sm text-destructive\">\n Nothing was changed: {(result.failures ?? []).length} row(s) failed.\n <ul className=\"mt-1 list-disc pl-5 text-xs\">\n {(result.failures ?? []).slice(0, 10).map((f) => (\n <li key={f.index}>{f.message}</li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)}>\n Cancel\n </Button>\n <Button type=\"button\" disabled={busy || !target} onClick={() => void apply()} testID=\"studio-bulk-apply\">\n {busy ? \"Saving…\" : `Set on ${count} row${count === 1 ? \"\" : \"s\"}`}\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n","import { useMemo, type ReactNode } from \"react\";\nimport { Maximize2 } from \"lucide-react\";\nimport type { BaseRecord, DataProvider } from \"@marktiderman/genesis-core/provider\";\nimport { encodeRecordKey, isDataWriteError, keyFields, type AuditEntry, type ResourceSchema } from \"@marktiderman/genesis-core/schema\";\nimport { SheetCommitError, SheetGrid, type SheetCellChange, type SheetGridColumn } from \"@marktiderman/genesis-ui/sheet-grid\";\nimport { choicesFor, editText, fieldLabel, parseDraft } from \"../values\";\nimport { CellValue, FieldIcon } from \"../grid/cells\";\n\ntype Row = Record<string, unknown>;\n\n/** Fields in grid order: the field that names a row first, as Airtable's primary field, then the table's order. */\nexport function gridFields(schema: ResourceSchema) {\n const primary = schema.fields.find((f) => f.name === schema.labelField);\n return primary ? [primary, ...schema.fields.filter((f) => f !== primary)] : [...schema.fields];\n}\n\nexport interface SheetViewProps {\n provider: DataProvider;\n schema: ResourceSchema;\n rows: Row[];\n keys: Map<Row, string>;\n linkLabels: Map<string, Map<string, string>>;\n /** Saved rows, to put back in the list. */\n onSaved: (updates: { old: Row; next: Row; audit?: AuditEntry }[]) => void;\n onFailed: (message: string) => void;\n onUndo: () => void;\n onNotice: (message: string) => void;\n /** Fields not shown. */\n hidden?: ReadonlySet<string>;\n /** Selected row ids, and how to change them. Without these, no checkboxes. */\n selected?: ReadonlySet<string>;\n onToggleSelect?: (id: string) => void;\n onToggleAll?: () => void;\n /** Open a row in the record pop-up. */\n onOpenRecord?: (id: string) => void;\n /** The number shown for the first row (pages after the first start later). */\n firstRowNumber?: number;\n /** Under the last row, e.g. \"Add a record\". */\n footer?: ReactNode;\n height?: number;\n /** Accessible name; defaults to the table's label. */\n label?: string;\n}\n\n/**\n * The spreadsheet view of a table (DATA-STUDIO.md P2). A paste across rows\n * is saved in ONE transaction through `updateMany`: every row changes, at\n * the version it was read, or none does, and the failing cells are marked.\n */\nexport function SheetView({\n provider,\n schema,\n rows,\n keys,\n linkLabels,\n onSaved,\n onFailed,\n onUndo,\n onNotice,\n hidden,\n selected,\n onToggleSelect,\n onToggleAll,\n onOpenRecord,\n firstRowNumber = 1,\n footer,\n height,\n label,\n}: SheetViewProps) {\n const versionField = schema.version?.field;\n const keyNames = useMemo(() => new Set(keyFields(schema)), [schema]);\n const columns = useMemo<SheetGridColumn<Row>[]>(\n () =>\n gridFields(schema).filter((field) => !hidden?.has(field.name)).map((field, index) => {\n const labels = linkLabels.get(field.name);\n return {\n key: field.name,\n header: fieldLabel(field),\n icon: <FieldIcon field={field} isKey={keyNames.has(field.name)} />,\n // The first column names the row, so it gets more room.\n width: index === 0 && field.name === schema.labelField ? 220 : field.type === \"json\" ? 220 : field.type === \"boolean\" ? 110 : 170,\n ...(field.type === \"number\" && !field.enumValues ? { align: \"end\" as const } : {}),\n getText: (row: Row) => editText(row[field.name]),\n render: (row: Row) => (\n <CellValue field={field} value={row[field.name]} linkLabel={labels?.get(String(row[field.name]))} />\n ),\n // Links are edited in the record form, with a picker.\n editable: Boolean(field.permissions?.update) && !field.references,\n readOnlyReason: field.references && field.permissions?.update ? \"Edit links in the record's form.\" : field.permissions?.reason,\n ...(choicesFor(field) ? { options: choicesFor(field) } : {}),\n };\n }),\n [schema, linkLabels, hidden, keyNames],\n );\n const selectable = Boolean(selected && onToggleSelect);\n const allSelected = selectable && rows.length > 0 && rows.every((row) => selected!.has(keys.get(row) ?? \"\"));\n\n async function commit(changes: SheetCellChange<Row>[]) {\n // One update per row, with every cell that changed in it.\n const byRow = new Map<string, { row: Row; data: Record<string, unknown> }>();\n for (const change of changes) {\n const field = schema.fields.find((f) => f.name === change.column)!;\n const entry = byRow.get(change.rowKey) ?? { row: change.row, data: {} };\n entry.data[change.column] = parseDraft(field, change.value);\n byRow.set(change.rowKey, entry);\n }\n const items = [...byRow.entries()];\n const expected = (row: Row) => (versionField ? (row[versionField] == null ? null : String(row[versionField])) : null);\n try {\n if (items.length === 1) {\n const [, { row, data }] = items[0]!;\n const result = await provider.update<BaseRecord>(schema.name, { id: encodeRecordKey(schema, row), data: data as never, expectedVersion: expected(row) });\n onSaved([{ old: row, next: result.data as Row, ...(result.audit ? { audit: result.audit } : {}) }]);\n return;\n }\n if (!provider.updateMany) throw new Error(\"This data provider can't save several rows at once.\");\n const result = await provider.updateMany(schema.name, {\n changes: items.map(([, { row, data }]) => ({ id: encodeRecordKey(schema, row), data, expectedVersion: expected(row) })),\n });\n if (!result.ok) {\n const failures = result.failures ?? [];\n const cells = failures.flatMap((f) => {\n const [rowKey, { data }] = items[f.index]!;\n return Object.keys(data).map((column) => ({ rowKey, column, message: f.message }));\n });\n const message = `Nothing was saved: ${failures.length} of ${items.length} rows failed. Fix the marked cells and paste again.`;\n onFailed(message);\n throw new SheetCommitError(message, cells);\n }\n // The bulk result carries audit entries, not rows: reload the page.\n onSaved(\n items.map(([, { row, data }], i) => ({\n old: row,\n next: { ...row, ...data },\n ...(result.audit?.[i] ? { audit: result.audit[i] } : {}),\n })),\n );\n onNotice(`Saved ${result.count} rows in one transaction.`);\n } catch (error) {\n if (error instanceof SheetCommitError) throw error;\n const message = isDataWriteError(error) || error instanceof Error ? error.message : String(error);\n onFailed(message);\n throw error;\n }\n }\n\n return (\n <SheetGrid<Row>\n label={label ?? `${schema.label ?? schema.name} sheet`}\n rows={rows}\n columns={columns}\n getKey={(row) => keys.get(row) ?? \"\"}\n onCommit={commit}\n onUndo={onUndo}\n onSkipped={(count) => onNotice(`${count} read-only cell${count === 1 ? \" was\" : \"s were\"} left as they were.`)}\n height={height ?? Math.min(640, Math.max(160, (rows.length + 2) * 32 + 4))}\n className=\"rounded-md\"\n empty=\"No records match.\"\n footer={footer}\n rowHeader={{\n width: selectable ? 84 : 64,\n header: selectable ? (\n <input\n type=\"checkbox\"\n aria-label=\"Select every row on this page\"\n className=\"h-3.5 w-3.5\"\n checked={allSelected}\n onChange={() => onToggleAll?.()}\n />\n ) : null,\n render: (row, index) => {\n const id = keys.get(row) ?? \"\";\n return (\n <span className=\"flex w-full items-center gap-1.5\">\n {selectable && (\n <input\n type=\"checkbox\"\n aria-label={`Select row ${firstRowNumber + index}`}\n className=\"h-3.5 w-3.5\"\n checked={selected!.has(id)}\n onChange={() => onToggleSelect!(id)}\n data-testid=\"studio-row-select\"\n />\n )}\n <span className=\"min-w-[1.5rem] tabular-nums\">{firstRowNumber + index}</span>\n {onOpenRecord && id && (\n <button\n type=\"button\"\n className=\"ml-auto rounded p-0.5 text-muted-foreground opacity-0 hover:bg-background hover:text-foreground focus-visible:opacity-100 group-hover/row:opacity-100\"\n aria-label={`Open row ${firstRowNumber + index}`}\n title=\"Open record\"\n onClick={() => onOpenRecord(id)}\n data-testid=\"studio-open-record\"\n >\n <Maximize2 className=\"h-3 w-3\" aria-hidden />\n </button>\n )}\n </span>\n );\n },\n }}\n />\n );\n}\n"],"mappings":"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","names":["useCallback","useEffect","useMemo","useState","keepPreviousData","useQuery","useQueryClient","ChevronLeft","ChevronRight","History","Lock","Plus","Table2","Trash2","X","encodeRecordKey","isDataWriteError","keyFields","Button","Dialog","DialogContent","DialogDescription","DialogHeader","DialogTitle","Alert","AlertDescription","AlertTitle","cn","useEffect","useMemo","useState","Button","useState","useQuery","useState","useQuery","jsx","jsxs","useMemo","values","useState","useEffect","Button","useMemo","useState","useQuery","Textarea","Button","jsx","jsxs","useQuery","useState","useMemo","Button","r","Textarea","useState","X","Button","Input","Popover","PopoverContent","PopoverTrigger","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","jsx","jsxs","NONE","useState","Popover","PopoverTrigger","Button","PopoverContent","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Input","X","jsxs","Select","jsx","SelectTrigger","SelectValue","SelectContent","SelectItem","Popover","PopoverTrigger","Button","PopoverContent","Input","useState","Popover","PopoverContent","PopoverTrigger","Plus","Search","X","jsx","jsxs","VIEWS","Link2","cn","Fragment","jsx","Link2","cn","useEffect","useMemo","useState","useQueries","encodeRecordKey","isDataWriteError","Button","jsx","jsxs","NONE","versionOf","useMemo","useState","useQueries","isDataWriteError","useEffect","encodeRecordKey","Button","useEffect","useMemo","useQuery","encodeRecordKey","isDataWriteError","Button","cn","jsx","jsxs","useQuery","isDataWriteError","useEffect","useMemo","Button","cn","encodeRecordKey","useMemo","useState","Button","Label","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","Fragment","jsx","jsxs","useState","useMemo","Button","Label","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","useState","Button","Dialog","DialogContent","DialogDescription","DialogHeader","DialogTitle","Input","Label","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","jsx","jsxs","useState","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","Label","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Input","Button","useMemo","encodeRecordKey","isDataWriteError","keyFields","jsx","jsxs","useMemo","keyFields","result","encodeRecordKey","isDataWriteError","Fragment","jsx","jsxs","isDataWriteError","useState","useEffect","useQueryClient","useCallback","useQuery","cn","Sheet","Table2","useMemo","keyFields","keepPreviousData","encodeRecordKey","Alert","AlertTitle","AlertDescription","versionOf","Plus","view","Lock","Button","Trash2","X","ChevronLeft","ChevronRight","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","jsxs","jsx","History","cn"]}
|