@hitachivantara/app-shell-ui 2.3.2 → 2.3.3

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 (62) hide show
  1. package/dist/components/AppShell/AppShell.js +16 -5
  2. package/dist/components/AppShell/AppShellContainer.js +75 -66
  3. package/dist/components/AppShell/AppShellRouter.js +98 -109
  4. package/dist/components/AppShellI18nProvider/AppShellI18nProvider.js +19 -25
  5. package/dist/components/AppShellProvider/AppShellProvider.js +84 -91
  6. package/dist/components/AppShellViewProvider/AppShellViewProvider.js +10 -7
  7. package/dist/components/ConfigIcon.js +13 -15
  8. package/dist/components/CustomHooksInitializer/CustomHooksInitializer.js +7 -7
  9. package/dist/components/GlobalStyles.js +11 -9
  10. package/dist/components/IconUiKit/IconUiKit.js +10 -8
  11. package/dist/components/InitErrorFallback/InitErrorFallback.js +31 -23
  12. package/dist/components/SnackbarProvider/SnackbarProvider.js +17 -20
  13. package/dist/components/layout/AppShellLayout.js +50 -65
  14. package/dist/components/layout/BrandLogo/BrandLogo.js +25 -35
  15. package/dist/components/layout/BrandLogo/logos.js +38 -55
  16. package/dist/components/layout/Header/Header.js +55 -74
  17. package/dist/components/layout/HeaderActions/AppSwitcherToggle/AppSwitcherToggle.js +66 -74
  18. package/dist/components/layout/HeaderActions/AppSwitcherToggle/styles.js +12 -12
  19. package/dist/components/layout/HeaderActions/ColorModeSwitcher.js +23 -26
  20. package/dist/components/layout/HeaderActions/DynamicAction.js +22 -21
  21. package/dist/components/layout/HeaderActions/HeaderActions.js +15 -22
  22. package/dist/components/layout/HeaderActions/HelpButton/HelpButton.js +22 -31
  23. package/dist/components/layout/HeaderActions/InternalAction/InternalAction.js +25 -36
  24. package/dist/components/layout/VerticalNavigation/NavigationCollapse.js +29 -34
  25. package/dist/components/layout/VerticalNavigation/NavigationHeader.js +18 -20
  26. package/dist/components/layout/VerticalNavigation/VerticalNavigation.js +96 -130
  27. package/dist/hooks/useClearLocationState.js +10 -12
  28. package/dist/hooks/useConditionsEvaluator.js +67 -81
  29. package/dist/hooks/useCustomEventListener.js +16 -28
  30. package/dist/hooks/useFilteredModel.js +30 -27
  31. package/dist/hooks/useLocalStorage.js +26 -26
  32. package/dist/hooks/useModelFromConfig.js +43 -39
  33. package/dist/hooks/useNavigationMenuItems.js +27 -30
  34. package/dist/hooks/useNotificationsEventListener.js +35 -42
  35. package/dist/hooks/useResizeObserver.js +13 -13
  36. package/dist/hooks/useThemeEventListener.js +17 -18
  37. package/dist/i18n/constants.js +5 -6
  38. package/dist/i18n/index.js +26 -20
  39. package/dist/i18n/useI18nInit.js +72 -66
  40. package/dist/index.js +4 -3
  41. package/dist/pages/ErrorPage/ErrorPage.js +33 -32
  42. package/dist/pages/ErrorPage/Footer.js +46 -55
  43. package/dist/pages/GenericError/CatServer.js +585 -569
  44. package/dist/pages/GenericError/GenericError.js +25 -26
  45. package/dist/pages/LoadingPage/LoadingPage.js +9 -17
  46. package/dist/pages/LoadingPage/index.js +4 -3
  47. package/dist/pages/NotFound/DogeSpace.js +505 -540
  48. package/dist/pages/NotFound/NotFound.js +17 -20
  49. package/dist/pages/NotFound/index.js +2 -4
  50. package/dist/pages/RootRoute.js +32 -19
  51. package/dist/providers/BannerProvider.js +98 -123
  52. package/dist/providers/LayoutProvider.js +26 -32
  53. package/dist/providers/NavigationProvider.js +96 -107
  54. package/dist/utils/CombinedProviders.js +12 -18
  55. package/dist/utils/documentUtil.js +12 -12
  56. package/dist/utils/filterModel.js +134 -170
  57. package/dist/utils/lazyImport.js +31 -36
  58. package/dist/utils/navigationUtil.js +68 -53
  59. package/dist/utils/processConfig.js +119 -153
  60. package/package.json +8 -8
  61. package/dist/components/IconUiKit/index.js +0 -6
  62. package/dist/pages/LoadingPage/styles.js +0 -30
@@ -1,38 +1,33 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
1
  import { useTranslation } from "react-i18next";
3
- import { css } from "@emotion/css";
4
- import { useHvAppShellRuntimeContext } from "@hitachivantara/app-shell-shared";
5
2
  import { HvVerticalNavigationAction } from "@hitachivantara/uikit-react-core";
6
- import { Start, End } from "@hitachivantara/uikit-react-icons";
7
- const classes = {
8
- root: css({
9
- position: "relative"
10
- }),
11
- icon: css({
12
- position: "absolute",
13
- pointerEvents: "none",
14
- right: 0
15
- })
16
- };
17
- const NavigationCollapse = ({ onClick, isOpen }) => {
18
- const { i18n } = useHvAppShellRuntimeContext();
19
- const { t } = useTranslation(void 0, {
20
- i18n,
21
- keyPrefix: "verticalNavigation"
22
- });
23
- return /* @__PURE__ */ jsxs("div", { className: classes.root, children: [
24
- isOpen && /* @__PURE__ */ jsx(Start, { className: classes.icon }),
25
- /* @__PURE__ */ jsx(
26
- HvVerticalNavigationAction,
27
- {
28
- label: t("collapseAction"),
29
- icon: isOpen ? void 0 : /* @__PURE__ */ jsx(End, {}),
30
- "aria-label": isOpen ? t("ariaLabelCollapse") : t("ariaLabelExpand"),
31
- onClick
32
- }
33
- )
34
- ] });
3
+ import { useHvAppShellRuntimeContext } from "@hitachivantara/app-shell-shared";
4
+ import { End, Start } from "@hitachivantara/uikit-react-icons";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { css } from "@emotion/css";
7
+ //#region src/components/layout/VerticalNavigation/NavigationCollapse.tsx
8
+ var classes = {
9
+ root: css({ position: "relative" }),
10
+ icon: css({
11
+ position: "absolute",
12
+ pointerEvents: "none",
13
+ right: 0
14
+ })
35
15
  };
36
- export {
37
- NavigationCollapse
16
+ var NavigationCollapse = ({ onClick, isOpen }) => {
17
+ const { i18n } = useHvAppShellRuntimeContext();
18
+ const { t } = useTranslation(void 0, {
19
+ i18n,
20
+ keyPrefix: "verticalNavigation"
21
+ });
22
+ return /* @__PURE__ */ jsxs("div", {
23
+ className: classes.root,
24
+ children: [isOpen && /* @__PURE__ */ jsx(Start, { className: classes.icon }), /* @__PURE__ */ jsx(HvVerticalNavigationAction, {
25
+ label: t("collapseAction"),
26
+ icon: isOpen ? void 0 : /* @__PURE__ */ jsx(End, {}),
27
+ "aria-label": isOpen ? t("ariaLabelCollapse") : t("ariaLabelExpand"),
28
+ onClick
29
+ })]
30
+ });
38
31
  };
32
+ //#endregion
33
+ export { NavigationCollapse };
@@ -1,23 +1,21 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { css } from "@emotion/css";
3
- import { useHvAppShellModel } from "@hitachivantara/app-shell-shared";
1
+ import { BrandLogo } from "../BrandLogo/BrandLogo.js";
4
2
  import { theme } from "@hitachivantara/uikit-react-core";
3
+ import { useHvAppShellModel } from "@hitachivantara/app-shell-shared";
5
4
  import { AppSwitcher } from "@hitachivantara/uikit-react-icons";
6
- import { BrandLogo } from "../BrandLogo/BrandLogo.js";
7
- const classes = {
8
- root: css({
9
- display: "flex",
10
- alignItems: "center",
11
- gap: theme.space.xxs
12
- })
13
- };
14
- const NavigationHeader = ({ isOpen }) => {
15
- const { logo } = useHvAppShellModel();
16
- return /* @__PURE__ */ jsxs("div", { className: classes.root, children: [
17
- /* @__PURE__ */ jsx(AppSwitcher, {}),
18
- isOpen && /* @__PURE__ */ jsx(BrandLogo, { logo })
19
- ] });
20
- };
21
- export {
22
- NavigationHeader
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { css } from "@emotion/css";
7
+ //#region src/components/layout/VerticalNavigation/NavigationHeader.tsx
8
+ var classes = { root: css({
9
+ display: "flex",
10
+ alignItems: "center",
11
+ gap: theme.space.xxs
12
+ }) };
13
+ var NavigationHeader = ({ isOpen }) => {
14
+ const { logo } = useHvAppShellModel();
15
+ return /* @__PURE__ */ jsxs("div", {
16
+ className: classes.root,
17
+ children: [/* @__PURE__ */ jsx(AppSwitcher, {}), isOpen && /* @__PURE__ */ jsx(BrandLogo, { logo })]
18
+ });
23
19
  };
20
+ //#endregion
21
+ export { NavigationHeader };
@@ -1,135 +1,101 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useRef } from "react";
3
- import { useTranslation } from "react-i18next";
4
- import { cx, css } from "@emotion/css";
5
- import ClickAwayListener from "@mui/material/ClickAwayListener";
6
- import { useHvNavigation } from "@hitachivantara/app-shell-navigation";
7
- import { useHvAppShellRuntimeContext } from "@hitachivantara/app-shell-shared";
8
- import { useTheme, HvVerticalNavigation, HvVerticalNavigationHeader, HvVerticalNavigationTree, HvVerticalNavigationActions, theme, verticalNavigationTreeClasses } from "@hitachivantara/uikit-react-core";
9
- import { useResizeObserver } from "../../../hooks/useResizeObserver.js";
10
- import { useLayoutContext } from "../../../providers/LayoutProvider.js";
11
1
  import { useNavigationContext } from "../../../providers/NavigationProvider.js";
2
+ import { useLayoutContext } from "../../../providers/LayoutProvider.js";
3
+ import { useResizeObserver } from "../../../hooks/useResizeObserver.js";
12
4
  import { NavigationCollapse } from "./NavigationCollapse.js";
13
5
  import { NavigationHeader } from "./NavigationHeader.js";
14
- const classes = {
15
- root: css({
16
- gridArea: "vnav",
17
- overflowY: "auto",
18
- position: "relative",
19
- zIndex: theme.zIndices.overlay
20
- }),
21
- pentaho: css({
22
- maxHeight: "100vh"
23
- }),
24
- floating: css({
25
- position: "absolute",
26
- top: theme.header.height,
27
- bottom: 0
28
- }),
29
- popup: css({
30
- maxHeight: `calc(100vh - ${theme.header.height})`,
31
- overflowY: "auto",
32
- boxShadow: theme.colors.shadow,
33
- [`& .${verticalNavigationTreeClasses.popup}`]: { boxShadow: "none" }
34
- })
35
- };
36
- const VerticalNavigation = () => {
37
- const { i18n } = useHvAppShellRuntimeContext();
38
- const { t } = useTranslation(void 0, {
39
- i18n,
40
- keyPrefix: "verticalNavigation"
41
- });
42
- const {
43
- selectedMenuItemId,
44
- rootMenuItemId,
45
- verticalNavigationItems,
46
- isCompactMode,
47
- verticalNavigationMode,
48
- switchVerticalNavigationMode
49
- } = useNavigationContext();
50
- const { setVerticalNavigationWidth } = useLayoutContext();
51
- const { navigate } = useHvNavigation();
52
- const { activeTheme } = useTheme();
53
- const ref = useRef(null);
54
- const open = verticalNavigationMode === "EXPANDED";
55
- const isPentahoTheme = activeTheme?.name === "pentahoPlus";
56
- const changeHandler = (event, selectedItem) => {
57
- event.preventDefault();
58
- if (selectedItem.href) {
59
- navigate(selectedItem.href, {
60
- state: { selectedItemId: selectedItem.id }
61
- });
62
- if (isCompactMode) {
63
- switchVerticalNavigationMode();
64
- }
65
- }
66
- };
67
- useResizeObserver(ref, (width) => {
68
- setVerticalNavigationWidth(isCompactMode ? 0 : width);
69
- });
70
- return /* @__PURE__ */ jsx(
71
- ClickAwayListener,
72
- {
73
- onClickAway: () => {
74
- if (!isCompactMode) return;
75
- switchVerticalNavigationMode();
76
- },
77
- children: /* @__PURE__ */ jsxs(
78
- HvVerticalNavigation,
79
- {
80
- ref,
81
- className: cx(classes.root, {
82
- [classes.pentaho]: isPentahoTheme,
83
- [classes.floating]: open && isCompactMode
84
- }),
85
- open,
86
- useIcons: true,
87
- slider: isCompactMode,
88
- children: [
89
- /* @__PURE__ */ jsxs("div", { children: [
90
- isPentahoTheme && /* @__PURE__ */ jsx(NavigationHeader, { isOpen: open }),
91
- (!isPentahoTheme || isCompactMode) && /* @__PURE__ */ jsx(
92
- HvVerticalNavigationHeader,
93
- {
94
- title: t("title"),
95
- onCollapseButtonClick: !isCompactMode ? switchVerticalNavigationMode : void 0,
96
- collapseButtonProps: {
97
- "aria-label": t(open ? "ariaLabelCollapse" : "ariaLabelExpand"),
98
- "aria-expanded": open
99
- },
100
- backButtonProps: {
101
- "aria-label": t("ariaLabelHeaderBackButton")
102
- }
103
- }
104
- )
105
- ] }),
106
- /* @__PURE__ */ jsx(
107
- HvVerticalNavigationTree,
108
- {
109
- mode: "navigation",
110
- collapsible: true,
111
- "aria-label": t("ariaLabelNavigationTree"),
112
- selected: selectedMenuItemId,
113
- onChange: changeHandler,
114
- data: verticalNavigationItems,
115
- classes: { navigationPopup: classes.popup },
116
- sliderForwardButtonAriaLabel: t("ariaLabelSliderForwardButton")
117
- },
118
- rootMenuItemId
119
- ),
120
- /* @__PURE__ */ jsx(HvVerticalNavigationActions, { children: isPentahoTheme && /* @__PURE__ */ jsx(
121
- NavigationCollapse,
122
- {
123
- onClick: switchVerticalNavigationMode,
124
- isOpen: open
125
- }
126
- ) })
127
- ]
128
- }
129
- )
130
- }
131
- );
6
+ import { useRef } from "react";
7
+ import { useTranslation } from "react-i18next";
8
+ import { HvVerticalNavigation, HvVerticalNavigationActions, HvVerticalNavigationHeader, HvVerticalNavigationTree, theme, useTheme, verticalNavigationTreeClasses } from "@hitachivantara/uikit-react-core";
9
+ import { useHvAppShellRuntimeContext } from "@hitachivantara/app-shell-shared";
10
+ import { useHvNavigation } from "@hitachivantara/app-shell-navigation";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ import { css, cx } from "@emotion/css";
13
+ import ClickAwayListener from "@mui/material/ClickAwayListener";
14
+ //#region src/components/layout/VerticalNavigation/VerticalNavigation.tsx
15
+ var classes = {
16
+ root: css({
17
+ gridArea: "vnav",
18
+ overflowY: "auto",
19
+ position: "relative",
20
+ zIndex: theme.zIndices.overlay
21
+ }),
22
+ pentaho: css({ maxHeight: "100vh" }),
23
+ floating: css({
24
+ position: "absolute",
25
+ top: theme.header.height,
26
+ bottom: 0
27
+ }),
28
+ popup: css({
29
+ maxHeight: `calc(100vh - ${theme.header.height})`,
30
+ overflowY: "auto",
31
+ boxShadow: theme.colors.shadow,
32
+ [`& .${verticalNavigationTreeClasses.popup}`]: { boxShadow: "none" }
33
+ })
132
34
  };
133
- export {
134
- VerticalNavigation
35
+ var VerticalNavigation = () => {
36
+ const { i18n } = useHvAppShellRuntimeContext();
37
+ const { t } = useTranslation(void 0, {
38
+ i18n,
39
+ keyPrefix: "verticalNavigation"
40
+ });
41
+ const { selectedMenuItemId, rootMenuItemId, verticalNavigationItems, isCompactMode, verticalNavigationMode, switchVerticalNavigationMode } = useNavigationContext();
42
+ const { setVerticalNavigationWidth } = useLayoutContext();
43
+ const { navigate } = useHvNavigation();
44
+ const { activeTheme } = useTheme();
45
+ const ref = useRef(null);
46
+ const open = verticalNavigationMode === "EXPANDED";
47
+ const isPentahoTheme = activeTheme?.name === "pentahoPlus";
48
+ const changeHandler = (event, selectedItem) => {
49
+ event.preventDefault();
50
+ if (selectedItem.href) {
51
+ navigate(selectedItem.href, { state: { selectedItemId: selectedItem.id } });
52
+ if (isCompactMode) switchVerticalNavigationMode();
53
+ }
54
+ };
55
+ useResizeObserver(ref, (width) => {
56
+ setVerticalNavigationWidth(isCompactMode ? 0 : width);
57
+ });
58
+ return /* @__PURE__ */ jsx(ClickAwayListener, {
59
+ onClickAway: () => {
60
+ if (!isCompactMode) return;
61
+ switchVerticalNavigationMode();
62
+ },
63
+ children: /* @__PURE__ */ jsxs(HvVerticalNavigation, {
64
+ ref,
65
+ className: cx(classes.root, {
66
+ [classes.pentaho]: isPentahoTheme,
67
+ [classes.floating]: open && isCompactMode
68
+ }),
69
+ open,
70
+ useIcons: true,
71
+ slider: isCompactMode,
72
+ children: [
73
+ /* @__PURE__ */ jsxs("div", { children: [isPentahoTheme && /* @__PURE__ */ jsx(NavigationHeader, { isOpen: open }), (!isPentahoTheme || isCompactMode) && /* @__PURE__ */ jsx(HvVerticalNavigationHeader, {
74
+ title: t("title"),
75
+ onCollapseButtonClick: !isCompactMode ? switchVerticalNavigationMode : void 0,
76
+ collapseButtonProps: {
77
+ "aria-label": t(open ? "ariaLabelCollapse" : "ariaLabelExpand"),
78
+ "aria-expanded": open
79
+ },
80
+ backButtonProps: { "aria-label": t("ariaLabelHeaderBackButton") }
81
+ })] }),
82
+ /* @__PURE__ */ jsx(HvVerticalNavigationTree, {
83
+ mode: "navigation",
84
+ collapsible: true,
85
+ "aria-label": t("ariaLabelNavigationTree"),
86
+ selected: selectedMenuItemId,
87
+ onChange: changeHandler,
88
+ data: verticalNavigationItems,
89
+ classes: { navigationPopup: classes.popup },
90
+ sliderForwardButtonAriaLabel: t("ariaLabelSliderForwardButton")
91
+ }, rootMenuItemId),
92
+ /* @__PURE__ */ jsx(HvVerticalNavigationActions, { children: isPentahoTheme && /* @__PURE__ */ jsx(NavigationCollapse, {
93
+ onClick: switchVerticalNavigationMode,
94
+ isOpen: open
95
+ }) })
96
+ ]
97
+ })
98
+ });
135
99
  };
100
+ //#endregion
101
+ export { VerticalNavigation };
@@ -1,15 +1,13 @@
1
1
  import { useCallback } from "react";
2
- import { useLocation, useBeforeUnload } from "react-router-dom";
2
+ import { useBeforeUnload, useLocation } from "react-router-dom";
3
3
  import { useHvNavigation } from "@hitachivantara/app-shell-navigation";
4
- const useClearLocationState = () => {
5
- const location = useLocation();
6
- const { navigate } = useHvNavigation();
7
- useBeforeUnload(
8
- useCallback(() => {
9
- navigate({ ...location }, { replace: true });
10
- }, [location, navigate])
11
- );
12
- };
13
- export {
14
- useClearLocationState as default
4
+ //#region src/hooks/useClearLocationState.tsx
5
+ var useClearLocationState = () => {
6
+ const location = useLocation();
7
+ const { navigate } = useHvNavigation();
8
+ useBeforeUnload(useCallback(() => {
9
+ navigate({ ...location }, { replace: true });
10
+ }, [location, navigate]));
15
11
  };
12
+ //#endregion
13
+ export { useClearLocationState as default };
@@ -1,87 +1,73 @@
1
1
  import { useRef } from "react";
2
+ //#region src/hooks/useConditionsEvaluator.ts
2
3
  function assert(condition, message) {
3
- if (!condition) {
4
- throw new Error(message || "Assertion failed");
5
- }
4
+ if (!condition) throw new Error(message || "Assertion failed");
6
5
  }
7
6
  function areArraysEqual(a, b) {
8
- if (a.length !== b.length) {
9
- return false;
10
- }
11
- for (let i = 0; i < a.length; i++) {
12
- if (a[i] !== b[i]) {
13
- return false;
14
- }
15
- }
16
- return true;
7
+ if (a.length !== b.length) return false;
8
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
9
+ return true;
17
10
  }
18
- const useConditionsEvaluator = (allConditions, preloadedBundles) => {
19
- const previousResultsRef = useRef([]);
20
- if (preloadedBundles.size === 0) {
21
- return {
22
- isPending: false,
23
- error: null,
24
- result: previousResultsRef.current
25
- };
26
- }
27
- const hookResults = [];
28
- for (const { bundle, config } of allConditions) {
29
- const module = preloadedBundles.get(bundle);
30
- if (!module) {
31
- hookResults.push({
32
- isPending: false,
33
- error: new Error(`Bundle '${bundle}' not loaded`),
34
- result: void 0
35
- });
36
- continue;
37
- }
38
- try {
39
- const result2 = module(config);
40
- hookResults.push(result2);
41
- } catch (error) {
42
- hookResults.push({
43
- isPending: false,
44
- error,
45
- result: void 0
46
- });
47
- }
48
- }
49
- const isAnyPending = hookResults.some((result2) => result2.isPending);
50
- const currentResults = [];
51
- for (let i = 0; i < allConditions.length; i++) {
52
- const condition = allConditions[i];
53
- const asyncResult = hookResults[i];
54
- if (asyncResult.error) {
55
- console.error(
56
- `Failed to execute ${condition.bundle} with: ${asyncResult.error}`
57
- );
58
- }
59
- const boolResult = asyncResult.isPending || asyncResult.error ? false : asyncResult.result;
60
- assert(
61
- i === condition.globalIndex,
62
- `Index mismatch: expected ${i} to equal globalIndex ${condition.globalIndex}`
63
- );
64
- currentResults[condition.globalIndex] = boolResult;
65
- }
66
- const previousResults = previousResultsRef.current;
67
- const hasChanged = !areArraysEqual(previousResults, currentResults);
68
- const result = hasChanged ? currentResults : previousResults;
69
- if (hasChanged) {
70
- previousResultsRef.current = currentResults;
71
- }
72
- if (isAnyPending) {
73
- return {
74
- isPending: true,
75
- error: null,
76
- result: void 0
77
- };
78
- }
79
- return {
80
- error: null,
81
- result,
82
- isPending: false
83
- };
84
- };
85
- export {
86
- useConditionsEvaluator
11
+ /**
12
+ * Hook to execute all loaded condition hooks and return results
13
+ *
14
+ * @param allConditions - Array of conditions with globalIndex from processed config
15
+ * @param preloadedBundles - Array of all the preloaded bundles
16
+ * @returns Object with isPending flag, error and results map
17
+ */
18
+ var useConditionsEvaluator = (allConditions, preloadedBundles) => {
19
+ const previousResultsRef = useRef([]);
20
+ if (preloadedBundles.size === 0) return {
21
+ isPending: false,
22
+ error: null,
23
+ result: previousResultsRef.current
24
+ };
25
+ const hookResults = [];
26
+ for (const { bundle, config } of allConditions) {
27
+ const module = preloadedBundles.get(bundle);
28
+ if (!module) {
29
+ hookResults.push({
30
+ isPending: false,
31
+ error: /* @__PURE__ */ new Error(`Bundle '${bundle}' not loaded`),
32
+ result: void 0
33
+ });
34
+ continue;
35
+ }
36
+ try {
37
+ const result = module(config);
38
+ hookResults.push(result);
39
+ } catch (error) {
40
+ hookResults.push({
41
+ isPending: false,
42
+ error,
43
+ result: void 0
44
+ });
45
+ }
46
+ }
47
+ const isAnyPending = hookResults.some((result) => result.isPending);
48
+ const currentResults = [];
49
+ for (let i = 0; i < allConditions.length; i++) {
50
+ const condition = allConditions[i];
51
+ const asyncResult = hookResults[i];
52
+ if (asyncResult.error) console.error(`Failed to execute ${condition.bundle} with: ${asyncResult.error}`);
53
+ const boolResult = asyncResult.isPending || asyncResult.error ? false : asyncResult.result;
54
+ assert(i === condition.globalIndex, `Index mismatch: expected ${i} to equal globalIndex ${condition.globalIndex}`);
55
+ currentResults[condition.globalIndex] = boolResult;
56
+ }
57
+ const previousResults = previousResultsRef.current;
58
+ const hasChanged = !areArraysEqual(previousResults, currentResults);
59
+ const result = hasChanged ? currentResults : previousResults;
60
+ if (hasChanged) previousResultsRef.current = currentResults;
61
+ if (isAnyPending) return {
62
+ isPending: true,
63
+ error: null,
64
+ result: void 0
65
+ };
66
+ return {
67
+ error: null,
68
+ result,
69
+ isPending: false
70
+ };
87
71
  };
72
+ //#endregion
73
+ export { useConditionsEvaluator };
@@ -1,31 +1,19 @@
1
- import { useEffect } from "react";
2
- import { HvAppShellEventNotificationTrigger, HvAppShellEventThemeTrigger } from "@hitachivantara/app-shell-events";
3
1
  import useNotificationsEventListener from "./useNotificationsEventListener.js";
4
2
  import useThemeEventListener from "./useThemeEventListener.js";
5
- const useCustomEventListener = () => {
6
- const { handleNotificationEvent } = useNotificationsEventListener();
7
- const { handleThemeEvent } = useThemeEventListener();
8
- useEffect(() => {
9
- globalThis.addEventListener(
10
- HvAppShellEventNotificationTrigger,
11
- handleNotificationEvent
12
- );
13
- globalThis.addEventListener(
14
- HvAppShellEventThemeTrigger,
15
- handleThemeEvent
16
- );
17
- return () => {
18
- globalThis.removeEventListener(
19
- HvAppShellEventNotificationTrigger,
20
- handleNotificationEvent
21
- );
22
- globalThis.removeEventListener(
23
- HvAppShellEventThemeTrigger,
24
- handleThemeEvent
25
- );
26
- };
27
- }, [handleNotificationEvent, handleThemeEvent]);
28
- };
29
- export {
30
- useCustomEventListener as default
3
+ import { useEffect } from "react";
4
+ import { HvAppShellEventNotificationTrigger, HvAppShellEventThemeTrigger } from "@hitachivantara/app-shell-events";
5
+ //#region src/hooks/useCustomEventListener.ts
6
+ var useCustomEventListener = () => {
7
+ const { handleNotificationEvent } = useNotificationsEventListener();
8
+ const { handleThemeEvent } = useThemeEventListener();
9
+ useEffect(() => {
10
+ globalThis.addEventListener(HvAppShellEventNotificationTrigger, handleNotificationEvent);
11
+ globalThis.addEventListener(HvAppShellEventThemeTrigger, handleThemeEvent);
12
+ return () => {
13
+ globalThis.removeEventListener(HvAppShellEventNotificationTrigger, handleNotificationEvent);
14
+ globalThis.removeEventListener(HvAppShellEventThemeTrigger, handleThemeEvent);
15
+ };
16
+ }, [handleNotificationEvent, handleThemeEvent]);
31
17
  };
18
+ //#endregion
19
+ export { useCustomEventListener as default };
@@ -1,30 +1,33 @@
1
- import { useMemo } from "react";
2
1
  import filterModel from "../utils/filterModel.js";
3
2
  import { useConditionsEvaluator } from "./useConditionsEvaluator.js";
4
- const useFilteredModel = (model) => {
5
- const { isPending: isModelPending, result } = useConditionsEvaluator(
6
- model.allConditions,
7
- model.preloadedBundles
8
- );
9
- const resolvedModel = useMemo(() => {
10
- if (isModelPending) {
11
- return void 0;
12
- }
13
- return filterModel(model, result);
14
- }, [isModelPending, model, result]);
15
- if (isModelPending) {
16
- return {
17
- error: null,
18
- isPending: true,
19
- model: void 0
20
- };
21
- }
22
- return {
23
- error: null,
24
- isPending: false,
25
- model: resolvedModel
26
- };
27
- };
28
- export {
29
- useFilteredModel
3
+ import { useMemo } from "react";
4
+ //#region src/hooks/useFilteredModel.ts
5
+ /**
6
+ * Hook to evaluate conditions and filter configuration
7
+ *
8
+ * @param model - The app shell model with config and preloaded bundles
9
+ * @returns Object with isPending flag and the filtered model
10
+ */
11
+ var useFilteredModel = (model) => {
12
+ const { isPending: isModelPending, result } = useConditionsEvaluator(model.allConditions, model.preloadedBundles);
13
+ const resolvedModel = useMemo(() => {
14
+ if (isModelPending) return;
15
+ return filterModel(model, result);
16
+ }, [
17
+ isModelPending,
18
+ model,
19
+ result
20
+ ]);
21
+ if (isModelPending) return {
22
+ error: null,
23
+ isPending: true,
24
+ model: void 0
25
+ };
26
+ return {
27
+ error: null,
28
+ isPending: false,
29
+ model: resolvedModel
30
+ };
30
31
  };
32
+ //#endregion
33
+ export { useFilteredModel };