ydb-embedded-ui 3.5.0 → 4.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/components/ClusterInfo/ClusterInfo.tsx +3 -3
  3. package/dist/{containers/Nodes/NodesTable.scss → components/NodeHostWrapper/NodeHostWrapper.scss} +4 -6
  4. package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +60 -0
  5. package/dist/containers/AsideNavigation/AsideNavigation.tsx +1 -11
  6. package/dist/containers/Header/Header.tsx +1 -1
  7. package/dist/containers/Nodes/getNodesColumns.tsx +7 -46
  8. package/dist/containers/Storage/StorageNodes/StorageNodes.scss +0 -24
  9. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +2 -39
  10. package/dist/containers/Tenant/QueryEditor/QueriesHistory/QueriesHistory.tsx +3 -3
  11. package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.scss +8 -0
  12. package/dist/containers/Tenant/QueryEditor/QueryDuration/QueryDuration.tsx +21 -0
  13. package/dist/containers/Tenant/QueryEditor/QueryEditor.js +58 -83
  14. package/dist/containers/Tenant/QueryEditor/QueryEditor.scss +0 -33
  15. package/dist/containers/Tenant/QueryEditor/QueryEditorControls/OldQueryEditorControls.tsx +83 -0
  16. package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.scss +57 -0
  17. package/dist/containers/Tenant/QueryEditor/QueryEditorControls/QueryEditorControls.tsx +84 -0
  18. package/dist/containers/Tenant/QueryEditor/QueryEditorControls/shared.ts +23 -0
  19. package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.js +12 -23
  20. package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.js +4 -6
  21. package/dist/containers/Tenant/QueryEditor/i18n/en.json +3 -0
  22. package/dist/containers/Tenant/QueryEditor/i18n/index.ts +11 -0
  23. package/dist/containers/Tenant/QueryEditor/i18n/ru.json +3 -0
  24. package/dist/containers/Tenants/Tenants.js +1 -1
  25. package/dist/containers/UserSettings/UserSettings.tsx +30 -1
  26. package/dist/services/api.ts +383 -0
  27. package/dist/store/reducers/{cluster.js → cluster/cluster.ts} +9 -14
  28. package/dist/store/reducers/cluster/types.ts +13 -0
  29. package/dist/store/reducers/executeQuery.ts +12 -37
  30. package/dist/store/reducers/executeTopQueries.ts +2 -2
  31. package/dist/store/reducers/{explainQuery.js → explainQuery.ts} +44 -59
  32. package/dist/store/reducers/index.ts +5 -4
  33. package/dist/store/reducers/settings.js +19 -17
  34. package/dist/store/reducers/{tenants.js → tenants/tenants.ts} +14 -9
  35. package/dist/store/reducers/tenants/types.ts +17 -0
  36. package/dist/store/utils.ts +3 -2
  37. package/dist/types/api/acl.ts +25 -0
  38. package/dist/types/api/cluster.ts +3 -0
  39. package/dist/types/api/compute.ts +5 -3
  40. package/dist/types/api/error.ts +14 -0
  41. package/dist/types/api/netInfo.ts +48 -0
  42. package/dist/types/api/nodes.ts +5 -3
  43. package/dist/types/api/pdisk.ts +11 -2
  44. package/dist/types/api/query.ts +226 -117
  45. package/dist/types/api/storage.ts +5 -3
  46. package/dist/types/api/tenant.ts +18 -3
  47. package/dist/types/api/vdisk.ts +10 -2
  48. package/dist/types/api/whoami.ts +19 -0
  49. package/dist/types/store/executeQuery.ts +4 -8
  50. package/dist/types/store/explainQuery.ts +38 -0
  51. package/dist/types/store/query.ts +23 -3
  52. package/dist/types/window.d.ts +5 -0
  53. package/dist/utils/constants.ts +2 -1
  54. package/dist/utils/error.ts +25 -0
  55. package/dist/utils/hooks/useTypedSelector.ts +2 -2
  56. package/dist/utils/index.js +0 -49
  57. package/dist/utils/nodes.ts +3 -1
  58. package/dist/utils/prepareQueryExplain.ts +7 -24
  59. package/dist/utils/query.test.ts +153 -231
  60. package/dist/utils/query.ts +44 -78
  61. package/dist/utils/timeParsers/i18n/en.json +9 -9
  62. package/dist/utils/timeParsers/i18n/ru.json +9 -9
  63. package/dist/utils/timeParsers/parsers.ts +9 -0
  64. package/dist/utils/utils.js +1 -2
  65. package/package.json +1 -1
  66. package/dist/services/api.d.ts +0 -86
  67. package/dist/services/api.js +0 -278
@@ -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
 
@@ -49,6 +46,7 @@ export const getColumnType = (type: string) => {
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
 
@@ -57,43 +55,17 @@ const parseExecuteModernResponse = (data: ExecuteModernResponse): IQueryResult =
57
55
  result &&
58
56
  columns &&
59
57
  result.map((row) => {
60
- return row.reduce((newRow: KeyValueRow, cellData, columnIndex) => {
58
+ return row.reduce((newRow, cellData, columnIndex) => {
61
59
  const {name} = columns[columnIndex];
62
60
  newRow[name] = cellData;
63
61
  return newRow;
64
- }, {});
62
+ }, {} as KeyValueRow);
65
63
  }),
66
64
  columns,
67
65
  ...restData,
68
66
  };
69
67
  };
70
68
 
71
- const parseDeprecatedExecuteResponseValue = (
72
- data?: DeprecatedExecuteResponsePlain | ExecuteClassicResponsePlain,
73
- ): KeyValueRow[] | undefined => {
74
- if (!data) {
75
- return undefined;
76
- }
77
-
78
- if (typeof data === 'string') {
79
- try {
80
- return JSON.parse(data);
81
- } catch (e) {
82
- return undefined;
83
- }
84
- }
85
-
86
- if (Array.isArray(data)) {
87
- return data;
88
- }
89
-
90
- // Plan is not a valid response in this case
91
- return undefined;
92
- };
93
-
94
- const hasResult = (data: AnyExecuteResponse): data is DeepExecuteResponse =>
95
- Boolean(data && typeof data === 'object' && 'result' in data);
96
-
97
69
  const isModern = (response: AnyExecuteResponse): response is ExecuteModernResponse =>
98
70
  Boolean(
99
71
  response &&
@@ -102,70 +74,64 @@ const isModern = (response: AnyExecuteResponse): response is ExecuteModernRespon
102
74
  Array.isArray((response as ExecuteModernResponse).columns),
103
75
  );
104
76
 
105
- const hasCommonFields = (data: AnyResponse): data is CommonFields =>
106
- Boolean(
107
- data && typeof data === 'object' && ('ast' in data || 'plan' in data || 'stats' in data),
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)),
108
92
  );
93
+ };
109
94
 
110
- // complex logic because of the variety of possible responses
111
- // after all backends are updated to the latest version, it can be simplified
112
- export const parseQueryAPIExecuteResponse = (data: AnyExecuteResponse): IQueryResult => {
113
- if (!data) {
95
+ export const parseQueryAPIExecuteResponse = (
96
+ data: AnyExecuteResponse | UnsupportedQueryResponseFormat,
97
+ ): IQueryResult => {
98
+ if (isUnsupportedType(data)) {
114
99
  return {};
115
100
  }
116
-
117
- if (hasResult(data)) {
118
- if (isModern(data)) {
119
- return parseExecuteModernResponse(data);
120
- }
121
-
122
- return {
123
- ...data,
124
- result: parseDeprecatedExecuteResponseValue(data.result),
125
- };
126
- }
127
-
128
- if (hasCommonFields(data)) {
129
- return data;
101
+ if (isModern(data)) {
102
+ return parseExecuteModernResponse(data);
130
103
  }
131
104
 
132
- return {
133
- result: parseDeprecatedExecuteResponseValue(data),
134
- };
105
+ return data;
135
106
  };
136
107
 
137
- // complex logic because of the variety of possible responses
138
- // after all backends are updated to the latest version, it can be simplified
139
- export const parseQueryAPIExplainResponse = (data: AnyExplainResponse): IQueryResult => {
140
- if (!data) {
108
+ export const parseQueryAPIExplainResponse = (
109
+ data: AnyExplainResponse | UnsupportedQueryResponseFormat,
110
+ ): IQueryResult => {
111
+ if (isUnsupportedType(data)) {
141
112
  return {};
142
113
  }
143
114
 
144
- if ('ast' in data) {
145
- return data;
146
- }
115
+ return data;
116
+ };
147
117
 
148
- if ('result' in data) {
149
- const {result, ...restData} = data;
118
+ const isExplainScriptPlan = (plan: ScriptPlan | ScanPlan): plan is ScriptPlan =>
119
+ Boolean(plan && 'queries' in plan);
150
120
 
151
- if ('ast' in data.result) {
152
- return {
153
- ast: result.ast,
154
- ...restData,
155
- };
121
+ export const parseQueryExplainPlan = (plan: ScriptPlan | ScanPlan): ScanPlan => {
122
+ if (isExplainScriptPlan(plan)) {
123
+ if (!plan.queries || !plan.queries.length) {
124
+ return {meta: plan.meta};
156
125
  }
157
126
 
158
127
  return {
159
- plan: data.result,
160
- ...restData,
128
+ Plan: plan.queries[0].Plan,
129
+ tables: plan.queries[0].tables,
130
+ meta: plan.meta,
161
131
  };
162
132
  }
163
133
 
164
- if (hasCommonFields(data)) {
165
- return data;
166
- }
167
-
168
- return {plan: data};
134
+ return plan;
169
135
  };
170
136
 
171
137
  export const prepareQueryResponse = (data?: KeyValueRow[]) => {
@@ -1,11 +1,11 @@
1
1
  {
2
- "daysHours": "{{days}}d {{hours}}h",
3
- "hoursMin": "{{hours}}h {{minutes}}m",
4
- "minSec": "{{minutes}}m {{seconds}}s",
5
- "secMs": "{{seconds}}s {{ms}}ms",
6
- "days": "{{days}}d",
7
- "hours": "{{hours}}h",
8
- "min": "{{minutes}}m",
9
- "sec": "{{seconds}}s",
10
- "ms": "{{ms}}ms"
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"
11
11
  }
@@ -1,11 +1,11 @@
1
1
  {
2
- "daysHours": "{{days}}д {{hours}}ч",
3
- "hoursMin": "{{hours}}ч {{minutes}}м",
4
- "minSec": "{{minutes}}м {{seconds}}с",
5
- "secMs": "{{seconds}}с {{ms}}мс",
6
- "days": "{{days}}д",
7
- "hours": "{{hours}}ч",
8
- "min": "{{minutes}}м",
9
- "sec": "{{seconds}}с",
10
- "ms": "{{ms}}мс"
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мс"
11
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
+ };
@@ -1,11 +1,10 @@
1
1
  export function parseJson(value) {
2
2
  if (!value) {
3
- return;
3
+ return undefined;
4
4
  }
5
5
  try {
6
6
  return JSON.parse(value);
7
7
  } catch (err) {
8
- console.log(err);
9
8
  return value;
10
9
  }
11
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "3.5.0",
3
+ "version": "4.1.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -1,86 +0,0 @@
1
- type AxiosOptions = {
2
- concurrentId?: string;
3
- };
4
-
5
- interface Window {
6
- api: {
7
- getSchema: (
8
- params: {path: string},
9
- axiosOptions?: AxiosOptions,
10
- ) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
11
- getDescribe: (
12
- params: {path: string},
13
- axiosOptions?: AxiosOptions,
14
- ) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
15
- getStorageInfo: (
16
- params: {
17
- tenant: string;
18
- filter: string;
19
- nodeId: string;
20
- },
21
- axiosOptions?: AxiosOptions,
22
- ) => Promise<import('../types/api/storage').TStorageInfo>;
23
- getNodes: (
24
- params: import('../types/store/nodes').INodesApiRequestParams,
25
- axiosOptions?: AxiosOptions,
26
- ) => Promise<import('../types/api/nodes').TNodesInfo>;
27
- getCompute: (path: string) => Promise<import('../types/api/compute').TComputeInfo>;
28
- sendQuery: <
29
- Action extends import('../types/api/query').Actions,
30
- Schema extends import('../types/api/query').Schemas = undefined,
31
- >(
32
- params: {
33
- query?: string;
34
- database?: string;
35
- action?: Action;
36
- stats?: string;
37
- schema?: Schema;
38
- },
39
- axiosOptions?: AxiosOptions,
40
- ) => Promise<import('../types/api/query').QueryAPIResponse<Action, Schema>>;
41
- getExplainQuery: (
42
- query: string,
43
- database: string,
44
- ) => Promise<import('../types/api/query').QueryAPIExplainResponse<'explain'>>;
45
- getExplainQueryAst: (
46
- query: string,
47
- database: string,
48
- ) => Promise<import('../types/api/query').QueryAPIExplainResponse<'explain-ast'>>;
49
- getHealthcheckInfo: (
50
- database: string,
51
- ) => Promise<import('../types/api/healthcheck').HealthCheckAPIResponse>;
52
- getTenantInfo: (params: {
53
- path: string;
54
- }) => Promise<import('../types/api/tenant').TTenantInfo>;
55
- getClusterInfo: () => Promise<import('../types/api/cluster').TClusterInfo>;
56
- getTabletsInfo: (params: {
57
- nodes?: string[];
58
- path?: string;
59
- }) => Promise<import('../types/api/tablet').TEvTabletStateResponse>;
60
- getTabletDescribe: (
61
- tenantId?: import('../types/api/tablet').TDomainKey,
62
- ) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
63
- getTablet: (params: {
64
- id?: string;
65
- }) => Promise<import('../types/api/tablet').TEvTabletStateResponse>;
66
- getTabletHistory: (params: {
67
- id?: string;
68
- }) => Promise<import('../types/api/tablet').UnmergedTEvTabletStateResponse>;
69
- getHeatmapData: (params: {
70
- path: string;
71
- }) => Promise<import('../types/api/schema').TEvDescribeSchemeResult>;
72
- getTopic: (params: {
73
- path?: string;
74
- }) => Promise<import('../types/api/topic').DescribeTopicResult>;
75
- getConsumer: (params: {
76
- path?: string;
77
- consumer?: string;
78
- }) => Promise<import('../types/api/consumer').DescribeConsumerResult>;
79
- getHostInfo: () => Promise<import('../types/api/systemState').TEvSystemStateResponse>;
80
- getNodeInfo: (
81
- id?: string,
82
- ) => Promise<import('../types/api/systemState').TEvSystemStateResponse>;
83
- getNodesList: () => Promise<import('../types/api/nodesList').TEvNodesInfo>;
84
- [method: string]: Function;
85
- };
86
- }
@@ -1,278 +0,0 @@
1
- import AxiosWrapper from '@gravity-ui/axios-wrapper';
2
-
3
- import {backend as BACKEND} from '../store';
4
-
5
- const config = {withCredentials: !window.custom_backend};
6
-
7
- const {settingsApi} = window.web_version ? window.systemSettings : {};
8
-
9
- export class YdbEmbeddedAPI extends AxiosWrapper {
10
- getPath(path) {
11
- return `${BACKEND}${path}`;
12
- }
13
- getClusterInfo() {
14
- return this.get(this.getPath('/viewer/json/cluster'), {tablets: true});
15
- }
16
- getNodeInfo(id) {
17
- return this.get(this.getPath('/viewer/json/sysinfo?enums=true'), {
18
- node_id: id,
19
- });
20
- }
21
- getTenants() {
22
- return this.get(this.getPath('/viewer/json/tenantinfo'), {
23
- tablets: 1,
24
- storage: 1,
25
- });
26
- }
27
- getTenantInfo({path}) {
28
- return this.get(this.getPath('/viewer/json/tenantinfo'), {
29
- path,
30
- tablets: true,
31
- storage: true,
32
- });
33
- }
34
- getNodes({tenant, filter, storage, type = 'any', tablets = true}, {concurrentId} = {}) {
35
- return this.get(
36
- this.getPath('/viewer/json/nodes?enums=true'),
37
- {
38
- tenant,
39
- with: filter,
40
- storage,
41
- type,
42
- tablets,
43
- },
44
- {
45
- concurrentId,
46
- },
47
- );
48
- }
49
- getCompute(path) {
50
- return this.get(this.getPath('/viewer/json/compute?enums=true'), {path});
51
- }
52
- getStorageInfo({tenant, filter, nodeId}, {concurrentId} = {}) {
53
- return this.get(
54
- this.getPath(`/viewer/json/storage?enums=true`),
55
- {
56
- tenant,
57
- node_id: nodeId,
58
- with: filter,
59
- },
60
- {
61
- concurrentId,
62
- },
63
- );
64
- }
65
- getPdiskInfo(nodeId, pdiskId) {
66
- return this.get(this.getPath('/viewer/json/pdiskinfo?enums=true'), {
67
- filter: `(NodeId=${nodeId}${pdiskId ? `;PDiskId=${pdiskId}` : ''})`,
68
- });
69
- }
70
- getVdiskInfo({vdiskId, pdiskId, nodeId}) {
71
- return this.get(this.getPath('/viewer/json/vdiskinfo?enums=true'), {
72
- filter: `(VDiskId=${vdiskId ?? ''};PDiskId=${pdiskId ?? ''};NodeId=${nodeId ?? ''})`,
73
- });
74
- }
75
- getGroupInfo(groupId) {
76
- return this.get(this.getPath('/viewer/json/storage?enums=true'), {
77
- group_id: groupId,
78
- });
79
- }
80
- getHostInfo() {
81
- return this.get(this.getPath('/viewer/json/sysinfo?node_id=.&enums=true'));
82
- }
83
- getTabletsInfo({nodes = [], path}) {
84
- const filter = nodes.length > 0 && `(NodeId=[${nodes.join(',')}])`;
85
- return this.get(this.getPath('/viewer/json/tabletinfo'), {
86
- filter,
87
- path,
88
- enums: true,
89
- });
90
- }
91
- getSchema({path}, {concurrentId} = {}) {
92
- return this.get(
93
- this.getPath('/viewer/json/describe'),
94
- {
95
- path,
96
- enums: true,
97
- backup: false,
98
- private: true,
99
- partition_config: true,
100
- partition_stats: true,
101
- partitioning_info: true,
102
- subs: 1,
103
- },
104
- {concurrentId: concurrentId || `getSchema|${path}`},
105
- );
106
- }
107
- getDescribe({path}, {concurrentId} = {}) {
108
- return this.get(
109
- this.getPath('/viewer/json/describe'),
110
- {
111
- path,
112
- enums: true,
113
- partition_stats: true,
114
- subs: 0,
115
- },
116
- {concurrentId: concurrentId || `getDescribe|${path}`},
117
- );
118
- }
119
- getSchemaAcl({path}) {
120
- return this.get(
121
- this.getPath('/viewer/json/acl'),
122
- {
123
- path,
124
- },
125
- {concurrentId: `getSchemaAcl|${path}`},
126
- );
127
- }
128
- getHeatmapData({path}) {
129
- return this.get(this.getPath('/viewer/json/describe'), {
130
- path,
131
- enums: true,
132
- backup: false,
133
- children: false,
134
- partition_config: false,
135
- partition_stats: true,
136
- });
137
- }
138
- getNetwork(path) {
139
- return this.get(this.getPath('/viewer/json/netinfo'), {
140
- enums: true,
141
- path,
142
- });
143
- }
144
- getTopic({path}, {concurrentId} = {}) {
145
- return this.get(
146
- this.getPath('/viewer/json/describe_topic'),
147
- {
148
- enums: true,
149
- include_stats: true,
150
- path,
151
- },
152
- {concurrentId: concurrentId || 'getTopic'},
153
- );
154
- }
155
- getConsumer({path, consumer}, {concurrentId} = {}) {
156
- return this.get(
157
- this.getPath('/viewer/json/describe_consumer'),
158
- {
159
- enums: true,
160
- include_stats: true,
161
- path,
162
- consumer,
163
- },
164
- {concurrentId: concurrentId || 'getConsumer'},
165
- );
166
- }
167
- getPoolInfo(poolName) {
168
- return this.get(this.getPath('/viewer/json/storage'), {
169
- pool: poolName,
170
- enums: true,
171
- });
172
- }
173
- getTablet({id}) {
174
- return this.get(this.getPath(`/viewer/json/tabletinfo?filter=(TabletId=${id})`), {
175
- enums: true,
176
- });
177
- }
178
- getTabletHistory({id}) {
179
- return this.get(this.getPath(`/viewer/json/tabletinfo?filter=(TabletId=${id})`), {
180
- enums: true,
181
- merge: false,
182
- });
183
- }
184
- getNodesList() {
185
- return this.get(this.getPath('/viewer/json/nodelist'), {enums: true});
186
- }
187
- getTenantsList() {
188
- return this.get(this.getPath('/viewer/json/tenants'), {
189
- enums: true,
190
- state: 0,
191
- });
192
- }
193
- sendQuery({query, database, action, stats, schema}, {concurrentId} = {}) {
194
- return this.post(
195
- this.getPath(`/viewer/json/query${schema ? `?schema=${schema}` : ''}`),
196
- {
197
- query,
198
- database,
199
- action,
200
- stats,
201
- timeout: 600000,
202
- },
203
- null,
204
- {
205
- concurrentId,
206
- timeout: 9 * 60 * 1000,
207
- },
208
- );
209
- }
210
- getExplainQuery(query, database) {
211
- return this.post(this.getPath('/viewer/json/query'), {
212
- query,
213
- database,
214
- action: 'explain',
215
- timeout: 600000,
216
- });
217
- }
218
- getExplainQueryAst(query, database) {
219
- return this.post(this.getPath('/viewer/json/query'), {
220
- query,
221
- database,
222
- action: 'explain-ast',
223
- timeout: 600000,
224
- });
225
- }
226
- getHotKeys(path, enableSampling) {
227
- return this.get(this.getPath('/viewer/json/hotkeys'), {
228
- path,
229
- enable_sampling: enableSampling,
230
- });
231
- }
232
- getHealthcheckInfo(database) {
233
- return this.get(this.getPath('/viewer/json/healthcheck'), {
234
- tenant: database,
235
- });
236
- }
237
- killTablet(id) {
238
- return this.get(this.getPath(`/tablets?KillTabletID=${id}`));
239
- }
240
- stopTablet(id, hiveId) {
241
- return this.get(
242
- this.getPath(`/tablets/app?TabletID=${hiveId}&page=StopTablet&tablet=${id}`),
243
- );
244
- }
245
- resumeTablet(id, hiveId) {
246
- return this.get(
247
- this.getPath(`/tablets/app?TabletID=${hiveId}&page=ResumeTablet&tablet=${id}`),
248
- );
249
- }
250
- getTabletDescribe(tenantId) {
251
- return this.get(this.getPath('/viewer/json/describe'), {
252
- schemeshard_id: tenantId?.SchemeShard,
253
- path_id: tenantId?.PathId,
254
- });
255
- }
256
- postSetting(name, value) {
257
- return this.request({
258
- method: 'PATCH',
259
- url: settingsApi,
260
- data: {[name]: value},
261
- });
262
- }
263
- authenticate(user, password) {
264
- return this.post(this.getPath('/login'), {
265
- user,
266
- password,
267
- });
268
- }
269
- logout() {
270
- return this.post(this.getPath('/logout'), {});
271
- }
272
- whoami() {
273
- return this.get(this.getPath('/viewer/json/whoami'));
274
- }
275
- }
276
-
277
- const api = new YdbEmbeddedAPI({config: config});
278
- window.api = api;