keycloak-scim/src/clients/authorization/ResourcesPolicySelect.tsx
Erik Jan de Wit 5fd344a7bd
Added scope typed permission screen (#1933)
* added scope type permission

* review comments

* Update src/clients/authorization/PermissionDetails.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>

* Update src/clients/authorization/ScopeSelect.tsx

Co-authored-by: Jon Koops <jonkoops@gmail.com>

* PR review

Co-authored-by: Jon Koops <jonkoops@gmail.com>
2022-02-10 09:23:23 +01:00

90 lines
2.5 KiB
TypeScript

import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Controller, useFormContext } from "react-hook-form";
import { Select, SelectOption, SelectVariant } from "@patternfly/react-core";
import type PolicyRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyRepresentation";
import type { Clients } from "@keycloak/keycloak-admin-client/lib/resources/clients";
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
type ResourcesPolicySelectProps = {
name: string;
clientId: string;
searchFunction: keyof Pick<Clients, "listPolicies" | "listResources">;
variant?: SelectVariant;
};
export const ResourcesPolicySelect = ({
name,
searchFunction,
clientId,
variant = SelectVariant.typeaheadMulti,
}: ResourcesPolicySelectProps) => {
const { t } = useTranslation("clients");
const adminClient = useAdminClient();
const { control } = useFormContext<PolicyRepresentation>();
const [items, setItems] = useState<JSX.Element[]>([]);
const [search, setSearch] = useState("");
const [open, setOpen] = useState(false);
useFetch(
async () =>
(
await adminClient.clients[searchFunction](
Object.assign(
{ id: clientId, first: 0, max: 10 },
search === "" ? null : { name: search }
)
)
).map((p) => ({
id: "_id" in p ? p._id : "id" in p ? p.id : undefined,
name: p.name,
})),
(policies) =>
setItems(
policies.map((p) => (
<SelectOption key={p.id} value={p.id}>
{p.name}
</SelectOption>
))
),
[search]
);
return (
<Controller
name={name}
defaultValue={[]}
control={control}
render={({ onChange, value }) => (
<Select
toggleId={name}
variant={variant}
onToggle={setOpen}
onFilter={(_, filter) => {
setSearch(filter);
return items;
}}
onClear={() => {
onChange([]);
setSearch("");
}}
selections={value}
onSelect={(_, selectedValue) => {
const option = selectedValue.toString();
const changedValue = value.find((p: string) => p === option)
? value.filter((p: string) => p !== option)
: [...value, option];
onChange(changedValue);
setSearch("");
}}
isOpen={open}
aria-labelledby={t(name)}
>
{items}
</Select>
)}
/>
);
};