Skip to content

Commit

Permalink
Merge pull request #138 from CybercentreCanada/hotfix/user_menu
Browse files Browse the repository at this point in the history
Hotfix/user menu
  • Loading branch information
cccs-sgaron authored Sep 24, 2021
2 parents 9d46251 + fcb5c75 commit 484a579
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 57 deletions.
3 changes: 2 additions & 1 deletion src/commons/components/layout/LayoutProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,12 @@ export interface AppLayoutProps {
apps?: AppElement[];
userMenu?: UserMenuElement[];
userMenuTitle?: string;
userMenuType?: 'icon' | 'list';
adminMenu?: UserMenuElement[];
adminMenuTitle?: string;
quickSearchURI?: string;
quickSearchParam?: string;
themeSelectionUnder: 'profile' | 'icon';
themeSelectionUnder?: 'profile' | 'icon';
left?: React.ReactNode;
leftAfterBreadcrumbs?: React.ReactNode;
right?: React.ReactNode;
Expand Down
1 change: 1 addition & 0 deletions src/commons/components/layout/leftnav/LeftNavDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export type LeftNavGroupProps = {
title: string;
icon: React.ReactElement<any>;
items: LeftNavItemProps[];
userPropValidators?: ValidatedProp[];
};

type LeftNavDrawerProps = {
Expand Down
8 changes: 5 additions & 3 deletions src/commons/components/layout/leftnav/LeftNavGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import { Collapse, List, ListItem, ListItemIcon, ListItemText, Popover, Tooltip
import ExpandLess from '@material-ui/icons/ExpandLess';
import ExpandMore from '@material-ui/icons/ExpandMore';
import useAppLayout from 'commons/components/hooks/useAppLayout';
import useAppUser from 'commons/components/hooks/useAppUser';
import { LeftNavGroupProps } from 'commons/components/layout/leftnav/LeftNavDrawer';
import LeftNavItem from 'commons/components/layout/leftnav/LeftNavItem';
import React, { useState } from 'react';

const LeftNavGroup: React.FC<LeftNavGroupProps> = ({ open = true, id, title, icon, items }) => {
const LeftNavGroup: React.FC<LeftNavGroupProps> = ({ open = true, id, title, icon, items, userPropValidators }) => {
const { drawerState } = useAppLayout();
const [popoverTarget, setPopoverTarget] = useState<(EventTarget & Element) | undefined>();
const { validateProps } = useAppUser();

const onPopoverClick = (event: React.MouseEvent) => {
setPopoverTarget(event ? event.currentTarget : undefined);
Expand All @@ -31,7 +33,7 @@ const LeftNavGroup: React.FC<LeftNavGroupProps> = ({ open = true, id, title, ico
</ListItem>
);

return (
return validateProps(userPropValidators) ? (
<div>
{drawerState ? (
groupItem
Expand Down Expand Up @@ -68,7 +70,7 @@ const LeftNavGroup: React.FC<LeftNavGroupProps> = ({ open = true, id, title, ico
</List>
</Popover>
</div>
);
) : null;
};

export default LeftNavGroup;
6 changes: 6 additions & 0 deletions src/commons/components/layout/topnav/AppSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ export type AppElement = {
const useStyles = makeStyles(theme => ({
popper: {
zIndex: theme.zIndex.drawer + 2
},
avatarIcon: {
'& img': {
objectFit: 'contain'
}
}
}));

Expand Down Expand Up @@ -101,6 +106,7 @@ const AppSwitcher: React.FC<AppsSwitcherProps> = ({ apps, width }) => {
? { width: theme.spacing(8), height: theme.spacing(8) }
: { backgroundColor: 'transparent', width: theme.spacing(8), height: theme.spacing(8) }
}
className={classes.avatarIcon}
>
{isDarkTheme
? a.img_d !== null && typeof a.img_d !== 'string'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const ThemeSelectionIcon = () => {

return allowPersonalization || layoutProps.allowTranslate || layoutProps.allowReset ? (
<ClickAwayListener onClickAway={onClickAway}>
<IconButton color="inherit" aria-label="open drawer" onClick={onThemeSelectionClick} edge="start">
<IconButton color="inherit" aria-label="open drawer" onClick={onThemeSelectionClick}>
<TuneIcon />
<Popper
open={isPopperOpen}
Expand Down
12 changes: 3 additions & 9 deletions src/commons/components/layout/topnav/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,8 @@ type AppBarProps = {
};

const TopBar: React.FC<AppBarProps> = ({ apps, width }) => {
const {
currentLayout,
layoutProps,
showQuickSearch,
autoHideAppbar,
breadcrumbsEnabled,
appbarState
} = useAppLayout();
const { currentLayout, layoutProps, showQuickSearch, autoHideAppbar, breadcrumbsEnabled, appbarState } =
useAppLayout();
const theme = useTheme();
const { getAppbarStyles } = useAppContext();
const classes = useStyles(currentLayout);
Expand Down Expand Up @@ -109,9 +103,9 @@ const TopBar: React.FC<AppBarProps> = ({ apps, width }) => {
(!showQuickSearch && !breadcrumbsEnabled) ||
(!showQuickSearch && breadcrumbsEnabled && isSm)) && <div style={{ flexGrow: 1 }} />}
{showQuickSearch && isWidthUp('sm', width) && <QuickSearch />}
{layoutProps.topnav.themeSelectionUnder === 'icon' && <ThemeSelectionIcon />}
{layoutProps.topnav.right}
<AppSwitcher apps={apps} />
{layoutProps.topnav.themeSelectionUnder === 'icon' && <ThemeSelectionIcon />}
<UserProfile />
</Toolbar>
</AppBar>
Expand Down
29 changes: 26 additions & 3 deletions src/commons/components/layout/topnav/UserProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
makeStyles,
Paper,
Popper,
Tooltip,
Typography,
useTheme
} from '@material-ui/core';
Expand Down Expand Up @@ -104,6 +105,26 @@ const UserProfile = () => {
return null;
};

const renderButtonMenu = menuItems => {
if (menuItems !== undefined && menuItems !== null && menuItems.length !== 0) {
return (
<div style={{ marginBottom: theme.spacing(-2), textAlign: 'end' }}>
{menuItems.map(
(a, i) =>
a.icon && (
<Tooltip title={a.name}>
<IconButton key={`buttonmenu-${i}`} component={Link} color="inherit" to={a.route}>
{a.icon}
</IconButton>
</Tooltip>
)
)}
</div>
);
}
return null;
};

return (
<ClickAwayListener onClickAway={onClickAway}>
<IconButton edge="end" className={classes.avatarButton} onClick={onProfileClick}>
Expand Down Expand Up @@ -141,8 +162,8 @@ const UserProfile = () => {
>
<Avatar
style={{
width: theme.spacing(8),
height: theme.spacing(8)
width: layoutProps.topnav.userMenuType === 'icon' ? theme.spacing(10) : theme.spacing(8),
height: layoutProps.topnav.userMenuType === 'icon' ? theme.spacing(10) : theme.spacing(8)
}}
alt={currentUser.name}
src={currentUser.avatar ? currentUser.avatar : gravatarUrl}
Expand All @@ -159,11 +180,13 @@ const UserProfile = () => {
<Typography variant="caption" noWrap>
{currentUser.email}
</Typography>
{layoutProps.topnav.userMenuType === 'icon' && renderButtonMenu(layoutProps.topnav.userMenu)}
</div>
</div>
</ListItem>
</List>
{renderMenu('usermenu', layoutProps.topnav.userMenu, layoutProps.topnav.userMenuTitle)}
{layoutProps.topnav.userMenuType !== 'icon' &&
renderMenu('usermenu', layoutProps.topnav.userMenu, layoutProps.topnav.userMenuTitle)}
{currentUser.is_admin &&
renderMenu('adminmenu', layoutProps.topnav.adminMenu, layoutProps.topnav.adminMenuTitle)}
{renderThemeSelection(layoutProps.topnav.themeSelectionUnder === 'profile')}
Expand Down
19 changes: 17 additions & 2 deletions src/components/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ const MyApp = () => {

const provider = getProvider();
const { t } = useTranslation();
const { setUser, setConfiguration, user } = useALContext();
const { setReady } = useAppLayout();
const { setUser, setConfiguration, user, configuration } = useALContext();
const { setReady, setApps } = useAppLayout();
const { showErrorMessage } = useMySnackbar();

const [renderedApp, setRenderedApp] = useState<PossibleApps>(user ? 'routes' : provider ? 'login' : 'load');
Expand All @@ -49,6 +49,12 @@ const MyApp = () => {
}
};

useEffect(() => {
if (configuration && configuration.ui.apps) {
setApps(configuration.ui.apps);
}
}, [configuration, setApps]);

useEffect(() => {
if (user || provider) {
return;
Expand All @@ -72,24 +78,33 @@ const MyApp = () => {
.then(api_data => {
// eslint-disable-next-line no-prototype-builtins
if (api_data === undefined || !api_data.hasOwnProperty('api_response')) {
// We got no response
showErrorMessage(t('api.unreachable'), 30000);
switchRenderedApp('load');
} else if (api_data.api_status_code === 403) {
// User account is locked
setConfiguration(api_data.api_response);
switchRenderedApp('locked');
} else if (api_data.api_status_code === 401) {
// User is not logged in
localStorage.setItem('loginParams', JSON.stringify(api_data.api_response));
setLoginParams(api_data.api_response);
switchRenderedApp('login');
} else if (api_data.api_status_code === 200) {
// Set the current user
setUser(api_data.api_response);

// Mark the interface ready
setReady(true);

// Render appropriate page
if (!api_data.api_response.agrees_with_tos && api_data.api_response.configuration.ui.tos) {
switchRenderedApp('tos');
} else {
switchRenderedApp('routes');
}
} else {
// We got an unexpected result
showErrorMessage(t('api.unreachable'), 30000);
switchRenderedApp('load');
}
Expand Down
117 changes: 83 additions & 34 deletions src/components/hooks/useMyLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import AccountTreeOutlinedIcon from '@material-ui/icons/AccountTreeOutlined';
import AmpStoriesOutlinedIcon from '@material-ui/icons/AmpStoriesOutlined';
import AssignmentOutlinedIcon from '@material-ui/icons/AssignmentOutlined';
import BuildOutlinedIcon from '@material-ui/icons/BuildOutlined';
import BusinessOutlinedIcon from '@material-ui/icons/BusinessOutlined';
import CodeOutlinedIcon from '@material-ui/icons/CodeOutlined';
import DashboardOutlinedIcon from '@material-ui/icons/DashboardOutlined';
import ErrorOutlineOutlinedIcon from '@material-ui/icons/ErrorOutlineOutlined';
Expand Down Expand Up @@ -169,6 +170,53 @@ const useMyLayout = (): AppLayoutProps => {
]
}
},

{
type: 'group' as 'group',
element: {
id: 'adminmenu',
title: t('adminmenu'),
userPropValidators: [{ prop: 'user.is_admin', value: true }],
icon: <BusinessOutlinedIcon />,
items: [
{
id: 'adminmenu.errors',
text: t('adminmenu.errors'),
route: '/admin/errors',
icon: <ErrorOutlineOutlinedIcon />,
nested: true
},
{
id: 'adminmenu.services',
text: t('adminmenu.services'),
route: '/admin/services',
icon: <AccountTreeOutlinedIcon />,
nested: true
},
{
id: 'adminmenu.sitemap',
text: t('adminmenu.sitemap'),
route: '/admin/sitemap',
icon: <MapOutlinedIcon />,
nested: true
},
{
id: 'adminmenu.tag_safelist',
text: t('adminmenu.tag_safelist'),
route: '/admin/tag_safelist',
icon: <PlaylistAddCheckIcon />,
nested: true
},
{
id: 'adminmenu.users',
text: t('adminmenu.users'),
route: '/admin/users',
icon: <SupervisorAccountOutlinedIcon />,
nested: true
}
]
}
},
{
type: 'divider' as 'divider',
element: null
Expand Down Expand Up @@ -222,13 +270,13 @@ const useMyLayout = (): AppLayoutProps => {
];

const APP_SWITCHER_ITEMS = [
// {
// alt: "AL",
// name: "Assemblyline",
// img_d: "/images/al_dark.svg",
// img_l: "/images/al.svg",
// route: "https://localhost"
// },
// {
// alt: 'AL',
// name: 'Assemblyline',
// img_d: '/images/al_dark.svg',
// img_l: '/images/al.svg',
// route: 'https://localhost'
// }
];

const USER_MENU_ITEMS = [
Expand All @@ -250,31 +298,31 @@ const useMyLayout = (): AppLayoutProps => {
];

const ADMIN_MENU_ITEMS = [
{
name: t('adminmenu.errors'),
route: '/admin/errors',
icon: <ErrorOutlineOutlinedIcon />
},
{
name: t('adminmenu.services'),
route: '/admin/services',
icon: <AccountTreeOutlinedIcon />
},
{
name: t('adminmenu.sitemap'),
route: '/admin/sitemap',
icon: <MapOutlinedIcon />
},
{
name: t('adminmenu.tag_safelist'),
route: '/admin/tag_safelist',
icon: <PlaylistAddCheckIcon />
},
{
name: t('adminmenu.users'),
route: '/admin/users',
icon: <SupervisorAccountOutlinedIcon />
}
// {
// name: t('adminmenu.errors'),
// route: '/admin/errors',
// icon: <ErrorOutlineOutlinedIcon />
// },
// {
// name: t('adminmenu.services'),
// route: '/admin/services',
// icon: <AccountTreeOutlinedIcon />
// },
// {
// name: t('adminmenu.sitemap'),
// route: '/admin/sitemap',
// icon: <MapOutlinedIcon />
// },
// {
// name: t('adminmenu.tag_safelist'),
// route: '/admin/tag_safelist',
// icon: <PlaylistAddCheckIcon />
// },
// {
// name: t('adminmenu.users'),
// route: '/admin/users',
// icon: <SupervisorAccountOutlinedIcon />
// }
];

const darkLogo = (
Expand Down Expand Up @@ -335,9 +383,10 @@ const useMyLayout = (): AppLayoutProps => {
quickSearchURI: '/search',
quickSearchParam: 'query',
right: <NotificationArea />,
themeSelectionUnder: 'icon' as 'icon',
themeSelectionUnder: 'profile' as 'profile',
userMenu: USER_MENU_ITEMS,
userMenuTitle: t('usermenu')
userMenuTitle: t('usermenu'),
userMenuType: 'icon' as 'icon'
}
};
};
Expand Down
2 changes: 2 additions & 0 deletions src/components/hooks/useMyUser.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AppElement } from 'commons/components/layout/topnav/AppSwitcher';
import { UserContextProps, UserProfileProps, ValidatedProp } from 'commons/components/user/UserProvider';
import { ClassificationDefinition } from 'helpers/classificationParser';
import { useState } from 'react';
Expand Down Expand Up @@ -69,6 +70,7 @@ export type ConfigurationDefinition = {
ui: {
allow_malicious_hinting: boolean;
allow_url_submissions: boolean;
apps: AppElement[];
banner: {
[lang: string]: string;
};
Expand Down
Loading

0 comments on commit 484a579

Please sign in to comment.