From 9275e23de55deb68874a378e4b18bb24b8c9450f Mon Sep 17 00:00:00 2001 From: mufazalov Date: Mon, 18 Mar 2024 17:50:28 +0300 Subject: [PATCH 1/3] feat(PDisk): add restart button --- .../ButtonWithConfirmDialog.tsx | 4 +- src/containers/PDisk/PDisk.scss | 1 + src/containers/PDisk/PDisk.tsx | 45 +++++++++++++++++-- src/containers/PDisk/i18n/en.json | 5 ++- src/services/api.ts | 19 ++++++++ 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx b/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx index f0a89e4018..a60ae75cef 100644 --- a/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx +++ b/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx @@ -6,8 +6,8 @@ import {CriticalActionDialog} from '../CriticalActionDialog'; interface ButtonWithConfirmDialogProps { children: ReactNode; - onConfirmAction: () => Promise; - onConfirmActionSuccess?: (() => Promise) | VoidFunction; + onConfirmAction: () => Promise | undefined; + onConfirmActionSuccess?: (() => Promise | undefined) | VoidFunction; dialogContent: string; buttonDisabled?: ButtonProps['disabled']; buttonView?: ButtonProps['view']; diff --git a/src/containers/PDisk/PDisk.scss b/src/containers/PDisk/PDisk.scss index 89525b07e4..df20d045b0 100644 --- a/src/containers/PDisk/PDisk.scss +++ b/src/containers/PDisk/PDisk.scss @@ -16,6 +16,7 @@ &__meta, &__title, &__info, + &__controls, &__groups-title { position: sticky; left: 0; diff --git a/src/containers/PDisk/PDisk.tsx b/src/containers/PDisk/PDisk.tsx index 5b8ac7cf02..7420f951ff 100644 --- a/src/containers/PDisk/PDisk.tsx +++ b/src/containers/PDisk/PDisk.tsx @@ -2,6 +2,9 @@ import {useCallback, useEffect} from 'react'; import {StringParam, useQueryParams} from 'use-query-params'; import {Helmet} from 'react-helmet-async'; +import {Icon} from '@gravity-ui/uikit'; +import ArrowRotateLeftIcon from '@gravity-ui/icons/svgs/arrow-rotate-left.svg'; + import { getPDiskData, getPDiskStorage, @@ -17,6 +20,7 @@ import {PageMeta} from '../../components/PageMeta/PageMeta'; import {StatusIcon} from '../../components/StatusIcon/StatusIcon'; import {PDiskInfo} from '../../components/PDiskInfo/PDiskInfo'; import {InfoViewerSkeleton} from '../../components/InfoViewerSkeleton/InfoViewerSkeleton'; +import {ButtonWithConfirmDialog} from '../../components/ButtonWithConfirmDialog/ButtonWithConfirmDialog'; import {PDiskGroups} from './PDiskGroups'; import {pdiskPageCn} from './shared'; @@ -46,20 +50,37 @@ export function PDisk() { }, [dispatch]); const fetchData = useCallback( - (isBackground: boolean) => { + (isBackground?: boolean) => { if (!isBackground) { dispatch(setPDiskDataWasNotLoaded()); } + if (nodeId && pDiskId) { - dispatch(getPDiskData({nodeId, pDiskId})); - dispatch(getPDiskStorage({nodeId, pDiskId})); + return Promise.all([ + dispatch(getPDiskData({nodeId, pDiskId})), + dispatch(getPDiskStorage({nodeId, pDiskId})), + ]); } + + return undefined; }, [dispatch, nodeId, pDiskId], ); useAutofetcher(fetchData, [fetchData], true); + const handleRestart = () => { + if (nodeId && pDiskId) { + return window.api.restartPDisk(nodeId, pDiskId); + } + + return undefined; + }; + + const handleAfterRestart = () => { + return fetchData(true); + }; + const renderHelmet = () => { const pDiskPagePart = pDiskId ? `${pDiskPageKeyset('pdisk')} ${pDiskId}` @@ -97,6 +118,23 @@ export function PDisk() { ); }; + const renderControls = () => { + return ( +
+ + + {pDiskPageKeyset('restart-pdisk-button')} + +
+ ); + }; + const renderInfo = () => { if (pDiskLoading && !pDiskWasLoaded) { return ; @@ -126,6 +164,7 @@ export function PDisk() { {renderHelmet()} {renderPageMeta()} {renderPageTitle()} + {renderControls()} {renderInfo()} {renderGroupsTable()} diff --git a/src/containers/PDisk/i18n/en.json b/src/containers/PDisk/i18n/en.json index 197ed9608a..f876518a1f 100644 --- a/src/containers/PDisk/i18n/en.json +++ b/src/containers/PDisk/i18n/en.json @@ -2,5 +2,8 @@ "fqdn": "FQDN", "pdisk": "PDisk", "groups": "Groups", - "node": "Node" + "node": "Node", + + "restart-pdisk-button": "Restart PDisk", + "restart-pdisk-dialog": "PDisk will be restarted. Do you want to proceed?" } diff --git a/src/services/api.ts b/src/services/api.ts index f40f69c7ad..b60527e3d8 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -38,6 +38,7 @@ import type {JsonHotKeysResponse} from '../types/api/hotkeys'; import {backend as BACKEND, metaBackend as META_BACKEND} from '../store'; import {prepareSortValue} from '../utils/filters'; +import {createPDiskDeveloperUILink} from '../utils/developerUI/developerUI'; import {BINARY_DATA_IN_PLAIN_TEXT_DISPLAY} from '../utils/constants'; import {parseMetaCluster} from './parsers/parseMetaCluster'; import {parseMetaTenants} from './parsers/parseMetaTenants'; @@ -378,6 +379,24 @@ export class YdbEmbeddedAPI extends AxiosWrapper { {concurrentId}, ); } + restartPDisk(nodeId: number | string, pDiskId: number | string) { + const pDiskPath = createPDiskDeveloperUILink({ + nodeId, + pDiskId, + host: this.getPath(''), + }); + + return this.post( + pDiskPath, + 'restartPDisk=', + {}, + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + }, + }, + ); + } killTablet(id?: string) { return this.get(this.getPath(`/tablets?KillTabletID=${id}`), {}); } From 1b0db73ef2317e6e96ba588d669ef96cbeb84ce4 Mon Sep 17 00:00:00 2001 From: mufazalov Date: Thu, 21 Mar 2024 17:25:30 +0300 Subject: [PATCH 2/3] fix: review --- .../ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx | 4 ++-- src/containers/PDisk/PDisk.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx b/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx index a60ae75cef..f0a89e4018 100644 --- a/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx +++ b/src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx @@ -6,8 +6,8 @@ import {CriticalActionDialog} from '../CriticalActionDialog'; interface ButtonWithConfirmDialogProps { children: ReactNode; - onConfirmAction: () => Promise | undefined; - onConfirmActionSuccess?: (() => Promise | undefined) | VoidFunction; + onConfirmAction: () => Promise; + onConfirmActionSuccess?: (() => Promise) | VoidFunction; dialogContent: string; buttonDisabled?: ButtonProps['disabled']; buttonView?: ButtonProps['view']; diff --git a/src/containers/PDisk/PDisk.tsx b/src/containers/PDisk/PDisk.tsx index 7420f951ff..f41191623a 100644 --- a/src/containers/PDisk/PDisk.tsx +++ b/src/containers/PDisk/PDisk.tsx @@ -69,7 +69,7 @@ export function PDisk() { useAutofetcher(fetchData, [fetchData], true); - const handleRestart = () => { + const handleRestart = async () => { if (nodeId && pDiskId) { return window.api.restartPDisk(nodeId, pDiskId); } @@ -77,7 +77,7 @@ export function PDisk() { return undefined; }; - const handleAfterRestart = () => { + const handleAfterRestart = async () => { return fetchData(true); }; From 9f2250bfbc5b939fc7b8bbc9a6554ff91fb36666 Mon Sep 17 00:00:00 2001 From: mufazalov Date: Thu, 21 Mar 2024 17:38:44 +0300 Subject: [PATCH 3/3] fix: review --- src/containers/PDisk/PDisk.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/PDisk/PDisk.tsx b/src/containers/PDisk/PDisk.tsx index f41191623a..0551b2b9c0 100644 --- a/src/containers/PDisk/PDisk.tsx +++ b/src/containers/PDisk/PDisk.tsx @@ -50,7 +50,7 @@ export function PDisk() { }, [dispatch]); const fetchData = useCallback( - (isBackground?: boolean) => { + async (isBackground?: boolean) => { if (!isBackground) { dispatch(setPDiskDataWasNotLoaded()); }