Skip to content

Commit 8d018bb

Browse files
authored
feat(ui): add sortable columns to application list (#24213) (#24535)
Signed-off-by: downfa11 <[email protected]>
1 parent 41f6644 commit 8d018bb

File tree

2 files changed

+81
-17
lines changed

2 files changed

+81
-17
lines changed

ui/src/app/applications/components/application-details/application-resource-list.tsx

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import * as classNames from 'classnames';
44
import * as models from '../../../shared/models';
55
import {ResourceIcon} from '../resource-icon';
66
import {ResourceLabel} from '../resource-label';
7-
import {ComparisonStatusIcon, HealthStatusIcon, nodeKey, createdOrNodeKey, isSameNode} from '../utils';
7+
import {ComparisonStatusIcon, HealthStatusIcon, nodeKey, isSameNode, createdOrNodeKey} from '../utils';
88
import {AppDetailsPreferences} from '../../../shared/services';
99
import {Consumer} from '../../../shared/context';
1010
import Moment from 'react-moment';
1111
import {format} from 'date-fns';
12-
import {ResourceNode} from '../../../shared/models';
12+
import {HealthPriority, ResourceNode, SyncPriority, SyncStatusCode} from '../../../shared/models';
1313
import './application-resource-list.scss';
1414

1515
export interface ApplicationResourceListProps {
@@ -54,17 +54,56 @@ export const ApplicationResourceList = (props: ApplicationResourceListProps) =>
5454

5555
const sortedResources = React.useMemo(() => {
5656
const resourcesToSort = [...props.resources];
57+
resourcesToSort.sort((a, b) => {
58+
let compare = 0;
59+
switch (sortConfig.key) {
60+
case 'name':
61+
compare = a.name.localeCompare(b.name);
62+
break;
5763

58-
if (sortConfig.key === 'syncOrder') {
59-
resourcesToSort.sort((a, b) => {
60-
const waveA = a.syncWave ?? 0;
61-
const waveB = b.syncWave ?? 0;
62-
const compare = waveA - waveB;
63-
return sortConfig.direction === 'asc' ? compare : -compare;
64-
});
65-
} else {
66-
resourcesToSort.sort((first, second) => -createdOrNodeKey(first).localeCompare(createdOrNodeKey(second), undefined, {numeric: true}));
67-
}
64+
case 'group-kind':
65+
{
66+
const groupKindA = [a.group, a.kind].filter(item => !!item).join('/');
67+
const groupKindB = [b.group, b.kind].filter(item => !!item).join('/');
68+
compare = groupKindA.localeCompare(groupKindB);
69+
}
70+
break;
71+
72+
case 'syncOrder':
73+
{
74+
const waveA = a.syncWave ?? 0;
75+
const waveB = b.syncWave ?? 0;
76+
compare = waveA - waveB;
77+
}
78+
break;
79+
case 'namespace':
80+
{
81+
const namespaceA = a.namespace ?? '';
82+
const namespaceB = b.namespace ?? '';
83+
compare = namespaceA.localeCompare(namespaceB);
84+
}
85+
break;
86+
case 'createdAt':
87+
{
88+
compare = createdOrNodeKey(a).localeCompare(createdOrNodeKey(b), undefined, {numeric: true});
89+
}
90+
break;
91+
case 'status':
92+
{
93+
const healthA = a.health?.status ?? 'Unknown';
94+
const healthB = b.health?.status ?? 'Unknown';
95+
const syncA = (a.status as SyncStatusCode) ?? 'Unknown';
96+
const syncB = (b.status as SyncStatusCode) ?? 'Unknown';
97+
98+
compare = HealthPriority[healthA] - HealthPriority[healthB];
99+
if (compare === 0) {
100+
compare = SyncPriority[syncA] - SyncPriority[syncB];
101+
}
102+
}
103+
break;
104+
}
105+
return sortConfig.direction === 'asc' ? compare : -compare;
106+
});
68107
return resourcesToSort;
69108
}, [props.resources, sortConfig]);
70109

@@ -103,15 +142,25 @@ export const ApplicationResourceList = (props: ApplicationResourceListProps) =>
103142
<div className='argo-table-list__head'>
104143
<div className='row'>
105144
<div className='columns small-1 xxxlarge-1' />
106-
<div className='columns small-2 xxxlarge-2'>NAME</div>
107-
<div className='columns small-1 xxxlarge-1'>GROUP/KIND</div>
145+
<div className='columns small-2 xxxlarge-2' onClick={() => handleSort('name')} style={{cursor: 'pointer'}}>
146+
NAME {getSortArrow('name')}
147+
</div>
148+
<div className='columns small-1 xxxlarge-1' onClick={() => handleSort('group-kind')} style={{cursor: 'pointer'}}>
149+
GROUP/KIND {getSortArrow('group-kind')}
150+
</div>
108151
<div className='columns small-1 xxxlarge-1' onClick={() => handleSort('syncOrder')} style={{cursor: 'pointer'}}>
109152
SYNC ORDER {getSortArrow('syncOrder')}
110153
</div>
111-
<div className='columns small-2 xxxlarge-1'>NAMESPACE</div>
154+
<div className='columns small-2 xxxlarge-1' onClick={() => handleSort('namespace')} style={{cursor: 'pointer'}}>
155+
NAMESPACE {getSortArrow('namespace')}
156+
</div>
112157
{isSameKind && props.resources[0].kind === 'ReplicaSet' && <div className='columns small-1 xxxlarge-1'>REVISION</div>}
113-
<div className='columns small-2 xxxlarge-2'>CREATED AT</div>
114-
<div className='columns small-2 xxxlarge-1'>STATUS</div>
158+
<div className='columns small-2 xxxlarge-2' onClick={() => handleSort('createdAt')} style={{cursor: 'pointer'}}>
159+
CREATED AT {getSortArrow('createdAt')}
160+
</div>
161+
<div className='columns small-2 xxxlarge-1' onClick={() => handleSort('status')} style={{cursor: 'pointer'}}>
162+
STATUS {getSortArrow('status')}
163+
</div>
115164
</div>
116165
</div>
117166
{sortedResources.map(res => {

ui/src/app/shared/models.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,12 @@ export const SyncStatuses: {[key: string]: SyncStatusCode} = {
361361
OutOfSync: 'OutOfSync'
362362
};
363363

364+
export const SyncPriority: Record<SyncStatusCode, number> = {
365+
Unknown: 0,
366+
OutOfSync: 1,
367+
Synced: 2
368+
};
369+
364370
export type HealthStatusCode = 'Unknown' | 'Progressing' | 'Healthy' | 'Suspended' | 'Degraded' | 'Missing';
365371

366372
export const HealthStatuses: {[key: string]: HealthStatusCode} = {
@@ -372,6 +378,15 @@ export const HealthStatuses: {[key: string]: HealthStatusCode} = {
372378
Unknown: 'Unknown'
373379
};
374380

381+
export const HealthPriority: Record<HealthStatusCode, number> = {
382+
Missing: 0,
383+
Degraded: 1,
384+
Unknown: 2,
385+
Progressing: 3,
386+
Suspended: 4,
387+
Healthy: 5
388+
};
389+
375390
export interface HealthStatus {
376391
status: HealthStatusCode;
377392
message: string;

0 commit comments

Comments
 (0)