mirror of
https://github.com/status-im/spiff-arena.git
synced 2025-01-29 19:25:50 +00:00
281 lines
8.4 KiB
TypeScript
281 lines
8.4 KiB
TypeScript
import {
|
|
Toggletip,
|
|
ToggletipButton,
|
|
ToggletipContent,
|
|
Button,
|
|
Header,
|
|
HeaderContainer,
|
|
HeaderMenuButton,
|
|
SkipToContent,
|
|
SideNav,
|
|
SideNavItems,
|
|
HeaderSideNavItems,
|
|
HeaderName,
|
|
HeaderNavigation,
|
|
HeaderMenuItem,
|
|
HeaderGlobalAction,
|
|
HeaderGlobalBar,
|
|
// @ts-ignore
|
|
} from '@carbon/react';
|
|
// @ts-ignore
|
|
import { Logout, Login } from '@carbon/icons-react';
|
|
import { useEffect, useState } from 'react';
|
|
import { useLocation } from 'react-router-dom';
|
|
import { Can } from '@casl/react';
|
|
// @ts-expect-error TS(2307) FIXME: Cannot find module '../logo.svg' or its correspond... Remove this comment to see the full error message
|
|
import logo from '../logo.svg';
|
|
import UserService from '../services/UserService';
|
|
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
|
|
import { PermissionsToCheck } from '../interfaces';
|
|
import { usePermissionFetcher } from '../hooks/PermissionService';
|
|
import { UnauthenticatedError } from '../services/HttpService';
|
|
import { SPIFF_ENVIRONMENT } from '../config';
|
|
import appVersionInfo from '../helpers/appVersionInfo';
|
|
|
|
// for ref: https://react-bootstrap.github.io/components/navbar/
|
|
export default function NavigationBar() {
|
|
const handleLogout = () => {
|
|
UserService.doLogout();
|
|
};
|
|
|
|
const handleLogin = () => {
|
|
UserService.doLogin();
|
|
};
|
|
|
|
const location = useLocation();
|
|
const [activeKey, setActiveKey] = useState<string>('');
|
|
|
|
const { targetUris } = useUriListForPermissions();
|
|
|
|
// App.jsx forces login (which redirects to keycloak) so we should never get here if we're not logged in.
|
|
if (!UserService.isLoggedIn()) {
|
|
throw new UnauthenticatedError('You must be authenticated to do this.');
|
|
}
|
|
const permissionRequestData: PermissionsToCheck = {
|
|
[targetUris.authenticationListPath]: ['GET'],
|
|
[targetUris.messageInstanceListPath]: ['GET'],
|
|
[targetUris.secretListPath]: ['GET'],
|
|
};
|
|
const { ability } = usePermissionFetcher(permissionRequestData);
|
|
|
|
// default to readthedocs and let someone specify an environment variable to override:
|
|
//
|
|
let documentationUrl = 'https://spiffworkflow.readthedocs.io';
|
|
if ('DOCUMENTATION_URL' in window.spiffworkflowFrontendJsenv) {
|
|
documentationUrl = window.spiffworkflowFrontendJsenv.DOCUMENTATION_URL;
|
|
}
|
|
|
|
const versionInfo = appVersionInfo();
|
|
|
|
useEffect(() => {
|
|
let newActiveKey = '/admin/process-groups';
|
|
if (location.pathname.match(/^\/admin\/messages\b/)) {
|
|
newActiveKey = '/admin/messages';
|
|
} else if (
|
|
location.pathname.match(/^\/admin\/process-instances\/reports\b/)
|
|
) {
|
|
newActiveKey = '/admin/process-instances/reports';
|
|
} else if (location.pathname.match(/^\/admin\/process-instances\b/)) {
|
|
newActiveKey = '/admin/process-instances';
|
|
} else if (location.pathname.match(/^\/admin\/configuration\b/)) {
|
|
newActiveKey = '/admin/configuration';
|
|
} else if (location.pathname === '/') {
|
|
newActiveKey = '/';
|
|
} else if (location.pathname.match(/^\/tasks\b/)) {
|
|
newActiveKey = '/';
|
|
}
|
|
setActiveKey(newActiveKey);
|
|
}, [location]);
|
|
|
|
const isActivePage = (menuItemPath: string) => {
|
|
return activeKey === menuItemPath;
|
|
};
|
|
|
|
let aboutLinkElement = null;
|
|
|
|
if (Object.keys(versionInfo).length) {
|
|
aboutLinkElement = <a href="/about">About</a>;
|
|
}
|
|
|
|
const userEmail = UserService.getUserEmail();
|
|
const username = UserService.getPreferredUsername();
|
|
|
|
const profileToggletip = (
|
|
<div style={{ display: 'flex' }} id="user-profile-toggletip">
|
|
<Toggletip isTabTip align="bottom-right">
|
|
<ToggletipButton
|
|
aria-label="User Actions"
|
|
className="user-profile-toggletip-button"
|
|
type="button"
|
|
>
|
|
<div className="user-circle">{username[0].toUpperCase()}</div>
|
|
</ToggletipButton>
|
|
<ToggletipContent className="user-profile-toggletip-content">
|
|
<p>
|
|
<strong>{username}</strong>
|
|
</p>
|
|
{username !== userEmail && <p>{userEmail}</p>}
|
|
<hr />
|
|
{aboutLinkElement}
|
|
<a target="_blank" href={documentationUrl} rel="noreferrer">
|
|
Documentation
|
|
</a>
|
|
<hr />
|
|
<Button
|
|
data-qa="logout-button"
|
|
className="button-link"
|
|
onClick={handleLogout}
|
|
>
|
|
<Logout />
|
|
Sign out
|
|
</Button>
|
|
</ToggletipContent>
|
|
</Toggletip>
|
|
</div>
|
|
);
|
|
|
|
const loginAndLogoutAction = () => {
|
|
if (UserService.isLoggedIn()) {
|
|
return (
|
|
<>
|
|
{SPIFF_ENVIRONMENT ? (
|
|
<HeaderGlobalAction
|
|
title={`The current SpiffWorkflow environment is: ${SPIFF_ENVIRONMENT}`}
|
|
className="spiff-environment-header-text unclickable-text"
|
|
>
|
|
{SPIFF_ENVIRONMENT}
|
|
</HeaderGlobalAction>
|
|
) : null}
|
|
{profileToggletip}
|
|
</>
|
|
);
|
|
}
|
|
return (
|
|
<HeaderGlobalAction
|
|
data-qa="login-button"
|
|
aria-label="Login"
|
|
onClick={handleLogin}
|
|
>
|
|
<Login />
|
|
</HeaderGlobalAction>
|
|
);
|
|
};
|
|
|
|
const configurationElement = () => {
|
|
return (
|
|
<Can
|
|
I="GET"
|
|
a={targetUris.authenticationListPath}
|
|
ability={ability}
|
|
passThrough
|
|
>
|
|
{(authenticationAllowed: boolean) => {
|
|
return (
|
|
<Can
|
|
I="GET"
|
|
a={targetUris.secretListPath}
|
|
ability={ability}
|
|
passThrough
|
|
>
|
|
{(secretAllowed: boolean) => {
|
|
if (secretAllowed || authenticationAllowed) {
|
|
return (
|
|
<HeaderMenuItem
|
|
href="/admin/configuration"
|
|
isCurrentPage={isActivePage('/admin/configuration')}
|
|
>
|
|
Configuration
|
|
</HeaderMenuItem>
|
|
);
|
|
}
|
|
return null;
|
|
}}
|
|
</Can>
|
|
);
|
|
}}
|
|
</Can>
|
|
);
|
|
};
|
|
|
|
const headerMenuItems = () => {
|
|
if (!UserService.isLoggedIn()) {
|
|
return null;
|
|
}
|
|
return (
|
|
<>
|
|
<HeaderMenuItem href="/" isCurrentPage={isActivePage('/')}>
|
|
Home
|
|
</HeaderMenuItem>
|
|
<HeaderMenuItem
|
|
href="/admin/process-groups"
|
|
isCurrentPage={isActivePage('/admin/process-groups')}
|
|
data-qa="header-nav-processes"
|
|
>
|
|
Processes
|
|
</HeaderMenuItem>
|
|
<HeaderMenuItem
|
|
href="/admin/process-instances"
|
|
isCurrentPage={isActivePage('/admin/process-instances')}
|
|
>
|
|
Process Instances
|
|
</HeaderMenuItem>
|
|
<Can I="GET" a={targetUris.messageInstanceListPath} ability={ability}>
|
|
<HeaderMenuItem
|
|
href="/admin/messages"
|
|
isCurrentPage={isActivePage('/admin/messages')}
|
|
>
|
|
Messages
|
|
</HeaderMenuItem>
|
|
</Can>
|
|
{configurationElement()}
|
|
<HeaderMenuItem
|
|
hidden
|
|
href="/admin/process-instances/reports"
|
|
isCurrentPage={isActivePage('/admin/process-instances/reports')}
|
|
>
|
|
Perspectives
|
|
</HeaderMenuItem>
|
|
</>
|
|
);
|
|
};
|
|
|
|
if (activeKey && ability) {
|
|
return (
|
|
<HeaderContainer
|
|
render={({ isSideNavExpanded, onClickSideNavExpand }: any) => (
|
|
<Header aria-label="IBM Platform Name" className="cds--g100">
|
|
<SkipToContent />
|
|
<HeaderMenuButton
|
|
data-qa="header-menu-expand-button"
|
|
aria-label="Open menu"
|
|
onClick={onClickSideNavExpand}
|
|
isActive={isSideNavExpanded}
|
|
/>
|
|
<HeaderName href="/" prefix="" data-qa="spiffworkflow-logo">
|
|
<img src={logo} className="app-logo" alt="logo" />
|
|
</HeaderName>
|
|
<HeaderNavigation
|
|
data-qa="main-nav-header"
|
|
aria-label="Spiffworkflow"
|
|
>
|
|
{headerMenuItems()}
|
|
</HeaderNavigation>
|
|
<SideNav
|
|
data-qa="side-nav-items"
|
|
aria-label="Side navigation"
|
|
expanded={isSideNavExpanded}
|
|
isPersistent={false}
|
|
>
|
|
<SideNavItems>
|
|
<HeaderSideNavItems>{headerMenuItems()}</HeaderSideNavItems>
|
|
</SideNavItems>
|
|
</SideNav>
|
|
<HeaderGlobalBar>{loginAndLogoutAction()}</HeaderGlobalBar>
|
|
</Header>
|
|
)}
|
|
/>
|
|
);
|
|
}
|
|
return null;
|
|
}
|