2022-08-03 12:12:07 +00:00
|
|
|
import { useState } from "react";
|
2021-12-01 07:58:25 +00:00
|
|
|
import { useTranslation } from "react-i18next";
|
2023-01-18 10:12:32 +00:00
|
|
|
import { Controller, useFormContext } from "react-hook-form-v7";
|
2021-12-01 07:58:25 +00:00
|
|
|
import {
|
|
|
|
FormGroup,
|
|
|
|
Select,
|
|
|
|
SelectOption,
|
|
|
|
SelectVariant,
|
|
|
|
} from "@patternfly/react-core";
|
|
|
|
|
2022-09-21 14:49:25 +00:00
|
|
|
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
2021-12-01 07:58:25 +00:00
|
|
|
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
|
|
|
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
|
|
|
|
|
|
|
type Scope = {
|
|
|
|
id: string;
|
|
|
|
name: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const ScopePicker = ({ clientId }: { clientId: string }) => {
|
|
|
|
const { t } = useTranslation("clients");
|
|
|
|
const { control } = useFormContext();
|
|
|
|
|
|
|
|
const [open, setOpen] = useState(false);
|
2022-09-21 14:49:25 +00:00
|
|
|
const [scopes, setScopes] = useState<ScopeRepresentation[]>();
|
2021-12-01 07:58:25 +00:00
|
|
|
const [search, setSearch] = useState("");
|
|
|
|
|
2022-07-14 13:02:28 +00:00
|
|
|
const { adminClient } = useAdminClient();
|
2021-12-01 07:58:25 +00:00
|
|
|
|
|
|
|
useFetch(
|
|
|
|
() => {
|
|
|
|
const params = {
|
|
|
|
id: clientId,
|
|
|
|
first: 0,
|
|
|
|
max: 20,
|
|
|
|
deep: false,
|
|
|
|
name: search,
|
|
|
|
};
|
|
|
|
return adminClient.clients.listAllScopes(params);
|
|
|
|
},
|
2022-09-21 14:49:25 +00:00
|
|
|
setScopes,
|
2021-12-01 07:58:25 +00:00
|
|
|
[search]
|
|
|
|
);
|
|
|
|
|
2022-09-21 14:49:25 +00:00
|
|
|
const renderScopes = (scopes?: ScopeRepresentation[]) =>
|
|
|
|
scopes?.map((option) => (
|
|
|
|
<SelectOption key={option.id} value={option}>
|
|
|
|
{option.name}
|
|
|
|
</SelectOption>
|
|
|
|
));
|
|
|
|
|
2021-12-01 07:58:25 +00:00
|
|
|
return (
|
|
|
|
<FormGroup
|
|
|
|
label={t("authorizationScopes")}
|
|
|
|
labelIcon={
|
|
|
|
<HelpItem
|
|
|
|
helpText="clients-help:scopes"
|
2021-12-14 14:56:36 +00:00
|
|
|
fieldLabelId="clients:scopes"
|
2021-12-01 07:58:25 +00:00
|
|
|
/>
|
|
|
|
}
|
|
|
|
fieldId="scopes"
|
|
|
|
>
|
|
|
|
<Controller
|
|
|
|
name="scopes"
|
|
|
|
defaultValue={[]}
|
|
|
|
control={control}
|
2023-01-18 10:12:32 +00:00
|
|
|
render={({ field }) => (
|
2021-12-01 07:58:25 +00:00
|
|
|
<Select
|
|
|
|
toggleId="scopes"
|
|
|
|
variant={SelectVariant.typeaheadMulti}
|
|
|
|
chipGroupProps={{
|
|
|
|
numChips: 3,
|
|
|
|
expandedText: t("common:hide"),
|
|
|
|
collapsedText: t("common:showRemaining"),
|
|
|
|
}}
|
2022-09-21 14:49:25 +00:00
|
|
|
onToggle={setOpen}
|
2021-12-01 07:58:25 +00:00
|
|
|
isOpen={open}
|
2023-01-18 10:12:32 +00:00
|
|
|
selections={field.value.map((o: Scope) => o.name)}
|
2021-12-01 07:58:25 +00:00
|
|
|
onFilter={(_, value) => {
|
|
|
|
setSearch(value);
|
2022-09-21 14:49:25 +00:00
|
|
|
return renderScopes(scopes);
|
2021-12-01 07:58:25 +00:00
|
|
|
}}
|
|
|
|
onSelect={(_, selectedValue) => {
|
|
|
|
const option =
|
|
|
|
typeof selectedValue === "string"
|
|
|
|
? selectedValue
|
|
|
|
: (selectedValue as Scope).name;
|
2023-01-18 10:12:32 +00:00
|
|
|
const changedValue = field.value.find(
|
|
|
|
(o: Scope) => o.name === option
|
|
|
|
)
|
|
|
|
? field.value.filter((item: Scope) => item.name !== option)
|
|
|
|
: [...field.value, selectedValue];
|
|
|
|
field.onChange(changedValue);
|
2021-12-01 07:58:25 +00:00
|
|
|
}}
|
|
|
|
onClear={(event) => {
|
|
|
|
event.stopPropagation();
|
|
|
|
setSearch("");
|
2023-01-18 10:12:32 +00:00
|
|
|
field.onChange([]);
|
2021-12-01 07:58:25 +00:00
|
|
|
}}
|
|
|
|
aria-label={t("authorizationScopes")}
|
|
|
|
>
|
2022-09-21 14:49:25 +00:00
|
|
|
{renderScopes(scopes)}
|
2021-12-01 07:58:25 +00:00
|
|
|
</Select>
|
|
|
|
)}
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
);
|
|
|
|
};
|