ydb-embedded-ui 3.4.5 → 3.5.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 +19 -0
- package/dist/components/InfoViewer/formatters/table.ts +6 -0
- package/dist/components/TruncatedQuery/TruncatedQuery.js +1 -1
- package/dist/components/TruncatedQuery/TruncatedQuery.scss +7 -3
- package/dist/containers/Node/{NodePages.js → NodePages.ts} +1 -1
- package/dist/containers/Tablet/TabletControls/TabletControls.tsx +2 -2
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +11 -43
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/TableInfo.tsx +19 -17
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo.ts +192 -37
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +20 -14
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +49 -12
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +37 -18
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +1 -0
- package/dist/routes.ts +1 -1
- package/dist/services/api.js +3 -3
- package/dist/store/reducers/{executeQuery.js → executeQuery.ts} +51 -21
- package/dist/store/reducers/executeTopQueries.ts +5 -1
- package/dist/store/reducers/{olapStats.js → olapStats.ts} +8 -18
- package/dist/store/reducers/settings.js +1 -1
- package/dist/store/reducers/storage.js +5 -7
- package/dist/types/api/query.ts +4 -1
- package/dist/types/api/schema.ts +523 -3
- package/dist/types/common.ts +1 -0
- package/dist/types/store/executeQuery.ts +42 -0
- package/dist/types/store/olapStats.ts +14 -0
- package/dist/utils/query.test.ts +42 -29
- package/dist/utils/query.ts +34 -22
- package/dist/utils/timeParsers/formatDuration.ts +30 -12
- package/dist/utils/timeParsers/i18n/en.json +4 -0
- package/dist/utils/timeParsers/i18n/ru.json +4 -0
- package/package.json +1 -1
package/dist/utils/query.test.ts
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
import {
|
2
|
-
parseQueryAPIExecuteResponse,
|
3
|
-
parseQueryAPIExplainResponse,
|
4
|
-
} from './query';
|
1
|
+
import {parseQueryAPIExecuteResponse, parseQueryAPIExplainResponse} from './query';
|
5
2
|
|
6
3
|
describe('API utils', () => {
|
7
4
|
describe('json/viewer/query', () => {
|
@@ -45,7 +42,9 @@ describe('API utils', () => {
|
|
45
42
|
|
46
43
|
it('should accept key-value rows in the result field', () => {
|
47
44
|
const response = {result: [{foo: 'bar'}]};
|
48
|
-
expect(parseQueryAPIExecuteResponse(response).result).toEqual(
|
45
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(
|
46
|
+
response.result,
|
47
|
+
);
|
49
48
|
});
|
50
49
|
});
|
51
50
|
|
@@ -98,19 +97,24 @@ describe('API utils', () => {
|
|
98
97
|
it('should parse modern schema', () => {
|
99
98
|
const response = {
|
100
99
|
result: [['42', 'hello world']],
|
101
|
-
columns: [
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
100
|
+
columns: [
|
101
|
+
{
|
102
|
+
name: 'id',
|
103
|
+
type: 'Uint64?',
|
104
|
+
},
|
105
|
+
{
|
106
|
+
name: 'value',
|
107
|
+
type: 'Utf8?',
|
108
|
+
},
|
109
|
+
],
|
108
110
|
};
|
109
111
|
const actual = parseQueryAPIExecuteResponse(response);
|
110
|
-
expect(actual.result).toEqual([
|
111
|
-
|
112
|
-
|
113
|
-
|
112
|
+
expect(actual.result).toEqual([
|
113
|
+
{
|
114
|
+
id: '42',
|
115
|
+
value: 'hello world',
|
116
|
+
},
|
117
|
+
]);
|
114
118
|
expect(actual.columns).toEqual(response.columns);
|
115
119
|
});
|
116
120
|
|
@@ -125,12 +129,16 @@ describe('API utils', () => {
|
|
125
129
|
|
126
130
|
it('should parse deep classic schema', () => {
|
127
131
|
const response = {result: [{foo: 'bar'}]};
|
128
|
-
expect(parseQueryAPIExecuteResponse(response).result).toEqual(
|
132
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(
|
133
|
+
response.result,
|
134
|
+
);
|
129
135
|
});
|
130
136
|
|
131
137
|
it('should parse ydb schema', () => {
|
132
138
|
const response = {result: [{foo: 'bar'}]};
|
133
|
-
expect(parseQueryAPIExecuteResponse(response).result).toEqual(
|
139
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(
|
140
|
+
response.result,
|
141
|
+
);
|
134
142
|
});
|
135
143
|
});
|
136
144
|
|
@@ -138,20 +146,25 @@ describe('API utils', () => {
|
|
138
146
|
it('should parse modern schema', () => {
|
139
147
|
const response = {
|
140
148
|
result: [['42', 'hello world']],
|
141
|
-
columns: [
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
149
|
+
columns: [
|
150
|
+
{
|
151
|
+
name: 'id',
|
152
|
+
type: 'Uint64?',
|
153
|
+
},
|
154
|
+
{
|
155
|
+
name: 'value',
|
156
|
+
type: 'Utf8?',
|
157
|
+
},
|
158
|
+
],
|
148
159
|
stats: {metric: 'good'},
|
149
160
|
};
|
150
161
|
const actual = parseQueryAPIExecuteResponse(response);
|
151
|
-
expect(actual.result).toEqual([
|
152
|
-
|
153
|
-
|
154
|
-
|
162
|
+
expect(actual.result).toEqual([
|
163
|
+
{
|
164
|
+
id: '42',
|
165
|
+
value: 'hello world',
|
166
|
+
},
|
167
|
+
]);
|
155
168
|
expect(actual.columns).toEqual(response.columns);
|
156
169
|
expect(actual.stats).toEqual(response.stats);
|
157
170
|
});
|
package/dist/utils/query.ts
CHANGED
@@ -47,25 +47,30 @@ export const getColumnType = (type: string) => {
|
|
47
47
|
default:
|
48
48
|
return undefined;
|
49
49
|
}
|
50
|
-
}
|
50
|
+
};
|
51
51
|
|
52
52
|
const parseExecuteModernResponse = (data: ExecuteModernResponse): IQueryResult => {
|
53
53
|
const {result, columns, ...restData} = data;
|
54
54
|
|
55
55
|
return {
|
56
|
-
result:
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return newRow
|
61
|
-
|
62
|
-
|
56
|
+
result:
|
57
|
+
result &&
|
58
|
+
columns &&
|
59
|
+
result.map((row) => {
|
60
|
+
return row.reduce((newRow: KeyValueRow, cellData, columnIndex) => {
|
61
|
+
const {name} = columns[columnIndex];
|
62
|
+
newRow[name] = cellData;
|
63
|
+
return newRow;
|
64
|
+
}, {});
|
65
|
+
}),
|
63
66
|
columns,
|
64
67
|
...restData,
|
65
68
|
};
|
66
69
|
};
|
67
70
|
|
68
|
-
const parseDeprecatedExecuteResponseValue = (
|
71
|
+
const parseDeprecatedExecuteResponseValue = (
|
72
|
+
data?: DeprecatedExecuteResponsePlain | ExecuteClassicResponsePlain,
|
73
|
+
): KeyValueRow[] | undefined => {
|
69
74
|
if (!data) {
|
70
75
|
return undefined;
|
71
76
|
}
|
@@ -86,20 +91,21 @@ const parseDeprecatedExecuteResponseValue = (data?: DeprecatedExecuteResponsePla
|
|
86
91
|
return undefined;
|
87
92
|
};
|
88
93
|
|
89
|
-
const hasResult = (data: AnyExecuteResponse): data is DeepExecuteResponse =>
|
90
|
-
data && typeof data === 'object' && 'result' in data
|
91
|
-
);
|
94
|
+
const hasResult = (data: AnyExecuteResponse): data is DeepExecuteResponse =>
|
95
|
+
Boolean(data && typeof data === 'object' && 'result' in data);
|
92
96
|
|
93
|
-
const isModern = (response: AnyExecuteResponse): response is ExecuteModernResponse =>
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
)
|
97
|
+
const isModern = (response: AnyExecuteResponse): response is ExecuteModernResponse =>
|
98
|
+
Boolean(
|
99
|
+
response &&
|
100
|
+
!Array.isArray(response) &&
|
101
|
+
Array.isArray((response as ExecuteModernResponse).result) &&
|
102
|
+
Array.isArray((response as ExecuteModernResponse).columns),
|
103
|
+
);
|
99
104
|
|
100
|
-
const hasCommonFields = (data: AnyResponse): data is CommonFields =>
|
101
|
-
|
102
|
-
)
|
105
|
+
const hasCommonFields = (data: AnyResponse): data is CommonFields =>
|
106
|
+
Boolean(
|
107
|
+
data && typeof data === 'object' && ('ast' in data || 'plan' in data || 'stats' in data),
|
108
|
+
);
|
103
109
|
|
104
110
|
// complex logic because of the variety of possible responses
|
105
111
|
// after all backends are updated to the latest version, it can be simplified
|
@@ -186,5 +192,11 @@ export const prepareQueryResponse = (data?: KeyValueRow[]) => {
|
|
186
192
|
};
|
187
193
|
|
188
194
|
export function prepareQueryError(error: any) {
|
189
|
-
return
|
195
|
+
return (
|
196
|
+
error.data?.error?.message ||
|
197
|
+
error.message ||
|
198
|
+
error.data ||
|
199
|
+
error.statusText ||
|
200
|
+
JSON.stringify(error)
|
201
|
+
);
|
190
202
|
}
|
@@ -4,9 +4,10 @@ import i18n from './i18n';
|
|
4
4
|
|
5
5
|
/**
|
6
6
|
* Process time difference in ms and returns formated time.
|
7
|
-
*
|
7
|
+
* By default only two major values are returned (days & hours, hours & minutes, minutes & seconds, etc.).
|
8
|
+
* It can be altered with valuesCount arg
|
8
9
|
*/
|
9
|
-
export const formatDurationToShortTimeFormat = (value: number) => {
|
10
|
+
export const formatDurationToShortTimeFormat = (value: number, valuesCount: 1 | 2 = 2) => {
|
10
11
|
const ms = value % 1000;
|
11
12
|
let remain = Math.floor(value / 1000);
|
12
13
|
|
@@ -29,17 +30,34 @@ export const formatDurationToShortTimeFormat = (value: number) => {
|
|
29
30
|
ms,
|
30
31
|
};
|
31
32
|
|
32
|
-
if (
|
33
|
-
|
33
|
+
if (valuesCount === 2) {
|
34
|
+
if (days > 0) {
|
35
|
+
return i18n('daysHours', duration);
|
36
|
+
}
|
37
|
+
if (hours > 0) {
|
38
|
+
return i18n('hoursMin', duration);
|
39
|
+
}
|
40
|
+
if (minutes > 0) {
|
41
|
+
return i18n('minSec', duration);
|
42
|
+
}
|
43
|
+
if (seconds > 0) {
|
44
|
+
return i18n('secMs', duration);
|
45
|
+
}
|
34
46
|
}
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
47
|
+
|
48
|
+
if (valuesCount === 1) {
|
49
|
+
if (days > 0) {
|
50
|
+
return i18n('days', duration);
|
51
|
+
}
|
52
|
+
if (hours > 0) {
|
53
|
+
return i18n('hours', duration);
|
54
|
+
}
|
55
|
+
if (minutes > 0) {
|
56
|
+
return i18n('min', duration);
|
57
|
+
}
|
58
|
+
if (seconds > 0) {
|
59
|
+
return i18n('sec', duration);
|
60
|
+
}
|
43
61
|
}
|
44
62
|
|
45
63
|
return i18n('ms', duration);
|