@proveanything/smartlinks-utils-ui 0.3.12 → 0.3.14
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-TY2UIZ24.js → chunk-76Y4UTYQ.js} +14 -5
- package/dist/chunk-76Y4UTYQ.js.map +1 -0
- package/dist/{chunk-MZ6JSCXO.js → chunk-JMCV6FOW.js} +2 -2
- package/dist/{chunk-MZ6JSCXO.js.map → chunk-JMCV6FOW.js.map} +1 -1
- package/dist/chunk-LLSIDR6U.js +28 -0
- package/dist/chunk-LLSIDR6U.js.map +1 -0
- package/dist/chunk-S27GIYV7.js +3 -0
- package/dist/chunk-S27GIYV7.js.map +1 -0
- package/dist/components/AssetPicker/index.js +1 -1
- package/dist/components/ConditionsEditor/index.js +1 -1
- package/dist/components/FacetRuleEditor/index.js +2 -1
- package/dist/components/FontPicker/index.js +1 -1
- package/dist/components/IconPicker/index.js +1 -1
- package/dist/components/RecordsAdmin/index.d.ts +58 -4
- package/dist/components/RecordsAdmin/index.js +441 -64
- package/dist/components/RecordsAdmin/index.js.map +1 -1
- package/dist/index.js +3 -2
- package/dist/records-AUJWCB7Q.js +3 -0
- package/dist/{records-66QWR67J.js.map → records-AUJWCB7Q.js.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-3BLWNYM4.js +0 -28
- package/dist/chunk-3BLWNYM4.js.map +0 -1
- package/dist/chunk-TY2UIZ24.js.map +0 -1
- package/dist/records-66QWR67J.js +0 -3
|
@@ -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/types/deepLink.ts","../../../src/components/RecordsAdmin/data/refs.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/hooks/usePasteConfirm.tsx","../../../src/components/RecordsAdmin/hooks/useRecordClipboard.ts","../../../src/components/RecordsAdmin/browser/ScopeTabs.tsx","../../../src/components/RecordsAdmin/browser/StatusFilterPills.tsx","../../../src/components/RecordsAdmin/browser/StatusIcon.tsx","../../../src/components/RecordsAdmin/browser/RowContextMenu.tsx","../../../src/components/RecordsAdmin/browser/formatFacetRule.ts","../../../src/components/RecordsAdmin/browser/DefaultRecordRow.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/hooks/useCollectionItems.ts","../../../src/components/RecordsAdmin/data/deepLinkAdapter.ts","../../../src/components/RecordsAdmin/hooks/useDeepLinkState.ts","../../../src/components/RecordsAdmin/shell/ScopeBreadcrumb.tsx","../../../src/components/RecordsAdmin/editor/BulkActionsMenu.tsx","../../../src/components/RecordsAdmin/browser/StatusDot.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/items/ItemViewSwitcher.tsx","../../../src/components/RecordsAdmin/items/DefaultItemTable.tsx","../../../src/components/RecordsAdmin/items/DefaultItemCards.tsx","../../../src/components/RecordsAdmin/items/ItemListView.tsx","../../../src/components/RecordsAdmin/items/EditorItemNav.tsx","../../../src/components/RecordsAdmin/items/SiblingRail.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/shell/ClipboardToast.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/browser/DefaultRecordCard.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","classify","total","useQueryClient","useState","useEffect","useCallback","useQuery","useRef","useMemo","QK","useInfiniteQuery","items","res","jsx","DEFAULTS","jsxs","MoreHorizontal","Copy","Inbox","QK_BASE","toSummary","Layers","Upload","Download","ChevronDown","Trash2","Fragment","ClipboardPaste","Package","Eye","ICONS","TableIcon","LayoutGrid","ImageIcon","labelFor","Pencil","Plus","PlusIcon","ChevronRight","ArrowLeft","Lightbulb","CheckCircle2","AlertTriangle","X","CopyIcon","deleteRecord","label","HelpCircle","Search","initials","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 SlidersHorizontal,\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: {\r\n collection: Globe,\r\n product: Package,\r\n variant: Layers,\r\n batch: Boxes,\r\n facet: Tag,\r\n universal: Globe,\r\n rule: SlidersHorizontal,\r\n },\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 presentationCompact: string;\r\n\r\n /** Right-pane item view (collection cardinality) switcher labels. */\r\n itemViewTable: string;\r\n itemViewCards: string;\r\n itemViewGallery: 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 * Right-pane multi-item flow strings (collection cardinality).\r\n * `{noun}` is replaced with `itemNoun` (e.g. \"recipe\", \"FAQ\").\r\n */\r\n backToList: string;\r\n prevItem: string;\r\n nextItem: string;\r\n itemListTitle: string;\r\n /** Friendly singular for table column header in built-in default. */\r\n itemColumnLabel: string;\r\n itemColumnUpdated: string;\r\n itemActions: string;\r\n\r\n /** Sibling rail (rail flips to items when one is open). */\r\n backToScopes: string;\r\n siblingsHeading: 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 /** Clipboard / copy-paste affordance. */\r\n copy: string;\r\n paste: string;\r\n pasteFrom: string;\r\n pasteReplace: string;\r\n clipboardEmpty: string;\r\n copyToast: string;\r\n pasteToast: string;\r\n /** Confirm dialog when pasting onto a destination with an existing saved value. */\r\n pasteConfirmTitle: string;\r\n pasteConfirmBody: string;\r\n pasteConfirmReplace: string;\r\n pasteConfirmCancel: string;\r\n /** Cross-scope warning copy (e.g. variant → product). */\r\n pasteWarnTitle: string;\r\n pasteWarnContinue: 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 presentationCompact: 'Compact',\r\n itemViewTable: 'Table',\r\n itemViewCards: 'Cards',\r\n itemViewGallery: 'Gallery',\r\n newItem: 'New item',\r\n noItemsTitle: 'No items yet',\r\n noItemsBody: 'Create your first item to get started.',\r\n backToList: 'Back to list',\r\n prevItem: 'Previous',\r\n nextItem: 'Next',\r\n itemListTitle: 'Items',\r\n itemColumnLabel: 'Name',\r\n itemColumnUpdated: 'Updated',\r\n itemActions: 'Actions',\r\n backToScopes: '← All scopes',\r\n siblingsHeading: 'Items in this scope',\r\n railEmptyTitle: 'No records yet',\r\n railEmptyBody: 'Records you create will appear here.',\r\n copy: 'Copy',\r\n paste: 'Paste',\r\n pasteFrom: 'Paste from {name}',\r\n pasteReplace: 'Paste (replace)',\r\n clipboardEmpty: 'Nothing to paste',\r\n copyToast: 'Copied {name}. Pick a destination to paste.',\r\n pasteToast: 'Pasted from {name}. Review and Save.',\r\n pasteConfirmTitle: 'Replace existing values?',\r\n pasteConfirmBody: '{destination} already has saved values. Replace them with the copied values?',\r\n pasteConfirmReplace: 'Replace',\r\n pasteConfirmCancel: 'Cancel',\r\n pasteWarnTitle: 'Cross-scope paste',\r\n pasteWarnContinue: 'Continue',\r\n};","// =============================================================================\r\n// RecordsAdmin — Rail presentation, item view, and cardinality\r\n// =============================================================================\r\n\r\n/**\r\n * How records are laid out in the **left rail** (the navigator).\r\n *\r\n * The rail is intentionally a dense tree/list — cards or galleries belong on\r\n * the right pane, not in a 260px column. Only the row densities are offered:\r\n *\r\n * - `list` → dense rows with status dot + label + subtitle (default).\r\n * - `compact` → minimal one-line rows (no subtitle, no status dot).\r\n */\r\nexport type RecordPresentation = 'list' | 'compact';\r\n\r\nexport const ALL_PRESENTATIONS: RecordPresentation[] = ['list', 'compact'];\r\n\r\n/**\r\n * How a multi-item collection is rendered in the **right pane** when a scope\r\n * is selected and no item is open. Right-pane only — cards and galleries\r\n * have the room to breathe here.\r\n *\r\n * - `table` → declarative columns (built-in default with `itemColumns`).\r\n * - `cards` → square cards with thumbnail + label.\r\n * - `gallery` → larger 16:9 cards with thumbnail + label + subtitle.\r\n */\r\nexport type ItemView = 'table' | 'cards' | 'gallery';\r\n\r\nexport const ALL_ITEM_VIEWS: ItemView[] = ['table', 'cards', 'gallery'];\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\r\n/**\r\n * What the left rail shows once an item is open in the editor (collection\r\n * cardinality only):\r\n *\r\n * - `siblings` *(default)* — rail flips to the list of items in the current\r\n * scope. Click any sibling to switch instantly. A pinned `← All scopes`\r\n * link returns to scope navigation.\r\n * - `scopes` — rail keeps showing scopes. Switching items requires going\r\n * back to the right-pane list first.\r\n */\r\nexport type CollectionRailMode = 'siblings' | 'scopes';","// =============================================================================\r\n// RecordsAdmin — Deep linking types\r\n//\r\n// The shell can mirror its own state (current scope, open item, right-pane\r\n// view) into URL query parameters so deep links into a specific record open\r\n// to the right place, and the browser back/forward buttons feel native.\r\n//\r\n// We deliberately keep the URL surface small:\r\n// - `item` → either a bare item id (`comp_winter_2026`, for items at the\r\n// collection root) or a full item ref including scope\r\n// (`product:abc/item:comp_winter_2026`). Either way the ref\r\n// carries enough information to resolve the item and derive\r\n// the scope, so we never need a separate `scope` param when\r\n// an item is open.\r\n// - `scope` → scope ref (e.g. `facet:region=eu` or `product:abc`). Used\r\n// only when no item is open, to deep-link to a list view.\r\n// - `view` → right-pane view (`table` / `cards` / `gallery`). Optional\r\n// UI preference — not part of \"what's open\".\r\n//\r\n// The shell never owns platform context (`appId`, `collectionId`, etc.) —\r\n// those live in the host's URL already and are out of scope here.\r\n// =============================================================================\r\n\r\n/**\r\n * How URL changes are pushed onto the browser history.\r\n *\r\n * - `push` — every change adds a history entry (rich back stack).\r\n * - `replace` — every change replaces the current entry (no history bloat).\r\n * - `smart` — meaningful navigation (open item, change scope) pushes;\r\n * cosmetic changes (toggle view, prev/next sibling) replace.\r\n * Default.\r\n */\r\nexport type DeepLinkHistoryMode = 'push' | 'replace' | 'smart';\r\n\r\n/**\r\n * Customise the URL parameter names the shell reads / writes. Useful when\r\n * a host already uses one of these keys for something else.\r\n */\r\nexport interface DeepLinkParamNames {\r\n /** Default `'item'`. */\r\n item?: string;\r\n /** Default `'scope'`. */\r\n scope?: string;\r\n /** Default `'view'`. */\r\n view?: string;\r\n}\r\n\r\n/**\r\n * The shell-owned deep-link state. All fields are optional — `null` /\r\n * `undefined` means \"absent from the URL\".\r\n */\r\nexport interface DeepLinkState {\r\n /** Item id when an item is open in the editor. */\r\n item?: string | null;\r\n /** Scope ref when no item is open and the user is browsing a list. */\r\n scope?: string | null;\r\n /** Right-pane view choice (`table` / `cards` / `gallery`). */\r\n view?: string | null;\r\n}\r\n\r\n/**\r\n * Pluggable bridge between the shell and the host's URL. Hosts can supply\r\n * their own adapter to integrate with React Router, hash routing, the\r\n * SmartLinks `persistentQueryParams` helper, etc. When omitted the shell\r\n * falls back to a plain `window.location` + `window.history` adapter.\r\n */\r\nexport interface DeepLinkAdapter {\r\n /** Read the current values for the shell-owned params. */\r\n read(): DeepLinkState;\r\n /**\r\n * Write a partial state update. `mode` is the resolved push/replace hint\r\n * (the shell already mapped `'smart'` to one of the two before calling).\r\n * Hosts should preserve every other URL parameter — only the keys\r\n * supplied here may be touched.\r\n */\r\n write(partial: DeepLinkState, mode: 'push' | 'replace'): void;\r\n /**\r\n * Subscribe to external URL changes (back/forward, host-driven nav).\r\n * Should fire whenever the params the shell cares about may have\r\n * changed. Returns an unsubscribe function.\r\n */\r\n subscribe(listener: () => void): () => void;\r\n}\r\n\r\nexport interface DeepLinkOptions {\r\n /** Master switch — default `false` (opt in per app). */\r\n enabled?: boolean;\r\n /** Push/replace strategy. Default `'smart'`. */\r\n history?: DeepLinkHistoryMode;\r\n /** Override the default param key names. */\r\n paramNames?: DeepLinkParamNames;\r\n /**\r\n * Pluggable URL bridge. Defaults to `window.location` + `window.history`\r\n * with a `popstate` subscription. Provide one when the host owns routing\r\n * (React Router, hash router, iframe postMessage relay, etc.).\r\n */\r\n adapter?: DeepLinkAdapter;\r\n}\r\n\r\n/**\r\n * Resolved param names — everywhere outside the public surface uses these\r\n * to avoid the optional-key ceremony.\r\n */\r\nexport interface ResolvedDeepLinkParamNames {\r\n item: string;\r\n scope: string;\r\n view: string;\r\n}\r\n\r\nexport const DEFAULT_DEEP_LINK_PARAM_NAMES: ResolvedDeepLinkParamNames = {\r\n item: 'item',\r\n scope: 'scope',\r\n view: 'view',\r\n};","// =============================================================================\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 // `rule` records carry an opaque id under the `rule:` prefix; we expose\r\n // the id via `productId`-equivalent slot to keep ParsedRef flat. Resolved\r\n // refs use the `ruleId` field (added below) so callers can disambiguate.\r\n rule: 'ruleId' as keyof ParsedRef,\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' | 'item';\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 === 'item') {\r\n // Item segments don't change `kind` — they're sub-keys under whatever\r\n // scope they appended to (or the collection root when alone).\r\n parsed.itemId = id;\r\n continue;\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 itemId?: 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 if (a.itemId) parts.push(`item:${a.itemId}`);\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 // Terminal rung — collection-wide default. Empty ref string targets the\r\n // app+collection record(s) with no further qualifier.\r\n if (supportedScopes.includes('collection')) {\r\n chain.push('');\r\n }\r\n // Dedupe while preserving order\r\n return Array.from(new Set(chain));\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Item-aware helpers (collection cardinality)\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Strip the trailing `/item:{id}` (or leading `item:{id}`) from a ref and\r\n * return both halves. For singleton refs `itemId` is `undefined` and\r\n * `scopeRef` equals the input.\r\n */\r\nexport const splitItemRef = (raw: string): { scopeRef: string; itemId?: string } => {\r\n if (!raw) return { scopeRef: '' };\r\n const segs = raw.split('/').filter(Boolean);\r\n const last = segs[segs.length - 1];\r\n if (last && last.startsWith('item:')) {\r\n return { scopeRef: segs.slice(0, -1).join('/'), itemId: last.slice('item:'.length) };\r\n }\r\n return { scopeRef: raw };\r\n};\r\n\r\n/** Concatenate a scope ref (possibly empty for collection) and an itemId. */\r\nexport const buildItemRef = (scopeRef: string, itemId: string): string => {\r\n return scopeRef ? `${scopeRef}/item:${itemId}` : `item:${itemId}`;\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, FacetRule } 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\n/**\r\n * Decide which records belong on which top-level scope tab.\r\n *\r\n * - `rule` — anything carrying a server-side `facetRule` (or whose\r\n * ref starts with `rule:` for forward-compat).\r\n * - `collection` — \"Global\" records: no pinned scope and no facetRule.\r\n * Critical for migrations where existing FAQs / SOPs /\r\n * recipes were created without a `ref`.\r\n * - `product`/`variant`/`batch`/`facet` — pinned-scope records, as before.\r\n *\r\n * Rule and Global records must NEVER leak into the pinned tabs (they'd\r\n * appear duplicated under every facet otherwise).\r\n */\r\nconst matchesScope = (\r\n kind: ScopeKind,\r\n rec: AppRecord,\r\n p: ParsedRef,\r\n): boolean => {\r\n const hasRule = !!(rec as { facetRule?: FacetRule | null }).facetRule\r\n || (rec.ref ?? '').startsWith('rule:');\r\n if (kind === 'rule') return hasRule;\r\n if (hasRule) return false;\r\n\r\n if (kind === 'collection') {\r\n // \"Global\" — no pinned scope at all. Empty/missing ref counts.\r\n return !p.productId && !p.facetId && !p.variantId && !p.batchId && !p.proofId;\r\n }\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 const facetRule = (rec as { facetRule?: FacetRule | null }).facetRule ?? null;\r\n // Friendly fallback for rule and global records — keeps the list readable\r\n // even before the host wires a `classify` / row renderer.\r\n const fallbackLabel = scope.batchId ?? scope.variantId ?? scope.productId\r\n ?? scope.facetValue ?? scope.facetId\r\n ?? (facetRule ? 'Rule-targeted record' : (ref || 'Global record'));\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: fallbackLabel,\r\n updatedAt: rec.updatedAt,\r\n facetRule,\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((rec) => ({ rec, summary: toSummary(rec) }))\r\n .filter(({ rec, summary }) => matchesScope(scopeKind, rec, summary.scope))\r\n .filter(({ summary }) => matchesContext(summary.scope, contextScope))\r\n .map(({ summary }) => ({ ...summary, status: cls(summary) }));\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 /** Save / primary action label. When empty/falsy the Save button is hidden\r\n * — useful for callers (e.g. Paste confirm) that only need Discard +\r\n * Cancel as a destructive-confirm pair. */\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 {saveLabel ? (\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 ) : null}\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// usePasteConfirm — themed two-button confirm used when pasting onto a\r\n// destination that already has a saved value, or across-scope when the\r\n// rules return `warn`. Reuses the existing <ConfirmDialog> chrome by\r\n// hiding the Save slot (only Discard / Cancel are wired).\r\n// =============================================================================\r\nimport { useCallback, useRef, useState, type ReactNode } from 'react';\r\nimport { ConfirmDialog } from '../shell/ConfirmDialog';\r\n\r\ninterface PendingState {\r\n title: string;\r\n body: string;\r\n confirmLabel: string;\r\n cancelLabel: string;\r\n}\r\n\r\nconst DEFAULTS: PendingState = {\r\n title: 'Replace existing values?',\r\n body: 'This destination already has saved values. Replace them?',\r\n confirmLabel: 'Replace',\r\n cancelLabel: 'Cancel',\r\n};\r\n\r\nexport interface UsePasteConfirmReturn {\r\n confirm: (i18n?: Partial<PendingState>) => Promise<boolean>;\r\n dialog: ReactNode;\r\n}\r\n\r\nexport const usePasteConfirm = (): UsePasteConfirmReturn => {\r\n const [open, setOpen] = useState(false);\r\n const [state, setState] = useState<PendingState>(DEFAULTS);\r\n const resolverRef = useRef<((ok: boolean) => void) | null>(null);\r\n\r\n const confirm = useCallback((i18n?: Partial<PendingState>) => {\r\n setState({ ...DEFAULTS, ...(i18n ?? {}) });\r\n setOpen(true);\r\n return new Promise<boolean>((resolve) => { resolverRef.current = resolve; });\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 // 'discard' is wired as the destructive primary (Replace).\r\n r?.(choice === 'discard');\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 // Hide the third (save) slot by giving it the same handler as cancel\r\n // and a blank label. ConfirmDialog always renders three buttons; we\r\n // pass an empty save label to keep visual parity minimal.\r\n saveLabel=\"\"\r\n discardLabel={state.confirmLabel}\r\n cancelLabel={state.cancelLabel}\r\n onChoice={handleChoice}\r\n />\r\n ),\r\n };\r\n};","// =============================================================================\r\n// useRecordClipboard — in-memory + sessionStorage clipboard scoped per\r\n// (appId, recordType). Powers the shell's Copy / Paste affordance.\r\n//\r\n// One module-level store per (appId, recordType) so all subscribers — the\r\n// editor footer, every row context menu, sibling shell mounts within the\r\n// same host page — react to changes without prop drilling. SessionStorage\r\n// keeps the clipboard alive across host route changes inside the iframe.\r\n// =============================================================================\r\nimport { useCallback, useEffect, useState } from 'react';\r\nimport type { ParsedRef, ScopeKind } from '../types';\r\n\r\nexport interface ClipboardEntry<T = unknown> {\r\n value: T;\r\n sourceScope: ScopeKind | 'collection';\r\n sourceRef: string;\r\n /** Friendly label captured at copy time so paste targets can show\r\n * \"Paste from {sourceLabel}\" without re-fetching the source. */\r\n sourceLabel?: string;\r\n /** ISO timestamp — debug/telemetry only. */\r\n copiedAt: string;\r\n}\r\n\r\ntype Listener = () => void;\r\n\r\ninterface Store {\r\n entry: ClipboardEntry | null;\r\n listeners: Set<Listener>;\r\n}\r\n\r\nconst stores = new Map<string, Store>();\r\nconst storageKey = (key: string) => `ra:clipboard:${key}`;\r\n\r\nconst getStore = (key: string): Store => {\r\n let s = stores.get(key);\r\n if (!s) {\r\n s = { entry: null, listeners: new Set() };\r\n // Hydrate from sessionStorage on first access so the clipboard\r\n // survives host-side route changes within the same browsing session.\r\n if (typeof window !== 'undefined') {\r\n try {\r\n const raw = window.sessionStorage.getItem(storageKey(key));\r\n if (raw) s.entry = JSON.parse(raw) as ClipboardEntry;\r\n } catch { /* sessionStorage may be blocked — fall back to memory only */ }\r\n }\r\n stores.set(key, s);\r\n }\r\n return s;\r\n};\r\n\r\nconst persist = (key: string, entry: ClipboardEntry | null) => {\r\n if (typeof window === 'undefined') return;\r\n try {\r\n if (entry) window.sessionStorage.setItem(storageKey(key), JSON.stringify(entry));\r\n else window.sessionStorage.removeItem(storageKey(key));\r\n } catch { /* ignore quota / disabled storage */ }\r\n};\r\n\r\nconst notify = (store: Store) => {\r\n store.listeners.forEach((l) => l());\r\n};\r\n\r\nexport interface UseRecordClipboardArgs {\r\n /** Required — clipboard is scoped per app to prevent cross-app paste. */\r\n appId: string;\r\n /** Required — also scoped per record type within the app. */\r\n recordType: string;\r\n}\r\n\r\nexport interface UseRecordClipboardReturn<T = unknown> {\r\n entry: ClipboardEntry<T> | null;\r\n hasEntry: boolean;\r\n set: (entry: Omit<ClipboardEntry<T>, 'copiedAt'>) => void;\r\n clear: () => void;\r\n}\r\n\r\nconst composeKey = (appId: string, recordType: string) => `${appId}::${recordType}`;\r\n\r\nexport function useRecordClipboard<T = unknown>(\r\n args: UseRecordClipboardArgs,\r\n): UseRecordClipboardReturn<T> {\r\n const key = composeKey(args.appId, args.recordType);\r\n const store = getStore(key);\r\n const [entry, setEntry] = useState<ClipboardEntry<T> | null>(\r\n store.entry as ClipboardEntry<T> | null,\r\n );\r\n\r\n useEffect(() => {\r\n const listener: Listener = () => setEntry(store.entry as ClipboardEntry<T> | null);\r\n store.listeners.add(listener);\r\n // Sync immediately in case the store changed between render and effect.\r\n listener();\r\n return () => { store.listeners.delete(listener); };\r\n }, [store]);\r\n\r\n const set = useCallback((next: Omit<ClipboardEntry<T>, 'copiedAt'>) => {\r\n const full: ClipboardEntry<T> = { ...next, copiedAt: new Date().toISOString() };\r\n store.entry = full as ClipboardEntry;\r\n persist(key, full as ClipboardEntry);\r\n notify(store);\r\n }, [store, key]);\r\n\r\n const clear = useCallback(() => {\r\n store.entry = null;\r\n persist(key, null);\r\n notify(store);\r\n }, [store, key]);\r\n\r\n return { entry, hasEntry: entry != null, set, clear };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Cross-scope paste rules — matches the proposal's table.\r\n// ---------------------------------------------------------------------------\r\nexport type PasteCompatibility = 'allowed' | 'warn' | 'denied';\r\n\r\nexport interface PasteCompatibilityResult {\r\n status: PasteCompatibility;\r\n /** Optional short reason — surfaced as a tooltip on the Paste button. */\r\n reason?: string;\r\n}\r\n\r\n/** Sane defaults — host can override entirely via `onPaste` returning null. */\r\nexport function checkPasteCompatibility(\r\n source: ParsedRef,\r\n destination: ParsedRef,\r\n): PasteCompatibilityResult {\r\n const from = source.kind;\r\n const to = destination.kind;\r\n\r\n // Same-kind paste is always allowed (the 99% case).\r\n if (from === to) return { status: 'allowed' };\r\n\r\n // Variant/batch → product is allowed but warns: a sub-scope value is\r\n // about to override the parent's value for *all* variants/batches.\r\n if ((from === 'variant' || from === 'batch') && to === 'product') {\r\n return { status: 'warn', reason: 'This will overwrite product-level values.' };\r\n }\r\n\r\n // All remaining cross-scope pastes from the proposal table are allowed.\r\n return { status: 'allowed' };\r\n}\r\n\r\n/** Deep clone — uses `structuredClone` when available, JSON fallback otherwise. */\r\nexport function cloneValue<T>(value: T): T {\r\n if (value == null) return value;\r\n try { return structuredClone(value); }\r\n catch {\r\n try { return JSON.parse(JSON.stringify(value)) as T; }\r\n catch { return value; }\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 collection: 'Global',\r\n product: 'Products',\r\n facet: 'Shared',\r\n variant: 'Variants',\r\n batch: 'Batches',\r\n rule: 'Rules',\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};","// =============================================================================\r\n// StatusIcon — bigger, coloured replacement for the old `<StatusDot>`.\r\n// Uses the icons declared in `DEFAULT_ICONS.status` (CheckCircle2 /\r\n// ArrowDownLeft / CircleDashed) with semantic tones from tokens.css so the\r\n// rail communicates state at a glance rather than via a tiny grey dot.\r\n// =============================================================================\r\nimport type { RecordSource, RecordStatus } from '../types';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nexport type StatusTone = 'own' | 'shared' | 'missing';\r\n\r\nconst resolveTone = (\r\n source?: RecordSource, status?: RecordStatus,\r\n): StatusTone => {\r\n if (source === 'self' || status === 'configured') return 'own';\r\n if (source === 'inherited' || status === 'partial') return 'shared';\r\n return 'missing';\r\n};\r\n\r\ninterface Props {\r\n source?: RecordSource;\r\n status?: RecordStatus;\r\n className?: string;\r\n /** Override icon size (default 1.05rem). */\r\n size?: string;\r\n /** Optional accessible label — defaults to the tone name. */\r\n label?: string;\r\n}\r\n\r\nexport const StatusIcon = ({ source, status, className, size = '1.05rem', label }: Props) => {\r\n const tone = resolveTone(source, status);\r\n const Icon = DEFAULT_ICONS.status[tone === 'own' ? 'own'\r\n : tone === 'shared' ? 'inherited'\r\n : 'missing'];\r\n return (\r\n <span\r\n className={cn('ra-status-icon', `ra-status-icon--${tone}`, className)}\r\n style={{ width: size, height: size }}\r\n role={label ? 'img' : undefined}\r\n aria-label={label}\r\n aria-hidden={label ? undefined : 'true'}\r\n >\r\n <Icon className=\"w-full h-full\" />\r\n </span>\r\n );\r\n};\r\n\r\n/** Short label rendered next to / under the row title. */\r\nexport const statusToneLabel = (tone: StatusTone): string => {\r\n if (tone === 'own') return 'Configured';\r\n if (tone === 'shared') return 'Inherited';\r\n return 'Empty';\r\n};\r\n\r\nexport { resolveTone };","// =============================================================================\r\n// RowContextMenu — kebab-triggered menu surfaced on every record row/card\r\n// when the host enables clipboard. Renders Copy / Paste and short-circuits\r\n// when neither is available so empty menus never appear.\r\n// =============================================================================\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { MoreHorizontal, Copy, ClipboardPaste } from 'lucide-react';\r\n\r\nexport interface RowContextMenuProps {\r\n onCopy?: () => void;\r\n onPaste?: () => void;\r\n canPaste?: boolean;\r\n pasteWillReplace?: boolean;\r\n pasteSourceLabel?: string;\r\n i18n: {\r\n copy: string;\r\n paste: string;\r\n pasteFrom: string;\r\n pasteReplace: string;\r\n clipboardEmpty: string;\r\n };\r\n}\r\n\r\nexport const RowContextMenu = ({\r\n onCopy, onPaste, canPaste, pasteWillReplace, pasteSourceLabel, i18n,\r\n}: RowContextMenuProps) => {\r\n const [open, setOpen] = useState(false);\r\n const wrapperRef = useRef<HTMLDivElement>(null);\r\n\r\n // Click-outside / Escape close.\r\n useEffect(() => {\r\n if (!open) return;\r\n const onDoc = (e: MouseEvent) => {\r\n if (!wrapperRef.current?.contains(e.target as Node)) setOpen(false);\r\n };\r\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); };\r\n document.addEventListener('mousedown', onDoc);\r\n document.addEventListener('keydown', onKey);\r\n return () => {\r\n document.removeEventListener('mousedown', onDoc);\r\n document.removeEventListener('keydown', onKey);\r\n };\r\n }, [open]);\r\n\r\n if (!onCopy && !onPaste) return null;\r\n\r\n const pasteLabel = !canPaste\r\n ? i18n.clipboardEmpty\r\n : pasteSourceLabel\r\n ? i18n.pasteFrom.replace('{name}', pasteSourceLabel)\r\n : pasteWillReplace\r\n ? i18n.pasteReplace\r\n : i18n.paste;\r\n\r\n return (\r\n <div ref={wrapperRef} className=\"ra-row-menu-wrap relative\">\r\n <button\r\n type=\"button\"\r\n className=\"ra-row-menu-trigger\"\r\n aria-label=\"Row actions\"\r\n aria-haspopup=\"menu\"\r\n aria-expanded={open}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n setOpen((v) => !v);\r\n }}\r\n >\r\n <MoreHorizontal className=\"w-3.5 h-3.5\" aria-hidden=\"true\" />\r\n </button>\r\n {open && (\r\n <div role=\"menu\" className=\"ra-row-menu\" onClick={(e) => e.stopPropagation()}>\r\n {onCopy && (\r\n <button\r\n type=\"button\"\r\n role=\"menuitem\"\r\n className=\"ra-row-menu-item\"\r\n onClick={(e) => { e.stopPropagation(); setOpen(false); onCopy(); }}\r\n >\r\n <Copy className=\"w-3 h-3\" aria-hidden=\"true\" />\r\n <span>{i18n.copy}</span>\r\n </button>\r\n )}\r\n {onPaste && (\r\n <button\r\n type=\"button\"\r\n role=\"menuitem\"\r\n className=\"ra-row-menu-item\"\r\n disabled={!canPaste}\r\n onClick={(e) => { e.stopPropagation(); setOpen(false); if (canPaste) onPaste(); }}\r\n >\r\n <ClipboardPaste className=\"w-3 h-3\" aria-hidden=\"true\" />\r\n <span className=\"truncate\">{pasteLabel}</span>\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// formatFacetRule — render a FacetRule as a compact human-readable string for\r\n// list rows and headers. Falls back to keys when the host hasn't passed in a\r\n// facet vocabulary, so the output is always at least debuggable.\r\n//\r\n// Examples:\r\n// { all: [{ facetKey: 'category', anyOf: ['premium'] }] }\r\n// → 'category = premium'\r\n// { all: [{ facetKey: 'region', anyOf: ['EU','UK'] },\r\n// { facetKey: 'tier', anyOf: ['gold'] }] }\r\n// → 'region ∈ {EU, UK} AND tier = gold'\r\n// =============================================================================\r\nimport type { FacetRule } from '../data/sdkTypes';\r\n\r\nexport function formatFacetRule(rule: FacetRule | null | undefined): string | null {\r\n if (!rule || !rule.all || rule.all.length === 0) return null;\r\n const parts = rule.all.map((c) => {\r\n const vals = (c.anyOf ?? []).filter(Boolean);\r\n if (vals.length === 0) return `${c.facetKey} (no values)`;\r\n if (vals.length === 1) return `${c.facetKey} = ${vals[0]}`;\r\n return `${c.facetKey} ∈ {${vals.join(', ')}}`;\r\n });\r\n return parts.join(' AND ');\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 { StatusIcon, resolveTone, statusToneLabel } from './StatusIcon';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\nimport { cn } from '../../../utils/cn';\r\nimport { RowContextMenu } from './RowContextMenu';\r\nimport { DEFAULT_I18N } from '../types';\r\nimport { formatFacetRule } from './formatFacetRule';\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, onCopy, onPaste, canPaste, pasteWillReplace, clipboardSourceLabel } = 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 const tone = resolveTone(undefined, record.status);\r\n // Friendly subtitle. Priority:\r\n // 1. App-supplied subtitle (SKU, scope, etc.).\r\n // 2. Rule summary for facetRule records (\"category=premium AND region=EU\").\r\n // 3. Status hint as a last resort.\r\n const ruleSummary = formatFacetRule(record.facetRule);\r\n const subtitle = record.subtitle ?? ruleSummary ?? (tone === 'missing'\r\n ? 'Empty — needs values'\r\n : tone === 'own' ? 'Configured' : 'Inherited');\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 data-tone={tone}\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-status\" aria-hidden=\"true\">\r\n <StatusIcon\r\n status={record.status}\r\n label={statusToneLabel(tone)}\r\n />\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 && (\r\n <div className=\"ra-row-sub\">{subtitle}</div>\r\n )}\r\n </div>\r\n {/* compact rows still get a tiny status icon trailing the title */}\r\n {compact && (\r\n <StatusIcon status={record.status} size=\"0.85rem\" />\r\n )}\r\n {/* scope icon trails the row so the rail doesn't lose context */}\r\n {!compact && record.scope.kind && record.scope.kind !== 'collection' && (\r\n <span className=\"ra-row-scope\" aria-hidden=\"true\">\r\n <ScopeIcon className=\"w-3 h-3\" />\r\n </span>\r\n )}\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-dirty-pip\"\r\n />\r\n )}\r\n {(onCopy || onPaste) && (\r\n <RowContextMenu\r\n onCopy={onCopy}\r\n onPaste={onPaste}\r\n canPaste={canPaste}\r\n pasteWillReplace={pasteWillReplace}\r\n pasteSourceLabel={clipboardSourceLabel}\r\n i18n={{\r\n copy: DEFAULT_I18N.copy,\r\n paste: DEFAULT_I18N.paste,\r\n pasteFrom: DEFAULT_I18N.pasteFrom,\r\n pasteReplace: DEFAULT_I18N.pasteReplace,\r\n clipboardEmpty: DEFAULT_I18N.clipboardEmpty,\r\n }}\r\n />\r\n )}\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 { 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 /** Rail row density. Defaults to `list`. */\r\n presentation?: RecordPresentation;\r\n /** Optional custom row renderer (still dense — applied to both densities). */\r\n renderListRow?: (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 * Optional clipboard wiring per row. When provided the shell's Copy /\r\n * Paste affordance appears in each row's context menu. Returning `null`\r\n * for a row hides the menu for that row.\r\n */\r\n rowClipboard?: (record: RecordSummary) => {\r\n onCopy?: () => void;\r\n onPaste?: () => void;\r\n canPaste?: boolean;\r\n pasteWillReplace?: boolean;\r\n clipboardSourceLabel?: string;\r\n } | 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, groupBy, rowClipboard,\r\n}: Props) => {\r\n const buildCtx = (item: RecordSummary): RecordSlotContext => {\r\n const cb = rowClipboard ? rowClipboard(item) : null;\r\n return {\r\n selected: item.ref === selectedRef,\r\n onSelect: () => onSelect(item),\r\n isDirty: !!dirtyRef && item.ref === dirtyRef,\r\n ...(cb ?? {}),\r\n };\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 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 { List, 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 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 '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, ItemView } from '../types';\r\n\r\nconst KEY_PREFIX = 'smartlinks-ui:records-admin:presentation';\r\nconst ITEM_VIEW_KEY_PREFIX = 'smartlinks-ui:records-admin:item-view';\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}\r\n\r\n/**\r\n * Twin of `usePresentationPref` for the right-pane item view (collection\r\n * cardinality only). Stored under a distinct key so toggling the rail\r\n * presentation never clobbers the table/cards/gallery preference.\r\n */\r\nexport function useItemViewPref(args: {\r\n appId: string;\r\n recordType?: string;\r\n options: ItemView[];\r\n defaultValue: ItemView;\r\n}): [ItemView, (next: ItemView) => void] {\r\n const { appId, recordType, options, defaultValue } = args;\r\n const key = `${ITEM_VIEW_KEY_PREFIX}:${appId}:${recordType ?? '_default'}`;\r\n\r\n const initial = (): ItemView => {\r\n const stored = safeRead(key) as ItemView | 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<ItemView>(initial);\r\n\r\n useEffect(() => {\r\n if (!options.includes(value)) setValue(options[0]);\r\n }, [options, value]);\r\n\r\n const set = useCallback((next: ItemView) => {\r\n setValue(next);\r\n safeWrite(key, next);\r\n }, [key]);\r\n\r\n return [value, set];\r\n}","// =============================================================================\r\n// useCollectionItems — list every item-cardinality record under a given scope.\r\n//\r\n// Powers the right-pane multi-item view (collection mode). Items are records\r\n// whose `ref` ends with `.../item:{itemId}` — they belong to the surrounding\r\n// scope but are individually addressable.\r\n//\r\n// Backed by `SL.app.records.list` with a `refPrefix` so we only round-trip\r\n// the slice we need. The hook keeps the result shape aligned with\r\n// `RecordSummary` so it slots straight into the existing list/table renderers.\r\n// =============================================================================\r\nimport { useMemo, useCallback } from 'react';\r\nimport { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';\r\nimport type { ParsedRef, RecordSummary } from '../types';\r\nimport { listRecords, type RecordsCtx } from '../data/records';\r\nimport type { AppRecord } from '../data/sdkTypes';\r\nimport { parseRef, splitItemRef } from '../data/refs';\r\n\r\nexport interface UseCollectionItemsArgs {\r\n ctx: RecordsCtx;\r\n /**\r\n * Scope the items live under. Items at the collection root pass an empty\r\n * `scope.raw` (the hook then uses `refPrefix: 'item:'`). Pass `null` to\r\n * keep the query disabled.\r\n */\r\n scope: ParsedRef | null;\r\n /** Per-page size requested from the SDK (default 100). */\r\n pageSize?: number;\r\n /**\r\n * Optional projector that derives the row label / subtitle / thumbnail\r\n * from a record's `data`. Falls back to the itemId.\r\n */\r\n toSummary?: (rec: AppRecord, base: RecordSummary) => RecordSummary;\r\n /** When false, the query is paused (used while the host is still booting). */\r\n enabled?: boolean;\r\n}\r\n\r\nconst QK_BASE = ['records-admin', 'collection-items'] as const;\r\n\r\nconst defaultToSummary = (rec: AppRecord, base: RecordSummary): RecordSummary => {\r\n const data = rec.data as Record<string, unknown> | null | undefined;\r\n if (!data) return base;\r\n // Try a few common label-shaped keys without forcing a schema on hosts.\r\n const label =\r\n (data.title as string | undefined) ??\r\n (data.name as string | undefined) ??\r\n (data.label as string | undefined) ??\r\n (data.question as string | undefined) ??\r\n base.label;\r\n const subtitle =\r\n (data.subtitle as string | undefined) ??\r\n (data.summary as string | undefined) ??\r\n (data.description as string | undefined) ??\r\n base.subtitle;\r\n const thumbnail =\r\n (data.thumbnail as string | undefined) ??\r\n (data.image as string | undefined) ??\r\n (data.cover as string | undefined) ??\r\n base.thumbnail;\r\n return { ...base, label, subtitle, thumbnail };\r\n};\r\n\r\n/**\r\n * The shell's `useRecordList` filters by *scope kind*, which doesn't\r\n * differentiate items from singletons. This hook intentionally bypasses\r\n * that filter and asks for refs under a precise prefix.\r\n */\r\nexport function useCollectionItems<T = unknown>(args: UseCollectionItemsArgs) {\r\n const {\r\n ctx, scope, pageSize = 100, toSummary = defaultToSummary, enabled = true,\r\n } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const scopeRef = scope?.raw ?? '';\r\n // `item:` is the prefix at the collection root; everywhere else it's\r\n // `{scopeRef}/item:`. Either way the SDK matches refs starting with this.\r\n const refPrefix = scopeRef ? `${scopeRef}/item:` : 'item:';\r\n\r\n const queryKey = useMemo(\r\n () => [...QK_BASE, ctx.collectionId, ctx.appId, ctx.recordType, scopeRef],\r\n [ctx.collectionId, ctx.appId, ctx.recordType, scopeRef],\r\n );\r\n\r\n const query = useInfiniteQuery({\r\n queryKey,\r\n enabled: enabled && !!scope,\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, {\r\n limit: pageSize,\r\n offset,\r\n refPrefix,\r\n });\r\n return { data, total, hasMore, nextOffset: offset + data.length };\r\n },\r\n getNextPageParam: (last) => (last.hasMore ? last.nextOffset : undefined),\r\n staleTime: 15_000,\r\n });\r\n\r\n const items: RecordSummary<T>[] = useMemo(() => {\r\n const all = query.data?.pages.flatMap((p) => p.data) ?? [];\r\n return all\r\n .map((rec): RecordSummary<T> | null => {\r\n const ref = rec.ref ?? '';\r\n const parsed = parseRef(ref);\r\n const { itemId } = splitItemRef(ref);\r\n // Defensive — `refPrefix` should already exclude non-item refs, but\r\n // a server quirk shouldn't be allowed to crash the table.\r\n if (!itemId) return null;\r\n const base: RecordSummary<T> = {\r\n id: rec.id,\r\n ref,\r\n scope: parsed,\r\n data: (rec.data ?? null) as T | null,\r\n status: rec.data ? 'configured' : 'empty',\r\n label: itemId,\r\n updatedAt: rec.updatedAt,\r\n itemId,\r\n };\r\n return toSummary(rec, base as RecordSummary) as RecordSummary<T>;\r\n })\r\n .filter((x): x is RecordSummary<T> => x !== null);\r\n }, [query.data, toSummary]);\r\n\r\n const refetch = useCallback(() => {\r\n queryClient.invalidateQueries({ queryKey });\r\n }, [queryClient, queryKey]);\r\n\r\n return {\r\n items,\r\n total: query.data?.pages[query.data.pages.length - 1]?.total ?? items.length,\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// Default DeepLinkAdapter — `window.location` + `window.history`.\r\n//\r\n// Handles both regular search-string routing (`/admin?item=x`) and hash\r\n// routing (`/#/admin?item=x`) by reading whichever side carries the query\r\n// and writing back to the same one. Hosts that own routing (React Router,\r\n// SmartLinks `persistentQueryParams`, etc.) should plug in their own\r\n// adapter instead.\r\n// =============================================================================\r\nimport type {\r\n DeepLinkAdapter, DeepLinkState, ResolvedDeepLinkParamNames,\r\n} from '../types/deepLink';\r\n\r\n/** Find the query string the host is using, if any. */\r\nconst findQueryHost = (loc: Location): 'search' | 'hash' => {\r\n // Search wins when both are present — that's the conventional setup.\r\n if (loc.search && loc.search.length > 1) return 'search';\r\n if (loc.hash && loc.hash.includes('?')) return 'hash';\r\n return 'search';\r\n};\r\n\r\nconst getQueryString = (loc: Location): string => {\r\n const host = findQueryHost(loc);\r\n if (host === 'search') return loc.search.startsWith('?') ? loc.search.slice(1) : loc.search;\r\n const idx = loc.hash.indexOf('?');\r\n return idx >= 0 ? loc.hash.slice(idx + 1) : '';\r\n};\r\n\r\nconst buildUrl = (loc: Location, nextQuery: string): string => {\r\n const host = findQueryHost(loc);\r\n const qs = nextQuery ? `?${nextQuery}` : '';\r\n if (host === 'search') {\r\n return `${loc.pathname}${qs}${loc.hash}`;\r\n }\r\n // Hash routing — reconstruct hash with new query while preserving the\r\n // hash path (everything before `?`).\r\n const hashPath = loc.hash.includes('?')\r\n ? loc.hash.slice(0, loc.hash.indexOf('?'))\r\n : loc.hash;\r\n return `${loc.pathname}${loc.search}${hashPath}${qs}`;\r\n};\r\n\r\nexport const createDefaultDeepLinkAdapter = (\r\n paramNames: ResolvedDeepLinkParamNames,\r\n): DeepLinkAdapter => ({\r\n read(): DeepLinkState {\r\n if (typeof window === 'undefined') return {};\r\n const params = new URLSearchParams(getQueryString(window.location));\r\n return {\r\n item: params.get(paramNames.item),\r\n scope: params.get(paramNames.scope),\r\n view: params.get(paramNames.view),\r\n };\r\n },\r\n\r\n write(partial, mode) {\r\n if (typeof window === 'undefined') return;\r\n const params = new URLSearchParams(getQueryString(window.location));\r\n const apply = (key: string, value: string | null | undefined) => {\r\n if (value == null || value === '') params.delete(key);\r\n else params.set(key, value);\r\n };\r\n if ('item' in partial) apply(paramNames.item, partial.item);\r\n if ('scope' in partial) apply(paramNames.scope, partial.scope);\r\n if ('view' in partial) apply(paramNames.view, partial.view);\r\n\r\n const nextUrl = buildUrl(window.location, params.toString());\r\n if (mode === 'push') window.history.pushState({}, '', nextUrl);\r\n else window.history.replaceState({}, '', nextUrl);\r\n },\r\n\r\n subscribe(listener) {\r\n if (typeof window === 'undefined') return () => {};\r\n // `popstate` covers back/forward. `hashchange` covers hash-routed hosts.\r\n window.addEventListener('popstate', listener);\r\n window.addEventListener('hashchange', listener);\r\n return () => {\r\n window.removeEventListener('popstate', listener);\r\n window.removeEventListener('hashchange', listener);\r\n };\r\n },\r\n});","// =============================================================================\r\n// useDeepLinkState — bridge between the shell's runtime state and a URL\r\n// adapter. Returns:\r\n//\r\n// - `urlState` — last-read snapshot from the adapter (refreshed on\r\n// subscribe events).\r\n// - `emit` — write helper. Auto-classifies into push/replace based on\r\n// the configured history mode; callers can override.\r\n//\r\n// Intentionally framework-agnostic — no React Router, no platform SDK.\r\n// Hosts plug their own routing in via `DeepLinkAdapter`.\r\n// =============================================================================\r\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\r\nimport type {\r\n DeepLinkAdapter, DeepLinkOptions, DeepLinkState, DeepLinkHistoryMode,\r\n ResolvedDeepLinkParamNames,\r\n} from '../types/deepLink';\r\nimport { DEFAULT_DEEP_LINK_PARAM_NAMES } from '../types/deepLink';\r\nimport { createDefaultDeepLinkAdapter } from '../data/deepLinkAdapter';\r\n\r\n/**\r\n * Which logical changes are \"meaningful navigation\" (push) vs \"cosmetic /\r\n * incremental\" (replace) under `'smart'` history mode. The shell tags each\r\n * emit with one of these.\r\n */\r\nexport type DeepLinkChangeKind =\r\n | 'item.open' // user opened a different item (push)\r\n | 'item.close' // user backed out to the list (push)\r\n | 'item.step' // prev/next sibling navigation (replace)\r\n | 'scope' // scope tab / facet / product change (push)\r\n | 'view'; // table/cards/gallery toggle (replace)\r\n\r\nconst SMART_PUSH: DeepLinkChangeKind[] = ['item.open', 'item.close', 'scope'];\r\n\r\nconst classify = (\r\n mode: DeepLinkHistoryMode,\r\n kind: DeepLinkChangeKind,\r\n): 'push' | 'replace' => {\r\n if (mode === 'push') return 'push';\r\n if (mode === 'replace') return 'replace';\r\n return SMART_PUSH.includes(kind) ? 'push' : 'replace';\r\n};\r\n\r\nexport interface UseDeepLinkStateResult {\r\n /** Latest snapshot read from the adapter. */\r\n urlState: DeepLinkState;\r\n /**\r\n * Push a partial update through the adapter. `kind` informs the\r\n * push-vs-replace decision under `'smart'` mode.\r\n */\r\n emit: (partial: DeepLinkState, kind: DeepLinkChangeKind) => void;\r\n /** Resolved param names for callers that need them. */\r\n paramNames: ResolvedDeepLinkParamNames;\r\n /** True when deep linking is active (host opted in + we have an adapter). */\r\n enabled: boolean;\r\n}\r\n\r\nexport function useDeepLinkState(\r\n options: DeepLinkOptions | undefined,\r\n): UseDeepLinkStateResult {\r\n const enabled = !!options?.enabled;\r\n const history = options?.history ?? 'smart';\r\n\r\n const paramNames: ResolvedDeepLinkParamNames = useMemo(() => ({\r\n ...DEFAULT_DEEP_LINK_PARAM_NAMES,\r\n ...(options?.paramNames ?? {}),\r\n }), [options?.paramNames]);\r\n\r\n // Default adapter is created lazily and once — host-supplied adapters win\r\n // when present and re-created if the host swaps them.\r\n const defaultAdapterRef = useRef<DeepLinkAdapter | null>(null);\r\n const adapter: DeepLinkAdapter | null = useMemo(() => {\r\n if (!enabled) return null;\r\n if (options?.adapter) return options.adapter;\r\n if (!defaultAdapterRef.current) {\r\n defaultAdapterRef.current = createDefaultDeepLinkAdapter(paramNames);\r\n }\r\n return defaultAdapterRef.current;\r\n }, [enabled, options?.adapter, paramNames]);\r\n\r\n const [urlState, setUrlState] = useState<DeepLinkState>(() =>\r\n adapter ? adapter.read() : {},\r\n );\r\n\r\n // Re-read on external changes (back/forward, host-driven nav).\r\n useEffect(() => {\r\n if (!adapter) return;\r\n setUrlState(adapter.read());\r\n return adapter.subscribe(() => setUrlState(adapter.read()));\r\n }, [adapter]);\r\n\r\n const emit = useCallback((partial: DeepLinkState, kind: DeepLinkChangeKind) => {\r\n if (!adapter) return;\r\n const mode = classify(history, kind);\r\n adapter.write(partial, mode);\r\n // Optimistically refresh — most adapters won't fire a synchronous\r\n // subscribe event for self-initiated writes.\r\n setUrlState((prev) => ({ ...prev, ...partial }));\r\n }, [adapter, history]);\r\n\r\n return { urlState, emit, paramNames, enabled };\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// StatusDot — legacy tiny dot. Kept for back-compat with custom row renderers\r\n// that still target it by class. New default rows use `<StatusIcon>` instead.\r\n// =============================================================================\r\nimport 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// 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, type ComponentType } 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 * Optional icon override for the resting state. Defaults to Lucide\r\n * `Trash2`. The confirm-state icon stays `Trash2` so the destructive\r\n * intent reads consistently regardless of the host's branding.\r\n */\r\n icon?: ComponentType<{ className?: string }>;\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 icon,\r\n}: DeleteButtonProps) => {\r\n const Icon = icon ?? Trash2;\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 <Icon className=\"w-3.5 h-3.5\" />\r\n {label}\r\n </button>\r\n );\r\n};","import type { ReactNode } from 'react';\r\nimport { Copy, ClipboardPaste } from 'lucide-react';\r\nimport type { EditorContext, RecordsAdminI18n } from '../types';\r\nimport type { RecordsAdminActionIcon, RecordsAdminActionKey } from '../types/shell';\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 * Clipboard footer actions. The shell wires these when `enableClipboard`\r\n * is on. Copy is always offered when there's an editing scope; Paste is\r\n * disabled when the clipboard is empty or the cross-scope rules deny it.\r\n */\r\n clipboard?: {\r\n onCopy: () => void;\r\n onPaste: () => void;\r\n canCopy: boolean;\r\n canPaste: boolean;\r\n pasteSourceLabel?: string;\r\n pasteWillReplace?: boolean;\r\n };\r\n /** Host-provided labels for save / discard / delete (resting state only). */\r\n actionLabels?: Partial<Record<RecordsAdminActionKey, string>>;\r\n /** Host-provided icons rendered before save / discard / delete labels. */\r\n actionIcons?: Partial<Record<RecordsAdminActionKey, RecordsAdminActionIcon>>;\r\n}\r\n\r\nexport function RecordEditor<T>({\r\n ctx, i18n, children, preview, bulkActions, footerExtra, onBeforeDelete,\r\n headerLabel, headerSubtitle, headerMeta, clipboard, actionLabels, actionIcons,\r\n}: Props<T>) {\r\n const saveLabel = actionLabels?.save ?? i18n.save;\r\n const discardLabel = actionLabels?.discard ?? i18n.discard;\r\n const deleteLabel = actionLabels?.delete ?? i18n.delete;\r\n const SaveIcon = actionIcons?.save;\r\n const DiscardIcon = actionIcons?.discard;\r\n const DeleteIcon = actionIcons?.delete;\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))] inline-flex items-center gap-1.5\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n {DiscardIcon && <DiscardIcon className=\"h-4 w-4\" />}\r\n {discardLabel}\r\n </button>\r\n {ctx.canRemove && (\r\n <DeleteButton\r\n onConfirm={() => ctx.remove()}\r\n onBeforeDelete={onBeforeDelete}\r\n label={deleteLabel}\r\n confirmLabel={i18n.confirmDelete}\r\n icon={DeleteIcon}\r\n />\r\n )}\r\n {clipboard && (\r\n <>\r\n <button\r\n type=\"button\"\r\n onClick={clipboard.onCopy}\r\n disabled={!clipboard.canCopy || !!ctx.isSaving}\r\n title={i18n.copy}\r\n aria-label={i18n.copy}\r\n className=\"text-xs px-2.5 py-1.5 rounded-md border transition-opacity disabled:opacity-40 hover:bg-[hsl(var(--ra-muted))] inline-flex items-center gap-1.5\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n <Copy className=\"w-3 h-3\" />\r\n {i18n.copy}\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={clipboard.onPaste}\r\n disabled={!clipboard.canPaste || !!ctx.isSaving}\r\n title={\r\n !clipboard.canPaste\r\n ? i18n.clipboardEmpty\r\n : clipboard.pasteSourceLabel\r\n ? i18n.pasteFrom.replace('{name}', clipboard.pasteSourceLabel)\r\n : i18n.paste\r\n }\r\n aria-label={i18n.paste}\r\n className=\"text-xs px-2.5 py-1.5 rounded-md border transition-opacity disabled:opacity-40 hover:bg-[hsl(var(--ra-muted))] inline-flex items-center gap-1.5\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n <ClipboardPaste className=\"w-3 h-3\" />\r\n {clipboard.pasteWillReplace ? i18n.pasteReplace : i18n.paste}\r\n </button>\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 inline-flex items-center gap-1.5\"\r\n style={{ background: 'hsl(var(--ra-accent))', color: 'hsl(var(--ra-surface))' }}\r\n >\r\n {SaveIcon && !ctx.isSaving && <SaveIcon className=\"h-4 w-4\" />}\r\n {ctx.isSaving ? (i18n.saving ?? 'Saving…') : saveLabel}\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 * When true, the drill-down tab strip is hidden even when only the\r\n * `product` tab would render (i.e. no variants / batches). The editor\r\n * header below already names the record so the single-tab strip is\r\n * redundant. The strip still appears whenever variants or batches are\r\n * available — at that point it's a real navigational choice.\r\n */\r\n hideSingleTab?: boolean;\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, hideSingleTab,\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 const showTabStrip = tabs.length > 1 || !hideSingleTab;\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 — hidden when only `product` is available\r\n and the host opts into `hideSingleTab`. */}\r\n {showTabStrip && (\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\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// ItemViewSwitcher — three-way segmented control for the right-pane item view.\r\n// Mirrors `PresentationSwitcher` but for `ItemView` (table / cards / gallery).\r\n// Hidden when fewer than two options are offered.\r\n// =============================================================================\r\nimport { Table as TableIcon, LayoutGrid, Image as ImageIcon } from 'lucide-react';\r\nimport type { ItemView, RecordsAdminI18n } from '../types';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nconst ICONS: Record<ItemView, typeof TableIcon> = {\r\n table: TableIcon,\r\n cards: LayoutGrid,\r\n gallery: ImageIcon,\r\n};\r\n\r\ninterface Props {\r\n options: ItemView[];\r\n value: ItemView;\r\n onChange: (next: ItemView) => void;\r\n i18n: Pick<RecordsAdminI18n, 'itemViewTable' | 'itemViewCards' | 'itemViewGallery'>;\r\n}\r\n\r\nconst labelFor = (v: ItemView, i18n: Props['i18n']): string => {\r\n if (v === 'table') return i18n.itemViewTable;\r\n if (v === 'cards') return i18n.itemViewCards;\r\n return i18n.itemViewGallery;\r\n};\r\n\r\nexport const ItemViewSwitcher = ({ options, value, onChange, i18n }: Props) => {\r\n if (options.length < 2) return null;\r\n return (\r\n <div role=\"tablist\" className=\"ra-tabs\" aria-label=\"Item view\" style={{ padding: '0.15rem' }}>\r\n {options.map((opt) => {\r\n const Icon = ICONS[opt];\r\n const active = value === opt;\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 onClick={() => onChange(opt)}\r\n className=\"ra-tab\"\r\n title={labelFor(opt, i18n)}\r\n style={{ padding: '0.3rem 0.55rem' }}\r\n >\r\n <Icon className={cn('ra-tab-icon w-3.5 h-3.5')} />\r\n <span className=\"sr-only\">{labelFor(opt, i18n)}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// DefaultItemTable — built-in `table` view for the right-pane item list.\r\n//\r\n// Renders the host's `itemColumns` when supplied; falls back to a single\r\n// label / updated / actions column so collection-mode apps that don't pass\r\n// columns still get a usable list.\r\n// =============================================================================\r\nimport type { ItemColumn, RecordSummary, RecordsAdminI18n } from '../types';\r\nimport { Pencil, Trash2 } from 'lucide-react';\r\n\r\ninterface Props<T> {\r\n items: RecordSummary<T>[];\r\n columns?: ItemColumn<T>[];\r\n selectedId?: string;\r\n onOpen: (itemId: string) => void;\r\n onDelete: (itemId: string) => void;\r\n i18n: Pick<RecordsAdminI18n,\r\n | 'itemColumnLabel' | 'itemColumnUpdated' | 'itemActions' | 'delete'\r\n >;\r\n}\r\n\r\nconst formatDate = (iso?: string): string => {\r\n if (!iso) return '—';\r\n try {\r\n const d = new Date(iso);\r\n return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\r\n } catch { return iso; }\r\n};\r\n\r\nexport function DefaultItemTable<T>({\r\n items, columns, selectedId, onOpen, onDelete, i18n,\r\n}: Props<T>) {\r\n const cols = columns ?? [];\r\n const useFallback = cols.length === 0;\r\n\r\n return (\r\n <div className=\"ra-item-table-wrap\">\r\n <table className=\"ra-item-table\">\r\n <thead>\r\n <tr>\r\n {useFallback ? (\r\n <>\r\n <th>{i18n.itemColumnLabel}</th>\r\n <th style={{ width: '12rem' }}>{i18n.itemColumnUpdated}</th>\r\n </>\r\n ) : cols.map((c) => (\r\n <th key={c.key} style={{ width: c.width, textAlign: c.align ?? 'left' }}>\r\n {c.header}\r\n </th>\r\n ))}\r\n <th\r\n style={{ width: '6.5rem', textAlign: 'right' }}\r\n aria-label={i18n.itemActions}\r\n />\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {items.map((item) => {\r\n const id = item.itemId ?? '';\r\n const isSelected = !!selectedId && selectedId === id;\r\n return (\r\n <tr\r\n key={item.ref}\r\n data-selected={isSelected}\r\n onClick={() => onOpen(id)}\r\n className=\"ra-item-row\"\r\n >\r\n {useFallback ? (\r\n <>\r\n <td>\r\n <div className=\"ra-item-row-title\">{item.label}</div>\r\n {item.subtitle && (\r\n <div className=\"ra-item-row-sub\">{item.subtitle}</div>\r\n )}\r\n </td>\r\n <td className=\"ra-item-row-meta\">{formatDate(item.updatedAt)}</td>\r\n </>\r\n ) : cols.map((c) => (\r\n <td key={c.key} style={{ textAlign: c.align ?? 'left' }}>\r\n {c.render(item)}\r\n </td>\r\n ))}\r\n <td className=\"ra-item-row-actions\">\r\n <button\r\n type=\"button\"\r\n className=\"ra-row-action\"\r\n onClick={(e) => { e.stopPropagation(); onOpen(id); }}\r\n aria-label=\"Edit\"\r\n >\r\n <Pencil className=\"w-3.5 h-3.5\" />\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-row-action\"\r\n data-tone=\"danger\"\r\n onClick={(e) => { e.stopPropagation(); onDelete(id); }}\r\n aria-label={i18n.delete}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n </button>\r\n </td>\r\n </tr>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// DefaultItemCards — built-in `cards` and `gallery` views for the right pane.\r\n//\r\n// Same component, two density modes:\r\n// - `cards` → square-ish tiles, label + subtitle.\r\n// - `gallery` → 16:9 thumbnails, more breathing room.\r\n// =============================================================================\r\nimport type { ReactNode } from 'react';\r\nimport type {\r\n ItemSlotContext, RecordSummary, ItemViewContext, RecordsAdminI18n,\r\n} from '../types';\r\nimport { Trash2 } from 'lucide-react';\r\n\r\ninterface Props<T> {\r\n items: RecordSummary<T>[];\r\n variant: 'cards' | 'gallery';\r\n selectedId?: string;\r\n ctx: ItemViewContext;\r\n renderCard?: (record: RecordSummary<T>, slotCtx: ItemSlotContext) => ReactNode;\r\n i18n: Pick<RecordsAdminI18n, 'delete'>;\r\n}\r\n\r\nconst initials = (label: string): string =>\r\n label\r\n .split(/\\s+/)\r\n .slice(0, 2)\r\n .map((s) => s[0]?.toUpperCase() ?? '')\r\n .join('') || '?';\r\n\r\nexport function DefaultItemCards<T>({\r\n items, variant, selectedId, ctx, renderCard, i18n,\r\n}: Props<T>) {\r\n const isGallery = variant === 'gallery';\r\n return (\r\n <div className={isGallery ? 'ra-item-gallery' : 'ra-item-cards'}>\r\n {items.map((item) => {\r\n const id = item.itemId ?? '';\r\n const slotCtx: ItemSlotContext = {\r\n ...ctx,\r\n selected: selectedId === id,\r\n };\r\n if (renderCard) {\r\n return (\r\n <div\r\n key={item.ref}\r\n onClick={() => ctx.onOpen(id)}\r\n className=\"ra-item-card-wrap\"\r\n data-selected={slotCtx.selected}\r\n >\r\n {renderCard(item, slotCtx)}\r\n </div>\r\n );\r\n }\r\n return (\r\n <button\r\n key={item.ref}\r\n type=\"button\"\r\n onClick={() => ctx.onOpen(id)}\r\n className={`ra-item-card ${isGallery ? 'ra-item-card--gallery' : ''}`}\r\n data-selected={slotCtx.selected}\r\n >\r\n <div className={`ra-item-card-thumb ${isGallery ? 'ra-item-card-thumb--gallery' : ''}`}>\r\n {item.thumbnail\r\n ? <img src={item.thumbnail} alt=\"\" loading=\"lazy\" />\r\n : <span className=\"ra-item-card-initials\">{initials(item.label)}</span>}\r\n </div>\r\n <div className=\"ra-item-card-body\">\r\n <div className=\"ra-item-card-title\">{item.label}</div>\r\n {item.subtitle && (\r\n <div className=\"ra-item-card-sub\">{item.subtitle}</div>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n className=\"ra-row-action ra-item-card-delete\"\r\n data-tone=\"danger\"\r\n onClick={(e) => { e.stopPropagation(); ctx.onDelete(id); }}\r\n aria-label={i18n.delete}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n </button>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// ItemListView — right-pane multi-item view shown when a collection-cardinality\r\n// scope is selected and no item is open.\r\n//\r\n// Honours, in order:\r\n// 1. `renderItemList` — full host override.\r\n// 2. `renderItemCard` — host card renderer for cards/gallery views.\r\n// 3. `itemColumns` — declarative columns for the table view.\r\n// 4. Built-in defaults — table with label + updated.\r\n//\r\n// Also owns the toolbar: title, item count, \"+ New {noun}\", and the\r\n// table/cards/gallery switcher when more than one view is offered.\r\n// =============================================================================\r\nimport type { ReactNode } from 'react';\r\nimport { Plus } from 'lucide-react';\r\nimport type {\r\n ItemColumn, ItemSlotContext, ItemView, ItemViewContext,\r\n RecordSummary, RecordsAdminI18n,\r\n} from '../types';\r\nimport { ItemViewSwitcher } from './ItemViewSwitcher';\r\nimport { DefaultItemTable } from './DefaultItemTable';\r\nimport { DefaultItemCards } from './DefaultItemCards';\r\nimport { EmptyState, LoadingState, ErrorState } from '../browser/EmptyStates';\r\nimport { Plus as PlusIcon } from 'lucide-react';\r\n\r\ninterface Props<T> {\r\n items: RecordSummary<T>[];\r\n isLoading: boolean;\r\n error: Error | null;\r\n ctx: ItemViewContext;\r\n itemNoun: string;\r\n\r\n // View configuration\r\n view: ItemView;\r\n views: ItemView[];\r\n onViewChange: (view: ItemView) => void;\r\n\r\n // Optional host overrides\r\n renderItemList?: (items: RecordSummary<T>[], ctx: ItemViewContext) => ReactNode;\r\n renderItemCard?: (record: RecordSummary<T>, ctx: ItemSlotContext) => ReactNode;\r\n renderItemEmpty?: (ctx: ItemViewContext) => ReactNode;\r\n itemColumns?: ItemColumn<T>[];\r\n\r\n i18n: RecordsAdminI18n;\r\n}\r\n\r\nexport function ItemListView<T>({\r\n items, isLoading, error, ctx, itemNoun,\r\n view, views, onViewChange,\r\n renderItemList, renderItemCard, renderItemEmpty, itemColumns,\r\n i18n,\r\n}: Props<T>) {\r\n const newLabel = i18n.newItem.includes('{noun}')\r\n ? i18n.newItem.replace('{noun}', itemNoun)\r\n : i18n.newItem;\r\n\r\n const toolbar = (\r\n <div className=\"ra-item-toolbar\">\r\n <div className=\"ra-item-toolbar-title\">\r\n <h2 className=\"ra-display\" style={{ fontSize: '0.95rem', margin: 0 }}>\r\n {i18n.itemListTitle}\r\n </h2>\r\n <span className=\"ra-item-toolbar-count\">{items.length}</span>\r\n </div>\r\n <div className=\"ra-item-toolbar-actions\">\r\n {/* View switcher only renders when host opts into 2+ views */}\r\n {!renderItemList && (\r\n <ItemViewSwitcher\r\n options={views}\r\n value={view}\r\n onChange={onViewChange}\r\n i18n={i18n}\r\n />\r\n )}\r\n <button\r\n type=\"button\"\r\n onClick={ctx.onCreate}\r\n className=\"ra-btn\"\r\n data-variant=\"primary\"\r\n >\r\n <Plus className=\"w-3.5 h-3.5\" />\r\n {newLabel}\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n\r\n let body: ReactNode;\r\n if (isLoading) {\r\n body = <LoadingState />;\r\n } else if (error) {\r\n body = <ErrorState error={error} />;\r\n } else if (items.length === 0) {\r\n body = renderItemEmpty\r\n ? renderItemEmpty(ctx)\r\n : (\r\n <EmptyState\r\n title={i18n.noItemsTitle}\r\n body={i18n.noItemsBody}\r\n action={(\r\n <button\r\n type=\"button\"\r\n onClick={ctx.onCreate}\r\n className=\"ra-btn\"\r\n data-variant=\"primary\"\r\n >\r\n <PlusIcon className=\"w-3.5 h-3.5\" />\r\n {newLabel}\r\n </button>\r\n )}\r\n />\r\n );\r\n } else if (renderItemList) {\r\n body = renderItemList(items, ctx);\r\n } else if (view === 'table') {\r\n body = (\r\n <DefaultItemTable\r\n items={items}\r\n columns={itemColumns}\r\n selectedId={ctx.selectedId}\r\n onOpen={ctx.onOpen}\r\n onDelete={ctx.onDelete}\r\n i18n={i18n}\r\n />\r\n );\r\n } else {\r\n body = (\r\n <DefaultItemCards\r\n items={items}\r\n variant={view}\r\n selectedId={ctx.selectedId}\r\n ctx={ctx}\r\n renderCard={renderItemCard}\r\n i18n={i18n}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"ra-item-list\">\r\n {toolbar}\r\n <div className=\"ra-item-list-body\">{body}</div>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// EditorItemNav — small chrome rendered above the editor when an item is open\r\n// in collection mode. Provides Back-to-list + previous/next arrows. The shell\r\n// passes pre-computed flags so this component is purely presentational.\r\n// =============================================================================\r\nimport { ChevronLeft, ChevronRight, ArrowLeft } from 'lucide-react';\r\nimport type { RecordsAdminI18n } from '../types';\r\n\r\ninterface Props {\r\n /** Friendly name of the item being edited (mostly for screen readers). */\r\n label?: string;\r\n /** 1-based position within the current sibling list. */\r\n position?: number;\r\n total?: number;\r\n onBack: () => void;\r\n onPrev?: () => void;\r\n onNext?: () => void;\r\n canPrev: boolean;\r\n canNext: boolean;\r\n i18n: Pick<RecordsAdminI18n, 'backToList' | 'prevItem' | 'nextItem'>;\r\n}\r\n\r\nexport const EditorItemNav = ({\r\n label, position, total, onBack, onPrev, onNext, canPrev, canNext, i18n,\r\n}: Props) => (\r\n <div className=\"ra-item-nav\">\r\n <button\r\n type=\"button\"\r\n onClick={onBack}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n >\r\n <ArrowLeft className=\"w-3.5 h-3.5\" />\r\n {i18n.backToList}\r\n </button>\r\n {typeof position === 'number' && typeof total === 'number' && total > 0 && (\r\n <span className=\"ra-item-nav-position\" aria-label={label}>\r\n {position} / {total}\r\n </span>\r\n )}\r\n <div className=\"ra-item-nav-arrows\">\r\n <button\r\n type=\"button\"\r\n onClick={onPrev}\r\n disabled={!canPrev}\r\n className=\"ra-row-action\"\r\n aria-label={i18n.prevItem}\r\n title={i18n.prevItem}\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onNext}\r\n disabled={!canNext}\r\n className=\"ra-row-action\"\r\n aria-label={i18n.nextItem}\r\n title={i18n.nextItem}\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n);","// =============================================================================\r\n// SiblingRail — replaces the scope rail when an item is open in collection\r\n// mode (and `collectionRailMode === 'siblings'`).\r\n//\r\n// Top: pinned `← All scopes` link to return the rail to scope navigation.\r\n// Body: dense rows of every item in the current scope. Click a row to switch\r\n// the editor to that item without leaving the page.\r\n// =============================================================================\r\nimport { ArrowLeft } from 'lucide-react';\r\nimport type { RecordSummary, RecordsAdminI18n } from '../types';\r\nimport { LoadingState, ErrorState, EmptyState } from '../browser/EmptyStates';\r\n\r\ninterface Props<T> {\r\n items: RecordSummary<T>[];\r\n selectedItemId?: string;\r\n isLoading: boolean;\r\n error: Error | null;\r\n onBack: () => void;\r\n onSelect: (itemId: string) => void;\r\n i18n: Pick<RecordsAdminI18n,\r\n | 'backToScopes' | 'siblingsHeading' | 'noItemsTitle' | 'noItemsBody'\r\n >;\r\n}\r\n\r\nexport function SiblingRail<T>({\r\n items, selectedItemId, isLoading, error, onBack, onSelect, i18n,\r\n}: Props<T>) {\r\n return (\r\n <div className=\"ra-sibling-rail\">\r\n <button\r\n type=\"button\"\r\n onClick={onBack}\r\n className=\"ra-sibling-back\"\r\n >\r\n <ArrowLeft className=\"w-3.5 h-3.5\" />\r\n {i18n.backToScopes}\r\n </button>\r\n <div className=\"ra-sibling-heading\">{i18n.siblingsHeading}</div>\r\n <div className=\"ra-sibling-body\">\r\n {isLoading && <LoadingState />}\r\n {!isLoading && error && <ErrorState error={error} />}\r\n {!isLoading && !error && items.length === 0 && (\r\n <EmptyState title={i18n.noItemsTitle} body={i18n.noItemsBody} />\r\n )}\r\n {!isLoading && !error && items.length > 0 && (\r\n <ul className=\"ra-sibling-list\">\r\n {items.map((item) => {\r\n const id = item.itemId ?? '';\r\n const selected = selectedItemId === id;\r\n return (\r\n <li key={item.ref}>\r\n <button\r\n type=\"button\"\r\n onClick={() => onSelect(id)}\r\n className=\"ra-row\"\r\n data-selected={selected}\r\n >\r\n <div className=\"ra-row-body\">\r\n <div className=\"ra-row-title\">{item.label}</div>\r\n {item.subtitle && (\r\n <div className=\"ra-row-sub\">{item.subtitle}</div>\r\n )}\r\n </div>\r\n </button>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n )}\r\n </div>\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 /** Optional override for the button label. When set, takes precedence over `label`. */\r\n customLabel?: string;\r\n introHidden: boolean;\r\n onShowIntro?: () => void;\r\n}\r\n\r\nexport const UtilityRow = ({ label, customLabel, introHidden, onShowIntro }: Props) => {\r\n if (!introHidden || !onShowIntro) return null;\r\n const text = customLabel ?? `How ${label.toLowerCase()} works`;\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 {text}\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 * Optional trailing slot rendered AFTER `headerActions`. Reserved for the\r\n * shell-managed intro reopen (`?`) button so it sits flush with the host's\r\n * own header actions without polluting the public `headerActions` slot.\r\n */\r\n trailingSlot?: 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 trailingSlot,\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 || trailingSlot ? (\r\n <div className=\"ra-header-actions\">\r\n {headerActions}\r\n {trailingSlot}\r\n </div>\r\n ) : 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\nimport type { ComponentType } from 'react';\r\n\r\ntype IconCmp = ComponentType<{ className?: string }>;\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 /** Optional icon override for the inline Save button (defaults to Lucide `Save`). */\r\n SaveIcon?: IconCmp;\r\n /** Optional icon override for the inline Discard button (defaults to Lucide `Undo2`). */\r\n DiscardIcon?: IconCmp;\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 SaveIcon, DiscardIcon,\r\n}: UnsavedBannerProps) => {\r\n const SI: IconCmp = SaveIcon ?? Save;\r\n const DI: IconCmp = DiscardIcon ?? Undo2;\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 <DI 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 <SI 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// ClipboardToast — lightweight transient toast used by the shell for Copy /\r\n// Paste feedback. Avoids pulling `sonner` into the library bundle while\r\n// keeping the affordance discoverable. Auto-dismisses after 2.5s.\r\n// =============================================================================\r\nimport { useEffect } from 'react';\r\nimport { Copy as CopyIcon, ClipboardPaste } from 'lucide-react';\r\n\r\nexport interface ClipboardToastProps {\r\n message: string;\r\n variant?: 'copy' | 'paste';\r\n onDismiss: () => void;\r\n}\r\n\r\nexport const ClipboardToast = ({ message, variant = 'copy', onDismiss }: ClipboardToastProps) => {\r\n useEffect(() => {\r\n const t = window.setTimeout(onDismiss, 2500);\r\n return () => window.clearTimeout(t);\r\n }, [message, onDismiss]);\r\n\r\n const Icon = variant === 'paste' ? ClipboardPaste : CopyIcon;\r\n\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n className=\"ra-clipboard-toast\"\r\n >\r\n <Icon className=\"w-3.5 h-3.5 shrink-0\" aria-hidden=\"true\" />\r\n <span className=\"truncate\">{message}</span>\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.55rem;\\n width: 100%;\\n text-align: left;\\n padding: 0.45rem 0.75rem;\\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-compact {\\n padding-block: 0.3rem;\\n}\\n.ra-shell .ra-row-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.5rem;\\n height: 1.5rem;\\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.8125rem;\\n line-height: 1.2;\\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.6875rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.05rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell[data-density=compact] .ra-row {\\n padding-block: 0.3rem;\\n gap: 0.45rem;\\n}\\n.ra-shell[data-density=compact] .ra-row-title {\\n font-size: 0.78125rem;\\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.ra-shell .ra-clipboard-toast {\\n position: fixed;\\n bottom: 1.25rem;\\n left: 50%;\\n transform: translateX(-50%);\\n z-index: 90;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.5rem;\\n max-width: min(28rem, calc(100vw - 2rem));\\n padding: 0.55rem 0.85rem;\\n border-radius: 999px;\\n background: hsl(var(--ra-text));\\n color: hsl(var(--ra-surface));\\n font-size: 0.75rem;\\n line-height: 1;\\n box-shadow: 0 8px 24px -10px hsl(0 0% 0% / 0.45);\\n animation: ra-clipboard-pop 0.18s ease-out both;\\n pointer-events: none;\\n}\\n@keyframes ra-clipboard-pop {\\n from {\\n opacity: 0;\\n transform: translate(-50%, 6px);\\n }\\n to {\\n opacity: 1;\\n transform: translate(-50%, 0);\\n }\\n}\\n.ra-shell .ra-row-menu-wrap {\\n display: inline-flex;\\n align-items: center;\\n margin-left: 0.25rem;\\n}\\n.ra-shell .ra-row-menu-trigger {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.5rem;\\n height: 1.5rem;\\n border-radius: 0.35rem;\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n opacity: 0;\\n transition:\\n opacity .15s ease,\\n background .15s ease,\\n color .15s ease;\\n border: 1px solid transparent;\\n}\\n.ra-shell .ra-row:hover .ra-row-menu-trigger,\\n.ra-shell .ra-card-hover:hover .ra-row-menu-trigger,\\n.ra-shell .ra-row-menu-trigger:focus-visible,\\n.ra-shell .ra-row-menu-trigger[aria-expanded=true] {\\n opacity: 1;\\n}\\n.ra-shell .ra-row-menu-trigger:hover {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-row-menu {\\n position: absolute;\\n right: 0;\\n top: calc(100% + 4px);\\n z-index: 50;\\n min-width: 11rem;\\n padding: 0.25rem;\\n border-radius: 0.5rem;\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n box-shadow: 0 12px 28px -10px hsl(0 0% 0% / 0.25);\\n display: flex;\\n flex-direction: column;\\n gap: 0.125rem;\\n}\\n.ra-shell .ra-row-menu-item {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.5rem;\\n padding: 0.4rem 0.55rem;\\n border-radius: 0.35rem;\\n font-size: 0.75rem;\\n color: hsl(var(--ra-text));\\n background: transparent;\\n border: 0;\\n text-align: left;\\n width: 100%;\\n cursor: pointer;\\n}\\n.ra-shell .ra-row-menu-item:hover:not(:disabled) {\\n background: hsl(var(--ra-muted));\\n}\\n.ra-shell .ra-row-menu-item:disabled {\\n opacity: 0.45;\\n cursor: not-allowed;\\n}\\n.ra-shell .ra-item-list {\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n min-height: 0;\\n}\\n.ra-shell .ra-item-list-body {\\n flex: 1;\\n min-height: 0;\\n overflow: auto;\\n padding: 1rem 1.25rem 1.5rem;\\n}\\n.ra-shell .ra-item-toolbar {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n gap: 0.75rem;\\n padding: 0.75rem 1.25rem;\\n border-bottom: 1px solid hsl(var(--ra-border));\\n background: hsl(var(--ra-surface));\\n}\\n.ra-shell .ra-item-toolbar-title {\\n display: flex;\\n align-items: baseline;\\n gap: 0.5rem;\\n min-width: 0;\\n}\\n.ra-shell .ra-item-toolbar-count {\\n font-size: 0.7rem;\\n font-weight: 600;\\n color: hsl(var(--ra-muted-text));\\n background: hsl(var(--ra-muted));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: 999px;\\n padding: 0.05rem 0.45rem;\\n}\\n.ra-shell .ra-item-toolbar-actions {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-item-table-wrap {\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: var(--ra-radius);\\n background: hsl(var(--ra-surface));\\n overflow: hidden;\\n box-shadow: var(--ra-card-shadow);\\n}\\n.ra-shell .ra-item-table {\\n width: 100%;\\n border-collapse: collapse;\\n font-size: 0.85rem;\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-item-table thead th {\\n text-align: left;\\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 padding: 0.65rem 0.85rem;\\n background: hsl(var(--ra-muted) / 0.55);\\n border-bottom: 1px solid hsl(var(--ra-border));\\n}\\n.ra-shell .ra-item-table tbody td {\\n padding: 0.65rem 0.85rem;\\n border-bottom: 1px solid hsl(var(--ra-border) / 0.7);\\n vertical-align: middle;\\n}\\n.ra-shell .ra-item-table tbody tr:last-child td {\\n border-bottom: 0;\\n}\\n.ra-shell .ra-item-row {\\n cursor: pointer;\\n transition: background .12s ease;\\n}\\n.ra-shell .ra-item-row:hover {\\n background: var(--ra-row-hover);\\n}\\n.ra-shell .ra-item-row[data-selected=true] {\\n background: var(--ra-row-active-bg);\\n}\\n.ra-shell .ra-item-row-title {\\n font-weight: var(--ra-title-weight);\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-item-row-sub {\\n font-size: 0.75rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.15rem;\\n}\\n.ra-shell .ra-item-row-meta {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-shell .ra-item-row-actions {\\n text-align: right;\\n white-space: nowrap;\\n}\\n.ra-shell .ra-item-row-actions .ra-row-action + .ra-row-action {\\n margin-left: 0.15rem;\\n}\\n.ra-shell .ra-item-cards {\\n display: grid;\\n grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));\\n gap: 0.85rem;\\n}\\n.ra-shell .ra-item-gallery {\\n display: grid;\\n grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));\\n gap: 1rem;\\n}\\n.ra-shell .ra-item-card {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n align-items: stretch;\\n text-align: left;\\n padding: 0;\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: var(--ra-radius);\\n overflow: hidden;\\n cursor: pointer;\\n transition:\\n box-shadow .18s ease,\\n transform .12s ease,\\n border-color .15s ease;\\n box-shadow: var(--ra-card-shadow);\\n font-family: inherit;\\n color: inherit;\\n}\\n.ra-shell .ra-item-card:hover {\\n box-shadow: var(--ra-card-shadow-hover);\\n border-color: hsl(var(--ra-accent) / 0.30);\\n}\\n.ra-shell .ra-item-card[data-selected=true] {\\n border-color: hsl(var(--ra-accent) / 0.55);\\n box-shadow: var(--ra-card-shadow-hover);\\n}\\n.ra-shell .ra-item-card-thumb {\\n width: 100%;\\n aspect-ratio: 1 / 1;\\n background:\\n linear-gradient(\\n 135deg,\\n hsl(var(--ra-accent) / 0.12),\\n hsl(var(--ra-accent) / 0.04));\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n color: hsl(var(--ra-accent));\\n overflow: hidden;\\n}\\n.ra-shell .ra-item-card-thumb--gallery {\\n aspect-ratio: 16 / 9;\\n}\\n.ra-shell .ra-item-card-thumb img {\\n width: 100%;\\n height: 100%;\\n -o-object-fit: cover;\\n object-fit: cover;\\n}\\n.ra-shell .ra-item-card-initials {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n font-size: 1.5rem;\\n letter-spacing: 0.02em;\\n}\\n.ra-shell .ra-item-card-body {\\n padding: 0.65rem 0.8rem 0.85rem;\\n min-width: 0;\\n}\\n.ra-shell .ra-item-card-title {\\n font-weight: var(--ra-title-weight);\\n font-size: 0.85rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-item-card-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-item-card-delete {\\n position: absolute;\\n top: 0.4rem;\\n right: 0.4rem;\\n background: hsl(var(--ra-surface) / 0.85);\\n backdrop-filter: blur(4px);\\n opacity: 0;\\n transition: opacity .15s ease;\\n}\\n.ra-shell .ra-item-card:hover .ra-item-card-delete,\\n.ra-shell .ra-item-card:focus-within .ra-item-card-delete {\\n opacity: 1;\\n}\\n.ra-shell .ra-item-nav {\\n display: flex;\\n align-items: center;\\n gap: 0.6rem;\\n padding: 0.5rem 1.25rem;\\n border-bottom: 1px solid hsl(var(--ra-border));\\n background: hsl(var(--ra-surface));\\n}\\n.ra-shell .ra-item-nav-position {\\n font-size: 0.72rem;\\n color: hsl(var(--ra-muted-text));\\n font-variant-numeric: tabular-nums;\\n}\\n.ra-shell .ra-item-nav-arrows {\\n margin-left: auto;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.15rem;\\n}\\n.ra-shell .ra-item-nav-arrows .ra-row-action[disabled] {\\n opacity: 0.35;\\n cursor: not-allowed;\\n}\\n.ra-shell .ra-sibling-rail {\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n min-height: 0;\\n}\\n.ra-shell .ra-sibling-back {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n padding: 0.6rem 0.85rem;\\n font-size: 0.75rem;\\n font-weight: 500;\\n color: hsl(var(--ra-muted-text));\\n background: hsl(var(--ra-muted) / 0.5);\\n border: 0;\\n border-bottom: 1px solid hsl(var(--ra-border));\\n cursor: pointer;\\n text-align: left;\\n transition: background .12s ease, color .12s ease;\\n}\\n.ra-shell .ra-sibling-back:hover {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-sibling-heading {\\n padding: 0.6rem 0.85rem 0.4rem;\\n font-size: 0.65rem;\\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-sibling-body {\\n flex: 1;\\n min-height: 0;\\n overflow-y: auto;\\n}\\n.ra-shell .ra-sibling-list {\\n list-style: none;\\n margin: 0;\\n padding: 0;\\n}\\n.ra-shell .ra-status-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n border-radius: 9999px;\\n}\\n.ra-shell .ra-status-icon > svg {\\n width: 100%;\\n height: 100%;\\n display: block;\\n}\\n.ra-shell .ra-status-icon--own {\\n color: hsl(var(--ra-status-own));\\n}\\n.ra-shell .ra-status-icon--shared {\\n color: hsl(var(--ra-status-shared));\\n}\\n.ra-shell .ra-status-icon--missing {\\n color: hsl(var(--ra-status-missing) / 0.7);\\n}\\n.ra-shell .ra-row-status {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.5rem;\\n height: 1.5rem;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-row-scope {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.25rem;\\n height: 1.25rem;\\n border-radius: calc(var(--ra-radius) * 0.5);\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-muted-text));\\n flex-shrink: 0;\\n margin-left: auto;\\n opacity: 0.55;\\n transition:\\n opacity .12s ease,\\n color .12s ease,\\n background .12s ease;\\n}\\n.ra-shell .ra-row:hover .ra-row-scope {\\n opacity: 0.85;\\n}\\n.ra-shell .ra-row[data-selected=true] .ra-row-scope {\\n opacity: 1;\\n background: hsl(var(--ra-accent) / 0.12);\\n color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-row[data-tone=own] .ra-row-sub {\\n color: hsl(var(--ra-status-own));\\n}\\n.ra-shell .ra-row[data-tone=shared] .ra-row-sub {\\n color: hsl(var(--ra-status-shared));\\n}\\n.ra-shell .ra-row[data-selected=true] {\\n background:\\n linear-gradient(\\n 90deg,\\n hsl(var(--ra-accent) / 0.10) 0%,\\n hsl(var(--ra-accent) / 0.04) 100%);\\n border-left-width: 3px;\\n border-left-color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-dirty-pip {\\n display: inline-block;\\n width: 0.45rem;\\n height: 0.45rem;\\n border-radius: 9999px;\\n background: hsl(var(--ra-warning));\\n box-shadow: 0 0 0 2px hsl(var(--ra-warning) / 0.18);\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-group-summary {\\n background: transparent;\\n}\\n.ra-shell {\\n position: relative;\\n}\\n.ra-shell .ra-help-float {\\n position: absolute;\\n top: 0.65rem;\\n right: 0.85rem;\\n z-index: 5;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.35rem;\\n padding: 0.3rem 0.6rem;\\n font-size: 0.7rem;\\n font-weight: 500;\\n color: hsl(var(--ra-muted-text));\\n background: hsl(var(--ra-surface) / 0.85);\\n backdrop-filter: blur(6px);\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: 999px;\\n cursor: pointer;\\n transition:\\n color .12s ease,\\n background .12s ease,\\n border-color .12s ease;\\n}\\n.ra-shell .ra-help-float:hover {\\n color: hsl(var(--ra-accent));\\n border-color: hsl(var(--ra-accent) / 0.4);\\n background: hsl(var(--ra-surface));\\n}\\n.ra-shell .ra-help-float svg {\\n width: 0.85rem;\\n height: 0.85rem;\\n}\\n.ra-shell .ra-preview-reopen {\\n position: absolute;\\n top: 50%;\\n right: 0;\\n transform: translateY(-50%);\\n z-index: 4;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n gap: 0.4rem;\\n padding: 0.65rem 0.45rem;\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-muted-text));\\n border: 1px solid hsl(var(--ra-border));\\n border-right: 0;\\n border-radius: calc(var(--ra-radius) * 0.85) 0 0 calc(var(--ra-radius) * 0.85);\\n box-shadow: var(--ra-card-shadow);\\n cursor: pointer;\\n transition:\\n color .12s ease,\\n background .12s ease,\\n padding-right .15s ease;\\n writing-mode: vertical-rl;\\n font-size: 0.7rem;\\n font-weight: 600;\\n letter-spacing: 0.06em;\\n text-transform: uppercase;\\n}\\n.ra-shell .ra-preview-reopen:hover {\\n color: hsl(var(--ra-accent));\\n background: hsl(var(--ra-accent) / 0.04);\\n padding-right: 0.6rem;\\n}\\n.ra-shell .ra-preview-reopen svg {\\n width: 0.85rem;\\n height: 0.85rem;\\n writing-mode: horizontal-tb;\\n}\\n\")","import { useEffect, useMemo, useRef, useState, useCallback, isValidElement, createElement, type ReactNode } from 'react';\r\nimport { Plus, Search, HelpCircle, Eye } from 'lucide-react';\r\nimport { mergeIcons, pickHeaderIcon } from './icons';\r\nimport type {\r\n RecordsAdminShellProps, RecordStatus, RecordSummary,\r\n ScopeKind, RecordsAdminI18n, ParsedRef, RecordPresentation, ItemView,\r\n} from '../types';\r\nimport { DEFAULT_I18N } from '../types';\r\nimport { parseRef, buildRef, splitItemRef, buildItemRef } 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 { usePasteConfirm } from '../hooks/usePasteConfirm';\r\nimport {\r\n useRecordClipboard, checkPasteCompatibility, cloneValue,\r\n} from '../hooks/useRecordClipboard';\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, useItemViewPref } from '../hooks/usePresentationPref';\r\nimport { useCollectionItems } from '../hooks/useCollectionItems';\r\nimport { useDeepLinkState } from '../hooks/useDeepLinkState';\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 { ItemListView } from '../items/ItemListView';\r\nimport { EditorItemNav } from '../items/EditorItemNav';\r\nimport { SiblingRail } from '../items/SiblingRail';\r\nimport { IntroCard } from './IntroCard';\r\nimport { UtilityRow } from './UtilityRow';\r\nimport { ShellHeader } from './ShellHeader';\r\nimport { UnsavedBanner } from './UnsavedBanner';\r\nimport { ClipboardToast } from './ClipboardToast';\r\nimport { exportCsv, importCsv, downloadBlob } from '../data/csv';\r\nimport './tokens.css';\r\nimport './shell.css';\r\n\r\n/**\r\n * Top-level scopes the rail can show. Drill-downs (variant / batch) live\r\n * under the selected product (see `ProductDrillDown`).\r\n *\r\n * Order matters: this drives tab order AND the default tab when the host\r\n * doesn't pass `defaultScope`. We lead with `rule` because — for any\r\n * collection with more than a handful of facet values — authors are far\r\n * more likely to target records by criteria (\"apply to all sourdough\r\n * loaves\") than by pinning one record per facet value. `collection`\r\n * (Global) covers the migration case of records that have no targeting\r\n * at all. `facet` (pin one record to one facet value) is now the\r\n * specialist option, last.\r\n */\r\nconst TOP_LEVEL_SCOPES: ScopeKind[] = ['rule', 'collection', '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 // 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 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 enableClipboard = true,\r\n onCopy: onCopyOverride,\r\n onPaste: onPasteOverride,\r\n actionLabels,\r\n actionIcons,\r\n editorTabs = 'off',\r\n // Right-pane item view (collection cardinality)\r\n itemViews = ['table'],\r\n defaultItemView,\r\n itemColumns,\r\n renderItemList,\r\n renderItemCard,\r\n renderItemEmpty,\r\n collectionRailMode = 'siblings',\r\n // Deep linking\r\n deepLink,\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 // Deep linking — set up the URL bridge early so user-action callbacks can\r\n // emit through it. The actual restore + emit wiring happens further down,\r\n // once the rest of the shell state has been declared.\r\n // ---------------------------------------------------------------------------\r\n const deepLinkState = useDeepLinkState(deepLink);\r\n // Track which params we've already applied so back/forward writes don't\r\n // bounce against our own emits.\r\n const lastAppliedDLRef = useRef<string>('');\r\n\r\n // `'multi'` is reserved for the upcoming multi-open editor (pinned tabs +\r\n // Save-all). Until that ships we behave like `'off'` and warn once so\r\n // hosts can adopt the prop early without surprise behaviour changes.\r\n const multiOpenWarnedRef = useRef(false);\r\n if (editorTabs === 'multi' && !multiOpenWarnedRef.current) {\r\n multiOpenWarnedRef.current = true;\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n '[RecordsAdminShell] editorTabs=\"multi\" is reserved for a future ' +\r\n 'release and currently behaves like \"off\". Track in records-admin-shell.md.',\r\n );\r\n }\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 // ---------------------------------------------------------------------------\r\n // Right-pane item view preference (collection cardinality only).\r\n // ---------------------------------------------------------------------------\r\n const [itemView, setItemView] = useItemViewPref({\r\n appId, recordType,\r\n options: itemViews,\r\n defaultValue: defaultItemView ?? itemViews[0] ?? 'table',\r\n });\r\n const onItemViewChange = useCallback((next: ItemView) => {\r\n onTelemetry?.({\r\n type: 'item.view.change',\r\n recordType,\r\n scopeRef: '', // populated below if a scope is active\r\n from: itemView,\r\n to: next,\r\n });\r\n setItemView(next);\r\n deepLinkState.emit({ view: next }, 'view');\r\n }, [onTelemetry, recordType, itemView, setItemView, deepLinkState]);\r\n\r\n // The selected per-item id (collection cardinality). When `null` the right\r\n // pane shows the multi-item list view; when set the editor renders against\r\n // the item ref `{scopeRef}/item:{id}` (or `item:{id}` at collection root).\r\n const [selectedItemId, setSelectedItemId] = useState<string | null>(null);\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 // Intro reopen affordance — resolve once. Defaults to `'header'`. When the\r\n // header card isn't rendered (host hasn't customised it & didn't opt in),\r\n // silently fall back to `'footer'` so the help button still has a home.\r\n // ---------------------------------------------------------------------------\r\n const headerWillRender = useMemo(() => {\r\n const headerCustomised =\r\n !!title || !!subtitle || !!headerIcon || !!headerActions ||\r\n showStats || !!statsItems || !!statsTitle || !!statsIcon;\r\n return showHeader === true || (showHeader !== false && headerCustomised);\r\n }, [showHeader, title, subtitle, headerIcon, headerActions, showStats, statsItems, statsTitle, statsIcon]);\r\n\r\n const resolvedReopenAffordance: 'header' | 'footer' | 'inline' | 'hidden' = useMemo(() => {\r\n const requested = intro?.reopenAffordance ?? 'header';\r\n if (requested === 'header' && !headerWillRender) return 'footer';\r\n return requested;\r\n }, [intro?.reopenAffordance, headerWillRender]);\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 by the facet tab AND by the new rule / global\r\n // tabs. The hook's `matchesScope` keeps each tab cleanly partitioned (rule\r\n // records never leak into facet, etc.). See `useRecordList` for the rules.\r\n const recordListEnabled =\r\n (activeScope === 'facet' || activeScope === 'rule' || activeScope === 'collection')\r\n && !probe.isLoading;\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: recordListEnabled,\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 the user's current browse selection. In\r\n // singleton mode this is also the record being edited. In collection mode\r\n // it's the *folder* that holds items — the actual editing target appends\r\n // an `item:{id}` segment (see `editingRef` below).\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 // ---------------------------------------------------------------------------\r\n // Collection-cardinality plumbing. The shell stays in singleton mode unless\r\n // the host opted in (`cardinality === 'collection'`).\r\n //\r\n // - `isCollection` — convenience flag.\r\n // - `editingItemRef` — the full `{scopeRef}/item:{id}` ref when an item\r\n // is open; otherwise null (right pane shows the\r\n // item list view rather than an editor).\r\n // - `editingTargetScope` — what the editor + resolver actually point at.\r\n // In singleton mode this is `editingScope`; in\r\n // collection mode with an item open it's the item\r\n // ref; without an item open it's null (no editor).\r\n // ---------------------------------------------------------------------------\r\n const isCollection = cardinality === 'collection';\r\n\r\n const editingItemRef: string | null = useMemo(() => {\r\n if (!isCollection) return null;\r\n if (!selectedItemId) return null;\r\n // `editingScope` may be null only at the collection root — we still want\r\n // an item ref like `item:{id}` in that case (future-proofing for the\r\n // dedicated `'collection'` scope tab).\r\n const baseRef = editingScope?.raw ?? '';\r\n return buildItemRef(baseRef, selectedItemId);\r\n }, [isCollection, selectedItemId, editingScope]);\r\n\r\n const editingTargetScope: ParsedRef | null = useMemo(() => {\r\n if (!isCollection) return editingScope;\r\n if (!editingItemRef) return null;\r\n return parseRef(editingItemRef);\r\n }, [isCollection, editingScope, editingItemRef]);\r\n\r\n // Reset the selected item whenever the *scope folder* changes — switching\r\n // from one product to another or one facet value to another should drop\r\n // back to the item list, not silently keep an item id from another scope.\r\n // Skipped on the very next render after a deep-link restore, since restore\r\n // intentionally pairs a scope change with an item id.\r\n const skipNextItemResetRef = useRef(false);\r\n useEffect(() => {\r\n if (skipNextItemResetRef.current) {\r\n skipNextItemResetRef.current = false;\r\n return;\r\n }\r\n setSelectedItemId(null);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [editingScope?.raw]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Items inside the current scope (collection cardinality only). Fetched up-\r\n // front because both the right-pane list and the sibling rail need them,\r\n // and the response is a single round-trip with `refPrefix`.\r\n // ---------------------------------------------------------------------------\r\n const collectionItems = useCollectionItems<TData>({\r\n ctx,\r\n scope: isCollection ? editingScope : null,\r\n enabled: isCollection,\r\n });\r\n\r\n // Emit `scope` whenever the rail moves and no item is open. Item moves are\r\n // already covered by the per-handler emits above and carry their own scope\r\n // inside the ref, so we deliberately skip emit here when an item is open.\r\n // Internal-vs-external echo is filtered by `lastAppliedDLRef` in the\r\n // restore effect (which signature-matches on the URL state we just wrote).\r\n useEffect(() => {\r\n if (!deepLinkState.enabled) return;\r\n if (selectedItemId) return; // item handlers own URL writes while open\r\n deepLinkState.emit({ scope: editingScope?.raw ?? null, item: null }, 'scope');\r\n // Mark this round trip as already-applied so the restore effect doesn't\r\n // try to re-process the same values we just wrote.\r\n lastAppliedDLRef.current = `${''}|${editingScope?.raw ?? ''}|${itemView}`;\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [deepLinkState.enabled, editingScope?.raw, selectedItemId, itemView]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Deep-link restore — apply URL state to shell state when the URL changes\r\n // externally (initial mount, back/forward, host-driven nav). We dedupe by\r\n // signature so our own emits don't bounce back through here.\r\n //\r\n // The `item` URL param can be either a bare id (`comp_winter_2026` → item\r\n // at the collection root) or a full item ref (`product:abc/item:foo`).\r\n // Either way the trailing `item:{id}` segment is the actual item id, and\r\n // anything before it tells us which scope to land on.\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (!deepLinkState.enabled) return;\r\n const { item, scope, view } = deepLinkState.urlState;\r\n const sig = `${item ?? ''}|${scope ?? ''}|${view ?? ''}`;\r\n if (sig === lastAppliedDLRef.current) return;\r\n lastAppliedDLRef.current = sig;\r\n\r\n // Apply view first — independent of item/scope and cheapest.\r\n if (view && itemViews.includes(view as ItemView) && view !== itemView) {\r\n setItemView(view as ItemView);\r\n }\r\n\r\n // Decide where the rail should land. Item wins when present (it carries\r\n // its own scope inside the ref). Otherwise honour `scope`.\r\n const railRef: string = item\r\n ? (item.includes('item:') ? item.slice(0, item.lastIndexOf('item:')).replace(/\\/$/, '') : '')\r\n : (scope ?? '');\r\n const itemId: string | null = item\r\n ? (item.includes('item:') ? item.slice(item.lastIndexOf('item:') + 'item:'.length) : item)\r\n : null;\r\n\r\n // Translate the rail ref into the existing scope-state shape.\r\n const parsed = railRef ? parseRef(railRef) : null;\r\n if (parsed?.productId) {\r\n if (activeScope !== 'product') setActiveScope('product');\r\n if (selectedProductId !== parsed.productId) setSelectedProductId(parsed.productId);\r\n const nextDrill: DrillTab = parsed.batchId ? 'batch' : parsed.variantId ? 'variant' : 'product';\r\n if (drillTab !== nextDrill) setDrillTab(nextDrill);\r\n if (parsed.variantId && selectedVariantId !== parsed.variantId) setSelectedVariantId(parsed.variantId);\r\n if (parsed.batchId && selectedBatchId !== parsed.batchId) setSelectedBatchId(parsed.batchId);\r\n } else if (parsed?.facetId) {\r\n if (activeScope !== 'facet') setActiveScope('facet');\r\n if (selectedFacetRef !== railRef) setSelectedFacetRef(railRef);\r\n } else {\r\n // Empty rail ref — collection root. Clear any facet selection so the\r\n // item list view shows the global pool. Active scope stays as-is\r\n // (host's `defaultScope` already picked an appropriate landing).\r\n if (selectedFacetRef) setSelectedFacetRef(undefined);\r\n }\r\n\r\n // Finally: open the item (or close, if URL has none).\r\n if (itemId !== selectedItemId) {\r\n // Pair the scope change with the item set without the reset effect\r\n // wiping the item id back to null on the next render.\r\n if (railRef && railRef !== editingScope?.raw) {\r\n skipNextItemResetRef.current = true;\r\n }\r\n setSelectedItemId(itemId);\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [deepLinkState.enabled, deepLinkState.urlState]);\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: editingTargetScope?.productId,\r\n variantId: editingTargetScope?.variantId,\r\n batchId: editingTargetScope?.batchId,\r\n facetId: editingTargetScope?.facetId,\r\n facetValue: editingTargetScope?.facetValue,\r\n supportedScopes: supportedForResolution,\r\n enabled: !!editingTargetScope,\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 if (isCollection) collectionItems.refetch();\r\n }, [productBrowse, recordList, facetBrowse, variantChildren, batchChildren, isCollection, collectionItems]);\r\n\r\n const editorCtx = useRecordEditor<TData>({\r\n ctx,\r\n scope: editingTargetScope ?? 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: editingTargetScope?.raw ?? '', isCreate: resolved.source !== 'self' });\r\n refetchAll();\r\n },\r\n onDeleted: () => {\r\n onTelemetry?.({ type: 'record.delete', recordType, ref: editingTargetScope?.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 (isCollection && selectedItemId) {\r\n // Drop back to the item list view; the scope folder selection stays.\r\n setSelectedItemId(null);\r\n } else 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 const pasteConfirm = usePasteConfirm();\r\n\r\n // ---------------------------------------------------------------------------\r\n // Clipboard — Copy / Paste across scopes for this `recordType`.\r\n // ---------------------------------------------------------------------------\r\n // Clipboard always mounts (cheap), but `enableClipboard` gates whether the\r\n // affordance is actually surfaced in the UI. Scoping per (appId,\r\n // recordType) prevents pasting nutrition values into a warranty editor.\r\n const clipboard = useRecordClipboard<TData>({\r\n appId,\r\n recordType: recordType ?? '__default',\r\n });\r\n const [clipboardNotice, setClipboardNotice] = useState<{\r\n message: string; variant: 'copy' | 'paste';\r\n } | null>(null);\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 // Clipboard wiring — needs `editorHeaderLabel` for friendly toasts and the\r\n // replace-confirm body, hence declared here rather than next to the other\r\n // editor state.\r\n // ---------------------------------------------------------------------------\r\n const copyCurrent = useCallback(() => {\r\n if (!enableClipboard || !editingScope) return;\r\n // Resolved value is what the user sees today (post-inheritance). The host\r\n // can transform via `onCopy` to strip per-scope-only fields.\r\n const sourceValue = onCopyOverride\r\n ? onCopyOverride({ value: editorCtx.value, scope: editingScope })\r\n : cloneValue(editorCtx.value);\r\n clipboard.set({\r\n value: sourceValue,\r\n sourceScope: editingScope.kind,\r\n sourceRef: editingScope.raw,\r\n sourceLabel: editorHeaderLabel,\r\n });\r\n onTelemetry?.({ type: 'clipboard.copy', recordType, sourceRef: editingScope.raw });\r\n setClipboardNotice({\r\n message: i18n.copyToast.replace('{name}', editorHeaderLabel ?? editingScope.raw),\r\n variant: 'copy',\r\n });\r\n }, [\r\n enableClipboard, editingScope, onCopyOverride, editorCtx.value, clipboard,\r\n editorHeaderLabel, onTelemetry, recordType, i18n.copyToast,\r\n ]);\r\n\r\n const pasteCurrent = useCallback(async () => {\r\n if (!enableClipboard || !editingScope || !clipboard.entry) return;\r\n\r\n const compat = checkPasteCompatibility(\r\n { kind: clipboard.entry.sourceScope, raw: clipboard.entry.sourceRef },\r\n editingScope,\r\n );\r\n\r\n if (compat.status === 'denied') {\r\n setClipboardNotice({ message: compat.reason ?? 'Paste not allowed here', variant: 'paste' });\r\n return;\r\n }\r\n\r\n if (compat.status === 'warn') {\r\n const ok = await pasteConfirm.confirm({\r\n title: i18n.pasteWarnTitle,\r\n body: compat.reason ?? '',\r\n confirmLabel: i18n.pasteWarnContinue,\r\n cancelLabel: i18n.pasteConfirmCancel,\r\n });\r\n if (!ok) return;\r\n }\r\n\r\n // Replace-confirm only when the destination already has its own saved value.\r\n const willReplace = resolved.source === 'self';\r\n if (willReplace) {\r\n const ok = await pasteConfirm.confirm({\r\n title: i18n.pasteConfirmTitle,\r\n body: i18n.pasteConfirmBody.replace(\r\n '{destination}', editorHeaderLabel ?? editingScope.raw,\r\n ),\r\n confirmLabel: i18n.pasteConfirmReplace,\r\n cancelLabel: i18n.pasteConfirmCancel,\r\n });\r\n if (!ok) return;\r\n }\r\n\r\n const sourceParsed = { kind: clipboard.entry.sourceScope, raw: clipboard.entry.sourceRef };\r\n const transformed = onPasteOverride\r\n ? onPasteOverride(\r\n { value: clipboard.entry.value as TData, sourceScope: sourceParsed as ParsedRef },\r\n { scope: editingScope, currentValue: editorCtx.value ?? null },\r\n )\r\n : cloneValue(clipboard.entry.value as TData);\r\n\r\n if (transformed === null) return; // host vetoed\r\n\r\n // Populate the editor — does NOT autosave. Existing dirty-guard +\r\n // UnsavedBanner take it from here.\r\n editorCtx.onChange(transformed);\r\n onTelemetry?.({\r\n type: 'clipboard.paste',\r\n recordType,\r\n sourceRef: clipboard.entry.sourceRef,\r\n destinationRef: editingScope.raw,\r\n replaced: willReplace,\r\n });\r\n setClipboardNotice({\r\n message: i18n.pasteToast.replace('{name}', clipboard.entry.sourceLabel ?? clipboard.entry.sourceRef),\r\n variant: 'paste',\r\n });\r\n }, [\r\n enableClipboard, editingScope, clipboard.entry, pasteConfirm, resolved.source,\r\n onPasteOverride, editorCtx, onTelemetry, recordType, editorHeaderLabel,\r\n i18n.pasteWarnTitle, i18n.pasteWarnContinue, i18n.pasteConfirmCancel,\r\n i18n.pasteConfirmTitle, i18n.pasteConfirmBody, i18n.pasteConfirmReplace,\r\n i18n.pasteToast,\r\n ]);\r\n\r\n const editorPasteCompat = useMemo(() => {\r\n if (!enableClipboard || !clipboard.entry || !editingScope) return null;\r\n if (clipboard.entry.sourceRef === editingScope.raw) return { status: 'denied' as const };\r\n return checkPasteCompatibility(\r\n { kind: clipboard.entry.sourceScope, raw: clipboard.entry.sourceRef },\r\n editingScope,\r\n );\r\n }, [enableClipboard, clipboard.entry, editingScope]);\r\n\r\n const editorClipboard = enableClipboard && editingScope ? {\r\n onCopy: copyCurrent,\r\n onPaste: () => { void pasteCurrent(); },\r\n canCopy: true,\r\n canPaste: !!clipboard.entry && (editorPasteCompat?.status !== 'denied'),\r\n pasteSourceLabel: clipboard.entry?.sourceLabel,\r\n pasteWillReplace: resolved.source === 'self' && !!clipboard.entry,\r\n } : undefined;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Row-level paste: queue the paste once the user has selected the target\r\n // record. We can't call `pasteCurrent` synchronously from a row click —\r\n // `editingScope` / `resolved` only update after the selection state change\r\n // ripples through. The effect below fires the queued paste once the\r\n // editing scope catches up.\r\n // ---------------------------------------------------------------------------\r\n const [pendingPasteRef, setPendingPasteRef] = useState<string | null>(null);\r\n useEffect(() => {\r\n if (!pendingPasteRef) return;\r\n if (!editingScope || editingScope.raw !== pendingPasteRef) return;\r\n // Wait one more tick so `resolved` (used to decide replace-confirm) has\r\n // a chance to settle for the new ref.\r\n const t = window.setTimeout(() => {\r\n setPendingPasteRef(null);\r\n void pasteCurrent();\r\n }, 0);\r\n return () => window.clearTimeout(t);\r\n }, [pendingPasteRef, editingScope, pasteCurrent]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Per-row clipboard wiring for the rail context menu. Row Copy uses the\r\n // summary's pre-loaded `data` (the facet rail loads it; product rail\r\n // stubs return null and surface no Copy). Row Paste selects the target\r\n // and queues the paste.\r\n // ---------------------------------------------------------------------------\r\n const rowClipboard = enableClipboard ? (record: RecordSummary) => {\r\n const summaryHasData = record.data != null;\r\n const sourceParsed: ParsedRef = record.scope;\r\n\r\n const compat = clipboard.entry\r\n ? checkPasteCompatibility(\r\n { kind: clipboard.entry.sourceScope, raw: clipboard.entry.sourceRef },\r\n sourceParsed,\r\n )\r\n : null;\r\n const sameRef = clipboard.entry?.sourceRef === record.ref;\r\n\r\n return {\r\n onCopy: summaryHasData ? () => {\r\n const value = onCopyOverride\r\n ? onCopyOverride({ value: record.data as TData, scope: sourceParsed })\r\n : cloneValue(record.data as TData);\r\n clipboard.set({\r\n value,\r\n sourceScope: sourceParsed.kind,\r\n sourceRef: record.ref,\r\n sourceLabel: record.label,\r\n });\r\n onTelemetry?.({ type: 'clipboard.copy', recordType, sourceRef: record.ref });\r\n setClipboardNotice({\r\n message: i18n.copyToast.replace('{name}', record.label),\r\n variant: 'copy',\r\n });\r\n } : undefined,\r\n onPaste: () => {\r\n // Select the row in the rail (drives editingScope), then queue paste.\r\n onLeftSelectRef.current?.(record);\r\n setPendingPasteRef(record.ref);\r\n },\r\n canPaste: !!clipboard.entry && !sameRef && (compat?.status !== 'denied'),\r\n pasteWillReplace: record.status === 'configured',\r\n clipboardSourceLabel: clipboard.entry?.sourceLabel,\r\n };\r\n } : undefined;\r\n\r\n // The rail's `onLeftSelect` is defined further down, but the rowClipboard\r\n // closure needs it. Capture the latest reference via a ref.\r\n const onLeftSelectRef = useRef<((item: RecordSummary) => void) | null>(null);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Collection-cardinality item handlers — open / create / delete. Each\r\n // routes through the dirty-nav guard so unsaved edits aren't silently lost.\r\n // ---------------------------------------------------------------------------\r\n const baseScopeRef = editingScope?.raw ?? '';\r\n const itemNounLabel = itemNoun || 'item';\r\n\r\n // Build the URL-facing `item` value: bare id at the collection root, full\r\n // ref like `product:abc/item:foo` when the item lives under a scope.\r\n const buildItemUrlValue = useCallback((id: string): string => {\r\n return baseScopeRef ? `${baseScopeRef}/item:${id}` : id;\r\n }, [baseScopeRef]);\r\n\r\n const onItemOpen = useCallback((itemId: string) => {\r\n if (!isCollection) return;\r\n void runWithGuard(() => {\r\n setSelectedItemId(itemId);\r\n onTelemetry?.({ type: 'item.open', recordType, scopeRef: baseScopeRef, itemId });\r\n deepLinkState.emit({ item: buildItemUrlValue(itemId) }, 'item.open');\r\n });\r\n }, [isCollection, runWithGuard, onTelemetry, recordType, baseScopeRef, deepLinkState, buildItemUrlValue]);\r\n\r\n const onItemCreate = useCallback(() => {\r\n if (!isCollection) return;\r\n void runWithGuard(() => {\r\n const id = generateItemId ? generateItemId() : defaultItemId();\r\n setSelectedItemId(id);\r\n onTelemetry?.({ type: 'item.create', recordType, scopeRef: baseScopeRef });\r\n deepLinkState.emit({ item: buildItemUrlValue(id) }, 'item.open');\r\n });\r\n }, [isCollection, runWithGuard, generateItemId, onTelemetry, recordType, baseScopeRef, deepLinkState, buildItemUrlValue]);\r\n\r\n const onItemDelete = useCallback(async (itemId: string) => {\r\n if (!isCollection) return;\r\n const ref = buildItemRef(baseScopeRef, itemId);\r\n // Delegate to the host's pre-delete hook when supplied. Same UX as the\r\n // editor's own Delete button.\r\n if (onBeforeDelete) {\r\n const ok = await onBeforeDelete(parseRef(ref));\r\n if (!ok) return;\r\n }\r\n try {\r\n const { deleteRecord } = await import('../data/records');\r\n await deleteRecord(ctx, ref);\r\n onTelemetry?.({ type: 'item.delete', recordType, scopeRef: baseScopeRef, itemId });\r\n // If the user happened to have this item open, drop back to the list.\r\n if (selectedItemId === itemId) setSelectedItemId(null);\r\n // If the URL pointed at the now-deleted item, clear it.\r\n if (selectedItemId === itemId) deepLinkState.emit({ item: null }, 'item.close');\r\n collectionItems.refetch();\r\n } catch (err) {\r\n // eslint-disable-next-line no-console\r\n console.error('[RecordsAdminShell] item delete failed', err);\r\n }\r\n }, [\r\n isCollection, baseScopeRef, ctx, onBeforeDelete, onTelemetry, recordType,\r\n selectedItemId, collectionItems, deepLinkState,\r\n ]);\r\n\r\n const itemViewCtx = useMemo(() => ({\r\n onOpen: onItemOpen,\r\n onCreate: onItemCreate,\r\n onDelete: (id: string) => { void onItemDelete(id); },\r\n scope: editingScope ?? parseRef(''),\r\n selectedId: selectedItemId ?? undefined,\r\n isLoading: collectionItems.isLoading,\r\n }), [onItemOpen, onItemCreate, onItemDelete, editingScope, selectedItemId, collectionItems.isLoading]);\r\n\r\n // Sibling navigation in the editor — Back / prev / next.\r\n const itemPosition = useMemo(() => {\r\n if (!isCollection || !selectedItemId) return null;\r\n const idx = collectionItems.items.findIndex((it) => it.itemId === selectedItemId);\r\n if (idx < 0) return null;\r\n return { index: idx, total: collectionItems.items.length };\r\n }, [isCollection, selectedItemId, collectionItems.items]);\r\n\r\n const onItemBack = useCallback(() => {\r\n void runWithGuard(() => {\r\n setSelectedItemId(null);\r\n deepLinkState.emit({ item: null }, 'item.close');\r\n });\r\n }, [runWithGuard, deepLinkState]);\r\n\r\n // Prev/next siblings move via `item.step` so the URL replaces rather than\r\n // pushes — keeps the back stack meaningful (back goes to the *list*, not\r\n // through every sibling you flicked past).\r\n const stepToItem = useCallback((id: string) => {\r\n void runWithGuard(() => {\r\n setSelectedItemId(id);\r\n onTelemetry?.({ type: 'item.open', recordType, scopeRef: baseScopeRef, itemId: id });\r\n deepLinkState.emit({ item: buildItemUrlValue(id) }, 'item.step');\r\n });\r\n }, [runWithGuard, onTelemetry, recordType, baseScopeRef, deepLinkState, buildItemUrlValue]);\r\n\r\n const onItemPrev = useCallback(() => {\r\n if (!itemPosition || itemPosition.index <= 0) return;\r\n const next = collectionItems.items[itemPosition.index - 1];\r\n if (next?.itemId) stepToItem(next.itemId);\r\n }, [itemPosition, collectionItems.items, stepToItem]);\r\n\r\n const onItemNext = useCallback(() => {\r\n if (!itemPosition || itemPosition.index >= itemPosition.total - 1) return;\r\n const next = collectionItems.items[itemPosition.index + 1];\r\n if (next?.itemId) stepToItem(next.itemId);\r\n }, [itemPosition, collectionItems.items, stepToItem]);\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 (!editingTargetScope) 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={editingTargetScope}\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 // Editor-item nav (Back / position / prev / next) renders above the\r\n // editor whenever an item is open in collection mode. Inserted via\r\n // RecordEditor's `headerExtra` slot if available — fall back to wrapping.\r\n const itemNav = isCollection && selectedItemId && itemPosition ? (\r\n <EditorItemNav\r\n label={editorHeaderLabel}\r\n position={itemPosition.index + 1}\r\n total={itemPosition.total}\r\n onBack={onItemBack}\r\n onPrev={onItemPrev}\r\n onNext={onItemNext}\r\n canPrev={itemPosition.index > 0}\r\n canNext={itemPosition.index < itemPosition.total - 1}\r\n i18n={i18n}\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 && editingTargetScope\r\n ? () => onBeforeDelete(editingTargetScope)\r\n : undefined}\r\n headerLabel={editorHeaderLabel}\r\n headerSubtitle={editorHeaderSubtitle}\r\n headerMeta={editorHeaderMeta}\r\n clipboard={editorClipboard}\r\n actionLabels={actionLabels}\r\n actionIcons={actionIcons}\r\n >\r\n {renderEditor(editorCtx)}\r\n </RecordEditor>\r\n );\r\n\r\n // Wrap any rendered editor variant with the item nav strip on top.\r\n const withNav = (node: ReactNode): ReactNode => itemNav ? (\r\n <div className=\"flex flex-col h-full min-h-0\">\r\n {itemNav}\r\n <div className=\"flex-1 min-h-0 overflow-hidden\">{node}</div>\r\n </div>\r\n ) : node;\r\n\r\n // No preview supplied → just the editor.\r\n if (!previewBody) return withNav(baseEditor());\r\n\r\n if (previewMode === 'inline') {\r\n return withNav(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 withNav(\r\n <div className=\"relative h-full\">\r\n {baseEditor()}\r\n <button\r\n type=\"button\"\r\n className=\"ra-preview-reopen\"\r\n onClick={() => setSidePreviewOpen(true)}\r\n aria-label={i18n.openPreview}\r\n title={i18n.openPreview}\r\n >\r\n <Eye aria-hidden=\"true\" />\r\n {i18n.preview}\r\n </button>\r\n </div>,\r\n );\r\n }\r\n return withNav(\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 withNav(\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 withNav(\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 // Rule / Global tabs surface records straight from `recordList`. Facet\r\n // keeps the existing facet-vocabulary-driven rail (synthesises rows for\r\n // facet values that don't yet have a record).\r\n const isRuleTab = activeScope === 'rule';\r\n const isGlobalTab = activeScope === 'collection';\r\n const isRecordsTab = isRuleTab || isGlobalTab;\r\n\r\n const leftItems = isProductTab\r\n ? productListItems\r\n : isRecordsTab\r\n ? recordList.items\r\n : facetBrowse.items;\r\n const leftLoading = isProductTab\r\n ? (!productPinned && productBrowse.isLoading)\r\n : isRecordsTab\r\n ? (recordList.isLoading || probe.isLoading)\r\n : (facetBrowse.isLoading || recordList.isLoading || probe.isLoading);\r\n const leftError = isProductTab\r\n ? productBrowse.error\r\n : isRecordsTab\r\n ? recordList.error\r\n : (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 // Keep the ref pointed at the latest selector so the rowClipboard closure\r\n // — created earlier in this render pass — can call into it.\r\n onLeftSelectRef.current = onLeftSelect;\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 {pasteConfirm.dialog}\r\n {clipboardNotice && (\r\n <ClipboardToast\r\n message={clipboardNotice.message}\r\n variant={clipboardNotice.variant}\r\n onDismiss={() => setClipboardNotice(null)}\r\n />\r\n )}\r\n {/* Floating help — overlays the top-right of the shell when there's no\r\n * header card. Doesn't reserve layout space so it never pushes the\r\n * rail/editor content down. */}\r\n {(() => {\r\n const showFloatHelp =\r\n !!intro && dismissed\r\n && resolvedReopenAffordance === 'footer'\r\n && !headerWillRender;\r\n if (!showFloatHelp) return null;\r\n const reopenLabel = intro?.reopenLabel ?? `How ${label.toLowerCase()} works`;\r\n return (\r\n <button\r\n type=\"button\"\r\n className=\"ra-help-float\"\r\n onClick={undismiss}\r\n aria-label={reopenLabel}\r\n title={reopenLabel}\r\n >\r\n <HelpCircle aria-hidden=\"true\" />\r\n <span>{reopenLabel}</span>\r\n </button>\r\n );\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 if (!headerWillRender) return null;\r\n const showHeaderReopen =\r\n !!intro && dismissed && resolvedReopenAffordance === 'header';\r\n const reopenLabel = intro?.reopenLabel ?? `How ${label.toLowerCase()} works`;\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 trailingSlot={showHeaderReopen ? (\r\n <button\r\n type=\"button\"\r\n onClick={undismiss}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n aria-label={reopenLabel}\r\n title={reopenLabel}\r\n style={{ width: '2rem', height: '2rem', padding: 0, justifyContent: 'center' }}\r\n >\r\n <HelpCircle className=\"w-4 h-4\" />\r\n </button>\r\n ) : undefined}\r\n />\r\n );\r\n })()}\r\n {resolvedReopenAffordance === 'inline' ? (\r\n <UtilityRow\r\n label={intro?.reopenLabel ? '' : label}\r\n customLabel={intro?.reopenLabel}\r\n introHidden={dismissed && !!intro}\r\n onShowIntro={undismiss}\r\n />\r\n ) : null}\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={actionLabels?.save ?? i18n.save}\r\n discardLabel={actionLabels?.discard ?? i18n.discard}\r\n SaveIcon={actionIcons?.save}\r\n DiscardIcon={actionIcons?.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 {isCollection && selectedItemId && collectionRailMode === 'siblings' ? (\r\n <SiblingRail\r\n items={collectionItems.items}\r\n selectedItemId={selectedItemId}\r\n isLoading={collectionItems.isLoading}\r\n error={collectionItems.error}\r\n onBack={onItemBack}\r\n onSelect={onItemOpen}\r\n i18n={i18n}\r\n />\r\n ) : (\r\n <>\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 {/* Collection-mode \"+ New\" lives in the right-pane toolbar now. */}\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 groupBy={effectiveGroupBy}\r\n rowClipboard={rowClipboard}\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 </>\r\n )}\r\n </aside>\r\n <main className=\"overflow-hidden\">\r\n {/* Collection mode: scope selected, no item open → item list view. */}\r\n {isCollection && editingScope && !selectedItemId && (\r\n <ItemListView\r\n items={collectionItems.items}\r\n isLoading={collectionItems.isLoading}\r\n error={collectionItems.error}\r\n ctx={itemViewCtx}\r\n itemNoun={itemNounLabel}\r\n view={itemView}\r\n views={itemViews}\r\n onViewChange={onItemViewChange}\r\n renderItemList={renderItemList}\r\n renderItemCard={renderItemCard}\r\n renderItemEmpty={renderItemEmpty}\r\n itemColumns={itemColumns}\r\n i18n={i18n}\r\n />\r\n )}\r\n {!isCollection && !editingScope && activeScope === 'product' && !selectedProductId && (\r\n <EmptyState title={i18n.emptyTitle} body={i18n.emptyBody} />\r\n )}\r\n {!isCollection && !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 In collection mode the editor only shows once an item is open;\r\n otherwise the item list view above takes the pane. */}\r\n {isProductTab && selectedProductId && (!isCollection || selectedItemId) && (\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 hideSingleTab={editorTabs === 'off' || editorTabs === 'multi'}\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 {editingTargetScope ? 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 (singleton mode), or the\r\n editor when an item is open (collection mode). */}\r\n {!isProductTab && editingTargetScope && (!isCollection || selectedItemId) && 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};","// =============================================================================\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\nimport { RowContextMenu } from './RowContextMenu';\r\nimport { DEFAULT_I18N } from '../types';\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, onCopy, onPaste, canPaste, pasteWillReplace, clipboardSourceLabel } = 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=\"flex items-start gap-1.5 min-w-0\">\r\n <div className=\"ra-row-title flex-1 min-w-0\">{record.label}</div>\r\n {(onCopy || onPaste) && (\r\n <RowContextMenu\r\n onCopy={onCopy}\r\n onPaste={onPaste}\r\n canPaste={canPaste}\r\n pasteWillReplace={pasteWillReplace}\r\n pasteSourceLabel={clipboardSourceLabel}\r\n i18n={{\r\n copy: DEFAULT_I18N.copy,\r\n paste: DEFAULT_I18N.paste,\r\n pasteFrom: DEFAULT_I18N.pasteFrom,\r\n pasteReplace: DEFAULT_I18N.pasteReplace,\r\n clipboardEmpty: DEFAULT_I18N.clipboardEmpty,\r\n }}\r\n />\r\n )}\r\n </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","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/types/deepLink.ts","../../../src/components/RecordsAdmin/data/refs.ts","../../../src/components/RecordsAdmin/hooks/useRecordList.ts","../../../src/components/RecordsAdmin/data/resolveRecord.ts","../../../src/components/RecordsAdmin/hooks/useResolvedRecord.ts","../../../src/components/RecordsAdmin/hooks/useRulePreview.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/hooks/usePasteConfirm.tsx","../../../src/components/RecordsAdmin/hooks/useRecordClipboard.ts","../../../src/components/RecordsAdmin/browser/ScopeTabs.tsx","../../../src/components/RecordsAdmin/browser/StatusFilterPills.tsx","../../../src/components/RecordsAdmin/browser/StatusIcon.tsx","../../../src/components/RecordsAdmin/browser/RowContextMenu.tsx","../../../src/components/RecordsAdmin/browser/formatFacetRule.ts","../../../src/components/RecordsAdmin/browser/DefaultRecordRow.tsx","../../../src/components/RecordsAdmin/browser/RecordList.tsx","../../../src/components/RecordsAdmin/browser/RuleFilterChips.tsx","../../../src/components/RecordsAdmin/browser/EmptyStates.tsx","../../../src/components/RecordsAdmin/browser/PresentationSwitcher.tsx","../../../src/components/RecordsAdmin/hooks/usePresentationPref.ts","../../../src/components/RecordsAdmin/hooks/useCollectionItems.ts","../../../src/components/RecordsAdmin/data/deepLinkAdapter.ts","../../../src/components/RecordsAdmin/hooks/useDeepLinkState.ts","../../../src/components/RecordsAdmin/shell/ScopeBreadcrumb.tsx","../../../src/components/RecordsAdmin/editor/BulkActionsMenu.tsx","../../../src/components/RecordsAdmin/browser/StatusDot.tsx","../../../src/components/RecordsAdmin/editor/DeleteButton.tsx","../../../src/components/RecordsAdmin/editor/RecordEditor.tsx","../../../src/components/RecordsAdmin/editor/RecordTargeting.tsx","../../../src/components/RecordsAdmin/editor/ProductDrillDown.tsx","../../../src/components/RecordsAdmin/editor/PreviewPane.tsx","../../../src/components/RecordsAdmin/editor/PreviewScopePicker.tsx","../../../src/components/RecordsAdmin/items/ItemViewSwitcher.tsx","../../../src/components/RecordsAdmin/items/DefaultItemTable.tsx","../../../src/components/RecordsAdmin/items/DefaultItemCards.tsx","../../../src/components/RecordsAdmin/items/ItemListView.tsx","../../../src/components/RecordsAdmin/items/EditorItemNav.tsx","../../../src/components/RecordsAdmin/items/SiblingRail.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/shell/ClipboardToast.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/browser/DefaultRecordCard.tsx","../../../src/components/RecordsAdmin/editor/InheritanceMarker.tsx","../../../src/components/RecordsAdmin/editor/ResolvedPreview.tsx","../../../src/components/RecordsAdmin/hooks/useResolveAllRecords.ts","../../../src/components/RecordsAdmin/hooks/useCollectedRecords.ts","../../../src/components/RecordsAdmin/hooks/useMergedRecord.ts"],"names":["eq","classify","total","useState","useEffect","useQuery","useQueryClient","useRef","useCallback","useMemo","QK","useInfiniteQuery","items","res","jsx","DEFAULTS","jsxs","MoreHorizontal","Copy","Inbox","QK_BASE","toSummary","Layers","Upload","Download","ChevronDown","Trash2","Fragment","ClipboardPaste","ChevronRight","Package","Eye","ICONS","TableIcon","LayoutGrid","ImageIcon","labelFor","Pencil","Plus","PlusIcon","ArrowLeft","Lightbulb","CheckCircle2","AlertTriangle","X","AlertCircle","CopyIcon","deleteRecord","label","HelpCircle","Search","initials","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 SlidersHorizontal,\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: {\r\n collection: Globe,\r\n product: Package,\r\n variant: Layers,\r\n batch: Boxes,\r\n facet: Tag,\r\n universal: Globe,\r\n rule: SlidersHorizontal,\r\n },\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 presentationCompact: string;\r\n\r\n /** Right-pane item view (collection cardinality) switcher labels. */\r\n itemViewTable: string;\r\n itemViewCards: string;\r\n itemViewGallery: 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 * Right-pane multi-item flow strings (collection cardinality).\r\n * `{noun}` is replaced with `itemNoun` (e.g. \"recipe\", \"FAQ\").\r\n */\r\n backToList: string;\r\n prevItem: string;\r\n nextItem: string;\r\n itemListTitle: string;\r\n /** Friendly singular for table column header in built-in default. */\r\n itemColumnLabel: string;\r\n itemColumnUpdated: string;\r\n itemActions: string;\r\n\r\n /** Sibling rail (rail flips to items when one is open). */\r\n backToScopes: string;\r\n siblingsHeading: 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 /** Clipboard / copy-paste affordance. */\r\n copy: string;\r\n paste: string;\r\n pasteFrom: string;\r\n pasteReplace: string;\r\n clipboardEmpty: string;\r\n copyToast: string;\r\n pasteToast: string;\r\n /** Confirm dialog when pasting onto a destination with an existing saved value. */\r\n pasteConfirmTitle: string;\r\n pasteConfirmBody: string;\r\n pasteConfirmReplace: string;\r\n pasteConfirmCancel: string;\r\n /** Cross-scope warning copy (e.g. variant → product). */\r\n pasteWarnTitle: string;\r\n pasteWarnContinue: 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 presentationCompact: 'Compact',\r\n itemViewTable: 'Table',\r\n itemViewCards: 'Cards',\r\n itemViewGallery: 'Gallery',\r\n newItem: 'New item',\r\n noItemsTitle: 'No items yet',\r\n noItemsBody: 'Create your first item to get started.',\r\n backToList: 'Back to list',\r\n prevItem: 'Previous',\r\n nextItem: 'Next',\r\n itemListTitle: 'Items',\r\n itemColumnLabel: 'Name',\r\n itemColumnUpdated: 'Updated',\r\n itemActions: 'Actions',\r\n backToScopes: '← All scopes',\r\n siblingsHeading: 'Items in this scope',\r\n railEmptyTitle: 'No records yet',\r\n railEmptyBody: 'Records you create will appear here.',\r\n copy: 'Copy',\r\n paste: 'Paste',\r\n pasteFrom: 'Paste from {name}',\r\n pasteReplace: 'Paste (replace)',\r\n clipboardEmpty: 'Nothing to paste',\r\n copyToast: 'Copied {name}. Pick a destination to paste.',\r\n pasteToast: 'Pasted from {name}. Review and Save.',\r\n pasteConfirmTitle: 'Replace existing values?',\r\n pasteConfirmBody: '{destination} already has saved values. Replace them with the copied values?',\r\n pasteConfirmReplace: 'Replace',\r\n pasteConfirmCancel: 'Cancel',\r\n pasteWarnTitle: 'Cross-scope paste',\r\n pasteWarnContinue: 'Continue',\r\n};","// =============================================================================\r\n// RecordsAdmin — Rail presentation, item view, and cardinality\r\n// =============================================================================\r\n\r\n/**\r\n * How records are laid out in the **left rail** (the navigator).\r\n *\r\n * The rail is intentionally a dense tree/list — cards or galleries belong on\r\n * the right pane, not in a 260px column. Only the row densities are offered:\r\n *\r\n * - `list` → dense rows with status dot + label + subtitle (default).\r\n * - `compact` → minimal one-line rows (no subtitle, no status dot).\r\n */\r\nexport type RecordPresentation = 'list' | 'compact';\r\n\r\nexport const ALL_PRESENTATIONS: RecordPresentation[] = ['list', 'compact'];\r\n\r\n/**\r\n * How a multi-item collection is rendered in the **right pane** when a scope\r\n * is selected and no item is open. Right-pane only — cards and galleries\r\n * have the room to breathe here.\r\n *\r\n * - `table` → declarative columns (built-in default with `itemColumns`).\r\n * - `cards` → square cards with thumbnail + label.\r\n * - `gallery` → larger 16:9 cards with thumbnail + label + subtitle.\r\n */\r\nexport type ItemView = 'table' | 'cards' | 'gallery';\r\n\r\nexport const ALL_ITEM_VIEWS: ItemView[] = ['table', 'cards', 'gallery'];\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\r\n/**\r\n * What the left rail shows once an item is open in the editor (collection\r\n * cardinality only):\r\n *\r\n * - `siblings` *(default)* — rail flips to the list of items in the current\r\n * scope. Click any sibling to switch instantly. A pinned `← All scopes`\r\n * link returns to scope navigation.\r\n * - `scopes` — rail keeps showing scopes. Switching items requires going\r\n * back to the right-pane list first.\r\n */\r\nexport type CollectionRailMode = 'siblings' | 'scopes';","// =============================================================================\r\n// RecordsAdmin — Deep linking types\r\n//\r\n// The shell can mirror its own state (current scope, open item, right-pane\r\n// view) into URL query parameters so deep links into a specific record open\r\n// to the right place, and the browser back/forward buttons feel native.\r\n//\r\n// We deliberately keep the URL surface small:\r\n// - `item` → either a bare item id (`comp_winter_2026`, for items at the\r\n// collection root) or a full item ref including scope\r\n// (`product:abc/item:comp_winter_2026`). Either way the ref\r\n// carries enough information to resolve the item and derive\r\n// the scope, so we never need a separate `scope` param when\r\n// an item is open.\r\n// - `scope` → scope ref (e.g. `facet:region=eu` or `product:abc`). Used\r\n// only when no item is open, to deep-link to a list view.\r\n// - `view` → right-pane view (`table` / `cards` / `gallery`). Optional\r\n// UI preference — not part of \"what's open\".\r\n//\r\n// The shell never owns platform context (`appId`, `collectionId`, etc.) —\r\n// those live in the host's URL already and are out of scope here.\r\n// =============================================================================\r\n\r\n/**\r\n * How URL changes are pushed onto the browser history.\r\n *\r\n * - `push` — every change adds a history entry (rich back stack).\r\n * - `replace` — every change replaces the current entry (no history bloat).\r\n * - `smart` — meaningful navigation (open item, change scope) pushes;\r\n * cosmetic changes (toggle view, prev/next sibling) replace.\r\n * Default.\r\n */\r\nexport type DeepLinkHistoryMode = 'push' | 'replace' | 'smart';\r\n\r\n/**\r\n * Customise the URL parameter names the shell reads / writes. Useful when\r\n * a host already uses one of these keys for something else.\r\n */\r\nexport interface DeepLinkParamNames {\r\n /** Default `'item'`. */\r\n item?: string;\r\n /** Default `'scope'`. */\r\n scope?: string;\r\n /** Default `'view'`. */\r\n view?: string;\r\n}\r\n\r\n/**\r\n * The shell-owned deep-link state. All fields are optional — `null` /\r\n * `undefined` means \"absent from the URL\".\r\n */\r\nexport interface DeepLinkState {\r\n /** Item id when an item is open in the editor. */\r\n item?: string | null;\r\n /** Scope ref when no item is open and the user is browsing a list. */\r\n scope?: string | null;\r\n /** Right-pane view choice (`table` / `cards` / `gallery`). */\r\n view?: string | null;\r\n}\r\n\r\n/**\r\n * Pluggable bridge between the shell and the host's URL. Hosts can supply\r\n * their own adapter to integrate with React Router, hash routing, the\r\n * SmartLinks `persistentQueryParams` helper, etc. When omitted the shell\r\n * falls back to a plain `window.location` + `window.history` adapter.\r\n */\r\nexport interface DeepLinkAdapter {\r\n /** Read the current values for the shell-owned params. */\r\n read(): DeepLinkState;\r\n /**\r\n * Write a partial state update. `mode` is the resolved push/replace hint\r\n * (the shell already mapped `'smart'` to one of the two before calling).\r\n * Hosts should preserve every other URL parameter — only the keys\r\n * supplied here may be touched.\r\n */\r\n write(partial: DeepLinkState, mode: 'push' | 'replace'): void;\r\n /**\r\n * Subscribe to external URL changes (back/forward, host-driven nav).\r\n * Should fire whenever the params the shell cares about may have\r\n * changed. Returns an unsubscribe function.\r\n */\r\n subscribe(listener: () => void): () => void;\r\n}\r\n\r\nexport interface DeepLinkOptions {\r\n /** Master switch — default `false` (opt in per app). */\r\n enabled?: boolean;\r\n /** Push/replace strategy. Default `'smart'`. */\r\n history?: DeepLinkHistoryMode;\r\n /** Override the default param key names. */\r\n paramNames?: DeepLinkParamNames;\r\n /**\r\n * Pluggable URL bridge. Defaults to `window.location` + `window.history`\r\n * with a `popstate` subscription. Provide one when the host owns routing\r\n * (React Router, hash router, iframe postMessage relay, etc.).\r\n */\r\n adapter?: DeepLinkAdapter;\r\n}\r\n\r\n/**\r\n * Resolved param names — everywhere outside the public surface uses these\r\n * to avoid the optional-key ceremony.\r\n */\r\nexport interface ResolvedDeepLinkParamNames {\r\n item: string;\r\n scope: string;\r\n view: string;\r\n}\r\n\r\nexport const DEFAULT_DEEP_LINK_PARAM_NAMES: ResolvedDeepLinkParamNames = {\r\n item: 'item',\r\n scope: 'scope',\r\n view: 'view',\r\n};","// =============================================================================\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 // `rule` records carry an opaque id under the `rule:` prefix; we expose\r\n // the id via `productId`-equivalent slot to keep ParsedRef flat. Resolved\r\n // refs use the `ruleId` field (added below) so callers can disambiguate.\r\n rule: 'ruleId' as keyof ParsedRef,\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' | 'item';\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 === 'item') {\r\n // Item segments don't change `kind` — they're sub-keys under whatever\r\n // scope they appended to (or the collection root when alone).\r\n parsed.itemId = id;\r\n continue;\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 itemId?: 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 if (a.itemId) parts.push(`item:${a.itemId}`);\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 // Terminal rung — collection-wide default. Empty ref string targets the\r\n // app+collection record(s) with no further qualifier.\r\n if (supportedScopes.includes('collection')) {\r\n chain.push('');\r\n }\r\n // Dedupe while preserving order\r\n return Array.from(new Set(chain));\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Item-aware helpers (collection cardinality)\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Strip the trailing `/item:{id}` (or leading `item:{id}`) from a ref and\r\n * return both halves. For singleton refs `itemId` is `undefined` and\r\n * `scopeRef` equals the input.\r\n */\r\nexport const splitItemRef = (raw: string): { scopeRef: string; itemId?: string } => {\r\n if (!raw) return { scopeRef: '' };\r\n const segs = raw.split('/').filter(Boolean);\r\n const last = segs[segs.length - 1];\r\n if (last && last.startsWith('item:')) {\r\n return { scopeRef: segs.slice(0, -1).join('/'), itemId: last.slice('item:'.length) };\r\n }\r\n return { scopeRef: raw };\r\n};\r\n\r\n/** Concatenate a scope ref (possibly empty for collection) and an itemId. */\r\nexport const buildItemRef = (scopeRef: string, itemId: string): string => {\r\n return scopeRef ? `${scopeRef}/item:${itemId}` : `item:${itemId}`;\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, FacetRule } 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\n/**\r\n * Decide which records belong on which top-level scope tab.\r\n *\r\n * - `rule` — anything carrying a server-side `facetRule` (or whose\r\n * ref starts with `rule:` for forward-compat).\r\n * - `collection` — \"Global\" records: no pinned scope and no facetRule.\r\n * Critical for migrations where existing FAQs / SOPs /\r\n * recipes were created without a `ref`.\r\n * - `product`/`variant`/`batch`/`facet` — pinned-scope records, as before.\r\n *\r\n * Rule and Global records must NEVER leak into the pinned tabs (they'd\r\n * appear duplicated under every facet otherwise).\r\n */\r\nconst matchesScope = (\r\n kind: ScopeKind,\r\n rec: AppRecord,\r\n p: ParsedRef,\r\n): boolean => {\r\n const hasRule = !!(rec as { facetRule?: FacetRule | null }).facetRule\r\n || (rec.ref ?? '').startsWith('rule:');\r\n if (kind === 'rule') return hasRule;\r\n if (hasRule) return false;\r\n\r\n if (kind === 'collection') {\r\n // \"Global\" — no pinned scope at all. Empty/missing ref counts.\r\n return !p.productId && !p.facetId && !p.variantId && !p.batchId && !p.proofId;\r\n }\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 const facetRule = (rec as { facetRule?: FacetRule | null }).facetRule ?? null;\r\n // Friendly fallback for rule and global records — keeps the list readable\r\n // even before the host wires a `classify` / row renderer.\r\n // For rule records, prefer a count-based title (\"Rule · 3 facets\") so the\r\n // dense per-clause chips below can carry the detail.\r\n const ruleLabel = facetRule && facetRule.all && facetRule.all.length > 0\r\n ? (facetRule.all.length === 1 ? 'Rule · 1 facet' : `Rule · ${facetRule.all.length} facets`)\r\n : null;\r\n const fallbackLabel = scope.batchId ?? scope.variantId ?? scope.productId\r\n ?? scope.facetValue ?? scope.facetId\r\n ?? ruleLabel\r\n ?? (ref.startsWith('rule:') ? 'Rule-targeted record' : (ref || 'Global record'));\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: fallbackLabel,\r\n updatedAt: rec.updatedAt,\r\n facetRule,\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((rec) => ({ rec, summary: toSummary(rec) }))\r\n .filter(({ rec, summary }) => matchesScope(scopeKind, rec, summary.scope))\r\n .filter(({ summary }) => matchesContext(summary.scope, contextScope))\r\n .map(({ summary }) => ({ ...summary, status: cls(summary) }));\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, getRecordByRef, 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 // Rule-targeted records are addressed by their `rule:{id}` ref directly.\r\n // The inheritance chain doesn't apply — there's at most one record at this\r\n // ref, and it either exists (self) or it doesn't (empty). Going through\r\n // `match()` here would either return nothing (no product target) or every\r\n // global record in the app, both of which are wrong.\r\n if (args.target.kind === 'rule' && args.target.raw) {\r\n const rec = await getRecordByRef(args.ctx, args.target.raw).catch(() => null);\r\n if (!rec) return { data: null, source: 'empty' };\r\n const recFacetRule = (rec as unknown as { facetRule?: import('./sdkTypes').FacetRule | null }).facetRule ?? null;\r\n return {\r\n data: rec.data as T,\r\n source: 'self',\r\n sourceRef: rec.ref ?? args.target.raw,\r\n facetRule: recFacetRule,\r\n };\r\n }\r\n\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 /**\r\n * Optional raw ref. Required for rule-targeted records (`rule:{id}`) so the\r\n * resolver can look them up by ref instead of running an inheritance chain.\r\n * For pinned scopes this can be left empty — the structured scope ids are\r\n * sufficient.\r\n */\r\n ref?: 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 ref?: 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.ref ?? 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, ref,\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, ref, withParent,\r\n }),\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime: 15_000,\r\n queryFn: async () => {\r\n // For rule-targeted records, `parseRef(ref)` carries the ruleId and\r\n // `kind: 'rule'` — `resolveRecord` short-circuits to a direct lookup.\r\n const target = ref ? parseRef(ref) : 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}","// =============================================================================\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\n/**\r\n * True when a rule is structurally valid for save / preview. A rule must\r\n * have at least one clause and every clause must specify a facet key plus\r\n * at least one selected value. Used by `useRulePreview` to skip pointless\r\n * server calls and re-exported so the editor can disable the Save button\r\n * (admins were able to save `{ all: [{ facetKey, anyOf: [] }] }` and got a\r\n * 500 from the server — that's now caught client-side).\r\n */\r\nexport const isFacetRuleValid = (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 = isFacetRuleValid(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}","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 type { FacetRule } from '../data/sdkTypes';\r\nimport { resolvedRecordQueryKey } from './useResolvedRecord';\r\nimport { isFacetRuleValid } from './useRulePreview';\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 * Initial facet rule for the record. Required for rule-targeted scopes —\r\n * pass `null` (or `{ all: [] }`) for a freshly minted `rule:{id}` ref so\r\n * the Targeting section has somewhere to author into. Ignored for pinned\r\n * scopes unless the host explicitly opts a record into rule targeting.\r\n */\r\n initialFacetRule?: FacetRule | null;\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', initialFacetRule = null,\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 const [facetRule, setFacetRule] = useState<FacetRule | null>(initialFacetRule);\r\n const [savedFacetRule, setSavedFacetRule] = useState<FacetRule | null>(initialFacetRule);\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 // Reset rule state when the editing target changes (different scope or\r\n // the resolved record's identity flipped). The host re-supplies the\r\n // initial rule via `initialFacetRule` keyed by scope.\r\n setFacetRule(initialFacetRule);\r\n setSavedFacetRule(initialFacetRule);\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 covers both record data and the attached facet rule. Inheritance\r\n // state has its own UI signal (`source`) and must not bleed into dirtiness.\r\n const isDirty = !isEqual(value, savedSnapshot) || !isEqual(facetRule, savedFacetRule);\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 previousRuleSnapshot = savedFacetRule;\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 ref: scope.raw,\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 setSavedFacetRule(facetRule);\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 facetRule,\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 setSavedFacetRule(previousRuleSnapshot);\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, facetRule, savedFacetRule, resolved.source, resolved.parentValue]);\r\n\r\n const reset = useCallback(() => {\r\n setValue(savedSnapshot);\r\n setFacetRule(savedFacetRule);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [savedSnapshot, savedFacetRule]);\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 // Rule-targeted scopes must have a valid `facetRule` before save — the\r\n // server rejects empty `anyOf` clauses with a 500 and admins were\r\n // hitting it. Pinned scopes have no rule and stay save-able.\r\n const isRuleScope = scope.kind === 'rule';\r\n const ruleValid = !isRuleScope || isFacetRuleValid(facetRule);\r\n const canSave = ruleValid;\r\n const cannotSaveReason = !ruleValid\r\n ? 'Pick at least one value for every facet in the rule before saving.'\r\n : undefined;\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 canSave,\r\n cannotSaveReason,\r\n isSaving,\r\n saveError,\r\n facetRule,\r\n onFacetRuleChange: setFacetRule,\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 /** Save / primary action label. When empty/falsy the Save button is hidden\r\n * — useful for callers (e.g. Paste confirm) that only need Discard +\r\n * Cancel as a destructive-confirm pair. */\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 {saveLabel ? (\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 ) : null}\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// usePasteConfirm — themed two-button confirm used when pasting onto a\r\n// destination that already has a saved value, or across-scope when the\r\n// rules return `warn`. Reuses the existing <ConfirmDialog> chrome by\r\n// hiding the Save slot (only Discard / Cancel are wired).\r\n// =============================================================================\r\nimport { useCallback, useRef, useState, type ReactNode } from 'react';\r\nimport { ConfirmDialog } from '../shell/ConfirmDialog';\r\n\r\ninterface PendingState {\r\n title: string;\r\n body: string;\r\n confirmLabel: string;\r\n cancelLabel: string;\r\n}\r\n\r\nconst DEFAULTS: PendingState = {\r\n title: 'Replace existing values?',\r\n body: 'This destination already has saved values. Replace them?',\r\n confirmLabel: 'Replace',\r\n cancelLabel: 'Cancel',\r\n};\r\n\r\nexport interface UsePasteConfirmReturn {\r\n confirm: (i18n?: Partial<PendingState>) => Promise<boolean>;\r\n dialog: ReactNode;\r\n}\r\n\r\nexport const usePasteConfirm = (): UsePasteConfirmReturn => {\r\n const [open, setOpen] = useState(false);\r\n const [state, setState] = useState<PendingState>(DEFAULTS);\r\n const resolverRef = useRef<((ok: boolean) => void) | null>(null);\r\n\r\n const confirm = useCallback((i18n?: Partial<PendingState>) => {\r\n setState({ ...DEFAULTS, ...(i18n ?? {}) });\r\n setOpen(true);\r\n return new Promise<boolean>((resolve) => { resolverRef.current = resolve; });\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 // 'discard' is wired as the destructive primary (Replace).\r\n r?.(choice === 'discard');\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 // Hide the third (save) slot by giving it the same handler as cancel\r\n // and a blank label. ConfirmDialog always renders three buttons; we\r\n // pass an empty save label to keep visual parity minimal.\r\n saveLabel=\"\"\r\n discardLabel={state.confirmLabel}\r\n cancelLabel={state.cancelLabel}\r\n onChoice={handleChoice}\r\n />\r\n ),\r\n };\r\n};","// =============================================================================\r\n// useRecordClipboard — in-memory + sessionStorage clipboard scoped per\r\n// (appId, recordType). Powers the shell's Copy / Paste affordance.\r\n//\r\n// One module-level store per (appId, recordType) so all subscribers — the\r\n// editor footer, every row context menu, sibling shell mounts within the\r\n// same host page — react to changes without prop drilling. SessionStorage\r\n// keeps the clipboard alive across host route changes inside the iframe.\r\n// =============================================================================\r\nimport { useCallback, useEffect, useState } from 'react';\r\nimport type { ParsedRef, ScopeKind } from '../types';\r\n\r\nexport interface ClipboardEntry<T = unknown> {\r\n value: T;\r\n sourceScope: ScopeKind | 'collection';\r\n sourceRef: string;\r\n /** Friendly label captured at copy time so paste targets can show\r\n * \"Paste from {sourceLabel}\" without re-fetching the source. */\r\n sourceLabel?: string;\r\n /** ISO timestamp — debug/telemetry only. */\r\n copiedAt: string;\r\n}\r\n\r\ntype Listener = () => void;\r\n\r\ninterface Store {\r\n entry: ClipboardEntry | null;\r\n listeners: Set<Listener>;\r\n}\r\n\r\nconst stores = new Map<string, Store>();\r\nconst storageKey = (key: string) => `ra:clipboard:${key}`;\r\n\r\nconst getStore = (key: string): Store => {\r\n let s = stores.get(key);\r\n if (!s) {\r\n s = { entry: null, listeners: new Set() };\r\n // Hydrate from sessionStorage on first access so the clipboard\r\n // survives host-side route changes within the same browsing session.\r\n if (typeof window !== 'undefined') {\r\n try {\r\n const raw = window.sessionStorage.getItem(storageKey(key));\r\n if (raw) s.entry = JSON.parse(raw) as ClipboardEntry;\r\n } catch { /* sessionStorage may be blocked — fall back to memory only */ }\r\n }\r\n stores.set(key, s);\r\n }\r\n return s;\r\n};\r\n\r\nconst persist = (key: string, entry: ClipboardEntry | null) => {\r\n if (typeof window === 'undefined') return;\r\n try {\r\n if (entry) window.sessionStorage.setItem(storageKey(key), JSON.stringify(entry));\r\n else window.sessionStorage.removeItem(storageKey(key));\r\n } catch { /* ignore quota / disabled storage */ }\r\n};\r\n\r\nconst notify = (store: Store) => {\r\n store.listeners.forEach((l) => l());\r\n};\r\n\r\nexport interface UseRecordClipboardArgs {\r\n /** Required — clipboard is scoped per app to prevent cross-app paste. */\r\n appId: string;\r\n /** Required — also scoped per record type within the app. */\r\n recordType: string;\r\n}\r\n\r\nexport interface UseRecordClipboardReturn<T = unknown> {\r\n entry: ClipboardEntry<T> | null;\r\n hasEntry: boolean;\r\n set: (entry: Omit<ClipboardEntry<T>, 'copiedAt'>) => void;\r\n clear: () => void;\r\n}\r\n\r\nconst composeKey = (appId: string, recordType: string) => `${appId}::${recordType}`;\r\n\r\nexport function useRecordClipboard<T = unknown>(\r\n args: UseRecordClipboardArgs,\r\n): UseRecordClipboardReturn<T> {\r\n const key = composeKey(args.appId, args.recordType);\r\n const store = getStore(key);\r\n const [entry, setEntry] = useState<ClipboardEntry<T> | null>(\r\n store.entry as ClipboardEntry<T> | null,\r\n );\r\n\r\n useEffect(() => {\r\n const listener: Listener = () => setEntry(store.entry as ClipboardEntry<T> | null);\r\n store.listeners.add(listener);\r\n // Sync immediately in case the store changed between render and effect.\r\n listener();\r\n return () => { store.listeners.delete(listener); };\r\n }, [store]);\r\n\r\n const set = useCallback((next: Omit<ClipboardEntry<T>, 'copiedAt'>) => {\r\n const full: ClipboardEntry<T> = { ...next, copiedAt: new Date().toISOString() };\r\n store.entry = full as ClipboardEntry;\r\n persist(key, full as ClipboardEntry);\r\n notify(store);\r\n }, [store, key]);\r\n\r\n const clear = useCallback(() => {\r\n store.entry = null;\r\n persist(key, null);\r\n notify(store);\r\n }, [store, key]);\r\n\r\n return { entry, hasEntry: entry != null, set, clear };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Cross-scope paste rules — matches the proposal's table.\r\n// ---------------------------------------------------------------------------\r\nexport type PasteCompatibility = 'allowed' | 'warn' | 'denied';\r\n\r\nexport interface PasteCompatibilityResult {\r\n status: PasteCompatibility;\r\n /** Optional short reason — surfaced as a tooltip on the Paste button. */\r\n reason?: string;\r\n}\r\n\r\n/** Sane defaults — host can override entirely via `onPaste` returning null. */\r\nexport function checkPasteCompatibility(\r\n source: ParsedRef,\r\n destination: ParsedRef,\r\n): PasteCompatibilityResult {\r\n const from = source.kind;\r\n const to = destination.kind;\r\n\r\n // Same-kind paste is always allowed (the 99% case).\r\n if (from === to) return { status: 'allowed' };\r\n\r\n // Variant/batch → product is allowed but warns: a sub-scope value is\r\n // about to override the parent's value for *all* variants/batches.\r\n if ((from === 'variant' || from === 'batch') && to === 'product') {\r\n return { status: 'warn', reason: 'This will overwrite product-level values.' };\r\n }\r\n\r\n // All remaining cross-scope pastes from the proposal table are allowed.\r\n return { status: 'allowed' };\r\n}\r\n\r\n/** Deep clone — uses `structuredClone` when available, JSON fallback otherwise. */\r\nexport function cloneValue<T>(value: T): T {\r\n if (value == null) return value;\r\n try { return structuredClone(value); }\r\n catch {\r\n try { return JSON.parse(JSON.stringify(value)) as T; }\r\n catch { return value; }\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 collection: 'Global',\r\n product: 'Products',\r\n facet: 'Shared',\r\n variant: 'Variants',\r\n batch: 'Batches',\r\n rule: 'Rules',\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};","// =============================================================================\r\n// StatusIcon — bigger, coloured replacement for the old `<StatusDot>`.\r\n// Uses the icons declared in `DEFAULT_ICONS.status` (CheckCircle2 /\r\n// ArrowDownLeft / CircleDashed) with semantic tones from tokens.css so the\r\n// rail communicates state at a glance rather than via a tiny grey dot.\r\n// =============================================================================\r\nimport type { RecordSource, RecordStatus } from '../types';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nexport type StatusTone = 'own' | 'shared' | 'missing';\r\n\r\nconst resolveTone = (\r\n source?: RecordSource, status?: RecordStatus,\r\n): StatusTone => {\r\n if (source === 'self' || status === 'configured') return 'own';\r\n if (source === 'inherited' || status === 'partial') return 'shared';\r\n return 'missing';\r\n};\r\n\r\ninterface Props {\r\n source?: RecordSource;\r\n status?: RecordStatus;\r\n className?: string;\r\n /** Override icon size (default 1.05rem). */\r\n size?: string;\r\n /** Optional accessible label — defaults to the tone name. */\r\n label?: string;\r\n}\r\n\r\nexport const StatusIcon = ({ source, status, className, size = '1.05rem', label }: Props) => {\r\n const tone = resolveTone(source, status);\r\n const Icon = DEFAULT_ICONS.status[tone === 'own' ? 'own'\r\n : tone === 'shared' ? 'inherited'\r\n : 'missing'];\r\n return (\r\n <span\r\n className={cn('ra-status-icon', `ra-status-icon--${tone}`, className)}\r\n style={{ width: size, height: size }}\r\n role={label ? 'img' : undefined}\r\n aria-label={label}\r\n aria-hidden={label ? undefined : 'true'}\r\n >\r\n <Icon className=\"w-full h-full\" />\r\n </span>\r\n );\r\n};\r\n\r\n/** Short label rendered next to / under the row title. */\r\nexport const statusToneLabel = (tone: StatusTone): string => {\r\n if (tone === 'own') return 'Configured';\r\n if (tone === 'shared') return 'Inherited';\r\n return 'Empty';\r\n};\r\n\r\nexport { resolveTone };","// =============================================================================\r\n// RowContextMenu — kebab-triggered menu surfaced on every record row/card\r\n// when the host enables clipboard. Renders Copy / Paste and short-circuits\r\n// when neither is available so empty menus never appear.\r\n// =============================================================================\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { MoreHorizontal, Copy, ClipboardPaste } from 'lucide-react';\r\n\r\nexport interface RowContextMenuProps {\r\n onCopy?: () => void;\r\n onPaste?: () => void;\r\n canPaste?: boolean;\r\n pasteWillReplace?: boolean;\r\n pasteSourceLabel?: string;\r\n i18n: {\r\n copy: string;\r\n paste: string;\r\n pasteFrom: string;\r\n pasteReplace: string;\r\n clipboardEmpty: string;\r\n };\r\n}\r\n\r\nexport const RowContextMenu = ({\r\n onCopy, onPaste, canPaste, pasteWillReplace, pasteSourceLabel, i18n,\r\n}: RowContextMenuProps) => {\r\n const [open, setOpen] = useState(false);\r\n const wrapperRef = useRef<HTMLDivElement>(null);\r\n\r\n // Click-outside / Escape close.\r\n useEffect(() => {\r\n if (!open) return;\r\n const onDoc = (e: MouseEvent) => {\r\n if (!wrapperRef.current?.contains(e.target as Node)) setOpen(false);\r\n };\r\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false); };\r\n document.addEventListener('mousedown', onDoc);\r\n document.addEventListener('keydown', onKey);\r\n return () => {\r\n document.removeEventListener('mousedown', onDoc);\r\n document.removeEventListener('keydown', onKey);\r\n };\r\n }, [open]);\r\n\r\n if (!onCopy && !onPaste) return null;\r\n\r\n const pasteLabel = !canPaste\r\n ? i18n.clipboardEmpty\r\n : pasteSourceLabel\r\n ? i18n.pasteFrom.replace('{name}', pasteSourceLabel)\r\n : pasteWillReplace\r\n ? i18n.pasteReplace\r\n : i18n.paste;\r\n\r\n return (\r\n <div ref={wrapperRef} className=\"ra-row-menu-wrap relative\">\r\n <button\r\n type=\"button\"\r\n className=\"ra-row-menu-trigger\"\r\n aria-label=\"Row actions\"\r\n aria-haspopup=\"menu\"\r\n aria-expanded={open}\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n setOpen((v) => !v);\r\n }}\r\n >\r\n <MoreHorizontal className=\"w-3.5 h-3.5\" aria-hidden=\"true\" />\r\n </button>\r\n {open && (\r\n <div role=\"menu\" className=\"ra-row-menu\" onClick={(e) => e.stopPropagation()}>\r\n {onCopy && (\r\n <button\r\n type=\"button\"\r\n role=\"menuitem\"\r\n className=\"ra-row-menu-item\"\r\n onClick={(e) => { e.stopPropagation(); setOpen(false); onCopy(); }}\r\n >\r\n <Copy className=\"w-3 h-3\" aria-hidden=\"true\" />\r\n <span>{i18n.copy}</span>\r\n </button>\r\n )}\r\n {onPaste && (\r\n <button\r\n type=\"button\"\r\n role=\"menuitem\"\r\n className=\"ra-row-menu-item\"\r\n disabled={!canPaste}\r\n onClick={(e) => { e.stopPropagation(); setOpen(false); if (canPaste) onPaste(); }}\r\n >\r\n <ClipboardPaste className=\"w-3 h-3\" aria-hidden=\"true\" />\r\n <span className=\"truncate\">{pasteLabel}</span>\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// formatFacetRule — render a FacetRule for the side rail.\r\n//\r\n// Two flavours:\r\n// * `formatFacetRule()` — single-line plain string (used for tooltips,\r\n// headers, search, and clipboard previews).\r\n// * `summarizeFacetRule()` — structured per-clause summary that the rail\r\n// renders as compact chips. This handles dense rules (think \"20 facets\"\r\n// across electronics) without the row exploding vertically.\r\n//\r\n// Examples:\r\n// { all: [{ facetKey: 'category', anyOf: ['premium'] }] }\r\n// → 'category = premium'\r\n// { all: [{ facetKey: 'region', anyOf: ['EU','UK'] },\r\n// { facetKey: 'tier', anyOf: ['gold'] }] }\r\n// → 'region ∈ {EU, UK} AND tier = gold'\r\n// =============================================================================\r\nimport type { FacetRule } from '../data/sdkTypes';\r\n\r\nexport interface FacetRuleClauseSummary {\r\n facetKey: string;\r\n values: string[];\r\n /** Human-readable rendering for a single clause, e.g. \"region: EU, UK\". */\r\n label: string;\r\n}\r\n\r\nexport function formatFacetRule(rule: FacetRule | null | undefined): string | null {\r\n if (!rule || !rule.all || rule.all.length === 0) return null;\r\n const parts = rule.all.map((c) => {\r\n const vals = (c.anyOf ?? []).filter(Boolean);\r\n if (vals.length === 0) return `${c.facetKey} (no values)`;\r\n if (vals.length === 1) return `${c.facetKey} = ${vals[0]}`;\r\n return `${c.facetKey} ∈ {${vals.join(', ')}}`;\r\n });\r\n return parts.join(' AND ');\r\n}\r\n\r\nexport function summarizeFacetRule(\r\n rule: FacetRule | null | undefined,\r\n): FacetRuleClauseSummary[] {\r\n if (!rule || !rule.all || rule.all.length === 0) return [];\r\n return rule.all.map((c) => {\r\n const values = (c.anyOf ?? []).filter(Boolean);\r\n let label: string;\r\n if (values.length === 0) label = `${c.facetKey}: —`;\r\n else if (values.length === 1) label = `${c.facetKey}: ${values[0]}`;\r\n else if (values.length <= 3) label = `${c.facetKey}: ${values.join(', ')}`;\r\n else label = `${c.facetKey}: ${values.slice(0, 2).join(', ')} +${values.length - 2}`;\r\n return { facetKey: c.facetKey, values, label };\r\n });\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 { StatusIcon, resolveTone, statusToneLabel } from './StatusIcon';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\nimport { cn } from '../../../utils/cn';\r\nimport { RowContextMenu } from './RowContextMenu';\r\nimport { DEFAULT_I18N } from '../types';\r\nimport { formatFacetRule, summarizeFacetRule } from './formatFacetRule';\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, onCopy, onPaste, canPaste, pasteWillReplace, clipboardSourceLabel } = 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 const tone = resolveTone(undefined, record.status);\r\n // Friendly subtitle. Priority:\r\n // 1. App-supplied subtitle (SKU, scope, etc.).\r\n // 2. Rule summary for facetRule records (\"category=premium AND region=EU\").\r\n // 3. Status hint as a last resort.\r\n const ruleSummary = formatFacetRule(record.facetRule);\r\n const ruleClauses = summarizeFacetRule(record.facetRule);\r\n const isRuleRecord = ruleClauses.length > 0;\r\n const subtitle = record.subtitle ?? (isRuleRecord ? null : ruleSummary) ?? (tone === 'missing'\r\n ? 'Empty — needs values'\r\n : tone === 'own' ? 'Configured' : 'Inherited');\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 data-tone={tone}\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-status\" aria-hidden=\"true\">\r\n <StatusIcon\r\n status={record.status}\r\n label={statusToneLabel(tone)}\r\n />\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 && isRuleRecord && (\r\n <div\r\n className=\"ra-row-rule-chips\"\r\n title={ruleSummary ?? undefined}\r\n aria-label={ruleSummary ?? undefined}\r\n >\r\n {ruleClauses.slice(0, 4).map((clause, i) => (\r\n <span key={`${clause.facetKey}-${i}`} className=\"ra-rule-chip\">\r\n {clause.label}\r\n </span>\r\n ))}\r\n {ruleClauses.length > 4 && (\r\n <span className=\"ra-rule-chip ra-rule-chip-more\">\r\n +{ruleClauses.length - 4}\r\n </span>\r\n )}\r\n </div>\r\n )}\r\n {!compact && !isRuleRecord && (\r\n <div className=\"ra-row-sub\">{subtitle}</div>\r\n )}\r\n </div>\r\n {/* compact rows still get a tiny status icon trailing the title */}\r\n {compact && (\r\n <StatusIcon status={record.status} size=\"0.85rem\" />\r\n )}\r\n {/* scope icon trails the row so the rail doesn't lose context */}\r\n {!compact && record.scope.kind && record.scope.kind !== 'collection' && (\r\n <span className=\"ra-row-scope\" aria-hidden=\"true\">\r\n <ScopeIcon className=\"w-3 h-3\" />\r\n </span>\r\n )}\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-dirty-pip\"\r\n />\r\n )}\r\n {(onCopy || onPaste) && (\r\n <RowContextMenu\r\n onCopy={onCopy}\r\n onPaste={onPaste}\r\n canPaste={canPaste}\r\n pasteWillReplace={pasteWillReplace}\r\n pasteSourceLabel={clipboardSourceLabel}\r\n i18n={{\r\n copy: DEFAULT_I18N.copy,\r\n paste: DEFAULT_I18N.paste,\r\n pasteFrom: DEFAULT_I18N.pasteFrom,\r\n pasteReplace: DEFAULT_I18N.pasteReplace,\r\n clipboardEmpty: DEFAULT_I18N.clipboardEmpty,\r\n }}\r\n />\r\n )}\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 { 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 /** Rail row density. Defaults to `list`. */\r\n presentation?: RecordPresentation;\r\n /** Optional custom row renderer (still dense — applied to both densities). */\r\n renderListRow?: (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 * Optional clipboard wiring per row. When provided the shell's Copy /\r\n * Paste affordance appears in each row's context menu. Returning `null`\r\n * for a row hides the menu for that row.\r\n */\r\n rowClipboard?: (record: RecordSummary) => {\r\n onCopy?: () => void;\r\n onPaste?: () => void;\r\n canPaste?: boolean;\r\n pasteWillReplace?: boolean;\r\n clipboardSourceLabel?: string;\r\n } | 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, groupBy, rowClipboard,\r\n}: Props) => {\r\n const buildCtx = (item: RecordSummary): RecordSlotContext => {\r\n const cb = rowClipboard ? rowClipboard(item) : null;\r\n return {\r\n selected: item.ref === selectedRef,\r\n onSelect: () => onSelect(item),\r\n isDirty: !!dirtyRef && item.ref === dirtyRef,\r\n ...(cb ?? {}),\r\n };\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 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// RuleFilterChips — quick-filter row above the rail when the Rules tab is\r\n// active. Lets admins narrow a long rule list by:\r\n// * facet key (only keys present in the visible rules are offered)\r\n// * complexity (\"≥3 facets\") — handy for spotting heavy multi-facet rules\r\n//\r\n// Pure presentation: state lives in the parent shell so the filter survives\r\n// list refetches and threads through the same `leftItems` derivation.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport type { RecordSummary } from '../types';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\n\r\nexport interface RuleFilters {\r\n facetKeys: string[]; // empty = all\r\n minClauses: number | null; // null = off\r\n}\r\n\r\nexport const EMPTY_RULE_FILTERS: RuleFilters = { facetKeys: [], minClauses: null };\r\n\r\nconst COMPLEXITY_THRESHOLDS = [3, 5, 10] as const;\r\n\r\nconst ruleOf = (r: RecordSummary): FacetRule | null =>\r\n (r as { facetRule?: FacetRule | null }).facetRule ?? null;\r\n\r\nexport interface RuleFilterChipsProps {\r\n /** All rule records (pre-filter) used to derive the chip vocabulary. */\r\n source: RecordSummary[];\r\n value: RuleFilters;\r\n onChange: (next: RuleFilters) => void;\r\n}\r\n\r\nexport function RuleFilterChips({ source, value, onChange }: RuleFilterChipsProps) {\r\n // Derive the facet-key vocabulary from records actually present. Sorted by\r\n // descending usage so the most common keys lead.\r\n const facetKeyEntries = useMemo(() => {\r\n const counts = new Map<string, number>();\r\n for (const r of source) {\r\n const rule = ruleOf(r);\r\n if (!rule) continue;\r\n for (const c of rule.all ?? []) {\r\n counts.set(c.facetKey, (counts.get(c.facetKey) ?? 0) + 1);\r\n }\r\n }\r\n return Array.from(counts.entries()).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));\r\n }, [source]);\r\n\r\n const maxClauses = useMemo(() => {\r\n let max = 0;\r\n for (const r of source) {\r\n const rule = ruleOf(r);\r\n if (!rule) continue;\r\n max = Math.max(max, rule.all?.length ?? 0);\r\n }\r\n return max;\r\n }, [source]);\r\n\r\n // Hide the whole bar if there's nothing to filter on.\r\n if (facetKeyEntries.length === 0 && maxClauses < 2) return null;\r\n\r\n const toggleKey = (key: string) => {\r\n const has = value.facetKeys.includes(key);\r\n const next = has\r\n ? value.facetKeys.filter((k) => k !== key)\r\n : [...value.facetKeys, key];\r\n onChange({ ...value, facetKeys: next });\r\n };\r\n\r\n const setMin = (n: number | null) => onChange({ ...value, minClauses: n });\r\n\r\n const hasAny = value.facetKeys.length > 0 || value.minClauses != null;\r\n\r\n return (\r\n <div className=\"ra-rule-filters\">\r\n <div className=\"ra-rule-filters-row\" role=\"group\" aria-label=\"Filter rules by facet\">\r\n {facetKeyEntries.map(([key, count]) => {\r\n const active = value.facetKeys.includes(key);\r\n return (\r\n <button\r\n key={key}\r\n type=\"button\"\r\n onClick={() => toggleKey(key)}\r\n className=\"ra-rule-filter-chip\"\r\n data-active={active ? 'true' : 'false'}\r\n aria-pressed={active}\r\n title={`Show rules using ${key}`}\r\n >\r\n <span className=\"ra-rule-filter-chip-label\">{key}</span>\r\n <span className=\"ra-rule-filter-chip-count\">{count}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n {maxClauses >= 2 && (\r\n <div className=\"ra-rule-filters-row\" role=\"group\" aria-label=\"Filter by clause count\">\r\n {COMPLEXITY_THRESHOLDS.filter((n) => maxClauses >= n).map((n) => {\r\n const active = value.minClauses === n;\r\n return (\r\n <button\r\n key={n}\r\n type=\"button\"\r\n onClick={() => setMin(active ? null : n)}\r\n className=\"ra-rule-filter-chip\"\r\n data-tone=\"complexity\"\r\n data-active={active ? 'true' : 'false'}\r\n aria-pressed={active}\r\n title={`Only rules with ≥ ${n} facets`}\r\n >\r\n ≥ {n} facets\r\n </button>\r\n );\r\n })}\r\n </div>\r\n )}\r\n {hasAny && (\r\n <button\r\n type=\"button\"\r\n onClick={() => onChange(EMPTY_RULE_FILTERS)}\r\n className=\"ra-rule-filter-clear\"\r\n aria-label=\"Clear rule filters\"\r\n >\r\n Clear filters\r\n </button>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/** Apply RuleFilters to a list of rule-bearing record summaries. */\r\nexport function applyRuleFilters(items: RecordSummary[], filters: RuleFilters): RecordSummary[] {\r\n if (filters.facetKeys.length === 0 && filters.minClauses == null) return items;\r\n return items.filter((r) => {\r\n const rule = ruleOf(r);\r\n if (!rule) return false;\r\n if (filters.minClauses != null && (rule.all?.length ?? 0) < filters.minClauses) return false;\r\n if (filters.facetKeys.length > 0) {\r\n const keys = new Set((rule.all ?? []).map((c) => c.facetKey));\r\n // Match if the rule uses ANY of the selected keys (OR semantics).\r\n if (!filters.facetKeys.some((k) => keys.has(k))) return false;\r\n }\r\n return true;\r\n });\r\n}\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 { List, 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 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 '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, ItemView } from '../types';\r\n\r\nconst KEY_PREFIX = 'smartlinks-ui:records-admin:presentation';\r\nconst ITEM_VIEW_KEY_PREFIX = 'smartlinks-ui:records-admin:item-view';\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}\r\n\r\n/**\r\n * Twin of `usePresentationPref` for the right-pane item view (collection\r\n * cardinality only). Stored under a distinct key so toggling the rail\r\n * presentation never clobbers the table/cards/gallery preference.\r\n */\r\nexport function useItemViewPref(args: {\r\n appId: string;\r\n recordType?: string;\r\n options: ItemView[];\r\n defaultValue: ItemView;\r\n}): [ItemView, (next: ItemView) => void] {\r\n const { appId, recordType, options, defaultValue } = args;\r\n const key = `${ITEM_VIEW_KEY_PREFIX}:${appId}:${recordType ?? '_default'}`;\r\n\r\n const initial = (): ItemView => {\r\n const stored = safeRead(key) as ItemView | 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<ItemView>(initial);\r\n\r\n useEffect(() => {\r\n if (!options.includes(value)) setValue(options[0]);\r\n }, [options, value]);\r\n\r\n const set = useCallback((next: ItemView) => {\r\n setValue(next);\r\n safeWrite(key, next);\r\n }, [key]);\r\n\r\n return [value, set];\r\n}","// =============================================================================\r\n// useCollectionItems — list every item-cardinality record under a given scope.\r\n//\r\n// Powers the right-pane multi-item view (collection mode). Items are records\r\n// whose `ref` ends with `.../item:{itemId}` — they belong to the surrounding\r\n// scope but are individually addressable.\r\n//\r\n// Backed by `SL.app.records.list` with a `refPrefix` so we only round-trip\r\n// the slice we need. The hook keeps the result shape aligned with\r\n// `RecordSummary` so it slots straight into the existing list/table renderers.\r\n// =============================================================================\r\nimport { useMemo, useCallback } from 'react';\r\nimport { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';\r\nimport type { ParsedRef, RecordSummary } from '../types';\r\nimport { listRecords, type RecordsCtx } from '../data/records';\r\nimport type { AppRecord } from '../data/sdkTypes';\r\nimport { parseRef, splitItemRef } from '../data/refs';\r\n\r\nexport interface UseCollectionItemsArgs {\r\n ctx: RecordsCtx;\r\n /**\r\n * Scope the items live under. Items at the collection root pass an empty\r\n * `scope.raw` (the hook then uses `refPrefix: 'item:'`). Pass `null` to\r\n * keep the query disabled.\r\n */\r\n scope: ParsedRef | null;\r\n /** Per-page size requested from the SDK (default 100). */\r\n pageSize?: number;\r\n /**\r\n * Optional projector that derives the row label / subtitle / thumbnail\r\n * from a record's `data`. Falls back to the itemId.\r\n */\r\n toSummary?: (rec: AppRecord, base: RecordSummary) => RecordSummary;\r\n /** When false, the query is paused (used while the host is still booting). */\r\n enabled?: boolean;\r\n}\r\n\r\nconst QK_BASE = ['records-admin', 'collection-items'] as const;\r\n\r\nconst defaultToSummary = (rec: AppRecord, base: RecordSummary): RecordSummary => {\r\n const data = rec.data as Record<string, unknown> | null | undefined;\r\n if (!data) return base;\r\n // Try a few common label-shaped keys without forcing a schema on hosts.\r\n const label =\r\n (data.title as string | undefined) ??\r\n (data.name as string | undefined) ??\r\n (data.label as string | undefined) ??\r\n (data.question as string | undefined) ??\r\n base.label;\r\n const subtitle =\r\n (data.subtitle as string | undefined) ??\r\n (data.summary as string | undefined) ??\r\n (data.description as string | undefined) ??\r\n base.subtitle;\r\n const thumbnail =\r\n (data.thumbnail as string | undefined) ??\r\n (data.image as string | undefined) ??\r\n (data.cover as string | undefined) ??\r\n base.thumbnail;\r\n return { ...base, label, subtitle, thumbnail };\r\n};\r\n\r\n/**\r\n * The shell's `useRecordList` filters by *scope kind*, which doesn't\r\n * differentiate items from singletons. This hook intentionally bypasses\r\n * that filter and asks for refs under a precise prefix.\r\n */\r\nexport function useCollectionItems<T = unknown>(args: UseCollectionItemsArgs) {\r\n const {\r\n ctx, scope, pageSize = 100, toSummary = defaultToSummary, enabled = true,\r\n } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const scopeRef = scope?.raw ?? '';\r\n // `item:` is the prefix at the collection root; everywhere else it's\r\n // `{scopeRef}/item:`. Either way the SDK matches refs starting with this.\r\n const refPrefix = scopeRef ? `${scopeRef}/item:` : 'item:';\r\n\r\n const queryKey = useMemo(\r\n () => [...QK_BASE, ctx.collectionId, ctx.appId, ctx.recordType, scopeRef],\r\n [ctx.collectionId, ctx.appId, ctx.recordType, scopeRef],\r\n );\r\n\r\n const query = useInfiniteQuery({\r\n queryKey,\r\n enabled: enabled && !!scope,\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, {\r\n limit: pageSize,\r\n offset,\r\n refPrefix,\r\n });\r\n return { data, total, hasMore, nextOffset: offset + data.length };\r\n },\r\n getNextPageParam: (last) => (last.hasMore ? last.nextOffset : undefined),\r\n staleTime: 15_000,\r\n });\r\n\r\n const items: RecordSummary<T>[] = useMemo(() => {\r\n const all = query.data?.pages.flatMap((p) => p.data) ?? [];\r\n return all\r\n .map((rec): RecordSummary<T> | null => {\r\n const ref = rec.ref ?? '';\r\n const parsed = parseRef(ref);\r\n const { itemId } = splitItemRef(ref);\r\n // Defensive — `refPrefix` should already exclude non-item refs, but\r\n // a server quirk shouldn't be allowed to crash the table.\r\n if (!itemId) return null;\r\n const base: RecordSummary<T> = {\r\n id: rec.id,\r\n ref,\r\n scope: parsed,\r\n data: (rec.data ?? null) as T | null,\r\n status: rec.data ? 'configured' : 'empty',\r\n label: itemId,\r\n updatedAt: rec.updatedAt,\r\n itemId,\r\n };\r\n return toSummary(rec, base as RecordSummary) as RecordSummary<T>;\r\n })\r\n .filter((x): x is RecordSummary<T> => x !== null);\r\n }, [query.data, toSummary]);\r\n\r\n const refetch = useCallback(() => {\r\n queryClient.invalidateQueries({ queryKey });\r\n }, [queryClient, queryKey]);\r\n\r\n return {\r\n items,\r\n total: query.data?.pages[query.data.pages.length - 1]?.total ?? items.length,\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// Default DeepLinkAdapter — `window.location` + `window.history`.\r\n//\r\n// Handles both regular search-string routing (`/admin?item=x`) and hash\r\n// routing (`/#/admin?item=x`) by reading whichever side carries the query\r\n// and writing back to the same one. Hosts that own routing (React Router,\r\n// SmartLinks `persistentQueryParams`, etc.) should plug in their own\r\n// adapter instead.\r\n// =============================================================================\r\nimport type {\r\n DeepLinkAdapter, DeepLinkState, ResolvedDeepLinkParamNames,\r\n} from '../types/deepLink';\r\n\r\n/** Find the query string the host is using, if any. */\r\nconst findQueryHost = (loc: Location): 'search' | 'hash' => {\r\n // Search wins when both are present — that's the conventional setup.\r\n if (loc.search && loc.search.length > 1) return 'search';\r\n if (loc.hash && loc.hash.includes('?')) return 'hash';\r\n return 'search';\r\n};\r\n\r\nconst getQueryString = (loc: Location): string => {\r\n const host = findQueryHost(loc);\r\n if (host === 'search') return loc.search.startsWith('?') ? loc.search.slice(1) : loc.search;\r\n const idx = loc.hash.indexOf('?');\r\n return idx >= 0 ? loc.hash.slice(idx + 1) : '';\r\n};\r\n\r\nconst buildUrl = (loc: Location, nextQuery: string): string => {\r\n const host = findQueryHost(loc);\r\n const qs = nextQuery ? `?${nextQuery}` : '';\r\n if (host === 'search') {\r\n return `${loc.pathname}${qs}${loc.hash}`;\r\n }\r\n // Hash routing — reconstruct hash with new query while preserving the\r\n // hash path (everything before `?`).\r\n const hashPath = loc.hash.includes('?')\r\n ? loc.hash.slice(0, loc.hash.indexOf('?'))\r\n : loc.hash;\r\n return `${loc.pathname}${loc.search}${hashPath}${qs}`;\r\n};\r\n\r\nexport const createDefaultDeepLinkAdapter = (\r\n paramNames: ResolvedDeepLinkParamNames,\r\n): DeepLinkAdapter => ({\r\n read(): DeepLinkState {\r\n if (typeof window === 'undefined') return {};\r\n const params = new URLSearchParams(getQueryString(window.location));\r\n return {\r\n item: params.get(paramNames.item),\r\n scope: params.get(paramNames.scope),\r\n view: params.get(paramNames.view),\r\n };\r\n },\r\n\r\n write(partial, mode) {\r\n if (typeof window === 'undefined') return;\r\n const params = new URLSearchParams(getQueryString(window.location));\r\n const apply = (key: string, value: string | null | undefined) => {\r\n if (value == null || value === '') params.delete(key);\r\n else params.set(key, value);\r\n };\r\n if ('item' in partial) apply(paramNames.item, partial.item);\r\n if ('scope' in partial) apply(paramNames.scope, partial.scope);\r\n if ('view' in partial) apply(paramNames.view, partial.view);\r\n\r\n const nextUrl = buildUrl(window.location, params.toString());\r\n if (mode === 'push') window.history.pushState({}, '', nextUrl);\r\n else window.history.replaceState({}, '', nextUrl);\r\n },\r\n\r\n subscribe(listener) {\r\n if (typeof window === 'undefined') return () => {};\r\n // `popstate` covers back/forward. `hashchange` covers hash-routed hosts.\r\n window.addEventListener('popstate', listener);\r\n window.addEventListener('hashchange', listener);\r\n return () => {\r\n window.removeEventListener('popstate', listener);\r\n window.removeEventListener('hashchange', listener);\r\n };\r\n },\r\n});","// =============================================================================\r\n// useDeepLinkState — bridge between the shell's runtime state and a URL\r\n// adapter. Returns:\r\n//\r\n// - `urlState` — last-read snapshot from the adapter (refreshed on\r\n// subscribe events).\r\n// - `emit` — write helper. Auto-classifies into push/replace based on\r\n// the configured history mode; callers can override.\r\n//\r\n// Intentionally framework-agnostic — no React Router, no platform SDK.\r\n// Hosts plug their own routing in via `DeepLinkAdapter`.\r\n// =============================================================================\r\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\r\nimport type {\r\n DeepLinkAdapter, DeepLinkOptions, DeepLinkState, DeepLinkHistoryMode,\r\n ResolvedDeepLinkParamNames,\r\n} from '../types/deepLink';\r\nimport { DEFAULT_DEEP_LINK_PARAM_NAMES } from '../types/deepLink';\r\nimport { createDefaultDeepLinkAdapter } from '../data/deepLinkAdapter';\r\n\r\n/**\r\n * Which logical changes are \"meaningful navigation\" (push) vs \"cosmetic /\r\n * incremental\" (replace) under `'smart'` history mode. The shell tags each\r\n * emit with one of these.\r\n */\r\nexport type DeepLinkChangeKind =\r\n | 'item.open' // user opened a different item (push)\r\n | 'item.close' // user backed out to the list (push)\r\n | 'item.step' // prev/next sibling navigation (replace)\r\n | 'scope' // scope tab / facet / product change (push)\r\n | 'view'; // table/cards/gallery toggle (replace)\r\n\r\nconst SMART_PUSH: DeepLinkChangeKind[] = ['item.open', 'item.close', 'scope'];\r\n\r\nconst classify = (\r\n mode: DeepLinkHistoryMode,\r\n kind: DeepLinkChangeKind,\r\n): 'push' | 'replace' => {\r\n if (mode === 'push') return 'push';\r\n if (mode === 'replace') return 'replace';\r\n return SMART_PUSH.includes(kind) ? 'push' : 'replace';\r\n};\r\n\r\nexport interface UseDeepLinkStateResult {\r\n /** Latest snapshot read from the adapter. */\r\n urlState: DeepLinkState;\r\n /**\r\n * Push a partial update through the adapter. `kind` informs the\r\n * push-vs-replace decision under `'smart'` mode.\r\n */\r\n emit: (partial: DeepLinkState, kind: DeepLinkChangeKind) => void;\r\n /** Resolved param names for callers that need them. */\r\n paramNames: ResolvedDeepLinkParamNames;\r\n /** True when deep linking is active (host opted in + we have an adapter). */\r\n enabled: boolean;\r\n}\r\n\r\nexport function useDeepLinkState(\r\n options: DeepLinkOptions | undefined,\r\n): UseDeepLinkStateResult {\r\n const enabled = !!options?.enabled;\r\n const history = options?.history ?? 'smart';\r\n\r\n const paramNames: ResolvedDeepLinkParamNames = useMemo(() => ({\r\n ...DEFAULT_DEEP_LINK_PARAM_NAMES,\r\n ...(options?.paramNames ?? {}),\r\n }), [options?.paramNames]);\r\n\r\n // Default adapter is created lazily and once — host-supplied adapters win\r\n // when present and re-created if the host swaps them.\r\n const defaultAdapterRef = useRef<DeepLinkAdapter | null>(null);\r\n const adapter: DeepLinkAdapter | null = useMemo(() => {\r\n if (!enabled) return null;\r\n if (options?.adapter) return options.adapter;\r\n if (!defaultAdapterRef.current) {\r\n defaultAdapterRef.current = createDefaultDeepLinkAdapter(paramNames);\r\n }\r\n return defaultAdapterRef.current;\r\n }, [enabled, options?.adapter, paramNames]);\r\n\r\n const [urlState, setUrlState] = useState<DeepLinkState>(() =>\r\n adapter ? adapter.read() : {},\r\n );\r\n\r\n // Re-read on external changes (back/forward, host-driven nav).\r\n useEffect(() => {\r\n if (!adapter) return;\r\n setUrlState(adapter.read());\r\n return adapter.subscribe(() => setUrlState(adapter.read()));\r\n }, [adapter]);\r\n\r\n const emit = useCallback((partial: DeepLinkState, kind: DeepLinkChangeKind) => {\r\n if (!adapter) return;\r\n const mode = classify(history, kind);\r\n adapter.write(partial, mode);\r\n // Optimistically refresh — most adapters won't fire a synchronous\r\n // subscribe event for self-initiated writes.\r\n setUrlState((prev) => ({ ...prev, ...partial }));\r\n }, [adapter, history]);\r\n\r\n return { urlState, emit, paramNames, enabled };\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// StatusDot — legacy tiny dot. Kept for back-compat with custom row renderers\r\n// that still target it by class. New default rows use `<StatusIcon>` instead.\r\n// =============================================================================\r\nimport 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// 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, type ComponentType } 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 * Optional icon override for the resting state. Defaults to Lucide\r\n * `Trash2`. The confirm-state icon stays `Trash2` so the destructive\r\n * intent reads consistently regardless of the host's branding.\r\n */\r\n icon?: ComponentType<{ className?: string }>;\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 icon,\r\n}: DeleteButtonProps) => {\r\n const Icon = icon ?? Trash2;\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 <Icon className=\"w-3.5 h-3.5\" />\r\n {label}\r\n </button>\r\n );\r\n};","import type { ReactNode } from 'react';\r\nimport { Copy, ClipboardPaste } from 'lucide-react';\r\nimport type { EditorContext, RecordsAdminI18n } from '../types';\r\nimport type { RecordsAdminActionIcon, RecordsAdminActionKey } from '../types/shell';\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 /**\r\n * Optional Targeting section rendered above `children`. The shell mounts\r\n * this for rule-targeted records (`scope.kind === 'rule'`) so admins can\r\n * author the facet rule alongside the record's data. Plain record types\r\n * leave it `undefined` and nothing renders.\r\n */\r\n targeting?: 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 * Clipboard footer actions. The shell wires these when `enableClipboard`\r\n * is on. Copy is always offered when there's an editing scope; Paste is\r\n * disabled when the clipboard is empty or the cross-scope rules deny it.\r\n */\r\n clipboard?: {\r\n onCopy: () => void;\r\n onPaste: () => void;\r\n canCopy: boolean;\r\n canPaste: boolean;\r\n pasteSourceLabel?: string;\r\n pasteWillReplace?: boolean;\r\n };\r\n /** Host-provided labels for save / discard / delete (resting state only). */\r\n actionLabels?: Partial<Record<RecordsAdminActionKey, string>>;\r\n /** Host-provided icons rendered before save / discard / delete labels. */\r\n actionIcons?: Partial<Record<RecordsAdminActionKey, RecordsAdminActionIcon>>;\r\n}\r\n\r\nexport function RecordEditor<T>({\r\n ctx, i18n, children, preview, targeting, bulkActions, footerExtra, onBeforeDelete,\r\n headerLabel, headerSubtitle, headerMeta, clipboard, actionLabels, actionIcons,\r\n}: Props<T>) {\r\n const saveLabel = actionLabels?.save ?? i18n.save;\r\n const discardLabel = actionLabels?.discard ?? i18n.discard;\r\n const deleteLabel = actionLabels?.delete ?? i18n.delete;\r\n const SaveIcon = actionIcons?.save;\r\n const DiscardIcon = actionIcons?.discard;\r\n const DeleteIcon = actionIcons?.delete;\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 {targeting}\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))] inline-flex items-center gap-1.5\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n {DiscardIcon && <DiscardIcon className=\"h-4 w-4\" />}\r\n {discardLabel}\r\n </button>\r\n {ctx.canRemove && (\r\n <DeleteButton\r\n onConfirm={() => ctx.remove()}\r\n onBeforeDelete={onBeforeDelete}\r\n label={deleteLabel}\r\n confirmLabel={i18n.confirmDelete}\r\n icon={DeleteIcon}\r\n />\r\n )}\r\n {clipboard && (\r\n <>\r\n <button\r\n type=\"button\"\r\n onClick={clipboard.onCopy}\r\n disabled={!clipboard.canCopy || !!ctx.isSaving}\r\n title={i18n.copy}\r\n aria-label={i18n.copy}\r\n className=\"text-xs px-2.5 py-1.5 rounded-md border transition-opacity disabled:opacity-40 hover:bg-[hsl(var(--ra-muted))] inline-flex items-center gap-1.5\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n <Copy className=\"w-3 h-3\" />\r\n {i18n.copy}\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={clipboard.onPaste}\r\n disabled={!clipboard.canPaste || !!ctx.isSaving}\r\n title={\r\n !clipboard.canPaste\r\n ? i18n.clipboardEmpty\r\n : clipboard.pasteSourceLabel\r\n ? i18n.pasteFrom.replace('{name}', clipboard.pasteSourceLabel)\r\n : i18n.paste\r\n }\r\n aria-label={i18n.paste}\r\n className=\"text-xs px-2.5 py-1.5 rounded-md border transition-opacity disabled:opacity-40 hover:bg-[hsl(var(--ra-muted))] inline-flex items-center gap-1.5\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', color: 'hsl(var(--ra-text))' }}\r\n >\r\n <ClipboardPaste className=\"w-3 h-3\" />\r\n {clipboard.pasteWillReplace ? i18n.pasteReplace : i18n.paste}\r\n </button>\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 || ctx.canSave === false}\r\n title={ctx.canSave === false ? ctx.cannotSaveReason : undefined}\r\n className=\"text-xs px-3 py-1.5 rounded-md font-medium transition-opacity disabled:opacity-40 inline-flex items-center gap-1.5\"\r\n style={{ background: 'hsl(var(--ra-accent))', color: 'hsl(var(--ra-surface))' }}\r\n >\r\n {SaveIcon && !ctx.isSaving && <SaveIcon className=\"h-4 w-4\" />}\r\n {ctx.isSaving ? (i18n.saving ?? 'Saving…') : saveLabel}\r\n </button>\r\n </footer>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// RecordTargeting — collapsible Targeting section for rule-targeted records.\r\n//\r\n// Renders a compact \"Targets: …\" summary chip with an Edit button. Clicking\r\n// expands the full `FacetRuleEditor`. For freshly-minted rules (no clauses\r\n// yet) the panel auto-opens so the first authoring step is to define the\r\n// rule. Once at least one clause exists the panel collapses on next mount,\r\n// keeping the record-data fields at the top of the scroll where admins\r\n// expect them.\r\n//\r\n// Wired by `RecordsAdminShell` and passed into `RecordEditor` via the\r\n// `targeting` slot. Hosts that want a custom targeting UI can ignore this\r\n// and inject their own ReactNode.\r\n//\r\n// The component is pure presentation around `useRulePreview` + the editor\r\n// context's `facetRule` / `onFacetRuleChange`. All persistence flows through\r\n// the shared `useRecordEditor.save()` path.\r\n// =============================================================================\r\nimport { useEffect, useMemo, useState } from 'react';\r\nimport { ChevronDown, ChevronRight, Settings2, Target, AlertCircle } from 'lucide-react';\r\nimport type { EditorContext, SmartLinksSDK } from '../types';\r\nimport type { FacetRuleClause } from '../data/sdkTypes';\r\nimport { FacetRuleEditor } from '../../FacetRuleEditor/FacetRuleEditor';\r\nimport { useFacets } from '../../ConditionsEditor/useFacets';\r\nimport { useRulePreview } from '../hooks/useRulePreview';\r\n\r\nexport interface RecordTargetingProps<T> {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n ctx: EditorContext<T>;\r\n}\r\n\r\n/** Build the short \"facet: a, b · facet2: c\" summary used in the collapsed header. */\r\nfunction summariseRule(\r\n clauses: FacetRuleClause[],\r\n facets: ReturnType<typeof useFacets>,\r\n): { text: string; clauseCount: number; valueCount: number } {\r\n let valueCount = 0;\r\n const parts = clauses.map((c) => {\r\n const facet = facets.find((f) => f.key === c.facetKey);\r\n const facetName = facet?.name ?? c.facetKey;\r\n const values = c.anyOf.map((v) => facet?.values.find((x) => x.key === v)?.name ?? v);\r\n valueCount += values.length;\r\n if (values.length === 0) return `${facetName}: (none)`;\r\n if (values.length <= 3) return `${facetName}: ${values.join(', ')}`;\r\n return `${facetName}: ${values.slice(0, 2).join(', ')} +${values.length - 2}`;\r\n });\r\n return { text: parts.join(' · '), clauseCount: clauses.length, valueCount };\r\n}\r\n\r\nexport function RecordTargeting<T>({ SL, collectionId, appId, ctx }: RecordTargetingProps<T>) {\r\n const facets = useFacets(collectionId, undefined);\r\n const preview = useRulePreview({ SL, collectionId, appId, rule: ctx.facetRule ?? null });\r\n\r\n const clauses = ctx.facetRule?.all ?? [];\r\n const hasAnyClause = clauses.length > 0;\r\n const isInvalid = ctx.canSave === false; // rule-scope-only flag from useRecordEditor\r\n\r\n // Auto-open when the rule is empty (new rule, first authoring step) OR\r\n // when any clause is missing values (admin needs to fix it before save).\r\n // Once a valid rule exists we default collapsed.\r\n const shouldAutoOpen = !hasAnyClause || isInvalid;\r\n const [open, setOpen] = useState(shouldAutoOpen);\r\n\r\n // If validity changes (e.g. user emptied a clause from inside the editor)\r\n // force the panel open so the issue is visible.\r\n useEffect(() => {\r\n if (shouldAutoOpen) setOpen(true);\r\n }, [shouldAutoOpen]);\r\n\r\n const summary = useMemo(() => summariseRule(clauses, facets), [clauses, facets]);\r\n\r\n if (!ctx.onFacetRuleChange) return null;\r\n\r\n const headerTone = isInvalid\r\n ? { color: 'hsl(var(--ra-danger, 0 70% 45%))' }\r\n : { color: 'hsl(var(--ra-muted-text))' };\r\n\r\n return (\r\n <div\r\n className=\"mb-4 rounded-lg border\"\r\n style={{\r\n borderColor: isInvalid\r\n ? 'hsl(var(--ra-danger, 0 70% 45%) / 0.5)'\r\n : 'hsl(var(--ra-border))',\r\n background: 'hsl(var(--ra-muted) / 0.3)',\r\n }}\r\n >\r\n {/* Collapsed / expanded header row */}\r\n <button\r\n type=\"button\"\r\n onClick={() => setOpen((o) => !o)}\r\n className=\"w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-[hsl(var(--ra-muted)/0.5)] rounded-lg transition-colors\"\r\n aria-expanded={open}\r\n >\r\n {open ? (\r\n <ChevronDown className=\"w-3.5 h-3.5 shrink-0\" style={headerTone} />\r\n ) : (\r\n <ChevronRight className=\"w-3.5 h-3.5 shrink-0\" style={headerTone} />\r\n )}\r\n <Target className=\"w-3.5 h-3.5 shrink-0\" style={headerTone} />\r\n <span\r\n className=\"text-[11px] font-medium uppercase tracking-wide shrink-0\"\r\n style={headerTone}\r\n >\r\n Targets\r\n </span>\r\n <span\r\n className=\"text-xs truncate flex-1 min-w-0\"\r\n style={{ color: 'hsl(var(--ra-text))' }}\r\n title={summary.text || undefined}\r\n >\r\n {hasAnyClause\r\n ? (summary.text || `${summary.clauseCount} facet${summary.clauseCount === 1 ? '' : 's'}`)\r\n : <span style={{ color: 'hsl(var(--ra-muted-text))', fontStyle: 'italic' }}>No rule yet — pick a facet to begin</span>}\r\n </span>\r\n {isInvalid && hasAnyClause && (\r\n <span\r\n className=\"inline-flex items-center gap-1 text-[10px] uppercase tracking-wide shrink-0\"\r\n style={{ color: 'hsl(var(--ra-danger, 0 70% 45%))' }}\r\n >\r\n <AlertCircle className=\"w-3 h-3\" />\r\n Incomplete\r\n </span>\r\n )}\r\n {!open && hasAnyClause && !isInvalid && preview.totalMatches != null && (\r\n <span\r\n className=\"text-[10px] uppercase tracking-wide shrink-0 px-1.5 py-0.5 rounded-full\"\r\n style={{\r\n color: 'hsl(var(--ra-muted-text))',\r\n background: 'hsl(var(--ra-muted) / 0.6)',\r\n }}\r\n >\r\n {preview.totalMatches} match{preview.totalMatches === 1 ? '' : 'es'}\r\n </span>\r\n )}\r\n <Settings2 className=\"w-3.5 h-3.5 shrink-0\" style={headerTone} />\r\n </button>\r\n\r\n {open && (\r\n <div\r\n className=\"px-3 pb-3 pt-1 border-t\"\r\n style={{ borderColor: 'hsl(var(--ra-border) / 0.6)' }}\r\n >\r\n <FacetRuleEditor\r\n value={ctx.facetRule ?? null}\r\n onChange={ctx.onFacetRuleChange}\r\n collectionId={collectionId}\r\n preview={preview}\r\n description=\"Pick one or more facets. The record applies to every product whose facets match.\"\r\n />\r\n </div>\r\n )}\r\n </div>\r\n );\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 * When true, the drill-down tab strip is hidden even when only the\r\n * `product` tab would render (i.e. no variants / batches). The editor\r\n * header below already names the record so the single-tab strip is\r\n * redundant. The strip still appears whenever variants or batches are\r\n * available — at that point it's a real navigational choice.\r\n */\r\n hideSingleTab?: boolean;\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, hideSingleTab,\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 const showTabStrip = tabs.length > 1 || !hideSingleTab;\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 — hidden when only `product` is available\r\n and the host opts into `hideSingleTab`. */}\r\n {showTabStrip && (\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\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// ItemViewSwitcher — three-way segmented control for the right-pane item view.\r\n// Mirrors `PresentationSwitcher` but for `ItemView` (table / cards / gallery).\r\n// Hidden when fewer than two options are offered.\r\n// =============================================================================\r\nimport { Table as TableIcon, LayoutGrid, Image as ImageIcon } from 'lucide-react';\r\nimport type { ItemView, RecordsAdminI18n } from '../types';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nconst ICONS: Record<ItemView, typeof TableIcon> = {\r\n table: TableIcon,\r\n cards: LayoutGrid,\r\n gallery: ImageIcon,\r\n};\r\n\r\ninterface Props {\r\n options: ItemView[];\r\n value: ItemView;\r\n onChange: (next: ItemView) => void;\r\n i18n: Pick<RecordsAdminI18n, 'itemViewTable' | 'itemViewCards' | 'itemViewGallery'>;\r\n}\r\n\r\nconst labelFor = (v: ItemView, i18n: Props['i18n']): string => {\r\n if (v === 'table') return i18n.itemViewTable;\r\n if (v === 'cards') return i18n.itemViewCards;\r\n return i18n.itemViewGallery;\r\n};\r\n\r\nexport const ItemViewSwitcher = ({ options, value, onChange, i18n }: Props) => {\r\n if (options.length < 2) return null;\r\n return (\r\n <div role=\"tablist\" className=\"ra-tabs\" aria-label=\"Item view\" style={{ padding: '0.15rem' }}>\r\n {options.map((opt) => {\r\n const Icon = ICONS[opt];\r\n const active = value === opt;\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 onClick={() => onChange(opt)}\r\n className=\"ra-tab\"\r\n title={labelFor(opt, i18n)}\r\n style={{ padding: '0.3rem 0.55rem' }}\r\n >\r\n <Icon className={cn('ra-tab-icon w-3.5 h-3.5')} />\r\n <span className=\"sr-only\">{labelFor(opt, i18n)}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// DefaultItemTable — built-in `table` view for the right-pane item list.\r\n//\r\n// Renders the host's `itemColumns` when supplied; falls back to a single\r\n// label / updated / actions column so collection-mode apps that don't pass\r\n// columns still get a usable list.\r\n// =============================================================================\r\nimport type { ItemColumn, RecordSummary, RecordsAdminI18n } from '../types';\r\nimport { Pencil, Trash2 } from 'lucide-react';\r\n\r\ninterface Props<T> {\r\n items: RecordSummary<T>[];\r\n columns?: ItemColumn<T>[];\r\n selectedId?: string;\r\n onOpen: (itemId: string) => void;\r\n onDelete: (itemId: string) => void;\r\n i18n: Pick<RecordsAdminI18n,\r\n | 'itemColumnLabel' | 'itemColumnUpdated' | 'itemActions' | 'delete'\r\n >;\r\n}\r\n\r\nconst formatDate = (iso?: string): string => {\r\n if (!iso) return '—';\r\n try {\r\n const d = new Date(iso);\r\n return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\r\n } catch { return iso; }\r\n};\r\n\r\nexport function DefaultItemTable<T>({\r\n items, columns, selectedId, onOpen, onDelete, i18n,\r\n}: Props<T>) {\r\n const cols = columns ?? [];\r\n const useFallback = cols.length === 0;\r\n\r\n return (\r\n <div className=\"ra-item-table-wrap\">\r\n <table className=\"ra-item-table\">\r\n <thead>\r\n <tr>\r\n {useFallback ? (\r\n <>\r\n <th>{i18n.itemColumnLabel}</th>\r\n <th style={{ width: '12rem' }}>{i18n.itemColumnUpdated}</th>\r\n </>\r\n ) : cols.map((c) => (\r\n <th key={c.key} style={{ width: c.width, textAlign: c.align ?? 'left' }}>\r\n {c.header}\r\n </th>\r\n ))}\r\n <th\r\n style={{ width: '6.5rem', textAlign: 'right' }}\r\n aria-label={i18n.itemActions}\r\n />\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {items.map((item) => {\r\n const id = item.itemId ?? '';\r\n const isSelected = !!selectedId && selectedId === id;\r\n return (\r\n <tr\r\n key={item.ref}\r\n data-selected={isSelected}\r\n onClick={() => onOpen(id)}\r\n className=\"ra-item-row\"\r\n >\r\n {useFallback ? (\r\n <>\r\n <td>\r\n <div className=\"ra-item-row-title\">{item.label}</div>\r\n {item.subtitle && (\r\n <div className=\"ra-item-row-sub\">{item.subtitle}</div>\r\n )}\r\n </td>\r\n <td className=\"ra-item-row-meta\">{formatDate(item.updatedAt)}</td>\r\n </>\r\n ) : cols.map((c) => (\r\n <td key={c.key} style={{ textAlign: c.align ?? 'left' }}>\r\n {c.render(item)}\r\n </td>\r\n ))}\r\n <td className=\"ra-item-row-actions\">\r\n <button\r\n type=\"button\"\r\n className=\"ra-row-action\"\r\n onClick={(e) => { e.stopPropagation(); onOpen(id); }}\r\n aria-label=\"Edit\"\r\n >\r\n <Pencil className=\"w-3.5 h-3.5\" />\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-row-action\"\r\n data-tone=\"danger\"\r\n onClick={(e) => { e.stopPropagation(); onDelete(id); }}\r\n aria-label={i18n.delete}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n </button>\r\n </td>\r\n </tr>\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// DefaultItemCards — built-in `cards` and `gallery` views for the right pane.\r\n//\r\n// Same component, two density modes:\r\n// - `cards` → square-ish tiles, label + subtitle.\r\n// - `gallery` → 16:9 thumbnails, more breathing room.\r\n// =============================================================================\r\nimport type { ReactNode } from 'react';\r\nimport type {\r\n ItemSlotContext, RecordSummary, ItemViewContext, RecordsAdminI18n,\r\n} from '../types';\r\nimport { Trash2 } from 'lucide-react';\r\n\r\ninterface Props<T> {\r\n items: RecordSummary<T>[];\r\n variant: 'cards' | 'gallery';\r\n selectedId?: string;\r\n ctx: ItemViewContext;\r\n renderCard?: (record: RecordSummary<T>, slotCtx: ItemSlotContext) => ReactNode;\r\n i18n: Pick<RecordsAdminI18n, 'delete'>;\r\n}\r\n\r\nconst initials = (label: string): string =>\r\n label\r\n .split(/\\s+/)\r\n .slice(0, 2)\r\n .map((s) => s[0]?.toUpperCase() ?? '')\r\n .join('') || '?';\r\n\r\nexport function DefaultItemCards<T>({\r\n items, variant, selectedId, ctx, renderCard, i18n,\r\n}: Props<T>) {\r\n const isGallery = variant === 'gallery';\r\n return (\r\n <div className={isGallery ? 'ra-item-gallery' : 'ra-item-cards'}>\r\n {items.map((item) => {\r\n const id = item.itemId ?? '';\r\n const slotCtx: ItemSlotContext = {\r\n ...ctx,\r\n selected: selectedId === id,\r\n };\r\n if (renderCard) {\r\n return (\r\n <div\r\n key={item.ref}\r\n onClick={() => ctx.onOpen(id)}\r\n className=\"ra-item-card-wrap\"\r\n data-selected={slotCtx.selected}\r\n >\r\n {renderCard(item, slotCtx)}\r\n </div>\r\n );\r\n }\r\n return (\r\n <button\r\n key={item.ref}\r\n type=\"button\"\r\n onClick={() => ctx.onOpen(id)}\r\n className={`ra-item-card ${isGallery ? 'ra-item-card--gallery' : ''}`}\r\n data-selected={slotCtx.selected}\r\n >\r\n <div className={`ra-item-card-thumb ${isGallery ? 'ra-item-card-thumb--gallery' : ''}`}>\r\n {item.thumbnail\r\n ? <img src={item.thumbnail} alt=\"\" loading=\"lazy\" />\r\n : <span className=\"ra-item-card-initials\">{initials(item.label)}</span>}\r\n </div>\r\n <div className=\"ra-item-card-body\">\r\n <div className=\"ra-item-card-title\">{item.label}</div>\r\n {item.subtitle && (\r\n <div className=\"ra-item-card-sub\">{item.subtitle}</div>\r\n )}\r\n </div>\r\n <button\r\n type=\"button\"\r\n className=\"ra-row-action ra-item-card-delete\"\r\n data-tone=\"danger\"\r\n onClick={(e) => { e.stopPropagation(); ctx.onDelete(id); }}\r\n aria-label={i18n.delete}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n </button>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// ItemListView — right-pane multi-item view shown when a collection-cardinality\r\n// scope is selected and no item is open.\r\n//\r\n// Honours, in order:\r\n// 1. `renderItemList` — full host override.\r\n// 2. `renderItemCard` — host card renderer for cards/gallery views.\r\n// 3. `itemColumns` — declarative columns for the table view.\r\n// 4. Built-in defaults — table with label + updated.\r\n//\r\n// Also owns the toolbar: title, item count, \"+ New {noun}\", and the\r\n// table/cards/gallery switcher when more than one view is offered.\r\n// =============================================================================\r\nimport type { ReactNode } from 'react';\r\nimport { Plus } from 'lucide-react';\r\nimport type {\r\n ItemColumn, ItemSlotContext, ItemView, ItemViewContext,\r\n RecordSummary, RecordsAdminI18n,\r\n} from '../types';\r\nimport { ItemViewSwitcher } from './ItemViewSwitcher';\r\nimport { DefaultItemTable } from './DefaultItemTable';\r\nimport { DefaultItemCards } from './DefaultItemCards';\r\nimport { EmptyState, LoadingState, ErrorState } from '../browser/EmptyStates';\r\nimport { Plus as PlusIcon } from 'lucide-react';\r\n\r\ninterface Props<T> {\r\n items: RecordSummary<T>[];\r\n isLoading: boolean;\r\n error: Error | null;\r\n ctx: ItemViewContext;\r\n itemNoun: string;\r\n\r\n // View configuration\r\n view: ItemView;\r\n views: ItemView[];\r\n onViewChange: (view: ItemView) => void;\r\n\r\n // Optional host overrides\r\n renderItemList?: (items: RecordSummary<T>[], ctx: ItemViewContext) => ReactNode;\r\n renderItemCard?: (record: RecordSummary<T>, ctx: ItemSlotContext) => ReactNode;\r\n renderItemEmpty?: (ctx: ItemViewContext) => ReactNode;\r\n itemColumns?: ItemColumn<T>[];\r\n\r\n i18n: RecordsAdminI18n;\r\n}\r\n\r\nexport function ItemListView<T>({\r\n items, isLoading, error, ctx, itemNoun,\r\n view, views, onViewChange,\r\n renderItemList, renderItemCard, renderItemEmpty, itemColumns,\r\n i18n,\r\n}: Props<T>) {\r\n const newLabel = i18n.newItem.includes('{noun}')\r\n ? i18n.newItem.replace('{noun}', itemNoun)\r\n : i18n.newItem;\r\n\r\n const toolbar = (\r\n <div className=\"ra-item-toolbar\">\r\n <div className=\"ra-item-toolbar-title\">\r\n <h2 className=\"ra-display\" style={{ fontSize: '0.95rem', margin: 0 }}>\r\n {i18n.itemListTitle}\r\n </h2>\r\n <span className=\"ra-item-toolbar-count\">{items.length}</span>\r\n </div>\r\n <div className=\"ra-item-toolbar-actions\">\r\n {/* View switcher only renders when host opts into 2+ views */}\r\n {!renderItemList && (\r\n <ItemViewSwitcher\r\n options={views}\r\n value={view}\r\n onChange={onViewChange}\r\n i18n={i18n}\r\n />\r\n )}\r\n <button\r\n type=\"button\"\r\n onClick={ctx.onCreate}\r\n className=\"ra-btn\"\r\n data-variant=\"primary\"\r\n >\r\n <Plus className=\"w-3.5 h-3.5\" />\r\n {newLabel}\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n\r\n let body: ReactNode;\r\n if (isLoading) {\r\n body = <LoadingState />;\r\n } else if (error) {\r\n body = <ErrorState error={error} />;\r\n } else if (items.length === 0) {\r\n body = renderItemEmpty\r\n ? renderItemEmpty(ctx)\r\n : (\r\n <EmptyState\r\n title={i18n.noItemsTitle}\r\n body={i18n.noItemsBody}\r\n action={(\r\n <button\r\n type=\"button\"\r\n onClick={ctx.onCreate}\r\n className=\"ra-btn\"\r\n data-variant=\"primary\"\r\n >\r\n <PlusIcon className=\"w-3.5 h-3.5\" />\r\n {newLabel}\r\n </button>\r\n )}\r\n />\r\n );\r\n } else if (renderItemList) {\r\n body = renderItemList(items, ctx);\r\n } else if (view === 'table') {\r\n body = (\r\n <DefaultItemTable\r\n items={items}\r\n columns={itemColumns}\r\n selectedId={ctx.selectedId}\r\n onOpen={ctx.onOpen}\r\n onDelete={ctx.onDelete}\r\n i18n={i18n}\r\n />\r\n );\r\n } else {\r\n body = (\r\n <DefaultItemCards\r\n items={items}\r\n variant={view}\r\n selectedId={ctx.selectedId}\r\n ctx={ctx}\r\n renderCard={renderItemCard}\r\n i18n={i18n}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"ra-item-list\">\r\n {toolbar}\r\n <div className=\"ra-item-list-body\">{body}</div>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// EditorItemNav — small chrome rendered above the editor when an item is open\r\n// in collection mode. Provides Back-to-list + previous/next arrows. The shell\r\n// passes pre-computed flags so this component is purely presentational.\r\n// =============================================================================\r\nimport { ChevronLeft, ChevronRight, ArrowLeft } from 'lucide-react';\r\nimport type { RecordsAdminI18n } from '../types';\r\n\r\ninterface Props {\r\n /** Friendly name of the item being edited (mostly for screen readers). */\r\n label?: string;\r\n /** 1-based position within the current sibling list. */\r\n position?: number;\r\n total?: number;\r\n onBack: () => void;\r\n onPrev?: () => void;\r\n onNext?: () => void;\r\n canPrev: boolean;\r\n canNext: boolean;\r\n i18n: Pick<RecordsAdminI18n, 'backToList' | 'prevItem' | 'nextItem'>;\r\n}\r\n\r\nexport const EditorItemNav = ({\r\n label, position, total, onBack, onPrev, onNext, canPrev, canNext, i18n,\r\n}: Props) => (\r\n <div className=\"ra-item-nav\">\r\n <button\r\n type=\"button\"\r\n onClick={onBack}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n >\r\n <ArrowLeft className=\"w-3.5 h-3.5\" />\r\n {i18n.backToList}\r\n </button>\r\n {typeof position === 'number' && typeof total === 'number' && total > 0 && (\r\n <span className=\"ra-item-nav-position\" aria-label={label}>\r\n {position} / {total}\r\n </span>\r\n )}\r\n <div className=\"ra-item-nav-arrows\">\r\n <button\r\n type=\"button\"\r\n onClick={onPrev}\r\n disabled={!canPrev}\r\n className=\"ra-row-action\"\r\n aria-label={i18n.prevItem}\r\n title={i18n.prevItem}\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </button>\r\n <button\r\n type=\"button\"\r\n onClick={onNext}\r\n disabled={!canNext}\r\n className=\"ra-row-action\"\r\n aria-label={i18n.nextItem}\r\n title={i18n.nextItem}\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n);","// =============================================================================\r\n// SiblingRail — replaces the scope rail when an item is open in collection\r\n// mode (and `collectionRailMode === 'siblings'`).\r\n//\r\n// Top: pinned `← All scopes` link to return the rail to scope navigation.\r\n// Body: dense rows of every item in the current scope. Click a row to switch\r\n// the editor to that item without leaving the page.\r\n// =============================================================================\r\nimport { ArrowLeft } from 'lucide-react';\r\nimport type { RecordSummary, RecordsAdminI18n } from '../types';\r\nimport { LoadingState, ErrorState, EmptyState } from '../browser/EmptyStates';\r\n\r\ninterface Props<T> {\r\n items: RecordSummary<T>[];\r\n selectedItemId?: string;\r\n isLoading: boolean;\r\n error: Error | null;\r\n onBack: () => void;\r\n onSelect: (itemId: string) => void;\r\n i18n: Pick<RecordsAdminI18n,\r\n | 'backToScopes' | 'siblingsHeading' | 'noItemsTitle' | 'noItemsBody'\r\n >;\r\n}\r\n\r\nexport function SiblingRail<T>({\r\n items, selectedItemId, isLoading, error, onBack, onSelect, i18n,\r\n}: Props<T>) {\r\n return (\r\n <div className=\"ra-sibling-rail\">\r\n <button\r\n type=\"button\"\r\n onClick={onBack}\r\n className=\"ra-sibling-back\"\r\n >\r\n <ArrowLeft className=\"w-3.5 h-3.5\" />\r\n {i18n.backToScopes}\r\n </button>\r\n <div className=\"ra-sibling-heading\">{i18n.siblingsHeading}</div>\r\n <div className=\"ra-sibling-body\">\r\n {isLoading && <LoadingState />}\r\n {!isLoading && error && <ErrorState error={error} />}\r\n {!isLoading && !error && items.length === 0 && (\r\n <EmptyState title={i18n.noItemsTitle} body={i18n.noItemsBody} />\r\n )}\r\n {!isLoading && !error && items.length > 0 && (\r\n <ul className=\"ra-sibling-list\">\r\n {items.map((item) => {\r\n const id = item.itemId ?? '';\r\n const selected = selectedItemId === id;\r\n return (\r\n <li key={item.ref}>\r\n <button\r\n type=\"button\"\r\n onClick={() => onSelect(id)}\r\n className=\"ra-row\"\r\n data-selected={selected}\r\n >\r\n <div className=\"ra-row-body\">\r\n <div className=\"ra-row-title\">{item.label}</div>\r\n {item.subtitle && (\r\n <div className=\"ra-row-sub\">{item.subtitle}</div>\r\n )}\r\n </div>\r\n </button>\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n )}\r\n </div>\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 /** Optional override for the button label. When set, takes precedence over `label`. */\r\n customLabel?: string;\r\n introHidden: boolean;\r\n onShowIntro?: () => void;\r\n}\r\n\r\nexport const UtilityRow = ({ label, customLabel, introHidden, onShowIntro }: Props) => {\r\n if (!introHidden || !onShowIntro) return null;\r\n const text = customLabel ?? `How ${label.toLowerCase()} works`;\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 {text}\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 * Optional trailing slot rendered AFTER `headerActions`. Reserved for the\r\n * shell-managed intro reopen (`?`) button so it sits flush with the host's\r\n * own header actions without polluting the public `headerActions` slot.\r\n */\r\n trailingSlot?: 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 trailingSlot,\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 || trailingSlot ? (\r\n <div className=\"ra-header-actions\">\r\n {headerActions}\r\n {trailingSlot}\r\n </div>\r\n ) : 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\nimport type { ComponentType } from 'react';\r\n\r\ntype IconCmp = ComponentType<{ className?: string }>;\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 /** Optional icon override for the inline Save button (defaults to Lucide `Save`). */\r\n SaveIcon?: IconCmp;\r\n /** Optional icon override for the inline Discard button (defaults to Lucide `Undo2`). */\r\n DiscardIcon?: IconCmp;\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 SaveIcon, DiscardIcon,\r\n}: UnsavedBannerProps) => {\r\n const SI: IconCmp = SaveIcon ?? Save;\r\n const DI: IconCmp = DiscardIcon ?? Undo2;\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 <DI 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 <SI 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// ClipboardToast — lightweight transient toast used by the shell for Copy /\r\n// Paste feedback. Avoids pulling `sonner` into the library bundle while\r\n// keeping the affordance discoverable. Auto-dismisses after 2.5s.\r\n// =============================================================================\r\nimport { useEffect } from 'react';\r\nimport { Copy as CopyIcon, ClipboardPaste } from 'lucide-react';\r\n\r\nexport interface ClipboardToastProps {\r\n message: string;\r\n variant?: 'copy' | 'paste';\r\n onDismiss: () => void;\r\n}\r\n\r\nexport const ClipboardToast = ({ message, variant = 'copy', onDismiss }: ClipboardToastProps) => {\r\n useEffect(() => {\r\n const t = window.setTimeout(onDismiss, 2500);\r\n return () => window.clearTimeout(t);\r\n }, [message, onDismiss]);\r\n\r\n const Icon = variant === 'paste' ? ClipboardPaste : CopyIcon;\r\n\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n className=\"ra-clipboard-toast\"\r\n >\r\n <Icon className=\"w-3.5 h-3.5 shrink-0\" aria-hidden=\"true\" />\r\n <span className=\"truncate\">{message}</span>\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.55rem;\\n width: 100%;\\n text-align: left;\\n padding: 0.45rem 0.75rem;\\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-compact {\\n padding-block: 0.3rem;\\n}\\n.ra-shell .ra-row-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.5rem;\\n height: 1.5rem;\\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.8125rem;\\n line-height: 1.2;\\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.6875rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.05rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-row-rule-chips {\\n display: flex;\\n flex-wrap: wrap;\\n gap: 0.2rem;\\n margin-top: 0.2rem;\\n}\\n.ra-shell .ra-rule-chip {\\n display: inline-flex;\\n align-items: center;\\n max-width: 100%;\\n padding: 0.05rem 0.4rem;\\n border-radius: 999px;\\n font-size: 0.625rem;\\n font-weight: 500;\\n line-height: 1.4;\\n background: hsl(var(--ra-accent) / 0.10);\\n color: hsl(var(--ra-accent));\\n border: 1px solid hsl(var(--ra-accent) / 0.20);\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-rule-chip-more {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-muted-text));\\n border-color: hsl(var(--ra-border));\\n}\\n.ra-shell[data-density=compact] .ra-row-rule-chips {\\n margin-top: 0.15rem;\\n gap: 0.15rem;\\n}\\n.ra-shell[data-density=compact] .ra-rule-chip {\\n font-size: 0.6rem;\\n padding: 0.02rem 0.35rem;\\n}\\n.ra-shell .ra-rule-filters {\\n display: flex;\\n flex-direction: column;\\n gap: 0.3rem;\\n}\\n.ra-shell .ra-rule-filters-row {\\n display: flex;\\n flex-wrap: wrap;\\n gap: 0.25rem;\\n}\\n.ra-shell .ra-rule-filter-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.65rem;\\n font-weight: 500;\\n line-height: 1.4;\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-muted-text));\\n border: 1px solid hsl(var(--ra-border));\\n cursor: pointer;\\n transition:\\n background .12s ease,\\n color .12s ease,\\n border-color .12s ease;\\n max-width: 100%;\\n}\\n.ra-shell .ra-rule-filter-chip:hover {\\n background: hsl(var(--ra-accent) / 0.10);\\n color: hsl(var(--ra-text));\\n border-color: hsl(var(--ra-accent) / 0.25);\\n}\\n.ra-shell .ra-rule-filter-chip[data-active=true] {\\n background: hsl(var(--ra-accent) / 0.15);\\n color: hsl(var(--ra-accent));\\n border-color: hsl(var(--ra-accent) / 0.40);\\n}\\n.ra-shell .ra-rule-filter-chip[data-tone=complexity][data-active=true] {\\n background: hsl(var(--ra-info) / 0.15);\\n color: hsl(var(--ra-info));\\n border-color: hsl(var(--ra-info) / 0.40);\\n}\\n.ra-shell .ra-rule-filter-chip-label {\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n max-width: 9rem;\\n}\\n.ra-shell .ra-rule-filter-chip-count {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n min-width: 1.1rem;\\n height: 1rem;\\n padding: 0 0.3rem;\\n border-radius: 999px;\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-muted-text));\\n font-size: 0.6rem;\\n font-weight: 600;\\n}\\n.ra-shell .ra-rule-filter-chip[data-active=true] .ra-rule-filter-chip-count {\\n background: hsl(var(--ra-accent) / 0.18);\\n color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-rule-filter-clear {\\n align-self: flex-start;\\n background: transparent;\\n border: 0;\\n padding: 0;\\n color: hsl(var(--ra-muted-text));\\n font-size: 0.65rem;\\n cursor: pointer;\\n text-decoration: underline;\\n text-decoration-style: dotted;\\n}\\n.ra-shell .ra-rule-filter-clear:hover {\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell[data-density=compact] .ra-row {\\n padding-block: 0.3rem;\\n gap: 0.45rem;\\n}\\n.ra-shell[data-density=compact] .ra-row-title {\\n font-size: 0.78125rem;\\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.ra-shell .ra-clipboard-toast {\\n position: fixed;\\n bottom: 1.25rem;\\n left: 50%;\\n transform: translateX(-50%);\\n z-index: 90;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.5rem;\\n max-width: min(28rem, calc(100vw - 2rem));\\n padding: 0.55rem 0.85rem;\\n border-radius: 999px;\\n background: hsl(var(--ra-text));\\n color: hsl(var(--ra-surface));\\n font-size: 0.75rem;\\n line-height: 1;\\n box-shadow: 0 8px 24px -10px hsl(0 0% 0% / 0.45);\\n animation: ra-clipboard-pop 0.18s ease-out both;\\n pointer-events: none;\\n}\\n@keyframes ra-clipboard-pop {\\n from {\\n opacity: 0;\\n transform: translate(-50%, 6px);\\n }\\n to {\\n opacity: 1;\\n transform: translate(-50%, 0);\\n }\\n}\\n.ra-shell .ra-row-menu-wrap {\\n display: inline-flex;\\n align-items: center;\\n margin-left: 0.25rem;\\n}\\n.ra-shell .ra-row-menu-trigger {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.5rem;\\n height: 1.5rem;\\n border-radius: 0.35rem;\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n opacity: 0;\\n transition:\\n opacity .15s ease,\\n background .15s ease,\\n color .15s ease;\\n border: 1px solid transparent;\\n}\\n.ra-shell .ra-row:hover .ra-row-menu-trigger,\\n.ra-shell .ra-card-hover:hover .ra-row-menu-trigger,\\n.ra-shell .ra-row-menu-trigger:focus-visible,\\n.ra-shell .ra-row-menu-trigger[aria-expanded=true] {\\n opacity: 1;\\n}\\n.ra-shell .ra-row-menu-trigger:hover {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-row-menu {\\n position: absolute;\\n right: 0;\\n top: calc(100% + 4px);\\n z-index: 50;\\n min-width: 11rem;\\n padding: 0.25rem;\\n border-radius: 0.5rem;\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n box-shadow: 0 12px 28px -10px hsl(0 0% 0% / 0.25);\\n display: flex;\\n flex-direction: column;\\n gap: 0.125rem;\\n}\\n.ra-shell .ra-row-menu-item {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.5rem;\\n padding: 0.4rem 0.55rem;\\n border-radius: 0.35rem;\\n font-size: 0.75rem;\\n color: hsl(var(--ra-text));\\n background: transparent;\\n border: 0;\\n text-align: left;\\n width: 100%;\\n cursor: pointer;\\n}\\n.ra-shell .ra-row-menu-item:hover:not(:disabled) {\\n background: hsl(var(--ra-muted));\\n}\\n.ra-shell .ra-row-menu-item:disabled {\\n opacity: 0.45;\\n cursor: not-allowed;\\n}\\n.ra-shell .ra-item-list {\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n min-height: 0;\\n}\\n.ra-shell .ra-item-list-body {\\n flex: 1;\\n min-height: 0;\\n overflow: auto;\\n padding: 1rem 1.25rem 1.5rem;\\n}\\n.ra-shell .ra-item-toolbar {\\n display: flex;\\n align-items: center;\\n justify-content: space-between;\\n gap: 0.75rem;\\n padding: 0.75rem 1.25rem;\\n border-bottom: 1px solid hsl(var(--ra-border));\\n background: hsl(var(--ra-surface));\\n}\\n.ra-shell .ra-item-toolbar-title {\\n display: flex;\\n align-items: baseline;\\n gap: 0.5rem;\\n min-width: 0;\\n}\\n.ra-shell .ra-item-toolbar-count {\\n font-size: 0.7rem;\\n font-weight: 600;\\n color: hsl(var(--ra-muted-text));\\n background: hsl(var(--ra-muted));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: 999px;\\n padding: 0.05rem 0.45rem;\\n}\\n.ra-shell .ra-item-toolbar-actions {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-item-table-wrap {\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: var(--ra-radius);\\n background: hsl(var(--ra-surface));\\n overflow: hidden;\\n box-shadow: var(--ra-card-shadow);\\n}\\n.ra-shell .ra-item-table {\\n width: 100%;\\n border-collapse: collapse;\\n font-size: 0.85rem;\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-item-table thead th {\\n text-align: left;\\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 padding: 0.65rem 0.85rem;\\n background: hsl(var(--ra-muted) / 0.55);\\n border-bottom: 1px solid hsl(var(--ra-border));\\n}\\n.ra-shell .ra-item-table tbody td {\\n padding: 0.65rem 0.85rem;\\n border-bottom: 1px solid hsl(var(--ra-border) / 0.7);\\n vertical-align: middle;\\n}\\n.ra-shell .ra-item-table tbody tr:last-child td {\\n border-bottom: 0;\\n}\\n.ra-shell .ra-item-row {\\n cursor: pointer;\\n transition: background .12s ease;\\n}\\n.ra-shell .ra-item-row:hover {\\n background: var(--ra-row-hover);\\n}\\n.ra-shell .ra-item-row[data-selected=true] {\\n background: var(--ra-row-active-bg);\\n}\\n.ra-shell .ra-item-row-title {\\n font-weight: var(--ra-title-weight);\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-item-row-sub {\\n font-size: 0.75rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.15rem;\\n}\\n.ra-shell .ra-item-row-meta {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-shell .ra-item-row-actions {\\n text-align: right;\\n white-space: nowrap;\\n}\\n.ra-shell .ra-item-row-actions .ra-row-action + .ra-row-action {\\n margin-left: 0.15rem;\\n}\\n.ra-shell .ra-item-cards {\\n display: grid;\\n grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));\\n gap: 0.85rem;\\n}\\n.ra-shell .ra-item-gallery {\\n display: grid;\\n grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));\\n gap: 1rem;\\n}\\n.ra-shell .ra-item-card {\\n position: relative;\\n display: flex;\\n flex-direction: column;\\n align-items: stretch;\\n text-align: left;\\n padding: 0;\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: var(--ra-radius);\\n overflow: hidden;\\n cursor: pointer;\\n transition:\\n box-shadow .18s ease,\\n transform .12s ease,\\n border-color .15s ease;\\n box-shadow: var(--ra-card-shadow);\\n font-family: inherit;\\n color: inherit;\\n}\\n.ra-shell .ra-item-card:hover {\\n box-shadow: var(--ra-card-shadow-hover);\\n border-color: hsl(var(--ra-accent) / 0.30);\\n}\\n.ra-shell .ra-item-card[data-selected=true] {\\n border-color: hsl(var(--ra-accent) / 0.55);\\n box-shadow: var(--ra-card-shadow-hover);\\n}\\n.ra-shell .ra-item-card-thumb {\\n width: 100%;\\n aspect-ratio: 1 / 1;\\n background:\\n linear-gradient(\\n 135deg,\\n hsl(var(--ra-accent) / 0.12),\\n hsl(var(--ra-accent) / 0.04));\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n color: hsl(var(--ra-accent));\\n overflow: hidden;\\n}\\n.ra-shell .ra-item-card-thumb--gallery {\\n aspect-ratio: 16 / 9;\\n}\\n.ra-shell .ra-item-card-thumb img {\\n width: 100%;\\n height: 100%;\\n -o-object-fit: cover;\\n object-fit: cover;\\n}\\n.ra-shell .ra-item-card-initials {\\n font-family: var(--ra-font-display);\\n font-weight: var(--ra-display-weight);\\n font-size: 1.5rem;\\n letter-spacing: 0.02em;\\n}\\n.ra-shell .ra-item-card-body {\\n padding: 0.65rem 0.8rem 0.85rem;\\n min-width: 0;\\n}\\n.ra-shell .ra-item-card-title {\\n font-weight: var(--ra-title-weight);\\n font-size: 0.85rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-shell .ra-item-card-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-item-card-delete {\\n position: absolute;\\n top: 0.4rem;\\n right: 0.4rem;\\n background: hsl(var(--ra-surface) / 0.85);\\n backdrop-filter: blur(4px);\\n opacity: 0;\\n transition: opacity .15s ease;\\n}\\n.ra-shell .ra-item-card:hover .ra-item-card-delete,\\n.ra-shell .ra-item-card:focus-within .ra-item-card-delete {\\n opacity: 1;\\n}\\n.ra-shell .ra-item-nav {\\n display: flex;\\n align-items: center;\\n gap: 0.6rem;\\n padding: 0.5rem 1.25rem;\\n border-bottom: 1px solid hsl(var(--ra-border));\\n background: hsl(var(--ra-surface));\\n}\\n.ra-shell .ra-item-nav-position {\\n font-size: 0.72rem;\\n color: hsl(var(--ra-muted-text));\\n font-variant-numeric: tabular-nums;\\n}\\n.ra-shell .ra-item-nav-arrows {\\n margin-left: auto;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.15rem;\\n}\\n.ra-shell .ra-item-nav-arrows .ra-row-action[disabled] {\\n opacity: 0.35;\\n cursor: not-allowed;\\n}\\n.ra-shell .ra-sibling-rail {\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n min-height: 0;\\n}\\n.ra-shell .ra-sibling-back {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n padding: 0.6rem 0.85rem;\\n font-size: 0.75rem;\\n font-weight: 500;\\n color: hsl(var(--ra-muted-text));\\n background: hsl(var(--ra-muted) / 0.5);\\n border: 0;\\n border-bottom: 1px solid hsl(var(--ra-border));\\n cursor: pointer;\\n text-align: left;\\n transition: background .12s ease, color .12s ease;\\n}\\n.ra-shell .ra-sibling-back:hover {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-sibling-heading {\\n padding: 0.6rem 0.85rem 0.4rem;\\n font-size: 0.65rem;\\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-sibling-body {\\n flex: 1;\\n min-height: 0;\\n overflow-y: auto;\\n}\\n.ra-shell .ra-sibling-list {\\n list-style: none;\\n margin: 0;\\n padding: 0;\\n}\\n.ra-shell .ra-status-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n border-radius: 9999px;\\n}\\n.ra-shell .ra-status-icon > svg {\\n width: 100%;\\n height: 100%;\\n display: block;\\n}\\n.ra-shell .ra-status-icon--own {\\n color: hsl(var(--ra-status-own));\\n}\\n.ra-shell .ra-status-icon--shared {\\n color: hsl(var(--ra-status-shared));\\n}\\n.ra-shell .ra-status-icon--missing {\\n color: hsl(var(--ra-status-missing) / 0.7);\\n}\\n.ra-shell .ra-row-status {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.5rem;\\n height: 1.5rem;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-row-scope {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 1.25rem;\\n height: 1.25rem;\\n border-radius: calc(var(--ra-radius) * 0.5);\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-muted-text));\\n flex-shrink: 0;\\n margin-left: auto;\\n opacity: 0.55;\\n transition:\\n opacity .12s ease,\\n color .12s ease,\\n background .12s ease;\\n}\\n.ra-shell .ra-row:hover .ra-row-scope {\\n opacity: 0.85;\\n}\\n.ra-shell .ra-row[data-selected=true] .ra-row-scope {\\n opacity: 1;\\n background: hsl(var(--ra-accent) / 0.12);\\n color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-row[data-tone=own] .ra-row-sub {\\n color: hsl(var(--ra-status-own));\\n}\\n.ra-shell .ra-row[data-tone=shared] .ra-row-sub {\\n color: hsl(var(--ra-status-shared));\\n}\\n.ra-shell .ra-row[data-selected=true] {\\n background:\\n linear-gradient(\\n 90deg,\\n hsl(var(--ra-accent) / 0.10) 0%,\\n hsl(var(--ra-accent) / 0.04) 100%);\\n border-left-width: 3px;\\n border-left-color: hsl(var(--ra-accent));\\n}\\n.ra-shell .ra-dirty-pip {\\n display: inline-block;\\n width: 0.45rem;\\n height: 0.45rem;\\n border-radius: 9999px;\\n background: hsl(var(--ra-warning));\\n box-shadow: 0 0 0 2px hsl(var(--ra-warning) / 0.18);\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-group-summary {\\n background: transparent;\\n}\\n.ra-shell {\\n position: relative;\\n}\\n.ra-shell .ra-help-float {\\n position: absolute;\\n top: 0.65rem;\\n right: 0.85rem;\\n z-index: 5;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.35rem;\\n padding: 0.3rem 0.6rem;\\n font-size: 0.7rem;\\n font-weight: 500;\\n color: hsl(var(--ra-muted-text));\\n background: hsl(var(--ra-surface) / 0.85);\\n backdrop-filter: blur(6px);\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: 999px;\\n cursor: pointer;\\n transition:\\n color .12s ease,\\n background .12s ease,\\n border-color .12s ease;\\n}\\n.ra-shell .ra-help-float:hover {\\n color: hsl(var(--ra-accent));\\n border-color: hsl(var(--ra-accent) / 0.4);\\n background: hsl(var(--ra-surface));\\n}\\n.ra-shell .ra-help-float svg {\\n width: 0.85rem;\\n height: 0.85rem;\\n}\\n.ra-shell .ra-preview-reopen {\\n position: absolute;\\n top: 50%;\\n right: 0;\\n transform: translateY(-50%);\\n z-index: 4;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n gap: 0.4rem;\\n padding: 0.65rem 0.45rem;\\n background: hsl(var(--ra-surface));\\n color: hsl(var(--ra-muted-text));\\n border: 1px solid hsl(var(--ra-border));\\n border-right: 0;\\n border-radius: calc(var(--ra-radius) * 0.85) 0 0 calc(var(--ra-radius) * 0.85);\\n box-shadow: var(--ra-card-shadow);\\n cursor: pointer;\\n transition:\\n color .12s ease,\\n background .12s ease,\\n padding-right .15s ease;\\n writing-mode: vertical-rl;\\n font-size: 0.7rem;\\n font-weight: 600;\\n letter-spacing: 0.06em;\\n text-transform: uppercase;\\n}\\n.ra-shell .ra-preview-reopen:hover {\\n color: hsl(var(--ra-accent));\\n background: hsl(var(--ra-accent) / 0.04);\\n padding-right: 0.6rem;\\n}\\n.ra-shell .ra-preview-reopen svg {\\n width: 0.85rem;\\n height: 0.85rem;\\n writing-mode: horizontal-tb;\\n}\\n\")","import { useEffect, useMemo, useRef, useState, useCallback, isValidElement, createElement, type ReactNode } from 'react';\r\nimport { Plus, Search, HelpCircle, Eye } from 'lucide-react';\r\nimport { mergeIcons, pickHeaderIcon } from './icons';\r\nimport type {\r\n RecordsAdminShellProps, RecordStatus, RecordSummary,\r\n ScopeKind, RecordsAdminI18n, ParsedRef, RecordPresentation, ItemView,\r\n} from '../types';\r\nimport { DEFAULT_I18N } from '../types';\r\nimport { parseRef, buildRef, splitItemRef, buildItemRef } 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 { usePasteConfirm } from '../hooks/usePasteConfirm';\r\nimport {\r\n useRecordClipboard, checkPasteCompatibility, cloneValue,\r\n} from '../hooks/useRecordClipboard';\r\nimport { ScopeTabs } from '../browser/ScopeTabs';\r\nimport { StatusFilterPills } from '../browser/StatusFilterPills';\r\nimport { RecordList } from '../browser/RecordList';\r\nimport { RuleFilterChips, applyRuleFilters, EMPTY_RULE_FILTERS, type RuleFilters } from '../browser/RuleFilterChips';\r\nimport { EmptyState, ErrorState, LoadingState } from '../browser/EmptyStates';\r\nimport { PresentationSwitcher } from '../browser/PresentationSwitcher';\r\nimport { usePresentationPref, useItemViewPref } from '../hooks/usePresentationPref';\r\nimport { useCollectionItems } from '../hooks/useCollectionItems';\r\nimport { useDeepLinkState } from '../hooks/useDeepLinkState';\r\nimport { RecordEditor } from '../editor/RecordEditor';\r\nimport { RecordTargeting } from '../editor/RecordTargeting';\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 { ItemListView } from '../items/ItemListView';\r\nimport { EditorItemNav } from '../items/EditorItemNav';\r\nimport { SiblingRail } from '../items/SiblingRail';\r\nimport { IntroCard } from './IntroCard';\r\nimport { UtilityRow } from './UtilityRow';\r\nimport { ShellHeader } from './ShellHeader';\r\nimport { UnsavedBanner } from './UnsavedBanner';\r\nimport { ClipboardToast } from './ClipboardToast';\r\nimport { exportCsv, importCsv, downloadBlob } from '../data/csv';\r\nimport './tokens.css';\r\nimport './shell.css';\r\n\r\n/**\r\n * Top-level scopes the rail can show. Drill-downs (variant / batch) live\r\n * under the selected product (see `ProductDrillDown`).\r\n *\r\n * Order matters: this drives tab order AND the default tab when the host\r\n * doesn't pass `defaultScope`. We lead with `rule` because — for any\r\n * collection with more than a handful of facet values — authors are far\r\n * more likely to target records by criteria (\"apply to all sourdough\r\n * loaves\") than by pinning one record per facet value. `collection`\r\n * (Global) covers the migration case of records that have no targeting\r\n * at all. `facet` (pin one record to one facet value) is now the\r\n * specialist option, last.\r\n */\r\nconst TOP_LEVEL_SCOPES: ScopeKind[] = ['rule', 'collection', '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\n/**\r\n * Generate an opaque rule id for a freshly-created `rule:{id}` ref. Reuses\r\n * the same compact, sortable shape as item ids — no external deps, easy to\r\n * eyeball in URLs while still safe under heavy creation.\r\n */\r\nconst newRuleId = (): string => {\r\n const time = Date.now().toString(36);\r\n const rand = Math.random().toString(36).slice(2, 10);\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 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 enableClipboard = true,\r\n onCopy: onCopyOverride,\r\n onPaste: onPasteOverride,\r\n actionLabels,\r\n actionIcons,\r\n editorTabs = 'off',\r\n // Right-pane item view (collection cardinality)\r\n itemViews = ['table'],\r\n defaultItemView,\r\n itemColumns,\r\n renderItemList,\r\n renderItemCard,\r\n renderItemEmpty,\r\n collectionRailMode = 'siblings',\r\n // Deep linking\r\n deepLink,\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 // Deep linking — set up the URL bridge early so user-action callbacks can\r\n // emit through it. The actual restore + emit wiring happens further down,\r\n // once the rest of the shell state has been declared.\r\n // ---------------------------------------------------------------------------\r\n const deepLinkState = useDeepLinkState(deepLink);\r\n // Track which params we've already applied so back/forward writes don't\r\n // bounce against our own emits.\r\n const lastAppliedDLRef = useRef<string>('');\r\n\r\n // `'multi'` is reserved for the upcoming multi-open editor (pinned tabs +\r\n // Save-all). Until that ships we behave like `'off'` and warn once so\r\n // hosts can adopt the prop early without surprise behaviour changes.\r\n const multiOpenWarnedRef = useRef(false);\r\n if (editorTabs === 'multi' && !multiOpenWarnedRef.current) {\r\n multiOpenWarnedRef.current = true;\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n '[RecordsAdminShell] editorTabs=\"multi\" is reserved for a future ' +\r\n 'release and currently behaves like \"off\". Track in records-admin-shell.md.',\r\n );\r\n }\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 // ---------------------------------------------------------------------------\r\n // Right-pane item view preference (collection cardinality only).\r\n // ---------------------------------------------------------------------------\r\n const [itemView, setItemView] = useItemViewPref({\r\n appId, recordType,\r\n options: itemViews,\r\n defaultValue: defaultItemView ?? itemViews[0] ?? 'table',\r\n });\r\n const onItemViewChange = useCallback((next: ItemView) => {\r\n onTelemetry?.({\r\n type: 'item.view.change',\r\n recordType,\r\n scopeRef: '', // populated below if a scope is active\r\n from: itemView,\r\n to: next,\r\n });\r\n setItemView(next);\r\n deepLinkState.emit({ view: next }, 'view');\r\n }, [onTelemetry, recordType, itemView, setItemView, deepLinkState]);\r\n\r\n // The selected per-item id (collection cardinality). When `null` the right\r\n // pane shows the multi-item list view; when set the editor renders against\r\n // the item ref `{scopeRef}/item:{id}` (or `item:{id}` at collection root).\r\n const [selectedItemId, setSelectedItemId] = useState<string | null>(null);\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 // Rule-tab quick filters (facet-key + complexity). Reset whenever the\r\n // active scope changes (handled in the same effect that resets search).\r\n const [ruleFilters, setRuleFilters] = useState<RuleFilters>(EMPTY_RULE_FILTERS);\r\n\r\n // Selected ref for the FACET tab (records-driven list).\r\n // Also used by the Rule and Global (collection-rung) tabs — they all share\r\n // the records-driven list pattern, so a single \"currently-open record ref\"\r\n // state covers them. The legacy name stays for now to keep the diff small.\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 // Intro reopen affordance — resolve once. Defaults to `'header'`. When the\r\n // header card isn't rendered (host hasn't customised it & didn't opt in),\r\n // silently fall back to `'footer'` so the help button still has a home.\r\n // ---------------------------------------------------------------------------\r\n const headerWillRender = useMemo(() => {\r\n const headerCustomised =\r\n !!title || !!subtitle || !!headerIcon || !!headerActions ||\r\n showStats || !!statsItems || !!statsTitle || !!statsIcon;\r\n return showHeader === true || (showHeader !== false && headerCustomised);\r\n }, [showHeader, title, subtitle, headerIcon, headerActions, showStats, statsItems, statsTitle, statsIcon]);\r\n\r\n const resolvedReopenAffordance: 'header' | 'footer' | 'inline' | 'hidden' = useMemo(() => {\r\n const requested = intro?.reopenAffordance ?? 'header';\r\n if (requested === 'header' && !headerWillRender) return 'footer';\r\n return requested;\r\n }, [intro?.reopenAffordance, headerWillRender]);\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 by the facet tab AND by the new rule / global\r\n // tabs. The hook's `matchesScope` keeps each tab cleanly partitioned (rule\r\n // records never leak into facet, etc.). See `useRecordList` for the rules.\r\n const recordListEnabled =\r\n (activeScope === 'facet' || activeScope === 'rule' || activeScope === 'collection')\r\n && !probe.isLoading;\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: recordListEnabled,\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 // Rule / Global tabs — auto-select the first record so the right pane\r\n // isn't a permanent empty state. New rule creation sets the selection\r\n // explicitly (see `onCreateRule` below) and bypasses this effect.\r\n useEffect(() => {\r\n if (activeScope !== 'rule' && activeScope !== 'collection') return;\r\n if (selectedFacetRef !== undefined) return;\r\n // Collection-cardinality + Global tab: the right pane is the multi-item\r\n // list view, not an editor. Seed the empty ref so `editingScope` resolves\r\n // to the collection root and `ItemListView` mounts immediately. Without\r\n // this the rail would auto-select an item-cardinality record and shove\r\n // the editor into a confusing half-state.\r\n if (activeScope === 'collection' && cardinality === 'collection') {\r\n setSelectedFacetRef('');\r\n return;\r\n }\r\n const first = recordList.items[0];\r\n if (first) setSelectedFacetRef(first.ref);\r\n }, [activeScope, selectedFacetRef, recordList.items, cardinality]);\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 setRuleFilters(EMPTY_RULE_FILTERS);\r\n // The records-driven tabs share `selectedFacetRef` — clearing on tab\r\n // change prevents a Rule selection from being interpreted as a Facet\r\n // selection (or vice versa).\r\n setSelectedFacetRef(undefined);\r\n }, [activeScope]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Build the parsed scope for the user's current browse selection. In\r\n // singleton mode this is also the record being edited. In collection mode\r\n // it's the *folder* that holds items — the actual editing target appends\r\n // an `item:{id}` segment (see `editingRef` below).\r\n // ---------------------------------------------------------------------------\r\n const editingScope: ParsedRef | null = useMemo(() => {\r\n // Records-driven tabs (facet, rule, collection/global) all read off the\r\n // same selected ref. parseRef handles `facet:…`, `rule:…` and the empty\r\n // ref (collection root) uniformly.\r\n if (activeScope === 'facet' || activeScope === 'rule' || activeScope === 'collection') {\r\n if (selectedFacetRef === undefined) return null;\r\n return parseRef(selectedFacetRef);\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 // ---------------------------------------------------------------------------\r\n // Collection-cardinality plumbing. The shell stays in singleton mode unless\r\n // the host opted in (`cardinality === 'collection'`).\r\n //\r\n // - `isCollection` — convenience flag.\r\n // - `editingItemRef` — the full `{scopeRef}/item:{id}` ref when an item\r\n // is open; otherwise null (right pane shows the\r\n // item list view rather than an editor).\r\n // - `editingTargetScope` — what the editor + resolver actually point at.\r\n // In singleton mode this is `editingScope`; in\r\n // collection mode with an item open it's the item\r\n // ref; without an item open it's null (no editor).\r\n // ---------------------------------------------------------------------------\r\n const isCollection = cardinality === 'collection';\r\n\r\n const editingItemRef: string | null = useMemo(() => {\r\n if (!isCollection) return null;\r\n if (!selectedItemId) return null;\r\n // `editingScope` may be null only at the collection root — we still want\r\n // an item ref like `item:{id}` in that case (future-proofing for the\r\n // dedicated `'collection'` scope tab).\r\n const baseRef = editingScope?.raw ?? '';\r\n return buildItemRef(baseRef, selectedItemId);\r\n }, [isCollection, selectedItemId, editingScope]);\r\n\r\n const editingTargetScope: ParsedRef | null = useMemo(() => {\r\n if (!isCollection) return editingScope;\r\n if (!editingItemRef) return null;\r\n return parseRef(editingItemRef);\r\n }, [isCollection, editingScope, editingItemRef]);\r\n\r\n // Reset the selected item whenever the *scope folder* changes — switching\r\n // from one product to another or one facet value to another should drop\r\n // back to the item list, not silently keep an item id from another scope.\r\n // Skipped on the very next render after a deep-link restore, since restore\r\n // intentionally pairs a scope change with an item id.\r\n const skipNextItemResetRef = useRef(false);\r\n useEffect(() => {\r\n if (skipNextItemResetRef.current) {\r\n skipNextItemResetRef.current = false;\r\n return;\r\n }\r\n setSelectedItemId(null);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [editingScope?.raw]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Items inside the current scope (collection cardinality only). Fetched up-\r\n // front because both the right-pane list and the sibling rail need them,\r\n // and the response is a single round-trip with `refPrefix`.\r\n // ---------------------------------------------------------------------------\r\n const collectionItems = useCollectionItems<TData>({\r\n ctx,\r\n scope: isCollection ? editingScope : null,\r\n enabled: isCollection,\r\n });\r\n\r\n // Emit `scope` whenever the rail moves and no item is open. Item moves are\r\n // already covered by the per-handler emits above and carry their own scope\r\n // inside the ref, so we deliberately skip emit here when an item is open.\r\n // Internal-vs-external echo is filtered by `lastAppliedDLRef` in the\r\n // restore effect (which signature-matches on the URL state we just wrote).\r\n useEffect(() => {\r\n if (!deepLinkState.enabled) return;\r\n if (selectedItemId) return; // item handlers own URL writes while open\r\n deepLinkState.emit({ scope: editingScope?.raw ?? null, item: null }, 'scope');\r\n // Mark this round trip as already-applied so the restore effect doesn't\r\n // try to re-process the same values we just wrote.\r\n lastAppliedDLRef.current = `${''}|${editingScope?.raw ?? ''}|${itemView}`;\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [deepLinkState.enabled, editingScope?.raw, selectedItemId, itemView]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Deep-link restore — apply URL state to shell state when the URL changes\r\n // externally (initial mount, back/forward, host-driven nav). We dedupe by\r\n // signature so our own emits don't bounce back through here.\r\n //\r\n // The `item` URL param can be either a bare id (`comp_winter_2026` → item\r\n // at the collection root) or a full item ref (`product:abc/item:foo`).\r\n // Either way the trailing `item:{id}` segment is the actual item id, and\r\n // anything before it tells us which scope to land on.\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (!deepLinkState.enabled) return;\r\n const { item, scope, view } = deepLinkState.urlState;\r\n const sig = `${item ?? ''}|${scope ?? ''}|${view ?? ''}`;\r\n if (sig === lastAppliedDLRef.current) return;\r\n lastAppliedDLRef.current = sig;\r\n\r\n // Apply view first — independent of item/scope and cheapest.\r\n if (view && itemViews.includes(view as ItemView) && view !== itemView) {\r\n setItemView(view as ItemView);\r\n }\r\n\r\n // Decide where the rail should land. Item wins when present (it carries\r\n // its own scope inside the ref). Otherwise honour `scope`.\r\n const railRef: string = item\r\n ? (item.includes('item:') ? item.slice(0, item.lastIndexOf('item:')).replace(/\\/$/, '') : '')\r\n : (scope ?? '');\r\n const itemId: string | null = item\r\n ? (item.includes('item:') ? item.slice(item.lastIndexOf('item:') + 'item:'.length) : item)\r\n : null;\r\n\r\n // Translate the rail ref into the existing scope-state shape.\r\n const parsed = railRef ? parseRef(railRef) : null;\r\n if (parsed?.productId) {\r\n if (activeScope !== 'product') setActiveScope('product');\r\n if (selectedProductId !== parsed.productId) setSelectedProductId(parsed.productId);\r\n const nextDrill: DrillTab = parsed.batchId ? 'batch' : parsed.variantId ? 'variant' : 'product';\r\n if (drillTab !== nextDrill) setDrillTab(nextDrill);\r\n if (parsed.variantId && selectedVariantId !== parsed.variantId) setSelectedVariantId(parsed.variantId);\r\n if (parsed.batchId && selectedBatchId !== parsed.batchId) setSelectedBatchId(parsed.batchId);\r\n } else if (parsed?.facetId) {\r\n if (activeScope !== 'facet') setActiveScope('facet');\r\n if (selectedFacetRef !== railRef) setSelectedFacetRef(railRef);\r\n } else {\r\n // Empty rail ref — collection root. Clear any facet selection so the\r\n // item list view shows the global pool. Active scope stays as-is\r\n // (host's `defaultScope` already picked an appropriate landing).\r\n if (selectedFacetRef) setSelectedFacetRef(undefined);\r\n }\r\n\r\n // Finally: open the item (or close, if URL has none).\r\n if (itemId !== selectedItemId) {\r\n // Pair the scope change with the item set without the reset effect\r\n // wiping the item id back to null on the next render.\r\n if (railRef && railRef !== editingScope?.raw) {\r\n skipNextItemResetRef.current = true;\r\n }\r\n setSelectedItemId(itemId);\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [deepLinkState.enabled, deepLinkState.urlState]);\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: editingTargetScope?.productId,\r\n variantId: editingTargetScope?.variantId,\r\n batchId: editingTargetScope?.batchId,\r\n facetId: editingTargetScope?.facetId,\r\n facetValue: editingTargetScope?.facetValue,\r\n ref: editingTargetScope?.raw,\r\n supportedScopes: supportedForResolution,\r\n enabled: !!editingTargetScope,\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 if (isCollection) collectionItems.refetch();\r\n }, [productBrowse, recordList, facetBrowse, variantChildren, batchChildren, isCollection, collectionItems]);\r\n\r\n const editorCtx = useRecordEditor<TData>({\r\n ctx,\r\n scope: editingTargetScope ?? parseRef(''),\r\n resolved: { data: resolved.data, source: resolved.source, sourceRef: resolved.sourceRef, parentValue: resolved.parentValue, facetRule: resolved.facetRule },\r\n defaultData,\r\n reseed: dirtyStrategy === 'keep' ? 'preserve-dirty' : 'always',\r\n // Seed an empty rule for freshly-minted `rule:{id}` refs so the Targeting\r\n // section can render its empty-state picker. For existing rule records\r\n // pull the saved rule off the resolved record. Pinned scopes get `null`\r\n // and the Targeting section stays hidden.\r\n initialFacetRule: editingTargetScope?.kind === 'rule'\r\n ? (resolved.facetRule ?? { all: [] })\r\n : null,\r\n onSaved: () => {\r\n onTelemetry?.({ type: 'record.save', recordType, ref: editingTargetScope?.raw ?? '', isCreate: resolved.source !== 'self' });\r\n refetchAll();\r\n },\r\n onDeleted: () => {\r\n onTelemetry?.({ type: 'record.delete', recordType, ref: editingTargetScope?.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 (isCollection && selectedItemId) {\r\n // Drop back to the item list view; the scope folder selection stays.\r\n setSelectedItemId(null);\r\n } else 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 const pasteConfirm = usePasteConfirm();\r\n\r\n // ---------------------------------------------------------------------------\r\n // Clipboard — Copy / Paste across scopes for this `recordType`.\r\n // ---------------------------------------------------------------------------\r\n // Clipboard always mounts (cheap), but `enableClipboard` gates whether the\r\n // affordance is actually surfaced in the UI. Scoping per (appId,\r\n // recordType) prevents pasting nutrition values into a warranty editor.\r\n const clipboard = useRecordClipboard<TData>({\r\n appId,\r\n recordType: recordType ?? '__default',\r\n });\r\n const [clipboardNotice, setClipboardNotice] = useState<{\r\n message: string; variant: 'copy' | 'paste';\r\n } | null>(null);\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 // Clipboard wiring — needs `editorHeaderLabel` for friendly toasts and the\r\n // replace-confirm body, hence declared here rather than next to the other\r\n // editor state.\r\n // ---------------------------------------------------------------------------\r\n const copyCurrent = useCallback(() => {\r\n if (!enableClipboard || !editingScope) return;\r\n // Resolved value is what the user sees today (post-inheritance). The host\r\n // can transform via `onCopy` to strip per-scope-only fields.\r\n const sourceValue = onCopyOverride\r\n ? onCopyOverride({ value: editorCtx.value, scope: editingScope })\r\n : cloneValue(editorCtx.value);\r\n clipboard.set({\r\n value: sourceValue,\r\n sourceScope: editingScope.kind,\r\n sourceRef: editingScope.raw,\r\n sourceLabel: editorHeaderLabel,\r\n });\r\n onTelemetry?.({ type: 'clipboard.copy', recordType, sourceRef: editingScope.raw });\r\n setClipboardNotice({\r\n message: i18n.copyToast.replace('{name}', editorHeaderLabel ?? editingScope.raw),\r\n variant: 'copy',\r\n });\r\n }, [\r\n enableClipboard, editingScope, onCopyOverride, editorCtx.value, clipboard,\r\n editorHeaderLabel, onTelemetry, recordType, i18n.copyToast,\r\n ]);\r\n\r\n const pasteCurrent = useCallback(async () => {\r\n if (!enableClipboard || !editingScope || !clipboard.entry) return;\r\n\r\n const compat = checkPasteCompatibility(\r\n { kind: clipboard.entry.sourceScope, raw: clipboard.entry.sourceRef },\r\n editingScope,\r\n );\r\n\r\n if (compat.status === 'denied') {\r\n setClipboardNotice({ message: compat.reason ?? 'Paste not allowed here', variant: 'paste' });\r\n return;\r\n }\r\n\r\n if (compat.status === 'warn') {\r\n const ok = await pasteConfirm.confirm({\r\n title: i18n.pasteWarnTitle,\r\n body: compat.reason ?? '',\r\n confirmLabel: i18n.pasteWarnContinue,\r\n cancelLabel: i18n.pasteConfirmCancel,\r\n });\r\n if (!ok) return;\r\n }\r\n\r\n // Replace-confirm only when the destination already has its own saved value.\r\n const willReplace = resolved.source === 'self';\r\n if (willReplace) {\r\n const ok = await pasteConfirm.confirm({\r\n title: i18n.pasteConfirmTitle,\r\n body: i18n.pasteConfirmBody.replace(\r\n '{destination}', editorHeaderLabel ?? editingScope.raw,\r\n ),\r\n confirmLabel: i18n.pasteConfirmReplace,\r\n cancelLabel: i18n.pasteConfirmCancel,\r\n });\r\n if (!ok) return;\r\n }\r\n\r\n const sourceParsed = { kind: clipboard.entry.sourceScope, raw: clipboard.entry.sourceRef };\r\n const transformed = onPasteOverride\r\n ? onPasteOverride(\r\n { value: clipboard.entry.value as TData, sourceScope: sourceParsed as ParsedRef },\r\n { scope: editingScope, currentValue: editorCtx.value ?? null },\r\n )\r\n : cloneValue(clipboard.entry.value as TData);\r\n\r\n if (transformed === null) return; // host vetoed\r\n\r\n // Populate the editor — does NOT autosave. Existing dirty-guard +\r\n // UnsavedBanner take it from here.\r\n editorCtx.onChange(transformed);\r\n onTelemetry?.({\r\n type: 'clipboard.paste',\r\n recordType,\r\n sourceRef: clipboard.entry.sourceRef,\r\n destinationRef: editingScope.raw,\r\n replaced: willReplace,\r\n });\r\n setClipboardNotice({\r\n message: i18n.pasteToast.replace('{name}', clipboard.entry.sourceLabel ?? clipboard.entry.sourceRef),\r\n variant: 'paste',\r\n });\r\n }, [\r\n enableClipboard, editingScope, clipboard.entry, pasteConfirm, resolved.source,\r\n onPasteOverride, editorCtx, onTelemetry, recordType, editorHeaderLabel,\r\n i18n.pasteWarnTitle, i18n.pasteWarnContinue, i18n.pasteConfirmCancel,\r\n i18n.pasteConfirmTitle, i18n.pasteConfirmBody, i18n.pasteConfirmReplace,\r\n i18n.pasteToast,\r\n ]);\r\n\r\n const editorPasteCompat = useMemo(() => {\r\n if (!enableClipboard || !clipboard.entry || !editingScope) return null;\r\n if (clipboard.entry.sourceRef === editingScope.raw) return { status: 'denied' as const };\r\n return checkPasteCompatibility(\r\n { kind: clipboard.entry.sourceScope, raw: clipboard.entry.sourceRef },\r\n editingScope,\r\n );\r\n }, [enableClipboard, clipboard.entry, editingScope]);\r\n\r\n const editorClipboard = enableClipboard && editingScope ? {\r\n onCopy: copyCurrent,\r\n onPaste: () => { void pasteCurrent(); },\r\n canCopy: true,\r\n canPaste: !!clipboard.entry && (editorPasteCompat?.status !== 'denied'),\r\n pasteSourceLabel: clipboard.entry?.sourceLabel,\r\n pasteWillReplace: resolved.source === 'self' && !!clipboard.entry,\r\n } : undefined;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Row-level paste: queue the paste once the user has selected the target\r\n // record. We can't call `pasteCurrent` synchronously from a row click —\r\n // `editingScope` / `resolved` only update after the selection state change\r\n // ripples through. The effect below fires the queued paste once the\r\n // editing scope catches up.\r\n // ---------------------------------------------------------------------------\r\n const [pendingPasteRef, setPendingPasteRef] = useState<string | null>(null);\r\n useEffect(() => {\r\n if (!pendingPasteRef) return;\r\n if (!editingScope || editingScope.raw !== pendingPasteRef) return;\r\n // Wait one more tick so `resolved` (used to decide replace-confirm) has\r\n // a chance to settle for the new ref.\r\n const t = window.setTimeout(() => {\r\n setPendingPasteRef(null);\r\n void pasteCurrent();\r\n }, 0);\r\n return () => window.clearTimeout(t);\r\n }, [pendingPasteRef, editingScope, pasteCurrent]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Per-row clipboard wiring for the rail context menu. Row Copy uses the\r\n // summary's pre-loaded `data` (the facet rail loads it; product rail\r\n // stubs return null and surface no Copy). Row Paste selects the target\r\n // and queues the paste.\r\n // ---------------------------------------------------------------------------\r\n const rowClipboard = enableClipboard ? (record: RecordSummary) => {\r\n const summaryHasData = record.data != null;\r\n const sourceParsed: ParsedRef = record.scope;\r\n\r\n const compat = clipboard.entry\r\n ? checkPasteCompatibility(\r\n { kind: clipboard.entry.sourceScope, raw: clipboard.entry.sourceRef },\r\n sourceParsed,\r\n )\r\n : null;\r\n const sameRef = clipboard.entry?.sourceRef === record.ref;\r\n\r\n return {\r\n onCopy: summaryHasData ? () => {\r\n const value = onCopyOverride\r\n ? onCopyOverride({ value: record.data as TData, scope: sourceParsed })\r\n : cloneValue(record.data as TData);\r\n clipboard.set({\r\n value,\r\n sourceScope: sourceParsed.kind,\r\n sourceRef: record.ref,\r\n sourceLabel: record.label,\r\n });\r\n onTelemetry?.({ type: 'clipboard.copy', recordType, sourceRef: record.ref });\r\n setClipboardNotice({\r\n message: i18n.copyToast.replace('{name}', record.label),\r\n variant: 'copy',\r\n });\r\n } : undefined,\r\n onPaste: () => {\r\n // Select the row in the rail (drives editingScope), then queue paste.\r\n onLeftSelectRef.current?.(record);\r\n setPendingPasteRef(record.ref);\r\n },\r\n canPaste: !!clipboard.entry && !sameRef && (compat?.status !== 'denied'),\r\n pasteWillReplace: record.status === 'configured',\r\n clipboardSourceLabel: clipboard.entry?.sourceLabel,\r\n };\r\n } : undefined;\r\n\r\n // The rail's `onLeftSelect` is defined further down, but the rowClipboard\r\n // closure needs it. Capture the latest reference via a ref.\r\n const onLeftSelectRef = useRef<((item: RecordSummary) => void) | null>(null);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Collection-cardinality item handlers — open / create / delete. Each\r\n // routes through the dirty-nav guard so unsaved edits aren't silently lost.\r\n // ---------------------------------------------------------------------------\r\n const baseScopeRef = editingScope?.raw ?? '';\r\n const itemNounLabel = itemNoun || 'item';\r\n\r\n // Build the URL-facing `item` value: bare id at the collection root, full\r\n // ref like `product:abc/item:foo` when the item lives under a scope.\r\n const buildItemUrlValue = useCallback((id: string): string => {\r\n return baseScopeRef ? `${baseScopeRef}/item:${id}` : id;\r\n }, [baseScopeRef]);\r\n\r\n const onItemOpen = useCallback((itemId: string) => {\r\n if (!isCollection) return;\r\n void runWithGuard(() => {\r\n setSelectedItemId(itemId);\r\n onTelemetry?.({ type: 'item.open', recordType, scopeRef: baseScopeRef, itemId });\r\n deepLinkState.emit({ item: buildItemUrlValue(itemId) }, 'item.open');\r\n });\r\n }, [isCollection, runWithGuard, onTelemetry, recordType, baseScopeRef, deepLinkState, buildItemUrlValue]);\r\n\r\n const onItemCreate = useCallback(() => {\r\n if (!isCollection) return;\r\n void runWithGuard(() => {\r\n const id = generateItemId ? generateItemId() : defaultItemId();\r\n setSelectedItemId(id);\r\n onTelemetry?.({ type: 'item.create', recordType, scopeRef: baseScopeRef });\r\n deepLinkState.emit({ item: buildItemUrlValue(id) }, 'item.open');\r\n });\r\n }, [isCollection, runWithGuard, generateItemId, onTelemetry, recordType, baseScopeRef, deepLinkState, buildItemUrlValue]);\r\n\r\n const onItemDelete = useCallback(async (itemId: string) => {\r\n if (!isCollection) return;\r\n const ref = buildItemRef(baseScopeRef, itemId);\r\n // Delegate to the host's pre-delete hook when supplied. Same UX as the\r\n // editor's own Delete button.\r\n if (onBeforeDelete) {\r\n const ok = await onBeforeDelete(parseRef(ref));\r\n if (!ok) return;\r\n }\r\n try {\r\n const { deleteRecord } = await import('../data/records');\r\n await deleteRecord(ctx, ref);\r\n onTelemetry?.({ type: 'item.delete', recordType, scopeRef: baseScopeRef, itemId });\r\n // If the user happened to have this item open, drop back to the list.\r\n if (selectedItemId === itemId) setSelectedItemId(null);\r\n // If the URL pointed at the now-deleted item, clear it.\r\n if (selectedItemId === itemId) deepLinkState.emit({ item: null }, 'item.close');\r\n collectionItems.refetch();\r\n } catch (err) {\r\n // eslint-disable-next-line no-console\r\n console.error('[RecordsAdminShell] item delete failed', err);\r\n }\r\n }, [\r\n isCollection, baseScopeRef, ctx, onBeforeDelete, onTelemetry, recordType,\r\n selectedItemId, collectionItems, deepLinkState,\r\n ]);\r\n\r\n const itemViewCtx = useMemo(() => ({\r\n onOpen: onItemOpen,\r\n onCreate: onItemCreate,\r\n onDelete: (id: string) => { void onItemDelete(id); },\r\n scope: editingScope ?? parseRef(''),\r\n selectedId: selectedItemId ?? undefined,\r\n isLoading: collectionItems.isLoading,\r\n }), [onItemOpen, onItemCreate, onItemDelete, editingScope, selectedItemId, collectionItems.isLoading]);\r\n\r\n // Sibling navigation in the editor — Back / prev / next.\r\n const itemPosition = useMemo(() => {\r\n if (!isCollection || !selectedItemId) return null;\r\n const idx = collectionItems.items.findIndex((it) => it.itemId === selectedItemId);\r\n if (idx < 0) return null;\r\n return { index: idx, total: collectionItems.items.length };\r\n }, [isCollection, selectedItemId, collectionItems.items]);\r\n\r\n const onItemBack = useCallback(() => {\r\n void runWithGuard(() => {\r\n setSelectedItemId(null);\r\n deepLinkState.emit({ item: null }, 'item.close');\r\n });\r\n }, [runWithGuard, deepLinkState]);\r\n\r\n // Prev/next siblings move via `item.step` so the URL replaces rather than\r\n // pushes — keeps the back stack meaningful (back goes to the *list*, not\r\n // through every sibling you flicked past).\r\n const stepToItem = useCallback((id: string) => {\r\n void runWithGuard(() => {\r\n setSelectedItemId(id);\r\n onTelemetry?.({ type: 'item.open', recordType, scopeRef: baseScopeRef, itemId: id });\r\n deepLinkState.emit({ item: buildItemUrlValue(id) }, 'item.step');\r\n });\r\n }, [runWithGuard, onTelemetry, recordType, baseScopeRef, deepLinkState, buildItemUrlValue]);\r\n\r\n const onItemPrev = useCallback(() => {\r\n if (!itemPosition || itemPosition.index <= 0) return;\r\n const next = collectionItems.items[itemPosition.index - 1];\r\n if (next?.itemId) stepToItem(next.itemId);\r\n }, [itemPosition, collectionItems.items, stepToItem]);\r\n\r\n const onItemNext = useCallback(() => {\r\n if (!itemPosition || itemPosition.index >= itemPosition.total - 1) return;\r\n const next = collectionItems.items[itemPosition.index + 1];\r\n if (next?.itemId) stepToItem(next.itemId);\r\n }, [itemPosition, collectionItems.items, stepToItem]);\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 (!editingTargetScope) 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={editingTargetScope}\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 // Editor-item nav (Back / position / prev / next) renders above the\r\n // editor whenever an item is open in collection mode. Inserted via\r\n // RecordEditor's `headerExtra` slot if available — fall back to wrapping.\r\n const itemNav = isCollection && selectedItemId && itemPosition ? (\r\n <EditorItemNav\r\n label={editorHeaderLabel}\r\n position={itemPosition.index + 1}\r\n total={itemPosition.total}\r\n onBack={onItemBack}\r\n onPrev={onItemPrev}\r\n onNext={onItemNext}\r\n canPrev={itemPosition.index > 0}\r\n canNext={itemPosition.index < itemPosition.total - 1}\r\n i18n={i18n}\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 targeting={editingTargetScope.kind === 'rule' ? (\r\n <RecordTargeting\r\n SL={SL}\r\n collectionId={collectionId}\r\n appId={appId}\r\n ctx={editorCtx}\r\n />\r\n ) : undefined}\r\n onBeforeDelete={onBeforeDelete && editingTargetScope\r\n ? () => onBeforeDelete(editingTargetScope)\r\n : undefined}\r\n headerLabel={editorHeaderLabel}\r\n headerSubtitle={editorHeaderSubtitle}\r\n headerMeta={editorHeaderMeta}\r\n clipboard={editorClipboard}\r\n actionLabels={actionLabels}\r\n actionIcons={actionIcons}\r\n >\r\n {renderEditor(editorCtx)}\r\n </RecordEditor>\r\n );\r\n\r\n // Wrap any rendered editor variant with the item nav strip on top.\r\n const withNav = (node: ReactNode): ReactNode => itemNav ? (\r\n <div className=\"flex flex-col h-full min-h-0\">\r\n {itemNav}\r\n <div className=\"flex-1 min-h-0 overflow-hidden\">{node}</div>\r\n </div>\r\n ) : node;\r\n\r\n // No preview supplied → just the editor.\r\n if (!previewBody) return withNav(baseEditor());\r\n\r\n if (previewMode === 'inline') {\r\n return withNav(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 withNav(\r\n <div className=\"relative h-full\">\r\n {baseEditor()}\r\n <button\r\n type=\"button\"\r\n className=\"ra-preview-reopen\"\r\n onClick={() => setSidePreviewOpen(true)}\r\n aria-label={i18n.openPreview}\r\n title={i18n.openPreview}\r\n >\r\n <Eye aria-hidden=\"true\" />\r\n {i18n.preview}\r\n </button>\r\n </div>,\r\n );\r\n }\r\n return withNav(\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 withNav(\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 withNav(\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 // Rule / Global tabs surface records straight from `recordList`. Facet\r\n // keeps the existing facet-vocabulary-driven rail (synthesises rows for\r\n // facet values that don't yet have a record).\r\n const isRuleTab = activeScope === 'rule';\r\n const isGlobalTab = activeScope === 'collection';\r\n const isRecordsTab = isRuleTab || isGlobalTab;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Rule creation — opens the editor seeded with an empty facet rule.\r\n //\r\n // We don't write anything to the SDK here. The editor mounts against the\r\n // newly-minted `rule:{id}` ref; the resolver returns `source: 'empty'`\r\n // (no record exists yet); the host's `renderEditor` is responsible for\r\n // surfacing the `FacetRuleEditor` and persisting the assembled rule on\r\n // first save (via `app.records.upsert({ facetRule, ref })`).\r\n //\r\n // This mirrors how `+ New product` / `+ New item` work elsewhere — the\r\n // shell creates the slot, the host owns the form.\r\n // ---------------------------------------------------------------------------\r\n const onCreateRule = useCallback(() => {\r\n void runWithGuard(() => {\r\n const id = newRuleId();\r\n const ref = `rule:${id}`;\r\n // Make sure we're on the Rules tab so the new ref is visible in the\r\n // rail (it'll appear once the next list refresh lands a saved record).\r\n if (activeScope !== 'rule') setActiveScope('rule');\r\n setSelectedFacetRef(ref);\r\n // Persistence-side telemetry fires from `useRecordEditor.onSaved` once\r\n // the host actually saves the new rule.\r\n });\r\n }, [runWithGuard, activeScope]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Global default creation — opens the editor seeded at the empty ref ('').\r\n //\r\n // The empty ref is the canonical collection-root scope: a record saved\r\n // here is inherited by every more-specific scope (product/facet/variant/\r\n // batch) until something overrides it. Like rule creation, we don't write\r\n // anything to the SDK here — the host's `renderEditor` mounts at this ref\r\n // and persists on first save.\r\n //\r\n // In singleton mode there can be at most one such record, so we hide the\r\n // button once one exists. Collection-cardinality apps may want many items\r\n // under the global scope, in which case the button stays available.\r\n // ---------------------------------------------------------------------------\r\n const hasGlobalRecord = useMemo(\r\n () => recordList.items.some((it) => !it.scope.productId && !it.scope.facetId\r\n && !it.scope.variantId && !it.scope.batchId && !it.scope.proofId\r\n && !it.scope.itemId && !it.ref.startsWith('item:') && !it.ref.includes('/item:')),\r\n [recordList.items],\r\n );\r\n const showCreateGlobal = isGlobalTab && (isCollection || !hasGlobalRecord);\r\n const onCreateGlobal = useCallback(() => {\r\n void runWithGuard(() => {\r\n if (activeScope !== 'collection') setActiveScope('collection');\r\n // Empty ref = collection root. Resolver returns `source: 'empty'`;\r\n // editor mounts an empty form and saves with `scope: {}`.\r\n setSelectedFacetRef('');\r\n });\r\n }, [runWithGuard, activeScope]);\r\n\r\n // Apply the Rules-tab quick filters on top of the records-driven list.\r\n // Facet-keys and minClauses live in shell state and reset when the tab\r\n // changes; the chip vocabulary is derived from the unfiltered list so\r\n // tightening a filter never makes the chips themselves disappear.\r\n const filteredRuleItems = useMemo(\r\n () => (isRuleTab ? applyRuleFilters(recordList.items, ruleFilters) : recordList.items),\r\n [isRuleTab, recordList.items, ruleFilters],\r\n );\r\n\r\n // In collection-cardinality mode, item-level records (refs containing an\r\n // `item:` segment) belong to the right-pane `ItemListView`, not the rail.\r\n // Without this filter the rail duplicates every SOP / FAQ / recipe as if\r\n // it were its own scope, and clicking one auto-selects an item ref that\r\n // never matches any rail-level scope — resulting in the \"configured rail\r\n // row, empty right pane\" confusion users were hitting on the Global tab.\r\n const stripItemRecords = useCallback(\r\n (items: RecordSummary[]) => items.filter((it) => !it.scope.itemId\r\n && !it.ref.startsWith('item:') && !it.ref.includes('/item:')),\r\n [],\r\n );\r\n\r\n const leftItems = isProductTab\r\n ? productListItems\r\n : isRuleTab\r\n ? (isCollection ? stripItemRecords(filteredRuleItems) : filteredRuleItems)\r\n : isRecordsTab\r\n ? (isCollection ? stripItemRecords(recordList.items) : recordList.items)\r\n : facetBrowse.items;\r\n const leftLoading = isProductTab\r\n ? (!productPinned && productBrowse.isLoading)\r\n : isRecordsTab\r\n ? (recordList.isLoading || probe.isLoading)\r\n : (facetBrowse.isLoading || recordList.isLoading || probe.isLoading);\r\n const leftError = isProductTab\r\n ? productBrowse.error\r\n : isRecordsTab\r\n ? recordList.error\r\n : (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 // Facet, Rule and Global tabs all flow through the records-driven\r\n // selection — `editingScope` re-derives from this ref.\r\n setSelectedFacetRef(item.ref);\r\n }\r\n });\r\n };\r\n // Keep the ref pointed at the latest selector so the rowClipboard closure\r\n // — created earlier in this render pass — can call into it.\r\n onLeftSelectRef.current = onLeftSelect;\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 {pasteConfirm.dialog}\r\n {clipboardNotice && (\r\n <ClipboardToast\r\n message={clipboardNotice.message}\r\n variant={clipboardNotice.variant}\r\n onDismiss={() => setClipboardNotice(null)}\r\n />\r\n )}\r\n {/* Floating help — overlays the top-right of the shell when there's no\r\n * header card. Doesn't reserve layout space so it never pushes the\r\n * rail/editor content down. */}\r\n {(() => {\r\n const showFloatHelp =\r\n !!intro && dismissed\r\n && resolvedReopenAffordance === 'footer'\r\n && !headerWillRender;\r\n if (!showFloatHelp) return null;\r\n const reopenLabel = intro?.reopenLabel ?? `How ${label.toLowerCase()} works`;\r\n return (\r\n <button\r\n type=\"button\"\r\n className=\"ra-help-float\"\r\n onClick={undismiss}\r\n aria-label={reopenLabel}\r\n title={reopenLabel}\r\n >\r\n <HelpCircle aria-hidden=\"true\" />\r\n <span>{reopenLabel}</span>\r\n </button>\r\n );\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 if (!headerWillRender) return null;\r\n const showHeaderReopen =\r\n !!intro && dismissed && resolvedReopenAffordance === 'header';\r\n const reopenLabel = intro?.reopenLabel ?? `How ${label.toLowerCase()} works`;\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 trailingSlot={showHeaderReopen ? (\r\n <button\r\n type=\"button\"\r\n onClick={undismiss}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n aria-label={reopenLabel}\r\n title={reopenLabel}\r\n style={{ width: '2rem', height: '2rem', padding: 0, justifyContent: 'center' }}\r\n >\r\n <HelpCircle className=\"w-4 h-4\" />\r\n </button>\r\n ) : undefined}\r\n />\r\n );\r\n })()}\r\n {resolvedReopenAffordance === 'inline' ? (\r\n <UtilityRow\r\n label={intro?.reopenLabel ? '' : label}\r\n customLabel={intro?.reopenLabel}\r\n introHidden={dismissed && !!intro}\r\n onShowIntro={undismiss}\r\n />\r\n ) : null}\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={actionLabels?.save ?? i18n.save}\r\n discardLabel={actionLabels?.discard ?? i18n.discard}\r\n SaveIcon={actionIcons?.save}\r\n DiscardIcon={actionIcons?.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 {isCollection && selectedItemId && collectionRailMode === 'siblings' ? (\r\n <SiblingRail\r\n items={collectionItems.items}\r\n selectedItemId={selectedItemId}\r\n isLoading={collectionItems.isLoading}\r\n error={collectionItems.error}\r\n onBack={onItemBack}\r\n onSelect={onItemOpen}\r\n i18n={i18n}\r\n />\r\n ) : (\r\n <>\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 {isRuleTab && (\r\n <button\r\n type=\"button\"\r\n onClick={onCreateRule}\r\n className=\"ra-btn w-full\"\r\n data-variant=\"primary\"\r\n aria-label=\"New rule\"\r\n >\r\n <Plus className=\"w-3.5 h-3.5\" aria-hidden=\"true\" />\r\n <span>New rule</span>\r\n </button>\r\n )}\r\n {showCreateGlobal && (\r\n <button\r\n type=\"button\"\r\n onClick={onCreateGlobal}\r\n className=\"ra-btn w-full\"\r\n data-variant=\"primary\"\r\n aria-label=\"New global default\"\r\n >\r\n <Plus className=\"w-3.5 h-3.5\" aria-hidden=\"true\" />\r\n <span>New global default</span>\r\n </button>\r\n )}\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 {isRuleTab && (\r\n <RuleFilterChips\r\n source={recordList.items}\r\n value={ruleFilters}\r\n onChange={setRuleFilters}\r\n />\r\n )}\r\n {/* Collection-mode \"+ New\" lives in the right-pane toolbar now. */}\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 groupBy={effectiveGroupBy}\r\n rowClipboard={rowClipboard}\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 </>\r\n )}\r\n </aside>\r\n <main className=\"overflow-hidden\">\r\n {/* Collection mode: scope selected, no item open → item list view. */}\r\n {isCollection && editingScope && !selectedItemId && (\r\n <ItemListView\r\n items={collectionItems.items}\r\n isLoading={collectionItems.isLoading}\r\n error={collectionItems.error}\r\n ctx={itemViewCtx}\r\n itemNoun={itemNounLabel}\r\n view={itemView}\r\n views={itemViews}\r\n onViewChange={onItemViewChange}\r\n renderItemList={renderItemList}\r\n renderItemCard={renderItemCard}\r\n renderItemEmpty={renderItemEmpty}\r\n itemColumns={itemColumns}\r\n i18n={i18n}\r\n />\r\n )}\r\n {!isCollection && !editingScope && activeScope === 'product' && !selectedProductId && (\r\n <EmptyState title={i18n.emptyTitle} body={i18n.emptyBody} />\r\n )}\r\n {!isCollection && !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 In collection mode the editor only shows once an item is open;\r\n otherwise the item list view above takes the pane. */}\r\n {isProductTab && selectedProductId && (!isCollection || selectedItemId) && (\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 hideSingleTab={editorTabs === 'off' || editorTabs === 'multi'}\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 {editingTargetScope ? 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 (singleton mode), or the\r\n editor when an item is open (collection mode). */}\r\n {!isProductTab && editingTargetScope && (!isCollection || selectedItemId) && 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};","// =============================================================================\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\nimport { RowContextMenu } from './RowContextMenu';\r\nimport { DEFAULT_I18N } from '../types';\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, onCopy, onPaste, canPaste, pasteWillReplace, clipboardSourceLabel } = 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=\"flex items-start gap-1.5 min-w-0\">\r\n <div className=\"ra-row-title flex-1 min-w-0\">{record.label}</div>\r\n {(onCopy || onPaste) && (\r\n <RowContextMenu\r\n onCopy={onCopy}\r\n onPaste={onPaste}\r\n canPaste={canPaste}\r\n pasteWillReplace={pasteWillReplace}\r\n pasteSourceLabel={clipboardSourceLabel}\r\n i18n={{\r\n copy: DEFAULT_I18N.copy,\r\n paste: DEFAULT_I18N.paste,\r\n pasteFrom: DEFAULT_I18N.pasteFrom,\r\n pasteReplace: DEFAULT_I18N.pasteReplace,\r\n clipboardEmpty: DEFAULT_I18N.clipboardEmpty,\r\n }}\r\n />\r\n )}\r\n </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","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// 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}"]}
|