diff --git a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_FR.json index 8212ea263c1c..402faf3f0384 100644 --- a/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_FR.json +++ b/packages/manager/apps/zimbra/public/translations/accounts/alias/add/Messages_fr_FR.json @@ -8,6 +8,7 @@ "zimbra_account_alias_add_input_email_helper_rule_3": "Les caractères spéciaux ne peuvent pas être placés côte à côte", "zimbra_account_alias_add_select_domain_placeholder": "Sélectionner un nom de domaine", "zimbra_account_alias_add_btn_confirm": "Confirmer", + "zimbra_account_alias_add_btn_cancel": "Annuler", "zimbra_account_alias_add_success_message": "Votre demande de création d'alias a bien été prise en compte. Elle sera traitée d'ici quelques instants.", "zimbra_account_alias_add_error_message": "Votre demande de création d'alias n'a pas pu aboutir. {{ error }}" } diff --git a/packages/manager/apps/zimbra/public/translations/organizations/addAndEdit/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/organizations/addAndEdit/Messages_fr_FR.json index 8197f89240c7..ef7b0051bfeb 100644 --- a/packages/manager/apps/zimbra/public/translations/organizations/addAndEdit/Messages_fr_FR.json +++ b/packages/manager/apps/zimbra/public/translations/organizations/addAndEdit/Messages_fr_FR.json @@ -1,5 +1,6 @@ { "zimbra_organization_add": "Confirmer", + "zimbra_organization_add_cancel": "Annuler", "zimbra_organization_add_modal_title": "Ajouter une organisation", "zimbra_organization_add_modal_content_part1": "L'organisation représente un groupement logique de domaines et de boites mails.", "zimbra_organization_add_modal_content_part2": "Elle permet de définir des politiques de gestion groupées et définit l'isolation de vos boites mails (limite de l'annuaire d'entreprise).", diff --git a/packages/manager/apps/zimbra/public/translations/organizations/delete/Messages_fr_FR.json b/packages/manager/apps/zimbra/public/translations/organizations/delete/Messages_fr_FR.json index f1815a6c94be..922caf1d06ac 100644 --- a/packages/manager/apps/zimbra/public/translations/organizations/delete/Messages_fr_FR.json +++ b/packages/manager/apps/zimbra/public/translations/organizations/delete/Messages_fr_FR.json @@ -1,5 +1,6 @@ { "zimbra_organization_delete": "Supprimer", + "zimbra_organization_delete_cancel": "Annuler", "zimbra_organization_delete_modal_title": "Supprimer l'organisation", "zimbra_organization_delete_modal_content": "Voulez-vous vraiment supprimer l'organisation ?", "zimbra_organization_delete_modal_message_disabled_part1": "Au moins un domaine est encore associé à cette organisation.", diff --git a/packages/manager/apps/zimbra/src/components/GuideLink.tsx b/packages/manager/apps/zimbra/src/components/GuideLink.tsx index 1c252dd82142..dae6d1b1c485 100644 --- a/packages/manager/apps/zimbra/src/components/GuideLink.tsx +++ b/packages/manager/apps/zimbra/src/components/GuideLink.tsx @@ -1,4 +1,9 @@ -import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { + ButtonType, + PageLocation, + ShellContext, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import React, { useContext, useMemo } from 'react'; import { IconLinkAlignmentType, @@ -7,24 +12,20 @@ import { } from '@ovh-ux/manager-react-components'; import { ODS_LINK_COLOR } from '@ovhcloud/ods-components'; import { Guide } from '@/guides.constants'; +import { GO_TO } from '@/tracking.constant'; interface GuideLinkProps { label: string; - guide: string | Guide; + guide: Guide; } export default function GuideLink({ label, guide }: Readonly) { const context = useContext(ShellContext); const { ovhSubsidiary } = context.environment.getUser(); + const { trackClick } = useOvhTracking(); const url = useMemo(() => { - if (typeof guide === 'string') { - return guide; - } - - return (typeof guide.url === 'string' - ? guide.url - : guide.url?.[ovhSubsidiary] || guide.url.DEFAULT) as string; + return guide.url?.[ovhSubsidiary] || guide.url.DEFAULT; }, [guide, ovhSubsidiary]); return ( @@ -35,6 +36,14 @@ export default function GuideLink({ label, guide }: Readonly) { target="_blank" href={url} label={label} + onClickReturn={() => { + trackClick({ + location: PageLocation.tile, + buttonType: ButtonType.externalLink, + actionType: 'navigation', + actions: [GO_TO(guide.tracking)], + }); + }} /> ); } diff --git a/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/Dashboard.tsx b/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/Dashboard.tsx index 6a026a732e0f..07b428816de8 100644 --- a/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/Dashboard.tsx +++ b/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/Dashboard.tsx @@ -15,16 +15,31 @@ import { } from '@ovh-ux/manager-react-components'; import { useTranslation } from 'react-i18next'; -import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { + ButtonType, + PageLocation, + ShellContext, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import TabsPanel, { TabItemProps } from './TabsPanel'; import Breadcrumb from '@/components/Breadcrumb/Breadcrumb'; import { GUIDES_LIST } from '@/guides.constants'; import { urls } from '@/routes/routes.constants'; - -import './Dashboard.scss'; import { FEATURE_FLAGS } from '@/utils'; +import { + AUTO_REPLY, + EMAIL_ACCOUNT, + DOMAIN, + GENERAL_INFORMATIONS, + MAILING_LIST, + ORGANIZATION, + REDIRECTION, + GO_TO, +} from '@/tracking.constant'; +import './Dashboard.scss'; export const Dashboard: React.FC = () => { + const { trackClick } = useOvhTracking(); const { platformId } = useParams(); const { notifications } = useNotifications(); const { t } = useTranslation('dashboard'); @@ -36,10 +51,18 @@ export const Dashboard: React.FC = () => { const guideItems: GuideItem[] = [ { id: 1, - href: `${GUIDES_LIST.administrator_guide.url[ovhSubsidiary] || - GUIDES_LIST.administrator_guide.url.DEFAULT}`, + href: (GUIDES_LIST.administrator_guide.url[ovhSubsidiary] || + GUIDES_LIST.administrator_guide.url.DEFAULT) as string, target: '_blank', label: t('zimbra_dashboard_administrator_guide'), + onClick: () => { + trackClick({ + location: PageLocation.tile, + buttonType: ButtonType.externalLink, + actionType: 'navigation', + actions: [GO_TO(GUIDES_LIST.administrator_guide.tracking)], + }); + }, }, ]; @@ -53,12 +76,14 @@ export const Dashboard: React.FC = () => { const tabsList: TabItemProps[] = [ { name: 'general_informations', + trackingName: GENERAL_INFORMATIONS, title: t('zimbra_dashboard_general_informations'), to: basePath, pathMatchers: computePathMatchers([urls.dashboard]), }, { - name: 'organizations', + name: 'organization', + trackingName: ORGANIZATION, title: t('zimbra_dashboard_organizations'), to: `${basePath}/organizations`, pathMatchers: computePathMatchers([ @@ -68,7 +93,8 @@ export const Dashboard: React.FC = () => { hidden: selectedOrganizationId !== null, }, { - name: 'domains', + name: 'domain', + trackingName: DOMAIN, title: t('zimbra_dashboard_domains'), to: `${basePath}/domains`, pathMatchers: computePathMatchers([ @@ -79,13 +105,15 @@ export const Dashboard: React.FC = () => { ]), }, { - name: 'email_accounts', + name: 'email_account', + trackingName: EMAIL_ACCOUNT, title: t('zimbra_dashboard_email_accounts'), to: `${basePath}/email_accounts`, pathMatchers: computePathMatchers([urls.email_accounts]), }, { - name: 'mailing_lists', + name: 'mailing_list', + trackingName: MAILING_LIST, title: t('zimbra_dashboard_mailing_lists'), to: `${basePath}/mailing_lists`, pathMatchers: computePathMatchers([ @@ -95,7 +123,8 @@ export const Dashboard: React.FC = () => { hidden: !FEATURE_FLAGS.MAILINGLISTS, }, { - name: 'redirections', + name: 'redirection', + trackingName: REDIRECTION, title: t('zimbra_dashboard_redirections'), to: `${basePath}/redirections`, pathMatchers: computePathMatchers([ @@ -106,7 +135,8 @@ export const Dashboard: React.FC = () => { hidden: !FEATURE_FLAGS.REDIRECTIONS, }, { - name: 'auto_replies', + name: 'auto_reply', + trackingName: AUTO_REPLY, title: t('zimbra_dashboard_auto_replies'), to: `${basePath}/auto_replies`, pathMatchers: computePathMatchers([urls.auto_replies]), diff --git a/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/TabsPanel.tsx b/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/TabsPanel.tsx index a9217150fac3..a339bcb7da04 100644 --- a/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/TabsPanel.tsx +++ b/packages/manager/apps/zimbra/src/components/layout-helpers/Dashboard/TabsPanel.tsx @@ -3,10 +3,17 @@ import { NavLink, useLocation, useNavigate } from 'react-router-dom'; import { OdsTabs, OdsTab, OdsTag } from '@ovhcloud/ods-components/react'; import { Headers } from '@ovh-ux/manager-react-components'; import { ODS_TAG_COLOR, ODS_TAG_SIZE } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useOverridePage, useOrganization } from '@/hooks'; +import { UNSELECT_ORGANIZATION } from '@/tracking.constant'; export type TabItemProps = { name: string; + trackingName: string; title: string; pathMatchers?: RegExp[]; to: string; @@ -21,6 +28,8 @@ const TabsPanel: React.FC = ({ tabs }) => { const [activePanel, setActivePanel] = useState(''); const location = useLocation(); const navigate = useNavigate(); + + const { trackClick } = useOvhTracking(); const { data: organization } = useOrganization(); const isOverriddedPage = useOverridePage(); @@ -50,7 +59,15 @@ const TabsPanel: React.FC = ({ tabs }) => { navigate(location.pathname)} + onClick={() => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [UNSELECT_ORGANIZATION], + }); + navigate(location.pathname); + }} className="ml-4" size={ODS_TAG_SIZE.lg} label={organization.currentState.label} @@ -71,6 +88,14 @@ const TabsPanel: React.FC = ({ tabs }) => { : tab.to } className="no-underline" + onClick={() => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.tab, + actionType: 'navigation', + actions: [tab.trackingName], + }); + }} > { - const context = await initShellContext(appName); + const context = await initShellContext(appName, trackingContext); await initI18n({ context, diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/ActionButtonAutoReply.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/ActionButtonAutoReply.component.tsx index 751c09e657ef..d0fbddf5034d 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/ActionButtonAutoReply.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/ActionButtonAutoReply.component.tsx @@ -6,10 +6,19 @@ import { ODS_BUTTON_VARIANT, ODS_ICON_NAME, } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { AutoRepliesItem } from './AutoReplies'; import { useGenerateUrl, usePlatform } from '@/hooks'; import { IAM_ACTIONS } from '@/utils/iamAction.constants'; import { ResourceStatus } from '@/api/api.type'; +import { + ADD_AUTO_REPLY, + EMAIL_ACCOUNT_DELETE_AUTO_REPLY, +} from '@/tracking.constant'; interface ActionButtonAutoReplyProps { autoReplyItem: AutoRepliesItem; @@ -18,18 +27,31 @@ interface ActionButtonAutoReplyProps { const ActionButtonAutoReply: React.FC = ({ autoReplyItem, }) => { + const { trackClick } = useOvhTracking(); const { platformUrn } = usePlatform(); const navigate = useNavigate(); const [searchParams] = useSearchParams(); const params = Object.fromEntries(searchParams.entries()); + const editEmailAccountId = searchParams.get('editEmailAccountId'); const hrefDeleteAutoReply = useGenerateUrl('./delete', 'href', { deleteAutoReplyId: autoReplyItem.id, ...params, }); - const handleDeleteClick = () => navigate(hrefDeleteAutoReply); + const handleDeleteClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ + editEmailAccountId ? EMAIL_ACCOUNT_DELETE_AUTO_REPLY : ADD_AUTO_REPLY, + ], + }); + + navigate(hrefDeleteAutoReply); + }; return ( navigate(goBackUrl); + const onClose = () => navigate(goBackUrl); const [form, setForm] = useState({ ...{ @@ -246,6 +263,10 @@ export default function AddAutoReply() { return Promise.resolve(payload); }, onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: trackingName, + }); addSuccess( {t('zimbra_auto_replies_add_success_message')} @@ -254,6 +275,10 @@ export default function AddAutoReply() { ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: trackingName, + }); addError( {t('zimbra_auto_replies_add_error_message', { @@ -267,19 +292,43 @@ export default function AddAutoReply() { /* queryClient.invalidateQueries({ queryKey: getZimbraPlatformMailingListsQueryKey(platformId), }); */ - goBack(); + onClose(); }, }); const handleSavelick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CONFIRM], + }); addAutoReply(getDataBody(form)); }; + const handleCancelClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CANCEL], + }); + onClose(); + }; + return (
{ + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.link, + actionType: 'navigation', + actions: [trackingName, BACK_PREVIOUS_PAGE], + }); + }} iconAlignment={IconLinkAlignmentType.left} label={t('zimbra_auto_replies_add_cta_back')} /> @@ -516,7 +565,7 @@ export default function AddAutoReply() { > [] = [ ]; export function AutoReplies() { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('autoReplies'); const { platformUrn } = usePlatform(); const navigate = useNavigate(); @@ -85,7 +95,18 @@ export function AutoReplies() { const params = Object.fromEntries(searchParams.entries()); const editEmailAccountId = searchParams.get('editEmailAccountId'); const hrefAddAutoReply = useGenerateUrl('./add', 'href', params); - const handleAddClick = () => navigate(hrefAddAutoReply); + const handleAddClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ + editEmailAccountId ? EMAIL_ACCOUNT_ADD_AUTO_REPLY : ADD_AUTO_REPLY, + ], + }); + + navigate(hrefAddAutoReply); + }; const location = useLocation(); const shouldHide = useMemo(() => location?.pathname?.endsWith('add'), [ diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/ModalDeleteAutoReply.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/ModalDeleteAutoReply.component.tsx index d5a83f1ee7e6..0bb9b7443168 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/ModalDeleteAutoReply.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/AutoReplies/ModalDeleteAutoReply.component.tsx @@ -10,10 +10,23 @@ import { ODS_MODAL_COLOR, ODS_TEXT_PRESET, } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useGenerateUrl } from '@/hooks'; import Modal from '@/components/Modals/Modal'; +import { + CANCEL, + CONFIRM, + DELETE_AUTO_REPLY, + EMAIL_ACCOUNT_DELETE_AUTO_REPLY, +} from '@/tracking.constant'; export default function ModalDeleteAutoReply() { + const { trackClick, trackPage } = useOvhTracking(); const { t } = useTranslation('autoReplies/delete'); const navigate = useNavigate(); @@ -22,6 +35,11 @@ export default function ModalDeleteAutoReply() { delete params.deleteAutoReplyId; const deleteAutoReplyId = searchParams.get('deleteAutoReplyId'); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + + const trackingName = editEmailAccountId + ? EMAIL_ACCOUNT_DELETE_AUTO_REPLY + : DELETE_AUTO_REPLY; const { addError, addSuccess } = useNotifications(); @@ -34,6 +52,10 @@ export default function ModalDeleteAutoReply() { return Promise.resolve(autoReplyId); }, onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: trackingName, + }); addSuccess( {t('zimbra_auto_replies_delete_success_message')} @@ -42,6 +64,10 @@ export default function ModalDeleteAutoReply() { ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: trackingName, + }); addError( {t('zimbra_auto_replies_delete_error_message', { @@ -61,9 +87,25 @@ export default function ModalDeleteAutoReply() { }); const handleDeleteClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CONFIRM], + }); deleteAutoReply(deleteAutoReplyId); }; + const handleCancelClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CANCEL], + }); + onClose(); + }; + return ( = ({ }) => { const { t } = useTranslation('domains'); const navigate = useNavigate(); + const { trackClick } = useOvhTracking(); const { platformUrn } = usePlatform(); const hrefDeleteDomain = useGenerateUrl('./delete', 'path', { @@ -23,6 +30,12 @@ const ActionButtonDomain: React.FC = ({ }); const handleDeleteDomainClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [DELETE_DOMAIN], + }); navigate(hrefDeleteDomain); }; @@ -31,6 +44,12 @@ const ActionButtonDomain: React.FC = ({ }); const handleEditDomainClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [EDIT_DOMAIN], + }); navigate(hrefEditDomain); }; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.page.tsx index b5bbc99f6d04..1feec2dcf66c 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.page.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/AddDomain.page.tsx @@ -40,6 +40,12 @@ import { } from '@ovhcloud/ods-components'; import { useMutation, useQuery } from '@tanstack/react-query'; import { ApiError } from '@ovh-ux/manager-core-api'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useOrganization, useOrganizationList, @@ -58,11 +64,12 @@ import { GUIDES_LIST } from '@/guides.constants'; import { DomainType } from '@/api/domain/type'; import { DNS_CONFIG_TYPE, DnsRecordType, FEATURE_FLAGS } from '@/utils'; import GuideLink from '@/components/GuideLink'; +import { ADD_DOMAIN, CONFIRM, BACK_PREVIOUS_PAGE } from '@/tracking.constant'; export default function AddDomain() { const { t } = useTranslation('domains/addDomain'); const navigate = useNavigate(); - + const { trackClick, trackPage } = useOvhTracking(); const { addError, addSuccess } = useNotifications(); const { platformId } = usePlatform(); @@ -171,6 +178,10 @@ export default function AddDomain() { return postZimbraDomain(platformId, params); }, onSuccess: (domain: DomainType) => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: ADD_DOMAIN, + }); addSuccess( {t('zimbra_domains_add_domain_success_message')} @@ -182,6 +193,10 @@ export default function AddDomain() { } }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: ADD_DOMAIN, + }); addError( {t('zimbra_domains_add_domain_error_message', { @@ -206,6 +221,12 @@ export default function AddDomain() { name: selectedDomainName, autoConfigureMX: selectedRadioDomain !== 'externalDomain', }; + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [ADD_DOMAIN, CONFIRM], + }); addDomain(formData); }; @@ -222,6 +243,14 @@ export default function AddDomain() { iconAlignment={IconLinkAlignmentType.left} type={LinkType.back} href={backLinkUrl} + onClickReturn={() => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ADD_DOMAIN, BACK_PREVIOUS_PAGE], + }); + }} color={ODS_LINK_COLOR.primary} label={t('zimbra_domains_add_domain_cta_back')} /> diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/Domains.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/Domains.tsx index 2c4861347451..9c2363c7eeba 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/Domains.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/Domains.tsx @@ -14,6 +14,11 @@ import { ManagerButton, } from '@ovh-ux/manager-react-components'; import { Outlet, useNavigate } from 'react-router-dom'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useOverridePage, useDomains, @@ -34,6 +39,7 @@ import Loading from '@/components/Loading/Loading'; import { DiagnosticBadge } from '@/components/DiagnosticBadge'; import { DomainType } from '@/api/domain/type'; import { AccountStatistics, ResourceStatus } from '@/api/api.type'; +import { ADD_DOMAIN } from '@/tracking.constant'; export type DomainsItem = { id: string; @@ -105,6 +111,7 @@ const columns: DatagridColumn[] = [ export default function Domains() { const { t } = useTranslation('domains'); + const { trackClick } = useOvhTracking(); const { platformUrn } = usePlatform(); const navigate = useNavigate(); const isOverridedPage = useOverridePage(); @@ -128,6 +135,12 @@ export default function Domains() { const hrefAddDomain = useGenerateUrl('./add', 'path'); const handleAddDomainClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ADD_DOMAIN], + }); navigate(hrefAddDomain); }; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.component.tsx index 8eaf6dad91a6..f92cd441a4db 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Domains/ModalDeleteDomain.component.tsx @@ -11,6 +11,12 @@ import { OdsMessage, OdsText } from '@ovhcloud/ods-components/react'; import { useNotifications } from '@ovh-ux/manager-react-components'; import { ApiError } from '@ovh-ux/manager-core-api'; import { useMutation } from '@tanstack/react-query'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useAccountList, useGenerateUrl, usePlatform } from '@/hooks'; import { deleteZimbraPlatformDomain, @@ -18,11 +24,12 @@ import { } from '@/api/domain'; import Modal from '@/components/Modals/Modal'; import queryClient from '@/queryClient'; +import { CANCEL, CONFIRM, DELETE_DOMAIN } from '@/tracking.constant'; export default function ModalDeleteDomain() { const { t } = useTranslation('domains/delete'); const navigate = useNavigate(); - + const { trackClick, trackPage } = useOvhTracking(); const [searchParams] = useSearchParams(); const deleteDomainId = searchParams.get('deleteDomainId'); @@ -34,13 +41,17 @@ export default function ModalDeleteDomain() { const { addError, addSuccess } = useNotifications(); const goBackUrl = useGenerateUrl('..', 'path'); - const goBack = () => navigate(goBackUrl); + const onClose = () => navigate(goBackUrl); const { mutate: deleteDomain, isPending: isSending } = useMutation({ mutationFn: (domainId: string) => { return deleteZimbraPlatformDomain(platformId, domainId); }, onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: DELETE_DOMAIN, + }); addSuccess( {t('zimbra_domain_delete_success_message')} @@ -49,6 +60,10 @@ export default function ModalDeleteDomain() { ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: DELETE_DOMAIN, + }); addError( {t('zimbra_domain_delete_error_message', { @@ -63,22 +78,42 @@ export default function ModalDeleteDomain() { queryKey: getZimbraPlatformDomainsQueryKey(platformId), }); - goBack(); + onClose(); }, }); const handleDeleteClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [DELETE_DOMAIN, CONFIRM], + }); deleteDomain(deleteDomainId); }; + const handleCancelClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [DELETE_DOMAIN, CANCEL], + }); + onClose(); + }; + return ( navigate(goBackUrl); + const onClose = () => navigate(goBackUrl); - const { mutate: handleEditDomain, isPending: isSending } = useMutation({ - mutationFn: () => + const { mutate: editDomain, isPending: isSending } = useMutation({ + mutationFn: (organization: string) => putZimbraDomain(platformId, detailDomain.id, { - organizationId: selectedOrganization, + organizationId: organization, }), onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: EDIT_DOMAIN, + }); addSuccess( {t('zimbra_domain_edit_success_message')} @@ -67,6 +77,10 @@ export default function ModalEditDomain() { ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: EDIT_DOMAIN, + }); addError( {t('zimbra_domain_edit_error_message', { @@ -81,10 +95,30 @@ export default function ModalEditDomain() { queryKey: getZimbraPlatformDomainsQueryKey(platformId), }); - goBack(); + onClose(); }, }); + const handleCancelClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [EDIT_DOMAIN, CANCEL], + }); + onClose(); + }; + + const handleConfirmClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [EDIT_DOMAIN, CONFIRM], + }); + editDomain(selectedOrganization); + }; + useEffect(() => { if (detailDomain && organizationsList) { setSelectedOrganization(detailDomain.currentState.organizationId); @@ -95,14 +129,13 @@ export default function ModalEditDomain() { @@ -121,7 +154,7 @@ export default function ModalEditDomain() { = ({ tabs }) => { + const { trackClick } = useOvhTracking(); const [activePanel, setActivePanel] = useState(''); const location = useLocation(); const navigate = useNavigate(); @@ -48,6 +55,14 @@ export const AccountTabsPanel: React.FC = ({ tabs }) => { key={`osds-tab-bar-item-${tab.name}`} to={tab.to} className="no-underline" + onClick={() => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.tab, + actionType: 'navigation', + actions: [tab.trackingName], + }); + }} > = ({ aliasItem, }) => { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('accounts/alias'); const { platformUrn } = usePlatform(); const navigate = useNavigate(); @@ -27,6 +34,12 @@ const ActionButtonAlias: React.FC = ({ }); const handleDeleteAliasClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [EMAIL_ACCOUNT_DELETE_ALIAS], + }); navigate(hrefDeleteAlias); }; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.component.tsx index 9af2d0dd14de..afb3c081d8c5 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ActionButtonEmail.component.tsx @@ -3,10 +3,16 @@ import { useTranslation } from 'react-i18next'; import { ActionMenu } from '@ovh-ux/manager-react-components'; import { useNavigate } from 'react-router-dom'; import { ODS_BUTTON_COLOR, ODS_BUTTON_VARIANT } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { EmailsItem } from './EmailAccounts'; import { useGenerateUrl, usePlatform } from '@/hooks'; import { IAM_ACTIONS } from '@/utils/iamAction.constants'; import { ResourceStatus } from '@/api/api.type'; +import { DELETE_EMAIL_ACCOUNT, EDIT_EMAIL_ACCOUNT } from '@/tracking.constant'; interface ActionButtonEmailAccountProps { emailsItem: EmailsItem; @@ -15,6 +21,7 @@ interface ActionButtonEmailAccountProps { const ActionButtonEmail: React.FC = ({ emailsItem, }) => { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('accounts'); const { platformUrn } = usePlatform(); const navigate = useNavigate(); @@ -24,6 +31,12 @@ const ActionButtonEmail: React.FC = ({ }); const handleEditEmailClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [EDIT_EMAIL_ACCOUNT], + }); navigate(hrefEditEmailAccount); }; @@ -32,6 +45,12 @@ const ActionButtonEmail: React.FC = ({ }); const handleDeleteEmailClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [DELETE_EMAIL_ACCOUNT], + }); navigate(hrefDeleteEmailAccount); }; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page.tsx index 88c2c2c718a5..4858ae7f44b8 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page.tsx @@ -7,6 +7,11 @@ import { } from '@ovh-ux/manager-react-components'; import { useTranslation } from 'react-i18next'; import { useLocation, useSearchParams } from 'react-router-dom'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useDomains, useGenerateUrl, usePlatform, useAccount } from '@/hooks'; import Loading from '@/components/Loading/Loading'; import { TabItemProps, AccountTabsPanel } from './AccountTabsPanel.component'; @@ -16,8 +21,17 @@ import EmailAccountsAlias from './EmailAccountsAlias.page'; import Redirections from '../Redirections/Redirections'; import { FEATURE_FLAGS } from '@/utils'; import AutoReplies from '../AutoReplies/AutoReplies'; +import { + ADD_EMAIL_ACCOUNT, + BACK_PREVIOUS_PAGE, + EDIT_EMAIL_ACCOUNT, + EMAIL_ACCOUNT_ALIAS, + EMAIL_ACCOUNT_AUTO_REPLY, + EMAIL_ACCOUNT_REDIRECTION, +} from '@/tracking.constant'; export default function AddAndEditAccount() { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('accounts/addAndEdit'); const location = useLocation(); const { platformId } = usePlatform(); @@ -95,12 +109,14 @@ export default function AddAndEditAccount() { const tabsList: TabItemProps[] = [ { name: 'settings', + trackingName: EDIT_EMAIL_ACCOUNT, title: t('zimbra_account_edit_tabs_settings'), to: hrefSettings, pathMatchers: pathMatcherSettingsTabs, }, { name: 'alias', + trackingName: EMAIL_ACCOUNT_ALIAS, title: t('zimbra_account_edit_tabs_alias'), to: hrefAlias, pathMatchers: pathMatcherAliasTabs, @@ -108,6 +124,7 @@ export default function AddAndEditAccount() { }, { name: 'redirections', + trackingName: EMAIL_ACCOUNT_REDIRECTION, title: t('zimbra_account_edit_tabs_redirections'), to: hrefRedirections, pathMatchers: pathMatcherRedirectionsTabs, @@ -115,6 +132,7 @@ export default function AddAndEditAccount() { }, { name: 'auto_replies', + trackingName: EMAIL_ACCOUNT_AUTO_REPLY, title: t('zimbra_account_edit_tabs_auto_replies'), to: hrefAutoReplies, pathMatchers: pathMatcherAutoRepliesTabs, @@ -135,6 +153,17 @@ export default function AddAndEditAccount() { iconAlignment={IconLinkAlignmentType.left} type={LinkType.back} href={goBackUrl} + onClickReturn={() => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.link, + actionType: 'navigation', + actions: [ + editEmailAccountId ? EDIT_EMAIL_ACCOUNT : ADD_EMAIL_ACCOUNT, + BACK_PREVIOUS_PAGE, + ], + }); + }} label={t('zimbra_account_add_cta_back')} /> diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountSettings.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountSettings.page.tsx index 046f9d65cc27..456b91082839 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountSettings.page.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountSettings.page.tsx @@ -21,6 +21,12 @@ import { } from '@ovhcloud/ods-components'; import { ApiError } from '@ovh-ux/manager-core-api'; import { useMutation } from '@tanstack/react-query'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useGenerateUrl, usePlatform } from '@/hooks'; import { AccountBodyParamsType, @@ -38,6 +44,12 @@ import { PASSWORD_REGEX, } from '@/utils'; import queryClient from '@/queryClient'; +import { + ADD_EMAIL_ACCOUNT, + CANCEL, + CONFIRM, + EDIT_EMAIL_ACCOUNT, +} from '@/tracking.constant'; export default function EmailAccountSettings({ domainList = [], @@ -46,19 +58,23 @@ export default function EmailAccountSettings({ domainList: DomainType[]; editAccountDetail: AccountType; }>) { + const { trackClick, trackPage } = useOvhTracking(); const { t } = useTranslation('accounts/addAndEdit'); const navigate = useNavigate(); const { addError, addSuccess } = useNotifications(); const { platformId } = usePlatform(); const [searchParams] = useSearchParams(); const editEmailAccountId = searchParams.get('editEmailAccountId'); + const trackingName = editAccountDetail + ? EDIT_EMAIL_ACCOUNT + : ADD_EMAIL_ACCOUNT; const [isFormValid, setIsFormValid] = useState(false); const [selectedDomainOrganization, setSelectedDomainOrganization] = useState( '', ); const goBackUrl = useGenerateUrl('..', 'path'); - const goBack = () => { + const onClose = () => { return navigate(goBackUrl); }; @@ -168,6 +184,10 @@ export default function EmailAccountSettings({ : postZimbraPlatformAccount(platformId, params); }, onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: trackingName, + }); addSuccess( {t( @@ -180,6 +200,10 @@ export default function EmailAccountSettings({ ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: trackingName, + }); addError( {t( @@ -198,11 +222,18 @@ export default function EmailAccountSettings({ queryClient.invalidateQueries({ queryKey: getZimbraPlatformAccountsQueryKey(platformId), }); - goBack(); + onClose(); }, }); const handleSaveClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CONFIRM], + }); + const { account: { value: account }, domain: { value: domain }, @@ -225,6 +256,16 @@ export default function EmailAccountSettings({ addOrEditEmailAccount(dataBody); }; + const handleCancelClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CANCEL], + }); + onClose(); + }; + return (
@@ -447,7 +488,7 @@ export default function EmailAccountSettings({ {editAccountDetail && ( [] = [ export default function EmailAccounts() { const { t } = useTranslation(['accounts', 'dashboard']); + const { trackClick } = useOvhTracking(); const navigate = useNavigate(); const { data: platform, platformUrn } = usePlatform(); const { data: organisation } = useOrganization(); @@ -135,15 +145,27 @@ export default function EmailAccounts() { : platform?.currentState?.accountsStatistics; }, [organisation, platform]); - const webmailUrl = guidesConstants.GUIDES_LIST.webmail.url; + const webmailUrl = GUIDES_LIST.webmail.url.DEFAULT; const hrefAddEmailAccount = useGenerateUrl('./add', 'path'); const hrefOrderEmailAccount = useGenerateUrl('./order', 'href'); const handleAddEmailAccountClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ADD_EMAIL_ACCOUNT], + }); navigate(hrefAddEmailAccount); }; const handleOrderEmailAccountClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ORDER_ZIMBRA_EMAIL_ACCOUNT], + }); navigate(hrefOrderEmailAccount); }; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsAlias.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsAlias.page.tsx index 421852706a70..f906c35e0a2d 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsAlias.page.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsAlias.page.tsx @@ -15,6 +15,11 @@ import { import { useTranslation } from 'react-i18next'; import { useQuery } from '@tanstack/react-query'; import { Outlet, useNavigate, useSearchParams } from 'react-router-dom'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { AliasType, getZimbraPlatformAlias, @@ -26,6 +31,7 @@ import { BadgeStatus } from '@/components/BadgeStatus'; import { IAM_ACTIONS } from '@/utils/iamAction.constants'; import { ResourceStatus } from '@/api/api.type'; import Loading from '@/components/Loading/Loading'; +import { EMAIL_ACCOUNT_ADD_ALIAS } from '@/tracking.constant'; export type AliasItem = { id: string; @@ -34,6 +40,7 @@ export type AliasItem = { }; export default function EmailAccountsAlias() { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('accounts/alias'); const navigate = useNavigate(); const [searchParams] = useSearchParams(); @@ -69,6 +76,12 @@ export default function EmailAccountsAlias() { const hrefAddAlias = useGenerateUrl('./add', 'href', params); const handleAddAliasClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [EMAIL_ACCOUNT_ADD_ALIAS], + }); navigate(hrefAddAlias); }; const items: AliasItem[] = diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsOrder.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsOrder.page.tsx index aec746d0192b..d9f7e25a8d73 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsOrder.page.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/EmailAccountsOrder.page.tsx @@ -27,7 +27,12 @@ import { ODS_ICON_NAME, ODS_TEXT_PRESET, } from '@ovhcloud/ods-components'; -import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { + ButtonType, + PageLocation, + ShellContext, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { getExpressOrderURL } from '@ovh-ux/manager-module-order'; import Loading from '@/components/Loading/Loading'; import { useOrderCatalog } from '@/hooks/useOrderCatalog'; @@ -43,6 +48,11 @@ import { FormTypeInterface, } from '@/utils'; import { usePlatform } from '@/hooks'; +import { + CANCEL, + CONFIRM, + ORDER_ZIMBRA_EMAIL_ACCOUNT, +} from '@/tracking.constant'; type OrderGeneratedTileProps = { orderURL: string; @@ -103,6 +113,7 @@ function OrderCatalogForm({ locale, orderBaseURL, }: Readonly) { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('accounts/order'); const { platformId } = usePlatform(); const [orderURL, setOrderURL] = useState(''); @@ -166,6 +177,12 @@ function OrderCatalogForm({ }; const handleConfirm = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [ORDER_ZIMBRA_EMAIL_ACCOUNT, CONFIRM, form.commitment.value], + }); const products = Object.entries(form) .filter(([key]) => whitelistedPlanCodes.includes(key as ZimbraPlanCodes)) .map(([key, { value }]) => { @@ -305,6 +322,7 @@ function OrderCatalogForm({ } export default function EmailAccountsOrder() { + const { trackClick } = useOvhTracking(); const { addError } = useNotifications(); const { t } = useTranslation('accounts/order'); const context = useContext(ShellContext); @@ -317,6 +335,12 @@ export default function EmailAccountsOrder() { const navigate = useNavigate(); const goBack = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [ORDER_ZIMBRA_EMAIL_ACCOUNT, CANCEL], + }); navigate('..'); }; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalAddAlias.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalAddAlias.component.tsx index dcae1bb43483..eb3240bea4f8 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalAddAlias.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalAddAlias.component.tsx @@ -17,6 +17,12 @@ import { import { useNotifications } from '@ovh-ux/manager-react-components'; import { useMutation } from '@tanstack/react-query'; import { ApiError } from '@ovh-ux/manager-core-api'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useDomains, useGenerateUrl, usePlatform, useAccount } from '@/hooks'; import Modal from '@/components/Modals/Modal'; import { @@ -30,8 +36,10 @@ import { FormTypeInterface, } from '@/utils'; import queryClient from '@/queryClient'; +import { CANCEL, CONFIRM, EMAIL_ACCOUNT_ADD_ALIAS } from '@/tracking.constant'; export default function ModalAddAndEditOrganization() { + const { trackClick, trackPage } = useOvhTracking(); const { t } = useTranslation('accounts/alias/add'); const { platformId } = usePlatform(); const [searchParams] = useSearchParams(); @@ -41,7 +49,7 @@ export default function ModalAddAndEditOrganization() { const { addError, addSuccess } = useNotifications(); const navigate = useNavigate(); const goBackUrl = useGenerateUrl('..', 'path', params); - const goBack = () => navigate(goBackUrl); + const onClose = () => navigate(goBackUrl); const [form, setForm] = useState({ alias: { @@ -76,7 +84,7 @@ export default function ModalAddAndEditOrganization() { } }, [isLoadingDomain, isLoadingEmailDetail]); - const { mutate: handleNewAliasClick, isPending: isSubmitting } = useMutation({ + const { mutate: addAlias, isPending: isSubmitting } = useMutation({ mutationFn: () => { const { alias: { value: alias }, @@ -91,6 +99,10 @@ export default function ModalAddAndEditOrganization() { return postZimbraPlatformAlias(platformId, dataBody); }, onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: EMAIL_ACCOUNT_ADD_ALIAS, + }); addSuccess( {t('zimbra_account_alias_add_success_message')} @@ -99,6 +111,10 @@ export default function ModalAddAndEditOrganization() { ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: EMAIL_ACCOUNT_ADD_ALIAS, + }); addError( {t('zimbra_account_alias_add_error_message', { @@ -112,7 +128,7 @@ export default function ModalAddAndEditOrganization() { queryClient.invalidateQueries({ queryKey: getZimbraPlatformAliasQueryKey(platformId), }); - goBack(); + onClose(); }, }); @@ -128,21 +144,47 @@ export default function ModalAddAndEditOrganization() { setIsFormValid(checkValidityForm(form)); }; + const handleConfirmClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [EMAIL_ACCOUNT_ADD_ALIAS, CONFIRM], + }); + + addAlias(); + }; + + const handleCancelClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [EMAIL_ACCOUNT_ADD_ALIAS, CANCEL], + }); + + onClose(); + }; + return ( <> diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteAlias.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteAlias.component.tsx index f728a644f40d..133b1119bb4a 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteAlias.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/EmailAccounts/ModalDeleteAlias.component.tsx @@ -11,6 +11,12 @@ import { ODS_MODAL_COLOR, ODS_TEXT_PRESET, } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useGenerateUrl, usePlatform } from '@/hooks'; import Modal from '@/components/Modals/Modal'; import { @@ -18,8 +24,14 @@ import { getZimbraPlatformAliasQueryKey, } from '@/api/alias'; import queryClient from '@/queryClient'; +import { + CANCEL, + CONFIRM, + EMAIL_ACCOUNT_DELETE_ALIAS, +} from '@/tracking.constant'; export default function ModalDeleteDomain() { + const { trackClick, trackPage } = useOvhTracking(); const { t } = useTranslation('accounts/alias/delete'); const navigate = useNavigate(); @@ -33,11 +45,15 @@ export default function ModalDeleteDomain() { const { addError, addSuccess } = useNotifications(); const goBackUrl = useGenerateUrl('..', 'path', params); - const goBack = () => navigate(goBackUrl); + const onClose = () => navigate(goBackUrl); - const { mutate: handleDeleteClick, isPending: isDeleting } = useMutation({ + const { mutate: deleteAlias, isPending: isDeleting } = useMutation({ mutationFn: () => deleteZimbraPlatformAlias(platformId, deleteAliasId), onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: EMAIL_ACCOUNT_DELETE_ALIAS, + }); addSuccess( {t('zimbra_account_alias_delete_success_message')} @@ -46,6 +62,10 @@ export default function ModalDeleteDomain() { ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: EMAIL_ACCOUNT_DELETE_ALIAS, + }); addError( {t('zimbra_account_alias_delete_error_message', { @@ -59,20 +79,40 @@ export default function ModalDeleteDomain() { queryClient.invalidateQueries({ queryKey: getZimbraPlatformAliasQueryKey(platformId), }); - goBack(); + onClose(); }, }); + const handleDeleteClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [EMAIL_ACCOUNT_DELETE_ALIAS, CONFIRM], + }); + deleteAlias(); + }; + + const handleCancelClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [EMAIL_ACCOUNT_DELETE_ALIAS, CANCEL], + }); + onClose(); + }; + return ( navigate(goBackUrl); + const onClose = () => navigate(goBackUrl); const [step, setStep] = useState(1); const { data, isLoading } = useAccount({ accountId: deleteEmailAccountId }); @@ -38,6 +46,10 @@ export default function ModalDeleteEmailAccount() { return deleteZimbraPlatformAccount(platformId, emailAccountId); }, onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: DELETE_EMAIL_ACCOUNT, + }); addSuccess( {t('zimbra_account_delete_success_message')} @@ -46,6 +58,10 @@ export default function ModalDeleteEmailAccount() { ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: DELETE_EMAIL_ACCOUNT, + }); addError( {t('zimbra_account_delete_error_message', { @@ -60,25 +76,41 @@ export default function ModalDeleteEmailAccount() { queryKey: getZimbraPlatformAccountsQueryKey(platformId), }); - goBack(); + onClose(); }, }); const handleDeleteClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [DELETE_EMAIL_ACCOUNT, CONFIRM], + }); deleteEmailAccount(deleteEmailAccountId); }; + const handleCancelClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [DELETE_EMAIL_ACCOUNT, CANCEL], + }); + onClose(); + }; + return ( = { zimbra_dashboard_webmail: GUIDES_LIST.webmail, zimbra_dashboard_administrator_guide: GUIDES_LIST.administrator_guide, zimbra_dashboard_user_guides: GUIDES_LIST.user_guide, diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/ActionButtonMailingList.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/ActionButtonMailingList.component.tsx index 17573264ec17..131497bd251f 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/ActionButtonMailingList.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/ActionButtonMailingList.component.tsx @@ -3,10 +3,21 @@ import { useTranslation } from 'react-i18next'; import { ActionMenu } from '@ovh-ux/manager-react-components'; import { useNavigate } from 'react-router-dom'; import { ODS_BUTTON_COLOR, ODS_BUTTON_VARIANT } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useGenerateUrl, usePlatform } from '@/hooks'; import { IAM_ACTIONS } from '@/utils/iamAction.constants'; import { MailingListItem } from './MailingLists'; import { ResourceStatus } from '@/api/api.type'; +import { + CONFIGURE_DELEGATION_MAILING_LIST, + DEFINE_MEMBERS_MAILING_LIST, + DELETE_MAILING_LIST, + EDIT_MAILING_LIST, +} from '@/tracking.constant'; interface ActionButtonMailingListProps { mailingListItem: MailingListItem; @@ -15,6 +26,7 @@ interface ActionButtonMailingListProps { const ActionButtonMailingList: React.FC = ({ mailingListItem, }) => { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('mailinglists'); const { platformUrn } = usePlatform(); const navigate = useNavigate(); @@ -24,6 +36,12 @@ const ActionButtonMailingList: React.FC = ({ }); const handleDeleteMailingListClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [DELETE_MAILING_LIST], + }); navigate(hrefDeleteMailingList); }; @@ -32,6 +50,12 @@ const ActionButtonMailingList: React.FC = ({ }); const handleEditMailingListClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [EDIT_MAILING_LIST], + }); navigate(hrefEditMailingList); }; @@ -44,6 +68,12 @@ const ActionButtonMailingList: React.FC = ({ ); const handleDefineMembersMailingListClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [DEFINE_MEMBERS_MAILING_LIST], + }); navigate(hrefDefineMembersMailingList); }; @@ -56,6 +86,12 @@ const ActionButtonMailingList: React.FC = ({ ); const handleDefineConfigureDelegationMailingList = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [CONFIGURE_DELEGATION_MAILING_LIST], + }); navigate(hrefConfigureDelegationMailingList); }; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/AddAndEditMailingList.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/AddAndEditMailingList.page.tsx index 9f475dcc95a2..fa5c1ece443f 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/AddAndEditMailingList.page.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/AddAndEditMailingList.page.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; +import { useLocation, useSearchParams } from 'react-router-dom'; import { IconLinkAlignmentType, Links, @@ -8,6 +8,11 @@ import { Subtitle, } from '@ovh-ux/manager-react-components'; import { ODS_LINK_COLOR } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useDomains, useGenerateUrl, @@ -16,19 +21,22 @@ import { } from '@/hooks'; import Loading from '@/components/Loading/Loading'; import MailingListSettings from './MailingListSettings.page'; +import { + ADD_MAILING_LIST, + BACK_PREVIOUS_PAGE, + EDIT_MAILING_LIST, +} from '@/tracking.constant'; export default function AddAndEditMailingList() { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('mailinglists/addAndEdit'); const location = useLocation(); - const navigate = useNavigate(); const { platformId } = usePlatform(); const [searchParams] = useSearchParams(); const editMailingListId = searchParams.get('editMailingListId'); const [isLoading, setIsLoading] = useState(true); const goBackUrl = useGenerateUrl('..', 'path'); - const goBack = () => navigate(goBackUrl); - const { data: editMailingListDetail, isLoading: isLoadingMailingListDetailRequest, @@ -63,7 +71,18 @@ export default function AddAndEditMailingList() { data-testid="back-btn" type={LinkType.back} iconAlignment={IconLinkAlignmentType.left} - onClickReturn={goBack} + href={goBackUrl} + onClickReturn={() => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.link, + actionType: 'navigation', + actions: [ + editMailingListId ? EDIT_MAILING_LIST : ADD_MAILING_LIST, + BACK_PREVIOUS_PAGE, + ], + }); + }} color={ODS_LINK_COLOR.primary} label={t('zimbra_mailinglist_add_cta_back')} /> diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingListSettings.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingListSettings.page.tsx index 2ee393ac85c6..a37464ed45f6 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingListSettings.page.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingListSettings.page.tsx @@ -23,6 +23,12 @@ import { } from '@ovhcloud/ods-components'; import { ApiError } from '@ovh-ux/manager-core-api'; import { useMutation } from '@tanstack/react-query'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useGenerateUrl, usePlatform } from '@/hooks'; import { postZimbraPlatformMailingList, @@ -42,6 +48,12 @@ import { OWNER_REGEX, } from '@/utils'; import queryClient from '@/queryClient'; +import { + ADD_MAILING_LIST, + CANCEL, + CONFIRM, + EDIT_MAILING_LIST, +} from '@/tracking.constant'; const replyToChoices = [ { @@ -83,6 +95,7 @@ export default function MailingListSettings({ domainList: DomainType[]; editMailingListDetail: MailingListType; }>) { + const { trackClick, trackPage } = useOvhTracking(); const { t } = useTranslation('mailinglists/addAndEdit'); const navigate = useNavigate(); const { addError, addSuccess } = useNotifications(); @@ -90,15 +103,14 @@ export default function MailingListSettings({ const [searchParams] = useSearchParams(); const editMailingListId = searchParams.get('editMailingListId'); const organizationIdParam = searchParams.get('organizationId'); + const trackingName = editMailingListId ? EDIT_MAILING_LIST : ADD_MAILING_LIST; const [isFormValid, setIsFormValid] = useState(false); const [selectedDomainOrganization, setSelectedDomainOrganization] = useState( '', ); const goBackUrl = useGenerateUrl('..', 'path'); - const goBack = () => { - return navigate(goBackUrl); - }; + const goBack = () => navigate(goBackUrl); const [form, setForm] = useState({ ...{ @@ -219,6 +231,10 @@ export default function MailingListSettings({ : postZimbraPlatformMailingList(platformId, params); }, onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: trackingName, + }); addSuccess( {t( @@ -231,6 +247,10 @@ export default function MailingListSettings({ ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: trackingName, + }); addError( {t( @@ -254,9 +274,25 @@ export default function MailingListSettings({ }); const handleSavelick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CONFIRM], + }); addOrEditMailingList(getDataBody(form)); }; + const handleCancelClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CANCEL], + }); + goBack(); + }; + return (
@@ -467,7 +503,7 @@ export default function MailingListSettings({ {editMailingListId && ( diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingLists.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingLists.tsx index 879f696e7a57..23dd880f64e7 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingLists.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/MailingLists/MailingLists.tsx @@ -13,6 +13,11 @@ import { DatagridColumn, ManagerButton, } from '@ovh-ux/manager-react-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { usePlatform, useGenerateUrl, @@ -26,6 +31,7 @@ import { ResourceStatus } from '@/api/api.type'; import { MailingListType } from '@/api/mailinglist'; import { DATAGRID_REFRESH_INTERVAL, DATAGRID_REFRESH_ON_MOUNT } from '@/utils'; import Loading from '@/components/Loading/Loading'; +import { ADD_MAILING_LIST } from '@/tracking.constant'; export type MailingListItem = { id: string; @@ -111,6 +117,7 @@ export const getMailingListItems = ( }; export default function MailingLists() { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('mailinglists'); const navigate = useNavigate(); const { platformUrn, data: platformData } = usePlatform(); @@ -125,6 +132,12 @@ export default function MailingLists() { const hrefAddMailingList = useGenerateUrl('./add', 'path'); const handleAddMailingListClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ADD_MAILING_LIST], + }); navigate(hrefAddMailingList); }; // this will need to be updated diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ActionButtonOrganization.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ActionButtonOrganization.component.tsx index b550627d4b9c..4ad950dfc9f1 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ActionButtonOrganization.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ActionButtonOrganization.component.tsx @@ -3,10 +3,16 @@ import { useTranslation } from 'react-i18next'; import { ActionMenu } from '@ovh-ux/manager-react-components'; import { useNavigate } from 'react-router-dom'; import { ODS_BUTTON_COLOR, ODS_BUTTON_VARIANT } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { OrganizationItem } from './Organizations'; import { useGenerateUrl, usePlatform } from '@/hooks'; import { IAM_ACTIONS } from '@/utils/iamAction.constants'; import { ResourceStatus } from '@/api/api.type'; +import { DELETE_ORGANIZATION, EDIT_ORGANIZATION } from '@/tracking.constant'; interface ActionButtonOrganizationProps { organizationItem: OrganizationItem; @@ -16,6 +22,7 @@ const ActionButtonOrganization: React.FC = ({ organizationItem, }) => { const { t } = useTranslation('organizations'); + const { trackClick } = useOvhTracking(); const { platformUrn } = usePlatform(); const navigate = useNavigate(); @@ -24,6 +31,12 @@ const ActionButtonOrganization: React.FC = ({ }); const handleDeleteOrganizationClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [DELETE_ORGANIZATION], + }); navigate(hrefDeleteOrganization); }; @@ -32,6 +45,12 @@ const ActionButtonOrganization: React.FC = ({ }); const handleEditOrganizationClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [EDIT_ORGANIZATION], + }); navigate(hrefEditOrganization); }; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/IdLink.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/IdLink.tsx index 07aa06107a54..e31afa78601f 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/IdLink.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/IdLink.tsx @@ -1,9 +1,14 @@ import React from 'react'; import { OdsLink } from '@ovhcloud/ods-components/react'; -import { useNavigate } from 'react-router-dom'; import { ODS_LINK_COLOR } from '@ovhcloud/ods-components'; import { IconLinkAlignmentType } from '@ovh-ux/manager-react-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useGenerateUrl } from '@/hooks'; +import { SELECT_ORGANIZATION } from '@/tracking.constant'; interface IdLinkProps { id: string; @@ -11,13 +16,18 @@ interface IdLinkProps { } const IdLink: React.FC = ({ id, label }) => { - const navigate = useNavigate(); + const { trackClick } = useOvhTracking(); const url = useGenerateUrl('..', 'href', { organizationId: id, }); const handleLinkClick = () => { - navigate(url); + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [SELECT_ORGANIZATION], + }); }; return ( diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.page.tsx index 303ce204ce89..f23d70d41690 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.page.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalAddAndEditOrganization.page.tsx @@ -18,6 +18,12 @@ import { import { useNotifications } from '@ovh-ux/manager-react-components'; import { useMutation } from '@tanstack/react-query'; import { ApiError } from '@ovh-ux/manager-core-api'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useGenerateUrl, useOrganization, usePlatform } from '@/hooks'; import Modal from '@/components/Modals/Modal'; import { @@ -32,12 +38,22 @@ import { checkValidityForm, FormTypeInterface, } from '@/utils'; +import { + ADD_ORGANIZATION, + CANCEL, + CONFIRM, + EDIT_ORGANIZATION, +} from '@/tracking.constant'; export default function ModalAddAndEditOrganization() { const { t } = useTranslation('organizations/addAndEdit'); + const { trackClick, trackPage } = useOvhTracking(); const { platformId } = usePlatform(); const [searchParams] = useSearchParams(); const editOrganizationId = searchParams?.get('editOrganizationId'); + const trackingName = editOrganizationId + ? EDIT_ORGANIZATION + : ADD_ORGANIZATION; const { addError, addSuccess } = useNotifications(); const navigate = useNavigate(); const goBackUrl = useGenerateUrl('..', 'path'); @@ -79,6 +95,10 @@ export default function ModalAddAndEditOrganization() { : postZimbraPlatformOrganization(platformId, params); }, onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: trackingName, + }); addSuccess( {t( @@ -91,6 +111,10 @@ export default function ModalAddAndEditOrganization() { ); }, onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: trackingName, + }); addError( {t( @@ -118,9 +142,26 @@ export default function ModalAddAndEditOrganization() { name: { value: name }, label: { value: label }, } = form; + + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CONFIRM], + }); addOrEditOrganization({ name, label }); }; + const handleCancelClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CANCEL], + }); + onClose(); + }; + const handleFormChange = (name: string, value: string) => { const newForm: FormTypeInterface = form; newForm[name] = { @@ -156,6 +197,10 @@ export default function ModalAddAndEditOrganization() { onClose={onClose} isDismissible isLoading={isLoading} + secondaryButton={{ + label: t('zimbra_organization_add_cancel'), + action: handleCancelClick, + }} primaryButton={{ testid: 'confirm-btn', variant: ODS_BUTTON_VARIANT.default, diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.component.tsx index 5814667dc811..b1705dff5f7f 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Organizations/ModalDeleteOrganization.component.tsx @@ -12,6 +12,12 @@ import { OdsMessage, OdsText } from '@ovhcloud/ods-components/react'; import { useNotifications } from '@ovh-ux/manager-react-components'; import { useMutation } from '@tanstack/react-query'; import { ApiError } from '@ovh-ux/manager-core-api'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { useDomains, usePlatform } from '@/hooks'; import { deleteZimbraPlatformOrganization, @@ -19,9 +25,11 @@ import { } from '@/api/organization'; import Modal from '@/components/Modals/Modal'; import queryClient from '@/queryClient'; +import { CANCEL, CONFIRM, DELETE_ORGANIZATION } from '@/tracking.constant'; export default function ModalDeleteOrganization() { const [searchParams] = useSearchParams(); + const { trackClick, trackPage } = useOvhTracking(); const deleteOrganizationId = searchParams.get('deleteOrganizationId'); const { t } = useTranslation('organizations/delete'); const { platformId } = usePlatform(); @@ -38,6 +46,10 @@ export default function ModalDeleteOrganization() { mutationFn: (organizationId: string) => deleteZimbraPlatformOrganization(platformId, organizationId), onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: DELETE_ORGANIZATION, + }); addSuccess( {t('zimbra_organization_delete_success_message')} @@ -45,8 +57,11 @@ export default function ModalDeleteOrganization() { true, ); }, - onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: DELETE_ORGANIZATION, + }); addError( {t('zimbra_organization_delete_error_message', { @@ -66,9 +81,25 @@ export default function ModalDeleteOrganization() { }); const handleDeleteClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [DELETE_ORGANIZATION, CONFIRM], + }); deleteOrganization(deleteOrganizationId); }; + const handleCancelClick = () => { + trackClick({ + location: PageLocation.popup, + buttonType: ButtonType.button, + actionType: 'action', + actions: [DELETE_ORGANIZATION, CANCEL], + }); + onClose(); + }; + return ( [] = [ export default function Organizations() { const { t } = useTranslation('organizations'); + const { trackClick } = useOvhTracking(); const navigate = useNavigate(); const { platformUrn } = usePlatform(); const { @@ -97,6 +103,12 @@ export default function Organizations() { const hrefAddOrganization = useGenerateUrl('./add', 'path'); const handleOrganizationClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ADD_ORGANIZATION], + }); navigate(hrefAddOrganization); }; diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ActionButtonRedirections.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ActionButtonRedirections.component.tsx index d07e8071508f..cb803a1b5823 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ActionButtonRedirections.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ActionButtonRedirections.component.tsx @@ -3,11 +3,22 @@ import { useTranslation } from 'react-i18next'; import { ActionMenu } from '@ovh-ux/manager-react-components'; import { useNavigate, useSearchParams } from 'react-router-dom'; import { ODS_BUTTON_COLOR, ODS_BUTTON_VARIANT } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import { RedirectionsItem } from './Redirections'; import { useGenerateUrl, usePlatform } from '@/hooks'; import { IAM_ACTIONS } from '@/utils/iamAction.constants'; import { ResourceStatus } from '@/api/api.type'; import { FEATURE_FLAGS } from '@/utils'; +import { + DELETE_REDIRECTION, + EDIT_REDIRECTION, + EMAIL_ACCOUNT_DELETE_REDIRECTION, + EMAIL_ACCOUNT_EDIT_REDIRECTION, +} from '@/tracking.constant'; interface ActionButtonRedirectionsAccountProps { redirectionsItem: RedirectionsItem; @@ -16,12 +27,14 @@ interface ActionButtonRedirectionsAccountProps { const ActionButtonRedirections: React.FC = ({ redirectionsItem, }) => { + const { trackClick } = useOvhTracking(); const { t } = useTranslation('redirections'); const { platformUrn } = usePlatform(); const navigate = useNavigate(); const [searchParams] = useSearchParams(); const params = Object.fromEntries(searchParams.entries()); + const editEmailAccountId = searchParams.get('editEmailAccountId'); const hrefEditRedirections = useGenerateUrl('./edit', 'path', { editRedirectionId: redirectionsItem.id, @@ -29,6 +42,14 @@ const ActionButtonRedirections: React.FC = }); const handleEditRedirectionsClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ + editEmailAccountId ? EMAIL_ACCOUNT_EDIT_REDIRECTION : EDIT_REDIRECTION, + ], + }); navigate(hrefEditRedirections); }; @@ -37,6 +58,16 @@ const ActionButtonRedirections: React.FC = ...params, }); const handleDeleteRedirectionsClick = () => { + trackClick({ + location: PageLocation.datagrid, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [ + editEmailAccountId + ? EMAIL_ACCOUNT_DELETE_REDIRECTION + : DELETE_REDIRECTION, + ], + }); navigate(hrefDeleteRedirections); }; const actionItems = [ diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalAddAndEditRedirections.page.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalAddAndEditRedirections.page.tsx index 6f6f5ec93b4c..40d637f70ffc 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalAddAndEditRedirections.page.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalAddAndEditRedirections.page.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { useNavigate, useSearchParams } from 'react-router-dom'; import { OdsCheckbox, @@ -15,6 +15,14 @@ import { ODS_TEXT_PRESET, } from '@ovhcloud/ods-components'; import { useNotifications } from '@ovh-ux/manager-react-components'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; +import { ApiError } from '@ovh-ux/manager-core-api'; +import { useMutation } from '@tanstack/react-query'; import Modal from '@/components/Modals/Modal'; import { useAccount, useDomains, useGenerateUrl } from '@/hooks'; import { @@ -25,8 +33,17 @@ import { EMAIL_REGEX, } from '@/utils'; import Loading from '@/components/Loading/Loading'; +import { + ADD_REDIRECTION, + CANCEL, + CONFIRM, + EDIT_REDIRECTION, + EMAIL_ACCOUNT_ADD_REDIRECTION, + EMAIL_ACCOUNT_EDIT_REDIRECTION, +} from '@/tracking.constant'; export default function ModalAddAndEditRedirections() { + const { trackClick, trackPage } = useOvhTracking(); const { t } = useTranslation('redirections/addAndEdit'); const navigate = useNavigate(); @@ -36,6 +53,15 @@ export default function ModalAddAndEditRedirections() { const params = Object.fromEntries(searchParams.entries()); delete params.editRedirectionId; + const trackingName = useMemo(() => { + if (editEmailAccountId) { + return editRedirectionId + ? EMAIL_ACCOUNT_EDIT_REDIRECTION + : EMAIL_ACCOUNT_ADD_REDIRECTION; + } + return editRedirectionId ? EDIT_REDIRECTION : ADD_REDIRECTION; + }, [editRedirectionId, editEmailAccountId]); + const goBackUrl = useGenerateUrl('..', 'path', params); const onClose = () => navigate(goBackUrl); @@ -123,24 +149,64 @@ export default function ModalAddAndEditRedirections() { [form], ); */ - const handleClickConfirm = () => { - if (isFormValid) { + const { mutate: addRedirection, isPending: isSending } = useMutation({ + mutationFn: () => { + return Promise.resolve(); + }, + onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: trackingName, + }); addSuccess( - t( - editRedirectionId - ? 'zimbra_redirections_edit_success' - : 'zimbra_redirections_add_success', - ), + + {t('zimbra_redirection_add_success_message')} + , + true, ); - } else { + }, + onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: trackingName, + }); addError( - t( - editRedirectionId - ? 'zimbra_redirections_edit_error' - : 'zimbra_redirections_add_error', - ), + + {t('zimbra_redirection_add_error_message', { + error: error?.response?.data?.message, + })} + , + true, ); - } + }, + onSettled: () => { + /* queryClient.invalidateQueries({ + queryKey: getZimbraPlatformRedirectionsQueryKey(platformId), + }); */ + + onClose(); + }, + }); + + const handleClickConfirm = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CONFIRM], + }); + + addRedirection(); + }; + + const handleCancelClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CANCEL], + }); + onClose(); }; @@ -158,7 +224,7 @@ export default function ModalAddAndEditRedirections() { secondaryButton={{ testid: 'cancel-btn', label: t('zimbra_redirections_add_btn_cancel'), - action: onClose, + action: handleCancelClick, }} primaryButton={{ testid: 'confirm-btn', @@ -166,6 +232,7 @@ export default function ModalAddAndEditRedirections() { label: t('zimbra_redirections_add_btn_confirm'), action: handleClickConfirm, isDisabled: !isFormValid, + isLoading: isSending, }} isLoading={isLoadingDomain || isLoadingAccount} > diff --git a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalDeleteRedirections.component.tsx b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalDeleteRedirections.component.tsx index 1a06dc490fbf..0fbd20b6ad25 100644 --- a/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalDeleteRedirections.component.tsx +++ b/packages/manager/apps/zimbra/src/pages/dashboard/Redirections/ModalDeleteRedirections.component.tsx @@ -7,36 +7,120 @@ import { ODS_MODAL_COLOR, ODS_TEXT_PRESET, } from '@ovhcloud/ods-components'; +import { + ButtonType, + PageLocation, + PageType, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; +import { useMutation } from '@tanstack/react-query'; +import { useNotifications } from '@ovh-ux/manager-react-components'; +import { ApiError } from '@ovh-ux/manager-core-api'; import Modal from '@/components/Modals/Modal'; import { useGenerateUrl } from '@/hooks'; +import { + CANCEL, + CONFIRM, + DELETE_REDIRECTION, + EMAIL_ACCOUNT_DELETE_REDIRECTION, +} from '@/tracking.constant'; export default function ModalDeleteRedirections() { + const { trackClick, trackPage } = useOvhTracking(); const { t } = useTranslation('redirections/delete'); const navigate = useNavigate(); + const { addSuccess, addError } = useNotifications(); const [searchParams] = useSearchParams(); const params = Object.fromEntries(searchParams.entries()); delete params.deleteRedirectionId; + const deleteRedirectionId = searchParams.get('deleteRedirectionId'); + const editEmailAccountId = searchParams.get('editEmailAccountId'); + + const trackingName = editEmailAccountId + ? EMAIL_ACCOUNT_DELETE_REDIRECTION + : DELETE_REDIRECTION; + const goBackUrl = useGenerateUrl('..', 'path', params); - const goBack = () => navigate(goBackUrl); + const onClose = () => navigate(goBackUrl); + + const { mutate: deleteRedirection, isPending: isSending } = useMutation({ + mutationFn: (redirectionId: string) => { + return Promise.resolve(redirectionId); + }, + onSuccess: () => { + trackPage({ + pageType: PageType.bannerSuccess, + pageName: trackingName, + }); + addSuccess( + + {t('zimbra_domain_delete_success_message')} + , + true, + ); + }, + onError: (error: ApiError) => { + trackPage({ + pageType: PageType.bannerError, + pageName: trackingName, + }); + addError( + + {t('zimbra_domain_delete_error_message', { + error: error?.response?.data?.message, + })} + , + true, + ); + }, + onSettled: () => { + /* queryClient.invalidateQueries({ + queryKey: getZimbraPlatformRedirectionsQueryKey(platformId), + }); */ + + onClose(); + }, + }); + + const handleConfirmClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CONFIRM], + }); + deleteRedirection(deleteRedirectionId); + }; + + const handleCancelClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'action', + actions: [trackingName, CANCEL], + }); + onClose(); + }; return ( diff --git a/packages/manager/apps/zimbra/src/pages/onboarding/index.tsx b/packages/manager/apps/zimbra/src/pages/onboarding/index.tsx index b4520423d6d6..db8e7dac1460 100644 --- a/packages/manager/apps/zimbra/src/pages/onboarding/index.tsx +++ b/packages/manager/apps/zimbra/src/pages/onboarding/index.tsx @@ -1,15 +1,29 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { OnboardingLayout } from '@ovh-ux/manager-react-components'; +import { + ButtonType, + PageLocation, + useOvhTracking, +} from '@ovh-ux/manager-react-shell-client'; import onboardingImgSrc from './onboarding-img.png'; +import { JOIN_ZIMBRA_BETA } from '@/tracking.constant'; export default function Onboarding() { const { t } = useTranslation('onboarding'); const title: string = t('title'); const description: string = t('description'); + const { trackClick } = useOvhTracking(); const onOrderButtonClick = () => { + trackClick({ + location: PageLocation.page, + buttonType: ButtonType.button, + actionType: 'navigation', + actions: [JOIN_ZIMBRA_BETA], + }); + window.open( 'https://labs.ovhcloud.com/en/zimbra-beta/', '_blank', diff --git a/packages/manager/apps/zimbra/src/routes/routes.tsx b/packages/manager/apps/zimbra/src/routes/routes.tsx index 30d1dfa86346..a34b0ce96a26 100644 --- a/packages/manager/apps/zimbra/src/routes/routes.tsx +++ b/packages/manager/apps/zimbra/src/routes/routes.tsx @@ -1,6 +1,44 @@ import React from 'react'; import { RouteObject } from 'react-router-dom'; +import { PageType } from '@ovh-ux/manager-react-shell-client'; import NotFound from '@/pages/404'; +import { + ADD_AUTO_REPLY, + ADD_DOMAIN, + ADD_EMAIL_ACCOUNT, + ADD_MAILING_LIST, + ADD_ORGANIZATION, + ADD_REDIRECTION, + AUTO_REPLY, + DELETE_AUTO_REPLY, + DELETE_DOMAIN, + DELETE_EMAIL_ACCOUNT, + DELETE_ORGANIZATION, + DELETE_REDIRECTION, + DOMAIN, + EDIT_DOMAIN, + EDIT_EMAIL_ACCOUNT, + EDIT_MAILING_LIST, + EDIT_ORGANIZATION, + EDIT_REDIRECTION, + EMAIL_ACCOUNT, + EMAIL_ACCOUNT_ADD_ALIAS, + EMAIL_ACCOUNT_ADD_AUTO_REPLY, + EMAIL_ACCOUNT_ADD_REDIRECTION, + EMAIL_ACCOUNT_ALIAS, + EMAIL_ACCOUNT_AUTO_REPLY, + EMAIL_ACCOUNT_DELETE_ALIAS, + EMAIL_ACCOUNT_DELETE_AUTO_REPLY, + EMAIL_ACCOUNT_DELETE_REDIRECTION, + EMAIL_ACCOUNT_EDIT_REDIRECTION, + EMAIL_ACCOUNT_REDIRECTION, + GENERAL_INFORMATIONS, + MAILING_LIST, + ONBOARDING, + ORDER_ZIMBRA_EMAIL_ACCOUNT, + ORGANIZATION, + REDIRECTION, +} from '@/tracking.constant'; const lazyRouteConfig = (importFn: CallableFunction): Partial => { return { @@ -28,12 +66,24 @@ export const Routes: any = [ ...lazyRouteConfig(() => import('@/pages/dashboard/GeneralInformation/GeneralInformation'), ), + handle: { + tracking: { + pageName: GENERAL_INFORMATIONS, + pageType: PageType.dashboard, + }, + }, }, { path: 'organizations', ...lazyRouteConfig(() => import('@/pages/dashboard/Organizations/Organizations'), ), + handle: { + tracking: { + pageName: ORGANIZATION, + pageType: PageType.listing, + }, + }, children: [ { path: 'add', @@ -42,6 +92,12 @@ export const Routes: any = [ '@/pages/dashboard/Organizations/ModalAddAndEditOrganization.page' ), ), + handle: { + tracking: { + pageName: ADD_ORGANIZATION, + pageType: PageType.popup, + }, + }, }, { path: 'edit', @@ -50,6 +106,12 @@ export const Routes: any = [ '@/pages/dashboard/Organizations/ModalAddAndEditOrganization.page' ), ), + handle: { + tracking: { + pageName: EDIT_ORGANIZATION, + pageType: PageType.popup, + }, + }, }, { path: 'delete', @@ -58,6 +120,12 @@ export const Routes: any = [ '@/pages/dashboard/Organizations/ModalDeleteOrganization.component' ), ), + handle: { + tracking: { + pageName: DELETE_ORGANIZATION, + pageType: PageType.popup, + }, + }, }, ], }, @@ -66,19 +134,37 @@ export const Routes: any = [ ...lazyRouteConfig(() => import('@/pages/dashboard/Domains/Domains'), ), + handle: { + tracking: { + pageName: DOMAIN, + pageType: PageType.listing, + }, + }, children: [ { path: 'add', ...lazyRouteConfig(() => import('@/pages/dashboard/Domains/AddDomain.page'), ), - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: ADD_DOMAIN, + pageType: PageType.funnel, + }, + }, }, { path: 'edit', ...lazyRouteConfig(() => import('@/pages/dashboard/Domains/ModalEditDomain.component'), ), + handle: { + tracking: { + pageName: EDIT_DOMAIN, + pageType: PageType.funnel, + }, + }, }, { path: 'delete', @@ -87,6 +173,12 @@ export const Routes: any = [ '@/pages/dashboard/Domains/ModalDeleteDomain.component' ), ), + handle: { + tracking: { + pageName: DELETE_DOMAIN, + pageType: PageType.funnel, + }, + }, }, { path: 'diagnostic', @@ -103,6 +195,12 @@ export const Routes: any = [ ...lazyRouteConfig(() => import('@/pages/dashboard/EmailAccounts/EmailAccounts'), ), + handle: { + tracking: { + pageName: EMAIL_ACCOUNT, + pageType: PageType.listing, + }, + }, children: [ { path: 'add', @@ -111,7 +209,13 @@ export const Routes: any = [ '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page' ), ), - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: ADD_EMAIL_ACCOUNT, + pageType: PageType.funnel, + }, + }, }, { path: 'settings', @@ -120,7 +224,13 @@ export const Routes: any = [ '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page' ), ), - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: EDIT_EMAIL_ACCOUNT, + pageType: PageType.funnel, + }, + }, }, { path: 'alias', @@ -129,7 +239,13 @@ export const Routes: any = [ '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page' ), ), - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: EMAIL_ACCOUNT_ALIAS, + pageType: PageType.listing, + }, + }, children: [ { path: 'add', @@ -138,6 +254,12 @@ export const Routes: any = [ '@/pages/dashboard/EmailAccounts/ModalAddAlias.component' ), ), + handle: { + tracking: { + pageName: EMAIL_ACCOUNT_ADD_ALIAS, + pageType: PageType.popup, + }, + }, }, { path: 'delete', @@ -146,6 +268,12 @@ export const Routes: any = [ '@/pages/dashboard/EmailAccounts/ModalDeleteAlias.component' ), ), + handle: { + tracking: { + pageName: EMAIL_ACCOUNT_DELETE_ALIAS, + pageType: PageType.popup, + }, + }, }, ], }, @@ -156,7 +284,13 @@ export const Routes: any = [ '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page' ), ), - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: EMAIL_ACCOUNT_REDIRECTION, + pageType: PageType.listing, + }, + }, children: [ { path: 'add', @@ -165,6 +299,12 @@ export const Routes: any = [ '@/pages/dashboard/Redirections/ModalAddAndEditRedirections.page' ), ), + handle: { + tracking: { + pageName: EMAIL_ACCOUNT_ADD_REDIRECTION, + pageType: PageType.popup, + }, + }, }, { path: 'edit', @@ -173,6 +313,12 @@ export const Routes: any = [ '@/pages/dashboard/Redirections/ModalAddAndEditRedirections.page' ), ), + handle: { + tracking: { + pageName: EMAIL_ACCOUNT_EDIT_REDIRECTION, + pageType: PageType.popup, + }, + }, }, { path: 'delete', @@ -181,12 +327,24 @@ export const Routes: any = [ '@/pages/dashboard/Redirections/ModalDeleteRedirections.component' ), ), + handle: { + tracking: { + pageName: EMAIL_ACCOUNT_DELETE_REDIRECTION, + pageType: PageType.popup, + }, + }, }, ], }, { path: 'auto_replies', - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: EMAIL_ACCOUNT_AUTO_REPLY, + pageType: PageType.listing, + }, + }, ...lazyRouteConfig(() => import( '@/pages/dashboard/EmailAccounts/AddAndEditEmailAccount.page' @@ -198,7 +356,13 @@ export const Routes: any = [ ...lazyRouteConfig(() => import('@/pages/dashboard/AutoReplies/AddAutoReply.page'), ), - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: EMAIL_ACCOUNT_ADD_AUTO_REPLY, + pageType: PageType.funnel, + }, + }, }, { path: 'delete', @@ -207,6 +371,12 @@ export const Routes: any = [ '@/pages/dashboard/AutoReplies/ModalDeleteAutoReply.component' ), ), + handle: { + tracking: { + pageName: EMAIL_ACCOUNT_DELETE_AUTO_REPLY, + pageType: PageType.popup, + }, + }, }, ], }, @@ -217,6 +387,12 @@ export const Routes: any = [ '@/pages/dashboard/EmailAccounts/ModalDeleteEmailAccount.component' ), ), + handle: { + tracking: { + pageName: DELETE_EMAIL_ACCOUNT, + pageType: PageType.popup, + }, + }, }, { path: 'order', @@ -225,7 +401,13 @@ export const Routes: any = [ '@/pages/dashboard/EmailAccounts/EmailAccountsOrder.page' ), ), - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: ORDER_ZIMBRA_EMAIL_ACCOUNT, + pageType: PageType.funnel, + }, + }, }, ], }, @@ -234,6 +416,12 @@ export const Routes: any = [ ...lazyRouteConfig(() => import('@/pages/dashboard/MailingLists/MailingLists'), ), + handle: { + tracking: { + pageName: MAILING_LIST, + pageType: PageType.listing, + }, + }, children: [ { path: 'add', @@ -242,7 +430,13 @@ export const Routes: any = [ '@/pages/dashboard/MailingLists/AddAndEditMailingList.page' ), ), - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: ADD_MAILING_LIST, + pageType: PageType.funnel, + }, + }, }, { path: 'settings', @@ -251,7 +445,13 @@ export const Routes: any = [ '@/pages/dashboard/MailingLists/AddAndEditMailingList.page' ), ), - handle: { isOverridePage: true }, + handle: { + isOverridePage: true, + tracking: { + pageName: EDIT_MAILING_LIST, + pageType: PageType.funnel, + }, + }, }, ], }, @@ -260,6 +460,12 @@ export const Routes: any = [ ...lazyRouteConfig(() => import('@/pages/dashboard/Redirections/Redirections'), ), + handle: { + tracking: { + pageName: REDIRECTION, + pageType: PageType.listing, + }, + }, children: [ { path: 'add', @@ -268,6 +474,12 @@ export const Routes: any = [ '@/pages/dashboard/Redirections/ModalAddAndEditRedirections.page' ), ), + handle: { + tracking: { + pageName: ADD_REDIRECTION, + pageType: PageType.popup, + }, + }, }, { path: 'edit', @@ -276,6 +488,12 @@ export const Routes: any = [ '@/pages/dashboard/Redirections/ModalAddAndEditRedirections.page' ), ), + handle: { + tracking: { + pageName: EDIT_REDIRECTION, + pageType: PageType.popup, + }, + }, }, { path: 'delete', @@ -284,6 +502,12 @@ export const Routes: any = [ '@/pages/dashboard/Redirections/ModalDeleteRedirections.component' ), ), + handle: { + tracking: { + pageName: DELETE_REDIRECTION, + pageType: PageType.popup, + }, + }, }, ], }, @@ -292,6 +516,12 @@ export const Routes: any = [ ...lazyRouteConfig(() => import('@/pages/dashboard/AutoReplies/AutoReplies'), ), + handle: { + tracking: { + pageName: AUTO_REPLY, + pageType: PageType.listing, + }, + }, children: [ { path: 'delete', @@ -300,12 +530,24 @@ export const Routes: any = [ '@/pages/dashboard/AutoReplies/ModalDeleteAutoReply.component' ), ), + handle: { + tracking: { + pageName: DELETE_AUTO_REPLY, + pageType: PageType.popup, + }, + }, }, { path: 'add', ...lazyRouteConfig(() => import('@/pages/dashboard/AutoReplies/AddAutoReply.page'), ), + handle: { + tracking: { + pageName: ADD_AUTO_REPLY, + pageType: PageType.popup, + }, + }, }, ], }, @@ -315,6 +557,12 @@ export const Routes: any = [ { path: 'onboarding', ...lazyRouteConfig(() => import('@/pages/onboarding')), + handle: { + tracking: { + pageName: ONBOARDING, + pageType: PageType.onboarding, + }, + }, }, ], }, diff --git a/packages/manager/apps/zimbra/src/tracking.constant.ts b/packages/manager/apps/zimbra/src/tracking.constant.ts new file mode 100644 index 000000000000..a194634e6a37 --- /dev/null +++ b/packages/manager/apps/zimbra/src/tracking.constant.ts @@ -0,0 +1,97 @@ +export const LEVEL2 = { + EU: { + config: { + level2: '', + }, + }, + CA: { + config: { + level2: '', + }, + }, + US: { + config: { + level2: '', + }, + }, +}; + +export const UNIVERSE = 'Web_solutions'; +export const SUB_UNIVERSE = 'Emails'; +export const APP_NAME = 'zimbra'; + +// COMMON/MISC +export const CANCEL = 'cancel'; +export const CONFIRM = 'confirm'; +export const BACK_PREVIOUS_PAGE = 'back_previous-page'; +export const TO_BE_DEFINED = 'to-be-defined'; + +export const ONBOARDING = 'onboarding'; +export const JOIN_ZIMBRA_BETA = 'join_zimbra_beta'; + +export const GENERAL_INFORMATIONS = 'general-informations'; + +// DOMAIN +export const DOMAIN = 'domain'; +export const ADD_DOMAIN = `add_${DOMAIN}`; +export const EDIT_DOMAIN = `edit_${DOMAIN}`; +export const DELETE_DOMAIN = `delete_${DOMAIN}`; + +// ORGANIZATION +export const ORGANIZATION = 'organization'; +export const ADD_ORGANIZATION = `add_${ORGANIZATION}`; +export const EDIT_ORGANIZATION = `edit_${ORGANIZATION}`; +export const DELETE_ORGANIZATION = `delete_${ORGANIZATION}`; +export const SELECT_ORGANIZATION = `select_${ORGANIZATION}`; +export const UNSELECT_ORGANIZATION = `unselect_${ORGANIZATION}`; + +// MAILING LIST +export const MAILING_LIST = 'mailing-list'; +export const ADD_MAILING_LIST = `add_${MAILING_LIST}`; +export const EDIT_MAILING_LIST = `edit_${MAILING_LIST}`; +export const DELETE_MAILING_LIST = `delete_${MAILING_LIST}`; +export const DEFINE_MEMBERS_MAILING_LIST = `define_members_${MAILING_LIST}`; +export const CONFIGURE_DELEGATION_MAILING_LIST = `configure_delegation_${MAILING_LIST}`; + +// REDIRECTION +export const REDIRECTION = 'redirection'; +export const ADD_REDIRECTION = `add_${REDIRECTION}`; +export const EDIT_REDIRECTION = `edit_${REDIRECTION}`; +export const DELETE_REDIRECTION = `delete_${REDIRECTION}`; + +// ALIAS +export const ALIAS = 'alias'; +export const ADD_ALIAS = `add_${ALIAS}`; +export const DELETE_ALIAS = `delete_${ALIAS}`; + +// AUTO REPLY +export const AUTO_REPLY = 'auto-reply'; +export const ADD_AUTO_REPLY = `add_${AUTO_REPLY}`; +export const DELETE_AUTO_REPLY = `delete_${AUTO_REPLY}`; + +// EMAIL ACCOUNT +export const EMAIL_ACCOUNT = 'email-account'; +export const ADD_EMAIL_ACCOUNT = `add_${EMAIL_ACCOUNT}`; +export const EDIT_EMAIL_ACCOUNT = `edit_${EMAIL_ACCOUNT}`; +export const DELETE_EMAIL_ACCOUNT = `delete_${EMAIL_ACCOUNT}`; +export const ORDER_ZIMBRA_EMAIL_ACCOUNT = `order_zimbra_${EMAIL_ACCOUNT}`; + +// EMAIL ACCOUNT SETTINGS +export const EMAIL_ACCOUNT_AUTO_REPLY = `${EMAIL_ACCOUNT}_${AUTO_REPLY}`; +export const EMAIL_ACCOUNT_ADD_AUTO_REPLY = `${EMAIL_ACCOUNT}_${ADD_AUTO_REPLY}`; +export const EMAIL_ACCOUNT_DELETE_AUTO_REPLY = `${EMAIL_ACCOUNT}_${DELETE_AUTO_REPLY}`; +export const EMAIL_ACCOUNT_REDIRECTION = `${EMAIL_ACCOUNT}_${REDIRECTION}`; +export const EMAIL_ACCOUNT_ADD_REDIRECTION = `${EMAIL_ACCOUNT}_${ADD_REDIRECTION}`; +export const EMAIL_ACCOUNT_EDIT_REDIRECTION = `${EMAIL_ACCOUNT}_${EDIT_REDIRECTION}`; +export const EMAIL_ACCOUNT_DELETE_REDIRECTION = `${EMAIL_ACCOUNT}_${DELETE_REDIRECTION}`; +export const EMAIL_ACCOUNT_ALIAS = `${EMAIL_ACCOUNT}_${ALIAS}`; +export const EMAIL_ACCOUNT_ADD_ALIAS = `${EMAIL_ACCOUNT}_${ADD_ALIAS}`; +export const EMAIL_ACCOUNT_DELETE_ALIAS = `${EMAIL_ACCOUNT}_${DELETE_ALIAS}`; + +// GUIDES +export const GUIDE_WEBMAIL = 'webmail'; +export const GUIDE_ADMINISTRATOR = 'administrator-guide'; +export const GUIDE_USER = 'user-guide'; +export const GUIDE_CNAME = 'cname-guide'; +export const GUIDE_DNS_CONFIG = 'dns-configuration-guide'; +export const GO_TO = (link: string) => `go-to-${link}`; diff --git a/packages/manager/apps/zimbra/src/utils/test.provider.tsx b/packages/manager/apps/zimbra/src/utils/test.provider.tsx index 29c853388307..40ae07f02b93 100644 --- a/packages/manager/apps/zimbra/src/utils/test.provider.tsx +++ b/packages/manager/apps/zimbra/src/utils/test.provider.tsx @@ -133,7 +133,7 @@ const customRender = ( // We should look into using that // https://testing-library.com/docs/user-event/intro -export function setup(jsx: React.ReactElement) { +export function setup(jsx: React.ReactElement): unknown { return { user: userEvent.setup(), ...customRender(jsx), diff --git a/packages/manager/apps/zimbra/src/utils/test.setup.tsx b/packages/manager/apps/zimbra/src/utils/test.setup.tsx index 715edee6eb70..e736a23c6ee0 100644 --- a/packages/manager/apps/zimbra/src/utils/test.setup.tsx +++ b/packages/manager/apps/zimbra/src/utils/test.setup.tsx @@ -44,6 +44,20 @@ vi.mock('axios', async (importActual) => { return mockAxios; }); +vi.mock('@ovh-ux/manager-react-shell-client', async (importActual) => { + return { + ...(await importActual< + typeof import('@ovh-ux/manager-react-shell-client') + >()), + useOvhTracking: vi.fn(() => { + return { + trackClick: vi.fn(), + trackPage: vi.fn(), + }; + }), + }; +}); + vi.mock('@/hooks', async (importActual) => { return { ...(await importActual()),