ydb-embedded-ui 1.13.2 → 1.14.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/assets/icons/flask.svg +3 -0
  3. package/dist/components/InfoViewer/formatters/common.ts +15 -0
  4. package/dist/components/InfoViewer/formatters/index.ts +2 -0
  5. package/dist/components/InfoViewer/formatters/schema.ts +43 -0
  6. package/dist/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx +44 -0
  7. package/dist/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx +34 -0
  8. package/dist/components/{IndexInfoViewer/IndexInfoViewer.tsx → InfoViewer/schemaInfo/TableIndexInfo.tsx} +7 -18
  9. package/dist/components/InfoViewer/schemaInfo/index.ts +3 -0
  10. package/dist/components/InfoViewer/schemaOverview/CDCStreamOverview.tsx +44 -0
  11. package/dist/components/InfoViewer/schemaOverview/PersQueueGroupOverview.tsx +35 -0
  12. package/dist/components/InfoViewer/schemaOverview/index.ts +2 -0
  13. package/dist/components/QueryResultTable/Cell/Cell.tsx +33 -0
  14. package/dist/components/QueryResultTable/Cell/index.ts +1 -0
  15. package/dist/components/QueryResultTable/QueryResultTable.scss +11 -0
  16. package/dist/components/QueryResultTable/QueryResultTable.tsx +115 -0
  17. package/dist/components/QueryResultTable/i18n/en.json +3 -0
  18. package/dist/components/QueryResultTable/i18n/index.ts +11 -0
  19. package/dist/components/QueryResultTable/i18n/ru.json +3 -0
  20. package/dist/components/QueryResultTable/index.ts +1 -0
  21. package/dist/containers/App/App.scss +1 -0
  22. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.scss +39 -14
  23. package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +18 -7
  24. package/dist/containers/Storage/Pdisk/__tests__/colors.tsx +4 -3
  25. package/dist/containers/Storage/Vdisk/__tests__/colors.tsx +7 -7
  26. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +6 -2
  27. package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +1 -1
  28. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +8 -3
  29. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +1 -1
  30. package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +1 -1
  31. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +36 -10
  32. package/dist/containers/Tenant/Preview/Preview.js +15 -57
  33. package/dist/containers/Tenant/Preview/Preview.scss +4 -8
  34. package/dist/containers/Tenant/QueryEditor/QueryEditor.js +12 -41
  35. package/dist/containers/Tenant/QueryEditor/QueryEditor.scss +0 -4
  36. package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.scss +1 -2
  37. package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.scss +2 -2
  38. package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +1 -1
  39. package/dist/containers/Tenant/utils/schema.ts +3 -0
  40. package/dist/containers/Tenant/utils/schemaActions.ts +1 -2
  41. package/dist/containers/Tenants/Tenants.js +12 -2
  42. package/dist/containers/UserSettings/UserSettings.tsx +26 -3
  43. package/dist/services/api.d.ts +19 -2
  44. package/dist/services/api.js +2 -2
  45. package/dist/setupTests.js +4 -0
  46. package/dist/store/reducers/executeQuery.js +4 -9
  47. package/dist/store/reducers/{preview.js → preview.ts} +22 -18
  48. package/dist/store/reducers/settings.js +3 -1
  49. package/dist/store/utils.ts +88 -0
  50. package/dist/types/api/query.ts +147 -0
  51. package/dist/types/api/schema.ts +235 -2
  52. package/dist/types/index.ts +33 -0
  53. package/dist/types/store/query.ts +9 -0
  54. package/dist/utils/{constants.js → constants.ts} +11 -6
  55. package/dist/utils/index.js +0 -24
  56. package/dist/utils/query.test.ts +189 -0
  57. package/dist/utils/query.ts +156 -0
  58. package/dist/utils/tests/providers.tsx +29 -0
  59. package/package.json +2 -2
  60. package/dist/store/utils.js +0 -51
@@ -0,0 +1,156 @@
1
+ import {YQLType} from '../types';
2
+ import type {
3
+ AnyExecuteResponse,
4
+ CommonFields,
5
+ DeepExecuteResponse,
6
+ DeprecatedExecuteResponsePlain,
7
+ ExecuteClassicResponsePlain,
8
+ ExecuteModernResponse,
9
+ KeyValueRow,
10
+ QueryAPIExecuteResponse,
11
+ Schemas,
12
+ } from '../types/api/query';
13
+ import type {IQueryResult} from '../types/store/query';
14
+
15
+ // eslint-disable-next-line complexity
16
+ export const getColumnType = (type: string) => {
17
+ switch (type.replace(/\?$/, '')) {
18
+ case YQLType.Bool:
19
+ return 'boolean';
20
+ case YQLType.Int8:
21
+ case YQLType.Int16:
22
+ case YQLType.Int32:
23
+ case YQLType.Int64:
24
+ case YQLType.Uint8:
25
+ case YQLType.Uint16:
26
+ case YQLType.Uint32:
27
+ case YQLType.Uint64:
28
+ case YQLType.Float:
29
+ case YQLType.Double:
30
+ case YQLType.Decimal:
31
+ return 'number';
32
+ case YQLType.String:
33
+ case YQLType.Utf8:
34
+ case YQLType.Json:
35
+ case YQLType.JsonDocument:
36
+ case YQLType.Yson:
37
+ case YQLType.Uuid:
38
+ return 'string';
39
+ case YQLType.Date:
40
+ case YQLType.Datetime:
41
+ case YQLType.Timestamp:
42
+ case YQLType.Interval:
43
+ case YQLType.TzDate:
44
+ case YQLType.TzDateTime:
45
+ case YQLType.TzTimestamp:
46
+ return 'date';
47
+ default:
48
+ return undefined;
49
+ }
50
+ }
51
+
52
+ const parseExecuteModernResponse = (data: ExecuteModernResponse): IQueryResult => {
53
+ const {result, columns, ...restData} = data;
54
+
55
+ return {
56
+ result: result && columns && result.map((row) => {
57
+ return row.reduce((newRow: KeyValueRow, cellData, columnIndex) => {
58
+ const {name} = columns[columnIndex];
59
+ newRow[name] = cellData;
60
+ return newRow;
61
+ }, {});
62
+ }),
63
+ columns,
64
+ ...restData,
65
+ };
66
+ };
67
+
68
+ const parseDeprecatedExecuteResponseValue = (data?: DeprecatedExecuteResponsePlain | ExecuteClassicResponsePlain): KeyValueRow[] | undefined => {
69
+ if (!data) {
70
+ return undefined;
71
+ }
72
+
73
+ if (typeof data === 'string') {
74
+ try {
75
+ return JSON.parse(data);
76
+ } catch (e) {
77
+ return undefined;
78
+ }
79
+ }
80
+
81
+ if (Array.isArray(data)) {
82
+ return data;
83
+ }
84
+
85
+ // Plan is not a valid response in this case
86
+ return undefined;
87
+ };
88
+
89
+ const hasResult = (data: AnyExecuteResponse): data is DeepExecuteResponse => Boolean(
90
+ data && typeof data === 'object' && 'result' in 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: AnyExecuteResponse): 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 = <T extends Schemas>(data: QueryAPIExecuteResponse<T>): IQueryResult => {
107
+ if (!data) {
108
+ return {};
109
+ }
110
+
111
+ if (hasResult(data)) {
112
+ if (isModern(data)) {
113
+ return parseExecuteModernResponse(data);
114
+ }
115
+
116
+ return {
117
+ ...data,
118
+ result: parseDeprecatedExecuteResponseValue(data.result),
119
+ };
120
+ }
121
+
122
+ if (hasCommonFields(data)) {
123
+ return data;
124
+ }
125
+
126
+ return {
127
+ result: parseDeprecatedExecuteResponseValue(data),
128
+ };
129
+ };
130
+
131
+ export const prepareQueryResponse = (data?: KeyValueRow[]) => {
132
+ if (!Array.isArray(data)) {
133
+ return [];
134
+ }
135
+
136
+ return data.map((row) => {
137
+ const formattedData: KeyValueRow = {};
138
+
139
+ for (const field in row) {
140
+ if (Object.prototype.hasOwnProperty.call(row, field)) {
141
+ const type = typeof row[field];
142
+ if (type === 'object' || type === 'boolean' || Array.isArray(row[field])) {
143
+ formattedData[field] = JSON.stringify(row[field]);
144
+ } else {
145
+ formattedData[field] = row[field];
146
+ }
147
+ }
148
+ }
149
+
150
+ return formattedData;
151
+ });
152
+ };
153
+
154
+ export function prepareQueryError(error: any) {
155
+ return error.data?.error?.message || error.data || error.statusText || JSON.stringify(error);
156
+ }
@@ -0,0 +1,29 @@
1
+ import React, {PropsWithChildren} from 'react';
2
+ import {Provider} from 'react-redux'
3
+ import {render} from '@testing-library/react'
4
+ import type {RenderOptions} from '@testing-library/react'
5
+
6
+ import configureStore from '../../store';
7
+
8
+ interface ExtendedRenderOptions extends Omit<RenderOptions, 'queries'> {
9
+ storeConfiguration?: {
10
+ store?: any;
11
+ history?: any;
12
+ };
13
+ }
14
+
15
+ export const renderWithStore = (
16
+ ui: React.ReactElement,
17
+ {
18
+ storeConfiguration = configureStore(),
19
+ ...renderOptions
20
+ }: ExtendedRenderOptions = {}
21
+ ) => {
22
+ const {store} = storeConfiguration;
23
+
24
+ function Wrapper({children}: PropsWithChildren<{}>) {
25
+ return <Provider store={store}>{children}</Provider>
26
+ }
27
+
28
+ return {store, ...render(ui, {wrapper: Wrapper, ...renderOptions})}
29
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "1.13.2",
3
+ "version": "1.14.1",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@yandex-cloud/i18n": "0.6.0",
13
- "@yandex-cloud/paranoid": "1.0.0",
13
+ "@yandex-cloud/paranoid": "^1.2.1",
14
14
  "@yandex-cloud/react-data-table": "0.2.1",
15
15
  "axios": "0.19.2",
16
16
  "bem-cn-lite": "4.0.0",
@@ -1,51 +0,0 @@
1
- import createToast from '../utils/createToast';
2
- import {SET_UNAUTHENTICATED} from './reducers/authentication';
3
-
4
- export const nop = (result) => result;
5
-
6
- export function createRequestActionTypes(prefix, type) {
7
- return {
8
- REQUEST: `${prefix}/${type}_REQUEST`,
9
- SUCCESS: `${prefix}/${type}_SUCCESS`,
10
- FAILURE: `${prefix}/${type}_FAILURE`,
11
- };
12
- }
13
-
14
- export function createApiRequest({actions, request, dataHandler = nop}) {
15
- const doRequest = async function (dispatch, getState) {
16
- dispatch({
17
- type: actions.REQUEST,
18
- });
19
-
20
- try {
21
- const result = await request;
22
- const data = dataHandler(result, getState);
23
-
24
- dispatch({
25
- type: actions.SUCCESS,
26
- data,
27
- });
28
-
29
- return data;
30
- } catch (error) {
31
- if (error && error.status === 401) {
32
- dispatch({
33
- type: SET_UNAUTHENTICATED.SUCCESS,
34
- });
35
- } else if (error && Number(error.status) >= 500 && error.statusText) {
36
- createToast({
37
- name: 'Request failure',
38
- title: 'Request failure',
39
- type: 'error',
40
- content: `${error.status} ${error.statusText}`,
41
- });
42
- }
43
- dispatch({
44
- type: actions.FAILURE,
45
- error,
46
- });
47
- }
48
- };
49
-
50
- return doRequest;
51
- }