From 2fa8855bf49dd4c0f229429898e53a7e8260b60b Mon Sep 17 00:00:00 2001 From: Erik Jan de Wit Date: Thu, 1 Oct 2020 16:25:29 +0200 Subject: [PATCH] initial version of the breadcrumb component (#119) * initial version of the breadcrumb component * moved breadcrumbs to Page component --- package.json | 3 +- src/App.tsx | 86 ++----------- src/clients/ClientList.tsx | 2 +- .../__snapshots__/ClientList.test.tsx.snap | 32 ++--- src/clients/messages.json | 1 + src/common-messages.json | 1 + .../bread-crumb/PageBreadCrumbs.tsx | 22 ++++ .../__tests__/PageBreadCrumbs.test.tsx | 15 +++ .../PageBreadCrumbs.test.tsx.snap | 92 ++++++++++++++ src/components/view-header/ViewHeader.tsx | 1 + src/events/messages.json | 5 + src/i18n.ts | 7 ++ src/route-config.ts | 117 ++++++++++++++++++ src/sessions/messages.json | 5 + src/user/messages.json | 5 + yarn.lock | 5 + 16 files changed, 307 insertions(+), 92 deletions(-) create mode 100644 src/components/bread-crumb/PageBreadCrumbs.tsx create mode 100644 src/components/bread-crumb/__tests__/PageBreadCrumbs.test.tsx create mode 100644 src/components/bread-crumb/__tests__/__snapshots__/PageBreadCrumbs.test.tsx.snap create mode 100644 src/events/messages.json create mode 100644 src/route-config.ts create mode 100644 src/sessions/messages.json create mode 100644 src/user/messages.json diff --git a/package.json b/package.json index 748754d6f2..3ac47420fd 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "react-dom": "^16.8.5", "react-hook-form": "^6.8.2", "react-i18next": "^11.7.0", - "react-router-dom": "^5.2.0" + "react-router-dom": "^5.2.0", + "use-react-router-breadcrumbs": "^1.0.4" }, "devDependencies": { "@babel/core": "^7.10.5", diff --git a/src/App.tsx b/src/App.tsx index 872df38f70..14f2a0faae 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,89 +5,27 @@ import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import { Header } from "./PageHeader"; import { PageNav } from "./PageNav"; import { Help } from "./components/help-enabler/HelpHeader"; -import { NewRealmForm } from "./realm/add/NewRealmForm"; -import { NewRoleForm } from "./realm-roles/add/NewRoleForm"; -import { NewClientForm } from "./clients/add/NewClientForm"; -import { NewClientScopeForm } from "./client-scopes/add/NewClientScopeForm"; -import { ImportForm } from "./clients/import/ImportForm"; -import { ClientsSection } from "./clients/ClientsSection"; -import { ClientScopesSection } from "./client-scopes/ClientScopesSection"; -import { RealmRolesSection } from "./realm-roles/RealmRolesSection"; -import { UsersSection } from "./user/UsersSection"; -import { GroupsSection } from "./groups/GroupsSection"; -import { SessionsSection } from "./sessions/SessionsSection"; -import { EventsSection } from "./events/EventsSection"; -import { RealmSettingsSection } from "./realm-settings/RealmSettingsSection"; -import { AuthenticationSection } from "./authentication/AuthenticationSection"; -import { IdentityProvidersSection } from "./identity-providers/IdentityProvidersSection"; -import { UserFederationSection } from "./user-federation/UserFederationSection"; - -import { PageNotFoundSection } from "./PageNotFoundSection"; import { RealmContextProvider } from "./components/realm-context/RealmContext"; -import { ClientSettings } from "./clients/ClientSettings"; + +import { routes } from "./route-config"; +import { PageBreadCrumbs } from "./components/bread-crumb/PageBreadCrumbs"; export const App = () => { return ( - } isManagedSidebar sidebar={}> + } + isManagedSidebar + sidebar={} + breadcrumb={} + > - - - - - - - - - - - - - - - - - - - - - - + {routes(() => {}).map((route, i) => ( + + ))} diff --git a/src/clients/ClientList.tsx b/src/clients/ClientList.tsx index 0dd76f7d64..481b907826 100644 --- a/src/clients/ClientList.tsx +++ b/src/clients/ClientList.tsx @@ -40,7 +40,7 @@ export const ClientList = ({ baseUrl, clients }: ClientListProps) => { const field = data!.toString(); const [id, clientId, disabled] = field.split("#"); return ( - + {clientId} {disabled !== "true" && Disabled} diff --git a/src/clients/__tests__/__snapshots__/ClientList.test.tsx.snap b/src/clients/__tests__/__snapshots__/ClientList.test.tsx.snap index e55b5ce7a6..cfe8551d2b 100644 --- a/src/clients/__tests__/__snapshots__/ClientList.test.tsx.snap +++ b/src/clients/__tests__/__snapshots__/ClientList.test.tsx.snap @@ -71,7 +71,7 @@ Object { data-label="clientID" > account @@ -170,7 +170,7 @@ Object { data-label="clientID" > account-console @@ -269,7 +269,7 @@ Object { data-label="clientID" > admin-cli @@ -342,7 +342,7 @@ Object { data-label="clientID" > broker @@ -415,7 +415,7 @@ Object { data-label="clientID" > master-realm @@ -486,7 +486,7 @@ Object { data-label="clientID" > new @@ -585,7 +585,7 @@ Object { data-label="clientID" > photoz-realm @@ -656,7 +656,7 @@ Object { data-label="clientID" > security-admin-console @@ -819,7 +819,7 @@ Object { data-label="clientID" > account @@ -918,7 +918,7 @@ Object { data-label="clientID" > account-console @@ -1017,7 +1017,7 @@ Object { data-label="clientID" > admin-cli @@ -1090,7 +1090,7 @@ Object { data-label="clientID" > broker @@ -1163,7 +1163,7 @@ Object { data-label="clientID" > master-realm @@ -1234,7 +1234,7 @@ Object { data-label="clientID" > new @@ -1333,7 +1333,7 @@ Object { data-label="clientID" > photoz-realm @@ -1404,7 +1404,7 @@ Object { data-label="clientID" > security-admin-console diff --git a/src/clients/messages.json b/src/clients/messages.json index 66f1c7cbee..6e01349368 100644 --- a/src/clients/messages.json +++ b/src/clients/messages.json @@ -10,6 +10,7 @@ "description": "Description", "name": "Name", "clientList": "Client list", + "clientSettings": "Client details", "generalSettings": "General Settings", "capabilityConfig": "Capability config", "clientsExplain": "Clients are applications and services that can request authentication of a user", diff --git a/src/common-messages.json b/src/common-messages.json index 922d8d0597..43d8aa2ae5 100644 --- a/src/common-messages.json +++ b/src/common-messages.json @@ -25,6 +25,7 @@ "documentation": "Documentation", "enableHelpMode": "Enable help mode", + "home": "Home", "manage": "Manage", "clients": "Clients", "clientScopes": "Client scopes", diff --git a/src/components/bread-crumb/PageBreadCrumbs.tsx b/src/components/bread-crumb/PageBreadCrumbs.tsx new file mode 100644 index 0000000000..85fec8622a --- /dev/null +++ b/src/components/bread-crumb/PageBreadCrumbs.tsx @@ -0,0 +1,22 @@ +import React from "react"; +import { Link } from "react-router-dom"; +import { Breadcrumb, BreadcrumbItem } from "@patternfly/react-core"; +import useBreadcrumbs from "use-react-router-breadcrumbs"; +import { useTranslation } from "react-i18next"; + +import { routes } from "../../route-config"; + +export const PageBreadCrumbs = () => { + const { t } = useTranslation(); + const crumbs = useBreadcrumbs(routes(t)); + return ( + + {crumbs.map(({ match, breadcrumb: crumb }, i) => ( + + {crumbs.length - 1 !== i && {crumb}} + {crumbs.length - 1 === i && <>{crumb}} + + ))} + + ); +}; diff --git a/src/components/bread-crumb/__tests__/PageBreadCrumbs.test.tsx b/src/components/bread-crumb/__tests__/PageBreadCrumbs.test.tsx new file mode 100644 index 0000000000..f5793466ac --- /dev/null +++ b/src/components/bread-crumb/__tests__/PageBreadCrumbs.test.tsx @@ -0,0 +1,15 @@ +import React from "react"; +import { mount } from "enzyme"; +import { PageBreadCrumbs } from "../PageBreadCrumbs"; +import { MemoryRouter } from "react-router-dom"; + +describe("BreadCrumbs tests", () => { + it("couple of crumbs", () => { + const crumbs = mount( + + + + ); + expect(crumbs.find(PageBreadCrumbs)).toMatchSnapshot(); + }); +}); diff --git a/src/components/bread-crumb/__tests__/__snapshots__/PageBreadCrumbs.test.tsx.snap b/src/components/bread-crumb/__tests__/__snapshots__/PageBreadCrumbs.test.tsx.snap new file mode 100644 index 0000000000..770757fbb5 --- /dev/null +++ b/src/components/bread-crumb/__tests__/__snapshots__/PageBreadCrumbs.test.tsx.snap @@ -0,0 +1,92 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`BreadCrumbs tests couple of crumbs 1`] = ` + + + + + +`; diff --git a/src/components/view-header/ViewHeader.tsx b/src/components/view-header/ViewHeader.tsx index 89c1d09913..0f6b30f5de 100644 --- a/src/components/view-header/ViewHeader.tsx +++ b/src/components/view-header/ViewHeader.tsx @@ -15,6 +15,7 @@ import { } from "@patternfly/react-core"; import { HelpContext } from "../help-enabler/HelpHeader"; import { useTranslation } from "react-i18next"; +import { PageBreadCrumbs } from "../bread-crumb/PageBreadCrumbs"; export type ViewHeaderProps = { titleKey: string; diff --git a/src/events/messages.json b/src/events/messages.json new file mode 100644 index 0000000000..9224d1f2f4 --- /dev/null +++ b/src/events/messages.json @@ -0,0 +1,5 @@ +{ + "events": { + "title": "Events" + } +} \ No newline at end of file diff --git a/src/i18n.ts b/src/i18n.ts index e8f0a23f01..079e7bd233 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -8,6 +8,9 @@ import clientScopes from "./client-scopes/messages.json"; import groups from "./groups/messages.json"; import realm from "./realm/messages.json"; import roles from "./realm-roles/messages.json"; +import users from "./user/messages.json"; +import sessions from "./sessions/messages.json"; +import events from "./events/messages.json"; import help from "./help.json"; const initOptions = { @@ -21,6 +24,10 @@ const initOptions = { ...groups, ...realm, ...roles, + ...groups, + ...users, + ...sessions, + ...events, }, }, lng: "en", diff --git a/src/route-config.ts b/src/route-config.ts new file mode 100644 index 0000000000..e72474179d --- /dev/null +++ b/src/route-config.ts @@ -0,0 +1,117 @@ +import { TFunction } from "i18next"; +import { AuthenticationSection } from "./authentication/AuthenticationSection"; +import { NewClientScopeForm } from "./client-scopes/add/NewClientScopeForm"; +import { ClientScopesSection } from "./client-scopes/ClientScopesSection"; +import { NewClientForm } from "./clients/add/NewClientForm"; +import { ClientSettings } from "./clients/ClientSettings"; +import { ClientsSection } from "./clients/ClientsSection"; +import { ImportForm } from "./clients/import/ImportForm"; +import { EventsSection } from "./events/EventsSection"; +import { GroupsSection } from "./groups/GroupsSection"; +import { IdentityProvidersSection } from "./identity-providers/IdentityProvidersSection"; +import { PageNotFoundSection } from "./PageNotFoundSection"; +import { NewRoleForm } from "./realm-roles/add/NewRoleForm"; +import { RealmRolesSection } from "./realm-roles/RealmRolesSection"; +import { RealmSettingsSection } from "./realm-settings/RealmSettingsSection"; +import { NewRealmForm } from "./realm/add/NewRealmForm"; +import { SessionsSection } from "./sessions/SessionsSection"; +import { UserFederationSection } from "./user-federation/UserFederationSection"; +import { UsersSection } from "./user/UsersSection"; + +export const routes = (t: TFunction) => [ + { + path: "/add-realm", + component: NewRealmForm, + breadcrumb: t("realm:createRealm"), + }, + { + path: "/clients", + component: ClientsSection, + breadcrumb: t("clients:clientList"), + }, + { + path: "/clients/:id", + component: ClientSettings, + breadcrumb: t("clients:clientSettings"), + }, + { + path: "/add-client", + component: NewClientForm, + breadcrumb: t("clients:createClient"), + }, + { + path: "/import-client", + component: ImportForm, + breadcrumb: t("clients:importClient"), + }, + { + path: "/client-scopes", + component: ClientScopesSection, + breadcrumb: t("clientScopeList"), + }, + { + path: "/add-client-scopes", + component: NewClientScopeForm, + breadcrumb: t("client-scopes:createClientScope"), + }, + { + path: "/realm-roles", + component: RealmRolesSection, + breadcrumb: t("roles:roleList"), + }, + { + path: "/add-role", + component: NewRoleForm, + breadcrumb: t("roles:createRole"), + }, + { + path: "/users", + component: UsersSection, + breadcrumb: t("users:title"), + }, + { + path: "/groups", + component: GroupsSection, + breadcrumb: t("groups"), + }, + { + path: "/sessions", + component: SessionsSection, + breadcrumb: t("sessions:title"), + }, + { + path: "/events", + component: EventsSection, + breadcrumb: t("events:title"), + }, + { + path: "/realm-settings", + component: RealmSettingsSection, + breadcrumb: t("realmSettings"), + }, + { + path: "/authentication", + component: AuthenticationSection, + breadcrumb: t("authentication"), + }, + { + path: "/identity-providers", + component: IdentityProvidersSection, + breadcrumb: t("identityProviders"), + }, + { + path: "/user-federation", + component: UserFederationSection, + breadcrumb: t("userFederation"), + }, + { + path: "/", + component: ClientsSection, + breadcrumb: t("common:home"), + }, + { + path: "", + component: PageNotFoundSection, + breadcrumb: "", + }, +]; diff --git a/src/sessions/messages.json b/src/sessions/messages.json new file mode 100644 index 0000000000..b450f23f45 --- /dev/null +++ b/src/sessions/messages.json @@ -0,0 +1,5 @@ +{ + "sessions": { + "title": "Sessions" + } +} \ No newline at end of file diff --git a/src/user/messages.json b/src/user/messages.json new file mode 100644 index 0000000000..2ef5a74bc5 --- /dev/null +++ b/src/user/messages.json @@ -0,0 +1,5 @@ +{ + "users": { + "title": "Users" + } +} diff --git a/yarn.lock b/yarn.lock index 37d936bb01..ac3faac5ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18484,6 +18484,11 @@ use-latest@^1.0.0: dependencies: use-isomorphic-layout-effect "^1.0.0" +use-react-router-breadcrumbs@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/use-react-router-breadcrumbs/-/use-react-router-breadcrumbs-1.0.4.tgz#12b67ba27ac7e6a00e6ae10896ea91e178e87ee2" + integrity sha512-SskKm+wFYPD7eiYrg89y1Wn8vMlY+DiZXNFuP4Wt5gMP2aolcahHGR6pRTWsfMW93CEQxdVkXv/ceHL7nfz2Fw== + use-sidecar@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.3.tgz#17a4e567d4830c0c0ee100040e85a7fe68611e0f"