@openshift-migration-advisor/shared-components 0.30.0 → 0.31.0-1fbc1a716dab

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 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 | Result |
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` | Release: `X.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 > 0 ? computed : 0;
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,CAkB1D,CAAC"}
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.30.0",
3
+ "version": "0.31.0-1fbc1a716dab",
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.2",
49
+ "html2canvas-pro": "^2.6.0",
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 > 0 ? computed : 0;
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 variant="outline" isCompact icon={<TimesCircleIcon />}>
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 { ChartExportProvider, useChartExport } from "../ChartExportProvider.js";
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
- background: chart_color_blue_300.value,
192
+ backgroundColor: chart_color_blue_300.value,
193
193
  });
194
194
  expect(screen.getByText("4.25")).toHaveStyle({
195
- background: chart_color_purple_300.value,
195
+ backgroundColor: chart_color_purple_300.value,
196
196
  });
197
197
  expect(screen.getByText("3.5")).toHaveStyle({
198
- background: chart_color_purple_100.value,
198
+ backgroundColor: chart_color_purple_100.value,
199
199
  });
200
200
  expect(screen.getByText("2")).toHaveStyle({
201
- background: chart_color_teal_200.value,
201
+ backgroundColor: chart_color_teal_200.value,
202
202
  });
203
203
  expect(screen.getByText("1")).toHaveStyle({
204
- background: chart_color_yellow_400.value,
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();