Skip to content

Commit

Permalink
update table filters into separate chip groups (#3202)
Browse files Browse the repository at this point in the history
* address UX concerns with connection types

* separate table filters into separate chip groups
  • Loading branch information
christianvogt committed Sep 17, 2024
1 parent 7964daa commit ec193eb
Show file tree
Hide file tree
Showing 23 changed files with 76 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('Manage runs', () => {
});

it('has param experiment filter by default', () => {
cy.findByTestId('experiment-filter-chip').should('have.text', 'Experiment: Default');
cy.findByTestId('experiment-filter-chip').should('have.text', 'Default');
});

it('has param run IDs checked by default', () => {
Expand Down
79 changes: 35 additions & 44 deletions frontend/src/components/FilterToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import {
ToolbarFilter,
ToolbarGroup,
ToolbarItem,
ToolbarChip,
Tooltip,
Dropdown,
DropdownItem,
MenuToggle,
Expand All @@ -24,7 +22,6 @@ export type ToolbarFilterProps<T extends string> = React.ComponentProps<typeof T
filterOptionRenders: Record<T, (props: FilterOptionRenders) => React.ReactNode>;
filterData: Record<T, string | { label: string; value: string } | undefined>;
onFilterUpdate: (filterType: T, value?: string | { label: string; value: string }) => void;
onClearFilters: () => void;
testId?: string;
};

Expand All @@ -33,7 +30,6 @@ function FilterToolbar<T extends string>({
filterOptionRenders,
filterData,
onFilterUpdate,
onClearFilters,
children,
testId = 'filter-toolbar',
...toolbarGroupProps
Expand All @@ -42,8 +38,6 @@ function FilterToolbar<T extends string>({
const keys = Object.keys(filterOptions) as Array<T>;
const [open, setOpen] = React.useState(false);
const [currentFilterType, setCurrentFilterType] = React.useState<T>(keys[0]);
const isToolbarChip = (v: unknown): v is ToolbarChip & { key: T } =>
!!v && Object.keys(v).every((k) => ['key', 'node'].includes(k));
const filterItem = filterData[currentFilterType];

return (
Expand Down Expand Up @@ -85,45 +79,42 @@ function FilterToolbar<T extends string>({
</DropdownList>
</Dropdown>
</ToolbarItem>
<ToolbarFilter
categoryName="Filters"
data-testid={`${testId}-text-field`}
variant="search-filter"
chips={keys
.map<ToolbarChip | null>((filterKey) => {
const optionValue = filterOptions[filterKey];
const data = filterData[filterKey];
if (data) {
const dataValue: { label: string; value: string } | undefined =
typeof data === 'string' ? { label: data, value: data } : data;
return {
key: filterKey,
node: (
<span data-testid={`${optionValue?.toLowerCase()}-filter-chip`}>
<b>{optionValue}:</b>{' '}
<Tooltip content={dataValue.value} position="top-start">
<span>{dataValue.label}</span>
</Tooltip>
</span>
),
};
{keys.map((filterKey) => {
const optionValue = filterOptions[filterKey];
const data = filterData[filterKey];
const dataValue: { label: string; value: string } | undefined =
typeof data === 'string' ? { label: data, value: data } : data;
return optionValue ? (
<ToolbarFilter
key={filterKey}
categoryName={optionValue}
data-testid={`${testId}-text-field`}
variant="search-filter"
chips={
data && dataValue
? [
{
key: filterKey,
node: (
<span data-testid={`${filterKey}-filter-chip`}>{dataValue.label}</span>
),
},
]
: []
}
return null;
})
.filter(isToolbarChip)}
deleteChip={(_, chip) => {
if (isToolbarChip(chip)) {
onFilterUpdate(chip.key, '');
}
}}
deleteChipGroup={() => onClearFilters()}
>
{filterOptionRenders[currentFilterType]({
onChange: (value, label) =>
onFilterUpdate(currentFilterType, label && value ? { label, value } : value),
...(typeof filterItem === 'string' ? { value: filterItem } : filterItem),
})}
</ToolbarFilter>
deleteChip={() => {
onFilterUpdate(filterKey, '');
}}
showToolbarItem={currentFilterType === filterKey}
>
{filterOptionRenders[filterKey]({
onChange: (value, label) =>
onFilterUpdate(filterKey, label && value ? { label, value } : value),
...(typeof filterItem === 'string' ? { value: filterItem } : filterItem),
})}
</ToolbarFilter>
) : null;
})}
</ToolbarGroup>
{children}
</>
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/components/table/TableBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Props<DataType> = {
enablePagination?: boolean | 'compact';
truncateRenderingAt?: number;
toolbarContent?: React.ReactElement<typeof ToolbarItem | typeof ToolbarGroup>;
onClearFilters?: () => void;
bottomToolbarContent?: React.ReactElement<typeof ToolbarItem | typeof ToolbarGroup>;
emptyTableView?: React.ReactNode;
caption?: string;
Expand Down Expand Up @@ -92,6 +93,7 @@ const TableBase = <T,>({
rowRenderer,
enablePagination,
toolbarContent,
onClearFilters,
bottomToolbarContent,
emptyTableView,
caption,
Expand Down Expand Up @@ -274,7 +276,8 @@ const TableBase = <T,>({
<Toolbar
inset={{ default: 'insetNone' }}
className="pf-v5-u-w-100"
customChipGroupContent={<></>}
customChipGroupContent={onClearFilters ? undefined : <></>}
clearAllFilters={onClearFilters}
>
<ToolbarContent>
{toolbarContent}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useCompareRuns } from '~/concepts/pipelines/content/compareRuns/Compare

export type FilterProps = Pick<
React.ComponentProps<typeof PipelineFilterBar>,
'filterData' | 'onFilterUpdate' | 'onClearFilters'
'filterData' | 'onFilterUpdate'
>;

const CompareRunTableToolbar: React.FC<FilterProps> = ({ ...toolbarProps }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const ExperimentTable: React.FC<ExperimentTableProps> = ({
getActionColumnItems,
...tableProps
}) => {
const filterToolbarProps = usePipelineFilter(setFilter);
const { onClearFilters, ...filterToolbarProps } = usePipelineFilter(setFilter);
const {
selections,
tableProps: checkboxTableProps,
Expand All @@ -65,9 +65,8 @@ const ExperimentTable: React.FC<ExperimentTableProps> = ({
data={experiments}
columns={experimentColumns}
enablePagination="compact"
emptyTableView={
<DashboardEmptyTableView onClearFilters={filterToolbarProps.onClearFilters} />
}
emptyTableView={<DashboardEmptyTableView onClearFilters={onClearFilters} />}
onClearFilters={onClearFilters}
toolbarContent={
<ExperimentTableToolbar data-testid="experiment-table-toolbar" {...filterToolbarProps}>
{toolbarContentRenderer(selections)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const options = {

export type FilterProps = Pick<
React.ComponentProps<typeof PipelineFilterBar>,
'filterData' | 'onFilterUpdate' | 'onClearFilters'
'filterData' | 'onFilterUpdate'
>;

type ExperimentTableToolbarProps = FilterProps & {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type PipelinesTableProps = {
setSortDirection: (dir: 'asc' | 'desc') => void;
} & Pick<
React.ComponentProps<typeof Table>,
'toolbarContent' | 'emptyTableView' | 'enablePagination' | 'variant'
'toolbarContent' | 'emptyTableView' | 'enablePagination' | 'variant' | 'onClearFilters'
>;

const PipelinesTable: React.FC<PipelinesTableProps> = ({
Expand All @@ -38,6 +38,7 @@ const PipelinesTable: React.FC<PipelinesTableProps> = ({
emptyTableView,
toolbarContent,
variant,
onClearFilters,
...sortProps
}) => {
const { refreshAllAPI } = usePipelinesAPI();
Expand All @@ -56,6 +57,7 @@ const PipelinesTable: React.FC<PipelinesTableProps> = ({
{...checkboxTableProps}
enablePagination={enablePagination}
emptyTableView={emptyTableView}
onClearFilters={onClearFilters}
toolbarContent={toolbarContent}
variant={variant}
loading={loading}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const PipelineRecurringRunTable: React.FC<PipelineRecurringRunTableProps> = ({
}) => {
const { refreshAllAPI } = usePipelinesAPI();
const { experimentId, pipelineVersionId } = useParams();
const filterToolbarProps = usePipelineFilter(setFilter);
const { onClearFilters, ...filterToolbarProps } = usePipelineFilter(setFilter);
const isExperimentsAvailable = useIsAreaAvailable(SupportedArea.PIPELINE_EXPERIMENTS).status;
const {
selections,
Expand Down Expand Up @@ -88,9 +88,8 @@ const PipelineRecurringRunTable: React.FC<PipelineRecurringRunTableProps> = ({
data={recurringRuns}
columns={getColumns()}
enablePagination="compact"
emptyTableView={
<DashboardEmptyTableView onClearFilters={filterToolbarProps.onClearFilters} />
}
emptyTableView={<DashboardEmptyTableView onClearFilters={onClearFilters} />}
onClearFilters={onClearFilters}
toolbarContent={
<PipelineRecurringRunTableToolbar
{...filterToolbarProps}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useContextExperimentArchived as useIsExperimentArchived } from '~/pages

export type FilterProps = Pick<
React.ComponentProps<typeof PipelineFilterBar>,
'filterData' | 'onFilterUpdate' | 'onClearFilters'
'filterData' | 'onFilterUpdate'
>;

interface PipelineRecurringRunTableToolbarProps extends FilterProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const PipelineRunTableInternal: React.FC<PipelineRunTableInternalProps> = ({
const navigate = useNavigate();
const { experimentId, pipelineVersionId, pipelineId } = useParams();
const { namespace, refreshAllAPI } = usePipelinesAPI();
const filterToolbarProps = usePipelineFilter(setFilter);
const { onClearFilters, ...filterToolbarProps } = usePipelineFilter(setFilter);
const {
selections: selectedIds,
tableProps: checkboxTableProps,
Expand Down Expand Up @@ -234,9 +234,8 @@ const PipelineRunTableInternal: React.FC<PipelineRunTableInternalProps> = ({
data={runs}
columns={getColumns()}
enablePagination="compact"
emptyTableView={
<DashboardEmptyTableView onClearFilters={filterToolbarProps.onClearFilters} />
}
emptyTableView={<DashboardEmptyTableView onClearFilters={onClearFilters} />}
onClearFilters={onClearFilters}
toolbarContent={
<PipelineRunTableToolbar
data-testid={`${runType}-runs-table-toolbar`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas';

export type FilterProps = Pick<
React.ComponentProps<typeof PipelineFilterBar>,
'filterData' | 'onFilterUpdate' | 'onClearFilters'
'filterData' | 'onFilterUpdate'
>;

interface PipelineRunTableToolbarProps extends FilterProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export const getDataValue = (data: string | { value: string } | undefined): stri

export type FilterProps = Pick<
React.ComponentProps<typeof FilterToolbar>,
'filterData' | 'onFilterUpdate' | 'onClearFilters'
>;
'filterData' | 'onFilterUpdate'
> & { onClearFilters: () => void };

const defaultFilterData: FilterProps['filterData'] = {
[FilterOptions.NAME]: '',
Expand Down
7 changes: 2 additions & 5 deletions frontend/src/pages/connectionTypes/ConnectionTypesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,9 @@ const ConnectionTypesTable: React.FC<Props> = ({ connectionTypes, onUpdate }) =>
handleDelete={(connection) => setDeleteConnectionType(connection)}
/>
)}
onClearFilters={onClearFilters}
toolbarContent={
<ConnectionTypesTableToolbar
filterData={filterData}
setFilterData={setFilterData}
onClearFilters={onClearFilters}
/>
<ConnectionTypesTableToolbar filterData={filterData} setFilterData={setFilterData} />
}
disableItemCount
emptyTableView={<DashboardEmptyTableView onClearFilters={onClearFilters} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,9 @@ import { ConnectionTypesOptions, FilterDataType, options } from '~/pages/connect
type Props = {
filterData: Record<ConnectionTypesOptions, string | undefined>;
setFilterData: React.Dispatch<React.SetStateAction<FilterDataType>>;
onClearFilters: () => void;
};

const ConnectionTypesTableToolbar: React.FC<Props> = ({
setFilterData,
filterData,
onClearFilters,
}) => {
const ConnectionTypesTableToolbar: React.FC<Props> = ({ setFilterData, filterData }) => {
const onFilterUpdate = React.useCallback(
(key: string, value: string | { label: string; value: string } | undefined) =>
setFilterData((prevValues) => ({ ...prevValues, [key]: value })),
Expand Down Expand Up @@ -52,7 +47,6 @@ const ConnectionTypesTableToolbar: React.FC<Props> = ({
),
}}
filterData={filterData}
onClearFilters={onClearFilters}
onFilterUpdate={onFilterUpdate}
>
<ToolbarItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,11 @@ export const ArtifactsTable: React.FC<ArtifactsTableProps> = ({
),
}}
filterData={filterData}
onClearFilters={onClearFilters}
onFilterUpdate={onFilterUpdate}
data-testid="artifacts-table-toolbar"
/>
),
[filterData, onClearFilters, onFilterUpdate],
[filterData, onFilterUpdate],
);

const rowRenderer = React.useCallback(
Expand Down Expand Up @@ -183,6 +182,7 @@ export const ArtifactsTable: React.FC<ArtifactsTableProps> = ({
}}
onPerPageSelect={(_, newSize) => setMaxResultSize(newSize)}
toggleTemplate={() => <>{maxResultSize} per page </>}
onClearFilters={onClearFilters}
toolbarContent={toolbarContent}
emptyTableView={<DashboardEmptyTableView onClearFilters={onClearFilters} />}
rowRenderer={rowRenderer}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const ManageRunsPageInternal: React.FC<ManageRunsPageInternalProps> = ({
const { namespace, project } = usePipelinesAPI();
const [[{ items: runs, totalSize }, loaded, error], { initialLoaded, ...tableProps }] =
usePipelineActiveRunsTable();
const filterProps = usePipelineFilter(tableProps.setFilter, {
const { onClearFilters, ...filterProps } = usePipelineFilter(tableProps.setFilter, {
[FilterOptions.EXPERIMENT]: {
label: experiment.display_name,
value: experiment.experiment_id,
Expand Down Expand Up @@ -153,6 +153,7 @@ export const ManageRunsPageInternal: React.FC<ManageRunsPageInternalProps> = ({
runs={runs}
experiment={experiment}
filterProps={filterProps}
onClearFilters={onClearFilters}
selectedRunIds={selectedRunIds}
loading={!loaded}
totalSize={totalSize}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type ManageRunsTableProps = Omit<React.ComponentProps<typeof PipelineRunTable>,
filterProps: FilterProps;
selectedRunIds: string[];
experiment: ExperimentKFv2 | null;
onClearFilters: () => void;
};

export const ManageRunsTable: React.FC<ManageRunsTableProps> = ({
Expand All @@ -34,6 +35,7 @@ export const ManageRunsTable: React.FC<ManageRunsTableProps> = ({
setPage,
setPageSize,
filterProps,
onClearFilters,
...tableProps
}) => {
const navigate = useNavigate();
Expand Down Expand Up @@ -86,7 +88,8 @@ export const ManageRunsTable: React.FC<ManageRunsTableProps> = ({
data={runs}
columns={pipelineRunColumns}
enablePagination="compact"
emptyTableView={<DashboardEmptyTableView onClearFilters={filterProps.onClearFilters} />}
emptyTableView={<DashboardEmptyTableView onClearFilters={onClearFilters} />}
onClearFilters={onClearFilters}
toolbarContent={
<PipelineRunTableToolbar
data-testid="manage-runs-table-toolbar"
Expand Down
Loading

0 comments on commit ec193eb

Please sign in to comment.