Use new routing conventions for client routes (#888)
This commit is contained in:
parent
242e6f7b98
commit
1860ea5b58
15 changed files with 243 additions and 149 deletions
|
@ -7,9 +7,9 @@ export default class ListingPage {
|
||||||
private searchBtn =
|
private searchBtn =
|
||||||
".pf-c-page__main .pf-c-toolbar__content-section button.pf-m-control:visible";
|
".pf-c-page__main .pf-c-toolbar__content-section button.pf-m-control:visible";
|
||||||
private createBtn =
|
private createBtn =
|
||||||
".pf-c-page__main .pf-c-toolbar__content-section button.pf-m-primary:visible";
|
".pf-c-page__main .pf-c-toolbar__content-section .pf-m-primary:visible";
|
||||||
private importBtn =
|
private importBtn =
|
||||||
".pf-c-page__main .pf-c-toolbar__content-section button.pf-m-link";
|
".pf-c-page__main .pf-c-toolbar__content-section .pf-m-link";
|
||||||
|
|
||||||
goToCreateItem() {
|
goToCreateItem() {
|
||||||
cy.get(this.createBtn).click();
|
cy.get(this.createBtn).click();
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
|
||||||
import { Controller, useFormContext } from "react-hook-form";
|
|
||||||
import moment from "moment";
|
|
||||||
import {
|
import {
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
|
@ -17,27 +12,32 @@ import {
|
||||||
TextInput,
|
TextInput,
|
||||||
ToolbarItem,
|
ToolbarItem,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
|
|
||||||
import type GlobalRequestResult from "keycloak-admin/lib/defs/globalRequestResult";
|
|
||||||
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
||||||
import { convertToFormValues, toUpperCase } from "../util";
|
import type GlobalRequestResult from "keycloak-admin/lib/defs/globalRequestResult";
|
||||||
import { FormAccess } from "../components/form-access/FormAccess";
|
import moment from "moment";
|
||||||
import { ScrollForm } from "../components/scroll-form/ScrollForm";
|
import React, { useEffect, useState } from "react";
|
||||||
import { HelpItem } from "../components/help-enabler/HelpItem";
|
import { Controller, useFormContext } from "react-hook-form";
|
||||||
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
import { FineGrainOpenIdConnect } from "./advanced/FineGrainOpenIdConnect";
|
import { Link } from "react-router-dom";
|
||||||
import { OpenIdConnectCompatibilityModes } from "./advanced/OpenIdConnectCompatibilityModes";
|
|
||||||
import { AdvancedSettings } from "./advanced/AdvancedSettings";
|
|
||||||
import { TimeSelector } from "../components/time-selector/TimeSelector";
|
|
||||||
import { useAdminClient } from "../context/auth/AdminClient";
|
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
import { AddHostDialog } from "./advanced/AddHostDialog";
|
import { FormAccess } from "../components/form-access/FormAccess";
|
||||||
import { FineGrainSamlEndpointConfig } from "./advanced/FineGrainSamlEndpointConfig";
|
import { HelpItem } from "../components/help-enabler/HelpItem";
|
||||||
import { AuthenticationOverrides } from "./advanced/AuthenticationOverrides";
|
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
|
||||||
import type { SaveOptions } from "./ClientDetails";
|
|
||||||
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||||
|
import { ScrollForm } from "../components/scroll-form/ScrollForm";
|
||||||
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||||
|
import { TimeSelector } from "../components/time-selector/TimeSelector";
|
||||||
|
import { useAdminClient } from "../context/auth/AdminClient";
|
||||||
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
|
import { convertToFormValues, toUpperCase } from "../util";
|
||||||
|
import { AddHostDialog } from "./advanced/AddHostDialog";
|
||||||
|
import { AdvancedSettings } from "./advanced/AdvancedSettings";
|
||||||
|
import { AuthenticationOverrides } from "./advanced/AuthenticationOverrides";
|
||||||
|
import { FineGrainOpenIdConnect } from "./advanced/FineGrainOpenIdConnect";
|
||||||
|
import { FineGrainSamlEndpointConfig } from "./advanced/FineGrainSamlEndpointConfig";
|
||||||
|
import { OpenIdConnectCompatibilityModes } from "./advanced/OpenIdConnectCompatibilityModes";
|
||||||
|
import type { SaveOptions } from "./ClientDetails";
|
||||||
|
import { toClient } from "./routes/Client";
|
||||||
|
|
||||||
type AdvancedProps = {
|
type AdvancedProps = {
|
||||||
save: (options?: SaveOptions) => void;
|
save: (options?: SaveOptions) => void;
|
||||||
|
@ -184,7 +184,7 @@ export const AdvancedTab = ({
|
||||||
<Text className="pf-u-pb-lg">
|
<Text className="pf-u-pb-lg">
|
||||||
<Trans i18nKey="clients-help:notBeforeIntro">
|
<Trans i18nKey="clients-help:notBeforeIntro">
|
||||||
In order to successfully push setup url on
|
In order to successfully push setup url on
|
||||||
<Link to={`/${realm}/clients/${id}/settings`}>
|
<Link to={toClient({ realm, clientId: id!, tab: "settings" })}>
|
||||||
{t("settings")}
|
{t("settings")}
|
||||||
</Link>
|
</Link>
|
||||||
tab
|
tab
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React, { useState } from "react";
|
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
|
@ -11,40 +10,42 @@ import {
|
||||||
Tabs,
|
Tabs,
|
||||||
TabTitleText,
|
TabTitleText,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { useHistory, useParams } from "react-router-dom";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
|
||||||
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import React, { useState } from "react";
|
||||||
import { ClientSettings } from "./ClientSettings";
|
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useHistory, useParams } from "react-router-dom";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
import {
|
import {
|
||||||
ConfirmDialogModal,
|
ConfirmDialogModal,
|
||||||
useConfirmDialog,
|
useConfirmDialog,
|
||||||
} from "../components/confirm-dialog/ConfirmDialog";
|
} from "../components/confirm-dialog/ConfirmDialog";
|
||||||
import { DownloadDialog } from "../components/download-dialog/DownloadDialog";
|
import { DownloadDialog } from "../components/download-dialog/DownloadDialog";
|
||||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
|
||||||
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
|
|
||||||
import { Credentials } from "./credentials/Credentials";
|
|
||||||
import {
|
|
||||||
convertFormValuesToObject,
|
|
||||||
convertToFormValues,
|
|
||||||
exportClient,
|
|
||||||
} from "../util";
|
|
||||||
import {
|
import {
|
||||||
convertToMultiline,
|
convertToMultiline,
|
||||||
MultiLine,
|
MultiLine,
|
||||||
toValue,
|
toValue,
|
||||||
} from "../components/multi-line-input/MultiLineInput";
|
} from "../components/multi-line-input/MultiLineInput";
|
||||||
|
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||||
|
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
|
||||||
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
|
import { RolesList } from "../realm-roles/RolesList";
|
||||||
|
import {
|
||||||
|
convertFormValuesToObject,
|
||||||
|
convertToFormValues,
|
||||||
|
exportClient,
|
||||||
|
} from "../util";
|
||||||
|
import { AdvancedTab } from "./AdvancedTab";
|
||||||
|
import { ClientSettings } from "./ClientSettings";
|
||||||
|
import { Credentials } from "./credentials/Credentials";
|
||||||
|
import { Keys } from "./keys/Keys";
|
||||||
|
import type { ClientParams } from "./routes/Client";
|
||||||
|
import { toClients } from "./routes/Clients";
|
||||||
import { ClientScopes } from "./scopes/ClientScopes";
|
import { ClientScopes } from "./scopes/ClientScopes";
|
||||||
import { EvaluateScopes } from "./scopes/EvaluateScopes";
|
import { EvaluateScopes } from "./scopes/EvaluateScopes";
|
||||||
import { RolesList } from "../realm-roles/RolesList";
|
|
||||||
import { ServiceAccount } from "./service-account/ServiceAccount";
|
import { ServiceAccount } from "./service-account/ServiceAccount";
|
||||||
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
|
|
||||||
import { AdvancedTab } from "./AdvancedTab";
|
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
|
||||||
import { Keys } from "./keys/Keys";
|
|
||||||
|
|
||||||
type ClientDetailHeaderProps = {
|
type ClientDetailHeaderProps = {
|
||||||
onChange: (value: boolean) => void;
|
onChange: (value: boolean) => void;
|
||||||
|
@ -137,7 +138,7 @@ export const ClientDetails = () => {
|
||||||
const [activeTab2, setActiveTab2] = useState(30);
|
const [activeTab2, setActiveTab2] = useState(30);
|
||||||
|
|
||||||
const form = useForm<ClientForm>();
|
const form = useForm<ClientForm>();
|
||||||
const { clientId } = useParams<{ clientId: string }>();
|
const { clientId } = useParams<ClientParams>();
|
||||||
|
|
||||||
const clientAuthenticatorType = useWatch({
|
const clientAuthenticatorType = useWatch({
|
||||||
control: form.control,
|
control: form.control,
|
||||||
|
@ -161,7 +162,7 @@ export const ClientDetails = () => {
|
||||||
try {
|
try {
|
||||||
await adminClient.clients.del({ id: clientId });
|
await adminClient.clients.del({ id: clientId });
|
||||||
addAlert(t("clientDeletedSuccess"), AlertVariant.success);
|
addAlert(t("clientDeletedSuccess"), AlertVariant.success);
|
||||||
history.push(`/${realm}/clients`);
|
history.push(toClients({ realm }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addAlert(`${t("clientDeleteError")} ${error}`, AlertVariant.danger);
|
addAlert(`${t("clientDeleteError")} ${error}`, AlertVariant.danger);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,35 @@
|
||||||
import React, { useState } from "react";
|
|
||||||
import { Link, useHistory } from "react-router-dom";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
import {
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
Badge,
|
Badge,
|
||||||
Button,
|
Button,
|
||||||
ButtonVariant,
|
ButtonVariant,
|
||||||
PageSection,
|
PageSection,
|
||||||
ToolbarItem,
|
|
||||||
Tab,
|
Tab,
|
||||||
TabTitleText,
|
TabTitleText,
|
||||||
|
ToolbarItem,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
|
import { cellWidth, TableText } from "@patternfly/react-table";
|
||||||
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
||||||
import { emptyFormatter, exportClient, getBaseUrl } from "../util";
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
import { formattedLinkTableCell } from "../components/external-link/FormattedLink";
|
import { formattedLinkTableCell } from "../components/external-link/FormattedLink";
|
||||||
|
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
|
||||||
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||||
import { useAdminClient } from "../context/auth/AdminClient";
|
import { useAdminClient } from "../context/auth/AdminClient";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
import { emptyFormatter, exportClient, getBaseUrl } from "../util";
|
||||||
import { useAlerts } from "../components/alert/Alerts";
|
|
||||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
|
||||||
import { KeycloakTabs } from "../components/keycloak-tabs/KeycloakTabs";
|
|
||||||
import { InitialAccessTokenList } from "./initial-access/InitialAccessTokenList";
|
import { InitialAccessTokenList } from "./initial-access/InitialAccessTokenList";
|
||||||
import { cellWidth, TableText } from "@patternfly/react-table";
|
import { toAddClient } from "./routes/AddClient";
|
||||||
|
import { toClient } from "./routes/Client";
|
||||||
|
import { toImportClient } from "./routes/ImportClient";
|
||||||
|
|
||||||
export const ClientsSection = () => {
|
export const ClientsSection = () => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
const { addAlert } = useAlerts();
|
const { addAlert } = useAlerts();
|
||||||
const history = useHistory();
|
|
||||||
|
|
||||||
const adminClient = useAdminClient();
|
const adminClient = useAdminClient();
|
||||||
const { realm } = useRealm();
|
const { realm } = useRealm();
|
||||||
|
@ -70,7 +71,10 @@ export const ClientsSection = () => {
|
||||||
|
|
||||||
const ClientDetailLink = (client: ClientRepresentation) => (
|
const ClientDetailLink = (client: ClientRepresentation) => (
|
||||||
<>
|
<>
|
||||||
<Link key={client.id} to={`/${realm}/clients/${client.id}/settings`}>
|
<Link
|
||||||
|
key={client.id}
|
||||||
|
to={toClient({ realm, clientId: client.id!, tab: "settings" })}
|
||||||
|
>
|
||||||
{client.clientId}
|
{client.clientId}
|
||||||
{!client.enabled && (
|
{!client.enabled && (
|
||||||
<Badge key={`${client.id}-disabled`} isRead className="pf-u-ml-sm">
|
<Badge key={`${client.id}-disabled`} isRead className="pf-u-ml-sm">
|
||||||
|
@ -114,19 +118,16 @@ export const ClientsSection = () => {
|
||||||
toolbarItem={
|
toolbarItem={
|
||||||
<>
|
<>
|
||||||
<ToolbarItem>
|
<ToolbarItem>
|
||||||
<Button
|
{/* @ts-ignore */}
|
||||||
onClick={() =>
|
<Button component={Link} to={toAddClient({ realm })}>
|
||||||
history.push(`/${realm}/clients/add-client`)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{t("createClient")}
|
{t("createClient")}
|
||||||
</Button>
|
</Button>
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem>
|
<ToolbarItem>
|
||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
component={Link}
|
||||||
history.push(`/${realm}/clients/import-client`)
|
// @ts-ignore
|
||||||
}
|
to={toImportClient({ realm })}
|
||||||
variant="link"
|
variant="link"
|
||||||
>
|
>
|
||||||
{t("importClient")}
|
{t("importClient")}
|
||||||
|
|
|
@ -1,23 +1,24 @@
|
||||||
import React, { useState } from "react";
|
|
||||||
import { useHistory } from "react-router-dom";
|
|
||||||
import {
|
import {
|
||||||
|
AlertVariant,
|
||||||
|
Button,
|
||||||
PageSection,
|
PageSection,
|
||||||
Wizard,
|
Wizard,
|
||||||
AlertVariant,
|
|
||||||
WizardFooter,
|
|
||||||
WizardContextConsumer,
|
WizardContextConsumer,
|
||||||
Button,
|
WizardFooter,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { useTranslation } from "react-i18next";
|
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
||||||
|
import React, { useState } from "react";
|
||||||
import { FormProvider, useForm } from "react-hook-form";
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import { GeneralSettings } from "./GeneralSettings";
|
import { useHistory } from "react-router-dom";
|
||||||
import { CapabilityConfig } from "./CapabilityConfig";
|
|
||||||
import { useAlerts } from "../../components/alert/Alerts";
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||||
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
|
||||||
import { useAdminClient } from "../../context/auth/AdminClient";
|
import { useAdminClient } from "../../context/auth/AdminClient";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
|
import { toClient } from "../routes/Client";
|
||||||
|
import { toClients } from "../routes/Clients";
|
||||||
|
import { CapabilityConfig } from "./CapabilityConfig";
|
||||||
|
import { GeneralSettings } from "./GeneralSettings";
|
||||||
|
|
||||||
export const NewClientForm = () => {
|
export const NewClientForm = () => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
|
@ -45,7 +46,9 @@ export const NewClientForm = () => {
|
||||||
try {
|
try {
|
||||||
const newClient = await adminClient.clients.create({ ...client });
|
const newClient = await adminClient.clients.create({ ...client });
|
||||||
addAlert(t("createSuccess"), AlertVariant.success);
|
addAlert(t("createSuccess"), AlertVariant.success);
|
||||||
history.push(`/${realm}/clients/${newClient.id}/settings`);
|
history.push(
|
||||||
|
toClient({ realm, clientId: newClient.id, tab: "settings" })
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addAlert(t("createError", { error }), AlertVariant.danger);
|
addAlert(t("createError", { error }), AlertVariant.danger);
|
||||||
}
|
}
|
||||||
|
@ -119,7 +122,7 @@ export const NewClientForm = () => {
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
<FormProvider {...methods}>
|
<FormProvider {...methods}>
|
||||||
<Wizard
|
<Wizard
|
||||||
onClose={() => history.push(`/${realm}/clients`)}
|
onClose={() => history.push(toClients({ realm }))}
|
||||||
navAriaLabel={`${title} steps`}
|
navAriaLabel={`${title} steps`}
|
||||||
mainAriaLabel={`${title} content`}
|
mainAriaLabel={`${title} content`}
|
||||||
steps={[
|
steps={[
|
||||||
|
|
|
@ -1,26 +1,27 @@
|
||||||
import React from "react";
|
|
||||||
import { useHistory } from "react-router-dom";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import {
|
import {
|
||||||
PageSection,
|
|
||||||
FormGroup,
|
|
||||||
TextInput,
|
|
||||||
ActionGroup,
|
ActionGroup,
|
||||||
Button,
|
|
||||||
AlertVariant,
|
AlertVariant,
|
||||||
|
Button,
|
||||||
|
FormGroup,
|
||||||
|
PageSection,
|
||||||
|
TextInput,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import { FormProvider, useForm } from "react-hook-form";
|
|
||||||
|
|
||||||
import { ClientDescription } from "../ClientDescription";
|
|
||||||
import { JsonFileUpload } from "../../components/json-file-upload/JsonFileUpload";
|
|
||||||
import { useAlerts } from "../../components/alert/Alerts";
|
|
||||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
|
||||||
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
import type ClientRepresentation from "keycloak-admin/lib/defs/clientRepresentation";
|
||||||
import { useAdminClient } from "../../context/auth/AdminClient";
|
import React from "react";
|
||||||
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Link, useHistory } from "react-router-dom";
|
||||||
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
import { FormAccess } from "../../components/form-access/FormAccess";
|
import { FormAccess } from "../../components/form-access/FormAccess";
|
||||||
|
import { JsonFileUpload } from "../../components/json-file-upload/JsonFileUpload";
|
||||||
|
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||||
|
import { useAdminClient } from "../../context/auth/AdminClient";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
import { convertFormValuesToObject, convertToFormValues } from "../../util";
|
||||||
import { CapabilityConfig } from "../add/CapabilityConfig";
|
import { CapabilityConfig } from "../add/CapabilityConfig";
|
||||||
|
import { ClientDescription } from "../ClientDescription";
|
||||||
|
import { toClient } from "../routes/Client";
|
||||||
|
import { toClients } from "../routes/Clients";
|
||||||
|
|
||||||
export const ImportForm = () => {
|
export const ImportForm = () => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
|
@ -56,7 +57,9 @@ export const ImportForm = () => {
|
||||||
attributes: convertFormValuesToObject(client.attributes || {}),
|
attributes: convertFormValuesToObject(client.attributes || {}),
|
||||||
});
|
});
|
||||||
addAlert(t("clientImportSuccess"), AlertVariant.success);
|
addAlert(t("clientImportSuccess"), AlertVariant.success);
|
||||||
history.push(`/${realm}/clients/${newClient.id}`);
|
history.push(
|
||||||
|
toClient({ realm, clientId: newClient.id, tab: "settings" })
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
addAlert(t("clientImportError", { error }), AlertVariant.danger);
|
addAlert(t("clientImportError", { error }), AlertVariant.danger);
|
||||||
}
|
}
|
||||||
|
@ -91,10 +94,8 @@ export const ImportForm = () => {
|
||||||
<Button variant="primary" type="submit">
|
<Button variant="primary" type="submit">
|
||||||
{t("common:save")}
|
{t("common:save")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
{/* @ts-ignore */}
|
||||||
variant="link"
|
<Button variant="link" component={Link} to={toClients({ realm })}>
|
||||||
onClick={() => history.push(`/${realm}/clients`)}
|
|
||||||
>
|
|
||||||
{t("common:cancel")}
|
{t("common:cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
</ActionGroup>
|
</ActionGroup>
|
||||||
|
|
|
@ -15,11 +15,12 @@ import { FormAccess } from "../../components/form-access/FormAccess";
|
||||||
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
import { ViewHeader } from "../../components/view-header/ViewHeader";
|
||||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||||
import { TimeSelector } from "../../components/time-selector/TimeSelector";
|
import { TimeSelector } from "../../components/time-selector/TimeSelector";
|
||||||
import { useHistory } from "react-router-dom";
|
import { Link, useHistory } from "react-router-dom";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import { useAdminClient } from "../../context/auth/AdminClient";
|
import { useAdminClient } from "../../context/auth/AdminClient";
|
||||||
import { useAlerts } from "../../components/alert/Alerts";
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
import { AccessTokenDialog } from "./AccessTokenDialog";
|
import { AccessTokenDialog } from "./AccessTokenDialog";
|
||||||
|
import { toClients } from "../routes/Clients";
|
||||||
|
|
||||||
export const CreateInitialAccessToken = () => {
|
export const CreateInitialAccessToken = () => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
|
@ -52,7 +53,7 @@ export const CreateInitialAccessToken = () => {
|
||||||
toggleDialog={() => {
|
toggleDialog={() => {
|
||||||
setToken("");
|
setToken("");
|
||||||
addAlert(t("tokenSaveSuccess"), AlertVariant.success);
|
addAlert(t("tokenSaveSuccess"), AlertVariant.success);
|
||||||
history.push(`/${realm}/clients/initialAccessToken`);
|
history.push(toClients({ realm, tab: "initialAccessToken" }));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -129,9 +130,9 @@ export const CreateInitialAccessToken = () => {
|
||||||
<Button
|
<Button
|
||||||
data-testid="cancel"
|
data-testid="cancel"
|
||||||
variant="link"
|
variant="link"
|
||||||
onClick={() =>
|
component={Link}
|
||||||
history.push(`/${realm}/clients/initialAccessToken`)
|
// @ts-ignore
|
||||||
}
|
to={toClients({ realm, tab: "initialAccessToken" })}
|
||||||
>
|
>
|
||||||
{t("common:cancel")}
|
{t("common:cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import React, { useState } from "react";
|
|
||||||
import { useHistory, useRouteMatch } from "react-router-dom";
|
|
||||||
import moment from "moment";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { AlertVariant, Button, ButtonVariant } from "@patternfly/react-core";
|
import { AlertVariant, Button, ButtonVariant } from "@patternfly/react-core";
|
||||||
import { wrappable } from "@patternfly/react-table";
|
import { wrappable } from "@patternfly/react-table";
|
||||||
|
|
||||||
import type ClientInitialAccessPresentation from "keycloak-admin/lib/defs/clientInitialAccessPresentation";
|
import type ClientInitialAccessPresentation from "keycloak-admin/lib/defs/clientInitialAccessPresentation";
|
||||||
|
import moment from "moment";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Link, useHistory } from "react-router-dom";
|
||||||
|
import { useAlerts } from "../../components/alert/Alerts";
|
||||||
|
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
||||||
|
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
|
||||||
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
import { KeycloakDataTable } from "../../components/table-toolbar/KeycloakDataTable";
|
||||||
import { useAdminClient } from "../../context/auth/AdminClient";
|
import { useAdminClient } from "../../context/auth/AdminClient";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
|
import { toCreateInitialAccessToken } from "../routes/CreateInitialAccessToken";
|
||||||
import { useConfirmDialog } from "../../components/confirm-dialog/ConfirmDialog";
|
|
||||||
import { useAlerts } from "../../components/alert/Alerts";
|
|
||||||
|
|
||||||
export const InitialAccessTokenList = () => {
|
export const InitialAccessTokenList = () => {
|
||||||
const { t } = useTranslation("clients");
|
const { t } = useTranslation("clients");
|
||||||
|
@ -21,7 +21,6 @@ export const InitialAccessTokenList = () => {
|
||||||
const { realm } = useRealm();
|
const { realm } = useRealm();
|
||||||
|
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { url } = useRouteMatch();
|
|
||||||
|
|
||||||
const [token, setToken] = useState<ClientInitialAccessPresentation>();
|
const [token, setToken] = useState<ClientInitialAccessPresentation>();
|
||||||
|
|
||||||
|
@ -57,7 +56,8 @@ export const InitialAccessTokenList = () => {
|
||||||
loader={loader}
|
loader={loader}
|
||||||
toolbarItem={
|
toolbarItem={
|
||||||
<>
|
<>
|
||||||
<Button onClick={() => history.push(`${url}/create`)}>
|
{/* @ts-ignore */}
|
||||||
|
<Button component={Link} to={toCreateInitialAccessToken({ realm })}>
|
||||||
{t("common:create")}
|
{t("common:create")}
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
|
@ -104,7 +104,9 @@ export const InitialAccessTokenList = () => {
|
||||||
message={t("noTokens")}
|
message={t("noTokens")}
|
||||||
instructions={t("noTokensInstructions")}
|
instructions={t("noTokensInstructions")}
|
||||||
primaryActionText={t("common:create")}
|
primaryActionText={t("common:create")}
|
||||||
onPrimaryAction={() => history.push(`${url}/create`)}
|
onPrimaryAction={() =>
|
||||||
|
history.push(toCreateInitialAccessToken({ realm }))
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
16
src/clients/routes.ts
Normal file
16
src/clients/routes.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import type { RouteDef } from "../route-config";
|
||||||
|
import { AddClientRoute } from "./routes/AddClient";
|
||||||
|
import { ClientRoute } from "./routes/Client";
|
||||||
|
import { ClientsRoute } from "./routes/Clients";
|
||||||
|
import { CreateInitialAccessTokenRoute } from "./routes/CreateInitialAccessToken";
|
||||||
|
import { ImportClientRoute } from "./routes/ImportClient";
|
||||||
|
|
||||||
|
const routes: RouteDef[] = [
|
||||||
|
AddClientRoute,
|
||||||
|
ImportClientRoute,
|
||||||
|
ClientsRoute,
|
||||||
|
CreateInitialAccessTokenRoute,
|
||||||
|
ClientRoute,
|
||||||
|
];
|
||||||
|
|
||||||
|
export default routes;
|
19
src/clients/routes/AddClient.ts
Normal file
19
src/clients/routes/AddClient.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import type { LocationDescriptorObject } from "history";
|
||||||
|
import { generatePath } from "react-router-dom";
|
||||||
|
import type { RouteDef } from "../../route-config";
|
||||||
|
import { NewClientForm } from "../add/NewClientForm";
|
||||||
|
|
||||||
|
export type AddClientParams = { realm: string };
|
||||||
|
|
||||||
|
export const AddClientRoute: RouteDef = {
|
||||||
|
path: "/:realm/clients/add-client",
|
||||||
|
component: NewClientForm,
|
||||||
|
breadcrumb: (t) => t("clients:createClient"),
|
||||||
|
access: "manage-clients",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toAddClient = (
|
||||||
|
params: AddClientParams
|
||||||
|
): LocationDescriptorObject => ({
|
||||||
|
pathname: generatePath(AddClientRoute.path, params),
|
||||||
|
});
|
23
src/clients/routes/Client.ts
Normal file
23
src/clients/routes/Client.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import type { LocationDescriptorObject } from "history";
|
||||||
|
import { generatePath } from "react-router-dom";
|
||||||
|
import type { RouteDef } from "../../route-config";
|
||||||
|
import { ClientDetails } from "../ClientDetails";
|
||||||
|
|
||||||
|
export type ClientTab = "settings" | "roles" | "clientScopes" | "advanced";
|
||||||
|
|
||||||
|
export type ClientParams = {
|
||||||
|
realm: string;
|
||||||
|
clientId: string;
|
||||||
|
tab: ClientTab;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ClientRoute: RouteDef = {
|
||||||
|
path: "/:realm/clients/:clientId/:tab",
|
||||||
|
component: ClientDetails,
|
||||||
|
breadcrumb: (t) => t("clients:clientSettings"),
|
||||||
|
access: "view-clients",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toClient = (params: ClientParams): LocationDescriptorObject => ({
|
||||||
|
pathname: generatePath(ClientRoute.path, params),
|
||||||
|
});
|
22
src/clients/routes/Clients.ts
Normal file
22
src/clients/routes/Clients.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import type { LocationDescriptorObject } from "history";
|
||||||
|
import { generatePath } from "react-router-dom";
|
||||||
|
import type { RouteDef } from "../../route-config";
|
||||||
|
import { ClientsSection } from "../ClientsSection";
|
||||||
|
|
||||||
|
export type ClientsTab = "list" | "initialAccessToken";
|
||||||
|
|
||||||
|
export type ClientsParams = {
|
||||||
|
realm: string;
|
||||||
|
tab?: ClientsTab;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ClientsRoute: RouteDef = {
|
||||||
|
path: "/:realm/clients/:tab?",
|
||||||
|
component: ClientsSection,
|
||||||
|
breadcrumb: (t) => t("clients:clientList"),
|
||||||
|
access: "query-clients",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toClients = (params: ClientsParams): LocationDescriptorObject => ({
|
||||||
|
pathname: generatePath(ClientsRoute.path, params),
|
||||||
|
});
|
19
src/clients/routes/CreateInitialAccessToken.ts
Normal file
19
src/clients/routes/CreateInitialAccessToken.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import type { LocationDescriptorObject } from "history";
|
||||||
|
import { generatePath } from "react-router-dom";
|
||||||
|
import type { RouteDef } from "../../route-config";
|
||||||
|
import { CreateInitialAccessToken } from "../initial-access/CreateInitialAccessToken";
|
||||||
|
|
||||||
|
export type CreateInitialAccessTokenParams = { realm: string };
|
||||||
|
|
||||||
|
export const CreateInitialAccessTokenRoute: RouteDef = {
|
||||||
|
path: "/:realm/clients/initialAccessToken/create",
|
||||||
|
component: CreateInitialAccessToken,
|
||||||
|
breadcrumb: (t) => t("clients:createToken"),
|
||||||
|
access: "manage-clients",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toCreateInitialAccessToken = (
|
||||||
|
params: CreateInitialAccessTokenParams
|
||||||
|
): LocationDescriptorObject => ({
|
||||||
|
pathname: generatePath(CreateInitialAccessTokenRoute.path, params),
|
||||||
|
});
|
19
src/clients/routes/ImportClient.ts
Normal file
19
src/clients/routes/ImportClient.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import type { LocationDescriptorObject } from "history";
|
||||||
|
import { generatePath } from "react-router-dom";
|
||||||
|
import type { RouteDef } from "../../route-config";
|
||||||
|
import { ImportForm } from "../import/ImportForm";
|
||||||
|
|
||||||
|
export type ImportClientParams = { realm: string };
|
||||||
|
|
||||||
|
export const ImportClientRoute: RouteDef = {
|
||||||
|
path: "/:realm/clients/import-client",
|
||||||
|
component: ImportForm,
|
||||||
|
breadcrumb: (t) => t("clients:importClient"),
|
||||||
|
access: "manage-clients",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toImportClient = (
|
||||||
|
params: ImportClientParams
|
||||||
|
): LocationDescriptorObject => ({
|
||||||
|
pathname: generatePath(ImportClientRoute.path, params),
|
||||||
|
});
|
|
@ -7,11 +7,7 @@ import { RoleMappingForm } from "./client-scopes/add/RoleMappingForm";
|
||||||
import { ClientScopesSection } from "./client-scopes/ClientScopesSection";
|
import { ClientScopesSection } from "./client-scopes/ClientScopesSection";
|
||||||
import { MappingDetails } from "./client-scopes/details/MappingDetails";
|
import { MappingDetails } from "./client-scopes/details/MappingDetails";
|
||||||
import { ClientScopeForm } from "./client-scopes/form/ClientScopeForm";
|
import { ClientScopeForm } from "./client-scopes/form/ClientScopeForm";
|
||||||
import { NewClientForm } from "./clients/add/NewClientForm";
|
import clientRoutes from "./clients/routes";
|
||||||
import { ClientDetails } from "./clients/ClientDetails";
|
|
||||||
import { ClientsSection } from "./clients/ClientsSection";
|
|
||||||
import { ImportForm } from "./clients/import/ImportForm";
|
|
||||||
import { CreateInitialAccessToken } from "./clients/initial-access/CreateInitialAccessToken";
|
|
||||||
import { DashboardSection } from "./dashboard/Dashboard";
|
import { DashboardSection } from "./dashboard/Dashboard";
|
||||||
import { EventsSection } from "./events/EventsSection";
|
import { EventsSection } from "./events/EventsSection";
|
||||||
import { GroupsSection } from "./groups/GroupsSection";
|
import { GroupsSection } from "./groups/GroupsSection";
|
||||||
|
@ -55,36 +51,13 @@ export type RouteDef = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const routes: RouteDef[] = [
|
export const routes: RouteDef[] = [
|
||||||
|
...clientRoutes,
|
||||||
{
|
{
|
||||||
path: "/:realm/add-realm",
|
path: "/:realm/add-realm",
|
||||||
component: NewRealmForm,
|
component: NewRealmForm,
|
||||||
breadcrumb: (t) => t("realm:createRealm"),
|
breadcrumb: (t) => t("realm:createRealm"),
|
||||||
access: "manage-realm",
|
access: "manage-realm",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/:realm/clients/add-client",
|
|
||||||
component: NewClientForm,
|
|
||||||
breadcrumb: (t) => t("clients:createClient"),
|
|
||||||
access: "manage-clients",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/:realm/clients/import-client",
|
|
||||||
component: ImportForm,
|
|
||||||
breadcrumb: (t) => t("clients:importClient"),
|
|
||||||
access: "manage-clients",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/:realm/clients/:tab?",
|
|
||||||
component: ClientsSection,
|
|
||||||
breadcrumb: (t) => t("clients:clientList"),
|
|
||||||
access: "query-clients",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/:realm/clients/initialAccessToken/create",
|
|
||||||
component: CreateInitialAccessToken,
|
|
||||||
breadcrumb: (t) => t("clients:createToken"),
|
|
||||||
access: "manage-clients",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/:realm/clients/:clientId/roles/add-role",
|
path: "/:realm/clients/:clientId/roles/add-role",
|
||||||
component: RealmRoleTabs,
|
component: RealmRoleTabs,
|
||||||
|
@ -97,12 +70,6 @@ export const routes: RouteDef[] = [
|
||||||
breadcrumb: (t) => t("roles:roleDetails"),
|
breadcrumb: (t) => t("roles:roleDetails"),
|
||||||
access: "view-realm",
|
access: "view-realm",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/:realm/clients/:clientId/:tab",
|
|
||||||
component: ClientDetails,
|
|
||||||
breadcrumb: (t) => t("clients:clientSettings"),
|
|
||||||
access: "view-clients",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/:realm/client-scopes/new",
|
path: "/:realm/client-scopes/new",
|
||||||
component: ClientScopeForm,
|
component: ClientScopeForm,
|
||||||
|
|
Loading…
Reference in a new issue