@proveanything/smartlinks-utils-ui 0.8.3 → 0.9.0
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-NSQRNFT2.js +28 -0
- package/dist/chunk-NSQRNFT2.js.map +1 -0
- package/dist/components/AssetPicker/index.js +1 -1
- package/dist/components/ConditionsEditor/index.js +1 -1
- package/dist/components/FontPicker/index.js +1 -1
- package/dist/components/IconPicker/index.js +1 -1
- package/dist/components/RecordsAdmin/index.d.ts +160 -260
- package/dist/components/RecordsAdmin/index.js +4303 -3907
- package/dist/components/RecordsAdmin/index.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-F2YH3NVP.js +0 -28
- package/dist/chunk-F2YH3NVP.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/RecordsAdmin/shell/icons.ts","../../../src/components/RecordsAdmin/types/i18n.ts","../../../src/components/RecordsAdmin/types/presentation.ts","../../../src/components/RecordsAdmin/types/deepLink.ts","../../../src/components/RecordsAdmin/data/refs.ts","../../../src/components/RecordsAdmin/data/resolveRecord.ts","../../../src/components/RecordsAdmin/hooks/useResolvedRecord.ts","../../../src/components/RecordsAdmin/hooks/useIntroDismissed.ts","../../../src/components/RecordsAdmin/hooks/useScopeProbe.ts","../../../src/components/RecordsAdmin/hooks/useRecordList.ts","../../../src/components/RecordsAdmin/hooks/useFacetBrowse.ts","../../../src/components/RecordsAdmin/hooks/useProductBrowse.ts","../../../src/components/RecordsAdmin/hooks/useProductChildren.ts","../../../src/components/RecordsAdmin/browser/RuleFilterChips.tsx","../../../src/components/RecordsAdmin/hooks/useShellBrowser.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/useRecordClipboard.ts","../../../src/components/RecordsAdmin/hooks/usePasteConfirm.tsx","../../../src/components/RecordsAdmin/shell/ClipboardToast.tsx","../../../src/components/RecordsAdmin/hooks/useShellClipboard.tsx","../../../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/FacetBrowseFilter.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/data/postMessageDeepLinkAdapter.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/hooks/useRulePreview.ts","../../../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/AdminPageHeader/admin-page-header.css","../../../src/components/AdminPageHeader/AdminPageHeader.tsx","../../../src/components/RecordsAdmin/shell/ShellHeader.tsx","../../../src/components/RecordsAdmin/shell/NewRuleWizard.tsx","../../../src/components/RecordsAdmin/shell/UnsavedTray.tsx","../../../src/components/RecordsAdmin/shell/HeaderUnsavedPill.tsx","../../../src/components/RecordsAdmin/shell/SaveAllProgress.tsx","../../../src/components/RecordsAdmin/editor-session/editorStore.ts","../../../src/components/RecordsAdmin/editor-session/EditorSessionProvider.tsx","../../../src/components/RecordsAdmin/editor-session/EditorMountPool.tsx","../../../src/components/RecordsAdmin/editor-session/useEditorSlotContext.ts","../../../src/components/RecordsAdmin/editor-session/useEditorBridge.ts","../../../src/components/RecordsAdmin/data/csv.ts","../../../src/components/RecordsAdmin/hooks/useShellCsvBulk.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/useDirtyDraftStore.tsx","../../../src/components/RecordsAdmin/hooks/useRecordEditor.ts","../../../src/components/RecordsAdmin/hooks/useResolveAllRecords.ts","../../../src/components/RecordsAdmin/hooks/useCollectedRecords.ts","../../../src/components/RecordsAdmin/hooks/useMergedRecord.ts"],"names":["eq","useQuery","classify","total","useState","useEffect","useCallback","useQueryClient","useMemo","QK","useInfiniteQuery","items","res","useRef","jsxs","jsx","DEFAULTS","CopyIcon","MoreHorizontal","Copy","ClipboardPaste","Inbox","QK_BASE","toSummary","Layers","Upload","Download","ChevronDown","Trash2","Fragment","ChevronRight","Package","Eye","ICONS","TableIcon","LayoutGrid","ImageIcon","labelFor","Pencil","Plus","PlusIcon","ArrowLeft","Lightbulb","CheckCircle2","AlertTriangle","X","TONE_ICON","HelpCircle","Info","AlertCircle","Save","Undo2","label","removeRecord","Search","initials","createContext","useContext","Circle","useSyncExternalStore","isEqual","isRuleScope","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 /**\r\n * Shell-level \"Save all\" tray strings (multi-record dirty workflow).\r\n * `{n}` placeholders interpolate the count.\r\n */\r\n unsavedTrayCount: string; // \"{n} records have unsaved changes\"\r\n unsavedTrayErrors: string; // \"{n} errors\"\r\n saveAll: string; // \"Save all\"\r\n discardAll: string; // \"Discard all\"\r\n saveAllInProgress: string; // \"Saving {n} records…\"\r\n saveAllSuccess: string; // \"Saved {n} records\"\r\n saveAllErrorTitle: string; // \"Saved with errors\"\r\n saveAllStop: string; // \"Stop\"\r\n saveAllClose: string; // \"Close\"\r\n saveAllRetryFailed: string; // \"Retry failed\"\r\n saveAllJumpToError: string; // \"Jump to first error\"\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\n * Label for the synthetic \"All items\" rail row shown on the Global tab in\r\n * collection-cardinality mode (no `groupBy`). Selecting it pins the right\r\n * pane to the multi-item list.\r\n */\r\n itemsAllLabel: string;\r\n\r\n /**\r\n * Default subtitle copy shown beneath a row's label in the browse rail when\r\n * the host hasn't supplied a `subtitle` on the RecordSummary. Apps can\r\n * override these to match their domain noun (e.g. \"No recipe yet\").\r\n */\r\n subtitleEmpty: string;\r\n subtitleConfigured: string;\r\n subtitleInherited: 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 unsavedTrayCount: '{n} records have unsaved changes',\r\n unsavedTrayErrors: '{n} errors',\r\n saveAll: 'Save all',\r\n discardAll: 'Discard all',\r\n saveAllInProgress: 'Saving {n} records…',\r\n saveAllSuccess: 'Saved {n} records',\r\n saveAllErrorTitle: 'Saved with errors',\r\n saveAllStop: 'Stop',\r\n saveAllClose: 'Close',\r\n saveAllRetryFailed: 'Retry failed',\r\n saveAllJumpToError: 'Jump to first error',\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 itemsAllLabel: 'All items',\r\n subtitleEmpty: 'Not set',\r\n subtitleConfigured: 'Configured',\r\n subtitleInherited: 'Inherited',\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// - `recordId` → SDK-assigned UUID of the open record. Loading by id is\r\n// unambiguous: the resolver returns the record, the shell\r\n// derives anchors from it and lands on the right tab.\r\n// - `scope` → anchor ref (e.g. `product:abc` or empty for collection\r\n// root). Used only when no record is open, to deep-link to\r\n// a list/browse view. Never carries synthetic `rule:` or\r\n// `item:` segments — the shell stopped minting those once\r\n// records grew stable UUIDs.\r\n// - `view` → right-pane view (`table` / `cards` / `gallery`).\r\n// Optional 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 `'recordId'`. */\r\n recordId?: 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 /** UUID of the record open in the editor (SDK-assigned). */\r\n recordId?: string | null;\r\n /** Anchor scope ref when no record 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 recordId: string;\r\n scope: string;\r\n view: string;\r\n}\r\n\r\nexport const DEFAULT_DEEP_LINK_PARAM_NAMES: ResolvedDeepLinkParamNames = {\r\n recordId: 'recordId',\r\n scope: 'scope',\r\n view: 'view',\r\n};","// =============================================================================\r\n// Ref parsing — `kind:id` segments joined by `/`.\r\n//\r\n// HISTORICAL NOTE: in earlier shell versions we used these helpers as the\r\n// universal \"coordinate\" for selection state, drafts, and item identity.\r\n// That conflated `record.ref` (an OPTIONAL EXTERNAL HANDLE the app sets to\r\n// map to a third-party id) with internal record identity (the SDK-assigned\r\n// UUID). Refs are now back to being app-owned strings only — the shell\r\n// addresses every record by UUID.\r\n//\r\n// What's still here, and why:\r\n// - `parseRef` / `buildRef` decode anchor IDs from URL deep-link `?scope=`\r\n// parameters and feed `useFacetBrowse` / CSV import (both consume\r\n// anchor-ref strings the user can paste). Anchors only — no synthetic\r\n// `rule:` or `item:` segments.\r\n// - `resolutionChain` builds the parent-anchor chain the resolver walks\r\n// for inheritance. Anchors only.\r\n//\r\n// What's GONE and must NOT come back:\r\n// - `splitItemRef` / `buildItemRef` — items are records; identity is\r\n// `record.id` (UUID). No `/item:{id}` suffix.\r\n// - `newRuleId()` and `rule:{id}` minting — drafts are tracked in shell\r\n// state until the first save returns a UUID.\r\n// - `KIND_KEYS.rule` / `parseRef`-of-`rule:…` — rule records are\r\n// identified by `facetRule != null`, addressed by UUID.\r\n// =============================================================================\r\nimport type { ParsedRef, ScopeKind } from '../types';\r\n\r\nconst KIND_KEYS: Record<'product' | 'facet' | 'variant' | 'batch' | 'proof' | 'collection', keyof ParsedRef> = {\r\n product: 'productId',\r\n facet: 'facetId',\r\n variant: 'variantId',\r\n batch: 'batchId',\r\n proof: 'proofId',\r\n collection: 'collectionId',\r\n};\r\n\r\nexport const parseRef = (raw: string): ParsedRef => {\r\n const parsed: ParsedRef = { kind: 'collection', raw };\r\n if (!raw) return parsed;\r\n const segments = raw.split('/').filter(Boolean);\r\n let kind: ParsedRef['kind'] = 'collection';\r\n for (const seg of segments) {\r\n const idx = seg.indexOf(':');\r\n if (idx < 0) continue;\r\n const k = seg.slice(0, idx) as ScopeKind | 'collection' | 'proof';\r\n const id = seg.slice(idx + 1);\r\n if (k === 'facet') {\r\n // facet:<id>=<value> or facet:<id>\r\n const eq = id.indexOf('=');\r\n if (eq >= 0) {\r\n parsed.facetId = id.slice(0, eq);\r\n parsed.facetValue = id.slice(eq + 1);\r\n } else {\r\n parsed.facetId = id;\r\n }\r\n } else if (k in KIND_KEYS) {\r\n const slot = KIND_KEYS[k as keyof typeof KIND_KEYS];\r\n (parsed as unknown as Record<string, string>)[slot] = id;\r\n }\r\n // Unknown segments (legacy `rule:…`, `item:…` from URLs created by old\r\n // builds) are silently ignored — the shell resolves the open record by\r\n // `?recordId=` instead.\r\n if (k !== 'collection') kind = k as ParsedRef['kind'];\r\n }\r\n parsed.kind = kind;\r\n return parsed;\r\n};\r\n\r\nexport interface BuildRefArgs {\r\n collectionId?: string;\r\n productId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n proofId?: string;\r\n}\r\n\r\nexport const buildRef = (a: BuildRefArgs): string => {\r\n const parts: string[] = [];\r\n if (a.facetId) {\r\n parts.push(a.facetValue ? `facet:${a.facetId}=${a.facetValue}` : `facet:${a.facetId}`);\r\n }\r\n if (a.productId) parts.push(`product:${a.productId}`);\r\n if (a.variantId) parts.push(`variant:${a.variantId}`);\r\n if (a.batchId) parts.push(`batch:${a.batchId}`);\r\n if (a.proofId) parts.push(`proof:${a.proofId}`);\r\n return parts.join('/');\r\n};\r\n\r\n/**\r\n * Build the resolution chain for a target ref, from most specific → least specific.\r\n * `supportedScopes` prunes scopes the app doesn't care about.\r\n */\r\nexport const resolutionChain = (\r\n target: ParsedRef,\r\n supportedScopes: ScopeKind[],\r\n): string[] => {\r\n const chain: string[] = [];\r\n // Most specific → least specific\r\n if (supportedScopes.includes('batch') && target.batchId && target.productId) {\r\n chain.push(buildRef({ productId: target.productId, batchId: target.batchId }));\r\n }\r\n if (supportedScopes.includes('variant') && target.variantId && target.productId) {\r\n chain.push(buildRef({ productId: target.productId, variantId: target.variantId }));\r\n }\r\n if (supportedScopes.includes('product') && target.productId) {\r\n chain.push(buildRef({ productId: target.productId }));\r\n }\r\n if (supportedScopes.includes('facet') && target.facetId) {\r\n chain.push(buildRef({ facetId: target.facetId, facetValue: target.facetValue }));\r\n }\r\n // 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// 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 // Records addressed by UUID never reach here — `useResolvedRecord`'s\r\n // id-primary path handles them with `getRecordById`. This function is\r\n // anchor-only: pinned-scope tabs (Product / Variant / Batch / Facet) ask\r\n // the server to evaluate the inheritance chain.\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 // SDK 1.10.2: `MatchResult.data` (was `.records`); each entry extends\r\n // `AppRecord` directly (no inner `record`).\r\n const entries = result?.data ?? [];\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdmin/resolveRecord]', {\r\n editingScope,\r\n target,\r\n matchCount: entries.length,\r\n winnerAnchors: entries[0] && {\r\n productId: entries[0].productId,\r\n variantId: entries[0].variantId,\r\n batchId: entries[0].batchId,\r\n proofId: entries[0].proofId,\r\n },\r\n winnerRef: entries[0]?.ref,\r\n });\r\n if (entries.length === 0) {\r\n return { data: null, source: 'empty' };\r\n }\r\n\r\n const winner = entries[0];\r\n // Compare flat anchor IDs on the winner against the editing scope.\r\n const winnerIsSelf = scopesEqual(\r\n {\r\n productId: winner.productId,\r\n variantId: winner.variantId,\r\n batchId: winner.batchId,\r\n proofId: winner.proofId,\r\n },\r\n editingScope,\r\n );\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdmin/resolveRecord] classification', {\r\n winnerIsSelf,\r\n winnerAnchors: {\r\n productId: winner.productId,\r\n variantId: winner.variantId,\r\n batchId: winner.batchId,\r\n proofId: winner.proofId,\r\n },\r\n editingScope,\r\n });\r\n\r\n if (winnerIsSelf) {\r\n const parent = entries[1];\r\n return {\r\n data: winner.data as T,\r\n source: 'self',\r\n sourceRef: winner.ref ?? undefined,\r\n recordId: winner.id,\r\n parentValue: args.withParent && parent ? (parent.data as T) : undefined,\r\n matchedAt: winner.matchedAt,\r\n matchedRule: winner.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 recordId: winner.id,\r\n parentValue: args.withParent ? (winner.data as T) : undefined,\r\n matchedAt: winner.matchedAt,\r\n matchedRule: winner.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 { getRecordById } from '../data/records';\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 * Direct UUID lookup. When set, the resolver bypasses the inheritance\r\n * chain and loads this record by id (used by `?recordId=` deep-links and\r\n * by rule-record edits — both cases where the row's identity is already\r\n * known and the resolver shouldn't run a `match()`).\r\n */\r\n recordId?: 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 recordId?: 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.recordId ?? 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, recordId,\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, recordId, withParent,\r\n }),\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime: 15_000,\r\n queryFn: async () => {\r\n // Id-primary path: when the caller already has the UUID, bypass the\r\n // inheritance chain entirely. Used by `?recordId=` deep-links and by\r\n // rule records (whose identity is the recordId, not anchors).\r\n if (recordId) {\r\n const rec = await getRecordById({ SL, collectionId, appId, recordType }, recordId);\r\n if (!rec) return { data: null, source: 'empty' };\r\n const recFacetRule = (rec as unknown as { facetRule?: import('../data/sdkTypes').FacetRule | null }).facetRule ?? null;\r\n return {\r\n data: rec.data as T,\r\n source: 'self',\r\n sourceRef: rec.ref ?? undefined,\r\n recordId: rec.id,\r\n facetRule: recFacetRule,\r\n };\r\n }\r\n // Anchor path: pinned-scope tabs (Product / Variant / Batch / Facet).\r\n // The resolver runs server-side `match()` against these anchors and\r\n // returns the winning record by inheritance specificity.\r\n const target: import('../types').ParsedRef = {\r\n kind: batchId ? 'batch'\r\n : variantId ? 'variant'\r\n : productId ? 'product'\r\n : facetId ? 'facet'\r\n : 'collection',\r\n raw: '',\r\n collectionId,\r\n productId, variantId, batchId,\r\n facetId, facetValue, proofId,\r\n };\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, 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 { 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 { 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`.\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 if (kind === 'rule') return hasRule;\r\n if (hasRule) return false;\r\n // Anchor checks read the canonical anchor IDs straight off the record —\r\n // no ref-string parsing needed now that the SDK keeps them flat.\r\n const productId = (rec as { productId?: string | null }).productId ?? undefined;\r\n const variantId = (rec as { variantId?: string | null }).variantId ?? undefined;\r\n const batchId = (rec as { batchId?: string | null }).batchId ?? undefined;\r\n const proofId = (rec as { proofId?: string | null }).proofId ?? undefined;\r\n\r\n if (kind === 'collection') {\r\n // \"Global\" — no pinned scope at all. Empty/missing ref counts.\r\n return !productId && !variantId && !batchId && !proofId;\r\n }\r\n if (kind === 'product') return !!productId && !variantId && !batchId;\r\n // `facet` was deprecated as a top-level tab in 0.5; pinned-facet records\r\n // never reach this branch from the modern shell.\r\n if (kind === 'variant') return !!variantId;\r\n if (kind === 'batch') return !!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 // Build a ParsedRef from the flat anchors on the record itself rather\r\n // than from `ref` — refs are now caller-supplied external keys (or empty)\r\n // and no longer encode anchors.\r\n const productId = (rec as { productId?: string | null }).productId ?? undefined;\r\n const variantId = (rec as { variantId?: string | null }).variantId ?? undefined;\r\n const batchId = (rec as { batchId?: string | null }).batchId ?? undefined;\r\n const proofId = (rec as { proofId?: string | null }).proofId ?? undefined;\r\n const scope: ParsedRef = {\r\n kind: batchId ? 'batch' : variantId ? 'variant' : productId ? 'product' : 'collection',\r\n raw: ref,\r\n productId, variantId, batchId, proofId,\r\n };\r\n const facetRule = (rec as { facetRule?: FacetRule | null }).facetRule ?? null;\r\n if (facetRule) scope.kind = 'rule';\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 ?? ruleLabel\r\n ?? (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};","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// 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// useShellBrowser — owns the rail's \"what records are visible\" state for the\r\n// RecordsAdminShell.\r\n//\r\n// Responsibilities:\r\n// • Filter state: search, status filter, rule filters, \"browse by facet\"\r\n// selection.\r\n// • Browse data sources: products, records (rule/global tabs), facet\r\n// vocabulary, lazy variant/batch children for the selected product.\r\n// • Cross-cutting effects:\r\n// - reset filters when the active top-level scope changes;\r\n// - bulk refetch helper used by save/delete success paths.\r\n//\r\n// Selection state (selectedRecordId / selectedProductId / draftKind /\r\n// rule wizard / drill-down) intentionally stays in the shell — it is too\r\n// entangled with the editor target and deep linking to move in this slice.\r\n// We accept those values as inputs and expose just the rail data + the\r\n// filter setters back to the shell.\r\n// =============================================================================\r\nimport { useCallback, useEffect, useState } from 'react';\r\nimport type { ScopeKind, RecordStatus, RecordSummary, SmartLinksSDK } from '../types';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport { useRecordList } from './useRecordList';\r\nimport { useFacetBrowse } from './useFacetBrowse';\r\nimport { useProductBrowse, type ProductBrowseItem } from './useProductBrowse';\r\nimport { useProductChildren } from './useProductChildren';\r\nimport {\r\n EMPTY_RULE_FILTERS,\r\n type RuleFilters,\r\n} from '../browser/RuleFilterChips';\r\nimport type { FacetBrowseSelection } from '../browser/FacetBrowseFilter';\r\nimport type { DrillTab } from '../editor/ProductDrillDown';\r\n\r\nexport interface UseShellBrowserOptions {\r\n ctx: RecordsCtx;\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n activeScope: ScopeKind;\r\n contextScope?: { productId?: string; variantId?: string; batchId?: string };\r\n /** Result of `useScopeProbe` — we only need its loading flag. */\r\n probeIsLoading: boolean;\r\n /** From the shell — `cardinality === 'collection'`. */\r\n isCollection: boolean;\r\n /** Selected product (drives variant/batch children fetches). */\r\n selectedProductId: string | undefined;\r\n /** Drill tab inside the product scope. */\r\n drillTab: DrillTab;\r\n /** Optional record classifier passed through from the host. */\r\n classify?: (r: RecordSummary) => RecordStatus;\r\n}\r\n\r\nexport interface UseShellBrowserResult {\r\n // Filter state\r\n search: string;\r\n setSearch: (v: string) => void;\r\n filter: 'all' | RecordStatus;\r\n setFilter: (v: 'all' | RecordStatus) => void;\r\n ruleFilters: RuleFilters;\r\n setRuleFilters: (v: RuleFilters) => void;\r\n facetBrowseFilter: FacetBrowseSelection | null;\r\n setFacetBrowseFilter: (v: FacetBrowseSelection | null) => void;\r\n\r\n // Data sources\r\n productBrowse: ReturnType<typeof useProductBrowse>;\r\n recordList: ReturnType<typeof useRecordList>;\r\n facetBrowse: ReturnType<typeof useFacetBrowse>;\r\n variantChildren: ReturnType<typeof useProductChildren>;\r\n batchChildren: ReturnType<typeof useProductChildren>;\r\n\r\n /** Refetch every browse data source. Used after save/delete. */\r\n refetchAll: () => void;\r\n}\r\n\r\n/** Re-export so the shell keeps a single import surface. */\r\nexport type { ProductBrowseItem };\r\n\r\nexport function useShellBrowser(opts: UseShellBrowserOptions): UseShellBrowserResult {\r\n const {\r\n ctx, SL, collectionId, activeScope, contextScope,\r\n probeIsLoading, isCollection: _isCollection,\r\n selectedProductId, drillTab, classify,\r\n } = opts;\r\n\r\n // ---- Filter state ----------------------------------------------------------\r\n const [search, setSearch] = useState('');\r\n const [filter, setFilter] = useState<'all' | RecordStatus>('all');\r\n const [ruleFilters, setRuleFilters] = useState<RuleFilters>(EMPTY_RULE_FILTERS);\r\n const [facetBrowseFilter, setFacetBrowseFilter] =\r\n useState<FacetBrowseSelection | null>(null);\r\n\r\n // Reset filters whenever the active top-level scope changes. Selection\r\n // resets (selectedRecordId / draftKind) still live in the shell because\r\n // they're entangled with the editor target.\r\n useEffect(() => {\r\n setSearch('');\r\n setFilter('all');\r\n setRuleFilters(EMPTY_RULE_FILTERS);\r\n setFacetBrowseFilter(null);\r\n }, [activeScope]);\r\n\r\n // ---- Browse data ----------------------------------------------------------\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 const recordListEnabled =\r\n (activeScope === 'rule' || activeScope === 'collection')\r\n && !probeIsLoading;\r\n const recordList = useRecordList({\r\n ctx, scopeKind: activeScope, search, filter,\r\n classify,\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: [],\r\n enabled: (activeScope === 'rule' || activeScope === 'collection') && !probeIsLoading,\r\n });\r\n\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 const refetchAll = useCallback(() => {\r\n productBrowse.refetch();\r\n recordList.refetch();\r\n facetBrowse.refetch();\r\n variantChildren.refetch?.();\r\n batchChildren.refetch?.();\r\n }, [productBrowse, recordList, facetBrowse, variantChildren, batchChildren]);\r\n\r\n return {\r\n search, setSearch,\r\n filter, setFilter,\r\n ruleFilters, setRuleFilters,\r\n facetBrowseFilter, setFacetBrowseFilter,\r\n productBrowse, recordList, facetBrowse,\r\n variantChildren, batchChildren,\r\n refetchAll,\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// 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 /**\r\n * The full parsed scope the value was copied from. Carries scope kind +\r\n * anchors so paste-compat can compare structurally without re-parsing a\r\n * string. The `raw` field is purely for friendly display (toasts).\r\n */\r\n sourceScope: ParsedRef;\r\n /**\r\n * UUID of the source record, when the copy originated from a saved\r\n * AppRecord (records-driven rails, in-editor copy of a saved record).\r\n * Absent when copying from a synthesised anchor row (Products tab) or\r\n * a never-saved draft. Used for self-paste detection.\r\n */\r\n sourceRecordId?: 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// 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// 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// useShellClipboard — extracted from RecordsAdminShell.\r\n//\r\n// Owns every clipboard concern the shell used to bake inline:\r\n// * the cross-shell clipboard store (useRecordClipboard)\r\n// * copy / paste handlers for the active editor\r\n// * row-level copy/paste wiring used by the rail context menu\r\n// * the deferred \"paste once selection settles\" effect\r\n// * the paste-confirm dialog (warn + replace) and the toast notice state\r\n//\r\n// The shell consumes a small, stable surface — `editorClipboard`,\r\n// `rowClipboard`, the paste-confirm dialog node, and the toast renderer —\r\n// instead of the dozen interleaved locals it managed previously.\r\n//\r\n// Pure refactor: no behaviour change. The hook reproduces every branch\r\n// from the original inline code (warn vs deny, replace-confirm, telemetry\r\n// payload shape, deferred row-paste timing).\r\n// =============================================================================\r\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\r\nimport type { ParsedRef, RecordSummary, RecordsAdminI18n, EditorContext, RecordSource } from '../types';\r\nimport type { TelemetryEvent } from '../types/telemetry';\r\nimport { useRecordClipboard, checkPasteCompatibility, cloneValue } from './useRecordClipboard';\r\nimport { usePasteConfirm } from './usePasteConfirm';\r\nimport { ClipboardToast } from '../shell/ClipboardToast';\r\n\r\ntype ClipboardNotice = { message: string; variant: 'copy' | 'paste' } | null;\r\n\r\nexport interface ShellClipboardOnCopyArgs<T> {\r\n value: T;\r\n scope: ParsedRef;\r\n}\r\nexport interface ShellClipboardOnPasteSource<T> {\r\n value: T;\r\n sourceScope: ParsedRef;\r\n}\r\nexport interface ShellClipboardOnPasteDest<T> {\r\n scope: ParsedRef;\r\n currentValue: T | null;\r\n}\r\n\r\nexport interface UseShellClipboardArgs<TData> {\r\n enabled: boolean;\r\n appId: string;\r\n recordType: string | undefined;\r\n i18n: RecordsAdminI18n;\r\n /** Editor context for the active record. */\r\n editorCtx: EditorContext<TData>;\r\n /** Anchors describing what's being edited right now. */\r\n editingScope: ParsedRef | null;\r\n /** Friendly label for toasts and the replace-confirm body. */\r\n editorHeaderLabel: string | undefined;\r\n /** Identity of the currently-selected item in collection cardinality. */\r\n isCollection: boolean;\r\n selectedItemId: string | null;\r\n selectedRecordId: string | null;\r\n /** Resolver state — only `source` and `recordId` are read. */\r\n resolved: { source: RecordSource; recordId?: string };\r\n /** Telemetry sink. */\r\n onTelemetry?: (event: TelemetryEvent) => void;\r\n /** Optional host transforms. */\r\n onCopyOverride?: (args: ShellClipboardOnCopyArgs<TData>) => TData;\r\n onPasteOverride?: (\r\n source: ShellClipboardOnPasteSource<TData>,\r\n dest: ShellClipboardOnPasteDest<TData>,\r\n ) => TData | null;\r\n /**\r\n * Imperative hook the rail will fire when the deferred row-paste\r\n * resolves. The shell owns rail selection; this hook only schedules the\r\n * paste once `editingScope` catches up.\r\n */\r\n onLeftSelectRef: React.MutableRefObject<((item: RecordSummary) => void) | null>;\r\n}\r\n\r\nexport interface ShellEditorClipboard {\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\r\nexport interface ShellRowClipboard {\r\n onCopy?: () => void;\r\n onPaste: () => void;\r\n canPaste: boolean;\r\n pasteWillReplace: boolean;\r\n clipboardSourceLabel?: string;\r\n}\r\n\r\nexport interface UseShellClipboardReturn<TData> {\r\n /** Wired into RecordEditor's `clipboard` slot. */\r\n editorClipboard: ShellEditorClipboard | undefined;\r\n /** Per-row factory for the rail context menu. */\r\n rowClipboard: ((record: RecordSummary) => ShellRowClipboard) | undefined;\r\n /** Render-once dialog for warn/replace confirms. */\r\n confirmDialog: ReactNode;\r\n /** Toast node (or null when nothing to show). */\r\n toast: ReactNode;\r\n /** Underlying store, exposed for advanced callers (rare). */\r\n store: ReturnType<typeof useRecordClipboard<TData>>;\r\n}\r\n\r\nexport function useShellClipboard<TData>(\r\n args: UseShellClipboardArgs<TData>,\r\n): UseShellClipboardReturn<TData> {\r\n const {\r\n enabled, appId, recordType, i18n,\r\n editorCtx, editingScope, editorHeaderLabel,\r\n isCollection, selectedItemId, selectedRecordId,\r\n resolved, onTelemetry,\r\n onCopyOverride, onPasteOverride,\r\n onLeftSelectRef,\r\n } = args;\r\n\r\n const clipboard = useRecordClipboard<TData>({\r\n appId,\r\n recordType: recordType ?? '__default',\r\n });\r\n const pasteConfirm = usePasteConfirm();\r\n const [notice, setNotice] = useState<ClipboardNotice>(null);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Editor-level copy\r\n // ---------------------------------------------------------------------------\r\n const copyCurrent = useCallback(() => {\r\n if (!enabled || !editingScope) return;\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,\r\n sourceRecordId: resolved.recordId,\r\n sourceLabel: editorHeaderLabel,\r\n });\r\n onTelemetry?.({ type: 'clipboard.copy', recordType, sourceRef: editingScope.raw });\r\n setNotice({\r\n message: i18n.copyToast.replace('{name}', editorHeaderLabel ?? editingScope.raw),\r\n variant: 'copy',\r\n });\r\n }, [\r\n enabled, editingScope, onCopyOverride, editorCtx.value, clipboard,\r\n editorHeaderLabel, onTelemetry, recordType, i18n.copyToast, resolved.recordId,\r\n ]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Editor-level paste (warn + replace dialogs)\r\n // ---------------------------------------------------------------------------\r\n const pasteCurrent = useCallback(async () => {\r\n if (!enabled || !editingScope || !clipboard.entry) return;\r\n\r\n const compat = checkPasteCompatibility(clipboard.entry.sourceScope, editingScope);\r\n\r\n if (compat.status === 'denied') {\r\n setNotice({ message: compat.reason ?? 'Paste not allowed here', variant: 'paste' });\r\n return;\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 = clipboard.entry.sourceScope;\r\n const transformed = onPasteOverride\r\n ? onPasteOverride(\r\n { value: clipboard.entry.value as TData, sourceScope: sourceParsed },\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 editorCtx.onChange(transformed);\r\n onTelemetry?.({\r\n type: 'clipboard.paste',\r\n recordType,\r\n sourceRef: clipboard.entry.sourceScope.raw,\r\n destinationRef: editingScope.raw,\r\n replaced: willReplace,\r\n });\r\n setNotice({\r\n message: i18n.pasteToast.replace('{name}', clipboard.entry.sourceLabel ?? clipboard.entry.sourceScope.raw),\r\n variant: 'paste',\r\n });\r\n }, [\r\n enabled, 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 // ---------------------------------------------------------------------------\r\n // Compat check for the editor's own paste affordance.\r\n // ---------------------------------------------------------------------------\r\n const editorPasteCompat = useMemo(() => {\r\n if (!enabled || !clipboard.entry || !editingScope) return null;\r\n const sameRecord = clipboard.entry.sourceRecordId\r\n && resolved.recordId\r\n && clipboard.entry.sourceRecordId === resolved.recordId;\r\n const sameAnchor = !clipboard.entry.sourceRecordId\r\n && clipboard.entry.sourceScope.raw === editingScope.raw;\r\n if (sameRecord || sameAnchor) return { status: 'denied' as const };\r\n return checkPasteCompatibility(clipboard.entry.sourceScope, editingScope);\r\n }, [enabled, clipboard.entry, editingScope, resolved.recordId]);\r\n\r\n const editorClipboard: ShellEditorClipboard | undefined = enabled && 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 // Deferred row-paste — fires once selection ripples through.\r\n // ---------------------------------------------------------------------------\r\n const [pendingPasteTarget, setPendingPasteTarget] = useState<\r\n { kind: 'record'; recordId: string } | { kind: 'anchor'; ref: string } | null\r\n >(null);\r\n\r\n useEffect(() => {\r\n if (!pendingPasteTarget) return;\r\n if (!editingScope) return;\r\n const matched = pendingPasteTarget.kind === 'record'\r\n ? (isCollection ? selectedItemId : selectedRecordId) === pendingPasteTarget.recordId\r\n : editingScope.raw === pendingPasteTarget.ref;\r\n if (!matched) return;\r\n const t = window.setTimeout(() => {\r\n setPendingPasteTarget(null);\r\n void pasteCurrent();\r\n }, 0);\r\n return () => window.clearTimeout(t);\r\n }, [pendingPasteTarget, editingScope, isCollection, selectedItemId, selectedRecordId, pasteCurrent]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Per-row clipboard wiring for the rail context menu.\r\n // ---------------------------------------------------------------------------\r\n const rowClipboard = enabled ? (record: RecordSummary): ShellRowClipboard => {\r\n const summaryHasData = record.data != null;\r\n const sourceParsed: ParsedRef = record.scope;\r\n const compat = clipboard.entry\r\n ? checkPasteCompatibility(clipboard.entry.sourceScope, sourceParsed)\r\n : null;\r\n const sameTarget = clipboard.entry\r\n ? (clipboard.entry.sourceRecordId && record.id\r\n ? clipboard.entry.sourceRecordId === record.id\r\n : clipboard.entry.sourceScope.raw === record.ref)\r\n : false;\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,\r\n sourceRecordId: record.id ?? undefined,\r\n sourceLabel: record.label,\r\n });\r\n onTelemetry?.({ type: 'clipboard.copy', recordType, sourceRef: record.ref });\r\n setNotice({\r\n message: i18n.copyToast.replace('{name}', record.label),\r\n variant: 'copy',\r\n });\r\n } : undefined,\r\n onPaste: () => {\r\n onLeftSelectRef.current?.(record);\r\n setPendingPasteTarget(\r\n record.id\r\n ? { kind: 'record', recordId: record.id }\r\n : { kind: 'anchor', ref: record.ref },\r\n );\r\n },\r\n canPaste: !!clipboard.entry && !sameTarget && (compat?.status !== 'denied'),\r\n pasteWillReplace: record.status === 'configured',\r\n clipboardSourceLabel: clipboard.entry?.sourceLabel,\r\n };\r\n } : undefined;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Render helpers — dialog must mount, toast renders when present.\r\n // ---------------------------------------------------------------------------\r\n const toast = notice ? (\r\n <ClipboardToast\r\n message={notice.message}\r\n variant={notice.variant}\r\n onDismiss={() => setNotice(null)}\r\n />\r\n ) : null;\r\n\r\n return {\r\n editorClipboard,\r\n rowClipboard,\r\n confirmDialog: pasteConfirm.dialog,\r\n toast,\r\n store: clipboard,\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 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--sl-control-focus-ring)/0.45)]',\r\n active ? 'font-semibold' : 'hover:bg-[hsl(var(--sl-control-hover-bg)/0.08)]',\r\n )}\r\n style={{\r\n background: active\r\n ? 'hsl(var(--sl-control-active-bg))'\r\n : 'hsl(var(--sl-control-bg))',\r\n borderColor: active\r\n ? 'hsl(var(--sl-control-active-bd))'\r\n : 'hsl(var(--sl-control-border))',\r\n color: active\r\n ? 'hsl(var(--sl-control-active-fg))'\r\n : 'hsl(var(--sl-control-fg))',\r\n }}\r\n >\r\n {o.label}\r\n <span\r\n className=\"ml-1.5\"\r\n style={{ opacity: active ? 0.85 : 0.6 }}\r\n >\r\n {o.count}\r\n </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, hasError, 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 i18n = ctx.i18n ?? DEFAULT_I18N;\r\n const subtitle = record.subtitle ?? (isRuleRecord ? null : ruleSummary) ?? (tone === 'missing'\r\n ? i18n.subtitleEmpty\r\n : tone === 'own' ? i18n.subtitleConfigured : i18n.subtitleInherited);\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 {hasError ? (\r\n <span\r\n title=\"Save failed\"\r\n aria-label=\"Save failed\"\r\n className=\"ra-error-pip\"\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 type { RecordsAdminI18n } from '../types/i18n';\r\nimport { DefaultRecordRow } from './DefaultRecordRow';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\n\r\ninterface Props {\r\n items: RecordSummary[];\r\n /**\r\n * UUID of the currently-selected row. Matches `RecordSummary.id`. Records\r\n * without an `id` (synthesised product/facet rows that don't yet have a\r\n * server-side record) can never be the selection target — those tabs key\r\n * highlighting off product/facet anchors via `selectedAnchorKey` instead.\r\n */\r\n selectedId?: string;\r\n /**\r\n * Anchor-based highlight fallback for tabs whose rail rows are not backed\r\n * by AppRecords (Products, Facets). Compared against `RecordSummary.ref`\r\n * which for those tabs is a synthesised display-only anchor string.\r\n */\r\n selectedAnchorKey?: string;\r\n onSelect: (item: RecordSummary) => void;\r\n /** UUID of the row currently being edited with unsaved changes. */\r\n dirtyId?: string;\r\n /** Anchor-key equivalent of `dirtyId` for non-record-backed tabs. */\r\n dirtyAnchorKey?: string;\r\n /**\r\n * Optional set of record IDs (or anchor refs) that have unsaved changes\r\n * registered with the shell-level dirty-draft store. Used by the shell to\r\n * paint dirty/error pips on rows the user has edited but isn't currently\r\n * looking at. `dirtyId`/`dirtyAnchorKey` remain for the active editor.\r\n */\r\n dirtyKeys?: ReadonlySet<string>;\r\n /** Subset of `dirtyKeys` whose last save attempt failed. */\r\n errorKeys?: ReadonlySet<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 /** Resolved i18n strings — used by default row/card renderers. */\r\n i18n?: RecordsAdminI18n;\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, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey,\r\n dirtyKeys, errorKeys,\r\n presentation = 'list', renderListRow, groupBy, rowClipboard, i18n,\r\n}: Props) => {\r\n const buildCtx = (item: RecordSummary): RecordSlotContext => {\r\n const cb = rowClipboard ? rowClipboard(item) : null;\r\n const idMatch = selectedId != null && item.id != null && item.id === selectedId;\r\n const anchorMatch = selectedAnchorKey != null && item.ref === selectedAnchorKey;\r\n const dirtyIdMatch = dirtyId != null && item.id != null && item.id === dirtyId;\r\n const dirtyAnchorMatch = dirtyAnchorKey != null && item.ref === dirtyAnchorKey;\r\n const idInStore = !!(item.id && dirtyKeys?.has(item.id));\r\n const refInStore = !!(item.ref && dirtyKeys?.has(item.ref));\r\n const errorInStore = !!(\r\n (item.id && errorKeys?.has(item.id)) ||\r\n (item.ref && errorKeys?.has(item.ref))\r\n );\r\n return {\r\n selected: idMatch || anchorMatch,\r\n onSelect: () => onSelect(item),\r\n isDirty: dirtyIdMatch || dirtyAnchorMatch || idInStore || refInStore,\r\n hasError: errorInStore,\r\n i18n,\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.id ?? 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// FacetBrowseFilter — replaces the legacy \"Shared\" top-level tab (v0.5).\r\n//\r\n// A small chip row that lets admins ask \"show me what would apply if a\r\n// product had facet X = Y\" while staying on the Rules or Global tab. The\r\n// active selection narrows the rail in two ways:\r\n//\r\n// * Rules tab — keep only rules whose `facetRule` would match a product\r\n// carrying the picked facet/value (clause `facetKey` =\r\n// selected key AND `anyOf` includes the selected value).\r\n// * Global tab — singleton mode only: keep records whose pinned scope\r\n// matches the picked facet/value. Collection-mode Global\r\n// is item-list-driven so this control is hidden there.\r\n//\r\n// The chip vocabulary is sourced from `useFacetBrowse` (the same hook the\r\n// old Shared tab used) so admins see every facet value the collection knows\r\n// about, not just ones with existing records. Picking a value emits a\r\n// `{ facetKey, facetValue }` selection; picking it again clears.\r\n//\r\n// Visual: identical to RuleFilterChips so the rail stays calm — one row of\r\n// facet keys, an indented row of values for the open key. Pure presentation;\r\n// the parent shell owns the selection state.\r\n// =============================================================================\r\nimport { useMemo, useState } from 'react';\r\n\r\n/** Collapsed-state cap on the number of facet-key chips rendered before\r\n * the \"Show all (N)\" expand link kicks in. Tuned to fit a typical rail\r\n * width (~280px) without wrapping more than two rows. */\r\nconst COLLAPSED_FACET_CAP = 6;\r\n\r\n/** Single facet vocabulary entry — typically one chip group per facet. */\r\nexport interface FacetBrowseFacet {\r\n key: string;\r\n /** Friendly facet name (e.g. \"Bread Type\"). Falls back to `key`. */\r\n label?: string;\r\n values: { key: string; label?: string }[];\r\n}\r\n\r\nexport interface FacetBrowseSelection {\r\n facetKey: string;\r\n facetValue: string;\r\n}\r\n\r\nexport interface FacetBrowseFilterProps {\r\n /** Full facet vocabulary for the collection. */\r\n facets: FacetBrowseFacet[];\r\n /** Currently-picked facet/value, or null when no filter is applied. */\r\n value: FacetBrowseSelection | null;\r\n onChange: (next: FacetBrowseSelection | null) => void;\r\n /** Optional placeholder shown when the vocabulary is still loading. */\r\n isLoading?: boolean;\r\n /** Override the inline help string. */\r\n helpText?: string;\r\n}\r\n\r\nexport function FacetBrowseFilter({\r\n facets, value, onChange, isLoading = false,\r\n helpText = 'Browse by facet — preview what would apply to a product.',\r\n}: FacetBrowseFilterProps) {\r\n // Which facet group is currently expanded for value selection. Defaults to\r\n // the active selection's facet, then the first non-empty facet. Local state\r\n // so admins can browse without committing to a value.\r\n const firstUsable = useMemo(\r\n () => facets.find((f) => f.values?.length)?.key,\r\n [facets],\r\n );\r\n const [openKey, setOpenKey] = useState<string | null>(value?.facetKey ?? firstUsable ?? null);\r\n /** Collapse the facet-keys row to ~6 entries by default — long\r\n * vocabularies otherwise dominate the rail. The currently-selected\r\n * facet (if any) is always kept visible so the active filter chip\r\n * never disappears behind the \"Show all\" link. */\r\n const [allExpanded, setAllExpanded] = useState(false);\r\n\r\n // Sync open group to the selection when it changes externally.\r\n const effectiveOpen = value?.facetKey ?? openKey ?? firstUsable ?? null;\r\n\r\n if (isLoading) {\r\n return (\r\n <div className=\"ra-rule-filters\" aria-busy=\"true\">\r\n <div className=\"ra-rule-filters-row\">\r\n <span className=\"ra-rule-filter-chip\" data-active=\"false\">Loading facets…</span>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!facets.length) return null;\r\n\r\n const openFacet = facets.find((f) => f.key === effectiveOpen) ?? null;\r\n\r\n // Decide which facet-key chips to render. When collapsed we cap the\r\n // visible set but always keep the active selection in view.\r\n const overflow = facets.length - COLLAPSED_FACET_CAP;\r\n let visibleFacets = facets;\r\n if (!allExpanded && overflow > 0) {\r\n const head = facets.slice(0, COLLAPSED_FACET_CAP);\r\n const activeFacet = value\r\n ? facets.find((f) => f.key === value.facetKey)\r\n : null;\r\n visibleFacets = activeFacet && !head.includes(activeFacet)\r\n ? [...head.slice(0, COLLAPSED_FACET_CAP - 1), activeFacet]\r\n : head;\r\n }\r\n\r\n return (\r\n <div className=\"ra-rule-filters\" role=\"group\" aria-label=\"Browse by facet\">\r\n <div className=\"ra-rule-filters-row\">\r\n {visibleFacets.map((f) => {\r\n const active = effectiveOpen === f.key;\r\n const isFiltered = value?.facetKey === f.key;\r\n return (\r\n <button\r\n key={f.key}\r\n type=\"button\"\r\n className=\"ra-rule-filter-chip\"\r\n data-active={isFiltered ? 'true' : 'false'}\r\n aria-pressed={active}\r\n onClick={() => {\r\n if (isFiltered) {\r\n // Clicking the active filter group clears the selection.\r\n onChange(null);\r\n return;\r\n }\r\n setOpenKey(f.key);\r\n }}\r\n title={`Browse ${f.label ?? f.key} values`}\r\n >\r\n <span className=\"ra-rule-filter-chip-label\">{f.label ?? f.key}</span>\r\n <span className=\"ra-rule-filter-chip-count\">{f.values.length}</span>\r\n </button>\r\n );\r\n })}\r\n {overflow > 0 && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setAllExpanded((v) => !v)}\r\n className=\"ra-rule-filter-chip\"\r\n data-active=\"false\"\r\n aria-expanded={allExpanded}\r\n title={allExpanded ? 'Show fewer facets' : `Show all ${facets.length} facets`}\r\n >\r\n <span className=\"ra-rule-filter-chip-label\">\r\n {allExpanded ? 'Show fewer' : `Show all (${facets.length})`}\r\n </span>\r\n </button>\r\n )}\r\n </div>\r\n {openFacet && openFacet.values.length > 0 && (\r\n <div\r\n className=\"ra-rule-filters-row\"\r\n role=\"group\"\r\n aria-label={`Pick a ${openFacet.label ?? openFacet.key} value`}\r\n style={{ paddingLeft: '0.25rem' }}\r\n >\r\n {openFacet.values.map((v) => {\r\n const active = value?.facetKey === openFacet.key && value?.facetValue === v.key;\r\n return (\r\n <button\r\n key={v.key}\r\n type=\"button\"\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 onClick={() => onChange(active ? null : { facetKey: openFacet.key, facetValue: v.key })}\r\n title={`Filter to ${openFacet.label ?? openFacet.key} = ${v.label ?? v.key}`}\r\n >\r\n <span className=\"ra-rule-filter-chip-label\">{v.label ?? v.key}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n )}\r\n {value && (\r\n <button\r\n type=\"button\"\r\n onClick={() => onChange(null)}\r\n className=\"ra-rule-filter-clear\"\r\n aria-label=\"Clear facet filter\"\r\n >\r\n Clear facet filter\r\n </button>\r\n )}\r\n {!value && (\r\n <span className=\"ra-rule-filter-clear\" style={{ cursor: 'default', textDecoration: 'none' }}>\r\n {helpText}\r\n </span>\r\n )}\r\n </div>\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 overflow-hidden border\"\r\n style={{\r\n borderColor: 'hsl(var(--sl-control-border))',\r\n background: 'hsl(var(--sl-control-bg))',\r\n borderRadius: 'var(--sl-control-radius)',\r\n }}\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 'focus-visible:outline-none focus-visible:ring-2',\r\n active\r\n ? 'bg-[hsl(var(--sl-control-active-bg))] text-[hsl(var(--sl-control-active-fg))]'\r\n : 'text-[hsl(var(--sl-control-fg))] hover:bg-[hsl(var(--sl-control-hover-bg)/0.10)] hover:text-[hsl(var(--sl-control-hover-fg))]',\r\n 'focus-visible:ring-[hsl(var(--sl-control-focus-ring)/0.45)]',\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 just\r\n// records whose anchors equal the current scope's anchors and which are not\r\n// rule-targeted. Each record is individually addressable by its UUID id —\r\n// we no longer mint synthetic `.../item:{itemId}` refs to identify them.\r\n//\r\n// Backed by `SL.app.records.list`. We page through results and filter by\r\n// anchor equality client-side; for typical scopes this stays cheap because\r\n// list responses are already scoped by app/recordType. The hook keeps the\r\n// result shape aligned with `RecordSummary` so it slots straight into the\r\n// 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, FacetRule } from '../data/sdkTypes';\r\nimport { parseRef } 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` (we then keep records with no anchors). Pass `null` to keep\r\n * the query disabled.\r\n */\r\n scope: ParsedRef | null;\r\n /**\r\n * When the scope is a rule (kind === 'rule'), pass the rule's `facetRule`\r\n * here. Items belonging to a rule are records that carry the *same*\r\n * facetRule — they share anchors only by coincidence (typically empty),\r\n * so anchor equality alone isn't enough to identify them. When this is\r\n * provided we match rule records by facetRule equality and ignore\r\n * anchors. When absent, anchor-based matching applies (and rule records\r\n * are skipped, since they belong on the Rules tab).\r\n */\r\n facetRule?: FacetRule | 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\n/** Stable JSON for deep-comparing two facetRules. Sorts clauses by facetKey\r\n * and the per-clause `anyOf` values so authoring order doesn't break\r\n * equality. */\r\nconst canonicalFacetRule = (rule: FacetRule | null | undefined): string => {\r\n if (!rule || !Array.isArray(rule.all)) return '';\r\n const clauses = rule.all\r\n .map((c) => ({\r\n facetKey: c.facetKey,\r\n anyOf: [...(c.anyOf ?? [])].sort(),\r\n }))\r\n .sort((a, b) => a.facetKey.localeCompare(b.facetKey));\r\n return JSON.stringify(clauses);\r\n};\r\n\r\nconst defaultToSummary = (rec: AppRecord, base: RecordSummary): RecordSummary => {\r\n const data = rec.data as Record<string, unknown> | null | undefined;\r\n const display = (data?.display as Record<string, unknown> | undefined) ?? 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 (display?.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 (data.slug 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 (display?.description 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 (data.home_image_url as string | undefined) ??\r\n base.thumbnail;\r\n return { ...base, label, subtitle, thumbnail };\r\n};\r\n\r\n/** A record \"belongs to\" a scope when:\r\n * - the scope is a rule (`scope.kind === 'rule'`) and the record's\r\n * `facetRule` matches the supplied rule, **or**\r\n * - the scope is anchor-based and the record's anchors match exactly\r\n * (rule records are skipped because they live on the Rules tab).\r\n */\r\nconst recordMatchesScope = (\r\n rec: AppRecord,\r\n scope: ParsedRef,\r\n ruleSignature: string,\r\n): boolean => {\r\n const facetRule = (rec as { facetRule?: FacetRule | null }).facetRule ?? null;\r\n if (scope.kind === 'rule') {\r\n if (!facetRule) return false;\r\n if (!ruleSignature) return false; // wizard / draft — no items yet\r\n return canonicalFacetRule(facetRule) === ruleSignature;\r\n }\r\n if (facetRule) return false;\r\n return (rec.productId ?? undefined) === scope.productId\r\n && (rec.variantId ?? undefined) === scope.variantId\r\n && (rec.batchId ?? undefined) === scope.batchId\r\n && (rec.proofId ?? undefined) === scope.proofId;\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, facetRule, pageSize = 100, toSummary = defaultToSummary, enabled = true,\r\n } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const scopeRef = scope?.raw ?? '';\r\n const ruleSignature = useMemo(\r\n () => (scope?.kind === 'rule' ? canonicalFacetRule(facetRule) : ''),\r\n [scope?.kind, facetRule],\r\n );\r\n\r\n const queryKey = useMemo(\r\n () => [...QK_BASE, ctx.collectionId, ctx.appId, ctx.recordType, scopeRef, ruleSignature],\r\n [ctx.collectionId, ctx.appId, ctx.recordType, scopeRef, ruleSignature],\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 });\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 if (!scope) return [];\r\n const all = query.data?.pages.flatMap((p) => p.data) ?? [];\r\n const relevant = all.filter((rec) => recordMatchesScope(rec, scope, ruleSignature));\r\n return relevant\r\n .map((rec): RecordSummary<T> | null => {\r\n const ref = rec.ref ?? '';\r\n const parsed = parseRef(ref);\r\n // Item identity is the record's UUID — stable, server-assigned, and\r\n // sufficient for selection/URL purposes. We deliberately no longer\r\n // require a synthetic `item:{slug}` segment in the ref.\r\n const stableItemId = rec.id;\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: stableItemId,\r\n updatedAt: rec.updatedAt,\r\n itemId: stableItemId,\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, scope, ruleSignature]);\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 recordId: params.get(paramNames.recordId),\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 ('recordId' in partial) apply(paramNames.recordId, partial.recordId);\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// PostMessage DeepLinkAdapter — for SmartLinks iframe hosts.\r\n//\r\n// The shell runs inside an iframe owned by the SmartLinks parent platform.\r\n// The platform expects route updates as a `smartlinks-route-change`\r\n// `postMessage` (matching the SDK `IframeResponder` protocol) — it owns the\r\n// browser address bar, history stack, and back/forward buttons. The iframe\r\n// must NOT touch its own `window.history`: doing so just confuses the host.\r\n//\r\n// This adapter therefore:\r\n// - reads the current state from `window.location` (so direct loads of a\r\n// pre-populated URL still hydrate correctly),\r\n// - writes by `postMessage`-ing to `window.parent` — never to history,\r\n// - subscribes to `popstate` / `hashchange` so back/forward initiated by\r\n// the parent (which it relays back into the iframe) still wakes the\r\n// shell.\r\n//\r\n// Param mapping into the SmartLinks message envelope:\r\n// - The shell-owned keys (`recordId`, `scope`, `view`) are sent under\r\n// `state` — they're per-app deep-link state, not platform context.\r\n// - `path` is the current hash route (or pathname for browser routers),\r\n// left untouched. We never invent a path from shell state.\r\n// - `appId` is forwarded if present in the URL so the parent can route\r\n// the message to the right app instance.\r\n// =============================================================================\r\nimport type {\r\n DeepLinkAdapter, DeepLinkState, ResolvedDeepLinkParamNames,\r\n} from '../types/deepLink';\r\n\r\n/** Reserved SmartLinks platform keys — surfaced under `context` in the message. */\r\nconst CONTEXT_KEYS = [\r\n 'dark', 'appId', 'collectionId', 'productId', 'proofId', 'lang', 'theme',\r\n] as const;\r\n\r\nconst findQueryString = (loc: Location): string => {\r\n if (loc.search && loc.search.length > 1) {\r\n return loc.search.startsWith('?') ? loc.search.slice(1) : loc.search;\r\n }\r\n if (loc.hash && loc.hash.includes('?')) {\r\n return loc.hash.slice(loc.hash.indexOf('?') + 1);\r\n }\r\n return '';\r\n};\r\n\r\nconst findPath = (loc: Location): string => {\r\n // Hash routers (`/#/admin?x=y`) — the path the parent cares about lives\r\n // in the hash. Strip the query, keep the leading `/`.\r\n if (loc.hash && loc.hash.startsWith('#')) {\r\n const hash = loc.hash.slice(1);\r\n const qIdx = hash.indexOf('?');\r\n const hashPath = qIdx >= 0 ? hash.slice(0, qIdx) : hash;\r\n if (hashPath) return hashPath;\r\n }\r\n return loc.pathname || '/';\r\n};\r\n\r\n/**\r\n * Detect whether the current window is an iframe with a usable parent.\r\n * Returns false during SSR or when sandboxed in a way that hides `parent`.\r\n */\r\nexport const isInSmartLinksIframe = (): boolean => {\r\n if (typeof window === 'undefined') return false;\r\n try {\r\n return window.parent != null && window.parent !== window;\r\n } catch {\r\n // Cross-origin access errors mean we ARE in an iframe — the throw is\r\n // diagnostic, not disqualifying.\r\n return true;\r\n }\r\n};\r\n\r\n/**\r\n * Build a `postMessage`-driven adapter that mirrors the shell's deep-link\r\n * state into the parent platform. The parent's `IframeResponder` listens\r\n * for `smartlinks-route-change` messages and updates its own URL.\r\n */\r\nexport const createPostMessageDeepLinkAdapter = (\r\n paramNames: ResolvedDeepLinkParamNames,\r\n): DeepLinkAdapter => {\r\n // Track the last shell-owned values we emitted so subsequent writes can\r\n // merge instead of clobbering (the parent may not echo state back).\r\n const lastShellState: DeepLinkState = {};\r\n\r\n const post = (path: string) => {\r\n if (typeof window === 'undefined') return;\r\n const params = new URLSearchParams(findQueryString(window.location));\r\n\r\n const context: Record<string, string> = {};\r\n const state: Record<string, string> = {};\r\n\r\n params.forEach((value, key) => {\r\n if (key === 'theme') return; // Too large for sync (matches host hook).\r\n if ((CONTEXT_KEYS as readonly string[]).includes(key)) context[key] = value;\r\n else state[key] = value;\r\n });\r\n\r\n // Overlay the latest shell-owned values — these are the source of truth\r\n // for record/scope/view, regardless of what's currently in the URL.\r\n const overlay = (key: keyof DeepLinkState, paramKey: string) => {\r\n const v = lastShellState[key];\r\n if (v == null || v === '') delete state[paramKey];\r\n else state[paramKey] = v;\r\n };\r\n overlay('recordId', paramNames.recordId);\r\n overlay('scope', paramNames.scope);\r\n overlay('view', paramNames.view);\r\n\r\n try {\r\n const message = {\r\n type: 'smartlinks-route-change',\r\n path,\r\n context,\r\n state,\r\n appId: context.appId,\r\n };\r\n // eslint-disable-next-line no-console\r\n console.debug('[smartlinks-ui] postMessage → parent', message, {\r\n sameWindow: window.parent === window,\r\n });\r\n window.parent.postMessage(message, '*');\r\n } catch {\r\n // Cross-origin parent that refuses messages — nothing we can do, and\r\n // throwing here would break the shell. Silently drop.\r\n }\r\n };\r\n\r\n return {\r\n read(): DeepLinkState {\r\n if (typeof window === 'undefined') return {};\r\n const params = new URLSearchParams(findQueryString(window.location));\r\n return {\r\n recordId: params.get(paramNames.recordId),\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 is ignored — parent owns history semantics */) {\r\n if (typeof window === 'undefined') return;\r\n if ('recordId' in partial) lastShellState.recordId = partial.recordId ?? null;\r\n if ('scope' in partial) lastShellState.scope = partial.scope ?? null;\r\n if ('view' in partial) lastShellState.view = partial.view ?? null;\r\n post(findPath(window.location));\r\n },\r\n\r\n subscribe(listener) {\r\n if (typeof window === 'undefined') return () => {};\r\n // The parent relays back/forward by updating the iframe URL — so the\r\n // same browser events apply.\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};","// =============================================================================\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\nimport {\r\n createPostMessageDeepLinkAdapter, isInSmartLinksIframe,\r\n} from '../data/postMessageDeepLinkAdapter';\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 | 'record.open' // user opened a different record (push)\r\n | 'record.close' // user backed out to the list (push)\r\n | 'record.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[] = ['record.open', 'record.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 // When the shell is mounted inside a SmartLinks iframe the parent\r\n // platform owns the address bar — speak its protocol via postMessage\r\n // instead of writing to our own `window.history` (which the parent\r\n // ignores and which never surfaces to the user-visible URL).\r\n const inIframe = isInSmartLinksIframe();\r\n // eslint-disable-next-line no-console\r\n console.debug('[smartlinks-ui] deep-link adapter selected', {\r\n adapter: inIframe ? 'postMessage' : 'default',\r\n inIframe,\r\n href: typeof window !== 'undefined' ? window.location.href : '(ssr)',\r\n });\r\n defaultAdapterRef.current = inIframe\r\n ? createPostMessageDeepLinkAdapter(paramNames)\r\n : 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 // We previously surfaced a \"Customised\" / \"Inherited\" badge in a\r\n // dedicated row beneath the title, alongside an \"UNSAVED\" pill. Both\r\n // caused the editor body to push down on first keystroke (and again\r\n // when \"Inherited\" appeared on scope change), and the \"UNSAVED\" signal\r\n // duplicated the shell-level UnsavedTray + the footer Save button.\r\n // We now show only \"Inherited\" — inline in the header's right cluster\r\n // — so the editor never reflows on edit. The shell tray + footer carry\r\n // the unsaved-changes affordance.\r\n const showInherited = ctx.source === 'inherited';\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 </div>\r\n <div className=\"flex items-start gap-2 shrink-0\">\r\n {showInherited && (\r\n <span\r\n className=\"inline-flex items-center gap-1 text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded mt-0.5\"\r\n style={{\r\n color: 'hsl(var(--ra-muted-text))',\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=\"This record is inherited from a parent scope\"\r\n >\r\n <StatusDot source={ctx.source} />\r\n Inherited\r\n </span>\r\n )}\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// 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 // SDK 1.10.2 reshaped `PreviewRuleResult`:\r\n // `totalMatches` → `total`\r\n // `sampleProductIds: string[]` → `matchingProducts: [{ productId, name?, facets }]`\r\n // We project back to the legacy hook shape so consumers don't break.\r\n return {\r\n totalMatches: query.data?.total ?? null,\r\n sampleProductIds: (query.data?.matchingProducts ?? []).map((p) => p.productId),\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// 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 cardSize?: 'sm' | 'md' | 'lg';\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, cardSize = 'md', i18n,\r\n}: Props<T>) {\r\n const isGallery = variant === 'gallery';\r\n return (\r\n <div\r\n className={isGallery ? 'ra-item-gallery' : 'ra-item-cards'}\r\n data-card-size={cardSize}\r\n >\r\n {items.map((item) => {\r\n const id = item.itemId ?? '';\r\n const open = () => ctx.onOpen(id);\r\n const slotCtx: ItemSlotContext = {\r\n ...ctx,\r\n selected: selectedId === id,\r\n onSelect: open,\r\n };\r\n if (renderCard) {\r\n return (\r\n <div\r\n key={item.ref}\r\n onClick={open}\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={open}\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 /** Card density for cards/gallery views. */\r\n cardSize?: 'sm' | 'md' | 'lg';\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 cardSize = 'md',\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 cardSize={cardSize}\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 /**\r\n * Set of keys (recordIds + scope refs) currently dirty in the shell-level\r\n * draft store. Used to paint a per-row pip on items the user has edited\r\n * but isn't currently looking at — mirrors the affordance the scope rail\r\n * gets via `RecordList.dirtyKeys`.\r\n */\r\n dirtyKeys?: ReadonlySet<string>;\r\n /** Subset of `dirtyKeys` whose last save attempt failed. */\r\n errorKeys?: ReadonlySet<string>;\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,\r\n dirtyKeys, errorKeys, 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 const isDirty = !!(\r\n (id && dirtyKeys?.has(id)) ||\r\n (item.ref && dirtyKeys?.has(item.ref))\r\n );\r\n const hasError = !!(\r\n (id && errorKeys?.has(id)) ||\r\n (item.ref && errorKeys?.has(item.ref))\r\n );\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 {hasError ? (\r\n <span\r\n className=\"ra-error-pip\"\r\n title=\"Save failed\"\r\n aria-label=\"Save failed\"\r\n />\r\n ) : isDirty ? (\r\n <span\r\n className=\"ra-dirty-pip\"\r\n title=\"Unsaved changes\"\r\n aria-label=\"Unsaved changes\"\r\n />\r\n ) : null}\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","import styleInject from '#style-inject';styleInject(\".sl-aph {\\n width: 100%;\\n font-family: var(--ra-font-ui, ui-sans-serif, system-ui, -apple-system, \\\"Segoe UI\\\", Roboto, sans-serif);\\n color: hsl(var(--ra-text, 222 47% 11%));\\n display: flex;\\n flex-direction: column;\\n gap: 0.5rem;\\n}\\n.sl-aph *,\\n.sl-aph *::before,\\n.sl-aph *::after {\\n box-sizing: border-box;\\n}\\n.sl-aph__row {\\n position: relative;\\n display: flex;\\n align-items: flex-start;\\n gap: 0.6rem;\\n padding: 0.25rem 0.25rem 0.5rem;\\n}\\n.sl-aph__main {\\n flex: 1;\\n min-width: 0;\\n display: flex;\\n align-items: flex-start;\\n gap: 0.55rem;\\n}\\n.sl-aph__aside {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n flex-shrink: 0;\\n}\\n.sl-aph__text {\\n flex: 1;\\n min-width: 0;\\n}\\n.sl-aph__title {\\n font-family: var(--ra-font-display, var(--ra-font-ui, ui-sans-serif, system-ui, sans-serif));\\n font-weight: 700;\\n font-size: 1.2rem;\\n line-height: 1.2;\\n color: hsl(var(--ra-text, 222 47% 11%));\\n letter-spacing: -0.015em;\\n margin: 0;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.5rem;\\n}\\n.sl-aph__icon {\\n flex-shrink: 0;\\n display: inline-flex;\\n align-items: center;\\n justify-content: flex-start;\\n background: transparent;\\n color: hsl(var(--ra-text, 222 47% 11%));\\n border: 0;\\n padding: 0;\\n}\\n.sl-aph__icon > svg {\\n width: 1.05rem;\\n height: 1.05rem;\\n}\\n.sl-aph__subtitle {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-muted-text, 220 9% 46%));\\n margin: 0.1rem 0 0;\\n line-height: 1.3;\\n}\\n.sl-aph__icon-btn {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 2rem;\\n height: 2rem;\\n padding: 0;\\n border-radius: 999px;\\n background: transparent;\\n border: 1px solid transparent;\\n color: hsl(var(--ra-muted-text, 220 9% 46%));\\n cursor: pointer;\\n transition:\\n background .15s ease,\\n color .15s ease,\\n border-color .15s ease;\\n text-decoration: none;\\n}\\n.sl-aph__icon-btn:hover {\\n background: hsl(var(--ra-text, 222 47% 11%) / 0.06);\\n color: hsl(var(--ra-text, 222 47% 11%));\\n}\\n.sl-aph__icon-btn:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px var(--ra-focus-ring, hsl(222 47% 11% / 0.35));\\n}\\n.sl-aph__icon-btn > svg {\\n width: 1rem;\\n height: 1rem;\\n}\\n.sl-aph__intro {\\n position: relative;\\n display: flex;\\n align-items: center;\\n gap: 0.55rem;\\n padding: 0.4rem 2rem 0.4rem 0.5rem;\\n border-radius: var(--ra-radius, 0.625rem);\\n border: 1px solid hsl(var(--ra-info, 214 95% 55%) / 0.30);\\n background: hsl(var(--ra-info, 214 95% 55%) / 0.08);\\n}\\n.sl-aph__intro[data-tone=success] {\\n border-color: hsl(var(--ra-success, 142 71% 45%) / 0.30);\\n background: hsl(var(--ra-success, 142 71% 45%) / 0.08);\\n}\\n.sl-aph__intro[data-tone=warning] {\\n border-color: hsl(var(--ra-warning, 38 92% 50%) / 0.35);\\n background: hsl(var(--ra-warning, 38 92% 50%) / 0.10);\\n}\\n.sl-aph__intro-icon {\\n flex-shrink: 0;\\n width: 1.5rem;\\n height: 1.5rem;\\n border-radius: 999px;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n background: hsl(var(--ra-info, 214 95% 55%) / 0.18);\\n color: hsl(var(--ra-info, 214 95% 55%));\\n}\\n.sl-aph__intro[data-tone=success] .sl-aph__intro-icon {\\n background: hsl(var(--ra-success, 142 71% 45%) / 0.18);\\n color: hsl(var(--ra-success, 142 71% 45%));\\n}\\n.sl-aph__intro[data-tone=warning] .sl-aph__intro-icon {\\n background: hsl(var(--ra-warning, 38 92% 50%) / 0.20);\\n color: hsl(var(--ra-warning, 38 92% 50%));\\n}\\n.sl-aph__intro-body {\\n flex: 1;\\n min-width: 0;\\n}\\n.sl-aph__intro-title {\\n font-family: var(--ra-font-display, var(--ra-font-ui, ui-sans-serif, system-ui, sans-serif));\\n font-weight: var(--ra-title-weight, 600);\\n font-size: 0.8rem;\\n color: hsl(var(--ra-text, 222 47% 11%));\\n margin: 0;\\n line-height: 1.2;\\n display: inline;\\n}\\n.sl-aph__intro-text {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-text, 222 47% 11%) / 0.85);\\n line-height: 1.35;\\n display: inline;\\n margin-left: 0.4rem;\\n}\\n.sl-aph__intro-action {\\n margin-left: 0.375rem;\\n}\\n.sl-aph__intro-dismiss {\\n position: absolute;\\n top: 50%;\\n right: 0.35rem;\\n transform: translateY(-50%);\\n width: 1.4rem;\\n height: 1.4rem;\\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, 220 9% 46%));\\n cursor: pointer;\\n padding: 0;\\n}\\n.sl-aph__intro-dismiss:hover {\\n background: hsl(var(--ra-text, 222 47% 11%) / 0.06);\\n color: hsl(var(--ra-text, 222 47% 11%));\\n}\\n\")","// =============================================================================\r\n// AdminPageHeader\r\n//\r\n// A standardised page header for any SmartLinks admin surface. Designed to be\r\n// used standalone (lightweight apps that don't need the full RecordsAdminShell)\r\n// or composed inside other shells. Supports:\r\n//\r\n// • Inline icon + title + full-width subtitle\r\n// • Right-aligned slot for app-specific actions (e.g. \"+ New\" button)\r\n// • External help link (icon-button that opens docs in a new tab)\r\n// • Optional dismissible intro card with `?` reopen affordance\r\n// • Optional `aside` slot for extra header content (stats strips, etc.)\r\n//\r\n// Styling is self-contained under `.sl-aph` and reuses the shared `--ra-*`\r\n// design tokens with sensible fallbacks, so it themes correctly whether the\r\n// host has loaded the records-admin token sheet or not.\r\n// =============================================================================\r\nimport { type ReactNode, useId } from 'react';\r\nimport { BookOpen, HelpCircle, X, Lightbulb, CheckCircle2, AlertTriangle, Info } from 'lucide-react';\r\nimport './admin-page-header.css';\r\n\r\nexport type AdminPageHeaderIntroTone = 'info' | 'success' | 'warning';\r\n\r\nexport interface AdminPageHeaderIntro {\r\n /** Short headline shown in bold at the start of the intro card. */\r\n title: string;\r\n /** Body content — plain text or rich nodes. */\r\n body: ReactNode;\r\n /** Visual tone — controls icon and surface tint. Default `'info'`. */\r\n tone?: AdminPageHeaderIntroTone;\r\n /** Optional action node rendered inline after the body (e.g. a Learn-more link). */\r\n action?: ReactNode;\r\n /** Whether the intro is currently dismissed. Controlled. */\r\n dismissed: boolean;\r\n /** Called when the user clicks the dismiss `X`. */\r\n onDismiss: () => void;\r\n /**\r\n * Called when the user clicks the reopen `?` button (only rendered when\r\n * dismissed is true). Omit to hide the reopen affordance entirely.\r\n */\r\n onReopen?: () => void;\r\n /** Tooltip / aria-label for the reopen button. Default \"How it works\". */\r\n reopenLabel?: string;\r\n}\r\n\r\nexport interface AdminPageHeaderProps {\r\n /** Page title — required. */\r\n title: string;\r\n /** Single-line muted subtitle under the title. */\r\n subtitle?: string;\r\n /** Icon rendered inline before the title. Pass a Lucide element or any node. */\r\n icon?: ReactNode;\r\n /**\r\n * External help / documentation URL. When set, renders a small icon-button\r\n * that opens the URL in a new tab. Use this to point at app-specific docs.\r\n */\r\n helpUrl?: string;\r\n /** Tooltip / aria-label for the help link. Default \"Help & documentation\". */\r\n helpLabel?: string;\r\n /**\r\n * Right-aligned action slot — typically a primary \"+ New\" button and/or\r\n * secondary controls. Rendered before the help / intro-reopen icon-buttons.\r\n */\r\n actions?: ReactNode;\r\n /**\r\n * Extra header content rendered between `actions` and the trailing\r\n * help / reopen icon-buttons. Used by RecordsAdminShell for its stats strip;\r\n * standalone apps rarely need it.\r\n */\r\n aside?: ReactNode;\r\n /**\r\n * Optional dismissible intro card rendered below the header row.\r\n * See {@link AdminPageHeaderIntro}.\r\n */\r\n intro?: AdminPageHeaderIntro;\r\n /** Extra class on the root container for layout overrides. */\r\n className?: string;\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 function AdminPageHeader({\r\n title, subtitle, icon, helpUrl, helpLabel,\r\n actions, aside, intro, className,\r\n}: AdminPageHeaderProps) {\r\n const titleId = useId();\r\n const resolvedHelpLabel = helpLabel ?? 'Help & documentation';\r\n const resolvedReopenLabel = intro?.reopenLabel ?? 'How it works';\r\n const showReopen = !!intro && intro.dismissed && !!intro.onReopen;\r\n const showIntro = !!intro && !intro.dismissed;\r\n\r\n return (\r\n <header className={`sl-aph${className ? ` ${className}` : ''}`} aria-labelledby={titleId}>\r\n <div className=\"sl-aph__row\">\r\n <div className=\"sl-aph__main\">\r\n <div className=\"sl-aph__text\">\r\n <h1 className=\"sl-aph__title\" id={titleId}>\r\n {icon ? (\r\n <span className=\"sl-aph__icon\" aria-hidden=\"true\">{icon}</span>\r\n ) : null}\r\n <span>{title}</span>\r\n </h1>\r\n {subtitle ? <p className=\"sl-aph__subtitle\">{subtitle}</p> : null}\r\n </div>\r\n </div>\r\n {(actions || aside || helpUrl || showReopen) ? (\r\n <div className=\"sl-aph__aside\">\r\n {actions}\r\n {aside}\r\n {helpUrl ? (\r\n <a\r\n href={helpUrl}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"sl-aph__icon-btn\"\r\n aria-label={resolvedHelpLabel}\r\n title={resolvedHelpLabel}\r\n >\r\n <BookOpen aria-hidden=\"true\" />\r\n </a>\r\n ) : null}\r\n {showReopen ? (\r\n <button\r\n type=\"button\"\r\n onClick={intro!.onReopen}\r\n className=\"sl-aph__icon-btn\"\r\n aria-label={resolvedReopenLabel}\r\n title={resolvedReopenLabel}\r\n >\r\n <HelpCircle aria-hidden=\"true\" />\r\n </button>\r\n ) : null}\r\n </div>\r\n ) : null}\r\n </div>\r\n {showIntro ? <AdminPageHeaderIntroCard intro={intro!} /> : null}\r\n </header>\r\n );\r\n}\r\n\r\nfunction AdminPageHeaderIntroCard({ intro }: { intro: AdminPageHeaderIntro }) {\r\n const tone = intro.tone ?? 'info';\r\n const Icon = TONE_ICON[tone] ?? Info;\r\n return (\r\n <div className=\"sl-aph__intro\" data-tone={tone} role=\"note\">\r\n <div className=\"sl-aph__intro-icon\">\r\n <Icon aria-hidden=\"true\" style={{ width: '0.95rem', height: '0.95rem' }} />\r\n </div>\r\n <div className=\"sl-aph__intro-body\">\r\n <h4 className=\"sl-aph__intro-title\">{intro.title}</h4>\r\n <span className=\"sl-aph__intro-text\">{intro.body}</span>\r\n {intro.action ? <span className=\"sl-aph__intro-action\">{intro.action}</span> : null}\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={intro.onDismiss}\r\n aria-label=\"Dismiss\"\r\n className=\"sl-aph__intro-dismiss\"\r\n >\r\n <X aria-hidden=\"true\" style={{ width: '0.875rem', height: '0.875rem' }} />\r\n </button>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// RecordsAdmin — ShellHeader (v0.5)\r\n//\r\n// Thin adapter that resolves the contextual icon + stats strip and delegates\r\n// the actual header chrome to the standalone `<AdminPageHeader>` so the shell\r\n// and any other admin app share one implementation.\r\n// =============================================================================\r\nimport { createElement, type ReactNode } from 'react';\r\nimport { pickHeaderIcon, type RecordsAdminIcons } from './icons';\r\nimport { AdminPageHeader, type AdminPageHeaderIntro } from '../../AdminPageHeader';\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 /** External help / docs URL (rendered as an icon-button to the right). */\r\n helpUrl?: string;\r\n /** Tooltip / aria-label for the help link. */\r\n helpLabel?: string;\r\n /**\r\n * Optional intro card config — when provided, AdminPageHeader renders the\r\n * dismissible intro and the `?` reopen affordance for us.\r\n */\r\n intro?: AdminPageHeaderIntro;\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 helpUrl, helpLabel, intro,\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 const statsNode = 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\r\n return (\r\n <div className=\"ra-header\">\r\n <AdminPageHeader\r\n title={title}\r\n subtitle={subtitle}\r\n icon={iconNode}\r\n actions={headerActions}\r\n aside={statsNode}\r\n helpUrl={helpUrl}\r\n helpLabel={helpLabel}\r\n intro={intro}\r\n />\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// NewRuleWizard\r\n//\r\n// Two-step inline wizard rendered in the editor pane when the admin clicks\r\n// \"+ New rule\". Replaces the old behaviour of dropping straight into the\r\n// editor (which, in collection cardinality mode, surfaced the existing items\r\n// at the collection root and confused users).\r\n//\r\n// Step 1 — Configure rule\r\n// Renders the standard <FacetRuleEditor> + a live \"matches N products\"\r\n// preview chip. Cancel / Next buttons. Next is disabled until the rule\r\n// has at least one clause and every clause has values.\r\n//\r\n// Step 2 — Configure record (host-driven)\r\n// The shell takes over: it mounts the normal editor with `initialFacetRule`\r\n// pre-seeded, OR (collection cardinality) shows the empty item list with a\r\n// primary \"Create your first item\" CTA. This component renders only a\r\n// compact step header (Back · Cancel) above whatever the shell hands in\r\n// via the `children` slot.\r\n//\r\n// Persistence: the rule itself is NOT persisted on Next. It rides into the\r\n// SDK on the first record save under it (carried as the record's facetRule).\r\n// =============================================================================\r\nimport { type ReactNode } from 'react';\r\nimport { ArrowLeft, ArrowRight, X } from 'lucide-react';\r\nimport type { SmartLinksSDK } from '../types';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport { FacetRuleEditor } from '../../FacetRuleEditor/FacetRuleEditor';\r\nimport { useRulePreview, isFacetRuleValid } from '../hooks/useRulePreview';\r\n\r\nexport interface NewRuleWizardProps {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n step: 1 | 2;\r\n rule: FacetRule | null;\r\n onRuleChange: (next: FacetRule | null) => void;\r\n onCancel: () => void;\r\n onNext: () => void;\r\n onBack: () => void;\r\n /**\r\n * Step 2 body — typically the normal record editor (singleton mode) or the\r\n * empty-state with a \"+ Create your first item\" CTA (collection mode).\r\n * The wizard owns only the step chrome above this.\r\n */\r\n children?: ReactNode;\r\n /** Display label for the record type (e.g. \"recipe\", \"discount\"). */\r\n itemNoun?: string;\r\n}\r\n\r\nexport function NewRuleWizard({\r\n SL, collectionId, appId, step, rule, onRuleChange,\r\n onCancel, onNext, onBack, children, itemNoun = 'record',\r\n}: NewRuleWizardProps) {\r\n const preview = useRulePreview({ SL, collectionId, appId, rule });\r\n const canProceed = isFacetRuleValid(rule);\r\n\r\n if (step === 1) {\r\n return (\r\n <div className=\"flex h-full flex-col overflow-hidden\">\r\n <WizardStepHeader\r\n step={1}\r\n totalSteps={2}\r\n title=\"Configure rule\"\r\n description=\"Pick the facet conditions that decide which products this rule applies to.\"\r\n onCancel={onCancel}\r\n />\r\n <div className=\"flex-1 min-h-0 overflow-auto px-5 py-4\">\r\n <FacetRuleEditor\r\n value={rule}\r\n onChange={onRuleChange}\r\n collectionId={collectionId}\r\n preview={preview}\r\n description=\"The new rule will apply to every product whose facets match every clause below.\"\r\n />\r\n </div>\r\n <WizardFooter\r\n left={\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n >\r\n Cancel\r\n </button>\r\n }\r\n right={\r\n <button\r\n type=\"button\"\r\n onClick={onNext}\r\n disabled={!canProceed}\r\n className=\"ra-btn\"\r\n data-variant=\"primary\"\r\n >\r\n <span>Next</span>\r\n <ArrowRight aria-hidden=\"true\" className=\"w-4 h-4\" />\r\n </button>\r\n }\r\n hint={\r\n !canProceed\r\n ? 'Add at least one facet clause with values to continue.'\r\n : preview.totalMatches != null\r\n ? `${preview.totalMatches} product${preview.totalMatches === 1 ? '' : 's'} currently match this rule.`\r\n : undefined\r\n }\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n // Step 2 — host-driven body, wizard only renders the step header.\r\n return (\r\n <div className=\"flex h-full flex-col overflow-hidden\">\r\n <WizardStepHeader\r\n step={2}\r\n totalSteps={2}\r\n title={`Configure ${itemNoun}`}\r\n description={\r\n preview.totalMatches != null\r\n ? `This rule currently matches ${preview.totalMatches} product${preview.totalMatches === 1 ? '' : 's'}.`\r\n : 'Fill in the details for this rule.'\r\n }\r\n onCancel={onCancel}\r\n onBack={onBack}\r\n />\r\n <div className=\"flex-1 min-h-0 overflow-hidden\">{children}</div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction WizardStepHeader({\r\n step, totalSteps, title, description, onCancel, onBack,\r\n}: {\r\n step: number;\r\n totalSteps: number;\r\n title: string;\r\n description?: string;\r\n onCancel: () => void;\r\n onBack?: () => void;\r\n}) {\r\n return (\r\n <div\r\n className=\"flex items-start gap-3 px-5 py-3 border-b\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-muted) / 0.4)' }}\r\n >\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 mb-0.5\">\r\n <span\r\n className=\"text-[10px] font-semibold uppercase tracking-wider px-1.5 py-0.5 rounded\"\r\n style={{\r\n color: 'hsl(var(--ra-accent))',\r\n background: 'hsl(var(--ra-accent) / 0.12)',\r\n }}\r\n >\r\n Step {step} of {totalSteps}\r\n </span>\r\n <h2\r\n className=\"text-sm font-semibold m-0\"\r\n style={{ color: 'hsl(var(--ra-text))' }}\r\n >\r\n {title}\r\n </h2>\r\n </div>\r\n {description ? (\r\n <p\r\n className=\"text-xs m-0\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n {description}\r\n </p>\r\n ) : null}\r\n </div>\r\n <div className=\"flex items-center gap-1.5 shrink-0\">\r\n {onBack ? (\r\n <button\r\n type=\"button\"\r\n onClick={onBack}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n aria-label=\"Back to rule\"\r\n >\r\n <ArrowLeft aria-hidden=\"true\" className=\"w-4 h-4\" />\r\n <span>Back</span>\r\n </button>\r\n ) : null}\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n aria-label=\"Cancel new rule\"\r\n title=\"Cancel\"\r\n style={{ width: '2rem', height: '2rem', padding: 0, justifyContent: 'center' }}\r\n >\r\n <X aria-hidden=\"true\" className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction WizardFooter({\r\n left, right, hint,\r\n}: {\r\n left?: ReactNode;\r\n right?: ReactNode;\r\n hint?: string;\r\n}) {\r\n return (\r\n <div\r\n className=\"flex items-center gap-3 px-5 py-3 border-t\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}\r\n >\r\n <div className=\"flex items-center gap-2\">{left}</div>\r\n {hint ? (\r\n <span\r\n className=\"text-xs flex-1 min-w-0 truncate\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n {hint}\r\n </span>\r\n ) : <div className=\"flex-1\" />}\r\n <div className=\"flex items-center gap-2 shrink-0\">{right}</div>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// UnsavedTray — shell-level pill replacing the per-record UnsavedBanner\r\n// when more than one record has unsaved changes. Collapses to a familiar\r\n// single-record banner when only one draft is in flight.\r\n//\r\n// Renders:\r\n// ● 5 records have unsaved changes [Save all] [Discard all]\r\n// ⚠ 2 errors [Jump to error]\r\n//\r\n// Consumes the new editor-session DirtyOverview shape (post-2a refactor).\r\n// =============================================================================\r\nimport { useState, useRef, useEffect, type ComponentType } from 'react';\r\nimport { AlertCircle, Save, Undo2, ChevronDown } from 'lucide-react';\r\nimport type { DirtyOverviewItem, EditorStatus } from '../editor-session/types';\r\n\r\ntype IconCmp = ComponentType<{ className?: string }>;\r\n\r\nexport interface UnsavedTrayProps {\r\n items: DirtyOverviewItem[];\r\n isSaving?: boolean;\r\n onSaveAll: () => void;\r\n onDiscardAll: () => void;\r\n onOpenItem?: (item: DirtyOverviewItem) => void;\r\n onJumpToError?: () => void;\r\n saveLabel: string;\r\n discardLabel: string;\r\n saveAllLabel: string;\r\n discardAllLabel: string;\r\n countTemplate: string; // \"{n} records have unsaved changes\"\r\n errorCountTemplate: string; // \"{n} errors\"\r\n jumpToErrorLabel: string;\r\n SaveIcon?: IconCmp;\r\n DiscardIcon?: IconCmp;\r\n}\r\n\r\nconst statusDot = (status: EditorStatus): string => {\r\n switch (status) {\r\n case 'saving': return 'hsl(var(--ra-accent))';\r\n case 'saved': return 'hsl(var(--ra-success, 142 71% 45%))';\r\n case 'error': return 'hsl(var(--ra-danger, 0 72% 51%))';\r\n case 'dirty':\r\n default: return 'hsl(var(--ra-warning, 38 92% 50%))';\r\n }\r\n};\r\n\r\nexport const UnsavedTray = ({\r\n items, isSaving, onSaveAll, onDiscardAll, onOpenItem, onJumpToError,\r\n saveLabel, discardLabel, saveAllLabel, discardAllLabel,\r\n countTemplate, errorCountTemplate, jumpToErrorLabel,\r\n SaveIcon, DiscardIcon,\r\n}: UnsavedTrayProps) => {\r\n const [open, setOpen] = useState(false);\r\n const wrapRef = useRef<HTMLDivElement | null>(null);\r\n const SI: IconCmp = SaveIcon ?? Save;\r\n const DI: IconCmp = DiscardIcon ?? Undo2;\r\n\r\n const total = items.length;\r\n const errors = items.filter((i) => i.status === 'error').length;\r\n const isSingle = total === 1;\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n const onDoc = (e: MouseEvent) => {\r\n if (!wrapRef.current?.contains(e.target as Node)) setOpen(false);\r\n };\r\n window.addEventListener('mousedown', onDoc);\r\n return () => window.removeEventListener('mousedown', onDoc);\r\n }, [open]);\r\n\r\n if (total === 0) return null;\r\n\r\n const countLabel = isSingle\r\n ? (items[0].label || 'this record')\r\n : countTemplate.replace('{n}', String(total));\r\n\r\n return (\r\n <div\r\n ref={wrapRef}\r\n className=\"ra-unsaved-tray\"\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n onClick={(e) => e.stopPropagation()}\r\n onMouseDown={(e) => e.stopPropagation()}\r\n onTouchStart={(e) => e.stopPropagation()}\r\n >\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\r\n {isSingle ? (\r\n <span className=\"ra-unsaved-text\">\r\n Unsaved changes on <strong>{countLabel}</strong>\r\n </span>\r\n ) : (\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-count\"\r\n onClick={() => setOpen((v) => !v)}\r\n aria-expanded={open}\r\n >\r\n {countLabel}\r\n <ChevronDown className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n\r\n {errors > 0 && (\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-error-chip\"\r\n onClick={() => onJumpToError?.()}\r\n title={jumpToErrorLabel}\r\n >\r\n ⚠ {errorCountTemplate.replace('{n}', String(errors))}\r\n </button>\r\n )}\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={onDiscardAll}\r\n disabled={isSaving}\r\n >\r\n <DI className=\"w-3 h-3\" />\r\n {isSingle ? discardLabel : discardAllLabel}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-primary\"\r\n onClick={onSaveAll}\r\n disabled={isSaving}\r\n >\r\n <SI className=\"w-3 h-3\" />\r\n {isSingle ? saveLabel : saveAllLabel}\r\n </button>\r\n </div>\r\n\r\n {open && !isSingle && (\r\n <div className=\"ra-unsaved-popover\" role=\"menu\">\r\n {items.map((it) => (\r\n <button\r\n type=\"button\"\r\n key={it.editorId}\r\n className=\"ra-unsaved-popover-row\"\r\n onClick={() => { setOpen(false); onOpenItem?.(it); }}\r\n role=\"menuitem\"\r\n >\r\n <span\r\n className=\"ra-unsaved-popover-dot\"\r\n style={{ background: statusDot(it.status) }}\r\n aria-hidden=\"true\"\r\n />\r\n <span className=\"ra-unsaved-popover-label\">{it.label || 'Default'}</span>\r\n {it.status === 'error' && (\r\n <span className=\"ra-unsaved-popover-err\">failed</span>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// HeaderUnsavedPill — compact unsaved-changes control surface designed to\r\n// live inside AdminPageHeader's right-aligned `actions` slot.\r\n//\r\n// Behaviour:\r\n// - 1 dirty record: just the Save + Discard buttons (no label).\r\n// - 2-4 dirty records: \"{n} unsaved\" label + Save all + Discard.\r\n// - 5+ dirty records OR any errors: returns null so the shell falls back\r\n// to the full-width UnsavedTray banner.\r\n//\r\n// Consumes the new editor-session DirtyOverview shape (post-2a refactor).\r\n// =============================================================================\r\nimport { type ComponentType } from 'react';\r\nimport { AlertCircle, Save, Undo2 } from 'lucide-react';\r\nimport type { DirtyOverviewItem } from '../editor-session/types';\r\n\r\ntype IconCmp = ComponentType<{ className?: string }>;\r\n\r\nexport interface HeaderUnsavedPillProps {\r\n items: DirtyOverviewItem[];\r\n isSaving?: boolean;\r\n onSaveAll: () => void;\r\n onDiscardAll: () => void;\r\n saveLabel: string;\r\n discardLabel: string;\r\n saveAllLabel: string;\r\n discardAllLabel: string;\r\n /** Template like \"{n} unsaved\" — `{n}` is replaced with the count. */\r\n countTemplate: string;\r\n SaveIcon?: IconCmp;\r\n DiscardIcon?: IconCmp;\r\n}\r\n\r\n/** Threshold past which the shell falls back to the full banner. */\r\nexport const HEADER_PILL_OVERFLOW_THRESHOLD = 5;\r\n\r\n/** True when the pill can render the dirty state inline; false → use tray. */\r\nexport function canRenderInHeader(items: DirtyOverviewItem[]): boolean {\r\n if (items.length === 0) return false;\r\n if (items.length >= HEADER_PILL_OVERFLOW_THRESHOLD) return false;\r\n if (items.some((i) => i.status === 'error')) return false;\r\n return true;\r\n}\r\n\r\nexport const HeaderUnsavedPill = ({\r\n items, isSaving,\r\n onSaveAll, onDiscardAll,\r\n saveLabel, discardLabel, saveAllLabel, discardAllLabel,\r\n countTemplate, SaveIcon, DiscardIcon,\r\n}: HeaderUnsavedPillProps) => {\r\n const SI: IconCmp = SaveIcon ?? Save;\r\n const DI: IconCmp = DiscardIcon ?? Undo2;\r\n\r\n if (items.length === 0) return null;\r\n const total = items.length;\r\n const isSingle = total === 1;\r\n\r\n return (\r\n <div\r\n className=\"ra-unsaved-pill\"\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n onClick={(e) => e.stopPropagation()}\r\n onMouseDown={(e) => e.stopPropagation()}\r\n onTouchStart={(e) => e.stopPropagation()}\r\n >\r\n {!isSingle && (\r\n <>\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-pill-text\">\r\n {countTemplate.replace('{n}', String(total))}\r\n </span>\r\n </>\r\n )}\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-ghost\"\r\n onClick={onDiscardAll}\r\n disabled={isSaving}\r\n >\r\n <DI className=\"w-3 h-3\" />\r\n {isSingle ? discardLabel : discardAllLabel}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-primary\"\r\n onClick={onSaveAll}\r\n disabled={isSaving}\r\n >\r\n <SI className=\"w-3 h-3\" />\r\n {isSingle ? saveLabel : saveAllLabel}\r\n </button>\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// SaveAllProgress — modal overlay shown while a \"Save all\" pass is running.\r\n//\r\n// Uses an injected `saveOne(editorId)` callback (provided by the shell from\r\n// the EditorStore) and reads live status via the items list which the\r\n// caller refreshes from useDirtyOverview.\r\n// =============================================================================\r\nimport { useEffect, useMemo, useRef, useState } from 'react';\r\nimport { CheckCircle2, Loader2, XCircle, Circle } from 'lucide-react';\r\nimport type { DirtyOverviewItem } from '../editor-session/types';\r\n\r\nexport interface SaveAllProgressProps {\r\n open: boolean;\r\n /** Live list of dirty/saving/errored items (typically from useDirtyOverview). */\r\n items: DirtyOverviewItem[];\r\n /** Persist a single editor by id. Resolves on success, throws on failure. */\r\n saveOne: (editorId: string) => Promise<void>;\r\n onClose: () => void;\r\n onJumpToError?: (item: DirtyOverviewItem) => void;\r\n i18n: {\r\n title: string; // \"Saving {n} records…\"\r\n successTitle: string; // \"Saved {n} records\"\r\n errorTitle: string; // \"Saved with errors\"\r\n stop: string;\r\n close: string;\r\n retryFailed: string;\r\n jumpToError: string;\r\n };\r\n}\r\n\r\nexport const SaveAllProgress = ({\r\n open, items, saveOne, onClose, onJumpToError, i18n,\r\n}: SaveAllProgressProps) => {\r\n const [running, setRunning] = useState(false);\r\n const [done, setDone] = useState(false);\r\n const stopRef = useRef(false);\r\n // Snapshot the editorIds at run start so the visible row list is stable\r\n // even though the underlying overview will change as saves progress.\r\n const [batchIds, setBatchIds] = useState<string[]>([]);\r\n\r\n useEffect(() => {\r\n if (!open) {\r\n setRunning(false);\r\n setDone(false);\r\n stopRef.current = false;\r\n setBatchIds([]);\r\n return;\r\n }\r\n const initial = items.map((i) => i.editorId);\r\n setBatchIds(initial);\r\n void runBatch(initial);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [open]);\r\n\r\n const runBatch = async (ids: string[]) => {\r\n setRunning(true);\r\n setDone(false);\r\n stopRef.current = false;\r\n for (const id of ids) {\r\n if (stopRef.current) break;\r\n try { await saveOne(id); }\r\n catch { /* status moves to 'error' in the store */ }\r\n }\r\n setRunning(false);\r\n setDone(true);\r\n };\r\n\r\n // Resolve current items by id so the overlay reflects live status.\r\n const visible = useMemo(() => batchIds.map((id) => {\r\n const live = items.find((i) => i.editorId === id);\r\n return live ?? {\r\n editorId: id, label: '', status: 'saved' as const, scope: { kind: 'collection', raw: '' as string } as DirtyOverviewItem['scope'],\r\n };\r\n }), [batchIds, items]);\r\n\r\n const total = visible.length;\r\n const completed = visible.filter((d) => d.status !== 'dirty' && d.status !== 'saving').length;\r\n const errors = visible.filter((d) => d.status === 'error');\r\n const successAll = done && errors.length === 0 && completed === total;\r\n\r\n useEffect(() => {\r\n if (!successAll) return;\r\n const t = window.setTimeout(() => onClose(), 800);\r\n return () => window.clearTimeout(t);\r\n }, [successAll, onClose]);\r\n\r\n if (!open) return null;\r\n\r\n const title = running\r\n ? i18n.title.replace('{n}', String(total))\r\n : (errors.length > 0\r\n ? i18n.errorTitle\r\n : i18n.successTitle.replace('{n}', String(total)));\r\n\r\n return (\r\n <div\r\n className=\"ra-saveall-overlay\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-label={title}\r\n >\r\n <div\r\n className=\"ra-saveall-card\"\r\n onClick={(e) => e.stopPropagation()}\r\n onMouseDown={(e) => e.stopPropagation()}\r\n onTouchStart={(e) => e.stopPropagation()}\r\n >\r\n <div className=\"ra-saveall-header\">\r\n <div className=\"ra-saveall-title\">{title}</div>\r\n <div className=\"ra-saveall-progress\" aria-hidden=\"true\">\r\n <div\r\n className=\"ra-saveall-progress-bar\"\r\n style={{ width: `${total ? (completed / total) * 100 : 0}%` }}\r\n />\r\n </div>\r\n <div className=\"ra-saveall-counter\">\r\n {completed} / {total}\r\n </div>\r\n </div>\r\n\r\n <ul className=\"ra-saveall-list\">\r\n {visible.map((d) => (\r\n <li key={d.editorId} className=\"ra-saveall-row\" data-status={d.status}>\r\n <span className=\"ra-saveall-icon\" aria-hidden=\"true\">\r\n {d.status === 'saving' && <Loader2 className=\"w-4 h-4 ra-spin\" />}\r\n {d.status === 'saved' && <CheckCircle2 className=\"w-4 h-4\" />}\r\n {d.status === 'error' && <XCircle className=\"w-4 h-4\" />}\r\n {(d.status === 'dirty') && <Circle className=\"w-4 h-4\" />}\r\n </span>\r\n <span className=\"ra-saveall-label\">{d.label || 'Default'}</span>\r\n {d.status === 'error' && (\r\n <span className=\"ra-saveall-err\" title={String((d.error as Error)?.message ?? d.error ?? '')}>\r\n {(d.error as Error)?.message ?? 'Save failed'}\r\n </span>\r\n )}\r\n </li>\r\n ))}\r\n </ul>\r\n\r\n <div className=\"ra-saveall-actions\">\r\n {running && (\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-ghost\"\r\n onClick={() => { stopRef.current = true; }}\r\n >\r\n {i18n.stop}\r\n </button>\r\n )}\r\n {!running && errors.length > 0 && (\r\n <>\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-ghost\"\r\n onClick={() => { onJumpToError?.(errors[0]); onClose(); }}\r\n >\r\n {i18n.jumpToError}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-primary\"\r\n onClick={() => void runBatch(errors.map((e) => e.editorId))}\r\n >\r\n {i18n.retryFailed}\r\n </button>\r\n </>\r\n )}\r\n {!running && (\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-ghost\"\r\n onClick={onClose}\r\n >\r\n {i18n.close}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// editor-session/editorStore.ts\r\n//\r\n// Single source of truth for every open editor session. Replaces the\r\n// distributed state that used to live across:\r\n// - useRecordEditor local React state (value, baseline, facetRule)\r\n// - useDirtyDraftStore (drafts keyed by inferred identity)\r\n// - the react-query resolver cache (optimistic pre-writes)\r\n//\r\n// The store is pure TypeScript (no React) and exposes a small subscribe-\r\n// snapshot API that React consumers wire into via useSyncExternalStore.\r\n//\r\n// Identity rules:\r\n// * editorId is opaque, minted by SelectionController, stable for the\r\n// lifetime of the entry. Once minted it never moves.\r\n// * findExistingEditorIdFor(spec) decides whether a new selection should\r\n// focus an existing entry instead of minting a new one. This is the\r\n// ONLY place identity is inferred from a target spec, and it runs\r\n// once per selection (not on every render).\r\n// =============================================================================\r\nimport { parsedRefToScope } from '../data/scopeBridge';\r\nimport {\r\n upsertRecord, updateRecord, removeRecord, createRecord,\r\n type RecordsCtx,\r\n} from '../data/records';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport type { ResolvedRecord } from '../types';\r\nimport type {\r\n EditorEntry, EditorId, EditorSaveSpec, EditorStatus, EditorTargetSpec,\r\n} from './types';\r\n\r\ntype Listener = () => void;\r\n\r\nconst isEqual = (a: unknown, b: unknown): boolean => {\r\n if (a === b) return true;\r\n try { return JSON.stringify(a) === JSON.stringify(b); }\r\n catch { return false; }\r\n};\r\n\r\nconst cloneDeep = <T,>(v: T): T => {\r\n if (v == null) return v;\r\n try { return structuredClone(v); }\r\n catch { return JSON.parse(JSON.stringify(v)) as T; }\r\n};\r\n\r\nconst TITLE_KEYS = ['title', 'name', 'label', 'heading', 'question', 'slug'] as const;\r\nconst TITLE_WRAPPERS = ['display', 'content', 'meta', 'data'] as const;\r\n\r\n/** Default label heuristic — matches legacy deriveDraftLabel so the tray\r\n * and sidebar continue to agree on row titles. */\r\nexport const deriveDefaultLabel = (value: unknown, spec: EditorTargetSpec): string => {\r\n const pickString = (obj: Record<string, unknown> | null | undefined): string | undefined => {\r\n if (!obj || typeof obj !== 'object') return undefined;\r\n for (const key of TITLE_KEYS) {\r\n const raw = obj[key];\r\n if (typeof raw === 'string' && raw.trim()) return raw.trim();\r\n }\r\n return undefined;\r\n };\r\n const v = value as Record<string, unknown> | null | undefined;\r\n const top = pickString(v);\r\n if (top) return top;\r\n if (v && typeof v === 'object') {\r\n for (const wrapper of TITLE_WRAPPERS) {\r\n const nested = pickString(v[wrapper] as Record<string, unknown> | undefined);\r\n if (nested) return nested;\r\n }\r\n }\r\n if (spec.scope.raw?.startsWith('item:')) return 'Untitled item';\r\n if (spec.scope.kind === 'rule') return 'Rule';\r\n if (spec.scope.kind && spec.scope.kind !== 'collection') {\r\n return spec.scope.kind.charAt(0).toUpperCase() + spec.scope.kind.slice(1);\r\n }\r\n return 'Default';\r\n};\r\n\r\nexport interface EditorStoreOpenInput {\r\n spec: EditorTargetSpec;\r\n saveSpec: EditorSaveSpec;\r\n seed: {\r\n value: unknown;\r\n facetRule: FacetRule | null;\r\n source: ResolvedRecord<unknown>['source'];\r\n parentValue: unknown;\r\n recordId?: string;\r\n } | null;\r\n defaultValue: unknown;\r\n editorId?: EditorId;\r\n label?: string;\r\n}\r\n\r\nexport interface EditorStore {\r\n list(): EditorEntry[];\r\n get(editorId: EditorId): EditorEntry | undefined;\r\n /** Find an alive entry that already represents `spec`. Used by\r\n * SelectionController to focus instead of minting a duplicate. */\r\n findExistingEditorIdFor(spec: EditorTargetSpec): EditorId | undefined;\r\n\r\n open(input: EditorStoreOpenInput): EditorId;\r\n close(editorId: EditorId): boolean;\r\n clearUnpinned(): void;\r\n\r\n setValue(editorId: EditorId, next: unknown | ((prev: unknown) => unknown)): void;\r\n setFacetRule(editorId: EditorId, next: FacetRule | null): void;\r\n\r\n /** Seed value/baseline from a fresh resolver result. No-op once the\r\n * editor has been touched — the store owns the value from then on. */\r\n hydrateFromResolver(editorId: EditorId, resolved: ResolvedRecord<unknown>): void;\r\n\r\n markMounted(editorId: EditorId): void;\r\n markActive(editorId: EditorId): void;\r\n\r\n save(editorId: EditorId): Promise<void>;\r\n reset(editorId: EditorId): void;\r\n remove(editorId: EditorId): Promise<void>;\r\n\r\n /** LRU-evict clean entries until alive count <= max. Pinned entries\r\n * (dirty/saving/error) are never evicted. */\r\n enforcePoolLimit(max: number, exceptEditorId?: EditorId): void;\r\n\r\n subscribe(listener: Listener): () => void;\r\n}\r\n\r\nlet editorIdCounter = 0;\r\nconst mintEditorId = (): EditorId => {\r\n editorIdCounter += 1;\r\n return `ed_${Date.now().toString(36)}_${editorIdCounter.toString(36)}`;\r\n};\r\n\r\nconst recomputePinned = (e: EditorEntry): boolean => {\r\n if (e.status === 'saving' || e.status === 'error') return true;\r\n if (e.status === 'dirty') return true;\r\n return false;\r\n};\r\n\r\nconst recomputeStatus = (e: EditorEntry): EditorStatus => {\r\n if (e.status === 'saving') return 'saving';\r\n if (e.status === 'error') return 'error';\r\n const valueDiff = !isEqual(e.value, e.baseline);\r\n const ruleDiff = !isEqual(e.facetRule, e.baselineFacetRule);\r\n if (valueDiff || ruleDiff) return 'dirty';\r\n return e.status === 'saved' ? 'saved' : 'idle';\r\n};\r\n\r\nexport const createEditorStore = (): EditorStore => {\r\n const map = new Map<EditorId, EditorEntry>();\r\n const listeners = new Set<Listener>();\r\n let cachedList: EditorEntry[] = [];\r\n let nextOrder = 0;\r\n\r\n const recompute = () => {\r\n cachedList = Array.from(map.values()).sort((a, b) => a.order - b.order);\r\n };\r\n const emit = () => {\r\n recompute();\r\n listeners.forEach((l) => l());\r\n };\r\n\r\n const update = (editorId: EditorId, mut: (e: EditorEntry) => EditorEntry | void): boolean => {\r\n const prev = map.get(editorId);\r\n if (!prev) return false;\r\n const draft: EditorEntry = { ...prev };\r\n const result = mut(draft);\r\n const next = (result as EditorEntry | undefined) ?? draft;\r\n next.status = recomputeStatus(next);\r\n next.pinned = recomputePinned(next);\r\n map.set(editorId, next);\r\n emit();\r\n return true;\r\n };\r\n\r\n return {\r\n list: () => cachedList,\r\n get: (editorId) => map.get(editorId),\r\n\r\n findExistingEditorIdFor(spec) {\r\n if (spec.recordId) {\r\n for (const entry of map.values()) {\r\n if (entry.recordId === spec.recordId) return entry.editorId;\r\n }\r\n }\r\n const wantCreate = !!spec.createMode;\r\n for (const entry of map.values()) {\r\n if (entry.recordId) continue;\r\n if (entry.spec.scope.raw !== spec.scope.raw) continue;\r\n if (!!entry.spec.createMode !== wantCreate) continue;\r\n return entry.editorId;\r\n }\r\n return undefined;\r\n },\r\n\r\n open(input) {\r\n const editorId = input.editorId ?? mintEditorId();\r\n if (map.has(editorId)) return editorId;\r\n\r\n const seedValue = input.seed?.value ?? input.defaultValue;\r\n // `spec.initialFacetRule` is an explicit caller intent (e.g. the\r\n // new-rule wizard handing a freshly-configured rule to a brand-new\r\n // draft editor). It must win over whatever the resolver happened to\r\n // surface for the anchor scope — that resolved record is unrelated\r\n // to the draft we're about to open. Falling back to `seed.facetRule`\r\n // covers the legacy resume-existing-record path.\r\n const seedFacetRule =\r\n input.spec.initialFacetRule !== undefined && input.spec.initialFacetRule !== null\r\n ? input.spec.initialFacetRule\r\n : (input.seed?.facetRule ?? null);\r\n const source = input.seed?.source ?? 'empty';\r\n const value = cloneDeep(seedValue);\r\n const baseline = cloneDeep(seedValue);\r\n const entry: EditorEntry = {\r\n editorId,\r\n spec: input.spec,\r\n saveSpec: input.saveSpec,\r\n value,\r\n baseline,\r\n facetRule: seedFacetRule,\r\n baselineFacetRule: seedFacetRule,\r\n status: 'idle',\r\n source,\r\n recordId: input.seed?.recordId ?? input.spec.recordId,\r\n parentValue: input.seed?.parentValue ?? null,\r\n label: input.label ?? input.spec.label ?? deriveDefaultLabel(value, input.spec),\r\n order: nextOrder++,\r\n lastActiveAt: Date.now(),\r\n pinned: false,\r\n mounted: false,\r\n };\r\n map.set(editorId, entry);\r\n emit();\r\n return editorId;\r\n },\r\n\r\n close(editorId) {\r\n const entry = map.get(editorId);\r\n if (!entry) return false;\r\n if (entry.pinned) return false;\r\n map.delete(editorId);\r\n emit();\r\n return true;\r\n },\r\n\r\n clearUnpinned() {\r\n let changed = false;\r\n for (const [id, entry] of map.entries()) {\r\n if (!entry.pinned) { map.delete(id); changed = true; }\r\n }\r\n if (changed) emit();\r\n },\r\n\r\n setValue(editorId, next) {\r\n update(editorId, (e) => {\r\n const prev = e.value;\r\n const resolved = typeof next === 'function'\r\n ? (next as (p: unknown) => unknown)(prev)\r\n : next;\r\n e.value = resolved;\r\n if (e.status === 'saved' || e.status === 'error') {\r\n e.status = 'idle';\r\n e.error = undefined;\r\n }\r\n if (!e.spec.label) {\r\n e.label = deriveDefaultLabel(e.value, e.spec);\r\n }\r\n });\r\n },\r\n\r\n setFacetRule(editorId, next) {\r\n update(editorId, (e) => {\r\n e.facetRule = next;\r\n if (e.status === 'saved' || e.status === 'error') {\r\n e.status = 'idle';\r\n e.error = undefined;\r\n }\r\n });\r\n },\r\n\r\n hydrateFromResolver(editorId, resolved) {\r\n const entry = map.get(editorId);\r\n if (!entry) return;\r\n if (entry.status === 'dirty' || entry.status === 'saving' || entry.status === 'error') return;\r\n if (entry.status === 'saved') {\r\n update(editorId, (e) => {\r\n e.source = resolved.source;\r\n if (resolved.recordId) e.recordId = resolved.recordId;\r\n e.parentValue = (resolved.parentValue ?? null) as unknown;\r\n });\r\n return;\r\n }\r\n update(editorId, (e) => {\r\n const fresh = resolved.data == null\r\n ? e.value\r\n : cloneDeep(resolved.data as unknown);\r\n e.value = fresh;\r\n e.baseline = cloneDeep(fresh);\r\n const rule = (resolved as ResolvedRecord<unknown> & { facetRule?: FacetRule | null }).facetRule ?? e.facetRule;\r\n e.facetRule = rule;\r\n e.baselineFacetRule = rule;\r\n e.source = resolved.source;\r\n if (resolved.recordId) e.recordId = resolved.recordId;\r\n e.parentValue = (resolved.parentValue ?? null) as unknown;\r\n if (!e.spec.label) e.label = deriveDefaultLabel(fresh, e.spec);\r\n });\r\n },\r\n\r\n markMounted(editorId) {\r\n update(editorId, (e) => { e.mounted = true; });\r\n },\r\n\r\n markActive(editorId) {\r\n update(editorId, (e) => { e.lastActiveAt = Date.now(); });\r\n },\r\n\r\n async save(editorId) {\r\n const entry = map.get(editorId);\r\n if (!entry) return;\r\n if (entry.status !== 'dirty' && entry.status !== 'error') return;\r\n\r\n const persistedValue = entry.value;\r\n const persistedFacetRule = entry.facetRule;\r\n const { ctx, anchors } = entry.saveSpec;\r\n const spec = entry.spec;\r\n\r\n update(editorId, (e) => { e.status = 'saving'; e.error = undefined; });\r\n\r\n try {\r\n let nextRecordId = entry.recordId;\r\n if (entry.recordId && entry.source === 'self') {\r\n await updateRecord(ctx, entry.recordId, {\r\n data: persistedValue,\r\n facetRule: persistedFacetRule,\r\n });\r\n } else if (spec.createMode) {\r\n const created = await createRecord(ctx, {\r\n ref: spec.scope.kind === 'rule' && spec.scope.raw ? spec.scope.raw : spec.ref,\r\n scope: anchors,\r\n data: persistedValue,\r\n facetRule: persistedFacetRule,\r\n });\r\n nextRecordId = (created as { id?: string } | undefined)?.id ?? nextRecordId;\r\n } else {\r\n const upserted = await upsertRecord(ctx, {\r\n ref: spec.scope.kind === 'rule' && spec.scope.raw ? spec.scope.raw : spec.ref,\r\n scope: anchors,\r\n data: persistedValue,\r\n facetRule: persistedFacetRule,\r\n });\r\n nextRecordId = upserted.record?.id ?? nextRecordId;\r\n }\r\n\r\n update(editorId, (e) => {\r\n // Reset the baseline against whatever the editor currently holds,\r\n // not just the snapshot we sent to the server. Hosts whose editors\r\n // re-fire `onChange` during the in-flight save (e.g. controlled\r\n // form libraries that normalise values on every render) would\r\n // otherwise leave the entry stuck in 'dirty' immediately after a\r\n // successful save: `persistedValue` no longer matches `e.value`,\r\n // so `recomputeStatus` flips status back from 'saved' to 'dirty'\r\n // and the SaveAllProgress dialog never advances past 0/N.\r\n //\r\n // The persisted value is still what's on the server; if the user\r\n // genuinely changed the value mid-save we accept that as the new\r\n // baseline and move on. This matches typical form-library\r\n // behaviour and avoids spurious dirtiness from cosmetic re-renders.\r\n e.baseline = cloneDeep(e.value);\r\n e.baselineFacetRule = e.facetRule;\r\n e.recordId = nextRecordId;\r\n e.source = 'self';\r\n e.status = 'saved';\r\n e.error = undefined;\r\n });\r\n } catch (err) {\r\n update(editorId, (e) => {\r\n e.status = 'error';\r\n e.error = err;\r\n });\r\n throw err;\r\n }\r\n },\r\n\r\n reset(editorId) {\r\n update(editorId, (e) => {\r\n e.value = cloneDeep(e.baseline);\r\n e.facetRule = e.baselineFacetRule;\r\n e.status = 'idle';\r\n e.error = undefined;\r\n });\r\n },\r\n\r\n async remove(editorId) {\r\n const entry = map.get(editorId);\r\n if (!entry) return;\r\n if (entry.source !== 'self') return;\r\n if (!entry.recordId) return;\r\n await removeRecord(entry.saveSpec.ctx, entry.recordId);\r\n map.delete(editorId);\r\n emit();\r\n },\r\n\r\n enforcePoolLimit(max, exceptEditorId) {\r\n const alive = Array.from(map.values());\r\n if (alive.length <= max) return;\r\n const evictable = alive\r\n .filter((e) => !e.pinned && e.editorId !== exceptEditorId)\r\n .sort((a, b) => a.lastActiveAt - b.lastActiveAt);\r\n let toEvict = alive.length - max;\r\n let changed = false;\r\n for (const entry of evictable) {\r\n if (toEvict <= 0) break;\r\n map.delete(entry.editorId);\r\n toEvict -= 1;\r\n changed = true;\r\n }\r\n if (changed) emit();\r\n },\r\n\r\n subscribe(listener) {\r\n listeners.add(listener);\r\n return () => { listeners.delete(listener); };\r\n },\r\n };\r\n};\r\n\r\nexport const buildSaveSpec = (\r\n ctx: RecordsCtx,\r\n spec: EditorTargetSpec,\r\n): EditorSaveSpec => ({\r\n ctx,\r\n anchors: parsedRefToScope(spec.scope),\r\n});\r\n","// =============================================================================\r\n// editor-session/EditorSessionProvider.tsx\r\n//\r\n// React surface over the EditorStore. Exposes:\r\n// * EditorSessionProvider — owns one EditorStore per mount\r\n// * useEditorSession(editorId) — the hook custom editor renderers use\r\n// * useEditorSelection() — selectTarget / current / open list\r\n// * useDirtyOverview() — header pill / tray / save-all\r\n//\r\n// Identity is ALWAYS supplied to consumers via editorId. We never re-derive\r\n// it from (scope, resolved) in this layer — that's the SelectionController's\r\n// job, and it happens once per click.\r\n// =============================================================================\r\nimport {\r\n createContext, useCallback, useContext, useMemo, useRef,\r\n useSyncExternalStore, type ReactNode,\r\n} from 'react';\r\nimport { useQueryClient } from '@tanstack/react-query';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport type { ParsedRef, ResolvedRecord } from '../types';\r\nimport { resolvedRecordQueryKey } from '../hooks/useResolvedRecord';\r\nimport { isFacetRuleValid } from '../hooks/useRulePreview';\r\nimport {\r\n createEditorStore, buildSaveSpec, type EditorStore,\r\n} from './editorStore';\r\nimport type {\r\n DirtyOverview, DirtyOverviewItem, EditorEntry, EditorId, EditorSession,\r\n EditorTargetSpec,\r\n} from './types';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Context shape — internal. Consumers reach for the hooks below.\r\n// ---------------------------------------------------------------------------\r\ninterface EditorSessionContextValue {\r\n store: EditorStore;\r\n ctx: RecordsCtx;\r\n /** Currently active editor (visible one in the mount pool). */\r\n currentEditorId: EditorId | undefined;\r\n setCurrentEditorId: (id: EditorId | undefined) => void;\r\n /** Pool size hint, used by enforcePoolLimit on each select. */\r\n maxOpenEditors: number;\r\n /** Optional default value factory used when seeding a brand-new draft. */\r\n defaultValueFactory?: () => unknown;\r\n}\r\n\r\nconst EditorSessionContext = createContext<EditorSessionContextValue | null>(null);\r\n\r\nconst useEditorSessionContext = (): EditorSessionContextValue => {\r\n const ctx = useContext(EditorSessionContext);\r\n if (!ctx) {\r\n throw new Error(\r\n '[smartlinks-ui] useEditorSession / useEditorSelection / useDirtyOverview must '\r\n + 'be used inside <EditorSessionProvider> (RecordsAdminShell mounts one for you).',\r\n );\r\n }\r\n return ctx;\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Provider\r\n// ---------------------------------------------------------------------------\r\nexport interface EditorSessionProviderProps {\r\n ctx: RecordsCtx;\r\n children: ReactNode;\r\n /** LRU cap on the mount pool. Default 8. Dirty editors are never evicted. */\r\n maxOpenEditors?: number;\r\n /** Factory for seeding brand-new drafts before the resolver responds. */\r\n defaultValueFactory?: () => unknown;\r\n}\r\n\r\nexport const EditorSessionProvider = ({\r\n ctx, children, maxOpenEditors = 8, defaultValueFactory,\r\n}: EditorSessionProviderProps) => {\r\n const storeRef = useRef<EditorStore | null>(null);\r\n if (!storeRef.current) storeRef.current = createEditorStore();\r\n const currentRef = useRef<EditorId | undefined>(undefined);\r\n // Use a tiny external store for currentEditorId so consumers re-render\r\n // when the active editor changes without reaching into React state.\r\n const listenersRef = useRef<Set<() => void>>(new Set());\r\n const subscribeCurrent = useCallback((cb: () => void) => {\r\n listenersRef.current.add(cb);\r\n return () => { listenersRef.current.delete(cb); };\r\n }, []);\r\n const getCurrent = useCallback(() => currentRef.current, []);\r\n const setCurrentEditorId = useCallback((id: EditorId | undefined) => {\r\n if (currentRef.current === id) return;\r\n currentRef.current = id;\r\n listenersRef.current.forEach((l) => l());\r\n }, []);\r\n const currentEditorId = useSyncExternalStore(subscribeCurrent, getCurrent, getCurrent);\r\n\r\n const value = useMemo<EditorSessionContextValue>(() => ({\r\n store: storeRef.current as EditorStore,\r\n ctx,\r\n currentEditorId,\r\n setCurrentEditorId,\r\n maxOpenEditors,\r\n defaultValueFactory,\r\n }), [ctx, currentEditorId, setCurrentEditorId, maxOpenEditors, defaultValueFactory]);\r\n\r\n return (\r\n <EditorSessionContext.Provider value={value}>\r\n {children}\r\n </EditorSessionContext.Provider>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Subscription helpers — keep snapshot identity stable across renders so\r\n// useSyncExternalStore doesn't loop.\r\n// ---------------------------------------------------------------------------\r\nconst useEntry = (editorId: EditorId | undefined): EditorEntry | undefined => {\r\n const { store } = useEditorSessionContext();\r\n const subscribe = useCallback((cb: () => void) => store.subscribe(cb), [store]);\r\n const getSnapshot = useCallback(\r\n () => (editorId ? store.get(editorId) : undefined),\r\n [store, editorId],\r\n );\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n};\r\n\r\nconst useStoreList = (): EditorEntry[] => {\r\n const { store } = useEditorSessionContext();\r\n const subscribe = useCallback((cb: () => void) => store.subscribe(cb), [store]);\r\n const getSnapshot = useCallback(() => store.list(), [store]);\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// useEditorSession — the public hook for custom editor renderers\r\n// ---------------------------------------------------------------------------\r\nexport function useEditorSession<T = unknown>(\r\n editorId: EditorId | undefined,\r\n): EditorSession<T> | null {\r\n const { store, currentEditorId, ctx } = useEditorSessionContext();\r\n const queryClient = useQueryClient();\r\n const entry = useEntry(editorId);\r\n\r\n const onChange = useCallback((next: T | ((prev: T) => T)) => {\r\n if (!editorId) return;\r\n store.setValue(editorId, next as unknown);\r\n }, [store, editorId]);\r\n\r\n const onFacetRuleChange = useCallback((next: FacetRule | null) => {\r\n if (!editorId) return;\r\n store.setFacetRule(editorId, next);\r\n }, [store, editorId]);\r\n\r\n const save = useCallback(async () => {\r\n if (!editorId) return;\r\n try {\r\n await store.save(editorId);\r\n // Invalidate the resolver cache for this target so any sibling\r\n // consumers (RecordList rows, previews) see the fresh server value.\r\n const e = store.get(editorId);\r\n if (e) {\r\n const key = resolvedRecordQueryKey({\r\n collectionId: ctx.collectionId,\r\n appId: ctx.appId,\r\n recordType: ctx.recordType,\r\n productId: e.spec.scope.productId,\r\n variantId: e.spec.scope.variantId,\r\n batchId: e.spec.scope.batchId,\r\n facetId: e.spec.scope.facetId,\r\n facetValue: e.spec.scope.facetValue,\r\n proofId: e.spec.scope.proofId,\r\n recordId: e.recordId,\r\n withParent: true,\r\n });\r\n queryClient.invalidateQueries({ queryKey: key });\r\n }\r\n } catch {\r\n // store.save already rolled status to 'error'; rethrow not needed\r\n // because the consumer reads `error` from the session object.\r\n }\r\n }, [store, editorId, ctx, queryClient]);\r\n\r\n const reset = useCallback(() => {\r\n if (!editorId) return;\r\n store.reset(editorId);\r\n }, [store, editorId]);\r\n\r\n const remove = useCallback(async () => {\r\n if (!editorId) return;\r\n await store.remove(editorId);\r\n }, [store, editorId]);\r\n\r\n if (!editorId || !entry) return null;\r\n\r\n const isRuleScope = entry.spec.scope.kind === 'rule';\r\n const ruleValid = !isRuleScope || isFacetRuleValid(entry.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 editorId,\r\n value: entry.value as T,\r\n onChange,\r\n source: entry.source,\r\n recordId: entry.recordId,\r\n parentValue: entry.parentValue as T | null,\r\n scope: entry.spec.scope,\r\n isDirty: entry.status === 'dirty' || entry.status === 'saving' || entry.status === 'error',\r\n status: entry.status,\r\n error: entry.error ?? null,\r\n save, reset, remove,\r\n canRemove: entry.source === 'self' && !!entry.recordId,\r\n canSave,\r\n cannotSaveReason,\r\n facetRule: entry.facetRule,\r\n onFacetRuleChange,\r\n isActive: editorId === currentEditorId,\r\n };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// useEditorSelection — explicit identity-first selection API\r\n// ---------------------------------------------------------------------------\r\nexport interface SelectTargetInput {\r\n spec: EditorTargetSpec;\r\n /**\r\n * Initial seed when minting a brand-new entry. Pass the resolver's\r\n * current snapshot when one is available; otherwise omit and the entry\r\n * will hydrate via hydrateFromResolver once data arrives.\r\n */\r\n seed?: {\r\n value: unknown;\r\n facetRule: FacetRule | null;\r\n source: ResolvedRecord<unknown>['source'];\r\n parentValue: unknown;\r\n recordId?: string;\r\n };\r\n /** Optional default to seed against if `seed` is omitted. */\r\n defaultValue?: unknown;\r\n /** Optional explicit label for the tray/pill. */\r\n label?: string;\r\n}\r\n\r\nexport interface EditorSelectionApi {\r\n /** Currently active editor id, or undefined when nothing is open. */\r\n currentEditorId: EditorId | undefined;\r\n /** All open editor entries in insertion order (read-only snapshot). */\r\n openEditors: EditorEntry[];\r\n /**\r\n * Select a target. Focuses an existing alive entry if one matches, or\r\n * mints a new one. Returns the chosen editorId.\r\n */\r\n selectTarget: (input: SelectTargetInput) => EditorId;\r\n /** Promote an existing editorId to active without changing its spec. */\r\n focus: (editorId: EditorId) => void;\r\n /** Clear the active editor (e.g. when the host navigates away). */\r\n blur: () => void;\r\n /** Close one editor (no-op if pinned dirty). */\r\n close: (editorId: EditorId) => boolean;\r\n /** Hydrate an entry from a fresh resolver result. */\r\n hydrate: (editorId: EditorId, resolved: ResolvedRecord<unknown>) => void;\r\n}\r\n\r\nexport const useEditorSelection = (): EditorSelectionApi => {\r\n const { store, ctx, currentEditorId, setCurrentEditorId, maxOpenEditors, defaultValueFactory } =\r\n useEditorSessionContext();\r\n const openEditors = useStoreList();\r\n\r\n const selectTarget = useCallback((input: SelectTargetInput): EditorId => {\r\n const existing = store.findExistingEditorIdFor(input.spec);\r\n if (existing) {\r\n store.markActive(existing);\r\n setCurrentEditorId(existing);\r\n store.enforcePoolLimit(maxOpenEditors, existing);\r\n return existing;\r\n }\r\n const editorId = store.open({\r\n spec: input.spec,\r\n saveSpec: buildSaveSpec(ctx, input.spec),\r\n seed: input.seed ?? null,\r\n defaultValue: input.defaultValue ?? defaultValueFactory?.() ?? {},\r\n label: input.label,\r\n });\r\n setCurrentEditorId(editorId);\r\n store.enforcePoolLimit(maxOpenEditors, editorId);\r\n return editorId;\r\n }, [store, ctx, setCurrentEditorId, maxOpenEditors, defaultValueFactory]);\r\n\r\n const focus = useCallback((editorId: EditorId) => {\r\n store.markActive(editorId);\r\n setCurrentEditorId(editorId);\r\n }, [store, setCurrentEditorId]);\r\n\r\n const blur = useCallback(() => setCurrentEditorId(undefined), [setCurrentEditorId]);\r\n\r\n const close = useCallback((editorId: EditorId) => {\r\n const closed = store.close(editorId);\r\n if (closed && currentEditorId === editorId) setCurrentEditorId(undefined);\r\n return closed;\r\n }, [store, currentEditorId, setCurrentEditorId]);\r\n\r\n const hydrate = useCallback((editorId: EditorId, resolved: ResolvedRecord<unknown>) => {\r\n store.hydrateFromResolver(editorId, resolved);\r\n }, [store]);\r\n\r\n return { currentEditorId, openEditors, selectTarget, focus, blur, close, hydrate };\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// useDirtyOverview — header pill / tray / save-all\r\n// ---------------------------------------------------------------------------\r\nconst overviewItemFromEntry = (e: EditorEntry): DirtyOverviewItem => ({\r\n editorId: e.editorId,\r\n label: e.label,\r\n status: e.status,\r\n error: e.error,\r\n scope: e.spec.scope,\r\n recordId: e.recordId,\r\n});\r\n\r\nexport const useDirtyOverview = (): DirtyOverview => {\r\n const { store } = useEditorSessionContext();\r\n const list = useStoreList();\r\n const items = useMemo(\r\n () => list\r\n .filter((e) => e.status === 'dirty' || e.status === 'saving' || e.status === 'error')\r\n .map(overviewItemFromEntry),\r\n [list],\r\n );\r\n const count = items.length;\r\n const errorCount = useMemo(() => items.filter((i) => i.status === 'error').length, [items]);\r\n\r\n const saveAll = useCallback(async () => {\r\n // Sequential: avoids hammering the server and surfaces errors one-by-one\r\n // for the per-record progress UI.\r\n const ids = list\r\n .filter((e) => e.status === 'dirty' || e.status === 'error')\r\n .map((e) => e.editorId);\r\n for (const id of ids) {\r\n try { await store.save(id); }\r\n catch { /* status already moved to 'error' */ }\r\n }\r\n }, [store, list]);\r\n\r\n const discardAll = useCallback(() => {\r\n const ids = list\r\n .filter((e) => e.status === 'dirty' || e.status === 'error')\r\n .map((e) => e.editorId);\r\n ids.forEach((id) => store.reset(id));\r\n }, [store, list]);\r\n\r\n const saveOne = useCallback(async (editorId: EditorId) => {\r\n await store.save(editorId);\r\n }, [store]);\r\n\r\n return { items, count, errorCount, saveAll, discardAll, saveOne };\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Convenience: parsed-ref → scope shape that the resolver expects.\r\n// (Not strictly part of the session surface but kept here so consumers can\r\n// build a target spec without importing data/* directly.)\r\n// ---------------------------------------------------------------------------\r\nexport const parsedRefToTargetSpec = (\r\n scope: ParsedRef,\r\n opts: Partial<Omit<EditorTargetSpec, 'scope'>> = {},\r\n): EditorTargetSpec => ({ scope, ...opts });\r\n","// =============================================================================\r\n// EditorMountPool — mounts the host's editor JSX once per open editorId and\r\n// toggles visibility so switching between records is instant (no remount).\r\n//\r\n// Design notes\r\n// ------------\r\n// * The pool only owns the *editor body* (whatever `renderSlot` returns).\r\n// All surrounding chrome — preview pane, item nav, scope picker, drawer —\r\n// stays in the shell and tracks the active selection. That chrome is cheap\r\n// to remount; the editor body (rich text, complex forms, file pickers) is\r\n// not, which is what we're protecting here.\r\n//\r\n// * Each slot is keyed by `editorId`, so React never reuses one slot's mount\r\n// for another. When the EditorStore evicts an entry (LRU), it falls out\r\n// of `openEditors` and the slot unmounts naturally. Dirty entries are\r\n// pinned in the store and therefore stay mounted across selections.\r\n//\r\n// * Inactive slots are hidden via `display: none`. This preserves React\r\n// state, refs, and uncontrolled DOM (form inputs, contenteditable, etc.)\r\n// without painting or laying out the subtree.\r\n//\r\n// * `keepMountedHidden={false}` is an opt-out for hosts whose editor\r\n// misbehaves when hidden (e.g. measurement-dependent canvases). In that\r\n// mode the pool degrades to single-active behaviour.\r\n//\r\n// * Inactive slots are wrapped with `inert` + `aria-hidden` so keyboard\r\n// focus and AT cursors don't escape into hidden editors.\r\n// =============================================================================\r\nimport { type ReactNode, useMemo } from 'react';\r\nimport { useEditorSelection } from './EditorSessionProvider';\r\nimport type { EditorId } from './types';\r\n\r\nexport interface EditorMountPoolProps {\r\n /**\r\n * Render the editor body for one slot. Called once per open editor and\r\n * memoised by `editorId` — the function itself does not need to be\r\n * referentially stable, but its output should depend only on `editorId`\r\n * (read live state inside via `useEditorSession(editorId)`).\r\n */\r\n renderSlot: (editorId: EditorId) => ReactNode;\r\n /**\r\n * When false, only the active slot mounts. Use for hosts whose editor\r\n * cannot survive `display: none` (rare). Defaults to true.\r\n */\r\n keepMountedHidden?: boolean;\r\n /** Optional fallback when no editor is selected. */\r\n fallback?: ReactNode;\r\n /** className applied to the pool container. */\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Renders one mounted slot per open editor. Only the slot matching\r\n * `currentEditorId` is visible; the rest are kept in the DOM but hidden.\r\n */\r\nexport const EditorMountPool = ({\r\n renderSlot, keepMountedHidden = true, fallback = null, className,\r\n}: EditorMountPoolProps) => {\r\n const { openEditors, currentEditorId } = useEditorSelection();\r\n\r\n // Snapshot ids in a stable order so React's reconciler doesn't shuffle\r\n // mounts when the store reorders entries (e.g. on markActive).\r\n const ids = useMemo(\r\n () => openEditors.map((e) => e.editorId).sort(),\r\n [openEditors],\r\n );\r\n\r\n if (!currentEditorId && ids.length === 0) {\r\n return <>{fallback}</>;\r\n }\r\n\r\n const visibleIds = keepMountedHidden\r\n ? ids\r\n : (currentEditorId ? [currentEditorId] : []);\r\n\r\n return (\r\n <div className={className} style={{ display: 'contents' }}>\r\n {visibleIds.map((id) => {\r\n const isActive = id === currentEditorId;\r\n return (\r\n <EditorPoolSlot key={id} editorId={id} isActive={isActive}>\r\n {renderSlot(id)}\r\n </EditorPoolSlot>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n\r\ninterface EditorPoolSlotProps {\r\n editorId: EditorId;\r\n isActive: boolean;\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * One pool entry. Wraps the host editor in a hidden container when\r\n * inactive. Uses `display: contents` when active so the wrapper does not\r\n * disturb the chrome's flex/grid layout.\r\n */\r\nconst EditorPoolSlot = ({ editorId, isActive, children }: EditorPoolSlotProps) => {\r\n // `inert` is the right tool here but isn't reflected as a JSX prop in\r\n // older React types — set via the boolean attribute string. Modern\r\n // browsers (and our target matrix) support it natively.\r\n const inertProps = isActive ? {} : { inert: '' as unknown as boolean };\r\n\r\n return (\r\n <div\r\n data-editor-slot={editorId}\r\n data-active={isActive ? 'true' : 'false'}\r\n aria-hidden={isActive ? undefined : true}\r\n style={{\r\n display: isActive ? 'contents' : 'none',\r\n }}\r\n {...inertProps}\r\n >\r\n {children}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// useEditorSlotContext — per-slot adapter for the EditorMountPool.\r\n//\r\n// EditorMountPool calls `renderSlot(editorId)` for every open editor,\r\n// including hidden ones. The host's `renderEditor(ctx)` still expects a\r\n// legacy EditorContext, so this hook produces one for any editorId by\r\n// reading directly from the EditorStore via `useEditorSession(editorId)`.\r\n//\r\n// Unlike `useEditorBridge`, this hook does NOT own selection or hydration\r\n// for its slot — those happen at the shell level for the active editor.\r\n// Inactive slots simply mirror the value/baseline already in the store.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport type { EditorContext } from '../types';\r\nimport { useEditorSession } from './EditorSessionProvider';\r\nimport type { EditorId } from './types';\r\n\r\nexport function useEditorSlotContext<T>(editorId: EditorId): EditorContext<T> | null {\r\n const session = useEditorSession<T>(editorId);\r\n return useMemo<EditorContext<T> | null>(() => {\r\n if (!session) return null;\r\n return {\r\n value: session.value,\r\n onChange: session.onChange as EditorContext<T>['onChange'],\r\n source: session.source,\r\n recordId: session.recordId,\r\n parentValue: session.parentValue,\r\n scope: session.scope,\r\n isDirty: session.isDirty,\r\n save: session.save,\r\n reset: session.reset,\r\n remove: session.remove,\r\n canRemove: session.canRemove,\r\n canSave: session.canSave,\r\n cannotSaveReason: session.cannotSaveReason,\r\n isSaving: session.status === 'saving',\r\n saveError: session.error,\r\n facetRule: session.facetRule,\r\n onFacetRuleChange: session.onFacetRuleChange,\r\n };\r\n }, [session]);\r\n}","// =============================================================================\r\n// editor-session/useEditorBridge.ts\r\n//\r\n// Internal-only bridge used by RecordsAdminShell during the 2a migration.\r\n// Wraps the new EditorStore behind an EditorContext-shaped return so the\r\n// shell's existing renderEditor / RecordEditor / RecordTargeting consumers\r\n// don't need to change in this pass.\r\n//\r\n// Phase 2b will hoist per-editor rendering into an EditorHost that calls\r\n// useEditorSession directly; at that point this bridge can be deleted.\r\n//\r\n// NOT exported from the package — purely an implementation detail.\r\n// =============================================================================\r\nimport { useEffect, useMemo, useRef } from 'react';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport type {\r\n EditorContext, ParsedRef, ResolvedRecord,\r\n} from '../types';\r\nimport { useEditorSelection, useEditorSession } from './EditorSessionProvider';\r\nimport type { EditorTargetSpec } from './types';\r\n\r\nexport interface UseEditorBridgeArgs<T> {\r\n /** Current target. When undefined, no editor is selected and the bridge\r\n * returns a sentinel ctx with `isDirty=false` and noop handlers. */\r\n target: EditorTargetSpec | null;\r\n /** Resolver result for `target`. Fed into the store via hydrate(). */\r\n resolved: ResolvedRecord<T> & { facetRule?: FacetRule | null };\r\n /** Default value factory for brand-new drafts (resolver source==='empty'). */\r\n defaultData?: () => T;\r\n /** Called after a successful save (refetch lists, run telemetry, etc.). */\r\n onSaved?: () => void;\r\n /** Called after a successful delete. */\r\n onDeleted?: () => void;\r\n}\r\n\r\nconst isEqualSpec = (a: EditorTargetSpec | null, b: EditorTargetSpec | null): boolean => {\r\n if (a === b) return true;\r\n if (!a || !b) return false;\r\n if (a.scope.raw !== b.scope.raw) return false;\r\n if ((a.recordId ?? null) !== (b.recordId ?? null)) return false;\r\n if (!!a.createMode !== !!b.createMode) return false;\r\n return true;\r\n};\r\n\r\n/**\r\n * Returns an EditorContext-shaped value backed by the new EditorStore.\r\n * The bridge is responsible for:\r\n * 1. Calling selection.selectTarget when `target` changes (mints/focuses\r\n * the editor for that target).\r\n * 2. Pushing resolver results into the store via hydrate().\r\n * 3. Wrapping the resulting EditorSession in the legacy EditorContext API.\r\n */\r\nexport function useEditorBridge<T>(args: UseEditorBridgeArgs<T>): EditorContext<T> {\r\n const { target, resolved, defaultData, onSaved, onDeleted } = args;\r\n const selection = useEditorSelection();\r\n\r\n // Track the most recently selected target so we only call selectTarget\r\n // when it actually changes — selectTarget itself is idempotent for\r\n // matching specs, but skipping the call avoids redundant store churn.\r\n const lastTargetRef = useRef<EditorTargetSpec | null>(null);\r\n const editorIdRef = useRef<string | undefined>(undefined);\r\n\r\n useEffect(() => {\r\n if (!target) {\r\n selection.blur();\r\n lastTargetRef.current = null;\r\n editorIdRef.current = undefined;\r\n return;\r\n }\r\n if (isEqualSpec(target, lastTargetRef.current)) return;\r\n lastTargetRef.current = target;\r\n const id = selection.selectTarget({\r\n spec: target,\r\n seed: resolved.source === 'empty' ? undefined : {\r\n value: resolved.data ?? (defaultData?.() ?? null),\r\n facetRule: resolved.facetRule ?? null,\r\n source: resolved.source,\r\n parentValue: resolved.parentValue ?? null,\r\n recordId: resolved.recordId,\r\n },\r\n defaultValue: defaultData?.() ?? {},\r\n });\r\n editorIdRef.current = id;\r\n // Intentionally only react to target identity changes, not resolver\r\n // updates — resolver changes are pushed via the hydrate effect below.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [target?.scope.raw, target?.recordId, target?.createMode]);\r\n\r\n // Hydrate the active editor whenever the resolver settles. The store's\r\n // hydrateFromResolver guards against clobbering dirty values.\r\n useEffect(() => {\r\n const id = editorIdRef.current;\r\n if (!id) return;\r\n if (resolved.source === 'empty' && !resolved.recordId) return;\r\n selection.hydrate(id, resolved as ResolvedRecord<unknown>);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [resolved.source, resolved.recordId, resolved.sourceRef, resolved.data, resolved.facetRule]);\r\n\r\n const editorId = selection.currentEditorId ?? editorIdRef.current;\r\n const session = useEditorSession<T>(editorId);\r\n\r\n // Side-effect callbacks. We watch `status` transitions to fire onSaved /\r\n // onDeleted exactly once per event. These mirror the legacy hook's\r\n // onSaved/onDeleted semantics.\r\n const prevStatusRef = useRef<string | null>(null);\r\n useEffect(() => {\r\n const prev = prevStatusRef.current;\r\n const next = session?.status ?? null;\r\n prevStatusRef.current = next;\r\n if (next === 'saved' && prev !== 'saved') {\r\n onSaved?.();\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [session?.status]);\r\n\r\n // Wrap remove() so onDeleted fires on success.\r\n const remove = useMemo(() => async () => {\r\n if (!session) return;\r\n await session.remove();\r\n onDeleted?.();\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [session?.remove]);\r\n\r\n // Sentinel context when nothing is selected — keeps the shell render path\r\n // happy. `isDirty=false` ensures unsaved guards don't fire spuriously.\r\n if (!session) {\r\n const sentinelScope: ParsedRef = target?.scope ?? { kind: 'collection', raw: '' };\r\n return {\r\n value: (defaultData?.() ?? ({} as T)),\r\n onChange: () => {},\r\n source: 'empty',\r\n recordId: undefined,\r\n parentValue: null,\r\n scope: sentinelScope,\r\n isDirty: false,\r\n save: async () => {},\r\n reset: () => {},\r\n remove: async () => {},\r\n canRemove: false,\r\n canSave: false,\r\n cannotSaveReason: undefined,\r\n isSaving: false,\r\n saveError: null,\r\n facetRule: null,\r\n onFacetRuleChange: () => {},\r\n };\r\n }\r\n\r\n return {\r\n value: session.value,\r\n onChange: session.onChange as EditorContext<T>['onChange'],\r\n source: session.source,\r\n recordId: session.recordId,\r\n parentValue: session.parentValue,\r\n scope: session.scope,\r\n isDirty: session.isDirty,\r\n save: session.save,\r\n reset: session.reset,\r\n remove,\r\n canRemove: session.canRemove,\r\n canSave: session.canSave,\r\n cannotSaveReason: session.cannotSaveReason,\r\n isSaving: session.status === 'saving',\r\n saveError: session.error,\r\n facetRule: session.facetRule,\r\n onFacetRuleChange: session.onFacetRuleChange,\r\n };\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};","// =============================================================================\r\n// useShellCsvBulk — extracted CSV import/export wiring for RecordsAdminShell.\r\n//\r\n// Returns a stable `csvBulk` object suitable for `RecordEditor`'s\r\n// `bulkActions` slot. When no `csvSchema` is supplied the hook returns an\r\n// empty object — same semantics as the original inline logic.\r\n//\r\n// Pure refactor: behaviour, telemetry payloads and filename derivation are\r\n// identical to the previous inline handlers.\r\n// =============================================================================\r\nimport { useCallback, useMemo } from 'react';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport { exportCsv, importCsv, downloadBlob } from '../data/csv';\r\nimport type { RecordSummary } from '../types';\r\nimport type { TelemetryEvent } from '../types/telemetry';\r\nimport type { CsvSchema } from '../types/csv';\r\n\r\nexport interface UseShellCsvBulkArgs<TData> {\r\n csvSchema?: CsvSchema<TData>;\r\n recordType?: string;\r\n /** Friendly label used as a fallback when `recordType` is unset. */\r\n label: string;\r\n /** Records-list snapshot used as the export source. */\r\n items: RecordSummary<TData>[];\r\n /** SDK context used by importCsv. */\r\n ctx: RecordsCtx;\r\n /** Refetcher fired after a successful import. */\r\n refetchAll: () => void;\r\n onTelemetry?: (event: TelemetryEvent) => void;\r\n}\r\n\r\nexport interface ShellCsvBulk {\r\n onImportCsv?: () => void;\r\n onExportCsv?: () => void;\r\n}\r\n\r\nexport function useShellCsvBulk<TData>(\r\n args: UseShellCsvBulkArgs<TData>,\r\n): ShellCsvBulk {\r\n const { csvSchema, recordType, label, items, ctx, refetchAll, onTelemetry } = args;\r\n\r\n const fileBase = useMemo(\r\n () => recordType ?? (label.toLowerCase().replace(/\\s+/g, '-') || 'records'),\r\n [recordType, label],\r\n );\r\n\r\n const handleExport = useCallback(() => {\r\n if (!csvSchema) return;\r\n const blob = exportCsv(items, csvSchema);\r\n downloadBlob(blob, `${fileBase}.csv`);\r\n onTelemetry?.({ type: 'csv.export', recordType, rows: items.length });\r\n }, [csvSchema, items, fileBase, onTelemetry, recordType]);\r\n\r\n const handleImport = useCallback(() => {\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 downloadBlob(\r\n new Blob([report.annotatedCsv], { type: 'text/csv' }),\r\n `${fileBase}-errors.csv`,\r\n );\r\n }\r\n refetchAll();\r\n };\r\n inp.click();\r\n }, [csvSchema, ctx, fileBase, onTelemetry, recordType, refetchAll]);\r\n\r\n return useMemo<ShellCsvBulk>(\r\n () => csvSchema ? { onImportCsv: handleImport, onExportCsv: handleExport } : {},\r\n [csvSchema, handleImport, handleExport],\r\n );\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:root {\\n --sl-control-bg: var(--muted, 220 14% 96%);\\n --sl-control-fg: var(--muted-foreground, 220 9% 40%);\\n --sl-control-border: var(--border, 220 13% 88%);\\n --sl-control-active-bg: var(--primary, 222 47% 11%);\\n --sl-control-active-fg: var(--primary-foreground, 0 0% 100%);\\n --sl-control-active-bd: var(--primary, 222 47% 11%);\\n --sl-control-hover-bg: var(--sl-control-active-bg, 222 47% 11%);\\n --sl-control-hover-fg: var(--foreground, 222 47% 11%);\\n --sl-control-focus-ring: var(--sl-control-active-bg, 222 47% 11%);\\n --sl-control-radius: var(--radius, 0.5rem);\\n --sl-control-weight: 500;\\n --sl-control-active-weight: 600;\\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 display: block;\\n width: 100%;\\n}\\n.ra-shell .ra-header__main {\\n flex: 1;\\n min-width: 0;\\n display: flex;\\n align-items: flex-start;\\n gap: 0.55rem;\\n}\\n.ra-shell .ra-header-aside {\\n display: flex;\\n align-items: flex-start;\\n gap: 0.5rem;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-header-icon {\\n flex-shrink: 0;\\n display: inline-flex;\\n align-items: center;\\n justify-content: flex-start;\\n background: transparent;\\n color: hsl(var(--ra-text));\\n border: 0;\\n padding: 0;\\n margin-top: 0.1rem;\\n}\\n.ra-shell .ra-header-icon > svg {\\n width: 1.05rem;\\n height: 1.05rem;\\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: 700;\\n font-size: 1.2rem;\\n line-height: 1.2;\\n color: hsl(var(--ra-text));\\n letter-spacing: -0.015em;\\n margin: 0;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.5rem;\\n}\\n.ra-shell .ra-header-subtitle {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.1rem;\\n line-height: 1.3;\\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(--sl-control-bg));\\n border-radius: var(--sl-control-radius);\\n border: 1px solid hsl(var(--sl-control-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(--sl-control-radius) - 2px);\\n font-size: 0.78rem;\\n font-weight: var(--sl-control-weight);\\n color: hsl(var(--sl-control-fg));\\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(--sl-control-hover-bg) / 0.10);\\n color: hsl(var(--sl-control-hover-fg));\\n}\\n.ra-shell .ra-tab:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 2px hsl(var(--sl-control-focus-ring) / 0.45);\\n}\\n.ra-shell .ra-tab[aria-selected=true] {\\n background: hsl(var(--sl-control-active-bg));\\n color: hsl(var(--sl-control-active-fg));\\n border-color: hsl(var(--sl-control-active-bd));\\n font-weight: var(--sl-control-active-weight);\\n box-shadow: 0 1px 2px hsl(var(--sl-control-active-bg) / 0.25);\\n}\\n.ra-shell .ra-tab[aria-selected=true]:hover {\\n background: hsl(var(--sl-control-active-bg) / 0.92);\\n color: hsl(var(--sl-control-active-fg));\\n}\\n.ra-shell .ra-tab[aria-selected=true] .ra-tab-icon {\\n color: hsl(var(--sl-control-active-fg));\\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(--sl-control-active-fg) / 0.20);\\n color: hsl(var(--sl-control-active-fg));\\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(--sl-control-fg) / 0.15);\\n color: hsl(var(--sl-control-fg));\\n}\\n.ra-shell[data-density=compact] .ra-row {\\n padding-block: 0.4rem;\\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 align-items: center;\\n gap: 0.55rem;\\n padding: 0.4rem 2rem 0.4rem 0.5rem;\\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}\\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: 1.5rem;\\n height: 1.5rem;\\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.8rem;\\n color: hsl(var(--ra-text));\\n margin: 0;\\n line-height: 1.2;\\n display: inline;\\n}\\n.ra-shell .ra-intro-text {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-text) / 0.85);\\n line-height: 1.35;\\n display: inline;\\n margin-left: 0.4rem;\\n}\\n.ra-shell .ra-intro-dismiss {\\n position: absolute;\\n top: 50%;\\n right: 0.35rem;\\n transform: translateY(-50%);\\n width: 1.4rem;\\n height: 1.4rem;\\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 padding: 0;\\n flex-shrink: 0;\\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 background: transparent;\\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.sl-aph .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, 8px) - 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.sl-aph .ra-unsaved-btn:disabled {\\n opacity: 0.5;\\n cursor: not-allowed;\\n}\\n.sl-aph .ra-unsaved-btn:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px var(--ra-focus-ring, 0 0 0 3px hsl(var(--ra-accent) / 0.35));\\n}\\n.sl-aph .ra-unsaved-btn-ghost {\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n border-color: hsl(var(--ra-border));\\n}\\n.sl-aph .ra-unsaved-btn-ghost:hover:not(:disabled) {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.sl-aph .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.sl-aph .ra-unsaved-btn-primary:hover:not(:disabled) {\\n filter: brightness(0.95);\\n}\\n.sl-aph .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@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-unsaved-pill,\\n.sl-aph .ra-unsaved-pill {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n padding: 0.25rem 0.5rem 0.25rem 0.6rem;\\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: 999px;\\n animation: ra-unsaved-slide .14s ease-out;\\n}\\n.ra-shell .ra-unsaved-pill .ra-unsaved-pill-text,\\n.sl-aph .ra-unsaved-pill .ra-unsaved-pill-text {\\n font-size: 0.75rem;\\n font-weight: 500;\\n color: hsl(var(--ra-text));\\n white-space: nowrap;\\n margin-right: 0.15rem;\\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(var(--ra-item-card-min, 240px), 1fr));\\n gap: 0.85rem;\\n}\\n.ra-shell .ra-item-gallery {\\n display: grid;\\n grid-template-columns: repeat(auto-fill, minmax(var(--ra-item-gallery-min, 320px), 1fr));\\n gap: 1rem;\\n}\\n.ra-shell .ra-item-cards[data-card-size=sm] {\\n --ra-item-card-min: 180px;\\n}\\n.ra-shell .ra-item-cards[data-card-size=md] {\\n --ra-item-card-min: 240px;\\n}\\n.ra-shell .ra-item-cards[data-card-size=lg] {\\n --ra-item-card-min: 320px;\\n gap: 1rem;\\n}\\n.ra-shell .ra-item-gallery[data-card-size=sm] {\\n --ra-item-gallery-min: 240px;\\n}\\n.ra-shell .ra-item-gallery[data-card-size=md] {\\n --ra-item-gallery-min: 320px;\\n}\\n.ra-shell .ra-item-gallery[data-card-size=lg] {\\n --ra-item-gallery-min: 420px;\\n gap: 1.25rem;\\n}\\n.ra-shell .ra-item-cards[data-card-size=lg] .ra-item-card-title,\\n.ra-shell .ra-item-gallery[data-card-size=lg] .ra-item-card-title {\\n font-size: 0.95rem;\\n white-space: normal;\\n display: -webkit-box;\\n -webkit-line-clamp: 2;\\n -webkit-box-orient: vertical;\\n}\\n.ra-shell .ra-item-cards[data-card-size=lg] .ra-item-card-body,\\n.ra-shell .ra-item-gallery[data-card-size=lg] .ra-item-card-body {\\n padding: 0.85rem 1rem 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-error-pip {\\n display: inline-block;\\n width: 0.45rem;\\n height: 0.45rem;\\n border-radius: 9999px;\\n background: hsl(var(--ra-danger, 0 72% 51%));\\n box-shadow: 0 0 0 2px hsl(var(--ra-danger, 0 72% 51%) / 0.22);\\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 justify-content: center;\\n width: 1.6rem;\\n height: 1.6rem;\\n padding: 0;\\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.95rem;\\n height: 0.95rem;\\n}\\n.ra-shell .ra-help-float > span {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n padding: 0;\\n margin: -1px;\\n overflow: hidden;\\n clip: rect(0, 0, 0, 0);\\n white-space: nowrap;\\n border: 0;\\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.ra-shell .ra-unsaved-tray {\\n position: relative;\\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-count {\\n flex: 1;\\n min-width: 0;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.3rem;\\n padding: 0.15rem 0.4rem;\\n margin: -0.15rem -0.4rem;\\n background: transparent;\\n border: 0;\\n color: inherit;\\n font: inherit;\\n font-weight: 500;\\n text-align: left;\\n cursor: pointer;\\n border-radius: calc(var(--ra-radius) - 4px);\\n}\\n.ra-shell .ra-unsaved-count:hover {\\n background: hsl(var(--ra-muted) / 0.6);\\n}\\n.ra-shell .ra-unsaved-error-chip {\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n appearance: none;\\n border: 1px solid hsl(var(--ra-danger, 0 72% 51%) / 0.35);\\n background: hsl(var(--ra-danger, 0 72% 51%) / 0.08);\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n border-radius: 999px;\\n padding: 0.15rem 0.55rem;\\n font-size: 0.7rem;\\n font-weight: 500;\\n cursor: pointer;\\n}\\n.ra-shell .ra-unsaved-error-chip:hover {\\n filter: brightness(0.97);\\n}\\n.ra-shell .ra-unsaved-popover {\\n position: absolute;\\n top: calc(100% + 6px);\\n left: 0;\\n z-index: 60;\\n min-width: 18rem;\\n max-height: 18rem;\\n overflow: auto;\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: var(--ra-radius);\\n box-shadow: 0 12px 30px -10px hsl(0 0% 0% / 0.25);\\n padding: 0.3rem;\\n display: flex;\\n flex-direction: column;\\n gap: 0.15rem;\\n}\\n.ra-shell .ra-unsaved-popover-row {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n padding: 0.4rem 0.55rem;\\n background: transparent;\\n border: 0;\\n border-radius: calc(var(--ra-radius) - 2px);\\n cursor: pointer;\\n text-align: left;\\n font: inherit;\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-unsaved-popover-row:hover {\\n background: hsl(var(--ra-muted));\\n}\\n.ra-shell .ra-unsaved-popover-dot {\\n width: 0.5rem;\\n height: 0.5rem;\\n border-radius: 999px;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-unsaved-popover-label {\\n flex: 1;\\n min-width: 0;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n font-size: 0.8125rem;\\n}\\n.ra-shell .ra-unsaved-popover-ctx {\\n color: hsl(var(--ra-muted-text));\\n font-size: 0.7rem;\\n text-transform: uppercase;\\n letter-spacing: 0.04em;\\n}\\n.ra-shell .ra-unsaved-popover-err {\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n font-size: 0.7rem;\\n font-weight: 500;\\n}\\n.ra-saveall-overlay {\\n position: fixed;\\n inset: 0;\\n z-index: 100;\\n background: hsl(0 0% 0% / 0.45);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 1rem;\\n animation: ra-confirm-fade .12s ease-out;\\n}\\n.ra-saveall-card {\\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 24px 48px -16px hsl(0 0% 0% / 0.45);\\n width: min(28rem, 100%);\\n max-height: min(80vh, 36rem);\\n display: flex;\\n flex-direction: column;\\n animation: ra-confirm-pop .14s ease-out;\\n}\\n.ra-saveall-header {\\n padding: 1rem 1rem 0.5rem;\\n display: flex;\\n flex-direction: column;\\n gap: 0.5rem;\\n}\\n.ra-saveall-title {\\n font-weight: 600;\\n font-size: 0.95rem;\\n}\\n.ra-saveall-progress {\\n height: 4px;\\n background: hsl(var(--ra-muted));\\n border-radius: 999px;\\n overflow: hidden;\\n}\\n.ra-saveall-progress-bar {\\n height: 100%;\\n background: hsl(var(--ra-accent));\\n transition: width .2s ease;\\n}\\n.ra-saveall-counter {\\n color: hsl(var(--ra-muted-text));\\n font-size: 0.75rem;\\n font-variant-numeric: tabular-nums;\\n}\\n.ra-saveall-list {\\n list-style: none;\\n margin: 0;\\n padding: 0.25rem 0.5rem;\\n overflow: auto;\\n flex: 1;\\n}\\n.ra-saveall-row {\\n display: flex;\\n align-items: center;\\n gap: 0.6rem;\\n padding: 0.45rem 0.5rem;\\n border-radius: calc(var(--ra-radius) - 4px);\\n font-size: 0.8125rem;\\n}\\n.ra-saveall-row[data-status=saving] {\\n background: hsl(var(--ra-accent) / 0.06);\\n}\\n.ra-saveall-row[data-status=saved] {\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-saveall-row[data-status=error] {\\n background: hsl(var(--ra-danger, 0 72% 51%) / 0.06);\\n}\\n.ra-saveall-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-saveall-row[data-status=saved] .ra-saveall-icon {\\n color: hsl(var(--ra-success, 142 71% 45%));\\n}\\n.ra-saveall-row[data-status=saving] .ra-saveall-icon {\\n color: hsl(var(--ra-accent));\\n}\\n.ra-saveall-row[data-status=error] .ra-saveall-icon {\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n}\\n.ra-saveall-label {\\n flex: 1;\\n min-width: 0;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-saveall-err {\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n font-size: 0.7rem;\\n max-width: 12rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-saveall-actions {\\n padding: 0.75rem 1rem 1rem;\\n display: flex;\\n justify-content: flex-end;\\n gap: 0.4rem;\\n border-top: 1px solid hsl(var(--ra-border));\\n}\\n.ra-spin {\\n animation: ra-spin 1s linear infinite;\\n}\\n@keyframes ra-spin {\\n to {\\n transform: rotate(360deg);\\n }\\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 EditorContext,\r\n} from '../types';\r\nimport { DEFAULT_I18N } from '../types';\r\nimport { parseRef, buildRef } from '../data/refs';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport { useResolvedRecord } from '../hooks/useResolvedRecord';\r\nimport { resolvedRecordQueryKey } from '../hooks/useResolvedRecord';\r\nimport { useQueryClient } from '@tanstack/react-query';\r\nimport { useIntroDismissed } from '../hooks/useIntroDismissed';\r\nimport { useScopeProbe } from '../hooks/useScopeProbe';\r\nimport { useShellBrowser, type ProductBrowseItem } from '../hooks/useShellBrowser';\r\nimport { useUnsavedGuard } from '../hooks/useUnsavedGuard';\r\nimport { useDirtyNavigation } from '../hooks/useDirtyNavigation';\r\nimport { useConfirmDialog } from '../hooks/useConfirmDialog';\r\nimport { useShellClipboard } from '../hooks/useShellClipboard';\r\nimport { ScopeTabs } from '../browser/ScopeTabs';\r\nimport { StatusFilterPills } from '../browser/StatusFilterPills';\r\nimport { RecordList } from '../browser/RecordList';\r\nimport { RuleFilterChips, applyRuleFilters, type RuleFilters } from '../browser/RuleFilterChips';\r\nimport { FacetBrowseFilter, type FacetBrowseSelection, type FacetBrowseFacet } from '../browser/FacetBrowseFilter';\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 { NewRuleWizard } from './NewRuleWizard';\r\nimport { UnsavedTray } from './UnsavedTray';\r\nimport { HeaderUnsavedPill, canRenderInHeader } from './HeaderUnsavedPill';\r\nimport { SaveAllProgress } from './SaveAllProgress';\r\nimport {\r\n EditorSessionProvider,\r\n useEditorSelection,\r\n useDirtyOverview,\r\n} from '../editor-session';\r\nimport { useEditorBridge } from '../editor-session/useEditorBridge';\r\nimport { EditorMountPool } from '../editor-session/EditorMountPool';\r\nimport { useEditorSlotContext } from '../editor-session/useEditorSlotContext';\r\nimport type { EditorTargetSpec } from '../editor-session/types';\r\nimport { useShellCsvBulk } from '../hooks/useShellCsvBulk';\r\nimport './tokens.css';\r\nimport './shell.css';\r\n\r\n// ---------------------------------------------------------------------------\r\n// EditorPoolBody — per-slot adapter rendered inside <EditorMountPool>.\r\n//\r\n// Defined at module scope (NOT inside the shell render) so React doesn't\r\n// see a fresh component identity on every shell re-render — that would\r\n// remount the host editor on every keystroke and defeat the pool entirely.\r\n// ---------------------------------------------------------------------------\r\nconst EditorPoolBody = ({\r\n editorId,\r\n renderEditor,\r\n}: {\r\n editorId: string;\r\n renderEditor: (ctx: EditorContext<unknown>) => ReactNode;\r\n}): ReactNode => {\r\n const ctx = useEditorSlotContext<unknown>(editorId);\r\n if (!ctx) return null;\r\n return renderEditor(ctx);\r\n};\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 * Tab order policy (v0.5.1+):\r\n * 1. If the host passes `scopes`, we honour the order they listed\r\n * (filtered to known top-level scopes). Hosts get full control.\r\n * 2. If the host does NOT pass `scopes`, we fall back to the canonical\r\n * order below — `collection` (Global) first because it's the\r\n * simplest mental model for new admins (\"where do records that apply\r\n * to everything live?\"), with `rule`-based targeting as the next\r\n * step up in complexity.\r\n *\r\n * NOTE (v0.5): The legacy `'facet'` scope is no longer surfaced as a\r\n * top-level tab. Hosts that still list it in `scopes` get a one-time\r\n * deprecation warning and the entry is silently dropped. The same admin\r\n * affordance now lives inside the Rules / Global tabs as the\r\n * `FacetBrowseFilter` chip row — see CHANGELOG 0.5.0.\r\n */\r\nconst TOP_LEVEL_SCOPES: ScopeKind[] = ['collection', 'rule', 'product'];\r\n\r\n/** One-time deprecation log gate (module-scoped — fires per page load). */\r\nlet WARNED_FACET_DEPRECATED = false;\r\n\r\n/**\r\n * Sentinel value for `selectedRecordId` while the user is authoring a\r\n * brand-new draft that hasn't been saved yet. Drafts have no UUID until\r\n * the first server round-trip — using a sentinel keeps the selection state\r\n * monomorphic (`string | null`) without inventing a synthetic ref string.\r\n * The shell distinguishes draft kind via `draftKind` state.\r\n */\r\nconst DRAFT_ID = '__draft__';\r\n\r\n/**\r\n * True for any synthetic draft id — either the singleton sentinel\r\n * `__draft__` (used for `selectedRecordId`) or a per-mint `draft:<uuid>`\r\n * value used for collection-item drafts. Hosts must treat both as\r\n * \"unsaved\" (no server round-trip yet) and not display the raw value.\r\n */\r\nconst isDraftId = (id: string | null | undefined): boolean =>\r\n !!id && (id === DRAFT_ID || id.startsWith('draft:'));\r\n\r\n/** Mint a unique synthetic id for a brand-new collection-item draft.\r\n * We avoid the bare `__draft__` sentinel here so multiple drafts in a\r\n * session don't collide and so the literal `__draft__` token never\r\n * surfaces in any host-visible identifier or in `scope.raw`. */\r\nconst mintDraftItemId = (): string => {\r\n const rand = (typeof crypto !== 'undefined' && 'randomUUID' in crypto)\r\n ? crypto.randomUUID()\r\n : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\r\n return `draft:${rand}`;\r\n};\r\n\r\n/**\r\n * Unsaved collection items must always use a shell-owned synthetic draft id.\r\n * Some hosts provide `generateItemId()` values that look like real UUIDs;\r\n * if we stored those verbatim the resolver would treat a brand-new draft as\r\n * an existing saved record and try to fetch it by id, surfacing the host's\r\n * \"Loading <id>\" placeholder forever. Prefix any host-supplied handle so the\r\n * rest of the shell consistently recognises it as local-only draft state.\r\n */\r\nconst coerceDraftItemId = (generateItemId?: () => string): string => {\r\n const candidate = generateItemId ? generateItemId() : mintDraftItemId();\r\n return isDraftId(candidate) ? candidate : `draft:${candidate}`;\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 // Build the records context once at the outermost level so we can mount\r\n // the EditorSessionProvider before any descendant tries to consume the\r\n // session hooks. The inner component re-derives the same memoised ctx\r\n // for its own data calls — both use the same primitive props so\r\n // referential identity stays stable per (SL, collectionId, appId,\r\n // recordType) tuple.\r\n const ctx = useMemo<RecordsCtx>(\r\n () => ({\r\n SL: props.SL,\r\n collectionId: props.collectionId,\r\n appId: props.appId,\r\n recordType: props.recordType,\r\n }),\r\n [props.SL, props.collectionId, props.appId, props.recordType],\r\n );\r\n return (\r\n <EditorSessionProvider\r\n ctx={ctx}\r\n defaultValueFactory={props.defaultData as (() => unknown) | undefined}\r\n >\r\n <RecordsAdminShellInner {...props} />\r\n </EditorSessionProvider>\r\n );\r\n}\r\n\r\nfunction RecordsAdminShellInner<TData = unknown>(props: RecordsAdminShellProps<TData>) {\r\n const {\r\n SL, appId, collectionId, recordType, label,\r\n scopes: requestedScopes, defaultScope, contextScope,\r\n contextScopeMode = 'strict',\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 helpUrl, helpLabel,\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 itemCardSize = 'md',\r\n collectionRailMode = 'siblings',\r\n // Deep linking\r\n deepLink,\r\n deriveDraftLabel,\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 picked item. The id stored here is the record's UUID for saved\r\n // items, or a transient local id for not-yet-saved drafts.\r\n const [selectedItemId, setSelectedItemId] = useState<string | null>(null);\r\n\r\n // URL-supplied recordId pending resolution — set by the deep-link restore\r\n // effect, consumed by the loader below to derive the full selection state.\r\n const [pendingDeepLinkRecordId, setPendingDeepLinkRecordId] = 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 // The shared react-query client — used to prime the resolved-record cache\r\n // from the already-loaded item list so opening an item doesn't flash the\r\n // editor's empty-state while a redundant `getRecordById` round-trips.\r\n const queryClient = useQueryClient();\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.\r\n //\r\n // Order policy:\r\n // • If the host passed `scopes`, render in the order they listed\r\n // (filtered to known top-level scopes — drill-downs like `variant` /\r\n // `batch` are stripped, and the deprecated `facet` is dropped).\r\n // • If the host omitted `scopes` entirely, fall back to the canonical\r\n // `TOP_LEVEL_SCOPES` order (collection → rule → product).\r\n //\r\n // v0.5 — `'facet'` is no longer a top-level tab. If a host still passes\r\n // it we drop it silently (the in-Rules `FacetBrowseFilter` covers the\r\n // same admin need). One deprecation warning per page load.\r\n const topLevelScopes = useMemo(() => {\r\n const requested = requestedScopes ?? [];\r\n if (requested.length > 0) {\r\n const seen = new Set<ScopeKind>();\r\n const ordered: ScopeKind[] = [];\r\n for (const s of requested) {\r\n if (!TOP_LEVEL_SCOPES.includes(s)) continue; // drops 'variant' / 'batch' / 'facet'\r\n if (seen.has(s)) continue;\r\n seen.add(s);\r\n ordered.push(s);\r\n }\r\n return ordered;\r\n }\r\n return [...TOP_LEVEL_SCOPES];\r\n }, [requestedScopes]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // contextScope-aware top-level scopes.\r\n //\r\n // When the host scopes this mount to a single product (`contextScope.productId`)\r\n // and uses the default `'strict'` mode, drop `'collection'` (Global) and\r\n // `'rule'` from the rail — those tabs target collection-wide records the\r\n // product inherits, not records owned by this product. `'expand'` keeps the\r\n // legacy behaviour for hosts that want the full rail anyway.\r\n // ---------------------------------------------------------------------------\r\n const productPinnedFromContext = !!contextScope?.productId;\r\n const effectiveTopLevelScopes = useMemo<ScopeKind[]>(() => {\r\n if (!productPinnedFromContext || contextScopeMode !== 'strict') return topLevelScopes;\r\n return topLevelScopes.filter((s) => s !== 'collection' && s !== 'rule');\r\n }, [productPinnedFromContext, contextScopeMode, topLevelScopes]);\r\n\r\n useEffect(() => {\r\n if (requestedScopes.includes('facet') && !WARNED_FACET_DEPRECATED) {\r\n WARNED_FACET_DEPRECATED = true;\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n '[RecordsAdminShell] The \"facet\" top-level scope was removed in 0.5.0. ' +\r\n 'Use the Rules tab\\'s built-in \"Browse by facet\" filter instead. ' +\r\n 'Drop \"facet\" (and any `defaultScope: \"facet\"`) from your `scopes` prop.',\r\n );\r\n }\r\n }, [requestedScopes]);\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 && effectiveTopLevelScopes.includes('product')) return 'product';\r\n if (defaultScope && effectiveTopLevelScopes.includes(defaultScope)) return defaultScope;\r\n // Honour the host's listed order: first scope wins. (When the host\r\n // omitted `scopes`, that's the canonical `collection`.)\r\n return effectiveTopLevelScopes[0] ?? 'product';\r\n }, [contextScope?.productId, defaultScope, effectiveTopLevelScopes]);\r\n\r\n const [activeScope, setActiveScope] = useState<ScopeKind>(initialScope);\r\n useEffect(() => { setActiveScope(initialScope); }, [initialScope]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Records-tab selection — used by the Rule and Global (collection-rung) tabs.\r\n //\r\n // We track the *record* (by UUID) that's open in the editor, not a ref\r\n // string. This is the canonical selection key everywhere in the shell —\r\n // anything that needs anchors derives them from `recordList.items` /\r\n // `editingTarget` rather than `parseRef`-ing a synthesised string.\r\n //\r\n // Sentinels:\r\n // - `null` — nothing selected; rail auto-selects on first load.\r\n // - `DRAFT_ID` — user clicked \"+ New rule\" / \"+ New global default\";\r\n // the editor mounts against `draftKind` instead.\r\n // - any other — the UUID of an existing saved record.\r\n // ---------------------------------------------------------------------------\r\n const [selectedRecordId, setSelectedRecordId] = useState<string | null>(null);\r\n /** Distinguishes the draft kind when `selectedRecordId === DRAFT_ID`. */\r\n const [draftKind, setDraftKind] = useState<'rule' | 'global' | 'item' | null>(null);\r\n\r\n // ---------------------------------------------------------------------------\r\n // New-rule wizard state. When the user clicks \"+ New rule\" we open a\r\n // two-step inline wizard in the right pane (configure rule → configure\r\n // record) instead of dropping them straight into the editor.\r\n //\r\n // - `ruleWizardStep === 1` — picking facet conditions (FacetRuleEditor).\r\n // - `ruleWizardStep === 2` — singleton: editor mounted with the rule\r\n // pre-seeded; collection: empty item list with\r\n // a \"Create your first item\" CTA.\r\n // - `ruleWizardStep === null` — wizard not active.\r\n //\r\n // The rule is held in `ruleWizardRule` until the first record under it is\r\n // saved; the SDK never sees it until then (the rule rides as that\r\n // record's facetRule).\r\n // ---------------------------------------------------------------------------\r\n const [ruleWizardStep, setRuleWizardStep] = useState<1 | 2 | null>(null);\r\n const [ruleWizardRule, setRuleWizardRule] = useState<import('./../data/sdkTypes').FacetRule | null>(null);\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 || !!helpUrl;\r\n return showHeader === true || (showHeader !== false && headerCustomised);\r\n }, [showHeader, title, subtitle, headerIcon, headerActions, showStats, statsItems, statsTitle, statsIcon, helpUrl]);\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 // Browser data + filter state — owned by `useShellBrowser`. This wraps the\r\n // four browse hooks (records / facets / products / product-children) and\r\n // the rail's filter state (search, status, rule filters, facet browse).\r\n // Selection (selectedRecordId / selectedProductId / draftKind / drill tab)\r\n // intentionally still lives in the shell.\r\n // ---------------------------------------------------------------------------\r\n const browser = useShellBrowser({\r\n ctx, SL, collectionId,\r\n activeScope, contextScope,\r\n probeIsLoading: probe.isLoading,\r\n isCollection: cardinality === 'collection',\r\n selectedProductId, drillTab,\r\n classify: classify as ((r: RecordSummary) => RecordStatus) | undefined,\r\n });\r\n const {\r\n search, setSearch,\r\n filter, setFilter,\r\n ruleFilters, setRuleFilters,\r\n facetBrowseFilter, setFacetBrowseFilter,\r\n productBrowse, recordList, facetBrowse,\r\n variantChildren, batchChildren,\r\n } = browser;\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 // Rule / Global tabs — auto-select the first record so the right pane\r\n // isn't a permanent empty state. New record creation (rule / global /\r\n // item draft) sets the selection explicitly (see `onCreateRule` /\r\n // `onCreateGlobal` below) and bypasses this effect by leaving\r\n // `selectedRecordId === DRAFT_ID`.\r\n useEffect(() => {\r\n if (activeScope !== 'rule' && activeScope !== 'collection') return;\r\n if (selectedRecordId !== null) return; // user already picked / drafted\r\n // Collection-cardinality + Global tab: the right pane is the multi-item\r\n // list view (driven by `editingScope` resolving to the collection root),\r\n // not an editor. Leave selection null and let the global-all sentinel\r\n // row drive the rail.\r\n if (activeScope === 'collection' && cardinality === 'collection') {\r\n return;\r\n }\r\n const first = recordList.items[0];\r\n if (first?.id) setSelectedRecordId(first.id);\r\n }, [activeScope, selectedRecordId, recordList.items, cardinality]);\r\n\r\n // Selection bits that piggyback on a scope change. Filter resets are\r\n // handled inside `useShellBrowser`; the records-driven tabs share\r\n // `selectedRecordId`, so we clear it here to prevent a Rule selection\r\n // from being interpreted as a Global selection.\r\n useEffect(() => {\r\n setSelectedRecordId(null);\r\n setDraftKind(null);\r\n }, [activeScope]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Build the parsed scope (anchors) for the user's current browse selection.\r\n //\r\n // In singleton mode this also describes the record being edited — the\r\n // resolver walks the inheritance chain to find the winning record and the\r\n // editor saves at this scope. In collection mode this is the *folder*\r\n // that holds items; the actual editing target is the per-item record\r\n // identified by `selectedRecordId` (a UUID, not a ref string).\r\n //\r\n // Source of anchors, by tab:\r\n // - rule / global, saved record selected → anchors from the record's\r\n // summary in `recordList.items`.\r\n // - rule / global, draft (`selectedRecordId === DRAFT_ID`) → empty\r\n // anchors at the collection root (drafts at this level apply globally\r\n // until the user pins them via the Targeting / Applies-to UI).\r\n // - product → drill-down state (selectedProductId, +variant/+batch).\r\n // ---------------------------------------------------------------------------\r\n const editingScope: ParsedRef | null = useMemo(() => {\r\n // Records-driven tabs (rule, collection/global).\r\n if (activeScope === 'rule' || activeScope === 'collection') {\r\n // New-rule wizard, collection cardinality: while the user is on\r\n // step 2 the rule isn't a saved record yet (selectedRecordId stays\r\n // null so the wizard drives the right pane). We still need an\r\n // anchor scope so `useCollectionItems` can query items under the\r\n // pending rule, the SiblingRail can mount once the user opens the\r\n // first item draft, and `editingTargetScope` can resolve. Synthesise\r\n // the same `rule:__draft__` ParsedRef we use for singleton drafts.\r\n if (activeScope === 'rule' && ruleWizardStep === 2 && selectedRecordId === null) {\r\n return { ...parseRef(''), kind: 'rule', raw: 'rule:__draft__' } as ParsedRef;\r\n }\r\n if (selectedRecordId === null) {\r\n // Collection-cardinality + Global tab: there is no per-record\r\n // selection because the right pane is the multi-item list view.\r\n // Anchor the editing scope at the collection root so the\r\n // `ItemListView` (which renders when `editingScope` is non-null)\r\n // actually gets a chance to mount and `useCollectionItems` gets\r\n // a non-null scope to query against.\r\n if (activeScope === 'collection' && cardinality === 'collection') {\r\n return parseRef('');\r\n }\r\n return null;\r\n }\r\n if (selectedRecordId === DRAFT_ID) {\r\n // Rule drafts surface as a synthetic `rule` scope so the editor\r\n // resolver / RecordTargeting react to it as a rule (kind === 'rule')\r\n // even though the rule itself isn't persisted yet. The transient id\r\n // never reaches the SDK — `useRecordEditor.save()` upserts a fresh\r\n // record carrying the assembled facetRule. Other drafts (global,\r\n // item) keep starting at the collection root.\r\n if (draftKind === 'rule') {\r\n return { ...parseRef(''), kind: 'rule', raw: 'rule:__draft__' } as ParsedRef;\r\n }\r\n return parseRef('');\r\n }\r\n // Saved record — pull anchors straight off its summary.\r\n const hit = recordList.items.find((it) => it.id === selectedRecordId);\r\n if (!hit) return null; // list still loading or item filtered out\r\n return hit.scope;\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, cardinality, selectedRecordId, draftKind, ruleWizardStep, recordList.items, 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 // - `editingTargetScope` — anchors the editor + resolver point at. In\r\n // singleton mode this equals `editingScope`. In\r\n // collection mode the per-item record carries\r\n // the same anchors as its containing scope —\r\n // item identity is the record's UUID, not an\r\n // additional anchor — so we still pass the\r\n // folder anchors here. Item identity is carried\r\n // separately via `selectedItemId` / `resolved.recordId`\r\n // / `EditorContext.recordId`; hosts must not parse\r\n // `scope.raw` to infer selection.\r\n // - `editingItemRecordId` — the record UUID currently open in the editor\r\n // (collection mode only). `null` when the right\r\n // pane shows the item list view, `DRAFT_ID` for\r\n // an unsaved item draft.\r\n // ---------------------------------------------------------------------------\r\n const isCollection = cardinality === 'collection';\r\n\r\n const editingItemRecordId: string | null = isCollection ? selectedItemId : null;\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 // When the editing scope is a rule, items belonging to that rule are\r\n // records carrying the *same* facetRule (anchors are typically empty\r\n // and would otherwise collide with global records). Look up the rule's\r\n // facetRule from the selected record's summary so `useCollectionItems`\r\n // can match by rule equality instead of by anchors.\r\n facetRule: editingScope?.kind === 'rule'\r\n ? (recordList.items.find((it) => it.id === selectedRecordId)?.facetRule ?? null)\r\n : null,\r\n enabled: isCollection,\r\n });\r\n\r\n const editingTargetScope: ParsedRef | null = useMemo(() => {\r\n if (!editingScope) return null;\r\n if (!isCollection || !editingItemRecordId) return editingScope;\r\n return {\r\n ...editingScope,\r\n itemId: editingItemRecordId,\r\n raw: editingScope.raw\r\n ? `${editingScope.raw}/item:${editingItemRecordId}`\r\n : `item:${editingItemRecordId}`,\r\n };\r\n }, [editingScope, isCollection, editingItemRecordId]);\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 // 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, recordId: 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 // URL surface:\r\n // - `recordId` → UUID of an open record. We load it by id, then derive\r\n // the rail/scope state from its anchors and `facetRule`.\r\n // - `scope` → anchor scope ref (no synthetic `rule:`/`item:`\r\n // segments). Used when no record is open.\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (!deepLinkState.enabled) return;\r\n const { recordId, scope, view } = deepLinkState.urlState;\r\n const sig = `${recordId ?? ''}|${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 // Honour `scope` for the rail landing. The id-primary record open is\r\n // handled by `pendingDeepLinkRecordId` further down — once the record\r\n // loads, we re-derive scope from its anchors and re-route. Until then\r\n // the rail follows whatever `scope` carries.\r\n const railRef: string = scope ?? '';\r\n const itemId: string | null = null; // recordId path drives item open\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 // Legacy deep link from before 0.5 — the facet tab is gone, so\r\n // land on Rules and pre-fill the \"Browse by facet\" filter so the\r\n // user gets equivalent context. We deliberately don't try to map\r\n // the facet ref onto a record selection: in 0.5 facet rows are a\r\n // filter, not a selectable scope.\r\n if (activeScope !== 'rule' && topLevelScopes.includes('rule')) setActiveScope('rule');\r\n if (parsed.facetValue) {\r\n setFacetBrowseFilter({ facetKey: parsed.facetId, facetValue: parsed.facetValue });\r\n }\r\n if (selectedRecordId !== null) setSelectedRecordId(null);\r\n } else {\r\n // Empty rail ref — collection root. Clear any record 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 (selectedRecordId !== null) setSelectedRecordId(null);\r\n }\r\n\r\n // Stash the URL-supplied recordId so the loader effect below can fetch\r\n // it and derive the full selection state.\r\n setPendingDeepLinkRecordId(recordId ?? null);\r\n if (!recordId && selectedItemId !== null) {\r\n // Ignore restore snapshots that would immediately clear a freshly opened\r\n // collection item before the adapter/state round-trip settles.\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdminShell] preserving selected item during restore without recordId', {\r\n selectedItemId,\r\n scope,\r\n view,\r\n });\r\n }\r\n void itemId;\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 // Id-primary path: when the user has selected a saved record by UUID\r\n // (records-driven tabs, deep-link by `?recordId=`), bypass the\r\n // inheritance chain and load that exact row. Drafts (`DRAFT_ID`) and\r\n // pinned-anchor tabs (Products) leave `recordId` undefined so the\r\n // resolver runs `match()` against the anchors above.\r\n //\r\n // In collection-cardinality mode the per-item UUID lives in\r\n // `selectedItemId` (set by the right-pane item list onOpen handler),\r\n // not `selectedRecordId`. Without this branch the resolver would\r\n // fall back to anchor-based `match()` at the collection root and the\r\n // editor would mount against `null` data — surfacing as the host's\r\n // \"Select a {noun} from the list to edit\" placeholder.\r\n recordId:\r\n isCollection && selectedItemId && !isDraftId(selectedItemId)\r\n ? selectedItemId\r\n : (selectedRecordId && !isDraftId(selectedRecordId))\r\n ? selectedRecordId\r\n : undefined,\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 // ---------------------------------------------------------------------------\r\n // Editor session — replaces the legacy useRecordEditor. The bridge takes\r\n // a stable EditorTargetSpec describing what we're editing right now and\r\n // returns an EditorContext-shaped object so the rest of the shell (and\r\n // RecordEditor / RecordTargeting downstream) stay unchanged in this pass.\r\n //\r\n // Identity is owned by the EditorStore via SelectionController — the\r\n // store decides whether to focus an existing alive editor or mint a new\r\n // one. Resolver results are pushed in via hydrateFromResolver and never\r\n // clobber a dirty editor.\r\n // ---------------------------------------------------------------------------\r\n const editorTargetSpec: EditorTargetSpec | null = useMemo(() => {\r\n if (!editingTargetScope) return null;\r\n const initialFacetRule = editingTargetScope.kind === 'rule'\r\n ? (ruleWizardStep === 2 && ruleWizardRule\r\n ? ruleWizardRule\r\n : (resolved.facetRule ?? { all: [] }))\r\n : (ruleWizardStep === 2 && ruleWizardRule && isCollection && !!selectedItemId\r\n ? ruleWizardRule\r\n : null);\r\n const label = deriveDraftLabel\r\n ? deriveDraftLabel(resolved.data as TData, editingTargetScope)\r\n : undefined;\r\n return {\r\n scope: editingTargetScope,\r\n recordId: resolved.recordId,\r\n // Collection-cardinality item drafts must `create` (insert a new\r\n // row) instead of upsert — multiple items can share the same scope\r\n // + recordType, so an upsert would collide on the server's dedupe\r\n // key. Flip on whenever the right pane shows an item that hasn't\r\n // been saved yet (no resolved.recordId).\r\n createMode: isCollection && !!selectedItemId && !resolved.recordId,\r\n ref: editingTargetScope.kind === 'rule' ? editingTargetScope.raw : undefined,\r\n initialFacetRule,\r\n label,\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n editingTargetScope?.raw, editingTargetScope?.kind,\r\n resolved.recordId, resolved.facetRule,\r\n isCollection, selectedItemId,\r\n ruleWizardStep, ruleWizardRule,\r\n ]);\r\n\r\n const editorCtx = useEditorBridge<TData>({\r\n target: editorTargetSpec,\r\n resolved: {\r\n data: resolved.data,\r\n source: resolved.source,\r\n sourceRef: resolved.sourceRef,\r\n recordId: resolved.recordId,\r\n parentValue: resolved.parentValue,\r\n facetRule: resolved.facetRule,\r\n },\r\n defaultData,\r\n onSaved: () => {\r\n onTelemetry?.({ type: 'record.save', recordType, ref: editingTargetScope?.raw ?? '', isCreate: resolved.source !== 'self' });\r\n // First save inside the new-rule wizard tears it down: the rule\r\n // now exists as a real record (singleton) or as the targeting on\r\n // the just-saved first item (collection). Subsequent edits go\r\n // through the normal selection path.\r\n if (ruleWizardStep !== null) {\r\n setRuleWizardStep(null);\r\n setRuleWizardRule(null);\r\n setDraftKind(null);\r\n }\r\n refetchAll();\r\n },\r\n onDeleted: () => {\r\n onTelemetry?.({ type: 'record.delete', recordType, ref: editingTargetScope?.raw ?? '' });\r\n if (isCollection && selectedItemId) {\r\n setSelectedItemId(null);\r\n } else if (drillTab === 'variant') {\r\n setSelectedVariantId(undefined);\r\n } else if (drillTab === 'batch') {\r\n setSelectedBatchId(undefined);\r\n }\r\n refetchAll();\r\n },\r\n });\r\n\r\n // ---------------------------------------------------------------------------\r\n // Unsaved guards — browser beforeunload + iframe parent message + nav guard\r\n // ---------------------------------------------------------------------------\r\n useUnsavedGuard({\r\n isDirty: editorCtx.isDirty,\r\n label: recordType,\r\n disableBeforeUnload,\r\n // In `keep` mode we don't want the host iframe to pop its own native\r\n // confirm — the banner is the canonical surface. Hosts on `prompt` /\r\n // `autosave` opt back into platform notifications.\r\n disableParentMessage: dirtyStrategy === 'keep',\r\n });\r\n\r\n // Themed confirm dialog used for in-app navigation away from a dirty editor.\r\n // Replaces window.confirm() so we don't get the host iframe's \"An embedded\r\n // page at … says\" framing and so the popup matches the shell chrome.\r\n const dirtyConfirm = useConfirmDialog();\r\n\r\n // ---------------------------------------------------------------------------\r\n // Shell-level dirty-draft registry — drives the multi-record \"N unsaved •\r\n // Save all\" tray and the sequential save-all progress overlay. The active\r\n // editor registers/clears its draft via `useRecordEditor`; the shell only\r\n // *reads* the store here for tray rendering and Save-all orchestration.\r\n // ---------------------------------------------------------------------------\r\n const dirtyOverview = useDirtyOverview();\r\n const editorSelection = useEditorSelection();\r\n const dirtyItems = dirtyOverview.items;\r\n // dirtyKeys / errorKeys are still consumed by SiblingRail + RecordList to\r\n // mark rows. They expect a Set of recordIds OR scope.raw fragments — we\r\n // emit both so the sidebar matches whether a row knows its recordId yet\r\n // or only its scope ref.\r\n const dirtyKeys = useMemo<Set<string>>(() => {\r\n const s = new Set<string>();\r\n for (const it of dirtyItems) {\r\n if (it.status === 'saved') continue;\r\n if (it.recordId) s.add(it.recordId);\r\n if (it.scope?.raw) s.add(it.scope.raw);\r\n }\r\n return s;\r\n }, [dirtyItems]);\r\n const errorKeys = useMemo<Set<string>>(() => {\r\n const s = new Set<string>();\r\n for (const it of dirtyItems) {\r\n if (it.status !== 'error') continue;\r\n if (it.recordId) s.add(it.recordId);\r\n if (it.scope?.raw) s.add(it.scope.raw);\r\n }\r\n return s;\r\n }, [dirtyItems]);\r\n const [saveAllOpen, setSaveAllOpen] = useState(false);\r\n\r\n // Shared handlers used by both the header pill and the (overflow) tray\r\n // so the two surfaces stay behaviourally identical.\r\n const handleSaveAll = () => setSaveAllOpen(true);\r\n const handleDiscardAll = () => {\r\n // Single source of truth: the EditorStore. discardAll resets every\r\n // dirty/errored editor back to its baseline. The active editor's\r\n // visible value flips back automatically because it reads from the\r\n // store. No separate clearAll() needed — clean editors aren't pinned\r\n // and will fall out of the LRU pool as new selections arrive.\r\n dirtyOverview.discardAll();\r\n };\r\n\r\n // The shell decides between two surfaces for unsaved controls:\r\n // • inline pill in AdminPageHeader.actions — the common case\r\n // • full-width UnsavedTray banner — overflow (5+ drafts or any error)\r\n // Computed once here so the header render and the tray render agree.\r\n const showHeaderUnsavedPill =\r\n dirtyStrategy === 'keep' && canRenderInHeader(dirtyItems);\r\n const showTrayBanner =\r\n dirtyStrategy === 'keep'\r\n && !showHeaderUnsavedPill\r\n && dirtyItems.length > 0;\r\n\r\n // Compose the header `actions` slot: pill (when shown) + whatever the host\r\n // passed. The pill renders to the left so it stays adjacent to the page\r\n // title, with host actions (e.g. \"+ New\") to its right.\r\n const composedHeaderActions = useMemo(() => {\r\n if (!showHeaderUnsavedPill) return headerActions;\r\n return (\r\n <>\r\n <HeaderUnsavedPill\r\n items={dirtyItems}\r\n isSaving={saveAllOpen}\r\n onSaveAll={handleSaveAll}\r\n onDiscardAll={handleDiscardAll}\r\n saveLabel={actionLabels?.save ?? i18n.save}\r\n discardLabel={actionLabels?.discard ?? i18n.discard}\r\n saveAllLabel={actionLabels?.saveAll ?? i18n.saveAll}\r\n discardAllLabel={actionLabels?.revertAll ?? i18n.discardAll}\r\n countTemplate={i18n.unsavedTrayCount}\r\n SaveIcon={actionIcons?.save}\r\n DiscardIcon={actionIcons?.discard}\r\n />\r\n {headerActions}\r\n </>\r\n );\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n showHeaderUnsavedPill, headerActions, dirtyItems, saveAllOpen,\r\n actionLabels, actionIcons, i18n,\r\n ]);\r\n\r\n // The rail's onLeftSelect (used by row-paste to focus the destination\r\n // before the deferred paste runs) is defined further down — capture\r\n // the latest reference via a ref so the clipboard hook can call it.\r\n const onLeftSelectRef = useRef<((item: RecordSummary) => void) | 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 // CSV import/export — extracted into useShellCsvBulk.\r\n const csvBulk = useShellCsvBulk<TData>({\r\n csvSchema,\r\n recordType,\r\n label,\r\n items: recordList.items as RecordSummary<TData>[],\r\n ctx,\r\n refetchAll,\r\n onTelemetry,\r\n });\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 === '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, selectedProductId, productBrowse.items]);\r\n\r\n const editorHeaderSubtitle: string | undefined = useMemo(() => {\r\n if (!editingScope) return undefined;\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]);\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 — Copy / Paste across scopes for this `recordType`.\r\n // Owned by the dedicated useShellClipboard hook (see hooks/useShellClipboard.tsx)\r\n // which encapsulates the underlying store, paste-confirm dialog, deferred\r\n // row-paste effect, and toast notice state.\r\n // ---------------------------------------------------------------------------\r\n const shellClipboard = useShellClipboard<TData>({\r\n enabled: !!enableClipboard,\r\n appId,\r\n recordType,\r\n i18n,\r\n editorCtx,\r\n editingScope,\r\n editorHeaderLabel,\r\n isCollection,\r\n selectedItemId,\r\n selectedRecordId,\r\n resolved: { source: resolved.source, recordId: resolved.recordId },\r\n onTelemetry,\r\n onCopyOverride,\r\n onPasteOverride,\r\n onLeftSelectRef,\r\n });\r\n const editorClipboard = shellClipboard.editorClipboard;\r\n const rowClipboard = shellClipboard.rowClipboard;\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 if (!baseScopeRef && id.startsWith('item:')) return id;\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 // eslint-disable-next-line no-console\r\n console.info('[RecordsAdminShell] item open requested', {\r\n itemId,\r\n scopeRef: baseScopeRef,\r\n previousSelectedItemId: selectedItemId,\r\n });\r\n // Prime the resolved-record cache from the row we already loaded in\r\n // `collectionItems`. Without this, the resolver mounts with no data\r\n // and the editor briefly renders against `null` (its empty/default\r\n // state) while `getRecordById` round-trips — a jarring blank-then-\r\n // populate flash on every item click. The query stays live and will\r\n // still reconcile against the server in the background, so freshness\r\n // isn't sacrificed.\r\n if (!isDraftId(itemId)) {\r\n const row = collectionItems.items.find((it) => it.itemId === itemId || it.id === itemId);\r\n if (row && row.data !== undefined) {\r\n const cacheKey = resolvedRecordQueryKey({\r\n collectionId, appId, recordType,\r\n productId: editingScope?.productId,\r\n variantId: editingScope?.variantId,\r\n batchId: editingScope?.batchId,\r\n facetId: editingScope?.facetId,\r\n facetValue: editingScope?.facetValue,\r\n proofId: editingScope?.proofId,\r\n recordId: itemId,\r\n withParent: true,\r\n });\r\n // Only seed if there's nothing in the cache yet — never clobber a\r\n // fresher value the resolver may have just landed.\r\n if (queryClient.getQueryData(cacheKey) === undefined) {\r\n queryClient.setQueryData(cacheKey, {\r\n data: row.data,\r\n source: 'self',\r\n sourceRef: row.ref || undefined,\r\n recordId: itemId,\r\n facetRule: row.facetRule ?? null,\r\n });\r\n }\r\n }\r\n }\r\n setSelectedItemId(itemId);\r\n onTelemetry?.({ type: 'item.open', recordType, scopeRef: baseScopeRef, itemId });\r\n // `itemId` is the record's UUID once saved (per useCollectionItems);\r\n // emit it directly as the deep-link recordId.\r\n deepLinkState.emit({ recordId: itemId, scope: baseScopeRef || null }, 'record.open');\r\n });\r\n }, [\r\n isCollection, runWithGuard, onTelemetry, recordType, baseScopeRef,\r\n deepLinkState, buildItemUrlValue, selectedItemId,\r\n collectionItems.items, queryClient, collectionId, appId, editingScope,\r\n ]);\r\n\r\n const onItemCreate = useCallback(() => {\r\n if (!isCollection) return;\r\n void runWithGuard(() => {\r\n // Item drafts have no UUID until first save — mint a unique synthetic\r\n // id (`draft:<uuid>`) so multiple drafts never collide and the literal\r\n // `__draft__` token never reaches host UI or `scope.raw`. Hosts that\r\n // want a stable client-side handle can supply `generateItemId`; the\r\n // shell still prefixes it so the draft never masquerades as a saved row.\r\n const id = coerceDraftItemId(generateItemId);\r\n setSelectedItemId(id);\r\n onTelemetry?.({ type: 'item.create', recordType, scopeRef: baseScopeRef });\r\n // Brand-new draft has no server id yet — clear `recordId` and rely on\r\n // `scope` to put the user back in the right rail context. The URL\r\n // gains a real `recordId` on first save.\r\n deepLinkState.emit({ recordId: null, scope: baseScopeRef || null }, 'record.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 if (isDraftId(itemId)) return; // unsaved draft — nothing on the server\r\n // `itemId` is the record's UUID — delete by id, no ref synthesis.\r\n if (onBeforeDelete) {\r\n const ok = await onBeforeDelete(editingScope ?? parseRef(''));\r\n if (!ok) return;\r\n }\r\n try {\r\n const { removeRecord } = await import('../data/records');\r\n await removeRecord(ctx, itemId);\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({ recordId: null }, 'record.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({ recordId: null }, 'record.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({ recordId: id, scope: baseScopeRef || null }, 'record.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 // Hide the item nav during the new-rule wizard — there is no saved\r\n // sibling list yet, so \"1 / N\" and prev/next would point at unrelated\r\n // items from the collection root.\r\n const itemNav = isCollection && selectedItemId && itemPosition && ruleWizardStep === null ? (\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 <EditorMountPool\r\n renderSlot={(slotId) => (\r\n <EditorPoolBody\r\n editorId={slotId}\r\n renderEditor={renderEditor as (ctx: EditorContext<unknown>) => ReactNode}\r\n />\r\n )}\r\n fallback={renderEditor(editorCtx)}\r\n />\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 // ---------------------------------------------------------------------------\r\n // Single-record collapse: when the host has scoped this mount to one product\r\n // (`contextScope.productId`) AND there's no variant/batch drill-down to\r\n // pick AND we've stripped the collection-wide tabs, the rail has nothing\r\n // to navigate. Hide it so the editor takes the whole pane. The host gets a\r\n // clean single-editor experience without having to configure anything.\r\n //\r\n // Caveat: in collection cardinality (FAQs / SOPs / recipes) the rail is\r\n // the *items* list under that product — keep it visible so users can pick\r\n // between items.\r\n // ---------------------------------------------------------------------------\r\n const railHidden = useMemo(() => {\r\n if (!productPinned) return false;\r\n if (contextScopeMode !== 'strict') return false;\r\n if (cardinality === 'collection') return false;\r\n if (effectiveTopLevelScopes.length > 1) return false;\r\n if (drillVariantsAllowed || drillBatchesAllowed) return false;\r\n return true;\r\n }, [\r\n productPinned, contextScopeMode, cardinality,\r\n effectiveTopLevelScopes.length, drillVariantsAllowed, drillBatchesAllowed,\r\n ]);\r\n\r\n // Records-driven tabs (rule, global) render a flat list — cards/grids\r\n // don't add value when each row is a record selector. Force `list` and\r\n // hide the presentation switcher unless we're on the products tab.\r\n const effectivePresentation: RecordPresentation = isProductTab ? presentation : 'list';\r\n const showPresentationSwitcher = isProductTab && presentations.length > 1;\r\n\r\n // Records-driven tabs no longer auto-group by facet — the legacy facet\r\n // rail is gone. Hosts that want grouping (e.g. by `category`) can still\r\n // pass `groupBy` directly.\r\n const effectiveGroupBy = groupBy;\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 // Open the two-step inline wizard. We deliberately do NOT mount the\r\n // editor yet — the rail / collection-root item list would otherwise\r\n // surface and confuse the admin (they asked for \"new rule\", not\r\n // \"edit existing global record\"). The editor is composed on Step 2\r\n // once the rule has been configured.\r\n if (activeScope !== 'rule') setActiveScope('rule');\r\n setSelectedRecordId(null);\r\n setSelectedItemId(null);\r\n setDraftKind('rule');\r\n setRuleWizardRule({ all: [] });\r\n setRuleWizardStep(1);\r\n });\r\n }, [runWithGuard, activeScope]);\r\n\r\n const onCancelRuleWizard = useCallback(() => {\r\n setRuleWizardStep(null);\r\n setRuleWizardRule(null);\r\n setSelectedRecordId(null);\r\n setSelectedItemId(null);\r\n setDraftKind(null);\r\n }, []);\r\n\r\n const onRuleWizardNext = useCallback(() => {\r\n // Step 1 → Step 2. In singleton mode we mount the editor against the\r\n // synthetic rule draft scope. In collection mode we keep the right\r\n // pane on the wizard's \"create your first item\" CTA — the user clicks\r\n // it to open an item draft.\r\n if (cardinality === 'collection') {\r\n setRuleWizardStep(2);\r\n // Stay with selectedRecordId === null so the right pane defers to\r\n // the wizard rather than the item list.\r\n } else {\r\n setRuleWizardStep(2);\r\n setSelectedRecordId(DRAFT_ID);\r\n }\r\n }, [cardinality]);\r\n\r\n const onRuleWizardBack = useCallback(() => {\r\n setRuleWizardStep(1);\r\n setSelectedRecordId(null);\r\n setSelectedItemId(null);\r\n }, []);\r\n\r\n const onRuleWizardCreateItem = useCallback(() => {\r\n // Collection mode only: open an item draft under the new rule. The\r\n // wizard rule is seeded into the editor's `initialFacetRule` so the\r\n // first save carries the rule onto the item record.\r\n if (!isCollection) return;\r\n const id = coerceDraftItemId(generateItemId);\r\n setSelectedItemId(id);\r\n }, [isCollection, generateItemId]);\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 [recordList.items],\r\n );\r\n // The \"+ New global default\" CTA only makes sense in singleton mode — there\r\n // can be at most one record at the collection root, and it acts as the\r\n // inherited default. In collection-cardinality mode (recipes / SOPs / FAQs)\r\n // there is no notion of \"the global default\": the Global tab is just the\r\n // bucket of items saved at the collection root, so the CTA would be\r\n // misleading. The right pane's `+ New {item}` button covers item creation.\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 // Global default draft — collection root, no facetRule, no anchors.\r\n setSelectedRecordId(DRAFT_ID);\r\n setDraftKind('global');\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 // Apply the shared \"Browse by facet\" filter on top of either tab's list.\r\n // For rule records we inspect the saved `facetRule` and keep rules whose\r\n // clauses would match the picked facet/value (clause facetKey matches AND\r\n // anyOf includes the value). For pinned-scope records on the Global tab\r\n // (singleton mode) we match by the record's own scope. Records that\r\n // can't be evaluated (no rule, no scope) drop out — they wouldn't apply\r\n // to a product carrying the picked facet either.\r\n const applyFacetBrowseFilter = useCallback(\r\n (items: RecordSummary[]): RecordSummary[] => {\r\n if (!facetBrowseFilter) return items;\r\n const { facetKey, facetValue } = facetBrowseFilter;\r\n return items.filter((r) => {\r\n const rule = (r as { facetRule?: { all?: { facetKey: string; anyOf: string[] }[] } | null }).facetRule;\r\n if (rule?.all?.length) {\r\n return rule.all.some((c) => c.facetKey === facetKey && (c.anyOf ?? []).includes(facetValue));\r\n }\r\n // Fallback: match pinned-scope records by their own facet.\r\n if (r.scope.facetId === facetKey && r.scope.facetValue === facetValue) return true;\r\n return false;\r\n });\r\n },\r\n [facetBrowseFilter],\r\n );\r\n\r\n // Build the facet vocabulary in the shape FacetBrowseFilter expects. We\r\n // rely on `useFacetBrowse`'s mergedItems for the list of values per facet —\r\n // each row is a `{facet}:{value}` pair, so we group by `subtitle` (facet\r\n // name). Order is whatever the facets API returned.\r\n const facetBrowseFacets: FacetBrowseFacet[] = useMemo(() => {\r\n if (!facetBrowse.items.length) return [];\r\n const byKey = new Map<string, FacetBrowseFacet>();\r\n for (const it of facetBrowse.items) {\r\n const key = it.scope.facetId;\r\n const value = it.scope.facetValue;\r\n if (!key || !value) continue;\r\n const facetLabel = it.subtitle ?? key;\r\n const valueLabel = it.label ?? value;\r\n const existing = byKey.get(key);\r\n if (existing) {\r\n if (!existing.values.some((v) => v.key === value)) {\r\n existing.values.push({ key: value, label: valueLabel });\r\n }\r\n } else {\r\n byKey.set(key, { key, label: facetLabel, values: [{ key: value, label: valueLabel }] });\r\n }\r\n }\r\n return Array.from(byKey.values());\r\n }, [facetBrowse.items]);\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 // Collection-cardinality + Global tab: the rail has no records to show\r\n // (item-level records belong on the right). Without a `groupBy` callback,\r\n // surface a single auto-selected \"All items\" row so the rail isn't a\r\n // confusing empty pane. With `groupBy`, hosts can later light up category\r\n // grouping from the right-pane items; today we still render an All row so\r\n // there's always something selected.\r\n const collectionGlobalAllRow: RecordSummary = useMemo(\r\n () => ({\r\n id: null,\r\n ref: '',\r\n scope: parseRef(''),\r\n data: null,\r\n status: 'empty',\r\n label: i18n.itemsAllLabel,\r\n subtitle: collectionItems.items.length\r\n ? `${collectionItems.items.length} ${itemNoun}${collectionItems.items.length === 1 ? '' : 's'}`\r\n : undefined,\r\n }),\r\n [i18n.itemsAllLabel, collectionItems.items.length, itemNoun],\r\n );\r\n\r\n const leftItems = isProductTab\r\n ? productListItems\r\n : isRuleTab\r\n ? applyFacetBrowseFilter(filteredRuleItems)\r\n : isGlobalTab && isCollection\r\n ? [collectionGlobalAllRow]\r\n : isRecordsTab\r\n ? applyFacetBrowseFilter(recordList.items)\r\n : [];\r\n const leftLoading = isProductTab\r\n ? (!productPinned && productBrowse.isLoading)\r\n : isRecordsTab\r\n ? (recordList.isLoading || probe.isLoading)\r\n : false;\r\n const leftError = isProductTab\r\n ? productBrowse.error\r\n : isRecordsTab\r\n ? recordList.error\r\n : null;\r\n // RecordList highlights the active row two ways:\r\n // - Records-driven tabs: by UUID (`selectedId` matches `RecordSummary.id`).\r\n // - Pinned-anchor tabs (Products today; Facets when added): by anchor key\r\n // (`selectedAnchorKey` matches `RecordSummary.ref`, a synthesised\r\n // display-only string). We don't have a UUID for \"the selected\r\n // product\" — products aren't AppRecords.\r\n const leftSelectedId = isProductTab\r\n ? undefined\r\n : (selectedRecordId && selectedRecordId !== DRAFT_ID ? selectedRecordId : undefined);\r\n const leftSelectedAnchorKey = isProductTab\r\n ? (selectedProductId ? buildRef({ productId: selectedProductId }) : undefined)\r\n : undefined;\r\n // Dirty-row indicator. For records-driven tabs this is the editor's\r\n // current record UUID. For product/facet tabs the editor edits an anchor,\r\n // so we fall back to anchor matching via `editingScope.raw`.\r\n const dirtyId = !editorCtx.isDirty\r\n ? undefined\r\n : (selectedRecordId && selectedRecordId !== DRAFT_ID ? selectedRecordId : undefined);\r\n const dirtyAnchorKey = !editorCtx.isDirty\r\n ? undefined\r\n : (isProductTab ? editingScope?.raw : undefined);\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 // Records-driven tabs — select by UUID. Drafts are cleared because\r\n // clicking a saved row is an explicit \"open this one instead\".\r\n setSelectedRecordId(item.id ?? null);\r\n setDraftKind(null);\r\n // Selecting an existing rule cancels an in-flight new-rule wizard.\r\n if (ruleWizardStep !== null) {\r\n setRuleWizardStep(null);\r\n setRuleWizardRule(null);\r\n }\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 {shellClipboard.confirmDialog}\r\n {shellClipboard.toast}\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 {/* When the header is rendering and the host opted into the inline\r\n * `'header'` reopen affordance, AdminPageHeader owns the intro card\r\n * (renders it directly under the title row). Otherwise the shell\r\n * renders the intro itself above the rail/editor split. */}\r\n {intro && !dismissed && !(headerWillRender && resolvedReopenAffordance === 'header') && (\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 reopenLabel = intro?.reopenLabel ?? `How ${label.toLowerCase()} works`;\r\n // Hand the intro to AdminPageHeader only when the host wants the\r\n // `'header'` affordance — that way it renders the dismissible card\r\n // inline under the title and the `?` reopen button to the right.\r\n const headerIntro = (intro && resolvedReopenAffordance === 'header') ? {\r\n title: intro.title,\r\n body: intro.body,\r\n dismissed,\r\n onDismiss: () => { dismiss(); onTelemetry?.({ type: 'intro.dismiss', recordType }); },\r\n onReopen: undismiss,\r\n reopenLabel,\r\n } : undefined;\r\n return (\r\n <ShellHeader\r\n title={title ?? label ?? recordType ?? ''}\r\n subtitle={subtitle}\r\n headerIcon={headerIcon}\r\n headerActions={composedHeaderActions}\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 helpUrl={helpUrl}\r\n helpLabel={helpLabel}\r\n intro={headerIntro}\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 {showTrayBanner && (\r\n <UnsavedTray\r\n items={dirtyItems}\r\n isSaving={saveAllOpen}\r\n onSaveAll={handleSaveAll}\r\n onDiscardAll={handleDiscardAll}\r\n onOpenItem={(it) => {\r\n // Selecting an item from the tray focuses the editor in the\r\n // pool (no remount) and jumps the rail to its record when\r\n // we already know the recordId.\r\n editorSelection.focus(it.editorId);\r\n if (it.recordId) {\r\n setSelectedRecordId(it.recordId);\r\n setDraftKind(null);\r\n }\r\n }}\r\n onJumpToError={() => {\r\n const first = dirtyItems.find((it) => it.status === 'error');\r\n if (!first) return;\r\n editorSelection.focus(first.editorId);\r\n if (first.recordId) {\r\n setSelectedRecordId(first.recordId);\r\n setDraftKind(null);\r\n }\r\n }}\r\n saveLabel={actionLabels?.save ?? i18n.save}\r\n discardLabel={actionLabels?.discard ?? i18n.discard}\r\n saveAllLabel={actionLabels?.saveAll ?? i18n.saveAll}\r\n discardAllLabel={actionLabels?.revertAll ?? i18n.discardAll}\r\n countTemplate={i18n.unsavedTrayCount}\r\n errorCountTemplate={i18n.unsavedTrayErrors}\r\n jumpToErrorLabel={i18n.saveAllJumpToError}\r\n SaveIcon={actionIcons?.save}\r\n DiscardIcon={actionIcons?.discard}\r\n />\r\n )}\r\n <SaveAllProgress\r\n open={saveAllOpen}\r\n items={dirtyItems}\r\n saveOne={dirtyOverview.saveOne}\r\n onClose={() => setSaveAllOpen(false)}\r\n onJumpToError={(it) => {\r\n editorSelection.focus(it.editorId);\r\n if (it.recordId) {\r\n setSelectedRecordId(it.recordId);\r\n setDraftKind(null);\r\n }\r\n }}\r\n i18n={{\r\n title: i18n.saveAllInProgress,\r\n successTitle: i18n.saveAllSuccess,\r\n errorTitle: i18n.saveAllErrorTitle,\r\n stop: i18n.saveAllStop,\r\n close: i18n.saveAllClose,\r\n retryFailed: i18n.saveAllRetryFailed,\r\n jumpToError: i18n.saveAllJumpToError,\r\n }}\r\n />\r\n </div>\r\n <div\r\n className=\"flex-1 grid border-t overflow-hidden\"\r\n style={{\r\n gridTemplateColumns: railHidden ? '1fr' : 'minmax(260px, 320px) 1fr',\r\n borderColor: 'hsl(var(--ra-border))',\r\n }}\r\n >\r\n {!railHidden && (\r\n <aside className=\"border-r overflow-hidden flex flex-col\" style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}>\r\n {/* Sibling rail mounts only outside the new-rule wizard. While the\r\n wizard is active there is no saved rule yet, so the items\r\n fetched against the placeholder rule scope fall back to the\r\n collection root and would surface unrelated rows in the rail. */}\r\n {isCollection && selectedItemId && collectionRailMode === 'siblings' && ruleWizardStep === null ? (\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 dirtyKeys={dirtyKeys}\r\n errorKeys={errorKeys}\r\n i18n={i18n}\r\n />\r\n ) : (\r\n <>\r\n <div className=\"p-2\">\r\n <ScopeTabs\r\n scopes={effectiveTopLevelScopes}\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 // Switching tabs cancels an in-flight new-rule wizard so\r\n // the user doesn't lose the unsaved rule silently.\r\n if (ruleWizardStep !== null) {\r\n setRuleWizardStep(null);\r\n setRuleWizardRule(null);\r\n setDraftKind(null);\r\n }\r\n setActiveScope(s);\r\n });\r\n }}\r\n loading={probe.isLoading}\r\n counts={{\r\n product: productBrowse.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 {/* Singleton-mode Global is a one-record tab — there is at most\r\n one row to show and \"search / browse by facet / no records\r\n yet\" all read as noise. Suppress the rail's search,\r\n presentation switcher, filter chips, browse-by-facet, and\r\n empty state. The \"+ New global default\" CTA above (when the\r\n record doesn't yet exist) plus the right pane carry the\r\n whole flow. */}\r\n {!(isGlobalTab && !isCollection) && (\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 {/* Status filter pills (Configured / Empty) describe facet-value\r\n coverage — the share of facet values that have a saved record.\r\n That story only lands on the facet rail in singleton mode. On\r\n the Rule and Global tabs the rail rows ARE records, so\r\n everything is \"configured\" by definition; in collection-\r\n cardinality mode the rail isn't records-driven at all. Hide in\r\n those cases to avoid meaningless 1/0 counters. */}\r\n {!isProductTab && !isRuleTab && !isGlobalTab && (\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 {/* Browse-by-facet filter — replaces the legacy \"Shared\" tab.\r\n Surfaced on Rules so admins can ask \"what would apply if a\r\n product had bagel = white?\". Hidden on Global in either\r\n cardinality mode: singleton-Global has at most one record\r\n (filtering is meaningless), and collection-Global rail is\r\n the synthetic All-items row. */}\r\n {isRuleTab && (\r\n <FacetBrowseFilter\r\n facets={facetBrowseFacets}\r\n value={facetBrowseFilter}\r\n onChange={setFacetBrowseFilter}\r\n isLoading={facetBrowse.isLoading}\r\n />\r\n )}\r\n {/* Collection-mode \"+ New\" lives in the right-pane toolbar now. */}\r\n </>\r\n )}\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto\">\r\n {/* Singleton-Global: skip the rail body entirely. The right\r\n pane shows either the editor (record exists) or an inert\r\n helper state matching the \"+ New global default\" CTA above. */}\r\n {isGlobalTab && !isCollection ? null : (\r\n <>\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 selectedId={leftSelectedId}\r\n selectedAnchorKey={leftSelectedAnchorKey}\r\n onSelect={onLeftSelect}\r\n dirtyId={dirtyId}\r\n dirtyAnchorKey={dirtyAnchorKey}\r\n dirtyKeys={dirtyKeys}\r\n errorKeys={errorKeys}\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 i18n={i18n}\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 </>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </aside>\r\n )}\r\n <main className=\"overflow-hidden\">\r\n {/* New-rule wizard takes over the right pane while active. */}\r\n {ruleWizardStep !== null && (\r\n <NewRuleWizard\r\n SL={SL}\r\n collectionId={collectionId}\r\n appId={appId}\r\n step={ruleWizardStep}\r\n rule={ruleWizardRule}\r\n onRuleChange={setRuleWizardRule}\r\n onCancel={onCancelRuleWizard}\r\n onNext={onRuleWizardNext}\r\n onBack={onRuleWizardBack}\r\n itemNoun={itemNoun}\r\n >\r\n {/* Step 2 body — singleton mode mounts the editor; collection\r\n mode shows the empty state until the user clicks \"Create\r\n your first item\". Once an item draft is open we mount the\r\n editor so the user can author the first item. */}\r\n {ruleWizardStep === 2 && !isCollection && editingTargetScope && renderEditorWithPreview()}\r\n {ruleWizardStep === 2 && isCollection && !selectedItemId && (\r\n <div className=\"h-full flex items-center justify-center px-6 py-10\">\r\n <div className=\"max-w-sm text-center space-y-3\">\r\n <h3\r\n className=\"text-base font-semibold m-0\"\r\n style={{ color: 'hsl(var(--ra-text))' }}\r\n >\r\n Create your first {itemNoun} for this rule\r\n </h3>\r\n <p\r\n className=\"text-sm m-0\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n The rule is set up. Now add the first {itemNoun} that should apply to every product matching it. You can add more later.\r\n </p>\r\n <button\r\n type=\"button\"\r\n onClick={onRuleWizardCreateItem}\r\n className=\"ra-btn\"\r\n data-variant=\"primary\"\r\n >\r\n <Plus aria-hidden=\"true\" className=\"w-4 h-4\" />\r\n <span>Create first {itemNoun}</span>\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n {ruleWizardStep === 2 && isCollection && !!selectedItemId && editingTargetScope && renderEditorWithPreview()}\r\n </NewRuleWizard>\r\n )}\r\n {/* Collection mode: scope selected, no item open → item list view. */}\r\n {ruleWizardStep === null && 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 cardSize={itemCardSize}\r\n i18n={i18n}\r\n />\r\n )}\r\n {ruleWizardStep === null && !isCollection && !editingScope && activeScope === 'product' && !selectedProductId && (\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 {ruleWizardStep === null && 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 {ruleWizardStep === null && !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 /** UUID of the highlighted row (matches `RecordSummary.id`). */\r\n selectedId?: 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 selectedId, 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} selectedId={selectedId} 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, hasError, 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 {hasError ? (\r\n <span\r\n title=\"Save failed\"\r\n aria-label=\"Save failed\"\r\n className=\"ra-error-pip absolute top-1.5 right-1.5\"\r\n />\r\n ) : isDirty && (\r\n <span\r\n title=\"Unsaved changes\"\r\n aria-label=\"Unsaved changes\"\r\n className=\"ra-status-dot ra-status-shared 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// useDirtyDraftStore — shell-level registry of unsaved record drafts.\r\n//\r\n// The single-record `useRecordEditor` only tracks dirtiness for the editor\r\n// that's currently mounted. As soon as the user clicks a different record\r\n// in the rail (in `keep` mode), the previous editor unmounts and its dirty\r\n// state would be lost. This store persists each draft in memory keyed by a\r\n// stable record key so the shell can:\r\n//\r\n// • show \"N records have unsaved changes • Save all\"\r\n// • re-seed the editor with the in-flight value when the user navigates\r\n// back to a previously-edited record\r\n// • run a sequential Save-all pass with per-record progress + errors\r\n//\r\n// In-memory only — does not persist across page reloads. Future iteration\r\n// can layer sessionStorage on top behind a flag.\r\n// =============================================================================\r\nimport {\r\n createContext, useCallback, useContext, useMemo, useRef,\r\n useSyncExternalStore, type ReactNode,\r\n} from 'react';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport type { RecordAnchors } from '../data/scopeBridge';\r\n\r\nexport type DirtyDraftStatus = 'dirty' | 'saving' | 'saved' | 'error';\r\n\r\nexport interface DirtyDraft {\r\n /** Stable key — recordId for saved rows, `draft:{kind}:{scope.raw}` otherwise. */\r\n key: string;\r\n /** Friendly label for the tray + per-record progress rows. */\r\n label: string;\r\n /** Optional secondary descriptor (e.g. scope kind / facet). */\r\n context?: string;\r\n /** ParsedRef.raw — used to re-select the record from the tray. */\r\n scopeRaw: string;\r\n /** When set, selecting this draft from the tray loads a saved row by id. */\r\n recordId?: string;\r\n /** Insertion order — drives the visual order in the tray + overlay. */\r\n order: number;\r\n /** Current value being edited. */\r\n value: unknown;\r\n /** Optional facet rule attached to the value. */\r\n facetRule: FacetRule | null;\r\n /** Last-saved baseline for the same record (for diff/discard). */\r\n baseline: unknown;\r\n baselineFacetRule: FacetRule | null;\r\n /** Whether this draft must be inserted (collection-cardinality items). */\r\n createMode: boolean;\r\n /** Anchor IDs for the save call. */\r\n scopeAnchors: RecordAnchors;\r\n /** Optional external ref (rule:{id}) to send with the save. */\r\n ref?: string;\r\n /** Save kind decided at draft creation time. */\r\n saveKind: 'update' | 'create' | 'upsert';\r\n status: DirtyDraftStatus;\r\n error?: unknown;\r\n /**\r\n * Performs the save against the SDK. Captured at draft creation time so\r\n * the overlay doesn't need access to the editor's resolver/ctx — keeps\r\n * the registry self-contained.\r\n */\r\n save: () => Promise<void>;\r\n}\r\n\r\ntype Listener = () => void;\r\n\r\nexport interface DirtyDraftStore {\r\n list(): DirtyDraft[];\r\n get(key: string): DirtyDraft | undefined;\r\n has(key: string): boolean;\r\n upsertDraft(input: Omit<DirtyDraft, 'order' | 'status'> & { order?: number; status?: DirtyDraftStatus }): void;\r\n setStatus(key: string, status: DirtyDraftStatus, error?: unknown): void;\r\n clearDraft(key: string): void;\r\n clearAll(): void;\r\n subscribe(listener: Listener): () => void;\r\n}\r\n\r\nconst createStore = (): DirtyDraftStore => {\r\n const map = new Map<string, DirtyDraft>();\r\n const listeners = new Set<Listener>();\r\n let nextOrder = 0;\r\n // Cached snapshot — useSyncExternalStore requires getSnapshot to return a\r\n // stable reference between mutations, otherwise React loops forever.\r\n let cachedList: DirtyDraft[] = [];\r\n const recompute = () => {\r\n cachedList = Array.from(map.values()).sort((a, b) => a.order - b.order);\r\n };\r\n const emit = () => {\r\n recompute();\r\n listeners.forEach((l) => l());\r\n };\r\n return {\r\n list: () => cachedList,\r\n get: (key) => map.get(key),\r\n has: (key) => map.has(key),\r\n upsertDraft(input) {\r\n const existing = map.get(input.key);\r\n const order = existing?.order ?? input.order ?? nextOrder++;\r\n const status = input.status ?? existing?.status ?? 'dirty';\r\n map.set(input.key, {\r\n ...input,\r\n order,\r\n status,\r\n } as DirtyDraft);\r\n emit();\r\n },\r\n setStatus(key, status, error) {\r\n const existing = map.get(key);\r\n if (!existing) return;\r\n map.set(key, { ...existing, status, error });\r\n emit();\r\n },\r\n clearDraft(key) {\r\n if (map.delete(key)) emit();\r\n },\r\n clearAll() {\r\n if (map.size === 0) return;\r\n map.clear();\r\n emit();\r\n },\r\n subscribe(listener) {\r\n listeners.add(listener);\r\n return () => { listeners.delete(listener); };\r\n },\r\n };\r\n};\r\n\r\nconst DirtyDraftContext = createContext<DirtyDraftStore | null>(null);\r\n\r\nexport const DirtyDraftProvider = ({ children }: { children: ReactNode }) => {\r\n const storeRef = useRef<DirtyDraftStore | null>(null);\r\n if (!storeRef.current) storeRef.current = createStore();\r\n return (\r\n <DirtyDraftContext.Provider value={storeRef.current}>\r\n {children}\r\n </DirtyDraftContext.Provider>\r\n );\r\n};\r\n\r\n/** Always returns a store — falls back to a noop when no provider is mounted\r\n * so the hook can be called from inside `useRecordEditor` without forcing\r\n * every host of the editor to wrap themselves in a provider. */\r\nexport const useDirtyDraftStore = (): DirtyDraftStore => {\r\n const ctx = useContext(DirtyDraftContext);\r\n const fallbackRef = useRef<DirtyDraftStore | null>(null);\r\n if (!ctx && !fallbackRef.current) fallbackRef.current = createStore();\r\n return ctx ?? (fallbackRef.current as DirtyDraftStore);\r\n};\r\n\r\n/** Subscribe to the store and re-render on any change. */\r\nexport const useDirtyDrafts = (): DirtyDraft[] => {\r\n const store = useDirtyDraftStore();\r\n return useSyncExternalStore(\r\n useCallback((cb) => store.subscribe(cb), [store]),\r\n useCallback(() => store.list(), [store]),\r\n useCallback(() => store.list(), [store]),\r\n );\r\n};\r\n\r\n/** Subscribe to a single draft (or undefined) by key. */\r\nexport const useDirtyDraft = (key: string | undefined): DirtyDraft | undefined => {\r\n const store = useDirtyDraftStore();\r\n const getSnapshot = useCallback(\r\n () => (key ? store.get(key) : undefined),\r\n [store, key],\r\n );\r\n return useSyncExternalStore(\r\n useCallback((cb) => store.subscribe(cb), [store]),\r\n getSnapshot,\r\n getSnapshot,\r\n );\r\n};\r\n\r\n/** Stable per-row dirty lookup used by DefaultRecordRow / DefaultRecordCard.\r\n * Returns the current status of any draft whose key matches `recordId` (or\r\n * the synthetic anchor key for unsaved drafts). */\r\nexport const useDirtyStatusForKey = (key: string | undefined): DirtyDraftStatus | undefined => {\r\n const draft = useDirtyDraft(key);\r\n return draft?.status;\r\n};\r\n\r\n/** Build the canonical key for a draft. */\r\nexport const buildDraftKey = (opts: {\r\n recordId?: string;\r\n scopeRaw: string;\r\n draftKind?: string;\r\n}): string => {\r\n if (opts.recordId) return opts.recordId;\r\n const kind = opts.draftKind ?? 'rec';\r\n return `draft:${kind}:${opts.scopeRaw}`;\r\n};\r\n\r\n/** Hook used by the shell tray to count + bulk-save. */\r\nexport const useDirtyDraftActions = () => {\r\n const store = useDirtyDraftStore();\r\n const drafts = useDirtyDrafts();\r\n const count = useMemo(() => drafts.filter((d) => d.status !== 'saved').length, [drafts]);\r\n const errorCount = useMemo(() => drafts.filter((d) => d.status === 'error').length, [drafts]);\r\n return { drafts, count, errorCount, store };\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 {\r\n upsertRecord, updateRecord, removeRecord, createRecord,\r\n type RecordsCtx,\r\n} 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\nimport { useDirtyDraftStore, buildDraftKey } from './useDirtyDraftStore';\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 * When true, every save calls `records.create` (a fresh insert) instead\r\n * of `records.upsert`. Used by collection-cardinality hosts where\r\n * multiple items can share the same scope/recordType — each draft must\r\n * become its own row, not collide on an upsert key. The shell flips\r\n * this on for unsaved item drafts and clears it once the resolver hands\r\n * back a concrete `recordId`.\r\n */\r\n createMode?: boolean;\r\n /**\r\n * Optional host-supplied derivation for the label this editor registers\r\n * with the unsaved-changes tray. Receives the in-flight value and the\r\n * scope; should return a short, human-readable title. When omitted (or\r\n * when it returns `undefined`), the hook falls back to a built-in heuristic\r\n * that scans common title-shaped fields (`title`, `display.title`,\r\n * `name`, `label`, `heading`, `question`, `slug`).\r\n */\r\n deriveDraftLabel?: (value: T, scope: ParsedRef) => string | undefined;\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\nconst getScopedResolvedRecordId = <T,>(scope: ParsedRef, resolved: ResolvedRecord<T>): string | undefined => {\r\n if (!resolved.recordId) return undefined;\r\n // Collection-cardinality items carry their stable identity on the synthetic\r\n // `item:{id}` segment the shell adds to `scope.raw`. The resolver's\r\n // `sourceRef` stays anchor-only for those rows, so matching on `itemId`\r\n // is the reliable signal that the resolved UUID belongs to the current\r\n // editor target.\r\n if (scope.itemId && scope.itemId === resolved.recordId) return resolved.recordId;\r\n const scopeRaw = scope.raw || '';\r\n const sourceRef = resolved.sourceRef || '';\r\n if (scopeRaw === sourceRef) return resolved.recordId;\r\n return undefined;\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, createMode = false,\r\n deriveDraftLabel,\r\n } = args;\r\n const queryClient = useQueryClient();\r\n const draftStore = useDirtyDraftStore();\r\n // If the shell already has a draft for this record (because the user\r\n // edited it earlier and navigated away in `keep` mode), prefer that\r\n // value over the resolver's clean copy. Computed at mount only — once\r\n // the editor is live the local state owns the truth.\r\n const scopedResolvedRecordId = getScopedResolvedRecordId(scope, resolved);\r\n const draftKey = buildDraftKey({\r\n // Scope identity must win during record switches. `resolved.recordId`\r\n // can briefly lag behind the newly-selected target while the resolver is\r\n // catching up, and keying drafts off that stale id lets one edited item\r\n // borrow another item's draft. Once the resolver confirms the matching\r\n // record for this scope, we transparently migrate onto the concrete UUID.\r\n recordId: scopedResolvedRecordId,\r\n scopeRaw: scope.raw,\r\n draftKind: scope.kind,\r\n });\r\n const initialDraft = draftStore.get(draftKey);\r\n const cleanSeed = cloneSeed(resolved, defaultData);\r\n const seed = (initialDraft && reseed === 'preserve-dirty')\r\n ? (initialDraft.value as T)\r\n : cleanSeed;\r\n const seedFacetRule = (initialDraft && reseed === 'preserve-dirty')\r\n ? initialDraft.facetRule\r\n : initialFacetRule;\r\n\r\n const [value, setValue] = useState<T>(seed);\r\n const [savedSnapshot, setSavedSnapshot] = useState<T>(\r\n initialDraft ? (initialDraft.baseline as T) : cleanSeed,\r\n );\r\n const [facetRule, setFacetRule] = useState<FacetRule | null>(seedFacetRule);\r\n const [savedFacetRule, setSavedFacetRule] = useState<FacetRule | null>(\r\n initialDraft ? initialDraft.baselineFacetRule : initialFacetRule,\r\n );\r\n // Tracks whether the user has actually interacted with this editor in the\r\n // current mount. Without this gate, the dirty-detection effect can register\r\n // a draft on first mount because of transient mismatches between the seed\r\n // value and the post-reseed `savedSnapshot` (e.g. cloned vs inherited data,\r\n // initialFacetRule object identity). We only want to surface drafts the\r\n // user genuinely created. Pre-existing drafts (resumed from the store)\r\n // start as already-interacted so the tray entry persists.\r\n const [userInteracted, setUserInteracted] = useState<boolean>(!!initialDraft);\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 // Track the previous editing target so we can distinguish \"same record\r\n // refetched\" (preserve-dirty applies) from \"user navigated to a different\r\n // record\" (preserve-dirty MUST NOT apply — otherwise the editor keeps the\r\n // first record's value while looking at the second). Two records share the\r\n // same scope.raw under collection cardinality (both `item:{recordId}`),\r\n // and in the deeper id-primary path scope.raw can be empty for both — so\r\n // the only reliable signal that the target changed is `recordId` flipping.\r\n const prevTargetRef = useRef<{ scopeRaw: string; recordId?: string }>({\r\n scopeRaw: scope.raw, recordId: resolved.recordId,\r\n });\r\n useEffect(() => {\r\n const prev = prevTargetRef.current;\r\n const targetChanged =\r\n prev.scopeRaw !== scope.raw\r\n || (prev.recordId ?? null) !== (resolved.recordId ?? null);\r\n prevTargetRef.current = { scopeRaw: scope.raw, recordId: resolved.recordId };\r\n\r\n const fresh = cloneSeed(resolved, defaultData);\r\n\r\n // When the user navigated to a *different* record, prefer that record's\r\n // pre-existing draft if one is registered in the shell store; otherwise\r\n // seed from the resolver. The `preserve-dirty` guard only applies to\r\n // refetches of the same record (so an in-flight refresh doesn't blow\r\n // away the user's local edits).\r\n if (targetChanged) {\r\n const incomingKey = buildDraftKey({\r\n recordId: getScopedResolvedRecordId(scope, resolved),\r\n scopeRaw: scope.raw,\r\n draftKind: scope.kind,\r\n });\r\n const incomingDraft = draftStore.get(incomingKey);\r\n if (incomingDraft && reseed === 'preserve-dirty') {\r\n setValue(incomingDraft.value as T);\r\n setSavedSnapshot(incomingDraft.baseline as T);\r\n setFacetRule(incomingDraft.facetRule);\r\n setSavedFacetRule(incomingDraft.baselineFacetRule);\r\n // The draft was authored by the user previously — keep the\r\n // interaction gate hot so the tray entry stays live.\r\n setUserInteracted(true);\r\n } else {\r\n setValue(fresh);\r\n setSavedSnapshot(fresh);\r\n setFacetRule(initialFacetRule);\r\n setSavedFacetRule(initialFacetRule);\r\n setUserInteracted(false);\r\n }\r\n } else {\r\n // Same record — just a resolver refresh. In `preserve-dirty` mode keep\r\n // any in-flight value the user is typing; otherwise overwrite.\r\n if (reseed === 'preserve-dirty') {\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 setFacetRule(initialFacetRule);\r\n setSavedFacetRule(initialFacetRule);\r\n }\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.recordId, 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 // Gate on `userInteracted` so transient seed/snapshot mismatches during\r\n // mount and resolver settling don't flag the record as dirty.\r\n const valueDiff = !isEqual(value, savedSnapshot) || !isEqual(facetRule, savedFacetRule);\r\n const isDirty = userInteracted && valueDiff;\r\n\r\n // Wrapped setters that flip the interaction gate the moment the user\r\n // changes anything via the returned `onChange` / `onFacetRuleChange` APIs.\r\n const handleChange = useCallback((next: T | ((prev: T) => T)) => {\r\n setUserInteracted(true);\r\n setValue(next as T);\r\n }, []);\r\n const handleFacetRuleChange = useCallback((next: FacetRule | null) => {\r\n setUserInteracted(true);\r\n setFacetRule(next);\r\n }, []);\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 // Empty `scope.raw` is legitimate — it's the collection-root singleton\r\n // case (a \"global default\" record). The only situation we genuinely\r\n // can't save is a `rule:` scope with no clauses yet — the server has\r\n // no addressing for an unanchored, ruleless, brand-new record.\r\n const anchors = parsedRefToScope(scope);\r\n const hasAnchors = !!(anchors.productId || anchors.variantId || anchors.batchId || anchors.proofId);\r\n const hasRule = !!(facetRule && facetRule.all && facetRule.all.length > 0);\r\n const isRuleScope = scope.kind === 'rule';\r\n if (isRuleScope && !hasAnchors && !hasRule && !resolved.recordId && !createMode) {\r\n // eslint-disable-next-line no-console\r\n console.warn('[useRecordEditor] save() bailed — rule scope with no clauses, no recordId, not in createMode');\r\n return;\r\n }\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 recordId: resolved.recordId,\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 recordId: resolved.recordId,\r\n parentValue: previousCache?.parentValue ?? resolved.parentValue,\r\n });\r\n\r\n try {\r\n // Id-primary save: when the resolver gave us a recordId AND the\r\n // record is genuinely the user's own (`source === 'self'`, not an\r\n // inherited parent), PATCH it directly. Otherwise this is a brand-\r\n // new record. In `createMode` (collection-cardinality items) every\r\n // such save inserts a fresh row via `createRecord` — `upsert` would\r\n // collide because items share scope+recordType. Otherwise we go\r\n // through `upsertRecord`, which the server addresses by anchors /\r\n // facetRule.\r\n if (resolved.recordId && resolved.source === 'self') {\r\n await updateRecord<T>(ctx, resolved.recordId, {\r\n data: value,\r\n facetRule,\r\n });\r\n } else if (createMode) {\r\n await createRecord<T>(ctx, {\r\n ref: scope.kind === 'rule' && scope.raw ? scope.raw : undefined,\r\n scope: anchors,\r\n data: value,\r\n facetRule,\r\n });\r\n } else {\r\n await upsertRecord<T>(ctx, {\r\n // External ref only when the underlying scope already carries\r\n // one (e.g. rule:{id} for an existing rule record). Empty for\r\n // anchor-only writes — server addresses by anchors.\r\n ref: scope.kind === 'rule' && scope.raw ? scope.raw : undefined,\r\n scope: anchors,\r\n data: value,\r\n facetRule,\r\n });\r\n }\r\n draftStore.clearDraft(draftKey);\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, resolved.recordId, createMode, draftKey]);\r\n\r\n const reset = useCallback(() => {\r\n setValue(savedSnapshot);\r\n setFacetRule(savedFacetRule);\r\n setUserInteracted(false);\r\n // Drop any registered draft — the editor is back to its baseline.\r\n draftStore.clearDraft(draftKey);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [savedSnapshot, savedFacetRule, draftKey]);\r\n\r\n const remove = useCallback(async () => {\r\n if (resolved.source !== 'self') return;\r\n // Id-primary delete. The resolver always surfaces a `recordId` for\r\n // `source === 'self'`; bail otherwise.\r\n if (!resolved.recordId) return;\r\n await removeRecord(ctx, resolved.recordId);\r\n draftStore.clearDraft(draftKey);\r\n onDeleted?.();\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [resolved.source, resolved.recordId, draftKey]);\r\n\r\n // If the draftKey for THIS editor instance changes (e.g. `resolved.recordId`\r\n // arrives after initial mount and we transition from `draft:item:…` to a\r\n // concrete UUID), migrate any draft we previously registered under the old\r\n // key onto the new one. We MUST NOT blindly clear the previous key when\r\n // the editor switches to a different record (e.g. user navigates from\r\n // item A to item B in `keep` mode) — that would wipe A's legitimate\r\n // unsaved draft. The migration only happens when both keys describe the\r\n // same underlying record, which we detect via matching `scopeRaw`.\r\n const prevDraftKeyRef = useRef<string>(draftKey);\r\n const prevScopeRawRef = useRef<string>(scope.raw);\r\n useEffect(() => {\r\n const prevKey = prevDraftKeyRef.current;\r\n const prevScopeRaw = prevScopeRawRef.current;\r\n if (prevKey && prevKey !== draftKey && prevScopeRaw === scope.raw) {\r\n // Same selected target, key just got upgraded from scope-backed draft\r\n // identity to a concrete recordId — drop the old synthetic entry so\r\n // the tray doesn't list the same record twice.\r\n const stale = draftStore.get(prevKey);\r\n if (stale) draftStore.clearDraft(prevKey);\r\n }\r\n prevDraftKeyRef.current = draftKey;\r\n prevScopeRawRef.current = scope.raw;\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [draftKey, scope.raw]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Draft store sync — register the in-flight value with the shell-level\r\n // registry whenever the editor is dirty, and clear it on save / reset.\r\n // The registered draft captures a closure over the current save() so the\r\n // shell's \"Save all\" can call it without re-mounting the editor.\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (!isDirty) {\r\n // If we held a draft for this key, it was either saved (clearDraft\r\n // called inside save()) or reset (clearDraft inside reset()). Either\r\n // way no further bookkeeping is required here.\r\n return;\r\n }\r\n const anchors = parsedRefToScope(scope);\r\n const saveKind: 'update' | 'create' | 'upsert' = (resolved.recordId && resolved.source === 'self')\r\n ? 'update'\r\n : (createMode ? 'create' : 'upsert');\r\n const deriveLabel = (): string => {\r\n // 1. Host override always wins.\r\n if (deriveDraftLabel) {\r\n try {\r\n const custom = deriveDraftLabel(value, scope);\r\n if (typeof custom === 'string' && custom.trim()) return custom.trim();\r\n } catch { /* fall through to heuristic */ }\r\n }\r\n // 2. Built-in heuristic — mirrors the row label resolution used by\r\n // `useCollectionItems` so the tray and the sidebar agree.\r\n const KEYS = ['title', 'name', 'label', 'heading', 'question', 'slug'] as const;\r\n const pickString = (obj: Record<string, unknown> | null | undefined): string | undefined => {\r\n if (!obj || typeof obj !== 'object') return undefined;\r\n for (const key of KEYS) {\r\n const raw = obj[key];\r\n if (typeof raw === 'string' && raw.trim()) return raw.trim();\r\n }\r\n return undefined;\r\n };\r\n const v = value as Record<string, unknown> | null | undefined;\r\n // Top-level …\r\n const top = pickString(v);\r\n if (top) return top;\r\n // … then well-known nested wrappers hosts use (display, content, meta).\r\n if (v && typeof v === 'object') {\r\n for (const wrapper of ['display', 'content', 'meta', 'data'] as const) {\r\n const nested = pickString(v[wrapper] as Record<string, unknown> | undefined);\r\n if (nested) return nested;\r\n }\r\n }\r\n // Fall back to a friendly scope descriptor — never leak raw IDs.\r\n if (scope.raw?.startsWith('item:')) return 'Untitled item';\r\n if (scope.kind === 'rule') return 'Rule';\r\n if (scope.kind && scope.kind !== 'collection') {\r\n return scope.kind.charAt(0).toUpperCase() + scope.kind.slice(1);\r\n }\r\n return 'Default';\r\n };\r\n draftStore.upsertDraft({\r\n key: draftKey,\r\n label: deriveLabel(),\r\n context: scope.kind,\r\n scopeRaw: scope.raw,\r\n recordId: resolved.recordId,\r\n value,\r\n facetRule,\r\n baseline: savedSnapshot,\r\n baselineFacetRule: savedFacetRule,\r\n createMode,\r\n scopeAnchors: anchors,\r\n ref: scope.kind === 'rule' && scope.raw ? scope.raw : undefined,\r\n saveKind,\r\n save: async () => { await save(); },\r\n });\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isDirty, value, facetRule, savedSnapshot, savedFacetRule, scope.raw, resolved.recordId, resolved.source, createMode, save]);\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: handleChange,\r\n source: effectiveSource,\r\n recordId: resolved.recordId,\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: handleFacetRuleChange,\r\n };\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, ResolveAllEntry, 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 /**\r\n * All matching records, sorted most-specific first. Each appears once.\r\n * SDK 1.10.2: `ResolveAllEntry` wraps `{ record: AppRecord, matchedAt,\r\n * specificity, matchedRule? }`.\r\n */\r\n records: ResolveAllEntry[];\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 // SDK 1.10.2: `MatchResult.data` (was `.records`).\r\n const entries = result?.data ?? [];\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 // SDK 1.10.2: `MatchEntry` extends `AppRecord` directly — no inner `record`.\r\n const baseList: CollectedRecord<T>[] = entries.map((entry: MatchEntry, i: number) => ({\r\n ref: entry.ref ?? '',\r\n scope: parseRef(entry.ref ?? ''),\r\n data: entry.data as T,\r\n depth: i,\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 // SDK 1.10.2: `MatchResult.data` (was `.records`); `MatchEntry`\r\n // extends `AppRecord` so we read `entry.ref` / `entry.data` directly.\r\n const entries = result?.data ?? [];\r\n if (entries.length === 0) return { data: null, provenance: {}, layers: [] };\r\n const present = entries.map((entry: MatchEntry) => ({\r\n ref: entry.ref ?? '',\r\n data: entry.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/data/resolveRecord.ts","../../../src/components/RecordsAdmin/hooks/useResolvedRecord.ts","../../../src/components/RecordsAdmin/hooks/useIntroDismissed.ts","../../../src/components/RecordsAdmin/hooks/useScopeProbe.ts","../../../src/components/RecordsAdmin/hooks/useRecordList.ts","../../../src/components/RecordsAdmin/hooks/useFacetBrowse.ts","../../../src/components/RecordsAdmin/hooks/useProductBrowse.ts","../../../src/components/RecordsAdmin/hooks/useProductChildren.ts","../../../src/components/RecordsAdmin/browser/RuleFilterChips.tsx","../../../src/components/RecordsAdmin/hooks/useShellBrowser.ts","../../../src/components/RecordsAdmin/hooks/useSingleProduct.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/useRecordClipboard.ts","../../../src/components/RecordsAdmin/hooks/usePasteConfirm.tsx","../../../src/components/RecordsAdmin/shell/ClipboardToast.tsx","../../../src/components/RecordsAdmin/hooks/useShellClipboard.tsx","../../../src/components/RecordsAdmin/shell/state/useShellPreviewPane.ts","../../../src/components/RecordsAdmin/shell/state/useShellNavigation.ts","../../../src/components/RecordsAdmin/shell/state/useEditingScope.ts","../../../src/components/RecordsAdmin/shell/state/useShellDeepLink.ts","../../../src/components/RecordsAdmin/hooks/useRulePreview.ts","../../../src/components/RecordsAdmin/editor-session/editorStore.ts","../../../src/components/RecordsAdmin/editor-session/EditorSessionProvider.tsx","../../../src/components/RecordsAdmin/editor-session/useEditorBridge.ts","../../../src/components/RecordsAdmin/shell/state/useShellEditorTarget.ts","../../../src/components/RecordsAdmin/shell/state/useShellSelection.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/FacetBrowseFilter.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/data/postMessageDeepLinkAdapter.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/AdminPageHeader/admin-page-header.css","../../../src/components/AdminPageHeader/AdminPageHeader.tsx","../../../src/components/RecordsAdmin/shell/ShellHeader.tsx","../../../src/components/RecordsAdmin/shell/NewRuleWizard.tsx","../../../src/components/RecordsAdmin/shell/UnsavedTray.tsx","../../../src/components/RecordsAdmin/shell/HeaderUnsavedPill.tsx","../../../src/components/RecordsAdmin/shell/SaveAllProgress.tsx","../../../src/components/RecordsAdmin/editor-session/EditorMountPool.tsx","../../../src/components/RecordsAdmin/editor-session/useEditorSlotContext.ts","../../../src/components/RecordsAdmin/data/csv.ts","../../../src/components/RecordsAdmin/hooks/useShellCsvBulk.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/useDirtyDraftStore.tsx","../../../src/components/RecordsAdmin/hooks/useRecordEditor.ts","../../../src/components/RecordsAdmin/hooks/useResolveAllRecords.ts","../../../src/components/RecordsAdmin/hooks/useCollectedRecords.ts","../../../src/components/RecordsAdmin/hooks/useMergedRecord.ts"],"names":["eq","useQuery","classify","total","useState","useEffect","useCallback","useQueryClient","useMemo","QK","useInfiniteQuery","items","res","toBrowseItem","useRef","jsxs","jsx","DEFAULTS","CopyIcon","removeRecord","DRAFT_PREFIX","DRAFT_ID","isDraftId","MoreHorizontal","Copy","ClipboardPaste","Inbox","QK_BASE","toSummary","Layers","Upload","Download","ChevronDown","Trash2","Fragment","ChevronRight","Package","Eye","ICONS","TableIcon","LayoutGrid","ImageIcon","labelFor","Pencil","Plus","PlusIcon","ArrowLeft","Lightbulb","CheckCircle2","AlertTriangle","X","TONE_ICON","HelpCircle","Info","AlertCircle","Save","Undo2","mintDraftItemId","coerceDraftItemId","Search","initials","createContext","useContext","Circle","useSyncExternalStore","isEqual","isRuleScope","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 /**\r\n * Shell-level \"Save all\" tray strings (multi-record dirty workflow).\r\n * `{n}` placeholders interpolate the count.\r\n */\r\n unsavedTrayCount: string; // \"{n} records have unsaved changes\"\r\n unsavedTrayErrors: string; // \"{n} errors\"\r\n saveAll: string; // \"Save all\"\r\n discardAll: string; // \"Discard all\"\r\n saveAllInProgress: string; // \"Saving {n} records…\"\r\n saveAllSuccess: string; // \"Saved {n} records\"\r\n saveAllErrorTitle: string; // \"Saved with errors\"\r\n saveAllStop: string; // \"Stop\"\r\n saveAllClose: string; // \"Close\"\r\n saveAllRetryFailed: string; // \"Retry failed\"\r\n saveAllJumpToError: string; // \"Jump to first error\"\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\n * Label for the synthetic \"All items\" rail row shown on the Global tab in\r\n * collection-cardinality mode (no `groupBy`). Selecting it pins the right\r\n * pane to the multi-item list.\r\n */\r\n itemsAllLabel: string;\r\n\r\n /**\r\n * Default subtitle copy shown beneath a row's label in the browse rail when\r\n * the host hasn't supplied a `subtitle` on the RecordSummary. Apps can\r\n * override these to match their domain noun (e.g. \"No recipe yet\").\r\n */\r\n subtitleEmpty: string;\r\n subtitleConfigured: string;\r\n subtitleInherited: 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 unsavedTrayCount: '{n} records have unsaved changes',\r\n unsavedTrayErrors: '{n} errors',\r\n saveAll: 'Save all',\r\n discardAll: 'Discard all',\r\n saveAllInProgress: 'Saving {n} records…',\r\n saveAllSuccess: 'Saved {n} records',\r\n saveAllErrorTitle: 'Saved with errors',\r\n saveAllStop: 'Stop',\r\n saveAllClose: 'Close',\r\n saveAllRetryFailed: 'Retry failed',\r\n saveAllJumpToError: 'Jump to first error',\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 itemsAllLabel: 'All items',\r\n subtitleEmpty: 'Not set',\r\n subtitleConfigured: 'Configured',\r\n subtitleInherited: 'Inherited',\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// - `recordId` → SDK-assigned UUID of the open record. Loading by id is\r\n// unambiguous: the resolver returns the record, the shell\r\n// derives anchors from it and lands on the right tab.\r\n// - `scope` → anchor ref (e.g. `product:abc` or empty for collection\r\n// root). Used only when no record is open, to deep-link to\r\n// a list/browse view. Never carries synthetic `rule:` or\r\n// `item:` segments — the shell stopped minting those once\r\n// records grew stable UUIDs.\r\n// - `view` → right-pane view (`table` / `cards` / `gallery`).\r\n// Optional 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 `'recordId'`. */\r\n recordId?: 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 /** UUID of the record open in the editor (SDK-assigned). */\r\n recordId?: string | null;\r\n /** Anchor scope ref when no record 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 recordId: string;\r\n scope: string;\r\n view: string;\r\n}\r\n\r\nexport const DEFAULT_DEEP_LINK_PARAM_NAMES: ResolvedDeepLinkParamNames = {\r\n recordId: 'recordId',\r\n scope: 'scope',\r\n view: 'view',\r\n};","// =============================================================================\r\n// Ref parsing — `kind:id` segments joined by `/`.\r\n//\r\n// HISTORICAL NOTE: in earlier shell versions we used these helpers as the\r\n// universal \"coordinate\" for selection state, drafts, and item identity.\r\n// That conflated `record.ref` (an OPTIONAL EXTERNAL HANDLE the app sets to\r\n// map to a third-party id) with internal record identity (the SDK-assigned\r\n// UUID). Refs are now back to being app-owned strings only — the shell\r\n// addresses every record by UUID.\r\n//\r\n// What's still here, and why:\r\n// - `parseRef` / `buildRef` decode anchor IDs from URL deep-link `?scope=`\r\n// parameters and feed `useFacetBrowse` / CSV import (both consume\r\n// anchor-ref strings the user can paste). Anchors only — no synthetic\r\n// `rule:` or `item:` segments.\r\n// - `resolutionChain` builds the parent-anchor chain the resolver walks\r\n// for inheritance. Anchors only.\r\n//\r\n// What's GONE and must NOT come back:\r\n// - `splitItemRef` / `buildItemRef` — items are records; identity is\r\n// `record.id` (UUID). No `/item:{id}` suffix.\r\n// - `newRuleId()` and `rule:{id}` minting — drafts are tracked in shell\r\n// state until the first save returns a UUID.\r\n// - `KIND_KEYS.rule` / `parseRef`-of-`rule:…` — rule records are\r\n// identified by `facetRule != null`, addressed by UUID.\r\n// =============================================================================\r\nimport type { ParsedRef, ScopeKind } from '../types';\r\n\r\nconst KIND_KEYS: Record<'product' | 'facet' | 'variant' | 'batch' | 'proof' | 'collection', keyof ParsedRef> = {\r\n product: 'productId',\r\n facet: 'facetId',\r\n variant: 'variantId',\r\n batch: 'batchId',\r\n proof: 'proofId',\r\n collection: 'collectionId',\r\n};\r\n\r\nexport const parseRef = (raw: string): ParsedRef => {\r\n const parsed: ParsedRef = { kind: 'collection', raw };\r\n if (!raw) return parsed;\r\n const segments = raw.split('/').filter(Boolean);\r\n let kind: ParsedRef['kind'] = 'collection';\r\n for (const seg of segments) {\r\n const idx = seg.indexOf(':');\r\n if (idx < 0) continue;\r\n const k = seg.slice(0, idx) as ScopeKind | 'collection' | 'proof';\r\n const id = seg.slice(idx + 1);\r\n if (k === 'facet') {\r\n // facet:<id>=<value> or facet:<id>\r\n const eq = id.indexOf('=');\r\n if (eq >= 0) {\r\n parsed.facetId = id.slice(0, eq);\r\n parsed.facetValue = id.slice(eq + 1);\r\n } else {\r\n parsed.facetId = id;\r\n }\r\n } else if (k in KIND_KEYS) {\r\n const slot = KIND_KEYS[k as keyof typeof KIND_KEYS];\r\n (parsed as unknown as Record<string, string>)[slot] = id;\r\n }\r\n // Unknown segments (legacy `rule:…`, `item:…` from URLs created by old\r\n // builds) are silently ignored — the shell resolves the open record by\r\n // `?recordId=` instead.\r\n if (k !== 'collection') kind = k as ParsedRef['kind'];\r\n }\r\n parsed.kind = kind;\r\n return parsed;\r\n};\r\n\r\nexport interface BuildRefArgs {\r\n collectionId?: string;\r\n productId?: string;\r\n facetId?: string;\r\n facetValue?: string;\r\n variantId?: string;\r\n batchId?: string;\r\n proofId?: string;\r\n}\r\n\r\nexport const buildRef = (a: BuildRefArgs): string => {\r\n const parts: string[] = [];\r\n if (a.facetId) {\r\n parts.push(a.facetValue ? `facet:${a.facetId}=${a.facetValue}` : `facet:${a.facetId}`);\r\n }\r\n if (a.productId) parts.push(`product:${a.productId}`);\r\n if (a.variantId) parts.push(`variant:${a.variantId}`);\r\n if (a.batchId) parts.push(`batch:${a.batchId}`);\r\n if (a.proofId) parts.push(`proof:${a.proofId}`);\r\n return parts.join('/');\r\n};\r\n\r\n/**\r\n * Build the resolution chain for a target ref, from most specific → least specific.\r\n * `supportedScopes` prunes scopes the app doesn't care about.\r\n */\r\nexport const resolutionChain = (\r\n target: ParsedRef,\r\n supportedScopes: ScopeKind[],\r\n): string[] => {\r\n const chain: string[] = [];\r\n // Most specific → least specific\r\n if (supportedScopes.includes('batch') && target.batchId && target.productId) {\r\n chain.push(buildRef({ productId: target.productId, batchId: target.batchId }));\r\n }\r\n if (supportedScopes.includes('variant') && target.variantId && target.productId) {\r\n chain.push(buildRef({ productId: target.productId, variantId: target.variantId }));\r\n }\r\n if (supportedScopes.includes('product') && target.productId) {\r\n chain.push(buildRef({ productId: target.productId }));\r\n }\r\n if (supportedScopes.includes('facet') && target.facetId) {\r\n chain.push(buildRef({ facetId: target.facetId, facetValue: target.facetValue }));\r\n }\r\n // 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// 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 // Records addressed by UUID never reach here — `useResolvedRecord`'s\r\n // id-primary path handles them with `getRecordById`. This function is\r\n // anchor-only: pinned-scope tabs (Product / Variant / Batch / Facet) ask\r\n // the server to evaluate the inheritance chain.\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 // SDK 1.10.2: `MatchResult.data` (was `.records`); each entry extends\r\n // `AppRecord` directly (no inner `record`).\r\n const entries = result?.data ?? [];\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdmin/resolveRecord]', {\r\n editingScope,\r\n target,\r\n matchCount: entries.length,\r\n winnerAnchors: entries[0] && {\r\n productId: entries[0].productId,\r\n variantId: entries[0].variantId,\r\n batchId: entries[0].batchId,\r\n proofId: entries[0].proofId,\r\n },\r\n winnerRef: entries[0]?.ref,\r\n });\r\n if (entries.length === 0) {\r\n return { data: null, source: 'empty' };\r\n }\r\n\r\n const winner = entries[0];\r\n // Compare flat anchor IDs on the winner against the editing scope.\r\n const winnerIsSelf = scopesEqual(\r\n {\r\n productId: winner.productId,\r\n variantId: winner.variantId,\r\n batchId: winner.batchId,\r\n proofId: winner.proofId,\r\n },\r\n editingScope,\r\n );\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdmin/resolveRecord] classification', {\r\n winnerIsSelf,\r\n winnerAnchors: {\r\n productId: winner.productId,\r\n variantId: winner.variantId,\r\n batchId: winner.batchId,\r\n proofId: winner.proofId,\r\n },\r\n editingScope,\r\n });\r\n\r\n if (winnerIsSelf) {\r\n const parent = entries[1];\r\n return {\r\n data: winner.data as T,\r\n source: 'self',\r\n sourceRef: winner.ref ?? undefined,\r\n recordId: winner.id,\r\n parentValue: args.withParent && parent ? (parent.data as T) : undefined,\r\n matchedAt: winner.matchedAt,\r\n matchedRule: winner.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 recordId: winner.id,\r\n parentValue: args.withParent ? (winner.data as T) : undefined,\r\n matchedAt: winner.matchedAt,\r\n matchedRule: winner.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 { getRecordById } from '../data/records';\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 * Direct UUID lookup. When set, the resolver bypasses the inheritance\r\n * chain and loads this record by id (used by `?recordId=` deep-links and\r\n * by rule-record edits — both cases where the row's identity is already\r\n * known and the resolver shouldn't run a `match()`).\r\n */\r\n recordId?: 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 recordId?: 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.recordId ?? 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, recordId,\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, recordId, withParent,\r\n }),\r\n enabled: enabled && !!collectionId && !!appId,\r\n staleTime: 15_000,\r\n queryFn: async () => {\r\n // Id-primary path: when the caller already has the UUID, bypass the\r\n // inheritance chain entirely. Used by `?recordId=` deep-links and by\r\n // rule records (whose identity is the recordId, not anchors).\r\n if (recordId) {\r\n const rec = await getRecordById({ SL, collectionId, appId, recordType }, recordId);\r\n if (!rec) return { data: null, source: 'empty' };\r\n const recFacetRule = (rec as unknown as { facetRule?: import('../data/sdkTypes').FacetRule | null }).facetRule ?? null;\r\n return {\r\n data: rec.data as T,\r\n source: 'self',\r\n sourceRef: rec.ref ?? undefined,\r\n recordId: rec.id,\r\n facetRule: recFacetRule,\r\n };\r\n }\r\n // Anchor path: pinned-scope tabs (Product / Variant / Batch / Facet).\r\n // The resolver runs server-side `match()` against these anchors and\r\n // returns the winning record by inheritance specificity.\r\n const target: import('../types').ParsedRef = {\r\n kind: batchId ? 'batch'\r\n : variantId ? 'variant'\r\n : productId ? 'product'\r\n : facetId ? 'facet'\r\n : 'collection',\r\n raw: '',\r\n collectionId,\r\n productId, variantId, batchId,\r\n facetId, facetValue, proofId,\r\n };\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, 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 { 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 { 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`.\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 if (kind === 'rule') return hasRule;\r\n if (hasRule) return false;\r\n // Anchor checks read the canonical anchor IDs straight off the record —\r\n // no ref-string parsing needed now that the SDK keeps them flat.\r\n const productId = (rec as { productId?: string | null }).productId ?? undefined;\r\n const variantId = (rec as { variantId?: string | null }).variantId ?? undefined;\r\n const batchId = (rec as { batchId?: string | null }).batchId ?? undefined;\r\n const proofId = (rec as { proofId?: string | null }).proofId ?? undefined;\r\n\r\n if (kind === 'collection') {\r\n // \"Global\" — no pinned scope at all. Empty/missing ref counts.\r\n return !productId && !variantId && !batchId && !proofId;\r\n }\r\n if (kind === 'product') return !!productId && !variantId && !batchId;\r\n // `facet` was deprecated as a top-level tab in 0.5; pinned-facet records\r\n // never reach this branch from the modern shell.\r\n if (kind === 'variant') return !!variantId;\r\n if (kind === 'batch') return !!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 // Build a ParsedRef from the flat anchors on the record itself rather\r\n // than from `ref` — refs are now caller-supplied external keys (or empty)\r\n // and no longer encode anchors.\r\n const productId = (rec as { productId?: string | null }).productId ?? undefined;\r\n const variantId = (rec as { variantId?: string | null }).variantId ?? undefined;\r\n const batchId = (rec as { batchId?: string | null }).batchId ?? undefined;\r\n const proofId = (rec as { proofId?: string | null }).proofId ?? undefined;\r\n const scope: ParsedRef = {\r\n kind: batchId ? 'batch' : variantId ? 'variant' : productId ? 'product' : 'collection',\r\n raw: ref,\r\n productId, variantId, batchId, proofId,\r\n };\r\n const facetRule = (rec as { facetRule?: FacetRule | null }).facetRule ?? null;\r\n if (facetRule) scope.kind = 'rule';\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 ?? ruleLabel\r\n ?? (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};","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// 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// useShellBrowser — owns the rail's \"what records are visible\" state for the\r\n// RecordsAdminShell.\r\n//\r\n// Responsibilities:\r\n// • Filter state: search, status filter, rule filters, \"browse by facet\"\r\n// selection.\r\n// • Browse data sources: products, records (rule/global tabs), facet\r\n// vocabulary, lazy variant/batch children for the selected product.\r\n// • Cross-cutting effects:\r\n// - reset filters when the active top-level scope changes;\r\n// - bulk refetch helper used by save/delete success paths.\r\n//\r\n// Selection state (selectedRecordId / selectedProductId / draftKind /\r\n// rule wizard / drill-down) intentionally stays in the shell — it is too\r\n// entangled with the editor target and deep linking to move in this slice.\r\n// We accept those values as inputs and expose just the rail data + the\r\n// filter setters back to the shell.\r\n// =============================================================================\r\nimport { useCallback, useEffect, useState } from 'react';\r\nimport type { ScopeKind, RecordStatus, RecordSummary, SmartLinksSDK } from '../types';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport { useRecordList } from './useRecordList';\r\nimport { useFacetBrowse } from './useFacetBrowse';\r\nimport { useProductBrowse, type ProductBrowseItem } from './useProductBrowse';\r\nimport { useProductChildren } from './useProductChildren';\r\nimport {\r\n EMPTY_RULE_FILTERS,\r\n type RuleFilters,\r\n} from '../browser/RuleFilterChips';\r\nimport type { FacetBrowseSelection } from '../browser/FacetBrowseFilter';\r\nimport type { DrillTab } from '../editor/ProductDrillDown';\r\n\r\nexport interface UseShellBrowserOptions {\r\n ctx: RecordsCtx;\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n activeScope: ScopeKind;\r\n contextScope?: { productId?: string; variantId?: string; batchId?: string };\r\n /** Result of `useScopeProbe` — we only need its loading flag. */\r\n probeIsLoading: boolean;\r\n /** From the shell — `cardinality === 'collection'`. */\r\n isCollection: boolean;\r\n /** Selected product (drives variant/batch children fetches). */\r\n selectedProductId: string | undefined;\r\n /** Drill tab inside the product scope. */\r\n drillTab: DrillTab;\r\n /** Optional record classifier passed through from the host. */\r\n classify?: (r: RecordSummary) => RecordStatus;\r\n}\r\n\r\nexport interface UseShellBrowserResult {\r\n // Filter state\r\n search: string;\r\n setSearch: (v: string) => void;\r\n filter: 'all' | RecordStatus;\r\n setFilter: (v: 'all' | RecordStatus) => void;\r\n ruleFilters: RuleFilters;\r\n setRuleFilters: (v: RuleFilters) => void;\r\n facetBrowseFilter: FacetBrowseSelection | null;\r\n setFacetBrowseFilter: (v: FacetBrowseSelection | null) => void;\r\n\r\n // Data sources\r\n productBrowse: ReturnType<typeof useProductBrowse>;\r\n recordList: ReturnType<typeof useRecordList>;\r\n facetBrowse: ReturnType<typeof useFacetBrowse>;\r\n variantChildren: ReturnType<typeof useProductChildren>;\r\n batchChildren: ReturnType<typeof useProductChildren>;\r\n\r\n /** Refetch every browse data source. Used after save/delete. */\r\n refetchAll: () => void;\r\n}\r\n\r\n/** Re-export so the shell keeps a single import surface. */\r\nexport type { ProductBrowseItem };\r\n\r\nexport function useShellBrowser(opts: UseShellBrowserOptions): UseShellBrowserResult {\r\n const {\r\n ctx, SL, collectionId, activeScope, contextScope,\r\n probeIsLoading, isCollection: _isCollection,\r\n selectedProductId, drillTab, classify,\r\n } = opts;\r\n\r\n // ---- Filter state ----------------------------------------------------------\r\n const [search, setSearch] = useState('');\r\n const [filter, setFilter] = useState<'all' | RecordStatus>('all');\r\n const [ruleFilters, setRuleFilters] = useState<RuleFilters>(EMPTY_RULE_FILTERS);\r\n const [facetBrowseFilter, setFacetBrowseFilter] =\r\n useState<FacetBrowseSelection | null>(null);\r\n\r\n // Reset filters whenever the active top-level scope changes. Selection\r\n // resets (selectedRecordId / draftKind) still live in the shell because\r\n // they're entangled with the editor target.\r\n useEffect(() => {\r\n setSearch('');\r\n setFilter('all');\r\n setRuleFilters(EMPTY_RULE_FILTERS);\r\n setFacetBrowseFilter(null);\r\n }, [activeScope]);\r\n\r\n // ---- Browse data ----------------------------------------------------------\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 const recordListEnabled =\r\n (activeScope === 'rule' || activeScope === 'collection')\r\n && !probeIsLoading;\r\n const recordList = useRecordList({\r\n ctx, scopeKind: activeScope, search, filter,\r\n classify,\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: [],\r\n enabled: (activeScope === 'rule' || activeScope === 'collection') && !probeIsLoading,\r\n });\r\n\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 const refetchAll = useCallback(() => {\r\n productBrowse.refetch();\r\n recordList.refetch();\r\n facetBrowse.refetch();\r\n variantChildren.refetch?.();\r\n batchChildren.refetch?.();\r\n }, [productBrowse, recordList, facetBrowse, variantChildren, batchChildren]);\r\n\r\n return {\r\n search, setSearch,\r\n filter, setFilter,\r\n ruleFilters, setRuleFilters,\r\n facetBrowseFilter, setFacetBrowseFilter,\r\n productBrowse, recordList, facetBrowse,\r\n variantChildren, batchChildren,\r\n refetchAll,\r\n };\r\n}","// =============================================================================\r\n// useSingleProduct — Fetch one product by id for the cases where the rail's\r\n// browse list isn't loaded (e.g. when the host pinned a single product via\r\n// `contextScope.productId`, the browse query is disabled to save bandwidth).\r\n//\r\n// Used by the shell to show the friendly product name in the editor header\r\n// instead of the raw productId.\r\n// =============================================================================\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport type { SmartLinksSDK } from '../types';\r\nimport type { ProductBrowseItem } from './useProductBrowse';\r\n\r\nexport interface UseSingleProductArgs {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n productId: string | undefined;\r\n enabled?: boolean;\r\n admin?: boolean;\r\n}\r\n\r\nconst QK = ['records-admin', 'single-product'] as const;\r\n\r\nconst toBrowseItem = (p: any, fallbackId: string): ProductBrowseItem => ({\r\n id: p?.id ?? p?.productId ?? fallbackId,\r\n name: p?.name ?? fallbackId,\r\n sku: p?.sku ?? null,\r\n sortOrder: p?.sortOrder ?? null,\r\n});\r\n\r\n/**\r\n * Resolve a single product by id. Tries the canonical `SL.product.get`\r\n * first, then falls back to `SL.products.get` and finally a list scan\r\n * (older SDKs / in-memory adapters). Returns undefined while loading.\r\n */\r\nexport const useSingleProduct = (args: UseSingleProductArgs) => {\r\n const { SL, collectionId, productId, enabled = true, admin = true } = args;\r\n\r\n const query = useQuery<ProductBrowseItem | null>({\r\n queryKey: [...QK, collectionId, productId, admin],\r\n enabled: enabled && !!collectionId && !!productId,\r\n staleTime: 60_000,\r\n queryFn: async () => {\r\n if (!productId) return null;\r\n try {\r\n if (SL?.product?.get) {\r\n const p = await SL.product.get(collectionId, productId, admin);\r\n if (p) return toBrowseItem(p, productId);\r\n }\r\n if (SL?.products?.get) {\r\n const p = await SL.products.get(collectionId, productId);\r\n if (p) return toBrowseItem(p, productId);\r\n }\r\n // Fallback — list scan. Only acceptable for tiny in-memory adapters.\r\n const list: 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 hit = list.find((p) => (p?.id ?? p?.productId) === productId);\r\n return hit ? toBrowseItem(hit, productId) : null;\r\n } catch {\r\n return null;\r\n }\r\n },\r\n });\r\n\r\n return {\r\n item: query.data ?? null,\r\n isLoading: query.isLoading,\r\n error: query.error as Error | null,\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// 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 /**\r\n * The full parsed scope the value was copied from. Carries scope kind +\r\n * anchors so paste-compat can compare structurally without re-parsing a\r\n * string. The `raw` field is purely for friendly display (toasts).\r\n */\r\n sourceScope: ParsedRef;\r\n /**\r\n * UUID of the source record, when the copy originated from a saved\r\n * AppRecord (records-driven rails, in-editor copy of a saved record).\r\n * Absent when copying from a synthesised anchor row (Products tab) or\r\n * a never-saved draft. Used for self-paste detection.\r\n */\r\n sourceRecordId?: 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// 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// 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// useShellClipboard — extracted from RecordsAdminShell.\r\n//\r\n// Owns every clipboard concern the shell used to bake inline:\r\n// * the cross-shell clipboard store (useRecordClipboard)\r\n// * copy / paste handlers for the active editor\r\n// * row-level copy/paste wiring used by the rail context menu\r\n// * the deferred \"paste once selection settles\" effect\r\n// * the paste-confirm dialog (warn + replace) and the toast notice state\r\n//\r\n// The shell consumes a small, stable surface — `editorClipboard`,\r\n// `rowClipboard`, the paste-confirm dialog node, and the toast renderer —\r\n// instead of the dozen interleaved locals it managed previously.\r\n//\r\n// Pure refactor: no behaviour change. The hook reproduces every branch\r\n// from the original inline code (warn vs deny, replace-confirm, telemetry\r\n// payload shape, deferred row-paste timing).\r\n// =============================================================================\r\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\r\nimport type { ParsedRef, RecordSummary, RecordsAdminI18n, EditorContext, RecordSource } from '../types';\r\nimport type { TelemetryEvent } from '../types/telemetry';\r\nimport { useRecordClipboard, checkPasteCompatibility, cloneValue } from './useRecordClipboard';\r\nimport { usePasteConfirm } from './usePasteConfirm';\r\nimport { ClipboardToast } from '../shell/ClipboardToast';\r\n\r\ntype ClipboardNotice = { message: string; variant: 'copy' | 'paste' } | null;\r\n\r\nexport interface ShellClipboardOnCopyArgs<T> {\r\n value: T;\r\n scope: ParsedRef;\r\n}\r\nexport interface ShellClipboardOnPasteSource<T> {\r\n value: T;\r\n sourceScope: ParsedRef;\r\n}\r\nexport interface ShellClipboardOnPasteDest<T> {\r\n scope: ParsedRef;\r\n currentValue: T | null;\r\n}\r\n\r\nexport interface UseShellClipboardArgs<TData> {\r\n enabled: boolean;\r\n appId: string;\r\n recordType: string | undefined;\r\n i18n: RecordsAdminI18n;\r\n /** Editor context for the active record. */\r\n editorCtx: EditorContext<TData>;\r\n /** Anchors describing what's being edited right now. */\r\n editingScope: ParsedRef | null;\r\n /** Friendly label for toasts and the replace-confirm body. */\r\n editorHeaderLabel: string | undefined;\r\n /** Identity of the currently-selected item in collection cardinality. */\r\n isCollection: boolean;\r\n selectedItemId: string | null;\r\n selectedRecordId: string | null;\r\n /** Resolver state — only `source` and `recordId` are read. */\r\n resolved: { source: RecordSource; recordId?: string };\r\n /** Telemetry sink. */\r\n onTelemetry?: (event: TelemetryEvent) => void;\r\n /** Optional host transforms. */\r\n onCopyOverride?: (args: ShellClipboardOnCopyArgs<TData>) => TData;\r\n onPasteOverride?: (\r\n source: ShellClipboardOnPasteSource<TData>,\r\n dest: ShellClipboardOnPasteDest<TData>,\r\n ) => TData | null;\r\n /**\r\n * Imperative hook the rail will fire when the deferred row-paste\r\n * resolves. The shell owns rail selection; this hook only schedules the\r\n * paste once `editingScope` catches up.\r\n */\r\n onLeftSelectRef: React.MutableRefObject<((item: RecordSummary) => void) | null>;\r\n}\r\n\r\nexport interface ShellEditorClipboard {\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\r\nexport interface ShellRowClipboard {\r\n onCopy?: () => void;\r\n onPaste: () => void;\r\n canPaste: boolean;\r\n pasteWillReplace: boolean;\r\n clipboardSourceLabel?: string;\r\n}\r\n\r\nexport interface UseShellClipboardReturn<TData> {\r\n /** Wired into RecordEditor's `clipboard` slot. */\r\n editorClipboard: ShellEditorClipboard | undefined;\r\n /** Per-row factory for the rail context menu. */\r\n rowClipboard: ((record: RecordSummary) => ShellRowClipboard) | undefined;\r\n /** Render-once dialog for warn/replace confirms. */\r\n confirmDialog: ReactNode;\r\n /** Toast node (or null when nothing to show). */\r\n toast: ReactNode;\r\n /** Underlying store, exposed for advanced callers (rare). */\r\n store: ReturnType<typeof useRecordClipboard<TData>>;\r\n}\r\n\r\nexport function useShellClipboard<TData>(\r\n args: UseShellClipboardArgs<TData>,\r\n): UseShellClipboardReturn<TData> {\r\n const {\r\n enabled, appId, recordType, i18n,\r\n editorCtx, editingScope, editorHeaderLabel,\r\n isCollection, selectedItemId, selectedRecordId,\r\n resolved, onTelemetry,\r\n onCopyOverride, onPasteOverride,\r\n onLeftSelectRef,\r\n } = args;\r\n\r\n const clipboard = useRecordClipboard<TData>({\r\n appId,\r\n recordType: recordType ?? '__default',\r\n });\r\n const pasteConfirm = usePasteConfirm();\r\n const [notice, setNotice] = useState<ClipboardNotice>(null);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Editor-level copy\r\n // ---------------------------------------------------------------------------\r\n const copyCurrent = useCallback(() => {\r\n if (!enabled || !editingScope) return;\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,\r\n sourceRecordId: resolved.recordId,\r\n sourceLabel: editorHeaderLabel,\r\n });\r\n onTelemetry?.({ type: 'clipboard.copy', recordType, sourceRef: editingScope.raw });\r\n setNotice({\r\n message: i18n.copyToast.replace('{name}', editorHeaderLabel ?? editingScope.raw),\r\n variant: 'copy',\r\n });\r\n }, [\r\n enabled, editingScope, onCopyOverride, editorCtx.value, clipboard,\r\n editorHeaderLabel, onTelemetry, recordType, i18n.copyToast, resolved.recordId,\r\n ]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Editor-level paste (warn + replace dialogs)\r\n // ---------------------------------------------------------------------------\r\n const pasteCurrent = useCallback(async () => {\r\n if (!enabled || !editingScope || !clipboard.entry) return;\r\n\r\n const compat = checkPasteCompatibility(clipboard.entry.sourceScope, editingScope);\r\n\r\n if (compat.status === 'denied') {\r\n setNotice({ message: compat.reason ?? 'Paste not allowed here', variant: 'paste' });\r\n return;\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 = clipboard.entry.sourceScope;\r\n const transformed = onPasteOverride\r\n ? onPasteOverride(\r\n { value: clipboard.entry.value as TData, sourceScope: sourceParsed },\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 editorCtx.onChange(transformed);\r\n onTelemetry?.({\r\n type: 'clipboard.paste',\r\n recordType,\r\n sourceRef: clipboard.entry.sourceScope.raw,\r\n destinationRef: editingScope.raw,\r\n replaced: willReplace,\r\n });\r\n setNotice({\r\n message: i18n.pasteToast.replace('{name}', clipboard.entry.sourceLabel ?? clipboard.entry.sourceScope.raw),\r\n variant: 'paste',\r\n });\r\n }, [\r\n enabled, 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 // ---------------------------------------------------------------------------\r\n // Compat check for the editor's own paste affordance.\r\n // ---------------------------------------------------------------------------\r\n const editorPasteCompat = useMemo(() => {\r\n if (!enabled || !clipboard.entry || !editingScope) return null;\r\n const sameRecord = clipboard.entry.sourceRecordId\r\n && resolved.recordId\r\n && clipboard.entry.sourceRecordId === resolved.recordId;\r\n const sameAnchor = !clipboard.entry.sourceRecordId\r\n && clipboard.entry.sourceScope.raw === editingScope.raw;\r\n if (sameRecord || sameAnchor) return { status: 'denied' as const };\r\n return checkPasteCompatibility(clipboard.entry.sourceScope, editingScope);\r\n }, [enabled, clipboard.entry, editingScope, resolved.recordId]);\r\n\r\n const editorClipboard: ShellEditorClipboard | undefined = enabled && 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 // Deferred row-paste — fires once selection ripples through.\r\n // ---------------------------------------------------------------------------\r\n const [pendingPasteTarget, setPendingPasteTarget] = useState<\r\n { kind: 'record'; recordId: string } | { kind: 'anchor'; ref: string } | null\r\n >(null);\r\n\r\n useEffect(() => {\r\n if (!pendingPasteTarget) return;\r\n if (!editingScope) return;\r\n const matched = pendingPasteTarget.kind === 'record'\r\n ? (isCollection ? selectedItemId : selectedRecordId) === pendingPasteTarget.recordId\r\n : editingScope.raw === pendingPasteTarget.ref;\r\n if (!matched) return;\r\n const t = window.setTimeout(() => {\r\n setPendingPasteTarget(null);\r\n void pasteCurrent();\r\n }, 0);\r\n return () => window.clearTimeout(t);\r\n }, [pendingPasteTarget, editingScope, isCollection, selectedItemId, selectedRecordId, pasteCurrent]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Per-row clipboard wiring for the rail context menu.\r\n // ---------------------------------------------------------------------------\r\n const rowClipboard = enabled ? (record: RecordSummary): ShellRowClipboard => {\r\n const summaryHasData = record.data != null;\r\n const sourceParsed: ParsedRef = record.scope;\r\n const compat = clipboard.entry\r\n ? checkPasteCompatibility(clipboard.entry.sourceScope, sourceParsed)\r\n : null;\r\n const sameTarget = clipboard.entry\r\n ? (clipboard.entry.sourceRecordId && record.id\r\n ? clipboard.entry.sourceRecordId === record.id\r\n : clipboard.entry.sourceScope.raw === record.ref)\r\n : false;\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,\r\n sourceRecordId: record.id ?? undefined,\r\n sourceLabel: record.label,\r\n });\r\n onTelemetry?.({ type: 'clipboard.copy', recordType, sourceRef: record.ref });\r\n setNotice({\r\n message: i18n.copyToast.replace('{name}', record.label),\r\n variant: 'copy',\r\n });\r\n } : undefined,\r\n onPaste: () => {\r\n onLeftSelectRef.current?.(record);\r\n setPendingPasteTarget(\r\n record.id\r\n ? { kind: 'record', recordId: record.id }\r\n : { kind: 'anchor', ref: record.ref },\r\n );\r\n },\r\n canPaste: !!clipboard.entry && !sameTarget && (compat?.status !== 'denied'),\r\n pasteWillReplace: record.status === 'configured',\r\n clipboardSourceLabel: clipboard.entry?.sourceLabel,\r\n };\r\n } : undefined;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Render helpers — dialog must mount, toast renders when present.\r\n // ---------------------------------------------------------------------------\r\n const toast = notice ? (\r\n <ClipboardToast\r\n message={notice.message}\r\n variant={notice.variant}\r\n onDismiss={() => setNotice(null)}\r\n />\r\n ) : null;\r\n\r\n return {\r\n editorClipboard,\r\n rowClipboard,\r\n confirmDialog: pasteConfirm.dialog,\r\n toast,\r\n store: clipboard,\r\n };\r\n}","// =============================================================================\r\n// shell/state/useShellPreviewPane.ts\r\n//\r\n// Owns the right-pane preview state — the secondary scope the preview pane\r\n// is pinned against (when the host opts into a scope picker), the drawer /\r\n// side-panel open toggles, and the friendly editor-header label/subtitle/\r\n// meta strings derived from the currently-selected browser row.\r\n//\r\n// Pure UI state — no SDK calls, no resolver dependencies. The shell hands\r\n// in `editingScope`, `activeScope`, and the product browse list and gets\r\n// back a ready-to-render bundle.\r\n// =============================================================================\r\nimport { useEffect, useMemo, useState } from 'react';\r\nimport type { ParsedRef } from '../../types';\r\nimport type { ScopeKind } from '../../types';\r\nimport type { ProductBrowseItem } from '../../hooks/useShellBrowser';\r\n\r\nexport interface UseShellPreviewPaneArgs {\r\n editingScope: ParsedRef | null;\r\n activeScope: ScopeKind;\r\n selectedProductId: string | undefined;\r\n productBrowseItems: ProductBrowseItem[];\r\n}\r\n\r\nexport interface ShellPreviewPane {\r\n /** Independent preview scope. `null` until the user picks one — the\r\n * effective scope falls back to `editingScope` in that case. */\r\n previewScope: ParsedRef | null;\r\n setPreviewScope: (next: ParsedRef | null) => void;\r\n /** What the preview should actually render against right now. */\r\n effectivePreviewScope: ParsedRef | null;\r\n /** Mobile / narrow-screen drawer toggle. */\r\n drawerOpen: boolean;\r\n setDrawerOpen: (next: boolean) => void;\r\n /** Side-panel collapse toggle. Resets to open on each fresh mount. */\r\n sidePreviewOpen: boolean;\r\n setSidePreviewOpen: (next: boolean) => void;\r\n /** Friendly headline for the editor header (product name, etc.). */\r\n editorHeaderLabel: string | undefined;\r\n /** Optional second line under the header label. */\r\n editorHeaderSubtitle: string | undefined;\r\n /** Tiny muted reference (SKU / id) shown top-right of the header. */\r\n editorHeaderMeta: string | undefined;\r\n}\r\n\r\nexport const useShellPreviewPane = (args: UseShellPreviewPaneArgs): ShellPreviewPane => {\r\n const { editingScope, activeScope, selectedProductId, productBrowseItems } = args;\r\n\r\n const [previewScope, setPreviewScope] = useState<ParsedRef | null>(null);\r\n const [drawerOpen, setDrawerOpen] = useState(false);\r\n const [sidePreviewOpen, setSidePreviewOpen] = useState(true);\r\n\r\n // Whenever the editing scope changes, seed the preview scope to follow\r\n // it — but only if the user hasn't 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 // Friendly editor header label — pulled from the currently-selected\r\n // summary (product display name) instead of raw scope keys. Falls back\r\n // to whatever ScopeBreadcrumb would show when no match.\r\n const editorHeaderLabel = useMemo<string | undefined>(() => {\r\n if (!editingScope) return undefined;\r\n if (activeScope === 'product' && selectedProductId) {\r\n const hit = productBrowseItems.find((it) => it.id === selectedProductId);\r\n // Fall back to productId so we never render the raw scope breadcrumb\r\n // (which prefixes \"Product: …\" — too technical for admins).\r\n return hit?.name ?? selectedProductId;\r\n }\r\n return undefined;\r\n }, [activeScope, editingScope, selectedProductId, productBrowseItems]);\r\n\r\n const editorHeaderSubtitle = useMemo<string | undefined>(() => {\r\n if (!editingScope) return undefined;\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 }, [editingScope]);\r\n\r\n // Technical reference shown as a tiny muted caption in the editor\r\n // header's top-right corner. Power users / support can scan it without\r\n // it competing with the friendly title. SKU is preferred over productId.\r\n const editorHeaderMeta = useMemo<string | undefined>(() => {\r\n if (!editingScope) return undefined;\r\n if (activeScope === 'product' && selectedProductId) {\r\n const hit = productBrowseItems.find((it) => it.id === selectedProductId);\r\n return hit?.sku ?? selectedProductId;\r\n }\r\n return undefined;\r\n }, [activeScope, editingScope, selectedProductId, productBrowseItems]);\r\n\r\n return {\r\n previewScope,\r\n setPreviewScope,\r\n effectivePreviewScope,\r\n drawerOpen,\r\n setDrawerOpen,\r\n sidePreviewOpen,\r\n setSidePreviewOpen,\r\n editorHeaderLabel,\r\n editorHeaderSubtitle,\r\n editorHeaderMeta,\r\n };\r\n};","// =============================================================================\r\n// shell/state/useShellNavigation.ts\r\n//\r\n// Collection-cardinality item navigation: open / create / delete / back /\r\n// prev / next / step. All routes through the dirty-nav guard so unsaved\r\n// edits aren't silently lost, and emits the right deep-link transitions\r\n// (`record.open`, `record.close`, `record.step`).\r\n//\r\n// Lives outside the shell so the orchestrator can wire the same handlers\r\n// into the right-pane item list, the editor's sibling nav, and the rail's\r\n// row-paste destination effect without duplicating the dirty-guard wiring.\r\n// =============================================================================\r\nimport { useCallback, useMemo } from 'react';\r\nimport type { QueryClient } from '@tanstack/react-query';\r\nimport { parseRef } from '../../data/refs';\r\nimport { resolvedRecordQueryKey } from '../../hooks/useResolvedRecord';\r\nimport type { ParsedRef } from '../../types';\r\nimport type { TelemetryEvent } from '../../types/telemetry';\r\nimport type { RecordsCtx } from '../../data/records';\r\nimport type { useCollectionItems } from '../../hooks/useCollectionItems';\r\nimport type { useDeepLinkState } from '../../hooks/useDeepLinkState';\r\n\r\ntype CollectionItems<T> = ReturnType<typeof useCollectionItems<T>>;\r\ntype DeepLinkState = ReturnType<typeof useDeepLinkState>;\r\n\r\nconst DRAFT_PREFIX = 'draft:';\r\nconst isDraftId = (id?: string | null): boolean =>\r\n !!id && (id === '__draft__' || id.startsWith(DRAFT_PREFIX));\r\n\r\nconst mintDraftItemId = (): string => {\r\n const rand = (typeof crypto !== 'undefined' && 'randomUUID' in crypto)\r\n ? (crypto as Crypto).randomUUID()\r\n : Math.random().toString(36).slice(2);\r\n return `${DRAFT_PREFIX}${rand}`;\r\n};\r\n\r\nconst coerceDraftItemId = (generateItemId?: () => string): string => {\r\n const candidate = generateItemId ? generateItemId() : mintDraftItemId();\r\n return candidate.startsWith(DRAFT_PREFIX) ? candidate : `${DRAFT_PREFIX}${candidate}`;\r\n};\r\n\r\nexport interface UseShellNavigationArgs<T> {\r\n isCollection: boolean;\r\n runWithGuard: (fn: () => void) => Promise<boolean> | void | Promise<void>;\r\n selectedItemId: string | null;\r\n setSelectedItemId: (next: string | null) => void;\r\n editingScope: ParsedRef | null;\r\n baseScopeRef: string;\r\n collectionItems: CollectionItems<T>;\r\n queryClient: QueryClient;\r\n ctx: RecordsCtx;\r\n collectionId: string;\r\n appId: string;\r\n recordType: string | undefined;\r\n deepLinkState: DeepLinkState;\r\n onTelemetry?: (e: TelemetryEvent) => void;\r\n onBeforeDelete?: (scope: ParsedRef) => boolean | Promise<boolean>;\r\n generateItemId?: () => string;\r\n}\r\n\r\nexport interface ShellItemViewCtx {\r\n onOpen: (itemId: string) => void;\r\n onCreate: () => void;\r\n onDelete: (itemId: string) => void;\r\n scope: ParsedRef;\r\n selectedId: string | undefined;\r\n isLoading: boolean;\r\n}\r\n\r\nexport interface ShellNavigation {\r\n onItemOpen: (itemId: string) => void;\r\n onItemCreate: () => void;\r\n onItemDelete: (itemId: string) => Promise<void>;\r\n onItemBack: () => void;\r\n onItemPrev: () => void;\r\n onItemNext: () => void;\r\n stepToItem: (id: string) => void;\r\n itemPosition: { index: number; total: number } | null;\r\n itemViewCtx: ShellItemViewCtx;\r\n buildItemUrlValue: (id: string) => string;\r\n}\r\n\r\nexport function useShellNavigation<T>(args: UseShellNavigationArgs<T>): ShellNavigation {\r\n const {\r\n isCollection, runWithGuard, selectedItemId, setSelectedItemId,\r\n editingScope, baseScopeRef, collectionItems, queryClient, ctx,\r\n collectionId, appId, recordType, deepLinkState, onTelemetry,\r\n onBeforeDelete, generateItemId,\r\n } = args;\r\n\r\n const buildItemUrlValue = useCallback((id: string): string => {\r\n if (!baseScopeRef && id.startsWith('item:')) return id;\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 // eslint-disable-next-line no-console\r\n console.info('[RecordsAdminShell] item open requested', {\r\n itemId, scopeRef: baseScopeRef, previousSelectedItemId: selectedItemId,\r\n });\r\n // Prime the resolved-record cache from the row we already loaded in\r\n // collectionItems so the editor doesn't briefly render against null\r\n // while getRecordById round-trips.\r\n if (!isDraftId(itemId)) {\r\n const row = collectionItems.items.find((it) => it.itemId === itemId || it.id === itemId);\r\n if (row && row.data !== undefined) {\r\n const cacheKey = resolvedRecordQueryKey({\r\n collectionId, appId, recordType,\r\n productId: editingScope?.productId,\r\n variantId: editingScope?.variantId,\r\n batchId: editingScope?.batchId,\r\n facetId: editingScope?.facetId,\r\n facetValue: editingScope?.facetValue,\r\n proofId: editingScope?.proofId,\r\n recordId: itemId,\r\n withParent: true,\r\n });\r\n if (queryClient.getQueryData(cacheKey) === undefined) {\r\n queryClient.setQueryData(cacheKey, {\r\n data: row.data,\r\n source: 'self',\r\n sourceRef: row.ref || undefined,\r\n recordId: itemId,\r\n facetRule: row.facetRule ?? null,\r\n });\r\n }\r\n }\r\n }\r\n setSelectedItemId(itemId);\r\n onTelemetry?.({ type: 'item.open', recordType, scopeRef: baseScopeRef, itemId });\r\n deepLinkState.emit({ recordId: itemId, scope: baseScopeRef || null }, 'record.open');\r\n });\r\n }, [\r\n isCollection, runWithGuard, baseScopeRef, selectedItemId, collectionItems.items,\r\n queryClient, collectionId, appId, recordType, editingScope, setSelectedItemId,\r\n onTelemetry, deepLinkState,\r\n ]);\r\n\r\n const onItemCreate = useCallback(() => {\r\n if (!isCollection) return;\r\n void runWithGuard(() => {\r\n // Item drafts have no UUID until first save — mint a unique synthetic\r\n // id so multiple drafts never collide and the literal `__draft__`\r\n // token never reaches host UI or `scope.raw`.\r\n const id = coerceDraftItemId(generateItemId);\r\n setSelectedItemId(id);\r\n onTelemetry?.({ type: 'item.create', recordType, scopeRef: baseScopeRef });\r\n // Brand-new draft has no server id yet — clear `recordId` and rely\r\n // on `scope` to put the user back in the right rail context. The\r\n // URL gains a real `recordId` on first save.\r\n deepLinkState.emit({ recordId: null, scope: baseScopeRef || null }, 'record.open');\r\n });\r\n }, [\r\n isCollection, runWithGuard, generateItemId, setSelectedItemId,\r\n onTelemetry, recordType, baseScopeRef, deepLinkState,\r\n ]);\r\n\r\n const onItemDelete = useCallback(async (itemId: string) => {\r\n if (!isCollection) return;\r\n if (isDraftId(itemId)) return; // unsaved draft — nothing on the server\r\n if (onBeforeDelete) {\r\n const ok = await onBeforeDelete(editingScope ?? parseRef(''));\r\n if (!ok) return;\r\n }\r\n try {\r\n const { removeRecord } = await import('../../data/records');\r\n await removeRecord(ctx, itemId);\r\n onTelemetry?.({ type: 'item.delete', recordType, scopeRef: baseScopeRef, itemId });\r\n if (selectedItemId === itemId) setSelectedItemId(null);\r\n if (selectedItemId === itemId) deepLinkState.emit({ recordId: null }, 'record.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, editingScope, setSelectedItemId,\r\n ]);\r\n\r\n const itemViewCtx = useMemo<ShellItemViewCtx>(() => ({\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 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({ recordId: null }, 'record.close');\r\n });\r\n }, [runWithGuard, deepLinkState, setSelectedItemId]);\r\n\r\n // Prev/next moves use `record.step` so the URL replaces rather than\r\n // pushes — back goes to the *list*, not through every sibling.\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({ recordId: id, scope: baseScopeRef || null }, 'record.step');\r\n });\r\n }, [runWithGuard, onTelemetry, recordType, baseScopeRef, deepLinkState, setSelectedItemId]);\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 return {\r\n onItemOpen, onItemCreate, onItemDelete,\r\n onItemBack, onItemPrev, onItemNext,\r\n stepToItem, itemPosition, itemViewCtx, buildItemUrlValue,\r\n };\r\n}","// =============================================================================\r\n// shell/state/useEditingScope.ts\r\n//\r\n// Pure derivation of the two anchor scopes the rest of the shell points\r\n// the resolver/editor at:\r\n//\r\n// - editingScope — folder anchors. In singleton mode this is\r\n// also the editor's target. In collection mode\r\n// it's the bucket items live under.\r\n// - editingTargetScope — what the resolver/editor actually loads.\r\n// Equals editingScope in singleton mode, gains\r\n// an `item:<recordId>` suffix in collection\r\n// mode when an item is open.\r\n//\r\n// All branching that used to sit in two large useMemo blocks lives here.\r\n// No effects, no SDK calls — easy to reason about and test in isolation.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport { parseRef, buildRef } from '../../data/refs';\r\nimport type { ParsedRef, ScopeKind, RecordSummary } from '../../types';\r\nimport type { RecordCardinality } from '../../types/presentation';\r\nimport type { DrillTab } from '../../editor/ProductDrillDown';\r\n\r\nconst DRAFT_ID = '__draft__';\r\n\r\nexport interface UseEditingScopeArgs {\r\n activeScope: ScopeKind;\r\n cardinality: RecordCardinality;\r\n selectedRecordId: string | null;\r\n draftKind: 'rule' | 'global' | 'item' | null;\r\n ruleWizardStep: 1 | 2 | null;\r\n recordListItems: RecordSummary[];\r\n selectedProductId: string | undefined;\r\n drillTab: DrillTab;\r\n selectedVariantId: string | undefined;\r\n selectedBatchId: string | undefined;\r\n selectedItemId: string | null;\r\n}\r\n\r\nexport interface EditingScopes {\r\n editingScope: ParsedRef | null;\r\n editingTargetScope: ParsedRef | null;\r\n isCollection: boolean;\r\n editingItemRecordId: string | null;\r\n baseScopeRef: string;\r\n}\r\n\r\nexport const useEditingScope = (args: UseEditingScopeArgs): EditingScopes => {\r\n const {\r\n activeScope, cardinality, selectedRecordId, draftKind, ruleWizardStep,\r\n recordListItems, selectedProductId, drillTab, selectedVariantId,\r\n selectedBatchId, selectedItemId,\r\n } = args;\r\n\r\n const isCollection = cardinality === 'collection';\r\n const editingItemRecordId: string | null = isCollection ? selectedItemId : null;\r\n\r\n const editingScope: ParsedRef | null = useMemo(() => {\r\n // Records-driven tabs (rule, collection/global).\r\n if (activeScope === 'rule' || activeScope === 'collection') {\r\n // New-rule wizard, collection cardinality: the rule isn't a saved\r\n // record yet. Synthesise the same `rule:__draft__` ParsedRef the\r\n // singleton draft path uses so collectionItems and editingTargetScope\r\n // can resolve.\r\n if (activeScope === 'rule' && ruleWizardStep === 2 && selectedRecordId === null) {\r\n return { ...parseRef(''), kind: 'rule', raw: 'rule:__draft__' } as ParsedRef;\r\n }\r\n if (selectedRecordId === null) {\r\n // Collection-cardinality + Global tab: anchor at the collection\r\n // root so the item list view actually mounts.\r\n if (activeScope === 'collection' && cardinality === 'collection') {\r\n return parseRef('');\r\n }\r\n return null;\r\n }\r\n if (selectedRecordId === DRAFT_ID) {\r\n if (draftKind === 'rule') {\r\n return { ...parseRef(''), kind: 'rule', raw: 'rule:__draft__' } as ParsedRef;\r\n }\r\n return parseRef('');\r\n }\r\n // Saved record — pull anchors straight off its summary.\r\n const hit = recordListItems.find((it) => it.id === selectedRecordId);\r\n if (!hit) return null;\r\n return hit.scope;\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 }, [\r\n activeScope, cardinality, selectedRecordId, draftKind, ruleWizardStep,\r\n recordListItems, selectedProductId, drillTab, selectedVariantId,\r\n selectedBatchId,\r\n ]);\r\n\r\n const editingTargetScope: ParsedRef | null = useMemo(() => {\r\n if (!editingScope) return null;\r\n if (!isCollection || !editingItemRecordId) return editingScope;\r\n return {\r\n ...editingScope,\r\n itemId: editingItemRecordId,\r\n raw: editingScope.raw\r\n ? `${editingScope.raw}/item:${editingItemRecordId}`\r\n : `item:${editingItemRecordId}`,\r\n };\r\n }, [editingScope, isCollection, editingItemRecordId]);\r\n\r\n const baseScopeRef = editingScope?.raw ?? '';\r\n\r\n return { editingScope, editingTargetScope, isCollection, editingItemRecordId, baseScopeRef };\r\n};","// =============================================================================\r\n// shell/state/useShellDeepLink.ts\r\n//\r\n// Owns the URL <-> shell round-trip. Two effects:\r\n// 1. Emit `scope` whenever the rail moves and no item is open.\r\n// 2. Apply external URL changes (initial mount, host nav, back/forward)\r\n// to shell selection state, deduped by signature so our own emits\r\n// don't bounce back through here.\r\n//\r\n// The shell still owns the actual selection setters — this hook accepts\r\n// them so the restore effect can reach in and adjust state without the\r\n// orchestrator inlining all the URL parsing.\r\n// =============================================================================\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { parseRef } from '../../data/refs';\r\nimport type { ItemView, ParsedRef, ScopeKind } from '../../types';\r\nimport type { DrillTab } from '../../editor/ProductDrillDown';\r\nimport type { useDeepLinkState } from '../../hooks/useDeepLinkState';\r\nimport type { FacetBrowseSelection } from '../../browser/FacetBrowseFilter';\r\n\r\ntype DeepLinkState = ReturnType<typeof useDeepLinkState>;\r\n\r\nexport interface UseShellDeepLinkArgs {\r\n deepLinkState: DeepLinkState;\r\n editingScope: ParsedRef | null;\r\n selectedItemId: string | null;\r\n itemView: ItemView;\r\n itemViews: ItemView[];\r\n setItemView: (next: ItemView) => void;\r\n activeScope: ScopeKind;\r\n setActiveScope: (next: ScopeKind) => void;\r\n topLevelScopes: ScopeKind[];\r\n selectedRecordId: string | null;\r\n setSelectedRecordId: (next: string | null) => void;\r\n selectedProductId: string | undefined;\r\n setSelectedProductId: (next: string | undefined) => void;\r\n drillTab: DrillTab;\r\n setDrillTab: (next: DrillTab) => void;\r\n selectedVariantId: string | undefined;\r\n setSelectedVariantId: (next: string | undefined) => void;\r\n selectedBatchId: string | undefined;\r\n setSelectedBatchId: (next: string | undefined) => void;\r\n setFacetBrowseFilter: (next: FacetBrowseSelection | null) => void;\r\n}\r\n\r\nexport interface ShellDeepLink {\r\n /** URL-supplied recordId pending resolution. Currently informational —\r\n * set by the restore effect, observed by future loaders. */\r\n pendingDeepLinkRecordId: string | null;\r\n /** Mutable echo signature — also written by item nav handlers so an\r\n * emit from there isn't immediately re-applied by the restore effect. */\r\n lastAppliedDLRef: React.MutableRefObject<string>;\r\n}\r\n\r\nexport const useShellDeepLink = (args: UseShellDeepLinkArgs): ShellDeepLink => {\r\n const {\r\n deepLinkState, editingScope, selectedItemId, itemView, itemViews, setItemView,\r\n activeScope, setActiveScope, topLevelScopes,\r\n selectedRecordId, setSelectedRecordId,\r\n selectedProductId, setSelectedProductId,\r\n drillTab, setDrillTab,\r\n selectedVariantId, setSelectedVariantId,\r\n selectedBatchId, setSelectedBatchId,\r\n setFacetBrowseFilter,\r\n } = args;\r\n\r\n const lastAppliedDLRef = useRef<string>('');\r\n const [pendingDeepLinkRecordId, setPendingDeepLinkRecordId] = useState<string | null>(null);\r\n\r\n // Emit `scope` whenever the rail moves and no item is open. Item moves are\r\n // covered by per-handler emits in useShellNavigation and carry their own\r\n // scope inside the ref, so we deliberately skip this emit while an item\r\n // is open. Internal-vs-external echo is filtered via `lastAppliedDLRef`.\r\n useEffect(() => {\r\n if (!deepLinkState.enabled) return;\r\n if (selectedItemId) return;\r\n deepLinkState.emit({ scope: editingScope?.raw ?? null, recordId: null }, 'scope');\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 // Restore — apply URL state to shell state when the URL changes externally.\r\n useEffect(() => {\r\n if (!deepLinkState.enabled) return;\r\n const { recordId, scope, view } = deepLinkState.urlState;\r\n const sig = `${recordId ?? ''}|${scope ?? ''}|${view ?? ''}`;\r\n if (sig === lastAppliedDLRef.current) return;\r\n lastAppliedDLRef.current = sig;\r\n\r\n if (view && itemViews.includes(view as ItemView) && view !== itemView) {\r\n setItemView(view as ItemView);\r\n }\r\n\r\n const railRef: string = scope ?? '';\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 // Legacy <0.5 deep link — facet tab is gone, land on Rules and pre-fill\r\n // the \"Browse by facet\" filter so the user gets equivalent context.\r\n if (activeScope !== 'rule' && topLevelScopes.includes('rule')) setActiveScope('rule');\r\n if (parsed.facetValue) {\r\n setFacetBrowseFilter({ facetKey: parsed.facetId, facetValue: parsed.facetValue });\r\n }\r\n if (selectedRecordId !== null) setSelectedRecordId(null);\r\n } else {\r\n if (selectedRecordId !== null) setSelectedRecordId(null);\r\n }\r\n\r\n setPendingDeepLinkRecordId(recordId ?? null);\r\n if (!recordId && selectedItemId !== null) {\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdminShell] preserving selected item during restore without recordId', {\r\n selectedItemId, scope, view,\r\n });\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [deepLinkState.enabled, deepLinkState.urlState]);\r\n\r\n return { pendingDeepLinkRecordId, lastAppliedDLRef };\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 // SDK 1.10.2 reshaped `PreviewRuleResult`:\r\n // `totalMatches` → `total`\r\n // `sampleProductIds: string[]` → `matchingProducts: [{ productId, name?, facets }]`\r\n // We project back to the legacy hook shape so consumers don't break.\r\n return {\r\n totalMatches: query.data?.total ?? null,\r\n sampleProductIds: (query.data?.matchingProducts ?? []).map((p) => p.productId),\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// editor-session/editorStore.ts\r\n//\r\n// Single source of truth for every open editor session. Replaces the\r\n// distributed state that used to live across:\r\n// - useRecordEditor local React state (value, baseline, facetRule)\r\n// - useDirtyDraftStore (drafts keyed by inferred identity)\r\n// - the react-query resolver cache (optimistic pre-writes)\r\n//\r\n// The store is pure TypeScript (no React) and exposes a small subscribe-\r\n// snapshot API that React consumers wire into via useSyncExternalStore.\r\n//\r\n// Identity rules:\r\n// * editorId is opaque, minted by SelectionController, stable for the\r\n// lifetime of the entry. Once minted it never moves.\r\n// * findExistingEditorIdFor(spec) decides whether a new selection should\r\n// focus an existing entry instead of minting a new one. This is the\r\n// ONLY place identity is inferred from a target spec, and it runs\r\n// once per selection (not on every render).\r\n// =============================================================================\r\nimport { parsedRefToScope } from '../data/scopeBridge';\r\nimport {\r\n upsertRecord, updateRecord, removeRecord, createRecord,\r\n type RecordsCtx,\r\n} from '../data/records';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport type { ResolvedRecord } from '../types';\r\nimport type {\r\n EditorEntry, EditorId, EditorSaveSpec, EditorStatus, EditorTargetSpec,\r\n} from './types';\r\n\r\ntype Listener = () => void;\r\n\r\nconst isEqual = (a: unknown, b: unknown): boolean => {\r\n if (a === b) return true;\r\n try { return JSON.stringify(a) === JSON.stringify(b); }\r\n catch { return false; }\r\n};\r\n\r\nconst cloneDeep = <T,>(v: T): T => {\r\n if (v == null) return v;\r\n try { return structuredClone(v); }\r\n catch { return JSON.parse(JSON.stringify(v)) as T; }\r\n};\r\n\r\nconst TITLE_KEYS = ['title', 'name', 'label', 'heading', 'question', 'slug'] as const;\r\nconst TITLE_WRAPPERS = ['display', 'content', 'meta', 'data'] as const;\r\n\r\n/** Default label heuristic — matches legacy deriveDraftLabel so the tray\r\n * and sidebar continue to agree on row titles. */\r\nexport const deriveDefaultLabel = (value: unknown, spec: EditorTargetSpec): string => {\r\n const pickString = (obj: Record<string, unknown> | null | undefined): string | undefined => {\r\n if (!obj || typeof obj !== 'object') return undefined;\r\n for (const key of TITLE_KEYS) {\r\n const raw = obj[key];\r\n if (typeof raw === 'string' && raw.trim()) return raw.trim();\r\n }\r\n return undefined;\r\n };\r\n const v = value as Record<string, unknown> | null | undefined;\r\n const top = pickString(v);\r\n if (top) return top;\r\n if (v && typeof v === 'object') {\r\n for (const wrapper of TITLE_WRAPPERS) {\r\n const nested = pickString(v[wrapper] as Record<string, unknown> | undefined);\r\n if (nested) return nested;\r\n }\r\n }\r\n if (spec.scope.raw?.startsWith('item:')) return 'Untitled item';\r\n if (spec.scope.kind === 'rule') return 'Rule';\r\n if (spec.scope.kind && spec.scope.kind !== 'collection') {\r\n return spec.scope.kind.charAt(0).toUpperCase() + spec.scope.kind.slice(1);\r\n }\r\n return 'Default';\r\n};\r\n\r\nexport interface EditorStoreOpenInput {\r\n spec: EditorTargetSpec;\r\n saveSpec: EditorSaveSpec;\r\n seed: {\r\n value: unknown;\r\n facetRule: FacetRule | null;\r\n source: ResolvedRecord<unknown>['source'];\r\n parentValue: unknown;\r\n recordId?: string;\r\n } | null;\r\n defaultValue: unknown;\r\n editorId?: EditorId;\r\n label?: string;\r\n}\r\n\r\nexport interface EditorStore {\r\n list(): EditorEntry[];\r\n get(editorId: EditorId): EditorEntry | undefined;\r\n /** Find an alive entry that already represents `spec`. Used by\r\n * SelectionController to focus instead of minting a duplicate. */\r\n findExistingEditorIdFor(spec: EditorTargetSpec): EditorId | undefined;\r\n\r\n open(input: EditorStoreOpenInput): EditorId;\r\n close(editorId: EditorId): boolean;\r\n clearUnpinned(): void;\r\n\r\n setValue(editorId: EditorId, next: unknown | ((prev: unknown) => unknown)): void;\r\n setFacetRule(editorId: EditorId, next: FacetRule | null): void;\r\n\r\n /** Seed value/baseline from a fresh resolver result. No-op once the\r\n * editor has been touched — the store owns the value from then on. */\r\n hydrateFromResolver(editorId: EditorId, resolved: ResolvedRecord<unknown>): void;\r\n\r\n markMounted(editorId: EditorId): void;\r\n markActive(editorId: EditorId): void;\r\n\r\n save(editorId: EditorId): Promise<void>;\r\n reset(editorId: EditorId): void;\r\n remove(editorId: EditorId): Promise<void>;\r\n\r\n /** LRU-evict clean entries until alive count <= max. Pinned entries\r\n * (dirty/saving/error) are never evicted. */\r\n enforcePoolLimit(max: number, exceptEditorId?: EditorId): void;\r\n\r\n subscribe(listener: Listener): () => void;\r\n}\r\n\r\nlet editorIdCounter = 0;\r\nconst mintEditorId = (): EditorId => {\r\n editorIdCounter += 1;\r\n return `ed_${Date.now().toString(36)}_${editorIdCounter.toString(36)}`;\r\n};\r\n\r\nconst recomputePinned = (e: EditorEntry): boolean => {\r\n if (e.status === 'saving' || e.status === 'error') return true;\r\n if (e.status === 'dirty') return true;\r\n return false;\r\n};\r\n\r\nconst recomputeStatus = (e: EditorEntry): EditorStatus => {\r\n if (e.status === 'saving') return 'saving';\r\n if (e.status === 'error') return 'error';\r\n const valueDiff = !isEqual(e.value, e.baseline);\r\n const ruleDiff = !isEqual(e.facetRule, e.baselineFacetRule);\r\n if (valueDiff || ruleDiff) return 'dirty';\r\n return e.status === 'saved' ? 'saved' : 'idle';\r\n};\r\n\r\nexport const createEditorStore = (): EditorStore => {\r\n const map = new Map<EditorId, EditorEntry>();\r\n const listeners = new Set<Listener>();\r\n let cachedList: EditorEntry[] = [];\r\n let nextOrder = 0;\r\n\r\n const recompute = () => {\r\n cachedList = Array.from(map.values()).sort((a, b) => a.order - b.order);\r\n };\r\n const emit = () => {\r\n recompute();\r\n listeners.forEach((l) => l());\r\n };\r\n\r\n const update = (editorId: EditorId, mut: (e: EditorEntry) => EditorEntry | void): boolean => {\r\n const prev = map.get(editorId);\r\n if (!prev) return false;\r\n const draft: EditorEntry = { ...prev };\r\n const result = mut(draft);\r\n const next = (result as EditorEntry | undefined) ?? draft;\r\n next.status = recomputeStatus(next);\r\n next.pinned = recomputePinned(next);\r\n map.set(editorId, next);\r\n emit();\r\n return true;\r\n };\r\n\r\n return {\r\n list: () => cachedList,\r\n get: (editorId) => map.get(editorId),\r\n\r\n findExistingEditorIdFor(spec) {\r\n if (spec.recordId) {\r\n for (const entry of map.values()) {\r\n if (entry.recordId === spec.recordId) return entry.editorId;\r\n }\r\n }\r\n const wantCreate = !!spec.createMode;\r\n // Draft entries: match by draftKey when supplied so sibling drafts\r\n // (e.g. two unsaved item drafts under the same rule) keep distinct\r\n // pool slots instead of focusing the first one we minted.\r\n if (spec.draftKey) {\r\n for (const entry of map.values()) {\r\n if (entry.spec.draftKey === spec.draftKey) return entry.editorId;\r\n }\r\n // No existing entry with this draftKey — let `open()` mint a fresh\r\n // one. Skip the scope.raw fallback below; otherwise two drafts\r\n // sharing the same parent scope (rule wizard + item drafts) would\r\n // collide on `scope.raw` and silently overwrite each other.\r\n return undefined;\r\n }\r\n for (const entry of map.values()) {\r\n if (entry.recordId) continue;\r\n if (entry.spec.scope.raw !== spec.scope.raw) continue;\r\n if (!!entry.spec.createMode !== wantCreate) continue;\r\n return entry.editorId;\r\n }\r\n return undefined;\r\n },\r\n\r\n open(input) {\r\n const editorId = input.editorId ?? mintEditorId();\r\n if (map.has(editorId)) return editorId;\r\n\r\n const seedValue = input.seed?.value ?? input.defaultValue;\r\n // `spec.initialFacetRule` is an explicit caller intent (e.g. the\r\n // new-rule wizard handing a freshly-configured rule to a brand-new\r\n // draft editor). It must win over whatever the resolver happened to\r\n // surface for the anchor scope — that resolved record is unrelated\r\n // to the draft we're about to open. Falling back to `seed.facetRule`\r\n // covers the legacy resume-existing-record path.\r\n const seedFacetRule =\r\n input.spec.initialFacetRule !== undefined && input.spec.initialFacetRule !== null\r\n ? input.spec.initialFacetRule\r\n : (input.seed?.facetRule ?? null);\r\n const source = input.seed?.source ?? 'empty';\r\n const value = cloneDeep(seedValue);\r\n const baseline = cloneDeep(seedValue);\r\n const entry: EditorEntry = {\r\n editorId,\r\n spec: input.spec,\r\n saveSpec: input.saveSpec,\r\n value,\r\n baseline,\r\n facetRule: seedFacetRule,\r\n baselineFacetRule: seedFacetRule,\r\n status: 'idle',\r\n source,\r\n recordId: input.seed?.recordId ?? input.spec.recordId,\r\n parentValue: input.seed?.parentValue ?? null,\r\n label: input.label ?? input.spec.label ?? deriveDefaultLabel(value, input.spec),\r\n order: nextOrder++,\r\n lastActiveAt: Date.now(),\r\n pinned: false,\r\n mounted: false,\r\n };\r\n map.set(editorId, entry);\r\n emit();\r\n return editorId;\r\n },\r\n\r\n close(editorId) {\r\n const entry = map.get(editorId);\r\n if (!entry) return false;\r\n if (entry.pinned) return false;\r\n map.delete(editorId);\r\n emit();\r\n return true;\r\n },\r\n\r\n clearUnpinned() {\r\n let changed = false;\r\n for (const [id, entry] of map.entries()) {\r\n if (!entry.pinned) { map.delete(id); changed = true; }\r\n }\r\n if (changed) emit();\r\n },\r\n\r\n setValue(editorId, next) {\r\n update(editorId, (e) => {\r\n const prev = e.value;\r\n const resolved = typeof next === 'function'\r\n ? (next as (p: unknown) => unknown)(prev)\r\n : next;\r\n e.value = resolved;\r\n if (e.status === 'saved' || e.status === 'error') {\r\n e.status = 'idle';\r\n e.error = undefined;\r\n }\r\n if (!e.spec.label) {\r\n e.label = deriveDefaultLabel(e.value, e.spec);\r\n }\r\n });\r\n },\r\n\r\n setFacetRule(editorId, next) {\r\n update(editorId, (e) => {\r\n e.facetRule = next;\r\n if (e.status === 'saved' || e.status === 'error') {\r\n e.status = 'idle';\r\n e.error = undefined;\r\n }\r\n });\r\n },\r\n\r\n hydrateFromResolver(editorId, resolved) {\r\n const entry = map.get(editorId);\r\n if (!entry) return;\r\n if (entry.status === 'dirty' || entry.status === 'saving' || entry.status === 'error') return;\r\n if (entry.status === 'saved') {\r\n update(editorId, (e) => {\r\n e.source = resolved.source;\r\n if (resolved.recordId) e.recordId = resolved.recordId;\r\n e.parentValue = (resolved.parentValue ?? null) as unknown;\r\n });\r\n return;\r\n }\r\n update(editorId, (e) => {\r\n const fresh = resolved.data == null\r\n ? e.value\r\n : cloneDeep(resolved.data as unknown);\r\n e.value = fresh;\r\n e.baseline = cloneDeep(fresh);\r\n const rule = (resolved as ResolvedRecord<unknown> & { facetRule?: FacetRule | null }).facetRule ?? e.facetRule;\r\n e.facetRule = rule;\r\n e.baselineFacetRule = rule;\r\n e.source = resolved.source;\r\n if (resolved.recordId) e.recordId = resolved.recordId;\r\n e.parentValue = (resolved.parentValue ?? null) as unknown;\r\n if (!e.spec.label) e.label = deriveDefaultLabel(fresh, e.spec);\r\n });\r\n },\r\n\r\n markMounted(editorId) {\r\n update(editorId, (e) => { e.mounted = true; });\r\n },\r\n\r\n markActive(editorId) {\r\n update(editorId, (e) => { e.lastActiveAt = Date.now(); });\r\n },\r\n\r\n async save(editorId) {\r\n const entry = map.get(editorId);\r\n if (!entry) return;\r\n if (entry.status !== 'dirty' && entry.status !== 'error') return;\r\n\r\n const persistedValue = entry.value;\r\n const persistedFacetRule = entry.facetRule;\r\n const { ctx, anchors } = entry.saveSpec;\r\n const spec = entry.spec;\r\n\r\n update(editorId, (e) => { e.status = 'saving'; e.error = undefined; });\r\n\r\n try {\r\n let nextRecordId = entry.recordId;\r\n if (entry.recordId && entry.source === 'self') {\r\n await updateRecord(ctx, entry.recordId, {\r\n data: persistedValue,\r\n facetRule: persistedFacetRule,\r\n });\r\n } else if (spec.createMode) {\r\n const created = await createRecord(ctx, {\r\n // Draft scopes synthesise placeholder refs (`rule:__draft__`,\r\n // `/item:draft:...`) for shell-internal routing only — never\r\n // forward them to the SDK as an external ref. Saved rules\r\n // still pass their real `rule:{id}` string through.\r\n ref: spec.isDraftScope\r\n ? spec.ref\r\n : (spec.scope.kind === 'rule' && spec.scope.raw ? spec.scope.raw : spec.ref),\r\n scope: anchors,\r\n data: persistedValue,\r\n facetRule: persistedFacetRule,\r\n });\r\n nextRecordId = (created as { id?: string } | undefined)?.id ?? nextRecordId;\r\n } else {\r\n const upserted = await upsertRecord(ctx, {\r\n ref: spec.isDraftScope\r\n ? spec.ref\r\n : (spec.scope.kind === 'rule' && spec.scope.raw ? spec.scope.raw : spec.ref),\r\n scope: anchors,\r\n data: persistedValue,\r\n facetRule: persistedFacetRule,\r\n });\r\n nextRecordId = upserted.record?.id ?? nextRecordId;\r\n }\r\n\r\n update(editorId, (e) => {\r\n // Reset the baseline against whatever the editor currently holds,\r\n // not just the snapshot we sent to the server. Hosts whose editors\r\n // re-fire `onChange` during the in-flight save (e.g. controlled\r\n // form libraries that normalise values on every render) would\r\n // otherwise leave the entry stuck in 'dirty' immediately after a\r\n // successful save: `persistedValue` no longer matches `e.value`,\r\n // so `recomputeStatus` flips status back from 'saved' to 'dirty'\r\n // and the SaveAllProgress dialog never advances past 0/N.\r\n //\r\n // The persisted value is still what's on the server; if the user\r\n // genuinely changed the value mid-save we accept that as the new\r\n // baseline and move on. This matches typical form-library\r\n // behaviour and avoids spurious dirtiness from cosmetic re-renders.\r\n e.baseline = cloneDeep(e.value);\r\n e.baselineFacetRule = e.facetRule;\r\n e.recordId = nextRecordId;\r\n e.source = 'self';\r\n e.status = 'saved';\r\n e.error = undefined;\r\n });\r\n } catch (err) {\r\n update(editorId, (e) => {\r\n e.status = 'error';\r\n e.error = err;\r\n });\r\n throw err;\r\n }\r\n },\r\n\r\n reset(editorId) {\r\n update(editorId, (e) => {\r\n e.value = cloneDeep(e.baseline);\r\n e.facetRule = e.baselineFacetRule;\r\n e.status = 'idle';\r\n e.error = undefined;\r\n });\r\n },\r\n\r\n async remove(editorId) {\r\n const entry = map.get(editorId);\r\n if (!entry) return;\r\n if (entry.source !== 'self') return;\r\n if (!entry.recordId) return;\r\n await removeRecord(entry.saveSpec.ctx, entry.recordId);\r\n map.delete(editorId);\r\n emit();\r\n },\r\n\r\n enforcePoolLimit(max, exceptEditorId) {\r\n const alive = Array.from(map.values());\r\n if (alive.length <= max) return;\r\n const evictable = alive\r\n .filter((e) => !e.pinned && e.editorId !== exceptEditorId)\r\n .sort((a, b) => a.lastActiveAt - b.lastActiveAt);\r\n let toEvict = alive.length - max;\r\n let changed = false;\r\n for (const entry of evictable) {\r\n if (toEvict <= 0) break;\r\n map.delete(entry.editorId);\r\n toEvict -= 1;\r\n changed = true;\r\n }\r\n if (changed) emit();\r\n },\r\n\r\n subscribe(listener) {\r\n listeners.add(listener);\r\n return () => { listeners.delete(listener); };\r\n },\r\n };\r\n};\r\n\r\nexport const buildSaveSpec = (\r\n ctx: RecordsCtx,\r\n spec: EditorTargetSpec,\r\n): EditorSaveSpec => ({\r\n ctx,\r\n anchors: parsedRefToScope(spec.scope),\r\n});\r\n","// =============================================================================\r\n// editor-session/EditorSessionProvider.tsx\r\n//\r\n// React surface over the EditorStore. Exposes:\r\n// * EditorSessionProvider — owns one EditorStore per mount\r\n// * useEditorSession(editorId) — the hook custom editor renderers use\r\n// * useEditorSelection() — selectTarget / current / open list\r\n// * useDirtyOverview() — header pill / tray / save-all\r\n//\r\n// Identity is ALWAYS supplied to consumers via editorId. We never re-derive\r\n// it from (scope, resolved) in this layer — that's the SelectionController's\r\n// job, and it happens once per click.\r\n// =============================================================================\r\nimport {\r\n createContext, useCallback, useContext, useMemo, useRef,\r\n useSyncExternalStore, type ReactNode,\r\n} from 'react';\r\nimport { useQueryClient } from '@tanstack/react-query';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport type { ParsedRef, ResolvedRecord } from '../types';\r\nimport { resolvedRecordQueryKey } from '../hooks/useResolvedRecord';\r\nimport { isFacetRuleValid } from '../hooks/useRulePreview';\r\nimport {\r\n createEditorStore, buildSaveSpec, type EditorStore,\r\n} from './editorStore';\r\nimport type {\r\n DirtyOverview, DirtyOverviewItem, EditorEntry, EditorId, EditorSession,\r\n EditorTargetSpec,\r\n} from './types';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Context shape — internal. Consumers reach for the hooks below.\r\n// ---------------------------------------------------------------------------\r\ninterface EditorSessionContextValue {\r\n store: EditorStore;\r\n ctx: RecordsCtx;\r\n /** Currently active editor (visible one in the mount pool). */\r\n currentEditorId: EditorId | undefined;\r\n setCurrentEditorId: (id: EditorId | undefined) => void;\r\n /** Pool size hint, used by enforcePoolLimit on each select. */\r\n maxOpenEditors: number;\r\n /** Optional default value factory used when seeding a brand-new draft. */\r\n defaultValueFactory?: () => unknown;\r\n}\r\n\r\nconst EditorSessionContext = createContext<EditorSessionContextValue | null>(null);\r\n\r\nconst useEditorSessionContext = (): EditorSessionContextValue => {\r\n const ctx = useContext(EditorSessionContext);\r\n if (!ctx) {\r\n throw new Error(\r\n '[smartlinks-ui] useEditorSession / useEditorSelection / useDirtyOverview must '\r\n + 'be used inside <EditorSessionProvider> (RecordsAdminShell mounts one for you).',\r\n );\r\n }\r\n return ctx;\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Provider\r\n// ---------------------------------------------------------------------------\r\nexport interface EditorSessionProviderProps {\r\n ctx: RecordsCtx;\r\n children: ReactNode;\r\n /** LRU cap on the mount pool. Default 8. Dirty editors are never evicted. */\r\n maxOpenEditors?: number;\r\n /** Factory for seeding brand-new drafts before the resolver responds. */\r\n defaultValueFactory?: () => unknown;\r\n}\r\n\r\nexport const EditorSessionProvider = ({\r\n ctx, children, maxOpenEditors = 8, defaultValueFactory,\r\n}: EditorSessionProviderProps) => {\r\n const storeRef = useRef<EditorStore | null>(null);\r\n if (!storeRef.current) storeRef.current = createEditorStore();\r\n const currentRef = useRef<EditorId | undefined>(undefined);\r\n // Use a tiny external store for currentEditorId so consumers re-render\r\n // when the active editor changes without reaching into React state.\r\n const listenersRef = useRef<Set<() => void>>(new Set());\r\n const subscribeCurrent = useCallback((cb: () => void) => {\r\n listenersRef.current.add(cb);\r\n return () => { listenersRef.current.delete(cb); };\r\n }, []);\r\n const getCurrent = useCallback(() => currentRef.current, []);\r\n const setCurrentEditorId = useCallback((id: EditorId | undefined) => {\r\n if (currentRef.current === id) return;\r\n currentRef.current = id;\r\n listenersRef.current.forEach((l) => l());\r\n }, []);\r\n const currentEditorId = useSyncExternalStore(subscribeCurrent, getCurrent, getCurrent);\r\n\r\n const value = useMemo<EditorSessionContextValue>(() => ({\r\n store: storeRef.current as EditorStore,\r\n ctx,\r\n currentEditorId,\r\n setCurrentEditorId,\r\n maxOpenEditors,\r\n defaultValueFactory,\r\n }), [ctx, currentEditorId, setCurrentEditorId, maxOpenEditors, defaultValueFactory]);\r\n\r\n return (\r\n <EditorSessionContext.Provider value={value}>\r\n {children}\r\n </EditorSessionContext.Provider>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Subscription helpers — keep snapshot identity stable across renders so\r\n// useSyncExternalStore doesn't loop.\r\n// ---------------------------------------------------------------------------\r\nconst useEntry = (editorId: EditorId | undefined): EditorEntry | undefined => {\r\n const { store } = useEditorSessionContext();\r\n const subscribe = useCallback((cb: () => void) => store.subscribe(cb), [store]);\r\n const getSnapshot = useCallback(\r\n () => (editorId ? store.get(editorId) : undefined),\r\n [store, editorId],\r\n );\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n};\r\n\r\nconst useStoreList = (): EditorEntry[] => {\r\n const { store } = useEditorSessionContext();\r\n const subscribe = useCallback((cb: () => void) => store.subscribe(cb), [store]);\r\n const getSnapshot = useCallback(() => store.list(), [store]);\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// useEditorSession — the public hook for custom editor renderers\r\n// ---------------------------------------------------------------------------\r\nexport function useEditorSession<T = unknown>(\r\n editorId: EditorId | undefined,\r\n): EditorSession<T> | null {\r\n const { store, currentEditorId, ctx } = useEditorSessionContext();\r\n const queryClient = useQueryClient();\r\n const entry = useEntry(editorId);\r\n\r\n const onChange = useCallback((next: T | ((prev: T) => T)) => {\r\n if (!editorId) return;\r\n store.setValue(editorId, next as unknown);\r\n }, [store, editorId]);\r\n\r\n const onFacetRuleChange = useCallback((next: FacetRule | null) => {\r\n if (!editorId) return;\r\n store.setFacetRule(editorId, next);\r\n }, [store, editorId]);\r\n\r\n const save = useCallback(async () => {\r\n if (!editorId) return;\r\n try {\r\n await store.save(editorId);\r\n // Invalidate the resolver cache for this target so any sibling\r\n // consumers (RecordList rows, previews) see the fresh server value.\r\n const e = store.get(editorId);\r\n if (e) {\r\n const key = resolvedRecordQueryKey({\r\n collectionId: ctx.collectionId,\r\n appId: ctx.appId,\r\n recordType: ctx.recordType,\r\n productId: e.spec.scope.productId,\r\n variantId: e.spec.scope.variantId,\r\n batchId: e.spec.scope.batchId,\r\n facetId: e.spec.scope.facetId,\r\n facetValue: e.spec.scope.facetValue,\r\n proofId: e.spec.scope.proofId,\r\n recordId: e.recordId,\r\n withParent: true,\r\n });\r\n queryClient.invalidateQueries({ queryKey: key });\r\n }\r\n } catch {\r\n // store.save already rolled status to 'error'; rethrow not needed\r\n // because the consumer reads `error` from the session object.\r\n }\r\n }, [store, editorId, ctx, queryClient]);\r\n\r\n const reset = useCallback(() => {\r\n if (!editorId) return;\r\n store.reset(editorId);\r\n }, [store, editorId]);\r\n\r\n const remove = useCallback(async () => {\r\n if (!editorId) return;\r\n await store.remove(editorId);\r\n }, [store, editorId]);\r\n\r\n if (!editorId || !entry) return null;\r\n\r\n const isRuleScope = entry.spec.scope.kind === 'rule';\r\n const ruleValid = !isRuleScope || isFacetRuleValid(entry.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 editorId,\r\n value: entry.value as T,\r\n onChange,\r\n source: entry.source,\r\n recordId: entry.recordId,\r\n parentValue: entry.parentValue as T | null,\r\n scope: entry.spec.scope,\r\n isDirty: entry.status === 'dirty' || entry.status === 'saving' || entry.status === 'error',\r\n status: entry.status,\r\n error: entry.error ?? null,\r\n save, reset, remove,\r\n canRemove: entry.source === 'self' && !!entry.recordId,\r\n canSave,\r\n cannotSaveReason,\r\n facetRule: entry.facetRule,\r\n onFacetRuleChange,\r\n isActive: editorId === currentEditorId,\r\n };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// useEditorSelection — explicit identity-first selection API\r\n// ---------------------------------------------------------------------------\r\nexport interface SelectTargetInput {\r\n spec: EditorTargetSpec;\r\n /**\r\n * Initial seed when minting a brand-new entry. Pass the resolver's\r\n * current snapshot when one is available; otherwise omit and the entry\r\n * will hydrate via hydrateFromResolver once data arrives.\r\n */\r\n seed?: {\r\n value: unknown;\r\n facetRule: FacetRule | null;\r\n source: ResolvedRecord<unknown>['source'];\r\n parentValue: unknown;\r\n recordId?: string;\r\n };\r\n /** Optional default to seed against if `seed` is omitted. */\r\n defaultValue?: unknown;\r\n /** Optional explicit label for the tray/pill. */\r\n label?: string;\r\n}\r\n\r\nexport interface EditorSelectionApi {\r\n /** Currently active editor id, or undefined when nothing is open. */\r\n currentEditorId: EditorId | undefined;\r\n /** All open editor entries in insertion order (read-only snapshot). */\r\n openEditors: EditorEntry[];\r\n /**\r\n * Select a target. Focuses an existing alive entry if one matches, or\r\n * mints a new one. Returns the chosen editorId.\r\n */\r\n selectTarget: (input: SelectTargetInput) => EditorId;\r\n /** Promote an existing editorId to active without changing its spec. */\r\n focus: (editorId: EditorId) => void;\r\n /** Clear the active editor (e.g. when the host navigates away). */\r\n blur: () => void;\r\n /** Close one editor (no-op if pinned dirty). */\r\n close: (editorId: EditorId) => boolean;\r\n /** Hydrate an entry from a fresh resolver result. */\r\n hydrate: (editorId: EditorId, resolved: ResolvedRecord<unknown>) => void;\r\n}\r\n\r\nexport const useEditorSelection = (): EditorSelectionApi => {\r\n const { store, ctx, currentEditorId, setCurrentEditorId, maxOpenEditors, defaultValueFactory } =\r\n useEditorSessionContext();\r\n const openEditors = useStoreList();\r\n\r\n const selectTarget = useCallback((input: SelectTargetInput): EditorId => {\r\n const existing = store.findExistingEditorIdFor(input.spec);\r\n if (existing) {\r\n store.markActive(existing);\r\n setCurrentEditorId(existing);\r\n store.enforcePoolLimit(maxOpenEditors, existing);\r\n return existing;\r\n }\r\n const editorId = store.open({\r\n spec: input.spec,\r\n saveSpec: buildSaveSpec(ctx, input.spec),\r\n seed: input.seed ?? null,\r\n defaultValue: input.defaultValue ?? defaultValueFactory?.() ?? {},\r\n label: input.label,\r\n });\r\n setCurrentEditorId(editorId);\r\n store.enforcePoolLimit(maxOpenEditors, editorId);\r\n return editorId;\r\n }, [store, ctx, setCurrentEditorId, maxOpenEditors, defaultValueFactory]);\r\n\r\n const focus = useCallback((editorId: EditorId) => {\r\n store.markActive(editorId);\r\n setCurrentEditorId(editorId);\r\n }, [store, setCurrentEditorId]);\r\n\r\n const blur = useCallback(() => setCurrentEditorId(undefined), [setCurrentEditorId]);\r\n\r\n const close = useCallback((editorId: EditorId) => {\r\n const closed = store.close(editorId);\r\n if (closed && currentEditorId === editorId) setCurrentEditorId(undefined);\r\n return closed;\r\n }, [store, currentEditorId, setCurrentEditorId]);\r\n\r\n const hydrate = useCallback((editorId: EditorId, resolved: ResolvedRecord<unknown>) => {\r\n store.hydrateFromResolver(editorId, resolved);\r\n }, [store]);\r\n\r\n return { currentEditorId, openEditors, selectTarget, focus, blur, close, hydrate };\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// useDirtyOverview — header pill / tray / save-all\r\n// ---------------------------------------------------------------------------\r\nconst overviewItemFromEntry = (e: EditorEntry): DirtyOverviewItem => ({\r\n editorId: e.editorId,\r\n label: e.label,\r\n status: e.status,\r\n error: e.error,\r\n scope: e.spec.scope,\r\n recordId: e.recordId,\r\n});\r\n\r\nexport const useDirtyOverview = (): DirtyOverview => {\r\n const { store } = useEditorSessionContext();\r\n const list = useStoreList();\r\n const items = useMemo(\r\n () => list\r\n .filter((e) => e.status === 'dirty' || e.status === 'saving' || e.status === 'error')\r\n .map(overviewItemFromEntry),\r\n [list],\r\n );\r\n const count = items.length;\r\n const errorCount = useMemo(() => items.filter((i) => i.status === 'error').length, [items]);\r\n\r\n const saveAll = useCallback(async () => {\r\n // Sequential: avoids hammering the server and surfaces errors one-by-one\r\n // for the per-record progress UI.\r\n const ids = list\r\n .filter((e) => e.status === 'dirty' || e.status === 'error')\r\n .map((e) => e.editorId);\r\n for (const id of ids) {\r\n try { await store.save(id); }\r\n catch { /* status already moved to 'error' */ }\r\n }\r\n }, [store, list]);\r\n\r\n const discardAll = useCallback(() => {\r\n const ids = list\r\n .filter((e) => e.status === 'dirty' || e.status === 'error')\r\n .map((e) => e.editorId);\r\n ids.forEach((id) => store.reset(id));\r\n }, [store, list]);\r\n\r\n const saveOne = useCallback(async (editorId: EditorId) => {\r\n await store.save(editorId);\r\n }, [store]);\r\n\r\n return { items, count, errorCount, saveAll, discardAll, saveOne };\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Convenience: parsed-ref → scope shape that the resolver expects.\r\n// (Not strictly part of the session surface but kept here so consumers can\r\n// build a target spec without importing data/* directly.)\r\n// ---------------------------------------------------------------------------\r\nexport const parsedRefToTargetSpec = (\r\n scope: ParsedRef,\r\n opts: Partial<Omit<EditorTargetSpec, 'scope'>> = {},\r\n): EditorTargetSpec => ({ scope, ...opts });\r\n","// =============================================================================\r\n// editor-session/useEditorBridge.ts\r\n//\r\n// Internal-only bridge used by RecordsAdminShell during the 2a migration.\r\n// Wraps the new EditorStore behind an EditorContext-shaped return so the\r\n// shell's existing renderEditor / RecordEditor / RecordTargeting consumers\r\n// don't need to change in this pass.\r\n//\r\n// Phase 2b will hoist per-editor rendering into an EditorHost that calls\r\n// useEditorSession directly; at that point this bridge can be deleted.\r\n//\r\n// NOT exported from the package — purely an implementation detail.\r\n// =============================================================================\r\nimport { useEffect, useMemo, useRef } from 'react';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport type {\r\n EditorContext, ParsedRef, ResolvedRecord,\r\n} from '../types';\r\nimport { useEditorSelection, useEditorSession } from './EditorSessionProvider';\r\nimport type { EditorTargetSpec } from './types';\r\n\r\nexport interface UseEditorBridgeArgs<T> {\r\n /** Current target. When undefined, no editor is selected and the bridge\r\n * returns a sentinel ctx with `isDirty=false` and noop handlers. */\r\n target: EditorTargetSpec | null;\r\n /** Resolver result for `target`. Fed into the store via hydrate(). */\r\n resolved: ResolvedRecord<T> & { facetRule?: FacetRule | null };\r\n /** Default value factory for brand-new drafts (resolver source==='empty'). */\r\n defaultData?: () => T;\r\n /** Called after a successful save (refetch lists, run telemetry, etc.). */\r\n onSaved?: () => void;\r\n /** Called after a successful delete. */\r\n onDeleted?: () => void;\r\n}\r\n\r\nconst isEqualSpec = (a: EditorTargetSpec | null, b: EditorTargetSpec | null): boolean => {\r\n if (a === b) return true;\r\n if (!a || !b) return false;\r\n if (a.scope.raw !== b.scope.raw) return false;\r\n if ((a.recordId ?? null) !== (b.recordId ?? null)) return false;\r\n if (!!a.createMode !== !!b.createMode) return false;\r\n if ((a.draftKey ?? null) !== (b.draftKey ?? null)) return false;\r\n return true;\r\n};\r\n\r\n/**\r\n * Returns an EditorContext-shaped value backed by the new EditorStore.\r\n * The bridge is responsible for:\r\n * 1. Calling selection.selectTarget when `target` changes (mints/focuses\r\n * the editor for that target).\r\n * 2. Pushing resolver results into the store via hydrate().\r\n * 3. Wrapping the resulting EditorSession in the legacy EditorContext API.\r\n */\r\nexport function useEditorBridge<T>(args: UseEditorBridgeArgs<T>): EditorContext<T> {\r\n const { target, resolved, defaultData, onSaved, onDeleted } = args;\r\n const selection = useEditorSelection();\r\n\r\n // Track the most recently selected target so we only call selectTarget\r\n // when it actually changes — selectTarget itself is idempotent for\r\n // matching specs, but skipping the call avoids redundant store churn.\r\n const lastTargetRef = useRef<EditorTargetSpec | null>(null);\r\n const editorIdRef = useRef<string | undefined>(undefined);\r\n\r\n useEffect(() => {\r\n if (!target) {\r\n selection.blur();\r\n lastTargetRef.current = null;\r\n editorIdRef.current = undefined;\r\n return;\r\n }\r\n if (isEqualSpec(target, lastTargetRef.current)) return;\r\n lastTargetRef.current = target;\r\n const id = selection.selectTarget({\r\n spec: target,\r\n seed: resolved.source === 'empty' ? undefined : {\r\n value: resolved.data ?? (defaultData?.() ?? null),\r\n facetRule: resolved.facetRule ?? null,\r\n source: resolved.source,\r\n parentValue: resolved.parentValue ?? null,\r\n recordId: resolved.recordId,\r\n },\r\n defaultValue: defaultData?.() ?? {},\r\n });\r\n editorIdRef.current = id;\r\n // Intentionally only react to target identity changes, not resolver\r\n // updates — resolver changes are pushed via the hydrate effect below.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [target?.scope.raw, target?.recordId, target?.createMode, target?.draftKey]);\r\n\r\n // Hydrate the active editor whenever the resolver settles. The store's\r\n // hydrateFromResolver guards against clobbering dirty values.\r\n useEffect(() => {\r\n const id = editorIdRef.current;\r\n if (!id) return;\r\n if (resolved.source === 'empty' && !resolved.recordId) return;\r\n selection.hydrate(id, resolved as ResolvedRecord<unknown>);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [resolved.source, resolved.recordId, resolved.sourceRef, resolved.data, resolved.facetRule]);\r\n\r\n const editorId = selection.currentEditorId ?? editorIdRef.current;\r\n const session = useEditorSession<T>(editorId);\r\n\r\n // Side-effect callbacks. We watch `status` transitions to fire onSaved /\r\n // onDeleted exactly once per event. These mirror the legacy hook's\r\n // onSaved/onDeleted semantics.\r\n const prevStatusRef = useRef<string | null>(null);\r\n useEffect(() => {\r\n const prev = prevStatusRef.current;\r\n const next = session?.status ?? null;\r\n prevStatusRef.current = next;\r\n if (next === 'saved' && prev !== 'saved') {\r\n onSaved?.();\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [session?.status]);\r\n\r\n // Wrap remove() so onDeleted fires on success.\r\n const remove = useMemo(() => async () => {\r\n if (!session) return;\r\n await session.remove();\r\n onDeleted?.();\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [session?.remove]);\r\n\r\n // Sentinel context when nothing is selected — keeps the shell render path\r\n // happy. `isDirty=false` ensures unsaved guards don't fire spuriously.\r\n if (!session) {\r\n const sentinelScope: ParsedRef = target?.scope ?? { kind: 'collection', raw: '' };\r\n return {\r\n value: (defaultData?.() ?? ({} as T)),\r\n onChange: () => {},\r\n source: 'empty',\r\n recordId: undefined,\r\n parentValue: null,\r\n scope: sentinelScope,\r\n isDirty: false,\r\n save: async () => {},\r\n reset: () => {},\r\n remove: async () => {},\r\n canRemove: false,\r\n canSave: false,\r\n cannotSaveReason: undefined,\r\n isSaving: false,\r\n saveError: null,\r\n facetRule: null,\r\n onFacetRuleChange: () => {},\r\n };\r\n }\r\n\r\n return {\r\n value: session.value,\r\n onChange: session.onChange as EditorContext<T>['onChange'],\r\n source: session.source,\r\n recordId: session.recordId,\r\n parentValue: session.parentValue,\r\n scope: session.scope,\r\n isDirty: session.isDirty,\r\n save: session.save,\r\n reset: session.reset,\r\n remove,\r\n canRemove: session.canRemove,\r\n canSave: session.canSave,\r\n cannotSaveReason: session.cannotSaveReason,\r\n isSaving: session.status === 'saving',\r\n saveError: session.error,\r\n facetRule: session.facetRule,\r\n onFacetRuleChange: session.onFacetRuleChange,\r\n };\r\n}\r\n","// =============================================================================\r\n// shell/state/useShellEditorTarget.ts\r\n//\r\n// Builds the EditorTargetSpec describing what the editor should mount\r\n// against right now, then runs it through `useEditorBridge` to get back\r\n// an EditorContext-shaped object the rest of the shell already consumes.\r\n//\r\n// All the draft-key / createMode / isDraftScope subtleties live here so\r\n// the orchestrator never has to think about why a `rule:__draft__` ref\r\n// has to be hidden from the SDK.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport type { ParsedRef, ScopeKind } from '../../types';\r\nimport type { EditorTargetSpec } from '../../editor-session/types';\r\nimport { useEditorBridge, type UseEditorBridgeArgs } from '../../editor-session/useEditorBridge';\r\nimport type { FacetRule } from '../../data/sdkTypes';\r\n\r\nconst DRAFT_PREFIX = 'draft:';\r\nconst DRAFT_ID = '__draft__';\r\nconst isDraftId = (id: string | null | undefined): boolean =>\r\n !!id && (id === DRAFT_ID || id.startsWith(DRAFT_PREFIX));\r\n\r\nexport interface UseShellEditorTargetArgs<TData> {\r\n editingTargetScope: ParsedRef | null;\r\n isCollection: boolean;\r\n selectedItemId: string | null;\r\n activeScope: ScopeKind;\r\n draftKind: 'rule' | 'global' | 'item' | null;\r\n ruleWizardStep: 1 | 2 | null;\r\n ruleWizardRule: FacetRule | null;\r\n resolved: UseEditorBridgeArgs<TData>['resolved'] & { facetRule: FacetRule | null | undefined };\r\n defaultData?: () => TData;\r\n deriveDraftLabel?: (data: TData, scope: ParsedRef) => string | undefined;\r\n onSaved: (isCreate: boolean) => void;\r\n onDeleted: () => void;\r\n}\r\n\r\nexport interface ShellEditorTarget<TData> {\r\n editorTargetSpec: EditorTargetSpec | null;\r\n editorCtx: ReturnType<typeof useEditorBridge<TData>>;\r\n}\r\n\r\nexport function useShellEditorTarget<TData>(\r\n args: UseShellEditorTargetArgs<TData>,\r\n): ShellEditorTarget<TData> {\r\n const {\r\n editingTargetScope, isCollection, selectedItemId, activeScope, draftKind,\r\n ruleWizardStep, ruleWizardRule, resolved, defaultData, deriveDraftLabel,\r\n onSaved, onDeleted,\r\n } = args;\r\n\r\n const editorTargetSpec: EditorTargetSpec | null = useMemo(() => {\r\n if (!editingTargetScope) return null;\r\n const initialFacetRule = editingTargetScope.kind === 'rule'\r\n ? (ruleWizardStep === 2 && ruleWizardRule\r\n ? ruleWizardRule\r\n : (resolved.facetRule ?? { all: [] }))\r\n : (ruleWizardStep === 2 && ruleWizardRule && isCollection && !!selectedItemId\r\n ? ruleWizardRule\r\n : null);\r\n const label = deriveDraftLabel\r\n ? deriveDraftLabel(resolved.data as TData, editingTargetScope)\r\n : undefined;\r\n // Draft scopes are anything the shell synthesised purely for routing —\r\n // the new-rule wizard's `rule:__draft__` sentinel and the per-item\r\n // `item:draft:*` suffix. Both must be invisible to the SDK; the save\r\n // path drops them and the editor pool keys on `draftKey` instead of\r\n // `scope.raw`.\r\n const rawScope = editingTargetScope.raw ?? '';\r\n const isDraftScope = rawScope.includes('__draft__') || rawScope.includes('item:draft:');\r\n const draftKey = isDraftScope\r\n ? (isCollection && selectedItemId && isDraftId(selectedItemId)\r\n ? `item:${selectedItemId}`\r\n : `${activeScope}:${draftKind ?? 'wizard'}`)\r\n : undefined;\r\n const itemDraftCreate = isCollection && !!selectedItemId && isDraftId(selectedItemId);\r\n const createMode = itemDraftCreate || (isCollection && !!selectedItemId && !resolved.recordId);\r\n return {\r\n scope: editingTargetScope,\r\n // Item drafts must NOT inherit the parent rule's resolved recordId —\r\n // otherwise the store's findExistingEditorIdFor would match the rule's\r\n // editor, focus it instead of minting a new draft, and the next save\r\n // would update the rule record in place.\r\n recordId: createMode ? undefined : resolved.recordId,\r\n createMode,\r\n ref: editingTargetScope.kind === 'rule' && !isDraftScope\r\n ? editingTargetScope.raw\r\n : undefined,\r\n initialFacetRule,\r\n label,\r\n draftKey,\r\n isDraftScope,\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n editingTargetScope?.raw, editingTargetScope?.kind,\r\n resolved.recordId, resolved.facetRule,\r\n isCollection, selectedItemId, activeScope, draftKind,\r\n ruleWizardStep, ruleWizardRule,\r\n ]);\r\n\r\n const editorCtx = useEditorBridge<TData>({\r\n target: editorTargetSpec,\r\n resolved: {\r\n data: resolved.data,\r\n source: resolved.source,\r\n sourceRef: resolved.sourceRef,\r\n recordId: resolved.recordId,\r\n parentValue: resolved.parentValue,\r\n facetRule: resolved.facetRule,\r\n },\r\n defaultData,\r\n onSaved: () => onSaved(resolved.source !== 'self'),\r\n onDeleted,\r\n });\r\n\r\n return { editorTargetSpec, editorCtx };\r\n}\r\n","// =============================================================================\r\n// shell/state/useShellSelection.ts\r\n//\r\n// All shell selection state in one place — active rail tab, the records-tab\r\n// selection (`selectedRecordId` + `draftKind`), the new-rule wizard\r\n// (`ruleWizardStep` + `ruleWizardRule`), the product drill-down\r\n// (`selectedProductId` / `drillTab` / variant / batch) and the per-item\r\n// id (`selectedItemId`).\r\n//\r\n// Plus the cross-cutting effects that keep these in sync:\r\n// - re-sync product/variant/batch from `contextScope` URL changes\r\n// - auto-select first product / first record when nothing's chosen\r\n// - clear records-tab selection when the rail tab changes\r\n// - reset `selectedItemId` when the editing folder changes (with a\r\n// deep-link skip flag exposed via `skipNextItemResetRef`)\r\n// =============================================================================\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport type { ScopeKind } from '../../types';\r\nimport type { DrillTab } from '../../editor/ProductDrillDown';\r\nimport type { FacetRule } from '../../data/sdkTypes';\r\n\r\nexport type DraftKind = 'rule' | 'global' | 'item' | null;\r\nexport type RuleWizardStep = 1 | 2 | null;\r\n\r\nexport interface UseShellSelectionArgs {\r\n initialScope: ScopeKind;\r\n contextScope: { productId?: string; variantId?: string; batchId?: string } | undefined;\r\n}\r\n\r\nexport interface ShellSelection {\r\n activeScope: ScopeKind;\r\n setActiveScope: React.Dispatch<React.SetStateAction<ScopeKind>>;\r\n selectedRecordId: string | null;\r\n setSelectedRecordId: React.Dispatch<React.SetStateAction<string | null>>;\r\n draftKind: DraftKind;\r\n setDraftKind: React.Dispatch<React.SetStateAction<DraftKind>>;\r\n ruleWizardStep: RuleWizardStep;\r\n setRuleWizardStep: React.Dispatch<React.SetStateAction<RuleWizardStep>>;\r\n ruleWizardRule: FacetRule | null;\r\n setRuleWizardRule: React.Dispatch<React.SetStateAction<FacetRule | null>>;\r\n selectedProductId: string | undefined;\r\n setSelectedProductId: React.Dispatch<React.SetStateAction<string | undefined>>;\r\n drillTab: DrillTab;\r\n setDrillTab: React.Dispatch<React.SetStateAction<DrillTab>>;\r\n selectedVariantId: string | undefined;\r\n setSelectedVariantId: React.Dispatch<React.SetStateAction<string | undefined>>;\r\n selectedBatchId: string | undefined;\r\n setSelectedBatchId: React.Dispatch<React.SetStateAction<string | undefined>>;\r\n selectedItemId: string | null;\r\n setSelectedItemId: React.Dispatch<React.SetStateAction<string | null>>;\r\n /** Deep-link restore sets this true to skip the next folder-reset of\r\n * `selectedItemId` (URL pairs scope change + item id intentionally). */\r\n skipNextItemResetRef: React.MutableRefObject<boolean>;\r\n}\r\n\r\nexport const useShellSelection = (args: UseShellSelectionArgs): ShellSelection => {\r\n const { initialScope, contextScope } = args;\r\n\r\n const [activeScope, setActiveScope] = useState<ScopeKind>(initialScope);\r\n useEffect(() => { setActiveScope(initialScope); }, [initialScope]);\r\n\r\n // Records-tab selection — see RecordsAdminShell for sentinel doc.\r\n const [selectedRecordId, setSelectedRecordId] = useState<string | null>(null);\r\n const [draftKind, setDraftKind] = useState<DraftKind>(null);\r\n\r\n // New-rule wizard.\r\n const [ruleWizardStep, setRuleWizardStep] = useState<RuleWizardStep>(null);\r\n const [ruleWizardRule, setRuleWizardRule] = useState<FacetRule | null>(null);\r\n\r\n // Product drill-down.\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 drill-down 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 // Per-item selection (collection cardinality). The \"reset on folder\r\n // change\" effect lives in the shell — it depends on `editingScope` which\r\n // is derived from this very state, so the orchestrator wires that effect\r\n // after `useEditingScope` runs. The skip flag travels with the rest of\r\n // the selection bundle so deep-link restore can reach it.\r\n const [selectedItemId, setSelectedItemId] = useState<string | null>(null);\r\n const skipNextItemResetRef = useRef(false);\r\n\r\n // Clear records-tab selection on rail-tab change so a Rule selection\r\n // isn't reinterpreted as a Global selection.\r\n useEffect(() => {\r\n setSelectedRecordId(null);\r\n setDraftKind(null);\r\n }, [activeScope]);\r\n\r\n return {\r\n activeScope, setActiveScope,\r\n selectedRecordId, setSelectedRecordId,\r\n draftKind, setDraftKind,\r\n ruleWizardStep, setRuleWizardStep,\r\n ruleWizardRule, setRuleWizardRule,\r\n selectedProductId, setSelectedProductId,\r\n drillTab, setDrillTab,\r\n selectedVariantId, setSelectedVariantId,\r\n selectedBatchId, setSelectedBatchId,\r\n selectedItemId, setSelectedItemId,\r\n skipNextItemResetRef,\r\n };\r\n};\r\n","// =============================================================================\r\n// ScopeTabs — pill-style segmented control for the top-level scopes.\r\n// v0.4: scope icon + label + count badge, active accent, hover lift.\r\n// =============================================================================\r\nimport type { ScopeKind } from '../types';\r\nimport { DEFAULT_ICONS, type RecordsAdminIcons } from '../shell/icons';\r\nimport { cn } from '../../../utils/cn';\r\n\r\nconst LABELS: Record<ScopeKind, string> = {\r\n 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 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--sl-control-focus-ring)/0.45)]',\r\n active ? 'font-semibold' : 'hover:bg-[hsl(var(--sl-control-hover-bg)/0.08)]',\r\n )}\r\n style={{\r\n background: active\r\n ? 'hsl(var(--sl-control-active-bg))'\r\n : 'hsl(var(--sl-control-bg))',\r\n borderColor: active\r\n ? 'hsl(var(--sl-control-active-bd))'\r\n : 'hsl(var(--sl-control-border))',\r\n color: active\r\n ? 'hsl(var(--sl-control-active-fg))'\r\n : 'hsl(var(--sl-control-fg))',\r\n }}\r\n >\r\n {o.label}\r\n <span\r\n className=\"ml-1.5\"\r\n style={{ opacity: active ? 0.85 : 0.6 }}\r\n >\r\n {o.count}\r\n </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, hasError, 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 i18n = ctx.i18n ?? DEFAULT_I18N;\r\n const subtitle = record.subtitle ?? (isRuleRecord ? null : ruleSummary) ?? (tone === 'missing'\r\n ? i18n.subtitleEmpty\r\n : tone === 'own' ? i18n.subtitleConfigured : i18n.subtitleInherited);\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 {hasError ? (\r\n <span\r\n title=\"Save failed\"\r\n aria-label=\"Save failed\"\r\n className=\"ra-error-pip\"\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 type { RecordsAdminI18n } from '../types/i18n';\r\nimport { DefaultRecordRow } from './DefaultRecordRow';\r\nimport { DEFAULT_ICONS } from '../shell/icons';\r\n\r\ninterface Props {\r\n items: RecordSummary[];\r\n /**\r\n * UUID of the currently-selected row. Matches `RecordSummary.id`. Records\r\n * without an `id` (synthesised product/facet rows that don't yet have a\r\n * server-side record) can never be the selection target — those tabs key\r\n * highlighting off product/facet anchors via `selectedAnchorKey` instead.\r\n */\r\n selectedId?: string;\r\n /**\r\n * Anchor-based highlight fallback for tabs whose rail rows are not backed\r\n * by AppRecords (Products, Facets). Compared against `RecordSummary.ref`\r\n * which for those tabs is a synthesised display-only anchor string.\r\n */\r\n selectedAnchorKey?: string;\r\n onSelect: (item: RecordSummary) => void;\r\n /** UUID of the row currently being edited with unsaved changes. */\r\n dirtyId?: string;\r\n /** Anchor-key equivalent of `dirtyId` for non-record-backed tabs. */\r\n dirtyAnchorKey?: string;\r\n /**\r\n * Optional set of record IDs (or anchor refs) that have unsaved changes\r\n * registered with the shell-level dirty-draft store. Used by the shell to\r\n * paint dirty/error pips on rows the user has edited but isn't currently\r\n * looking at. `dirtyId`/`dirtyAnchorKey` remain for the active editor.\r\n */\r\n dirtyKeys?: ReadonlySet<string>;\r\n /** Subset of `dirtyKeys` whose last save attempt failed. */\r\n errorKeys?: ReadonlySet<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 /** Resolved i18n strings — used by default row/card renderers. */\r\n i18n?: RecordsAdminI18n;\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, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey,\r\n dirtyKeys, errorKeys,\r\n presentation = 'list', renderListRow, groupBy, rowClipboard, i18n,\r\n}: Props) => {\r\n const buildCtx = (item: RecordSummary): RecordSlotContext => {\r\n const cb = rowClipboard ? rowClipboard(item) : null;\r\n const idMatch = selectedId != null && item.id != null && item.id === selectedId;\r\n const anchorMatch = selectedAnchorKey != null && item.ref === selectedAnchorKey;\r\n const dirtyIdMatch = dirtyId != null && item.id != null && item.id === dirtyId;\r\n const dirtyAnchorMatch = dirtyAnchorKey != null && item.ref === dirtyAnchorKey;\r\n const idInStore = !!(item.id && dirtyKeys?.has(item.id));\r\n const refInStore = !!(item.ref && dirtyKeys?.has(item.ref));\r\n const errorInStore = !!(\r\n (item.id && errorKeys?.has(item.id)) ||\r\n (item.ref && errorKeys?.has(item.ref))\r\n );\r\n return {\r\n selected: idMatch || anchorMatch,\r\n onSelect: () => onSelect(item),\r\n isDirty: dirtyIdMatch || dirtyAnchorMatch || idInStore || refInStore,\r\n hasError: errorInStore,\r\n i18n,\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.id ?? 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// FacetBrowseFilter — replaces the legacy \"Shared\" top-level tab (v0.5).\r\n//\r\n// A small chip row that lets admins ask \"show me what would apply if a\r\n// product had facet X = Y\" while staying on the Rules or Global tab. The\r\n// active selection narrows the rail in two ways:\r\n//\r\n// * Rules tab — keep only rules whose `facetRule` would match a product\r\n// carrying the picked facet/value (clause `facetKey` =\r\n// selected key AND `anyOf` includes the selected value).\r\n// * Global tab — singleton mode only: keep records whose pinned scope\r\n// matches the picked facet/value. Collection-mode Global\r\n// is item-list-driven so this control is hidden there.\r\n//\r\n// The chip vocabulary is sourced from `useFacetBrowse` (the same hook the\r\n// old Shared tab used) so admins see every facet value the collection knows\r\n// about, not just ones with existing records. Picking a value emits a\r\n// `{ facetKey, facetValue }` selection; picking it again clears.\r\n//\r\n// Visual: identical to RuleFilterChips so the rail stays calm — one row of\r\n// facet keys, an indented row of values for the open key. Pure presentation;\r\n// the parent shell owns the selection state.\r\n// =============================================================================\r\nimport { useMemo, useState } from 'react';\r\n\r\n/** Collapsed-state cap on the number of facet-key chips rendered before\r\n * the \"Show all (N)\" expand link kicks in. Tuned to fit a typical rail\r\n * width (~280px) without wrapping more than two rows. */\r\nconst COLLAPSED_FACET_CAP = 6;\r\n\r\n/** Single facet vocabulary entry — typically one chip group per facet. */\r\nexport interface FacetBrowseFacet {\r\n key: string;\r\n /** Friendly facet name (e.g. \"Bread Type\"). Falls back to `key`. */\r\n label?: string;\r\n values: { key: string; label?: string }[];\r\n}\r\n\r\nexport interface FacetBrowseSelection {\r\n facetKey: string;\r\n facetValue: string;\r\n}\r\n\r\nexport interface FacetBrowseFilterProps {\r\n /** Full facet vocabulary for the collection. */\r\n facets: FacetBrowseFacet[];\r\n /** Currently-picked facet/value, or null when no filter is applied. */\r\n value: FacetBrowseSelection | null;\r\n onChange: (next: FacetBrowseSelection | null) => void;\r\n /** Optional placeholder shown when the vocabulary is still loading. */\r\n isLoading?: boolean;\r\n /** Override the inline help string. */\r\n helpText?: string;\r\n}\r\n\r\nexport function FacetBrowseFilter({\r\n facets, value, onChange, isLoading = false,\r\n helpText = 'Browse by facet — preview what would apply to a product.',\r\n}: FacetBrowseFilterProps) {\r\n // Which facet group is currently expanded for value selection. Defaults to\r\n // the active selection's facet, then the first non-empty facet. Local state\r\n // so admins can browse without committing to a value.\r\n const firstUsable = useMemo(\r\n () => facets.find((f) => f.values?.length)?.key,\r\n [facets],\r\n );\r\n const [openKey, setOpenKey] = useState<string | null>(value?.facetKey ?? firstUsable ?? null);\r\n /** Collapse the facet-keys row to ~6 entries by default — long\r\n * vocabularies otherwise dominate the rail. The currently-selected\r\n * facet (if any) is always kept visible so the active filter chip\r\n * never disappears behind the \"Show all\" link. */\r\n const [allExpanded, setAllExpanded] = useState(false);\r\n\r\n // Sync open group to the selection when it changes externally.\r\n const effectiveOpen = value?.facetKey ?? openKey ?? firstUsable ?? null;\r\n\r\n if (isLoading) {\r\n return (\r\n <div className=\"ra-rule-filters\" aria-busy=\"true\">\r\n <div className=\"ra-rule-filters-row\">\r\n <span className=\"ra-rule-filter-chip\" data-active=\"false\">Loading facets…</span>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!facets.length) return null;\r\n\r\n const openFacet = facets.find((f) => f.key === effectiveOpen) ?? null;\r\n\r\n // Decide which facet-key chips to render. When collapsed we cap the\r\n // visible set but always keep the active selection in view.\r\n const overflow = facets.length - COLLAPSED_FACET_CAP;\r\n let visibleFacets = facets;\r\n if (!allExpanded && overflow > 0) {\r\n const head = facets.slice(0, COLLAPSED_FACET_CAP);\r\n const activeFacet = value\r\n ? facets.find((f) => f.key === value.facetKey)\r\n : null;\r\n visibleFacets = activeFacet && !head.includes(activeFacet)\r\n ? [...head.slice(0, COLLAPSED_FACET_CAP - 1), activeFacet]\r\n : head;\r\n }\r\n\r\n return (\r\n <div className=\"ra-rule-filters\" role=\"group\" aria-label=\"Browse by facet\">\r\n <div className=\"ra-rule-filters-row\">\r\n {visibleFacets.map((f) => {\r\n const active = effectiveOpen === f.key;\r\n const isFiltered = value?.facetKey === f.key;\r\n return (\r\n <button\r\n key={f.key}\r\n type=\"button\"\r\n className=\"ra-rule-filter-chip\"\r\n data-active={isFiltered ? 'true' : 'false'}\r\n aria-pressed={active}\r\n onClick={() => {\r\n if (isFiltered) {\r\n // Clicking the active filter group clears the selection.\r\n onChange(null);\r\n return;\r\n }\r\n setOpenKey(f.key);\r\n }}\r\n title={`Browse ${f.label ?? f.key} values`}\r\n >\r\n <span className=\"ra-rule-filter-chip-label\">{f.label ?? f.key}</span>\r\n <span className=\"ra-rule-filter-chip-count\">{f.values.length}</span>\r\n </button>\r\n );\r\n })}\r\n {overflow > 0 && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setAllExpanded((v) => !v)}\r\n className=\"ra-rule-filter-chip\"\r\n data-active=\"false\"\r\n aria-expanded={allExpanded}\r\n title={allExpanded ? 'Show fewer facets' : `Show all ${facets.length} facets`}\r\n >\r\n <span className=\"ra-rule-filter-chip-label\">\r\n {allExpanded ? 'Show fewer' : `Show all (${facets.length})`}\r\n </span>\r\n </button>\r\n )}\r\n </div>\r\n {openFacet && openFacet.values.length > 0 && (\r\n <div\r\n className=\"ra-rule-filters-row\"\r\n role=\"group\"\r\n aria-label={`Pick a ${openFacet.label ?? openFacet.key} value`}\r\n style={{ paddingLeft: '0.25rem' }}\r\n >\r\n {openFacet.values.map((v) => {\r\n const active = value?.facetKey === openFacet.key && value?.facetValue === v.key;\r\n return (\r\n <button\r\n key={v.key}\r\n type=\"button\"\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 onClick={() => onChange(active ? null : { facetKey: openFacet.key, facetValue: v.key })}\r\n title={`Filter to ${openFacet.label ?? openFacet.key} = ${v.label ?? v.key}`}\r\n >\r\n <span className=\"ra-rule-filter-chip-label\">{v.label ?? v.key}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n )}\r\n {value && (\r\n <button\r\n type=\"button\"\r\n onClick={() => onChange(null)}\r\n className=\"ra-rule-filter-clear\"\r\n aria-label=\"Clear facet filter\"\r\n >\r\n Clear facet filter\r\n </button>\r\n )}\r\n {!value && (\r\n <span className=\"ra-rule-filter-clear\" style={{ cursor: 'default', textDecoration: 'none' }}>\r\n {helpText}\r\n </span>\r\n )}\r\n </div>\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 overflow-hidden border\"\r\n style={{\r\n borderColor: 'hsl(var(--sl-control-border))',\r\n background: 'hsl(var(--sl-control-bg))',\r\n borderRadius: 'var(--sl-control-radius)',\r\n }}\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 'focus-visible:outline-none focus-visible:ring-2',\r\n active\r\n ? 'bg-[hsl(var(--sl-control-active-bg))] text-[hsl(var(--sl-control-active-fg))]'\r\n : 'text-[hsl(var(--sl-control-fg))] hover:bg-[hsl(var(--sl-control-hover-bg)/0.10)] hover:text-[hsl(var(--sl-control-hover-fg))]',\r\n 'focus-visible:ring-[hsl(var(--sl-control-focus-ring)/0.45)]',\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 just\r\n// records whose anchors equal the current scope's anchors and which are not\r\n// rule-targeted. Each record is individually addressable by its UUID id —\r\n// we no longer mint synthetic `.../item:{itemId}` refs to identify them.\r\n//\r\n// Backed by `SL.app.records.list`. We page through results and filter by\r\n// anchor equality client-side; for typical scopes this stays cheap because\r\n// list responses are already scoped by app/recordType. The hook keeps the\r\n// result shape aligned with `RecordSummary` so it slots straight into the\r\n// 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, FacetRule } from '../data/sdkTypes';\r\nimport { parseRef } 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` (we then keep records with no anchors). Pass `null` to keep\r\n * the query disabled.\r\n */\r\n scope: ParsedRef | null;\r\n /**\r\n * When the scope is a rule (kind === 'rule'), pass the rule's `facetRule`\r\n * here. Items belonging to a rule are records that carry the *same*\r\n * facetRule — they share anchors only by coincidence (typically empty),\r\n * so anchor equality alone isn't enough to identify them. When this is\r\n * provided we match rule records by facetRule equality and ignore\r\n * anchors. When absent, anchor-based matching applies (and rule records\r\n * are skipped, since they belong on the Rules tab).\r\n */\r\n facetRule?: FacetRule | 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\n/** Stable JSON for deep-comparing two facetRules. Sorts clauses by facetKey\r\n * and the per-clause `anyOf` values so authoring order doesn't break\r\n * equality. */\r\nconst canonicalFacetRule = (rule: FacetRule | null | undefined): string => {\r\n if (!rule || !Array.isArray(rule.all)) return '';\r\n const clauses = rule.all\r\n .map((c) => ({\r\n facetKey: c.facetKey,\r\n anyOf: [...(c.anyOf ?? [])].sort(),\r\n }))\r\n .sort((a, b) => a.facetKey.localeCompare(b.facetKey));\r\n return JSON.stringify(clauses);\r\n};\r\n\r\nconst defaultToSummary = (rec: AppRecord, base: RecordSummary): RecordSummary => {\r\n const data = rec.data as Record<string, unknown> | null | undefined;\r\n const display = (data?.display as Record<string, unknown> | undefined) ?? 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 (display?.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 (data.slug 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 (display?.description 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 (data.home_image_url as string | undefined) ??\r\n base.thumbnail;\r\n return { ...base, label, subtitle, thumbnail };\r\n};\r\n\r\n/** A record \"belongs to\" a scope when:\r\n * - the scope is a rule (`scope.kind === 'rule'`) and the record's\r\n * `facetRule` matches the supplied rule, **or**\r\n * - the scope is anchor-based and the record's anchors match exactly\r\n * (rule records are skipped because they live on the Rules tab).\r\n */\r\nconst recordMatchesScope = (\r\n rec: AppRecord,\r\n scope: ParsedRef,\r\n ruleSignature: string,\r\n): boolean => {\r\n const facetRule = (rec as { facetRule?: FacetRule | null }).facetRule ?? null;\r\n if (scope.kind === 'rule') {\r\n if (!facetRule) return false;\r\n if (!ruleSignature) return false; // wizard / draft — no items yet\r\n return canonicalFacetRule(facetRule) === ruleSignature;\r\n }\r\n if (facetRule) return false;\r\n return (rec.productId ?? undefined) === scope.productId\r\n && (rec.variantId ?? undefined) === scope.variantId\r\n && (rec.batchId ?? undefined) === scope.batchId\r\n && (rec.proofId ?? undefined) === scope.proofId;\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, facetRule, pageSize = 100, toSummary = defaultToSummary, enabled = true,\r\n } = args;\r\n const queryClient = useQueryClient();\r\n\r\n const scopeRef = scope?.raw ?? '';\r\n const ruleSignature = useMemo(\r\n () => (scope?.kind === 'rule' ? canonicalFacetRule(facetRule) : ''),\r\n [scope?.kind, facetRule],\r\n );\r\n\r\n const queryKey = useMemo(\r\n () => [...QK_BASE, ctx.collectionId, ctx.appId, ctx.recordType, scopeRef, ruleSignature],\r\n [ctx.collectionId, ctx.appId, ctx.recordType, scopeRef, ruleSignature],\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 });\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 if (!scope) return [];\r\n const all = query.data?.pages.flatMap((p) => p.data) ?? [];\r\n const relevant = all.filter((rec) => recordMatchesScope(rec, scope, ruleSignature));\r\n return relevant\r\n .map((rec): RecordSummary<T> | null => {\r\n const ref = rec.ref ?? '';\r\n const parsed = parseRef(ref);\r\n // Item identity is the record's UUID — stable, server-assigned, and\r\n // sufficient for selection/URL purposes. We deliberately no longer\r\n // require a synthetic `item:{slug}` segment in the ref.\r\n const stableItemId = rec.id;\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: stableItemId,\r\n updatedAt: rec.updatedAt,\r\n itemId: stableItemId,\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, scope, ruleSignature]);\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 recordId: params.get(paramNames.recordId),\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 ('recordId' in partial) apply(paramNames.recordId, partial.recordId);\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// PostMessage DeepLinkAdapter — for SmartLinks iframe hosts.\r\n//\r\n// The shell runs inside an iframe owned by the SmartLinks parent platform.\r\n// The platform expects route updates as a `smartlinks-route-change`\r\n// `postMessage` (matching the SDK `IframeResponder` protocol) — it owns the\r\n// browser address bar, history stack, and back/forward buttons. The iframe\r\n// must NOT touch its own `window.history`: doing so just confuses the host.\r\n//\r\n// This adapter therefore:\r\n// - reads the current state from `window.location` (so direct loads of a\r\n// pre-populated URL still hydrate correctly),\r\n// - writes by `postMessage`-ing to `window.parent` — never to history,\r\n// - subscribes to `popstate` / `hashchange` so back/forward initiated by\r\n// the parent (which it relays back into the iframe) still wakes the\r\n// shell.\r\n//\r\n// Param mapping into the SmartLinks message envelope:\r\n// - The shell-owned keys (`recordId`, `scope`, `view`) are sent under\r\n// `state` — they're per-app deep-link state, not platform context.\r\n// - `path` is the current hash route (or pathname for browser routers),\r\n// left untouched. We never invent a path from shell state.\r\n// - `appId` is forwarded if present in the URL so the parent can route\r\n// the message to the right app instance.\r\n// =============================================================================\r\nimport type {\r\n DeepLinkAdapter, DeepLinkState, ResolvedDeepLinkParamNames,\r\n} from '../types/deepLink';\r\n\r\n/** Reserved SmartLinks platform keys — surfaced under `context` in the message. */\r\nconst CONTEXT_KEYS = [\r\n 'dark', 'appId', 'collectionId', 'productId', 'proofId', 'lang', 'theme',\r\n] as const;\r\n\r\nconst findQueryString = (loc: Location): string => {\r\n if (loc.search && loc.search.length > 1) {\r\n return loc.search.startsWith('?') ? loc.search.slice(1) : loc.search;\r\n }\r\n if (loc.hash && loc.hash.includes('?')) {\r\n return loc.hash.slice(loc.hash.indexOf('?') + 1);\r\n }\r\n return '';\r\n};\r\n\r\nconst findPath = (loc: Location): string => {\r\n // Hash routers (`/#/admin?x=y`) — the path the parent cares about lives\r\n // in the hash. Strip the query, keep the leading `/`.\r\n if (loc.hash && loc.hash.startsWith('#')) {\r\n const hash = loc.hash.slice(1);\r\n const qIdx = hash.indexOf('?');\r\n const hashPath = qIdx >= 0 ? hash.slice(0, qIdx) : hash;\r\n if (hashPath) return hashPath;\r\n }\r\n return loc.pathname || '/';\r\n};\r\n\r\n/**\r\n * Detect whether the current window is an iframe with a usable parent.\r\n * Returns false during SSR or when sandboxed in a way that hides `parent`.\r\n */\r\nexport const isInSmartLinksIframe = (): boolean => {\r\n if (typeof window === 'undefined') return false;\r\n try {\r\n return window.parent != null && window.parent !== window;\r\n } catch {\r\n // Cross-origin access errors mean we ARE in an iframe — the throw is\r\n // diagnostic, not disqualifying.\r\n return true;\r\n }\r\n};\r\n\r\n/**\r\n * Build a `postMessage`-driven adapter that mirrors the shell's deep-link\r\n * state into the parent platform. The parent's `IframeResponder` listens\r\n * for `smartlinks-route-change` messages and updates its own URL.\r\n */\r\nexport const createPostMessageDeepLinkAdapter = (\r\n paramNames: ResolvedDeepLinkParamNames,\r\n): DeepLinkAdapter => {\r\n // Track the last shell-owned values we emitted so subsequent writes can\r\n // merge instead of clobbering (the parent may not echo state back).\r\n const lastShellState: DeepLinkState = {};\r\n\r\n const post = (path: string) => {\r\n if (typeof window === 'undefined') return;\r\n const params = new URLSearchParams(findQueryString(window.location));\r\n\r\n const context: Record<string, string> = {};\r\n const state: Record<string, string> = {};\r\n\r\n params.forEach((value, key) => {\r\n if (key === 'theme') return; // Too large for sync (matches host hook).\r\n if ((CONTEXT_KEYS as readonly string[]).includes(key)) context[key] = value;\r\n else state[key] = value;\r\n });\r\n\r\n // Overlay the latest shell-owned values — these are the source of truth\r\n // for record/scope/view, regardless of what's currently in the URL.\r\n const overlay = (key: keyof DeepLinkState, paramKey: string) => {\r\n const v = lastShellState[key];\r\n if (v == null || v === '') delete state[paramKey];\r\n else state[paramKey] = v;\r\n };\r\n overlay('recordId', paramNames.recordId);\r\n overlay('scope', paramNames.scope);\r\n overlay('view', paramNames.view);\r\n\r\n try {\r\n const message = {\r\n type: 'smartlinks-route-change',\r\n path,\r\n context,\r\n state,\r\n appId: context.appId,\r\n };\r\n // eslint-disable-next-line no-console\r\n console.debug('[smartlinks-ui] postMessage → parent', message, {\r\n sameWindow: window.parent === window,\r\n });\r\n window.parent.postMessage(message, '*');\r\n } catch {\r\n // Cross-origin parent that refuses messages — nothing we can do, and\r\n // throwing here would break the shell. Silently drop.\r\n }\r\n };\r\n\r\n return {\r\n read(): DeepLinkState {\r\n if (typeof window === 'undefined') return {};\r\n const params = new URLSearchParams(findQueryString(window.location));\r\n return {\r\n recordId: params.get(paramNames.recordId),\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 is ignored — parent owns history semantics */) {\r\n if (typeof window === 'undefined') return;\r\n if ('recordId' in partial) lastShellState.recordId = partial.recordId ?? null;\r\n if ('scope' in partial) lastShellState.scope = partial.scope ?? null;\r\n if ('view' in partial) lastShellState.view = partial.view ?? null;\r\n post(findPath(window.location));\r\n },\r\n\r\n subscribe(listener) {\r\n if (typeof window === 'undefined') return () => {};\r\n // The parent relays back/forward by updating the iframe URL — so the\r\n // same browser events apply.\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};","// =============================================================================\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\nimport {\r\n createPostMessageDeepLinkAdapter, isInSmartLinksIframe,\r\n} from '../data/postMessageDeepLinkAdapter';\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 | 'record.open' // user opened a different record (push)\r\n | 'record.close' // user backed out to the list (push)\r\n | 'record.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[] = ['record.open', 'record.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 // When the shell is mounted inside a SmartLinks iframe the parent\r\n // platform owns the address bar — speak its protocol via postMessage\r\n // instead of writing to our own `window.history` (which the parent\r\n // ignores and which never surfaces to the user-visible URL).\r\n const inIframe = isInSmartLinksIframe();\r\n // eslint-disable-next-line no-console\r\n console.debug('[smartlinks-ui] deep-link adapter selected', {\r\n adapter: inIframe ? 'postMessage' : 'default',\r\n inIframe,\r\n href: typeof window !== 'undefined' ? window.location.href : '(ssr)',\r\n });\r\n defaultAdapterRef.current = inIframe\r\n ? createPostMessageDeepLinkAdapter(paramNames)\r\n : 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 // We previously surfaced a \"Customised\" / \"Inherited\" badge in a\r\n // dedicated row beneath the title, alongside an \"UNSAVED\" pill. Both\r\n // caused the editor body to push down on first keystroke (and again\r\n // when \"Inherited\" appeared on scope change), and the \"UNSAVED\" signal\r\n // duplicated the shell-level UnsavedTray + the footer Save button.\r\n // We now show only \"Inherited\" — inline in the header's right cluster\r\n // — so the editor never reflows on edit. The shell tray + footer carry\r\n // the unsaved-changes affordance.\r\n const showInherited = ctx.source === 'inherited';\r\n // Surface \"no record yet\" state explicitly. When the resolver returns\r\n // `source === 'empty'` it means nothing has been saved at this scope\r\n // (or anywhere it would inherit from). Without a visible signal, the\r\n // editor looks identical to \"loaded with empty defaults\" and admins\r\n // can't tell whether they're about to create the first record or\r\n // overwriting an existing one.\r\n const showEmpty = ctx.source === 'empty';\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 </div>\r\n <div className=\"flex items-start gap-2 shrink-0\">\r\n {showInherited && (\r\n <span\r\n className=\"inline-flex items-center gap-1 text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded mt-0.5\"\r\n style={{\r\n color: 'hsl(var(--ra-muted-text))',\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=\"This record is inherited from a parent scope\"\r\n >\r\n <StatusDot source={ctx.source} />\r\n Inherited\r\n </span>\r\n )}\r\n {showEmpty && (\r\n <span\r\n className=\"inline-flex items-center gap-1 text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded mt-0.5\"\r\n style={{\r\n color: 'hsl(var(--ra-muted-text))',\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=\"No record exists for this scope yet — save to create one\"\r\n >\r\n <StatusDot source={ctx.source} />\r\n No record yet\r\n </span>\r\n )}\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 cardSize?: 'sm' | 'md' | 'lg';\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, cardSize = 'md', i18n,\r\n}: Props<T>) {\r\n const isGallery = variant === 'gallery';\r\n return (\r\n <div\r\n className={isGallery ? 'ra-item-gallery' : 'ra-item-cards'}\r\n data-card-size={cardSize}\r\n >\r\n {items.map((item) => {\r\n const id = item.itemId ?? '';\r\n const open = () => ctx.onOpen(id);\r\n const slotCtx: ItemSlotContext = {\r\n ...ctx,\r\n selected: selectedId === id,\r\n onSelect: open,\r\n };\r\n if (renderCard) {\r\n return (\r\n <div\r\n key={item.ref}\r\n onClick={open}\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={open}\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 /** Card density for cards/gallery views. */\r\n cardSize?: 'sm' | 'md' | 'lg';\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 cardSize = 'md',\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 cardSize={cardSize}\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 /**\r\n * Set of keys (recordIds + scope refs) currently dirty in the shell-level\r\n * draft store. Used to paint a per-row pip on items the user has edited\r\n * but isn't currently looking at — mirrors the affordance the scope rail\r\n * gets via `RecordList.dirtyKeys`.\r\n */\r\n dirtyKeys?: ReadonlySet<string>;\r\n /** Subset of `dirtyKeys` whose last save attempt failed. */\r\n errorKeys?: ReadonlySet<string>;\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,\r\n dirtyKeys, errorKeys, 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 const isDirty = !!(\r\n (id && dirtyKeys?.has(id)) ||\r\n (item.ref && dirtyKeys?.has(item.ref))\r\n );\r\n const hasError = !!(\r\n (id && errorKeys?.has(id)) ||\r\n (item.ref && errorKeys?.has(item.ref))\r\n );\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 {hasError ? (\r\n <span\r\n className=\"ra-error-pip\"\r\n title=\"Save failed\"\r\n aria-label=\"Save failed\"\r\n />\r\n ) : isDirty ? (\r\n <span\r\n className=\"ra-dirty-pip\"\r\n title=\"Unsaved changes\"\r\n aria-label=\"Unsaved changes\"\r\n />\r\n ) : null}\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","import styleInject from '#style-inject';styleInject(\".sl-aph {\\n width: 100%;\\n font-family: var(--ra-font-ui, ui-sans-serif, system-ui, -apple-system, \\\"Segoe UI\\\", Roboto, sans-serif);\\n color: hsl(var(--ra-text, 222 47% 11%));\\n display: flex;\\n flex-direction: column;\\n gap: 0.5rem;\\n}\\n.sl-aph *,\\n.sl-aph *::before,\\n.sl-aph *::after {\\n box-sizing: border-box;\\n}\\n.sl-aph__row {\\n position: relative;\\n display: flex;\\n align-items: flex-start;\\n gap: 0.6rem;\\n padding: 0.25rem 0.25rem 0.5rem;\\n}\\n.sl-aph__main {\\n flex: 1;\\n min-width: 0;\\n display: flex;\\n align-items: flex-start;\\n gap: 0.55rem;\\n}\\n.sl-aph__aside {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n flex-shrink: 0;\\n}\\n.sl-aph__text {\\n flex: 1;\\n min-width: 0;\\n}\\n.sl-aph__title {\\n font-family: var(--ra-font-display, var(--ra-font-ui, ui-sans-serif, system-ui, sans-serif));\\n font-weight: 700;\\n font-size: 1.2rem;\\n line-height: 1.2;\\n color: hsl(var(--ra-text, 222 47% 11%));\\n letter-spacing: -0.015em;\\n margin: 0;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.5rem;\\n}\\n.sl-aph__icon {\\n flex-shrink: 0;\\n display: inline-flex;\\n align-items: center;\\n justify-content: flex-start;\\n background: transparent;\\n color: hsl(var(--ra-text, 222 47% 11%));\\n border: 0;\\n padding: 0;\\n}\\n.sl-aph__icon > svg {\\n width: 1.05rem;\\n height: 1.05rem;\\n}\\n.sl-aph__subtitle {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-muted-text, 220 9% 46%));\\n margin: 0.1rem 0 0;\\n line-height: 1.3;\\n}\\n.sl-aph__icon-btn {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n width: 2rem;\\n height: 2rem;\\n padding: 0;\\n border-radius: 999px;\\n background: transparent;\\n border: 1px solid transparent;\\n color: hsl(var(--ra-muted-text, 220 9% 46%));\\n cursor: pointer;\\n transition:\\n background .15s ease,\\n color .15s ease,\\n border-color .15s ease;\\n text-decoration: none;\\n}\\n.sl-aph__icon-btn:hover {\\n background: hsl(var(--ra-text, 222 47% 11%) / 0.06);\\n color: hsl(var(--ra-text, 222 47% 11%));\\n}\\n.sl-aph__icon-btn:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px var(--ra-focus-ring, hsl(222 47% 11% / 0.35));\\n}\\n.sl-aph__icon-btn > svg {\\n width: 1rem;\\n height: 1rem;\\n}\\n.sl-aph__intro {\\n position: relative;\\n display: flex;\\n align-items: center;\\n gap: 0.55rem;\\n padding: 0.4rem 2rem 0.4rem 0.5rem;\\n border-radius: var(--ra-radius, 0.625rem);\\n border: 1px solid hsl(var(--ra-info, 214 95% 55%) / 0.30);\\n background: hsl(var(--ra-info, 214 95% 55%) / 0.08);\\n}\\n.sl-aph__intro[data-tone=success] {\\n border-color: hsl(var(--ra-success, 142 71% 45%) / 0.30);\\n background: hsl(var(--ra-success, 142 71% 45%) / 0.08);\\n}\\n.sl-aph__intro[data-tone=warning] {\\n border-color: hsl(var(--ra-warning, 38 92% 50%) / 0.35);\\n background: hsl(var(--ra-warning, 38 92% 50%) / 0.10);\\n}\\n.sl-aph__intro-icon {\\n flex-shrink: 0;\\n width: 1.5rem;\\n height: 1.5rem;\\n border-radius: 999px;\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n background: hsl(var(--ra-info, 214 95% 55%) / 0.18);\\n color: hsl(var(--ra-info, 214 95% 55%));\\n}\\n.sl-aph__intro[data-tone=success] .sl-aph__intro-icon {\\n background: hsl(var(--ra-success, 142 71% 45%) / 0.18);\\n color: hsl(var(--ra-success, 142 71% 45%));\\n}\\n.sl-aph__intro[data-tone=warning] .sl-aph__intro-icon {\\n background: hsl(var(--ra-warning, 38 92% 50%) / 0.20);\\n color: hsl(var(--ra-warning, 38 92% 50%));\\n}\\n.sl-aph__intro-body {\\n flex: 1;\\n min-width: 0;\\n}\\n.sl-aph__intro-title {\\n font-family: var(--ra-font-display, var(--ra-font-ui, ui-sans-serif, system-ui, sans-serif));\\n font-weight: var(--ra-title-weight, 600);\\n font-size: 0.8rem;\\n color: hsl(var(--ra-text, 222 47% 11%));\\n margin: 0;\\n line-height: 1.2;\\n display: inline;\\n}\\n.sl-aph__intro-text {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-text, 222 47% 11%) / 0.85);\\n line-height: 1.35;\\n display: inline;\\n margin-left: 0.4rem;\\n}\\n.sl-aph__intro-action {\\n margin-left: 0.375rem;\\n}\\n.sl-aph__intro-dismiss {\\n position: absolute;\\n top: 50%;\\n right: 0.35rem;\\n transform: translateY(-50%);\\n width: 1.4rem;\\n height: 1.4rem;\\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, 220 9% 46%));\\n cursor: pointer;\\n padding: 0;\\n}\\n.sl-aph__intro-dismiss:hover {\\n background: hsl(var(--ra-text, 222 47% 11%) / 0.06);\\n color: hsl(var(--ra-text, 222 47% 11%));\\n}\\n\")","// =============================================================================\r\n// AdminPageHeader\r\n//\r\n// A standardised page header for any SmartLinks admin surface. Designed to be\r\n// used standalone (lightweight apps that don't need the full RecordsAdminShell)\r\n// or composed inside other shells. Supports:\r\n//\r\n// • Inline icon + title + full-width subtitle\r\n// • Right-aligned slot for app-specific actions (e.g. \"+ New\" button)\r\n// • External help link (icon-button that opens docs in a new tab)\r\n// • Optional dismissible intro card with `?` reopen affordance\r\n// • Optional `aside` slot for extra header content (stats strips, etc.)\r\n//\r\n// Styling is self-contained under `.sl-aph` and reuses the shared `--ra-*`\r\n// design tokens with sensible fallbacks, so it themes correctly whether the\r\n// host has loaded the records-admin token sheet or not.\r\n// =============================================================================\r\nimport { type ReactNode, useId } from 'react';\r\nimport { BookOpen, HelpCircle, X, Lightbulb, CheckCircle2, AlertTriangle, Info } from 'lucide-react';\r\nimport './admin-page-header.css';\r\n\r\nexport type AdminPageHeaderIntroTone = 'info' | 'success' | 'warning';\r\n\r\nexport interface AdminPageHeaderIntro {\r\n /** Short headline shown in bold at the start of the intro card. */\r\n title: string;\r\n /** Body content — plain text or rich nodes. */\r\n body: ReactNode;\r\n /** Visual tone — controls icon and surface tint. Default `'info'`. */\r\n tone?: AdminPageHeaderIntroTone;\r\n /** Optional action node rendered inline after the body (e.g. a Learn-more link). */\r\n action?: ReactNode;\r\n /** Whether the intro is currently dismissed. Controlled. */\r\n dismissed: boolean;\r\n /** Called when the user clicks the dismiss `X`. */\r\n onDismiss: () => void;\r\n /**\r\n * Called when the user clicks the reopen `?` button (only rendered when\r\n * dismissed is true). Omit to hide the reopen affordance entirely.\r\n */\r\n onReopen?: () => void;\r\n /** Tooltip / aria-label for the reopen button. Default \"How it works\". */\r\n reopenLabel?: string;\r\n}\r\n\r\nexport interface AdminPageHeaderProps {\r\n /** Page title — required. */\r\n title: string;\r\n /** Single-line muted subtitle under the title. */\r\n subtitle?: string;\r\n /** Icon rendered inline before the title. Pass a Lucide element or any node. */\r\n icon?: ReactNode;\r\n /**\r\n * External help / documentation URL. When set, renders a small icon-button\r\n * that opens the URL in a new tab. Use this to point at app-specific docs.\r\n */\r\n helpUrl?: string;\r\n /** Tooltip / aria-label for the help link. Default \"Help & documentation\". */\r\n helpLabel?: string;\r\n /**\r\n * Right-aligned action slot — typically a primary \"+ New\" button and/or\r\n * secondary controls. Rendered before the help / intro-reopen icon-buttons.\r\n */\r\n actions?: ReactNode;\r\n /**\r\n * Extra header content rendered between `actions` and the trailing\r\n * help / reopen icon-buttons. Used by RecordsAdminShell for its stats strip;\r\n * standalone apps rarely need it.\r\n */\r\n aside?: ReactNode;\r\n /**\r\n * Optional dismissible intro card rendered below the header row.\r\n * See {@link AdminPageHeaderIntro}.\r\n */\r\n intro?: AdminPageHeaderIntro;\r\n /** Extra class on the root container for layout overrides. */\r\n className?: string;\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 function AdminPageHeader({\r\n title, subtitle, icon, helpUrl, helpLabel,\r\n actions, aside, intro, className,\r\n}: AdminPageHeaderProps) {\r\n const titleId = useId();\r\n const resolvedHelpLabel = helpLabel ?? 'Help & documentation';\r\n const resolvedReopenLabel = intro?.reopenLabel ?? 'How it works';\r\n const showReopen = !!intro && intro.dismissed && !!intro.onReopen;\r\n const showIntro = !!intro && !intro.dismissed;\r\n\r\n return (\r\n <header className={`sl-aph${className ? ` ${className}` : ''}`} aria-labelledby={titleId}>\r\n <div className=\"sl-aph__row\">\r\n <div className=\"sl-aph__main\">\r\n <div className=\"sl-aph__text\">\r\n <h1 className=\"sl-aph__title\" id={titleId}>\r\n {icon ? (\r\n <span className=\"sl-aph__icon\" aria-hidden=\"true\">{icon}</span>\r\n ) : null}\r\n <span>{title}</span>\r\n </h1>\r\n {subtitle ? <p className=\"sl-aph__subtitle\">{subtitle}</p> : null}\r\n </div>\r\n </div>\r\n {(actions || aside || helpUrl || showReopen) ? (\r\n <div className=\"sl-aph__aside\">\r\n {actions}\r\n {aside}\r\n {helpUrl ? (\r\n <a\r\n href={helpUrl}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"sl-aph__icon-btn\"\r\n aria-label={resolvedHelpLabel}\r\n title={resolvedHelpLabel}\r\n >\r\n <BookOpen aria-hidden=\"true\" />\r\n </a>\r\n ) : null}\r\n {showReopen ? (\r\n <button\r\n type=\"button\"\r\n onClick={intro!.onReopen}\r\n className=\"sl-aph__icon-btn\"\r\n aria-label={resolvedReopenLabel}\r\n title={resolvedReopenLabel}\r\n >\r\n <HelpCircle aria-hidden=\"true\" />\r\n </button>\r\n ) : null}\r\n </div>\r\n ) : null}\r\n </div>\r\n {showIntro ? <AdminPageHeaderIntroCard intro={intro!} /> : null}\r\n </header>\r\n );\r\n}\r\n\r\nfunction AdminPageHeaderIntroCard({ intro }: { intro: AdminPageHeaderIntro }) {\r\n const tone = intro.tone ?? 'info';\r\n const Icon = TONE_ICON[tone] ?? Info;\r\n return (\r\n <div className=\"sl-aph__intro\" data-tone={tone} role=\"note\">\r\n <div className=\"sl-aph__intro-icon\">\r\n <Icon aria-hidden=\"true\" style={{ width: '0.95rem', height: '0.95rem' }} />\r\n </div>\r\n <div className=\"sl-aph__intro-body\">\r\n <h4 className=\"sl-aph__intro-title\">{intro.title}</h4>\r\n <span className=\"sl-aph__intro-text\">{intro.body}</span>\r\n {intro.action ? <span className=\"sl-aph__intro-action\">{intro.action}</span> : null}\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={intro.onDismiss}\r\n aria-label=\"Dismiss\"\r\n className=\"sl-aph__intro-dismiss\"\r\n >\r\n <X aria-hidden=\"true\" style={{ width: '0.875rem', height: '0.875rem' }} />\r\n </button>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// RecordsAdmin — ShellHeader (v0.5)\r\n//\r\n// Thin adapter that resolves the contextual icon + stats strip and delegates\r\n// the actual header chrome to the standalone `<AdminPageHeader>` so the shell\r\n// and any other admin app share one implementation.\r\n// =============================================================================\r\nimport { createElement, type ReactNode } from 'react';\r\nimport { pickHeaderIcon, type RecordsAdminIcons } from './icons';\r\nimport { AdminPageHeader, type AdminPageHeaderIntro } from '../../AdminPageHeader';\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 /** External help / docs URL (rendered as an icon-button to the right). */\r\n helpUrl?: string;\r\n /** Tooltip / aria-label for the help link. */\r\n helpLabel?: string;\r\n /**\r\n * Optional intro card config — when provided, AdminPageHeader renders the\r\n * dismissible intro and the `?` reopen affordance for us.\r\n */\r\n intro?: AdminPageHeaderIntro;\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 helpUrl, helpLabel, intro,\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 const statsNode = 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\r\n return (\r\n <div className=\"ra-header\">\r\n <AdminPageHeader\r\n title={title}\r\n subtitle={subtitle}\r\n icon={iconNode}\r\n actions={headerActions}\r\n aside={statsNode}\r\n helpUrl={helpUrl}\r\n helpLabel={helpLabel}\r\n intro={intro}\r\n />\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// NewRuleWizard\r\n//\r\n// Two-step inline wizard rendered in the editor pane when the admin clicks\r\n// \"+ New rule\". Replaces the old behaviour of dropping straight into the\r\n// editor (which, in collection cardinality mode, surfaced the existing items\r\n// at the collection root and confused users).\r\n//\r\n// Step 1 — Configure rule\r\n// Renders the standard <FacetRuleEditor> + a live \"matches N products\"\r\n// preview chip. Cancel / Next buttons. Next is disabled until the rule\r\n// has at least one clause and every clause has values.\r\n//\r\n// Step 2 — Configure record (host-driven)\r\n// The shell takes over: it mounts the normal editor with `initialFacetRule`\r\n// pre-seeded, OR (collection cardinality) shows the empty item list with a\r\n// primary \"Create your first item\" CTA. This component renders only a\r\n// compact step header (Back · Cancel) above whatever the shell hands in\r\n// via the `children` slot.\r\n//\r\n// Persistence: the rule itself is NOT persisted on Next. It rides into the\r\n// SDK on the first record save under it (carried as the record's facetRule).\r\n// =============================================================================\r\nimport { type ReactNode } from 'react';\r\nimport { ArrowLeft, ArrowRight, X } from 'lucide-react';\r\nimport type { SmartLinksSDK } from '../types';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport { FacetRuleEditor } from '../../FacetRuleEditor/FacetRuleEditor';\r\nimport { useRulePreview, isFacetRuleValid } from '../hooks/useRulePreview';\r\n\r\nexport interface NewRuleWizardProps {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n step: 1 | 2;\r\n rule: FacetRule | null;\r\n onRuleChange: (next: FacetRule | null) => void;\r\n onCancel: () => void;\r\n onNext: () => void;\r\n onBack: () => void;\r\n /**\r\n * Step 2 body — typically the normal record editor (singleton mode) or the\r\n * empty-state with a \"+ Create your first item\" CTA (collection mode).\r\n * The wizard owns only the step chrome above this.\r\n */\r\n children?: ReactNode;\r\n /** Display label for the record type (e.g. \"recipe\", \"discount\"). */\r\n itemNoun?: string;\r\n}\r\n\r\nexport function NewRuleWizard({\r\n SL, collectionId, appId, step, rule, onRuleChange,\r\n onCancel, onNext, onBack, children, itemNoun = 'record',\r\n}: NewRuleWizardProps) {\r\n const preview = useRulePreview({ SL, collectionId, appId, rule });\r\n const canProceed = isFacetRuleValid(rule);\r\n\r\n if (step === 1) {\r\n return (\r\n <div className=\"flex h-full flex-col overflow-hidden\">\r\n <WizardStepHeader\r\n step={1}\r\n totalSteps={2}\r\n title=\"Configure rule\"\r\n description=\"Pick the facet conditions that decide which products this rule applies to.\"\r\n onCancel={onCancel}\r\n />\r\n <div className=\"flex-1 min-h-0 overflow-auto px-5 py-4\">\r\n <FacetRuleEditor\r\n value={rule}\r\n onChange={onRuleChange}\r\n collectionId={collectionId}\r\n preview={preview}\r\n description=\"The new rule will apply to every product whose facets match every clause below.\"\r\n />\r\n </div>\r\n <WizardFooter\r\n left={\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n >\r\n Cancel\r\n </button>\r\n }\r\n right={\r\n <button\r\n type=\"button\"\r\n onClick={onNext}\r\n disabled={!canProceed}\r\n className=\"ra-btn\"\r\n data-variant=\"primary\"\r\n >\r\n <span>Next</span>\r\n <ArrowRight aria-hidden=\"true\" className=\"w-4 h-4\" />\r\n </button>\r\n }\r\n hint={\r\n !canProceed\r\n ? 'Add at least one facet clause with values to continue.'\r\n : preview.totalMatches != null\r\n ? `${preview.totalMatches} product${preview.totalMatches === 1 ? '' : 's'} currently match this rule.`\r\n : undefined\r\n }\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n // Step 2 — host-driven body, wizard only renders the step header.\r\n return (\r\n <div className=\"flex h-full flex-col overflow-hidden\">\r\n <WizardStepHeader\r\n step={2}\r\n totalSteps={2}\r\n title={`Configure ${itemNoun}`}\r\n description={\r\n preview.totalMatches != null\r\n ? `This rule currently matches ${preview.totalMatches} product${preview.totalMatches === 1 ? '' : 's'}.`\r\n : 'Fill in the details for this rule.'\r\n }\r\n onCancel={onCancel}\r\n onBack={onBack}\r\n />\r\n <div className=\"flex-1 min-h-0 overflow-hidden\">{children}</div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction WizardStepHeader({\r\n step, totalSteps, title, description, onCancel, onBack,\r\n}: {\r\n step: number;\r\n totalSteps: number;\r\n title: string;\r\n description?: string;\r\n onCancel: () => void;\r\n onBack?: () => void;\r\n}) {\r\n return (\r\n <div\r\n className=\"flex items-start gap-3 px-5 py-3 border-b\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-muted) / 0.4)' }}\r\n >\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 mb-0.5\">\r\n <span\r\n className=\"text-[10px] font-semibold uppercase tracking-wider px-1.5 py-0.5 rounded\"\r\n style={{\r\n color: 'hsl(var(--ra-accent))',\r\n background: 'hsl(var(--ra-accent) / 0.12)',\r\n }}\r\n >\r\n Step {step} of {totalSteps}\r\n </span>\r\n <h2\r\n className=\"text-sm font-semibold m-0\"\r\n style={{ color: 'hsl(var(--ra-text))' }}\r\n >\r\n {title}\r\n </h2>\r\n </div>\r\n {description ? (\r\n <p\r\n className=\"text-xs m-0\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n {description}\r\n </p>\r\n ) : null}\r\n </div>\r\n <div className=\"flex items-center gap-1.5 shrink-0\">\r\n {onBack ? (\r\n <button\r\n type=\"button\"\r\n onClick={onBack}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n aria-label=\"Back to rule\"\r\n >\r\n <ArrowLeft aria-hidden=\"true\" className=\"w-4 h-4\" />\r\n <span>Back</span>\r\n </button>\r\n ) : null}\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"ra-btn\"\r\n data-variant=\"ghost\"\r\n aria-label=\"Cancel new rule\"\r\n title=\"Cancel\"\r\n style={{ width: '2rem', height: '2rem', padding: 0, justifyContent: 'center' }}\r\n >\r\n <X aria-hidden=\"true\" className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction WizardFooter({\r\n left, right, hint,\r\n}: {\r\n left?: ReactNode;\r\n right?: ReactNode;\r\n hint?: string;\r\n}) {\r\n return (\r\n <div\r\n className=\"flex items-center gap-3 px-5 py-3 border-t\"\r\n style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}\r\n >\r\n <div className=\"flex items-center gap-2\">{left}</div>\r\n {hint ? (\r\n <span\r\n className=\"text-xs flex-1 min-w-0 truncate\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n {hint}\r\n </span>\r\n ) : <div className=\"flex-1\" />}\r\n <div className=\"flex items-center gap-2 shrink-0\">{right}</div>\r\n </div>\r\n );\r\n}","// =============================================================================\r\n// UnsavedTray — shell-level pill replacing the per-record UnsavedBanner\r\n// when more than one record has unsaved changes. Collapses to a familiar\r\n// single-record banner when only one draft is in flight.\r\n//\r\n// Renders:\r\n// ● 5 records have unsaved changes [Save all] [Discard all]\r\n// ⚠ 2 errors [Jump to error]\r\n//\r\n// Consumes the new editor-session DirtyOverview shape (post-2a refactor).\r\n// =============================================================================\r\nimport { useState, useRef, useEffect, type ComponentType } from 'react';\r\nimport { AlertCircle, Save, Undo2, ChevronDown } from 'lucide-react';\r\nimport type { DirtyOverviewItem, EditorStatus } from '../editor-session/types';\r\n\r\ntype IconCmp = ComponentType<{ className?: string }>;\r\n\r\nexport interface UnsavedTrayProps {\r\n items: DirtyOverviewItem[];\r\n isSaving?: boolean;\r\n onSaveAll: () => void;\r\n onDiscardAll: () => void;\r\n onOpenItem?: (item: DirtyOverviewItem) => void;\r\n onJumpToError?: () => void;\r\n saveLabel: string;\r\n discardLabel: string;\r\n saveAllLabel: string;\r\n discardAllLabel: string;\r\n countTemplate: string; // \"{n} records have unsaved changes\"\r\n errorCountTemplate: string; // \"{n} errors\"\r\n jumpToErrorLabel: string;\r\n SaveIcon?: IconCmp;\r\n DiscardIcon?: IconCmp;\r\n}\r\n\r\nconst statusDot = (status: EditorStatus): string => {\r\n switch (status) {\r\n case 'saving': return 'hsl(var(--ra-accent))';\r\n case 'saved': return 'hsl(var(--ra-success, 142 71% 45%))';\r\n case 'error': return 'hsl(var(--ra-danger, 0 72% 51%))';\r\n case 'dirty':\r\n default: return 'hsl(var(--ra-warning, 38 92% 50%))';\r\n }\r\n};\r\n\r\nexport const UnsavedTray = ({\r\n items, isSaving, onSaveAll, onDiscardAll, onOpenItem, onJumpToError,\r\n saveLabel, discardLabel, saveAllLabel, discardAllLabel,\r\n countTemplate, errorCountTemplate, jumpToErrorLabel,\r\n SaveIcon, DiscardIcon,\r\n}: UnsavedTrayProps) => {\r\n const [open, setOpen] = useState(false);\r\n const wrapRef = useRef<HTMLDivElement | null>(null);\r\n const SI: IconCmp = SaveIcon ?? Save;\r\n const DI: IconCmp = DiscardIcon ?? Undo2;\r\n\r\n const total = items.length;\r\n const errors = items.filter((i) => i.status === 'error').length;\r\n const isSingle = total === 1;\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n const onDoc = (e: MouseEvent) => {\r\n if (!wrapRef.current?.contains(e.target as Node)) setOpen(false);\r\n };\r\n window.addEventListener('mousedown', onDoc);\r\n return () => window.removeEventListener('mousedown', onDoc);\r\n }, [open]);\r\n\r\n if (total === 0) return null;\r\n\r\n const countLabel = isSingle\r\n ? (items[0].label || 'this record')\r\n : countTemplate.replace('{n}', String(total));\r\n\r\n return (\r\n <div\r\n ref={wrapRef}\r\n className=\"ra-unsaved-tray\"\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n onClick={(e) => e.stopPropagation()}\r\n onMouseDown={(e) => e.stopPropagation()}\r\n onTouchStart={(e) => e.stopPropagation()}\r\n >\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\r\n {isSingle ? (\r\n <span className=\"ra-unsaved-text\">\r\n Unsaved changes on <strong>{countLabel}</strong>\r\n </span>\r\n ) : (\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-count\"\r\n onClick={() => setOpen((v) => !v)}\r\n aria-expanded={open}\r\n >\r\n {countLabel}\r\n <ChevronDown className=\"w-3 h-3\" />\r\n </button>\r\n )}\r\n\r\n {errors > 0 && (\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-error-chip\"\r\n onClick={() => onJumpToError?.()}\r\n title={jumpToErrorLabel}\r\n >\r\n ⚠ {errorCountTemplate.replace('{n}', String(errors))}\r\n </button>\r\n )}\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={onDiscardAll}\r\n disabled={isSaving}\r\n >\r\n <DI className=\"w-3 h-3\" />\r\n {isSingle ? discardLabel : discardAllLabel}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-primary\"\r\n onClick={onSaveAll}\r\n disabled={isSaving}\r\n >\r\n <SI className=\"w-3 h-3\" />\r\n {isSingle ? saveLabel : saveAllLabel}\r\n </button>\r\n </div>\r\n\r\n {open && !isSingle && (\r\n <div className=\"ra-unsaved-popover\" role=\"menu\">\r\n {items.map((it) => (\r\n <button\r\n type=\"button\"\r\n key={it.editorId}\r\n className=\"ra-unsaved-popover-row\"\r\n onClick={() => { setOpen(false); onOpenItem?.(it); }}\r\n role=\"menuitem\"\r\n >\r\n <span\r\n className=\"ra-unsaved-popover-dot\"\r\n style={{ background: statusDot(it.status) }}\r\n aria-hidden=\"true\"\r\n />\r\n <span className=\"ra-unsaved-popover-label\">{it.label || 'Default'}</span>\r\n {it.status === 'error' && (\r\n <span className=\"ra-unsaved-popover-err\">failed</span>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// HeaderUnsavedPill — compact unsaved-changes control surface designed to\r\n// live inside AdminPageHeader's right-aligned `actions` slot.\r\n//\r\n// Behaviour:\r\n// - 1 dirty record: just the Save + Discard buttons (no label).\r\n// - 2-4 dirty records: \"{n} unsaved\" label + Save all + Discard.\r\n// - 5+ dirty records OR any errors: returns null so the shell falls back\r\n// to the full-width UnsavedTray banner.\r\n//\r\n// Consumes the new editor-session DirtyOverview shape (post-2a refactor).\r\n// =============================================================================\r\nimport { type ComponentType } from 'react';\r\nimport { AlertCircle, Save, Undo2 } from 'lucide-react';\r\nimport type { DirtyOverviewItem } from '../editor-session/types';\r\n\r\ntype IconCmp = ComponentType<{ className?: string }>;\r\n\r\nexport interface HeaderUnsavedPillProps {\r\n items: DirtyOverviewItem[];\r\n isSaving?: boolean;\r\n onSaveAll: () => void;\r\n onDiscardAll: () => void;\r\n saveLabel: string;\r\n discardLabel: string;\r\n saveAllLabel: string;\r\n discardAllLabel: string;\r\n /** Template like \"{n} unsaved\" — `{n}` is replaced with the count. */\r\n countTemplate: string;\r\n SaveIcon?: IconCmp;\r\n DiscardIcon?: IconCmp;\r\n}\r\n\r\n/** Threshold past which the shell falls back to the full banner. */\r\nexport const HEADER_PILL_OVERFLOW_THRESHOLD = 5;\r\n\r\n/** True when the pill can render the dirty state inline; false → use tray. */\r\nexport function canRenderInHeader(items: DirtyOverviewItem[]): boolean {\r\n if (items.length === 0) return false;\r\n if (items.length >= HEADER_PILL_OVERFLOW_THRESHOLD) return false;\r\n if (items.some((i) => i.status === 'error')) return false;\r\n return true;\r\n}\r\n\r\nexport const HeaderUnsavedPill = ({\r\n items, isSaving,\r\n onSaveAll, onDiscardAll,\r\n saveLabel, discardLabel, saveAllLabel, discardAllLabel,\r\n countTemplate, SaveIcon, DiscardIcon,\r\n}: HeaderUnsavedPillProps) => {\r\n const SI: IconCmp = SaveIcon ?? Save;\r\n const DI: IconCmp = DiscardIcon ?? Undo2;\r\n\r\n if (items.length === 0) return null;\r\n const total = items.length;\r\n const isSingle = total === 1;\r\n\r\n return (\r\n <div\r\n className=\"ra-unsaved-pill\"\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n onClick={(e) => e.stopPropagation()}\r\n onMouseDown={(e) => e.stopPropagation()}\r\n onTouchStart={(e) => e.stopPropagation()}\r\n >\r\n {!isSingle && (\r\n <>\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-pill-text\">\r\n {countTemplate.replace('{n}', String(total))}\r\n </span>\r\n </>\r\n )}\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-ghost\"\r\n onClick={onDiscardAll}\r\n disabled={isSaving}\r\n >\r\n <DI className=\"w-3 h-3\" />\r\n {isSingle ? discardLabel : discardAllLabel}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-primary\"\r\n onClick={onSaveAll}\r\n disabled={isSaving}\r\n >\r\n <SI className=\"w-3 h-3\" />\r\n {isSingle ? saveLabel : saveAllLabel}\r\n </button>\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// SaveAllProgress — modal overlay shown while a \"Save all\" pass is running.\r\n//\r\n// Uses an injected `saveOne(editorId)` callback (provided by the shell from\r\n// the EditorStore) and reads live status via the items list which the\r\n// caller refreshes from useDirtyOverview.\r\n// =============================================================================\r\nimport { useEffect, useMemo, useRef, useState } from 'react';\r\nimport { CheckCircle2, Loader2, XCircle, Circle } from 'lucide-react';\r\nimport type { DirtyOverviewItem } from '../editor-session/types';\r\n\r\nexport interface SaveAllProgressProps {\r\n open: boolean;\r\n /** Live list of dirty/saving/errored items (typically from useDirtyOverview). */\r\n items: DirtyOverviewItem[];\r\n /** Persist a single editor by id. Resolves on success, throws on failure. */\r\n saveOne: (editorId: string) => Promise<void>;\r\n onClose: () => void;\r\n onJumpToError?: (item: DirtyOverviewItem) => void;\r\n i18n: {\r\n title: string; // \"Saving {n} records…\"\r\n successTitle: string; // \"Saved {n} records\"\r\n errorTitle: string; // \"Saved with errors\"\r\n stop: string;\r\n close: string;\r\n retryFailed: string;\r\n jumpToError: string;\r\n };\r\n}\r\n\r\nexport const SaveAllProgress = ({\r\n open, items, saveOne, onClose, onJumpToError, i18n,\r\n}: SaveAllProgressProps) => {\r\n const [running, setRunning] = useState(false);\r\n const [done, setDone] = useState(false);\r\n const stopRef = useRef(false);\r\n // Snapshot the editorIds at run start so the visible row list is stable\r\n // even though the underlying overview will change as saves progress.\r\n const [batchIds, setBatchIds] = useState<string[]>([]);\r\n\r\n useEffect(() => {\r\n if (!open) {\r\n setRunning(false);\r\n setDone(false);\r\n stopRef.current = false;\r\n setBatchIds([]);\r\n return;\r\n }\r\n const initial = items.map((i) => i.editorId);\r\n setBatchIds(initial);\r\n void runBatch(initial);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [open]);\r\n\r\n const runBatch = async (ids: string[]) => {\r\n setRunning(true);\r\n setDone(false);\r\n stopRef.current = false;\r\n for (const id of ids) {\r\n if (stopRef.current) break;\r\n try { await saveOne(id); }\r\n catch { /* status moves to 'error' in the store */ }\r\n }\r\n setRunning(false);\r\n setDone(true);\r\n };\r\n\r\n // Resolve current items by id so the overlay reflects live status.\r\n const visible = useMemo(() => batchIds.map((id) => {\r\n const live = items.find((i) => i.editorId === id);\r\n return live ?? {\r\n editorId: id, label: '', status: 'saved' as const, scope: { kind: 'collection', raw: '' as string } as DirtyOverviewItem['scope'],\r\n };\r\n }), [batchIds, items]);\r\n\r\n const total = visible.length;\r\n const completed = visible.filter((d) => d.status !== 'dirty' && d.status !== 'saving').length;\r\n const errors = visible.filter((d) => d.status === 'error');\r\n const successAll = done && errors.length === 0 && completed === total;\r\n\r\n useEffect(() => {\r\n if (!successAll) return;\r\n const t = window.setTimeout(() => onClose(), 800);\r\n return () => window.clearTimeout(t);\r\n }, [successAll, onClose]);\r\n\r\n if (!open) return null;\r\n\r\n const title = running\r\n ? i18n.title.replace('{n}', String(total))\r\n : (errors.length > 0\r\n ? i18n.errorTitle\r\n : i18n.successTitle.replace('{n}', String(total)));\r\n\r\n return (\r\n <div\r\n className=\"ra-saveall-overlay\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-label={title}\r\n >\r\n <div\r\n className=\"ra-saveall-card\"\r\n onClick={(e) => e.stopPropagation()}\r\n onMouseDown={(e) => e.stopPropagation()}\r\n onTouchStart={(e) => e.stopPropagation()}\r\n >\r\n <div className=\"ra-saveall-header\">\r\n <div className=\"ra-saveall-title\">{title}</div>\r\n <div className=\"ra-saveall-progress\" aria-hidden=\"true\">\r\n <div\r\n className=\"ra-saveall-progress-bar\"\r\n style={{ width: `${total ? (completed / total) * 100 : 0}%` }}\r\n />\r\n </div>\r\n <div className=\"ra-saveall-counter\">\r\n {completed} / {total}\r\n </div>\r\n </div>\r\n\r\n <ul className=\"ra-saveall-list\">\r\n {visible.map((d) => (\r\n <li key={d.editorId} className=\"ra-saveall-row\" data-status={d.status}>\r\n <span className=\"ra-saveall-icon\" aria-hidden=\"true\">\r\n {d.status === 'saving' && <Loader2 className=\"w-4 h-4 ra-spin\" />}\r\n {d.status === 'saved' && <CheckCircle2 className=\"w-4 h-4\" />}\r\n {d.status === 'error' && <XCircle className=\"w-4 h-4\" />}\r\n {(d.status === 'dirty') && <Circle className=\"w-4 h-4\" />}\r\n </span>\r\n <span className=\"ra-saveall-label\">{d.label || 'Default'}</span>\r\n {d.status === 'error' && (\r\n <span className=\"ra-saveall-err\" title={String((d.error as Error)?.message ?? d.error ?? '')}>\r\n {(d.error as Error)?.message ?? 'Save failed'}\r\n </span>\r\n )}\r\n </li>\r\n ))}\r\n </ul>\r\n\r\n <div className=\"ra-saveall-actions\">\r\n {running && (\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-ghost\"\r\n onClick={() => { stopRef.current = true; }}\r\n >\r\n {i18n.stop}\r\n </button>\r\n )}\r\n {!running && errors.length > 0 && (\r\n <>\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-ghost\"\r\n onClick={() => { onJumpToError?.(errors[0]); onClose(); }}\r\n >\r\n {i18n.jumpToError}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-primary\"\r\n onClick={() => void runBatch(errors.map((e) => e.editorId))}\r\n >\r\n {i18n.retryFailed}\r\n </button>\r\n </>\r\n )}\r\n {!running && (\r\n <button\r\n type=\"button\"\r\n className=\"ra-unsaved-btn ra-unsaved-btn-ghost\"\r\n onClick={onClose}\r\n >\r\n {i18n.close}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// EditorMountPool — mounts the host's editor JSX once per open editorId and\r\n// toggles visibility so switching between records is instant (no remount).\r\n//\r\n// Design notes\r\n// ------------\r\n// * The pool only owns the *editor body* (whatever `renderSlot` returns).\r\n// All surrounding chrome — preview pane, item nav, scope picker, drawer —\r\n// stays in the shell and tracks the active selection. That chrome is cheap\r\n// to remount; the editor body (rich text, complex forms, file pickers) is\r\n// not, which is what we're protecting here.\r\n//\r\n// * Each slot is keyed by `editorId`, so React never reuses one slot's mount\r\n// for another. When the EditorStore evicts an entry (LRU), it falls out\r\n// of `openEditors` and the slot unmounts naturally. Dirty entries are\r\n// pinned in the store and therefore stay mounted across selections.\r\n//\r\n// * Inactive slots are hidden via `display: none`. This preserves React\r\n// state, refs, and uncontrolled DOM (form inputs, contenteditable, etc.)\r\n// without painting or laying out the subtree.\r\n//\r\n// * `keepMountedHidden={false}` is an opt-out for hosts whose editor\r\n// misbehaves when hidden (e.g. measurement-dependent canvases). In that\r\n// mode the pool degrades to single-active behaviour.\r\n//\r\n// * Inactive slots are wrapped with `inert` + `aria-hidden` so keyboard\r\n// focus and AT cursors don't escape into hidden editors.\r\n// =============================================================================\r\nimport { type ReactNode, useMemo } from 'react';\r\nimport { useEditorSelection } from './EditorSessionProvider';\r\nimport type { EditorId } from './types';\r\n\r\nexport interface EditorMountPoolProps {\r\n /**\r\n * Render the editor body for one slot. Called once per open editor and\r\n * memoised by `editorId` — the function itself does not need to be\r\n * referentially stable, but its output should depend only on `editorId`\r\n * (read live state inside via `useEditorSession(editorId)`).\r\n */\r\n renderSlot: (editorId: EditorId) => ReactNode;\r\n /**\r\n * When false, only the active slot mounts. Use for hosts whose editor\r\n * cannot survive `display: none` (rare). Defaults to true.\r\n */\r\n keepMountedHidden?: boolean;\r\n /** Optional fallback when no editor is selected. */\r\n fallback?: ReactNode;\r\n /** className applied to the pool container. */\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Renders one mounted slot per open editor. Only the slot matching\r\n * `currentEditorId` is visible; the rest are kept in the DOM but hidden.\r\n */\r\nexport const EditorMountPool = ({\r\n renderSlot, keepMountedHidden = true, fallback = null, className,\r\n}: EditorMountPoolProps) => {\r\n const { openEditors, currentEditorId } = useEditorSelection();\r\n\r\n // Snapshot ids in a stable order so React's reconciler doesn't shuffle\r\n // mounts when the store reorders entries (e.g. on markActive).\r\n const ids = useMemo(\r\n () => openEditors.map((e) => e.editorId).sort(),\r\n [openEditors],\r\n );\r\n\r\n if (!currentEditorId && ids.length === 0) {\r\n return <>{fallback}</>;\r\n }\r\n\r\n const visibleIds = keepMountedHidden\r\n ? ids\r\n : (currentEditorId ? [currentEditorId] : []);\r\n\r\n return (\r\n <div className={className} style={{ display: 'contents' }}>\r\n {visibleIds.map((id) => {\r\n const isActive = id === currentEditorId;\r\n return (\r\n <EditorPoolSlot key={id} editorId={id} isActive={isActive}>\r\n {renderSlot(id)}\r\n </EditorPoolSlot>\r\n );\r\n })}\r\n </div>\r\n );\r\n};\r\n\r\ninterface EditorPoolSlotProps {\r\n editorId: EditorId;\r\n isActive: boolean;\r\n children: ReactNode;\r\n}\r\n\r\n/**\r\n * One pool entry. Wraps the host editor in a hidden container when\r\n * inactive. Uses `display: contents` when active so the wrapper does not\r\n * disturb the chrome's flex/grid layout.\r\n */\r\nconst EditorPoolSlot = ({ editorId, isActive, children }: EditorPoolSlotProps) => {\r\n // `inert` is the right tool here but isn't reflected as a JSX prop in\r\n // older React types — set via the boolean attribute string. Modern\r\n // browsers (and our target matrix) support it natively.\r\n const inertProps = isActive ? {} : { inert: '' as unknown as boolean };\r\n\r\n return (\r\n <div\r\n data-editor-slot={editorId}\r\n data-active={isActive ? 'true' : 'false'}\r\n aria-hidden={isActive ? undefined : true}\r\n style={{\r\n display: isActive ? 'contents' : 'none',\r\n }}\r\n {...inertProps}\r\n >\r\n {children}\r\n </div>\r\n );\r\n};","// =============================================================================\r\n// useEditorSlotContext — per-slot adapter for the EditorMountPool.\r\n//\r\n// EditorMountPool calls `renderSlot(editorId)` for every open editor,\r\n// including hidden ones. The host's `renderEditor(ctx)` still expects a\r\n// legacy EditorContext, so this hook produces one for any editorId by\r\n// reading directly from the EditorStore via `useEditorSession(editorId)`.\r\n//\r\n// Unlike `useEditorBridge`, this hook does NOT own selection or hydration\r\n// for its slot — those happen at the shell level for the active editor.\r\n// Inactive slots simply mirror the value/baseline already in the store.\r\n// =============================================================================\r\nimport { useMemo } from 'react';\r\nimport type { EditorContext } from '../types';\r\nimport { useEditorSession } from './EditorSessionProvider';\r\nimport type { EditorId } from './types';\r\n\r\nexport function useEditorSlotContext<T>(editorId: EditorId): EditorContext<T> | null {\r\n const session = useEditorSession<T>(editorId);\r\n return useMemo<EditorContext<T> | null>(() => {\r\n if (!session) return null;\r\n return {\r\n value: session.value,\r\n onChange: session.onChange as EditorContext<T>['onChange'],\r\n source: session.source,\r\n recordId: session.recordId,\r\n parentValue: session.parentValue,\r\n scope: session.scope,\r\n isDirty: session.isDirty,\r\n save: session.save,\r\n reset: session.reset,\r\n remove: session.remove,\r\n canRemove: session.canRemove,\r\n canSave: session.canSave,\r\n cannotSaveReason: session.cannotSaveReason,\r\n isSaving: session.status === 'saving',\r\n saveError: session.error,\r\n facetRule: session.facetRule,\r\n onFacetRuleChange: session.onFacetRuleChange,\r\n };\r\n }, [session]);\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};","// =============================================================================\r\n// useShellCsvBulk — extracted CSV import/export wiring for RecordsAdminShell.\r\n//\r\n// Returns a stable `csvBulk` object suitable for `RecordEditor`'s\r\n// `bulkActions` slot. When no `csvSchema` is supplied the hook returns an\r\n// empty object — same semantics as the original inline logic.\r\n//\r\n// Pure refactor: behaviour, telemetry payloads and filename derivation are\r\n// identical to the previous inline handlers.\r\n// =============================================================================\r\nimport { useCallback, useMemo } from 'react';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport { exportCsv, importCsv, downloadBlob } from '../data/csv';\r\nimport type { RecordSummary } from '../types';\r\nimport type { TelemetryEvent } from '../types/telemetry';\r\nimport type { CsvSchema } from '../types/csv';\r\n\r\nexport interface UseShellCsvBulkArgs<TData> {\r\n csvSchema?: CsvSchema<TData>;\r\n recordType?: string;\r\n /** Friendly label used as a fallback when `recordType` is unset. */\r\n label: string;\r\n /** Records-list snapshot used as the export source. */\r\n items: RecordSummary<TData>[];\r\n /** SDK context used by importCsv. */\r\n ctx: RecordsCtx;\r\n /** Refetcher fired after a successful import. */\r\n refetchAll: () => void;\r\n onTelemetry?: (event: TelemetryEvent) => void;\r\n}\r\n\r\nexport interface ShellCsvBulk {\r\n onImportCsv?: () => void;\r\n onExportCsv?: () => void;\r\n}\r\n\r\nexport function useShellCsvBulk<TData>(\r\n args: UseShellCsvBulkArgs<TData>,\r\n): ShellCsvBulk {\r\n const { csvSchema, recordType, label, items, ctx, refetchAll, onTelemetry } = args;\r\n\r\n const fileBase = useMemo(\r\n () => recordType ?? (label.toLowerCase().replace(/\\s+/g, '-') || 'records'),\r\n [recordType, label],\r\n );\r\n\r\n const handleExport = useCallback(() => {\r\n if (!csvSchema) return;\r\n const blob = exportCsv(items, csvSchema);\r\n downloadBlob(blob, `${fileBase}.csv`);\r\n onTelemetry?.({ type: 'csv.export', recordType, rows: items.length });\r\n }, [csvSchema, items, fileBase, onTelemetry, recordType]);\r\n\r\n const handleImport = useCallback(() => {\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 downloadBlob(\r\n new Blob([report.annotatedCsv], { type: 'text/csv' }),\r\n `${fileBase}-errors.csv`,\r\n );\r\n }\r\n refetchAll();\r\n };\r\n inp.click();\r\n }, [csvSchema, ctx, fileBase, onTelemetry, recordType, refetchAll]);\r\n\r\n return useMemo<ShellCsvBulk>(\r\n () => csvSchema ? { onImportCsv: handleImport, onExportCsv: handleExport } : {},\r\n [csvSchema, handleImport, handleExport],\r\n );\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:root {\\n --sl-control-bg: var(--muted, 220 14% 96%);\\n --sl-control-fg: var(--muted-foreground, 220 9% 40%);\\n --sl-control-border: var(--border, 220 13% 88%);\\n --sl-control-active-bg: var(--primary, 222 47% 11%);\\n --sl-control-active-fg: var(--primary-foreground, 0 0% 100%);\\n --sl-control-active-bd: var(--primary, 222 47% 11%);\\n --sl-control-hover-bg: var(--sl-control-active-bg, 222 47% 11%);\\n --sl-control-hover-fg: var(--foreground, 222 47% 11%);\\n --sl-control-focus-ring: var(--sl-control-active-bg, 222 47% 11%);\\n --sl-control-radius: var(--radius, 0.5rem);\\n --sl-control-weight: 500;\\n --sl-control-active-weight: 600;\\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 display: block;\\n width: 100%;\\n}\\n.ra-shell .ra-header__main {\\n flex: 1;\\n min-width: 0;\\n display: flex;\\n align-items: flex-start;\\n gap: 0.55rem;\\n}\\n.ra-shell .ra-header-aside {\\n display: flex;\\n align-items: flex-start;\\n gap: 0.5rem;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-header-icon {\\n flex-shrink: 0;\\n display: inline-flex;\\n align-items: center;\\n justify-content: flex-start;\\n background: transparent;\\n color: hsl(var(--ra-text));\\n border: 0;\\n padding: 0;\\n margin-top: 0.1rem;\\n}\\n.ra-shell .ra-header-icon > svg {\\n width: 1.05rem;\\n height: 1.05rem;\\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: 700;\\n font-size: 1.2rem;\\n line-height: 1.2;\\n color: hsl(var(--ra-text));\\n letter-spacing: -0.015em;\\n margin: 0;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.5rem;\\n}\\n.ra-shell .ra-header-subtitle {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-muted-text));\\n margin-top: 0.1rem;\\n line-height: 1.3;\\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(--sl-control-bg));\\n border-radius: var(--sl-control-radius);\\n border: 1px solid hsl(var(--sl-control-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(--sl-control-radius) - 2px);\\n font-size: 0.78rem;\\n font-weight: var(--sl-control-weight);\\n color: hsl(var(--sl-control-fg));\\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(--sl-control-hover-bg) / 0.10);\\n color: hsl(var(--sl-control-hover-fg));\\n}\\n.ra-shell .ra-tab:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 2px hsl(var(--sl-control-focus-ring) / 0.45);\\n}\\n.ra-shell .ra-tab[aria-selected=true] {\\n background: hsl(var(--sl-control-active-bg));\\n color: hsl(var(--sl-control-active-fg));\\n border-color: hsl(var(--sl-control-active-bd));\\n font-weight: var(--sl-control-active-weight);\\n box-shadow: 0 1px 2px hsl(var(--sl-control-active-bg) / 0.25);\\n}\\n.ra-shell .ra-tab[aria-selected=true]:hover {\\n background: hsl(var(--sl-control-active-bg) / 0.92);\\n color: hsl(var(--sl-control-active-fg));\\n}\\n.ra-shell .ra-tab[aria-selected=true] .ra-tab-icon {\\n color: hsl(var(--sl-control-active-fg));\\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(--sl-control-active-fg) / 0.20);\\n color: hsl(var(--sl-control-active-fg));\\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(--sl-control-fg) / 0.15);\\n color: hsl(var(--sl-control-fg));\\n}\\n.ra-shell[data-density=compact] .ra-row {\\n padding-block: 0.4rem;\\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 align-items: center;\\n gap: 0.55rem;\\n padding: 0.4rem 2rem 0.4rem 0.5rem;\\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}\\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: 1.5rem;\\n height: 1.5rem;\\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.8rem;\\n color: hsl(var(--ra-text));\\n margin: 0;\\n line-height: 1.2;\\n display: inline;\\n}\\n.ra-shell .ra-intro-text {\\n font-size: 0.78rem;\\n color: hsl(var(--ra-text) / 0.85);\\n line-height: 1.35;\\n display: inline;\\n margin-left: 0.4rem;\\n}\\n.ra-shell .ra-intro-dismiss {\\n position: absolute;\\n top: 50%;\\n right: 0.35rem;\\n transform: translateY(-50%);\\n width: 1.4rem;\\n height: 1.4rem;\\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 padding: 0;\\n flex-shrink: 0;\\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 background: transparent;\\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.sl-aph .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, 8px) - 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.sl-aph .ra-unsaved-btn:disabled {\\n opacity: 0.5;\\n cursor: not-allowed;\\n}\\n.sl-aph .ra-unsaved-btn:focus-visible {\\n outline: none;\\n box-shadow: 0 0 0 3px var(--ra-focus-ring, 0 0 0 3px hsl(var(--ra-accent) / 0.35));\\n}\\n.sl-aph .ra-unsaved-btn-ghost {\\n background: transparent;\\n color: hsl(var(--ra-muted-text));\\n border-color: hsl(var(--ra-border));\\n}\\n.sl-aph .ra-unsaved-btn-ghost:hover:not(:disabled) {\\n background: hsl(var(--ra-muted));\\n color: hsl(var(--ra-text));\\n}\\n.sl-aph .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.sl-aph .ra-unsaved-btn-primary:hover:not(:disabled) {\\n filter: brightness(0.95);\\n}\\n.sl-aph .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@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-unsaved-pill,\\n.sl-aph .ra-unsaved-pill {\\n display: inline-flex;\\n align-items: center;\\n gap: 0.4rem;\\n padding: 0.25rem 0.5rem 0.25rem 0.6rem;\\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: 999px;\\n animation: ra-unsaved-slide .14s ease-out;\\n}\\n.ra-shell .ra-unsaved-pill .ra-unsaved-pill-text,\\n.sl-aph .ra-unsaved-pill .ra-unsaved-pill-text {\\n font-size: 0.75rem;\\n font-weight: 500;\\n color: hsl(var(--ra-text));\\n white-space: nowrap;\\n margin-right: 0.15rem;\\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(var(--ra-item-card-min, 240px), 1fr));\\n gap: 0.85rem;\\n}\\n.ra-shell .ra-item-gallery {\\n display: grid;\\n grid-template-columns: repeat(auto-fill, minmax(var(--ra-item-gallery-min, 320px), 1fr));\\n gap: 1rem;\\n}\\n.ra-shell .ra-item-cards[data-card-size=sm] {\\n --ra-item-card-min: 180px;\\n}\\n.ra-shell .ra-item-cards[data-card-size=md] {\\n --ra-item-card-min: 240px;\\n}\\n.ra-shell .ra-item-cards[data-card-size=lg] {\\n --ra-item-card-min: 320px;\\n gap: 1rem;\\n}\\n.ra-shell .ra-item-gallery[data-card-size=sm] {\\n --ra-item-gallery-min: 240px;\\n}\\n.ra-shell .ra-item-gallery[data-card-size=md] {\\n --ra-item-gallery-min: 320px;\\n}\\n.ra-shell .ra-item-gallery[data-card-size=lg] {\\n --ra-item-gallery-min: 420px;\\n gap: 1.25rem;\\n}\\n.ra-shell .ra-item-cards[data-card-size=lg] .ra-item-card-title,\\n.ra-shell .ra-item-gallery[data-card-size=lg] .ra-item-card-title {\\n font-size: 0.95rem;\\n white-space: normal;\\n display: -webkit-box;\\n -webkit-line-clamp: 2;\\n -webkit-box-orient: vertical;\\n}\\n.ra-shell .ra-item-cards[data-card-size=lg] .ra-item-card-body,\\n.ra-shell .ra-item-gallery[data-card-size=lg] .ra-item-card-body {\\n padding: 0.85rem 1rem 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-error-pip {\\n display: inline-block;\\n width: 0.45rem;\\n height: 0.45rem;\\n border-radius: 9999px;\\n background: hsl(var(--ra-danger, 0 72% 51%));\\n box-shadow: 0 0 0 2px hsl(var(--ra-danger, 0 72% 51%) / 0.22);\\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 justify-content: center;\\n width: 1.6rem;\\n height: 1.6rem;\\n padding: 0;\\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.95rem;\\n height: 0.95rem;\\n}\\n.ra-shell .ra-help-float > span {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n padding: 0;\\n margin: -1px;\\n overflow: hidden;\\n clip: rect(0, 0, 0, 0);\\n white-space: nowrap;\\n border: 0;\\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.ra-shell .ra-unsaved-tray {\\n position: relative;\\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-count {\\n flex: 1;\\n min-width: 0;\\n display: inline-flex;\\n align-items: center;\\n gap: 0.3rem;\\n padding: 0.15rem 0.4rem;\\n margin: -0.15rem -0.4rem;\\n background: transparent;\\n border: 0;\\n color: inherit;\\n font: inherit;\\n font-weight: 500;\\n text-align: left;\\n cursor: pointer;\\n border-radius: calc(var(--ra-radius) - 4px);\\n}\\n.ra-shell .ra-unsaved-count:hover {\\n background: hsl(var(--ra-muted) / 0.6);\\n}\\n.ra-shell .ra-unsaved-error-chip {\\n -webkit-appearance: none;\\n -moz-appearance: none;\\n appearance: none;\\n border: 1px solid hsl(var(--ra-danger, 0 72% 51%) / 0.35);\\n background: hsl(var(--ra-danger, 0 72% 51%) / 0.08);\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n border-radius: 999px;\\n padding: 0.15rem 0.55rem;\\n font-size: 0.7rem;\\n font-weight: 500;\\n cursor: pointer;\\n}\\n.ra-shell .ra-unsaved-error-chip:hover {\\n filter: brightness(0.97);\\n}\\n.ra-shell .ra-unsaved-popover {\\n position: absolute;\\n top: calc(100% + 6px);\\n left: 0;\\n z-index: 60;\\n min-width: 18rem;\\n max-height: 18rem;\\n overflow: auto;\\n background: hsl(var(--ra-surface));\\n border: 1px solid hsl(var(--ra-border));\\n border-radius: var(--ra-radius);\\n box-shadow: 0 12px 30px -10px hsl(0 0% 0% / 0.25);\\n padding: 0.3rem;\\n display: flex;\\n flex-direction: column;\\n gap: 0.15rem;\\n}\\n.ra-shell .ra-unsaved-popover-row {\\n display: flex;\\n align-items: center;\\n gap: 0.5rem;\\n padding: 0.4rem 0.55rem;\\n background: transparent;\\n border: 0;\\n border-radius: calc(var(--ra-radius) - 2px);\\n cursor: pointer;\\n text-align: left;\\n font: inherit;\\n color: hsl(var(--ra-text));\\n}\\n.ra-shell .ra-unsaved-popover-row:hover {\\n background: hsl(var(--ra-muted));\\n}\\n.ra-shell .ra-unsaved-popover-dot {\\n width: 0.5rem;\\n height: 0.5rem;\\n border-radius: 999px;\\n flex-shrink: 0;\\n}\\n.ra-shell .ra-unsaved-popover-label {\\n flex: 1;\\n min-width: 0;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n font-size: 0.8125rem;\\n}\\n.ra-shell .ra-unsaved-popover-ctx {\\n color: hsl(var(--ra-muted-text));\\n font-size: 0.7rem;\\n text-transform: uppercase;\\n letter-spacing: 0.04em;\\n}\\n.ra-shell .ra-unsaved-popover-err {\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n font-size: 0.7rem;\\n font-weight: 500;\\n}\\n.ra-saveall-overlay {\\n position: fixed;\\n inset: 0;\\n z-index: 100;\\n background: hsl(0 0% 0% / 0.45);\\n display: flex;\\n align-items: center;\\n justify-content: center;\\n padding: 1rem;\\n animation: ra-confirm-fade .12s ease-out;\\n}\\n.ra-saveall-card {\\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 24px 48px -16px hsl(0 0% 0% / 0.45);\\n width: min(28rem, 100%);\\n max-height: min(80vh, 36rem);\\n display: flex;\\n flex-direction: column;\\n animation: ra-confirm-pop .14s ease-out;\\n}\\n.ra-saveall-header {\\n padding: 1rem 1rem 0.5rem;\\n display: flex;\\n flex-direction: column;\\n gap: 0.5rem;\\n}\\n.ra-saveall-title {\\n font-weight: 600;\\n font-size: 0.95rem;\\n}\\n.ra-saveall-progress {\\n height: 4px;\\n background: hsl(var(--ra-muted));\\n border-radius: 999px;\\n overflow: hidden;\\n}\\n.ra-saveall-progress-bar {\\n height: 100%;\\n background: hsl(var(--ra-accent));\\n transition: width .2s ease;\\n}\\n.ra-saveall-counter {\\n color: hsl(var(--ra-muted-text));\\n font-size: 0.75rem;\\n font-variant-numeric: tabular-nums;\\n}\\n.ra-saveall-list {\\n list-style: none;\\n margin: 0;\\n padding: 0.25rem 0.5rem;\\n overflow: auto;\\n flex: 1;\\n}\\n.ra-saveall-row {\\n display: flex;\\n align-items: center;\\n gap: 0.6rem;\\n padding: 0.45rem 0.5rem;\\n border-radius: calc(var(--ra-radius) - 4px);\\n font-size: 0.8125rem;\\n}\\n.ra-saveall-row[data-status=saving] {\\n background: hsl(var(--ra-accent) / 0.06);\\n}\\n.ra-saveall-row[data-status=saved] {\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-saveall-row[data-status=error] {\\n background: hsl(var(--ra-danger, 0 72% 51%) / 0.06);\\n}\\n.ra-saveall-icon {\\n display: inline-flex;\\n align-items: center;\\n justify-content: center;\\n flex-shrink: 0;\\n color: hsl(var(--ra-muted-text));\\n}\\n.ra-saveall-row[data-status=saved] .ra-saveall-icon {\\n color: hsl(var(--ra-success, 142 71% 45%));\\n}\\n.ra-saveall-row[data-status=saving] .ra-saveall-icon {\\n color: hsl(var(--ra-accent));\\n}\\n.ra-saveall-row[data-status=error] .ra-saveall-icon {\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n}\\n.ra-saveall-label {\\n flex: 1;\\n min-width: 0;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-saveall-err {\\n color: hsl(var(--ra-danger, 0 72% 51%));\\n font-size: 0.7rem;\\n max-width: 12rem;\\n white-space: nowrap;\\n overflow: hidden;\\n text-overflow: ellipsis;\\n}\\n.ra-saveall-actions {\\n padding: 0.75rem 1rem 1rem;\\n display: flex;\\n justify-content: flex-end;\\n gap: 0.4rem;\\n border-top: 1px solid hsl(var(--ra-border));\\n}\\n.ra-spin {\\n animation: ra-spin 1s linear infinite;\\n}\\n@keyframes ra-spin {\\n to {\\n transform: rotate(360deg);\\n }\\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 EditorContext,\r\n} from '../types';\r\nimport { DEFAULT_I18N } from '../types';\r\nimport { parseRef, buildRef } from '../data/refs';\r\nimport type { RecordsCtx } from '../data/records';\r\nimport { useResolvedRecord } from '../hooks/useResolvedRecord';\r\nimport { resolvedRecordQueryKey } from '../hooks/useResolvedRecord';\r\nimport { useQueryClient } from '@tanstack/react-query';\r\nimport { useIntroDismissed } from '../hooks/useIntroDismissed';\r\nimport { useScopeProbe } from '../hooks/useScopeProbe';\r\nimport { useShellBrowser, type ProductBrowseItem } from '../hooks/useShellBrowser';\r\nimport { useSingleProduct } from '../hooks/useSingleProduct';\r\nimport { useUnsavedGuard } from '../hooks/useUnsavedGuard';\r\nimport { useDirtyNavigation } from '../hooks/useDirtyNavigation';\r\nimport { useConfirmDialog } from '../hooks/useConfirmDialog';\r\nimport { useShellClipboard } from '../hooks/useShellClipboard';\r\nimport { useShellPreviewPane } from './state/useShellPreviewPane';\r\nimport { useShellNavigation } from './state/useShellNavigation';\r\nimport { useEditingScope } from './state/useEditingScope';\r\nimport { useShellDeepLink } from './state/useShellDeepLink';\r\nimport { useShellEditorTarget } from './state/useShellEditorTarget';\r\nimport { useShellSelection } from './state/useShellSelection';\r\nimport { ScopeTabs } from '../browser/ScopeTabs';\r\nimport { StatusFilterPills } from '../browser/StatusFilterPills';\r\nimport { RecordList } from '../browser/RecordList';\r\nimport { RuleFilterChips, applyRuleFilters, type RuleFilters } from '../browser/RuleFilterChips';\r\nimport { FacetBrowseFilter, type FacetBrowseSelection, type FacetBrowseFacet } from '../browser/FacetBrowseFilter';\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 { NewRuleWizard } from './NewRuleWizard';\r\nimport { UnsavedTray } from './UnsavedTray';\r\nimport { HeaderUnsavedPill, canRenderInHeader } from './HeaderUnsavedPill';\r\nimport { SaveAllProgress } from './SaveAllProgress';\r\nimport {\r\n EditorSessionProvider,\r\n useEditorSelection,\r\n useDirtyOverview,\r\n} from '../editor-session';\r\nimport { EditorMountPool } from '../editor-session/EditorMountPool';\r\nimport { useEditorSlotContext } from '../editor-session/useEditorSlotContext';\r\nimport { useShellCsvBulk } from '../hooks/useShellCsvBulk';\r\nimport './tokens.css';\r\nimport './shell.css';\r\n\r\n// ---------------------------------------------------------------------------\r\n// EditorPoolBody — per-slot adapter rendered inside <EditorMountPool>.\r\n//\r\n// Defined at module scope (NOT inside the shell render) so React doesn't\r\n// see a fresh component identity on every shell re-render — that would\r\n// remount the host editor on every keystroke and defeat the pool entirely.\r\n// ---------------------------------------------------------------------------\r\nconst EditorPoolBody = ({\r\n editorId,\r\n renderEditor,\r\n}: {\r\n editorId: string;\r\n renderEditor: (ctx: EditorContext<unknown>) => ReactNode;\r\n}): ReactNode => {\r\n const ctx = useEditorSlotContext<unknown>(editorId);\r\n if (!ctx) return null;\r\n return renderEditor(ctx);\r\n};\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 * Tab order policy (v0.5.1+):\r\n * 1. If the host passes `scopes`, we honour the order they listed\r\n * (filtered to known top-level scopes). Hosts get full control.\r\n * 2. If the host does NOT pass `scopes`, we fall back to the canonical\r\n * order below — `collection` (Global) first because it's the\r\n * simplest mental model for new admins (\"where do records that apply\r\n * to everything live?\"), with `rule`-based targeting as the next\r\n * step up in complexity.\r\n *\r\n * NOTE (v0.5): The legacy `'facet'` scope is no longer surfaced as a\r\n * top-level tab. Hosts that still list it in `scopes` get a one-time\r\n * deprecation warning and the entry is silently dropped. The same admin\r\n * affordance now lives inside the Rules / Global tabs as the\r\n * `FacetBrowseFilter` chip row — see CHANGELOG 0.5.0.\r\n */\r\nconst TOP_LEVEL_SCOPES: ScopeKind[] = ['collection', 'rule', 'product'];\r\n\r\n/** One-time deprecation log gate (module-scoped — fires per page load). */\r\nlet WARNED_FACET_DEPRECATED = false;\r\n\r\n/**\r\n * Sentinel value for `selectedRecordId` while the user is authoring a\r\n * brand-new draft that hasn't been saved yet. Drafts have no UUID until\r\n * the first server round-trip — using a sentinel keeps the selection state\r\n * monomorphic (`string | null`) without inventing a synthetic ref string.\r\n * The shell distinguishes draft kind via `draftKind` state.\r\n */\r\nconst DRAFT_ID = '__draft__';\r\n\r\n/**\r\n * True for any synthetic draft id — either the singleton sentinel\r\n * `__draft__` (used for `selectedRecordId`) or a per-mint `draft:<uuid>`\r\n * value used for collection-item drafts. Hosts must treat both as\r\n * \"unsaved\" (no server round-trip yet) and not display the raw value.\r\n */\r\nconst isDraftId = (id: string | null | undefined): boolean =>\r\n !!id && (id === DRAFT_ID || id.startsWith('draft:'));\r\n\r\n/** Mint a unique synthetic id for a brand-new collection-item draft.\r\n * We avoid the bare `__draft__` sentinel here so multiple drafts in a\r\n * session don't collide and so the literal `__draft__` token never\r\n * surfaces in any host-visible identifier or in `scope.raw`. */\r\nconst mintDraftItemId = (): string => {\r\n const rand = (typeof crypto !== 'undefined' && 'randomUUID' in crypto)\r\n ? crypto.randomUUID()\r\n : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;\r\n return `draft:${rand}`;\r\n};\r\n\r\n/**\r\n * Unsaved collection items must always use a shell-owned synthetic draft id.\r\n * Some hosts provide `generateItemId()` values that look like real UUIDs;\r\n * if we stored those verbatim the resolver would treat a brand-new draft as\r\n * an existing saved record and try to fetch it by id, surfacing the host's\r\n * \"Loading <id>\" placeholder forever. Prefix any host-supplied handle so the\r\n * rest of the shell consistently recognises it as local-only draft state.\r\n */\r\nconst coerceDraftItemId = (generateItemId?: () => string): string => {\r\n const candidate = generateItemId ? generateItemId() : mintDraftItemId();\r\n return isDraftId(candidate) ? candidate : `draft:${candidate}`;\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 // Build the records context once at the outermost level so we can mount\r\n // the EditorSessionProvider before any descendant tries to consume the\r\n // session hooks. The inner component re-derives the same memoised ctx\r\n // for its own data calls — both use the same primitive props so\r\n // referential identity stays stable per (SL, collectionId, appId,\r\n // recordType) tuple.\r\n const ctx = useMemo<RecordsCtx>(\r\n () => ({\r\n SL: props.SL,\r\n collectionId: props.collectionId,\r\n appId: props.appId,\r\n recordType: props.recordType,\r\n }),\r\n [props.SL, props.collectionId, props.appId, props.recordType],\r\n );\r\n return (\r\n <EditorSessionProvider\r\n ctx={ctx}\r\n defaultValueFactory={props.defaultData as (() => unknown) | undefined}\r\n >\r\n <RecordsAdminShellInner {...props} />\r\n </EditorSessionProvider>\r\n );\r\n}\r\n\r\nfunction RecordsAdminShellInner<TData = unknown>(props: RecordsAdminShellProps<TData>) {\r\n const {\r\n SL, appId, collectionId, recordType, label,\r\n scopes: requestedScopes, defaultScope, contextScope,\r\n contextScopeMode = 'strict',\r\n renderEditor, intro, csvSchema,\r\n classify, defaultData, i18n: i18nOverride, onTelemetry, className,\r\n header,\r\n rail,\r\n editor,\r\n items,\r\n unsaved,\r\n clipboard,\r\n actions,\r\n icons: iconsOverride,\r\n // Deep linking\r\n deepLink,\r\n } = props;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Unpack nested config groups into the local variable names the rest of\r\n // the shell body uses. Keeping these names stable means the prop\r\n // regrouping is a one-block API change with no body-wide rewrite.\r\n // ---------------------------------------------------------------------------\r\n const {\r\n show: showHeader,\r\n title,\r\n subtitle,\r\n icon: headerIcon,\r\n showIcon: showHeaderIcon = true,\r\n actions: headerActions,\r\n helpUrl,\r\n helpLabel,\r\n stats: headerStats,\r\n } = header ?? {};\r\n const {\r\n show: showStats = false,\r\n items: statsItems,\r\n title: statsTitle,\r\n icon: statsIcon,\r\n } = headerStats ?? {};\r\n\r\n const {\r\n presentations = ['list'],\r\n defaultPresentation,\r\n renderListRow,\r\n renderEmpty: renderEmptyState,\r\n groupBy,\r\n density = 'comfortable',\r\n } = rail ?? {};\r\n\r\n const {\r\n tabs: editorTabs = 'off',\r\n preview: editorPreview,\r\n } = editor ?? {};\r\n const {\r\n render: renderPreview,\r\n mode: previewMode = 'inline',\r\n scopePicker: previewScopePicker = false,\r\n } = editorPreview ?? {};\r\n\r\n const {\r\n cardinality = 'singleton',\r\n noun: itemNoun = 'item',\r\n generateId: generateItemId,\r\n views: itemViews = ['table'],\r\n defaultView: defaultItemView,\r\n columns: itemColumns,\r\n renderList: renderItemList,\r\n renderCard: renderItemCard,\r\n renderEmpty: renderItemEmpty,\r\n cardSize: itemCardSize = 'md',\r\n railMode: collectionRailMode = 'siblings',\r\n } = items ?? {};\r\n\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 const {\r\n strategy: dirtyStrategy = 'keep',\r\n disableBeforeUnload = false,\r\n onBeforeDelete,\r\n deriveDraftLabel,\r\n } = unsaved ?? {};\r\n\r\n const {\r\n enabled: enableClipboard = true,\r\n onCopy: onCopyOverride,\r\n onPaste: onPasteOverride,\r\n } = clipboard ?? {};\r\n\r\n const {\r\n labels: actionLabels,\r\n icons: actionIcons,\r\n } = actions ?? {};\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\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 const ctx: RecordsCtx = useMemo(\r\n () => ({ SL, collectionId, appId, recordType }),\r\n [SL, collectionId, appId, recordType],\r\n );\r\n\r\n // The shared react-query client — used to prime the resolved-record cache\r\n // from the already-loaded item list so opening an item doesn't flash the\r\n // editor's empty-state while a redundant `getRecordById` round-trips.\r\n const queryClient = useQueryClient();\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.\r\n //\r\n // Order policy:\r\n // • If the host passed `scopes`, render in the order they listed\r\n // (filtered to known top-level scopes — drill-downs like `variant` /\r\n // `batch` are stripped, and the deprecated `facet` is dropped).\r\n // • If the host omitted `scopes` entirely, fall back to the canonical\r\n // `TOP_LEVEL_SCOPES` order (collection → rule → product).\r\n //\r\n // v0.5 — `'facet'` is no longer a top-level tab. If a host still passes\r\n // it we drop it silently (the in-Rules `FacetBrowseFilter` covers the\r\n // same admin need). One deprecation warning per page load.\r\n const topLevelScopes = useMemo(() => {\r\n const requested = requestedScopes ?? [];\r\n if (requested.length > 0) {\r\n const seen = new Set<ScopeKind>();\r\n const ordered: ScopeKind[] = [];\r\n for (const s of requested) {\r\n if (!TOP_LEVEL_SCOPES.includes(s)) continue; // drops 'variant' / 'batch' / 'facet'\r\n if (seen.has(s)) continue;\r\n seen.add(s);\r\n ordered.push(s);\r\n }\r\n return ordered;\r\n }\r\n return [...TOP_LEVEL_SCOPES];\r\n }, [requestedScopes]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // contextScope-aware top-level scopes.\r\n //\r\n // When the host scopes this mount to a single product (`contextScope.productId`)\r\n // and uses the default `'strict'` mode, drop `'collection'` (Global) and\r\n // `'rule'` from the rail — those tabs target collection-wide records the\r\n // product inherits, not records owned by this product. `'expand'` keeps the\r\n // legacy behaviour for hosts that want the full rail anyway.\r\n // ---------------------------------------------------------------------------\r\n const productPinnedFromContext = !!contextScope?.productId;\r\n const effectiveTopLevelScopes = useMemo<ScopeKind[]>(() => {\r\n if (!productPinnedFromContext || contextScopeMode !== 'strict') return topLevelScopes;\r\n return topLevelScopes.filter((s) => s !== 'collection' && s !== 'rule');\r\n }, [productPinnedFromContext, contextScopeMode, topLevelScopes]);\r\n\r\n useEffect(() => {\r\n if (requestedScopes.includes('facet') && !WARNED_FACET_DEPRECATED) {\r\n WARNED_FACET_DEPRECATED = true;\r\n // eslint-disable-next-line no-console\r\n console.warn(\r\n '[RecordsAdminShell] The \"facet\" top-level scope was removed in 0.5.0. ' +\r\n 'Use the Rules tab\\'s built-in \"Browse by facet\" filter instead. ' +\r\n 'Drop \"facet\" (and any `defaultScope: \"facet\"`) from your `scopes` prop.',\r\n );\r\n }\r\n }, [requestedScopes]);\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 && effectiveTopLevelScopes.includes('product')) return 'product';\r\n if (defaultScope && effectiveTopLevelScopes.includes(defaultScope)) return defaultScope;\r\n // Honour the host's listed order: first scope wins. (When the host\r\n // omitted `scopes`, that's the canonical `collection`.)\r\n return effectiveTopLevelScopes[0] ?? 'product';\r\n }, [contextScope?.productId, defaultScope, effectiveTopLevelScopes]);\r\n\r\n // All shell selection state — see useShellSelection. State is owned in\r\n // one place; auto-select effects (which depend on browser data) stay\r\n // inline below, as does the per-item folder-reset effect (which depends\r\n // on the derived `editingScope`).\r\n const selection = useShellSelection({ initialScope, contextScope });\r\n const {\r\n activeScope, setActiveScope,\r\n selectedRecordId, setSelectedRecordId,\r\n draftKind, setDraftKind,\r\n ruleWizardStep, setRuleWizardStep,\r\n ruleWizardRule, setRuleWizardRule,\r\n selectedProductId, setSelectedProductId,\r\n drillTab, setDrillTab,\r\n selectedVariantId, setSelectedVariantId,\r\n selectedBatchId, setSelectedBatchId,\r\n selectedItemId, setSelectedItemId,\r\n skipNextItemResetRef,\r\n } = selection;\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 || !!helpUrl;\r\n return showHeader === true || (showHeader !== false && headerCustomised);\r\n }, [showHeader, title, subtitle, headerIcon, headerActions, showStats, statsItems, statsTitle, statsIcon, helpUrl]);\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 // Browser data + filter state — owned by `useShellBrowser`. This wraps the\r\n // four browse hooks (records / facets / products / product-children) and\r\n // the rail's filter state (search, status, rule filters, facet browse).\r\n // Selection (selectedRecordId / selectedProductId / draftKind / drill tab)\r\n // intentionally still lives in the shell.\r\n // ---------------------------------------------------------------------------\r\n const browser = useShellBrowser({\r\n ctx, SL, collectionId,\r\n activeScope, contextScope,\r\n probeIsLoading: probe.isLoading,\r\n isCollection: cardinality === 'collection',\r\n selectedProductId, drillTab,\r\n classify: classify as ((r: RecordSummary) => RecordStatus) | undefined,\r\n });\r\n const {\r\n search, setSearch,\r\n filter, setFilter,\r\n ruleFilters, setRuleFilters,\r\n facetBrowseFilter, setFacetBrowseFilter,\r\n productBrowse, recordList, facetBrowse,\r\n variantChildren, batchChildren,\r\n } = browser;\r\n\r\n // When the host has pinned a single product (`contextScope.productId`),\r\n // the rail's product browse query is intentionally disabled — fetching\r\n // the whole catalogue would be wasteful when only one product is\r\n // editable. We still need the product's friendly name + SKU for the\r\n // editor header (and the collapsed rail row in expand mode), so resolve\r\n // it via a single GET here.\r\n const pinnedProduct = useSingleProduct({\r\n SL,\r\n collectionId,\r\n productId: contextScope?.productId,\r\n enabled: !!contextScope?.productId,\r\n });\r\n\r\n // Effective product list used for header/label lookups. Merges the\r\n // pinned product into the browse list so downstream consumers don't\r\n // need to know which mode we're in.\r\n const productLookupItems = useMemo<ProductBrowseItem[]>(() => {\r\n if (pinnedProduct.item) return [pinnedProduct.item];\r\n return productBrowse.items;\r\n }, [pinnedProduct.item, productBrowse.items]);\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 // Rule / Global tabs — auto-select the first record so the right pane\r\n // isn't a permanent empty state. New record creation (rule / global /\r\n // item draft) sets the selection explicitly (see `onCreateRule` /\r\n // `onCreateGlobal` below) and bypasses this effect by leaving\r\n // `selectedRecordId === DRAFT_ID`.\r\n useEffect(() => {\r\n if (activeScope !== 'rule' && activeScope !== 'collection') return;\r\n if (selectedRecordId !== null) return; // user already picked / drafted\r\n // Don't auto-pick during the new-rule wizard — it deliberately holds\r\n // selectedRecordId at null while the user configures the rule. Without\r\n // this guard, clicking \"+ New rule\" while a rule is already selected\r\n // briefly clears the selection, fires this effect, and snaps back to\r\n // the first rule before the wizard can render.\r\n if (ruleWizardStep !== null) return;\r\n // Same rationale for in-flight draft kinds (global/item) — the draft\r\n // explicitly sits at selectedRecordId === DRAFT_ID, not null.\r\n if (draftKind !== null) return;\r\n // Collection-cardinality + Global tab: the right pane is the multi-item\r\n // list view (driven by `editingScope` resolving to the collection root),\r\n // not an editor. Leave selection null and let the global-all sentinel\r\n // row drive the rail.\r\n if (activeScope === 'collection' && cardinality === 'collection') {\r\n return;\r\n }\r\n const first = recordList.items[0];\r\n if (first?.id) setSelectedRecordId(first.id);\r\n }, [activeScope, selectedRecordId, recordList.items, cardinality, ruleWizardStep, draftKind]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Build the parsed scope (anchors) for the user's current browse selection.\r\n //\r\n // In singleton mode this also describes the record being edited — the\r\n // resolver walks the inheritance chain to find the winning record and the\r\n // editor saves at this scope. In collection mode this is the *folder*\r\n // that holds items; the actual editing target is the per-item record\r\n // identified by `selectedRecordId` (a UUID, not a ref string).\r\n //\r\n // Source of anchors, by tab:\r\n // - rule / global, saved record selected → anchors from the record's\r\n // summary in `recordList.items`.\r\n // - rule / global, draft (`selectedRecordId === DRAFT_ID`) → empty\r\n // anchors at the collection root (drafts at this level apply globally\r\n // until the user pins them via the Targeting / Applies-to UI).\r\n // - product → drill-down state (selectedProductId, +variant/+batch).\r\n // ---------------------------------------------------------------------------\r\n // Folder + per-item editor anchors. See useEditingScope for the full\r\n // branching table (rule wizard, drafts, saved records, product drill-\r\n // down). Both scopes derive together so the editor's target is always\r\n // consistent with the rail's anchor.\r\n const editingScopes = useEditingScope({\r\n activeScope,\r\n cardinality,\r\n selectedRecordId,\r\n draftKind,\r\n ruleWizardStep,\r\n recordListItems: recordList.items,\r\n selectedProductId,\r\n drillTab,\r\n selectedVariantId,\r\n selectedBatchId,\r\n selectedItemId,\r\n });\r\n const { editingScope, editingTargetScope, isCollection, editingItemRecordId } = editingScopes;\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 // When the editing scope is a rule, items belonging to that rule are\r\n // records carrying the *same* facetRule (anchors are typically empty\r\n // and would otherwise collide with global records). Look up the rule's\r\n // facetRule from the selected record's summary so `useCollectionItems`\r\n // can match by rule equality instead of by anchors.\r\n facetRule: editingScope?.kind === 'rule'\r\n ? (recordList.items.find((it) => it.id === selectedRecordId)?.facetRule ?? null)\r\n : null,\r\n enabled: isCollection,\r\n });\r\n\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 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 // Deep-link round-trip — emit on rail moves + restore on external URL\r\n // changes. See useShellDeepLink for the full URL <-> state mapping.\r\n useShellDeepLink({\r\n deepLinkState,\r\n editingScope,\r\n selectedItemId,\r\n itemView,\r\n itemViews,\r\n setItemView,\r\n activeScope,\r\n setActiveScope,\r\n topLevelScopes,\r\n selectedRecordId,\r\n setSelectedRecordId,\r\n selectedProductId,\r\n setSelectedProductId,\r\n drillTab,\r\n setDrillTab,\r\n selectedVariantId,\r\n setSelectedVariantId,\r\n selectedBatchId,\r\n setSelectedBatchId,\r\n setFacetBrowseFilter,\r\n });\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 // Id-primary path: when the user has selected a saved record by UUID\r\n // (records-driven tabs, deep-link by `?recordId=`), bypass the\r\n // inheritance chain and load that exact row. Drafts (`DRAFT_ID`) and\r\n // pinned-anchor tabs (Products) leave `recordId` undefined so the\r\n // resolver runs `match()` against the anchors above.\r\n //\r\n // In collection-cardinality mode the per-item UUID lives in\r\n // `selectedItemId` (set by the right-pane item list onOpen handler),\r\n // not `selectedRecordId`. Without this branch the resolver would\r\n // fall back to anchor-based `match()` at the collection root and the\r\n // editor would mount against `null` data — surfacing as the host's\r\n // \"Select a {noun} from the list to edit\" placeholder.\r\n recordId:\r\n isCollection && selectedItemId && !isDraftId(selectedItemId)\r\n ? selectedItemId\r\n : (selectedRecordId && !isDraftId(selectedRecordId))\r\n ? selectedRecordId\r\n : undefined,\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 // Editor session — see useShellEditorTarget for the EditorTargetSpec\r\n // construction (draft/createMode/ref handling) and bridge wiring.\r\n const { editorTargetSpec, editorCtx } = useShellEditorTarget<TData>({\r\n editingTargetScope,\r\n isCollection,\r\n selectedItemId,\r\n activeScope,\r\n draftKind,\r\n ruleWizardStep,\r\n ruleWizardRule,\r\n resolved: {\r\n data: resolved.data,\r\n source: resolved.source,\r\n sourceRef: resolved.sourceRef,\r\n recordId: resolved.recordId,\r\n parentValue: resolved.parentValue,\r\n facetRule: resolved.facetRule,\r\n },\r\n defaultData,\r\n deriveDraftLabel,\r\n onSaved: (isCreate) => {\r\n onTelemetry?.({ type: 'record.save', recordType, ref: editingTargetScope?.raw ?? '', isCreate });\r\n // First save inside the new-rule wizard tears it down: the rule\r\n // now exists as a real record (singleton) or as the targeting on\r\n // the just-saved first item (collection).\r\n if (ruleWizardStep !== null) {\r\n setRuleWizardStep(null);\r\n setRuleWizardRule(null);\r\n setDraftKind(null);\r\n }\r\n refetchAll();\r\n },\r\n onDeleted: () => {\r\n onTelemetry?.({ type: 'record.delete', recordType, ref: editingTargetScope?.raw ?? '' });\r\n if (isCollection && selectedItemId) {\r\n setSelectedItemId(null);\r\n } else if (drillTab === 'variant') {\r\n setSelectedVariantId(undefined);\r\n } else if (drillTab === 'batch') {\r\n setSelectedBatchId(undefined);\r\n }\r\n refetchAll();\r\n },\r\n });\r\n\r\n // ---------------------------------------------------------------------------\r\n // Unsaved guards — browser beforeunload + iframe parent message + nav guard\r\n // ---------------------------------------------------------------------------\r\n useUnsavedGuard({\r\n isDirty: editorCtx.isDirty,\r\n label: recordType,\r\n disableBeforeUnload,\r\n // In `keep` mode we don't want the host iframe to pop its own native\r\n // confirm — the banner is the canonical surface. Hosts on `prompt` /\r\n // `autosave` opt back into platform notifications.\r\n disableParentMessage: dirtyStrategy === 'keep',\r\n });\r\n\r\n // Themed confirm dialog used for in-app navigation away from a dirty editor.\r\n // Replaces window.confirm() so we don't get the host iframe's \"An embedded\r\n // page at … says\" framing and so the popup matches the shell chrome.\r\n const dirtyConfirm = useConfirmDialog();\r\n\r\n // ---------------------------------------------------------------------------\r\n // Shell-level dirty-draft registry — drives the multi-record \"N unsaved •\r\n // Save all\" tray and the sequential save-all progress overlay. The active\r\n // editor registers/clears its draft via `useRecordEditor`; the shell only\r\n // *reads* the store here for tray rendering and Save-all orchestration.\r\n // ---------------------------------------------------------------------------\r\n const dirtyOverview = useDirtyOverview();\r\n const editorSelection = useEditorSelection();\r\n const dirtyItems = dirtyOverview.items;\r\n // dirtyKeys / errorKeys are still consumed by SiblingRail + RecordList to\r\n // mark rows. They expect a Set of recordIds OR scope.raw fragments — we\r\n // emit both so the sidebar matches whether a row knows its recordId yet\r\n // or only its scope ref.\r\n const dirtyKeys = useMemo<Set<string>>(() => {\r\n const s = new Set<string>();\r\n for (const it of dirtyItems) {\r\n if (it.status === 'saved') continue;\r\n if (it.recordId) s.add(it.recordId);\r\n if (it.scope?.raw) s.add(it.scope.raw);\r\n }\r\n return s;\r\n }, [dirtyItems]);\r\n const errorKeys = useMemo<Set<string>>(() => {\r\n const s = new Set<string>();\r\n for (const it of dirtyItems) {\r\n if (it.status !== 'error') continue;\r\n if (it.recordId) s.add(it.recordId);\r\n if (it.scope?.raw) s.add(it.scope.raw);\r\n }\r\n return s;\r\n }, [dirtyItems]);\r\n const [saveAllOpen, setSaveAllOpen] = useState(false);\r\n\r\n // Shared handlers used by both the header pill and the (overflow) tray\r\n // so the two surfaces stay behaviourally identical.\r\n const handleSaveAll = () => setSaveAllOpen(true);\r\n const handleDiscardAll = () => {\r\n // Single source of truth: the EditorStore. discardAll resets every\r\n // dirty/errored editor back to its baseline. The active editor's\r\n // visible value flips back automatically because it reads from the\r\n // store. No separate clearAll() needed — clean editors aren't pinned\r\n // and will fall out of the LRU pool as new selections arrive.\r\n dirtyOverview.discardAll();\r\n };\r\n\r\n // The shell decides between two surfaces for unsaved controls:\r\n // • inline pill in AdminPageHeader.actions — the common case\r\n // • full-width UnsavedTray banner — overflow (5+ drafts or any error)\r\n // Computed once here so the header render and the tray render agree.\r\n const showHeaderUnsavedPill =\r\n dirtyStrategy === 'keep' && canRenderInHeader(dirtyItems);\r\n const showTrayBanner =\r\n dirtyStrategy === 'keep'\r\n && !showHeaderUnsavedPill\r\n && dirtyItems.length > 0;\r\n\r\n // Compose the header `actions` slot: pill (when shown) + whatever the host\r\n // passed. The pill renders to the left so it stays adjacent to the page\r\n // title, with host actions (e.g. \"+ New\") to its right.\r\n const composedHeaderActions = useMemo(() => {\r\n if (!showHeaderUnsavedPill) return headerActions;\r\n return (\r\n <>\r\n <HeaderUnsavedPill\r\n items={dirtyItems}\r\n isSaving={saveAllOpen}\r\n onSaveAll={handleSaveAll}\r\n onDiscardAll={handleDiscardAll}\r\n saveLabel={actionLabels?.save ?? i18n.save}\r\n discardLabel={actionLabels?.discard ?? i18n.discard}\r\n saveAllLabel={actionLabels?.saveAll ?? i18n.saveAll}\r\n discardAllLabel={actionLabels?.revertAll ?? i18n.discardAll}\r\n countTemplate={i18n.unsavedTrayCount}\r\n SaveIcon={actionIcons?.save}\r\n DiscardIcon={actionIcons?.discard}\r\n />\r\n {headerActions}\r\n </>\r\n );\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n showHeaderUnsavedPill, headerActions, dirtyItems, saveAllOpen,\r\n actionLabels, actionIcons, i18n,\r\n ]);\r\n\r\n // The rail's onLeftSelect (used by row-paste to focus the destination\r\n // before the deferred paste runs) is defined further down — capture\r\n // the latest reference via a ref so the clipboard hook can call it.\r\n const onLeftSelectRef = useRef<((item: RecordSummary) => void) | 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 // CSV import/export — extracted into useShellCsvBulk.\r\n const csvBulk = useShellCsvBulk<TData>({\r\n csvSchema,\r\n recordType,\r\n label,\r\n items: recordList.items as RecordSummary<TData>[],\r\n ctx,\r\n refetchAll,\r\n onTelemetry,\r\n });\r\n\r\n // ---------------------------------------------------------------------------\r\n // Preview state — independent scope (when picker enabled) + drawer toggle.\r\n // ---------------------------------------------------------------------------\r\n const {\r\n previewScope, setPreviewScope, effectivePreviewScope,\r\n drawerOpen, setDrawerOpen,\r\n sidePreviewOpen, setSidePreviewOpen,\r\n editorHeaderLabel, editorHeaderSubtitle, editorHeaderMeta,\r\n } = useShellPreviewPane({\r\n editingScope,\r\n activeScope,\r\n selectedProductId,\r\n productBrowseItems: productLookupItems,\r\n });\r\n // `previewScope` is read by the render path's preview pane; reference it\r\n // here so the destructure isn't seen as unused by linters in shell builds\r\n // that strip the preview branch.\r\n void previewScope;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Clipboard — Copy / Paste across scopes for this `recordType`.\r\n // Owned by the dedicated useShellClipboard hook (see hooks/useShellClipboard.tsx)\r\n // which encapsulates the underlying store, paste-confirm dialog, deferred\r\n // row-paste effect, and toast notice state.\r\n // ---------------------------------------------------------------------------\r\n const shellClipboard = useShellClipboard<TData>({\r\n enabled: !!enableClipboard,\r\n appId,\r\n recordType,\r\n i18n,\r\n editorCtx,\r\n editingScope,\r\n editorHeaderLabel,\r\n isCollection,\r\n selectedItemId,\r\n selectedRecordId,\r\n resolved: { source: resolved.source, recordId: resolved.recordId },\r\n onTelemetry,\r\n onCopyOverride,\r\n onPasteOverride,\r\n onLeftSelectRef,\r\n });\r\n const editorClipboard = shellClipboard.editorClipboard;\r\n const rowClipboard = shellClipboard.rowClipboard;\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 const {\r\n onItemOpen, onItemCreate, onItemDelete,\r\n onItemBack, onItemPrev, onItemNext,\r\n itemPosition, itemViewCtx, buildItemUrlValue,\r\n } = useShellNavigation<TData>({\r\n isCollection,\r\n runWithGuard,\r\n selectedItemId,\r\n setSelectedItemId,\r\n editingScope,\r\n baseScopeRef,\r\n collectionItems,\r\n queryClient,\r\n ctx,\r\n collectionId,\r\n appId,\r\n recordType,\r\n deepLinkState,\r\n onTelemetry,\r\n onBeforeDelete,\r\n generateItemId,\r\n });\r\n // `onItemDelete` is consumed inside `itemViewCtx`; `buildItemUrlValue`\r\n // is no longer referenced from the shell render path but kept exported\r\n // for parity with prior versions / hosts that may rely on the URL shape.\r\n void onItemDelete; void buildItemUrlValue;\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 // Hide the item nav during the new-rule wizard — there is no saved\r\n // sibling list yet, so \"1 / N\" and prev/next would point at unrelated\r\n // items from the collection root.\r\n const itemNav = isCollection && selectedItemId && itemPosition && ruleWizardStep === null ? (\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 <EditorMountPool\r\n renderSlot={(slotId) => (\r\n <EditorPoolBody\r\n editorId={slotId}\r\n renderEditor={renderEditor as (ctx: EditorContext<unknown>) => ReactNode}\r\n />\r\n )}\r\n fallback={renderEditor(editorCtx)}\r\n />\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 // ---------------------------------------------------------------------------\r\n // Single-record collapse: when the host has scoped this mount to one product\r\n // (`contextScope.productId`) AND there's no variant/batch drill-down to\r\n // pick AND we've stripped the collection-wide tabs, the rail has nothing\r\n // to navigate. Hide it so the editor takes the whole pane. The host gets a\r\n // clean single-editor experience without having to configure anything.\r\n //\r\n // Caveat: in collection cardinality (FAQs / SOPs / recipes) the rail is\r\n // the *items* list under that product — keep it visible so users can pick\r\n // between items.\r\n // ---------------------------------------------------------------------------\r\n const railHidden = useMemo(() => {\r\n if (!productPinned) return false;\r\n if (contextScopeMode !== 'strict') return false;\r\n if (cardinality === 'collection') return false;\r\n // Pinned-singleton mode is \"edit one record\". The rail has nothing\r\n // useful to show — the only product is already implicit in the\r\n // header, the Global / Rules tabs were stripped above, and any\r\n // variant/batch drill-down would change scope away from the pinned\r\n // product (admins can pin a variantId / batchId via `contextScope`\r\n // explicitly if they want to edit those instead). Collapse to a\r\n // full-width editor.\r\n return true;\r\n }, [\r\n productPinned, contextScopeMode, cardinality,\r\n ]);\r\n\r\n // Records-driven tabs (rule, global) render a flat list — cards/grids\r\n // don't add value when each row is a record selector. Force `list` and\r\n // hide the presentation switcher unless we're on the products tab.\r\n const effectivePresentation: RecordPresentation = isProductTab ? presentation : 'list';\r\n const showPresentationSwitcher = isProductTab && presentations.length > 1;\r\n\r\n // Records-driven tabs no longer auto-group by facet — the legacy facet\r\n // rail is gone. Hosts that want grouping (e.g. by `category`) can still\r\n // pass `groupBy` directly.\r\n const effectiveGroupBy = groupBy;\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\r\n // context. Prefer the resolved product name (fetched via\r\n // `useSingleProduct`) over the raw productId so the rail row reads\r\n // like a real product entry rather than an opaque key.\r\n const pid = contextScope!.productId!;\r\n return [{\r\n id: null, ref: buildRef({ productId: pid }),\r\n scope: parseRef(buildRef({ productId: pid })),\r\n data: null, status: 'empty',\r\n label: pinnedProduct.item?.name ?? pid,\r\n subtitle: pinnedProduct.item?.sku ?? undefined,\r\n }];\r\n }\r\n return productBrowse.items.map(productItemToSummary);\r\n }, [productPinned, contextScope, productBrowse.items, pinnedProduct.item]);\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 // Open the two-step inline wizard. We deliberately do NOT mount the\r\n // editor yet — the rail / collection-root item list would otherwise\r\n // surface and confuse the admin (they asked for \"new rule\", not\r\n // \"edit existing global record\"). The editor is composed on Step 2\r\n // once the rule has been configured.\r\n if (activeScope !== 'rule') setActiveScope('rule');\r\n setSelectedRecordId(null);\r\n setSelectedItemId(null);\r\n setDraftKind('rule');\r\n setRuleWizardRule({ all: [] });\r\n setRuleWizardStep(1);\r\n });\r\n }, [runWithGuard, activeScope]);\r\n\r\n const onCancelRuleWizard = useCallback(() => {\r\n setRuleWizardStep(null);\r\n setRuleWizardRule(null);\r\n setSelectedRecordId(null);\r\n setSelectedItemId(null);\r\n setDraftKind(null);\r\n }, []);\r\n\r\n const onRuleWizardNext = useCallback(() => {\r\n // Step 1 → Step 2. In singleton mode we mount the editor against the\r\n // synthetic rule draft scope. In collection mode we keep the right\r\n // pane on the wizard's \"create your first item\" CTA — the user clicks\r\n // it to open an item draft.\r\n if (cardinality === 'collection') {\r\n setRuleWizardStep(2);\r\n // Stay with selectedRecordId === null so the right pane defers to\r\n // the wizard rather than the item list.\r\n } else {\r\n setRuleWizardStep(2);\r\n setSelectedRecordId(DRAFT_ID);\r\n }\r\n }, [cardinality]);\r\n\r\n const onRuleWizardBack = useCallback(() => {\r\n setRuleWizardStep(1);\r\n setSelectedRecordId(null);\r\n setSelectedItemId(null);\r\n }, []);\r\n\r\n const onRuleWizardCreateItem = useCallback(() => {\r\n // Collection mode only: open an item draft under the new rule. The\r\n // wizard rule is seeded into the editor's `initialFacetRule` so the\r\n // first save carries the rule onto the item record.\r\n if (!isCollection) return;\r\n const id = coerceDraftItemId(generateItemId);\r\n setSelectedItemId(id);\r\n }, [isCollection, generateItemId]);\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 [recordList.items],\r\n );\r\n // The \"+ New global default\" CTA only makes sense in singleton mode — there\r\n // can be at most one record at the collection root, and it acts as the\r\n // inherited default. In collection-cardinality mode (recipes / SOPs / FAQs)\r\n // there is no notion of \"the global default\": the Global tab is just the\r\n // bucket of items saved at the collection root, so the CTA would be\r\n // misleading. The right pane's `+ New {item}` button covers item creation.\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 // Global default draft — collection root, no facetRule, no anchors.\r\n setSelectedRecordId(DRAFT_ID);\r\n setDraftKind('global');\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 // Apply the shared \"Browse by facet\" filter on top of either tab's list.\r\n // For rule records we inspect the saved `facetRule` and keep rules whose\r\n // clauses would match the picked facet/value (clause facetKey matches AND\r\n // anyOf includes the value). For pinned-scope records on the Global tab\r\n // (singleton mode) we match by the record's own scope. Records that\r\n // can't be evaluated (no rule, no scope) drop out — they wouldn't apply\r\n // to a product carrying the picked facet either.\r\n const applyFacetBrowseFilter = useCallback(\r\n (items: RecordSummary[]): RecordSummary[] => {\r\n if (!facetBrowseFilter) return items;\r\n const { facetKey, facetValue } = facetBrowseFilter;\r\n return items.filter((r) => {\r\n const rule = (r as { facetRule?: { all?: { facetKey: string; anyOf: string[] }[] } | null }).facetRule;\r\n if (rule?.all?.length) {\r\n return rule.all.some((c) => c.facetKey === facetKey && (c.anyOf ?? []).includes(facetValue));\r\n }\r\n // Fallback: match pinned-scope records by their own facet.\r\n if (r.scope.facetId === facetKey && r.scope.facetValue === facetValue) return true;\r\n return false;\r\n });\r\n },\r\n [facetBrowseFilter],\r\n );\r\n\r\n // Build the facet vocabulary in the shape FacetBrowseFilter expects. We\r\n // rely on `useFacetBrowse`'s mergedItems for the list of values per facet —\r\n // each row is a `{facet}:{value}` pair, so we group by `subtitle` (facet\r\n // name). Order is whatever the facets API returned.\r\n const facetBrowseFacets: FacetBrowseFacet[] = useMemo(() => {\r\n if (!facetBrowse.items.length) return [];\r\n const byKey = new Map<string, FacetBrowseFacet>();\r\n for (const it of facetBrowse.items) {\r\n const key = it.scope.facetId;\r\n const value = it.scope.facetValue;\r\n if (!key || !value) continue;\r\n const facetLabel = it.subtitle ?? key;\r\n const valueLabel = it.label ?? value;\r\n const existing = byKey.get(key);\r\n if (existing) {\r\n if (!existing.values.some((v) => v.key === value)) {\r\n existing.values.push({ key: value, label: valueLabel });\r\n }\r\n } else {\r\n byKey.set(key, { key, label: facetLabel, values: [{ key: value, label: valueLabel }] });\r\n }\r\n }\r\n return Array.from(byKey.values());\r\n }, [facetBrowse.items]);\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 // Collection-cardinality + Global tab: the rail has no records to show\r\n // (item-level records belong on the right). Without a `groupBy` callback,\r\n // surface a single auto-selected \"All items\" row so the rail isn't a\r\n // confusing empty pane. With `groupBy`, hosts can later light up category\r\n // grouping from the right-pane items; today we still render an All row so\r\n // there's always something selected.\r\n const collectionGlobalAllRow: RecordSummary = useMemo(\r\n () => ({\r\n id: null,\r\n ref: '',\r\n scope: parseRef(''),\r\n data: null,\r\n status: 'empty',\r\n label: i18n.itemsAllLabel,\r\n subtitle: collectionItems.items.length\r\n ? `${collectionItems.items.length} ${itemNoun}${collectionItems.items.length === 1 ? '' : 's'}`\r\n : undefined,\r\n }),\r\n [i18n.itemsAllLabel, collectionItems.items.length, itemNoun],\r\n );\r\n\r\n const leftItems = isProductTab\r\n ? productListItems\r\n : isRuleTab\r\n ? applyFacetBrowseFilter(filteredRuleItems)\r\n : isGlobalTab && isCollection\r\n ? [collectionGlobalAllRow]\r\n : isRecordsTab\r\n ? applyFacetBrowseFilter(recordList.items)\r\n : [];\r\n const leftLoading = isProductTab\r\n ? (!productPinned && productBrowse.isLoading)\r\n : isRecordsTab\r\n ? (recordList.isLoading || probe.isLoading)\r\n : false;\r\n const leftError = isProductTab\r\n ? productBrowse.error\r\n : isRecordsTab\r\n ? recordList.error\r\n : null;\r\n // RecordList highlights the active row two ways:\r\n // - Records-driven tabs: by UUID (`selectedId` matches `RecordSummary.id`).\r\n // - Pinned-anchor tabs (Products today; Facets when added): by anchor key\r\n // (`selectedAnchorKey` matches `RecordSummary.ref`, a synthesised\r\n // display-only string). We don't have a UUID for \"the selected\r\n // product\" — products aren't AppRecords.\r\n const leftSelectedId = isProductTab\r\n ? undefined\r\n : (selectedRecordId && selectedRecordId !== DRAFT_ID ? selectedRecordId : undefined);\r\n const leftSelectedAnchorKey = isProductTab\r\n ? (selectedProductId ? buildRef({ productId: selectedProductId }) : undefined)\r\n : undefined;\r\n // Dirty-row indicator. For records-driven tabs this is the editor's\r\n // current record UUID. For product/facet tabs the editor edits an anchor,\r\n // so we fall back to anchor matching via `editingScope.raw`.\r\n const dirtyId = !editorCtx.isDirty\r\n ? undefined\r\n : (selectedRecordId && selectedRecordId !== DRAFT_ID ? selectedRecordId : undefined);\r\n const dirtyAnchorKey = !editorCtx.isDirty\r\n ? undefined\r\n : (isProductTab ? editingScope?.raw : undefined);\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 // Records-driven tabs — select by UUID. Drafts are cleared because\r\n // clicking a saved row is an explicit \"open this one instead\".\r\n setSelectedRecordId(item.id ?? null);\r\n setDraftKind(null);\r\n // Selecting an existing rule cancels an in-flight new-rule wizard.\r\n if (ruleWizardStep !== null) {\r\n setRuleWizardStep(null);\r\n setRuleWizardRule(null);\r\n }\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 {shellClipboard.confirmDialog}\r\n {shellClipboard.toast}\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 {/* When the header is rendering and the host opted into the inline\r\n * `'header'` reopen affordance, AdminPageHeader owns the intro card\r\n * (renders it directly under the title row). Otherwise the shell\r\n * renders the intro itself above the rail/editor split. */}\r\n {intro && !dismissed && !(headerWillRender && resolvedReopenAffordance === 'header') && (\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 reopenLabel = intro?.reopenLabel ?? `How ${label.toLowerCase()} works`;\r\n // Hand the intro to AdminPageHeader only when the host wants the\r\n // `'header'` affordance — that way it renders the dismissible card\r\n // inline under the title and the `?` reopen button to the right.\r\n const headerIntro = (intro && resolvedReopenAffordance === 'header') ? {\r\n title: intro.title,\r\n body: intro.body,\r\n dismissed,\r\n onDismiss: () => { dismiss(); onTelemetry?.({ type: 'intro.dismiss', recordType }); },\r\n onReopen: undismiss,\r\n reopenLabel,\r\n } : undefined;\r\n return (\r\n <ShellHeader\r\n title={title ?? label ?? recordType ?? ''}\r\n subtitle={subtitle}\r\n headerIcon={headerIcon}\r\n headerActions={composedHeaderActions}\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 helpUrl={helpUrl}\r\n helpLabel={helpLabel}\r\n intro={headerIntro}\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 {showTrayBanner && (\r\n <UnsavedTray\r\n items={dirtyItems}\r\n isSaving={saveAllOpen}\r\n onSaveAll={handleSaveAll}\r\n onDiscardAll={handleDiscardAll}\r\n onOpenItem={(it) => {\r\n // Selecting an item from the tray focuses the editor in the\r\n // pool (no remount) and jumps the rail to its record when\r\n // we already know the recordId.\r\n editorSelection.focus(it.editorId);\r\n if (it.recordId) {\r\n setSelectedRecordId(it.recordId);\r\n setDraftKind(null);\r\n }\r\n }}\r\n onJumpToError={() => {\r\n const first = dirtyItems.find((it) => it.status === 'error');\r\n if (!first) return;\r\n editorSelection.focus(first.editorId);\r\n if (first.recordId) {\r\n setSelectedRecordId(first.recordId);\r\n setDraftKind(null);\r\n }\r\n }}\r\n saveLabel={actionLabels?.save ?? i18n.save}\r\n discardLabel={actionLabels?.discard ?? i18n.discard}\r\n saveAllLabel={actionLabels?.saveAll ?? i18n.saveAll}\r\n discardAllLabel={actionLabels?.revertAll ?? i18n.discardAll}\r\n countTemplate={i18n.unsavedTrayCount}\r\n errorCountTemplate={i18n.unsavedTrayErrors}\r\n jumpToErrorLabel={i18n.saveAllJumpToError}\r\n SaveIcon={actionIcons?.save}\r\n DiscardIcon={actionIcons?.discard}\r\n />\r\n )}\r\n <SaveAllProgress\r\n open={saveAllOpen}\r\n items={dirtyItems}\r\n saveOne={dirtyOverview.saveOne}\r\n onClose={() => setSaveAllOpen(false)}\r\n onJumpToError={(it) => {\r\n editorSelection.focus(it.editorId);\r\n if (it.recordId) {\r\n setSelectedRecordId(it.recordId);\r\n setDraftKind(null);\r\n }\r\n }}\r\n i18n={{\r\n title: i18n.saveAllInProgress,\r\n successTitle: i18n.saveAllSuccess,\r\n errorTitle: i18n.saveAllErrorTitle,\r\n stop: i18n.saveAllStop,\r\n close: i18n.saveAllClose,\r\n retryFailed: i18n.saveAllRetryFailed,\r\n jumpToError: i18n.saveAllJumpToError,\r\n }}\r\n />\r\n </div>\r\n <div\r\n className=\"flex-1 grid border-t overflow-hidden\"\r\n style={{\r\n gridTemplateColumns: railHidden ? '1fr' : 'minmax(260px, 320px) 1fr',\r\n borderColor: 'hsl(var(--ra-border))',\r\n }}\r\n >\r\n {!railHidden && (\r\n <aside className=\"border-r overflow-hidden flex flex-col\" style={{ borderColor: 'hsl(var(--ra-border))', background: 'hsl(var(--ra-surface))' }}>\r\n {/* Sibling rail mounts only outside the new-rule wizard. While the\r\n wizard is active there is no saved rule yet, so the items\r\n fetched against the placeholder rule scope fall back to the\r\n collection root and would surface unrelated rows in the rail. */}\r\n {isCollection && selectedItemId && collectionRailMode === 'siblings' && ruleWizardStep === null ? (\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 dirtyKeys={dirtyKeys}\r\n errorKeys={errorKeys}\r\n i18n={i18n}\r\n />\r\n ) : (\r\n <>\r\n <div className=\"p-2\">\r\n <ScopeTabs\r\n scopes={effectiveTopLevelScopes}\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 // Switching tabs cancels an in-flight new-rule wizard so\r\n // the user doesn't lose the unsaved rule silently.\r\n if (ruleWizardStep !== null) {\r\n setRuleWizardStep(null);\r\n setRuleWizardRule(null);\r\n setDraftKind(null);\r\n }\r\n setActiveScope(s);\r\n });\r\n }}\r\n loading={probe.isLoading}\r\n counts={{\r\n product: productBrowse.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 {/* Singleton-mode Global is a one-record tab — there is at most\r\n one row to show and \"search / browse by facet / no records\r\n yet\" all read as noise. Suppress the rail's search,\r\n presentation switcher, filter chips, browse-by-facet, and\r\n empty state. The \"+ New global default\" CTA above (when the\r\n record doesn't yet exist) plus the right pane carry the\r\n whole flow. */}\r\n {!(isGlobalTab && !isCollection) && (\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 {/* Status filter pills (Configured / Empty) describe facet-value\r\n coverage — the share of facet values that have a saved record.\r\n That story only lands on the facet rail in singleton mode. On\r\n the Rule and Global tabs the rail rows ARE records, so\r\n everything is \"configured\" by definition; in collection-\r\n cardinality mode the rail isn't records-driven at all. Hide in\r\n those cases to avoid meaningless 1/0 counters. */}\r\n {!isProductTab && !isRuleTab && !isGlobalTab && (\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 {/* Browse-by-facet filter — replaces the legacy \"Shared\" tab.\r\n Surfaced on Rules so admins can ask \"what would apply if a\r\n product had bagel = white?\". Hidden on Global in either\r\n cardinality mode: singleton-Global has at most one record\r\n (filtering is meaningless), and collection-Global rail is\r\n the synthetic All-items row. */}\r\n {isRuleTab && (\r\n <FacetBrowseFilter\r\n facets={facetBrowseFacets}\r\n value={facetBrowseFilter}\r\n onChange={setFacetBrowseFilter}\r\n isLoading={facetBrowse.isLoading}\r\n />\r\n )}\r\n {/* Collection-mode \"+ New\" lives in the right-pane toolbar now. */}\r\n </>\r\n )}\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto\">\r\n {/* Singleton-Global: skip the rail body entirely. The right\r\n pane shows either the editor (record exists) or an inert\r\n helper state matching the \"+ New global default\" CTA above. */}\r\n {isGlobalTab && !isCollection ? null : (\r\n <>\r\n {leftLoading && <LoadingState />}\r\n {!leftLoading && leftError && <ErrorState error={leftError} />}\r\n {!leftLoading && !leftError && leftItems.length === 0 && (\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 selectedId={leftSelectedId}\r\n selectedAnchorKey={leftSelectedAnchorKey}\r\n onSelect={onLeftSelect}\r\n dirtyId={dirtyId}\r\n dirtyAnchorKey={dirtyAnchorKey}\r\n dirtyKeys={dirtyKeys}\r\n errorKeys={errorKeys}\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 i18n={i18n}\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 </>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </aside>\r\n )}\r\n <main className=\"overflow-hidden\">\r\n {/* New-rule wizard takes over the right pane while active. */}\r\n {ruleWizardStep !== null && (\r\n <NewRuleWizard\r\n SL={SL}\r\n collectionId={collectionId}\r\n appId={appId}\r\n step={ruleWizardStep}\r\n rule={ruleWizardRule}\r\n onRuleChange={setRuleWizardRule}\r\n onCancel={onCancelRuleWizard}\r\n onNext={onRuleWizardNext}\r\n onBack={onRuleWizardBack}\r\n itemNoun={itemNoun}\r\n >\r\n {/* Step 2 body — singleton mode mounts the editor; collection\r\n mode shows the empty state until the user clicks \"Create\r\n your first item\". Once an item draft is open we mount the\r\n editor so the user can author the first item. */}\r\n {ruleWizardStep === 2 && !isCollection && editingTargetScope && renderEditorWithPreview()}\r\n {ruleWizardStep === 2 && isCollection && !selectedItemId && (\r\n <div className=\"h-full flex items-center justify-center px-6 py-10\">\r\n <div className=\"max-w-sm text-center space-y-3\">\r\n <h3\r\n className=\"text-base font-semibold m-0\"\r\n style={{ color: 'hsl(var(--ra-text))' }}\r\n >\r\n Create your first {itemNoun} for this rule\r\n </h3>\r\n <p\r\n className=\"text-sm m-0\"\r\n style={{ color: 'hsl(var(--ra-muted-text))' }}\r\n >\r\n The rule is set up. Now add the first {itemNoun} that should apply to every product matching it. You can add more later.\r\n </p>\r\n <button\r\n type=\"button\"\r\n onClick={onRuleWizardCreateItem}\r\n className=\"ra-btn\"\r\n data-variant=\"primary\"\r\n >\r\n <Plus aria-hidden=\"true\" className=\"w-4 h-4\" />\r\n <span>Create first {itemNoun}</span>\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n {ruleWizardStep === 2 && isCollection && !!selectedItemId && editingTargetScope && renderEditorWithPreview()}\r\n </NewRuleWizard>\r\n )}\r\n {/* Collection mode: scope selected, no item open → item list view. */}\r\n {ruleWizardStep === null && 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 cardSize={itemCardSize}\r\n i18n={i18n}\r\n />\r\n )}\r\n {ruleWizardStep === null && !isCollection && !editingScope && activeScope === 'product' && !selectedProductId && (\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 {ruleWizardStep === null && 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 {ruleWizardStep === null && !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 /** UUID of the highlighted row (matches `RecordSummary.id`). */\r\n selectedId?: 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 selectedId, 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} selectedId={selectedId} 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, hasError, 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 {hasError ? (\r\n <span\r\n title=\"Save failed\"\r\n aria-label=\"Save failed\"\r\n className=\"ra-error-pip absolute top-1.5 right-1.5\"\r\n />\r\n ) : isDirty && (\r\n <span\r\n title=\"Unsaved changes\"\r\n aria-label=\"Unsaved changes\"\r\n className=\"ra-status-dot ra-status-shared 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// useDirtyDraftStore — shell-level registry of unsaved record drafts.\r\n//\r\n// The single-record `useRecordEditor` only tracks dirtiness for the editor\r\n// that's currently mounted. As soon as the user clicks a different record\r\n// in the rail (in `keep` mode), the previous editor unmounts and its dirty\r\n// state would be lost. This store persists each draft in memory keyed by a\r\n// stable record key so the shell can:\r\n//\r\n// • show \"N records have unsaved changes • Save all\"\r\n// • re-seed the editor with the in-flight value when the user navigates\r\n// back to a previously-edited record\r\n// • run a sequential Save-all pass with per-record progress + errors\r\n//\r\n// In-memory only — does not persist across page reloads. Future iteration\r\n// can layer sessionStorage on top behind a flag.\r\n// =============================================================================\r\nimport {\r\n createContext, useCallback, useContext, useMemo, useRef,\r\n useSyncExternalStore, type ReactNode,\r\n} from 'react';\r\nimport type { FacetRule } from '../data/sdkTypes';\r\nimport type { RecordAnchors } from '../data/scopeBridge';\r\n\r\nexport type DirtyDraftStatus = 'dirty' | 'saving' | 'saved' | 'error';\r\n\r\nexport interface DirtyDraft {\r\n /** Stable key — recordId for saved rows, `draft:{kind}:{scope.raw}` otherwise. */\r\n key: string;\r\n /** Friendly label for the tray + per-record progress rows. */\r\n label: string;\r\n /** Optional secondary descriptor (e.g. scope kind / facet). */\r\n context?: string;\r\n /** ParsedRef.raw — used to re-select the record from the tray. */\r\n scopeRaw: string;\r\n /** When set, selecting this draft from the tray loads a saved row by id. */\r\n recordId?: string;\r\n /** Insertion order — drives the visual order in the tray + overlay. */\r\n order: number;\r\n /** Current value being edited. */\r\n value: unknown;\r\n /** Optional facet rule attached to the value. */\r\n facetRule: FacetRule | null;\r\n /** Last-saved baseline for the same record (for diff/discard). */\r\n baseline: unknown;\r\n baselineFacetRule: FacetRule | null;\r\n /** Whether this draft must be inserted (collection-cardinality items). */\r\n createMode: boolean;\r\n /** Anchor IDs for the save call. */\r\n scopeAnchors: RecordAnchors;\r\n /** Optional external ref (rule:{id}) to send with the save. */\r\n ref?: string;\r\n /** Save kind decided at draft creation time. */\r\n saveKind: 'update' | 'create' | 'upsert';\r\n status: DirtyDraftStatus;\r\n error?: unknown;\r\n /**\r\n * Performs the save against the SDK. Captured at draft creation time so\r\n * the overlay doesn't need access to the editor's resolver/ctx — keeps\r\n * the registry self-contained.\r\n */\r\n save: () => Promise<void>;\r\n}\r\n\r\ntype Listener = () => void;\r\n\r\nexport interface DirtyDraftStore {\r\n list(): DirtyDraft[];\r\n get(key: string): DirtyDraft | undefined;\r\n has(key: string): boolean;\r\n upsertDraft(input: Omit<DirtyDraft, 'order' | 'status'> & { order?: number; status?: DirtyDraftStatus }): void;\r\n setStatus(key: string, status: DirtyDraftStatus, error?: unknown): void;\r\n clearDraft(key: string): void;\r\n clearAll(): void;\r\n subscribe(listener: Listener): () => void;\r\n}\r\n\r\nconst createStore = (): DirtyDraftStore => {\r\n const map = new Map<string, DirtyDraft>();\r\n const listeners = new Set<Listener>();\r\n let nextOrder = 0;\r\n // Cached snapshot — useSyncExternalStore requires getSnapshot to return a\r\n // stable reference between mutations, otherwise React loops forever.\r\n let cachedList: DirtyDraft[] = [];\r\n const recompute = () => {\r\n cachedList = Array.from(map.values()).sort((a, b) => a.order - b.order);\r\n };\r\n const emit = () => {\r\n recompute();\r\n listeners.forEach((l) => l());\r\n };\r\n return {\r\n list: () => cachedList,\r\n get: (key) => map.get(key),\r\n has: (key) => map.has(key),\r\n upsertDraft(input) {\r\n const existing = map.get(input.key);\r\n const order = existing?.order ?? input.order ?? nextOrder++;\r\n const status = input.status ?? existing?.status ?? 'dirty';\r\n map.set(input.key, {\r\n ...input,\r\n order,\r\n status,\r\n } as DirtyDraft);\r\n emit();\r\n },\r\n setStatus(key, status, error) {\r\n const existing = map.get(key);\r\n if (!existing) return;\r\n map.set(key, { ...existing, status, error });\r\n emit();\r\n },\r\n clearDraft(key) {\r\n if (map.delete(key)) emit();\r\n },\r\n clearAll() {\r\n if (map.size === 0) return;\r\n map.clear();\r\n emit();\r\n },\r\n subscribe(listener) {\r\n listeners.add(listener);\r\n return () => { listeners.delete(listener); };\r\n },\r\n };\r\n};\r\n\r\nconst DirtyDraftContext = createContext<DirtyDraftStore | null>(null);\r\n\r\nexport const DirtyDraftProvider = ({ children }: { children: ReactNode }) => {\r\n const storeRef = useRef<DirtyDraftStore | null>(null);\r\n if (!storeRef.current) storeRef.current = createStore();\r\n return (\r\n <DirtyDraftContext.Provider value={storeRef.current}>\r\n {children}\r\n </DirtyDraftContext.Provider>\r\n );\r\n};\r\n\r\n/** Always returns a store — falls back to a noop when no provider is mounted\r\n * so the hook can be called from inside `useRecordEditor` without forcing\r\n * every host of the editor to wrap themselves in a provider. */\r\nexport const useDirtyDraftStore = (): DirtyDraftStore => {\r\n const ctx = useContext(DirtyDraftContext);\r\n const fallbackRef = useRef<DirtyDraftStore | null>(null);\r\n if (!ctx && !fallbackRef.current) fallbackRef.current = createStore();\r\n return ctx ?? (fallbackRef.current as DirtyDraftStore);\r\n};\r\n\r\n/** Subscribe to the store and re-render on any change. */\r\nexport const useDirtyDrafts = (): DirtyDraft[] => {\r\n const store = useDirtyDraftStore();\r\n return useSyncExternalStore(\r\n useCallback((cb) => store.subscribe(cb), [store]),\r\n useCallback(() => store.list(), [store]),\r\n useCallback(() => store.list(), [store]),\r\n );\r\n};\r\n\r\n/** Subscribe to a single draft (or undefined) by key. */\r\nexport const useDirtyDraft = (key: string | undefined): DirtyDraft | undefined => {\r\n const store = useDirtyDraftStore();\r\n const getSnapshot = useCallback(\r\n () => (key ? store.get(key) : undefined),\r\n [store, key],\r\n );\r\n return useSyncExternalStore(\r\n useCallback((cb) => store.subscribe(cb), [store]),\r\n getSnapshot,\r\n getSnapshot,\r\n );\r\n};\r\n\r\n/** Stable per-row dirty lookup used by DefaultRecordRow / DefaultRecordCard.\r\n * Returns the current status of any draft whose key matches `recordId` (or\r\n * the synthetic anchor key for unsaved drafts). */\r\nexport const useDirtyStatusForKey = (key: string | undefined): DirtyDraftStatus | undefined => {\r\n const draft = useDirtyDraft(key);\r\n return draft?.status;\r\n};\r\n\r\n/** Build the canonical key for a draft. */\r\nexport const buildDraftKey = (opts: {\r\n recordId?: string;\r\n scopeRaw: string;\r\n draftKind?: string;\r\n}): string => {\r\n if (opts.recordId) return opts.recordId;\r\n const kind = opts.draftKind ?? 'rec';\r\n return `draft:${kind}:${opts.scopeRaw}`;\r\n};\r\n\r\n/** Hook used by the shell tray to count + bulk-save. */\r\nexport const useDirtyDraftActions = () => {\r\n const store = useDirtyDraftStore();\r\n const drafts = useDirtyDrafts();\r\n const count = useMemo(() => drafts.filter((d) => d.status !== 'saved').length, [drafts]);\r\n const errorCount = useMemo(() => drafts.filter((d) => d.status === 'error').length, [drafts]);\r\n return { drafts, count, errorCount, store };\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 {\r\n upsertRecord, updateRecord, removeRecord, createRecord,\r\n type RecordsCtx,\r\n} 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\nimport { useDirtyDraftStore, buildDraftKey } from './useDirtyDraftStore';\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 * When true, every save calls `records.create` (a fresh insert) instead\r\n * of `records.upsert`. Used by collection-cardinality hosts where\r\n * multiple items can share the same scope/recordType — each draft must\r\n * become its own row, not collide on an upsert key. The shell flips\r\n * this on for unsaved item drafts and clears it once the resolver hands\r\n * back a concrete `recordId`.\r\n */\r\n createMode?: boolean;\r\n /**\r\n * Optional host-supplied derivation for the label this editor registers\r\n * with the unsaved-changes tray. Receives the in-flight value and the\r\n * scope; should return a short, human-readable title. When omitted (or\r\n * when it returns `undefined`), the hook falls back to a built-in heuristic\r\n * that scans common title-shaped fields (`title`, `display.title`,\r\n * `name`, `label`, `heading`, `question`, `slug`).\r\n */\r\n deriveDraftLabel?: (value: T, scope: ParsedRef) => string | undefined;\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\nconst getScopedResolvedRecordId = <T,>(scope: ParsedRef, resolved: ResolvedRecord<T>): string | undefined => {\r\n if (!resolved.recordId) return undefined;\r\n // Collection-cardinality items carry their stable identity on the synthetic\r\n // `item:{id}` segment the shell adds to `scope.raw`. The resolver's\r\n // `sourceRef` stays anchor-only for those rows, so matching on `itemId`\r\n // is the reliable signal that the resolved UUID belongs to the current\r\n // editor target.\r\n if (scope.itemId && scope.itemId === resolved.recordId) return resolved.recordId;\r\n const scopeRaw = scope.raw || '';\r\n const sourceRef = resolved.sourceRef || '';\r\n if (scopeRaw === sourceRef) return resolved.recordId;\r\n return undefined;\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, createMode = false,\r\n deriveDraftLabel,\r\n } = args;\r\n const queryClient = useQueryClient();\r\n const draftStore = useDirtyDraftStore();\r\n // If the shell already has a draft for this record (because the user\r\n // edited it earlier and navigated away in `keep` mode), prefer that\r\n // value over the resolver's clean copy. Computed at mount only — once\r\n // the editor is live the local state owns the truth.\r\n const scopedResolvedRecordId = getScopedResolvedRecordId(scope, resolved);\r\n const draftKey = buildDraftKey({\r\n // Scope identity must win during record switches. `resolved.recordId`\r\n // can briefly lag behind the newly-selected target while the resolver is\r\n // catching up, and keying drafts off that stale id lets one edited item\r\n // borrow another item's draft. Once the resolver confirms the matching\r\n // record for this scope, we transparently migrate onto the concrete UUID.\r\n recordId: scopedResolvedRecordId,\r\n scopeRaw: scope.raw,\r\n draftKind: scope.kind,\r\n });\r\n const initialDraft = draftStore.get(draftKey);\r\n const cleanSeed = cloneSeed(resolved, defaultData);\r\n const seed = (initialDraft && reseed === 'preserve-dirty')\r\n ? (initialDraft.value as T)\r\n : cleanSeed;\r\n const seedFacetRule = (initialDraft && reseed === 'preserve-dirty')\r\n ? initialDraft.facetRule\r\n : initialFacetRule;\r\n\r\n const [value, setValue] = useState<T>(seed);\r\n const [savedSnapshot, setSavedSnapshot] = useState<T>(\r\n initialDraft ? (initialDraft.baseline as T) : cleanSeed,\r\n );\r\n const [facetRule, setFacetRule] = useState<FacetRule | null>(seedFacetRule);\r\n const [savedFacetRule, setSavedFacetRule] = useState<FacetRule | null>(\r\n initialDraft ? initialDraft.baselineFacetRule : initialFacetRule,\r\n );\r\n // Tracks whether the user has actually interacted with this editor in the\r\n // current mount. Without this gate, the dirty-detection effect can register\r\n // a draft on first mount because of transient mismatches between the seed\r\n // value and the post-reseed `savedSnapshot` (e.g. cloned vs inherited data,\r\n // initialFacetRule object identity). We only want to surface drafts the\r\n // user genuinely created. Pre-existing drafts (resumed from the store)\r\n // start as already-interacted so the tray entry persists.\r\n const [userInteracted, setUserInteracted] = useState<boolean>(!!initialDraft);\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 // Track the previous editing target so we can distinguish \"same record\r\n // refetched\" (preserve-dirty applies) from \"user navigated to a different\r\n // record\" (preserve-dirty MUST NOT apply — otherwise the editor keeps the\r\n // first record's value while looking at the second). Two records share the\r\n // same scope.raw under collection cardinality (both `item:{recordId}`),\r\n // and in the deeper id-primary path scope.raw can be empty for both — so\r\n // the only reliable signal that the target changed is `recordId` flipping.\r\n const prevTargetRef = useRef<{ scopeRaw: string; recordId?: string }>({\r\n scopeRaw: scope.raw, recordId: resolved.recordId,\r\n });\r\n useEffect(() => {\r\n const prev = prevTargetRef.current;\r\n const targetChanged =\r\n prev.scopeRaw !== scope.raw\r\n || (prev.recordId ?? null) !== (resolved.recordId ?? null);\r\n prevTargetRef.current = { scopeRaw: scope.raw, recordId: resolved.recordId };\r\n\r\n const fresh = cloneSeed(resolved, defaultData);\r\n\r\n // When the user navigated to a *different* record, prefer that record's\r\n // pre-existing draft if one is registered in the shell store; otherwise\r\n // seed from the resolver. The `preserve-dirty` guard only applies to\r\n // refetches of the same record (so an in-flight refresh doesn't blow\r\n // away the user's local edits).\r\n if (targetChanged) {\r\n const incomingKey = buildDraftKey({\r\n recordId: getScopedResolvedRecordId(scope, resolved),\r\n scopeRaw: scope.raw,\r\n draftKind: scope.kind,\r\n });\r\n const incomingDraft = draftStore.get(incomingKey);\r\n if (incomingDraft && reseed === 'preserve-dirty') {\r\n setValue(incomingDraft.value as T);\r\n setSavedSnapshot(incomingDraft.baseline as T);\r\n setFacetRule(incomingDraft.facetRule);\r\n setSavedFacetRule(incomingDraft.baselineFacetRule);\r\n // The draft was authored by the user previously — keep the\r\n // interaction gate hot so the tray entry stays live.\r\n setUserInteracted(true);\r\n } else {\r\n setValue(fresh);\r\n setSavedSnapshot(fresh);\r\n setFacetRule(initialFacetRule);\r\n setSavedFacetRule(initialFacetRule);\r\n setUserInteracted(false);\r\n }\r\n } else {\r\n // Same record — just a resolver refresh. In `preserve-dirty` mode keep\r\n // any in-flight value the user is typing; otherwise overwrite.\r\n if (reseed === 'preserve-dirty') {\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 setFacetRule(initialFacetRule);\r\n setSavedFacetRule(initialFacetRule);\r\n }\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.recordId, 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 // Gate on `userInteracted` so transient seed/snapshot mismatches during\r\n // mount and resolver settling don't flag the record as dirty.\r\n const valueDiff = !isEqual(value, savedSnapshot) || !isEqual(facetRule, savedFacetRule);\r\n const isDirty = userInteracted && valueDiff;\r\n\r\n // Wrapped setters that flip the interaction gate the moment the user\r\n // changes anything via the returned `onChange` / `onFacetRuleChange` APIs.\r\n const handleChange = useCallback((next: T | ((prev: T) => T)) => {\r\n setUserInteracted(true);\r\n setValue(next as T);\r\n }, []);\r\n const handleFacetRuleChange = useCallback((next: FacetRule | null) => {\r\n setUserInteracted(true);\r\n setFacetRule(next);\r\n }, []);\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 // Empty `scope.raw` is legitimate — it's the collection-root singleton\r\n // case (a \"global default\" record). The only situation we genuinely\r\n // can't save is a `rule:` scope with no clauses yet — the server has\r\n // no addressing for an unanchored, ruleless, brand-new record.\r\n const anchors = parsedRefToScope(scope);\r\n const hasAnchors = !!(anchors.productId || anchors.variantId || anchors.batchId || anchors.proofId);\r\n const hasRule = !!(facetRule && facetRule.all && facetRule.all.length > 0);\r\n const isRuleScope = scope.kind === 'rule';\r\n if (isRuleScope && !hasAnchors && !hasRule && !resolved.recordId && !createMode) {\r\n // eslint-disable-next-line no-console\r\n console.warn('[useRecordEditor] save() bailed — rule scope with no clauses, no recordId, not in createMode');\r\n return;\r\n }\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 recordId: resolved.recordId,\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 recordId: resolved.recordId,\r\n parentValue: previousCache?.parentValue ?? resolved.parentValue,\r\n });\r\n\r\n try {\r\n // Id-primary save: when the resolver gave us a recordId AND the\r\n // record is genuinely the user's own (`source === 'self'`, not an\r\n // inherited parent), PATCH it directly. Otherwise this is a brand-\r\n // new record. In `createMode` (collection-cardinality items) every\r\n // such save inserts a fresh row via `createRecord` — `upsert` would\r\n // collide because items share scope+recordType. Otherwise we go\r\n // through `upsertRecord`, which the server addresses by anchors /\r\n // facetRule.\r\n if (resolved.recordId && resolved.source === 'self') {\r\n await updateRecord<T>(ctx, resolved.recordId, {\r\n data: value,\r\n facetRule,\r\n });\r\n } else if (createMode) {\r\n await createRecord<T>(ctx, {\r\n ref: scope.kind === 'rule' && scope.raw ? scope.raw : undefined,\r\n scope: anchors,\r\n data: value,\r\n facetRule,\r\n });\r\n } else {\r\n await upsertRecord<T>(ctx, {\r\n // External ref only when the underlying scope already carries\r\n // one (e.g. rule:{id} for an existing rule record). Empty for\r\n // anchor-only writes — server addresses by anchors.\r\n ref: scope.kind === 'rule' && scope.raw ? scope.raw : undefined,\r\n scope: anchors,\r\n data: value,\r\n facetRule,\r\n });\r\n }\r\n draftStore.clearDraft(draftKey);\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, resolved.recordId, createMode, draftKey]);\r\n\r\n const reset = useCallback(() => {\r\n setValue(savedSnapshot);\r\n setFacetRule(savedFacetRule);\r\n setUserInteracted(false);\r\n // Drop any registered draft — the editor is back to its baseline.\r\n draftStore.clearDraft(draftKey);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [savedSnapshot, savedFacetRule, draftKey]);\r\n\r\n const remove = useCallback(async () => {\r\n if (resolved.source !== 'self') return;\r\n // Id-primary delete. The resolver always surfaces a `recordId` for\r\n // `source === 'self'`; bail otherwise.\r\n if (!resolved.recordId) return;\r\n await removeRecord(ctx, resolved.recordId);\r\n draftStore.clearDraft(draftKey);\r\n onDeleted?.();\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [resolved.source, resolved.recordId, draftKey]);\r\n\r\n // If the draftKey for THIS editor instance changes (e.g. `resolved.recordId`\r\n // arrives after initial mount and we transition from `draft:item:…` to a\r\n // concrete UUID), migrate any draft we previously registered under the old\r\n // key onto the new one. We MUST NOT blindly clear the previous key when\r\n // the editor switches to a different record (e.g. user navigates from\r\n // item A to item B in `keep` mode) — that would wipe A's legitimate\r\n // unsaved draft. The migration only happens when both keys describe the\r\n // same underlying record, which we detect via matching `scopeRaw`.\r\n const prevDraftKeyRef = useRef<string>(draftKey);\r\n const prevScopeRawRef = useRef<string>(scope.raw);\r\n useEffect(() => {\r\n const prevKey = prevDraftKeyRef.current;\r\n const prevScopeRaw = prevScopeRawRef.current;\r\n if (prevKey && prevKey !== draftKey && prevScopeRaw === scope.raw) {\r\n // Same selected target, key just got upgraded from scope-backed draft\r\n // identity to a concrete recordId — drop the old synthetic entry so\r\n // the tray doesn't list the same record twice.\r\n const stale = draftStore.get(prevKey);\r\n if (stale) draftStore.clearDraft(prevKey);\r\n }\r\n prevDraftKeyRef.current = draftKey;\r\n prevScopeRawRef.current = scope.raw;\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [draftKey, scope.raw]);\r\n\r\n // ---------------------------------------------------------------------------\r\n // Draft store sync — register the in-flight value with the shell-level\r\n // registry whenever the editor is dirty, and clear it on save / reset.\r\n // The registered draft captures a closure over the current save() so the\r\n // shell's \"Save all\" can call it without re-mounting the editor.\r\n // ---------------------------------------------------------------------------\r\n useEffect(() => {\r\n if (!isDirty) {\r\n // If we held a draft for this key, it was either saved (clearDraft\r\n // called inside save()) or reset (clearDraft inside reset()). Either\r\n // way no further bookkeeping is required here.\r\n return;\r\n }\r\n const anchors = parsedRefToScope(scope);\r\n const saveKind: 'update' | 'create' | 'upsert' = (resolved.recordId && resolved.source === 'self')\r\n ? 'update'\r\n : (createMode ? 'create' : 'upsert');\r\n const deriveLabel = (): string => {\r\n // 1. Host override always wins.\r\n if (deriveDraftLabel) {\r\n try {\r\n const custom = deriveDraftLabel(value, scope);\r\n if (typeof custom === 'string' && custom.trim()) return custom.trim();\r\n } catch { /* fall through to heuristic */ }\r\n }\r\n // 2. Built-in heuristic — mirrors the row label resolution used by\r\n // `useCollectionItems` so the tray and the sidebar agree.\r\n const KEYS = ['title', 'name', 'label', 'heading', 'question', 'slug'] as const;\r\n const pickString = (obj: Record<string, unknown> | null | undefined): string | undefined => {\r\n if (!obj || typeof obj !== 'object') return undefined;\r\n for (const key of KEYS) {\r\n const raw = obj[key];\r\n if (typeof raw === 'string' && raw.trim()) return raw.trim();\r\n }\r\n return undefined;\r\n };\r\n const v = value as Record<string, unknown> | null | undefined;\r\n // Top-level …\r\n const top = pickString(v);\r\n if (top) return top;\r\n // … then well-known nested wrappers hosts use (display, content, meta).\r\n if (v && typeof v === 'object') {\r\n for (const wrapper of ['display', 'content', 'meta', 'data'] as const) {\r\n const nested = pickString(v[wrapper] as Record<string, unknown> | undefined);\r\n if (nested) return nested;\r\n }\r\n }\r\n // Fall back to a friendly scope descriptor — never leak raw IDs.\r\n if (scope.raw?.startsWith('item:')) return 'Untitled item';\r\n if (scope.kind === 'rule') return 'Rule';\r\n if (scope.kind && scope.kind !== 'collection') {\r\n return scope.kind.charAt(0).toUpperCase() + scope.kind.slice(1);\r\n }\r\n return 'Default';\r\n };\r\n draftStore.upsertDraft({\r\n key: draftKey,\r\n label: deriveLabel(),\r\n context: scope.kind,\r\n scopeRaw: scope.raw,\r\n recordId: resolved.recordId,\r\n value,\r\n facetRule,\r\n baseline: savedSnapshot,\r\n baselineFacetRule: savedFacetRule,\r\n createMode,\r\n scopeAnchors: anchors,\r\n ref: scope.kind === 'rule' && scope.raw ? scope.raw : undefined,\r\n saveKind,\r\n save: async () => { await save(); },\r\n });\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isDirty, value, facetRule, savedSnapshot, savedFacetRule, scope.raw, resolved.recordId, resolved.source, createMode, save]);\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: handleChange,\r\n source: effectiveSource,\r\n recordId: resolved.recordId,\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: handleFacetRuleChange,\r\n };\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, ResolveAllEntry, 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 /**\r\n * All matching records, sorted most-specific first. Each appears once.\r\n * SDK 1.10.2: `ResolveAllEntry` wraps `{ record: AppRecord, matchedAt,\r\n * specificity, matchedRule? }`.\r\n */\r\n records: ResolveAllEntry[];\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 // SDK 1.10.2: `MatchResult.data` (was `.records`).\r\n const entries = result?.data ?? [];\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 // SDK 1.10.2: `MatchEntry` extends `AppRecord` directly — no inner `record`.\r\n const baseList: CollectedRecord<T>[] = entries.map((entry: MatchEntry, i: number) => ({\r\n ref: entry.ref ?? '',\r\n scope: parseRef(entry.ref ?? ''),\r\n data: entry.data as T,\r\n depth: i,\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 // SDK 1.10.2: `MatchResult.data` (was `.records`); `MatchEntry`\r\n // extends `AppRecord` so we read `entry.ref` / `entry.data` directly.\r\n const entries = result?.data ?? [];\r\n if (entries.length === 0) return { data: null, provenance: {}, layers: [] };\r\n const present = entries.map((entry: MatchEntry) => ({\r\n ref: entry.ref ?? '',\r\n data: entry.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}"]}
|