2022-12-07 09:03:51 +00:00
|
|
|
import type ScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/scopeRepresentation";
|
2022-01-04 09:17:43 +00:00
|
|
|
import {
|
|
|
|
ActionGroup,
|
|
|
|
AlertVariant,
|
|
|
|
Button,
|
|
|
|
ButtonVariant,
|
|
|
|
DropdownItem,
|
|
|
|
FormGroup,
|
|
|
|
PageSection,
|
|
|
|
ValidatedOptions,
|
|
|
|
} from "@patternfly/react-core";
|
2022-12-07 09:03:51 +00:00
|
|
|
import { useState } from "react";
|
2023-01-26 09:31:07 +00:00
|
|
|
import { useForm } from "react-hook-form";
|
2022-12-07 09:03:51 +00:00
|
|
|
import { useTranslation } from "react-i18next";
|
2023-01-18 12:09:49 +00:00
|
|
|
import { Link, useNavigate } from "react-router-dom";
|
2022-01-04 09:17:43 +00:00
|
|
|
|
2022-12-07 09:03:51 +00:00
|
|
|
import { useAlerts } from "../../components/alert/Alerts";
|
2022-01-04 09:17:43 +00:00
|
|
|
import { FormAccess } from "../../components/form-access/FormAccess";
|
|
|
|
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
2022-12-07 09:03:51 +00:00
|
|
|
import { KeycloakTextInput } from "../../components/keycloak-text-input/KeycloakTextInput";
|
2022-01-04 09:17:43 +00:00
|
|
|
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
|
|
|
import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
2022-12-07 14:23:12 +00:00
|
|
|
import { useParams } from "../../utils/useParams";
|
2022-01-04 09:17:43 +00:00
|
|
|
import useToggle from "../../utils/useToggle";
|
2022-12-07 09:03:51 +00:00
|
|
|
import { toAuthorizationTab } from "../routes/AuthenticationTab";
|
|
|
|
import type { ScopeDetailsParams } from "../routes/Scope";
|
2022-01-04 09:17:43 +00:00
|
|
|
import { DeleteScopeDialog } from "./DeleteScopeDialog";
|
|
|
|
|
2022-12-07 09:03:51 +00:00
|
|
|
type FormFields = Omit<ScopeRepresentation, "resources">;
|
|
|
|
|
2022-01-04 09:17:43 +00:00
|
|
|
export default function ScopeDetails() {
|
|
|
|
const { t } = useTranslation("clients");
|
|
|
|
const { id, scopeId, realm } = useParams<ScopeDetailsParams>();
|
2022-08-16 13:09:14 +00:00
|
|
|
const navigate = useNavigate();
|
2022-01-04 09:17:43 +00:00
|
|
|
|
2022-07-14 13:02:28 +00:00
|
|
|
const { adminClient } = useAdminClient();
|
2022-01-04 09:17:43 +00:00
|
|
|
const { addAlert, addError } = useAlerts();
|
|
|
|
|
|
|
|
const [deleteDialog, toggleDeleteDialog] = useToggle();
|
|
|
|
const [scope, setScope] = useState<ScopeRepresentation>();
|
2022-04-08 12:37:31 +00:00
|
|
|
const {
|
|
|
|
register,
|
|
|
|
reset,
|
|
|
|
handleSubmit,
|
|
|
|
formState: { errors },
|
2022-12-07 09:03:51 +00:00
|
|
|
} = useForm<FormFields>({
|
2022-04-08 12:37:31 +00:00
|
|
|
mode: "onChange",
|
|
|
|
});
|
2022-01-04 09:17:43 +00:00
|
|
|
|
|
|
|
useFetch(
|
|
|
|
async () => {
|
|
|
|
if (scopeId) {
|
|
|
|
const scope = await adminClient.clients.getAuthorizationScope({
|
|
|
|
id,
|
|
|
|
scopeId,
|
|
|
|
});
|
|
|
|
if (!scope) {
|
|
|
|
throw new Error(t("common:notFound"));
|
|
|
|
}
|
|
|
|
return scope;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
(scope) => {
|
|
|
|
setScope(scope);
|
|
|
|
reset({ ...scope });
|
|
|
|
},
|
|
|
|
[]
|
|
|
|
);
|
|
|
|
|
2022-12-07 09:03:51 +00:00
|
|
|
const onSubmit = async (scope: ScopeRepresentation) => {
|
2022-01-04 09:17:43 +00:00
|
|
|
try {
|
|
|
|
if (scopeId) {
|
|
|
|
await adminClient.clients.updateAuthorizationScope(
|
|
|
|
{ id, scopeId },
|
|
|
|
scope
|
|
|
|
);
|
|
|
|
setScope(scope);
|
|
|
|
} else {
|
|
|
|
await adminClient.clients.createAuthorizationScope(
|
|
|
|
{ id },
|
|
|
|
{
|
|
|
|
name: scope.name!,
|
|
|
|
displayName: scope.displayName,
|
|
|
|
iconUri: scope.iconUri,
|
|
|
|
}
|
|
|
|
);
|
2022-08-16 13:09:14 +00:00
|
|
|
navigate(toAuthorizationTab({ realm, clientId: id, tab: "scopes" }));
|
2022-01-04 09:17:43 +00:00
|
|
|
}
|
|
|
|
addAlert(
|
|
|
|
t((scopeId ? "update" : "create") + "ScopeSuccess"),
|
|
|
|
AlertVariant.success
|
|
|
|
);
|
|
|
|
} catch (error) {
|
|
|
|
addError("clients:scopeSaveError", error);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<DeleteScopeDialog
|
|
|
|
clientId={id}
|
|
|
|
open={deleteDialog}
|
|
|
|
toggleDialog={toggleDeleteDialog}
|
|
|
|
selectedScope={scope}
|
|
|
|
refresh={() =>
|
2022-08-16 13:09:14 +00:00
|
|
|
navigate(toAuthorizationTab({ realm, clientId: id, tab: "scopes" }))
|
2022-01-04 09:17:43 +00:00
|
|
|
}
|
|
|
|
/>
|
|
|
|
<ViewHeader
|
2022-03-21 08:52:07 +00:00
|
|
|
titleKey={
|
|
|
|
scopeId ? scope?.name! : t("clients:createAuthorizationScope")
|
|
|
|
}
|
2022-01-04 09:17:43 +00:00
|
|
|
dropdownItems={
|
|
|
|
scopeId
|
|
|
|
? [
|
|
|
|
<DropdownItem
|
|
|
|
key="delete"
|
|
|
|
data-testid="delete-resource"
|
|
|
|
onClick={() => toggleDeleteDialog()}
|
|
|
|
>
|
|
|
|
{t("common:delete")}
|
|
|
|
</DropdownItem>,
|
|
|
|
]
|
|
|
|
: undefined
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
<PageSection variant="light">
|
|
|
|
<FormAccess
|
|
|
|
isHorizontal
|
2022-05-30 09:23:24 +00:00
|
|
|
role="view-clients"
|
2022-12-07 09:03:51 +00:00
|
|
|
onSubmit={handleSubmit(onSubmit)}
|
2022-01-04 09:17:43 +00:00
|
|
|
>
|
|
|
|
<FormGroup
|
|
|
|
label={t("common:name")}
|
|
|
|
fieldId="name"
|
|
|
|
labelIcon={
|
|
|
|
<HelpItem helpText="clients-help:scopeName" fieldLabelId="name" />
|
|
|
|
}
|
|
|
|
helperTextInvalid={t("common:required")}
|
|
|
|
validated={
|
|
|
|
errors.name ? ValidatedOptions.error : ValidatedOptions.default
|
|
|
|
}
|
|
|
|
isRequired
|
|
|
|
>
|
2022-04-21 15:03:26 +00:00
|
|
|
<KeycloakTextInput
|
2022-01-04 09:17:43 +00:00
|
|
|
id="name"
|
|
|
|
validated={
|
|
|
|
errors.name ? ValidatedOptions.error : ValidatedOptions.default
|
|
|
|
}
|
2022-12-07 09:03:51 +00:00
|
|
|
isRequired
|
|
|
|
{...register("name", { required: true })}
|
2022-01-04 09:17:43 +00:00
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
<FormGroup
|
|
|
|
label={t("displayName")}
|
|
|
|
fieldId="displayName"
|
|
|
|
labelIcon={
|
|
|
|
<HelpItem
|
|
|
|
helpText="clients-help:scopeDisplayName"
|
|
|
|
fieldLabelId="displayName"
|
|
|
|
/>
|
|
|
|
}
|
|
|
|
>
|
2022-12-07 09:03:51 +00:00
|
|
|
<KeycloakTextInput id="displayName" {...register("displayName")} />
|
2022-01-04 09:17:43 +00:00
|
|
|
</FormGroup>
|
|
|
|
<FormGroup
|
|
|
|
label={t("iconUri")}
|
|
|
|
fieldId="iconUri"
|
|
|
|
labelIcon={
|
|
|
|
<HelpItem
|
|
|
|
helpText="clients-help:iconUri"
|
|
|
|
fieldLabelId="clients:iconUri"
|
|
|
|
/>
|
|
|
|
}
|
|
|
|
>
|
2022-12-07 09:03:51 +00:00
|
|
|
<KeycloakTextInput id="iconUri" {...register("iconUri")} />
|
2022-01-04 09:17:43 +00:00
|
|
|
</FormGroup>
|
|
|
|
<ActionGroup>
|
|
|
|
<div className="pf-u-mt-md">
|
|
|
|
<Button
|
|
|
|
variant={ButtonVariant.primary}
|
|
|
|
type="submit"
|
|
|
|
data-testid="save"
|
|
|
|
>
|
|
|
|
{t("common:save")}
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
{!scope ? (
|
|
|
|
<Button
|
|
|
|
variant="link"
|
|
|
|
data-testid="cancel"
|
|
|
|
component={(props) => (
|
|
|
|
<Link
|
|
|
|
{...props}
|
2022-01-31 07:20:35 +00:00
|
|
|
to={toAuthorizationTab({
|
2022-01-04 09:17:43 +00:00
|
|
|
realm,
|
|
|
|
clientId: id,
|
2022-01-31 07:20:35 +00:00
|
|
|
tab: "scopes",
|
2022-01-04 09:17:43 +00:00
|
|
|
})}
|
|
|
|
></Link>
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
{t("common:cancel")}
|
|
|
|
</Button>
|
|
|
|
) : (
|
|
|
|
<Button
|
|
|
|
variant="link"
|
|
|
|
data-testid="revert"
|
|
|
|
onClick={() => reset({ ...scope })}
|
|
|
|
>
|
|
|
|
{t("common:revert")}
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</ActionGroup>
|
|
|
|
</FormAccess>
|
|
|
|
</PageSection>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
}
|