ydb-embedded-ui 4.8.2 → 4.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/components/NodeHostWrapper/NodeHostWrapper.tsx +2 -2
  3. package/dist/containers/Nodes/Nodes.tsx +1 -1
  4. package/dist/containers/Nodes/getNodesColumns.tsx +2 -2
  5. package/dist/containers/Storage/PDisk/PDisk.tsx +1 -1
  6. package/dist/containers/Storage/Storage.js +26 -48
  7. package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +16 -19
  8. package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +12 -10
  9. package/dist/containers/Storage/StorageTypeFilter/StorageTypeFilter.tsx +27 -0
  10. package/dist/containers/Storage/StorageVisibleEntityFilter/StorageVisibleEntityFilter.tsx +31 -0
  11. package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.js +17 -43
  12. package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.scss +20 -15
  13. package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.tsx +74 -27
  14. package/dist/containers/Tenant/Query/i18n/en.json +1 -1
  15. package/dist/containers/Tenant/Query/i18n/ru.json +1 -1
  16. package/dist/containers/UserSettings/i18n/en.json +1 -1
  17. package/dist/containers/UserSettings/i18n/ru.json +1 -1
  18. package/dist/services/api.ts +6 -13
  19. package/dist/store/reducers/executeQuery.ts +2 -3
  20. package/dist/store/reducers/explainQuery.ts +2 -2
  21. package/dist/store/reducers/index.ts +2 -2
  22. package/dist/store/reducers/{nodes.ts → nodes/nodes.ts} +31 -30
  23. package/dist/{types/store/nodes.ts → store/reducers/nodes/types.ts} +24 -27
  24. package/dist/store/reducers/settings/settings.ts +10 -2
  25. package/dist/store/reducers/storage/constants.ts +10 -0
  26. package/dist/store/reducers/{storage.js → storage/storage.js} +19 -53
  27. package/dist/store/reducers/storage/types.ts +12 -0
  28. package/dist/types/store/query.ts +5 -6
  29. package/dist/utils/constants.ts +1 -0
  30. package/dist/utils/nodes.ts +2 -2
  31. package/dist/utils/query.ts +12 -0
  32. package/package.json +1 -1
  33. package/dist/containers/Tenant/Query/QueryEditorControls/OldQueryEditorControls.tsx +0 -90
  34. package/dist/containers/Tenant/Query/QueryEditorControls/shared.ts +0 -18
@@ -1,31 +1,16 @@
1
1
  import _ from 'lodash';
2
2
  import {createSelector} from 'reselect';
3
3
 
4
- import {calcUptime} from '../../utils';
5
- import {getUsage} from '../../utils/storage';
6
- import {NodesUptimeFilterValues} from '../../utils/nodes';
7
- import {getPDiskType} from '../../utils/pdisk';
8
- import '../../services/api';
9
-
10
- import {createRequestActionTypes, createApiRequest} from '../utils';
11
- import {filterNodesByUptime} from './nodes';
12
-
13
- export const VisibleEntities = {
14
- All: 'All',
15
- Missing: 'Missing',
16
- Space: 'Space',
17
- };
4
+ import {calcUptime} from '../../../utils';
5
+ import {getUsage} from '../../../utils/storage';
6
+ import {NodesUptimeFilterValues} from '../../../utils/nodes';
7
+ import {getPDiskType} from '../../../utils/pdisk';
8
+ import '../../../services/api';
18
9
 
19
- export const VisibleEntitiesTitles = {
20
- [VisibleEntities.All]: 'All',
21
- [VisibleEntities.Missing]: 'Degraded',
22
- [VisibleEntities.Space]: 'Out of Space',
23
- };
10
+ import {createRequestActionTypes, createApiRequest} from '../../utils';
11
+ import {filterNodesByUptime} from '../nodes/nodes';
24
12
 
25
- export const StorageTypes = {
26
- groups: 'Groups',
27
- nodes: 'Nodes',
28
- };
13
+ import {VISIBLE_ENTITIES, STORAGE_TYPES} from './constants';
29
14
 
30
15
  const FETCH_STORAGE = createRequestActionTypes('storage', 'FETCH_STORAGE');
31
16
  const SET_INITIAL = 'storage/SET_INITIAL';
@@ -41,9 +26,9 @@ const initialState = {
41
26
  wasLoaded: false,
42
27
  filter: '',
43
28
  usageFilter: [],
44
- visible: VisibleEntities.Missing,
29
+ visible: VISIBLE_ENTITIES.missing,
45
30
  nodesUptimeFilter: NodesUptimeFilterValues.All,
46
- type: StorageTypes.groups,
31
+ type: STORAGE_TYPES.groups,
47
32
  };
48
33
 
49
34
  const storage = (state = initialState, action) => {
@@ -134,16 +119,16 @@ export function setInitialState() {
134
119
  };
135
120
  }
136
121
 
137
- export function getStorageInfo({tenant, filter, nodeId, type}, {concurrentId}) {
138
- if (type === StorageTypes.nodes) {
122
+ export function getStorageInfo({tenant, visibleEntities, nodeId, type}, {concurrentId}) {
123
+ if (type === STORAGE_TYPES.nodes) {
139
124
  return createApiRequest({
140
- request: window.api.getNodes({tenant, filter, type: 'static'}, {concurrentId}),
125
+ request: window.api.getNodes({tenant, visibleEntities, type: 'static'}, {concurrentId}),
141
126
  actions: FETCH_STORAGE,
142
127
  });
143
128
  }
144
129
 
145
130
  return createApiRequest({
146
- request: window.api.getStorageInfo({tenant, filter, nodeId}, {concurrentId}),
131
+ request: window.api.getStorageInfo({tenant, visibleEntities, nodeId}, {concurrentId}),
147
132
  actions: FETCH_STORAGE,
148
133
  });
149
134
  }
@@ -343,26 +328,13 @@ export const getVDisksForPDisk = createSelector(
343
328
  export const getFlatListStorage = createSelector(
344
329
  [getStorageType, getFlatListStorageGroups, getFlatListStorageNodes],
345
330
  (storageType, groupsList, nodesList) => {
346
- if (storageType === StorageTypes.groups) {
331
+ if (storageType === STORAGE_TYPES.groups) {
347
332
  return groupsList;
348
333
  }
349
334
  return nodesList;
350
335
  },
351
336
  );
352
337
 
353
- export const getVisibleEntitiesList = createSelector(
354
- [getVisibleEntities, getFlatListStorage],
355
- (visibleGroups, storageList) => {
356
- if (visibleGroups === VisibleEntities.All) {
357
- return storageList;
358
- } else if (visibleGroups === VisibleEntities.Missing) {
359
- return _.filter(storageList, (g) => g.Missing > 0);
360
- } else {
361
- return _.filter(storageList, (g) => g.UsedSpaceFlag > 100);
362
- }
363
- },
364
- );
365
-
366
338
  const filterByText = (entities, type, text) => {
367
339
  const cleanedFilter = text.trim().toLowerCase();
368
340
 
@@ -371,7 +343,7 @@ const filterByText = (entities, type, text) => {
371
343
  }
372
344
 
373
345
  return entities.filter((entity) => {
374
- if (type === StorageTypes.groups) {
346
+ if (type === STORAGE_TYPES.groups) {
375
347
  return (
376
348
  entity.PoolName.toLowerCase().includes(cleanedFilter) ||
377
349
  entity.GroupID?.toString().includes(cleanedFilter)
@@ -397,19 +369,13 @@ const filterByUsage = (entities, usage) => {
397
369
  };
398
370
 
399
371
  export const getFilteredEntities = createSelector(
400
- [
401
- getStorageFilter,
402
- getUsageFilter,
403
- getStorageType,
404
- getNodesUptimeFilter,
405
- getVisibleEntitiesList,
406
- ],
372
+ [getStorageFilter, getUsageFilter, getStorageType, getNodesUptimeFilter, getFlatListStorage],
407
373
  (textFilter, usageFilter, type, nodesUptimeFilter, entities) => {
408
374
  let result = entities;
409
375
  result = filterByText(result, type, textFilter);
410
376
  result = filterByUsage(result, usageFilter);
411
377
 
412
- if (type === StorageTypes.nodes) {
378
+ if (type === STORAGE_TYPES.nodes) {
413
379
  result = filterNodesByUptime(result, nodesUptimeFilter);
414
380
  }
415
381
 
@@ -417,7 +383,7 @@ export const getFilteredEntities = createSelector(
417
383
  },
418
384
  );
419
385
 
420
- export const getUsageFilterOptions = createSelector(getVisibleEntitiesList, (entities) => {
386
+ export const getUsageFilterOptions = createSelector(getFlatListStorage, (entities) => {
421
387
  const items = {};
422
388
 
423
389
  entities.forEach((entity) => {
@@ -0,0 +1,12 @@
1
+ import type {ValueOf} from '../../../types/common';
2
+
3
+ import {STORAGE_TYPES, VISIBLE_ENTITIES} from './constants';
4
+
5
+ export type VisibleEntities = ValueOf<typeof VISIBLE_ENTITIES>;
6
+ export type StorageType = ValueOf<typeof STORAGE_TYPES>;
7
+
8
+ export interface StorageApiRequestParams {
9
+ tenant?: string;
10
+ nodeId?: string;
11
+ visibleEntities?: VisibleEntities;
12
+ }
@@ -1,3 +1,5 @@
1
+ import {QUERY_ACTIONS, QUERY_MODES} from '../../utils/query';
2
+
1
3
  import type {NetworkError} from '../api/error';
2
4
  import type {
3
5
  KeyValueRow,
@@ -7,6 +9,7 @@ import type {
7
9
  QueryPlan,
8
10
  TKqpStatsQuery,
9
11
  } from '../api/query';
12
+ import type {ValueOf} from '../common';
10
13
 
11
14
  export interface IQueryResult {
12
15
  result?: KeyValueRow[];
@@ -23,12 +26,8 @@ export interface QueryRequestParams {
23
26
 
24
27
  export type QueryError = NetworkError | ErrorResponse;
25
28
 
26
- export enum QueryModes {
27
- scan = 'scan',
28
- script = 'script',
29
- data = 'data',
30
- query = 'query',
31
- }
29
+ export type QueryAction = ValueOf<typeof QUERY_ACTIONS>;
30
+ export type QueryMode = ValueOf<typeof QUERY_MODES>;
32
31
 
33
32
  export interface SavedQuery {
34
33
  name: string;
@@ -105,6 +105,7 @@ export const DEFAULT_TABLE_SETTINGS = {
105
105
  } as const;
106
106
 
107
107
  export const QUERY_INITIAL_MODE_KEY = 'query_initial_mode';
108
+ export const LAST_USED_QUERY_ACTION_KEY = 'last_used_query_action';
108
109
 
109
110
  export const PARTITIONS_HIDDEN_COLUMNS_KEY = 'partitionsHiddenColumns';
110
111
 
@@ -1,6 +1,6 @@
1
1
  import type {TSystemStateInfo} from '../types/api/nodes';
2
2
  import type {TNodeInfo} from '../types/api/nodesList';
3
- import type {INodesPreparedEntity} from '../types/store/nodes';
3
+ import type {NodesPreparedEntity} from '../store/reducers/nodes/types';
4
4
  import type {NodesMap} from '../types/store/nodesList';
5
5
  import {EFlag} from '../types/api/enums';
6
6
 
@@ -14,7 +14,7 @@ export const NodesUptimeFilterTitles = {
14
14
  [NodesUptimeFilterValues.SmallUptime]: 'Uptime < 1h',
15
15
  };
16
16
 
17
- export const isUnavailableNode = (node: INodesPreparedEntity | TSystemStateInfo) =>
17
+ export const isUnavailableNode = (node: NodesPreparedEntity | TSystemStateInfo) =>
18
18
  !node.SystemState || node.SystemState === EFlag.Grey;
19
19
 
20
20
  export type NodeAddress = Pick<TSystemStateInfo, 'Host' | 'Endpoints'>;
@@ -9,6 +9,18 @@ import type {
9
9
  } from '../types/api/query';
10
10
  import type {IQueryResult} from '../types/store/query';
11
11
 
12
+ export const QUERY_ACTIONS = {
13
+ execute: 'execute',
14
+ explain: 'explain',
15
+ } as const;
16
+
17
+ export const QUERY_MODES = {
18
+ scan: 'scan',
19
+ script: 'script',
20
+ data: 'data',
21
+ query: 'query',
22
+ } as const;
23
+
12
24
  // eslint-disable-next-line complexity
13
25
  export const getColumnType = (type: string) => {
14
26
  switch (type.replace(/\?$/, '')) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-embedded-ui",
3
- "version": "4.8.2",
3
+ "version": "4.9.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -1,90 +0,0 @@
1
- import {Button, DropdownMenu} from '@gravity-ui/uikit';
2
- import {useMemo} from 'react';
3
-
4
- import {QueryModes} from '../../../../types/store/query';
5
- import {Icon} from '../../../../components/Icon';
6
-
7
- import SaveQuery from '../SaveQuery/SaveQuery';
8
-
9
- import {QueryEditorControlsProps, b} from './shared';
10
-
11
- import './QueryEditorControls.scss';
12
-
13
- type OldQueryModes = QueryModes.script | QueryModes.scan;
14
-
15
- export const QueryModeSelectorTitles = {
16
- [QueryModes.script]: 'Script',
17
- [QueryModes.scan]: 'Scan',
18
- } as const;
19
-
20
- export const OldQueryEditorControls = ({
21
- onRunButtonClick,
22
- runIsLoading,
23
- onExplainButtonClick,
24
- explainIsLoading,
25
- onSaveQueryClick,
26
- savedQueries,
27
- disabled,
28
- onUpdateQueryMode,
29
- queryMode,
30
- }: QueryEditorControlsProps) => {
31
- const runModeSelectorMenuItems = useMemo(() => {
32
- return Object.entries(QueryModeSelectorTitles).map(([mode, title]) => {
33
- return {
34
- text: `Run ${title}`,
35
- action: () => {
36
- onUpdateQueryMode(mode as OldQueryModes);
37
- },
38
- };
39
- });
40
- }, [onUpdateQueryMode]);
41
-
42
- return (
43
- <div className={b()}>
44
- <div className={b('left')}>
45
- <div className={b('run')}>
46
- <Button
47
- onClick={() => onRunButtonClick(queryMode)}
48
- view="action"
49
- pin="round-brick"
50
- disabled={disabled}
51
- loading={runIsLoading}
52
- >
53
- <Icon name="startPlay" viewBox="0 0 16 16" width={16} height={16} />
54
- {`Run ${QueryModeSelectorTitles[queryMode as OldQueryModes]}`}
55
- </Button>
56
- <DropdownMenu
57
- items={runModeSelectorMenuItems}
58
- popupProps={{className: b('select-query-action-popup')}}
59
- switcher={
60
- <Button
61
- view="action"
62
- pin="brick-round"
63
- disabled={disabled}
64
- loading={runIsLoading}
65
- className={b('select-query-action')}
66
- >
67
- <Icon name="chevron-down" width={16} height={16} />
68
- </Button>
69
- }
70
- />
71
- </div>
72
- <Button
73
- onClick={() => {
74
- // Without defined query mode it sends 'explain' action
75
- onExplainButtonClick();
76
- }}
77
- disabled={disabled}
78
- loading={explainIsLoading}
79
- >
80
- Explain
81
- </Button>
82
- </div>
83
- <SaveQuery
84
- savedQueries={savedQueries}
85
- onSaveQuery={onSaveQueryClick}
86
- saveButtonDisabled={disabled}
87
- />
88
- </div>
89
- );
90
- };
@@ -1,18 +0,0 @@
1
- import block from 'bem-cn-lite';
2
-
3
- import type {QueryModes} from '../../../../types/store/query';
4
-
5
- export const b = block('ydb-query-editor-controls');
6
-
7
- export interface QueryEditorControlsProps {
8
- onRunButtonClick: (mode?: QueryModes) => void;
9
- runIsLoading: boolean;
10
- onExplainButtonClick: (mode?: QueryModes) => void;
11
- explainIsLoading: boolean;
12
- onSaveQueryClick: (queryName: string) => void;
13
- savedQueries: unknown;
14
- disabled: boolean;
15
- onUpdateQueryMode: (mode: QueryModes) => void;
16
- queryMode: QueryModes;
17
- enableQueryModesForExplain: boolean;
18
- }