ydb-embedded-ui 6.12.0 → 6.13.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/components/AutoRefreshControl/i18n/index.d.ts +1 -1
- package/dist/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.d.ts +3 -2
- package/dist/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.js +9 -5
- package/dist/components/CriticalActionDialog/CriticalActionDialog.d.ts +5 -3
- package/dist/components/CriticalActionDialog/CriticalActionDialog.js +8 -7
- package/dist/components/CriticalActionDialog/CriticalActionDialog.scss +1 -1
- package/dist/components/CriticalActionDialog/i18n/en.json +1 -0
- package/dist/components/CriticalActionDialog/i18n/index.d.ts +1 -1
- package/dist/components/Errors/PageError/PageError.d.ts +11 -0
- package/dist/components/Errors/PageError/PageError.js +19 -0
- package/dist/components/Errors/i18n/en.json +2 -1
- package/dist/components/Errors/i18n/index.d.ts +1 -1
- package/dist/components/Errors/i18n/ru.json +2 -1
- package/dist/components/Fullscreen/Fullscreen.d.ts +1 -1
- package/dist/components/Fullscreen/Fullscreen.js +34 -27
- package/dist/components/Fullscreen/Fullscreen.scss +16 -8
- package/dist/components/Graph/Graph.d.ts +13 -0
- package/dist/components/Graph/Graph.js +41 -0
- package/dist/components/LabelWithPopover/LabelWithPopover.d.ts +4 -1
- package/dist/components/LabelWithPopover/LabelWithPopover.js +1 -1
- package/dist/components/Loader/Loader.d.ts +2 -1
- package/dist/components/Loader/Loader.js +6 -1
- package/dist/components/LoaderWrapper/LoaderWrapper.d.ts +10 -0
- package/dist/components/LoaderWrapper/LoaderWrapper.js +8 -0
- package/dist/components/MetricChart/reducer.d.ts +2 -2
- package/dist/components/PDiskInfo/PDiskInfo.d.ts +2 -2
- package/dist/components/PDiskInfo/PDiskInfo.js +9 -6
- package/dist/components/PDiskInfo/i18n/index.d.ts +1 -1
- package/dist/components/ProgressViewer/ProgressViewer.js +3 -0
- package/dist/components/QueryExecutionStatus/QueryExecutionStatus.js +13 -3
- package/dist/components/QueryExecutionStatus/QueryExecutionStatus.scss +4 -0
- package/dist/components/QuerySettingsDescription/QuerySettingsDescription.d.ts +7 -0
- package/dist/components/QuerySettingsDescription/QuerySettingsDescription.js +8 -0
- package/dist/components/QuerySettingsDescription/QuerySettingsDescription.scss +8 -0
- package/dist/components/QuerySettingsDescription/index.d.ts +1 -0
- package/dist/components/QuerySettingsDescription/index.js +1 -0
- package/dist/components/VDisk/VDisk.js +3 -4
- package/dist/components/VDiskInfo/VDiskInfo.d.ts +2 -2
- package/dist/components/VDiskInfo/VDiskInfo.js +4 -2
- package/dist/containers/App/Content.js +15 -19
- package/dist/containers/AsideNavigation/AsideNavigation.js +2 -1
- package/dist/containers/AsideNavigation/YdbInternalUser/YdbInternalUser.js +4 -4
- package/dist/containers/Authentication/Authentication.js +8 -10
- package/dist/containers/Authentication/utils.d.ts +8 -0
- package/dist/containers/Authentication/utils.js +15 -0
- package/dist/containers/Cluster/ClusterInfo/ClusterInfo.js +6 -6
- package/dist/containers/Clusters/constants.d.ts +1 -1
- package/dist/containers/Heatmap/Heatmap.js +5 -4
- package/dist/containers/Node/Node.js +5 -7
- package/dist/containers/Node/Node.scss +4 -0
- package/dist/containers/Node/NodeStructure/NodeStructure.js +4 -4
- package/dist/containers/Node/NodeStructure/NodeStructure.scss +4 -0
- package/dist/containers/Node/NodeStructure/Pdisk.js +2 -2
- package/dist/containers/Nodes/Nodes.js +6 -8
- package/dist/containers/Nodes/getNodesColumns.js +6 -21
- package/dist/containers/PDiskPage/PDiskPage.js +19 -8
- package/dist/containers/PDiskPage/i18n/en.json +1 -0
- package/dist/containers/PDiskPage/i18n/index.d.ts +1 -1
- package/dist/containers/Storage/PDisk/PDisk.js +3 -4
- package/dist/containers/Storage/Storage.js +4 -6
- package/dist/containers/Tablet/Tablet.js +2 -2
- package/dist/containers/Tablet/TabletControls/TabletControls.js +2 -1
- package/dist/containers/Tablets/Tablets.js +3 -5
- package/dist/containers/Tenant/Diagnostics/Consumers/Consumers.js +2 -5
- package/dist/containers/Tenant/Diagnostics/Describe/Describe.js +10 -13
- package/dist/containers/Tenant/Diagnostics/DetailedOverview/DetailedOverview.scss +1 -0
- package/dist/containers/Tenant/Diagnostics/Network/Network.js +8 -11
- package/dist/containers/Tenant/Diagnostics/Network/Network.scss +1 -0
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.d.ts +1 -2
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.js +3 -5
- package/dist/containers/Tenant/Diagnostics/Overview/TopicStats/TopicStats.js +3 -4
- package/dist/containers/Tenant/Diagnostics/Partitions/Partitions.js +1 -4
- package/dist/containers/Tenant/Diagnostics/TenantOverview/TenantOverviewTableLayout.js +3 -3
- package/dist/containers/Tenant/Diagnostics/TenantOverview/i18n/index.d.ts +1 -1
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +4 -3
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +4 -3
- package/dist/containers/Tenant/Query/ExecuteResult/ExecuteResult.d.ts +2 -2
- package/dist/containers/Tenant/Query/ExecuteResult/ExecuteResult.js +56 -20
- package/dist/containers/Tenant/Query/ExecuteResult/ExecuteResult.scss +10 -6
- package/dist/containers/Tenant/Query/ExecuteResult/i18n/en.json +7 -0
- package/dist/containers/Tenant/Query/ExecuteResult/i18n/index.d.ts +2 -0
- package/dist/containers/Tenant/Query/ExecuteResult/i18n/index.js +4 -0
- package/dist/containers/Tenant/Query/ExecuteResult/utils.d.ts +18 -0
- package/dist/containers/Tenant/Query/ExecuteResult/utils.js +36 -0
- package/dist/containers/Tenant/Query/ExplainResult/ExplainResult.d.ts +23 -1
- package/dist/containers/Tenant/Query/ExplainResult/ExplainResult.js +56 -111
- package/dist/containers/Tenant/Query/ExplainResult/ExplainResult.scss +1 -30
- package/dist/containers/Tenant/Query/ExplainResult/components/Ast/Ast.d.ts +7 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/Ast/Ast.js +18 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/Ast/Ast.scss +8 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/Graph/Graph.d.ts +8 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/Graph/Graph.js +14 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/Graph/Graph.scss +14 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/MetricsCell.d.ts +6 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/MetricsCell.js +11 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/OperationCell.d.ts +13 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/OperationCell.js +48 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/OperationParams.d.ts +6 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/OperationParams.js +66 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/SimplifiedPlan.d.ts +7 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/SimplifiedPlan.js +100 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/SimplifiedPlan.scss +128 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/types.d.ts +5 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/utils.d.ts +5 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/utils.js +59 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/TextExplain/TextExplain.d.ts +8 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/TextExplain/TextExplain.js +11 -0
- package/dist/containers/Tenant/Query/ExplainResult/components/TextExplain/TextExplain.scss +14 -0
- package/dist/containers/Tenant/Query/ExplainResult/i18n/en.json +8 -0
- package/dist/containers/Tenant/Query/ExplainResult/i18n/index.d.ts +2 -0
- package/dist/containers/Tenant/Query/ExplainResult/i18n/index.js +4 -0
- package/dist/containers/Tenant/Query/Preview/Preview.js +2 -3
- package/dist/containers/Tenant/Query/QueriesHistory/QueriesHistory.js +1 -19
- package/dist/containers/Tenant/Query/QueryDuration/QueryDuration.js +1 -1
- package/dist/containers/Tenant/Query/QueryDuration/QueryDuration.scss +11 -0
- package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.d.ts +1 -1
- package/dist/containers/Tenant/Query/QueryEditor/QueryEditor.js +91 -95
- package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.d.ts +4 -6
- package/dist/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.js +18 -49
- package/dist/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettings.d.ts +2 -0
- package/dist/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettings.js +5 -0
- package/dist/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettings.test.d.ts +1 -0
- package/dist/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettings.test.js +42 -0
- package/dist/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettingsDescription.d.ts +5 -0
- package/dist/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettingsDescription.js +19 -0
- package/dist/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettingsDescription.test.d.ts +1 -0
- package/dist/containers/Tenant/Query/QueryEditorControls/utils/getChangedQueryExecutionSettingsDescription.test.js +56 -0
- package/dist/containers/Tenant/Query/QuerySettingsBanner/QuerySettingsBanner.d.ts +2 -0
- package/dist/containers/Tenant/Query/QuerySettingsBanner/QuerySettingsBanner.js +12 -0
- package/dist/containers/Tenant/Query/QuerySettingsBanner/QuerySettingsBanner.scss +3 -0
- package/dist/containers/Tenant/Query/QuerySettingsDialog/QuerySettingsDialog.js +20 -23
- package/dist/containers/Tenant/Query/QuerySettingsDialog/constants.d.ts +123 -7
- package/dist/containers/Tenant/Query/QuerySettingsDialog/constants.js +32 -10
- package/dist/containers/Tenant/Query/i18n/en.json +3 -1
- package/dist/containers/Tenant/Query/i18n/index.d.ts +1 -1
- package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.js +6 -6
- package/dist/containers/Tenant/Schema/SchemaViewer/SchemaViewer.js +5 -2
- package/dist/containers/Tenant/Schema/SchemaViewer/columns.d.ts +2 -1
- package/dist/containers/Tenant/Schema/SchemaViewer/columns.js +13 -1
- package/dist/containers/Tenant/Schema/SchemaViewer/i18n/en.json +1 -0
- package/dist/containers/Tenant/Schema/SchemaViewer/i18n/index.d.ts +1 -1
- package/dist/containers/Tenant/Schema/SchemaViewer/prepareData.js +3 -2
- package/dist/containers/Tenant/Schema/SchemaViewer/types.d.ts +1 -0
- package/dist/containers/Tenant/Tenant.js +4 -8
- package/dist/containers/Tenant/utils/schemaActions.d.ts +2 -2
- package/dist/containers/Tenant/utils/schemaActions.js +2 -2
- package/dist/containers/Tenants/Tenants.js +4 -7
- package/dist/containers/UserSettings/i18n/en.json +3 -5
- package/dist/containers/UserSettings/i18n/index.d.ts +1 -1
- package/dist/containers/UserSettings/settings.d.ts +2 -3
- package/dist/containers/UserSettings/settings.js +17 -23
- package/dist/containers/VDiskPage/VDiskPage.js +27 -13
- package/dist/containers/VDiskPage/i18n/en.json +1 -0
- package/dist/containers/VDiskPage/i18n/index.d.ts +1 -1
- package/dist/services/api.d.ts +21 -8
- package/dist/services/api.js +29 -42
- package/dist/services/settings.d.ts +11 -4
- package/dist/services/settings.js +7 -6
- package/dist/store/configureStore.d.ts +7 -7
- package/dist/store/defaultStore.d.ts +3 -3
- package/dist/store/reducers/api.d.ts +1 -1
- package/dist/store/reducers/api.js +1 -1
- package/dist/store/reducers/authentication/authentication.d.ts +37 -24
- package/dist/store/reducers/authentication/authentication.js +77 -57
- package/dist/store/reducers/authentication/types.d.ts +0 -8
- package/dist/store/reducers/capabilities/capabilities.d.ts +106 -0
- package/dist/store/reducers/capabilities/capabilities.js +22 -0
- package/dist/store/reducers/capabilities/hooks.d.ts +2 -0
- package/dist/store/reducers/capabilities/hooks.js +13 -0
- package/dist/store/reducers/cluster/cluster.d.ts +2 -2
- package/dist/store/reducers/clusterNodes/clusterNodes.d.ts +2 -2
- package/dist/store/reducers/clusters/clusters.d.ts +2 -2
- package/dist/store/reducers/describe.d.ts +2 -2
- package/dist/store/reducers/executeQuery.d.ts +7 -14
- package/dist/store/reducers/executeQuery.js +19 -14
- package/dist/store/reducers/executeTopQueries/executeTopQueries.d.ts +2 -2
- package/dist/store/reducers/explainQuery/explainQuery.d.ts +5 -4
- package/dist/store/reducers/explainQuery/explainQuery.js +14 -4
- package/dist/store/reducers/explainQuery/types.d.ts +13 -1
- package/dist/store/reducers/explainQuery/utils.js +7 -2
- package/dist/store/reducers/healthcheckInfo/healthcheckInfo.d.ts +58 -58
- package/dist/store/reducers/heatmap.d.ts +2 -2
- package/dist/store/reducers/hotKeys/hotKeys.d.ts +2 -2
- package/dist/store/reducers/index.d.ts +6 -6
- package/dist/store/reducers/network/network.d.ts +2 -2
- package/dist/store/reducers/node/node.d.ts +3 -3
- package/dist/store/reducers/node/selectors.d.ts +1 -1
- package/dist/store/reducers/nodes/nodes.d.ts +3 -3
- package/dist/store/reducers/nodesList.d.ts +3 -3
- package/dist/store/reducers/overview/overview.d.ts +2 -2
- package/dist/store/reducers/partitions/partitions.d.ts +2 -2
- package/dist/store/reducers/pdisk/pdisk.d.ts +3 -3
- package/dist/store/reducers/preview.d.ts +2 -2
- package/dist/store/reducers/schema/schema.d.ts +3 -3
- package/dist/store/reducers/schema/schema.js +10 -3
- package/dist/store/reducers/schemaAcl/schemaAcl.d.ts +2 -2
- package/dist/store/reducers/shardsWorkload/shardsWorkload.d.ts +2 -2
- package/dist/store/reducers/storage/storage.d.ts +3 -3
- package/dist/store/reducers/tablet.d.ts +3 -3
- package/dist/store/reducers/tablets.d.ts +13 -13
- package/dist/store/reducers/tabletsFilters.d.ts +1 -1
- package/dist/store/reducers/tenant/tenant.d.ts +2 -2
- package/dist/store/reducers/tenantOverview/executeTopTables/executeTopTables.d.ts +2 -2
- package/dist/store/reducers/tenantOverview/topNodes/topNodes.d.ts +2 -2
- package/dist/store/reducers/tenantOverview/topShards/tenantOverviewTopShards.d.ts +2 -2
- package/dist/store/reducers/tenantOverview/topStorageGroups/topStorageGroups.d.ts +2 -2
- package/dist/store/reducers/tenants/selectors.d.ts +31 -30
- package/dist/store/reducers/tenants/selectors.js +8 -2
- package/dist/store/reducers/tenants/tenants.d.ts +2 -2
- package/dist/store/reducers/topic.d.ts +44 -44
- package/dist/store/reducers/vdisk/vdisk.d.ts +2 -2
- package/dist/store/reducers/viewSchema/viewSchema.d.ts +2 -2
- package/dist/styles/mixins.scss +2 -0
- package/dist/types/api/capabilities.d.ts +7 -0
- package/dist/types/api/capabilities.js +1 -0
- package/dist/types/api/modifyDisk.d.ts +8 -0
- package/dist/types/api/modifyDisk.js +1 -0
- package/dist/types/api/query.d.ts +39 -3
- package/dist/types/api/query.js +9 -1
- package/dist/types/api/schema/shared.d.ts +8 -0
- package/dist/types/store/query.d.ts +7 -0
- package/dist/utils/__test__/prepareQueryExplain.test.d.ts +1 -0
- package/dist/utils/__test__/prepareQueryExplain.test.js +115 -0
- package/dist/utils/constants.d.ts +13 -4
- package/dist/utils/constants.js +15 -4
- package/dist/utils/dataFormatters/dataFormatters.d.ts +0 -1
- package/dist/utils/dataFormatters/dataFormatters.js +1 -4
- package/dist/utils/hooks/index.d.ts +2 -1
- package/dist/utils/hooks/index.js +2 -1
- package/dist/utils/hooks/useChangedQuerySettings.d.ts +10 -0
- package/dist/utils/hooks/useChangedQuerySettings.js +46 -0
- package/dist/utils/hooks/useDelayed.d.ts +1 -0
- package/dist/utils/hooks/useDelayed.js +13 -0
- package/dist/utils/hooks/useEventHandler.d.ts +6 -0
- package/dist/utils/hooks/useEventHandler.js +17 -0
- package/dist/utils/hooks/useLastQueryExecutionSettings.d.ts +2 -0
- package/dist/utils/hooks/useLastQueryExecutionSettings.js +5 -0
- package/dist/utils/hooks/useQueryExecutionSettings.d.ts +8 -0
- package/dist/utils/hooks/useQueryExecutionSettings.js +15 -0
- package/dist/utils/prepareQueryExplain.d.ts +3 -1
- package/dist/utils/prepareQueryExplain.js +54 -2
- package/dist/utils/query.js +1 -0
- package/dist/utils/query.test.js +3 -0
- package/dist/utils/utils.d.ts +8 -7
- package/dist/utils/utils.js +23 -11
- package/package.json +4 -2
- package/dist/containers/Tenant/Query/ExplainResult/utils.d.ts +0 -2
- package/dist/containers/Tenant/Query/ExplainResult/utils.js +0 -4
- package/dist/store/utils.d.ts +0 -23
- package/dist/store/utils.js +0 -49
- package/dist/types/api/restartPDisk.d.ts +0 -4
- package/dist/utils/hooks/useQueryModes.d.ts +0 -2
- package/dist/utils/hooks/useQueryModes.js +0 -5
- /package/dist/{types/api/restartPDisk.js → containers/Tenant/Query/ExplainResult/components/SimplifiedPlan/types.js} +0 -0
@@ -2,12 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
3
3
|
import { STRUCTURE } from '../../containers/Node/NodePages';
|
4
4
|
import routes, { createHref, getVDiskPagePath } from '../../routes';
|
5
|
+
import { useDiskPagesAvailable } from '../../store/reducers/capabilities/hooks';
|
5
6
|
import { valueIsDefined } from '../../utils';
|
6
7
|
import { cn } from '../../utils/cn';
|
7
|
-
import { USE_SEPARATE_DISKS_PAGES_KEY } from '../../utils/constants';
|
8
8
|
import { stringifyVdiskId } from '../../utils/dataFormatters/dataFormatters';
|
9
9
|
import { isFullVDiskData } from '../../utils/disks/helpers';
|
10
|
-
import { useSetting } from '../../utils/hooks';
|
11
10
|
import { DiskStateProgressBar } from '../DiskStateProgressBar/DiskStateProgressBar';
|
12
11
|
import { InternalLink } from '../InternalLink';
|
13
12
|
import { VDiskPopup } from '../VDiskPopup/VDiskPopup';
|
@@ -15,7 +14,7 @@ import './VDisk.scss';
|
|
15
14
|
const b = cn('ydb-vdisk-component');
|
16
15
|
export const VDisk = ({ data = {}, nodes, compact }) => {
|
17
16
|
const isFullData = isFullVDiskData(data);
|
18
|
-
const
|
17
|
+
const diskPagesAvailable = useDiskPagesAvailable();
|
19
18
|
const [isPopupVisible, setIsPopupVisible] = React.useState(false);
|
20
19
|
const anchor = React.useRef(null);
|
21
20
|
const showPopup = () => {
|
@@ -25,7 +24,7 @@ export const VDisk = ({ data = {}, nodes, compact }) => {
|
|
25
24
|
setIsPopupVisible(false);
|
26
25
|
};
|
27
26
|
let vDiskPath;
|
28
|
-
if (
|
27
|
+
if (diskPagesAvailable &&
|
29
28
|
valueIsDefined(data.VDiskSlotId) &&
|
30
29
|
valueIsDefined(data.PDiskId) &&
|
31
30
|
valueIsDefined(data.NodeId)) {
|
@@ -3,8 +3,8 @@ import type { InfoViewerProps } from '../InfoViewer/InfoViewer';
|
|
3
3
|
import './VDiskInfo.scss';
|
4
4
|
interface VDiskInfoProps<T extends PreparedVDisk> extends Omit<InfoViewerProps, 'info'> {
|
5
5
|
data?: T;
|
6
|
-
|
6
|
+
withVDiskPageLink?: boolean;
|
7
7
|
withTitle?: boolean;
|
8
8
|
}
|
9
|
-
export declare function VDiskInfo<T extends PreparedVDisk>({ data,
|
9
|
+
export declare function VDiskInfo<T extends PreparedVDisk>({ data, withVDiskPageLink, withTitle, ...infoViewerProps }: VDiskInfoProps<T>): import("react/jsx-runtime").JSX.Element;
|
10
10
|
export {};
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
2
|
import { getVDiskPagePath } from '../../routes';
|
3
|
+
import { useDiskPagesAvailable } from '../../store/reducers/capabilities/hooks';
|
3
4
|
import { valueIsDefined } from '../../utils';
|
4
5
|
import { cn } from '../../utils/cn';
|
5
6
|
import { formatStorageValuesToGb, stringifyVdiskId } from '../../utils/dataFormatters/dataFormatters';
|
@@ -14,8 +15,9 @@ import { vDiskInfoKeyset } from './i18n';
|
|
14
15
|
import './VDiskInfo.scss';
|
15
16
|
const b = cn('ydb-vdisk-info');
|
16
17
|
// eslint-disable-next-line complexity
|
17
|
-
export function VDiskInfo({ data,
|
18
|
+
export function VDiskInfo({ data, withVDiskPageLink, withTitle, ...infoViewerProps }) {
|
18
19
|
var _a, _b, _c, _d;
|
20
|
+
const diskPagesAvailable = useDiskPagesAvailable();
|
19
21
|
const { AllocatedSize, DiskSpace, FrontQueues, Guid, Replicated, VDiskState, VDiskSlotId, Kind, SatisfactionRank, AvailableSize, HasUnreadableBlobs, IncarnationGuid, InstanceGuid, StoragePoolName, ReadThroughput, WriteThroughput, PDiskId, NodeId, } = data || {};
|
20
22
|
const vdiskInfo = [];
|
21
23
|
if (valueIsDefined(VDiskSlotId)) {
|
@@ -105,7 +107,7 @@ export function VDiskInfo({ data, isVDiskPage, withTitle, ...infoViewerProps })
|
|
105
107
|
});
|
106
108
|
vdiskInfo.push({
|
107
109
|
label: vDiskInfoKeyset('links'),
|
108
|
-
value: (_jsxs("span", { className: b('links'), children: [
|
110
|
+
value: (_jsxs("span", { className: b('links'), children: [withVDiskPageLink && diskPagesAvailable && (_jsx(LinkWithIcon, { title: vDiskInfoKeyset('vdisk-page'), url: vDiskPagePath, external: false })), _jsx(LinkWithIcon, { title: vDiskInfoKeyset('developer-ui'), url: vDiskInternalViewerPath })] })),
|
109
111
|
});
|
110
112
|
}
|
111
113
|
const title = data && withTitle ? _jsx(VDiskTitle, { data: data }) : null;
|
@@ -1,13 +1,14 @@
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import
|
3
|
-
import { connect, shallowEqual } from 'react-redux';
|
2
|
+
import { connect } from 'react-redux';
|
4
3
|
import { Redirect, Route, Switch } from 'react-router-dom';
|
4
|
+
import { PageError } from '../../components/Errors/PageError/PageError';
|
5
|
+
import { LoaderWrapper } from '../../components/LoaderWrapper/LoaderWrapper';
|
5
6
|
import { useSlots } from '../../components/slots';
|
6
7
|
import routes from '../../routes';
|
7
|
-
import {
|
8
|
+
import { authenticationApi } from '../../store/reducers/authentication/authentication';
|
9
|
+
import { capabilitiesApi } from '../../store/reducers/capabilities/capabilities';
|
8
10
|
import { nodesListApi } from '../../store/reducers/nodesList';
|
9
11
|
import { cn } from '../../utils/cn';
|
10
|
-
import { useTypedDispatch, useTypedSelector } from '../../utils/hooks';
|
11
12
|
import { lazyComponent } from '../../utils/lazyComponent';
|
12
13
|
import Authentication from '../Authentication/Authentication';
|
13
14
|
import { getClusterPath } from '../Cluster/utils';
|
@@ -89,27 +90,22 @@ export function Content(props) {
|
|
89
90
|
exact: true,
|
90
91
|
component: Clusters,
|
91
92
|
slot: ClustersSlot,
|
92
|
-
}), additionalRoutes === null || additionalRoutes === void 0 ? void 0 : additionalRoutes.rendered,
|
93
|
-
|
94
|
-
|
93
|
+
}), additionalRoutes === null || additionalRoutes === void 0 ? void 0 : additionalRoutes.rendered, _jsx(Route, { children: _jsxs(GetUser, { children: [_jsx(GetNodesList, {}), _jsx(GetCapabilities, {}), _jsx(Header, { mainPage: mainPage }), _jsxs(Switch, { children: [routesSlots.map((route) => {
|
94
|
+
return renderRouteSlot(slots, route);
|
95
|
+
}), _jsx(Route, { path: redirectProps.from || redirectProps.path, exact: redirectProps.exact, strict: redirectProps.strict, render: () => (_jsx(Redirect, { to: redirectProps.to, push: redirectProps.push })) })] })] }) }, "single-cluster")] }));
|
95
96
|
}
|
96
|
-
function GetUser() {
|
97
|
-
const
|
98
|
-
|
99
|
-
isAuthenticated: state.authentication.isAuthenticated,
|
100
|
-
isInternalUser: Boolean(state.authentication.user),
|
101
|
-
}), shallowEqual);
|
102
|
-
React.useEffect(() => {
|
103
|
-
if (isAuthenticated && !isInternalUser) {
|
104
|
-
dispatch(getUser());
|
105
|
-
}
|
106
|
-
}, [dispatch, isAuthenticated, isInternalUser]);
|
107
|
-
return null;
|
97
|
+
function GetUser({ children }) {
|
98
|
+
const { isLoading, error } = authenticationApi.useWhoamiQuery(undefined);
|
99
|
+
return (_jsx(LoaderWrapper, { loading: isLoading, size: "l", children: _jsx(PageError, { error: error, children: children }) }));
|
108
100
|
}
|
109
101
|
function GetNodesList() {
|
110
102
|
nodesListApi.useGetNodesListQuery(undefined);
|
111
103
|
return null;
|
112
104
|
}
|
105
|
+
function GetCapabilities() {
|
106
|
+
capabilitiesApi.useGetClusterCapabilitiesQuery(undefined);
|
107
|
+
return null;
|
108
|
+
}
|
113
109
|
function ContentWrapper(props) {
|
114
110
|
const { singleClusterMode, isAuthenticated } = props;
|
115
111
|
return (_jsxs(Switch, { children: [_jsx(Route, { path: routes.auth, children: _jsx(Authentication, { closable: true }) }), _jsx(Route, { children: _jsx("div", { className: b({ embedded: singleClusterMode }), children: isAuthenticated ? props.children : _jsx(Authentication, {}) }) })] }));
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
3
3
|
import { CircleQuestion, Gear, Person } from '@gravity-ui/icons';
|
4
4
|
import { AsideHeader, FooterItem } from '@gravity-ui/navigation';
|
5
5
|
import { useHistory } from 'react-router-dom';
|
6
|
+
import { selectUser } from '../../store/reducers/authentication/authentication';
|
6
7
|
import { cn } from '../../utils/cn';
|
7
8
|
import { ASIDE_HEADER_COMPACT_KEY } from '../../utils/constants';
|
8
9
|
import { useSetting, useTypedSelector } from '../../utils/hooks';
|
@@ -29,7 +30,7 @@ var Panel;
|
|
29
30
|
export function AsideNavigation(props) {
|
30
31
|
const history = useHistory();
|
31
32
|
const [visiblePanel, setVisiblePanel] = React.useState();
|
32
|
-
const
|
33
|
+
const ydbUser = useTypedSelector(selectUser);
|
33
34
|
const [compact, setIsCompact] = useSetting(ASIDE_HEADER_COMPACT_KEY);
|
34
35
|
return (_jsx(React.Fragment, { children: _jsx(AsideHeader, { logo: {
|
35
36
|
text: 'YDB',
|
@@ -3,21 +3,21 @@ import { ArrowRightFromSquare, ArrowRightToSquare } from '@gravity-ui/icons';
|
|
3
3
|
import { Button, Icon } from '@gravity-ui/uikit';
|
4
4
|
import { useHistory } from 'react-router-dom';
|
5
5
|
import routes, { createHref } from '../../../routes';
|
6
|
-
import {
|
6
|
+
import { authenticationApi } from '../../../store/reducers/authentication/authentication';
|
7
7
|
import { cn } from '../../../utils/cn';
|
8
|
-
import {
|
8
|
+
import { useTypedSelector } from '../../../utils/hooks';
|
9
9
|
import i18n from '../i18n';
|
10
10
|
import './YdbInternalUser.scss';
|
11
11
|
const b = cn('kv-ydb-internal-user');
|
12
12
|
export function YdbInternalUser() {
|
13
13
|
const { user: ydbUser } = useTypedSelector((state) => state.authentication);
|
14
|
+
const [logout] = authenticationApi.useLogoutMutation();
|
14
15
|
const history = useHistory();
|
15
16
|
const handleLoginClick = () => {
|
16
17
|
history.push(createHref(routes.auth, undefined, { returnUrl: encodeURIComponent(location.href) }));
|
17
18
|
};
|
18
|
-
const dispatch = useTypedDispatch();
|
19
19
|
const handleLogout = () => {
|
20
|
-
|
20
|
+
logout(undefined);
|
21
21
|
};
|
22
22
|
return (_jsxs("div", { className: b(), children: [_jsxs("div", { className: b('user-info-wrapper'), children: [_jsx("div", { className: b('ydb-internal-user-title'), children: i18n('account.user') }), ydbUser && _jsx("div", { className: b('username'), children: ydbUser })] }), ydbUser ? (_jsx(Button, { view: "flat-secondary", title: i18n('account.logout'), onClick: handleLogout, children: _jsx(Icon, { data: ArrowRightFromSquare }) })) : (_jsx(Button, { view: "flat-secondary", title: i18n('account.login'), onClick: handleLoginClick, children: _jsx(Icon, { data: ArrowRightToSquare }) }))] }));
|
23
23
|
}
|
@@ -4,29 +4,27 @@ import { Eye, EyeSlash, Xmark } from '@gravity-ui/icons';
|
|
4
4
|
import { Button, Link as ExternalLink, Icon, TextInput } from '@gravity-ui/uikit';
|
5
5
|
import { useHistory, useLocation } from 'react-router-dom';
|
6
6
|
import { parseQuery } from '../../routes';
|
7
|
-
import {
|
7
|
+
import { authenticationApi } from '../../store/reducers/authentication/authentication';
|
8
8
|
import { cn } from '../../utils/cn';
|
9
|
-
import {
|
9
|
+
import { isPasswordError, isUserError } from './utils';
|
10
10
|
import ydbLogoIcon from '../../assets/icons/ydb.svg';
|
11
11
|
import './Authentication.scss';
|
12
12
|
const b = cn('authentication');
|
13
13
|
function Authentication({ closable = false }) {
|
14
|
-
const dispatch = useTypedDispatch();
|
15
14
|
const history = useHistory();
|
16
15
|
const location = useLocation();
|
16
|
+
const [authenticate, { error, isLoading }] = authenticationApi.useAuthenticateMutation(undefined);
|
17
17
|
const { returnUrl } = parseQuery(location);
|
18
|
-
const { error } = useTypedSelector((state) => state.authentication);
|
19
18
|
const [login, setLogin] = React.useState('');
|
20
|
-
const [
|
19
|
+
const [password, setPass] = React.useState('');
|
21
20
|
const [loginError, setLoginError] = React.useState('');
|
22
21
|
const [passwordError, setPasswordError] = React.useState('');
|
23
22
|
const [showPassword, setShowPassword] = React.useState(false);
|
24
23
|
React.useEffect(() => {
|
25
|
-
|
26
|
-
if ((_b = (_a = error === null || error === void 0 ? void 0 : error.data) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.includes('user')) {
|
24
|
+
if (isUserError(error)) {
|
27
25
|
setLoginError(error.data.error);
|
28
26
|
}
|
29
|
-
if ((
|
27
|
+
if (isPasswordError(error)) {
|
30
28
|
setPasswordError(error.data.error);
|
31
29
|
}
|
32
30
|
}, [error]);
|
@@ -39,7 +37,7 @@ function Authentication({ closable = false }) {
|
|
39
37
|
setPasswordError('');
|
40
38
|
};
|
41
39
|
const onLoginClick = () => {
|
42
|
-
|
40
|
+
authenticate({ user: login, password }).then(() => {
|
43
41
|
if (returnUrl) {
|
44
42
|
const decodedUrl = decodeURIComponent(returnUrl.toString());
|
45
43
|
// to prevent page reload we use router history
|
@@ -62,6 +60,6 @@ function Authentication({ closable = false }) {
|
|
62
60
|
const onTogglePasswordVisibility = () => {
|
63
61
|
setShowPassword((prev) => !prev);
|
64
62
|
};
|
65
|
-
return (_jsxs("section", { className: b(), children: [_jsxs("form", { className: b('form-wrapper'), children: [_jsxs("div", { className: b('header'), children: [_jsxs("div", { className: b('logo'), children: [_jsx(Icon, { data: ydbLogoIcon, size: 24 }), "YDB"] }), _jsx(ExternalLink, { href: "
|
63
|
+
return (_jsxs("section", { className: b(), children: [_jsxs("form", { className: b('form-wrapper'), children: [_jsxs("div", { className: b('header'), children: [_jsxs("div", { className: b('logo'), children: [_jsx(Icon, { data: ydbLogoIcon, size: 24 }), "YDB"] }), _jsx(ExternalLink, { href: "https://ydb.tech/docs", target: "_blank", children: "Documentation" })] }), _jsx("h2", { className: b('title'), children: "Sign in" }), _jsx("div", { className: b('field-wrapper'), children: _jsx(TextInput, { value: login, onUpdate: onLoginUpdate, placeholder: 'Username', error: loginError, onKeyDown: onEnterClick, size: "l", autoFocus: true }) }), _jsxs("div", { className: b('field-wrapper'), children: [_jsx(TextInput, { value: password, onUpdate: onPassUpdate, type: showPassword ? 'text' : 'password', placeholder: 'Password', error: passwordError, onKeyDown: onEnterClick, size: "l" }), _jsx(Button, { onClick: onTogglePasswordVisibility, size: "l", className: b('show-password-button'), children: _jsx(Icon, { data: showPassword ? EyeSlash : Eye, size: 16 }) })] }), _jsx(Button, { view: "action", onClick: onLoginClick, width: "max", size: "l", disabled: Boolean(!login || loginError || passwordError), loading: isLoading, className: b('button-sign-in'), children: "Sign in" })] }), closable && history.length > 1 && (_jsx(Button, { onClick: onClose, className: b('close'), children: _jsx(Icon, { data: Xmark, size: 24 }) }))] }));
|
66
64
|
}
|
67
65
|
export default Authentication;
|
@@ -0,0 +1,15 @@
|
|
1
|
+
function isAuthError(error) {
|
2
|
+
return Boolean(error &&
|
3
|
+
typeof error === 'object' &&
|
4
|
+
'data' in error &&
|
5
|
+
error.data &&
|
6
|
+
typeof error.data === 'object' &&
|
7
|
+
'error' in error.data &&
|
8
|
+
typeof error.data.error === 'string');
|
9
|
+
}
|
10
|
+
export function isUserError(error) {
|
11
|
+
return isAuthError(error) && error.data.error.includes('user');
|
12
|
+
}
|
13
|
+
export function isPasswordError(error) {
|
14
|
+
return isAuthError(error) && error.data.error.includes('password');
|
15
|
+
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
2
|
import { ContentWithPopup } from '../../../components/ContentWithPopup/ContentWithPopup';
|
3
3
|
import { ResponseError } from '../../../components/Errors/ResponseError';
|
4
4
|
import InfoViewer from '../../../components/InfoViewer/InfoViewer';
|
@@ -102,14 +102,14 @@ const getInfo = (cluster, versionsValues, groupsStats, additionalInfo, links) =>
|
|
102
102
|
});
|
103
103
|
return info;
|
104
104
|
};
|
105
|
-
export const ClusterInfo = ({ cluster
|
105
|
+
export const ClusterInfo = ({ cluster, versionsValues = [], groupsStats = {}, loading, error, additionalClusterProps = {}, }) => {
|
106
106
|
const singleClusterMode = useTypedSelector((state) => state.singleClusterMode);
|
107
107
|
let internalLink = backend + '/internal';
|
108
108
|
if (singleClusterMode && !customBackend) {
|
109
109
|
internalLink = `/internal`;
|
110
110
|
}
|
111
111
|
const { info = [], links = [] } = additionalClusterProps;
|
112
|
-
const clusterInfo = getInfo(cluster, versionsValues, groupsStats, info, [
|
112
|
+
const clusterInfo = getInfo(cluster !== null && cluster !== void 0 ? cluster : {}, versionsValues, groupsStats, info, [
|
113
113
|
{ title: DEVELOPER_UI_TITLE, url: internalLink },
|
114
114
|
...links,
|
115
115
|
]);
|
@@ -117,10 +117,10 @@ export const ClusterInfo = ({ cluster = {}, versionsValues = [], groupsStats = {
|
|
117
117
|
if (loading) {
|
118
118
|
return _jsx(InfoViewerSkeleton, { className: b('skeleton'), rows: 9 });
|
119
119
|
}
|
120
|
-
if (error) {
|
121
|
-
return
|
120
|
+
if (error && !cluster) {
|
121
|
+
return null;
|
122
122
|
}
|
123
123
|
return _jsx(InfoViewer, { dots: true, info: clusterInfo });
|
124
124
|
};
|
125
|
-
return (
|
125
|
+
return (_jsxs("div", { className: b(), children: [error ? _jsx(ResponseError, { error: error, className: b('error') }) : null, _jsx("div", { className: b('info'), children: getContent() })] }));
|
126
126
|
};
|
@@ -14,7 +14,7 @@ export declare const COLUMNS_NAMES: {
|
|
14
14
|
readonly DESCRIPTION: "description";
|
15
15
|
readonly BALANCER: "balancer";
|
16
16
|
};
|
17
|
-
export declare const DEFAULT_COLUMNS: ("
|
17
|
+
export declare const DEFAULT_COLUMNS: ("status" | "nodes" | "storage" | "tenants" | "versions" | "service" | "load" | "hosts" | "balancer" | "owner" | "title")[];
|
18
18
|
export declare const COLUMNS_TITLES: {
|
19
19
|
readonly title: "Cluster";
|
20
20
|
readonly versions: "Versions";
|
@@ -68,13 +68,14 @@ export const Heatmap = ({ path, database }) => {
|
|
68
68
|
};
|
69
69
|
const renderContent = () => {
|
70
70
|
const { min, max } = getCurrentMetricLimits(currentMetric, tablets);
|
71
|
-
|
71
|
+
let content;
|
72
|
+
if (!error || currentData) {
|
73
|
+
content = heatmap ? renderHeatmapCanvas() : renderHistogram();
|
74
|
+
}
|
75
|
+
return (_jsxs("div", { className: b(), children: [_jsxs("div", { className: b('filters'), children: [_jsx(Select, { className: b('heatmap-select'), value: currentMetric ? [currentMetric] : [], options: metrics, onUpdate: handleMetricChange, width: 200 }), _jsx("div", { className: b('sort-checkbox'), children: _jsx(Checkbox, { onUpdate: handleCheckboxChange, checked: sort, children: "Sort" }) }), _jsx("div", { className: b('histogram-checkbox'), children: _jsx(Checkbox, { onUpdate: handleHeatmapChange, checked: heatmap, children: "Heatmap" }) }), _jsxs("div", { className: b('limits'), children: [_jsxs("div", { className: b('limits-block'), children: [_jsx("div", { className: b('limits-title'), children: "min:" }), _jsx("div", { className: b('limits-value'), children: Number.isInteger(min) ? formatNumber(min) : '—' })] }), _jsxs("div", { className: b('limits-block'), children: [_jsx("div", { className: b('limits-title'), children: "max:" }), _jsx("div", { className: b('limits-value'), children: Number.isInteger(max) ? formatNumber(max) : '—' })] }), _jsxs("div", { className: b('limits-block'), children: [_jsx("div", { className: b('limits-title'), children: "count:" }), _jsx("div", { className: b('limits-value'), children: formatNumber(tablets.length) })] })] })] }), error ? _jsx(ResponseError, { error: error }) : null, content] }));
|
72
76
|
};
|
73
77
|
if (loading) {
|
74
78
|
return _jsx(Loader, {});
|
75
79
|
}
|
76
|
-
if (error) {
|
77
|
-
return _jsx(ResponseError, { error: error });
|
78
|
-
}
|
79
80
|
return renderContent();
|
80
81
|
};
|
@@ -80,13 +80,11 @@ export function Node(props) {
|
|
80
80
|
if (loading) {
|
81
81
|
return _jsx(Loader, { size: "l" });
|
82
82
|
}
|
83
|
-
|
84
|
-
return _jsx(ResponseError, { error: error });
|
83
|
+
if (node) {
|
84
|
+
return (_jsxs("div", { className: b(null, props.className), ref: container, children: [_jsx(Helmet, { titleTemplate: `%s — ${node.Host} — YDB Monitoring`, defaultTitle: `${node.Host} — YDB Monitoring`, children: _jsx("title", { children: activeTabVerified.title }) }), _jsx(BasicNodeViewer, { node: node, additionalNodesProps: props.additionalNodesProps, className: b('header') }), error ? _jsx(ResponseError, { error: error, className: b('error') }) : null, renderTabs(), _jsx("div", { className: b('content'), children: renderTabContent() })] }));
|
85
85
|
}
|
86
|
-
|
87
|
-
|
88
|
-
return (_jsxs("div", { className: b(null, props.className), ref: container, children: [_jsx(Helmet, { titleTemplate: `%s — ${node.Host} — YDB Monitoring`, defaultTitle: `${node.Host} — YDB Monitoring`, children: _jsx("title", { children: activeTabVerified.title }) }), _jsx(BasicNodeViewer, { node: node, additionalNodesProps: props.additionalNodesProps, className: b('header') }), renderTabs(), _jsx("div", { className: b('content'), children: renderTabContent() })] }));
|
89
|
-
}
|
90
|
-
return _jsx("div", { className: "error", children: "no node data" });
|
86
|
+
if (error) {
|
87
|
+
return _jsx(ResponseError, { error: error });
|
91
88
|
}
|
89
|
+
return _jsx("div", { className: "error", children: "no node data" });
|
92
90
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
2
|
import url from 'url';
|
3
3
|
import React from 'react';
|
4
4
|
import isEmpty from 'lodash/isEmpty';
|
@@ -59,11 +59,11 @@ function NodeStructure({ nodeId, className }) {
|
|
59
59
|
if (loadingStructure) {
|
60
60
|
return _jsx(Loader, { size: "m" });
|
61
61
|
}
|
62
|
-
if (error) {
|
63
|
-
return
|
62
|
+
if (error && !currentData) {
|
63
|
+
return null;
|
64
64
|
}
|
65
65
|
return renderStructure();
|
66
66
|
};
|
67
|
-
return (
|
67
|
+
return (_jsxs("div", { className: b(), ref: scrollContainerRef, children: [error ? _jsx(ResponseError, { error: error, className: b('error') }) : null, _jsx("div", { className: className, children: renderContent() })] }));
|
68
68
|
}
|
69
69
|
export default NodeStructure;
|
@@ -78,7 +78,7 @@ function getColumns({ pDiskId, selectedVdiskId, nodeId, }) {
|
|
78
78
|
header: vDiskTableColumnsNames[VDiskTableColumnsIds.Info],
|
79
79
|
width: 70,
|
80
80
|
render: ({ row }) => {
|
81
|
-
return (_jsx(Popover, { placement: ['right'], content: _jsx(VDiskInfo, { data: row, withTitle: true }), tooltipContentClassName: b('vdisk-details'), children: _jsx(Button, { view: "flat-secondary", className: b('vdisk-details-button', {
|
81
|
+
return (_jsx(Popover, { placement: ['right'], content: _jsx(VDiskInfo, { data: row, withTitle: true, withVDiskPageLink: true }), tooltipContentClassName: b('vdisk-details'), children: _jsx(Button, { view: "flat-secondary", className: b('vdisk-details-button', {
|
82
82
|
selected: row.id === selectedVdiskId,
|
83
83
|
}), children: _jsx(Icon, { data: CircleInfoFill, size: 18 }) }) }));
|
84
84
|
},
|
@@ -107,7 +107,7 @@ export function PDisk({ id, data, selectedVdiskId, nodeId, unfolded: unfoldedFro
|
|
107
107
|
if (isEmpty(data)) {
|
108
108
|
return _jsx("div", { children: "No information about PDisk" });
|
109
109
|
}
|
110
|
-
return (_jsxs("div", { children: [_jsx(PDiskInfo, { pDisk: data, nodeId: nodeId, className: b('pdisk-details') }), _jsxs("div", { className: b('vdisks-container'), children: [_jsx("div", { className: b('vdisks-header'), children: "VDisks" }), renderVDisks()] })] }));
|
110
|
+
return (_jsxs("div", { children: [_jsx(PDiskInfo, { pDisk: data, nodeId: nodeId, className: b('pdisk-details'), withPDiskPageLink: true }), _jsxs("div", { className: b('vdisks-container'), children: [_jsx("div", { className: b('vdisks-header'), children: "VDisks" }), renderVDisks()] })] }));
|
111
111
|
};
|
112
112
|
return (_jsxs("div", { className: b('pdisk'), id: id, children: [_jsxs("div", { className: b('pdisk-header'), children: [_jsxs("div", { className: b('pdisk-title-wrapper'), children: [_jsx(EntityStatus, { status: Device }), _jsx(PDiskTitleBadge, { label: "PDiskID", value: PDiskId, className: b('pdisk-title-id') }), _jsx(PDiskTitleBadge, { value: Type, className: b('pdisk-title-type') }), _jsx(ProgressViewer, { value: total - available, capacity: total, formatValues: formatStorageValuesToGb, colorizeProgress: true, className: b('pdisk-title-size') }), _jsx(PDiskTitleBadge, { label: "VDisks", value: vDisks.length })] }), _jsx(Button, { onClick: unfolded ? onClosePDiskDetails : onOpenPDiskDetails, view: "flat-secondary", children: _jsx(ArrowToggle, { direction: unfolded ? 'top' : 'bottom' }) })] }), unfolded && renderPDiskDetails()] }));
|
113
113
|
}
|
@@ -5,6 +5,7 @@ import { skipToken } from '@reduxjs/toolkit/query';
|
|
5
5
|
import { StringParam, useQueryParams } from 'use-query-params';
|
6
6
|
import { EntitiesCount } from '../../components/EntitiesCount';
|
7
7
|
import { AccessDenied } from '../../components/Errors/403';
|
8
|
+
import { isAccessError } from '../../components/Errors/PageError/PageError';
|
8
9
|
import { ResponseError } from '../../components/Errors/ResponseError';
|
9
10
|
import { Illustration } from '../../components/Illustration';
|
10
11
|
import { ProblemFilter } from '../../components/ProblemFilter';
|
@@ -65,7 +66,7 @@ export const Nodes = ({ path, additionalNodesProps = {} }) => {
|
|
65
66
|
}, [data, searchValue, uptimeFilter, problemFilter]);
|
66
67
|
const totalNodes = (data === null || data === void 0 ? void 0 : data.TotalNodes) || 0;
|
67
68
|
const renderControls = () => {
|
68
|
-
return (_jsxs(React.Fragment, { children: [_jsx(Search, { onChange: handleSearchQueryChange, placeholder: "Host name", className: b('search'), value: searchValue }), _jsx(ProblemFilter, { value: problemFilter, onChange: handleProblemFilterChange }), _jsx(UptimeFilter, { value: uptimeFilter, onChange: handleUptimeFilterChange }), _jsx(EntitiesCount, { total: totalNodes, current:
|
69
|
+
return (_jsxs(React.Fragment, { children: [_jsx(Search, { onChange: handleSearchQueryChange, placeholder: "Host name", className: b('search'), value: searchValue }), _jsx(ProblemFilter, { value: problemFilter, onChange: handleProblemFilterChange }), _jsx(UptimeFilter, { value: uptimeFilter, onChange: handleUptimeFilterChange }), _jsx(EntitiesCount, { total: totalNodes, current: nodes.length, label: 'Nodes', loading: isLoading })] }));
|
69
70
|
};
|
70
71
|
const renderTable = () => {
|
71
72
|
const rawColumns = getNodesColumns({
|
@@ -74,7 +75,7 @@ export const Nodes = ({ path, additionalNodesProps = {} }) => {
|
|
74
75
|
const columns = rawColumns.map((column) => {
|
75
76
|
return { ...column, sortable: isSortableNodesProperty(column.name) };
|
76
77
|
});
|
77
|
-
if (nodes
|
78
|
+
if (nodes.length === 0) {
|
78
79
|
if (problemFilter !== ProblemFilterValues.ALL ||
|
79
80
|
uptimeFilter !== NodesUptimeFilterValues.All) {
|
80
81
|
return _jsx(Illustration, { name: "thumbsUp", width: "200" });
|
@@ -82,11 +83,8 @@ export const Nodes = ({ path, additionalNodesProps = {} }) => {
|
|
82
83
|
}
|
83
84
|
return (_jsx(ResizeableDataTable, { columnsWidthLSKey: NODES_COLUMNS_WIDTH_LS_KEY, data: nodes || [], columns: columns, settings: DEFAULT_TABLE_SETTINGS, sortOrder: sort, onSort: handleSort, emptyDataMessage: i18n('empty.default'), rowClassName: (row) => b('node', { unavailable: isUnavailableNode(row) }) }));
|
84
85
|
};
|
85
|
-
if (error) {
|
86
|
-
|
87
|
-
return _jsx(AccessDenied, {});
|
88
|
-
}
|
89
|
-
return _jsx(ResponseError, { error: error });
|
86
|
+
if (isAccessError(error)) {
|
87
|
+
return _jsx(AccessDenied, {});
|
90
88
|
}
|
91
|
-
return (_jsxs(TableWithControlsLayout, { children: [_jsx(TableWithControlsLayout.Controls, { children: renderControls() }), _jsx(TableWithControlsLayout.Table, { loading: isLoading, children: renderTable() })] }));
|
89
|
+
return (_jsxs(TableWithControlsLayout, { children: [_jsx(TableWithControlsLayout.Controls, { children: renderControls() }), error ? _jsx(ResponseError, { error: error }) : null, _jsx(TableWithControlsLayout.Table, { loading: isLoading, children: data ? renderTable() : null })] }));
|
92
90
|
};
|
@@ -8,7 +8,7 @@ import { TabletsStatistic } from '../../components/TabletsStatistic';
|
|
8
8
|
import { UsageLabel } from '../../components/UsageLabel/UsageLabel';
|
9
9
|
import { getLoadSeverityForNode } from '../../store/reducers/nodes/utils';
|
10
10
|
import { EMPTY_DATA_PLACEHOLDER } from '../../utils/constants';
|
11
|
-
import {
|
11
|
+
import { formatStorageValuesToGb } from '../../utils/dataFormatters/dataFormatters';
|
12
12
|
export const NODES_COLUMNS_WIDTH_LS_KEY = 'nodesTableColumnsWidth';
|
13
13
|
const NODES_COLUMNS_IDS = {
|
14
14
|
NodeId: 'NodeId',
|
@@ -84,14 +84,7 @@ const memoryColumn = {
|
|
84
84
|
header: 'Memory',
|
85
85
|
sortAccessor: ({ MemoryUsed = 0 }) => Number(MemoryUsed),
|
86
86
|
defaultOrder: DataTable.DESCENDING,
|
87
|
-
render: ({ row }) => {
|
88
|
-
if (row.MemoryUsed) {
|
89
|
-
return formatBytesToGigabyte(row.MemoryUsed);
|
90
|
-
}
|
91
|
-
else {
|
92
|
-
return '—';
|
93
|
-
}
|
94
|
-
},
|
87
|
+
render: ({ row }) => (_jsx(ProgressViewer, { value: row.MemoryUsed, capacity: row.MemoryLimit, formatValues: formatStorageValuesToGb, colorizeProgress: true })),
|
95
88
|
align: DataTable.RIGHT,
|
96
89
|
width: 120,
|
97
90
|
};
|
@@ -111,7 +104,9 @@ const loadAverageColumn = {
|
|
111
104
|
header: 'Load average',
|
112
105
|
sortAccessor: ({ LoadAveragePercents = [] }) => LoadAveragePercents[0],
|
113
106
|
defaultOrder: DataTable.DESCENDING,
|
114
|
-
render: ({ row }) =>
|
107
|
+
render: ({ row }) => (_jsx(ProgressViewer, { value: row.LoadAveragePercents && row.LoadAveragePercents.length > 0
|
108
|
+
? row.LoadAveragePercents[0]
|
109
|
+
: undefined, percents: true, colorizeProgress: true, capacity: 100 })),
|
115
110
|
align: DataTable.LEFT,
|
116
111
|
width: 140,
|
117
112
|
resizeMinWidth: 140,
|
@@ -147,22 +142,13 @@ const topNodesMemoryColumn = {
|
|
147
142
|
};
|
148
143
|
const sharedCacheUsageColumn = {
|
149
144
|
name: NODES_COLUMNS_IDS.SharedCacheUsage,
|
150
|
-
header: '
|
145
|
+
header: 'Caches',
|
151
146
|
render: ({ row }) => (_jsx(ProgressViewer, { value: row.SharedCacheUsed, capacity: row.SharedCacheLimit, formatValues: formatStorageValuesToGb, colorizeProgress: true })),
|
152
147
|
align: DataTable.LEFT,
|
153
148
|
width: 140,
|
154
149
|
resizeMinWidth: 140,
|
155
150
|
sortable: false,
|
156
151
|
};
|
157
|
-
const memoryUsedInAllocColumn = {
|
158
|
-
name: NODES_COLUMNS_IDS.MemoryUsedInAlloc,
|
159
|
-
header: 'Query Runtime',
|
160
|
-
render: ({ row }) => (_jsx(ProgressViewer, { value: row.MemoryUsedInAlloc, capacity: row.MemoryLimit, formatValues: formatStorageValuesToGb, colorizeProgress: true })),
|
161
|
-
align: DataTable.LEFT,
|
162
|
-
width: 140,
|
163
|
-
resizeMinWidth: 140,
|
164
|
-
sortable: false,
|
165
|
-
};
|
166
152
|
const sessionsColumn = {
|
167
153
|
name: NODES_COLUMNS_IDS.TotalSessions,
|
168
154
|
header: 'Sessions',
|
@@ -204,7 +190,6 @@ export function getTopNodesByMemoryColumns({ tabletsPath, getNodeRef, }) {
|
|
204
190
|
topNodesLoadAverageColumn,
|
205
191
|
topNodesMemoryColumn,
|
206
192
|
sharedCacheUsageColumn,
|
207
|
-
memoryUsedInAllocColumn,
|
208
193
|
sessionsColumn,
|
209
194
|
getTabletsColumn(tabletsPath),
|
210
195
|
];
|
@@ -9,12 +9,14 @@ import { z } from 'zod';
|
|
9
9
|
import { AutoRefreshControl } from '../../components/AutoRefreshControl/AutoRefreshControl';
|
10
10
|
import { ButtonWithConfirmDialog } from '../../components/ButtonWithConfirmDialog/ButtonWithConfirmDialog';
|
11
11
|
import { DiskPageTitle } from '../../components/DiskPageTitle/DiskPageTitle';
|
12
|
+
import { ResponseError } from '../../components/Errors/ResponseError';
|
12
13
|
import { InfoViewerSkeleton } from '../../components/InfoViewerSkeleton/InfoViewerSkeleton';
|
13
14
|
import { InternalLink } from '../../components/InternalLink/InternalLink';
|
14
15
|
import { PDiskInfo } from '../../components/PDiskInfo/PDiskInfo';
|
15
16
|
import { PageMeta } from '../../components/PageMeta/PageMeta';
|
16
17
|
import { getPDiskPagePath } from '../../routes';
|
17
18
|
import { api } from '../../store/reducers/api';
|
19
|
+
import { selectIsUserAllowedToMakeChanges } from '../../store/reducers/authentication/authentication';
|
18
20
|
import { setHeaderBreadcrumbs } from '../../store/reducers/header/header';
|
19
21
|
import { pDiskApi } from '../../store/reducers/pdisk/pdisk';
|
20
22
|
import { valueIsDefined } from '../../utils';
|
@@ -46,7 +48,7 @@ const PDISK_PAGE_TABS = [
|
|
46
48
|
const pDiskTabSchema = z.nativeEnum(PDISK_TABS_IDS).catch(PDISK_TABS_IDS.diskDistribution);
|
47
49
|
export function PDiskPage() {
|
48
50
|
const dispatch = useTypedDispatch();
|
49
|
-
const
|
51
|
+
const isUserAllowedToMakeChanges = useTypedSelector(selectIsUserAllowedToMakeChanges);
|
50
52
|
const [{ nodeId, pDiskId, activeTab }] = useQueryParams({
|
51
53
|
activeTab: StringParam,
|
52
54
|
nodeId: StringParam,
|
@@ -65,11 +67,14 @@ export function PDiskPage() {
|
|
65
67
|
const pDiskLoading = pdiskDataQuery.isFetching && pdiskDataQuery.currentData === undefined;
|
66
68
|
const pDiskData = pdiskDataQuery.currentData;
|
67
69
|
const { NodeHost, NodeId, NodeType, NodeDC, Severity } = pDiskData || {};
|
68
|
-
const handleRestart = async () => {
|
70
|
+
const handleRestart = async (isRetry) => {
|
69
71
|
if (pDiskParamsDefined) {
|
70
|
-
return window.api.restartPDisk(nodeId, pDiskId).then((
|
71
|
-
if ((
|
72
|
-
const err = {
|
72
|
+
return window.api.restartPDisk({ nodeId, pDiskId, force: isRetry }).then((response) => {
|
73
|
+
if ((response === null || response === void 0 ? void 0 : response.result) === false) {
|
74
|
+
const err = {
|
75
|
+
statusText: response.error,
|
76
|
+
retryPossible: response.forceRetryPossible,
|
77
|
+
};
|
73
78
|
throw err;
|
74
79
|
}
|
75
80
|
});
|
@@ -97,13 +102,13 @@ export function PDiskPage() {
|
|
97
102
|
return (_jsx(DiskPageTitle, { entityName: pDiskPageKeyset('pdisk'), status: getSeverityColor(Severity), id: pDiskParamsDefined ? getPDiskId(nodeId, pDiskId) : null, className: pdiskPageCn('title') }));
|
98
103
|
};
|
99
104
|
const renderControls = () => {
|
100
|
-
return (_jsx("div", { className: pdiskPageCn('controls'), children: _jsxs(ButtonWithConfirmDialog, { onConfirmAction: handleRestart, onConfirmActionSuccess: handleAfterRestart, buttonDisabled: !nodeId || !pDiskId || !isUserAllowedToMakeChanges, buttonView: "normal", dialogContent: pDiskPageKeyset('restart-pdisk-dialog'), withPopover: true, popoverContent: pDiskPageKeyset('restart-pdisk-not-allowed'), popoverDisabled: isUserAllowedToMakeChanges, children: [_jsx(Icon, { data: ArrowRotateLeft }), pDiskPageKeyset('restart-pdisk-button')] }) }));
|
105
|
+
return (_jsx("div", { className: pdiskPageCn('controls'), children: _jsxs(ButtonWithConfirmDialog, { onConfirmAction: handleRestart, onConfirmActionSuccess: handleAfterRestart, buttonDisabled: !nodeId || !pDiskId || !isUserAllowedToMakeChanges, buttonView: "normal", dialogContent: pDiskPageKeyset('restart-pdisk-dialog'), retryButtonText: pDiskPageKeyset('force-restart-pdisk-button'), withPopover: true, popoverContent: pDiskPageKeyset('restart-pdisk-not-allowed'), popoverDisabled: isUserAllowedToMakeChanges, children: [_jsx(Icon, { data: ArrowRotateLeft }), pDiskPageKeyset('restart-pdisk-button')] }) }));
|
101
106
|
};
|
102
107
|
const renderInfo = () => {
|
103
108
|
if (pDiskLoading) {
|
104
109
|
return _jsx(InfoViewerSkeleton, { className: pdiskPageCn('info'), rows: 10 });
|
105
110
|
}
|
106
|
-
return
|
111
|
+
return _jsx(PDiskInfo, { pDisk: pDiskData, nodeId: nodeId, className: pdiskPageCn('info') });
|
107
112
|
};
|
108
113
|
const renderTabs = () => {
|
109
114
|
return (_jsx("div", { className: pdiskPageCn('tabs'), children: _jsx(Tabs, { size: "l", items: PDISK_PAGE_TABS, activeTab: pDiskTab, wrapTo: ({ id }, tabNode) => {
|
@@ -125,5 +130,11 @@ export function PDiskPage() {
|
|
125
130
|
return null;
|
126
131
|
}
|
127
132
|
};
|
128
|
-
|
133
|
+
const renderError = () => {
|
134
|
+
if (!pdiskDataQuery.error) {
|
135
|
+
return null;
|
136
|
+
}
|
137
|
+
return _jsx(ResponseError, { error: pdiskDataQuery.error });
|
138
|
+
};
|
139
|
+
return (_jsxs("div", { className: pdiskPageCn(null), children: [renderHelmet(), renderPageMeta(), renderPageTitle(), renderControls(), renderError(), renderInfo(), renderTabs(), renderTabsContent()] }));
|
129
140
|
}
|
@@ -11,6 +11,7 @@
|
|
11
11
|
"label.slot-size": "Slot Size",
|
12
12
|
"no-slots-data": "No slots data",
|
13
13
|
"restart-pdisk-button": "Restart PDisk",
|
14
|
+
"force-restart-pdisk-button": "Restart anyway",
|
14
15
|
"restart-pdisk-dialog": "PDisk will be restarted. Do you want to proceed?",
|
15
16
|
"restart-pdisk-not-allowed": "You don't have enough rights to restart PDisk"
|
16
17
|
}
|
@@ -1 +1 @@
|
|
1
|
-
export declare const pDiskPageKeyset: (key: "node" | "groups" | "fqdn" | "log" | "pdisk" | "disk-distribution" | "empty-slot" | "label.log-size" | "label.system-size" | "label.slot-size" | "no-slots-data" | "restart-pdisk-button" | "restart-pdisk-dialog" | "restart-pdisk-not-allowed", params?: import("@gravity-ui/i18n").Params) => string;
|
1
|
+
export declare const pDiskPageKeyset: (key: "node" | "groups" | "fqdn" | "log" | "pdisk" | "disk-distribution" | "empty-slot" | "label.log-size" | "label.system-size" | "label.slot-size" | "no-slots-data" | "restart-pdisk-button" | "force-restart-pdisk-button" | "restart-pdisk-dialog" | "restart-pdisk-not-allowed", params?: import("@gravity-ui/i18n").Params) => string;
|