Skip to content

Commit ec2de50

Browse files
authored
feat(story): product list (#302)
1 parent 7cbdca2 commit ec2de50

File tree

9 files changed

+1206
-364
lines changed

9 files changed

+1206
-364
lines changed

.storybook/main.ts

+22-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ const config: StorybookConfig = {
2626
name: getAbsolutePath("@storybook/react-webpack5"),
2727
options: {},
2828
},
29-
staticDirs: ["../public", "../client/public", "../client/src/app/images"],
29+
staticDirs: [
30+
"../public",
31+
"../branding/images",
32+
"../client/public",
33+
"../client/src/app/images",
34+
],
3035
typescript: {
3136
reactDocgen: "react-docgen-typescript",
3237
reactDocgenTypescriptOptions: {
@@ -47,11 +52,24 @@ const config: StorybookConfig = {
4752
];
4853
}
4954
if (config.module) {
50-
config.module.rules?.push({
51-
test: /\.svg$/,
52-
use: ["@svgr/webpack"],
55+
// remove svg from existing rule
56+
config.module.rules = config.module.rules?.map((rule: any) => {
57+
if (
58+
String(rule.test) ===
59+
String(
60+
/\.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani)(\?.*)?$/
61+
)
62+
) {
63+
return {
64+
...rule,
65+
test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani)(\?.*)?$/,
66+
};
67+
}
68+
69+
return rule;
5370
});
5471
}
72+
5573
return config;
5674
},
5775
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import React from "react";
3+
import { SBOMVulnerabilities } from "./SbomVulnerabilities";
4+
5+
type SbomVulnerabilitiesPropsAndCustomArgs = React.ComponentProps<
6+
typeof SBOMVulnerabilities
7+
> & {
8+
userStory?: string;
9+
};
10+
11+
const meta: Meta<SbomVulnerabilitiesPropsAndCustomArgs> = {
12+
title: "Components/SbomVulnerabilities",
13+
component: SBOMVulnerabilities,
14+
};
15+
16+
export default meta;
17+
type Story = StoryObj<typeof meta>;
18+
19+
export const PrimaryState: Story = {
20+
args: {
21+
sbomId: "urn:uuid:01932ff3-0fc4-7bf2-8201-5d5e9dc471bd",
22+
},
23+
};

client/src/mocks/handlers.ts

+41-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { http, HttpResponse } from "msw";
22
import { VulnerabilityHead } from "@app/client";
33

4+
import imgAvatar from "../app/images/avatar.svg";
5+
import logo from "../../../branding/images/masthead-logo.svg";
6+
47
import getAdvisories from "@mocks/data/advisory/list.json";
58
import getProducts from "@mocks/data/product/list.json";
69
import getPurls from "@mocks/data/purl/list.json";
@@ -9,6 +12,17 @@ import getVulnerabilities from "@mocks/data/vulnerability/list.json";
912

1013
// DATA IMPORTS
1114

15+
import advisory_03bb16dc from "@mocks/data/advisory/details/03bb16dc-3cff-4a7d-8393-9a6a7124ecc2.json";
16+
import advisory_87aa81c3 from "@mocks/data/advisory/details/87aa81c3-2aa5-438e-b5d4-d67ca4e321a9.json";
17+
import advisory_88a4fc6c from "@mocks/data/advisory/details/88a4fc6c-60ae-4e4a-bdbe-4fb2e1d33e9c.json";
18+
import advisory_459c504b from "@mocks/data/advisory/details/459c504b-7e09-4ea9-9cbb-baa8ce040e83.json";
19+
import advisory_671dd85b from "@mocks/data/advisory/details/671dd85b-409f-4509-9a50-c4b2404ac10a.json";
20+
import advisory_673acfc8 from "@mocks/data/advisory/details/673acfc8-ea7d-4c6d-aff9-20cf70caade0.json";
21+
import advisory_32600b15 from "@mocks/data/advisory/details/32600b15-f2c1-4115-bcfb-0d0e1786f86d.json";
22+
import advisory_d99d1421 from "@mocks/data/advisory/details/d99d1421-e2fd-49c2-b2dd-82fe848fff48.json";
23+
import advisory_ea257645 from "@mocks/data/advisory/details/ea257645-f52f-4723-9c73-a4ed589f67ac.json";
24+
import advisory_ee8cff4d from "@mocks/data/advisory/details/ee8cff4d-d6bc-4a27-89ac-a7ad193f5eb6.json";
25+
1226
import cve_202245787 from "@mocks/data/vulnerability/CVE-2022-45787/details.json";
1327
import cve_20230044 from "@mocks/data/vulnerability/CVE-2023-0044/details.json";
1428
import cve_20230481 from "@mocks/data/vulnerability/CVE-2023-0481/details.json";
@@ -57,7 +71,18 @@ import purl_e0b74cfd from "@mocks/data/purl/details/e0b74cfd-e0b0-512b-8814-947f
5771
import purl_f4f6b460 from "@mocks/data/purl/details/f4f6b460-82e5-59f0-a7f6-da5f226a9b24.json";
5872
import purl_f357b0cc from "@mocks/data/purl/details/f357b0cc-75d5-532e-b7d9-2233f6f752c8.json";
5973

60-
import imgAvatar from "@app/images/avatar.svg";
74+
export const advisoryDetails: { [identifier: string]: any } = {
75+
"urn:uuid:03bb16dc-3cff-4a7d-8393-9a6a7124ecc2": advisory_03bb16dc,
76+
"urn:uuid:87aa81c3-2aa5-438e-b5d4-d67ca4e321a9": advisory_87aa81c3,
77+
"urn:uuid:88a4fc6c-60ae-4e4a-bdbe-4fb2e1d33e9c": advisory_88a4fc6c,
78+
"urn:uuid:459c504b-7e09-4ea9-9cbb-baa8ce040e83": advisory_459c504b,
79+
"urn:uuid:671dd85b-409f-4509-9a50-c4b2404ac10a": advisory_671dd85b,
80+
"urn:uuid:673acfc8-ea7d-4c6d-aff9-20cf70caade0": advisory_673acfc8,
81+
"urn:uuid:32600b15-f2c1-4115-bcfb-0d0e1786f86d": advisory_32600b15,
82+
"urn:uuid:d99d1421-e2fd-49c2-b2dd-82fe848fff48": advisory_d99d1421,
83+
"urn:uuid:ea257645-f52f-4723-9c73-a4ed589f67ac": advisory_ea257645,
84+
"urn:uuid:ee8cff4d-d6bc-4a27-89ac-a7ad193f5eb6": advisory_ee8cff4d,
85+
};
6186

6287
export const cveDetails: { [identifier: string]: Partial<VulnerabilityHead> } =
6388
{
@@ -139,7 +164,19 @@ const advisoryHandlers = [
139164
http.patch("/api/v1/advisory/:id/label", () => {}),
140165

141166
// get an advisory
142-
http.get("/api/v1/advisory/:key", () => {}),
167+
http.get("/api/v1/advisory/:key", ({ params }) => {
168+
const { key } = params;
169+
if (!key) {
170+
return new HttpResponse("Advisory for SBOM not found", { status: 404 });
171+
} else {
172+
const data = sbomAdvisory[key as string];
173+
if (!data) {
174+
return new HttpResponse("Advisory for SBOM not found", { status: 404 });
175+
}
176+
177+
return HttpResponse.json(data);
178+
}
179+
}),
143180

144181
// delete an advisory
145182
http.delete("/api/v1/advisory/:key", () => {}),
@@ -170,8 +207,9 @@ const analysisHandlers = [
170207
// ASSET HANDLERS
171208

172209
const assetHandlers = [
210+
http.get("/branding/images/placeholder.svg", () => {}),
173211
http.get("/branding/images/masthead-logo.svg", () => {
174-
return new HttpResponse(imgAvatar);
212+
return new HttpResponse(logo);
175213
}),
176214
];
177215

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import React from "react";
3+
4+
import {
5+
Title,
6+
Subtitle,
7+
Description,
8+
Primary,
9+
Controls,
10+
Stories,
11+
} from "@storybook/blocks";
12+
import { ProductDetails } from "@app/client";
13+
14+
interface IProductExplorer {
15+
product: ProductDetails;
16+
}
17+
18+
const ProductExplorer: React.FC<IProductExplorer> = ({ product }) => {
19+
return (
20+
<>
21+
<p>Product Explorer: {product.id}</p>
22+
</>
23+
);
24+
};
25+
26+
type ProductExplorerPropsAndCustomArgs = React.ComponentProps<
27+
typeof ProductExplorer
28+
> & { userStory?: string };
29+
30+
const meta: Meta<ProductExplorerPropsAndCustomArgs> = {
31+
title: "v2.1/Product Explorer",
32+
component: ProductExplorer,
33+
parameters: {
34+
docs: {
35+
page: () => (
36+
<>
37+
<Title />
38+
<Subtitle />
39+
<Description />
40+
<Primary />
41+
<Controls />
42+
<Stories />
43+
</>
44+
),
45+
},
46+
},
47+
};
48+
49+
export default meta;
50+
type Story = StoryObj<typeof meta>;
51+
52+
export const PrimaryState: Story = {
53+
args: {
54+
product: {
55+
id: "urn:uuid:2e167215-42ec-4a71-912c-73082c21cf57",
56+
name: "RH Trusted Artifact Signer",
57+
vendor: {
58+
cpe_key: "example",
59+
id: "red-hat",
60+
name: "Red Hat",
61+
website: "https://www.redhat.com",
62+
},
63+
versions: [],
64+
},
65+
userStory:
66+
"As a developer I want to view all the information about a Product.",
67+
},
68+
};

0 commit comments

Comments
 (0)