@hitachivantara/app-shell-ui 1.9.1 → 1.10.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.
- package/dist/esm/components/AppShell/AppShell.mjs +10 -0
- package/dist/esm/components/AppShellProvider/AppShellProvider.mjs +112 -0
- package/dist/esm/components/AppShellRoutes/AppShellRoutes.mjs +118 -0
- package/dist/esm/components/AppShellViewProvider/{AppShellViewProvider.js → AppShellViewProvider.mjs} +3 -8
- package/dist/esm/components/CustomHooksInitializer/{CustomHooksInitializer.js → CustomHooksInitializer.mjs} +2 -2
- package/dist/esm/components/GlobalStyles/GlobalStyles.mjs +16 -0
- package/dist/esm/components/GlobalStyles/index.mjs +4 -0
- package/dist/esm/components/IconUiKit/IconUiKit.mjs +10 -0
- package/dist/esm/components/IconUiKit/index.mjs +6 -0
- package/dist/esm/components/SnackbarProvider/SnackbarProvider.mjs +24 -0
- package/dist/esm/components/hoc/{withClickAwayListener.js → withClickAwayListener.mjs} +6 -3
- package/dist/esm/components/hoc/{withGlobalProvider.js → withGlobalProvider.mjs} +25 -13
- package/dist/esm/components/layout/BrandLogo/{BrandLogo.js → BrandLogo.mjs} +7 -11
- package/dist/esm/components/layout/BrandLogo/Logos/Hitachi.mjs +30 -0
- package/dist/esm/components/layout/BrandLogo/Logos/Lumada.mjs +48 -0
- package/dist/esm/components/layout/BrandLogo/Logos/Pentaho.mjs +30 -0
- package/dist/esm/components/layout/Header/Header.mjs +88 -0
- package/dist/esm/components/layout/Header/HeaderActions/{DynamicAction/DynamicAction.js → DynamicAction.mjs} +12 -15
- package/dist/esm/components/layout/Header/HeaderActions/HeaderActions.mjs +25 -0
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/AppSwitcherToggle/AppSwitcherToggle.mjs +83 -0
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/AppSwitcherToggle/index.mjs +4 -0
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/AppSwitcherToggle/styles.mjs +14 -0
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/{ColorModeSwitcher/ColorModeSwitcher.js → ColorModeSwitcher.mjs} +12 -13
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/HelpButton/HelpButton.mjs +28 -0
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/HelpButton/index.mjs +4 -0
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/InternalAction/InternalAction.mjs +39 -0
- package/dist/esm/components/layout/Header/HeaderActions/index.mjs +4 -0
- package/dist/esm/components/layout/Header/styles.mjs +10 -0
- package/dist/esm/components/layout/Loading/Loading.mjs +8 -0
- package/dist/esm/components/layout/Loading/styles.mjs +14 -0
- package/dist/esm/components/layout/Main/Main.mjs +48 -0
- package/dist/esm/components/layout/Main/styles.mjs +14 -0
- package/dist/esm/components/layout/VerticalNavigation/NavigationCollapse.mjs +34 -0
- package/dist/esm/components/layout/VerticalNavigation/{NavigationHeader.js → NavigationHeader.mjs} +4 -6
- package/dist/esm/components/layout/VerticalNavigation/VerticalNavigation.mjs +98 -0
- package/dist/esm/components/layout/VerticalNavigation/styles.mjs +55 -0
- package/dist/esm/{lib/hooks/useClearLocationState.js → hooks/useClearLocationState.mjs} +6 -10
- package/dist/esm/hooks/useCustomEventListener.mjs +31 -0
- package/dist/esm/{lib/hooks/useLocalStorage.js → hooks/useLocalStorage.mjs} +1 -4
- package/dist/esm/{lib/hooks/useNavigationMenuItems.js → hooks/useNavigationMenuItems.mjs} +16 -21
- package/dist/esm/{lib/hooks/useNotificationsEventListener.js → hooks/useNotificationsEventListener.mjs} +5 -16
- package/dist/esm/{lib/hooks/useThemeEventListener.js → hooks/useThemeEventListener.mjs} +5 -16
- package/dist/esm/{lib/i18n/index.js → i18n/index.mjs} +10 -8
- package/dist/esm/i18n/localization/en.json.mjs +17 -0
- package/dist/esm/i18n/localization/pt.json.mjs +17 -0
- package/dist/esm/index.mjs +4 -0
- package/dist/esm/pages/ErrorPage/ErrorPage.mjs +41 -0
- package/dist/esm/pages/ErrorPage/Footer.mjs +60 -0
- package/dist/esm/pages/ErrorPage/styles.mjs +41 -0
- package/dist/esm/pages/GenericError/GenericError.mjs +21 -0
- package/dist/esm/pages/LoadingPage/LoadingPage.mjs +18 -0
- package/dist/esm/pages/LoadingPage/index.mjs +4 -0
- package/dist/esm/pages/LoadingPage/styles.mjs +23 -0
- package/dist/esm/pages/NotFound/NotFound.mjs +19 -0
- package/dist/esm/pages/NotFound/index.mjs +4 -0
- package/dist/esm/pages/Root/Root.mjs +20 -0
- package/dist/esm/providers/BannerProvider.mjs +126 -0
- package/dist/esm/providers/LayoutProvider.mjs +36 -0
- package/dist/esm/providers/{NavigationProvider.js → NavigationProvider.mjs} +48 -34
- package/dist/esm/utils/CombinedProviders.mjs +23 -0
- package/dist/esm/{lib/utils/navigationUtil.js → utils/navigationUtil.mjs} +5 -15
- package/dist/types/index.d.ts +27 -0
- package/package.json +37 -48
- package/LICENSE +0 -201
- package/dist/dts/index.d.ts +0 -9
- package/dist/esm/components/AppShell/AppShell.js +0 -10
- package/dist/esm/components/AppShellProvider/AppShellProvider.js +0 -84
- package/dist/esm/components/AppShellRoutes/AppShellRoutes.js +0 -94
- package/dist/esm/components/GlobalStyles/GlobalStyles.js +0 -18
- package/dist/esm/components/GlobalStyles/index.js +0 -4
- package/dist/esm/components/IconUiKit/IconUiKit.js +0 -12
- package/dist/esm/components/IconUiKit/index.js +0 -6
- package/dist/esm/components/SnackbarProvider/SnackbarProvider.js +0 -22
- package/dist/esm/components/layout/BrandLogo/Logos/Hitachi.js +0 -11
- package/dist/esm/components/layout/BrandLogo/Logos/Lumada.js +0 -16
- package/dist/esm/components/layout/BrandLogo/Logos/Pentaho.js +0 -11
- package/dist/esm/components/layout/Header/Header.js +0 -72
- package/dist/esm/components/layout/Header/HeaderActions/DynamicAction/index.js +0 -4
- package/dist/esm/components/layout/Header/HeaderActions/HeaderActions.js +0 -18
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/AppSwitcherToggle/AppSwitcherToggle.js +0 -69
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/AppSwitcherToggle/index.js +0 -4
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/AppSwitcherToggle/styles.js +0 -19
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/ColorModeSwitcher/index.js +0 -4
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/HelpButton/HelpButton.js +0 -28
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/HelpButton/index.js +0 -4
- package/dist/esm/components/layout/Header/HeaderActions/InternalActions/InternalAction/InternalAction.js +0 -36
- package/dist/esm/components/layout/Header/HeaderActions/index.js +0 -4
- package/dist/esm/components/layout/Header/styles.js +0 -21
- package/dist/esm/components/layout/Loading/Loading.js +0 -10
- package/dist/esm/components/layout/Loading/styles.js +0 -36
- package/dist/esm/components/layout/Main/Main.js +0 -38
- package/dist/esm/components/layout/Main/styles.js +0 -36
- package/dist/esm/components/layout/VerticalNavigation/NavigationCollapse.js +0 -25
- package/dist/esm/components/layout/VerticalNavigation/VerticalNavigation.js +0 -75
- package/dist/esm/components/layout/VerticalNavigation/styles.js +0 -79
- package/dist/esm/index.js +0 -4
- package/dist/esm/lib/hooks/useCustomEventListener.js +0 -23
- package/dist/esm/lib/i18n/localization/en.json.js +0 -59
- package/dist/esm/lib/i18n/localization/pt.json.js +0 -59
- package/dist/esm/lib/utils/CombinedProviders.js +0 -22
- package/dist/esm/lib/utils/textUtil.js +0 -6
- package/dist/esm/pages/ErrorPage/ErrorPage.js +0 -31
- package/dist/esm/pages/ErrorPage/Footer/Footer.js +0 -53
- package/dist/esm/pages/ErrorPage/Footer/styles.js +0 -22
- package/dist/esm/pages/ErrorPage/styles.js +0 -64
- package/dist/esm/pages/GenericError/GenericError.js +0 -18
- package/dist/esm/pages/LoadingPage/LoadingPage.js +0 -14
- package/dist/esm/pages/LoadingPage/index.js +0 -4
- package/dist/esm/pages/LoadingPage/styles.js +0 -27
- package/dist/esm/pages/NotFound/NotFound.js +0 -15
- package/dist/esm/pages/NotFound/index.js +0 -4
- package/dist/esm/pages/Root/Root.js +0 -22
- package/dist/esm/providers/BannerProvider.js +0 -108
- package/dist/esm/providers/LayoutProvider.js +0 -27
- package/dist/esm/providers/hooks/useBannerContext.js +0 -12
- package/dist/esm/providers/hooks/useLayoutContext.js +0 -12
- package/dist/esm/providers/hooks/useNavigationContext.js +0 -12
- /package/dist/esm/{lib/hooks/useResizeObserver.js → hooks/useResizeObserver.mjs} +0 -0
- /package/dist/esm/pages/GenericError/{500.svg.js → 500.svg.mjs} +0 -0
- /package/dist/esm/pages/NotFound/{404.svg.js → 404.svg.mjs} +0 -0
- /package/dist/esm/{lib/utils/basePathUtils.js → utils/basePathUtils.mjs} +0 -0
- /package/dist/esm/{lib/utils/documentUtil.js → utils/documentUtil.mjs} +0 -0
|
@@ -1,30 +1,25 @@
|
|
|
1
1
|
import { useContext, useMemo, useEffect } from "react";
|
|
2
2
|
import { useLocation } from "react-router-dom";
|
|
3
|
-
import { useHvAppShellConfig, HvAppShellRuntimeContext, CONFIG_TRANSLATIONS_NAMESPACE, useHvMenuItems } from "@hitachivantara/app-shell-shared";
|
|
4
3
|
import { useHvNavigation } from "@hitachivantara/app-shell-navigation";
|
|
5
|
-
import {
|
|
4
|
+
import { useHvAppShellConfig, HvAppShellRuntimeContext, CONFIG_TRANSLATIONS_NAMESPACE, useHvMenuItems } from "@hitachivantara/app-shell-shared";
|
|
5
|
+
import { createNavigationMenuItems } from "../utils/navigationUtil.mjs";
|
|
6
6
|
const MAX_TOP_MENU_DEPTH = 2;
|
|
7
7
|
const useNavigationMenuItems = () => {
|
|
8
|
-
const {
|
|
9
|
-
|
|
10
|
-
} =
|
|
11
|
-
const {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const tConfig = useMemo(() => i18n?.getFixedT(i18n.language, CONFIG_TRANSLATIONS_NAMESPACE) ?? // should not happen, but fallback if the i18n instance is not available
|
|
21
|
-
((l) => l), [i18n]);
|
|
22
|
-
const {
|
|
8
|
+
const { pathname } = useLocation();
|
|
9
|
+
const { navigationMode } = useHvAppShellConfig();
|
|
10
|
+
const { navigate } = useHvNavigation();
|
|
11
|
+
const { i18n } = useContext(HvAppShellRuntimeContext) ?? {};
|
|
12
|
+
const tConfig = useMemo(
|
|
13
|
+
() => i18n?.getFixedT(i18n.language, CONFIG_TRANSLATIONS_NAMESPACE) ?? // should not happen, but fallback if the i18n instance is not available
|
|
14
|
+
((l) => l),
|
|
15
|
+
[i18n]
|
|
16
|
+
);
|
|
17
|
+
const { items, selectedMenuItemId, rootMenuItemId } = useHvMenuItems();
|
|
18
|
+
const navigationMenuItemsTmp = createNavigationMenuItems(
|
|
19
|
+
tConfig,
|
|
23
20
|
items,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} = useHvMenuItems();
|
|
27
|
-
const navigationMenuItemsTmp = createNavigationMenuItems(tConfig, items, navigationMode === "ONLY_TOP" ? MAX_TOP_MENU_DEPTH : void 0);
|
|
21
|
+
navigationMode === "ONLY_TOP" ? MAX_TOP_MENU_DEPTH : void 0
|
|
22
|
+
);
|
|
28
23
|
useEffect(() => {
|
|
29
24
|
if (!selectedMenuItemId && pathname === "/" && items[0]?.href) {
|
|
30
25
|
navigate(items[0].href);
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import { useHvSnackbar } from "@hitachivantara/uikit-react-core";
|
|
2
|
-
import useBannerContext from "
|
|
2
|
+
import { useBannerContext } from "../providers/BannerProvider.mjs";
|
|
3
3
|
const useNotificationsEventListener = () => {
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
} = useHvSnackbar();
|
|
7
|
-
const {
|
|
8
|
-
show
|
|
9
|
-
} = useBannerContext();
|
|
4
|
+
const { enqueueSnackbar } = useHvSnackbar();
|
|
5
|
+
const { show } = useBannerContext();
|
|
10
6
|
const handleCustomEventSnackbar = (notification) => {
|
|
11
|
-
const {
|
|
12
|
-
message,
|
|
13
|
-
variant,
|
|
14
|
-
actions,
|
|
15
|
-
actionsCallback
|
|
16
|
-
} = notification;
|
|
7
|
+
const { message, variant, actions, actionsCallback } = notification;
|
|
17
8
|
let snackbarContentProps;
|
|
18
9
|
if (actions) {
|
|
19
10
|
snackbarContentProps = {
|
|
@@ -46,9 +37,7 @@ const useNotificationsEventListener = () => {
|
|
|
46
37
|
console.warn("Invalid notification type", notificationEvent.type);
|
|
47
38
|
}
|
|
48
39
|
};
|
|
49
|
-
return {
|
|
50
|
-
handleNotificationEvent
|
|
51
|
-
};
|
|
40
|
+
return { handleNotificationEvent };
|
|
52
41
|
};
|
|
53
42
|
export {
|
|
54
43
|
useNotificationsEventListener as default
|
|
@@ -1,31 +1,20 @@
|
|
|
1
1
|
import { useTheme } from "@hitachivantara/uikit-react-core";
|
|
2
|
-
import useLocalStorage from "./useLocalStorage.
|
|
2
|
+
import useLocalStorage from "./useLocalStorage.mjs";
|
|
3
3
|
const useThemeEventListener = () => {
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
changeTheme,
|
|
7
|
-
selectedMode,
|
|
8
|
-
colorModes
|
|
9
|
-
} = useTheme();
|
|
10
|
-
const {
|
|
11
|
-
setStoredValue
|
|
12
|
-
} = useLocalStorage("COLOR_MODE");
|
|
4
|
+
const { selectedTheme, changeTheme, selectedMode, colorModes } = useTheme();
|
|
5
|
+
const { setStoredValue } = useLocalStorage("COLOR_MODE");
|
|
13
6
|
const getNextColorMode = () => {
|
|
14
7
|
const index = colorModes.indexOf(selectedMode);
|
|
15
8
|
const nextIndex = (index + 1) % colorModes.length;
|
|
16
9
|
return colorModes[nextIndex];
|
|
17
10
|
};
|
|
18
11
|
const handleThemeEvent = (event) => {
|
|
19
|
-
const {
|
|
20
|
-
colorMode
|
|
21
|
-
} = event.detail;
|
|
12
|
+
const { colorMode } = event.detail;
|
|
22
13
|
const newColorMode = !colorMode || colorModes.indexOf(colorMode) === -1 ? getNextColorMode() : colorMode;
|
|
23
14
|
changeTheme(selectedTheme, newColorMode);
|
|
24
15
|
setStoredValue(newColorMode);
|
|
25
16
|
};
|
|
26
|
-
return {
|
|
27
|
-
handleThemeEvent
|
|
28
|
-
};
|
|
17
|
+
return { handleThemeEvent };
|
|
29
18
|
};
|
|
30
19
|
export {
|
|
31
20
|
useThemeEventListener as default
|
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
import i18next from "i18next";
|
|
2
1
|
import { initReactI18next } from "react-i18next";
|
|
2
|
+
import { createInstance } from "i18next";
|
|
3
3
|
import LanguageDetector from "i18next-browser-languagedetector";
|
|
4
|
-
import en from "./localization/en.json.
|
|
5
|
-
import pt from "./localization/pt.json.
|
|
4
|
+
import en from "./localization/en.json.mjs";
|
|
5
|
+
import pt from "./localization/pt.json.mjs";
|
|
6
6
|
const APP_SHELL_NAMESPACE = "appShell";
|
|
7
7
|
const addResourceBundles = (i18nInstance, bundles, namespace) => {
|
|
8
8
|
Object.entries(bundles).forEach((entry) => {
|
|
9
9
|
const [key, value] = entry;
|
|
10
|
-
i18nInstance.addResourceBundle(
|
|
10
|
+
i18nInstance.addResourceBundle(
|
|
11
|
+
key,
|
|
12
|
+
namespace ?? APP_SHELL_NAMESPACE,
|
|
13
|
+
value
|
|
14
|
+
);
|
|
11
15
|
});
|
|
12
16
|
};
|
|
13
17
|
const createI18Next = () => {
|
|
14
|
-
const newInstance =
|
|
18
|
+
const newInstance = createInstance();
|
|
15
19
|
newInstance.use(LanguageDetector).use(initReactI18next).init({
|
|
16
20
|
defaultNS: APP_SHELL_NAMESPACE,
|
|
17
21
|
fallbackLng: "en",
|
|
18
|
-
detection: {
|
|
19
|
-
order: ["navigator"]
|
|
20
|
-
},
|
|
22
|
+
detection: { order: ["navigator"] },
|
|
21
23
|
resources: {}
|
|
22
24
|
});
|
|
23
25
|
newInstance.addResourceBundle("en", APP_SHELL_NAMESPACE, en);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const errors = { "missing": { "configuration": "Missing or incomplete configuration." }, "notFound": { "code": "404", "title": "Oops! Seems like the page is lost in space.", "image_description": "404 Page not found" }, "genericError": { "code": "500", "title": "Shoot! We have a problem! Be back soon.", "image_description": "500 Generic error" }, "footer": "Click <navigate>here</navigate> to go back to the {{label}} page." };
|
|
2
|
+
const header = { "helpUrl": { "documentationLink": "Documentation link" }, "appSwitcher": { "title": "Apps", "ariaLabel": "App Switcher Panel" }, "navigation": { "openNavigationPanel": "Open navigation panel", "closeNavigationPanel": "Close navigation panel" }, "colorModeSwitcher": { "ariaLabel": "Switch color mode" } };
|
|
3
|
+
const verticalNavigation = { "ariaLabelNavigationTree": "Vertical navigation", "ariaLabelCollapse": "Collapse vertical navigation", "ariaLabelExpand": "Expand vertical navigation", "title": "Menu", "ariaLabelSliderForwardButton": "Navigate to submenu", "ariaLabelHeaderBackButton": "Back", "collapseAction": "Collapse Menu" };
|
|
4
|
+
const notifications = { "banner": { "close": "Close banner" } };
|
|
5
|
+
const en = {
|
|
6
|
+
errors,
|
|
7
|
+
header,
|
|
8
|
+
verticalNavigation,
|
|
9
|
+
notifications
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
en as default,
|
|
13
|
+
errors,
|
|
14
|
+
header,
|
|
15
|
+
notifications,
|
|
16
|
+
verticalNavigation
|
|
17
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const errors = { "missing": { "configuration": "Configuração em falta ou incompleta." }, "notFound": { "code": "404", "title": "Oops! Parece que a página está perdida no espaço.", "image_description": "404 Página não encontrada" }, "genericError": { "code": "500", "title": "Bolas! Temos um problema! Estaremos de volta em breve.", "image_description": "500 Erro genérico" }, "footer": "Carregue <navigate>aqui</navigate> para voltar à página {{label}}." };
|
|
2
|
+
const header = { "helpUrl": { "documentationLink": "Link de documentação" }, "appSwitcher": { "title": "Aplicações", "ariaLabel": "Painel do App Switcher" }, "navigation": { "openNavigationPanel": "Abrir painel de navegação", "closeNavigationPanel": "Fechar painel de navegação" }, "colorModeSwitcher": { "ariaLabel": "Alternar modo de cor" } };
|
|
3
|
+
const verticalNavigation = { "ariaLabelNavigationTree": "Navegação vertical", "ariaLabelCollapse": "Recolher navegação vertical", "ariaLabelExpand": "Expandir navegação vertical", "title": "Menu", "ariaLabelSliderForwardButton": "Navegar para submenu", "ariaLabelHeaderBackButton": "Voltar", "collapseAction": "Fechar" };
|
|
4
|
+
const notifications = { "banner": { "close": "Fechar barra de notificação" } };
|
|
5
|
+
const pt = {
|
|
6
|
+
errors,
|
|
7
|
+
header,
|
|
8
|
+
verticalNavigation,
|
|
9
|
+
notifications
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
pt as default,
|
|
13
|
+
errors,
|
|
14
|
+
header,
|
|
15
|
+
notifications,
|
|
16
|
+
verticalNavigation
|
|
17
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { HvTypography } from "@hitachivantara/uikit-react-core";
|
|
3
|
+
import { useNavigationContext } from "../../providers/NavigationProvider.mjs";
|
|
4
|
+
import { Footer } from "./Footer.mjs";
|
|
5
|
+
import { StyledErrorPage, StyledTitleWrapper, StyledImageWrapper } from "./styles.mjs";
|
|
6
|
+
const ErrorPage = ({
|
|
7
|
+
code = void 0,
|
|
8
|
+
title,
|
|
9
|
+
background,
|
|
10
|
+
backgroundLabel,
|
|
11
|
+
fullPage = false,
|
|
12
|
+
includeFooter = true
|
|
13
|
+
}) => {
|
|
14
|
+
const { isCompactMode, showHeaderSubMenu } = useNavigationContext();
|
|
15
|
+
return /* @__PURE__ */ jsxs(
|
|
16
|
+
StyledErrorPage,
|
|
17
|
+
{
|
|
18
|
+
showHeaderSubMenu,
|
|
19
|
+
isCompactMode,
|
|
20
|
+
fullPage,
|
|
21
|
+
children: [
|
|
22
|
+
/* @__PURE__ */ jsxs(StyledTitleWrapper, { children: [
|
|
23
|
+
code && /* @__PURE__ */ jsx(HvTypography, { variant: "title1", children: code }),
|
|
24
|
+
/* @__PURE__ */ jsx(HvTypography, { variant: isCompactMode ? "xsTitle" : "display", children: title })
|
|
25
|
+
] }),
|
|
26
|
+
/* @__PURE__ */ jsx(
|
|
27
|
+
StyledImageWrapper,
|
|
28
|
+
{
|
|
29
|
+
style: { backgroundImage: background },
|
|
30
|
+
role: "img",
|
|
31
|
+
"aria-label": backgroundLabel
|
|
32
|
+
}
|
|
33
|
+
),
|
|
34
|
+
includeFooter && /* @__PURE__ */ jsx(Footer, {})
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
export {
|
|
40
|
+
ErrorPage as default
|
|
41
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useErrorBoundary } from "react-error-boundary";
|
|
3
|
+
import { useTranslation, Trans } from "react-i18next";
|
|
4
|
+
import styled from "@emotion/styled";
|
|
5
|
+
import { useHvNavigation } from "@hitachivantara/app-shell-navigation";
|
|
6
|
+
import { useHvAppShellConfig } from "@hitachivantara/app-shell-shared";
|
|
7
|
+
import { HvTypography } from "@hitachivantara/uikit-react-core";
|
|
8
|
+
import { useNavigationContext } from "../../providers/NavigationProvider.mjs";
|
|
9
|
+
const StyledFooterWrapper = styled("div")({
|
|
10
|
+
textAlign: "center"
|
|
11
|
+
});
|
|
12
|
+
const Footer = () => {
|
|
13
|
+
const { t } = useTranslation();
|
|
14
|
+
const { navigate } = useHvNavigation();
|
|
15
|
+
const { navigationMode } = useHvAppShellConfig();
|
|
16
|
+
const { resetBoundary } = useErrorBoundary();
|
|
17
|
+
const { items, verticalNavigationItems, isCompactMode } = useNavigationContext();
|
|
18
|
+
const getFirstMenuItem = () => {
|
|
19
|
+
if (!isCompactMode && navigationMode !== "ONLY_LEFT") {
|
|
20
|
+
return items.length > 0 ? items[0] : null;
|
|
21
|
+
}
|
|
22
|
+
return verticalNavigationItems.length > 0 ? verticalNavigationItems[0] : null;
|
|
23
|
+
};
|
|
24
|
+
const firstMenuItem = getFirstMenuItem();
|
|
25
|
+
const handleClick = (event) => {
|
|
26
|
+
event.preventDefault();
|
|
27
|
+
if (firstMenuItem?.href) {
|
|
28
|
+
resetBoundary();
|
|
29
|
+
let path = firstMenuItem.href;
|
|
30
|
+
if (path.startsWith(".")) {
|
|
31
|
+
path = path.substring(1);
|
|
32
|
+
}
|
|
33
|
+
navigate(path);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
return firstMenuItem && /* @__PURE__ */ jsx(StyledFooterWrapper, { children: /* @__PURE__ */ jsx(HvTypography, { variant: "body", children: /* @__PURE__ */ jsx(
|
|
37
|
+
Trans,
|
|
38
|
+
{
|
|
39
|
+
t,
|
|
40
|
+
i18nKey: "errors.footer",
|
|
41
|
+
values: { label: firstMenuItem.label },
|
|
42
|
+
components: {
|
|
43
|
+
navigate: /* @__PURE__ */ jsx(
|
|
44
|
+
HvTypography,
|
|
45
|
+
{
|
|
46
|
+
link: true,
|
|
47
|
+
component: "a",
|
|
48
|
+
href: firstMenuItem.href,
|
|
49
|
+
variant: "label",
|
|
50
|
+
onClick: handleClick,
|
|
51
|
+
children: firstMenuItem.label
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
) }) });
|
|
57
|
+
};
|
|
58
|
+
export {
|
|
59
|
+
Footer
|
|
60
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import styled from "@emotion/styled";
|
|
2
|
+
import { theme } from "@hitachivantara/uikit-react-core";
|
|
3
|
+
const calcHeight = ({
|
|
4
|
+
showHeaderSubMenu,
|
|
5
|
+
isCompactMode,
|
|
6
|
+
fullPage
|
|
7
|
+
}) => {
|
|
8
|
+
if (fullPage) {
|
|
9
|
+
return `100vh`;
|
|
10
|
+
}
|
|
11
|
+
if (showHeaderSubMenu && !isCompactMode) {
|
|
12
|
+
return `calc(100vh - (${theme.header.height} + ${theme.header.secondLevelHeight}px + ${theme.space.lg} + ${theme.space.lg}))`;
|
|
13
|
+
}
|
|
14
|
+
return `calc(100vh - (${theme.header.height} + ${theme.space.lg} + ${theme.space.lg}))`;
|
|
15
|
+
};
|
|
16
|
+
const StyledErrorPage = styled("div")(
|
|
17
|
+
{
|
|
18
|
+
flex: 1,
|
|
19
|
+
display: "flex",
|
|
20
|
+
flexDirection: "column",
|
|
21
|
+
marginTop: theme.space.lg
|
|
22
|
+
},
|
|
23
|
+
(props) => ({ height: calcHeight(props) })
|
|
24
|
+
);
|
|
25
|
+
const StyledImageWrapper = styled("div")({
|
|
26
|
+
flex: 1,
|
|
27
|
+
display: "flex",
|
|
28
|
+
backgroundSize: "contain",
|
|
29
|
+
backgroundPosition: "center center",
|
|
30
|
+
backgroundRepeat: "no-repeat",
|
|
31
|
+
flexDirection: "column",
|
|
32
|
+
height: "100%"
|
|
33
|
+
});
|
|
34
|
+
const StyledTitleWrapper = styled("div")({
|
|
35
|
+
textAlign: "center"
|
|
36
|
+
});
|
|
37
|
+
export {
|
|
38
|
+
StyledErrorPage,
|
|
39
|
+
StyledImageWrapper,
|
|
40
|
+
StyledTitleWrapper
|
|
41
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation } from "react-i18next";
|
|
3
|
+
import BlackCat from "./500.svg.mjs";
|
|
4
|
+
import ErrorPage from "../ErrorPage/ErrorPage.mjs";
|
|
5
|
+
const GenericError = ({ fullPage = false, includeFooter = true }) => {
|
|
6
|
+
const { t } = useTranslation(void 0, { keyPrefix: "errors.genericError" });
|
|
7
|
+
return /* @__PURE__ */ jsx(
|
|
8
|
+
ErrorPage,
|
|
9
|
+
{
|
|
10
|
+
code: t("code"),
|
|
11
|
+
title: t("title"),
|
|
12
|
+
backgroundLabel: t("image_description"),
|
|
13
|
+
fullPage,
|
|
14
|
+
includeFooter,
|
|
15
|
+
background: `url(${BlackCat})`
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
export {
|
|
20
|
+
GenericError as default
|
|
21
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import Loading from "../../components/layout/Loading/Loading.mjs";
|
|
3
|
+
import { useNavigationContext } from "../../providers/NavigationProvider.mjs";
|
|
4
|
+
import StyledLoadingPage from "./styles.mjs";
|
|
5
|
+
const LoadingPage = () => {
|
|
6
|
+
const { isCompactMode, showHeaderSubMenu } = useNavigationContext();
|
|
7
|
+
return /* @__PURE__ */ jsx(
|
|
8
|
+
StyledLoadingPage,
|
|
9
|
+
{
|
|
10
|
+
showHeaderSubMenu,
|
|
11
|
+
isCompactMode,
|
|
12
|
+
children: /* @__PURE__ */ jsx(Loading, {})
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
export {
|
|
17
|
+
LoadingPage as default
|
|
18
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import styled from "@emotion/styled";
|
|
2
|
+
import { theme } from "@hitachivantara/uikit-react-core";
|
|
3
|
+
const calcHeight = ({
|
|
4
|
+
showHeaderSubMenu,
|
|
5
|
+
isCompactMode
|
|
6
|
+
}) => {
|
|
7
|
+
if (showHeaderSubMenu && !isCompactMode) {
|
|
8
|
+
return `calc(100vh - (${theme.header.height} + ${theme.header.secondLevelHeight}px + ${theme.space.lg} + ${theme.space.lg}))`;
|
|
9
|
+
}
|
|
10
|
+
return `calc(100vh - (${theme.header.height} + ${theme.space.lg} + ${theme.space.lg}))`;
|
|
11
|
+
};
|
|
12
|
+
const StyledLoadingPage = styled("div")(
|
|
13
|
+
{
|
|
14
|
+
flex: 1,
|
|
15
|
+
display: "flex",
|
|
16
|
+
flexDirection: "column",
|
|
17
|
+
marginTop: theme.space.lg
|
|
18
|
+
},
|
|
19
|
+
(props) => ({ height: calcHeight(props) })
|
|
20
|
+
);
|
|
21
|
+
export {
|
|
22
|
+
StyledLoadingPage as default
|
|
23
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation } from "react-i18next";
|
|
3
|
+
import DogeSpace from "./404.svg.mjs";
|
|
4
|
+
import ErrorPage from "../ErrorPage/ErrorPage.mjs";
|
|
5
|
+
const NotFound = () => {
|
|
6
|
+
const { t } = useTranslation(void 0, { keyPrefix: "errors.notFound" });
|
|
7
|
+
return /* @__PURE__ */ jsx(
|
|
8
|
+
ErrorPage,
|
|
9
|
+
{
|
|
10
|
+
code: t("code"),
|
|
11
|
+
title: t("title"),
|
|
12
|
+
backgroundLabel: t("image_description"),
|
|
13
|
+
background: `url(${DogeSpace})`
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
NotFound as default
|
|
19
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense } from "react";
|
|
3
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
4
|
+
import { Outlet } from "react-router-dom";
|
|
5
|
+
import { BannerProvider } from "../../providers/BannerProvider.mjs";
|
|
6
|
+
import { NavigationProvider } from "../../providers/NavigationProvider.mjs";
|
|
7
|
+
import CombinedProviders from "../../utils/CombinedProviders.mjs";
|
|
8
|
+
import LoadingPage from "../LoadingPage/LoadingPage.mjs";
|
|
9
|
+
import CustomHooksInitializer from "../../components/CustomHooksInitializer/CustomHooksInitializer.mjs";
|
|
10
|
+
import Header from "../../components/layout/Header/Header.mjs";
|
|
11
|
+
import Main from "../../components/layout/Main/Main.mjs";
|
|
12
|
+
import GenericError from "../GenericError/GenericError.mjs";
|
|
13
|
+
const Root = ({ providers }) => /* @__PURE__ */ jsx(ErrorBoundary, { fallback: /* @__PURE__ */ jsx(GenericError, { fullPage: true }), children: /* @__PURE__ */ jsx(CombinedProviders, { providers, children: /* @__PURE__ */ jsx(NavigationProvider, { children: /* @__PURE__ */ jsxs(BannerProvider, { children: [
|
|
14
|
+
/* @__PURE__ */ jsx(CustomHooksInitializer, {}),
|
|
15
|
+
/* @__PURE__ */ jsx(Header, {}),
|
|
16
|
+
/* @__PURE__ */ jsx(Main, { children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingPage, {}), children: /* @__PURE__ */ jsx(Outlet, {}) }) })
|
|
17
|
+
] }) }) }) });
|
|
18
|
+
export {
|
|
19
|
+
Root as default
|
|
20
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo, useEffect, createContext, useContext } from "react";
|
|
3
|
+
import { useTranslation } from "react-i18next";
|
|
4
|
+
import { css } from "@emotion/css";
|
|
5
|
+
import { uid } from "uid";
|
|
6
|
+
import { useTheme, theme, HvBanner } from "@hitachivantara/uikit-react-core";
|
|
7
|
+
import { useLayoutContext } from "./LayoutProvider.mjs";
|
|
8
|
+
import { useNavigationContext } from "./NavigationProvider.mjs";
|
|
9
|
+
const BannerContext = createContext({
|
|
10
|
+
show: () => {
|
|
11
|
+
},
|
|
12
|
+
dismiss: () => {
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
const BannerProvider = ({ children }) => {
|
|
16
|
+
const { t } = useTranslation(void 0, {
|
|
17
|
+
keyPrefix: "notifications.banner"
|
|
18
|
+
});
|
|
19
|
+
const { activeTheme } = useTheme();
|
|
20
|
+
const { showHeaderSubMenu, isCompactMode } = useNavigationContext();
|
|
21
|
+
const { verticalNavigationWidth, setBannerMaxHeight } = useLayoutContext();
|
|
22
|
+
const [banners, setBanners] = useState([]);
|
|
23
|
+
const isPentahoTheme = activeTheme?.name === "pentahoPlus";
|
|
24
|
+
const show = (notification) => {
|
|
25
|
+
const id = uid();
|
|
26
|
+
const newBanner = {
|
|
27
|
+
id,
|
|
28
|
+
...notification,
|
|
29
|
+
variant: notification.variant ?? "default"
|
|
30
|
+
};
|
|
31
|
+
setBanners((prevBanners) => [...prevBanners, newBanner]);
|
|
32
|
+
};
|
|
33
|
+
const dismiss = (id) => {
|
|
34
|
+
setBanners(
|
|
35
|
+
(prevBanners) => prevBanners.filter((banner) => banner.id !== id)
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
const value = useMemo(
|
|
39
|
+
() => ({
|
|
40
|
+
show,
|
|
41
|
+
dismiss
|
|
42
|
+
}),
|
|
43
|
+
[]
|
|
44
|
+
);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (banners.length > 0) {
|
|
47
|
+
const bannerHeights = banners.map((item) => {
|
|
48
|
+
const bannerElement = document.getElementById(item.id);
|
|
49
|
+
return bannerElement ? bannerElement.clientHeight : 0;
|
|
50
|
+
});
|
|
51
|
+
const maxBannerHeight = Math.max(...bannerHeights);
|
|
52
|
+
setBannerMaxHeight(maxBannerHeight);
|
|
53
|
+
} else {
|
|
54
|
+
setBannerMaxHeight(0);
|
|
55
|
+
}
|
|
56
|
+
}, [banners, setBannerMaxHeight]);
|
|
57
|
+
const { root, topCenter, bottomCenter } = useMemo(() => {
|
|
58
|
+
const paddingY = theme.space.xs;
|
|
59
|
+
const paddingX = theme.space.sm;
|
|
60
|
+
return {
|
|
61
|
+
root: css({
|
|
62
|
+
left: `calc(${verticalNavigationWidth}px + ${paddingX})`,
|
|
63
|
+
width: `calc(100% - (${verticalNavigationWidth}px + ${paddingX}) - ${paddingX})`,
|
|
64
|
+
transform: "unset",
|
|
65
|
+
minWidth: "unset",
|
|
66
|
+
zIndex: theme.zIndices.banner,
|
|
67
|
+
...isPentahoTheme && {
|
|
68
|
+
maxWidth: 540,
|
|
69
|
+
left: `calc(${verticalNavigationWidth}px + (100% - ${verticalNavigationWidth}px) / 2)`,
|
|
70
|
+
transform: `translateX(-50%)`
|
|
71
|
+
}
|
|
72
|
+
}),
|
|
73
|
+
topCenter: css({
|
|
74
|
+
marginTop: showHeaderSubMenu && !isCompactMode ? `calc(${theme.header.height} + ${theme.header.secondLevelHeight} + ${paddingY})` : `calc(${theme.header.height} + ${paddingY})`
|
|
75
|
+
}),
|
|
76
|
+
bottomCenter: css({
|
|
77
|
+
marginBottom: theme.space.md
|
|
78
|
+
})
|
|
79
|
+
};
|
|
80
|
+
}, [
|
|
81
|
+
isCompactMode,
|
|
82
|
+
isPentahoTheme,
|
|
83
|
+
showHeaderSubMenu,
|
|
84
|
+
verticalNavigationWidth
|
|
85
|
+
]);
|
|
86
|
+
return /* @__PURE__ */ jsxs(BannerContext.Provider, { value, children: [
|
|
87
|
+
banners.map((banner) => /* @__PURE__ */ jsx(
|
|
88
|
+
HvBanner,
|
|
89
|
+
{
|
|
90
|
+
classes: {
|
|
91
|
+
root,
|
|
92
|
+
anchorOriginBottomCenter: bottomCenter,
|
|
93
|
+
anchorOriginTopCenter: topCenter
|
|
94
|
+
},
|
|
95
|
+
id: banner.id,
|
|
96
|
+
offset: 0,
|
|
97
|
+
open: true,
|
|
98
|
+
onClose: () => dismiss(banner.id),
|
|
99
|
+
variant: banner.variant,
|
|
100
|
+
label: banner.message,
|
|
101
|
+
showIcon: true,
|
|
102
|
+
actions: banner.actions,
|
|
103
|
+
actionsCallback: banner.actionsCallback,
|
|
104
|
+
bannerContentProps: {
|
|
105
|
+
actionProps: { "aria-label": t("close") }
|
|
106
|
+
},
|
|
107
|
+
anchorOrigin: isPentahoTheme ? "bottom" : void 0,
|
|
108
|
+
transitionDirection: isPentahoTheme ? "up" : void 0
|
|
109
|
+
},
|
|
110
|
+
banner.id
|
|
111
|
+
)),
|
|
112
|
+
children
|
|
113
|
+
] });
|
|
114
|
+
};
|
|
115
|
+
const useBannerContext = () => {
|
|
116
|
+
const context = useContext(BannerContext);
|
|
117
|
+
if (!context) {
|
|
118
|
+
console.error("BannerContext was used outside of its Provider");
|
|
119
|
+
}
|
|
120
|
+
return context;
|
|
121
|
+
};
|
|
122
|
+
export {
|
|
123
|
+
BannerContext,
|
|
124
|
+
BannerProvider,
|
|
125
|
+
useBannerContext
|
|
126
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo, createContext, useContext } from "react";
|
|
3
|
+
const LayoutContext = createContext({
|
|
4
|
+
bannerMaxHeight: 0,
|
|
5
|
+
setBannerMaxHeight: () => {
|
|
6
|
+
},
|
|
7
|
+
verticalNavigationWidth: 0,
|
|
8
|
+
setVerticalNavigationWidth: () => {
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const LayoutProvider = ({ children }) => {
|
|
12
|
+
const [bannerMaxHeight, setBannerMaxHeight] = useState(0);
|
|
13
|
+
const [verticalNavigationWidth, setVerticalNavigationWidth] = useState(0);
|
|
14
|
+
const value = useMemo(
|
|
15
|
+
() => ({
|
|
16
|
+
bannerMaxHeight,
|
|
17
|
+
setBannerMaxHeight,
|
|
18
|
+
verticalNavigationWidth,
|
|
19
|
+
setVerticalNavigationWidth
|
|
20
|
+
}),
|
|
21
|
+
[bannerMaxHeight, verticalNavigationWidth]
|
|
22
|
+
);
|
|
23
|
+
return /* @__PURE__ */ jsx(LayoutContext.Provider, { value, children });
|
|
24
|
+
};
|
|
25
|
+
const useLayoutContext = () => {
|
|
26
|
+
const context = useContext(LayoutContext);
|
|
27
|
+
if (!context) {
|
|
28
|
+
console.error("LayoutContext was used outside of its Provider");
|
|
29
|
+
}
|
|
30
|
+
return context;
|
|
31
|
+
};
|
|
32
|
+
export {
|
|
33
|
+
LayoutContext,
|
|
34
|
+
LayoutProvider,
|
|
35
|
+
useLayoutContext
|
|
36
|
+
};
|