@almadar/ui 5.127.0 → 5.129.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.
@@ -1,7 +1,8 @@
1
1
  import React__default, { ReactNode } from 'react';
2
2
  import { EntityRow, FieldValue } from '@almadar/core';
3
- import { U as UIThemeDefinition } from '../UserContext-BKckAUv7.js';
4
- export { A as ANONYMOUS_USER, a as CurrentPagePathContext, b as CurrentPagePathProvider, c as CurrentPagePathProviderProps, d as DesignThemeProvider, O as OrbitalThemeProvider, e as OrbitalThemeProviderProps, h as UserContext, i as UserContextValue, j as UserData, k as UserProvider, l as UserProviderProps, u as useCurrentPagePath, m as useDesignTheme, n as useHasPermission, o as useHasRole, q as useUser, r as useUserForEvaluation } from '../UserContext-BKckAUv7.js';
3
+ export { ANONYMOUS_USER } from '@almadar/core';
4
+ import { U as UIThemeDefinition, j as UserData } from '../UserContext-g_LcDiGN.js';
5
+ export { a as CurrentPagePathContext, b as CurrentPagePathProvider, c as CurrentPagePathProviderProps, d as DesignThemeProvider, O as OrbitalThemeProvider, e as OrbitalThemeProviderProps, h as UserContext, i as UserContextValue, k as UserProvider, l as UserProviderProps, u as useCurrentPagePath, m as useDesignTheme, n as useHasPermission, o as useHasRole, q as useUser, r as useUserForEvaluation } from '../UserContext-g_LcDiGN.js';
5
6
  export { E as EntitySchemaContextValue, a as EntitySchemaProvider, b as EntitySchemaProviderProps, S as SendEventResult, c as ServerBridgeContextValue, d as ServerBridgeProvider, e as ServerBridgeProviderProps, f as ServerBridgeTransport, g as ServerClientEffect, h as ServerResponseMeta, T as TraitContext, i as TraitContextValue, j as TraitInstance, k as TraitProvider, l as TraitProviderProps, u as useEntitySchema, m as useEntitySchemaOptional, n as useServerBridge, o as useTrait, p as useTraitContext } from '../TraitProvider-Ch79cUcb.js';
6
7
  import { U as UseOfflineExecutorResult, a as UseOfflineExecutorOptions } from '../offline-executor-Qz4b6GpF.js';
7
8
  export { N as NavigationContextValue, b as NavigationProvider, c as NavigationProviderProps, d as NavigationState, e as comparePathSpecificity, f as extractRouteParams, g as findPageByName, h as findPageByPath, i as getAllPages, j as getDefaultPage, m as matchPath, k as matchPathAmong, p as pathMatches, u as useActivePage, l as useInitPayload, n as useNavigateTo, o as useNavigation, q as useNavigationId, r as useNavigationState } from '../offline-executor-Qz4b6GpF.js';
@@ -145,6 +146,7 @@ declare function useSelectionOptional<T = EntityRow>(): SelectionContextType<T>
145
146
  * - ThemeProvider - Theme and color mode management
146
147
  * - EventBusProvider - Page-scoped event pub/sub
147
148
  * - SelectionProvider - Selected entity tracking
149
+ * - UserProvider - the viewer `@user.x` bindings resolve against
148
150
  *
149
151
  * Entity data flows through props (via enrichFromResponse in ServerBridge),
150
152
  * not through context. FetchedDataProvider has been removed.
@@ -188,6 +190,15 @@ interface OrbitalProviderProps {
188
190
  * preview's events don't clobber the host's global bus). Default false.
189
191
  */
190
192
  isolated?: boolean;
193
+ /**
194
+ * The signed-in viewer. Generated trait hooks read `@user.x` through
195
+ * `useUser()`, so without this every role gate takes its negative branch and
196
+ * every ownership-scoped list renders empty — silently, since `useUser()`
197
+ * falls back to anonymous rather than throwing
198
+ * (U-USERPROVIDER-MOUNTED-NOWHERE). Mounting the provider here means every
199
+ * host that already wraps its app in OrbitalProvider only has to pass the user.
200
+ */
201
+ user?: UserData | null;
191
202
  }
192
203
  /**
193
204
  * OrbitalProvider - Unified context provider for Orbital applications
@@ -236,7 +247,7 @@ interface OrbitalProviderProps {
236
247
  * }
237
248
  * ```
238
249
  */
239
- declare function OrbitalProvider({ children, themes, defaultTheme, defaultMode, targetRef, skipTheme, debug, initialData, suspense, verification, isolated, }: OrbitalProviderProps): React__default.ReactElement;
250
+ declare function OrbitalProvider({ children, themes, defaultTheme, defaultMode, targetRef, skipTheme, debug, initialData, suspense, verification, isolated, user, }: OrbitalProviderProps): React__default.ReactElement;
240
251
  declare namespace OrbitalProvider {
241
252
  var displayName: string;
242
253
  }
@@ -454,4 +465,4 @@ declare function useOfflineMode(): OfflineModeContextValue;
454
465
  */
455
466
  declare function useOptionalOfflineMode(): OfflineModeContextValue | null;
456
467
 
457
- export { EventBusContext, EventBusProvider, type OfflineModeContextValue, OfflineModeProvider, type OfflineModeProviderProps, OrbitalProvider, type OrbitalProviderProps, SelectionContext, type SelectionContextType, SelectionProvider, type TraitScope, TraitScopeProvider, type TraitScopeProviderProps, UIThemeDefinition, VerificationProvider, type VerificationProviderProps, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useTraitScope, useTraitScopeChain };
468
+ export { EventBusContext, EventBusProvider, type OfflineModeContextValue, OfflineModeProvider, type OfflineModeProviderProps, OrbitalProvider, type OrbitalProviderProps, SelectionContext, type SelectionContextType, SelectionProvider, type TraitScope, TraitScopeProvider, type TraitScopeProviderProps, UIThemeDefinition, UserData, VerificationProvider, type VerificationProviderProps, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useTraitScope, useTraitScopeChain };
@@ -68,7 +68,8 @@ import ReactMarkdown from 'react-markdown';
68
68
  import remarkGfm from 'remark-gfm';
69
69
  import remarkMath from 'remark-math';
70
70
  import rehypeKatex from 'rehype-katex';
71
- import { isInlineTrait } from '@almadar/core';
71
+ import { ANONYMOUS_USER, isInlineTrait } from '@almadar/core';
72
+ export { ANONYMOUS_USER } from '@almadar/core';
72
73
  import { DndContext, pointerWithin, rectIntersection, closestCorners, useSensors, useSensor, PointerSensor, KeyboardSensor, useDroppable } from '@dnd-kit/core';
73
74
  import { useSortable, arrayMove, sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
74
75
  import { CSS } from '@dnd-kit/utilities';
@@ -21993,7 +21994,7 @@ var init_DashboardLayout = __esm({
21993
21994
  ]
21994
21995
  }
21995
21996
  ),
21996
- user && /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
21997
+ user?.name && /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
21997
21998
  /* @__PURE__ */ jsxs(
21998
21999
  Button,
21999
22000
  {
@@ -27313,12 +27314,12 @@ var init_MapView = __esm({
27313
27314
  shadowSize: [41, 41]
27314
27315
  });
27315
27316
  L.Marker.prototype.options.icon = defaultIcon;
27316
- const { useEffect: useEffect62, useRef: useRef59, useCallback: useCallback93, useState: useState91 } = React84__default;
27317
+ const { useEffect: useEffect62, useRef: useRef60, useCallback: useCallback93, useState: useState91 } = React84__default;
27317
27318
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
27318
27319
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
27319
27320
  function MapUpdater({ centerLat, centerLng, zoom }) {
27320
27321
  const map = useMap();
27321
- const prevRef = useRef59({ centerLat, centerLng, zoom });
27322
+ const prevRef = useRef60({ centerLat, centerLng, zoom });
27322
27323
  useEffect62(() => {
27323
27324
  const prev = prevRef.current;
27324
27325
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
@@ -36508,6 +36509,290 @@ var init_GraphCanvas = __esm({
36508
36509
  GraphCanvas.displayName = "GraphCanvas";
36509
36510
  }
36510
36511
  });
36512
+ var ImportSourcePicker;
36513
+ var init_ImportSourcePicker = __esm({
36514
+ "components/core/molecules/import/ImportSourcePicker.tsx"() {
36515
+ "use client";
36516
+ init_Box();
36517
+ init_Icon();
36518
+ init_Typography();
36519
+ init_cn();
36520
+ ImportSourcePicker = ({
36521
+ sources,
36522
+ onSelect,
36523
+ onFilesSelected,
36524
+ title,
36525
+ moreSources,
36526
+ className
36527
+ }) => {
36528
+ const fileInputRef = useRef(null);
36529
+ const handlePick = (source) => {
36530
+ if (source.disabled) return;
36531
+ if (source.kind === "file") {
36532
+ const input = fileInputRef.current;
36533
+ if (!input) return;
36534
+ input.accept = source.accept ?? "";
36535
+ input.multiple = source.multiple ?? false;
36536
+ input.click();
36537
+ return;
36538
+ }
36539
+ onSelect?.(source.id);
36540
+ };
36541
+ const handleFiles = (event) => {
36542
+ const files = event.target.files ? Array.from(event.target.files) : [];
36543
+ event.target.value = "";
36544
+ if (files.length > 0) onFilesSelected?.(files);
36545
+ };
36546
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col gap-2", className), children: [
36547
+ title ? /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title }) : null,
36548
+ sources.map((source) => /* @__PURE__ */ jsxs(
36549
+ Box,
36550
+ {
36551
+ role: "button",
36552
+ tabIndex: source.disabled ? -1 : 0,
36553
+ "aria-disabled": source.disabled,
36554
+ onClick: () => handlePick(source),
36555
+ onKeyDown: (event) => {
36556
+ if (event.key === "Enter" || event.key === " ") {
36557
+ event.preventDefault();
36558
+ handlePick(source);
36559
+ }
36560
+ },
36561
+ className: cn(
36562
+ "flex items-center gap-3 rounded-md border border-border bg-card px-4 py-3 text-left",
36563
+ source.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-accent hover:text-accent-foreground"
36564
+ ),
36565
+ children: [
36566
+ source.icon ? /* @__PURE__ */ jsx(Icon, { icon: source.icon, size: "md" }) : null,
36567
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-col", children: [
36568
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: source.label }),
36569
+ source.description ? /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: source.description }) : null
36570
+ ] })
36571
+ ]
36572
+ },
36573
+ source.id
36574
+ )),
36575
+ moreSources,
36576
+ /* @__PURE__ */ jsx(
36577
+ "input",
36578
+ {
36579
+ ref: fileInputRef,
36580
+ type: "file",
36581
+ className: "hidden",
36582
+ onChange: handleFiles,
36583
+ "data-testid": "import-source-file-input"
36584
+ }
36585
+ )
36586
+ ] });
36587
+ };
36588
+ }
36589
+ });
36590
+ function formatFieldValue(value) {
36591
+ if (value === null) return "\u2014";
36592
+ if (value instanceof Date) return value.toISOString();
36593
+ if (Array.isArray(value)) return value.map(formatFieldValue).join(", ");
36594
+ if (typeof value === "object") return JSON.stringify(value);
36595
+ return String(value);
36596
+ }
36597
+ function unitTitle(unit) {
36598
+ for (const key of TITLE_KEYS) {
36599
+ const value = unit.fields[key];
36600
+ if (typeof value === "string" && value.length > 0) return value;
36601
+ }
36602
+ return unit.ref;
36603
+ }
36604
+ function fieldSummary(unit) {
36605
+ return Object.entries(unit.fields).filter(([key]) => !TITLE_KEYS.includes(key)).map(([key, value]) => `${key}: ${formatFieldValue(value)}`).join(" \xB7 ");
36606
+ }
36607
+ var TITLE_KEYS, ImportPreviewTree;
36608
+ var init_ImportPreviewTree = __esm({
36609
+ "components/core/molecules/import/ImportPreviewTree.tsx"() {
36610
+ "use client";
36611
+ init_Box();
36612
+ init_Badge();
36613
+ init_Button();
36614
+ init_Icon();
36615
+ init_Typography();
36616
+ init_cn();
36617
+ TITLE_KEYS = ["title", "name", "label"];
36618
+ ImportPreviewTree = ({
36619
+ units,
36620
+ skipped = [],
36621
+ entityDisplay,
36622
+ onConfirm,
36623
+ onCancel,
36624
+ confirmLabel = "Confirm import",
36625
+ cancelLabel = "Cancel",
36626
+ indent = 16,
36627
+ className
36628
+ }) => {
36629
+ const groups = /* @__PURE__ */ new Map();
36630
+ for (const unit of units) {
36631
+ const group = groups.get(unit.targetEntity);
36632
+ if (group) group.push(unit);
36633
+ else groups.set(unit.targetEntity, [unit]);
36634
+ }
36635
+ const renderUnit = (unit, childrenByParent, depth) => {
36636
+ const summary = fieldSummary(unit);
36637
+ const children = childrenByParent.get(unit.ref) ?? [];
36638
+ return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
36639
+ /* @__PURE__ */ jsxs(
36640
+ Box,
36641
+ {
36642
+ className: "flex flex-col py-1",
36643
+ style: { paddingLeft: depth * indent },
36644
+ "data-testid": `import-preview-unit-${unit.ref}`,
36645
+ children: [
36646
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
36647
+ /* @__PURE__ */ jsx(Icon, { icon: "file-text", size: "xs", className: "text-muted-foreground" }),
36648
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", children: unitTitle(unit) })
36649
+ ] }),
36650
+ summary ? /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: summary }) : null
36651
+ ]
36652
+ }
36653
+ ),
36654
+ children.map((child) => renderUnit(child, childrenByParent, depth + 1))
36655
+ ] }, unit.ref);
36656
+ };
36657
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col gap-4", className), children: [
36658
+ units.length === 0 ? /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: "No units staged." }) : null,
36659
+ Array.from(groups.entries()).map(([entity, groupUnits]) => {
36660
+ const refs = new Set(groupUnits.map((unit) => unit.ref));
36661
+ const childrenByParent = /* @__PURE__ */ new Map();
36662
+ const roots = [];
36663
+ for (const unit of groupUnits) {
36664
+ if (unit.parentRef && refs.has(unit.parentRef)) {
36665
+ const siblings = childrenByParent.get(unit.parentRef);
36666
+ if (siblings) siblings.push(unit);
36667
+ else childrenByParent.set(unit.parentRef, [unit]);
36668
+ } else {
36669
+ roots.push(unit);
36670
+ }
36671
+ }
36672
+ const label = entityDisplay[entity]?.plural ?? entity;
36673
+ return /* @__PURE__ */ jsxs(Box, { border: true, className: "rounded-md border-border bg-card p-3", children: [
36674
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2 pb-2", children: [
36675
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: label }),
36676
+ /* @__PURE__ */ jsx(Badge, { amount: groupUnits.length })
36677
+ ] }),
36678
+ roots.map((unit) => renderUnit(unit, childrenByParent, 0))
36679
+ ] }, entity);
36680
+ }),
36681
+ skipped.length > 0 ? /* @__PURE__ */ jsxs(Box, { border: true, className: "rounded-md border-border bg-card p-3", children: [
36682
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2 pb-2", children: [
36683
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: "Skipped" }),
36684
+ /* @__PURE__ */ jsx(Badge, { amount: skipped.length })
36685
+ ] }),
36686
+ skipped.map((element) => /* @__PURE__ */ jsxs(Box, { className: "flex items-baseline gap-2 py-1", children: [
36687
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", children: element.ref }),
36688
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: element.reason })
36689
+ ] }, element.ref))
36690
+ ] }) : null,
36691
+ onConfirm || onCancel ? /* @__PURE__ */ jsxs(Box, { className: "flex items-center justify-end gap-2", children: [
36692
+ onCancel ? /* @__PURE__ */ jsx(Button, { variant: "default", label: cancelLabel, onClick: onCancel }) : null,
36693
+ onConfirm ? /* @__PURE__ */ jsx(Button, { variant: "primary", label: confirmLabel, onClick: onConfirm }) : null
36694
+ ] }) : null
36695
+ ] });
36696
+ };
36697
+ }
36698
+ });
36699
+ var PIPELINE, DEFAULT_LABELS, ImportProgress;
36700
+ var init_ImportProgress = __esm({
36701
+ "components/core/molecules/import/ImportProgress.tsx"() {
36702
+ "use client";
36703
+ init_Box();
36704
+ init_Badge();
36705
+ init_Icon();
36706
+ init_Typography();
36707
+ init_cn();
36708
+ PIPELINE = [
36709
+ "fetching",
36710
+ "mapping",
36711
+ "reviewing",
36712
+ "committing"
36713
+ ];
36714
+ DEFAULT_LABELS = {
36715
+ fetching: "Fetching",
36716
+ mapping: "Mapping",
36717
+ reviewing: "Reviewing",
36718
+ committing: "Committing",
36719
+ done: "Done",
36720
+ failed: "Failed"
36721
+ };
36722
+ ImportProgress = ({
36723
+ step,
36724
+ counts,
36725
+ labels,
36726
+ className
36727
+ }) => {
36728
+ const label = (key) => labels?.[key] ?? DEFAULT_LABELS[key];
36729
+ const currentIndex = step === "done" || step === "failed" ? PIPELINE.length : PIPELINE.indexOf(step);
36730
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col gap-3", className), children: [
36731
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
36732
+ PIPELINE.map((key, index) => {
36733
+ const isComplete = index < currentIndex;
36734
+ const isActive = index === currentIndex;
36735
+ return /* @__PURE__ */ jsxs(React84__default.Fragment, { children: [
36736
+ index > 0 ? /* @__PURE__ */ jsx(Box, { className: "h-px w-4 bg-border" }) : null,
36737
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", "data-testid": `import-progress-step-${key}`, children: [
36738
+ /* @__PURE__ */ jsx(
36739
+ Icon,
36740
+ {
36741
+ icon: isComplete ? "check" : isActive ? "loader" : "circle",
36742
+ size: "sm",
36743
+ className: cn(
36744
+ isComplete ? "text-success" : isActive ? "text-primary" : "text-muted-foreground"
36745
+ )
36746
+ }
36747
+ ),
36748
+ /* @__PURE__ */ jsx(
36749
+ Typography,
36750
+ {
36751
+ variant: "caption",
36752
+ className: cn(isActive ? "text-foreground" : "text-muted-foreground"),
36753
+ children: label(key)
36754
+ }
36755
+ )
36756
+ ] })
36757
+ ] }, key);
36758
+ }),
36759
+ step === "done" || step === "failed" ? /* @__PURE__ */ jsxs(Fragment, { children: [
36760
+ /* @__PURE__ */ jsx(Box, { className: "h-px w-4 bg-border" }),
36761
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", "data-testid": `import-progress-step-${step}`, children: [
36762
+ /* @__PURE__ */ jsx(
36763
+ Icon,
36764
+ {
36765
+ icon: step === "done" ? "check" : "x",
36766
+ size: "sm",
36767
+ className: step === "done" ? "text-success" : "text-error"
36768
+ }
36769
+ ),
36770
+ /* @__PURE__ */ jsx(
36771
+ Typography,
36772
+ {
36773
+ variant: "caption",
36774
+ className: step === "done" ? "text-success" : "text-error",
36775
+ children: label(step)
36776
+ }
36777
+ )
36778
+ ] })
36779
+ ] }) : null
36780
+ ] }),
36781
+ counts ? /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
36782
+ counts.staged !== void 0 ? /* @__PURE__ */ jsx(Badge, { label: `Staged ${counts.staged}` }) : null,
36783
+ counts.committed !== void 0 ? /* @__PURE__ */ jsx(Badge, { variant: "success", label: `Committed ${counts.committed}` }) : null,
36784
+ counts.failed !== void 0 ? /* @__PURE__ */ jsx(Badge, { variant: "danger", label: `Failed ${counts.failed}` }) : null
36785
+ ] }) : null
36786
+ ] });
36787
+ };
36788
+ }
36789
+ });
36790
+
36791
+ // components/core/molecules/import/index.ts
36792
+ var init_import = __esm({
36793
+ "components/core/molecules/import/index.ts"() {
36794
+ }
36795
+ });
36511
36796
  var ReflectionBlock;
36512
36797
  var init_ReflectionBlock = __esm({
36513
36798
  "components/core/molecules/ReflectionBlock.tsx"() {
@@ -36582,6 +36867,7 @@ var init_molecules2 = __esm({
36582
36867
  init_EmptyState();
36583
36868
  init_Pagination();
36584
36869
  init_molecules();
36870
+ init_import();
36585
36871
  }
36586
36872
  });
36587
36873
 
@@ -37062,7 +37348,7 @@ function getBadgeVariant(fieldName, value) {
37062
37348
  function formatFieldLabel(fieldName) {
37063
37349
  return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase());
37064
37350
  }
37065
- function formatFieldValue(value, fieldName) {
37351
+ function formatFieldValue2(value, fieldName) {
37066
37352
  if (typeof value === "number") {
37067
37353
  if (fieldName.toLowerCase().includes("progress") || fieldName.toLowerCase().includes("percent")) {
37068
37354
  return `${value}%`;
@@ -37157,7 +37443,7 @@ function renderRichFieldValue(value, fieldName, fieldType) {
37157
37443
  return str;
37158
37444
  }
37159
37445
  default:
37160
- return formatFieldValue(value, fieldName);
37446
+ return formatFieldValue2(value, fieldName);
37161
37447
  }
37162
37448
  }
37163
37449
  function normalizeFieldDefs(fields) {
@@ -37268,7 +37554,7 @@ var init_DetailPanel = __esm({
37268
37554
  const value = getNestedValue(normalizedData, field);
37269
37555
  return {
37270
37556
  label: labelFor(field),
37271
- value: formatFieldValue(value, field),
37557
+ value: formatFieldValue2(value, field),
37272
37558
  icon: getFieldIcon(field)
37273
37559
  };
37274
37560
  }
@@ -43280,6 +43566,9 @@ var init_component_registry_generated = __esm({
43280
43566
  init_HeroOrganism();
43281
43567
  init_HeroSection();
43282
43568
  init_Icon();
43569
+ init_ImportPreviewTree();
43570
+ init_ImportProgress();
43571
+ init_ImportSourcePicker();
43283
43572
  init_InfiniteScrollSentinel();
43284
43573
  init_Input();
43285
43574
  init_InputGroup();
@@ -43543,6 +43832,9 @@ var init_component_registry_generated = __esm({
43543
43832
  "HeroOrganism": HeroOrganism,
43544
43833
  "HeroSection": HeroSection,
43545
43834
  "Icon": Icon,
43835
+ "ImportPreviewTree": ImportPreviewTree,
43836
+ "ImportProgress": ImportProgress,
43837
+ "ImportSourcePicker": ImportSourcePicker,
43546
43838
  "InfiniteScrollSentinel": InfiniteScrollSentinel,
43547
43839
  "Input": Input,
43548
43840
  "InputGroup": InputGroup,
@@ -45079,6 +45371,96 @@ function VerificationProvider({
45079
45371
  return /* @__PURE__ */ jsx(Fragment, { children });
45080
45372
  }
45081
45373
  VerificationProvider.displayName = "VerificationProvider";
45374
+ var UserContext = createContext(null);
45375
+ function UserProvider({
45376
+ user = null,
45377
+ children
45378
+ }) {
45379
+ const hasRole = useCallback(
45380
+ (role) => {
45381
+ if (!user) return role === "anonymous";
45382
+ return user.role === role;
45383
+ },
45384
+ [user]
45385
+ );
45386
+ const hasPermission = useCallback(
45387
+ (permission) => {
45388
+ if (!user) return false;
45389
+ return user.permissions?.includes(permission) ?? false;
45390
+ },
45391
+ [user]
45392
+ );
45393
+ const hasAnyRole = useCallback(
45394
+ (roles) => {
45395
+ if (!user) return roles.includes("anonymous");
45396
+ return user.role ? roles.includes(user.role) : false;
45397
+ },
45398
+ [user]
45399
+ );
45400
+ const hasAllPermissions = useCallback(
45401
+ (permissions) => {
45402
+ if (!user || !user.permissions) return false;
45403
+ return permissions.every((p) => user.permissions?.includes(p));
45404
+ },
45405
+ [user]
45406
+ );
45407
+ const getUserField = useCallback(
45408
+ (path) => {
45409
+ const viewer = user ?? ANONYMOUS_USER;
45410
+ const [first, ...rest] = path.split(".");
45411
+ if (!first) return void 0;
45412
+ let value = viewer[first];
45413
+ for (const segment of rest) {
45414
+ if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date) {
45415
+ return void 0;
45416
+ }
45417
+ value = value[segment];
45418
+ }
45419
+ return value;
45420
+ },
45421
+ [user]
45422
+ );
45423
+ const contextValue = useMemo(
45424
+ () => ({
45425
+ user,
45426
+ isLoggedIn: user !== null,
45427
+ hasRole,
45428
+ hasPermission,
45429
+ hasAnyRole,
45430
+ hasAllPermissions,
45431
+ getUserField
45432
+ }),
45433
+ [user, hasRole, hasPermission, hasAnyRole, hasAllPermissions, getUserField]
45434
+ );
45435
+ return /* @__PURE__ */ jsx(UserContext.Provider, { value: contextValue, children });
45436
+ }
45437
+ function useUser() {
45438
+ const context = useContext(UserContext);
45439
+ if (!context) {
45440
+ return {
45441
+ user: null,
45442
+ isLoggedIn: false,
45443
+ hasRole: (role) => role === "anonymous",
45444
+ hasPermission: () => false,
45445
+ hasAnyRole: (roles) => roles.includes("anonymous"),
45446
+ hasAllPermissions: () => false,
45447
+ getUserField: () => void 0
45448
+ };
45449
+ }
45450
+ return context;
45451
+ }
45452
+ function useHasRole(role) {
45453
+ const { hasRole } = useUser();
45454
+ return hasRole(role);
45455
+ }
45456
+ function useHasPermission(permission) {
45457
+ const { hasPermission } = useUser();
45458
+ return hasPermission(permission);
45459
+ }
45460
+ function useUserForEvaluation() {
45461
+ const { user, isLoggedIn } = useUser();
45462
+ return isLoggedIn && user ? user : void 0;
45463
+ }
45082
45464
  function OrbitalProvider({
45083
45465
  children,
45084
45466
  themes,
@@ -45090,13 +45472,14 @@ function OrbitalProvider({
45090
45472
  initialData,
45091
45473
  suspense = false,
45092
45474
  verification,
45093
- isolated = false
45475
+ isolated = false,
45476
+ user = null
45094
45477
  }) {
45095
45478
  const suspenseConfig = useMemo(
45096
45479
  () => ({ enabled: suspense }),
45097
45480
  [suspense]
45098
45481
  );
45099
- const inner = /* @__PURE__ */ jsx(EventBusProvider, { debug: debug2, isolated, children: /* @__PURE__ */ jsx(VerificationProvider, { enabled: verification, children: /* @__PURE__ */ jsx(SelectionProvider, { debug: debug2, children: /* @__PURE__ */ jsx(SuspenseConfigProvider, { config: suspenseConfig, children }) }) }) });
45482
+ const inner = /* @__PURE__ */ jsx(EventBusProvider, { debug: debug2, isolated, children: /* @__PURE__ */ jsx(VerificationProvider, { enabled: verification, children: /* @__PURE__ */ jsx(UserProvider, { user, children: /* @__PURE__ */ jsx(SelectionProvider, { debug: debug2, children: /* @__PURE__ */ jsx(SuspenseConfigProvider, { config: suspenseConfig, children }) }) }) }) });
45100
45483
  if (skipTheme) {
45101
45484
  return inner;
45102
45485
  }
@@ -45352,104 +45735,6 @@ var CurrentPagePathProvider = ({
45352
45735
  }) => /* @__PURE__ */ jsx(CurrentPagePathContext.Provider, { value, children });
45353
45736
  CurrentPagePathProvider.displayName = "CurrentPagePathProvider";
45354
45737
  var useCurrentPagePath2 = () => useContext(CurrentPagePathContext);
45355
- var ANONYMOUS_USER = {
45356
- id: "anonymous",
45357
- role: "anonymous",
45358
- permissions: []
45359
- };
45360
- var UserContext = createContext(null);
45361
- function UserProvider({
45362
- user = null,
45363
- children
45364
- }) {
45365
- const hasRole = useCallback(
45366
- (role) => {
45367
- if (!user) return role === "anonymous";
45368
- return user.role === role;
45369
- },
45370
- [user]
45371
- );
45372
- const hasPermission = useCallback(
45373
- (permission) => {
45374
- if (!user) return false;
45375
- return user.permissions?.includes(permission) ?? false;
45376
- },
45377
- [user]
45378
- );
45379
- const hasAnyRole = useCallback(
45380
- (roles) => {
45381
- if (!user) return roles.includes("anonymous");
45382
- return user.role ? roles.includes(user.role) : false;
45383
- },
45384
- [user]
45385
- );
45386
- const hasAllPermissions = useCallback(
45387
- (permissions) => {
45388
- if (!user || !user.permissions) return false;
45389
- return permissions.every((p) => user.permissions?.includes(p));
45390
- },
45391
- [user]
45392
- );
45393
- const getUserField = useCallback(
45394
- (path) => {
45395
- const userData = user ?? ANONYMOUS_USER;
45396
- const parts = path.split(".");
45397
- let value = userData;
45398
- for (const segment of parts) {
45399
- if (value === null || value === void 0) {
45400
- return void 0;
45401
- }
45402
- if (typeof value === "object") {
45403
- value = value[segment];
45404
- } else {
45405
- return void 0;
45406
- }
45407
- }
45408
- return value;
45409
- },
45410
- [user]
45411
- );
45412
- const contextValue = useMemo(
45413
- () => ({
45414
- user,
45415
- isLoggedIn: user !== null,
45416
- hasRole,
45417
- hasPermission,
45418
- hasAnyRole,
45419
- hasAllPermissions,
45420
- getUserField
45421
- }),
45422
- [user, hasRole, hasPermission, hasAnyRole, hasAllPermissions, getUserField]
45423
- );
45424
- return /* @__PURE__ */ jsx(UserContext.Provider, { value: contextValue, children });
45425
- }
45426
- function useUser() {
45427
- const context = useContext(UserContext);
45428
- if (!context) {
45429
- return {
45430
- user: null,
45431
- isLoggedIn: false,
45432
- hasRole: (role) => role === "anonymous",
45433
- hasPermission: () => false,
45434
- hasAnyRole: (roles) => roles.includes("anonymous"),
45435
- hasAllPermissions: () => false,
45436
- getUserField: () => void 0
45437
- };
45438
- }
45439
- return context;
45440
- }
45441
- function useHasRole(role) {
45442
- const { hasRole } = useUser();
45443
- return hasRole(role);
45444
- }
45445
- function useHasPermission(permission) {
45446
- const { hasPermission } = useUser();
45447
- return hasPermission(permission);
45448
- }
45449
- function useUserForEvaluation() {
45450
- const { user, isLoggedIn } = useUser();
45451
- return isLoggedIn && user ? user : void 0;
45452
- }
45453
45738
  var EntitySchemaContext = createContext(null);
45454
45739
  function EntitySchemaProvider({
45455
45740
  entities,
@@ -46165,4 +46450,4 @@ function GameAudioProvider2({
46165
46450
  }
46166
46451
  GameAudioProvider2.displayName = "GameAudioProvider";
46167
46452
 
46168
- export { ANONYMOUS_USER, CurrentPagePathContext, CurrentPagePathProvider, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, GameAudioContext2 as GameAudioContext, GameAudioProvider2 as GameAudioProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, comparePathSpecificity2 as comparePathSpecificity, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, matchPathAmong2 as matchPathAmong, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntitySchema, useEntitySchemaOptional6 as useEntitySchemaOptional, useGameAudioContext2 as useGameAudioContext, useGameAudioContextOptional2 as useGameAudioContextOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope, useTraitScopeChain2 as useTraitScopeChain, useUser, useUserForEvaluation };
46453
+ export { CurrentPagePathContext, CurrentPagePathProvider, EntitySchemaProvider, EventBusContext2 as EventBusContext, EventBusProvider, GameAudioContext2 as GameAudioContext, GameAudioProvider2 as GameAudioProvider, NavigationProvider2 as NavigationProvider, OfflineModeProvider, OrbitalProvider, OrbitalThemeProvider, SelectionContext, SelectionProvider, ServerBridgeProvider, TraitContext, TraitProvider, TraitScopeProvider3 as TraitScopeProvider, UserContext, UserProvider, VerificationProvider, comparePathSpecificity2 as comparePathSpecificity, extractRouteParams2 as extractRouteParams, findPageByName2 as findPageByName, findPageByPath2 as findPageByPath, getAllPages2 as getAllPages, getDefaultPage2 as getDefaultPage, matchPath2 as matchPath, matchPathAmong2 as matchPathAmong, pathMatches2 as pathMatches, useActivePage2 as useActivePage, useCurrentPagePath2 as useCurrentPagePath, useEntitySchema, useEntitySchemaOptional6 as useEntitySchemaOptional, useGameAudioContext2 as useGameAudioContext, useGameAudioContextOptional2 as useGameAudioContextOptional, useHasPermission, useHasRole, useInitPayload2 as useInitPayload, useNavigateTo2 as useNavigateTo, useNavigation2 as useNavigation, useNavigationId2 as useNavigationId, useNavigationState2 as useNavigationState, useOfflineMode, useOptionalOfflineMode, useSelection, useSelectionOptional, useServerBridge, useTrait, useTraitContext, useTraitScope, useTraitScopeChain2 as useTraitScopeChain, useUser, useUserForEvaluation };