Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,21 @@ import { ResourceFilters, ResourceMetadata, GetDataViewRows } from './types';
import { useConsoleDataViewData } from './useConsoleDataViewData';
import { useConsoleDataViewFilters } from './useConsoleDataViewFilters';

export type ConsoleDataViewProps<TData, TCustomRowData, TFilters> = {
export const initialFiltersDefault: ResourceFilters = { name: '', label: '' };

export type ConsoleDataViewProps<
TData,
TCustomRowData = any,
TFilters extends ResourceFilters = ResourceFilters
> = {
label?: string;
data: TData[];
loaded: boolean;
loadError?: any;
columns: TableColumn<TData>[];
columnLayout?: ColumnLayout;
columnManagementID?: string;
initialFilters: TFilters;
initialFilters?: TFilters;
additionalFilterNodes?: React.ReactNode[];
/**
* By default, `TData` is assumed to be assignable to `K8sResourceCommon` type.
Expand Down Expand Up @@ -86,7 +92,7 @@ export const ConsoleDataView = <
columns,
columnLayout,
columnManagementID,
initialFilters,
initialFilters = initialFiltersDefault as TFilters,
additionalFilterNodes,
getObjectMetadata,
matchesAdditionalFilters,
Expand Down Expand Up @@ -253,5 +259,3 @@ export const actionsCellProps = {
hasLeftBorder: true,
isActionCell: true,
};

export const initialFiltersDefault = { name: '', label: '' };
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type ConsoleDataViewRow = DataViewTd[];
/**
* Maps Console `RowProps` data to DataView compatible format.
*/
export type GetDataViewRows<TData, TCustomRowData> = (
export type GetDataViewRows<TData, TCustomRowData = any> = (
data: RowProps<TData, TCustomRowData>[],
columns: ConsoleDataViewColumn<TData>[],
) => ConsoleDataViewRow[];
13 changes: 8 additions & 5 deletions frontend/packages/console-app/src/components/nodes/NodesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,11 @@ const NodeList: React.FC<NodeListProps> = ({
[],
);

const initialFilters = React.useMemo<NodeFilters>(
() => ({ ...initialFiltersDefault, status: [], roles: [], architecture: [] }),
[],
);

// Create stable filter nodes with stable option references to prevent filter resets
const additionalFilterNodes = React.useMemo<React.ReactNode[]>(
() => [
Expand Down Expand Up @@ -622,9 +627,7 @@ const NodeList: React.FC<NodeListProps> = ({
columns={columns}
columnLayout={columnLayout}
columnManagementID={columnManagementID}
initialFilters={
{ ...initialFiltersDefault, status: [], roles: [], architecture: [] } as NodeFilters
}
initialFilters={initialFilters}
additionalFilterNodes={additionalFilterNodes}
matchesAdditionalFilters={matchesAdditionalFilters}
getDataViewRows={(rowData, tableColumns) =>
Expand All @@ -645,11 +648,11 @@ const NodeList: React.FC<NodeListProps> = ({

type NodeRowItem = NodeKind | NodeCertificateSigningRequestKind;

interface NodeFilters extends ResourceFilters {
type NodeFilters = ResourceFilters & {
status: string[];
roles: string[];
architecture: string[];
}
};

const useWatchCSRs = (): [CertificateSigningRequestKind[], boolean, unknown] => {
const [isAllowed, checkIsLoading] = useAccessReview({
Expand Down
4 changes: 1 addition & 3 deletions frontend/packages/console-app/src/components/pdb/PDBList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
actionsCellProps,
cellIsStickyProps,
getNameCellProps,
initialFiltersDefault,
ConsoleDataView,
} from '@console/app/src/components/data-view/ConsoleDataView';
import { GetDataViewRows } from '@console/app/src/components/data-view/types';
Expand All @@ -31,7 +30,7 @@ export const tableColumnInfo = [
{ id: '' },
];

const getDataViewRows: GetDataViewRows<PodDisruptionBudgetKind, undefined> = (data, columns) => {
const getDataViewRows: GetDataViewRows<PodDisruptionBudgetKind> = (data, columns) => {
return data.map(({ obj: pdb }) => {
const { name, namespace } = pdb.metadata;
const resourceKind = referenceForModel(PodDisruptionBudgetModel);
Expand Down Expand Up @@ -155,7 +154,6 @@ const PodDisruptionBudgetList: React.FCC<PodDisruptionBudgetsListProps> = ({
data={data}
loaded={loaded}
columns={columns}
initialFilters={initialFiltersDefault}
getDataViewRows={getDataViewRows}
hideColumnManagement
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import * as React from 'react';
import { css } from '@patternfly/react-styles';
import { sortable } from '@patternfly/react-table';
import { useTranslation } from 'react-i18next';
import {
actionsCellProps,
cellIsStickyProps,
getNameCellProps,
ConsoleDataView,
} from '@console/app/src/components/data-view/ConsoleDataView';
import { GetDataViewRows } from '@console/app/src/components/data-view/types';
import {
ListPageBody,
useListPageFilter,
ListPageCreate,
ListPageFilter,
ListPageHeader,
VirtualizedTable,
TableColumn,
RowProps,
} from '@console/dynamic-plugin-sdk/src/lib-core';
import { TableData } from '@console/internal/components/factory';
import { useActiveColumns } from '@console/internal/components/factory/Table/active-columns-hook';
import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook';
import { Kebab } from '@console/internal/components/utils/kebab';
import { ResourceLink } from '@console/internal/components/utils/resource-link';
import { VolumeSnapshotClassModel } from '@console/internal/models';
import {
Expand All @@ -25,95 +23,131 @@ import {
referenceFor,
} from '@console/internal/module/k8s';
import LazyActionMenu from '@console/shared/src/components/actions/LazyActionMenu';
import { LoadingBox } from '@console/shared/src/components/loading/LoadingBox';
import { DASH } from '@console/shared/src/constants/ui';
import { getAnnotations } from '@console/shared/src/selectors/common';

const tableColumnInfo = [
{ id: 'name' },
{ className: css('pf-m-hidden', 'pf-m-visible-on-md'), id: 'driver' },
{ className: css('pf-m-hidden', 'pf-m-visible-on-md'), id: 'deletionPolicy' },
{ className: Kebab.columnClass, id: '' },
];
const kind = referenceForModel(VolumeSnapshotClassModel);

const tableColumnInfo = [{ id: 'name' }, { id: 'driver' }, { id: 'deletionPolicy' }, { id: '' }];

const defaultSnapshotClassAnnotation = 'snapshot.storage.kubernetes.io/is-default-class';

const defaultSnapshotClassAnnotation: string = 'snapshot.storage.kubernetes.io/is-default-class';
export const isDefaultSnapshotClass = (volumeSnapshotClass: VolumeSnapshotClassKind) =>
getAnnotations(volumeSnapshotClass, { defaultSnapshotClassAnnotation: 'false' })[
defaultSnapshotClassAnnotation
] === 'true';

const Row: React.FC<RowProps<VolumeSnapshotClassKind>> = ({ obj }) => {
const { name } = obj?.metadata || {};
const { deletionPolicy, driver } = obj || {};
const resourceKind = referenceFor(obj);
const context = { [resourceKind]: obj };
return (
<>
<TableData {...tableColumnInfo[0]}>
<ResourceLink name={name} kind={referenceForModel(VolumeSnapshotClassModel)}>
{isDefaultSnapshotClass(obj) && (
<span className="pf-v6-u-font-size-xs pf-v6-u-text-color-subtle co-resource-item__help-text">
&ndash; Default
</span>
)}
</ResourceLink>
</TableData>
<TableData {...tableColumnInfo[1]}>{driver}</TableData>
<TableData {...tableColumnInfo[2]}>{deletionPolicy}</TableData>
<TableData {...tableColumnInfo[3]}>
<LazyActionMenu context={context} />
</TableData>
</>
);
const getDataViewRows: GetDataViewRows<VolumeSnapshotClassKind> = (data, columns) => {
return data.map(({ obj }) => {
const name = obj.metadata?.name || '';
const { deletionPolicy, driver } = obj;
const context = { [referenceFor(obj)]: obj };

const rowCells = {
[tableColumnInfo[0].id]: {
cell: (
<ResourceLink name={name} kind={kind}>
{isDefaultSnapshotClass(obj) && (
<span className="pf-v6-u-font-size-xs pf-v6-u-text-color-subtle co-resource-item__help-text">
&ndash; Default
</span>
)}
</ResourceLink>
),
props: getNameCellProps(name),
},
[tableColumnInfo[1].id]: {
cell: driver,
},
[tableColumnInfo[2].id]: {
cell: deletionPolicy,
},
[tableColumnInfo[3].id]: {
cell: <LazyActionMenu context={context} />,
props: {
...actionsCellProps,
},
},
};

return columns.map(({ id }) => {
const cell = rowCells[id]?.cell || DASH;
const props = rowCells[id]?.props || undefined;
return {
id,
props,
cell,
};
});
});
};

const VolumeSnapshotClassTable: React.FC<VolumeSnapshotClassTableProps> = (props) => {
const useVolumeSnapshotClassColumns = (): TableColumn<VolumeSnapshotClassKind>[] => {
const { t } = useTranslation();
const getTableColumns = (): TableColumn<VolumeSnapshotClassKind>[] => [
{
title: t('console-app~Name'),
sort: 'metadata.name',
transforms: [sortable],
id: tableColumnInfo[0].id,
},
{
title: t('console-app~Driver'),
sort: 'driver',
transforms: [sortable],
props: { className: tableColumnInfo[1].className },
id: tableColumnInfo[1].id,
},
{
title: t('console-app~Deletion policy'),
sort: 'deletionPolicy',
transforms: [sortable],
props: { className: tableColumnInfo[2].className },
id: tableColumnInfo[2].id,
},
{
title: '',
props: { className: tableColumnInfo[3].className },
id: tableColumnInfo[3].id,
},
];
const [columns] = useActiveColumns({ columns: getTableColumns() });

const columns: TableColumn<VolumeSnapshotClassKind>[] = React.useMemo(
() => [
{
title: t('console-app~Name'),
sort: 'metadata.name',
id: tableColumnInfo[0].id,
props: { ...cellIsStickyProps, modifier: 'nowrap' },
},
{
title: t('console-app~Driver'),
sort: 'driver',
id: tableColumnInfo[1].id,
props: { modifier: 'nowrap' },
},
{
title: t('console-app~Deletion policy'),
sort: 'deletionPolicy',
id: tableColumnInfo[2].id,
props: { modifier: 'nowrap' },
},
{
title: '',
id: tableColumnInfo[3].id,
props: { ...cellIsStickyProps },
},
],
[t],
);

return columns;
};

const VolumeSnapshotClassTable: React.FCC<VolumeSnapshotClassTableProps> = ({
data,
loaded,
...props
}) => {
const columns = useVolumeSnapshotClassColumns();

return (
<VirtualizedTable<VolumeSnapshotClassKind>
{...props}
aria-label={t('console-app~VolumeSnapshotClasses')}
label={t('console-app~VolumeSnapshotClasses')}
columns={columns}
Row={Row}
/>
<React.Suspense fallback={<LoadingBox />}>
<ConsoleDataView<VolumeSnapshotClassKind>
{...props}
label={VolumeSnapshotClassModel.labelPlural}
data={data}
loaded={loaded}
columns={columns}
getDataViewRows={getDataViewRows}
hideColumnManagement
/>
</React.Suspense>
);
};

const VolumeSnapshotClassPage: React.FC<VolumeSnapshotClassPageProps> = ({
const VolumeSnapshotClassPage: React.FCC<VolumeSnapshotClassPageProps> = ({
canCreate = true,
showTitle = true,
namespace,
selector,
}) => {
const { t } = useTranslation();

const [resources, loaded, loadError] = useK8sWatchResource<VolumeSnapshotClassKind[]>({
groupVersionKind: {
group: VolumeSnapshotClassModel.apiGroup,
Expand All @@ -125,26 +159,18 @@ const VolumeSnapshotClassPage: React.FC<VolumeSnapshotClassPageProps> = ({
namespace,
selector,
});
const [data, filteredData, onFilterChange] = useListPageFilter(resources);
const resourceKind = referenceForModel(VolumeSnapshotClassModel);

return (
<>
<ListPageHeader title={showTitle ? t(VolumeSnapshotClassModel.labelPluralKey || '') : ''}>
{canCreate && (
<ListPageCreate groupVersionKind={resourceKind}>
<ListPageCreate groupVersionKind={kind}>
{t('console-app~Create VolumeSnapshotClass')}
</ListPageCreate>
)}
</ListPageHeader>
<ListPageBody>
<ListPageFilter data={data} loaded={loaded} onFilterChange={onFilterChange} />
<VolumeSnapshotClassTable
unfilteredData={resources}
data={filteredData}
loaded={loaded}
loadError={loadError}
/>
<VolumeSnapshotClassTable data={resources} loaded={loaded} loadError={loadError} />
</ListPageBody>
</>
);
Expand All @@ -159,8 +185,8 @@ type VolumeSnapshotClassPageProps = {

type VolumeSnapshotClassTableProps = {
data: VolumeSnapshotClassKind[];
unfilteredData: VolumeSnapshotClassKind[];
loaded: boolean;
loadError: unknown;
};

export default VolumeSnapshotClassPage;
Loading