@proveanything/smartlinks-utils-ui 0.3.7 → 0.3.8
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/chunk-NIAIQRFC.js +28 -0
- package/dist/chunk-NIAIQRFC.js.map +1 -0
- package/dist/components/AssetPicker/index.js +1 -1
- package/dist/components/ConditionsEditor/index.js +1 -1
- package/dist/components/FontPicker/index.js +1 -1
- package/dist/components/IconPicker/index.js +1 -1
- package/dist/components/RecordsAdmin/index.d.ts +34 -4
- package/dist/components/RecordsAdmin/index.js +443 -34
- package/dist/components/RecordsAdmin/index.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-WFNEZQCD.js +0 -28
- package/dist/chunk-WFNEZQCD.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/RecordsAdmin/shell/icons.ts","../../../src/components/RecordsAdmin/types/i18n.ts","../../../src/components/RecordsAdmin/types/presentation.ts","../../../src/components/RecordsAdmin/data/refs.ts","../../../src/components/RecordsAdmin/data/scopeBridge.ts","../../../src/components/RecordsAdmin/data/records.ts","../../../src/components/RecordsAdmin/hooks/useRecordList.ts","../../../src/components/RecordsAdmin/data/resolveRecord.ts","../../../src/components/RecordsAdmin/hooks/useResolvedRecord.ts","../../../src/components/RecordsAdmin/hooks/useRecordEditor.ts","../../../src/components/RecordsAdmin/hooks/useIntroDismissed.ts","../../../src/components/RecordsAdmin/hooks/useScopeProbe.ts","../../../src/components/RecordsAdmin/hooks/useFacetBrowse.ts","../../../src/components/RecordsAdmin/hooks/useProductBrowse.ts","../../../src/components/RecordsAdmin/hooks/useProductChildren.ts","../../../src/components/RecordsAdmin/hooks/useUnsavedGuard.ts","../../../src/components/RecordsAdmin/hooks/useDirtyNavigation.ts","../../../src/components/RecordsAdmin/browser/ScopeTabs.tsx","../../../src/components/RecordsAdmin/browser/StatusFilterPills.tsx","../../../src/components/RecordsAdmin/browser/StatusDot.tsx","../../../src/components/RecordsAdmin/browser/DefaultRecordRow.tsx","../../../src/components/RecordsAdmin/browser/DefaultRecordCard.tsx","../../../src/components/RecordsAdmin/browser/RecordList.tsx","../../../src/components/RecordsAdmin/browser/EmptyStates.tsx","../../../src/components/RecordsAdmin/browser/PresentationSwitcher.tsx","../../../src/components/RecordsAdmin/hooks/usePresentationPref.ts","../../../src/components/RecordsAdmin/shell/ScopeBreadcrumb.tsx","../../../src/components/RecordsAdmin/editor/BulkActionsMenu.tsx","../../../src/components/RecordsAdmin/editor/DeleteButton.tsx","../../../src/components/RecordsAdmin/editor/RecordEditor.tsx","../../../src/components/RecordsAdmin/editor/ProductDrillDown.tsx","../../../src/components/RecordsAdmin/editor/PreviewPane.tsx","../../../src/components/RecordsAdmin/editor/PreviewScopePicker.tsx","../../../src/components/RecordsAdmin/shell/IntroCard.tsx","../../../src/components/RecordsAdmin/shell/UtilityRow.tsx","../../../src/components/RecordsAdmin/shell/ShellHeader.tsx","../../../src/components/RecordsAdmin/data/csv.ts","../../../src/components/RecordsAdmin/shell/tokens.css","../../../src/components/RecordsAdmin/shell/shell.css","../../../src/components/RecordsAdmin/shell/RecordsAdminShell.tsx","../../../src/components/RecordsAdmin/browser/RecordBrowser.tsx","../../../src/components/RecordsAdmin/editor/InheritanceMarker.tsx","../../../src/components/RecordsAdmin/editor/ResolvedPreview.tsx","../../../src/components/RecordsAdmin/hooks/useResolveAllRecords.ts","../../../src/components/RecordsAdmin/hooks/useRulePreview.ts","../../../src/components/RecordsAdmin/hooks/useCollectedRecords.ts","../../../src/components/RecordsAdmin/hooks/useMergedRecord.ts"],"names":["eq","total","useQueryClient","useState","useEffect","useCallback","useQuery","useRef","useMemo","QK","useInfiniteQuery","items","res","jsx","jsxs","Inbox","LayoutGrid","ImageIcon","Layers","Copy","Upload","Download","ChevronDown","Trash2","Package","Eye","Fragment","Lightbulb","CheckCircle2","X","Plus","Search","DEFAULT_SCOPES"],"mappings":"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","file":"index.js","sourcesContent":["// =============================================================================\r\n// RecordsAdmin — Icon registry (v0.4)\r\n//\r\n// Lucide icons used at known anchor points in the shell. Apps can override the\r\n// whole registry, or any subset, via the `icons` prop on RecordsAdminShell.\r\n// =============================================================================\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport {\r\n Package, Layers, Boxes, Tag, Globe,\r\n CheckCircle2, ArrowDownLeft, CircleDashed,\r\n Plus, Pencil, Copy, Trash2, Upload, Download,\r\n Eye, LayoutGrid, Inbox, SearchX,\r\n Database, FileText, Lightbulb, ChevronDown, MoreHorizontal,\r\n} from 'lucide-react';\r\nimport type { ScopeKind } from '../types';\r\n\r\nexport interface RecordsAdminIcons {\r\n scope: Record<ScopeKind | 'universal', LucideIcon>;\r\n status: { own: LucideIcon; inherited: LucideIcon; missing: LucideIcon };\r\n action: {\r\n add: LucideIcon; edit: LucideIcon; duplicate: LucideIcon; delete: LucideIcon;\r\n import: LucideIcon; export: LucideIcon; more: LucideIcon;\r\n };\r\n preview: { eye: LucideIcon; switch: LucideIcon };\r\n empty: { default: LucideIcon; search: LucideIcon };\r\n intro: { info: LucideIcon };\r\n /** Header — used when no `headerIcon` prop is passed. Apps can override\r\n * `byRecordType[recordType]` for a contextual icon, or `default` as the\r\n * catch-all. */\r\n header: { default: LucideIcon; byRecordType: Record<string, LucideIcon> };\r\n group: { chevron: LucideIcon };\r\n}\r\n\r\n/** Library defaults — every consumer gets these unless `icons` is overridden. */\r\nexport const DEFAULT_ICONS: RecordsAdminIcons = {\r\n scope: { product: Package, variant: Layers, batch: Boxes, facet: Tag, universal: Globe },\r\n status: { own: CheckCircle2, inherited: ArrowDownLeft, missing: CircleDashed },\r\n action: {\r\n add: Plus, edit: Pencil, duplicate: Copy, delete: Trash2,\r\n import: Upload, export: Download, more: MoreHorizontal,\r\n },\r\n preview: { eye: Eye, switch: LayoutGrid },\r\n empty: { default: Inbox, search: SearchX },\r\n intro: { info: Lightbulb },\r\n header: { default: Database, byRecordType: {} },\r\n group: { chevron: ChevronDown },\r\n};\r\n\r\n/** Deep-merge an `icons` prop onto the defaults. */\r\nexport function mergeIcons(override?: Partial<RecordsAdminIcons>): RecordsAdminIcons {\r\n if (!override) return DEFAULT_ICONS;\r\n return {\r\n scope: { ...DEFAULT_ICONS.scope, ...(override.scope ?? {}) },\r\n status: { ...DEFAULT_ICONS.status, ...(override.status ?? {}) },\r\n action: { ...DEFAULT_ICONS.action, ...(override.action ?? {}) },\r\n preview: { ...DEFAULT_ICONS.preview, ...(override.preview ?? {}) },\r\n empty: { ...DEFAULT_ICONS.empty, ...(override.empty ?? {}) },\r\n intro: { ...DEFAULT_ICONS.intro, ...(override.intro ?? {}) },\r\n header: {\r\n default: override.header?.default ?? DEFAULT_ICONS.header.default,\r\n byRecordType: { ...DEFAULT_ICONS.header.byRecordType, ...(override.header?.byRecordType ?? {}) },\r\n },\r\n group: { ...DEFAULT_ICONS.group, ...(override.group ?? {}) },\r\n };\r\n}\r\n\r\n/** Look up the right header icon based on prop precedence:\r\n * explicit `headerIcon` > `icons.header.byRecordType[type]` > `icons.header.default`. */\r\nexport function pickHeaderIcon(\r\n icons: RecordsAdminIcons,\r\n recordType?: string,\r\n): LucideIcon {\r\n if (recordType && icons.header.byRecordType[recordType]) {\r\n return icons.header.byRecordType[recordType];\r\n }\r\n return icons.header.default;\r\n}\r\n\r\n// Re-export the underlying Lucide icon type for app overrides.\r\nexport type { LucideIcon };\r\n","// =============================================================================\r\n// RecordsAdmin — i18n strings + defaults\r\n// =============================================================================\r\nexport interface RecordsAdminI18n {\r\n emptyTitle: string;\r\n emptyBody: string;\r\n noResults: string;\r\n searchPlaceholder: string;\r\n filterAll: string;\r\n filterConfigured: string;\r\n filterPartial: string;\r\n filterEmpty: string;\r\n save: string;\r\n discard: string;\r\n delete: string;\r\n /** Save button label while a save is in flight. */\r\n saving: string;\r\n /** Inline error label shown next to the Save button when a save fails. */\r\n saveError: string;\r\n inherited: string;\r\n override: string;\r\n reset: string;\r\n bulkActions: string;\r\n applyToMany: string;\r\n copyFrom: string;\r\n clear: string;\r\n importCsv: string;\r\n exportCsv: string;\r\n preview: string;\r\n editor: string;\r\n closePreview: string;\r\n openPreview: string;\r\n previewAs: string;\r\n previewAsDefault: string;\r\n confirmDelete: string;\r\n unsavedBadge: string;\r\n unsavedPromptTitle: string;\r\n unsavedPromptBody: string;\r\n unsavedPromptDiscard: string;\r\n unsavedPromptCancel: string;\r\n unsavedPromptSave: string;\r\n\r\n /** Presentation mode switcher labels. */\r\n presentationList: string;\r\n presentationGrid: string;\r\n presentationGallery: string;\r\n presentationCompact: string;\r\n\r\n /** Collection cardinality affordances. */\r\n newItem: string;\r\n noItemsTitle: string;\r\n noItemsBody: string;\r\n\r\n /**\r\n * Empty-state copy for the LEFT browse rail (the list itself is empty).\r\n * Defaults to a friendly \"no records exist yet\" message — distinct from\r\n * `emptyTitle/emptyBody` which is the RIGHT pane \"pick something\" prompt.\r\n */\r\n railEmptyTitle: string;\r\n railEmptyBody: string;\r\n}\r\n\r\nexport const DEFAULT_I18N: RecordsAdminI18n = {\r\n emptyTitle: 'Nothing here yet',\r\n emptyBody: 'Pick a record from the left to start editing.',\r\n noResults: 'No records match your search.',\r\n searchPlaceholder: 'Search…',\r\n filterAll: 'All',\r\n filterConfigured: 'Configured',\r\n filterPartial: 'Partial',\r\n filterEmpty: 'Empty',\r\n save: 'Save',\r\n discard: 'Discard',\r\n delete: 'Delete record',\r\n saving: 'Saving…',\r\n saveError: 'Save failed',\r\n inherited: 'Inherited',\r\n override: 'Override',\r\n reset: 'Reset to inherited',\r\n bulkActions: 'Bulk actions',\r\n applyToMany: 'Apply to many…',\r\n copyFrom: 'Copy from…',\r\n clear: 'Clear records…',\r\n importCsv: 'Import CSV',\r\n exportCsv: 'Export CSV',\r\n preview: 'Preview',\r\n editor: 'Editor',\r\n closePreview: 'Close preview',\r\n openPreview: 'Open preview',\r\n previewAs: 'Preview as',\r\n previewAsDefault: 'Same as edited',\r\n confirmDelete: 'Confirm delete',\r\n unsavedBadge: 'Unsaved',\r\n unsavedPromptTitle: 'Unsaved changes',\r\n unsavedPromptBody: 'You have unsaved changes. What would you like to do?',\r\n unsavedPromptDiscard: 'Discard changes',\r\n unsavedPromptCancel: 'Stay here',\r\n unsavedPromptSave: 'Save & continue',\r\n presentationList: 'List',\r\n presentationGrid: 'Grid',\r\n presentationGallery: 'Gallery',\r\n presentationCompact: 'Compact',\r\n newItem: 'New item',\r\n noItemsTitle: 'No items yet',\r\n noItemsBody: 'Create your first item to get started.',\r\n railEmptyTitle: 'No records yet',\r\n railEmptyBody: 'Records you create will appear here.',\r\n};","// =============================================================================\r\n// RecordsAdmin — Presentation modes & cardinality\r\n// =============================================================================\r\n\r\n/**\r\n * How records are laid out in the browse rail / panel.\r\n * - `list` → dense rows with status dot + label + subtitle (default).\r\n * - `grid` → square cards with thumbnail + label.\r\n * - `gallery` → larger 16:9 cards with thumbnail + label + subtitle.\r\n * - `compact` → minimal one-line rows (no subtitle, no status dot).\r\n */\r\nexport type RecordPresentation = 'list' | 'grid' | 'gallery' | 'compact';\r\n\r\nexport const ALL_PRESENTATIONS: RecordPresentation[] = ['list', 'grid', 'gallery', 'compact'];\r\n\r\n/**\r\n * Whether each scope holds at most one record of this type, or many.\r\n * - `singleton` → one record per scope (e.g. washing instructions). Default.\r\n * - `collection` → many records per scope (e.g. FAQs, recipes, SOPs).\r\n */\r\nexport type RecordCardinality = 'singleton' | 'collection';\r\n\r\n/**\r\n * How `useCollectedRecords` orders the aggregated chain.\r\n * - `specificity` → most-specific scope first (default).\r\n * - `field` → use a numeric/string `data.<field>` to sort.\r\n */\r\nexport type CollectedSort =\r\n | { kind: 'specificity'; direction?: 'asc' | 'desc' }\r\n | { kind: 'field'; field: string; direction?: 'asc' | 'desc' };","// =============================================================================\r\n// Ref parsing — `kind:id` segments joined by `/`\r\n// =============================================================================\r\nimport type { ParsedRef, ScopeKind } from '../types';\r\n\r\nconst KIND_KEYS: Record<ScopeKind | 'collection' | 'proof', keyof ParsedRef> = {\r\n product: 'productId',\r\n facet: 'facetId',\r\n variant: 'variantId',\r\n batch: 'batchId',\r\n proof: 'proofId',\r\n collection: 'collectionId',\r\n};\r\n\r\nexport const parseRef = (raw: string): ParsedRef => {\r\n const parsed: ParsedRef = { kind: 'collection', raw };\r\n if (!raw) return parsed;\r\n const segments = raw.split('/').filter(Boolean);\r\n let kind: ParsedRef['kind'] = 'collection';\r\n for (const seg of segments) {\r\n const idx = seg.indexOf(':');\r\n if (idx < 0) continue;\r\n const k = seg.slice(0, idx) as ScopeKind | 'collection' | 'proof';\r\n const id = seg.slice(idx + 1);\r\n if (k === 'facet') {\r\n // facet:<id>=<value> or facet:<id>\r\n const eq = id.indexOf('=');\r\n if (eq >= 0) {\r\n parsed.facetId = id.slice(0, eq);\r\n parsed.facetValue = id.slice(eq + 1);\r\n } else {\r\n parsed.facetId = id;\r\n }\r\n } else if (k in KIND_KEYS) {\r\n // @ts-expect-error narrow\r\n parsed[KIND_KEYS[k]] = id;\r\n }\r\n if (k !== 'collection') kind = k as ParsedRef['kind'];\r\n }\r\n parsed.kind = kind;\r\n return parsed;\r\n};\r\n\r\nexport interface BuildRefArgs {\r\n collectionId?: string;\r\n productId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n proofId?: string;\r\n}\r\n\r\nexport const buildRef = (a: BuildRefArgs): string => {\r\n const parts: string[] = [];\r\n if (a.facetId) {\r\n parts.push(a.facetValue ? `facet:${a.facetId}=${a.facetValue}` : `facet:${a.facetId}`);\r\n }\r\n if (a.productId) parts.push(`product:${a.productId}`);\r\n if (a.variantId) parts.push(`variant:${a.variantId}`);\r\n if (a.batchId) parts.push(`batch:${a.batchId}`);\r\n if (a.proofId) parts.push(`proof:${a.proofId}`);\r\n return parts.join('/');\r\n};\r\n\r\n/**\r\n * Build the resolution chain for a target ref, from most specific → least specific.\r\n * `supportedScopes` prunes scopes the app doesn't care about.\r\n */\r\nexport const resolutionChain = (\r\n target: ParsedRef,\r\n supportedScopes: ScopeKind[],\r\n): string[] => {\r\n const chain: string[] = [];\r\n // Most specific → least specific\r\n if (supportedScopes.includes('batch') && target.batchId && target.productId) {\r\n chain.push(buildRef({ productId: target.productId, batchId: target.batchId }));\r\n }\r\n if (supportedScopes.includes('variant') && target.variantId && target.productId) {\r\n chain.push(buildRef({ productId: target.productId, variantId: target.variantId }));\r\n }\r\n if (supportedScopes.includes('product') && target.productId) {\r\n chain.push(buildRef({ productId: target.productId }));\r\n }\r\n if (supportedScopes.includes('facet') && target.facetId) {\r\n chain.push(buildRef({ facetId: target.facetId, facetValue: target.facetValue }));\r\n }\r\n // Dedupe while preserving order\r\n return Array.from(new Set(chain));\r\n};","// =============================================================================\r\n// scopeBridge — Convert between our UI `ParsedRef` and the SDK `RecordScope`.\r\n//\r\n// Our `ParsedRef` is a UI-friendly flat object that round-trips with the\r\n// `kind:id/kind:id` URL refs. The SDK's `RecordScope` is the structured\r\n// canonical form used for server-side specificity & `match()`. Use these\r\n// helpers at every boundary so we never write a record without `scope`.\r\n// =============================================================================\r\nimport type { RecordScope, RecordTarget } from './sdkTypes';\r\nimport type { ParsedRef } from '../types';\r\n\r\nexport const parsedRefToScope = (ref: ParsedRef): RecordScope => {\r\n const scope: RecordScope = {};\r\n if (ref.productId) scope.productId = ref.productId;\r\n if (ref.variantId) scope.variantId = ref.variantId;\r\n if (ref.batchId) scope.batchId = ref.batchId;\r\n if (ref.proofId) scope.proofId = ref.proofId;\r\n if (ref.facetId) {\r\n scope.facets = [{\r\n key: ref.facetId,\r\n valueKeys: ref.facetValue ? [ref.facetValue] : [],\r\n }];\r\n }\r\n return scope;\r\n};\r\n\r\nexport const parsedRefToTarget = (ref: ParsedRef): RecordTarget => {\r\n const target: RecordTarget = {};\r\n if (ref.productId) target.productId = ref.productId;\r\n if (ref.variantId) target.variantId = ref.variantId;\r\n if (ref.batchId) target.batchId = ref.batchId;\r\n if (ref.proofId) target.proofId = ref.proofId;\r\n if (ref.facetId && ref.facetValue) {\r\n target.facets = { [ref.facetId]: [ref.facetValue] };\r\n }\r\n return target;\r\n};\r\n\r\n/**\r\n * Compare a winning record's scope against the editing scope.\r\n * Returns true when they refer to the same node — used to decide\r\n * \"self\" vs \"inherited\" when consuming `match()` results.\r\n */\r\nexport const scopesEqual = (a: RecordScope, b: RecordScope): boolean => {\r\n if ((a.productId ?? null) !== (b.productId ?? null)) return false;\r\n if ((a.variantId ?? null) !== (b.variantId ?? null)) return false;\r\n if ((a.batchId ?? null) !== (b.batchId ?? null)) return false;\r\n if ((a.proofId ?? null) !== (b.proofId ?? null)) return false;\r\n const af = a.facets ?? [];\r\n const bf = b.facets ?? [];\r\n if (af.length !== bf.length) return false;\r\n const norm = (xs: typeof af) => xs\r\n .map((f) => `${f.key}:${[...f.valueKeys].sort().join(',')}`)\r\n .sort()\r\n .join('|');\r\n return norm(af) === norm(bf);\r\n};","// =============================================================================\r\n// Thin wrappers over SL.app.records.* — always admin: true here.\r\n//\r\n// As of `@proveanything/smartlinks` 1.9.0 the records surface ships a proper\r\n// `upsert()`, server-side `match()`, and atomic `bulkUpsert` / `bulkDelete`.\r\n// We delegate to those rather than rolling our own list+update sequences,\r\n// which were racy and ignored facet AND-of-OR semantics.\r\n// =============================================================================\r\nimport type {\r\n AppRecord, RecordScope, RecordTarget, BulkUpsertItem, BulkDeleteResult,\r\n MatchResult,\r\n} from './sdkTypes';\r\nimport type { ParsedRef, SmartLinksSDK } from '../types';\r\nimport { parsedRefToScope } from './scopeBridge';\r\n\r\nexport interface RecordsCtx {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n /** Optional — when omitted, records are stored against the app id alone\r\n * (no type qualifier). Set this only when an app uses multiple record types\r\n * and needs to query/scope by type. */\r\n recordType?: string;\r\n}\r\n\r\n/** Shape of a single record write — uses the SDK's structured `scope`. */\r\nexport interface RecordWrite<T = unknown> {\r\n /** Logical key. The server canonicalises this from `scope` if omitted. */\r\n ref?: string;\r\n /** Structured scope; required for specificity / `match()` to work. */\r\n scope: RecordScope;\r\n data: T;\r\n visibility?: 'public' | 'owner' | 'admin';\r\n productId?: string;\r\n status?: string;\r\n startsAt?: string | null;\r\n expiresAt?: string | null;\r\n customId?: string;\r\n sourceSystem?: string;\r\n}\r\n\r\nexport const listRecords = async (\r\n ctx: RecordsCtx,\r\n params: { ref?: string; refPrefix?: string; q?: string; limit?: number; offset?: number; sort?: string } = {},\r\n): Promise<{ data: AppRecord[]; total: number; hasMore: boolean }> => {\r\n const { limit = 100, offset, ref, refPrefix, q, sort } = params;\r\n const res = await ctx.SL.app.records.list(\r\n ctx.collectionId,\r\n ctx.appId,\r\n {\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n limit, offset, ref, refPrefix, q, sort,\r\n },\r\n true,\r\n );\r\n return {\r\n data: res?.data ?? [],\r\n total: res?.pagination?.total ?? (res?.data?.length ?? 0),\r\n hasMore: res?.pagination?.hasMore ?? false,\r\n };\r\n};\r\n\r\n/** Look up a single record by its canonical ref. */\r\nexport const getRecordByRef = async (\r\n ctx: RecordsCtx,\r\n ref: string,\r\n): Promise<AppRecord | null> => {\r\n const res = await ctx.SL.app.records.list(\r\n ctx.collectionId,\r\n ctx.appId,\r\n { ...(ctx.recordType ? { recordType: ctx.recordType } : {}), ref, limit: 1 },\r\n true,\r\n );\r\n return res?.data?.[0] ?? null;\r\n};\r\n\r\n/**\r\n * Atomic upsert via the SDK. Always sends `scope` so the server can compute\r\n * `specificity` and derive `ref` deterministically.\r\n */\r\nexport const upsertRecord = async <T,>(\r\n ctx: RecordsCtx,\r\n write: RecordWrite<T>,\r\n): Promise<{ record: AppRecord; isCreate: boolean }> => {\r\n const ref = write.ref ?? deriveRefFromScope(write.scope);\r\n const res = await ctx.SL.app.records.upsert(ctx.collectionId, ctx.appId, {\r\n ref,\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n scope: write.scope,\r\n data: write.data as Record<string, unknown>,\r\n status: write.status,\r\n startsAt: write.startsAt,\r\n expiresAt: write.expiresAt,\r\n customId: write.customId,\r\n sourceSystem: write.sourceSystem,\r\n });\r\n return { record: res, isCreate: !!res?.created };\r\n};\r\n\r\n/**\r\n * Convenience wrapper for callers that only have a `ParsedRef` and a payload —\r\n * matches the previous (`ref`, `data`) call shape used by the editor hook.\r\n */\r\nexport const upsertRecordForScope = async <T,>(\r\n ctx: RecordsCtx,\r\n scope: ParsedRef,\r\n data: T,\r\n extra: { visibility?: 'public' | 'owner' | 'admin' } = {},\r\n) => upsertRecord<T>(ctx, {\r\n ref: scope.raw || undefined,\r\n scope: parsedRefToScope(scope),\r\n data,\r\n visibility: extra.visibility,\r\n});\r\n\r\nexport const deleteRecord = async (\r\n ctx: RecordsCtx,\r\n ref: string,\r\n): Promise<boolean> => {\r\n const existing = await getRecordByRef(ctx, ref).catch(() => null);\r\n if (!existing) return false;\r\n await ctx.SL.app.records.remove(ctx.collectionId, ctx.appId, existing.id, true);\r\n return true;\r\n};\r\n\r\n/** Restore a soft-deleted record by ID (admin only). */\r\nexport const restoreRecord = async (\r\n ctx: RecordsCtx,\r\n recordId: string,\r\n): Promise<AppRecord> => ctx.SL.app.records.restore(ctx.collectionId, ctx.appId, recordId);\r\n\r\n/**\r\n * Server-side match — single round trip that returns every record whose\r\n * `scope` is satisfied by `target`, ordered by descending `specificity`.\r\n * Replaces the per-scope N+1 chain walk we used pre-1.9.\r\n */\r\nexport const matchRecords = async (\r\n ctx: RecordsCtx,\r\n target: RecordTarget,\r\n opts: {\r\n strategy?: 'all' | 'best';\r\n at?: string;\r\n includeScheduled?: boolean;\r\n includeExpired?: boolean;\r\n limit?: number;\r\n } = {},\r\n): Promise<MatchResult> => ctx.SL.app.records.match(\r\n ctx.collectionId,\r\n ctx.appId,\r\n {\r\n target,\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n strategy: opts.strategy ?? 'all',\r\n at: opts.at,\r\n includeScheduled: opts.includeScheduled,\r\n includeExpired: opts.includeExpired,\r\n limit: opts.limit,\r\n },\r\n true,\r\n);\r\n\r\n/**\r\n * Server-side bulk upsert. Up to 500 rows per call; any leftover is chunked.\r\n * Each row is error-isolated by the server.\r\n */\r\nexport const bulkUpsert = async <T,>(\r\n ctx: RecordsCtx,\r\n entries: Array<{ ref?: string; scope: RecordScope; data: T; status?: string }>,\r\n): Promise<{ saved: number; failed: number }> => {\r\n const CHUNK = 500;\r\n let saved = 0;\r\n let failed = 0;\r\n for (let i = 0; i < entries.length; i += CHUNK) {\r\n const slice = entries.slice(i, i + CHUNK);\r\n const items: BulkUpsertItem[] = slice.map((e) => ({\r\n ref: e.ref ?? deriveRefFromScope(e.scope),\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n scope: e.scope,\r\n data: e.data as Record<string, unknown>,\r\n status: e.status,\r\n }));\r\n const res = await ctx.SL.app.records.bulkUpsert(ctx.collectionId, ctx.appId, items)\r\n .catch((): { saved: number; failed: number } => ({ saved: 0, failed: items.length }));\r\n saved += res.saved ?? 0;\r\n failed += res.failed ?? 0;\r\n }\r\n return { saved, failed };\r\n};\r\n\r\n/**\r\n * Server-side bulk delete. Accepts an explicit ref list (max 1000 per call,\r\n * chunked here) or a scope anchor (single call).\r\n */\r\nexport const bulkDelete = async (\r\n ctx: RecordsCtx,\r\n input: { refs: string[] } | { scope: Omit<RecordScope, 'facets'> },\r\n): Promise<{ removed: number }> => {\r\n if ('scope' in input) {\r\n const res: BulkDeleteResult = await ctx.SL.app.records.bulkDelete(\r\n ctx.collectionId, ctx.appId,\r\n { scope: input.scope, ...(ctx.recordType ? { recordType: ctx.recordType } : {}) },\r\n );\r\n return { removed: res.deleted ?? 0 };\r\n }\r\n\r\n const CHUNK = 1000;\r\n let removed = 0;\r\n for (let i = 0; i < input.refs.length; i += CHUNK) {\r\n const slice = input.refs.slice(i, i + CHUNK);\r\n const res: BulkDeleteResult = await ctx.SL.app.records.bulkDelete(\r\n ctx.collectionId, ctx.appId,\r\n { refs: slice, ...(ctx.recordType ? { recordType: ctx.recordType } : {}) },\r\n );\r\n removed += res.deleted ?? 0;\r\n }\r\n return { removed };\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Internal — derive a stable ref string from a structured scope. The server\r\n// re-derives this canonically on write; we send our best guess so callers\r\n// (and our own list/lookup helpers) can find the record by ref afterwards.\r\n// ---------------------------------------------------------------------------\r\nconst deriveRefFromScope = (scope: RecordScope): string => {\r\n const parts: string[] = [];\r\n if (scope.facets && scope.facets.length > 0) {\r\n // Sort for determinism.\r\n const sorted = [...scope.facets].sort((a, b) => a.key.localeCompare(b.key));\r\n for (const f of sorted) {\r\n const vals = [...f.valueKeys].sort().join(',');\r\n parts.push(vals ? `facet:${f.key}=${vals}` : `facet:${f.key}`);\r\n }\r\n }\r\n if (scope.productId) parts.push(`product:${scope.productId}`);\r\n if (scope.variantId) parts.push(`variant:${scope.variantId}`);\r\n if (scope.batchId) parts.push(`batch:${scope.batchId}`);\r\n if (scope.proofId) parts.push(`proof:${scope.proofId}`);\r\n return parts.join('/');\r\n};","import { useMemo, useCallback, useState, useEffect } from 'react';\r\nimport { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';\r\nimport type { RecordSummary, RecordStatus, ScopeKind, ParsedRef } from '../types';\r\nimport { parseRef } from '../data/refs';\r\nimport { listRecords, type RecordsCtx } from '../data/records';\r\nimport type { AppRecord } from '../data/sdkTypes';\r\n\r\nexport interface UseRecordListArgs {\r\n ctx: RecordsCtx;\r\n scopeKind: ScopeKind;\r\n search?: string;\r\n filter?: 'all' | RecordStatus;\r\n classify?: (record: RecordSummary) => RecordStatus;\r\n enabled?: boolean;\r\n scaffolder?: (existing: RecordSummary[]) => Promise<RecordSummary[]> | RecordSummary[];\r\n /**\r\n * Constrain the list to a subtree (e.g. a specific product when the host URL\r\n * pins one). Records whose ParsedRef does not match every set field are dropped.\r\n */\r\n contextScope?: { productId?: string; variantId?: string; batchId?: string };\r\n /** Page size requested from the SDK (default 100). */\r\n pageSize?: number;\r\n}\r\n\r\nconst defaultClassify = (r: RecordSummary): RecordStatus => {\r\n if (!r.data) return 'empty';\r\n const keys = Object.keys(r.data as Record<string, unknown>);\r\n if (keys.length === 0) return 'empty';\r\n return 'configured';\r\n};\r\n\r\nconst matchesScope = (kind: ScopeKind, p: ParsedRef): boolean => {\r\n if (kind === 'product') return !!p.productId && !p.variantId && !p.batchId;\r\n if (kind === 'facet') return !!p.facetId;\r\n if (kind === 'variant') return !!p.variantId;\r\n if (kind === 'batch') return !!p.batchId;\r\n return false;\r\n};\r\n\r\nconst matchesContext = (\r\n p: ParsedRef,\r\n ctx: { productId?: string; variantId?: string; batchId?: string } | undefined,\r\n): boolean => {\r\n if (!ctx) return true;\r\n if (ctx.productId && p.productId !== ctx.productId) return false;\r\n if (ctx.variantId && p.variantId !== ctx.variantId) return false;\r\n if (ctx.batchId && p.batchId !== ctx.batchId) return false;\r\n return true;\r\n};\r\n\r\nconst toSummary = (rec: AppRecord): RecordSummary => {\r\n const ref = rec.ref ?? '';\r\n const scope = parseRef(ref);\r\n return {\r\n id: rec.id,\r\n ref,\r\n scope,\r\n data: rec.data ?? null,\r\n status: 'configured',\r\n label: scope.batchId ?? scope.variantId ?? scope.productId ?? scope.facetValue ?? scope.facetId ?? ref,\r\n updatedAt: rec.updatedAt,\r\n };\r\n};\r\n\r\nconst QK_BASE = ['records-admin', 'list'] as const;\r\n\r\nexport const useRecordList = (args: UseRecordListArgs) => {\r\n const {\r\n ctx, scopeKind, search = '', filter = 'all',\r\n classify, enabled = true, scaffolder, contextScope, pageSize = 100,\r\n } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const queryKey = useMemo(\r\n () => [...QK_BASE, ctx.collectionId, ctx.appId, ctx.recordType, scopeKind,\r\n contextScope?.productId ?? null, contextScope?.variantId ?? null, contextScope?.batchId ?? null],\r\n [ctx.collectionId, ctx.appId, ctx.recordType, scopeKind, contextScope?.productId, contextScope?.variantId, contextScope?.batchId],\r\n );\r\n\r\n const query = useInfiniteQuery({\r\n queryKey,\r\n enabled,\r\n initialPageParam: 0,\r\n queryFn: async ({ pageParam }) => {\r\n const offset = pageParam as number;\r\n const { data, total, hasMore } = await listRecords(ctx, { limit: pageSize, offset });\r\n return { data, total, hasMore, nextOffset: offset + data.length };\r\n },\r\n getNextPageParam: (last) => (last.hasMore ? last.nextOffset : undefined),\r\n staleTime: 30_000,\r\n });\r\n\r\n const [scaffolded, setScaffolded] = useState<RecordSummary[] | null>(null);\r\n\r\n const rawItems = useMemo(() => {\r\n const all = query.data?.pages.flatMap((p) => p.data) ?? [];\r\n const cls = classify ?? defaultClassify;\r\n return all\r\n .map(toSummary)\r\n .filter((s) => matchesScope(scopeKind, s.scope))\r\n .filter((s) => matchesContext(s.scope, contextScope))\r\n .map((s) => ({ ...s, status: cls(s) }));\r\n }, [query.data, scopeKind, classify, contextScope]);\r\n\r\n // Run optional scaffolder when raw items change\r\n useEffect(() => {\r\n if (!scaffolder) { setScaffolded(null); return; }\r\n let cancelled = false;\r\n Promise.resolve(scaffolder(rawItems)).then((next) => {\r\n if (!cancelled) setScaffolded(next);\r\n });\r\n return () => { cancelled = true; };\r\n }, [rawItems, scaffolder]);\r\n\r\n const items = scaffolded ?? rawItems;\r\n\r\n const filtered = useMemo(() => {\r\n let out = items;\r\n if (filter !== 'all') out = out.filter((r) => r.status === filter);\r\n if (search.trim()) {\r\n const q = search.trim().toLowerCase();\r\n out = out.filter((r) => `${r.label} ${r.subtitle ?? ''} ${r.ref}`.toLowerCase().includes(q));\r\n }\r\n return out;\r\n }, [items, filter, search]);\r\n\r\n const counts = useMemo(() => ({\r\n all: items.length,\r\n configured: items.filter((r) => r.status === 'configured').length,\r\n partial: items.filter((r) => r.status === 'partial').length,\r\n empty: items.filter((r) => r.status === 'empty').length,\r\n }), [items]);\r\n\r\n const refetch = useCallback(() => {\r\n queryClient.invalidateQueries({ queryKey: [...QK_BASE, ctx.collectionId, ctx.appId, ctx.recordType] });\r\n }, [queryClient, ctx.collectionId, ctx.appId, ctx.recordType]);\r\n\r\n const total = query.data?.pages[query.data.pages.length - 1]?.total ?? items.length;\r\n\r\n return {\r\n allItems: items,\r\n items: filtered,\r\n total,\r\n counts,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch,\r\n hasNextPage: query.hasNextPage,\r\n isFetchingNextPage: query.isFetchingNextPage,\r\n fetchNextPage: query.fetchNextPage,\r\n };\r\n};","// =============================================================================\r\n// Canonical record resolver — backed by server-side `match()`.\r\n//\r\n// As of `@proveanything/smartlinks` 1.9 this is a single round-trip:\r\n// the server evaluates the full scope chain (including facet AND/OR\r\n// semantics we cannot replicate client-side) and returns records ordered\r\n// by descending specificity. We classify the winning record as `self` vs\r\n// `inherited` by comparing its `scope` against the editing scope.\r\n// =============================================================================\r\nimport type { ParsedRef, ResolvedRecord, ScopeKind } from '../types';\r\nimport { matchRecords, type RecordsCtx } from './records';\r\nimport { parsedRefToScope, parsedRefToTarget, scopesEqual } from './scopeBridge';\r\n\r\nexport interface ResolveArgs {\r\n ctx: RecordsCtx;\r\n target: ParsedRef;\r\n /**\r\n * Ignored — kept for API compatibility. The server determines the\r\n * resolution chain from the structured scope.\r\n */\r\n supportedScopes?: ScopeKind[];\r\n /** When true, also returns the parent value (next-best after self). */\r\n withParent?: boolean;\r\n admin?: boolean;\r\n}\r\n\r\nexport const resolveRecord = async <T,>(args: ResolveArgs): Promise<ResolvedRecord<T>> => {\r\n const target = parsedRefToTarget(args.target);\r\n const editingScope = parsedRefToScope(args.target);\r\n\r\n const result = await matchRecords(args.ctx, target, { strategy: 'all' })\r\n .catch(() => null);\r\n const records = result?.records ?? [];\r\n if (records.length === 0) {\r\n return { data: null, source: 'empty' };\r\n }\r\n\r\n const winnerEntry = records[0];\r\n const winner = winnerEntry.record;\r\n const winnerIsSelf = scopesEqual(winner.scope, editingScope);\r\n\r\n if (winnerIsSelf) {\r\n const parent = records[1]?.record;\r\n return {\r\n data: winner.data as T,\r\n source: 'self',\r\n sourceRef: winner.ref ?? undefined,\r\n parentValue: args.withParent && parent ? (parent.data as T) : undefined,\r\n matchedAt: winnerEntry.matchedAt,\r\n matchedRule: winnerEntry.matchedRule,\r\n };\r\n }\r\n return {\r\n data: winner.data as T,\r\n source: 'inherited',\r\n sourceRef: winner.ref ?? undefined,\r\n parentValue: args.withParent ? (winner.data as T) : undefined,\r\n matchedAt: winnerEntry.matchedAt,\r\n matchedRule: winnerEntry.matchedRule,\r\n };\r\n};","// =============================================================================\r\n// useResolvedRecord — resolver hook backed by react-query.\r\n// =============================================================================\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { ResolvedRecord, ScopeKind, SmartLinksSDK } from '../types';\r\nimport { resolveRecord } from '../data/resolveRecord';\r\nimport { parseRef } from '../data/refs';\r\n\r\nexport interface UseResolvedRecordArgs {\r\n SL: SmartLinksSDK;\r\n appId: string;\r\n /** Optional — see `RecordsAdminShellProps.recordType`. */\r\n recordType?: string;\r\n collectionId: string;\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n proofId?: string;\r\n supportedScopes?: ScopeKind[];\r\n enabled?: boolean;\r\n withParent?: boolean;\r\n}\r\n\r\nconst DEFAULT_SCOPES: ScopeKind[] = ['batch', 'variant', 'product', 'facet'];\r\n\r\n/**\r\n * Build the react-query key used by `useResolvedRecord`. Exported so other\r\n * hooks (notably `useRecordEditor`'s optimistic save path) can prime or\r\n * roll back the resolved-record cache for the same scope.\r\n */\r\nexport const resolvedRecordQueryKey = (args: {\r\n collectionId: string;\r\n appId: string;\r\n recordType?: string;\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n proofId?: string;\r\n withParent?: boolean;\r\n}): unknown[] => [\r\n 'records-admin', 'resolved',\r\n args.collectionId, args.appId, args.recordType ?? null,\r\n args.productId ?? null, args.variantId ?? null, args.batchId ?? null,\r\n args.facetId ?? null, args.facetValue ?? null, args.proofId ?? null,\r\n args.withParent ?? true,\r\n];\r\n\r\nexport function useResolvedRecord<T = unknown>(args: UseResolvedRecordArgs) {\r\n const {\r\n SL, appId, recordType, collectionId,\r\n productId, variantId, batchId, facetId, facetValue, proofId,\r\n supportedScopes = DEFAULT_SCOPES,\r\n enabled = true,\r\n withParent = true,\r\n } = args;\r\n\r\n const query = useQuery<ResolvedRecord<T>>({\r\n queryKey: resolvedRecordQueryKey({\r\n collectionId, appId, recordType,\r\n productId, variantId, batchId, facetId, facetValue, proofId, withParent,\r\n }),\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime: 15_000,\r\n queryFn: async () => {\r\n const target = parseRef('');\r\n target.productId = productId;\r\n target.variantId = variantId;\r\n target.batchId = batchId;\r\n target.facetId = facetId;\r\n target.facetValue = facetValue;\r\n target.proofId = proofId;\r\n return resolveRecord<T>({\r\n ctx: { SL, collectionId, appId, recordType },\r\n target,\r\n supportedScopes,\r\n withParent,\r\n });\r\n },\r\n });\r\n\r\n const data: ResolvedRecord<T> = query.data ?? { data: null, source: 'empty' };\r\n return {\r\n ...data,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n };\r\n}","import { useCallback, useEffect, useRef, useState } from 'react';\r\nimport { useQueryClient } from '@tanstack/react-query';\r\nimport type { EditorContext, ParsedRef, ResolvedRecord } from '../types';\r\nimport { upsertRecord, deleteRecord, type RecordsCtx } from '../data/records';\r\nimport { parsedRefToScope } from '../data/scopeBridge';\r\nimport { resolvedRecordQueryKey } from './useResolvedRecord';\r\n\r\nexport interface UseRecordEditorArgs<T> {\r\n ctx: RecordsCtx;\r\n scope: ParsedRef;\r\n resolved: ResolvedRecord<T>;\r\n defaultData?: () => T;\r\n onSaved?: () => void;\r\n onDeleted?: () => void;\r\n /** Fired after a save fails and local state has been rolled back. */\r\n onSaveError?: (err: unknown) => void;\r\n /**\r\n * Controls how the editor reseeds its local value when the resolved\r\n * record changes. Default `'always'` matches legacy behaviour.\r\n * `'preserve-dirty'` keeps unsaved local edits across resolve refreshes\r\n * (used by the shell when `dirtyStrategy === 'keep'`).\r\n */\r\n reseed?: 'always' | 'preserve-dirty';\r\n}\r\n\r\nconst isEqual = (a: unknown, b: unknown) => {\r\n try { return JSON.stringify(a) === JSON.stringify(b); }\r\n catch { return false; }\r\n};\r\n\r\nconst cloneSeed = <T,>(resolved: ResolvedRecord<T>, defaultData?: () => T): T => {\r\n if (resolved.source === 'self') return resolved.data as T;\r\n if (resolved.source === 'inherited' && resolved.data != null) {\r\n try { return structuredClone(resolved.data); }\r\n catch { return JSON.parse(JSON.stringify(resolved.data)) as T; }\r\n }\r\n return defaultData?.() ?? ({} as T);\r\n};\r\n\r\nexport function useRecordEditor<T>(args: UseRecordEditorArgs<T>): EditorContext<T> {\r\n const {\r\n ctx, scope, resolved, defaultData, onSaved, onDeleted, onSaveError,\r\n reseed = 'always',\r\n } = args;\r\n const queryClient = useQueryClient();\r\n const seed = cloneSeed(resolved, defaultData);\r\n\r\n const [value, setValue] = useState<T>(seed);\r\n const [savedSnapshot, setSavedSnapshot] = useState<T>(seed);\r\n /** Local override of `resolved.source` while a save is in flight or just\r\n * landed — lets the editor flip to `'self'` before the refetch confirms. */\r\n const [optimisticSource, setOptimisticSource] = useState<ResolvedRecord<T>['source'] | null>(null);\r\n const [isSaving, setIsSaving] = useState(false);\r\n const [saveError, setSaveError] = useState<unknown | null>(null);\r\n // Track the most-recent `value` without forcing reseeds to depend on it.\r\n const valueRef = useRef<T>(seed);\r\n useEffect(() => { valueRef.current = value; }, [value]);\r\n\r\n useEffect(() => {\r\n const fresh = cloneSeed(resolved, defaultData);\r\n if (reseed === 'preserve-dirty') {\r\n // Only reseed the editor value when there are no unsaved local edits;\r\n // otherwise just refresh the saved snapshot baseline.\r\n const hasUnsaved = !isEqual(valueRef.current, savedSnapshot);\r\n if (!hasUnsaved) setValue(fresh);\r\n } else {\r\n setValue(fresh);\r\n }\r\n setSavedSnapshot(fresh);\r\n // Real server state has caught up — drop any optimistic source override.\r\n setOptimisticSource(null);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [scope.raw, resolved.source, resolved.sourceRef]);\r\n\r\n // Dirty is strictly local-edit vs saved-snapshot. Inheritance state has\r\n // its own UI signal (`source`) and must not bleed into dirtiness.\r\n const isDirty = !isEqual(value, savedSnapshot);\r\n\r\n /**\r\n * Optimistic save:\r\n * 1. Snapshot prior state.\r\n * 2. Flip local UI to \"saved + self\" immediately (Save disables, status\r\n * dot turns green, `isDirty` clears).\r\n * 3. Prime the resolved-record cache so anything else reading it (the\r\n * rail, preview, sibling consumers) reflects the new value too.\r\n * 4. Fire the upsert in the background.\r\n * 5. On success: fire `onSaved` (the shell uses this to refetch and\r\n * reconcile — the prior `setQueryData` makes that a no-op visually).\r\n * 6. On failure: roll all three back, surface the error, leave the\r\n * editor dirty so the user can retry.\r\n */\r\n const save = useCallback(async () => {\r\n if (!scope.raw) return;\r\n const previousSnapshot = savedSnapshot;\r\n const previousSource = resolved.source;\r\n const cacheKey = resolvedRecordQueryKey({\r\n collectionId: ctx.collectionId,\r\n appId: ctx.appId,\r\n recordType: ctx.recordType,\r\n productId: scope.productId,\r\n variantId: scope.variantId,\r\n batchId: scope.batchId,\r\n facetId: scope.facetId,\r\n facetValue: scope.facetValue,\r\n proofId: scope.proofId,\r\n withParent: true,\r\n });\r\n const previousCache = queryClient.getQueryData<ResolvedRecord<T>>(cacheKey);\r\n\r\n // Optimistic flip — the UI shows \"saved\" before the server confirms.\r\n setSaveError(null);\r\n setIsSaving(true);\r\n setSavedSnapshot(value);\r\n setOptimisticSource('self');\r\n queryClient.setQueryData<ResolvedRecord<T>>(cacheKey, {\r\n data: value,\r\n source: 'self',\r\n sourceRef: scope.raw,\r\n parentValue: previousCache?.parentValue ?? resolved.parentValue,\r\n });\r\n\r\n try {\r\n await upsertRecord<T>(ctx, {\r\n ref: scope.raw,\r\n scope: parsedRefToScope(scope),\r\n data: value,\r\n });\r\n onSaved?.();\r\n } catch (err) {\r\n // Roll everything back — local snapshot, optimistic source, cache.\r\n setSavedSnapshot(previousSnapshot);\r\n setOptimisticSource(null);\r\n if (previousCache !== undefined) {\r\n queryClient.setQueryData(cacheKey, previousCache);\r\n } else {\r\n queryClient.invalidateQueries({ queryKey: cacheKey });\r\n }\r\n setSaveError(err);\r\n onSaveError?.(err);\r\n void previousSource;\r\n throw err;\r\n } finally {\r\n setIsSaving(false);\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [scope.raw, value, savedSnapshot, resolved.source, resolved.parentValue]);\r\n\r\n const reset = useCallback(() => {\r\n setValue(savedSnapshot);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [savedSnapshot]);\r\n\r\n const remove = useCallback(async () => {\r\n if (resolved.source !== 'self' || !scope.raw) return;\r\n await deleteRecord(ctx, scope.raw);\r\n onDeleted?.();\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [resolved.source, scope.raw]);\r\n\r\n const effectiveSource = optimisticSource ?? resolved.source;\r\n\r\n return {\r\n value,\r\n onChange: setValue,\r\n source: effectiveSource,\r\n parentValue: resolved.parentValue,\r\n scope,\r\n isDirty,\r\n save,\r\n reset,\r\n remove,\r\n canRemove: effectiveSource === 'self',\r\n isSaving,\r\n saveError,\r\n };\r\n}","import { useCallback, useEffect, useState } from 'react';\r\nimport type { SmartLinksSDK } from '../types';\r\n\r\n/** Untyped apps share a single intro-dismissed slot under `_default`. */\r\nconst RT_KEY = (recordType?: string) => recordType ?? '_default';\r\nconst lsKey = (appId: string, recordType?: string) => `ra:intro:${appId}:${RT_KEY(recordType)}`;\r\n\r\nexport const useIntroDismissed = (\r\n SL: SmartLinksSDK,\r\n collectionId: string,\r\n appId: string,\r\n recordType?: string,\r\n) => {\r\n const [dismissed, setDismissed] = useState<boolean>(() => {\r\n try { return localStorage.getItem(lsKey(appId, recordType)) === '1'; }\r\n catch { return false; }\r\n });\r\n\r\n useEffect(() => {\r\n let cancelled = false;\r\n (async () => {\r\n try {\r\n const cfg = await SL?.appConfiguration?.getConfig?.({ collectionId, appId, admin: true });\r\n if (cancelled) return;\r\n const flag = cfg?._meta?.introDismissed?.[RT_KEY(recordType)];\r\n if (flag) setDismissed(true);\r\n } catch { /* ignore */ }\r\n })();\r\n return () => { cancelled = true; };\r\n }, [SL, collectionId, appId, recordType]);\r\n\r\n const dismiss = useCallback(async () => {\r\n setDismissed(true);\r\n try { localStorage.setItem(lsKey(appId, recordType), '1'); } catch { /* ignore */ }\r\n try {\r\n const cfg = await SL?.appConfiguration?.getConfig?.({ collectionId, appId, admin: true }).catch(() => ({}));\r\n const next = {\r\n ...(cfg ?? {}),\r\n _meta: {\r\n ...(cfg?._meta ?? {}),\r\n introDismissed: { ...(cfg?._meta?.introDismissed ?? {}), [RT_KEY(recordType)]: true },\r\n },\r\n };\r\n await SL?.appConfiguration?.setConfig?.({ collectionId, appId, admin: true, config: next });\r\n } catch { /* best-effort */ }\r\n }, [SL, collectionId, appId, recordType]);\r\n\r\n const undismiss = useCallback(() => {\r\n setDismissed(false);\r\n try { localStorage.removeItem(lsKey(appId, recordType)); } catch { /* ignore */ }\r\n }, [appId, recordType]);\r\n\r\n return { dismissed, dismiss, undismiss };\r\n};","import { useQuery } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\n\r\nexport interface UseScopeProbeArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n /** Force admin endpoint when fetching the collection (default true). */\r\n admin?: boolean;\r\n enabled?: boolean;\r\n}\r\n\r\n/**\r\n * Reports whether a collection has variants/batches enabled.\r\n *\r\n * Uses the canonical `Collection.variants` / `Collection.batches` boolean flags\r\n * from `SL.collection.get(collectionId)` (SDK ≥ 1.9). No more guessing by\r\n * probing list endpoints.\r\n */\r\nexport const useScopeProbe = ({ SL, collectionId, admin = true, enabled = true }: UseScopeProbeArgs) => {\r\n const query = useQuery({\r\n queryKey: ['records-admin', 'scope-probe', collectionId, admin],\r\n enabled: enabled && !!collectionId && !!SL?.collection?.get,\r\n staleTime: 5 * 60_000,\r\n queryFn: async () => {\r\n const c = await SL.collection.get(collectionId, admin);\r\n return {\r\n hasVariants: !!c?.variants,\r\n hasBatches: !!c?.batches,\r\n };\r\n },\r\n });\r\n\r\n return {\r\n hasVariants: query.data?.hasVariants ?? false,\r\n hasBatches: query.data?.hasBatches ?? false,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n };\r\n};","import { useEffect, useMemo, useRef } from 'react';\r\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\r\nimport type { RecordStatus, RecordSummary, SmartLinksSDK } from '../types';\r\nimport { buildRef, parseRef } from '../data/refs';\r\n\r\nconst LOG = '[RecordsAdmin/useFacetBrowse]';\r\n\r\ninterface FacetValueShape {\r\n key?: string;\r\n name?: string;\r\n}\r\n\r\ninterface FacetShape {\r\n key?: string;\r\n name?: string;\r\n values?: FacetValueShape[];\r\n}\r\n\r\nexport interface UseFacetBrowseArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n existing: RecordSummary[];\r\n search?: string;\r\n filter?: 'all' | RecordStatus;\r\n enabled?: boolean;\r\n}\r\n\r\nconst QK = ['records-admin', 'facet-browse'] as const;\r\n\r\nconst toScaffoldSummary = (facet: FacetShape, value: FacetValueShape): RecordSummary => {\r\n const facetKey = facet.key ?? '';\r\n const valueKey = value.key ?? '';\r\n const ref = buildRef({ facetId: facetKey, facetValue: valueKey });\r\n return {\r\n id: null,\r\n ref,\r\n scope: parseRef(ref),\r\n data: null,\r\n status: 'empty',\r\n label: value.name ?? valueKey ?? 'Untitled value',\r\n subtitle: facet.name ?? facetKey ?? undefined,\r\n };\r\n};\r\n\r\nexport const useFacetBrowse = ({\r\n SL,\r\n collectionId,\r\n existing,\r\n search = '',\r\n filter = 'all',\r\n enabled = true,\r\n}: UseFacetBrowseArgs) => {\r\n const queryClient = useQueryClient();\r\n\r\n // Pre-compute these for both the query gate and the logging effect below.\r\n // We must NOT call any other hooks between `useQueryClient` and `useQuery`\r\n // — doing so reorders hooks across renders and trips React's reducer.\r\n const hasAdminList = !!SL?.facets?.list;\r\n const hasPublicList = !!SL?.facets?.publicList;\r\n const hasAnyList = hasAdminList || hasPublicList;\r\n const queryEnabled = enabled && !!collectionId && hasAnyList;\r\n\r\n const query = useQuery({\r\n queryKey: [...QK, collectionId],\r\n enabled: queryEnabled,\r\n staleTime: 30_000,\r\n queryFn: async (): Promise<FacetShape[]> => {\r\n const t0 = performance.now();\r\n try {\r\n if (SL?.facets?.list) {\r\n console.info(`${LOG} → SL.facets.list(\"${collectionId}\", { includeValues: true })`);\r\n const res = await SL.facets.list(collectionId, { includeValues: true });\r\n const items: FacetShape[] = res?.items ?? [];\r\n console.info(\r\n `${LOG} ← SL.facets.list ok in ${Math.round(performance.now() - t0)}ms — ${items.length} facet(s)`,\r\n items,\r\n );\r\n return items;\r\n }\r\n if (SL?.facets?.publicList) {\r\n console.info(`${LOG} → SL.facets.publicList(\"${collectionId}\", { includeValues: true })`);\r\n const res = await SL.facets.publicList(collectionId, { includeValues: true });\r\n const items: FacetShape[] = res?.items ?? [];\r\n console.info(\r\n `${LOG} ← SL.facets.publicList ok in ${Math.round(performance.now() - t0)}ms — ${items.length} facet(s)`,\r\n items,\r\n );\r\n return items;\r\n }\r\n console.warn(`${LOG} queryFn ran but no facets API is available on SL`);\r\n return [];\r\n } catch (err) {\r\n console.error(`${LOG} ✖ facets fetch failed`, err);\r\n throw err;\r\n }\r\n },\r\n });\r\n\r\n // Diagnostic logging — placed AFTER `useQuery` so we never insert a hook\r\n // between the query client and the query itself.\r\n const lastLoggedRef = useRef<string>('');\r\n useEffect(() => {\r\n const signature = `${enabled}|${collectionId}|${hasAdminList}|${hasPublicList}`;\r\n if (signature === lastLoggedRef.current) return;\r\n lastLoggedRef.current = signature;\r\n if (!enabled) {\r\n console.info(`${LOG} skipped — enabled=false (shell not on facet tab yet)`);\r\n return;\r\n }\r\n if (!collectionId) {\r\n console.warn(`${LOG} skipped — no collectionId provided`);\r\n return;\r\n }\r\n if (!hasAnyList) {\r\n console.warn(\r\n `${LOG} skipped — SDK is missing both SL.facets.list and SL.facets.publicList. ` +\r\n `Update @proveanything/smartlinks (>=1.8) or check the SDK build.`,\r\n { facetsNamespace: SL?.facets ? Object.keys(SL.facets) : null },\r\n );\r\n return;\r\n }\r\n console.info(\r\n `${LOG} will fetch facets for collection \"${collectionId}\" via ` +\r\n `${hasAdminList ? 'SL.facets.list (admin)' : 'SL.facets.publicList (fallback)'}`,\r\n );\r\n }, [enabled, collectionId, hasAdminList, hasPublicList, hasAnyList, SL]);\r\n\r\n const mergedItems = useMemo(() => {\r\n const existingByRef = new Map(existing.map((item) => [item.ref, item]));\r\n const scaffolded = (query.data ?? []).flatMap((facet) =>\r\n (facet.values ?? [])\r\n .filter((value) => !!facet.key && !!value.key)\r\n .map((value) => {\r\n const scaffold = toScaffoldSummary(facet, value);\r\n return existingByRef.get(scaffold.ref) ?? scaffold;\r\n }),\r\n );\r\n\r\n const extras = existing.filter((item) => !scaffolded.some((scaffold) => scaffold.ref === item.ref));\r\n return [...scaffolded, ...extras];\r\n }, [existing, query.data]);\r\n\r\n const filteredItems = useMemo(() => {\r\n let next = mergedItems;\r\n if (filter !== 'all') next = next.filter((item) => item.status === filter);\r\n if (search.trim()) {\r\n const q = search.trim().toLowerCase();\r\n next = next.filter((item) => `${item.label} ${item.subtitle ?? ''} ${item.ref}`.toLowerCase().includes(q));\r\n }\r\n return next;\r\n }, [mergedItems, filter, search]);\r\n\r\n const counts = useMemo(() => ({\r\n all: mergedItems.length,\r\n configured: mergedItems.filter((item) => item.status === 'configured').length,\r\n partial: mergedItems.filter((item) => item.status === 'partial').length,\r\n empty: mergedItems.filter((item) => item.status === 'empty').length,\r\n }), [mergedItems]);\r\n\r\n const refetch = () => {\r\n queryClient.invalidateQueries({ queryKey: [...QK, collectionId] });\r\n };\r\n\r\n return {\r\n items: filteredItems,\r\n total: mergedItems.length,\r\n counts,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch,\r\n };\r\n};","// =============================================================================\r\n// useProductBrowse — Cursor-paginated product browser via SL.products.query.\r\n// Designed to scale to collections with millions of products: each page is a\r\n// thin Product list (id + name + sku + sortOrder), no record data is loaded\r\n// up-front. The shell pairs this with `useProductChildren` for drill-down.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport { useInfiniteQuery, useQueryClient, type InfiniteData } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\n\r\nexport interface ProductBrowseItem {\r\n /** Product id (used in refs as `product:<id>`). */\r\n id: string;\r\n /** Display name. */\r\n name: string;\r\n /** Optional subtitle. */\r\n sku?: string | null;\r\n /** Optional ordering hint. */\r\n sortOrder?: number | null;\r\n}\r\n\r\nexport interface UseProductBrowseArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n search?: string;\r\n /** Soft cap per page (default 50). */\r\n pageSize?: number;\r\n enabled?: boolean;\r\n /** Override admin flag if needed (default true). */\r\n admin?: boolean;\r\n}\r\n\r\nconst QK = ['records-admin', 'product-browse'] as const;\r\ntype PageParam = { offset: number; cursor: string | null };\r\n\r\ninterface ProductBrowsePage {\r\n items: ProductBrowseItem[];\r\n nextOffset: number;\r\n nextCursor: string | null;\r\n hasMore: boolean;\r\n total?: number;\r\n}\r\n\r\n/** Truncate Product objects to the few fields we actually display. */\r\nconst toBrowseItem = (p: any): ProductBrowseItem => ({\r\n id: p.id ?? p.productId ?? '',\r\n name: p.name ?? p.id ?? 'Untitled',\r\n sku: p.sku ?? null,\r\n sortOrder: p.sortOrder ?? null,\r\n});\r\n\r\n/**\r\n * Cursor-paginated product list backed by `SL.products.query`. When the SDK\r\n * returns a `nextCursor`, we use it; otherwise we fall back to offset-based\r\n * paging so the hook works against older SDKs or in-memory adapters too.\r\n */\r\nexport const useProductBrowse = (args: UseProductBrowseArgs) => {\r\n const { SL, collectionId, search = '', pageSize = 50, enabled = true, admin = true } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const queryKey = useMemo(\r\n () => [...QK, collectionId, search.trim(), pageSize, admin] as const,\r\n [collectionId, search, pageSize, admin],\r\n );\r\n\r\n const query = useInfiniteQuery<ProductBrowsePage, Error, InfiniteData<ProductBrowsePage>, typeof queryKey, PageParam>({\r\n queryKey,\r\n enabled: enabled && !!collectionId && !!(SL?.products?.query || SL?.product?.query || SL?.products?.list || SL?.product?.list),\r\n initialPageParam: { offset: 0, cursor: null as string | null },\r\n queryFn: async ({ pageParam }) => {\r\n const body: Record<string, unknown> = {\r\n page: { limit: pageSize, ...(pageParam.cursor ? { cursor: pageParam.cursor } : { offset: pageParam.offset }) },\r\n sort: [{ field: 'sortOrder', direction: 'asc' }, { field: 'name', direction: 'asc' }],\r\n };\r\n if (search.trim()) body.query = { search: search.trim() };\r\n\r\n let res: { items?: unknown[]; page?: { nextCursor?: string | null; hasMore?: boolean; total?: number } } | null = null;\r\n if (SL?.products?.query) {\r\n res = await SL.products.query(collectionId, body);\r\n } else if (SL?.product?.query) {\r\n res = await SL.product.query(collectionId, body, admin);\r\n } else {\r\n const legacy: any[] = SL?.products?.list\r\n ? await SL.products.list(collectionId, admin)\r\n : SL?.product?.list\r\n ? await SL.product.list(collectionId, admin)\r\n : [];\r\n const filteredLegacy = search.trim()\r\n ? legacy.filter((item: any) => `${item?.name ?? ''} ${item?.sku ?? ''} ${item?.id ?? ''}`.toLowerCase().includes(search.trim().toLowerCase()))\r\n : legacy;\r\n const pageItems = filteredLegacy.slice(pageParam.offset, pageParam.offset + pageSize);\r\n return {\r\n items: pageItems.map(toBrowseItem),\r\n nextOffset: pageParam.offset + pageItems.length,\r\n nextCursor: null,\r\n hasMore: pageParam.offset + pageItems.length < filteredLegacy.length,\r\n total: filteredLegacy.length,\r\n };\r\n }\r\n\r\n const items = (res?.items ?? []).map(toBrowseItem);\r\n const page = res?.page ?? {};\r\n return {\r\n items,\r\n nextOffset: pageParam.offset + items.length,\r\n nextCursor: page.nextCursor ?? null,\r\n hasMore: page.hasMore ?? items.length >= pageSize,\r\n total: page.total,\r\n };\r\n },\r\n getNextPageParam: (last) => {\r\n if (!last.hasMore) return undefined;\r\n if (last.nextCursor) return { offset: last.nextOffset, cursor: last.nextCursor };\r\n return { offset: last.nextOffset, cursor: null };\r\n },\r\n staleTime: 30_000,\r\n });\r\n\r\n const items = useMemo(\r\n () => query.data?.pages.flatMap((p: ProductBrowsePage) => p.items) ?? [],\r\n [query.data],\r\n );\r\n\r\n const refetch = () => queryClient.invalidateQueries({ queryKey: [...QK, collectionId] });\r\n\r\n return {\r\n items,\r\n total: query.data?.pages[query.data.pages.length - 1]?.total,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n hasNextPage: !!query.hasNextPage,\r\n isFetchingNextPage: query.isFetchingNextPage,\r\n fetchNextPage: query.fetchNextPage,\r\n refetch,\r\n };\r\n};","// =============================================================================\r\n// useProductChildren — Lazy-fetch variants & batches for ONE product.\r\n// Only fires when the relevant sub-tab is opened, never collection-wide.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\n\r\nexport interface ProductChildItem {\r\n /** Variant or batch id (the `<id>` part of `variant:<id>` / `batch:<id>`). */\r\n id: string;\r\n /** Display name. */\r\n name: string;\r\n /** Optional subtitle (sku, expiry, etc.). */\r\n subtitle?: string;\r\n}\r\n\r\nexport interface UseProductChildrenArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n productId: string | undefined;\r\n /** Which child kind to fetch. Hooks only fire when both productId and kind are set. */\r\n kind: 'variant' | 'batch' | null;\r\n enabled?: boolean;\r\n}\r\n\r\nconst QK = ['records-admin', 'product-children'] as const;\r\n\r\nconst variantToItem = (v: any): ProductChildItem => ({\r\n id: v.id ?? v.variantId ?? '',\r\n name: v.name ?? v.label ?? v.id ?? 'Untitled variant',\r\n subtitle: v.sku ?? v.size ?? undefined,\r\n});\r\n\r\nconst batchToItem = (b: any): ProductChildItem => ({\r\n id: b.id ?? b.batchId ?? '',\r\n name: b.name ?? b.id ?? 'Untitled batch',\r\n subtitle: b.expiryDate?.iso ?? b.expiry ?? b.lotCode ?? undefined,\r\n});\r\n\r\n/**\r\n * Lazy children loader. When `kind` is `null` or `productId` is missing the\r\n * underlying query is disabled, so opening the shell at collection level never\r\n * touches `variant.list` / `batch.list`.\r\n */\r\nexport const useProductChildren = (args: UseProductChildrenArgs) => {\r\n const { SL, collectionId, productId, kind, enabled = true } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const queryKey = useMemo(\r\n () => [...QK, collectionId, productId ?? null, kind] as const,\r\n [collectionId, productId, kind],\r\n );\r\n\r\n const query = useQuery({\r\n queryKey,\r\n enabled: enabled && !!collectionId && !!productId && !!kind,\r\n staleTime: 30_000,\r\n queryFn: async (): Promise<ProductChildItem[]> => {\r\n if (!productId || !kind) return [];\r\n if (kind === 'variant') {\r\n const res = await SL.variant.list(collectionId, productId);\r\n return (res ?? []).map(variantToItem);\r\n }\r\n const res = await SL.batch.list(collectionId, productId);\r\n return (res ?? []).map(batchToItem);\r\n },\r\n });\r\n\r\n const refetch = () => queryClient.invalidateQueries({\r\n queryKey: [...QK, collectionId, productId ?? null],\r\n });\r\n\r\n return {\r\n items: query.data ?? [],\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch,\r\n };\r\n};","// =============================================================================\r\n// useUnsavedGuard — Cross-context guard against losing unsaved edits.\r\n//\r\n// 1. Browser: `beforeunload` listener prompts on tab/window close.\r\n// 2. Iframe: posts `smartlinks:unsaved-changes` to `window.parent` so the\r\n// host platform can intercept its own navigation.\r\n// 3. App-level: exposes `confirmDiscard()` so app code (e.g. router\r\n// transitions, custom close buttons) can prompt manually.\r\n//\r\n// The hook is idempotent — multiple editors on a page can each call it; the\r\n// guard fires while ANY of them are dirty.\r\n// =============================================================================\r\nimport { useCallback, useEffect } from 'react';\r\n\r\nconst MESSAGE_TYPE = 'smartlinks:unsaved-changes' as const;\r\n\r\nexport interface UseUnsavedGuardArgs {\r\n /** Whether there are unsaved edits right now. */\r\n isDirty: boolean;\r\n /**\r\n * Optional human-friendly label (e.g. recordType). Posted to the parent\r\n * frame so the host can describe what's unsaved.\r\n */\r\n label?: string;\r\n /**\r\n * Optional async confirm impl. Defaults to `window.confirm`. Apps can pass\r\n * a custom dialog (e.g. a shadcn AlertDialog promise wrapper).\r\n */\r\n confirm?: (message: string) => boolean | Promise<boolean>;\r\n /**\r\n * Disable the browser-level `beforeunload` listener (e.g. when running\r\n * inside a host that handles it already). Default false.\r\n */\r\n disableBeforeUnload?: boolean;\r\n /**\r\n * Disable the parent-frame `postMessage` notification. Default false.\r\n */\r\n disableParentMessage?: boolean;\r\n}\r\n\r\n/**\r\n * Tracks unsaved state and wires up the browser/iframe guards. Returns a\r\n * `confirmDiscard` helper apps can `await` from their own navigation code.\r\n */\r\nexport function useUnsavedGuard({\r\n isDirty,\r\n label,\r\n confirm,\r\n disableBeforeUnload = false,\r\n disableParentMessage = false,\r\n}: UseUnsavedGuardArgs) {\r\n // ---------------------------------------------------------------------------\r\n // 1. Browser tab/window close\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (disableBeforeUnload || !isDirty || typeof window === 'undefined') return;\r\n const handler = (e: BeforeUnloadEvent) => {\r\n // Modern browsers ignore the custom string but require preventDefault\r\n // + setting returnValue to trigger the native prompt.\r\n e.preventDefault();\r\n e.returnValue = '';\r\n return '';\r\n };\r\n window.addEventListener('beforeunload', handler);\r\n return () => window.removeEventListener('beforeunload', handler);\r\n }, [isDirty, disableBeforeUnload]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // 2. Iframe: notify parent so the host platform can guard its navigation\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (disableParentMessage || typeof window === 'undefined') return;\r\n if (window.parent === window) return; // not in iframe\r\n try {\r\n window.parent.postMessage({\r\n type: MESSAGE_TYPE,\r\n isDirty,\r\n label: label ?? null,\r\n }, '*');\r\n } catch {\r\n // Parent in cross-origin context or sandboxed — fail silently.\r\n }\r\n }, [isDirty, label, disableParentMessage]);\r\n\r\n // Always emit a final \"clean\" message on unmount so the parent can drop\r\n // any retained dirty state. (Only when we previously sent dirty messages.)\r\n useEffect(() => {\r\n if (disableParentMessage || typeof window === 'undefined') return;\r\n if (window.parent === window) return;\r\n return () => {\r\n try {\r\n window.parent.postMessage({ type: MESSAGE_TYPE, isDirty: false, label: label ?? null }, '*');\r\n } catch { /* noop */ }\r\n };\r\n }, [disableParentMessage, label]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // 3. App-level helper\r\n // ---------------------------------------------------------------------------\r\n const confirmDiscard = useCallback(\r\n async (message?: string): Promise<boolean> => {\r\n if (!isDirty) return true;\r\n const msg = message ?? 'You have unsaved changes. Discard them?';\r\n if (confirm) {\r\n try { return !!(await confirm(msg)); }\r\n catch { return false; }\r\n }\r\n if (typeof window === 'undefined') return true;\r\n return window.confirm(msg);\r\n },\r\n [isDirty, confirm],\r\n );\r\n\r\n return { confirmDiscard };\r\n}","// =============================================================================\r\n// useDirtyNavigation — Wraps navigation intents (selecting a different\r\n// record/scope/tab) in a dirty-aware policy.\r\n//\r\n// Strategies:\r\n// - `prompt`: ask before discarding unsaved changes\r\n// - `autosave`: save quietly, then navigate\r\n// - `keep`: navigate freely; the editor preserves dirty values per-ref\r\n// =============================================================================\r\nimport { useCallback } from 'react';\r\n\r\nexport type DirtyStrategy = 'prompt' | 'autosave' | 'keep';\r\n\r\nexport interface UseDirtyNavigationArgs {\r\n strategy: DirtyStrategy;\r\n isDirty: boolean;\r\n /** Persist current edits. Resolves when the SDK call completes. */\r\n save: () => void | Promise<void>;\r\n /** Discard local edits to the saved snapshot. */\r\n reset: () => void;\r\n /**\r\n * Confirm impl: returns `'save' | 'discard' | 'cancel'`. Defaults to a\r\n * `window.confirm` fallback (Save = OK, Discard = Cancel, no Cancel option).\r\n */\r\n confirm?: (i18n?: NavConfirmI18n) => Promise<'save' | 'discard' | 'cancel'>;\r\n i18n?: NavConfirmI18n;\r\n}\r\n\r\nexport interface NavConfirmI18n {\r\n title?: string;\r\n body?: string;\r\n save?: string;\r\n discard?: string;\r\n cancel?: string;\r\n}\r\n\r\nconst fallbackConfirm = async (i18n?: NavConfirmI18n): Promise<'save' | 'discard' | 'cancel'> => {\r\n if (typeof window === 'undefined') return 'discard';\r\n const msg = `${i18n?.title ?? 'Unsaved changes'}\\n\\n${i18n?.body ?? 'OK to save & continue, Cancel to discard.'}`;\r\n return window.confirm(msg) ? 'save' : 'discard';\r\n};\r\n\r\n/**\r\n * Returns `runWithGuard(action)` — call it instead of executing the\r\n * navigation directly. The guard handles dirty-state policy and only calls\r\n * `action()` when it's safe to proceed.\r\n */\r\nexport const useDirtyNavigation = ({\r\n strategy, isDirty, save, reset, confirm, i18n,\r\n}: UseDirtyNavigationArgs) => {\r\n const runWithGuard = useCallback(\r\n async (action: () => void): Promise<boolean> => {\r\n if (!isDirty || strategy === 'keep') {\r\n action();\r\n return true;\r\n }\r\n if (strategy === 'autosave') {\r\n try { await save(); }\r\n catch { /* If save fails, fall through to prompt so user can decide. */\r\n const fallback = await (confirm ?? fallbackConfirm)(i18n);\r\n if (fallback === 'cancel') return false;\r\n if (fallback === 'discard') reset();\r\n }\r\n action();\r\n return true;\r\n }\r\n // prompt\r\n const choice = await (confirm ?? fallbackConfirm)(i18n);\r\n if (choice === 'cancel') return false;\r\n if (choice === 'save') {\r\n try { await save(); }\r\n catch { return false; }\r\n } else {\r\n reset();\r\n }\r\n action();\r\n return true;\r\n },\r\n [strategy, isDirty, save, reset, confirm, i18n],\r\n );\r\n\r\n return { runWithGuard };\r\n};","// =============================================================================\r\n// ScopeTabs — pill-style segmented control for the top-level scopes.\r\n// v0.4: scope icon + label + count badge, active accent, hover lift.\r\n// =============================================================================\r\nimport type { ScopeKind } from '../types';\r\nimport { DEFAULT_ICONS, type RecordsAdminIcons } from '../shell/icons';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nconst LABELS: Record<ScopeKind, string> = {\r\n product: 'Products',\r\n facet: 'Shared',\r\n variant: 'Variants',\r\n batch: 'Batches',\r\n};\r\n\r\ninterface Props {\r\n scopes: ScopeKind[];\r\n active: ScopeKind;\r\n onChange: (s: ScopeKind) => void;\r\n /** When true, tabs render disabled (used while collection flags are loading). */\r\n loading?: boolean;\r\n /** Optional per-scope counts displayed as tiny badges. */\r\n counts?: Partial<Record<ScopeKind, number>>;\r\n /** Override icons used per scope. Falls back to DEFAULT_ICONS.scope. */\r\n icons?: RecordsAdminIcons['scope'];\r\n}\r\n\r\nexport const ScopeTabs = ({\r\n scopes, active, onChange, loading = false, counts, icons,\r\n}: Props) => {\r\n const iconMap = icons ?? DEFAULT_ICONS.scope;\r\n return (\r\n <div role=\"tablist\" className=\"ra-tabs\" aria-label=\"Record scope\">\r\n {scopes.map((s) => {\r\n const Icon = iconMap[s] ?? DEFAULT_ICONS.scope[s];\r\n const isActive = active === s;\r\n const count = counts?.[s];\r\n return (\r\n <button\r\n key={s}\r\n type=\"button\"\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n onClick={() => onChange(s)}\r\n disabled={loading}\r\n className=\"ra-tab\"\r\n >\r\n <Icon className={cn('ra-tab-icon w-3.5 h-3.5', loading && 'animate-pulse')} />\r\n <span>{LABELS[s]}</span>\r\n {typeof count === 'number' && count > 0 && (\r\n <span className=\"ra-tab-count\">{count}</span>\r\n )}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n","import { cn } from '../../../utils/cn';\r\nimport type { RecordStatus, RecordsAdminI18n } from '../types';\r\n\r\ninterface Props {\r\n value: 'all' | RecordStatus;\r\n onChange: (v: 'all' | RecordStatus) => void;\r\n counts: { all: number; configured: number; partial: number; empty: number };\r\n i18n: RecordsAdminI18n;\r\n}\r\n\r\nexport const StatusFilterPills = ({ value, onChange, counts, i18n }: Props) => {\r\n const opts: Array<{ key: 'all' | RecordStatus; label: string; count: number }> = [\r\n { key: 'all', label: i18n.filterAll, count: counts.all },\r\n { key: 'configured', label: i18n.filterConfigured, count: counts.configured },\r\n { key: 'partial', label: i18n.filterPartial, count: counts.partial },\r\n { key: 'empty', label: i18n.filterEmpty, count: counts.empty },\r\n ];\r\n return (\r\n <div className=\"flex flex-wrap gap-1.5\">\r\n {opts.map((o) => {\r\n const active = value === o.key;\r\n return (\r\n <button\r\n key={o.key}\r\n type=\"button\"\r\n onClick={() => onChange(o.key)}\r\n className={cn(\r\n 'text-xs px-2.5 py-1 rounded-full border transition-colors',\r\n active ? 'font-medium' : 'opacity-80 hover:opacity-100',\r\n )}\r\n style={{\r\n background: active ? 'hsl(var(--ra-accent) / 0.12)' : 'hsl(var(--ra-muted))',\r\n borderColor: active ? 'hsl(var(--ra-accent) / 0.5)' : 'hsl(var(--ra-border))',\r\n color: 'hsl(var(--ra-text))',\r\n }}\r\n >\r\n {o.label}\r\n <span className=\"ml-1.5 opacity-60\">{o.count}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};","import type { RecordSource, RecordStatus } from '../types';\r\nimport { cn } from '../../../utils/cn';\r\n\r\ninterface Props {\r\n source?: RecordSource;\r\n status?: RecordStatus;\r\n className?: string;\r\n}\r\n\r\n/** Emerald = own data, amber = inherited, muted = empty */\r\nexport const StatusDot = ({ source, status, className }: Props) => {\r\n let cls = 'ra-status-missing';\r\n if (source === 'self' || status === 'configured') cls = 'ra-status-own';\r\n else if (source === 'inherited' || status === 'partial') cls = 'ra-status-shared';\r\n return <span className={cn('ra-status-dot', cls, className)} aria-hidden=\"true\" />;\r\n};","// =============================================================================\r\n// DefaultRecordRow — used by `list` & `compact` presentations.\r\n// v0.4: scope-aware icon, status dot, optional inheritance chip, hover slot.\r\n// =============================================================================\r\nimport type { RecordSummary } from '../types';\r\nimport type { RecordSlotContext } from '../types/shell';\r\nimport { StatusDot } from './StatusDot';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nexport interface DefaultRecordRowProps {\r\n record: RecordSummary;\r\n ctx: RecordSlotContext;\r\n /** Drop the icon + subtitle (used by the `compact` preset). */\r\n compact?: boolean;\r\n}\r\n\r\nexport const DefaultRecordRow = ({ record, ctx, compact = false }: DefaultRecordRowProps) => {\r\n const { selected, onSelect, isDirty } = ctx;\r\n // The scope kind drives the leading icon.\r\n const ScopeIcon = (record.scope.kind && record.scope.kind !== 'collection')\r\n ? DEFAULT_ICONS.scope[record.scope.kind]\r\n : DEFAULT_ICONS.scope.product;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={onSelect}\r\n data-selected={selected ? 'true' : 'false'}\r\n className={cn('ra-row', compact && 'ra-row-compact')}\r\n style={compact ? { paddingTop: '0.4rem', paddingBottom: '0.4rem' } : undefined}\r\n >\r\n {!compact && (\r\n <span className=\"ra-row-icon\" aria-hidden=\"true\">\r\n <ScopeIcon className=\"w-3.5 h-3.5\" />\r\n </span>\r\n )}\r\n <div className=\"ra-row-body\">\r\n <div className=\"ra-row-title\">{record.label}</div>\r\n {!compact && record.subtitle && (\r\n <div className=\"ra-row-sub\">{record.subtitle}</div>\r\n )}\r\n </div>\r\n {/* status dot — keeps the existing semantic so apps can still target it */}\r\n <StatusDot status={record.status} />\r\n {record.badges?.slice(0, 1).map((b, i) => (\r\n <span key={`${b.label}-${i}`} className=\"ra-chip\" data-tone=\"muted\">\r\n {b.label}\r\n </span>\r\n ))}\r\n {isDirty && (\r\n <span\r\n title=\"Unsaved changes\"\r\n aria-label=\"Unsaved changes\"\r\n className=\"ra-status-dot ra-status-shared shrink-0\"\r\n />\r\n )}\r\n </button>\r\n );\r\n};\r\n","// =============================================================================\r\n// DefaultRecordCard — used by `grid` & `gallery` presentations.\r\n// v0.4: layered surface, hover lift, status + dirty indicators.\r\n// =============================================================================\r\nimport type { RecordSummary } from '../types';\r\nimport type { RecordSlotContext } from '../types/shell';\r\nimport { StatusDot } from './StatusDot';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nexport interface DefaultRecordCardProps {\r\n record: RecordSummary;\r\n ctx: RecordSlotContext;\r\n /** `grid` → 1:1, `gallery` → 16:9 with denser meta. Default `grid`. */\r\n variant?: 'grid' | 'gallery';\r\n}\r\n\r\nconst initials = (s: string) =>\r\n s.split(/\\s+/).filter(Boolean).slice(0, 2)\r\n .map((p) => p[0]?.toUpperCase() ?? '').join('') || '?';\r\n\r\nexport const DefaultRecordCard = ({ record, ctx, variant = 'grid' }: DefaultRecordCardProps) => {\r\n const { selected, onSelect, isDirty } = ctx;\r\n const aspect = variant === 'gallery' ? 'aspect-video' : 'aspect-square';\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={onSelect}\r\n className={cn(\r\n 'group flex flex-col text-left rounded-md overflow-hidden border ra-card-hover',\r\n selected && 'ring-2',\r\n )}\r\n style={{\r\n background: 'hsl(var(--ra-surface))',\r\n borderColor: selected ? 'var(--ra-row-active-bd)' : 'hsl(var(--ra-border))',\r\n boxShadow: selected\r\n ? `0 0 0 2px hsl(var(--ra-accent) / 0.45), var(--ra-card-shadow)`\r\n : 'var(--ra-card-shadow)',\r\n }}\r\n >\r\n <div\r\n className={cn(aspect, 'relative w-full flex items-center justify-center overflow-hidden')}\r\n style={{ background: 'hsl(var(--ra-muted))' }}\r\n >\r\n {record.thumbnail ? (\r\n <img\r\n src={record.thumbnail}\r\n alt=\"\"\r\n loading=\"lazy\"\r\n className=\"w-full h-full object-cover\"\r\n />\r\n ) : (\r\n <span\r\n className=\"text-2xl ra-display\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n {initials(record.label)}\r\n </span>\r\n )}\r\n <div className=\"absolute top-1.5 left-1.5\">\r\n <StatusDot status={record.status} />\r\n </div>\r\n {isDirty && (\r\n <span\r\n title=\"Unsaved changes\"\r\n aria-label=\"Unsaved changes\"\r\n className=\"ra-status-dot ra-status-shared absolute top-1.5 right-1.5\"\r\n />\r\n )}\r\n </div>\r\n <div className=\"p-2.5 min-w-0\">\r\n <div className=\"ra-row-title\">{record.label}</div>\r\n {variant === 'gallery' && record.subtitle && (\r\n <div className=\"ra-row-sub\">{record.subtitle}</div>\r\n )}\r\n {record.badges && record.badges.length > 0 && (\r\n <div className=\"flex gap-1 mt-1.5 flex-wrap\">\r\n {record.badges.slice(0, 3).map((b, i) => (\r\n <span key={`${b.label}-${i}`} className=\"ra-chip\" data-tone=\"muted\">\r\n {b.label}\r\n </span>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n </button>\r\n );\r\n};\r\n","// =============================================================================\r\n// RecordList — presentation-aware container for the browse rail.\r\n// v0.4: optional `groupBy` enables accordion-style grouping.\r\n// =============================================================================\r\nimport { useMemo, useState, type ReactNode } from 'react';\r\nimport type { RecordSummary, RecordPresentation } from '../types';\r\nimport type { RecordSlotContext } from '../types/shell';\r\nimport { DefaultRecordRow } from './DefaultRecordRow';\r\nimport { DefaultRecordCard } from './DefaultRecordCard';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\n\r\ninterface Props {\r\n items: RecordSummary[];\r\n selectedRef?: string;\r\n onSelect: (item: RecordSummary) => void;\r\n /** When set, the matching row gets a small \"unsaved\" indicator. */\r\n dirtyRef?: string;\r\n /** Layout. Defaults to `list` for full back-compat. */\r\n presentation?: RecordPresentation;\r\n /** Optional override for `list` / `compact` rows. */\r\n renderListRow?: (record: RecordSummary, ctx: RecordSlotContext) => ReactNode;\r\n /** Optional override for `grid` / `gallery` cards. */\r\n renderCard?: (record: RecordSummary, ctx: RecordSlotContext) => ReactNode;\r\n /** Optional grouping function. Returning null buckets the row under \"Other\". */\r\n groupBy?: (record: RecordSummary) => { key: string; label: string; icon?: ReactNode } | null;\r\n}\r\n\r\ninterface GroupBucket {\r\n key: string;\r\n label: string;\r\n icon?: ReactNode;\r\n items: RecordSummary[];\r\n}\r\n\r\nexport const RecordList = ({\r\n items, selectedRef, onSelect, dirtyRef,\r\n presentation = 'list', renderListRow, renderCard, groupBy,\r\n}: Props) => {\r\n const buildCtx = (item: RecordSummary): RecordSlotContext => ({\r\n selected: item.ref === selectedRef,\r\n onSelect: () => onSelect(item),\r\n isDirty: !!dirtyRef && item.ref === dirtyRef,\r\n });\r\n\r\n const groups: GroupBucket[] | null = useMemo(() => {\r\n if (!groupBy) return null;\r\n const buckets = new Map<string, GroupBucket>();\r\n const orderedKeys: string[] = [];\r\n for (const item of items) {\r\n const g = groupBy(item) ?? { key: '__other', label: 'Other' };\r\n if (!buckets.has(g.key)) {\r\n buckets.set(g.key, { ...g, items: [] });\r\n orderedKeys.push(g.key);\r\n }\r\n buckets.get(g.key)!.items.push(item);\r\n }\r\n return orderedKeys.map((k) => buckets.get(k)!);\r\n }, [items, groupBy]);\r\n\r\n const renderItems = (rows: RecordSummary[]) => {\r\n if (presentation === 'grid' || presentation === 'gallery') {\r\n const minColPx = presentation === 'gallery' ? 200 : 120;\r\n return (\r\n <div\r\n className=\"grid gap-2 p-2\"\r\n style={{ gridTemplateColumns: `repeat(auto-fill, minmax(${minColPx}px, 1fr))` }}\r\n >\r\n {rows.map((item) => {\r\n const ctx = buildCtx(item);\r\n return (\r\n <div key={item.ref}>\r\n {renderCard\r\n ? renderCard(item, ctx)\r\n : <DefaultRecordCard record={item} ctx={ctx} variant={presentation} />}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n }\r\n const compact = presentation === 'compact';\r\n return (\r\n <ul>\r\n {rows.map((item) => {\r\n const ctx = buildCtx(item);\r\n return (\r\n <li key={item.ref}>\r\n {renderListRow\r\n ? renderListRow(item, ctx)\r\n : <DefaultRecordRow record={item} ctx={ctx} compact={compact} />}\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n );\r\n };\r\n\r\n if (groups) {\r\n return <GroupedList groups={groups} renderItems={renderItems} />;\r\n }\r\n\r\n return renderItems(items);\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Accordion grouping\r\n// ---------------------------------------------------------------------------\r\nconst GroupedList = ({\r\n groups, renderItems,\r\n}: { groups: GroupBucket[]; renderItems: (rows: RecordSummary[]) => ReactNode }) => {\r\n const Chevron = DEFAULT_ICONS.group.chevron;\r\n const [open, setOpen] = useState<Record<string, boolean>>(() =>\r\n Object.fromEntries(groups.map((g) => [g.key, true])),\r\n );\r\n return (\r\n <>\r\n {groups.map((g) => {\r\n const isOpen = open[g.key] !== false;\r\n return (\r\n <section key={g.key} className=\"ra-group\" data-open={isOpen ? 'true' : 'false'}>\r\n <button\r\n type=\"button\"\r\n className=\"ra-group-summary\"\r\n onClick={() => setOpen((s) => ({ ...s, [g.key]: !isOpen }))}\r\n aria-expanded={isOpen}\r\n >\r\n <Chevron className=\"ra-group-chevron w-3 h-3\" />\r\n {g.icon}\r\n <span className=\"ra-group-name\">{g.label}</span>\r\n <span className=\"ra-group-count\">{g.items.length}</span>\r\n </button>\r\n <div className=\"ra-group-body\">{renderItems(g.items)}</div>\r\n </section>\r\n );\r\n })}\r\n </>\r\n );\r\n};\r\n\r\n// Backward-compat named exports — same component for all scopes.\r\nexport const ProductList = RecordList;\r\nexport const FacetList = RecordList;\r\nexport const VariantList = RecordList;\r\nexport const BatchList = RecordList;\r\n","// =============================================================================\r\n// EmptyStates — friendly empty / loading / error states for the records rail.\r\n// v0.4: large soft icon, display-weight title, two-line body, optional CTA pair.\r\n// =============================================================================\r\nimport type { ReactNode } from 'react';\r\nimport { Inbox } from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\n\r\nexport interface EmptyStateProps {\r\n title: string;\r\n body?: ReactNode;\r\n /** Primary call-to-action — typically \"+ Add your first …\". */\r\n action?: ReactNode;\r\n /** Optional secondary action — typically \"Import from CSV\". */\r\n secondaryAction?: ReactNode;\r\n /** Lucide icon component. Defaults to `Inbox`. */\r\n icon?: LucideIcon;\r\n}\r\n\r\nexport const EmptyState = ({\r\n title, body, action, secondaryAction, icon: Icon = Inbox,\r\n}: EmptyStateProps) => (\r\n <div className=\"ra-empty\">\r\n <div className=\"ra-empty-icon\">\r\n <Icon className=\"w-6 h-6\" />\r\n </div>\r\n <h3 className=\"ra-empty-title\">{title}</h3>\r\n {body && <p className=\"ra-empty-body\">{body}</p>}\r\n {(action || secondaryAction) && (\r\n <div className=\"ra-empty-actions\">\r\n {action}\r\n {secondaryAction}\r\n </div>\r\n )}\r\n </div>\r\n);\r\n\r\nexport const LoadingState = () => (\r\n <div className=\"p-3 space-y-2\">\r\n {[0, 1, 2, 3].map((i) => (\r\n <div\r\n key={i}\r\n className=\"h-11 rounded-md animate-pulse\"\r\n style={{ background: 'hsl(var(--ra-muted))' }}\r\n />\r\n ))}\r\n </div>\r\n);\r\n\r\nexport const ErrorState = ({ error }: { error: Error }) => (\r\n <div className=\"ra-empty\">\r\n <div\r\n className=\"ra-empty-icon\"\r\n style={{ background: 'hsl(var(--ra-danger) / 0.10)', color: 'hsl(var(--ra-danger))' }}\r\n >\r\n !\r\n </div>\r\n <h3 className=\"ra-empty-title\">Something went wrong</h3>\r\n <p className=\"ra-empty-body\">{error.message || 'Please try again.'}</p>\r\n </div>\r\n);\r\n","// =============================================================================\r\n// PresentationSwitcher — segmented control above the rail when more than one\r\n// presentation is enabled. Persistence is handled by the shell.\r\n// =============================================================================\r\nimport { LayoutGrid, List, Image as ImageIcon, Rows3 } from 'lucide-react';\r\nimport type { RecordPresentation } from '../types';\r\nimport type { RecordsAdminI18n } from '../types';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nconst ICONS: Record<RecordPresentation, typeof List> = {\r\n list: List,\r\n grid: LayoutGrid,\r\n gallery: ImageIcon,\r\n compact: Rows3,\r\n};\r\n\r\nconst labelFor = (p: RecordPresentation, i18n: RecordsAdminI18n): string => {\r\n switch (p) {\r\n case 'list': return i18n.presentationList;\r\n case 'grid': return i18n.presentationGrid;\r\n case 'gallery': return i18n.presentationGallery;\r\n case 'compact': return i18n.presentationCompact;\r\n }\r\n};\r\n\r\nexport interface PresentationSwitcherProps {\r\n options: RecordPresentation[];\r\n value: RecordPresentation;\r\n onChange: (next: RecordPresentation) => void;\r\n i18n: RecordsAdminI18n;\r\n}\r\n\r\nexport const PresentationSwitcher = ({ options, value, onChange, i18n }: PresentationSwitcherProps) => {\r\n if (options.length < 2) return null;\r\n return (\r\n <div\r\n className=\"inline-flex rounded-md border overflow-hidden\"\r\n style={{ borderColor: 'hsl(var(--ra-border))' }}\r\n role=\"tablist\"\r\n aria-label=\"View\"\r\n >\r\n {options.map((opt) => {\r\n const Icon = ICONS[opt];\r\n const active = opt === value;\r\n return (\r\n <button\r\n key={opt}\r\n type=\"button\"\r\n role=\"tab\"\r\n aria-selected={active}\r\n title={labelFor(opt, i18n)}\r\n aria-label={labelFor(opt, i18n)}\r\n onClick={() => onChange(opt)}\r\n className={cn(\r\n 'flex items-center justify-center w-7 h-7 transition-colors',\r\n active\r\n ? 'bg-[hsl(var(--ra-text))] text-[hsl(var(--ra-surface))]'\r\n : 'hover:bg-[hsl(var(--ra-muted))]',\r\n )}\r\n >\r\n <Icon className=\"w-3.5 h-3.5\" />\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// usePresentationPref — persists the chosen presentation per app/recordType\r\n// in localStorage. Falls back to the supplied default when nothing is stored\r\n// or the stored value isn't in the allowed set.\r\n// =============================================================================\r\nimport { useCallback, useEffect, useState } from 'react';\r\nimport type { RecordPresentation } from '../types';\r\n\r\nconst KEY_PREFIX = 'smartlinks-ui:records-admin:presentation';\r\n\r\nconst safeRead = (key: string): string | null => {\r\n try { return typeof window === 'undefined' ? null : window.localStorage.getItem(key); }\r\n catch { return null; }\r\n};\r\nconst safeWrite = (key: string, val: string): void => {\r\n try { if (typeof window !== 'undefined') window.localStorage.setItem(key, val); }\r\n catch { /* ignore quota / privacy errors */ }\r\n};\r\n\r\nexport function usePresentationPref(args: {\r\n appId: string;\r\n recordType?: string;\r\n options: RecordPresentation[];\r\n defaultValue: RecordPresentation;\r\n}): [RecordPresentation, (next: RecordPresentation) => void] {\r\n const { appId, recordType, options, defaultValue } = args;\r\n const key = `${KEY_PREFIX}:${appId}:${recordType ?? '_default'}`;\r\n\r\n const initial = (): RecordPresentation => {\r\n const stored = safeRead(key) as RecordPresentation | null;\r\n if (stored && options.includes(stored)) return stored;\r\n return options.includes(defaultValue) ? defaultValue : options[0];\r\n };\r\n\r\n const [value, setValue] = useState<RecordPresentation>(initial);\r\n\r\n // Re-sync if `options` shrinks and excludes the current value.\r\n useEffect(() => {\r\n if (!options.includes(value)) setValue(options[0]);\r\n }, [options, value]);\r\n\r\n const set = useCallback((next: RecordPresentation) => {\r\n setValue(next);\r\n safeWrite(key, next);\r\n }, [key]);\r\n\r\n return [value, set];\r\n}","import { ChevronRight } from 'lucide-react';\r\nimport type { ParsedRef } from '../types';\r\n\r\ninterface Segment { label: string; key: string }\r\n\r\nconst segmentsFor = (s: ParsedRef): Segment[] => {\r\n const out: Segment[] = [];\r\n if (s.facetId) out.push({ label: s.facetValue ? `${s.facetId}: ${s.facetValue}` : `Facet: ${s.facetId}`, key: 'facet' });\r\n if (s.productId) out.push({ label: `Product: ${s.productId}`, key: 'product' });\r\n if (s.variantId) out.push({ label: `Variant: ${s.variantId}`, key: 'variant' });\r\n if (s.batchId) out.push({ label: `Batch: ${s.batchId}`, key: 'batch' });\r\n return out;\r\n};\r\n\r\nexport const ScopeBreadcrumb = ({ scope }: { scope: ParsedRef }) => {\r\n const segs = segmentsFor(scope);\r\n if (segs.length === 0) return null;\r\n return (\r\n <nav aria-label=\"Scope\" className=\"flex items-center gap-1 text-xs flex-wrap\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n {segs.map((s, i) => (\r\n <span key={s.key} className=\"flex items-center gap-1\">\r\n {i > 0 && <ChevronRight className=\"w-3 h-3 opacity-50\" />}\r\n <span style={{ color: 'hsl(var(--ra-text))' }}>{s.label}</span>\r\n </span>\r\n ))}\r\n </nav>\r\n );\r\n};","// =============================================================================\r\n// BulkActionsMenu — Apply to many / Copy from / Clear / Import / Export.\r\n// v0.4: each action gets a Lucide icon, destructive items separated and tinted.\r\n// =============================================================================\r\nimport { useState, useRef, useEffect } from 'react';\r\nimport {\r\n ChevronDown, Copy, Eraser, Layers,\r\n Upload, Download, Trash2,\r\n} from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport type { RecordsAdminI18n } from '../types';\r\n\r\ninterface Props {\r\n i18n: RecordsAdminI18n;\r\n onApplyToMany?: () => void;\r\n onCopyFrom?: () => void;\r\n onClearMany?: () => void;\r\n onImportCsv?: () => void;\r\n onExportCsv?: () => void;\r\n}\r\n\r\ninterface ItemDef {\r\n key: string;\r\n label: string;\r\n onClick: () => void;\r\n icon: LucideIcon;\r\n tone?: 'danger';\r\n divider?: boolean;\r\n}\r\n\r\nexport const BulkActionsMenu = ({\r\n i18n, onApplyToMany, onCopyFrom, onClearMany, onImportCsv, onExportCsv,\r\n}: Props) => {\r\n const [open, setOpen] = useState(false);\r\n const ref = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n const onDocClick = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\r\n };\r\n document.addEventListener('mousedown', onDocClick);\r\n return () => document.removeEventListener('mousedown', onDocClick);\r\n }, [open]);\r\n\r\n const items: ItemDef[] = [\r\n onApplyToMany && { key: 'apply', label: i18n.applyToMany, onClick: onApplyToMany, icon: Layers },\r\n onCopyFrom && { key: 'copy', label: i18n.copyFrom, onClick: onCopyFrom, icon: Copy },\r\n onImportCsv && { key: 'imp', label: i18n.importCsv, onClick: onImportCsv, icon: Upload, divider: true },\r\n onExportCsv && { key: 'exp', label: i18n.exportCsv, onClick: onExportCsv, icon: Download },\r\n onClearMany && { key: 'clear', label: i18n.clear, onClick: onClearMany, icon: Eraser, tone: 'danger' as const, divider: true },\r\n ].filter(Boolean) as ItemDef[];\r\n\r\n if (items.length === 0) return null;\r\n\r\n return (\r\n <div className=\"relative\" ref={ref}>\r\n <button\r\n type=\"button\"\r\n onClick={() => setOpen((v) => !v)}\r\n className=\"ra-btn\"\r\n aria-haspopup=\"menu\"\r\n aria-expanded={open}\r\n >\r\n {i18n.bulkActions}\r\n <ChevronDown className=\"w-3.5 h-3.5 opacity-70\" />\r\n </button>\r\n {open && (\r\n <div className=\"absolute right-0 mt-1.5 ra-bulk-menu\" role=\"menu\">\r\n {items.map((it, i) => {\r\n const Icon = it.icon;\r\n return (\r\n <div key={it.key}>\r\n {it.divider && i > 0 && <div className=\"ra-bulk-divider\" />}\r\n <button\r\n type=\"button\"\r\n role=\"menuitem\"\r\n data-tone={it.tone}\r\n onClick={() => { setOpen(false); it.onClick(); }}\r\n className=\"ra-bulk-item\"\r\n >\r\n <Icon className=\"w-3.5 h-3.5 opacity-80\" />\r\n {it.label}\r\n {it.tone === 'danger' && <Trash2 className=\"w-3 h-3 ml-auto opacity-50\" />}\r\n </button>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// DeleteButton — Inline two-step confirm for record deletion. First click\r\n// flips into \"Confirm delete\" in destructive style; auto-reverts after\r\n// `revertMs` if the user doesn't confirm. Apps can intercept via\r\n// `onBeforeDelete` to swap in a heavier modal when stakes are high.\r\n// =============================================================================\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { Trash2 } from 'lucide-react';\r\n\r\nexport interface DeleteButtonProps {\r\n /** Performs the delete. Should resolve when the SDK call completes. */\r\n onConfirm: () => void | Promise<void>;\r\n /**\r\n * Optional async pre-check — return false to abort BEFORE the inline\r\n * confirm flips. Lets apps run their own modal for high-stakes deletes.\r\n */\r\n onBeforeDelete?: () => boolean | Promise<boolean>;\r\n /** Default label (idle state). */\r\n label?: string;\r\n /** Confirm-state label. */\r\n confirmLabel?: string;\r\n /** Auto-revert timeout in ms (default 3000). */\r\n revertMs?: number;\r\n disabled?: boolean;\r\n}\r\n\r\nexport const DeleteButton = ({\r\n onConfirm,\r\n onBeforeDelete,\r\n label = 'Delete record',\r\n confirmLabel = 'Confirm delete',\r\n revertMs = 3000,\r\n disabled,\r\n}: DeleteButtonProps) => {\r\n const [armed, setArmed] = useState(false);\r\n const [busy, setBusy] = useState(false);\r\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n const clearTimer = () => {\r\n if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = null; }\r\n };\r\n useEffect(() => () => clearTimer(), []);\r\n\r\n const arm = async () => {\r\n if (onBeforeDelete) {\r\n const ok = await onBeforeDelete();\r\n if (!ok) return; // App-level modal said no.\r\n }\r\n setArmed(true);\r\n clearTimer();\r\n timerRef.current = setTimeout(() => setArmed(false), revertMs);\r\n };\r\n\r\n const fire = async () => {\r\n clearTimer();\r\n setBusy(true);\r\n try {\r\n await onConfirm();\r\n } finally {\r\n setBusy(false);\r\n setArmed(false);\r\n }\r\n };\r\n\r\n if (armed) {\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={fire}\r\n disabled={busy}\r\n className=\"text-xs px-3 py-1.5 rounded-md font-medium transition-colors flex items-center gap-1.5 disabled:opacity-60\"\r\n style={{\r\n background: 'hsl(var(--ra-danger, 0 70% 45%))',\r\n color: 'hsl(0 0% 100%)',\r\n }}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n {busy ? '…' : confirmLabel}\r\n </button>\r\n );\r\n }\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={arm}\r\n disabled={disabled}\r\n className=\"text-xs px-3 py-1.5 rounded-md border transition-colors hover:bg-[hsl(var(--ra-muted))] disabled:opacity-40 flex items-center gap-1.5\"\r\n style={{\r\n borderColor: 'hsl(var(--ra-border))',\r\n color: 'hsl(var(--ra-danger, var(--ra-text)))',\r\n }}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n {label}\r\n </button>\r\n );\r\n};","import type { ReactNode } from 'react';\r\nimport type { EditorContext, RecordsAdminI18n } from '../types';\r\nimport { ScopeBreadcrumb } from '../shell/ScopeBreadcrumb';\r\nimport { BulkActionsMenu } from './BulkActionsMenu';\r\nimport { StatusDot } from '../browser/StatusDot';\r\nimport { DeleteButton } from './DeleteButton';\r\n\r\ninterface Props<T> {\r\n ctx: EditorContext<T>;\r\n i18n: RecordsAdminI18n;\r\n children: ReactNode;\r\n preview?: ReactNode;\r\n bulkActions?: React.ComponentProps<typeof BulkActionsMenu>;\r\n /** Extra slot rendered in the footer between the danger actions and Save. */\r\n footerExtra?: ReactNode;\r\n /** Optional pre-delete hook (see DeleteButton). */\r\n onBeforeDelete?: () => boolean | Promise<boolean>;\r\n}\r\n\r\nexport function RecordEditor<T>({\r\n ctx, i18n, children, preview, bulkActions, footerExtra, onBeforeDelete,\r\n}: Props<T>) {\r\n const sourceLabel = ctx.source === 'self' ? 'Own' : ctx.source === 'inherited' ? 'Inherited' : 'New';\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <header\r\n className=\"sticky top-0 z-10 px-5 py-3 border-b flex items-center justify-between gap-3\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}\r\n >\r\n <div className=\"min-w-0 flex-1\">\r\n <ScopeBreadcrumb scope={ctx.scope} />\r\n <div className=\"flex items-center gap-1.5 mt-1\">\r\n <StatusDot source={ctx.source} />\r\n <span className=\"text-[10px] uppercase tracking-wide\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n {sourceLabel}\r\n </span>\r\n {ctx.isDirty && (\r\n <span\r\n className=\"ml-2 flex items-center gap-1 text-[10px] uppercase tracking-wide\"\r\n style={{ color: 'hsl(var(--ra-accent))' }}\r\n >\r\n <span className=\"ra-status-dot ra-status-shared\" aria-hidden=\"true\" />\r\n {i18n.unsavedBadge ?? 'Unsaved'}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n {bulkActions && <BulkActionsMenu {...bulkActions} i18n={i18n} />}\r\n </header>\r\n <div className=\"flex-1 overflow-y-auto px-5 py-4\">\r\n {children}\r\n {preview}\r\n </div>\r\n <footer\r\n className=\"sticky bottom-0 px-5 py-3 border-t flex items-center justify-between gap-2\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}\r\n >\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={ctx.reset}\r\n disabled={!ctx.isDirty || !!ctx.isSaving}\r\n className=\"text-xs px-3 py-1.5 rounded-md border transition-opacity disabled:opacity-40 hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n {i18n.discard}\r\n </button>\r\n {ctx.canRemove && (\r\n <DeleteButton\r\n onConfirm={() => ctx.remove()}\r\n onBeforeDelete={onBeforeDelete}\r\n label={i18n.delete}\r\n confirmLabel={i18n.confirmDelete}\r\n />\r\n )}\r\n {footerExtra}\r\n {ctx.saveError != null && !ctx.isSaving && (\r\n <span\r\n className=\"text-[10px] uppercase tracking-wide\"\r\n style={{ color: 'hsl(var(--ra-danger, 0 70% 45%))' }}\r\n role=\"alert\"\r\n >\r\n {i18n.saveError ?? 'Save failed'}\r\n </span>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={() => { void ctx.save().catch(() => { /* surfaced via ctx.saveError */ }); }}\r\n disabled={!ctx.isDirty || !!ctx.isSaving}\r\n className=\"text-xs px-3 py-1.5 rounded-md font-medium transition-opacity disabled:opacity-40\"\r\n style={{ background: 'hsl(var(--ra-accent))', color: 'hsl(var(--ra-surface))' }}\r\n >\r\n {ctx.isSaving ? (i18n.saving ?? 'Saving…') : i18n.save}\r\n </button>\r\n </footer>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// ProductDrillDown — Sub-navigation that appears in the editor pane when a\r\n// product is selected. Lets admins jump between the product itself and its\r\n// variants/batches without leaving the product context. Children are loaded\r\n// lazily (per product) by the parent shell, so opening at collection level\r\n// never triggers a collection-wide variant/batch fetch.\r\n// =============================================================================\r\nimport type { ReactNode } from 'react';\r\nimport { Box, Layers, Package } from 'lucide-react';\r\nimport { cn } from '../../../utils/cn';\r\nimport type { ProductChildItem } from '../hooks/useProductChildren';\r\n\r\nexport type DrillTab = 'product' | 'variant' | 'batch';\r\n\r\ninterface Props {\r\n productLabel: string;\r\n /** Which child types are available on the collection. */\r\n showVariants: boolean;\r\n showBatches: boolean;\r\n active: DrillTab;\r\n onChange: (tab: DrillTab) => void;\r\n /** Currently selected child id (variant or batch), if any. */\r\n selectedChildId?: string;\r\n onSelectChild: (id: string) => void;\r\n variants: ProductChildItem[];\r\n batches: ProductChildItem[];\r\n variantsLoading: boolean;\r\n batchesLoading: boolean;\r\n /** Editor body rendered to the right of the picker. */\r\n children: ReactNode;\r\n}\r\n\r\nconst TAB_META: Record<DrillTab, { icon: typeof Box; label: string }> = {\r\n product: { icon: Box, label: 'Product' },\r\n variant: { icon: Layers, label: 'Variants' },\r\n batch: { icon: Package, label: 'Batches' },\r\n};\r\n\r\nexport const ProductDrillDown = ({\r\n productLabel, showVariants, showBatches, active, onChange,\r\n selectedChildId, onSelectChild,\r\n variants, batches, variantsLoading, batchesLoading,\r\n children,\r\n}: Props) => {\r\n const tabs: DrillTab[] = ['product'];\r\n if (showVariants) tabs.push('variant');\r\n if (showBatches) tabs.push('batch');\r\n\r\n // Children list shown for the active tab (only variants/batches use it).\r\n const childList = active === 'variant' ? variants : active === 'batch' ? batches : [];\r\n const childLoading = active === 'variant' ? variantsLoading : active === 'batch' ? batchesLoading : false;\r\n const childEmptyLabel = active === 'variant' ? 'No variants' : 'No batches';\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Drill-down tab strip */}\r\n <div\r\n className=\"flex items-center gap-1 px-4 pt-3 border-b\"\r\n style={{ borderColor: 'hsl(var(--ra-border))' }}\r\n >\r\n {tabs.map((t) => {\r\n const meta = TAB_META[t];\r\n const Icon = meta.icon;\r\n const isActive = active === t;\r\n const label = t === 'product' ? productLabel : meta.label;\r\n return (\r\n <button\r\n key={t}\r\n type=\"button\"\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n onClick={() => onChange(t)}\r\n className={cn(\r\n 'flex items-center gap-1.5 px-3 py-2 text-xs border-b-2 -mb-px transition-colors',\r\n isActive ? 'font-medium' : 'opacity-60 hover:opacity-100',\r\n )}\r\n style={{\r\n borderColor: isActive ? 'hsl(var(--ra-accent))' : 'transparent',\r\n color: 'hsl(var(--ra-text))',\r\n }}\r\n >\r\n <Icon className=\"w-3.5 h-3.5\" />\r\n <span className=\"truncate max-w-[160px]\">{label}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n {/* Body: optional child picker on the left, editor on the right */}\r\n <div className=\"flex-1 min-h-0 grid\" style={{\r\n gridTemplateColumns: active === 'product' ? '1fr' : 'minmax(200px, 240px) 1fr',\r\n }}>\r\n {active !== 'product' && (\r\n <aside\r\n className=\"border-r overflow-y-auto\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}\r\n >\r\n {childLoading && (\r\n <div className=\"p-3 space-y-2\">\r\n {[0, 1, 2].map((i) => (\r\n <div key={i} className=\"h-9 rounded animate-pulse\" style={{ background: 'hsl(var(--ra-muted))' }} />\r\n ))}\r\n </div>\r\n )}\r\n {!childLoading && childList.length === 0 && (\r\n <div className=\"p-4 text-xs\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n {childEmptyLabel}\r\n </div>\r\n )}\r\n {!childLoading && childList.length > 0 && (\r\n <ul className=\"divide-y\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n {childList.map((c) => {\r\n const isActive = c.id === selectedChildId;\r\n return (\r\n <li key={c.id}>\r\n <button\r\n type=\"button\"\r\n onClick={() => onSelectChild(c.id)}\r\n className={cn(\r\n 'w-full text-left px-3 py-2 transition-colors hover:bg-[hsl(var(--ra-muted))]',\r\n isActive && 'ra-row-active',\r\n )}\r\n >\r\n <div className=\"text-sm truncate\" style={{ color: 'hsl(var(--ra-text))' }}>{c.name}</div>\r\n {c.subtitle && (\r\n <div className=\"text-xs truncate\" style={{ color: 'hsl(var(--ra-muted-text))' }}>{c.subtitle}</div>\r\n )}\r\n </button>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n )}\r\n </aside>\r\n )}\r\n <div className=\"overflow-hidden\">{children}</div>\r\n </div>\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// PreviewPane — Chrome around an app-supplied preview. Handles the four\r\n// surface modes (inline / side / tab / drawer) and hosts the optional\r\n// PreviewScopePicker. Apps stay focused on their preview content.\r\n// =============================================================================\r\nimport { useState, type ReactNode } from 'react';\r\nimport { X, Eye } from 'lucide-react';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nexport type PreviewMode = 'inline' | 'side' | 'tab' | 'drawer';\r\n\r\ninterface CommonProps {\r\n /** App-rendered preview body. */\r\n children: ReactNode;\r\n /** Optional scope picker rendered in the chrome header. */\r\n scopePicker?: ReactNode;\r\n /** Header label (defaults to \"Preview\"). */\r\n label?: string;\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// Shared header — used by side/drawer/tab variants.\r\n// -----------------------------------------------------------------------------\r\nconst PreviewHeader = ({\r\n label, scopePicker, onClose,\r\n}: { label: string; scopePicker?: ReactNode; onClose?: () => void }) => (\r\n <header\r\n className=\"px-4 py-2.5 border-b flex items-center justify-between gap-3 flex-wrap\"\r\n style={{\r\n borderColor: 'hsl(var(--ra-border))',\r\n background: 'hsl(var(--ra-surface))',\r\n }}\r\n >\r\n <div\r\n className=\"flex items-center gap-1.5 text-[10px] uppercase tracking-wide\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n <Eye className=\"w-3 h-3\" />\r\n {label}\r\n </div>\r\n {scopePicker}\r\n {onClose && (\r\n <button\r\n type=\"button\"\r\n onClick={onClose}\r\n aria-label=\"Close preview\"\r\n className=\"p-1 rounded hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n <X className=\"w-3.5 h-3.5\" />\r\n </button>\r\n )}\r\n </header>\r\n);\r\n\r\n// -----------------------------------------------------------------------------\r\n// inline — bottom of the editor body. Same as legacy ResolvedPreview.\r\n// -----------------------------------------------------------------------------\r\nexport const InlinePreview = ({ children, scopePicker, label = 'Preview' }: CommonProps) => (\r\n <div className=\"mt-4 pt-4 border-t\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n <div className=\"flex items-center justify-between gap-2 mb-2 flex-wrap\">\r\n <div\r\n className=\"text-[10px] uppercase tracking-wide\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n {label}\r\n </div>\r\n {scopePicker}\r\n </div>\r\n {children}\r\n </div>\r\n);\r\n\r\n// -----------------------------------------------------------------------------\r\n// side — fixed-width pane to the right of the editor. The shell composes the\r\n// outer grid; this component just renders the header + body.\r\n// -----------------------------------------------------------------------------\r\nexport const SidePreview = ({ children, scopePicker, label = 'Preview' }: CommonProps) => (\r\n <div className=\"ra-preview-rail\">\r\n <header className=\"ra-preview-rail-header\">\r\n <div className=\"ra-preview-rail-title\">\r\n <Eye className=\"w-3 h-3\" />\r\n {label}\r\n </div>\r\n {scopePicker && <div className=\"ml-auto\">{scopePicker}</div>}\r\n </header>\r\n <div className=\"ra-preview-rail-body\">{children}</div>\r\n </div>\r\n);\r\n\r\n// -----------------------------------------------------------------------------\r\n// tab — Editor / Preview siblings inside the same column. Caller passes the\r\n// editor + preview as children in a `{ editor, preview }` slot pattern.\r\n// -----------------------------------------------------------------------------\r\nexport interface TabbedPreviewProps {\r\n editor: ReactNode;\r\n preview: ReactNode;\r\n scopePicker?: ReactNode;\r\n /** Initial active tab (default `editor`). */\r\n defaultTab?: 'editor' | 'preview';\r\n i18n?: { editor?: string; preview?: string };\r\n}\r\n\r\nexport const TabbedPreview = ({\r\n editor, preview, scopePicker, defaultTab = 'editor', i18n,\r\n}: TabbedPreviewProps) => {\r\n const [tab, setTab] = useState<'editor' | 'preview'>(defaultTab);\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <div\r\n className=\"flex items-center gap-1 px-4 pt-3 border-b\"\r\n style={{ borderColor: 'hsl(var(--ra-border))' }}\r\n >\r\n {(['editor', 'preview'] as const).map((t) => {\r\n const isActive = tab === t;\r\n const lbl = t === 'editor'\r\n ? (i18n?.editor ?? 'Editor')\r\n : (i18n?.preview ?? 'Preview');\r\n return (\r\n <button\r\n key={t}\r\n type=\"button\"\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n onClick={() => setTab(t)}\r\n className={cn(\r\n 'px-3 py-2 text-xs border-b-2 -mb-px transition-colors',\r\n isActive ? 'font-medium' : 'opacity-60 hover:opacity-100',\r\n )}\r\n style={{\r\n borderColor: isActive ? 'hsl(var(--ra-accent))' : 'transparent',\r\n color: 'hsl(var(--ra-text))',\r\n }}\r\n >\r\n {lbl}\r\n </button>\r\n );\r\n })}\r\n {tab === 'preview' && scopePicker && (\r\n <div className=\"ml-auto pb-1\">{scopePicker}</div>\r\n )}\r\n </div>\r\n <div className=\"flex-1 min-h-0\">\r\n {tab === 'editor' ? editor : (\r\n <div className=\"h-full overflow-y-auto p-4\">{preview}</div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n// -----------------------------------------------------------------------------\r\n// drawer — slides in from the right, overlaying the editor.\r\n// -----------------------------------------------------------------------------\r\nexport interface DrawerPreviewProps extends CommonProps {\r\n open: boolean;\r\n onClose: () => void;\r\n /** Drawer width (default 420). */\r\n width?: number;\r\n}\r\n\r\nexport const DrawerPreview = ({\r\n open, onClose, children, scopePicker, label = 'Preview', width = 420,\r\n}: DrawerPreviewProps) => {\r\n if (!open) return null;\r\n return (\r\n <>\r\n <div\r\n className=\"absolute inset-0 z-10 transition-opacity\"\r\n style={{ background: 'hsl(0 0% 0% / 0.25)' }}\r\n onClick={onClose}\r\n aria-hidden=\"true\"\r\n />\r\n <aside\r\n className=\"absolute top-0 right-0 bottom-0 z-20 flex flex-col shadow-xl\"\r\n style={{\r\n width,\r\n background: 'hsl(var(--ra-bg, var(--ra-surface)))',\r\n borderLeft: '1px solid hsl(var(--ra-border))',\r\n }}\r\n role=\"dialog\"\r\n aria-label={label}\r\n >\r\n <PreviewHeader label={label} scopePicker={scopePicker} onClose={onClose} />\r\n <div className=\"flex-1 overflow-y-auto p-4\">{children}</div>\r\n </aside>\r\n </>\r\n );\r\n};\r\n\r\n// -----------------------------------------------------------------------------\r\n// Toggle button — used by the editor footer to summon a closed drawer.\r\n// -----------------------------------------------------------------------------\r\nexport const PreviewToggleButton = ({\r\n onClick, label = 'Open preview',\r\n}: { onClick: () => void; label?: string }) => (\r\n <button\r\n type=\"button\"\r\n onClick={onClick}\r\n className=\"text-xs px-3 py-1.5 rounded-md border transition-colors hover:bg-[hsl(var(--ra-muted))] flex items-center gap-1.5\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n <Eye className=\"w-3.5 h-3.5\" />\r\n {label}\r\n </button>\r\n);","// =============================================================================\r\n// PreviewScopePicker — Lets admins preview as a different scope than they're\r\n// editing. E.g. edit a facet-level recipe, preview as Product X to see how it\r\n// cascades. Lazy-loaded children scoped to the picked product.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport type { ParsedRef, SmartLinksSDK } from '../types';\r\nimport { useProductBrowse } from '../hooks/useProductBrowse';\r\nimport { useProductChildren } from '../hooks/useProductChildren';\r\nimport { Eye } from 'lucide-react';\r\n\r\nexport interface PreviewScopePickerProps {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n /** The scope currently being edited — used as the \"Same as edited\" default. */\r\n editingScope: ParsedRef;\r\n /** The current preview scope. */\r\n value: ParsedRef;\r\n onChange: (next: ParsedRef) => void;\r\n /** Are variants/batches available for drill-down. */\r\n showVariants: boolean;\r\n showBatches: boolean;\r\n /** i18n strings (uses defaults if omitted). */\r\n i18n?: { previewAs?: string; previewAsDefault?: string };\r\n}\r\n\r\nconst SELECT_CLS =\r\n 'text-xs px-2 py-1 rounded-md border bg-transparent focus:outline-none focus:ring-1';\r\n\r\nexport const PreviewScopePicker = ({\r\n SL, collectionId, editingScope, value, onChange,\r\n showVariants, showBatches, i18n,\r\n}: PreviewScopePickerProps) => {\r\n const products = useProductBrowse({ SL, collectionId, pageSize: 100 });\r\n const variants = useProductChildren({\r\n SL, collectionId, productId: value.productId,\r\n kind: showVariants ? 'variant' : null,\r\n });\r\n const batches = useProductChildren({\r\n SL, collectionId, productId: value.productId,\r\n kind: showBatches ? 'batch' : null,\r\n });\r\n\r\n const isDefault = useMemo(\r\n () => value.raw === editingScope.raw,\r\n [value.raw, editingScope.raw],\r\n );\r\n\r\n const selectStyle = {\r\n borderColor: 'hsl(var(--ra-border))',\r\n color: 'hsl(var(--ra-text))',\r\n };\r\n\r\n return (\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span\r\n className=\"flex items-center gap-1 text-[10px] uppercase tracking-wide\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n <Eye className=\"w-3 h-3\" />\r\n {i18n?.previewAs ?? 'Preview as'}\r\n </span>\r\n\r\n {/* Reset to \"same as edited\" */}\r\n {!isDefault && (\r\n <button\r\n type=\"button\"\r\n onClick={() => onChange(editingScope)}\r\n className=\"text-[10px] px-2 py-1 rounded-md border hover:bg-[hsl(var(--ra-muted))]\"\r\n style={selectStyle}\r\n >\r\n ↺ {i18n?.previewAsDefault ?? 'Same as edited'}\r\n </button>\r\n )}\r\n\r\n {/* Product picker */}\r\n <select\r\n className={SELECT_CLS}\r\n style={selectStyle}\r\n value={value.productId ?? ''}\r\n onChange={(e) => {\r\n const productId = e.target.value || undefined;\r\n onChange({\r\n ...value,\r\n productId,\r\n // Clear variant/batch when switching products.\r\n variantId: undefined,\r\n batchId: undefined,\r\n raw: productId ? `product:${productId}` : '',\r\n });\r\n }}\r\n >\r\n <option value=\"\">— Any product —</option>\r\n {products.items.map((p) => (\r\n <option key={p.id} value={p.id}>{p.name}</option>\r\n ))}\r\n </select>\r\n\r\n {/* Variant picker (only when product selected and variants supported) */}\r\n {showVariants && value.productId && variants.items.length > 0 && (\r\n <select\r\n className={SELECT_CLS}\r\n style={selectStyle}\r\n value={value.variantId ?? ''}\r\n onChange={(e) => {\r\n const variantId = e.target.value || undefined;\r\n onChange({\r\n ...value,\r\n variantId,\r\n batchId: undefined,\r\n raw: variantId ? `product:${value.productId}/variant:${variantId}` : `product:${value.productId}`,\r\n });\r\n }}\r\n >\r\n <option value=\"\">— Any variant —</option>\r\n {variants.items.map((v) => (\r\n <option key={v.id} value={v.id}>{v.name}</option>\r\n ))}\r\n </select>\r\n )}\r\n\r\n {/* Batch picker */}\r\n {showBatches && value.productId && batches.items.length > 0 && (\r\n <select\r\n className={SELECT_CLS}\r\n style={selectStyle}\r\n value={value.batchId ?? ''}\r\n onChange={(e) => {\r\n const batchId = e.target.value || undefined;\r\n onChange({\r\n ...value,\r\n batchId,\r\n raw: batchId ? `product:${value.productId}/batch:${batchId}` : `product:${value.productId}`,\r\n });\r\n }}\r\n >\r\n <option value=\"\">— Any batch —</option>\r\n {batches.items.map((b) => (\r\n <option key={b.id} value={b.id}>{b.name}</option>\r\n ))}\r\n </select>\r\n )}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// IntroCard — soft tinted onboarding banner with tone variants.\r\n// v0.4: lightbulb icon, title, body, optional learn-more, dismiss X.\r\n// =============================================================================\r\nimport { X, Lightbulb, CheckCircle2, AlertTriangle, Info } from 'lucide-react';\r\nimport type { ReactNode } from 'react';\r\n\r\nexport type IntroTone = 'info' | 'success' | 'warning';\r\n\r\ninterface Props {\r\n title: string;\r\n body: ReactNode;\r\n onDismiss: () => void;\r\n /** Visual tone — controls icon and surface tint. */\r\n tone?: IntroTone;\r\n /** Optional \"Learn more\" link or button rendered inline after the body. */\r\n action?: ReactNode;\r\n}\r\n\r\nconst TONE_ICON = {\r\n info: Lightbulb,\r\n success: CheckCircle2,\r\n warning: AlertTriangle,\r\n} as const;\r\n\r\nexport const IntroCard = ({ title, body, onDismiss, tone = 'info', action }: Props) => {\r\n const Icon = TONE_ICON[tone] ?? Info;\r\n return (\r\n <div className=\"ra-intro\" data-tone={tone} role=\"note\">\r\n <div className=\"ra-intro-icon\">\r\n <Icon className=\"w-4 h-4\" />\r\n </div>\r\n <div className=\"ra-intro-body\">\r\n <h4 className=\"ra-intro-title\">{title}</h4>\r\n <div className=\"ra-intro-text\">\r\n {body}\r\n {action && <span className=\"ml-1.5\">{action}</span>}\r\n </div>\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={onDismiss}\r\n aria-label=\"Dismiss\"\r\n className=\"ra-intro-dismiss\"\r\n >\r\n <X className=\"w-3.5 h-3.5\" />\r\n </button>\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// UtilityRow — quiet metadata strip above the shell body.\r\n// v0.4: shows the slug + \"How {label} works\" reopen link, lighter chrome.\r\n// =============================================================================\r\nimport { HelpCircle } from 'lucide-react';\r\n\r\ninterface Props {\r\n label: string;\r\n introHidden: boolean;\r\n onShowIntro?: () => void;\r\n}\r\n\r\nexport const UtilityRow = ({ label, introHidden, onShowIntro }: Props) => {\r\n if (!introHidden || !onShowIntro) return null;\r\n return (\r\n <div\r\n className=\"flex items-center justify-end gap-2 text-xs\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n <button\r\n type=\"button\"\r\n onClick={onShowIntro}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n style={{ padding: '0.25rem 0.55rem', fontSize: '0.7rem' }}\r\n >\r\n <HelpCircle className=\"w-3 h-3\" />\r\n How {label.toLowerCase()} works\r\n </button>\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// RecordsAdmin — ShellHeader (v0.4)\r\n//\r\n// Branded header card rendered at the top of `RecordsAdminShell`. Provides:\r\n// - Contextual icon (explicit `headerIcon` or registry fallback)\r\n// - Display-weight title + muted subtitle\r\n// - Right-aligned action slot (typically primary \"+ New\" + secondary controls)\r\n// - Optional per-scope counts strip\r\n// =============================================================================\r\nimport { createElement, type ReactNode } from 'react';\r\nimport { pickHeaderIcon, type RecordsAdminIcons } from './icons';\r\n\r\nexport interface ShellHeaderProps {\r\n title: string;\r\n subtitle?: string;\r\n headerIcon?: ReactNode;\r\n headerActions?: ReactNode;\r\n showStats?: boolean;\r\n showHeaderIcon?: boolean;\r\n recordType?: string;\r\n icons: RecordsAdminIcons;\r\n stats?: { products?: number; shared?: number };\r\n /** Fully custom items — when provided, replace the built-in Shared/Products counts. */\r\n statsItems?: Array<{ label: string; value: string | number }>;\r\n /** Optional title rendered above the stats items. */\r\n statsTitle?: string;\r\n /** Optional icon rendered alongside `statsTitle`. */\r\n statsIcon?: ReactNode;\r\n}\r\n\r\nexport function ShellHeader({\r\n title, subtitle, headerIcon, headerActions, showStats = false,\r\n showHeaderIcon = true,\r\n recordType, icons, stats, statsItems, statsTitle, statsIcon,\r\n}: ShellHeaderProps) {\r\n // Resolve the header icon: explicit prop wins; otherwise look up in registry.\r\n // Skip entirely when showHeaderIcon is false.\r\n let iconNode: ReactNode = null;\r\n if (showHeaderIcon) {\r\n if (headerIcon) {\r\n iconNode = headerIcon;\r\n } else {\r\n const Icon = pickHeaderIcon(icons, recordType);\r\n iconNode = createElement(Icon, { className: 'w-4 h-4', 'aria-hidden': true });\r\n }\r\n }\r\n\r\n // Resolve stats items. Custom `statsItems` always wins. Otherwise fall back\r\n // to the built-in Shared/Products pair, but only when there is at least one\r\n // non-zero value — a fresh app shouldn't render \"0 Shared 0 Products\".\r\n const resolvedItems: Array<{ label: string; value: string | number }> = (() => {\r\n if (!showStats) return [];\r\n if (statsItems && statsItems.length > 0) return statsItems;\r\n const items: Array<{ label: string; value: string | number }> = [];\r\n if (typeof stats?.shared === 'number' && stats.shared > 0) {\r\n items.push({ label: 'Shared', value: stats.shared });\r\n }\r\n if (typeof stats?.products === 'number' && stats.products > 0) {\r\n items.push({ label: 'Products', value: stats.products });\r\n }\r\n return items;\r\n })();\r\n const hasStats = resolvedItems.length > 0;\r\n const hasStatsHeading = !!(statsTitle || statsIcon);\r\n\r\n return (\r\n <header className=\"ra-header\">\r\n <div className=\"ra-header__main\">\r\n {iconNode ? (\r\n <div className=\"ra-header-icon\" aria-hidden=\"true\">\r\n {iconNode}\r\n </div>\r\n ) : null}\r\n <div className=\"ra-header-text\">\r\n <h1 className=\"ra-header-title\">{title}</h1>\r\n {subtitle ? <p className=\"ra-header-subtitle\">{subtitle}</p> : null}\r\n </div>\r\n </div>\r\n <div className=\"ra-header-aside\">\r\n {hasStats ? (\r\n <div\r\n className={`ra-header-stats${hasStatsHeading ? ' ra-header-stats--titled' : ''}`}\r\n role=\"group\"\r\n aria-label={statsTitle ?? 'Record counts'}\r\n >\r\n {hasStatsHeading ? (\r\n <div className=\"ra-stats-heading\">\r\n {statsIcon ? (\r\n <span className=\"ra-stats-heading-icon\" aria-hidden=\"true\">{statsIcon}</span>\r\n ) : null}\r\n {statsTitle ? <span className=\"ra-stats-heading-label\">{statsTitle}</span> : null}\r\n </div>\r\n ) : null}\r\n <div className=\"ra-stats-items\">\r\n {resolvedItems.map((item, idx) => (\r\n <span key={`${item.label}-${idx}`} style={{ display: 'contents' }}>\r\n {idx > 0 && <span className=\"ra-stat-divider\" aria-hidden=\"true\" />}\r\n <span className=\"ra-stat\">\r\n <span className=\"ra-stat-value\">{item.value}</span>\r\n <span className=\"ra-stat-label\">{item.label}</span>\r\n </span>\r\n </span>\r\n ))}\r\n </div>\r\n </div>\r\n ) : null}\r\n {headerActions ? <div className=\"ra-header-actions\">{headerActions}</div> : null}\r\n </div>\r\n </header>\r\n );\r\n}","// =============================================================================\r\n// CSV import / export — minimal RFC4180-ish round-trip (no quoted newlines)\r\n// =============================================================================\r\nimport type { CsvSchema, RecordSummary } from '../types';\r\nimport type { RecordsCtx } from './records';\r\nimport { upsertRecord } from './records';\r\nimport { parseRef } from './refs';\r\nimport { parsedRefToScope } from './scopeBridge';\r\n\r\nexport interface ImportReport {\r\n total: number;\r\n saved: number;\r\n failed: number;\r\n errorRows: Array<{ row: number; error: string }>;\r\n /** Annotated CSV ready for download (input + `error` column). */\r\n annotatedCsv: string;\r\n}\r\n\r\nconst escapeCell = (s: string): string => {\r\n if (/[\",\\n]/.test(s)) return `\"${s.replace(/\"/g, '\"\"')}\"`;\r\n return s;\r\n};\r\n\r\nconst parseLine = (line: string): string[] => {\r\n const out: string[] = [];\r\n let cur = '';\r\n let inQuotes = false;\r\n for (let i = 0; i < line.length; i += 1) {\r\n const ch = line[i];\r\n if (inQuotes) {\r\n if (ch === '\"' && line[i + 1] === '\"') { cur += '\"'; i += 1; }\r\n else if (ch === '\"') inQuotes = false;\r\n else cur += ch;\r\n } else if (ch === '\"') inQuotes = true;\r\n else if (ch === ',') { out.push(cur); cur = ''; }\r\n else cur += ch;\r\n }\r\n out.push(cur);\r\n return out;\r\n};\r\n\r\nexport const exportCsv = <T,>(\r\n records: RecordSummary<T>[],\r\n schema: CsvSchema<T>,\r\n): Blob => {\r\n const headers = ['ref', ...schema.columns.map((c) => c.header)];\r\n const rows = records\r\n .filter((r) => r.data != null)\r\n .map((r) => [r.ref, ...schema.columns.map((c) => c.toCell(r.data as T))]);\r\n const csv = [headers, ...rows]\r\n .map((row) => row.map((cell) => escapeCell(String(cell ?? ''))).join(','))\r\n .join('\\n');\r\n return new Blob([csv], { type: 'text/csv;charset=utf-8' });\r\n};\r\n\r\nexport const importCsv = async <T,>(\r\n file: File,\r\n schema: CsvSchema<T>,\r\n ctx: RecordsCtx,\r\n): Promise<ImportReport> => {\r\n const text = await file.text();\r\n const lines = text.split(/\\r?\\n/).filter((l) => l.length > 0);\r\n if (lines.length === 0) {\r\n return { total: 0, saved: 0, failed: 0, errorRows: [], annotatedCsv: '' };\r\n }\r\n const headers = parseLine(lines[0]);\r\n const refIdx = headers.indexOf('ref');\r\n const colMap = schema.columns.map((c) => ({ col: c, idx: headers.indexOf(c.header) }));\r\n\r\n const errorRows: Array<{ row: number; error: string }> = [];\r\n let saved = 0;\r\n for (let i = 1; i < lines.length; i += 1) {\r\n const cells = parseLine(lines[i]);\r\n const ref = refIdx >= 0 ? cells[refIdx] : '';\r\n if (!ref) {\r\n errorRows.push({ row: i, error: 'Missing ref' });\r\n continue;\r\n }\r\n const data: Record<string, unknown> = {};\r\n for (const { col, idx } of colMap) {\r\n if (idx < 0) continue;\r\n try { data[col.key] = col.fromCell(cells[idx] ?? ''); }\r\n catch (e) { errorRows.push({ row: i, error: (e as Error).message }); continue; }\r\n }\r\n const validation = schema.validate?.(data);\r\n if (validation) { errorRows.push({ row: i, error: validation }); continue; }\r\n try {\r\n // eslint-disable-next-line no-await-in-loop\r\n await upsertRecord<T>(ctx, {\r\n ref,\r\n scope: parsedRefToScope(parseRef(ref)),\r\n data: data as T,\r\n });\r\n saved += 1;\r\n } catch (e) {\r\n errorRows.push({ row: i, error: (e as Error).message });\r\n }\r\n }\r\n\r\n const annotatedHeaders = [...headers, 'error'];\r\n const annotatedRows = lines.slice(1).map((line, idx) => {\r\n const err = errorRows.find((er) => er.row === idx + 1);\r\n const cells = parseLine(line);\r\n while (cells.length < headers.length) cells.push('');\r\n cells.push(err?.error ?? '');\r\n return cells.map(escapeCell).join(',');\r\n });\r\n const annotatedCsv = [annotatedHeaders.join(','), ...annotatedRows].join('\\n');\r\n\r\n return {\r\n total: lines.length - 1,\r\n saved,\r\n failed: errorRows.length,\r\n errorRows,\r\n annotatedCsv,\r\n };\r\n};\r\n\r\nexport const downloadBlob = (blob: Blob, filename: string): void => {\r\n const url = URL.createObjectURL(blob);\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = filename;\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n URL.revokeObjectURL(url);\r\n};","import styleInject from '#style-inject';styleInject(\":root {\\n --ra-status-own: var(--ra-emerald, 142 71% 45%);\\n --ra-status-shared: var(--ra-amber, 38 92% 50%);\\n --ra-status-missing: var(--muted-foreground, 220 9% 46%);\\n --ra-accent: var(--primary, 222 47% 11%);\\n --ra-surface: var(--card, 0 0% 100%);\\n --ra-border: var(--border, 220 13% 91%);\\n --ra-text: var(--foreground, 222 47% 11%);\\n --ra-muted: var(--muted, 220 14% 96%);\\n --ra-muted-text: var(--muted-foreground, 220 9% 46%);\\n --ra-radius: var(--radius, 0.625rem);\\n --ra-dot-size: 0.5rem;\\n --ra-page-bg: var(--background, 220 14% 98%);\\n --ra-card-shadow: 0 1px 2px hsl(var(--ra-accent) / 0.04), 0 4px 12px hsl(var(--ra-accent) / 0.05);\\n --ra-card-shadow-hover: 0 2px 4px hsl(var(--ra-accent) / 0.06), 0 8px 24px hsl(var(--ra-accent) / 0.08);\\n --ra-row-hover: hsl(var(--ra-accent) / 0.05);\\n --ra-row-active-bg: hsl(var(--ra-accent) / 0.10);\\n --ra-row-active-bd: hsl(var(--ra-accent) / 0.45);\\n --ra-focus-ring: hsl(var(--ra-accent) / 0.35);\\n --ra-font-display: var(--font-display, var(--font-sans, ui-sans-serif, system-ui, -apple-system, \\\"Segoe UI\\\", Roboto, sans-serif));\\n --ra-font-ui: var(--font-sans, ui-sans-serif, system-ui, -apple-system, \\\"Segoe UI\\\", Roboto, sans-serif);\\n --ra-title-weight: 600;\\n --ra-display-weight: 700;\\n --ra-info: var(--ra-blue, 214 95% 55%);\\n --ra-success: var(--ra-emerald, 142 71% 45%);\\n --ra-warning: var(--ra-amber, 38 92% 50%);\\n --ra-danger: var(--destructive, 0 72% 51%);\\n}\\n.ra-status-dot {\\n display: inline-block;\\n width: var(--ra-dot-size);\\n height: var(--ra-dot-size);\\n border-radius: 9999px;\\n flex-shrink: 0;\\n}\\n.ra-status-own {\\n background: hsl(var(--ra-status-own));\\n}\\n.ra-status-shared {\\n background: hsl(var(--ra-status-shared));\\n}\\n.ra-status-missing {\\n background: hsl(var(--ra-status-missing) / 0.4);\\n border: 1px solid hsl(var(--ra-status-missing) / 0.6);\\n}\\n.ra-row-active {\\n background: var(--ra-row-active-bg);\\n border-color: var(--ra-row-active-bd) !important;\\n}\\n\")","import styleInject from '#style-inject';styleInject(\".ra-shell {\\n color: hsl(var(--ra-text));\\n background: hsl(var(--ra-page-bg));\\n font-family: var(--ra-font-ui);\\n}\\n.ra-shell *,\\n.ra-shell *::before,\\n.ra-shell *::after {\\n box-sizing: border-box;\\n}\\n.ra-shell .ra-card {\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: var(--ra-radius);\\n box-shadow: var(--ra-card-shadow);\\n}\\n.ra-shell .ra-card-hover {\\n transition:\\n box-shadow .18s ease,\\n transform .18s ease,\\n border-color .18s ease;\\n}\\n.ra-shell .ra-card-hover:hover {\\n box-shadow: var(--ra-card-shadow-hover);\\n}\\n.ra-shell .ra-display {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n letter-spacing: -0.01em;\\n}\\n.ra-shell .ra-title {\\n font-weight: var(--ra-title-weight);\\n}\\n.ra-shell :where(button, [role=button], input, select, textarea, a):focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\\n border-radius: calc(var(--ra-radius) * 0.6);\\n}\\n.ra-shell .ra-header {\\n position: relative;\\n display: flex;\\n align-items: center;\\n gap: 0.75rem;\\n padding: 0.65rem 0.9rem;\\n border-radius: var(--ra-radius);\\n border: 1px solid hsl(var(--ra-accent) / 0.12);\\n background:\\n linear-gradient(\\n 135deg,\\n hsl(var(--ra-accent) / 0.08),\\n hsl(var(--ra-accent) / 0.02) 60%,\\n hsl(var(--ra-surface)) 100%);\\n box-shadow: var(--ra-card-shadow);\\n}\\n.ra-shell .ra-header__main {\\n flex: 1;\\n min-width: 0;\\n display: flex;\\n align-items: center;\\n gap: 0.625rem;\\n}\\n.ra-shell .ra-header-aside {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-header-icon {\\n flex-shrink: 0;\\n width: 2rem;\\n height: 2rem;\\n border-radius: calc(var(--ra-radius) * 0.9);\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n background: hsl(var(--ra-accent) / 0.12);\\n color: hsl(var(--ra-accent));\\n border: 1px solid hsl(var(--ra-accent) / 0.18);\\n}\\n.ra-shell .ra-header-text {\\n flex: 1;\\n min-width: 0;\\n}\\n.ra-shell .ra-header-title {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n font-size: 1rem;\\n line-height: 1.2;\\n color: hsl(var(--ra-text));\\n letter-spacing: -0.01em;\\n margin: 0;\\n}\\n.ra-shell .ra-header-subtitle {\\n font-size: 0.75rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.125rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-header-stats {\\n display: flex;\\n align-items: stretch;\\n gap: 0.15rem;\\n padding: 0.15rem 0.4rem;\\n border-radius: calc(var(--ra-radius) * 0.75);\\n background: hsl(var(--ra-surface) / 0.7);\\n border: 1px solid hsl(var(--ra-border));\\n}\\n.ra-shell .ra-header-stats--titled {\\n flex-direction: column;\\n align-items: stretch;\\n padding: 0.4rem 0.55rem;\\n gap: 0.3rem;\\n}\\n.ra-shell .ra-header-stats .ra-stats-items {\\n display: flex;\\n align-items: stretch;\\n gap: 0.15rem;\\n}\\n.ra-shell .ra-header-stats .ra-stats-heading {\\n display: flex;\\n align-items: center;\\n gap: 0.35rem;\\n color: hsl(var(--ra-muted-text));\\n font-size: 0.65rem;\\n text-transform: uppercase;\\n letter-spacing: 0.06em;\\n}\\n.ra-shell .ra-header-stats .ra-stats-heading-icon {\\n display: inline-flex;\\n align-items: center;\\n color: hsl(var(--ra-text));\\n opacity: 0.75;\\n}\\n.ra-shell .ra-header-stats .ra-stats-heading-icon > svg {\\n width: 0.85rem;\\n height: 0.85rem;\\n}\\n.ra-shell .ra-stat {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n padding: 0.15rem 0.45rem;\\n min-width: 2.5rem;\\n}\\n.ra-shell .ra-stat-value {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n font-size: 0.85rem;\\n color: hsl(var(--ra-text));\\n line-height: 1;\\n}\\n.ra-shell .ra-stat-label {\\n font-size: 0.6rem;\\n text-transform: uppercase;\\n letter-spacing: 0.04em;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.15rem;\\n}\\n.ra-shell .ra-stat-divider {\\n width: 1px;\\n background: hsl(var(--ra-border));\\n margin: 0.25rem 0;\\n}\\n.ra-shell .ra-header-actions {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n}\\n.ra-shell .ra-tabs {\\n display: flex;\\n gap: 0.25rem;\\n padding: 0.25rem;\\n background: hsl(var(--ra-muted));\\n border-radius: calc(var(--ra-radius) * 0.85);\\n border: 1px solid hsl(var(--ra-border));\\n}\\n.ra-shell .ra-tab {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n padding: 0.4rem 0.7rem;\\n border-radius: calc(var(--ra-radius) * 0.65);\\n font-size: 0.78rem;\\n font-weight: 500;\\n color: hsl(var(--ra-muted-text));\\n background: transparent;\\n border: 0;\\n cursor: pointer;\\n transition:\\n background .15s ease,\\n color .15s ease,\\n transform .15s ease;\\n white-space: nowrap;\\n}\\n.ra-shell .ra-tab:hover {\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-tab[aria-selected=true] {\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-text));\\n box-shadow: var(--ra-card-shadow);\\n font-weight: var(--ra-title-weight);\\n}\\n.ra-shell .ra-tab[aria-selected=true] .ra-tab-icon {\\n color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-tab[disabled] {\\n opacity: .5;\\n cursor: not-allowed;\\n}\\n.ra-shell .ra-tab-count {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n min-width: 1.25rem;\\n padding: 0 0.35rem;\\n height: 1.1rem;\\n border-radius: 999px;\\n background: hsl(var(--ra-accent) / 0.12);\\n color: hsl(var(--ra-accent));\\n font-size: 0.625rem;\\n font-weight: 600;\\n line-height: 1;\\n}\\n.ra-shell .ra-tab[aria-selected=false] .ra-tab-count {\\n background: hsl(var(--ra-muted-text) / 0.15);\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-shell[data-density=compact] .ra-row {\\n padding-block: 0.4rem;\\n}\\n.ra-shell[data-density=compact] .ra-header {\\n padding: 0.75rem 1rem;\\n}\\n.ra-shell[data-density=compact] .ra-header-icon {\\n width: 2.25rem;\\n height: 2.25rem;\\n}\\n.ra-shell .ra-row {\\n display: flex;\\n align-items: center;\\n gap: 0.65rem;\\n width: 100%;\\n text-align: left;\\n padding: 0.65rem 0.85rem;\\n border-left: 3px solid transparent;\\n background: transparent;\\n border-bottom: 1px solid transparent;\\n transition: background .12s ease, border-color .12s ease;\\n cursor: pointer;\\n color: hsl(var(--ra-text));\\n font-family: inherit;\\n}\\n.ra-shell .ra-row + .ra-row {\\n border-top: 1px solid hsl(var(--ra-border) / 0.6);\\n}\\n.ra-shell .ra-row:hover {\\n background: var(--ra-row-hover);\\n}\\n.ra-shell .ra-row[data-selected=true] {\\n background: var(--ra-row-active-bg);\\n border-left-color: var(--ra-row-active-bd);\\n}\\n.ra-shell .ra-row-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.75rem;\\n height: 1.75rem;\\n border-radius: calc(var(--ra-radius) * 0.6);\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-muted-text));\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-row[data-selected=true] .ra-row-icon {\\n background: hsl(var(--ra-accent) / 0.15);\\n color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-row-body {\\n flex: 1;\\n min-width: 0;\\n}\\n.ra-shell .ra-row-title {\\n font-weight: var(--ra-title-weight);\\n font-size: 0.875rem;\\n line-height: 1.25;\\n color: hsl(var(--ra-text));\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-row-sub {\\n font-size: 0.75rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.15rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-row-actions {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.15rem;\\n margin-left: auto;\\n opacity: 0;\\n transition: opacity .15s ease;\\n}\\n.ra-shell .ra-row:hover .ra-row-actions,\\n.ra-shell .ra-row:focus-within .ra-row-actions {\\n opacity: 1;\\n}\\n.ra-shell .ra-row-action {\\n width: 1.6rem;\\n height: 1.6rem;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 999px;\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n border: 0;\\n cursor: pointer;\\n transition: background .15s ease, color .15s ease;\\n}\\n.ra-shell .ra-row-action:hover {\\n background: hsl(var(--ra-accent) / 0.10);\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-row-action[data-tone=danger]:hover {\\n background: hsl(var(--ra-danger) / 0.12);\\n color: hsl(var(--ra-danger));\\n}\\n.ra-shell .ra-chip {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.3rem;\\n padding: 0.15rem 0.5rem;\\n border-radius: 999px;\\n font-size: 0.6875rem;\\n font-weight: 500;\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-muted-text));\\n border: 1px solid hsl(var(--ra-border));\\n white-space: nowrap;\\n max-width: 14rem;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-chip[data-tone=success] {\\n background: hsl(var(--ra-success) / 0.12);\\n color: hsl(var(--ra-success));\\n border-color: hsl(var(--ra-success) / 0.30);\\n}\\n.ra-shell .ra-chip[data-tone=warning] {\\n background: hsl(var(--ra-warning) / 0.14);\\n color: hsl(var(--ra-warning));\\n border-color: hsl(var(--ra-warning) / 0.35);\\n}\\n.ra-shell .ra-chip[data-tone=info] {\\n background: hsl(var(--ra-info) / 0.10);\\n color: hsl(var(--ra-info));\\n border-color: hsl(var(--ra-info) / 0.30);\\n}\\n.ra-shell .ra-chip[data-tone=danger] {\\n background: hsl(var(--ra-danger) / 0.10);\\n color: hsl(var(--ra-danger));\\n border-color: hsl(var(--ra-danger) / 0.30);\\n}\\n.ra-shell .ra-chip[data-tone=muted] {\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n border-style: dashed;\\n}\\n.ra-shell .ra-group {\\n border-bottom: 1px solid hsl(var(--ra-border));\\n}\\n.ra-shell .ra-group:last-child {\\n border-bottom: 0;\\n}\\n.ra-shell .ra-group-summary {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n width: 100%;\\n padding: 0.5rem 0.85rem;\\n background: hsl(var(--ra-muted) / 0.6);\\n font-size: 0.7rem;\\n font-weight: 600;\\n text-transform: uppercase;\\n letter-spacing: 0.04em;\\n color: hsl(var(--ra-muted-text));\\n border: 0;\\n cursor: pointer;\\n transition: background .12s ease;\\n}\\n.ra-shell .ra-group-summary:hover {\\n background: hsl(var(--ra-muted));\\n}\\n.ra-shell .ra-group-summary .ra-group-chevron {\\n transition: transform .15s ease;\\n}\\n.ra-shell .ra-group[data-open=false] .ra-group-chevron {\\n transform: rotate(-90deg);\\n}\\n.ra-shell .ra-group-name {\\n flex: 1;\\n text-align: left;\\n}\\n.ra-shell .ra-group-count {\\n font-size: 0.65rem;\\n font-weight: 600;\\n color: hsl(var(--ra-muted-text));\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: 999px;\\n padding: 0.05rem 0.4rem;\\n}\\n.ra-shell .ra-group[data-open=false] .ra-group-body {\\n display: none;\\n}\\n.ra-shell .ra-empty {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n text-align: center;\\n padding: 2.5rem 1.5rem;\\n gap: 0.75rem;\\n}\\n.ra-shell .ra-empty-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 3.25rem;\\n height: 3.25rem;\\n border-radius: 999px;\\n background: hsl(var(--ra-accent) / 0.08);\\n color: hsl(var(--ra-accent));\\n margin-bottom: 0.25rem;\\n}\\n.ra-shell .ra-empty-title {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n font-size: 1rem;\\n color: hsl(var(--ra-text));\\n margin: 0;\\n letter-spacing: -0.01em;\\n}\\n.ra-shell .ra-empty-body {\\n font-size: 0.8125rem;\\n color: hsl(var(--ra-muted-text));\\n max-width: 22rem;\\n line-height: 1.45;\\n}\\n.ra-shell .ra-empty-actions {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n margin-top: 0.25rem;\\n flex-wrap: wrap;\\n justify-content: center;\\n}\\n.ra-shell .ra-btn {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n padding: 0.45rem 0.85rem;\\n border-radius: calc(var(--ra-radius) * 0.7);\\n font-size: 0.8125rem;\\n font-weight: 500;\\n border: 1px solid hsl(var(--ra-border));\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-text));\\n cursor: pointer;\\n transition:\\n background .15s ease,\\n border-color .15s ease,\\n box-shadow .15s ease,\\n transform .1s ease;\\n}\\n.ra-shell .ra-btn:hover {\\n background: hsl(var(--ra-muted));\\n box-shadow: var(--ra-card-shadow);\\n}\\n.ra-shell .ra-btn:active {\\n transform: translateY(1px);\\n}\\n.ra-shell .ra-btn[data-variant=primary] {\\n background: hsl(var(--ra-accent));\\n color: hsl(var(--ra-surface));\\n border-color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-btn[data-variant=primary]:hover {\\n background: hsl(var(--ra-accent) / 0.92);\\n}\\n.ra-shell .ra-btn[data-variant=ghost] {\\n background: transparent;\\n border-color: transparent;\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-shell .ra-btn[data-variant=ghost]:hover {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-btn[data-variant=danger] {\\n color: hsl(var(--ra-danger));\\n}\\n.ra-shell .ra-btn[data-variant=danger]:hover {\\n background: hsl(var(--ra-danger) / 0.10);\\n border-color: hsl(var(--ra-danger) / 0.40);\\n}\\n.ra-shell .ra-intro {\\n position: relative;\\n display: flex;\\n gap: 0.85rem;\\n padding: 0.9rem 1rem;\\n border-radius: var(--ra-radius);\\n border: 1px solid hsl(var(--ra-info) / 0.30);\\n background: hsl(var(--ra-info) / 0.08);\\n margin-bottom: 1rem;\\n}\\n.ra-shell .ra-intro[data-tone=success] {\\n border-color: hsl(var(--ra-success) / 0.30);\\n background: hsl(var(--ra-success) / 0.08);\\n}\\n.ra-shell .ra-intro[data-tone=warning] {\\n border-color: hsl(var(--ra-warning) / 0.35);\\n background: hsl(var(--ra-warning) / 0.10);\\n}\\n.ra-shell .ra-intro-icon {\\n flex-shrink: 0;\\n width: 2rem;\\n height: 2rem;\\n border-radius: 999px;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n background: hsl(var(--ra-info) / 0.18);\\n color: hsl(var(--ra-info));\\n}\\n.ra-shell .ra-intro[data-tone=success] .ra-intro-icon {\\n background: hsl(var(--ra-success) / 0.18);\\n color: hsl(var(--ra-success));\\n}\\n.ra-shell .ra-intro[data-tone=warning] .ra-intro-icon {\\n background: hsl(var(--ra-warning) / 0.20);\\n color: hsl(var(--ra-warning));\\n}\\n.ra-shell .ra-intro-body {\\n flex: 1;\\n min-width: 0;\\n}\\n.ra-shell .ra-intro-title {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-title-weight);\\n font-size: 0.875rem;\\n color: hsl(var(--ra-text));\\n margin: 0 0 0.2rem 0;\\n}\\n.ra-shell .ra-intro-text {\\n font-size: 0.8125rem;\\n color: hsl(var(--ra-text) / 0.85);\\n line-height: 1.45;\\n}\\n.ra-shell .ra-intro-dismiss {\\n position: absolute;\\n top: 0.5rem;\\n right: 0.5rem;\\n width: 1.6rem;\\n height: 1.6rem;\\n border-radius: 999px;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n background: transparent;\\n border: 0;\\n color: hsl(var(--ra-muted-text));\\n cursor: pointer;\\n}\\n.ra-shell .ra-intro-dismiss:hover {\\n background: hsl(var(--ra-text) / 0.06);\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-bulk-menu {\\n min-width: 12rem;\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: calc(var(--ra-radius) * 0.85);\\n box-shadow: var(--ra-card-shadow-hover);\\n padding: 0.3rem;\\n z-index: 30;\\n}\\n.ra-shell .ra-bulk-item {\\n display: flex;\\n align-items: center;\\n gap: 0.55rem;\\n width: 100%;\\n padding: 0.45rem 0.6rem;\\n border-radius: calc(var(--ra-radius) * 0.6);\\n font-size: 0.8125rem;\\n color: hsl(var(--ra-text));\\n background: transparent;\\n border: 0;\\n cursor: pointer;\\n text-align: left;\\n transition: background .12s ease, color .12s ease;\\n}\\n.ra-shell .ra-bulk-item:hover {\\n background: hsl(var(--ra-muted));\\n}\\n.ra-shell .ra-bulk-item[data-tone=danger] {\\n color: hsl(var(--ra-danger));\\n}\\n.ra-shell .ra-bulk-item[data-tone=danger]:hover {\\n background: hsl(var(--ra-danger) / 0.10);\\n}\\n.ra-shell .ra-bulk-divider {\\n height: 1px;\\n background: hsl(var(--ra-border));\\n margin: 0.25rem 0;\\n}\\n.ra-shell .ra-preview-rail {\\n background: hsl(var(--ra-surface));\\n border-left: 1px solid hsl(var(--ra-border));\\n box-shadow: -4px 0 16px hsl(var(--ra-accent) / 0.04);\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n overflow: hidden;\\n}\\n.ra-shell .ra-preview-rail-header {\\n position: sticky;\\n top: 0;\\n z-index: 1;\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n padding: 0.75rem 1rem;\\n background:\\n linear-gradient(\\n 180deg,\\n hsl(var(--ra-surface)) 0%,\\n hsl(var(--ra-surface) / 0.92) 100%);\\n border-bottom: 1px solid hsl(var(--ra-border));\\n backdrop-filter: blur(6px);\\n}\\n.ra-shell .ra-preview-rail-title {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n font-size: 0.7rem;\\n font-weight: 600;\\n text-transform: uppercase;\\n letter-spacing: 0.06em;\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-shell .ra-preview-rail-body {\\n flex: 1;\\n overflow-y: auto;\\n padding: 1rem;\\n}\\n\")","import { useEffect, useMemo, useState, useCallback, isValidElement, createElement, type ReactNode } from 'react';\r\nimport { Plus, Search } from 'lucide-react';\r\nimport { mergeIcons, pickHeaderIcon } from './icons';\r\nimport type {\r\n RecordsAdminShellProps, RecordStatus, RecordSummary,\r\n ScopeKind, RecordsAdminI18n, ParsedRef, RecordPresentation,\r\n} from '../types';\r\nimport { DEFAULT_I18N } from '../types';\r\nimport { parseRef, buildRef } from '../data/refs';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport { useRecordList } from '../hooks/useRecordList';\r\nimport { useRecordEditor } from '../hooks/useRecordEditor';\r\nimport { useResolvedRecord } from '../hooks/useResolvedRecord';\r\nimport { useIntroDismissed } from '../hooks/useIntroDismissed';\r\nimport { useScopeProbe } from '../hooks/useScopeProbe';\r\nimport { useFacetBrowse } from '../hooks/useFacetBrowse';\r\nimport { useProductBrowse, type ProductBrowseItem } from '../hooks/useProductBrowse';\r\nimport { useProductChildren } from '../hooks/useProductChildren';\r\nimport { useUnsavedGuard } from '../hooks/useUnsavedGuard';\r\nimport { useDirtyNavigation } from '../hooks/useDirtyNavigation';\r\nimport { ScopeTabs } from '../browser/ScopeTabs';\r\nimport { StatusFilterPills } from '../browser/StatusFilterPills';\r\nimport { RecordList } from '../browser/RecordList';\r\nimport { EmptyState, ErrorState, LoadingState } from '../browser/EmptyStates';\r\nimport { PresentationSwitcher } from '../browser/PresentationSwitcher';\r\nimport { usePresentationPref } from '../hooks/usePresentationPref';\r\nimport { RecordEditor } from '../editor/RecordEditor';\r\nimport { ProductDrillDown, type DrillTab } from '../editor/ProductDrillDown';\r\nimport {\r\n InlinePreview, SidePreview, TabbedPreview, DrawerPreview, PreviewToggleButton,\r\n} from '../editor/PreviewPane';\r\nimport { PreviewScopePicker } from '../editor/PreviewScopePicker';\r\nimport { IntroCard } from './IntroCard';\r\nimport { UtilityRow } from './UtilityRow';\r\nimport { ShellHeader } from './ShellHeader';\r\nimport { exportCsv, importCsv, downloadBlob } from '../data/csv';\r\nimport './tokens.css';\r\nimport './shell.css';\r\n\r\n/** Top-level scopes are limited to product / facet — variants and batches\r\n * are drill-downs under a selected product (see `ProductDrillDown`). */\r\nconst TOP_LEVEL_SCOPES: ScopeKind[] = ['product', 'facet'];\r\n\r\n/** ULID-ish item id — short, sortable, no external deps. */\r\nconst defaultItemId = (): string => {\r\n const time = Date.now().toString(36);\r\n const rand = Math.random().toString(36).slice(2, 8);\r\n return `${time}${rand}`;\r\n};\r\n\r\nconst productItemToSummary = (p: ProductBrowseItem): RecordSummary => {\r\n const ref = buildRef({ productId: p.id });\r\n return {\r\n id: null,\r\n ref,\r\n scope: parseRef(ref),\r\n data: null,\r\n status: 'empty',\r\n label: p.name,\r\n subtitle: p.sku ?? undefined,\r\n };\r\n};\r\n\r\nexport function RecordsAdminShell<TData = unknown>(props: RecordsAdminShellProps<TData>) {\r\n const {\r\n SL, appId, collectionId, recordType, label,\r\n scopes: requestedScopes, defaultScope, contextScope,\r\n renderEditor, renderPreview, intro, csvSchema,\r\n classify, defaultData, i18n: i18nOverride, onTelemetry, className,\r\n previewMode = 'inline',\r\n previewScopePicker = false,\r\n dirtyStrategy = 'prompt',\r\n onBeforeDelete,\r\n disableBeforeUnload = false,\r\n presentations = ['list'],\r\n defaultPresentation,\r\n renderCard,\r\n renderListRow,\r\n renderEmpty,\r\n cardinality = 'singleton',\r\n itemNoun = 'item',\r\n generateItemId,\r\n title, subtitle, headerIcon, headerActions,\r\n showStats = false, showHeaderIcon = true, statsItems,\r\n statsTitle, statsIcon,\r\n showHeader,\r\n icons: iconsOverride,\r\n groupBy,\r\n renderEmptyState,\r\n density = 'comfortable',\r\n } = props;\r\n\r\n const i18n: RecordsAdminI18n = { ...DEFAULT_I18N, ...(i18nOverride ?? {}) };\r\n const icons = useMemo(() => mergeIcons(iconsOverride), [iconsOverride]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Presentation — persisted per app/recordType.\r\n // ---------------------------------------------------------------------------\r\n const [presentation, setPresentation] = usePresentationPref({\r\n appId, recordType,\r\n options: presentations,\r\n defaultValue: defaultPresentation ?? presentations[0] ?? 'list',\r\n });\r\n\r\n const onPresentationChange = useCallback((next: RecordPresentation) => {\r\n onTelemetry?.({ type: 'presentation.change', recordType, from: presentation, to: next });\r\n setPresentation(next);\r\n }, [onTelemetry, recordType, presentation, setPresentation]);\r\n\r\n const ctx: RecordsCtx = useMemo(\r\n () => ({ SL, collectionId, appId, recordType }),\r\n [SL, collectionId, appId, recordType],\r\n );\r\n\r\n // ---------------------------------------------------------------------------\r\n // Scope discovery — `variants` / `batches` flags off the Collection control\r\n // whether the drill-down sub-tabs render at all.\r\n // ---------------------------------------------------------------------------\r\n const probe = useScopeProbe({ SL, collectionId });\r\n\r\n // Top-level tabs: only product / facet (filter by what the host requested).\r\n const topLevelScopes = useMemo(\r\n () => requestedScopes.filter((s) => TOP_LEVEL_SCOPES.includes(s)),\r\n [requestedScopes],\r\n );\r\n\r\n // Are variants/batches available *for drill-down* under a product?\r\n const drillVariantsAllowed = useMemo(\r\n () => requestedScopes.includes('variant') && (probe.isLoading || probe.hasVariants),\r\n [requestedScopes, probe.isLoading, probe.hasVariants],\r\n );\r\n const drillBatchesAllowed = useMemo(\r\n () => requestedScopes.includes('batch') && (probe.isLoading || probe.hasBatches),\r\n [requestedScopes, probe.isLoading, probe.hasBatches],\r\n );\r\n\r\n // ---------------------------------------------------------------------------\r\n // Initial scope/selection from URL context.\r\n // - Any of productId/variantId/batchId pinned → start on `product` tab,\r\n // that product auto-selected, and drill into variant/batch if specified.\r\n // - Otherwise, prefer requested defaultScope or first top-level scope.\r\n // ---------------------------------------------------------------------------\r\n const initialScope: ScopeKind = useMemo(() => {\r\n if (contextScope?.productId && topLevelScopes.includes('product')) return 'product';\r\n if (defaultScope && topLevelScopes.includes(defaultScope)) return defaultScope;\r\n return topLevelScopes[0] ?? 'product';\r\n }, [contextScope?.productId, defaultScope, topLevelScopes]);\r\n\r\n const [activeScope, setActiveScope] = useState<ScopeKind>(initialScope);\r\n useEffect(() => { setActiveScope(initialScope); }, [initialScope]);\r\n\r\n // List query state (search/filter applies per top-level tab).\r\n const [search, setSearch] = useState('');\r\n const [filter, setFilter] = useState<'all' | RecordStatus>('all');\r\n\r\n // Selected ref for the FACET tab (records-driven list).\r\n const [selectedFacetRef, setSelectedFacetRef] = useState<string | undefined>();\r\n\r\n // Selected product (drives the right pane) + drill-down state.\r\n const [selectedProductId, setSelectedProductId] = useState<string | undefined>(\r\n contextScope?.productId,\r\n );\r\n const [drillTab, setDrillTab] = useState<DrillTab>(\r\n contextScope?.batchId ? 'batch' : contextScope?.variantId ? 'variant' : 'product',\r\n );\r\n const [selectedVariantId, setSelectedVariantId] = useState<string | undefined>(\r\n contextScope?.variantId,\r\n );\r\n const [selectedBatchId, setSelectedBatchId] = useState<string | undefined>(\r\n contextScope?.batchId,\r\n );\r\n\r\n // Re-sync from URL changes in the host.\r\n useEffect(() => {\r\n if (contextScope?.productId) setSelectedProductId(contextScope.productId);\r\n }, [contextScope?.productId]);\r\n useEffect(() => {\r\n if (contextScope?.variantId) {\r\n setSelectedVariantId(contextScope.variantId);\r\n setDrillTab('variant');\r\n }\r\n }, [contextScope?.variantId]);\r\n useEffect(() => {\r\n if (contextScope?.batchId) {\r\n setSelectedBatchId(contextScope.batchId);\r\n setDrillTab('batch');\r\n }\r\n }, [contextScope?.batchId]);\r\n\r\n const { dismissed, dismiss, undismiss } = useIntroDismissed(SL, collectionId, appId, recordType);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Data sources — switch by active top-level scope.\r\n // ---------------------------------------------------------------------------\r\n const productBrowse = useProductBrowse({\r\n SL, collectionId,\r\n search: activeScope === 'product' ? search : '',\r\n enabled: activeScope === 'product' && !contextScope?.productId,\r\n });\r\n\r\n // Records-driven list (used for facet tab today; could power custom scopes later).\r\n const recordList = useRecordList({\r\n ctx, scopeKind: activeScope, search, filter,\r\n classify: classify as ((r: RecordSummary) => RecordStatus) | undefined,\r\n contextScope,\r\n enabled: activeScope === 'facet' && !probe.isLoading,\r\n });\r\n\r\n const facetBrowse = useFacetBrowse({\r\n SL,\r\n collectionId,\r\n existing: recordList.allItems,\r\n search,\r\n filter,\r\n enabled: activeScope === 'facet' && !probe.isLoading,\r\n });\r\n\r\n // Lazy children for the selected product (only fires when drilled in).\r\n const variantChildren = useProductChildren({\r\n SL, collectionId, productId: selectedProductId,\r\n kind: drillTab === 'variant' ? 'variant' : null,\r\n });\r\n const batchChildren = useProductChildren({\r\n SL, collectionId, productId: selectedProductId,\r\n kind: drillTab === 'batch' ? 'batch' : null,\r\n });\r\n\r\n // ---------------------------------------------------------------------------\r\n // Auto-select on first load.\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (activeScope !== 'product') return;\r\n if (selectedProductId) return;\r\n const first = productBrowse.items[0];\r\n if (first) setSelectedProductId(first.id);\r\n }, [activeScope, selectedProductId, productBrowse.items]);\r\n\r\n useEffect(() => {\r\n if (activeScope !== 'facet') return;\r\n if (selectedFacetRef) return;\r\n const first = facetBrowse.items[0];\r\n if (first) setSelectedFacetRef(first.ref);\r\n }, [activeScope, selectedFacetRef, facetBrowse.items]);\r\n\r\n // Reset selection bits when the active top-level scope changes.\r\n useEffect(() => {\r\n setSearch('');\r\n setFilter('all');\r\n }, [activeScope]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Build the parsed scope for whatever's currently being edited.\r\n // ---------------------------------------------------------------------------\r\n const editingScope: ParsedRef | null = useMemo(() => {\r\n if (activeScope === 'facet') {\r\n return selectedFacetRef ? parseRef(selectedFacetRef) : null;\r\n }\r\n // Product tab — the editor follows the drill-down state.\r\n if (!selectedProductId) return null;\r\n if (drillTab === 'variant') {\r\n if (!selectedVariantId) return null;\r\n return parseRef(buildRef({ productId: selectedProductId, variantId: selectedVariantId }));\r\n }\r\n if (drillTab === 'batch') {\r\n if (!selectedBatchId) return null;\r\n return parseRef(buildRef({ productId: selectedProductId, batchId: selectedBatchId }));\r\n }\r\n return parseRef(buildRef({ productId: selectedProductId }));\r\n }, [activeScope, selectedFacetRef, selectedProductId, drillTab, selectedVariantId, selectedBatchId]);\r\n\r\n // Scope chain for the resolver (always pass all four when supported).\r\n const supportedForResolution = useMemo(() => requestedScopes, [requestedScopes]);\r\n\r\n const resolved = useResolvedRecord<TData>({\r\n SL, appId, recordType, collectionId,\r\n productId: editingScope?.productId,\r\n variantId: editingScope?.variantId,\r\n batchId: editingScope?.batchId,\r\n facetId: editingScope?.facetId,\r\n facetValue: editingScope?.facetValue,\r\n supportedScopes: supportedForResolution,\r\n enabled: !!editingScope,\r\n });\r\n\r\n const refetchAll = useCallback(() => {\r\n productBrowse.refetch();\r\n recordList.refetch();\r\n facetBrowse.refetch();\r\n variantChildren.refetch();\r\n batchChildren.refetch();\r\n }, [productBrowse, recordList, facetBrowse, variantChildren, batchChildren]);\r\n\r\n const editorCtx = useRecordEditor<TData>({\r\n ctx,\r\n scope: editingScope ?? parseRef(''),\r\n resolved: { data: resolved.data, source: resolved.source, sourceRef: resolved.sourceRef, parentValue: resolved.parentValue },\r\n defaultData,\r\n reseed: dirtyStrategy === 'keep' ? 'preserve-dirty' : 'always',\r\n onSaved: () => {\r\n onTelemetry?.({ type: 'record.save', recordType, ref: editingScope?.raw ?? '', isCreate: resolved.source !== 'self' });\r\n refetchAll();\r\n },\r\n onDeleted: () => {\r\n onTelemetry?.({ type: 'record.delete', recordType, ref: editingScope?.raw ?? '' });\r\n // Clear selection on the appropriate axis so the now-deleted record\r\n // doesn't appear \"still selected\" while the list refreshes.\r\n if (activeScope === 'facet') {\r\n setSelectedFacetRef(undefined);\r\n } else if (drillTab === 'variant') {\r\n setSelectedVariantId(undefined);\r\n } else if (drillTab === 'batch') {\r\n setSelectedBatchId(undefined);\r\n }\r\n refetchAll();\r\n },\r\n });\r\n\r\n // ---------------------------------------------------------------------------\r\n // Unsaved guards — browser beforeunload + iframe parent message + nav guard\r\n // ---------------------------------------------------------------------------\r\n useUnsavedGuard({\r\n isDirty: editorCtx.isDirty,\r\n label: recordType,\r\n disableBeforeUnload,\r\n });\r\n\r\n const { runWithGuard } = useDirtyNavigation({\r\n strategy: dirtyStrategy,\r\n isDirty: editorCtx.isDirty,\r\n save: editorCtx.save,\r\n reset: editorCtx.reset,\r\n i18n: {\r\n title: i18n.unsavedPromptTitle,\r\n body: i18n.unsavedPromptBody,\r\n save: i18n.unsavedPromptSave,\r\n discard: i18n.unsavedPromptDiscard,\r\n cancel: i18n.unsavedPromptCancel,\r\n },\r\n });\r\n\r\n // ---------------------------------------------------------------------------\r\n // CSV import/export — only meaningful for the records list (facet tab today).\r\n // ---------------------------------------------------------------------------\r\n const handleExport = () => {\r\n if (!csvSchema) return;\r\n const fileBase = recordType ?? (label.toLowerCase().replace(/\\s+/g, '-') || 'records');\r\n const blob = exportCsv(recordList.items as RecordSummary<TData>[], csvSchema);\r\n downloadBlob(blob, `${fileBase}.csv`);\r\n onTelemetry?.({ type: 'csv.export', recordType, rows: recordList.items.length });\r\n };\r\n const handleImport = () => {\r\n if (!csvSchema) return;\r\n const inp = document.createElement('input');\r\n inp.type = 'file';\r\n inp.accept = '.csv,text/csv';\r\n inp.onchange = async () => {\r\n const file = inp.files?.[0];\r\n if (!file) return;\r\n const report = await importCsv(file, csvSchema, ctx);\r\n onTelemetry?.({ type: 'csv.import', recordType, rows: report.total, errors: report.failed });\r\n if (report.failed > 0) {\r\n const fileBase = recordType ?? (label.toLowerCase().replace(/\\s+/g, '-') || 'records');\r\n downloadBlob(new Blob([report.annotatedCsv], { type: 'text/csv' }), `${fileBase}-errors.csv`);\r\n }\r\n refetchAll();\r\n };\r\n inp.click();\r\n };\r\n const csvBulk = csvSchema ? { onImportCsv: handleImport, onExportCsv: handleExport } : {};\r\n\r\n // ---------------------------------------------------------------------------\r\n // Preview state — independent scope (when picker enabled) + drawer toggle.\r\n // ---------------------------------------------------------------------------\r\n const [previewScope, setPreviewScope] = useState<ParsedRef | null>(null);\r\n const [drawerOpen, setDrawerOpen] = useState(false);\r\n\r\n // Whenever the editing scope changes, reset the preview scope to follow it\r\n // (unless the user explicitly picked a different one).\r\n useEffect(() => {\r\n if (!editingScope) return;\r\n setPreviewScope((cur) => (cur === null ? editingScope : cur));\r\n }, [editingScope]);\r\n\r\n const effectivePreviewScope: ParsedRef | null = previewScope ?? editingScope;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Build the editor + preview pair according to `previewMode`. Both call\r\n // sites (product drill-down + facet tab) render through this helper so the\r\n // chrome stays consistent.\r\n // ---------------------------------------------------------------------------\r\n const renderEditorWithPreview = (): ReactNode => {\r\n if (!editingScope) return null;\r\n\r\n const previewBody: ReactNode = renderPreview && effectivePreviewScope\r\n ? renderPreview({ resolved: editorCtx.value, previewScope: effectivePreviewScope })\r\n : null;\r\n\r\n const scopePicker = previewScopePicker && effectivePreviewScope ? (\r\n <PreviewScopePicker\r\n SL={SL}\r\n collectionId={collectionId}\r\n editingScope={editingScope}\r\n value={effectivePreviewScope}\r\n onChange={setPreviewScope}\r\n showVariants={drillVariantsAllowed}\r\n showBatches={drillBatchesAllowed}\r\n i18n={{ previewAs: i18n.previewAs, previewAsDefault: i18n.previewAsDefault }}\r\n />\r\n ) : null;\r\n\r\n const baseEditor = (extraFooter?: ReactNode, inlinePreviewBody?: ReactNode) => (\r\n <RecordEditor\r\n ctx={editorCtx}\r\n i18n={i18n}\r\n bulkActions={{ ...csvBulk, i18n }}\r\n preview={inlinePreviewBody}\r\n footerExtra={extraFooter}\r\n onBeforeDelete={onBeforeDelete && editingScope\r\n ? () => onBeforeDelete(editingScope)\r\n : undefined}\r\n >\r\n {renderEditor(editorCtx)}\r\n </RecordEditor>\r\n );\r\n\r\n // No preview supplied → just the editor.\r\n if (!previewBody) return baseEditor();\r\n\r\n if (previewMode === 'inline') {\r\n return baseEditor(undefined,\r\n <InlinePreview label={i18n.preview} scopePicker={scopePicker}>{previewBody}</InlinePreview>,\r\n );\r\n }\r\n\r\n if (previewMode === 'side') {\r\n return (\r\n <div className=\"grid h-full\" style={{ gridTemplateColumns: 'minmax(0, 1fr) minmax(280px, 420px)' }}>\r\n <div className=\"overflow-hidden\">{baseEditor()}</div>\r\n <SidePreview label={i18n.preview} scopePicker={scopePicker}>{previewBody}</SidePreview>\r\n </div>\r\n );\r\n }\r\n\r\n if (previewMode === 'tab') {\r\n return (\r\n <TabbedPreview\r\n editor={baseEditor()}\r\n preview={previewBody}\r\n scopePicker={scopePicker}\r\n i18n={{ editor: i18n.editor, preview: i18n.preview }}\r\n />\r\n );\r\n }\r\n\r\n // drawer\r\n return (\r\n <div className=\"relative h-full\">\r\n {baseEditor(\r\n <PreviewToggleButton onClick={() => setDrawerOpen(true)} label={i18n.openPreview} />,\r\n )}\r\n <DrawerPreview\r\n open={drawerOpen}\r\n onClose={() => setDrawerOpen(false)}\r\n label={i18n.preview}\r\n scopePicker={scopePicker}\r\n >\r\n {previewBody}\r\n </DrawerPreview>\r\n </div>\r\n );\r\n };\r\n\r\n // ---------------------------------------------------------------------------\r\n // Render — left rail (top-level browse) + right pane (editor or drill-down).\r\n // ---------------------------------------------------------------------------\r\n const isProductTab = activeScope === 'product';\r\n const productPinned = !!contextScope?.productId;\r\n\r\n // Items shown in the left rail under the products tab (browse-driven).\r\n const productListItems: RecordSummary[] = useMemo(() => {\r\n if (productPinned) {\r\n // Pinned mode: collapse the rail to just that product so the user has context.\r\n return [{\r\n id: null, ref: buildRef({ productId: contextScope!.productId! }),\r\n scope: parseRef(buildRef({ productId: contextScope!.productId! })),\r\n data: null, status: 'empty',\r\n label: contextScope!.productId!, subtitle: undefined,\r\n }];\r\n }\r\n return productBrowse.items.map(productItemToSummary);\r\n }, [productPinned, contextScope, productBrowse.items]);\r\n\r\n const leftItems = isProductTab ? productListItems : facetBrowse.items;\r\n const leftLoading = isProductTab\r\n ? (!productPinned && productBrowse.isLoading)\r\n : (facetBrowse.isLoading || recordList.isLoading || probe.isLoading);\r\n const leftError = isProductTab ? productBrowse.error : (facetBrowse.error ?? recordList.error);\r\n const leftSelectedRef = isProductTab\r\n ? (selectedProductId ? buildRef({ productId: selectedProductId }) : undefined)\r\n : selectedFacetRef;\r\n\r\n const onLeftSelect = (item: RecordSummary) => {\r\n void runWithGuard(() => {\r\n if (isProductTab) {\r\n setSelectedProductId(item.scope.productId);\r\n setSelectedVariantId(undefined);\r\n setSelectedBatchId(undefined);\r\n setDrillTab('product');\r\n } else {\r\n setSelectedFacetRef(item.ref);\r\n }\r\n });\r\n };\r\n\r\n return (\r\n <div\r\n className={`ra-shell flex flex-col h-full ${className ?? ''}`}\r\n data-density={density}\r\n >\r\n <div className=\"px-4 pt-4 space-y-3\">\r\n {intro && !dismissed && (\r\n <IntroCard\r\n title={intro.title}\r\n body={intro.body}\r\n onDismiss={() => { dismiss(); onTelemetry?.({ type: 'intro.dismiss', recordType }); }}\r\n />\r\n )}\r\n {(() => {\r\n // Auto-show the header card when the host customised it in any way,\r\n // even without explicitly setting `showHeader`. Off otherwise — most\r\n // apps don't need it and the internal record-type label is noise.\r\n const headerCustomised =\r\n !!title || !!subtitle || !!headerIcon || !!headerActions ||\r\n showStats || !!statsItems || !!statsTitle || !!statsIcon;\r\n const renderHeader = showHeader === true || (showHeader !== false && headerCustomised);\r\n if (!renderHeader) return null;\r\n return (\r\n <ShellHeader\r\n title={title ?? label ?? recordType ?? ''}\r\n subtitle={subtitle}\r\n headerIcon={headerIcon}\r\n headerActions={headerActions}\r\n showStats={showStats}\r\n showHeaderIcon={showHeaderIcon}\r\n recordType={recordType}\r\n icons={icons}\r\n stats={{\r\n products: productBrowse.items.length,\r\n shared: recordList.items.length,\r\n }}\r\n statsItems={statsItems}\r\n statsTitle={statsTitle}\r\n statsIcon={statsIcon}\r\n />\r\n );\r\n })()}\r\n <UtilityRow\r\n label={label}\r\n introHidden={dismissed && !!intro}\r\n onShowIntro={undismiss}\r\n />\r\n </div>\r\n <div\r\n className=\"flex-1 grid border-t overflow-hidden\"\r\n style={{ gridTemplateColumns: 'minmax(260px, 320px) 1fr', borderColor: 'hsl(var(--ra-border))', marginTop: '0.75rem' }}\r\n >\r\n <aside className=\"border-r overflow-hidden flex flex-col\" style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}>\r\n <div className=\"p-2\">\r\n <ScopeTabs\r\n scopes={topLevelScopes}\r\n active={activeScope}\r\n onChange={(s) => {\r\n void runWithGuard(() => {\r\n onTelemetry?.({ type: 'scope.change', recordType, from: activeScope, to: s });\r\n setActiveScope(s);\r\n });\r\n }}\r\n loading={probe.isLoading}\r\n counts={{\r\n product: productBrowse.items.length,\r\n facet: facetBrowse.items.length,\r\n }}\r\n icons={icons.scope}\r\n />\r\n </div>\r\n <div className=\"p-3 space-y-2.5 border-b\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n <div className=\"flex items-center gap-2\">\r\n <div className=\"relative flex-1 min-w-0\">\r\n <Search className=\"absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 opacity-50\" />\r\n <input\r\n type=\"text\"\r\n value={search}\r\n onChange={(e) => setSearch(e.target.value)}\r\n placeholder={i18n.searchPlaceholder}\r\n className=\"w-full pl-8 pr-3 py-1.5 text-xs rounded-md border bg-transparent focus:outline-none focus:ring-1\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n />\r\n </div>\r\n <PresentationSwitcher\r\n options={presentations}\r\n value={presentation}\r\n onChange={onPresentationChange}\r\n i18n={i18n}\r\n />\r\n </div>\r\n {!isProductTab && (\r\n <StatusFilterPills value={filter} onChange={setFilter} counts={facetBrowse.counts} i18n={i18n} />\r\n )}\r\n {cardinality === 'collection' && !isProductTab && editingScope && (\r\n <button\r\n type=\"button\"\r\n onClick={() => {\r\n void runWithGuard(() => {\r\n const id = generateItemId ? generateItemId() : defaultItemId();\r\n const baseRef = editingScope.raw;\r\n const itemRef = baseRef ? `${baseRef}/item:${id}` : `item:${id}`;\r\n setSelectedFacetRef(itemRef);\r\n onTelemetry?.({ type: 'item.create', recordType, scopeRef: baseRef });\r\n });\r\n }}\r\n className=\"w-full inline-flex items-center justify-center gap-1.5 text-xs py-1.5 rounded-md border transition-colors hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n <Plus className=\"w-3.5 h-3.5\" />\r\n {i18n.newItem || `New ${itemNoun}`}\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto\">\r\n {leftLoading && <LoadingState />}\r\n {!leftLoading && leftError && <ErrorState error={leftError} />}\r\n {!leftLoading && !leftError && leftItems.length === 0 && (\r\n renderEmpty\r\n ? renderEmpty({ scope: editingScope })\r\n : renderEmptyState\r\n ? renderEmptyState({ scope: activeScope })\r\n : <EmptyState\r\n icon={search ? icons.empty.search : icons.empty.default}\r\n title={search ? i18n.noResults : i18n.railEmptyTitle}\r\n body={search ? undefined : i18n.railEmptyBody}\r\n />\r\n )}\r\n {!leftLoading && !leftError && leftItems.length > 0 && (\r\n <>\r\n <RecordList\r\n items={leftItems}\r\n selectedRef={leftSelectedRef}\r\n onSelect={onLeftSelect}\r\n dirtyRef={editorCtx.isDirty ? editingScope?.raw : undefined}\r\n presentation={presentation}\r\n renderListRow={renderListRow as ((r: RecordSummary, c: { selected: boolean; onSelect: () => void; isDirty?: boolean }) => ReactNode) | undefined}\r\n renderCard={renderCard as ((r: RecordSummary, c: { selected: boolean; onSelect: () => void; isDirty?: boolean }) => ReactNode) | undefined}\r\n groupBy={groupBy}\r\n />\r\n {isProductTab && !productPinned && productBrowse.hasNextPage && (\r\n <div className=\"p-2\">\r\n <button\r\n type=\"button\"\r\n onClick={() => { void productBrowse.fetchNextPage(); }}\r\n disabled={productBrowse.isFetchingNextPage}\r\n className=\"w-full text-xs py-2 rounded-md border transition-opacity disabled:opacity-50 hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n {productBrowse.isFetchingNextPage ? 'Loading…' : `Load more (${leftItems.length} shown)`}\r\n </button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </aside>\r\n <main className=\"overflow-hidden\">\r\n {!editingScope && activeScope === 'product' && !selectedProductId && (\r\n <EmptyState title={i18n.emptyTitle} body={i18n.emptyBody} />\r\n )}\r\n {!editingScope && activeScope === 'facet' && (\r\n <EmptyState title={i18n.emptyTitle} body={i18n.emptyBody} />\r\n )}\r\n {/* Product tab → drill-down wrapper around the editor */}\r\n {isProductTab && selectedProductId && (\r\n <ProductDrillDown\r\n productLabel={\r\n productBrowse.items.find((p: { id: string; name?: string }) => p.id === selectedProductId)?.name ?? selectedProductId\r\n }\r\n showVariants={drillVariantsAllowed}\r\n showBatches={drillBatchesAllowed}\r\n active={drillTab}\r\n onChange={(t) => {\r\n void runWithGuard(() => {\r\n setDrillTab(t);\r\n if (t === 'product') { setSelectedVariantId(undefined); setSelectedBatchId(undefined); }\r\n });\r\n }}\r\n selectedChildId={drillTab === 'variant' ? selectedVariantId : drillTab === 'batch' ? selectedBatchId : undefined}\r\n onSelectChild={(id) => {\r\n void runWithGuard(() => {\r\n if (drillTab === 'variant') setSelectedVariantId(id);\r\n else if (drillTab === 'batch') setSelectedBatchId(id);\r\n });\r\n }}\r\n variants={variantChildren.items}\r\n batches={batchChildren.items}\r\n variantsLoading={variantChildren.isLoading}\r\n batchesLoading={batchChildren.isLoading}\r\n >\r\n {editingScope ? renderEditorWithPreview() : (\r\n <EmptyState\r\n title={drillTab === 'variant' ? 'Pick a variant' : 'Pick a batch'}\r\n body={`Select a ${drillTab} on the left to edit its ${recordType ?? label.toLowerCase()}.`}\r\n />\r\n )}\r\n </ProductDrillDown>\r\n )}\r\n {/* Facet tab → straight to the editor */}\r\n {!isProductTab && editingScope && renderEditorWithPreview()}\r\n </main>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { Search } from 'lucide-react';\r\nimport type { RecordStatus, RecordSummary, ScopeKind, RecordsAdminI18n } from '../types';\r\nimport { ScopeTabs } from './ScopeTabs';\r\nimport { StatusFilterPills } from './StatusFilterPills';\r\nimport { RecordList } from './RecordList';\r\nimport { EmptyState, ErrorState, LoadingState } from './EmptyStates';\r\n\r\nexport interface RecordBrowserProps {\r\n scopes: ScopeKind[];\r\n activeScope: ScopeKind;\r\n onActiveScopeChange: (s: ScopeKind) => void;\r\n\r\n selectedRef?: string;\r\n onSelectRef: (item: RecordSummary) => void;\r\n\r\n items: RecordSummary[];\r\n counts: { all: number; configured: number; partial: number; empty: number };\r\n isLoading: boolean;\r\n error: Error | null;\r\n\r\n filter: 'all' | RecordStatus;\r\n onFilterChange: (v: 'all' | RecordStatus) => void;\r\n search: string;\r\n onSearchChange: (v: string) => void;\r\n\r\n hasNextPage?: boolean;\r\n isFetchingNextPage?: boolean;\r\n onLoadMore?: () => void;\r\n\r\n scopesLoading?: boolean;\r\n\r\n i18n: RecordsAdminI18n;\r\n}\r\n\r\nexport const RecordBrowser = ({\r\n scopes, activeScope, onActiveScopeChange,\r\n selectedRef, onSelectRef,\r\n items, counts, isLoading, error,\r\n filter, onFilterChange, search, onSearchChange,\r\n hasNextPage, isFetchingNextPage, onLoadMore,\r\n scopesLoading,\r\n i18n,\r\n}: RecordBrowserProps) => {\r\n return (\r\n <div className=\"flex flex-col h-full\" style={{ background: 'hsl(var(--ra-surface))' }}>\r\n <ScopeTabs scopes={scopes} active={activeScope} onChange={onActiveScopeChange} loading={scopesLoading} />\r\n <div className=\"p-3 space-y-2.5 border-b\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 opacity-50\" />\r\n <input\r\n type=\"text\"\r\n value={search}\r\n onChange={(e) => onSearchChange(e.target.value)}\r\n placeholder={i18n.searchPlaceholder}\r\n className=\"w-full pl-8 pr-3 py-1.5 text-xs rounded-md border bg-transparent focus:outline-none focus:ring-1\"\r\n style={{\r\n borderColor: 'hsl(var(--ra-border))',\r\n color: 'hsl(var(--ra-text))',\r\n }}\r\n />\r\n </div>\r\n <StatusFilterPills value={filter} onChange={onFilterChange} counts={counts} i18n={i18n} />\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto\">\r\n {isLoading && <LoadingState />}\r\n {!isLoading && error && <ErrorState error={error} />}\r\n {!isLoading && !error && items.length === 0 && (\r\n <EmptyState title={i18n.noResults} body={search ? undefined : i18n.emptyBody} />\r\n )}\r\n {!isLoading && !error && items.length > 0 && (\r\n <>\r\n <RecordList items={items} selectedRef={selectedRef} onSelect={onSelectRef} />\r\n {hasNextPage && (\r\n <div className=\"p-2\">\r\n <button\r\n type=\"button\"\r\n onClick={onLoadMore}\r\n disabled={isFetchingNextPage}\r\n className=\"w-full text-xs py-2 rounded-md border transition-opacity disabled:opacity-50 hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n {isFetchingNextPage ? 'Loading…' : `Load more (${items.length} shown)`}\r\n </button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};","import { type ReactNode, createContext, useContext } from 'react';\r\nimport { CornerDownLeft, Circle } from 'lucide-react';\r\n\r\ninterface InheritanceCtx {\r\n parentValue?: Record<string, unknown> | null;\r\n ownValue?: Record<string, unknown> | null;\r\n onResetField?: (field: string) => void;\r\n}\r\n\r\nconst Ctx = createContext<InheritanceCtx>({});\r\n\r\nexport const InheritanceProvider = ({\r\n parentValue, ownValue, onResetField, children,\r\n}: InheritanceCtx & { children: ReactNode }) => (\r\n <Ctx.Provider value={{ parentValue, ownValue, onResetField }}>{children}</Ctx.Provider>\r\n);\r\n\r\ninterface MarkerProps {\r\n field: string;\r\n inheritedValue?: unknown;\r\n value?: unknown;\r\n children: ReactNode;\r\n}\r\n\r\nconst eq = (a: unknown, b: unknown) => {\r\n try { return JSON.stringify(a) === JSON.stringify(b); }\r\n catch { return false; }\r\n};\r\n\r\nexport const InheritanceMarker = ({ field, inheritedValue, value, children }: MarkerProps) => {\r\n const ctx = useContext(Ctx);\r\n const inh = inheritedValue !== undefined ? inheritedValue : ctx.parentValue?.[field];\r\n const cur = value !== undefined ? value : ctx.ownValue?.[field];\r\n const isInherited = inh !== undefined && eq(inh, cur);\r\n if (inh === undefined) return <>{children}</>;\r\n return (\r\n <div className=\"space-y-1\">\r\n {children}\r\n <div className=\"flex items-center gap-1 text-[10px]\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n {isInherited ? (\r\n <>\r\n <CornerDownLeft className=\"w-2.5 h-2.5\" />\r\n <span>Inherited</span>\r\n </>\r\n ) : (\r\n <>\r\n <Circle className=\"w-2 h-2 fill-current\" style={{ color: 'hsl(var(--ra-status-shared))' }} />\r\n <span>Override</span>\r\n {ctx.onResetField && (\r\n <button\r\n type=\"button\"\r\n onClick={() => ctx.onResetField?.(field)}\r\n className=\"underline opacity-70 hover:opacity-100 ml-1\"\r\n >\r\n Reset\r\n </button>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};","import type { ReactNode } from 'react';\r\n\r\ninterface Props { children: ReactNode }\r\n\r\nexport const ResolvedPreview = ({ children }: Props) => (\r\n <div className=\"mt-4 pt-4 border-t\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n <div className=\"text-[10px] uppercase tracking-wide mb-2\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n Public preview\r\n </div>\r\n {children}\r\n </div>\r\n);","// =============================================================================\r\n// useResolveAllRecords — fetch every applicable record for a product context.\r\n//\r\n// Wraps the SDK 1.10 `app.records.resolveAll()` endpoint (single round-trip).\r\n// Use this when an app needs the *stack* of records that apply (warranty +\r\n// nutrition + facet-rule overlays etc.), not just the single most-specific\r\n// winner. For the single-winner case keep using `useResolvedRecord`.\r\n// =============================================================================\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\nimport type {\r\n ResolveAllResult, MatchEntry, MatchedAt,\r\n} from '../data/sdkTypes';\r\n\r\nexport interface UseResolveAllRecordsArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n /** Limit to a single record type. Omit to return every type. */\r\n recordType?: string;\r\n /** Product context — at minimum a productId in most apps. */\r\n context: {\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n proofId?: string;\r\n /**\r\n * Facet assignments for the product. Used for both legacy facet refs\r\n * and `facetRule` evaluation server-side.\r\n * e.g. `{ brand: 'samsung', type: ['tv', 'laptop'] }`\r\n */\r\n facets?: Record<string, string | string[]>;\r\n };\r\n /** Restrict to specific tiers (e.g. only `['rule', 'product']`). */\r\n tiers?: MatchedAt[];\r\n /** Safety cap. Default 500, max 5000. */\r\n limit?: number;\r\n /** Point-in-time evaluation for scheduled records. ISO 8601. */\r\n at?: string;\r\n includeScheduled?: boolean;\r\n includeExpired?: boolean;\r\n /**\r\n * `false` to use the public (visibility-filtered) endpoint.\r\n * Defaults to `false` so this hook is safe to call from public surfaces.\r\n */\r\n admin?: boolean;\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport const resolveAllQueryKey = (args: UseResolveAllRecordsArgs): unknown[] => [\r\n 'records-admin', 'resolve-all',\r\n args.collectionId, args.appId, args.recordType ?? null,\r\n args.context.productId ?? null,\r\n args.context.variantId ?? null,\r\n args.context.batchId ?? null,\r\n args.context.proofId ?? null,\r\n args.context.facets ?? null,\r\n args.tiers ?? null,\r\n args.limit ?? null,\r\n args.at ?? null,\r\n args.includeScheduled ?? false,\r\n args.includeExpired ?? false,\r\n args.admin ?? false,\r\n];\r\n\r\nexport interface UseResolveAllResult {\r\n /** All matching records, sorted most-specific first. Each appears once. */\r\n records: MatchEntry[];\r\n /** True when the result hit the `limit` safety cap. */\r\n truncated: boolean;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => void;\r\n}\r\n\r\nexport function useResolveAllRecords(args: UseResolveAllRecordsArgs): UseResolveAllResult {\r\n const {\r\n SL, collectionId, appId, recordType,\r\n context, tiers, limit, at, includeScheduled, includeExpired,\r\n admin = false, enabled = true, staleTime = 15_000,\r\n } = args;\r\n\r\n const query = useQuery<ResolveAllResult>({\r\n queryKey: resolveAllQueryKey(args),\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime,\r\n queryFn: () => SL.app.records.resolveAll(\r\n collectionId, appId,\r\n {\r\n context,\r\n ...(recordType ? { recordType } : {}),\r\n ...(tiers ? { tiers: tiers as Array<Exclude<MatchedAt, 'universal'>> } : {}),\r\n ...(limit !== undefined ? { limit } : {}),\r\n ...(at ? { at } : {}),\r\n ...(includeScheduled !== undefined ? { includeScheduled } : {}),\r\n ...(includeExpired !== undefined ? { includeExpired } : {}),\r\n },\r\n admin,\r\n ),\r\n });\r\n\r\n return {\r\n records: query.data?.records ?? [],\r\n truncated: query.data?.truncated ?? false,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch: () => { void query.refetch(); },\r\n };\r\n}","// =============================================================================\r\n// useRulePreview — debounced live \"matches N products\" feedback for the\r\n// FacetRuleEditor. Wraps SDK 1.10 `app.records.previewRule()` (admin-only).\r\n//\r\n// Returns a sample of product IDs and the total count so admins can sanity-\r\n// check the rule they are authoring before saving.\r\n// =============================================================================\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\nimport type { FacetRule, FacetRuleClause, PreviewRuleResult } from '../data/sdkTypes';\r\n\r\nexport interface UseRulePreviewArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n rule: FacetRule | null;\r\n /** Sample size. Default 20, max 200. */\r\n limit?: number;\r\n /** Debounce window in ms while the admin types. Default 350ms. */\r\n debounceMs?: number;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseRulePreviewResult {\r\n totalMatches: number | null;\r\n sampleProductIds: string[];\r\n isLoading: boolean;\r\n isStale: boolean;\r\n error: Error | null;\r\n}\r\n\r\nconst isRuleValid = (rule: FacetRule | null): rule is FacetRule => {\r\n if (!rule || !Array.isArray(rule.all) || rule.all.length === 0) return false;\r\n return rule.all.every(\r\n (c: FacetRuleClause) => !!c.facetKey && Array.isArray(c.anyOf) && c.anyOf.length > 0,\r\n );\r\n};\r\n\r\nexport function useRulePreview(args: UseRulePreviewArgs): UseRulePreviewResult {\r\n const {\r\n SL, collectionId, appId, rule,\r\n limit = 20, debounceMs = 350, enabled = true,\r\n } = args;\r\n\r\n const [debouncedRule, setDebouncedRule] = useState<FacetRule | null>(rule);\r\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n useEffect(() => {\r\n if (timer.current) clearTimeout(timer.current);\r\n timer.current = setTimeout(() => setDebouncedRule(rule), debounceMs);\r\n return () => { if (timer.current) clearTimeout(timer.current); };\r\n }, [rule, debounceMs]);\r\n\r\n const valid = isRuleValid(debouncedRule);\r\n\r\n const query = useQuery<PreviewRuleResult>({\r\n queryKey: ['records-admin', 'preview-rule', collectionId, appId, debouncedRule, limit],\r\n enabled: enabled && !!collectionId && !!appId && valid,\r\n staleTime: 30_000,\r\n queryFn: () => SL.app.records.previewRule(collectionId, appId, {\r\n facetRule: debouncedRule as FacetRule,\r\n limit,\r\n }),\r\n });\r\n\r\n return {\r\n totalMatches: query.data?.totalMatches ?? null,\r\n sampleProductIds: query.data?.sampleProductIds ?? [],\r\n isLoading: query.isFetching,\r\n isStale: rule !== debouncedRule,\r\n error: (query.error as Error | null) ?? null,\r\n };\r\n}","// =============================================================================\r\n// useCollectedRecords — Returns EVERY record matching a target scope, ordered\r\n// most-specific → least-specific. Backed by server-side `match()` as of\r\n// SDK 1.9, so this is a single round-trip and honours facet AND/OR semantics.\r\n// =============================================================================\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { ParsedRef, ScopeKind, SmartLinksSDK, CollectedSort } from '../types';\r\nimport { parseRef } from '../data/refs';\r\nimport { matchRecords } from '../data/records';\r\nimport type { MatchEntry } from '../data/sdkTypes';\r\nimport { parsedRefToTarget } from '../data/scopeBridge';\r\n\r\nexport interface CollectedRecord<T = unknown> {\r\n /** The ref this record was loaded from. */\r\n ref: string;\r\n /** Parsed scope of the ref (gives you `productId`, `facetId`, etc.). */\r\n scope: ParsedRef;\r\n /** Domain payload. */\r\n data: T;\r\n /** Index in the resolution chain (0 = most-specific). */\r\n depth: number;\r\n}\r\n\r\nexport interface UseCollectedRecordsArgs {\r\n SL: SmartLinksSDK;\r\n appId: string;\r\n recordType?: string;\r\n collectionId: string;\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n /** Scopes to walk. Defaults to all four. */\r\n supportedScopes?: ScopeKind[];\r\n /** Drop scopes that don't have a record (default true). */\r\n filterEmpty?: boolean;\r\n /**\r\n * Ordering applied to the result. Defaults to specificity-descending\r\n * (most-specific scope first), matching the previous behaviour and aligning\r\n * with the future `match()` API.\r\n */\r\n sort?: CollectedSort;\r\n enabled?: boolean;\r\n}\r\n\r\nconst DEFAULT_SCOPES: ScopeKind[] = ['batch', 'variant', 'product', 'facet'];\r\n\r\n/** Read a possibly-nested field path from arbitrary record data. */\r\nconst readField = (data: unknown, path: string): unknown => {\r\n if (data == null || typeof data !== 'object') return undefined;\r\n return path.split('.').reduce<unknown>((acc, key) => {\r\n if (acc == null || typeof acc !== 'object') return undefined;\r\n return (acc as Record<string, unknown>)[key];\r\n }, data);\r\n};\r\n\r\nconst compareValues = (a: unknown, b: unknown): number => {\r\n // Nullish always sorts last regardless of direction.\r\n const aNull = a === undefined || a === null;\r\n const bNull = b === undefined || b === null;\r\n if (aNull && bNull) return 0;\r\n if (aNull) return 1;\r\n if (bNull) return -1;\r\n if (typeof a === 'number' && typeof b === 'number') return a - b;\r\n return String(a).localeCompare(String(b), undefined, { numeric: true, sensitivity: 'base' });\r\n};\r\n\r\nexport function useCollectedRecords<T = unknown>(args: UseCollectedRecordsArgs) {\r\n const {\r\n SL, appId, recordType, collectionId,\r\n productId, variantId, batchId, facetId, facetValue,\r\n supportedScopes = DEFAULT_SCOPES,\r\n filterEmpty = true,\r\n sort,\r\n enabled = true,\r\n } = args;\r\n\r\n const sortKey = sort\r\n ? sort.kind === 'field'\r\n ? `field:${sort.field}:${sort.direction ?? 'asc'}`\r\n : `specificity:${sort.direction ?? 'desc'}`\r\n : 'specificity:desc';\r\n\r\n const query = useQuery<CollectedRecord<T>[]>({\r\n queryKey: ['records-admin', 'collected', collectionId, appId, recordType ?? null,\r\n productId ?? null, variantId ?? null, batchId ?? null, facetId ?? null, facetValue ?? null,\r\n supportedScopes.join(','), filterEmpty, sortKey],\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime: 15_000,\r\n queryFn: async () => {\r\n const target = parseRef('');\r\n target.productId = productId;\r\n target.variantId = variantId;\r\n target.batchId = batchId;\r\n target.facetId = facetId;\r\n target.facetValue = facetValue;\r\n const ctx = { SL, collectionId, appId, recordType };\r\n const result = await matchRecords(ctx, parsedRefToTarget(target), { strategy: 'all' })\r\n .catch(() => null);\r\n const records = result?.records ?? [];\r\n // The server returns records ordered by descending specificity.\r\n // We map specificity → depth here so existing consumers keep working\r\n // (lower `depth` = more-specific, matching the previous semantics).\r\n const baseList: CollectedRecord<T>[] = records.map((entry: MatchEntry, i: number) => {\r\n const rec = entry.record;\r\n return {\r\n ref: rec.ref ?? '',\r\n scope: parseRef(rec.ref ?? ''),\r\n data: rec.data as T,\r\n depth: i,\r\n };\r\n });\r\n // `filterEmpty` is now a no-op — `match()` only returns records that exist.\r\n void filterEmpty;\r\n void supportedScopes;\r\n\r\n const sortKind = sort?.kind ?? 'specificity';\r\n const direction = sort?.direction ?? (sortKind === 'specificity' ? 'desc' : 'asc');\r\n const sign = direction === 'desc' ? -1 : 1;\r\n const fieldPath = sort?.kind === 'field' ? sort.field : '';\r\n\r\n const sorted = [...baseList].sort((a, b) => {\r\n if (sortKind === 'field') {\r\n const cmp = compareValues(readField(a.data, fieldPath), readField(b.data, fieldPath));\r\n if (cmp !== 0) return sign * cmp;\r\n // Stable tiebreak on specificity (most-specific first).\r\n return a.depth - b.depth;\r\n }\r\n // specificity: lower depth = more specific\r\n return direction === 'desc' ? a.depth - b.depth : b.depth - a.depth;\r\n });\r\n\r\n return sorted;\r\n },\r\n });\r\n\r\n return {\r\n items: query.data ?? [],\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch: query.refetch,\r\n };\r\n}","// =============================================================================\r\n// useMergedRecord — Deep-merges every record in the resolution chain so apps\r\n// can ship shared defaults at one scope and field-level overrides at another.\r\n//\r\n// Walks LEAST-specific → MOST-specific, so deeper scopes win on conflict\r\n// (i.e. a batch override beats the product default). The result includes\r\n// per-key `provenance` so the UI can show where each field came from.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { ParsedRef, ScopeKind, SmartLinksSDK } from '../types';\r\nimport type { MatchEntry } from '../data/sdkTypes';\r\nimport { parseRef } from '../data/refs';\r\nimport { matchRecords } from '../data/records';\r\nimport { parsedRefToTarget } from '../data/scopeBridge';\r\n\r\nexport type MergeStrategy = 'deep' | 'shallow';\r\n\r\nexport interface MergedRecord<T = unknown> {\r\n /** The merged result. */\r\n data: T | null;\r\n /**\r\n * For each top-level key, the ref of the record that contributed its\r\n * winning value. Useful for \"Inherited from facet:gluten-free\" hints.\r\n */\r\n provenance: Record<string, string>;\r\n /** Refs that contributed something to the merge, deepest-first. */\r\n layers: string[];\r\n}\r\n\r\nexport interface UseMergedRecordArgs<T> {\r\n SL: SmartLinksSDK;\r\n appId: string;\r\n recordType?: string;\r\n collectionId: string;\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n supportedScopes?: ScopeKind[];\r\n /**\r\n * Merge strategy. `deep` recursively merges plain objects; arrays are\r\n * replaced wholesale. `shallow` does Object.assign at the top level.\r\n * Default `deep`.\r\n */\r\n strategy?: MergeStrategy;\r\n /** Custom merge fn. Receives `(parent, child)` and returns the winner. */\r\n merge?: (parent: T | null, child: T) => T;\r\n enabled?: boolean;\r\n}\r\n\r\nconst DEFAULT_SCOPES: ScopeKind[] = ['batch', 'variant', 'product', 'facet'];\r\n\r\nconst isPlainObject = (v: unknown): v is Record<string, unknown> =>\r\n !!v && typeof v === 'object' && !Array.isArray(v) && (v as object).constructor === Object;\r\n\r\nconst deepMerge = <T,>(parent: T | null, child: T): T => {\r\n if (!isPlainObject(parent) || !isPlainObject(child)) return child;\r\n const out: Record<string, unknown> = { ...parent };\r\n for (const [k, v] of Object.entries(child)) {\r\n out[k] = isPlainObject(v) && isPlainObject(out[k])\r\n ? deepMerge(out[k] as T, v as T)\r\n : v;\r\n }\r\n return out as T;\r\n};\r\n\r\nconst shallowMerge = <T,>(parent: T | null, child: T): T => {\r\n if (!isPlainObject(parent) || !isPlainObject(child)) return child;\r\n return { ...(parent as object), ...(child as object) } as T;\r\n};\r\n\r\nexport function useMergedRecord<T = unknown>(args: UseMergedRecordArgs<T>) {\r\n const {\r\n SL, appId, recordType, collectionId,\r\n productId, variantId, batchId, facetId, facetValue,\r\n supportedScopes = DEFAULT_SCOPES,\r\n strategy = 'deep',\r\n merge,\r\n enabled = true,\r\n } = args;\r\n\r\n const mergeFn = useMemo(() => {\r\n if (merge) return merge;\r\n return strategy === 'shallow' ? shallowMerge : deepMerge;\r\n }, [merge, strategy]);\r\n\r\n const query = useQuery<MergedRecord<T>>({\r\n queryKey: ['records-admin', 'merged', collectionId, appId, recordType ?? null,\r\n productId ?? null, variantId ?? null, batchId ?? null, facetId ?? null, facetValue ?? null,\r\n supportedScopes.join(','), strategy],\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime: 15_000,\r\n queryFn: async (): Promise<MergedRecord<T>> => {\r\n const target = parseRef('');\r\n target.productId = productId;\r\n target.variantId = variantId;\r\n target.batchId = batchId;\r\n target.facetId = facetId;\r\n target.facetValue = facetValue;\r\n const ctx = { SL, collectionId, appId, recordType };\r\n void supportedScopes; // server resolves the chain\r\n const result = await matchRecords(ctx, parsedRefToTarget(target), { strategy: 'all' })\r\n .catch(() => null);\r\n const records = result?.records ?? [];\r\n if (records.length === 0) return { data: null, provenance: {}, layers: [] };\r\n const present = records.map((entry: MatchEntry) => ({\r\n ref: entry.record.ref ?? '',\r\n data: entry.record.data as T,\r\n }));\r\n\r\n // Merge least-specific → most-specific so deeper scopes win.\r\n const ordered = [...present].reverse();\r\n let merged: T | null = null;\r\n const provenance: Record<string, string> = {};\r\n for (const layer of ordered) {\r\n merged = mergeFn(merged, layer.data);\r\n if (isPlainObject(layer.data)) {\r\n for (const k of Object.keys(layer.data as object)) provenance[k] = layer.ref;\r\n }\r\n }\r\n return { data: merged, provenance, layers: present.map((p) => p.ref) };\r\n },\r\n });\r\n\r\n const data = query.data ?? { data: null, provenance: {}, layers: [] };\r\n return {\r\n ...data,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch: query.refetch,\r\n };\r\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/RecordsAdmin/shell/icons.ts","../../../src/components/RecordsAdmin/types/i18n.ts","../../../src/components/RecordsAdmin/types/presentation.ts","../../../src/components/RecordsAdmin/data/refs.ts","../../../src/components/RecordsAdmin/data/scopeBridge.ts","../../../src/components/RecordsAdmin/data/records.ts","../../../src/components/RecordsAdmin/hooks/useRecordList.ts","../../../src/components/RecordsAdmin/data/resolveRecord.ts","../../../src/components/RecordsAdmin/hooks/useResolvedRecord.ts","../../../src/components/RecordsAdmin/hooks/useRecordEditor.ts","../../../src/components/RecordsAdmin/hooks/useIntroDismissed.ts","../../../src/components/RecordsAdmin/hooks/useScopeProbe.ts","../../../src/components/RecordsAdmin/hooks/useFacetBrowse.ts","../../../src/components/RecordsAdmin/hooks/useProductBrowse.ts","../../../src/components/RecordsAdmin/hooks/useProductChildren.ts","../../../src/components/RecordsAdmin/hooks/useUnsavedGuard.ts","../../../src/components/RecordsAdmin/hooks/useDirtyNavigation.ts","../../../src/components/RecordsAdmin/shell/ConfirmDialog.tsx","../../../src/components/RecordsAdmin/hooks/useConfirmDialog.tsx","../../../src/components/RecordsAdmin/browser/ScopeTabs.tsx","../../../src/components/RecordsAdmin/browser/StatusFilterPills.tsx","../../../src/components/RecordsAdmin/browser/StatusDot.tsx","../../../src/components/RecordsAdmin/browser/DefaultRecordRow.tsx","../../../src/components/RecordsAdmin/browser/DefaultRecordCard.tsx","../../../src/components/RecordsAdmin/browser/RecordList.tsx","../../../src/components/RecordsAdmin/browser/EmptyStates.tsx","../../../src/components/RecordsAdmin/browser/PresentationSwitcher.tsx","../../../src/components/RecordsAdmin/hooks/usePresentationPref.ts","../../../src/components/RecordsAdmin/shell/ScopeBreadcrumb.tsx","../../../src/components/RecordsAdmin/editor/BulkActionsMenu.tsx","../../../src/components/RecordsAdmin/editor/DeleteButton.tsx","../../../src/components/RecordsAdmin/editor/RecordEditor.tsx","../../../src/components/RecordsAdmin/editor/ProductDrillDown.tsx","../../../src/components/RecordsAdmin/editor/PreviewPane.tsx","../../../src/components/RecordsAdmin/editor/PreviewScopePicker.tsx","../../../src/components/RecordsAdmin/shell/IntroCard.tsx","../../../src/components/RecordsAdmin/shell/UtilityRow.tsx","../../../src/components/RecordsAdmin/shell/ShellHeader.tsx","../../../src/components/RecordsAdmin/shell/UnsavedBanner.tsx","../../../src/components/RecordsAdmin/data/csv.ts","../../../src/components/RecordsAdmin/shell/tokens.css","../../../src/components/RecordsAdmin/shell/shell.css","../../../src/components/RecordsAdmin/shell/RecordsAdminShell.tsx","../../../src/components/RecordsAdmin/browser/RecordBrowser.tsx","../../../src/components/RecordsAdmin/editor/InheritanceMarker.tsx","../../../src/components/RecordsAdmin/editor/ResolvedPreview.tsx","../../../src/components/RecordsAdmin/hooks/useResolveAllRecords.ts","../../../src/components/RecordsAdmin/hooks/useRulePreview.ts","../../../src/components/RecordsAdmin/hooks/useCollectedRecords.ts","../../../src/components/RecordsAdmin/hooks/useMergedRecord.ts"],"names":["eq","total","useQueryClient","useState","useEffect","useCallback","useQuery","useRef","useMemo","QK","useInfiniteQuery","items","res","jsx","jsxs","Inbox","LayoutGrid","ImageIcon","Layers","Copy","Upload","Download","ChevronDown","Trash2","Fragment","Package","Eye","Lightbulb","CheckCircle2","AlertTriangle","X","label","Plus","Search","DEFAULT_SCOPES"],"mappings":"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","file":"index.js","sourcesContent":["// =============================================================================\r\n// RecordsAdmin — Icon registry (v0.4)\r\n//\r\n// Lucide icons used at known anchor points in the shell. Apps can override the\r\n// whole registry, or any subset, via the `icons` prop on RecordsAdminShell.\r\n// =============================================================================\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport {\r\n Package, Layers, Boxes, Tag, Globe,\r\n CheckCircle2, ArrowDownLeft, CircleDashed,\r\n Plus, Pencil, Copy, Trash2, Upload, Download,\r\n Eye, LayoutGrid, Inbox, SearchX,\r\n Database, FileText, Lightbulb, ChevronDown, MoreHorizontal,\r\n} from 'lucide-react';\r\nimport type { ScopeKind } from '../types';\r\n\r\nexport interface RecordsAdminIcons {\r\n scope: Record<ScopeKind | 'universal', LucideIcon>;\r\n status: { own: LucideIcon; inherited: LucideIcon; missing: LucideIcon };\r\n action: {\r\n add: LucideIcon; edit: LucideIcon; duplicate: LucideIcon; delete: LucideIcon;\r\n import: LucideIcon; export: LucideIcon; more: LucideIcon;\r\n };\r\n preview: { eye: LucideIcon; switch: LucideIcon };\r\n empty: { default: LucideIcon; search: LucideIcon };\r\n intro: { info: LucideIcon };\r\n /** Header — used when no `headerIcon` prop is passed. Apps can override\r\n * `byRecordType[recordType]` for a contextual icon, or `default` as the\r\n * catch-all. */\r\n header: { default: LucideIcon; byRecordType: Record<string, LucideIcon> };\r\n group: { chevron: LucideIcon };\r\n}\r\n\r\n/** Library defaults — every consumer gets these unless `icons` is overridden. */\r\nexport const DEFAULT_ICONS: RecordsAdminIcons = {\r\n scope: { product: Package, variant: Layers, batch: Boxes, facet: Tag, universal: Globe },\r\n status: { own: CheckCircle2, inherited: ArrowDownLeft, missing: CircleDashed },\r\n action: {\r\n add: Plus, edit: Pencil, duplicate: Copy, delete: Trash2,\r\n import: Upload, export: Download, more: MoreHorizontal,\r\n },\r\n preview: { eye: Eye, switch: LayoutGrid },\r\n empty: { default: Inbox, search: SearchX },\r\n intro: { info: Lightbulb },\r\n header: { default: Database, byRecordType: {} },\r\n group: { chevron: ChevronDown },\r\n};\r\n\r\n/** Deep-merge an `icons` prop onto the defaults. */\r\nexport function mergeIcons(override?: Partial<RecordsAdminIcons>): RecordsAdminIcons {\r\n if (!override) return DEFAULT_ICONS;\r\n return {\r\n scope: { ...DEFAULT_ICONS.scope, ...(override.scope ?? {}) },\r\n status: { ...DEFAULT_ICONS.status, ...(override.status ?? {}) },\r\n action: { ...DEFAULT_ICONS.action, ...(override.action ?? {}) },\r\n preview: { ...DEFAULT_ICONS.preview, ...(override.preview ?? {}) },\r\n empty: { ...DEFAULT_ICONS.empty, ...(override.empty ?? {}) },\r\n intro: { ...DEFAULT_ICONS.intro, ...(override.intro ?? {}) },\r\n header: {\r\n default: override.header?.default ?? DEFAULT_ICONS.header.default,\r\n byRecordType: { ...DEFAULT_ICONS.header.byRecordType, ...(override.header?.byRecordType ?? {}) },\r\n },\r\n group: { ...DEFAULT_ICONS.group, ...(override.group ?? {}) },\r\n };\r\n}\r\n\r\n/** Look up the right header icon based on prop precedence:\r\n * explicit `headerIcon` > `icons.header.byRecordType[type]` > `icons.header.default`. */\r\nexport function pickHeaderIcon(\r\n icons: RecordsAdminIcons,\r\n recordType?: string,\r\n): LucideIcon {\r\n if (recordType && icons.header.byRecordType[recordType]) {\r\n return icons.header.byRecordType[recordType];\r\n }\r\n return icons.header.default;\r\n}\r\n\r\n// Re-export the underlying Lucide icon type for app overrides.\r\nexport type { LucideIcon };\r\n","// =============================================================================\r\n// RecordsAdmin — i18n strings + defaults\r\n// =============================================================================\r\nexport interface RecordsAdminI18n {\r\n emptyTitle: string;\r\n emptyBody: string;\r\n noResults: string;\r\n searchPlaceholder: string;\r\n filterAll: string;\r\n filterConfigured: string;\r\n filterPartial: string;\r\n filterEmpty: string;\r\n save: string;\r\n discard: string;\r\n delete: string;\r\n /** Save button label while a save is in flight. */\r\n saving: string;\r\n /** Inline error label shown next to the Save button when a save fails. */\r\n saveError: string;\r\n inherited: string;\r\n override: string;\r\n reset: string;\r\n bulkActions: string;\r\n applyToMany: string;\r\n copyFrom: string;\r\n clear: string;\r\n importCsv: string;\r\n exportCsv: string;\r\n preview: string;\r\n editor: string;\r\n closePreview: string;\r\n openPreview: string;\r\n previewAs: string;\r\n previewAsDefault: string;\r\n confirmDelete: string;\r\n unsavedBadge: string;\r\n unsavedPromptTitle: string;\r\n unsavedPromptBody: string;\r\n unsavedPromptDiscard: string;\r\n unsavedPromptCancel: string;\r\n unsavedPromptSave: string;\r\n /**\r\n * Inline banner shown at the top of the shell while the editor is dirty.\r\n * `{name}` is replaced with the friendly label of the dirty record.\r\n */\r\n unsavedBannerBody: string;\r\n\r\n /** Presentation mode switcher labels. */\r\n presentationList: string;\r\n presentationGrid: string;\r\n presentationGallery: string;\r\n presentationCompact: string;\r\n\r\n /** Collection cardinality affordances. */\r\n newItem: string;\r\n noItemsTitle: string;\r\n noItemsBody: string;\r\n\r\n /**\r\n * Empty-state copy for the LEFT browse rail (the list itself is empty).\r\n * Defaults to a friendly \"no records exist yet\" message — distinct from\r\n * `emptyTitle/emptyBody` which is the RIGHT pane \"pick something\" prompt.\r\n */\r\n railEmptyTitle: string;\r\n railEmptyBody: string;\r\n}\r\n\r\nexport const DEFAULT_I18N: RecordsAdminI18n = {\r\n emptyTitle: 'Nothing here yet',\r\n emptyBody: 'Pick a record from the left to start editing.',\r\n noResults: 'No records match your search.',\r\n searchPlaceholder: 'Search…',\r\n filterAll: 'All',\r\n filterConfigured: 'Configured',\r\n filterPartial: 'Partial',\r\n filterEmpty: 'Empty',\r\n save: 'Save',\r\n discard: 'Discard',\r\n delete: 'Delete record',\r\n saving: 'Saving…',\r\n saveError: 'Save failed',\r\n inherited: 'Inherited',\r\n override: 'Override',\r\n reset: 'Reset to inherited',\r\n bulkActions: 'Bulk actions',\r\n applyToMany: 'Apply to many…',\r\n copyFrom: 'Copy from…',\r\n clear: 'Clear records…',\r\n importCsv: 'Import CSV',\r\n exportCsv: 'Export CSV',\r\n preview: 'Preview',\r\n editor: 'Editor',\r\n closePreview: 'Close preview',\r\n openPreview: 'Open preview',\r\n previewAs: 'Preview as',\r\n previewAsDefault: 'Same as edited',\r\n confirmDelete: 'Confirm delete',\r\n unsavedBadge: 'Unsaved',\r\n unsavedPromptTitle: 'Unsaved changes',\r\n unsavedPromptBody: 'You have unsaved changes. What would you like to do?',\r\n unsavedPromptDiscard: 'Discard changes',\r\n unsavedPromptCancel: 'Stay here',\r\n unsavedPromptSave: 'Save & continue',\r\n unsavedBannerBody: 'Unsaved changes on {name}',\r\n presentationList: 'List',\r\n presentationGrid: 'Grid',\r\n presentationGallery: 'Gallery',\r\n presentationCompact: 'Compact',\r\n newItem: 'New item',\r\n noItemsTitle: 'No items yet',\r\n noItemsBody: 'Create your first item to get started.',\r\n railEmptyTitle: 'No records yet',\r\n railEmptyBody: 'Records you create will appear here.',\r\n};","// =============================================================================\r\n// RecordsAdmin — Presentation modes & cardinality\r\n// =============================================================================\r\n\r\n/**\r\n * How records are laid out in the browse rail / panel.\r\n * - `list` → dense rows with status dot + label + subtitle (default).\r\n * - `grid` → square cards with thumbnail + label.\r\n * - `gallery` → larger 16:9 cards with thumbnail + label + subtitle.\r\n * - `compact` → minimal one-line rows (no subtitle, no status dot).\r\n */\r\nexport type RecordPresentation = 'list' | 'grid' | 'gallery' | 'compact';\r\n\r\nexport const ALL_PRESENTATIONS: RecordPresentation[] = ['list', 'grid', 'gallery', 'compact'];\r\n\r\n/**\r\n * Whether each scope holds at most one record of this type, or many.\r\n * - `singleton` → one record per scope (e.g. washing instructions). Default.\r\n * - `collection` → many records per scope (e.g. FAQs, recipes, SOPs).\r\n */\r\nexport type RecordCardinality = 'singleton' | 'collection';\r\n\r\n/**\r\n * How `useCollectedRecords` orders the aggregated chain.\r\n * - `specificity` → most-specific scope first (default).\r\n * - `field` → use a numeric/string `data.<field>` to sort.\r\n */\r\nexport type CollectedSort =\r\n | { kind: 'specificity'; direction?: 'asc' | 'desc' }\r\n | { kind: 'field'; field: string; direction?: 'asc' | 'desc' };","// =============================================================================\r\n// Ref parsing — `kind:id` segments joined by `/`\r\n// =============================================================================\r\nimport type { ParsedRef, ScopeKind } from '../types';\r\n\r\nconst KIND_KEYS: Record<ScopeKind | 'collection' | 'proof', keyof ParsedRef> = {\r\n product: 'productId',\r\n facet: 'facetId',\r\n variant: 'variantId',\r\n batch: 'batchId',\r\n proof: 'proofId',\r\n collection: 'collectionId',\r\n};\r\n\r\nexport const parseRef = (raw: string): ParsedRef => {\r\n const parsed: ParsedRef = { kind: 'collection', raw };\r\n if (!raw) return parsed;\r\n const segments = raw.split('/').filter(Boolean);\r\n let kind: ParsedRef['kind'] = 'collection';\r\n for (const seg of segments) {\r\n const idx = seg.indexOf(':');\r\n if (idx < 0) continue;\r\n const k = seg.slice(0, idx) as ScopeKind | 'collection' | 'proof';\r\n const id = seg.slice(idx + 1);\r\n if (k === 'facet') {\r\n // facet:<id>=<value> or facet:<id>\r\n const eq = id.indexOf('=');\r\n if (eq >= 0) {\r\n parsed.facetId = id.slice(0, eq);\r\n parsed.facetValue = id.slice(eq + 1);\r\n } else {\r\n parsed.facetId = id;\r\n }\r\n } else if (k in KIND_KEYS) {\r\n // @ts-expect-error narrow\r\n parsed[KIND_KEYS[k]] = id;\r\n }\r\n if (k !== 'collection') kind = k as ParsedRef['kind'];\r\n }\r\n parsed.kind = kind;\r\n return parsed;\r\n};\r\n\r\nexport interface BuildRefArgs {\r\n collectionId?: string;\r\n productId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n proofId?: string;\r\n}\r\n\r\nexport const buildRef = (a: BuildRefArgs): string => {\r\n const parts: string[] = [];\r\n if (a.facetId) {\r\n parts.push(a.facetValue ? `facet:${a.facetId}=${a.facetValue}` : `facet:${a.facetId}`);\r\n }\r\n if (a.productId) parts.push(`product:${a.productId}`);\r\n if (a.variantId) parts.push(`variant:${a.variantId}`);\r\n if (a.batchId) parts.push(`batch:${a.batchId}`);\r\n if (a.proofId) parts.push(`proof:${a.proofId}`);\r\n return parts.join('/');\r\n};\r\n\r\n/**\r\n * Build the resolution chain for a target ref, from most specific → least specific.\r\n * `supportedScopes` prunes scopes the app doesn't care about.\r\n */\r\nexport const resolutionChain = (\r\n target: ParsedRef,\r\n supportedScopes: ScopeKind[],\r\n): string[] => {\r\n const chain: string[] = [];\r\n // Most specific → least specific\r\n if (supportedScopes.includes('batch') && target.batchId && target.productId) {\r\n chain.push(buildRef({ productId: target.productId, batchId: target.batchId }));\r\n }\r\n if (supportedScopes.includes('variant') && target.variantId && target.productId) {\r\n chain.push(buildRef({ productId: target.productId, variantId: target.variantId }));\r\n }\r\n if (supportedScopes.includes('product') && target.productId) {\r\n chain.push(buildRef({ productId: target.productId }));\r\n }\r\n if (supportedScopes.includes('facet') && target.facetId) {\r\n chain.push(buildRef({ facetId: target.facetId, facetValue: target.facetValue }));\r\n }\r\n // Dedupe while preserving order\r\n return Array.from(new Set(chain));\r\n};","// =============================================================================\r\n// scopeBridge — Convert between our UI `ParsedRef` and the SDK `RecordScope`.\r\n//\r\n// Our `ParsedRef` is a UI-friendly flat object that round-trips with the\r\n// `kind:id/kind:id` URL refs. The SDK's `RecordScope` is the structured\r\n// canonical form used for server-side specificity & `match()`. Use these\r\n// helpers at every boundary so we never write a record without `scope`.\r\n// =============================================================================\r\nimport type { RecordScope, RecordTarget } from './sdkTypes';\r\nimport type { ParsedRef } from '../types';\r\n\r\nexport const parsedRefToScope = (ref: ParsedRef): RecordScope => {\r\n const scope: RecordScope = {};\r\n if (ref.productId) scope.productId = ref.productId;\r\n if (ref.variantId) scope.variantId = ref.variantId;\r\n if (ref.batchId) scope.batchId = ref.batchId;\r\n if (ref.proofId) scope.proofId = ref.proofId;\r\n if (ref.facetId) {\r\n scope.facets = [{\r\n key: ref.facetId,\r\n valueKeys: ref.facetValue ? [ref.facetValue] : [],\r\n }];\r\n }\r\n return scope;\r\n};\r\n\r\nexport const parsedRefToTarget = (ref: ParsedRef): RecordTarget => {\r\n const target: RecordTarget = {};\r\n if (ref.productId) target.productId = ref.productId;\r\n if (ref.variantId) target.variantId = ref.variantId;\r\n if (ref.batchId) target.batchId = ref.batchId;\r\n if (ref.proofId) target.proofId = ref.proofId;\r\n if (ref.facetId && ref.facetValue) {\r\n target.facets = { [ref.facetId]: [ref.facetValue] };\r\n }\r\n return target;\r\n};\r\n\r\n/**\r\n * Compare a winning record's scope against the editing scope.\r\n * Returns true when they refer to the same node — used to decide\r\n * \"self\" vs \"inherited\" when consuming `match()` results.\r\n */\r\nexport const scopesEqual = (a: RecordScope, b: RecordScope): boolean => {\r\n if ((a.productId ?? null) !== (b.productId ?? null)) return false;\r\n if ((a.variantId ?? null) !== (b.variantId ?? null)) return false;\r\n if ((a.batchId ?? null) !== (b.batchId ?? null)) return false;\r\n if ((a.proofId ?? null) !== (b.proofId ?? null)) return false;\r\n const af = a.facets ?? [];\r\n const bf = b.facets ?? [];\r\n if (af.length !== bf.length) return false;\r\n const norm = (xs: typeof af) => xs\r\n .map((f) => `${f.key}:${[...f.valueKeys].sort().join(',')}`)\r\n .sort()\r\n .join('|');\r\n return norm(af) === norm(bf);\r\n};","// =============================================================================\r\n// Thin wrappers over SL.app.records.* — always admin: true here.\r\n//\r\n// As of `@proveanything/smartlinks` 1.9.0 the records surface ships a proper\r\n// `upsert()`, server-side `match()`, and atomic `bulkUpsert` / `bulkDelete`.\r\n// We delegate to those rather than rolling our own list+update sequences,\r\n// which were racy and ignored facet AND-of-OR semantics.\r\n// =============================================================================\r\nimport type {\r\n AppRecord, RecordScope, RecordTarget, BulkUpsertItem, BulkDeleteResult,\r\n MatchResult,\r\n} from './sdkTypes';\r\nimport type { ParsedRef, SmartLinksSDK } from '../types';\r\nimport { parsedRefToScope } from './scopeBridge';\r\n\r\nexport interface RecordsCtx {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n /** Optional — when omitted, records are stored against the app id alone\r\n * (no type qualifier). Set this only when an app uses multiple record types\r\n * and needs to query/scope by type. */\r\n recordType?: string;\r\n}\r\n\r\n/** Shape of a single record write — uses the SDK's structured `scope`. */\r\nexport interface RecordWrite<T = unknown> {\r\n /** Logical key. The server canonicalises this from `scope` if omitted. */\r\n ref?: string;\r\n /** Structured scope; required for specificity / `match()` to work. */\r\n scope: RecordScope;\r\n data: T;\r\n visibility?: 'public' | 'owner' | 'admin';\r\n productId?: string;\r\n status?: string;\r\n startsAt?: string | null;\r\n expiresAt?: string | null;\r\n customId?: string;\r\n sourceSystem?: string;\r\n}\r\n\r\nexport const listRecords = async (\r\n ctx: RecordsCtx,\r\n params: { ref?: string; refPrefix?: string; q?: string; limit?: number; offset?: number; sort?: string } = {},\r\n): Promise<{ data: AppRecord[]; total: number; hasMore: boolean }> => {\r\n const { limit = 100, offset, ref, refPrefix, q, sort } = params;\r\n const res = await ctx.SL.app.records.list(\r\n ctx.collectionId,\r\n ctx.appId,\r\n {\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n limit, offset, ref, refPrefix, q, sort,\r\n },\r\n true,\r\n );\r\n return {\r\n data: res?.data ?? [],\r\n total: res?.pagination?.total ?? (res?.data?.length ?? 0),\r\n hasMore: res?.pagination?.hasMore ?? false,\r\n };\r\n};\r\n\r\n/** Look up a single record by its canonical ref. */\r\nexport const getRecordByRef = async (\r\n ctx: RecordsCtx,\r\n ref: string,\r\n): Promise<AppRecord | null> => {\r\n const res = await ctx.SL.app.records.list(\r\n ctx.collectionId,\r\n ctx.appId,\r\n { ...(ctx.recordType ? { recordType: ctx.recordType } : {}), ref, limit: 1 },\r\n true,\r\n );\r\n return res?.data?.[0] ?? null;\r\n};\r\n\r\n/**\r\n * Atomic upsert via the SDK. Always sends `scope` so the server can compute\r\n * `specificity` and derive `ref` deterministically.\r\n */\r\nexport const upsertRecord = async <T,>(\r\n ctx: RecordsCtx,\r\n write: RecordWrite<T>,\r\n): Promise<{ record: AppRecord; isCreate: boolean }> => {\r\n const ref = write.ref ?? deriveRefFromScope(write.scope);\r\n const res = await ctx.SL.app.records.upsert(ctx.collectionId, ctx.appId, {\r\n ref,\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n scope: write.scope,\r\n data: write.data as Record<string, unknown>,\r\n status: write.status,\r\n startsAt: write.startsAt,\r\n expiresAt: write.expiresAt,\r\n customId: write.customId,\r\n sourceSystem: write.sourceSystem,\r\n });\r\n return { record: res, isCreate: !!res?.created };\r\n};\r\n\r\n/**\r\n * Convenience wrapper for callers that only have a `ParsedRef` and a payload —\r\n * matches the previous (`ref`, `data`) call shape used by the editor hook.\r\n */\r\nexport const upsertRecordForScope = async <T,>(\r\n ctx: RecordsCtx,\r\n scope: ParsedRef,\r\n data: T,\r\n extra: { visibility?: 'public' | 'owner' | 'admin' } = {},\r\n) => upsertRecord<T>(ctx, {\r\n ref: scope.raw || undefined,\r\n scope: parsedRefToScope(scope),\r\n data,\r\n visibility: extra.visibility,\r\n});\r\n\r\nexport const deleteRecord = async (\r\n ctx: RecordsCtx,\r\n ref: string,\r\n): Promise<boolean> => {\r\n const existing = await getRecordByRef(ctx, ref).catch(() => null);\r\n if (!existing) return false;\r\n await ctx.SL.app.records.remove(ctx.collectionId, ctx.appId, existing.id, true);\r\n return true;\r\n};\r\n\r\n/** Restore a soft-deleted record by ID (admin only). */\r\nexport const restoreRecord = async (\r\n ctx: RecordsCtx,\r\n recordId: string,\r\n): Promise<AppRecord> => ctx.SL.app.records.restore(ctx.collectionId, ctx.appId, recordId);\r\n\r\n/**\r\n * Server-side match — single round trip that returns every record whose\r\n * `scope` is satisfied by `target`, ordered by descending `specificity`.\r\n * Replaces the per-scope N+1 chain walk we used pre-1.9.\r\n */\r\nexport const matchRecords = async (\r\n ctx: RecordsCtx,\r\n target: RecordTarget,\r\n opts: {\r\n strategy?: 'all' | 'best';\r\n at?: string;\r\n includeScheduled?: boolean;\r\n includeExpired?: boolean;\r\n limit?: number;\r\n } = {},\r\n): Promise<MatchResult> => ctx.SL.app.records.match(\r\n ctx.collectionId,\r\n ctx.appId,\r\n {\r\n target,\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n strategy: opts.strategy ?? 'all',\r\n at: opts.at,\r\n includeScheduled: opts.includeScheduled,\r\n includeExpired: opts.includeExpired,\r\n limit: opts.limit,\r\n },\r\n true,\r\n);\r\n\r\n/**\r\n * Server-side bulk upsert. Up to 500 rows per call; any leftover is chunked.\r\n * Each row is error-isolated by the server.\r\n */\r\nexport const bulkUpsert = async <T,>(\r\n ctx: RecordsCtx,\r\n entries: Array<{ ref?: string; scope: RecordScope; data: T; status?: string }>,\r\n): Promise<{ saved: number; failed: number }> => {\r\n const CHUNK = 500;\r\n let saved = 0;\r\n let failed = 0;\r\n for (let i = 0; i < entries.length; i += CHUNK) {\r\n const slice = entries.slice(i, i + CHUNK);\r\n const items: BulkUpsertItem[] = slice.map((e) => ({\r\n ref: e.ref ?? deriveRefFromScope(e.scope),\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n scope: e.scope,\r\n data: e.data as Record<string, unknown>,\r\n status: e.status,\r\n }));\r\n const res = await ctx.SL.app.records.bulkUpsert(ctx.collectionId, ctx.appId, items)\r\n .catch((): { saved: number; failed: number } => ({ saved: 0, failed: items.length }));\r\n saved += res.saved ?? 0;\r\n failed += res.failed ?? 0;\r\n }\r\n return { saved, failed };\r\n};\r\n\r\n/**\r\n * Server-side bulk delete. Accepts an explicit ref list (max 1000 per call,\r\n * chunked here) or a scope anchor (single call).\r\n */\r\nexport const bulkDelete = async (\r\n ctx: RecordsCtx,\r\n input: { refs: string[] } | { scope: Omit<RecordScope, 'facets'> },\r\n): Promise<{ removed: number }> => {\r\n if ('scope' in input) {\r\n const res: BulkDeleteResult = await ctx.SL.app.records.bulkDelete(\r\n ctx.collectionId, ctx.appId,\r\n { scope: input.scope, ...(ctx.recordType ? { recordType: ctx.recordType } : {}) },\r\n );\r\n return { removed: res.deleted ?? 0 };\r\n }\r\n\r\n const CHUNK = 1000;\r\n let removed = 0;\r\n for (let i = 0; i < input.refs.length; i += CHUNK) {\r\n const slice = input.refs.slice(i, i + CHUNK);\r\n const res: BulkDeleteResult = await ctx.SL.app.records.bulkDelete(\r\n ctx.collectionId, ctx.appId,\r\n { refs: slice, ...(ctx.recordType ? { recordType: ctx.recordType } : {}) },\r\n );\r\n removed += res.deleted ?? 0;\r\n }\r\n return { removed };\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Internal — derive a stable ref string from a structured scope. The server\r\n// re-derives this canonically on write; we send our best guess so callers\r\n// (and our own list/lookup helpers) can find the record by ref afterwards.\r\n// ---------------------------------------------------------------------------\r\nconst deriveRefFromScope = (scope: RecordScope): string => {\r\n const parts: string[] = [];\r\n if (scope.facets && scope.facets.length > 0) {\r\n // Sort for determinism.\r\n const sorted = [...scope.facets].sort((a, b) => a.key.localeCompare(b.key));\r\n for (const f of sorted) {\r\n const vals = [...f.valueKeys].sort().join(',');\r\n parts.push(vals ? `facet:${f.key}=${vals}` : `facet:${f.key}`);\r\n }\r\n }\r\n if (scope.productId) parts.push(`product:${scope.productId}`);\r\n if (scope.variantId) parts.push(`variant:${scope.variantId}`);\r\n if (scope.batchId) parts.push(`batch:${scope.batchId}`);\r\n if (scope.proofId) parts.push(`proof:${scope.proofId}`);\r\n return parts.join('/');\r\n};","import { useMemo, useCallback, useState, useEffect } from 'react';\r\nimport { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';\r\nimport type { RecordSummary, RecordStatus, ScopeKind, ParsedRef } from '../types';\r\nimport { parseRef } from '../data/refs';\r\nimport { listRecords, type RecordsCtx } from '../data/records';\r\nimport type { AppRecord } from '../data/sdkTypes';\r\n\r\nexport interface UseRecordListArgs {\r\n ctx: RecordsCtx;\r\n scopeKind: ScopeKind;\r\n search?: string;\r\n filter?: 'all' | RecordStatus;\r\n classify?: (record: RecordSummary) => RecordStatus;\r\n enabled?: boolean;\r\n scaffolder?: (existing: RecordSummary[]) => Promise<RecordSummary[]> | RecordSummary[];\r\n /**\r\n * Constrain the list to a subtree (e.g. a specific product when the host URL\r\n * pins one). Records whose ParsedRef does not match every set field are dropped.\r\n */\r\n contextScope?: { productId?: string; variantId?: string; batchId?: string };\r\n /** Page size requested from the SDK (default 100). */\r\n pageSize?: number;\r\n}\r\n\r\nconst defaultClassify = (r: RecordSummary): RecordStatus => {\r\n if (!r.data) return 'empty';\r\n const keys = Object.keys(r.data as Record<string, unknown>);\r\n if (keys.length === 0) return 'empty';\r\n return 'configured';\r\n};\r\n\r\nconst matchesScope = (kind: ScopeKind, p: ParsedRef): boolean => {\r\n if (kind === 'product') return !!p.productId && !p.variantId && !p.batchId;\r\n if (kind === 'facet') return !!p.facetId;\r\n if (kind === 'variant') return !!p.variantId;\r\n if (kind === 'batch') return !!p.batchId;\r\n return false;\r\n};\r\n\r\nconst matchesContext = (\r\n p: ParsedRef,\r\n ctx: { productId?: string; variantId?: string; batchId?: string } | undefined,\r\n): boolean => {\r\n if (!ctx) return true;\r\n if (ctx.productId && p.productId !== ctx.productId) return false;\r\n if (ctx.variantId && p.variantId !== ctx.variantId) return false;\r\n if (ctx.batchId && p.batchId !== ctx.batchId) return false;\r\n return true;\r\n};\r\n\r\nconst toSummary = (rec: AppRecord): RecordSummary => {\r\n const ref = rec.ref ?? '';\r\n const scope = parseRef(ref);\r\n return {\r\n id: rec.id,\r\n ref,\r\n scope,\r\n data: rec.data ?? null,\r\n status: 'configured',\r\n label: scope.batchId ?? scope.variantId ?? scope.productId ?? scope.facetValue ?? scope.facetId ?? ref,\r\n updatedAt: rec.updatedAt,\r\n };\r\n};\r\n\r\nconst QK_BASE = ['records-admin', 'list'] as const;\r\n\r\nexport const useRecordList = (args: UseRecordListArgs) => {\r\n const {\r\n ctx, scopeKind, search = '', filter = 'all',\r\n classify, enabled = true, scaffolder, contextScope, pageSize = 100,\r\n } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const queryKey = useMemo(\r\n () => [...QK_BASE, ctx.collectionId, ctx.appId, ctx.recordType, scopeKind,\r\n contextScope?.productId ?? null, contextScope?.variantId ?? null, contextScope?.batchId ?? null],\r\n [ctx.collectionId, ctx.appId, ctx.recordType, scopeKind, contextScope?.productId, contextScope?.variantId, contextScope?.batchId],\r\n );\r\n\r\n const query = useInfiniteQuery({\r\n queryKey,\r\n enabled,\r\n initialPageParam: 0,\r\n queryFn: async ({ pageParam }) => {\r\n const offset = pageParam as number;\r\n const { data, total, hasMore } = await listRecords(ctx, { limit: pageSize, offset });\r\n return { data, total, hasMore, nextOffset: offset + data.length };\r\n },\r\n getNextPageParam: (last) => (last.hasMore ? last.nextOffset : undefined),\r\n staleTime: 30_000,\r\n });\r\n\r\n const [scaffolded, setScaffolded] = useState<RecordSummary[] | null>(null);\r\n\r\n const rawItems = useMemo(() => {\r\n const all = query.data?.pages.flatMap((p) => p.data) ?? [];\r\n const cls = classify ?? defaultClassify;\r\n return all\r\n .map(toSummary)\r\n .filter((s) => matchesScope(scopeKind, s.scope))\r\n .filter((s) => matchesContext(s.scope, contextScope))\r\n .map((s) => ({ ...s, status: cls(s) }));\r\n }, [query.data, scopeKind, classify, contextScope]);\r\n\r\n // Run optional scaffolder when raw items change\r\n useEffect(() => {\r\n if (!scaffolder) { setScaffolded(null); return; }\r\n let cancelled = false;\r\n Promise.resolve(scaffolder(rawItems)).then((next) => {\r\n if (!cancelled) setScaffolded(next);\r\n });\r\n return () => { cancelled = true; };\r\n }, [rawItems, scaffolder]);\r\n\r\n const items = scaffolded ?? rawItems;\r\n\r\n const filtered = useMemo(() => {\r\n let out = items;\r\n if (filter !== 'all') out = out.filter((r) => r.status === filter);\r\n if (search.trim()) {\r\n const q = search.trim().toLowerCase();\r\n out = out.filter((r) => `${r.label} ${r.subtitle ?? ''} ${r.ref}`.toLowerCase().includes(q));\r\n }\r\n return out;\r\n }, [items, filter, search]);\r\n\r\n const counts = useMemo(() => ({\r\n all: items.length,\r\n configured: items.filter((r) => r.status === 'configured').length,\r\n partial: items.filter((r) => r.status === 'partial').length,\r\n empty: items.filter((r) => r.status === 'empty').length,\r\n }), [items]);\r\n\r\n const refetch = useCallback(() => {\r\n queryClient.invalidateQueries({ queryKey: [...QK_BASE, ctx.collectionId, ctx.appId, ctx.recordType] });\r\n }, [queryClient, ctx.collectionId, ctx.appId, ctx.recordType]);\r\n\r\n const total = query.data?.pages[query.data.pages.length - 1]?.total ?? items.length;\r\n\r\n return {\r\n allItems: items,\r\n items: filtered,\r\n total,\r\n counts,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch,\r\n hasNextPage: query.hasNextPage,\r\n isFetchingNextPage: query.isFetchingNextPage,\r\n fetchNextPage: query.fetchNextPage,\r\n };\r\n};","// =============================================================================\r\n// Canonical record resolver — backed by server-side `match()`.\r\n//\r\n// As of `@proveanything/smartlinks` 1.9 this is a single round-trip:\r\n// the server evaluates the full scope chain (including facet AND/OR\r\n// semantics we cannot replicate client-side) and returns records ordered\r\n// by descending specificity. We classify the winning record as `self` vs\r\n// `inherited` by comparing its `scope` against the editing scope.\r\n// =============================================================================\r\nimport type { ParsedRef, ResolvedRecord, ScopeKind } from '../types';\r\nimport { matchRecords, type RecordsCtx } from './records';\r\nimport { parsedRefToScope, parsedRefToTarget, scopesEqual } from './scopeBridge';\r\n\r\nexport interface ResolveArgs {\r\n ctx: RecordsCtx;\r\n target: ParsedRef;\r\n /**\r\n * Ignored — kept for API compatibility. The server determines the\r\n * resolution chain from the structured scope.\r\n */\r\n supportedScopes?: ScopeKind[];\r\n /** When true, also returns the parent value (next-best after self). */\r\n withParent?: boolean;\r\n admin?: boolean;\r\n}\r\n\r\nexport const resolveRecord = async <T,>(args: ResolveArgs): Promise<ResolvedRecord<T>> => {\r\n const target = parsedRefToTarget(args.target);\r\n const editingScope = parsedRefToScope(args.target);\r\n\r\n const result = await matchRecords(args.ctx, target, { strategy: 'all' })\r\n .catch(() => null);\r\n const records = result?.records ?? [];\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdmin/resolveRecord]', {\r\n editingScope,\r\n target,\r\n matchCount: records.length,\r\n winnerScope: records[0]?.record?.scope,\r\n winnerRef: records[0]?.record?.ref,\r\n });\r\n if (records.length === 0) {\r\n return { data: null, source: 'empty' };\r\n }\r\n\r\n const winnerEntry = records[0];\r\n const winner = winnerEntry.record;\r\n const winnerIsSelf = scopesEqual(winner.scope, editingScope);\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdmin/resolveRecord] classification', {\r\n winnerIsSelf,\r\n winnerScope: winner.scope,\r\n editingScope,\r\n });\r\n\r\n if (winnerIsSelf) {\r\n const parent = records[1]?.record;\r\n return {\r\n data: winner.data as T,\r\n source: 'self',\r\n sourceRef: winner.ref ?? undefined,\r\n parentValue: args.withParent && parent ? (parent.data as T) : undefined,\r\n matchedAt: winnerEntry.matchedAt,\r\n matchedRule: winnerEntry.matchedRule,\r\n };\r\n }\r\n return {\r\n data: winner.data as T,\r\n source: 'inherited',\r\n sourceRef: winner.ref ?? undefined,\r\n parentValue: args.withParent ? (winner.data as T) : undefined,\r\n matchedAt: winnerEntry.matchedAt,\r\n matchedRule: winnerEntry.matchedRule,\r\n };\r\n};","// =============================================================================\r\n// useResolvedRecord — resolver hook backed by react-query.\r\n// =============================================================================\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { ResolvedRecord, ScopeKind, SmartLinksSDK } from '../types';\r\nimport { resolveRecord } from '../data/resolveRecord';\r\nimport { parseRef } from '../data/refs';\r\n\r\nexport interface UseResolvedRecordArgs {\r\n SL: SmartLinksSDK;\r\n appId: string;\r\n /** Optional — see `RecordsAdminShellProps.recordType`. */\r\n recordType?: string;\r\n collectionId: string;\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n proofId?: string;\r\n supportedScopes?: ScopeKind[];\r\n enabled?: boolean;\r\n withParent?: boolean;\r\n}\r\n\r\nconst DEFAULT_SCOPES: ScopeKind[] = ['batch', 'variant', 'product', 'facet'];\r\n\r\n/**\r\n * Build the react-query key used by `useResolvedRecord`. Exported so other\r\n * hooks (notably `useRecordEditor`'s optimistic save path) can prime or\r\n * roll back the resolved-record cache for the same scope.\r\n */\r\nexport const resolvedRecordQueryKey = (args: {\r\n collectionId: string;\r\n appId: string;\r\n recordType?: string;\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n proofId?: string;\r\n withParent?: boolean;\r\n}): unknown[] => [\r\n 'records-admin', 'resolved',\r\n args.collectionId, args.appId, args.recordType ?? null,\r\n args.productId ?? null, args.variantId ?? null, args.batchId ?? null,\r\n args.facetId ?? null, args.facetValue ?? null, args.proofId ?? null,\r\n args.withParent ?? true,\r\n];\r\n\r\nexport function useResolvedRecord<T = unknown>(args: UseResolvedRecordArgs) {\r\n const {\r\n SL, appId, recordType, collectionId,\r\n productId, variantId, batchId, facetId, facetValue, proofId,\r\n supportedScopes = DEFAULT_SCOPES,\r\n enabled = true,\r\n withParent = true,\r\n } = args;\r\n\r\n const query = useQuery<ResolvedRecord<T>>({\r\n queryKey: resolvedRecordQueryKey({\r\n collectionId, appId, recordType,\r\n productId, variantId, batchId, facetId, facetValue, proofId, withParent,\r\n }),\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime: 15_000,\r\n queryFn: async () => {\r\n const target = parseRef('');\r\n target.productId = productId;\r\n target.variantId = variantId;\r\n target.batchId = batchId;\r\n target.facetId = facetId;\r\n target.facetValue = facetValue;\r\n target.proofId = proofId;\r\n return resolveRecord<T>({\r\n ctx: { SL, collectionId, appId, recordType },\r\n target,\r\n supportedScopes,\r\n withParent,\r\n });\r\n },\r\n });\r\n\r\n const data: ResolvedRecord<T> = query.data ?? { data: null, source: 'empty' };\r\n return {\r\n ...data,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n };\r\n}","import { useCallback, useEffect, useRef, useState } from 'react';\r\nimport { useQueryClient } from '@tanstack/react-query';\r\nimport type { EditorContext, ParsedRef, ResolvedRecord } from '../types';\r\nimport { upsertRecord, deleteRecord, type RecordsCtx } from '../data/records';\r\nimport { parsedRefToScope } from '../data/scopeBridge';\r\nimport { resolvedRecordQueryKey } from './useResolvedRecord';\r\n\r\nexport interface UseRecordEditorArgs<T> {\r\n ctx: RecordsCtx;\r\n scope: ParsedRef;\r\n resolved: ResolvedRecord<T>;\r\n defaultData?: () => T;\r\n onSaved?: () => void;\r\n onDeleted?: () => void;\r\n /** Fired after a save fails and local state has been rolled back. */\r\n onSaveError?: (err: unknown) => void;\r\n /**\r\n * Controls how the editor reseeds its local value when the resolved\r\n * record changes. Default `'always'` matches legacy behaviour.\r\n * `'preserve-dirty'` keeps unsaved local edits across resolve refreshes\r\n * (used by the shell when `dirtyStrategy === 'keep'`).\r\n */\r\n reseed?: 'always' | 'preserve-dirty';\r\n}\r\n\r\nconst isEqual = (a: unknown, b: unknown) => {\r\n try { return JSON.stringify(a) === JSON.stringify(b); }\r\n catch { return false; }\r\n};\r\n\r\nconst cloneSeed = <T,>(resolved: ResolvedRecord<T>, defaultData?: () => T): T => {\r\n if (resolved.source === 'self') return resolved.data as T;\r\n if (resolved.source === 'inherited' && resolved.data != null) {\r\n try { return structuredClone(resolved.data); }\r\n catch { return JSON.parse(JSON.stringify(resolved.data)) as T; }\r\n }\r\n return defaultData?.() ?? ({} as T);\r\n};\r\n\r\nexport function useRecordEditor<T>(args: UseRecordEditorArgs<T>): EditorContext<T> {\r\n const {\r\n ctx, scope, resolved, defaultData, onSaved, onDeleted, onSaveError,\r\n reseed = 'always',\r\n } = args;\r\n const queryClient = useQueryClient();\r\n const seed = cloneSeed(resolved, defaultData);\r\n\r\n const [value, setValue] = useState<T>(seed);\r\n const [savedSnapshot, setSavedSnapshot] = useState<T>(seed);\r\n /** Local override of `resolved.source` while a save is in flight or just\r\n * landed — lets the editor flip to `'self'` before the refetch confirms. */\r\n const [optimisticSource, setOptimisticSource] = useState<ResolvedRecord<T>['source'] | null>(null);\r\n const [isSaving, setIsSaving] = useState(false);\r\n const [saveError, setSaveError] = useState<unknown | null>(null);\r\n // Track the most-recent `value` without forcing reseeds to depend on it.\r\n const valueRef = useRef<T>(seed);\r\n useEffect(() => { valueRef.current = value; }, [value]);\r\n\r\n useEffect(() => {\r\n const fresh = cloneSeed(resolved, defaultData);\r\n if (reseed === 'preserve-dirty') {\r\n // Only reseed the editor value when there are no unsaved local edits;\r\n // otherwise just refresh the saved snapshot baseline.\r\n const hasUnsaved = !isEqual(valueRef.current, savedSnapshot);\r\n if (!hasUnsaved) setValue(fresh);\r\n } else {\r\n setValue(fresh);\r\n }\r\n setSavedSnapshot(fresh);\r\n // Real server state has caught up — drop any optimistic source override.\r\n setOptimisticSource(null);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [scope.raw, resolved.source, resolved.sourceRef]);\r\n\r\n // Dirty is strictly local-edit vs saved-snapshot. Inheritance state has\r\n // its own UI signal (`source`) and must not bleed into dirtiness.\r\n const isDirty = !isEqual(value, savedSnapshot);\r\n\r\n /**\r\n * Optimistic save:\r\n * 1. Snapshot prior state.\r\n * 2. Flip local UI to \"saved + self\" immediately (Save disables, status\r\n * dot turns green, `isDirty` clears).\r\n * 3. Prime the resolved-record cache so anything else reading it (the\r\n * rail, preview, sibling consumers) reflects the new value too.\r\n * 4. Fire the upsert in the background.\r\n * 5. On success: fire `onSaved` (the shell uses this to refetch and\r\n * reconcile — the prior `setQueryData` makes that a no-op visually).\r\n * 6. On failure: roll all three back, surface the error, leave the\r\n * editor dirty so the user can retry.\r\n */\r\n const save = useCallback(async () => {\r\n if (!scope.raw) return;\r\n const previousSnapshot = savedSnapshot;\r\n const previousSource = resolved.source;\r\n const cacheKey = resolvedRecordQueryKey({\r\n collectionId: ctx.collectionId,\r\n appId: ctx.appId,\r\n recordType: ctx.recordType,\r\n productId: scope.productId,\r\n variantId: scope.variantId,\r\n batchId: scope.batchId,\r\n facetId: scope.facetId,\r\n facetValue: scope.facetValue,\r\n proofId: scope.proofId,\r\n withParent: true,\r\n });\r\n const previousCache = queryClient.getQueryData<ResolvedRecord<T>>(cacheKey);\r\n\r\n // Optimistic flip — the UI shows \"saved\" before the server confirms.\r\n setSaveError(null);\r\n setIsSaving(true);\r\n setSavedSnapshot(value);\r\n setOptimisticSource('self');\r\n queryClient.setQueryData<ResolvedRecord<T>>(cacheKey, {\r\n data: value,\r\n source: 'self',\r\n sourceRef: scope.raw,\r\n parentValue: previousCache?.parentValue ?? resolved.parentValue,\r\n });\r\n\r\n try {\r\n await upsertRecord<T>(ctx, {\r\n ref: scope.raw,\r\n scope: parsedRefToScope(scope),\r\n data: value,\r\n });\r\n onSaved?.();\r\n } catch (err) {\r\n // Roll everything back — local snapshot, optimistic source, cache.\r\n setSavedSnapshot(previousSnapshot);\r\n setOptimisticSource(null);\r\n if (previousCache !== undefined) {\r\n queryClient.setQueryData(cacheKey, previousCache);\r\n } else {\r\n queryClient.invalidateQueries({ queryKey: cacheKey });\r\n }\r\n setSaveError(err);\r\n onSaveError?.(err);\r\n void previousSource;\r\n throw err;\r\n } finally {\r\n setIsSaving(false);\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [scope.raw, value, savedSnapshot, resolved.source, resolved.parentValue]);\r\n\r\n const reset = useCallback(() => {\r\n setValue(savedSnapshot);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [savedSnapshot]);\r\n\r\n const remove = useCallback(async () => {\r\n if (resolved.source !== 'self' || !scope.raw) return;\r\n await deleteRecord(ctx, scope.raw);\r\n onDeleted?.();\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [resolved.source, scope.raw]);\r\n\r\n const effectiveSource = optimisticSource ?? resolved.source;\r\n\r\n return {\r\n value,\r\n onChange: setValue,\r\n source: effectiveSource,\r\n parentValue: resolved.parentValue,\r\n scope,\r\n isDirty,\r\n save,\r\n reset,\r\n remove,\r\n canRemove: effectiveSource === 'self',\r\n isSaving,\r\n saveError,\r\n };\r\n}","import { useCallback, useEffect, useState } from 'react';\r\nimport type { SmartLinksSDK } from '../types';\r\n\r\n/** Untyped apps share a single intro-dismissed slot under `_default`. */\r\nconst RT_KEY = (recordType?: string) => recordType ?? '_default';\r\nconst lsKey = (appId: string, recordType?: string) => `ra:intro:${appId}:${RT_KEY(recordType)}`;\r\n\r\nexport const useIntroDismissed = (\r\n SL: SmartLinksSDK,\r\n collectionId: string,\r\n appId: string,\r\n recordType?: string,\r\n) => {\r\n const [dismissed, setDismissed] = useState<boolean>(() => {\r\n try { return localStorage.getItem(lsKey(appId, recordType)) === '1'; }\r\n catch { return false; }\r\n });\r\n\r\n useEffect(() => {\r\n let cancelled = false;\r\n (async () => {\r\n try {\r\n const cfg = await SL?.appConfiguration?.getConfig?.({ collectionId, appId, admin: true });\r\n if (cancelled) return;\r\n const flag = cfg?._meta?.introDismissed?.[RT_KEY(recordType)];\r\n if (flag) setDismissed(true);\r\n } catch { /* ignore */ }\r\n })();\r\n return () => { cancelled = true; };\r\n }, [SL, collectionId, appId, recordType]);\r\n\r\n const dismiss = useCallback(async () => {\r\n setDismissed(true);\r\n try { localStorage.setItem(lsKey(appId, recordType), '1'); } catch { /* ignore */ }\r\n try {\r\n const cfg = await SL?.appConfiguration?.getConfig?.({ collectionId, appId, admin: true }).catch(() => ({}));\r\n const next = {\r\n ...(cfg ?? {}),\r\n _meta: {\r\n ...(cfg?._meta ?? {}),\r\n introDismissed: { ...(cfg?._meta?.introDismissed ?? {}), [RT_KEY(recordType)]: true },\r\n },\r\n };\r\n await SL?.appConfiguration?.setConfig?.({ collectionId, appId, admin: true, config: next });\r\n } catch { /* best-effort */ }\r\n }, [SL, collectionId, appId, recordType]);\r\n\r\n const undismiss = useCallback(() => {\r\n setDismissed(false);\r\n try { localStorage.removeItem(lsKey(appId, recordType)); } catch { /* ignore */ }\r\n }, [appId, recordType]);\r\n\r\n return { dismissed, dismiss, undismiss };\r\n};","import { useQuery } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\n\r\nexport interface UseScopeProbeArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n /** Force admin endpoint when fetching the collection (default true). */\r\n admin?: boolean;\r\n enabled?: boolean;\r\n}\r\n\r\n/**\r\n * Reports whether a collection has variants/batches enabled.\r\n *\r\n * Uses the canonical `Collection.variants` / `Collection.batches` boolean flags\r\n * from `SL.collection.get(collectionId)` (SDK ≥ 1.9). No more guessing by\r\n * probing list endpoints.\r\n */\r\nexport const useScopeProbe = ({ SL, collectionId, admin = true, enabled = true }: UseScopeProbeArgs) => {\r\n const query = useQuery({\r\n queryKey: ['records-admin', 'scope-probe', collectionId, admin],\r\n enabled: enabled && !!collectionId && !!SL?.collection?.get,\r\n staleTime: 5 * 60_000,\r\n queryFn: async () => {\r\n const c = await SL.collection.get(collectionId, admin);\r\n return {\r\n hasVariants: !!c?.variants,\r\n hasBatches: !!c?.batches,\r\n };\r\n },\r\n });\r\n\r\n return {\r\n hasVariants: query.data?.hasVariants ?? false,\r\n hasBatches: query.data?.hasBatches ?? false,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n };\r\n};","import { useEffect, useMemo, useRef } from 'react';\r\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\r\nimport type { RecordStatus, RecordSummary, SmartLinksSDK } from '../types';\r\nimport { buildRef, parseRef } from '../data/refs';\r\n\r\nconst LOG = '[RecordsAdmin/useFacetBrowse]';\r\n\r\ninterface FacetValueShape {\r\n key?: string;\r\n name?: string;\r\n}\r\n\r\ninterface FacetShape {\r\n key?: string;\r\n name?: string;\r\n values?: FacetValueShape[];\r\n}\r\n\r\nexport interface UseFacetBrowseArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n existing: RecordSummary[];\r\n search?: string;\r\n filter?: 'all' | RecordStatus;\r\n enabled?: boolean;\r\n}\r\n\r\nconst QK = ['records-admin', 'facet-browse'] as const;\r\n\r\nconst toScaffoldSummary = (facet: FacetShape, value: FacetValueShape): RecordSummary => {\r\n const facetKey = facet.key ?? '';\r\n const valueKey = value.key ?? '';\r\n const ref = buildRef({ facetId: facetKey, facetValue: valueKey });\r\n return {\r\n id: null,\r\n ref,\r\n scope: parseRef(ref),\r\n data: null,\r\n status: 'empty',\r\n label: value.name ?? valueKey ?? 'Untitled value',\r\n subtitle: facet.name ?? facetKey ?? undefined,\r\n };\r\n};\r\n\r\nexport const useFacetBrowse = ({\r\n SL,\r\n collectionId,\r\n existing,\r\n search = '',\r\n filter = 'all',\r\n enabled = true,\r\n}: UseFacetBrowseArgs) => {\r\n const queryClient = useQueryClient();\r\n\r\n // Pre-compute these for both the query gate and the logging effect below.\r\n // We must NOT call any other hooks between `useQueryClient` and `useQuery`\r\n // — doing so reorders hooks across renders and trips React's reducer.\r\n const hasAdminList = !!SL?.facets?.list;\r\n const hasPublicList = !!SL?.facets?.publicList;\r\n const hasAnyList = hasAdminList || hasPublicList;\r\n const queryEnabled = enabled && !!collectionId && hasAnyList;\r\n\r\n const query = useQuery({\r\n queryKey: [...QK, collectionId],\r\n enabled: queryEnabled,\r\n staleTime: 30_000,\r\n queryFn: async (): Promise<FacetShape[]> => {\r\n const t0 = performance.now();\r\n try {\r\n if (SL?.facets?.list) {\r\n console.info(`${LOG} → SL.facets.list(\"${collectionId}\", { includeValues: true })`);\r\n const res = await SL.facets.list(collectionId, { includeValues: true });\r\n const items: FacetShape[] = res?.items ?? [];\r\n console.info(\r\n `${LOG} ← SL.facets.list ok in ${Math.round(performance.now() - t0)}ms — ${items.length} facet(s)`,\r\n items,\r\n );\r\n return items;\r\n }\r\n if (SL?.facets?.publicList) {\r\n console.info(`${LOG} → SL.facets.publicList(\"${collectionId}\", { includeValues: true })`);\r\n const res = await SL.facets.publicList(collectionId, { includeValues: true });\r\n const items: FacetShape[] = res?.items ?? [];\r\n console.info(\r\n `${LOG} ← SL.facets.publicList ok in ${Math.round(performance.now() - t0)}ms — ${items.length} facet(s)`,\r\n items,\r\n );\r\n return items;\r\n }\r\n console.warn(`${LOG} queryFn ran but no facets API is available on SL`);\r\n return [];\r\n } catch (err) {\r\n console.error(`${LOG} ✖ facets fetch failed`, err);\r\n throw err;\r\n }\r\n },\r\n });\r\n\r\n // Diagnostic logging — placed AFTER `useQuery` so we never insert a hook\r\n // between the query client and the query itself.\r\n const lastLoggedRef = useRef<string>('');\r\n useEffect(() => {\r\n const signature = `${enabled}|${collectionId}|${hasAdminList}|${hasPublicList}`;\r\n if (signature === lastLoggedRef.current) return;\r\n lastLoggedRef.current = signature;\r\n if (!enabled) {\r\n console.info(`${LOG} skipped — enabled=false (shell not on facet tab yet)`);\r\n return;\r\n }\r\n if (!collectionId) {\r\n console.warn(`${LOG} skipped — no collectionId provided`);\r\n return;\r\n }\r\n if (!hasAnyList) {\r\n console.warn(\r\n `${LOG} skipped — SDK is missing both SL.facets.list and SL.facets.publicList. ` +\r\n `Update @proveanything/smartlinks (>=1.8) or check the SDK build.`,\r\n { facetsNamespace: SL?.facets ? Object.keys(SL.facets) : null },\r\n );\r\n return;\r\n }\r\n console.info(\r\n `${LOG} will fetch facets for collection \"${collectionId}\" via ` +\r\n `${hasAdminList ? 'SL.facets.list (admin)' : 'SL.facets.publicList (fallback)'}`,\r\n );\r\n }, [enabled, collectionId, hasAdminList, hasPublicList, hasAnyList, SL]);\r\n\r\n const mergedItems = useMemo(() => {\r\n const existingByRef = new Map(existing.map((item) => [item.ref, item]));\r\n const scaffolded = (query.data ?? []).flatMap((facet) =>\r\n (facet.values ?? [])\r\n .filter((value) => !!facet.key && !!value.key)\r\n .map((value) => {\r\n const scaffold = toScaffoldSummary(facet, value);\r\n return existingByRef.get(scaffold.ref) ?? scaffold;\r\n }),\r\n );\r\n\r\n const extras = existing.filter((item) => !scaffolded.some((scaffold) => scaffold.ref === item.ref));\r\n return [...scaffolded, ...extras];\r\n }, [existing, query.data]);\r\n\r\n const filteredItems = useMemo(() => {\r\n let next = mergedItems;\r\n if (filter !== 'all') next = next.filter((item) => item.status === filter);\r\n if (search.trim()) {\r\n const q = search.trim().toLowerCase();\r\n next = next.filter((item) => `${item.label} ${item.subtitle ?? ''} ${item.ref}`.toLowerCase().includes(q));\r\n }\r\n return next;\r\n }, [mergedItems, filter, search]);\r\n\r\n const counts = useMemo(() => ({\r\n all: mergedItems.length,\r\n configured: mergedItems.filter((item) => item.status === 'configured').length,\r\n partial: mergedItems.filter((item) => item.status === 'partial').length,\r\n empty: mergedItems.filter((item) => item.status === 'empty').length,\r\n }), [mergedItems]);\r\n\r\n const refetch = () => {\r\n queryClient.invalidateQueries({ queryKey: [...QK, collectionId] });\r\n };\r\n\r\n return {\r\n items: filteredItems,\r\n total: mergedItems.length,\r\n counts,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch,\r\n };\r\n};","// =============================================================================\r\n// useProductBrowse — Cursor-paginated product browser via SL.products.query.\r\n// Designed to scale to collections with millions of products: each page is a\r\n// thin Product list (id + name + sku + sortOrder), no record data is loaded\r\n// up-front. The shell pairs this with `useProductChildren` for drill-down.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport { useInfiniteQuery, useQueryClient, type InfiniteData } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\n\r\nexport interface ProductBrowseItem {\r\n /** Product id (used in refs as `product:<id>`). */\r\n id: string;\r\n /** Display name. */\r\n name: string;\r\n /** Optional subtitle. */\r\n sku?: string | null;\r\n /** Optional ordering hint. */\r\n sortOrder?: number | null;\r\n}\r\n\r\nexport interface UseProductBrowseArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n search?: string;\r\n /** Soft cap per page (default 50). */\r\n pageSize?: number;\r\n enabled?: boolean;\r\n /** Override admin flag if needed (default true). */\r\n admin?: boolean;\r\n}\r\n\r\nconst QK = ['records-admin', 'product-browse'] as const;\r\ntype PageParam = { offset: number; cursor: string | null };\r\n\r\ninterface ProductBrowsePage {\r\n items: ProductBrowseItem[];\r\n nextOffset: number;\r\n nextCursor: string | null;\r\n hasMore: boolean;\r\n total?: number;\r\n}\r\n\r\n/** Truncate Product objects to the few fields we actually display. */\r\nconst toBrowseItem = (p: any): ProductBrowseItem => ({\r\n id: p.id ?? p.productId ?? '',\r\n name: p.name ?? p.id ?? 'Untitled',\r\n sku: p.sku ?? null,\r\n sortOrder: p.sortOrder ?? null,\r\n});\r\n\r\n/**\r\n * Cursor-paginated product list backed by `SL.products.query`. When the SDK\r\n * returns a `nextCursor`, we use it; otherwise we fall back to offset-based\r\n * paging so the hook works against older SDKs or in-memory adapters too.\r\n */\r\nexport const useProductBrowse = (args: UseProductBrowseArgs) => {\r\n const { SL, collectionId, search = '', pageSize = 50, enabled = true, admin = true } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const queryKey = useMemo(\r\n () => [...QK, collectionId, search.trim(), pageSize, admin] as const,\r\n [collectionId, search, pageSize, admin],\r\n );\r\n\r\n const query = useInfiniteQuery<ProductBrowsePage, Error, InfiniteData<ProductBrowsePage>, typeof queryKey, PageParam>({\r\n queryKey,\r\n enabled: enabled && !!collectionId && !!(SL?.products?.query || SL?.product?.query || SL?.products?.list || SL?.product?.list),\r\n initialPageParam: { offset: 0, cursor: null as string | null },\r\n queryFn: async ({ pageParam }) => {\r\n const body: Record<string, unknown> = {\r\n page: { limit: pageSize, ...(pageParam.cursor ? { cursor: pageParam.cursor } : { offset: pageParam.offset }) },\r\n sort: [{ field: 'sortOrder', direction: 'asc' }, { field: 'name', direction: 'asc' }],\r\n };\r\n if (search.trim()) body.query = { search: search.trim() };\r\n\r\n let res: { items?: unknown[]; page?: { nextCursor?: string | null; hasMore?: boolean; total?: number } } | null = null;\r\n if (SL?.products?.query) {\r\n res = await SL.products.query(collectionId, body);\r\n } else if (SL?.product?.query) {\r\n res = await SL.product.query(collectionId, body, admin);\r\n } else {\r\n const legacy: any[] = SL?.products?.list\r\n ? await SL.products.list(collectionId, admin)\r\n : SL?.product?.list\r\n ? await SL.product.list(collectionId, admin)\r\n : [];\r\n const filteredLegacy = search.trim()\r\n ? legacy.filter((item: any) => `${item?.name ?? ''} ${item?.sku ?? ''} ${item?.id ?? ''}`.toLowerCase().includes(search.trim().toLowerCase()))\r\n : legacy;\r\n const pageItems = filteredLegacy.slice(pageParam.offset, pageParam.offset + pageSize);\r\n return {\r\n items: pageItems.map(toBrowseItem),\r\n nextOffset: pageParam.offset + pageItems.length,\r\n nextCursor: null,\r\n hasMore: pageParam.offset + pageItems.length < filteredLegacy.length,\r\n total: filteredLegacy.length,\r\n };\r\n }\r\n\r\n const items = (res?.items ?? []).map(toBrowseItem);\r\n const page = res?.page ?? {};\r\n return {\r\n items,\r\n nextOffset: pageParam.offset + items.length,\r\n nextCursor: page.nextCursor ?? null,\r\n hasMore: page.hasMore ?? items.length >= pageSize,\r\n total: page.total,\r\n };\r\n },\r\n getNextPageParam: (last) => {\r\n if (!last.hasMore) return undefined;\r\n if (last.nextCursor) return { offset: last.nextOffset, cursor: last.nextCursor };\r\n return { offset: last.nextOffset, cursor: null };\r\n },\r\n staleTime: 30_000,\r\n });\r\n\r\n const items = useMemo(\r\n () => query.data?.pages.flatMap((p: ProductBrowsePage) => p.items) ?? [],\r\n [query.data],\r\n );\r\n\r\n const refetch = () => queryClient.invalidateQueries({ queryKey: [...QK, collectionId] });\r\n\r\n return {\r\n items,\r\n total: query.data?.pages[query.data.pages.length - 1]?.total,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n hasNextPage: !!query.hasNextPage,\r\n isFetchingNextPage: query.isFetchingNextPage,\r\n fetchNextPage: query.fetchNextPage,\r\n refetch,\r\n };\r\n};","// =============================================================================\r\n// useProductChildren — Lazy-fetch variants & batches for ONE product.\r\n// Only fires when the relevant sub-tab is opened, never collection-wide.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\n\r\nexport interface ProductChildItem {\r\n /** Variant or batch id (the `<id>` part of `variant:<id>` / `batch:<id>`). */\r\n id: string;\r\n /** Display name. */\r\n name: string;\r\n /** Optional subtitle (sku, expiry, etc.). */\r\n subtitle?: string;\r\n}\r\n\r\nexport interface UseProductChildrenArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n productId: string | undefined;\r\n /** Which child kind to fetch. Hooks only fire when both productId and kind are set. */\r\n kind: 'variant' | 'batch' | null;\r\n enabled?: boolean;\r\n}\r\n\r\nconst QK = ['records-admin', 'product-children'] as const;\r\n\r\nconst variantToItem = (v: any): ProductChildItem => ({\r\n id: v.id ?? v.variantId ?? '',\r\n name: v.name ?? v.label ?? v.id ?? 'Untitled variant',\r\n subtitle: v.sku ?? v.size ?? undefined,\r\n});\r\n\r\nconst batchToItem = (b: any): ProductChildItem => ({\r\n id: b.id ?? b.batchId ?? '',\r\n name: b.name ?? b.id ?? 'Untitled batch',\r\n subtitle: b.expiryDate?.iso ?? b.expiry ?? b.lotCode ?? undefined,\r\n});\r\n\r\n/**\r\n * Lazy children loader. When `kind` is `null` or `productId` is missing the\r\n * underlying query is disabled, so opening the shell at collection level never\r\n * touches `variant.list` / `batch.list`.\r\n */\r\nexport const useProductChildren = (args: UseProductChildrenArgs) => {\r\n const { SL, collectionId, productId, kind, enabled = true } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const queryKey = useMemo(\r\n () => [...QK, collectionId, productId ?? null, kind] as const,\r\n [collectionId, productId, kind],\r\n );\r\n\r\n const query = useQuery({\r\n queryKey,\r\n enabled: enabled && !!collectionId && !!productId && !!kind,\r\n staleTime: 30_000,\r\n queryFn: async (): Promise<ProductChildItem[]> => {\r\n if (!productId || !kind) return [];\r\n if (kind === 'variant') {\r\n const res = await SL.variant.list(collectionId, productId);\r\n return (res ?? []).map(variantToItem);\r\n }\r\n const res = await SL.batch.list(collectionId, productId);\r\n return (res ?? []).map(batchToItem);\r\n },\r\n });\r\n\r\n const refetch = () => queryClient.invalidateQueries({\r\n queryKey: [...QK, collectionId, productId ?? null],\r\n });\r\n\r\n return {\r\n items: query.data ?? [],\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch,\r\n };\r\n};","// =============================================================================\r\n// useUnsavedGuard — Cross-context guard against losing unsaved edits.\r\n//\r\n// 1. Browser: `beforeunload` listener prompts on tab/window close.\r\n// 2. Iframe: posts `smartlinks:unsaved-changes` to `window.parent` so the\r\n// host platform can intercept its own navigation.\r\n// 3. App-level: exposes `confirmDiscard()` so app code (e.g. router\r\n// transitions, custom close buttons) can prompt manually.\r\n//\r\n// The hook is idempotent — multiple editors on a page can each call it; the\r\n// guard fires while ANY of them are dirty.\r\n// =============================================================================\r\nimport { useCallback, useEffect } from 'react';\r\n\r\nconst MESSAGE_TYPE = 'smartlinks:unsaved-changes' as const;\r\n\r\nexport interface UseUnsavedGuardArgs {\r\n /** Whether there are unsaved edits right now. */\r\n isDirty: boolean;\r\n /**\r\n * Optional human-friendly label (e.g. recordType). Posted to the parent\r\n * frame so the host can describe what's unsaved.\r\n */\r\n label?: string;\r\n /**\r\n * Optional async confirm impl. Defaults to `window.confirm`. Apps can pass\r\n * a custom dialog (e.g. a shadcn AlertDialog promise wrapper).\r\n */\r\n confirm?: (message: string) => boolean | Promise<boolean>;\r\n /**\r\n * Disable the browser-level `beforeunload` listener (e.g. when running\r\n * inside a host that handles it already). Default false.\r\n */\r\n disableBeforeUnload?: boolean;\r\n /**\r\n * Disable the parent-frame `postMessage` notification. Default false.\r\n */\r\n disableParentMessage?: boolean;\r\n}\r\n\r\n/**\r\n * Tracks unsaved state and wires up the browser/iframe guards. Returns a\r\n * `confirmDiscard` helper apps can `await` from their own navigation code.\r\n */\r\nexport function useUnsavedGuard({\r\n isDirty,\r\n label,\r\n confirm,\r\n disableBeforeUnload = false,\r\n disableParentMessage = false,\r\n}: UseUnsavedGuardArgs) {\r\n // ---------------------------------------------------------------------------\r\n // 1. Browser tab/window close\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (disableBeforeUnload || !isDirty || typeof window === 'undefined') return;\r\n const handler = (e: BeforeUnloadEvent) => {\r\n // Modern browsers ignore the custom string but require preventDefault\r\n // + setting returnValue to trigger the native prompt.\r\n e.preventDefault();\r\n e.returnValue = '';\r\n return '';\r\n };\r\n window.addEventListener('beforeunload', handler);\r\n return () => window.removeEventListener('beforeunload', handler);\r\n }, [isDirty, disableBeforeUnload]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // 2. Iframe: notify parent so the host platform can guard its navigation\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (disableParentMessage || typeof window === 'undefined') return;\r\n if (window.parent === window) return; // not in iframe\r\n try {\r\n window.parent.postMessage({\r\n type: MESSAGE_TYPE,\r\n isDirty,\r\n label: label ?? null,\r\n }, '*');\r\n } catch {\r\n // Parent in cross-origin context or sandboxed — fail silently.\r\n }\r\n }, [isDirty, label, disableParentMessage]);\r\n\r\n // Always emit a final \"clean\" message on unmount so the parent can drop\r\n // any retained dirty state. (Only when we previously sent dirty messages.)\r\n useEffect(() => {\r\n if (disableParentMessage || typeof window === 'undefined') return;\r\n if (window.parent === window) return;\r\n return () => {\r\n try {\r\n window.parent.postMessage({ type: MESSAGE_TYPE, isDirty: false, label: label ?? null }, '*');\r\n } catch { /* noop */ }\r\n };\r\n }, [disableParentMessage, label]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // 3. App-level helper\r\n // ---------------------------------------------------------------------------\r\n const confirmDiscard = useCallback(\r\n async (message?: string): Promise<boolean> => {\r\n if (!isDirty) return true;\r\n const msg = message ?? 'You have unsaved changes. Discard them?';\r\n if (confirm) {\r\n try { return !!(await confirm(msg)); }\r\n catch { return false; }\r\n }\r\n if (typeof window === 'undefined') return true;\r\n return window.confirm(msg);\r\n },\r\n [isDirty, confirm],\r\n );\r\n\r\n return { confirmDiscard };\r\n}","// =============================================================================\r\n// useDirtyNavigation — Wraps navigation intents (selecting a different\r\n// record/scope/tab) in a dirty-aware policy.\r\n//\r\n// Strategies:\r\n// - `prompt`: ask before discarding unsaved changes\r\n// - `autosave`: save quietly, then navigate\r\n// - `keep`: navigate freely; the editor preserves dirty values per-ref\r\n// =============================================================================\r\nimport { useCallback } from 'react';\r\n\r\nexport type DirtyStrategy = 'prompt' | 'autosave' | 'keep';\r\n\r\nexport interface UseDirtyNavigationArgs {\r\n strategy: DirtyStrategy;\r\n isDirty: boolean;\r\n /** Persist current edits. Resolves when the SDK call completes. */\r\n save: () => void | Promise<void>;\r\n /** Discard local edits to the saved snapshot. */\r\n reset: () => void;\r\n /**\r\n * Confirm impl: returns `'save' | 'discard' | 'cancel'`. Defaults to a\r\n * `window.confirm` fallback (Save = OK, Discard = Cancel, no Cancel option).\r\n */\r\n confirm?: (i18n?: NavConfirmI18n) => Promise<'save' | 'discard' | 'cancel'>;\r\n i18n?: NavConfirmI18n;\r\n}\r\n\r\nexport interface NavConfirmI18n {\r\n title?: string;\r\n body?: string;\r\n save?: string;\r\n discard?: string;\r\n cancel?: string;\r\n}\r\n\r\nconst fallbackConfirm = async (i18n?: NavConfirmI18n): Promise<'save' | 'discard' | 'cancel'> => {\r\n if (typeof window === 'undefined') return 'discard';\r\n const msg = `${i18n?.title ?? 'Unsaved changes'}\\n\\n${i18n?.body ?? 'OK to save & continue, Cancel to discard.'}`;\r\n return window.confirm(msg) ? 'save' : 'discard';\r\n};\r\n\r\n/**\r\n * Returns `runWithGuard(action)` — call it instead of executing the\r\n * navigation directly. The guard handles dirty-state policy and only calls\r\n * `action()` when it's safe to proceed.\r\n */\r\nexport const useDirtyNavigation = ({\r\n strategy, isDirty, save, reset, confirm, i18n,\r\n}: UseDirtyNavigationArgs) => {\r\n const runWithGuard = useCallback(\r\n async (action: () => void): Promise<boolean> => {\r\n if (!isDirty || strategy === 'keep') {\r\n action();\r\n return true;\r\n }\r\n if (strategy === 'autosave') {\r\n try { await save(); }\r\n catch { /* If save fails, fall through to prompt so user can decide. */\r\n const fallback = await (confirm ?? fallbackConfirm)(i18n);\r\n if (fallback === 'cancel') return false;\r\n if (fallback === 'discard') reset();\r\n }\r\n action();\r\n return true;\r\n }\r\n // prompt\r\n const choice = await (confirm ?? fallbackConfirm)(i18n);\r\n if (choice === 'cancel') return false;\r\n if (choice === 'save') {\r\n try { await save(); }\r\n catch { return false; }\r\n } else {\r\n reset();\r\n }\r\n action();\r\n return true;\r\n },\r\n [strategy, isDirty, save, reset, confirm, i18n],\r\n );\r\n\r\n return { runWithGuard };\r\n};","// =============================================================================\r\n// ConfirmDialog — themed three-button modal for unsaved-changes prompts.\r\n// Replaces native window.confirm() so the popup matches the shell chrome,\r\n// avoids the host iframe's \"An embedded page at … says\" framing, and offers\r\n// the proper Save / Discard / Cancel triad instead of just OK / Cancel.\r\n// =============================================================================\r\nimport { useEffect, useRef } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { AlertTriangle } from 'lucide-react';\r\n\r\nexport interface ConfirmDialogProps {\r\n open: boolean;\r\n title: string;\r\n body: string;\r\n saveLabel: string;\r\n discardLabel: string;\r\n cancelLabel: string;\r\n onChoice: (choice: 'save' | 'discard' | 'cancel') => void;\r\n}\r\n\r\nexport const ConfirmDialog = ({\r\n open, title, body, saveLabel, discardLabel, cancelLabel, onChoice,\r\n}: ConfirmDialogProps) => {\r\n const saveBtnRef = useRef<HTMLButtonElement | null>(null);\r\n\r\n // Focus the primary action when the dialog opens, and lock background\r\n // scroll while it's visible.\r\n useEffect(() => {\r\n if (!open) return;\r\n const prev = document.body.style.overflow;\r\n document.body.style.overflow = 'hidden';\r\n const t = window.setTimeout(() => saveBtnRef.current?.focus(), 0);\r\n const onKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') { e.stopPropagation(); onChoice('cancel'); }\r\n };\r\n window.addEventListener('keydown', onKey, true);\r\n return () => {\r\n window.clearTimeout(t);\r\n window.removeEventListener('keydown', onKey, true);\r\n document.body.style.overflow = prev;\r\n };\r\n }, [open, onChoice]);\r\n\r\n if (!open || typeof document === 'undefined') return null;\r\n\r\n // Portal to <body> so the host's stacking context (sticky headers, sidebars,\r\n // any z-index tricks) can never clip the modal.\r\n return createPortal(\r\n <div\r\n className=\"ra-shell ra-confirm-root\"\r\n role=\"presentation\"\r\n onMouseDown={(e) => e.stopPropagation()}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n <div className=\"ra-confirm-backdrop\" onClick={() => onChoice('cancel')} />\r\n <div\r\n role=\"alertdialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby=\"ra-confirm-title\"\r\n aria-describedby=\"ra-confirm-body\"\r\n className=\"ra-confirm-card\"\r\n >\r\n <div className=\"ra-confirm-header\">\r\n <span className=\"ra-confirm-icon\" aria-hidden=\"true\">\r\n <AlertTriangle className=\"w-4 h-4\" />\r\n </span>\r\n <h2 id=\"ra-confirm-title\" className=\"ra-confirm-title\">{title}</h2>\r\n </div>\r\n <p id=\"ra-confirm-body\" className=\"ra-confirm-body\">{body}</p>\r\n <div className=\"ra-confirm-actions\">\r\n <button\r\n type=\"button\"\r\n className=\"ra-confirm-btn ra-confirm-btn-ghost\"\r\n onClick={() => onChoice('cancel')}\r\n >\r\n {cancelLabel}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-confirm-btn ra-confirm-btn-danger\"\r\n onClick={() => onChoice('discard')}\r\n >\r\n {discardLabel}\r\n </button>\r\n <button\r\n type=\"button\"\r\n ref={saveBtnRef}\r\n className=\"ra-confirm-btn ra-confirm-btn-primary\"\r\n onClick={() => onChoice('save')}\r\n >\r\n {saveLabel}\r\n </button>\r\n </div>\r\n </div>\r\n </div>,\r\n document.body,\r\n );\r\n};","// =============================================================================\r\n// useConfirmDialog — promise-based replacement for window.confirm() that\r\n// renders a themed three-button dialog (Save / Discard / Cancel). Designed\r\n// to plug into useDirtyNavigation's optional `confirm` slot so the unsaved-\r\n// changes prompt matches the shell chrome instead of the native iframe one.\r\n// =============================================================================\r\nimport { useCallback, useRef, useState, type ReactNode } from 'react';\r\nimport { ConfirmDialog } from '../shell/ConfirmDialog';\r\nimport type { NavConfirmI18n } from './useDirtyNavigation';\r\n\r\ninterface PendingState {\r\n title: string;\r\n body: string;\r\n saveLabel: string;\r\n discardLabel: string;\r\n cancelLabel: string;\r\n}\r\n\r\nconst DEFAULTS: PendingState = {\r\n title: 'Unsaved changes',\r\n body: 'You have unsaved changes. Save them, discard them, or stay on this record?',\r\n saveLabel: 'Save & continue',\r\n discardLabel: 'Discard',\r\n cancelLabel: 'Stay here',\r\n};\r\n\r\nexport interface UseConfirmDialogReturn {\r\n /** Resolves with the user's choice. Suitable as `confirm` for `useDirtyNavigation`. */\r\n confirm: (i18n?: NavConfirmI18n) => Promise<'save' | 'discard' | 'cancel'>;\r\n /** Render this once near the top of the shell so the portal mounts. */\r\n dialog: ReactNode;\r\n}\r\n\r\nexport const useConfirmDialog = (): UseConfirmDialogReturn => {\r\n const [open, setOpen] = useState(false);\r\n const [state, setState] = useState<PendingState>(DEFAULTS);\r\n const resolverRef = useRef<((c: 'save' | 'discard' | 'cancel') => void) | null>(null);\r\n\r\n const confirm = useCallback((i18n?: NavConfirmI18n) => {\r\n setState({\r\n title: i18n?.title ?? DEFAULTS.title,\r\n body: i18n?.body ?? DEFAULTS.body,\r\n saveLabel: i18n?.save ?? DEFAULTS.saveLabel,\r\n discardLabel: i18n?.discard ?? DEFAULTS.discardLabel,\r\n cancelLabel: i18n?.cancel ?? DEFAULTS.cancelLabel,\r\n });\r\n setOpen(true);\r\n return new Promise<'save' | 'discard' | 'cancel'>((resolve) => {\r\n resolverRef.current = resolve;\r\n });\r\n }, []);\r\n\r\n const handleChoice = useCallback((choice: 'save' | 'discard' | 'cancel') => {\r\n setOpen(false);\r\n const r = resolverRef.current;\r\n resolverRef.current = null;\r\n r?.(choice);\r\n }, []);\r\n\r\n return {\r\n confirm,\r\n dialog: (\r\n <ConfirmDialog\r\n open={open}\r\n title={state.title}\r\n body={state.body}\r\n saveLabel={state.saveLabel}\r\n discardLabel={state.discardLabel}\r\n cancelLabel={state.cancelLabel}\r\n onChoice={handleChoice}\r\n />\r\n ),\r\n };\r\n};","// =============================================================================\r\n// ScopeTabs — pill-style segmented control for the top-level scopes.\r\n// v0.4: scope icon + label + count badge, active accent, hover lift.\r\n// =============================================================================\r\nimport type { ScopeKind } from '../types';\r\nimport { DEFAULT_ICONS, type RecordsAdminIcons } from '../shell/icons';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nconst LABELS: Record<ScopeKind, string> = {\r\n product: 'Products',\r\n facet: 'Shared',\r\n variant: 'Variants',\r\n batch: 'Batches',\r\n};\r\n\r\ninterface Props {\r\n scopes: ScopeKind[];\r\n active: ScopeKind;\r\n onChange: (s: ScopeKind) => void;\r\n /** When true, tabs render disabled (used while collection flags are loading). */\r\n loading?: boolean;\r\n /** Optional per-scope counts displayed as tiny badges. */\r\n counts?: Partial<Record<ScopeKind, number>>;\r\n /** Override icons used per scope. Falls back to DEFAULT_ICONS.scope. */\r\n icons?: RecordsAdminIcons['scope'];\r\n}\r\n\r\nexport const ScopeTabs = ({\r\n scopes, active, onChange, loading = false, counts, icons,\r\n}: Props) => {\r\n const iconMap = icons ?? DEFAULT_ICONS.scope;\r\n return (\r\n <div role=\"tablist\" className=\"ra-tabs\" aria-label=\"Record scope\">\r\n {scopes.map((s) => {\r\n const Icon = iconMap[s] ?? DEFAULT_ICONS.scope[s];\r\n const isActive = active === s;\r\n const count = counts?.[s];\r\n return (\r\n <button\r\n key={s}\r\n type=\"button\"\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n onClick={() => onChange(s)}\r\n disabled={loading}\r\n className=\"ra-tab\"\r\n >\r\n <Icon className={cn('ra-tab-icon w-3.5 h-3.5', loading && 'animate-pulse')} />\r\n <span>{LABELS[s]}</span>\r\n {typeof count === 'number' && count > 0 && (\r\n <span className=\"ra-tab-count\">{count}</span>\r\n )}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n","import { cn } from '../../../utils/cn';\r\nimport type { RecordStatus, RecordsAdminI18n } from '../types';\r\n\r\ninterface Props {\r\n value: 'all' | RecordStatus;\r\n onChange: (v: 'all' | RecordStatus) => void;\r\n counts: { all: number; configured: number; partial: number; empty: number };\r\n i18n: RecordsAdminI18n;\r\n /** Status keys to omit when their count is 0 — e.g. `['partial']` keeps the\r\n * pill row on a single line while no records are partially configured. The\r\n * active filter is always rendered so users never lose context. */\r\n hideZero?: Array<'all' | RecordStatus>;\r\n}\r\n\r\nexport const StatusFilterPills = ({ value, onChange, counts, i18n, hideZero }: Props) => {\r\n const opts: Array<{ key: 'all' | RecordStatus; label: string; count: number }> = [\r\n { key: 'all', label: i18n.filterAll, count: counts.all },\r\n { key: 'configured', label: i18n.filterConfigured, count: counts.configured },\r\n { key: 'partial', label: i18n.filterPartial, count: counts.partial },\r\n { key: 'empty', label: i18n.filterEmpty, count: counts.empty },\r\n ];\r\n const visible = opts.filter((o) =>\r\n o.key === value || !hideZero?.includes(o.key) || o.count > 0,\r\n );\r\n return (\r\n <div className=\"flex flex-wrap gap-1.5\">\r\n {visible.map((o) => {\r\n const active = value === o.key;\r\n return (\r\n <button\r\n key={o.key}\r\n type=\"button\"\r\n onClick={() => onChange(o.key)}\r\n className={cn(\r\n 'text-xs px-2.5 py-1 rounded-full border transition-colors',\r\n active ? 'font-medium' : 'opacity-80 hover:opacity-100',\r\n )}\r\n style={{\r\n background: active ? 'hsl(var(--ra-accent) / 0.12)' : 'hsl(var(--ra-muted))',\r\n borderColor: active ? 'hsl(var(--ra-accent) / 0.5)' : 'hsl(var(--ra-border))',\r\n color: 'hsl(var(--ra-text))',\r\n }}\r\n >\r\n {o.label}\r\n <span className=\"ml-1.5 opacity-60\">{o.count}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};","import type { RecordSource, RecordStatus } from '../types';\r\nimport { cn } from '../../../utils/cn';\r\n\r\ninterface Props {\r\n source?: RecordSource;\r\n status?: RecordStatus;\r\n className?: string;\r\n}\r\n\r\n/** Emerald = own data, amber = inherited, muted = empty */\r\nexport const StatusDot = ({ source, status, className }: Props) => {\r\n let cls = 'ra-status-missing';\r\n if (source === 'self' || status === 'configured') cls = 'ra-status-own';\r\n else if (source === 'inherited' || status === 'partial') cls = 'ra-status-shared';\r\n return <span className={cn('ra-status-dot', cls, className)} aria-hidden=\"true\" />;\r\n};","// =============================================================================\r\n// DefaultRecordRow — used by `list` & `compact` presentations.\r\n// v0.4: scope-aware icon, status dot, optional inheritance chip, hover slot.\r\n// =============================================================================\r\nimport type { RecordSummary } from '../types';\r\nimport type { RecordSlotContext } from '../types/shell';\r\nimport { StatusDot } from './StatusDot';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nexport interface DefaultRecordRowProps {\r\n record: RecordSummary;\r\n ctx: RecordSlotContext;\r\n /** Drop the icon + subtitle (used by the `compact` preset). */\r\n compact?: boolean;\r\n}\r\n\r\nexport const DefaultRecordRow = ({ record, ctx, compact = false }: DefaultRecordRowProps) => {\r\n const { selected, onSelect, isDirty } = ctx;\r\n // The scope kind drives the leading icon.\r\n const ScopeIcon = (record.scope.kind && record.scope.kind !== 'collection')\r\n ? DEFAULT_ICONS.scope[record.scope.kind]\r\n : DEFAULT_ICONS.scope.product;\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={onSelect}\r\n data-selected={selected ? 'true' : 'false'}\r\n className={cn('ra-row', compact && 'ra-row-compact')}\r\n style={compact ? { paddingTop: '0.4rem', paddingBottom: '0.4rem' } : undefined}\r\n >\r\n {!compact && (\r\n <span className=\"ra-row-icon\" aria-hidden=\"true\">\r\n <ScopeIcon className=\"w-3.5 h-3.5\" />\r\n </span>\r\n )}\r\n <div className=\"ra-row-body\">\r\n <div className=\"ra-row-title\">{record.label}</div>\r\n {!compact && record.subtitle && (\r\n <div className=\"ra-row-sub\">{record.subtitle}</div>\r\n )}\r\n </div>\r\n {/* status dot — keeps the existing semantic so apps can still target it */}\r\n <StatusDot status={record.status} />\r\n {record.badges?.slice(0, 1).map((b, i) => (\r\n <span key={`${b.label}-${i}`} className=\"ra-chip\" data-tone=\"muted\">\r\n {b.label}\r\n </span>\r\n ))}\r\n {isDirty && (\r\n <span\r\n title=\"Unsaved changes\"\r\n aria-label=\"Unsaved changes\"\r\n className=\"ra-status-dot ra-status-shared shrink-0\"\r\n />\r\n )}\r\n </button>\r\n );\r\n};\r\n","// =============================================================================\r\n// DefaultRecordCard — used by `grid` & `gallery` presentations.\r\n// v0.4: layered surface, hover lift, status + dirty indicators.\r\n// =============================================================================\r\nimport type { RecordSummary } from '../types';\r\nimport type { RecordSlotContext } from '../types/shell';\r\nimport { StatusDot } from './StatusDot';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nexport interface DefaultRecordCardProps {\r\n record: RecordSummary;\r\n ctx: RecordSlotContext;\r\n /** `grid` → 1:1, `gallery` → 16:9 with denser meta. Default `grid`. */\r\n variant?: 'grid' | 'gallery';\r\n}\r\n\r\nconst initials = (s: string) =>\r\n s.split(/\\s+/).filter(Boolean).slice(0, 2)\r\n .map((p) => p[0]?.toUpperCase() ?? '').join('') || '?';\r\n\r\nexport const DefaultRecordCard = ({ record, ctx, variant = 'grid' }: DefaultRecordCardProps) => {\r\n const { selected, onSelect, isDirty } = ctx;\r\n const aspect = variant === 'gallery' ? 'aspect-video' : 'aspect-square';\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={onSelect}\r\n className={cn(\r\n 'group flex flex-col text-left rounded-md overflow-hidden border ra-card-hover',\r\n selected && 'ring-2',\r\n )}\r\n style={{\r\n background: 'hsl(var(--ra-surface))',\r\n borderColor: selected ? 'var(--ra-row-active-bd)' : 'hsl(var(--ra-border))',\r\n boxShadow: selected\r\n ? `0 0 0 2px hsl(var(--ra-accent) / 0.45), var(--ra-card-shadow)`\r\n : 'var(--ra-card-shadow)',\r\n }}\r\n >\r\n <div\r\n className={cn(aspect, 'relative w-full flex items-center justify-center overflow-hidden')}\r\n style={{ background: 'hsl(var(--ra-muted))' }}\r\n >\r\n {record.thumbnail ? (\r\n <img\r\n src={record.thumbnail}\r\n alt=\"\"\r\n loading=\"lazy\"\r\n className=\"w-full h-full object-cover\"\r\n />\r\n ) : (\r\n <span\r\n className=\"text-2xl ra-display\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n {initials(record.label)}\r\n </span>\r\n )}\r\n <div className=\"absolute top-1.5 left-1.5\">\r\n <StatusDot status={record.status} />\r\n </div>\r\n {isDirty && (\r\n <span\r\n title=\"Unsaved changes\"\r\n aria-label=\"Unsaved changes\"\r\n className=\"ra-status-dot ra-status-shared absolute top-1.5 right-1.5\"\r\n />\r\n )}\r\n </div>\r\n <div className=\"p-2.5 min-w-0\">\r\n <div className=\"ra-row-title\">{record.label}</div>\r\n {variant === 'gallery' && record.subtitle && (\r\n <div className=\"ra-row-sub\">{record.subtitle}</div>\r\n )}\r\n {record.badges && record.badges.length > 0 && (\r\n <div className=\"flex gap-1 mt-1.5 flex-wrap\">\r\n {record.badges.slice(0, 3).map((b, i) => (\r\n <span key={`${b.label}-${i}`} className=\"ra-chip\" data-tone=\"muted\">\r\n {b.label}\r\n </span>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n </button>\r\n );\r\n};\r\n","// =============================================================================\r\n// RecordList — presentation-aware container for the browse rail.\r\n// v0.4: optional `groupBy` enables accordion-style grouping.\r\n// =============================================================================\r\nimport { useMemo, useState, type ReactNode } from 'react';\r\nimport type { RecordSummary, RecordPresentation } from '../types';\r\nimport type { RecordSlotContext } from '../types/shell';\r\nimport { DefaultRecordRow } from './DefaultRecordRow';\r\nimport { DefaultRecordCard } from './DefaultRecordCard';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\n\r\ninterface Props {\r\n items: RecordSummary[];\r\n selectedRef?: string;\r\n onSelect: (item: RecordSummary) => void;\r\n /** When set, the matching row gets a small \"unsaved\" indicator. */\r\n dirtyRef?: string;\r\n /** Layout. Defaults to `list` for full back-compat. */\r\n presentation?: RecordPresentation;\r\n /** Optional override for `list` / `compact` rows. */\r\n renderListRow?: (record: RecordSummary, ctx: RecordSlotContext) => ReactNode;\r\n /** Optional override for `grid` / `gallery` cards. */\r\n renderCard?: (record: RecordSummary, ctx: RecordSlotContext) => ReactNode;\r\n /** Optional grouping function. Returning null buckets the row under \"Other\". */\r\n groupBy?: (record: RecordSummary) => { key: string; label: string; icon?: ReactNode } | null;\r\n}\r\n\r\ninterface GroupBucket {\r\n key: string;\r\n label: string;\r\n icon?: ReactNode;\r\n items: RecordSummary[];\r\n}\r\n\r\nexport const RecordList = ({\r\n items, selectedRef, onSelect, dirtyRef,\r\n presentation = 'list', renderListRow, renderCard, groupBy,\r\n}: Props) => {\r\n const buildCtx = (item: RecordSummary): RecordSlotContext => ({\r\n selected: item.ref === selectedRef,\r\n onSelect: () => onSelect(item),\r\n isDirty: !!dirtyRef && item.ref === dirtyRef,\r\n });\r\n\r\n const groups: GroupBucket[] | null = useMemo(() => {\r\n if (!groupBy) return null;\r\n const buckets = new Map<string, GroupBucket>();\r\n const orderedKeys: string[] = [];\r\n for (const item of items) {\r\n const g = groupBy(item) ?? { key: '__other', label: 'Other' };\r\n if (!buckets.has(g.key)) {\r\n buckets.set(g.key, { ...g, items: [] });\r\n orderedKeys.push(g.key);\r\n }\r\n buckets.get(g.key)!.items.push(item);\r\n }\r\n return orderedKeys.map((k) => buckets.get(k)!);\r\n }, [items, groupBy]);\r\n\r\n const renderItems = (rows: RecordSummary[]) => {\r\n if (presentation === 'grid' || presentation === 'gallery') {\r\n const minColPx = presentation === 'gallery' ? 200 : 120;\r\n return (\r\n <div\r\n className=\"grid gap-2 p-2\"\r\n style={{ gridTemplateColumns: `repeat(auto-fill, minmax(${minColPx}px, 1fr))` }}\r\n >\r\n {rows.map((item) => {\r\n const ctx = buildCtx(item);\r\n return (\r\n <div key={item.ref}>\r\n {renderCard\r\n ? renderCard(item, ctx)\r\n : <DefaultRecordCard record={item} ctx={ctx} variant={presentation} />}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n }\r\n const compact = presentation === 'compact';\r\n return (\r\n <ul>\r\n {rows.map((item) => {\r\n const ctx = buildCtx(item);\r\n return (\r\n <li key={item.ref}>\r\n {renderListRow\r\n ? renderListRow(item, ctx)\r\n : <DefaultRecordRow record={item} ctx={ctx} compact={compact} />}\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n );\r\n };\r\n\r\n if (groups) {\r\n return <GroupedList groups={groups} renderItems={renderItems} />;\r\n }\r\n\r\n return renderItems(items);\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Accordion grouping\r\n// ---------------------------------------------------------------------------\r\nconst GroupedList = ({\r\n groups, renderItems,\r\n}: { groups: GroupBucket[]; renderItems: (rows: RecordSummary[]) => ReactNode }) => {\r\n const Chevron = DEFAULT_ICONS.group.chevron;\r\n const [open, setOpen] = useState<Record<string, boolean>>(() =>\r\n Object.fromEntries(groups.map((g) => [g.key, true])),\r\n );\r\n return (\r\n <>\r\n {groups.map((g) => {\r\n const isOpen = open[g.key] !== false;\r\n return (\r\n <section key={g.key} className=\"ra-group\" data-open={isOpen ? 'true' : 'false'}>\r\n <button\r\n type=\"button\"\r\n className=\"ra-group-summary\"\r\n onClick={() => setOpen((s) => ({ ...s, [g.key]: !isOpen }))}\r\n aria-expanded={isOpen}\r\n >\r\n <Chevron className=\"ra-group-chevron w-3 h-3\" />\r\n {g.icon}\r\n <span className=\"ra-group-name\">{g.label}</span>\r\n <span className=\"ra-group-count\">{g.items.length}</span>\r\n </button>\r\n <div className=\"ra-group-body\">{renderItems(g.items)}</div>\r\n </section>\r\n );\r\n })}\r\n </>\r\n );\r\n};\r\n\r\n// Backward-compat named exports — same component for all scopes.\r\nexport const ProductList = RecordList;\r\nexport const FacetList = RecordList;\r\nexport const VariantList = RecordList;\r\nexport const BatchList = RecordList;\r\n","// =============================================================================\r\n// EmptyStates — friendly empty / loading / error states for the records rail.\r\n// v0.4: large soft icon, display-weight title, two-line body, optional CTA pair.\r\n// =============================================================================\r\nimport type { ReactNode } from 'react';\r\nimport { Inbox } from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\n\r\nexport interface EmptyStateProps {\r\n title: string;\r\n body?: ReactNode;\r\n /** Primary call-to-action — typically \"+ Add your first …\". */\r\n action?: ReactNode;\r\n /** Optional secondary action — typically \"Import from CSV\". */\r\n secondaryAction?: ReactNode;\r\n /** Lucide icon component. Defaults to `Inbox`. */\r\n icon?: LucideIcon;\r\n}\r\n\r\nexport const EmptyState = ({\r\n title, body, action, secondaryAction, icon: Icon = Inbox,\r\n}: EmptyStateProps) => (\r\n <div className=\"ra-empty\">\r\n <div className=\"ra-empty-icon\">\r\n <Icon className=\"w-6 h-6\" />\r\n </div>\r\n <h3 className=\"ra-empty-title\">{title}</h3>\r\n {body && <p className=\"ra-empty-body\">{body}</p>}\r\n {(action || secondaryAction) && (\r\n <div className=\"ra-empty-actions\">\r\n {action}\r\n {secondaryAction}\r\n </div>\r\n )}\r\n </div>\r\n);\r\n\r\nexport const LoadingState = () => (\r\n <div className=\"p-3 space-y-2\">\r\n {[0, 1, 2, 3].map((i) => (\r\n <div\r\n key={i}\r\n className=\"h-11 rounded-md animate-pulse\"\r\n style={{ background: 'hsl(var(--ra-muted))' }}\r\n />\r\n ))}\r\n </div>\r\n);\r\n\r\nexport const ErrorState = ({ error }: { error: Error }) => (\r\n <div className=\"ra-empty\">\r\n <div\r\n className=\"ra-empty-icon\"\r\n style={{ background: 'hsl(var(--ra-danger) / 0.10)', color: 'hsl(var(--ra-danger))' }}\r\n >\r\n !\r\n </div>\r\n <h3 className=\"ra-empty-title\">Something went wrong</h3>\r\n <p className=\"ra-empty-body\">{error.message || 'Please try again.'}</p>\r\n </div>\r\n);\r\n","// =============================================================================\r\n// PresentationSwitcher — segmented control above the rail when more than one\r\n// presentation is enabled. Persistence is handled by the shell.\r\n// =============================================================================\r\nimport { LayoutGrid, List, Image as ImageIcon, Rows3 } from 'lucide-react';\r\nimport type { RecordPresentation } from '../types';\r\nimport type { RecordsAdminI18n } from '../types';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nconst ICONS: Record<RecordPresentation, typeof List> = {\r\n list: List,\r\n grid: LayoutGrid,\r\n gallery: ImageIcon,\r\n compact: Rows3,\r\n};\r\n\r\nconst labelFor = (p: RecordPresentation, i18n: RecordsAdminI18n): string => {\r\n switch (p) {\r\n case 'list': return i18n.presentationList;\r\n case 'grid': return i18n.presentationGrid;\r\n case 'gallery': return i18n.presentationGallery;\r\n case 'compact': return i18n.presentationCompact;\r\n }\r\n};\r\n\r\nexport interface PresentationSwitcherProps {\r\n options: RecordPresentation[];\r\n value: RecordPresentation;\r\n onChange: (next: RecordPresentation) => void;\r\n i18n: RecordsAdminI18n;\r\n}\r\n\r\nexport const PresentationSwitcher = ({ options, value, onChange, i18n }: PresentationSwitcherProps) => {\r\n if (options.length < 2) return null;\r\n return (\r\n <div\r\n className=\"inline-flex rounded-md border overflow-hidden\"\r\n style={{ borderColor: 'hsl(var(--ra-border))' }}\r\n role=\"tablist\"\r\n aria-label=\"View\"\r\n >\r\n {options.map((opt) => {\r\n const Icon = ICONS[opt];\r\n const active = opt === value;\r\n return (\r\n <button\r\n key={opt}\r\n type=\"button\"\r\n role=\"tab\"\r\n aria-selected={active}\r\n title={labelFor(opt, i18n)}\r\n aria-label={labelFor(opt, i18n)}\r\n onClick={() => onChange(opt)}\r\n className={cn(\r\n 'flex items-center justify-center w-7 h-7 transition-colors',\r\n active\r\n ? 'bg-[hsl(var(--ra-text))] text-[hsl(var(--ra-surface))]'\r\n : 'hover:bg-[hsl(var(--ra-muted))]',\r\n )}\r\n >\r\n <Icon className=\"w-3.5 h-3.5\" />\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// usePresentationPref — persists the chosen presentation per app/recordType\r\n// in localStorage. Falls back to the supplied default when nothing is stored\r\n// or the stored value isn't in the allowed set.\r\n// =============================================================================\r\nimport { useCallback, useEffect, useState } from 'react';\r\nimport type { RecordPresentation } from '../types';\r\n\r\nconst KEY_PREFIX = 'smartlinks-ui:records-admin:presentation';\r\n\r\nconst safeRead = (key: string): string | null => {\r\n try { return typeof window === 'undefined' ? null : window.localStorage.getItem(key); }\r\n catch { return null; }\r\n};\r\nconst safeWrite = (key: string, val: string): void => {\r\n try { if (typeof window !== 'undefined') window.localStorage.setItem(key, val); }\r\n catch { /* ignore quota / privacy errors */ }\r\n};\r\n\r\nexport function usePresentationPref(args: {\r\n appId: string;\r\n recordType?: string;\r\n options: RecordPresentation[];\r\n defaultValue: RecordPresentation;\r\n}): [RecordPresentation, (next: RecordPresentation) => void] {\r\n const { appId, recordType, options, defaultValue } = args;\r\n const key = `${KEY_PREFIX}:${appId}:${recordType ?? '_default'}`;\r\n\r\n const initial = (): RecordPresentation => {\r\n const stored = safeRead(key) as RecordPresentation | null;\r\n if (stored && options.includes(stored)) return stored;\r\n return options.includes(defaultValue) ? defaultValue : options[0];\r\n };\r\n\r\n const [value, setValue] = useState<RecordPresentation>(initial);\r\n\r\n // Re-sync if `options` shrinks and excludes the current value.\r\n useEffect(() => {\r\n if (!options.includes(value)) setValue(options[0]);\r\n }, [options, value]);\r\n\r\n const set = useCallback((next: RecordPresentation) => {\r\n setValue(next);\r\n safeWrite(key, next);\r\n }, [key]);\r\n\r\n return [value, set];\r\n}","import { ChevronRight } from 'lucide-react';\r\nimport type { ParsedRef } from '../types';\r\n\r\ninterface Segment { label: string; key: string }\r\n\r\nconst segmentsFor = (s: ParsedRef): Segment[] => {\r\n const out: Segment[] = [];\r\n if (s.facetId) out.push({ label: s.facetValue ? `${s.facetId}: ${s.facetValue}` : `Facet: ${s.facetId}`, key: 'facet' });\r\n if (s.productId) out.push({ label: `Product: ${s.productId}`, key: 'product' });\r\n if (s.variantId) out.push({ label: `Variant: ${s.variantId}`, key: 'variant' });\r\n if (s.batchId) out.push({ label: `Batch: ${s.batchId}`, key: 'batch' });\r\n return out;\r\n};\r\n\r\nexport const ScopeBreadcrumb = ({ scope }: { scope: ParsedRef }) => {\r\n const segs = segmentsFor(scope);\r\n if (segs.length === 0) return null;\r\n return (\r\n <nav aria-label=\"Scope\" className=\"flex items-center gap-1 text-xs flex-wrap\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n {segs.map((s, i) => (\r\n <span key={s.key} className=\"flex items-center gap-1\">\r\n {i > 0 && <ChevronRight className=\"w-3 h-3 opacity-50\" />}\r\n <span style={{ color: 'hsl(var(--ra-text))' }}>{s.label}</span>\r\n </span>\r\n ))}\r\n </nav>\r\n );\r\n};","// =============================================================================\r\n// BulkActionsMenu — Apply to many / Copy from / Clear / Import / Export.\r\n// v0.4: each action gets a Lucide icon, destructive items separated and tinted.\r\n// =============================================================================\r\nimport { useState, useRef, useEffect } from 'react';\r\nimport {\r\n ChevronDown, Copy, Eraser, Layers,\r\n Upload, Download, Trash2,\r\n} from 'lucide-react';\r\nimport type { LucideIcon } from 'lucide-react';\r\nimport type { RecordsAdminI18n } from '../types';\r\n\r\ninterface Props {\r\n i18n: RecordsAdminI18n;\r\n onApplyToMany?: () => void;\r\n onCopyFrom?: () => void;\r\n onClearMany?: () => void;\r\n onImportCsv?: () => void;\r\n onExportCsv?: () => void;\r\n}\r\n\r\ninterface ItemDef {\r\n key: string;\r\n label: string;\r\n onClick: () => void;\r\n icon: LucideIcon;\r\n tone?: 'danger';\r\n divider?: boolean;\r\n}\r\n\r\nexport const BulkActionsMenu = ({\r\n i18n, onApplyToMany, onCopyFrom, onClearMany, onImportCsv, onExportCsv,\r\n}: Props) => {\r\n const [open, setOpen] = useState(false);\r\n const ref = useRef<HTMLDivElement>(null);\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n const onDocClick = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\r\n };\r\n document.addEventListener('mousedown', onDocClick);\r\n return () => document.removeEventListener('mousedown', onDocClick);\r\n }, [open]);\r\n\r\n const items: ItemDef[] = [\r\n onApplyToMany && { key: 'apply', label: i18n.applyToMany, onClick: onApplyToMany, icon: Layers },\r\n onCopyFrom && { key: 'copy', label: i18n.copyFrom, onClick: onCopyFrom, icon: Copy },\r\n onImportCsv && { key: 'imp', label: i18n.importCsv, onClick: onImportCsv, icon: Upload, divider: true },\r\n onExportCsv && { key: 'exp', label: i18n.exportCsv, onClick: onExportCsv, icon: Download },\r\n onClearMany && { key: 'clear', label: i18n.clear, onClick: onClearMany, icon: Eraser, tone: 'danger' as const, divider: true },\r\n ].filter(Boolean) as ItemDef[];\r\n\r\n if (items.length === 0) return null;\r\n\r\n return (\r\n <div className=\"relative\" ref={ref}>\r\n <button\r\n type=\"button\"\r\n onClick={() => setOpen((v) => !v)}\r\n className=\"ra-btn\"\r\n aria-haspopup=\"menu\"\r\n aria-expanded={open}\r\n >\r\n {i18n.bulkActions}\r\n <ChevronDown className=\"w-3.5 h-3.5 opacity-70\" />\r\n </button>\r\n {open && (\r\n <div className=\"absolute right-0 mt-1.5 ra-bulk-menu\" role=\"menu\">\r\n {items.map((it, i) => {\r\n const Icon = it.icon;\r\n return (\r\n <div key={it.key}>\r\n {it.divider && i > 0 && <div className=\"ra-bulk-divider\" />}\r\n <button\r\n type=\"button\"\r\n role=\"menuitem\"\r\n data-tone={it.tone}\r\n onClick={() => { setOpen(false); it.onClick(); }}\r\n className=\"ra-bulk-item\"\r\n >\r\n <Icon className=\"w-3.5 h-3.5 opacity-80\" />\r\n {it.label}\r\n {it.tone === 'danger' && <Trash2 className=\"w-3 h-3 ml-auto opacity-50\" />}\r\n </button>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// DeleteButton — Inline two-step confirm for record deletion. First click\r\n// flips into \"Confirm delete\" in destructive style; auto-reverts after\r\n// `revertMs` if the user doesn't confirm. Apps can intercept via\r\n// `onBeforeDelete` to swap in a heavier modal when stakes are high.\r\n// =============================================================================\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { Trash2 } from 'lucide-react';\r\n\r\nexport interface DeleteButtonProps {\r\n /** Performs the delete. Should resolve when the SDK call completes. */\r\n onConfirm: () => void | Promise<void>;\r\n /**\r\n * Optional async pre-check — return false to abort BEFORE the inline\r\n * confirm flips. Lets apps run their own modal for high-stakes deletes.\r\n */\r\n onBeforeDelete?: () => boolean | Promise<boolean>;\r\n /** Default label (idle state). */\r\n label?: string;\r\n /** Confirm-state label. */\r\n confirmLabel?: string;\r\n /** Auto-revert timeout in ms (default 3000). */\r\n revertMs?: number;\r\n disabled?: boolean;\r\n}\r\n\r\nexport const DeleteButton = ({\r\n onConfirm,\r\n onBeforeDelete,\r\n label = 'Delete record',\r\n confirmLabel = 'Confirm delete',\r\n revertMs = 3000,\r\n disabled,\r\n}: DeleteButtonProps) => {\r\n const [armed, setArmed] = useState(false);\r\n const [busy, setBusy] = useState(false);\r\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n const clearTimer = () => {\r\n if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = null; }\r\n };\r\n useEffect(() => () => clearTimer(), []);\r\n\r\n const arm = async () => {\r\n if (onBeforeDelete) {\r\n const ok = await onBeforeDelete();\r\n if (!ok) return; // App-level modal said no.\r\n }\r\n setArmed(true);\r\n clearTimer();\r\n timerRef.current = setTimeout(() => setArmed(false), revertMs);\r\n };\r\n\r\n const fire = async () => {\r\n clearTimer();\r\n setBusy(true);\r\n try {\r\n await onConfirm();\r\n } finally {\r\n setBusy(false);\r\n setArmed(false);\r\n }\r\n };\r\n\r\n if (armed) {\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={fire}\r\n disabled={busy}\r\n className=\"text-xs px-3 py-1.5 rounded-md font-medium transition-colors flex items-center gap-1.5 disabled:opacity-60\"\r\n style={{\r\n background: 'hsl(var(--ra-danger, 0 70% 45%))',\r\n color: 'hsl(0 0% 100%)',\r\n }}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n {busy ? '…' : confirmLabel}\r\n </button>\r\n );\r\n }\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={arm}\r\n disabled={disabled}\r\n className=\"text-xs px-3 py-1.5 rounded-md border transition-colors hover:bg-[hsl(var(--ra-muted))] disabled:opacity-40 flex items-center gap-1.5\"\r\n style={{\r\n borderColor: 'hsl(var(--ra-border))',\r\n color: 'hsl(var(--ra-danger, var(--ra-text)))',\r\n }}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n {label}\r\n </button>\r\n );\r\n};","import type { ReactNode } from 'react';\r\nimport type { EditorContext, RecordsAdminI18n } from '../types';\r\nimport { ScopeBreadcrumb } from '../shell/ScopeBreadcrumb';\r\nimport { BulkActionsMenu } from './BulkActionsMenu';\r\nimport { StatusDot } from '../browser/StatusDot';\r\nimport { DeleteButton } from './DeleteButton';\r\n\r\ninterface Props<T> {\r\n ctx: EditorContext<T>;\r\n i18n: RecordsAdminI18n;\r\n children: ReactNode;\r\n preview?: ReactNode;\r\n bulkActions?: React.ComponentProps<typeof BulkActionsMenu>;\r\n /** Extra slot rendered in the footer between the danger actions and Save. */\r\n footerExtra?: ReactNode;\r\n /** Optional pre-delete hook (see DeleteButton). */\r\n onBeforeDelete?: () => boolean | Promise<boolean>;\r\n /**\r\n * Friendly title for the editor header (e.g. the selected record's pretty\r\n * `label` from its `RecordSummary`). Falls back to the raw scope breadcrumb\r\n * when omitted, but consumers should pass this so admins see the\r\n * human-readable name rather than internal keys.\r\n */\r\n headerLabel?: string;\r\n /** Optional subtitle shown beneath `headerLabel` (e.g. facet name). */\r\n headerSubtitle?: string;\r\n /**\r\n * Optional technical reference (e.g. productId / SKU) shown as a tiny muted\r\n * caption pinned to the top-right of the header. Power users can scan it\r\n * without it competing with the friendly name as a subtitle.\r\n */\r\n headerMeta?: string;\r\n}\r\n\r\nexport function RecordEditor<T>({\r\n ctx, i18n, children, preview, bulkActions, footerExtra, onBeforeDelete,\r\n headerLabel, headerSubtitle, headerMeta,\r\n}: Props<T>) {\r\n // Only show a source badge when it carries information. \"New\" on a freshly\r\n // selected record is noise — admins find it confusing because it appears\r\n // even on records they consider \"saved\" (the saved value lives at a\r\n // different scope). Inherited / Customised are the cases worth surfacing.\r\n const sourceLabel: string | null =\r\n ctx.source === 'self' ? 'Customised' :\r\n ctx.source === 'inherited' ? 'Inherited' :\r\n null;\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <header\r\n className=\"sticky top-0 z-40 px-5 py-3 border-b flex items-start justify-between gap-3\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}\r\n >\r\n <div className=\"min-w-0 flex-1\">\r\n {headerLabel ? (\r\n <div className=\"min-w-0\">\r\n <div\r\n className=\"text-sm font-medium truncate\"\r\n style={{ color: 'hsl(var(--ra-text))' }}\r\n title={headerLabel}\r\n >\r\n {headerLabel}\r\n </div>\r\n {headerSubtitle && (\r\n <div\r\n className=\"text-xs truncate\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n title={headerSubtitle}\r\n >\r\n {headerSubtitle}\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <ScopeBreadcrumb scope={ctx.scope} />\r\n )}\r\n {(sourceLabel || ctx.isDirty) && (\r\n <div className=\"flex items-center gap-1.5 mt-1\">\r\n {sourceLabel && (\r\n <>\r\n <StatusDot source={ctx.source} />\r\n <span className=\"text-[10px] uppercase tracking-wide\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n {sourceLabel}\r\n </span>\r\n </>\r\n )}\r\n {ctx.isDirty && (\r\n <span\r\n className={`flex items-center gap-1 text-[10px] uppercase tracking-wide ${sourceLabel ? 'ml-2' : ''}`}\r\n style={{ color: 'hsl(var(--ra-accent))' }}\r\n >\r\n <span className=\"ra-status-dot ra-status-shared\" aria-hidden=\"true\" />\r\n {i18n.unsavedBadge ?? 'Unsaved'}\r\n </span>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n <div className=\"flex items-start gap-2 shrink-0\">\r\n {headerMeta && (\r\n <code\r\n className=\"text-[10px] font-mono px-1.5 py-0.5 rounded truncate max-w-[14rem] mt-0.5\"\r\n style={{\r\n color: 'hsl(var(--ra-muted-text) / 0.85)',\r\n background: 'hsl(var(--ra-muted) / 0.5)',\r\n border: '1px solid hsl(var(--ra-border) / 0.6)',\r\n }}\r\n title={headerMeta}\r\n >\r\n {headerMeta}\r\n </code>\r\n )}\r\n {bulkActions && <BulkActionsMenu {...bulkActions} i18n={i18n} />}\r\n </div>\r\n </header>\r\n <div className=\"flex-1 overflow-y-auto px-5 py-4\">\r\n {children}\r\n {preview}\r\n </div>\r\n <footer\r\n className=\"sticky bottom-0 px-5 py-3 border-t flex items-center justify-between gap-2\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}\r\n >\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n type=\"button\"\r\n onClick={ctx.reset}\r\n disabled={!ctx.isDirty || !!ctx.isSaving}\r\n className=\"text-xs px-3 py-1.5 rounded-md border transition-opacity disabled:opacity-40 hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n {i18n.discard}\r\n </button>\r\n {ctx.canRemove && (\r\n <DeleteButton\r\n onConfirm={() => ctx.remove()}\r\n onBeforeDelete={onBeforeDelete}\r\n label={i18n.delete}\r\n confirmLabel={i18n.confirmDelete}\r\n />\r\n )}\r\n {footerExtra}\r\n {ctx.saveError != null && !ctx.isSaving && (\r\n <span\r\n className=\"text-[10px] uppercase tracking-wide\"\r\n style={{ color: 'hsl(var(--ra-danger, 0 70% 45%))' }}\r\n role=\"alert\"\r\n >\r\n {i18n.saveError ?? 'Save failed'}\r\n </span>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={() => { void ctx.save().catch(() => { /* surfaced via ctx.saveError */ }); }}\r\n disabled={!ctx.isDirty || !!ctx.isSaving}\r\n className=\"text-xs px-3 py-1.5 rounded-md font-medium transition-opacity disabled:opacity-40\"\r\n style={{ background: 'hsl(var(--ra-accent))', color: 'hsl(var(--ra-surface))' }}\r\n >\r\n {ctx.isSaving ? (i18n.saving ?? 'Saving…') : i18n.save}\r\n </button>\r\n </footer>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// ProductDrillDown — Sub-navigation that appears in the editor pane when a\r\n// product is selected. Lets admins jump between the product itself and its\r\n// variants/batches without leaving the product context. Children are loaded\r\n// lazily (per product) by the parent shell, so opening at collection level\r\n// never triggers a collection-wide variant/batch fetch.\r\n// =============================================================================\r\nimport type { ReactNode } from 'react';\r\nimport { Box, Layers, Package } from 'lucide-react';\r\nimport { cn } from '../../../utils/cn';\r\nimport type { ProductChildItem } from '../hooks/useProductChildren';\r\n\r\nexport type DrillTab = 'product' | 'variant' | 'batch';\r\n\r\ninterface Props {\r\n productLabel: string;\r\n /** Which child types are available on the collection. */\r\n showVariants: boolean;\r\n showBatches: boolean;\r\n active: DrillTab;\r\n onChange: (tab: DrillTab) => void;\r\n /** Currently selected child id (variant or batch), if any. */\r\n selectedChildId?: string;\r\n onSelectChild: (id: string) => void;\r\n variants: ProductChildItem[];\r\n batches: ProductChildItem[];\r\n variantsLoading: boolean;\r\n batchesLoading: boolean;\r\n /** Editor body rendered to the right of the picker. */\r\n children: ReactNode;\r\n}\r\n\r\nconst TAB_META: Record<DrillTab, { icon: typeof Box; label: string }> = {\r\n product: { icon: Box, label: 'Product' },\r\n variant: { icon: Layers, label: 'Variants' },\r\n batch: { icon: Package, label: 'Batches' },\r\n};\r\n\r\nexport const ProductDrillDown = ({\r\n productLabel, showVariants, showBatches, active, onChange,\r\n selectedChildId, onSelectChild,\r\n variants, batches, variantsLoading, batchesLoading,\r\n children,\r\n}: Props) => {\r\n const tabs: DrillTab[] = ['product'];\r\n if (showVariants) tabs.push('variant');\r\n if (showBatches) tabs.push('batch');\r\n\r\n // Children list shown for the active tab (only variants/batches use it).\r\n const childList = active === 'variant' ? variants : active === 'batch' ? batches : [];\r\n const childLoading = active === 'variant' ? variantsLoading : active === 'batch' ? batchesLoading : false;\r\n const childEmptyLabel = active === 'variant' ? 'No variants' : 'No batches';\r\n\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n {/* Drill-down tab strip */}\r\n <div\r\n className=\"flex items-center gap-1 px-4 pt-3 border-b\"\r\n style={{ borderColor: 'hsl(var(--ra-border))' }}\r\n >\r\n {tabs.map((t) => {\r\n const meta = TAB_META[t];\r\n const Icon = meta.icon;\r\n const isActive = active === t;\r\n const label = t === 'product' ? productLabel : meta.label;\r\n return (\r\n <button\r\n key={t}\r\n type=\"button\"\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n onClick={() => onChange(t)}\r\n className={cn(\r\n 'flex items-center gap-1.5 px-3 py-2 text-xs border-b-2 -mb-px transition-colors',\r\n isActive ? 'font-medium' : 'opacity-60 hover:opacity-100',\r\n )}\r\n style={{\r\n borderColor: isActive ? 'hsl(var(--ra-accent))' : 'transparent',\r\n color: 'hsl(var(--ra-text))',\r\n }}\r\n >\r\n <Icon className=\"w-3.5 h-3.5\" />\r\n <span className=\"truncate max-w-[160px]\">{label}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n {/* Body: optional child picker on the left, editor on the right */}\r\n <div className=\"flex-1 min-h-0 grid\" style={{\r\n gridTemplateColumns: active === 'product' ? '1fr' : 'minmax(200px, 240px) 1fr',\r\n }}>\r\n {active !== 'product' && (\r\n <aside\r\n className=\"border-r overflow-y-auto\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}\r\n >\r\n {childLoading && (\r\n <div className=\"p-3 space-y-2\">\r\n {[0, 1, 2].map((i) => (\r\n <div key={i} className=\"h-9 rounded animate-pulse\" style={{ background: 'hsl(var(--ra-muted))' }} />\r\n ))}\r\n </div>\r\n )}\r\n {!childLoading && childList.length === 0 && (\r\n <div className=\"p-4 text-xs\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n {childEmptyLabel}\r\n </div>\r\n )}\r\n {!childLoading && childList.length > 0 && (\r\n <ul className=\"divide-y\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n {childList.map((c) => {\r\n const isActive = c.id === selectedChildId;\r\n return (\r\n <li key={c.id}>\r\n <button\r\n type=\"button\"\r\n onClick={() => onSelectChild(c.id)}\r\n className={cn(\r\n 'w-full text-left px-3 py-2 transition-colors hover:bg-[hsl(var(--ra-muted))]',\r\n isActive && 'ra-row-active',\r\n )}\r\n >\r\n <div className=\"text-sm truncate\" style={{ color: 'hsl(var(--ra-text))' }}>{c.name}</div>\r\n {c.subtitle && (\r\n <div className=\"text-xs truncate\" style={{ color: 'hsl(var(--ra-muted-text))' }}>{c.subtitle}</div>\r\n )}\r\n </button>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n )}\r\n </aside>\r\n )}\r\n <div className=\"overflow-hidden\">{children}</div>\r\n </div>\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// PreviewPane — Chrome around an app-supplied preview. Handles the four\r\n// surface modes (inline / side / tab / drawer) and hosts the optional\r\n// PreviewScopePicker. Apps stay focused on their preview content.\r\n// =============================================================================\r\nimport { useState, type ReactNode } from 'react';\r\nimport { X, Eye } from 'lucide-react';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nexport type PreviewMode = 'inline' | 'side' | 'tab' | 'drawer';\r\n\r\ninterface CommonProps {\r\n /** App-rendered preview body. */\r\n children: ReactNode;\r\n /** Optional scope picker rendered in the chrome header. */\r\n scopePicker?: ReactNode;\r\n /** Header label (defaults to \"Preview\"). */\r\n label?: string;\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// Shared header — used by side/drawer/tab variants.\r\n// -----------------------------------------------------------------------------\r\nconst PreviewHeader = ({\r\n label, scopePicker, onClose,\r\n}: { label: string; scopePicker?: ReactNode; onClose?: () => void }) => (\r\n <header\r\n className=\"px-4 py-2.5 border-b flex items-center justify-between gap-3 flex-wrap\"\r\n style={{\r\n borderColor: 'hsl(var(--ra-border))',\r\n background: 'hsl(var(--ra-surface))',\r\n }}\r\n >\r\n <div\r\n className=\"flex items-center gap-1.5 text-[10px] uppercase tracking-wide\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n <Eye className=\"w-3 h-3\" />\r\n {label}\r\n </div>\r\n {scopePicker}\r\n {onClose && (\r\n <button\r\n type=\"button\"\r\n onClick={onClose}\r\n aria-label=\"Close preview\"\r\n className=\"p-1 rounded hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n <X className=\"w-3.5 h-3.5\" />\r\n </button>\r\n )}\r\n </header>\r\n);\r\n\r\n// -----------------------------------------------------------------------------\r\n// inline — bottom of the editor body. Same as legacy ResolvedPreview.\r\n// -----------------------------------------------------------------------------\r\nexport const InlinePreview = ({ children, scopePicker, label = 'Preview' }: CommonProps) => (\r\n <div className=\"mt-4 pt-4 border-t\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n <div className=\"flex items-center justify-between gap-2 mb-2 flex-wrap\">\r\n <div\r\n className=\"text-[10px] uppercase tracking-wide\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n {label}\r\n </div>\r\n {scopePicker}\r\n </div>\r\n {children}\r\n </div>\r\n);\r\n\r\n// -----------------------------------------------------------------------------\r\n// side — fixed-width pane to the right of the editor. The shell composes the\r\n// outer grid; this component just renders the header + body.\r\n// -----------------------------------------------------------------------------\r\nexport interface SidePreviewProps extends CommonProps {\r\n /** When provided, renders an inline close button so admins can collapse\r\n * the preview pane on narrow screens. Caller is responsible for hiding\r\n * the pane afterwards. */\r\n onClose?: () => void;\r\n}\r\n\r\nexport const SidePreview = ({\r\n children, scopePicker, label = 'Preview', onClose,\r\n}: SidePreviewProps) => (\r\n <div className=\"ra-preview-rail\">\r\n <header className=\"ra-preview-rail-header\">\r\n <div className=\"ra-preview-rail-title\">\r\n <Eye className=\"w-3 h-3\" />\r\n {label}\r\n </div>\r\n {scopePicker && <div className=\"ml-auto\">{scopePicker}</div>}\r\n {onClose && (\r\n <button\r\n type=\"button\"\r\n onClick={onClose}\r\n aria-label=\"Close preview\"\r\n className={scopePicker ? 'p-1 rounded hover:bg-[hsl(var(--ra-muted))]' : 'ml-auto p-1 rounded hover:bg-[hsl(var(--ra-muted))]'}\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n <X className=\"w-3.5 h-3.5\" />\r\n </button>\r\n )}\r\n </header>\r\n <div className=\"ra-preview-rail-body\">{children}</div>\r\n </div>\r\n);\r\n\r\n// -----------------------------------------------------------------------------\r\n// tab — Editor / Preview siblings inside the same column. Caller passes the\r\n// editor + preview as children in a `{ editor, preview }` slot pattern.\r\n// -----------------------------------------------------------------------------\r\nexport interface TabbedPreviewProps {\r\n editor: ReactNode;\r\n preview: ReactNode;\r\n scopePicker?: ReactNode;\r\n /** Initial active tab (default `editor`). */\r\n defaultTab?: 'editor' | 'preview';\r\n i18n?: { editor?: string; preview?: string };\r\n}\r\n\r\nexport const TabbedPreview = ({\r\n editor, preview, scopePicker, defaultTab = 'editor', i18n,\r\n}: TabbedPreviewProps) => {\r\n const [tab, setTab] = useState<'editor' | 'preview'>(defaultTab);\r\n return (\r\n <div className=\"flex flex-col h-full\">\r\n <div\r\n className=\"flex items-center gap-1 px-4 pt-3 border-b\"\r\n style={{ borderColor: 'hsl(var(--ra-border))' }}\r\n >\r\n {(['editor', 'preview'] as const).map((t) => {\r\n const isActive = tab === t;\r\n const lbl = t === 'editor'\r\n ? (i18n?.editor ?? 'Editor')\r\n : (i18n?.preview ?? 'Preview');\r\n return (\r\n <button\r\n key={t}\r\n type=\"button\"\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n onClick={() => setTab(t)}\r\n className={cn(\r\n 'px-3 py-2 text-xs border-b-2 -mb-px transition-colors',\r\n isActive ? 'font-medium' : 'opacity-60 hover:opacity-100',\r\n )}\r\n style={{\r\n borderColor: isActive ? 'hsl(var(--ra-accent))' : 'transparent',\r\n color: 'hsl(var(--ra-text))',\r\n }}\r\n >\r\n {lbl}\r\n </button>\r\n );\r\n })}\r\n {tab === 'preview' && scopePicker && (\r\n <div className=\"ml-auto pb-1\">{scopePicker}</div>\r\n )}\r\n </div>\r\n <div className=\"flex-1 min-h-0\">\r\n {tab === 'editor' ? editor : (\r\n <div className=\"h-full overflow-y-auto p-4\">{preview}</div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n// -----------------------------------------------------------------------------\r\n// drawer — slides in from the right, overlaying the editor.\r\n// -----------------------------------------------------------------------------\r\nexport interface DrawerPreviewProps extends CommonProps {\r\n open: boolean;\r\n onClose: () => void;\r\n /** Drawer width (default 420). */\r\n width?: number;\r\n}\r\n\r\nexport const DrawerPreview = ({\r\n open, onClose, children, scopePicker, label = 'Preview', width = 420,\r\n}: DrawerPreviewProps) => {\r\n if (!open) return null;\r\n return (\r\n <>\r\n <div\r\n className=\"absolute inset-0 z-10 transition-opacity\"\r\n style={{ background: 'hsl(0 0% 0% / 0.25)' }}\r\n onClick={onClose}\r\n aria-hidden=\"true\"\r\n />\r\n <aside\r\n className=\"absolute top-0 right-0 bottom-0 z-20 flex flex-col shadow-xl\"\r\n style={{\r\n width,\r\n background: 'hsl(var(--ra-bg, var(--ra-surface)))',\r\n borderLeft: '1px solid hsl(var(--ra-border))',\r\n }}\r\n role=\"dialog\"\r\n aria-label={label}\r\n >\r\n <PreviewHeader label={label} scopePicker={scopePicker} onClose={onClose} />\r\n <div className=\"flex-1 overflow-y-auto p-4\">{children}</div>\r\n </aside>\r\n </>\r\n );\r\n};\r\n\r\n// -----------------------------------------------------------------------------\r\n// Toggle button — used by the editor footer to summon a closed drawer.\r\n// -----------------------------------------------------------------------------\r\nexport const PreviewToggleButton = ({\r\n onClick, label = 'Open preview',\r\n}: { onClick: () => void; label?: string }) => (\r\n <button\r\n type=\"button\"\r\n onClick={onClick}\r\n className=\"text-xs px-3 py-1.5 rounded-md border transition-colors hover:bg-[hsl(var(--ra-muted))] flex items-center gap-1.5\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n <Eye className=\"w-3.5 h-3.5\" />\r\n {label}\r\n </button>\r\n);","// =============================================================================\r\n// PreviewScopePicker — Lets admins preview as a different scope than they're\r\n// editing. E.g. edit a facet-level recipe, preview as Product X to see how it\r\n// cascades. Lazy-loaded children scoped to the picked product.\r\n// =============================================================================\r\nimport { useEffect, useMemo, useState } from 'react';\r\nimport type { ParsedRef, SmartLinksSDK } from '../types';\r\nimport { useProductBrowse } from '../hooks/useProductBrowse';\r\nimport { useProductChildren } from '../hooks/useProductChildren';\r\nimport { Eye, ChevronDown } from 'lucide-react';\r\n\r\nexport interface PreviewScopePickerProps {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n /** The scope currently being edited — used as the \"Same as edited\" default. */\r\n editingScope: ParsedRef;\r\n /** The current preview scope. */\r\n value: ParsedRef;\r\n onChange: (next: ParsedRef) => void;\r\n /** Are variants/batches available for drill-down. */\r\n showVariants: boolean;\r\n showBatches: boolean;\r\n /** i18n strings (uses defaults if omitted). */\r\n i18n?: { previewAs?: string; previewAsDefault?: string };\r\n}\r\n\r\nconst SELECT_CLS =\r\n 'text-xs px-2 py-1 rounded-md border bg-transparent focus:outline-none focus:ring-1';\r\n\r\nexport const PreviewScopePicker = ({\r\n SL, collectionId, editingScope, value, onChange,\r\n showVariants, showBatches, i18n,\r\n}: PreviewScopePickerProps) => {\r\n // The product axis is only meaningful when the scope being edited isn't\r\n // already pinned to a product — i.e. on the facet (Shared) tab. When the\r\n // user is already editing a specific product/variant/batch, switching\r\n // products in the preview picker is incoherent.\r\n const productPinned = !!editingScope.productId;\r\n\r\n // Only fetch products when we actually need them — keeps the facet tab\r\n // snappy and avoids paginated SDK calls for hosts that pin a product.\r\n const products = useProductBrowse({\r\n SL, collectionId, pageSize: 100,\r\n enabled: !productPinned,\r\n });\r\n const variants = useProductChildren({\r\n SL, collectionId, productId: value.productId,\r\n kind: showVariants ? 'variant' : null,\r\n });\r\n const batches = useProductChildren({\r\n SL, collectionId, productId: value.productId,\r\n kind: showBatches ? 'batch' : null,\r\n });\r\n\r\n const isDefault = useMemo(\r\n () => value.raw === editingScope.raw,\r\n [value.raw, editingScope.raw],\r\n );\r\n\r\n // Auto-pick the first product when previewing from facet scope so the\r\n // preview surface always has something to render. The user can override\r\n // via the on-demand picker, but the default is a sensible \"best match\".\r\n useEffect(() => {\r\n if (productPinned) return;\r\n if (value.productId) return;\r\n const first = products.items[0];\r\n if (!first) return;\r\n onChange({\r\n ...value,\r\n productId: first.id,\r\n variantId: undefined,\r\n batchId: undefined,\r\n raw: `product:${first.id}`,\r\n });\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [productPinned, value.productId, products.items]);\r\n\r\n // The product picker is collapsed by default — most admins don't need it.\r\n // Click the muted \"as <Product Name>\" chip to reveal the dropdown.\r\n const [productPickerOpen, setProductPickerOpen] = useState(false);\r\n\r\n const showProductPicker = !productPinned && products.items.length > 1;\r\n const showVariantPicker = showVariants && !!value.productId && variants.items.length > 0;\r\n const showBatchPicker = showBatches && !!value.productId && batches.items.length > 0;\r\n\r\n // If there's nothing meaningful to pick (single product, no variants /\r\n // batches), don't render the picker chrome at all — it just took up\r\n // horizontal space and pushed the rail onto two lines.\r\n if (!showProductPicker && !showVariantPicker && !showBatchPicker) {\r\n return null;\r\n }\r\n\r\n const currentProductName =\r\n products.items.find((p) => p.id === value.productId)?.name\r\n ?? value.productId\r\n ?? '';\r\n\r\n const selectStyle = {\r\n borderColor: 'hsl(var(--ra-border))',\r\n color: 'hsl(var(--ra-text))',\r\n };\r\n\r\n return (\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span\r\n className=\"flex items-center gap-1 text-[10px] uppercase tracking-wide\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n <Eye className=\"w-3 h-3\" />\r\n {i18n?.previewAs ?? 'Preview as'}\r\n </span>\r\n\r\n {/* Reset to \"same as edited\" */}\r\n {!isDefault && (\r\n <button\r\n type=\"button\"\r\n onClick={() => onChange(editingScope)}\r\n className=\"text-[10px] px-2 py-1 rounded-md border hover:bg-[hsl(var(--ra-muted))]\"\r\n style={selectStyle}\r\n >\r\n ↺ {i18n?.previewAsDefault ?? 'Same as edited'}\r\n </button>\r\n )}\r\n\r\n {/* Product picker — collapsed by default. Reveal on demand so the\r\n picker doesn't take over the preview header on narrow screens. */}\r\n {showProductPicker && !productPickerOpen && currentProductName && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setProductPickerOpen(true)}\r\n className=\"text-[10px] px-2 py-1 rounded-md border hover:bg-[hsl(var(--ra-muted))] inline-flex items-center gap-1 max-w-[12rem] truncate\"\r\n style={selectStyle}\r\n title={`Preview as ${currentProductName} — click to change`}\r\n >\r\n as <span className=\"font-medium truncate\">{currentProductName}</span>\r\n <ChevronDown className=\"w-3 h-3 opacity-60\" />\r\n </button>\r\n )}\r\n {showProductPicker && productPickerOpen && (\r\n <select\r\n className={SELECT_CLS}\r\n style={selectStyle}\r\n autoFocus\r\n onBlur={() => setProductPickerOpen(false)}\r\n value={value.productId ?? ''}\r\n onChange={(e) => {\r\n const productId = e.target.value || undefined;\r\n onChange({\r\n ...value,\r\n productId,\r\n variantId: undefined,\r\n batchId: undefined,\r\n raw: productId ? `product:${productId}` : '',\r\n });\r\n setProductPickerOpen(false);\r\n }}\r\n >\r\n {products.items.map((p) => (\r\n <option key={p.id} value={p.id}>{p.name}</option>\r\n ))}\r\n </select>\r\n )}\r\n\r\n {/* Variant picker (only when product selected and variants supported) */}\r\n {showVariantPicker && (\r\n <select\r\n className={SELECT_CLS}\r\n style={selectStyle}\r\n value={value.variantId ?? ''}\r\n onChange={(e) => {\r\n const variantId = e.target.value || undefined;\r\n onChange({\r\n ...value,\r\n variantId,\r\n batchId: undefined,\r\n raw: variantId ? `product:${value.productId}/variant:${variantId}` : `product:${value.productId}`,\r\n });\r\n }}\r\n >\r\n <option value=\"\">— Any variant —</option>\r\n {variants.items.map((v) => (\r\n <option key={v.id} value={v.id}>{v.name}</option>\r\n ))}\r\n </select>\r\n )}\r\n\r\n {/* Batch picker */}\r\n {showBatchPicker && (\r\n <select\r\n className={SELECT_CLS}\r\n style={selectStyle}\r\n value={value.batchId ?? ''}\r\n onChange={(e) => {\r\n const batchId = e.target.value || undefined;\r\n onChange({\r\n ...value,\r\n batchId,\r\n raw: batchId ? `product:${value.productId}/batch:${batchId}` : `product:${value.productId}`,\r\n });\r\n }}\r\n >\r\n <option value=\"\">— Any batch —</option>\r\n {batches.items.map((b) => (\r\n <option key={b.id} value={b.id}>{b.name}</option>\r\n ))}\r\n </select>\r\n )}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// IntroCard — soft tinted onboarding banner with tone variants.\r\n// v0.4: lightbulb icon, title, body, optional learn-more, dismiss X.\r\n// =============================================================================\r\nimport { X, Lightbulb, CheckCircle2, AlertTriangle, Info } from 'lucide-react';\r\nimport type { ReactNode } from 'react';\r\n\r\nexport type IntroTone = 'info' | 'success' | 'warning';\r\n\r\ninterface Props {\r\n title: string;\r\n body: ReactNode;\r\n onDismiss: () => void;\r\n /** Visual tone — controls icon and surface tint. */\r\n tone?: IntroTone;\r\n /** Optional \"Learn more\" link or button rendered inline after the body. */\r\n action?: ReactNode;\r\n}\r\n\r\nconst TONE_ICON = {\r\n info: Lightbulb,\r\n success: CheckCircle2,\r\n warning: AlertTriangle,\r\n} as const;\r\n\r\nexport const IntroCard = ({ title, body, onDismiss, tone = 'info', action }: Props) => {\r\n const Icon = TONE_ICON[tone] ?? Info;\r\n return (\r\n <div className=\"ra-intro\" data-tone={tone} role=\"note\">\r\n <div className=\"ra-intro-icon\">\r\n <Icon className=\"w-4 h-4\" />\r\n </div>\r\n <div className=\"ra-intro-body\">\r\n <h4 className=\"ra-intro-title\">{title}</h4>\r\n <div className=\"ra-intro-text\">\r\n {body}\r\n {action && <span className=\"ml-1.5\">{action}</span>}\r\n </div>\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={onDismiss}\r\n aria-label=\"Dismiss\"\r\n className=\"ra-intro-dismiss\"\r\n >\r\n <X className=\"w-3.5 h-3.5\" />\r\n </button>\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// UtilityRow — quiet metadata strip above the shell body.\r\n// v0.4: shows the slug + \"How {label} works\" reopen link, lighter chrome.\r\n// =============================================================================\r\nimport { HelpCircle } from 'lucide-react';\r\n\r\ninterface Props {\r\n label: string;\r\n introHidden: boolean;\r\n onShowIntro?: () => void;\r\n}\r\n\r\nexport const UtilityRow = ({ label, introHidden, onShowIntro }: Props) => {\r\n if (!introHidden || !onShowIntro) return null;\r\n return (\r\n <div\r\n className=\"flex items-center justify-end gap-2 text-xs\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n <button\r\n type=\"button\"\r\n onClick={onShowIntro}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n style={{ padding: '0.25rem 0.55rem', fontSize: '0.7rem' }}\r\n >\r\n <HelpCircle className=\"w-3 h-3\" />\r\n How {label.toLowerCase()} works\r\n </button>\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// RecordsAdmin — ShellHeader (v0.4)\r\n//\r\n// Branded header card rendered at the top of `RecordsAdminShell`. Provides:\r\n// - Contextual icon (explicit `headerIcon` or registry fallback)\r\n// - Display-weight title + muted subtitle\r\n// - Right-aligned action slot (typically primary \"+ New\" + secondary controls)\r\n// - Optional per-scope counts strip\r\n// =============================================================================\r\nimport { createElement, type ReactNode } from 'react';\r\nimport { pickHeaderIcon, type RecordsAdminIcons } from './icons';\r\n\r\nexport interface ShellHeaderProps {\r\n title: string;\r\n subtitle?: string;\r\n headerIcon?: ReactNode;\r\n headerActions?: ReactNode;\r\n showStats?: boolean;\r\n showHeaderIcon?: boolean;\r\n recordType?: string;\r\n icons: RecordsAdminIcons;\r\n stats?: { products?: number; shared?: number };\r\n /** Fully custom items — when provided, replace the built-in Shared/Products counts. */\r\n statsItems?: Array<{ label: string; value: string | number }>;\r\n /** Optional title rendered above the stats items. */\r\n statsTitle?: string;\r\n /** Optional icon rendered alongside `statsTitle`. */\r\n statsIcon?: ReactNode;\r\n}\r\n\r\nexport function ShellHeader({\r\n title, subtitle, headerIcon, headerActions, showStats = false,\r\n showHeaderIcon = true,\r\n recordType, icons, stats, statsItems, statsTitle, statsIcon,\r\n}: ShellHeaderProps) {\r\n // Resolve the header icon: explicit prop wins; otherwise look up in registry.\r\n // Skip entirely when showHeaderIcon is false.\r\n let iconNode: ReactNode = null;\r\n if (showHeaderIcon) {\r\n if (headerIcon) {\r\n iconNode = headerIcon;\r\n } else {\r\n const Icon = pickHeaderIcon(icons, recordType);\r\n iconNode = createElement(Icon, { className: 'w-4 h-4', 'aria-hidden': true });\r\n }\r\n }\r\n\r\n // Resolve stats items. Custom `statsItems` always wins. Otherwise fall back\r\n // to the built-in Shared/Products pair, but only when there is at least one\r\n // non-zero value — a fresh app shouldn't render \"0 Shared 0 Products\".\r\n const resolvedItems: Array<{ label: string; value: string | number }> = (() => {\r\n if (!showStats) return [];\r\n if (statsItems && statsItems.length > 0) return statsItems;\r\n const items: Array<{ label: string; value: string | number }> = [];\r\n if (typeof stats?.shared === 'number' && stats.shared > 0) {\r\n items.push({ label: 'Shared', value: stats.shared });\r\n }\r\n if (typeof stats?.products === 'number' && stats.products > 0) {\r\n items.push({ label: 'Products', value: stats.products });\r\n }\r\n return items;\r\n })();\r\n const hasStats = resolvedItems.length > 0;\r\n const hasStatsHeading = !!(statsTitle || statsIcon);\r\n\r\n return (\r\n <header className=\"ra-header\">\r\n <div className=\"ra-header__main\">\r\n {iconNode ? (\r\n <div className=\"ra-header-icon\" aria-hidden=\"true\">\r\n {iconNode}\r\n </div>\r\n ) : null}\r\n <div className=\"ra-header-text\">\r\n <h1 className=\"ra-header-title\">{title}</h1>\r\n {subtitle ? <p className=\"ra-header-subtitle\">{subtitle}</p> : null}\r\n </div>\r\n </div>\r\n <div className=\"ra-header-aside\">\r\n {hasStats ? (\r\n <div\r\n className={`ra-header-stats${hasStatsHeading ? ' ra-header-stats--titled' : ''}`}\r\n role=\"group\"\r\n aria-label={statsTitle ?? 'Record counts'}\r\n >\r\n {hasStatsHeading ? (\r\n <div className=\"ra-stats-heading\">\r\n {statsIcon ? (\r\n <span className=\"ra-stats-heading-icon\" aria-hidden=\"true\">{statsIcon}</span>\r\n ) : null}\r\n {statsTitle ? <span className=\"ra-stats-heading-label\">{statsTitle}</span> : null}\r\n </div>\r\n ) : null}\r\n <div className=\"ra-stats-items\">\r\n {resolvedItems.map((item, idx) => (\r\n <span key={`${item.label}-${idx}`} style={{ display: 'contents' }}>\r\n {idx > 0 && <span className=\"ra-stat-divider\" aria-hidden=\"true\" />}\r\n <span className=\"ra-stat\">\r\n <span className=\"ra-stat-value\">{item.value}</span>\r\n <span className=\"ra-stat-label\">{item.label}</span>\r\n </span>\r\n </span>\r\n ))}\r\n </div>\r\n </div>\r\n ) : null}\r\n {headerActions ? <div className=\"ra-header-actions\">{headerActions}</div> : null}\r\n </div>\r\n </header>\r\n );\r\n}","// =============================================================================\r\n// UnsavedBanner — slim, themed notice rendered at the top of the shell when\r\n// the editor has unsaved changes. Replaces the old blocking confirm() with an\r\n// always-visible \"you have unsaved changes on X\" affordance, plus inline\r\n// Save / Discard buttons so admins can act from anywhere without losing\r\n// context. The banner is purely advisory — navigation isn't blocked.\r\n// =============================================================================\r\nimport { Save, Undo2, AlertCircle } from 'lucide-react';\r\n\r\nexport interface UnsavedBannerProps {\r\n /** Friendly label for the dirty record (e.g. selected facet value name). */\r\n label?: string;\r\n /** Optional secondary descriptor (e.g. facet name, scope kind). */\r\n context?: string;\r\n isSaving?: boolean;\r\n saveError?: unknown;\r\n onSave: () => void;\r\n onDiscard: () => void;\r\n saveLabel: string;\r\n discardLabel: string;\r\n /** Body template containing `{name}` placeholder. */\r\n bodyTemplate: string;\r\n savingLabel?: string;\r\n errorLabel?: string;\r\n}\r\n\r\nexport const UnsavedBanner = ({\r\n label, context, isSaving, saveError, onSave, onDiscard,\r\n saveLabel, discardLabel, bodyTemplate, savingLabel, errorLabel,\r\n}: UnsavedBannerProps) => {\r\n const name = label ?? context ?? 'this record';\r\n const message = bodyTemplate.replace('{name}', name);\r\n return (\r\n <div className=\"ra-unsaved-banner\" role=\"status\" aria-live=\"polite\">\r\n <span className=\"ra-unsaved-icon\" aria-hidden=\"true\">\r\n <AlertCircle className=\"w-3.5 h-3.5\" />\r\n </span>\r\n <span className=\"ra-unsaved-text\">\r\n {message}\r\n {context && label && (\r\n <span className=\"ra-unsaved-context\"> · {context}</span>\r\n )}\r\n </span>\r\n {saveError != null && !isSaving && (\r\n <span className=\"ra-unsaved-error\" role=\"alert\">\r\n {errorLabel ?? 'Save failed'}\r\n </span>\r\n )}\r\n <div className=\"ra-unsaved-actions\">\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-ghost\"\r\n onClick={onDiscard}\r\n disabled={isSaving}\r\n >\r\n <Undo2 className=\"w-3 h-3\" />\r\n {discardLabel}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-primary\"\r\n onClick={onSave}\r\n disabled={isSaving}\r\n >\r\n <Save className=\"w-3 h-3\" />\r\n {isSaving ? (savingLabel ?? 'Saving…') : saveLabel}\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// CSV import / export — minimal RFC4180-ish round-trip (no quoted newlines)\r\n// =============================================================================\r\nimport type { CsvSchema, RecordSummary } from '../types';\r\nimport type { RecordsCtx } from './records';\r\nimport { upsertRecord } from './records';\r\nimport { parseRef } from './refs';\r\nimport { parsedRefToScope } from './scopeBridge';\r\n\r\nexport interface ImportReport {\r\n total: number;\r\n saved: number;\r\n failed: number;\r\n errorRows: Array<{ row: number; error: string }>;\r\n /** Annotated CSV ready for download (input + `error` column). */\r\n annotatedCsv: string;\r\n}\r\n\r\nconst escapeCell = (s: string): string => {\r\n if (/[\",\\n]/.test(s)) return `\"${s.replace(/\"/g, '\"\"')}\"`;\r\n return s;\r\n};\r\n\r\nconst parseLine = (line: string): string[] => {\r\n const out: string[] = [];\r\n let cur = '';\r\n let inQuotes = false;\r\n for (let i = 0; i < line.length; i += 1) {\r\n const ch = line[i];\r\n if (inQuotes) {\r\n if (ch === '\"' && line[i + 1] === '\"') { cur += '\"'; i += 1; }\r\n else if (ch === '\"') inQuotes = false;\r\n else cur += ch;\r\n } else if (ch === '\"') inQuotes = true;\r\n else if (ch === ',') { out.push(cur); cur = ''; }\r\n else cur += ch;\r\n }\r\n out.push(cur);\r\n return out;\r\n};\r\n\r\nexport const exportCsv = <T,>(\r\n records: RecordSummary<T>[],\r\n schema: CsvSchema<T>,\r\n): Blob => {\r\n const headers = ['ref', ...schema.columns.map((c) => c.header)];\r\n const rows = records\r\n .filter((r) => r.data != null)\r\n .map((r) => [r.ref, ...schema.columns.map((c) => c.toCell(r.data as T))]);\r\n const csv = [headers, ...rows]\r\n .map((row) => row.map((cell) => escapeCell(String(cell ?? ''))).join(','))\r\n .join('\\n');\r\n return new Blob([csv], { type: 'text/csv;charset=utf-8' });\r\n};\r\n\r\nexport const importCsv = async <T,>(\r\n file: File,\r\n schema: CsvSchema<T>,\r\n ctx: RecordsCtx,\r\n): Promise<ImportReport> => {\r\n const text = await file.text();\r\n const lines = text.split(/\\r?\\n/).filter((l) => l.length > 0);\r\n if (lines.length === 0) {\r\n return { total: 0, saved: 0, failed: 0, errorRows: [], annotatedCsv: '' };\r\n }\r\n const headers = parseLine(lines[0]);\r\n const refIdx = headers.indexOf('ref');\r\n const colMap = schema.columns.map((c) => ({ col: c, idx: headers.indexOf(c.header) }));\r\n\r\n const errorRows: Array<{ row: number; error: string }> = [];\r\n let saved = 0;\r\n for (let i = 1; i < lines.length; i += 1) {\r\n const cells = parseLine(lines[i]);\r\n const ref = refIdx >= 0 ? cells[refIdx] : '';\r\n if (!ref) {\r\n errorRows.push({ row: i, error: 'Missing ref' });\r\n continue;\r\n }\r\n const data: Record<string, unknown> = {};\r\n for (const { col, idx } of colMap) {\r\n if (idx < 0) continue;\r\n try { data[col.key] = col.fromCell(cells[idx] ?? ''); }\r\n catch (e) { errorRows.push({ row: i, error: (e as Error).message }); continue; }\r\n }\r\n const validation = schema.validate?.(data);\r\n if (validation) { errorRows.push({ row: i, error: validation }); continue; }\r\n try {\r\n // eslint-disable-next-line no-await-in-loop\r\n await upsertRecord<T>(ctx, {\r\n ref,\r\n scope: parsedRefToScope(parseRef(ref)),\r\n data: data as T,\r\n });\r\n saved += 1;\r\n } catch (e) {\r\n errorRows.push({ row: i, error: (e as Error).message });\r\n }\r\n }\r\n\r\n const annotatedHeaders = [...headers, 'error'];\r\n const annotatedRows = lines.slice(1).map((line, idx) => {\r\n const err = errorRows.find((er) => er.row === idx + 1);\r\n const cells = parseLine(line);\r\n while (cells.length < headers.length) cells.push('');\r\n cells.push(err?.error ?? '');\r\n return cells.map(escapeCell).join(',');\r\n });\r\n const annotatedCsv = [annotatedHeaders.join(','), ...annotatedRows].join('\\n');\r\n\r\n return {\r\n total: lines.length - 1,\r\n saved,\r\n failed: errorRows.length,\r\n errorRows,\r\n annotatedCsv,\r\n };\r\n};\r\n\r\nexport const downloadBlob = (blob: Blob, filename: string): void => {\r\n const url = URL.createObjectURL(blob);\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = filename;\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n URL.revokeObjectURL(url);\r\n};","import styleInject from '#style-inject';styleInject(\":root {\\n --ra-status-own: var(--ra-emerald, 142 71% 45%);\\n --ra-status-shared: var(--ra-amber, 38 92% 50%);\\n --ra-status-missing: var(--muted-foreground, 220 9% 46%);\\n --ra-accent: var(--primary, 222 47% 11%);\\n --ra-surface: var(--card, 0 0% 100%);\\n --ra-border: var(--border, 220 13% 91%);\\n --ra-text: var(--foreground, 222 47% 11%);\\n --ra-muted: var(--muted, 220 14% 96%);\\n --ra-muted-text: var(--muted-foreground, 220 9% 46%);\\n --ra-radius: var(--radius, 0.625rem);\\n --ra-dot-size: 0.5rem;\\n --ra-page-bg: var(--background, 220 14% 98%);\\n --ra-card-shadow: 0 1px 2px hsl(var(--ra-accent) / 0.04), 0 4px 12px hsl(var(--ra-accent) / 0.05);\\n --ra-card-shadow-hover: 0 2px 4px hsl(var(--ra-accent) / 0.06), 0 8px 24px hsl(var(--ra-accent) / 0.08);\\n --ra-row-hover: hsl(var(--ra-accent) / 0.05);\\n --ra-row-active-bg: hsl(var(--ra-accent) / 0.10);\\n --ra-row-active-bd: hsl(var(--ra-accent) / 0.45);\\n --ra-focus-ring: hsl(var(--ra-accent) / 0.35);\\n --ra-font-display: var(--font-display, var(--font-sans, ui-sans-serif, system-ui, -apple-system, \\\"Segoe UI\\\", Roboto, sans-serif));\\n --ra-font-ui: var(--font-sans, ui-sans-serif, system-ui, -apple-system, \\\"Segoe UI\\\", Roboto, sans-serif);\\n --ra-title-weight: 600;\\n --ra-display-weight: 700;\\n --ra-info: var(--ra-blue, 214 95% 55%);\\n --ra-success: var(--ra-emerald, 142 71% 45%);\\n --ra-warning: var(--ra-amber, 38 92% 50%);\\n --ra-danger: var(--destructive, 0 72% 51%);\\n}\\n.ra-status-dot {\\n display: inline-block;\\n width: var(--ra-dot-size);\\n height: var(--ra-dot-size);\\n border-radius: 9999px;\\n flex-shrink: 0;\\n}\\n.ra-status-own {\\n background: hsl(var(--ra-status-own));\\n}\\n.ra-status-shared {\\n background: hsl(var(--ra-status-shared));\\n}\\n.ra-status-missing {\\n background: hsl(var(--ra-status-missing) / 0.4);\\n border: 1px solid hsl(var(--ra-status-missing) / 0.6);\\n}\\n.ra-row-active {\\n background: var(--ra-row-active-bg);\\n border-color: var(--ra-row-active-bd) !important;\\n}\\n\")","import styleInject from '#style-inject';styleInject(\".ra-shell {\\n color: hsl(var(--ra-text));\\n background: hsl(var(--ra-page-bg));\\n font-family: var(--ra-font-ui);\\n}\\n.ra-shell *,\\n.ra-shell *::before,\\n.ra-shell *::after {\\n box-sizing: border-box;\\n}\\n.ra-shell .ra-card {\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: var(--ra-radius);\\n box-shadow: var(--ra-card-shadow);\\n}\\n.ra-shell .ra-card-hover {\\n transition:\\n box-shadow .18s ease,\\n transform .18s ease,\\n border-color .18s ease;\\n}\\n.ra-shell .ra-card-hover:hover {\\n box-shadow: var(--ra-card-shadow-hover);\\n}\\n.ra-shell .ra-display {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n letter-spacing: -0.01em;\\n}\\n.ra-shell .ra-title {\\n font-weight: var(--ra-title-weight);\\n}\\n.ra-shell :where(button, [role=button], input, select, textarea, a):focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\\n border-radius: calc(var(--ra-radius) * 0.6);\\n}\\n.ra-shell .ra-header {\\n position: relative;\\n display: flex;\\n align-items: center;\\n gap: 0.75rem;\\n padding: 0.65rem 0.9rem;\\n border-radius: var(--ra-radius);\\n border: 1px solid hsl(var(--ra-accent) / 0.12);\\n background:\\n linear-gradient(\\n 135deg,\\n hsl(var(--ra-accent) / 0.08),\\n hsl(var(--ra-accent) / 0.02) 60%,\\n hsl(var(--ra-surface)) 100%);\\n box-shadow: var(--ra-card-shadow);\\n}\\n.ra-shell .ra-header__main {\\n flex: 1;\\n min-width: 0;\\n display: flex;\\n align-items: center;\\n gap: 0.625rem;\\n}\\n.ra-shell .ra-header-aside {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-header-icon {\\n flex-shrink: 0;\\n width: 2rem;\\n height: 2rem;\\n border-radius: calc(var(--ra-radius) * 0.9);\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n background: hsl(var(--ra-accent) / 0.12);\\n color: hsl(var(--ra-accent));\\n border: 1px solid hsl(var(--ra-accent) / 0.18);\\n}\\n.ra-shell .ra-header-text {\\n flex: 1;\\n min-width: 0;\\n}\\n.ra-shell .ra-header-title {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n font-size: 1rem;\\n line-height: 1.2;\\n color: hsl(var(--ra-text));\\n letter-spacing: -0.01em;\\n margin: 0;\\n}\\n.ra-shell .ra-header-subtitle {\\n font-size: 0.75rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.125rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-header-stats {\\n display: flex;\\n align-items: stretch;\\n gap: 0.15rem;\\n padding: 0.15rem 0.4rem;\\n border-radius: calc(var(--ra-radius) * 0.75);\\n background: hsl(var(--ra-surface) / 0.7);\\n border: 1px solid hsl(var(--ra-border));\\n}\\n.ra-shell .ra-header-stats--titled {\\n flex-direction: column;\\n align-items: stretch;\\n padding: 0.4rem 0.55rem;\\n gap: 0.3rem;\\n}\\n.ra-shell .ra-header-stats .ra-stats-items {\\n display: flex;\\n align-items: stretch;\\n gap: 0.15rem;\\n}\\n.ra-shell .ra-header-stats .ra-stats-heading {\\n display: flex;\\n align-items: center;\\n gap: 0.35rem;\\n color: hsl(var(--ra-muted-text));\\n font-size: 0.65rem;\\n text-transform: uppercase;\\n letter-spacing: 0.06em;\\n}\\n.ra-shell .ra-header-stats .ra-stats-heading-icon {\\n display: inline-flex;\\n align-items: center;\\n color: hsl(var(--ra-text));\\n opacity: 0.75;\\n}\\n.ra-shell .ra-header-stats .ra-stats-heading-icon > svg {\\n width: 0.85rem;\\n height: 0.85rem;\\n}\\n.ra-shell .ra-stat {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n padding: 0.15rem 0.45rem;\\n min-width: 2.5rem;\\n}\\n.ra-shell .ra-stat-value {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n font-size: 0.85rem;\\n color: hsl(var(--ra-text));\\n line-height: 1;\\n}\\n.ra-shell .ra-stat-label {\\n font-size: 0.6rem;\\n text-transform: uppercase;\\n letter-spacing: 0.04em;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.15rem;\\n}\\n.ra-shell .ra-stat-divider {\\n width: 1px;\\n background: hsl(var(--ra-border));\\n margin: 0.25rem 0;\\n}\\n.ra-shell .ra-header-actions {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n}\\n.ra-shell .ra-tabs {\\n display: flex;\\n gap: 0.25rem;\\n padding: 0.25rem;\\n background: hsl(var(--ra-muted));\\n border-radius: calc(var(--ra-radius) * 0.85);\\n border: 1px solid hsl(var(--ra-border));\\n}\\n.ra-shell .ra-tab {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n padding: 0.4rem 0.7rem;\\n border-radius: calc(var(--ra-radius) * 0.65);\\n font-size: 0.78rem;\\n font-weight: 500;\\n color: hsl(var(--ra-muted-text));\\n background: transparent;\\n border: 0;\\n cursor: pointer;\\n transition:\\n background .15s ease,\\n color .15s ease,\\n transform .15s ease;\\n white-space: nowrap;\\n}\\n.ra-shell .ra-tab:hover {\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-tab[aria-selected=true] {\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-text));\\n box-shadow: var(--ra-card-shadow);\\n font-weight: var(--ra-title-weight);\\n}\\n.ra-shell .ra-tab[aria-selected=true] .ra-tab-icon {\\n color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-tab[disabled] {\\n opacity: .5;\\n cursor: not-allowed;\\n}\\n.ra-shell .ra-tab-count {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n min-width: 1.25rem;\\n padding: 0 0.35rem;\\n height: 1.1rem;\\n border-radius: 999px;\\n background: hsl(var(--ra-accent) / 0.12);\\n color: hsl(var(--ra-accent));\\n font-size: 0.625rem;\\n font-weight: 600;\\n line-height: 1;\\n}\\n.ra-shell .ra-tab[aria-selected=false] .ra-tab-count {\\n background: hsl(var(--ra-muted-text) / 0.15);\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-shell[data-density=compact] .ra-row {\\n padding-block: 0.4rem;\\n}\\n.ra-shell[data-density=compact] .ra-header {\\n padding: 0.75rem 1rem;\\n}\\n.ra-shell[data-density=compact] .ra-header-icon {\\n width: 2.25rem;\\n height: 2.25rem;\\n}\\n.ra-shell .ra-row {\\n display: flex;\\n align-items: center;\\n gap: 0.65rem;\\n width: 100%;\\n text-align: left;\\n padding: 0.65rem 0.85rem;\\n border-left: 3px solid transparent;\\n background: transparent;\\n border-bottom: 1px solid transparent;\\n transition: background .12s ease, border-color .12s ease;\\n cursor: pointer;\\n color: hsl(var(--ra-text));\\n font-family: inherit;\\n}\\n.ra-shell .ra-row + .ra-row {\\n border-top: 1px solid hsl(var(--ra-border) / 0.6);\\n}\\n.ra-shell .ra-row:hover {\\n background: var(--ra-row-hover);\\n}\\n.ra-shell .ra-row[data-selected=true] {\\n background: var(--ra-row-active-bg);\\n border-left-color: var(--ra-row-active-bd);\\n}\\n.ra-shell .ra-row-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.75rem;\\n height: 1.75rem;\\n border-radius: calc(var(--ra-radius) * 0.6);\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-muted-text));\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-row[data-selected=true] .ra-row-icon {\\n background: hsl(var(--ra-accent) / 0.15);\\n color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-row-body {\\n flex: 1;\\n min-width: 0;\\n}\\n.ra-shell .ra-row-title {\\n font-weight: var(--ra-title-weight);\\n font-size: 0.875rem;\\n line-height: 1.25;\\n color: hsl(var(--ra-text));\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-row-sub {\\n font-size: 0.75rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.15rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-row-actions {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.15rem;\\n margin-left: auto;\\n opacity: 0;\\n transition: opacity .15s ease;\\n}\\n.ra-shell .ra-row:hover .ra-row-actions,\\n.ra-shell .ra-row:focus-within .ra-row-actions {\\n opacity: 1;\\n}\\n.ra-shell .ra-row-action {\\n width: 1.6rem;\\n height: 1.6rem;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n border-radius: 999px;\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n border: 0;\\n cursor: pointer;\\n transition: background .15s ease, color .15s ease;\\n}\\n.ra-shell .ra-row-action:hover {\\n background: hsl(var(--ra-accent) / 0.10);\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-row-action[data-tone=danger]:hover {\\n background: hsl(var(--ra-danger) / 0.12);\\n color: hsl(var(--ra-danger));\\n}\\n.ra-shell .ra-chip {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.3rem;\\n padding: 0.15rem 0.5rem;\\n border-radius: 999px;\\n font-size: 0.6875rem;\\n font-weight: 500;\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-muted-text));\\n border: 1px solid hsl(var(--ra-border));\\n white-space: nowrap;\\n max-width: 14rem;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-chip[data-tone=success] {\\n background: hsl(var(--ra-success) / 0.12);\\n color: hsl(var(--ra-success));\\n border-color: hsl(var(--ra-success) / 0.30);\\n}\\n.ra-shell .ra-chip[data-tone=warning] {\\n background: hsl(var(--ra-warning) / 0.14);\\n color: hsl(var(--ra-warning));\\n border-color: hsl(var(--ra-warning) / 0.35);\\n}\\n.ra-shell .ra-chip[data-tone=info] {\\n background: hsl(var(--ra-info) / 0.10);\\n color: hsl(var(--ra-info));\\n border-color: hsl(var(--ra-info) / 0.30);\\n}\\n.ra-shell .ra-chip[data-tone=danger] {\\n background: hsl(var(--ra-danger) / 0.10);\\n color: hsl(var(--ra-danger));\\n border-color: hsl(var(--ra-danger) / 0.30);\\n}\\n.ra-shell .ra-chip[data-tone=muted] {\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n border-style: dashed;\\n}\\n.ra-shell .ra-group {\\n border-bottom: 1px solid hsl(var(--ra-border));\\n}\\n.ra-shell .ra-group:last-child {\\n border-bottom: 0;\\n}\\n.ra-shell .ra-group-summary {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n width: 100%;\\n padding: 0.5rem 0.85rem;\\n background: hsl(var(--ra-muted) / 0.6);\\n font-size: 0.7rem;\\n font-weight: 600;\\n text-transform: uppercase;\\n letter-spacing: 0.04em;\\n color: hsl(var(--ra-muted-text));\\n border: 0;\\n cursor: pointer;\\n transition: background .12s ease;\\n}\\n.ra-shell .ra-group-summary:hover {\\n background: hsl(var(--ra-muted));\\n}\\n.ra-shell .ra-group-summary .ra-group-chevron {\\n transition: transform .15s ease;\\n}\\n.ra-shell .ra-group[data-open=false] .ra-group-chevron {\\n transform: rotate(-90deg);\\n}\\n.ra-shell .ra-group-name {\\n flex: 1;\\n text-align: left;\\n}\\n.ra-shell .ra-group-count {\\n font-size: 0.65rem;\\n font-weight: 600;\\n color: hsl(var(--ra-muted-text));\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: 999px;\\n padding: 0.05rem 0.4rem;\\n}\\n.ra-shell .ra-group[data-open=false] .ra-group-body {\\n display: none;\\n}\\n.ra-shell .ra-empty {\\n display: flex;\\n flex-direction: column;\\n align-items: center;\\n justify-content: center;\\n text-align: center;\\n padding: 2.5rem 1.5rem;\\n gap: 0.75rem;\\n}\\n.ra-shell .ra-empty-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 3.25rem;\\n height: 3.25rem;\\n border-radius: 999px;\\n background: hsl(var(--ra-accent) / 0.08);\\n color: hsl(var(--ra-accent));\\n margin-bottom: 0.25rem;\\n}\\n.ra-shell .ra-empty-title {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n font-size: 1rem;\\n color: hsl(var(--ra-text));\\n margin: 0;\\n letter-spacing: -0.01em;\\n}\\n.ra-shell .ra-empty-body {\\n font-size: 0.8125rem;\\n color: hsl(var(--ra-muted-text));\\n max-width: 22rem;\\n line-height: 1.45;\\n}\\n.ra-shell .ra-empty-actions {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n margin-top: 0.25rem;\\n flex-wrap: wrap;\\n justify-content: center;\\n}\\n.ra-shell .ra-btn {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n padding: 0.45rem 0.85rem;\\n border-radius: calc(var(--ra-radius) * 0.7);\\n font-size: 0.8125rem;\\n font-weight: 500;\\n border: 1px solid hsl(var(--ra-border));\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-text));\\n cursor: pointer;\\n transition:\\n background .15s ease,\\n border-color .15s ease,\\n box-shadow .15s ease,\\n transform .1s ease;\\n}\\n.ra-shell .ra-btn:hover {\\n background: hsl(var(--ra-muted));\\n box-shadow: var(--ra-card-shadow);\\n}\\n.ra-shell .ra-btn:active {\\n transform: translateY(1px);\\n}\\n.ra-shell .ra-btn[data-variant=primary] {\\n background: hsl(var(--ra-accent));\\n color: hsl(var(--ra-surface));\\n border-color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-btn[data-variant=primary]:hover {\\n background: hsl(var(--ra-accent) / 0.92);\\n}\\n.ra-shell .ra-btn[data-variant=ghost] {\\n background: transparent;\\n border-color: transparent;\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-shell .ra-btn[data-variant=ghost]:hover {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-btn[data-variant=danger] {\\n color: hsl(var(--ra-danger));\\n}\\n.ra-shell .ra-btn[data-variant=danger]:hover {\\n background: hsl(var(--ra-danger) / 0.10);\\n border-color: hsl(var(--ra-danger) / 0.40);\\n}\\n.ra-shell .ra-intro {\\n position: relative;\\n display: flex;\\n gap: 0.85rem;\\n padding: 0.9rem 1rem;\\n border-radius: var(--ra-radius);\\n border: 1px solid hsl(var(--ra-info) / 0.30);\\n background: hsl(var(--ra-info) / 0.08);\\n margin-bottom: 1rem;\\n}\\n.ra-shell .ra-intro[data-tone=success] {\\n border-color: hsl(var(--ra-success) / 0.30);\\n background: hsl(var(--ra-success) / 0.08);\\n}\\n.ra-shell .ra-intro[data-tone=warning] {\\n border-color: hsl(var(--ra-warning) / 0.35);\\n background: hsl(var(--ra-warning) / 0.10);\\n}\\n.ra-shell .ra-intro-icon {\\n flex-shrink: 0;\\n width: 2rem;\\n height: 2rem;\\n border-radius: 999px;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n background: hsl(var(--ra-info) / 0.18);\\n color: hsl(var(--ra-info));\\n}\\n.ra-shell .ra-intro[data-tone=success] .ra-intro-icon {\\n background: hsl(var(--ra-success) / 0.18);\\n color: hsl(var(--ra-success));\\n}\\n.ra-shell .ra-intro[data-tone=warning] .ra-intro-icon {\\n background: hsl(var(--ra-warning) / 0.20);\\n color: hsl(var(--ra-warning));\\n}\\n.ra-shell .ra-intro-body {\\n flex: 1;\\n min-width: 0;\\n}\\n.ra-shell .ra-intro-title {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-title-weight);\\n font-size: 0.875rem;\\n color: hsl(var(--ra-text));\\n margin: 0 0 0.2rem 0;\\n}\\n.ra-shell .ra-intro-text {\\n font-size: 0.8125rem;\\n color: hsl(var(--ra-text) / 0.85);\\n line-height: 1.45;\\n}\\n.ra-shell .ra-intro-dismiss {\\n position: absolute;\\n top: 0.5rem;\\n right: 0.5rem;\\n width: 1.6rem;\\n height: 1.6rem;\\n border-radius: 999px;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n background: transparent;\\n border: 0;\\n color: hsl(var(--ra-muted-text));\\n cursor: pointer;\\n}\\n.ra-shell .ra-intro-dismiss:hover {\\n background: hsl(var(--ra-text) / 0.06);\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-bulk-menu {\\n min-width: 12rem;\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: calc(var(--ra-radius) * 0.85);\\n box-shadow: var(--ra-card-shadow-hover);\\n padding: 0.3rem;\\n z-index: 60;\\n}\\n.ra-shell .ra-bulk-item {\\n display: flex;\\n align-items: center;\\n gap: 0.55rem;\\n width: 100%;\\n padding: 0.45rem 0.6rem;\\n border-radius: calc(var(--ra-radius) * 0.6);\\n font-size: 0.8125rem;\\n color: hsl(var(--ra-text));\\n background: transparent;\\n border: 0;\\n cursor: pointer;\\n text-align: left;\\n transition: background .12s ease, color .12s ease;\\n}\\n.ra-shell .ra-bulk-item:hover {\\n background: hsl(var(--ra-muted));\\n}\\n.ra-shell .ra-bulk-item[data-tone=danger] {\\n color: hsl(var(--ra-danger));\\n}\\n.ra-shell .ra-bulk-item[data-tone=danger]:hover {\\n background: hsl(var(--ra-danger) / 0.10);\\n}\\n.ra-shell .ra-bulk-divider {\\n height: 1px;\\n background: hsl(var(--ra-border));\\n margin: 0.25rem 0;\\n}\\n.ra-shell .ra-preview-rail {\\n background: hsl(var(--ra-surface));\\n border-left: 1px solid hsl(var(--ra-border));\\n box-shadow: -4px 0 16px hsl(var(--ra-accent) / 0.04);\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n overflow: hidden;\\n}\\n.ra-shell .ra-preview-rail-header {\\n position: sticky;\\n top: 0;\\n z-index: 1;\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n padding: 0.75rem 1rem;\\n background:\\n linear-gradient(\\n 180deg,\\n hsl(var(--ra-surface)) 0%,\\n hsl(var(--ra-surface) / 0.92) 100%);\\n border-bottom: 1px solid hsl(var(--ra-border));\\n backdrop-filter: blur(6px);\\n}\\n.ra-shell .ra-preview-rail-title {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n font-size: 0.7rem;\\n font-weight: 600;\\n text-transform: uppercase;\\n letter-spacing: 0.06em;\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-shell .ra-preview-rail-body {\\n flex: 1;\\n overflow-y: auto;\\n padding: 1rem;\\n}\\n.ra-confirm-root {\\n position: fixed;\\n inset: 0;\\n z-index: 2147483000;\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 1rem;\\n}\\n.ra-confirm-root .ra-confirm-backdrop {\\n position: absolute;\\n inset: 0;\\n background: hsl(0 0% 0% / 0.45);\\n backdrop-filter: blur(2px);\\n animation: ra-confirm-fade .12s ease-out;\\n}\\n.ra-confirm-root .ra-confirm-card {\\n position: relative;\\n width: min(440px, 100%);\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-text));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: var(--ra-radius);\\n box-shadow: 0 1px 2px hsl(0 0% 0% / 0.08), 0 24px 48px -12px hsl(0 0% 0% / 0.32);\\n padding: 1.25rem;\\n animation: ra-confirm-pop .14s ease-out;\\n}\\n.ra-confirm-root .ra-confirm-header {\\n display: flex;\\n align-items: center;\\n gap: 0.6rem;\\n margin-bottom: 0.5rem;\\n}\\n.ra-confirm-root .ra-confirm-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.75rem;\\n height: 1.75rem;\\n border-radius: 999px;\\n background: hsl(var(--ra-warning, 38 92% 50%) / 0.12);\\n color: hsl(var(--ra-warning, 38 92% 50%));\\n}\\n.ra-confirm-root .ra-confirm-title {\\n font-family: var(--ra-font-display);\\n font-weight: 600;\\n font-size: 1rem;\\n margin: 0;\\n}\\n.ra-confirm-root .ra-confirm-body {\\n font-size: 0.875rem;\\n color: hsl(var(--ra-muted-text));\\n margin: 0 0 1.1rem;\\n line-height: 1.45;\\n}\\n.ra-confirm-root .ra-confirm-actions {\\n display: flex;\\n justify-content: flex-end;\\n gap: 0.5rem;\\n flex-wrap: wrap;\\n}\\n.ra-confirm-root .ra-confirm-btn {\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n appearance: none;\\n border: 1px solid transparent;\\n border-radius: calc(var(--ra-radius) - 2px);\\n padding: 0.45rem 0.85rem;\\n font-size: 0.8125rem;\\n font-weight: 500;\\n cursor: pointer;\\n transition:\\n background-color .12s ease,\\n border-color .12s ease,\\n color .12s ease;\\n}\\n.ra-confirm-root .ra-confirm-btn:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\\n}\\n.ra-confirm-root .ra-confirm-btn-ghost {\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n border-color: hsl(var(--ra-border));\\n}\\n.ra-confirm-root .ra-confirm-btn-ghost:hover {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.ra-confirm-root .ra-confirm-btn-danger {\\n background: transparent;\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n border-color: hsl(var(--ra-danger, 0 72% 51%) / 0.45);\\n}\\n.ra-confirm-root .ra-confirm-btn-danger:hover {\\n background: hsl(var(--ra-danger, 0 72% 51%) / 0.08);\\n border-color: hsl(var(--ra-danger, 0 72% 51%));\\n}\\n.ra-confirm-root .ra-confirm-btn-primary {\\n background: hsl(var(--ra-accent));\\n color: hsl(var(--ra-accent-fg, 0 0% 100%));\\n border-color: hsl(var(--ra-accent));\\n}\\n.ra-confirm-root .ra-confirm-btn-primary:hover {\\n filter: brightness(0.95);\\n}\\n@keyframes ra-confirm-fade {\\n from {\\n opacity: 0;\\n }\\n to {\\n opacity: 1;\\n }\\n}\\n@keyframes ra-confirm-pop {\\n from {\\n opacity: 0;\\n transform: translateY(4px) scale(.98);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0) scale(1);\\n }\\n}\\n.ra-shell .ra-unsaved-banner {\\n display: flex;\\n align-items: center;\\n gap: 0.6rem;\\n padding: 0.5rem 0.75rem;\\n border: 1px solid hsl(var(--ra-warning, 38 92% 50%) / 0.35);\\n background: hsl(var(--ra-warning, 38 92% 50%) / 0.08);\\n border-radius: var(--ra-radius);\\n font-size: 0.8125rem;\\n color: hsl(var(--ra-text));\\n animation: ra-unsaved-slide .14s ease-out;\\n}\\n.ra-shell .ra-unsaved-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n color: hsl(var(--ra-warning, 38 92% 50%));\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-unsaved-text {\\n flex: 1;\\n min-width: 0;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n white-space: nowrap;\\n}\\n.ra-shell .ra-unsaved-context {\\n color: hsl(var(--ra-muted-text));\\n font-weight: 400;\\n}\\n.ra-shell .ra-unsaved-error {\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n font-size: 0.75rem;\\n text-transform: uppercase;\\n letter-spacing: 0.04em;\\n font-weight: 500;\\n}\\n.ra-shell .ra-unsaved-actions {\\n display: inline-flex;\\n gap: 0.4rem;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-unsaved-btn {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.3rem;\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n appearance: none;\\n border: 1px solid transparent;\\n border-radius: calc(var(--ra-radius) - 2px);\\n padding: 0.3rem 0.6rem;\\n font-size: 0.75rem;\\n font-weight: 500;\\n cursor: pointer;\\n transition:\\n background-color .12s ease,\\n border-color .12s ease,\\n color .12s ease,\\n opacity .12s ease;\\n}\\n.ra-shell .ra-unsaved-btn:disabled {\\n opacity: 0.5;\\n cursor: not-allowed;\\n}\\n.ra-shell .ra-unsaved-btn:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\\n}\\n.ra-shell .ra-unsaved-btn-ghost {\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n border-color: hsl(var(--ra-border));\\n}\\n.ra-shell .ra-unsaved-btn-ghost:hover:not(:disabled) {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-unsaved-btn-primary {\\n background: hsl(var(--ra-accent));\\n color: hsl(var(--ra-accent-fg, 0 0% 100%));\\n border-color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-unsaved-btn-primary:hover:not(:disabled) {\\n filter: brightness(0.95);\\n}\\n@keyframes ra-unsaved-slide {\\n from {\\n opacity: 0;\\n transform: translateY(-3px);\\n }\\n to {\\n opacity: 1;\\n transform: translateY(0);\\n }\\n}\\n\")","import { useEffect, useMemo, useState, useCallback, isValidElement, createElement, type ReactNode } from 'react';\r\nimport { Plus, Search } from 'lucide-react';\r\nimport { mergeIcons, pickHeaderIcon } from './icons';\r\nimport type {\r\n RecordsAdminShellProps, RecordStatus, RecordSummary,\r\n ScopeKind, RecordsAdminI18n, ParsedRef, RecordPresentation,\r\n} from '../types';\r\nimport { DEFAULT_I18N } from '../types';\r\nimport { parseRef, buildRef } from '../data/refs';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport { useRecordList } from '../hooks/useRecordList';\r\nimport { useRecordEditor } from '../hooks/useRecordEditor';\r\nimport { useResolvedRecord } from '../hooks/useResolvedRecord';\r\nimport { useIntroDismissed } from '../hooks/useIntroDismissed';\r\nimport { useScopeProbe } from '../hooks/useScopeProbe';\r\nimport { useFacetBrowse } from '../hooks/useFacetBrowse';\r\nimport { useProductBrowse, type ProductBrowseItem } from '../hooks/useProductBrowse';\r\nimport { useProductChildren } from '../hooks/useProductChildren';\r\nimport { useUnsavedGuard } from '../hooks/useUnsavedGuard';\r\nimport { useDirtyNavigation } from '../hooks/useDirtyNavigation';\r\nimport { useConfirmDialog } from '../hooks/useConfirmDialog';\r\nimport { ScopeTabs } from '../browser/ScopeTabs';\r\nimport { StatusFilterPills } from '../browser/StatusFilterPills';\r\nimport { RecordList } from '../browser/RecordList';\r\nimport { EmptyState, ErrorState, LoadingState } from '../browser/EmptyStates';\r\nimport { PresentationSwitcher } from '../browser/PresentationSwitcher';\r\nimport { usePresentationPref } from '../hooks/usePresentationPref';\r\nimport { RecordEditor } from '../editor/RecordEditor';\r\nimport { ProductDrillDown, type DrillTab } from '../editor/ProductDrillDown';\r\nimport {\r\n InlinePreview, SidePreview, TabbedPreview, DrawerPreview, PreviewToggleButton,\r\n} from '../editor/PreviewPane';\r\nimport { PreviewScopePicker } from '../editor/PreviewScopePicker';\r\nimport { IntroCard } from './IntroCard';\r\nimport { UtilityRow } from './UtilityRow';\r\nimport { ShellHeader } from './ShellHeader';\r\nimport { UnsavedBanner } from './UnsavedBanner';\r\nimport { exportCsv, importCsv, downloadBlob } from '../data/csv';\r\nimport './tokens.css';\r\nimport './shell.css';\r\n\r\n/** Top-level scopes are limited to facet / product — variants and batches\r\n * are drill-downs under a selected product (see `ProductDrillDown`).\r\n *\r\n * Order matters: this drives the order tabs render in AND the default tab\r\n * when the host doesn't pass `defaultScope`. We put `facet` (Shared labels)\r\n * first because at the collection level admins are far more likely to be\r\n * setting shared values across many products than editing a single product. */\r\nconst TOP_LEVEL_SCOPES: ScopeKind[] = ['facet', 'product'];\r\n\r\n/** ULID-ish item id — short, sortable, no external deps. */\r\nconst defaultItemId = (): string => {\r\n const time = Date.now().toString(36);\r\n const rand = Math.random().toString(36).slice(2, 8);\r\n return `${time}${rand}`;\r\n};\r\n\r\nconst productItemToSummary = (p: ProductBrowseItem): RecordSummary => {\r\n const ref = buildRef({ productId: p.id });\r\n return {\r\n id: null,\r\n ref,\r\n scope: parseRef(ref),\r\n data: null,\r\n status: 'empty',\r\n label: p.name,\r\n subtitle: p.sku ?? undefined,\r\n };\r\n};\r\n\r\nexport function RecordsAdminShell<TData = unknown>(props: RecordsAdminShellProps<TData>) {\r\n const {\r\n SL, appId, collectionId, recordType, label,\r\n scopes: requestedScopes, defaultScope, contextScope,\r\n renderEditor, renderPreview, intro, csvSchema,\r\n classify, defaultData, i18n: i18nOverride, onTelemetry, className,\r\n previewMode = 'inline',\r\n previewScopePicker = false,\r\n // Default to `keep` — admins can tab around freely while edits are\r\n // preserved per editor mount, and the inline UnsavedBanner surfaces the\r\n // dirty state at the top of the shell with Save/Discard buttons. Hosts\r\n // that want the old blocking behaviour can opt back into `'prompt'`.\r\n dirtyStrategy = 'keep',\r\n onBeforeDelete,\r\n disableBeforeUnload = false,\r\n presentations = ['list'],\r\n defaultPresentation,\r\n renderCard,\r\n renderListRow,\r\n renderEmpty,\r\n cardinality = 'singleton',\r\n itemNoun = 'item',\r\n generateItemId,\r\n title, subtitle, headerIcon, headerActions,\r\n showStats = false, showHeaderIcon = true, statsItems,\r\n statsTitle, statsIcon,\r\n showHeader,\r\n icons: iconsOverride,\r\n groupBy,\r\n renderEmptyState,\r\n density = 'comfortable',\r\n } = props;\r\n\r\n const i18n: RecordsAdminI18n = { ...DEFAULT_I18N, ...(i18nOverride ?? {}) };\r\n const icons = useMemo(() => mergeIcons(iconsOverride), [iconsOverride]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Presentation — persisted per app/recordType.\r\n // ---------------------------------------------------------------------------\r\n const [presentation, setPresentation] = usePresentationPref({\r\n appId, recordType,\r\n options: presentations,\r\n defaultValue: defaultPresentation ?? presentations[0] ?? 'list',\r\n });\r\n\r\n const onPresentationChange = useCallback((next: RecordPresentation) => {\r\n onTelemetry?.({ type: 'presentation.change', recordType, from: presentation, to: next });\r\n setPresentation(next);\r\n }, [onTelemetry, recordType, presentation, setPresentation]);\r\n\r\n const ctx: RecordsCtx = useMemo(\r\n () => ({ SL, collectionId, appId, recordType }),\r\n [SL, collectionId, appId, recordType],\r\n );\r\n\r\n // ---------------------------------------------------------------------------\r\n // Scope discovery — `variants` / `batches` flags off the Collection control\r\n // whether the drill-down sub-tabs render at all.\r\n // ---------------------------------------------------------------------------\r\n const probe = useScopeProbe({ SL, collectionId });\r\n\r\n // Top-level tabs: only facet / product (intersect with what the host\r\n // requested). We render in the canonical TOP_LEVEL_SCOPES order — facet\r\n // first — regardless of the order the host listed scopes in.\r\n const topLevelScopes = useMemo(\r\n () => TOP_LEVEL_SCOPES.filter((s) => requestedScopes.includes(s)),\r\n [requestedScopes],\r\n );\r\n\r\n // Are variants/batches available *for drill-down* under a product?\r\n const drillVariantsAllowed = useMemo(\r\n () => requestedScopes.includes('variant') && (probe.isLoading || probe.hasVariants),\r\n [requestedScopes, probe.isLoading, probe.hasVariants],\r\n );\r\n const drillBatchesAllowed = useMemo(\r\n () => requestedScopes.includes('batch') && (probe.isLoading || probe.hasBatches),\r\n [requestedScopes, probe.isLoading, probe.hasBatches],\r\n );\r\n\r\n // ---------------------------------------------------------------------------\r\n // Initial scope/selection from URL context.\r\n // - Any of productId/variantId/batchId pinned → start on `product` tab,\r\n // that product auto-selected, and drill into variant/batch if specified.\r\n // - Otherwise, prefer requested defaultScope or first top-level scope.\r\n // ---------------------------------------------------------------------------\r\n const initialScope: ScopeKind = useMemo(() => {\r\n if (contextScope?.productId && topLevelScopes.includes('product')) return 'product';\r\n if (defaultScope && topLevelScopes.includes(defaultScope)) return defaultScope;\r\n // Prefer facet (Shared labels) when available — it's the more common\r\n // entry point at the collection level. Otherwise fall through to whatever\r\n // the host requested.\r\n if (topLevelScopes.includes('facet')) return 'facet';\r\n return topLevelScopes[0] ?? 'product';\r\n }, [contextScope?.productId, defaultScope, topLevelScopes]);\r\n\r\n const [activeScope, setActiveScope] = useState<ScopeKind>(initialScope);\r\n useEffect(() => { setActiveScope(initialScope); }, [initialScope]);\r\n\r\n // List query state (search/filter applies per top-level tab).\r\n const [search, setSearch] = useState('');\r\n const [filter, setFilter] = useState<'all' | RecordStatus>('all');\r\n\r\n // Selected ref for the FACET tab (records-driven list).\r\n const [selectedFacetRef, setSelectedFacetRef] = useState<string | undefined>();\r\n\r\n // Selected product (drives the right pane) + drill-down state.\r\n const [selectedProductId, setSelectedProductId] = useState<string | undefined>(\r\n contextScope?.productId,\r\n );\r\n const [drillTab, setDrillTab] = useState<DrillTab>(\r\n contextScope?.batchId ? 'batch' : contextScope?.variantId ? 'variant' : 'product',\r\n );\r\n const [selectedVariantId, setSelectedVariantId] = useState<string | undefined>(\r\n contextScope?.variantId,\r\n );\r\n const [selectedBatchId, setSelectedBatchId] = useState<string | undefined>(\r\n contextScope?.batchId,\r\n );\r\n\r\n // Re-sync from URL changes in the host.\r\n useEffect(() => {\r\n if (contextScope?.productId) setSelectedProductId(contextScope.productId);\r\n }, [contextScope?.productId]);\r\n useEffect(() => {\r\n if (contextScope?.variantId) {\r\n setSelectedVariantId(contextScope.variantId);\r\n setDrillTab('variant');\r\n }\r\n }, [contextScope?.variantId]);\r\n useEffect(() => {\r\n if (contextScope?.batchId) {\r\n setSelectedBatchId(contextScope.batchId);\r\n setDrillTab('batch');\r\n }\r\n }, [contextScope?.batchId]);\r\n\r\n const { dismissed, dismiss, undismiss } = useIntroDismissed(SL, collectionId, appId, recordType);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Data sources — switch by active top-level scope.\r\n // ---------------------------------------------------------------------------\r\n const productBrowse = useProductBrowse({\r\n SL, collectionId,\r\n search: activeScope === 'product' ? search : '',\r\n enabled: activeScope === 'product' && !contextScope?.productId,\r\n });\r\n\r\n // Records-driven list (used for facet tab today; could power custom scopes later).\r\n const recordList = useRecordList({\r\n ctx, scopeKind: activeScope, search, filter,\r\n classify: classify as ((r: RecordSummary) => RecordStatus) | undefined,\r\n contextScope,\r\n enabled: activeScope === 'facet' && !probe.isLoading,\r\n });\r\n\r\n const facetBrowse = useFacetBrowse({\r\n SL,\r\n collectionId,\r\n existing: recordList.allItems,\r\n search,\r\n filter,\r\n enabled: activeScope === 'facet' && !probe.isLoading,\r\n });\r\n\r\n // Lazy children for the selected product (only fires when drilled in).\r\n const variantChildren = useProductChildren({\r\n SL, collectionId, productId: selectedProductId,\r\n kind: drillTab === 'variant' ? 'variant' : null,\r\n });\r\n const batchChildren = useProductChildren({\r\n SL, collectionId, productId: selectedProductId,\r\n kind: drillTab === 'batch' ? 'batch' : null,\r\n });\r\n\r\n // ---------------------------------------------------------------------------\r\n // Auto-select on first load.\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (activeScope !== 'product') return;\r\n if (selectedProductId) return;\r\n const first = productBrowse.items[0];\r\n if (first) setSelectedProductId(first.id);\r\n }, [activeScope, selectedProductId, productBrowse.items]);\r\n\r\n useEffect(() => {\r\n if (activeScope !== 'facet') return;\r\n if (selectedFacetRef) return;\r\n const first = facetBrowse.items[0];\r\n if (first) setSelectedFacetRef(first.ref);\r\n }, [activeScope, selectedFacetRef, facetBrowse.items]);\r\n\r\n // Reset selection bits when the active top-level scope changes.\r\n useEffect(() => {\r\n setSearch('');\r\n setFilter('all');\r\n }, [activeScope]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Build the parsed scope for whatever's currently being edited.\r\n // ---------------------------------------------------------------------------\r\n const editingScope: ParsedRef | null = useMemo(() => {\r\n if (activeScope === 'facet') {\r\n return selectedFacetRef ? parseRef(selectedFacetRef) : null;\r\n }\r\n // Product tab — the editor follows the drill-down state.\r\n if (!selectedProductId) return null;\r\n if (drillTab === 'variant') {\r\n if (!selectedVariantId) return null;\r\n return parseRef(buildRef({ productId: selectedProductId, variantId: selectedVariantId }));\r\n }\r\n if (drillTab === 'batch') {\r\n if (!selectedBatchId) return null;\r\n return parseRef(buildRef({ productId: selectedProductId, batchId: selectedBatchId }));\r\n }\r\n return parseRef(buildRef({ productId: selectedProductId }));\r\n }, [activeScope, selectedFacetRef, selectedProductId, drillTab, selectedVariantId, selectedBatchId]);\r\n\r\n // Scope chain for the resolver (always pass all four when supported).\r\n const supportedForResolution = useMemo(() => requestedScopes, [requestedScopes]);\r\n\r\n const resolved = useResolvedRecord<TData>({\r\n SL, appId, recordType, collectionId,\r\n productId: editingScope?.productId,\r\n variantId: editingScope?.variantId,\r\n batchId: editingScope?.batchId,\r\n facetId: editingScope?.facetId,\r\n facetValue: editingScope?.facetValue,\r\n supportedScopes: supportedForResolution,\r\n enabled: !!editingScope,\r\n });\r\n\r\n const refetchAll = useCallback(() => {\r\n productBrowse.refetch();\r\n recordList.refetch();\r\n facetBrowse.refetch();\r\n variantChildren.refetch();\r\n batchChildren.refetch();\r\n }, [productBrowse, recordList, facetBrowse, variantChildren, batchChildren]);\r\n\r\n const editorCtx = useRecordEditor<TData>({\r\n ctx,\r\n scope: editingScope ?? parseRef(''),\r\n resolved: { data: resolved.data, source: resolved.source, sourceRef: resolved.sourceRef, parentValue: resolved.parentValue },\r\n defaultData,\r\n reseed: dirtyStrategy === 'keep' ? 'preserve-dirty' : 'always',\r\n onSaved: () => {\r\n onTelemetry?.({ type: 'record.save', recordType, ref: editingScope?.raw ?? '', isCreate: resolved.source !== 'self' });\r\n refetchAll();\r\n },\r\n onDeleted: () => {\r\n onTelemetry?.({ type: 'record.delete', recordType, ref: editingScope?.raw ?? '' });\r\n // Clear selection on the appropriate axis so the now-deleted record\r\n // doesn't appear \"still selected\" while the list refreshes.\r\n if (activeScope === 'facet') {\r\n setSelectedFacetRef(undefined);\r\n } else if (drillTab === 'variant') {\r\n setSelectedVariantId(undefined);\r\n } else if (drillTab === 'batch') {\r\n setSelectedBatchId(undefined);\r\n }\r\n refetchAll();\r\n },\r\n });\r\n\r\n // ---------------------------------------------------------------------------\r\n // Unsaved guards — browser beforeunload + iframe parent message + nav guard\r\n // ---------------------------------------------------------------------------\r\n useUnsavedGuard({\r\n isDirty: editorCtx.isDirty,\r\n label: recordType,\r\n disableBeforeUnload,\r\n // In `keep` mode we don't want the host iframe to pop its own native\r\n // confirm — the banner is the canonical surface. Hosts on `prompt` /\r\n // `autosave` opt back into platform notifications.\r\n disableParentMessage: dirtyStrategy === 'keep',\r\n });\r\n\r\n // Themed confirm dialog used for in-app navigation away from a dirty editor.\r\n // Replaces window.confirm() so we don't get the host iframe's \"An embedded\r\n // page at … says\" framing and so the popup matches the shell chrome.\r\n const dirtyConfirm = useConfirmDialog();\r\n\r\n const { runWithGuard } = useDirtyNavigation({\r\n strategy: dirtyStrategy,\r\n isDirty: editorCtx.isDirty,\r\n save: editorCtx.save,\r\n reset: editorCtx.reset,\r\n confirm: dirtyConfirm.confirm,\r\n i18n: {\r\n title: i18n.unsavedPromptTitle,\r\n body: i18n.unsavedPromptBody,\r\n save: i18n.unsavedPromptSave,\r\n discard: i18n.unsavedPromptDiscard,\r\n cancel: i18n.unsavedPromptCancel,\r\n },\r\n });\r\n\r\n // ---------------------------------------------------------------------------\r\n // CSV import/export — only meaningful for the records list (facet tab today).\r\n // ---------------------------------------------------------------------------\r\n const handleExport = () => {\r\n if (!csvSchema) return;\r\n const fileBase = recordType ?? (label.toLowerCase().replace(/\\s+/g, '-') || 'records');\r\n const blob = exportCsv(recordList.items as RecordSummary<TData>[], csvSchema);\r\n downloadBlob(blob, `${fileBase}.csv`);\r\n onTelemetry?.({ type: 'csv.export', recordType, rows: recordList.items.length });\r\n };\r\n const handleImport = () => {\r\n if (!csvSchema) return;\r\n const inp = document.createElement('input');\r\n inp.type = 'file';\r\n inp.accept = '.csv,text/csv';\r\n inp.onchange = async () => {\r\n const file = inp.files?.[0];\r\n if (!file) return;\r\n const report = await importCsv(file, csvSchema, ctx);\r\n onTelemetry?.({ type: 'csv.import', recordType, rows: report.total, errors: report.failed });\r\n if (report.failed > 0) {\r\n const fileBase = recordType ?? (label.toLowerCase().replace(/\\s+/g, '-') || 'records');\r\n downloadBlob(new Blob([report.annotatedCsv], { type: 'text/csv' }), `${fileBase}-errors.csv`);\r\n }\r\n refetchAll();\r\n };\r\n inp.click();\r\n };\r\n const csvBulk = csvSchema ? { onImportCsv: handleImport, onExportCsv: handleExport } : {};\r\n\r\n // ---------------------------------------------------------------------------\r\n // Preview state — independent scope (when picker enabled) + drawer toggle.\r\n // ---------------------------------------------------------------------------\r\n const [previewScope, setPreviewScope] = useState<ParsedRef | null>(null);\r\n const [drawerOpen, setDrawerOpen] = useState(false);\r\n // Side preview can be collapsed by the admin (e.g. on narrower screens).\r\n // Persisted only in component state; the next mount starts open again\r\n // because `previewMode='side'` is opt-in by the host.\r\n const [sidePreviewOpen, setSidePreviewOpen] = useState(true);\r\n\r\n // Whenever the editing scope changes, reset the preview scope to follow it\r\n // (unless the user explicitly picked a different one).\r\n useEffect(() => {\r\n if (!editingScope) return;\r\n setPreviewScope((cur) => (cur === null ? editingScope : cur));\r\n }, [editingScope]);\r\n\r\n const effectivePreviewScope: ParsedRef | null = previewScope ?? editingScope;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Friendly editor header label — pulled from the currently-selected summary\r\n // (facet value name, product display name) instead of raw scope keys. We\r\n // look up by ref so this works for both auto-selected and user-selected\r\n // entries. Falls back to whatever ScopeBreadcrumb would show when no match.\r\n // ---------------------------------------------------------------------------\r\n const editorHeaderLabel: string | undefined = useMemo(() => {\r\n if (!editingScope) return undefined;\r\n if (activeScope === 'facet' && selectedFacetRef) {\r\n const hit = facetBrowse.items.find((it) => it.ref === selectedFacetRef);\r\n return hit?.label;\r\n }\r\n if (activeScope === 'product' && selectedProductId) {\r\n const hit = productBrowse.items.find((it) => it.id === selectedProductId);\r\n // Fall back to the productId so we never render the raw scope\r\n // breadcrumb (which prefixes \"Product: …\" — too technical for admins).\r\n return hit?.name ?? selectedProductId;\r\n }\r\n return undefined;\r\n }, [activeScope, editingScope, selectedFacetRef, selectedProductId, facetBrowse.items, productBrowse.items]);\r\n\r\n const editorHeaderSubtitle: string | undefined = useMemo(() => {\r\n if (!editingScope) return undefined;\r\n if (activeScope === 'facet' && selectedFacetRef) {\r\n const hit = facetBrowse.items.find((it) => it.ref === selectedFacetRef);\r\n return hit?.subtitle;\r\n }\r\n // For product scope we deliberately omit the subtitle — the SKU / id is\r\n // surfaced via `headerMeta` (subtle top-right caption) instead so it\r\n // doesn't compete with the friendly product name.\r\n return undefined;\r\n }, [activeScope, editingScope, selectedFacetRef, selectedProductId, facetBrowse.items, productBrowse.items]);\r\n\r\n // Technical reference shown as a tiny muted caption in the editor header's\r\n // top-right corner. Power users (and support / debugging) can scan it\r\n // without it becoming a visual subtitle. SKU is preferred over productId\r\n // when both exist.\r\n const editorHeaderMeta: string | undefined = useMemo(() => {\r\n if (!editingScope) return undefined;\r\n if (activeScope === 'product' && selectedProductId) {\r\n const hit = productBrowse.items.find((it) => it.id === selectedProductId);\r\n return hit?.sku ?? selectedProductId;\r\n }\r\n return undefined;\r\n }, [activeScope, editingScope, selectedProductId, productBrowse.items]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Build the editor + preview pair according to `previewMode`. Both call\r\n // sites (product drill-down + facet tab) render through this helper so the\r\n // chrome stays consistent.\r\n // ---------------------------------------------------------------------------\r\n const renderEditorWithPreview = (): ReactNode => {\r\n if (!editingScope) return null;\r\n\r\n const previewBody: ReactNode = renderPreview && effectivePreviewScope\r\n ? renderPreview({ resolved: editorCtx.value, previewScope: effectivePreviewScope })\r\n : null;\r\n\r\n const scopePicker = previewScopePicker && effectivePreviewScope ? (\r\n <PreviewScopePicker\r\n SL={SL}\r\n collectionId={collectionId}\r\n editingScope={editingScope}\r\n value={effectivePreviewScope}\r\n onChange={setPreviewScope}\r\n showVariants={drillVariantsAllowed}\r\n showBatches={drillBatchesAllowed}\r\n i18n={{ previewAs: i18n.previewAs, previewAsDefault: i18n.previewAsDefault }}\r\n />\r\n ) : null;\r\n\r\n const baseEditor = (extraFooter?: ReactNode, inlinePreviewBody?: ReactNode) => (\r\n <RecordEditor\r\n ctx={editorCtx}\r\n i18n={i18n}\r\n bulkActions={{ ...csvBulk, i18n }}\r\n preview={inlinePreviewBody}\r\n footerExtra={extraFooter}\r\n onBeforeDelete={onBeforeDelete && editingScope\r\n ? () => onBeforeDelete(editingScope)\r\n : undefined}\r\n headerLabel={editorHeaderLabel}\r\n headerSubtitle={editorHeaderSubtitle}\r\n headerMeta={editorHeaderMeta}\r\n >\r\n {renderEditor(editorCtx)}\r\n </RecordEditor>\r\n );\r\n\r\n // No preview supplied → just the editor.\r\n if (!previewBody) return baseEditor();\r\n\r\n if (previewMode === 'inline') {\r\n return baseEditor(undefined,\r\n <InlinePreview label={i18n.preview} scopePicker={scopePicker}>{previewBody}</InlinePreview>,\r\n );\r\n }\r\n\r\n if (previewMode === 'side') {\r\n if (!sidePreviewOpen) {\r\n return (\r\n <div className=\"relative h-full\">\r\n {baseEditor(\r\n <PreviewToggleButton\r\n onClick={() => setSidePreviewOpen(true)}\r\n label={i18n.openPreview}\r\n />,\r\n )}\r\n </div>\r\n );\r\n }\r\n return (\r\n <div className=\"grid h-full\" style={{ gridTemplateColumns: 'minmax(0, 1fr) minmax(280px, 420px)' }}>\r\n <div className=\"overflow-hidden\">{baseEditor()}</div>\r\n <SidePreview\r\n label={i18n.preview}\r\n scopePicker={scopePicker}\r\n onClose={() => setSidePreviewOpen(false)}\r\n >\r\n {previewBody}\r\n </SidePreview>\r\n </div>\r\n );\r\n }\r\n\r\n if (previewMode === 'tab') {\r\n return (\r\n <TabbedPreview\r\n editor={baseEditor()}\r\n preview={previewBody}\r\n scopePicker={scopePicker}\r\n i18n={{ editor: i18n.editor, preview: i18n.preview }}\r\n />\r\n );\r\n }\r\n\r\n // drawer\r\n return (\r\n <div className=\"relative h-full\">\r\n {baseEditor(\r\n <PreviewToggleButton onClick={() => setDrawerOpen(true)} label={i18n.openPreview} />,\r\n )}\r\n <DrawerPreview\r\n open={drawerOpen}\r\n onClose={() => setDrawerOpen(false)}\r\n label={i18n.preview}\r\n scopePicker={scopePicker}\r\n >\r\n {previewBody}\r\n </DrawerPreview>\r\n </div>\r\n );\r\n };\r\n\r\n // ---------------------------------------------------------------------------\r\n // Render — left rail (top-level browse) + right pane (editor or drill-down).\r\n // ---------------------------------------------------------------------------\r\n const isProductTab = activeScope === 'product';\r\n const productPinned = !!contextScope?.productId;\r\n\r\n // The facet tab is a flat list of facet *values* grouped by their facet\r\n // (e.g. BAGEL → white; BREAD TYPE → Bagel/Loaf/Slice). Cards/grids don't\r\n // add value here — those layouts are intended for record-as-content cases\r\n // (recipes, FAQs). Force `list` on this tab and hide the switcher.\r\n const effectivePresentation: RecordPresentation = isProductTab ? presentation : 'list';\r\n const showPresentationSwitcher = isProductTab && presentations.length > 1;\r\n\r\n // On the facet tab, default to grouping by facet key so the rail looks\r\n // like the screenshot the user shipped (BAGEL / BREAD TYPE / COOKING GUIDE\r\n // accordion sections). The host can still override by passing `groupBy`.\r\n const effectiveGroupBy = useMemo(() => {\r\n if (groupBy) return groupBy;\r\n if (isProductTab) return undefined;\r\n return (record: RecordSummary) => {\r\n const key = record.scope.facetId;\r\n if (!key) return null;\r\n const label = record.subtitle ?? key;\r\n return { key, label };\r\n };\r\n }, [groupBy, isProductTab]);\r\n\r\n // Items shown in the left rail under the products tab (browse-driven).\r\n const productListItems: RecordSummary[] = useMemo(() => {\r\n if (productPinned) {\r\n // Pinned mode: collapse the rail to just that product so the user has context.\r\n return [{\r\n id: null, ref: buildRef({ productId: contextScope!.productId! }),\r\n scope: parseRef(buildRef({ productId: contextScope!.productId! })),\r\n data: null, status: 'empty',\r\n label: contextScope!.productId!, subtitle: undefined,\r\n }];\r\n }\r\n return productBrowse.items.map(productItemToSummary);\r\n }, [productPinned, contextScope, productBrowse.items]);\r\n\r\n const leftItems = isProductTab ? productListItems : facetBrowse.items;\r\n const leftLoading = isProductTab\r\n ? (!productPinned && productBrowse.isLoading)\r\n : (facetBrowse.isLoading || recordList.isLoading || probe.isLoading);\r\n const leftError = isProductTab ? productBrowse.error : (facetBrowse.error ?? recordList.error);\r\n const leftSelectedRef = isProductTab\r\n ? (selectedProductId ? buildRef({ productId: selectedProductId }) : undefined)\r\n : selectedFacetRef;\r\n\r\n const onLeftSelect = (item: RecordSummary) => {\r\n void runWithGuard(() => {\r\n if (isProductTab) {\r\n setSelectedProductId(item.scope.productId);\r\n setSelectedVariantId(undefined);\r\n setSelectedBatchId(undefined);\r\n setDrillTab('product');\r\n } else {\r\n setSelectedFacetRef(item.ref);\r\n }\r\n });\r\n };\r\n\r\n return (\r\n <div\r\n className={`ra-shell flex flex-col h-full ${className ?? ''}`}\r\n data-density={density}\r\n >\r\n {dirtyConfirm.dialog}\r\n <div className=\"px-4 pt-4 space-y-3\">\r\n {intro && !dismissed && (\r\n <IntroCard\r\n title={intro.title}\r\n body={intro.body}\r\n onDismiss={() => { dismiss(); onTelemetry?.({ type: 'intro.dismiss', recordType }); }}\r\n />\r\n )}\r\n {(() => {\r\n // Auto-show the header card when the host customised it in any way,\r\n // even without explicitly setting `showHeader`. Off otherwise — most\r\n // apps don't need it and the internal record-type label is noise.\r\n const headerCustomised =\r\n !!title || !!subtitle || !!headerIcon || !!headerActions ||\r\n showStats || !!statsItems || !!statsTitle || !!statsIcon;\r\n const renderHeader = showHeader === true || (showHeader !== false && headerCustomised);\r\n if (!renderHeader) return null;\r\n return (\r\n <ShellHeader\r\n title={title ?? label ?? recordType ?? ''}\r\n subtitle={subtitle}\r\n headerIcon={headerIcon}\r\n headerActions={headerActions}\r\n showStats={showStats}\r\n showHeaderIcon={showHeaderIcon}\r\n recordType={recordType}\r\n icons={icons}\r\n stats={{\r\n products: productBrowse.items.length,\r\n shared: recordList.items.length,\r\n }}\r\n statsItems={statsItems}\r\n statsTitle={statsTitle}\r\n statsIcon={statsIcon}\r\n />\r\n );\r\n })()}\r\n <UtilityRow\r\n label={label}\r\n introHidden={dismissed && !!intro}\r\n onShowIntro={undismiss}\r\n />\r\n {editorCtx.isDirty && (\r\n <UnsavedBanner\r\n label={editorHeaderLabel}\r\n context={editorHeaderSubtitle}\r\n isSaving={!!editorCtx.isSaving}\r\n saveError={editorCtx.saveError}\r\n onSave={() => { void editorCtx.save().catch(() => { /* surfaced via saveError */ }); }}\r\n onDiscard={editorCtx.reset}\r\n saveLabel={i18n.save}\r\n discardLabel={i18n.discard}\r\n savingLabel={i18n.saving}\r\n errorLabel={i18n.saveError}\r\n bodyTemplate={i18n.unsavedBannerBody}\r\n />\r\n )}\r\n </div>\r\n <div\r\n className=\"flex-1 grid border-t overflow-hidden\"\r\n style={{ gridTemplateColumns: 'minmax(260px, 320px) 1fr', borderColor: 'hsl(var(--ra-border))', marginTop: '0.75rem' }}\r\n >\r\n <aside className=\"border-r overflow-hidden flex flex-col\" style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}>\r\n <div className=\"p-2\">\r\n <ScopeTabs\r\n scopes={topLevelScopes}\r\n active={activeScope}\r\n onChange={(s) => {\r\n void runWithGuard(() => {\r\n onTelemetry?.({ type: 'scope.change', recordType, from: activeScope, to: s });\r\n setActiveScope(s);\r\n });\r\n }}\r\n loading={probe.isLoading}\r\n counts={{\r\n product: productBrowse.items.length,\r\n facet: facetBrowse.items.length,\r\n }}\r\n icons={icons.scope}\r\n />\r\n </div>\r\n <div className=\"p-3 space-y-2.5 border-b\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n <div className=\"flex items-center gap-2\">\r\n <div className=\"relative flex-1 min-w-0\">\r\n <Search className=\"absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 opacity-50\" />\r\n <input\r\n type=\"text\"\r\n value={search}\r\n onChange={(e) => setSearch(e.target.value)}\r\n placeholder={i18n.searchPlaceholder}\r\n className=\"w-full pl-8 pr-3 py-1.5 text-xs rounded-md border bg-transparent focus:outline-none focus:ring-1\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n />\r\n </div>\r\n <PresentationSwitcher\r\n options={showPresentationSwitcher ? presentations : []}\r\n value={presentation}\r\n onChange={onPresentationChange}\r\n i18n={i18n}\r\n />\r\n </div>\r\n {!isProductTab && (\r\n <StatusFilterPills\r\n value={filter}\r\n onChange={setFilter}\r\n counts={facetBrowse.counts}\r\n hideZero={['partial']}\r\n i18n={i18n}\r\n />\r\n )}\r\n {cardinality === 'collection' && !isProductTab && editingScope && (\r\n <button\r\n type=\"button\"\r\n onClick={() => {\r\n void runWithGuard(() => {\r\n const id = generateItemId ? generateItemId() : defaultItemId();\r\n const baseRef = editingScope.raw;\r\n const itemRef = baseRef ? `${baseRef}/item:${id}` : `item:${id}`;\r\n setSelectedFacetRef(itemRef);\r\n onTelemetry?.({ type: 'item.create', recordType, scopeRef: baseRef });\r\n });\r\n }}\r\n className=\"w-full inline-flex items-center justify-center gap-1.5 text-xs py-1.5 rounded-md border transition-colors hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n <Plus className=\"w-3.5 h-3.5\" />\r\n {i18n.newItem || `New ${itemNoun}`}\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto\">\r\n {leftLoading && <LoadingState />}\r\n {!leftLoading && leftError && <ErrorState error={leftError} />}\r\n {!leftLoading && !leftError && leftItems.length === 0 && (\r\n renderEmpty\r\n ? renderEmpty({ scope: editingScope })\r\n : renderEmptyState\r\n ? renderEmptyState({ scope: activeScope })\r\n : <EmptyState\r\n icon={search ? icons.empty.search : icons.empty.default}\r\n title={search ? i18n.noResults : i18n.railEmptyTitle}\r\n body={search ? undefined : i18n.railEmptyBody}\r\n />\r\n )}\r\n {!leftLoading && !leftError && leftItems.length > 0 && (\r\n <>\r\n <RecordList\r\n items={leftItems}\r\n selectedRef={leftSelectedRef}\r\n onSelect={onLeftSelect}\r\n dirtyRef={editorCtx.isDirty ? editingScope?.raw : undefined}\r\n presentation={effectivePresentation}\r\n renderListRow={renderListRow as ((r: RecordSummary, c: { selected: boolean; onSelect: () => void; isDirty?: boolean }) => ReactNode) | undefined}\r\n renderCard={renderCard as ((r: RecordSummary, c: { selected: boolean; onSelect: () => void; isDirty?: boolean }) => ReactNode) | undefined}\r\n groupBy={effectiveGroupBy}\r\n />\r\n {isProductTab && !productPinned && productBrowse.hasNextPage && (\r\n <div className=\"p-2\">\r\n <button\r\n type=\"button\"\r\n onClick={() => { void productBrowse.fetchNextPage(); }}\r\n disabled={productBrowse.isFetchingNextPage}\r\n className=\"w-full text-xs py-2 rounded-md border transition-opacity disabled:opacity-50 hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n {productBrowse.isFetchingNextPage ? 'Loading…' : `Load more (${leftItems.length} shown)`}\r\n </button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </aside>\r\n <main className=\"overflow-hidden\">\r\n {!editingScope && activeScope === 'product' && !selectedProductId && (\r\n <EmptyState title={i18n.emptyTitle} body={i18n.emptyBody} />\r\n )}\r\n {!editingScope && activeScope === 'facet' && (\r\n <EmptyState title={i18n.emptyTitle} body={i18n.emptyBody} />\r\n )}\r\n {/* Product tab → drill-down wrapper around the editor */}\r\n {isProductTab && selectedProductId && (\r\n <ProductDrillDown\r\n productLabel={\r\n productBrowse.items.find((p: { id: string; name?: string }) => p.id === selectedProductId)?.name ?? selectedProductId\r\n }\r\n showVariants={drillVariantsAllowed}\r\n showBatches={drillBatchesAllowed}\r\n active={drillTab}\r\n onChange={(t) => {\r\n void runWithGuard(() => {\r\n setDrillTab(t);\r\n if (t === 'product') { setSelectedVariantId(undefined); setSelectedBatchId(undefined); }\r\n });\r\n }}\r\n selectedChildId={drillTab === 'variant' ? selectedVariantId : drillTab === 'batch' ? selectedBatchId : undefined}\r\n onSelectChild={(id) => {\r\n void runWithGuard(() => {\r\n if (drillTab === 'variant') setSelectedVariantId(id);\r\n else if (drillTab === 'batch') setSelectedBatchId(id);\r\n });\r\n }}\r\n variants={variantChildren.items}\r\n batches={batchChildren.items}\r\n variantsLoading={variantChildren.isLoading}\r\n batchesLoading={batchChildren.isLoading}\r\n >\r\n {editingScope ? renderEditorWithPreview() : (\r\n <EmptyState\r\n title={drillTab === 'variant' ? 'Pick a variant' : 'Pick a batch'}\r\n body={`Select a ${drillTab} on the left to edit its ${recordType ?? label.toLowerCase()}.`}\r\n />\r\n )}\r\n </ProductDrillDown>\r\n )}\r\n {/* Facet tab → straight to the editor */}\r\n {!isProductTab && editingScope && renderEditorWithPreview()}\r\n </main>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { Search } from 'lucide-react';\r\nimport type { RecordStatus, RecordSummary, ScopeKind, RecordsAdminI18n } from '../types';\r\nimport { ScopeTabs } from './ScopeTabs';\r\nimport { StatusFilterPills } from './StatusFilterPills';\r\nimport { RecordList } from './RecordList';\r\nimport { EmptyState, ErrorState, LoadingState } from './EmptyStates';\r\n\r\nexport interface RecordBrowserProps {\r\n scopes: ScopeKind[];\r\n activeScope: ScopeKind;\r\n onActiveScopeChange: (s: ScopeKind) => void;\r\n\r\n selectedRef?: string;\r\n onSelectRef: (item: RecordSummary) => void;\r\n\r\n items: RecordSummary[];\r\n counts: { all: number; configured: number; partial: number; empty: number };\r\n isLoading: boolean;\r\n error: Error | null;\r\n\r\n filter: 'all' | RecordStatus;\r\n onFilterChange: (v: 'all' | RecordStatus) => void;\r\n search: string;\r\n onSearchChange: (v: string) => void;\r\n\r\n hasNextPage?: boolean;\r\n isFetchingNextPage?: boolean;\r\n onLoadMore?: () => void;\r\n\r\n scopesLoading?: boolean;\r\n\r\n i18n: RecordsAdminI18n;\r\n}\r\n\r\nexport const RecordBrowser = ({\r\n scopes, activeScope, onActiveScopeChange,\r\n selectedRef, onSelectRef,\r\n items, counts, isLoading, error,\r\n filter, onFilterChange, search, onSearchChange,\r\n hasNextPage, isFetchingNextPage, onLoadMore,\r\n scopesLoading,\r\n i18n,\r\n}: RecordBrowserProps) => {\r\n return (\r\n <div className=\"flex flex-col h-full\" style={{ background: 'hsl(var(--ra-surface))' }}>\r\n <ScopeTabs scopes={scopes} active={activeScope} onChange={onActiveScopeChange} loading={scopesLoading} />\r\n <div className=\"p-3 space-y-2.5 border-b\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 opacity-50\" />\r\n <input\r\n type=\"text\"\r\n value={search}\r\n onChange={(e) => onSearchChange(e.target.value)}\r\n placeholder={i18n.searchPlaceholder}\r\n className=\"w-full pl-8 pr-3 py-1.5 text-xs rounded-md border bg-transparent focus:outline-none focus:ring-1\"\r\n style={{\r\n borderColor: 'hsl(var(--ra-border))',\r\n color: 'hsl(var(--ra-text))',\r\n }}\r\n />\r\n </div>\r\n <StatusFilterPills value={filter} onChange={onFilterChange} counts={counts} i18n={i18n} />\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto\">\r\n {isLoading && <LoadingState />}\r\n {!isLoading && error && <ErrorState error={error} />}\r\n {!isLoading && !error && items.length === 0 && (\r\n <EmptyState title={i18n.noResults} body={search ? undefined : i18n.emptyBody} />\r\n )}\r\n {!isLoading && !error && items.length > 0 && (\r\n <>\r\n <RecordList items={items} selectedRef={selectedRef} onSelect={onSelectRef} />\r\n {hasNextPage && (\r\n <div className=\"p-2\">\r\n <button\r\n type=\"button\"\r\n onClick={onLoadMore}\r\n disabled={isFetchingNextPage}\r\n className=\"w-full text-xs py-2 rounded-md border transition-opacity disabled:opacity-50 hover:bg-[hsl(var(--ra-muted))]\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n {isFetchingNextPage ? 'Loading…' : `Load more (${items.length} shown)`}\r\n </button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};","import { type ReactNode, createContext, useContext } from 'react';\r\nimport { CornerDownLeft, Circle } from 'lucide-react';\r\n\r\ninterface InheritanceCtx {\r\n parentValue?: Record<string, unknown> | null;\r\n ownValue?: Record<string, unknown> | null;\r\n onResetField?: (field: string) => void;\r\n}\r\n\r\nconst Ctx = createContext<InheritanceCtx>({});\r\n\r\nexport const InheritanceProvider = ({\r\n parentValue, ownValue, onResetField, children,\r\n}: InheritanceCtx & { children: ReactNode }) => (\r\n <Ctx.Provider value={{ parentValue, ownValue, onResetField }}>{children}</Ctx.Provider>\r\n);\r\n\r\ninterface MarkerProps {\r\n field: string;\r\n inheritedValue?: unknown;\r\n value?: unknown;\r\n children: ReactNode;\r\n}\r\n\r\nconst eq = (a: unknown, b: unknown) => {\r\n try { return JSON.stringify(a) === JSON.stringify(b); }\r\n catch { return false; }\r\n};\r\n\r\nexport const InheritanceMarker = ({ field, inheritedValue, value, children }: MarkerProps) => {\r\n const ctx = useContext(Ctx);\r\n const inh = inheritedValue !== undefined ? inheritedValue : ctx.parentValue?.[field];\r\n const cur = value !== undefined ? value : ctx.ownValue?.[field];\r\n const isInherited = inh !== undefined && eq(inh, cur);\r\n if (inh === undefined) return <>{children}</>;\r\n return (\r\n <div className=\"space-y-1\">\r\n {children}\r\n <div className=\"flex items-center gap-1 text-[10px]\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n {isInherited ? (\r\n <>\r\n <CornerDownLeft className=\"w-2.5 h-2.5\" />\r\n <span>Inherited</span>\r\n </>\r\n ) : (\r\n <>\r\n <Circle className=\"w-2 h-2 fill-current\" style={{ color: 'hsl(var(--ra-status-shared))' }} />\r\n <span>Override</span>\r\n {ctx.onResetField && (\r\n <button\r\n type=\"button\"\r\n onClick={() => ctx.onResetField?.(field)}\r\n className=\"underline opacity-70 hover:opacity-100 ml-1\"\r\n >\r\n Reset\r\n </button>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};","import type { ReactNode } from 'react';\r\n\r\ninterface Props { children: ReactNode }\r\n\r\nexport const ResolvedPreview = ({ children }: Props) => (\r\n <div className=\"mt-4 pt-4 border-t\" style={{ borderColor: 'hsl(var(--ra-border))' }}>\r\n <div className=\"text-[10px] uppercase tracking-wide mb-2\" style={{ color: 'hsl(var(--ra-muted-text))' }}>\r\n Public preview\r\n </div>\r\n {children}\r\n </div>\r\n);","// =============================================================================\r\n// useResolveAllRecords — fetch every applicable record for a product context.\r\n//\r\n// Wraps the SDK 1.10 `app.records.resolveAll()` endpoint (single round-trip).\r\n// Use this when an app needs the *stack* of records that apply (warranty +\r\n// nutrition + facet-rule overlays etc.), not just the single most-specific\r\n// winner. For the single-winner case keep using `useResolvedRecord`.\r\n// =============================================================================\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\nimport type {\r\n ResolveAllResult, MatchEntry, MatchedAt,\r\n} from '../data/sdkTypes';\r\n\r\nexport interface UseResolveAllRecordsArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n /** Limit to a single record type. Omit to return every type. */\r\n recordType?: string;\r\n /** Product context — at minimum a productId in most apps. */\r\n context: {\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n proofId?: string;\r\n /**\r\n * Facet assignments for the product. Used for both legacy facet refs\r\n * and `facetRule` evaluation server-side.\r\n * e.g. `{ brand: 'samsung', type: ['tv', 'laptop'] }`\r\n */\r\n facets?: Record<string, string | string[]>;\r\n };\r\n /** Restrict to specific tiers (e.g. only `['rule', 'product']`). */\r\n tiers?: MatchedAt[];\r\n /** Safety cap. Default 500, max 5000. */\r\n limit?: number;\r\n /** Point-in-time evaluation for scheduled records. ISO 8601. */\r\n at?: string;\r\n includeScheduled?: boolean;\r\n includeExpired?: boolean;\r\n /**\r\n * `false` to use the public (visibility-filtered) endpoint.\r\n * Defaults to `false` so this hook is safe to call from public surfaces.\r\n */\r\n admin?: boolean;\r\n enabled?: boolean;\r\n staleTime?: number;\r\n}\r\n\r\nexport const resolveAllQueryKey = (args: UseResolveAllRecordsArgs): unknown[] => [\r\n 'records-admin', 'resolve-all',\r\n args.collectionId, args.appId, args.recordType ?? null,\r\n args.context.productId ?? null,\r\n args.context.variantId ?? null,\r\n args.context.batchId ?? null,\r\n args.context.proofId ?? null,\r\n args.context.facets ?? null,\r\n args.tiers ?? null,\r\n args.limit ?? null,\r\n args.at ?? null,\r\n args.includeScheduled ?? false,\r\n args.includeExpired ?? false,\r\n args.admin ?? false,\r\n];\r\n\r\nexport interface UseResolveAllResult {\r\n /** All matching records, sorted most-specific first. Each appears once. */\r\n records: MatchEntry[];\r\n /** True when the result hit the `limit` safety cap. */\r\n truncated: boolean;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => void;\r\n}\r\n\r\nexport function useResolveAllRecords(args: UseResolveAllRecordsArgs): UseResolveAllResult {\r\n const {\r\n SL, collectionId, appId, recordType,\r\n context, tiers, limit, at, includeScheduled, includeExpired,\r\n admin = false, enabled = true, staleTime = 15_000,\r\n } = args;\r\n\r\n const query = useQuery<ResolveAllResult>({\r\n queryKey: resolveAllQueryKey(args),\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime,\r\n queryFn: () => SL.app.records.resolveAll(\r\n collectionId, appId,\r\n {\r\n context,\r\n ...(recordType ? { recordType } : {}),\r\n ...(tiers ? { tiers: tiers as Array<Exclude<MatchedAt, 'universal'>> } : {}),\r\n ...(limit !== undefined ? { limit } : {}),\r\n ...(at ? { at } : {}),\r\n ...(includeScheduled !== undefined ? { includeScheduled } : {}),\r\n ...(includeExpired !== undefined ? { includeExpired } : {}),\r\n },\r\n admin,\r\n ),\r\n });\r\n\r\n return {\r\n records: query.data?.records ?? [],\r\n truncated: query.data?.truncated ?? false,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch: () => { void query.refetch(); },\r\n };\r\n}","// =============================================================================\r\n// useRulePreview — debounced live \"matches N products\" feedback for the\r\n// FacetRuleEditor. Wraps SDK 1.10 `app.records.previewRule()` (admin-only).\r\n//\r\n// Returns a sample of product IDs and the total count so admins can sanity-\r\n// check the rule they are authoring before saving.\r\n// =============================================================================\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\nimport type { FacetRule, FacetRuleClause, PreviewRuleResult } from '../data/sdkTypes';\r\n\r\nexport interface UseRulePreviewArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n rule: FacetRule | null;\r\n /** Sample size. Default 20, max 200. */\r\n limit?: number;\r\n /** Debounce window in ms while the admin types. Default 350ms. */\r\n debounceMs?: number;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseRulePreviewResult {\r\n totalMatches: number | null;\r\n sampleProductIds: string[];\r\n isLoading: boolean;\r\n isStale: boolean;\r\n error: Error | null;\r\n}\r\n\r\nconst isRuleValid = (rule: FacetRule | null): rule is FacetRule => {\r\n if (!rule || !Array.isArray(rule.all) || rule.all.length === 0) return false;\r\n return rule.all.every(\r\n (c: FacetRuleClause) => !!c.facetKey && Array.isArray(c.anyOf) && c.anyOf.length > 0,\r\n );\r\n};\r\n\r\nexport function useRulePreview(args: UseRulePreviewArgs): UseRulePreviewResult {\r\n const {\r\n SL, collectionId, appId, rule,\r\n limit = 20, debounceMs = 350, enabled = true,\r\n } = args;\r\n\r\n const [debouncedRule, setDebouncedRule] = useState<FacetRule | null>(rule);\r\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n useEffect(() => {\r\n if (timer.current) clearTimeout(timer.current);\r\n timer.current = setTimeout(() => setDebouncedRule(rule), debounceMs);\r\n return () => { if (timer.current) clearTimeout(timer.current); };\r\n }, [rule, debounceMs]);\r\n\r\n const valid = isRuleValid(debouncedRule);\r\n\r\n const query = useQuery<PreviewRuleResult>({\r\n queryKey: ['records-admin', 'preview-rule', collectionId, appId, debouncedRule, limit],\r\n enabled: enabled && !!collectionId && !!appId && valid,\r\n staleTime: 30_000,\r\n queryFn: () => SL.app.records.previewRule(collectionId, appId, {\r\n facetRule: debouncedRule as FacetRule,\r\n limit,\r\n }),\r\n });\r\n\r\n return {\r\n totalMatches: query.data?.totalMatches ?? null,\r\n sampleProductIds: query.data?.sampleProductIds ?? [],\r\n isLoading: query.isFetching,\r\n isStale: rule !== debouncedRule,\r\n error: (query.error as Error | null) ?? null,\r\n };\r\n}","// =============================================================================\r\n// useCollectedRecords — Returns EVERY record matching a target scope, ordered\r\n// most-specific → least-specific. Backed by server-side `match()` as of\r\n// SDK 1.9, so this is a single round-trip and honours facet AND/OR semantics.\r\n// =============================================================================\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { ParsedRef, ScopeKind, SmartLinksSDK, CollectedSort } from '../types';\r\nimport { parseRef } from '../data/refs';\r\nimport { matchRecords } from '../data/records';\r\nimport type { MatchEntry } from '../data/sdkTypes';\r\nimport { parsedRefToTarget } from '../data/scopeBridge';\r\n\r\nexport interface CollectedRecord<T = unknown> {\r\n /** The ref this record was loaded from. */\r\n ref: string;\r\n /** Parsed scope of the ref (gives you `productId`, `facetId`, etc.). */\r\n scope: ParsedRef;\r\n /** Domain payload. */\r\n data: T;\r\n /** Index in the resolution chain (0 = most-specific). */\r\n depth: number;\r\n}\r\n\r\nexport interface UseCollectedRecordsArgs {\r\n SL: SmartLinksSDK;\r\n appId: string;\r\n recordType?: string;\r\n collectionId: string;\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n /** Scopes to walk. Defaults to all four. */\r\n supportedScopes?: ScopeKind[];\r\n /** Drop scopes that don't have a record (default true). */\r\n filterEmpty?: boolean;\r\n /**\r\n * Ordering applied to the result. Defaults to specificity-descending\r\n * (most-specific scope first), matching the previous behaviour and aligning\r\n * with the future `match()` API.\r\n */\r\n sort?: CollectedSort;\r\n enabled?: boolean;\r\n}\r\n\r\nconst DEFAULT_SCOPES: ScopeKind[] = ['batch', 'variant', 'product', 'facet'];\r\n\r\n/** Read a possibly-nested field path from arbitrary record data. */\r\nconst readField = (data: unknown, path: string): unknown => {\r\n if (data == null || typeof data !== 'object') return undefined;\r\n return path.split('.').reduce<unknown>((acc, key) => {\r\n if (acc == null || typeof acc !== 'object') return undefined;\r\n return (acc as Record<string, unknown>)[key];\r\n }, data);\r\n};\r\n\r\nconst compareValues = (a: unknown, b: unknown): number => {\r\n // Nullish always sorts last regardless of direction.\r\n const aNull = a === undefined || a === null;\r\n const bNull = b === undefined || b === null;\r\n if (aNull && bNull) return 0;\r\n if (aNull) return 1;\r\n if (bNull) return -1;\r\n if (typeof a === 'number' && typeof b === 'number') return a - b;\r\n return String(a).localeCompare(String(b), undefined, { numeric: true, sensitivity: 'base' });\r\n};\r\n\r\nexport function useCollectedRecords<T = unknown>(args: UseCollectedRecordsArgs) {\r\n const {\r\n SL, appId, recordType, collectionId,\r\n productId, variantId, batchId, facetId, facetValue,\r\n supportedScopes = DEFAULT_SCOPES,\r\n filterEmpty = true,\r\n sort,\r\n enabled = true,\r\n } = args;\r\n\r\n const sortKey = sort\r\n ? sort.kind === 'field'\r\n ? `field:${sort.field}:${sort.direction ?? 'asc'}`\r\n : `specificity:${sort.direction ?? 'desc'}`\r\n : 'specificity:desc';\r\n\r\n const query = useQuery<CollectedRecord<T>[]>({\r\n queryKey: ['records-admin', 'collected', collectionId, appId, recordType ?? null,\r\n productId ?? null, variantId ?? null, batchId ?? null, facetId ?? null, facetValue ?? null,\r\n supportedScopes.join(','), filterEmpty, sortKey],\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime: 15_000,\r\n queryFn: async () => {\r\n const target = parseRef('');\r\n target.productId = productId;\r\n target.variantId = variantId;\r\n target.batchId = batchId;\r\n target.facetId = facetId;\r\n target.facetValue = facetValue;\r\n const ctx = { SL, collectionId, appId, recordType };\r\n const result = await matchRecords(ctx, parsedRefToTarget(target), { strategy: 'all' })\r\n .catch(() => null);\r\n const records = result?.records ?? [];\r\n // The server returns records ordered by descending specificity.\r\n // We map specificity → depth here so existing consumers keep working\r\n // (lower `depth` = more-specific, matching the previous semantics).\r\n const baseList: CollectedRecord<T>[] = records.map((entry: MatchEntry, i: number) => {\r\n const rec = entry.record;\r\n return {\r\n ref: rec.ref ?? '',\r\n scope: parseRef(rec.ref ?? ''),\r\n data: rec.data as T,\r\n depth: i,\r\n };\r\n });\r\n // `filterEmpty` is now a no-op — `match()` only returns records that exist.\r\n void filterEmpty;\r\n void supportedScopes;\r\n\r\n const sortKind = sort?.kind ?? 'specificity';\r\n const direction = sort?.direction ?? (sortKind === 'specificity' ? 'desc' : 'asc');\r\n const sign = direction === 'desc' ? -1 : 1;\r\n const fieldPath = sort?.kind === 'field' ? sort.field : '';\r\n\r\n const sorted = [...baseList].sort((a, b) => {\r\n if (sortKind === 'field') {\r\n const cmp = compareValues(readField(a.data, fieldPath), readField(b.data, fieldPath));\r\n if (cmp !== 0) return sign * cmp;\r\n // Stable tiebreak on specificity (most-specific first).\r\n return a.depth - b.depth;\r\n }\r\n // specificity: lower depth = more specific\r\n return direction === 'desc' ? a.depth - b.depth : b.depth - a.depth;\r\n });\r\n\r\n return sorted;\r\n },\r\n });\r\n\r\n return {\r\n items: query.data ?? [],\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch: query.refetch,\r\n };\r\n}","// =============================================================================\r\n// useMergedRecord — Deep-merges every record in the resolution chain so apps\r\n// can ship shared defaults at one scope and field-level overrides at another.\r\n//\r\n// Walks LEAST-specific → MOST-specific, so deeper scopes win on conflict\r\n// (i.e. a batch override beats the product default). The result includes\r\n// per-key `provenance` so the UI can show where each field came from.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { ParsedRef, ScopeKind, SmartLinksSDK } from '../types';\r\nimport type { MatchEntry } from '../data/sdkTypes';\r\nimport { parseRef } from '../data/refs';\r\nimport { matchRecords } from '../data/records';\r\nimport { parsedRefToTarget } from '../data/scopeBridge';\r\n\r\nexport type MergeStrategy = 'deep' | 'shallow';\r\n\r\nexport interface MergedRecord<T = unknown> {\r\n /** The merged result. */\r\n data: T | null;\r\n /**\r\n * For each top-level key, the ref of the record that contributed its\r\n * winning value. Useful for \"Inherited from facet:gluten-free\" hints.\r\n */\r\n provenance: Record<string, string>;\r\n /** Refs that contributed something to the merge, deepest-first. */\r\n layers: string[];\r\n}\r\n\r\nexport interface UseMergedRecordArgs<T> {\r\n SL: SmartLinksSDK;\r\n appId: string;\r\n recordType?: string;\r\n collectionId: string;\r\n productId?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n supportedScopes?: ScopeKind[];\r\n /**\r\n * Merge strategy. `deep` recursively merges plain objects; arrays are\r\n * replaced wholesale. `shallow` does Object.assign at the top level.\r\n * Default `deep`.\r\n */\r\n strategy?: MergeStrategy;\r\n /** Custom merge fn. Receives `(parent, child)` and returns the winner. */\r\n merge?: (parent: T | null, child: T) => T;\r\n enabled?: boolean;\r\n}\r\n\r\nconst DEFAULT_SCOPES: ScopeKind[] = ['batch', 'variant', 'product', 'facet'];\r\n\r\nconst isPlainObject = (v: unknown): v is Record<string, unknown> =>\r\n !!v && typeof v === 'object' && !Array.isArray(v) && (v as object).constructor === Object;\r\n\r\nconst deepMerge = <T,>(parent: T | null, child: T): T => {\r\n if (!isPlainObject(parent) || !isPlainObject(child)) return child;\r\n const out: Record<string, unknown> = { ...parent };\r\n for (const [k, v] of Object.entries(child)) {\r\n out[k] = isPlainObject(v) && isPlainObject(out[k])\r\n ? deepMerge(out[k] as T, v as T)\r\n : v;\r\n }\r\n return out as T;\r\n};\r\n\r\nconst shallowMerge = <T,>(parent: T | null, child: T): T => {\r\n if (!isPlainObject(parent) || !isPlainObject(child)) return child;\r\n return { ...(parent as object), ...(child as object) } as T;\r\n};\r\n\r\nexport function useMergedRecord<T = unknown>(args: UseMergedRecordArgs<T>) {\r\n const {\r\n SL, appId, recordType, collectionId,\r\n productId, variantId, batchId, facetId, facetValue,\r\n supportedScopes = DEFAULT_SCOPES,\r\n strategy = 'deep',\r\n merge,\r\n enabled = true,\r\n } = args;\r\n\r\n const mergeFn = useMemo(() => {\r\n if (merge) return merge;\r\n return strategy === 'shallow' ? shallowMerge : deepMerge;\r\n }, [merge, strategy]);\r\n\r\n const query = useQuery<MergedRecord<T>>({\r\n queryKey: ['records-admin', 'merged', collectionId, appId, recordType ?? null,\r\n productId ?? null, variantId ?? null, batchId ?? null, facetId ?? null, facetValue ?? null,\r\n supportedScopes.join(','), strategy],\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime: 15_000,\r\n queryFn: async (): Promise<MergedRecord<T>> => {\r\n const target = parseRef('');\r\n target.productId = productId;\r\n target.variantId = variantId;\r\n target.batchId = batchId;\r\n target.facetId = facetId;\r\n target.facetValue = facetValue;\r\n const ctx = { SL, collectionId, appId, recordType };\r\n void supportedScopes; // server resolves the chain\r\n const result = await matchRecords(ctx, parsedRefToTarget(target), { strategy: 'all' })\r\n .catch(() => null);\r\n const records = result?.records ?? [];\r\n if (records.length === 0) return { data: null, provenance: {}, layers: [] };\r\n const present = records.map((entry: MatchEntry) => ({\r\n ref: entry.record.ref ?? '',\r\n data: entry.record.data as T,\r\n }));\r\n\r\n // Merge least-specific → most-specific so deeper scopes win.\r\n const ordered = [...present].reverse();\r\n let merged: T | null = null;\r\n const provenance: Record<string, string> = {};\r\n for (const layer of ordered) {\r\n merged = mergeFn(merged, layer.data);\r\n if (isPlainObject(layer.data)) {\r\n for (const k of Object.keys(layer.data as object)) provenance[k] = layer.ref;\r\n }\r\n }\r\n return { data: merged, provenance, layers: present.map((p) => p.ref) };\r\n },\r\n });\r\n\r\n const data = query.data ?? { data: null, provenance: {}, layers: [] };\r\n return {\r\n ...data,\r\n isLoading: query.isLoading,\r\n error: (query.error as Error | null) ?? null,\r\n refetch: query.refetch,\r\n };\r\n}"]}
|