From e0289ba9f24c30a579fdb4208156715b89d9523a Mon Sep 17 00:00:00 2001 From: bosiraphael <71827178+bosiraphael@users.noreply.github.com> Date: Fri, 10 Nov 2023 12:36:25 +0100 Subject: [PATCH] 2363 refactor the dialog component to use the new scope architecture (#2415) * create Scope * refactor dialog manager * finished refactoring * modify closeDialog to use a recoilcallback * modify according to comments + add effet component * fix spreadsheet import stories --- front/src/index.tsx | 15 +++-- .../components/ModalCloseButton.tsx | 4 +- .../MatchColumnsStep/MatchColumnsStep.tsx | 4 +- .../ValidationStep/ValidationStep.tsx | 4 +- .../__stories__/MatchColumns.stories.tsx | 21 ++++--- .../__stories__/SelectHeader.stories.tsx | 19 +++--- .../__stories__/SelectSheet.stories.tsx | 19 +++--- .../components/__stories__/Upload.stories.tsx | 13 ++-- .../__stories__/Validation.stories.tsx | 13 ++-- .../components/Dialog.tsx | 0 .../components/DialogManager.tsx | 24 +++++++ .../components/DialogManagerEffect.tsx | 22 +++++++ .../internal/useDialogManagerScopedStates.ts | 25 ++++++++ .../dialog-manager/hooks/useDialogManager.ts | 62 +++++++++++++++++++ .../scopes/DialogManagerScope.tsx | 23 +++++++ .../DialogManagerScopeInternalContext.ts | 7 +++ .../states/dialogInternalScopedState.ts | 16 +++++ .../types/DialogHotkeyScope.ts | 0 .../dialog-manager/types/DialogOptions.ts | 5 ++ .../dialog/components/DialogProvider.tsx | 49 --------------- .../ui/feedback/dialog/hooks/useDialog.ts | 17 ----- .../ui/feedback/dialog/states/dialogState.ts | 39 ------------ 22 files changed, 249 insertions(+), 152 deletions(-) rename front/src/modules/ui/feedback/{dialog => dialog-manager}/components/Dialog.tsx (100%) create mode 100644 front/src/modules/ui/feedback/dialog-manager/components/DialogManager.tsx create mode 100644 front/src/modules/ui/feedback/dialog-manager/components/DialogManagerEffect.tsx create mode 100644 front/src/modules/ui/feedback/dialog-manager/hooks/internal/useDialogManagerScopedStates.ts create mode 100644 front/src/modules/ui/feedback/dialog-manager/hooks/useDialogManager.ts create mode 100644 front/src/modules/ui/feedback/dialog-manager/scopes/DialogManagerScope.tsx create mode 100644 front/src/modules/ui/feedback/dialog-manager/scopes/scope-internal-context/DialogManagerScopeInternalContext.ts create mode 100644 front/src/modules/ui/feedback/dialog-manager/states/dialogInternalScopedState.ts rename front/src/modules/ui/feedback/{dialog => dialog-manager}/types/DialogHotkeyScope.ts (100%) create mode 100644 front/src/modules/ui/feedback/dialog-manager/types/DialogOptions.ts delete mode 100644 front/src/modules/ui/feedback/dialog/components/DialogProvider.tsx delete mode 100644 front/src/modules/ui/feedback/dialog/hooks/useDialog.ts delete mode 100644 front/src/modules/ui/feedback/dialog/states/dialogState.ts diff --git a/front/src/index.tsx b/front/src/index.tsx index 2a58dabae..73701a023 100644 --- a/front/src/index.tsx +++ b/front/src/index.tsx @@ -7,7 +7,8 @@ import { RecoilRoot } from 'recoil'; import { ApolloProvider } from '@/apollo/components/ApolloProvider'; import { ClientConfigProvider } from '@/client-config/components/ClientConfigProvider'; import { RecoilDebugObserverEffect } from '@/debug/components/RecoilDebugObserver'; -import { DialogProvider } from '@/ui/feedback/dialog/components/DialogProvider'; +import { DialogManager } from '@/ui/feedback/dialog-manager/components/DialogManager'; +import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope'; import { SnackBarProvider } from '@/ui/feedback/snack-bar/components/SnackBarProvider'; import { AppThemeProvider } from '@/ui/theme/components/AppThemeProvider'; import { ThemeType } from '@/ui/theme/constants/theme'; @@ -38,11 +39,13 @@ root.render( - - - - - + + + + + + + diff --git a/front/src/modules/spreadsheet-import/components/ModalCloseButton.tsx b/front/src/modules/spreadsheet-import/components/ModalCloseButton.tsx index d8593bb17..e58837010 100644 --- a/front/src/modules/spreadsheet-import/components/ModalCloseButton.tsx +++ b/front/src/modules/spreadsheet-import/components/ModalCloseButton.tsx @@ -3,7 +3,7 @@ import styled from '@emotion/styled'; import { useSpreadsheetImportInitialStep } from '@/spreadsheet-import/hooks/useSpreadsheetImportInitialStep'; import { useSpreadsheetImportInternal } from '@/spreadsheet-import/hooks/useSpreadsheetImportInternal'; import { IconX } from '@/ui/display/icon/index'; -import { useDialog } from '@/ui/feedback/dialog//hooks/useDialog'; +import { useDialogManager } from '@/ui/feedback/dialog-manager/hooks/useDialogManager'; import { IconButton } from '@/ui/input/button/components/IconButton'; import { useStepBar } from '@/ui/navigation/step-bar/hooks/useStepBar'; @@ -33,7 +33,7 @@ export const ModalCloseButton = ({ onClose }: ModalCloseButtonProps) => { initialStep, }); - const { enqueueDialog } = useDialog(); + const { enqueueDialog } = useDialogManager(); const handleClose = () => { if (activeStep === -1) { diff --git a/front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx b/front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx index 46c5bd8fb..55f962f08 100644 --- a/front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx +++ b/front/src/modules/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep.tsx @@ -11,7 +11,7 @@ import { normalizeTableData } from '@/spreadsheet-import/utils/normalizeTableDat import { setColumn } from '@/spreadsheet-import/utils/setColumn'; import { setIgnoreColumn } from '@/spreadsheet-import/utils/setIgnoreColumn'; import { setSubColumn } from '@/spreadsheet-import/utils/setSubColumn'; -import { useDialog } from '@/ui/feedback/dialog//hooks/useDialog'; +import { useDialogManager } from '@/ui/feedback/dialog-manager/hooks/useDialogManager'; import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar'; import { Modal } from '@/ui/layout/modal/components/Modal'; @@ -112,7 +112,7 @@ export const MatchColumnsStep = ({ headerValues, onContinue, }: MatchColumnsStepProps) => { - const { enqueueDialog } = useDialog(); + const { enqueueDialog } = useDialogManager(); const { enqueueSnackBar } = useSnackBar(); const dataExample = data.slice(0, 2); const { fields, autoMapHeaders, autoMapDistance } = diff --git a/front/src/modules/spreadsheet-import/steps/components/ValidationStep/ValidationStep.tsx b/front/src/modules/spreadsheet-import/steps/components/ValidationStep/ValidationStep.tsx index 75085649f..7e2ff4ef5 100644 --- a/front/src/modules/spreadsheet-import/steps/components/ValidationStep/ValidationStep.tsx +++ b/front/src/modules/spreadsheet-import/steps/components/ValidationStep/ValidationStep.tsx @@ -9,7 +9,7 @@ import { useSpreadsheetImportInternal } from '@/spreadsheet-import/hooks/useSpre import { Data } from '@/spreadsheet-import/types'; import { addErrorsAndRunHooks } from '@/spreadsheet-import/utils/dataMutations'; import { IconTrash } from '@/ui/display/icon'; -import { useDialog } from '@/ui/feedback/dialog//hooks/useDialog'; +import { useDialogManager } from '@/ui/feedback/dialog-manager/hooks/useDialogManager'; import { Button } from '@/ui/input/button/components/Button'; import { Toggle } from '@/ui/input/components/Toggle'; import { Modal } from '@/ui/layout/modal/components/Modal'; @@ -69,7 +69,7 @@ export const ValidationStep = ({ file, onSubmitStart, }: ValidationStepProps) => { - const { enqueueDialog } = useDialog(); + const { enqueueDialog } = useDialogManager(); const { fields, onClose, onSubmit, rowHook, tableHook } = useSpreadsheetImportInternal(); diff --git a/front/src/modules/spreadsheet-import/steps/components/__stories__/MatchColumns.stories.tsx b/front/src/modules/spreadsheet-import/steps/components/__stories__/MatchColumns.stories.tsx index a0ee07056..f97189d7d 100644 --- a/front/src/modules/spreadsheet-import/steps/components/__stories__/MatchColumns.stories.tsx +++ b/front/src/modules/spreadsheet-import/steps/components/__stories__/MatchColumns.stories.tsx @@ -4,6 +4,7 @@ import { ModalWrapper } from '@/spreadsheet-import/components/ModalWrapper'; import { Providers } from '@/spreadsheet-import/components/Providers'; import { MatchColumnsStep } from '@/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep'; import { mockRsiValues } from '@/spreadsheet-import/tests/mockRsiValues'; +import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope'; const meta: Meta = { title: 'Modules/SpreadsheetImport/MatchColumnsStep', @@ -57,13 +58,15 @@ const mockData = [ ]; export const Default = () => ( - - null}> - null} - /> - - + + + null}> + null} + /> + + + ); diff --git a/front/src/modules/spreadsheet-import/steps/components/__stories__/SelectHeader.stories.tsx b/front/src/modules/spreadsheet-import/steps/components/__stories__/SelectHeader.stories.tsx index 8a28599df..45f700833 100644 --- a/front/src/modules/spreadsheet-import/steps/components/__stories__/SelectHeader.stories.tsx +++ b/front/src/modules/spreadsheet-import/steps/components/__stories__/SelectHeader.stories.tsx @@ -7,6 +7,7 @@ import { headerSelectionTableFields, mockRsiValues, } from '@/spreadsheet-import/tests/mockRsiValues'; +import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope'; const meta: Meta = { title: 'Modules/SpreadsheetImport/SelectHeaderStep', @@ -19,12 +20,14 @@ const meta: Meta = { export default meta; export const Default = () => ( - - null}> - Promise.resolve()} - /> - - + + + null}> + Promise.resolve()} + /> + + + ); diff --git a/front/src/modules/spreadsheet-import/steps/components/__stories__/SelectSheet.stories.tsx b/front/src/modules/spreadsheet-import/steps/components/__stories__/SelectSheet.stories.tsx index 4ec059c66..54c2e0034 100644 --- a/front/src/modules/spreadsheet-import/steps/components/__stories__/SelectSheet.stories.tsx +++ b/front/src/modules/spreadsheet-import/steps/components/__stories__/SelectSheet.stories.tsx @@ -4,6 +4,7 @@ import { ModalWrapper } from '@/spreadsheet-import/components/ModalWrapper'; import { Providers } from '@/spreadsheet-import/components/Providers'; import { SelectSheetStep } from '@/spreadsheet-import/steps/components/SelectSheetStep/SelectSheetStep'; import { mockRsiValues } from '@/spreadsheet-import/tests/mockRsiValues'; +import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope'; const meta: Meta = { title: 'Modules/SpreadsheetImport/SelectSheetStep', @@ -18,12 +19,14 @@ export default meta; const sheetNames = ['Sheet1', 'Sheet2', 'Sheet3']; export const Default = () => ( - - null}> - Promise.resolve()} - /> - - + + + null}> + Promise.resolve()} + /> + + + ); diff --git a/front/src/modules/spreadsheet-import/steps/components/__stories__/Upload.stories.tsx b/front/src/modules/spreadsheet-import/steps/components/__stories__/Upload.stories.tsx index 8ff0b5808..ed449c310 100644 --- a/front/src/modules/spreadsheet-import/steps/components/__stories__/Upload.stories.tsx +++ b/front/src/modules/spreadsheet-import/steps/components/__stories__/Upload.stories.tsx @@ -4,6 +4,7 @@ import { ModalWrapper } from '@/spreadsheet-import/components/ModalWrapper'; import { Providers } from '@/spreadsheet-import/components/Providers'; import { UploadStep } from '@/spreadsheet-import/steps/components/UploadStep/UploadStep'; import { mockRsiValues } from '@/spreadsheet-import/tests/mockRsiValues'; +import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope'; const meta: Meta = { title: 'Modules/SpreadsheetImport/UploadStep', @@ -16,9 +17,11 @@ const meta: Meta = { export default meta; export const Default = () => ( - - null}> - Promise.resolve()} /> - - + + + null}> + Promise.resolve()} /> + + + ); diff --git a/front/src/modules/spreadsheet-import/steps/components/__stories__/Validation.stories.tsx b/front/src/modules/spreadsheet-import/steps/components/__stories__/Validation.stories.tsx index 32fc9547b..641df1ea9 100644 --- a/front/src/modules/spreadsheet-import/steps/components/__stories__/Validation.stories.tsx +++ b/front/src/modules/spreadsheet-import/steps/components/__stories__/Validation.stories.tsx @@ -7,6 +7,7 @@ import { editableTableInitialData, mockRsiValues, } from '@/spreadsheet-import/tests/mockRsiValues'; +import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope'; const meta: Meta = { title: 'Modules/SpreadsheetImport/ValidationStep', @@ -21,9 +22,11 @@ export default meta; const file = new File([''], 'file.csv'); export const Default = () => ( - - null}> - - - + + + null}> + + + + ); diff --git a/front/src/modules/ui/feedback/dialog/components/Dialog.tsx b/front/src/modules/ui/feedback/dialog-manager/components/Dialog.tsx similarity index 100% rename from front/src/modules/ui/feedback/dialog/components/Dialog.tsx rename to front/src/modules/ui/feedback/dialog-manager/components/Dialog.tsx diff --git a/front/src/modules/ui/feedback/dialog-manager/components/DialogManager.tsx b/front/src/modules/ui/feedback/dialog-manager/components/DialogManager.tsx new file mode 100644 index 000000000..cf8040f51 --- /dev/null +++ b/front/src/modules/ui/feedback/dialog-manager/components/DialogManager.tsx @@ -0,0 +1,24 @@ +import { useDialogManagerScopedStates } from '../hooks/internal/useDialogManagerScopedStates'; +import { useDialogManager } from '../hooks/useDialogManager'; + +import { Dialog } from './Dialog'; +import { DialogManagerEffect } from './DialogManagerEffect'; + +export const DialogManager = ({ children }: React.PropsWithChildren) => { + const { dialogInternal } = useDialogManagerScopedStates(); + const { closeDialog } = useDialogManager(); + + return ( + <> + + {children} + {dialogInternal.queue.map(({ buttons, children, id, message, title }) => ( + closeDialog(id)} + /> + ))} + + ); +}; diff --git a/front/src/modules/ui/feedback/dialog-manager/components/DialogManagerEffect.tsx b/front/src/modules/ui/feedback/dialog-manager/components/DialogManagerEffect.tsx new file mode 100644 index 000000000..b4f85c41d --- /dev/null +++ b/front/src/modules/ui/feedback/dialog-manager/components/DialogManagerEffect.tsx @@ -0,0 +1,22 @@ +import { useEffect } from 'react'; + +import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; + +import { useDialogManagerScopedStates } from '../hooks/internal/useDialogManagerScopedStates'; +import { DialogHotkeyScope } from '../types/DialogHotkeyScope'; + +export const DialogManagerEffect = () => { + const { dialogInternal } = useDialogManagerScopedStates(); + + const { setHotkeyScopeAndMemorizePreviousScope } = usePreviousHotkeyScope(); + + useEffect(() => { + if (dialogInternal.queue.length === 0) { + return; + } + + setHotkeyScopeAndMemorizePreviousScope(DialogHotkeyScope.Dialog); + }, [dialogInternal.queue, setHotkeyScopeAndMemorizePreviousScope]); + + return <>; +}; diff --git a/front/src/modules/ui/feedback/dialog-manager/hooks/internal/useDialogManagerScopedStates.ts b/front/src/modules/ui/feedback/dialog-manager/hooks/internal/useDialogManagerScopedStates.ts new file mode 100644 index 000000000..f032f25b4 --- /dev/null +++ b/front/src/modules/ui/feedback/dialog-manager/hooks/internal/useDialogManagerScopedStates.ts @@ -0,0 +1,25 @@ +import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2'; +import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; + +import { DialogManagerScopeInternalContext } from '../../scopes/scope-internal-context/DialogManagerScopeInternalContext'; +import { dialogInternalScopedState } from '../../states/dialogInternalScopedState'; + +type useDialogManagerScopedStatesProps = { + dialogManagerScopeId?: string; +}; + +export const useDialogManagerScopedStates = ( + props?: useDialogManagerScopedStatesProps, +) => { + const scopeId = useAvailableScopeIdOrThrow( + DialogManagerScopeInternalContext, + props?.dialogManagerScopeId, + ); + + const [dialogInternal, setDialogInternal] = useRecoilScopedStateV2( + dialogInternalScopedState, + scopeId, + ); + + return { dialogInternal, setDialogInternal }; +}; diff --git a/front/src/modules/ui/feedback/dialog-manager/hooks/useDialogManager.ts b/front/src/modules/ui/feedback/dialog-manager/hooks/useDialogManager.ts new file mode 100644 index 000000000..84ce4187e --- /dev/null +++ b/front/src/modules/ui/feedback/dialog-manager/hooks/useDialogManager.ts @@ -0,0 +1,62 @@ +import { useRecoilCallback } from 'recoil'; +import { v4 } from 'uuid'; + +import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; +import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; + +import { DialogManagerScopeInternalContext } from '../scopes/scope-internal-context/DialogManagerScopeInternalContext'; +import { dialogInternalScopedState } from '../states/dialogInternalScopedState'; +import { DialogOptions } from '../types/DialogOptions'; + +type useDialogManagerProps = { + dialogManagerScopeId?: string; +}; + +export const useDialogManager = (props?: useDialogManagerProps) => { + const scopeId = useAvailableScopeIdOrThrow( + DialogManagerScopeInternalContext, + props?.dialogManagerScopeId, + ); + + const { goBackToPreviousHotkeyScope } = usePreviousHotkeyScope(); + + const closeDialog = useRecoilCallback( + ({ set }) => + (id: string) => { + set(dialogInternalScopedState({ scopeId: scopeId }), (prevState) => ({ + ...prevState, + queue: prevState.queue.filter((snackBar) => snackBar.id !== id), + })); + goBackToPreviousHotkeyScope(); + }, + [goBackToPreviousHotkeyScope, scopeId], + ); + + const setDialogQueue = useRecoilCallback( + ({ set }) => + (newValue) => + set(dialogInternalScopedState({ scopeId: scopeId }), (prev) => { + if (prev.queue.length >= prev.maxQueue) { + return { + ...prev, + queue: [...prev.queue.slice(1), newValue] as DialogOptions[], + }; + } + + return { + ...prev, + queue: [...prev.queue, newValue] as DialogOptions[], + }; + }), + [scopeId], + ); + + const enqueueDialog = (options?: Omit) => { + setDialogQueue({ + id: v4(), + ...options, + }); + }; + + return { closeDialog, enqueueDialog }; +}; diff --git a/front/src/modules/ui/feedback/dialog-manager/scopes/DialogManagerScope.tsx b/front/src/modules/ui/feedback/dialog-manager/scopes/DialogManagerScope.tsx new file mode 100644 index 000000000..cc44570f5 --- /dev/null +++ b/front/src/modules/ui/feedback/dialog-manager/scopes/DialogManagerScope.tsx @@ -0,0 +1,23 @@ +import { ReactNode } from 'react'; + +import { DialogManagerScopeInternalContext } from './scope-internal-context/DialogManagerScopeInternalContext'; + +type DialogManagerScopeProps = { + children: ReactNode; + dialogManagerScopeId: string; +}; + +export const DialogManagerScope = ({ + children, + dialogManagerScopeId, +}: DialogManagerScopeProps) => { + return ( + + {children} + + ); +}; diff --git a/front/src/modules/ui/feedback/dialog-manager/scopes/scope-internal-context/DialogManagerScopeInternalContext.ts b/front/src/modules/ui/feedback/dialog-manager/scopes/scope-internal-context/DialogManagerScopeInternalContext.ts new file mode 100644 index 000000000..346dcc5fb --- /dev/null +++ b/front/src/modules/ui/feedback/dialog-manager/scopes/scope-internal-context/DialogManagerScopeInternalContext.ts @@ -0,0 +1,7 @@ +import { ScopedStateKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/ScopedStateKey'; +import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext'; + +type DialogManagerScopeInternalContextProps = ScopedStateKey; + +export const DialogManagerScopeInternalContext = + createScopeInternalContext(); diff --git a/front/src/modules/ui/feedback/dialog-manager/states/dialogInternalScopedState.ts b/front/src/modules/ui/feedback/dialog-manager/states/dialogInternalScopedState.ts new file mode 100644 index 000000000..797e07c62 --- /dev/null +++ b/front/src/modules/ui/feedback/dialog-manager/states/dialogInternalScopedState.ts @@ -0,0 +1,16 @@ +import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState'; + +import { DialogOptions } from '../types/DialogOptions'; + +type DialogState = { + maxQueue: number; + queue: DialogOptions[]; +}; + +export const dialogInternalScopedState = createScopedState({ + key: 'dialog/internal-state', + defaultValue: { + maxQueue: 2, + queue: [], + }, +}); diff --git a/front/src/modules/ui/feedback/dialog/types/DialogHotkeyScope.ts b/front/src/modules/ui/feedback/dialog-manager/types/DialogHotkeyScope.ts similarity index 100% rename from front/src/modules/ui/feedback/dialog/types/DialogHotkeyScope.ts rename to front/src/modules/ui/feedback/dialog-manager/types/DialogHotkeyScope.ts diff --git a/front/src/modules/ui/feedback/dialog-manager/types/DialogOptions.ts b/front/src/modules/ui/feedback/dialog-manager/types/DialogOptions.ts new file mode 100644 index 000000000..1071b0a9e --- /dev/null +++ b/front/src/modules/ui/feedback/dialog-manager/types/DialogOptions.ts @@ -0,0 +1,5 @@ +import { DialogProps } from '../components/Dialog'; + +export type DialogOptions = DialogProps & { + id: string; +}; diff --git a/front/src/modules/ui/feedback/dialog/components/DialogProvider.tsx b/front/src/modules/ui/feedback/dialog/components/DialogProvider.tsx deleted file mode 100644 index 19e4fec64..000000000 --- a/front/src/modules/ui/feedback/dialog/components/DialogProvider.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { useEffect } from 'react'; -import { useRecoilState } from 'recoil'; - -import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; - -import { dialogInternalState } from '../states/dialogState'; -import { DialogHotkeyScope } from '../types/DialogHotkeyScope'; - -import { Dialog } from './Dialog'; - -export const DialogProvider = ({ children }: React.PropsWithChildren) => { - const [dialogInternal, setDialogInternal] = - useRecoilState(dialogInternalState); - - const { - setHotkeyScopeAndMemorizePreviousScope, - goBackToPreviousHotkeyScope, - } = usePreviousHotkeyScope(); - - // Handle dialog close event - const handleDialogClose = (id: string) => { - setDialogInternal((prevState) => ({ - ...prevState, - queue: prevState.queue.filter((snackBar) => snackBar.id !== id), - })); - goBackToPreviousHotkeyScope(); - }; - - useEffect(() => { - if (dialogInternal.queue.length === 0) { - return; - } - - setHotkeyScopeAndMemorizePreviousScope(DialogHotkeyScope.Dialog); - }, [dialogInternal.queue, setHotkeyScopeAndMemorizePreviousScope]); - - return ( - <> - {children} - {dialogInternal.queue.map(({ buttons, children, id, message, title }) => ( - handleDialogClose(id)} - /> - ))} - - ); -}; diff --git a/front/src/modules/ui/feedback/dialog/hooks/useDialog.ts b/front/src/modules/ui/feedback/dialog/hooks/useDialog.ts deleted file mode 100644 index 2827a97ca..000000000 --- a/front/src/modules/ui/feedback/dialog/hooks/useDialog.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { useSetRecoilState } from 'recoil'; -import { v4 as uuidv4 } from 'uuid'; - -import { DialogOptions, dialogSetQueueState } from '../states/dialogState'; - -export const useDialog = () => { - const setDialogQueue = useSetRecoilState(dialogSetQueueState); - - const enqueueDialog = (options?: Omit) => { - setDialogQueue({ - id: uuidv4(), - ...options, - }); - }; - - return { enqueueDialog }; -}; diff --git a/front/src/modules/ui/feedback/dialog/states/dialogState.ts b/front/src/modules/ui/feedback/dialog/states/dialogState.ts deleted file mode 100644 index 10e877c09..000000000 --- a/front/src/modules/ui/feedback/dialog/states/dialogState.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { atom, selector } from 'recoil'; - -import { DialogProps } from '../components/Dialog'; - -export type DialogOptions = DialogProps & { - id: string; -}; - -export type DialogState = { - maxQueue: number; - queue: DialogOptions[]; -}; - -export const dialogInternalState = atom({ - key: 'dialog/internal-state', - default: { - maxQueue: 2, - queue: [], - }, -}); - -export const dialogSetQueueState = selector({ - key: 'dialog/queue-state', - get: ({ get: _get }) => null, // We don't care about getting the value - set: ({ set }, newValue) => - set(dialogInternalState, (prev) => { - if (prev.queue.length >= prev.maxQueue) { - return { - ...prev, - queue: [...prev.queue.slice(1), newValue] as DialogOptions[], - }; - } - - return { - ...prev, - queue: [...prev.queue, newValue] as DialogOptions[], - }; - }), -});