ydb-embedded-ui 3.5.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
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;