Skip to content

Commit 6d86d5c

Browse files
committed
add mamanged columns for AppSets && add Additional columns for Apps&AppSets
Signed-off-by: Atif Ali <atali@redhat.com>
1 parent d217e1d commit 6d86d5c

5 files changed

Lines changed: 221 additions & 120 deletions

File tree

‎src/gitops/components/shared/ApplicationSetList.tsx‎

Lines changed: 108 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ import {
1414
} from '@openshift-console/dynamic-plugin-sdk';
1515
import { ErrorState } from '@patternfly/react-component-groups';
1616
import { EmptyState, EmptyStateBody } from '@patternfly/react-core';
17-
import { DataViewTh, DataViewTr } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
1817
import { DataViewState } from '@patternfly/react-data-view/dist/esm/DataView';
18+
import type { DataViewTd } from '@patternfly/react-data-view/dist/esm/DataViewTable';
19+
import { DataViewTh, DataViewTr } from '@patternfly/react-data-view/dist/esm/DataViewTable';
1920
import { CubesIcon } from '@patternfly/react-icons';
2021
import { Tbody, Td, ThProps, Tr } from '@patternfly/react-table';
2122

@@ -31,11 +32,21 @@ import {
3132
ShowOperandsInAllNamespacesRadioGroup,
3233
useShowOperandsInAllNamespaces,
3334
} from './AllNamespaces';
35+
import {
36+
APPLICATION_SET_LIST_COLUMN_MANAGEMENT_ID,
37+
getApplicationSetManagedColumns,
38+
} from './applicationSetListColumns';
39+
import {
40+
type GitOpsManagedColumn,
41+
NAMESPACE_COLUMN_ID,
42+
useGitOpsColumnManagement,
43+
} from './ColumnManagement';
3444
import {
3545
GitOpsDataViewTable,
3646
useGitOpsDataViewSort,
3747
useGitOpsListPagePagination,
3848
} from './DataView';
49+
import { GitOpsListPageToolbar } from './GitOpsListPageToolbar';
3950
import {
4051
filterByConsoleNameAndLabels,
4152
filterResourcesByLabelQuery,
@@ -122,20 +133,21 @@ const ApplicationSetList: React.FC<ApplicationSetProps> = ({
122133
});
123134

124135
const { t } = useTranslation('plugin__gitops-plugin');
136+
const includeNamespaceColumn = !namespace;
137+
const managedColumns = React.useMemo(() => getApplicationSetManagedColumns(true, t), [t]);
138+
139+
const { activeColumnIds, columnManagement, filterDataView } = useGitOpsColumnManagement({
140+
columnManagementID: APPLICATION_SET_LIST_COLUMN_MANAGEMENT_ID,
141+
columns: managedColumns,
142+
resourceType: t('ApplicationSet'),
143+
includeNamespaceColumn,
144+
showNamespaceHelp: includeNamespaceColumn,
145+
});
125146

126147
const columnSortConfig = React.useMemo(
127148
() =>
128-
[
129-
'name',
130-
...(!listAllNamespaces || !namespace ? ['namespace'] : []),
131-
'status',
132-
'generated-apps',
133-
'generators',
134-
'labels',
135-
'created-at',
136-
'actions',
137-
].map((key) => ({ key })),
138-
[listAllNamespaces, namespace],
149+
managedColumns.filter((column) => !column.alwaysShown).map((column) => ({ key: column.id })),
150+
[managedColumns],
139151
);
140152

141153
const { searchParams, sortBy, direction, getSortParams } =
@@ -146,7 +158,7 @@ const ApplicationSetList: React.FC<ApplicationSetProps> = ({
146158
const nameQuery = searchParams.get('name') || '';
147159
const labelsParam = searchParams.get('labels') || '';
148160

149-
const columnsDV = useColumnsDV(namespace, getSortParams);
161+
const columnsDV = useColumnsDV(managedColumns, getSortParams, columnSortConfig);
150162
const sortedApplicationSets = React.useMemo(() => {
151163
return sortData(
152164
applicationSets as ApplicationSetKind[],
@@ -175,7 +187,15 @@ const ApplicationSetList: React.FC<ApplicationSetProps> = ({
175187
namespace,
176188
searchParams,
177189
});
178-
const rows = useApplicationSetRowsDV(pagedItems, namespace, applications, appsLoaded);
190+
const rows = useApplicationSetRowsDV(pagedItems, managedColumns, applications, appsLoaded);
191+
const columnIds = React.useMemo(
192+
() => managedColumns.map((column) => column.id),
193+
[managedColumns],
194+
);
195+
const { columns: visibleColumnsDV, rows: visibleRows } = React.useMemo(
196+
() => filterDataView(columnsDV, rows, columnIds, activeColumnIds),
197+
[filterDataView, columnsDV, rows, columnIds, activeColumnIds],
198+
);
179199

180200
// Check if there are ApplicationSets initially (before search)
181201
const hasApplicationSets = React.useMemo(() => {
@@ -200,7 +220,7 @@ const ApplicationSetList: React.FC<ApplicationSetProps> = ({
200220
const empty = (
201221
<Tbody>
202222
<Tr key="loading" ouiaId="table-tr-loading">
203-
<Td colSpan={columnsDV.length}>
223+
<Td colSpan={visibleColumnsDV.length || columnsDV.length}>
204224
<EmptyState
205225
headingLevel="h4"
206226
icon={CubesIcon}
@@ -220,7 +240,7 @@ const ApplicationSetList: React.FC<ApplicationSetProps> = ({
220240
const error = loadError && (
221241
<Tbody>
222242
<Tr key="loading" ouiaId={'table-tr-loading'}>
223-
<Td colSpan={columnsDV.length}>
243+
<Td colSpan={visibleColumnsDV.length || columnsDV.length}>
224244
<ErrorState
225245
titleText={t('Unable to load data')}
226246
bodyText={t(
@@ -237,6 +257,15 @@ const ApplicationSetList: React.FC<ApplicationSetProps> = ({
237257
sortedApplicationSets.length === 0 ||
238258
filteredBySearch.length === 0;
239259

260+
const listPageFilter = !hideNameLabelFilters && hasApplicationSets && (
261+
<ListPageFilter
262+
data={data}
263+
loaded={loaded}
264+
rowFilters={filters}
265+
onFilterChange={onFilterChange}
266+
/>
267+
);
268+
240269
return (
241270
<div>
242271
{showTitle == undefined && (
@@ -255,17 +284,12 @@ const ApplicationSetList: React.FC<ApplicationSetProps> = ({
255284
</ListPageHeader>
256285
)}
257286
<ListPageBody>
258-
{!hideNameLabelFilters && hasApplicationSets && (
259-
<ListPageFilter
260-
data={data}
261-
loaded={loaded}
262-
rowFilters={filters}
263-
onFilterChange={onFilterChange}
264-
/>
287+
{hasApplicationSets && (
288+
<GitOpsListPageToolbar filters={listPageFilter} columnManagement={columnManagement} />
265289
)}
266290
<GitOpsDataViewTable
267-
rows={rows}
268-
columns={columnsDV}
291+
rows={visibleRows}
292+
columns={visibleColumnsDV}
269293
isEmpty={isEmptyState}
270294
emptyState={empty}
271295
isLoading={!loaded}
@@ -300,15 +324,15 @@ const ApplicationSetActionsCell: React.FC<{ appSet: ApplicationSetKind; index: n
300324
};
301325

302326
const useApplicationSetRowsDV = (
303-
applicationSetsList,
304-
namespace,
305-
applications,
306-
appsLoaded,
327+
applicationSetsList: ApplicationSetKind[],
328+
managedColumns: GitOpsManagedColumn[],
329+
applications: K8sResourceCommon[],
330+
appsLoaded: boolean,
307331
): DataViewTr[] => {
308332
const rows: DataViewTr[] = [];
309333
applicationSetsList.forEach((appSet: ApplicationSetKind, index: number) => {
310-
rows.push([
311-
{
334+
const cellsById: Record<string, DataViewTd> = {
335+
name: {
312336
cell: (
313337
<div>
314338
<ResourceLink
@@ -322,28 +346,24 @@ const useApplicationSetRowsDV = (
322346
id: appSet.metadata?.name,
323347
dataLabel: 'Name',
324348
},
325-
...(!namespace
326-
? [
327-
{
328-
cell: <ResourceLink kind="Namespace" name={appSet.metadata.namespace} />,
329-
id: appSet.metadata.namespace,
330-
dataLabel: 'Namespace',
331-
},
332-
]
333-
: []),
334-
{
349+
[NAMESPACE_COLUMN_ID]: {
350+
cell: <ResourceLink kind="Namespace" name={appSet.metadata.namespace} />,
351+
id: appSet.metadata.namespace,
352+
dataLabel: 'Namespace',
353+
},
354+
status: {
335355
id: getAppSetStatus(appSet),
336356
cell: <ApplicationSetStatusFragment status={getAppSetStatus(appSet)} />,
337357
},
338-
{
358+
'generated-apps': {
339359
id: 'generated-apps-' + index,
340360
cell: <div>{getGeneratedAppsCount(appSet, applications, appsLoaded).toString()}</div>,
341361
},
342-
{
362+
generators: {
343363
id: 'generators-' + index,
344364
cell: <div>{getAppSetGeneratorCount(appSet).toString()}</div>,
345365
},
346-
{
366+
labels: {
347367
id: 'labels',
348368
dataLabel: 'Labels',
349369
cell: (
@@ -362,93 +382,67 @@ const useApplicationSetRowsDV = (
362382
</div>
363383
),
364384
},
365-
{
385+
'created-at': {
366386
id: 'created-at-' + index,
367387
cell: <div>{formatCreationTimestamp(appSet.metadata.creationTimestamp)}</div>,
368388
},
369-
{
389+
actions: {
370390
id: 'actions-' + index,
371391
cell: <ApplicationSetActionsCell appSet={appSet} index={index} />,
372392
props: { style: { paddingTop: 8, paddingRight: 0, paddingLeft: 0, width: 10 } },
373393
},
374-
]);
394+
};
395+
396+
rows.push(managedColumns.map((column) => cellsById[column.id]));
375397
});
376398
return rows;
377399
};
378400

379401
const useColumnsDV = (
380-
namespace: string,
402+
managedColumns: GitOpsManagedColumn[],
381403
getSortParams: (columnIndex: number) => ThProps['sort'],
404+
columnSortConfig: { key: string }[],
382405
): DataViewTh[] => {
383-
const i: number = namespace ? 0 : 1;
384406
const { t } = useTranslation('plugin__gitops-plugin');
385-
const columns: DataViewTh[] = [
386-
{
387-
cell: t('Name'),
388-
props: {
389-
'aria-label': 'name',
390-
className: 'pf-m-width-25',
391-
sort: getSortParams(0),
392-
},
393-
},
394-
...(!namespace
395-
? [
396-
{
397-
cell: t('Namespace'),
398-
props: {
399-
'aria-label': 'namespace',
400-
className: 'pf-m-width-15',
401-
sort: getSortParams(1),
402-
},
403-
},
404-
]
405-
: []),
406-
{
407-
cell: t('Health Status'),
408-
props: {
409-
'aria-label': 'health status',
410-
className: 'pf-m-width-15',
411-
sort: getSortParams(1 + i),
412-
},
413-
},
414-
{
415-
cell: t('Generated Apps'),
416-
props: {
417-
'aria-label': 'generated apps',
418-
className: 'pf-m-width-15',
419-
sort: getSortParams(2 + i),
420-
},
421-
},
422-
{
423-
cell: t('Generators'),
424-
props: {
425-
'aria-label': 'generators',
426-
className: 'pf-m-width-15',
427-
sort: getSortParams(3 + i),
428-
},
429-
},
430-
{
431-
cell: t('Labels'),
432-
props: {
433-
'aria-label': 'labels',
434-
className: 'pf-m-width-20',
435-
sort: getSortParams(4 + i),
436-
},
437-
},
438-
{
439-
cell: t('Created At'),
407+
408+
const titleById: Record<string, string> = {
409+
name: t('Name'),
410+
[NAMESPACE_COLUMN_ID]: t('Namespace'),
411+
status: t('Health Status'),
412+
'generated-apps': t('Generated Apps'),
413+
generators: t('Generators'),
414+
labels: t('Labels'),
415+
'created-at': t('Created At'),
416+
actions: '',
417+
};
418+
419+
const widthById: Record<string, string> = {
420+
name: 'pf-m-width-25',
421+
[NAMESPACE_COLUMN_ID]: 'pf-m-width-15',
422+
status: 'pf-m-width-15',
423+
'generated-apps': 'pf-m-width-15',
424+
generators: 'pf-m-width-15',
425+
labels: 'pf-m-width-20',
426+
'created-at': 'pf-m-width-15',
427+
};
428+
429+
return managedColumns.map((column) => {
430+
if (column.id === 'actions') {
431+
return {
432+
cell: '',
433+
props: { 'aria-label': 'actions' },
434+
};
435+
}
436+
const sortIndex = columnSortConfig.findIndex((entry) => entry.key === column.id);
437+
return {
438+
cell: titleById[column.id] ?? column.title,
440439
props: {
441-
'aria-label': 'created at',
442-
className: 'pf-m-width-15',
443-
sort: getSortParams(5 + i),
440+
'aria-label': column.id,
441+
className: widthById[column.id],
442+
...(sortIndex >= 0 ? { sort: getSortParams(sortIndex) } : {}),
444443
},
445-
},
446-
{
447-
cell: '',
448-
props: { 'aria-label': 'actions' },
449-
},
450-
];
451-
return columns;
444+
};
445+
});
452446
};
453447

454448
const getFilters = (t: (key: string) => string): RowFilter[] => [

‎src/gitops/components/shared/applicationListColumns.test.ts‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,18 @@ describe('getApplicationManagedColumns', () => {
2020
expect(byId.name.isUntoggleable).toBe(true);
2121
expect(byId.labels.isShownByDefault).toBe(true);
2222
expect(byId.actions.alwaysShown).toBe(true);
23-
expect(columns.some((column) => column.additional)).toBe(false);
23+
});
24+
25+
it('puts Revision and App Project under Additional columns', () => {
26+
const columns = getApplicationManagedColumns(true, t);
27+
const byId = Object.fromEntries(columns.map((column) => [column.id, column]));
28+
29+
expect(byId.revision).toMatchObject({ isShownByDefault: false, additional: true });
30+
expect(byId.project).toMatchObject({ isShownByDefault: false, additional: true });
31+
expect(columns.filter((column) => column.additional).map((column) => column.id)).toEqual([
32+
'revision',
33+
'project',
34+
]);
2435
});
2536

2637
it('includes Namespace only for All projects', () => {
@@ -45,16 +56,14 @@ describe('getApplicationManagedColumns', () => {
4556
]);
4657
});
4758

48-
it('defaults to every non-additional column visible', () => {
59+
it('defaults to Default columns only (excludes Additional)', () => {
4960
const columns = getApplicationManagedColumns(true, t);
5061
expect(getDefaultActiveColumnIds(columns)).toEqual([
5162
'name',
5263
'namespace',
5364
'sync-status',
5465
'health-status',
55-
'revision',
5666
'labels',
57-
'project',
5867
'actions',
5968
]);
6069
});

‎src/gitops/components/shared/applicationListColumns.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ export const getApplicationManagedColumns = (
1919
columns.push(
2020
{ id: 'sync-status', title: t('Sync Status'), isShownByDefault: true },
2121
{ id: 'health-status', title: t('Health Status'), isShownByDefault: true },
22-
{ id: 'revision', title: t('Revision'), isShownByDefault: true },
22+
{ id: 'revision', title: t('Revision'), isShownByDefault: false, additional: true },
2323
{ id: 'labels', title: t('Labels'), isShownByDefault: true },
24-
{ id: 'project', title: t('App Project'), isShownByDefault: true },
24+
{ id: 'project', title: t('App Project'), isShownByDefault: false, additional: true },
2525
{ id: 'actions', title: '', isShownByDefault: true, alwaysShown: true },
2626
);
2727
return columns;

0 commit comments

Comments
 (0)