Create attribute - required toggle in general settings (#2279)
* fixed required in general settings * feedback * indentation fix Co-authored-by: Agnieszka Gancarczyk <agancarc@redhat.com>
This commit is contained in:
parent
5e5f9acda6
commit
12977d929c
1 changed files with 135 additions and 117 deletions
|
@ -13,7 +13,7 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { HelpItem } from "../../../components/help-enabler/HelpItem";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
||||
import { FormAccess } from "../../../components/form-access/FormAccess";
|
||||
import { useAdminClient, useFetch } from "../../../context/auth/AdminClient";
|
||||
import type ClientScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientScopeRepresentation";
|
||||
|
@ -21,8 +21,10 @@ import "../../realm-settings-section.css";
|
|||
|
||||
const ENABLED_REQUIRED_WHEN = ["Always", "Scopes are requested"] as const;
|
||||
const REQUIRED_FOR = [
|
||||
{ label: "Both users and admins", value: ["admin", "user"]}, { label: "Only users", value: "user" },{ label: "Only admins", value: "admin" }
|
||||
] as const;
|
||||
{ label: "Both users and admins", value: ["admin", "user"] },
|
||||
{ label: "Only users", value: ["user"] },
|
||||
{ label: "Only admins", value: ["admin"] },
|
||||
] as const;
|
||||
|
||||
export const AttributeGeneralSettings = () => {
|
||||
const { t } = useTranslation("realm-settings");
|
||||
|
@ -37,6 +39,12 @@ export const AttributeGeneralSettings = () => {
|
|||
const [enabledWhenSelection, setEnabledWhenSelection] = useState("Always");
|
||||
const [requiredWhenSelection, setRequiredWhenSelection] = useState("Always");
|
||||
|
||||
const requiredToggle = useWatch({
|
||||
control: form.control,
|
||||
name: "required",
|
||||
defaultValue: false,
|
||||
});
|
||||
|
||||
useFetch(
|
||||
() => adminClient.clientScopes.find(),
|
||||
(clientScopes) => {
|
||||
|
@ -137,7 +145,7 @@ export const AttributeGeneralSettings = () => {
|
|||
name="enabledWhen"
|
||||
data-testid="enabledWhen"
|
||||
control={form.control}
|
||||
defaultValue={ENABLED_REQUIRED_WHEN[0]}
|
||||
defaultValue={ENABLED_REQUIRED_WHEN[0]}
|
||||
render={({ onChange, value }) => (
|
||||
<>
|
||||
{ENABLED_REQUIRED_WHEN.map((option) => (
|
||||
|
@ -163,7 +171,7 @@ export const AttributeGeneralSettings = () => {
|
|||
<Controller
|
||||
name="scopes"
|
||||
control={form.control}
|
||||
defaultValue={[]}
|
||||
defaultValue={[]}
|
||||
render={({
|
||||
onChange,
|
||||
value,
|
||||
|
@ -186,14 +194,14 @@ export const AttributeGeneralSettings = () => {
|
|||
onSelect={(_, selectedValue) => {
|
||||
const option = selectedValue.toString();
|
||||
let changedValue = [""];
|
||||
if (value) {
|
||||
if (value) {
|
||||
changedValue = value.includes(option)
|
||||
? value.filter((item) => item !== option)
|
||||
: [...value, option];
|
||||
} else {
|
||||
changedValue = [option];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onChange(changedValue);
|
||||
}}
|
||||
onClear={(selectedValues) => {
|
||||
|
@ -225,126 +233,136 @@ export const AttributeGeneralSettings = () => {
|
|||
>
|
||||
<Controller
|
||||
name="required"
|
||||
defaultValue={["false"]}
|
||||
defaultValue={false}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<Switch
|
||||
id={"kc-required"}
|
||||
isDisabled={false}
|
||||
onChange={(value) => onChange([`${value}`])}
|
||||
isChecked={value[0] === "true"}
|
||||
onChange={(value) => {
|
||||
onChange(value);
|
||||
form.setValue("required", value);
|
||||
}}
|
||||
isChecked={value === true}
|
||||
label={t("common:on")}
|
||||
labelOff={t("common:off")}
|
||||
/>
|
||||
)}
|
||||
></Controller>
|
||||
</FormGroup>
|
||||
<FormGroup label={t("requiredFor")} fieldId="requiredFor" hasNoPaddingTop>
|
||||
<Controller
|
||||
name="roles"
|
||||
data-testid="requiredFor"
|
||||
defaultValue={REQUIRED_FOR[0].value}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<div className="kc-requiredFor">
|
||||
{REQUIRED_FOR.map((option) => (
|
||||
<Radio
|
||||
id={option.label}
|
||||
key={option.label}
|
||||
data-testid={option}
|
||||
isChecked={value === option.value}
|
||||
name="roles"
|
||||
onChange={() => onChange(Array.isArray(option.value) ? option.value : [option.value])}
|
||||
label={option.label}
|
||||
className="kc-requiredFor-option"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={t("requiredWhen")}
|
||||
fieldId="requiredWhen"
|
||||
hasNoPaddingTop
|
||||
>
|
||||
<Controller
|
||||
name="requiredWhen"
|
||||
data-testid="requiredWhen"
|
||||
defaultValue={ENABLED_REQUIRED_WHEN[0]}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<>
|
||||
{ENABLED_REQUIRED_WHEN.map((option) => (
|
||||
<Radio
|
||||
id={option}
|
||||
key={option}
|
||||
data-testid={option}
|
||||
isChecked={value === option}
|
||||
name="requiredWhen"
|
||||
onChange={() => {
|
||||
onChange(option);
|
||||
setRequiredWhenSelection(option);
|
||||
{requiredToggle && (
|
||||
<>
|
||||
<FormGroup
|
||||
label={t("requiredFor")}
|
||||
fieldId="requiredFor"
|
||||
hasNoPaddingTop
|
||||
>
|
||||
<Controller
|
||||
name="roles"
|
||||
data-testid="requiredFor"
|
||||
defaultValue={REQUIRED_FOR[0].value}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<div className="kc-requiredFor">
|
||||
{REQUIRED_FOR.map((option) => (
|
||||
<Radio
|
||||
id={option.label}
|
||||
key={option.label}
|
||||
data-testid={option}
|
||||
isChecked={value === option.value}
|
||||
name="roles"
|
||||
onChange={() => onChange(option.value)}
|
||||
label={option.label}
|
||||
className="kc-requiredFor-option"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={t("requiredWhen")}
|
||||
fieldId="requiredWhen"
|
||||
hasNoPaddingTop
|
||||
>
|
||||
<Controller
|
||||
name="requiredWhen"
|
||||
data-testid="requiredWhen"
|
||||
defaultValue={ENABLED_REQUIRED_WHEN[0]}
|
||||
control={form.control}
|
||||
render={({ onChange, value }) => (
|
||||
<>
|
||||
{ENABLED_REQUIRED_WHEN.map((option) => (
|
||||
<Radio
|
||||
id={option}
|
||||
key={option}
|
||||
data-testid={option}
|
||||
isChecked={value === option}
|
||||
name="requiredWhen"
|
||||
onChange={() => {
|
||||
onChange(option);
|
||||
setRequiredWhenSelection(option);
|
||||
}}
|
||||
label={option}
|
||||
className="pf-u-mb-md"
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup fieldId="kc-scope-required-when">
|
||||
<Controller
|
||||
name="scopeRequired"
|
||||
control={form.control}
|
||||
defaultValue={[]}
|
||||
render={({
|
||||
onChange,
|
||||
value,
|
||||
}: {
|
||||
onChange: (newValue: string[]) => void;
|
||||
value: string[];
|
||||
}) => (
|
||||
<Select
|
||||
name="scopeRequired"
|
||||
data-testid="required-when-scope-field"
|
||||
variant={SelectVariant.typeaheadMulti}
|
||||
typeAheadAriaLabel="Select"
|
||||
chipGroupProps={{
|
||||
numChips: 3,
|
||||
expandedText: t("common:hide"),
|
||||
collapsedText: t("common:showRemaining"),
|
||||
}}
|
||||
label={option}
|
||||
className="pf-u-mb-md"
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup fieldId="kc-scope-required-when">
|
||||
<Controller
|
||||
name="scopeRequired"
|
||||
control={form.control}
|
||||
defaultValue={[]}
|
||||
render={({
|
||||
onChange,
|
||||
value,
|
||||
}: {
|
||||
onChange: (newValue: string[]) => void;
|
||||
value: string[];
|
||||
}) => (
|
||||
<Select
|
||||
name="scopeRequired"
|
||||
data-testid="required-when-scope-field"
|
||||
variant={SelectVariant.typeaheadMulti}
|
||||
typeAheadAriaLabel="Select"
|
||||
chipGroupProps={{
|
||||
numChips: 3,
|
||||
expandedText: t("common:hide"),
|
||||
collapsedText: t("common:showRemaining"),
|
||||
}}
|
||||
onToggle={(isOpen) => setSelectRequiredForOpen(isOpen)}
|
||||
selections={value}
|
||||
onSelect={(_, selectedValue) => {
|
||||
const option = selectedValue.toString();
|
||||
let changedValue = [""];
|
||||
if (value) {
|
||||
changedValue = value.includes(option)
|
||||
? value.filter((item) => item !== option)
|
||||
: [...value, option];
|
||||
} else {
|
||||
changedValue = [option];
|
||||
}
|
||||
onChange(changedValue);
|
||||
}}
|
||||
onClear={(selectedValues) => {
|
||||
selectedValues.stopPropagation();
|
||||
onChange([]);
|
||||
}}
|
||||
isOpen={selectRequiredForOpen}
|
||||
isDisabled={requiredWhenSelection === "Always"}
|
||||
aria-labelledby={"scope"}
|
||||
>
|
||||
{clientScopes?.map((option) => (
|
||||
<SelectOption key={option.name} value={option.name} />
|
||||
))}
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
onToggle={(isOpen) => setSelectRequiredForOpen(isOpen)}
|
||||
selections={value}
|
||||
onSelect={(_, selectedValue) => {
|
||||
const option = selectedValue.toString();
|
||||
let changedValue = [""];
|
||||
if (value) {
|
||||
changedValue = value.includes(option)
|
||||
? value.filter((item) => item !== option)
|
||||
: [...value, option];
|
||||
} else {
|
||||
changedValue = [option];
|
||||
}
|
||||
onChange(changedValue);
|
||||
}}
|
||||
onClear={(selectedValues) => {
|
||||
selectedValues.stopPropagation();
|
||||
onChange([]);
|
||||
}}
|
||||
isOpen={selectRequiredForOpen}
|
||||
isDisabled={requiredWhenSelection === "Always"}
|
||||
aria-labelledby={"scope"}
|
||||
>
|
||||
{clientScopes?.map((option) => (
|
||||
<SelectOption key={option.name} value={option.name} />
|
||||
))}
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
</>
|
||||
)}
|
||||
</FormAccess>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue