@openshift-migration-advisor/shared-components 0.28.0-47af17e06309 → 0.28.0-811d1036212f
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/report/ReportExportMenu.d.ts +1 -0
- package/dist/report/ReportExportMenu.d.ts.map +1 -1
- package/dist/report/ReportExportMenu.js +38 -4
- package/dist/report/StorageOverview.d.ts.map +1 -1
- package/dist/report/StorageOverview.js +13 -1
- package/dist/report/index.d.ts +1 -1
- package/dist/report/index.d.ts.map +1 -1
- package/dist/report/reportExportOptions.d.ts +13 -2
- package/dist/report/reportExportOptions.d.ts.map +1 -1
- package/dist/report/reportExportOptions.js +13 -5
- package/package.json +1 -1
- package/src/report/ReportExportMenu.tsx +69 -13
- package/src/report/StorageOverview.tsx +18 -1
- package/src/report/__tests__/StorageOverview.test.tsx +44 -0
- package/src/report/index.ts +2 -0
- package/src/report/reportExportOptions.ts +28 -5
|
@@ -14,6 +14,7 @@ export interface ExportReportButtonProps extends StandardReportExportHandlers {
|
|
|
14
14
|
loadingLabel?: string | null;
|
|
15
15
|
isDisabled?: boolean;
|
|
16
16
|
toggleLabel?: string;
|
|
17
|
+
assessmentSectionLabel?: string;
|
|
17
18
|
}
|
|
18
19
|
export declare const ExportReportButton: FC<ExportReportButtonProps>;
|
|
19
20
|
//# sourceMappingURL=ReportExportMenu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReportExportMenu.d.ts","sourceRoot":"","sources":["../../src/report/ReportExportMenu.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ReportExportMenu.d.ts","sourceRoot":"","sources":["../../src/report/ReportExportMenu.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,EAAE,EAA+C,MAAM,OAAO,CAAC;AAC7E,OAAO,EACL,KAAK,kBAAkB,EAEvB,KAAK,4BAA4B,EAElC,MAAM,0BAA0B,CAAC;AA6BlC,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAqFtD,CAAC;AAIF,MAAM,WAAW,uBAAwB,SAAQ,4BAA4B;IAC3E,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAoB1D,CAAC"}
|
|
@@ -1,13 +1,46 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Dropdown, DropdownItem, DropdownList, MenuToggle, Spinner, } from "@patternfly/react-core";
|
|
2
|
+
import { Divider, Dropdown, DropdownGroup, DropdownItem, DropdownList, MenuToggle, Spinner, } from "@patternfly/react-core";
|
|
3
3
|
import { DownloadIcon } from "@patternfly/react-icons";
|
|
4
|
-
import { useState } from "react";
|
|
4
|
+
import { useMemo, useState } from "react";
|
|
5
5
|
import { standardReportExportOptions, } from "./reportExportOptions.js";
|
|
6
|
+
function sectionGroupKey(section) {
|
|
7
|
+
return section?.id;
|
|
8
|
+
}
|
|
9
|
+
function groupExportOptions(options) {
|
|
10
|
+
const groups = [];
|
|
11
|
+
for (const option of options) {
|
|
12
|
+
const sectionKey = sectionGroupKey(option.section);
|
|
13
|
+
const last = groups.length > 0 ? groups[groups.length - 1] : undefined;
|
|
14
|
+
const lastKey = last ? sectionGroupKey(last.section) : undefined;
|
|
15
|
+
if (last && lastKey === sectionKey) {
|
|
16
|
+
last.options.push(option);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
groups.push({ section: option.section, options: [option] });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return groups;
|
|
23
|
+
}
|
|
6
24
|
export const ReportExportMenu = ({ options, isLoading = false, loadingLabel = null, isDisabled = false, toggleLabel = "Export", }) => {
|
|
7
25
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
26
|
+
const optionGroups = useMemo(() => groupExportOptions(options), [options]);
|
|
8
27
|
if (options.length === 0) {
|
|
9
28
|
return null;
|
|
10
29
|
}
|
|
30
|
+
const menuItems = [];
|
|
31
|
+
optionGroups.forEach((group, index) => {
|
|
32
|
+
if (index > 0) {
|
|
33
|
+
const dividerKey = group.section?.id ?? group.options[0]?.key ?? "ungrouped";
|
|
34
|
+
menuItems.push(_jsx(Divider, { component: "li" }, `divider-before-${dividerKey}`));
|
|
35
|
+
}
|
|
36
|
+
const items = group.options.map((option) => (_jsx(DropdownItem, { isDisabled: option.isDisabled, description: option.description, onClick: option.onSelect, children: option.label }, option.key)));
|
|
37
|
+
if (group.section) {
|
|
38
|
+
menuItems.push(_jsx(DropdownGroup, { label: group.section.label, children: items }, group.section.id));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
menuItems.push(...items);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
11
44
|
return (_jsx(Dropdown, { isOpen: isDropdownOpen, popperProps: {
|
|
12
45
|
placement: "bottom-end",
|
|
13
46
|
preventOverflow: true,
|
|
@@ -17,14 +50,15 @@ export const ReportExportMenu = ({ options, isLoading = false, loadingLabel = nu
|
|
|
17
50
|
setIsDropdownOpen(isOpen);
|
|
18
51
|
}, toggle: (toggleRef) => (_jsx(MenuToggle, { ref: toggleRef, onClick: () => {
|
|
19
52
|
setIsDropdownOpen((open) => !open);
|
|
20
|
-
}, isExpanded: isDropdownOpen, variant: "secondary", isDisabled: isLoading || isDisabled, "aria-label": "Export report options", icon: isLoading ? (_jsx(Spinner, { size: "sm", "aria-hidden": "true" })) : (_jsx(DownloadIcon, { "aria-hidden": "true" })), children: isLoading ? (loadingLabel ?? "Generating...") : toggleLabel })), children: _jsx(DropdownList, { children:
|
|
53
|
+
}, isExpanded: isDropdownOpen, variant: "secondary", isDisabled: isLoading || isDisabled, "aria-label": "Export report options", icon: isLoading ? (_jsx(Spinner, { size: "sm", "aria-hidden": "true" })) : (_jsx(DownloadIcon, { "aria-hidden": "true" })), children: isLoading ? (loadingLabel ?? "Generating...") : toggleLabel })), children: _jsx(DropdownList, { children: menuItems }) }));
|
|
21
54
|
};
|
|
22
55
|
ReportExportMenu.displayName = "ReportExportMenu";
|
|
23
|
-
export const ExportReportButton = ({ onExportPdf, onExportPng, onExportHtml, extraOptions = [], ...menuProps }) => (_jsx(ReportExportMenu, { options: [
|
|
56
|
+
export const ExportReportButton = ({ onExportPdf, onExportPng, onExportHtml, extraOptions = [], assessmentSectionLabel, ...menuProps }) => (_jsx(ReportExportMenu, { options: [
|
|
24
57
|
...standardReportExportOptions({
|
|
25
58
|
onExportPdf,
|
|
26
59
|
onExportPng,
|
|
27
60
|
onExportHtml,
|
|
61
|
+
assessmentSectionLabel,
|
|
28
62
|
}),
|
|
29
63
|
...extraOptions,
|
|
30
64
|
], ...menuProps }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageOverview.d.ts","sourceRoot":"","sources":["../../src/report/StorageOverview.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,EAAE,EAAO,MAAM,OAAO,CAAC;AAErC,OAAO,EAGL,KAAK,gCAAgC,EACtC,MAAM,kCAAkC,CAAC;AAQ1C,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACtE,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,qDAAqD;IACrD,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAClD;AA0TD,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"StorageOverview.d.ts","sourceRoot":"","sources":["../../src/report/StorageOverview.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,EAAE,EAAO,MAAM,OAAO,CAAC;AAErC,OAAO,EAGL,KAAK,gCAAgC,EACtC,MAAM,kCAAkC,CAAC;AAQ1C,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACtE,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,qDAAqD;IACrD,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAClD;AA0TD,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CA8QpD,CAAC"}
|
|
@@ -240,6 +240,18 @@ export const StorageOverview = ({ diskSizeTier = {}, diskTypes = {}, totalVMs, t
|
|
|
240
240
|
}))
|
|
241
241
|
.sort((a, b) => orderIndex(a.name) - orderIndex(b.name));
|
|
242
242
|
}, [diskTypes]);
|
|
243
|
+
const isSharedDisksViewAvailable = totalWithSharedDisks !== 0;
|
|
244
|
+
// Exclude the "Shared disks" view from the chart export cycle (used to
|
|
245
|
+
// build the PDF/PNG/HTML exports) when that view is disabled in the
|
|
246
|
+
// dropdown, so the exported report stays consistent with what's
|
|
247
|
+
// selectable on screen.
|
|
248
|
+
const availableExportViewLabels = useMemo(() => {
|
|
249
|
+
if (isSharedDisksViewAvailable) {
|
|
250
|
+
return VIEW_MODE_LABELS;
|
|
251
|
+
}
|
|
252
|
+
const { sharedDisks: _sharedDisks, ...rest } = VIEW_MODE_LABELS;
|
|
253
|
+
return rest;
|
|
254
|
+
}, [isSharedDisksViewAvailable]);
|
|
243
255
|
const sharedDisksChartData = useMemo(() => {
|
|
244
256
|
if (totalWithSharedDisks === undefined ||
|
|
245
257
|
totalVMs === undefined ||
|
|
@@ -290,7 +302,7 @@ export const StorageOverview = ({ diskSizeTier = {}, diskTypes = {}, totalVMs, t
|
|
|
290
302
|
}
|
|
291
303
|
};
|
|
292
304
|
const chartTitle = `${CHART_TITLE} — ${VIEW_MODE_LABELS[viewMode]}`;
|
|
293
|
-
return (_jsx(ChartExportSurface, { id: CHART_ID, title: chartTitle, exportViews: chartExportViewsFromLabels(CHART_TITLE,
|
|
305
|
+
return (_jsx(ChartExportSurface, { id: CHART_ID, title: chartTitle, exportViews: chartExportViewsFromLabels(CHART_TITLE, availableExportViewLabels), activeExportViewId: viewMode, onExportViewChange: (viewId) => {
|
|
294
306
|
if (isViewMode(viewId)) {
|
|
295
307
|
setViewMode(viewId);
|
|
296
308
|
}
|
package/dist/report/index.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export type { PowerStateChartModel } from "./powerStates.js";
|
|
|
35
35
|
export { buildHostPowerStateChart, buildVmPowerStateChart, HOST_POWER_COLORS, VM_POWER_COLORS, } from "./powerStates.js";
|
|
36
36
|
export { ExportReportButton, type ExportReportButtonProps, ReportExportMenu, type ReportExportMenuProps, } from "./ReportExportMenu.js";
|
|
37
37
|
export { ReportTable, type ReportTableProps } from "./ReportTable.js";
|
|
38
|
-
export { type ReportExportOption, type StandardReportExportHandlers, standardReportExportOptions, } from "./reportExportOptions.js";
|
|
38
|
+
export { type ReportExportOption, type ReportExportSection, type StandardReportExportHandlers, type StandardReportExportOptionsConfig, standardReportExportOptions, } from "./reportExportOptions.js";
|
|
39
39
|
export { type StorageDiskTierData, StorageOverview, type StorageOverviewProps, } from "./StorageOverview.js";
|
|
40
40
|
export { SupportTierBadge } from "./SupportTierBadge.js";
|
|
41
41
|
export { ALL_TIERS_FILTER, type OsBarChartViewModel, type OsTableRow, useOsBarChartViewModel, } from "./useOsBarChartViewModel.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,28 @@
|
|
|
1
|
+
export interface ReportExportSection {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
}
|
|
1
5
|
export interface ReportExportOption {
|
|
2
6
|
key: string;
|
|
3
7
|
label: string;
|
|
4
8
|
description?: string;
|
|
5
9
|
onSelect: () => void;
|
|
6
10
|
isDisabled?: boolean;
|
|
11
|
+
/** When set, the menu groups rows and shows `label` as the group heading. */
|
|
12
|
+
section?: ReportExportSection;
|
|
7
13
|
}
|
|
8
14
|
export interface StandardReportExportHandlers {
|
|
9
15
|
onExportPdf?: () => void;
|
|
10
16
|
onExportPng?: () => void;
|
|
11
17
|
onExportHtml?: () => void;
|
|
12
18
|
}
|
|
19
|
+
export type StandardReportExportOptionsConfig = StandardReportExportHandlers & {
|
|
20
|
+
/** Dropdown group label for PDF / HTML / PNG. Default: `"Assessment report"`. */
|
|
21
|
+
assessmentSectionLabel?: string;
|
|
22
|
+
};
|
|
13
23
|
/**
|
|
14
|
-
*
|
|
24
|
+
* Optional helper for chart-based assessment downloads. Omit a handler to hide
|
|
25
|
+
* that format. Override `assessmentSectionLabel` if product copy differs per app.
|
|
15
26
|
*/
|
|
16
|
-
export declare const standardReportExportOptions: ({ onExportPdf, onExportPng, onExportHtml, }:
|
|
27
|
+
export declare const standardReportExportOptions: ({ onExportPdf, onExportPng, onExportHtml, assessmentSectionLabel, }: StandardReportExportOptionsConfig) => ReportExportOption[];
|
|
17
28
|
//# sourceMappingURL=reportExportOptions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportExportOptions.d.ts","sourceRoot":"","sources":["../../src/report/reportExportOptions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"reportExportOptions.d.ts","sourceRoot":"","sources":["../../src/report/reportExportOptions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC/B;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,MAAM,MAAM,iCAAiC,GAAG,4BAA4B,GAAG;IAC7E,iFAAiF;IACjF,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAOF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GAAI,qEAKzC,iCAAiC,KAAG,kBAAkB,EAmCxD,CAAC"}
|
|
@@ -1,30 +1,38 @@
|
|
|
1
|
+
const DEFAULT_ASSESSMENT_SECTION = {
|
|
2
|
+
id: "assessment-report",
|
|
3
|
+
label: "Assessment report",
|
|
4
|
+
};
|
|
1
5
|
/**
|
|
2
|
-
*
|
|
6
|
+
* Optional helper for chart-based assessment downloads. Omit a handler to hide
|
|
7
|
+
* that format. Override `assessmentSectionLabel` if product copy differs per app.
|
|
3
8
|
*/
|
|
4
|
-
export const standardReportExportOptions = ({ onExportPdf, onExportPng, onExportHtml, }) => {
|
|
9
|
+
export const standardReportExportOptions = ({ onExportPdf, onExportPng, onExportHtml, assessmentSectionLabel, }) => {
|
|
10
|
+
const section = assessmentSectionLabel
|
|
11
|
+
? { ...DEFAULT_ASSESSMENT_SECTION, label: assessmentSectionLabel }
|
|
12
|
+
: DEFAULT_ASSESSMENT_SECTION;
|
|
5
13
|
const options = [];
|
|
6
14
|
if (onExportPdf) {
|
|
7
15
|
options.push({
|
|
8
16
|
key: "pdf",
|
|
9
17
|
label: "PDF",
|
|
10
|
-
description: "Export the report as a PDF",
|
|
11
18
|
onSelect: onExportPdf,
|
|
19
|
+
section,
|
|
12
20
|
});
|
|
13
21
|
}
|
|
14
22
|
if (onExportHtml) {
|
|
15
23
|
options.push({
|
|
16
24
|
key: "html",
|
|
17
25
|
label: "HTML",
|
|
18
|
-
description: "Export the report as HTML",
|
|
19
26
|
onSelect: onExportHtml,
|
|
27
|
+
section,
|
|
20
28
|
});
|
|
21
29
|
}
|
|
22
30
|
if (onExportPng) {
|
|
23
31
|
options.push({
|
|
24
32
|
key: "png",
|
|
25
33
|
label: "PNG",
|
|
26
|
-
description: "Download all charts as PNG files",
|
|
27
34
|
onSelect: onExportPng,
|
|
35
|
+
section,
|
|
28
36
|
});
|
|
29
37
|
}
|
|
30
38
|
return options;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openshift-migration-advisor/shared-components",
|
|
3
|
-
"version": "0.28.0-
|
|
3
|
+
"version": "0.28.0-811d1036212f",
|
|
4
4
|
"description": "Shared React UI components for Migration Advisor apps (report charts, forms, OS support tiers)",
|
|
5
5
|
"author": "Montse Ortega <mortegag@redhat.com>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Divider,
|
|
2
3
|
Dropdown,
|
|
4
|
+
DropdownGroup,
|
|
3
5
|
DropdownItem,
|
|
4
6
|
DropdownList,
|
|
5
7
|
MenuToggle,
|
|
@@ -7,13 +9,41 @@ import {
|
|
|
7
9
|
Spinner,
|
|
8
10
|
} from "@patternfly/react-core";
|
|
9
11
|
import { DownloadIcon } from "@patternfly/react-icons";
|
|
10
|
-
import { type FC, type Ref, useState } from "react";
|
|
12
|
+
import { type FC, type ReactNode, type Ref, useMemo, useState } from "react";
|
|
11
13
|
import {
|
|
12
14
|
type ReportExportOption,
|
|
15
|
+
type ReportExportSection,
|
|
13
16
|
type StandardReportExportHandlers,
|
|
14
17
|
standardReportExportOptions,
|
|
15
18
|
} from "./reportExportOptions.js";
|
|
16
19
|
|
|
20
|
+
function sectionGroupKey(section?: ReportExportSection): string | undefined {
|
|
21
|
+
return section?.id;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function groupExportOptions(options: ReportExportOption[]): {
|
|
25
|
+
section?: ReportExportSection;
|
|
26
|
+
options: ReportExportOption[];
|
|
27
|
+
}[] {
|
|
28
|
+
const groups: {
|
|
29
|
+
section?: ReportExportSection;
|
|
30
|
+
options: ReportExportOption[];
|
|
31
|
+
}[] = [];
|
|
32
|
+
|
|
33
|
+
for (const option of options) {
|
|
34
|
+
const sectionKey = sectionGroupKey(option.section);
|
|
35
|
+
const last = groups.length > 0 ? groups[groups.length - 1] : undefined;
|
|
36
|
+
const lastKey = last ? sectionGroupKey(last.section) : undefined;
|
|
37
|
+
if (last && lastKey === sectionKey) {
|
|
38
|
+
last.options.push(option);
|
|
39
|
+
} else {
|
|
40
|
+
groups.push({ section: option.section, options: [option] });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return groups;
|
|
45
|
+
}
|
|
46
|
+
|
|
17
47
|
export interface ReportExportMenuProps {
|
|
18
48
|
options: ReportExportOption[];
|
|
19
49
|
isLoading?: boolean;
|
|
@@ -31,10 +61,44 @@ export const ReportExportMenu: FC<ReportExportMenuProps> = ({
|
|
|
31
61
|
}) => {
|
|
32
62
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
33
63
|
|
|
64
|
+
const optionGroups = useMemo(() => groupExportOptions(options), [options]);
|
|
65
|
+
|
|
34
66
|
if (options.length === 0) {
|
|
35
67
|
return null;
|
|
36
68
|
}
|
|
37
69
|
|
|
70
|
+
const menuItems: ReactNode[] = [];
|
|
71
|
+
optionGroups.forEach((group, index) => {
|
|
72
|
+
if (index > 0) {
|
|
73
|
+
const dividerKey =
|
|
74
|
+
group.section?.id ?? group.options[0]?.key ?? "ungrouped";
|
|
75
|
+
menuItems.push(
|
|
76
|
+
<Divider key={`divider-before-${dividerKey}`} component="li" />,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const items = group.options.map((option) => (
|
|
81
|
+
<DropdownItem
|
|
82
|
+
key={option.key}
|
|
83
|
+
isDisabled={option.isDisabled}
|
|
84
|
+
description={option.description}
|
|
85
|
+
onClick={option.onSelect}
|
|
86
|
+
>
|
|
87
|
+
{option.label}
|
|
88
|
+
</DropdownItem>
|
|
89
|
+
));
|
|
90
|
+
|
|
91
|
+
if (group.section) {
|
|
92
|
+
menuItems.push(
|
|
93
|
+
<DropdownGroup key={group.section.id} label={group.section.label}>
|
|
94
|
+
{items}
|
|
95
|
+
</DropdownGroup>,
|
|
96
|
+
);
|
|
97
|
+
} else {
|
|
98
|
+
menuItems.push(...items);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
38
102
|
return (
|
|
39
103
|
<Dropdown
|
|
40
104
|
isOpen={isDropdownOpen}
|
|
@@ -70,18 +134,7 @@ export const ReportExportMenu: FC<ReportExportMenuProps> = ({
|
|
|
70
134
|
</MenuToggle>
|
|
71
135
|
)}
|
|
72
136
|
>
|
|
73
|
-
<DropdownList>
|
|
74
|
-
{options.map((option) => (
|
|
75
|
-
<DropdownItem
|
|
76
|
-
key={option.key}
|
|
77
|
-
isDisabled={option.isDisabled}
|
|
78
|
-
description={option.description}
|
|
79
|
-
onClick={option.onSelect}
|
|
80
|
-
>
|
|
81
|
-
{option.label}
|
|
82
|
-
</DropdownItem>
|
|
83
|
-
))}
|
|
84
|
-
</DropdownList>
|
|
137
|
+
<DropdownList>{menuItems}</DropdownList>
|
|
85
138
|
</Dropdown>
|
|
86
139
|
);
|
|
87
140
|
};
|
|
@@ -94,6 +147,7 @@ export interface ExportReportButtonProps extends StandardReportExportHandlers {
|
|
|
94
147
|
loadingLabel?: string | null;
|
|
95
148
|
isDisabled?: boolean;
|
|
96
149
|
toggleLabel?: string;
|
|
150
|
+
assessmentSectionLabel?: string;
|
|
97
151
|
}
|
|
98
152
|
|
|
99
153
|
export const ExportReportButton: FC<ExportReportButtonProps> = ({
|
|
@@ -101,6 +155,7 @@ export const ExportReportButton: FC<ExportReportButtonProps> = ({
|
|
|
101
155
|
onExportPng,
|
|
102
156
|
onExportHtml,
|
|
103
157
|
extraOptions = [],
|
|
158
|
+
assessmentSectionLabel,
|
|
104
159
|
...menuProps
|
|
105
160
|
}) => (
|
|
106
161
|
<ReportExportMenu
|
|
@@ -109,6 +164,7 @@ export const ExportReportButton: FC<ExportReportButtonProps> = ({
|
|
|
109
164
|
onExportPdf,
|
|
110
165
|
onExportPng,
|
|
111
166
|
onExportHtml,
|
|
167
|
+
assessmentSectionLabel,
|
|
112
168
|
}),
|
|
113
169
|
...extraOptions,
|
|
114
170
|
]}
|
|
@@ -427,6 +427,20 @@ export const StorageOverview: FC<StorageOverviewProps> = ({
|
|
|
427
427
|
.sort((a, b) => orderIndex(a.name) - orderIndex(b.name));
|
|
428
428
|
}, [diskTypes]);
|
|
429
429
|
|
|
430
|
+
const isSharedDisksViewAvailable = totalWithSharedDisks !== 0;
|
|
431
|
+
|
|
432
|
+
// Exclude the "Shared disks" view from the chart export cycle (used to
|
|
433
|
+
// build the PDF/PNG/HTML exports) when that view is disabled in the
|
|
434
|
+
// dropdown, so the exported report stays consistent with what's
|
|
435
|
+
// selectable on screen.
|
|
436
|
+
const availableExportViewLabels = useMemo(() => {
|
|
437
|
+
if (isSharedDisksViewAvailable) {
|
|
438
|
+
return VIEW_MODE_LABELS;
|
|
439
|
+
}
|
|
440
|
+
const { sharedDisks: _sharedDisks, ...rest } = VIEW_MODE_LABELS;
|
|
441
|
+
return rest;
|
|
442
|
+
}, [isSharedDisksViewAvailable]);
|
|
443
|
+
|
|
430
444
|
const sharedDisksChartData = useMemo(() => {
|
|
431
445
|
if (
|
|
432
446
|
totalWithSharedDisks === undefined ||
|
|
@@ -489,7 +503,10 @@ export const StorageOverview: FC<StorageOverviewProps> = ({
|
|
|
489
503
|
<ChartExportSurface
|
|
490
504
|
id={CHART_ID}
|
|
491
505
|
title={chartTitle}
|
|
492
|
-
exportViews={chartExportViewsFromLabels(
|
|
506
|
+
exportViews={chartExportViewsFromLabels(
|
|
507
|
+
CHART_TITLE,
|
|
508
|
+
availableExportViewLabels,
|
|
509
|
+
)}
|
|
493
510
|
activeExportViewId={viewMode}
|
|
494
511
|
onExportViewChange={(viewId) => {
|
|
495
512
|
if (isViewMode(viewId)) {
|
|
@@ -27,6 +27,23 @@ vi.mock("../../charts/MigrationDonutChart.js", () => ({
|
|
|
27
27
|
},
|
|
28
28
|
}));
|
|
29
29
|
|
|
30
|
+
vi.mock("../ChartExportSurface.js", () => ({
|
|
31
|
+
ChartExportSurface: ({
|
|
32
|
+
exportViews,
|
|
33
|
+
children,
|
|
34
|
+
}: {
|
|
35
|
+
exportViews?: Array<{ id: string; title: string }>;
|
|
36
|
+
children?: React.ReactNode;
|
|
37
|
+
}): JSX.Element => (
|
|
38
|
+
<div
|
|
39
|
+
data-testid="chart-export-surface"
|
|
40
|
+
data-export-view-ids={JSON.stringify(exportViews?.map((view) => view.id))}
|
|
41
|
+
>
|
|
42
|
+
{children}
|
|
43
|
+
</div>
|
|
44
|
+
),
|
|
45
|
+
}));
|
|
46
|
+
|
|
30
47
|
afterEach(() => {
|
|
31
48
|
donutProps.current = null;
|
|
32
49
|
cleanup();
|
|
@@ -171,6 +188,33 @@ describe("StorageOverview", () => {
|
|
|
171
188
|
});
|
|
172
189
|
});
|
|
173
190
|
|
|
191
|
+
it("excludes the shared disks view from the chart export cycle when disabled, so PDF/PNG/HTML exports stay consistent with the dropdown", () => {
|
|
192
|
+
render(<StorageOverview totalVMs={10} totalWithSharedDisks={0} />);
|
|
193
|
+
|
|
194
|
+
const exportViewIds = JSON.parse(
|
|
195
|
+
screen
|
|
196
|
+
.getByTestId("chart-export-surface")
|
|
197
|
+
.getAttribute("data-export-view-ids") || "[]",
|
|
198
|
+
) as string[];
|
|
199
|
+
|
|
200
|
+
expect(exportViewIds).not.toContain("sharedDisks");
|
|
201
|
+
expect(exportViewIds).toEqual(
|
|
202
|
+
expect.arrayContaining(["totalSize", "vmCount", "vmCountByDiskType"]),
|
|
203
|
+
);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("includes the shared disks view in the chart export cycle when available", () => {
|
|
207
|
+
render(<StorageOverview totalVMs={10} totalWithSharedDisks={4} />);
|
|
208
|
+
|
|
209
|
+
const exportViewIds = JSON.parse(
|
|
210
|
+
screen
|
|
211
|
+
.getByTestId("chart-export-surface")
|
|
212
|
+
.getAttribute("data-export-view-ids") || "[]",
|
|
213
|
+
) as string[];
|
|
214
|
+
|
|
215
|
+
expect(exportViewIds).toContain("sharedDisks");
|
|
216
|
+
});
|
|
217
|
+
|
|
174
218
|
it("disables the shared-disks view when no VMs have shared disks", async () => {
|
|
175
219
|
const user = userEvent.setup();
|
|
176
220
|
render(<StorageOverview totalVMs={10} totalWithSharedDisks={0} />);
|
package/src/report/index.ts
CHANGED
|
@@ -192,7 +192,9 @@ export {
|
|
|
192
192
|
export { ReportTable, type ReportTableProps } from "./ReportTable.js";
|
|
193
193
|
export {
|
|
194
194
|
type ReportExportOption,
|
|
195
|
+
type ReportExportSection,
|
|
195
196
|
type StandardReportExportHandlers,
|
|
197
|
+
type StandardReportExportOptionsConfig,
|
|
196
198
|
standardReportExportOptions,
|
|
197
199
|
} from "./reportExportOptions.js";
|
|
198
200
|
export {
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
export interface ReportExportSection {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
1
6
|
export interface ReportExportOption {
|
|
2
7
|
key: string;
|
|
3
8
|
label: string;
|
|
4
9
|
description?: string;
|
|
5
10
|
onSelect: () => void;
|
|
6
11
|
isDisabled?: boolean;
|
|
12
|
+
/** When set, the menu groups rows and shows `label` as the group heading. */
|
|
13
|
+
section?: ReportExportSection;
|
|
7
14
|
}
|
|
8
15
|
|
|
9
16
|
export interface StandardReportExportHandlers {
|
|
@@ -12,22 +19,38 @@ export interface StandardReportExportHandlers {
|
|
|
12
19
|
onExportHtml?: () => void;
|
|
13
20
|
}
|
|
14
21
|
|
|
22
|
+
export type StandardReportExportOptionsConfig = StandardReportExportHandlers & {
|
|
23
|
+
/** Dropdown group label for PDF / HTML / PNG. Default: `"Assessment report"`. */
|
|
24
|
+
assessmentSectionLabel?: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const DEFAULT_ASSESSMENT_SECTION: ReportExportSection = {
|
|
28
|
+
id: "assessment-report",
|
|
29
|
+
label: "Assessment report",
|
|
30
|
+
};
|
|
31
|
+
|
|
15
32
|
/**
|
|
16
|
-
*
|
|
33
|
+
* Optional helper for chart-based assessment downloads. Omit a handler to hide
|
|
34
|
+
* that format. Override `assessmentSectionLabel` if product copy differs per app.
|
|
17
35
|
*/
|
|
18
36
|
export const standardReportExportOptions = ({
|
|
19
37
|
onExportPdf,
|
|
20
38
|
onExportPng,
|
|
21
39
|
onExportHtml,
|
|
22
|
-
|
|
40
|
+
assessmentSectionLabel,
|
|
41
|
+
}: StandardReportExportOptionsConfig): ReportExportOption[] => {
|
|
42
|
+
const section: ReportExportSection = assessmentSectionLabel
|
|
43
|
+
? { ...DEFAULT_ASSESSMENT_SECTION, label: assessmentSectionLabel }
|
|
44
|
+
: DEFAULT_ASSESSMENT_SECTION;
|
|
45
|
+
|
|
23
46
|
const options: ReportExportOption[] = [];
|
|
24
47
|
|
|
25
48
|
if (onExportPdf) {
|
|
26
49
|
options.push({
|
|
27
50
|
key: "pdf",
|
|
28
51
|
label: "PDF",
|
|
29
|
-
description: "Export the report as a PDF",
|
|
30
52
|
onSelect: onExportPdf,
|
|
53
|
+
section,
|
|
31
54
|
});
|
|
32
55
|
}
|
|
33
56
|
|
|
@@ -35,8 +58,8 @@ export const standardReportExportOptions = ({
|
|
|
35
58
|
options.push({
|
|
36
59
|
key: "html",
|
|
37
60
|
label: "HTML",
|
|
38
|
-
description: "Export the report as HTML",
|
|
39
61
|
onSelect: onExportHtml,
|
|
62
|
+
section,
|
|
40
63
|
});
|
|
41
64
|
}
|
|
42
65
|
|
|
@@ -44,8 +67,8 @@ export const standardReportExportOptions = ({
|
|
|
44
67
|
options.push({
|
|
45
68
|
key: "png",
|
|
46
69
|
label: "PNG",
|
|
47
|
-
description: "Download all charts as PNG files",
|
|
48
70
|
onSelect: onExportPng,
|
|
71
|
+
section,
|
|
49
72
|
});
|
|
50
73
|
}
|
|
51
74
|
|