diff --git a/src/client-scopes/ClientScopesSection.tsx b/src/client-scopes/ClientScopesSection.tsx
index dcc4f217e0..60f1414bcf 100644
--- a/src/client-scopes/ClientScopesSection.tsx
+++ b/src/client-scopes/ClientScopesSection.tsx
@@ -21,7 +21,7 @@ export const ClientScopesSection = () => {
const ClientScopeDetailLink = (clientScope: ClientScopeRepresentation) => (
<>
-
+
{clientScope.name}
>
diff --git a/src/client-scopes/add/RoleMappingForm.tsx b/src/client-scopes/add/RoleMappingForm.tsx
index 37ba06eb93..c9fc142f74 100644
--- a/src/client-scopes/add/RoleMappingForm.tsx
+++ b/src/client-scopes/add/RoleMappingForm.tsx
@@ -42,7 +42,7 @@ export const RoleMappingForm = () => {
const { t } = useTranslation("client-scopes");
const { register, handleSubmit, control, errors } = useForm();
- const { clientScopeId } = useParams<{ clientScopeId: string }>();
+ const { id } = useParams<{ id: string }>();
const [roleOpen, setRoleOpen] = useState(false);
@@ -101,10 +101,7 @@ export const RoleMappingForm = () => {
const save = async (mapping: ProtocolMapperRepresentation) => {
try {
- await adminClient.clientScopes.addProtocolMapper(
- { id: clientScopeId },
- mapping
- );
+ await adminClient.clientScopes.addProtocolMapper({ id }, mapping);
addAlert(t("mapperCreateSuccess"));
} catch (error) {
addAlert(t("mapperCreateError", error));
@@ -227,7 +224,7 @@ export const RoleMappingForm = () => {
placeholderText={t("selectASourceOfRoles")}
isGrouped
onFilter={(evt) => {
- const textInput = evt.target.value;
+ const textInput = evt?.target.value || "";
if (textInput === "") {
return createSelectGroup(clients);
} else {
diff --git a/src/client-scopes/details/MapperList.tsx b/src/client-scopes/details/MapperList.tsx
index 7894258f1e..25ebb67eb1 100644
--- a/src/client-scopes/details/MapperList.tsx
+++ b/src/client-scopes/details/MapperList.tsx
@@ -59,7 +59,7 @@ export const MapperList = ({ clientScope, refresh }: MapperListProps) => {
const [filter, setFilter] = useState(clientScope.protocolMappers);
const toggleAddMapperDialog = (buildIn: boolean) => {
if (buildIn) {
- setFilter(mapperList);
+ setFilter(mapperList || []);
} else {
setFilter(undefined);
}
@@ -123,9 +123,7 @@ export const MapperList = ({ clientScope, refresh }: MapperListProps) => {
cells: {
name: (
<>
-
- {mapper.name}
-
+ {mapper.name}
>
),
category: mapperType.category,
diff --git a/src/client-scopes/details/MappingDetails.tsx b/src/client-scopes/details/MappingDetails.tsx
index 31bfa55723..0ea75a2bf4 100644
--- a/src/client-scopes/details/MappingDetails.tsx
+++ b/src/client-scopes/details/MappingDetails.tsx
@@ -37,8 +37,8 @@ import { convertFormValuesToObject, convertToFormValues } from "../../util";
import { FormAccess } from "../../components/form-access/FormAccess";
type Params = {
- scopeId: string;
id: string;
+ mapperId: string;
};
export const MappingDetails = () => {
@@ -47,7 +47,7 @@ export const MappingDetails = () => {
const handleError = useErrorHandler();
const { addAlert } = useAlerts();
- const { scopeId, id } = useParams();
+ const { id, mapperId } = useParams();
const { register, errors, setValue, control, handleSubmit } = useForm();
const [mapping, setMapping] = useState();
const [typeOpen, setTypeOpen] = useState(false);
@@ -63,10 +63,10 @@ export const MappingDetails = () => {
useEffect(() => {
return asyncStateFetch(
async () => {
- if (id.match(isGuid)) {
+ if (mapperId.match(isGuid)) {
const data = await adminClient.clientScopes.findProtocolMapper({
- id: scopeId,
- mapperId: id,
+ id,
+ mapperId,
});
if (data) {
Object.entries(data).map((entry) => {
@@ -83,9 +83,19 @@ export const MappingDetails = () => {
mapping: data,
};
} else {
- const scope = await adminClient.clientScopes.findOne({ id: scopeId });
+ const scope = await adminClient.clientScopes.findOne({ id });
+ const protocolMappers = serverInfo.protocolMapperTypes![
+ scope.protocol!
+ ];
+ const mapping = protocolMappers.find(
+ (mapper) => mapper.id === mapperId
+ )!;
return {
- mapping: { protocol: scope.protocol, protocolMapper: id },
+ mapping: {
+ name: mapping.name,
+ protocol: scope.protocol,
+ protocolMapper: mapperId,
+ },
};
}
},
@@ -105,11 +115,11 @@ export const MappingDetails = () => {
onConfirm: async () => {
try {
await adminClient.clientScopes.delClientScopeMappings(
- { client: scopeId, id },
+ { client: id, id: mapperId },
[]
);
addAlert(t("mappingDeletedSuccess"), AlertVariant.success);
- history.push(`${url}/${scopeId}`);
+ history.push(`${url}/${id}`);
} catch (error) {
addAlert(t("mappingDeletedError", { error }), AlertVariant.danger);
}
@@ -119,15 +129,15 @@ export const MappingDetails = () => {
const save = async (formMapping: ProtocolMapperRepresentation) => {
const config = convertFormValuesToObject(formMapping.config);
const map = { ...mapping, ...formMapping, config };
- const key = id.match(isGuid) ? "Updated" : "Created";
+ const key = mapperId.match(isGuid) ? "Updated" : "Created";
try {
- if (id.match(isGuid)) {
+ if (mapperId.match(isGuid)) {
await adminClient.clientScopes.updateProtocolMapper(
- { id: scopeId, mapperId: id },
+ { id, mapperId },
map
);
} else {
- await adminClient.clientScopes.addProtocolMapper({ id: scopeId }, map);
+ await adminClient.clientScopes.addProtocolMapper({ id }, map);
}
addAlert(t(`mapping${key}Success`), AlertVariant.success);
} catch (error) {
@@ -140,10 +150,10 @@ export const MappingDetails = () => {
{
role="manage-clients"
>
<>
- {!id.match(isGuid) && (
+ {!mapperId.match(isGuid) && (
{
const { addAlert } = useAlerts();
const [downloadDialogOpen, setDownloadDialogOpen] = useState(false);
const toggleDownloadDialog = () => setDownloadDialogOpen(!downloadDialogOpen);
+ const [activeTab2, setActiveTab2] = useState(30);
const form = useForm();
const publicClient = useWatch({
@@ -121,12 +123,12 @@ export const ClientDetails = () => {
defaultValue: false,
});
- const { id } = useParams<{ id: string }>();
+ const { clientId } = useParams<{ clientId: string }>();
const [client, setClient] = useState();
const loader = async () => {
- const roles = await adminClient.clients.listRoles({ id });
+ const roles = await adminClient.clients.listRoles({ id: clientId });
return _.sortBy(roles, (role) => role.name?.toUpperCase());
};
@@ -137,7 +139,7 @@ export const ClientDetails = () => {
continueButtonVariant: ButtonVariant.danger,
onConfirm: async () => {
try {
- await adminClient.clients.del({ id });
+ await adminClient.clients.del({ id: clientId });
addAlert(t("clientDeletedSuccess"), AlertVariant.success);
} catch (error) {
addAlert(`${t("clientDeleteError")} ${error}`, AlertVariant.danger);
@@ -162,14 +164,14 @@ export const ClientDetails = () => {
useEffect(() => {
return asyncStateFetch(
- () => adminClient.clients.findOne({ id }),
+ () => adminClient.clients.findOne({ id: clientId }),
(fetchedClient) => {
setClient(fetchedClient);
setupForm(fetchedClient);
},
handleError
);
- }, [id]);
+ }, [clientId]);
const save = async () => {
if (await form.trigger()) {
@@ -187,7 +189,7 @@ export const ClientDetails = () => {
webOrigins,
attributes,
};
- await adminClient.clients.update({ id }, newClient);
+ await adminClient.clients.update({ id: clientId }, newClient);
setupForm(newClient);
setClient(newClient);
addAlert(t("clientSaveSuccess"), AlertVariant.success);
@@ -244,7 +246,7 @@ export const ClientDetails = () => {
eventKey="credentials"
title={{t("credentials")}}
>
-
+
)}
{
eventKey="clientScopes"
title={{t("clientScopes")}}
>
-
+ setActiveTab2(key as number)}
+ >
{t("setup")}}
>
-
+
{t("evaluate")}}
>
-
+
-
+
{client!.serviceAccountsEnabled && (
{
eventKey="serviceAccount"
title={{t("serviceAccount")}}
>
-
+
)}
{
const ClientDetailLink = (client: ClientRepresentation) => (
<>
-
+
{client.clientId}
{!client.enabled && (
diff --git a/src/components/keycloak-tabs/KeycloakTabs.tsx b/src/components/keycloak-tabs/KeycloakTabs.tsx
index de6101b39f..c0a6fafcd9 100644
--- a/src/components/keycloak-tabs/KeycloakTabs.tsx
+++ b/src/components/keycloak-tabs/KeycloakTabs.tsx
@@ -15,8 +15,6 @@ const createUrl = (
const value = params[key];
if (url.indexOf(key) !== -1) {
url = url.replace(new RegExp(`:${key}\\??`), value || "");
- } else {
- url += `/${value}`;
}
}
return url;
@@ -37,13 +35,13 @@ export const KeycloakTabs = ({
(isValidElement(firstTab) && firstTab.props.eventKey) ||
"";
+ const pathIndex = match.path.indexOf(paramName) + paramName.length;
+ const path = match.path.substr(0, pathIndex);
return (
- history.push(
- createUrl(match.path, { ...params, [paramName]: key as string })
- )
+ history.push(createUrl(path, { ...params, [paramName]: key as string }))
}
{...rest}
>
diff --git a/src/realm-roles/RolesList.tsx b/src/realm-roles/RolesList.tsx
index 2b0d2be105..57a235a04f 100644
--- a/src/realm-roles/RolesList.tsx
+++ b/src/realm-roles/RolesList.tsx
@@ -22,6 +22,15 @@ type RolesListProps = {
) => Promise;
};
+const RoleLink = ({ role }: { role: RoleRepresentation }) => {
+ const { url } = useRouteMatch();
+ return (
+
+ {role.name}
+
+ );
+};
+
export const RolesList = ({
loader,
paginated = true,
@@ -37,9 +46,7 @@ export const RolesList = ({
const RoleDetailLink = (role: RoleRepresentation) => (
<>
-
- {role.name}
-
+
>
);
diff --git a/src/route-config.ts b/src/route-config.ts
index 9474c7cec2..729381050a 100644
--- a/src/route-config.ts
+++ b/src/route-config.ts
@@ -59,12 +59,6 @@ export const routes: RoutesFn = (t: TFunction) => [
breadcrumb: t("clients:importClient"),
access: "manage-clients",
},
- {
- path: "/:realm/clients/:id",
- component: ClientDetails,
- breadcrumb: t("clients:clientSettings"),
- access: "view-clients",
- },
{
path: "/:realm/clients/:clientId/roles/add-role",
component: RealmRoleTabs,
@@ -84,9 +78,9 @@ export const routes: RoutesFn = (t: TFunction) => [
access: "view-realm",
},
{
- path: "/:realm/clients/:id/:tab?/:subtab?",
+ path: "/:realm/clients/:clientId/:tab",
component: ClientDetails,
- breadcrumb: null,
+ breadcrumb: t("clients:clientSettings"),
access: "view-clients",
},
{
@@ -96,31 +90,19 @@ export const routes: RoutesFn = (t: TFunction) => [
access: "manage-clients",
},
{
- path: "/:realm/client-scopes/:id",
- component: ClientScopeForm,
- breadcrumb: t("client-scopes:clientScopeDetails"),
- access: "view-clients",
- },
- {
- path: "/:realm/client-scopes/:id/:tab",
- component: ClientScopeForm,
- breadcrumb: null,
- access: "view-clients",
- },
- {
- path: "/:realm/client-scopes/:scopeId/oidc-role-name-mapper",
+ path: "/:realm/client-scopes/:id/mappers/oidc-role-name-mapper",
component: RoleMappingForm,
breadcrumb: t("client-scopes:mappingDetails"),
access: "view-clients",
},
{
- path: "/:realm/client-scopes/:scopeId/:id",
+ path: "/:realm/client-scopes/:id/mappers/:mapperId",
component: MappingDetails,
breadcrumb: t("client-scopes:mappingDetails"),
access: "view-clients",
},
{
- path: "/:realm/client-scopes/:id",
+ path: "/:realm/client-scopes/:id/:tab",
component: ClientScopeForm,
breadcrumb: t("client-scopes:clientScopeDetails"),
access: "view-clients",