ydb-embedded-ui 4.13.0 → 4.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);