Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Switch sidebar type based on routes #1889

Merged
merged 7 commits into from
May 9, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
345 changes: 176 additions & 169 deletions client/src/app/layout/SidebarApp/SidebarApp.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from "react";
import { NavLink, useHistory, useLocation } from "react-router-dom";
import React, { FC } from "react";
import { NavLink, Route, Switch, useHistory } from "react-router-dom";
import { useTranslation } from "react-i18next";
import {
Nav,
Expand All @@ -8,201 +8,208 @@ import {
NavList,
NavExpandable,
PageSidebarBody,
SelectOptionProps,
} from "@patternfly/react-core";

import { Paths } from "@app/Paths";
import { LayoutTheme } from "../LayoutUtils";
import { checkAccess } from "@app/utils/rbac-utils";
import keycloak from "@app/keycloak";

import { useLocalStorage } from "@migtools/lib-ui";
import { LocalStorageKey } from "@app/Constants";
import { FEATURES_ENABLED } from "@app/FeatureFlags";
import { SimpleSelectBasic } from "@app/components/SimpleSelectBasic";
import "./SidebarApp.css";
import { ReactElement } from "react-markdown/lib/react-markdown";
import { adminRoutes, devRoutes } from "@app/Routes";

export const SidebarApp: React.FC = () => {
const token = keycloak.tokenParsed || undefined;
const userRoles = token?.realm_access?.roles || [],
adminAccess = checkAccess(userRoles, ["tackle-admin"]);
type PersonaType = "ADMINISTRATION" | "MIGRATION";

const { t } = useTranslation();
const { search } = useLocation();
const history = useHistory();
const PersonaKey = {
ADMINISTRATION: "Administration",
MIGRATION: "Migration",
};
const PersonaKey: { [key in PersonaType]: string } = {
ADMINISTRATION: "Administration",
MIGRATION: "Migration",
};

const personaOptions: SelectOptionProps[] = [
{ value: PersonaKey.MIGRATION, children: PersonaKey.MIGRATION },
adminAccess && {
value: PersonaKey.ADMINISTRATION,
children: PersonaKey.ADMINISTRATION,
},
].filter(Boolean);
export const SidebarApp: React.FC = () => (
<Switch>
{devRoutes.map(({ path, exact }, index) => (
<Route
path={path}
exact={exact}
key={index}
render={() => <MigrationSidebar />}
/>
rszwajko marked this conversation as resolved.
Show resolved Hide resolved
))}
{adminRoutes.map(({ path, exact }, index) => (
<Route
path={path}
exact={exact}
key={index}
render={() => <AdminSidebar />}
/>
))}
</Switch>
);

const [selectedPersona, setSelectedPersona] = useLocalStorage<string | null>({
key: LocalStorageKey.selectedPersona,
defaultValue: null,
});
const PersonaSidebar: FC<{
children: ReactElement;
selectedPersona: PersonaType;
targetPath: Paths;
}> = ({ children, selectedPersona, targetPath }) => {
rszwajko marked this conversation as resolved.
Show resolved Hide resolved
const token = keycloak.tokenParsed || undefined;
const userRoles = token?.realm_access?.roles || [];
const adminAccess = checkAccess(userRoles, ["tackle-admin"]);

useEffect(() => {
if (!selectedPersona) {
history.push("/applications");
setSelectedPersona(PersonaKey.MIGRATION);
}
}, []);
const personaOptions: PersonaType[] = [
"MIGRATION",
adminAccess && "ADMINISTRATION",
].filter(Boolean);

const history = useHistory();
return (
<PageSidebar theme={LayoutTheme}>
<div className="perspective">
<SimpleSelectBasic
value={selectedPersona || undefined}
options={personaOptions}
onChange={(selection) => {
const selectionValue = selection;
setSelectedPersona(selectionValue);
if (selectionValue === PersonaKey.ADMINISTRATION) {
history.push(Paths.general);
} else {
history.push(Paths.applications);
value={selectedPersona}
options={personaOptions.map((value) => ({
value,
children: PersonaKey[value],
}))}
onChange={(value) => {
if (value !== selectedPersona) {
history.push(targetPath);
}
}}
/>
</div>
<PageSidebarBody>
<Nav id="nav-primary" aria-label="Nav" theme={LayoutTheme}>
{selectedPersona === PersonaKey.MIGRATION ? (
<NavList title="Global">
<NavItem>
<NavLink to={Paths.applications} activeClassName="pf-m-current">
{t("sidebar.applicationInventory")}
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.archetypes} activeClassName="pf-m-current">
{t("sidebar.archetypes")}
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.reports} activeClassName="pf-m-current">
{t("sidebar.reports")}
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.controls} activeClassName="pf-m-current">
{t("sidebar.controls")}
</NavLink>
</NavItem>
{FEATURES_ENABLED.migrationWaves ? (
<NavItem>
<NavLink
to={Paths.migrationWaves}
activeClassName="pf-m-current"
>
{t("sidebar.migrationWaves")}
</NavLink>
</NavItem>
) : null}
{FEATURES_ENABLED.dynamicReports ? (
<>
<NavItem>
<NavLink to={Paths.issues} activeClassName="pf-m-current">
{t("sidebar.issues")}
</NavLink>
</NavItem>
<NavItem>
<NavLink
to={Paths.dependencies}
activeClassName="pf-m-current"
>
{t("sidebar.dependencies")}
</NavLink>
</NavItem>
</>
) : null}
</NavList>
) : (
<NavList title="Admin">
<NavItem>
<NavLink to={Paths.general} activeClassName="pf-m-current">
{t("terms.general")}
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.identities} activeClassName="pf-m-current">
{t("terms.credentials")}
</NavLink>
</NavItem>
<NavExpandable
title="Repositories"
srText="SR Link"
groupId="admin-repos"
isExpanded
>
<NavItem>
<NavLink
to={Paths.repositoriesGit}
activeClassName="pf-m-current"
>
Git
</NavLink>
</NavItem>
<NavItem>
<NavLink
to={Paths.repositoriesSvn}
activeClassName="pf-m-current"
>
Subversion
</NavLink>
</NavItem>
<NavItem>
<NavLink
to={Paths.repositoriesMvn}
activeClassName="pf-m-current"
>
Maven
</NavLink>
</NavItem>
</NavExpandable>
<NavItem>
<NavLink to={Paths.proxies} activeClassName="pf-m-current">
Proxy
</NavLink>
</NavItem>
<NavItem>
<NavLink
to={Paths.migrationTargets}
activeClassName="pf-m-current"
>
Custom migration targets
</NavLink>
</NavItem>
{FEATURES_ENABLED.migrationWaves ? (
<NavExpandable
title="Issue management"
srText="SR Link"
groupId="admin-issue-management"
isExpanded
>
<NavItem>
<NavLink to={Paths.jira} activeClassName="pf-m-current">
Jira
</NavLink>
</NavItem>
</NavExpandable>
) : null}
<NavItem>
<NavLink to={Paths.assessment} activeClassName="pf-m-current">
{t("terms.assessmentQuestionnaires")}
</NavLink>
</NavItem>
</NavList>
)}
{children}
</Nav>
</PageSidebarBody>
</PageSidebar>
);
};

export const MigrationSidebar = () => {
const { t } = useTranslation();
return (
<PersonaSidebar selectedPersona="MIGRATION" targetPath={Paths.general}>
<NavList title="Global">
<NavItem>
<NavLink to={Paths.applications} activeClassName="pf-m-current">
{t("sidebar.applicationInventory")}
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.archetypes} activeClassName="pf-m-current">
{t("sidebar.archetypes")}
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.reports} activeClassName="pf-m-current">
{t("sidebar.reports")}
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.controls} activeClassName="pf-m-current">
{t("sidebar.controls")}
</NavLink>
</NavItem>
{FEATURES_ENABLED.migrationWaves ? (
<NavItem>
<NavLink to={Paths.migrationWaves} activeClassName="pf-m-current">
{t("sidebar.migrationWaves")}
</NavLink>
</NavItem>
) : null}
{FEATURES_ENABLED.dynamicReports ? (
<>
<NavItem>
<NavLink to={Paths.issues} activeClassName="pf-m-current">
{t("sidebar.issues")}
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.dependencies} activeClassName="pf-m-current">
{t("sidebar.dependencies")}
</NavLink>
</NavItem>
</>
) : null}
</NavList>
</PersonaSidebar>
);
};

export const AdminSidebar = () => {
const { t } = useTranslation();
return (
<PersonaSidebar
selectedPersona="ADMINISTRATION"
targetPath={Paths.applications}
>
<NavList title="Admin">
<NavItem>
<NavLink to={Paths.general} activeClassName="pf-m-current">
{t("terms.general")}
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.identities} activeClassName="pf-m-current">
{t("terms.credentials")}
</NavLink>
</NavItem>
<NavExpandable
title="Repositories"
srText="SR Link"
groupId="admin-repos"
isExpanded
>
<NavItem>
<NavLink to={Paths.repositoriesGit} activeClassName="pf-m-current">
Git
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.repositoriesSvn} activeClassName="pf-m-current">
Subversion
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.repositoriesMvn} activeClassName="pf-m-current">
Maven
</NavLink>
</NavItem>
</NavExpandable>
<NavItem>
<NavLink to={Paths.proxies} activeClassName="pf-m-current">
Proxy
</NavLink>
</NavItem>
<NavItem>
<NavLink to={Paths.migrationTargets} activeClassName="pf-m-current">
Custom migration targets
</NavLink>
</NavItem>
{FEATURES_ENABLED.migrationWaves ? (
<NavExpandable
title="Issue management"
srText="SR Link"
groupId="admin-issue-management"
isExpanded
>
<NavItem>
<NavLink to={Paths.jira} activeClassName="pf-m-current">
Jira
</NavLink>
</NavItem>
</NavExpandable>
) : null}
<NavItem>
<NavLink to={Paths.assessment} activeClassName="pf-m-current">
{t("terms.assessmentQuestionnaires")}
</NavLink>
</NavItem>
</NavList>
</PersonaSidebar>
);
};
Loading