@umituz/web-dashboard 6.2.1 → 6.4.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.4.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",
|
|
@@ -10,35 +10,36 @@
|
|
|
10
10
|
],
|
|
11
11
|
"exports": {
|
|
12
12
|
".": "./src/index.ts",
|
|
13
|
-
"./styles.css": "./src/styles/dashboard.css",
|
|
14
|
-
"./permissions": "./src/domains/permissions/index.ts",
|
|
15
|
-
"./modules": "./src/domains/modules/index.ts",
|
|
16
|
-
"./layouts": "./src/domains/layouts/index.ts",
|
|
17
|
-
"./layouts/components": "./src/domains/layouts/components/index.ts",
|
|
18
|
-
"./layouts/hooks": "./src/domains/layouts/hooks/index.ts",
|
|
19
|
-
"./layouts/utils": "./src/domains/layouts/utils/index.ts",
|
|
20
|
-
"./layouts/types": "./src/domains/layouts/types/index.ts",
|
|
21
|
-
"./layouts/theme": "./src/domains/layouts/theme/index.ts",
|
|
22
|
-
"./settings": "./src/domains/settings/index.ts",
|
|
23
|
-
"./settings/components": "./src/domains/settings/components/index.ts",
|
|
24
|
-
"./settings/hooks": "./src/domains/settings/hooks/index.ts",
|
|
25
|
-
"./settings/utils": "./src/domains/settings/utils/index.ts",
|
|
26
|
-
"./settings/types": "./src/domains/settings/types/index.ts",
|
|
27
13
|
"./analytics": "./src/domains/analytics/index.ts",
|
|
28
14
|
"./analytics/components": "./src/domains/analytics/components/index.ts",
|
|
29
15
|
"./analytics/hooks": "./src/domains/analytics/hooks/index.ts",
|
|
30
|
-
"./analytics/utils": "./src/domains/analytics/utils/index.ts",
|
|
31
|
-
"./analytics/types": "./src/domains/analytics/types/index.ts",
|
|
32
16
|
"./analytics/services": "./src/domains/analytics/services/index.ts",
|
|
17
|
+
"./analytics/types": "./src/domains/analytics/types/index.ts",
|
|
18
|
+
"./analytics/utils": "./src/domains/analytics/utils/index.ts",
|
|
33
19
|
"./calendar": "./src/domains/calendar/index.ts",
|
|
34
|
-
"./calendar/types": "./src/domains/calendar/types/calendar.types.ts",
|
|
35
|
-
"./calendar/services": "./src/domains/calendar/services/index.ts",
|
|
36
20
|
"./calendar/hooks": "./src/domains/calendar/hooks/index.ts",
|
|
21
|
+
"./calendar/services": "./src/domains/calendar/services/index.ts",
|
|
22
|
+
"./calendar/types": "./src/domains/calendar/types/calendar.types.ts",
|
|
37
23
|
"./calendar/utils": "./src/domains/calendar/utils/index.ts",
|
|
24
|
+
"./charts": "./src/domains/charts/index.ts",
|
|
25
|
+
"./chrome.css": "./src/styles/chrome.css",
|
|
38
26
|
"./config": "./src/config/index.ts",
|
|
27
|
+
"./layouts": "./src/domains/layouts/index.ts",
|
|
28
|
+
"./layouts/components": "./src/domains/layouts/components/index.ts",
|
|
29
|
+
"./layouts/hooks": "./src/domains/layouts/hooks/index.ts",
|
|
30
|
+
"./layouts/theme": "./src/domains/layouts/theme/index.ts",
|
|
31
|
+
"./layouts/types": "./src/domains/layouts/types/index.ts",
|
|
32
|
+
"./layouts/utils": "./src/domains/layouts/utils/index.ts",
|
|
33
|
+
"./modules": "./src/domains/modules/index.ts",
|
|
34
|
+
"./onboarding": "./src/domains/onboarding/index.ts",
|
|
39
35
|
"./package.json": "./package.json",
|
|
40
|
-
"./
|
|
41
|
-
"./
|
|
36
|
+
"./permissions": "./src/domains/permissions/index.ts",
|
|
37
|
+
"./settings": "./src/domains/settings/index.ts",
|
|
38
|
+
"./settings/components": "./src/domains/settings/components/index.ts",
|
|
39
|
+
"./settings/hooks": "./src/domains/settings/hooks/index.ts",
|
|
40
|
+
"./settings/types": "./src/domains/settings/types/index.ts",
|
|
41
|
+
"./settings/utils": "./src/domains/settings/utils/index.ts",
|
|
42
|
+
"./styles.css": "./src/styles/dashboard.css"
|
|
42
43
|
},
|
|
43
44
|
"files": [
|
|
44
45
|
"src",
|
|
@@ -86,6 +86,29 @@ describe('charts markup smoke', () => {
|
|
|
86
86
|
expect(html).toContain('height:100%');
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
+
it('BarChart renders a dashed goal line that counts toward max and clamps at 100%', () => {
|
|
90
|
+
const html = renderToString(
|
|
91
|
+
<BarChart
|
|
92
|
+
labels={['a', 'b']}
|
|
93
|
+
series={[{ label: 'A', values: [2, 4] }]}
|
|
94
|
+
goalLine={{ value: 4, label: 'goal 4', tone: '#111111' }}
|
|
95
|
+
/>,
|
|
96
|
+
);
|
|
97
|
+
expect(html).toContain('udb-barchart__goal');
|
|
98
|
+
expect(html).toContain('bottom:100%');
|
|
99
|
+
expect(html).toContain('border-top-color:#111111');
|
|
100
|
+
expect(html).toContain('>goal 4<');
|
|
101
|
+
|
|
102
|
+
const above = renderToString(
|
|
103
|
+
<BarChart labels={['a']} series={[{ label: 'A', values: [2] }]} goalLine={{ value: 99 }} />,
|
|
104
|
+
);
|
|
105
|
+
expect(above).toContain('bottom:100%');
|
|
106
|
+
expect(above).not.toContain('udb-barchart__goallabel');
|
|
107
|
+
|
|
108
|
+
const without = renderToString(<BarChart labels={['a']} series={[{ label: 'A', values: [2] }]} />);
|
|
109
|
+
expect(without).not.toContain('udb-barchart__goal');
|
|
110
|
+
});
|
|
111
|
+
|
|
89
112
|
it('fleet aliases: Legend renders hint suffix and Donut accepts color', () => {
|
|
90
113
|
const html = renderToString(
|
|
91
114
|
<>
|
|
@@ -149,25 +149,58 @@ export interface BarSeries {
|
|
|
149
149
|
color?: string;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
export interface BarChartGoalLine {
|
|
153
|
+
value: number;
|
|
154
|
+
label?: string;
|
|
155
|
+
tone?: string;
|
|
156
|
+
}
|
|
157
|
+
|
|
152
158
|
export function BarChart({
|
|
153
159
|
labels,
|
|
154
160
|
series,
|
|
155
161
|
height = 130,
|
|
156
162
|
formatValue = (v: number) => String(v),
|
|
157
163
|
formatLabel = (l: string) => l,
|
|
164
|
+
goalLine,
|
|
158
165
|
}: {
|
|
159
166
|
labels: readonly string[];
|
|
160
167
|
series: BarSeries[];
|
|
161
168
|
height?: number;
|
|
162
169
|
formatValue?: (v: number) => string;
|
|
163
170
|
formatLabel?: (l: string) => string;
|
|
171
|
+
goalLine?: BarChartGoalLine;
|
|
164
172
|
}) {
|
|
165
173
|
const [hover, setHover] = useState<number | null>(null);
|
|
166
174
|
const vals = (s: BarSeries) => s.values ?? s.data ?? [];
|
|
167
|
-
const max = Math.max(1, ...series.flatMap((s) => vals(s)));
|
|
175
|
+
const max = Math.max(1, ...series.flatMap((s) => vals(s)), goalLine?.value ?? 0);
|
|
168
176
|
const toneOf = (s: BarSeries, i: number) => s.tone ?? s.color ?? PALETTE[i % PALETTE.length]!;
|
|
177
|
+
const goalPct = goalLine !== undefined ? Math.min(100, (goalLine.value / max) * 100) : null;
|
|
169
178
|
return (
|
|
170
179
|
<div className="udb-barchart" style={{ height }}>
|
|
180
|
+
{goalLine !== undefined && goalPct !== null && (
|
|
181
|
+
<div
|
|
182
|
+
className="udb-barchart__goal"
|
|
183
|
+
style={{
|
|
184
|
+
bottom: `${goalPct}%`,
|
|
185
|
+
...(goalLine.tone !== undefined ? { borderTopColor: goalLine.tone } : {}),
|
|
186
|
+
}}
|
|
187
|
+
title={goalLine.label ?? formatValue(goalLine.value)}
|
|
188
|
+
aria-hidden="true"
|
|
189
|
+
>
|
|
190
|
+
{goalLine.label !== undefined && (
|
|
191
|
+
<span
|
|
192
|
+
className="udb-barchart__goallabel"
|
|
193
|
+
style={
|
|
194
|
+
goalLine.tone !== undefined
|
|
195
|
+
? { color: goalLine.tone, borderColor: goalLine.tone }
|
|
196
|
+
: undefined
|
|
197
|
+
}
|
|
198
|
+
>
|
|
199
|
+
{goalLine.label}
|
|
200
|
+
</span>
|
|
201
|
+
)}
|
|
202
|
+
</div>
|
|
203
|
+
)}
|
|
171
204
|
{labels.map((label, i) => (
|
|
172
205
|
<div
|
|
173
206
|
key={label}
|