ydb-embedded-ui 3.4.0 → 3.4.2

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 (70) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/components/BasicNodeViewer/BasicNodeViewer.tsx +2 -3
  3. package/dist/components/ClusterInfo/ClusterInfo.tsx +14 -36
  4. package/dist/components/CopyToClipboard/CopyToClipboard.tsx +1 -2
  5. package/dist/components/CriticalActionDialog/CriticalActionDialog.js +1 -1
  6. package/dist/components/EmptyState/{EmptyState.js → EmptyState.tsx} +12 -15
  7. package/dist/components/EmptyState/index.ts +1 -0
  8. package/dist/components/EnableFullscreenButton/EnableFullscreenButton.tsx +7 -2
  9. package/dist/components/Errors/403/AccessDenied.tsx +1 -1
  10. package/dist/components/Fullscreen/Fullscreen.tsx +1 -1
  11. package/dist/components/Icon/Icon.tsx +33 -0
  12. package/dist/components/Icon/index.ts +1 -0
  13. package/dist/components/Pagination/Pagination.js +1 -1
  14. package/dist/components/QueryExecutionStatus/QueryExecutionStatus.tsx +1 -1
  15. package/dist/components/Tablet/Tablet.tsx +59 -0
  16. package/dist/components/Tablet/index.ts +1 -0
  17. package/dist/components/Tag/Tag.tsx +16 -0
  18. package/dist/components/Tag/index.ts +1 -0
  19. package/dist/components/Tags/Tags.tsx +22 -0
  20. package/dist/components/Tags/index.ts +1 -0
  21. package/dist/containers/Header/Header.tsx +2 -3
  22. package/dist/containers/Header/Host/Host.js +1 -1
  23. package/dist/containers/Node/NodeStructure/Pdisk.tsx +1 -1
  24. package/dist/containers/Nodes/getNodesColumns.tsx +1 -1
  25. package/dist/containers/Storage/EmptyFilter/EmptyFilter.tsx +8 -9
  26. package/dist/containers/Storage/PDisk/PDisk.scss +15 -0
  27. package/dist/containers/Storage/PDisk/PDisk.tsx +38 -13
  28. package/dist/containers/Storage/StorageNodes/StorageNodes.scss +4 -2
  29. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +1 -0
  30. package/dist/containers/Tablet/Tablet.js +6 -6
  31. package/dist/containers/Tablets/Tablets.scss +0 -4
  32. package/dist/containers/Tablets/Tablets.tsx +1 -2
  33. package/dist/containers/TabletsFilters/TabletsFilters.js +1 -1
  34. package/dist/containers/Tenant/Diagnostics/Consumers/TopicStats/ConsumersTopicStats.scss +1 -1
  35. package/dist/containers/Tenant/Diagnostics/Consumers/columns/columns.tsx +27 -1
  36. package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.tsx +1 -2
  37. package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +1 -1
  38. package/dist/containers/Tenant/Diagnostics/Network/Network.js +1 -1
  39. package/dist/containers/Tenant/Diagnostics/Partitions/Partitions.tsx +17 -13
  40. package/dist/containers/Tenant/Diagnostics/Partitions/PartitionsWrapper.tsx +2 -0
  41. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +1 -1
  42. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +1 -1
  43. package/dist/containers/Tenant/Preview/Preview.js +1 -1
  44. package/dist/containers/Tenant/QueryEditor/QueryEditor.js +1 -1
  45. package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.js +1 -1
  46. package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.js +1 -1
  47. package/dist/containers/Tenant/TenantPages.tsx +1 -2
  48. package/dist/containers/Tenant/utils/paneVisibilityToggleHelpers.tsx +2 -2
  49. package/dist/services/api.d.ts +11 -0
  50. package/dist/services/api.js +3 -3
  51. package/dist/store/reducers/consumer.ts +14 -0
  52. package/dist/store/reducers/{host.js → host.ts} +9 -5
  53. package/dist/store/reducers/shardsWorkload.ts +4 -0
  54. package/dist/store/reducers/tablet.ts +111 -0
  55. package/dist/store/reducers/topic.ts +13 -0
  56. package/dist/store/state-url-mapping.js +3 -0
  57. package/dist/types/api/cluster.ts +34 -0
  58. package/dist/types/api/systemState.ts +13 -0
  59. package/dist/types/api/tablet.ts +12 -4
  60. package/dist/types/store/consumer.ts +10 -2
  61. package/dist/types/store/host.ts +23 -0
  62. package/dist/types/store/tablet.ts +50 -0
  63. package/dist/types/store/tooltip.ts +3 -1
  64. package/dist/types/store/topic.ts +3 -2
  65. package/package.json +7 -5
  66. package/dist/components/Icon/Icon.js +0 -28
  67. package/dist/components/Tablet/Tablet.js +0 -61
  68. package/dist/components/Tag/Tag.js +0 -14
  69. package/dist/components/Tags/Tags.js +0 -36
  70. package/dist/store/reducers/tablet.js +0 -94
@@ -27,10 +27,6 @@
27
27
  max-width: 180px;
28
28
  }
29
29
 
30
- &__tablet {
31
- margin-bottom: 2px;
32
- }
33
-
34
30
  .tablet {
35
31
  display: inline-block;
36
32
 
@@ -5,7 +5,7 @@ import ReactList from 'react-list';
5
5
 
6
6
  import {Select} from '@gravity-ui/uikit';
7
7
 
8
- import Tablet from '../../components/Tablet/Tablet';
8
+ import {Tablet} from '../../components/Tablet';
9
9
  import TabletsOverall from '../../components/TabletsOverall/TabletsOverall';
10
10
  import {Loader} from '../../components/Loader';
11
11
 
@@ -104,7 +104,6 @@ export const Tablets = ({path, nodeId, className}: TabletsProps) => {
104
104
  onMouseEnter={onShowTooltip}
105
105
  tablet={tabletsToRender[tabletIndex]}
106
106
  key={tabletIndex}
107
- className={b('tablet')}
108
107
  />
109
108
  );
110
109
  };
@@ -8,7 +8,7 @@ import _ from 'lodash';
8
8
  import {Loader, Select} from '@gravity-ui/uikit';
9
9
  import ReactList from 'react-list';
10
10
 
11
- import Tablet from '../../components/Tablet/Tablet';
11
+ import {Tablet} from '../../components/Tablet';
12
12
  import {AccessDenied} from '../../components/Errors/403';
13
13
 
14
14
  import {tabletColorToTabletState, tabletStates} from '../../utils/tablet';
@@ -24,7 +24,7 @@
24
24
  }
25
25
  &__value {
26
26
  display: flex;
27
- justify-content: flex-end;
27
+ justify-content: flex-start;
28
28
  align-items: center;
29
29
 
30
30
  height: 30px;
@@ -1,9 +1,15 @@
1
1
  import DataTable, {Column} from '@gravity-ui/react-data-table';
2
2
  import block from 'bem-cn-lite';
3
+ import qs from 'qs';
3
4
 
4
5
  import type {IPreparedConsumerData} from '../../../../../types/store/topic';
5
6
  import {SpeedMultiMeter} from '../../../../../components/SpeedMultiMeter';
7
+ import {InternalLink} from '../../../../../components/InternalLink';
6
8
  import {formatMsToUptime} from '../../../../../utils';
9
+ import routes, {createHref} from '../../../../../routes';
10
+
11
+ import {TenantTabsGroups} from '../../../TenantPages';
12
+ import {GeneralPagesIds} from '../../DiagnosticsPages';
7
13
 
8
14
  import {
9
15
  CONSUMERS_COLUMNS_IDS,
@@ -23,7 +29,27 @@ export const columns: Column<IPreparedConsumerData>[] = [
23
29
  name: CONSUMERS_COLUMNS_IDS.CONSUMER,
24
30
  header: CONSUMERS_COLUMNS_TITILES[CONSUMERS_COLUMNS_IDS.CONSUMER],
25
31
  align: DataTable.LEFT,
26
- render: ({row}) => row.name || '-',
32
+ render: ({row}) => {
33
+ if (!row.name) {
34
+ return '–';
35
+ }
36
+
37
+ const queryParams = qs.parse(location.search, {
38
+ ignoreQueryPrefix: true,
39
+ });
40
+
41
+ return (
42
+ <InternalLink
43
+ to={createHref(routes.tenant, undefined, {
44
+ ...queryParams,
45
+ [TenantTabsGroups.generalTab]: GeneralPagesIds.partitions,
46
+ selectedConsumer: row.name,
47
+ })}
48
+ >
49
+ {row.name}
50
+ </InternalLink>
51
+ );
52
+ },
27
53
  },
28
54
  {
29
55
  name: CONSUMERS_COLUMNS_IDS.READ_SPEED,
@@ -5,8 +5,7 @@ import cn from 'bem-cn-lite';
5
5
  import {Button, Modal} from '@gravity-ui/uikit';
6
6
 
7
7
  import type {EPathType} from '../../../../types/api/schema';
8
- //@ts-ignore
9
- import Icon from '../../../../components/Icon/Icon';
8
+ import {Icon} from '../../../../components/Icon';
10
9
  import Overview from '../Overview/Overview';
11
10
  import {Healthcheck} from '../Healthcheck';
12
11
  //@ts-ignore
@@ -4,7 +4,7 @@ import {connect} from 'react-redux';
4
4
  import {Loader} from '@gravity-ui/uikit';
5
5
  import DataTable from '@gravity-ui/react-data-table';
6
6
 
7
- import Icon from '../../../../components/Icon/Icon';
7
+ import {Icon} from '../../../../components/Icon';
8
8
 
9
9
  import {AutoFetcher} from '../../../../utils/autofetcher';
10
10
  import {getHotKeys, setHotKeysOptions} from '../../../../store/reducers/hotKeys';
@@ -8,7 +8,7 @@ import {Link} from 'react-router-dom';
8
8
  import {Loader, Checkbox} from '@gravity-ui/uikit';
9
9
 
10
10
  import NodeNetwork from './NodeNetwork/NodeNetwork';
11
- import Icon from '../../../../components/Icon/Icon';
11
+ import {Icon} from '../../../../components/Icon';
12
12
  import {ProblemFilter} from '../../../../components/ProblemFilter';
13
13
  import {Illustration} from '../../../../components/Illustration';
14
14
 
@@ -17,6 +17,7 @@ import {
17
17
  getConsumer,
18
18
  selectPreparedPartitionsData,
19
19
  setDataWasNotLoaded,
20
+ setSelectedConsumer,
20
21
  } from '../../../../store/reducers/consumer';
21
22
 
22
23
  import {TableSkeleton} from '../../../../components/TableSkeleton/TableSkeleton';
@@ -52,14 +53,15 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
52
53
 
53
54
  const dispatch = useDispatch();
54
55
 
55
- const [selectedConsumer, setSelectedConsumer] = useState<string[]>();
56
56
  const [generalSearchValue, setGeneralSearchValue] = useState('');
57
57
  const [partitionIdSearchValue, setPartitionIdSearchValue] = useState('');
58
58
 
59
59
  const [componentCurrentPath, setComponentCurrentPath] = useState(path);
60
60
 
61
61
  const {autorefresh} = useTypedSelector((state) => state.schema);
62
- const {loading, wasLoaded, error} = useTypedSelector((state) => state.consumer);
62
+ const {loading, wasLoaded, error, selectedConsumer} = useTypedSelector(
63
+ (state) => state.consumer,
64
+ );
63
65
 
64
66
  const partitions = useTypedSelector((state) => selectPreparedPartitionsData(state));
65
67
 
@@ -70,7 +72,7 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
70
72
  useEffect(() => {
71
73
  // Manual path control to ensure it updates with other values so no request with wrong params will be sent
72
74
  setComponentCurrentPath(path);
73
- }, [path]);
75
+ }, [dispatch, path]);
74
76
 
75
77
  const fetchConsumerData = useCallback(
76
78
  (isBackground: boolean) => {
@@ -78,11 +80,11 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
78
80
  dispatch(setDataWasNotLoaded());
79
81
  }
80
82
 
81
- if (selectedConsumer && selectedConsumer.length) {
82
- dispatch(getConsumer(componentCurrentPath, selectedConsumer[0]));
83
+ if (selectedConsumer && consumers && consumers.includes(selectedConsumer)) {
84
+ dispatch(getConsumer(componentCurrentPath, selectedConsumer));
83
85
  }
84
86
  },
85
- [dispatch, selectedConsumer, componentCurrentPath],
87
+ [dispatch, selectedConsumer, componentCurrentPath, consumers],
86
88
  );
87
89
 
88
90
  useAutofetcher(fetchConsumerData, [fetchConsumerData], autorefresh);
@@ -99,12 +101,13 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
99
101
  );
100
102
 
101
103
  useEffect(() => {
102
- if (consumersToSelect && consumersToSelect.length) {
103
- setSelectedConsumer([consumersToSelect[0].value]);
104
- } else {
105
- setSelectedConsumer(undefined);
104
+ const shouldUpdateSelectedConsumer =
105
+ !selectedConsumer || (consumers && !consumers.includes(selectedConsumer));
106
+
107
+ if (consumersToSelect && consumersToSelect.length && shouldUpdateSelectedConsumer) {
108
+ dispatch(setSelectedConsumer(consumersToSelect[0].value));
106
109
  }
107
- }, [consumersToSelect]);
110
+ }, [dispatch, consumersToSelect, selectedConsumer, consumers]);
108
111
 
109
112
  const selectedColumns: string[] = useMemo(
110
113
  () =>
@@ -183,7 +186,7 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
183
186
  };
184
187
 
185
188
  const handleConsumerSelectChange = (value: string[]) => {
186
- setSelectedConsumer(value);
189
+ dispatch(setSelectedConsumer(value[0]));
187
190
  };
188
191
 
189
192
  const handlePartitionIdSearchChange = (value: string) => {
@@ -210,8 +213,9 @@ export const Partitions = ({path, type, nodes, consumers}: PartitionsProps) => {
210
213
  placeholder={i18n('controls.consumerSelector.placeholder')}
211
214
  label={i18n('controls.consumerSelector')}
212
215
  options={consumersToSelect}
213
- value={selectedConsumer}
216
+ value={[selectedConsumer || '']}
214
217
  onUpdate={handleConsumerSelectChange}
218
+ filterable={consumers && consumers.length > 5}
215
219
  />
216
220
  <Search
217
221
  onChange={handlePartitionIdSearchChange}
@@ -6,6 +6,7 @@ import type {EPathType} from '../../../../types/api/schema';
6
6
  import {useTypedSelector} from '../../../../utils/hooks';
7
7
 
8
8
  import {
9
+ cleanTopicData,
9
10
  getTopic,
10
11
  setDataWasNotLoaded as setTopicDataWasNotLoaded,
11
12
  } from '../../../../store/reducers/topic';
@@ -61,6 +62,7 @@ export const PartitionsWrapper = ({path, type}: PartitionsWrapperProps) => {
61
62
 
62
63
  useEffect(() => {
63
64
  dispatch(setTopicDataWasNotLoaded());
65
+ dispatch(cleanTopicData());
64
66
  dispatch(setNodesDataWasNotLoaded());
65
67
 
66
68
  dispatch(getTopic(path));
@@ -7,7 +7,7 @@ import {Loader} from '@gravity-ui/uikit';
7
7
  import EntityStatus from '../../../../components/EntityStatus/EntityStatus';
8
8
  import InfoViewer from '../../../../components/InfoViewer/InfoViewer';
9
9
  import PoolUsage from '../../../../components/PoolUsage/PoolUsage';
10
- import Tablet from '../../../../components/Tablet/Tablet';
10
+ import {Tablet} from '../../../../components/Tablet';
11
11
 
12
12
  import {hideTooltip, showTooltip} from '../../../../store/reducers/tooltip';
13
13
  import {getTenantInfo} from '../../../../store/reducers/tenant';
@@ -18,7 +18,7 @@ import {
18
18
  CDCStreamOverview,
19
19
  PersQueueGroupOverview,
20
20
  } from '../../../components/InfoViewer/schemaOverview';
21
- import Icon from '../../../components/Icon/Icon';
21
+ import {Icon} from '../../../components/Icon';
22
22
 
23
23
  import {
24
24
  EPathSubType,
@@ -5,7 +5,7 @@ import cn from 'bem-cn-lite';
5
5
 
6
6
  import {Loader, Button} from '@gravity-ui/uikit';
7
7
 
8
- import Icon from '../../../components/Icon/Icon';
8
+ import {Icon} from '../../../components/Icon';
9
9
  import Fullscreen from '../../../components/Fullscreen/Fullscreen';
10
10
  import {QueryResultTable} from '../../../components/QueryResultTable';
11
11
 
@@ -11,7 +11,7 @@ import {QueryResultTable} from '../../../components/QueryResultTable';
11
11
 
12
12
  import SaveQuery from './SaveQuery/SaveQuery';
13
13
  import SavedQueries from './SavedQueries/SavedQueries';
14
- import Icon from '../../../components/Icon/Icon';
14
+ import {Icon} from '../../../components/Icon';
15
15
  import QueryResult from './QueryResult/QueryResult';
16
16
  import QueryExplain from './QueryExplain/QueryExplain';
17
17
 
@@ -4,7 +4,7 @@ import cn from 'bem-cn-lite';
4
4
  import {Dialog, Popup, Button} from '@gravity-ui/uikit';
5
5
 
6
6
  import TruncatedQuery from '../../../../components/TruncatedQuery/TruncatedQuery';
7
- import Icon from '../../../../components/Icon/Icon';
7
+ import {Icon} from '../../../../components/Icon';
8
8
  import './SavedQueries.scss';
9
9
  import {setQueryNameToEdit} from '../../../../store/reducers/saveQuery';
10
10
  import {useDispatch} from 'react-redux';
@@ -4,7 +4,7 @@ import cn from 'bem-cn-lite';
4
4
 
5
5
  import find from 'lodash/find';
6
6
 
7
- import Icon from '../../../../components/Icon/Icon';
7
+ import {Icon} from '../../../../components/Icon';
8
8
  import DataTable from '@gravity-ui/react-data-table';
9
9
  import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants';
10
10
  import './SchemaViewer.scss';
@@ -1,5 +1,4 @@
1
- //@ts-ignore
2
- import Icon from '../../components/Icon/Icon';
1
+ import {Icon} from '../../components/Icon';
3
2
 
4
3
  export enum TenantGeneralTabsIds {
5
4
  query = 'query',
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import {Button} from '@gravity-ui/uikit';
3
3
  import cn from 'bem-cn-lite';
4
- //@ts-ignore
5
- import Icon from '../../../components/Icon/Icon';
4
+
5
+ import {Icon} from '../../../components/Icon';
6
6
 
7
7
  import './ToggleButton.scss';
8
8
 
@@ -52,10 +52,20 @@ interface Window {
52
52
  getTenantInfo: (params: {
53
53
  path: string;
54
54
  }) => Promise<import('../types/api/tenant').TTenantInfo>;
55
+ getClusterInfo: () => Promise<import('../types/api/cluster').TClusterInfo>;
55
56
  getTabletsInfo: (params: {
56
57
  nodes?: string[];
57
58
  path?: string;
58
59
  }) => Promise<import('../types/api/tablet').TEvTabletStateResponse>;
60
+ getTabletDescribe: (
61
+ tenantId?: import('../types/api/tablet').TDomainKey,
62
+ ) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
63
+ getTablet: (params: {
64
+ id?: string;
65
+ }) => Promise<import('../types/api/tablet').TEvTabletStateResponse>;
66
+ getTabletHistory: (params: {
67
+ id?: string;
68
+ }) => Promise<import('../types/api/tablet').UnmergedTEvTabletStateResponse>;
59
69
  getHeatmapData: (params: {
60
70
  path: string;
61
71
  }) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
@@ -66,6 +76,7 @@ interface Window {
66
76
  path?: string;
67
77
  consumer?: string;
68
78
  }) => Promise<import('../types/api/consumer').DescribeConsumerResult>;
79
+ getHostInfo: () => Promise<import('../types/api/systemState').TEvSystemStateResponse>;
69
80
  [method: string]: Function;
70
81
  };
71
82
  }
@@ -247,10 +247,10 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
247
247
  this.getPath(`/tablets/app?TabletID=${hiveId}&page=ResumeTablet&tablet=${id}`),
248
248
  );
249
249
  }
250
- getTabletDescribe(TenantId) {
250
+ getTabletDescribe(tenantId) {
251
251
  return this.get(this.getPath('/viewer/json/describe'), {
252
- schemeshard_id: TenantId.SchemeShard,
253
- path_id: TenantId.PathId,
252
+ schemeshard_id: tenantId?.SchemeShard,
253
+ path_id: tenantId?.PathId,
254
254
  });
255
255
  }
256
256
  postSetting(name, value) {
@@ -20,6 +20,7 @@ import {createRequestActionTypes, createApiRequest} from '../utils';
20
20
  export const FETCH_CONSUMER = createRequestActionTypes('consumer', 'FETCH_CONSUMER');
21
21
 
22
22
  const SET_DATA_WAS_NOT_LOADED = 'consumer/SET_DATA_WAS_NOT_LOADED';
23
+ const SET_SELECTED_CONSUMER = 'consumer/SET_SELECTED_CONSUMER';
23
24
 
24
25
  const initialState = {
25
26
  loading: false,
@@ -66,6 +67,12 @@ const consumer: Reducer<IConsumerState, IConsumerAction> = (state = initialState
66
67
  wasLoaded: false,
67
68
  };
68
69
  }
70
+ case SET_SELECTED_CONSUMER: {
71
+ return {
72
+ ...state,
73
+ selectedConsumer: action.data,
74
+ };
75
+ }
69
76
  default:
70
77
  return state;
71
78
  }
@@ -77,6 +84,13 @@ export const setDataWasNotLoaded = () => {
77
84
  } as const;
78
85
  };
79
86
 
87
+ export const setSelectedConsumer = (value?: string) => {
88
+ return {
89
+ type: SET_SELECTED_CONSUMER,
90
+ data: value,
91
+ } as const;
92
+ };
93
+
80
94
  export function getConsumer(path?: string, consumerName?: string) {
81
95
  return createApiRequest({
82
96
  request: window.api.getConsumer({path, consumer: consumerName}),
@@ -1,11 +1,15 @@
1
- import {createRequestActionTypes, createApiRequest} from '../utils';
1
+ import type {Reducer} from 'redux';
2
+
3
+ import type {IHostAction, IHostState} from '../../types/store/host';
2
4
  import '../../services/api';
3
5
 
4
- const FETCH_HOST = createRequestActionTypes('host', 'FETCH_HOST');
6
+ import {createRequestActionTypes, createApiRequest} from '../utils';
7
+
8
+ export const FETCH_HOST = createRequestActionTypes('host', 'FETCH_HOST');
5
9
 
6
10
  const initialState = {loading: true, wasLoaded: false, data: {}};
7
11
 
8
- const cluster = function (state = initialState, action) {
12
+ const host: Reducer<IHostState, IHostAction> = (state = initialState, action) => {
9
13
  switch (action.type) {
10
14
  case FETCH_HOST.REQUEST: {
11
15
  return {
@@ -16,7 +20,7 @@ const cluster = function (state = initialState, action) {
16
20
  case FETCH_HOST.SUCCESS: {
17
21
  return {
18
22
  ...state,
19
- data: action.data.SystemStateInfo[0],
23
+ data: action.data.SystemStateInfo?.[0],
20
24
  loading: false,
21
25
  wasLoaded: true,
22
26
  error: undefined,
@@ -41,4 +45,4 @@ export function getHostInfo() {
41
45
  });
42
46
  }
43
47
 
44
- export default cluster;
48
+ export default host;
@@ -133,6 +133,10 @@ const shardsWorkload: Reducer<IShardsWorkloadState, IShardsWorkloadAction> = (
133
133
  }
134
134
  // 401 Unauthorized error is handled by GenericAPI
135
135
  case SEND_SHARD_QUERY.FAILURE: {
136
+ if (action.error?.isCancelled) {
137
+ return state;
138
+ }
139
+
136
140
  return {
137
141
  ...state,
138
142
  error: action.error || 'Unauthorized',
@@ -0,0 +1,111 @@
1
+ import type {Reducer} from 'redux';
2
+
3
+ import type {TDomainKey} from '../../types/api/tablet';
4
+ import type {
5
+ ITabletAction,
6
+ ITabletDescribeHandledResponse,
7
+ ITabletHandledResponse,
8
+ ITabletPreparedHistoryItem,
9
+ ITabletState,
10
+ } from '../../types/store/tablet';
11
+ import '../../services/api';
12
+
13
+ import {createRequestActionTypes, createApiRequest} from '../utils';
14
+
15
+ export const FETCH_TABLET = createRequestActionTypes('TABLET', 'FETCH_TABLET');
16
+ export const FETCH_TABLET_DESCRIBE = createRequestActionTypes('TABLET', 'FETCH_TABLET_DESCRIBE');
17
+
18
+ const initialState = {
19
+ loading: false,
20
+ tenantPath: '-',
21
+ };
22
+
23
+ const tablet: Reducer<ITabletState, ITabletAction> = (state = initialState, action) => {
24
+ switch (action.type) {
25
+ case FETCH_TABLET.REQUEST: {
26
+ return {
27
+ ...state,
28
+ loading: true,
29
+ };
30
+ }
31
+ case FETCH_TABLET.SUCCESS: {
32
+ const {tabletData, historyData} = action.data;
33
+ const {TabletId: id} = tabletData;
34
+ return {
35
+ ...state,
36
+ id,
37
+ data: tabletData,
38
+ history: historyData,
39
+ loading: false,
40
+ error: undefined,
41
+ };
42
+ }
43
+ case FETCH_TABLET.FAILURE: {
44
+ return {
45
+ ...state,
46
+ error: action.error,
47
+ loading: false,
48
+ };
49
+ }
50
+ case FETCH_TABLET_DESCRIBE.SUCCESS: {
51
+ const {tenantPath} = action.data;
52
+
53
+ return {
54
+ ...state,
55
+ tenantPath,
56
+ error: undefined,
57
+ };
58
+ }
59
+ default:
60
+ return state;
61
+ }
62
+ };
63
+
64
+ export const getTablet = (id: string) => {
65
+ return createApiRequest({
66
+ request: Promise.all([window.api.getTablet({id}), window.api.getTabletHistory({id})]),
67
+ actions: FETCH_TABLET,
68
+ dataHandler: ([tabletResponseData, historyResponseData]): ITabletHandledResponse => {
69
+ const historyData = Object.keys(historyResponseData).reduce<
70
+ ITabletPreparedHistoryItem[]
71
+ >((list, nodeId) => {
72
+ const tabletInfo = historyResponseData[nodeId]?.TabletStateInfo;
73
+ if (tabletInfo && tabletInfo.length) {
74
+ const leaderTablet = tabletInfo.find((t) => t.Leader) || tabletInfo[0];
75
+
76
+ const {ChangeTime, Generation, State, Leader, FollowerId} = leaderTablet;
77
+
78
+ list.push({
79
+ nodeId,
80
+ generation: Generation,
81
+ changeTime: ChangeTime,
82
+ state: State,
83
+ leader: Leader,
84
+ followerId: FollowerId,
85
+ });
86
+ }
87
+ return list;
88
+ }, []);
89
+
90
+ const {TabletStateInfo = []} = tabletResponseData;
91
+ const [tabletData = {}] = TabletStateInfo;
92
+
93
+ return {tabletData, historyData};
94
+ },
95
+ });
96
+ };
97
+
98
+ export const getTabletDescribe = (tenantId: TDomainKey = {}) => {
99
+ return createApiRequest({
100
+ request: window.api.getTabletDescribe(tenantId),
101
+ actions: FETCH_TABLET_DESCRIBE,
102
+ dataHandler: (tabletDescribe): ITabletDescribeHandledResponse => {
103
+ const {SchemeShard, PathId} = tenantId;
104
+ const tenantPath = tabletDescribe.Path || `${SchemeShard}:${PathId}`;
105
+
106
+ return {tenantPath};
107
+ },
108
+ });
109
+ };
110
+
111
+ export default tablet;
@@ -18,6 +18,7 @@ import {convertBytesObjectToSpeed} from '../../utils/bytesParsers';
18
18
  export const FETCH_TOPIC = createRequestActionTypes('topic', 'FETCH_TOPIC');
19
19
 
20
20
  const SET_DATA_WAS_NOT_LOADED = 'topic/SET_DATA_WAS_NOT_LOADED';
21
+ const CLEAN_TOPIC_DATA = 'topic/CLEAN_TOPIC_DATA';
21
22
 
22
23
  const initialState = {
23
24
  loading: true,
@@ -64,6 +65,12 @@ const topic: Reducer<ITopicState, ITopicAction> = (state = initialState, action)
64
65
  wasLoaded: false,
65
66
  };
66
67
  }
68
+ case CLEAN_TOPIC_DATA: {
69
+ return {
70
+ ...state,
71
+ data: undefined,
72
+ };
73
+ }
67
74
  default:
68
75
  return state;
69
76
  }
@@ -75,6 +82,12 @@ export const setDataWasNotLoaded = () => {
75
82
  } as const;
76
83
  };
77
84
 
85
+ export const cleanTopicData = () => {
86
+ return {
87
+ type: CLEAN_TOPIC_DATA,
88
+ } as const;
89
+ };
90
+
78
91
  export function getTopic(path?: string) {
79
92
  return createApiRequest({
80
93
  request: window.api.getTopic({path}),
@@ -67,6 +67,9 @@ const paramSetup = {
67
67
  stateKey: 'executeTopQueries.filters.to',
68
68
  type: 'number',
69
69
  },
70
+ selectedConsumer: {
71
+ stateKey: 'consumer.selectedConsumer',
72
+ },
70
73
  },
71
74
  };
72
75
 
@@ -0,0 +1,34 @@
1
+ import type {EFlag} from './enums';
2
+ import type {TTabletStateInfo} from './tablet';
3
+
4
+ /**
5
+ * endpoint: viewer/json/cluster
6
+ *
7
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/viewer/protos/viewer.proto
8
+ */
9
+ export interface TClusterInfo {
10
+ Name?: string;
11
+ Overall?: EFlag;
12
+ NodesTotal?: number;
13
+ NodesAlive?: number;
14
+ NumberOfCpus?: number;
15
+ /** double */
16
+ LoadAverage?: number;
17
+ /** uint64 */
18
+ MemoryTotal?: string;
19
+ /** uint64 */
20
+ MemoryUsed?: string;
21
+ /** uint64 */
22
+ StorageTotal?: string;
23
+ /** uint64 */
24
+ StorageUsed?: string;
25
+ DataCenters?: string[];
26
+ Versions?: string[];
27
+ SystemTablets?: TTabletStateInfo[];
28
+ /** uint64 */
29
+ Hosts?: string;
30
+ /** uint64 */
31
+ Tenants?: string;
32
+ /** uint64 */
33
+ Tablets?: string;
34
+ }
@@ -0,0 +1,13 @@
1
+ import {TSystemStateInfo} from './nodes';
2
+
3
+ /**
4
+ * endpoint: /viewer/json/sysinfo
5
+ *
6
+ * source: https://github.com/ydb-platform/ydb/blob/main/ydb/core/protos/node_whiteboard.proto
7
+ */
8
+ export interface TEvSystemStateResponse {
9
+ SystemStateInfo?: TSystemStateInfo[];
10
+ /** uint64 */
11
+ ResponseTime?: string;
12
+ ResponseDuration?: number;
13
+ }