diff --git a/src/components/UserSettings.tsx b/src/components/UserSettings.tsx index 5b5c418a3..9e7b9ab6f 100644 --- a/src/components/UserSettings.tsx +++ b/src/components/UserSettings.tsx @@ -53,6 +53,7 @@ import RebuildAutoMembership from "./modals/RebuildAutoMembership"; import UnlockUser from "./modals/UnlockUser"; import ResetPassword from "./modals/ResetPassword"; import IssueNewCertificate from "./modals/IssueNewCertificate"; +import ActivateStageUsers from "./modals/ActivateStageUsers"; export interface PropsToUserSettings { originalUser: Partial; @@ -173,6 +174,12 @@ const UserSettings = (props: PropsToUserSettings) => { setIsNewCertificateModalOpen(false); }; + // Stage users - 'Activate' option + const [isActivateModalOpen, setIsActivateModalOpen] = React.useState(false); + const onCloseActivateModal = () => { + setIsActivateModalOpen(false); + }; + // Kebab const [isKebabOpen, setIsKebabOpen] = useState(false); @@ -223,7 +230,9 @@ const UserSettings = (props: PropsToUserSettings) => { ]; const stageDropdownItems = [ - Activate, + setIsActivateModalOpen(true)}> + Activate + , setIsDeleteModalOpen(true)}> Delete , @@ -523,6 +532,11 @@ const UserSettings = (props: PropsToUserSettings) => { showPrincipalFields={false} onRefresh={props.onRefresh} /> + ); }; diff --git a/src/components/modals/ActivateStageUsers.tsx b/src/components/modals/ActivateStageUsers.tsx index 5e077ff3c..ff5bf5a85 100644 --- a/src/components/modals/ActivateStageUsers.tsx +++ b/src/components/modals/ActivateStageUsers.tsx @@ -15,17 +15,7 @@ import UsersDisplayTable from "src/components/tables/UsersDisplayTable"; import { useAppDispatch } from "src/store/hooks"; import { removeUser as removeStageUser } from "src/store/Identity/stageUsers-slice"; // RPC -import { - Command, - BatchRPCResponse, - useBatchMutCommandMutation, -} from "src/services/rpc"; -import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query"; -import { SerializedError } from "@reduxjs/toolkit"; -// Modals -import ErrorModal from "./ErrorModal"; -// Data types -import { ErrorData } from "src/utils/datatypes/globalDataTypes"; +import { useActivateUserMutation, ErrorResult } from "src/services/rpc"; // Hooks import useAlerts from "src/hooks/useAlerts"; @@ -39,8 +29,6 @@ export interface PropsToActivateUsers { handleModalToggle: () => void; selectedUsersData: SelectedUsersData; onRefresh?: () => void; - onOpenDeleteModal?: () => void; - onCloseDeleteModal?: () => void; } const ActivateStageUsers = (props: PropsToActivateUsers) => { @@ -51,7 +39,7 @@ const ActivateStageUsers = (props: PropsToActivateUsers) => { const alerts = useAlerts(); // Define 'executeUserStageCommand' to activate user data to IPA server - const [executeUserActivateCommand] = useBatchMutCommandMutation(); + const [activateUsersCommand] = useActivateUserMutation(); const [noMembersChecked, setNoMembers] = useState(false); @@ -97,106 +85,39 @@ const ActivateStageUsers = (props: PropsToActivateUsers) => { props.handleModalToggle(); }; - // Handle API error data - const [isModalErrorOpen, setIsModalErrorOpen] = useState(false); - const [errorTitle, setErrorTitle] = useState(""); - const [errorMessage, setErrorMessage] = useState(""); - - const closeAndCleanErrorParameters = () => { - setIsModalErrorOpen(false); - setErrorTitle(""); - setErrorMessage(""); - }; - - const onCloseErrorModal = () => { - closeAndCleanErrorParameters(); - }; - - const errorModalActions = [ - , - ]; - - const handleAPIError = (error: FetchBaseQueryError | SerializedError) => { - if ("code" in error) { - setErrorTitle("IPA error " + error.code + ": " + error.name); - if (error.message !== undefined) { - setErrorMessage(error.message); - } - } else if ("data" in error) { - const errorData = error.data as ErrorData; - const errorCode = errorData.code as string; - const errorName = errorData.name as string; - const errorMessage = errorData.error as string; - - setErrorTitle("IPA error " + errorCode + ": " + errorName); - setErrorMessage(errorMessage); - } - setIsModalErrorOpen(true); - }; - // Stage user const activateUsers = () => { // Prepare users params - const uidsToActivatePayload: Command[] = []; - - props.selectedUsersData.selectedUsers.map((uid) => { - const payloadItem = { - method: "stageuser_activate", - params: [uid, { no_members: noMembersChecked }], - } as Command; - uidsToActivatePayload.push(payloadItem); - }); + const usersToActivatePayload = props.selectedUsersData.selectedUsers; // [API call] activate elements - executeUserActivateCommand(uidsToActivatePayload).then((response) => { + activateUsersCommand(usersToActivatePayload).then((response) => { if ("data" in response) { - const data = response.data as BatchRPCResponse; - const result = data.result; - const error = data.error as FetchBaseQueryError | SerializedError; - - if (result) { - if ("error" in result.results[0] && result.results[0].error) { - const errorData = { - code: result.results[0].error_code, - name: result.results[0].error_name, - error: result.results[0].error, - } as ErrorData; - - const error = { - status: "CUSTOM_ERROR", - data: errorData, - } as FetchBaseQueryError; - - // Handle error - handleAPIError(error); - } else { - // Update data from Redux - props.selectedUsersData.selectedUsers.map((user) => { - dispatch(removeStageUser(user[0])); - }); - - // Reset selected values - props.selectedUsersData.updateSelectedUsers([]); - - // Refresh data - if (props.onRefresh !== undefined) { - props.onRefresh(); - } - - // Show alert: success - alerts.addAlert( - "activate-users-success", - "Users activated", - "success" - ); - - closeModal(); + if (response.data.result) { + // Close modal + props.handleModalToggle(); + // Update data from Redux + props.selectedUsersData.selectedUsers.map((user) => { + dispatch(removeStageUser(user[0])); + }); + // Set alert: success + alerts.addAlert( + "activate-users-success", + response.data.result.count + " users activated", + "success" + ); + // Refresh data + if (props.onRefresh !== undefined) { + props.onRefresh(); } - } else if (error) { - // Handle error - handleAPIError(error); + } else if (response.data.error) { + // Set alert: error + const errorMessage = response.data.error as ErrorResult; + alerts.addAlert( + "activate-users-error", + errorMessage.message, + "danger" + ); } } }); @@ -217,34 +138,21 @@ const ActivateStageUsers = (props: PropsToActivateUsers) => { , ]; - const modalActivate: JSX.Element = ( - - ); - // Render 'ActivateStageUsers' return ( <> - {modalActivate} - {isModalErrorOpen && ( - - )} + ); }; diff --git a/src/components/tables/UsersDisplayTable.tsx b/src/components/tables/UsersDisplayTable.tsx index 51d3ae073..180694382 100644 --- a/src/components/tables/UsersDisplayTable.tsx +++ b/src/components/tables/UsersDisplayTable.tsx @@ -53,7 +53,7 @@ const UsersDisplayTable = (props: PropsToDisplayUsersTable) => { case "stage-users": stageUsersListCopy.map((user) => { props.usersToDisplay.map((selected) => { - if (user.uid === selected || user.uid[0] === selected) { + if (user.uid[0] === selected[0] || user.uid[0] === selected) { usersToDisplay.push(user); } }); @@ -63,7 +63,7 @@ const UsersDisplayTable = (props: PropsToDisplayUsersTable) => { case "preserved-users": preservedUsersListCopy.map((user) => { props.usersToDisplay.map((selected) => { - if (user.uid === selected || user.uid[0] === selected) { + if (user.uid[0] === selected[0] || user.uid[0] === selected) { usersToDisplay.push(user); } }); diff --git a/src/services/rpc.ts b/src/services/rpc.ts index 40c277c91..ccef5369e 100644 --- a/src/services/rpc.ts +++ b/src/services/rpc.ts @@ -749,6 +749,29 @@ export const api = createApi({ response.result.result as unknown as CertProfile[], providesTags: ["CertProfile"], }), + activateUser: build.mutation({ + query: (query_args) => { + const batchPayload: Command[] = []; + query_args.map((userToActivate) => { + let individualUserParams; + if (Array.isArray(userToActivate)) { + individualUserParams = [userToActivate, {}]; + } else { + individualUserParams = [[userToActivate], {}]; + } + + batchPayload.push({ + method: "stageuser_activate", + params: individualUserParams, + }); + }); + + return getBatchCommand( + batchPayload, + query_args["version"] || API_VERSION_BACKUP + ); + }, + }), }), }); @@ -819,4 +842,5 @@ export const { useUnlockUserMutation, useChangePasswordMutation, useGetCertProfileQuery, + useActivateUserMutation, } = api;