diff --git a/src/Components/CreateImageWizardV2/CreateImageWizard.scss b/src/Components/CreateImageWizardV2/CreateImageWizard.scss index 4f159154..6aba0e42 100644 --- a/src/Components/CreateImageWizardV2/CreateImageWizard.scss +++ b/src/Components/CreateImageWizardV2/CreateImageWizard.scss @@ -68,3 +68,7 @@ ul.pf-m-plain { .not-available { color: #6a6e73; } + +.panel-border { + --pf-v5-c-panel--before--BorderColor: #BEE1F4; +} diff --git a/src/Components/CreateImageWizardV2/steps/Packages/PackageRecommendations.tsx b/src/Components/CreateImageWizardV2/steps/Packages/PackageRecommendations.tsx new file mode 100644 index 00000000..d40c8d03 --- /dev/null +++ b/src/Components/CreateImageWizardV2/steps/Packages/PackageRecommendations.tsx @@ -0,0 +1,173 @@ +import React, { useEffect, useState } from 'react'; + +import { + Alert, + Button, + ExpandableSection, + Icon, + Panel, + PanelMain, + PanelMainBody, + Spinner, + Text, + TextContent, +} from '@patternfly/react-core'; +import { OptimizeIcon } from '@patternfly/react-icons'; +import { Table, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table'; +import { useDispatch } from 'react-redux'; + +import { useAppSelector } from '../../../../store/hooks'; +import { useRecommendPackageMutation } from '../../../../store/imageBuilderApi'; +import { addPackage, selectPackages } from '../../../../store/wizardSlice'; + +const PackageRecommendations = () => { + const dispatch = useDispatch(); + + const packages = useAppSelector(selectPackages); + + const [isExpanded, setIsExpanded] = useState(false); + + const onToggle = (_event: React.MouseEvent, isExpanded: boolean) => { + setIsExpanded(isExpanded); + }; + + const [fetchRecommendedPackages, { data, isSuccess, isLoading, isError }] = + useRecommendPackageMutation(); + + useEffect(() => { + const getRecommendedPackages = async () => { + await fetchRecommendedPackages({ + recommendPackageRequest: { + packages: packages.map((pkg) => pkg.name), + recommendedPackages: 5, + }, + }); + }; + + if (packages.length > 0) { + getRecommendedPackages(); + } + }, [fetchRecommendedPackages, packages]); + + const addAllPackages = () => { + if (data) { + for (const pkg in data[0].packages) { + dispatch( + addPackage({ + name: data[0].packages[pkg], + summary: 'Added from recommended packages', + repository: 'distro', + isRequiredByOpenScap: false, + }) + ); + } + } + }; + + const addRecommendedPackage = (pkg: string) => { + dispatch( + addPackage({ + name: pkg, + summary: 'Added from recommended packages', + repository: 'distro', + isRequiredByOpenScap: false, + }) + ); + }; + + const isRecommendedPackageSelected = (recPkg: string) => { + const foundInPackages = packages.some((pkg) => recPkg === pkg.name); + return foundInPackages; + }; + + return ( + + + + + + + {' '} + Recommended Red Hat packages + > + } + onToggle={onToggle} + isExpanded={isExpanded} + > + {packages.length === 0 && ( + <>Select packages to generate recommendations.> + )} + {isLoading && } + {isError && ( + + There was an error when fetching package recommendations. Try + again by changing your selected packages. + + )} + {isSuccess && !data && ( + <>No recommendations found for the set of selected packages> + )} + {isSuccess && data && data[0].packages && ( + <> + + + Other users commonly add these packages with the ones you + selected. + + + + + + Package name + {/*Package summary*/} + + addAllPackages()} + isInline + data-testid="add-all-recommendations-button" + > + Add all packages + + + + + + {data[0].packages.map((pkg) => ( + + {pkg} + {/*TODO summary*/} + + addRecommendedPackage(pkg)} + isInline + isDisabled={isRecommendedPackageSelected(pkg)} + data-testid="add-recommendation-button" + > + Add package + + + + ))} + + + > + )} + + + + + ); +}; + +export default PackageRecommendations; diff --git a/src/Components/CreateImageWizardV2/steps/Packages/index.tsx b/src/Components/CreateImageWizardV2/steps/Packages/index.tsx index b569ab08..3f5498d9 100644 --- a/src/Components/CreateImageWizardV2/steps/Packages/index.tsx +++ b/src/Components/CreateImageWizardV2/steps/Packages/index.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Text, Form, Title } from '@patternfly/react-core'; +import PackageRecommendations from './PackageRecommendations'; import Packages from './Packages'; const PackagesStep = () => { @@ -12,6 +13,7 @@ const PackagesStep = () => { Blueprints created with Images include all required packages. + ); };