From e830a095b809044502a527e8309061f73678b911 Mon Sep 17 00:00:00 2001 From: Davor Date: Tue, 19 Jul 2022 16:47:50 +0200 Subject: [PATCH] added steps modal with next and previous buttons - changes for improve app access setting flow --- .../Modal/StepsModal/StepsModal.tsx | 143 ++++++++++++++++++ src/components/Modal/StepsModal/index.ts | 1 + src/components/Modal/StepsModal/types.ts | 16 ++ src/components/Modal/index.ts | 1 + .../ProgressSteps.tsx | 0 .../{Steps => ProgressSteps}/index.ts | 0 .../{Steps => ProgressSteps}/types.ts | 0 src/components/UserModal/UserModal.tsx | 2 + src/components/index.ts | 4 +- .../MultipleUsersModal/MultipleUsersModal.tsx | 33 +++- src/services/users/redux/actions.ts | 21 +-- src/services/users/transformations.ts | 5 +- 12 files changed, 200 insertions(+), 26 deletions(-) create mode 100644 src/components/Modal/StepsModal/StepsModal.tsx create mode 100644 src/components/Modal/StepsModal/index.ts create mode 100644 src/components/Modal/StepsModal/types.ts rename src/components/{Steps => ProgressSteps}/ProgressSteps.tsx (100%) rename src/components/{Steps => ProgressSteps}/index.ts (100%) rename src/components/{Steps => ProgressSteps}/types.ts (100%) diff --git a/src/components/Modal/StepsModal/StepsModal.tsx b/src/components/Modal/StepsModal/StepsModal.tsx new file mode 100644 index 0000000..7e2135b --- /dev/null +++ b/src/components/Modal/StepsModal/StepsModal.tsx @@ -0,0 +1,143 @@ +import React, { Fragment, useRef } from 'react'; +import { Dialog, Transition } from '@headlessui/react'; +import { XIcon } from '@heroicons/react/solid'; +import { StepsModalProps } from './types'; + +export const StepsModal: React.FC = ({ + open, + onClose, + onSave, + onNext, + onPrevious, + children, + title = '', + useCancelButton = false, + isLoading = false, + leftActions = <>, + showSaveButton = false, + showPreviousButton = false, + saveButtonDisabled = false, +}) => { + const cancelButtonRef = useRef(null); + const saveButtonRef = useRef(null); + const nextButtonRef = useRef(null); + const previousButtonRef = useRef(null); + + return ( + + {}}> +
+ + + + + {/* This element is to trick the browser into centering the modal contents. */} + + +
+ {isLoading && ( + + + + + + + )} + + {!useCancelButton && ( +
+
{title}
+ +
+ )} + +
{children}
+
+ {leftActions} +
+ {showSaveButton && onSave && ( + + )} + {!showSaveButton && ( + + )} + {showPreviousButton && ( + + )} + {useCancelButton && ( + + )} +
+
+
+
+
+
+
+ ); +}; diff --git a/src/components/Modal/StepsModal/index.ts b/src/components/Modal/StepsModal/index.ts new file mode 100644 index 0000000..7c9bae5 --- /dev/null +++ b/src/components/Modal/StepsModal/index.ts @@ -0,0 +1 @@ +export { StepsModal } from './StepsModal'; diff --git a/src/components/Modal/StepsModal/types.ts b/src/components/Modal/StepsModal/types.ts new file mode 100644 index 0000000..f0b5bbd --- /dev/null +++ b/src/components/Modal/StepsModal/types.ts @@ -0,0 +1,16 @@ +import React from 'react'; + +export type StepsModalProps = { + open: boolean; + onClose: () => void; + onNext: () => void; + onPrevious: () => void; + title?: string; + onSave?: () => void; + useCancelButton?: boolean; + isLoading?: boolean; + leftActions?: React.ReactNode; + showSaveButton?: boolean; + showPreviousButton?: boolean; + saveButtonDisabled?: boolean; +}; diff --git a/src/components/Modal/index.ts b/src/components/Modal/index.ts index 4ef3e38..e5800df 100644 --- a/src/components/Modal/index.ts +++ b/src/components/Modal/index.ts @@ -1,2 +1,3 @@ export { ConfirmationModal } from './ConfirmationModal'; export { Modal } from './Modal'; +export { StepsModal } from './StepsModal'; diff --git a/src/components/Steps/ProgressSteps.tsx b/src/components/ProgressSteps/ProgressSteps.tsx similarity index 100% rename from src/components/Steps/ProgressSteps.tsx rename to src/components/ProgressSteps/ProgressSteps.tsx diff --git a/src/components/Steps/index.ts b/src/components/ProgressSteps/index.ts similarity index 100% rename from src/components/Steps/index.ts rename to src/components/ProgressSteps/index.ts diff --git a/src/components/Steps/types.ts b/src/components/ProgressSteps/types.ts similarity index 100% rename from src/components/Steps/types.ts rename to src/components/ProgressSteps/types.ts diff --git a/src/components/UserModal/UserModal.tsx b/src/components/UserModal/UserModal.tsx index 0993b94..404db4b 100644 --- a/src/components/UserModal/UserModal.tsx +++ b/src/components/UserModal/UserModal.tsx @@ -68,6 +68,8 @@ export const UserModal = ({ open, onClose, userId, setUserId }: UserModalProps) setAdminRoleSelected(isAdminDashboardRoleSelected); if (isAdminDashboardRoleSelected) { fields.forEach((field, index) => update(index, { name: field.name, role: UserRole.Admin })); + } else { + fields.forEach((field, index) => update(index, { name: field.name, role: UserRole.User })); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [dashboardRole]); diff --git a/src/components/index.ts b/src/components/index.ts index aff49e2..9a2f607 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -3,6 +3,6 @@ export { Header } from './Header'; export { Table } from './Table'; export { Banner } from './Banner'; export { Tabs } from './Tabs'; -export { Modal, ConfirmationModal } from './Modal'; +export { Modal, ConfirmationModal, StepsModal } from './Modal'; export { UserModal } from './UserModal'; -export { ProgressSteps } from './Steps'; +export { ProgressSteps } from './ProgressSteps'; diff --git a/src/modules/users/components/MultipleUsersModal/MultipleUsersModal.tsx b/src/modules/users/components/MultipleUsersModal/MultipleUsersModal.tsx index 02200e8..74f60c6 100644 --- a/src/modules/users/components/MultipleUsersModal/MultipleUsersModal.tsx +++ b/src/modules/users/components/MultipleUsersModal/MultipleUsersModal.tsx @@ -2,11 +2,11 @@ import React, { useEffect, useState } from 'react'; import _ from 'lodash'; import { useFieldArray, useForm, useWatch } from 'react-hook-form'; -import { Banner, Modal, ProgressSteps } from 'src/components'; +import { Banner, StepsModal, ProgressSteps } from 'src/components'; import { Select, TextArea } from 'src/components/Form'; import { MultipleUsersData, UserRole, useUsers } from 'src/services/users'; import { allAppAccessList } from 'src/components/UserModal/consts'; -import { ProgressStepInfo, ProgressStepStatus } from 'src/components/Steps/types'; +import { ProgressStepInfo, ProgressStepStatus } from 'src/components/ProgressSteps/types'; import { initialMultipleUsersForm, MultipleUsersModalProps } from './types'; export const MultipleUsersModal = ({ open, onClose }: MultipleUsersModalProps) => { @@ -181,6 +181,8 @@ export const MultipleUsersModal = ({ open, onClose }: MultipleUsersModalProps) = onClose(); }; + const getActiveStepIndex = () => _.findIndex(steps, { status: ProgressStepStatus.Current }); + const updateStepsStatus = (nextIndex: number) => { const updatedSteps = [...steps]; _.forEach(updatedSteps, (step, index) => { @@ -200,17 +202,32 @@ export const MultipleUsersModal = ({ open, onClose }: MultipleUsersModalProps) = updateStepsStatus(activeStepIndex); }; - const getActiveStepIndex = _.findIndex(steps, { status: ProgressStepStatus.Current }); - const disableSave = _.isEmpty(csvDataWatch) || _.some(steps, { status: ProgressStepStatus.Upcoming }); + const handleNext = () => { + const nextIndex = getActiveStepIndex() + 1; + updateStepsStatus(nextIndex); + }; + + const handlePrevious = () => { + const nextIndex = getActiveStepIndex() - 1; + updateStepsStatus(nextIndex); + }; + + const activeStepIndex = getActiveStepIndex(); + const showSave = !_.some(steps, { status: ProgressStepStatus.Upcoming }); + const showPrevious = _.some(steps, { status: ProgressStepStatus.Complete }); return ( -
@@ -220,12 +237,12 @@ export const MultipleUsersModal = ({ open, onClose }: MultipleUsersModalProps) =
- {getActiveStepIndex === 0 ? renderUsersCsvDataInput() : renderAppAccess()} + {activeStepIndex === 0 ? renderUsersCsvDataInput() : renderAppAccess()}
-
+ ); }; diff --git a/src/services/users/redux/actions.ts b/src/services/users/redux/actions.ts index ac5adc9..a09b590 100644 --- a/src/services/users/redux/actions.ts +++ b/src/services/users/redux/actions.ts @@ -227,21 +227,14 @@ export const createBatchUsers = (users: any) => async (dispatch: Dispatch) }); // show information about created users - const createdUsersNumber = _.size(responseData.createdUsers); - if (createdUsersNumber > 0) { - showToast( - `${_.size(responseData.createdUsers)} ${createdUsersNumber > 1 ? 'users' : 'user'} created successfully.`, - ToastType.Success, - ); + if (!_.isEmpty(responseData.success)) { + showToast(responseData.success.message, ToastType.Success); } - const notCreatedUsersNumber = _.size(responseData.notCreatedUsers); - if (notCreatedUsersNumber > 0) { - showToast( - `${_.size(responseData.notCreatedUsers)} - ${notCreatedUsersNumber > 1 ? 'users' : 'user'} not created with - ${notCreatedUsersNumber > 1 ? 'emails' : 'email'}: \n${responseData.notCreatedUsers.join(',\n')}`, - ToastType.Error, - ); + if (!_.isEmpty(responseData.existing)) { + showToast(responseData.existing.message, ToastType.Error); + } + if (!_.isEmpty(responseData.failed)) { + showToast(responseData.failed.message, ToastType.Error); } dispatch(fetchUsers()); diff --git a/src/services/users/transformations.ts b/src/services/users/transformations.ts index 65b869c..21e7db4 100644 --- a/src/services/users/transformations.ts +++ b/src/services/users/transformations.ts @@ -86,7 +86,8 @@ export const transformRequestMultipleUsers = (data: MultipleUsersData) => { export const transformBatchResponse = (response: any): any => { return { - createdUsers: response.created_users, - notCreatedUsers: response.not_created_users, + success: response.success, + existing: response.existing, + failed: response.failed, }; };