@openshift-migration-advisor/shared-components 0.28.0-9da6a7613f16 → 0.28.0-a68bc28c8af9

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.
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationDonutChart.d.ts","sourceRoot":"","sources":["../../src/charts/MigrationDonutChart.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,EAAE,EAAgB,MAAM,OAAO,CAAC;AAG9C,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,WAAW,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,MAAM,gCAAgC,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,wBAAwB,EAAE,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC7B,KAAK,EAAE;YACL,CAAC,EAAE,MAAM,CAAC;YACV,CAAC,EAAE,MAAM,CAAC;YACV,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;YAC/B,cAAc,EAAE,MAAM,CAAC;SACxB,CAAC;QACF,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,KAAK,MAAM,CAAC;IACb,iDAAiD;IACjD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACvD,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,mFAAmF;IACnF,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC5B,CAAC,EAAE,MAAM,CAAC;QACV,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KAChC,KAAK,MAAM,CAAC;IACb;;;;OAIG;IACH,aAAa,CAAC,EAAE,gCAAgC,CAAC;IACjD,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAoFD,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CAoX5D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"MigrationDonutChart.d.ts","sourceRoot":"","sources":["../../src/charts/MigrationDonutChart.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,EAAE,EAAgB,MAAM,OAAO,CAAC;AAG9C,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,WAAW,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,MAAM,gCAAgC,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,wBAAwB,EAAE,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC7B,KAAK,EAAE;YACL,CAAC,EAAE,MAAM,CAAC;YACV,CAAC,EAAE,MAAM,CAAC;YACV,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;YAC/B,cAAc,EAAE,MAAM,CAAC;SACxB,CAAC;QACF,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,KAAK,MAAM,CAAC;IACb,iDAAiD;IACjD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACvD,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,mFAAmF;IACnF,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE;QAC5B,CAAC,EAAE,MAAM,CAAC;QACV,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KAChC,KAAK,MAAM,CAAC;IACb;;;;OAIG;IACH,aAAa,CAAC,EAAE,gCAAgC,CAAC;IACjD,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAoFD,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CAgY5D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -111,9 +111,13 @@ export const MigrationDonutChart = ({ data, legend, customColors, height = 260,
111
111
  countDisplay: item.countDisplay ?? item.count,
112
112
  }));
113
113
  }, [data]);
114
- const colorScale = useMemo(() => {
115
- return chartData.map((item) => getColor(item.legendCategory));
116
- }, [chartData, getColor]);
114
+ // Victory renders zero-value slices as degenerate zero-angle wedges but still
115
+ // keeps a `padAngle` gap around each one.
116
+ const donutChartData = useMemo(() => chartData.filter((item) => Number(item.y) > 0), [chartData]);
117
+ const donutColorScale = useMemo(() => donutChartData.map((item) => getColor(item.legendCategory)), [donutChartData, getColor]);
118
+ // A lone slice has no neighbour to pad against; forcing padAngle to 0 keeps it
119
+ // from leaving a gap against itself.
120
+ const effectivePadAngle = donutChartData.length <= 1 ? 0 : padAngle;
117
121
  const legendData = useMemo(() => {
118
122
  return chartData.map((item) => ({
119
123
  name: `${item.x} (${item.countDisplay})`,
@@ -221,7 +225,7 @@ export const MigrationDonutChart = ({ data, legend, customColors, height = 260,
221
225
  fontFamily: chartTextFontFamily,
222
226
  },
223
227
  } }) }) }) }));
224
- return (_jsxs(Flex, { direction: { default: "column" }, alignItems: { default: "alignItemsCenter" }, className: `${onItemClick ? styles.cursorPointer : styles.cursorDefault} ${styles.chartContainer}`, children: [_jsxs("div", { className: styles.donutWrapper, children: [_jsx(ChartDonut, { ariaDesc: "Migration data donut chart", data: chartData, events: chartEvents, labelComponent: donutTooltip, labels: ({ datum, }) => formatLabel(datum), colorScale: colorScale, constrainToVisibleArea: true, innerRadius: innerRadius, padAngle: padAngle, title: title, subTitle: subTitle, height: height, width: width, padding: {
228
+ return (_jsxs(Flex, { direction: { default: "column" }, alignItems: { default: "alignItemsCenter" }, className: `${onItemClick ? styles.cursorPointer : styles.cursorDefault} ${styles.chartContainer}`, children: [_jsxs("div", { className: styles.donutWrapper, children: [_jsx(ChartDonut, { ariaDesc: "Migration data donut chart", data: donutChartData, events: chartEvents, labelComponent: donutTooltip, labels: ({ datum, }) => formatLabel(datum), colorScale: donutColorScale, constrainToVisibleArea: true, innerRadius: innerRadius, padAngle: effectivePadAngle, title: title, subTitle: subTitle, height: height, width: width, padding: {
225
229
  bottom: 5,
226
230
  left: 20,
227
231
  right: 20,
@@ -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
  }
@@ -0,0 +1,33 @@
1
+ import type { FC } from "react";
2
+ import { type MigrationDonutChartLegendVariant } from "../charts/MigrationDonutChart.js";
3
+ /**
4
+ * VM-issue counts this card reads. agent-sdk's `IssuesBreakdown` satisfies it;
5
+ * each field stays optional so older or partial payloads do not throw.
6
+ */
7
+ export interface IssuesBreakdownLike {
8
+ critical?: number;
9
+ error?: number;
10
+ warning?: number;
11
+ information?: number;
12
+ advisory?: number;
13
+ }
14
+ export interface VMMigrationStatusProps {
15
+ data: {
16
+ migratable: number;
17
+ nonMigratable: number;
18
+ };
19
+ issuesBreakdown?: IssuesBreakdownLike;
20
+ /**
21
+ * Donut-slice click. `true` for the migratable slice, `false` otherwise.
22
+ * Agent-ui maps it to a VM migration-readiness filter; ui-app omits it.
23
+ */
24
+ onReadinessSelect?: (isMigratable: boolean) => void;
25
+ /** Breakdown-bar click. The argument is the concern category label. */
26
+ onCategorySelect?: (category: string) => void;
27
+ /** Center-title click. Agent-ui opens the VM list with no extra filters. */
28
+ onTitleClick?: () => void;
29
+ /** `"html"` in agent-ui; ui-app passes `"chart"`. */
30
+ legendVariant?: MigrationDonutChartLegendVariant;
31
+ }
32
+ export declare const VMMigrationStatus: FC<VMMigrationStatusProps>;
33
+ //# sourceMappingURL=VMMigrationStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VMMigrationStatus.d.ts","sourceRoot":"","sources":["../../src/report/VMMigrationStatus.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,EAAE,EAAO,MAAM,OAAO,CAAC;AAErC,OAAO,EAEL,KAAK,gCAAgC,EACtC,MAAM,kCAAkC,CAAC;AAY1C;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,qDAAqD;IACrD,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAClD;AA+CD,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAgPxD,CAAC"}
@@ -0,0 +1,129 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { css } from "@emotion/css";
3
+ import { Card, CardBody, CardTitle, Content, Dropdown, DropdownItem, DropdownList, Flex, FlexItem, MenuToggle, } from "@patternfly/react-core";
4
+ import { VirtualMachineIcon } from "@patternfly/react-icons";
5
+ import { chart_color_blue_300, chart_color_purple_100, chart_color_purple_300, chart_color_teal_200, chart_color_yellow_400, } from "@patternfly/react-tokens";
6
+ import { useMemo, useState } from "react";
7
+ import { MigrationDonutChart, } from "../charts/MigrationDonutChart.js";
8
+ import { CardEmptyState } from "./CardEmptyState.js";
9
+ import { ChartHeaderActions } from "./ChartDownloadButton.js";
10
+ import { ChartExportSurface } from "./ChartExportSurface.js";
11
+ import { chartExportViewsFromLabels } from "./chartExport.js";
12
+ import { chartColorFailure, chartColorSuccess, REPORT_CARD_EMPTY_STATE_TITLES, } from "./constants.js";
13
+ import { dashboardStyles } from "./dashboardStyles.js";
14
+ const VIEW_MODE_LABELS = {
15
+ issuesVsNoIssues: "No issues vs with issues",
16
+ issuesBreakdown: "With issues breakdown",
17
+ };
18
+ const CHART_ID = "vm-migration-status";
19
+ const CHART_TITLE = "VM migration status";
20
+ const MIGRATABLE_LABEL = "Migratable";
21
+ const NOT_MIGRATABLE_LABEL = "Not ready for migration";
22
+ const CATEGORY_ORDER = [
23
+ { label: "Critical", key: "critical" },
24
+ { label: "Error", key: "error" },
25
+ { label: "Warning", key: "warning" },
26
+ { label: "Information", key: "information" },
27
+ { label: "Advisory", key: "advisory" },
28
+ ];
29
+ /**
30
+ * Same categorical order as the previous breakdown hex palette, mapped onto
31
+ * PatternFly `chart_color_*` tokens (nearest token where the old hex was not
32
+ * itself a token).
33
+ */
34
+ const CATEGORY_COLORS = {
35
+ Critical: chart_color_blue_300.value,
36
+ Error: chart_color_purple_300.value,
37
+ Warning: chart_color_purple_100.value,
38
+ Information: chart_color_teal_200.value,
39
+ Advisory: chart_color_yellow_400.value,
40
+ };
41
+ const menuToggleMinWidth = css `
42
+ min-width: 250px;
43
+ `;
44
+ const isViewMode = (value) => value === "issuesVsNoIssues" || value === "issuesBreakdown";
45
+ const toCount = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
46
+ export const VMMigrationStatus = ({ data, issuesBreakdown, onReadinessSelect, onCategorySelect, onTitleClick, legendVariant = "html", }) => {
47
+ const [viewMode, setViewMode] = useState("issuesVsNoIssues");
48
+ const [isDropdownOpen, setIsDropdownOpen] = useState(false);
49
+ const totalVMs = data.migratable + data.nonMigratable;
50
+ const donutData = [
51
+ {
52
+ name: MIGRATABLE_LABEL,
53
+ count: data.migratable,
54
+ countDisplay: `${data.migratable} VMs`,
55
+ legendCategory: MIGRATABLE_LABEL,
56
+ },
57
+ {
58
+ name: NOT_MIGRATABLE_LABEL,
59
+ count: data.nonMigratable,
60
+ countDisplay: `${data.nonMigratable} VMs`,
61
+ legendCategory: NOT_MIGRATABLE_LABEL,
62
+ },
63
+ ];
64
+ const legend = {
65
+ [MIGRATABLE_LABEL]: chartColorSuccess,
66
+ [NOT_MIGRATABLE_LABEL]: chartColorFailure,
67
+ };
68
+ const breakdownData = useMemo(() => {
69
+ if (!issuesBreakdown) {
70
+ return [];
71
+ }
72
+ return CATEGORY_ORDER.map(({ label, key }) => ({
73
+ name: label,
74
+ count: toCount(issuesBreakdown[key]),
75
+ }));
76
+ }, [issuesBreakdown]);
77
+ const maxCount = useMemo(() => breakdownData.length > 0
78
+ ? Math.max(...breakdownData.map((d) => d.count))
79
+ : 0, [breakdownData]);
80
+ const chartTitle = `${CHART_TITLE} — ${VIEW_MODE_LABELS[viewMode]}`;
81
+ return (_jsx(ChartExportSurface, { id: CHART_ID, title: chartTitle, exportViews: chartExportViewsFromLabels(CHART_TITLE, VIEW_MODE_LABELS), activeExportViewId: viewMode, onExportViewChange: (viewId) => {
82
+ if (isViewMode(viewId)) {
83
+ setViewMode(viewId);
84
+ }
85
+ }, children: _jsxs(Card, { className: dashboardStyles.card, children: [_jsx(CardTitle, { children: _jsxs(Flex, { alignItems: { default: "alignItemsCenter" }, justifyContent: { default: "justifyContentSpaceBetween" }, children: [_jsxs(FlexItem, { children: [_jsx(VirtualMachineIcon, {}), " VM Migration Status"] }), _jsx(ChartHeaderActions, { chartId: CHART_ID, title: chartTitle, children: _jsx(Dropdown, { isOpen: isDropdownOpen, onSelect: (_event, value) => {
86
+ if (isViewMode(value)) {
87
+ setViewMode(value);
88
+ }
89
+ setIsDropdownOpen(false);
90
+ }, onOpenChange: setIsDropdownOpen, toggle: (toggleRef) => (_jsx(MenuToggle, { ref: toggleRef, onClick: () => setIsDropdownOpen((open) => !open), isExpanded: isDropdownOpen, className: menuToggleMinWidth, children: VIEW_MODE_LABELS[viewMode] })), children: _jsxs(DropdownList, { children: [_jsx(DropdownItem, { value: "issuesVsNoIssues", children: VIEW_MODE_LABELS.issuesVsNoIssues }, "issuesVsNoIssues"), _jsx(DropdownItem, { value: "issuesBreakdown", children: VIEW_MODE_LABELS.issuesBreakdown }, "issuesBreakdown")] }) }) })] }) }), _jsx(CardBody, { className: dashboardStyles.cardBodyScrollable, children: viewMode === "issuesVsNoIssues" ? (totalVMs === 0 ? (_jsx(CardEmptyState, { title: REPORT_CARD_EMPTY_STATE_TITLES.migrationStatus })) : (_jsx(MigrationDonutChart, { legendVariant: legendVariant, data: donutData, legend: legend, height: 300, width: 420, donutThickness: 18, padAngle: 1, title: `${totalVMs}`, subTitle: "VMs", subTitleColor: "var(--pf-t--global--text--color--subtle)", titleFontSize: 34, legendLabelFormatter: ({ x, countDisplay }) => `${x} (${countDisplay})`, onItemClick: onReadinessSelect
91
+ ? (item) => onReadinessSelect(item.name === MIGRATABLE_LABEL)
92
+ : undefined, onTitleClick: onTitleClick }))) : breakdownData.length === 0 ? (_jsx(CardEmptyState, { title: REPORT_CARD_EMPTY_STATE_TITLES.issuesBreakdown })) : (_jsxs("div", { children: [_jsx("div", { className: dashboardStyles.storageChartWrapper, children: _jsx(Flex, { direction: { default: "row" }, alignItems: { default: "alignItemsFlexEnd" }, justifyContent: { default: "justifyContentCenter" }, spaceItems: { default: "spaceItemsMd" }, style: {
93
+ height: "250px",
94
+ width: "100%",
95
+ }, children: breakdownData.map((item) => {
96
+ const heightPercentage = maxCount > 0 ? (item.count / maxCount) * 100 : 0;
97
+ const minHeightPercentage = item.count > 0 ? 20 : 0;
98
+ const finalHeightPercentage = Math.max(heightPercentage, minHeightPercentage);
99
+ const barColor = CATEGORY_COLORS[item.name] || CATEGORY_COLORS.Critical;
100
+ return (_jsxs(Flex, { direction: { default: "column" }, alignItems: { default: "alignItemsCenter" }, spaceItems: { default: "spaceItemsSm" }, style: { flex: "1", maxWidth: "120px" }, children: [_jsx(FlexItem, { style: {
101
+ height: "200px",
102
+ display: "flex",
103
+ alignItems: "flex-end",
104
+ width: "100%",
105
+ justifyContent: "center",
106
+ }, children: _jsx("button", { type: "button", onClick: () => onCategorySelect?.(item.name), title: `${item.name}: ${item.count} VMs`, style: {
107
+ width: "60px",
108
+ height: `${finalHeightPercentage}%`,
109
+ backgroundColor: barColor,
110
+ transition: "height 0.3s ease",
111
+ borderRadius: "4px 4px 0 0",
112
+ cursor: "pointer",
113
+ border: "none",
114
+ padding: 0,
115
+ } }) }), _jsx(FlexItem, { children: _jsxs(Content, { component: "small", style: {
116
+ fontSize: "12px",
117
+ textAlign: "center",
118
+ wordBreak: "break-word",
119
+ color: "var(--pf-t--global--text--color--regular)",
120
+ }, children: [item.name, _jsx("br", {}), "(", item.count, " VMs)"] }) })] }, item.name));
121
+ }) }) }), _jsx("div", { children: _jsx(Content, { component: "small", style: {
122
+ fontSize: "12px",
123
+ color: "var(--pf-t--global--text--color--subtle)",
124
+ marginTop: "16px",
125
+ textAlign: "center",
126
+ display: "block",
127
+ }, children: "Totals may exceed the unique VM count because a VM can appear in multiple categories" }) })] })) })] }) }));
128
+ };
129
+ VMMigrationStatus.displayName = "VMMigrationStatus";
@@ -35,11 +35,12 @@ 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";
42
42
  export { VCenterClusterDetails, type VCenterClusterDetailsProps, } from "./VCenterClusterDetails.js";
43
+ export { type IssuesBreakdownLike, VMMigrationStatus, type VMMigrationStatusProps, } from "./VMMigrationStatus.js";
43
44
  export { VmPowerStates, type VmPowerStatesProps, } from "./VmPowerStates.js";
44
45
  export { WarningsTable, type WarningsTableProps, } from "./WarningsTable.js";
45
46
  export { zipChartPngs } from "./zipChartPngs.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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"}
@@ -37,6 +37,7 @@ export { StorageOverview, } from "./StorageOverview.js";
37
37
  export { SupportTierBadge } from "./SupportTierBadge.js";
38
38
  export { ALL_TIERS_FILTER, useOsBarChartViewModel, } from "./useOsBarChartViewModel.js";
39
39
  export { VCenterClusterDetails, } from "./VCenterClusterDetails.js";
40
+ export { VMMigrationStatus, } from "./VMMigrationStatus.js";
40
41
  export { VmPowerStates, } from "./VmPowerStates.js";
41
42
  export { WarningsTable, } from "./WarningsTable.js";
42
43
  export { zipChartPngs } from "./zipChartPngs.js";
@@ -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-9da6a7613f16",
3
+ "version": "0.28.0-a68bc28c8af9",
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",
@@ -220,9 +220,21 @@ export const MigrationDonutChart: FC<MigrationDonutChartProps> = ({
220
220
  }));
221
221
  }, [data]);
222
222
 
223
- const colorScale = useMemo(() => {
224
- return chartData.map((item) => getColor(item.legendCategory));
225
- }, [chartData, getColor]);
223
+ // Victory renders zero-value slices as degenerate zero-angle wedges but still
224
+ // keeps a `padAngle` gap around each one.
225
+ const donutChartData = useMemo(
226
+ () => chartData.filter((item) => Number(item.y) > 0),
227
+ [chartData],
228
+ );
229
+
230
+ const donutColorScale = useMemo(
231
+ () => donutChartData.map((item) => getColor(item.legendCategory)),
232
+ [donutChartData, getColor],
233
+ );
234
+
235
+ // A lone slice has no neighbour to pad against; forcing padAngle to 0 keeps it
236
+ // from leaving a gap against itself.
237
+ const effectivePadAngle = donutChartData.length <= 1 ? 0 : padAngle;
226
238
 
227
239
  const legendData = useMemo(() => {
228
240
  return chartData.map((item) => ({
@@ -446,7 +458,7 @@ export const MigrationDonutChart: FC<MigrationDonutChartProps> = ({
446
458
  <div className={styles.donutWrapper}>
447
459
  <ChartDonut
448
460
  ariaDesc="Migration data donut chart"
449
- data={chartData}
461
+ data={donutChartData}
450
462
  events={chartEvents}
451
463
  labelComponent={donutTooltip}
452
464
  labels={({
@@ -459,10 +471,10 @@ export const MigrationDonutChart: FC<MigrationDonutChartProps> = ({
459
471
  countDisplay?: string | number;
460
472
  };
461
473
  }) => formatLabel(datum)}
462
- colorScale={colorScale}
474
+ colorScale={donutColorScale}
463
475
  constrainToVisibleArea
464
476
  innerRadius={innerRadius}
465
- padAngle={padAngle}
477
+ padAngle={effectivePadAngle}
466
478
  title={title}
467
479
  subTitle={subTitle}
468
480
  height={height}
@@ -0,0 +1,53 @@
1
+ import "@testing-library/jest-dom";
2
+ import { cleanup, render } from "@testing-library/react";
3
+ import { afterEach, describe, expect, it } from "vitest";
4
+ import {
5
+ MigrationDonutChart,
6
+ type MigrationDonutChartDatum,
7
+ } from "../MigrationDonutChart.js";
8
+
9
+ afterEach(() => cleanup());
10
+
11
+ /**
12
+ * Victory renders one `<path role="presentation">` per slice handed to ChartDonut.
13
+ * Only real pie slices carry an arc command (`A`) in their path data — legend
14
+ * symbols are squares — so filtering on it isolates the donut slices.
15
+ */
16
+ const sliceCount = (container: HTMLElement): number =>
17
+ Array.from(container.querySelectorAll("path[role='presentation']")).filter(
18
+ (path) => (path.getAttribute("d") ?? "").includes("A"),
19
+ ).length;
20
+
21
+ describe("MigrationDonutChart", () => {
22
+ it("does not render slices for zero-value categories", () => {
23
+ // Fixed-category chart (e.g. power states) where only one category is populated.
24
+ const data: MigrationDonutChartDatum[] = [
25
+ { name: "Powered on", count: 7, legendCategory: "Powered on" },
26
+ { name: "Powered off", count: 0, legendCategory: "Powered off" },
27
+ { name: "Standby", count: 0, legendCategory: "Standby" },
28
+ { name: "Not responding", count: 0, legendCategory: "Not responding" },
29
+ { name: "Maintenance", count: 0, legendCategory: "Maintenance" },
30
+ ];
31
+
32
+ const { container } = render(
33
+ <MigrationDonutChart data={data} legendVariant="chart" />,
34
+ );
35
+
36
+ // Only the single populated slice should be drawn, leaving no empty gap.
37
+ expect(sliceCount(container)).toBe(1);
38
+ });
39
+
40
+ it("renders one slice per populated category", () => {
41
+ const data: MigrationDonutChartDatum[] = [
42
+ { name: "Powered on", count: 5, legendCategory: "Powered on" },
43
+ { name: "Powered off", count: 3, legendCategory: "Powered off" },
44
+ { name: "Standby", count: 0, legendCategory: "Standby" },
45
+ ];
46
+
47
+ const { container } = render(
48
+ <MigrationDonutChart data={data} legendVariant="chart" />,
49
+ );
50
+
51
+ expect(sliceCount(container)).toBe(2);
52
+ });
53
+ });