From c0a9b5cebce81a3e4d87871a8b6861fe899c81da Mon Sep 17 00:00:00 2001 From: Erik Jan de Wit Date: Wed, 16 Feb 2022 15:53:45 +0100 Subject: [PATCH] Made form readonly and fixed initialisation (#2070) * add the ablity for dynamic component to become disabeled when used in a Co-authored-by: Jon Koops --- src/components/dynamic/BooleanComponent.tsx | 2 + .../dynamic/ClientSelectComponent.tsx | 2 + src/components/dynamic/DynamicComponents.tsx | 7 +++- src/components/dynamic/ListComponent.tsx | 2 + .../dynamic/MultivaluedChipsComponent.tsx | 2 + .../dynamic/MultivaluedListComponent.tsx | 2 + .../dynamic/MultivaluedRoleComponent.tsx | 2 + .../dynamic/MultivaluedScopesComponent.tsx | 2 + .../dynamic/MultivaluedStringComponent.tsx | 2 + src/components/dynamic/RoleComponent.tsx | 8 +++- src/components/dynamic/ScriptComponent.tsx | 2 + src/components/dynamic/StringComponent.tsx | 2 + src/components/dynamic/components.ts | 5 ++- src/components/form-access/FormAccess.tsx | 8 +++- src/realm-settings/ExecutorForm.tsx | 37 ++++++++++--------- 15 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/components/dynamic/BooleanComponent.tsx b/src/components/dynamic/BooleanComponent.tsx index a63eb38955..b4af4e71d6 100644 --- a/src/components/dynamic/BooleanComponent.tsx +++ b/src/components/dynamic/BooleanComponent.tsx @@ -11,6 +11,7 @@ export const BooleanComponent = ({ label, helpText, defaultValue, + isDisabled = false, }: ComponentProps) => { const { t } = useTranslation("dynamic"); const { control } = useFormContext(); @@ -32,6 +33,7 @@ export const BooleanComponent = ({ render={({ onChange, value }) => ( { const { t } = useTranslation("dynamic"); const { control } = useFormContext(); @@ -66,6 +67,7 @@ export const ClientSelectComponent = ({ variant={SelectVariant.typeahead} onToggle={(open) => setOpen(open)} isOpen={open} + isDisabled={isDisabled} selections={value} onFilter={(_, value) => { setSearch(value); diff --git a/src/components/dynamic/DynamicComponents.tsx b/src/components/dynamic/DynamicComponents.tsx index fd3b7ceea2..504e7a90ea 100644 --- a/src/components/dynamic/DynamicComponents.tsx +++ b/src/components/dynamic/DynamicComponents.tsx @@ -9,13 +9,16 @@ type DynamicComponentProps = { parentCallback?: (data: string[]) => void; }; -export const DynamicComponents = ({ properties }: DynamicComponentProps) => ( +export const DynamicComponents = ({ + properties, + ...rest +}: DynamicComponentProps) => ( <> {properties.map((property) => { const componentType = property.type!; if (isValidComponentType(componentType) && property.name !== "scopes") { const Component = COMPONENTS[componentType]; - return ; + return ; } else { console.warn(`There is no editor registered for ${componentType}`); } diff --git a/src/components/dynamic/ListComponent.tsx b/src/components/dynamic/ListComponent.tsx index afd569828c..eea408c336 100644 --- a/src/components/dynamic/ListComponent.tsx +++ b/src/components/dynamic/ListComponent.tsx @@ -17,6 +17,7 @@ export const ListComponent = ({ helpText, defaultValue, options, + isDisabled = false, }: ComponentProps) => { const { t } = useTranslation("dynamic"); const { control } = useFormContext(); @@ -38,6 +39,7 @@ export const ListComponent = ({ render={({ onChange, value }) => ( { const { t } = useTranslation("dynamic"); const { whoAmI } = useWhoAmI(); @@ -73,6 +74,7 @@ export const MultivaluedRoleComponent = ({ rules={{ required: true }} render={({ onChange, value }) => ( setClientsOpen(!clientsOpen)} isOpen={clientsOpen} variant={SelectVariant.typeahead} diff --git a/src/components/dynamic/ScriptComponent.tsx b/src/components/dynamic/ScriptComponent.tsx index b1b487961b..286d2d2148 100644 --- a/src/components/dynamic/ScriptComponent.tsx +++ b/src/components/dynamic/ScriptComponent.tsx @@ -12,6 +12,7 @@ export const ScriptComponent = ({ label, helpText, defaultValue, + isDisabled = false, }: ComponentProps) => { const { t } = useTranslation("dynamic"); const { control } = useFormContext(); @@ -35,6 +36,7 @@ export const ScriptComponent = ({ { const { t } = useTranslation("dynamic"); const { register } = useFormContext(); @@ -26,6 +27,7 @@ export const StringComponent = ({ ; +export type ComponentProps = Omit & { + isDisabled?: boolean; +}; + const ComponentTypes = [ "String", "boolean", diff --git a/src/components/form-access/FormAccess.tsx b/src/components/form-access/FormAccess.tsx index bca014f8cf..3b8a89ebc7 100644 --- a/src/components/form-access/FormAccess.tsx +++ b/src/components/form-access/FormAccess.tsx @@ -41,6 +41,11 @@ export type FormAccessProps = FormProps & { * @type {boolean} */ unWrap?: boolean; + + /** + * Overwrite the fineGrainedAccess and make form regardless of access rights. + */ + isReadOnly?: boolean; }; /** @@ -51,6 +56,7 @@ export const FormAccess: FunctionComponent = ({ children, role, fineGrainedAccess = false, + isReadOnly = false, unWrap = false, ...rest }) => { @@ -107,7 +113,7 @@ export const FormAccess: FunctionComponent = ({ }); }; - const isDisabled = !hasAccess(role) && !fineGrainedAccess; + const isDisabled = isReadOnly || (!hasAccess(role) && !fineGrainedAccess); return ( <> diff --git a/src/realm-settings/ExecutorForm.tsx b/src/realm-settings/ExecutorForm.tsx index 36f30b7063..1a17bc7159 100644 --- a/src/realm-settings/ExecutorForm.tsx +++ b/src/realm-settings/ExecutorForm.tsx @@ -24,7 +24,6 @@ import type ClientProfileRepresentation from "@keycloak/keycloak-admin-client/li import { ClientProfileParams, toClientProfile } from "./routes/ClientProfile"; import { DynamicComponents } from "../components/dynamic/DynamicComponents"; import type { ExecutorParams } from "./routes/Executor"; -import { convertToFormValues } from "../util"; type ExecutorForm = { config: object; @@ -57,28 +56,27 @@ export default function ExecutorForm() { ClientProfileRepresentation[] >([]); const [profiles, setProfiles] = useState([]); - const form = useForm({ defaultValues }); - const { control, setValue, handleSubmit } = form; + const form = useForm({ defaultValues, shouldUnregister: false }); + const { control, reset, handleSubmit } = form; const editMode = !!executorName; + const setupForm = (profiles: ClientProfileRepresentation[]) => { + const profile = profiles.find((profile) => profile.name === profileName); + const executor = profile?.executors?.find( + (executor) => executor.executor === executorName + ); + if (executor) reset({ config: executor.configuration }); + }; + useFetch( () => adminClient.clientPolicies.listProfiles({ includeGlobalProfiles: true }), (profiles) => { - setGlobalProfiles(profiles.globalProfiles ?? []); - setProfiles(profiles.profiles ?? []); + setGlobalProfiles(profiles.globalProfiles!); + setProfiles(profiles.profiles!); - const profile = profiles.profiles!.find( - (profile) => profile.name === profileName - ); - - const profileExecutor = profile?.executors!.find( - (executor) => executor.executor === executorName - ); - - if (profileExecutor) { - convertToFormValues(profileExecutor, setValue); - } + setupForm(profiles.profiles!); + setupForm(profiles.globalProfiles!); }, [] ); @@ -163,7 +161,12 @@ export default function ExecutorForm() { divider /> - +