ydb-embedded-ui 3.4.5 → 4.0.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 +41 -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/QueriesHistory/QueriesHistory.tsx +3 -3
- package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.scss +8 -0
- package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.tsx +21 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +58 -82
- package/dist/containers/Tenant/QueryEditor/QueryEditor.scss +0 -33
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/OldQueryEditorControls.tsx +83 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.scss +57 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.tsx +84 -0
- package/dist/containers/Tenant/QueryEditor/QueryEditorControls/shared.ts +23 -0
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +12 -23
- package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.js +4 -6
- package/dist/containers/Tenant/QueryEditor/i18n/en.json +3 -0
- package/dist/containers/Tenant/QueryEditor/i18n/index.ts +11 -0
- package/dist/containers/Tenant/QueryEditor/i18n/ru.json +3 -0
- package/dist/containers/UserSettings/UserSettings.tsx +30 -1
- package/dist/routes.ts +1 -1
- package/dist/services/api.d.ts +4 -3
- package/dist/services/api.js +5 -5
- package/dist/store/reducers/{executeQuery.js → executeQuery.ts} +48 -43
- package/dist/store/reducers/executeTopQueries.ts +5 -1
- package/dist/store/reducers/{explainQuery.js → explainQuery.ts} +44 -59
- package/dist/store/reducers/{olapStats.js → olapStats.ts} +8 -18
- package/dist/store/reducers/settings.js +19 -4
- package/dist/store/reducers/storage.js +5 -7
- package/dist/types/api/error.ts +14 -0
- package/dist/types/api/query.ts +227 -115
- package/dist/types/api/schema.ts +523 -3
- package/dist/types/common.ts +1 -0
- package/dist/types/store/executeQuery.ts +38 -0
- package/dist/types/store/explainQuery.ts +38 -0
- package/dist/types/store/olapStats.ts +14 -0
- package/dist/types/store/query.ts +23 -3
- package/dist/utils/constants.ts +2 -1
- package/dist/utils/error.ts +25 -0
- package/dist/utils/index.js +0 -49
- package/dist/utils/prepareQueryExplain.ts +7 -24
- package/dist/utils/query.test.ts +148 -213
- package/dist/utils/query.ts +68 -90
- package/dist/utils/timeParsers/formatDuration.ts +30 -12
- package/dist/utils/timeParsers/i18n/en.json +9 -5
- package/dist/utils/timeParsers/i18n/ru.json +9 -5
- package/dist/utils/timeParsers/parsers.ts +9 -0
- package/dist/utils/utils.js +1 -2
- package/package.json +1 -1
package/dist/utils/query.ts
CHANGED
@@ -2,13 +2,10 @@ import {YQLType} from '../types';
|
|
2
2
|
import type {
|
3
3
|
AnyExecuteResponse,
|
4
4
|
AnyExplainResponse,
|
5
|
-
AnyResponse,
|
6
|
-
CommonFields,
|
7
|
-
DeepExecuteResponse,
|
8
|
-
DeprecatedExecuteResponsePlain,
|
9
|
-
ExecuteClassicResponsePlain,
|
10
5
|
ExecuteModernResponse,
|
11
6
|
KeyValueRow,
|
7
|
+
ScanPlan,
|
8
|
+
ScriptPlan,
|
12
9
|
} from '../types/api/query';
|
13
10
|
import type {IQueryResult} from '../types/store/query';
|
14
11
|
|
@@ -47,119 +44,94 @@ export const getColumnType = (type: string) => {
|
|
47
44
|
default:
|
48
45
|
return undefined;
|
49
46
|
}
|
50
|
-
}
|
47
|
+
};
|
51
48
|
|
49
|
+
/** parse response result field from ArrayRow to KeyValueRow */
|
52
50
|
const parseExecuteModernResponse = (data: ExecuteModernResponse): IQueryResult => {
|
53
51
|
const {result, columns, ...restData} = data;
|
54
52
|
|
55
53
|
return {
|
56
|
-
result:
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return newRow
|
61
|
-
|
62
|
-
|
54
|
+
result:
|
55
|
+
result &&
|
56
|
+
columns &&
|
57
|
+
result.map((row) => {
|
58
|
+
return row.reduce((newRow, cellData, columnIndex) => {
|
59
|
+
const {name} = columns[columnIndex];
|
60
|
+
newRow[name] = cellData;
|
61
|
+
return newRow;
|
62
|
+
}, {} as KeyValueRow);
|
63
|
+
}),
|
63
64
|
columns,
|
64
65
|
...restData,
|
65
66
|
};
|
66
67
|
};
|
67
68
|
|
68
|
-
const
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
return
|
69
|
+
const isModern = (response: AnyExecuteResponse): response is ExecuteModernResponse =>
|
70
|
+
Boolean(
|
71
|
+
response &&
|
72
|
+
!Array.isArray(response) &&
|
73
|
+
Array.isArray((response as ExecuteModernResponse).result) &&
|
74
|
+
Array.isArray((response as ExecuteModernResponse).columns),
|
75
|
+
);
|
76
|
+
|
77
|
+
type UnsupportedQueryResponseFormat =
|
78
|
+
| Array<unknown>
|
79
|
+
| string
|
80
|
+
| null
|
81
|
+
| undefined
|
82
|
+
| {result: string | Record<string, unknown>};
|
83
|
+
|
84
|
+
const isUnsupportedType = (
|
85
|
+
data: AnyExecuteResponse | AnyExplainResponse | UnsupportedQueryResponseFormat,
|
86
|
+
): data is UnsupportedQueryResponseFormat => {
|
87
|
+
return Boolean(
|
88
|
+
!data ||
|
89
|
+
typeof data !== 'object' ||
|
90
|
+
Array.isArray(data) ||
|
91
|
+
('result' in data && !Array.isArray(data.result)),
|
92
|
+
);
|
87
93
|
};
|
88
94
|
|
89
|
-
const
|
90
|
-
data
|
91
|
-
)
|
92
|
-
|
93
|
-
const isModern = (response: AnyExecuteResponse): response is ExecuteModernResponse => Boolean(
|
94
|
-
response &&
|
95
|
-
!Array.isArray(response) &&
|
96
|
-
Array.isArray((response as ExecuteModernResponse).result) &&
|
97
|
-
Array.isArray((response as ExecuteModernResponse).columns)
|
98
|
-
);
|
99
|
-
|
100
|
-
const hasCommonFields = (data: AnyResponse): data is CommonFields => Boolean(
|
101
|
-
data && typeof data === 'object' && ('ast' in data || 'plan' in data || 'stats' in data)
|
102
|
-
);
|
103
|
-
|
104
|
-
// complex logic because of the variety of possible responses
|
105
|
-
// after all backends are updated to the latest version, it can be simplified
|
106
|
-
export const parseQueryAPIExecuteResponse = (data: AnyExecuteResponse): IQueryResult => {
|
107
|
-
if (!data) {
|
95
|
+
export const parseQueryAPIExecuteResponse = (
|
96
|
+
data: AnyExecuteResponse | UnsupportedQueryResponseFormat,
|
97
|
+
): IQueryResult => {
|
98
|
+
if (isUnsupportedType(data)) {
|
108
99
|
return {};
|
109
100
|
}
|
110
|
-
|
111
|
-
|
112
|
-
if (isModern(data)) {
|
113
|
-
return parseExecuteModernResponse(data);
|
114
|
-
}
|
115
|
-
|
116
|
-
return {
|
117
|
-
...data,
|
118
|
-
result: parseDeprecatedExecuteResponseValue(data.result),
|
119
|
-
};
|
101
|
+
if (isModern(data)) {
|
102
|
+
return parseExecuteModernResponse(data);
|
120
103
|
}
|
121
104
|
|
122
|
-
|
123
|
-
return data;
|
124
|
-
}
|
125
|
-
|
126
|
-
return {
|
127
|
-
result: parseDeprecatedExecuteResponseValue(data),
|
128
|
-
};
|
105
|
+
return data;
|
129
106
|
};
|
130
107
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
if (
|
108
|
+
export const parseQueryAPIExplainResponse = (
|
109
|
+
data: AnyExplainResponse | UnsupportedQueryResponseFormat,
|
110
|
+
): IQueryResult => {
|
111
|
+
if (isUnsupportedType(data)) {
|
135
112
|
return {};
|
136
113
|
}
|
137
114
|
|
138
|
-
|
139
|
-
|
140
|
-
}
|
115
|
+
return data;
|
116
|
+
};
|
141
117
|
|
142
|
-
|
143
|
-
|
118
|
+
const isExplainScriptPlan = (plan: ScriptPlan | ScanPlan): plan is ScriptPlan =>
|
119
|
+
Boolean(plan && 'queries' in plan);
|
144
120
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
};
|
121
|
+
export const parseQueryExplainPlan = (plan: ScriptPlan | ScanPlan): ScanPlan => {
|
122
|
+
if (isExplainScriptPlan(plan)) {
|
123
|
+
if (!plan.queries || !plan.queries.length) {
|
124
|
+
return {meta: plan.meta};
|
150
125
|
}
|
151
126
|
|
152
127
|
return {
|
153
|
-
|
154
|
-
|
128
|
+
Plan: plan.queries[0].Plan,
|
129
|
+
tables: plan.queries[0].tables,
|
130
|
+
meta: plan.meta,
|
155
131
|
};
|
156
132
|
}
|
157
133
|
|
158
|
-
|
159
|
-
return data;
|
160
|
-
}
|
161
|
-
|
162
|
-
return {plan: data};
|
134
|
+
return plan;
|
163
135
|
};
|
164
136
|
|
165
137
|
export const prepareQueryResponse = (data?: KeyValueRow[]) => {
|
@@ -186,5 +158,11 @@ export const prepareQueryResponse = (data?: KeyValueRow[]) => {
|
|
186
158
|
};
|
187
159
|
|
188
160
|
export function prepareQueryError(error: any) {
|
189
|
-
return
|
161
|
+
return (
|
162
|
+
error.data?.error?.message ||
|
163
|
+
error.message ||
|
164
|
+
error.data ||
|
165
|
+
error.statusText ||
|
166
|
+
JSON.stringify(error)
|
167
|
+
);
|
190
168
|
}
|
@@ -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);
|
@@ -1,7 +1,11 @@
|
|
1
1
|
{
|
2
|
-
"daysHours": "{{days}}
|
3
|
-
"hoursMin": "{{hours}}
|
4
|
-
"minSec": "{{minutes}}
|
5
|
-
"secMs": "{{seconds}}
|
6
|
-
"
|
2
|
+
"daysHours": "{{days}}\u00a0d\u00a0{{hours}}\u00a0h",
|
3
|
+
"hoursMin": "{{hours}}\u00a0h\u00a0{{minutes}}\u00a0m",
|
4
|
+
"minSec": "{{minutes}}\u00a0m\u00a0{{seconds}}\u00a0s",
|
5
|
+
"secMs": "{{seconds}}\u00a0s\u00a0{{ms}}\u00a0ms",
|
6
|
+
"days": "{{days}}\u00a0d",
|
7
|
+
"hours": "{{hours}}\u00a0h",
|
8
|
+
"min": "{{minutes}}\u00a0m",
|
9
|
+
"sec": "{{seconds}}\u00a0s",
|
10
|
+
"ms": "{{ms}}\u00a0ms"
|
7
11
|
}
|
@@ -1,7 +1,11 @@
|
|
1
1
|
{
|
2
|
-
"daysHours": "{{days}}
|
3
|
-
"hoursMin": "{{hours}}
|
4
|
-
"minSec": "{{minutes}}
|
5
|
-
"secMs": "{{seconds}}
|
6
|
-
"
|
2
|
+
"daysHours": "{{days}}\u00a0д\u00a0{{hours}}\u00a0ч",
|
3
|
+
"hoursMin": "{{hours}}\u00a0ч\u00a0{{minutes}}\u00a0м",
|
4
|
+
"minSec": "{{minutes}}\u00a0м\u00a0{{seconds}}\u00a0с",
|
5
|
+
"secMs": "{{seconds}}\u00a0с\u00a0{{ms}}\u00a0мс",
|
6
|
+
"days": "{{days}}\u00a0д",
|
7
|
+
"hours": "{{hours}}\u00a0ч",
|
8
|
+
"min": "{{minutes}}\u00a0м",
|
9
|
+
"sec": "{{seconds}}\u00a0с",
|
10
|
+
"ms": "{{ms}}\u00a0мс"
|
7
11
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import type {IProtobufTimeObject} from '../../types/api/common';
|
2
2
|
|
3
|
+
import {isNumeric} from '../utils';
|
3
4
|
import {parseProtobufDurationToMs, parseProtobufTimestampToMs} from '.';
|
4
5
|
|
5
6
|
export const parseLag = (value: string | IProtobufTimeObject | undefined) =>
|
@@ -16,3 +17,11 @@ export const parseTimestampToIdleTime = (value: string | IProtobufTimeObject | u
|
|
16
17
|
// Usually it below 100ms, so it could be omitted
|
17
18
|
return duration < 0 ? 0 : duration;
|
18
19
|
};
|
20
|
+
|
21
|
+
export const parseUsToMs = (value: string | number | undefined) => {
|
22
|
+
if (!value || !isNumeric(value)) {
|
23
|
+
return 0;
|
24
|
+
}
|
25
|
+
|
26
|
+
return Math.round(Number(value) / 1000);
|
27
|
+
};
|
package/dist/utils/utils.js
CHANGED