@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.
@@ -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":"AASA,OAAO,EAAE,KAAK,EAAE,EAAsB,MAAM,OAAO,CAAC;AACpD,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,4BAA4B,EAElC,MAAM,0BAA0B,CAAC;AAElC,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,CA8DtD,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;CACtB;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAkB1D,CAAC"}
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: options.map((option) => (_jsx(DropdownItem, { isDisabled: option.isDisabled, description: option.description, onClick: option.onSelect, children: option.label }, option.key))) }) }));
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,CA6PpD,CAAC"}
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, VIEW_MODE_LABELS), activeExportViewId: viewMode, onExportViewChange: (viewId) => {
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
  }
@@ -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
- * Standard report-download actions. Omit a handler to hide that format.
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, }: StandardReportExportHandlers) => ReportExportOption[];
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;CACtB;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;;GAEG;AACH,eAAO,MAAM,2BAA2B,GAAI,6CAIzC,4BAA4B,KAAG,kBAAkB,EA+BnD,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
- * Standard report-download actions. Omit a handler to hide that format.
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-47af17e06309",
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(CHART_TITLE, VIEW_MODE_LABELS)}
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} />);
@@ -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
- * Standard report-download actions. Omit a handler to hide that format.
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
- }: StandardReportExportHandlers): ReportExportOption[] => {
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