Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Active users][Settings][Account settings] Add functionality for checkbox list #139

Merged
merged 1 commit into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions src/components/Form/IpaCheckboxes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from "react";
// PatternFly
import { Checkbox } from "@patternfly/react-core";
// Utils
import {
IPAParamDefinition,
getParamProperties,
toArray,
updateIpaObject,
} from "src/utils/ipaObjectUtils";

interface CheckboxOption {
value: string;
text: string;
}

export interface IPAParamDefinitionCheckboxes extends IPAParamDefinition {
options: CheckboxOption[];
}

const IpaCheckboxes = (props: IPAParamDefinitionCheckboxes) => {
const { required, readOnly, value } = getParamProperties(props);

const valueAsArray = toArray(value);

// Updates the list of checked values when a specific checkbox is clicked
// - This is implemented here because we need to know which specific
// value (option.value) to add/remove from the list
const updateList = (checked: boolean, elementToChange: string) => {
if (props.ipaObject !== undefined && props.onChange !== undefined) {
const updatedList = [...valueAsArray];
if (checked) {
updatedList.push(elementToChange);
} else {
const index = updatedList.indexOf(elementToChange);
if (index > -1) {
updatedList.splice(index, 1);
}
}
// Update the IPA object
updateIpaObject(props.ipaObject, props.onChange, updatedList, props.name);
}
};

return (
<>
{props.options.map((option, idx) => (
<Checkbox
key={props.name + "-" + option.value}
id={props.name + "-" + option.value} // Mandatory
name={props.name}
label={option.text}
onChange={(checked) => updateList(checked, option.value)}
isRequired={required}
readOnly={readOnly}
isChecked={
pvoborni marked this conversation as resolved.
Show resolved Hide resolved
valueAsArray.find((val) => val === option.value) !== undefined
}
aria-label={props.name}
className={
idx !== props.options.length - 1 ? "pf-u-mt-xs pf-u-mb-sm" : ""
}
isDisabled={readOnly}
/>
))}
</>
);
};

export default IpaCheckboxes;
92 changes: 32 additions & 60 deletions src/components/UsersSections/UsersAccountSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
Form,
FormGroup,
TextInput,
Checkbox,
DropdownItem,
CalendarMonth,
Button,
Expand All @@ -33,6 +32,7 @@ import { asRecord } from "src/utils/userUtils";
// Form
import IpaTextInput from "src/components/Form/IpaTextInput";
import IpaSelect from "../Form/IpaSelect";
import IpaCheckboxes from "../Form/IpaCheckboxes";

interface PropsToUsersAccountSettings {
user: Partial<User>;
Expand Down Expand Up @@ -346,14 +346,6 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
</Button>,
];

// Checkboxes
const [passwordCheckbox] = useState(false);
const [radiusCheckbox] = useState(false);
const [tpaCheckbox] = useState(false);
const [pkinitCheckbox] = useState(false);
const [hardenedPassCheckbox] = useState(false);
const [extIdentityProvCheckbox] = useState(false);

// Date and time picker (Calendar)
const [isCalendarOpen, setIsCalendarOpen] = React.useState(false);
const [isTimeOpen, setIsTimeOpen] = React.useState(false);
Expand Down Expand Up @@ -626,58 +618,38 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
<PopoverWithIconLayout message={userAuthTypesMessage} />
}
>
<Checkbox
label="Password"
isChecked={passwordCheckbox}
aria-label="password from user authentication types"
id="passwordCheckbox"
name="ipauserauthtype"
value="password"
className="pf-u-mt-xs pf-u-mb-sm"
/>
<Checkbox
label="RADIUS"
isChecked={radiusCheckbox}
aria-label="radius from user authentication types"
id="radiusCheckbox"
name="ipauserauthtype"
value="radius"
className="pf-u-mt-xs pf-u-mb-sm"
/>
<Checkbox
label="Two-factor authentication (password + OTP)"
isChecked={tpaCheckbox}
aria-label="two factor authentication from user authentication types"
id="tpaCheckbox"
name="ipauserauthtype"
value="otp"
className="pf-u-mt-xs pf-u-mb-sm"
/>
<Checkbox
label="PKINIT"
isChecked={pkinitCheckbox}
aria-label="pkinit from user authentication types"
id="pkinitCheckbox"
<IpaCheckboxes
name="ipauserauthtype"
value="pkinit"
className="pf-u-mt-xs pf-u-mb-sm"
/>
<Checkbox
label="Hardened password (by SPAKE or FAST)"
isChecked={hardenedPassCheckbox}
aria-label="hardened password from user authentication types"
id="hardenedPassCheckbox"
name="ipauserauthtype"
value="hardened"
className="pf-u-mt-xs pf-u-mb-sm"
/>
<Checkbox
label="External Identity Provider"
isChecked={extIdentityProvCheckbox}
aria-label="external identity provider from user authentication types"
id="extIdentityProvCheckbox"
name="ipauserauthtype"
value="idp"
options={[
{
value: "password",
text: "Password",
},
{
value: "radius",
text: "RADIUS",
},
{
value: "otp",
text: "Two-factor authentication (password + OTP)",
},
{
value: "pkinit",
text: "PKINIT",
},
{
value: "hardened",
text: "Hardened password (by SPAKE or FAST)",
},
{
value: "idp",
text: "External Identity Provider",
},
]}
ipaObject={ipaObject}
onChange={recordOnChange}
objectName="user"
metadata={props.metadata}
/>
</FormGroup>
<FormGroup
Expand Down
11 changes: 11 additions & 0 deletions src/utils/ipaObjectUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export function getParamProperties(
parDef.onChange({ ...parDef.ipaObject, [propName]: value });
}
};

return {
writable,
required,
Expand Down Expand Up @@ -194,3 +195,13 @@ export const updateIpaObject = (
) => {
setIpaObject({ ...ipaObject, [paramName]: newValue });
};

export function toArray(value: BasicType): BasicType[] {
if (Array.isArray(value)) {
return value;
} else if (value === null || value === undefined) {
return [];
} else {
return [value];
}
}