ydb-embedded-ui 4.5.0 → 4.5.2

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 (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;