@openshift-migration-advisor/shared-components 0.30.0 → 0.31.0-695f8185a741
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 +6 -6
- package/dist/charts/MigrationDonutChart.js +1 -1
- package/dist/report/FeatureStatusBadge.d.ts.map +1 -1
- package/dist/report/FeatureStatusBadge.js +2 -2
- package/package.json +2 -2
- package/src/charts/MigrationDonutChart.tsx +1 -1
- package/src/report/FeatureStatusBadge.tsx +10 -2
- package/src/report/__tests__/ChartExportProvider.test.tsx +33 -28
- package/src/report/__tests__/ClustersOverview.test.tsx +5 -5
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
|
|
42
42
|
<ChartExportProvider>
|
|
43
43
|
<Dashboard />
|
|
44
|
-
</ChartExportProvider
|
|
44
|
+
</ChartExportProvider>;
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
`ChartExportProvider` lazy-loads capture, ZIP, PDF, and HTML. Wrap the chart visual (not the Card chrome) in `ChartExportSurface`. All formats snapshot those same nodes, encode one chart at a time, and drop the canvas. There is no second print tree and no `isExportMode` render:
|
|
@@ -56,7 +56,7 @@ import { ChartExportSurface } from "@openshift-migration-advisor/shared-componen
|
|
|
56
56
|
<MigrationDonutChart {...chartProps} />
|
|
57
57
|
</ChartExportSurface>
|
|
58
58
|
</CardBody>
|
|
59
|
-
</Card
|
|
59
|
+
</Card>;
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
`ReportExportMenu` accepts a fully custom `options` list. `standardReportExportOptions()` builds the PDF / HTML / PNG entries; omit a handler to hide that format.
|
|
@@ -78,10 +78,10 @@ The package is published to npm under `@openshift-migration-advisor/shared-compo
|
|
|
78
78
|
|
|
79
79
|
**Workflow:** [`.github/workflows/release-shared-components.yaml`](../../.github/workflows/release-shared-components.yaml)
|
|
80
80
|
|
|
81
|
-
| Trigger
|
|
82
|
-
|
|
81
|
+
| Trigger | Result |
|
|
82
|
+
| ------------------------------------------------------------------ | --------------------------------------- |
|
|
83
83
|
| Push to `main` / `stable` changing `packages/shared-components/**` | Prerelease: `{latestTag}-{12-char-sha}` |
|
|
84
|
-
| Tag `vX.Y.Z`
|
|
84
|
+
| Tag `vX.Y.Z` | Release: `X.Y.Z` |
|
|
85
85
|
|
|
86
86
|
### One-time npm setup (required before first publish)
|
|
87
87
|
|
|
@@ -95,4 +95,4 @@ No npm token is stored in the repo; publish uses OIDC (`id-token: write`).
|
|
|
95
95
|
|
|
96
96
|
## License
|
|
97
97
|
|
|
98
|
-
[Apache 2.0](LICENSE)
|
|
98
|
+
[Apache 2.0](LICENSE)
|
|
@@ -144,7 +144,7 @@ export const MigrationDonutChart = ({ data, legend, customColors, height = 260,
|
|
|
144
144
|
const innerRadius = useMemo(() => {
|
|
145
145
|
const outerApprox = Math.min(width, height) / 2;
|
|
146
146
|
const computed = outerApprox - donutThickness;
|
|
147
|
-
return computed
|
|
147
|
+
return Math.max(computed, 0);
|
|
148
148
|
}, [width, height, donutThickness]);
|
|
149
149
|
const totalY = useMemo(() => {
|
|
150
150
|
return chartData.reduce((sum, item) => sum + (Number(item.y) || 0), 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeatureStatusBadge.d.ts","sourceRoot":"","sources":["../../src/report/FeatureStatusBadge.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,
|
|
1
|
+
{"version":3,"file":"FeatureStatusBadge.d.ts","sourceRoot":"","sources":["../../src/report/FeatureStatusBadge.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CA0B1D,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Label } from "@patternfly/react-core";
|
|
2
|
+
import { Icon, Label } from "@patternfly/react-core";
|
|
3
3
|
import { CheckCircleIcon, TimesCircleIcon } from "@patternfly/react-icons";
|
|
4
4
|
export const FeatureStatusBadge = ({ status }) => {
|
|
5
5
|
if (status === "unknown") {
|
|
@@ -8,6 +8,6 @@ export const FeatureStatusBadge = ({ status }) => {
|
|
|
8
8
|
if (status === "enabled") {
|
|
9
9
|
return (_jsx(Label, { color: "green", isCompact: true, icon: _jsx(CheckCircleIcon, {}), children: "Enabled" }));
|
|
10
10
|
}
|
|
11
|
-
return (_jsx(Label, { variant: "outline", isCompact: true, icon: _jsx(TimesCircleIcon, {}), children: "Disabled" }));
|
|
11
|
+
return (_jsx(Label, { variant: "outline", isCompact: true, icon: _jsx(Icon, { status: "danger", children: _jsx(TimesCircleIcon, {}) }), children: "Disabled" }));
|
|
12
12
|
};
|
|
13
13
|
FeatureStatusBadge.displayName = "FeatureStatusBadge";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openshift-migration-advisor/shared-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0-695f8185a741",
|
|
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",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"README.md"
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"html2canvas-pro": "^2.5.
|
|
49
|
+
"html2canvas-pro": "^2.5.4",
|
|
50
50
|
"jspdf": "^4.2.1",
|
|
51
51
|
"jszip": "^3.10.2"
|
|
52
52
|
}
|
|
@@ -266,7 +266,7 @@ export const MigrationDonutChart: FC<MigrationDonutChartProps> = ({
|
|
|
266
266
|
const innerRadius = useMemo(() => {
|
|
267
267
|
const outerApprox = Math.min(width, height) / 2;
|
|
268
268
|
const computed = outerApprox - donutThickness;
|
|
269
|
-
return computed
|
|
269
|
+
return Math.max(computed, 0);
|
|
270
270
|
}, [width, height, donutThickness]);
|
|
271
271
|
|
|
272
272
|
const totalY = useMemo(() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Label } from "@patternfly/react-core";
|
|
1
|
+
import { Icon, Label } from "@patternfly/react-core";
|
|
2
2
|
import { CheckCircleIcon, TimesCircleIcon } from "@patternfly/react-icons";
|
|
3
3
|
import type { FC } from "react";
|
|
4
4
|
import type { FeatureStatus } from "./infrastructureSummaryModel.js";
|
|
@@ -21,7 +21,15 @@ export const FeatureStatusBadge: FC<FeatureStatusBadgeProps> = ({ status }) => {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
|
-
<Label
|
|
24
|
+
<Label
|
|
25
|
+
variant="outline"
|
|
26
|
+
isCompact
|
|
27
|
+
icon={
|
|
28
|
+
<Icon status="danger">
|
|
29
|
+
<TimesCircleIcon />
|
|
30
|
+
</Icon>
|
|
31
|
+
}
|
|
32
|
+
>
|
|
25
33
|
Disabled
|
|
26
34
|
</Label>
|
|
27
35
|
);
|
|
@@ -3,7 +3,12 @@ import { cleanup, render, screen, waitFor } from "@testing-library/react";
|
|
|
3
3
|
import userEvent from "@testing-library/user-event";
|
|
4
4
|
import { useState } from "react";
|
|
5
5
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
type BuildChartDocument,
|
|
8
|
+
type BuildPdfDocument,
|
|
9
|
+
ChartExportProvider,
|
|
10
|
+
useChartExport,
|
|
11
|
+
} from "../ChartExportProvider.js";
|
|
7
12
|
import { ChartExportSurface } from "../ChartExportSurface.js";
|
|
8
13
|
import {
|
|
9
14
|
CHART_EXPORT_HIDE_ATTR,
|
|
@@ -32,6 +37,29 @@ vi.mock("../../charts/MigrationDonutChart.js", () => ({
|
|
|
32
37
|
|
|
33
38
|
afterEach(() => cleanup());
|
|
34
39
|
|
|
40
|
+
function DropdownChart(): JSX.Element {
|
|
41
|
+
const [view, setView] = useState("a");
|
|
42
|
+
return (
|
|
43
|
+
<ChartExportSurface
|
|
44
|
+
id="vm"
|
|
45
|
+
title={view === "a" ? "View A" : "View B"}
|
|
46
|
+
exportViews={[
|
|
47
|
+
{ id: "a", title: "View A" },
|
|
48
|
+
{ id: "b", title: "View B" },
|
|
49
|
+
]}
|
|
50
|
+
activeExportViewId={view}
|
|
51
|
+
onExportViewChange={setView}
|
|
52
|
+
>
|
|
53
|
+
<div data-testid="active-view">{view}</div>
|
|
54
|
+
</ChartExportSurface>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function ErrorText(): JSX.Element {
|
|
59
|
+
const exportApi = useChartExport();
|
|
60
|
+
return <div>{exportApi?.exportError}</div>;
|
|
61
|
+
}
|
|
62
|
+
|
|
35
63
|
function RegisteredChart({
|
|
36
64
|
id,
|
|
37
65
|
title,
|
|
@@ -255,7 +283,7 @@ describe("ChartExportProvider", () => {
|
|
|
255
283
|
it("builds a PDF from the same captured canvases", async () => {
|
|
256
284
|
const user = userEvent.setup();
|
|
257
285
|
const capture = vi.fn(async () => fakeCanvas());
|
|
258
|
-
const buildPdf = vi.fn(async () => new Blob(["pdf"]));
|
|
286
|
+
const buildPdf = vi.fn<BuildPdfDocument>(async () => new Blob(["pdf"]));
|
|
259
287
|
const downloadFile = vi.fn();
|
|
260
288
|
|
|
261
289
|
render(
|
|
@@ -285,7 +313,7 @@ describe("ChartExportProvider", () => {
|
|
|
285
313
|
it("forwards extra text pages (e.g. cluster sizing recommendations) to the pdf builder", async () => {
|
|
286
314
|
const user = userEvent.setup();
|
|
287
315
|
const capture = vi.fn(async () => fakeCanvas());
|
|
288
|
-
const buildPdf = vi.fn(async () => new Blob(["pdf"]));
|
|
316
|
+
const buildPdf = vi.fn<BuildPdfDocument>(async () => new Blob(["pdf"]));
|
|
289
317
|
const downloadFile = vi.fn();
|
|
290
318
|
const extraPages = [
|
|
291
319
|
{
|
|
@@ -320,7 +348,7 @@ describe("ChartExportProvider", () => {
|
|
|
320
348
|
|
|
321
349
|
it("builds a PDF from extra text pages alone when no charts are registered", async () => {
|
|
322
350
|
const user = userEvent.setup();
|
|
323
|
-
const buildPdf = vi.fn(async () => new Blob(["pdf"]));
|
|
351
|
+
const buildPdf = vi.fn<BuildPdfDocument>(async () => new Blob(["pdf"]));
|
|
324
352
|
const downloadFile = vi.fn();
|
|
325
353
|
const extraPages = [{ title: "Cluster sizing recommendations", items: [] }];
|
|
326
354
|
|
|
@@ -347,7 +375,7 @@ describe("ChartExportProvider", () => {
|
|
|
347
375
|
it("builds HTML from the same captured canvases", async () => {
|
|
348
376
|
const user = userEvent.setup();
|
|
349
377
|
const capture = vi.fn(async () => fakeCanvas());
|
|
350
|
-
const buildHtml = vi.fn(async () => new Blob(["html"]));
|
|
378
|
+
const buildHtml = vi.fn<BuildChartDocument>(async () => new Blob(["html"]));
|
|
351
379
|
const downloadFile = vi.fn();
|
|
352
380
|
|
|
353
381
|
render(
|
|
@@ -397,24 +425,6 @@ describe("ChartExportProvider", () => {
|
|
|
397
425
|
);
|
|
398
426
|
const downloadFile = vi.fn();
|
|
399
427
|
|
|
400
|
-
function DropdownChart(): JSX.Element {
|
|
401
|
-
const [view, setView] = useState("a");
|
|
402
|
-
return (
|
|
403
|
-
<ChartExportSurface
|
|
404
|
-
id="vm"
|
|
405
|
-
title={view === "a" ? "View A" : "View B"}
|
|
406
|
-
exportViews={[
|
|
407
|
-
{ id: "a", title: "View A" },
|
|
408
|
-
{ id: "b", title: "View B" },
|
|
409
|
-
]}
|
|
410
|
-
activeExportViewId={view}
|
|
411
|
-
onExportViewChange={setView}
|
|
412
|
-
>
|
|
413
|
-
<div data-testid="active-view">{view}</div>
|
|
414
|
-
</ChartExportSurface>
|
|
415
|
-
);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
428
|
render(
|
|
419
429
|
<ChartExportProvider
|
|
420
430
|
capture={capture}
|
|
@@ -473,11 +483,6 @@ describe("ChartExportProvider", () => {
|
|
|
473
483
|
const user = userEvent.setup();
|
|
474
484
|
vi.spyOn(console, "error").mockImplementation(() => undefined);
|
|
475
485
|
|
|
476
|
-
function ErrorText(): JSX.Element {
|
|
477
|
-
const exportApi = useChartExport();
|
|
478
|
-
return <div>{exportApi?.exportError}</div>;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
486
|
render(
|
|
482
487
|
<ChartExportProvider
|
|
483
488
|
capture={vi.fn(async () => {
|
|
@@ -189,19 +189,19 @@ describe("ClustersOverview", () => {
|
|
|
189
189
|
|
|
190
190
|
expect(screen.queryByTestId("clusters-donut")).not.toBeInTheDocument();
|
|
191
191
|
expect(screen.getByText("8")).toHaveStyle({
|
|
192
|
-
|
|
192
|
+
backgroundColor: chart_color_blue_300.value,
|
|
193
193
|
});
|
|
194
194
|
expect(screen.getByText("4.25")).toHaveStyle({
|
|
195
|
-
|
|
195
|
+
backgroundColor: chart_color_purple_300.value,
|
|
196
196
|
});
|
|
197
197
|
expect(screen.getByText("3.5")).toHaveStyle({
|
|
198
|
-
|
|
198
|
+
backgroundColor: chart_color_purple_100.value,
|
|
199
199
|
});
|
|
200
200
|
expect(screen.getByText("2")).toHaveStyle({
|
|
201
|
-
|
|
201
|
+
backgroundColor: chart_color_teal_200.value,
|
|
202
202
|
});
|
|
203
203
|
expect(screen.getByText("1")).toHaveStyle({
|
|
204
|
-
|
|
204
|
+
backgroundColor: chart_color_yellow_400.value,
|
|
205
205
|
});
|
|
206
206
|
expect(screen.queryByText("0.5")).not.toBeInTheDocument();
|
|
207
207
|
expect(screen.getByText("Cluster 1 (8)")).toBeInTheDocument();
|