@hitachivantara/app-shell-shared 1.4.0 → 1.4.1
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/bundles/app-shell-shared.esm.js +201 -96
- package/dist/esm/AppShellCombinedProvidersContext.js +3 -4
- package/dist/esm/AppShellContext.js +3 -4
- package/dist/esm/AppShellRuntimeContext.js +3 -4
- package/dist/esm/AppShellViewContext.js +3 -4
- package/dist/esm/hooks/useAppShellCombinedProviders.js +7 -5
- package/dist/esm/hooks/useAppShellConfig.js +7 -5
- package/dist/esm/hooks/useMenuItems.js +50 -39
- package/dist/esm/i18n/index.js +3 -3
- package/dist/esm/index.js +16 -17
- package/dist/esm/utils/navigationUtils.js +139 -61
- package/package.json +2 -2
- package/dist/bundles/app-shell-shared.esm.js.map +0 -1
- package/dist/esm/AppShellCombinedProvidersContext.js.map +0 -1
- package/dist/esm/AppShellContext.js.map +0 -1
- package/dist/esm/AppShellRuntimeContext.js.map +0 -1
- package/dist/esm/AppShellViewContext.js.map +0 -1
- package/dist/esm/hooks/useAppShellCombinedProviders.js.map +0 -1
- package/dist/esm/hooks/useAppShellConfig.js.map +0 -1
- package/dist/esm/hooks/useMenuItems.js.map +0 -1
- package/dist/esm/i18n/index.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/utils/navigationUtils.js.map +0 -1
|
@@ -1,109 +1,214 @@
|
|
|
1
|
-
import { createContext
|
|
2
|
-
import { useLocation
|
|
3
|
-
const
|
|
1
|
+
import { createContext, useContext, useMemo, useState, useEffect } from "react";
|
|
2
|
+
import { useLocation } from "react-router-dom";
|
|
3
|
+
const HvAppShellContext = createContext(void 0);
|
|
4
|
+
const HvAppShellViewContext = createContext(void 0);
|
|
5
|
+
const HvAppShellRuntimeContext = createContext(void 0);
|
|
6
|
+
const HvAppShellCombinedProvidersContext = createContext(void 0);
|
|
7
|
+
const CONFIG_TRANSLATIONS_NAMESPACE = "configTranslations";
|
|
8
|
+
const CONFIG_TRANSLATIONS_NAMESPACE$1 = CONFIG_TRANSLATIONS_NAMESPACE;
|
|
9
|
+
const useAppShellConfig = () => {
|
|
10
|
+
return useContext(HvAppShellContext);
|
|
11
|
+
};
|
|
12
|
+
const useAppShellConfig$1 = useAppShellConfig;
|
|
13
|
+
const getMenuTargetHref = (menuItem) => {
|
|
4
14
|
const {
|
|
5
|
-
target
|
|
6
|
-
} =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
target
|
|
16
|
+
} = menuItem;
|
|
17
|
+
if (target) {
|
|
18
|
+
return target;
|
|
19
|
+
}
|
|
20
|
+
if (menuItem.submenus) {
|
|
21
|
+
return getMenuTargetHref(menuItem.submenus[0]);
|
|
22
|
+
}
|
|
23
|
+
return "";
|
|
24
|
+
};
|
|
25
|
+
const addPrefixToHref = (href) => {
|
|
26
|
+
return !href.startsWith(".") ? `.${href}` : href;
|
|
27
|
+
};
|
|
28
|
+
const createMenuItems = (t, menuItems, maxDepth, parentMenuItem) => {
|
|
29
|
+
if (maxDepth !== void 0 && maxDepth <= 0) {
|
|
30
|
+
return [];
|
|
19
31
|
}
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
return menuItems?.reduce((accumulator, currentValue, index) => {
|
|
33
|
+
const navItem = {
|
|
34
|
+
id: parentMenuItem ? `${parentMenuItem.id}-${index}` : `${index}`,
|
|
35
|
+
label: t(currentValue.label),
|
|
36
|
+
href: addPrefixToHref(getMenuTargetHref(currentValue)),
|
|
37
|
+
icon: currentValue.icon,
|
|
38
|
+
parent: parentMenuItem
|
|
39
|
+
};
|
|
40
|
+
if (currentValue.submenus) {
|
|
41
|
+
const updatedDepth = maxDepth !== void 0 ? maxDepth - 1 : void 0;
|
|
42
|
+
const data = createMenuItems(t, currentValue.submenus, updatedDepth, navItem);
|
|
43
|
+
if (data.length > 0) {
|
|
44
|
+
navItem.data = data;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
accumulator.push(navItem);
|
|
48
|
+
return accumulator;
|
|
49
|
+
}, []) ?? [];
|
|
50
|
+
};
|
|
51
|
+
const flatMenuItems = (items) => {
|
|
52
|
+
return items.reduce((acc, item) => {
|
|
53
|
+
if (item.data) {
|
|
54
|
+
acc.push(...flatMenuItems(item.data));
|
|
55
|
+
} else {
|
|
56
|
+
acc.push(item);
|
|
57
|
+
}
|
|
58
|
+
return acc;
|
|
59
|
+
}, []);
|
|
60
|
+
};
|
|
61
|
+
const decomposeHrefStringToArray = (normalizedHref) => {
|
|
62
|
+
const hrefArray = normalizedHref.split("/").reduce((accumulator, currentValue) => {
|
|
63
|
+
if (currentValue === "") {
|
|
64
|
+
return accumulator;
|
|
65
|
+
}
|
|
66
|
+
const prefix = accumulator.length === 0 ? "" : accumulator[0];
|
|
67
|
+
const href = currentValue === "." ? currentValue : `${prefix}/${currentValue}`;
|
|
68
|
+
accumulator.unshift(href);
|
|
69
|
+
return accumulator;
|
|
27
70
|
}, []);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
71
|
+
hrefArray.push("./");
|
|
72
|
+
return hrefArray;
|
|
73
|
+
};
|
|
74
|
+
const searchHrefMatch = (items, normalizedHref, normalizedFullHref) => {
|
|
75
|
+
let toBeSelectedId;
|
|
76
|
+
let toBeSelectedHref;
|
|
77
|
+
const reducedNormalizedHref = decomposeHrefStringToArray(normalizedHref);
|
|
78
|
+
flatMenuItems(items).some((item) => {
|
|
79
|
+
let normalizedItemHref;
|
|
80
|
+
let normalizedItemHrefParams;
|
|
81
|
+
const idx = item.href?.indexOf("?");
|
|
82
|
+
if (idx !== -1) {
|
|
83
|
+
normalizedItemHref = item.href?.slice(0, idx).toLowerCase();
|
|
84
|
+
normalizedItemHrefParams = item.href?.slice(idx, item.href.length).toLowerCase();
|
|
85
|
+
} else {
|
|
86
|
+
normalizedItemHref = item.href?.toLowerCase();
|
|
87
|
+
normalizedItemHrefParams = "";
|
|
88
|
+
}
|
|
89
|
+
if (normalizedItemHref && normalizedItemHref.length > 1 && normalizedItemHref.endsWith("/")) {
|
|
90
|
+
normalizedItemHref = normalizedItemHref.slice(0, normalizedItemHref.length - 1);
|
|
91
|
+
}
|
|
92
|
+
const normalizedFullItemHref = `${normalizedItemHref}${normalizedItemHrefParams}`;
|
|
93
|
+
if (normalizedFullItemHref === normalizedFullHref) {
|
|
94
|
+
toBeSelectedId = item.id;
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
const matchedHref = reducedNormalizedHref.find((href) => normalizedItemHref === href);
|
|
98
|
+
if (matchedHref && (!toBeSelectedHref || matchedHref.length > toBeSelectedHref?.length)) {
|
|
99
|
+
toBeSelectedId = item.id;
|
|
100
|
+
toBeSelectedHref = matchedHref;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
});
|
|
104
|
+
return toBeSelectedId;
|
|
105
|
+
};
|
|
106
|
+
const searchHrefInMenuItems = (items, href, parameters) => {
|
|
107
|
+
if (!href) {
|
|
108
|
+
return void 0;
|
|
109
|
+
}
|
|
110
|
+
const normalizedHref = href.length > 1 && href.endsWith("/") ? href.slice(0, href.length - 1).toLowerCase() : href.toLowerCase();
|
|
111
|
+
const normalizedFullHref = parameters ? normalizedHref.concat(parameters.toLowerCase()) : normalizedHref;
|
|
112
|
+
return searchHrefMatch(items, normalizedHref, normalizedFullHref);
|
|
113
|
+
};
|
|
114
|
+
const getRootIdFromItemId = (menuItemId) => {
|
|
115
|
+
if (!menuItemId) {
|
|
116
|
+
return void 0;
|
|
117
|
+
}
|
|
118
|
+
return menuItemId.split("-")[0];
|
|
119
|
+
};
|
|
120
|
+
const findItemById = (data, itemId) => {
|
|
121
|
+
let foundItem = null;
|
|
122
|
+
data.some((obj) => {
|
|
52
123
|
const {
|
|
53
|
-
id:
|
|
54
|
-
data:
|
|
55
|
-
} =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
124
|
+
id: objId,
|
|
125
|
+
data: childData
|
|
126
|
+
} = obj;
|
|
127
|
+
if (objId === itemId) {
|
|
128
|
+
foundItem = obj;
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
if (childData && childData.length > 0) {
|
|
132
|
+
foundItem = findItemById(childData, itemId);
|
|
133
|
+
return foundItem !== null;
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
});
|
|
137
|
+
return foundItem;
|
|
138
|
+
};
|
|
139
|
+
const findFirstLeafItem = (data) => {
|
|
140
|
+
let foundItem = null;
|
|
141
|
+
data.some((obj) => {
|
|
142
|
+
if (!obj.data || obj.data.length === 0) {
|
|
143
|
+
foundItem = obj;
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
foundItem = findFirstLeafItem(obj.data);
|
|
147
|
+
return foundItem !== null;
|
|
148
|
+
});
|
|
149
|
+
return foundItem;
|
|
150
|
+
};
|
|
151
|
+
const MAX_TOP_MENU_DEPTH = 2;
|
|
152
|
+
const useMenuItems = () => {
|
|
153
|
+
const {
|
|
154
|
+
pathname,
|
|
155
|
+
search,
|
|
156
|
+
state: locationState
|
|
157
|
+
} = useLocation();
|
|
158
|
+
const appShellContext = useAppShellConfig$1();
|
|
62
159
|
const {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (!r.length)
|
|
160
|
+
i18n
|
|
161
|
+
} = useContext(HvAppShellRuntimeContext) ?? {};
|
|
162
|
+
const tConfig = useMemo(() => i18n?.getFixedT(i18n.language, CONFIG_TRANSLATIONS_NAMESPACE$1) ?? // should not happen, but fallback if the i18n instance is not available
|
|
163
|
+
((l) => l), [i18n]);
|
|
164
|
+
const items = useMemo(() => {
|
|
165
|
+
const menuItemsDepth = appShellContext.navigationMode === "ONLY_TOP" ? MAX_TOP_MENU_DEPTH : void 0;
|
|
166
|
+
return createMenuItems(tConfig, appShellContext.menu, menuItemsDepth);
|
|
167
|
+
}, [appShellContext, tConfig]);
|
|
168
|
+
const [selectedMenuItemId, setSelectedMenuItemId] = useState(searchHrefInMenuItems(items, addPrefixToHref(pathname), search));
|
|
169
|
+
const [rootMenuItemId, setRootMenuItemId] = useState(getRootIdFromItemId(selectedMenuItemId));
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
if (!items.length) {
|
|
76
172
|
return;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
173
|
+
}
|
|
174
|
+
if (locationState?.selectedItemId) {
|
|
175
|
+
setRootMenuItemId(getRootIdFromItemId(locationState.selectedItemId));
|
|
176
|
+
const selectedItem = findItemById(items, locationState.selectedItemId);
|
|
177
|
+
if (selectedItem?.data?.length) {
|
|
178
|
+
const firstItemToSelect = findFirstLeafItem(selectedItem.data);
|
|
179
|
+
setSelectedMenuItemId(firstItemToSelect?.id);
|
|
180
|
+
} else {
|
|
181
|
+
setSelectedMenuItemId(selectedItem?.id);
|
|
182
|
+
}
|
|
85
183
|
return;
|
|
86
184
|
}
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
-
|
|
185
|
+
const toBeSelected = searchHrefInMenuItems(items, addPrefixToHref(pathname), search);
|
|
186
|
+
if (toBeSelected) {
|
|
187
|
+
setRootMenuItemId(getRootIdFromItemId(toBeSelected));
|
|
188
|
+
setSelectedMenuItemId(toBeSelected);
|
|
90
189
|
return;
|
|
91
190
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
191
|
+
setRootMenuItemId(void 0);
|
|
192
|
+
setSelectedMenuItemId(void 0);
|
|
193
|
+
}, [items, locationState, pathname, search]);
|
|
194
|
+
return {
|
|
195
|
+
items,
|
|
196
|
+
selectedMenuItemId,
|
|
197
|
+
rootMenuItemId
|
|
97
198
|
};
|
|
98
|
-
}
|
|
199
|
+
};
|
|
200
|
+
const useMenuItems$1 = useMenuItems;
|
|
201
|
+
const useAppShellCombinedProviders = () => {
|
|
202
|
+
return useContext(HvAppShellCombinedProvidersContext);
|
|
203
|
+
};
|
|
204
|
+
const useAppShellCombinedProviders$1 = useAppShellCombinedProviders;
|
|
99
205
|
export {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
206
|
+
CONFIG_TRANSLATIONS_NAMESPACE$1 as CONFIG_TRANSLATIONS_NAMESPACE,
|
|
207
|
+
HvAppShellCombinedProvidersContext,
|
|
208
|
+
HvAppShellContext,
|
|
209
|
+
HvAppShellRuntimeContext,
|
|
210
|
+
HvAppShellViewContext,
|
|
211
|
+
useAppShellCombinedProviders$1 as useHvAppShellCombinedProviders,
|
|
212
|
+
useAppShellConfig$1 as useHvAppShellConfig,
|
|
213
|
+
useMenuItems$1 as useHvMenuItems
|
|
108
214
|
};
|
|
109
|
-
//# sourceMappingURL=app-shell-shared.esm.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { createContext
|
|
2
|
-
const
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
const HvAppShellCombinedProvidersContext = createContext(void 0);
|
|
3
3
|
export {
|
|
4
|
-
|
|
4
|
+
HvAppShellCombinedProvidersContext
|
|
5
5
|
};
|
|
6
|
-
//# sourceMappingURL=AppShellCombinedProvidersContext.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { createContext
|
|
2
|
-
const
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
const HvAppShellContext = createContext(void 0);
|
|
3
3
|
export {
|
|
4
|
-
|
|
4
|
+
HvAppShellContext
|
|
5
5
|
};
|
|
6
|
-
//# sourceMappingURL=AppShellContext.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { createContext
|
|
2
|
-
const
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
const HvAppShellRuntimeContext = createContext(void 0);
|
|
3
3
|
export {
|
|
4
|
-
|
|
4
|
+
HvAppShellRuntimeContext
|
|
5
5
|
};
|
|
6
|
-
//# sourceMappingURL=AppShellRuntimeContext.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { createContext
|
|
2
|
-
const
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
const HvAppShellViewContext = createContext(void 0);
|
|
3
3
|
export {
|
|
4
|
-
|
|
4
|
+
HvAppShellViewContext
|
|
5
5
|
};
|
|
6
|
-
//# sourceMappingURL=AppShellViewContext.js.map
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { useContext
|
|
2
|
-
import { HvAppShellCombinedProvidersContext
|
|
3
|
-
const
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { HvAppShellCombinedProvidersContext } from "../AppShellCombinedProvidersContext.js";
|
|
3
|
+
const useAppShellCombinedProviders = () => {
|
|
4
|
+
return useContext(HvAppShellCombinedProvidersContext);
|
|
5
|
+
};
|
|
6
|
+
const useAppShellCombinedProviders$1 = useAppShellCombinedProviders;
|
|
4
7
|
export {
|
|
5
|
-
|
|
8
|
+
useAppShellCombinedProviders$1 as default
|
|
6
9
|
};
|
|
7
|
-
//# sourceMappingURL=useAppShellCombinedProviders.js.map
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { useContext
|
|
2
|
-
import { HvAppShellContext
|
|
3
|
-
const
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { HvAppShellContext } from "../AppShellContext.js";
|
|
3
|
+
const useAppShellConfig = () => {
|
|
4
|
+
return useContext(HvAppShellContext);
|
|
5
|
+
};
|
|
6
|
+
const useAppShellConfig$1 = useAppShellConfig;
|
|
4
7
|
export {
|
|
5
|
-
|
|
8
|
+
useAppShellConfig$1 as default
|
|
6
9
|
};
|
|
7
|
-
//# sourceMappingURL=useAppShellConfig.js.map
|
|
@@ -1,48 +1,59 @@
|
|
|
1
|
-
import { useContext
|
|
2
|
-
import { useLocation
|
|
3
|
-
import { createMenuItems
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { HvAppShellRuntimeContext
|
|
7
|
-
const
|
|
1
|
+
import { useContext, useMemo, useState, useEffect } from "react";
|
|
2
|
+
import { useLocation } from "react-router-dom";
|
|
3
|
+
import { createMenuItems, searchHrefInMenuItems, addPrefixToHref, getRootIdFromItemId, findItemById, findFirstLeafItem } from "../utils/navigationUtils.js";
|
|
4
|
+
import CONFIG_TRANSLATIONS_NAMESPACE from "../i18n/index.js";
|
|
5
|
+
import useAppShellConfig from "./useAppShellConfig.js";
|
|
6
|
+
import { HvAppShellRuntimeContext } from "../AppShellRuntimeContext.js";
|
|
7
|
+
const MAX_TOP_MENU_DEPTH = 2;
|
|
8
|
+
const useMenuItems = () => {
|
|
8
9
|
const {
|
|
9
|
-
pathname
|
|
10
|
-
search
|
|
11
|
-
state:
|
|
12
|
-
} =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
pathname,
|
|
11
|
+
search,
|
|
12
|
+
state: locationState
|
|
13
|
+
} = useLocation();
|
|
14
|
+
const appShellContext = useAppShellConfig();
|
|
15
|
+
const {
|
|
16
|
+
i18n
|
|
17
|
+
} = useContext(HvAppShellRuntimeContext) ?? {};
|
|
18
|
+
const tConfig = useMemo(() => i18n?.getFixedT(i18n.language, CONFIG_TRANSLATIONS_NAMESPACE) ?? // should not happen, but fallback if the i18n instance is not available
|
|
19
|
+
((l) => l), [i18n]);
|
|
20
|
+
const items = useMemo(() => {
|
|
21
|
+
const menuItemsDepth = appShellContext.navigationMode === "ONLY_TOP" ? MAX_TOP_MENU_DEPTH : void 0;
|
|
22
|
+
return createMenuItems(tConfig, appShellContext.menu, menuItemsDepth);
|
|
23
|
+
}, [appShellContext, tConfig]);
|
|
24
|
+
const [selectedMenuItemId, setSelectedMenuItemId] = useState(searchHrefInMenuItems(items, addPrefixToHref(pathname), search));
|
|
25
|
+
const [rootMenuItemId, setRootMenuItemId] = useState(getRootIdFromItemId(selectedMenuItemId));
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!items.length) {
|
|
22
28
|
return;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
}
|
|
30
|
+
if (locationState?.selectedItemId) {
|
|
31
|
+
setRootMenuItemId(getRootIdFromItemId(locationState.selectedItemId));
|
|
32
|
+
const selectedItem = findItemById(items, locationState.selectedItemId);
|
|
33
|
+
if (selectedItem?.data?.length) {
|
|
34
|
+
const firstItemToSelect = findFirstLeafItem(selectedItem.data);
|
|
35
|
+
setSelectedMenuItemId(firstItemToSelect?.id);
|
|
36
|
+
} else {
|
|
37
|
+
setSelectedMenuItemId(selectedItem?.id);
|
|
38
|
+
}
|
|
31
39
|
return;
|
|
32
40
|
}
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
|
|
41
|
+
const toBeSelected = searchHrefInMenuItems(items, addPrefixToHref(pathname), search);
|
|
42
|
+
if (toBeSelected) {
|
|
43
|
+
setRootMenuItemId(getRootIdFromItemId(toBeSelected));
|
|
44
|
+
setSelectedMenuItemId(toBeSelected);
|
|
36
45
|
return;
|
|
37
46
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
setRootMenuItemId(void 0);
|
|
48
|
+
setSelectedMenuItemId(void 0);
|
|
49
|
+
}, [items, locationState, pathname, search]);
|
|
50
|
+
return {
|
|
51
|
+
items,
|
|
52
|
+
selectedMenuItemId,
|
|
53
|
+
rootMenuItemId
|
|
43
54
|
};
|
|
44
|
-
}
|
|
55
|
+
};
|
|
56
|
+
const useMenuItems$1 = useMenuItems;
|
|
45
57
|
export {
|
|
46
|
-
|
|
58
|
+
useMenuItems$1 as default
|
|
47
59
|
};
|
|
48
|
-
//# sourceMappingURL=useMenuItems.js.map
|
package/dist/esm/i18n/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const
|
|
1
|
+
const CONFIG_TRANSLATIONS_NAMESPACE = "configTranslations";
|
|
2
|
+
const CONFIG_TRANSLATIONS_NAMESPACE$1 = CONFIG_TRANSLATIONS_NAMESPACE;
|
|
2
3
|
export {
|
|
3
|
-
|
|
4
|
+
CONFIG_TRANSLATIONS_NAMESPACE$1 as default
|
|
4
5
|
};
|
|
5
|
-
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { HvAppShellContext
|
|
2
|
-
import { HvAppShellViewContext
|
|
3
|
-
import { HvAppShellRuntimeContext
|
|
4
|
-
import { HvAppShellCombinedProvidersContext
|
|
5
|
-
import { default as
|
|
6
|
-
import { default as
|
|
7
|
-
import { default as
|
|
8
|
-
import { default as
|
|
1
|
+
import { HvAppShellContext } from "./AppShellContext.js";
|
|
2
|
+
import { HvAppShellViewContext } from "./AppShellViewContext.js";
|
|
3
|
+
import { HvAppShellRuntimeContext } from "./AppShellRuntimeContext.js";
|
|
4
|
+
import { HvAppShellCombinedProvidersContext } from "./AppShellCombinedProvidersContext.js";
|
|
5
|
+
import { default as default2 } from "./i18n/index.js";
|
|
6
|
+
import { default as default3 } from "./hooks/useAppShellConfig.js";
|
|
7
|
+
import { default as default4 } from "./hooks/useMenuItems.js";
|
|
8
|
+
import { default as default5 } from "./hooks/useAppShellCombinedProviders.js";
|
|
9
9
|
export {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
default2 as CONFIG_TRANSLATIONS_NAMESPACE,
|
|
11
|
+
HvAppShellCombinedProvidersContext,
|
|
12
|
+
HvAppShellContext,
|
|
13
|
+
HvAppShellRuntimeContext,
|
|
14
|
+
HvAppShellViewContext,
|
|
15
|
+
default5 as useHvAppShellCombinedProviders,
|
|
16
|
+
default3 as useHvAppShellConfig,
|
|
17
|
+
default4 as useHvMenuItems
|
|
18
18
|
};
|
|
19
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,68 +1,146 @@
|
|
|
1
|
-
const
|
|
1
|
+
const getMenuTargetHref = (menuItem) => {
|
|
2
2
|
const {
|
|
3
|
-
target
|
|
4
|
-
} =
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const o = {
|
|
8
|
-
id: n ? `${n.id}-${i}` : `${i}`,
|
|
9
|
-
label: r(d.label),
|
|
10
|
-
href: z(H(d)),
|
|
11
|
-
icon: d.icon,
|
|
12
|
-
parent: n
|
|
13
|
-
};
|
|
14
|
-
if (d.submenus) {
|
|
15
|
-
const l = t !== void 0 ? t - 1 : void 0, f = L(r, d.submenus, l, o);
|
|
16
|
-
f.length > 0 && (o.data = f);
|
|
3
|
+
target
|
|
4
|
+
} = menuItem;
|
|
5
|
+
if (target) {
|
|
6
|
+
return target;
|
|
17
7
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
8
|
+
if (menuItem.submenus) {
|
|
9
|
+
return getMenuTargetHref(menuItem.submenus[0]);
|
|
10
|
+
}
|
|
11
|
+
return "";
|
|
12
|
+
};
|
|
13
|
+
const addPrefixToHref = (href) => {
|
|
14
|
+
return !href.startsWith(".") ? `.${href}` : href;
|
|
15
|
+
};
|
|
16
|
+
const createMenuItems = (t, menuItems, maxDepth, parentMenuItem) => {
|
|
17
|
+
if (maxDepth !== void 0 && maxDepth <= 0) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
return menuItems?.reduce((accumulator, currentValue, index) => {
|
|
21
|
+
const navItem = {
|
|
22
|
+
id: parentMenuItem ? `${parentMenuItem.id}-${index}` : `${index}`,
|
|
23
|
+
label: t(currentValue.label),
|
|
24
|
+
href: addPrefixToHref(getMenuTargetHref(currentValue)),
|
|
25
|
+
icon: currentValue.icon,
|
|
26
|
+
parent: parentMenuItem
|
|
27
|
+
};
|
|
28
|
+
if (currentValue.submenus) {
|
|
29
|
+
const updatedDepth = maxDepth !== void 0 ? maxDepth - 1 : void 0;
|
|
30
|
+
const data = createMenuItems(t, currentValue.submenus, updatedDepth, navItem);
|
|
31
|
+
if (data.length > 0) {
|
|
32
|
+
navItem.data = data;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
accumulator.push(navItem);
|
|
36
|
+
return accumulator;
|
|
37
|
+
}, []) ?? [];
|
|
38
|
+
};
|
|
39
|
+
const flatMenuItems = (items) => {
|
|
40
|
+
return items.reduce((acc, item) => {
|
|
41
|
+
if (item.data) {
|
|
42
|
+
acc.push(...flatMenuItems(item.data));
|
|
43
|
+
} else {
|
|
44
|
+
acc.push(item);
|
|
45
|
+
}
|
|
46
|
+
return acc;
|
|
47
|
+
}, []);
|
|
48
|
+
};
|
|
49
|
+
const decomposeHrefStringToArray = (normalizedHref) => {
|
|
50
|
+
const hrefArray = normalizedHref.split("/").reduce((accumulator, currentValue) => {
|
|
51
|
+
if (currentValue === "") {
|
|
52
|
+
return accumulator;
|
|
53
|
+
}
|
|
54
|
+
const prefix = accumulator.length === 0 ? "" : accumulator[0];
|
|
55
|
+
const href = currentValue === "." ? currentValue : `${prefix}/${currentValue}`;
|
|
56
|
+
accumulator.unshift(href);
|
|
57
|
+
return accumulator;
|
|
25
58
|
}, []);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
hrefArray.push("./");
|
|
60
|
+
return hrefArray;
|
|
61
|
+
};
|
|
62
|
+
const searchHrefMatch = (items, normalizedHref, normalizedFullHref) => {
|
|
63
|
+
let toBeSelectedId;
|
|
64
|
+
let toBeSelectedHref;
|
|
65
|
+
const reducedNormalizedHref = decomposeHrefStringToArray(normalizedHref);
|
|
66
|
+
flatMenuItems(items).some((item) => {
|
|
67
|
+
let normalizedItemHref;
|
|
68
|
+
let normalizedItemHrefParams;
|
|
69
|
+
const idx = item.href?.indexOf("?");
|
|
70
|
+
if (idx !== -1) {
|
|
71
|
+
normalizedItemHref = item.href?.slice(0, idx).toLowerCase();
|
|
72
|
+
normalizedItemHrefParams = item.href?.slice(idx, item.href.length).toLowerCase();
|
|
73
|
+
} else {
|
|
74
|
+
normalizedItemHref = item.href?.toLowerCase();
|
|
75
|
+
normalizedItemHrefParams = "";
|
|
76
|
+
}
|
|
77
|
+
if (normalizedItemHref && normalizedItemHref.length > 1 && normalizedItemHref.endsWith("/")) {
|
|
78
|
+
normalizedItemHref = normalizedItemHref.slice(0, normalizedItemHref.length - 1);
|
|
79
|
+
}
|
|
80
|
+
const normalizedFullItemHref = `${normalizedItemHref}${normalizedItemHrefParams}`;
|
|
81
|
+
if (normalizedFullItemHref === normalizedFullHref) {
|
|
82
|
+
toBeSelectedId = item.id;
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
const matchedHref = reducedNormalizedHref.find((href) => normalizedItemHref === href);
|
|
86
|
+
if (matchedHref && (!toBeSelectedHref || matchedHref.length > toBeSelectedHref?.length)) {
|
|
87
|
+
toBeSelectedId = item.id;
|
|
88
|
+
toBeSelectedHref = matchedHref;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
});
|
|
92
|
+
return toBeSelectedId;
|
|
93
|
+
};
|
|
94
|
+
const searchHrefInMenuItems = (items, href, parameters) => {
|
|
95
|
+
if (!href) {
|
|
96
|
+
return void 0;
|
|
97
|
+
}
|
|
98
|
+
const normalizedHref = href.length > 1 && href.endsWith("/") ? href.slice(0, href.length - 1).toLowerCase() : href.toLowerCase();
|
|
99
|
+
const normalizedFullHref = parameters ? normalizedHref.concat(parameters.toLowerCase()) : normalizedHref;
|
|
100
|
+
return searchHrefMatch(items, normalizedHref, normalizedFullHref);
|
|
101
|
+
};
|
|
102
|
+
const getRootIdFromItemId = (menuItemId) => {
|
|
103
|
+
if (!menuItemId) {
|
|
104
|
+
return void 0;
|
|
105
|
+
}
|
|
106
|
+
return menuItemId.split("-")[0];
|
|
107
|
+
};
|
|
108
|
+
const findItemById = (data, itemId) => {
|
|
109
|
+
let foundItem = null;
|
|
110
|
+
data.some((obj) => {
|
|
50
111
|
const {
|
|
51
|
-
id:
|
|
52
|
-
data:
|
|
53
|
-
} =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
112
|
+
id: objId,
|
|
113
|
+
data: childData
|
|
114
|
+
} = obj;
|
|
115
|
+
if (objId === itemId) {
|
|
116
|
+
foundItem = obj;
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
if (childData && childData.length > 0) {
|
|
120
|
+
foundItem = findItemById(childData, itemId);
|
|
121
|
+
return foundItem !== null;
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
});
|
|
125
|
+
return foundItem;
|
|
126
|
+
};
|
|
127
|
+
const findFirstLeafItem = (data) => {
|
|
128
|
+
let foundItem = null;
|
|
129
|
+
data.some((obj) => {
|
|
130
|
+
if (!obj.data || obj.data.length === 0) {
|
|
131
|
+
foundItem = obj;
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
foundItem = findFirstLeafItem(obj.data);
|
|
135
|
+
return foundItem !== null;
|
|
136
|
+
});
|
|
137
|
+
return foundItem;
|
|
59
138
|
};
|
|
60
139
|
export {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
140
|
+
addPrefixToHref,
|
|
141
|
+
createMenuItems,
|
|
142
|
+
findFirstLeafItem,
|
|
143
|
+
findItemById,
|
|
144
|
+
getRootIdFromItemId,
|
|
145
|
+
searchHrefInMenuItems
|
|
67
146
|
};
|
|
68
|
-
//# sourceMappingURL=navigationUtils.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hitachivantara/app-shell-shared",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "App Shell Shared",
|
|
5
5
|
"author": "Hitachi Vantara - Boba Fett Team",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@hitachivantara/uikit-react-core": "^5.66.7"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "bbee984ca345cfaa5d6a3829f5ec65cc6373b37b"
|
|
57
57
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-shell-shared.esm.js","sources":["../../src/AppShellContext.tsx","../../src/AppShellViewContext.tsx","../../src/AppShellRuntimeContext.tsx","../../src/AppShellCombinedProvidersContext.tsx","../../src/i18n/index.ts","../../src/hooks/useAppShellConfig.tsx","../../src/utils/navigationUtils.tsx","../../src/hooks/useMenuItems.tsx","../../src/hooks/useAppShellCombinedProviders.tsx"],"sourcesContent":["import { createContext } from \"react\";\n\nimport { HvAppShellConfig } from \"./types\";\n\nexport type HvAppShellContextValue = HvAppShellConfig;\nexport const HvAppShellContext = createContext<\n HvAppShellContextValue | undefined\n>(undefined);\n","import { createContext } from \"react\";\n\nexport interface HvAppShellViewContextValue {\n id: string;\n}\n\nexport const HvAppShellViewContext = createContext<\n HvAppShellViewContextValue | undefined\n>(undefined);\n","import { createContext } from \"react\";\n\nimport type { i18n } from \"i18next\";\n\nexport interface HvAppShellRuntimeContextValue {\n i18n: i18n;\n}\n\nexport const HvAppShellRuntimeContext = createContext<\n HvAppShellRuntimeContextValue | undefined\n>(undefined);\n","import { createContext } from \"react\";\n\nexport interface HvAppShellCombinedProvidersContextValue {\n providers?: React.ComponentType<{\n children: React.ReactNode;\n }>[];\n}\n\nexport const HvAppShellCombinedProvidersContext = createContext<\n HvAppShellCombinedProvidersContextValue | undefined\n>(undefined);\n","const CONFIG_TRANSLATIONS_NAMESPACE = \"configTranslations\";\nexport default CONFIG_TRANSLATIONS_NAMESPACE;\n","import { useContext } from \"react\";\n\nimport { HvAppShellContext, HvAppShellContextValue } from \"../AppShellContext\";\n\nconst useAppShellConfig = (): HvAppShellContextValue => {\n return useContext(HvAppShellContext) as HvAppShellContextValue;\n};\n\nexport default useAppShellConfig;\n","import { HvAppShellMenuConfig, MenuItem } from \"../types\";\n\n/**\n * Compute the target href for menu item.\n *\n * @param menuItem The root target href.\n *\n * @returns The menu item target href. If empty, returns the first child that has it defined or empty string if none.\n */\nconst getMenuTargetHref = (menuItem: HvAppShellMenuConfig): string => {\n const { target } = menuItem;\n if (target) {\n return target;\n }\n\n if (menuItem.submenus) {\n return getMenuTargetHref(menuItem.submenus[0]);\n }\n\n return \"\";\n};\n\n/**\n * Adds a dot to the href to indicate that it is a relative path.\n */\nconst addPrefixToHref = (href: string): string => {\n return !href.startsWith(\".\") ? `.${href}` : href;\n};\n\n/**\n * Creates a navigation data structure ({@link MenuItem}) from the provided menu configuration ({@link HvAppShellMenuConfig}).\n *\n * @param t\n * @param menuItems The set of menu items from configuration.\n * @param maxDepth The maximum depth up until the recursiveness should occur for the creation of the menu items.\n * @param parentMenuItem The parent menu item of the set of menu items.\n *\n * @returns An array of {@link MenuItem}.\n */\nconst createMenuItems = (\n t: (key: string) => string,\n menuItems?: HvAppShellMenuConfig[],\n maxDepth?: number,\n parentMenuItem?: MenuItem\n): MenuItem[] => {\n if (maxDepth !== undefined && maxDepth <= 0) {\n return [];\n }\n\n return (\n menuItems?.reduce<MenuItem[]>((accumulator, currentValue, index) => {\n const navItem: MenuItem = {\n id: parentMenuItem ? `${parentMenuItem.id}-${index}` : `${index}`,\n label: t(currentValue.label),\n href: addPrefixToHref(getMenuTargetHref(currentValue)),\n icon: currentValue.icon,\n parent: parentMenuItem\n };\n\n if (currentValue.submenus) {\n const updatedDepth = maxDepth !== undefined ? maxDepth - 1 : undefined;\n const data = createMenuItems(\n t,\n currentValue.submenus,\n updatedDepth,\n navItem\n );\n if (data.length > 0) {\n navItem.data = data;\n }\n }\n\n accumulator.push(navItem);\n return accumulator;\n }, []) ?? []\n );\n};\n\n/**\n * Removes the items that do not have path and replaces it by its children, recursively.\n *\n * @param items The list of {@link MenuItem}.\n *\n * @returns A flat array of {@link MenuItem}.\n */\nconst flatMenuItems = (items: MenuItem[]) => {\n return items.reduce<MenuItem[]>((acc, item) => {\n if (item.data) {\n acc.push(...flatMenuItems(item.data));\n } else {\n acc.push(item);\n }\n\n return acc;\n }, []);\n};\n\n/**\n * Helper function that uses a cumulative reduction to derive an array of cumulative hrefs based on the components\n * of the input string.\n * @example\n * // returns ['/', '/app', '/app/details', '/app/details/1']\n * // normalizedHref: \"/app/details/1\"\n *\n * @param normalizedHref The href string to be reduced.\n *\n * @returns the array of cumulative hrefs.\n */\nconst decomposeHrefStringToArray = (normalizedHref: string): string[] => {\n const hrefArray = normalizedHref\n .split(\"/\")\n .reduce<string[]>((accumulator, currentValue) => {\n if (currentValue === \"\") {\n return accumulator;\n }\n\n const prefix = accumulator.length === 0 ? \"\" : accumulator[0];\n const href =\n currentValue === \".\" ? currentValue : `${prefix}/${currentValue}`;\n accumulator.unshift(href);\n return accumulator;\n }, []);\n\n hrefArray.push(\"./\");\n\n return hrefArray;\n};\n\n/**\n * Algorithm implementation of the searchHrefInMenuItems function.\n *\n * @returns An object containing an item id or empty, if no match is found, and a flag to indicate if a\n * full href match was found. If the id is filled but the flag is 'false', then only partial match was found.\n */\nconst searchHrefMatch = (\n items: MenuItem[],\n normalizedHref: string,\n normalizedFullHref: string\n): string | undefined => {\n let toBeSelectedId: string | undefined;\n let toBeSelectedHref: string | undefined;\n\n const reducedNormalizedHref = decomposeHrefStringToArray(normalizedHref);\n\n flatMenuItems(items).some(item => {\n let normalizedItemHref: string | undefined;\n let normalizedItemHrefParams: string | undefined;\n\n const idx = item.href?.indexOf(\"?\");\n if (idx !== -1) {\n normalizedItemHref = item.href?.slice(0, idx).toLowerCase();\n normalizedItemHrefParams = item.href\n ?.slice(idx, item.href.length)\n .toLowerCase();\n } else {\n normalizedItemHref = item.href?.toLowerCase();\n normalizedItemHrefParams = \"\";\n }\n\n if (\n normalizedItemHref &&\n normalizedItemHref.length > 1 &&\n normalizedItemHref.endsWith(\"/\")\n ) {\n normalizedItemHref = normalizedItemHref.slice(\n 0,\n normalizedItemHref.length - 1\n );\n }\n\n const normalizedFullItemHref = `${normalizedItemHref}${normalizedItemHrefParams}`;\n\n // if the normalized full href is met, then search is complete\n if (normalizedFullItemHref === normalizedFullHref) {\n toBeSelectedId = item.id;\n return true;\n }\n\n // since it is not a full href match, we want to keep searching for a full href match,\n // while storing only the first/longer partial match found\n const matchedHref = reducedNormalizedHref.find(\n (href: string) => normalizedItemHref === href\n );\n if (\n matchedHref &&\n (!toBeSelectedHref || matchedHref.length > toBeSelectedHref?.length)\n ) {\n toBeSelectedId = item.id;\n toBeSelectedHref = matchedHref;\n }\n\n return false;\n });\n\n return toBeSelectedId;\n};\n\n/**\n * Searches for the href and parameters on all the menu items and its children until an exact match is found. If no\n * exact match is found but partial is, then the parent id for the first partial match found is returned.\n * @example\n * // returns '2'\n * // href: '/home', parameters: '?x=y', items: [{id:'1', href:'/home?z=v'},{id:'2', href:'/home'}\n *\n * For consistency purposes and based on the Router behavior, if either the href or the item href\n * (stripped of its query params) ends with a forward slash, then the comparison will ignore it\n * @example\n * // returns '1'\n * // href: '/home/', parameters: <empty>, items: [{id:'1', href:'/home'}]\n *\n * @param items The list of menu items to be searched.\n * @param href The url href after the domain up to the query parameters.\n * @param [parameters] The url query string after pathname.\n *\n * @returns The id of a parent menu item or an empty string.\n */\nconst searchHrefInMenuItems = (\n items: MenuItem[],\n href: string,\n parameters?: string\n): string | undefined => {\n if (!href) {\n return undefined;\n }\n\n const normalizedHref =\n href.length > 1 && href.endsWith(\"/\")\n ? href.slice(0, href.length - 1).toLowerCase()\n : href.toLowerCase();\n\n const normalizedFullHref = parameters\n ? normalizedHref.concat(parameters.toLowerCase())\n : normalizedHref;\n\n return searchHrefMatch(items, normalizedHref, normalizedFullHref);\n};\n\n/**\n * Get root menu id from the path (in the format 0-0-0 - id's separated by `-`)\n * @param menuItemId\n * @returns the Id of the first menu or undefined if the provided value is undefined\n */\nconst getRootIdFromItemId = (\n menuItemId: string | undefined\n): string | undefined => {\n if (!menuItemId) {\n return undefined;\n }\n return menuItemId.split(\"-\")[0];\n};\n\n/**\n * Searches for an item with the specified id.\n *\n * @param {MenuItem[]} data - The navigation data structure.\n * @param {string} itemId - The item id.\n * @returns The item with matching id.\n */\nconst findItemById = (data: MenuItem[], itemId: string): MenuItem | null => {\n let foundItem: MenuItem | null = null;\n data.some(obj => {\n const { id: objId, data: childData } = obj;\n if (objId === itemId) {\n foundItem = obj;\n return true;\n }\n if (childData && childData.length > 0) {\n foundItem = findItemById(childData, itemId);\n return foundItem !== null;\n }\n return false;\n });\n return foundItem;\n};\n\n/**\n * Finds the first leaf item (item with children) inside the received structure.\n *\n * @param {MenuItem[]} data - The navigation data structure.\n * @returns - The first leaf item inside the structure.\n */\nconst findFirstLeafItem = (data: MenuItem[]): MenuItem | null => {\n let foundItem: MenuItem | null = null;\n data.some(obj => {\n if (!obj.data || obj.data.length === 0) {\n foundItem = obj;\n return true;\n }\n foundItem = findFirstLeafItem(obj.data);\n return foundItem !== null;\n });\n return foundItem;\n};\n\nexport {\n createMenuItems,\n searchHrefInMenuItems,\n getRootIdFromItemId,\n addPrefixToHref,\n findItemById,\n findFirstLeafItem\n};\n","import { useContext, useEffect, useMemo, useState } from \"react\";\nimport { useLocation } from \"react-router-dom\";\n\nimport { MenuItemsContext } from \"../types\";\nimport {\n addPrefixToHref,\n createMenuItems,\n findFirstLeafItem,\n findItemById,\n getRootIdFromItemId,\n searchHrefInMenuItems\n} from \"../utils/navigationUtils\";\n\nimport CONFIG_TRANSLATIONS_NAMESPACE from \"../i18n\";\nimport useAppShellConfig from \"./useAppShellConfig\";\nimport { HvAppShellRuntimeContext } from \"../AppShellRuntimeContext\";\n\nconst MAX_TOP_MENU_DEPTH = 2;\n\nconst useMenuItems = (): MenuItemsContext => {\n const { pathname, search, state: locationState } = useLocation();\n const appShellContext = useAppShellConfig();\n\n // use the i18n instance from the app shell runtime context to ensure we're using\n // the app shell instance of i18n and not the one from the embedded app\n const { i18n } = useContext(HvAppShellRuntimeContext) ?? {};\n const tConfig = useMemo(\n () =>\n i18n?.getFixedT(i18n.language, CONFIG_TRANSLATIONS_NAMESPACE) ??\n // should not happen, but fallback if the i18n instance is not available\n ((l: string) => l),\n [i18n]\n );\n\n const items = useMemo(() => {\n const menuItemsDepth =\n appShellContext.navigationMode === \"ONLY_TOP\"\n ? MAX_TOP_MENU_DEPTH\n : undefined;\n\n return createMenuItems(tConfig, appShellContext.menu, menuItemsDepth);\n }, [appShellContext, tConfig]);\n\n const [selectedMenuItemId, setSelectedMenuItemId] = useState<\n string | undefined\n >(searchHrefInMenuItems(items, addPrefixToHref(pathname), search));\n\n const [rootMenuItemId, setRootMenuItemId] = useState<string | undefined>(\n getRootIdFromItemId(selectedMenuItemId)\n );\n\n useEffect(() => {\n // no menu items, nothing to select\n if (!items.length) {\n return;\n }\n // state property is used when we already know which menu is to be selected\n if (locationState?.selectedItemId) {\n setRootMenuItemId(getRootIdFromItemId(locationState.selectedItemId));\n // If the selected item has children we want to select the first child instead\n const selectedItem = findItemById(items, locationState.selectedItemId);\n if (selectedItem?.data?.length) {\n const firstItemToSelect = findFirstLeafItem(selectedItem.data);\n setSelectedMenuItemId(firstItemToSelect?.id);\n } else {\n setSelectedMenuItemId(selectedItem?.id);\n }\n return;\n }\n const toBeSelected = searchHrefInMenuItems(\n items,\n addPrefixToHref(pathname),\n search\n );\n if (toBeSelected) {\n setRootMenuItemId(getRootIdFromItemId(toBeSelected));\n setSelectedMenuItemId(toBeSelected);\n return;\n }\n // if none of the previous scenarios, then nothing is marked as selected\n setRootMenuItemId(undefined);\n setSelectedMenuItemId(undefined);\n }, [items, locationState, pathname, search]);\n return {\n items,\n selectedMenuItemId,\n rootMenuItemId\n };\n};\nexport default useMenuItems;\n","import { useContext } from \"react\";\n\nimport {\n HvAppShellCombinedProvidersContext,\n HvAppShellCombinedProvidersContextValue\n} from \"../AppShellCombinedProvidersContext\";\n\nconst useAppShellCombinedProviders =\n (): HvAppShellCombinedProvidersContextValue => {\n return useContext(\n HvAppShellCombinedProvidersContext\n ) as HvAppShellCombinedProvidersContextValue;\n };\n\nexport default useAppShellCombinedProviders;\n"],"names":["HvAppShellContext","createContext","undefined","HvAppShellViewContext","HvAppShellRuntimeContext","HvAppShellCombinedProvidersContext","CONFIG_TRANSLATIONS_NAMESPACE","CONFIG_TRANSLATIONS_NAMESPACE$1","useAppShellConfig","useContext","useAppShellConfig$1","getMenuTargetHref","menuItem","target","submenus","addPrefixToHref","href","startsWith","createMenuItems","t","menuItems","maxDepth","parentMenuItem","reduce","accumulator","currentValue","index","navItem","id","label","icon","parent","updatedDepth","data","length","push","flatMenuItems","items","acc","item","decomposeHrefStringToArray","normalizedHref","hrefArray","split","prefix","unshift","searchHrefMatch","normalizedFullHref","toBeSelectedId","toBeSelectedHref","reducedNormalizedHref","some","normalizedItemHref","normalizedItemHrefParams","idx","indexOf","slice","toLowerCase","endsWith","matchedHref","find","searchHrefInMenuItems","parameters","concat","getRootIdFromItemId","menuItemId","findItemById","itemId","foundItem","obj","objId","childData","findFirstLeafItem","MAX_TOP_MENU_DEPTH","useMenuItems","pathname","search","state","locationState","useLocation","appShellContext","i18n","tConfig","useMemo","getFixedT","language","l","menuItemsDepth","navigationMode","menu","selectedMenuItemId","setSelectedMenuItemId","useState","rootMenuItemId","setRootMenuItemId","useEffect","selectedItemId","selectedItem","firstItemToSelect","toBeSelected","useMenuItems$1","useAppShellCombinedProviders","useAppShellCombinedProviders$1"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AppShellCombinedProvidersContext.js","sources":["../../src/AppShellCombinedProvidersContext.tsx"],"sourcesContent":["import { createContext } from \"react\";\n\nexport interface HvAppShellCombinedProvidersContextValue {\n providers?: React.ComponentType<{\n children: React.ReactNode;\n }>[];\n}\n\nexport const HvAppShellCombinedProvidersContext = createContext<\n HvAppShellCombinedProvidersContextValue | undefined\n>(undefined);\n"],"names":["HvAppShellCombinedProvidersContext","createContext","undefined"],"mappings":";AAQaA,MAAAA,IAAqCC,EAEhDC,MAAS;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AppShellContext.js","sources":["../../src/AppShellContext.tsx"],"sourcesContent":["import { createContext } from \"react\";\n\nimport { HvAppShellConfig } from \"./types\";\n\nexport type HvAppShellContextValue = HvAppShellConfig;\nexport const HvAppShellContext = createContext<\n HvAppShellContextValue | undefined\n>(undefined);\n"],"names":["HvAppShellContext","createContext","undefined"],"mappings":";AAKaA,MAAAA,IAAoBC,EAE/BC,MAAS;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AppShellRuntimeContext.js","sources":["../../src/AppShellRuntimeContext.tsx"],"sourcesContent":["import { createContext } from \"react\";\n\nimport type { i18n } from \"i18next\";\n\nexport interface HvAppShellRuntimeContextValue {\n i18n: i18n;\n}\n\nexport const HvAppShellRuntimeContext = createContext<\n HvAppShellRuntimeContextValue | undefined\n>(undefined);\n"],"names":["HvAppShellRuntimeContext","createContext","undefined"],"mappings":";AAQaA,MAAAA,IAA2BC,EAEtCC,MAAS;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AppShellViewContext.js","sources":["../../src/AppShellViewContext.tsx"],"sourcesContent":["import { createContext } from \"react\";\n\nexport interface HvAppShellViewContextValue {\n id: string;\n}\n\nexport const HvAppShellViewContext = createContext<\n HvAppShellViewContextValue | undefined\n>(undefined);\n"],"names":["HvAppShellViewContext","createContext","undefined"],"mappings":";AAMaA,MAAAA,IAAwBC,EAEnCC,MAAS;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useAppShellCombinedProviders.js","sources":["../../../src/hooks/useAppShellCombinedProviders.tsx"],"sourcesContent":["import { useContext } from \"react\";\n\nimport {\n HvAppShellCombinedProvidersContext,\n HvAppShellCombinedProvidersContextValue\n} from \"../AppShellCombinedProvidersContext\";\n\nconst useAppShellCombinedProviders =\n (): HvAppShellCombinedProvidersContextValue => {\n return useContext(\n HvAppShellCombinedProvidersContext\n ) as HvAppShellCombinedProvidersContextValue;\n };\n\nexport default useAppShellCombinedProviders;\n"],"names":["useAppShellCombinedProviders","useContext","HvAppShellCombinedProvidersContext","useAppShellCombinedProviders$1"],"mappings":";;AAOA,MAAMA,IACJA,MACSC,EACLC,CACF,GAGJC,IAAeH;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useAppShellConfig.js","sources":["../../../src/hooks/useAppShellConfig.tsx"],"sourcesContent":["import { useContext } from \"react\";\n\nimport { HvAppShellContext, HvAppShellContextValue } from \"../AppShellContext\";\n\nconst useAppShellConfig = (): HvAppShellContextValue => {\n return useContext(HvAppShellContext) as HvAppShellContextValue;\n};\n\nexport default useAppShellConfig;\n"],"names":["useAppShellConfig","useContext","HvAppShellContext","useAppShellConfig$1"],"mappings":";;AAIA,MAAMA,IAAoBA,MACjBC,EAAWC,CAAiB,GAGrCC,IAAeH;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useMenuItems.js","sources":["../../../src/hooks/useMenuItems.tsx"],"sourcesContent":["import { useContext, useEffect, useMemo, useState } from \"react\";\nimport { useLocation } from \"react-router-dom\";\n\nimport { MenuItemsContext } from \"../types\";\nimport {\n addPrefixToHref,\n createMenuItems,\n findFirstLeafItem,\n findItemById,\n getRootIdFromItemId,\n searchHrefInMenuItems\n} from \"../utils/navigationUtils\";\n\nimport CONFIG_TRANSLATIONS_NAMESPACE from \"../i18n\";\nimport useAppShellConfig from \"./useAppShellConfig\";\nimport { HvAppShellRuntimeContext } from \"../AppShellRuntimeContext\";\n\nconst MAX_TOP_MENU_DEPTH = 2;\n\nconst useMenuItems = (): MenuItemsContext => {\n const { pathname, search, state: locationState } = useLocation();\n const appShellContext = useAppShellConfig();\n\n // use the i18n instance from the app shell runtime context to ensure we're using\n // the app shell instance of i18n and not the one from the embedded app\n const { i18n } = useContext(HvAppShellRuntimeContext) ?? {};\n const tConfig = useMemo(\n () =>\n i18n?.getFixedT(i18n.language, CONFIG_TRANSLATIONS_NAMESPACE) ??\n // should not happen, but fallback if the i18n instance is not available\n ((l: string) => l),\n [i18n]\n );\n\n const items = useMemo(() => {\n const menuItemsDepth =\n appShellContext.navigationMode === \"ONLY_TOP\"\n ? MAX_TOP_MENU_DEPTH\n : undefined;\n\n return createMenuItems(tConfig, appShellContext.menu, menuItemsDepth);\n }, [appShellContext, tConfig]);\n\n const [selectedMenuItemId, setSelectedMenuItemId] = useState<\n string | undefined\n >(searchHrefInMenuItems(items, addPrefixToHref(pathname), search));\n\n const [rootMenuItemId, setRootMenuItemId] = useState<string | undefined>(\n getRootIdFromItemId(selectedMenuItemId)\n );\n\n useEffect(() => {\n // no menu items, nothing to select\n if (!items.length) {\n return;\n }\n // state property is used when we already know which menu is to be selected\n if (locationState?.selectedItemId) {\n setRootMenuItemId(getRootIdFromItemId(locationState.selectedItemId));\n // If the selected item has children we want to select the first child instead\n const selectedItem = findItemById(items, locationState.selectedItemId);\n if (selectedItem?.data?.length) {\n const firstItemToSelect = findFirstLeafItem(selectedItem.data);\n setSelectedMenuItemId(firstItemToSelect?.id);\n } else {\n setSelectedMenuItemId(selectedItem?.id);\n }\n return;\n }\n const toBeSelected = searchHrefInMenuItems(\n items,\n addPrefixToHref(pathname),\n search\n );\n if (toBeSelected) {\n setRootMenuItemId(getRootIdFromItemId(toBeSelected));\n setSelectedMenuItemId(toBeSelected);\n return;\n }\n // if none of the previous scenarios, then nothing is marked as selected\n setRootMenuItemId(undefined);\n setSelectedMenuItemId(undefined);\n }, [items, locationState, pathname, search]);\n return {\n items,\n selectedMenuItemId,\n rootMenuItemId\n };\n};\nexport default useMenuItems;\n"],"names":["MAX_TOP_MENU_DEPTH","useMenuItems","pathname","search","state","locationState","useLocation","appShellContext","useAppShellConfig","i18n","useContext","HvAppShellRuntimeContext","tConfig","useMemo","getFixedT","language","CONFIG_TRANSLATIONS_NAMESPACE","l","items","menuItemsDepth","navigationMode","undefined","createMenuItems","menu","selectedMenuItemId","setSelectedMenuItemId","useState","searchHrefInMenuItems","addPrefixToHref","rootMenuItemId","setRootMenuItemId","getRootIdFromItemId","useEffect","length","selectedItemId","selectedItem","findItemById","data","firstItemToSelect","findFirstLeafItem","id","toBeSelected","useMenuItems$1"],"mappings":";;;;;;AAiBA,MAAMA,IAAqB,GAErBC,IAAeA,MAAwB;AACrC,QAAA;AAAA,IAAEC,UAAAA;AAAAA,IAAUC,QAAAA;AAAAA,IAAQC,OAAOC;AAAAA,MAAkBC,EAAY,GACzDC,IAAkBC,KAIlB;AAAA,IAAEC,MAAAA;AAAAA,EAAAA,IAASC,EAAWC,CAAwB,KAAK,IACnDC,IAAUC,EACd,OACEJ,KAAAA,gBAAAA,EAAMK,UAAUL,EAAKM,UAAUC;AAAAA,GAE9B,CAACC,MAAcA,IAClB,CAACR,CAAI,CACP,GAEMS,IAAQL,EAAQ,MAAM;AAC1B,UAAMM,IACJZ,EAAgBa,mBAAmB,aAC/BpB,IACAqB;AAEN,WAAOC,EAAgBV,GAASL,EAAgBgB,MAAMJ,CAAc;AAAA,EAAA,GACnE,CAACZ,GAAiBK,CAAO,CAAC,GAEvB,CAACY,GAAoBC,CAAqB,IAAIC,EAElDC,EAAsBT,GAAOU,EAAgB1B,CAAQ,GAAGC,CAAM,CAAC,GAE3D,CAAC0B,GAAgBC,CAAiB,IAAIJ,EAC1CK,EAAoBP,CAAkB,CACxC;AAEAQ,SAAAA,EAAU,MAAM;;AAEV,QAAA,CAACd,EAAMe;AACT;AAGF,QAAI5B,KAAAA,QAAAA,EAAe6B,gBAAgB;AACfH,MAAAA,EAAAA,EAAoB1B,EAAc6B,cAAc,CAAC;AAEnE,YAAMC,IAAeC,EAAalB,GAAOb,EAAc6B,cAAc;AACjEC,WAAAA,IAAAA,KAAAA,gBAAAA,EAAcE,SAAdF,QAAAA,EAAoBF,QAAQ;AACxBK,cAAAA,IAAoBC,EAAkBJ,EAAaE,IAAI;AAC7DZ,QAAAA,EAAsBa,KAAAA,gBAAAA,EAAmBE,EAAE;AAAA,MAAA;AAE3Cf,QAAAA,EAAsBU,KAAAA,gBAAAA,EAAcK,EAAE;AAExC;AAAA,IACF;AACA,UAAMC,IAAed,EACnBT,GACAU,EAAgB1B,CAAQ,GACxBC,CACF;AACA,QAAIsC,GAAc;AACEV,MAAAA,EAAAA,EAAoBU,CAAY,CAAC,GACnDhB,EAAsBgB,CAAY;AAClC;AAAA,IACF;AAEAX,IAAAA,EAAkBT,MAAS,GAC3BI,EAAsBJ,MAAS;AAAA,KAC9B,CAACH,GAAOb,GAAeH,GAAUC,CAAM,CAAC,GACpC;AAAA,IACLe,OAAAA;AAAAA,IACAM,oBAAAA;AAAAA,IACAK,gBAAAA;AAAAA,EAAAA;AAEJ,GACAa,IAAezC;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/i18n/index.ts"],"sourcesContent":["const CONFIG_TRANSLATIONS_NAMESPACE = \"configTranslations\";\nexport default CONFIG_TRANSLATIONS_NAMESPACE;\n"],"names":["CONFIG_TRANSLATIONS_NAMESPACE","CONFIG_TRANSLATIONS_NAMESPACE$1"],"mappings":"AAAA,MAAMA,IAAgC,sBACtCC,IAAeD;"}
|
package/dist/esm/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"navigationUtils.js","sources":["../../../src/utils/navigationUtils.tsx"],"sourcesContent":["import { HvAppShellMenuConfig, MenuItem } from \"../types\";\n\n/**\n * Compute the target href for menu item.\n *\n * @param menuItem The root target href.\n *\n * @returns The menu item target href. If empty, returns the first child that has it defined or empty string if none.\n */\nconst getMenuTargetHref = (menuItem: HvAppShellMenuConfig): string => {\n const { target } = menuItem;\n if (target) {\n return target;\n }\n\n if (menuItem.submenus) {\n return getMenuTargetHref(menuItem.submenus[0]);\n }\n\n return \"\";\n};\n\n/**\n * Adds a dot to the href to indicate that it is a relative path.\n */\nconst addPrefixToHref = (href: string): string => {\n return !href.startsWith(\".\") ? `.${href}` : href;\n};\n\n/**\n * Creates a navigation data structure ({@link MenuItem}) from the provided menu configuration ({@link HvAppShellMenuConfig}).\n *\n * @param t\n * @param menuItems The set of menu items from configuration.\n * @param maxDepth The maximum depth up until the recursiveness should occur for the creation of the menu items.\n * @param parentMenuItem The parent menu item of the set of menu items.\n *\n * @returns An array of {@link MenuItem}.\n */\nconst createMenuItems = (\n t: (key: string) => string,\n menuItems?: HvAppShellMenuConfig[],\n maxDepth?: number,\n parentMenuItem?: MenuItem\n): MenuItem[] => {\n if (maxDepth !== undefined && maxDepth <= 0) {\n return [];\n }\n\n return (\n menuItems?.reduce<MenuItem[]>((accumulator, currentValue, index) => {\n const navItem: MenuItem = {\n id: parentMenuItem ? `${parentMenuItem.id}-${index}` : `${index}`,\n label: t(currentValue.label),\n href: addPrefixToHref(getMenuTargetHref(currentValue)),\n icon: currentValue.icon,\n parent: parentMenuItem\n };\n\n if (currentValue.submenus) {\n const updatedDepth = maxDepth !== undefined ? maxDepth - 1 : undefined;\n const data = createMenuItems(\n t,\n currentValue.submenus,\n updatedDepth,\n navItem\n );\n if (data.length > 0) {\n navItem.data = data;\n }\n }\n\n accumulator.push(navItem);\n return accumulator;\n }, []) ?? []\n );\n};\n\n/**\n * Removes the items that do not have path and replaces it by its children, recursively.\n *\n * @param items The list of {@link MenuItem}.\n *\n * @returns A flat array of {@link MenuItem}.\n */\nconst flatMenuItems = (items: MenuItem[]) => {\n return items.reduce<MenuItem[]>((acc, item) => {\n if (item.data) {\n acc.push(...flatMenuItems(item.data));\n } else {\n acc.push(item);\n }\n\n return acc;\n }, []);\n};\n\n/**\n * Helper function that uses a cumulative reduction to derive an array of cumulative hrefs based on the components\n * of the input string.\n * @example\n * // returns ['/', '/app', '/app/details', '/app/details/1']\n * // normalizedHref: \"/app/details/1\"\n *\n * @param normalizedHref The href string to be reduced.\n *\n * @returns the array of cumulative hrefs.\n */\nconst decomposeHrefStringToArray = (normalizedHref: string): string[] => {\n const hrefArray = normalizedHref\n .split(\"/\")\n .reduce<string[]>((accumulator, currentValue) => {\n if (currentValue === \"\") {\n return accumulator;\n }\n\n const prefix = accumulator.length === 0 ? \"\" : accumulator[0];\n const href =\n currentValue === \".\" ? currentValue : `${prefix}/${currentValue}`;\n accumulator.unshift(href);\n return accumulator;\n }, []);\n\n hrefArray.push(\"./\");\n\n return hrefArray;\n};\n\n/**\n * Algorithm implementation of the searchHrefInMenuItems function.\n *\n * @returns An object containing an item id or empty, if no match is found, and a flag to indicate if a\n * full href match was found. If the id is filled but the flag is 'false', then only partial match was found.\n */\nconst searchHrefMatch = (\n items: MenuItem[],\n normalizedHref: string,\n normalizedFullHref: string\n): string | undefined => {\n let toBeSelectedId: string | undefined;\n let toBeSelectedHref: string | undefined;\n\n const reducedNormalizedHref = decomposeHrefStringToArray(normalizedHref);\n\n flatMenuItems(items).some(item => {\n let normalizedItemHref: string | undefined;\n let normalizedItemHrefParams: string | undefined;\n\n const idx = item.href?.indexOf(\"?\");\n if (idx !== -1) {\n normalizedItemHref = item.href?.slice(0, idx).toLowerCase();\n normalizedItemHrefParams = item.href\n ?.slice(idx, item.href.length)\n .toLowerCase();\n } else {\n normalizedItemHref = item.href?.toLowerCase();\n normalizedItemHrefParams = \"\";\n }\n\n if (\n normalizedItemHref &&\n normalizedItemHref.length > 1 &&\n normalizedItemHref.endsWith(\"/\")\n ) {\n normalizedItemHref = normalizedItemHref.slice(\n 0,\n normalizedItemHref.length - 1\n );\n }\n\n const normalizedFullItemHref = `${normalizedItemHref}${normalizedItemHrefParams}`;\n\n // if the normalized full href is met, then search is complete\n if (normalizedFullItemHref === normalizedFullHref) {\n toBeSelectedId = item.id;\n return true;\n }\n\n // since it is not a full href match, we want to keep searching for a full href match,\n // while storing only the first/longer partial match found\n const matchedHref = reducedNormalizedHref.find(\n (href: string) => normalizedItemHref === href\n );\n if (\n matchedHref &&\n (!toBeSelectedHref || matchedHref.length > toBeSelectedHref?.length)\n ) {\n toBeSelectedId = item.id;\n toBeSelectedHref = matchedHref;\n }\n\n return false;\n });\n\n return toBeSelectedId;\n};\n\n/**\n * Searches for the href and parameters on all the menu items and its children until an exact match is found. If no\n * exact match is found but partial is, then the parent id for the first partial match found is returned.\n * @example\n * // returns '2'\n * // href: '/home', parameters: '?x=y', items: [{id:'1', href:'/home?z=v'},{id:'2', href:'/home'}\n *\n * For consistency purposes and based on the Router behavior, if either the href or the item href\n * (stripped of its query params) ends with a forward slash, then the comparison will ignore it\n * @example\n * // returns '1'\n * // href: '/home/', parameters: <empty>, items: [{id:'1', href:'/home'}]\n *\n * @param items The list of menu items to be searched.\n * @param href The url href after the domain up to the query parameters.\n * @param [parameters] The url query string after pathname.\n *\n * @returns The id of a parent menu item or an empty string.\n */\nconst searchHrefInMenuItems = (\n items: MenuItem[],\n href: string,\n parameters?: string\n): string | undefined => {\n if (!href) {\n return undefined;\n }\n\n const normalizedHref =\n href.length > 1 && href.endsWith(\"/\")\n ? href.slice(0, href.length - 1).toLowerCase()\n : href.toLowerCase();\n\n const normalizedFullHref = parameters\n ? normalizedHref.concat(parameters.toLowerCase())\n : normalizedHref;\n\n return searchHrefMatch(items, normalizedHref, normalizedFullHref);\n};\n\n/**\n * Get root menu id from the path (in the format 0-0-0 - id's separated by `-`)\n * @param menuItemId\n * @returns the Id of the first menu or undefined if the provided value is undefined\n */\nconst getRootIdFromItemId = (\n menuItemId: string | undefined\n): string | undefined => {\n if (!menuItemId) {\n return undefined;\n }\n return menuItemId.split(\"-\")[0];\n};\n\n/**\n * Searches for an item with the specified id.\n *\n * @param {MenuItem[]} data - The navigation data structure.\n * @param {string} itemId - The item id.\n * @returns The item with matching id.\n */\nconst findItemById = (data: MenuItem[], itemId: string): MenuItem | null => {\n let foundItem: MenuItem | null = null;\n data.some(obj => {\n const { id: objId, data: childData } = obj;\n if (objId === itemId) {\n foundItem = obj;\n return true;\n }\n if (childData && childData.length > 0) {\n foundItem = findItemById(childData, itemId);\n return foundItem !== null;\n }\n return false;\n });\n return foundItem;\n};\n\n/**\n * Finds the first leaf item (item with children) inside the received structure.\n *\n * @param {MenuItem[]} data - The navigation data structure.\n * @returns - The first leaf item inside the structure.\n */\nconst findFirstLeafItem = (data: MenuItem[]): MenuItem | null => {\n let foundItem: MenuItem | null = null;\n data.some(obj => {\n if (!obj.data || obj.data.length === 0) {\n foundItem = obj;\n return true;\n }\n foundItem = findFirstLeafItem(obj.data);\n return foundItem !== null;\n });\n return foundItem;\n};\n\nexport {\n createMenuItems,\n searchHrefInMenuItems,\n getRootIdFromItemId,\n addPrefixToHref,\n findItemById,\n findFirstLeafItem\n};\n"],"names":["getMenuTargetHref","menuItem","target","submenus","addPrefixToHref","href","startsWith","createMenuItems","t","menuItems","maxDepth","parentMenuItem","undefined","reduce","accumulator","currentValue","index","navItem","id","label","icon","parent","updatedDepth","data","length","push","flatMenuItems","items","acc","item","decomposeHrefStringToArray","normalizedHref","hrefArray","split","prefix","unshift","searchHrefMatch","normalizedFullHref","toBeSelectedId","toBeSelectedHref","reducedNormalizedHref","some","_a","_b","_c","_d","normalizedItemHref","normalizedItemHrefParams","idx","indexOf","slice","toLowerCase","endsWith","matchedHref","find","searchHrefInMenuItems","parameters","concat","getRootIdFromItemId","menuItemId","findItemById","itemId","foundItem","obj","objId","childData","findFirstLeafItem"],"mappings":"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"}
|