@proveanything/smartlinks-utils-ui 0.7.2 → 0.7.4

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.
@@ -329,6 +329,21 @@ interface RecordsAdminI18n {
329
329
  * `{name}` is replaced with the friendly label of the dirty record.
330
330
  */
331
331
  unsavedBannerBody: string;
332
+ /**
333
+ * Shell-level "Save all" tray strings (multi-record dirty workflow).
334
+ * `{n}` placeholders interpolate the count.
335
+ */
336
+ unsavedTrayCount: string;
337
+ unsavedTrayErrors: string;
338
+ saveAll: string;
339
+ discardAll: string;
340
+ saveAllInProgress: string;
341
+ saveAllSuccess: string;
342
+ saveAllErrorTitle: string;
343
+ saveAllStop: string;
344
+ saveAllClose: string;
345
+ saveAllRetryFailed: string;
346
+ saveAllJumpToError: string;
332
347
  /** Presentation mode switcher labels. */
333
348
  presentationList: string;
334
349
  presentationCompact: string;
@@ -541,6 +556,8 @@ interface RecordSlotContext {
541
556
  selected: boolean;
542
557
  onSelect: () => void;
543
558
  isDirty?: boolean;
559
+ /** True when the row has a draft whose last save attempt failed. */
560
+ hasError?: boolean;
544
561
  /**
545
562
  * Resolved i18n strings for the shell. Default row/card renderers use this
546
563
  * for fallback subtitles ("Not set", "Configured", "Inherited") so apps
@@ -1033,6 +1050,15 @@ interface Props$c {
1033
1050
  dirtyId?: string;
1034
1051
  /** Anchor-key equivalent of `dirtyId` for non-record-backed tabs. */
1035
1052
  dirtyAnchorKey?: string;
1053
+ /**
1054
+ * Optional set of record IDs (or anchor refs) that have unsaved changes
1055
+ * registered with the shell-level dirty-draft store. Used by the shell to
1056
+ * paint dirty/error pips on rows the user has edited but isn't currently
1057
+ * looking at. `dirtyId`/`dirtyAnchorKey` remain for the active editor.
1058
+ */
1059
+ dirtyKeys?: ReadonlySet<string>;
1060
+ /** Subset of `dirtyKeys` whose last save attempt failed. */
1061
+ errorKeys?: ReadonlySet<string>;
1036
1062
  /** Rail row density. Defaults to `list`. */
1037
1063
  presentation?: RecordPresentation;
1038
1064
  /** Optional custom row renderer (still dense — applied to both densities). */
@@ -1058,11 +1084,11 @@ interface Props$c {
1058
1084
  /** Resolved i18n strings — used by default row/card renderers. */
1059
1085
  i18n?: RecordsAdminI18n;
1060
1086
  }
1061
- declare const RecordList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1062
- declare const ProductList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1063
- declare const FacetList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1064
- declare const VariantList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1065
- declare const BatchList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1087
+ declare const RecordList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, dirtyKeys, errorKeys, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1088
+ declare const ProductList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, dirtyKeys, errorKeys, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1089
+ declare const FacetList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, dirtyKeys, errorKeys, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1090
+ declare const VariantList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, dirtyKeys, errorKeys, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1091
+ declare const BatchList: ({ items, selectedId, selectedAnchorKey, onSelect, dirtyId, dirtyAnchorKey, dirtyKeys, errorKeys, presentation, renderListRow, groupBy, rowClipboard, i18n, }: Props$c) => react_jsx_runtime.JSX.Element;
1066
1092
 
1067
1093
  interface DefaultRecordRowProps {
1068
1094
  record: RecordSummary;
@@ -1952,6 +1978,83 @@ declare const useDirtyNavigation: ({ strategy, isDirty, save, reset, confirm, i1
1952
1978
  runWithGuard: (action: () => void) => Promise<boolean>;
1953
1979
  };
1954
1980
 
1981
+ type DirtyDraftStatus = 'dirty' | 'saving' | 'saved' | 'error';
1982
+ interface DirtyDraft {
1983
+ /** Stable key — recordId for saved rows, `draft:{kind}:{scope.raw}` otherwise. */
1984
+ key: string;
1985
+ /** Friendly label for the tray + per-record progress rows. */
1986
+ label: string;
1987
+ /** Optional secondary descriptor (e.g. scope kind / facet). */
1988
+ context?: string;
1989
+ /** ParsedRef.raw — used to re-select the record from the tray. */
1990
+ scopeRaw: string;
1991
+ /** When set, selecting this draft from the tray loads a saved row by id. */
1992
+ recordId?: string;
1993
+ /** Insertion order — drives the visual order in the tray + overlay. */
1994
+ order: number;
1995
+ /** Current value being edited. */
1996
+ value: unknown;
1997
+ /** Optional facet rule attached to the value. */
1998
+ facetRule: FacetRule | null;
1999
+ /** Last-saved baseline for the same record (for diff/discard). */
2000
+ baseline: unknown;
2001
+ baselineFacetRule: FacetRule | null;
2002
+ /** Whether this draft must be inserted (collection-cardinality items). */
2003
+ createMode: boolean;
2004
+ /** Anchor IDs for the save call. */
2005
+ scopeAnchors: RecordAnchors;
2006
+ /** Optional external ref (rule:{id}) to send with the save. */
2007
+ ref?: string;
2008
+ /** Save kind decided at draft creation time. */
2009
+ saveKind: 'update' | 'create' | 'upsert';
2010
+ status: DirtyDraftStatus;
2011
+ error?: unknown;
2012
+ /**
2013
+ * Performs the save against the SDK. Captured at draft creation time so
2014
+ * the overlay doesn't need access to the editor's resolver/ctx — keeps
2015
+ * the registry self-contained.
2016
+ */
2017
+ save: () => Promise<void>;
2018
+ }
2019
+ type Listener = () => void;
2020
+ interface DirtyDraftStore {
2021
+ list(): DirtyDraft[];
2022
+ get(key: string): DirtyDraft | undefined;
2023
+ has(key: string): boolean;
2024
+ upsertDraft(input: Omit<DirtyDraft, 'order' | 'status'> & {
2025
+ order?: number;
2026
+ status?: DirtyDraftStatus;
2027
+ }): void;
2028
+ setStatus(key: string, status: DirtyDraftStatus, error?: unknown): void;
2029
+ clearDraft(key: string): void;
2030
+ clearAll(): void;
2031
+ subscribe(listener: Listener): () => void;
2032
+ }
2033
+ declare const DirtyDraftProvider: ({ children }: {
2034
+ children: ReactNode;
2035
+ }) => react_jsx_runtime.JSX.Element;
2036
+ /** Always returns a store — falls back to a noop when no provider is mounted
2037
+ * so the hook can be called from inside `useRecordEditor` without forcing
2038
+ * every host of the editor to wrap themselves in a provider. */
2039
+ declare const useDirtyDraftStore: () => DirtyDraftStore;
2040
+ /** Subscribe to the store and re-render on any change. */
2041
+ declare const useDirtyDrafts: () => DirtyDraft[];
2042
+ /** Subscribe to a single draft (or undefined) by key. */
2043
+ declare const useDirtyDraft: (key: string | undefined) => DirtyDraft | undefined;
2044
+ /** Build the canonical key for a draft. */
2045
+ declare const buildDraftKey: (opts: {
2046
+ recordId?: string;
2047
+ scopeRaw: string;
2048
+ draftKind?: string;
2049
+ }) => string;
2050
+ /** Hook used by the shell tray to count + bulk-save. */
2051
+ declare const useDirtyDraftActions: () => {
2052
+ drafts: DirtyDraft[];
2053
+ count: number;
2054
+ errorCount: number;
2055
+ store: DirtyDraftStore;
2056
+ };
2057
+
1955
2058
  declare function usePresentationPref(args: {
1956
2059
  appId: string;
1957
2060
  recordType?: string;
@@ -2037,9 +2140,18 @@ interface Props<T> {
2037
2140
  error: Error | null;
2038
2141
  onBack: () => void;
2039
2142
  onSelect: (itemId: string) => void;
2143
+ /**
2144
+ * Set of keys (recordIds + scope refs) currently dirty in the shell-level
2145
+ * draft store. Used to paint a per-row pip on items the user has edited
2146
+ * but isn't currently looking at — mirrors the affordance the scope rail
2147
+ * gets via `RecordList.dirtyKeys`.
2148
+ */
2149
+ dirtyKeys?: ReadonlySet<string>;
2150
+ /** Subset of `dirtyKeys` whose last save attempt failed. */
2151
+ errorKeys?: ReadonlySet<string>;
2040
2152
  i18n: Pick<RecordsAdminI18n, 'backToScopes' | 'siblingsHeading' | 'noItemsTitle' | 'noItemsBody'>;
2041
2153
  }
2042
- declare function SiblingRail<T>({ items, selectedItemId, isLoading, error, onBack, onSelect, i18n, }: Props<T>): react_jsx_runtime.JSX.Element;
2154
+ declare function SiblingRail<T>({ items, selectedItemId, isLoading, error, onBack, onSelect, dirtyKeys, errorKeys, i18n, }: Props<T>): react_jsx_runtime.JSX.Element;
2043
2155
 
2044
2156
  interface ClipboardEntry<T = unknown> {
2045
2157
  value: T;
@@ -2158,4 +2270,4 @@ declare const exportCsv: <T>(records: RecordSummary<T>[], schema: CsvSchema<T>)
2158
2270
  declare const importCsv: <T>(file: File, schema: CsvSchema<T>, ctx: RecordsCtx) => Promise<ImportReport>;
2159
2271
  declare const downloadBlob: (blob: Blob, filename: string) => void;
2160
2272
 
2161
- export { ALL_ITEM_VIEWS, ALL_PRESENTATIONS, BatchList, BulkActionsMenu, type ClipboardEntry, type CollectedRecord, type CollectedSort, type CollectionRailMode, type CsvSchema, type CsvSchemaColumn, DEFAULT_DEEP_LINK_PARAM_NAMES, DEFAULT_I18N, DEFAULT_ICONS, type DeepLinkAdapter, type DeepLinkChangeKind, type DeepLinkHistoryMode, type DeepLinkOptions, type DeepLinkParamNames, type DeepLinkState, DefaultItemCards, DefaultItemTable, DefaultRecordCard, DefaultRecordRow, DeleteButton, type DirtyStrategy, DrawerPreview, type EditorContext, EditorItemNav, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, type ItemColumn, ItemListView, type ItemSlotContext, type ItemView, type ItemViewContext, ItemViewSwitcher, LoadingState, type MergeStrategy, type MergedRecord, type NavConfirmI18n, type ParsedRef, type PasteCompatibility, type PasteCompatibilityResult, PresentationSwitcher, type PreviewMode, PreviewScopePicker, PreviewToggleButton, type ProductBrowseItem, type ProductChildItem, ProductDrillDown, ProductList, type RecordBadge, RecordBrowser, type RecordCardinality, RecordEditor, RecordList, type RecordPresentation, type RecordSlotContext, type RecordSource, type RecordStatus, type RecordSummary, type RecordsAdminI18n, type RecordsAdminIcons, RecordsAdminShell, type RecordsAdminShellProps, type ResolvedDeepLinkParamNames, ResolvedPreview, type ResolvedRecord, ScopeBreadcrumb, type ScopeKind, ScopeTabs, SiblingRail, SidePreview, type SmartLinksSDK, StatusDot, StatusFilterPills, StatusIcon, type StatusTone, TabbedPreview, type TelemetryEvent, type UseCollectionItemsArgs, type UseRecordClipboardArgs, type UseRecordClipboardReturn, type UseResolveAllRecordsArgs, type UseResolveAllResult, type UseRulePreviewArgs, type UseRulePreviewResult, UtilityRow, VariantList, buildRef, bulkDelete, bulkUpsert, checkPasteCompatibility, cloneValue, createDefaultDeepLinkAdapter, createRecord, downloadBlob, exportCsv, getRecordById, importCsv, listRecords, matchRecords, mergeIcons, parseRef, parsedRefToScope, parsedRefToTarget, pickHeaderIcon, removeRecord, resolutionChain, resolveRecord, restoreRecord, scopesEqual, statusToneLabel, upsertRecord, useCollectedRecords, useCollectionItems, useDeepLinkState, useDirtyNavigation, useFacetBrowse, useIntroDismissed, useItemViewPref, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordClipboard, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeProbe, useUnsavedGuard };
2273
+ export { ALL_ITEM_VIEWS, ALL_PRESENTATIONS, BatchList, BulkActionsMenu, type ClipboardEntry, type CollectedRecord, type CollectedSort, type CollectionRailMode, type CsvSchema, type CsvSchemaColumn, DEFAULT_DEEP_LINK_PARAM_NAMES, DEFAULT_I18N, DEFAULT_ICONS, type DeepLinkAdapter, type DeepLinkChangeKind, type DeepLinkHistoryMode, type DeepLinkOptions, type DeepLinkParamNames, type DeepLinkState, DefaultItemCards, DefaultItemTable, DefaultRecordCard, DefaultRecordRow, DeleteButton, type DirtyDraft, DirtyDraftProvider, type DirtyDraftStatus, type DirtyDraftStore, type DirtyStrategy, DrawerPreview, type EditorContext, EditorItemNav, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, type ItemColumn, ItemListView, type ItemSlotContext, type ItemView, type ItemViewContext, ItemViewSwitcher, LoadingState, type MergeStrategy, type MergedRecord, type NavConfirmI18n, type ParsedRef, type PasteCompatibility, type PasteCompatibilityResult, PresentationSwitcher, type PreviewMode, PreviewScopePicker, PreviewToggleButton, type ProductBrowseItem, type ProductChildItem, ProductDrillDown, ProductList, type RecordBadge, RecordBrowser, type RecordCardinality, RecordEditor, RecordList, type RecordPresentation, type RecordSlotContext, type RecordSource, type RecordStatus, type RecordSummary, type RecordsAdminI18n, type RecordsAdminIcons, RecordsAdminShell, type RecordsAdminShellProps, type ResolvedDeepLinkParamNames, ResolvedPreview, type ResolvedRecord, ScopeBreadcrumb, type ScopeKind, ScopeTabs, SiblingRail, SidePreview, type SmartLinksSDK, StatusDot, StatusFilterPills, StatusIcon, type StatusTone, TabbedPreview, type TelemetryEvent, type UseCollectionItemsArgs, type UseRecordClipboardArgs, type UseRecordClipboardReturn, type UseResolveAllRecordsArgs, type UseResolveAllResult, type UseRulePreviewArgs, type UseRulePreviewResult, UtilityRow, VariantList, buildDraftKey, buildRef, bulkDelete, bulkUpsert, checkPasteCompatibility, cloneValue, createDefaultDeepLinkAdapter, createRecord, downloadBlob, exportCsv, getRecordById, importCsv, listRecords, matchRecords, mergeIcons, parseRef, parsedRefToScope, parsedRefToTarget, pickHeaderIcon, removeRecord, resolutionChain, resolveRecord, restoreRecord, scopesEqual, statusToneLabel, upsertRecord, useCollectedRecords, useCollectionItems, useDeepLinkState, useDirtyDraft, useDirtyDraftActions, useDirtyDraftStore, useDirtyDrafts, useDirtyNavigation, useFacetBrowse, useIntroDismissed, useItemViewPref, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordClipboard, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeProbe, useUnsavedGuard };