fixing the remainder of issue 428 (#621)
* fixing the remainder of issue 428 fixing: #428 * fix undefined * add leave dialog
This commit is contained in:
parent
0f6ce35687
commit
29323cb12c
7 changed files with 82 additions and 31 deletions
|
@ -35,7 +35,7 @@ export const SignedJWT = () => {
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
name="attributes.token-endpoint-auth-signing-alg"
|
name="attributes.token-endpoint-auth-signing-alg"
|
||||||
defaultValue={providers[0]}
|
defaultValue=""
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<Select
|
<Select
|
||||||
|
@ -46,18 +46,23 @@ export const SignedJWT = () => {
|
||||||
onChange(value as string);
|
onChange(value as string);
|
||||||
isOpen(false);
|
isOpen(false);
|
||||||
}}
|
}}
|
||||||
selections={value}
|
selections={value || t("anyAlgorithm")}
|
||||||
variant={SelectVariant.single}
|
variant={SelectVariant.single}
|
||||||
aria-label={t("signatureAlgorithm")}
|
aria-label={t("signatureAlgorithm")}
|
||||||
isOpen={open}
|
isOpen={open}
|
||||||
>
|
>
|
||||||
{providers.map((option) => (
|
<SelectOption selected={value === ""} key="any" value="">
|
||||||
<SelectOption
|
{t("anyAlgorithm")}
|
||||||
selected={option === value}
|
</SelectOption>
|
||||||
key={option}
|
<>
|
||||||
value={option}
|
{providers.map((option) => (
|
||||||
/>
|
<SelectOption
|
||||||
))}
|
selected={option === value}
|
||||||
|
key={option}
|
||||||
|
value={option}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
</Select>
|
</Select>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useFormContext } from "react-hook-form";
|
import { useFormContext } from "react-hook-form";
|
||||||
import { FormGroup, TextInput } from "@patternfly/react-core";
|
import { FormGroup, TextInput, ValidatedOptions } from "@patternfly/react-core";
|
||||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||||
|
|
||||||
export const X509 = () => {
|
export const X509 = () => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
const { register } = useFormContext();
|
const { register, errors } = useFormContext();
|
||||||
return (
|
return (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={t("subject")}
|
label={t("subject")}
|
||||||
|
@ -18,12 +18,24 @@ export const X509 = () => {
|
||||||
forID="kc-subject"
|
forID="kc-subject"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
helperTextInvalid={t("common:required")}
|
||||||
|
validated={
|
||||||
|
errors.attributes && errors.attributes["x509-subjectdn"]
|
||||||
|
? ValidatedOptions.error
|
||||||
|
: ValidatedOptions.default
|
||||||
|
}
|
||||||
|
isRequired
|
||||||
>
|
>
|
||||||
<TextInput
|
<TextInput
|
||||||
ref={register()}
|
ref={register({ required: true })}
|
||||||
type="text"
|
type="text"
|
||||||
id="kc-subject"
|
id="kc-subject"
|
||||||
name="attributes.x509-subjectdn"
|
name="attributes.x509-subjectdn"
|
||||||
|
validated={
|
||||||
|
errors.attributes && errors.attributes["x509-subjectdn"]
|
||||||
|
? ValidatedOptions.error
|
||||||
|
: ValidatedOptions.default
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
);
|
);
|
||||||
|
|
|
@ -128,6 +128,7 @@
|
||||||
"changeAuthenticatorConfirmTitle": "Change to {{clientAuthenticatorType}}",
|
"changeAuthenticatorConfirmTitle": "Change to {{clientAuthenticatorType}}",
|
||||||
"changeAuthenticatorConfirm": "If you change authenticator to {{clientAuthenticatorType}}, the keycloak database will be updated and you may need to download a new adapter configuration for this client",
|
"changeAuthenticatorConfirm": "If you change authenticator to {{clientAuthenticatorType}}, the keycloak database will be updated and you may need to download a new adapter configuration for this client",
|
||||||
"signedJWTConfirm": "You should configure JWKS URL or keys in the \"Keys\" tab to change the parameters of Signed JWT authenticator.",
|
"signedJWTConfirm": "You should configure JWKS URL or keys in the \"Keys\" tab to change the parameters of Signed JWT authenticator.",
|
||||||
|
"anyAlgorithm": "Any algorithm",
|
||||||
"clientSecret": "Client secret",
|
"clientSecret": "Client secret",
|
||||||
"regenerate": "Regenerate",
|
"regenerate": "Regenerate",
|
||||||
"confirmClientSecretTitle": "Regenerate secret for this client?",
|
"confirmClientSecretTitle": "Regenerate secret for this client?",
|
||||||
|
|
|
@ -127,6 +127,10 @@
|
||||||
|
|
||||||
"emptyMappers": "No mappers",
|
"emptyMappers": "No mappers",
|
||||||
"emptyMappersInstructions": "If you want to add mappers, please click the button below to add some predefined mappers or to configure a new mapper.",
|
"emptyMappersInstructions": "If you want to add mappers, please click the button below to add some predefined mappers or to configure a new mapper.",
|
||||||
"emptyPrimaryAction": "Add predefined mapper"
|
"emptyPrimaryAction": "Add predefined mapper",
|
||||||
|
|
||||||
|
"leaveDirtyTitle": "Leave without saving?",
|
||||||
|
"leaveDirtyConfirm": "Do you want to leave this page without saving? Any unsaved changes will be lost.",
|
||||||
|
"leave": "Leave"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import React, { Children, isValidElement } from "react";
|
import React, { Children, isValidElement, useState } from "react";
|
||||||
import { useHistory, useRouteMatch } from "react-router-dom";
|
import { useHistory, useRouteMatch } from "react-router-dom";
|
||||||
import { TabProps, Tabs, TabsProps } from "@patternfly/react-core";
|
import { TabProps, Tabs, TabsProps } from "@patternfly/react-core";
|
||||||
|
import { useFormContext } from "react-hook-form";
|
||||||
|
import { useConfirmDialog } from "../confirm-dialog/ConfirmDialog";
|
||||||
|
|
||||||
type KeycloakTabsProps = Omit<TabsProps, "ref" | "activeKey" | "onSelect"> & {
|
type KeycloakTabsProps = Omit<TabsProps, "ref" | "activeKey" | "onSelect"> & {
|
||||||
paramName?: string;
|
paramName?: string;
|
||||||
|
@ -28,6 +30,8 @@ export const KeycloakTabs = ({
|
||||||
const match = useRouteMatch();
|
const match = useRouteMatch();
|
||||||
const params = match.params as { [index: string]: string };
|
const params = match.params as { [index: string]: string };
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const form = useFormContext();
|
||||||
|
const [key, setKey] = useState("");
|
||||||
|
|
||||||
const firstTab = Children.toArray(children)[0];
|
const firstTab = Children.toArray(children)[0];
|
||||||
const tab =
|
const tab =
|
||||||
|
@ -37,21 +41,42 @@ export const KeycloakTabs = ({
|
||||||
|
|
||||||
const pathIndex = match.path.indexOf(paramName) + paramName.length;
|
const pathIndex = match.path.indexOf(paramName) + paramName.length;
|
||||||
const path = match.path.substr(0, pathIndex);
|
const path = match.path.substr(0, pathIndex);
|
||||||
|
|
||||||
|
const [toggleChangeTabDialog, ChangeTabConfirm] = useConfirmDialog({
|
||||||
|
titleKey: "common:leaveDirtyTitle",
|
||||||
|
messageKey: "common:leaveDirtyConfirm",
|
||||||
|
continueButtonLabel: "common:leave",
|
||||||
|
onConfirm: () => {
|
||||||
|
form.reset();
|
||||||
|
history.push(createUrl(path, { ...params, [paramName]: key as string }));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<>
|
||||||
inset={{
|
<ChangeTabConfirm />
|
||||||
default: "insetNone",
|
<Tabs
|
||||||
md: "insetSm",
|
inset={{
|
||||||
xl: "inset2xl",
|
default: "insetNone",
|
||||||
"2xl": "insetLg",
|
md: "insetSm",
|
||||||
}}
|
xl: "inset2xl",
|
||||||
activeKey={tab}
|
"2xl": "insetLg",
|
||||||
onSelect={(_, key) =>
|
}}
|
||||||
history.push(createUrl(path, { ...params, [paramName]: key as string }))
|
activeKey={tab}
|
||||||
}
|
onSelect={(_, key) => {
|
||||||
{...rest}
|
if (form?.formState.isDirty) {
|
||||||
>
|
setKey(key as string);
|
||||||
{children}
|
toggleChangeTabDialog();
|
||||||
</Tabs>
|
} else {
|
||||||
|
history.push(
|
||||||
|
createUrl(path, { ...params, [paramName]: key as string })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Tabs>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ export function convertToMultiline(fields: string[]): MultiLine[] {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toValue(formValue: MultiLine[]): string[] {
|
export function toValue(formValue: MultiLine[]): string[] {
|
||||||
return formValue.map((field) => field.value);
|
return formValue?.map((field) => field.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MultiLineInputProps = Omit<TextInputProps, "form"> & {
|
export type MultiLineInputProps = Omit<TextInputProps, "form"> & {
|
||||||
|
|
|
@ -45,7 +45,11 @@ export const ScrollForm = ({
|
||||||
</ScrollPanel>
|
</ScrollPanel>
|
||||||
)}
|
)}
|
||||||
{borders && (
|
{borders && (
|
||||||
<FormPanel scrollId={spacesToHyphens(cat)} title={cat}>
|
<FormPanel
|
||||||
|
scrollId={spacesToHyphens(cat)}
|
||||||
|
title={cat}
|
||||||
|
className="kc-form-panel__panel"
|
||||||
|
>
|
||||||
{nodes[index]}
|
{nodes[index]}
|
||||||
</FormPanel>
|
</FormPanel>
|
||||||
)}
|
)}
|
||||||
|
|
Loading…
Reference in a new issue