ydb-embedded-ui 4.5.0 → 4.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/CriticalActionDialog/CriticalActionDialog.tsx +3 -0
  3. package/dist/components/FullNodeViewer/FullNodeViewer.js +1 -1
  4. package/dist/components/PoolUsage/PoolUsage.scss +1 -1
  5. package/dist/components/PoolUsage/PoolUsage.tsx +50 -0
  6. package/dist/containers/Node/Node.tsx +1 -1
  7. package/dist/containers/Node/NodeStructure/NodeStructure.tsx +19 -17
  8. package/dist/containers/Tablet/Tablet.scss +4 -0
  9. package/dist/containers/Tablet/Tablet.tsx +2 -1
  10. package/dist/containers/Tablet/TabletControls/TabletControls.tsx +19 -27
  11. package/dist/containers/Tenant/Diagnostics/Consumers/columns/columns.tsx +2 -2
  12. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +37 -38
  13. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +15 -28
  14. package/dist/containers/Tenant/Diagnostics/Network/Network.js +2 -2
  15. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +3 -3
  16. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +5 -3
  17. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +2 -3
  18. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +3 -3
  19. package/dist/containers/Tenant/Tenant.tsx +14 -15
  20. package/dist/containers/Tenant/TenantPages.tsx +3 -6
  21. package/dist/containers/Tenant/utils/schemaActions.ts +4 -4
  22. package/dist/containers/Versions/GroupedNodesTree/GroupedNodesTree.scss +1 -0
  23. package/dist/containers/Versions/NodesTable/NodesTable.tsx +2 -3
  24. package/dist/routes.ts +1 -1
  25. package/dist/services/api.ts +2 -2
  26. package/dist/store/reducers/index.ts +4 -4
  27. package/dist/store/reducers/{network.js → network/network.ts} +11 -8
  28. package/dist/store/reducers/network/types.ts +16 -0
  29. package/dist/store/reducers/node/node.ts +102 -0
  30. package/dist/store/reducers/node/selectors.ts +59 -0
  31. package/dist/store/reducers/node/types.ts +44 -0
  32. package/dist/store/reducers/{schemaAcl.js → schemaAcl/schemaAcl.ts} +20 -9
  33. package/dist/store/reducers/schemaAcl/types.ts +15 -0
  34. package/dist/store/reducers/tenant/constants.ts +19 -0
  35. package/dist/store/reducers/{tenant.js → tenant/tenant.ts} +27 -36
  36. package/dist/store/reducers/tenant/types.ts +25 -0
  37. package/dist/types/api/acl.ts +1 -1
  38. package/dist/utils/index.js +2 -1
  39. package/package.json +2 -1
  40. package/dist/components/Breadcrumbs/Breadcrumbs.js +0 -25
  41. package/dist/components/Breadcrumbs/Breadcrumbs.scss +0 -5
  42. package/dist/components/Collapse/Collapse.js +0 -84
  43. package/dist/components/Collapse/Collapse.scss +0 -70
  44. package/dist/components/PoolUsage/PoolUsage.js +0 -54
  45. package/dist/store/reducers/node.js +0 -141
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.5.2](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.5.1...v4.5.2) (2023-06-06)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **Versions:** enable table dynamic render ([#416](https://github.com/ydb-platform/ydb-embedded-ui/issues/416)) ([3c877ea](https://github.com/ydb-platform/ydb-embedded-ui/commit/3c877ea88a0c4036213b38099676f473cf3ac2d6))
9
+
10
+ ## [4.5.1](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.5.0...v4.5.1) (2023-06-02)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **Tablet:** fetch data on action finish ([#405](https://github.com/ydb-platform/ydb-embedded-ui/issues/405)) ([f1d71c5](https://github.com/ydb-platform/ydb-embedded-ui/commit/f1d71c5af330a0a13246f8d87433e6bba1d3509a))
16
+
3
17
  ## [4.5.0](https://github.com/ydb-platform/ydb-embedded-ui/compare/v4.4.2...v4.5.0) (2023-06-01)
4
18
 
5
19
 
@@ -13,6 +13,7 @@ interface CriticalActionDialogProps {
13
13
  text: string;
14
14
  onClose: VoidFunction;
15
15
  onConfirm: () => Promise<unknown>;
16
+ onConfirmActionFinish: VoidFunction;
16
17
  }
17
18
 
18
19
  export const CriticalActionDialog = ({
@@ -20,6 +21,7 @@ export const CriticalActionDialog = ({
20
21
  text,
21
22
  onClose,
22
23
  onConfirm,
24
+ onConfirmActionFinish,
23
25
  }: CriticalActionDialogProps) => {
24
26
  const [isLoading, setIsLoading] = useState(false);
25
27
 
@@ -28,6 +30,7 @@ export const CriticalActionDialog = ({
28
30
  setIsLoading(true);
29
31
 
30
32
  return onConfirm().then(() => {
33
+ onConfirmActionFinish();
31
34
  setIsLoading(false);
32
35
  onClose();
33
36
  });
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
4
4
 
5
5
  import InfoViewer from '../InfoViewer/InfoViewer';
6
6
  import ProgressViewer from '../ProgressViewer/ProgressViewer';
7
- import PoolUsage from '../PoolUsage/PoolUsage';
7
+ import {PoolUsage} from '../PoolUsage/PoolUsage';
8
8
 
9
9
  import {LOAD_AVERAGE_TIME_INTERVALS} from '../../utils/constants';
10
10
  import {calcUptime} from '../../utils';
@@ -1,4 +1,4 @@
1
- .pool-usage {
1
+ .ydb-pool-usage {
2
2
  font-size: var(--yc-text-body-2-font-size);
3
3
  line-height: var(--yc-text-body-2-line-height);
4
4
  &__info {
@@ -0,0 +1,50 @@
1
+ import block from 'bem-cn-lite';
2
+
3
+ import type {TPoolStats} from '../../types/api/nodes';
4
+
5
+ import './PoolUsage.scss';
6
+
7
+ const b = block('ydb-pool-usage');
8
+
9
+ const getLineType = (fillWidth: number) => {
10
+ let fillColor = 'green';
11
+ if (fillWidth > 60 && fillWidth <= 80) {
12
+ fillColor = 'yellow';
13
+ } else if (fillWidth > 80) {
14
+ fillColor = 'red';
15
+ }
16
+
17
+ return fillColor;
18
+ };
19
+
20
+ interface PoolUsageProps {
21
+ data?: TPoolStats;
22
+ }
23
+
24
+ export const PoolUsage = ({data: pool = {}}: PoolUsageProps) => {
25
+ const {Threads, Name = 'Unknown', Usage = 0} = pool;
26
+ const dataExist = Usage && Threads;
27
+
28
+ const value = Math.floor(Usage * 100);
29
+ const fillWidth = value > 100 ? 100 : value;
30
+
31
+ return (
32
+ <div className={b()}>
33
+ <div className={b('info')}>
34
+ <div className={b('pool-name')}>{Name}</div>
35
+ {dataExist && (
36
+ <div className={b('value')}>
37
+ <div className={b('percents')}>{value < 1 ? '<1' : value}%</div>
38
+ <div className={b('threads')}>(×{Threads})</div>
39
+ </div>
40
+ )}
41
+ </div>
42
+ <div className={b('visual')}>
43
+ <div
44
+ className={b('usage-line', {type: getLineType(fillWidth)})}
45
+ style={{width: `${fillWidth}%`}}
46
+ />
47
+ </div>
48
+ </div>
49
+ );
50
+ };
@@ -15,7 +15,7 @@ import NodeStructure from './NodeStructure/NodeStructure';
15
15
  import {Loader} from '../../components/Loader';
16
16
  import {BasicNodeViewer} from '../../components/BasicNodeViewer';
17
17
 
18
- import {getNodeInfo, resetNode} from '../../store/reducers/node';
18
+ import {getNodeInfo, resetNode} from '../../store/reducers/node/node';
19
19
  import routes, {CLUSTER_PAGES, createHref} from '../../routes';
20
20
  import {setHeader} from '../../store/reducers/header';
21
21
  import {AutoFetcher} from '../../utils/autofetcher';
@@ -1,16 +1,19 @@
1
1
  import {useEffect, useRef, useMemo} from 'react';
2
- import {useDispatch, useSelector} from 'react-redux';
2
+ import {useDispatch} from 'react-redux';
3
3
  import url from 'url';
4
4
  import _ from 'lodash';
5
5
 
6
6
  import cn from 'bem-cn-lite';
7
7
 
8
- import {PDisk} from './Pdisk';
9
8
  import {Loader} from '../.././../components/Loader';
10
9
 
11
- import {getNodeStructure, selectNodeStructure} from '../../../store/reducers/node';
10
+ import {getNodeStructure} from '../../../store/reducers/node/node';
11
+ import {selectNodeStructure} from '../../../store/reducers/node/selectors';
12
12
 
13
13
  import {AutoFetcher} from '../../../utils/autofetcher';
14
+ import {useTypedSelector} from '../../../utils/hooks';
15
+
16
+ import {PDisk} from './Pdisk';
14
17
 
15
18
  import './NodeStructure.scss';
16
19
 
@@ -32,20 +35,19 @@ interface NodeStructureProps {
32
35
 
33
36
  const autofetcher = new AutoFetcher();
34
37
 
35
- function NodeStructure(props: NodeStructureProps) {
38
+ function NodeStructure({nodeId, className, additionalNodesInfo}: NodeStructureProps) {
36
39
  const dispatch = useDispatch();
37
40
 
38
- const nodeStructure: any = useSelector(selectNodeStructure);
41
+ const nodeStructure = useTypedSelector(selectNodeStructure);
39
42
 
40
- const loadingStructure = useSelector((state: any) => state.node.loadingStructure);
41
- const wasLoadedStructure = useSelector((state: any) => state.node.wasLoadedStructure);
42
- const nodeData = useSelector((state: any) => state.node?.data?.SystemStateInfo?.[0]);
43
+ const {loadingStructure, wasLoadedStructure} = useTypedSelector((state) => state.node);
44
+ const nodeData = useTypedSelector((state) => state.node?.data?.SystemStateInfo?.[0]);
43
45
 
44
46
  const nodeHref = useMemo(() => {
45
- return props.additionalNodesInfo?.getNodeRef
46
- ? props.additionalNodesInfo.getNodeRef(nodeData)
47
+ return additionalNodesInfo?.getNodeRef
48
+ ? additionalNodesInfo.getNodeRef(nodeData)
47
49
  : undefined;
48
- }, [nodeData, props.additionalNodesInfo]);
50
+ }, [nodeData, additionalNodesInfo]);
49
51
 
50
52
  const {pdiskId: pdiskIdFromUrl, vdiskId: vdiskIdFromUrl} = url.parse(
51
53
  window.location.href,
@@ -71,16 +73,16 @@ function NodeStructure(props: NodeStructureProps) {
71
73
  }, []);
72
74
 
73
75
  useEffect(() => {
74
- dispatch(getNodeStructure(props.nodeId));
76
+ dispatch(getNodeStructure(nodeId));
75
77
  autofetcher.start();
76
- autofetcher.fetch(() => dispatch(getNodeStructure(props.nodeId)));
78
+ autofetcher.fetch(() => dispatch(getNodeStructure(nodeId)));
77
79
 
78
80
  return () => {
79
81
  scrolled.current = false;
80
82
  isReady.current = false;
81
83
  autofetcher.stop();
82
84
  };
83
- }, [props.nodeId, dispatch]);
85
+ }, [nodeId, dispatch]);
84
86
 
85
87
  useEffect(() => {
86
88
  if (!_.isEmpty(nodeStructure) && scrollContainer) {
@@ -98,9 +100,9 @@ function NodeStructure(props: NodeStructureProps) {
98
100
 
99
101
  if (vdiskIdFromUrl) {
100
102
  const vDisks = nodeStructure[pdiskIdFromUrl as string]?.vDisks;
101
- const vDisk = vDisks?.find((el: any) => el.id === vdiskIdFromUrl);
103
+ const vDisk = vDisks?.find((el) => el.id === vdiskIdFromUrl);
102
104
  const dataTable = vDisk ? document.querySelector('.data-table') : undefined;
103
- const order = vDisk?.order;
105
+ const order = vDisk?.order || 0;
104
106
 
105
107
  if (dataTable) {
106
108
  scrollToVdisk += (dataTable as HTMLElement).offsetTop + 40 * order;
@@ -147,7 +149,7 @@ function NodeStructure(props: NodeStructureProps) {
147
149
 
148
150
  return (
149
151
  <div className={b()} ref={scrollContainerRef}>
150
- <div className={props.className}>{renderContent()}</div>
152
+ <div className={className}>{renderContent()}</div>
151
153
  </div>
152
154
  );
153
155
  }
@@ -52,6 +52,10 @@
52
52
  text-transform: uppercase;
53
53
  }
54
54
 
55
+ &__loader {
56
+ width: 25px;
57
+ }
58
+
55
59
  .info-viewer__items {
56
60
  grid-template-columns: auto;
57
61
  }
@@ -108,9 +108,10 @@ export const Tablet = () => {
108
108
  <Icon name="external" />
109
109
  </a>
110
110
  {Leader && <Tag text="Leader" type="blue" />}
111
+ <span className={b('loader')}>{loading && <Loader size="s" />}</span>
111
112
  </div>
112
113
  <TabletInfo tablet={tablet} tenantPath={tenantPath} />
113
- <TabletControls tablet={tablet} />
114
+ <TabletControls tablet={tablet} fetchData={fetchData} />
114
115
  </div>
115
116
  <div className={b('rigth-pane')}>
116
117
  <TabletTable history={history} />
@@ -17,18 +17,19 @@ type VisibleDialogType = EVisibleDialogType | null;
17
17
 
18
18
  interface TabletControlsProps {
19
19
  tablet: TTabletStateInfo;
20
+ fetchData: VoidFunction;
20
21
  }
21
22
 
22
- export const TabletControls = ({tablet}: TabletControlsProps) => {
23
+ export const TabletControls = ({tablet, fetchData}: TabletControlsProps) => {
23
24
  const {TabletId, HiveId} = tablet;
24
25
 
25
26
  const [isDialogVisible, setIsDialogVisible] = useState(false);
26
27
  const [visibleDialogType, setVisibleDialogType] = useState<VisibleDialogType>(null);
27
- const [isTabletActionsDisabled, setIsTabletActionsDisabled] = useState(false);
28
+ const [isTabletActionLoading, setIsTabletActionLoading] = useState(false);
28
29
 
29
30
  // Enable controls after data update
30
31
  useEffect(() => {
31
- setIsTabletActionsDisabled(false);
32
+ setIsTabletActionLoading(false);
32
33
  }, [tablet]);
33
34
 
34
35
  const makeShowDialog = (type: VisibleDialogType) => () => {
@@ -46,15 +47,15 @@ export const TabletControls = ({tablet}: TabletControlsProps) => {
46
47
  };
47
48
 
48
49
  const _onKillClick = () => {
49
- setIsTabletActionsDisabled(true);
50
+ setIsTabletActionLoading(true);
50
51
  return window.api.killTablet(TabletId);
51
52
  };
52
53
  const _onStopClick = () => {
53
- setIsTabletActionsDisabled(true);
54
+ setIsTabletActionLoading(true);
54
55
  return window.api.stopTablet(TabletId, HiveId);
55
56
  };
56
57
  const _onResumeClick = () => {
57
- setIsTabletActionsDisabled(true);
58
+ setIsTabletActionLoading(true);
58
59
  return window.api.resumeTablet(TabletId, HiveId);
59
60
  };
60
61
 
@@ -62,25 +63,11 @@ export const TabletControls = ({tablet}: TabletControlsProps) => {
62
63
  return HiveId && HiveId !== '0';
63
64
  };
64
65
 
65
- const isDisabledResume = () => {
66
- if (isTabletActionsDisabled) {
67
- return true;
68
- }
69
-
70
- return tablet.State !== ETabletState.Stopped && tablet.State !== ETabletState.Dead;
71
- };
72
-
73
- const isDisabledKill = () => {
74
- return isTabletActionsDisabled;
75
- };
76
-
77
- const isDisabledStop = () => {
78
- if (isTabletActionsDisabled) {
79
- return true;
80
- }
66
+ const isDisabledResume =
67
+ tablet.State !== ETabletState.Stopped && tablet.State !== ETabletState.Dead;
81
68
 
82
- return tablet.State === ETabletState.Stopped || tablet.State === ETabletState.Deleted;
83
- };
69
+ const isDisabledStop =
70
+ tablet.State === ETabletState.Stopped || tablet.State === ETabletState.Deleted;
84
71
 
85
72
  const renderDialog = () => {
86
73
  if (!isDialogVisible) {
@@ -95,6 +82,7 @@ export const TabletControls = ({tablet}: TabletControlsProps) => {
95
82
  text={i18n('dialog.kill')}
96
83
  onClose={hideDialog}
97
84
  onConfirm={_onKillClick}
85
+ onConfirmActionFinish={fetchData}
98
86
  />
99
87
  );
100
88
  }
@@ -105,6 +93,7 @@ export const TabletControls = ({tablet}: TabletControlsProps) => {
105
93
  text={i18n('dialog.stop')}
106
94
  onClose={hideDialog}
107
95
  onConfirm={_onStopClick}
96
+ onConfirmActionFinish={fetchData}
108
97
  />
109
98
  );
110
99
  }
@@ -115,6 +104,7 @@ export const TabletControls = ({tablet}: TabletControlsProps) => {
115
104
  text={i18n('dialog.resume')}
116
105
  onClose={hideDialog}
117
106
  onConfirm={_onResumeClick}
107
+ onConfirmActionFinish={fetchData}
118
108
  />
119
109
  );
120
110
  }
@@ -128,7 +118,7 @@ export const TabletControls = ({tablet}: TabletControlsProps) => {
128
118
  <Button
129
119
  onClick={showKillDialog}
130
120
  view="action"
131
- disabled={isDisabledKill()}
121
+ loading={isTabletActionLoading}
132
122
  className={b('control')}
133
123
  >
134
124
  {i18n('controls.kill')}
@@ -138,7 +128,8 @@ export const TabletControls = ({tablet}: TabletControlsProps) => {
138
128
  <Button
139
129
  onClick={showStopDialog}
140
130
  view="action"
141
- disabled={isDisabledStop()}
131
+ disabled={isDisabledStop}
132
+ loading={!isDisabledStop && isTabletActionLoading}
142
133
  className={b('control')}
143
134
  >
144
135
  {i18n('controls.stop')}
@@ -146,7 +137,8 @@ export const TabletControls = ({tablet}: TabletControlsProps) => {
146
137
  <Button
147
138
  onClick={showResumeDialog}
148
139
  view="action"
149
- disabled={isDisabledResume()}
140
+ disabled={isDisabledResume}
141
+ loading={!isDisabledResume && isTabletActionLoading}
150
142
  className={b('control')}
151
143
  >
152
144
  {i18n('controls.resume')}
@@ -3,13 +3,13 @@ import block from 'bem-cn-lite';
3
3
  import qs from 'qs';
4
4
 
5
5
  import type {IPreparedConsumerData} from '../../../../../types/store/topic';
6
+ import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../../../store/reducers/tenant/constants';
6
7
  import {SpeedMultiMeter} from '../../../../../components/SpeedMultiMeter';
7
8
  import {InternalLink} from '../../../../../components/InternalLink';
8
9
  import {formatMsToUptime} from '../../../../../utils';
9
10
  import routes, {createHref} from '../../../../../routes';
10
11
 
11
12
  import {TenantTabsGroups} from '../../../TenantPages';
12
- import {GeneralPagesIds} from '../../DiagnosticsPages';
13
13
 
14
14
  import {
15
15
  CONSUMERS_COLUMNS_IDS,
@@ -42,7 +42,7 @@ export const columns: Column<IPreparedConsumerData>[] = [
42
42
  <InternalLink
43
43
  to={createHref(routes.tenant, undefined, {
44
44
  ...queryParams,
45
- [TenantTabsGroups.generalTab]: GeneralPagesIds.partitions,
45
+ [TenantTabsGroups.generalTab]: TENANT_DIAGNOSTICS_TABS_IDS.partitions,
46
46
  selectedConsumer: row.name,
47
47
  })}
48
48
  >
@@ -7,37 +7,36 @@ import {useLocation} from 'react-router';
7
7
 
8
8
  import {Switch, Tabs} from '@gravity-ui/uikit';
9
9
 
10
+ import type {EPathType} from '../../../types/api/schema';
11
+
12
+ import {useTypedSelector} from '../../../utils/hooks';
13
+ import routes, {createHref} from '../../../routes';
14
+ import type {TenantDiagnosticsTab, TenantGeneralTab} from '../../../store/reducers/tenant/types';
15
+ import {enableAutorefresh, disableAutorefresh} from '../../../store/reducers/schema';
16
+ import {setTopLevelTab, setDiagnosticsTab} from '../../../store/reducers/tenant/tenant';
17
+ import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../store/reducers/tenant/constants';
18
+
10
19
  import {Loader} from '../../../components/Loader';
11
20
 
12
- import {TopQueries} from './TopQueries';
13
- //@ts-ignore
14
- import DetailedOverview from './DetailedOverview/DetailedOverview';
15
- import {TopShards} from './TopShards';
16
- //@ts-ignore
17
- import Storage from '../../Storage/Storage';
18
- //@ts-ignore
19
- import Network from './Network/Network';
20
- //@ts-ignore
21
- import Describe from './Describe/Describe';
22
- //@ts-ignore
23
- import HotKeys from './HotKeys/HotKeys';
24
- //@ts-ignore
25
21
  import {Heatmap} from '../../Heatmap';
26
22
  import {Nodes} from '../../Nodes';
27
- //@ts-ignore
23
+ import Storage from '../../Storage/Storage';
28
24
  import {Tablets} from '../../Tablets';
29
- import {Consumers} from './Consumers';
25
+
26
+ import Describe from './Describe/Describe';
27
+ import HotKeys from './HotKeys/HotKeys';
28
+ import Network from './Network/Network';
30
29
  import {Partitions} from './Partitions/Partitions';
30
+ import {Consumers} from './Consumers';
31
+ import {TopQueries} from './TopQueries';
32
+ import {TopShards} from './TopShards';
33
+ import DetailedOverview from './DetailedOverview/DetailedOverview';
31
34
 
32
- import routes, {createHref} from '../../../routes';
33
- import type {EPathType} from '../../../types/api/schema';
34
- import {TenantGeneralTabsIds, TenantTabsGroups} from '../TenantPages';
35
- import {GeneralPagesIds, DATABASE_PAGES, getPagesByType} from './DiagnosticsPages';
36
- //@ts-ignore
37
- import {enableAutorefresh, disableAutorefresh} from '../../../store/reducers/schema';
38
- import {setTopLevelTab, setDiagnosticsTab} from '../../../store/reducers/tenant';
39
35
  import {isDatabaseEntityType} from '../utils/schema';
40
36
 
37
+ import {TenantTabsGroups} from '../TenantPages';
38
+ import {DATABASE_PAGES, getPagesByType} from './DiagnosticsPages';
39
+
41
40
  import './Diagnostics.scss';
42
41
 
43
42
  interface DiagnosticsProps {
@@ -51,8 +50,8 @@ const b = cn('kv-tenant-diagnostics');
51
50
  function Diagnostics(props: DiagnosticsProps) {
52
51
  const dispatch = useDispatch();
53
52
  const {currentSchemaPath, autorefresh} = useSelector((state: any) => state.schema);
54
- const {diagnosticsTab = GeneralPagesIds.overview, wasLoaded} = useSelector(
55
- (state: any) => state.tenant,
53
+ const {diagnosticsTab = TENANT_DIAGNOSTICS_TABS_IDS.overview, wasLoaded} = useTypedSelector(
54
+ (state) => state.tenant,
56
55
  );
57
56
 
58
57
  const location = useLocation();
@@ -73,7 +72,7 @@ function Diagnostics(props: DiagnosticsProps) {
73
72
  return getPagesByType(props.type);
74
73
  }, [props.type, isDatabase]);
75
74
 
76
- const forwardToDiagnosticTab = (tab: GeneralPagesIds) => {
75
+ const forwardToDiagnosticTab = (tab: TenantDiagnosticsTab) => {
77
76
  dispatch(setDiagnosticsTab(tab));
78
77
  };
79
78
  const activeTab = useMemo(() => {
@@ -97,7 +96,7 @@ function Diagnostics(props: DiagnosticsProps) {
97
96
  }
98
97
  };
99
98
 
100
- const forwardToGeneralTab = (tab: TenantGeneralTabsIds) => {
99
+ const forwardToGeneralTab = (tab: TenantGeneralTab) => {
101
100
  dispatch(setTopLevelTab(tab));
102
101
  };
103
102
 
@@ -107,7 +106,7 @@ function Diagnostics(props: DiagnosticsProps) {
107
106
  const tenantNameString = tenantName as string;
108
107
 
109
108
  switch (diagnosticsTab) {
110
- case GeneralPagesIds.overview: {
109
+ case TENANT_DIAGNOSTICS_TABS_IDS.overview: {
111
110
  return (
112
111
  <DetailedOverview
113
112
  type={type}
@@ -116,7 +115,7 @@ function Diagnostics(props: DiagnosticsProps) {
116
115
  />
117
116
  );
118
117
  }
119
- case GeneralPagesIds.topQueries: {
118
+ case TENANT_DIAGNOSTICS_TABS_IDS.topQueries: {
120
119
  return (
121
120
  <TopQueries
122
121
  path={tenantNameString}
@@ -125,10 +124,10 @@ function Diagnostics(props: DiagnosticsProps) {
125
124
  />
126
125
  );
127
126
  }
128
- case GeneralPagesIds.topShards: {
127
+ case TENANT_DIAGNOSTICS_TABS_IDS.topShards: {
129
128
  return <TopShards tenantPath={tenantNameString} type={type} />;
130
129
  }
131
- case GeneralPagesIds.nodes: {
130
+ case TENANT_DIAGNOSTICS_TABS_IDS.nodes: {
132
131
  return (
133
132
  <Nodes
134
133
  path={currentSchemaPath}
@@ -137,28 +136,28 @@ function Diagnostics(props: DiagnosticsProps) {
137
136
  />
138
137
  );
139
138
  }
140
- case GeneralPagesIds.tablets: {
139
+ case TENANT_DIAGNOSTICS_TABS_IDS.tablets: {
141
140
  return <Tablets path={currentSchemaPath} />;
142
141
  }
143
- case GeneralPagesIds.storage: {
142
+ case TENANT_DIAGNOSTICS_TABS_IDS.storage: {
144
143
  return <Storage tenant={tenantNameString} database={true} />;
145
144
  }
146
- case GeneralPagesIds.network: {
145
+ case TENANT_DIAGNOSTICS_TABS_IDS.network: {
147
146
  return <Network path={tenantNameString} />;
148
147
  }
149
- case GeneralPagesIds.describe: {
148
+ case TENANT_DIAGNOSTICS_TABS_IDS.describe: {
150
149
  return <Describe tenant={tenantNameString} type={type} />;
151
150
  }
152
- case GeneralPagesIds.hotKeys: {
151
+ case TENANT_DIAGNOSTICS_TABS_IDS.hotKeys: {
153
152
  return <HotKeys type={type} />;
154
153
  }
155
- case GeneralPagesIds.graph: {
154
+ case TENANT_DIAGNOSTICS_TABS_IDS.graph: {
156
155
  return <Heatmap path={currentSchemaPath} />;
157
156
  }
158
- case GeneralPagesIds.consumers: {
157
+ case TENANT_DIAGNOSTICS_TABS_IDS.consumers: {
159
158
  return <Consumers path={currentSchemaPath} type={type} />;
160
159
  }
161
- case GeneralPagesIds.partitions: {
160
+ case TENANT_DIAGNOSTICS_TABS_IDS.partitions: {
162
161
  return <Partitions path={currentSchemaPath} />;
163
162
  }
164
163
  default: {
@@ -1,80 +1,67 @@
1
+ import type {TenantDiagnosticsTab} from '../../../store/reducers/tenant/types';
2
+ import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../store/reducers/tenant/constants';
1
3
  import {EPathType} from '../../../types/api/schema';
2
4
 
3
- export enum GeneralPagesIds {
4
- 'overview' = 'Overview',
5
- 'topQueries' = 'topQueries',
6
- 'topShards' = 'topShards',
7
- 'nodes' = 'Nodes',
8
- 'tablets' = 'Tablets',
9
- 'storage' = 'Storage',
10
- 'network' = 'Network',
11
- 'describe' = 'Describe',
12
- 'hotKeys' = 'hotKeys',
13
- 'graph' = 'graph',
14
- 'consumers' = 'consumers',
15
- 'partitions' = 'partitions',
16
- }
17
-
18
5
  type Page = {
19
- id: GeneralPagesIds;
6
+ id: TenantDiagnosticsTab;
20
7
  title: string;
21
8
  };
22
9
 
23
10
  const overview = {
24
- id: GeneralPagesIds.overview,
11
+ id: TENANT_DIAGNOSTICS_TABS_IDS.overview,
25
12
  title: 'Info',
26
13
  };
27
14
 
28
15
  const topQueries = {
29
- id: GeneralPagesIds.topQueries,
16
+ id: TENANT_DIAGNOSTICS_TABS_IDS.topQueries,
30
17
  title: 'Top queries',
31
18
  };
32
19
 
33
20
  const topShards = {
34
- id: GeneralPagesIds.topShards,
21
+ id: TENANT_DIAGNOSTICS_TABS_IDS.topShards,
35
22
  title: 'Top shards',
36
23
  };
37
24
 
38
25
  const nodes = {
39
- id: GeneralPagesIds.nodes,
26
+ id: TENANT_DIAGNOSTICS_TABS_IDS.nodes,
40
27
  title: 'Nodes',
41
28
  };
42
29
 
43
30
  const tablets = {
44
- id: GeneralPagesIds.tablets,
31
+ id: TENANT_DIAGNOSTICS_TABS_IDS.tablets,
45
32
  title: 'Tablets',
46
33
  };
47
34
  const storage = {
48
- id: GeneralPagesIds.storage,
35
+ id: TENANT_DIAGNOSTICS_TABS_IDS.storage,
49
36
  title: 'Storage',
50
37
  };
51
38
  const network = {
52
- id: GeneralPagesIds.network,
39
+ id: TENANT_DIAGNOSTICS_TABS_IDS.network,
53
40
  title: 'Network',
54
41
  };
55
42
 
56
43
  const describe = {
57
- id: GeneralPagesIds.describe,
44
+ id: TENANT_DIAGNOSTICS_TABS_IDS.describe,
58
45
  title: 'Describe',
59
46
  };
60
47
 
61
48
  const hotKeys = {
62
- id: GeneralPagesIds.hotKeys,
49
+ id: TENANT_DIAGNOSTICS_TABS_IDS.hotKeys,
63
50
  title: 'Hot keys',
64
51
  };
65
52
 
66
53
  const graph = {
67
- id: GeneralPagesIds.graph,
54
+ id: TENANT_DIAGNOSTICS_TABS_IDS.graph,
68
55
  title: 'Graph',
69
56
  };
70
57
 
71
58
  const consumers = {
72
- id: GeneralPagesIds.consumers,
59
+ id: TENANT_DIAGNOSTICS_TABS_IDS.consumers,
73
60
  title: 'Consumers',
74
61
  };
75
62
 
76
63
  const partitions = {
77
- id: GeneralPagesIds.partitions,
64
+ id: TENANT_DIAGNOSTICS_TABS_IDS.partitions,
78
65
  title: 'Partitions',
79
66
  };
80
67
 
@@ -12,7 +12,7 @@ import {Icon} from '../../../../components/Icon';
12
12
  import {ProblemFilter} from '../../../../components/ProblemFilter';
13
13
  import {Illustration} from '../../../../components/Illustration';
14
14
 
15
- import {getNetworkInfo, setDataWasNotLoaded} from '../../../../store/reducers/network';
15
+ import {getNetworkInfo, setDataWasNotLoaded} from '../../../../store/reducers/network/network';
16
16
  import {hideTooltip, showTooltip} from '../../../../store/reducers/tooltip';
17
17
  import {changeFilter, ProblemFilterValues} from '../../../../store/reducers/settings/settings';
18
18
  import {AutoFetcher} from '../../../../utils/autofetcher';
@@ -361,7 +361,7 @@ class Network extends React.Component {
361
361
  }
362
362
 
363
363
  const mapStateToProps = (state) => {
364
- const {wasLoaded, loading, data: netWorkInfo} = state.network;
364
+ const {wasLoaded, loading, data: netWorkInfo = {}} = state.network;
365
365
  const {autorefresh} = state.schema;
366
366
  return {
367
367
  netWorkInfo,