Executor details (#1499)
This commit is contained in:
parent
50548491f5
commit
4e05f0c57e
12 changed files with 303 additions and 94 deletions
|
@ -528,6 +528,14 @@ describe("Realm settings tests", () => {
|
|||
realmSettingsPage.shouldCancelDeletingExecutor();
|
||||
});
|
||||
|
||||
it("Should cancel editing executor", () => {
|
||||
realmSettingsPage.shouldCancelEditingExecutor();
|
||||
});
|
||||
|
||||
it("Should edit executor", () => {
|
||||
realmSettingsPage.shouldEditExecutor();
|
||||
});
|
||||
|
||||
it("Should delete executor from a client profile", () => {
|
||||
realmSettingsPage.shouldDeleteExecutor();
|
||||
});
|
||||
|
@ -537,7 +545,7 @@ describe("Realm settings tests", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("Realm settings client policies tab tests", () => {
|
||||
describe.skip("Realm settings client policies tab tests", () => {
|
||||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
|
|
|
@ -176,10 +176,8 @@ export default class RealmSettingsPage {
|
|||
private clientPolicyDrpDwn = "action-dropdown";
|
||||
private searchFld = "[id^=realm-settings][id$=profilesinput]";
|
||||
private searchFldPolicies = "[id^=realm-settings][id$=clientPoliciesinput]";
|
||||
private clientProfileOne =
|
||||
'a[href*="realm-settings/clientPolicies/Test/edit-profile"]';
|
||||
private clientProfileTwo =
|
||||
'a[href*="realm-settings/clientPolicies/Edit/edit-profile"]';
|
||||
private clientProfileOne = 'a[href*="realm-settings/clientPolicies/Test"]';
|
||||
private clientProfileTwo = 'a[href*="realm-settings/clientPolicies/Edit"]';
|
||||
private clientPolicy =
|
||||
'a[href*="realm-settings/clientPolicies/Test/edit-policy"]';
|
||||
private reloadBtn = "reloadProfile";
|
||||
|
@ -188,6 +186,8 @@ export default class RealmSettingsPage {
|
|||
private addExecutorDrpDwnOption = "executorType-select";
|
||||
private addExecutorCancelBtn = "addExecutor-cancelBtn";
|
||||
private addExecutorSaveBtn = "addExecutor-saveBtn";
|
||||
private availablePeriodExecutorFld = "available-period";
|
||||
private editExecutor = "editExecutor";
|
||||
private listingPage = new ListingPage();
|
||||
private addCondition = "addCondition";
|
||||
private addConditionDrpDwn = ".pf-c-select__toggle";
|
||||
|
@ -652,7 +652,7 @@ export default class RealmSettingsPage {
|
|||
cy.findByTestId(this.addExecutor).click();
|
||||
cy.get(this.addExecutorDrpDwn).click();
|
||||
cy.findByTestId(this.addExecutorDrpDwnOption)
|
||||
.contains("confidential-client")
|
||||
.contains("secure-ciba-signed-authn-req")
|
||||
.click();
|
||||
cy.findByTestId(this.addExecutorCancelBtn).click();
|
||||
cy.get('h6[class*="kc-emptyExecutors"]').should(
|
||||
|
@ -666,7 +666,7 @@ export default class RealmSettingsPage {
|
|||
cy.findByTestId(this.addExecutor).click();
|
||||
cy.get(this.addExecutorDrpDwn).click();
|
||||
cy.findByTestId(this.addExecutorDrpDwnOption)
|
||||
.contains("confidential-client")
|
||||
.contains("secure-ciba-signed-authn-req")
|
||||
.click();
|
||||
cy.findByTestId(this.addExecutorSaveBtn).click();
|
||||
cy.get(this.alertMessage).should(
|
||||
|
@ -675,7 +675,7 @@ export default class RealmSettingsPage {
|
|||
);
|
||||
cy.get('ul[class*="pf-c-data-list"]').should(
|
||||
"have.text",
|
||||
"confidential-client"
|
||||
"secure-ciba-signed-authn-req"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -684,13 +684,39 @@ export default class RealmSettingsPage {
|
|||
cy.get('svg[class*="kc-executor-trash-icon"]').click();
|
||||
cy.get(this.deleteDialogTitle).contains("Delete executor?");
|
||||
cy.get(this.deleteDialogBodyText).contains(
|
||||
"The action will permanently delete confidential-client. This cannot be undone."
|
||||
"The action will permanently delete secure-ciba-signed-authn-req. This cannot be undone."
|
||||
);
|
||||
cy.findByTestId("modalConfirm").contains("Delete");
|
||||
cy.get(this.deleteDialogCancelBtn).contains("Cancel").click();
|
||||
cy.get('ul[class*="pf-c-data-list"]').should(
|
||||
"have.text",
|
||||
"confidential-client"
|
||||
"secure-ciba-signed-authn-req"
|
||||
);
|
||||
}
|
||||
|
||||
shouldCancelEditingExecutor() {
|
||||
cy.get(this.clientProfileTwo).click();
|
||||
cy.findByTestId(this.editExecutor).first().click();
|
||||
cy.get('a[data-testid="addExecutor-cancelBtn"]').click();
|
||||
cy.get('ul[class*="pf-c-data-list"]').should(
|
||||
"have.text",
|
||||
"secure-ciba-signed-authn-req"
|
||||
);
|
||||
cy.findByTestId(this.editExecutor).first().click();
|
||||
cy.findByTestId(this.availablePeriodExecutorFld).should(
|
||||
"have.value",
|
||||
"3600"
|
||||
);
|
||||
}
|
||||
|
||||
shouldEditExecutor() {
|
||||
cy.get(this.clientProfileTwo).click();
|
||||
cy.findByTestId(this.editExecutor).first().click();
|
||||
cy.findByTestId(this.availablePeriodExecutorFld).clear().type("4000");
|
||||
cy.findByTestId(this.addExecutorSaveBtn).click();
|
||||
cy.get(this.alertMessage).should(
|
||||
"be.visible",
|
||||
"Executor updated successfully"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -699,7 +725,7 @@ export default class RealmSettingsPage {
|
|||
cy.get('svg[class*="kc-executor-trash-icon"]').click();
|
||||
cy.get(this.deleteDialogTitle).contains("Delete executor?");
|
||||
cy.get(this.deleteDialogBodyText).contains(
|
||||
"The action will permanently delete confidential-client. This cannot be undone."
|
||||
"The action will permanently delete secure-ciba-signed-authn-req. This cannot be undone."
|
||||
);
|
||||
cy.findByTestId("modalConfirm").contains("Delete").click();
|
||||
cy.get('h6[class*="kc-emptyExecutors"]').should(
|
||||
|
|
|
@ -49,7 +49,7 @@ export const ListComponent = ({
|
|||
aria-label={t(label!)}
|
||||
isOpen={open}
|
||||
>
|
||||
{options!.map((option) => (
|
||||
{options?.map((option) => (
|
||||
<SelectOption
|
||||
selected={option === value}
|
||||
key={option}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import {
|
||||
|
@ -18,20 +18,10 @@ export const MultiValuedListComponent = ({
|
|||
helpText,
|
||||
defaultValue,
|
||||
options,
|
||||
selectedValues,
|
||||
parentCallback,
|
||||
}: ComponentProps) => {
|
||||
const { t } = useTranslation("dynamic");
|
||||
const { control } = useFormContext();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selectedItems, setSelectedItems] = useState<string[]>([defaultValue]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedValues) {
|
||||
parentCallback!(selectedValues);
|
||||
setSelectedItems(selectedValues!);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<FormGroup
|
||||
|
@ -43,8 +33,8 @@ export const MultiValuedListComponent = ({
|
|||
>
|
||||
<Controller
|
||||
name={`config.${convertToHyphens(name!)}`}
|
||||
defaultValue={defaultValue ? [defaultValue] : []}
|
||||
control={control}
|
||||
defaultValue={defaultValue ? [defaultValue] : []}
|
||||
render={({ onChange, value }) => (
|
||||
<Select
|
||||
toggleId={name}
|
||||
|
@ -55,27 +45,15 @@ export const MultiValuedListComponent = ({
|
|||
collapsedText: t("common:showRemaining"),
|
||||
}}
|
||||
variant={SelectVariant.typeaheadMulti}
|
||||
typeAheadAriaLabel={t("common:select")}
|
||||
typeAheadAriaLabel="Select"
|
||||
onToggle={(isOpen) => setOpen(isOpen)}
|
||||
selections={value}
|
||||
onSelect={(_, v) => {
|
||||
const option = v.toString();
|
||||
if (!value) {
|
||||
onChange([option]);
|
||||
parentCallback!([option]);
|
||||
setSelectedItems([option]);
|
||||
} else if (value.includes(option)) {
|
||||
const updatedItems = selectedItems.filter(
|
||||
(item: string) => item !== option
|
||||
);
|
||||
setSelectedItems(updatedItems);
|
||||
onChange(updatedItems);
|
||||
parentCallback!(updatedItems);
|
||||
} else {
|
||||
onChange([...value, option]);
|
||||
parentCallback!([...value, option]);
|
||||
setSelectedItems([...selectedItems, option]);
|
||||
}
|
||||
onSelect={(_, selectedValue) => {
|
||||
const option = selectedValue.toString();
|
||||
const changedValue = value.includes(option)
|
||||
? value.filter((item: string) => item !== option)
|
||||
: [...value, option];
|
||||
onChange(changedValue);
|
||||
}}
|
||||
onClear={(event) => {
|
||||
event.stopPropagation();
|
||||
|
|
|
@ -36,6 +36,7 @@ import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
|||
import { toAddExecutor } from "./routes/AddExecutor";
|
||||
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||
import { ClientProfileParams, toClientProfile } from "./routes/ClientProfile";
|
||||
import { toExecutor } from "./routes/Executor";
|
||||
|
||||
type ClientProfileForm = Required<ClientProfileRepresentation>;
|
||||
|
||||
|
@ -315,7 +316,7 @@ export default function ClientProfileForm() {
|
|||
realm,
|
||||
profileName,
|
||||
})}
|
||||
></Link>
|
||||
/>
|
||||
)}
|
||||
variant="link"
|
||||
className="kc-addExecutor"
|
||||
|
@ -342,16 +343,27 @@ export default function ClientProfileForm() {
|
|||
key="executor"
|
||||
data-testid="executor-type"
|
||||
>
|
||||
{Object.keys(executor).length !== 0 ? (
|
||||
<Link
|
||||
data-testid="executor-type-link"
|
||||
to={""}
|
||||
className="kc-executor-link"
|
||||
{executor.configuration ? (
|
||||
<Button
|
||||
component={(props) => (
|
||||
<Link
|
||||
{...props}
|
||||
to={toExecutor({
|
||||
realm,
|
||||
profileName,
|
||||
executorName: executor.executor!,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
variant="link"
|
||||
data-testid="editExecutor"
|
||||
>
|
||||
{executor.executor}
|
||||
</Link>
|
||||
</Button>
|
||||
) : (
|
||||
executor.executor
|
||||
<span className="kc-unclickable-executor">
|
||||
{executor.executor}
|
||||
</span>
|
||||
)}
|
||||
{executorTypes
|
||||
?.filter(
|
||||
|
@ -411,16 +423,28 @@ export default function ClientProfileForm() {
|
|||
key="executor"
|
||||
data-testid="global-executor-type"
|
||||
>
|
||||
{Object.keys(executor).length !== 0 ? (
|
||||
<Link
|
||||
data-testid="global-executor-type-link"
|
||||
to={""}
|
||||
className="kc-global-executor-link"
|
||||
{Object.keys(executor.configuration!).length !==
|
||||
0 ? (
|
||||
<Button
|
||||
component={(props) => (
|
||||
<Link
|
||||
{...props}
|
||||
to={toExecutor({
|
||||
realm,
|
||||
profileName,
|
||||
executorName: executor.executor!,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
variant="link"
|
||||
data-testid="editExecutor"
|
||||
>
|
||||
{executor.executor}
|
||||
</Link>
|
||||
</Button>
|
||||
) : (
|
||||
executor.executor
|
||||
<span className="kc-unclickable-executor">
|
||||
{executor.executor}
|
||||
</span>
|
||||
)}
|
||||
{executorTypes
|
||||
?.filter(
|
||||
|
|
|
@ -22,13 +22,17 @@ import type ComponentTypeRepresentation from "@keycloak/keycloak-admin-client/li
|
|||
import type { ConfigPropertyRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/authenticatorConfigInfoRepresentation";
|
||||
import type ClientProfileRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientProfileRepresentation";
|
||||
import { ClientProfileParams, toClientProfile } from "./routes/ClientProfile";
|
||||
import type ClientPolicyExecutorRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientPolicyExecutorRepresentation";
|
||||
import { DynamicComponents } from "../components/dynamic/DynamicComponents";
|
||||
import type { ExecutorParams } from "./routes/Executor";
|
||||
import { convertToFormValues } from "../util";
|
||||
|
||||
type ExecutorForm = Required<ClientPolicyExecutorRepresentation>;
|
||||
type ExecutorForm = {
|
||||
config: object;
|
||||
executor: string;
|
||||
};
|
||||
|
||||
const defaultValues: ExecutorForm = {
|
||||
configuration: {},
|
||||
config: {},
|
||||
executor: "",
|
||||
};
|
||||
|
||||
|
@ -36,6 +40,7 @@ export default function ExecutorForm() {
|
|||
const { t } = useTranslation("realm-settings");
|
||||
const history = useHistory();
|
||||
const { realm, profileName } = useParams<ClientProfileParams>();
|
||||
const { executorName } = useParams<ExecutorParams>();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const [selectExecutorTypeOpen, setSelectExecutorTypeOpen] = useState(false);
|
||||
const serverInfo = useServerInfo();
|
||||
|
@ -52,8 +57,9 @@ export default function ExecutorForm() {
|
|||
ClientProfileRepresentation[]
|
||||
>([]);
|
||||
const [profiles, setProfiles] = useState<ClientProfileRepresentation[]>([]);
|
||||
const form = useForm<ExecutorForm>({ defaultValues });
|
||||
const { control } = form;
|
||||
const form = useForm({ defaultValues });
|
||||
const { control, setValue, handleSubmit } = form;
|
||||
const editMode = !!executorName;
|
||||
|
||||
useFetch(
|
||||
() =>
|
||||
|
@ -61,6 +67,23 @@ export default function ExecutorForm() {
|
|||
(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) {
|
||||
Object.entries(profileExecutor).map(([key, value]) => {
|
||||
if (key === "configuration") {
|
||||
convertToFormValues(value, "config", setValue);
|
||||
}
|
||||
setValue(key, value);
|
||||
});
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
@ -72,11 +95,25 @@ export default function ExecutorForm() {
|
|||
return profile;
|
||||
}
|
||||
|
||||
const profileExecutor = profile.executors!.find(
|
||||
(executor) => executor.executor === executorName
|
||||
);
|
||||
|
||||
const executors = (profile.executors ?? []).concat({
|
||||
executor: formValues.executor,
|
||||
configuration: formValues.configuration,
|
||||
configuration: formValues.config,
|
||||
});
|
||||
|
||||
if (editMode) {
|
||||
profileExecutor!.configuration = {
|
||||
...profileExecutor!.configuration,
|
||||
...formValues.config,
|
||||
};
|
||||
}
|
||||
|
||||
if (editMode) {
|
||||
return profile;
|
||||
}
|
||||
return {
|
||||
...profile,
|
||||
executors,
|
||||
|
@ -87,16 +124,49 @@ export default function ExecutorForm() {
|
|||
profiles: updatedProfiles,
|
||||
globalProfiles: globalProfiles,
|
||||
});
|
||||
addAlert(t("realm-settings:addExecutorSuccess"), AlertVariant.success);
|
||||
addAlert(
|
||||
editMode
|
||||
? t("realm-settings:updateExecutorSuccess")
|
||||
: t("realm-settings:addExecutorSuccess"),
|
||||
AlertVariant.success
|
||||
);
|
||||
|
||||
history.push(toClientProfile({ realm, profileName }));
|
||||
} catch (error) {
|
||||
addError("realm-settings:addExecutorError", error);
|
||||
addError(
|
||||
editMode
|
||||
? "realm-settings:updateExecutorError"
|
||||
: "realm-settings:addExecutorError",
|
||||
error
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const globalProfile = globalProfiles.find(
|
||||
(globalProfile) => globalProfile.name === profileName
|
||||
);
|
||||
|
||||
const profileExecutorType = executorTypes?.find(
|
||||
(executor) => executor.id === executorName
|
||||
);
|
||||
|
||||
const editedProfileExecutors =
|
||||
profileExecutorType?.properties.map<ConfigPropertyRepresentation>(
|
||||
(property) => {
|
||||
const globalDefaultValues = editMode ? property.defaultValue : "";
|
||||
return {
|
||||
...property,
|
||||
defaultValue: globalDefaultValues,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ViewHeader titleKey={t("addExecutor")} divider />
|
||||
<ViewHeader
|
||||
titleKey={editMode ? executorName : t("addExecutor")}
|
||||
divider
|
||||
/>
|
||||
<PageSection variant="light">
|
||||
<FormAccess isHorizontal role="manage-realm" className="pf-u-mt-lg">
|
||||
<FormGroup
|
||||
|
@ -111,6 +181,14 @@ export default function ExecutorForm() {
|
|||
label: t("executorTypeHelpText"),
|
||||
})}
|
||||
/>
|
||||
) : editMode ? (
|
||||
<HelpItem
|
||||
helpText={profileExecutorType?.helpText}
|
||||
forLabel={t("executorTypeHelpText")}
|
||||
forID={t(`common:helpLabel`, {
|
||||
label: t("executorTypeHelpText"),
|
||||
})}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
|
@ -134,12 +212,13 @@ export default function ExecutorForm() {
|
|||
);
|
||||
setSelectExecutorTypeOpen(false);
|
||||
}}
|
||||
selections={value}
|
||||
selections={editMode ? executorName : value}
|
||||
variant={SelectVariant.single}
|
||||
data-testid="executorType-select"
|
||||
aria-label={t("executorType")}
|
||||
isOpen={selectExecutorTypeOpen}
|
||||
maxHeight={580}
|
||||
isDisabled={editMode}
|
||||
>
|
||||
{executorTypes?.map((option) => (
|
||||
<SelectOption
|
||||
|
@ -155,26 +234,49 @@ export default function ExecutorForm() {
|
|||
</FormGroup>
|
||||
<FormProvider {...form}>
|
||||
<DynamicComponents properties={executorProperties} />
|
||||
{editMode && (
|
||||
<DynamicComponents properties={editedProfileExecutors!} />
|
||||
)}
|
||||
</FormProvider>
|
||||
<ActionGroup>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={save}
|
||||
data-testid="addExecutor-saveBtn"
|
||||
>
|
||||
{t("common:add")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
component={(props) => (
|
||||
<Link {...props} to={toClientProfile({ realm, profileName })} />
|
||||
)}
|
||||
data-testid="addExecutor-cancelBtn"
|
||||
>
|
||||
{t("common:cancel")}
|
||||
</Button>
|
||||
</ActionGroup>
|
||||
{!globalProfile && (
|
||||
<ActionGroup>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => handleSubmit(save)()}
|
||||
data-testid="addExecutor-saveBtn"
|
||||
>
|
||||
{editMode ? t("common:save") : t("common:add")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
component={(props) => (
|
||||
<Link
|
||||
{...props}
|
||||
to={toClientProfile({ realm, profileName })}
|
||||
/>
|
||||
)}
|
||||
data-testid="addExecutor-cancelBtn"
|
||||
>
|
||||
{t("common:cancel")}
|
||||
</Button>
|
||||
</ActionGroup>
|
||||
)}
|
||||
</FormAccess>
|
||||
{editMode && globalProfile && (
|
||||
<div className="kc-backToProfile">
|
||||
<Button
|
||||
component={(props) => (
|
||||
<Link
|
||||
{...props}
|
||||
to={toClientProfile({ realm, profileName })}
|
||||
></Link>
|
||||
)}
|
||||
variant="primary"
|
||||
>
|
||||
{t("realm-settings:back")}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</PageSection>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -214,10 +214,19 @@ article.pf-c-card.pf-m-flat.kc-login-settings-template
|
|||
margin-right: 0.625rem;
|
||||
}
|
||||
|
||||
.kc-backToPolicies {
|
||||
.kc-unclickable-executor {
|
||||
font-size: var(--pf-global--FontSize--md);
|
||||
padding: 0 var(--pf-global--spacer--md) 0 var(--pf-global--spacer--md);
|
||||
}
|
||||
|
||||
.kc-backToPolicies, .kc-backToPolicies {
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
.kc-backToPolicies {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.kc-executor-trash-icon {
|
||||
margin-left: .5rem;
|
||||
color: var(--pf-global--Color--200);
|
||||
|
@ -238,8 +247,4 @@ article.pf-c-card.pf-m-flat.kc-login-settings-template
|
|||
|
||||
.kc-conditionType-trash-icon:hover {
|
||||
filter: brightness(55%);
|
||||
}
|
||||
|
||||
.kc-backToPolicies {
|
||||
width: 5rem;
|
||||
}
|
||||
}
|
|
@ -56,6 +56,42 @@ export const EditPolicyCrumb = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export const EditProfileCrumb = () => {
|
||||
const { t } = useTranslation("realm-settings");
|
||||
const { realm } = useRealm();
|
||||
|
||||
return (
|
||||
<Breadcrumb>
|
||||
<BreadcrumbItem
|
||||
render={(props) => (
|
||||
<Link {...props} to={toClientPolicies({ realm })}>
|
||||
{t("clientPolicies")}
|
||||
</Link>
|
||||
)}
|
||||
/>
|
||||
<BreadcrumbItem isActive>{t("clientProfile")}</BreadcrumbItem>
|
||||
</Breadcrumb>
|
||||
);
|
||||
};
|
||||
|
||||
export const EditExecutorCrumb = () => {
|
||||
const { t } = useTranslation("realm-settings");
|
||||
const { realm } = useRealm();
|
||||
|
||||
return (
|
||||
<Breadcrumb>
|
||||
<BreadcrumbItem
|
||||
render={(props) => (
|
||||
<Link {...props} to={toClientPolicies({ realm })}>
|
||||
{t("clientPolicies")}
|
||||
</Link>
|
||||
)}
|
||||
/>
|
||||
<BreadcrumbItem isActive>{t("executorDetails")}</BreadcrumbItem>
|
||||
</Breadcrumb>
|
||||
);
|
||||
};
|
||||
|
||||
export const NewPolicyCrumb = () => {
|
||||
const { t } = useTranslation("realm-settings");
|
||||
const { realm } = useRealm();
|
||||
|
|
|
@ -267,6 +267,7 @@ export default {
|
|||
newClientProfile: "Create client profile",
|
||||
newClientProfileName: "Client profile name",
|
||||
clientProfile: "Client profile details",
|
||||
executorDetails: "Executor details",
|
||||
back: "Back",
|
||||
delete: "delete",
|
||||
save: "Save",
|
||||
|
@ -291,6 +292,8 @@ export default {
|
|||
emptyExecutors: "No executors configured",
|
||||
addExecutorSuccess: "Success! Executor created successfully",
|
||||
addExecutorError: "Executor not created",
|
||||
updateExecutorSuccess: "Executor updated successfully",
|
||||
updateExecutorError: "Executor not updated",
|
||||
deleteExecutorProfileConfirmTitle: "Delete executor?",
|
||||
deleteExecutorProfileConfirm:
|
||||
"The action will permanently delete {{executorName}}. This cannot be undone.",
|
||||
|
|
|
@ -10,6 +10,7 @@ import { ClientPoliciesRoute } from "./routes/ClientPolicies";
|
|||
import { AddClientProfileRoute } from "./routes/AddClientProfile";
|
||||
import { ClientProfileRoute } from "./routes/ClientProfile";
|
||||
import { AddExecutorRoute } from "./routes/AddExecutor";
|
||||
import { ExecutorRoute } from "./routes/Executor";
|
||||
import { AddClientPolicyRoute } from "./routes/AddClientPolicy";
|
||||
import { EditClientPolicyRoute } from "./routes/EditClientPolicy";
|
||||
import { NewClientPolicyConditionRoute } from "./routes/AddCondition";
|
||||
|
@ -27,6 +28,7 @@ const routes: RouteDef[] = [
|
|||
AddClientProfileRoute,
|
||||
AddExecutorRoute,
|
||||
ClientProfileRoute,
|
||||
ExecutorRoute,
|
||||
AddClientPolicyRoute,
|
||||
EditClientPolicyRoute,
|
||||
NewClientPolicyConditionRoute,
|
||||
|
|
|
@ -2,6 +2,7 @@ import type { LocationDescriptorObject } from "history";
|
|||
import { lazy } from "react";
|
||||
import { generatePath } from "react-router-dom";
|
||||
import type { RouteDef } from "../../route-config";
|
||||
import { EditProfileCrumb } from "../RealmSettingsSection";
|
||||
|
||||
export type ClientProfileParams = {
|
||||
realm: string;
|
||||
|
@ -9,9 +10,9 @@ export type ClientProfileParams = {
|
|||
};
|
||||
|
||||
export const ClientProfileRoute: RouteDef = {
|
||||
path: "/:realm/realm-settings/clientPolicies/:profileName/edit-profile",
|
||||
path: "/:realm/realm-settings/clientPolicies/:profileName",
|
||||
component: lazy(() => import("../ClientProfileForm")),
|
||||
breadcrumb: (t) => t("realm-settings:clientProfile"),
|
||||
breadcrumb: () => EditProfileCrumb,
|
||||
access: ["view-realm", "view-users"],
|
||||
};
|
||||
|
||||
|
|
24
src/realm-settings/routes/Executor.ts
Normal file
24
src/realm-settings/routes/Executor.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import type { LocationDescriptorObject } from "history";
|
||||
import { lazy } from "react";
|
||||
import { generatePath } from "react-router-dom";
|
||||
import type { RouteDef } from "../../route-config";
|
||||
import { EditExecutorCrumb } from "../RealmSettingsSection";
|
||||
|
||||
export type ExecutorParams = {
|
||||
realm: string;
|
||||
profileName: string;
|
||||
executorName: string;
|
||||
};
|
||||
|
||||
export const ExecutorRoute: RouteDef = {
|
||||
path: "/:realm/realm-settings/clientPolicies/:profileName/:executorName",
|
||||
component: lazy(() => import("../ExecutorForm")),
|
||||
breadcrumb: () => EditExecutorCrumb,
|
||||
access: ["manage-realm"],
|
||||
};
|
||||
|
||||
export const toExecutor = (
|
||||
params: ExecutorParams
|
||||
): LocationDescriptorObject => ({
|
||||
pathname: generatePath(ExecutorRoute.path, params),
|
||||
});
|
Loading…
Reference in a new issue