ydb-embedded-ui 4.13.0 → 4.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/components/Tablet/Tablet.scss +1 -16
  3. package/dist/components/Tablet/Tablet.tsx +5 -5
  4. package/dist/components/TabletIcon/TabletIcon.scss +17 -0
  5. package/dist/components/TabletIcon/TabletIcon.tsx +18 -0
  6. package/dist/containers/App/App.js +1 -1
  7. package/dist/containers/AsideNavigation/AsideNavigation.tsx +1 -1
  8. package/dist/containers/Authentication/Authentication.tsx +1 -1
  9. package/dist/containers/Header/Header.scss +2 -0
  10. package/dist/containers/Header/Header.tsx +2 -7
  11. package/dist/containers/Header/{breadcrumbs.ts → breadcrumbs.tsx} +19 -8
  12. package/dist/containers/Nodes/Nodes.tsx +53 -16
  13. package/dist/containers/Nodes/getNodesColumns.tsx +31 -13
  14. package/dist/containers/Storage/Storage.tsx +64 -32
  15. package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +56 -73
  16. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +33 -43
  17. package/dist/containers/Storage/utils/index.ts +3 -3
  18. package/dist/containers/Tablet/Tablet.tsx +9 -3
  19. package/dist/containers/Tenant/Query/QueryDuration/QueryDuration.scss +8 -0
  20. package/dist/containers/Tenant/Query/QueryDuration/QueryDuration.tsx +13 -1
  21. package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.scss +3 -1
  22. package/dist/containers/Tenant/Query/i18n/en.json +6 -4
  23. package/dist/containers/Tenant/Query/i18n/ru.json +6 -4
  24. package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +4 -0
  25. package/dist/containers/Tenant/i18n/en.json +3 -0
  26. package/dist/containers/Tenant/i18n/ru.json +3 -0
  27. package/dist/containers/Tenant/utils/queryTemplates.ts +89 -0
  28. package/dist/containers/Tenant/utils/schema.ts +1 -1
  29. package/dist/containers/Tenant/utils/schemaActions.ts +30 -54
  30. package/dist/containers/Tenant/utils/schemaControls.tsx +69 -0
  31. package/dist/containers/UserSettings/i18n/en.json +3 -0
  32. package/dist/containers/UserSettings/i18n/ru.json +3 -0
  33. package/dist/containers/UserSettings/settings.ts +12 -1
  34. package/dist/{reportWebVitals.js → reportWebVitals.ts} +3 -1
  35. package/dist/services/api.ts +30 -16
  36. package/dist/store/reducers/{authentication.js → authentication/authentication.ts} +14 -7
  37. package/dist/store/reducers/authentication/types.ts +15 -0
  38. package/dist/store/reducers/describe.ts +1 -16
  39. package/dist/store/reducers/header/types.ts +2 -0
  40. package/dist/store/reducers/index.ts +1 -1
  41. package/dist/store/reducers/nodes/nodes.ts +23 -6
  42. package/dist/store/reducers/nodes/selectors.ts +2 -2
  43. package/dist/store/reducers/nodes/types.ts +15 -5
  44. package/dist/store/reducers/settings/settings.ts +5 -0
  45. package/dist/store/reducers/storage/selectors.ts +50 -150
  46. package/dist/store/reducers/storage/storage.ts +73 -25
  47. package/dist/store/reducers/storage/types.ts +49 -17
  48. package/dist/store/reducers/storage/utils.ts +207 -0
  49. package/dist/store/utils.ts +1 -1
  50. package/dist/types/api/compute.ts +0 -12
  51. package/dist/types/api/error.ts +4 -0
  52. package/dist/types/api/nodes.ts +0 -12
  53. package/dist/types/api/storage.ts +32 -4
  54. package/dist/types/window.d.ts +1 -0
  55. package/dist/utils/constants.ts +3 -0
  56. package/dist/utils/filters.ts +23 -0
  57. package/dist/utils/hooks/index.ts +4 -0
  58. package/dist/utils/hooks/useNodesRequestParams.ts +46 -0
  59. package/dist/utils/hooks/useStorageRequestParams.ts +28 -0
  60. package/dist/utils/hooks/useTableSort.ts +37 -0
  61. package/dist/utils/nodes.ts +25 -0
  62. package/dist/utils/storage.ts +31 -3
  63. package/package.json +2 -6
  64. package/dist/HOCS/WithSearch/WithSearch.js +0 -26
  65. package/dist/HOCS/index.js +0 -1
  66. package/dist/components/Hotkey/Hotkey.js +0 -102
  67. package/dist/components/Pagination/Pagination.js +0 -63
  68. package/dist/components/Pagination/Pagination.scss +0 -28
  69. package/dist/types/store/storage.ts +0 -12
  70. /package/dist/{index.js → index.tsx} +0 -0
  71. /package/dist/utils/{monaco.js → monaco.ts} +0 -0
@@ -1,20 +1,22 @@
1
+ import type {OrderType} from '@gravity-ui/react-data-table';
2
+
1
3
  import type {IResponseError} from '../../../types/api/error';
2
- import type {TNodesInfo, TSystemStateInfo} from '../../../types/api/nodes';
4
+ import type {TSystemStateInfo} from '../../../types/api/nodes';
3
5
  import type {TPDiskStateInfo} from '../../../types/api/pdisk';
4
- import type {
5
- TBSGroupStateInfo,
6
- THiveStorageGroupStats,
7
- TStorageInfo,
8
- } from '../../../types/api/storage';
6
+ import type {EVersion, TStorageGroupInfo} from '../../../types/api/storage';
7
+ import type {TVDiskStateInfo} from '../../../types/api/vdisk';
9
8
  import type {ValueOf} from '../../../types/common';
10
- import type {NodesUptimeFilterValues} from '../../../utils/nodes';
9
+ import type {NodesSortValue, NodesUptimeFilterValues} from '../../../utils/nodes';
10
+ import type {StorageSortValue} from '../../../utils/storage';
11
11
  import type {ApiRequestAction} from '../../utils';
12
12
 
13
13
  import {STORAGE_TYPES, VISIBLE_ENTITIES} from './constants';
14
14
  import {
15
15
  FETCH_STORAGE,
16
16
  setDataWasNotLoaded,
17
+ setGroupsSortParams,
17
18
  setInitialState,
19
+ setNodesSortParams,
18
20
  setNodesUptimeFilter,
19
21
  setStorageTextFilter,
20
22
  setStorageType,
@@ -28,23 +30,24 @@ export type StorageType = ValueOf<typeof STORAGE_TYPES>;
28
30
  export interface PreparedStorageNode extends TSystemStateInfo {
29
31
  NodeId: number;
30
32
  PDisks: TPDiskStateInfo[] | undefined;
33
+ VDisks: TVDiskStateInfo[] | undefined;
31
34
 
32
35
  Missing: number;
33
36
  Uptime: string;
34
37
  }
35
38
 
36
- export type RawStorageGroup = TBSGroupStateInfo & THiveStorageGroupStats;
37
-
38
- export interface PreparedStorageGroup extends RawStorageGroup {
39
+ export interface PreparedStorageGroup extends TStorageGroupInfo {
39
40
  PoolName: string | undefined;
40
41
 
42
+ Usage: number;
41
43
  Read: number;
42
44
  Write: number;
43
45
  Used: number;
44
46
  Limit: number;
45
- Missing: number;
47
+ Degraded: number;
48
+ Kind: string | undefined;
49
+
46
50
  UsedSpaceFlag: number;
47
- Type: string | null;
48
51
  }
49
52
 
50
53
  export interface UsageFilter {
@@ -52,10 +55,24 @@ export interface UsageFilter {
52
55
  count: number;
53
56
  }
54
57
 
55
- export interface StorageApiRequestParams {
58
+ export interface StorageSortParams {
59
+ sortOrder?: OrderType;
60
+ sortValue?: StorageSortValue;
61
+ }
62
+
63
+ export interface StorageSortAndFilterParams extends StorageSortParams {
64
+ filter?: string; // PoolName or GroupId
65
+
66
+ offser?: number;
67
+ limit?: number;
68
+ }
69
+
70
+ export interface StorageApiRequestParams extends StorageSortAndFilterParams {
56
71
  tenant?: string;
57
72
  nodeId?: string;
58
73
  visibleEntities?: VisibleEntities;
74
+
75
+ version?: EVersion;
59
76
  }
60
77
 
61
78
  export interface StorageState {
@@ -65,15 +82,28 @@ export interface StorageState {
65
82
  usageFilter: string[];
66
83
  visible: VisibleEntities;
67
84
  nodesUptimeFilter: NodesUptimeFilterValues;
85
+ groupsSortValue?: StorageSortValue;
86
+ groupsSortOrder?: OrderType;
87
+ nodesSortValue?: NodesSortValue;
88
+ nodesSortOrder?: OrderType;
68
89
  type: StorageType;
69
- nodes?: TNodesInfo;
70
- groups?: TStorageInfo;
90
+ nodes?: PreparedStorageNode[];
91
+ groups?: PreparedStorageGroup[];
92
+ found?: number;
93
+ total?: number;
71
94
  error?: IResponseError;
72
95
  }
73
96
 
97
+ export interface PreparedStorageResponse {
98
+ nodes?: PreparedStorageNode[];
99
+ groups?: PreparedStorageGroup[];
100
+ found: number | undefined;
101
+ total: number | undefined;
102
+ }
103
+
74
104
  type GetStorageInfoApiRequestAction = ApiRequestAction<
75
105
  typeof FETCH_STORAGE,
76
- {nodes?: TNodesInfo; groups?: TStorageInfo},
106
+ PreparedStorageResponse,
77
107
  IResponseError
78
108
  >;
79
109
 
@@ -85,7 +115,9 @@ export type StorageAction =
85
115
  | ReturnType<typeof setUsageFilter>
86
116
  | ReturnType<typeof setVisibleEntities>
87
117
  | ReturnType<typeof setNodesUptimeFilter>
88
- | ReturnType<typeof setDataWasNotLoaded>;
118
+ | ReturnType<typeof setDataWasNotLoaded>
119
+ | ReturnType<typeof setNodesSortParams>
120
+ | ReturnType<typeof setGroupsSortParams>;
89
121
 
90
122
  export interface StorageStateSlice {
91
123
  storage: StorageState;
@@ -0,0 +1,207 @@
1
+ import type {TNodeInfo, TNodesInfo} from '../../../types/api/nodes';
2
+ import type {
3
+ TStorageGroupInfo,
4
+ TStorageGroupInfoV2,
5
+ TStorageInfo,
6
+ } from '../../../types/api/storage';
7
+ import {EVDiskState, type TVDiskStateInfo} from '../../../types/api/vdisk';
8
+ import {TPDiskState} from '../../../types/api/pdisk';
9
+ import {EFlag} from '../../../types/api/enums';
10
+ import {getPDiskType} from '../../../utils/pdisk';
11
+ import {getUsage} from '../../../utils/storage';
12
+ import {calcUptime} from '../../../utils';
13
+
14
+ import type {PreparedStorageGroup, PreparedStorageNode, PreparedStorageResponse} from './types';
15
+
16
+ // ==== Constants ====
17
+
18
+ const FLAGS_POINTS = {
19
+ [EFlag.Green]: 1,
20
+ [EFlag.Yellow]: 100,
21
+ [EFlag.Orange]: 10_000,
22
+ [EFlag.Red]: 1_000_000,
23
+ };
24
+
25
+ // ==== Prepare groups ====
26
+
27
+ const prepareVDisk = (vDisk: TVDiskStateInfo, poolName: string | undefined) => {
28
+ // VDisk doesn't have its own StoragePoolName when located inside StoragePool data
29
+ return {
30
+ ...vDisk,
31
+ StoragePoolName: poolName,
32
+ Donors: vDisk.Donors?.map((donor) => ({
33
+ ...donor,
34
+ StoragePoolName: poolName,
35
+ })),
36
+ };
37
+ };
38
+
39
+ const prepareStorageGroupData = (
40
+ group: TStorageGroupInfo,
41
+ poolName?: string,
42
+ ): PreparedStorageGroup => {
43
+ let missing = 0;
44
+ let usedSpaceFlag = 0;
45
+ let usedSpaceBytes = 0;
46
+ let limitSizeBytes = 0;
47
+ let readSpeedBytesPerSec = 0;
48
+ let writeSpeedBytesPerSec = 0;
49
+ let mediaType = '';
50
+
51
+ if (group.VDisks) {
52
+ for (const vDisk of group.VDisks) {
53
+ const {
54
+ Replicated,
55
+ VDiskState,
56
+ AvailableSize,
57
+ AllocatedSize,
58
+ PDisk,
59
+ DiskSpace,
60
+ ReadThroughput,
61
+ WriteThroughput,
62
+ } = vDisk;
63
+
64
+ if (
65
+ !Replicated ||
66
+ PDisk?.State !== TPDiskState.Normal ||
67
+ VDiskState !== EVDiskState.OK
68
+ ) {
69
+ missing += 1;
70
+ }
71
+
72
+ if (DiskSpace && DiskSpace !== EFlag.Grey) {
73
+ usedSpaceFlag += FLAGS_POINTS[DiskSpace];
74
+ }
75
+
76
+ const available = Number(AvailableSize ?? PDisk?.AvailableSize) || 0;
77
+ const allocated = Number(AllocatedSize) || 0;
78
+
79
+ usedSpaceBytes += allocated;
80
+ limitSizeBytes += available + allocated;
81
+
82
+ readSpeedBytesPerSec += Number(ReadThroughput) || 0;
83
+ writeSpeedBytesPerSec += Number(WriteThroughput) || 0;
84
+
85
+ const currentType = getPDiskType(PDisk || {});
86
+ mediaType =
87
+ currentType && (currentType === mediaType || mediaType === '')
88
+ ? currentType
89
+ : 'Mixed';
90
+ }
91
+ }
92
+
93
+ const vDisks = group.VDisks?.map((vdisk) => prepareVDisk(vdisk, poolName));
94
+ const usage = getUsage({Used: usedSpaceBytes, Limit: limitSizeBytes}, 5);
95
+
96
+ return {
97
+ ...group,
98
+ VDisks: vDisks,
99
+ Usage: usage,
100
+ Read: readSpeedBytesPerSec,
101
+ Write: writeSpeedBytesPerSec,
102
+ PoolName: poolName,
103
+ Used: usedSpaceBytes,
104
+ Limit: limitSizeBytes,
105
+ Degraded: missing,
106
+ UsedSpaceFlag: usedSpaceFlag,
107
+ Kind: mediaType || undefined,
108
+ };
109
+ };
110
+
111
+ const prepareStorageGroupDataV2 = (group: TStorageGroupInfoV2): PreparedStorageGroup => {
112
+ const {
113
+ VDisks = [],
114
+ PoolName,
115
+ Usage = 0,
116
+ Read = 0,
117
+ Write = 0,
118
+ Used = 0,
119
+ Limit = 0,
120
+ Degraded = 0,
121
+ Kind,
122
+ } = group;
123
+
124
+ const UsedSpaceFlag = VDisks.reduce((acc, {DiskSpace}) => {
125
+ if (DiskSpace && DiskSpace !== EFlag.Grey) {
126
+ return acc + FLAGS_POINTS[DiskSpace];
127
+ }
128
+ return acc;
129
+ }, 0);
130
+
131
+ const vDisks = VDisks.map((vdisk) => prepareVDisk(vdisk, PoolName));
132
+ const usage = Math.floor(Number(Usage) * 100);
133
+
134
+ return {
135
+ ...group,
136
+ UsedSpaceFlag,
137
+ PoolName,
138
+ Kind,
139
+ VDisks: vDisks,
140
+ Usage: usage,
141
+ Read: Number(Read),
142
+ Write: Number(Write),
143
+ Used: Number(Used),
144
+ Limit: Number(Limit),
145
+ Degraded: Number(Degraded),
146
+ };
147
+ };
148
+
149
+ // ==== Prepare nodes ====
150
+
151
+ const prepareStorageNodeData = (node: TNodeInfo): PreparedStorageNode => {
152
+ const systemState = node.SystemState ?? {};
153
+ const missing =
154
+ node.PDisks?.filter((pDisk) => {
155
+ return pDisk.State !== TPDiskState.Normal;
156
+ }).length || 0;
157
+
158
+ return {
159
+ NodeId: node.NodeId,
160
+ SystemState: systemState.SystemState,
161
+ DataCenter: systemState.DataCenter,
162
+ Rack: systemState.Rack,
163
+ Host: systemState.Host,
164
+ Endpoints: systemState.Endpoints,
165
+ Uptime: calcUptime(systemState.StartTime),
166
+ StartTime: systemState.StartTime,
167
+ PDisks: node.PDisks,
168
+ VDisks: node.VDisks,
169
+ Missing: missing,
170
+ };
171
+ };
172
+
173
+ // ==== Prepare responses ====
174
+
175
+ export const prepareStorageNodesResponse = (data: TNodesInfo): PreparedStorageResponse => {
176
+ const {Nodes, TotalNodes, FoundNodes} = data;
177
+
178
+ const preparedNodes = Nodes?.map(prepareStorageNodeData);
179
+
180
+ return {
181
+ nodes: preparedNodes,
182
+ total: Number(TotalNodes) || preparedNodes?.length,
183
+ found: Number(FoundNodes),
184
+ };
185
+ };
186
+
187
+ export const prepareStorageGroupsResponse = (data: TStorageInfo): PreparedStorageResponse => {
188
+ const {StoragePools, StorageGroups, TotalGroups, FoundGroups} = data;
189
+
190
+ let preparedGroups: PreparedStorageGroup[] = [];
191
+
192
+ if (StorageGroups) {
193
+ preparedGroups = StorageGroups.map(prepareStorageGroupDataV2);
194
+ } else {
195
+ StoragePools?.forEach((pool) => {
196
+ pool.Groups?.forEach((group) => {
197
+ preparedGroups.push(prepareStorageGroupData(group, pool.Name));
198
+ });
199
+ });
200
+ }
201
+
202
+ return {
203
+ groups: preparedGroups,
204
+ total: Number(TotalGroups) || preparedGroups.length,
205
+ found: Number(FoundGroups),
206
+ };
207
+ };
@@ -3,7 +3,7 @@ import {AxiosResponse} from 'axios';
3
3
 
4
4
  import createToast from '../utils/createToast';
5
5
 
6
- import {SET_UNAUTHENTICATED} from './reducers/authentication';
6
+ import {SET_UNAUTHENTICATED} from './reducers/authentication/authentication';
7
7
  import type {GetState} from './reducers';
8
8
 
9
9
  export const nop = (result: any) => result;
@@ -65,15 +65,3 @@ export enum EVersion {
65
65
  v1 = 'v1',
66
66
  v2 = 'v2', // only this versions works with sorting
67
67
  }
68
-
69
- export enum ESort {
70
- NodeId = 'NodeId',
71
- Host = 'Host',
72
- DC = 'DC',
73
- Rack = 'Rack',
74
- Version = 'Version',
75
- Uptime = 'Uptime',
76
- Memory = 'Memory',
77
- CPU = 'CPU',
78
- LoadAverage = 'LoadAverage',
79
- }
@@ -18,3 +18,7 @@ export interface NetworkError {
18
18
  number?: unknown;
19
19
  stack?: string;
20
20
  }
21
+
22
+ export type AuthErrorResponse = IResponseError<{
23
+ error?: string;
24
+ }>;
@@ -101,15 +101,3 @@ enum EConfigState {
101
101
  'Consistent' = 'Consistent',
102
102
  'Outdated' = 'Outdated',
103
103
  }
104
-
105
- export enum ESort {
106
- NodeId = 'NodeId',
107
- Host = 'Host',
108
- DC = 'DC',
109
- Rack = 'Rack',
110
- Version = 'Version',
111
- Uptime = 'Uptime',
112
- Memory = 'Memory',
113
- CPU = 'CPU',
114
- LoadAverage = 'LoadAverage',
115
- }
@@ -8,7 +8,8 @@ import {TVDiskStateInfo} from './vdisk';
8
8
  */
9
9
  export interface TStorageInfo {
10
10
  Overall?: EFlag;
11
- StoragePools?: TStoragePoolInfo[];
11
+ StoragePools?: TStoragePoolInfo[]; // v1
12
+ StorageGroups?: TStorageGroupInfoV2[]; // v2
12
13
  /** uint64 */
13
14
  TotalGroups?: string;
14
15
  /** uint64 */
@@ -19,7 +20,7 @@ interface TStoragePoolInfo {
19
20
  Overall?: EFlag;
20
21
  Name?: string;
21
22
  Kind?: string;
22
- Groups?: (TBSGroupStateInfo & THiveStorageGroupStats)[];
23
+ Groups?: TStorageGroupInfo[];
23
24
  /** uint64 */
24
25
  AcquiredUnits?: string;
25
26
  AcquiredIOPS?: number;
@@ -34,7 +35,29 @@ interface TStoragePoolInfo {
34
35
  MaximumSize?: string;
35
36
  }
36
37
 
37
- export interface TBSGroupStateInfo {
38
+ export interface TStorageGroupInfoV2 extends TStorageGroupInfo {
39
+ PoolName?: string;
40
+ Kind?: string;
41
+
42
+ /** uint64 */
43
+ Degraded?: string;
44
+
45
+ /** uint64 */
46
+ Used: string;
47
+ /** uint64 */
48
+ Limit: string;
49
+ /** uint64 */
50
+ Read: string;
51
+ /** uint64 */
52
+ Write: string;
53
+
54
+ /** uint64 */
55
+ Usage?: string;
56
+ }
57
+
58
+ export type TStorageGroupInfo = TBSGroupStateInfo & THiveStorageGroupStats;
59
+
60
+ interface TBSGroupStateInfo {
38
61
  GroupID?: number;
39
62
  ErasureSpecies?: string;
40
63
  VDisks?: TVDiskStateInfo[];
@@ -57,7 +80,7 @@ export interface TBSGroupStateInfo {
57
80
  Encryption?: boolean;
58
81
  }
59
82
 
60
- export interface THiveStorageGroupStats {
83
+ interface THiveStorageGroupStats {
61
84
  GroupID?: number;
62
85
  /** uint64 */
63
86
  AcquiredUnits?: string;
@@ -76,3 +99,8 @@ export interface THiveStorageGroupStats {
76
99
  /** uint64 */
77
100
  AvailableSize?: string;
78
101
  }
102
+
103
+ export enum EVersion {
104
+ v1 = 'v1',
105
+ v2 = 'v2', // only this versions works with sorting
106
+ }
@@ -37,6 +37,7 @@ interface Window {
37
37
  custom_backend?: string;
38
38
 
39
39
  __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof import('redux').compose;
40
+ store?: import('redux').Store;
40
41
 
41
42
  userSettings?: Record<string, string | undefined>;
42
43
  systemSettings?: Record<string, string | undefined>;
@@ -119,3 +119,6 @@ export const CLUSTER_INFO_HIDDEN_KEY = 'clusterInfoHidden';
119
119
 
120
120
  // Remain "tab" in key name for backward compatibility
121
121
  export const TENANT_INITIAL_PAGE_KEY = 'saved_tenant_initial_tab';
122
+
123
+ // Send filters and sort params to backend for Nodes and Storage tables
124
+ export const USE_BACKEND_PARAMS_FOR_TABLES_KEY = 'useBackendParamsForTables';
@@ -0,0 +1,23 @@
1
+ import {escapeRegExp} from 'lodash';
2
+
3
+ import type {OrderType} from '@gravity-ui/react-data-table';
4
+ import {DESCENDING} from '@gravity-ui/react-data-table/build/esm/lib/constants';
5
+
6
+ export const prepareSortValue = (
7
+ sortValue: string | undefined,
8
+ sortOrder: OrderType = DESCENDING,
9
+ ) => {
10
+ if (!sortValue) {
11
+ return '';
12
+ }
13
+
14
+ if (sortOrder === DESCENDING) {
15
+ return '-' + sortValue;
16
+ }
17
+
18
+ return sortValue;
19
+ };
20
+
21
+ export const prepareSearchValue = (searchValue = '') => {
22
+ return new RegExp(escapeRegExp(searchValue), 'i');
23
+ };
@@ -2,3 +2,7 @@ export * from './useAutofetcher';
2
2
  export * from './useTypedSelector';
3
3
  export * from './useSetting';
4
4
  export * from './useQueryModes';
5
+ export * from './useTableSort';
6
+
7
+ export * from './useNodesRequestParams';
8
+ export * from './useStorageRequestParams';
@@ -0,0 +1,46 @@
1
+ import {useMemo} from 'react';
2
+
3
+ import type {NodesGeneralRequestParams} from '../../store/reducers/nodes/types';
4
+ import type {ProblemFilterValue} from '../../store/reducers/settings/types';
5
+ import {ProblemFilterValues} from '../../store/reducers/settings/settings';
6
+
7
+ import {HOUR_IN_SECONDS, USE_BACKEND_PARAMS_FOR_TABLES_KEY} from '../constants';
8
+ import {NodesUptimeFilterValues} from '../nodes';
9
+ import {useSetting} from './useSetting';
10
+
11
+ interface NodesRawRequestParams
12
+ extends Omit<NodesGeneralRequestParams, 'problems_only' | 'uptime'> {
13
+ problemFilter?: ProblemFilterValue;
14
+ nodesUptimeFilter?: NodesUptimeFilterValues;
15
+ }
16
+
17
+ export const useNodesRequestParams = ({
18
+ filter,
19
+ problemFilter,
20
+ nodesUptimeFilter,
21
+ sortOrder,
22
+ sortValue,
23
+ }: NodesRawRequestParams) => {
24
+ const [useBackendParamsForTables] = useSetting<boolean>(USE_BACKEND_PARAMS_FOR_TABLES_KEY);
25
+
26
+ // If backend params are enabled, update params value to use them in fetch request
27
+ // Otherwise no params will be updated, no hooks that depend on requestParams will be triggered
28
+ return useMemo(() => {
29
+ if (useBackendParamsForTables) {
30
+ const problemsOnly = problemFilter === ProblemFilterValues.PROBLEMS;
31
+ const uptime =
32
+ nodesUptimeFilter === NodesUptimeFilterValues.SmallUptime
33
+ ? HOUR_IN_SECONDS
34
+ : undefined;
35
+
36
+ return {
37
+ filter,
38
+ problems_only: problemsOnly,
39
+ uptime,
40
+ sortOrder,
41
+ sortValue,
42
+ };
43
+ }
44
+ return undefined;
45
+ }, [useBackendParamsForTables, filter, problemFilter, nodesUptimeFilter, sortOrder, sortValue]);
46
+ };
@@ -0,0 +1,28 @@
1
+ import {useMemo} from 'react';
2
+
3
+ import type {StorageSortAndFilterParams} from '../../store/reducers/storage/types';
4
+ import {EVersion} from '../../types/api/storage';
5
+ import {USE_BACKEND_PARAMS_FOR_TABLES_KEY} from '../constants';
6
+ import {useSetting} from './useSetting';
7
+
8
+ export const useStorageRequestParams = ({
9
+ filter,
10
+ sortOrder,
11
+ sortValue,
12
+ }: StorageSortAndFilterParams) => {
13
+ const [useBackendParamsForTables] = useSetting<boolean>(USE_BACKEND_PARAMS_FOR_TABLES_KEY);
14
+
15
+ // If backend params are enabled, update params value to use them in fetch request
16
+ // Otherwise no params will be updated, no hooks that depend on requestParams will be triggered
17
+ return useMemo(() => {
18
+ if (useBackendParamsForTables) {
19
+ return {
20
+ version: EVersion.v2,
21
+ filter,
22
+ sortOrder,
23
+ sortValue,
24
+ };
25
+ }
26
+ return undefined;
27
+ }, [useBackendParamsForTables, filter, sortOrder, sortValue]);
28
+ };
@@ -0,0 +1,37 @@
1
+ import {useMemo} from 'react';
2
+
3
+ import {OrderType, SortOrder} from '@gravity-ui/react-data-table';
4
+ import {DESCENDING} from '@gravity-ui/react-data-table/build/esm/lib/constants';
5
+
6
+ interface SortParams {
7
+ sortValue: string | undefined;
8
+ sortOrder: OrderType | undefined;
9
+ }
10
+
11
+ export type HandleSort = (rawValue: SortOrder | SortOrder[] | undefined) => void;
12
+
13
+ export const useTableSort = (
14
+ {sortValue, sortOrder = DESCENDING}: SortParams,
15
+ onSort: (params: SortParams) => void,
16
+ ): [SortOrder | undefined, HandleSort] => {
17
+ const sort: SortOrder | undefined = useMemo(() => {
18
+ if (!sortValue) {
19
+ return undefined;
20
+ }
21
+
22
+ return {
23
+ columnId: sortValue,
24
+ order: sortOrder,
25
+ };
26
+ }, [sortValue, sortOrder]);
27
+
28
+ const handleSort: HandleSort = (rawValue) => {
29
+ const value = Array.isArray(rawValue) ? rawValue[0] : rawValue;
30
+ onSort({
31
+ sortValue: value?.columnId,
32
+ sortOrder: value?.order,
33
+ });
34
+ };
35
+
36
+ return [sort, handleSort];
37
+ };
@@ -2,6 +2,7 @@ import type {TSystemStateInfo} from '../types/api/nodes';
2
2
  import type {TNodeInfo} from '../types/api/nodesList';
3
3
  import type {NodesPreparedEntity} from '../store/reducers/nodes/types';
4
4
  import type {NodesMap} from '../types/store/nodesList';
5
+ import type {ValueOf} from '../types/common';
5
6
  import {EFlag} from '../types/api/enums';
6
7
 
7
8
  export enum NodesUptimeFilterValues {
@@ -31,3 +32,27 @@ export const prepareNodesMap = (nodesList?: TNodeInfo[]) => {
31
32
  return nodesMap;
32
33
  }, new Map());
33
34
  };
35
+
36
+ /**
37
+ * Values to sort /compute v2 and /nodes responses
38
+ *
39
+ * For actual values go to:\
40
+ * /nodes: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/json_nodes.h\
41
+ * /compute: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/json_compute.h
42
+ */
43
+ export const NODES_SORT_VALUES = {
44
+ NodeId: 'NodeId',
45
+ Host: 'Host',
46
+ DC: 'DC',
47
+ Rack: 'Rack',
48
+ Version: 'Version',
49
+ Uptime: 'Uptime',
50
+ Memory: 'Memory',
51
+ CPU: 'CPU',
52
+ LoadAverage: 'LoadAverage',
53
+ } as const;
54
+
55
+ export type NodesSortValue = ValueOf<typeof NODES_SORT_VALUES>;
56
+
57
+ export const isSortableNodesProperty = (value: string): value is NodesSortValue =>
58
+ Object.values(NODES_SORT_VALUES).includes(value as NodesSortValue);