Fixed feedback discussions (#31409)
see: #24805 Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
6ce89670b5
commit
83f8622d15
5 changed files with 62 additions and 19 deletions
|
@ -25,7 +25,7 @@ export const PageBreadCrumbs = () => {
|
|||
const crumbs = uniqBy(
|
||||
useBreadcrumbs(routesWithCrumbs, {
|
||||
disableDefaults: true,
|
||||
excludePaths: ["/", `/${realm}`],
|
||||
excludePaths: ["/", `/${realm}`, `/${realm}/page-section`],
|
||||
}),
|
||||
elementText,
|
||||
);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
import { ButtonVariant, DropdownItem } from "@patternfly/react-core";
|
||||
import { get } from "lodash-es";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||
import { useRealm } from "../context/realm-context/RealmContext";
|
||||
|
@ -10,6 +11,9 @@ import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
|||
import { PageHandler } from "./PageHandler";
|
||||
import { PAGE_PROVIDER } from "./PageList";
|
||||
import { PageParams, toPage } from "./routes";
|
||||
import { useFetch } from "../utils/useFetch";
|
||||
import ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function Page() {
|
||||
const { adminClient } = useAdminClient();
|
||||
|
@ -21,12 +25,19 @@ export default function Page() {
|
|||
const navigate = useNavigate();
|
||||
const { id, providerId } = useParams<PageParams>();
|
||||
const { addAlert, addError } = useAlerts();
|
||||
const [pageData, setPageData] = useState<ComponentRepresentation>();
|
||||
|
||||
const page = pages?.find((p) => p.id === providerId);
|
||||
if (!page) {
|
||||
throw new Error(t("notFound"));
|
||||
}
|
||||
|
||||
useFetch(
|
||||
async () => adminClient.components.findOne({ id: id! }),
|
||||
setPageData,
|
||||
[id],
|
||||
);
|
||||
|
||||
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
|
||||
titleKey: "itemDeleteConfirmTitle",
|
||||
messageKey: "itemDeleteConfirm",
|
||||
|
@ -48,7 +59,10 @@ export default function Page() {
|
|||
<>
|
||||
<DeleteConfirm />
|
||||
<ViewHeader
|
||||
titleKey={id || t("createItem")}
|
||||
titleKey={
|
||||
get(pageData, `config.${page.metadata.displayFields[0]}`)?.[0] ||
|
||||
t("createItem")
|
||||
}
|
||||
dropdownItems={
|
||||
id
|
||||
? [
|
||||
|
|
|
@ -70,7 +70,7 @@ export const PageHandler = ({
|
|||
} else {
|
||||
await adminClient.components.create(updatedComponent);
|
||||
}
|
||||
addAlert("itemSaveSuccessful");
|
||||
addAlert(t("itemSaveSuccessful"));
|
||||
} catch (error) {
|
||||
addError("itemSaveError", error);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation";
|
||||
import type { ComponentQuery } from "@keycloak/keycloak-admin-client/lib/resources/components";
|
||||
import { useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
|
@ -7,30 +8,36 @@ import {
|
|||
ToolbarItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { IRowData } from "@patternfly/react-table";
|
||||
import { get } from "lodash-es";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
import { useAdminClient } from "../admin-client";
|
||||
import { useAlerts } from "@keycloak/keycloak-ui-shared";
|
||||
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||
import { ViewHeader } from "../components/view-header/ViewHeader";
|
||||
import { useRealm } from "../context/realm-context/RealmContext";
|
||||
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||
import { PageListParams, toDetailPage } from "./routes";
|
||||
import { addDetailPage, PageListParams, toDetailPage } from "./routes";
|
||||
|
||||
export const PAGE_PROVIDER = "org.keycloak.services.ui.extend.UiPageProvider";
|
||||
export const TAB_PROVIDER = "org.keycloak.services.ui.extend.UiTabProvider";
|
||||
|
||||
const DetailLink = (obj: ComponentRepresentation) => {
|
||||
type DetailLinkProps = {
|
||||
obj: ComponentRepresentation;
|
||||
field: string;
|
||||
};
|
||||
|
||||
const DetailLink = ({ obj, field }: DetailLinkProps) => {
|
||||
const { realm } = useRealm();
|
||||
const value = get(obj, field);
|
||||
return (
|
||||
<Link
|
||||
key={obj.id}
|
||||
key={value}
|
||||
to={toDetailPage({ realm, providerId: obj.providerId!, id: obj.id! })}
|
||||
>
|
||||
{obj.id}
|
||||
{value}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
@ -89,7 +96,7 @@ export default function PageList() {
|
|||
component={(props) => (
|
||||
<Link
|
||||
{...props}
|
||||
to={toDetailPage({ realm: realmName, providerId: page.id })}
|
||||
to={addDetailPage({ realm: realmName, providerId: page.id })}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
|
@ -109,10 +116,15 @@ export default function PageList() {
|
|||
searchPlaceholderKey="searchItem"
|
||||
loader={loader}
|
||||
columns={[
|
||||
{ name: "id", cellRenderer: DetailLink },
|
||||
...page.properties.slice(0, 3).map((p) => ({
|
||||
name: `config.${p.name}[0]`,
|
||||
displayKey: p.label,
|
||||
...page.metadata.displayFields.map((name: string, index: number) => ({
|
||||
name: `config.${name}[0]`,
|
||||
displayKey: page.properties.find((p) => p.name === name)!.label,
|
||||
cellRenderer:
|
||||
index === 0
|
||||
? (obj: ComponentRepresentation) => (
|
||||
<DetailLink obj={obj} field={`config.${name}`} />
|
||||
)
|
||||
: undefined,
|
||||
})),
|
||||
]}
|
||||
ariaLabelKey="list"
|
||||
|
@ -123,7 +135,7 @@ export default function PageList() {
|
|||
instructions={t("noItemsInstructions")}
|
||||
primaryActionText={t("createItem")}
|
||||
onPrimaryAction={() =>
|
||||
navigate(toDetailPage({ realm: realmName, providerId: page.id }))
|
||||
navigate(addDetailPage({ realm: realmName, providerId: page.id }))
|
||||
}
|
||||
/>
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { AppRouteObject } from "../routes";
|
|||
import { lazy } from "react";
|
||||
|
||||
export type PageListParams = { realm?: string; providerId: string };
|
||||
export type PageParams = { realm: string; providerId: string; id?: string };
|
||||
export type PageParams = { realm: string; providerId: string; id: string };
|
||||
|
||||
const PageList = lazy(() => import("./PageList"));
|
||||
const Page = lazy(() => import("./Page"));
|
||||
|
@ -18,15 +18,28 @@ const PageListRoute: AppRouteObject = {
|
|||
};
|
||||
|
||||
const PageDetailRoute: AppRouteObject = {
|
||||
path: "/:realm/page/:providerId/:id?",
|
||||
path: "/:realm/page-section/:providerId/:id",
|
||||
element: <Page />,
|
||||
breadcrumb: (t) => t("page"),
|
||||
breadcrumb: (t) => t("details"),
|
||||
handle: {
|
||||
access: "view-realm",
|
||||
},
|
||||
};
|
||||
|
||||
const routes: AppRouteObject[] = [PageListRoute, PageDetailRoute];
|
||||
const AddPageDetailRoute: AppRouteObject = {
|
||||
path: "/:realm/page-section/:providerId/add",
|
||||
element: <Page />,
|
||||
breadcrumb: (t) => t("add"),
|
||||
handle: {
|
||||
access: "view-realm",
|
||||
},
|
||||
};
|
||||
|
||||
const routes: AppRouteObject[] = [
|
||||
PageDetailRoute,
|
||||
AddPageDetailRoute,
|
||||
PageListRoute,
|
||||
];
|
||||
|
||||
export const toPage = (params: PageListParams): Partial<Path> => ({
|
||||
pathname: generatePath(PageListRoute.path, params),
|
||||
|
@ -36,4 +49,8 @@ export const toDetailPage = (params: PageParams): Partial<Path> => ({
|
|||
pathname: generatePath(PageDetailRoute.path, params),
|
||||
});
|
||||
|
||||
export const addDetailPage = (params: Partial<PageParams>): Partial<Path> => ({
|
||||
pathname: generatePath(AddPageDetailRoute.path, params),
|
||||
});
|
||||
|
||||
export default routes;
|
||||
|
|
Loading…
Reference in a new issue