fix confirm close dialog + add restart confirm dialog (#12761)
Test: - On upload > No dialog at modal closing - On match > Confirm cancel dialog at closing (escape, click outside, cancel cross) - On match > Restart dialog at Restart Import - On validation > Confirm cancel dialog at closing (escape, click outside, cancel cross) - On import > Confirm cancel dialog at closing (escape, click outside, cancel cross) - On import > No confirm at import end closes : https://github.com/twentyhq/core-team-issues/issues/1071
This commit is contained in:
@ -1,10 +1,5 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { useSpreadsheetImportInitialStep } from '@/spreadsheet-import/hooks/useSpreadsheetImportInitialStep';
|
|
||||||
import { useSpreadsheetImportInternal } from '@/spreadsheet-import/hooks/useSpreadsheetImportInternal';
|
|
||||||
import { useDialogManager } from '@/ui/feedback/dialog-manager/hooks/useDialogManager';
|
|
||||||
import { useStepBar } from '@/ui/navigation/step-bar/hooks/useStepBar';
|
|
||||||
import { useLingui } from '@lingui/react/macro';
|
|
||||||
import { IconX } from 'twenty-ui/display';
|
import { IconX } from 'twenty-ui/display';
|
||||||
import { IconButton } from 'twenty-ui/input';
|
import { IconButton } from 'twenty-ui/input';
|
||||||
|
|
||||||
@ -20,49 +15,15 @@ const StyledCloseButtonContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
type SpreadSheetImportModalCloseButtonProps = {
|
type SpreadSheetImportModalCloseButtonProps = {
|
||||||
onClose?: () => void;
|
onClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SpreadSheetImportModalCloseButton = ({
|
export const SpreadSheetImportModalCloseButton = ({
|
||||||
onClose,
|
onClose,
|
||||||
}: SpreadSheetImportModalCloseButtonProps) => {
|
}: SpreadSheetImportModalCloseButtonProps) => {
|
||||||
const { initialStepState } = useSpreadsheetImportInternal();
|
|
||||||
|
|
||||||
const { initialStep } = useSpreadsheetImportInitialStep(
|
|
||||||
initialStepState?.type,
|
|
||||||
);
|
|
||||||
|
|
||||||
const { activeStep } = useStepBar({
|
|
||||||
initialStep,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { enqueueDialog } = useDialogManager();
|
|
||||||
|
|
||||||
const { t } = useLingui();
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
if (activeStep === -1) {
|
|
||||||
onClose?.();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
enqueueDialog({
|
|
||||||
title: t`Exit import flow`,
|
|
||||||
message: t`Are you sure? Your current information will not be saved.`,
|
|
||||||
buttons: [
|
|
||||||
{ title: t`Cancel` },
|
|
||||||
{
|
|
||||||
title: t`Exit`,
|
|
||||||
onClick: onClose,
|
|
||||||
accent: 'danger',
|
|
||||||
role: 'confirm',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledCloseButtonContainer>
|
<StyledCloseButtonContainer>
|
||||||
<IconButton Icon={IconX} onClick={handleClose} />
|
<IconButton Icon={IconX} onClick={onClose} />
|
||||||
</StyledCloseButtonContainer>
|
</StyledCloseButtonContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const StyledRtlLtr = styled.div`
|
|||||||
type SpreadSheetImportModalWrapperProps = {
|
type SpreadSheetImportModalWrapperProps = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
modalId: string;
|
modalId: string;
|
||||||
onClose?: () => void;
|
onClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SpreadSheetImportModalWrapper = ({
|
export const SpreadSheetImportModalWrapper = ({
|
||||||
@ -44,6 +44,7 @@ export const SpreadSheetImportModalWrapper = ({
|
|||||||
modalId={modalId}
|
modalId={modalId}
|
||||||
isClosable={true}
|
isClosable={true}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
|
shouldCloseModalOnClickOutsideOrEscape={false}
|
||||||
>
|
>
|
||||||
<StyledRtlLtr dir={rtl ? 'rtl' : 'ltr'}>
|
<StyledRtlLtr dir={rtl ? 'rtl' : 'ltr'}>
|
||||||
<SpreadSheetImportModalCloseButton onClose={onClose} />
|
<SpreadSheetImportModalCloseButton onClose={onClose} />
|
||||||
|
|||||||
@ -2,8 +2,13 @@ import { ReactSpreadsheetImportContextProvider } from '@/spreadsheet-import/comp
|
|||||||
import { SpreadSheetImportModalWrapper } from '@/spreadsheet-import/components/SpreadSheetImportModalWrapper';
|
import { SpreadSheetImportModalWrapper } from '@/spreadsheet-import/components/SpreadSheetImportModalWrapper';
|
||||||
import { SPREADSHEET_IMPORT_MODAL_ID } from '@/spreadsheet-import/constants/SpreadsheetImportModalId';
|
import { SPREADSHEET_IMPORT_MODAL_ID } from '@/spreadsheet-import/constants/SpreadsheetImportModalId';
|
||||||
import { SpreadsheetMaxRecordImportCapacity } from '@/spreadsheet-import/constants/SpreadsheetMaxRecordImportCapacity';
|
import { SpreadsheetMaxRecordImportCapacity } from '@/spreadsheet-import/constants/SpreadsheetMaxRecordImportCapacity';
|
||||||
|
import { useSpreadsheetImportInitialStep } from '@/spreadsheet-import/hooks/useSpreadsheetImportInitialStep';
|
||||||
|
import { useSpreadsheetImportInternal } from '@/spreadsheet-import/hooks/useSpreadsheetImportInternal';
|
||||||
import { SpreadsheetImportStepperContainer } from '@/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer';
|
import { SpreadsheetImportStepperContainer } from '@/spreadsheet-import/steps/components/SpreadsheetImportStepperContainer';
|
||||||
import { SpreadsheetImportDialogOptions as SpreadsheetImportProps } from '@/spreadsheet-import/types';
|
import { SpreadsheetImportDialogOptions as SpreadsheetImportProps } from '@/spreadsheet-import/types';
|
||||||
|
import { useDialogManager } from '@/ui/feedback/dialog-manager/hooks/useDialogManager';
|
||||||
|
import { useStepBar } from '@/ui/navigation/step-bar/hooks/useStepBar';
|
||||||
|
import { useLingui } from '@lingui/react/macro';
|
||||||
|
|
||||||
export const defaultSpreadsheetImportProps: Partial<
|
export const defaultSpreadsheetImportProps: Partial<
|
||||||
SpreadsheetImportProps<any>
|
SpreadsheetImportProps<any>
|
||||||
@ -31,11 +36,46 @@ export const SpreadsheetImport = <T extends string>(
|
|||||||
...props,
|
...props,
|
||||||
} as SpreadsheetImportProps<T>;
|
} as SpreadsheetImportProps<T>;
|
||||||
|
|
||||||
|
const { enqueueDialog } = useDialogManager();
|
||||||
|
|
||||||
|
const { initialStepState } = useSpreadsheetImportInternal();
|
||||||
|
|
||||||
|
const { initialStep } = useSpreadsheetImportInitialStep(
|
||||||
|
initialStepState?.type,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { activeStep } = useStepBar({
|
||||||
|
initialStep,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { t } = useLingui();
|
||||||
|
|
||||||
|
const confirmOnClose = () => {
|
||||||
|
if (activeStep < 1) {
|
||||||
|
mergedProps.onClose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enqueueDialog({
|
||||||
|
title: t`Exit import flow`,
|
||||||
|
message: t`Are you sure? Your current information will not be saved.`,
|
||||||
|
buttons: [
|
||||||
|
{ title: t`Cancel` },
|
||||||
|
{
|
||||||
|
title: t`Exit`,
|
||||||
|
onClick: mergedProps.onClose,
|
||||||
|
accent: 'danger',
|
||||||
|
role: 'confirm',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactSpreadsheetImportContextProvider values={mergedProps}>
|
<ReactSpreadsheetImportContextProvider values={mergedProps}>
|
||||||
<SpreadSheetImportModalWrapper
|
<SpreadSheetImportModalWrapper
|
||||||
modalId={SPREADSHEET_IMPORT_MODAL_ID}
|
modalId={SPREADSHEET_IMPORT_MODAL_ID}
|
||||||
onClose={mergedProps.onClose}
|
onClose={confirmOnClose}
|
||||||
>
|
>
|
||||||
<SpreadsheetImportStepperContainer />
|
<SpreadsheetImportStepperContainer />
|
||||||
</SpreadSheetImportModalWrapper>
|
</SpreadSheetImportModalWrapper>
|
||||||
|
|||||||
@ -247,6 +247,27 @@ export const MatchColumnsStep = <T extends string>({
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onBackConfirmation = () => {
|
||||||
|
onBack?.();
|
||||||
|
setColumns([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openRestartDialog = () => {
|
||||||
|
enqueueDialog({
|
||||||
|
title: t`Restart Import`,
|
||||||
|
message: t`You will lose all your mappings.`,
|
||||||
|
buttons: [
|
||||||
|
{ title: t`Cancel` },
|
||||||
|
{
|
||||||
|
title: t`Restart`,
|
||||||
|
onClick: onBackConfirmation,
|
||||||
|
accent: 'danger',
|
||||||
|
role: 'confirm',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<StyledContent>
|
<StyledContent>
|
||||||
@ -282,10 +303,8 @@ export const MatchColumnsStep = <T extends string>({
|
|||||||
onContinue={handleOnContinue}
|
onContinue={handleOnContinue}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
continueTitle={t`Next Step`}
|
continueTitle={t`Next Step`}
|
||||||
onBack={() => {
|
backTitle={t`Restart Import`}
|
||||||
onBack?.();
|
onBack={openRestartDialog}
|
||||||
setColumns([]);
|
|
||||||
}}
|
|
||||||
isContinueDisabled={!hasMatchedColumns}
|
isContinueDisabled={!hasMatchedColumns}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -42,7 +42,10 @@ export default meta;
|
|||||||
export const Default = () => (
|
export const Default = () => (
|
||||||
<DialogManagerScope dialogManagerScopeId="dialog-manager">
|
<DialogManagerScope dialogManagerScopeId="dialog-manager">
|
||||||
<ReactSpreadsheetImportContextProvider values={mockRsiValues}>
|
<ReactSpreadsheetImportContextProvider values={mockRsiValues}>
|
||||||
<SpreadSheetImportModalWrapper modalId="select-header-step">
|
<SpreadSheetImportModalWrapper
|
||||||
|
modalId="select-header-step"
|
||||||
|
onClose={() => null}
|
||||||
|
>
|
||||||
<SelectHeaderStep
|
<SelectHeaderStep
|
||||||
importedRows={headerSelectionTableFields}
|
importedRows={headerSelectionTableFields}
|
||||||
setCurrentStepState={() => null}
|
setCurrentStepState={() => null}
|
||||||
|
|||||||
@ -195,6 +195,7 @@ export type ModalProps = React.PropsWithChildren & {
|
|||||||
onEnter?: () => void;
|
onEnter?: () => void;
|
||||||
modalVariant?: ModalVariants;
|
modalVariant?: ModalVariants;
|
||||||
dataGloballyPreventClickOutside?: boolean;
|
dataGloballyPreventClickOutside?: boolean;
|
||||||
|
shouldCloseModalOnClickOutsideOrEscape?: boolean;
|
||||||
} & (
|
} & (
|
||||||
| { isClosable: true; onClose?: () => void }
|
| { isClosable: true; onClose?: () => void }
|
||||||
| { isClosable?: false; onClose?: never }
|
| { isClosable?: false; onClose?: never }
|
||||||
@ -217,6 +218,7 @@ export const Modal = ({
|
|||||||
onClose,
|
onClose,
|
||||||
modalVariant = 'primary',
|
modalVariant = 'primary',
|
||||||
dataGloballyPreventClickOutside = false,
|
dataGloballyPreventClickOutside = false,
|
||||||
|
shouldCloseModalOnClickOutsideOrEscape = true,
|
||||||
}: ModalProps) => {
|
}: ModalProps) => {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const modalRef = useRef<HTMLDivElement>(null);
|
const modalRef = useRef<HTMLDivElement>(null);
|
||||||
@ -236,7 +238,7 @@ export const Modal = ({
|
|||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
onClose?.();
|
onClose?.();
|
||||||
closeModal(modalId);
|
if (shouldCloseModalOnClickOutsideOrEscape) closeModal(modalId);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user