From 8395449125529b4ae386bf9176f1859fee16f745 Mon Sep 17 00:00:00 2001 From: Antoine Clausse Date: Thu, 12 Dec 2024 09:14:52 +0100 Subject: [PATCH] [web] Add icon menus in the Sidebar (#22318) * Add sidebar icons and menus (Help, Account) * Place the account dropdown menu above the tooltip * Hide tooltip when dropdown menu is shown * Fixup tooltip position * Add Digital Science link * Add aria-labels on the dropdown toggles * Update sidebar items spacings - Add space between notification and DS icons - Balance margin/padding in the scrollable part * Revert changing the side of .dev-tool-bar-open-button * Remove `!important` in link color * Add Help tooltip * Revert dropdown-menu z-index change * Move `AccountMenuItems` to its own file * Revert "Remove `!important` in link color" This reverts commit b2de83f815d05cd1e224604d4ca355986ba76b99. GitOrigin-RevId: 286266ea5348384f2592f748d3ae32c452558988 --- .../components/sidebar/sidebar-ds-nav.tsx | 94 ++++++++++++++++++- .../bootstrap-5/navbar/account-menu-items.tsx | 55 +++++++++++ .../bootstrap-5/navbar/logged-in-items.tsx | 44 +-------- .../navbar/nav-dropdown-from-data.tsx | 26 ++++- .../pages/project-list-ds-nav.scss | 63 +++++++++++-- 5 files changed, 226 insertions(+), 56 deletions(-) create mode 100644 services/web/frontend/js/features/ui/components/bootstrap-5/navbar/account-menu-items.tsx diff --git a/services/web/frontend/js/features/project-list/components/sidebar/sidebar-ds-nav.tsx b/services/web/frontend/js/features/project-list/components/sidebar/sidebar-ds-nav.tsx index 49261752da..f095b0a02e 100644 --- a/services/web/frontend/js/features/project-list/components/sidebar/sidebar-ds-nav.tsx +++ b/services/web/frontend/js/features/project-list/components/sidebar/sidebar-ds-nav.tsx @@ -1,15 +1,36 @@ +import { useState } from 'react' import NewProjectButton from '../new-project-button' import SidebarFilters from './sidebar-filters' import AddAffiliation, { useAddAffiliation } from '../add-affiliation' import SurveyWidget from '../survey-widget' import { usePersistedResize } from '../../../../shared/hooks/use-resize' +import MaterialIcon from '@/shared/components/material-icon' +import { Dropdown } from 'react-bootstrap-5' +import getMeta from '@/utils/meta' +import OLTooltip from '@/features/ui/components/ol/ol-tooltip' +import { useTranslation } from 'react-i18next' +import { NavDropdownMenuItems } from '@/features/ui/components/bootstrap-5/navbar/nav-dropdown-from-data' +import { NavbarDropdownItemData } from '@/features/ui/components/types/navbar' +import { useContactUsModal } from '@/shared/hooks/use-contact-us-modal' +import { UserProvider } from '@/shared/context/user-context' +import { AccountMenuItems } from '@/features/ui/components/bootstrap-5/navbar/account-menu-items' function SidebarDsNav() { + const { t } = useTranslation() + const [showAccountDropdown, setShowAccountDropdown] = useState(false) + const [showHelpDropdown, setShowHelpDropdown] = useState(false) + const { showModal: showContactUsModal, modal: contactUsModal } = + useContactUsModal({ + autofillProjectUrl: false, + }) const { show: showAddAffiliationWidget } = useAddAffiliation() const { mousePos, getHandleProps, getTargetProps } = usePersistedResize({ name: 'project-sidebar', }) - + const { sessionUser, showSubscriptionLink, items } = getMeta('ol-navbar') + const helpItem = items.find( + item => item.text === 'help' + ) as NavbarDropdownItemData return (
-
- Help / Profile -
- DS Nav +
+ {helpItem && ( + setShowHelpDropdown(show)} + > + + +
+ +
+
+
+ + + +
+ )} + {sessionUser && ( + <> + setShowAccountDropdown(show)} + > + + +
+ +
+
+
+ + + +
+ {contactUsModal} + + )} +
+
+ + Digital Science +
+ + {sessionUser.email} + + + + {t('Account Settings')} + + {showSubscriptionLink ? ( + + {t('subscription')} + + ) : null} + + + { + // The button is outside the form but still belongs to it via the + // form attribute. The reason to do this is that if the button is + // inside the form, screen readers will not count it in the total + // number of menu items + } + + {t('log_out')} + +
+ +
+
+ + ) +} diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/logged-in-items.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/logged-in-items.tsx index b1990b22a8..17f29591f0 100644 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/logged-in-items.tsx +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/logged-in-items.tsx @@ -1,12 +1,8 @@ import { useTranslation } from 'react-i18next' -import { Dropdown } from 'react-bootstrap-5' -import NavDropdownDivider from '@/features/ui/components/bootstrap-5/navbar/nav-dropdown-divider' -import getMeta from '@/utils/meta' import NavDropdownMenu from '@/features/ui/components/bootstrap-5/navbar/nav-dropdown-menu' -import NavDropdownLinkItem from '@/features/ui/components/bootstrap-5/navbar/nav-dropdown-link-item' -import DropdownListItem from '@/features/ui/components/bootstrap-5/dropdown-list-item' import type { NavbarSessionUser } from '@/features/ui/components/types/navbar' import NavLinkItem from '@/features/ui/components/bootstrap-5/navbar/nav-link-item' +import { AccountMenuItems } from './account-menu-items' export default function LoggedInItems({ sessionUser, @@ -16,44 +12,14 @@ export default function LoggedInItems({ showSubscriptionLink: boolean }) { const { t } = useTranslation() - const logOutFormId = 'logOutForm' - return ( <> {t('projects')} - - {sessionUser.email} - - - - {t('Account Settings')} - - {showSubscriptionLink ? ( - - {t('subscription')} - - ) : null} - - - { - // The button is outside the form but still belongs to it via the - // form attribute. The reason to do this is that if the button is - // inside the form, screen readers will not count it in the total - // number of menu items - } - - {t('log_out')} - -
- -
-
+
) diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-dropdown-from-data.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-dropdown-from-data.tsx index 0fc1a211e2..030220abb4 100644 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-dropdown-from-data.tsx +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-dropdown-from-data.tsx @@ -1,4 +1,7 @@ -import type { NavbarDropdownItemData } from '@/features/ui/components/types/navbar' +import type { + NavbarDropdownItemData, + NavbarItemDropdownData, +} from '@/features/ui/components/types/navbar' import NavDropdownDivider from '@/features/ui/components/bootstrap-5/navbar/nav-dropdown-divider' import { sendMB } from '@/infrastructure/event-tracking' import { isDropdownLinkItem } from '@/features/ui/components/bootstrap-5/navbar/util' @@ -16,7 +19,24 @@ export default function NavDropdownFromData({ }) { return ( - {item.dropdown.map((child, index) => { + + + ) +} + +export function NavDropdownMenuItems({ + dropdown, + showContactUsModal, +}: { + dropdown: NavbarItemDropdownData + showContactUsModal: (event?: Event) => void +}) { + return ( + <> + {dropdown.map((child, index) => { if ('divider' in child) { return } else if ('isContactUs' in child) { @@ -41,6 +61,6 @@ export default function NavDropdownFromData({ ) } })} - + ) } diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/project-list-ds-nav.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/project-list-ds-nav.scss index 713dea276d..59832353de 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/pages/project-list-ds-nav.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/project-list-ds-nav.scss @@ -25,10 +25,6 @@ display: flex; overflow-y: hidden; - .new-project-button { - margin-bottom: var(--spacing-08); - } - .project-list-sidebar-wrapper-react { position: relative; display: flex; @@ -41,8 +37,8 @@ .project-list-sidebar-scroll { flex: 1 1 auto; overflow: auto; - margin: 0 calc(var(--spacing-07) * -1); - padding: 0 var(--spacing-07); + margin: var(--spacing-05) calc(var(--spacing-07) * -1); + padding: var(--spacing-05) var(--spacing-07); } .project-list-sidebar-survey-link { @@ -59,9 +55,15 @@ padding: 0; } } + + .project-list-sidebar-survey-wrapper .user-notifications { + margin-bottom: var(--spacing-05); + } } ul.project-list-filters { + margin-bottom: 0; + hr { margin: var(--spacing-05) 0; } @@ -143,8 +145,51 @@ width: 100% !important; } } -} -.project-list-sidebar-survey-wrapper { - margin-top: var(--spacing-05); + .ds-nav-icon-dropdown { + .dropdown-toggle { + color: var(--content-secondary); + background: none; + height: 44px; + width: 44px; + padding: 0; + overflow: hidden; + + &:hover { + background-color: var(--bg-light-secondary); + } + + &.show { + background-color: var(--bg-accent-03); + } + + &::after { + display: none; + } + + > div { + height: 100%; + display: flex; + align-items: center; + justify-content: center; + } + + .material-symbols { + vertical-align: middle; + } + } + } + + .ds-nav-ds-link { + margin-bottom: var(--spacing-05); + + a { + color: var(--content-secondary) !important; + text-transform: uppercase; + font-weight: bold; + text-decoration: none; + + @include body-xs; + } + } }