ydb-embedded-ui 2.6.0 → 3.0.1
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.
- package/CHANGELOG.md +28 -0
- package/dist/components/ClusterInfo/ClusterInfo.tsx +1 -1
- package/dist/components/InfoViewer/InfoViewer.tsx +1 -1
- package/dist/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx +5 -2
- package/dist/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx +6 -5
- package/dist/components/InfoViewer/schemaInfo/TableIndexInfo.tsx +5 -2
- package/dist/components/ProblemFilter/ProblemFilter.tsx +18 -0
- package/dist/components/ProblemFilter/index.ts +1 -0
- package/dist/components/UptimeFIlter/UptimeFilter.tsx +4 -3
- package/dist/containers/Nodes/Nodes.js +2 -2
- package/dist/containers/NodesViewer/NodesViewer.js +2 -2
- package/dist/containers/Pool/Pool.js +2 -2
- package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +2 -3
- package/dist/containers/Tenant/Diagnostics/Network/Network.js +2 -2
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +11 -9
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +6 -3
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.scss +0 -4
- package/dist/containers/Tenant/Diagnostics/TopShards/{TopShards.js → TopShards.tsx} +95 -119
- package/dist/containers/Tenant/Diagnostics/TopShards/index.ts +1 -0
- package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.js +35 -22
- package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.scss +8 -0
- package/dist/containers/Tenant/Tenant.tsx +1 -1
- package/dist/containers/Tenant/utils/index.ts +8 -0
- package/dist/containers/Tenant/utils/schema.ts +45 -0
- package/dist/containers/Tenants/Tenants.js +2 -2
- package/dist/services/api.d.ts +3 -0
- package/dist/services/api.js +1 -1
- package/dist/store/reducers/{nodes.js → nodes.ts} +20 -14
- package/dist/store/reducers/{shardsWorkload.js → shardsWorkload.ts} +28 -13
- package/dist/store/reducers/{tooltip.js → tooltip.ts} +28 -11
- package/dist/types/api/nodes.ts +3 -3
- package/dist/types/api/schema.ts +1 -1
- package/dist/types/api/tenant.ts +131 -0
- package/dist/types/store/nodes.ts +32 -0
- package/dist/types/store/shardsWorkload.ts +19 -0
- package/dist/types/store/tooltip.ts +25 -0
- package/dist/utils/constants.ts +2 -0
- package/dist/utils/nodes.ts +4 -4
- package/dist/utils/tooltip.js +8 -6
- package/package.json +4 -3
- package/dist/components/ProblemFilter/ProblemFilter.js +0 -24
- package/dist/utils/actionsConstants.js +0 -4
@@ -1,27 +1,34 @@
|
|
1
1
|
import {useState, useContext, useEffect, useMemo} from 'react';
|
2
|
+
import {useDispatch} from 'react-redux';
|
2
3
|
import cn from 'bem-cn-lite';
|
3
|
-
|
4
|
+
|
5
|
+
import DataTable, {Column, Settings, SortOrder} from '@yandex-cloud/react-data-table';
|
4
6
|
import {Loader} from '@gravity-ui/uikit';
|
5
|
-
import DataTable from '@yandex-cloud/react-data-table';
|
6
7
|
|
7
8
|
import InternalLink from '../../../../components/InternalLink/InternalLink';
|
8
9
|
|
10
|
+
import HistoryContext from '../../../../contexts/HistoryContext';
|
11
|
+
|
9
12
|
import routes, {createHref} from '../../../../routes';
|
13
|
+
|
10
14
|
import {sendShardQuery, setShardQueryOptions} from '../../../../store/reducers/shardsWorkload';
|
11
15
|
import {setCurrentSchemaPath, getSchema} from '../../../../store/reducers/schema';
|
12
|
-
|
13
|
-
import
|
16
|
+
|
17
|
+
import type {EPathType} from '../../../../types/api/schema';
|
18
|
+
|
14
19
|
import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants';
|
15
|
-
import {
|
16
|
-
import {prepareQueryError} from '../../../../utils/query';
|
20
|
+
import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
|
17
21
|
import {i18n} from '../../../../utils/i18n';
|
22
|
+
import {prepareQueryError} from '../../../../utils/query';
|
23
|
+
|
24
|
+
import {isColumnEntityType} from '../../utils/schema';
|
18
25
|
|
19
26
|
import './TopShards.scss';
|
20
27
|
|
21
28
|
const b = cn('top-shards');
|
22
29
|
const bLink = cn('yc-link');
|
23
30
|
|
24
|
-
const TABLE_SETTINGS = {
|
31
|
+
const TABLE_SETTINGS: Settings = {
|
25
32
|
...DEFAULT_TABLE_SETTINGS,
|
26
33
|
dynamicRender: false, // no more than 20 rows
|
27
34
|
externalSort: true,
|
@@ -36,121 +43,108 @@ const tableColumnsNames = {
|
|
36
43
|
Path: 'Path',
|
37
44
|
};
|
38
45
|
|
39
|
-
|
40
|
-
|
41
|
-
function prepareCPUWorkloadValue(value) {
|
42
|
-
return `${(value * 100).toFixed(2)}%`;
|
46
|
+
function prepareCPUWorkloadValue(value: string) {
|
47
|
+
return `${(Number(value) * 100).toFixed(2)}%`;
|
43
48
|
}
|
44
49
|
|
45
|
-
function prepareDateSizeValue(value) {
|
50
|
+
function prepareDateSizeValue(value: number) {
|
46
51
|
return new Intl.NumberFormat(i18n.lang).format(value);
|
47
52
|
}
|
48
53
|
|
49
|
-
function stringToDataTableSortOrder(value) {
|
50
|
-
return
|
51
|
-
value
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
);
|
54
|
+
function stringToDataTableSortOrder(value: string): SortOrder[] | undefined {
|
55
|
+
return value
|
56
|
+
? value.split(',').map((columnId) => ({
|
57
|
+
columnId,
|
58
|
+
order: DataTable.DESCENDING,
|
59
|
+
}))
|
60
|
+
: undefined;
|
57
61
|
}
|
58
62
|
|
59
|
-
function stringToQuerySortOrder(value) {
|
60
|
-
return
|
61
|
-
value
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
);
|
63
|
+
function stringToQuerySortOrder(value: string) {
|
64
|
+
return value
|
65
|
+
? value.split(',').map((columnId) => ({
|
66
|
+
columnId,
|
67
|
+
order: 'DESC',
|
68
|
+
}))
|
69
|
+
: undefined;
|
67
70
|
}
|
68
71
|
|
69
|
-
function dataTableToStringSortOrder(value = []) {
|
70
|
-
|
72
|
+
function dataTableToStringSortOrder(value: SortOrder | SortOrder[] = []) {
|
73
|
+
const sortOrders = Array.isArray(value) ? value : [value];
|
74
|
+
return sortOrders.map(({columnId}) => columnId).join(',');
|
71
75
|
}
|
72
76
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
loading,
|
78
|
-
data,
|
79
|
-
error,
|
80
|
-
setCurrentSchemaPath,
|
81
|
-
getSchema,
|
82
|
-
autorefresh,
|
83
|
-
wasLoaded,
|
84
|
-
setShardQueryOptions,
|
85
|
-
type,
|
86
|
-
}) {
|
87
|
-
const [sortOrder, setSortOrder] = useState(tableColumnsNames.CPUCores);
|
77
|
+
interface TopShardsProps {
|
78
|
+
tenantPath: string;
|
79
|
+
type?: EPathType;
|
80
|
+
}
|
88
81
|
|
89
|
-
|
90
|
-
|
82
|
+
export const TopShards = ({tenantPath, type}: TopShardsProps) => {
|
83
|
+
const dispatch = useDispatch();
|
84
|
+
|
85
|
+
const {autorefresh, currentSchemaPath} = useTypedSelector((state) => state.schema);
|
86
|
+
|
87
|
+
const {
|
88
|
+
loading,
|
89
|
+
data: {result: data = undefined} = {},
|
90
|
+
error,
|
91
|
+
wasLoaded,
|
92
|
+
} = useTypedSelector((state) => state.shardsWorkload);
|
91
93
|
|
92
|
-
|
93
|
-
|
94
|
-
|
94
|
+
const [sortOrder, setSortOrder] = useState(tableColumnsNames.CPUCores);
|
95
|
+
|
96
|
+
useAutofetcher(
|
97
|
+
() => {
|
98
|
+
dispatch(
|
95
99
|
sendShardQuery({
|
96
|
-
database:
|
100
|
+
database: tenantPath,
|
97
101
|
path: currentSchemaPath,
|
98
102
|
sortOrder: stringToQuerySortOrder(sortOrder),
|
99
103
|
}),
|
100
104
|
);
|
101
|
-
}
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
};
|
106
|
-
}, [autorefresh, currentSchemaPath, path, sendShardQuery, sortOrder]);
|
105
|
+
},
|
106
|
+
[dispatch, currentSchemaPath, tenantPath, sortOrder],
|
107
|
+
autorefresh,
|
108
|
+
);
|
107
109
|
|
108
110
|
// don't show loader for requests triggered by table sort, only for path change
|
109
111
|
useEffect(() => {
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
sendShardQuery({
|
118
|
-
database: path,
|
119
|
-
path: currentSchemaPath,
|
120
|
-
sortOrder: stringToQuerySortOrder(sortOrder),
|
121
|
-
});
|
122
|
-
}, [currentSchemaPath, path, sendShardQuery, sortOrder]);
|
112
|
+
dispatch(
|
113
|
+
setShardQueryOptions({
|
114
|
+
wasLoaded: false,
|
115
|
+
data: undefined,
|
116
|
+
}),
|
117
|
+
);
|
118
|
+
}, [dispatch, currentSchemaPath, tenantPath]);
|
123
119
|
|
124
120
|
const history = useContext(HistoryContext);
|
125
121
|
|
126
|
-
const
|
127
|
-
return () => {
|
128
|
-
setCurrentSchemaPath(schemaPath);
|
129
|
-
getSchema({path: schemaPath});
|
130
|
-
history.go(0);
|
131
|
-
};
|
132
|
-
};
|
133
|
-
|
134
|
-
const onSort = (newSortOrder) => {
|
122
|
+
const onSort = (newSortOrder?: SortOrder | SortOrder[]) => {
|
135
123
|
// omit information about sort order to disable ASC order, only DESC makes sense for top shards
|
136
124
|
// use a string (and not the DataTable default format) to prevent reference change,
|
137
125
|
// which would cause an excess state change, to avoid repeating requests
|
138
126
|
setSortOrder(dataTableToStringSortOrder(newSortOrder));
|
139
127
|
};
|
140
128
|
|
141
|
-
const tableColumns = useMemo(() => {
|
129
|
+
const tableColumns: Column<any>[] = useMemo(() => {
|
130
|
+
const onSchemaClick = (schemaPath: string) => {
|
131
|
+
return () => {
|
132
|
+
dispatch(setCurrentSchemaPath(schemaPath));
|
133
|
+
dispatch(getSchema({path: schemaPath}));
|
134
|
+
history.go(0);
|
135
|
+
};
|
136
|
+
};
|
137
|
+
|
142
138
|
return [
|
143
139
|
{
|
144
140
|
name: tableColumnsNames.Path,
|
145
|
-
|
146
|
-
render: ({value}) => {
|
141
|
+
render: ({value: relativeNodePath}) => {
|
147
142
|
return (
|
148
143
|
<span
|
149
|
-
|
150
|
-
onClick={onSchemaClick(path + value)}
|
144
|
+
onClick={onSchemaClick(tenantPath + relativeNodePath)}
|
151
145
|
className={bLink({view: 'normal'})}
|
152
146
|
>
|
153
|
-
{
|
147
|
+
{relativeNodePath as string}
|
154
148
|
</span>
|
155
149
|
);
|
156
150
|
},
|
@@ -158,9 +152,8 @@ function TopShards({
|
|
158
152
|
},
|
159
153
|
{
|
160
154
|
name: tableColumnsNames.CPUCores,
|
161
|
-
// eslint-disable-next-line
|
162
155
|
render: ({value}) => {
|
163
|
-
return prepareCPUWorkloadValue(value);
|
156
|
+
return prepareCPUWorkloadValue(value as string);
|
164
157
|
},
|
165
158
|
align: DataTable.RIGHT,
|
166
159
|
},
|
@@ -168,24 +161,23 @@ function TopShards({
|
|
168
161
|
name: tableColumnsNames.DataSize,
|
169
162
|
header: 'DataSize (B)',
|
170
163
|
render: ({value}) => {
|
171
|
-
return prepareDateSizeValue(value);
|
164
|
+
return prepareDateSizeValue(value as number);
|
172
165
|
},
|
173
166
|
align: DataTable.RIGHT,
|
174
167
|
},
|
175
168
|
{
|
176
169
|
name: tableColumnsNames.TabletId,
|
177
|
-
// eslint-disable-next-line
|
178
170
|
render: ({value}) => {
|
179
171
|
return (
|
180
172
|
<InternalLink to={createHref(routes.tablet, {id: value})}>
|
181
|
-
{value}
|
173
|
+
{value as string}
|
182
174
|
</InternalLink>
|
183
175
|
);
|
184
176
|
},
|
185
177
|
sortable: false,
|
186
178
|
},
|
187
179
|
];
|
188
|
-
}, []);
|
180
|
+
}, [dispatch, history, tenantPath]);
|
189
181
|
|
190
182
|
const renderLoader = () => {
|
191
183
|
return (
|
@@ -196,51 +188,35 @@ function TopShards({
|
|
196
188
|
};
|
197
189
|
|
198
190
|
const renderContent = () => {
|
199
|
-
if (
|
191
|
+
if (loading && !wasLoaded) {
|
192
|
+
return renderLoader();
|
193
|
+
}
|
194
|
+
|
195
|
+
if (!data || data.length === 0 || isColumnEntityType(type)) {
|
200
196
|
return 'No data';
|
201
197
|
}
|
198
|
+
|
202
199
|
if (error && !error.isCancelled) {
|
203
200
|
return prepareQueryError(error);
|
204
201
|
}
|
205
202
|
|
206
|
-
return
|
203
|
+
return (
|
207
204
|
<div className={b('table')}>
|
208
205
|
<DataTable
|
209
206
|
columns={tableColumns}
|
210
207
|
data={data}
|
211
208
|
settings={TABLE_SETTINGS}
|
212
|
-
className={b('table')}
|
213
209
|
theme="yandex-cloud"
|
214
210
|
onSort={onSort}
|
215
211
|
sortOrder={stringToDataTableSortOrder(sortOrder)}
|
216
212
|
/>
|
217
213
|
</div>
|
218
|
-
) : (
|
219
|
-
data
|
220
214
|
);
|
221
215
|
};
|
222
216
|
|
223
|
-
return
|
224
|
-
}
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
const {autorefresh} = state.schema;
|
229
|
-
return {
|
230
|
-
loading,
|
231
|
-
data: data.result,
|
232
|
-
error,
|
233
|
-
currentSchemaPath: state.schema?.currentSchema?.Path,
|
234
|
-
autorefresh,
|
235
|
-
wasLoaded,
|
236
|
-
};
|
237
|
-
};
|
238
|
-
|
239
|
-
const mapDispatchToProps = {
|
240
|
-
sendShardQuery,
|
241
|
-
setCurrentSchemaPath,
|
242
|
-
getSchema,
|
243
|
-
setShardQueryOptions,
|
217
|
+
return (
|
218
|
+
<div className={b()}>
|
219
|
+
{renderContent()}
|
220
|
+
</div>
|
221
|
+
);
|
244
222
|
};
|
245
|
-
|
246
|
-
export default connect(mapStateToProps, mapDispatchToProps)(TopShards);
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './TopShards';
|
@@ -1,12 +1,15 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import cn from 'bem-cn-lite';
|
4
|
-
import './SchemaInfoViewer.scss';
|
5
4
|
|
6
5
|
import {formatCPU, formatBytes, formatNumber, formatBps, formatDateTime} from '../../../../utils';
|
7
6
|
|
8
7
|
import {InfoViewer, createInfoFormatter} from '../../../../components/InfoViewer';
|
9
8
|
|
9
|
+
import {getEntityName} from '../../utils';
|
10
|
+
|
11
|
+
import './SchemaInfoViewer.scss';
|
12
|
+
|
10
13
|
const b = cn('schema-info-viewer');
|
11
14
|
|
12
15
|
const formatTabletMetricsItem = createInfoFormatter({
|
@@ -68,6 +71,8 @@ class SchemaInfoViewer extends React.Component {
|
|
68
71
|
|
69
72
|
renderContent(data) {
|
70
73
|
const {PathDescription = {}} = data;
|
74
|
+
const entityName = getEntityName(PathDescription);
|
75
|
+
|
71
76
|
const {
|
72
77
|
TableStats = {},
|
73
78
|
TabletMetrics = {},
|
@@ -99,13 +104,15 @@ class SchemaInfoViewer extends React.Component {
|
|
99
104
|
} = TableStats;
|
100
105
|
const {FollowerGroups, FollowerCount, CrossDataCenterFollowerCount} = PartitionConfig;
|
101
106
|
|
107
|
+
const generalTableInfo = formatTableStats({
|
108
|
+
PartCount,
|
109
|
+
RowCount,
|
110
|
+
DataSize,
|
111
|
+
IndexSize,
|
112
|
+
...restTableStats,
|
113
|
+
});
|
114
|
+
|
102
115
|
const tableStatsInfo = [
|
103
|
-
formatTableStats({
|
104
|
-
PartCount,
|
105
|
-
RowCount,
|
106
|
-
DataSize,
|
107
|
-
IndexSize,
|
108
|
-
}),
|
109
116
|
formatTableStats({
|
110
117
|
LastAccessTime,
|
111
118
|
LastUpdateTime,
|
@@ -125,7 +132,6 @@ class SchemaInfoViewer extends React.Component {
|
|
125
132
|
RangeReads,
|
126
133
|
RangeReadRows,
|
127
134
|
}),
|
128
|
-
formatTableStats(restTableStats),
|
129
135
|
];
|
130
136
|
|
131
137
|
const tabletMetricsInfo = Object.keys(TabletMetrics).map((key) =>
|
@@ -151,24 +157,30 @@ class SchemaInfoViewer extends React.Component {
|
|
151
157
|
);
|
152
158
|
}
|
153
159
|
|
154
|
-
if (
|
155
|
-
|
160
|
+
if (
|
161
|
+
[generalTableInfo, tabletMetricsInfo, partitionConfigInfo, tableStatsInfo.flat()].flat()
|
162
|
+
.length === 0
|
163
|
+
) {
|
164
|
+
return <div className={b('title')}>{entityName}</div>;
|
156
165
|
}
|
157
166
|
|
158
167
|
return (
|
159
|
-
<div
|
160
|
-
{
|
168
|
+
<div>
|
169
|
+
<div>{this.renderItem(generalTableInfo, entityName)}</div>
|
170
|
+
<div className={b('row')}>
|
171
|
+
{tabletMetricsInfo.length > 0 || partitionConfigInfo.length > 0 ? (
|
172
|
+
<div className={b('col')}>
|
173
|
+
{this.renderItem(tabletMetricsInfo, 'Tablet Metrics')}
|
174
|
+
{this.renderItem(partitionConfigInfo, 'Partition Config')}
|
175
|
+
</div>
|
176
|
+
) : null}
|
161
177
|
<div className={b('col')}>
|
162
|
-
{
|
163
|
-
|
178
|
+
{tableStatsInfo.map((info, index) => (
|
179
|
+
<React.Fragment key={index}>
|
180
|
+
{this.renderItem(info, index === 0 ? 'Table Stats' : undefined)}
|
181
|
+
</React.Fragment>
|
182
|
+
))}
|
164
183
|
</div>
|
165
|
-
) : null}
|
166
|
-
<div className={b('col')}>
|
167
|
-
{tableStatsInfo.map((info, index) => (
|
168
|
-
<React.Fragment key={index}>
|
169
|
-
{this.renderItem(info, index === 0 ? 'Table Stats' : undefined)}
|
170
|
-
</React.Fragment>
|
171
|
-
))}
|
172
184
|
</div>
|
173
185
|
</div>
|
174
186
|
);
|
@@ -176,11 +188,12 @@ class SchemaInfoViewer extends React.Component {
|
|
176
188
|
|
177
189
|
render() {
|
178
190
|
const {data} = this.props;
|
191
|
+
const entityName = getEntityName(data?.PathDescription);
|
179
192
|
|
180
193
|
if (data) {
|
181
194
|
return <div className={b()}>{this.renderContent(data)}</div>;
|
182
195
|
} else {
|
183
|
-
return <div className="error">
|
196
|
+
return <div className="error">No {entityName} data</div>;
|
184
197
|
}
|
185
198
|
}
|
186
199
|
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import {TPathDescription} from '../../../types/api/schema';
|
2
|
+
import {mapPathTypeToEntityName} from './schema';
|
3
|
+
|
4
|
+
export const getEntityName = (pathDescription?: TPathDescription) => {
|
5
|
+
const {PathType, PathSubType} = pathDescription?.Self || {};
|
6
|
+
|
7
|
+
return mapPathTypeToEntityName(PathType, PathSubType);
|
8
|
+
};
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import type {NavigationTreeNodeType} from 'ydb-ui-components';
|
2
|
+
|
2
3
|
import {EPathSubType, EPathType} from '../../../types/api/schema';
|
4
|
+
import {ETenantType} from '../../../types/api/tenant';
|
3
5
|
|
4
6
|
// this file contains verbose mappings that are typed in a way that ensures
|
5
7
|
// correctness when a new node type or a new path type is added
|
@@ -41,6 +43,49 @@ export const mapPathTypeToNavigationTreeType = (
|
|
41
43
|
|
42
44
|
// ====================
|
43
45
|
|
46
|
+
const pathSubTypeToEntityName: Record<EPathSubType, string | undefined> = {
|
47
|
+
[EPathSubType.EPathSubTypeSyncIndexImplTable]: 'Secondary Index Table',
|
48
|
+
[EPathSubType.EPathSubTypeAsyncIndexImplTable]: 'Secondary Index Table',
|
49
|
+
|
50
|
+
[EPathSubType.EPathSubTypeStreamImpl]: undefined,
|
51
|
+
[EPathSubType.EPathSubTypeEmpty]: undefined,
|
52
|
+
};
|
53
|
+
|
54
|
+
const pathTypeToEntityName: Record<EPathType, string | undefined> = {
|
55
|
+
[EPathType.EPathTypeInvalid]: undefined,
|
56
|
+
|
57
|
+
[EPathType.EPathTypeSubDomain]: 'Database',
|
58
|
+
[EPathType.EPathTypeExtSubDomain]: 'Database',
|
59
|
+
|
60
|
+
[EPathType.EPathTypeDir]: 'Directory',
|
61
|
+
[EPathType.EPathTypeTable]: 'Table',
|
62
|
+
[EPathType.EPathTypeTableIndex]: 'Secondary Index',
|
63
|
+
[EPathType.EPathTypeColumnStore]: 'Tablestore',
|
64
|
+
[EPathType.EPathTypeColumnTable]: 'Columntable',
|
65
|
+
[EPathType.EPathTypeCdcStream]: 'Changefeed',
|
66
|
+
[EPathType.EPathTypePersQueueGroup]: 'Topic',
|
67
|
+
};
|
68
|
+
|
69
|
+
export const mapPathTypeToEntityName = (
|
70
|
+
type?: EPathType,
|
71
|
+
subType?: EPathSubType,
|
72
|
+
): string | undefined =>
|
73
|
+
(subType && pathSubTypeToEntityName[subType]) || (type && pathTypeToEntityName[type]);
|
74
|
+
|
75
|
+
// ====================
|
76
|
+
|
77
|
+
const databaseTypeToDBName: Record<ETenantType, string | undefined> = {
|
78
|
+
[ETenantType.UnknownTenantType]: 'Database',
|
79
|
+
[ETenantType.Domain]: 'Cluster Root',
|
80
|
+
[ETenantType.Dedicated]: 'Dedicated Database',
|
81
|
+
[ETenantType.Shared]: 'Shared Database',
|
82
|
+
[ETenantType.Serverless]: 'Serverless Database',
|
83
|
+
};
|
84
|
+
|
85
|
+
export const mapDatabaseTypeToDBName = (type?: ETenantType) => type && databaseTypeToDBName[type];
|
86
|
+
|
87
|
+
// ====================
|
88
|
+
|
44
89
|
const pathTypeToIsTable: Record<EPathType, boolean> = {
|
45
90
|
[EPathType.EPathTypeTable]: true,
|
46
91
|
[EPathType.EPathTypeColumnTable]: true,
|
@@ -10,7 +10,7 @@ import {Loader, TextInput, Button} from '@gravity-ui/uikit';
|
|
10
10
|
import EntityStatus from '../../components/EntityStatus/EntityStatus';
|
11
11
|
import PoolsGraph from '../../components/PoolsGraph/PoolsGraph';
|
12
12
|
import TabletsStatistic from '../../components/TabletsStatistic/TabletsStatistic';
|
13
|
-
import ProblemFilter
|
13
|
+
import {ProblemFilter} from '../../components/ProblemFilter';
|
14
14
|
import {Illustration} from '../../components/Illustration';
|
15
15
|
import {AutoFetcher} from '../../utils/autofetcher';
|
16
16
|
|
@@ -50,7 +50,7 @@ class Tenants extends React.Component {
|
|
50
50
|
searchQuery: PropTypes.string,
|
51
51
|
handleSearchQuery: PropTypes.func,
|
52
52
|
setHeader: PropTypes.func,
|
53
|
-
filter:
|
53
|
+
filter: PropTypes.string,
|
54
54
|
changeFilter: PropTypes.func,
|
55
55
|
cluster: PropTypes.object,
|
56
56
|
singleClusterMode: PropTypes.bool,
|
package/dist/services/api.d.ts
CHANGED
@@ -45,6 +45,9 @@ interface Window {
|
|
45
45
|
getHealthcheckInfo: (
|
46
46
|
database: string,
|
47
47
|
) => Promise<import('../types/api/healthcheck').HealthCheckAPIResponse>;
|
48
|
+
getTenantInfo: (params: {
|
49
|
+
path: string;
|
50
|
+
}) => Promise<import('../types/api/tenant').TTenantInfo>;
|
48
51
|
[method: string]: Function;
|
49
52
|
};
|
50
53
|
}
|
package/dist/services/api.js
CHANGED
@@ -1,8 +1,12 @@
|
|
1
|
-
import {
|
1
|
+
import type {Reducer} from 'redux';
|
2
|
+
|
2
3
|
import '../../services/api';
|
3
4
|
import {NodesUptimeFilterValues} from '../../utils/nodes';
|
5
|
+
import {INodesAction, INodesRootStateSlice, INodesState} from '../../types/store/nodes';
|
6
|
+
|
7
|
+
import {createRequestActionTypes, createApiRequest} from '../utils';
|
4
8
|
|
5
|
-
const FETCH_NODES = createRequestActionTypes('nodes', 'FETCH_NODES');
|
9
|
+
export const FETCH_NODES = createRequestActionTypes('nodes', 'FETCH_NODES');
|
6
10
|
|
7
11
|
const CLEAR_NODES = 'nodes/CLEAR_NODES';
|
8
12
|
const SET_NODES_UPTIME_FILTER = 'nodes/SET_NODES_UPTIME_FILTER';
|
@@ -14,13 +18,12 @@ const initialState = {
|
|
14
18
|
nodesUptimeFilter: NodesUptimeFilterValues.All,
|
15
19
|
};
|
16
20
|
|
17
|
-
const nodes = (state = initialState, action) => {
|
21
|
+
const nodes: Reducer<INodesState, INodesAction> = (state = initialState, action) => {
|
18
22
|
switch (action.type) {
|
19
23
|
case FETCH_NODES.REQUEST: {
|
20
24
|
return {
|
21
25
|
...state,
|
22
26
|
loading: true,
|
23
|
-
requestTime: new Date().getTime(),
|
24
27
|
};
|
25
28
|
}
|
26
29
|
case FETCH_NODES.SUCCESS: {
|
@@ -45,13 +48,15 @@ const nodes = (state = initialState, action) => {
|
|
45
48
|
loading: true,
|
46
49
|
data: undefined,
|
47
50
|
wasLoaded: false,
|
48
|
-
requestTime: new Date().getTime(),
|
49
51
|
error: undefined,
|
50
52
|
};
|
51
53
|
}
|
52
54
|
|
53
55
|
case SET_NODES_UPTIME_FILTER: {
|
54
|
-
return {
|
56
|
+
return {
|
57
|
+
...state,
|
58
|
+
nodesUptimeFilter: action.data,
|
59
|
+
};
|
55
60
|
}
|
56
61
|
case SET_DATA_WAS_NOT_LOADED: {
|
57
62
|
return {
|
@@ -64,26 +69,27 @@ const nodes = (state = initialState, action) => {
|
|
64
69
|
}
|
65
70
|
};
|
66
71
|
|
67
|
-
export function getNodes(path) {
|
72
|
+
export function getNodes(path: string) {
|
68
73
|
return createApiRequest({
|
69
74
|
request: window.api.getNodes(path),
|
70
75
|
actions: FETCH_NODES,
|
71
76
|
});
|
72
77
|
}
|
73
78
|
|
74
|
-
export const clearNodes = () => ({type: CLEAR_NODES});
|
79
|
+
export const clearNodes = () => ({type: CLEAR_NODES} as const);
|
75
80
|
|
76
|
-
export const setNodesUptimeFilter = (value) =>
|
77
|
-
|
78
|
-
|
79
|
-
|
81
|
+
export const setNodesUptimeFilter = (value: NodesUptimeFilterValues) =>
|
82
|
+
({
|
83
|
+
type: SET_NODES_UPTIME_FILTER,
|
84
|
+
data: value,
|
85
|
+
} as const);
|
80
86
|
|
81
87
|
export const setDataWasNotLoaded = () => {
|
82
88
|
return {
|
83
89
|
type: SET_DATA_WAS_NOT_LOADED,
|
84
|
-
};
|
90
|
+
} as const;
|
85
91
|
};
|
86
92
|
|
87
|
-
export const getNodesUptimeFilter = (state) => state.nodes.nodesUptimeFilter;
|
93
|
+
export const getNodesUptimeFilter = (state: INodesRootStateSlice) => state.nodes.nodesUptimeFilter;
|
88
94
|
|
89
95
|
export default nodes;
|