Skip to content

Commit 45c0a1e

Browse files
feat: use groups handler for storage (#1225)
1 parent a3488da commit 45c0a1e

File tree

10 files changed

+160
-73
lines changed

10 files changed

+160
-73
lines changed

src/containers/PDiskPage/PDiskGroups/PDiskGroups.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import React from 'react';
22

33
import {ResizeableDataTable} from '../../../components/ResizeableDataTable/ResizeableDataTable';
44
import {TableSkeleton} from '../../../components/TableSkeleton/TableSkeleton';
5+
import {
6+
useCapabilitiesLoaded,
7+
useStorageGroupsHandlerAvailable,
8+
} from '../../../store/reducers/capabilities/hooks';
59
import {storageApi} from '../../../store/reducers/storage/storage';
610
import {DEFAULT_TABLE_SETTINGS} from '../../../utils/constants';
711
import {useAutoRefreshInterval} from '../../../utils/hooks';
@@ -16,11 +20,16 @@ interface PDiskGroupsProps {
1620
}
1721

1822
export function PDiskGroups({pDiskId, nodeId}: PDiskGroupsProps) {
23+
const capabilitiesLoaded = useCapabilitiesLoaded();
24+
const groupsHandlerAvailable = useStorageGroupsHandlerAvailable();
1925
const [autoRefreshInterval] = useAutoRefreshInterval();
2026

2127
const {currentData, isFetching} = storageApi.useGetStorageGroupsInfoQuery(
22-
{pDiskId, nodeId},
23-
{pollingInterval: autoRefreshInterval},
28+
{pDiskId, nodeId, shouldUseGroupsHandler: groupsHandlerAvailable},
29+
{
30+
pollingInterval: autoRefreshInterval,
31+
skip: !capabilitiesLoaded,
32+
},
2433
);
2534
const loading = isFetching && currentData === undefined;
2635

@@ -30,7 +39,7 @@ export function PDiskGroups({pDiskId, nodeId}: PDiskGroupsProps) {
3039

3140
const pDiskStorageColumns = useGetDiskStorageColumns();
3241

33-
if (loading) {
42+
if (loading || !capabilitiesLoaded) {
3443
return <TableSkeleton />;
3544
}
3645

src/containers/Storage/Storage.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import {AccessDenied} from '../../components/Errors/403';
66
import {isAccessError} from '../../components/Errors/PageError/PageError';
77
import {ResponseError} from '../../components/Errors/ResponseError';
88
import {TableWithControlsLayout} from '../../components/TableWithControlsLayout/TableWithControlsLayout';
9+
import {
10+
useCapabilitiesLoaded,
11+
useStorageGroupsHandlerAvailable,
12+
} from '../../store/reducers/capabilities/hooks';
913
import type {NodesSortParams} from '../../store/reducers/nodes/types';
1014
import {STORAGE_TYPES, VISIBLE_ENTITIES} from '../../store/reducers/storage/constants';
1115
import {
@@ -57,7 +61,10 @@ interface StorageProps {
5761
}
5862

5963
export const Storage = ({additionalNodesProps, database, nodeId}: StorageProps) => {
64+
const capabilitiesLoaded = useCapabilitiesLoaded();
65+
const groupsHandlerAvailable = useStorageGroupsHandlerAvailable();
6066
const [autoRefreshInterval] = useAutoRefreshInterval();
67+
6168
const [queryParams, setQueryParams] = useQueryParams({
6269
type: StringParam,
6370
visible: StringParam,
@@ -95,9 +102,9 @@ export const Storage = ({additionalNodesProps, database, nodeId}: StorageProps)
95102
},
96103
);
97104
const groupsQuery = storageApi.useGetStorageGroupsInfoQuery(
98-
{database, with: visibleEntities, nodeId},
105+
{database, with: visibleEntities, nodeId, shouldUseGroupsHandler: groupsHandlerAvailable},
99106
{
100-
skip: storageType !== STORAGE_TYPES.groups,
107+
skip: storageType !== STORAGE_TYPES.groups || !capabilitiesLoaded,
101108
pollingInterval: autoRefreshInterval,
102109
},
103110
);
@@ -220,7 +227,10 @@ export const Storage = ({additionalNodesProps, database, nodeId}: StorageProps)
220227
<TableWithControlsLayout>
221228
<TableWithControlsLayout.Controls>{renderControls()}</TableWithControlsLayout.Controls>
222229
{error ? <ResponseError error={error} /> : null}
223-
<TableWithControlsLayout.Table loading={isLoading} className={b('table')}>
230+
<TableWithControlsLayout.Table
231+
loading={isLoading || !capabilitiesLoaded}
232+
className={b('table')}
233+
>
224234
{currentData ? renderDataTable() : null}
225235
</TableWithControlsLayout.Table>
226236
</TableWithControlsLayout>

src/containers/Storage/StorageGroups/PaginatedStorageGroups.tsx

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import React from 'react';
22

3+
import {LoaderWrapper} from '../../../components/LoaderWrapper/LoaderWrapper';
34
import type {RenderControls, RenderErrorMessage} from '../../../components/PaginatedTable';
45
import {ResizeablePaginatedTable} from '../../../components/PaginatedTable';
6+
import {
7+
useCapabilitiesLoaded,
8+
useStorageGroupsHandlerAvailable,
9+
} from '../../../store/reducers/capabilities/hooks';
510
import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
611
import type {VisibleEntities} from '../../../store/reducers/storage/types';
712

813
import {StorageGroupsEmptyDataMessage} from './StorageGroupsEmptyDataMessage';
914
import {STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY} from './columns/getStorageGroupsColumns';
1015
import {useGetStorageGroupsColumns} from './columns/hooks';
11-
import {getStorageGroups} from './getGroups';
16+
import {useGroupsGetter} from './getGroups';
1217
import i18n from './i18n';
1318

1419
interface PaginatedStorageGroupsProps {
@@ -36,6 +41,11 @@ export const PaginatedStorageGroups = ({
3641
}: PaginatedStorageGroupsProps) => {
3742
const columns = useGetStorageGroupsColumns(visibleEntities);
3843

44+
const capabilitiesLoaded = useCapabilitiesLoaded();
45+
const groupsHandlerAvailable = useStorageGroupsHandlerAvailable();
46+
47+
const fetchData = useGroupsGetter(groupsHandlerAvailable);
48+
3949
const tableFilters = React.useMemo(() => {
4050
return {searchValue, visibleEntities, database, nodeId};
4151
}, [searchValue, visibleEntities, database, nodeId]);
@@ -54,17 +64,19 @@ export const PaginatedStorageGroups = ({
5464
};
5565

5666
return (
57-
<ResizeablePaginatedTable
58-
columnsWidthLSKey={STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY}
59-
parentContainer={parentContainer}
60-
columns={columns}
61-
fetchData={getStorageGroups}
62-
limit={50}
63-
renderControls={renderControls}
64-
renderErrorMessage={renderErrorMessage}
65-
renderEmptyDataMessage={renderEmptyDataMessage}
66-
filters={tableFilters}
67-
tableName="storage-groups"
68-
/>
67+
<LoaderWrapper loading={!capabilitiesLoaded}>
68+
<ResizeablePaginatedTable
69+
columnsWidthLSKey={STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY}
70+
parentContainer={parentContainer}
71+
columns={columns}
72+
fetchData={fetchData}
73+
limit={50}
74+
renderControls={renderControls}
75+
renderErrorMessage={renderErrorMessage}
76+
renderEmptyDataMessage={renderEmptyDataMessage}
77+
filters={tableFilters}
78+
tableName="storage-groups"
79+
/>
80+
</LoaderWrapper>
6981
);
7082
};
Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,51 @@
1+
import React from 'react';
2+
13
import type {FetchData} from '../../../components/PaginatedTable';
4+
import {requestStorageData} from '../../../store/reducers/storage/requestStorageData';
25
import type {
36
PreparedStorageGroup,
47
PreparedStorageGroupFilters,
58
} from '../../../store/reducers/storage/types';
6-
import {prepareStorageResponse} from '../../../store/reducers/storage/utils';
79
import type {StorageV2Sort} from '../../../types/api/storage';
810
import {prepareSortValue} from '../../../utils/filters';
911

1012
const getConcurrentId = (limit?: number, offset?: number) => {
1113
return `getStorageGroups|offset${offset}|limit${limit}`;
1214
};
1315

14-
export const getStorageGroups: FetchData<
15-
PreparedStorageGroup,
16-
PreparedStorageGroupFilters
17-
> = async (params) => {
18-
const {limit, offset, sortParams, filters} = params;
19-
const {sortOrder, columnId} = sortParams ?? {};
20-
const {searchValue, visibleEntities, database, nodeId} = filters ?? {};
21-
22-
const sort = prepareSortValue(columnId, sortOrder) as StorageV2Sort;
23-
24-
const response = await window.api.getStorageInfo(
25-
{
26-
version: 'v2',
27-
limit,
28-
offset,
29-
sort,
30-
filter: searchValue,
31-
with: visibleEntities,
32-
database,
33-
nodeId,
16+
type GetStorageGroups = FetchData<PreparedStorageGroup, PreparedStorageGroupFilters>;
17+
18+
export function useGroupsGetter(shouldUseGroupsHandler: boolean) {
19+
const fetchData: GetStorageGroups = React.useCallback(
20+
async (params) => {
21+
const {limit, offset, sortParams, filters} = params;
22+
const {sortOrder, columnId} = sortParams ?? {};
23+
const {searchValue, visibleEntities, database, nodeId} = filters ?? {};
24+
25+
const sort = prepareSortValue(columnId, sortOrder) as StorageV2Sort;
26+
27+
const {groups, found, total} = await requestStorageData(
28+
{
29+
limit,
30+
offset,
31+
sort,
32+
filter: searchValue,
33+
with: visibleEntities,
34+
database,
35+
nodeId,
36+
shouldUseGroupsHandler,
37+
},
38+
{concurrentId: getConcurrentId(limit, offset)},
39+
);
40+
41+
return {
42+
data: groups || [],
43+
found: found || 0,
44+
total: total || 0,
45+
};
3446
},
35-
{concurrentId: getConcurrentId(limit, offset)},
47+
[shouldUseGroupsHandler],
3648
);
37-
const preparedResponse = prepareStorageResponse(response);
3849

39-
return {
40-
data: preparedResponse.groups || [],
41-
found: preparedResponse.found || 0,
42-
total: preparedResponse.total || 0,
43-
};
44-
};
50+
return fetchData;
51+
}

src/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopGroups.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import React from 'react';
22

3+
import {
4+
useCapabilitiesLoaded,
5+
useStorageGroupsHandlerAvailable,
6+
} from '../../../../../store/reducers/capabilities/hooks';
37
import {storageApi} from '../../../../../store/reducers/storage/storage';
48
import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../../../store/reducers/tenant/constants';
59
import {TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../../utils/constants';
@@ -22,6 +26,8 @@ interface TopGroupsProps {
2226
export function TopGroups({tenant}: TopGroupsProps) {
2327
const query = useSearchQuery();
2428

29+
const capabilitiesLoaded = useCapabilitiesLoaded();
30+
const groupsHandlerAvailable = useStorageGroupsHandlerAvailable();
2531
const [autoRefreshInterval] = useAutoRefreshInterval();
2632

2733
const columns = getStorageTopGroupsColumns();
@@ -32,8 +38,12 @@ export function TopGroups({tenant}: TopGroupsProps) {
3238
sort: '-Usage',
3339
with: 'all',
3440
limit: TENANT_OVERVIEW_TABLES_LIMIT,
41+
shouldUseGroupsHandler: groupsHandlerAvailable,
42+
},
43+
{
44+
pollingInterval: autoRefreshInterval,
45+
skip: !capabilitiesLoaded,
3546
},
36-
{pollingInterval: autoRefreshInterval},
3747
);
3848

3949
const loading = isFetching && currentData === undefined;
@@ -57,7 +67,7 @@ export function TopGroups({tenant}: TopGroupsProps) {
5767
data={preparedGroups}
5868
columns={columns}
5969
title={title}
60-
loading={loading}
70+
loading={loading || !capabilitiesLoaded}
6171
error={error}
6272
/>
6373
);

src/containers/VDiskPage/VDiskPage.tsx

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ import {ResizeableDataTable} from '../../components/ResizeableDataTable/Resizeab
1515
import {VDiskInfo} from '../../components/VDiskInfo/VDiskInfo';
1616
import {api} from '../../store/reducers/api';
1717
import {selectIsUserAllowedToMakeChanges} from '../../store/reducers/authentication/authentication';
18+
import {
19+
useCapabilitiesLoaded,
20+
useStorageGroupsHandlerAvailable,
21+
} from '../../store/reducers/capabilities/hooks';
1822
import {setHeaderBreadcrumbs} from '../../store/reducers/header/header';
1923
import {storageApi} from '../../store/reducers/storage/storage';
2024
import {vDiskApi} from '../../store/reducers/vdisk/vdisk';
@@ -180,12 +184,7 @@ export function VDiskPage() {
180184

181185
const renderGroupInfo = () => {
182186
if (valueIsDefined(GroupID)) {
183-
return (
184-
<React.Fragment>
185-
<div className={vDiskPageCn('group-title')}>{vDiskPageKeyset('group')}</div>
186-
<VDiskGroup groupId={GroupID} />
187-
</React.Fragment>
188-
);
187+
return <VDiskGroup groupId={GroupID} />;
189188
}
190189

191190
return null;
@@ -217,11 +216,16 @@ export function VDiskPage() {
217216
}
218217

219218
export function VDiskGroup({groupId}: {groupId: string | number}) {
219+
const capabilitiesLoaded = useCapabilitiesLoaded();
220+
const groupsHandlerAvailable = useStorageGroupsHandlerAvailable();
220221
const [autoRefreshInterval] = useAutoRefreshInterval();
221222

222223
const {currentData} = storageApi.useGetStorageGroupsInfoQuery(
223-
{groupId},
224-
{pollingInterval: autoRefreshInterval},
224+
{groupId, shouldUseGroupsHandler: groupsHandlerAvailable},
225+
{
226+
pollingInterval: autoRefreshInterval,
227+
skip: !capabilitiesLoaded,
228+
},
225229
);
226230

227231
const preparedGroups = React.useMemo(() => {
@@ -237,11 +241,14 @@ export function VDiskGroup({groupId}: {groupId: string | number}) {
237241
}
238242

239243
return (
240-
<ResizeableDataTable
241-
columnsWidthLSKey={STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY}
242-
data={preparedGroups}
243-
columns={vDiskStorageColumns}
244-
settings={DEFAULT_TABLE_SETTINGS}
245-
/>
244+
<React.Fragment>
245+
<div className={vDiskPageCn('group-title')}>{vDiskPageKeyset('group')}</div>
246+
<ResizeableDataTable
247+
columnsWidthLSKey={STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY}
248+
data={preparedGroups}
249+
columns={vDiskStorageColumns}
250+
settings={DEFAULT_TABLE_SETTINGS}
251+
/>
252+
</React.Fragment>
246253
);
247254
}

src/services/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const TRACE_CHECK_TIMEOUT = 2 * SECOND_IN_MS;
7171
const TRACE_API_ERROR_TIMEOUT = 10 * SECOND_IN_MS;
7272
const MAX_TRACE_CHECK_RETRIES = 30;
7373

74-
type AxiosOptions = {
74+
export type AxiosOptions = {
7575
concurrentId?: string;
7676
signal?: AbortSignal;
7777
withRetries?: boolean;

src/store/reducers/capabilities/hooks.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import type {Capability} from '../../../types/api/capabilities';
22
import {useTypedSelector} from '../../../utils/hooks';
33

4-
import {selectCapabilityVersion} from './capabilities';
4+
import {capabilitiesApi, selectCapabilityVersion} from './capabilities';
5+
6+
export function useCapabilitiesLoaded() {
7+
const {data, error} = capabilitiesApi.useGetClusterCapabilitiesQuery(undefined);
8+
9+
return Boolean(data || error);
10+
}
511

612
const useGetFeatureVersion = (feature: Capability) => {
713
return useTypedSelector((state) => selectCapabilityVersion(state, feature) || 0);
@@ -20,3 +26,7 @@ export const useDiskPagesAvailable = () => {
2026
export const useTracingLevelOptionAvailable = () => {
2127
return useGetFeatureVersion('/viewer/query') > 2;
2228
};
29+
30+
export const useStorageGroupsHandlerAvailable = () => {
31+
return useGetFeatureVersion('/storage/groups') > 2;
32+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type {AxiosOptions} from '../../../services/api';
2+
import type {StorageRequestParams} from '../../../types/api/storage';
3+
4+
import {prepareGroupsResponse, prepareStorageResponse} from './utils';
5+
6+
export async function requestStorageData(
7+
{
8+
version = 'v2',
9+
shouldUseGroupsHandler,
10+
...params
11+
}: StorageRequestParams & {shouldUseGroupsHandler?: boolean},
12+
options: AxiosOptions,
13+
) {
14+
if (shouldUseGroupsHandler && version !== 'v1') {
15+
const result = await window.api.getStorageGroups({...params}, options);
16+
return prepareGroupsResponse(result);
17+
} else {
18+
const result = await window.api.getStorageInfo({version, ...params}, options);
19+
return prepareStorageResponse(result);
20+
}
21+
}

0 commit comments

Comments
 (0)