keycloak-scim/js/apps/admin-ui/src/identity-providers/component/DiscoveryEndpointField.tsx

123 lines
3.4 KiB
TypeScript
Raw Normal View History

import { FormGroup, Spinner, Switch } from "@patternfly/react-core";
import debouncePromise from "p-debounce";
import { ReactNode, useMemo, useState } from "react";
import { useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { HelpItem, TextControl } from "@keycloak/keycloak-ui-shared";
import { adminClient } from "../../admin-client";
type DiscoveryEndpointFieldProps = {
id: string;
fileUpload: ReactNode;
children: (readOnly: boolean) => ReactNode;
};
export const DiscoveryEndpointField = ({
id,
fileUpload,
children,
}: DiscoveryEndpointFieldProps) => {
const { t } = useTranslation();
const {
setValue,
clearErrors,
formState: { errors },
} = useFormContext();
const [discovery, setDiscovery] = useState(true);
const [discovering, setDiscovering] = useState(false);
const [discoveryResult, setDiscoveryResult] =
useState<Record<string, string>>();
const setupForm = (result: Record<string, string>) => {
Object.keys(result).map((k) => setValue(`config.${k}`, result[k]));
};
const discover = async (fromUrl: string) => {
setDiscovering(true);
try {
const result = await adminClient.identityProviders.importFromUrl({
providerId: id,
fromUrl,
});
setupForm(result);
setDiscoveryResult(result);
} catch (error) {
return (error as Error).message;
} finally {
setDiscovering(false);
}
};
const discoverDebounced = useMemo(() => debouncePromise(discover, 1000), []);
return (
<>
<FormGroup
2022-02-21 13:55:02 +00:00
label={t(
id === "oidc" ? "useDiscoveryEndpoint" : "useEntityDescriptor",
2022-02-21 13:55:02 +00:00
)}
fieldId="kc-discovery-endpoint"
labelIcon={
<HelpItem
helpText={t(
id === "oidc"
? "useDiscoveryEndpointHelp"
: "useEntityDescriptorHelp",
)}
fieldLabelId="discoveryEndpoint"
/>
}
>
<Switch
id="kc-discovery-endpoint-switch"
label={t("on")}
labelOff={t("off")}
isChecked={discovery}
onChange={(_event, checked) => {
clearErrors("discoveryError");
setDiscovery(checked);
}}
aria-label={t(
id === "oidc" ? "useDiscoveryEndpoint" : "useEntityDescriptor",
)}
/>
</FormGroup>
{discovery && (
<TextControl
name="discoveryEndpoint"
2022-02-21 13:55:02 +00:00
label={t(
id === "oidc" ? "discoveryEndpoint" : "samlEntityDescriptor",
2022-02-21 13:55:02 +00:00
)}
labelIcon={t(
id === "oidc"
? "discoveryEndpointHelp"
: "samlEntityDescriptorHelp",
)}
type="url"
placeholder={
id === "oidc"
? "https://hostname/auth/realms/master/.well-known/openid-configuration"
: ""
}
validated={
errors.discoveryError || errors.discoveryEndpoint
? "error"
: !discoveryResult
? "default"
: "success"
}
customIcon={discovering ? <Spinner isInline /> : undefined}
rules={{
required: t("required"),
validate: (value: string) => discoverDebounced(value),
}}
/>
)}
{!discovery && fileUpload}
{discovery && !errors.discoveryError && children(true)}
{!discovery && children(false)}
</>
);
};