@proveanything/smartlinks-utils-ui 0.3.4 → 0.3.7
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.
|
@@ -4,6 +4,7 @@ import * as _proveanything_smartlinks_dist_types_appObjects from '@proveanything
|
|
|
4
4
|
import { MatchedAt, FacetRule, RecordScope, AppRecord, RecordTarget, MatchResult, MatchEntry } from '@proveanything/smartlinks/dist/types/appObjects';
|
|
5
5
|
import { LucideIcon } from 'lucide-react';
|
|
6
6
|
import * as _tanstack_query_core from '@tanstack/query-core';
|
|
7
|
+
import { InfiniteData } from '@tanstack/react-query';
|
|
7
8
|
|
|
8
9
|
type ScopeKind = 'product' | 'facet' | 'variant' | 'batch';
|
|
9
10
|
/** Parsed `ref` string — see `data/refs.ts`. Format: `kind:id` or chain. */
|
|
@@ -219,6 +220,13 @@ interface RecordsAdminI18n {
|
|
|
219
220
|
newItem: string;
|
|
220
221
|
noItemsTitle: string;
|
|
221
222
|
noItemsBody: string;
|
|
223
|
+
/**
|
|
224
|
+
* Empty-state copy for the LEFT browse rail (the list itself is empty).
|
|
225
|
+
* Defaults to a friendly "no records exist yet" message — distinct from
|
|
226
|
+
* `emptyTitle/emptyBody` which is the RIGHT pane "pick something" prompt.
|
|
227
|
+
*/
|
|
228
|
+
railEmptyTitle: string;
|
|
229
|
+
railEmptyBody: string;
|
|
222
230
|
}
|
|
223
231
|
declare const DEFAULT_I18N: RecordsAdminI18n;
|
|
224
232
|
|
|
@@ -395,6 +403,14 @@ interface RecordsAdminShellProps<TData = unknown> {
|
|
|
395
403
|
title?: string;
|
|
396
404
|
/** Single-line muted subtitle under the header title. */
|
|
397
405
|
subtitle?: string;
|
|
406
|
+
/**
|
|
407
|
+
* Render the branded header card above the rail. Off by default — most apps
|
|
408
|
+
* don't need it (the surrounding host typically already shows a title). Set
|
|
409
|
+
* `true` to opt in, or simply pass any of the header-customising props
|
|
410
|
+
* (`title`, `subtitle`, `headerIcon`, `headerActions`, `showStats`,
|
|
411
|
+
* `statsItems`) and the header will auto-show.
|
|
412
|
+
*/
|
|
413
|
+
showHeader?: boolean;
|
|
398
414
|
/** Icon shown in the header card. Falls back to `icons.header.byRecordType[recordType]`
|
|
399
415
|
* or `icons.header.default`. Pass a Lucide icon component or any ReactNode. */
|
|
400
416
|
headerIcon?: ReactNode;
|
|
@@ -413,6 +429,11 @@ interface RecordsAdminShellProps<TData = unknown> {
|
|
|
413
429
|
label: string;
|
|
414
430
|
value: string | number;
|
|
415
431
|
}>;
|
|
432
|
+
/** Optional title rendered above the stats strip (e.g. "At a glance"). */
|
|
433
|
+
statsTitle?: string;
|
|
434
|
+
/** Optional icon rendered next to `statsTitle`. Pass a Lucide icon element
|
|
435
|
+
* or any ReactNode. */
|
|
436
|
+
statsIcon?: ReactNode;
|
|
416
437
|
/** Override the default Lucide icons used by the shell (scope tabs, statuses,
|
|
417
438
|
* empty states, action menus, etc.). Deep-merged onto `DEFAULT_ICONS`. */
|
|
418
439
|
icons?: Partial<RecordsAdminIcons>;
|
|
@@ -839,6 +860,7 @@ interface UseRecordListArgs {
|
|
|
839
860
|
pageSize?: number;
|
|
840
861
|
}
|
|
841
862
|
declare const useRecordList: (args: UseRecordListArgs) => {
|
|
863
|
+
allItems: RecordSummary<unknown>[];
|
|
842
864
|
items: RecordSummary<unknown>[];
|
|
843
865
|
total: number;
|
|
844
866
|
counts: {
|
|
@@ -1019,28 +1041,51 @@ interface UseProductBrowseArgs {
|
|
|
1019
1041
|
/** Override admin flag if needed (default true). */
|
|
1020
1042
|
admin?: boolean;
|
|
1021
1043
|
}
|
|
1044
|
+
interface ProductBrowsePage {
|
|
1045
|
+
items: ProductBrowseItem[];
|
|
1046
|
+
nextOffset: number;
|
|
1047
|
+
nextCursor: string | null;
|
|
1048
|
+
hasMore: boolean;
|
|
1049
|
+
total?: number;
|
|
1050
|
+
}
|
|
1022
1051
|
/**
|
|
1023
|
-
* Cursor-paginated product list backed by `SL.
|
|
1052
|
+
* Cursor-paginated product list backed by `SL.products.query`. When the SDK
|
|
1024
1053
|
* returns a `nextCursor`, we use it; otherwise we fall back to offset-based
|
|
1025
1054
|
* paging so the hook works against older SDKs or in-memory adapters too.
|
|
1026
1055
|
*/
|
|
1027
1056
|
declare const useProductBrowse: (args: UseProductBrowseArgs) => {
|
|
1028
|
-
items:
|
|
1029
|
-
total:
|
|
1057
|
+
items: ProductBrowseItem[];
|
|
1058
|
+
total: number | undefined;
|
|
1030
1059
|
isLoading: boolean;
|
|
1031
1060
|
error: Error | null;
|
|
1032
1061
|
hasNextPage: boolean;
|
|
1033
1062
|
isFetchingNextPage: boolean;
|
|
1034
|
-
fetchNextPage: (options?: _tanstack_query_core.FetchNextPageOptions) => Promise<_tanstack_query_core.InfiniteQueryObserverResult<
|
|
1035
|
-
items: any;
|
|
1036
|
-
nextOffset: any;
|
|
1037
|
-
nextCursor: any;
|
|
1038
|
-
hasMore: any;
|
|
1039
|
-
total: any;
|
|
1040
|
-
}, unknown>, Error>>;
|
|
1063
|
+
fetchNextPage: (options?: _tanstack_query_core.FetchNextPageOptions) => Promise<_tanstack_query_core.InfiniteQueryObserverResult<InfiniteData<ProductBrowsePage, unknown>, Error>>;
|
|
1041
1064
|
refetch: () => Promise<void>;
|
|
1042
1065
|
};
|
|
1043
1066
|
|
|
1067
|
+
interface UseFacetBrowseArgs {
|
|
1068
|
+
SL: SmartLinksSDK;
|
|
1069
|
+
collectionId: string;
|
|
1070
|
+
existing: RecordSummary[];
|
|
1071
|
+
search?: string;
|
|
1072
|
+
filter?: 'all' | RecordStatus;
|
|
1073
|
+
enabled?: boolean;
|
|
1074
|
+
}
|
|
1075
|
+
declare const useFacetBrowse: ({ SL, collectionId, existing, search, filter, enabled, }: UseFacetBrowseArgs) => {
|
|
1076
|
+
items: RecordSummary<unknown>[];
|
|
1077
|
+
total: number;
|
|
1078
|
+
counts: {
|
|
1079
|
+
all: number;
|
|
1080
|
+
configured: number;
|
|
1081
|
+
partial: number;
|
|
1082
|
+
empty: number;
|
|
1083
|
+
};
|
|
1084
|
+
isLoading: boolean;
|
|
1085
|
+
error: Error | null;
|
|
1086
|
+
refetch: () => void;
|
|
1087
|
+
};
|
|
1088
|
+
|
|
1044
1089
|
interface CollectedRecord<T = unknown> {
|
|
1045
1090
|
/** The ref this record was loaded from. */
|
|
1046
1091
|
ref: string;
|
|
@@ -1270,4 +1315,4 @@ declare const exportCsv: <T>(records: RecordSummary<T>[], schema: CsvSchema<T>)
|
|
|
1270
1315
|
declare const importCsv: <T>(file: File, schema: CsvSchema<T>, ctx: RecordsCtx) => Promise<ImportReport>;
|
|
1271
1316
|
declare const downloadBlob: (blob: Blob, filename: string) => void;
|
|
1272
1317
|
|
|
1273
|
-
export { ALL_PRESENTATIONS, BatchList, BulkActionsMenu, type CollectedRecord, type CollectedSort, type CsvSchema, type CsvSchemaColumn, DEFAULT_I18N, DEFAULT_ICONS, DefaultRecordCard, DefaultRecordRow, DeleteButton, type DirtyStrategy, DrawerPreview, type EditorContext, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, LoadingState, type MergeStrategy, type MergedRecord, type NavConfirmI18n, type ParsedRef, 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, ResolvedPreview, type ResolvedRecord, ScopeBreadcrumb, type ScopeKind, ScopeTabs, SidePreview, type SmartLinksSDK, StatusDot, StatusFilterPills, TabbedPreview, type TelemetryEvent, type UseResolveAllRecordsArgs, type UseResolveAllResult, type UseRulePreviewArgs, type UseRulePreviewResult, UtilityRow, VariantList, buildRef, bulkDelete, bulkUpsert, deleteRecord, downloadBlob, exportCsv, getRecordByRef, importCsv, listRecords, matchRecords, mergeIcons, parseRef, parsedRefToScope, parsedRefToTarget, pickHeaderIcon, resolutionChain, resolveRecord, restoreRecord, scopesEqual, upsertRecord, useCollectedRecords, useDirtyNavigation, useIntroDismissed, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeProbe, useUnsavedGuard };
|
|
1318
|
+
export { ALL_PRESENTATIONS, BatchList, BulkActionsMenu, type CollectedRecord, type CollectedSort, type CsvSchema, type CsvSchemaColumn, DEFAULT_I18N, DEFAULT_ICONS, DefaultRecordCard, DefaultRecordRow, DeleteButton, type DirtyStrategy, DrawerPreview, type EditorContext, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, LoadingState, type MergeStrategy, type MergedRecord, type NavConfirmI18n, type ParsedRef, 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, ResolvedPreview, type ResolvedRecord, ScopeBreadcrumb, type ScopeKind, ScopeTabs, SidePreview, type SmartLinksSDK, StatusDot, StatusFilterPills, TabbedPreview, type TelemetryEvent, type UseResolveAllRecordsArgs, type UseResolveAllResult, type UseRulePreviewArgs, type UseRulePreviewResult, UtilityRow, VariantList, buildRef, bulkDelete, bulkUpsert, deleteRecord, downloadBlob, exportCsv, getRecordByRef, importCsv, listRecords, matchRecords, mergeIcons, parseRef, parsedRefToScope, parsedRefToTarget, pickHeaderIcon, resolutionChain, resolveRecord, restoreRecord, scopesEqual, upsertRecord, useCollectedRecords, useDirtyNavigation, useFacetBrowse, useIntroDismissed, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeProbe, useUnsavedGuard };
|
|
@@ -89,7 +89,9 @@ var DEFAULT_I18N = {
|
|
|
89
89
|
presentationCompact: "Compact",
|
|
90
90
|
newItem: "New item",
|
|
91
91
|
noItemsTitle: "No items yet",
|
|
92
|
-
noItemsBody: "Create your first item to get started."
|
|
92
|
+
noItemsBody: "Create your first item to get started.",
|
|
93
|
+
railEmptyTitle: "No records yet",
|
|
94
|
+
railEmptyBody: "Records you create will appear here."
|
|
93
95
|
};
|
|
94
96
|
|
|
95
97
|
// src/components/RecordsAdmin/types/presentation.ts
|
|
@@ -434,6 +436,7 @@ var useRecordList = (args) => {
|
|
|
434
436
|
}, [queryClient, ctx.collectionId, ctx.appId, ctx.recordType]);
|
|
435
437
|
const total = query.data?.pages[query.data.pages.length - 1]?.total ?? items.length;
|
|
436
438
|
return {
|
|
439
|
+
allItems: items,
|
|
437
440
|
items: filtered,
|
|
438
441
|
total,
|
|
439
442
|
counts,
|
|
@@ -748,7 +751,133 @@ var useScopeProbe = ({ SL, collectionId, admin = true, enabled = true }) => {
|
|
|
748
751
|
error: query.error ?? null
|
|
749
752
|
};
|
|
750
753
|
};
|
|
751
|
-
var
|
|
754
|
+
var LOG = "[RecordsAdmin/useFacetBrowse]";
|
|
755
|
+
var QK = ["records-admin", "facet-browse"];
|
|
756
|
+
var toScaffoldSummary = (facet, value) => {
|
|
757
|
+
const facetKey = facet.key ?? "";
|
|
758
|
+
const valueKey = value.key ?? "";
|
|
759
|
+
const ref = buildRef({ facetId: facetKey, facetValue: valueKey });
|
|
760
|
+
return {
|
|
761
|
+
id: null,
|
|
762
|
+
ref,
|
|
763
|
+
scope: parseRef(ref),
|
|
764
|
+
data: null,
|
|
765
|
+
status: "empty",
|
|
766
|
+
label: value.name ?? valueKey ?? "Untitled value",
|
|
767
|
+
subtitle: facet.name ?? facetKey ?? void 0
|
|
768
|
+
};
|
|
769
|
+
};
|
|
770
|
+
var useFacetBrowse = ({
|
|
771
|
+
SL,
|
|
772
|
+
collectionId,
|
|
773
|
+
existing,
|
|
774
|
+
search = "",
|
|
775
|
+
filter = "all",
|
|
776
|
+
enabled = true
|
|
777
|
+
}) => {
|
|
778
|
+
const queryClient = useQueryClient();
|
|
779
|
+
const hasAdminList = !!SL?.facets?.list;
|
|
780
|
+
const hasPublicList = !!SL?.facets?.publicList;
|
|
781
|
+
const hasAnyList = hasAdminList || hasPublicList;
|
|
782
|
+
const queryEnabled = enabled && !!collectionId && hasAnyList;
|
|
783
|
+
const query = useQuery({
|
|
784
|
+
queryKey: [...QK, collectionId],
|
|
785
|
+
enabled: queryEnabled,
|
|
786
|
+
staleTime: 3e4,
|
|
787
|
+
queryFn: async () => {
|
|
788
|
+
const t0 = performance.now();
|
|
789
|
+
try {
|
|
790
|
+
if (SL?.facets?.list) {
|
|
791
|
+
console.info(`${LOG} \u2192 SL.facets.list("${collectionId}", { includeValues: true })`);
|
|
792
|
+
const res = await SL.facets.list(collectionId, { includeValues: true });
|
|
793
|
+
const items = res?.items ?? [];
|
|
794
|
+
console.info(
|
|
795
|
+
`${LOG} \u2190 SL.facets.list ok in ${Math.round(performance.now() - t0)}ms \u2014 ${items.length} facet(s)`,
|
|
796
|
+
items
|
|
797
|
+
);
|
|
798
|
+
return items;
|
|
799
|
+
}
|
|
800
|
+
if (SL?.facets?.publicList) {
|
|
801
|
+
console.info(`${LOG} \u2192 SL.facets.publicList("${collectionId}", { includeValues: true })`);
|
|
802
|
+
const res = await SL.facets.publicList(collectionId, { includeValues: true });
|
|
803
|
+
const items = res?.items ?? [];
|
|
804
|
+
console.info(
|
|
805
|
+
`${LOG} \u2190 SL.facets.publicList ok in ${Math.round(performance.now() - t0)}ms \u2014 ${items.length} facet(s)`,
|
|
806
|
+
items
|
|
807
|
+
);
|
|
808
|
+
return items;
|
|
809
|
+
}
|
|
810
|
+
console.warn(`${LOG} queryFn ran but no facets API is available on SL`);
|
|
811
|
+
return [];
|
|
812
|
+
} catch (err) {
|
|
813
|
+
console.error(`${LOG} \u2716 facets fetch failed`, err);
|
|
814
|
+
throw err;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
const lastLoggedRef = useRef("");
|
|
819
|
+
useEffect(() => {
|
|
820
|
+
const signature = `${enabled}|${collectionId}|${hasAdminList}|${hasPublicList}`;
|
|
821
|
+
if (signature === lastLoggedRef.current) return;
|
|
822
|
+
lastLoggedRef.current = signature;
|
|
823
|
+
if (!enabled) {
|
|
824
|
+
console.info(`${LOG} skipped \u2014 enabled=false (shell not on facet tab yet)`);
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
if (!collectionId) {
|
|
828
|
+
console.warn(`${LOG} skipped \u2014 no collectionId provided`);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if (!hasAnyList) {
|
|
832
|
+
console.warn(
|
|
833
|
+
`${LOG} skipped \u2014 SDK is missing both SL.facets.list and SL.facets.publicList. Update @proveanything/smartlinks (>=1.8) or check the SDK build.`,
|
|
834
|
+
{ facetsNamespace: SL?.facets ? Object.keys(SL.facets) : null }
|
|
835
|
+
);
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
console.info(
|
|
839
|
+
`${LOG} will fetch facets for collection "${collectionId}" via ${hasAdminList ? "SL.facets.list (admin)" : "SL.facets.publicList (fallback)"}`
|
|
840
|
+
);
|
|
841
|
+
}, [enabled, collectionId, hasAdminList, hasPublicList, hasAnyList, SL]);
|
|
842
|
+
const mergedItems = useMemo(() => {
|
|
843
|
+
const existingByRef = new Map(existing.map((item) => [item.ref, item]));
|
|
844
|
+
const scaffolded = (query.data ?? []).flatMap(
|
|
845
|
+
(facet) => (facet.values ?? []).filter((value) => !!facet.key && !!value.key).map((value) => {
|
|
846
|
+
const scaffold = toScaffoldSummary(facet, value);
|
|
847
|
+
return existingByRef.get(scaffold.ref) ?? scaffold;
|
|
848
|
+
})
|
|
849
|
+
);
|
|
850
|
+
const extras = existing.filter((item) => !scaffolded.some((scaffold) => scaffold.ref === item.ref));
|
|
851
|
+
return [...scaffolded, ...extras];
|
|
852
|
+
}, [existing, query.data]);
|
|
853
|
+
const filteredItems = useMemo(() => {
|
|
854
|
+
let next = mergedItems;
|
|
855
|
+
if (filter !== "all") next = next.filter((item) => item.status === filter);
|
|
856
|
+
if (search.trim()) {
|
|
857
|
+
const q = search.trim().toLowerCase();
|
|
858
|
+
next = next.filter((item) => `${item.label} ${item.subtitle ?? ""} ${item.ref}`.toLowerCase().includes(q));
|
|
859
|
+
}
|
|
860
|
+
return next;
|
|
861
|
+
}, [mergedItems, filter, search]);
|
|
862
|
+
const counts = useMemo(() => ({
|
|
863
|
+
all: mergedItems.length,
|
|
864
|
+
configured: mergedItems.filter((item) => item.status === "configured").length,
|
|
865
|
+
partial: mergedItems.filter((item) => item.status === "partial").length,
|
|
866
|
+
empty: mergedItems.filter((item) => item.status === "empty").length
|
|
867
|
+
}), [mergedItems]);
|
|
868
|
+
const refetch = () => {
|
|
869
|
+
queryClient.invalidateQueries({ queryKey: [...QK, collectionId] });
|
|
870
|
+
};
|
|
871
|
+
return {
|
|
872
|
+
items: filteredItems,
|
|
873
|
+
total: mergedItems.length,
|
|
874
|
+
counts,
|
|
875
|
+
isLoading: query.isLoading,
|
|
876
|
+
error: query.error ?? null,
|
|
877
|
+
refetch
|
|
878
|
+
};
|
|
879
|
+
};
|
|
880
|
+
var QK2 = ["records-admin", "product-browse"];
|
|
752
881
|
var toBrowseItem = (p) => ({
|
|
753
882
|
id: p.id ?? p.productId ?? "",
|
|
754
883
|
name: p.name ?? p.id ?? "Untitled",
|
|
@@ -759,12 +888,12 @@ var useProductBrowse = (args) => {
|
|
|
759
888
|
const { SL, collectionId, search = "", pageSize = 50, enabled = true, admin = true } = args;
|
|
760
889
|
const queryClient = useQueryClient();
|
|
761
890
|
const queryKey = useMemo(
|
|
762
|
-
() => [...
|
|
891
|
+
() => [...QK2, collectionId, search.trim(), pageSize, admin],
|
|
763
892
|
[collectionId, search, pageSize, admin]
|
|
764
893
|
);
|
|
765
894
|
const query = useInfiniteQuery({
|
|
766
895
|
queryKey,
|
|
767
|
-
enabled: enabled && !!collectionId && !!SL?.product?.query,
|
|
896
|
+
enabled: enabled && !!collectionId && !!(SL?.products?.query || SL?.product?.query || SL?.products?.list || SL?.product?.list),
|
|
768
897
|
initialPageParam: { offset: 0, cursor: null },
|
|
769
898
|
queryFn: async ({ pageParam }) => {
|
|
770
899
|
const body = {
|
|
@@ -772,7 +901,23 @@ var useProductBrowse = (args) => {
|
|
|
772
901
|
sort: [{ field: "sortOrder", direction: "asc" }, { field: "name", direction: "asc" }]
|
|
773
902
|
};
|
|
774
903
|
if (search.trim()) body.query = { search: search.trim() };
|
|
775
|
-
|
|
904
|
+
let res = null;
|
|
905
|
+
if (SL?.products?.query) {
|
|
906
|
+
res = await SL.products.query(collectionId, body);
|
|
907
|
+
} else if (SL?.product?.query) {
|
|
908
|
+
res = await SL.product.query(collectionId, body, admin);
|
|
909
|
+
} else {
|
|
910
|
+
const legacy = SL?.products?.list ? await SL.products.list(collectionId, admin) : SL?.product?.list ? await SL.product.list(collectionId, admin) : [];
|
|
911
|
+
const filteredLegacy = search.trim() ? legacy.filter((item) => `${item?.name ?? ""} ${item?.sku ?? ""} ${item?.id ?? ""}`.toLowerCase().includes(search.trim().toLowerCase())) : legacy;
|
|
912
|
+
const pageItems = filteredLegacy.slice(pageParam.offset, pageParam.offset + pageSize);
|
|
913
|
+
return {
|
|
914
|
+
items: pageItems.map(toBrowseItem),
|
|
915
|
+
nextOffset: pageParam.offset + pageItems.length,
|
|
916
|
+
nextCursor: null,
|
|
917
|
+
hasMore: pageParam.offset + pageItems.length < filteredLegacy.length,
|
|
918
|
+
total: filteredLegacy.length
|
|
919
|
+
};
|
|
920
|
+
}
|
|
776
921
|
const items2 = (res?.items ?? []).map(toBrowseItem);
|
|
777
922
|
const page = res?.page ?? {};
|
|
778
923
|
return {
|
|
@@ -794,7 +939,7 @@ var useProductBrowse = (args) => {
|
|
|
794
939
|
() => query.data?.pages.flatMap((p) => p.items) ?? [],
|
|
795
940
|
[query.data]
|
|
796
941
|
);
|
|
797
|
-
const refetch = () => queryClient.invalidateQueries({ queryKey: [...
|
|
942
|
+
const refetch = () => queryClient.invalidateQueries({ queryKey: [...QK2, collectionId] });
|
|
798
943
|
return {
|
|
799
944
|
items,
|
|
800
945
|
total: query.data?.pages[query.data.pages.length - 1]?.total,
|
|
@@ -806,7 +951,7 @@ var useProductBrowse = (args) => {
|
|
|
806
951
|
refetch
|
|
807
952
|
};
|
|
808
953
|
};
|
|
809
|
-
var
|
|
954
|
+
var QK3 = ["records-admin", "product-children"];
|
|
810
955
|
var variantToItem = (v) => ({
|
|
811
956
|
id: v.id ?? v.variantId ?? "",
|
|
812
957
|
name: v.name ?? v.label ?? v.id ?? "Untitled variant",
|
|
@@ -821,7 +966,7 @@ var useProductChildren = (args) => {
|
|
|
821
966
|
const { SL, collectionId, productId, kind, enabled = true } = args;
|
|
822
967
|
const queryClient = useQueryClient();
|
|
823
968
|
const queryKey = useMemo(
|
|
824
|
-
() => [...
|
|
969
|
+
() => [...QK3, collectionId, productId ?? null, kind],
|
|
825
970
|
[collectionId, productId, kind]
|
|
826
971
|
);
|
|
827
972
|
const query = useQuery({
|
|
@@ -839,7 +984,7 @@ var useProductChildren = (args) => {
|
|
|
839
984
|
}
|
|
840
985
|
});
|
|
841
986
|
const refetch = () => queryClient.invalidateQueries({
|
|
842
|
-
queryKey: [...
|
|
987
|
+
queryKey: [...QK3, collectionId, productId ?? null]
|
|
843
988
|
});
|
|
844
989
|
return {
|
|
845
990
|
items: query.data ?? [],
|
|
@@ -2035,7 +2180,9 @@ function ShellHeader({
|
|
|
2035
2180
|
recordType,
|
|
2036
2181
|
icons,
|
|
2037
2182
|
stats,
|
|
2038
|
-
statsItems
|
|
2183
|
+
statsItems,
|
|
2184
|
+
statsTitle,
|
|
2185
|
+
statsIcon
|
|
2039
2186
|
}) {
|
|
2040
2187
|
let iconNode = null;
|
|
2041
2188
|
if (showHeaderIcon) {
|
|
@@ -2059,6 +2206,7 @@ function ShellHeader({
|
|
|
2059
2206
|
return items;
|
|
2060
2207
|
})();
|
|
2061
2208
|
const hasStats = resolvedItems.length > 0;
|
|
2209
|
+
const hasStatsHeading = !!(statsTitle || statsIcon);
|
|
2062
2210
|
return /* @__PURE__ */ jsxs("header", { className: "ra-header", children: [
|
|
2063
2211
|
/* @__PURE__ */ jsxs("div", { className: "ra-header__main", children: [
|
|
2064
2212
|
iconNode ? /* @__PURE__ */ jsx("div", { className: "ra-header-icon", "aria-hidden": "true", children: iconNode }) : null,
|
|
@@ -2068,13 +2216,27 @@ function ShellHeader({
|
|
|
2068
2216
|
] })
|
|
2069
2217
|
] }),
|
|
2070
2218
|
/* @__PURE__ */ jsxs("div", { className: "ra-header-aside", children: [
|
|
2071
|
-
hasStats ? /* @__PURE__ */
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2219
|
+
hasStats ? /* @__PURE__ */ jsxs(
|
|
2220
|
+
"div",
|
|
2221
|
+
{
|
|
2222
|
+
className: `ra-header-stats${hasStatsHeading ? " ra-header-stats--titled" : ""}`,
|
|
2223
|
+
role: "group",
|
|
2224
|
+
"aria-label": statsTitle ?? "Record counts",
|
|
2225
|
+
children: [
|
|
2226
|
+
hasStatsHeading ? /* @__PURE__ */ jsxs("div", { className: "ra-stats-heading", children: [
|
|
2227
|
+
statsIcon ? /* @__PURE__ */ jsx("span", { className: "ra-stats-heading-icon", "aria-hidden": "true", children: statsIcon }) : null,
|
|
2228
|
+
statsTitle ? /* @__PURE__ */ jsx("span", { className: "ra-stats-heading-label", children: statsTitle }) : null
|
|
2229
|
+
] }) : null,
|
|
2230
|
+
/* @__PURE__ */ jsx("div", { className: "ra-stats-items", children: resolvedItems.map((item, idx) => /* @__PURE__ */ jsxs("span", { style: { display: "contents" }, children: [
|
|
2231
|
+
idx > 0 && /* @__PURE__ */ jsx("span", { className: "ra-stat-divider", "aria-hidden": "true" }),
|
|
2232
|
+
/* @__PURE__ */ jsxs("span", { className: "ra-stat", children: [
|
|
2233
|
+
/* @__PURE__ */ jsx("span", { className: "ra-stat-value", children: item.value }),
|
|
2234
|
+
/* @__PURE__ */ jsx("span", { className: "ra-stat-label", children: item.label })
|
|
2235
|
+
] })
|
|
2236
|
+
] }, `${item.label}-${idx}`)) })
|
|
2237
|
+
]
|
|
2238
|
+
}
|
|
2239
|
+
) : null,
|
|
2078
2240
|
headerActions ? /* @__PURE__ */ jsx("div", { className: "ra-header-actions", children: headerActions }) : null
|
|
2079
2241
|
] })
|
|
2080
2242
|
] });
|
|
@@ -2188,7 +2350,7 @@ var downloadBlob = (blob, filename) => {
|
|
|
2188
2350
|
styleInject(':root {\n --ra-status-own: var(--ra-emerald, 142 71% 45%);\n --ra-status-shared: var(--ra-amber, 38 92% 50%);\n --ra-status-missing: var(--muted-foreground, 220 9% 46%);\n --ra-accent: var(--primary, 222 47% 11%);\n --ra-surface: var(--card, 0 0% 100%);\n --ra-border: var(--border, 220 13% 91%);\n --ra-text: var(--foreground, 222 47% 11%);\n --ra-muted: var(--muted, 220 14% 96%);\n --ra-muted-text: var(--muted-foreground, 220 9% 46%);\n --ra-radius: var(--radius, 0.625rem);\n --ra-dot-size: 0.5rem;\n --ra-page-bg: var(--background, 220 14% 98%);\n --ra-card-shadow: 0 1px 2px hsl(var(--ra-accent) / 0.04), 0 4px 12px hsl(var(--ra-accent) / 0.05);\n --ra-card-shadow-hover: 0 2px 4px hsl(var(--ra-accent) / 0.06), 0 8px 24px hsl(var(--ra-accent) / 0.08);\n --ra-row-hover: hsl(var(--ra-accent) / 0.05);\n --ra-row-active-bg: hsl(var(--ra-accent) / 0.10);\n --ra-row-active-bd: hsl(var(--ra-accent) / 0.45);\n --ra-focus-ring: hsl(var(--ra-accent) / 0.35);\n --ra-font-display: var(--font-display, var(--font-sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif));\n --ra-font-ui: var(--font-sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);\n --ra-title-weight: 600;\n --ra-display-weight: 700;\n --ra-info: var(--ra-blue, 214 95% 55%);\n --ra-success: var(--ra-emerald, 142 71% 45%);\n --ra-warning: var(--ra-amber, 38 92% 50%);\n --ra-danger: var(--destructive, 0 72% 51%);\n}\n.ra-status-dot {\n display: inline-block;\n width: var(--ra-dot-size);\n height: var(--ra-dot-size);\n border-radius: 9999px;\n flex-shrink: 0;\n}\n.ra-status-own {\n background: hsl(var(--ra-status-own));\n}\n.ra-status-shared {\n background: hsl(var(--ra-status-shared));\n}\n.ra-status-missing {\n background: hsl(var(--ra-status-missing) / 0.4);\n border: 1px solid hsl(var(--ra-status-missing) / 0.6);\n}\n.ra-row-active {\n background: var(--ra-row-active-bg);\n border-color: var(--ra-row-active-bd) !important;\n}\n');
|
|
2189
2351
|
|
|
2190
2352
|
// src/components/RecordsAdmin/shell/shell.css
|
|
2191
|
-
styleInject(".ra-shell {\n color: hsl(var(--ra-text));\n background: hsl(var(--ra-page-bg));\n font-family: var(--ra-font-ui);\n}\n.ra-shell *,\n.ra-shell *::before,\n.ra-shell *::after {\n box-sizing: border-box;\n}\n.ra-shell .ra-card {\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: var(--ra-radius);\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-card-hover {\n transition:\n box-shadow .18s ease,\n transform .18s ease,\n border-color .18s ease;\n}\n.ra-shell .ra-card-hover:hover {\n box-shadow: var(--ra-card-shadow-hover);\n}\n.ra-shell .ra-display {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n letter-spacing: -0.01em;\n}\n.ra-shell .ra-title {\n font-weight: var(--ra-title-weight);\n}\n.ra-shell :where(button, [role=button], input, select, textarea, a):focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\n border-radius: calc(var(--ra-radius) * 0.6);\n}\n.ra-shell .ra-header {\n position: relative;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.65rem 0.9rem;\n border-radius: var(--ra-radius);\n border: 1px solid hsl(var(--ra-accent) / 0.12);\n background:\n linear-gradient(\n 135deg,\n hsl(var(--ra-accent) / 0.08),\n hsl(var(--ra-accent) / 0.02) 60%,\n hsl(var(--ra-surface)) 100%);\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-header__main {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 0.625rem;\n}\n.ra-shell .ra-header-aside {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.ra-shell .ra-header-icon {\n flex-shrink: 0;\n width: 2rem;\n height: 2rem;\n border-radius: calc(var(--ra-radius) * 0.9);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: hsl(var(--ra-accent) / 0.12);\n color: hsl(var(--ra-accent));\n border: 1px solid hsl(var(--ra-accent) / 0.18);\n}\n.ra-shell .ra-header-text {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-header-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 1rem;\n line-height: 1.2;\n color: hsl(var(--ra-text));\n letter-spacing: -0.01em;\n margin: 0;\n}\n.ra-shell .ra-header-subtitle {\n font-size: 0.75rem;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.125rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-header-stats {\n display: flex;\n align-items: stretch;\n gap: 0.15rem;\n padding: 0.15rem 0.4rem;\n border-radius: calc(var(--ra-radius) * 0.75);\n background: hsl(var(--ra-surface) / 0.7);\n border: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-stat {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 0.15rem 0.45rem;\n min-width: 2.5rem;\n}\n.ra-shell .ra-stat-value {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 0.85rem;\n color: hsl(var(--ra-text));\n line-height: 1;\n}\n.ra-shell .ra-stat-label {\n font-size: 0.6rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.15rem;\n}\n.ra-shell .ra-stat-divider {\n width: 1px;\n background: hsl(var(--ra-border));\n margin: 0.25rem 0;\n}\n.ra-shell .ra-header-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.ra-shell .ra-tabs {\n display: flex;\n gap: 0.25rem;\n padding: 0.25rem;\n background: hsl(var(--ra-muted));\n border-radius: calc(var(--ra-radius) * 0.85);\n border: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-tab {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.7rem;\n border-radius: calc(var(--ra-radius) * 0.65);\n font-size: 0.78rem;\n font-weight: 500;\n color: hsl(var(--ra-muted-text));\n background: transparent;\n border: 0;\n cursor: pointer;\n transition:\n background .15s ease,\n color .15s ease,\n transform .15s ease;\n white-space: nowrap;\n}\n.ra-shell .ra-tab:hover {\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-tab[aria-selected=true] {\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n box-shadow: var(--ra-card-shadow);\n font-weight: var(--ra-title-weight);\n}\n.ra-shell .ra-tab[aria-selected=true] .ra-tab-icon {\n color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-tab[disabled] {\n opacity: .5;\n cursor: not-allowed;\n}\n.ra-shell .ra-tab-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n padding: 0 0.35rem;\n height: 1.1rem;\n border-radius: 999px;\n background: hsl(var(--ra-accent) / 0.12);\n color: hsl(var(--ra-accent));\n font-size: 0.625rem;\n font-weight: 600;\n line-height: 1;\n}\n.ra-shell .ra-tab[aria-selected=false] .ra-tab-count {\n background: hsl(var(--ra-muted-text) / 0.15);\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell[data-density=compact] .ra-row {\n padding-block: 0.4rem;\n}\n.ra-shell[data-density=compact] .ra-header {\n padding: 0.75rem 1rem;\n}\n.ra-shell[data-density=compact] .ra-header-icon {\n width: 2.25rem;\n height: 2.25rem;\n}\n.ra-shell .ra-row {\n display: flex;\n align-items: center;\n gap: 0.65rem;\n width: 100%;\n text-align: left;\n padding: 0.65rem 0.85rem;\n border-left: 3px solid transparent;\n background: transparent;\n border-bottom: 1px solid transparent;\n transition: background .12s ease, border-color .12s ease;\n cursor: pointer;\n color: hsl(var(--ra-text));\n font-family: inherit;\n}\n.ra-shell .ra-row + .ra-row {\n border-top: 1px solid hsl(var(--ra-border) / 0.6);\n}\n.ra-shell .ra-row:hover {\n background: var(--ra-row-hover);\n}\n.ra-shell .ra-row[data-selected=true] {\n background: var(--ra-row-active-bg);\n border-left-color: var(--ra-row-active-bd);\n}\n.ra-shell .ra-row-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n border-radius: calc(var(--ra-radius) * 0.6);\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-muted-text));\n flex-shrink: 0;\n}\n.ra-shell .ra-row[data-selected=true] .ra-row-icon {\n background: hsl(var(--ra-accent) / 0.15);\n color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-row-body {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-row-title {\n font-weight: var(--ra-title-weight);\n font-size: 0.875rem;\n line-height: 1.25;\n color: hsl(var(--ra-text));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-row-sub {\n font-size: 0.75rem;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.15rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-row-actions {\n display: inline-flex;\n align-items: center;\n gap: 0.15rem;\n margin-left: auto;\n opacity: 0;\n transition: opacity .15s ease;\n}\n.ra-shell .ra-row:hover .ra-row-actions,\n.ra-shell .ra-row:focus-within .ra-row-actions {\n opacity: 1;\n}\n.ra-shell .ra-row-action {\n width: 1.6rem;\n height: 1.6rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 999px;\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border: 0;\n cursor: pointer;\n transition: background .15s ease, color .15s ease;\n}\n.ra-shell .ra-row-action:hover {\n background: hsl(var(--ra-accent) / 0.10);\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-row-action[data-tone=danger]:hover {\n background: hsl(var(--ra-danger) / 0.12);\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n padding: 0.15rem 0.5rem;\n border-radius: 999px;\n font-size: 0.6875rem;\n font-weight: 500;\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-muted-text));\n border: 1px solid hsl(var(--ra-border));\n white-space: nowrap;\n max-width: 14rem;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-chip[data-tone=success] {\n background: hsl(var(--ra-success) / 0.12);\n color: hsl(var(--ra-success));\n border-color: hsl(var(--ra-success) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=warning] {\n background: hsl(var(--ra-warning) / 0.14);\n color: hsl(var(--ra-warning));\n border-color: hsl(var(--ra-warning) / 0.35);\n}\n.ra-shell .ra-chip[data-tone=info] {\n background: hsl(var(--ra-info) / 0.10);\n color: hsl(var(--ra-info));\n border-color: hsl(var(--ra-info) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=danger] {\n background: hsl(var(--ra-danger) / 0.10);\n color: hsl(var(--ra-danger));\n border-color: hsl(var(--ra-danger) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=muted] {\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border-style: dashed;\n}\n.ra-shell .ra-group {\n border-bottom: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-group:last-child {\n border-bottom: 0;\n}\n.ra-shell .ra-group-summary {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.85rem;\n background: hsl(var(--ra-muted) / 0.6);\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: hsl(var(--ra-muted-text));\n border: 0;\n cursor: pointer;\n transition: background .12s ease;\n}\n.ra-shell .ra-group-summary:hover {\n background: hsl(var(--ra-muted));\n}\n.ra-shell .ra-group-summary .ra-group-chevron {\n transition: transform .15s ease;\n}\n.ra-shell .ra-group[data-open=false] .ra-group-chevron {\n transform: rotate(-90deg);\n}\n.ra-shell .ra-group-name {\n flex: 1;\n text-align: left;\n}\n.ra-shell .ra-group-count {\n font-size: 0.65rem;\n font-weight: 600;\n color: hsl(var(--ra-muted-text));\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: 999px;\n padding: 0.05rem 0.4rem;\n}\n.ra-shell .ra-group[data-open=false] .ra-group-body {\n display: none;\n}\n.ra-shell .ra-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 2.5rem 1.5rem;\n gap: 0.75rem;\n}\n.ra-shell .ra-empty-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 3.25rem;\n height: 3.25rem;\n border-radius: 999px;\n background: hsl(var(--ra-accent) / 0.08);\n color: hsl(var(--ra-accent));\n margin-bottom: 0.25rem;\n}\n.ra-shell .ra-empty-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 1rem;\n color: hsl(var(--ra-text));\n margin: 0;\n letter-spacing: -0.01em;\n}\n.ra-shell .ra-empty-body {\n font-size: 0.8125rem;\n color: hsl(var(--ra-muted-text));\n max-width: 22rem;\n line-height: 1.45;\n}\n.ra-shell .ra-empty-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-top: 0.25rem;\n flex-wrap: wrap;\n justify-content: center;\n}\n.ra-shell .ra-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.45rem 0.85rem;\n border-radius: calc(var(--ra-radius) * 0.7);\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid hsl(var(--ra-border));\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n cursor: pointer;\n transition:\n background .15s ease,\n border-color .15s ease,\n box-shadow .15s ease,\n transform .1s ease;\n}\n.ra-shell .ra-btn:hover {\n background: hsl(var(--ra-muted));\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-btn:active {\n transform: translateY(1px);\n}\n.ra-shell .ra-btn[data-variant=primary] {\n background: hsl(var(--ra-accent));\n color: hsl(var(--ra-surface));\n border-color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-btn[data-variant=primary]:hover {\n background: hsl(var(--ra-accent) / 0.92);\n}\n.ra-shell .ra-btn[data-variant=ghost] {\n background: transparent;\n border-color: transparent;\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell .ra-btn[data-variant=ghost]:hover {\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-btn[data-variant=danger] {\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-btn[data-variant=danger]:hover {\n background: hsl(var(--ra-danger) / 0.10);\n border-color: hsl(var(--ra-danger) / 0.40);\n}\n.ra-shell .ra-intro {\n position: relative;\n display: flex;\n gap: 0.85rem;\n padding: 0.9rem 1rem;\n border-radius: var(--ra-radius);\n border: 1px solid hsl(var(--ra-info) / 0.30);\n background: hsl(var(--ra-info) / 0.08);\n margin-bottom: 1rem;\n}\n.ra-shell .ra-intro[data-tone=success] {\n border-color: hsl(var(--ra-success) / 0.30);\n background: hsl(var(--ra-success) / 0.08);\n}\n.ra-shell .ra-intro[data-tone=warning] {\n border-color: hsl(var(--ra-warning) / 0.35);\n background: hsl(var(--ra-warning) / 0.10);\n}\n.ra-shell .ra-intro-icon {\n flex-shrink: 0;\n width: 2rem;\n height: 2rem;\n border-radius: 999px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: hsl(var(--ra-info) / 0.18);\n color: hsl(var(--ra-info));\n}\n.ra-shell .ra-intro[data-tone=success] .ra-intro-icon {\n background: hsl(var(--ra-success) / 0.18);\n color: hsl(var(--ra-success));\n}\n.ra-shell .ra-intro[data-tone=warning] .ra-intro-icon {\n background: hsl(var(--ra-warning) / 0.20);\n color: hsl(var(--ra-warning));\n}\n.ra-shell .ra-intro-body {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-intro-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-title-weight);\n font-size: 0.875rem;\n color: hsl(var(--ra-text));\n margin: 0 0 0.2rem 0;\n}\n.ra-shell .ra-intro-text {\n font-size: 0.8125rem;\n color: hsl(var(--ra-text) / 0.85);\n line-height: 1.45;\n}\n.ra-shell .ra-intro-dismiss {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n width: 1.6rem;\n height: 1.6rem;\n border-radius: 999px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 0;\n color: hsl(var(--ra-muted-text));\n cursor: pointer;\n}\n.ra-shell .ra-intro-dismiss:hover {\n background: hsl(var(--ra-text) / 0.06);\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-bulk-menu {\n min-width: 12rem;\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: calc(var(--ra-radius) * 0.85);\n box-shadow: var(--ra-card-shadow-hover);\n padding: 0.3rem;\n z-index: 30;\n}\n.ra-shell .ra-bulk-item {\n display: flex;\n align-items: center;\n gap: 0.55rem;\n width: 100%;\n padding: 0.45rem 0.6rem;\n border-radius: calc(var(--ra-radius) * 0.6);\n font-size: 0.8125rem;\n color: hsl(var(--ra-text));\n background: transparent;\n border: 0;\n cursor: pointer;\n text-align: left;\n transition: background .12s ease, color .12s ease;\n}\n.ra-shell .ra-bulk-item:hover {\n background: hsl(var(--ra-muted));\n}\n.ra-shell .ra-bulk-item[data-tone=danger] {\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-bulk-item[data-tone=danger]:hover {\n background: hsl(var(--ra-danger) / 0.10);\n}\n.ra-shell .ra-bulk-divider {\n height: 1px;\n background: hsl(var(--ra-border));\n margin: 0.25rem 0;\n}\n.ra-shell .ra-preview-rail {\n background: hsl(var(--ra-surface));\n border-left: 1px solid hsl(var(--ra-border));\n box-shadow: -4px 0 16px hsl(var(--ra-accent) / 0.04);\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n.ra-shell .ra-preview-rail-header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background:\n linear-gradient(\n 180deg,\n hsl(var(--ra-surface)) 0%,\n hsl(var(--ra-surface) / 0.92) 100%);\n border-bottom: 1px solid hsl(var(--ra-border));\n backdrop-filter: blur(6px);\n}\n.ra-shell .ra-preview-rail-title {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell .ra-preview-rail-body {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n}\n");
|
|
2353
|
+
styleInject(".ra-shell {\n color: hsl(var(--ra-text));\n background: hsl(var(--ra-page-bg));\n font-family: var(--ra-font-ui);\n}\n.ra-shell *,\n.ra-shell *::before,\n.ra-shell *::after {\n box-sizing: border-box;\n}\n.ra-shell .ra-card {\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: var(--ra-radius);\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-card-hover {\n transition:\n box-shadow .18s ease,\n transform .18s ease,\n border-color .18s ease;\n}\n.ra-shell .ra-card-hover:hover {\n box-shadow: var(--ra-card-shadow-hover);\n}\n.ra-shell .ra-display {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n letter-spacing: -0.01em;\n}\n.ra-shell .ra-title {\n font-weight: var(--ra-title-weight);\n}\n.ra-shell :where(button, [role=button], input, select, textarea, a):focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px var(--ra-focus-ring);\n border-radius: calc(var(--ra-radius) * 0.6);\n}\n.ra-shell .ra-header {\n position: relative;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.65rem 0.9rem;\n border-radius: var(--ra-radius);\n border: 1px solid hsl(var(--ra-accent) / 0.12);\n background:\n linear-gradient(\n 135deg,\n hsl(var(--ra-accent) / 0.08),\n hsl(var(--ra-accent) / 0.02) 60%,\n hsl(var(--ra-surface)) 100%);\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-header__main {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 0.625rem;\n}\n.ra-shell .ra-header-aside {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n.ra-shell .ra-header-icon {\n flex-shrink: 0;\n width: 2rem;\n height: 2rem;\n border-radius: calc(var(--ra-radius) * 0.9);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: hsl(var(--ra-accent) / 0.12);\n color: hsl(var(--ra-accent));\n border: 1px solid hsl(var(--ra-accent) / 0.18);\n}\n.ra-shell .ra-header-text {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-header-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 1rem;\n line-height: 1.2;\n color: hsl(var(--ra-text));\n letter-spacing: -0.01em;\n margin: 0;\n}\n.ra-shell .ra-header-subtitle {\n font-size: 0.75rem;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.125rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-header-stats {\n display: flex;\n align-items: stretch;\n gap: 0.15rem;\n padding: 0.15rem 0.4rem;\n border-radius: calc(var(--ra-radius) * 0.75);\n background: hsl(var(--ra-surface) / 0.7);\n border: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-header-stats--titled {\n flex-direction: column;\n align-items: stretch;\n padding: 0.4rem 0.55rem;\n gap: 0.3rem;\n}\n.ra-shell .ra-header-stats .ra-stats-items {\n display: flex;\n align-items: stretch;\n gap: 0.15rem;\n}\n.ra-shell .ra-header-stats .ra-stats-heading {\n display: flex;\n align-items: center;\n gap: 0.35rem;\n color: hsl(var(--ra-muted-text));\n font-size: 0.65rem;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n.ra-shell .ra-header-stats .ra-stats-heading-icon {\n display: inline-flex;\n align-items: center;\n color: hsl(var(--ra-text));\n opacity: 0.75;\n}\n.ra-shell .ra-header-stats .ra-stats-heading-icon > svg {\n width: 0.85rem;\n height: 0.85rem;\n}\n.ra-shell .ra-stat {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 0.15rem 0.45rem;\n min-width: 2.5rem;\n}\n.ra-shell .ra-stat-value {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 0.85rem;\n color: hsl(var(--ra-text));\n line-height: 1;\n}\n.ra-shell .ra-stat-label {\n font-size: 0.6rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.15rem;\n}\n.ra-shell .ra-stat-divider {\n width: 1px;\n background: hsl(var(--ra-border));\n margin: 0.25rem 0;\n}\n.ra-shell .ra-header-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.ra-shell .ra-tabs {\n display: flex;\n gap: 0.25rem;\n padding: 0.25rem;\n background: hsl(var(--ra-muted));\n border-radius: calc(var(--ra-radius) * 0.85);\n border: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-tab {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.7rem;\n border-radius: calc(var(--ra-radius) * 0.65);\n font-size: 0.78rem;\n font-weight: 500;\n color: hsl(var(--ra-muted-text));\n background: transparent;\n border: 0;\n cursor: pointer;\n transition:\n background .15s ease,\n color .15s ease,\n transform .15s ease;\n white-space: nowrap;\n}\n.ra-shell .ra-tab:hover {\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-tab[aria-selected=true] {\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n box-shadow: var(--ra-card-shadow);\n font-weight: var(--ra-title-weight);\n}\n.ra-shell .ra-tab[aria-selected=true] .ra-tab-icon {\n color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-tab[disabled] {\n opacity: .5;\n cursor: not-allowed;\n}\n.ra-shell .ra-tab-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n padding: 0 0.35rem;\n height: 1.1rem;\n border-radius: 999px;\n background: hsl(var(--ra-accent) / 0.12);\n color: hsl(var(--ra-accent));\n font-size: 0.625rem;\n font-weight: 600;\n line-height: 1;\n}\n.ra-shell .ra-tab[aria-selected=false] .ra-tab-count {\n background: hsl(var(--ra-muted-text) / 0.15);\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell[data-density=compact] .ra-row {\n padding-block: 0.4rem;\n}\n.ra-shell[data-density=compact] .ra-header {\n padding: 0.75rem 1rem;\n}\n.ra-shell[data-density=compact] .ra-header-icon {\n width: 2.25rem;\n height: 2.25rem;\n}\n.ra-shell .ra-row {\n display: flex;\n align-items: center;\n gap: 0.65rem;\n width: 100%;\n text-align: left;\n padding: 0.65rem 0.85rem;\n border-left: 3px solid transparent;\n background: transparent;\n border-bottom: 1px solid transparent;\n transition: background .12s ease, border-color .12s ease;\n cursor: pointer;\n color: hsl(var(--ra-text));\n font-family: inherit;\n}\n.ra-shell .ra-row + .ra-row {\n border-top: 1px solid hsl(var(--ra-border) / 0.6);\n}\n.ra-shell .ra-row:hover {\n background: var(--ra-row-hover);\n}\n.ra-shell .ra-row[data-selected=true] {\n background: var(--ra-row-active-bg);\n border-left-color: var(--ra-row-active-bd);\n}\n.ra-shell .ra-row-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n border-radius: calc(var(--ra-radius) * 0.6);\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-muted-text));\n flex-shrink: 0;\n}\n.ra-shell .ra-row[data-selected=true] .ra-row-icon {\n background: hsl(var(--ra-accent) / 0.15);\n color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-row-body {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-row-title {\n font-weight: var(--ra-title-weight);\n font-size: 0.875rem;\n line-height: 1.25;\n color: hsl(var(--ra-text));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-row-sub {\n font-size: 0.75rem;\n color: hsl(var(--ra-muted-text));\n margin-top: 0.15rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-row-actions {\n display: inline-flex;\n align-items: center;\n gap: 0.15rem;\n margin-left: auto;\n opacity: 0;\n transition: opacity .15s ease;\n}\n.ra-shell .ra-row:hover .ra-row-actions,\n.ra-shell .ra-row:focus-within .ra-row-actions {\n opacity: 1;\n}\n.ra-shell .ra-row-action {\n width: 1.6rem;\n height: 1.6rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 999px;\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border: 0;\n cursor: pointer;\n transition: background .15s ease, color .15s ease;\n}\n.ra-shell .ra-row-action:hover {\n background: hsl(var(--ra-accent) / 0.10);\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-row-action[data-tone=danger]:hover {\n background: hsl(var(--ra-danger) / 0.12);\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n padding: 0.15rem 0.5rem;\n border-radius: 999px;\n font-size: 0.6875rem;\n font-weight: 500;\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-muted-text));\n border: 1px solid hsl(var(--ra-border));\n white-space: nowrap;\n max-width: 14rem;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.ra-shell .ra-chip[data-tone=success] {\n background: hsl(var(--ra-success) / 0.12);\n color: hsl(var(--ra-success));\n border-color: hsl(var(--ra-success) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=warning] {\n background: hsl(var(--ra-warning) / 0.14);\n color: hsl(var(--ra-warning));\n border-color: hsl(var(--ra-warning) / 0.35);\n}\n.ra-shell .ra-chip[data-tone=info] {\n background: hsl(var(--ra-info) / 0.10);\n color: hsl(var(--ra-info));\n border-color: hsl(var(--ra-info) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=danger] {\n background: hsl(var(--ra-danger) / 0.10);\n color: hsl(var(--ra-danger));\n border-color: hsl(var(--ra-danger) / 0.30);\n}\n.ra-shell .ra-chip[data-tone=muted] {\n background: transparent;\n color: hsl(var(--ra-muted-text));\n border-style: dashed;\n}\n.ra-shell .ra-group {\n border-bottom: 1px solid hsl(var(--ra-border));\n}\n.ra-shell .ra-group:last-child {\n border-bottom: 0;\n}\n.ra-shell .ra-group-summary {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.85rem;\n background: hsl(var(--ra-muted) / 0.6);\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: hsl(var(--ra-muted-text));\n border: 0;\n cursor: pointer;\n transition: background .12s ease;\n}\n.ra-shell .ra-group-summary:hover {\n background: hsl(var(--ra-muted));\n}\n.ra-shell .ra-group-summary .ra-group-chevron {\n transition: transform .15s ease;\n}\n.ra-shell .ra-group[data-open=false] .ra-group-chevron {\n transform: rotate(-90deg);\n}\n.ra-shell .ra-group-name {\n flex: 1;\n text-align: left;\n}\n.ra-shell .ra-group-count {\n font-size: 0.65rem;\n font-weight: 600;\n color: hsl(var(--ra-muted-text));\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: 999px;\n padding: 0.05rem 0.4rem;\n}\n.ra-shell .ra-group[data-open=false] .ra-group-body {\n display: none;\n}\n.ra-shell .ra-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 2.5rem 1.5rem;\n gap: 0.75rem;\n}\n.ra-shell .ra-empty-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 3.25rem;\n height: 3.25rem;\n border-radius: 999px;\n background: hsl(var(--ra-accent) / 0.08);\n color: hsl(var(--ra-accent));\n margin-bottom: 0.25rem;\n}\n.ra-shell .ra-empty-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-display-weight);\n font-size: 1rem;\n color: hsl(var(--ra-text));\n margin: 0;\n letter-spacing: -0.01em;\n}\n.ra-shell .ra-empty-body {\n font-size: 0.8125rem;\n color: hsl(var(--ra-muted-text));\n max-width: 22rem;\n line-height: 1.45;\n}\n.ra-shell .ra-empty-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-top: 0.25rem;\n flex-wrap: wrap;\n justify-content: center;\n}\n.ra-shell .ra-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.45rem 0.85rem;\n border-radius: calc(var(--ra-radius) * 0.7);\n font-size: 0.8125rem;\n font-weight: 500;\n border: 1px solid hsl(var(--ra-border));\n background: hsl(var(--ra-surface));\n color: hsl(var(--ra-text));\n cursor: pointer;\n transition:\n background .15s ease,\n border-color .15s ease,\n box-shadow .15s ease,\n transform .1s ease;\n}\n.ra-shell .ra-btn:hover {\n background: hsl(var(--ra-muted));\n box-shadow: var(--ra-card-shadow);\n}\n.ra-shell .ra-btn:active {\n transform: translateY(1px);\n}\n.ra-shell .ra-btn[data-variant=primary] {\n background: hsl(var(--ra-accent));\n color: hsl(var(--ra-surface));\n border-color: hsl(var(--ra-accent));\n}\n.ra-shell .ra-btn[data-variant=primary]:hover {\n background: hsl(var(--ra-accent) / 0.92);\n}\n.ra-shell .ra-btn[data-variant=ghost] {\n background: transparent;\n border-color: transparent;\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell .ra-btn[data-variant=ghost]:hover {\n background: hsl(var(--ra-muted));\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-btn[data-variant=danger] {\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-btn[data-variant=danger]:hover {\n background: hsl(var(--ra-danger) / 0.10);\n border-color: hsl(var(--ra-danger) / 0.40);\n}\n.ra-shell .ra-intro {\n position: relative;\n display: flex;\n gap: 0.85rem;\n padding: 0.9rem 1rem;\n border-radius: var(--ra-radius);\n border: 1px solid hsl(var(--ra-info) / 0.30);\n background: hsl(var(--ra-info) / 0.08);\n margin-bottom: 1rem;\n}\n.ra-shell .ra-intro[data-tone=success] {\n border-color: hsl(var(--ra-success) / 0.30);\n background: hsl(var(--ra-success) / 0.08);\n}\n.ra-shell .ra-intro[data-tone=warning] {\n border-color: hsl(var(--ra-warning) / 0.35);\n background: hsl(var(--ra-warning) / 0.10);\n}\n.ra-shell .ra-intro-icon {\n flex-shrink: 0;\n width: 2rem;\n height: 2rem;\n border-radius: 999px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: hsl(var(--ra-info) / 0.18);\n color: hsl(var(--ra-info));\n}\n.ra-shell .ra-intro[data-tone=success] .ra-intro-icon {\n background: hsl(var(--ra-success) / 0.18);\n color: hsl(var(--ra-success));\n}\n.ra-shell .ra-intro[data-tone=warning] .ra-intro-icon {\n background: hsl(var(--ra-warning) / 0.20);\n color: hsl(var(--ra-warning));\n}\n.ra-shell .ra-intro-body {\n flex: 1;\n min-width: 0;\n}\n.ra-shell .ra-intro-title {\n font-family: var(--ra-font-display);\n font-weight: var(--ra-title-weight);\n font-size: 0.875rem;\n color: hsl(var(--ra-text));\n margin: 0 0 0.2rem 0;\n}\n.ra-shell .ra-intro-text {\n font-size: 0.8125rem;\n color: hsl(var(--ra-text) / 0.85);\n line-height: 1.45;\n}\n.ra-shell .ra-intro-dismiss {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n width: 1.6rem;\n height: 1.6rem;\n border-radius: 999px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 0;\n color: hsl(var(--ra-muted-text));\n cursor: pointer;\n}\n.ra-shell .ra-intro-dismiss:hover {\n background: hsl(var(--ra-text) / 0.06);\n color: hsl(var(--ra-text));\n}\n.ra-shell .ra-bulk-menu {\n min-width: 12rem;\n background: hsl(var(--ra-surface));\n border: 1px solid hsl(var(--ra-border));\n border-radius: calc(var(--ra-radius) * 0.85);\n box-shadow: var(--ra-card-shadow-hover);\n padding: 0.3rem;\n z-index: 30;\n}\n.ra-shell .ra-bulk-item {\n display: flex;\n align-items: center;\n gap: 0.55rem;\n width: 100%;\n padding: 0.45rem 0.6rem;\n border-radius: calc(var(--ra-radius) * 0.6);\n font-size: 0.8125rem;\n color: hsl(var(--ra-text));\n background: transparent;\n border: 0;\n cursor: pointer;\n text-align: left;\n transition: background .12s ease, color .12s ease;\n}\n.ra-shell .ra-bulk-item:hover {\n background: hsl(var(--ra-muted));\n}\n.ra-shell .ra-bulk-item[data-tone=danger] {\n color: hsl(var(--ra-danger));\n}\n.ra-shell .ra-bulk-item[data-tone=danger]:hover {\n background: hsl(var(--ra-danger) / 0.10);\n}\n.ra-shell .ra-bulk-divider {\n height: 1px;\n background: hsl(var(--ra-border));\n margin: 0.25rem 0;\n}\n.ra-shell .ra-preview-rail {\n background: hsl(var(--ra-surface));\n border-left: 1px solid hsl(var(--ra-border));\n box-shadow: -4px 0 16px hsl(var(--ra-accent) / 0.04);\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n}\n.ra-shell .ra-preview-rail-header {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background:\n linear-gradient(\n 180deg,\n hsl(var(--ra-surface)) 0%,\n hsl(var(--ra-surface) / 0.92) 100%);\n border-bottom: 1px solid hsl(var(--ra-border));\n backdrop-filter: blur(6px);\n}\n.ra-shell .ra-preview-rail-title {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n font-size: 0.7rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: hsl(var(--ra-muted-text));\n}\n.ra-shell .ra-preview-rail-body {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n}\n");
|
|
2192
2354
|
var TOP_LEVEL_SCOPES = ["product", "facet"];
|
|
2193
2355
|
var defaultItemId = () => {
|
|
2194
2356
|
const time = Date.now().toString(36);
|
|
@@ -2246,6 +2408,9 @@ function RecordsAdminShell(props) {
|
|
|
2246
2408
|
showStats = false,
|
|
2247
2409
|
showHeaderIcon = true,
|
|
2248
2410
|
statsItems,
|
|
2411
|
+
statsTitle,
|
|
2412
|
+
statsIcon,
|
|
2413
|
+
showHeader,
|
|
2249
2414
|
icons: iconsOverride,
|
|
2250
2415
|
groupBy,
|
|
2251
2416
|
renderEmptyState,
|
|
@@ -2335,6 +2500,14 @@ function RecordsAdminShell(props) {
|
|
|
2335
2500
|
contextScope,
|
|
2336
2501
|
enabled: activeScope === "facet" && !probe.isLoading
|
|
2337
2502
|
});
|
|
2503
|
+
const facetBrowse = useFacetBrowse({
|
|
2504
|
+
SL,
|
|
2505
|
+
collectionId,
|
|
2506
|
+
existing: recordList.allItems,
|
|
2507
|
+
search,
|
|
2508
|
+
filter,
|
|
2509
|
+
enabled: activeScope === "facet" && !probe.isLoading
|
|
2510
|
+
});
|
|
2338
2511
|
const variantChildren = useProductChildren({
|
|
2339
2512
|
SL,
|
|
2340
2513
|
collectionId,
|
|
@@ -2356,9 +2529,9 @@ function RecordsAdminShell(props) {
|
|
|
2356
2529
|
useEffect(() => {
|
|
2357
2530
|
if (activeScope !== "facet") return;
|
|
2358
2531
|
if (selectedFacetRef) return;
|
|
2359
|
-
const first =
|
|
2532
|
+
const first = facetBrowse.items[0];
|
|
2360
2533
|
if (first) setSelectedFacetRef(first.ref);
|
|
2361
|
-
}, [activeScope, selectedFacetRef,
|
|
2534
|
+
}, [activeScope, selectedFacetRef, facetBrowse.items]);
|
|
2362
2535
|
useEffect(() => {
|
|
2363
2536
|
setSearch("");
|
|
2364
2537
|
setFilter("all");
|
|
@@ -2395,9 +2568,10 @@ function RecordsAdminShell(props) {
|
|
|
2395
2568
|
const refetchAll = useCallback(() => {
|
|
2396
2569
|
productBrowse.refetch();
|
|
2397
2570
|
recordList.refetch();
|
|
2571
|
+
facetBrowse.refetch();
|
|
2398
2572
|
variantChildren.refetch();
|
|
2399
2573
|
batchChildren.refetch();
|
|
2400
|
-
}, [productBrowse, recordList, variantChildren, batchChildren]);
|
|
2574
|
+
}, [productBrowse, recordList, facetBrowse, variantChildren, batchChildren]);
|
|
2401
2575
|
const editorCtx = useRecordEditor({
|
|
2402
2576
|
ctx,
|
|
2403
2577
|
scope: editingScope ?? parseRef(""),
|
|
@@ -2555,9 +2729,9 @@ function RecordsAdminShell(props) {
|
|
|
2555
2729
|
}
|
|
2556
2730
|
return productBrowse.items.map(productItemToSummary);
|
|
2557
2731
|
}, [productPinned, contextScope, productBrowse.items]);
|
|
2558
|
-
const leftItems = isProductTab ? productListItems :
|
|
2559
|
-
const leftLoading = isProductTab ? !productPinned && productBrowse.isLoading : recordList.isLoading || probe.isLoading;
|
|
2560
|
-
const leftError = isProductTab ? productBrowse.error : recordList.error;
|
|
2732
|
+
const leftItems = isProductTab ? productListItems : facetBrowse.items;
|
|
2733
|
+
const leftLoading = isProductTab ? !productPinned && productBrowse.isLoading : facetBrowse.isLoading || recordList.isLoading || probe.isLoading;
|
|
2734
|
+
const leftError = isProductTab ? productBrowse.error : facetBrowse.error ?? recordList.error;
|
|
2561
2735
|
const leftSelectedRef = isProductTab ? selectedProductId ? buildRef({ productId: selectedProductId }) : void 0 : selectedFacetRef;
|
|
2562
2736
|
const onLeftSelect = (item) => {
|
|
2563
2737
|
void runWithGuard(() => {
|
|
@@ -2589,24 +2763,31 @@ function RecordsAdminShell(props) {
|
|
|
2589
2763
|
}
|
|
2590
2764
|
}
|
|
2591
2765
|
),
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2766
|
+
(() => {
|
|
2767
|
+
const headerCustomised = !!title || !!subtitle || !!headerIcon || !!headerActions || showStats || !!statsItems || !!statsTitle || !!statsIcon;
|
|
2768
|
+
const renderHeader = showHeader === true || showHeader !== false && headerCustomised;
|
|
2769
|
+
if (!renderHeader) return null;
|
|
2770
|
+
return /* @__PURE__ */ jsx(
|
|
2771
|
+
ShellHeader,
|
|
2772
|
+
{
|
|
2773
|
+
title: title ?? label ?? recordType ?? "",
|
|
2774
|
+
subtitle,
|
|
2775
|
+
headerIcon,
|
|
2776
|
+
headerActions,
|
|
2777
|
+
showStats,
|
|
2778
|
+
showHeaderIcon,
|
|
2779
|
+
recordType,
|
|
2780
|
+
icons,
|
|
2781
|
+
stats: {
|
|
2782
|
+
products: productBrowse.items.length,
|
|
2783
|
+
shared: recordList.items.length
|
|
2784
|
+
},
|
|
2785
|
+
statsItems,
|
|
2786
|
+
statsTitle,
|
|
2787
|
+
statsIcon
|
|
2788
|
+
}
|
|
2789
|
+
);
|
|
2790
|
+
})(),
|
|
2610
2791
|
/* @__PURE__ */ jsx(
|
|
2611
2792
|
UtilityRow,
|
|
2612
2793
|
{
|
|
@@ -2637,7 +2818,7 @@ function RecordsAdminShell(props) {
|
|
|
2637
2818
|
loading: probe.isLoading,
|
|
2638
2819
|
counts: {
|
|
2639
2820
|
product: productBrowse.items.length,
|
|
2640
|
-
facet:
|
|
2821
|
+
facet: facetBrowse.items.length
|
|
2641
2822
|
},
|
|
2642
2823
|
icons: icons.scope
|
|
2643
2824
|
}
|
|
@@ -2668,7 +2849,7 @@ function RecordsAdminShell(props) {
|
|
|
2668
2849
|
}
|
|
2669
2850
|
)
|
|
2670
2851
|
] }),
|
|
2671
|
-
!isProductTab && /* @__PURE__ */ jsx(StatusFilterPills, { value: filter, onChange: setFilter, counts:
|
|
2852
|
+
!isProductTab && /* @__PURE__ */ jsx(StatusFilterPills, { value: filter, onChange: setFilter, counts: facetBrowse.counts, i18n }),
|
|
2672
2853
|
cardinality === "collection" && !isProductTab && editingScope && /* @__PURE__ */ jsxs(
|
|
2673
2854
|
"button",
|
|
2674
2855
|
{
|
|
@@ -2698,8 +2879,8 @@ function RecordsAdminShell(props) {
|
|
|
2698
2879
|
EmptyState,
|
|
2699
2880
|
{
|
|
2700
2881
|
icon: search ? icons.empty.search : icons.empty.default,
|
|
2701
|
-
title: search ? i18n.noResults : i18n.
|
|
2702
|
-
body: search ? void 0 : i18n.
|
|
2882
|
+
title: search ? i18n.noResults : i18n.railEmptyTitle,
|
|
2883
|
+
body: search ? void 0 : i18n.railEmptyBody
|
|
2703
2884
|
}
|
|
2704
2885
|
)),
|
|
2705
2886
|
!leftLoading && !leftError && leftItems.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -3173,6 +3354,6 @@ function useMergedRecord(args) {
|
|
|
3173
3354
|
};
|
|
3174
3355
|
}
|
|
3175
3356
|
|
|
3176
|
-
export { ALL_PRESENTATIONS, BatchList, BulkActionsMenu, DEFAULT_I18N, DEFAULT_ICONS, DefaultRecordCard, DefaultRecordRow, DeleteButton, DrawerPreview, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, LoadingState, PresentationSwitcher, PreviewScopePicker, PreviewToggleButton, ProductDrillDown, ProductList, RecordBrowser, RecordEditor, RecordList, RecordsAdminShell, ResolvedPreview, ScopeBreadcrumb, ScopeTabs, SidePreview, StatusDot, StatusFilterPills, TabbedPreview, UtilityRow, VariantList, buildRef, bulkDelete, bulkUpsert, deleteRecord, downloadBlob, exportCsv, getRecordByRef, importCsv, listRecords, matchRecords, mergeIcons, parseRef, parsedRefToScope, parsedRefToTarget, pickHeaderIcon, resolutionChain, resolveRecord, restoreRecord, scopesEqual, upsertRecord, useCollectedRecords, useDirtyNavigation, useIntroDismissed, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeProbe, useUnsavedGuard };
|
|
3357
|
+
export { ALL_PRESENTATIONS, BatchList, BulkActionsMenu, DEFAULT_I18N, DEFAULT_ICONS, DefaultRecordCard, DefaultRecordRow, DeleteButton, DrawerPreview, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, LoadingState, PresentationSwitcher, PreviewScopePicker, PreviewToggleButton, ProductDrillDown, ProductList, RecordBrowser, RecordEditor, RecordList, RecordsAdminShell, ResolvedPreview, ScopeBreadcrumb, ScopeTabs, SidePreview, StatusDot, StatusFilterPills, TabbedPreview, UtilityRow, VariantList, buildRef, bulkDelete, bulkUpsert, deleteRecord, downloadBlob, exportCsv, getRecordByRef, importCsv, listRecords, matchRecords, mergeIcons, parseRef, parsedRefToScope, parsedRefToTarget, pickHeaderIcon, resolutionChain, resolveRecord, restoreRecord, scopesEqual, upsertRecord, useCollectedRecords, useDirtyNavigation, useFacetBrowse, useIntroDismissed, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeProbe, useUnsavedGuard };
|
|
3177
3358
|
//# sourceMappingURL=index.js.map
|
|
3178
3359
|
//# sourceMappingURL=index.js.map
|