ydb-embedded-ui 3.0.0 → 3.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 (52) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/components/ClusterInfo/ClusterInfo.tsx +1 -1
  3. package/dist/components/InfoViewer/InfoViewer.tsx +1 -1
  4. package/dist/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx +5 -2
  5. package/dist/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx +6 -5
  6. package/dist/components/InfoViewer/schemaInfo/TableIndexInfo.tsx +5 -2
  7. package/dist/components/ProblemFilter/ProblemFilter.tsx +18 -0
  8. package/dist/components/ProblemFilter/index.ts +1 -0
  9. package/dist/components/UptimeFIlter/UptimeFilter.tsx +4 -3
  10. package/dist/containers/Nodes/Nodes.js +2 -2
  11. package/dist/containers/NodesViewer/NodesViewer.js +2 -2
  12. package/dist/containers/Pool/Pool.js +2 -2
  13. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +2 -3
  14. package/dist/containers/Tenant/Diagnostics/Network/Network.js +2 -2
  15. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +11 -9
  16. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +6 -3
  17. package/dist/containers/Tenant/Diagnostics/TopShards/DateRange/DateRange.scss +13 -0
  18. package/dist/containers/Tenant/Diagnostics/TopShards/DateRange/DateRange.tsx +75 -0
  19. package/dist/containers/Tenant/Diagnostics/TopShards/DateRange/index.ts +1 -0
  20. package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.scss +17 -1
  21. package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +278 -0
  22. package/dist/containers/Tenant/Diagnostics/TopShards/i18n/en.json +4 -0
  23. package/dist/containers/Tenant/Diagnostics/TopShards/i18n/index.ts +11 -0
  24. package/dist/containers/Tenant/Diagnostics/TopShards/i18n/ru.json +4 -0
  25. package/dist/containers/Tenant/Diagnostics/TopShards/index.ts +1 -0
  26. package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.js +35 -22
  27. package/dist/containers/Tenant/Schema/SchemaInfoViewer/SchemaInfoViewer.scss +8 -0
  28. package/dist/containers/Tenant/Tenant.tsx +1 -1
  29. package/dist/containers/Tenant/utils/index.ts +8 -0
  30. package/dist/containers/Tenant/utils/schema.ts +45 -0
  31. package/dist/containers/Tenants/Tenants.js +2 -2
  32. package/dist/services/api.d.ts +3 -0
  33. package/dist/services/api.js +1 -1
  34. package/dist/store/reducers/{nodes.js → nodes.ts} +20 -14
  35. package/dist/store/reducers/shardsWorkload.ts +182 -0
  36. package/dist/store/reducers/{tooltip.js → tooltip.ts} +28 -11
  37. package/dist/store/state-url-mapping.js +8 -0
  38. package/dist/types/api/nodes.ts +3 -3
  39. package/dist/types/api/schema.ts +1 -1
  40. package/dist/types/api/tenant.ts +131 -0
  41. package/dist/types/store/nodes.ts +32 -0
  42. package/dist/types/store/shardsWorkload.ts +28 -0
  43. package/dist/types/store/tooltip.ts +25 -0
  44. package/dist/utils/constants.ts +2 -0
  45. package/dist/utils/nodes.ts +4 -4
  46. package/dist/utils/query.ts +1 -1
  47. package/dist/utils/tooltip.js +8 -6
  48. package/package.json +2 -2
  49. package/dist/components/ProblemFilter/ProblemFilter.js +0 -24
  50. package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +0 -246
  51. package/dist/store/reducers/shardsWorkload.js +0 -101
  52. package/dist/utils/actionsConstants.js +0 -4
@@ -0,0 +1,182 @@
1
+ import type {Reducer} from 'redux';
2
+
3
+ import '../../services/api';
4
+ import type {
5
+ IShardsWorkloadAction,
6
+ IShardsWorkloadFilters,
7
+ IShardsWorkloadState,
8
+ } from '../../types/store/shardsWorkload';
9
+
10
+ import {parseQueryAPIExecuteResponse} from '../../utils/query';
11
+
12
+ import {createRequestActionTypes, createApiRequest} from '../utils';
13
+
14
+ export const SEND_SHARD_QUERY = createRequestActionTypes('query', 'SEND_SHARD_QUERY');
15
+ const SET_SHARD_QUERY_OPTIONS = 'query/SET_SHARD_QUERY_OPTIONS';
16
+ const SET_TOP_SHARDS_FILTERS = 'shardsWorkload/SET_TOP_SHARDS_FILTERS';
17
+
18
+ const initialState = {
19
+ loading: false,
20
+ wasLoaded: false,
21
+ filters: {},
22
+ };
23
+
24
+ export interface SortOrder {
25
+ columnId: string;
26
+ order: string;
27
+ }
28
+
29
+ function formatSortOrder({columnId, order}: SortOrder) {
30
+ return `${columnId} ${order}`;
31
+ }
32
+
33
+ function getFiltersConditions(filters?: IShardsWorkloadFilters) {
34
+ const conditions: string[] = [];
35
+
36
+ if (filters?.from && filters?.to && filters.from > filters.to) {
37
+ throw new Error('Invalid date range');
38
+ }
39
+
40
+ if (filters?.from) {
41
+ // matching `from` & `to` is an edge case
42
+ // other cases should not include the starting point, since intervals are stored using the ending time
43
+ const gt = filters.to === filters.from ? '>=' : '>';
44
+ conditions.push(`IntervalEnd ${gt} Timestamp('${new Date(filters.from).toISOString()}')`);
45
+ }
46
+
47
+ if (filters?.to) {
48
+ conditions.push(`IntervalEnd <= Timestamp('${new Date(filters.to).toISOString()}')`);
49
+ }
50
+
51
+ return conditions.join(' AND ');
52
+ }
53
+
54
+ function createShardQuery(
55
+ path: string,
56
+ filters?: IShardsWorkloadFilters,
57
+ sortOrder?: SortOrder[],
58
+ tenantName?: string,
59
+ ) {
60
+ const pathSelect = tenantName
61
+ ? `CAST(SUBSTRING(CAST(Path AS String), ${tenantName.length}) AS Utf8) AS Path`
62
+ : 'Path';
63
+
64
+ let where = `Path='${path}' OR Path LIKE '${path}/%'`;
65
+
66
+ const filterConditions = getFiltersConditions(filters);
67
+ if (filterConditions.length) {
68
+ where = `(${where}) AND ${filterConditions}`;
69
+ }
70
+
71
+ const orderBy = sortOrder ? `ORDER BY ${sortOrder.map(formatSortOrder).join(', ')}` : '';
72
+
73
+ return `SELECT
74
+ ${pathSelect},
75
+ TabletId,
76
+ CPUCores,
77
+ DataSize,
78
+ NodeId,
79
+ PeakTime,
80
+ InFlightTxCount
81
+ FROM \`.sys/top_partitions_one_hour\`
82
+ WHERE ${where}
83
+ ${orderBy}
84
+ LIMIT 20`;
85
+ }
86
+
87
+ const queryAction = 'execute-scan';
88
+
89
+ const shardsWorkload: Reducer<IShardsWorkloadState, IShardsWorkloadAction> = (
90
+ state = initialState,
91
+ action,
92
+ ) => {
93
+ switch (action.type) {
94
+ case SEND_SHARD_QUERY.REQUEST: {
95
+ return {
96
+ ...state,
97
+ loading: true,
98
+ error: undefined,
99
+ };
100
+ }
101
+ case SEND_SHARD_QUERY.SUCCESS: {
102
+ return {
103
+ ...state,
104
+ data: action.data,
105
+ loading: false,
106
+ error: undefined,
107
+ wasLoaded: true,
108
+ };
109
+ }
110
+ // 401 Unauthorized error is handled by GenericAPI
111
+ case SEND_SHARD_QUERY.FAILURE: {
112
+ return {
113
+ ...state,
114
+ error: action.error || 'Unauthorized',
115
+ loading: false,
116
+ };
117
+ }
118
+ case SET_SHARD_QUERY_OPTIONS:
119
+ return {
120
+ ...state,
121
+ ...action.data,
122
+ };
123
+ case SET_TOP_SHARDS_FILTERS:
124
+ return {
125
+ ...state,
126
+ filters: {
127
+ ...state.filters,
128
+ ...action.filters,
129
+ },
130
+ };
131
+ default:
132
+ return state;
133
+ }
134
+ };
135
+
136
+ interface SendShardQueryParams {
137
+ database?: string;
138
+ path?: string;
139
+ sortOrder?: SortOrder[];
140
+ filters?: IShardsWorkloadFilters;
141
+ }
142
+
143
+ export const sendShardQuery = ({database, path = '', sortOrder, filters}: SendShardQueryParams) => {
144
+ try {
145
+ return createApiRequest({
146
+ request: window.api.sendQuery(
147
+ {
148
+ schema: 'modern',
149
+ query: createShardQuery(path, filters, sortOrder, database),
150
+ database,
151
+ action: queryAction,
152
+ },
153
+ {
154
+ concurrentId: 'topShards',
155
+ },
156
+ ),
157
+ actions: SEND_SHARD_QUERY,
158
+ dataHandler: parseQueryAPIExecuteResponse,
159
+ });
160
+ } catch (error) {
161
+ return {
162
+ type: SEND_SHARD_QUERY.FAILURE,
163
+ error,
164
+ };
165
+ }
166
+ };
167
+
168
+ export function setShardQueryOptions(options: Partial<IShardsWorkloadState>) {
169
+ return {
170
+ type: SET_SHARD_QUERY_OPTIONS,
171
+ data: options,
172
+ } as const;
173
+ }
174
+
175
+ export function setTopShardFilters(filters: Partial<IShardsWorkloadFilters>) {
176
+ return {
177
+ type: SET_TOP_SHARDS_FILTERS,
178
+ filters,
179
+ } as const;
180
+ }
181
+
182
+ export default shardsWorkload;
@@ -1,8 +1,19 @@
1
- import {toolTipConstants} from '../../utils/actionsConstants';
1
+ import isEqual from 'lodash/isEqual';
2
+ import type {Reducer} from 'redux';
3
+
2
4
  import {tooltipTemplates} from '../../utils/tooltip';
3
- import _ from 'lodash';
4
5
 
5
- const initialState = {
6
+ import {
7
+ ITooltipAction,
8
+ ITooltipPositions,
9
+ ITooltipState,
10
+ ITooltipTemplateType,
11
+ } from '../../types/store/tooltip';
12
+
13
+ const HIDE_TOOLTIP = 'tooltip/HIDE_TOOLTIP';
14
+ const UPDATE_REF = 'tooltip/UPDATE_REF';
15
+
16
+ const initialState: ITooltipState = {
6
17
  toolTipVisible: false,
7
18
  currentHoveredRef: undefined,
8
19
  data: undefined,
@@ -10,9 +21,9 @@ const initialState = {
10
21
  template: tooltipTemplates['pool'],
11
22
  };
12
23
 
13
- const tooltip = (state = initialState, action) => {
24
+ const tooltip: Reducer<ITooltipState, ITooltipAction> = (state = initialState, action) => {
14
25
  switch (action.type) {
15
- case toolTipConstants.HIDE_TOOLTIP: {
26
+ case HIDE_TOOLTIP: {
16
27
  return {
17
28
  ...state,
18
29
  currentHoveredRef: undefined,
@@ -20,8 +31,8 @@ const tooltip = (state = initialState, action) => {
20
31
  };
21
32
  }
22
33
 
23
- case toolTipConstants.UPDATE_REF: {
24
- if (action.templateType === 'cell' && _.isEqual(action.node, state.currentHoveredRef)) {
34
+ case UPDATE_REF: {
35
+ if (action.templateType === 'cell' && isEqual(action.node, state.currentHoveredRef)) {
25
36
  return {
26
37
  ...state,
27
38
  currentHoveredRef: undefined,
@@ -36,7 +47,7 @@ const tooltip = (state = initialState, action) => {
36
47
  positions: action.positions,
37
48
  data: action.data,
38
49
  additionalData: action.additionalData,
39
- type: action.templateType,
50
+ templateType: action.templateType,
40
51
  template: tooltipTemplates[action.templateType],
41
52
  };
42
53
  }
@@ -47,12 +58,18 @@ const tooltip = (state = initialState, action) => {
47
58
  };
48
59
 
49
60
  export const hideTooltip = () => {
50
- return {type: toolTipConstants.HIDE_TOOLTIP};
61
+ return {type: HIDE_TOOLTIP} as const;
51
62
  };
52
63
 
53
- export const showTooltip = (node, data, templateType, additionalData, positions) => {
64
+ export const showTooltip = (
65
+ node: EventTarget,
66
+ data: any,
67
+ templateType: ITooltipTemplateType,
68
+ additionalData?: any,
69
+ positions?: ITooltipPositions,
70
+ ) => {
54
71
  return {
55
- type: toolTipConstants.UPDATE_REF,
72
+ type: UPDATE_REF,
56
73
  node,
57
74
  data,
58
75
  templateType,
@@ -48,6 +48,14 @@ const paramSetup = {
48
48
  generalTab: {
49
49
  stateKey: 'tenant.diagnosticsTab',
50
50
  },
51
+ topShardsFrom: {
52
+ stateKey: 'shardsWorkload.filters.from',
53
+ type: 'number',
54
+ },
55
+ topShardsTo: {
56
+ stateKey: 'shardsWorkload.filters.to',
57
+ type: 'number',
58
+ },
51
59
  },
52
60
  };
53
61
 
@@ -12,14 +12,14 @@ export interface TNodesInfo {
12
12
  FoundNodes: string;
13
13
  }
14
14
 
15
- interface TNodeInfo {
15
+ export interface TNodeInfo {
16
16
  NodeId: number;
17
17
  SystemState: TSystemStateInfo;
18
18
  PDisks?: TPDiskStateInfo[];
19
19
  Tablets?: TTabletStateInfo[];
20
20
  }
21
21
 
22
- interface TSystemStateInfo {
22
+ export interface TSystemStateInfo {
23
23
  /** uint64 */
24
24
  StartTime?: string;
25
25
  /** uint64 */
@@ -57,7 +57,7 @@ interface TSystemStateInfo {
57
57
  Location?: TNodeLocation;
58
58
  }
59
59
 
60
- interface TPoolStats {
60
+ export interface TPoolStats {
61
61
  Name?: string;
62
62
  /** double */
63
63
  Usage?: number;
@@ -38,7 +38,7 @@ enum EStatus {
38
38
  }
39
39
 
40
40
  // incomplete interface, only currently used fields are covered
41
- interface TPathDescription {
41
+ export interface TPathDescription {
42
42
  /** info about the path itself */
43
43
  Self?: TDirEntry;
44
44
  DomainDescription?: TDomainDescription;
@@ -0,0 +1,131 @@
1
+ import {EFlag} from './enums';
2
+ import {TPoolStats, TSystemStateInfo} from './nodes';
3
+ import {TTabletStateInfo} from './tablet';
4
+
5
+ export interface TTenants {
6
+ Tenants?: TTenant[];
7
+ }
8
+
9
+ export interface TTenantInfo {
10
+ TenantInfo?: TTenant[];
11
+ Errors?: string[];
12
+ }
13
+
14
+ export interface TTenant {
15
+ Name: string;
16
+ Id: string;
17
+ Type: ETenantType;
18
+ State: State;
19
+ StateStats?: THiveDomainStatsStateCount[];
20
+ Metrics: TMetrics;
21
+ NodeIds?: number[];
22
+ AliveNodes: number;
23
+ Resources: TTenantResources;
24
+ /** uint64 */
25
+ CreateTime: string;
26
+ Owner: string;
27
+ Users?: string[];
28
+ PoolStats?: TPoolStats[];
29
+ UserAttributes: Record<string, string>;
30
+ Overall: EFlag;
31
+ SystemTablets?: TTabletStateInfo[];
32
+ ResourceId: string;
33
+ Tablets?: TTabletStateInfo[];
34
+ /** uint64 */
35
+ StorageAllocatedSize: string;
36
+ /** uint64 */
37
+ StorageMinAvailableSize: string;
38
+ Nodes?: TSystemStateInfo[];
39
+ /** uint64 */
40
+ MemoryUsed: string;
41
+ /** uint64 */
42
+ MemoryLimit: string;
43
+ /** double */
44
+ CoresUsed: number;
45
+ /** uint64 */
46
+ StorageGroups: string;
47
+ }
48
+
49
+ interface THiveDomainStatsStateCount {
50
+ VolatileState?: ETabletVolatileState;
51
+ Count?: number;
52
+ }
53
+
54
+ interface TMetrics {
55
+ /** uint64 */
56
+ CPU?: string;
57
+ /** uint64 */
58
+ Memory?: string;
59
+ /** uint64 */
60
+ Network?: string;
61
+ /** uint64 */
62
+ Counter?: string;
63
+ /** uint64 */
64
+ Storage?: string;
65
+ /** uint64 */
66
+ ReadThroughput?: string;
67
+ /** uint64 */
68
+ WriteThroughput?: string;
69
+ /** uint64 */
70
+ ReadIops?: string;
71
+ /** uint64 */
72
+ WriteIops?: string;
73
+
74
+ GroupReadThroughput?: TThroughputRecord[];
75
+ GroupWriteThroughput?: TThroughputRecord[];
76
+
77
+ GroupReadIops?: TIopsRecord[];
78
+ GroupWriteIops?: TIopsRecord[];
79
+ }
80
+
81
+ interface TThroughputRecord {
82
+ GroupID?: number;
83
+ Channel?: number;
84
+ /** uint64 */
85
+ Throughput?: string;
86
+ }
87
+
88
+ interface TIopsRecord {
89
+ GroupID?: number;
90
+ Channel?: number;
91
+ /** uint64 */
92
+ Iops?: string;
93
+ }
94
+
95
+ interface TTenantResources {
96
+ Required?: TTenantResource[];
97
+ Allocated?: TTenantResource[];
98
+ }
99
+
100
+ interface TTenantResource {
101
+ Type: string;
102
+ Zone: string;
103
+ Kind: string;
104
+ Count: number;
105
+ }
106
+
107
+ export enum ETenantType {
108
+ 'UnknownTenantType' = 'UnknownTenantType',
109
+ 'Domain' = 'Domain',
110
+ 'Dedicated' = 'Dedicated',
111
+ 'Shared' = 'Shared',
112
+ 'Serverless' = 'Serverless',
113
+ }
114
+
115
+ enum State {
116
+ 'STATE_UNSPECIFIED' = 'STATE_UNSPECIFIED',
117
+ 'CREATING' = 'CREATING',
118
+ 'RUNNING' = 'RUNNING',
119
+ 'REMOVING' = 'REMOVING',
120
+ 'PENDING_RESOURCES' = 'PENDING_RESOURCES',
121
+ 'CONFIGURING' = 'CONFIGURING',
122
+ }
123
+
124
+ enum ETabletVolatileState {
125
+ 'TABLET_VOLATILE_STATE_UNKNOWN' = 'TABLET_VOLATILE_STATE_UNKNOWN',
126
+ 'TABLET_VOLATILE_STATE_STOPPED' = 'TABLET_VOLATILE_STATE_STOPPED',
127
+ 'TABLET_VOLATILE_STATE_BOOTING' = 'TABLET_VOLATILE_STATE_BOOTING',
128
+ 'TABLET_VOLATILE_STATE_STARTING' = 'TABLET_VOLATILE_STATE_STARTING',
129
+ 'TABLET_VOLATILE_STATE_RUNNING' = 'TABLET_VOLATILE_STATE_RUNNING',
130
+ '_TABLET_VOLATILE_STATE_BLOCKED' = '_TABLET_VOLATILE_STATE_BLOCKED',
131
+ }
@@ -0,0 +1,32 @@
1
+ import {NodesUptimeFilterValues} from '../../utils/nodes';
2
+ import {
3
+ FETCH_NODES,
4
+ clearNodes,
5
+ setDataWasNotLoaded,
6
+ setNodesUptimeFilter,
7
+ } from '../../store/reducers/nodes';
8
+ import {ApiRequestAction} from '../../store/utils';
9
+ import {IResponseError} from '../api/error';
10
+ import {TNodesInfo} from '../api/nodes';
11
+
12
+ export interface INodesState {
13
+ loading: boolean;
14
+ wasLoaded: boolean;
15
+ nodesUptimeFilter: NodesUptimeFilterValues;
16
+ data?: TNodesInfo;
17
+ error?: IResponseError;
18
+ }
19
+
20
+ type INodesApiRequestAction = ApiRequestAction<typeof FETCH_NODES, TNodesInfo, IResponseError>;
21
+
22
+ export type INodesAction =
23
+ | INodesApiRequestAction
24
+ | (
25
+ | ReturnType<typeof clearNodes>
26
+ | ReturnType<typeof setDataWasNotLoaded>
27
+ | ReturnType<typeof setNodesUptimeFilter>
28
+ );
29
+
30
+ export interface INodesRootStateSlice {
31
+ nodes: INodesState;
32
+ }
@@ -0,0 +1,28 @@
1
+ import {SEND_SHARD_QUERY, setShardQueryOptions, setTopShardFilters} from '../../store/reducers/shardsWorkload';
2
+ import type {ApiRequestAction} from '../../store/utils';
3
+ import type {IResponseError} from '../api/error';
4
+ import type {IQueryResult} from './query';
5
+
6
+ export interface IShardsWorkloadFilters {
7
+ /** ms from epoch */
8
+ from?: number;
9
+ /** ms from epoch */
10
+ to?: number;
11
+ }
12
+
13
+ export interface IShardsWorkloadState {
14
+ loading: boolean;
15
+ wasLoaded: boolean;
16
+ data?: IQueryResult;
17
+ error?: IResponseError;
18
+ filters: IShardsWorkloadFilters;
19
+ }
20
+
21
+ export type IShardsWorkloadAction =
22
+ | ApiRequestAction<typeof SEND_SHARD_QUERY, IQueryResult, IResponseError>
23
+ | ReturnType<typeof setShardQueryOptions>
24
+ | ReturnType<typeof setTopShardFilters>;
25
+
26
+ export interface IShardsWorkloadRootStateSlice {
27
+ shardsWorkload: IShardsWorkloadState;
28
+ }
@@ -0,0 +1,25 @@
1
+ import {hideTooltip, showTooltip} from '../../store/reducers/tooltip';
2
+ import {tooltipTemplates} from '../../utils/tooltip';
3
+
4
+ export type ITooltipTemplateType = keyof typeof tooltipTemplates;
5
+
6
+ export interface ITooltipPositions {
7
+ left: number;
8
+ top: number;
9
+ }
10
+
11
+ export interface ITooltipState {
12
+ toolTipVisible: boolean;
13
+ positions?: ITooltipPositions;
14
+ currentHoveredRef?: EventTarget;
15
+ template: (data: any) => JSX.Element;
16
+ templateType: ITooltipTemplateType;
17
+ data?: any;
18
+ additionalData?: any;
19
+ }
20
+
21
+ export type ITooltipAction = ReturnType<typeof hideTooltip> | ReturnType<typeof showTooltip>;
22
+
23
+ export interface ITooltipRootStateSlice {
24
+ tooltip: ITooltipState;
25
+ }
@@ -118,6 +118,8 @@ export const COLORS_PRIORITY = {
118
118
  export const ALL = 'All';
119
119
  export const PROBLEMS = 'With problems';
120
120
 
121
+ export type IProblemFilterValues = typeof ALL | typeof PROBLEMS;
122
+
121
123
  export const THEME_KEY = 'theme';
122
124
  export const INVERTED_DISKS_KEY = 'invertedDisks';
123
125
  export const SAVED_QUERIES_KEY = 'saved_queries';
@@ -1,7 +1,7 @@
1
- export const NodesUptimeFilterValues = {
2
- All: 'All',
3
- SmallUptime: 'SmallUptime',
4
- };
1
+ export enum NodesUptimeFilterValues {
2
+ 'All' = 'All',
3
+ 'SmallUptime' = 'SmallUptime',
4
+ }
5
5
 
6
6
  export const NodesUptimeFilterTitles = {
7
7
  [NodesUptimeFilterValues.All]: 'All',
@@ -186,5 +186,5 @@ export const prepareQueryResponse = (data?: KeyValueRow[]) => {
186
186
  };
187
187
 
188
188
  export function prepareQueryError(error: any) {
189
- return error.data?.error?.message || error.data || error.statusText || JSON.stringify(error);
189
+ return error.data?.error?.message || error.message || error.data || error.statusText || JSON.stringify(error);
190
190
  }
@@ -122,12 +122,14 @@ const NodeEndpointsTooltip = (props) => {
122
122
  <td className={nodeB('value')}>{data.Rack}</td>
123
123
  </tr>
124
124
  )}
125
- {data.Endpoints && data.Endpoints.length && data.Endpoints.map(({Name, Address}) => (
126
- <tr key={Name}>
127
- <td className={nodeB('label')}>{Name}</td>
128
- <td className={nodeB('value')}>{Address}</td>
129
- </tr>
130
- ))}
125
+ {data.Endpoints &&
126
+ data.Endpoints.length &&
127
+ data.Endpoints.map(({Name, Address}) => (
128
+ <tr key={Name}>
129
+ <td className={nodeB('label')}>{Name}</td>
130
+ <td className={nodeB('value')}>{Address}</td>
131
+ </tr>
132
+ ))}
131
133
  </tbody>
132
134
  </table>
133
135
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -9,6 +9,7 @@
9
9
  "url": "git@github.com:ydb-platform/ydb-embedded-ui.git"
10
10
  },
11
11
  "dependencies": {
12
+ "@gravity-ui/axios-wrapper": "^1.3.0",
12
13
  "@gravity-ui/i18n": "^1.0.0",
13
14
  "@yandex-cloud/paranoid": "^1.3.0",
14
15
  "@yandex-cloud/react-data-table": "0.2.1",
@@ -112,7 +113,6 @@
112
113
  "@types/react-router-dom": "^5.3.2",
113
114
  "@types/react-transition-group": "^4.4.4",
114
115
  "@types/react-virtualized-auto-sizer": "^1.0.1",
115
- "@yandex-cloud/axios-wrapper": "^1.0.2",
116
116
  "copyfiles": "^2.4.1",
117
117
  "eslint-config-prettier": "^8.3.0",
118
118
  "husky": "^7.0.4",
@@ -1,24 +0,0 @@
1
- import PropTypes from 'prop-types';
2
-
3
- import {RadioButton} from '@gravity-ui/uikit';
4
-
5
- import {ALL, PROBLEMS} from '../../utils/constants';
6
-
7
- export default function ProblemFilter(props) {
8
- const {value, onChange, className} = props;
9
-
10
- return (
11
- <RadioButton value={value} onUpdate={(value) => onChange(value)} className={className}>
12
- <RadioButton.Option value={ALL}>{ALL}</RadioButton.Option>
13
- <RadioButton.Option value={PROBLEMS}>{PROBLEMS}</RadioButton.Option>
14
- </RadioButton>
15
- );
16
- }
17
-
18
- export const problemFilterType = PropTypes.oneOf([ALL, PROBLEMS]);
19
-
20
- ProblemFilter.propTypes = {
21
- value: problemFilterType,
22
- onChange: PropTypes.func,
23
- className: PropTypes.string,
24
- };