From 866922176676c669866b095702a7a08b0aeb3183 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 19 Aug 2024 23:03:32 +1000 Subject: [PATCH 1/5] Added new placeholder routes for side nav menu Signed-off-by: root --- app/src/constants/routes.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/constants/routes.tsx b/app/src/constants/routes.tsx index a4d8efadb..ce2081b62 100644 --- a/app/src/constants/routes.tsx +++ b/app/src/constants/routes.tsx @@ -38,6 +38,8 @@ export const REVISION = '/revision/'; export const ABOUT_BUILD = '/about-build'; export const AUTOINCREMENT = '/autoincrements/'; export const PROJECT_ATTACHMENT = '/attachment/'; +export const SWITCH_ORG = '/switch-organisation'; +export const HELP = '/help'; export function getRecordRoute( project_id: ProjectID, From bd1695e92e8b7d063d952a195825599477fbdb73 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 19 Aug 2024 23:29:34 +1000 Subject: [PATCH 2/5] Enhanced side nav styling, new menu options, more clear to read & visually recognise Signed-off-by: root --- app/src/gui/layout/appBar.tsx | 79 +++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/app/src/gui/layout/appBar.tsx b/app/src/gui/layout/appBar.tsx index 18c4c55be..90bd32b1f 100644 --- a/app/src/gui/layout/appBar.tsx +++ b/app/src/gui/layout/appBar.tsx @@ -48,7 +48,6 @@ import ExpandMore from '@mui/icons-material/ExpandMore'; import AccountTree from '@mui/icons-material/AccountTree'; import DashboardIcon from '@mui/icons-material/Dashboard'; import ListItemText from '@mui/material/ListItemText'; - import * as ROUTES from '../../constants/routes'; import {getActiveProjectList} from '../../sync/projects'; import SystemAlert from '../components/alert'; @@ -56,8 +55,10 @@ import {ProjectInformation} from '@faims3/data-model'; import AppBarAuth from '../components/authentication/appbarAuth'; import {TokenContents} from '@faims3/data-model'; import {checkToken} from '../../utils/helpers'; -// import ConnectedStatus from '../components/authentication/connectedStatus'; import SyncStatus from '../components/sync'; +import HelpIcon from '@mui/icons-material/Help'; +import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; +import { now } from 'lodash'; type ProjectListItemProps = { title: string; @@ -115,14 +116,15 @@ const useStyles = makeStyles({ }, drawerPaper: { width: drawerWidth, + height: '100vh', + boxShadow: '2px 0 10px rgba(0, 0, 0, 0.3)', + borderRight: '1px solid rgba(0, 0, 0, 0.1)', }, drawerHeader: { display: 'flex', alignItems: 'center', padding: theme.spacing(0, 1), - // necessary for content to be below app bar minHeight: '64px', - // ...theme.mixins.toolbar, justifyContent: 'flex-end', }, content: { @@ -144,8 +146,21 @@ const useStyles = makeStyles({ nested: { paddingLeft: theme.spacing(4), }, + listItemText: { + fontSize: '1.1rem', + fontWeight: 'bold', + color: 'rgba(0, 0, 0, 0.54)', // Use the same gray color as the icons (this is a common MUI icon color) + }, + bottomOptions: { + borderTop: `1px solid ${theme.palette.divider}`, + padding: theme.spacing(2, 0), + }, + bottomSection: { + marginTop: 'auto', + }, }); + function getNestedProjects(pouchProjectList: ProjectInformation[]) { const projectListItems: ProjectListItemProps[] = []; pouchProjectList.map(project_info => { @@ -170,7 +185,6 @@ type NavbarProps = { }; export default function MainAppBar(props: NavbarProps) { const classes = useStyles(); - // const globalState = useContext(store); const [isOpen, setIsOpen] = useState(false); const isAuthenticated = checkToken(props.token); @@ -178,6 +192,8 @@ export default function MainAppBar(props: NavbarProps) { const [projectList, setProjectList] = useState([]); + console.log("projectlist in appBar", projectList); + useEffect(() => { getActiveProjectList().then(projects => setProjectList(projects)); }, []); @@ -198,7 +214,7 @@ export default function MainAppBar(props: NavbarProps) { projectList === null ? { title: 'Loading notebooks...', - icon: , + icon: , to: '/', disabled: true, } @@ -206,31 +222,50 @@ export default function MainAppBar(props: NavbarProps) { ? getNestedProjects(projectList) : { title: 'Notebooks', - icon: , + icon: , to: '/', disabled: true, }, ]; + const bottomMenuItems: Array = [ + + // @TODO Ranisa: Commented this for now, to be discussed if needed to display this nav item + // { + // title: 'About Build', + // icon: , + // to: ROUTES.ABOUT_BUILD, + // disabled: false, + // }, + + { + title: 'Help', + icon: , + to: ROUTES.HELP, + disabled: false, + }, + + { + title: 'Switch org', + icon: , + to: ROUTES.SWITCH_ORG, + disabled: false, + }, + isAuthenticated ? { - title: 'User', + title: 'Sign out', icon: , to: ROUTES.SIGN_IN, disabled: false, } : { - title: 'User', + title: 'Sign out', icon: , to: '/', disabled: true, }, - { - title: 'About Build', - icon: , - to: ROUTES.ABOUT_BUILD, - disabled: false, - }, + ]; const [nestedMenuOpen, setNestedMenuOpen] = useState<{ @@ -302,7 +337,7 @@ export default function MainAppBar(props: NavbarProps) { disabled={item.disabled} > {item.icon} - {item.title} + {item.title} {item.nested.length === 0 ? ( ) : nestedMenuOpen[item.title] ? ( @@ -335,7 +370,7 @@ export default function MainAppBar(props: NavbarProps) { onClick={toggle} > {nestedItem.icon} - + ) )} @@ -351,13 +386,14 @@ export default function MainAppBar(props: NavbarProps) { onClick={toggle} > {item.icon} - + ); })} - - +
+ + {bottomMenuItems.map( (item: { title: string; @@ -373,11 +409,12 @@ export default function MainAppBar(props: NavbarProps) { onClick={toggle} > {item.icon} - + ) )} +
From cf6fdb4e676c983630e48a4c9a9bd8a465cfb0b4 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 20 Aug 2024 14:02:54 +1000 Subject: [PATCH 3/5] Added some jdoc comments for better readability Signed-off-by: root --- app/src/gui/layout/appBar.tsx | 164 +++++++++++++++++++++------------- 1 file changed, 101 insertions(+), 63 deletions(-) diff --git a/app/src/gui/layout/appBar.tsx b/app/src/gui/layout/appBar.tsx index 90bd32b1f..c0a771db5 100644 --- a/app/src/gui/layout/appBar.tsx +++ b/app/src/gui/layout/appBar.tsx @@ -19,8 +19,8 @@ * throughout the app. */ -import React, {useEffect, useState} from 'react'; -import {Link as RouterLink, NavLink} from 'react-router-dom'; +import React, { useEffect, useState } from 'react'; +import { Link as RouterLink, NavLink } from 'react-router-dom'; import { AppBar as MuiAppBar, CircularProgress, @@ -30,7 +30,7 @@ import { ListItemButton, } from '@mui/material'; import MenuIcon from '@mui/icons-material/Menu'; -import {createUseStyles as makeStyles} from 'react-jss'; +import { createUseStyles as makeStyles } from 'react-jss'; import CssBaseline from '@mui/material/CssBaseline'; import clsx from 'clsx'; import Collapse from '@mui/material/Collapse'; @@ -49,25 +49,37 @@ import AccountTree from '@mui/icons-material/AccountTree'; import DashboardIcon from '@mui/icons-material/Dashboard'; import ListItemText from '@mui/material/ListItemText'; import * as ROUTES from '../../constants/routes'; -import {getActiveProjectList} from '../../sync/projects'; +import { getActiveProjectList } from '../../sync/projects'; import SystemAlert from '../components/alert'; -import {ProjectInformation} from '@faims3/data-model'; +import { ProjectInformation } from '@faims3/data-model'; import AppBarAuth from '../components/authentication/appbarAuth'; -import {TokenContents} from '@faims3/data-model'; -import {checkToken} from '../../utils/helpers'; +import { TokenContents } from '@faims3/data-model'; +import { checkToken } from '../../utils/helpers'; import SyncStatus from '../components/sync'; import HelpIcon from '@mui/icons-material/Help'; -import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; +import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; import { now } from 'lodash'; +/** + * Represents the properties for a menu list item. + * @typedef {Object} ProjectListItemProps + * @property {string} title - The title of the menuitem. + * @property {React.ReactElement} icon - The icon associated with the menuitem. + * @property {string} to - The path to navigate to for this menuitem. + * @property {boolean} disabled - Whether the menuitem is disabled in the list. + */ + type ProjectListItemProps = { title: string; icon: any; to: string; disabled: boolean; }; -// in place of deprecated React.ReactChild -type IconType = + +/** + * Represents the type of icon used in the navigation menu. + * @typedef {React.ReactElement | string | number | undefined} IconType + */type IconType = | undefined | string | number @@ -146,20 +158,39 @@ const useStyles = makeStyles({ nested: { paddingLeft: theme.spacing(4), }, + /** + * Styles for the ListItemText component in the navigation items. + * @type {Object} + */ listItemText: { fontSize: '1.1rem', fontWeight: 'bold', color: 'rgba(0, 0, 0, 0.54)', // Use the same gray color as the icons (this is a common MUI icon color) }, + /** + * Styles for the bottom section options in the drawer. + * Includes padding and a border at the top. + * @type {Object} + */ bottomOptions: { borderTop: `1px solid ${theme.palette.divider}`, padding: theme.spacing(2, 0), }, + /** + * Ensures that the bottom section of the drawer is positioned at the bottom of the viewport. + * @type {Object} + */ bottomSection: { marginTop: 'auto', }, }); +/** + * Retrieves a list of nested menu items to be displayed in the navigation menu. + * @function + * @param {ProjectInformation[]} pouchProjectList - List of project information. + * @returns {MenuItemProps} - The item for nested menu. + */ function getNestedProjects(pouchProjectList: ProjectInformation[]) { const projectListItems: ProjectListItemProps[] = []; @@ -183,6 +214,14 @@ function getNestedProjects(pouchProjectList: ProjectInformation[]) { type NavbarProps = { token?: null | undefined | TokenContents; }; +/** + * MainAppBar component handles the display of the navigation drawer and the app bar. + * It includes top menu items, bottom menu items, and conditional rendering based on authentication status. + * + * @component + * @param {NavbarProps} props - Props passed to the component. + * @returns {JSX.Element} - The rendered MainAppBar component. + */ export default function MainAppBar(props: NavbarProps) { const classes = useStyles(); @@ -192,7 +231,6 @@ export default function MainAppBar(props: NavbarProps) { const [projectList, setProjectList] = useState([]); - console.log("projectlist in appBar", projectList); useEffect(() => { getActiveProjectList().then(projects => setProjectList(projects)); @@ -213,30 +251,30 @@ export default function MainAppBar(props: NavbarProps) { }, projectList === null ? { - title: 'Loading notebooks...', - icon: , - to: '/', - disabled: true, - } + title: 'Loading notebooks...', + icon: , + to: '/', + disabled: true, + } : isAuthenticated ? getNestedProjects(projectList) : { - title: 'Notebooks', - icon: , - to: '/', - disabled: true, - }, + title: 'Notebooks', + icon: , + to: '/', + disabled: true, + }, ]; const bottomMenuItems: Array = [ - // @TODO Ranisa: Commented this for now, to be discussed if needed to display this nav item - // { - // title: 'About Build', - // icon: , - // to: ROUTES.ABOUT_BUILD, - // disabled: false, - // }, + // @TODO Ranisa: Commented this for now, to be discussed if needed to display this nav item + // { + // title: 'About Build', + // icon: , + // to: ROUTES.ABOUT_BUILD, + // disabled: false, + // }, { title: 'Help', @@ -254,23 +292,23 @@ export default function MainAppBar(props: NavbarProps) { isAuthenticated ? { - title: 'Sign out', - icon: , - to: ROUTES.SIGN_IN, - disabled: false, - } + title: 'Sign out', + icon: , + to: ROUTES.SIGN_IN, + disabled: false, + } : { - title: 'Sign out', - icon: , - to: '/', - disabled: true, - }, - + title: 'Sign out', + icon: , + to: '/', + disabled: true, + }, + ]; const [nestedMenuOpen, setNestedMenuOpen] = useState<{ [key: string]: boolean; - }>({Projects: false}); + }>({ Projects: false }); return ( @@ -293,10 +331,10 @@ export default function MainAppBar(props: NavbarProps) { > - +
@@ -311,7 +349,7 @@ export default function MainAppBar(props: NavbarProps) { variant="temporary" anchor="left" open={isOpen} - ModalProps={{onBackdropClick: toggle}} + ModalProps={{ onBackdropClick: toggle }} classes={{ paper: classes.drawerPaper, }} @@ -394,26 +432,26 @@ export default function MainAppBar(props: NavbarProps) {
- {bottomMenuItems.map( - (item: { - title: string; - icon: IconType; - disabled: boolean; - to: any; - }) => ( - - {item.icon} - - - ) - )} - + {bottomMenuItems.map( + (item: { + title: string; + icon: IconType; + disabled: boolean; + to: any; + }) => ( + + {item.icon} + + + ) + )} +
From de79067b761a9105086af5ae0382b6109de4e934 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 20 Aug 2024 16:51:51 +1000 Subject: [PATCH 4/5] More comments, todos.. Signed-off-by: root --- app/src/gui/layout/appBar.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/gui/layout/appBar.tsx b/app/src/gui/layout/appBar.tsx index c0a771db5..8577582f8 100644 --- a/app/src/gui/layout/appBar.tsx +++ b/app/src/gui/layout/appBar.tsx @@ -268,7 +268,7 @@ export default function MainAppBar(props: NavbarProps) { const bottomMenuItems: Array = [ - // @TODO Ranisa: Commented this for now, to be discussed if needed to display this nav item + // @TODO Ranisa: Commented this for now, to be discussed if needed to display this menu item // { // title: 'About Build', // icon: , @@ -283,6 +283,7 @@ export default function MainAppBar(props: NavbarProps) { disabled: false, }, + //@TODO: Conditionally render the "Switch org" option if user is part of multi organisations { title: 'Switch org', icon: , From 9aa1082ac6a70611a0ae7179c853eea7d92b9cb4 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 23 Aug 2024 11:18:40 +1000 Subject: [PATCH 5/5] Updated PR based on comments, resolved lint issues Signed-off-by: root --- app/src/gui/layout/appBar.tsx | 90 ++++++++++++++++------------------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/app/src/gui/layout/appBar.tsx b/app/src/gui/layout/appBar.tsx index a717644ce..3adcafa8b 100644 --- a/app/src/gui/layout/appBar.tsx +++ b/app/src/gui/layout/appBar.tsx @@ -19,8 +19,8 @@ * throughout the app. */ -import React, { useEffect, useState } from 'react'; -import { Link as RouterLink, NavLink } from 'react-router-dom'; +import React, {useEffect, useState} from 'react'; +import {Link as RouterLink, NavLink} from 'react-router-dom'; import { AppBar as MuiAppBar, CircularProgress, @@ -30,7 +30,7 @@ import { ListItemButton, } from '@mui/material'; import MenuIcon from '@mui/icons-material/Menu'; -import { createUseStyles as makeStyles } from 'react-jss'; +import {createUseStyles as makeStyles} from 'react-jss'; import CssBaseline from '@mui/material/CssBaseline'; import clsx from 'clsx'; import Collapse from '@mui/material/Collapse'; @@ -48,17 +48,17 @@ import AccountTree from '@mui/icons-material/AccountTree'; import DashboardIcon from '@mui/icons-material/Dashboard'; import ListItemText from '@mui/material/ListItemText'; import * as ROUTES from '../../constants/routes'; -import { getActiveProjectList } from '../../sync/projects'; +import {getActiveProjectList} from '../../sync/projects'; import SystemAlert from '../components/alert'; -import { ProjectInformation } from '@faims3/data-model'; +import {ProjectInformation} from '@faims3/data-model'; import AppBarAuth from '../components/authentication/appbarAuth'; -import { TokenContents } from '@faims3/data-model'; -import { checkToken } from '../../utils/helpers'; +import {TokenContents} from '@faims3/data-model'; +import {checkToken} from '../../utils/helpers'; import SyncStatus from '../components/sync'; import {NOTEBOOK_NAME, NOTEBOOK_NAME_CAPITALIZED} from '../../buildconfig'; import HelpIcon from '@mui/icons-material/Help'; import SwapHorizIcon from '@mui/icons-material/SwapHoriz'; -import { now } from 'lodash'; +import {now} from 'lodash'; /** * Represents the properties for a menu list item. @@ -79,7 +79,7 @@ type ProjectListItemProps = { /** * Represents the type of icon used in the navigation menu. * @typedef {React.ReactElement | string | number | undefined} IconType - */type IconType = + */ type IconType = | undefined | string | number @@ -231,7 +231,6 @@ export default function MainAppBar(props: NavbarProps) { const [projectList, setProjectList] = useState([]); - useEffect(() => { getActiveProjectList().then(projects => setProjectList(projects)); }, []); @@ -261,49 +260,31 @@ export default function MainAppBar(props: NavbarProps) { ]; const bottomMenuItems: Array = [ - - // @TODO Ranisa: Commented this for now, to be discussed if needed to display this menu item - // { - // title: 'About Build', - // icon: , - // to: ROUTES.ABOUT_BUILD, - // disabled: false, - // }, - { - title: 'Help', - icon: , - to: ROUTES.HELP, - disabled: false, - }, - - //@TODO: Conditionally render the "Switch org" option if user is part of multi organisations - { - title: 'Switch org', - icon: , - to: ROUTES.SWITCH_ORG, + title: 'About Build', + icon: , + to: ROUTES.ABOUT_BUILD, disabled: false, }, isAuthenticated ? { - title: 'Sign out', - icon: , - to: ROUTES.SIGN_IN, - disabled: false, - } + title: 'Sign out', + icon: , + to: ROUTES.SIGN_IN, + disabled: false, + } : { - title: 'Sign out', - icon: , - to: '/', - disabled: true, - }, - + title: 'Sign out', + icon: , + to: '/', + disabled: true, + }, ]; const [nestedMenuOpen, setNestedMenuOpen] = useState<{ [key: string]: boolean; - }>({ Projects: false }); + }>({Projects: false}); return ( @@ -326,10 +307,10 @@ export default function MainAppBar(props: NavbarProps) { > - +
@@ -344,7 +325,7 @@ export default function MainAppBar(props: NavbarProps) { variant="temporary" anchor="left" open={isOpen} - ModalProps={{ onBackdropClick: toggle }} + ModalProps={{onBackdropClick: toggle}} classes={{ paper: classes.drawerPaper, }} @@ -370,7 +351,9 @@ export default function MainAppBar(props: NavbarProps) { disabled={item.disabled} > {item.icon} - {item.title} + + {item.title}{' '} + {item.nested.length === 0 ? ( ) : nestedMenuOpen[item.title] ? ( @@ -403,7 +386,10 @@ export default function MainAppBar(props: NavbarProps) { onClick={toggle} > {nestedItem.icon} - + ) )} @@ -419,7 +405,10 @@ export default function MainAppBar(props: NavbarProps) { onClick={toggle} > {item.icon} - + ); })} @@ -442,7 +431,10 @@ export default function MainAppBar(props: NavbarProps) { onClick={toggle} > {item.icon} - + ) )}