UNPKG

@boomerang-io/carbon-addons-boomerang-react

Version:
319 lines (316 loc) 21 kB
import React, { useState, useEffect } from 'react'; import { useMutation } from 'react-query'; import { InlineLoading, HeaderMenu, HeaderMenuItem } from '@carbon/react'; import { CheckmarkFilled, AddAlt, GroupAccount, ChevronDown } from '@carbon/react/icons'; import sortBy from 'lodash.sortby'; import HeaderMenu$1 from './HeaderMenu.js'; import { resolver } from '../../config/servicesConfig.js'; import { prefix } from '../../internal/settings.js'; import { USER_PLATFORM_ROLE } from '../../constants/UserType.js'; /* IBM Confidential 694970X, 69497O0 © Copyright IBM Corp. 2022, 2025 */ const headerDropdownMenuContainerClassname = `${prefix}--header-dropdown-menu-container`; const headerDropdownMenuLoadingClassname = `${prefix}--header-dropdown-menu-loading`; const headerDropdownMenuSuccessClassname = `${prefix}--header-dropdown-menu-success`; const headerDropdownMenuClassname = `${prefix}--header-dropdown-menu`; const headerDropdownMenuListClassname = `${prefix}--bmrg-header-drop-down`; const headerDropdownMenuItemContainerClassname = `${prefix}--header-dropdown-menu-item-container`; const headerDropdownMenuItemClassname = `${prefix}--header-dropdown-menu-item`; const headerDropdownMenuItemTextIconClassname = `${prefix}--header-dropdown-menu-item-text-icon`; const headerDropdownMenuItemTextClassname = `${prefix}--header-dropdown-menu-item-text`; const headerDropdownMenuItemIconClassname = `${prefix}--header-dropdown-menu-item-icon`; const headerDropdownMenuItemAccountContainerClassname = `${prefix}--header-dropdown-menu-item-account-container`; const headerDropdownMenuItemAccountClassname = `${prefix}--header-dropdown-menu-item-account`; const headerDropdownMenuItemAccountIconsClassname = `${prefix}--header-dropdown-menu-item-account-icons`; const headerDropdownMenuItemAccountGroupIconClassname = `${prefix}--header-dropdown-menu-item-account-group-icon`; const headerDropdownMenuItemAccountChevronIconClassname = `${prefix}--header-dropdown-menu-item-account-chevron-icon`; const headerDropdownMenuItemAccountSubmenuClassname = `${prefix}--header-dropdown-menu-item-account-submenu`; const headerTeamSwitcherCreateTeamButtonContainerClassname = `${prefix}--header-team-switcher-create-team-button-container`; const headerTeamSwitcherCreateTeamButtonClassname = `${prefix}--header-team-switcher-create-team-button`; const headerTeamSwitcherCreateTeamButtonTextClassname = `${prefix}--header-team-switcher-create-team-button-text`; const headerTeamSwitcherCreateTeamButtonIconClassname = `${prefix}--header-team-switcher-create-team-button-icon`; function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamTrigger, history, isLaunchpad, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, menuAriaLabelRecord, menuButtonId, menuListId, navigationPlatform, refetchUser, refetchNavigation, teamsQuery, trackEvent, user, userTeams, }) { const [selectedTeam, setSelectedTeam] = useState(); const [openAccountSubmenuId, setOpenAccountSubmenuId] = useState(""); const hasUserTeams = Boolean(userTeams); const showSelectTeamPurpose = navigationPlatform?.requireTeamPurpose; const createTeamButtonText = showSelectTeamPurpose ? "Create Team" : "Create or Join Team"; const userTeamInstanceSwitcherDefault = user?.teamInstanceSwitcherDefault; const teamLink = ({ teamId }) => { return `${navigationPlatform.baseEnvUrl}/launchpad/teams/${teamId}`; }; const { mutateAsync: mutateUserProfile, isLoading: mutateUserProfileIsLoading } = useMutation(resolver.patchUserProfile, { onSuccess: () => { if (refetchUser) refetchUser(); if (refetchNavigation) refetchNavigation(); }, }); React.useEffect(() => { let timer; if (isSuccessTeamSwitcher && setIsSuccessTeamSwitcher) { timer = setTimeout(() => { setIsSuccessTeamSwitcher(false); }, 3000); } return () => clearTimeout(timer); }, [isSuccessTeamSwitcher, setIsSuccessTeamSwitcher]); useEffect(() => { let accountTeams, standardTeams, personalTeam = []; if (hasUserTeams) { accountTeams = userTeams?.data?.accountTeams ?? []; standardTeams = userTeams?.data?.standardTeams ?? []; personalTeam = userTeams?.data?.personalTeam ?? []; } else { accountTeams = teamsQuery?.data?.accountTeams ?? []; standardTeams = teamsQuery?.data?.standardTeams ?? []; personalTeam = teamsQuery?.data?.personalTeam ?? []; } const userHasPersonalTeam = personalTeam.length > 0; const userHasAccountTeams = accountTeams.length > 0; const userHasStandardTeams = standardTeams.length > 0; const userHasTeams = userHasPersonalTeam || userHasAccountTeams || userHasStandardTeams; const handleSelectTeam = async ({ team }) => { setSelectedTeam(team); if (!userTeamInstanceSwitcherDefault) { const body = { teamInstanceSwitcherDefault: team.id, }; await mutateUserProfile({ baseServicesUrl, body }); } }; if (userHasTeams) { if (!userTeamInstanceSwitcherDefault) { if (userHasPersonalTeam) { handleSelectTeam({ team: personalTeam[0] }); } else if (userHasAccountTeams) { const sortedAccounts = sortBy(accountTeams, [ (account) => (account.displayName ? account.displayName : account.name), ]); handleSelectTeam({ team: sortedAccounts[0] }); } else if (userHasStandardTeams) { const sortedStandardTeams = sortBy(standardTeams, [ (standardTeam) => (standardTeam.displayName ? standardTeam.displayName : standardTeam.name), ]); handleSelectTeam({ team: sortedStandardTeams[0] }); } } else if (selectedTeam?.id !== userTeamInstanceSwitcherDefault) { let allProjectTeams = []; if (userHasAccountTeams) { accountTeams.forEach((team) => { if (team.projectTeams && team.projectTeams.length > 0) { allProjectTeams = allProjectTeams.concat(team.projectTeams); } }); } const allTeams = personalTeam.concat(standardTeams, accountTeams, allProjectTeams); const newSelectedTeam = allTeams.find((team) => team.id === userTeamInstanceSwitcherDefault); handleSelectTeam({ team: newSelectedTeam }); } } }, [ baseServicesUrl, hasUserTeams, mutateUserProfile, selectedTeam, teamsQuery?.data?.accountTeams, teamsQuery?.data?.personalTeam, teamsQuery?.data?.standardTeams, userTeamInstanceSwitcherDefault, userTeams?.data?.accountTeams, userTeams?.data?.personalTeam, userTeams?.data?.standardTeams, ]); const handleHeaderMenuClick = () => { setOpenAccountSubmenuId(""); }; const handleTeamClick = ({ team, type }) => { setOpenAccountSubmenuId(""); if (analyticsHelpers?.navigateEventHandler && trackEvent) { analyticsHelpers.navigateEventHandler({ action: `Clicked ${team.name} in Team Switcher`, category: "Team Switcher", destinationPath: teamLink({ teamId: team.id }), teamId: team.id, teamType: type, trackEvent, }); } if (isLaunchpad && Boolean(history)) { history.push(`/teams/${team.id}`); } else { window.open(teamLink({ teamId: team.id }), "_self"); } }; const handleCreateJoinTeamClick = (e) => { if (analyticsHelpers?.ctaEventHandler && trackEvent) { analyticsHelpers.ctaEventHandler({ category: "Team Switcher", CTA: "Create/Join team clicked", pageName: "", trackEvent, }); } if (createJoinTeamTrigger) { createJoinTeamTrigger(e); } else { window.open(`${navigationPlatform.baseEnvUrl}/launchpad?createJoinTeam=true`, "_self"); } }; const handleOpenAccountSubmenu = ({ e, id }) => { e.stopPropagation(); if (openAccountSubmenuId === id) { setOpenAccountSubmenuId(""); } else { setOpenAccountSubmenuId(id); } }; if (userTeams?.isLoading || teamsQuery?.isLoading || mutateUserProfileIsLoading) { return (React.createElement("div", { style: { display: "flex", alignItems: "center" } }, React.createElement(InlineLoading, null))); } if (userTeams?.data || teamsQuery?.data) { let accountTeams, standardTeams, personalTeam = []; if (hasUserTeams) { accountTeams = userTeams?.data?.accountTeams ?? []; standardTeams = userTeams?.data?.standardTeams ?? []; personalTeam = userTeams?.data?.personalTeam ?? []; } else { accountTeams = teamsQuery?.data?.accountTeams ?? []; standardTeams = teamsQuery?.data?.standardTeams ?? []; personalTeam = teamsQuery?.data?.personalTeam ?? []; } let sortedAccountTeamsWithNamesToDisplay = []; let sortedStandardTeamsWithNamesToDisplay = []; if (accountTeams?.length > 0) { const newAccountTeams = accountTeams.map((team) => { let newProjectTeams = []; if (team.projectTeams && team.projectTeams.length > 0) { newProjectTeams = team.projectTeams?.map((team) => ({ ...team, nameToDisplay: team.displayName ? team.displayName : team.name, })); } return { ...team, nameToDisplay: team.displayName ? team.displayName : team.name, projectTeams: sortBy(newProjectTeams, ["nameToDisplay"]), }; }); sortedAccountTeamsWithNamesToDisplay = sortBy(newAccountTeams, ["nameToDisplay"]); } if (standardTeams?.length > 0) { const newStandardTeams = standardTeams.map((team) => { return { ...team, nameToDisplay: team.displayName ? team.displayName : team.name, }; }); sortedStandardTeamsWithNamesToDisplay = sortBy(newStandardTeams, ["nameToDisplay"]); } let selectedTeamName = selectedTeam?.displayName ? selectedTeam.displayName : selectedTeam?.name; if (selectedTeamName && selectedTeamName.length > 65) { selectedTeamName = selectedTeamName.slice(0, 65) + "..."; } const isPartnerUser = Boolean(user?.type === USER_PLATFORM_ROLE.Partner); return (React.createElement("div", { className: headerDropdownMenuContainerClassname }, isLoadingTeamSwitcher ? (React.createElement("div", { className: headerDropdownMenuLoadingClassname }, React.createElement(InlineLoading, null))) : isSuccessTeamSwitcher ? (React.createElement("div", { className: headerDropdownMenuSuccessClassname }, React.createElement(CheckmarkFilled, null))) : null, React.createElement(HeaderMenu, { id: "header-team-switcher-menu", "aria-label": menuAriaLabelRecord, className: headerDropdownMenuClassname, menuLinkName: selectedTeamName ? selectedTeamName : "No team selected", onClick: handleHeaderMenuClick, "data-testid": "header-team-switcher-menu" }, React.createElement(HeaderMenu$1, { "aria-labelledby": menuButtonId, className: headerDropdownMenuListClassname, id: menuListId }, !isPartnerUser && (React.createElement(HeaderMenuItem, { id: "header-team-switcher-create-join-team-button", className: headerTeamSwitcherCreateTeamButtonContainerClassname, onClick: handleCreateJoinTeamClick, // eslint-disable-next-line no-script-url href: "javascript:void(0)", role: "menuitem", "data-testid": "header-team-switcher-create-join-team-button" }, React.createElement("div", { className: headerTeamSwitcherCreateTeamButtonClassname }, React.createElement("span", { className: headerTeamSwitcherCreateTeamButtonTextClassname }, createTeamButtonText), React.createElement(AddAlt, { className: headerTeamSwitcherCreateTeamButtonIconClassname })))), personalTeam.length > 0 ? personalTeam.map((team) => { const teamName = team.displayName ? team.displayName : team.name; const isTeamSelected = team.id === selectedTeam?.id; return (React.createElement("div", { key: team.id, id: `${team.id}-personal-menu-item-id` }, React.createElement(HeaderMenuItem, { key: team.id, id: `${team.id}-personal-menu-item`, "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => { handleTeamClick({ team, type: "personal" }); }, // eslint-disable-next-line no-script-url href: "javascript:void(0)", "data-testid": "header-team-switcher-menu-item" }, React.createElement("div", { className: headerDropdownMenuItemClassname }, React.createElement("span", { title: teamName, className: headerDropdownMenuItemTextClassname }, teamName), isTeamSelected ? React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null)))); }) : null, accountTeams.length > 0 ? sortedAccountTeamsWithNamesToDisplay.map((team) => { const isSubmenuOpen = team.id === openAccountSubmenuId; const isProjectTeamSelected = team.projectTeams && team.projectTeams.length > 0 && team.projectTeams.some((team) => team.id === selectedTeam?.id); const isTeamSelected = team.id === selectedTeam?.id; const isMenuSelected = isTeamSelected || isProjectTeamSelected; return (React.createElement("div", { key: team.id, id: `${team.id}-account-menu` }, React.createElement(HeaderMenuItem, { "aria-expanded": isSubmenuOpen, "aria-selected": isMenuSelected, className: headerDropdownMenuItemAccountContainerClassname, onClick: (e) => handleOpenAccountSubmenu({ e, id: team.id }), // eslint-disable-next-line no-script-url href: "javascript:void(0)", "data-testid": "header-team-switcher-menu-account-accordion" }, React.createElement("div", { className: headerDropdownMenuItemAccountClassname }, React.createElement("div", { className: headerDropdownMenuItemTextIconClassname }, React.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, team.nameToDisplay), isMenuSelected ? (React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname })) : null), React.createElement("div", { className: headerDropdownMenuItemAccountIconsClassname }, React.createElement(GroupAccount, { className: headerDropdownMenuItemAccountGroupIconClassname }), React.createElement(ChevronDown, { className: headerDropdownMenuItemAccountChevronIconClassname })))), React.createElement("div", { id: `${team.id}-account-submenu`, key: `${team.id}-account-submenu`, "aria-expanded": isSubmenuOpen, className: headerDropdownMenuItemAccountSubmenuClassname }, React.createElement(HeaderMenuItem, { key: `${team.id}-menu-item`, id: `${team.id}-account-menu-item`, "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => { handleTeamClick({ team, type: "account" }); }, "data-testid": "header-team-switcher-menu-account-accordion-item", // eslint-disable-next-line no-script-url href: "javascript:void(0)" }, React.createElement("div", { className: headerDropdownMenuItemClassname, style: { paddingLeft: "1rem" } }, React.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, "Account Page"), isTeamSelected ? (React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname })) : null)), team.projectTeams && team.projectTeams.length > 0 ? team.projectTeams.map((team) => { const isTeamSelected = team.id === selectedTeam?.id; return (React.createElement("div", { key: team.id, id: `${team.id}-project-menu-item` }, React.createElement(HeaderMenuItem, { "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => { handleTeamClick({ team, type: "project" }); }, "data-testid": "header-team-switcher-menu-account-accordion-item", // eslint-disable-next-line no-script-url href: "javascript:void(0)" }, React.createElement("div", { className: headerDropdownMenuItemClassname, style: { paddingLeft: "1rem" } }, React.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, team.nameToDisplay), isTeamSelected ? (React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname })) : null)))); }) : null))); }) : null, standardTeams.length > 0 ? sortedStandardTeamsWithNamesToDisplay.map((team) => { const isTeamSelected = team.id === selectedTeam?.id; return (React.createElement("div", { key: team.id, id: `${team.id}-standard-menu-item` }, React.createElement(HeaderMenuItem, { "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => { handleTeamClick({ team, type: "standard" }); }, "data-testid": "header-team-switcher-menu-item", // eslint-disable-next-line no-script-url href: "javascript:void(0)" }, React.createElement("div", { className: headerDropdownMenuItemClassname }, React.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, team.nameToDisplay), isTeamSelected ? React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null)))); }) : null)))); } return null; } export { HeaderTeamSwitcher as default };