Skip to content

Commit

Permalink
Add 'Enable/disable' options
Browse files Browse the repository at this point in the history
The 'Enable'/'Disable' option should
change the status of a given user.

For this solution, the
`DisableEnableUsers` component
has been adapted to perform the
API calls needed.

Signed-off-by: Carla Martinez <carlmart@redhat.com>
  • Loading branch information
carma12 committed Dec 15, 2023
1 parent 52b1c09 commit d89de04
Show file tree
Hide file tree
Showing 3 changed files with 231 additions and 81 deletions.
60 changes: 58 additions & 2 deletions src/components/UserSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ import {
} from "src/services/rpc";
// Hooks
import useAlerts from "src/hooks/useAlerts";
// Modals
import DisableEnableUsers from "./modals/DisableEnableUsers";

export interface PropsToUserSettings {
originalUser: Partial<User>;
Expand Down Expand Up @@ -78,15 +80,60 @@ const UserSettings = (props: PropsToUserSettings) => {
[saveUser] = useSaveStageUserMutation();
}

// To handle the logic of the selectedUsersData (from
// the 'Disable / Enable' modal), lets use the 'selectedUsers' state
const uidArray: string[] = ([props.user.uid] as string[]) || [];
const [selectedUsers, setSelectedUsers] = React.useState<string[]>(uidArray);
const [selectedUsersData, setSelectedUsersData] = React.useState({
selectedUsers: selectedUsers,
updateSelectedUsers: setSelectedUsers,
});

// Data is updated on 'props.user' changes
React.useEffect(() => {
if (props.user.nsaccountlock !== undefined) {
setOptionSelected(!props.user.nsaccountlock);
}

if (props.user.uid !== undefined) {
setSelectedUsers([props.user.uid]);
setSelectedUsersData({
selectedUsers: [props.user.uid],
updateSelectedUsers: setSelectedUsers,
});
}
}, [props.user]);

// 'Enable / disable' option
const [isDisableEnableModalOpen, setIsDisableEnableModalOpen] =
React.useState(false);
const [optionSelected, setOptionSelected] = React.useState<boolean>(
!props.user.nsaccountlock || false
); // 'enable': false | 'disable': true

const onCloseDisableEnableModal = () => {
setIsDisableEnableModalOpen(false);
};

// Kebab
const [isKebabOpen, setIsKebabOpen] = useState(false);

const dropdownItems = [
<DropdownItem key="reset password">Reset password</DropdownItem>,
<DropdownItem key="enable" isDisabled>
<DropdownItem
key="enable"
isDisabled={!props.user.nsaccountlock}
onClick={() => setIsDisableEnableModalOpen(true)}
>
Enable
</DropdownItem>,
<DropdownItem key="disable">Disable</DropdownItem>,
<DropdownItem
key="disable"
isDisabled={props.user.nsaccountlock}
onClick={() => setIsDisableEnableModalOpen(true)}
>
Disable
</DropdownItem>,
<DropdownItem key="delete">Delete</DropdownItem>,
<DropdownItem key="unlock" isDisabled>
Unlock
Expand Down Expand Up @@ -339,6 +386,15 @@ const UserSettings = (props: PropsToUserSettings) => {
className={"pf-u-p-md pf-u-ml-lg pf-u-mr-lg"}
toolbarItems={toolbarFields}
/>
<DisableEnableUsers
show={isDisableEnableModalOpen}
from={props.from}
handleModalToggle={onCloseDisableEnableModal}
optionSelected={optionSelected}
selectedUsersData={selectedUsersData}
singleUser={true}
onRefresh={props.onRefresh}
/>
</>
);
};
Expand Down
220 changes: 141 additions & 79 deletions src/components/modals/DisableEnableUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import {
Command,
BatchRPCResponse,
useBatchMutCommandMutation,
useEnableUserMutation,
useDisableUserMutation,
ErrorResult,
} from "src/services/rpc";
// Errors
import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query";
Expand Down Expand Up @@ -44,11 +47,14 @@ export interface PropsToDisableEnableUsers {
handleModalToggle: () => void;
optionSelected: boolean; // 'enable': false | 'disable': true
selectedUsersData: SelectedUsersData;
buttonsData: ButtonsData;
buttonsData?: ButtonsData;
// NOTE: 'onRefresh' is handled as { (User) => void | undefined } as a temporal solution
// until the C.L. is adapted in 'stage-' and 'preserved users' (otherwise
// the operation will fail for those components)
onRefresh?: () => void;
// By default, the API call will be a batch operation (multiple users at once)
// - If 'singleUser' is set to 'true', the API call will be a single operation
singleUser?: boolean | false;
}

const DisableEnableUsers = (props: PropsToDisableEnableUsers) => {
Expand All @@ -60,6 +66,9 @@ const DisableEnableUsers = (props: PropsToDisableEnableUsers) => {

// Define 'executeEnableDisableCommand' to add user data to IPA server
const [executeEnableDisableCommand] = useBatchMutCommandMutation();
// Single user operations
const [enableSingleUser] = useEnableUserMutation();
const [disableSingleUser] = useDisableUserMutation();

// Define which action (enable | disable) based on 'optionSelected'
const action = !props.optionSelected ? "enable" : "disable";
Expand Down Expand Up @@ -154,18 +163,20 @@ const DisableEnableUsers = (props: PropsToDisableEnableUsers) => {
// Update changes to Redux
dispatchToRedux(newStatus, selectedUsers);

// Update 'isDisbleEnableOp' to notify table that an updating operation is performed
props.buttonsData.updateIsDisableEnableOp(true);

// Update buttons
if (!props.optionSelected) {
// Enable
props.buttonsData.updateIsEnableButtonDisabled(true);
props.buttonsData.updateIsDisableButtonDisabled(false);
} else if (props.optionSelected) {
// Disable
props.buttonsData.updateIsEnableButtonDisabled(false);
props.buttonsData.updateIsDisableButtonDisabled(true);
if (props.buttonsData !== undefined) {
// Update 'isDisbleEnableOp' to notify table that an updating operation is performed
props.buttonsData.updateIsDisableEnableOp(true);

// Update buttons
if (!props.optionSelected) {
// Enable
props.buttonsData.updateIsEnableButtonDisabled(true);
props.buttonsData.updateIsDisableButtonDisabled(false);
} else if (props.optionSelected) {
// Disable
props.buttonsData.updateIsEnableButtonDisabled(false);
props.buttonsData.updateIsDisableButtonDisabled(true);
}
}

// Reset selected users
Expand All @@ -174,88 +185,139 @@ const DisableEnableUsers = (props: PropsToDisableEnableUsers) => {
};

// Modify user status using IPA commands
// TODO: Better Adapt this function to several use-cases
const modifyStatus = (newStatus: boolean, selectedUsers: string[]) => {
// Prepare users params
const uidsToChangeStatusPayload: Command[] = [];
const changeStatusParams = {};
const option = props.optionSelected ? "user_disable" : "user_enable";

selectedUsers.map((uid) => {
const payloadItem = {
method: option,
params: [uid, changeStatusParams],
} as Command;

uidsToChangeStatusPayload.push(payloadItem);
});

executeEnableDisableCommand(uidsToChangeStatusPayload).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 changes to Redux
dispatchToRedux(newStatus, selectedUsers);

// Update 'isDisbleEnableOp' to notify table that an updating operation is performed
props.buttonsData.updateIsDisableEnableOp(true);

// Update buttons
if (!props.optionSelected) {
// Enable
props.buttonsData.updateIsEnableButtonDisabled(true);
props.buttonsData.updateIsDisableButtonDisabled(false);
// Set alert: success
alerts.addAlert(
"enable-user-success",
"Users enabled",
"success"
);
} else if (props.optionSelected) {
// Disable
props.buttonsData.updateIsEnableButtonDisabled(false);
props.buttonsData.updateIsDisableButtonDisabled(true);
// Set alert: success
alerts.addAlert(
"disable-user-success",
"Users disabled",
"success"
);
// Make the API call (depending on 'singleUser' value)
if (props.singleUser === undefined || !props.singleUser) {
selectedUsers.map((uid) => {
const payloadItem = {
method: option,
params: [uid, changeStatusParams],
} as Command;

uidsToChangeStatusPayload.push(payloadItem);
});

executeEnableDisableCommand(uidsToChangeStatusPayload).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 changes to Redux
dispatchToRedux(newStatus, selectedUsers);

if (props.buttonsData !== undefined) {
// Update 'isDisbleEnableOp' to notify table that an updating operation is performed
props.buttonsData.updateIsDisableEnableOp(true);

// Update buttons
if (!props.optionSelected) {
// Enable
props.buttonsData.updateIsEnableButtonDisabled(true);
props.buttonsData.updateIsDisableButtonDisabled(false);
// Set alert: success
alerts.addAlert(
"enable-user-success",
"Users enabled",
"success"
);
} else if (props.optionSelected) {
// Disable
props.buttonsData.updateIsEnableButtonDisabled(false);
props.buttonsData.updateIsDisableButtonDisabled(true);
// Set alert: success
alerts.addAlert(
"disable-user-success",
"Users disabled",
"success"
);
}
}

// Reset selected users
props.selectedUsersData.updateSelectedUsers([]);

// Refresh data
if (props.onRefresh !== undefined) {
props.onRefresh();
}
}
} else if (error) {
// Handle error
handleAPIError(error);
}
// Close modal
closeModal();
}
}
);
} else {
// Single user operation
let command;
if (option === "user_disable") {
command = disableSingleUser;
} else {
command = enableSingleUser;
}

const payload = props.selectedUsersData.selectedUsers[0];

command(payload).then((response) => {
if ("data" in response) {
if (response.data.result) {
// Update changes to Redux
dispatchToRedux(newStatus, selectedUsers);
// Close modal
closeModal();
// Set alert: success
alerts.addAlert(
"enable-user-success",
"Enabled user account '" +
props.selectedUsersData.selectedUsers[0] +
"'",
"success"
);
// Reset selected users
props.selectedUsersData.updateSelectedUsers([]);

// Refresh data
if (props.onRefresh !== undefined) {
props.onRefresh();
}
} else if (response.data.error) {
// Set alert: error
const errorMessage = response.data.error as ErrorResult;
alerts.addAlert(
"enable-user-error",
errorMessage.message,
"danger"
);
}
} else if (error) {
// Handle error
handleAPIError(error);
}
// Close modal
closeModal();
}
});
});
}
};

// Set the Modal and Action buttons for 'Disable' option
Expand Down
Loading

0 comments on commit d89de04

Please sign in to comment.