ydb-embedded-ui 3.1.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +2 -0
  3. package/dist/components/DateRange/DateRange.scss +11 -0
  4. package/dist/{containers/Tenant/Diagnostics/TopShards → components}/DateRange/DateRange.tsx +7 -7
  5. package/dist/{containers/Tenant/Diagnostics/TopShards → components}/DateRange/index.ts +0 -0
  6. package/dist/components/EntitiesCount/EntitiesCount.tsx +34 -0
  7. package/dist/components/EntitiesCount/i18n/en.json +3 -0
  8. package/dist/components/{AsideNavigation/Settings → EntitiesCount}/i18n/index.ts +2 -2
  9. package/dist/components/EntitiesCount/i18n/ru.json +3 -0
  10. package/dist/components/EntitiesCount/index.ts +1 -0
  11. package/dist/components/Fullscreen/Fullscreen.scss +7 -5
  12. package/dist/components/Illustration/Illustration.tsx +4 -11
  13. package/dist/components/InfoViewer/InfoViewer.scss +2 -0
  14. package/dist/components/TabletsOverall/TabletsOverall.tsx +4 -4
  15. package/dist/components/TabletsStatistic/TabletsStatistic.tsx +56 -0
  16. package/dist/components/TabletsStatistic/index.ts +1 -0
  17. package/dist/containers/App/App.scss +4 -12
  18. package/dist/containers/AsideNavigation/AsideNavigation.scss +0 -18
  19. package/dist/containers/AsideNavigation/AsideNavigation.tsx +95 -33
  20. package/dist/containers/Heatmap/Heatmap.scss +0 -7
  21. package/dist/containers/Heatmap/Heatmap.tsx +203 -0
  22. package/dist/containers/Heatmap/HeatmapCanvas/HeatmapCanvas.js +2 -1
  23. package/dist/containers/Heatmap/index.ts +1 -0
  24. package/dist/containers/Node/Node.tsx +1 -1
  25. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +1 -1
  26. package/dist/containers/Storage/Storage.js +12 -19
  27. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +16 -0
  28. package/dist/containers/Tablets/Tablets.scss +0 -5
  29. package/dist/containers/Tablets/Tablets.tsx +172 -0
  30. package/dist/containers/Tablets/i18n/en.json +6 -0
  31. package/dist/{components/AsideNavigation → containers/Tablets}/i18n/index.ts +1 -1
  32. package/dist/containers/Tablets/i18n/ru.json +6 -0
  33. package/dist/containers/Tablets/index.ts +1 -0
  34. package/dist/containers/TabletsFilters/TabletsFilters.js +4 -8
  35. package/dist/containers/TabletsFilters/TabletsFilters.scss +6 -2
  36. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +8 -13
  37. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +7 -7
  38. package/dist/containers/Tenant/Diagnostics/{TopShards/TopShards.scss → OverloadedShards/OverloadedShards.scss} +1 -1
  39. package/dist/containers/Tenant/Diagnostics/{TopShards/TopShards.tsx → OverloadedShards/OverloadedShards.tsx} +10 -11
  40. package/dist/containers/Tenant/Diagnostics/{TopShards → OverloadedShards}/i18n/en.json +0 -0
  41. package/dist/containers/Tenant/Diagnostics/OverloadedShards/i18n/index.ts +11 -0
  42. package/dist/containers/Tenant/Diagnostics/{TopShards → OverloadedShards}/i18n/ru.json +0 -0
  43. package/dist/containers/Tenant/Diagnostics/OverloadedShards/index.ts +1 -0
  44. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +7 -7
  45. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +16 -19
  46. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +202 -0
  47. package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/en.json +4 -0
  48. package/dist/containers/Tenant/Diagnostics/{TopShards → TopQueries}/i18n/index.ts +1 -1
  49. package/dist/containers/Tenant/Diagnostics/TopQueries/i18n/ru.json +4 -0
  50. package/dist/containers/Tenant/Diagnostics/TopQueries/index.ts +1 -0
  51. package/dist/containers/Tenants/Tenants.js +1 -1
  52. package/dist/containers/UserSettings/UserSettings.tsx +5 -4
  53. package/dist/routes.ts +1 -1
  54. package/dist/services/api.d.ts +7 -0
  55. package/dist/store/reducers/describe.ts +4 -1
  56. package/dist/store/reducers/executeTopQueries.ts +170 -0
  57. package/dist/store/reducers/{heatmap.js → heatmap.ts} +33 -18
  58. package/dist/store/reducers/settings.js +13 -3
  59. package/dist/store/reducers/shardsWorkload.ts +9 -9
  60. package/dist/store/reducers/storage.js +2 -0
  61. package/dist/store/reducers/{tablets.js → tablets.ts} +30 -17
  62. package/dist/store/state-url-mapping.js +10 -2
  63. package/dist/types/api/compute.ts +52 -0
  64. package/dist/types/api/consumer.ts +257 -0
  65. package/dist/types/api/enums.ts +2 -2
  66. package/dist/types/api/nodes.ts +5 -2
  67. package/dist/types/api/pdisk.ts +3 -0
  68. package/dist/types/api/schema.ts +17 -3
  69. package/dist/types/api/storage.ts +31 -28
  70. package/dist/types/api/tablet.ts +18 -2
  71. package/dist/types/api/tenant.ts +4 -1
  72. package/dist/types/api/topic.ts +157 -0
  73. package/dist/types/api/vdisk.ts +3 -0
  74. package/dist/types/store/executeTopQueries.ts +29 -0
  75. package/dist/types/store/heatmap.ts +51 -0
  76. package/dist/types/store/schema.ts +3 -3
  77. package/dist/types/store/shardsWorkload.ts +3 -3
  78. package/dist/types/store/tablets.ts +42 -0
  79. package/dist/utils/constants.ts +1 -37
  80. package/dist/utils/getNodesColumns.js +14 -2
  81. package/dist/utils/tablet.ts +53 -0
  82. package/package.json +4 -3
  83. package/dist/components/AsideNavigation/AsideHeader.scss +0 -147
  84. package/dist/components/AsideNavigation/AsideHeader.tsx +0 -389
  85. package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.scss +0 -82
  86. package/dist/components/AsideNavigation/AsideHeaderFooterItem/AsideHeaderFooterItem.tsx +0 -138
  87. package/dist/components/AsideNavigation/AsideHeaderFooterSlot/AsideHeaderFooterSlot.tsx +0 -33
  88. package/dist/components/AsideNavigation/AsideHeaderFooterSlot/SlotsContext.tsx +0 -49
  89. package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.scss +0 -16
  90. package/dist/components/AsideNavigation/AsideHeaderTooltip/AsideHeaderTooltip.tsx +0 -37
  91. package/dist/components/AsideNavigation/CompositeBar/CompositeBar.scss +0 -108
  92. package/dist/components/AsideNavigation/CompositeBar/CompositeBar.tsx +0 -282
  93. package/dist/components/AsideNavigation/Content/Content.tsx +0 -35
  94. package/dist/components/AsideNavigation/Drawer/Drawer.scss +0 -76
  95. package/dist/components/AsideNavigation/Drawer/Drawer.tsx +0 -134
  96. package/dist/components/AsideNavigation/Drawer/index.ts +0 -1
  97. package/dist/components/AsideNavigation/Logo/Logo.scss +0 -43
  98. package/dist/components/AsideNavigation/Logo/Logo.tsx +0 -82
  99. package/dist/components/AsideNavigation/Settings/README.md +0 -92
  100. package/dist/components/AsideNavigation/Settings/Settings.scss +0 -128
  101. package/dist/components/AsideNavigation/Settings/Settings.tsx +0 -270
  102. package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.scss +0 -78
  103. package/dist/components/AsideNavigation/Settings/SettingsMenu/SettingsMenu.tsx +0 -141
  104. package/dist/components/AsideNavigation/Settings/SettingsSearch/SettingsSearch.tsx +0 -57
  105. package/dist/components/AsideNavigation/Settings/collect-settings.ts +0 -156
  106. package/dist/components/AsideNavigation/Settings/filter-settings.ts +0 -38
  107. package/dist/components/AsideNavigation/Settings/helpers.ts +0 -39
  108. package/dist/components/AsideNavigation/Settings/i18n/en.json +0 -5
  109. package/dist/components/AsideNavigation/Settings/i18n/ru.json +0 -5
  110. package/dist/components/AsideNavigation/Settings/index.ts +0 -1
  111. package/dist/components/AsideNavigation/constants.ts +0 -28
  112. package/dist/components/AsideNavigation/helpers.ts +0 -34
  113. package/dist/components/AsideNavigation/i18n/en.json +0 -4
  114. package/dist/components/AsideNavigation/i18n/ru.json +0 -4
  115. package/dist/components/AsideNavigation/icons.ts +0 -32
  116. package/dist/components/AsideNavigation/types.ts +0 -23
  117. package/dist/components/TabletsStatistic/TabletsStatistic.js +0 -58
  118. package/dist/containers/Heatmap/Heatmap.js +0 -244
  119. package/dist/containers/Tablets/Tablets.js +0 -228
  120. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +0 -188
  121. package/dist/containers/Tenant/Diagnostics/TopShards/DateRange/DateRange.scss +0 -13
  122. package/dist/containers/Tenant/Diagnostics/TopShards/index.ts +0 -1
  123. package/dist/store/reducers/executeTopQueries.js +0 -66
  124. package/dist/types/api/consumers.ts +0 -3
@@ -0,0 +1,170 @@
1
+ import type {AnyAction, Reducer} from 'redux';
2
+ import type {ThunkAction} from 'redux-thunk';
3
+
4
+ import '../../services/api';
5
+ import {
6
+ ITopQueriesAction,
7
+ ITopQueriesFilters,
8
+ ITopQueriesState,
9
+ } from '../../types/store/executeTopQueries';
10
+ import {IQueryResult} from '../../types/store/query';
11
+
12
+ import {parseQueryAPIExecuteResponse} from '../../utils/query';
13
+
14
+ import {createRequestActionTypes, createApiRequest} from '../utils';
15
+
16
+ import type {IRootState} from '.';
17
+
18
+ export const FETCH_TOP_QUERIES = createRequestActionTypes('top-queries', 'FETCH_TOP_QUERIES');
19
+ const SET_TOP_QUERIES_STATE = 'top-queries/SET_TOP_QUERIES_STATE';
20
+ const SET_TOP_QUERIES_FILTERS = 'top-queries/SET_TOP_QUERIES_FILTERS';
21
+
22
+ const initialState = {
23
+ loading: false,
24
+ wasLoaded: false,
25
+ filters: {},
26
+ };
27
+
28
+ const getMaxIntervalSubquery = (path: string) => `(
29
+ SELECT
30
+ MAX(IntervalEnd)
31
+ FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
32
+ )`;
33
+
34
+ function getFiltersConditions(path: string, filters?: ITopQueriesFilters) {
35
+ const conditions: string[] = [];
36
+
37
+ if (filters?.from && filters?.to && filters.from > filters.to) {
38
+ throw new Error('Invalid date range');
39
+ }
40
+
41
+ if (filters?.from) {
42
+ // matching `from` & `to` is an edge case
43
+ // other cases should not include the starting point, since intervals are stored using the ending time
44
+ const gt = filters.to === filters.from ? '>=' : '>';
45
+ conditions.push(`IntervalEnd ${gt} Timestamp('${new Date(filters.from).toISOString()}')`);
46
+ }
47
+
48
+ if (filters?.to) {
49
+ conditions.push(`IntervalEnd <= Timestamp('${new Date(filters.to).toISOString()}')`);
50
+ }
51
+
52
+ if (!filters?.from && !filters?.to) {
53
+ conditions.push(`IntervalEnd IN ${getMaxIntervalSubquery(path)}`);
54
+ }
55
+
56
+ if (filters?.text) {
57
+ conditions.push(`QueryText ILIKE '%${filters.text}%'`);
58
+ }
59
+
60
+ return conditions.join(' AND ');
61
+ }
62
+
63
+ const getQueryText = (path: string, filters?: ITopQueriesFilters) => {
64
+ const filterConditions = getFiltersConditions(path, filters);
65
+ return `
66
+ SELECT
67
+ CPUTime as CPUTimeUs,
68
+ QueryText,
69
+ IntervalEnd
70
+ FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
71
+ WHERE ${filterConditions || 'true'}
72
+ `;
73
+ };
74
+
75
+ const executeTopQueries: Reducer<ITopQueriesState, ITopQueriesAction> = (
76
+ state = initialState,
77
+ action,
78
+ ) => {
79
+ switch (action.type) {
80
+ case FETCH_TOP_QUERIES.REQUEST: {
81
+ return {
82
+ ...state,
83
+ loading: true,
84
+ error: undefined,
85
+ };
86
+ }
87
+ case FETCH_TOP_QUERIES.SUCCESS: {
88
+ return {
89
+ ...state,
90
+ data: action.data,
91
+ loading: false,
92
+ error: undefined,
93
+ wasLoaded: true,
94
+ };
95
+ }
96
+ // 401 Unauthorized error is handled by GenericAPI
97
+ case FETCH_TOP_QUERIES.FAILURE: {
98
+ return {
99
+ ...state,
100
+ error: action.error || 'Unauthorized',
101
+ loading: false,
102
+ };
103
+ }
104
+ case SET_TOP_QUERIES_STATE:
105
+ return {
106
+ ...state,
107
+ ...action.data,
108
+ };
109
+ case SET_TOP_QUERIES_FILTERS:
110
+ return {
111
+ ...state,
112
+ filters: {
113
+ ...state.filters,
114
+ ...action.filters,
115
+ },
116
+ };
117
+ default:
118
+ return state;
119
+ }
120
+ };
121
+
122
+ type FetchTopQueries = (params: {
123
+ database: string;
124
+ filters?: ITopQueriesFilters;
125
+ }) => ThunkAction<Promise<IQueryResult | undefined>, IRootState, unknown, AnyAction>;
126
+
127
+ export const fetchTopQueries: FetchTopQueries =
128
+ ({database, filters}) =>
129
+ async (dispatch, getState) => {
130
+ try {
131
+ return createApiRequest({
132
+ request: window.api.sendQuery(
133
+ {
134
+ schema: 'modern',
135
+ query: getQueryText(database, filters),
136
+ database,
137
+ action: 'execute-scan',
138
+ },
139
+ {
140
+ concurrentId: 'executeTopQueries',
141
+ },
142
+ ),
143
+ actions: FETCH_TOP_QUERIES,
144
+ dataHandler: parseQueryAPIExecuteResponse,
145
+ })(dispatch, getState);
146
+ } catch (error) {
147
+ dispatch({
148
+ type: FETCH_TOP_QUERIES.FAILURE,
149
+ error,
150
+ });
151
+
152
+ throw error;
153
+ }
154
+ };
155
+
156
+ export function setTopQueriesState(state: Partial<ITopQueriesState>) {
157
+ return {
158
+ type: SET_TOP_QUERIES_STATE,
159
+ data: state,
160
+ } as const;
161
+ }
162
+
163
+ export function setTopQueriesFilters(filters: Partial<ITopQueriesFilters>) {
164
+ return {
165
+ type: SET_TOP_QUERIES_FILTERS,
166
+ filters,
167
+ } as const;
168
+ }
169
+
170
+ export default executeTopQueries;
@@ -1,7 +1,17 @@
1
- import {createRequestActionTypes, createApiRequest} from '../utils';
1
+ import type {Reducer} from 'redux';
2
+
2
3
  import '../../services/api';
4
+ import type {
5
+ IHeatmapAction,
6
+ IHeatmapApiRequestParams,
7
+ IHeatmapState,
8
+ IHeatmapTabletData,
9
+ } from '../../types/store/heatmap';
10
+
11
+ import {createRequestActionTypes, createApiRequest} from '../utils';
12
+
13
+ export const FETCH_HEATMAP = createRequestActionTypes('heatmap', 'FETCH_HEATMAP');
3
14
 
4
- const FETCH_TABLETS = createRequestActionTypes('heatmap', 'FETCH_TABLETS');
5
15
  const SET_HEATMAP_OPTIONS = 'heatmap/SET_HEATMAP_OPTIONS';
6
16
 
7
17
  export const initialState = {
@@ -12,15 +22,15 @@ export const initialState = {
12
22
  heatmap: false,
13
23
  };
14
24
 
15
- const tablets = function z(state = initialState, action) {
25
+ const heatmap: Reducer<IHeatmapState, IHeatmapAction> = (state = initialState, action) => {
16
26
  switch (action.type) {
17
- case FETCH_TABLETS.REQUEST: {
27
+ case FETCH_HEATMAP.REQUEST: {
18
28
  return {
19
29
  ...state,
20
30
  loading: true,
21
31
  };
22
32
  }
23
- case FETCH_TABLETS.SUCCESS: {
33
+ case FETCH_HEATMAP.SUCCESS: {
24
34
  return {
25
35
  ...state,
26
36
  ...action.data,
@@ -29,7 +39,7 @@ const tablets = function z(state = initialState, action) {
29
39
  error: undefined,
30
40
  };
31
41
  }
32
- case FETCH_TABLETS.FAILURE: {
42
+ case FETCH_HEATMAP.FAILURE: {
33
43
  return {
34
44
  ...state,
35
45
  error: action.error,
@@ -47,16 +57,16 @@ const tablets = function z(state = initialState, action) {
47
57
  }
48
58
  };
49
59
 
50
- export function getTabletsInfo({nodes, path}) {
60
+ export function getTabletsInfo({nodes, path}: IHeatmapApiRequestParams) {
51
61
  return createApiRequest({
52
62
  request: Promise.all([
53
63
  window.api.getTabletsInfo({nodes, path}),
54
64
  window.api.getHeatmapData({path}),
55
65
  ]),
56
- actions: FETCH_TABLETS,
57
- dataHandler: ([tabletsData = [], describe = {}]) => {
66
+ actions: FETCH_HEATMAP,
67
+ dataHandler: ([tabletsData = {}, describe = {}]) => {
58
68
  const {TabletStateInfo: tablets = []} = tabletsData;
59
- const TabletsMap = new Map();
69
+ const TabletsMap: Map<string, IHeatmapTabletData> = new Map();
60
70
  const {PathDescription = {}} = describe;
61
71
  const {
62
72
  TablePartitions = [],
@@ -65,7 +75,9 @@ export function getTabletsInfo({nodes, path}) {
65
75
  } = PathDescription;
66
76
 
67
77
  tablets.forEach((item) => {
68
- TabletsMap.set(item.TabletId, item);
78
+ if (item.TabletId) {
79
+ TabletsMap.set(item.TabletId, item);
80
+ }
69
81
  });
70
82
 
71
83
  TablePartitions.forEach((item, index) => {
@@ -74,15 +86,18 @@ export function getTabletsInfo({nodes, path}) {
74
86
  TablePartitionStats[index],
75
87
  TablePartitionMetrics[index],
76
88
  );
77
- TabletsMap.set(item.DatashardId, {
78
- ...TabletsMap.get(item.DatashardId),
79
- metrics,
80
- });
89
+ if (item.DatashardId) {
90
+ TabletsMap.set(item.DatashardId, {
91
+ ...TabletsMap.get(item.DatashardId),
92
+ metrics,
93
+ });
94
+ }
81
95
  });
82
96
 
83
97
  const preparedTablets = Array.from(TabletsMap.values());
84
98
  const selectMetrics =
85
99
  preparedTablets[0] &&
100
+ preparedTablets[0].metrics &&
86
101
  Object.keys(preparedTablets[0].metrics).map((item) => {
87
102
  return {
88
103
  value: item,
@@ -95,11 +110,11 @@ export function getTabletsInfo({nodes, path}) {
95
110
  });
96
111
  }
97
112
 
98
- export function setHeatmapOptions(options) {
113
+ export function setHeatmapOptions(options: Partial<IHeatmapState>) {
99
114
  return {
100
115
  type: SET_HEATMAP_OPTIONS,
101
116
  data: options,
102
- };
117
+ } as const;
103
118
  }
104
119
 
105
- export default tablets;
120
+ export default heatmap;
@@ -1,11 +1,11 @@
1
1
  import {
2
- defaultUserSettings,
3
2
  ALL,
4
3
  SAVED_QUERIES_KEY,
5
4
  THEME_KEY,
6
5
  TENANT_INITIAL_TAB_KEY,
7
6
  QUERY_INITIAL_RUN_ACTION_KEY,
8
7
  INVERTED_DISKS_KEY,
8
+ ASIDE_HEADER_COMPACT_KEY,
9
9
  } from '../../utils/constants';
10
10
  import '../../services/api';
11
11
  import {getValueFromLS} from '../../utils/utils';
@@ -24,16 +24,26 @@ export function readSavedSettingsValue(key, defaultValue) {
24
24
  return savedValue ?? defaultValue;
25
25
  }
26
26
 
27
+ // navigation managed its compact state internally before, and its approach is not compatible with settings
28
+ // try reading the old localStorage entry to use it as a default value, for backward compatibility
29
+ // assume it is safe to remove this code block if it is at least a few months old
30
+ // there a two of these, search for a similar comment
31
+ let legacyAsideNavCompactState = '';
32
+ try {
33
+ legacyAsideNavCompactState = String(JSON.parse(getValueFromLS('nvAsideHeader')).isCompact);
34
+ localStorage.removeItem('nvAsideHeader');
35
+ } catch {}
36
+
27
37
  export const initialState = {
28
38
  problemFilter: ALL,
29
39
  userSettings: {
30
- ...defaultUserSettings,
31
40
  ...userSettings,
32
41
  [THEME_KEY]: readSavedSettingsValue(THEME_KEY, 'light'),
33
- [INVERTED_DISKS_KEY]: readSavedSettingsValue(INVERTED_DISKS_KEY) === 'true',
42
+ [INVERTED_DISKS_KEY]: readSavedSettingsValue(INVERTED_DISKS_KEY, 'false'),
34
43
  [SAVED_QUERIES_KEY]: readSavedSettingsValue(SAVED_QUERIES_KEY, '[]'),
35
44
  [TENANT_INITIAL_TAB_KEY]: readSavedSettingsValue(TENANT_INITIAL_TAB_KEY),
36
45
  [QUERY_INITIAL_RUN_ACTION_KEY]: readSavedSettingsValue(QUERY_INITIAL_RUN_ACTION_KEY),
46
+ [ASIDE_HEADER_COMPACT_KEY]: readSavedSettingsValue(ASIDE_HEADER_COMPACT_KEY, legacyAsideNavCompactState || 'true'),
37
47
  },
38
48
  systemSettings,
39
49
  };
@@ -12,8 +12,8 @@ import {parseQueryAPIExecuteResponse} from '../../utils/query';
12
12
  import {createRequestActionTypes, createApiRequest} from '../utils';
13
13
 
14
14
  export const SEND_SHARD_QUERY = createRequestActionTypes('query', 'SEND_SHARD_QUERY');
15
- const SET_SHARD_QUERY_OPTIONS = 'query/SET_SHARD_QUERY_OPTIONS';
16
- const SET_TOP_SHARDS_FILTERS = 'shardsWorkload/SET_TOP_SHARDS_FILTERS';
15
+ const SET_SHARD_STATE = 'query/SET_SHARD_STATE';
16
+ const SET_SHARD_QUERY_FILTERS = 'shardsWorkload/SET_SHARD_QUERY_FILTERS';
17
17
 
18
18
  const initialState = {
19
19
  loading: false,
@@ -115,12 +115,12 @@ const shardsWorkload: Reducer<IShardsWorkloadState, IShardsWorkloadAction> = (
115
115
  loading: false,
116
116
  };
117
117
  }
118
- case SET_SHARD_QUERY_OPTIONS:
118
+ case SET_SHARD_STATE:
119
119
  return {
120
120
  ...state,
121
121
  ...action.data,
122
122
  };
123
- case SET_TOP_SHARDS_FILTERS:
123
+ case SET_SHARD_QUERY_FILTERS:
124
124
  return {
125
125
  ...state,
126
126
  filters: {
@@ -151,7 +151,7 @@ export const sendShardQuery = ({database, path = '', sortOrder, filters}: SendSh
151
151
  action: queryAction,
152
152
  },
153
153
  {
154
- concurrentId: 'topShards',
154
+ concurrentId: 'shardsWorkload',
155
155
  },
156
156
  ),
157
157
  actions: SEND_SHARD_QUERY,
@@ -165,16 +165,16 @@ export const sendShardQuery = ({database, path = '', sortOrder, filters}: SendSh
165
165
  }
166
166
  };
167
167
 
168
- export function setShardQueryOptions(options: Partial<IShardsWorkloadState>) {
168
+ export function setShardsState(options: Partial<IShardsWorkloadState>) {
169
169
  return {
170
- type: SET_SHARD_QUERY_OPTIONS,
170
+ type: SET_SHARD_STATE,
171
171
  data: options,
172
172
  } as const;
173
173
  }
174
174
 
175
- export function setTopShardFilters(filters: Partial<IShardsWorkloadFilters>) {
175
+ export function setShardsQueryFilters(filters: Partial<IShardsWorkloadFilters>) {
176
176
  return {
177
- type: SET_TOP_SHARDS_FILTERS,
177
+ type: SET_SHARD_QUERY_FILTERS,
178
178
  filters,
179
179
  } as const;
180
180
  }
@@ -307,6 +307,8 @@ export const getFlatListStorageNodes = createSelector([getStorageNodes], (storag
307
307
  return {
308
308
  NodeId: node.NodeId,
309
309
  FQDN: systemState.Host,
310
+ DataCenter: systemState.DataCenter,
311
+ Rack: systemState.Rack,
310
312
  uptime: calcUptime(systemState.StartTime),
311
313
  StartTime: systemState.StartTime,
312
314
  PDisks: node.PDisks,
@@ -1,7 +1,20 @@
1
- import {createRequestActionTypes, createApiRequest} from '../utils';
1
+ import type {Reducer} from 'redux';
2
2
  import '../../services/api';
3
3
 
4
- const FETCH_TABLETS = createRequestActionTypes('tablets', 'FETCH_TABLETS');
4
+ import type {ETabletState, EType} from '../../types/api/tablet';
5
+ import type {
6
+ ITabletsAction,
7
+ ITabletsApiRequestParams,
8
+ ITabletsState,
9
+ } from '../../types/store/tablets';
10
+
11
+ import {createRequestActionTypes, createApiRequest} from '../utils';
12
+
13
+ export const FETCH_TABLETS = createRequestActionTypes('tablets', 'FETCH_TABLETS');
14
+
15
+ const CLEAR_WAS_LOADING_TABLETS = 'tablets/CLEAR_WAS_LOADING_TABLETS';
16
+ const SET_STATE_FILTER = 'tablets/SET_STATE_FILTER';
17
+ const SET_TYPE_FILTER = 'tablets/SET_TYPE_FILTER';
5
18
 
6
19
  const initialState = {
7
20
  loading: true,
@@ -10,13 +23,12 @@ const initialState = {
10
23
  typeFilter: [],
11
24
  };
12
25
 
13
- const tablets = function z(state = initialState, action) {
26
+ const tablets: Reducer<ITabletsState, ITabletsAction> = (state = initialState, action) => {
14
27
  switch (action.type) {
15
28
  case FETCH_TABLETS.REQUEST: {
16
29
  return {
17
30
  ...state,
18
31
  loading: true,
19
- requestTime: new Date().getTime(),
20
32
  };
21
33
  }
22
34
  case FETCH_TABLETS.SUCCESS: {
@@ -35,20 +47,20 @@ const tablets = function z(state = initialState, action) {
35
47
  loading: false,
36
48
  };
37
49
  }
38
- case 'CLEAR_WAS_LOADING_TABLETS': {
50
+ case CLEAR_WAS_LOADING_TABLETS: {
39
51
  return {
40
52
  ...state,
41
53
  wasLoaded: false,
42
54
  loading: true,
43
55
  };
44
56
  }
45
- case 'SET_STATE_FILTER': {
57
+ case SET_STATE_FILTER: {
46
58
  return {
47
59
  ...state,
48
60
  stateFilter: action.data,
49
61
  };
50
62
  }
51
- case 'SET_TYPE_FILTER': {
63
+ case SET_TYPE_FILTER: {
52
64
  return {
53
65
  ...state,
54
66
  typeFilter: action.data,
@@ -59,25 +71,26 @@ const tablets = function z(state = initialState, action) {
59
71
  }
60
72
  };
61
73
 
62
- export const setStateFilter = (stateFilter) => {
74
+ export const setStateFilter = (stateFilter: ETabletState[]) => {
63
75
  return {
64
- type: 'SET_STATE_FILTER',
76
+ type: SET_STATE_FILTER,
65
77
  data: stateFilter,
66
- };
78
+ } as const;
67
79
  };
68
80
 
69
- export const setTypeFilter = (typeFilter) => {
81
+ export const setTypeFilter = (typeFilter: EType[]) => {
70
82
  return {
71
- type: 'SET_TYPE_FILTER',
83
+ type: SET_TYPE_FILTER,
72
84
  data: typeFilter,
73
- };
85
+ } as const;
74
86
  };
75
87
 
76
- export const clearWasLoadingFlag = () => ({
77
- type: 'CLEAR_WAS_LOADING_TABLETS',
78
- });
88
+ export const clearWasLoadingFlag = () =>
89
+ ({
90
+ type: CLEAR_WAS_LOADING_TABLETS,
91
+ } as const);
79
92
 
80
- export function getTabletsInfo(data) {
93
+ export function getTabletsInfo(data: ITabletsApiRequestParams) {
81
94
  return createApiRequest({
82
95
  request: window.api.getTabletsInfo(data),
83
96
  actions: FETCH_TABLETS,
@@ -48,14 +48,22 @@ const paramSetup = {
48
48
  generalTab: {
49
49
  stateKey: 'tenant.diagnosticsTab',
50
50
  },
51
- topShardsFrom: {
51
+ shardsDateFrom: {
52
52
  stateKey: 'shardsWorkload.filters.from',
53
53
  type: 'number',
54
54
  },
55
- topShardsTo: {
55
+ shardsDateTo: {
56
56
  stateKey: 'shardsWorkload.filters.to',
57
57
  type: 'number',
58
58
  },
59
+ topQueriesDateFrom: {
60
+ stateKey: 'executeTopQueries.filters.from',
61
+ type: 'number',
62
+ },
63
+ topQueriesDateTo: {
64
+ stateKey: 'executeTopQueries.filters.to',
65
+ type: 'number',
66
+ },
59
67
  },
60
68
  };
61
69
 
@@ -0,0 +1,52 @@
1
+ import {EFlag} from './enums';
2
+ import {TEndpoint, TLegacyNodeLocation, TPoolStats} from './nodes';
3
+ import {TMetrics} from './tenant';
4
+
5
+ // endpoint: viewer/json/compute
6
+ // source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
7
+
8
+ export interface TComputeInfo {
9
+ Overall: EFlag;
10
+ Tenants?: TComputeTenantInfo[];
11
+ Errors?: string[];
12
+ }
13
+
14
+ interface TComputeTenantInfo {
15
+ Overall: EFlag;
16
+ Name: string;
17
+ Nodes?: TComputeNodeInfo[];
18
+ }
19
+
20
+ interface TComputeNodeInfo {
21
+ /** uint64 */
22
+ StartTime: string;
23
+ /** uint64 */
24
+ ChangeTime: string;
25
+ SystemLocation: TLegacyNodeLocation;
26
+ /** double */
27
+ LoadAverage: number[];
28
+ NumberOfCpus: number;
29
+ Overall: EFlag;
30
+ NodeId: number;
31
+ DataCenter: string;
32
+ Rack: string;
33
+ Host: string;
34
+ Version: string;
35
+ PoolStats?: TPoolStats[];
36
+ Endpoints?: TEndpoint[];
37
+ Roles?: string[];
38
+ /** uint64 */
39
+ MemoryUsed?: string;
40
+ /** uint64 */
41
+ MemoryLimit?: string;
42
+ Metrics: TMetrics;
43
+ Tablets?: TTabletStateInfo[];
44
+ }
45
+
46
+ // Tablets in compute nodes
47
+ // Types for tabletInfo and tablets inside nodes and storage endpoints are in tablet.ts
48
+ export interface TTabletStateInfo {
49
+ Type: string;
50
+ State: EFlag;
51
+ Count: number;
52
+ }