ydb-embedded-ui 4.5.2 → 4.7.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +33 -0
- package/dist/assets/icons/versions.svg +3 -0
- package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +7 -2
- package/dist/components/Tablet/Tablet.tsx +17 -3
- package/dist/components/TabletsStatistic/TabletsStatistic.tsx +23 -16
- package/dist/containers/App/Content.js +8 -4
- package/dist/containers/AsideNavigation/AsideNavigation.tsx +4 -50
- package/dist/containers/Cluster/Cluster.scss +7 -48
- package/dist/containers/Cluster/Cluster.tsx +129 -20
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.scss +34 -17
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.tsx +58 -92
- package/dist/containers/Cluster/ClusterInfoSkeleton/ClusterInfoSkeleton.scss +48 -0
- package/dist/containers/Cluster/ClusterInfoSkeleton/ClusterInfoSkeleton.tsx +34 -0
- package/dist/containers/Cluster/utils.tsx +45 -0
- package/dist/containers/Header/Header.scss +4 -19
- package/dist/containers/Header/Header.tsx +72 -46
- package/dist/containers/Header/breadcrumbs.ts +146 -0
- package/dist/containers/Node/Node.tsx +25 -29
- package/dist/containers/Node/NodePages.ts +10 -6
- package/dist/containers/Nodes/Nodes.tsx +0 -16
- package/dist/containers/Nodes/getNodesColumns.tsx +1 -1
- package/dist/containers/Storage/Storage.js +1 -11
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +11 -3
- package/dist/containers/Tablet/Tablet.tsx +40 -4
- package/dist/containers/Tablet/TabletInfo/TabletInfo.tsx +2 -2
- package/dist/containers/TabletsFilters/TabletsFilters.js +15 -2
- package/dist/containers/Tenant/Diagnostics/Consumers/columns/columns.tsx +1 -1
- package/dist/containers/Tenant/Diagnostics/Describe/Describe.tsx +1 -1
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +7 -0
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +4 -4
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.scss +5 -3
- package/dist/containers/Tenant/Diagnostics/Healthcheck/Healthcheck.tsx +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/ChangefeedInfo/ChangefeedInfo.tsx +4 -6
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +56 -53
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +2 -1
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +11 -13
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +1 -1
- package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +2 -2
- package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +7 -3
- package/dist/containers/Tenant/Preview/Preview.js +1 -1
- package/dist/containers/Tenant/{QueryEditor/QueryResult/QueryResult.js → Query/ExecuteResult/ExecuteResult.js} +3 -5
- package/dist/containers/Tenant/{QueryEditor/QueryResult/QueryResult.scss → Query/ExecuteResult/ExecuteResult.scss} +1 -1
- package/dist/containers/Tenant/{QueryEditor/QueryExplain/QueryExplain.js → Query/ExplainResult/ExplainResult.js} +3 -5
- package/dist/containers/Tenant/{QueryEditor/QueryExplain/QueryExplain.scss → Query/ExplainResult/ExplainResult.scss} +1 -1
- package/dist/containers/Tenant/Query/QueriesHistory/QueriesHistory.scss +20 -0
- package/dist/containers/Tenant/Query/QueriesHistory/QueriesHistory.tsx +60 -0
- package/dist/containers/Tenant/Query/Query.scss +16 -0
- package/dist/containers/Tenant/Query/Query.tsx +73 -0
- package/dist/containers/Tenant/{QueryEditor → Query/QueryEditor}/QueryEditor.js +43 -100
- package/dist/containers/Tenant/{QueryEditor → Query/QueryEditor}/QueryEditor.scss +7 -23
- package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/OldQueryEditorControls.tsx +10 -3
- package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/QueryEditorControls.scss +1 -4
- package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/QueryEditorControls.tsx +8 -1
- package/dist/containers/Tenant/{QueryEditor → Query}/QueryEditorControls/shared.ts +1 -6
- package/dist/containers/Tenant/Query/QueryTabs/QueryTabs.tsx +59 -0
- package/dist/containers/Tenant/{QueryEditor → Query}/SaveQuery/SaveQuery.js +5 -5
- package/dist/containers/Tenant/Query/SavedQueries/SavedQueries.scss +55 -0
- package/dist/containers/Tenant/Query/SavedQueries/SavedQueries.tsx +150 -0
- package/dist/containers/Tenant/Query/i18n/en.json +12 -0
- package/dist/containers/Tenant/Query/i18n/ru.json +12 -0
- package/dist/containers/Tenant/Query/utils/getPreparedResult.ts +30 -0
- package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +1 -1
- package/dist/containers/Tenant/Tenant.tsx +4 -25
- package/dist/containers/Tenant/TenantPages.tsx +8 -2
- package/dist/containers/Tenant/utils/constants.ts +10 -0
- package/dist/containers/Tenant/utils/schemaActions.ts +8 -3
- package/dist/containers/Tenants/Tenants.js +39 -37
- package/dist/containers/Tenants/Tenants.scss +2 -4
- package/dist/containers/UserSettings/i18n/en.json +2 -2
- package/dist/containers/UserSettings/i18n/ru.json +2 -2
- package/dist/containers/UserSettings/settings.ts +4 -4
- package/dist/containers/Versions/Versions.scss +0 -4
- package/dist/containers/Versions/Versions.tsx +74 -66
- package/dist/routes.ts +8 -6
- package/dist/services/api.ts +15 -7
- package/dist/store/reducers/clusterNodes/clusterNodes.tsx +4 -0
- package/dist/store/reducers/executeQuery.ts +1 -1
- package/dist/store/reducers/header/header.ts +31 -0
- package/dist/store/reducers/header/types.ts +54 -0
- package/dist/store/reducers/index.ts +4 -2
- package/dist/store/reducers/node/types.ts +2 -0
- package/dist/store/reducers/overview/overview.ts +109 -0
- package/dist/store/reducers/overview/types.ts +24 -0
- package/dist/store/reducers/{schema.ts → schema/schema.ts} +24 -50
- package/dist/{types/store/schema.ts → store/reducers/schema/types.ts} +16 -15
- package/dist/store/reducers/settings/settings.ts +5 -3
- package/dist/store/reducers/tablet.ts +18 -1
- package/dist/store/reducers/tenant/constants.ts +6 -0
- package/dist/store/reducers/tenant/tenant.ts +21 -2
- package/dist/store/reducers/tenant/types.ts +9 -2
- package/dist/store/reducers/topic.ts +1 -1
- package/dist/store/state-url-mapping.js +4 -1
- package/dist/types/api/query.ts +78 -44
- package/dist/types/store/explainQuery.ts +2 -2
- package/dist/types/store/query.ts +9 -2
- package/dist/types/store/tablet.ts +7 -4
- package/dist/utils/constants.ts +5 -1
- package/dist/utils/nodes.ts +1 -1
- package/dist/utils/query.ts +3 -3
- package/package.json +2 -1
- package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.scss +0 -85
- package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.tsx +0 -95
- package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.js +0 -161
- package/dist/containers/Tenant/QueryEditor/SavedQueries/SavedQueries.scss +0 -93
- package/dist/containers/Tenant/QueryEditor/i18n/en.json +0 -3
- package/dist/containers/Tenant/QueryEditor/i18n/ru.json +0 -3
- package/dist/store/reducers/header.ts +0 -26
- /package/dist/containers/Tenant/{QueryEditor → Query}/Issues/Issues.scss +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/Issues/Issues.tsx +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/Issues/models.ts +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/QueryDuration/QueryDuration.scss +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/QueryDuration/QueryDuration.tsx +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/SaveQuery/SaveQuery.scss +0 -0
- /package/dist/containers/Tenant/{QueryEditor → Query}/i18n/index.ts +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
import * as React from 'react';
|
2
|
-
import {useRouteMatch} from 'react-router';
|
2
|
+
import {useLocation, useRouteMatch} from 'react-router';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
|
-
import {useDispatch
|
4
|
+
import {useDispatch} from 'react-redux';
|
5
5
|
import _ from 'lodash';
|
6
6
|
|
7
7
|
import {Tabs} from '@gravity-ui/uikit';
|
@@ -16,9 +16,12 @@ import {Loader} from '../../components/Loader';
|
|
16
16
|
import {BasicNodeViewer} from '../../components/BasicNodeViewer';
|
17
17
|
|
18
18
|
import {getNodeInfo, resetNode} from '../../store/reducers/node/node';
|
19
|
-
import routes, {
|
20
|
-
import {
|
19
|
+
import routes, {createHref, parseQuery} from '../../routes';
|
20
|
+
import {setHeaderBreadcrumbs} from '../../store/reducers/header/header';
|
21
21
|
import {AutoFetcher} from '../../utils/autofetcher';
|
22
|
+
import {useTypedSelector} from '../../utils/hooks';
|
23
|
+
|
24
|
+
import {clusterTabsIds} from '../Cluster/utils';
|
22
25
|
|
23
26
|
import './Node.scss';
|
24
27
|
|
@@ -26,11 +29,6 @@ const b = cn('node');
|
|
26
29
|
|
27
30
|
export const STORAGE_ROLE = 'Storage';
|
28
31
|
|
29
|
-
const headerNodes = {
|
30
|
-
text: CLUSTER_PAGES.nodes.title,
|
31
|
-
link: createHref(routes.cluster, {activeTab: CLUSTER_PAGES.nodes.id}),
|
32
|
-
};
|
33
|
-
|
34
32
|
const autofetcher = new AutoFetcher();
|
35
33
|
|
36
34
|
interface NodeProps {
|
@@ -40,19 +38,16 @@ interface NodeProps {
|
|
40
38
|
|
41
39
|
function Node(props: NodeProps) {
|
42
40
|
const dispatch = useDispatch();
|
41
|
+
const location = useLocation();
|
43
42
|
|
44
|
-
const wasLoaded =
|
45
|
-
const
|
46
|
-
const error = useSelector((state: any) => state.node.error);
|
47
|
-
|
48
|
-
const node = useSelector((state: any) => state.node?.data?.SystemStateInfo?.[0]);
|
49
|
-
|
50
|
-
const nodeHost = node?.Host;
|
43
|
+
const {loading, wasLoaded, error, data} = useTypedSelector((state) => state.node);
|
44
|
+
const node = data?.SystemStateInfo?.[0];
|
51
45
|
|
52
46
|
const match =
|
53
47
|
useRouteMatch<{id: string; activeTab: string}>(routes.node) ?? Object.create(null);
|
54
48
|
|
55
49
|
const {id: nodeId, activeTab} = match.params;
|
50
|
+
const {tenantName: tenantNameFromQuery} = parseQuery(location);
|
56
51
|
|
57
52
|
const {activeTabVerified, nodeTabs} = React.useMemo(() => {
|
58
53
|
const hasStorage = _.find(node?.Roles as any[], (el) => el === STORAGE_ROLE);
|
@@ -72,28 +67,29 @@ function Node(props: NodeProps) {
|
|
72
67
|
return {activeTabVerified, nodeTabs};
|
73
68
|
}, [activeTab, node]);
|
74
69
|
|
70
|
+
React.useEffect(() => {
|
71
|
+
const tenantName = node?.Tenants?.[0] || tenantNameFromQuery?.toString();
|
72
|
+
|
73
|
+
dispatch(
|
74
|
+
setHeaderBreadcrumbs('node', {
|
75
|
+
clusterTab: clusterTabsIds.nodes,
|
76
|
+
tenantName,
|
77
|
+
nodeId,
|
78
|
+
}),
|
79
|
+
);
|
80
|
+
}, [dispatch, node, nodeId, tenantNameFromQuery]);
|
81
|
+
|
75
82
|
React.useEffect(() => {
|
76
83
|
const fetchData = () => dispatch(getNodeInfo(nodeId));
|
77
84
|
fetchData();
|
78
85
|
autofetcher.start();
|
79
86
|
autofetcher.fetch(() => fetchData());
|
80
|
-
|
87
|
+
|
81
88
|
return () => {
|
82
89
|
autofetcher.stop();
|
83
90
|
dispatch(resetNode());
|
84
91
|
};
|
85
|
-
}, [nodeId]);
|
86
|
-
|
87
|
-
React.useEffect(() => {
|
88
|
-
dispatch(
|
89
|
-
setHeader([
|
90
|
-
headerNodes,
|
91
|
-
{
|
92
|
-
text: nodeHost,
|
93
|
-
},
|
94
|
-
]),
|
95
|
-
);
|
96
|
-
}, [nodeHost]);
|
92
|
+
}, [dispatch, nodeId]);
|
97
93
|
|
98
94
|
const renderTabs = () => {
|
99
95
|
return (
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import routes, {createHref} from '../../routes';
|
1
|
+
import routes, {Query, createHref} from '../../routes';
|
2
2
|
|
3
3
|
export const STORAGE = 'storage';
|
4
4
|
export const TABLETS = 'tablets';
|
@@ -21,9 +21,13 @@ export const NODE_PAGES = [
|
|
21
21
|
},
|
22
22
|
];
|
23
23
|
|
24
|
-
export function getDefaultNodePath(nodeId: string | number) {
|
25
|
-
return createHref(
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
export function getDefaultNodePath(nodeId: string | number, query: Query = {}) {
|
25
|
+
return createHref(
|
26
|
+
routes.node,
|
27
|
+
{
|
28
|
+
id: nodeId,
|
29
|
+
activeTab: OVERVIEW,
|
30
|
+
},
|
31
|
+
query,
|
32
|
+
);
|
29
33
|
}
|
@@ -15,13 +15,10 @@ import {ProblemFilter} from '../../components/ProblemFilter';
|
|
15
15
|
import {UptimeFilter} from '../../components/UptimeFIlter';
|
16
16
|
import {EntitiesCount} from '../../components/EntitiesCount';
|
17
17
|
|
18
|
-
import routes, {CLUSTER_PAGES, createHref} from '../../routes';
|
19
|
-
|
20
18
|
import {DEFAULT_TABLE_SETTINGS, USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY} from '../../utils/constants';
|
21
19
|
import {useAutofetcher, useSetting, useTypedSelector} from '../../utils/hooks';
|
22
20
|
import {AdditionalNodesInfo, isUnavailableNode, NodesUptimeFilterValues} from '../../utils/nodes';
|
23
21
|
|
24
|
-
import {setHeader} from '../../store/reducers/header';
|
25
22
|
import {
|
26
23
|
getNodes,
|
27
24
|
getFilteredPreparedNodesList,
|
@@ -82,19 +79,6 @@ export const Nodes = ({path, type, className, additionalNodesInfo = {}}: NodesPr
|
|
82
79
|
|
83
80
|
useAutofetcher(fetchNodes, [fetchNodes], isClusterNodes ? true : autorefresh);
|
84
81
|
|
85
|
-
useEffect(() => {
|
86
|
-
if (isClusterNodes) {
|
87
|
-
dispatch(
|
88
|
-
setHeader([
|
89
|
-
{
|
90
|
-
text: CLUSTER_PAGES.nodes.title,
|
91
|
-
link: createHref(routes.cluster, {activeTab: CLUSTER_PAGES.nodes.id}),
|
92
|
-
},
|
93
|
-
]),
|
94
|
-
);
|
95
|
-
}
|
96
|
-
}, [dispatch, isClusterNodes]);
|
97
|
-
|
98
82
|
const handleSearchQueryChange = (value: string) => {
|
99
83
|
dispatch(setSearchValue(value));
|
100
84
|
};
|
@@ -13,7 +13,7 @@ import type {INodesPreparedEntity} from '../../types/store/nodes';
|
|
13
13
|
|
14
14
|
interface GetNodesColumnsProps {
|
15
15
|
tabletsPath?: string;
|
16
|
-
getNodeRef?: (node?: NodeAddress) => string;
|
16
|
+
getNodeRef?: (node?: NodeAddress) => string | null;
|
17
17
|
}
|
18
18
|
|
19
19
|
export function getNodesColumns({tabletsPath, getNodeRef}: GetNodesColumnsProps) {
|
@@ -35,8 +35,6 @@ import {getNodesList, selectNodesMap} from '../../store/reducers/nodesList';
|
|
35
35
|
import StorageGroups from './StorageGroups/StorageGroups';
|
36
36
|
import StorageNodes from './StorageNodes/StorageNodes';
|
37
37
|
import {DEFAULT_TABLE_SETTINGS} from '../../utils/constants';
|
38
|
-
import {setHeader} from '../../store/reducers/header';
|
39
|
-
import routes, {CLUSTER_PAGES, createHref} from '../../routes';
|
40
38
|
|
41
39
|
import './Storage.scss';
|
42
40
|
|
@@ -67,7 +65,6 @@ class Storage extends React.Component {
|
|
67
65
|
setStorageFilter: PropTypes.func,
|
68
66
|
setVisibleEntities: PropTypes.func,
|
69
67
|
visibleEntities: PropTypes.string,
|
70
|
-
setHeader: PropTypes.func,
|
71
68
|
tenant: PropTypes.string,
|
72
69
|
nodeId: PropTypes.string,
|
73
70
|
nodesUptimeFilter: PropTypes.string,
|
@@ -77,7 +74,7 @@ class Storage extends React.Component {
|
|
77
74
|
};
|
78
75
|
|
79
76
|
componentDidMount() {
|
80
|
-
const {tenant, nodeId, setVisibleEntities, storageType,
|
77
|
+
const {tenant, nodeId, setVisibleEntities, storageType, getNodesList} =
|
81
78
|
this.props;
|
82
79
|
|
83
80
|
this.autofetcher = new AutoFetcher();
|
@@ -89,12 +86,6 @@ class Storage extends React.Component {
|
|
89
86
|
type: storageType,
|
90
87
|
});
|
91
88
|
} else {
|
92
|
-
setHeader([
|
93
|
-
{
|
94
|
-
text: CLUSTER_PAGES.storage.title,
|
95
|
-
link: createHref(routes.cluster, {activeTab: CLUSTER_PAGES.storage.id}),
|
96
|
-
},
|
97
|
-
]);
|
98
89
|
this.getStorageInfo({
|
99
90
|
filter: FILTER_OPTIONS.Missing,
|
100
91
|
type: storageType,
|
@@ -375,7 +366,6 @@ const mapDispatchToProps = {
|
|
375
366
|
setNodesUptimeFilter,
|
376
367
|
getNodesList,
|
377
368
|
setStorageType,
|
378
|
-
setHeader,
|
379
369
|
setDataWasNotLoaded,
|
380
370
|
};
|
381
371
|
|
@@ -74,8 +74,8 @@ function setSortOrder(visibleEntities: keyof typeof VisibleEntities): SortOrder
|
|
74
74
|
switch (visibleEntities) {
|
75
75
|
case VisibleEntities.All: {
|
76
76
|
return {
|
77
|
-
columnId: TableColumnsIds.
|
78
|
-
order: DataTable.
|
77
|
+
columnId: TableColumnsIds.PoolName,
|
78
|
+
order: DataTable.ASCENDING,
|
79
79
|
};
|
80
80
|
}
|
81
81
|
case VisibleEntities.Missing: {
|
@@ -87,7 +87,7 @@ function setSortOrder(visibleEntities: keyof typeof VisibleEntities): SortOrder
|
|
87
87
|
case VisibleEntities.Space: {
|
88
88
|
return {
|
89
89
|
columnId: TableColumnsIds.UsedSpaceFlag,
|
90
|
-
order: DataTable.
|
90
|
+
order: DataTable.DESCENDING,
|
91
91
|
};
|
92
92
|
}
|
93
93
|
default: {
|
@@ -295,6 +295,14 @@ function StorageGroups({
|
|
295
295
|
|
296
296
|
let columns = allColumns;
|
297
297
|
|
298
|
+
if (visibleEntities === VisibleEntities.All) {
|
299
|
+
columns = allColumns.filter((col) => {
|
300
|
+
return (
|
301
|
+
col.name !== TableColumnsIds.Missing && col.name !== TableColumnsIds.UsedSpaceFlag
|
302
|
+
);
|
303
|
+
});
|
304
|
+
}
|
305
|
+
|
298
306
|
if (visibleEntities === VisibleEntities.Space) {
|
299
307
|
columns = allColumns.filter((col) => col.name !== TableColumnsIds.Missing);
|
300
308
|
|
@@ -1,13 +1,17 @@
|
|
1
1
|
import {useCallback, useEffect, useRef} from 'react';
|
2
|
-
import {useParams} from 'react-router';
|
2
|
+
import {useLocation, useParams} from 'react-router';
|
3
3
|
import {useDispatch} from 'react-redux';
|
4
4
|
import cn from 'bem-cn-lite';
|
5
5
|
import {Link as ExternalLink} from '@gravity-ui/uikit';
|
6
6
|
|
7
7
|
import {backend} from '../../store';
|
8
|
-
import {getTablet, getTabletDescribe} from '../../store/reducers/tablet';
|
8
|
+
import {getTablet, getTabletDescribe, clearTabletData} from '../../store/reducers/tablet';
|
9
|
+
import {setHeaderBreadcrumbs} from '../../store/reducers/header/header';
|
10
|
+
|
9
11
|
import {useAutofetcher, useTypedSelector} from '../../utils/hooks';
|
12
|
+
import {DEVELOPER_UI} from '../../utils/constants';
|
10
13
|
import '../../services/api';
|
14
|
+
import {parseQuery} from '../../routes';
|
11
15
|
|
12
16
|
import EntityStatus from '../../components/EntityStatus/EntityStatus';
|
13
17
|
import {ResponseError} from '../../components/Errors/ResponseError';
|
@@ -30,6 +34,7 @@ export const Tablet = () => {
|
|
30
34
|
const isFirstDataFetchRef = useRef(true);
|
31
35
|
|
32
36
|
const dispatch = useDispatch();
|
37
|
+
const location = useLocation();
|
33
38
|
|
34
39
|
const params = useParams<{id: string}>();
|
35
40
|
const {id} = params;
|
@@ -43,6 +48,25 @@ export const Tablet = () => {
|
|
43
48
|
error,
|
44
49
|
} = useTypedSelector((state) => state.tablet);
|
45
50
|
|
51
|
+
const {
|
52
|
+
nodeId: queryNodeId,
|
53
|
+
type: queryType,
|
54
|
+
state: queryState,
|
55
|
+
tenantName: queryTenantName,
|
56
|
+
} = parseQuery(location);
|
57
|
+
|
58
|
+
const nodeId = tablet.NodeId?.toString() || queryNodeId?.toString();
|
59
|
+
const tabletState = tablet.State || queryState?.toString();
|
60
|
+
const tabletType = tablet.Type || queryType?.toString();
|
61
|
+
const tenantName = tenantPath || queryTenantName?.toString();
|
62
|
+
|
63
|
+
// NOTE: should be reviewed when migrating to React 18
|
64
|
+
useEffect(() => {
|
65
|
+
return () => {
|
66
|
+
dispatch(clearTabletData());
|
67
|
+
};
|
68
|
+
}, [dispatch]);
|
69
|
+
|
46
70
|
useEffect(() => {
|
47
71
|
if (isFirstDataFetchRef.current && tablet && tablet.TenantId) {
|
48
72
|
dispatch(getTabletDescribe(tablet.TenantId));
|
@@ -56,6 +80,18 @@ export const Tablet = () => {
|
|
56
80
|
|
57
81
|
useAutofetcher(fetchData, [fetchData], true);
|
58
82
|
|
83
|
+
useEffect(() => {
|
84
|
+
dispatch(
|
85
|
+
setHeaderBreadcrumbs('tablet', {
|
86
|
+
nodeIds: nodeId ? [nodeId] : [],
|
87
|
+
state: tabletState,
|
88
|
+
type: tabletType,
|
89
|
+
tenantName,
|
90
|
+
tabletId: id,
|
91
|
+
}),
|
92
|
+
);
|
93
|
+
}, [dispatch, tenantName, id, nodeId, tabletState, tabletType]);
|
94
|
+
|
59
95
|
const renderExternalLinks = (link: {name: string; path: string}, index: number) => {
|
60
96
|
return (
|
61
97
|
<li key={index} className={b('link', {external: true})}>
|
@@ -86,7 +122,7 @@ export const Tablet = () => {
|
|
86
122
|
|
87
123
|
const externalLinks = [
|
88
124
|
{
|
89
|
-
name:
|
125
|
+
name: `${DEVELOPER_UI} - tablet`,
|
90
126
|
path: `/tablets?TabletID=${TabletId}`,
|
91
127
|
},
|
92
128
|
];
|
@@ -110,7 +146,7 @@ export const Tablet = () => {
|
|
110
146
|
{Leader && <Tag text="Leader" type="blue" />}
|
111
147
|
<span className={b('loader')}>{loading && <Loader size="s" />}</span>
|
112
148
|
</div>
|
113
|
-
<TabletInfo tablet={tablet} tenantPath={
|
149
|
+
<TabletInfo tablet={tablet} tenantPath={tenantName} />
|
114
150
|
<TabletControls tablet={tablet} fetchData={fetchData} />
|
115
151
|
</div>
|
116
152
|
<div className={b('rigth-pane')}>
|
@@ -12,7 +12,7 @@ import {b} from '../Tablet';
|
|
12
12
|
|
13
13
|
interface TabletInfoProps {
|
14
14
|
tablet: TTabletStateInfo;
|
15
|
-
tenantPath
|
15
|
+
tenantPath?: string;
|
16
16
|
}
|
17
17
|
|
18
18
|
export const TabletInfo = ({tablet, tenantPath}: TabletInfoProps) => {
|
@@ -30,7 +30,7 @@ export const TabletInfo = ({tablet, tenantPath}: TabletInfoProps) => {
|
|
30
30
|
const hasHiveId = HiveId && HiveId !== '0';
|
31
31
|
const hasUptime = State === ETabletState.Active;
|
32
32
|
|
33
|
-
const tabletInfo: InfoViewerItem[] = [{label: 'Database', value: tenantPath}];
|
33
|
+
const tabletInfo: InfoViewerItem[] = [{label: 'Database', value: tenantPath || '-'}];
|
34
34
|
|
35
35
|
if (hasHiveId) {
|
36
36
|
tabletInfo.push({
|
@@ -11,6 +11,7 @@ import ReactList from 'react-list';
|
|
11
11
|
import {Tablet} from '../../components/Tablet';
|
12
12
|
import {AccessDenied} from '../../components/Errors/403';
|
13
13
|
|
14
|
+
import {setHeaderBreadcrumbs} from '../../store/reducers/header/header';
|
14
15
|
import {tabletColorToTabletState, tabletStates} from '../../utils/tablet';
|
15
16
|
import {
|
16
17
|
getTabletsInfo,
|
@@ -41,6 +42,7 @@ class TabletsFilters extends React.Component {
|
|
41
42
|
stateFilter: PropTypes.array,
|
42
43
|
typeFilter: PropTypes.array,
|
43
44
|
error: PropTypes.oneOf([PropTypes.string, PropTypes.object]),
|
45
|
+
setHeader: PropTypes.func,
|
44
46
|
};
|
45
47
|
|
46
48
|
static renderLoader() {
|
@@ -72,7 +74,7 @@ class TabletsFilters extends React.Component {
|
|
72
74
|
reloadDescriptor = -1;
|
73
75
|
|
74
76
|
componentDidMount() {
|
75
|
-
const {setStateFilter, setTypeFilter} = this.props;
|
77
|
+
const {setStateFilter, setTypeFilter, setHeaderBreadcrumbs} = this.props;
|
76
78
|
|
77
79
|
const queryParams = qs.parse(this.props.location.search, {
|
78
80
|
ignoreQueryPrefix: true,
|
@@ -87,6 +89,10 @@ class TabletsFilters extends React.Component {
|
|
87
89
|
this.setState({nodeFilter: nodes, tenantPath: path}, () => {
|
88
90
|
this.makeRequest();
|
89
91
|
});
|
92
|
+
|
93
|
+
setHeaderBreadcrumbs('tablets', {
|
94
|
+
tenantName: path,
|
95
|
+
});
|
90
96
|
}
|
91
97
|
|
92
98
|
componentDidUpdate(prevProps) {
|
@@ -141,7 +147,13 @@ class TabletsFilters extends React.Component {
|
|
141
147
|
const {filteredTablets, size} = this.props;
|
142
148
|
|
143
149
|
return (
|
144
|
-
<Tablet
|
150
|
+
<Tablet
|
151
|
+
tablet={filteredTablets[index]}
|
152
|
+
tenantName={this.state.tenantPath}
|
153
|
+
key={key}
|
154
|
+
size={size}
|
155
|
+
className={b('tablet')}
|
156
|
+
/>
|
145
157
|
);
|
146
158
|
};
|
147
159
|
|
@@ -326,6 +338,7 @@ const mapDispatchToProps = {
|
|
326
338
|
clearWasLoadingFlag,
|
327
339
|
setStateFilter,
|
328
340
|
setTypeFilter,
|
341
|
+
setHeaderBreadcrumbs,
|
329
342
|
};
|
330
343
|
|
331
344
|
export default connect(mapStateToProps, mapDispatchToProps)(TabletsFilters);
|
@@ -42,7 +42,7 @@ export const columns: Column<IPreparedConsumerData>[] = [
|
|
42
42
|
<InternalLink
|
43
43
|
to={createHref(routes.tenant, undefined, {
|
44
44
|
...queryParams,
|
45
|
-
[TenantTabsGroups.
|
45
|
+
[TenantTabsGroups.diagnosticsTab]: TENANT_DIAGNOSTICS_TABS_IDS.partitions,
|
46
46
|
selectedConsumer: row.name,
|
47
47
|
})}
|
48
48
|
>
|
@@ -15,7 +15,7 @@ import {
|
|
15
15
|
setCurrentDescribePath,
|
16
16
|
getDescribeBatched,
|
17
17
|
} from '../../../../store/reducers/describe';
|
18
|
-
import {selectSchemaMergedChildrenPaths} from '../../../../store/reducers/schema';
|
18
|
+
import {selectSchemaMergedChildrenPaths} from '../../../../store/reducers/schema/schema';
|
19
19
|
import type {EPathType} from '../../../../types/api/schema';
|
20
20
|
|
21
21
|
import {isEntityWithMergedImplementation} from '../../utils/schema';
|
@@ -3,12 +3,19 @@ $section-title-line-height: 24px;
|
|
3
3
|
|
4
4
|
.kv-detailed-overview {
|
5
5
|
display: flex;
|
6
|
+
|
7
|
+
width: 100%;
|
8
|
+
height: 100%;
|
6
9
|
gap: 20px;
|
10
|
+
|
7
11
|
&__section {
|
8
12
|
display: flex;
|
9
13
|
overflow-x: hidden;
|
10
14
|
flex: 0 0 calc(50% - 10px);
|
11
15
|
flex-direction: column;
|
16
|
+
|
17
|
+
min-width: 300px;
|
18
|
+
height: max-content;
|
12
19
|
}
|
13
20
|
|
14
21
|
&__modal {
|
@@ -12,7 +12,7 @@ import type {EPathType} from '../../../types/api/schema';
|
|
12
12
|
import {useTypedSelector} from '../../../utils/hooks';
|
13
13
|
import routes, {createHref} from '../../../routes';
|
14
14
|
import type {TenantDiagnosticsTab, TenantGeneralTab} from '../../../store/reducers/tenant/types';
|
15
|
-
import {enableAutorefresh, disableAutorefresh} from '../../../store/reducers/schema';
|
15
|
+
import {enableAutorefresh, disableAutorefresh} from '../../../store/reducers/schema/schema';
|
16
16
|
import {setTopLevelTab, setDiagnosticsTab} from '../../../store/reducers/tenant/tenant';
|
17
17
|
import {TENANT_DIAGNOSTICS_TABS_IDS} from '../../../store/reducers/tenant/constants';
|
18
18
|
|
@@ -49,8 +49,8 @@ const b = cn('kv-tenant-diagnostics');
|
|
49
49
|
|
50
50
|
function Diagnostics(props: DiagnosticsProps) {
|
51
51
|
const dispatch = useDispatch();
|
52
|
-
const {currentSchemaPath, autorefresh} = useSelector((state: any) => state.schema);
|
53
|
-
const {diagnosticsTab = TENANT_DIAGNOSTICS_TABS_IDS.overview
|
52
|
+
const {currentSchemaPath, autorefresh, wasLoaded} = useSelector((state: any) => state.schema);
|
53
|
+
const {diagnosticsTab = TENANT_DIAGNOSTICS_TABS_IDS.overview} = useTypedSelector(
|
54
54
|
(state) => state.tenant,
|
55
55
|
);
|
56
56
|
|
@@ -176,7 +176,7 @@ function Diagnostics(props: DiagnosticsProps) {
|
|
176
176
|
wrapTo={({id}, node) => {
|
177
177
|
const path = createHref(routes.tenant, undefined, {
|
178
178
|
...queryParams,
|
179
|
-
[TenantTabsGroups.
|
179
|
+
[TenantTabsGroups.diagnosticsTab]: id,
|
180
180
|
});
|
181
181
|
|
182
182
|
return (
|
@@ -3,9 +3,11 @@
|
|
3
3
|
@import '@gravity-ui/uikit/styles/mixins.scss';
|
4
4
|
|
5
5
|
.healthcheck {
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
&_expanded {
|
7
|
+
// Since most of the inner containers have fixed width, we can set fixed width here as well
|
8
|
+
// Thus we will get rid of unneeded layout shift when scrollbar appear
|
9
|
+
min-width: 885px;
|
10
|
+
}
|
9
11
|
|
10
12
|
&__details {
|
11
13
|
padding: 25px 20px 20px;
|
@@ -99,5 +99,5 @@ export const Healthcheck = (props: HealthcheckProps) => {
|
|
99
99
|
return <div className="error">{i18n('no-data')}</div>;
|
100
100
|
};
|
101
101
|
|
102
|
-
return <div className={b()}>{renderContent()}</div>;
|
102
|
+
return <div className={b({expanded: !preview})}>{renderContent()}</div>;
|
103
103
|
};
|
@@ -7,7 +7,6 @@ import {
|
|
7
7
|
} from '../../../../../components/InfoViewer/formatters';
|
8
8
|
|
9
9
|
import {useTypedSelector} from '../../../../../utils/hooks';
|
10
|
-
import {selectSchemaData} from '../../../../../store/reducers/schema';
|
11
10
|
|
12
11
|
import {getEntityName} from '../../../utils';
|
13
12
|
|
@@ -42,27 +41,26 @@ const prepareChangefeedInfo = (
|
|
42
41
|
|
43
42
|
interface ChangefeedProps {
|
44
43
|
data?: TEvDescribeSchemeResult;
|
45
|
-
|
44
|
+
topic?: TEvDescribeSchemeResult;
|
46
45
|
}
|
47
46
|
|
48
47
|
/** Displays overview for CDCStream EPathType */
|
49
|
-
export const ChangefeedInfo = ({data,
|
48
|
+
export const ChangefeedInfo = ({data, topic}: ChangefeedProps) => {
|
50
49
|
const entityName = getEntityName(data?.PathDescription);
|
51
50
|
|
52
51
|
const {error: schemaError} = useTypedSelector((state) => state.schema);
|
53
|
-
const pqGroupData = useTypedSelector((state) => selectSchemaData(state, childrenPaths?.[0]));
|
54
52
|
|
55
53
|
if (schemaError) {
|
56
54
|
return <div className="error">{schemaError.statusText}</div>;
|
57
55
|
}
|
58
56
|
|
59
|
-
if (!data || !
|
57
|
+
if (!data || !topic) {
|
60
58
|
return <div className="error">No {entityName} data</div>;
|
61
59
|
}
|
62
60
|
|
63
61
|
return (
|
64
62
|
<div>
|
65
|
-
<InfoViewer title={entityName} info={prepareChangefeedInfo(data,
|
63
|
+
<InfoViewer title={entityName} info={prepareChangefeedInfo(data, topic)} />
|
66
64
|
<TopicStats />
|
67
65
|
</div>
|
68
66
|
);
|