@judo/app-shell 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 (81) hide show
  1. package/LICENSE +277 -0
  2. package/README.md +186 -0
  3. package/dist/AppShell.d.ts +15 -0
  4. package/dist/AppShell.d.ts.map +1 -0
  5. package/dist/actors/ActorSelector.d.ts +8 -0
  6. package/dist/actors/ActorSelector.d.ts.map +1 -0
  7. package/dist/errors/AppErrorBoundary.d.ts +20 -0
  8. package/dist/errors/AppErrorBoundary.d.ts.map +1 -0
  9. package/dist/hooks/use-navigation-badge.d.ts +8 -0
  10. package/dist/hooks/use-navigation-badge.d.ts.map +1 -0
  11. package/dist/hooks/use-theme.d.ts +33 -0
  12. package/dist/hooks/use-theme.d.ts.map +1 -0
  13. package/dist/index.d.ts +38 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +2068 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/layout/AppBar.d.ts +19 -0
  18. package/dist/layout/AppBar.d.ts.map +1 -0
  19. package/dist/layout/AppShellLayout.d.ts +14 -0
  20. package/dist/layout/AppShellLayout.d.ts.map +1 -0
  21. package/dist/layout/Breadcrumbs.d.ts +8 -0
  22. package/dist/layout/Breadcrumbs.d.ts.map +1 -0
  23. package/dist/layout/Footer.d.ts +9 -0
  24. package/dist/layout/Footer.d.ts.map +1 -0
  25. package/dist/layout/PageDialogHost.d.ts +9 -0
  26. package/dist/layout/PageDialogHost.d.ts.map +1 -0
  27. package/dist/layout/layout-constants.d.ts +8 -0
  28. package/dist/layout/layout-constants.d.ts.map +1 -0
  29. package/dist/locale/LocaleSwitcher.d.ts +16 -0
  30. package/dist/locale/LocaleSwitcher.d.ts.map +1 -0
  31. package/dist/navigation/HorizontalNavigation.d.ts +14 -0
  32. package/dist/navigation/HorizontalNavigation.d.ts.map +1 -0
  33. package/dist/navigation/HorizontalNavigationItem.d.ts +20 -0
  34. package/dist/navigation/HorizontalNavigationItem.d.ts.map +1 -0
  35. package/dist/navigation/NavigationDrawer.d.ts +13 -0
  36. package/dist/navigation/NavigationDrawer.d.ts.map +1 -0
  37. package/dist/navigation/NavigationItemRenderer.d.ts +19 -0
  38. package/dist/navigation/NavigationItemRenderer.d.ts.map +1 -0
  39. package/dist/navigation/dashboard-utils.d.ts +8 -0
  40. package/dist/navigation/dashboard-utils.d.ts.map +1 -0
  41. package/dist/navigation/navigation-utils.d.ts +41 -0
  42. package/dist/navigation/navigation-utils.d.ts.map +1 -0
  43. package/dist/navigation/use-menu-operation-dispatch.d.ts +26 -0
  44. package/dist/navigation/use-menu-operation-dispatch.d.ts.map +1 -0
  45. package/dist/routes/DefaultGuestPage.d.ts +10 -0
  46. package/dist/routes/DefaultGuestPage.d.ts.map +1 -0
  47. package/dist/routes/DefaultSettingsPage.d.ts +9 -0
  48. package/dist/routes/DefaultSettingsPage.d.ts.map +1 -0
  49. package/dist/routes/PageRoute.d.ts +13 -0
  50. package/dist/routes/PageRoute.d.ts.map +1 -0
  51. package/dist/routes/RedirectPage.d.ts +12 -0
  52. package/dist/routes/RedirectPage.d.ts.map +1 -0
  53. package/dist/routes/generate-routes.d.ts +24 -0
  54. package/dist/routes/generate-routes.d.ts.map +1 -0
  55. package/dist/runtime/DefaultErrorScreen.d.ts +11 -0
  56. package/dist/runtime/DefaultErrorScreen.d.ts.map +1 -0
  57. package/dist/runtime/DefaultLoadingScreen.d.ts +5 -0
  58. package/dist/runtime/DefaultLoadingScreen.d.ts.map +1 -0
  59. package/dist/runtime/JudoRuntime.d.ts +27 -0
  60. package/dist/runtime/JudoRuntime.d.ts.map +1 -0
  61. package/dist/runtime/PrincipalBridge.d.ts +14 -0
  62. package/dist/runtime/PrincipalBridge.d.ts.map +1 -0
  63. package/dist/runtime/index.d.ts +5 -0
  64. package/dist/runtime/index.d.ts.map +1 -0
  65. package/dist/runtime/types.d.ts +308 -0
  66. package/dist/runtime/types.d.ts.map +1 -0
  67. package/dist/theme/ThemeProvider.d.ts +21 -0
  68. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  69. package/dist/theme/ThemeToggle.d.ts +11 -0
  70. package/dist/theme/ThemeToggle.d.ts.map +1 -0
  71. package/dist/theme/density.d.ts +19 -0
  72. package/dist/theme/density.d.ts.map +1 -0
  73. package/dist/theme/judo-theme-factory.d.ts +29 -0
  74. package/dist/theme/judo-theme-factory.d.ts.map +1 -0
  75. package/dist/theme/presets.d.ts +51 -0
  76. package/dist/theme/presets.d.ts.map +1 -0
  77. package/dist/user/DefaultHeroComponent.d.ts +11 -0
  78. package/dist/user/DefaultHeroComponent.d.ts.map +1 -0
  79. package/dist/user/UserMenu.d.ts +8 -0
  80. package/dist/user/UserMenu.d.ts.map +1 -0
  81. package/package.json +99 -0
package/dist/index.js ADDED
@@ -0,0 +1,2068 @@
1
+ import { Alert, AppBar as AppBar$1, Avatar, Badge, Box, Breadcrumbs as Breadcrumbs$1, Button, CircularProgress, Collapse, CssBaseline, Dialog, DialogActions, DialogContent, DialogTitle, Divider, Drawer, FormControl, IconButton, InputAdornment, InputLabel, Link, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Menu, MenuItem, Paper, Select, TextField, ThemeProvider as ThemeProvider$1, Toolbar, Tooltip, Typography, createTheme } from "@mui/material";
2
+ import * as React from "react";
3
+ import { Component, useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
+ import { BrowserRouter, HashRouter, MemoryRouter, Route, Routes, useLocation, useNavigate, useParams } from "react-router";
5
+ import { ApiProvider, createJudoRestApi, useActionDispatcher, useApi } from "@judo/actions";
6
+ import { ActorAuthBoundary, ActorSwitchDialog, JudoAuthProvider, PrincipalProvider, createOidcOptions, getAuthConfig, useActorSwitch, useAuth } from "@judo/auth";
7
+ import { ApplicationProvider, CustomizationsProvider, DataProvider, DispatchProvider, MuiProProvider, NavigationProvider, PageActionOverridesProvider, PageProvider, RuntimeConfigProvider, SelectorSelectionProvider, ValidationProvider, VisualPropertiesProvider, useApplication, useApplicationOptional, useCustomizationsOptional, useDataStore, useNavigation, useResolvedPageActionOverrides, useSelectorSelectionOptional, useValidationContextOptional } from "@judo/core";
8
+ import { ExpressionProvider } from "@judo/expressions";
9
+ import { FeedbackProvider, useNotifications } from "@judo/feedback";
10
+ import { I18nProvider, useLocaleOptional, useModelLabel } from "@judo/i18n";
11
+ import { EmbeddedModelLoader, HttpModelLoader, ModelRegistry } from "@judo/model-loader";
12
+ import { DialogSize, MenuLayout, PageContainerType } from "@judo/model-api";
13
+ import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
14
+ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
15
+ import SearchIcon from "@mui/icons-material/Search";
16
+ import { ButtonGroupRenderer, IconRenderer, PageRenderer, usePageTitle } from "@judo/components";
17
+ import { getActorSelectorTestId, getBreadcrumbTestId, getNavItemTestId, getUserMenuTestId } from "@judo/test-ids";
18
+ import ExpandLessIcon from "@mui/icons-material/ExpandLess";
19
+ import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
20
+ import FolderIcon from "@mui/icons-material/Folder";
21
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
22
+ import MenuIcon from "@mui/icons-material/Menu";
23
+ import LanguageIcon from "@mui/icons-material/Language";
24
+ import DarkModeIcon from "@mui/icons-material/DarkMode";
25
+ import LightModeIcon from "@mui/icons-material/LightMode";
26
+ import SettingsBrightnessIcon from "@mui/icons-material/SettingsBrightness";
27
+ import LogoutIcon from "@mui/icons-material/Logout";
28
+ import PersonIcon from "@mui/icons-material/Person";
29
+ import SettingsIcon from "@mui/icons-material/Settings";
30
+ import { useTranslation } from "react-i18next";
31
+ import RefreshIcon from "@mui/icons-material/Refresh";
32
+ import ErrorIcon from "@mui/icons-material/Error";
33
+ var __commonJSMin = (e, D) => () => (D || e((D = { exports: {} }).exports, D), D.exports), THEME_MODE_KEY = "theme-mode", THEME_SYSTEM_KEY = "theme-system";
34
+ function getInitialMode$1() {
35
+ if (typeof window > "u") return "light";
36
+ let e = localStorage.getItem(THEME_MODE_KEY);
37
+ return e === "light" || e === "dark" ? e : typeof window.matchMedia == "function" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
38
+ }
39
+ function getStoredSystemPreference() {
40
+ return typeof window > "u" ? !1 : localStorage.getItem(THEME_SYSTEM_KEY) === "true";
41
+ }
42
+ var localStore = new class {
43
+ config = {
44
+ mode: getInitialMode$1(),
45
+ isSystemMode: getStoredSystemPreference()
46
+ };
47
+ listeners = /* @__PURE__ */ new Set();
48
+ useSystemPreference = getStoredSystemPreference();
49
+ mediaQuery = null;
50
+ mediaQueryListener = null;
51
+ constructor() {
52
+ typeof window < "u" && typeof window.matchMedia == "function" && (this.mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"), this.useSystemPreference && this.startSystemPreferenceTracking());
53
+ }
54
+ subscribe = (e) => (this.listeners.add(e), () => this.listeners.delete(e));
55
+ getSnapshot = () => this.config;
56
+ getSystemPreference() {
57
+ return this.mediaQuery?.matches ? "dark" : "light";
58
+ }
59
+ startSystemPreferenceTracking() {
60
+ !this.mediaQuery || this.mediaQueryListener || (this.mediaQueryListener = (e) => {
61
+ if (this.useSystemPreference) {
62
+ let D = e.matches ? "dark" : "light";
63
+ this.config = {
64
+ ...this.config,
65
+ mode: D
66
+ };
67
+ for (let e of this.listeners) e();
68
+ }
69
+ }, this.mediaQuery.addEventListener("change", this.mediaQueryListener));
70
+ }
71
+ stopSystemPreferenceTracking() {
72
+ this.mediaQuery && this.mediaQueryListener && (this.mediaQuery.removeEventListener("change", this.mediaQueryListener), this.mediaQueryListener = null);
73
+ }
74
+ setTheme = (e) => {
75
+ e.__useSystemPreference !== void 0 && (this.useSystemPreference = e.__useSystemPreference, e.__useSystemPreference = void 0, this.useSystemPreference ? (this.startSystemPreferenceTracking(), e.mode = this.getSystemPreference(), e.isSystemMode = !0, localStorage.setItem(THEME_SYSTEM_KEY, "true"), localStorage.removeItem(THEME_MODE_KEY)) : (this.stopSystemPreferenceTracking(), e.isSystemMode = !1, localStorage.removeItem(THEME_SYSTEM_KEY))), this.config = {
76
+ ...this.config,
77
+ ...e
78
+ }, e.mode && !this.useSystemPreference && localStorage.setItem(THEME_MODE_KEY, e.mode);
79
+ for (let e of this.listeners) e();
80
+ };
81
+ cleanup = () => {
82
+ this.stopSystemPreferenceTracking();
83
+ };
84
+ }();
85
+ function hasUserThemePreference() {
86
+ return typeof window > "u" ? !1 : localStorage.getItem(THEME_MODE_KEY) !== null || localStorage.getItem(THEME_SYSTEM_KEY) !== null;
87
+ }
88
+ function initializeThemeStore(e, D = !1) {
89
+ if (hasUserThemePreference()) {
90
+ let { mode: D, ...O } = e;
91
+ localStore.setTheme(O);
92
+ } else localStore.setTheme({
93
+ ...e,
94
+ __useSystemPreference: D
95
+ });
96
+ }
97
+ function useTheme() {
98
+ return {
99
+ config: useSyncExternalStore(localStore.subscribe, localStore.getSnapshot, localStore.getSnapshot),
100
+ setTheme: useCallback((e) => {
101
+ localStore.setTheme(e);
102
+ }, [])
103
+ };
104
+ }
105
+ function useNavigationBadge(e) {
106
+ return null;
107
+ }
108
+ function filterNavigationItems(e, D) {
109
+ let O = D.toLowerCase();
110
+ return e.filter((e) => {
111
+ let k = (e.label ?? e.name).toLowerCase().includes(O), A = e.items ? filterNavigationItems(e.items, D).length > 0 : !1;
112
+ return k || A;
113
+ });
114
+ }
115
+ function getContainerTypeSuffix(e) {
116
+ switch (e.type) {
117
+ case PageContainerType.TABLE: return "table";
118
+ case PageContainerType.FORM: return "form";
119
+ case PageContainerType.VIEW: return "view";
120
+ default: return "table";
121
+ }
122
+ }
123
+ function hasResolvedContainer(e) {
124
+ return e.container !== null && typeof e.container == "object";
125
+ }
126
+ function getBasePathFromName(e) {
127
+ return e.replace(/::Access(Table|Form|View)Page$/, "").replace(/::Relation(Table|Form|View)Page$/, "").replace(/::/g, "/").toLowerCase();
128
+ }
129
+ function getRouteForPage(e) {
130
+ if (e && typeof e == "object") {
131
+ let D = e;
132
+ if (hasResolvedContainer(D) && D.name) return `/${getBasePathFromName(D.name)}/${getContainerTypeSuffix(D.container)}`;
133
+ if (typeof D.name == "string") return getRouteFromString(D.name);
134
+ let O = D["xmi:id"];
135
+ return typeof O == "string" ? getRouteFromString(O) : "/";
136
+ }
137
+ return typeof e == "string" ? getRouteFromString(e) : "/";
138
+ }
139
+ function getRoutePattern(e) {
140
+ let D = getRouteForPage(e);
141
+ return e.container?.type === PageContainerType.VIEW || e.name?.includes("::Relation") ? `${D}/:signedIdentifier?` : D;
142
+ }
143
+ function getRouteFromString(e) {
144
+ if (e.includes("/(esm/")) {
145
+ let D = e.match(/^([^/]+)\/.*\/(.*)PageDefinition$/);
146
+ if (D) {
147
+ let [, e, O] = D, k = O.match(/^Access(Table|Form|View)$/);
148
+ return k ? `/${e.toLowerCase()}/${k[1].toLowerCase()}` : `/${e.toLowerCase()}/${O.toLowerCase()}`;
149
+ }
150
+ return `/${e.split("/")[0].toLowerCase()}`;
151
+ }
152
+ let D = e.match(/(.*)::Access(Table|Form|View)Page$/);
153
+ if (D) {
154
+ let [, e, O] = D;
155
+ return `/${e.replace(/::/g, "/").toLowerCase()}/${O.toLowerCase()}`;
156
+ }
157
+ let O = e.match(/(.*)::Relation(Table|Form|View)Page$/);
158
+ if (O) {
159
+ let [, e, D] = O;
160
+ return `/${e.replace(/::/g, "/").toLowerCase()}/${D.toLowerCase()}`;
161
+ }
162
+ return `/${e.replace(/::/g, "/").toLowerCase()}`;
163
+ }
164
+ function getNavExpandedStorageKey() {
165
+ return "nav-expanded";
166
+ }
167
+ function loadExpandedItems() {
168
+ try {
169
+ let e = localStorage.getItem(getNavExpandedStorageKey());
170
+ if (e) return new Set(JSON.parse(e));
171
+ } catch {}
172
+ return /* @__PURE__ */ new Set();
173
+ }
174
+ function saveExpandedItems(e) {
175
+ try {
176
+ localStorage.setItem(getNavExpandedStorageKey(), JSON.stringify([...e]));
177
+ } catch {}
178
+ }
179
+ function findActionForNavigationItem(e, D) {
180
+ if (!D.actionDefinition || !e.actions) return;
181
+ let O = D.actionDefinition["xmi:id"];
182
+ if (O) return e.actions.find((e) => {
183
+ let D = e.actionDefinition;
184
+ return typeof D == "object" && D ? D["xmi:id"] === O : typeof D == "string" ? D === O : !1;
185
+ });
186
+ }
187
+ function NavigationItemRenderer({ item: e, collapsed: D, expanded: O, onToggleExpanded: A, depth: j, expandedItems: M, onItemExpand: N, navigationActions: F, onMenuAction: I }) {
188
+ let L = useNavigate(), R = useLocation(), z = useNavigationBadge(e["xmi:id"] ?? ""), { label: B } = useModelLabel(e), V = e.items && e.items.length > 0, H = e.target ? getRouteForPage(e.target) : void 0, U = !!e.actionDefinition, W = H && R.pathname.includes(H), G = getNavItemTestId(e), K = () => {
189
+ if (V) A();
190
+ else if (U && I && F) {
191
+ let D = e.actionDefinition?.["xmi:id"];
192
+ if (D) {
193
+ let e = F.find((e) => {
194
+ let O = e.actionDefinition;
195
+ return typeof O == "object" && O ? O["xmi:id"] === D : typeof O == "string" && O === D;
196
+ });
197
+ e && I(e);
198
+ }
199
+ } else H && L(H);
200
+ }, Q = /* @__PURE__ */ jsx(ListItem, {
201
+ disablePadding: !0,
202
+ sx: { pl: j * 2 },
203
+ "data-testid": G,
204
+ children: /* @__PURE__ */ jsxs(ListItemButton, {
205
+ onClick: K,
206
+ selected: !!W,
207
+ sx: {
208
+ minHeight: 48,
209
+ justifyContent: D ? "center" : "initial"
210
+ },
211
+ children: [/* @__PURE__ */ jsx(ListItemIcon, {
212
+ sx: {
213
+ minWidth: 0,
214
+ mr: D ? 0 : 2,
215
+ justifyContent: "center"
216
+ },
217
+ children: /* @__PURE__ */ jsx(Badge, {
218
+ badgeContent: z?.count,
219
+ color: z?.color ?? "primary",
220
+ max: z?.max ?? 99,
221
+ invisible: !z,
222
+ children: e.icon ? /* @__PURE__ */ jsx(IconRenderer, {
223
+ icon: e.icon,
224
+ size: "medium"
225
+ }) : /* @__PURE__ */ jsx(FolderIcon, {})
226
+ })
227
+ }), !D && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ListItemText, { primary: B }), V && jsx(O ? ExpandLessIcon : ExpandMoreIcon, {})] })]
228
+ })
229
+ });
230
+ return /* @__PURE__ */ jsxs(Fragment, { children: [D ? /* @__PURE__ */ jsx(Tooltip, {
231
+ title: B,
232
+ placement: "right",
233
+ children: Q
234
+ }) : Q, V && !D && /* @__PURE__ */ jsx(Collapse, {
235
+ in: O,
236
+ timeout: "auto",
237
+ unmountOnExit: !0,
238
+ children: /* @__PURE__ */ jsx(List, {
239
+ component: "div",
240
+ disablePadding: !0,
241
+ children: e.items?.map((e) => {
242
+ let O = e["xmi:id"] ?? "";
243
+ return /* @__PURE__ */ jsx(NavigationItemRenderer, {
244
+ item: e,
245
+ collapsed: D,
246
+ expanded: M.has(O),
247
+ onToggleExpanded: () => N(O),
248
+ depth: j + 1,
249
+ expandedItems: M,
250
+ onItemExpand: N,
251
+ navigationActions: F,
252
+ onMenuAction: I
253
+ }, O);
254
+ })
255
+ })
256
+ })] });
257
+ }
258
+ function useMenuOperationDispatch() {
259
+ let { dispatch: e } = useActionDispatcher({
260
+ navigation: useNavigation(),
261
+ data: useDataStore(),
262
+ registry: useApplication(),
263
+ api: useApi(),
264
+ notifications: useNotifications()
265
+ });
266
+ return { dispatchMenuAction: e };
267
+ }
268
+ function NavigationDrawer({ open: e, collapsed: D, onCollapse: O, width: k, navigationController: j }) {
269
+ let [M, N] = useState(""), [P, F] = useState(/* @__PURE__ */ new Set());
270
+ useEffect(() => {
271
+ F(loadExpandedItems());
272
+ }, []);
273
+ let I = (e) => {
274
+ F((D) => {
275
+ let O = new Set(D);
276
+ return O.has(e) ? O.delete(e) : O.add(e), saveExpandedItems(O), O;
277
+ });
278
+ }, L = useCustomizationsOptional()?.getMenuCustomizer(), R = useMemo(() => {
279
+ let e = j?.items ?? [];
280
+ return L ? L(e) : e;
281
+ }, [j?.items, L]), z = useMemo(() => M ? filterNavigationItems(R, M) : R, [R, M]), { dispatchMenuAction: H } = useMenuOperationDispatch(), G = j?.actions;
282
+ return /* @__PURE__ */ jsxs(Drawer, {
283
+ variant: "persistent",
284
+ open: e,
285
+ sx: {
286
+ width: k,
287
+ flexShrink: 0,
288
+ "& .MuiDrawer-paper": {
289
+ width: k,
290
+ boxSizing: "border-box",
291
+ transition: "width 0.2s"
292
+ }
293
+ },
294
+ "data-testid": "navigation-drawer",
295
+ children: [
296
+ /* @__PURE__ */ jsx(Box, {
297
+ sx: {
298
+ display: "flex",
299
+ alignItems: "center",
300
+ justifyContent: "flex-end",
301
+ minHeight: {
302
+ xs: 56,
303
+ sm: 64
304
+ },
305
+ px: 1
306
+ },
307
+ children: /* @__PURE__ */ jsx(IconButton, {
308
+ onClick: O,
309
+ "data-testid": "navigation-drawer::collapse",
310
+ children: jsx(D ? ChevronRightIcon : ChevronLeftIcon, {})
311
+ })
312
+ }),
313
+ /* @__PURE__ */ jsx(Divider, {}),
314
+ !D && /* @__PURE__ */ jsx(Box, {
315
+ sx: { p: 1 },
316
+ children: /* @__PURE__ */ jsx(TextField, {
317
+ size: "small",
318
+ placeholder: "Search menu...",
319
+ value: M,
320
+ onChange: (e) => N(e.target.value),
321
+ fullWidth: !0,
322
+ "data-testid": "navigation-drawer::search",
323
+ slotProps: { input: { startAdornment: /* @__PURE__ */ jsx(InputAdornment, {
324
+ position: "start",
325
+ children: /* @__PURE__ */ jsx(SearchIcon, {})
326
+ }) } }
327
+ })
328
+ }),
329
+ /* @__PURE__ */ jsx(List, {
330
+ "data-testid": "navigation-drawer::items",
331
+ children: z.map((e) => {
332
+ let O = e["xmi:id"] ?? "";
333
+ return /* @__PURE__ */ jsx(NavigationItemRenderer, {
334
+ item: e,
335
+ collapsed: D,
336
+ expanded: P.has(O),
337
+ onToggleExpanded: () => I(O),
338
+ depth: 0,
339
+ expandedItems: P,
340
+ onItemExpand: I,
341
+ navigationActions: G,
342
+ onMenuAction: H
343
+ }, O);
344
+ })
345
+ })
346
+ ]
347
+ });
348
+ }
349
+ function getNavigationTargets(e) {
350
+ let D = [];
351
+ for (let O of e) O.target && D.push(O.target.name), O.items && D.push(...getNavigationTargets(O.items));
352
+ return D;
353
+ }
354
+ function getDashboardRoute(e) {
355
+ let D = e.navigationController ? getNavigationTargets(e.navigationController.items) : [], O = e.pages.find((e) => e.dashboard === !0 && D.includes(e.name));
356
+ return O ? getRouteForPage(O) : "/";
357
+ }
358
+ function ActorSelector({ className: e }) {
359
+ let { application: D, applications: O, actorName: k, switchActorWithNavigation: A } = useApplication(), j = useNavigate(), { switchActor: M, pendingSwitch: N, confirmSwitch: P, cancelSwitch: F } = useActorSwitch(D, useCallback((e) => {
360
+ let D = O.find((D) => D.name === e || D.actor?.name === e);
361
+ if (!D) throw Error(`Application for actor '${e}' not found`);
362
+ return D;
363
+ }, [O]), useCallback((e) => {
364
+ A(e, (e) => {
365
+ j(getDashboardRoute(e));
366
+ });
367
+ }, [A, j])), I = getActorSelectorTestId(k);
368
+ return O.length <= 1 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(FormControl, {
369
+ size: "small",
370
+ sx: (e) => ({
371
+ minWidth: 200,
372
+ "& .MuiInputLabel-root": {
373
+ color: e.palette.common.white,
374
+ "&.Mui-focused": { color: e.palette.common.white }
375
+ },
376
+ "& .MuiOutlinedInput-root": {
377
+ color: e.palette.common.white,
378
+ "& fieldset": { borderColor: "rgba(255, 255, 255, 0.5)" },
379
+ "&:hover fieldset": { borderColor: "rgba(255, 255, 255, 0.7)" },
380
+ "&.Mui-focused fieldset": { borderColor: e.palette.common.white }
381
+ },
382
+ "& .MuiSelect-select": { color: e.palette.common.white },
383
+ "& .MuiSvgIcon-root": { color: e.palette.common.white }
384
+ }),
385
+ className: e,
386
+ children: [/* @__PURE__ */ jsx(InputLabel, {
387
+ id: "actor-selector-label",
388
+ children: "Application"
389
+ }), /* @__PURE__ */ jsx(Select, {
390
+ labelId: "actor-selector-label",
391
+ value: k,
392
+ onChange: (e) => M(e.target.value),
393
+ label: "Application",
394
+ "data-testid": I,
395
+ children: O.map((e) => /* @__PURE__ */ jsx(MenuItem, {
396
+ value: e.name,
397
+ children: e.name
398
+ }, e.name))
399
+ })]
400
+ }), /* @__PURE__ */ jsx(ActorSwitchDialog, {
401
+ open: !!N,
402
+ currentActor: k,
403
+ targetActor: N?.targetActor ?? "",
404
+ currentRealm: D.authentication?.realm,
405
+ targetRealm: N?.targetRealm,
406
+ onConfirm: P,
407
+ onCancel: F
408
+ })] });
409
+ }
410
+ function LocaleSwitcher() {
411
+ let e = useLocaleOptional(), [D, O] = useState(null), k = useCallback((e) => {
412
+ O(e.currentTarget);
413
+ }, []), A = useCallback(() => {
414
+ O(null);
415
+ }, []), j = useCallback(async (D) => {
416
+ O(null), e && await e.setLocale(D);
417
+ }, [e]);
418
+ if (!e) return null;
419
+ let M = Object.entries(e.locales);
420
+ return M.length < 2 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Tooltip, {
421
+ title: e.locales[e.locale] ?? e.locale,
422
+ children: /* @__PURE__ */ jsx(IconButton, {
423
+ color: "inherit",
424
+ onClick: k,
425
+ "data-testid": "locale-switcher",
426
+ "aria-label": "Change locale",
427
+ children: /* @__PURE__ */ jsx(LanguageIcon, {})
428
+ })
429
+ }), /* @__PURE__ */ jsx(Menu, {
430
+ anchorEl: D,
431
+ open: !!D,
432
+ onClose: A,
433
+ "data-testid": "locale-switcher::menu",
434
+ children: M.map(([D, O]) => /* @__PURE__ */ jsx(MenuItem, {
435
+ selected: D === e.locale,
436
+ onClick: () => j(D),
437
+ "data-testid": `locale-switcher::option::${D}`,
438
+ children: /* @__PURE__ */ jsx(Typography, {
439
+ variant: "body2",
440
+ children: O
441
+ })
442
+ }, D))
443
+ })] });
444
+ }
445
+ function HorizontalNavigationItem({ item: e, depth: D, navigationActions: O, onMenuAction: A }) {
446
+ let j = useNavigate(), N = useLocation(), P = useNavigationBadge(e["xmi:id"] ?? ""), { label: F } = useModelLabel(e), [I, L] = useState(null), R = !!I, z = e.items && e.items.length > 0, B = e.target ? getRouteForPage(e.target) : void 0, V = !!e.actionDefinition, H = B ? N.pathname.includes(B) : !1, U = getNavItemTestId(e), W = (e) => {
447
+ L(e.currentTarget);
448
+ }, G = () => {
449
+ L(null);
450
+ }, K = () => {
451
+ if (V && A && O) {
452
+ let D = e.actionDefinition?.["xmi:id"];
453
+ if (D) {
454
+ let e = O.find((e) => {
455
+ let O = e.actionDefinition;
456
+ return typeof O == "object" && O ? O["xmi:id"] === D : typeof O == "string" && O === D;
457
+ });
458
+ e && A(e);
459
+ }
460
+ } else B && j(B);
461
+ G();
462
+ }, q = /* @__PURE__ */ jsx(Badge, {
463
+ badgeContent: P?.count,
464
+ color: P?.color ?? "primary",
465
+ max: P?.max ?? 99,
466
+ invisible: !P,
467
+ children: e.icon ? /* @__PURE__ */ jsx(IconRenderer, {
468
+ icon: e.icon,
469
+ size: "small"
470
+ }) : /* @__PURE__ */ jsx(FolderIcon, { fontSize: "small" })
471
+ });
472
+ return D === 0 ? z ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
473
+ color: "inherit",
474
+ onClick: W,
475
+ startIcon: q,
476
+ endIcon: /* @__PURE__ */ jsx(ExpandMoreIcon, {}),
477
+ sx: {
478
+ textTransform: "none",
479
+ fontWeight: H ? 700 : 400,
480
+ opacity: H ? 1 : .85
481
+ },
482
+ "data-testid": U,
483
+ children: F
484
+ }), /* @__PURE__ */ jsx(Menu, {
485
+ anchorEl: I,
486
+ open: R,
487
+ onClose: G,
488
+ anchorOrigin: {
489
+ vertical: "bottom",
490
+ horizontal: "left"
491
+ },
492
+ transformOrigin: {
493
+ vertical: "top",
494
+ horizontal: "left"
495
+ },
496
+ "data-testid": `${U}::menu`,
497
+ children: e.items?.map((e) => /* @__PURE__ */ jsx(HorizontalNavigationSubItem, {
498
+ item: e,
499
+ onCloseAll: G,
500
+ navigationActions: O,
501
+ onMenuAction: A
502
+ }, e["xmi:id"] ?? e.name))
503
+ })] }) : /* @__PURE__ */ jsx(Button, {
504
+ color: "inherit",
505
+ onClick: K,
506
+ startIcon: q,
507
+ sx: {
508
+ textTransform: "none",
509
+ fontWeight: H ? 700 : 400,
510
+ opacity: H ? 1 : .85
511
+ },
512
+ "data-testid": U,
513
+ children: F
514
+ }) : null;
515
+ }
516
+ function HorizontalNavigationSubItem({ item: e, onCloseAll: D, navigationActions: O, onMenuAction: A }) {
517
+ let j = useNavigate(), M = useLocation(), N = useNavigationBadge(e["xmi:id"] ?? ""), { label: P } = useModelLabel(e), [F, I] = useState(null), L = !!F, R = e.items && e.items.length > 0, z = e.target ? getRouteForPage(e.target) : void 0, B = !!e.actionDefinition, V = z ? M.pathname.includes(z) : !1, H = getNavItemTestId(e), U = (e) => {
518
+ I(e.currentTarget);
519
+ }, W = () => {
520
+ I(null);
521
+ }, G = () => {
522
+ if (B && A && O) {
523
+ let D = e.actionDefinition?.["xmi:id"];
524
+ if (D) {
525
+ let e = O.find((e) => {
526
+ let O = e.actionDefinition;
527
+ return typeof O == "object" && O ? O["xmi:id"] === D : typeof O == "string" && O === D;
528
+ });
529
+ e && A(e);
530
+ }
531
+ } else z && j(z);
532
+ D();
533
+ }, K = /* @__PURE__ */ jsx(Badge, {
534
+ badgeContent: N?.count,
535
+ color: N?.color ?? "primary",
536
+ max: N?.max ?? 99,
537
+ invisible: !N,
538
+ children: e.icon ? /* @__PURE__ */ jsx(IconRenderer, {
539
+ icon: e.icon,
540
+ size: "small"
541
+ }) : /* @__PURE__ */ jsx(FolderIcon, { fontSize: "small" })
542
+ });
543
+ return R ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(MenuItem, {
544
+ onClick: U,
545
+ selected: V,
546
+ "data-testid": H,
547
+ children: [
548
+ /* @__PURE__ */ jsx(ListItemIcon, { children: K }),
549
+ /* @__PURE__ */ jsx(ListItemText, { children: P }),
550
+ /* @__PURE__ */ jsx(ExpandMoreIcon, {
551
+ fontSize: "small",
552
+ sx: {
553
+ ml: 1,
554
+ transform: "rotate(-90deg)"
555
+ }
556
+ })
557
+ ]
558
+ }), /* @__PURE__ */ jsx(Menu, {
559
+ anchorEl: F,
560
+ open: L,
561
+ onClose: W,
562
+ anchorOrigin: {
563
+ vertical: "top",
564
+ horizontal: "right"
565
+ },
566
+ transformOrigin: {
567
+ vertical: "top",
568
+ horizontal: "left"
569
+ },
570
+ "data-testid": `${H}::menu`,
571
+ children: e.items?.map((e) => /* @__PURE__ */ jsx(HorizontalNavigationSubItem, {
572
+ item: e,
573
+ onCloseAll: () => {
574
+ W(), D();
575
+ },
576
+ navigationActions: O,
577
+ onMenuAction: A
578
+ }, e["xmi:id"] ?? e.name))
579
+ })] }) : /* @__PURE__ */ jsxs(MenuItem, {
580
+ onClick: G,
581
+ selected: V,
582
+ "data-testid": H,
583
+ children: [/* @__PURE__ */ jsx(ListItemIcon, { children: K }), /* @__PURE__ */ jsx(ListItemText, { children: P })]
584
+ });
585
+ }
586
+ function HorizontalNavigation({ navigationController: e }) {
587
+ let D = useCustomizationsOptional()?.getMenuCustomizer(), O = useMemo(() => {
588
+ let O = e?.items ?? [];
589
+ return D ? D(O) : O;
590
+ }, [e?.items, D]), { dispatchMenuAction: k } = useMenuOperationDispatch(), j = e?.actions;
591
+ return /* @__PURE__ */ jsx(Box, {
592
+ component: "nav",
593
+ sx: {
594
+ display: "flex",
595
+ alignItems: "center",
596
+ gap: .5,
597
+ flexWrap: "wrap"
598
+ },
599
+ "data-testid": "horizontal-navigation",
600
+ children: O.map((e) => /* @__PURE__ */ jsx(HorizontalNavigationItem, {
601
+ item: e,
602
+ depth: 0,
603
+ navigationActions: j,
604
+ onMenuAction: k
605
+ }, e["xmi:id"] ?? e.name))
606
+ });
607
+ }
608
+ function ThemeToggle({ className: e }) {
609
+ let { config: D, setTheme: O } = useTheme(), { mode: k, isSystemMode: A } = D, j = () => {
610
+ O(A ? {
611
+ mode: "light",
612
+ __useSystemPreference: !1
613
+ } : k === "light" ? {
614
+ mode: "dark",
615
+ __useSystemPreference: !1
616
+ } : {
617
+ mode: typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light",
618
+ __useSystemPreference: !0
619
+ });
620
+ }, M = () => A ? "Switch to light mode" : k === "light" ? "Switch to dark mode" : "Switch to system preference", N = () => jsx(A ? LightModeIcon : k === "light" ? DarkModeIcon : SettingsBrightnessIcon, {});
621
+ return /* @__PURE__ */ jsx(Tooltip, {
622
+ title: M(),
623
+ children: /* @__PURE__ */ jsx(IconButton, {
624
+ color: "inherit",
625
+ onClick: j,
626
+ className: e,
627
+ "data-testid": "theme-toggle",
628
+ children: N()
629
+ })
630
+ });
631
+ }
632
+ function DefaultHeroComponent({ principal: e, actorName: D, signOut: k, onNavigateToProfile: j, onNavigateToSettings: M, profilePictureUrl: N }) {
633
+ let { t: P } = useTranslation(), [F, I] = useState(null), L = e?.preferredUsername ?? e?.name ?? "User", R = (L[0] ?? "?").toUpperCase(), z = () => {
634
+ I(null), k();
635
+ }, V = () => {
636
+ I(null), j?.();
637
+ }, H = () => {
638
+ I(null), M();
639
+ }, W = getUserMenuTestId("trigger");
640
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(IconButton, {
641
+ onClick: (e) => I(e.currentTarget),
642
+ color: "inherit",
643
+ "data-testid": W,
644
+ children: /* @__PURE__ */ jsx(Avatar, {
645
+ src: N,
646
+ sx: {
647
+ width: 32,
648
+ height: 32
649
+ },
650
+ children: R
651
+ })
652
+ }), /* @__PURE__ */ jsxs(Menu, {
653
+ anchorEl: F,
654
+ open: !!F,
655
+ onClose: () => I(null),
656
+ "data-testid": getUserMenuTestId("menu"),
657
+ children: [
658
+ /* @__PURE__ */ jsxs(Box, {
659
+ sx: {
660
+ px: 2,
661
+ py: 1
662
+ },
663
+ children: [/* @__PURE__ */ jsx(Typography, {
664
+ variant: "subtitle1",
665
+ children: L
666
+ }), e?.email && /* @__PURE__ */ jsx(Typography, {
667
+ variant: "body2",
668
+ color: "text.secondary",
669
+ children: e.email
670
+ })]
671
+ }),
672
+ /* @__PURE__ */ jsx(Divider, {}),
673
+ j && /* @__PURE__ */ jsxs(MenuItem, {
674
+ onClick: V,
675
+ "data-testid": getUserMenuTestId("profile"),
676
+ children: [/* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(PersonIcon, { fontSize: "small" }) }), /* @__PURE__ */ jsx(ListItemText, { children: P("system.auth.profile", { defaultValue: "Profile" }) })]
677
+ }),
678
+ /* @__PURE__ */ jsxs(MenuItem, {
679
+ onClick: H,
680
+ "data-testid": getUserMenuTestId("settings"),
681
+ children: [/* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(SettingsIcon, { fontSize: "small" }) }), /* @__PURE__ */ jsx(ListItemText, { children: P("system.common.settings", { defaultValue: "Settings" }) })]
682
+ }),
683
+ /* @__PURE__ */ jsx(Divider, {}),
684
+ /* @__PURE__ */ jsxs(MenuItem, {
685
+ onClick: z,
686
+ "data-testid": getUserMenuTestId("logout"),
687
+ children: [/* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(LogoutIcon, { fontSize: "small" }) }), /* @__PURE__ */ jsx(ListItemText, { children: P("system.auth.logout", { defaultValue: "Log Out" }) })]
688
+ })
689
+ ]
690
+ })] });
691
+ }
692
+ function AppBar({ drawerWidth: e, onMenuClick: O, logo: k, extra: j, menuLayout: M, navigationController: N }) {
693
+ let { application: P, applications: F } = useApplication(), { requiresAuth: I, principal: L, actorName: R, signoutRedirect: z } = useAuth(), B = useCustomizationsOptional()?.getHeroComponent(), V = F.length > 1, H = M === MenuLayout.HORIZONTAL, W = useNavigate(), G = useMemo(() => P.profilePage ? getRouteForPage(P.profilePage) : void 0, [P.profilePage]), K = useCallback(() => {
694
+ G && W(G);
695
+ }, [W, G]), q = {
696
+ principal: L,
697
+ actorName: R,
698
+ signOut: z,
699
+ onNavigateToSettings: useCallback(() => {
700
+ W("/settings");
701
+ }, [W]),
702
+ profilePictureUrl: useMemo(() => {
703
+ let e = P.principal;
704
+ if (!e?.attributes || !L) return;
705
+ let D = e.attributes.find((e) => String(e.isProfilePicture) === "true");
706
+ if (!D) return;
707
+ let O = L[D.name];
708
+ return typeof O == "string" && O.length > 0 ? O : void 0;
709
+ }, [P.principal, L]),
710
+ ...G ? { onNavigateToProfile: K } : {}
711
+ };
712
+ return /* @__PURE__ */ jsx(AppBar$1, {
713
+ position: "fixed",
714
+ sx: {
715
+ width: `calc(100% - ${e}px)`,
716
+ ml: `${e}px`,
717
+ transition: "width 0.2s, margin 0.2s"
718
+ },
719
+ "data-testid": "app-bar",
720
+ children: /* @__PURE__ */ jsxs(Toolbar, { children: [
721
+ O && /* @__PURE__ */ jsx(IconButton, {
722
+ edge: "start",
723
+ color: "inherit",
724
+ onClick: O,
725
+ sx: { mr: 2 },
726
+ "data-testid": "app-bar::menu-toggle",
727
+ children: /* @__PURE__ */ jsx(MenuIcon, {})
728
+ }),
729
+ k ?? /* @__PURE__ */ jsx(Typography, {
730
+ variant: "h6",
731
+ noWrap: !0,
732
+ component: "div",
733
+ children: P.name
734
+ }),
735
+ V && /* @__PURE__ */ jsx(Box, {
736
+ sx: { ml: 2 },
737
+ children: /* @__PURE__ */ jsx(ActorSelector, {})
738
+ }),
739
+ H && /* @__PURE__ */ jsx(Box, {
740
+ sx: { ml: 2 },
741
+ children: /* @__PURE__ */ jsx(HorizontalNavigation, { navigationController: N })
742
+ }),
743
+ /* @__PURE__ */ jsx(Box, { sx: { flexGrow: 1 } }),
744
+ j,
745
+ /* @__PURE__ */ jsx(LocaleSwitcher, {}),
746
+ /* @__PURE__ */ jsx(ThemeToggle, {}),
747
+ I && jsx(B || DefaultHeroComponent, { ...q })
748
+ ] })
749
+ });
750
+ }
751
+ function Breadcrumbs({ className: e }) {
752
+ let { pageStack: D, currentPage: O, goBack: k } = useNavigation(), A = useNavigate(), { t: M } = useTranslation();
753
+ if (D.length === 0 && !O) return null;
754
+ let N = getBreadcrumbTestId(0);
755
+ return /* @__PURE__ */ jsxs(Breadcrumbs$1, {
756
+ sx: { mb: 2 },
757
+ className: e,
758
+ "data-testid": N,
759
+ children: [
760
+ /* @__PURE__ */ jsx(Link, {
761
+ component: "button",
762
+ variant: "body2",
763
+ onClick: () => A("/"),
764
+ underline: "hover",
765
+ "data-testid": `${N}::home`,
766
+ children: M("system.nav.home", { defaultValue: "Home" })
767
+ }),
768
+ D.map((e, O) => /* @__PURE__ */ jsx(BreadcrumbLink, {
769
+ pageDefinition: e.pageDefinition,
770
+ onClick: () => {
771
+ let e = D.length - 1 - O;
772
+ for (let D = 0; D < e; D++) k();
773
+ },
774
+ testId: `${N}::${e.pageDefinition.name}`
775
+ }, e.pageDefinition["xmi:id"])),
776
+ O && /* @__PURE__ */ jsx(BreadcrumbCurrent, {
777
+ pageDefinition: O,
778
+ testId: `${N}::current`
779
+ })
780
+ ]
781
+ });
782
+ }
783
+ function BreadcrumbLink({ pageDefinition: e, onClick: D, testId: O }) {
784
+ let { label: k } = useModelLabel(e);
785
+ return /* @__PURE__ */ jsx(Link, {
786
+ component: "button",
787
+ variant: "body2",
788
+ onClick: D,
789
+ underline: "hover",
790
+ "data-testid": O,
791
+ children: k
792
+ });
793
+ }
794
+ function BreadcrumbCurrent({ pageDefinition: e, testId: D }) {
795
+ let { title: O } = usePageTitle(e);
796
+ return /* @__PURE__ */ jsx(Typography, {
797
+ color: "text.primary",
798
+ variant: "body2",
799
+ "data-testid": D,
800
+ children: O
801
+ });
802
+ }
803
+ function Footer() {
804
+ let e = useCustomizationsOptional()?.getFooterText(), D = useApplicationOptional()?.application?.modelName, O = e === void 0 ? `© ${(/* @__PURE__ */ new Date()).getFullYear()} ${D ?? ""}`.trim() : typeof e == "function" ? e() : e;
805
+ return /* @__PURE__ */ jsx(Box, {
806
+ component: "footer",
807
+ sx: {
808
+ py: 1.5,
809
+ px: 3,
810
+ textAlign: "center",
811
+ borderTop: 1,
812
+ borderColor: "divider",
813
+ bgcolor: "background.default"
814
+ },
815
+ "data-testid": "app-shell-footer",
816
+ children: /* @__PURE__ */ jsx(Typography, {
817
+ variant: "body2",
818
+ color: "text.secondary",
819
+ children: O
820
+ })
821
+ });
822
+ }
823
+ function getMaxWidth(e) {
824
+ switch (e) {
825
+ case DialogSize.XS: return "xs";
826
+ case DialogSize.SM: return "sm";
827
+ case DialogSize.MD: return "md";
828
+ case DialogSize.LG: return "lg";
829
+ case DialogSize.XL: return "xl";
830
+ default: return "md";
831
+ }
832
+ }
833
+ function generateDialogEntityId(e, D) {
834
+ if (D?.isCreate) return `dialog::create::${e}`;
835
+ let O = D?.transfer;
836
+ return O?.__signedIdentifier ? `dialog::transfer::${O.__signedIdentifier}` : `dialog::${e}`;
837
+ }
838
+ function DialogContentWithValidation({ pageDefinition: e, transferId: D, params: O, actionButtonGroups: k, navigation: j, dataStore: M, application: N, api: P, notifications: F, transfer: I, closeDialog: z, isCreate: B, isEager: V, relation: H, ownerTransfer: U, parentTransferId: W, relationName: G }) {
839
+ let K = useValidationContextOptional(), q = useMemo(() => {
840
+ if (K) return {
841
+ setError: K.setError,
842
+ setErrors: (e) => {
843
+ K.setErrors(e);
844
+ for (let D of Object.keys(e)) K.touch(D);
845
+ },
846
+ clearErrors: K.clearErrors,
847
+ clearError: K.clearError
848
+ };
849
+ }, [K]), { dispatch: J } = useActionDispatcher({
850
+ navigation: j,
851
+ data: M,
852
+ registry: N,
853
+ api: P,
854
+ transfer: I,
855
+ closeDialog: z,
856
+ notifications: F,
857
+ actionOverrides: useResolvedPageActionOverrides(),
858
+ additionalContext: {
859
+ pageTransferId: D,
860
+ pageType: "FORM",
861
+ isEditMode: !0,
862
+ isEager: V,
863
+ validation: q,
864
+ ...V && W && { parentTransferId: W },
865
+ ...V && G && { relationName: G },
866
+ createDialog: B ? {
867
+ relation: H,
868
+ ownerTransfer: U,
869
+ isEager: V,
870
+ parentTransferId: W,
871
+ relationName: G
872
+ } : void 0
873
+ }
874
+ }), Y = useSelectorSelectionOptional(), X = useCallback((e) => {
875
+ let D = { isPageAction: !0 };
876
+ if (Y) {
877
+ D.ownerTransfer = Y.ownerTransfer;
878
+ let e = Y.selectedTransfersRef.current;
879
+ D.selectedEntities = e, D.selectedEntity = e[0];
880
+ }
881
+ return J(e, D);
882
+ }, [J, Y]), Z = e.container?.type === PageContainerType.VIEW;
883
+ return /* @__PURE__ */ jsxs(DispatchProvider, {
884
+ dispatch: J,
885
+ children: [/* @__PURE__ */ jsx(DialogContent, {
886
+ dividers: !0,
887
+ sx: {
888
+ flex: 1,
889
+ overflow: "auto"
890
+ },
891
+ children: /* @__PURE__ */ jsx(PageRenderer, { page: e })
892
+ }), k.length > 0 && /* @__PURE__ */ jsx(DialogActions, {
893
+ "data-testid": `page-dialog::${e["xmi:id"]}::actions`,
894
+ children: /* @__PURE__ */ jsx(Box, {
895
+ sx: {
896
+ display: "flex",
897
+ gap: 1,
898
+ justifyContent: "flex-end"
899
+ },
900
+ children: k.map((D) => /* @__PURE__ */ jsx(ButtonGroupRenderer, {
901
+ element: D,
902
+ page: e,
903
+ editMode: Z,
904
+ onDispatch: X
905
+ }, D["xmi:id"]))
906
+ })
907
+ })]
908
+ });
909
+ }
910
+ function PageDialogHost() {
911
+ let e = useNavigation(), { dialogStack: D, closeDialog: O } = e;
912
+ return D.length === 0 ? null : /* @__PURE__ */ jsx(Fragment, { children: D.map((k, A) => /* @__PURE__ */ jsx(SinglePageDialog, {
913
+ dialog: k,
914
+ isTopmost: A === D.length - 1,
915
+ navigation: e,
916
+ closeDialog: O
917
+ }, `${k.pageDefinition["xmi:id"]}::${A}`)) });
918
+ }
919
+ function SinglePageDialog({ dialog: e, isTopmost: D, navigation: O, closeDialog: k }) {
920
+ let A = useApplication(), j = useApi(), M = useDataStore(), N = useNotifications(), { pageDefinition: P, size: F, params: L } = e, R = useMemo(() => generateDialogEntityId(P["xmi:id"], L), [P, L]), z = useMemo(() => {
921
+ if (L?.transfer) return L.transfer;
922
+ }, [L?.transfer]), B = L?.isCreate === !0, V = L?.isEager === !0, H = L?.relation, U = L?.ownerTransfer, W = L?.parentTransferId, G = L?.relationName, K = useCallback(() => {
923
+ D && k({ type: "cancelled" });
924
+ }, [k, D]), q = getMaxWidth(F), J = P.container?.actionButtonGroups ?? [], Y = String(P.isSelector) === "true", X = (e) => Y ? /* @__PURE__ */ jsx(SelectorSelectionProvider, {
925
+ ownerTransfer: U,
926
+ children: e
927
+ }) : e;
928
+ return /* @__PURE__ */ jsxs(Dialog, {
929
+ open: !0,
930
+ onClose: K,
931
+ maxWidth: q,
932
+ fullWidth: !0,
933
+ scroll: "paper",
934
+ "data-testid": `page-dialog::${P["xmi:id"]}`,
935
+ sx: D ? void 0 : {
936
+ visibility: "hidden",
937
+ pointerEvents: "none"
938
+ },
939
+ slotProps: D ? void 0 : { backdrop: { sx: { display: "none" } } },
940
+ PaperProps: { sx: {
941
+ maxHeight: "90vh",
942
+ display: "flex",
943
+ flexDirection: "column"
944
+ } },
945
+ children: [/* @__PURE__ */ jsx(TranslatedDialogTitle, {
946
+ pageDefinition: P,
947
+ transferId: R
948
+ }), /* @__PURE__ */ jsx(PageProvider, {
949
+ pageDefinition: P,
950
+ transferId: R,
951
+ params: L,
952
+ isDialog: !0,
953
+ children: /* @__PURE__ */ jsx(PageActionOverridesProvider, { children: /* @__PURE__ */ jsx(VisualPropertiesProvider, { children: /* @__PURE__ */ jsx(ValidationProvider, { children: X(/* @__PURE__ */ jsx(DialogContentWithValidation, {
954
+ pageDefinition: P,
955
+ transferId: R,
956
+ params: L,
957
+ actionButtonGroups: J,
958
+ navigation: O,
959
+ dataStore: M,
960
+ application: A,
961
+ api: j,
962
+ notifications: N,
963
+ transfer: z,
964
+ closeDialog: k,
965
+ isCreate: B,
966
+ isEager: V,
967
+ relation: H,
968
+ ownerTransfer: U,
969
+ parentTransferId: W,
970
+ relationName: G
971
+ })) }) }) })
972
+ })]
973
+ });
974
+ }
975
+ function TranslatedDialogTitle({ pageDefinition: e, transferId: D }) {
976
+ let { title: O } = usePageTitle(e, D);
977
+ return O ? /* @__PURE__ */ jsx(DialogTitle, {
978
+ "data-testid": `page-dialog::${e["xmi:id"]}::title`,
979
+ children: O
980
+ }) : null;
981
+ }
982
+ function AppShellLayout({ children: e, logo: D, appBarExtra: O, menuLayout: k }) {
983
+ let [j, M] = useState(!0), [N, P] = useState(!1), { application: F } = useApplication(), I = k ?? F.defaultMenuLayout ?? MenuLayout.VERTICAL, L = I === MenuLayout.HORIZONTAL, R = N ? 64 : 280, z = L ? 0 : j ? R : 0;
984
+ return /* @__PURE__ */ jsxs(Box, {
985
+ sx: {
986
+ display: "flex",
987
+ minHeight: "100vh"
988
+ },
989
+ "data-testid": "app-shell-layout",
990
+ children: [
991
+ /* @__PURE__ */ jsx(AppBar, {
992
+ drawerWidth: z,
993
+ onMenuClick: L ? void 0 : () => M(!j),
994
+ logo: D,
995
+ extra: O,
996
+ menuLayout: I,
997
+ navigationController: F.navigationController
998
+ }),
999
+ !L && /* @__PURE__ */ jsx(NavigationDrawer, {
1000
+ open: j,
1001
+ collapsed: N,
1002
+ onCollapse: () => P(!N),
1003
+ width: j ? R : 0,
1004
+ navigationController: F.navigationController
1005
+ }),
1006
+ /* @__PURE__ */ jsxs(Box, {
1007
+ sx: {
1008
+ display: "flex",
1009
+ flexDirection: "column",
1010
+ flexGrow: 1,
1011
+ minHeight: "100vh",
1012
+ width: `calc(100% - ${z}px)`,
1013
+ transition: "width 0.2s"
1014
+ },
1015
+ children: [/* @__PURE__ */ jsxs(Box, {
1016
+ component: "main",
1017
+ sx: {
1018
+ flexGrow: 1,
1019
+ p: 3,
1020
+ mt: 8
1021
+ },
1022
+ "data-testid": "app-shell-layout::main",
1023
+ children: [/* @__PURE__ */ jsx(Breadcrumbs, {}), e]
1024
+ }), /* @__PURE__ */ jsx(Footer, {})]
1025
+ }),
1026
+ /* @__PURE__ */ jsx(PageDialogHost, {})
1027
+ ]
1028
+ });
1029
+ }
1030
+ function PrincipalBridge({ children: e }) {
1031
+ let D = useApi(), { application: O } = useApplication(), k = useCallback(async () => (await D.getPrincipal()).data, [D]);
1032
+ return /* @__PURE__ */ jsx(PrincipalProvider, {
1033
+ fetchPrincipal: O.authentication ? k : void 0,
1034
+ children: e
1035
+ });
1036
+ }
1037
+ function DefaultGuestPage({ application: e, signIn: D }) {
1038
+ return /* @__PURE__ */ jsx(Box, {
1039
+ display: "flex",
1040
+ justifyContent: "center",
1041
+ alignItems: "center",
1042
+ minHeight: "100vh",
1043
+ "data-testid": "guest-page",
1044
+ children: /* @__PURE__ */ jsxs(Paper, {
1045
+ elevation: 3,
1046
+ sx: {
1047
+ p: 4,
1048
+ maxWidth: 400,
1049
+ width: "100%",
1050
+ textAlign: "center"
1051
+ },
1052
+ children: [
1053
+ /* @__PURE__ */ jsx(Typography, {
1054
+ variant: "h4",
1055
+ gutterBottom: !0,
1056
+ "data-testid": "guest-page-title",
1057
+ children: e.title ?? e.name
1058
+ }),
1059
+ /* @__PURE__ */ jsx(Typography, {
1060
+ variant: "body1",
1061
+ color: "text.secondary",
1062
+ sx: { mb: 3 },
1063
+ children: "Sign in to access the application."
1064
+ }),
1065
+ /* @__PURE__ */ jsx(Button, {
1066
+ variant: "contained",
1067
+ size: "large",
1068
+ onClick: D,
1069
+ "data-testid": "guest-page-sign-in",
1070
+ children: "Sign In"
1071
+ })
1072
+ ]
1073
+ })
1074
+ });
1075
+ }
1076
+ function DefaultSettingsPage() {
1077
+ let { t: e } = useTranslation();
1078
+ return /* @__PURE__ */ jsx(Box, {
1079
+ sx: {
1080
+ display: "flex",
1081
+ justifyContent: "center",
1082
+ alignItems: "center",
1083
+ minHeight: "60vh"
1084
+ },
1085
+ "data-testid": "default-settings-page",
1086
+ children: /* @__PURE__ */ jsxs(Paper, {
1087
+ sx: {
1088
+ p: 4,
1089
+ textAlign: "center",
1090
+ maxWidth: 480
1091
+ },
1092
+ elevation: 2,
1093
+ children: [
1094
+ /* @__PURE__ */ jsx(SettingsIcon, { sx: {
1095
+ fontSize: 48,
1096
+ color: "text.secondary",
1097
+ mb: 2
1098
+ } }),
1099
+ /* @__PURE__ */ jsx(Typography, {
1100
+ variant: "h5",
1101
+ gutterBottom: !0,
1102
+ children: e("system.common.settings", { defaultValue: "Settings" })
1103
+ }),
1104
+ /* @__PURE__ */ jsx(Typography, {
1105
+ variant: "body1",
1106
+ color: "text.secondary",
1107
+ children: e("system.common.settingsPlaceholder", { defaultValue: "This page can be customized by providing a settingsPage component." })
1108
+ })
1109
+ ]
1110
+ })
1111
+ });
1112
+ }
1113
+ function generatePageEntityId(e) {
1114
+ return e.container?.type === "TABLE" ? `page::${e["xmi:id"]}` : null;
1115
+ }
1116
+ function PageRoute({ page: e }) {
1117
+ let { signedIdentifier: D } = useParams();
1118
+ return /* @__PURE__ */ jsx(PageProvider, {
1119
+ pageDefinition: e,
1120
+ transferId: useMemo(() => {
1121
+ let O = e.container;
1122
+ return O?.type === "VIEW" && D || O?.type === "TABLE" && D ? `transfer::${decodeURIComponent(D)}` : generatePageEntityId(e);
1123
+ }, [e, D]),
1124
+ params: useMemo(() => {
1125
+ if (D) return { signedIdentifier: decodeURIComponent(D) };
1126
+ }, [D]),
1127
+ children: /* @__PURE__ */ jsx(PageActionOverridesProvider, { children: /* @__PURE__ */ jsx(VisualPropertiesProvider, { children: /* @__PURE__ */ jsx(PageRenderer, { page: e }) }) })
1128
+ });
1129
+ }
1130
+ function RedirectPage() {
1131
+ let e = useCustomizationsOptional()?.getRedirectHandler();
1132
+ return e ? /* @__PURE__ */ jsx(e, {}) : /* @__PURE__ */ jsx("div", {
1133
+ "data-testid": "redirect-no-handler",
1134
+ children: /* @__PURE__ */ jsx("p", { children: "No redirect handler configured." })
1135
+ });
1136
+ }
1137
+ function generateRoutes({ application: e, DashboardPage: D, NotFoundPage: O, customRoutes: k, SettingsPage: A }) {
1138
+ let j = e.pages.map((e) => ({
1139
+ page: e,
1140
+ route: getRoutePattern(e)
1141
+ }));
1142
+ return /* @__PURE__ */ jsxs(Routes, { children: [
1143
+ !j.some(({ route: e }) => e === "/") && /* @__PURE__ */ jsx(Route, {
1144
+ path: "/",
1145
+ element: jsx(D || DefaultDashboard, { application: e })
1146
+ }),
1147
+ j.map(({ page: e, route: D }) => /* @__PURE__ */ jsx(Route, {
1148
+ path: D,
1149
+ element: /* @__PURE__ */ jsx(PageRoute, { page: e })
1150
+ }, e["xmi:id"])),
1151
+ /* @__PURE__ */ jsx(Route, {
1152
+ path: "/_redirect",
1153
+ element: /* @__PURE__ */ jsx(RedirectPage, {})
1154
+ }),
1155
+ /* @__PURE__ */ jsx(Route, {
1156
+ path: "/settings",
1157
+ element: jsx(A || DefaultSettingsPage, {})
1158
+ }),
1159
+ k?.map(({ path: e, element: D }) => /* @__PURE__ */ jsx(Route, {
1160
+ path: e,
1161
+ element: D
1162
+ }, e)),
1163
+ /* @__PURE__ */ jsx(Route, {
1164
+ path: "*",
1165
+ element: jsx(O || DefaultNotFound, {})
1166
+ })
1167
+ ] });
1168
+ }
1169
+ function DefaultDashboard({ application: e }) {
1170
+ return /* @__PURE__ */ jsx("div", {
1171
+ "data-testid": "dashboard",
1172
+ children: /* @__PURE__ */ jsxs("h1", { children: ["Welcome to ", e.name] })
1173
+ });
1174
+ }
1175
+ function DefaultNotFound() {
1176
+ return /* @__PURE__ */ jsx("div", {
1177
+ "data-testid": "not-found",
1178
+ children: /* @__PURE__ */ jsx("h1", { children: "404 - Page Not Found" })
1179
+ });
1180
+ }
1181
+ /**
1182
+ * @license React
1183
+ * react-is.production.js
1184
+ *
1185
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
1186
+ *
1187
+ * This source code is licensed under the MIT license found in the
1188
+ * LICENSE file in the root directory of this source tree.
1189
+ */
1190
+ var require_react_is_production = /* @__PURE__ */ __commonJSMin(((e) => {
1191
+ var D = Symbol.for("react.fragment"), O = Symbol.for("react.strict_mode"), k = Symbol.for("react.profiler"), A = Symbol.for("react.consumer"), j = Symbol.for("react.context"), M = Symbol.for("react.forward_ref"), N = Symbol.for("react.suspense"), P = Symbol.for("react.suspense_list"), F = Symbol.for("react.memo"), I = Symbol.for("react.lazy"), L = Symbol.for("react.client.reference");
1192
+ e.isValidElementType = function(e) {
1193
+ return !!(typeof e == "string" || typeof e == "function" || e === D || e === k || e === O || e === N || e === P || typeof e == "object" && e && (e.$$typeof === I || e.$$typeof === F || e.$$typeof === j || e.$$typeof === A || e.$$typeof === M || e.$$typeof === L || e.getModuleId !== void 0));
1194
+ };
1195
+ })), require_react_is_development = /* @__PURE__ */ __commonJSMin(((e) => {
1196
+ process.env.NODE_ENV !== "production" && (function() {
1197
+ function D(e) {
1198
+ if (typeof e == "object" && e) {
1199
+ var D = e.$$typeof;
1200
+ switch (D) {
1201
+ case O: switch (e = e.type, e) {
1202
+ case A:
1203
+ case M:
1204
+ case j:
1205
+ case I:
1206
+ case L:
1207
+ case B: return e;
1208
+ default: switch (e &&= e.$$typeof, e) {
1209
+ case P:
1210
+ case F:
1211
+ case z:
1212
+ case R: return e;
1213
+ case N: return e;
1214
+ default: return D;
1215
+ }
1216
+ }
1217
+ case k: return D;
1218
+ }
1219
+ }
1220
+ }
1221
+ var O = Symbol.for("react.transitional.element"), k = Symbol.for("react.portal"), A = Symbol.for("react.fragment"), j = Symbol.for("react.strict_mode"), M = Symbol.for("react.profiler"), N = Symbol.for("react.consumer"), P = Symbol.for("react.context"), F = Symbol.for("react.forward_ref"), I = Symbol.for("react.suspense"), L = Symbol.for("react.suspense_list"), R = Symbol.for("react.memo"), z = Symbol.for("react.lazy"), B = Symbol.for("react.view_transition"), V = Symbol.for("react.client.reference");
1222
+ e.ContextConsumer = N, e.ContextProvider = P, e.Element = O, e.ForwardRef = F, e.Fragment = A, e.Lazy = z, e.Memo = R, e.Portal = k, e.Profiler = M, e.StrictMode = j, e.Suspense = I, e.SuspenseList = L, e.isContextConsumer = function(e) {
1223
+ return D(e) === N;
1224
+ }, e.isContextProvider = function(e) {
1225
+ return D(e) === P;
1226
+ }, e.isElement = function(e) {
1227
+ return typeof e == "object" && !!e && e.$$typeof === O;
1228
+ }, e.isForwardRef = function(e) {
1229
+ return D(e) === F;
1230
+ }, e.isFragment = function(e) {
1231
+ return D(e) === A;
1232
+ }, e.isLazy = function(e) {
1233
+ return D(e) === z;
1234
+ }, e.isMemo = function(e) {
1235
+ return D(e) === R;
1236
+ }, e.isPortal = function(e) {
1237
+ return D(e) === k;
1238
+ }, e.isProfiler = function(e) {
1239
+ return D(e) === M;
1240
+ }, e.isStrictMode = function(e) {
1241
+ return D(e) === j;
1242
+ }, e.isSuspense = function(e) {
1243
+ return D(e) === I;
1244
+ }, e.isSuspenseList = function(e) {
1245
+ return D(e) === L;
1246
+ }, e.isValidElementType = function(e) {
1247
+ return !!(typeof e == "string" || typeof e == "function" || e === A || e === M || e === j || e === I || e === L || typeof e == "object" && e && (e.$$typeof === z || e.$$typeof === R || e.$$typeof === P || e.$$typeof === N || e.$$typeof === F || e.$$typeof === V || e.getModuleId !== void 0));
1248
+ }, e.typeOf = D;
1249
+ })();
1250
+ })), import_react_is = (/* @__PURE__ */ __commonJSMin(((e, D) => {
1251
+ process.env.NODE_ENV === "production" ? D.exports = require_react_is_production() : D.exports = require_react_is_development();
1252
+ })))();
1253
+ function isPlainObject(e) {
1254
+ if (typeof e != "object" || !e) return !1;
1255
+ let D = Object.getPrototypeOf(e);
1256
+ return (D === null || D === Object.prototype || Object.getPrototypeOf(D) === null) && !(Symbol.toStringTag in e) && !(Symbol.iterator in e);
1257
+ }
1258
+ function deepClone(e) {
1259
+ if (/* @__PURE__ */ React.isValidElement(e) || (0, import_react_is.isValidElementType)(e) || !isPlainObject(e)) return e;
1260
+ let D = {};
1261
+ return Object.keys(e).forEach((O) => {
1262
+ D[O] = deepClone(e[O]);
1263
+ }), D;
1264
+ }
1265
+ function deepmerge(e, D, O = { clone: !0 }) {
1266
+ let k = O.clone ? { ...e } : e;
1267
+ return isPlainObject(e) && isPlainObject(D) && Object.keys(D).forEach((A) => {
1268
+ /* @__PURE__ */ React.isValidElement(D[A]) || (0, import_react_is.isValidElementType)(D[A]) ? k[A] = D[A] : isPlainObject(D[A]) && Object.prototype.hasOwnProperty.call(e, A) && isPlainObject(e[A]) ? k[A] = deepmerge(e[A], D[A], O) : O.clone ? k[A] = isPlainObject(D[A]) ? deepClone(D[A]) : D[A] : k[A] = D[A];
1269
+ }), k;
1270
+ }
1271
+ function createDensityThemeOptions(e) {
1272
+ switch (e) {
1273
+ case "compact": return {
1274
+ spacing: 6,
1275
+ typography: { fontSize: 13 },
1276
+ components: {
1277
+ MuiButton: { defaultProps: { size: "small" } },
1278
+ MuiTextField: { defaultProps: {
1279
+ size: "small",
1280
+ margin: "dense"
1281
+ } },
1282
+ MuiFormControl: { defaultProps: {
1283
+ size: "small",
1284
+ margin: "dense"
1285
+ } },
1286
+ MuiInputBase: { defaultProps: { size: "small" } },
1287
+ MuiInputLabel: { defaultProps: { size: "small" } },
1288
+ MuiSelect: { defaultProps: {
1289
+ size: "small",
1290
+ margin: "dense"
1291
+ } },
1292
+ MuiIconButton: { defaultProps: { size: "small" } },
1293
+ MuiToolbar: { defaultProps: { variant: "dense" } },
1294
+ MuiTable: { defaultProps: { size: "small" } },
1295
+ MuiTableCell: { styleOverrides: { root: { padding: "4px 8px" } } },
1296
+ MuiCardContent: { styleOverrides: { root: { padding: "12px" } } },
1297
+ MuiDataGrid: { defaultProps: { density: "compact" } },
1298
+ MuiDataGridPro: { defaultProps: { density: "compact" } }
1299
+ }
1300
+ };
1301
+ case "standard": return {
1302
+ spacing: 10,
1303
+ typography: { fontSize: 15 },
1304
+ components: {
1305
+ MuiButton: { defaultProps: { size: "large" } },
1306
+ MuiTextField: { defaultProps: {
1307
+ size: "medium",
1308
+ margin: "normal"
1309
+ } },
1310
+ MuiFormControl: { defaultProps: {
1311
+ size: "medium",
1312
+ margin: "normal"
1313
+ } },
1314
+ MuiToolbar: { defaultProps: { variant: "regular" } },
1315
+ MuiTableCell: { styleOverrides: { root: { padding: "12px 16px" } } },
1316
+ MuiCardContent: { styleOverrides: { root: { padding: "20px" } } },
1317
+ MuiDataGrid: { defaultProps: { density: "comfortable" } },
1318
+ MuiDataGridPro: { defaultProps: { density: "comfortable" } }
1319
+ }
1320
+ };
1321
+ case "comfortable":
1322
+ default: return {};
1323
+ }
1324
+ }
1325
+ function hexAlpha(e, D) {
1326
+ return `${e}${Math.round(D * 255).toString(16).padStart(2, "0")}`;
1327
+ }
1328
+ function createJudoThemeOptions(e) {
1329
+ let { primaryColor: D, secondaryColor: O, mode: k, lightBackground: A, darkBackground: j } = e, M = k === "light";
1330
+ return {
1331
+ palette: {
1332
+ mode: k,
1333
+ primary: { main: D },
1334
+ secondary: { main: O },
1335
+ background: M ? {
1336
+ default: A ?? "#F5F6FA",
1337
+ paper: "#FFFFFF"
1338
+ } : {
1339
+ default: j ?? "#0A1929",
1340
+ paper: "#132F4C"
1341
+ },
1342
+ divider: M ? "rgba(0, 0, 0, 0.08)" : "rgba(255, 255, 255, 0.08)"
1343
+ },
1344
+ shape: { borderRadius: 8 },
1345
+ typography: {
1346
+ fontFamily: [
1347
+ "\"Inter\"",
1348
+ "\"Segoe UI\"",
1349
+ "\"Roboto\"",
1350
+ "\"Helvetica Neue\"",
1351
+ "Arial",
1352
+ "sans-serif"
1353
+ ].join(","),
1354
+ h1: {
1355
+ fontWeight: 700,
1356
+ letterSpacing: "-0.02em"
1357
+ },
1358
+ h2: {
1359
+ fontWeight: 700,
1360
+ letterSpacing: "-0.01em"
1361
+ },
1362
+ h3: { fontWeight: 600 },
1363
+ h4: { fontWeight: 600 },
1364
+ h5: { fontWeight: 600 },
1365
+ h6: { fontWeight: 600 },
1366
+ subtitle1: { fontWeight: 500 },
1367
+ subtitle2: { fontWeight: 500 },
1368
+ button: {
1369
+ fontWeight: 600,
1370
+ textTransform: "none"
1371
+ }
1372
+ },
1373
+ shadows: createModernShadows(M),
1374
+ components: {
1375
+ MuiCssBaseline: { styleOverrides: {
1376
+ "*, *::before, *::after": { boxSizing: "border-box" },
1377
+ body: {
1378
+ WebkitFontSmoothing: "antialiased",
1379
+ MozOsxFontSmoothing: "grayscale"
1380
+ },
1381
+ "@keyframes judoFadeInUp": {
1382
+ from: {
1383
+ opacity: 0,
1384
+ transform: "translateY(8px)"
1385
+ },
1386
+ to: {
1387
+ opacity: 1,
1388
+ transform: "translateY(0)"
1389
+ }
1390
+ },
1391
+ "@keyframes judoFadeIn": {
1392
+ from: { opacity: 0 },
1393
+ to: { opacity: 1 }
1394
+ },
1395
+ "*::-webkit-scrollbar": {
1396
+ width: 6,
1397
+ height: 6
1398
+ },
1399
+ "*::-webkit-scrollbar-track": { background: "transparent" },
1400
+ "*::-webkit-scrollbar-thumb": {
1401
+ background: M ? "rgba(0,0,0,0.15)" : "rgba(255,255,255,0.15)",
1402
+ borderRadius: 3
1403
+ },
1404
+ "*::-webkit-scrollbar-thumb:hover": { background: M ? "rgba(0,0,0,0.25)" : "rgba(255,255,255,0.25)" }
1405
+ } },
1406
+ MuiPaper: {
1407
+ defaultProps: { elevation: 0 },
1408
+ styleOverrides: {
1409
+ root: {
1410
+ backgroundImage: M ? "linear-gradient(135deg, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0.7) 100%)" : "linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%)",
1411
+ border: `1px solid ${M ? "rgba(0, 0, 0, 0.08)" : "rgba(255, 255, 255, 0.08)"}`,
1412
+ transition: "box-shadow 0.25s cubic-bezier(0.4,0,0.2,1), border-color 0.25s cubic-bezier(0.4,0,0.2,1), transform 0.25s cubic-bezier(0.4,0,0.2,1)"
1413
+ },
1414
+ elevation0: { border: `1px solid ${M ? "rgba(0, 0, 0, 0.08)" : "rgba(255, 255, 255, 0.08)"}` }
1415
+ }
1416
+ },
1417
+ MuiCard: {
1418
+ defaultProps: { elevation: 0 },
1419
+ styleOverrides: { root: {
1420
+ border: `1px solid ${M ? "rgba(0, 0, 0, 0.08)" : "rgba(255, 255, 255, 0.08)"}`,
1421
+ transition: "box-shadow 0.3s cubic-bezier(0.4,0,0.2,1), border-color 0.3s cubic-bezier(0.4,0,0.2,1), transform 0.25s cubic-bezier(0.4,0,0.2,1)",
1422
+ "&:hover": {
1423
+ borderColor: hexAlpha(D, .3),
1424
+ boxShadow: M ? `0 4px 16px ${hexAlpha(D, .12)}` : `0 4px 16px ${hexAlpha(D, .2)}`,
1425
+ transform: "translateY(-1px)"
1426
+ }
1427
+ } }
1428
+ },
1429
+ MuiAppBar: {
1430
+ defaultProps: { elevation: 0 },
1431
+ styleOverrides: { root: {
1432
+ backgroundImage: "none",
1433
+ borderBottom: `1px solid ${M ? "rgba(0, 0, 0, 0.08)" : "rgba(255, 255, 255, 0.08)"}`
1434
+ } }
1435
+ },
1436
+ MuiButton: {
1437
+ defaultProps: { disableElevation: !0 },
1438
+ styleOverrides: {
1439
+ root: {
1440
+ textTransform: "none",
1441
+ fontWeight: 600,
1442
+ borderRadius: 6,
1443
+ transition: "all 0.15s ease"
1444
+ },
1445
+ containedPrimary: { "&:hover": { boxShadow: `0 2px 8px ${hexAlpha(D, .35)}` } },
1446
+ containedSecondary: { "&:hover": { boxShadow: `0 2px 8px ${hexAlpha(O, .35)}` } },
1447
+ outlined: {
1448
+ borderWidth: 1.5,
1449
+ "&:hover": { borderWidth: 1.5 }
1450
+ }
1451
+ }
1452
+ },
1453
+ MuiButtonGroup: { defaultProps: { disableElevation: !0 } },
1454
+ MuiIconButton: { styleOverrides: { root: {
1455
+ borderRadius: 8,
1456
+ transition: "background-color 0.15s ease"
1457
+ } } },
1458
+ MuiFab: {
1459
+ defaultProps: { color: "secondary" },
1460
+ styleOverrides: { root: { boxShadow: `0 3px 12px ${hexAlpha(O, .3)}` } }
1461
+ },
1462
+ MuiTextField: { defaultProps: {
1463
+ variant: "outlined",
1464
+ size: "small"
1465
+ } },
1466
+ MuiOutlinedInput: { styleOverrides: {
1467
+ root: {
1468
+ borderRadius: 6,
1469
+ "&.Mui-focused .MuiOutlinedInput-notchedOutline": { borderWidth: 2 }
1470
+ },
1471
+ notchedOutline: {
1472
+ borderColor: M ? "rgba(0, 0, 0, 0.15)" : "rgba(255, 255, 255, 0.15)",
1473
+ transition: "border-color 0.15s ease"
1474
+ }
1475
+ } },
1476
+ MuiInputLabel: { styleOverrides: { root: { fontWeight: 500 } } },
1477
+ MuiSelect: { defaultProps: { size: "small" } },
1478
+ MuiAutocomplete: { styleOverrides: { paper: {
1479
+ borderRadius: 8,
1480
+ marginTop: 4,
1481
+ boxShadow: M ? "0 4px 20px rgba(0,0,0,0.1)" : "0 4px 20px rgba(0,0,0,0.4)"
1482
+ } } },
1483
+ MuiCheckbox: { defaultProps: { color: "primary" } },
1484
+ MuiRadio: { defaultProps: { color: "primary" } },
1485
+ MuiSwitch: { defaultProps: { color: "primary" } },
1486
+ MuiListItemButton: { styleOverrides: { root: {
1487
+ borderRadius: 6,
1488
+ margin: "1px 4px",
1489
+ transition: "background-color 0.15s ease",
1490
+ "&.Mui-selected": {
1491
+ backgroundColor: hexAlpha(D, .1),
1492
+ "&:hover": { backgroundColor: hexAlpha(D, .16) }
1493
+ }
1494
+ } } },
1495
+ MuiListItemIcon: { styleOverrides: { root: { minWidth: 36 } } },
1496
+ MuiTab: { styleOverrides: { root: {
1497
+ textTransform: "none",
1498
+ fontWeight: 500,
1499
+ minHeight: 40
1500
+ } } },
1501
+ MuiTabs: { styleOverrides: { indicator: {
1502
+ height: 2.5,
1503
+ borderRadius: "2px 2px 0 0"
1504
+ } } },
1505
+ MuiTableHead: { styleOverrides: { root: { "& .MuiTableCell-head": {
1506
+ fontWeight: 600,
1507
+ backgroundColor: M ? "rgba(0, 0, 0, 0.02)" : "rgba(255, 255, 255, 0.03)",
1508
+ borderBottom: `2px solid ${M ? "rgba(0, 0, 0, 0.1)" : "rgba(255, 255, 255, 0.1)"}`
1509
+ } } } },
1510
+ MuiTableRow: { styleOverrides: { root: { "&:last-child td": { borderBottom: 0 } } } },
1511
+ MuiDataGrid: { styleOverrides: { root: {
1512
+ border: `1px solid ${M ? "rgba(0, 0, 0, 0.08)" : "rgba(255, 255, 255, 0.08)"}`,
1513
+ borderRadius: 8,
1514
+ "& .MuiDataGrid-columnHeaders": { backgroundColor: M ? "rgba(0, 0, 0, 0.02)" : "rgba(255, 255, 255, 0.03)" },
1515
+ "& .MuiDataGrid-columnHeaderTitle": { fontWeight: 600 },
1516
+ "& .MuiDataGrid-row:hover": { backgroundColor: M ? hexAlpha(D, .04) : hexAlpha(D, .08) },
1517
+ "& .MuiDataGrid-row.Mui-selected": {
1518
+ backgroundColor: hexAlpha(D, .08),
1519
+ "&:hover": { backgroundColor: hexAlpha(D, .12) }
1520
+ },
1521
+ "& .MuiDataGrid-cell:focus": {
1522
+ outline: `2px solid ${D}`,
1523
+ outlineOffset: -2
1524
+ }
1525
+ } } },
1526
+ MuiDialog: {
1527
+ defaultProps: { PaperProps: { elevation: 0 } },
1528
+ styleOverrides: {
1529
+ paper: {
1530
+ borderRadius: 16,
1531
+ boxShadow: M ? `0 20px 60px rgba(0,0,0,0.15), 0 0 0 1px ${hexAlpha(D, .06)}` : `0 20px 60px rgba(0,0,0,0.6), 0 0 0 1px ${hexAlpha(D, .1)}`
1532
+ },
1533
+ root: { "& .MuiBackdrop-root": {
1534
+ backdropFilter: "blur(4px)",
1535
+ backgroundColor: M ? "rgba(0, 0, 0, 0.3)" : "rgba(0, 0, 0, 0.5)"
1536
+ } }
1537
+ }
1538
+ },
1539
+ MuiDialogTitle: { styleOverrides: { root: {
1540
+ fontWeight: 600,
1541
+ fontSize: "1.1rem"
1542
+ } } },
1543
+ MuiChip: { styleOverrides: { root: {
1544
+ fontWeight: 500,
1545
+ borderRadius: 6,
1546
+ transition: "background-color 0.2s ease, box-shadow 0.2s ease"
1547
+ } } },
1548
+ MuiBadge: { styleOverrides: { standard: { fontWeight: 600 } } },
1549
+ MuiTooltip: {
1550
+ defaultProps: { arrow: !0 },
1551
+ styleOverrides: { tooltip: {
1552
+ borderRadius: 6,
1553
+ fontSize: "0.75rem",
1554
+ fontWeight: 500
1555
+ } }
1556
+ },
1557
+ MuiAlert: {
1558
+ defaultProps: { variant: "outlined" },
1559
+ styleOverrides: { root: { borderRadius: 8 } }
1560
+ },
1561
+ MuiDrawer: { styleOverrides: { paper: {
1562
+ borderRight: `1px solid ${M ? "rgba(0, 0, 0, 0.08)" : "rgba(255, 255, 255, 0.08)"}`,
1563
+ backgroundImage: M ? "linear-gradient(180deg, rgba(255,255,255,0.95) 0%, rgba(245,246,250,0.95) 100%)" : "linear-gradient(180deg, rgba(19,47,76,0.95) 0%, rgba(10,25,41,0.95) 100%)"
1564
+ } } },
1565
+ MuiBreadcrumbs: { styleOverrides: { root: { fontSize: "0.8rem" } } },
1566
+ MuiToolbar: { styleOverrides: { root: { minHeight: "52px !important" } } }
1567
+ }
1568
+ };
1569
+ }
1570
+ function createModernShadows(e) {
1571
+ let D = "0,0,0";
1572
+ return [
1573
+ "none",
1574
+ `0 1px 2px rgba(${D},0.06)`,
1575
+ `0 1px 4px rgba(${D},0.08)`,
1576
+ `0 2px 6px rgba(${D},0.1)`,
1577
+ `0 2px 8px rgba(${D},0.1)`,
1578
+ `0 3px 10px rgba(${D},0.1)`,
1579
+ `0 3px 12px rgba(${D},0.12)`,
1580
+ `0 4px 14px rgba(${D},0.12)`,
1581
+ `0 4px 16px rgba(${D},0.14)`,
1582
+ `0 5px 18px rgba(${D},0.14)`,
1583
+ `0 5px 20px rgba(${D},0.14)`,
1584
+ `0 6px 22px rgba(${D},0.14)`,
1585
+ `0 6px 24px rgba(${D},0.16)`,
1586
+ `0 7px 26px rgba(${D},0.16)`,
1587
+ `0 7px 28px rgba(${D},0.16)`,
1588
+ `0 8px 30px rgba(${D},0.16)`,
1589
+ `0 8px 32px rgba(${D},0.18)`,
1590
+ `0 9px 34px rgba(${D},0.18)`,
1591
+ `0 9px 36px rgba(${D},0.18)`,
1592
+ `0 10px 38px rgba(${D},0.18)`,
1593
+ `0 10px 40px rgba(${D},0.2)`,
1594
+ `0 11px 42px rgba(${D},0.2)`,
1595
+ `0 11px 44px rgba(${D},0.2)`,
1596
+ `0 12px 46px rgba(${D},0.2)`,
1597
+ `0 12px 48px rgba(${D},0.22)`
1598
+ ];
1599
+ }
1600
+ const themePresets = {
1601
+ corporate: {
1602
+ name: "Corporate",
1603
+ primaryColor: "#1565C0",
1604
+ secondaryColor: "#00897B",
1605
+ lightBackground: "#F5F6FA",
1606
+ darkBackground: "#0A1929"
1607
+ },
1608
+ ocean: {
1609
+ name: "Ocean",
1610
+ primaryColor: "#0277BD",
1611
+ secondaryColor: "#26A69A",
1612
+ lightBackground: "#F0F7FA",
1613
+ darkBackground: "#0D1B2A"
1614
+ },
1615
+ slate: {
1616
+ name: "Slate",
1617
+ primaryColor: "#37474F",
1618
+ secondaryColor: "#FF8F00",
1619
+ lightBackground: "#F7F8F9",
1620
+ darkBackground: "#121212"
1621
+ },
1622
+ indigo: {
1623
+ name: "Indigo",
1624
+ primaryColor: "#283593",
1625
+ secondaryColor: "#F4511E",
1626
+ lightBackground: "#F5F5FB",
1627
+ darkBackground: "#0D0D2B"
1628
+ },
1629
+ forest: {
1630
+ name: "Forest",
1631
+ primaryColor: "#2E7D32",
1632
+ secondaryColor: "#00695C",
1633
+ lightBackground: "#F4F8F4",
1634
+ darkBackground: "#0A1F0A"
1635
+ },
1636
+ royal: {
1637
+ name: "Royal",
1638
+ primaryColor: "#4527A0",
1639
+ secondaryColor: "#AD1457",
1640
+ lightBackground: "#F6F3FA",
1641
+ darkBackground: "#1A0A2E"
1642
+ }
1643
+ };
1644
+ function resolvePreset(e) {
1645
+ return themePresets[e];
1646
+ }
1647
+ function ThemeProvider({ children: e }) {
1648
+ let { config: D } = useTheme(), { mode: O, primaryColor: k, secondaryColor: A, muiThemeOptions: j, density: M, preset: N } = D;
1649
+ return /* @__PURE__ */ jsxs(ThemeProvider$1, {
1650
+ theme: useMemo(() => {
1651
+ let e = resolvePreset(N || "corporate"), D = k ?? e?.primaryColor, P = A ?? e?.secondaryColor;
1652
+ return createTheme(deepmerge(deepmerge(D && P ? createJudoThemeOptions({
1653
+ primaryColor: D,
1654
+ secondaryColor: P,
1655
+ mode: O,
1656
+ lightBackground: e?.lightBackground,
1657
+ darkBackground: e?.darkBackground
1658
+ }) : { palette: {
1659
+ mode: O,
1660
+ background: O === "light" ? { default: "#F5F6FA" } : {},
1661
+ ...D && { primary: { main: D } },
1662
+ ...P && { secondary: { main: P } }
1663
+ } }, createDensityThemeOptions(M ?? "compact")), j ?? {}));
1664
+ }, [
1665
+ O,
1666
+ k,
1667
+ A,
1668
+ j,
1669
+ M,
1670
+ N
1671
+ ]),
1672
+ children: [/* @__PURE__ */ jsx(CssBaseline, {}), e]
1673
+ });
1674
+ }
1675
+ function DefaultErrorScreen({ error: D, onRetry: O }) {
1676
+ return /* @__PURE__ */ jsxs(Box, {
1677
+ "data-testid": "error-screen",
1678
+ sx: {
1679
+ display: "flex",
1680
+ flexDirection: "column",
1681
+ alignItems: "center",
1682
+ justifyContent: "center",
1683
+ minHeight: "100vh",
1684
+ gap: 3,
1685
+ p: 4
1686
+ },
1687
+ children: [
1688
+ /* @__PURE__ */ jsx(Typography, {
1689
+ variant: "h5",
1690
+ component: "h1",
1691
+ color: "error",
1692
+ children: "Application Error"
1693
+ }),
1694
+ /* @__PURE__ */ jsx(Alert, {
1695
+ severity: "error",
1696
+ sx: { maxWidth: 600 },
1697
+ children: /* @__PURE__ */ jsx(Typography, {
1698
+ variant: "body2",
1699
+ component: "pre",
1700
+ sx: {
1701
+ whiteSpace: "pre-wrap",
1702
+ wordBreak: "break-word"
1703
+ },
1704
+ children: D.message
1705
+ })
1706
+ }),
1707
+ O && /* @__PURE__ */ jsx(Button, {
1708
+ variant: "contained",
1709
+ startIcon: /* @__PURE__ */ jsx(RefreshIcon, {}),
1710
+ onClick: O,
1711
+ children: "Retry"
1712
+ }),
1713
+ !1
1714
+ ]
1715
+ });
1716
+ }
1717
+ function DefaultLoadingScreen() {
1718
+ return /* @__PURE__ */ jsxs(Box, {
1719
+ "data-testid": "loading-screen",
1720
+ sx: {
1721
+ display: "flex",
1722
+ flexDirection: "column",
1723
+ alignItems: "center",
1724
+ justifyContent: "center",
1725
+ minHeight: "100vh",
1726
+ gap: 2
1727
+ },
1728
+ children: [/* @__PURE__ */ jsx(CircularProgress, { size: 48 }), /* @__PURE__ */ jsx(Typography, {
1729
+ variant: "body1",
1730
+ color: "text.secondary",
1731
+ children: "Loading application..."
1732
+ })]
1733
+ });
1734
+ }
1735
+ function getInitialMode() {
1736
+ if (typeof window > "u") return "light";
1737
+ let e = localStorage.getItem("theme-mode");
1738
+ return e === "light" || e === "dark" ? e : typeof window.matchMedia == "function" && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
1739
+ }
1740
+ function JudoRuntime({ config: e = {}, modelSource: D, logo: O, appBarExtra: k, loadingComponent: A, errorComponent: j, children: M, customizations: N }) {
1741
+ let P = useMemo(() => ({
1742
+ ...e,
1743
+ model: {
1744
+ ...e.model,
1745
+ source: D ?? e.model?.source
1746
+ }
1747
+ }), [e, D]), [I, L] = useState({
1748
+ phase: "initializing",
1749
+ error: null
1750
+ }), [R, z] = useState(null), [B, V] = useState(null), [H, U] = useState({}), [W, G] = useState(0);
1751
+ useEffect(() => {
1752
+ let e = !1;
1753
+ async function D() {
1754
+ try {
1755
+ L({
1756
+ phase: "loading",
1757
+ error: null
1758
+ });
1759
+ let D = P.model?.source;
1760
+ if (!D) throw Error("No model source provided. Pass modelSource prop or config.model.source.");
1761
+ let O;
1762
+ if (O = typeof D == "function" ? await new EmbeddedModelLoader(await D()).load() : await new HttpModelLoader().load(D), O.length === 0) throw Error("No applications found in model");
1763
+ if (e) return;
1764
+ let k = new ModelRegistry();
1765
+ if (k.registerModel(O), k.setActiveApplication(P.model?.initialApplication ?? O[0].name), e) return;
1766
+ let A = k.getActiveApplication(), j = createJudoRestApi({
1767
+ baseUrl: `${P.api?.baseUrl ?? window.location.origin}/api`,
1768
+ application: A,
1769
+ timeout: P.api?.timeout,
1770
+ defaultHeaders: P.api?.headers
1771
+ });
1772
+ if (e) return;
1773
+ let M = {};
1774
+ if (P.muiProLicenseKey) try {
1775
+ let [e, D] = await Promise.all([import("@mui/x-license"), import("@mui/x-data-grid-pro")]);
1776
+ e.LicenseInfo.setLicenseKey(P.muiProLicenseKey), M = { DataGrid: D.DataGridPro };
1777
+ } catch {}
1778
+ if (e) return;
1779
+ z(k), V(j), U(M), L({
1780
+ phase: "ready",
1781
+ error: null
1782
+ });
1783
+ } catch (D) {
1784
+ if (e) return;
1785
+ L({
1786
+ phase: "error",
1787
+ error: D instanceof Error ? D : Error(String(D))
1788
+ });
1789
+ }
1790
+ }
1791
+ return D(), () => {
1792
+ e = !0;
1793
+ };
1794
+ }, [P, W]);
1795
+ let K = useCallback(() => {
1796
+ G((e) => e + 1);
1797
+ }, []), q = useMemo(() => {
1798
+ switch (P.router?.type ?? "browser") {
1799
+ case "hash": return HashRouter;
1800
+ case "memory": return MemoryRouter;
1801
+ default: return BrowserRouter;
1802
+ }
1803
+ }, [P.router?.type]);
1804
+ useEffect(() => {
1805
+ let e = P.theme ?? {}, D = e.defaultMode === "system" || e.defaultMode === void 0;
1806
+ initializeThemeStore({
1807
+ mode: e.defaultMode === "dark" ? "dark" : e.defaultMode === "light" ? "light" : getInitialMode(),
1808
+ primaryColor: e.primaryColor,
1809
+ secondaryColor: e.secondaryColor,
1810
+ muiThemeOptions: e.muiThemeOptions,
1811
+ density: e.density,
1812
+ preset: e.preset
1813
+ }, D);
1814
+ }, [P.theme]);
1815
+ let J = useMemo(() => {
1816
+ let e = P.theme ?? {}, D = { palette: {
1817
+ mode: e.defaultMode === "dark" ? "dark" : e.defaultMode === "light" ? "light" : getInitialMode(),
1818
+ ...e.primaryColor && { primary: { main: e.primaryColor } },
1819
+ ...e.secondaryColor && { secondary: { main: e.secondaryColor } }
1820
+ } };
1821
+ return e.muiThemeOptions ? createTheme(D, e.muiThemeOptions) : createTheme(D);
1822
+ }, [P.theme]), Y = useMemo(() => {
1823
+ let e = P.auth;
1824
+ return e?.skip || !e?.oidc ? null : createOidcOptions(e.oidc);
1825
+ }, [P.auth]);
1826
+ if (I.phase === "initializing" || I.phase === "loading") return /* @__PURE__ */ jsxs(ThemeProvider$1, {
1827
+ theme: J,
1828
+ children: [/* @__PURE__ */ jsx(CssBaseline, {}), A ?? /* @__PURE__ */ jsx(DefaultLoadingScreen, {})]
1829
+ });
1830
+ if (I.phase === "error" && I.error) {
1831
+ let e = typeof j == "function" ? j(I.error, K) : j ?? /* @__PURE__ */ jsx(DefaultErrorScreen, {
1832
+ error: I.error,
1833
+ onRetry: K
1834
+ });
1835
+ return /* @__PURE__ */ jsxs(ThemeProvider$1, {
1836
+ theme: J,
1837
+ children: [/* @__PURE__ */ jsx(CssBaseline, {}), e]
1838
+ });
1839
+ }
1840
+ if (!R || !B) return null;
1841
+ let X = Object.keys(H).length > 0, Z = {
1842
+ features: P.features,
1843
+ density: P.theme?.density,
1844
+ muiProLicenseKey: P.muiProLicenseKey
1845
+ }, Q = R.getActiveApplication().defaultLanguage ?? "en-US", $ = P.i18n;
1846
+ return /* @__PURE__ */ jsx(CustomizationsProvider, {
1847
+ customizations: N,
1848
+ children: /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(FeedbackProvider, { children: /* @__PURE__ */ jsx(ApiProvider, {
1849
+ api: B,
1850
+ children: /* @__PURE__ */ jsx(RuntimeConfigProvider, {
1851
+ config: Z,
1852
+ children: /* @__PURE__ */ jsx(MuiProProvider, {
1853
+ isProEnabled: X,
1854
+ components: H,
1855
+ children: /* @__PURE__ */ jsxs(ApplicationProvider, {
1856
+ registry: R,
1857
+ children: [/* @__PURE__ */ jsxs(ExpressionProvider, { children: [/* @__PURE__ */ jsx(I18nProvider, {
1858
+ defaultLocale: Q,
1859
+ locales: $?.locales,
1860
+ localeLoader: $?.localeLoader,
1861
+ translationKeyMap: $?.translationKeyMap,
1862
+ persistLocale: $?.persistLocale,
1863
+ children: /* @__PURE__ */ jsx(AuthBridge, {
1864
+ oidcOptions: Y,
1865
+ skipAuth: P.auth?.skip,
1866
+ loadingComponent: A,
1867
+ children: /* @__PURE__ */ jsx(DataProvider, { children: /* @__PURE__ */ jsx(q, {
1868
+ basename: P.router?.basePath,
1869
+ children: /* @__PURE__ */ jsx(NavigationProviderBridge, {
1870
+ logo: O,
1871
+ appBarExtra: k,
1872
+ menuLayout: P.menuLayout,
1873
+ children: M ?? /* @__PURE__ */ jsx(ApplicationRoutes, {})
1874
+ })
1875
+ }) })
1876
+ })
1877
+ }), " "] }), " "]
1878
+ })
1879
+ })
1880
+ })
1881
+ }) }) })
1882
+ });
1883
+ }
1884
+ function AuthBridge({ oidcOptions: e, skipAuth: D, loadingComponent: O, children: k }) {
1885
+ let { application: A } = useApplication(), j = useCustomizationsOptional(), M = useMemo(() => getAuthConfig(A), [A]);
1886
+ if (D || !e) return /* @__PURE__ */ jsx(Fragment, { children: k });
1887
+ let N = String(A.supportGuestAccess) === "true", P = j?.getGuestComponent() ?? DefaultGuestPage;
1888
+ return /* @__PURE__ */ jsxs(JudoAuthProvider, {
1889
+ config: M,
1890
+ oidcOptions: e,
1891
+ children: [/* @__PURE__ */ jsx(AuthTokenSync, {}), /* @__PURE__ */ jsx(ActorAuthBoundary, {
1892
+ loadingComponent: O,
1893
+ supportGuestAccess: N,
1894
+ guestComponent: N ? /* @__PURE__ */ jsx(GuestPageBridge, {
1895
+ application: A,
1896
+ GuestComponent: P
1897
+ }) : void 0,
1898
+ children: /* @__PURE__ */ jsx(PrincipalBridge, { children: k })
1899
+ })]
1900
+ });
1901
+ }
1902
+ function GuestPageBridge({ application: e, GuestComponent: D }) {
1903
+ let { signinRedirect: O } = useAuth();
1904
+ return /* @__PURE__ */ jsx(D, {
1905
+ application: e,
1906
+ signIn: useCallback(() => {
1907
+ O();
1908
+ }, [O])
1909
+ });
1910
+ }
1911
+ function AuthTokenSync() {
1912
+ let { user: e } = useAuth(), D = useApi(), O = useRef(void 0);
1913
+ return useEffect(() => {
1914
+ let k = e?.access_token;
1915
+ k !== O.current && (O.current = k, k ? D.setDefaultHeaders({ Authorization: `Bearer ${k}` }) : D.setDefaultHeaders({}));
1916
+ }, [D, e?.access_token]), null;
1917
+ }
1918
+ function NavigationProviderBridge({ logo: e, appBarExtra: D, menuLayout: O, children: k }) {
1919
+ return /* @__PURE__ */ jsx(NavigationProvider, {
1920
+ navigate: useNavigate(),
1921
+ getRouteForPage,
1922
+ children: /* @__PURE__ */ jsx(AppShellLayout, {
1923
+ logo: e,
1924
+ appBarExtra: D,
1925
+ menuLayout: O,
1926
+ children: k
1927
+ })
1928
+ });
1929
+ }
1930
+ function ApplicationRoutes() {
1931
+ let { application: e } = useApplication(), D = useCustomizationsOptional(), O = D?.getCustomRoutes(), k = D?.getSettingsPage();
1932
+ return generateRoutes({
1933
+ application: e,
1934
+ customRoutes: O,
1935
+ SettingsPage: k
1936
+ });
1937
+ }
1938
+ var AppErrorBoundary = class extends Component {
1939
+ state = {
1940
+ hasError: !1,
1941
+ error: null
1942
+ };
1943
+ static getDerivedStateFromError(e) {
1944
+ return {
1945
+ hasError: !0,
1946
+ error: e
1947
+ };
1948
+ }
1949
+ componentDidCatch(e, D) {
1950
+ console.error("Application error:", e, D);
1951
+ }
1952
+ render() {
1953
+ return this.state.hasError ? /* @__PURE__ */ jsx(Box, {
1954
+ display: "flex",
1955
+ justifyContent: "center",
1956
+ alignItems: "center",
1957
+ minHeight: "100vh",
1958
+ p: 4,
1959
+ "data-testid": "app-error-boundary",
1960
+ children: /* @__PURE__ */ jsxs(Paper, {
1961
+ sx: {
1962
+ p: 4,
1963
+ maxWidth: 500,
1964
+ textAlign: "center"
1965
+ },
1966
+ children: [
1967
+ /* @__PURE__ */ jsx(ErrorIcon, {
1968
+ color: "error",
1969
+ sx: {
1970
+ fontSize: 64,
1971
+ mb: 2
1972
+ }
1973
+ }),
1974
+ /* @__PURE__ */ jsx(Typography, {
1975
+ variant: "h5",
1976
+ gutterBottom: !0,
1977
+ children: "Application Error"
1978
+ }),
1979
+ /* @__PURE__ */ jsx(Typography, {
1980
+ color: "text.secondary",
1981
+ paragraph: !0,
1982
+ children: "An unexpected error occurred. Please refresh the page to continue."
1983
+ }),
1984
+ /* @__PURE__ */ jsx(Typography, {
1985
+ variant: "body2",
1986
+ color: "error",
1987
+ fontFamily: "monospace",
1988
+ sx: { mb: 2 },
1989
+ "data-testid": "app-error-boundary::message",
1990
+ children: this.state.error?.message
1991
+ }),
1992
+ /* @__PURE__ */ jsx(Button, {
1993
+ variant: "contained",
1994
+ onClick: () => window.location.reload(),
1995
+ "data-testid": "app-error-boundary::refresh",
1996
+ children: "Refresh Page"
1997
+ })
1998
+ ]
1999
+ })
2000
+ }) : this.props.children;
2001
+ }
2002
+ };
2003
+ function AppShell({ children: e, logo: D, appBarExtra: O }) {
2004
+ return /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(AppErrorBoundary, { children: /* @__PURE__ */ jsx(AppShellLayout, {
2005
+ logo: D,
2006
+ appBarExtra: O,
2007
+ children: e
2008
+ }) }) });
2009
+ }
2010
+ function UserMenu({ className: e }) {
2011
+ let [D, k] = useState(null), { principal: j, signoutRedirect: M, requiresAuth: N } = useAuth();
2012
+ if (!N) return null;
2013
+ let P = () => {
2014
+ k(null), M();
2015
+ }, F = getUserMenuTestId("trigger"), I = j?.preferredUsername ?? j?.name ?? "User", L = I[0] ?? "?";
2016
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(IconButton, {
2017
+ onClick: (e) => k(e.currentTarget),
2018
+ color: "inherit",
2019
+ className: e,
2020
+ "data-testid": F,
2021
+ children: /* @__PURE__ */ jsx(Avatar, {
2022
+ sx: {
2023
+ width: 32,
2024
+ height: 32
2025
+ },
2026
+ children: L
2027
+ })
2028
+ }), /* @__PURE__ */ jsxs(Menu, {
2029
+ anchorEl: D,
2030
+ open: !!D,
2031
+ onClose: () => k(null),
2032
+ "data-testid": getUserMenuTestId("menu"),
2033
+ children: [
2034
+ /* @__PURE__ */ jsxs(Box, {
2035
+ sx: {
2036
+ px: 2,
2037
+ py: 1
2038
+ },
2039
+ children: [/* @__PURE__ */ jsx(Typography, {
2040
+ variant: "subtitle1",
2041
+ children: I
2042
+ }), /* @__PURE__ */ jsx(Typography, {
2043
+ variant: "body2",
2044
+ color: "text.secondary",
2045
+ children: j?.email
2046
+ })]
2047
+ }),
2048
+ /* @__PURE__ */ jsx(Divider, {}),
2049
+ /* @__PURE__ */ jsxs(MenuItem, {
2050
+ onClick: () => k(null),
2051
+ "data-testid": getUserMenuTestId("profile"),
2052
+ children: [/* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(PersonIcon, { fontSize: "small" }) }), /* @__PURE__ */ jsx(ListItemText, { children: "Profile" })]
2053
+ }),
2054
+ /* @__PURE__ */ jsxs(MenuItem, {
2055
+ onClick: () => k(null),
2056
+ "data-testid": getUserMenuTestId("settings"),
2057
+ children: [/* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(SettingsIcon, { fontSize: "small" }) }), /* @__PURE__ */ jsx(ListItemText, { children: "Settings" })]
2058
+ }),
2059
+ /* @__PURE__ */ jsx(Divider, {}),
2060
+ /* @__PURE__ */ jsxs(MenuItem, {
2061
+ onClick: P,
2062
+ "data-testid": getUserMenuTestId("logout"),
2063
+ children: [/* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(LogoutIcon, { fontSize: "small" }) }), /* @__PURE__ */ jsx(ListItemText, { children: "Logout" })]
2064
+ })
2065
+ ]
2066
+ })] });
2067
+ }
2068
+ export { ActorSelector, AppBar, AppErrorBoundary, AppShell, AppShellLayout, Breadcrumbs, DefaultErrorScreen, DefaultGuestPage, DefaultHeroComponent, DefaultLoadingScreen, DefaultSettingsPage, HorizontalNavigation, HorizontalNavigationItem, JudoRuntime, LocaleSwitcher, NavigationDrawer, NavigationItemRenderer, PageDialogHost, PageRoute, RedirectPage, ThemeProvider, ThemeToggle, UserMenu, createDensityThemeOptions, createJudoThemeOptions, filterNavigationItems, findActionForNavigationItem, generateRoutes, getDashboardRoute, getRouteForPage, hasUserThemePreference, initializeThemeStore, resolvePreset, themePresets, useMenuOperationDispatch, useNavigationBadge, useTheme };