Skip to content

Commit

Permalink
feat(PDiskPage): add decommission button (#1168)
Browse files Browse the repository at this point in the history
  • Loading branch information
artemmufazalov authored Sep 4, 2024
1 parent c79ccbc commit d3e5f70
Show file tree
Hide file tree
Showing 25 changed files with 445 additions and 103 deletions.
6 changes: 6 additions & 0 deletions src/assets/icons/decommission.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 13 additions & 18 deletions src/components/ButtonWithConfirmDialog/ButtonWithConfirmDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import React from 'react';
import {Button, Popover} from '@gravity-ui/uikit';
import type {ButtonProps, PopoverProps} from '@gravity-ui/uikit';

import {CriticalActionDialog} from '../CriticalActionDialog';
import {CriticalActionDialog} from '../CriticalActionDialog/CriticalActionDialog';
import {isErrorWithRetry} from '../CriticalActionDialog/utils';

interface ButtonWithConfirmDialogProps<T, K> {
children: React.ReactNode;
onConfirmAction: (isRetry?: boolean) => Promise<T>;
onConfirmActionSuccess?: (() => Promise<K>) | VoidFunction;
dialogContent: string;
dialogHeader: string;
dialogText: string;
retryButtonText?: string;
buttonDisabled?: ButtonProps['disabled'];
buttonView?: ButtonProps['view'];
Expand All @@ -24,7 +26,8 @@ export function ButtonWithConfirmDialog<T, K>({
children,
onConfirmAction,
onConfirmActionSuccess,
dialogContent,
dialogHeader,
dialogText,
retryButtonText,
buttonDisabled = false,
buttonView = 'action',
Expand All @@ -41,29 +44,20 @@ export function ButtonWithConfirmDialog<T, K>({
const handleConfirmAction = async (isRetry?: boolean) => {
setButtonLoading(true);
await onConfirmAction(isRetry);
setButtonLoading(false);
};

const handleConfirmActionSuccess = async () => {
setWithRetry(false);

if (onConfirmActionSuccess) {
setButtonLoading(true);

try {
await onConfirmActionSuccess();
} catch {
} finally {
setButtonLoading(false);
}
try {
await onConfirmActionSuccess?.();
} finally {
setButtonLoading(false);
}
};

const handleConfirmActionError = (error: unknown) => {
const isWithRetry = Boolean(
error && typeof error === 'object' && 'retryPossible' in error && error.retryPossible,
);
setWithRetry(isWithRetry);
setWithRetry(isErrorWithRetry(error));
setButtonLoading(false);
};

Expand Down Expand Up @@ -101,7 +95,8 @@ export function ButtonWithConfirmDialog<T, K>({
<React.Fragment>
<CriticalActionDialog
visible={isConfirmDialogVisible}
text={dialogContent}
header={dialogHeader}
text={dialogText}
withRetry={withRetry}
retryButtonText={retryButtonText}
onConfirm={handleConfirmAction}
Expand Down
24 changes: 23 additions & 1 deletion src/components/CriticalActionDialog/CriticalActionDialog.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.ydb-critical-dialog {
padding-top: var(--g-spacing-7);
padding-top: var(--g-spacing-3);

&__warning-icon {
margin-right: 16px;
Expand All @@ -15,7 +15,29 @@
}

&__body {
display: flex;
flex-direction: column;
gap: var(--g-spacing-6);
}

&__body-message {
display: flex;
align-items: center;

&_warning,
&_error {
padding: var(--g-spacing-4) var(--g-spacing-5);

border: 1px solid;
border-radius: var(--g-modal-border-radius, 5px);
}

&_warning {
border-color: var(--ydb-color-status-yellow);
}

&_error {
border-color: var(--ydb-color-status-red);
}
}
}
33 changes: 23 additions & 10 deletions src/components/CriticalActionDialog/CriticalActionDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ const parseError = (error: IResponseError) => {

interface CriticalActionDialogProps<T> {
visible: boolean;
text: string;
header?: React.ReactNode;
text?: string;
withRetry?: boolean;
retryButtonText?: string;
onClose: VoidFunction;
Expand All @@ -36,6 +37,7 @@ interface CriticalActionDialogProps<T> {

export function CriticalActionDialog<T>({
visible,
header,
text,
withRetry,
retryButtonText,
Expand Down Expand Up @@ -64,15 +66,22 @@ export function CriticalActionDialog<T>({
});
};

const handleTransitionExited = () => {
setError(undefined);
};

const renderDialogContent = () => {
if (error) {
return (
<React.Fragment>
<Dialog.Header caption={header} />
<Dialog.Body className={b('body')}>
<span className={b('error-icon')}>
<CircleXmarkFill width="24" height="22" />
</span>
{parseError(error)}
<div className={b('body-message', {error: true})}>
<span className={b('error-icon')}>
<CircleXmarkFill width="24" height="22" />
</span>
{parseError(error)}
</div>
</Dialog.Body>

<Dialog.Footer
Expand All @@ -93,11 +102,15 @@ export function CriticalActionDialog<T>({

return (
<React.Fragment>
<Dialog.Header caption={header} />

<Dialog.Body className={b('body')}>
<span className={b('warning-icon')}>
<Icon data={TriangleExclamationFill} size={24} />
</span>
{text}
<div className={b('body-message', {warning: true})}>
<span className={b('warning-icon')}>
<Icon data={TriangleExclamationFill} size={24} />
</span>
{text}
</div>
</Dialog.Body>

<Dialog.Footer
Expand All @@ -120,7 +133,7 @@ export function CriticalActionDialog<T>({
className={b()}
size="s"
onClose={onClose}
onTransitionExited={() => setError(undefined)}
onTransitionExited={handleTransitionExited}
>
{renderDialogContent()}
</Dialog>
Expand Down
1 change: 0 additions & 1 deletion src/components/CriticalActionDialog/index.ts

This file was deleted.

9 changes: 9 additions & 0 deletions src/components/CriticalActionDialog/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface ErrorWithRetry {
retryPossible: boolean;
}

export const isErrorWithRetry = (error: unknown): error is ErrorWithRetry => {
return Boolean(
error && typeof error === 'object' && 'retryPossible' in error && error.retryPossible,
);
};
10 changes: 1 addition & 9 deletions src/components/EntityPageTitle/EntityPageTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,14 @@ interface EntityPageTitleProps {
status: EFlag;
id: React.ReactNode;
className?: string;
children?: React.ReactNode;
}

export function EntityPageTitle({
entityName,
status,
id,
className,
children,
}: EntityPageTitleProps) {
export function EntityPageTitle({entityName, status, id, className}: EntityPageTitleProps) {
return (
<div className={b(null, className)}>
<span className={b('prefix')}>{entityName}</span>
<StatusIcon className={b('icon')} status={status} size="s" />
{id}
{children}
</div>
);
}
7 changes: 0 additions & 7 deletions src/components/PDiskInfo/PDiskInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ function getPDiskInfo<T extends PreparedPDisk>({
SerialNumber,
TotalSize,
AllocatedSize,
DecommitStatus,
StatusV2,
NumActiveSlots,
ExpectedSlotCount,
Expand All @@ -58,12 +57,6 @@ function getPDiskInfo<T extends PreparedPDisk>({

const generalInfo: InfoViewerItem[] = [];

if (valueIsDefined(DecommitStatus)) {
generalInfo.push({
label: pDiskInfoKeyset('decomission-status'),
value: DecommitStatus.replace('DECOMMIT_', ''),
});
}
if (valueIsDefined(Category)) {
generalInfo.push({label: pDiskInfoKeyset('type'), value: Type});
}
Expand Down
1 change: 0 additions & 1 deletion src/components/PDiskInfo/i18n/en.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"decomission-status": "Decomission Status",
"type": "Type",
"path": "Path",
"guid": "GUID",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.ydb-pdisk-decommission-button {
&__button,
&__popup {
width: 160px;
}
}
Loading

0 comments on commit d3e5f70

Please sign in to comment.