@umituz/web-dashboard 6.8.0 → 6.9.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/web-dashboard",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.9.0",
|
|
4
4
|
"description": "Installable app skeleton for the fleet — layouts, analytics (dependency-free SVG charts), calendar, onboarding flow, i18n via @umituz/web-localization, permissions/module registry; udb-* stylesheet on design-system tokens",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -98,4 +98,28 @@ describe("DashboardLayout (command palette)", () => {
|
|
|
98
98
|
expect(onActivate).toHaveBeenCalledTimes(1);
|
|
99
99
|
expect(screen.queryByRole("dialog")).toBeNull();
|
|
100
100
|
});
|
|
101
|
+
|
|
102
|
+
it("derives navigation groups from the sidebar when includeSidebar is set", async () => {
|
|
103
|
+
renderAt("/", undefined, {
|
|
104
|
+
...config,
|
|
105
|
+
commandPalette: {
|
|
106
|
+
includeSidebar: true,
|
|
107
|
+
groups: [{ heading: "Quick", items: [{ id: "q", label: "Quick action", onSelect: () => {} }] }],
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
fireEvent.keyDown(window, { key: "k", metaKey: true });
|
|
111
|
+
expect(await screen.findByRole("option", { name: "Quick action" })).toBeTruthy();
|
|
112
|
+
// The custom group has no "Home" — the one present is derived from the sidebar,
|
|
113
|
+
// carrying the path as its hint (accessible name "Home /").
|
|
114
|
+
const derived = screen.getByRole("option", { name: /home/i });
|
|
115
|
+
expect(derived.textContent).toContain("/");
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("omits sidebar-derived items from the palette by default", async () => {
|
|
119
|
+
renderAt("/", undefined, paletteConfig());
|
|
120
|
+
fireEvent.keyDown(window, { key: "k", metaKey: true });
|
|
121
|
+
// Only the palette's own "Home" (no path hint) — nothing derived from the sidebar.
|
|
122
|
+
const own = await screen.findByRole("option", { name: "Home" });
|
|
123
|
+
expect(own.textContent).toBe("Home");
|
|
124
|
+
});
|
|
101
125
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useEffect, type ReactNode } from "react";
|
|
2
|
-
import { useLocation, Outlet, Navigate } from "react-router-dom";
|
|
2
|
+
import { useLocation, useNavigate, Outlet, Navigate } from "react-router-dom";
|
|
3
3
|
import { useT } from "@umituz/web-localization/react";
|
|
4
4
|
import { Skeleton } from "@umituz/web-design-system/atoms";
|
|
5
5
|
import { CommandPalette } from "@umituz/web-design-system/organisms";
|
|
@@ -61,6 +61,7 @@ export const DashboardLayout = ({
|
|
|
61
61
|
skipToContentLabel,
|
|
62
62
|
}: DashboardLayoutProps) => {
|
|
63
63
|
const location = useLocation();
|
|
64
|
+
const navigate = useNavigate();
|
|
64
65
|
const t = useT();
|
|
65
66
|
const [collapsed, setCollapsed] = useState(() => readCollapsed(collapsedStorageKey));
|
|
66
67
|
const [mobileOpen, setMobileOpen] = useState(false);
|
|
@@ -132,6 +133,23 @@ export const DashboardLayout = ({
|
|
|
132
133
|
|
|
133
134
|
const currentTitle = getTitle();
|
|
134
135
|
|
|
136
|
+
// Sidebar-derived navigation groups — one nav definition feeds both chrome surfaces.
|
|
137
|
+
const paletteGroups = palette?.includeSidebar
|
|
138
|
+
? [
|
|
139
|
+
...palette.groups,
|
|
140
|
+
...config.sidebarGroups.map((group) => ({
|
|
141
|
+
heading: group.title,
|
|
142
|
+
items: group.items.map((item) => ({
|
|
143
|
+
id: `nav-${item.path}`,
|
|
144
|
+
label: item.raw ? item.label : t(item.label),
|
|
145
|
+
icon: <item.icon size={16} aria-hidden="true" />,
|
|
146
|
+
hint: item.path,
|
|
147
|
+
onSelect: () => navigate(item.path),
|
|
148
|
+
})),
|
|
149
|
+
})),
|
|
150
|
+
]
|
|
151
|
+
: undefined;
|
|
152
|
+
|
|
135
153
|
const sidebarProps = {
|
|
136
154
|
sidebarGroups: config.sidebarGroups,
|
|
137
155
|
brandName: config.brandName,
|
|
@@ -225,7 +243,7 @@ export const DashboardLayout = ({
|
|
|
225
243
|
<CommandPalette
|
|
226
244
|
open={paletteOpen}
|
|
227
245
|
onOpenChange={setPaletteOpen}
|
|
228
|
-
groups={palette.groups}
|
|
246
|
+
groups={paletteGroups ?? palette.groups}
|
|
229
247
|
placeholder={palette.placeholder}
|
|
230
248
|
emptyLabel={palette.emptyLabel}
|
|
231
249
|
label={palette.label}
|
|
@@ -42,6 +42,9 @@ export interface CommandPaletteConfig {
|
|
|
42
42
|
label?: string;
|
|
43
43
|
/** Bind ⌘K/Ctrl+K to open the palette (default true). */
|
|
44
44
|
shortcut?: boolean;
|
|
45
|
+
/** Append the sidebar groups as navigation groups — derived from
|
|
46
|
+
* sidebarGroups and routed internally, so apps never map their nav twice. */
|
|
47
|
+
includeSidebar?: boolean;
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
export interface DashboardSidebarProps {
|