Skip to content

Commit

Permalink
Merge pull request #167 from Kuadrant/resource-filtering
Browse files Browse the repository at this point in the history
Resource filtering
  • Loading branch information
openshift-merge-bot[bot] authored Nov 19, 2024
2 parents 3d36c5c + 9addfde commit 59839c4
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 21 deletions.
1 change: 1 addition & 0 deletions locales/en/plugin__kuadrant-console-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"Reference to an existing secret resource containing DNS provider credentials and configuration": "Reference to an existing secret resource containing DNS provider credentials and configuration",
"Release Notes": "Release Notes",
"Save": "Save",
"Search by {{filterValue}}...": "Search by {{filterValue}}...",
"Select a gateway": "Select a gateway",
"Select a Protocol": "Select a Protocol",
"Select an ClusterIssuer": "Select an ClusterIssuer",
Expand Down
2 changes: 1 addition & 1 deletion src/components/KuadrantOverviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ const KuadrantOverviewPage: React.FC = () => {
<title data-test="example-page-title">{t('Kuadrant')}</title>
</Helmet>
<Page>
<PageSection>
<PageSection isFilled>
<Title headingLevel="h1">{t('Kuadrant')} Overview</Title>
<br />

Expand Down
116 changes: 104 additions & 12 deletions src/components/ResourceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,28 @@ import {
EmptyStateBody,
Title,
Tooltip,
ToolbarItem,
ToolbarGroup,
Select,
MenuToggle,
InputGroup,
TextInput,
MenuToggleElement,
SelectOption,
Toolbar,
ToolbarContent,
} from '@patternfly/react-core';
import {
K8sResourceCommon,
ResourceLink,
useK8sWatchResources,
VirtualizedTable,
useListPageFilter,
Timestamp,
TableData,
RowProps,
TableColumn,
WatchK8sResource,
ListPageBody,
ListPageFilter,
} from '@openshift-console/dynamic-plugin-sdk';
import { SearchIcon } from '@patternfly/react-icons';
import {
Expand Down Expand Up @@ -340,8 +348,12 @@ const ResourceList: React.FC<ResourceListProps> = ({
resourceDescriptors,
);

const allData = Object.values(watchedResources).flatMap((res) =>
res.loaded && !res.loadError ? (res.data as K8sResourceCommon[]) : [],
const allData = React.useMemo(
() =>
Object.values(watchedResources).flatMap((res) =>
res.loaded && !res.loadError ? (res.data as K8sResourceCommon[]) : [],
),
[watchedResources],
);

const allLoaded = Object.values(watchedResources).every((res) => res.loaded);
Expand All @@ -353,7 +365,42 @@ const ResourceList: React.FC<ResourceListProps> = ({
const combinedLoadError =
loadErrors.length > 0 ? new Error(loadErrors.map((err) => err.message).join('; ')) : null;

const [data, filteredData, onFilterChange] = useListPageFilter(allData);
// Implement local filter state
const [filters, setFilters] = React.useState<string>('');
const [isOpen, setIsOpen] = React.useState(false);
const [filterSelected, setFilterSelected] = React.useState('Name');
const [filteredData, setFilteredData] = React.useState<K8sResourceCommon[]>([]);

const onToggleClick = () => {
setIsOpen(!isOpen);
};

const onFilterSelect = (
_event: React.MouseEvent<Element, MouseEvent> | undefined,
selection: string,
) => {
setFilterSelected(selection);
setIsOpen(false);
};

React.useEffect(() => {
let data = allData;

if (filters) {
const filterValue = filters.toLowerCase();
data = data.filter((item) => {
if (filterSelected === 'Name') {
return item.metadata.name.toLowerCase().includes(filterValue);
} else if (filterSelected === 'Namespace') {
return item.metadata.namespace?.toLowerCase().includes(filterValue);
} else if (filterSelected === 'Type') {
return item.kind.toLowerCase().includes(filterValue);
}
return true;
});
}
setFilteredData(data);
}, [allData, filters]);

const defaultColumns: TableColumn<K8sResourceCommon>[] = [
{
Expand Down Expand Up @@ -415,6 +462,11 @@ const ResourceList: React.FC<ResourceListProps> = ({
setCurrentPage(1);
};

const handleFilterChange = (value: string) => {
setCurrentPage(1);
setFilters(value);
};

const ResourceRow: React.FC<RowProps<K8sResourceCommon>> = ({ obj, activeColumnIDs }) => {
const { apiVersion, kind } = obj;
const [group, version] = apiVersion.includes('/') ? apiVersion.split('/') : ['', apiVersion];
Expand Down Expand Up @@ -442,10 +494,14 @@ const ResourceList: React.FC<ResourceListProps> = ({
case 'namespace':
return (
<TableData key={column.id} id={column.id} activeColumnIDs={activeColumnIDs}>
<ResourceLink
groupVersionKind={{ version: 'v1', kind: 'Namespace' }}
name={obj.metadata.namespace}
/>
{obj.metadata.namespace ? (
<ResourceLink
groupVersionKind={{ version: 'v1', kind: 'Namespace' }}
name={obj.metadata.namespace}
/>
) : (
'-'
)}
</TableData>
);
case 'Status':
Expand Down Expand Up @@ -490,7 +546,43 @@ const ResourceList: React.FC<ResourceListProps> = ({
)}
<div className="kuadrant-policy-list-body">
<ListPageBody>
<ListPageFilter data={data} loaded={allLoaded} onFilterChange={onFilterChange} />
<Toolbar>
<ToolbarContent>
<ToolbarGroup variant="filter-group">
<ToolbarItem>
<Select
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>
{filterSelected}
</MenuToggle>
)}
onSelect={onFilterSelect}
onOpenChange={setIsOpen}
isOpen={isOpen}
>
{['Name', 'Namespace', 'Type'].map((option, index) => (
<SelectOption key={index} value={option}>
{option}
</SelectOption>
))}
</Select>
</ToolbarItem>

<ToolbarItem>
<InputGroup className="pf-v5-c-input-group co-filter-group">
<TextInput
type="text"
placeholder={t('Search by {{filterValue}}...', {
filterValue: filterSelected.toLowerCase(),
})}
onChange={(_event, value) => handleFilterChange(value)}
className="pf-v5-c-form-control co-text-filter-with-icon "
/>
</InputGroup>
</ToolbarItem>
</ToolbarGroup>
</ToolbarContent>
</Toolbar>
{paginatedData.length === 0 && allLoaded ? (
<EmptyState>
<EmptyStateIcon icon={SearchIcon} />
Expand All @@ -504,15 +596,15 @@ const ResourceList: React.FC<ResourceListProps> = ({
) : (
<VirtualizedTable<K8sResourceCommon>
data={paginatedData}
unfilteredData={data}
unfilteredData={filteredData}
loaded={allLoaded}
loadError={combinedLoadError}
columns={usedColumns}
Row={ResourceRow}
/>
)}

{paginatedData.length > 0 && (
{filteredData.length > 0 && (
<div className="kuadrant-pagination-left">
<Pagination
itemCount={filteredData.length}
Expand Down
20 changes: 12 additions & 8 deletions src/components/kuadrant.css
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@
padding: 1rem;
}

.kuadrant-dashboard-learning, .kuadrant-dashboard-feature-highlights, .kuadrant-dashboard-enhance {
.kuadrant-dashboard-learning,
.kuadrant-dashboard-feature-highlights,
.kuadrant-dashboard-enhance {
margin-bottom: 0.5em;
}

Expand All @@ -79,7 +81,7 @@
color: var(--pf-global--palette--purple-700);
}

.pf-theme-dark .kuadrant-dashboard-learning {
.pf-theme-dark .kuadrant-dashboard-learning {
color: var(--pf-v5-global--palette--purple-200);
}

Expand Down Expand Up @@ -107,14 +109,15 @@
font-size: 0.8rem;
color: var(--pf-global--palette--black-600);
margin-left: 1rem;
margin-right: 1rem
margin-right: 1rem;
}

.kuadrant-limits-header {
margin: 1rem 0 0;
}

.kuadrant-limits-button, .pf-v5-c-label-group {
.kuadrant-limits-button,
.pf-v5-c-label-group {
margin: 1rem;
}

Expand Down Expand Up @@ -143,11 +146,12 @@

.kuadrant-overview-create-button {
position: absolute;
top: 0;
right: 0;
top: 0;
right: 0;
}

.kuadrant-overview-create-list, .kuadrant-overview-create-button {
.kuadrant-overview-create-list,
.kuadrant-overview-create-button {
font-family: RedHatText, helvetica, arial, sans-serif;
}
}

0 comments on commit 59839c4

Please sign in to comment.