ydb-embedded-ui 4.5.0 → 4.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/CriticalActionDialog/CriticalActionDialog.tsx +3 -0
  3. package/dist/components/FullNodeViewer/FullNodeViewer.js +1 -1
  4. package/dist/components/PoolUsage/PoolUsage.scss +1 -1
  5. package/dist/components/PoolUsage/PoolUsage.tsx +50 -0
  6. package/dist/containers/Node/Node.tsx +1 -1
  7. package/dist/containers/Node/NodeStructure/NodeStructure.tsx +19 -17
  8. package/dist/containers/Tablet/Tablet.scss +4 -0
  9. package/dist/containers/Tablet/Tablet.tsx +2 -1
  10. package/dist/containers/Tablet/TabletControls/TabletControls.tsx +19 -27
  11. package/dist/containers/Tenant/Diagnostics/Consumers/columns/columns.tsx +2 -2
  12. package/dist/containers/Tenant/Diagnostics/Diagnostics.tsx +37 -38
  13. package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +15 -28
  14. package/dist/containers/Tenant/Diagnostics/Network/Network.js +2 -2
  15. package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverview.js +3 -3
  16. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +5 -3
  17. package/dist/containers/Tenant/ObjectGeneral/ObjectGeneral.tsx +2 -3
  18. package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +3 -3
  19. package/dist/containers/Tenant/Tenant.tsx +14 -15
  20. package/dist/containers/Tenant/TenantPages.tsx +3 -6
  21. package/dist/containers/Tenant/utils/schemaActions.ts +4 -4
  22. package/dist/containers/Versions/GroupedNodesTree/GroupedNodesTree.scss +1 -0
  23. package/dist/containers/Versions/NodesTable/NodesTable.tsx +2 -3
  24. package/dist/routes.ts +1 -1
  25. package/dist/services/api.ts +2 -2
  26. package/dist/store/reducers/index.ts +4 -4
  27. package/dist/store/reducers/{network.js → network/network.ts} +11 -8
  28. package/dist/store/reducers/network/types.ts +16 -0
  29. package/dist/store/reducers/node/node.ts +102 -0
  30. package/dist/store/reducers/node/selectors.ts +59 -0
  31. package/dist/store/reducers/node/types.ts +44 -0
  32. package/dist/store/reducers/{schemaAcl.js → schemaAcl/schemaAcl.ts} +20 -9
  33. package/dist/store/reducers/schemaAcl/types.ts +15 -0
  34. package/dist/store/reducers/tenant/constants.ts +19 -0
  35. package/dist/store/reducers/{tenant.js → tenant/tenant.ts} +27 -36
  36. package/dist/store/reducers/tenant/types.ts +25 -0
  37. package/dist/types/api/acl.ts +1 -1
  38. package/dist/utils/index.js +2 -1
  39. package/package.json +2 -1
  40. package/dist/components/Breadcrumbs/Breadcrumbs.js +0 -25
  41. package/dist/components/Breadcrumbs/Breadcrumbs.scss +0 -5
  42. package/dist/components/Collapse/Collapse.js +0 -84
  43. package/dist/components/Collapse/Collapse.scss +0 -70
  44. package/dist/components/PoolUsage/PoolUsage.js +0 -54
  45. package/dist/store/reducers/node.js +0 -141
@@ -6,10 +6,10 @@ import {Loader} from '@gravity-ui/uikit';
6
6
 
7
7
  import EntityStatus from '../../../../components/EntityStatus/EntityStatus';
8
8
  import InfoViewer from '../../../../components/InfoViewer/InfoViewer';
9
- import PoolUsage from '../../../../components/PoolUsage/PoolUsage';
9
+ import {PoolUsage} from '../../../../components/PoolUsage/PoolUsage';
10
10
  import {Tablet} from '../../../../components/Tablet';
11
11
 
12
- import {getTenantInfo} from '../../../../store/reducers/tenant';
12
+ import {getTenantInfo} from '../../../../store/reducers/tenant/tenant';
13
13
 
14
14
  import {formatCPU} from '../../../../utils';
15
15
  import {bytesToGB} from '../../../../utils/utils';
@@ -191,7 +191,7 @@ class TenantOverview extends React.Component {
191
191
  }
192
192
 
193
193
  function mapStateToProps(state) {
194
- const {tenant = {}, loading, data: {status} = {}} = state.tenant;
194
+ const {tenant = {}, loading, error: {status} = {}} = state.tenant;
195
195
  const {autorefresh} = state.schema;
196
196
 
197
197
  return {
@@ -22,7 +22,9 @@ import type {KeyValueRow} from '../../../../types/api/query';
22
22
  import type {EPathType} from '../../../../types/api/schema';
23
23
  import type {ITopQueriesFilters} from '../../../../types/store/executeTopQueries';
24
24
  import type {IQueryResult} from '../../../../types/store/query';
25
+ import type {TenantGeneralTab} from '../../../../store/reducers/tenant/types';
25
26
 
27
+ import {TENANT_GENERAL_TABS_IDS} from '../../../../store/reducers/tenant/constants';
26
28
  import {formatDateTime, formatNumber} from '../../../../utils';
27
29
  import {DEFAULT_TABLE_SETTINGS, HOUR_IN_SECONDS} from '../../../../utils/constants';
28
30
  import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
@@ -30,7 +32,7 @@ import {prepareQueryError} from '../../../../utils/query';
30
32
  import routes, {createHref} from '../../../../routes';
31
33
 
32
34
  import {isColumnEntityType} from '../../utils/schema';
33
- import {TenantGeneralTabsIds, TenantTabsGroups} from '../../TenantPages';
35
+ import {TenantTabsGroups} from '../../TenantPages';
34
36
 
35
37
  import i18n from './i18n';
36
38
  import './TopQueries.scss';
@@ -86,7 +88,7 @@ const COLUMNS: Column<KeyValueRow>[] = [
86
88
 
87
89
  interface TopQueriesProps {
88
90
  path: string;
89
- changeSchemaTab: (tab: TenantGeneralTabsIds) => void;
91
+ changeSchemaTab: (tab: TenantGeneralTab) => void;
90
92
  type?: EPathType;
91
93
  }
92
94
 
@@ -178,7 +180,7 @@ export const TopQueries = ({path, type}: TopQueriesProps) => {
178
180
 
179
181
  const queryPath = createHref(routes.tenant, undefined, {
180
182
  ...queryParams,
181
- [TenantTabsGroups.general]: TenantGeneralTabsIds.query,
183
+ [TenantTabsGroups.general]: TENANT_GENERAL_TABS_IDS.query,
182
184
  });
183
185
 
184
186
  history.push(queryPath);
@@ -5,12 +5,11 @@ import cn from 'bem-cn-lite';
5
5
  import {useThemeValue} from '@gravity-ui/uikit';
6
6
 
7
7
  import type {EPathType} from '../../../types/api/schema';
8
+ import {TENANT_GENERAL_TABS_IDS} from '../../../store/reducers/tenant/constants';
8
9
 
9
10
  import QueryEditor from '../QueryEditor/QueryEditor';
10
11
  import Diagnostics from '../Diagnostics/Diagnostics';
11
12
 
12
- import {TenantGeneralTabsIds} from '../TenantPages';
13
-
14
13
  import './ObjectGeneral.scss';
15
14
 
16
15
  const b = cn('object-general');
@@ -35,7 +34,7 @@ function ObjectGeneral(props: ObjectGeneralProps) {
35
34
  const renderTabContent = () => {
36
35
  const {type, additionalTenantInfo, additionalNodesInfo} = props;
37
36
  switch (generalTab) {
38
- case TenantGeneralTabsIds.query: {
37
+ case TENANT_GENERAL_TABS_IDS.query: {
39
38
  return <QueryEditor path={tenantName as string} theme={theme} type={type} />;
40
39
  }
41
40
  default: {
@@ -35,7 +35,6 @@ import {
35
35
  DEFAULT_SIZE_TENANT_SUMMARY_KEY,
36
36
  } from '../../../utils/constants';
37
37
  import {
38
- TenantGeneralTabsIds,
39
38
  TenantInfoTabsIds,
40
39
  TenantTabsGroups,
41
40
  TENANT_INFO_TABS,
@@ -48,7 +47,8 @@ import {
48
47
  PaneVisibilityToggleButtons,
49
48
  } from '../utils/paneVisibilityToggleHelpers';
50
49
  import {setShowPreview} from '../../../store/reducers/schema';
51
- import {setTopLevelTab} from '../../../store/reducers/tenant';
50
+ import {setTopLevelTab} from '../../../store/reducers/tenant/tenant';
51
+ import {TENANT_GENERAL_TABS_IDS} from '../../../store/reducers/tenant/constants';
52
52
 
53
53
  import './ObjectSummary.scss';
54
54
 
@@ -275,7 +275,7 @@ function ObjectSummary(props: ObjectSummaryProps) {
275
275
 
276
276
  const onOpenPreview = () => {
277
277
  dispatch(setShowPreview(true));
278
- dispatch(setTopLevelTab(TenantGeneralTabsIds.query));
278
+ dispatch(setTopLevelTab(TENANT_GENERAL_TABS_IDS.query));
279
279
  };
280
280
 
281
281
  const renderCommonInfoControls = () => {
@@ -4,28 +4,27 @@ import cn from 'bem-cn-lite';
4
4
  import {useLocation} from 'react-router';
5
5
  import qs from 'qs';
6
6
 
7
- import {AccessDenied} from '../../components/Errors/403';
7
+ import type {TEvDescribeSchemeResult} from '../../types/api/schema';
8
8
 
9
+ import {DEFAULT_IS_TENANT_SUMMARY_COLLAPSED, DEFAULT_SIZE_TENANT_KEY} from '../../utils/constants';
10
+ import {useTypedSelector} from '../../utils/hooks';
11
+ import routes, {CLUSTER_PAGES, createHref} from '../../routes';
9
12
  import {setHeader} from '../../store/reducers/header';
13
+ import {disableAutorefresh, getSchema, resetLoadingState} from '../../store/reducers/schema';
14
+ import {getSchemaAcl} from '../../store/reducers/schemaAcl/schemaAcl';
15
+ import {getTenantInfo, clearTenant} from '../../store/reducers/tenant/tenant';
16
+
17
+ import SplitPane from '../../components/SplitPane';
18
+ import {AccessDenied} from '../../components/Errors/403';
19
+
10
20
  import ObjectGeneralTabs from './ObjectGeneralTabs/ObjectGeneralTabs';
11
21
  import ObjectSummary from './ObjectSummary/ObjectSummary';
12
22
  import ObjectGeneral from './ObjectGeneral/ObjectGeneral';
13
- //@ts-ignore
14
- import SplitPane from '../../components/SplitPane';
15
- //@ts-ignore
16
- import {DEFAULT_IS_TENANT_SUMMARY_COLLAPSED, DEFAULT_SIZE_TENANT_KEY} from '../../utils/constants';
17
- //@ts-ignore
18
- import {disableAutorefresh, getSchema, resetLoadingState} from '../../store/reducers/schema';
19
- //@ts-ignore
20
- import {getSchemaAcl} from '../../store/reducers/schemaAcl';
23
+
21
24
  import {
22
25
  PaneVisibilityActionTypes,
23
26
  paneVisibilityToggleReducerCreator,
24
27
  } from './utils/paneVisibilityToggleHelpers';
25
- //@ts-ignore
26
- import {getTenantInfo, clearTenant} from '../../store/reducers/tenant';
27
- import routes, {CLUSTER_PAGES, createHref} from '../../routes';
28
- import type {TEvDescribeSchemeResult} from '../../types/api/schema';
29
28
 
30
29
  import './Tenant.scss';
31
30
 
@@ -63,8 +62,8 @@ function Tenant(props: TenantProps) {
63
62
  const {PathType: currentPathType, PathSubType: currentPathSubType} =
64
63
  (currentItem as TEvDescribeSchemeResult).PathDescription?.Self || {};
65
64
 
66
- const {data: {status: tenantStatus = 200} = {}} = useSelector((state: any) => state.tenant);
67
- const {error: {status: schemaStatus = 200} = {}} = useSelector((state: any) => state.schema);
65
+ const {error: {status: tenantStatus = 200} = {}} = useTypedSelector((state) => state.tenant);
66
+ const {error: {status: schemaStatus = 200} = {}} = useTypedSelector((state) => state.schema);
68
67
 
69
68
  const dispatch = useDispatch();
70
69
 
@@ -1,9 +1,6 @@
1
1
  import {Icon} from '../../components/Icon';
2
+ import {TENANT_GENERAL_TABS_IDS} from '../../store/reducers/tenant/constants';
2
3
 
3
- export enum TenantGeneralTabsIds {
4
- query = 'query',
5
- diagnostics = 'diagnostics',
6
- }
7
4
  export enum TenantInfoTabsIds {
8
5
  overview = 'overview',
9
6
  acl = 'acl',
@@ -18,12 +15,12 @@ export enum TenantTabsGroups {
18
15
 
19
16
  export const TENANT_GENERAL_TABS = [
20
17
  {
21
- id: TenantGeneralTabsIds.query,
18
+ id: TENANT_GENERAL_TABS_IDS.query,
22
19
  title: 'Query',
23
20
  icon: <Icon name="query" viewBox="0 0 16 16" />,
24
21
  },
25
22
  {
26
- id: TenantGeneralTabsIds.diagnostics,
23
+ id: TENANT_GENERAL_TABS_IDS.diagnostics,
27
24
  title: 'Diagnostics',
28
25
  icon: <Icon name="diagnostics" viewBox="0 0 17 16" />,
29
26
  },
@@ -3,9 +3,9 @@ import type {NavigationTreeNodeType, NavigationTreeProps} from 'ydb-ui-component
3
3
 
4
4
  import {changeUserInput} from '../../../store/reducers/executeQuery';
5
5
  import {setShowPreview} from '../../../store/reducers/schema';
6
- import {setTopLevelTab} from '../../../store/reducers/tenant';
6
+ import {setTopLevelTab} from '../../../store/reducers/tenant/tenant';
7
+ import {TENANT_GENERAL_TABS_IDS} from '../../../store/reducers/tenant/constants';
7
8
  import createToast from '../../../utils/createToast';
8
- import {TenantGeneralTabsIds} from '../TenantPages';
9
9
 
10
10
  const createTableTemplate = (path: string) => {
11
11
  return `CREATE TABLE \`${path}/my_table\`
@@ -37,7 +37,7 @@ const bindActions = (
37
37
  ) => {
38
38
  const inputQuery = (tmpl: (path: string) => string) => () => {
39
39
  dispatch(changeUserInput({input: tmpl(path)}));
40
- dispatch(setTopLevelTab(TenantGeneralTabsIds.query));
40
+ dispatch(setTopLevelTab(TENANT_GENERAL_TABS_IDS.query));
41
41
  setActivePath(path);
42
42
  };
43
43
 
@@ -66,7 +66,7 @@ const bindActions = (
66
66
  },
67
67
  openPreview: () => {
68
68
  dispatch(setShowPreview(true));
69
- dispatch(setTopLevelTab(TenantGeneralTabsIds.query));
69
+ dispatch(setTopLevelTab(TENANT_GENERAL_TABS_IDS.query));
70
70
  setActivePath(path);
71
71
  },
72
72
  };
@@ -17,6 +17,7 @@
17
17
  z-index: 0;
18
18
 
19
19
  overflow-x: auto;
20
+ overflow-y: hidden;
20
21
 
21
22
  margin-right: $margin-size;
22
23
  margin-left: $margin-size;
@@ -2,6 +2,7 @@ import DataTable, {Column} from '@gravity-ui/react-data-table';
2
2
 
3
3
  import type {PreparedClusterNode} from '../../../store/reducers/clusterNodes/types';
4
4
  import {isUnavailableNode} from '../../../utils/nodes';
5
+ import {DEFAULT_TABLE_SETTINGS} from '../../../utils/constants';
5
6
  import {formatBytes} from '../../../utils';
6
7
  import {getDefaultNodePath} from '../../Node/NodePages';
7
8
 
@@ -112,9 +113,7 @@ export const NodesTable = ({nodes}: NodesTableProps) => {
112
113
  theme="yandex-cloud"
113
114
  data={nodes}
114
115
  columns={columns}
115
- settings={{
116
- displayIndices: false,
117
- }}
116
+ settings={DEFAULT_TABLE_SETTINGS}
118
117
  />
119
118
  );
120
119
  };
package/dist/routes.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import qs from 'qs';
2
2
  import {compile} from 'path-to-regexp';
3
3
  import isEmpty from 'lodash/isEmpty';
4
- //@ts-ignore
4
+
5
5
  import {backend, clusterName, webVersion} from './store';
6
6
 
7
7
  const routes = {
@@ -99,8 +99,8 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
99
99
  filter,
100
100
  nodeId,
101
101
  }: {
102
- tenant: string;
103
- filter: string;
102
+ tenant?: string;
103
+ filter?: string;
104
104
  nodeId: string;
105
105
  },
106
106
  {concurrentId}: AxiosOptions = {},
@@ -3,15 +3,15 @@ import {combineReducers} from 'redux';
3
3
  import nodes from './nodes';
4
4
  import cluster from './cluster/cluster';
5
5
  import clusterNodes from './clusterNodes/clusterNodes';
6
- import tenant from './tenant';
6
+ import tenant from './tenant/tenant';
7
7
  import storage from './storage';
8
- import node from './node';
8
+ import node from './node/node';
9
9
  import tooltip from './tooltip';
10
10
  import tablets from './tablets';
11
11
  import heatmap from './heatmap';
12
12
  import schema from './schema';
13
13
  import host from './host';
14
- import network from './network';
14
+ import network from './network/network';
15
15
  import tenants from './tenants/tenants';
16
16
  import tablet from './tablet';
17
17
  import topic from './topic';
@@ -23,7 +23,7 @@ import settings from './settings/settings';
23
23
  import preview from './preview';
24
24
  import nodesList from './nodesList';
25
25
  import describe from './describe';
26
- import schemaAcl from './schemaAcl';
26
+ import schemaAcl from './schemaAcl/schemaAcl';
27
27
  import executeTopQueries from './executeTopQueries';
28
28
  import healthcheckInfo from './healthcheckInfo';
29
29
  import shardsWorkload from './shardsWorkload';
@@ -1,20 +1,23 @@
1
- import {createRequestActionTypes, createApiRequest} from '../utils';
2
- import '../../services/api';
1
+ import {Reducer} from 'redux';
3
2
 
4
- const FETCH_ALL_NODES_NETWORK = createRequestActionTypes(
5
- 'ALL_NODES_NETWORK',
3
+ import '../../../services/api';
4
+ import {createRequestActionTypes, createApiRequest} from '../../utils';
5
+
6
+ import type {NetworkAction, NetworkState} from './types';
7
+
8
+ export const FETCH_ALL_NODES_NETWORK = createRequestActionTypes(
9
+ 'network',
6
10
  'FETCH_ALL_NODES_NETWORK',
7
11
  );
8
12
 
9
13
  const SET_DATA_WAS_NOT_LOADED = 'network/SET_DATA_WAS_NOT_LOADED';
10
14
 
11
15
  const initialState = {
12
- data: {},
13
16
  loading: false,
14
17
  wasLoaded: false,
15
18
  };
16
19
 
17
- const network = (state = initialState, action) => {
20
+ const network: Reducer<NetworkState, NetworkAction> = (state = initialState, action) => {
18
21
  switch (action.type) {
19
22
  case FETCH_ALL_NODES_NETWORK.REQUEST: {
20
23
  return {
@@ -53,10 +56,10 @@ const network = (state = initialState, action) => {
53
56
  export const setDataWasNotLoaded = () => {
54
57
  return {
55
58
  type: SET_DATA_WAS_NOT_LOADED,
56
- };
59
+ } as const;
57
60
  };
58
61
 
59
- export const getNetworkInfo = (tenant) => {
62
+ export const getNetworkInfo = (tenant: string) => {
60
63
  return createApiRequest({
61
64
  request: window.api.getNetwork(tenant),
62
65
  actions: FETCH_ALL_NODES_NETWORK,
@@ -0,0 +1,16 @@
1
+ import type {IResponseError} from '../../../types/api/error';
2
+ import type {TNetInfo} from '../../../types/api/netInfo';
3
+ import type {ApiRequestAction} from '../../utils';
4
+
5
+ import {FETCH_ALL_NODES_NETWORK, setDataWasNotLoaded} from './network';
6
+
7
+ export interface NetworkState {
8
+ loading: boolean;
9
+ wasLoaded: boolean;
10
+ data?: TNetInfo;
11
+ error?: IResponseError;
12
+ }
13
+
14
+ export type NetworkAction =
15
+ | ApiRequestAction<typeof FETCH_ALL_NODES_NETWORK, TNetInfo, IResponseError>
16
+ | ReturnType<typeof setDataWasNotLoaded>;
@@ -0,0 +1,102 @@
1
+ import {Reducer} from 'redux';
2
+
3
+ import '../../../services/api';
4
+ import {createRequestActionTypes, createApiRequest} from '../../utils';
5
+
6
+ import type {NodeAction, NodeState} from './types';
7
+
8
+ export const FETCH_NODE = createRequestActionTypes('node', 'FETCH_NODE');
9
+ export const FETCH_NODE_STRUCTURE = createRequestActionTypes('node', 'FETCH_NODE_STRUCTURE');
10
+
11
+ const RESET_NODE = 'node/RESET_NODE';
12
+
13
+ const initialState = {
14
+ data: {},
15
+ loading: true,
16
+ wasLoaded: false,
17
+ nodeStructure: {},
18
+ loadingStructure: true,
19
+ wasLoadedStructure: false,
20
+ };
21
+
22
+ const node: Reducer<NodeState, NodeAction> = (state = initialState, action) => {
23
+ switch (action.type) {
24
+ case FETCH_NODE.REQUEST: {
25
+ return {
26
+ ...state,
27
+ loading: true,
28
+ };
29
+ }
30
+ case FETCH_NODE.SUCCESS: {
31
+ return {
32
+ ...state,
33
+ data: action.data,
34
+ loading: false,
35
+ wasLoaded: true,
36
+ error: undefined,
37
+ };
38
+ }
39
+ case FETCH_NODE.FAILURE: {
40
+ return {
41
+ ...state,
42
+ error: action.error,
43
+ loading: false,
44
+ };
45
+ }
46
+ case FETCH_NODE_STRUCTURE.REQUEST: {
47
+ return {
48
+ ...state,
49
+ loadingStructure: true,
50
+ };
51
+ }
52
+ case FETCH_NODE_STRUCTURE.SUCCESS: {
53
+ return {
54
+ ...state,
55
+ nodeStructure: action.data,
56
+ loadingStructure: false,
57
+ wasLoadedStructure: true,
58
+ errorStructure: undefined,
59
+ };
60
+ }
61
+ case FETCH_NODE_STRUCTURE.FAILURE: {
62
+ return {
63
+ ...state,
64
+ errorStructure: action.error,
65
+ loadingStructure: false,
66
+ };
67
+ }
68
+ case RESET_NODE: {
69
+ return {
70
+ ...state,
71
+ data: {},
72
+ wasLoaded: false,
73
+ nodeStructure: {},
74
+ wasLoadedStructure: false,
75
+ };
76
+ }
77
+ default:
78
+ return state;
79
+ }
80
+ };
81
+
82
+ export const getNodeInfo = (id: string) => {
83
+ return createApiRequest({
84
+ request: window.api.getNodeInfo(id),
85
+ actions: FETCH_NODE,
86
+ });
87
+ };
88
+
89
+ export const getNodeStructure = (nodeId: string) => {
90
+ return createApiRequest({
91
+ request: window.api.getStorageInfo({nodeId}, {concurrentId: 'getNodeStructure'}),
92
+ actions: FETCH_NODE_STRUCTURE,
93
+ });
94
+ };
95
+
96
+ export function resetNode() {
97
+ return {
98
+ type: RESET_NODE,
99
+ } as const;
100
+ }
101
+
102
+ export default node;
@@ -0,0 +1,59 @@
1
+ import type {Selector} from 'reselect';
2
+ import {createSelector} from 'reselect';
3
+
4
+ import {stringifyVdiskId} from '../../../utils';
5
+
6
+ import type {
7
+ NodeStateSlice,
8
+ PreparedNodeStructure,
9
+ PreparedStructureVDisk,
10
+ RawNodeStructure,
11
+ } from './types';
12
+
13
+ const selectNodeId = (state: NodeStateSlice) => state.node?.data?.SystemStateInfo?.[0].NodeId;
14
+
15
+ const selectRawNodeStructure = (state: NodeStateSlice) => state.node?.nodeStructure;
16
+
17
+ export const selectNodeStructure: Selector<NodeStateSlice, PreparedNodeStructure> = createSelector(
18
+ [selectNodeId, selectRawNodeStructure],
19
+ (nodeId, storageInfo) => {
20
+ const pools = storageInfo?.StoragePools;
21
+ const structure: RawNodeStructure = {};
22
+
23
+ pools?.forEach((pool) => {
24
+ const groups = pool.Groups;
25
+ groups?.forEach((group) => {
26
+ const vDisks = group.VDisks?.filter((el) => el.NodeId === nodeId);
27
+ vDisks?.forEach((vd) => {
28
+ const vDiskId = stringifyVdiskId(vd.VDiskId);
29
+ const pDiskId = vd.PDisk?.PDiskId;
30
+ if (!structure[String(pDiskId)]) {
31
+ structure[String(pDiskId)] = {vDisks: {}, ...vd.PDisk};
32
+ }
33
+ structure[String(pDiskId)].vDisks[vDiskId] = {
34
+ ...vd,
35
+ // VDisk doesn't have its own StoragePoolName when located inside StoragePool data
36
+ StoragePoolName: pool.Name,
37
+ };
38
+ });
39
+ });
40
+ });
41
+
42
+ const structureWithVdisksArray = Object.keys(structure).reduce<PreparedNodeStructure>(
43
+ (preparedStructure, el) => {
44
+ const vDisks = structure[el].vDisks;
45
+ const vDisksArray = Object.keys(vDisks).reduce<PreparedStructureVDisk[]>(
46
+ (acc, key, index) => {
47
+ acc.push({...vDisks[key], id: key, order: index});
48
+ return acc;
49
+ },
50
+ [],
51
+ );
52
+ preparedStructure[el] = {...structure[el], vDisks: vDisksArray};
53
+ return preparedStructure;
54
+ },
55
+ {},
56
+ );
57
+ return structureWithVdisksArray;
58
+ },
59
+ );
@@ -0,0 +1,44 @@
1
+ import type {IResponseError} from '../../../types/api/error';
2
+ import type {TPDiskStateInfo} from '../../../types/api/pdisk';
3
+ import type {TStorageInfo} from '../../../types/api/storage';
4
+ import type {TEvSystemStateResponse} from '../../../types/api/systemState';
5
+ import type {TVDiskStateInfo} from '../../../types/api/vdisk';
6
+ import type {ApiRequestAction} from '../../utils';
7
+
8
+ import {FETCH_NODE, FETCH_NODE_STRUCTURE, resetNode} from './node';
9
+
10
+ interface RawStructurePDisk extends TPDiskStateInfo {
11
+ vDisks: Record<string, TVDiskStateInfo>;
12
+ }
13
+
14
+ export type RawNodeStructure = Record<string, RawStructurePDisk>;
15
+
16
+ export interface PreparedStructureVDisk extends TVDiskStateInfo {
17
+ id: string;
18
+ order: number;
19
+ }
20
+
21
+ export interface PreparedStructurePDisk extends TPDiskStateInfo {
22
+ vDisks: PreparedStructureVDisk[];
23
+ }
24
+
25
+ export type PreparedNodeStructure = Record<string, PreparedStructurePDisk>;
26
+
27
+ export interface NodeState {
28
+ data: TEvSystemStateResponse;
29
+ loading: boolean;
30
+ wasLoaded: boolean;
31
+
32
+ nodeStructure: TStorageInfo;
33
+ loadingStructure: boolean;
34
+ wasLoadedStructure: boolean;
35
+ }
36
+
37
+ export type NodeAction =
38
+ | ApiRequestAction<typeof FETCH_NODE, TEvSystemStateResponse, IResponseError>
39
+ | ApiRequestAction<typeof FETCH_NODE_STRUCTURE, TStorageInfo, IResponseError>
40
+ | ReturnType<typeof resetNode>;
41
+
42
+ export interface NodeStateSlice {
43
+ node: NodeState;
44
+ }
@@ -1,10 +1,18 @@
1
- import {createRequestActionTypes, createApiRequest} from '../utils';
2
- import '../../services/api';
3
- import _ from 'lodash';
1
+ import type {Reducer} from 'redux';
4
2
 
5
- const FETCH_SCHEMA_ACL = createRequestActionTypes('schemaAcl', 'FETCH_SCHEMA_ACL');
3
+ import '../../../services/api';
4
+ import {createRequestActionTypes, createApiRequest} from '../../utils';
6
5
 
7
- const schemaAcl = function z(state = {loading: false, wasLoaded: false, acl: undefined}, action) {
6
+ import type {SchemaAclAction, SchemaAclState} from './types';
7
+
8
+ export const FETCH_SCHEMA_ACL = createRequestActionTypes('schemaAcl', 'FETCH_SCHEMA_ACL');
9
+
10
+ const initialState = {
11
+ loading: false,
12
+ wasLoaded: false,
13
+ };
14
+
15
+ const schemaAcl: Reducer<SchemaAclState, SchemaAclAction> = (state = initialState, action) => {
8
16
  switch (action.type) {
9
17
  case FETCH_SCHEMA_ACL.REQUEST: {
10
18
  return {
@@ -13,13 +21,16 @@ const schemaAcl = function z(state = {loading: false, wasLoaded: false, acl: und
13
21
  };
14
22
  }
15
23
  case FETCH_SCHEMA_ACL.SUCCESS: {
24
+ const acl = action.data.Common?.ACL;
25
+ const owner = action.data.Common?.Owner;
26
+
16
27
  return {
17
28
  ...state,
18
- error: undefined,
19
- acl: _.get(action.data, 'Common.ACL'),
20
- owner: _.get(action.data, 'Common.Owner'),
29
+ acl,
30
+ owner,
21
31
  loading: false,
22
32
  wasLoaded: true,
33
+ error: undefined,
23
34
  };
24
35
  }
25
36
  case FETCH_SCHEMA_ACL.FAILURE: {
@@ -34,7 +45,7 @@ const schemaAcl = function z(state = {loading: false, wasLoaded: false, acl: und
34
45
  }
35
46
  };
36
47
 
37
- export function getSchemaAcl({path}) {
48
+ export function getSchemaAcl({path}: {path: string}) {
38
49
  return createApiRequest({
39
50
  request: window.api.getSchemaAcl({path}),
40
51
  actions: FETCH_SCHEMA_ACL,
@@ -0,0 +1,15 @@
1
+ import type {TACE, TMetaInfo} from '../../../types/api/acl';
2
+ import type {IResponseError} from '../../../types/api/error';
3
+ import type {ApiRequestAction} from '../../utils';
4
+
5
+ import {FETCH_SCHEMA_ACL} from './schemaAcl';
6
+
7
+ export interface SchemaAclState {
8
+ loading: boolean
9
+ wasLoaded: boolean
10
+ acl?: TACE[]
11
+ owner?: string
12
+ error?: IResponseError
13
+ }
14
+
15
+ export type SchemaAclAction = ApiRequestAction<typeof FETCH_SCHEMA_ACL, TMetaInfo, IResponseError>;
@@ -0,0 +1,19 @@
1
+ export const TENANT_GENERAL_TABS_IDS = {
2
+ query: 'query',
3
+ diagnostics: 'diagnostics',
4
+ } as const;
5
+
6
+ export const TENANT_DIAGNOSTICS_TABS_IDS = {
7
+ overview: 'overview',
8
+ topQueries: 'topQueries',
9
+ topShards: 'topShards',
10
+ nodes: 'nodes',
11
+ tablets: 'tablets',
12
+ storage: 'storage',
13
+ network: 'network',
14
+ describe: 'describe',
15
+ hotKeys: 'hotKeys',
16
+ graph: 'graph',
17
+ consumers: 'consumers',
18
+ partitions: 'partitions',
19
+ } as const;