Skip to content

Commit

Permalink
fix: Toggle on/off Catalog "component", "proceeosr" and "kamelet" ind…
Browse files Browse the repository at this point in the history
…ependently. Enable all of them by default

Fixes: KaotoIO#1040
Fixes: KaotoIO#1039
  • Loading branch information
igarashitm committed Apr 30, 2024
1 parent c85ec20 commit 6826941
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 47 deletions.
53 changes: 19 additions & 34 deletions packages/ui/src/components/Catalog/BaseCatalog.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { DataList, Gallery, Title } from '@patternfly/react-core';
import { FunctionComponent, useCallback, useEffect, useRef } from 'react';
import './BaseCatalog.scss';
import { CatalogLayout, ITile } from './Catalog.models';
import { CatalogDataListItem } from './DataListItem';
import { Tile } from './Tile';
import { BaseCatalogItemGroup } from './BaseCatalogItemGroup';

interface BaseCatalogProps {
className?: string;
tiles: ITile[];
activeGroups: string[];
tilesByGroup: Record<string, ITile[]>;
catalogLayout: CatalogLayout;
onTileClick?: (tile: ITile) => void;
onTagClick: (_event: unknown, value: string) => void;
Expand All @@ -22,39 +21,25 @@ export const BaseCatalog: FunctionComponent<BaseCatalogProps> = (props) => {
[props],
);

const onSelectDataListItem = useCallback(
(_event: React.MouseEvent | React.KeyboardEvent, id: string) => {
const tile = props.tiles.find((tile) => tile.name === id);
onTileClick(tile!);
},
[onTileClick, props.tiles],
);

useEffect(() => {
catalogBodyRef.current!.scrollTop = 0;
}, [props.tiles]);
}, [props.tilesByGroup]);

return (
<>
<Title headingLevel="h2" size="xl">
Showing {props.tiles?.length} elements
</Title>
<div id="catalog-list" className="catalog-list" ref={catalogBodyRef}>
{props.catalogLayout == CatalogLayout.List && (
<DataList aria-label="Catalog list" onSelectDataListItem={onSelectDataListItem} isCompact>
{props.tiles?.map((tile) => (
<CatalogDataListItem key={`${tile.name}-${tile.type}`} tile={tile} onTagClick={props.onTagClick} />
))}
</DataList>
)}
{props.catalogLayout == CatalogLayout.Gallery && (
<Gallery hasGutter>
{props.tiles?.map((tile) => (
<Tile key={`${tile.name}-${tile.type}`} tile={tile} onClick={onTileClick} onTagClick={props.onTagClick} />
))}
</Gallery>
)}
</div>
</>
<div id="catalog-list" className="catalog-list" ref={catalogBodyRef}>
{Object.entries(props.tilesByGroup).map(
([group, tiles]) =>
props.activeGroups.includes(group) &&
tiles.length > 0 && (
<BaseCatalogItemGroup
group={group}
tiles={tiles}
catalogLayout={props.catalogLayout}
onTagClick={props.onTagClick}
onTileClick={onTileClick}
/>
),
)}
</div>
);
};
62 changes: 62 additions & 0 deletions packages/ui/src/components/Catalog/BaseCatalogItemGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Card, CardExpandableContent, CardHeader, CardTitle, DataList, Gallery } from '@patternfly/react-core';
import { CatalogDataListItem } from './DataListItem';
import { Tile } from './Tile';
import { FunctionComponent, useCallback, useState } from 'react';
import { CatalogLayout, ITile } from './Catalog.models';

interface BaseCatalogItemGroupProps {
group: string;
tiles: ITile[];
catalogLayout: CatalogLayout;
onTagClick: (_event: unknown, value: string) => void;
onTileClick: (tile: ITile) => void;
}

export const BaseCatalogItemGroup: FunctionComponent<BaseCatalogItemGroupProps> = ({
group,
tiles,
catalogLayout,
onTagClick,
onTileClick,
}) => {
const [isExpanded, setIsExpanded] = useState<boolean>(true);

const toggleExpand = useCallback(
(_event: React.MouseEvent, _id: string) => {
setIsExpanded(!isExpanded);
},
[isExpanded],
);

const onSelectDataListItem = useCallback(
(_event: React.MouseEvent | React.KeyboardEvent, id: string) => {
const tile = tiles.find((tile) => tile.name === id);
onTileClick(tile!);
},
[onTileClick, tiles],
);

return (
<Card key={`catalog-card-${group}`} data-testid={`catalog-card-${group}`} isLarge isExpanded={isExpanded}>
<CardHeader onExpand={toggleExpand}>
<CardTitle>{`${group.charAt(0).toUpperCase() + group.slice(1)}s (${tiles.length})`}</CardTitle>
</CardHeader>
<CardExpandableContent>
{catalogLayout == CatalogLayout.List && (
<DataList aria-label="Catalog list" onSelectDataListItem={onSelectDataListItem} isCompact>
{tiles.map((tile) => (
<CatalogDataListItem key={`${tile.name}-${tile.type}`} tile={tile} onTagClick={onTagClick} />
))}
</DataList>
)}
{catalogLayout == CatalogLayout.Gallery && (
<Gallery hasGutter>
{tiles.map((tile) => (
<Tile key={`${tile.name}-${tile.type}`} tile={tile} onClick={onTileClick} onTagClick={onTagClick} />
))}
</Gallery>
)}
</CardExpandableContent>
</Card>
);
};
10 changes: 5 additions & 5 deletions packages/ui/src/components/Catalog/Catalog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ export const Catalog: FunctionComponent<PropsWithChildren<CatalogProps>> = (prop
return Object.entries(filteredTilesByGroup).map(([group, tiles]) => ({ name: group, count: tiles.length }));
}, [filteredTilesByGroup]);

const [activeGroup, setActiveGroup] = useState<string>(tilesGroups[0].name);
const [activeGroups, setActiveGroups] = useState<string[]>(tilesGroups.map((g) => g.name));
const [activeLayout, setActiveLayout] = useLocalStorage(LocalStorageKeys.CatalogLayout, CatalogLayout.Gallery);
const filteredTiles = useMemo(() => filteredTilesByGroup[activeGroup] ?? [], [activeGroup, filteredTilesByGroup]);

const onFilterChange = useCallback(
(_event: unknown, value = '') => {
Expand Down Expand Up @@ -62,17 +61,18 @@ export const Catalog: FunctionComponent<PropsWithChildren<CatalogProps>> = (prop
searchTerm={searchTerm}
groups={tilesGroups}
layouts={[CatalogLayout.Gallery, CatalogLayout.List]}
activeGroup={activeGroup}
activeGroups={activeGroups}
activeLayout={activeLayout}
filterTags={filterTags}
onChange={onFilterChange}
setActiveGroup={setActiveGroup}
setActiveGroups={setActiveGroups}
setActiveLayout={setActiveLayout}
setFilterTags={setFilterTags}
/>
<BaseCatalog
className="catalog__base"
tiles={filteredTiles}
activeGroups={activeGroups}
tilesByGroup={filteredTilesByGroup}
catalogLayout={activeLayout}
onTileClick={onTileClick}
onTagClick={onTagClick}
Expand Down
25 changes: 17 additions & 8 deletions packages/ui/src/components/Catalog/CatalogFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ interface CatalogFilterProps {
searchTerm: string;
groups: { name: string; count: number }[];
layouts: CatalogLayout[];
activeGroup: string;
activeGroups: string[];
activeLayout: CatalogLayout;
filterTags: string[];
onChange: (event: unknown, value?: string) => void;
setActiveGroup: (group: string) => void;
setActiveGroups: (groups: string[]) => void;
setActiveLayout: (layout: CatalogLayout) => void;
setFilterTags: (tags: string[]) => void;
}
Expand All @@ -40,12 +40,24 @@ export const CatalogFilter: FunctionComponent<CatalogFilterProps> = (props) => {
props.setFilterTags(props.filterTags.filter((savedTag) => savedTag !== tag));
};

const toggleActiveGroup = (selected: boolean, group: string) => {
if (selected && !props.activeGroups.includes(group)) {
props.activeGroups.push(group);
props.setActiveGroups([...props.activeGroups]);
} else if (!selected && props.activeGroups.includes(group)) {
props.activeGroups.splice(props.activeGroups.indexOf(group), 1);
props.setActiveGroups([...props.activeGroups]);
}
inputRef.current?.focus();
};

return (
<Form className={props.className}>
<Grid hasGutter>
<GridItem md={5} lg={6}>
<FormGroup label="Filter" fieldId="search-term">
<SearchInput
data-testid="catalog-search-input"
aria-label="Filter by name, description or tag"
placeholder="Filter by name, description or tag"
value={props.searchTerm}
Expand All @@ -67,13 +79,10 @@ export const CatalogFilter: FunctionComponent<CatalogFilterProps> = (props) => {
</>
}
key={tileGroup.name}
data-testid={`${tileGroup.name}-catalog-tab`}
data-testid={`${tileGroup.name}-catalog-toggle`}
buttonId={`toggle-group-button-${tileGroup.name}`}
isSelected={props.activeGroup === tileGroup.name}
onChange={() => {
props.setActiveGroup(tileGroup.name);
inputRef.current?.focus();
}}
isSelected={props.activeGroups.includes(tileGroup.name)}
onChange={(_event, selected: boolean) => toggleActiveGroup(selected, tileGroup.name)}
/>
))}
</ToggleGroup>
Expand Down

0 comments on commit 6826941

Please sign in to comment.