Skip to content

Commit 034a89a

Browse files
feat(Storage): sort on backend (#510)
1 parent 6700136 commit 034a89a

File tree

10 files changed

+254
-134
lines changed

10 files changed

+254
-134
lines changed

src/containers/Storage/Storage.tsx

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ import {useCallback, useEffect} from 'react';
22
import {useDispatch} from 'react-redux';
33
import cn from 'bem-cn-lite';
44

5-
import DataTable, {Settings} from '@gravity-ui/react-data-table';
6-
75
import {Search} from '../../components/Search';
86
import {UptimeFilter} from '../../components/UptimeFIlter';
97
import {AccessDenied} from '../../components/Errors/403';
108
import {EntitiesCount} from '../../components/EntitiesCount';
119
import {TableWithControlsLayout} from '../../components/TableWithControlsLayout/TableWithControlsLayout';
1210
import {ResponseError} from '../../components/Errors/ResponseError';
1311

14-
import type {StorageType, VisibleEntities} from '../../store/reducers/storage/types';
12+
import type {
13+
StorageSortParams,
14+
StorageType,
15+
VisibleEntities,
16+
} from '../../store/reducers/storage/types';
17+
import type {NodesSortParams} from '../../store/reducers/nodes/types';
1518
import {
1619
setInitialState,
1720
setVisibleEntities,
@@ -22,19 +25,24 @@ import {
2225
setDataWasNotLoaded,
2326
getStorageNodesInfo,
2427
getStorageGroupsInfo,
28+
setNodesSortParams,
29+
setGroupsSortParams,
2530
} from '../../store/reducers/storage/storage';
2631
import {
2732
selectFilteredGroups,
2833
selectFilteredNodes,
2934
selectEntitiesCount,
3035
selectUsageFilterOptions,
36+
selectNodesSortParams,
37+
selectGroupsSortParams,
3138
} from '../../store/reducers/storage/selectors';
3239
import {VISIBLE_ENTITIES, STORAGE_TYPES} from '../../store/reducers/storage/constants';
3340
import {getNodesList, selectNodesMap} from '../../store/reducers/nodesList';
3441
import {
3542
useAutofetcher,
3643
useNodesRequestParams,
3744
useStorageRequestParams,
45+
useTableSort,
3846
useTypedSelector,
3947
} from '../../utils/hooks';
4048
import {AdditionalNodesInfo, NodesUptimeFilterValues} from '../../utils/nodes';
@@ -50,11 +58,6 @@ import './Storage.scss';
5058

5159
const b = cn('global-storage');
5260

53-
const tableSettings: Settings = {
54-
...DEFAULT_TABLE_SETTINGS,
55-
defaultOrder: DataTable.DESCENDING,
56-
};
57-
5861
interface StorageProps {
5962
additionalNodesInfo?: AdditionalNodesInfo;
6063
tenant?: string;
@@ -80,6 +83,8 @@ export const Storage = ({additionalNodesInfo, tenant, nodeId}: StorageProps) =>
8083
const entitiesCount = useTypedSelector(selectEntitiesCount);
8184
const nodesMap = useTypedSelector(selectNodesMap);
8285
const usageFilterOptions = useTypedSelector(selectUsageFilterOptions);
86+
const nodesSortParams = useTypedSelector(selectNodesSortParams);
87+
const groupsSortParams = useTypedSelector(selectGroupsSortParams);
8388

8489
useEffect(() => {
8590
dispatch(getNodesList());
@@ -90,8 +95,22 @@ export const Storage = ({additionalNodesInfo, tenant, nodeId}: StorageProps) =>
9095
};
9196
}, [dispatch]);
9297

93-
const nodesRequestParams = useNodesRequestParams({filter, nodesUptimeFilter});
94-
const storageRequestParams = useStorageRequestParams({filter});
98+
const nodesRequestParams = useNodesRequestParams({
99+
filter,
100+
nodesUptimeFilter,
101+
...nodesSortParams,
102+
});
103+
const storageRequestParams = useStorageRequestParams({
104+
filter,
105+
...groupsSortParams,
106+
});
107+
108+
const [nodesSort, handleNodesSort] = useTableSort(nodesSortParams, (params) =>
109+
dispatch(setNodesSortParams(params as NodesSortParams)),
110+
);
111+
const [groupsSort, handleGroupsSort] = useTableSort(groupsSortParams, (params) =>
112+
dispatch(setGroupsSortParams(params as StorageSortParams)),
113+
);
95114

96115
const fetchData = useCallback(
97116
(isBackground: boolean) => {
@@ -155,19 +174,23 @@ export const Storage = ({additionalNodesInfo, tenant, nodeId}: StorageProps) =>
155174
<StorageGroups
156175
visibleEntities={visibleEntities}
157176
data={storageGroups}
158-
tableSettings={tableSettings}
177+
tableSettings={DEFAULT_TABLE_SETTINGS}
159178
nodes={nodesMap}
160179
onShowAll={() => handleGroupVisibilityChange(VISIBLE_ENTITIES.all)}
180+
sort={groupsSort}
181+
handleSort={handleGroupsSort}
161182
/>
162183
)}
163184
{storageType === STORAGE_TYPES.nodes && (
164185
<StorageNodes
165186
visibleEntities={visibleEntities}
166187
nodesUptimeFilter={nodesUptimeFilter}
167188
data={storageNodes}
168-
tableSettings={tableSettings}
189+
tableSettings={DEFAULT_TABLE_SETTINGS}
169190
onShowAll={handleShowAllNodes}
170191
additionalNodesInfo={additionalNodesInfo}
192+
sort={nodesSort}
193+
handleSort={handleNodesSort}
171194
/>
172195
)}
173196
</>

src/containers/Storage/StorageGroups/StorageGroups.tsx

Lines changed: 50 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import cn from 'bem-cn-lite';
33
import DataTable, {Column, Settings, SortOrder} from '@gravity-ui/react-data-table';
44
import {Icon, Label, Popover, PopoverBehavior} from '@gravity-ui/uikit';
55

6+
import type {ValueOf} from '../../../types/common';
67
import type {NodesMap} from '../../../types/store/nodesList';
78
import type {PreparedStorageGroup, VisibleEntities} from '../../../store/reducers/storage/types';
9+
import type {HandleSort} from '../../../utils/hooks/useTableSort';
810

911
import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
1012
import {bytesToGB, bytesToSpeed} from '../../../utils/utils';
1113
import {stringifyVdiskId} from '../../../utils';
12-
import {getUsage, isFullVDiskData} from '../../../utils/storage';
14+
import {getUsage, isFullVDiskData, isSortableStorageProperty} from '../../../utils/storage';
1315

1416
import shieldIcon from '../../../assets/icons/shield.svg';
1517
import {Stack} from '../../../components/Stack/Stack';
@@ -22,83 +24,60 @@ import {getDegradedSeverity, getUsageSeverityForStorageGroup} from '../utils';
2224
import i18n from './i18n';
2325
import './StorageGroups.scss';
2426

25-
enum TableColumnsIds {
26-
PoolName = 'PoolName',
27-
Type = 'Type',
28-
ErasureSpecies = 'ErasureSpecies',
29-
GroupID = 'GroupID',
30-
Used = 'Used',
31-
Limit = 'Limit',
32-
UsedPercents = 'UsedPercents',
33-
UsedSpaceFlag = 'UsedSpaceFlag',
34-
Read = 'Read',
35-
Write = 'Write',
36-
VDisks = 'VDisks',
37-
Missing = 'Missing',
38-
}
27+
const TableColumnsIds = {
28+
PoolName: 'PoolName',
29+
Kind: 'Kind',
30+
Erasure: 'Erasure',
31+
GroupId: 'GroupId',
32+
Used: 'Used',
33+
Limit: 'Limit',
34+
Usage: 'Usage',
35+
UsedSpaceFlag: 'UsedSpaceFlag',
36+
Read: 'Read',
37+
Write: 'Write',
38+
VDisks: 'VDisks',
39+
Degraded: 'Degraded',
40+
} as const;
3941

40-
type TableColumnsIdsKeys = keyof typeof TableColumnsIds;
41-
type TableColumnsIdsValues = typeof TableColumnsIds[TableColumnsIdsKeys];
42+
type TableColumnId = ValueOf<typeof TableColumnsIds>;
4243

4344
interface StorageGroupsProps {
4445
data: PreparedStorageGroup[];
4546
nodes?: NodesMap;
4647
tableSettings: Settings;
4748
visibleEntities: VisibleEntities;
4849
onShowAll?: VoidFunction;
50+
sort?: SortOrder;
51+
handleSort?: HandleSort;
4952
}
5053

51-
const tableColumnsNames: Record<TableColumnsIdsValues, string> = {
54+
const tableColumnsNames: Record<TableColumnId, string> = {
5255
PoolName: 'Pool Name',
53-
Type: 'Type',
54-
ErasureSpecies: 'Erasure',
55-
GroupID: 'Group ID',
56+
Kind: 'Type',
57+
Erasure: 'Erasure',
58+
GroupId: 'Group ID',
5659
Used: 'Used',
5760
Limit: 'Limit',
5861
UsedSpaceFlag: 'Space',
59-
UsedPercents: 'Usage',
62+
Usage: 'Usage',
6063
Read: 'Read',
6164
Write: 'Write',
6265
VDisks: 'VDisks',
63-
Missing: 'Degraded',
66+
Degraded: 'Degraded',
6467
};
6568

6669
const b = cn('global-storage-groups');
6770

68-
function setSortOrder(visibleEntities: VisibleEntities): SortOrder | undefined {
69-
switch (visibleEntities) {
70-
case VISIBLE_ENTITIES.all: {
71-
return {
72-
columnId: TableColumnsIds.PoolName,
73-
order: DataTable.ASCENDING,
74-
};
75-
}
76-
case VISIBLE_ENTITIES.missing: {
77-
return {
78-
columnId: TableColumnsIds.Missing,
79-
order: DataTable.DESCENDING,
80-
};
81-
}
82-
case VISIBLE_ENTITIES.space: {
83-
return {
84-
columnId: TableColumnsIds.UsedSpaceFlag,
85-
order: DataTable.DESCENDING,
86-
};
87-
}
88-
default: {
89-
return undefined;
90-
}
91-
}
92-
}
93-
9471
export function StorageGroups({
9572
data,
9673
tableSettings,
9774
visibleEntities,
9875
nodes,
9976
onShowAll,
77+
sort,
78+
handleSort,
10079
}: StorageGroupsProps) {
101-
const allColumns: Column<PreparedStorageGroup>[] = [
80+
const rawColumns: Column<PreparedStorageGroup>[] = [
10281
{
10382
name: TableColumnsIds.PoolName,
10483
header: tableColumnsNames[TableColumnsIds.PoolName],
@@ -124,8 +103,8 @@ export function StorageGroups({
124103
align: DataTable.LEFT,
125104
},
126105
{
127-
name: TableColumnsIds.Type,
128-
header: tableColumnsNames[TableColumnsIds.Type],
106+
name: TableColumnsIds.Kind,
107+
header: tableColumnsNames[TableColumnsIds.Kind],
129108
// prettier-ignore
130109
render: ({row}) => (
131110
<>
@@ -146,14 +125,14 @@ export function StorageGroups({
146125
),
147126
},
148127
{
149-
name: TableColumnsIds.ErasureSpecies,
150-
header: tableColumnsNames[TableColumnsIds.ErasureSpecies],
128+
name: TableColumnsIds.Erasure,
129+
header: tableColumnsNames[TableColumnsIds.Erasure],
151130
render: ({row}) => (row.ErasureSpecies ? row.ErasureSpecies : '-'),
152131
align: DataTable.LEFT,
153132
},
154133
{
155-
name: TableColumnsIds.Missing,
156-
header: tableColumnsNames[TableColumnsIds.Missing],
134+
name: TableColumnsIds.Degraded,
135+
header: tableColumnsNames[TableColumnsIds.Degraded],
157136
width: 100,
158137
render: ({row}) =>
159138
row.Degraded ? (
@@ -165,8 +144,8 @@ export function StorageGroups({
165144
defaultOrder: DataTable.DESCENDING,
166145
},
167146
{
168-
name: TableColumnsIds.UsedPercents,
169-
header: tableColumnsNames[TableColumnsIds.UsedPercents],
147+
name: TableColumnsIds.Usage,
148+
header: tableColumnsNames[TableColumnsIds.Usage],
170149
width: 100,
171150
render: ({row}) => {
172151
// without a limit the usage can be evaluated as 0,
@@ -187,12 +166,13 @@ export function StorageGroups({
187166
align: DataTable.LEFT,
188167
},
189168
{
190-
name: TableColumnsIds.GroupID,
191-
header: tableColumnsNames[TableColumnsIds.GroupID],
169+
name: TableColumnsIds.GroupId,
170+
header: tableColumnsNames[TableColumnsIds.GroupId],
192171
width: 130,
193172
render: ({row}) => {
194173
return <span className={b('group-id')}>{row.GroupID}</span>;
195174
},
175+
sortAccessor: (row) => Number(row.GroupID),
196176
align: DataTable.RIGHT,
197177
},
198178
{
@@ -296,18 +276,21 @@ export function StorageGroups({
296276
},
297277
];
298278

299-
let columns = allColumns;
279+
let columns = rawColumns.map((column) => ({
280+
...column,
281+
sortable: isSortableStorageProperty(column.name),
282+
}));
300283

301284
if (visibleEntities === VISIBLE_ENTITIES.all) {
302-
columns = allColumns.filter((col) => {
285+
columns = columns.filter((col) => {
303286
return (
304-
col.name !== TableColumnsIds.Missing && col.name !== TableColumnsIds.UsedSpaceFlag
287+
col.name !== TableColumnsIds.Degraded && col.name !== TableColumnsIds.UsedSpaceFlag
305288
);
306289
});
307290
}
308291

309292
if (visibleEntities === VISIBLE_ENTITIES.space) {
310-
columns = allColumns.filter((col) => col.name !== TableColumnsIds.Missing);
293+
columns = columns.filter((col) => col.name !== TableColumnsIds.Degraded);
311294

312295
if (!data.length) {
313296
return (
@@ -321,7 +304,7 @@ export function StorageGroups({
321304
}
322305

323306
if (visibleEntities === VISIBLE_ENTITIES.missing) {
324-
columns = allColumns.filter((col) => col.name !== TableColumnsIds.UsedSpaceFlag);
307+
columns = columns.filter((col) => col.name !== TableColumnsIds.UsedSpaceFlag);
325308

326309
if (!data.length) {
327310
return (
@@ -341,8 +324,9 @@ export function StorageGroups({
341324
data={data}
342325
columns={columns}
343326
settings={tableSettings}
344-
initialSortOrder={setSortOrder(visibleEntities)}
345327
emptyDataMessage={i18n('empty.default')}
328+
sortOrder={sort}
329+
onSort={handleSort}
346330
/>
347331
) : null;
348332
}

0 commit comments

Comments
 (0)