mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-25 10:10:08 +02:00
[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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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') || '{}'
|
||||
)
|
||||
|
||||
@@ -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<Nullable<NewProjectButtonModalVariant>>(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({
|
||||
<Dropdown
|
||||
className={classnames('new-project-dropdown', className)}
|
||||
onSelect={handleMainButtonClick}
|
||||
onToggle={nextShow => {
|
||||
if (nextShow) sendProjectListMB('new-project-expand', undefined)
|
||||
}}
|
||||
>
|
||||
<DropdownToggle
|
||||
id={id}
|
||||
@@ -217,9 +231,7 @@ function NewProjectButton({
|
||||
<DropdownItem
|
||||
key={`portal-template-${index}`}
|
||||
href={`${portalTemplate.url}#templates`}
|
||||
onClick={e =>
|
||||
handlePortalTemplateClick(e, portalTemplate.name)
|
||||
}
|
||||
onClick={e => handlePortalTemplateClick(e, portalTemplate)}
|
||||
aria-label={`${portalTemplate.name} ${t('template')}`}
|
||||
>
|
||||
{portalTemplate.name}
|
||||
@@ -241,9 +253,7 @@ function NewProjectButton({
|
||||
<li role="none" key={`new-project-button-template-${index}`}>
|
||||
<DropdownItem
|
||||
href={templateLink.url}
|
||||
onClick={e =>
|
||||
handleStaticTemplateClick(e, templateLink.trackingKey)
|
||||
}
|
||||
onClick={e => handleStaticTemplateClick(e, templateLink)}
|
||||
aria-label={`${templateLink.name} ${t('template')}`}
|
||||
>
|
||||
{templateLink.name === 'view_all'
|
||||
|
||||
@@ -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(
|
||||
<T extends keyof ExtraSegmentations>(
|
||||
event: T,
|
||||
payload: ExtraSegmentations[T]
|
||||
) =>
|
||||
sendMB(event, { ...payload, 'sidebar-navigation-ui-update': hasDsNav }),
|
||||
[hasDsNav]
|
||||
)
|
||||
}
|
||||
@@ -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 && (
|
||||
<Dropdown
|
||||
className="ds-nav-icon-dropdown"
|
||||
onToggle={show => setShowHelpDropdown(show)}
|
||||
onToggle={show => {
|
||||
setShowHelpDropdown(show)
|
||||
if (show) {
|
||||
sendMB('menu-expand', { item: 'help', location: 'sidebar' })
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Dropdown.Toggle role="menuitem" aria-label={t('help')}>
|
||||
<OLTooltip
|
||||
@@ -92,6 +99,7 @@ function SidebarDsNav() {
|
||||
<NavDropdownMenuItems
|
||||
dropdown={helpItem.dropdown}
|
||||
showContactUsModal={showContactUsModal}
|
||||
location="sidebar"
|
||||
/>
|
||||
</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
@@ -100,7 +108,15 @@ function SidebarDsNav() {
|
||||
<>
|
||||
<Dropdown
|
||||
className="ds-nav-icon-dropdown"
|
||||
onToggle={show => setShowAccountDropdown(show)}
|
||||
onToggle={show => {
|
||||
setShowAccountDropdown(show)
|
||||
if (show) {
|
||||
sendMB('menu-expand', {
|
||||
item: 'account',
|
||||
location: 'sidebar',
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Dropdown.Toggle role="menuitem" aria-label={t('Account')}>
|
||||
<OLTooltip
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { DefaultNavbarMetadata } from '@/features/ui/components/types/default-navbar-metadata'
|
||||
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 { useSendProjectListMB } from '@/features/project-list/components/project-list-events'
|
||||
|
||||
export default function AdminMenu({
|
||||
canDisplayAdminMenu,
|
||||
@@ -16,8 +17,20 @@ export default function AdminMenu({
|
||||
| 'canDisplaySurveyMenu'
|
||||
| 'adminUrl'
|
||||
>) {
|
||||
const sendProjectListMB = useSendProjectListMB()
|
||||
return (
|
||||
<NavDropdownMenu title="Admin" className="subdued">
|
||||
<NavDropdownMenu
|
||||
title="Admin"
|
||||
className="subdued"
|
||||
onToggle={nextShow => {
|
||||
if (nextShow) {
|
||||
sendProjectListMB('menu-expand', {
|
||||
item: 'admin',
|
||||
location: 'top-menu',
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
{canDisplayAdminMenu ? (
|
||||
<>
|
||||
<NavDropdownLinkItem href="/admin">Manage Site</NavDropdownLinkItem>
|
||||
|
||||
@@ -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 (
|
||||
<DropdownListItem>
|
||||
@@ -16,7 +22,7 @@ export default function ContactUsItem({
|
||||
as="button"
|
||||
role="menuitem"
|
||||
onClick={() => {
|
||||
sendMB('menu-clicked-contact')
|
||||
sendMB('menu-click', { item: 'contact', location })
|
||||
showModal()
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
) : (
|
||||
<LoggedOutItems
|
||||
showSignUpLink={showSignUpLink}
|
||||
currentUrl={currentUrl}
|
||||
/>
|
||||
<LoggedOutItems showSignUpLink={showSignUpLink} />
|
||||
)}
|
||||
</Nav>
|
||||
</Navbar.Collapse>
|
||||
|
||||
@@ -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 (
|
||||
<>
|
||||
<NavLinkItem href="/project" className="nav-item-projects">
|
||||
{t('projects')}
|
||||
</NavLinkItem>
|
||||
<NavDropdownMenu title={t('Account')} className="nav-item-account">
|
||||
<NavDropdownMenu
|
||||
title={t('Account')}
|
||||
className="nav-item-account"
|
||||
onToggle={nextShow => {
|
||||
if (nextShow) {
|
||||
sendProjectListMB('menu-expand', {
|
||||
item: 'account',
|
||||
location: 'top-menu',
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AccountMenuItems
|
||||
sessionUser={sessionUser}
|
||||
showSubscriptionLink={showSubscriptionLink}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import NavLinkItem from '@/features/ui/components/bootstrap-5/navbar/nav-link-item'
|
||||
import { sendMB } from '@/infrastructure/event-tracking'
|
||||
import { useSendProjectListMB } from '@/features/project-list/components/project-list-events'
|
||||
|
||||
export default function LoggedOutItems({
|
||||
showSignUpLink,
|
||||
currentUrl,
|
||||
}: {
|
||||
showSignUpLink: boolean
|
||||
currentUrl: string
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const sendMB = useSendProjectListMB()
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -17,8 +16,8 @@ export default function LoggedOutItems({
|
||||
<NavLinkItem
|
||||
href="/register"
|
||||
className="primary nav-account-item"
|
||||
onClick={e => {
|
||||
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({
|
||||
<NavLinkItem
|
||||
href="/login"
|
||||
className="nav-account-item"
|
||||
onClick={e => {
|
||||
sendMB('menu-clicked-login', { page: currentUrl })
|
||||
onClick={() => {
|
||||
sendMB('menu-click', { item: 'login', location: 'top-menu' })
|
||||
}}
|
||||
>
|
||||
{t('log_in')}
|
||||
|
||||
@@ -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 (
|
||||
<NavDropdownMenu title={item.translatedText} className={item.class}>
|
||||
<NavDropdownMenu
|
||||
title={item.translatedText}
|
||||
className={item.class}
|
||||
onToggle={nextShow => {
|
||||
if (nextShow) {
|
||||
sendProjectListMB('menu-expand', {
|
||||
item: item.trackingKey,
|
||||
location: 'top-menu',
|
||||
})
|
||||
}
|
||||
}}
|
||||
>
|
||||
<NavDropdownMenuItems
|
||||
dropdown={item.dropdown}
|
||||
showContactUsModal={showContactUsModal}
|
||||
location="top-menu"
|
||||
/>
|
||||
</NavDropdownMenu>
|
||||
)
|
||||
@@ -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 <NavDropdownDivider key={index} />
|
||||
} else if ('isContactUs' in child) {
|
||||
return <ContactUsItem key={index} showModal={showContactUsModal} />
|
||||
return (
|
||||
<ContactUsItem
|
||||
key={index}
|
||||
showModal={showContactUsModal}
|
||||
location={location}
|
||||
/>
|
||||
)
|
||||
} else if (isDropdownLinkItem(child)) {
|
||||
return (
|
||||
<NavDropdownLinkItem
|
||||
key={index}
|
||||
href={child.url}
|
||||
onClick={() => {
|
||||
sendMB(child.event)
|
||||
sendProjectListMB('menu-click', {
|
||||
item: child.trackingKey as ExtraSegmentations['menu-click']['item'],
|
||||
location,
|
||||
destinationURL: child.url,
|
||||
})
|
||||
}}
|
||||
>
|
||||
{child.translatedText}
|
||||
|
||||
@@ -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 <ul> element using NavDropdown
|
||||
return (
|
||||
<Dropdown as="li" role="none" className={className}>
|
||||
<Dropdown as="li" role="none" className={className} onToggle={onToggle}>
|
||||
<Dropdown.Toggle role="menuitem">{title}</Dropdown.Toggle>
|
||||
<Dropdown.Menu as="ul" role="menu" align="end">
|
||||
{children}
|
||||
|
||||
@@ -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 (
|
||||
<NavDropdownFromData
|
||||
@@ -28,7 +29,11 @@ export default function NavItemFromData({
|
||||
className={item.class}
|
||||
href={item.url}
|
||||
onClick={() => {
|
||||
sendMB(item.event)
|
||||
sendProjectListMB('menu-click', {
|
||||
item: item.trackingKey as any,
|
||||
location: 'top-menu',
|
||||
destinationURL: item.url,
|
||||
})
|
||||
}}
|
||||
>
|
||||
{item.translatedText}
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface NavbarDropdownTextItem {
|
||||
|
||||
export interface NavbarDropdownLinkItem extends NavbarDropdownTextItem {
|
||||
url: string
|
||||
event: string
|
||||
trackingKey: string
|
||||
eventSegmentation?: Record<string, any>
|
||||
}
|
||||
|
||||
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user