@hitachivantara/app-shell-shared 2.3.1 → 2.3.2
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/AppShellCombinedProvidersContext.js +6 -9
- package/dist/AppShellContext.js +6 -7
- package/dist/AppShellModelContext.js +8 -13
- package/dist/AppShellRuntimeContext.js +8 -13
- package/dist/AppShellViewContext.js +4 -4
- package/dist/bundles/app-shell-shared.esm.js +305 -281
- package/dist/components/DynamicHooksEvaluator/DynamicHooksEvaluator.js +33 -45
- package/dist/hooks/useMenuItems.js +52 -59
- package/dist/i18n/index.js +12 -15
- package/dist/index.js +2 -18
- package/dist/utils/navigationUtils.js +188 -141
- package/package.json +8 -5
|
@@ -1,48 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { createElement, useCallback, useEffect, useRef } from "react";
|
|
2
|
+
//#region src/components/DynamicHooksEvaluator/DynamicHooksEvaluator.tsx
|
|
3
|
+
var generateKey = () => {
|
|
4
|
+
return `hooks-${Date.now()}-${Math.round(1e3 * Math.random())}`;
|
|
4
5
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
useEffect(() => onEvaluate(results), []);
|
|
15
|
-
return null;
|
|
6
|
+
var DynamicHooksEvaluatorInner = ({ hooks, onEvaluate }) => {
|
|
7
|
+
const results = [];
|
|
8
|
+
for (const { hook, params = [] } of hooks) {
|
|
9
|
+
const result = hook(...params);
|
|
10
|
+
results.push(result);
|
|
11
|
+
}
|
|
12
|
+
useEffect(() => onEvaluate(results), []);
|
|
13
|
+
return null;
|
|
16
14
|
};
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
onEvaluate(results);
|
|
37
|
-
},
|
|
38
|
-
[onEvaluate]
|
|
39
|
-
);
|
|
40
|
-
return createElement(DynamicHooksEvaluatorInner, {
|
|
41
|
-
key: keyRef.current,
|
|
42
|
-
hooks,
|
|
43
|
-
onEvaluate: onEvaluateWrapper
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
export {
|
|
47
|
-
DynamicHooksEvaluator
|
|
15
|
+
var DynamicHooksEvaluator = ({ hooks, onEvaluate }) => {
|
|
16
|
+
const skipRenderRef = useRef(false);
|
|
17
|
+
const keyRef = useRef(generateKey());
|
|
18
|
+
const hooksRef = useRef(hooks);
|
|
19
|
+
if (hooksRef.current !== hooks) {
|
|
20
|
+
skipRenderRef.current = false;
|
|
21
|
+
hooksRef.current = hooks;
|
|
22
|
+
}
|
|
23
|
+
if (skipRenderRef.current) skipRenderRef.current = false;
|
|
24
|
+
else keyRef.current = generateKey();
|
|
25
|
+
const onEvaluateWrapper = useCallback((results) => {
|
|
26
|
+
skipRenderRef.current = true;
|
|
27
|
+
onEvaluate(results);
|
|
28
|
+
}, [onEvaluate]);
|
|
29
|
+
return createElement(DynamicHooksEvaluatorInner, {
|
|
30
|
+
key: keyRef.current,
|
|
31
|
+
hooks,
|
|
32
|
+
onEvaluate: onEvaluateWrapper
|
|
33
|
+
});
|
|
48
34
|
};
|
|
35
|
+
//#endregion
|
|
36
|
+
export { DynamicHooksEvaluator };
|
|
@@ -1,62 +1,55 @@
|
|
|
1
|
-
import { useMemo, useState, useEffect } from "react";
|
|
2
|
-
import { useLocation } from "react-router-dom";
|
|
3
1
|
import { useHvAppShellModel } from "../AppShellModelContext.js";
|
|
4
2
|
import { useHvAppShellRuntimeContext } from "../AppShellRuntimeContext.js";
|
|
5
|
-
import { useHvAppShellI18n
|
|
6
|
-
import { createMenuItems,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
items,
|
|
56
|
-
selectedMenuItemId,
|
|
57
|
-
rootMenuItemId
|
|
58
|
-
};
|
|
59
|
-
};
|
|
60
|
-
export {
|
|
61
|
-
useHvMenuItems
|
|
3
|
+
import { useHvAppShellI18n } from "../i18n/index.js";
|
|
4
|
+
import { addPrefixToHref, createMenuItems, findFirstLeafItem, findItemById, getRootIdFromItemId, searchHrefInMenuItems } from "../utils/navigationUtils.js";
|
|
5
|
+
import { useEffect, useMemo, useState } from "react";
|
|
6
|
+
import { useLocation } from "react-router-dom";
|
|
7
|
+
//#region src/hooks/useMenuItems.tsx
|
|
8
|
+
var MAX_TOP_MENU_DEPTH = 2;
|
|
9
|
+
var useHvMenuItems = () => {
|
|
10
|
+
const { pathname, search, state: locationState } = useLocation();
|
|
11
|
+
const { navigationMode, menu } = useHvAppShellModel();
|
|
12
|
+
useHvAppShellI18n();
|
|
13
|
+
const { i18n } = useHvAppShellRuntimeContext();
|
|
14
|
+
const resolvedLanguage = i18n.resolvedLanguage;
|
|
15
|
+
const tConfig = useMemo(() => i18n.getFixedT(resolvedLanguage ?? null, "app"), [i18n, resolvedLanguage]);
|
|
16
|
+
const items = useMemo(() => {
|
|
17
|
+
return createMenuItems(tConfig, menu, navigationMode === "ONLY_TOP" ? MAX_TOP_MENU_DEPTH : void 0);
|
|
18
|
+
}, [
|
|
19
|
+
navigationMode,
|
|
20
|
+
menu,
|
|
21
|
+
tConfig
|
|
22
|
+
]);
|
|
23
|
+
const [selectedMenuItemId, setSelectedMenuItemId] = useState(searchHrefInMenuItems(items, addPrefixToHref(pathname), search));
|
|
24
|
+
const [rootMenuItemId, setRootMenuItemId] = useState(getRootIdFromItemId(selectedMenuItemId));
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!items.length) return;
|
|
27
|
+
if (locationState?.selectedItemId) {
|
|
28
|
+
setRootMenuItemId(getRootIdFromItemId(locationState.selectedItemId));
|
|
29
|
+
const selectedItem = findItemById(items, locationState.selectedItemId);
|
|
30
|
+
if (selectedItem?.data?.length) setSelectedMenuItemId(findFirstLeafItem(selectedItem.data)?.id);
|
|
31
|
+
else setSelectedMenuItemId(selectedItem?.id);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const toBeSelected = searchHrefInMenuItems(items, addPrefixToHref(pathname), search);
|
|
35
|
+
if (toBeSelected) {
|
|
36
|
+
setRootMenuItemId(getRootIdFromItemId(toBeSelected));
|
|
37
|
+
setSelectedMenuItemId(toBeSelected);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
setRootMenuItemId(void 0);
|
|
41
|
+
setSelectedMenuItemId(void 0);
|
|
42
|
+
}, [
|
|
43
|
+
items,
|
|
44
|
+
locationState,
|
|
45
|
+
pathname,
|
|
46
|
+
search
|
|
47
|
+
]);
|
|
48
|
+
return {
|
|
49
|
+
items,
|
|
50
|
+
selectedMenuItemId,
|
|
51
|
+
rootMenuItemId
|
|
52
|
+
};
|
|
62
53
|
};
|
|
54
|
+
//#endregion
|
|
55
|
+
export { useHvMenuItems };
|
package/dist/i18n/index.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import { createContext, useContext } from "react";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
13
|
-
export {
|
|
14
|
-
CONFIG_TRANSLATIONS_NAMESPACE,
|
|
15
|
-
HvAppShellI18nContext,
|
|
16
|
-
useHvAppShellI18n
|
|
2
|
+
//#region src/i18n/index.ts
|
|
3
|
+
var CONFIG_TRANSLATIONS_NAMESPACE = "app";
|
|
4
|
+
var HvAppShellI18nContext = createContext(void 0);
|
|
5
|
+
/**
|
|
6
|
+
* Gets the App Shell's I18N context.
|
|
7
|
+
*/
|
|
8
|
+
var useHvAppShellI18n = () => {
|
|
9
|
+
const context = useContext(HvAppShellI18nContext);
|
|
10
|
+
if (!context) throw new Error("useHvAppShellI18n must be used within HvAppShellI18nContext.Provider");
|
|
11
|
+
return context;
|
|
17
12
|
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { CONFIG_TRANSLATIONS_NAMESPACE, HvAppShellI18nContext, useHvAppShellI18n };
|
package/dist/index.js
CHANGED
|
@@ -3,24 +3,8 @@ import { HvAppShellModelContext, useHvAppShellModel } from "./AppShellModelConte
|
|
|
3
3
|
import { HvAppShellViewContext } from "./AppShellViewContext.js";
|
|
4
4
|
import { HvAppShellRuntimeContext, useHvAppShellRuntimeContext } from "./AppShellRuntimeContext.js";
|
|
5
5
|
import { HvAppShellCombinedProvidersContext, useHvAppShellCombinedProviders } from "./AppShellCombinedProvidersContext.js";
|
|
6
|
-
import { useAsync } from "@hitachivantara/app-shell-services";
|
|
7
6
|
import { CONFIG_TRANSLATIONS_NAMESPACE, HvAppShellI18nContext, useHvAppShellI18n } from "./i18n/index.js";
|
|
8
7
|
import { useHvMenuItems } from "./hooks/useMenuItems.js";
|
|
9
8
|
import { DynamicHooksEvaluator } from "./components/DynamicHooksEvaluator/DynamicHooksEvaluator.js";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
DynamicHooksEvaluator,
|
|
13
|
-
HvAppShellCombinedProvidersContext,
|
|
14
|
-
HvAppShellContext,
|
|
15
|
-
HvAppShellI18nContext,
|
|
16
|
-
HvAppShellModelContext,
|
|
17
|
-
HvAppShellRuntimeContext,
|
|
18
|
-
HvAppShellViewContext,
|
|
19
|
-
useAsync,
|
|
20
|
-
useHvAppShellCombinedProviders,
|
|
21
|
-
useHvAppShellConfig,
|
|
22
|
-
useHvAppShellI18n,
|
|
23
|
-
useHvAppShellModel,
|
|
24
|
-
useHvAppShellRuntimeContext,
|
|
25
|
-
useHvMenuItems
|
|
26
|
-
};
|
|
9
|
+
import { useAsync } from "@hitachivantara/app-shell-services";
|
|
10
|
+
export { CONFIG_TRANSLATIONS_NAMESPACE, DynamicHooksEvaluator, HvAppShellCombinedProvidersContext, HvAppShellContext, HvAppShellI18nContext, HvAppShellModelContext, HvAppShellRuntimeContext, HvAppShellViewContext, useAsync, useHvAppShellCombinedProviders, useHvAppShellConfig, useHvAppShellI18n, useHvAppShellModel, useHvAppShellRuntimeContext, useHvMenuItems };
|
|
@@ -1,151 +1,198 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
//#region src/utils/navigationUtils.ts
|
|
2
|
+
/**
|
|
3
|
+
* Compute the target href for menu item.
|
|
4
|
+
*
|
|
5
|
+
* @param menuItem The root target href.
|
|
6
|
+
*
|
|
7
|
+
* @returns The menu item target href. If empty, returns the first child that has it defined or empty string if none.
|
|
8
|
+
*/
|
|
9
|
+
var getMenuTargetHref = (menuItem) => {
|
|
10
|
+
const { target } = menuItem;
|
|
11
|
+
if (target) return target;
|
|
12
|
+
if (menuItem.submenus) return getMenuTargetHref(menuItem.submenus[0]);
|
|
13
|
+
return "";
|
|
10
14
|
};
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Adds a dot to the href to indicate that it is a relative path.
|
|
17
|
+
*/
|
|
18
|
+
var addPrefixToHref = (href) => {
|
|
19
|
+
return !href.startsWith(".") ? `.${href}` : href;
|
|
13
20
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Creates a navigation data structure ({@link MenuItem}) from the provided menu configuration ({@link HvAppShellMenuConfig}).
|
|
23
|
+
*
|
|
24
|
+
* Note: The menu configuration received here has already been filtered based on conditions.
|
|
25
|
+
*
|
|
26
|
+
* @param t Translation function
|
|
27
|
+
* @param menuItems The set of menu items from configuration (already filtered)
|
|
28
|
+
* @param maxDepth The maximum depth up until the recursiveness should occur for the creation of the menu items
|
|
29
|
+
* @param parentMenuItem The parent menu item of the set of menu items
|
|
30
|
+
*
|
|
31
|
+
* @returns An array of {@link MenuItem}
|
|
32
|
+
*/
|
|
33
|
+
var createMenuItems = (t, menuItems, maxDepth, parentMenuItem) => {
|
|
34
|
+
if (maxDepth !== void 0 && maxDepth <= 0) return [];
|
|
35
|
+
return menuItems?.reduce((accumulator, currentValue, index) => {
|
|
36
|
+
const navItem = {
|
|
37
|
+
id: parentMenuItem ? `${parentMenuItem.id}-${index}` : `${index}`,
|
|
38
|
+
label: t(currentValue.label),
|
|
39
|
+
href: addPrefixToHref(getMenuTargetHref(currentValue)),
|
|
40
|
+
icon: currentValue.icon,
|
|
41
|
+
parent: parentMenuItem
|
|
42
|
+
};
|
|
43
|
+
if (currentValue.submenus) {
|
|
44
|
+
const updatedDepth = maxDepth !== void 0 ? maxDepth - 1 : void 0;
|
|
45
|
+
const data = createMenuItems(t, currentValue.submenus, updatedDepth, navItem);
|
|
46
|
+
if (data.length > 0) navItem.data = data;
|
|
47
|
+
}
|
|
48
|
+
accumulator.push(navItem);
|
|
49
|
+
return accumulator;
|
|
50
|
+
}, []) ?? [];
|
|
41
51
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Removes the items that do not have path and replaces it by its children, recursively.
|
|
54
|
+
*
|
|
55
|
+
* @param items The list of {@link MenuItem}.
|
|
56
|
+
*
|
|
57
|
+
* @returns A flat array of {@link MenuItem}.
|
|
58
|
+
*/
|
|
59
|
+
var flatMenuItems = (items) => {
|
|
60
|
+
return items.reduce((acc, item) => {
|
|
61
|
+
if (item.data) acc.push(...flatMenuItems(item.data));
|
|
62
|
+
else acc.push(item);
|
|
63
|
+
return acc;
|
|
64
|
+
}, []);
|
|
51
65
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Helper function that uses a cumulative reduction to derive an array of cumulative hrefs based on the components
|
|
68
|
+
* of the input string.
|
|
69
|
+
* @example
|
|
70
|
+
* // returns ['/', '/app', '/app/details', '/app/details/1']
|
|
71
|
+
* // normalizedHref: "/app/details/1"
|
|
72
|
+
*
|
|
73
|
+
* @param normalizedHref The href string to be reduced.
|
|
74
|
+
*
|
|
75
|
+
* @returns the array of cumulative hrefs.
|
|
76
|
+
*/
|
|
77
|
+
var decomposeHrefStringToArray = (normalizedHref) => {
|
|
78
|
+
const hrefArray = normalizedHref.split("/").reduce((accumulator, currentValue) => {
|
|
79
|
+
if (currentValue === "") return accumulator;
|
|
80
|
+
const prefix = accumulator.length === 0 ? "" : accumulator[0];
|
|
81
|
+
const href = currentValue === "." ? currentValue : `${prefix}/${currentValue}`;
|
|
82
|
+
accumulator.unshift(href);
|
|
83
|
+
return accumulator;
|
|
84
|
+
}, []);
|
|
85
|
+
hrefArray.push("./");
|
|
86
|
+
return hrefArray;
|
|
64
87
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
});
|
|
100
|
-
return toBeSelectedId;
|
|
88
|
+
/**
|
|
89
|
+
* Algorithm implementation of the searchHrefInMenuItems function.
|
|
90
|
+
*
|
|
91
|
+
* @returns An object containing an item id or empty, if no match is found, and a flag to indicate if a
|
|
92
|
+
* full href match was found. If the id is filled but the flag is 'false', then only partial match was found.
|
|
93
|
+
*/
|
|
94
|
+
var searchHrefMatch = (items, normalizedHref, normalizedFullHref) => {
|
|
95
|
+
let toBeSelectedId;
|
|
96
|
+
let toBeSelectedHref;
|
|
97
|
+
const reducedNormalizedHref = decomposeHrefStringToArray(normalizedHref);
|
|
98
|
+
flatMenuItems(items).some((item) => {
|
|
99
|
+
let normalizedItemHref;
|
|
100
|
+
let normalizedItemHrefParams;
|
|
101
|
+
const idx = item.href?.indexOf("?");
|
|
102
|
+
if (idx !== -1) {
|
|
103
|
+
normalizedItemHref = item.href?.slice(0, idx).toLowerCase();
|
|
104
|
+
normalizedItemHrefParams = item.href?.slice(idx).toLowerCase();
|
|
105
|
+
} else {
|
|
106
|
+
normalizedItemHref = item.href?.toLowerCase();
|
|
107
|
+
normalizedItemHrefParams = "";
|
|
108
|
+
}
|
|
109
|
+
if (normalizedItemHref && normalizedItemHref.length > 1 && normalizedItemHref.endsWith("/")) normalizedItemHref = normalizedItemHref.slice(0, normalizedItemHref.length - 1);
|
|
110
|
+
if (`${normalizedItemHref}${normalizedItemHrefParams}` === normalizedFullHref) {
|
|
111
|
+
toBeSelectedId = item.id;
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
const matchedHref = reducedNormalizedHref.find((href) => normalizedItemHref === href);
|
|
115
|
+
if (matchedHref && (!toBeSelectedHref || matchedHref.length > toBeSelectedHref?.length)) {
|
|
116
|
+
toBeSelectedId = item.id;
|
|
117
|
+
toBeSelectedHref = matchedHref;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
});
|
|
121
|
+
return toBeSelectedId;
|
|
101
122
|
};
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Searches for the href and parameters on all the menu items and its children until an exact match is found. If no
|
|
125
|
+
* exact match is found but partial is, then the parent id for the first partial match found is returned.
|
|
126
|
+
* @example
|
|
127
|
+
* // returns '2'
|
|
128
|
+
* // href: '/home', parameters: '?x=y', items: [{id:'1', href:'/home?z=v'},{id:'2', href:'/home'}
|
|
129
|
+
*
|
|
130
|
+
* For consistency purposes and based on the Router behavior, if either the href or the item href
|
|
131
|
+
* (stripped of its query params) ends with a forward slash, then the comparison will ignore it
|
|
132
|
+
* @example
|
|
133
|
+
* // returns '1'
|
|
134
|
+
* // href: '/home/', parameters: <empty>, items: [{id:'1', href:'/home'}]
|
|
135
|
+
*
|
|
136
|
+
* @param items The list of menu items to be searched.
|
|
137
|
+
* @param href The url href after the domain up to the query parameters.
|
|
138
|
+
* @param [parameters] The url query string after pathname.
|
|
139
|
+
*
|
|
140
|
+
* @returns The id of a parent menu item or an empty string.
|
|
141
|
+
*/
|
|
142
|
+
var searchHrefInMenuItems = (items, href, parameters) => {
|
|
143
|
+
if (!href) return;
|
|
144
|
+
const normalizedHref = href.length > 1 && href.endsWith("/") ? href.slice(0, href.length - 1).toLowerCase() : href.toLowerCase();
|
|
145
|
+
return searchHrefMatch(items, normalizedHref, parameters ? normalizedHref.concat(parameters.toLowerCase()) : normalizedHref);
|
|
109
146
|
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Get root menu id from the path (in the format 0-0-0 - id's separated by `-`)
|
|
149
|
+
* @param menuItemId
|
|
150
|
+
* @returns the Id of the first menu or undefined if the provided value is undefined
|
|
151
|
+
*/
|
|
152
|
+
var getRootIdFromItemId = (menuItemId) => {
|
|
153
|
+
if (!menuItemId) return;
|
|
154
|
+
return menuItemId.split("-")[0];
|
|
115
155
|
};
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Searches for an item with the specified id.
|
|
158
|
+
*
|
|
159
|
+
* @param {MenuItem[]} data - The navigation data structure.
|
|
160
|
+
* @param {string} itemId - The item id.
|
|
161
|
+
* @returns The item with matching id.
|
|
162
|
+
*/
|
|
163
|
+
var findItemById = (data, itemId) => {
|
|
164
|
+
let foundItem = null;
|
|
165
|
+
data.some((obj) => {
|
|
166
|
+
const { id: objId, data: childData } = obj;
|
|
167
|
+
if (objId === itemId) {
|
|
168
|
+
foundItem = obj;
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
if (childData && childData.length > 0) {
|
|
172
|
+
foundItem = findItemById(childData, itemId);
|
|
173
|
+
return foundItem !== null;
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
});
|
|
177
|
+
return foundItem;
|
|
131
178
|
};
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
getRootIdFromItemId,
|
|
150
|
-
searchHrefInMenuItems
|
|
179
|
+
/**
|
|
180
|
+
* Finds the first leaf item (item with children) inside the received structure.
|
|
181
|
+
*
|
|
182
|
+
* @param {MenuItem[]} data - The navigation data structure.
|
|
183
|
+
* @returns - The first leaf item inside the structure.
|
|
184
|
+
*/
|
|
185
|
+
var findFirstLeafItem = (data) => {
|
|
186
|
+
let foundItem = null;
|
|
187
|
+
data.some((obj) => {
|
|
188
|
+
if (!obj.data || obj.data.length === 0) {
|
|
189
|
+
foundItem = obj;
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
foundItem = findFirstLeafItem(obj.data);
|
|
193
|
+
return foundItem !== null;
|
|
194
|
+
});
|
|
195
|
+
return foundItem;
|
|
151
196
|
};
|
|
197
|
+
//#endregion
|
|
198
|
+
export { addPrefixToHref, createMenuItems, findFirstLeafItem, findItemById, getRootIdFromItemId, searchHrefInMenuItems };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hitachivantara/app-shell-shared",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Hitachi Vantara UI Kit Team",
|
|
@@ -15,14 +15,17 @@
|
|
|
15
15
|
},
|
|
16
16
|
"bugs": "https://github.com/pentaho/hv-uikit-react/issues",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@hitachivantara/app-shell-services": "^2.0.
|
|
18
|
+
"@hitachivantara/app-shell-services": "^2.0.4"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
|
+
"@hitachivantara/uikit-react-core": "^6.0.0",
|
|
21
22
|
"react": "^18.2.0",
|
|
22
23
|
"react-router-dom": "^6.9.0"
|
|
23
24
|
},
|
|
24
|
-
"
|
|
25
|
-
"@hitachivantara/uikit-react-core":
|
|
25
|
+
"peerDependenciesMeta": {
|
|
26
|
+
"@hitachivantara/uikit-react-core": {
|
|
27
|
+
"optional": true
|
|
28
|
+
}
|
|
26
29
|
},
|
|
27
30
|
"files": [
|
|
28
31
|
"dist"
|
|
@@ -39,7 +42,7 @@
|
|
|
39
42
|
"access": "public",
|
|
40
43
|
"directory": "package"
|
|
41
44
|
},
|
|
42
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "65c4f4394e8f8c7cccb58203e1c08c6832434638",
|
|
43
46
|
"types": "./dist/index.d.ts",
|
|
44
47
|
"module": "dist/index.js"
|
|
45
48
|
}
|