@rebasepro/core 0.0.1-canary.eae7889 → 0.1.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.
Files changed (37) hide show
  1. package/dist/components/BootstrapAdminBanner.d.ts +4 -0
  2. package/dist/components/LoginView/LoginView.d.ts +22 -0
  3. package/dist/components/common/useDataTableController.d.ts +3 -3
  4. package/dist/components/index.d.ts +1 -0
  5. package/dist/hooks/data/useRelationSelector.d.ts +2 -2
  6. package/dist/hooks/index.d.ts +1 -0
  7. package/dist/hooks/useCollapsedGroups.d.ts +16 -1
  8. package/dist/hooks/useResolvedComponent.d.ts +47 -0
  9. package/dist/index.es.js +333 -121
  10. package/dist/index.es.js.map +1 -1
  11. package/dist/index.umd.js +330 -118
  12. package/dist/index.umd.js.map +1 -1
  13. package/dist/vitePlugin.d.ts +28 -1
  14. package/dist/vitePlugin.js +42 -0
  15. package/package.json +7 -8
  16. package/src/components/BootstrapAdminBanner.tsx +66 -0
  17. package/src/components/LoginView/LoginView.tsx +73 -42
  18. package/src/components/UserSelectPopover.tsx +8 -34
  19. package/src/components/common/useColumnsIds.tsx +16 -16
  20. package/src/components/common/useDataTableController.tsx +30 -18
  21. package/src/components/index.tsx +1 -1
  22. package/src/core/Rebase.tsx +20 -14
  23. package/src/hooks/data/useRelationSelector.tsx +6 -6
  24. package/src/hooks/index.tsx +1 -0
  25. package/src/hooks/useCollapsedGroups.ts +48 -6
  26. package/src/hooks/useRebaseContext.tsx +11 -6
  27. package/src/hooks/useResolvedComponent.tsx +157 -0
  28. package/src/hooks/useStudioBridge.tsx +2 -1
  29. package/src/locales/de.ts +4 -0
  30. package/src/locales/en.ts +6 -0
  31. package/src/locales/es.ts +4 -0
  32. package/src/locales/fr.ts +4 -0
  33. package/src/locales/hi.ts +4 -0
  34. package/src/locales/it.ts +4 -0
  35. package/src/locales/pt.ts +4 -0
  36. package/src/util/previews.ts +16 -7
  37. package/src/vitePlugin.ts +87 -1
package/dist/index.umd.js CHANGED
@@ -367,6 +367,9 @@
367
367
  const useAuthController = () => {
368
368
  return React.useContext(AuthControllerContext);
369
369
  };
370
+ function useRebaseClient() {
371
+ return React.useContext(RebaseClientInstanceContext);
372
+ }
370
373
  const useStorageSource = (collection) => {
371
374
  const defaultStorageSource = React.useContext(StorageSourceContext);
372
375
  if (collection?.overrides?.storageSource) {
@@ -422,6 +425,7 @@
422
425
  }
423
426
  const DatabaseAdminContext = React.createContext(void 0);
424
427
  const useRebaseContext = () => {
428
+ const client = useRebaseClient();
425
429
  const authController = useAuthController();
426
430
  const data = useData();
427
431
  const storageSource = useStorageSource();
@@ -444,7 +448,9 @@
444
448
  analyticsController,
445
449
  userManagement,
446
450
  effectiveRoleController,
447
- databaseAdmin
451
+ databaseAdmin,
452
+ client
453
+ // Client should be provided
448
454
  });
449
455
  React.useEffect(() => {
450
456
  rebaseContextRef.current = {
@@ -458,9 +464,10 @@
458
464
  analyticsController,
459
465
  userManagement,
460
466
  effectiveRoleController,
461
- databaseAdmin
467
+ databaseAdmin,
468
+ client
462
469
  };
463
- }, [authController, dialogsController, effectiveRoleController, data, databaseAdmin]);
470
+ }, [authController, data, storageSource, snackbarController, userConfigPersistence, dialogsController, customizationController, analyticsController, userManagement, effectiveRoleController, databaseAdmin, client]);
464
471
  return rebaseContextRef.current;
465
472
  };
466
473
  const CACHE = {};
@@ -570,7 +577,7 @@
570
577
  function useRelationSelector({
571
578
  path,
572
579
  collection,
573
- forceFilter,
580
+ fixedFilter,
574
581
  pageSize = DEFAULT_PAGE_SIZE$2,
575
582
  getLabelFromEntity,
576
583
  getDescriptionFromEntity,
@@ -631,8 +638,8 @@
631
638
  setError(void 0);
632
639
  setLoading(true);
633
640
  const whereMap = {};
634
- if (forceFilter) {
635
- Object.entries(forceFilter).forEach(([key, value]) => {
641
+ if (fixedFilter) {
642
+ Object.entries(fixedFilter).forEach(([key, value]) => {
636
643
  if (value && Array.isArray(value)) {
637
644
  const [op, val] = value;
638
645
  const postgrestOp = op === "==" ? "eq" : op === "!=" ? "neq" : op === ">" ? "gt" : op === ">=" ? "gte" : op === "<" ? "lt" : op === "<=" ? "lte" : op === "in" ? "in" : op === "not-in" ? "nin" : op === "array-contains" ? "cs" : op === "array-contains-any" ? "csa" : "eq";
@@ -679,7 +686,7 @@
679
686
  };
680
687
  }
681
688
  unsubscribeRef.current = unsubscribe || null;
682
- }, [dataClient, path, forceFilter, limit, currentSearch, entityToRelationItem, cleanupSubscription, setLoading]);
689
+ }, [dataClient, path, fixedFilter, limit, currentSearch, entityToRelationItem, cleanupSubscription, setLoading]);
683
690
  const search = React.useCallback((searchString) => {
684
691
  if (searchTimeoutRef.current) {
685
692
  clearTimeout(searchTimeoutRef.current);
@@ -1359,7 +1366,7 @@
1359
1366
  return window.matchMedia(`(min-width: ${breakpoints[breakpoint] + 1}px)`).matches;
1360
1367
  }
1361
1368
  const STORAGE_KEY_PREFIX = "rebase-collapsed-groups";
1362
- function useCollapsedGroups(groupNames, namespace = "default") {
1369
+ function useCollapsedGroups(groupNames, namespace = "default", defaults) {
1363
1370
  const storageKey = `${STORAGE_KEY_PREFIX}-${namespace}`;
1364
1371
  const [collapsedGroups, setCollapsedGroups] = React.useState(() => {
1365
1372
  try {
@@ -1389,19 +1396,42 @@
1389
1396
  });
1390
1397
  }, [groupNames]);
1391
1398
  const isGroupCollapsed = React.useCallback((name) => {
1392
- return !!collapsedGroups[name];
1393
- }, [collapsedGroups]);
1399
+ if (name in collapsedGroups) {
1400
+ return collapsedGroups[name];
1401
+ }
1402
+ return defaults?.[name] ?? false;
1403
+ }, [collapsedGroups, defaults]);
1394
1404
  const toggleGroupCollapsed = React.useCallback((name_0) => {
1395
- setCollapsedGroups((prev_0) => ({
1396
- ...prev_0,
1397
- [name_0]: !prev_0[name_0]
1398
- }));
1399
- }, []);
1405
+ setCollapsedGroups((prev_0) => {
1406
+ const currentlyCollapsed = name_0 in prev_0 ? prev_0[name_0] : defaults?.[name_0] ?? false;
1407
+ return {
1408
+ ...prev_0,
1409
+ [name_0]: !currentlyCollapsed
1410
+ };
1411
+ });
1412
+ }, [defaults]);
1400
1413
  return React.useMemo(() => ({
1401
1414
  isGroupCollapsed,
1402
1415
  toggleGroupCollapsed
1403
1416
  }), [isGroupCollapsed, toggleGroupCollapsed]);
1404
1417
  }
1418
+ function buildCollapsedDefaults(mappings, namespace) {
1419
+ if (!mappings) return {};
1420
+ const result = {};
1421
+ for (const mapping of mappings) {
1422
+ const val = mapping.collapsedByDefault;
1423
+ if (val === void 0) continue;
1424
+ if (typeof val === "boolean") {
1425
+ result[mapping.name] = val;
1426
+ } else {
1427
+ const ns = val[namespace];
1428
+ if (ns !== void 0) {
1429
+ result[mapping.name] = ns;
1430
+ }
1431
+ }
1432
+ }
1433
+ return result;
1434
+ }
1405
1435
  const rebaseLogo = "data:image/png;base64,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";
1406
1436
  function useBrowserTitleAndIcon(name, logo) {
1407
1437
  const $ = reactCompilerRuntime.c(4);
@@ -2155,8 +2185,58 @@
2155
2185
  t1 = t2;
2156
2186
  return t1;
2157
2187
  }
2158
- function useRebaseClient() {
2159
- return React.useContext(RebaseClientInstanceContext);
2188
+ const lazyCache = /* @__PURE__ */ new WeakMap();
2189
+ function useResolvedComponent(ref) {
2190
+ const $ = reactCompilerRuntime.c(2);
2191
+ let t0;
2192
+ let t1;
2193
+ if ($[0] !== ref) {
2194
+ t1 = resolveComponentRef(ref);
2195
+ $[0] = ref;
2196
+ $[1] = t1;
2197
+ } else {
2198
+ t1 = $[1];
2199
+ }
2200
+ t0 = t1;
2201
+ return t0;
2202
+ }
2203
+ function getOrCreateLazy(key, loader) {
2204
+ const cached = lazyCache.get(key);
2205
+ if (cached) return cached;
2206
+ const LazyComponent = React.lazy(loader);
2207
+ lazyCache.set(key, LazyComponent);
2208
+ return LazyComponent;
2209
+ }
2210
+ function resolveComponentRef(ref) {
2211
+ if (ref == null) return void 0;
2212
+ if (typeof ref === "string") {
2213
+ console.warn(`[Rebase] Encountered a raw string ComponentRef ("${ref}") at runtime. This usually means the Vite transform plugin did not process this file. Ensure the file is inside the configured collectionsDir.`);
2214
+ return void 0;
2215
+ }
2216
+ if (types.isLazyComponentRef(ref)) {
2217
+ return getOrCreateLazy(ref, () => ref.load());
2218
+ }
2219
+ if (typeof ref === "function") {
2220
+ const fn = ref;
2221
+ if (fn.prototype?.isReactComponent) {
2222
+ return ref;
2223
+ }
2224
+ if ("$$typeof" in fn) {
2225
+ return ref;
2226
+ }
2227
+ if (fn.length > 0) {
2228
+ return ref;
2229
+ }
2230
+ const name = fn.name;
2231
+ if (name && /^[A-Z]/.test(name)) {
2232
+ return ref;
2233
+ }
2234
+ return getOrCreateLazy(fn, ref);
2235
+ }
2236
+ if (typeof ref === "object" && "$$typeof" in ref) {
2237
+ return ref;
2238
+ }
2239
+ return void 0;
2160
2240
  }
2161
2241
  function ErrorTooltip(props) {
2162
2242
  const $ = reactCompilerRuntime.c(2);
@@ -2323,7 +2403,7 @@
2323
2403
  if (key.includes(".")) {
2324
2404
  const rootKey = key.split(".")[0];
2325
2405
  const rootProperty = collection.properties[rootKey];
2326
- if (rootProperty && rootProperty.type === "map" && rootProperty.spreadChildren && rootProperty.properties) {
2406
+ if (rootProperty && rootProperty.type === "map" && rootProperty.ui?.spreadChildren && rootProperty.properties) {
2327
2407
  rootsWithExplicitChildren.add(rootKey);
2328
2408
  }
2329
2409
  }
@@ -2334,9 +2414,9 @@
2334
2414
  const property = collection.properties[key];
2335
2415
  if (property) {
2336
2416
  processedPropertyKeys.add(key);
2337
- if (property.hideFromCollection) return [null];
2338
- if (property.disabled && typeof property.disabled === "object" && property.disabled.hidden) return [null];
2339
- if (property.type === "map" && property.spreadChildren && property.properties) {
2417
+ if (property.ui?.hideFromCollection) return [null];
2418
+ if (property.ui?.disabled && typeof property.ui?.disabled === "object" && property.ui?.disabled.hidden) return [null];
2419
+ if (property.type === "map" && property.ui?.spreadChildren && property.properties) {
2340
2420
  if (rootsWithExplicitChildren.has(key)) {
2341
2421
  return [null];
2342
2422
  }
@@ -2346,7 +2426,7 @@
2346
2426
  }
2347
2427
  return [{
2348
2428
  key,
2349
- disabled: Boolean(property.disabled) || Boolean(property.readOnly)
2429
+ disabled: Boolean(property.ui?.disabled) || Boolean(property.ui?.readOnly)
2350
2430
  }];
2351
2431
  }
2352
2432
  if (key.includes(".")) {
@@ -2357,11 +2437,11 @@
2357
2437
  if (nestedProperty) {
2358
2438
  processedPropertyKeys.add(key);
2359
2439
  processedPropertyKeys.add(rootKey);
2360
- if (nestedProperty.hideFromCollection) return [null];
2361
- if (nestedProperty.disabled && typeof nestedProperty.disabled === "object" && nestedProperty.disabled.hidden) return [null];
2440
+ if (nestedProperty.ui?.hideFromCollection) return [null];
2441
+ if (nestedProperty.ui?.disabled && typeof nestedProperty.ui?.disabled === "object" && nestedProperty.ui?.disabled.hidden) return [null];
2362
2442
  return [{
2363
2443
  key,
2364
- disabled: Boolean(rootProperty.disabled) || Boolean(rootProperty.readOnly) || Boolean(nestedProperty.disabled) || Boolean(nestedProperty.readOnly)
2444
+ disabled: Boolean(rootProperty.ui?.disabled) || Boolean(rootProperty.ui?.readOnly) || Boolean(nestedProperty.ui?.disabled) || Boolean(nestedProperty.ui?.readOnly)
2365
2445
  }];
2366
2446
  }
2367
2447
  }
@@ -2389,9 +2469,9 @@
2389
2469
  if (processedPropertyKeys.has(propKey)) continue;
2390
2470
  const property = collection.properties[propKey];
2391
2471
  if (!property) continue;
2392
- if (property.hideFromCollection) continue;
2393
- if (property.disabled && typeof property.disabled === "object" && property.disabled.hidden) continue;
2394
- if (property.type === "map" && property.spreadChildren && property.properties) {
2472
+ if (property.ui?.hideFromCollection) continue;
2473
+ if (property.ui?.disabled && typeof property.ui?.disabled === "object" && property.ui?.disabled.hidden) continue;
2474
+ if (property.type === "map" && property.ui?.spreadChildren && property.properties) {
2395
2475
  const allChildConfigs = getColumnKeysForProperty(property, propKey);
2396
2476
  for (const childConfig of allChildConfigs) {
2397
2477
  if (!processedPropertyKeys.has(childConfig.key)) {
@@ -2402,7 +2482,7 @@
2402
2482
  } else {
2403
2483
  result.push({
2404
2484
  key: propKey,
2405
- disabled: Boolean(property.disabled) || Boolean(property.readOnly)
2485
+ disabled: Boolean(property.ui?.disabled) || Boolean(property.ui?.readOnly)
2406
2486
  });
2407
2487
  processedPropertyKeys.add(propKey);
2408
2488
  }
@@ -2425,12 +2505,12 @@
2425
2505
  return hideAndExpandKeys(collection, columnIds);
2426
2506
  }
2427
2507
  function getColumnKeysForProperty(property, key, disabled) {
2428
- if (property.type === "map" && property.spreadChildren && property.properties) {
2429
- return Object.entries(property.properties).flatMap(([childKey, childProperty]) => getColumnKeysForProperty(childProperty, `${key}.${childKey}`, disabled || Boolean(property.disabled) || Boolean(property.readOnly)));
2508
+ if (property.type === "map" && property.ui?.spreadChildren && property.properties) {
2509
+ return Object.entries(property.properties).flatMap(([childKey, childProperty]) => getColumnKeysForProperty(childProperty, `${key}.${childKey}`, disabled || Boolean(property.ui?.disabled) || Boolean(property.ui?.readOnly)));
2430
2510
  }
2431
2511
  return [{
2432
2512
  key,
2433
- disabled: disabled || Boolean(property.disabled) || Boolean(property.readOnly)
2513
+ disabled: disabled || Boolean(property.ui?.disabled) || Boolean(property.ui?.readOnly)
2434
2514
  }];
2435
2515
  }
2436
2516
  function getFormFieldKeys(collection) {
@@ -2457,36 +2537,43 @@
2457
2537
  scrollRestoration,
2458
2538
  entitiesDisplayedFirst,
2459
2539
  lastDeleteTimestamp: _lastDeleteTimestamp,
2460
- forceFilter: forceFilterFromProps,
2540
+ fixedFilter: fixedFilterFromProps,
2461
2541
  updateUrl
2462
2542
  }) {
2463
2543
  const {
2464
- filter,
2544
+ defaultFilter,
2465
2545
  sort,
2466
- forceFilter: forceFilterFromCollection
2546
+ fixedFilter: fixedFilterFromCollection
2467
2547
  } = collection;
2468
2548
  const [popupCell, setPopupCell] = React.useState(void 0);
2469
2549
  const dataClient = useData();
2470
- const forceFilter = forceFilterFromProps ?? forceFilterFromCollection;
2550
+ const fixedFilter = fixedFilterFromProps ?? fixedFilterFromCollection;
2471
2551
  const paginationEnabled = collection.pagination === void 0 || Boolean(collection.pagination);
2472
2552
  const pageSize = typeof collection.pagination === "number" ? collection.pagination : DEFAULT_PAGE_SIZE;
2473
- const [searchString, setSearchString] = React.useState();
2553
+ const location = reactRouterDom.useLocation();
2554
+ const [searchString, setSearchString] = React.useState(() => {
2555
+ if (updateUrl) {
2556
+ const params = new URLSearchParams(location.search);
2557
+ const urlSearch = params.get("search");
2558
+ return urlSearch ? decodeURIComponent(urlSearch) : void 0;
2559
+ }
2560
+ return void 0;
2561
+ });
2474
2562
  const checkFilterCombination = React.useCallback((filterValues, sortBy) => {
2475
2563
  return true;
2476
2564
  }, []);
2477
2565
  const sortInternal = React.useMemo(() => {
2478
- if (sort && forceFilter && !checkFilterCombination(forceFilter, sort)) {
2566
+ if (sort && fixedFilter && !checkFilterCombination(fixedFilter, sort)) {
2479
2567
  console.warn("Initial sort is not compatible with the force filter. Ignoring initial sort");
2480
2568
  return void 0;
2481
2569
  }
2482
2570
  return sort;
2483
- }, [sort, forceFilter]);
2484
- const location = reactRouterDom.useLocation();
2571
+ }, [sort, fixedFilter]);
2485
2572
  const {
2486
2573
  filterValues: filterUrl,
2487
2574
  sortBy: sortUrl
2488
2575
  } = parseFilterAndSort(location.search);
2489
- const [filterValues_0, setFilterValues] = React.useState(forceFilter ?? (updateUrl ? filterUrl : void 0) ?? filter ?? void 0);
2576
+ const [filterValues_0, setFilterValues] = React.useState(fixedFilter ?? (updateUrl ? filterUrl : void 0) ?? defaultFilter ?? void 0);
2490
2577
  const [sortBy_0, setSortBy] = React.useState((updateUrl ? sortUrl : void 0) ?? sortInternal);
2491
2578
  const initialSearchRef = React.useRef(location.search);
2492
2579
  React.useEffect(() => {
@@ -2500,15 +2587,18 @@
2500
2587
  filterValues: urlFilterValues,
2501
2588
  sortBy: urlSortBy
2502
2589
  } = parseFilterAndSort(location.search);
2503
- if (!forceFilter) {
2590
+ if (!fixedFilter) {
2504
2591
  setFilterValues(urlFilterValues);
2505
2592
  }
2506
- if (urlSortBy && forceFilter && !checkFilterCombination(forceFilter, urlSortBy)) {
2593
+ if (urlSortBy && fixedFilter && !checkFilterCombination(fixedFilter, urlSortBy)) {
2507
2594
  console.warn("URL sort is not compatible with the force filter.");
2508
2595
  } else {
2509
2596
  setSortBy(urlSortBy);
2510
2597
  }
2511
- }, [location.search, updateUrl, forceFilter, checkFilterCombination]);
2598
+ const urlParams = new URLSearchParams(location.search);
2599
+ const urlSearch_0 = urlParams.get("search");
2600
+ setSearchString(urlSearch_0 ? decodeURIComponent(urlSearch_0) : void 0);
2601
+ }, [location.search, updateUrl, fixedFilter, checkFilterCombination]);
2512
2602
  useUpdateUrl(filterValues_0, sortBy_0, searchString, updateUrl);
2513
2603
  const collectionScroll = scrollRestoration?.getCollectionScroll(path, filterValues_0);
2514
2604
  const initialItemCount = collectionScroll?.data.length ?? pageSize;
@@ -2542,9 +2632,9 @@
2542
2632
  const [dataLoading, setDataLoading] = React.useState(false);
2543
2633
  const [dataLoadingError, setDataLoadingError] = React.useState();
2544
2634
  const [noMoreToLoad, setNoMoreToLoad] = React.useState(false);
2545
- const clearFilter = React.useCallback(() => setFilterValues(forceFilter ?? void 0), [forceFilter]);
2635
+ const clearFilter = React.useCallback(() => setFilterValues(fixedFilter ?? void 0), [fixedFilter]);
2546
2636
  const updateFilterValues = React.useCallback((updatedFilter) => {
2547
- if (forceFilter) {
2637
+ if (fixedFilter) {
2548
2638
  console.warn("Filter is not compatible with the force filter. Ignoring filter");
2549
2639
  return;
2550
2640
  }
@@ -2553,7 +2643,7 @@
2553
2643
  } else {
2554
2644
  setFilterValues(updatedFilter);
2555
2645
  }
2556
- }, [forceFilter]);
2646
+ }, [fixedFilter]);
2557
2647
  React.useEffect(() => {
2558
2648
  setDataLoading(true);
2559
2649
  const onEntitiesUpdate = async (entities) => {
@@ -6030,14 +6120,7 @@
6030
6120
  totalFilterable !== 1 ? "s" : ""
6031
6121
  ] })
6032
6122
  ] }),
6033
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls("px-2 py-1.5 border-b shrink-0", ui.defaultBorderMixin), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
6034
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { size: "smallest", className: "absolute left-2 top-1/2 -translate-y-1/2 text-text-disabled dark:text-text-disabled-dark pointer-events-none" }),
6035
- /* @__PURE__ */ jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: searchText, onChange: (e_0) => setSearchText(e_0.target.value), placeholder: "SearchIcon by name, email, or role…", className: ui.cls("w-full pl-7 pr-7 py-1.5 text-xs rounded-md", "bg-surface-100 dark:bg-surface-950 border", ui.defaultBorderMixin, "outline-none focus:ring-1 focus:ring-primary/40", "placeholder-text-disabled dark:placeholder-text-disabled-dark", "text-text-primary dark:text-text-primary-dark") }),
6036
- searchText && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => {
6037
- setSearchText("");
6038
- inputRef.current?.focus();
6039
- }, className: "absolute right-1.5 top-1/2 -translate-y-1/2 p-0.5 rounded hover:bg-surface-200 dark:hover:bg-surface-700 text-text-disabled", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { size: ui.iconSize.smallest }) })
6040
- ] }) }),
6123
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls("px-2 py-1.5 border-b shrink-0", ui.defaultBorderMixin), children: /* @__PURE__ */ jsxRuntime.jsx(ui.SearchBar, { inputRef, size: "smallest", placeholder: "Search by name, email, or role…", onTextSearch: (val) => setSearchText(val ?? "") }) }),
6041
6124
  /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: listRef, className: "overflow-y-auto overscroll-contain", style: {
6042
6125
  maxHeight: MAX_VISIBLE_ITEMS * ITEM_HEIGHT
6043
6126
  }, children: [
@@ -6325,7 +6408,7 @@
6325
6408
  t4 = $[2];
6326
6409
  }
6327
6410
  const caps = t4;
6328
- const isBootstrapMode = needsSetup ?? authController.needsSetup ?? false;
6411
+ const isBootstrapMode = needsSetup ?? ("needsSetup" in authController && !!authController.needsSetup) ?? false;
6329
6412
  const canRegister = registrationEnabled ?? caps.registration ?? false;
6330
6413
  const hasGoogleLogin = googleEnabled ?? caps.googleLogin ?? false;
6331
6414
  const hasPasswordReset = caps.passwordReset ?? !!authController.forgotPassword;
@@ -6411,7 +6494,7 @@
6411
6494
  const t8 = fadeIn ? "opacity-100" : "opacity-0";
6412
6495
  let t9;
6413
6496
  if ($[12] !== t8) {
6414
- t9 = ui.cls("relative flex items-center justify-center h-screen w-screen p-4 transition-opacity duration-500 bg-white dark:bg-surface-950", t8);
6497
+ t9 = ui.cls("relative flex items-center justify-center h-screen w-screen p-4 transition-opacity duration-500 bg-white dark:bg-surface-900", t8);
6415
6498
  $[12] = t8;
6416
6499
  $[13] = t9;
6417
6500
  } else {
@@ -6728,42 +6811,60 @@
6728
6811
  }
6729
6812
  return t4;
6730
6813
  }
6814
+ const GoogleIcon = () => {
6815
+ const $ = reactCompilerRuntime.c(1);
6816
+ let t0;
6817
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6818
+ t0 = /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", width: "20", height: "20", children: [
6819
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#4285F4", d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" }),
6820
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#34A853", d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" }),
6821
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#FBBC05", d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" }),
6822
+ /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#EA4335", d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" })
6823
+ ] });
6824
+ $[0] = t0;
6825
+ } else {
6826
+ t0 = $[0];
6827
+ }
6828
+ return t0;
6829
+ };
6731
6830
  function GoogleLoginButton(t0) {
6732
- const $ = reactCompilerRuntime.c(7);
6831
+ const $ = reactCompilerRuntime.c(10);
6733
6832
  const {
6734
6833
  disabled,
6735
6834
  googleClientId,
6736
6835
  authController
6737
6836
  } = t0;
6837
+ const codeClientRef = React.useRef(null);
6738
6838
  let t1;
6739
6839
  if ($[0] !== authController.googleLogin || $[1] !== googleClientId) {
6740
- t1 = async () => {
6840
+ t1 = () => {
6741
6841
  if (!authController.googleLogin) {
6742
6842
  return;
6743
6843
  }
6744
- try {
6745
- const google = window.google;
6746
- if (!google) {
6747
- console.error("Google Sign-In not loaded");
6748
- return;
6749
- }
6750
- google.accounts.id.initialize({
6751
- client_id: googleClientId,
6752
- callback: async (response) => {
6753
- ;
6754
- try {
6755
- await authController.googleLogin(response.credential);
6756
- } catch (t32) {
6757
- const err_0 = t32;
6758
- console.error("Google login error:", err_0);
6759
- }
6760
- }
6761
- });
6762
- google.accounts.id.prompt();
6763
- } catch (t22) {
6764
- const err = t22;
6765
- console.error("Google login error:", err);
6844
+ const google = window.google;
6845
+ if (!google || codeClientRef.current) {
6846
+ return;
6766
6847
  }
6848
+ codeClientRef.current = google.accounts.oauth2.initCodeClient({
6849
+ client_id: googleClientId,
6850
+ scope: "openid email profile",
6851
+ ux_mode: "popup",
6852
+ callback: async (response) => {
6853
+ if (response.error || !response.code) {
6854
+ console.error("Google login error:", response.error);
6855
+ return;
6856
+ }
6857
+ try {
6858
+ await authController.googleLogin({
6859
+ code: response.code,
6860
+ redirectUri: "postmessage"
6861
+ });
6862
+ } catch (t22) {
6863
+ const err = t22;
6864
+ console.error("Google login error:", err);
6865
+ }
6866
+ }
6867
+ });
6767
6868
  };
6768
6869
  $[0] = authController.googleLogin;
6769
6870
  $[1] = googleClientId;
@@ -6771,32 +6872,46 @@
6771
6872
  } else {
6772
6873
  t1 = $[2];
6773
6874
  }
6774
- const handleGoogleLogin = t1;
6775
6875
  let t2;
6776
- if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6777
- t2 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center w-full gap-3 py-1", children: [
6778
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", width: "20", height: "20", children: [
6779
- /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#4285F4", d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" }),
6780
- /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#34A853", d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" }),
6781
- /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#FBBC05", d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" }),
6782
- /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "#EA4335", d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" })
6783
- ] }),
6784
- /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "button", children: "Continue with Google" })
6785
- ] });
6786
- $[3] = t2;
6876
+ if ($[3] !== authController || $[4] !== googleClientId) {
6877
+ t2 = [googleClientId, authController];
6878
+ $[3] = authController;
6879
+ $[4] = googleClientId;
6880
+ $[5] = t2;
6787
6881
  } else {
6788
- t2 = $[3];
6882
+ t2 = $[5];
6789
6883
  }
6884
+ React.useEffect(t1, t2);
6790
6885
  let t3;
6791
- if ($[4] !== disabled || $[5] !== handleGoogleLogin) {
6792
- t3 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { disabled, className: "w-full", variant: "outlined", size: "large", onClick: handleGoogleLogin, children: t2 });
6793
- $[4] = disabled;
6794
- $[5] = handleGoogleLogin;
6886
+ if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6887
+ t3 = () => {
6888
+ if (!codeClientRef.current) {
6889
+ console.error("Google Sign-In not loaded");
6890
+ return;
6891
+ }
6892
+ codeClientRef.current.requestCode();
6893
+ };
6795
6894
  $[6] = t3;
6796
6895
  } else {
6797
6896
  t3 = $[6];
6798
6897
  }
6799
- return t3;
6898
+ const handleClick = t3;
6899
+ let t4;
6900
+ if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6901
+ t4 = /* @__PURE__ */ jsxRuntime.jsx(GoogleIcon, {});
6902
+ $[7] = t4;
6903
+ } else {
6904
+ t4 = $[7];
6905
+ }
6906
+ let t5;
6907
+ if ($[8] !== disabled) {
6908
+ t5 = /* @__PURE__ */ jsxRuntime.jsx(LoginButton, { disabled, text: "Sign in with Google", icon: t4, onClick: handleClick });
6909
+ $[8] = disabled;
6910
+ $[9] = t5;
6911
+ } else {
6912
+ t5 = $[9];
6913
+ }
6914
+ return t5;
6800
6915
  }
6801
6916
  function LoginForm(t0) {
6802
6917
  const $ = reactCompilerRuntime.c(67);
@@ -7014,7 +7129,7 @@
7014
7129
  const t22 = authController.authLoading || !email || !password;
7015
7130
  let t23;
7016
7131
  if ($[45] !== authController.authLoading || $[46] !== buttonLabel || $[47] !== t22) {
7017
- t23 = /* @__PURE__ */ jsxRuntime.jsx(ui.LoadingButton, { type: "submit", variant: "filled", className: "w-full mt-1", size: "large", loading: authController.authLoading, disabled: t22, children: buttonLabel });
7132
+ t23 = /* @__PURE__ */ jsxRuntime.jsx(ui.LoadingButton, { type: "submit", variant: "filled", color: "primary", className: "w-full mt-1", size: "large", loading: authController.authLoading, disabled: t22, children: buttonLabel });
7018
7133
  $[45] = authController.authLoading;
7019
7134
  $[46] = buttonLabel;
7020
7135
  $[47] = t22;
@@ -7337,6 +7452,58 @@
7337
7452
  React.useLayoutEffect(t1, t2);
7338
7453
  return null;
7339
7454
  }
7455
+ function BootstrapAdminBanner({
7456
+ className
7457
+ }) {
7458
+ const userManagement = useInternalUserManagementController();
7459
+ const {
7460
+ user: loggedInUser
7461
+ } = useAuthController();
7462
+ const {
7463
+ t
7464
+ } = useTranslation();
7465
+ const snackbarController = useSnackbarController();
7466
+ const [bootstrapping, setBootstrapping] = React.useState(false);
7467
+ if (typeof window !== "undefined" && window.location.hostname !== "localhost" && window.location.hostname !== "127.0.0.1") {
7468
+ return null;
7469
+ }
7470
+ if (!userManagement || !loggedInUser) {
7471
+ return null;
7472
+ }
7473
+ const {
7474
+ users,
7475
+ loading: delegateLoading,
7476
+ bootstrapAdmin,
7477
+ usersError
7478
+ } = userManagement;
7479
+ const hasAdmin = users.some((u) => u.roles?.includes("admin"));
7480
+ if (delegateLoading || hasAdmin || usersError || !bootstrapAdmin) {
7481
+ return null;
7482
+ }
7483
+ const handleBootstrap = async () => {
7484
+ if (!bootstrapAdmin) return;
7485
+ setBootstrapping(true);
7486
+ try {
7487
+ await bootstrapAdmin();
7488
+ snackbarController.open({
7489
+ type: "success",
7490
+ message: t("bootstrap_admin_success") || "Admin successfully created"
7491
+ });
7492
+ window.location.reload();
7493
+ } catch (error) {
7494
+ snackbarController.open({
7495
+ type: "error",
7496
+ message: error instanceof Error ? error.message : t("failed_to_bootstrap_admin") || "Failed to bootstrap admin"
7497
+ });
7498
+ } finally {
7499
+ setBootstrapping(false);
7500
+ }
7501
+ };
7502
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `bg-yellow-100 dark:bg-yellow-900 border border-yellow-400 dark:border-yellow-700 rounded p-4 flex items-center justify-between ${className || ""}`, children: [
7503
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "label", className: "text-yellow-800 dark:text-yellow-200", children: t("no_users_or_roles_defined") || "No admins found. Click to add your user as admin." }) }),
7504
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleBootstrap, disabled: bootstrapping, children: bootstrapping ? /* @__PURE__ */ jsxRuntime.jsx(ui.CircularProgress, { size: "small" }) : t("add_logged_user_as_admin") || "Add logged user as admin" })
7505
+ ] });
7506
+ }
7340
7507
  const en = {
7341
7508
  // ─── Form actions ────────────────────────────────────────────
7342
7509
  save: "Save",
@@ -7377,6 +7544,7 @@
7377
7544
  all_entries_loaded: "All {{count}} entries loaded",
7378
7545
  create_your_first_entry: "Create your first entry",
7379
7546
  no_results_filter_sort: "No results with the applied filter/sort",
7547
+ no_results_search: 'No results found for "{{search}}"',
7380
7548
  add: "Add",
7381
7549
  remove: "Remove",
7382
7550
  multiple_entities: "Multiple entities",
@@ -7780,6 +7948,10 @@
7780
7948
  reset_password: "Reset Password",
7781
7949
  reset_password_success: "Password reset successfully",
7782
7950
  reset_password_confirmation: "Are you sure you want to reset this user's password?",
7951
+ /** Permission-denied empty states */
7952
+ no_permission_to_view_users: "You don't have permission to view users",
7953
+ no_permission_to_view_roles: "You don't have permission to view roles",
7954
+ no_permission_description: "Contact an administrator if you need access to this section.",
7783
7955
  error_resetting_password: "Error resetting password",
7784
7956
  /** Editor table-bubble */
7785
7957
  add_row_before: "Add row before",
@@ -8245,6 +8417,7 @@
8245
8417
  all_entries_loaded: "Todas las {{count}} entradas cargadas",
8246
8418
  create_your_first_entry: "Crea tu primera entrada",
8247
8419
  no_results_filter_sort: "No hay resultados con el filtro/orden aplicado",
8420
+ no_results_search: 'No se encontraron resultados para "{{search}}"',
8248
8421
  add: "Añadir",
8249
8422
  remove: "Quitar",
8250
8423
  multiple_entities: "Múltiples entidades",
@@ -8324,6 +8497,9 @@
8324
8497
  delete_user_confirmation: "¿Estás seguro de que quieres eliminar a este usuario?",
8325
8498
  create_your_users_and_roles: "Crea tus usuarios y roles",
8326
8499
  no_users_or_roles_defined: "No tienes usuarios ni roles. Puedes crear los roles por defecto y añadirte a ti mismo como administrador.",
8500
+ no_permission_to_view_users: "No tienes permisos para ver los usuarios",
8501
+ no_permission_to_view_roles: "No tienes permisos para ver los roles",
8502
+ no_permission_description: "Contacta a un administrador si necesitas acceso a esta sección.",
8327
8503
  save_before_changing_schema: "Debes guardar el documento antes de cambiar el esquema",
8328
8504
  edit_schema_for_this_form: "Editar esquema para este formulario",
8329
8505
  no_permissions_to_edit_collection: "No tienes permisos para editar esta colección",
@@ -9087,6 +9263,7 @@
9087
9263
  all_entries_loaded: "Alle {{count}} Einträge geladen",
9088
9264
  create_your_first_entry: "Erstellen Sie Ihren ersten Eintrag",
9089
9265
  no_results_filter_sort: "Keine Ergebnisse mit angewendetem Filter/Sortierung",
9266
+ no_results_search: 'Keine Ergebnisse gefunden für "{{search}}"',
9090
9267
  add: "Hinzufügen",
9091
9268
  remove: "Entfernen",
9092
9269
  multiple_entities: "Mehrere Entitäten",
@@ -9168,6 +9345,9 @@
9168
9345
  delete_user_confirmation: "Sind Sie sicher, dass Sie diesen Benutzer löschen möchten?",
9169
9346
  create_your_users_and_roles: "Erstellen Sie Ihre Benutzer und Rollen",
9170
9347
  no_users_or_roles_defined: "Sie haben keine Benutzer oder Rollen definiert. Sie können Standardrollen erstellen und den aktuellen Benutzer als Administrator hinzufügen.",
9348
+ no_permission_to_view_users: "Sie haben keine Berechtigung, Benutzer anzuzeigen",
9349
+ no_permission_to_view_roles: "Sie haben keine Berechtigung, Rollen anzuzeigen",
9350
+ no_permission_description: "Wenden Sie sich an einen Administrator, wenn Sie Zugang zu diesem Bereich benötigen.",
9171
9351
  save_before_changing_schema: "Sie müssen das Dokument speichern, bevor Sie das Schema ändern können",
9172
9352
  edit_schema_for_this_form: "Schema für dieses Formular bearbeiten",
9173
9353
  no_permissions_to_edit_collection: "Sie haben keine Berechtigung, diese Sammlung zu bearbeiten",
@@ -9928,6 +10108,7 @@
9928
10108
  all_entries_loaded: "Toutes les {{count}} entrées chargées",
9929
10109
  create_your_first_entry: "Créez votre première entrée",
9930
10110
  no_results_filter_sort: "Aucun résultat avec le filtre/tri appliqué",
10111
+ no_results_search: 'Aucun résultat trouvé pour "{{search}}"',
9931
10112
  add: "Ajouter",
9932
10113
  remove: "Supprimer",
9933
10114
  multiple_entities: "Entités multiples",
@@ -10009,6 +10190,9 @@
10009
10190
  delete_user_confirmation: "Êtes-vous sûr de vouloir supprimer cet utilisateur ?",
10010
10191
  create_your_users_and_roles: "Créez vos utilisateurs et rôles",
10011
10192
  no_users_or_roles_defined: "Vous n'avez défini aucun utilisateur ni rôle. Vous pouvez créer les rôles par défaut et ajouter l'utilisateur actuel en tant qu'administrateur.",
10193
+ no_permission_to_view_users: "Vous n'avez pas la permission de voir les utilisateurs",
10194
+ no_permission_to_view_roles: "Vous n'avez pas la permission de voir les rôles",
10195
+ no_permission_description: "Contactez un administrateur si vous avez besoin d'accéder à cette section.",
10012
10196
  save_before_changing_schema: "Vous devez enregistrer le document avant de modifier le schéma",
10013
10197
  edit_schema_for_this_form: "Modifier le schéma de ce formulaire",
10014
10198
  no_permissions_to_edit_collection: "Vous n'avez pas l'autorisation de modifier cette collection",
@@ -10769,6 +10953,7 @@
10769
10953
  all_entries_loaded: "Tutte le {{count}} voci caricate",
10770
10954
  create_your_first_entry: "Crea la tua prima voce",
10771
10955
  no_results_filter_sort: "Nessun risultato con il filtro/ordinamento applicato",
10956
+ no_results_search: 'Nessun risultato trovato per "{{search}}"',
10772
10957
  add: "Aggiungi",
10773
10958
  remove: "Rimuovi",
10774
10959
  multiple_entities: "Entità multiple",
@@ -10850,6 +11035,9 @@
10850
11035
  delete_user_confirmation: "Sei sicuro di voler eliminare questo utente?",
10851
11036
  create_your_users_and_roles: "Crea i tuoi utenti e ruoli",
10852
11037
  no_users_or_roles_defined: "Non hai definito né utenti né ruoli. Puoi creare ruoli predefiniti e aggiungere l'utente corrente come amministratore.",
11038
+ no_permission_to_view_users: "Non hai i permessi per visualizzare gli utenti",
11039
+ no_permission_to_view_roles: "Non hai i permessi per visualizzare i ruoli",
11040
+ no_permission_description: "Contatta un amministratore se hai bisogno di accedere a questa sezione.",
10853
11041
  save_before_changing_schema: "Devi salvare il documento prima di modificare lo schema",
10854
11042
  edit_schema_for_this_form: "Modifica lo schema per questo modulo",
10855
11043
  no_permissions_to_edit_collection: "Non hai i permessi per modificare questa collezione",
@@ -11610,6 +11798,7 @@
11610
11798
  all_entries_loaded: "सभी {{count}} प्रविष्टियाँ लोड हो गईं",
11611
11799
  create_your_first_entry: "अपनी पहली प्रविष्टि बनाएं",
11612
11800
  no_results_filter_sort: "लागू किए गए फ़िल्टर/सॉर्ट के साथ कोई परिणाम नहीं",
11801
+ no_results_search: '"{{search}}" के लिए कोई परिणाम नहीं मिला',
11613
11802
  add: "जोड़ें",
11614
11803
  remove: "हटाएं",
11615
11804
  multiple_entities: "एकाधिक इकाइयां",
@@ -11691,6 +11880,9 @@
11691
11880
  delete_user_confirmation: "क्या आप वाकई इस उपयोगकर्ता को हटाना चाहते हैं?",
11692
11881
  create_your_users_and_roles: "अपने उपयोगकर्ता और भूमिकाएँ बनाएँ",
11693
11882
  no_users_or_roles_defined: "आपके पास कोई उपयोगकर्ता या भूमिका परिभाषित नहीं है। आप डिफ़ॉल्ट भूमिकाएँ बना सकते हैं और वर्तमान उपयोगकर्ता को एडमिन के रूप में जोड़ सकते हैं।",
11883
+ no_permission_to_view_users: "आपको उपयोगकर्ताओं को देखने की अनुमति नहीं है",
11884
+ no_permission_to_view_roles: "आपको भूमिकाओं को देखने की अनुमति नहीं है",
11885
+ no_permission_description: "यदि आपको इस अनुभाग तक पहुँच की आवश्यकता है तो किसी व्यवस्थापक से संपर्क करें।",
11694
11886
  save_before_changing_schema: "स्कीमा बदलने से पहले आपको दस्तावेज़ सहेजना होगा",
11695
11887
  edit_schema_for_this_form: "इस फॉर्म के लिए स्कीमा संपादित करें",
11696
11888
  no_permissions_to_edit_collection: "आपके पास इस संग्रह को संपादित करने की अनुमति नहीं है",
@@ -12451,6 +12643,7 @@
12451
12643
  all_entries_loaded: "Todos os {{count}} registos carregados",
12452
12644
  create_your_first_entry: "Crie o seu primeiro registo",
12453
12645
  no_results_filter_sort: "Sem resultados com o filtro/ordenação aplicado",
12646
+ no_results_search: 'Nenhum resultado encontrado para "{{search}}"',
12454
12647
  add: "Adicionar",
12455
12648
  remove: "Remover",
12456
12649
  multiple_entities: "Múltiplas entidades",
@@ -12532,6 +12725,9 @@
12532
12725
  delete_user_confirmation: "Tem a certeza de que quer eliminar este utilizador?",
12533
12726
  create_your_users_and_roles: "Crie os seus utilizadores e funções",
12534
12727
  no_users_or_roles_defined: "Não tem utilizadores ou funções definidas. Pode criar funções predefinidas e adicionar o utilizador atual como administrador.",
12728
+ no_permission_to_view_users: "Não tem permissão para ver os utilizadores",
12729
+ no_permission_to_view_roles: "Não tem permissão para ver as funções",
12730
+ no_permission_description: "Contacte um administrador se precisar de acesso a esta secção.",
12535
12731
  save_before_changing_schema: "Precisa de guardar o documento antes de alterar o esquema",
12536
12732
  edit_schema_for_this_form: "Editar esquema para este formulário",
12537
12733
  no_permissions_to_edit_collection: "Não tem permissões para editar esta coleção",
@@ -13424,18 +13620,19 @@
13424
13620
  }
13425
13621
  const ws = client?.ws;
13426
13622
  if (ws && typeof ws.executeSql === "function") {
13623
+ const wsAdmin = ws;
13427
13624
  return {
13428
- executeSql: ws.executeSql.bind(ws),
13429
- fetchAvailableDatabases: ws.fetchAvailableDatabases?.bind(ws),
13430
- fetchAvailableRoles: ws.fetchAvailableRoles?.bind(ws),
13431
- fetchCurrentDatabase: ws.fetchCurrentDatabase?.bind(ws),
13432
- fetchUnmappedTables: ws.fetchUnmappedTables?.bind(ws),
13433
- fetchTableMetadata: ws.fetchTableMetadata?.bind(ws),
13625
+ executeSql: wsAdmin.executeSql.bind(wsAdmin),
13626
+ fetchAvailableDatabases: wsAdmin.fetchAvailableDatabases?.bind(wsAdmin),
13627
+ fetchAvailableRoles: wsAdmin.fetchAvailableRoles?.bind(wsAdmin),
13628
+ fetchCurrentDatabase: wsAdmin.fetchCurrentDatabase?.bind(wsAdmin),
13629
+ fetchUnmappedTables: wsAdmin.fetchUnmappedTables?.bind(wsAdmin),
13630
+ fetchTableMetadata: wsAdmin.fetchTableMetadata?.bind(wsAdmin),
13434
13631
  // Branch admin capabilities
13435
- ...typeof ws.createBranch === "function" ? {
13436
- createBranch: ws.createBranch.bind(ws),
13437
- deleteBranch: ws.deleteBranch.bind(ws),
13438
- listBranches: ws.listBranches.bind(ws)
13632
+ ...typeof wsAdmin.createBranch === "function" ? {
13633
+ createBranch: wsAdmin.createBranch.bind(wsAdmin),
13634
+ deleteBranch: wsAdmin.deleteBranch.bind(wsAdmin),
13635
+ listBranches: wsAdmin.listBranches.bind(wsAdmin)
13439
13636
  } : {}
13440
13637
  };
13441
13638
  }
@@ -13497,7 +13694,9 @@
13497
13694
  }
13498
13695
  const childrenResult = t1;
13499
13696
  const plugins = customizationController.plugins;
13500
- if (!loading && plugins && plugins.length > 0) {
13697
+ const authController = context.authController;
13698
+ const authReady = !loading && !authController.authLoading && (Boolean(authController.user) || authController.loginSkipped);
13699
+ if (authReady && plugins && plugins.length > 0) {
13501
13700
  let t2;
13502
13701
  if ($[4] !== context) {
13503
13702
  t2 = {
@@ -14249,7 +14448,7 @@
14249
14448
  if (listProperties && listProperties.length > 0) {
14250
14449
  return listProperties;
14251
14450
  } else {
14252
- listProperties = allProperties;
14451
+ listProperties = targetCollection.propertiesOrder || allProperties;
14253
14452
  return listProperties.filter((key) => {
14254
14453
  const prop = targetCollection.properties[key];
14255
14454
  const isIdProp = prop && typeof prop === "object" && "isId" in prop && Boolean(prop.isId);
@@ -14264,16 +14463,24 @@
14264
14463
  if (collection.titleProperty) {
14265
14464
  return collection.titleProperty;
14266
14465
  }
14267
- for (const key in collection.properties) {
14466
+ const orderToSearch = collection.propertiesOrder || Object.keys(collection.properties);
14467
+ let firstStringCandidate;
14468
+ for (const key of orderToSearch) {
14268
14469
  const property = collection.properties[key];
14269
- if (!common.isPropertyBuilder(property)) {
14470
+ if (property && !common.isPropertyBuilder(property)) {
14270
14471
  const prop = property;
14271
- if (prop.type === "string" && !prop.multiline && !prop.markdown && !prop.storage && !prop.isId) {
14272
- return key;
14472
+ if (prop.type === "string" && !prop.ui?.multiline && !prop.ui?.markdown && !prop.storage && !prop.isId) {
14473
+ if (!firstStringCandidate) {
14474
+ firstStringCandidate = key;
14475
+ }
14476
+ const lowerKey = key.toLowerCase();
14477
+ if (["name", "title", "label", "displayname", "username"].includes(lowerKey)) {
14478
+ return key;
14479
+ }
14273
14480
  }
14274
14481
  }
14275
14482
  }
14276
- return void 0;
14483
+ return firstStringCandidate;
14277
14484
  }
14278
14485
  function getColorScheme(enumValues, key) {
14279
14486
  const labelOrConfig = common.getLabelOrConfigFrom(enumValues, key);
@@ -14465,7 +14672,8 @@
14465
14672
  getCollection: () => void 0,
14466
14673
  getRawCollection: () => void 0,
14467
14674
  getParentReferencesFromPath: () => [],
14468
- getParentCollectionIds: () => [],
14675
+ getParentCollectionSlugs: () => [],
14676
+ getParentEntityIds: () => [],
14469
14677
  convertIdsToPaths: () => [],
14470
14678
  initialised: false
14471
14679
  };
@@ -14613,6 +14821,7 @@
14613
14821
  exports2.AnalyticsContext = AnalyticsContext;
14614
14822
  exports2.ApiConfigProvider = ApiConfigProvider;
14615
14823
  exports2.AuthControllerContext = AuthControllerContext;
14824
+ exports2.BootstrapAdminBanner = BootstrapAdminBanner;
14616
14825
  exports2.CONTAINER_FULL_WIDTH = CONTAINER_FULL_WIDTH;
14617
14826
  exports2.ConfirmationDialog = ConfirmationDialog;
14618
14827
  exports2.CustomizationControllerContext = CustomizationControllerContext;
@@ -14656,6 +14865,7 @@
14656
14865
  exports2.UserDisplay = UserDisplay;
14657
14866
  exports2.UserSelectPopover = UserSelectPopover;
14658
14867
  exports2.UserSettingsView = UserSettingsView;
14868
+ exports2.buildCollapsedDefaults = buildCollapsedDefaults;
14659
14869
  exports2.buildEnumLabel = buildEnumLabel;
14660
14870
  exports2.clearEntityCache = clearEntityCache;
14661
14871
  exports2.createFormexStub = createFormexStub;
@@ -14681,6 +14891,7 @@
14681
14891
  exports2.printChanged = printChanged;
14682
14892
  exports2.removeEntityFromCache = removeEntityFromCache;
14683
14893
  exports2.removeEntityFromMemoryCache = removeEntityFromMemoryCache;
14894
+ exports2.resolveComponentRef = resolveComponentRef;
14684
14895
  exports2.saveEntityToCache = saveEntityToCache;
14685
14896
  exports2.saveEntityToMemoryCache = saveEntityToMemoryCache;
14686
14897
  exports2.saveEntityWithCallbacks = saveEntityWithCallbacks;
@@ -14716,6 +14927,7 @@
14716
14927
  exports2.useRebaseRegistry = useRebaseRegistry;
14717
14928
  exports2.useRebaseRegistryDispatch = useRebaseRegistryDispatch;
14718
14929
  exports2.useRelationSelector = useRelationSelector;
14930
+ exports2.useResolvedComponent = useResolvedComponent;
14719
14931
  exports2.useRestoreScroll = useRestoreScroll;
14720
14932
  exports2.useScrollRestoration = useScrollRestoration;
14721
14933
  exports2.useSlot = useSlot;