@openshift-migration-advisor/shared-components 0.24.0 → 0.25.0-1701f64050d7
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/README.md +31 -0
- package/dist/charts/index.d.ts +1 -1
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/forms/RadioButtonFormGroup.d.ts.map +1 -1
- package/dist/forms/RadioButtonFormGroup.js +2 -2
- package/dist/report/ChartDownloadButton.d.ts +11 -0
- package/dist/report/ChartDownloadButton.d.ts.map +1 -0
- package/dist/report/ChartDownloadButton.js +24 -0
- package/dist/report/ChartExportProvider.d.ts +23 -0
- package/dist/report/ChartExportProvider.d.ts.map +1 -0
- package/dist/report/ChartExportProvider.js +222 -0
- package/dist/report/ChartExportSurface.d.ts +12 -0
- package/dist/report/ChartExportSurface.d.ts.map +1 -0
- package/dist/report/ChartExportSurface.js +32 -0
- package/dist/report/ErrorTable.d.ts +18 -0
- package/dist/report/ErrorTable.d.ts.map +1 -0
- package/dist/report/ErrorTable.js +20 -0
- package/dist/report/FeatureStatusBadge.d.ts +7 -0
- package/dist/report/FeatureStatusBadge.d.ts.map +1 -0
- package/dist/report/FeatureStatusBadge.js +13 -0
- package/dist/report/HostPowerStates.d.ts +8 -0
- package/dist/report/HostPowerStates.d.ts.map +1 -0
- package/dist/report/HostPowerStates.js +11 -0
- package/dist/report/HostsOverview.d.ts +13 -0
- package/dist/report/HostsOverview.d.ts.map +1 -0
- package/dist/report/HostsOverview.js +84 -0
- package/dist/report/InfrastructureSummary.d.ts +7 -0
- package/dist/report/InfrastructureSummary.d.ts.map +1 -0
- package/dist/report/InfrastructureSummary.js +9 -0
- package/dist/report/NetworkOverview.d.ts +31 -0
- package/dist/report/NetworkOverview.d.ts.map +1 -0
- package/dist/report/NetworkOverview.js +201 -0
- package/dist/report/OSDistribution.d.ts +0 -2
- package/dist/report/OSDistribution.d.ts.map +1 -1
- package/dist/report/OSDistribution.js +10 -15
- package/dist/report/OsSupportTiersHelpPopover.d.ts.map +1 -1
- package/dist/report/OsSupportTiersHelpPopover.js +2 -31
- package/dist/report/OsUpgradeNotice.d.ts.map +1 -1
- package/dist/report/OsUpgradeNotice.js +1 -5
- package/dist/report/OsUpgradeRecommendationPopover.d.ts +0 -1
- package/dist/report/OsUpgradeRecommendationPopover.d.ts.map +1 -1
- package/dist/report/OsUpgradeRecommendationPopover.js +4 -3
- package/dist/report/PowerStateCard.d.ts +16 -0
- package/dist/report/PowerStateCard.d.ts.map +1 -0
- package/dist/report/PowerStateCard.js +9 -0
- package/dist/report/ReportExportMenu.d.ts +19 -0
- package/dist/report/ReportExportMenu.d.ts.map +1 -0
- package/dist/report/ReportExportMenu.js +31 -0
- package/dist/report/ReportTable.d.ts +14 -0
- package/dist/report/ReportTable.d.ts.map +1 -0
- package/dist/report/ReportTable.js +23 -0
- package/dist/report/SupportTierBadge.d.ts +0 -1
- package/dist/report/SupportTierBadge.d.ts.map +1 -1
- package/dist/report/SupportTierBadge.js +1 -19
- package/dist/report/VCenterClusterDetails.d.ts +9 -0
- package/dist/report/VCenterClusterDetails.d.ts.map +1 -0
- package/dist/report/VCenterClusterDetails.js +31 -0
- package/dist/report/VmPowerStates.d.ts +8 -0
- package/dist/report/VmPowerStates.d.ts.map +1 -0
- package/dist/report/VmPowerStates.js +11 -0
- package/dist/report/WarningsTable.d.ts +9 -0
- package/dist/report/WarningsTable.d.ts.map +1 -0
- package/dist/report/WarningsTable.js +20 -0
- package/dist/report/captureChartElement.d.ts +8 -0
- package/dist/report/captureChartElement.d.ts.map +1 -0
- package/dist/report/captureChartElement.js +284 -0
- package/dist/report/chartExport.d.ts +73 -0
- package/dist/report/chartExport.d.ts.map +1 -0
- package/dist/report/chartExport.js +162 -0
- package/dist/report/chartExportContext.d.ts +32 -0
- package/dist/report/chartExportContext.d.ts.map +1 -0
- package/dist/report/chartExportContext.js +36 -0
- package/dist/report/chartExportFilenames.d.ts +4 -0
- package/dist/report/chartExportFilenames.d.ts.map +1 -0
- package/dist/report/chartExportFilenames.js +16 -0
- package/dist/report/constants.d.ts +4 -0
- package/dist/report/constants.d.ts.map +1 -1
- package/dist/report/constants.js +4 -0
- package/dist/report/dashboardStyles.d.ts +0 -4
- package/dist/report/dashboardStyles.d.ts.map +1 -1
- package/dist/report/dashboardStyles.js +0 -19
- package/dist/report/htmlExport.d.ts +9 -0
- package/dist/report/htmlExport.d.ts.map +1 -0
- package/dist/report/htmlExport.js +65 -0
- package/dist/report/index.d.ts +28 -0
- package/dist/report/index.d.ts.map +1 -1
- package/dist/report/index.js +26 -0
- package/dist/report/infrastructureSummaryModel.d.ts +82 -0
- package/dist/report/infrastructureSummaryModel.d.ts.map +1 -0
- package/dist/report/infrastructureSummaryModel.js +139 -0
- package/dist/report/pdfExport.d.ts +3 -0
- package/dist/report/pdfExport.d.ts.map +1 -0
- package/dist/report/pdfExport.js +131 -0
- package/dist/report/pdfPage.d.ts +15 -0
- package/dist/report/pdfPage.d.ts.map +1 -0
- package/dist/report/pdfPage.js +44 -0
- package/dist/report/powerStates.d.ts +11 -0
- package/dist/report/powerStates.d.ts.map +1 -0
- package/dist/report/powerStates.js +113 -0
- package/dist/report/reportExportOptions.d.ts +17 -0
- package/dist/report/reportExportOptions.d.ts.map +1 -0
- package/dist/report/reportExportOptions.js +31 -0
- package/dist/report/zipChartPngs.d.ts +3 -0
- package/dist/report/zipChartPngs.d.ts.map +1 -0
- package/dist/report/zipChartPngs.js +8 -0
- package/package.json +7 -2
- package/src/charts/index.ts +1 -0
- package/src/forms/RadioButtonFormGroup.tsx +10 -3
- package/src/report/ChartDownloadButton.tsx +59 -0
- package/src/report/ChartExportProvider.tsx +392 -0
- package/src/report/ChartExportSurface.tsx +60 -0
- package/src/report/ErrorTable.tsx +85 -0
- package/src/report/FeatureStatusBadge.tsx +30 -0
- package/src/report/HostPowerStates.tsx +38 -0
- package/src/report/HostsOverview.tsx +185 -0
- package/src/report/InfrastructureSummary.tsx +73 -0
- package/src/report/NetworkOverview.tsx +405 -0
- package/src/report/OSDistribution.tsx +96 -99
- package/src/report/OsSupportTiersHelpPopover.tsx +32 -62
- package/src/report/OsUpgradeNotice.tsx +1 -7
- package/src/report/OsUpgradeRecommendationPopover.tsx +3 -4
- package/src/report/PowerStateCard.tsx +86 -0
- package/src/report/ReportExportMenu.tsx +119 -0
- package/src/report/ReportTable.tsx +81 -0
- package/src/report/SupportTierBadge.tsx +12 -38
- package/src/report/VCenterClusterDetails.tsx +233 -0
- package/src/report/VmPowerStates.tsx +38 -0
- package/src/report/WarningsTable.tsx +75 -0
- package/src/report/__tests__/ChartExportProvider.test.tsx +542 -0
- package/src/report/__tests__/HostPowerStates.test.tsx +47 -0
- package/src/report/__tests__/HostsOverview.test.tsx +145 -0
- package/src/report/__tests__/InfrastructureSummary.test.tsx +126 -0
- package/src/report/__tests__/NetworkOverview.test.tsx +269 -0
- package/src/report/__tests__/OSDistribution.test.tsx +10 -11
- package/src/report/__tests__/captureChartElement.test.ts +132 -0
- package/src/report/__tests__/chartExportPackagers.test.ts +282 -0
- package/src/report/__tests__/infrastructureSummaryModel.test.ts +224 -0
- package/src/report/__tests__/powerStates.test.ts +70 -0
- package/src/report/captureChartElement.ts +368 -0
- package/src/report/chartExport.ts +255 -0
- package/src/report/chartExportContext.tsx +92 -0
- package/src/report/chartExportFilenames.ts +21 -0
- package/src/report/constants.ts +4 -0
- package/src/report/dashboardStyles.ts +0 -23
- package/src/report/htmlExport.ts +83 -0
- package/src/report/index.ts +154 -0
- package/src/report/infrastructureSummaryModel.ts +281 -0
- package/src/report/pdfExport.ts +233 -0
- package/src/report/pdfPage.ts +83 -0
- package/src/report/powerStates.ts +169 -0
- package/src/report/reportExportOptions.ts +53 -0
- package/src/report/zipChartPngs.ts +10 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Card, CardBody, CardTitle, DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm, Flex, FlexItem, } from "@patternfly/react-core";
|
|
3
|
+
import { ChartHeaderActions } from "./ChartDownloadButton.js";
|
|
4
|
+
import { ChartExportSurface } from "./ChartExportSurface.js";
|
|
5
|
+
const formatCount = (value) => typeof value === "number" ? String(value) : "—";
|
|
6
|
+
const INFRA_CHART_ID = "infrastructure-summary";
|
|
7
|
+
const INFRA_TITLE = "Infrastructure summary";
|
|
8
|
+
export const InfrastructureSummary = ({ summary, }) => (_jsx(ChartExportSurface, { id: INFRA_CHART_ID, title: INFRA_TITLE, children: _jsxs(Card, { isFullHeight: true, children: [_jsx(CardTitle, { children: _jsxs(Flex, { justifyContent: { default: "justifyContentSpaceBetween" }, alignItems: { default: "alignItemsCenter" }, children: [_jsx(FlexItem, { children: INFRA_TITLE }), _jsx(ChartHeaderActions, { chartId: INFRA_CHART_ID, title: INFRA_TITLE })] }) }), _jsx(CardBody, { children: _jsxs(DescriptionList, { isAutoFit: true, displaySize: "lg", children: [_jsxs(DescriptionListGroup, { children: [_jsx(DescriptionListTerm, { children: "VMware version" }), _jsx(DescriptionListDescription, { children: summary.vmwareVersion })] }), _jsxs(DescriptionListGroup, { children: [_jsx(DescriptionListTerm, { children: "Datacenters" }), _jsx(DescriptionListDescription, { children: formatCount(summary.datacenters) })] }), _jsxs(DescriptionListGroup, { children: [_jsx(DescriptionListTerm, { children: "vCenters" }), _jsx(DescriptionListDescription, { children: formatCount(summary.vCenters) })] }), _jsxs(DescriptionListGroup, { children: [_jsx(DescriptionListTerm, { children: "ESXi hosts" }), _jsx(DescriptionListDescription, { children: formatCount(summary.esxiHosts) })] })] }) })] }) }));
|
|
9
|
+
InfrastructureSummary.displayName = "InfrastructureSummary";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { FC } from "react";
|
|
2
|
+
import { type MigrationDonutChartLegendVariant } from "../charts/MigrationDonutChart.js";
|
|
3
|
+
/** Network fields this card reads. Apps pass SDK networks structurally. */
|
|
4
|
+
export interface NetworkLike {
|
|
5
|
+
vmsCount?: number;
|
|
6
|
+
vlanId?: string | number;
|
|
7
|
+
}
|
|
8
|
+
/** Infra fields this card reads. */
|
|
9
|
+
export interface NetworkInfraLike {
|
|
10
|
+
networks?: NetworkLike[];
|
|
11
|
+
}
|
|
12
|
+
/** Deprecated NIC histogram used when `distributionByNicCount` is absent. */
|
|
13
|
+
export interface NicCountHistogram {
|
|
14
|
+
data?: number[];
|
|
15
|
+
minValue?: number;
|
|
16
|
+
step?: number;
|
|
17
|
+
}
|
|
18
|
+
/** NIC summary fields this card reads from the VM resource breakdown. */
|
|
19
|
+
export interface NicCountSummary {
|
|
20
|
+
total?: number;
|
|
21
|
+
histogram?: NicCountHistogram;
|
|
22
|
+
}
|
|
23
|
+
export interface NetworkOverviewProps {
|
|
24
|
+
infra?: NetworkInfraLike;
|
|
25
|
+
nicCount?: NicCountSummary;
|
|
26
|
+
distributionByNicCount?: Record<string, number>;
|
|
27
|
+
/** `"html"` in agent-ui; ui-app passes `"chart"`. */
|
|
28
|
+
legendVariant?: MigrationDonutChartLegendVariant;
|
|
29
|
+
}
|
|
30
|
+
export declare const NetworkOverview: FC<NetworkOverviewProps>;
|
|
31
|
+
//# sourceMappingURL=NetworkOverview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkOverview.d.ts","sourceRoot":"","sources":["../../src/report/NetworkOverview.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,EAAE,EAAO,MAAM,OAAO,CAAC;AAErC,OAAO,EAGL,KAAK,gCAAgC,EACtC,MAAM,kCAAkC,CAAC;AAQ1C,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED,oCAAoC;AACpC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,qDAAqD;IACrD,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAClD;AAiND,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CA2HpD,CAAC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { css } from "@emotion/css";
|
|
3
|
+
import { Card, CardBody, CardTitle, Dropdown, DropdownItem, DropdownList, Flex, FlexItem, MenuToggle, } from "@patternfly/react-core";
|
|
4
|
+
import { TopologyIcon } from "@patternfly/react-icons";
|
|
5
|
+
import { chart_color_black_500, chart_color_blue_300, chart_color_green_300, chart_color_orange_100, chart_color_purple_100, chart_color_purple_300, chart_color_red_orange_200, chart_color_teal_200, chart_color_teal_400, 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 { REPORT_CARD_EMPTY_STATE_TITLES } from "./constants.js";
|
|
13
|
+
import { dashboardStyles } from "./dashboardStyles.js";
|
|
14
|
+
const VIEW_MODE_LABELS = {
|
|
15
|
+
networkDistribution: "VM distribution by network",
|
|
16
|
+
nicCount: "VM distribution by NIC count",
|
|
17
|
+
};
|
|
18
|
+
const TOP_NETWORKS = 4;
|
|
19
|
+
const REST_OF_NETWORKS_LABEL = "Rest of networks";
|
|
20
|
+
const CHART_ID = "network-overview";
|
|
21
|
+
const CHART_TITLE = "Networks";
|
|
22
|
+
/**
|
|
23
|
+
* Categorical order from the ui-app network donut, mapped onto PatternFly
|
|
24
|
+
* `chart_color_*` tokens (nearest token where the old hex was not a token).
|
|
25
|
+
*/
|
|
26
|
+
const NETWORK_COLORS = [
|
|
27
|
+
chart_color_blue_300.value,
|
|
28
|
+
chart_color_purple_300.value,
|
|
29
|
+
chart_color_purple_100.value,
|
|
30
|
+
chart_color_teal_200.value,
|
|
31
|
+
chart_color_yellow_400.value,
|
|
32
|
+
chart_color_green_300.value,
|
|
33
|
+
chart_color_orange_100.value,
|
|
34
|
+
chart_color_red_orange_200.value,
|
|
35
|
+
chart_color_teal_400.value,
|
|
36
|
+
chart_color_black_500.value,
|
|
37
|
+
];
|
|
38
|
+
const cardSubtitle = css `
|
|
39
|
+
color: var(--pf-t--global--text--color--subtle);
|
|
40
|
+
font-size: 0.85rem;
|
|
41
|
+
`;
|
|
42
|
+
const menuToggleMinWidth = css `
|
|
43
|
+
min-width: 250px;
|
|
44
|
+
`;
|
|
45
|
+
const titleRow = css `
|
|
46
|
+
width: 100%;
|
|
47
|
+
`;
|
|
48
|
+
const isViewMode = (value) => value === "networkDistribution" || value === "nicCount";
|
|
49
|
+
const legendFor = (categories) => {
|
|
50
|
+
const legend = {};
|
|
51
|
+
categories.forEach((category, index) => {
|
|
52
|
+
const color = NETWORK_COLORS[index % NETWORK_COLORS.length];
|
|
53
|
+
if (color) {
|
|
54
|
+
legend[category] = color;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return legend;
|
|
58
|
+
};
|
|
59
|
+
const vlanLabel = (vlanId) => {
|
|
60
|
+
if (typeof vlanId !== "string" && typeof vlanId !== "number") {
|
|
61
|
+
return "-";
|
|
62
|
+
}
|
|
63
|
+
const value = String(vlanId).trim();
|
|
64
|
+
return value !== "" ? value : "-";
|
|
65
|
+
};
|
|
66
|
+
const buildNetworkDonut = (networks) => {
|
|
67
|
+
const items = (Array.isArray(networks) ? networks : [])
|
|
68
|
+
.map((network) => ({
|
|
69
|
+
vmsCount: typeof network?.vmsCount === "number" ? network.vmsCount : Number.NaN,
|
|
70
|
+
vlanId: vlanLabel(network?.vlanId),
|
|
71
|
+
}))
|
|
72
|
+
.filter((network) => Number.isFinite(network.vmsCount) && network.vmsCount >= 0)
|
|
73
|
+
.sort((a, b) => b.vmsCount - a.vmsCount);
|
|
74
|
+
const totalVMs = items.reduce((sum, network) => sum + network.vmsCount, 0);
|
|
75
|
+
const top = items.slice(0, TOP_NETWORKS);
|
|
76
|
+
const restSum = items
|
|
77
|
+
.slice(TOP_NETWORKS)
|
|
78
|
+
.reduce((sum, network) => sum + network.vmsCount, 0);
|
|
79
|
+
const vlanBySlice = {};
|
|
80
|
+
const slices = top.map((network, index) => {
|
|
81
|
+
const name = `Network ${index + 1}`;
|
|
82
|
+
vlanBySlice[name] = network.vlanId;
|
|
83
|
+
return {
|
|
84
|
+
name,
|
|
85
|
+
count: network.vmsCount,
|
|
86
|
+
countDisplay: `${network.vmsCount} VMs`,
|
|
87
|
+
legendCategory: name,
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
if (restSum > 0) {
|
|
91
|
+
slices.push({
|
|
92
|
+
name: REST_OF_NETWORKS_LABEL,
|
|
93
|
+
count: restSum,
|
|
94
|
+
countDisplay: `${restSum} VMs`,
|
|
95
|
+
legendCategory: REST_OF_NETWORKS_LABEL,
|
|
96
|
+
});
|
|
97
|
+
vlanBySlice[REST_OF_NETWORKS_LABEL] = "-";
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
slices,
|
|
101
|
+
legend: legendFor(slices.map((slice) => slice.legendCategory)),
|
|
102
|
+
title: `${totalVMs}`,
|
|
103
|
+
vlanBySlice,
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
const nicBucketLabel = (bucket) => {
|
|
107
|
+
const count = Number.parseInt(bucket, 10);
|
|
108
|
+
if (bucket.endsWith("+")) {
|
|
109
|
+
return `${count}+ NIC`;
|
|
110
|
+
}
|
|
111
|
+
return count === 1 ? "1 NIC" : `${count} NIC`;
|
|
112
|
+
};
|
|
113
|
+
const compareNicBuckets = (a, b) => {
|
|
114
|
+
const aPlus = a.bucket.endsWith("+");
|
|
115
|
+
const bPlus = b.bucket.endsWith("+");
|
|
116
|
+
if (aPlus !== bPlus) {
|
|
117
|
+
return aPlus ? 1 : -1;
|
|
118
|
+
}
|
|
119
|
+
const aNum = Number.parseInt(a.bucket, 10);
|
|
120
|
+
const bNum = Number.parseInt(b.bucket, 10);
|
|
121
|
+
if (Number.isFinite(aNum) && Number.isFinite(bNum)) {
|
|
122
|
+
return aNum - bNum;
|
|
123
|
+
}
|
|
124
|
+
return a.bucket.localeCompare(b.bucket);
|
|
125
|
+
};
|
|
126
|
+
const slicesFromBuckets = (entries) => entries.map((entry) => {
|
|
127
|
+
const label = nicBucketLabel(entry.bucket);
|
|
128
|
+
return {
|
|
129
|
+
name: label,
|
|
130
|
+
count: entry.count,
|
|
131
|
+
countDisplay: `${entry.count} VMs`,
|
|
132
|
+
legendCategory: label,
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
const buildNicDonut = (distributionByNicCount, nicCount) => {
|
|
136
|
+
if (distributionByNicCount != null) {
|
|
137
|
+
const entries = Object.entries(distributionByNicCount)
|
|
138
|
+
.map(([bucket, value]) => ({
|
|
139
|
+
bucket,
|
|
140
|
+
count: Number.isFinite(Number(value)) ? Number(value) : 0,
|
|
141
|
+
}))
|
|
142
|
+
.filter((entry) => entry.count > 0)
|
|
143
|
+
.sort(compareNicBuckets);
|
|
144
|
+
const slices = slicesFromBuckets(entries);
|
|
145
|
+
const total = entries.reduce((sum, entry) => sum + entry.count, 0);
|
|
146
|
+
return {
|
|
147
|
+
slices,
|
|
148
|
+
legend: legendFor(slices.map((slice) => slice.legendCategory)),
|
|
149
|
+
title: `${total}`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const histogram = nicCount?.histogram;
|
|
153
|
+
const data = Array.isArray(histogram?.data) ? histogram.data : [];
|
|
154
|
+
const minValue = typeof histogram?.minValue === "number" ? histogram.minValue : 0;
|
|
155
|
+
const step = typeof histogram?.step === "number" ? histogram.step : 1;
|
|
156
|
+
const buckets = data
|
|
157
|
+
.map((count, index) => ({
|
|
158
|
+
bucket: String(minValue + index * step),
|
|
159
|
+
count: Number(count) || 0,
|
|
160
|
+
}))
|
|
161
|
+
.filter((entry) => entry.count > 0)
|
|
162
|
+
.sort((a, b) => Number(a.bucket) - Number(b.bucket));
|
|
163
|
+
const slices = slicesFromBuckets(buckets);
|
|
164
|
+
const total = typeof nicCount?.total === "number"
|
|
165
|
+
? nicCount.total
|
|
166
|
+
: buckets.reduce((sum, entry) => sum + entry.count, 0);
|
|
167
|
+
return {
|
|
168
|
+
slices,
|
|
169
|
+
legend: legendFor(slices.map((slice) => slice.legendCategory)),
|
|
170
|
+
title: `${total}`,
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
export const NetworkOverview = ({ infra, nicCount, distributionByNicCount, legendVariant = "html", }) => {
|
|
174
|
+
const [viewMode, setViewMode] = useState("networkDistribution");
|
|
175
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
176
|
+
const networkChart = useMemo(() => buildNetworkDonut(infra?.networks), [infra?.networks]);
|
|
177
|
+
const nicChart = useMemo(() => buildNicDonut(distributionByNicCount, nicCount), [distributionByNicCount, nicCount]);
|
|
178
|
+
const chartTitle = `${CHART_TITLE} — ${VIEW_MODE_LABELS[viewMode]}`;
|
|
179
|
+
const activeChart = viewMode === "networkDistribution" ? networkChart : nicChart;
|
|
180
|
+
const emptyTitle = viewMode === "networkDistribution"
|
|
181
|
+
? REPORT_CARD_EMPTY_STATE_TITLES.networks
|
|
182
|
+
: REPORT_CARD_EMPTY_STATE_TITLES.nicCount;
|
|
183
|
+
return (_jsx(ChartExportSurface, { id: CHART_ID, title: chartTitle, exportViews: chartExportViewsFromLabels(CHART_TITLE, VIEW_MODE_LABELS), activeExportViewId: viewMode, onExportViewChange: (viewId) => {
|
|
184
|
+
if (isViewMode(viewId)) {
|
|
185
|
+
setViewMode(viewId);
|
|
186
|
+
}
|
|
187
|
+
}, children: _jsxs(Card, { className: dashboardStyles.card, children: [_jsx(CardTitle, { children: _jsxs(Flex, { className: titleRow, justifyContent: { default: "justifyContentSpaceBetween" }, alignItems: { default: "alignItemsCenter" }, children: [_jsx(FlexItem, { children: _jsxs("div", { children: [_jsxs("div", { children: [_jsx(TopologyIcon, {}), " ", CHART_TITLE] }), viewMode === "networkDistribution" && (_jsx("div", { className: cardSubtitle, children: "Top 5 networks" }))] }) }), _jsx(ChartHeaderActions, { chartId: CHART_ID, title: chartTitle, children: _jsx(Dropdown, { isOpen: isDropdownOpen, onSelect: (_event, value) => {
|
|
188
|
+
if (isViewMode(value)) {
|
|
189
|
+
setViewMode(value);
|
|
190
|
+
}
|
|
191
|
+
setIsDropdownOpen(false);
|
|
192
|
+
}, 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: "networkDistribution", children: VIEW_MODE_LABELS.networkDistribution }, "networkDistribution"), _jsx(DropdownItem, { value: "nicCount", children: VIEW_MODE_LABELS.nicCount }, "nicCount")] }) }) })] }) }), _jsx(CardBody, { className: dashboardStyles.cardBodyScrollable, children: activeChart.slices.length === 0 ? (_jsx(CardEmptyState, { title: emptyTitle })) : (_jsx(MigrationDonutChart, { legendVariant: legendVariant, data: activeChart.slices, legend: activeChart.legend, height: 300, width: 420, donutThickness: 18, titleFontSize: 34, title: activeChart.title, subTitle: "VMs", subTitleColor: "var(--pf-t--global--text--color--subtle)", itemsPerRow: Math.ceil(activeChart.slices.length / 2), labelFontSize: 18, marginLeft: "0%", tooltipLabelFormatter: ({ datum, percent }) => {
|
|
193
|
+
const summary = `${datum.countDisplay}\n${percent.toFixed(1)}%`;
|
|
194
|
+
if (viewMode !== "networkDistribution") {
|
|
195
|
+
return summary;
|
|
196
|
+
}
|
|
197
|
+
const vlan = networkChart.vlanBySlice[datum.legendCategory];
|
|
198
|
+
return `${summary}\nVLAN: ${vlan ?? "-"}`;
|
|
199
|
+
} })) })] }) }));
|
|
200
|
+
};
|
|
201
|
+
NetworkOverview.displayName = "NetworkOverview";
|
|
@@ -2,12 +2,10 @@ import type { FC } from "react";
|
|
|
2
2
|
import { type OSDistributionEntry } from "./osSupportTier.js";
|
|
3
3
|
interface OSDistributionProps {
|
|
4
4
|
osData: Record<string, OSDistributionEntry>;
|
|
5
|
-
isExportMode?: boolean;
|
|
6
5
|
}
|
|
7
6
|
export declare const OSDistribution: FC<OSDistributionProps>;
|
|
8
7
|
interface OSBarChartProps {
|
|
9
8
|
osData: Record<string, OSDistributionEntry>;
|
|
10
|
-
isExportMode?: boolean;
|
|
11
9
|
}
|
|
12
10
|
export declare const OSBarChart: FC<OSBarChartProps>;
|
|
13
11
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OSDistribution.d.ts","sourceRoot":"","sources":["../../src/report/OSDistribution.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OSDistribution.d.ts","sourceRoot":"","sources":["../../src/report/OSDistribution.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,EAAE,EAAO,MAAM,OAAO,CAAC;AAWrC,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAe5B,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC7C;AAED,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAmClD,CAAC;AAEF,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC7C;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CA0G1C,CAAC"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { css } from "@emotion/css";
|
|
3
|
-
import { Card, CardBody, CardTitle, Flex, FlexItem, MenuToggle, SearchInput, Select, SelectList, SelectOption, Toolbar, ToolbarContent, ToolbarItem, } from "@patternfly/react-core";
|
|
3
|
+
import { Card, CardBody, CardTitle, Flex, FlexItem, MenuToggle, SearchInput, Select, SelectList, SelectOption, Stack, StackItem, Toolbar, ToolbarContent, ToolbarItem, } from "@patternfly/react-core";
|
|
4
4
|
import { DesktopIcon } from "@patternfly/react-icons";
|
|
5
5
|
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
|
|
6
6
|
import { CardEmptyState } from "./CardEmptyState.js";
|
|
7
|
+
import { ChartHeaderActions } from "./ChartDownloadButton.js";
|
|
8
|
+
import { ChartExportSurface } from "./ChartExportSurface.js";
|
|
9
|
+
import { chartExportHideProps, chartExportScrollProps } from "./chartExport.js";
|
|
7
10
|
import { REPORT_CARD_EMPTY_STATE_TITLES } from "./constants.js";
|
|
8
11
|
import { dashboardStyles, tableFullWidthStyle } from "./dashboardStyles.js";
|
|
9
12
|
import { EmptySearchResults } from "./EmptySearchResults.js";
|
|
@@ -13,25 +16,17 @@ import { OsNameCell } from "./OsUpgradeRecommendationPopover.js";
|
|
|
13
16
|
import { getSupportTierLegendLabel, ORDERED_SUPPORT_TIERS, } from "./osSupportTier.js";
|
|
14
17
|
import { SupportTierBadge } from "./SupportTierBadge.js";
|
|
15
18
|
import { ALL_TIERS_FILTER, useOsBarChartViewModel, } from "./useOsBarChartViewModel.js";
|
|
16
|
-
const filterToolbarStyle = css `
|
|
17
|
-
padding-left: 0;
|
|
18
|
-
padding-right: 0;
|
|
19
|
-
`;
|
|
20
|
-
const filterItemStyle = css `
|
|
21
|
-
flex: 1 1 0;
|
|
22
|
-
min-width: 0;
|
|
23
|
-
`;
|
|
24
|
-
const vmsColumnStyle = css `
|
|
25
|
-
text-align: right;
|
|
26
|
-
`;
|
|
27
19
|
const tableScrollStyle = css `
|
|
28
20
|
overflow: auto;
|
|
21
|
+
max-height: 350px;
|
|
29
22
|
`;
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
const OS_DISTRIBUTION_CHART_ID = "os-distribution";
|
|
24
|
+
const OS_DISTRIBUTION_TITLE = "Operating system distribution";
|
|
25
|
+
export const OSDistribution = ({ osData }) => (_jsx(ChartExportSurface, { id: OS_DISTRIBUTION_CHART_ID, title: OS_DISTRIBUTION_TITLE, children: _jsxs(Card, { className: dashboardStyles.card, children: [_jsx(CardTitle, { children: _jsxs(Flex, { justifyContent: { default: "justifyContentSpaceBetween" }, alignItems: { default: "alignItemsCenter" }, children: [_jsx(FlexItem, { children: _jsxs(Flex, { alignItems: { default: "alignItemsCenter" }, spaceItems: { default: "spaceItemsSm" }, children: [_jsxs(FlexItem, { children: [_jsx(DesktopIcon, {}), " Operating Systems"] }), _jsx(FlexItem, { ...chartExportHideProps, children: _jsx(OsSupportTiersHelpPopover, {}) })] }) }), _jsx(ChartHeaderActions, { chartId: OS_DISTRIBUTION_CHART_ID, title: OS_DISTRIBUTION_TITLE })] }) }), _jsx(CardBody, { children: _jsx(OSBarChart, { osData: osData }) })] }) }));
|
|
26
|
+
export const OSBarChart = ({ osData }) => {
|
|
32
27
|
const vm = useOsBarChartViewModel(osData);
|
|
33
28
|
if (vm.tableRows.length === 0) {
|
|
34
29
|
return (_jsx(CardEmptyState, { title: REPORT_CARD_EMPTY_STATE_TITLES.operatingSystems }));
|
|
35
30
|
}
|
|
36
|
-
return (_jsxs(_Fragment, { children: [
|
|
31
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { ...chartExportHideProps, children: _jsx(Toolbar, { hasNoPadding: true, children: _jsxs(ToolbarContent, { children: [_jsx(ToolbarItem, { children: _jsx(SearchInput, { placeholder: "Filter by OS", value: vm.osFilter, onChange: (_event, value) => vm.setOsFilter(value), onClear: vm.clearOsFilter, "aria-label": "Filter operating systems by name" }) }), _jsx(ToolbarItem, { children: _jsx(Select, { isOpen: vm.isTierSelectOpen, selected: vm.tierFilter, onSelect: vm.handleTierSelect, onOpenChange: vm.setIsTierSelectOpen, toggle: (toggleRef) => (_jsx(MenuToggle, { ref: toggleRef, isExpanded: vm.isTierSelectOpen, onClick: vm.toggleTierSelectOpen, isFullWidth: true, children: vm.tierFilterLabel })), "aria-label": "Filter operating systems by support tier", children: _jsxs(SelectList, { children: [_jsx(SelectOption, { value: ALL_TIERS_FILTER, children: "All tiers" }), ORDERED_SUPPORT_TIERS.map((tier) => (_jsx(SelectOption, { value: tier, children: getSupportTierLegendLabel(tier) }, tier)))] }) }) })] }) }) }), _jsxs(Stack, { hasGutter: true, children: [vm.showUpgradeNotice ? (_jsx(StackItem, { children: _jsx(OsUpgradeNotice, {}) })) : null, _jsx(StackItem, { children: _jsx("div", { className: `${tableScrollStyle} ${tableFullWidthStyle}`, ...chartExportScrollProps, children: _jsxs(Table, { "aria-label": "Operating systems", variant: "compact", children: [_jsx(Thead, { children: _jsxs(Tr, { children: [_jsx(Th, { children: "OS" }), _jsx(Th, { children: "Tier" }), _jsx(Th, { children: "VMs" })] }) }), _jsx(Tbody, { children: vm.showNoResults ? (_jsx(Tr, { children: _jsx(Td, { colSpan: 3, children: _jsx(EmptySearchResults, { title: "No matching operating system found" }) }) })) : (vm.filteredRows.map((row) => (_jsxs(Tr, { children: [_jsx(Td, { dataLabel: "OS", children: _jsx(OsNameCell, { osName: row.osName, upgradeRecommendation: row.upgradeRecommendation }) }), _jsx(Td, { dataLabel: "Tier", children: _jsx(SupportTierBadge, { tier: row.tier }) }), _jsx(Td, { dataLabel: "VMs", children: row.count })] }, row.osName)))) })] }) }) })] })] }));
|
|
37
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OsSupportTiersHelpPopover.d.ts","sourceRoot":"","sources":["../../src/report/OsSupportTiersHelpPopover.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OsSupportTiersHelpPopover.d.ts","sourceRoot":"","sources":["../../src/report/OsSupportTiersHelpPopover.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAsChC,eAAO,MAAM,yBAAyB,EAAE,EASvC,CAAC"}
|
|
@@ -1,37 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { Label } from "@patternfly/react-core";
|
|
2
|
+
import { Button, Content, Label, Stack, StackItem, } from "@patternfly/react-core";
|
|
4
3
|
import { ExternalLinkAltIcon } from "@patternfly/react-icons";
|
|
5
4
|
import { getSupportTierBadgeColor, getSupportTierDefinition, getSupportTierLegendLabel, ORDERED_SUPPORT_TIERS, SUPPORT_TIER_LEARN_MORE_URL, } from "./osSupportTier.js";
|
|
6
5
|
import PopoverIcon from "./PopoverIcon.js";
|
|
7
|
-
const
|
|
8
|
-
list-style: none;
|
|
9
|
-
padding: 0;
|
|
10
|
-
margin: 0;
|
|
11
|
-
display: flex;
|
|
12
|
-
flex-direction: column;
|
|
13
|
-
gap: var(--pf-t--global--spacer--400);
|
|
14
|
-
`;
|
|
15
|
-
const tierItemStyle = css `
|
|
16
|
-
display: flex;
|
|
17
|
-
flex-direction: column;
|
|
18
|
-
gap: var(--pf-t--global--spacer--100);
|
|
19
|
-
`;
|
|
20
|
-
const tierBadgeStyle = css `
|
|
21
|
-
width: fit-content;
|
|
22
|
-
max-width: 100%;
|
|
23
|
-
align-self: flex-start;
|
|
24
|
-
`;
|
|
25
|
-
const tierDescriptionStyle = css `
|
|
26
|
-
margin: 0;
|
|
27
|
-
color: var(--pf-t--global--text--color--regular);
|
|
28
|
-
`;
|
|
29
|
-
const learnMoreLinkStyle = css `
|
|
30
|
-
display: inline-flex;
|
|
31
|
-
align-items: center;
|
|
32
|
-
gap: var(--pf-t--global--spacer--xs);
|
|
33
|
-
margin-top: var(--pf-t--global--spacer--400);
|
|
34
|
-
`;
|
|
35
|
-
const OsSupportTiersHelpBody = () => (_jsxs("div", { children: [_jsx("ul", { className: tierListStyle, children: ORDERED_SUPPORT_TIERS.map((tier) => (_jsxs("li", { className: tierItemStyle, children: [_jsx(Label, { className: tierBadgeStyle, color: getSupportTierBadgeColor(tier), isCompact: true, children: getSupportTierLegendLabel(tier) }), _jsx("p", { className: tierDescriptionStyle, children: getSupportTierDefinition(tier) })] }, tier))) }), _jsxs("a", { "aria-label": "Learn more about operating system support tiers", className: learnMoreLinkStyle, href: SUPPORT_TIER_LEARN_MORE_URL, target: "_blank", rel: "noopener noreferrer", children: ["Learn more ", _jsx(ExternalLinkAltIcon, {})] })] }));
|
|
6
|
+
const OsSupportTiersHelpBody = () => (_jsxs(Stack, { hasGutter: true, children: [ORDERED_SUPPORT_TIERS.map((tier) => (_jsxs(StackItem, { children: [_jsx(Label, { color: getSupportTierBadgeColor(tier), isCompact: true, children: getSupportTierLegendLabel(tier) }), _jsx(Content, { component: "p", children: getSupportTierDefinition(tier) })] }, tier))), _jsx(StackItem, { children: _jsx(Button, { variant: "link", isInline: true, component: "a", href: SUPPORT_TIER_LEARN_MORE_URL, target: "_blank", rel: "noopener noreferrer", icon: _jsx(ExternalLinkAltIcon, {}), iconPosition: "end", "aria-label": "Learn more about operating system support tiers", children: "Learn more" }) })] }));
|
|
36
7
|
export const OsSupportTiersHelpPopover = () => (_jsx(PopoverIcon, { noVerticalAlign: true, maxWidth: "40rem", headerContent: "Guest OS support tiers", bodyContent: _jsx(OsSupportTiersHelpBody, {}), buttonOuiaId: "guest-os-support-tiers-help", "aria-label": "Guest OS support tiers help" }));
|
|
37
8
|
OsSupportTiersHelpPopover.displayName = "OsSupportTiersHelpPopover";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OsUpgradeNotice.d.ts","sourceRoot":"","sources":["../../src/report/OsUpgradeNotice.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OsUpgradeNotice.d.ts","sourceRoot":"","sources":["../../src/report/OsUpgradeNotice.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,eAAO,MAAM,eAAe,EAAE,EAgB7B,CAAC"}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { css } from "@emotion/css";
|
|
3
2
|
import { Content, Flex, FlexItem, Icon } from "@patternfly/react-core";
|
|
4
3
|
import { InfoCircleIcon } from "@patternfly/react-icons";
|
|
5
|
-
const
|
|
6
|
-
margin-bottom: var(--pf-t--global--spacer--200);
|
|
7
|
-
`;
|
|
8
|
-
export const OsUpgradeNotice = () => (_jsxs(Flex, { alignItems: { default: "alignItemsCenter" }, spaceItems: { default: "spaceItemsSm" }, className: noticeStyle, children: [_jsx(FlexItem, { children: _jsx(Icon, { status: "info", children: _jsx(InfoCircleIcon, {}) }) }), _jsx(FlexItem, { children: _jsx(Content, { component: "p", style: { fontWeight: 500 }, children: "Some operating systems may need upgrades before migration" }) })] }));
|
|
4
|
+
export const OsUpgradeNotice = () => (_jsxs(Flex, { alignItems: { default: "alignItemsCenter" }, spaceItems: { default: "spaceItemsSm" }, children: [_jsx(FlexItem, { children: _jsx(Icon, { status: "info", children: _jsx(InfoCircleIcon, {}) }) }), _jsx(FlexItem, { children: _jsx(Content, { component: "p", children: "Some operating systems may need upgrades before migration" }) })] }));
|
|
9
5
|
OsUpgradeNotice.displayName = "OsUpgradeNotice";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OsUpgradeRecommendationPopover.d.ts","sourceRoot":"","sources":["../../src/report/OsUpgradeRecommendationPopover.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"OsUpgradeRecommendationPopover.d.ts","sourceRoot":"","sources":["../../src/report/OsUpgradeRecommendationPopover.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAehC,UAAU,mCAAmC;IAC3C,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,8BAA8B,EAAE,EAAE,CAC7C,mCAAmC,CAiBpC,CAAC;AAIF,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAyB1C,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { css } from "@emotion/css";
|
|
3
3
|
import { Button, Flex, FlexItem, Popover } from "@patternfly/react-core";
|
|
4
4
|
import { InfoCircleIcon } from "@patternfly/react-icons";
|
|
5
|
+
import { chartExportHideProps } from "./chartExport.js";
|
|
5
6
|
const upgradeRecommendationPopoverCloseButton = css `
|
|
6
7
|
.pf-v6-c-popover__close .pf-v6-c-button.pf-m-plain,
|
|
7
8
|
.pf-v6-c-popover__close .pf-v6-c-button.pf-m-plain:hover {
|
|
@@ -14,11 +15,11 @@ const infoButtonStyle = css `
|
|
|
14
15
|
`;
|
|
15
16
|
export const OsUpgradeRecommendationPopover = ({ upgradeRecommendation }) => (_jsx(Popover, { className: upgradeRecommendationPopoverCloseButton, position: "bottom", headerContent: "Upgrade to get support", bodyContent: _jsx("div", { children: upgradeRecommendation }), children: _jsx(Button, { type: "button", "aria-label": "Open operating system upgrade information", variant: "plain", className: infoButtonStyle, children: _jsx(InfoCircleIcon, { color: "var(--pf-t--global--icon--color--status--info--default)" }) }) }));
|
|
16
17
|
OsUpgradeRecommendationPopover.displayName = "OsUpgradeRecommendationPopover";
|
|
17
|
-
export const OsNameCell = ({ osName, upgradeRecommendation,
|
|
18
|
+
export const OsNameCell = ({ osName, upgradeRecommendation, }) => {
|
|
18
19
|
const hasUpgradeRecommendation = upgradeRecommendation && upgradeRecommendation.trim() !== "";
|
|
19
|
-
if (!hasUpgradeRecommendation
|
|
20
|
+
if (!hasUpgradeRecommendation) {
|
|
20
21
|
return _jsx(_Fragment, { children: osName });
|
|
21
22
|
}
|
|
22
|
-
return (_jsxs(Flex, { alignItems: { default: "alignItemsCenter" }, spaceItems: { default: "spaceItemsXs" }, flexWrap: { default: "nowrap" }, children: [_jsx(FlexItem, { children: osName }), _jsx(FlexItem, { shrink: { default: "shrink" }, children: _jsx(OsUpgradeRecommendationPopover, { upgradeRecommendation: upgradeRecommendation }) })] }));
|
|
23
|
+
return (_jsxs(Flex, { alignItems: { default: "alignItemsCenter" }, spaceItems: { default: "spaceItemsXs" }, flexWrap: { default: "nowrap" }, children: [_jsx(FlexItem, { children: osName }), _jsx(FlexItem, { shrink: { default: "shrink" }, ...chartExportHideProps, children: _jsx(OsUpgradeRecommendationPopover, { upgradeRecommendation: upgradeRecommendation }) })] }));
|
|
23
24
|
};
|
|
24
25
|
OsNameCell.displayName = "OsNameCell";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FC, ReactNode } from "react";
|
|
2
|
+
import { type MigrationDonutChartDatum, type MigrationDonutChartLegendVariant } from "../charts/MigrationDonutChart.js";
|
|
3
|
+
export interface PowerStateCardProps {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
icon: ReactNode;
|
|
7
|
+
emptyTitle: string;
|
|
8
|
+
slices: MigrationDonutChartDatum[];
|
|
9
|
+
legend: Record<string, string>;
|
|
10
|
+
total: number;
|
|
11
|
+
subTitle: string;
|
|
12
|
+
itemsPerRow?: number;
|
|
13
|
+
legendVariant?: MigrationDonutChartLegendVariant;
|
|
14
|
+
}
|
|
15
|
+
export declare const PowerStateCard: FC<PowerStateCardProps>;
|
|
16
|
+
//# sourceMappingURL=PowerStateCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PowerStateCard.d.ts","sourceRoot":"","sources":["../../src/report/PowerStateCard.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,gCAAgC,EACtC,MAAM,kCAAkC,CAAC;AAM1C,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAClD;AAED,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAoDlD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Card, CardBody, CardTitle, Flex, FlexItem, } from "@patternfly/react-core";
|
|
3
|
+
import { MigrationDonutChart, } from "../charts/MigrationDonutChart.js";
|
|
4
|
+
import { CardEmptyState } from "./CardEmptyState.js";
|
|
5
|
+
import { ChartHeaderActions } from "./ChartDownloadButton.js";
|
|
6
|
+
import { ChartExportSurface } from "./ChartExportSurface.js";
|
|
7
|
+
import { dashboardStyles } from "./dashboardStyles.js";
|
|
8
|
+
export const PowerStateCard = ({ id, title, icon, emptyTitle, slices, legend, total, subTitle, itemsPerRow = 2, legendVariant = "html", }) => (_jsx(ChartExportSurface, { id: id, title: title, children: _jsxs(Card, { className: dashboardStyles.card, children: [_jsx(CardTitle, { children: _jsxs(Flex, { justifyContent: { default: "justifyContentSpaceBetween" }, alignItems: { default: "alignItemsCenter" }, children: [_jsxs(FlexItem, { children: [icon, " ", title] }), _jsx(ChartHeaderActions, { chartId: id, title: title })] }) }), _jsx(CardBody, { children: total === 0 ? (_jsx(CardEmptyState, { title: emptyTitle })) : (_jsx(MigrationDonutChart, { legendVariant: legendVariant, data: slices, legend: legend, height: 300, width: 420, donutThickness: 18, padAngle: 1, title: `${total}`, subTitle: subTitle, subTitleColor: "var(--pf-t--global--text--color--subtle)", titleFontSize: 34, labelFontSize: 16, itemsPerRow: itemsPerRow, marginLeft: "0%", tooltipLabelFormatter: ({ datum, percent }) => `${datum.countDisplay}\n${percent.toFixed(1)}%` })) })] }) }));
|
|
9
|
+
PowerStateCard.displayName = "PowerStateCard";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type FC } from "react";
|
|
2
|
+
import { type ReportExportOption, type StandardReportExportHandlers } from "./reportExportOptions.js";
|
|
3
|
+
export interface ReportExportMenuProps {
|
|
4
|
+
options: ReportExportOption[];
|
|
5
|
+
isLoading?: boolean;
|
|
6
|
+
loadingLabel?: string | null;
|
|
7
|
+
isDisabled?: boolean;
|
|
8
|
+
toggleLabel?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const ReportExportMenu: FC<ReportExportMenuProps>;
|
|
11
|
+
export interface ExportReportButtonProps extends StandardReportExportHandlers {
|
|
12
|
+
extraOptions?: ReportExportOption[];
|
|
13
|
+
isLoading?: boolean;
|
|
14
|
+
loadingLabel?: string | null;
|
|
15
|
+
isDisabled?: boolean;
|
|
16
|
+
toggleLabel?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const ExportReportButton: FC<ExportReportButtonProps>;
|
|
19
|
+
//# sourceMappingURL=ReportExportMenu.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Dropdown, DropdownItem, DropdownList, MenuToggle, Spinner, } from "@patternfly/react-core";
|
|
3
|
+
import { DownloadIcon } from "@patternfly/react-icons";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { standardReportExportOptions, } from "./reportExportOptions.js";
|
|
6
|
+
export const ReportExportMenu = ({ options, isLoading = false, loadingLabel = null, isDisabled = false, toggleLabel = "Export", }) => {
|
|
7
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
8
|
+
if (options.length === 0) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return (_jsx(Dropdown, { isOpen: isDropdownOpen, popperProps: {
|
|
12
|
+
placement: "bottom-end",
|
|
13
|
+
preventOverflow: true,
|
|
14
|
+
}, onSelect: () => {
|
|
15
|
+
setIsDropdownOpen(false);
|
|
16
|
+
}, onOpenChange: (isOpen) => {
|
|
17
|
+
setIsDropdownOpen(isOpen);
|
|
18
|
+
}, toggle: (toggleRef) => (_jsx(MenuToggle, { ref: toggleRef, onClick: () => {
|
|
19
|
+
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))) }) }));
|
|
21
|
+
};
|
|
22
|
+
ReportExportMenu.displayName = "ReportExportMenu";
|
|
23
|
+
export const ExportReportButton = ({ onExportPdf, onExportPng, onExportHtml, extraOptions = [], ...menuProps }) => (_jsx(ReportExportMenu, { options: [
|
|
24
|
+
...standardReportExportOptions({
|
|
25
|
+
onExportPdf,
|
|
26
|
+
onExportPng,
|
|
27
|
+
onExportHtml,
|
|
28
|
+
}),
|
|
29
|
+
...extraOptions,
|
|
30
|
+
], ...menuProps }));
|
|
31
|
+
ExportReportButton.displayName = "ExportReportButton";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
export interface ReportTableProps<DataItem> {
|
|
3
|
+
columns: string[];
|
|
4
|
+
data: DataItem[];
|
|
5
|
+
fields: Array<keyof DataItem>;
|
|
6
|
+
caption?: string;
|
|
7
|
+
onRowClick?: (item: DataItem) => void;
|
|
8
|
+
clickableFields?: Array<keyof DataItem>;
|
|
9
|
+
}
|
|
10
|
+
export declare function ReportTable<DataItem>(props: ReportTableProps<DataItem>): React.ReactNode;
|
|
11
|
+
export declare namespace ReportTable {
|
|
12
|
+
var displayName: string;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=ReportTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReportTable.d.ts","sourceRoot":"","sources":["../../src/report/ReportTable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,gBAAgB,CAAC,QAAQ;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,MAAM,EAAE,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACtC,eAAe,CAAC,EAAE,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC;CACzC;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAClC,KAAK,EAAE,gBAAgB,CAAC,QAAQ,CAAC,GAChC,KAAK,CAAC,SAAS,CA8DjB;yBAhEe,WAAW"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@patternfly/react-core";
|
|
3
|
+
import { Table, Tbody, Td, Th, Thead, Tr } from "@patternfly/react-table";
|
|
4
|
+
import { tableFullWidthStyle } from "./dashboardStyles.js";
|
|
5
|
+
export function ReportTable(props) {
|
|
6
|
+
const { columns, data, fields, caption, onRowClick, clickableFields = [], } = props;
|
|
7
|
+
const renderCell = (item, field) => {
|
|
8
|
+
const value = item[field];
|
|
9
|
+
if (value === "" || value == null) {
|
|
10
|
+
return "-";
|
|
11
|
+
}
|
|
12
|
+
if (typeof value === "boolean") {
|
|
13
|
+
return value ? "True" : "False";
|
|
14
|
+
}
|
|
15
|
+
// Make field clickable if specified
|
|
16
|
+
if (clickableFields.includes(field) && onRowClick) {
|
|
17
|
+
return (_jsx(Button, { variant: "link", isInline: true, onClick: () => onRowClick(item), style: { padding: 0, fontSize: "inherit" }, children: value }));
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
};
|
|
21
|
+
return (_jsxs(Table, { variant: "compact", borders: false, className: tableFullWidthStyle, children: [caption && _jsx("caption", { children: caption }), _jsx(Thead, { children: _jsx(Tr, { children: columns.map((name) => (_jsx(Th, { children: name }, name))) }) }), _jsx(Tbody, { children: data.map((item) => (_jsx(Tr, { children: fields.map((f) => (_jsx(Td, { children: renderCell(item, f) }, String(f)))) }, `row-${String(item[fields[0]])}`))) })] }));
|
|
22
|
+
}
|
|
23
|
+
ReportTable.displayName = "ReportTable";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupportTierBadge.d.ts","sourceRoot":"","sources":["../../src/report/SupportTierBadge.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SupportTierBadge.d.ts","sourceRoot":"","sources":["../../src/report/SupportTierBadge.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAE5B,UAAU,qBAAqB;IAC7B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAYtD,CAAC"}
|
|
@@ -1,23 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { css } from "@emotion/css";
|
|
3
2
|
import { Label, Tooltip } from "@patternfly/react-core";
|
|
4
3
|
import { getSupportTierBadgeColor, getSupportTierBadgeInlineStyle, getSupportTierDefinition, getSupportTierLegendLabel, } from "./osSupportTier.js";
|
|
5
|
-
const
|
|
6
|
-
display: inline-block;
|
|
7
|
-
padding: var(--pf-t--global--spacer--xs) var(--pf-t--global--spacer--sm);
|
|
8
|
-
border-radius: var(--pf-t--global--border--radius--pill);
|
|
9
|
-
font-size: var(--pf-t--global--font--size--body--sm);
|
|
10
|
-
line-height: var(--pf-t--global--font--line-height--body);
|
|
11
|
-
white-space: nowrap;
|
|
12
|
-
`;
|
|
13
|
-
const ExportSupportTierBadge = ({ tier }) => {
|
|
14
|
-
const { backgroundColor, color } = getSupportTierBadgeInlineStyle(tier);
|
|
15
|
-
return (_jsx("span", { className: exportBadgeStyle, style: { backgroundColor, color }, children: getSupportTierLegendLabel(tier) }));
|
|
16
|
-
};
|
|
17
|
-
export const SupportTierBadge = ({ tier, isExportMode = false, }) => {
|
|
18
|
-
if (isExportMode) {
|
|
19
|
-
return _jsx(ExportSupportTierBadge, { tier: tier });
|
|
20
|
-
}
|
|
21
|
-
return (_jsx(Tooltip, { content: getSupportTierDefinition(tier), children: _jsx("span", { children: _jsx(Label, { color: getSupportTierBadgeColor(tier), isCompact: true, children: getSupportTierLegendLabel(tier) }) }) }));
|
|
22
|
-
};
|
|
4
|
+
export const SupportTierBadge = ({ tier }) => (_jsx(Tooltip, { content: getSupportTierDefinition(tier), children: _jsx("span", { children: _jsx(Label, { color: getSupportTierBadgeColor(tier), isCompact: true, style: getSupportTierBadgeInlineStyle(tier), children: getSupportTierLegendLabel(tier) }) }) }));
|
|
23
5
|
SupportTierBadge.displayName = "SupportTierBadge";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FC } from "react";
|
|
2
|
+
import type { ClusterDetailRow, ClusterDetailsModel } from "./infrastructureSummaryModel.js";
|
|
3
|
+
export interface VCenterClusterDetailsProps {
|
|
4
|
+
isAggregateView: boolean;
|
|
5
|
+
rows: ClusterDetailRow[];
|
|
6
|
+
details?: ClusterDetailsModel;
|
|
7
|
+
}
|
|
8
|
+
export declare const VCenterClusterDetails: FC<VCenterClusterDetailsProps>;
|
|
9
|
+
//# sourceMappingURL=VCenterClusterDetails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VCenterClusterDetails.d.ts","sourceRoot":"","sources":["../../src/report/VCenterClusterDetails.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKhC,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EAEpB,MAAM,iCAAiC,CAAC;AAEzC,MAAM,WAAW,0BAA0B;IACzC,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC/B;AAsKD,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CA+BhE,CAAC"}
|