wizard: add Administrator checkbox to users step (HMS-4903)

this commit add Administrator checkbox to users step
This commit is contained in:
Michal Gold 2025-01-02 16:05:20 +02:00 committed by Klara Simickova
parent bdd259f758
commit 25f124077c
5 changed files with 87 additions and 1 deletions

View file

@ -1,17 +1,19 @@
import React from 'react';
import { Button, FormGroup } from '@patternfly/react-core';
import { Button, FormGroup, Checkbox } from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import { GENERATING_SSH_KEY_PAIRS_URL } from '../../../../../constants';
import { useAppDispatch, useAppSelector } from '../../../../../store/hooks';
import {
selectUserAdministrator,
selectUserNameByIndex,
selectUserPasswordByIndex,
selectUserSshKeyByIndex,
setUserNameByIndex,
setUserPasswordByIndex,
setUserSshKeyByIndex,
setUserAdministratorByIndex,
} from '../../../../../store/wizardSlice';
import { useUsersValidation } from '../../../utilities/useValidation';
import { HookValidatedInput } from '../../../ValidatedTextInput';
@ -24,6 +26,8 @@ const UserInfo = () => {
const userPassword = useAppSelector(userPasswordSelector);
const userSshKeySelector = selectUserSshKeyByIndex(index);
const userSshKey = useAppSelector(userSshKeySelector);
const userIsAdministratorSelector = selectUserAdministrator(index);
const userIsAdministrator = useAppSelector(userIsAdministratorSelector);
const handleNameChange = (
_e: React.FormEvent<HTMLInputElement>,
@ -48,6 +52,15 @@ const UserInfo = () => {
const stepValidation = useUsersValidation();
const handleCheckboxChange = (
_event: React.FormEvent<HTMLInputElement>,
value: boolean
) => {
dispatch(
setUserAdministratorByIndex({ index: index, isAdministrator: value })
);
};
return (
<>
<FormGroup isRequired label="Username">
@ -92,6 +105,16 @@ const UserInfo = () => {
Learn more about SSH keys
</Button>
</FormGroup>
<FormGroup>
<Checkbox
label="Administrator"
isChecked={userIsAdministrator}
onChange={(_e, value) => handleCheckboxChange(_e, value)}
aria-label="Administrator"
id="user Administrator"
name="user Administrator"
/>
</FormGroup>
</>
);
};

View file

@ -608,6 +608,9 @@ const getUsers = (state: RootState): User[] | undefined => {
if (user.ssh_key !== '') {
result.ssh_key = user.ssh_key;
}
if (user.groups.length > 0) {
result.groups = user.groups;
}
return result as User;
});
};

View file

@ -46,6 +46,8 @@ export type ComplianceType = 'openscap' | 'compliance';
export type UserWithAdditionalInfo = {
[K in keyof User]-?: NonNullable<User[K]>;
} & {
isAdministrator: boolean;
};
type UserPayload = {
@ -63,6 +65,11 @@ type UserSshKeyPayload = {
sshKey: string;
};
type UserAdministratorPayload = {
index: number;
isAdministrator: boolean;
};
export type wizardState = {
env: {
serverUrl: string;
@ -386,6 +393,11 @@ export const selectUserSshKeyByIndex =
return state.wizard.users[userIndex]?.ssh_key;
};
export const selectUserAdministrator =
(userIndex: number) => (state: RootState) => {
return state.wizard.users[userIndex].isAdministrator;
};
export const selectKernel = (state: RootState) => {
return state.wizard.kernel;
};
@ -864,6 +876,20 @@ export const wizardSlice = createSlice({
1
);
},
setUserAdministratorByIndex: (
state,
action: PayloadAction<UserAdministratorPayload>
) => {
const { index, isAdministrator } = action.payload;
const user = state.users[index];
user.isAdministrator = isAdministrator;
if (isAdministrator) {
user.groups.push('wheel');
} else {
user.groups = user.groups.filter((group) => group !== 'wheel');
}
},
},
});
@ -939,5 +965,6 @@ export const {
setUserNameByIndex,
setUserPasswordByIndex,
setUserSshKeyByIndex,
setUserAdministratorByIndex,
} = wizardSlice.actions;
export default wizardSlice.reducer;

View file

@ -164,6 +164,38 @@ describe('Step Users', () => {
});
});
test('with valid name, ssh key and checked Administrator checkbox', async () => {
const user = userEvent.setup();
await renderCreateMode();
await goToRegistrationStep();
await clickRegisterLater();
await goToUsersStep();
await addValidUser();
const isAdmin = screen.getByRole('checkbox', {
name: /administrator/i,
});
user.click(isAdmin);
await goToReviewStep();
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
const expectedRequest = {
...blueprintRequest,
customizations: {
users: [
{
name: 'best',
ssh_key: 'ssh-rsa d',
groups: ['wheel'],
},
],
},
};
await waitFor(() => {
expect(receivedRequest).toEqual(expectedRequest);
});
});
test('with invalid name', async () => {
await renderCreateMode();
await goToRegistrationStep();

View file

@ -448,6 +448,7 @@ export const usersCreateBlueprintRequest: CreateBlueprintRequest = {
{
name: 'best',
ssh_key: 'ssh-rsa d',
groups: ['wheel'],
},
],
},