ydb-embedded-ui 4.10.0 → 4.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/components/InfoViewer/formatters/schema.ts +3 -1
  3. package/dist/components/QueryResultTable/Cell/Cell.tsx +8 -8
  4. package/dist/components/QueryResultTable/i18n/en.json +1 -1
  5. package/dist/components/QueryResultTable/i18n/ru.json +1 -1
  6. package/dist/components/ShortyString/ShortyString.tsx +3 -6
  7. package/dist/components/ShortyString/i18n/en.json +8 -8
  8. package/dist/components/ShortyString/i18n/ru.json +8 -8
  9. package/dist/components/SpeedMultiMeter/i18n/index.ts +0 -2
  10. package/dist/components/Stack/Stack.tsx +16 -16
  11. package/dist/components/TableSkeleton/TableSkeleton.tsx +3 -3
  12. package/dist/components/TableWithControlsLayout/TableWithControlsLayout.scss +32 -0
  13. package/dist/components/TableWithControlsLayout/TableWithControlsLayout.tsx +43 -0
  14. package/dist/containers/AsideNavigation/AsideNavigation.tsx +2 -2
  15. package/dist/containers/Cluster/Cluster.scss +4 -5
  16. package/dist/containers/Cluster/Cluster.tsx +3 -22
  17. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.scss +4 -0
  18. package/dist/containers/Cluster/ClusterInfo/ClusterInfo.tsx +14 -3
  19. package/dist/containers/Cluster/ClusterInfoSkeleton/ClusterInfoSkeleton.tsx +1 -1
  20. package/dist/containers/Cluster/utils.tsx +0 -11
  21. package/dist/containers/Header/Header.scss +1 -5
  22. package/dist/containers/Header/Header.tsx +2 -2
  23. package/dist/containers/Header/breadcrumbs.ts +2 -1
  24. package/dist/containers/Heatmap/Heatmap.tsx +4 -3
  25. package/dist/containers/Node/NodeStructure/PDiskTitleBadge.tsx +2 -8
  26. package/dist/containers/Nodes/Nodes.scss +1 -24
  27. package/dist/containers/Nodes/Nodes.tsx +29 -39
  28. package/dist/containers/Storage/EmptyFilter/i18n/en.json +2 -2
  29. package/dist/containers/Storage/EmptyFilter/i18n/ru.json +2 -2
  30. package/dist/containers/Storage/Storage.scss +1 -14
  31. package/dist/containers/Storage/Storage.tsx +15 -18
  32. package/dist/containers/Storage/StorageGroups/i18n/en.json +5 -5
  33. package/dist/containers/Storage/StorageGroups/i18n/ru.json +5 -5
  34. package/dist/containers/Storage/StorageTypeFilter/StorageTypeFilter.tsx +3 -1
  35. package/dist/containers/Storage/{StorageVisibleEntityFilter/StorageVisibleEntityFilter.tsx → StorageVisibleEntitiesFilter/StorageVisibleEntitiesFilter.tsx} +4 -2
  36. package/dist/containers/Storage/UsageFilter/i18n/en.json +3 -8
  37. package/dist/containers/Storage/UsageFilter/i18n/ru.json +3 -8
  38. package/dist/containers/Tablet/Tablet.tsx +2 -2
  39. package/dist/containers/Tenant/Acl/Acl.scss +1 -9
  40. package/dist/containers/Tenant/Acl/Acl.tsx +137 -0
  41. package/dist/containers/Tenant/Diagnostics/Describe/Describe.tsx +2 -2
  42. package/dist/containers/Tenant/Diagnostics/Diagnostics.scss +6 -2
  43. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +6 -0
  44. package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +3 -3
  45. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +2 -0
  46. package/dist/containers/Tenant/Diagnostics/Overview/utils/prepareTopicSchemaInfo.ts +2 -3
  47. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.scss +3 -18
  48. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +95 -88
  49. package/dist/containers/Tenant/Query/Issues/Issues.tsx +27 -23
  50. package/dist/containers/Tenant/Query/Issues/models.ts +0 -11
  51. package/dist/containers/Tenant/Query/Preview/Preview.tsx +3 -3
  52. package/dist/containers/Tenant/Query/i18n/en.json +1 -1
  53. package/dist/containers/Tenant/Query/i18n/ru.json +1 -1
  54. package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +2 -2
  55. package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx +99 -0
  56. package/dist/containers/Tenant/Tenant.tsx +1 -5
  57. package/dist/containers/Tenant/TenantPages.tsx +9 -14
  58. package/dist/containers/Tenant/i18n/en.json +11 -0
  59. package/dist/containers/Tenant/i18n/index.ts +11 -0
  60. package/dist/containers/Tenant/i18n/ru.json +11 -0
  61. package/dist/containers/Tenant/utils/schema.ts +24 -0
  62. package/dist/containers/Tenant/utils/schemaActions.ts +28 -24
  63. package/dist/containers/Tenants/Tenants.scss +1 -13
  64. package/dist/containers/Tenants/Tenants.tsx +18 -28
  65. package/dist/services/api.ts +6 -7
  66. package/dist/store/index.js +1 -1
  67. package/dist/store/reducers/nodes/nodes.ts +12 -111
  68. package/dist/store/reducers/nodes/selectors.ts +74 -0
  69. package/dist/store/reducers/nodes/types.ts +22 -3
  70. package/dist/store/reducers/nodes/utils.ts +59 -0
  71. package/dist/store/reducers/preview.ts +6 -4
  72. package/dist/store/reducers/schemaAcl/schemaAcl.ts +17 -0
  73. package/dist/store/reducers/schemaAcl/types.ts +9 -7
  74. package/dist/store/reducers/storage/selectors.ts +1 -1
  75. package/dist/store/reducers/tenant/constants.ts +6 -0
  76. package/dist/store/reducers/tenant/tenant.ts +15 -0
  77. package/dist/store/reducers/tenant/types.ts +18 -3
  78. package/dist/store/state-url-mapping.js +3 -0
  79. package/dist/types/api/cluster.ts +1 -1
  80. package/dist/types/api/compute.ts +27 -2
  81. package/dist/types/api/error.ts +2 -2
  82. package/dist/types/api/netInfo.ts +3 -3
  83. package/dist/types/api/nodes.ts +13 -1
  84. package/dist/types/api/query.ts +1 -1
  85. package/dist/types/api/schema/cdcStream.ts +32 -0
  86. package/dist/types/api/schema/columnEntity.ts +138 -0
  87. package/dist/types/api/schema/externalDataSource.ts +24 -0
  88. package/dist/types/api/schema/externalTable.ts +14 -0
  89. package/dist/types/api/schema/index.ts +10 -0
  90. package/dist/types/api/schema/persQueueGroup.ts +191 -0
  91. package/dist/types/api/schema/schema.ts +302 -0
  92. package/dist/types/api/schema/shared.ts +42 -0
  93. package/dist/types/api/schema/table.ts +616 -0
  94. package/dist/types/api/schema/tableIndex.ts +33 -0
  95. package/dist/types/api/storage.ts +1 -1
  96. package/dist/types/assets.d.ts +1 -2
  97. package/dist/types/store/executeQuery.ts +2 -3
  98. package/dist/types/store/executeTopQueries.ts +8 -5
  99. package/dist/types/store/explainQuery.ts +4 -4
  100. package/dist/types/store/query.ts +4 -3
  101. package/dist/types/store/shardsWorkload.ts +8 -5
  102. package/dist/utils/constants.ts +4 -1
  103. package/dist/utils/error.ts +2 -3
  104. package/dist/utils/query.ts +3 -9
  105. package/dist/utils/tests/providers.tsx +6 -9
  106. package/package.json +6 -2
  107. package/dist/assets/icons/versions.svg +0 -3
  108. package/dist/containers/Tenant/Acl/Acl.js +0 -153
  109. package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.js +0 -94
  110. package/dist/types/api/schema.ts +0 -1326
@@ -1,25 +1,18 @@
1
1
  import type {Reducer} from 'redux';
2
- import {createSelector, Selector} from 'reselect';
3
- import {escapeRegExp} from 'lodash/fp';
4
2
 
5
3
  import '../../../services/api';
6
- import {HOUR_IN_SECONDS} from '../../../utils/constants';
7
- import {calcUptime, calcUptimeInSeconds} from '../../../utils';
8
4
  import {NodesUptimeFilterValues} from '../../../utils/nodes';
9
- import {EFlag} from '../../../types/api/enums';
5
+ import {EVersion} from '../../../types/api/compute';
10
6
 
11
- import type {ProblemFilterValue} from '../settings/types';
12
7
  import {createRequestActionTypes, createApiRequest} from '../../utils';
13
- import {ProblemFilterValues} from '../settings/settings';
14
8
 
15
9
  import type {
10
+ ComputeApiRequestParams,
16
11
  NodesAction,
17
12
  NodesApiRequestParams,
18
- NodesHandledResponse,
19
- NodesPreparedEntity,
20
- NodesStateSlice,
21
13
  NodesState,
22
14
  } from './types';
15
+ import {prepareComputeNodesData, prepareNodesData} from './utils';
23
16
 
24
17
  export const FETCH_NODES = createRequestActionTypes('nodes', 'FETCH_NODES');
25
18
 
@@ -93,60 +86,22 @@ const nodes: Reducer<NodesState, NodesAction> = (state = initialState, action) =
93
86
  }
94
87
  };
95
88
 
96
- export function getNodes({tenant, visibleEntities, type = 'any'}: NodesApiRequestParams) {
89
+ export function getNodes({type = 'any', ...params}: NodesApiRequestParams) {
97
90
  return createApiRequest({
98
- request: window.api.getNodes({tenant, visibleEntities, type}),
91
+ request: window.api.getNodes({
92
+ type,
93
+ ...params,
94
+ }),
99
95
  actions: FETCH_NODES,
100
- dataHandler: (data): NodesHandledResponse => {
101
- const rawNodes = data.Nodes || [];
102
-
103
- const preparedNodes = rawNodes.map((node) => {
104
- return {
105
- ...node?.SystemState,
106
- Tablets: node?.Tablets,
107
- NodeId: node?.NodeId,
108
- Uptime: calcUptime(node?.SystemState?.StartTime),
109
- TenantName: node?.SystemState?.Tenants?.[0],
110
- };
111
- });
112
-
113
- return {
114
- Nodes: preparedNodes,
115
- TotalNodes: Number(data.TotalNodes) || preparedNodes.length,
116
- };
117
- },
96
+ dataHandler: prepareNodesData,
118
97
  });
119
98
  }
120
99
 
121
- export function getComputeNodes(path: string) {
100
+ export function getComputeNodes({version = EVersion.v2, ...params}: ComputeApiRequestParams) {
122
101
  return createApiRequest({
123
- request: window.api.getCompute(path),
102
+ request: window.api.getCompute({version, ...params}),
124
103
  actions: FETCH_NODES,
125
- dataHandler: (data): NodesHandledResponse => {
126
- const preparedNodes: NodesPreparedEntity[] = [];
127
-
128
- if (data.Tenants) {
129
- for (const tenant of data.Tenants) {
130
- if (tenant && tenant.Nodes) {
131
- const tenantNodes = tenant.Nodes.map((node) => {
132
- return {
133
- ...node,
134
- TenantName: tenant.Name,
135
- SystemState: node?.Overall,
136
- Uptime: calcUptime(node?.StartTime),
137
- };
138
- });
139
-
140
- preparedNodes.push(...tenantNodes);
141
- }
142
- }
143
- }
144
-
145
- return {
146
- Nodes: preparedNodes,
147
- TotalNodes: preparedNodes.length,
148
- };
149
- },
104
+ dataHandler: prepareComputeNodesData,
150
105
  });
151
106
  }
152
107
 
@@ -175,58 +130,4 @@ export const setSearchValue = (value: string) => {
175
130
  } as const;
176
131
  };
177
132
 
178
- const getNodesUptimeFilter = (state: NodesStateSlice) => state.nodes.nodesUptimeFilter;
179
- const getSearchValue = (state: NodesStateSlice) => state.nodes.searchValue;
180
- const getNodesList = (state: NodesStateSlice) => state.nodes.data;
181
-
182
- const filterNodesByProblemsStatus = (
183
- nodesList: NodesPreparedEntity[] = [],
184
- problemFilter: ProblemFilterValue,
185
- ) => {
186
- if (problemFilter === ProblemFilterValues.ALL) {
187
- return nodesList;
188
- }
189
-
190
- return nodesList.filter(({SystemState}) => {
191
- return SystemState && SystemState !== EFlag.Green;
192
- });
193
- };
194
-
195
- export const filterNodesByUptime = <T extends {StartTime?: string}>(
196
- nodesList: T[] = [],
197
- nodesUptimeFilter: NodesUptimeFilterValues,
198
- ) => {
199
- if (nodesUptimeFilter === NodesUptimeFilterValues.All) {
200
- return nodesList;
201
- }
202
- return nodesList.filter(({StartTime}) => {
203
- return !StartTime || calcUptimeInSeconds(StartTime) < HOUR_IN_SECONDS;
204
- });
205
- };
206
-
207
- const filterNodesBySearchValue = (nodesList: NodesPreparedEntity[] = [], searchValue: string) => {
208
- if (!searchValue) {
209
- return nodesList;
210
- }
211
- const re = new RegExp(escapeRegExp(searchValue), 'i');
212
-
213
- return nodesList.filter((node) => {
214
- return node.Host ? re.test(node.Host) || re.test(String(node.NodeId)) : true;
215
- });
216
- };
217
-
218
- export const getFilteredPreparedNodesList: Selector<
219
- NodesStateSlice,
220
- NodesPreparedEntity[] | undefined
221
- > = createSelector(
222
- [getNodesList, getNodesUptimeFilter, getSearchValue, (state) => state.settings.problemFilter],
223
- (nodesList, uptimeFilter, searchValue, problemFilter) => {
224
- let result = filterNodesByUptime(nodesList, uptimeFilter);
225
- result = filterNodesByProblemsStatus(result, problemFilter);
226
- result = filterNodesBySearchValue(result, searchValue);
227
-
228
- return result;
229
- },
230
- );
231
-
232
133
  export default nodes;
@@ -0,0 +1,74 @@
1
+ import {Selector, createSelector} from 'reselect';
2
+ import {escapeRegExp} from 'lodash';
3
+
4
+ import {EFlag} from '../../../types/api/enums';
5
+ import {calcUptimeInSeconds} from '../../../utils';
6
+ import {HOUR_IN_SECONDS} from '../../../utils/constants';
7
+ import {NodesUptimeFilterValues} from '../../../utils/nodes';
8
+
9
+ import type {ProblemFilterValue} from '../settings/types';
10
+ import type {NodesPreparedEntity, NodesStateSlice} from './types';
11
+ import {ProblemFilterValues} from '../settings/settings';
12
+
13
+ // ==== Filters ====
14
+
15
+ const filterNodesByProblemsStatus = (
16
+ nodesList: NodesPreparedEntity[] = [],
17
+ problemFilter: ProblemFilterValue,
18
+ ) => {
19
+ if (problemFilter === ProblemFilterValues.ALL) {
20
+ return nodesList;
21
+ }
22
+
23
+ return nodesList.filter(({SystemState}) => {
24
+ return SystemState && SystemState !== EFlag.Green;
25
+ });
26
+ };
27
+
28
+ export const filterNodesByUptime = <T extends {StartTime?: string}>(
29
+ nodesList: T[] = [],
30
+ nodesUptimeFilter: NodesUptimeFilterValues,
31
+ ) => {
32
+ if (nodesUptimeFilter === NodesUptimeFilterValues.All) {
33
+ return nodesList;
34
+ }
35
+ return nodesList.filter(({StartTime}) => {
36
+ return !StartTime || calcUptimeInSeconds(StartTime) < HOUR_IN_SECONDS;
37
+ });
38
+ };
39
+
40
+ const filterNodesBySearchValue = (nodesList: NodesPreparedEntity[] = [], searchValue: string) => {
41
+ if (!searchValue) {
42
+ return nodesList;
43
+ }
44
+ const re = new RegExp(escapeRegExp(searchValue), 'i');
45
+
46
+ return nodesList.filter((node) => {
47
+ return node.Host ? re.test(node.Host) || re.test(String(node.NodeId)) : true;
48
+ });
49
+ };
50
+
51
+ // ==== Simple selectors ====
52
+
53
+ const selectNodesUptimeFilter = (state: NodesStateSlice) => state.nodes.nodesUptimeFilter;
54
+ const selectSearchValue = (state: NodesStateSlice) => state.nodes.searchValue;
55
+ const selectNodesList = (state: NodesStateSlice) => state.nodes.data;
56
+
57
+ // ==== Complex selectors ====
58
+
59
+ export const selectFilteredNodes: Selector<NodesStateSlice, NodesPreparedEntity[] | undefined> =
60
+ createSelector(
61
+ [
62
+ selectNodesList,
63
+ selectNodesUptimeFilter,
64
+ selectSearchValue,
65
+ (state) => state.settings.problemFilter,
66
+ ],
67
+ (nodesList, uptimeFilter, searchValue, problemFilter) => {
68
+ let result = filterNodesByUptime(nodesList, uptimeFilter);
69
+ result = filterNodesByProblemsStatus(result, problemFilter);
70
+ result = filterNodesBySearchValue(result, searchValue);
71
+
72
+ return result;
73
+ },
74
+ );
@@ -1,6 +1,9 @@
1
1
  import type {IResponseError} from '../../../types/api/error';
2
2
  import type {TEndpoint, TPoolStats} from '../../../types/api/nodes';
3
- import type {TTabletStateInfo as TComputeTabletStateInfo} from '../../../types/api/compute';
3
+ import type {
4
+ EVersion,
5
+ TTabletStateInfo as TComputeTabletStateInfo,
6
+ } from '../../../types/api/compute';
4
7
  import type {TTabletStateInfo as TFullTabletStateInfo} from '../../../types/api/tablet';
5
8
  import type {EFlag} from '../../../types/api/enums';
6
9
  import type {ApiRequestAction} from '../../utils';
@@ -46,17 +49,33 @@ export interface NodesState {
46
49
 
47
50
  export type NodeType = 'static' | 'dynamic' | 'any';
48
51
 
49
- export interface NodesApiRequestParams {
52
+ interface RequestParams {
53
+ filter?: string; // NodeId or Host
54
+ uptime?: number; // return nodes with less uptime in seconds
55
+ problems_only?: boolean; // return nodes with SystemState !== EFlag.Green
56
+ sort?: string; // Sort by one of ESort params (may differ for /nodes and /compute)
57
+
58
+ offser?: number;
59
+ limit?: number;
60
+ }
61
+
62
+ export interface NodesApiRequestParams extends RequestParams {
50
63
  tenant?: string;
51
64
  type?: NodeType;
52
- visibleEntities?: VisibleEntities;
65
+ visibleEntities?: VisibleEntities; // "with" param
53
66
  storage?: boolean;
54
67
  tablets?: boolean;
55
68
  }
56
69
 
70
+ export interface ComputeApiRequestParams extends RequestParams {
71
+ path: string;
72
+ version?: EVersion; // only v2 works with filters
73
+ }
74
+
57
75
  export interface NodesHandledResponse {
58
76
  Nodes?: NodesPreparedEntity[];
59
77
  TotalNodes: number;
78
+ FoundNodes?: number;
60
79
  }
61
80
 
62
81
  type NodesApiRequestAction = ApiRequestAction<
@@ -0,0 +1,59 @@
1
+ import type {TComputeInfo, TComputeNodeInfo} from '../../../types/api/compute';
2
+ import type {TNodesInfo} from '../../../types/api/nodes';
3
+ import {calcUptime} from '../../../utils';
4
+
5
+ import type {NodesHandledResponse, NodesPreparedEntity} from './types';
6
+
7
+ const prepareComputeNode = (node: TComputeNodeInfo, tenantName?: string) => {
8
+ return {
9
+ ...node,
10
+ // v2 response has tenant name, v1 - doesn't
11
+ TenantName: node.Tenant ?? tenantName,
12
+ SystemState: node?.Overall,
13
+ Uptime: calcUptime(node?.StartTime),
14
+ };
15
+ };
16
+
17
+ export const prepareComputeNodesData = (data: TComputeInfo): NodesHandledResponse => {
18
+ const preparedNodes: NodesPreparedEntity[] = [];
19
+
20
+ // First try to parse v2 response in case backend supports it
21
+ // Else parse v1 response
22
+ if (data.Nodes) {
23
+ data.Nodes.forEach((node) => {
24
+ preparedNodes.push(prepareComputeNode(node));
25
+ });
26
+ } else if (data.Tenants) {
27
+ for (const tenant of data.Tenants) {
28
+ tenant.Nodes?.forEach((node) => {
29
+ preparedNodes.push(prepareComputeNode(node, tenant.Name));
30
+ });
31
+ }
32
+ }
33
+
34
+ return {
35
+ Nodes: preparedNodes,
36
+ TotalNodes: Number(data.TotalNodes) || preparedNodes.length,
37
+ FoundNodes: Number(data.FoundNodes),
38
+ };
39
+ };
40
+
41
+ export const prepareNodesData = (data: TNodesInfo): NodesHandledResponse => {
42
+ const rawNodes = data.Nodes || [];
43
+
44
+ const preparedNodes = rawNodes.map((node) => {
45
+ return {
46
+ ...node.SystemState,
47
+ Tablets: node.Tablets,
48
+ NodeId: node.NodeId,
49
+ Uptime: calcUptime(node.SystemState?.StartTime),
50
+ TenantName: node.SystemState?.Tenants?.[0],
51
+ };
52
+ });
53
+
54
+ return {
55
+ Nodes: preparedNodes,
56
+ TotalNodes: Number(data.TotalNodes) || preparedNodes.length,
57
+ FoundNodes: Number(data.FoundNodes),
58
+ };
59
+ };
@@ -1,7 +1,7 @@
1
1
  import '../../services/api';
2
2
 
3
- import type {ErrorResponse, ExecuteActions} from '../../types/api/query';
4
- import type {IQueryResult} from '../../types/store/query';
3
+ import type {ExecuteActions} from '../../types/api/query';
4
+ import type {IQueryResult, QueryErrorResponse} from '../../types/store/query';
5
5
  import {parseQueryAPIExecuteResponse} from '../../utils/query';
6
6
 
7
7
  import {createRequestActionTypes, createApiRequest, ApiRequestAction} from '../utils';
@@ -16,7 +16,9 @@ const initialState = {
16
16
 
17
17
  const preview = (
18
18
  state = initialState,
19
- action: ApiRequestAction<typeof SEND_QUERY, IQueryResult, ErrorResponse> | ReturnType<typeof setQueryOptions>,
19
+ action:
20
+ | ApiRequestAction<typeof SEND_QUERY, IQueryResult, QueryErrorResponse>
21
+ | ReturnType<typeof setQueryOptions>,
20
22
  ) => {
21
23
  switch (action.type) {
22
24
  case SEND_QUERY.REQUEST: {
@@ -57,7 +59,7 @@ interface SendQueryParams {
57
59
  query?: string;
58
60
  database?: string;
59
61
  action?: ExecuteActions;
60
- };
62
+ }
61
63
 
62
64
  export const sendQuery = ({query, database, action}: SendQueryParams) => {
63
65
  return createApiRequest({
@@ -6,6 +6,7 @@ import {createRequestActionTypes, createApiRequest} from '../../utils';
6
6
  import type {SchemaAclAction, SchemaAclState} from './types';
7
7
 
8
8
  export const FETCH_SCHEMA_ACL = createRequestActionTypes('schemaAcl', 'FETCH_SCHEMA_ACL');
9
+ const SET_ACL_WAS_NOT_LOADED = 'schemaAcl/SET_DATA_WAS_NOT_LOADED';
9
10
 
10
11
  const initialState = {
11
12
  loading: false,
@@ -34,12 +35,22 @@ const schemaAcl: Reducer<SchemaAclState, SchemaAclAction> = (state = initialStat
34
35
  };
35
36
  }
36
37
  case FETCH_SCHEMA_ACL.FAILURE: {
38
+ if (action.error?.isCancelled) {
39
+ return state;
40
+ }
41
+
37
42
  return {
38
43
  ...state,
39
44
  error: action.error,
40
45
  loading: false,
41
46
  };
42
47
  }
48
+ case SET_ACL_WAS_NOT_LOADED: {
49
+ return {
50
+ ...state,
51
+ wasLoaded: false,
52
+ };
53
+ }
43
54
  default:
44
55
  return state;
45
56
  }
@@ -52,4 +63,10 @@ export function getSchemaAcl({path}: {path: string}) {
52
63
  });
53
64
  }
54
65
 
66
+ export const setAclWasNotLoaded = () => {
67
+ return {
68
+ type: SET_ACL_WAS_NOT_LOADED,
69
+ } as const;
70
+ };
71
+
55
72
  export default schemaAcl;
@@ -2,14 +2,16 @@ import type {TACE, TMetaInfo} from '../../../types/api/acl';
2
2
  import type {IResponseError} from '../../../types/api/error';
3
3
  import type {ApiRequestAction} from '../../utils';
4
4
 
5
- import {FETCH_SCHEMA_ACL} from './schemaAcl';
5
+ import {FETCH_SCHEMA_ACL, setAclWasNotLoaded} from './schemaAcl';
6
6
 
7
7
  export interface SchemaAclState {
8
- loading: boolean
9
- wasLoaded: boolean
10
- acl?: TACE[]
11
- owner?: string
12
- error?: IResponseError
8
+ loading: boolean;
9
+ wasLoaded: boolean;
10
+ acl?: TACE[];
11
+ owner?: string;
12
+ error?: IResponseError;
13
13
  }
14
14
 
15
- export type SchemaAclAction = ApiRequestAction<typeof FETCH_SCHEMA_ACL, TMetaInfo, IResponseError>;
15
+ export type SchemaAclAction =
16
+ | ApiRequestAction<typeof FETCH_SCHEMA_ACL, TMetaInfo, IResponseError>
17
+ | ReturnType<typeof setAclWasNotLoaded>;
@@ -15,7 +15,7 @@ import type {
15
15
  StorageStateSlice,
16
16
  UsageFilter,
17
17
  } from './types';
18
- import {filterNodesByUptime} from '../nodes/nodes';
18
+ import {filterNodesByUptime} from '../nodes/selectors';
19
19
 
20
20
  // ==== Prepare data ====
21
21
  const FLAGS_POINTS = {
@@ -25,3 +25,9 @@ export const TENANT_DIAGNOSTICS_TABS_IDS = {
25
25
  consumers: 'consumers',
26
26
  partitions: 'partitions',
27
27
  } as const;
28
+
29
+ export const TENANT_SUMMARY_TABS_IDS = {
30
+ overview: 'overview',
31
+ acl: 'acl',
32
+ schema: 'schema',
33
+ } as const;
@@ -7,6 +7,7 @@ import type {
7
7
  TenantPage,
8
8
  TenantQueryTab,
9
9
  TenantState,
10
+ TenantSummaryTab,
10
11
  } from './types';
11
12
 
12
13
  import '../../../services/api';
@@ -17,6 +18,7 @@ export const FETCH_TENANT = createRequestActionTypes('tenant', 'FETCH_TENANT');
17
18
  const SET_TOP_LEVEL_TAB = 'tenant/SET_TOP_LEVEL_TAB';
18
19
  const SET_QUERY_TAB = 'tenant/SET_QUERY_TAB';
19
20
  const SET_DIAGNOSTICS_TAB = 'tenant/SET_DIAGNOSTICS_TAB';
21
+ const SET_SUMMARY_TAB = 'tenant/SET_SUMMARY_TAB';
20
22
  const CLEAR_TENANT = 'tenant/CLEAR_TENANT';
21
23
 
22
24
  const initialState = {loading: false, wasLoaded: false};
@@ -75,6 +77,12 @@ const tenantReducer: Reducer<TenantState, TenantAction> = (state = initialState,
75
77
  diagnosticsTab: action.data,
76
78
  };
77
79
  }
80
+ case SET_SUMMARY_TAB: {
81
+ return {
82
+ ...state,
83
+ summaryTab: action.data,
84
+ };
85
+ }
78
86
 
79
87
  default:
80
88
  return state;
@@ -116,4 +124,11 @@ export function setDiagnosticsTab(tab: TenantDiagnosticsTab) {
116
124
  } as const;
117
125
  }
118
126
 
127
+ export function setSummaryTab(tab: TenantSummaryTab) {
128
+ return {
129
+ type: SET_SUMMARY_TAB,
130
+ data: tab,
131
+ } as const;
132
+ }
133
+
119
134
  export default tenantReducer;
@@ -3,13 +3,26 @@ import type {TTenant} from '../../../types/api/tenant';
3
3
  import type {ValueOf} from '../../../types/common';
4
4
  import type {ApiRequestAction} from '../../utils';
5
5
 
6
- import {TENANT_QUERY_TABS_ID, TENANT_DIAGNOSTICS_TABS_IDS, TENANT_PAGES_IDS} from './constants';
7
- import {FETCH_TENANT, clearTenant, setDiagnosticsTab, setQueryTab, setTenantPage} from './tenant';
6
+ import {
7
+ TENANT_QUERY_TABS_ID,
8
+ TENANT_DIAGNOSTICS_TABS_IDS,
9
+ TENANT_PAGES_IDS,
10
+ TENANT_SUMMARY_TABS_IDS,
11
+ } from './constants';
12
+ import {
13
+ FETCH_TENANT,
14
+ clearTenant,
15
+ setDiagnosticsTab,
16
+ setQueryTab,
17
+ setSummaryTab,
18
+ setTenantPage,
19
+ } from './tenant';
8
20
 
9
21
  export type TenantPage = ValueOf<typeof TENANT_PAGES_IDS>;
10
22
 
11
23
  export type TenantQueryTab = ValueOf<typeof TENANT_QUERY_TABS_ID>;
12
24
  export type TenantDiagnosticsTab = ValueOf<typeof TENANT_DIAGNOSTICS_TABS_IDS>;
25
+ export type TenantSummaryTab = ValueOf<typeof TENANT_SUMMARY_TABS_IDS>;
13
26
 
14
27
  export interface TenantState {
15
28
  loading: boolean;
@@ -17,6 +30,7 @@ export interface TenantState {
17
30
  tenantPage?: TenantPage;
18
31
  queryTab?: TenantQueryTab;
19
32
  diagnosticsTab?: TenantDiagnosticsTab;
33
+ summaryTab?: TenantSummaryTab;
20
34
  tenant?: TTenant;
21
35
  error?: IResponseError;
22
36
  }
@@ -26,4 +40,5 @@ export type TenantAction =
26
40
  | ReturnType<typeof clearTenant>
27
41
  | ReturnType<typeof setTenantPage>
28
42
  | ReturnType<typeof setQueryTab>
29
- | ReturnType<typeof setDiagnosticsTab>;
43
+ | ReturnType<typeof setDiagnosticsTab>
44
+ | ReturnType<typeof setSummaryTab>;
@@ -51,6 +51,9 @@ const paramSetup = {
51
51
  diagnosticsTab: {
52
52
  stateKey: 'tenant.diagnosticsTab',
53
53
  },
54
+ summaryTab: {
55
+ stateKey: 'tenant.summaryTab',
56
+ },
54
57
  shardsMode: {
55
58
  stateKey: 'shardsWorkload.filters.mode',
56
59
  },
@@ -31,7 +31,7 @@ export interface TClusterInfo {
31
31
  Tenants?: string;
32
32
  /** uint64 */
33
33
  Tablets?: string;
34
-
34
+
35
35
  Balancer?: string; // additional
36
36
  Solomon?: string; // additional
37
37
  }
@@ -4,13 +4,20 @@ import {TMetrics} from './tenant';
4
4
 
5
5
  /**
6
6
  * endpoint: viewer/json/compute
7
- *
7
+ *
8
8
  * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
9
+ *
10
+ * response has 2 versions, depending on version param in request
9
11
  */
10
12
  export interface TComputeInfo {
11
13
  Overall: EFlag;
12
- Tenants?: TComputeTenantInfo[];
14
+ Tenants?: TComputeTenantInfo[]; // v1
13
15
  Errors?: string[];
16
+ /** uint64 */
17
+ TotalNodes: string;
18
+ /** uint64 */
19
+ FoundNodes: string;
20
+ Nodes?: TComputeNodeInfo[]; // v2
14
21
  }
15
22
 
16
23
  interface TComputeTenantInfo {
@@ -43,6 +50,7 @@ export interface TComputeNodeInfo {
43
50
  MemoryLimit?: string;
44
51
  Metrics: TMetrics;
45
52
  Tablets?: TTabletStateInfo[];
53
+ Tenant?: string; // For v2 response without grouping by tenants
46
54
  }
47
55
 
48
56
  // Tablets in compute nodes
@@ -52,3 +60,20 @@ export interface TTabletStateInfo {
52
60
  State: EFlag;
53
61
  Count: number;
54
62
  }
63
+
64
+ export enum EVersion {
65
+ v1 = 'v1',
66
+ v2 = 'v2', // only this versions works with sorting
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
+ }
@@ -1,5 +1,5 @@
1
- export interface IResponseError {
2
- data?: unknown;
1
+ export interface IResponseError<T = unknown> {
2
+ data?: T;
3
3
  status?: number;
4
4
  statusText?: string;
5
5
  isCancelled?: boolean;
@@ -42,7 +42,7 @@ interface TNetNodePeerInfo {
42
42
  }
43
43
 
44
44
  enum ENodeType {
45
- UnknownNodeType,
46
- Static,
47
- Dynamic,
45
+ UnknownNodeType = 'UnknownNodeType',
46
+ Static = 'Static',
47
+ Dynamic = 'Dynamic',
48
48
  }
@@ -5,7 +5,7 @@ import {TVDiskStateInfo} from './vdisk';
5
5
 
6
6
  /**
7
7
  * endpoint: /viewer/json/nodes
8
- *
8
+ *
9
9
  * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
10
10
  */
11
11
  export interface TNodesInfo {
@@ -101,3 +101,15 @@ 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
+ }
@@ -205,7 +205,7 @@ export type Actions = ExecuteActions | ExplainActions;
205
205
 
206
206
  export interface ErrorResponse {
207
207
  error?: IssueMessage;
208
- issues?: IssueMessage[];
208
+ issues?: IssueMessage[] | null;
209
209
  }
210
210
 
211
211
  // ==== Explain Responses ====