ydb-embedded-ui 3.0.0 → 3.1.0
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 +17 -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/DateRange/DateRange.scss +13 -0
- package/dist/containers/Tenant/Diagnostics/TopShards/DateRange/DateRange.tsx +75 -0
- package/dist/containers/Tenant/Diagnostics/TopShards/DateRange/index.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.scss +17 -1
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +278 -0
- package/dist/containers/Tenant/Diagnostics/TopShards/i18n/en.json +4 -0
- package/dist/containers/Tenant/Diagnostics/TopShards/i18n/index.ts +11 -0
- package/dist/containers/Tenant/Diagnostics/TopShards/i18n/ru.json +4 -0
- 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.ts +182 -0
- package/dist/store/reducers/{tooltip.js → tooltip.ts} +28 -11
- package/dist/store/state-url-mapping.js +8 -0
- 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 +28 -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/query.ts +1 -1
- package/dist/utils/tooltip.js +8 -6
- package/package.json +2 -2
- package/dist/components/ProblemFilter/ProblemFilter.js +0 -24
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +0 -246
- package/dist/store/reducers/shardsWorkload.js +0 -101
- package/dist/utils/actionsConstants.js +0 -4
@@ -1,246 +0,0 @@
|
|
1
|
-
import {useState, useContext, useEffect, useMemo} from 'react';
|
2
|
-
import cn from 'bem-cn-lite';
|
3
|
-
import {connect} from 'react-redux';
|
4
|
-
import {Loader} from '@gravity-ui/uikit';
|
5
|
-
import DataTable from '@yandex-cloud/react-data-table';
|
6
|
-
|
7
|
-
import InternalLink from '../../../../components/InternalLink/InternalLink';
|
8
|
-
|
9
|
-
import routes, {createHref} from '../../../../routes';
|
10
|
-
import {sendShardQuery, setShardQueryOptions} from '../../../../store/reducers/shardsWorkload';
|
11
|
-
import {setCurrentSchemaPath, getSchema} from '../../../../store/reducers/schema';
|
12
|
-
import {AutoFetcher} from '../../../../utils/autofetcher';
|
13
|
-
import HistoryContext from '../../../../contexts/HistoryContext';
|
14
|
-
import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants';
|
15
|
-
import {isColumnEntityType} from '../../utils/schema';
|
16
|
-
import {prepareQueryError} from '../../../../utils/query';
|
17
|
-
import {i18n} from '../../../../utils/i18n';
|
18
|
-
|
19
|
-
import './TopShards.scss';
|
20
|
-
|
21
|
-
const b = cn('top-shards');
|
22
|
-
const bLink = cn('yc-link');
|
23
|
-
|
24
|
-
const TABLE_SETTINGS = {
|
25
|
-
...DEFAULT_TABLE_SETTINGS,
|
26
|
-
dynamicRender: false, // no more than 20 rows
|
27
|
-
externalSort: true,
|
28
|
-
disableSortReset: true,
|
29
|
-
defaultOrder: DataTable.DESCENDING,
|
30
|
-
};
|
31
|
-
|
32
|
-
const tableColumnsNames = {
|
33
|
-
TabletId: 'TabletId',
|
34
|
-
CPUCores: 'CPUCores',
|
35
|
-
DataSize: 'DataSize',
|
36
|
-
Path: 'Path',
|
37
|
-
};
|
38
|
-
|
39
|
-
const autofetcher = new AutoFetcher();
|
40
|
-
|
41
|
-
function prepareCPUWorkloadValue(value) {
|
42
|
-
return `${(value * 100).toFixed(2)}%`;
|
43
|
-
}
|
44
|
-
|
45
|
-
function prepareDateSizeValue(value) {
|
46
|
-
return new Intl.NumberFormat(i18n.lang).format(value);
|
47
|
-
}
|
48
|
-
|
49
|
-
function stringToDataTableSortOrder(value) {
|
50
|
-
return (
|
51
|
-
value &&
|
52
|
-
value.split(',').map((columnId) => ({
|
53
|
-
columnId,
|
54
|
-
order: DataTable.DESCENDING,
|
55
|
-
}))
|
56
|
-
);
|
57
|
-
}
|
58
|
-
|
59
|
-
function stringToQuerySortOrder(value) {
|
60
|
-
return (
|
61
|
-
value &&
|
62
|
-
value.split(',').map((columnId) => ({
|
63
|
-
columnId,
|
64
|
-
order: 'DESC',
|
65
|
-
}))
|
66
|
-
);
|
67
|
-
}
|
68
|
-
|
69
|
-
function dataTableToStringSortOrder(value = []) {
|
70
|
-
return value.map(({columnId}) => columnId).join(',');
|
71
|
-
}
|
72
|
-
|
73
|
-
function TopShards({
|
74
|
-
sendShardQuery,
|
75
|
-
currentSchemaPath,
|
76
|
-
path,
|
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);
|
88
|
-
|
89
|
-
useEffect(() => {
|
90
|
-
autofetcher.stop();
|
91
|
-
|
92
|
-
if (autorefresh) {
|
93
|
-
autofetcher.start();
|
94
|
-
autofetcher.fetch(() =>
|
95
|
-
sendShardQuery({
|
96
|
-
database: path,
|
97
|
-
path: currentSchemaPath,
|
98
|
-
sortOrder: stringToQuerySortOrder(sortOrder),
|
99
|
-
}),
|
100
|
-
);
|
101
|
-
}
|
102
|
-
|
103
|
-
return () => {
|
104
|
-
autofetcher.stop();
|
105
|
-
};
|
106
|
-
}, [autorefresh, currentSchemaPath, path, sendShardQuery, sortOrder]);
|
107
|
-
|
108
|
-
// don't show loader for requests triggered by table sort, only for path change
|
109
|
-
useEffect(() => {
|
110
|
-
setShardQueryOptions({
|
111
|
-
wasLoaded: false,
|
112
|
-
data: undefined,
|
113
|
-
});
|
114
|
-
}, [currentSchemaPath, path, setShardQueryOptions]);
|
115
|
-
|
116
|
-
useEffect(() => {
|
117
|
-
sendShardQuery({
|
118
|
-
database: path,
|
119
|
-
path: currentSchemaPath,
|
120
|
-
sortOrder: stringToQuerySortOrder(sortOrder),
|
121
|
-
});
|
122
|
-
}, [currentSchemaPath, path, sendShardQuery, sortOrder]);
|
123
|
-
|
124
|
-
const history = useContext(HistoryContext);
|
125
|
-
|
126
|
-
const onSchemaClick = (schemaPath) => {
|
127
|
-
return () => {
|
128
|
-
setCurrentSchemaPath(schemaPath);
|
129
|
-
getSchema({path: schemaPath});
|
130
|
-
history.go(0);
|
131
|
-
};
|
132
|
-
};
|
133
|
-
|
134
|
-
const onSort = (newSortOrder) => {
|
135
|
-
// omit information about sort order to disable ASC order, only DESC makes sense for top shards
|
136
|
-
// use a string (and not the DataTable default format) to prevent reference change,
|
137
|
-
// which would cause an excess state change, to avoid repeating requests
|
138
|
-
setSortOrder(dataTableToStringSortOrder(newSortOrder));
|
139
|
-
};
|
140
|
-
|
141
|
-
const tableColumns = useMemo(() => {
|
142
|
-
return [
|
143
|
-
{
|
144
|
-
name: tableColumnsNames.Path,
|
145
|
-
// eslint-disable-next-line
|
146
|
-
render: ({value}) => {
|
147
|
-
return (
|
148
|
-
<span
|
149
|
-
// tenant name is substringed out in sql query but is needed here
|
150
|
-
onClick={onSchemaClick(path + value)}
|
151
|
-
className={bLink({view: 'normal'})}
|
152
|
-
>
|
153
|
-
{value}
|
154
|
-
</span>
|
155
|
-
);
|
156
|
-
},
|
157
|
-
sortable: false,
|
158
|
-
},
|
159
|
-
{
|
160
|
-
name: tableColumnsNames.CPUCores,
|
161
|
-
// eslint-disable-next-line
|
162
|
-
render: ({value}) => {
|
163
|
-
return prepareCPUWorkloadValue(value);
|
164
|
-
},
|
165
|
-
align: DataTable.RIGHT,
|
166
|
-
},
|
167
|
-
{
|
168
|
-
name: tableColumnsNames.DataSize,
|
169
|
-
header: 'DataSize (B)',
|
170
|
-
render: ({value}) => {
|
171
|
-
return prepareDateSizeValue(value);
|
172
|
-
},
|
173
|
-
align: DataTable.RIGHT,
|
174
|
-
},
|
175
|
-
{
|
176
|
-
name: tableColumnsNames.TabletId,
|
177
|
-
// eslint-disable-next-line
|
178
|
-
render: ({value}) => {
|
179
|
-
return (
|
180
|
-
<InternalLink to={createHref(routes.tablet, {id: value})}>
|
181
|
-
{value}
|
182
|
-
</InternalLink>
|
183
|
-
);
|
184
|
-
},
|
185
|
-
sortable: false,
|
186
|
-
},
|
187
|
-
];
|
188
|
-
}, []);
|
189
|
-
|
190
|
-
const renderLoader = () => {
|
191
|
-
return (
|
192
|
-
<div className={b('loader')}>
|
193
|
-
<Loader size="m" />
|
194
|
-
</div>
|
195
|
-
);
|
196
|
-
};
|
197
|
-
|
198
|
-
const renderContent = () => {
|
199
|
-
if (isColumnEntityType(type)) {
|
200
|
-
return 'No data';
|
201
|
-
}
|
202
|
-
if (error && !error.isCancelled) {
|
203
|
-
return prepareQueryError(error);
|
204
|
-
}
|
205
|
-
|
206
|
-
return data && data.length > 0 ? (
|
207
|
-
<div className={b('table')}>
|
208
|
-
<DataTable
|
209
|
-
columns={tableColumns}
|
210
|
-
data={data}
|
211
|
-
settings={TABLE_SETTINGS}
|
212
|
-
className={b('table')}
|
213
|
-
theme="yandex-cloud"
|
214
|
-
onSort={onSort}
|
215
|
-
sortOrder={stringToDataTableSortOrder(sortOrder)}
|
216
|
-
/>
|
217
|
-
</div>
|
218
|
-
) : (
|
219
|
-
data
|
220
|
-
);
|
221
|
-
};
|
222
|
-
|
223
|
-
return loading && !wasLoaded ? renderLoader() : <div className={b()}>{renderContent()}</div>;
|
224
|
-
}
|
225
|
-
|
226
|
-
const mapStateToProps = (state) => {
|
227
|
-
const {loading, data = {}, error, wasLoaded} = state.shardsWorkload;
|
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,
|
244
|
-
};
|
245
|
-
|
246
|
-
export default connect(mapStateToProps, mapDispatchToProps)(TopShards);
|
@@ -1,101 +0,0 @@
|
|
1
|
-
import '../../services/api';
|
2
|
-
|
3
|
-
import {parseQueryAPIExecuteResponse} from '../../utils/query';
|
4
|
-
|
5
|
-
import {createRequestActionTypes, createApiRequest} from '../utils';
|
6
|
-
|
7
|
-
const SEND_SHARD_QUERY = createRequestActionTypes('query', 'SEND_SHARD_QUERY');
|
8
|
-
const SET_SHARD_QUERY_OPTIONS = 'query/SET_SHARD_QUERY_OPTIONS';
|
9
|
-
|
10
|
-
const initialState = {
|
11
|
-
loading: false,
|
12
|
-
wasLoaded: false,
|
13
|
-
};
|
14
|
-
|
15
|
-
function formatSortOrder({columnId, order}) {
|
16
|
-
return `${columnId} ${order}`;
|
17
|
-
}
|
18
|
-
|
19
|
-
function createShardQuery(path, sortOrder, tenantName) {
|
20
|
-
const orderBy = Array.isArray(sortOrder) ?
|
21
|
-
`ORDER BY ${sortOrder.map(formatSortOrder).join(', ')}` :
|
22
|
-
'';
|
23
|
-
|
24
|
-
const pathSelect = tenantName ?
|
25
|
-
`CAST(SUBSTRING(CAST(Path AS String), ${tenantName.length}) AS Utf8) AS Path` :
|
26
|
-
'Path';
|
27
|
-
|
28
|
-
return `SELECT
|
29
|
-
${pathSelect},
|
30
|
-
TabletId,
|
31
|
-
CPUCores,
|
32
|
-
DataSize
|
33
|
-
FROM \`.sys/partition_stats\`
|
34
|
-
WHERE
|
35
|
-
Path='${path}'
|
36
|
-
OR Path LIKE '${path}/%'
|
37
|
-
${orderBy}
|
38
|
-
LIMIT 20`;
|
39
|
-
}
|
40
|
-
|
41
|
-
const queryAction = 'execute-scan';
|
42
|
-
|
43
|
-
const shardsWorkload = (state = initialState, action) => {
|
44
|
-
switch (action.type) {
|
45
|
-
case SEND_SHARD_QUERY.REQUEST: {
|
46
|
-
return {
|
47
|
-
...state,
|
48
|
-
loading: true,
|
49
|
-
error: undefined,
|
50
|
-
};
|
51
|
-
}
|
52
|
-
case SEND_SHARD_QUERY.SUCCESS: {
|
53
|
-
return {
|
54
|
-
...state,
|
55
|
-
data: action.data,
|
56
|
-
loading: false,
|
57
|
-
error: undefined,
|
58
|
-
wasLoaded: true,
|
59
|
-
};
|
60
|
-
}
|
61
|
-
// 401 Unauthorized error is handled by GenericAPI
|
62
|
-
case SEND_SHARD_QUERY.FAILURE: {
|
63
|
-
return {
|
64
|
-
...state,
|
65
|
-
error: action.error || 'Unauthorized',
|
66
|
-
loading: false,
|
67
|
-
};
|
68
|
-
}
|
69
|
-
case SET_SHARD_QUERY_OPTIONS:
|
70
|
-
return {
|
71
|
-
...state,
|
72
|
-
...action.data,
|
73
|
-
};
|
74
|
-
default:
|
75
|
-
return state;
|
76
|
-
}
|
77
|
-
};
|
78
|
-
|
79
|
-
export const sendShardQuery = ({database, path = '', sortOrder}) => {
|
80
|
-
return createApiRequest({
|
81
|
-
request: window.api.sendQuery({
|
82
|
-
schema: 'modern',
|
83
|
-
query: createShardQuery(path, sortOrder, database),
|
84
|
-
database,
|
85
|
-
action: queryAction,
|
86
|
-
}, {
|
87
|
-
concurrentId: 'topShards',
|
88
|
-
}),
|
89
|
-
actions: SEND_SHARD_QUERY,
|
90
|
-
dataHandler: parseQueryAPIExecuteResponse,
|
91
|
-
});
|
92
|
-
};
|
93
|
-
|
94
|
-
export function setShardQueryOptions(options) {
|
95
|
-
return {
|
96
|
-
type: SET_SHARD_QUERY_OPTIONS,
|
97
|
-
data: options,
|
98
|
-
};
|
99
|
-
}
|
100
|
-
|
101
|
-
export default shardsWorkload;
|