From a1e42ff003ea1feca1d0726fa4a8d9af96862d6e Mon Sep 17 00:00:00 2001 From: Antoine Clausse Date: Tue, 17 Dec 2024 17:40:17 +0100 Subject: [PATCH] [web] Reapply "Update navigation events (navbar menu, new project)" and bugfix (#22576) * Reapply "[web] Update navigation events (navbar menu, new project) (#22473)" This reverts commit 134809f73c57d3f019e8158243e1fc74f9f6540a. * Set the analytics event on the links, not the small contained span (pug) * Fixup `menu-click` events in pug files: use `trackingKey`, correct event name, ... * Add `location` prop in NavDropdownMenuItems and ContactUsItem, because they're used in the sidebar too GitOrigin-RevId: 0bb95f69182268c34929f51121f2d5a2b19c4692 --- .../layout/navbar-marketing-bootstrap-5.pug | 31 +++++++---- .../web/app/views/layout/navbar-marketing.pug | 31 +++++++---- .../views/layout/navbar-website-redesign.pug | 31 +++++++---- .../js/features/event-tracking/index.js | 8 +++ .../components/new-project-button.tsx | 38 ++++++++----- .../components/project-list-events.ts | 54 +++++++++++++++++++ .../components/sidebar/sidebar-ds-nav.tsx | 20 ++++++- .../bootstrap-5/navbar/admin-menu.tsx | 15 +++++- .../bootstrap-5/navbar/contact-us-item.tsx | 10 +++- .../bootstrap-5/navbar/default-navbar.tsx | 6 +-- .../bootstrap-5/navbar/logged-in-items.tsx | 15 +++++- .../bootstrap-5/navbar/logged-out-items.tsx | 13 +++-- .../navbar/nav-dropdown-from-data.tsx | 37 +++++++++++-- .../bootstrap-5/navbar/nav-dropdown-menu.tsx | 4 +- .../bootstrap-5/navbar/nav-item-from-data.tsx | 9 +++- .../js/features/ui/components/types/navbar.ts | 5 +- 16 files changed, 259 insertions(+), 68 deletions(-) create mode 100644 services/web/frontend/js/features/project-list/components/project-list-events.ts diff --git a/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug b/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug index ec16744a44..1c527c93d2 100644 --- a/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug +++ b/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug @@ -48,6 +48,10 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={ aria-expanded="false", data-bs-toggle="dropdown" role="menuitem" + event-tracking="menu-expand" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation={"item": "admin", "location": "top-menu"} ) | Admin span.caret @@ -84,6 +88,10 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={ aria-expanded="false", data-bs-toggle="dropdown" role="menuitem" + event-tracking="menu-expand" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation={"item": item.trackingKey, "location": "top-menu"} ) | !{translate(item.text)} span.caret @@ -92,18 +100,18 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={ if child.divider +dropdown-menu-divider else if child.isContactUs - +dropdown-menu-link-item()(data-ol-open-contact-form-modal="contact-us" data-bs-target="#contactUsModal" href data-bs-toggle="modal") - span(event-tracking="menu-clicked-contact" event-tracking-mb="true" event-tracking-trigger="click") + +dropdown-menu-link-item()(data-ol-open-contact-form-modal="contact-us" data-bs-target="#contactUsModal" href data-bs-toggle="modal" event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={"item": "contact", "location": "top-menu"}) + span | #{translate("contact_us")} else if child.url +dropdown-menu-link-item()( href=child.url, class=child.class, - event-tracking=child.event + event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" - event-segmentation=child.eventSegmentation + event-segmentation={ item: child.trackingKey, location: 'top-menu' } ) !{translate(child.text)} else +dropdown-menu-item !{translate(child.text)} @@ -113,9 +121,10 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={ +nav-link( href=item.url, class=item.class, - event-tracking=item.event + event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" + event-segmentation={ item: item.trackingKey, location: 'top-menu' } ) !{translate(item.text)} else | !{translate(item.text)} @@ -127,22 +136,22 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={ +nav-item.primary +nav-link( href="/register" - event-tracking="menu-clicked-register" + event-tracking="menu-click" event-tracking-action="clicked" event-tracking-trigger="click" event-tracking-mb="true" - event-segmentation={ page: currentUrl } + event-segmentation={ page: currentUrl, item: 'register', location: 'top-menu' } ) #{translate('sign_up')} // login link +nav-item +nav-link( href="/login" - event-tracking="menu-clicked-login" + event-tracking="menu-click" event-tracking-action="clicked" event-tracking-trigger="click" event-tracking-mb="true" - event-segmentation={ page: currentUrl } + event-segmentation={ page: currentUrl, item: 'login', location: 'top-menu' } ) #{translate('log_in')} // projects link and account menu @@ -155,6 +164,10 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={ aria-expanded="false", data-bs-toggle="dropdown" role="menuitem" + event-tracking="menu-expand" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation={"item": "account", "location": "top-menu"} ) | #{translate('Account')} span.caret diff --git a/services/web/app/views/layout/navbar-marketing.pug b/services/web/app/views/layout/navbar-marketing.pug index 01676bbfe7..ebf698f726 100644 --- a/services/web/app/views/layout/navbar-marketing.pug +++ b/services/web/app/views/layout/navbar-marketing.pug @@ -42,6 +42,10 @@ nav.navbar.navbar-default.navbar-main aria-haspopup="true", aria-expanded="false", data-toggle="dropdown" + event-tracking="menu-expand" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation={"item": "admin", "location": "top-menu"} ) | Admin span.caret @@ -85,6 +89,10 @@ nav.navbar.navbar-default.navbar-main aria-haspopup="true", aria-expanded="false", data-toggle="dropdown" + event-tracking="menu-expand" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation={"item": item.trackingKey, "location": "top-menu"} ) | !{translate(item.text)} span.caret @@ -94,8 +102,8 @@ nav.navbar.navbar-default.navbar-main li.divider else if child.isContactUs li - a(data-ol-open-contact-form-modal="contact-us" href) - span(event-tracking="menu-clicked-contact" event-tracking-mb="true" event-tracking-trigger="click") + a(data-ol-open-contact-form-modal="contact-us" href event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={"item": "contact", "location": "top-menu"}) + span | #{translate("contact_us")} else li @@ -103,10 +111,10 @@ nav.navbar.navbar-default.navbar-main a( href=child.url, class=child.class, - event-tracking=child.event + event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" - event-segmentation=child.eventSegmentation + event-segmentation={item: item.trackingKey, location: 'top-menu'} ) !{translate(child.text)} else | !{translate(child.text)} @@ -116,9 +124,10 @@ nav.navbar.navbar-default.navbar-main a( href=item.url, class=item.class, - event-tracking=item.event + event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" + event-segmentation={ item: item.trackingKey, location: 'top-menu' } ) !{translate(item.text)} else | !{translate(item.text)} @@ -130,22 +139,22 @@ nav.navbar.navbar-default.navbar-main li.primary a( href="/register" - event-tracking="menu-clicked-register" + event-tracking="menu-click" event-tracking-action="clicked" event-tracking-trigger="click" event-tracking-mb="true" - event-segmentation={ page: currentUrl } + event-segmentation={ page: currentUrl, item: 'register', location: 'top-menu' } ) #{translate('sign_up')} // login link li a( href="/login" - event-tracking="menu-clicked-login" + event-tracking="menu-click" event-tracking-action="clicked" event-tracking-trigger="click" event-tracking-mb="true" - event-segmentation={ page: currentUrl } + event-segmentation={ page: currentUrl, item: 'login', location: 'top-menu' } ) #{translate('log_in')} // projects link and account menu @@ -159,6 +168,10 @@ nav.navbar.navbar-default.navbar-main aria-haspopup="true", aria-expanded="false", data-toggle="dropdown" + event-tracking="menu-expand" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation={"item": "account", "location": "top-menu"} ) | #{translate('Account')} span.caret diff --git a/services/web/app/views/layout/navbar-website-redesign.pug b/services/web/app/views/layout/navbar-website-redesign.pug index 58616f9c3e..3e18ca94bc 100644 --- a/services/web/app/views/layout/navbar-website-redesign.pug +++ b/services/web/app/views/layout/navbar-website-redesign.pug @@ -42,6 +42,10 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar aria-haspopup="true", aria-expanded="false", data-toggle="dropdown" + event-tracking="menu-expand" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation={"item": "admin", "location": "top-menu"} ) | Admin span.caret @@ -85,6 +89,10 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar aria-haspopup="true", aria-expanded="false", data-toggle="dropdown" + event-tracking="menu-expand" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation={"item": item.trackingKey, "location": "top-menu"} ) | !{translate(item.text)} span.caret @@ -94,8 +102,8 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar li.divider else if child.isContactUs li - a(data-ol-open-contact-form-modal="contact-us" href) - span(event-tracking="menu-clicked-contact" event-tracking-mb="true" event-tracking-trigger="click") + a(data-ol-open-contact-form-modal="contact-us" href event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={"item": "contact", "location": "top-menu"}) + span | #{translate("contact_us")} else li @@ -103,10 +111,10 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar a( href=child.url, class=child.class, - event-tracking=child.event + event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" - event-segmentation=child.eventSegmentation + event-segmentation={item: child.trackingKey, location: 'top-menu'} ) !{translate(child.text)} else | !{translate(child.text)} @@ -116,9 +124,10 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar a( href=item.url, class=item.class, - event-tracking=item.event + event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" + event-segmentation={ item: item.trackingKey, location: 'top-menu' } ) !{translate(item.text)} else | !{translate(item.text)} @@ -130,22 +139,22 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar li.primary a( href="/register" - event-tracking="menu-clicked-register" + event-tracking="menu-click" event-tracking-action="clicked" event-tracking-trigger="click" event-tracking-mb="true" - event-segmentation={ page: currentUrl } + event-segmentation={ page: currentUrl, item: 'register', location: 'top-menu' } ) #{translate('sign_up')} // login link li.secondary a( href="/login" - event-tracking="menu-clicked-login" + event-tracking="menu-click" event-tracking-action="clicked" event-tracking-trigger="click" event-tracking-mb="true" - event-segmentation={ page: currentUrl } + event-segmentation={ page: currentUrl, item: 'login', location: 'top-menu' } ) #{translate('log_in')} // projects link and account menu @@ -159,6 +168,10 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar aria-haspopup="true", aria-expanded="false", data-toggle="dropdown" + event-tracking="menu-expand" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation={"item": "account", "location": "top-menu"} ) | #{translate('Account')} span.caret diff --git a/services/web/frontend/js/features/event-tracking/index.js b/services/web/frontend/js/features/event-tracking/index.js index beae334153..e016f59026 100644 --- a/services/web/frontend/js/features/event-tracking/index.js +++ b/services/web/frontend/js/features/event-tracking/index.js @@ -12,6 +12,14 @@ function setupEventTracking(el) { const element = el.getAttribute('event-tracking-element') function submit() { + if (key === 'menu-expand') { + const expanded = el.getAttribute('aria-expanded') + if (expanded === 'true') { + // skip if the menu is already expanded + return + } + } + const segmentation = JSON.parse( el.getAttribute('event-segmentation') || '{}' ) diff --git a/services/web/frontend/js/features/project-list/components/new-project-button.tsx b/services/web/frontend/js/features/project-list/components/new-project-button.tsx index 5a0cf33f44..ea9e8bf549 100644 --- a/services/web/frontend/js/features/project-list/components/new-project-button.tsx +++ b/services/web/frontend/js/features/project-list/components/new-project-button.tsx @@ -17,6 +17,8 @@ import { DropdownMenu, DropdownToggle, } from '@/features/ui/components/bootstrap-5/dropdown-menu' +import { useSendProjectListMB } from '@/features/project-list/components/project-list-events' +import type { PortalTemplate } from '../../../../../types/portal-template' type SendTrackingEvent = { dropdownMenu: string @@ -54,7 +56,7 @@ function NewProjectButton({ useState>(null) const portalTemplates = getMeta('ol-portalTemplates') || [] const { show: enableAddAffiliationWidget } = useAddAffiliation() - + const sendProjectListMB = useSendProjectListMB() const sendTrackingEvent = useCallback( ({ dropdownMenu, @@ -103,37 +105,46 @@ function NewProjectButton({ dropdownMenu: dropdownMenuEvent, dropdownOpen: true, }) + sendProjectListMB('new-project-click', { item: dropdownMenuEvent }) setModal(modalVariant) }, - [sendTrackingEvent] + [sendProjectListMB, sendTrackingEvent] ) const handlePortalTemplateClick = useCallback( - (e: React.MouseEvent, institutionTemplateName: string) => { + (e: React.MouseEvent, template: PortalTemplate) => { // avoid invoking the "onClick" callback on the main dropdown button e.stopPropagation() sendTrackingEvent({ dropdownMenu: 'institution-template', dropdownOpen: true, - institutionTemplateName, + institutionTemplateName: template.name, + }) + sendProjectListMB('new-project-click', { + item: template.name, + destinationURL: template.url, }) }, - [sendTrackingEvent] + [sendProjectListMB, sendTrackingEvent] ) const handleStaticTemplateClick = useCallback( - (e: React.MouseEvent, templateTrackingKey: string) => { + (e: React.MouseEvent, template: { trackingKey: string; url: string }) => { // avoid invoking the "onClick" callback on the main dropdown button e.stopPropagation() sendTrackingEvent({ - dropdownMenu: templateTrackingKey, + dropdownMenu: template.trackingKey, dropdownOpen: true, }) + sendProjectListMB('new-project-click', { + item: template.trackingKey, + destinationURL: template.url, + }) }, - [sendTrackingEvent] + [sendProjectListMB, sendTrackingEvent] ) const [importProjectFromGithubMenu] = importOverleafModules( @@ -149,6 +160,9 @@ function NewProjectButton({ { + if (nextShow) sendProjectListMB('new-project-expand', undefined) + }} > - handlePortalTemplateClick(e, portalTemplate.name) - } + onClick={e => handlePortalTemplateClick(e, portalTemplate)} aria-label={`${portalTemplate.name} ${t('template')}`} > {portalTemplate.name} @@ -241,9 +253,7 @@ function NewProjectButton({
  • - handleStaticTemplateClick(e, templateLink.trackingKey) - } + onClick={e => handleStaticTemplateClick(e, templateLink)} aria-label={`${templateLink.name} ${t('template')}`} > {templateLink.name === 'view_all' diff --git a/services/web/frontend/js/features/project-list/components/project-list-events.ts b/services/web/frontend/js/features/project-list/components/project-list-events.ts new file mode 100644 index 0000000000..eda62016ed --- /dev/null +++ b/services/web/frontend/js/features/project-list/components/project-list-events.ts @@ -0,0 +1,54 @@ +import { useCallback } from 'react' +import { useSplitTestContext } from '@/shared/context/split-test-context' +import { sendMB } from '@/infrastructure/event-tracking' + +export type ExtraSegmentations = { + 'menu-expand': { + item: 'help' | 'account' | 'features' | 'admin' + location: 'top-menu' | 'sidebar' + } + 'menu-click': { + item: + | 'login' + | 'register' + | 'premium-features' + | 'enterprises' + | 'universities' + | 'publishers' + | 'edu' + | 'government' + | 'why-latex' + | 'learn' + | 'contact' + | 'templates' + | 'plans' + location: 'top-menu' | 'sidebar' + destinationURL?: string + } + 'new-project-expand': undefined + 'new-project-click': { + item: + | 'blank-project' + | 'example-project' + | 'upload' + | 'github-import' + | 'all-templates' + | (string & {}) + destinationURL?: string + } +} + +export const useSendProjectListMB = () => { + const { splitTestVariants } = useSplitTestContext() + const hasDsNav = splitTestVariants['sidebar-navigation-ui-update'] as + | 'default' + | 'active' + return useCallback( + ( + event: T, + payload: ExtraSegmentations[T] + ) => + sendMB(event, { ...payload, 'sidebar-navigation-ui-update': hasDsNav }), + [hasDsNav] + ) +} 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 0a2942f944..068f80c7a1 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 @@ -16,6 +16,7 @@ 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' import { useScrolled } from '@/features/project-list/components/sidebar/use-scroll' +import { useSendProjectListMB } from '@/features/project-list/components/project-list-events' function SidebarDsNav() { const { t } = useTranslation() @@ -29,6 +30,7 @@ function SidebarDsNav() { const { mousePos, getHandleProps, getTargetProps } = usePersistedResize({ name: 'project-sidebar', }) + const sendMB = useSendProjectListMB() const { sessionUser, showSubscriptionLink, items } = getMeta('ol-navbar') const helpItem = items.find( item => item.text === 'help' @@ -65,7 +67,12 @@ function SidebarDsNav() { {helpItem && ( setShowHelpDropdown(show)} + onToggle={show => { + setShowHelpDropdown(show) + if (show) { + sendMB('menu-expand', { item: 'help', location: 'sidebar' }) + } + }} > @@ -100,7 +108,15 @@ function SidebarDsNav() { <> setShowAccountDropdown(show)} + onToggle={show => { + setShowAccountDropdown(show) + if (show) { + sendMB('menu-expand', { + item: 'account', + location: 'sidebar', + }) + } + }} > ) { + const sendProjectListMB = useSendProjectListMB() return ( - + { + if (nextShow) { + sendProjectListMB('menu-expand', { + item: 'admin', + location: 'top-menu', + }) + } + }} + > {canDisplayAdminMenu ? ( <> Manage Site diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/contact-us-item.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/contact-us-item.tsx index 85ece25d7d..80d731cc46 100644 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/contact-us-item.tsx +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/contact-us-item.tsx @@ -1,14 +1,20 @@ -import { sendMB } from '@/infrastructure/event-tracking' import { useTranslation } from 'react-i18next' import { DropdownItem } from 'react-bootstrap-5' import DropdownListItem from '@/features/ui/components/bootstrap-5/dropdown-list-item' +import { + type ExtraSegmentations, + useSendProjectListMB, +} from '@/features/project-list/components/project-list-events' export default function ContactUsItem({ showModal, + location, }: { showModal: (event?: Event) => void + location: ExtraSegmentations['menu-click']['location'] }) { const { t } = useTranslation() + const sendMB = useSendProjectListMB() return ( @@ -16,7 +22,7 @@ export default function ContactUsItem({ as="button" role="menuitem" onClick={() => { - sendMB('menu-clicked-contact') + sendMB('menu-click', { item: 'contact', location }) showModal() }} > diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/default-navbar.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/default-navbar.tsx index a65e803ea1..80827f9b29 100644 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/default-navbar.tsx +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/default-navbar.tsx @@ -27,7 +27,6 @@ function DefaultNavbar(props: DefaultNavbarMetadata) { showCloseIcon = false, showSubscriptionLink, showSignUpLink, - currentUrl, sessionUser, adminUrl, items, @@ -125,10 +124,7 @@ function DefaultNavbar(props: DefaultNavbarMetadata) { showSubscriptionLink={showSubscriptionLink} /> ) : ( - + )} 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 3b123c0afb..5273eb8e98 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 @@ -3,6 +3,7 @@ import NavDropdownMenu from '@/features/ui/components/bootstrap-5/navbar/nav-dro 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' +import { useSendProjectListMB } from '@/features/project-list/components/project-list-events' export default function LoggedInItems({ sessionUser, @@ -12,12 +13,24 @@ export default function LoggedInItems({ showSubscriptionLink: boolean }) { const { t } = useTranslation() + const sendProjectListMB = useSendProjectListMB() return ( <> {t('projects')} - + { + if (nextShow) { + sendProjectListMB('menu-expand', { + item: 'account', + location: 'top-menu', + }) + } + }} + > @@ -17,8 +16,8 @@ export default function LoggedOutItems({ { - sendMB('menu-clicked-register', { page: currentUrl }) + onClick={() => { + sendMB('menu-click', { item: 'register', location: 'top-menu' }) }} > {t('sign_up')} @@ -27,8 +26,8 @@ export default function LoggedOutItems({ { - sendMB('menu-clicked-login', { page: currentUrl }) + onClick={() => { + sendMB('menu-click', { item: 'login', location: 'top-menu' }) }} > {t('log_in')} 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 030220abb4..02dac4c821 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 @@ -3,12 +3,15 @@ import type { 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' 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 NavDropdownMenu from '@/features/ui/components/bootstrap-5/navbar/nav-dropdown-menu' import ContactUsItem from '@/features/ui/components/bootstrap-5/navbar/contact-us-item' +import { + type ExtraSegmentations, + useSendProjectListMB, +} from '@/features/project-list/components/project-list-events' export default function NavDropdownFromData({ item, @@ -17,11 +20,24 @@ export default function NavDropdownFromData({ item: NavbarDropdownItemData showContactUsModal: (event?: Event) => void }) { + const sendProjectListMB = useSendProjectListMB() return ( - + { + if (nextShow) { + sendProjectListMB('menu-expand', { + item: item.trackingKey, + location: 'top-menu', + }) + } + }} + > ) @@ -30,24 +46,37 @@ export default function NavDropdownFromData({ export function NavDropdownMenuItems({ dropdown, showContactUsModal, + location, }: { dropdown: NavbarItemDropdownData showContactUsModal: (event?: Event) => void + location: ExtraSegmentations['menu-expand']['location'] }) { + const sendProjectListMB = useSendProjectListMB() return ( <> {dropdown.map((child, index) => { if ('divider' in child) { return } else if ('isContactUs' in child) { - return + return ( + + ) } else if (isDropdownLinkItem(child)) { return ( { - sendMB(child.event) + sendProjectListMB('menu-click', { + item: child.trackingKey as ExtraSegmentations['menu-click']['item'], + location, + destinationURL: child.url, + }) }} > {child.translatedText} diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-dropdown-menu.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-dropdown-menu.tsx index d98613aa9d..65eae92d9b 100644 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-dropdown-menu.tsx +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-dropdown-menu.tsx @@ -5,15 +5,17 @@ export default function NavDropdownMenu({ title, className, children, + onToggle, }: { title: string className?: string children: ReactNode + onToggle?: (nextShow: boolean) => void }) { // Can't use a NavDropdown here because it's impossible to render the menu as // a
      element using NavDropdown return ( - + {title} {children} diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-item-from-data.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-item-from-data.tsx index 2627ef2deb..a4dca0dcb8 100644 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-item-from-data.tsx +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/navbar/nav-item-from-data.tsx @@ -5,8 +5,8 @@ import { } from '@/features/ui/components/bootstrap-5/navbar/util' import NavDropdownFromData from '@/features/ui/components/bootstrap-5/navbar/nav-dropdown-from-data' import NavItem from '@/features/ui/components/bootstrap-5/navbar/nav-item' -import { sendMB } from '@/infrastructure/event-tracking' import NavLinkItem from '@/features/ui/components/bootstrap-5/navbar/nav-link-item' +import { useSendProjectListMB } from '@/features/project-list/components/project-list-events' export default function NavItemFromData({ item, @@ -15,6 +15,7 @@ export default function NavItemFromData({ item: NavbarItemData showContactUsModal: (event?: Event) => void }) { + const sendProjectListMB = useSendProjectListMB() if (isDropdownItem(item)) { return ( { - sendMB(item.event) + sendProjectListMB('menu-click', { + item: item.trackingKey as any, + location: 'top-menu', + destinationURL: item.url, + }) }} > {item.translatedText} diff --git a/services/web/frontend/js/features/ui/components/types/navbar.ts b/services/web/frontend/js/features/ui/components/types/navbar.ts index 2ab49e18a9..ff4e1829cf 100644 --- a/services/web/frontend/js/features/ui/components/types/navbar.ts +++ b/services/web/frontend/js/features/ui/components/types/navbar.ts @@ -14,7 +14,7 @@ export interface NavbarDropdownTextItem { export interface NavbarDropdownLinkItem extends NavbarDropdownTextItem { url: string - event: string + trackingKey: string eventSegmentation?: Record } @@ -37,11 +37,12 @@ export interface NavbarTextItemData { export interface NavbarDropdownItemData extends NavbarTextItemData { dropdown: NavbarItemDropdownData + trackingKey: 'help' | 'account' | 'features' | 'admin' } export interface NavbarLinkItemData extends NavbarTextItemData { url: string - event: string + trackingKey: string } export type NavbarItemData =