Fixed feedback discussions (#31409)

see: #24805

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
Erik Jan de Wit 2024-07-25 07:16:23 +02:00 committed by GitHub
parent 6ce89670b5
commit 83f8622d15
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 62 additions and 19 deletions

View file

@ -25,7 +25,7 @@ export const PageBreadCrumbs = () => {
const crumbs = uniqBy(
useBreadcrumbs(routesWithCrumbs, {
disableDefaults: true,
excludePaths: ["/", `/${realm}`],
excludePaths: ["/", `/${realm}`, `/${realm}/page-section`],
}),
elementText,
);

View file

@ -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
? [

View file

@ -70,7 +70,7 @@ export const PageHandler = ({
} else {
await adminClient.components.create(updatedComponent);
}
addAlert("itemSaveSuccessful");
addAlert(t("itemSaveSuccessful"));
} catch (error) {
addError("itemSaveError", error);
}

View file

@ -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 }))
}
/>
}

View file

@ -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;