Skip to content

Commit a63e5e4

Browse files
feat(Storage): add columns setup
1 parent a987c76 commit a63e5e4

21 files changed

+392
-231
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import React from 'react';
22

3+
import {TableColumnSetup} from '@gravity-ui/uikit';
4+
35
import {ResizeableDataTable} from '../../../components/ResizeableDataTable/ResizeableDataTable';
4-
import {TableSkeleton} from '../../../components/TableSkeleton/TableSkeleton';
6+
import {TableWithControlsLayout} from '../../../components/TableWithControlsLayout/TableWithControlsLayout';
57
import {
68
useCapabilitiesLoaded,
79
useStorageGroupsHandlerAvailable,
@@ -10,7 +12,7 @@ import {storageApi} from '../../../store/reducers/storage/storage';
1012
import {DEFAULT_TABLE_SETTINGS} from '../../../utils/constants';
1113
import {useAutoRefreshInterval} from '../../../utils/hooks';
1214
import {STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY} from '../../Storage/StorageGroups/columns/constants';
13-
import {useGetDiskStorageColumns} from '../../Storage/StorageGroups/columns/hooks';
15+
import {useStorageGroupsSelectedColumns} from '../../Storage/StorageGroups/columns/hooks';
1416

1517
import {preparePDiskStorageResponse} from './utils';
1618

@@ -20,6 +22,8 @@ interface PDiskGroupsProps {
2022
}
2123

2224
export function PDiskGroups({pDiskId, nodeId}: PDiskGroupsProps) {
25+
const {columnsToShow, columnsToSelect, setColumns} = useStorageGroupsSelectedColumns();
26+
2327
const capabilitiesLoaded = useCapabilitiesLoaded();
2428
const groupsHandlerAvailable = useStorageGroupsHandlerAvailable();
2529
const [autoRefreshInterval] = useAutoRefreshInterval();
@@ -37,18 +41,25 @@ export function PDiskGroups({pDiskId, nodeId}: PDiskGroupsProps) {
3741
return preparePDiskStorageResponse(currentData, pDiskId, nodeId) || [];
3842
}, [currentData, pDiskId, nodeId]);
3943

40-
const pDiskStorageColumns = useGetDiskStorageColumns();
41-
42-
if (loading || !capabilitiesLoaded) {
43-
return <TableSkeleton />;
44-
}
45-
4644
return (
47-
<ResizeableDataTable
48-
columnsWidthLSKey={STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY}
49-
data={preparedGroups}
50-
columns={pDiskStorageColumns}
51-
settings={DEFAULT_TABLE_SETTINGS}
52-
/>
45+
<TableWithControlsLayout>
46+
<TableWithControlsLayout.Controls>
47+
<TableColumnSetup
48+
popupWidth={200}
49+
items={columnsToSelect}
50+
showStatus
51+
onUpdate={setColumns}
52+
sortable={false}
53+
/>
54+
</TableWithControlsLayout.Controls>
55+
<TableWithControlsLayout.Table loading={loading || !capabilitiesLoaded}>
56+
<ResizeableDataTable
57+
columnsWidthLSKey={STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY}
58+
data={preparedGroups}
59+
columns={columnsToShow}
60+
settings={DEFAULT_TABLE_SETTINGS}
61+
/>
62+
</TableWithControlsLayout.Table>
63+
</TableWithControlsLayout>
5364
);
5465
}

src/containers/PDiskPage/PDiskPage.scss

+14-14
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,29 @@
66
overflow: auto;
77

88
height: 100%;
9+
padding: 0 20px;
910

10-
&__info-content {
11+
&__meta,
12+
&__title,
13+
&__info,
14+
&__controls,
15+
&__tabs {
1116
position: sticky;
1217
left: 0;
1318

14-
display: flex;
15-
flex-direction: column;
16-
gap: 20px;
17-
18-
padding: 20px;
19+
margin-bottom: 20px;
1920
}
2021

21-
&__tabs-content {
22-
padding-left: 20px;
22+
&__meta {
23+
margin-top: 20px;
2324
}
2425

25-
&__meta,
26-
&__title,
27-
&__info,
28-
&__controls,
2926
&__tabs {
30-
position: sticky;
31-
left: 0;
27+
margin-bottom: 0;
28+
}
29+
30+
&__disk-distribution {
31+
padding: 20px 0;
3232
}
3333

3434
&__title {

src/containers/PDiskPage/PDiskPage.tsx

+13-11
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,11 @@ export function PDiskPage() {
231231
const renderTabsContent = () => {
232232
switch (pDiskTab) {
233233
case 'diskDistribution': {
234-
return pDiskData ? <PDiskSpaceDistribution data={pDiskData} /> : null;
234+
return pDiskData ? (
235+
<div className={pdiskPageCn('disk-distribution')}>
236+
<PDiskSpaceDistribution data={pDiskData} />
237+
</div>
238+
) : null;
235239
}
236240
case 'groups': {
237241
return pDiskParamsDefined ? (
@@ -252,16 +256,14 @@ export function PDiskPage() {
252256

253257
return (
254258
<div className={pdiskPageCn(null)}>
255-
<div className={pdiskPageCn('info-content')}>
256-
{renderHelmet()}
257-
{renderPageMeta()}
258-
{renderPageTitle()}
259-
{renderControls()}
260-
{renderError()}
261-
{renderInfo()}
262-
{renderTabs()}
263-
</div>
264-
<div className={pdiskPageCn('tabs-content')}>{renderTabsContent()}</div>
259+
{renderHelmet()}
260+
{renderPageMeta()}
261+
{renderPageTitle()}
262+
{renderControls()}
263+
{renderError()}
264+
{renderInfo()}
265+
{renderTabs()}
266+
{renderTabsContent()}
265267
</div>
266268
);
267269
}

src/containers/Storage/PaginatedStorage.tsx

+35-5
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import {StringParam, useQueryParams} from 'use-query-params';
33
import {AccessDenied} from '../../components/Errors/403/AccessDenied';
44
import {ResponseError} from '../../components/Errors/ResponseError/ResponseError';
55
import type {RenderControls, RenderErrorMessage} from '../../components/PaginatedTable';
6-
import {STORAGE_TYPES, VISIBLE_ENTITIES} from '../../store/reducers/storage/constants';
6+
import {VISIBLE_ENTITIES} from '../../store/reducers/storage/constants';
77
import {storageTypeSchema, visibleEntitiesSchema} from '../../store/reducers/storage/types';
88
import type {StorageType, VisibleEntities} from '../../store/reducers/storage/types';
99
import type {AdditionalNodesProps} from '../../types/additionalProps';
1010
import {NodesUptimeFilterValues, nodesUptimeFilterValuesSchema} from '../../utils/nodes';
1111

1212
import {StorageControls} from './StorageControls/StorageControls';
1313
import {PaginatedStorageGroups} from './StorageGroups/PaginatedStorageGroups';
14+
import {useStorageGroupsSelectedColumns} from './StorageGroups/columns/hooks';
1415
import {PaginatedStorageNodes} from './StorageNodes/PaginatedStorageNodes';
15-
16-
import './Storage.scss';
16+
import {useStorageNodesSelectedColumns} from './StorageNodes/columns/hooks';
1717

1818
interface PaginatedStorageProps {
1919
database?: string;
@@ -35,10 +35,29 @@ export const PaginatedStorage = ({
3535
uptimeFilter: StringParam,
3636
});
3737
const storageType = storageTypeSchema.parse(queryParams.type);
38+
const isGroups = storageType === 'groups';
39+
const isNodes = storageType === 'nodes';
40+
3841
const visibleEntities = visibleEntitiesSchema.parse(queryParams.visible);
3942
const searchValue = queryParams.search ?? '';
4043
const nodesUptimeFilter = nodesUptimeFilterValuesSchema.parse(queryParams.uptimeFilter);
4144

45+
const {
46+
columnsToShow: storageNodesColumnsToShow,
47+
columnsToSelect: storageNodesColumnsToSelect,
48+
setColumns: setStorageNodesSelectedColumns,
49+
} = useStorageNodesSelectedColumns({
50+
additionalNodesProps,
51+
visibleEntities,
52+
database,
53+
});
54+
55+
const {
56+
columnsToShow: storageGroupsColumnsToShow,
57+
columnsToSelect: storageGroupsColumnsToSelect,
58+
setColumns: setStorageGroupsSelectedColumns,
59+
} = useStorageGroupsSelectedColumns(visibleEntities);
60+
4261
const handleTextFilterChange = (value: string) => {
4362
setQueryParams({search: value || undefined}, 'replaceIn');
4463
};
@@ -70,6 +89,14 @@ export const PaginatedStorage = ({
7089
};
7190

7291
const renderControls: RenderControls = ({totalEntities, foundEntities, inited}) => {
92+
const columnsToSelect = isGroups
93+
? storageGroupsColumnsToSelect
94+
: storageNodesColumnsToSelect;
95+
96+
const handleSelectedColumnsUpdate = isGroups
97+
? setStorageGroupsSelectedColumns
98+
: setStorageNodesSelectedColumns;
99+
73100
return (
74101
<StorageControls
75102
searchValue={searchValue}
@@ -85,6 +112,8 @@ export const PaginatedStorage = ({
85112
entitiesCountCurrent={foundEntities}
86113
entitiesCountTotal={totalEntities}
87114
entitiesLoading={!inited}
115+
columnsToSelect={columnsToSelect}
116+
handleSelectedColumnsUpdate={handleSelectedColumnsUpdate}
88117
/>
89118
);
90119
};
@@ -97,18 +126,18 @@ export const PaginatedStorage = ({
97126
return <ResponseError error={error} />;
98127
};
99128

100-
if (storageType === STORAGE_TYPES.nodes) {
129+
if (isNodes) {
101130
return (
102131
<PaginatedStorageNodes
103132
searchValue={searchValue}
104133
visibleEntities={visibleEntities}
105134
nodesUptimeFilter={nodesUptimeFilter}
106135
database={database}
107-
additionalNodesProps={additionalNodesProps}
108136
onShowAll={handleShowAllNodes}
109137
parentContainer={parentContainer}
110138
renderControls={renderControls}
111139
renderErrorMessage={renderErrorMessage}
140+
columns={storageNodesColumnsToShow}
112141
/>
113142
);
114143
}
@@ -123,6 +152,7 @@ export const PaginatedStorage = ({
123152
parentContainer={parentContainer}
124153
renderControls={renderControls}
125154
renderErrorMessage={renderErrorMessage}
155+
columns={storageGroupsColumnsToShow}
126156
/>
127157
);
128158
};

src/containers/Storage/Storage.tsx

+44-16
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
useStorageGroupsHandlerAvailable,
1212
} from '../../store/reducers/capabilities/hooks';
1313
import type {NodesSortParams} from '../../store/reducers/nodes/types';
14-
import {STORAGE_TYPES, VISIBLE_ENTITIES} from '../../store/reducers/storage/constants';
14+
import {VISIBLE_ENTITIES} from '../../store/reducers/storage/constants';
1515
import {
1616
filterGroups,
1717
filterNodes,
@@ -31,7 +31,9 @@ import {NodesUptimeFilterValues, nodesUptimeFilterValuesSchema} from '../../util
3131

3232
import {StorageControls} from './StorageControls/StorageControls';
3333
import {StorageGroups} from './StorageGroups/StorageGroups';
34+
import {useStorageGroupsSelectedColumns} from './StorageGroups/columns/hooks';
3435
import {StorageNodes} from './StorageNodes/StorageNodes';
36+
import {useStorageNodesSelectedColumns} from './StorageNodes/columns/hooks';
3537
import {b} from './shared';
3638
import {defaultSortNode, getDefaultSortGroup} from './utils';
3739

@@ -73,6 +75,9 @@ export const Storage = ({additionalNodesProps, database, nodeId}: StorageProps)
7375
usageFilter: UsageFilterParam,
7476
});
7577
const storageType = storageTypeSchema.parse(queryParams.type);
78+
const isGroups = storageType === 'groups';
79+
const isNodes = storageType === 'nodes';
80+
7681
const visibleEntities = visibleEntitiesSchema.parse(queryParams.visible);
7782
const filter = queryParams.search ?? '';
7883
const uptimeFilter = nodesUptimeFilterValuesSchema.parse(queryParams.uptimeFilter);
@@ -90,23 +95,38 @@ export const Storage = ({additionalNodesProps, database, nodeId}: StorageProps)
9095
});
9196
const groupsSortParams = groupSort.sortOrder ? groupSort : getDefaultSortGroup(visibleEntities);
9297

98+
const {
99+
columnsToShow: storageNodesColumnsToShow,
100+
columnsToSelect: storageNodesColumnsToSelect,
101+
setColumns: setStorageNodesSelectedColumns,
102+
} = useStorageNodesSelectedColumns({
103+
additionalNodesProps,
104+
visibleEntities,
105+
database,
106+
});
107+
108+
const {
109+
columnsToShow: storageGroupsColumnsToShow,
110+
columnsToSelect: storageGroupsColumnsToSelect,
111+
setColumns: setStorageGroupsSelectedColumns,
112+
} = useStorageGroupsSelectedColumns(visibleEntities);
113+
93114
const nodesQuery = storageApi.useGetStorageNodesInfoQuery(
94115
{database, with: visibleEntities, node_id: nodeId},
95116
{
96-
skip: storageType !== STORAGE_TYPES.nodes,
117+
skip: !isNodes,
97118
pollingInterval: autoRefreshInterval,
98119
},
99120
);
100121
const groupsQuery = storageApi.useGetStorageGroupsInfoQuery(
101122
{database, with: visibleEntities, nodeId, shouldUseGroupsHandler: groupsHandlerAvailable},
102123
{
103-
skip: storageType !== STORAGE_TYPES.groups || !capabilitiesLoaded,
124+
skip: !isGroups || !capabilitiesLoaded,
104125
pollingInterval: autoRefreshInterval,
105126
},
106127
);
107128

108-
const {currentData, isFetching, error} =
109-
storageType === STORAGE_TYPES.nodes ? nodesQuery : groupsQuery;
129+
const {currentData, isFetching, error} = isNodes ? nodesQuery : groupsQuery;
110130

111131
const {currentData: {nodes = []} = {}} = nodesQuery;
112132
const {currentData: {groups = []} = {}} = groupsQuery;
@@ -160,7 +180,7 @@ export const Storage = ({additionalNodesProps, database, nodeId}: StorageProps)
160180
const renderDataTable = () => {
161181
return (
162182
<React.Fragment>
163-
{storageType === STORAGE_TYPES.groups && (
183+
{isGroups ? (
164184
<StorageGroups
165185
key="groups"
166186
visibleEntities={visibleEntities}
@@ -169,27 +189,37 @@ export const Storage = ({additionalNodesProps, database, nodeId}: StorageProps)
169189
onShowAll={() => handleGroupVisibilityChange(VISIBLE_ENTITIES.all)}
170190
sort={groupsSort}
171191
handleSort={handleGroupsSort}
192+
columns={storageGroupsColumnsToShow}
172193
/>
173-
)}
174-
{storageType === STORAGE_TYPES.nodes && (
194+
) : null}
195+
{isNodes ? (
175196
<StorageNodes
176197
key="nodes"
177198
visibleEntities={visibleEntities}
178199
nodesUptimeFilter={uptimeFilter}
179200
data={storageNodes}
180201
tableSettings={DEFAULT_TABLE_SETTINGS}
181202
onShowAll={handleShowAllNodes}
182-
additionalNodesProps={additionalNodesProps}
183203
sort={nodesSort}
184204
handleSort={handleNodesSort}
185-
database={database}
205+
columns={storageNodesColumnsToShow}
186206
/>
187-
)}
207+
) : null}
188208
</React.Fragment>
189209
);
190210
};
191211

192212
const renderControls = () => {
213+
const entitiesCountCurrent = isGroups ? storageGroups.length : storageNodes.length;
214+
215+
const columnsToSelect = isGroups
216+
? storageGroupsColumnsToSelect
217+
: storageNodesColumnsToSelect;
218+
219+
const handleSelectedColumnsUpdate = isGroups
220+
? setStorageGroupsSelectedColumns
221+
: setStorageNodesSelectedColumns;
222+
193223
return (
194224
<StorageControls
195225
searchValue={filter}
@@ -204,13 +234,11 @@ export const Storage = ({additionalNodesProps, database, nodeId}: StorageProps)
204234
groupsUsageFilter={usageFilter}
205235
groupsUsageFilterOptions={usageFilterOptions}
206236
handleGroupsUsageFilterChange={handleUsageFilterChange}
207-
entitiesCountCurrent={
208-
storageType === STORAGE_TYPES.groups
209-
? storageGroups.length
210-
: storageNodes.length
211-
}
237+
entitiesCountCurrent={entitiesCountCurrent}
212238
entitiesCountTotal={entitiesCount.total}
213239
entitiesLoading={isLoading}
240+
columnsToSelect={columnsToSelect}
241+
handleSelectedColumnsUpdate={handleSelectedColumnsUpdate}
214242
/>
215243
);
216244
};

0 commit comments

Comments
 (0)