ydb-embedded-ui 4.27.1 → 4.29.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.
- package/CHANGELOG.md +14 -0
- package/dist/assets/illustrations/dark/error.svg +32 -0
- package/dist/assets/illustrations/light/error.svg +32 -0
- package/dist/components/EmptyState/EmptyState.scss +5 -2
- package/dist/components/EmptyState/EmptyState.tsx +11 -3
- package/dist/components/ErrorBoundary/ErrorBoundary.scss +40 -0
- package/dist/components/ErrorBoundary/ErrorBoundary.tsx +62 -0
- package/dist/components/ErrorBoundary/i18n/en.json +7 -0
- package/dist/components/ErrorBoundary/i18n/index.ts +11 -0
- package/dist/components/ErrorBoundary/i18n/ru.json +7 -0
- package/dist/components/Errors/403/AccessDenied.tsx +4 -3
- package/dist/components/Illustration/Illustration.tsx +3 -1
- package/dist/components/ProblemFilter/ProblemFilter.tsx +1 -1
- package/dist/components/UptimeFIlter/UptimeFilter.tsx +1 -1
- package/dist/components/VirtualTable/VirtualTable.scss +1 -1
- package/dist/containers/App/App.js +5 -2
- package/dist/containers/Cluster/Cluster.tsx +11 -12
- package/dist/containers/Nodes/Nodes.tsx +4 -4
- package/dist/containers/Nodes/NodesWrapper.tsx +21 -0
- package/dist/containers/Nodes/VirtualNodes.tsx +4 -14
- package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.scss +1 -0
- package/dist/containers/Storage/EmptyFilter/EmptyFilter.tsx +1 -0
- package/dist/containers/Storage/PDisk/PDisk.tsx +5 -7
- package/dist/containers/Storage/Storage.tsx +30 -67
- package/dist/containers/Storage/StorageControls/StorageControls.tsx +104 -0
- package/dist/containers/Storage/StorageGroups/StorageGroups.tsx +18 -62
- package/dist/containers/Storage/StorageGroups/StorageGroupsEmptyDataMessage.tsx +30 -0
- package/dist/containers/Storage/StorageGroups/VirtualStorageGroups.tsx +94 -0
- package/dist/containers/Storage/StorageGroups/getGroups.ts +21 -0
- package/dist/containers/Storage/StorageGroups/getStorageGroupsColumns.tsx +73 -50
- package/dist/containers/Storage/StorageNodes/StorageNodes.tsx +23 -138
- package/dist/containers/Storage/StorageNodes/StorageNodesEmptyDataMessage.tsx +44 -0
- package/dist/containers/Storage/StorageNodes/VirtualStorageNodes.tsx +105 -0
- package/dist/containers/Storage/StorageNodes/getNodes.ts +26 -0
- package/dist/containers/Storage/StorageNodes/getStorageNodesColumns.tsx +125 -0
- package/dist/containers/Storage/StorageNodes/shared.ts +9 -0
- package/dist/containers/Storage/StorageTypeFilter/StorageTypeFilter.tsx +1 -1
- package/dist/containers/Storage/StorageVisibleEntitiesFilter/StorageVisibleEntitiesFilter.tsx +1 -1
- package/dist/containers/Storage/StorageWrapper.tsx +23 -0
- package/dist/containers/Storage/UsageFilter/UsageFilter.tsx +3 -4
- package/dist/containers/Storage/VirtualStorage.tsx +112 -0
- package/dist/containers/Storage/i18n/en.json +7 -0
- package/dist/containers/Storage/i18n/index.ts +11 -0
- package/dist/containers/Storage/i18n/ru.json +7 -0
- package/dist/containers/Storage/shared.ts +3 -0
- package/dist/containers/Tenants/Tenants.tsx +2 -2
- package/dist/containers/UserSettings/i18n/en.json +2 -2
- package/dist/containers/UserSettings/i18n/ru.json +2 -2
- package/dist/containers/UserSettings/settings.ts +4 -4
- package/dist/index.tsx +8 -5
- package/dist/store/reducers/storage/selectors.ts +0 -20
- package/dist/utils/registerError.ts +18 -0
- package/package.json +7 -6
@@ -0,0 +1,125 @@
|
|
1
|
+
import DataTable, {type Column as DataTableColumn} from '@gravity-ui/react-data-table';
|
2
|
+
|
3
|
+
import type {PreparedStorageNode, VisibleEntities} from '../../../store/reducers/storage/types';
|
4
|
+
import type {AdditionalNodesProps} from '../../../types/additionalProps';
|
5
|
+
import type {Column as VirtualTableColumn} from '../../../components/VirtualTable';
|
6
|
+
import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
|
7
|
+
import {NodeHostWrapper} from '../../../components/NodeHostWrapper/NodeHostWrapper';
|
8
|
+
import {isSortableNodesProperty} from '../../../utils/nodes';
|
9
|
+
|
10
|
+
import {PDisk} from '../PDisk/PDisk';
|
11
|
+
import {b} from './shared';
|
12
|
+
|
13
|
+
export const STORAGE_NODES_COLUMNS_IDS = {
|
14
|
+
NodeId: 'NodeId',
|
15
|
+
Host: 'Host',
|
16
|
+
DC: 'DC',
|
17
|
+
Rack: 'Rack',
|
18
|
+
Uptime: 'Uptime',
|
19
|
+
PDisks: 'PDisks',
|
20
|
+
Missing: 'Missing',
|
21
|
+
} as const;
|
22
|
+
|
23
|
+
type StorageGroupsColumn = VirtualTableColumn<PreparedStorageNode> &
|
24
|
+
DataTableColumn<PreparedStorageNode>;
|
25
|
+
|
26
|
+
const getStorageNodesColumns = (additionalNodesProps: AdditionalNodesProps | undefined) => {
|
27
|
+
const getNodeRef = additionalNodesProps?.getNodeRef;
|
28
|
+
|
29
|
+
const columns: StorageGroupsColumn[] = [
|
30
|
+
{
|
31
|
+
name: STORAGE_NODES_COLUMNS_IDS.NodeId,
|
32
|
+
header: 'Node ID',
|
33
|
+
width: 100,
|
34
|
+
align: DataTable.RIGHT,
|
35
|
+
render: ({row}) => row.NodeId,
|
36
|
+
},
|
37
|
+
{
|
38
|
+
name: STORAGE_NODES_COLUMNS_IDS.Host,
|
39
|
+
header: 'Host',
|
40
|
+
width: 350,
|
41
|
+
render: ({row}) => {
|
42
|
+
return <NodeHostWrapper node={row} getNodeRef={getNodeRef} />;
|
43
|
+
},
|
44
|
+
align: DataTable.LEFT,
|
45
|
+
},
|
46
|
+
{
|
47
|
+
name: STORAGE_NODES_COLUMNS_IDS.DC,
|
48
|
+
header: 'DC',
|
49
|
+
width: 100,
|
50
|
+
render: ({row}) => row.DataCenter || '—',
|
51
|
+
align: DataTable.LEFT,
|
52
|
+
},
|
53
|
+
{
|
54
|
+
name: STORAGE_NODES_COLUMNS_IDS.Rack,
|
55
|
+
header: 'Rack',
|
56
|
+
width: 100,
|
57
|
+
render: ({row}) => row.Rack || '—',
|
58
|
+
align: DataTable.LEFT,
|
59
|
+
},
|
60
|
+
{
|
61
|
+
name: STORAGE_NODES_COLUMNS_IDS.Uptime,
|
62
|
+
header: 'Uptime',
|
63
|
+
width: 130,
|
64
|
+
sortAccessor: ({StartTime}) => (StartTime ? -StartTime : 0),
|
65
|
+
align: DataTable.RIGHT,
|
66
|
+
render: ({row}) => row.Uptime,
|
67
|
+
},
|
68
|
+
{
|
69
|
+
name: STORAGE_NODES_COLUMNS_IDS.Missing,
|
70
|
+
header: 'Missing',
|
71
|
+
width: 100,
|
72
|
+
align: DataTable.CENTER,
|
73
|
+
defaultOrder: DataTable.DESCENDING,
|
74
|
+
render: ({row}) => row.Missing,
|
75
|
+
},
|
76
|
+
{
|
77
|
+
name: STORAGE_NODES_COLUMNS_IDS.PDisks,
|
78
|
+
className: b('pdisks-column'),
|
79
|
+
header: 'PDisks',
|
80
|
+
render: ({row}) => {
|
81
|
+
return (
|
82
|
+
<div className={b('pdisks-wrapper')}>
|
83
|
+
{row.PDisks?.map((pDisk) => {
|
84
|
+
const vDisks = row.VDisks?.filter(
|
85
|
+
(vdisk) => vdisk.PDiskId === pDisk.PDiskId,
|
86
|
+
).map((data) => ({
|
87
|
+
...data,
|
88
|
+
NodeId: row.NodeId,
|
89
|
+
}));
|
90
|
+
|
91
|
+
return (
|
92
|
+
<div className={b('pdisks-item')} key={pDisk.PDiskId}>
|
93
|
+
<PDisk data={pDisk} nodeId={row.NodeId} vDisks={vDisks} />
|
94
|
+
</div>
|
95
|
+
);
|
96
|
+
})}
|
97
|
+
</div>
|
98
|
+
);
|
99
|
+
},
|
100
|
+
align: DataTable.CENTER,
|
101
|
+
sortable: false,
|
102
|
+
width: 900,
|
103
|
+
},
|
104
|
+
];
|
105
|
+
|
106
|
+
return columns;
|
107
|
+
};
|
108
|
+
|
109
|
+
export const getPreparedStorageNodesColumns = (
|
110
|
+
additionalNodesProps: AdditionalNodesProps | undefined,
|
111
|
+
visibleEntities: VisibleEntities,
|
112
|
+
) => {
|
113
|
+
const rawColumns = getStorageNodesColumns(additionalNodesProps);
|
114
|
+
|
115
|
+
const sortableColumns = rawColumns.map((column) => ({
|
116
|
+
...column,
|
117
|
+
sortable: isSortableNodesProperty(column.name),
|
118
|
+
}));
|
119
|
+
|
120
|
+
if (visibleEntities !== VISIBLE_ENTITIES.missing) {
|
121
|
+
return sortableColumns.filter((col) => col.name !== STORAGE_NODES_COLUMNS_IDS.Missing);
|
122
|
+
}
|
123
|
+
|
124
|
+
return sortableColumns;
|
125
|
+
};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import cn from 'bem-cn-lite';
|
2
|
+
|
3
|
+
import type {PreparedStorageNode} from '../../../store/reducers/storage/types';
|
4
|
+
import {isUnavailableNode} from '../../../utils/nodes';
|
5
|
+
|
6
|
+
export const b = cn('global-storage-nodes');
|
7
|
+
|
8
|
+
export const getRowUnavailableClassName = (row: PreparedStorageNode) =>
|
9
|
+
b('node', {unavailable: isUnavailableNode(row)});
|
package/dist/containers/Storage/StorageVisibleEntitiesFilter/StorageVisibleEntitiesFilter.tsx
CHANGED
@@ -11,7 +11,7 @@ export const VisibleEntitiesTitles = {
|
|
11
11
|
|
12
12
|
interface StorageProblemFilterProps {
|
13
13
|
value: VisibleEntities;
|
14
|
-
onChange: (value:
|
14
|
+
onChange: (value: VisibleEntities) => void;
|
15
15
|
}
|
16
16
|
|
17
17
|
const storageVisibleEntitiesFilterQa = 'storage-visible-entities-filter';
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import type {AdditionalNodesProps} from '../../types/additionalProps';
|
2
|
+
import {USE_BACKEND_PARAMS_FOR_TABLES_KEY} from '../../utils/constants';
|
3
|
+
import {useSetting} from '../../utils/hooks';
|
4
|
+
|
5
|
+
import {VirtualStorage} from './VirtualStorage';
|
6
|
+
import {Storage} from './Storage';
|
7
|
+
|
8
|
+
interface StorageWrapperProps {
|
9
|
+
tenant?: string;
|
10
|
+
nodeId?: string;
|
11
|
+
parentContainer?: Element | null;
|
12
|
+
additionalNodesProps?: AdditionalNodesProps;
|
13
|
+
}
|
14
|
+
|
15
|
+
export const StorageWrapper = ({parentContainer, ...props}: StorageWrapperProps) => {
|
16
|
+
const [useVirtualTable] = useSetting<boolean>(USE_BACKEND_PARAMS_FOR_TABLES_KEY);
|
17
|
+
|
18
|
+
if (useVirtualTable) {
|
19
|
+
return <VirtualStorage parentContainer={parentContainer} {...props} />;
|
20
|
+
}
|
21
|
+
|
22
|
+
return <Storage {...props} />;
|
23
|
+
};
|
@@ -10,7 +10,7 @@ import {getUsageSeverityForEntityStatus} from '../utils';
|
|
10
10
|
import i18n from './i18n';
|
11
11
|
import './UsageFilter.scss';
|
12
12
|
|
13
|
-
interface UsageFilterItem {
|
13
|
+
export interface UsageFilterItem {
|
14
14
|
threshold: number;
|
15
15
|
count: number;
|
16
16
|
}
|
@@ -21,13 +21,12 @@ interface UsageFilterProps {
|
|
21
21
|
groups?: UsageFilterItem[];
|
22
22
|
onChange?: (value: string[]) => void;
|
23
23
|
debounce?: number;
|
24
|
-
disabled?: boolean;
|
25
24
|
}
|
26
25
|
|
27
26
|
const b = cn('usage-filter');
|
28
27
|
|
29
28
|
export const UsageFilter = (props: UsageFilterProps) => {
|
30
|
-
const {className, value = [], groups = [], onChange, debounce = 200
|
29
|
+
const {className, value = [], groups = [], onChange, debounce = 200} = props;
|
31
30
|
|
32
31
|
const [filterValue, setFilterValue] = useState(value);
|
33
32
|
const timer = useRef<number>();
|
@@ -94,7 +93,7 @@ export const UsageFilter = (props: UsageFilterProps) => {
|
|
94
93
|
renderOption={renderOption}
|
95
94
|
getOptionHeight={() => 50}
|
96
95
|
popupWidth={280}
|
97
|
-
disabled={
|
96
|
+
disabled={groups.length === 0}
|
98
97
|
/>
|
99
98
|
);
|
100
99
|
};
|
@@ -0,0 +1,112 @@
|
|
1
|
+
import {useEffect, useState} from 'react';
|
2
|
+
import {useDispatch} from 'react-redux';
|
3
|
+
|
4
|
+
import type {AdditionalNodesProps} from '../../types/additionalProps';
|
5
|
+
import type {RenderControls, RenderErrorMessage} from '../../components/VirtualTable';
|
6
|
+
import type {StorageType, VisibleEntities} from '../../store/reducers/storage/types';
|
7
|
+
import {STORAGE_TYPES, VISIBLE_ENTITIES} from '../../store/reducers/storage/constants';
|
8
|
+
import {NodesUptimeFilterValues} from '../../utils/nodes';
|
9
|
+
import {AccessDenied} from '../../components/Errors/403/AccessDenied';
|
10
|
+
import {ResponseError} from '../../components/Errors/ResponseError/ResponseError';
|
11
|
+
import {getNodesList, selectNodesMap} from '../../store/reducers/nodesList';
|
12
|
+
import {useTypedSelector} from '../../utils/hooks';
|
13
|
+
|
14
|
+
import {StorageControls} from './StorageControls/StorageControls';
|
15
|
+
import {VirtualStorageGroups} from './StorageGroups/VirtualStorageGroups';
|
16
|
+
import {VirtualStorageNodes} from './StorageNodes/VirtualStorageNodes';
|
17
|
+
|
18
|
+
interface VirtualStorageProps {
|
19
|
+
tenant?: string;
|
20
|
+
nodeId?: string;
|
21
|
+
parentContainer?: Element | null;
|
22
|
+
additionalNodesProps?: AdditionalNodesProps;
|
23
|
+
}
|
24
|
+
|
25
|
+
export const VirtualStorage = ({
|
26
|
+
tenant,
|
27
|
+
nodeId,
|
28
|
+
parentContainer,
|
29
|
+
additionalNodesProps,
|
30
|
+
}: VirtualStorageProps) => {
|
31
|
+
const dispatch = useDispatch();
|
32
|
+
|
33
|
+
const [searchValue, setSearchValue] = useState('');
|
34
|
+
const [storageType, setStorageType] = useState<StorageType>(STORAGE_TYPES.groups);
|
35
|
+
const [visibleEntities, setVisibleEntities] = useState<VisibleEntities>(VISIBLE_ENTITIES.all);
|
36
|
+
const [nodesUptimeFilter, setNodesUptimeFilter] = useState<NodesUptimeFilterValues>(
|
37
|
+
NodesUptimeFilterValues.All,
|
38
|
+
);
|
39
|
+
|
40
|
+
const nodesMap = useTypedSelector(selectNodesMap);
|
41
|
+
|
42
|
+
useEffect(() => {
|
43
|
+
dispatch(getNodesList());
|
44
|
+
}, [dispatch]);
|
45
|
+
|
46
|
+
const handleShowAllGroups = () => {
|
47
|
+
setVisibleEntities(VISIBLE_ENTITIES.all);
|
48
|
+
};
|
49
|
+
|
50
|
+
const handleShowAllNodes = () => {
|
51
|
+
setVisibleEntities(VISIBLE_ENTITIES.all);
|
52
|
+
setNodesUptimeFilter(NodesUptimeFilterValues.All);
|
53
|
+
};
|
54
|
+
|
55
|
+
const renderControls: RenderControls = ({totalEntities, foundEntities, inited}) => {
|
56
|
+
return (
|
57
|
+
<StorageControls
|
58
|
+
searchValue={searchValue}
|
59
|
+
handleSearchValueChange={setSearchValue}
|
60
|
+
withTypeSelector={!nodeId}
|
61
|
+
storageType={storageType}
|
62
|
+
handleStorageTypeChange={setStorageType}
|
63
|
+
visibleEntities={visibleEntities}
|
64
|
+
handleVisibleEntitiesChange={setVisibleEntities}
|
65
|
+
nodesUptimeFilter={nodesUptimeFilter}
|
66
|
+
handleNodesUptimeFilterChange={setNodesUptimeFilter}
|
67
|
+
withGroupsUsageFilter={false}
|
68
|
+
entitiesCountCurrent={foundEntities}
|
69
|
+
entitiesCountTotal={totalEntities}
|
70
|
+
entitiesLoading={!inited}
|
71
|
+
/>
|
72
|
+
);
|
73
|
+
};
|
74
|
+
|
75
|
+
const renderErrorMessage: RenderErrorMessage = (error) => {
|
76
|
+
if (error.status === 403) {
|
77
|
+
return <AccessDenied position="left" />;
|
78
|
+
}
|
79
|
+
|
80
|
+
return <ResponseError error={error} />;
|
81
|
+
};
|
82
|
+
|
83
|
+
if (storageType === STORAGE_TYPES.nodes) {
|
84
|
+
return (
|
85
|
+
<VirtualStorageNodes
|
86
|
+
searchValue={searchValue}
|
87
|
+
visibleEntities={visibleEntities}
|
88
|
+
nodesUptimeFilter={nodesUptimeFilter}
|
89
|
+
tenant={tenant}
|
90
|
+
additionalNodesProps={additionalNodesProps}
|
91
|
+
onShowAll={handleShowAllNodes}
|
92
|
+
parentContainer={parentContainer}
|
93
|
+
renderControls={renderControls}
|
94
|
+
renderErrorMessage={renderErrorMessage}
|
95
|
+
/>
|
96
|
+
);
|
97
|
+
}
|
98
|
+
|
99
|
+
return (
|
100
|
+
<VirtualStorageGroups
|
101
|
+
searchValue={searchValue}
|
102
|
+
visibleEntities={visibleEntities}
|
103
|
+
tenant={tenant}
|
104
|
+
nodeId={nodeId}
|
105
|
+
nodesMap={nodesMap}
|
106
|
+
onShowAll={handleShowAllGroups}
|
107
|
+
parentContainer={parentContainer}
|
108
|
+
renderControls={renderControls}
|
109
|
+
renderErrorMessage={renderErrorMessage}
|
110
|
+
/>
|
111
|
+
);
|
112
|
+
};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import {i18n, Lang} from '../../../utils/i18n';
|
2
|
+
|
3
|
+
import en from './en.json';
|
4
|
+
import ru from './ru.json';
|
5
|
+
|
6
|
+
const COMPONENT = 'ydb-storage';
|
7
|
+
|
8
|
+
i18n.registerKeyset(Lang.En, COMPONENT, en);
|
9
|
+
i18n.registerKeyset(Lang.Ru, COMPONENT, ru);
|
10
|
+
|
11
|
+
export default i18n.keyset(COMPONENT);
|
@@ -61,8 +61,8 @@ export const Tenants = ({additionalTenantsProps}: TenantsProps) => {
|
|
61
61
|
true,
|
62
62
|
);
|
63
63
|
|
64
|
-
const handleProblemFilterChange = (value:
|
65
|
-
dispatch(changeFilter(value
|
64
|
+
const handleProblemFilterChange = (value: ProblemFilterValue) => {
|
65
|
+
dispatch(changeFilter(value));
|
66
66
|
};
|
67
67
|
|
68
68
|
const handleSearchChange = (value: string) => {
|
@@ -19,8 +19,8 @@
|
|
19
19
|
"settings.useNodesEndpoint.title": "Break the Nodes tab in Diagnostics",
|
20
20
|
"settings.useNodesEndpoint.popover": "Use /viewer/json/nodes endpoint for Nodes Tab in diagnostics. It could return incorrect data on some versions",
|
21
21
|
|
22
|
-
"settings.
|
23
|
-
"settings.
|
22
|
+
"settings.useVirtualTables.title": "Use table with data load on scroll for Nodes and Storage cluster tabs",
|
23
|
+
"settings.useVirtualTables.popover": "It will increase performance, but could work unstable",
|
24
24
|
|
25
25
|
"settings.queryUseMultiSchema.title": "Allow queries with multiple result sets",
|
26
26
|
"settings.queryUseMultiSchema.popover": "Use 'multi' schema for queries that enables queries with multiple result sets. Returns nothing on versions 23-3 and older"
|
@@ -19,8 +19,8 @@
|
|
19
19
|
"settings.useNodesEndpoint.title": "Сломать вкладку Nodes в диагностике",
|
20
20
|
"settings.useNodesEndpoint.popover": "Использовать эндпоинт /viewer/json/nodes для вкладки Nodes в диагностике. Может возвращать некорректные данные на некоторых версиях",
|
21
21
|
|
22
|
-
"settings.
|
23
|
-
"settings.
|
22
|
+
"settings.useVirtualTables.title": "Использовать таблицу с загрузкой данных по скроллу для вкладок Nodes и Storage кластера",
|
23
|
+
"settings.useVirtualTables.popover": "Это улучшит производительность, но может работать нестабильно",
|
24
24
|
|
25
25
|
"settings.queryUseMultiSchema.title": "Разрешить запросы с несколькими результатами",
|
26
26
|
"settings.queryUseMultiSchema.popover": "Использовать для запросов схему 'multi', которая позволяет выполнять запросы с несколькими результатами. На версиях 23-3 и старше результат не возвращается вообще"
|
@@ -84,10 +84,10 @@ export const useNodesEndpointSetting: SettingProps = {
|
|
84
84
|
title: i18n('settings.useNodesEndpoint.title'),
|
85
85
|
helpPopoverContent: i18n('settings.useNodesEndpoint.popover'),
|
86
86
|
};
|
87
|
-
export const
|
87
|
+
export const useVirtualTables: SettingProps = {
|
88
88
|
settingKey: USE_BACKEND_PARAMS_FOR_TABLES_KEY,
|
89
|
-
title: i18n('settings.
|
90
|
-
helpPopoverContent: i18n('settings.
|
89
|
+
title: i18n('settings.useVirtualTables.title'),
|
90
|
+
helpPopoverContent: i18n('settings.useVirtualTables.popover'),
|
91
91
|
};
|
92
92
|
export const queryUseMultiSchemaSetting: SettingProps = {
|
93
93
|
settingKey: QUERY_USE_MULTI_SCHEMA_KEY,
|
@@ -103,7 +103,7 @@ export const appearanceSection: SettingsSection = {
|
|
103
103
|
export const experimentsSection: SettingsSection = {
|
104
104
|
id: 'experimentsSection',
|
105
105
|
title: i18n('section.experiments'),
|
106
|
-
settings: [useNodesEndpointSetting,
|
106
|
+
settings: [useNodesEndpointSetting, useVirtualTables, queryUseMultiSchemaSetting],
|
107
107
|
};
|
108
108
|
|
109
109
|
export const generalPage: SettingsPage = {
|
package/dist/index.tsx
CHANGED
@@ -8,6 +8,7 @@ import App from './containers/App/App';
|
|
8
8
|
import configureStore from './store';
|
9
9
|
import reportWebVitals from './reportWebVitals';
|
10
10
|
import HistoryContext from './contexts/HistoryContext';
|
11
|
+
import {ErrorBoundary} from './components/ErrorBoundary/ErrorBoundary';
|
11
12
|
|
12
13
|
import './styles/themes.scss';
|
13
14
|
import './styles/constants.scss';
|
@@ -18,11 +19,13 @@ window.store = store;
|
|
18
19
|
|
19
20
|
ReactDOM.render(
|
20
21
|
<React.StrictMode>
|
21
|
-
<
|
22
|
-
<
|
23
|
-
<
|
24
|
-
|
25
|
-
|
22
|
+
<ErrorBoundary>
|
23
|
+
<Provider store={store}>
|
24
|
+
<HistoryContext.Provider value={history}>
|
25
|
+
<App />
|
26
|
+
</HistoryContext.Provider>
|
27
|
+
</Provider>
|
28
|
+
</ErrorBoundary>
|
26
29
|
</React.StrictMode>,
|
27
30
|
document.getElementById('root'),
|
28
31
|
);
|
@@ -3,7 +3,6 @@ import {Selector, createSelector} from 'reselect';
|
|
3
3
|
import type {OrderType} from '@gravity-ui/react-data-table';
|
4
4
|
import {ASCENDING, DESCENDING} from '@gravity-ui/react-data-table/build/esm/lib/constants';
|
5
5
|
|
6
|
-
import type {TVDiskStateInfo} from '../../../types/api/vdisk';
|
7
6
|
import {NODES_SORT_VALUES, type NodesSortValue} from '../../../utils/nodes';
|
8
7
|
import {STORAGE_SORT_VALUES, type StorageSortValue, getUsage} from '../../../utils/storage';
|
9
8
|
|
@@ -111,25 +110,6 @@ export const selectGroupsSortParams = (state: StorageStateSlice) => {
|
|
111
110
|
};
|
112
111
|
// ==== Complex selectors ====
|
113
112
|
|
114
|
-
export const selectVDisksForPDisk: Selector<
|
115
|
-
StorageStateSlice,
|
116
|
-
TVDiskStateInfo[] | undefined,
|
117
|
-
[number | undefined, number | undefined]
|
118
|
-
> = createSelector(
|
119
|
-
[
|
120
|
-
selectStorageNodes,
|
121
|
-
(_state, nodeId: number | undefined) => nodeId,
|
122
|
-
(_state, _nodeId, pdiskId: number | undefined) => pdiskId,
|
123
|
-
],
|
124
|
-
(storageNodes, nodeId, pdiskId) => {
|
125
|
-
const targetNode = storageNodes?.find((node) => node.NodeId === nodeId);
|
126
|
-
return targetNode?.VDisks?.filter((vdisk) => vdisk.PDiskId === pdiskId).map((data) => ({
|
127
|
-
...data,
|
128
|
-
NodeId: nodeId,
|
129
|
-
}));
|
130
|
-
},
|
131
|
-
);
|
132
|
-
|
133
113
|
export const selectUsageFilterOptions: Selector<StorageStateSlice, UsageFilter[]> = createSelector(
|
134
114
|
selectStorageGroups,
|
135
115
|
(groups) => {
|
@@ -0,0 +1,18 @@
|
|
1
|
+
export function registerError(error: Error, message?: string, type = 'error') {
|
2
|
+
if (typeof window !== 'undefined' && window.Ya?.Rum) {
|
3
|
+
window.Ya.Rum.logError(
|
4
|
+
{
|
5
|
+
additional: {
|
6
|
+
url: window.location.href,
|
7
|
+
},
|
8
|
+
type,
|
9
|
+
message,
|
10
|
+
level: window.Ya.Rum.ERROR_LEVEL.ERROR,
|
11
|
+
},
|
12
|
+
error,
|
13
|
+
);
|
14
|
+
} else {
|
15
|
+
// eslint-disable-next-line no-console
|
16
|
+
console.error(error);
|
17
|
+
}
|
18
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "ydb-embedded-ui",
|
3
|
-
"version": "4.
|
3
|
+
"version": "4.29.0",
|
4
4
|
"files": [
|
5
5
|
"dist"
|
6
6
|
],
|
@@ -16,6 +16,8 @@
|
|
16
16
|
"@gravity-ui/navigation": "^1.8.0",
|
17
17
|
"@gravity-ui/paranoid": "^1.4.0",
|
18
18
|
"@gravity-ui/react-data-table": "^1.0.3",
|
19
|
+
"@types/numeral": "^2.0.2",
|
20
|
+
"@types/qs": "^6.9.7",
|
19
21
|
"@types/react": "^17.0.58",
|
20
22
|
"axios": "0.19.2",
|
21
23
|
"bem-cn-lite": "4.0.0",
|
@@ -27,6 +29,8 @@
|
|
27
29
|
"monaco-editor": "0.24.0",
|
28
30
|
"numeral": "2.0.6",
|
29
31
|
"path-to-regexp": "3.0.0",
|
32
|
+
"qs": "^6.11.0",
|
33
|
+
"react-error-boundary": "^4.0.12",
|
30
34
|
"react-json-inspector": "7.1.1",
|
31
35
|
"react-list": "0.8.11",
|
32
36
|
"react-monaco-editor": "0.30.1",
|
@@ -40,6 +44,7 @@
|
|
40
44
|
"redux-thunk": "2.3.0",
|
41
45
|
"reselect": "4.1.6",
|
42
46
|
"sass": "1.32.8",
|
47
|
+
"url": "^0.11.0",
|
43
48
|
"web-vitals": "1.1.2",
|
44
49
|
"ydb-ui-components": "^3.5.0"
|
45
50
|
},
|
@@ -118,8 +123,6 @@
|
|
118
123
|
"@testing-library/react": "^11.2.7",
|
119
124
|
"@testing-library/user-event": "^12.8.3",
|
120
125
|
"@types/lodash": "^4.14.178",
|
121
|
-
"@types/numeral": "^2.0.2",
|
122
|
-
"@types/qs": "^6.9.7",
|
123
126
|
"@types/react-dom": "^17.0.11",
|
124
127
|
"@types/react-router": "^5.1.17",
|
125
128
|
"@types/react-router-dom": "^5.3.2",
|
@@ -130,14 +133,12 @@
|
|
130
133
|
"lint-staged": "^12.3.7",
|
131
134
|
"postcss": "^8.4.6",
|
132
135
|
"prettier": "^2.5.1",
|
133
|
-
"qs": "^6.11.0",
|
134
136
|
"react": "^17.0.2",
|
135
137
|
"react-app-rewired": "^2.1.11",
|
136
138
|
"react-dom": "^17.0.2",
|
137
139
|
"stylelint": "^14.3.0",
|
138
140
|
"ts-jest": "^28.0.7",
|
139
|
-
"typescript": "^4.5.5"
|
140
|
-
"url": "^0.11.0"
|
141
|
+
"typescript": "^4.5.5"
|
141
142
|
},
|
142
143
|
"peerDependencies": {
|
143
144
|
"@gravity-ui/uikit": "^5.24.0"
|