ImagesTable: extract toolbar to separate component

This extracts the toolbar, that was getting bit too big to a separate component.
It also adjusts the title to correspond to the filter of the images.
If there is a Blueprint selected, it changes the title to '<BlueprintName> images'
This commit is contained in:
Ondrej Ezr 2024-03-07 12:57:42 +01:00 committed by Lucas Garfield
parent 61c25e8331
commit 947c20875c
3 changed files with 136 additions and 62 deletions

View file

@ -2,25 +2,22 @@ import React from 'react';
import { Button } from '@patternfly/react-core';
import { selectSelectedBlueprintId } from '../../store/BlueprintSlice';
import { useAppSelector } from '../../store/hooks';
import { useComposeBlueprintMutation } from '../../store/imageBuilderApi';
interface BuildImagesButtonProps {
selectedBlueprint?: string | undefined;
}
export const BuildImagesButton: React.FunctionComponent<
BuildImagesButtonProps
> = ({ selectedBlueprint }: BuildImagesButtonProps) => {
export const BuildImagesButton = () => {
const selectedBlueprintId = useAppSelector(selectSelectedBlueprintId);
const [buildBlueprint, { isLoading: imageBuildLoading }] =
useComposeBlueprintMutation();
const onBuildHandler = async () => {
selectedBlueprint && (await buildBlueprint({ id: selectedBlueprint }));
selectedBlueprintId && (await buildBlueprint({ id: selectedBlueprintId }));
};
return (
<Button
ouiaId="build-images-button"
onClick={onBuildHandler}
isDisabled={!selectedBlueprint}
isDisabled={!selectedBlueprintId}
isLoading={imageBuildLoading}
>
Build images

View file

@ -11,7 +11,6 @@ import {
Spinner,
Bullseye,
Badge,
Title,
} from '@patternfly/react-core';
import {
ActionsColumn,
@ -23,7 +22,7 @@ import {
Thead,
Tr,
} from '@patternfly/react-table';
import { Link, NavigateFunction, useNavigate } from 'react-router-dom';
import { NavigateFunction, useNavigate } from 'react-router-dom';
import './ImagesTable.scss';
import ImagesEmptyState from './EmptyState';
@ -34,6 +33,7 @@ import {
GcpDetails,
OciDetails,
} from './ImageDetails';
import ImagesTableToolbar from './ImagesTableToolbar';
import { AwsS3Instance, CloudInstance, OciInstance } from './Instance';
import Release from './Release';
import { ExpiringStatus, CloudStatus } from './Status';
@ -64,9 +64,6 @@ import {
timestampToDisplayString,
} from '../../Utilities/time';
import { useExperimentalFlag } from '../../Utilities/useExperimentalFlag';
import { BlueprintActionsMenu } from '../Blueprints/BlueprintActionsMenu';
import { BuildImagesButton } from '../Blueprints/BuildImagesButton';
import { DeleteBlueprintModal } from '../Blueprints/DeleteBlueprintModal';
const ImagesTable = () => {
const [page, setPage] = useState(1);
@ -92,7 +89,6 @@ const ImagesTable = () => {
setPerPage(perPage);
};
const [showDeleteModal, setShowDeleteModal] = useState(false);
const {
data: blueprintsComposes,
isSuccess: isBlueprintsSuccess,
@ -173,54 +169,13 @@ const ImagesTable = () => {
return (
<>
<>
<DeleteBlueprintModal
setShowDeleteModal={setShowDeleteModal}
isOpen={showDeleteModal}
<ImagesTableToolbar
itemCount={itemCount}
perPage={perPage}
page={page}
onSetPage={onSetPage}
onPerPageSelect={onPerPageSelect}
/>
<Toolbar>
{experimentalFlag && (
<ToolbarContent>
<Title headingLevel="h1">All image types</Title>
</ToolbarContent>
)}
<ToolbarContent>
{!experimentalFlag && (
<ToolbarItem>
<Link
to={resolveRelPath('imagewizard')}
className="pf-c-button pf-m-primary"
data-testid="create-image-action"
>
Create image
</Link>
</ToolbarItem>
)}
{experimentalFlag && (
<>
<ToolbarItem>
<BuildImagesButton selectedBlueprint={selectedBlueprintId} />
</ToolbarItem>
<ToolbarItem>
<BlueprintActionsMenu
setShowDeleteModal={setShowDeleteModal}
/>
</ToolbarItem>
</>
)}
<ToolbarItem variant="pagination" align={{ default: 'alignRight' }}>
<Pagination
itemCount={itemCount}
perPage={perPage}
page={page}
onSetPage={onSetPage}
onPerPageSelect={onPerPageSelect}
widgetId="compose-pagination-top"
data-testid="images-pagination-top"
isCompact
/>
</ToolbarItem>
</ToolbarContent>
</Toolbar>
<Table variant="compact" data-testid="images-table">
<Thead>
<Tr>

View file

@ -0,0 +1,122 @@
import React, { useState } from 'react';
import {
Pagination,
Toolbar,
ToolbarContent,
ToolbarItem,
Title,
} from '@patternfly/react-core';
import { Link } from 'react-router-dom';
import {
selectSelectedBlueprintId,
selectBlueprintSearchInput,
} from '../../store/BlueprintSlice';
import { useAppSelector } from '../../store/hooks';
import {
BlueprintItem,
useGetBlueprintsQuery,
} from '../../store/imageBuilderApi';
import { resolveRelPath } from '../../Utilities/path';
import { useExperimentalFlag } from '../../Utilities/useExperimentalFlag';
import { BlueprintActionsMenu } from '../Blueprints/BlueprintActionsMenu';
import { BuildImagesButton } from '../Blueprints/BuildImagesButton';
import { DeleteBlueprintModal } from '../Blueprints/DeleteBlueprintModal';
interface imagesTableToolbarProps {
itemCount: number;
perPage: number;
page: number;
onSetPage: (event: React.MouseEvent, page: number) => void;
onPerPageSelect: (event: React.MouseEvent, perPage: number) => void;
}
const ImagesTableToolbar: React.FC<imagesTableToolbarProps> = ({
itemCount,
perPage,
page,
onSetPage,
onPerPageSelect,
}: imagesTableToolbarProps) => {
const experimentalFlag = useExperimentalFlag();
const [showDeleteModal, setShowDeleteModal] = useState(false);
const selectedBlueprintId = useAppSelector(selectSelectedBlueprintId);
const blueprintSearchInput = useAppSelector(selectBlueprintSearchInput);
const { selectedBlueprintName } = useGetBlueprintsQuery(
{ search: blueprintSearchInput },
{
selectFromResult: ({ data }) => ({
selectedBlueprintName: data?.data?.find(
(blueprint: BlueprintItem) => blueprint.id === selectedBlueprintId
)?.name,
}),
}
);
const pagination = (
<Pagination
itemCount={itemCount}
perPage={perPage}
page={page}
onSetPage={onSetPage}
onPerPageSelect={onPerPageSelect}
widgetId="compose-pagination-top"
data-testid="images-pagination-top"
isCompact
/>
);
if (!experimentalFlag) {
return (
<Toolbar>
<ToolbarContent>
<ToolbarItem>
<Link
to={resolveRelPath('imagewizard')}
className="pf-c-button pf-m-primary"
data-testid="create-image-action"
>
Create image
</Link>
</ToolbarItem>
<ToolbarItem variant="pagination" align={{ default: 'alignRight' }}>
{pagination}
</ToolbarItem>
</ToolbarContent>
</Toolbar>
);
}
return (
<>
<DeleteBlueprintModal
setShowDeleteModal={setShowDeleteModal}
isOpen={showDeleteModal}
/>
<Toolbar>
<ToolbarContent>
<Title headingLevel="h1">
{selectedBlueprintId
? `${selectedBlueprintName} images`
: 'All images'}
</Title>
</ToolbarContent>
<ToolbarContent>
<ToolbarItem>
<BuildImagesButton />
</ToolbarItem>
<ToolbarItem>
<BlueprintActionsMenu setShowDeleteModal={setShowDeleteModal} />
</ToolbarItem>
<ToolbarItem variant="pagination" align={{ default: 'alignRight' }}>
{pagination}
</ToolbarItem>
</ToolbarContent>
</Toolbar>
</>
);
};
export default ImagesTableToolbar;