diff --git a/client/src/app/pages/sbom-details/packages-by-sbom.tsx b/client/src/app/pages/sbom-details/packages-by-sbom.tsx index cac6d6497..0ae9f253a 100644 --- a/client/src/app/pages/sbom-details/packages-by-sbom.tsx +++ b/client/src/app/pages/sbom-details/packages-by-sbom.tsx @@ -1,5 +1,4 @@ import type React from "react"; -import { useMemo } from "react"; import { Link } from "react-router-dom"; import { @@ -7,9 +6,6 @@ import { DescriptionListDescription, DescriptionListGroup, DescriptionListTerm, - Flex, - FlexItem, - Label, List, ListItem, Toolbar, @@ -27,86 +23,75 @@ import { Tr, } from "@patternfly/react-table"; -import type { DecomposedPurl } from "@app/api/models"; -import type { PurlSummary } from "@app/client"; +import { FILTER_TEXT_CATEGORY_KEY } from "@app/Constants"; import { FilterToolbar, FilterType } from "@app/components/FilterToolbar"; -import { PackageQualifiers } from "@app/components/PackageQualifiers"; import { SimplePagination } from "@app/components/SimplePagination"; import { ConditionalTableBody, TableHeaderContentWithControls, TableRowContentWithControls, } from "@app/components/TableControls"; -import { useLocalTableControls } from "@app/hooks/table-controls"; +import { + getHubRequestParams, + useTableControlProps, + useTableControlState, +} from "@app/hooks/table-controls"; +import { useSelectionState } from "@app/hooks/useSelectionState"; import { useFetchPackagesBySbomId } from "@app/queries/packages"; -import { decomposePurl } from "@app/utils/utils"; - -interface TableData extends PurlSummary { - decomposedPurl?: DecomposedPurl; -} interface PackagesProps { sbomId: string; } export const PackagesBySbom: React.FC = ({ sbomId }) => { - const { - result: { data: allPackages }, - isFetching, - fetchError, - } = useFetchPackagesBySbomId(sbomId, { - page: { pageNumber: 1, itemsPerPage: 0 }, - }); - - const tableData = useMemo(() => { - return allPackages - .flatMap((item) => item.purl) - .map((item) => { - const result: TableData = { - ...item, - decomposedPurl: decomposePurl(item.purl), - }; - return result; - }); - }, [allPackages]); - - const tableControls = useLocalTableControls({ + const tableControlState = useTableControlState({ tableName: "package-table", - idProperty: "uuid", - items: tableData, - isLoading: isFetching, columnNames: { name: "Name", version: "Version", - qualifiers: "Qualifiers", }, - hasActionsColumn: false, isSortEnabled: true, - sortableColumns: ["name", "version"], - getSortValues: (item) => ({ - name: `${item.decomposedPurl?.name}/${item.decomposedPurl?.namespace}`, - version: item.version.version, - }), + sortableColumns: ["name"], isPaginationEnabled: true, isFilterEnabled: true, filterCategories: [ { - categoryKey: "filterText", - title: "Filter tex", + categoryKey: FILTER_TEXT_CATEGORY_KEY, + title: "Filter text", + placeholderText: "Search", type: FilterType.search, - placeholderText: "Filter", - getItemValue: (item) => { - return ( - `${item.decomposedPurl?.name}/${item.decomposedPurl?.namespace}` || - "" - ); - }, }, ], isExpansionEnabled: true, expandableVariant: "single", }); + const { + result: { data: packages, total: totalItemCount }, + isFetching, + fetchError, + } = useFetchPackagesBySbomId( + sbomId, + getHubRequestParams({ + ...tableControlState, + hubSortFieldKeys: { + name: "name", + }, + }), + ); + + const tableControls = useTableControlProps({ + ...tableControlState, + idProperty: "id", + currentPageItems: packages, + totalItemCount, + isLoading: isFetching, + selectionState: useSelectionState({ + items: packages, + isEqual: (a, b) => a.id === b.id, + }), + }); + const { currentPageItems, numRenderedColumns, @@ -145,52 +130,29 @@ export const PackagesBySbom: React.FC = ({ sbomId }) => { - {currentPageItems?.map((item, rowIndex) => { return ( - + - - - - {(() => { - const name = item.decomposedPurl?.name || ""; - const namespace = item.decomposedPurl?.namespace - ? `/${item.decomposedPurl.namespace}` - : ""; - return `${name}${namespace}`; - })()} - - - - - + + {[item.name, item.group].filter(Boolean).join("/")} - {item.decomposedPurl?.version} - - - {item.decomposedPurl?.qualifiers && ( - - )} + {item?.version} @@ -204,36 +166,20 @@ export const PackagesBySbom: React.FC = ({ sbomId }) => { className={spacing.pyLg} > - - - Packages - - - - - {item.purl} - - - - - + - Base package + External identifier - - {item.base.purl} - - - - Versions - {item.version.version} + {item.purl.map((item) => ( + + + {item.purl} + + + ))}