diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 96b0a0e9..95a64482 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -48,7 +48,7 @@ const preview: Preview = { }, options: { storySort: { - order: ["v1", "v1.2x", "v2", "v2.1", "v2.x"], + order: ["v2.0", "v2.4", "v2.3", "v2.2", "v2.1"], }, }, }, diff --git a/client/src/app/layout/header.stories.tsx b/client/src/app/layout/header.stories.tsx index f987d44a..d1def64e 100644 --- a/client/src/app/layout/header.stories.tsx +++ b/client/src/app/layout/header.stories.tsx @@ -1,6 +1,8 @@ +import React from "react"; import type { Meta, StoryObj } from "@storybook/react"; import { HeaderApp } from "@app/layout/header"; import { fn } from "@storybook/test"; +import { BrowserRouter } from "react-router-dom"; import * as actual from "@app/hooks/useBranding"; const useBranding = fn(actual.useBranding).mockName("useBranding"); @@ -10,6 +12,13 @@ import { BrandingStrings } from "@trustify-ui/common"; const meta = { title: "Components/Layout/HeaderApp", component: HeaderApp, + decorators: [ + (Story) => ( + + + + ), + ], } satisfies Meta; export default meta; diff --git a/client/src/app/pages/advisory-list/advisory-context.tsx b/client/src/app/pages/advisory-list/advisory-context.tsx index 197a548c..5dce3580 100644 --- a/client/src/app/pages/advisory-list/advisory-context.tsx +++ b/client/src/app/pages/advisory-list/advisory-context.tsx @@ -17,7 +17,7 @@ import { import { useSelectionState } from "@app/hooks/useSelectionState"; import { useFetchAdvisories } from "@app/queries/advisories"; -export interface IAdvisorySearchContext { +interface IAdvisorySearchContext { tableControls: ITableControls< AdvisorySummary, "identifier" | "title" | "severity" | "modified" | "vulnerabilities", diff --git a/client/src/app/pages/advisory-list/advisory-table.stories.tsx b/client/src/app/pages/advisory-list/advisory-table.stories.tsx index 71b4ad90..fe83706f 100644 --- a/client/src/app/pages/advisory-list/advisory-table.stories.tsx +++ b/client/src/app/pages/advisory-list/advisory-table.stories.tsx @@ -3,20 +3,43 @@ import type { Meta, StoryObj } from "@storybook/react"; import { AdvisoryTable } from "./advisory-table"; import { AdvisorySearchContext } from "./advisory-context"; import listResponse from "@mocks/data/advisory/list.json"; +import { BrowserRouter } from "react-router-dom"; + +const meta = { + title: "Components/AdvisoryList/AdvisoryTable", + component: AdvisoryTable, + tags: ["autodocs"], + decorators: [ + (Story, { parameters }) => { + const { contextDefaultValue } = parameters; + return ( + + + + + + ); + }, + ], +} satisfies Meta; + +export default meta; +type Story = StoryObj; const tableControlsCustom = { tableName: "advisory", - persistenceKeyPrefix: "vn", + persistenceKeyPrefix: "ad", + persistTo: "urlParams", columnNames: { identifier: "ID", - title: "Description", - severity: "CVSS", - published: "Date published", - sboms: "Related documents", + title: "Title", + severity: "Aggregated Severity", + modified: "Revision", + vulnerabilities: "Vulnerabilities", }, isPaginationEnabled: true, isSortEnabled: true, - sortableColumns: ["published", "sboms"], + sortableColumns: ["identifier", "severity", "modified"], isFilterEnabled: true, filterCategories: [ { @@ -27,8 +50,8 @@ const tableControlsCustom = { }, { categoryKey: "average_severity", - title: "CVSS", - placeholderText: "CVSS", + title: "Severity", + placeholderText: "Severity", type: "multiselect", selectOptions: [ { @@ -53,15 +76,19 @@ const tableControlsCustom = { }, ], }, + { + categoryKey: "modified", + title: "Revision", + type: "dateRange", + }, ], - isExpansionEnabled: true, - expandableVariant: "compound", + isExpansionEnabled: false, filterState: { filterValues: {}, }, sortState: { activeSort: { - columnKey: "modified", + columnKey: "identifier", direction: "asc", }, }, @@ -84,22 +111,22 @@ const tableControlsCustom = { }, { id: "title", - label: "Description", + label: "Title", isVisible: true, }, { id: "severity", - label: "CVSS", + label: "Aggregated Severity", isVisible: true, }, { - id: "published", - label: "Date published", + id: "modified", + label: "Revision", isVisible: true, }, { - id: "sboms", - label: "Related documents", + id: "vulnerabilities", + label: "Vulnerabilities", isVisible: true, }, ], @@ -123,89 +150,27 @@ const tableControlsCustom = { }, propHelpers: { toolbarProps: { + className: "", collapseListedFiltersBreakpoint: "xl", clearFiltersButtonText: "Clear all filters", }, tableProps: { isExpandable: false, }, - filterToolbarProps: { - filterCategories: [ - { - categoryKey: "", - title: "Filter text", - placeholderText: "Search", - type: "search", - }, - { - categoryKey: "average_severity", - title: "CVSS", - placeholderText: "CVSS", - type: "multiselect", - selectOptions: [ - { - value: "none", - label: "None", - }, - { - value: "low", - label: "Low", - }, - { - value: "medium", - label: "Medium", - }, - { - value: "high", - label: "High", - }, - { - value: "critical", - label: "Critical", - }, - ], - }, - ], - filterValues: {}, + filterToolbarProps: {}, + paginationProps: { + itemCount: 58, + perPage: 10, + page: 1, }, - filterPanelProps: { - filterCategories: [ - { - categoryKey: "", - title: "Filter text", - placeholderText: "Search", - type: "search", - }, - { - categoryKey: "average_severity", - title: "CVSS", - placeholderText: "CVSS", - type: "multiselect", - selectOptions: [ - { - value: "none", - label: "None", - }, - { - value: "low", - label: "Low", - }, - { - value: "medium", - label: "Medium", - }, - { - value: "high", - label: "High", - }, - { - value: "critical", - label: "Critical", - }, - ], - }, - ], - filterValues: {}, + paginationToolbarItemProps: { + variant: "pagination", + align: { + default: "alignRight", + }, + }, + toolbarBulkSelectorProps: { + areAllSelected: false, }, getThProps: () => {}, getTrProps: () => {}, @@ -213,34 +178,13 @@ const tableControlsCustom = { }, }; -const meta = { - title: "Components/AdvisoryList/AdvisoryTable", - component: AdvisoryTable, - tags: ["autodocs"], - decorators: [ - (Story, { parameters }) => { - const { contextDefaultValue } = parameters; - return ( - - - - ); - }, - ], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - export const PrimaryState: Story = { parameters: { contextDefaultValue: { isFetching: false, - fetchError: "", + fetchError: null, tableControls: { ...tableControlsCustom }, - totalItemCount: 3, - currentPageItems: 10, - numRenderedColumns: 3, + totalItemCount: 58, }, }, }; diff --git a/client/src/mocks/handlers.ts b/client/src/mocks/handlers.ts index 62126ab0..5d196b11 100644 --- a/client/src/mocks/handlers.ts +++ b/client/src/mocks/handlers.ts @@ -19,10 +19,6 @@ import cve_202326464 from "@mocks/data/vulnerability/CVE-2023-26464/details.json import sbom_5d5e9dc471bd from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0fc4-7bf2-8201-5d5e9dc471bd/details.json"; import sbom_c26de2fe81d9 from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0fe1-7ca0-8ba6-c26de2fe81d9/details.json"; -// import sbom_f92bac24a6b0 from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0f06-74e0-b673-f92bac24a6b0/details.json"; -// import sbom_1fac54a371f3 from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0f90-7e51-9c9d-1fac54a371f3/details.json"; -// import sbom_c399c1e9a923 from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0f91-7543-af38-c399c1e9a923/details.json"; -// import sbom_18044dbbb574 from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0fbc-7b82-b9c2-18044dbbb574/details.json"; import sbom_5d5e9dc471bd_advisory from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0fc4-7bf2-8201-5d5e9dc471bd/advisory.json"; import sbom_c26de2fe81d9_advisory from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0fe1-7ca0-8ba6-c26de2fe81d9/advisory.json"; @@ -39,6 +35,12 @@ import sbom_c399c1e9a923_packages from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0 import sbom_18044dbbb574_packages from "@mocks/data/sbom/urn%3Auuid%3A01932ff3-0fbc-7b82-b9c2-18044dbbb574/packages.json"; import purl_2e05fb3a from "@mocks/data/purl/details/2e05fb3a-cda9-5e54-96b2-d8c7ea390f8d.json"; +import purl_14c5c61d from "@mocks/data/purl/details/14c5c61d-c4cc-56fb-9db6-f62541076b80.json"; +import purl_25ddc770 from "@mocks/data/purl/details/25ddc770-5fde-53a8-8451-41091d5fcb3b.json"; +import purl_62c9cfab from "@mocks/data/purl/details/62c9cfab-997b-5126-ad5c-90bc277e048f.json"; +import purl_81293bba from "@mocks/data/purl/details/81293bba-1ab5-5524-8444-0bd55d19b9b3.json"; +import purl_b9a43108 from "@mocks/data/purl/details/b9a43108-525d-59ea-bc31-ff217d4c7925.json"; +import purl_d6dea366 from "@mocks/data/purl/details/d6dea366-e8a6-5500-9aef-14464b717295.json"; import purl_e0b74cfd from "@mocks/data/purl/details/e0b74cfd-e0b0-512b-8814-947f868bc50e.json"; import purl_f4f6b460 from "@mocks/data/purl/details/f4f6b460-82e5-59f0-a7f6-da5f226a9b24.json"; import purl_f357b0cc from "@mocks/data/purl/details/f357b0cc-75d5-532e-b7d9-2233f6f752c8.json"; @@ -85,6 +87,12 @@ export const sbomAdvisory: { [identifier: string]: any } = { export const purlDetails: { [identifier: string]: any } = { "2e05fb3a-cda9-5e54-96b2-d8c7ea390f8d": purl_2e05fb3a, + "14c5c61d-c4cc-56fb-9db6-f62541076b80": purl_14c5c61d, + "25ddc770-5fde-53a8-8451-41091d5fcb3b": purl_25ddc770, + "62c9cfab-997b-5126-ad5c-90bc277e048f": purl_62c9cfab, + "81293bba-1ab5-5524-8444-0bd55d19b9b3": purl_81293bba, + "b9a43108-525d-59ea-bc31-ff217d4c7925": purl_b9a43108, + "d6dea366-e8a6-5500-9aef-14464b717295": purl_d6dea366, "e0b74cfd-e0b0-512b-8814-947f868bc50e": purl_e0b74cfd, "f4f6b460-82e5-59f0-a7f6-da5f226a9b24": purl_f4f6b460, "f357b0cc-75d5-532e-b7d9-2233f6f752c8": purl_f357b0cc, diff --git a/client/src/stories/v1.2.x/cve-details.stories.tsx b/client/src/stories/v2.0/cve-details.stories.tsx similarity index 94% rename from client/src/stories/v1.2.x/cve-details.stories.tsx rename to client/src/stories/v2.0/cve-details.stories.tsx index fd169792..351b0c1f 100644 --- a/client/src/stories/v1.2.x/cve-details.stories.tsx +++ b/client/src/stories/v2.0/cve-details.stories.tsx @@ -4,7 +4,7 @@ import Overview from "@app/pages/vulnerability-details"; import { MemoryRouter, Routes, Route } from "react-router"; const meta = { - title: "v1/CVEs/CVE Details", + title: "v2.0/CVEs/CVE Details", component: Overview, decorators: [ (Story) => ( diff --git a/client/src/stories/v1.2.x/cve-page.stories.tsx b/client/src/stories/v2.0/cve-page.stories.tsx similarity index 96% rename from client/src/stories/v1.2.x/cve-page.stories.tsx rename to client/src/stories/v2.0/cve-page.stories.tsx index 2f0c9317..18121195 100644 --- a/client/src/stories/v1.2.x/cve-page.stories.tsx +++ b/client/src/stories/v2.0/cve-page.stories.tsx @@ -5,7 +5,7 @@ import { BrowserRouter } from "react-router-dom"; // import { http, HttpResponse } from "msw"; const meta = { - title: "v1/CVEs/CVE List", + title: "v2.0/CVEs/CVE List", component: VulnerabilityList, decorators: [ (Story) => ( diff --git a/client/src/stories/v1.2.x/home.stories.tsx b/client/src/stories/v2.0/home.stories.tsx similarity index 96% rename from client/src/stories/v1.2.x/home.stories.tsx rename to client/src/stories/v2.0/home.stories.tsx index 0c7f03ba..f8fcc8bd 100644 --- a/client/src/stories/v1.2.x/home.stories.tsx +++ b/client/src/stories/v2.0/home.stories.tsx @@ -6,7 +6,7 @@ import { NotificationsProvider } from "@app/components/NotificationsContext"; import { DefaultLayout } from "@app/layout"; const meta = { - title: "v1/Home", + title: "v2.0/Home", component: Home, decorators: [ (Story) => ( diff --git a/client/src/stories/v1.2.x/sbom-page.stories.tsx b/client/src/stories/v2.0/sbom-page.stories.tsx similarity index 95% rename from client/src/stories/v1.2.x/sbom-page.stories.tsx rename to client/src/stories/v2.0/sbom-page.stories.tsx index 778751bd..bd2b4ab6 100644 --- a/client/src/stories/v1.2.x/sbom-page.stories.tsx +++ b/client/src/stories/v2.0/sbom-page.stories.tsx @@ -5,7 +5,7 @@ import { BrowserRouter } from "react-router-dom"; // import { http, HttpResponse } from "msw"; const meta = { - title: "v1/SBOMs/SBOM List", + title: "v2.0/SBOMs/SBOM List", component: SbomList, decorators: [ (Story) => ( diff --git a/client/src/stories/v1.2.x/search.stories.tsx b/client/src/stories/v2.0/search.stories.tsx similarity index 97% rename from client/src/stories/v1.2.x/search.stories.tsx rename to client/src/stories/v2.0/search.stories.tsx index e16640d1..ca0176cb 100644 --- a/client/src/stories/v1.2.x/search.stories.tsx +++ b/client/src/stories/v2.0/search.stories.tsx @@ -10,7 +10,7 @@ const CustomBody: React.FC = () => { }; const meta = { - title: "v1/Search", + title: "v2.0/Search", component: SearchPage, decorators: [ (Story) => ( diff --git a/client/src/stories/v2.1/home.stories.tsx b/client/src/stories/v2.1/home.stories.tsx index 47de2060..0b6bca3c 100644 --- a/client/src/stories/v2.1/home.stories.tsx +++ b/client/src/stories/v2.1/home.stories.tsx @@ -8,7 +8,7 @@ import { DefaultLayout } from "@app/layout"; const meta = { title: "v2.1/Home", component: () => { - return <>A custom homepage for v2.1; + return <>An example custom homepage for v2.1; }, decorators: [ (Story) => ( diff --git a/client/src/stories/v2.2/home.stories.tsx b/client/src/stories/v2.2/home.stories.tsx index c45ddf11..439de8b4 100644 --- a/client/src/stories/v2.2/home.stories.tsx +++ b/client/src/stories/v2.2/home.stories.tsx @@ -6,9 +6,9 @@ import { NotificationsProvider } from "@app/components/NotificationsContext"; import { DefaultLayout } from "@app/layout"; const meta = { - title: "v2.x/Home", + title: "v2.2/Home", component: () => { - return <>A custom homepage for v2.x; + return <>An example custom homepage for v2.2; }, decorators: [ (Story) => ( diff --git a/client/src/stories/v2.3/home.stories.tsx b/client/src/stories/v2.3/home.stories.tsx new file mode 100644 index 00000000..ed1b3c95 --- /dev/null +++ b/client/src/stories/v2.3/home.stories.tsx @@ -0,0 +1,31 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import React from "react"; +import { MemoryRouter } from "react-router"; +import Home from "@app/pages/home"; +import { NotificationsProvider } from "@app/components/NotificationsContext"; +import { DefaultLayout } from "@app/layout"; + +const meta = { + title: "v2.3/Home", + component: () => { + return <>An example custom homepage for v2.3; + }, + decorators: [ + (Story) => ( + + + + + + + + ), + ], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: {}, +};