UNPKG

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

Version:
212 lines (209 loc) 16.2 kB
import React from 'react'; import cx from 'classnames'; import { SideNavLink, SideNav, SideNavItems, SideNavDivider, SkeletonPlaceholder, SideNavMenu } from '@carbon/react'; import TooltipHover from '../TooltipHover/TooltipHover.js'; import { ChatBot, Home, AddAlt, UserMultiple, User, Locked, Unlocked, ChevronRight, GroupAccount } from '@carbon/react/icons'; import { USER_PLATFORM_ROLE } from '../../constants/UserType.js'; import { prefix } from '../../internal/settings.js'; /* IBM Confidential 694970X, 69497O0 © Copyright IBM Corp. 2022, 2024 */ function AdvantageSideNav(props) { const { app, enableChatButton = true, showChatButton = true, showSelectTeamPurpose = false, homeLink, assistantLink, defaultAssistantLink, joinCreateTrigger, isLoading, isOpen, teams = [], triggerEvent, accounts = [], baseEnvUrl, className, navLinks, personalTeams = [], user, showChatTooltip, templateMeteringEvent, tooltipMessage, isLaunchpad = false, userTeamsError = false, userTeamsLoading = false, history, children, ...rest } = props; const [activeSubmenu, setActiveSubmenu] = React.useState(""); const [activeMenu, setActiveMenu] = React.useState(false); const isMenuOpen = isOpen || activeMenu; const windowLocation = window.location; const isPartnerUser = user?.type === USER_PLATFORM_ROLE.Partner; const joinButtontitle = showSelectTeamPurpose ? "Create Team" : "Create or Join Team"; const standardTeamsList = [...personalTeams.map(pteams => ({ ...pteams, isPersonal: true })), ...teams]; const teamsMenuRef = React.useRef(null); const accountsMenuRef = React.useRef(null); const hamburguerMenu = document.getElementById("header-sidenav-menu-button"); const noTeamsMessage = userTeamsError ? "Failed to get teams, please try again later." : "No teams or accounts available."; const teamsRef = React.useRef([]); const accountsRef = React.useRef([]); // Functions to track IBM Instrumentation on Segment const handleHomeClick = () => { triggerEvent && triggerEvent({ action: "Clicked on SideNav Home link", category: "Sidenav", destinationPath: homeLink, }); }; const handleAssistantClick = () => { triggerEvent && triggerEvent({ action: "Clicked on SideNav Assistant link", category: "Sidenav", destinationPath: assistantLink, }); }; const handleCreateJoinClick = () => { triggerEvent && triggerEvent({ action: "Clicked on SideNav Create/Join link", category: "Sidenav", CTA: "Create/Join team cliked", type: "Button", }); }; const handleTeamClick = (team) => { triggerEvent && triggerEvent({ action: "Clicked on SideNav Team link", category: "Sidenav", destinationPath: `${baseEnvUrl}/${app}/teams/${team.id}`, teamId: team.id }); }; const handleServiceClick = ({ service, team }) => { if (templateMeteringEvent) { templateMeteringEvent({ service, team }); } triggerEvent && triggerEvent({ action: "Clicked on SideNav Service link", category: "Sidenav", destinationPath: service.url, }); }; const handleLaunchpadLink = (event) => { event.preventDefault(); // remediation to close menu, submenu and accordion when select a team on Launchpad //@ts-ignore if (Boolean(teamsMenuRef.current?.ariaExpanded === "true")) { //@ts-ignore teamsMenuRef.current.click(); } //@ts-ignore if (Boolean(accountsMenuRef.current?.ariaExpanded === "true")) { //@ts-ignore accountsMenuRef.current.click(); } //@ts-ignore if (Boolean(hamburguerMenu) && hamburguerMenu.className.includes("active")) { //@ts-ignore Boolean(hamburguerMenu) && hamburguerMenu?.click(); } setActiveMenu(false); setActiveSubmenu(""); }; // add or remove refs if (teamsRef.current.length !== standardTeamsList?.length) { //@ts-ignore teamsRef.current = Array(standardTeamsList?.length).fill().map((_, i) => teamsRef.current[i] || React.createRef()); } if (accountsRef.current.length !== accounts?.length) { //@ts-ignore accountsRef.current = Array(accounts?.length).fill().map((_, i) => accountsRef.current[i] || React.createRef()); } const assistantSideNavLink = assistantLink && (React.createElement(SideNavLink, { "data-testid": "sidenav-assistant-link", className: !enableChatButton ? `${prefix}--bmrg-advantage-sidenav__inactive-link` : "", disabled: Boolean(!enableChatButton), isActive: windowLocation.href.includes(assistantLink), renderIcon: ChatBot, href: enableChatButton && assistantLink, onClick: enableChatButton ? handleAssistantClick : (e) => e.preventDefault() }, `Start a ${defaultAssistantLink ? "" : "New "}Chat`)); return (React.createElement(SideNav, { "aria-label": "sidenav-container", className: cx(`${prefix}--bmrg-advantage-sidenav-container`, className, { "--closed": !isMenuOpen }), "data-testid": "sidenav-container", isRail: true, expanded: isMenuOpen, onToggle: () => setActiveSubmenu(""), onMouseEnter: () => setActiveMenu(true), onMouseLeave: () => { setActiveMenu(false); setActiveSubmenu(""); }, ...rest }, (React.createElement(SideNavItems, null, isMenuOpen && navLinks?.length ? (React.createElement("div", null, navLinks.map((link) => (React.createElement(SideNavLink, { href: link.url, target: link.isExternal ? "_blank" : undefined, rel: link.isExternal ? "noopener noreferrer" : undefined }, link.name))), React.createElement(SideNavDivider, null))) : null, React.createElement("div", { onMouseEnter: () => setActiveSubmenu("") }, homeLink ? React.createElement(SideNavLink, { "data-testid": "sidenav-home-link", isActive: `${baseEnvUrl}/${app}/`.includes(windowLocation.href), renderIcon: Home, href: homeLink, onClick: (e) => { if (isLaunchpad) { handleLaunchpadLink(e); history.push(homeLink); } handleHomeClick(); } }, "Home") : null, !isPartnerUser && assistantLink && showChatButton && (showChatTooltip ? (React.createElement(TooltipHover, { className: `${prefix}--bmrg-side-nav__tooltip`, content: tooltipMessage, direction: "right" }, React.createElement("span", null, assistantSideNavLink))) : (assistantSideNavLink)), (!isPartnerUser && joinCreateTrigger) ? React.createElement(SideNavLink, { "data-testid": "sidenav-create-join-trigger", renderIcon: AddAlt, onClick: (e) => { joinCreateTrigger(e); handleCreateJoinClick(); } }, joinButtontitle) : null), children ? React.createElement(React.Fragment, null, React.createElement(SideNavDivider, null), children) : null, userTeamsLoading && isMenuOpen ? React.createElement(React.Fragment, null, React.createElement(SideNavDivider, null), React.createElement("div", { className: `${prefix}--bmrg-advantage-sidenav-loading-container` }, React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` }), React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` }), React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` }))) : null, ((!Boolean(standardTeamsList?.length) && !Boolean(accounts?.length) && !userTeamsLoading) || userTeamsError) && isMenuOpen ? React.createElement(React.Fragment, null, React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-no-teams__text` }, noTeamsMessage)) : null, Boolean(standardTeamsList?.length) ? React.createElement(React.Fragment, null, React.createElement(SideNavDivider, null), React.createElement(SideNavMenu, { className: cx(`${prefix}--bmrg-advantage-sidenav-menu`, { "--active-closed": !isMenuOpen && standardTeamsList.some(t => windowLocation.href.includes(t.id)) }), renderIcon: UserMultiple, title: "Teams", "data-testid": "sidenav-teams", id: "sidenav-teams", ref: teamsMenuRef, isActive: standardTeamsList.some(t => windowLocation.href.includes(t.id)), isSideNavExpanded: isMenuOpen }, isMenuOpen ? standardTeamsList?.map((team, i) => { const topPosition = document?.getElementById(team.id)?.getBoundingClientRect()?.top ?? 0; const teamDisplayName = Boolean(team.displayName) ? team.displayName : team.name; return (React.createElement(React.Fragment, null, React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-team-item` }, React.createElement(SideNavLink, { title: teamDisplayName, name: team.name, "data-testid": "sidenav-team-link", id: team.id, isActive: windowLocation.href.includes(team.id), ref: teamsRef.current[i], className: `${prefix}--bmrg-advantage-sidenav-team`, renderIcon: team?.isPersonal ? User : (team.privateTeam ? Locked : Unlocked), href: `${baseEnvUrl}/${app}/teams/${team.id}`, onMouseEnter: () => setActiveSubmenu(team.id), onFocus: () => setActiveSubmenu(team.id), onClick: (e) => { if (isLaunchpad) { handleLaunchpadLink(e); history.push(`/teams/${team.id}`); } handleTeamClick(team); } }, React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-teams__title` }, teamDisplayName), Boolean(team?.services?.length) ? React.createElement(ChevronRight, null) : null), Boolean(team?.services?.length) && team.id === activeSubmenu ? React.createElement("ul", { className: cx(`${prefix}--bmrg-advantage-sidenav-submenu`, { "--open": team.id === activeSubmenu }), style: { top: `${window.scrollY + topPosition}px` } }, React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-submenu-wrapper` }, React.createElement("ul", { className: `${prefix}--bmrg-advantage-sidenav-services-submenu` }, React.createElement(SideNavLink, { title: "Team Page", className: `${prefix}--bmrg-advantage-sidenav-submenu-link`, "data-testid": "sidenav-team-submenu-link", href: `${baseEnvUrl}/${app}/teams/${team.id}`, onClick: (e) => { if (isLaunchpad) { handleLaunchpadLink(e); history.push(`/teams/${team.id}`); } handleTeamClick(team); } }, "Team Page"), team.services?.map((service) => (React.createElement(SideNavLink, { title: service.name, className: `${prefix}--bmrg-advantage-sidenav-submenu-link`, "data-testid": "sidenav-service-submenu-link", href: service.url, onClick: () => handleServiceClick({ service, team }) }, service.name))) ?? null))) : null))); }) : null)) : null, Boolean(accounts?.length) ? React.createElement(React.Fragment, null, React.createElement(SideNavDivider, null), React.createElement(SideNavMenu, { className: cx(`${prefix}--bmrg-advantage-sidenav-menu`, { "--active-closed": !isMenuOpen && (accounts.some(t => { const pIds = t?.projectTeams?.map(project => project.id) ?? []; return windowLocation.href.includes(t.id) || pIds.some(id => windowLocation.href.includes(id)); })) }), renderIcon: GroupAccount, title: "Accounts", "data-testid": "sidenav-accounts", id: "sidenav-accounts", ref: accountsMenuRef, "aria-expanded": isMenuOpen, isSideNavExpanded: isMenuOpen }, isMenuOpen ? accounts?.map((team, i) => { const topPosition = document?.getElementById(team.id)?.getBoundingClientRect()?.top ?? 0; const teamDisplayName = Boolean(team.displayName) ? team.displayName : team.name; const projectIds = team?.projectTeams?.map(project => project.id) ?? []; const isAccountActive = windowLocation.href.includes(team.id) || projectIds.some(id => windowLocation.href.includes(id)); return (React.createElement(React.Fragment, null, React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-team-item` }, React.createElement(SideNavLink, { title: teamDisplayName, id: team.id, isActive: isAccountActive, ref: accountsRef.current[i], className: `${prefix}--bmrg-advantage-sidenav-account`, href: `${baseEnvUrl}/${app}/teams/${team.id}`, onMouseEnter: () => setActiveSubmenu(team.id), onFocus: () => setActiveSubmenu(team.id), onClick: (e) => { if (isLaunchpad) { handleLaunchpadLink(e); history.push(`/teams/${team.id}`); } handleTeamClick(team); } }, React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-teams__title` }, teamDisplayName), Boolean(team?.projectTeams?.length) ? React.createElement(ChevronRight, null) : null), Boolean(team?.projectTeams?.length) && team.id === activeSubmenu ? React.createElement("ul", { className: cx(`${prefix}--bmrg-advantage-sidenav-submenu`, { "--open": team.id === activeSubmenu }), style: { top: `${window.scrollY + topPosition}px` } }, React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-submenu-wrapper` }, React.createElement("ul", { className: `${prefix}--bmrg-advantage-sidenav-services-submenu` }, team.projectTeams?.map((accTeam) => (React.createElement(SideNavLink, { title: accTeam.name, className: `${prefix}--bmrg-advantage-sidenav-submenu-link`, "data-testid": "sidenav-account-submenu-link", href: `${baseEnvUrl}/${app}/teams/${accTeam.id}`, onClick: (e) => { if (isLaunchpad) { handleLaunchpadLink(e); history.push(`/teams/${accTeam.id}`); } handleTeamClick(accTeam); } }, accTeam.name))) ?? null))) : null))); }) : null)) : null)))); } export { AdvantageSideNav, AdvantageSideNav as default };