From 8054c39db0f8591c19785a890199eb012dbbb32f Mon Sep 17 00:00:00 2001 From: Elena Makarova Date: Fri, 15 Nov 2024 15:25:46 +0300 Subject: [PATCH] feat(ConfirmationDialog): add saving query before replace --- .../ConfirmationDialog.scss | 3 +- .../ConfirmationDialog/ConfirmationDialog.tsx | 12 ++-- .../QueryEditorControls.tsx | 2 +- .../Tenant/Query/SaveQuery/SaveQuery.tsx | 57 ++++++++++++------- src/utils/hooks/withConfirmation/i18n/en.json | 4 +- ....ts => useChangeInputWithConfirmation.tsx} | 37 ++++++++++++ 6 files changed, 88 insertions(+), 27 deletions(-) rename src/utils/hooks/withConfirmation/{useChangeInputWithConfirmation.ts => useChangeInputWithConfirmation.tsx} (52%) diff --git a/src/components/ConfirmationDialog/ConfirmationDialog.scss b/src/components/ConfirmationDialog/ConfirmationDialog.scss index 44fce835c0..3d6047d517 100644 --- a/src/components/ConfirmationDialog/ConfirmationDialog.scss +++ b/src/components/ConfirmationDialog/ConfirmationDialog.scss @@ -1,5 +1,6 @@ .confirmation-dialog { - &__message { + &__message, + &__caption { white-space: pre-wrap; } } diff --git a/src/components/ConfirmationDialog/ConfirmationDialog.tsx b/src/components/ConfirmationDialog/ConfirmationDialog.tsx index 0b4f47e689..ce3655232e 100644 --- a/src/components/ConfirmationDialog/ConfirmationDialog.tsx +++ b/src/components/ConfirmationDialog/ConfirmationDialog.tsx @@ -1,5 +1,7 @@ +import React from 'react'; + import * as NiceModal from '@ebay/nice-modal-react'; -import type {ButtonView} from '@gravity-ui/uikit'; +import type {ButtonView, DialogFooterProps} from '@gravity-ui/uikit'; import {Dialog} from '@gravity-ui/uikit'; import {cn} from '../../utils/cn'; @@ -23,11 +25,11 @@ interface CommonDialogProps { onConfirm?: () => void; } -interface ConfirmationDialogNiceModalProps extends CommonDialogProps { +interface ConfirmationDialogNiceModalProps extends CommonDialogProps, DialogFooterProps { onClose?: () => void; } -interface ConfirmationDialogProps extends CommonDialogProps { +interface ConfirmationDialogProps extends CommonDialogProps, DialogFooterProps { onClose: () => void; open: boolean; children?: React.ReactNode; @@ -44,6 +46,7 @@ function ConfirmationDialog({ textButtonCancel, buttonApplyView = 'normal', className, + renderButtons, open, }: ConfirmationDialogProps) { return ( @@ -54,7 +57,7 @@ function ConfirmationDialog({ disableOutsideClick open={open} > - + {caption}} /> {children} ); diff --git a/src/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.tsx b/src/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.tsx index 64d252c953..a662edf418 100644 --- a/src/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.tsx +++ b/src/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.tsx @@ -110,7 +110,7 @@ export const QueryEditorControls = ({
- +
); diff --git a/src/containers/Tenant/Query/SaveQuery/SaveQuery.tsx b/src/containers/Tenant/Query/SaveQuery/SaveQuery.tsx index ae38233098..6897ee0f4a 100644 --- a/src/containers/Tenant/Query/SaveQuery/SaveQuery.tsx +++ b/src/containers/Tenant/Query/SaveQuery/SaveQuery.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import type {ButtonProps} from '@gravity-ui/uikit'; import {Button, Dialog, DropdownMenu, TextInput} from '@gravity-ui/uikit'; import { @@ -20,31 +21,38 @@ import './SaveQuery.scss'; const b = cn('ydb-save-query'); interface SaveQueryProps { - isSaveButtonDisabled?: boolean; + buttonProps?: ButtonProps; } -export function SaveQuery({isSaveButtonDisabled}: SaveQueryProps) { +function useSaveQueryHandler() { const dispatch = useTypedDispatch(); - const queryNameToEdit = useTypedSelector(selectQueryName); - - const onSaveQueryClick = () => { + const onSaveQueryClick = React.useCallback(() => { dispatch(setQueryAction('save')); dispatch(clearQueryNameToEdit()); - }; + }, [dispatch]); + + return onSaveQueryClick; +} + +export function SaveQueryButton(props: ButtonProps) { + const onSaveQueryClick = useSaveQueryHandler(); + return ( + + ); +} + +export function SaveQuery({buttonProps = {}}: SaveQueryProps) { + const dispatch = useTypedDispatch(); + const queryNameToEdit = useTypedSelector(selectQueryName); + const onSaveQueryClick = useSaveQueryHandler(); const onEditQueryClick = () => { dispatch(saveQuery(queryNameToEdit)); dispatch(clearQueryNameToEdit()); }; - const renderSaveButton = () => { - return ( - - ); - }; - const renderSaveDropdownMenu = () => { const items = [ { @@ -60,7 +68,7 @@ export function SaveQuery({isSaveButtonDisabled}: SaveQueryProps) { ( - )} @@ -69,10 +77,15 @@ export function SaveQuery({isSaveButtonDisabled}: SaveQueryProps) { ); }; - return queryNameToEdit ? renderSaveDropdownMenu() : renderSaveButton(); + return queryNameToEdit ? renderSaveDropdownMenu() : ; } -export function SaveQueryDialog() { +interface SaveQueryDialogProps { + onSuccess?: () => void; + onCancel?: () => void; +} + +export function SaveQueryDialog({onSuccess, onCancel}: SaveQueryDialogProps) { const savedQueries = useSavedQueries(); const dispatch = useTypedDispatch(); const queryAction = useTypedSelector(selectQueryAction); @@ -95,6 +108,11 @@ export function SaveQueryDialog() { setValidationError(undefined); }; + const onCloseWithoutSave = () => { + onCancel?.(); + onCloseDialog(); + }; + const handleQueryNameChange = (value: string) => { setQueryName(value); setValidationError(undefined); @@ -103,6 +121,7 @@ export function SaveQueryDialog() { const onSaveClick = () => { dispatch(saveQuery(queryName)); onCloseDialog(); + onSuccess?.(); }; return ( @@ -110,7 +129,7 @@ export function SaveQueryDialog() { open={queryAction === 'save'} hasCloseButton={false} size="s" - onClose={onCloseDialog} + onClose={onCloseWithoutSave} >
{ + modal.hide(); + modal.remove(); + }; + const handleSaveQuerySuccess = () => { + modal.resolve(true); + closeModal(); + }; + const handleCancelQuerySave = () => { + modal.resolve(false); + closeModal(); + }; + return ( + + + + + ); +} + export async function getConfirmation(): Promise { return await NiceModal.show(CONFIRMATION_DIALOG, { id: CONFIRMATION_DIALOG, caption: i18n('context_unsaved-changes-warning'), textButtonApply: i18n('action_apply'), + propsButtonApply: {view: 'l'}, + renderButtons: (buttonApply: React.ReactNode, buttonCancel: React.ReactNode) => { + return ( + + {buttonCancel} + + {buttonApply} + + ); + }, }); }