ydb-embedded-ui 4.19.3 → 4.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/components/CellWithPopover/CellWithPopover.scss +13 -0
  3. package/dist/components/CellWithPopover/CellWithPopover.tsx +26 -0
  4. package/dist/components/LinkToSchemaObject/LinkToSchemaObject.tsx +20 -0
  5. package/dist/components/NodeHostWrapper/NodeHostWrapper.scss +0 -2
  6. package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +28 -29
  7. package/dist/components/QueryExecutionStatus/QueryExecutionStatus.tsx +3 -2
  8. package/dist/components/TruncatedQuery/TruncatedQuery.scss +8 -0
  9. package/dist/components/TruncatedQuery/TruncatedQuery.tsx +15 -1
  10. package/dist/components/UsageLabel/UsageLabel.scss +6 -0
  11. package/dist/components/UsageLabel/UsageLabel.tsx +22 -0
  12. package/dist/containers/AsideNavigation/AsideNavigation.tsx +13 -8
  13. package/dist/containers/AsideNavigation/i18n/en.json +13 -0
  14. package/dist/containers/AsideNavigation/i18n/index.ts +11 -0
  15. package/dist/containers/AsideNavigation/i18n/ru.json +13 -0
  16. package/dist/containers/Node/NodeStructure/Pdisk.tsx +74 -68
  17. package/dist/containers/Node/NodeStructure/Vdisk.tsx +9 -33
  18. package/dist/containers/Nodes/Nodes.tsx +10 -2
  19. package/dist/containers/Nodes/getNodesColumns.tsx +207 -123
  20. package/dist/containers/Storage/Storage.tsx +9 -2
  21. package/dist/containers/Storage/StorageGroups/StorageGroups.scss +0 -11
  22. package/dist/containers/Storage/StorageGroups/getStorageGroupsColumns.tsx +11 -11
  23. package/dist/containers/Storage/utils/index.ts +1 -22
  24. package/dist/containers/Tenant/Diagnostics/Describe/Describe.tsx +2 -3
  25. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +0 -1
  26. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +4 -2
  27. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +1 -0
  28. package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckDetails.tsx +8 -1
  29. package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/HealthcheckPreview.tsx +11 -1
  30. package/dist/containers/Tenant/Diagnostics/TenantOverview/Healthcheck/IssuesViewer/IssueTree.tsx +0 -1
  31. package/dist/containers/Tenant/Diagnostics/TenantOverview/MetricsCards/MetricsCards.tsx +3 -0
  32. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TenantCpu.tsx +21 -0
  33. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopNodesByCpu.tsx +53 -0
  34. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopNodesByLoad.tsx +53 -0
  35. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopQueries.tsx +83 -0
  36. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopShards.tsx +53 -0
  37. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/TenantMemory.tsx +9 -0
  38. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantMemory/TopNodesByMemory.tsx +55 -0
  39. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.scss +44 -0
  40. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.tsx +35 -19
  41. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverviewTableLayout.tsx +53 -0
  42. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TenantStorage.tsx +4 -2
  43. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopGroups.tsx +9 -36
  44. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TopTables.tsx +22 -41
  45. package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/en.json +3 -3
  46. package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/ru.json +3 -3
  47. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +0 -2
  48. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +19 -61
  49. package/dist/containers/Tenant/Diagnostics/TopQueries/getTopQueriesColumns.tsx +102 -0
  50. package/dist/containers/Tenant/Diagnostics/TopShards/Filters/Filters.tsx +2 -2
  51. package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +18 -97
  52. package/dist/containers/Tenant/Diagnostics/TopShards/getTopShardsColumns.tsx +138 -0
  53. package/dist/containers/Tenant/Info/ExternalTable/ExternalTable.tsx +2 -4
  54. package/dist/containers/Tenant/Query/ExecuteResult/{ExecuteResult.js → ExecuteResult.tsx} +51 -31
  55. package/dist/containers/Tenant/Query/Issues/Issues.tsx +4 -6
  56. package/dist/containers/Tenant/Query/QueryDuration/QueryDuration.tsx +1 -1
  57. package/dist/containers/Tenant/utils/paneVisibilityToggleHelpers.tsx +1 -1
  58. package/dist/routes.ts +26 -1
  59. package/dist/store/reducers/{executeTopQueries.ts → executeTopQueries/executeTopQueries.ts} +23 -75
  60. package/dist/{types/store/executeTopQueries.ts → store/reducers/executeTopQueries/types.ts} +3 -7
  61. package/dist/store/reducers/executeTopQueries/utils.ts +36 -0
  62. package/dist/store/reducers/index.ts +12 -2
  63. package/dist/store/reducers/nodes/types.ts +1 -0
  64. package/dist/store/reducers/nodes/utils.ts +16 -6
  65. package/dist/store/reducers/{shardsWorkload.ts → shardsWorkload/shardsWorkload.ts} +5 -11
  66. package/dist/{types/store/shardsWorkload.ts → store/reducers/shardsWorkload/types.ts} +3 -7
  67. package/dist/store/reducers/tenantOverview/topNodesByCpu/topNodesByCpu.ts +87 -0
  68. package/dist/store/reducers/tenantOverview/topNodesByCpu/types.ts +29 -0
  69. package/dist/store/reducers/tenantOverview/topNodesByLoad/topNodesByLoad.ts +87 -0
  70. package/dist/store/reducers/tenantOverview/topNodesByLoad/types.ts +29 -0
  71. package/dist/store/reducers/tenantOverview/topNodesByMemory/topNodesByMemory.ts +87 -0
  72. package/dist/store/reducers/tenantOverview/topNodesByMemory/types.ts +29 -0
  73. package/dist/store/reducers/tenantOverview/topQueries/tenantOverviewTopQueries.ts +93 -0
  74. package/dist/store/reducers/tenantOverview/topQueries/types.ts +14 -0
  75. package/dist/store/reducers/tenantOverview/topShards/tenantOverviewTopShards.ts +103 -0
  76. package/dist/store/reducers/tenantOverview/topShards/types.ts +14 -0
  77. package/dist/store/reducers/tenantOverview/topShards/utils.ts +3 -0
  78. package/dist/styles/mixins.scss +4 -0
  79. package/dist/types/additionalProps.ts +3 -1
  80. package/dist/types/api/compute.ts +1 -1
  81. package/dist/types/react-json-inspector.d.ts +21 -0
  82. package/dist/utils/diagnostics.ts +23 -0
  83. package/dist/utils/generateEvaluator.ts +21 -0
  84. package/dist/utils/generateHash.ts +11 -0
  85. package/package.json +3 -2
  86. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantStorage/TenantStorage.scss +0 -41
@@ -1,6 +1,7 @@
1
- import type {TComputeInfo, TComputeNodeInfo} from '../../../types/api/compute';
1
+ import type {TComputeInfo, TComputeNodeInfo, TComputeTenantInfo} from '../../../types/api/compute';
2
2
  import type {TNodesInfo} from '../../../types/api/nodes';
3
3
  import {calcUptime} from '../../../utils/dataFormatters/dataFormatters';
4
+ import {generateEvaluator} from '../../../utils/generateEvaluator';
4
5
 
5
6
  import type {NodesHandledResponse, NodesPreparedEntity} from './types';
6
7
 
@@ -14,23 +15,30 @@ const prepareComputeNode = (node: TComputeNodeInfo, tenantName?: string) => {
14
15
  };
15
16
  };
16
17
 
17
- export const prepareComputeNodesData = (data: TComputeInfo): NodesHandledResponse => {
18
+ export const prepareComputeNodes = (nodes?: TComputeNodeInfo[], tenants?: TComputeTenantInfo[]) => {
18
19
  const preparedNodes: NodesPreparedEntity[] = [];
19
20
 
20
21
  // First try to parse v2 response in case backend supports it
21
22
  // Else parse v1 response
22
- if (data.Nodes) {
23
- data.Nodes.forEach((node) => {
23
+
24
+ if (nodes) {
25
+ nodes.forEach((node) => {
24
26
  preparedNodes.push(prepareComputeNode(node));
25
27
  });
26
- } else if (data.Tenants) {
27
- for (const tenant of data.Tenants) {
28
+ } else if (tenants) {
29
+ for (const tenant of tenants) {
28
30
  tenant.Nodes?.forEach((node) => {
29
31
  preparedNodes.push(prepareComputeNode(node, tenant.Name));
30
32
  });
31
33
  }
32
34
  }
33
35
 
36
+ return preparedNodes;
37
+ };
38
+
39
+ export const prepareComputeNodesData = (data: TComputeInfo): NodesHandledResponse => {
40
+ const preparedNodes = prepareComputeNodes(data.Nodes, data.Tenants);
41
+
34
42
  return {
35
43
  Nodes: preparedNodes,
36
44
  TotalNodes: Number(data.TotalNodes) || preparedNodes.length,
@@ -57,3 +65,5 @@ export const prepareNodesData = (data: TNodesInfo): NodesHandledResponse => {
57
65
  FoundNodes: Number(data.FoundNodes),
58
66
  };
59
67
  };
68
+
69
+ export const getLoadSeverityForNode = generateEvaluator(60, 80, ['success', 'warning', 'danger']);
@@ -1,16 +1,10 @@
1
1
  import type {Reducer} from 'redux';
2
2
 
3
- import '../../services/api';
4
- import type {
5
- IShardsWorkloadAction,
6
- IShardsWorkloadFilters,
7
- IShardsWorkloadState,
8
- } from '../../types/store/shardsWorkload';
9
- import {EShardsWorkloadMode} from '../../types/store/shardsWorkload';
10
-
11
- import {parseQueryAPIExecuteResponse} from '../../utils/query';
12
-
13
- import {createRequestActionTypes, createApiRequest} from '../utils';
3
+ import '../../../services/api';
4
+ import {parseQueryAPIExecuteResponse} from '../../../utils/query';
5
+ import {createRequestActionTypes, createApiRequest} from '../../utils';
6
+ import type {IShardsWorkloadAction, IShardsWorkloadFilters, IShardsWorkloadState} from './types';
7
+ import {EShardsWorkloadMode} from './types';
14
8
 
15
9
  export const SEND_SHARD_QUERY = createRequestActionTypes('query', 'SEND_SHARD_QUERY');
16
10
  const SET_SHARD_STATE = 'query/SET_SHARD_STATE';
@@ -1,10 +1,6 @@
1
- import {
2
- SEND_SHARD_QUERY,
3
- setShardsState,
4
- setShardsQueryFilters,
5
- } from '../../store/reducers/shardsWorkload';
6
- import type {ApiRequestAction} from '../../store/utils';
7
- import type {IQueryResult, QueryErrorResponse} from './query';
1
+ import {SEND_SHARD_QUERY, setShardsState, setShardsQueryFilters} from './shardsWorkload';
2
+ import type {ApiRequestAction} from '../../utils';
3
+ import type {IQueryResult, QueryErrorResponse} from '../../../types/store/query';
8
4
 
9
5
  export enum EShardsWorkloadMode {
10
6
  Immediate = 'immediate',
@@ -0,0 +1,87 @@
1
+ import type {Reducer} from 'redux';
2
+
3
+ import {TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../utils/constants';
4
+ import {createApiRequest, createRequestActionTypes} from '../../../utils';
5
+ import {prepareNodesData} from '../../nodes/utils';
6
+ import type {NodesApiRequestParams} from '../../nodes/types';
7
+ import type {TopNodesByCpuAction, TopNodesByCpuState, TopPoolsStateSlice} from './types';
8
+
9
+ export const FETCH_TOP_NODES_BY_CPU = createRequestActionTypes(
10
+ 'topNodesByCpu',
11
+ 'FETCH_TOP_NODES_BY_CPU',
12
+ );
13
+ const SET_DATA_WAS_NOT_LOADED = 'topNodesByCpu/SET_DATA_WAS_NOT_LOADED';
14
+
15
+ const initialState = {
16
+ loading: false,
17
+ wasLoaded: false,
18
+ };
19
+
20
+ export const topNodesByCpu: Reducer<TopNodesByCpuState, TopNodesByCpuAction> = (
21
+ state = initialState,
22
+ action,
23
+ ) => {
24
+ switch (action.type) {
25
+ case FETCH_TOP_NODES_BY_CPU.REQUEST: {
26
+ return {
27
+ ...state,
28
+ loading: true,
29
+ };
30
+ }
31
+ case FETCH_TOP_NODES_BY_CPU.SUCCESS: {
32
+ return {
33
+ ...state,
34
+ data: action.data?.Nodes,
35
+ loading: false,
36
+ wasLoaded: true,
37
+ error: undefined,
38
+ };
39
+ }
40
+ case FETCH_TOP_NODES_BY_CPU.FAILURE: {
41
+ if (action.error?.isCancelled) {
42
+ return state;
43
+ }
44
+
45
+ return {
46
+ ...state,
47
+ error: action.error,
48
+ loading: false,
49
+ };
50
+ }
51
+ case SET_DATA_WAS_NOT_LOADED: {
52
+ return {
53
+ ...state,
54
+ wasLoaded: false,
55
+ };
56
+ }
57
+ default:
58
+ return state;
59
+ }
60
+ };
61
+
62
+ const concurrentId = 'getTopNodeByCpu';
63
+
64
+ export function getTopNodesByCpu({
65
+ type = 'any',
66
+ sortOrder = -1,
67
+ sortValue = 'CPU',
68
+ limit = TENANT_OVERVIEW_TABLES_LIMIT,
69
+ ...params
70
+ }: NodesApiRequestParams) {
71
+ return createApiRequest({
72
+ request: window.api.getNodes(
73
+ {type, sortOrder, sortValue, limit, ...params},
74
+ {concurrentId},
75
+ ),
76
+ actions: FETCH_TOP_NODES_BY_CPU,
77
+ dataHandler: prepareNodesData,
78
+ });
79
+ }
80
+
81
+ export const selectTopNodesByCpu = (state: TopPoolsStateSlice) => state.topNodesByCpu.data;
82
+
83
+ export const setDataWasNotLoaded = () => {
84
+ return {
85
+ type: SET_DATA_WAS_NOT_LOADED,
86
+ } as const;
87
+ };
@@ -0,0 +1,29 @@
1
+ import type {IResponseError} from '../../../../types/api/error';
2
+ import type {ApiRequestAction} from '../../../utils';
3
+ import type {NodesPreparedEntity} from '../../nodes/types';
4
+ import {FETCH_TOP_NODES_BY_CPU, setDataWasNotLoaded} from './topNodesByCpu';
5
+
6
+ export interface TopNodesByCpuState {
7
+ loading: boolean;
8
+ wasLoaded: boolean;
9
+ data?: NodesPreparedEntity[];
10
+ error?: IResponseError;
11
+ }
12
+
13
+ export interface TopNodesByCpuHandledResponse {
14
+ Nodes?: NodesPreparedEntity[];
15
+ }
16
+
17
+ type TopNodesByCpuApiRequestAction = ApiRequestAction<
18
+ typeof FETCH_TOP_NODES_BY_CPU,
19
+ TopNodesByCpuHandledResponse,
20
+ IResponseError
21
+ >;
22
+
23
+ export type TopNodesByCpuAction =
24
+ | TopNodesByCpuApiRequestAction
25
+ | ReturnType<typeof setDataWasNotLoaded>;
26
+
27
+ export interface TopPoolsStateSlice {
28
+ topNodesByCpu: TopNodesByCpuState;
29
+ }
@@ -0,0 +1,87 @@
1
+ import type {Reducer} from 'redux';
2
+
3
+ import {TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../utils/constants';
4
+ import {createApiRequest, createRequestActionTypes} from '../../../utils';
5
+ import {prepareNodesData} from '../../nodes/utils';
6
+ import type {NodesApiRequestParams} from '../../nodes/types';
7
+ import type {TopNodesByLoadAction, TopNodesByLoadState, TopNodesByLoadStateSlice} from './types';
8
+
9
+ export const FETCH_TOP_NODES_BY_LOAD = createRequestActionTypes(
10
+ 'topNodesByLoad',
11
+ 'FETCH_TOP_NODES_BY_LOAD',
12
+ );
13
+ const SET_DATA_WAS_NOT_LOADED = 'topNodesByLoad/SET_DATA_WAS_NOT_LOADED';
14
+
15
+ const initialState = {
16
+ loading: false,
17
+ wasLoaded: false,
18
+ };
19
+
20
+ export const topNodesByLoad: Reducer<TopNodesByLoadState, TopNodesByLoadAction> = (
21
+ state = initialState,
22
+ action,
23
+ ) => {
24
+ switch (action.type) {
25
+ case FETCH_TOP_NODES_BY_LOAD.REQUEST: {
26
+ return {
27
+ ...state,
28
+ loading: true,
29
+ };
30
+ }
31
+ case FETCH_TOP_NODES_BY_LOAD.SUCCESS: {
32
+ return {
33
+ ...state,
34
+ data: action.data?.Nodes,
35
+ loading: false,
36
+ wasLoaded: true,
37
+ error: undefined,
38
+ };
39
+ }
40
+ case FETCH_TOP_NODES_BY_LOAD.FAILURE: {
41
+ if (action.error?.isCancelled) {
42
+ return state;
43
+ }
44
+
45
+ return {
46
+ ...state,
47
+ error: action.error,
48
+ loading: false,
49
+ };
50
+ }
51
+ case SET_DATA_WAS_NOT_LOADED: {
52
+ return {
53
+ ...state,
54
+ wasLoaded: false,
55
+ };
56
+ }
57
+ default:
58
+ return state;
59
+ }
60
+ };
61
+
62
+ const concurrentId = 'getTopNodesByLoad';
63
+
64
+ export function getTopNodesByLoad({
65
+ type = 'any',
66
+ sortOrder = -1,
67
+ sortValue = 'LoadAverage',
68
+ limit = TENANT_OVERVIEW_TABLES_LIMIT,
69
+ ...params
70
+ }: NodesApiRequestParams) {
71
+ return createApiRequest({
72
+ request: window.api.getNodes(
73
+ {type, sortOrder, sortValue, limit, ...params},
74
+ {concurrentId},
75
+ ),
76
+ actions: FETCH_TOP_NODES_BY_LOAD,
77
+ dataHandler: prepareNodesData,
78
+ });
79
+ }
80
+
81
+ export const selectTopNodesByLoad = (state: TopNodesByLoadStateSlice) => state.topNodesByLoad.data;
82
+
83
+ export const setDataWasNotLoaded = () => {
84
+ return {
85
+ type: SET_DATA_WAS_NOT_LOADED,
86
+ } as const;
87
+ };
@@ -0,0 +1,29 @@
1
+ import type {IResponseError} from '../../../../types/api/error';
2
+ import type {ApiRequestAction} from '../../../utils';
3
+ import type {NodesPreparedEntity} from '../../nodes/types';
4
+ import {FETCH_TOP_NODES_BY_LOAD, setDataWasNotLoaded} from './topNodesByLoad';
5
+
6
+ export interface TopNodesByLoadState {
7
+ loading: boolean;
8
+ wasLoaded: boolean;
9
+ data?: NodesPreparedEntity[];
10
+ error?: IResponseError;
11
+ }
12
+
13
+ export interface TopNodesByLoadHandledResponse {
14
+ Nodes?: NodesPreparedEntity[];
15
+ }
16
+
17
+ type TopNodesByLoadApiRequestAction = ApiRequestAction<
18
+ typeof FETCH_TOP_NODES_BY_LOAD,
19
+ TopNodesByLoadHandledResponse,
20
+ IResponseError
21
+ >;
22
+
23
+ export type TopNodesByLoadAction =
24
+ | TopNodesByLoadApiRequestAction
25
+ | ReturnType<typeof setDataWasNotLoaded>;
26
+
27
+ export interface TopNodesByLoadStateSlice {
28
+ topNodesByLoad: TopNodesByLoadState;
29
+ }
@@ -0,0 +1,87 @@
1
+ import type {Reducer} from 'redux';
2
+
3
+ import {TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../utils/constants';
4
+ import {createApiRequest, createRequestActionTypes} from '../../../utils';
5
+ import {prepareNodesData} from '../../nodes/utils';
6
+ import type {NodesApiRequestParams} from '../../nodes/types';
7
+ import type {TopNodesByMemoryAction, TopNodesByMemoryState, TopNodesByMemorySlice} from './types';
8
+
9
+ export const FETCH_TOP_NODES_BY_MEMORY = createRequestActionTypes(
10
+ 'topNodesByMemory',
11
+ 'FETCH_TOP_NODES_BY_MEMORY',
12
+ );
13
+ const SET_DATA_WAS_NOT_LOADED = 'topNodesByMemory/SET_DATA_WAS_NOT_LOADED';
14
+
15
+ const initialState = {
16
+ loading: false,
17
+ wasLoaded: false,
18
+ };
19
+
20
+ export const topNodesByMemory: Reducer<TopNodesByMemoryState, TopNodesByMemoryAction> = (
21
+ state = initialState,
22
+ action,
23
+ ) => {
24
+ switch (action.type) {
25
+ case FETCH_TOP_NODES_BY_MEMORY.REQUEST: {
26
+ return {
27
+ ...state,
28
+ loading: true,
29
+ };
30
+ }
31
+ case FETCH_TOP_NODES_BY_MEMORY.SUCCESS: {
32
+ return {
33
+ ...state,
34
+ data: action.data?.Nodes,
35
+ loading: false,
36
+ wasLoaded: true,
37
+ error: undefined,
38
+ };
39
+ }
40
+ case FETCH_TOP_NODES_BY_MEMORY.FAILURE: {
41
+ if (action.error?.isCancelled) {
42
+ return state;
43
+ }
44
+
45
+ return {
46
+ ...state,
47
+ error: action.error,
48
+ loading: false,
49
+ };
50
+ }
51
+ case SET_DATA_WAS_NOT_LOADED: {
52
+ return {
53
+ ...state,
54
+ wasLoaded: false,
55
+ };
56
+ }
57
+ default:
58
+ return state;
59
+ }
60
+ };
61
+
62
+ const concurrentId = 'getTopNodeByMemory';
63
+
64
+ export function getTopNodesByMemory({
65
+ type = 'any',
66
+ sortOrder = -1,
67
+ sortValue = 'Memory',
68
+ limit = TENANT_OVERVIEW_TABLES_LIMIT,
69
+ ...params
70
+ }: NodesApiRequestParams) {
71
+ return createApiRequest({
72
+ request: window.api.getNodes(
73
+ {type, sortOrder, sortValue, limit, ...params},
74
+ {concurrentId},
75
+ ),
76
+ actions: FETCH_TOP_NODES_BY_MEMORY,
77
+ dataHandler: prepareNodesData,
78
+ });
79
+ }
80
+
81
+ export const selectTopNodesByMemory = (state: TopNodesByMemorySlice) => state.topNodesByMemory.data;
82
+
83
+ export const setDataWasNotLoaded = () => {
84
+ return {
85
+ type: SET_DATA_WAS_NOT_LOADED,
86
+ } as const;
87
+ };
@@ -0,0 +1,29 @@
1
+ import type {IResponseError} from '../../../../types/api/error';
2
+ import type {ApiRequestAction} from '../../../utils';
3
+ import type {NodesPreparedEntity} from '../../nodes/types';
4
+ import {FETCH_TOP_NODES_BY_MEMORY, setDataWasNotLoaded} from './topNodesByMemory';
5
+
6
+ export interface TopNodesByMemoryState {
7
+ loading: boolean;
8
+ wasLoaded: boolean;
9
+ data?: NodesPreparedEntity[];
10
+ error?: IResponseError;
11
+ }
12
+
13
+ export interface TopNodesByMemoryHandledResponse {
14
+ Nodes?: NodesPreparedEntity[];
15
+ }
16
+
17
+ type TopNodesByMemoryApiRequestAction = ApiRequestAction<
18
+ typeof FETCH_TOP_NODES_BY_MEMORY,
19
+ TopNodesByMemoryHandledResponse,
20
+ IResponseError
21
+ >;
22
+
23
+ export type TopNodesByMemoryAction =
24
+ | TopNodesByMemoryApiRequestAction
25
+ | ReturnType<typeof setDataWasNotLoaded>;
26
+
27
+ export interface TopNodesByMemorySlice {
28
+ topNodesByMemory: TopNodesByMemoryState;
29
+ }
@@ -0,0 +1,93 @@
1
+ import type {Reducer} from 'redux';
2
+
3
+ import '../../../../services/api';
4
+ import {TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../utils/constants';
5
+ import {parseQueryAPIExecuteResponse} from '../../../../utils/query';
6
+
7
+ import {createRequestActionTypes, createApiRequest} from '../../../utils';
8
+ import type {TenantOverviewTopQueriesAction, TenantOverviewTopQueriesState} from './types';
9
+
10
+ export const FETCH_TENANT_OVERVIEW_TOP_QUERIES = createRequestActionTypes(
11
+ 'tenantOverviewTopQueries',
12
+ 'FETCH_TOP_QUERIES',
13
+ );
14
+ const SET_DATA_WAS_NOT_LOADED = 'tenantOverviewTopQueries/SET_DATA_WAS_NOT_LOADED';
15
+
16
+ const initialState = {
17
+ loading: false,
18
+ wasLoaded: false,
19
+ filters: {},
20
+ };
21
+
22
+ const getQueryText = (path: string) => {
23
+ return `
24
+ SELECT
25
+ CPUTime as CPUTimeUs,
26
+ QueryText,
27
+ FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
28
+ ORDER BY CPUTimeUs DESC
29
+ LIMIT ${TENANT_OVERVIEW_TABLES_LIMIT}
30
+ `;
31
+ };
32
+
33
+ export const tenantOverviewTopQueries: Reducer<
34
+ TenantOverviewTopQueriesState,
35
+ TenantOverviewTopQueriesAction
36
+ > = (state = initialState, action) => {
37
+ switch (action.type) {
38
+ case FETCH_TENANT_OVERVIEW_TOP_QUERIES.REQUEST: {
39
+ return {
40
+ ...state,
41
+ loading: true,
42
+ error: undefined,
43
+ };
44
+ }
45
+ case FETCH_TENANT_OVERVIEW_TOP_QUERIES.SUCCESS: {
46
+ return {
47
+ ...state,
48
+ data: action.data,
49
+ loading: false,
50
+ error: undefined,
51
+ wasLoaded: true,
52
+ };
53
+ }
54
+ // 401 Unauthorized error is handled by GenericAPI
55
+ case FETCH_TENANT_OVERVIEW_TOP_QUERIES.FAILURE: {
56
+ return {
57
+ ...state,
58
+ error: action.error || 'Unauthorized',
59
+ loading: false,
60
+ };
61
+ }
62
+ case SET_DATA_WAS_NOT_LOADED:
63
+ return {
64
+ ...state,
65
+ wasLoaded: false,
66
+ };
67
+ default:
68
+ return state;
69
+ }
70
+ };
71
+
72
+ export const fetchTenantOverviewTopQueries = (database: string) =>
73
+ createApiRequest({
74
+ request: window.api.sendQuery(
75
+ {
76
+ schema: 'modern',
77
+ query: getQueryText(database),
78
+ database,
79
+ action: 'execute-scan',
80
+ },
81
+ {
82
+ concurrentId: 'executeTopQueries',
83
+ },
84
+ ),
85
+ actions: FETCH_TENANT_OVERVIEW_TOP_QUERIES,
86
+ dataHandler: parseQueryAPIExecuteResponse,
87
+ });
88
+
89
+ export function setDataWasNotLoaded() {
90
+ return {
91
+ type: SET_DATA_WAS_NOT_LOADED,
92
+ } as const;
93
+ }
@@ -0,0 +1,14 @@
1
+ import type {IQueryResult, QueryErrorResponse} from '../../../../types/store/query';
2
+ import type {ApiRequestAction} from '../../../utils';
3
+ import {FETCH_TENANT_OVERVIEW_TOP_QUERIES, setDataWasNotLoaded} from './tenantOverviewTopQueries';
4
+
5
+ export interface TenantOverviewTopQueriesState {
6
+ loading: boolean;
7
+ wasLoaded: boolean;
8
+ data?: IQueryResult;
9
+ error?: QueryErrorResponse;
10
+ }
11
+
12
+ export type TenantOverviewTopQueriesAction =
13
+ | ApiRequestAction<typeof FETCH_TENANT_OVERVIEW_TOP_QUERIES, IQueryResult, QueryErrorResponse>
14
+ | ReturnType<typeof setDataWasNotLoaded>;
@@ -0,0 +1,103 @@
1
+ import type {Reducer} from 'redux';
2
+
3
+ import '../../../../services/api';
4
+ import {TENANT_OVERVIEW_TABLES_LIMIT} from '../../../../utils/constants';
5
+ import {parseQueryAPIExecuteResponse} from '../../../../utils/query';
6
+ import {createRequestActionTypes, createApiRequest} from '../../../utils';
7
+ import {TenantOverviewTopShardsAction, TenantOverviewTopShardsState} from './types';
8
+
9
+ export const FETCH_TENANT_OVERVIEW_TOP_SHARDS = createRequestActionTypes(
10
+ 'tenantOverviewTopShards',
11
+ 'FETCH_TENANT_OVERVIEW_TOP_SHARDS',
12
+ );
13
+ const SET_DATA_WAS_NOT_LOADED = 'tenantOverviewTopShards/SET_DATA_WAS_NOT_LOADED';
14
+
15
+ const initialState = {
16
+ loading: false,
17
+ wasLoaded: false,
18
+ };
19
+
20
+ function createShardQuery(path: string, tenantName?: string) {
21
+ const pathSelect = tenantName
22
+ ? `CAST(SUBSTRING(CAST(Path AS String), ${tenantName.length}) AS Utf8) AS Path`
23
+ : 'Path';
24
+
25
+ return `SELECT
26
+ ${pathSelect},
27
+ TabletId,
28
+ CPUCores,
29
+ FROM \`.sys/partition_stats\`
30
+ WHERE
31
+ Path='${path}'
32
+ OR Path LIKE '${path}/%'
33
+ ORDER BY CPUCores DESC
34
+ LIMIT ${TENANT_OVERVIEW_TABLES_LIMIT}`;
35
+ }
36
+
37
+ const queryAction = 'execute-scan';
38
+
39
+ export const tenantOverviewTopShards: Reducer<
40
+ TenantOverviewTopShardsState,
41
+ TenantOverviewTopShardsAction
42
+ > = (state = initialState, action) => {
43
+ switch (action.type) {
44
+ case FETCH_TENANT_OVERVIEW_TOP_SHARDS.REQUEST: {
45
+ return {
46
+ ...state,
47
+ loading: true,
48
+ error: undefined,
49
+ };
50
+ }
51
+ case FETCH_TENANT_OVERVIEW_TOP_SHARDS.SUCCESS: {
52
+ return {
53
+ ...state,
54
+ data: action.data,
55
+ loading: false,
56
+ error: undefined,
57
+ wasLoaded: true,
58
+ };
59
+ }
60
+ // 401 Unauthorized error is handled by GenericAPI
61
+ case FETCH_TENANT_OVERVIEW_TOP_SHARDS.FAILURE: {
62
+ if (action.error?.isCancelled) {
63
+ return state;
64
+ }
65
+
66
+ return {
67
+ ...state,
68
+ error: action.error || 'Unauthorized',
69
+ loading: false,
70
+ };
71
+ }
72
+ case SET_DATA_WAS_NOT_LOADED:
73
+ return {
74
+ ...state,
75
+ wasLoaded: false,
76
+ };
77
+ default:
78
+ return state;
79
+ }
80
+ };
81
+
82
+ export const sendTenantOverviewTopShardsQuery = (database: string, path = '') =>
83
+ createApiRequest({
84
+ request: window.api.sendQuery(
85
+ {
86
+ schema: 'modern',
87
+ query: createShardQuery(path, database),
88
+ database,
89
+ action: queryAction,
90
+ },
91
+ {
92
+ concurrentId: 'executeTopShards',
93
+ },
94
+ ),
95
+ actions: FETCH_TENANT_OVERVIEW_TOP_SHARDS,
96
+ dataHandler: parseQueryAPIExecuteResponse,
97
+ });
98
+
99
+ export function setDataWasNotLoaded() {
100
+ return {
101
+ type: SET_DATA_WAS_NOT_LOADED,
102
+ } as const;
103
+ }
@@ -0,0 +1,14 @@
1
+ import type {IQueryResult, QueryErrorResponse} from '../../../../types/store/query';
2
+ import type {ApiRequestAction} from '../../../utils';
3
+ import {FETCH_TENANT_OVERVIEW_TOP_SHARDS, setDataWasNotLoaded} from './tenantOverviewTopShards';
4
+
5
+ export interface TenantOverviewTopShardsState {
6
+ loading: boolean;
7
+ wasLoaded: boolean;
8
+ data?: IQueryResult;
9
+ error?: QueryErrorResponse;
10
+ }
11
+
12
+ export type TenantOverviewTopShardsAction =
13
+ | ApiRequestAction<typeof FETCH_TENANT_OVERVIEW_TOP_SHARDS, IQueryResult, QueryErrorResponse>
14
+ | ReturnType<typeof setDataWasNotLoaded>;
@@ -0,0 +1,3 @@
1
+ import {generateEvaluator} from '../../../../utils/generateEvaluator';
2
+
3
+ export const getLoadSeverityForShard = generateEvaluator(60, 80, ['success', 'warning', 'danger']);
@@ -177,6 +177,10 @@
177
177
  .data-table__table-wrapper {
178
178
  padding-bottom: 20px;
179
179
  }
180
+
181
+ &_sticky-head_fixed {
182
+ overflow: initial;
183
+ }
180
184
  }
181
185
  }
182
186
  }