@boomerang-io/carbon-addons-boomerang-react 4.6.11-beta.2 → 4.6.11-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import cx from 'classnames';
3
- import { SideNavLink, SideNav, SideNavItems, SideNavDivider, ComposedModal, ModalHeader, ModalBody, ComboBox, ModalFooter, Button, SkeletonPlaceholder, SideNavMenu } from '@carbon/react';
3
+ import { SideNavLink, SideNav, SideNavItems, SideNavDivider } from '@carbon/react';
4
4
  import TooltipHover from '../TooltipHover/TooltipHover.js';
5
- import { ChatBot, Home, AddAlt, UserMultiple, User, Locked, Unlocked, ChevronRight, GroupAccount } from '@carbon/react/icons';
5
+ import { ChatBot, Home, UserMultiple, AddAlt, Api, IntentRequestCreate, Folders, DocumentMultiple_02, Catalog, Settings, LicenseThirdParty } from '@carbon/react/icons';
6
6
  import { USER_PLATFORM_ROLE } from '../../constants/UserType.js';
7
7
  import { prefix } from '../../internal/settings.js';
8
8
 
@@ -12,25 +12,46 @@ IBM Confidential
12
12
  © Copyright IBM Corp. 2022, 2024
13
13
  */
14
14
  function AdvantageSideNav(props) {
15
- const { app, appLink, regionalTeam, 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;
16
- const [activeSubmenu, setActiveSubmenu] = React.useState("");
15
+ const { app, appLink, regionalTeam, enableChatButton = true, showChatButton = true, showSelectTeamPurpose = false, homeLink, agentAssistantStudioLink, agentAssistantLibraryLink, assistantLink, defaultAssistantLink, documentCollectionsLink, settingsLink, toolsLink, joinCreateTrigger, isLoading, isOpen, teams = [], triggerEvent, accounts = [], baseEnvUrl, className, navLinks, navigation, personalTeams = [], user, showChatTooltip, templateMeteringEvent, tooltipMessage, isLaunchpad = false, history, children, ...rest } = props;
17
16
  const [activeMenu, setActiveMenu] = React.useState(false);
18
- const [teamList, setTeamList] = React.useState(null);
19
- const [regionalModalIsOpen, setRegionalModalIsOpen] = React.useState(false);
20
- const [selectedTeam, setSelectedTeam] = React.useState(null);
17
+ React.useState(null);
18
+ // const [regionalModalIsOpen, setRegionalModalIsOpen] = React.useState(false);
19
+ React.useState(null);
21
20
  const isMenuOpen = isOpen || activeMenu;
22
21
  const windowLocation = window.location;
23
22
  const isPartnerUser = user?.type === USER_PLATFORM_ROLE.Partner;
24
23
  const joinButtontitle = showSelectTeamPurpose ? "Create Team" : "Create or Join Team";
25
- const standardTeamsList = [...personalTeams.map((pteams) => ({ ...pteams, isPersonal: true })), ...teams];
26
- const teamsMenuRef = React.useRef(null);
27
- const accountsMenuRef = React.useRef(null);
28
24
  const hamburguerMenu = document.getElementById("header-sidenav-menu-button");
29
- const noTeamsMessage = userTeamsError
30
- ? "Failed to get teams, please try again later."
31
- : "No teams or accounts available.";
32
- const teamsRef = React.useRef([]);
33
- const accountsRef = React.useRef([]);
25
+ // get current selected team
26
+ let teamSwitcherTeam = null;
27
+ if (personalTeams.length > 0) {
28
+ personalTeams.forEach((team) => {
29
+ if (team.id === user?.teamInstanceSwitcherDefault) {
30
+ teamSwitcherTeam = { ...team, isPersonal: true };
31
+ }
32
+ });
33
+ }
34
+ if (teams.length > 0) {
35
+ teams.forEach((team) => {
36
+ if (team.id === user?.teamInstanceSwitcherDefault) {
37
+ teamSwitcherTeam = { ...team, isStandard: true };
38
+ }
39
+ });
40
+ }
41
+ if (accounts.length > 0) {
42
+ accounts.forEach((account) => {
43
+ if (account.id === user?.teamInstanceSwitcherDefault) {
44
+ teamSwitcherTeam = { ...account, isAccount: true };
45
+ }
46
+ else if (account.projectTeams && account.projectTeams?.length > 0) {
47
+ account.projectTeams.forEach((projectTeam) => {
48
+ if (projectTeam.id === user?.teamInstanceSwitcherDefault) {
49
+ teamSwitcherTeam = { ...projectTeam, isProject: true };
50
+ }
51
+ });
52
+ }
53
+ });
54
+ }
34
55
  // Functions to track IBM Instrumentation on Segment
35
56
  const handleHomeClick = () => {
36
57
  triggerEvent &&
@@ -40,24 +61,57 @@ function AdvantageSideNav(props) {
40
61
  destinationPath: homeLink,
41
62
  });
42
63
  };
43
- const handleRegionalNewStartNewChat = (team) => {
44
- const assistantLink = `${appLink?.newChatRedirect()}?teamName=${team.name}&teamId=${team.id}`;
45
- window.open(assistantLink, "_self", "noopener,noreferrer");
64
+ const handleToolsClick = () => {
65
+ triggerEvent &&
66
+ triggerEvent({
67
+ action: "Clicked on SideNav Tools link",
68
+ category: "Sidenav",
69
+ destinationPath: toolsLink,
70
+ });
71
+ };
72
+ const handleAgentAssistantStudioClick = () => {
73
+ triggerEvent &&
74
+ triggerEvent({
75
+ action: "Clicked on SideNav Agent & Assistant Studio link",
76
+ category: "Sidenav",
77
+ destinationPath: agentAssistantStudioLink,
78
+ });
79
+ };
80
+ const handleAgentAssistantLibraryClick = () => {
81
+ triggerEvent &&
82
+ triggerEvent({
83
+ action: "Clicked on SideNav Agent & Assistant Library link",
84
+ category: "Sidenav",
85
+ destinationPath: agentAssistantLibraryLink,
86
+ });
87
+ };
88
+ const handleDocumentCollectionsClick = () => {
89
+ triggerEvent &&
90
+ triggerEvent({
91
+ action: "Clicked on SideNav Document Collections link",
92
+ category: "Sidenav",
93
+ destinationPath: documentCollectionsLink,
94
+ });
95
+ };
96
+ const handleSettingsClick = () => {
97
+ triggerEvent &&
98
+ triggerEvent({
99
+ action: "Clicked on SideNav Settings link",
100
+ category: "Sidenav",
101
+ destinationPath: settingsLink,
102
+ });
46
103
  };
47
104
  const handleAssistantClick = () => {
48
- if (regionalTeam?.length > 1) {
49
- setRegionalModalIsOpen(true);
50
- setTeamList(regionalTeam?.map((team) => ({
51
- id: team.id,
52
- name: team.name,
53
- })));
54
- }
105
+ console.log("assistantLink checking", assistantLink);
106
+ let redirectLink = `${appLink.newChatRedirect()}?teamName=${teamSwitcherTeam.name}&teamId=${teamSwitcherTeam.id}`;
107
+ console.log("redirectLink checking", redirectLink);
55
108
  triggerEvent &&
56
109
  triggerEvent({
57
110
  action: "Clicked on SideNav Assistant link",
58
111
  category: "Sidenav",
59
- destinationPath: assistantLink,
60
112
  });
113
+ console.log("asddasd", assistantLink);
114
+ // window.open(assistantLink, "_self", "noopener,noreferrer");
61
115
  };
62
116
  const handleCreateJoinClick = () => {
63
117
  triggerEvent &&
@@ -78,60 +132,35 @@ function AdvantageSideNav(props) {
78
132
  teamType: type,
79
133
  });
80
134
  };
81
- const handleServiceClick = ({ service, team }) => {
82
- if (templateMeteringEvent) {
83
- templateMeteringEvent({ service, team });
84
- }
85
- triggerEvent &&
86
- triggerEvent({
87
- action: "Clicked on SideNav Service link",
88
- category: "Sidenav",
89
- destinationPath: service.url,
90
- });
91
- };
92
135
  const handleLaunchpadLink = (event) => {
93
136
  event.preventDefault();
94
- // remediation to close menu, submenu and accordion when select a team on Launchpad
95
- //@ts-ignore
96
- if (Boolean(teamsMenuRef.current?.ariaExpanded === "true")) {
97
- //@ts-ignore
98
- teamsMenuRef.current.click();
99
- }
100
- //@ts-ignore
101
- if (Boolean(accountsMenuRef.current?.ariaExpanded === "true")) {
102
- //@ts-ignore
103
- accountsMenuRef.current.click();
104
- }
105
137
  //@ts-ignore
106
138
  if (Boolean(hamburguerMenu) && hamburguerMenu.className.includes("active")) {
107
139
  //@ts-ignore
108
140
  Boolean(hamburguerMenu) && hamburguerMenu?.click();
109
141
  }
110
142
  setActiveMenu(false);
111
- setActiveSubmenu("");
112
143
  };
113
- // add or remove refs
114
- if (teamsRef.current.length !== standardTeamsList?.length) {
115
- //@ts-ignore
116
- teamsRef.current = Array(standardTeamsList?.length).fill().map((_, i) => teamsRef.current[i] || React.createRef());
117
- }
118
- if (accountsRef.current.length !== accounts?.length) {
119
- //@ts-ignore
120
- accountsRef.current = Array(accounts?.length).fill().map((_, i) => accountsRef.current[i] || React.createRef());
121
- }
122
144
  const assistantSideNavLink = (
123
- // assistantLink &&
124
- React.createElement(SideNavLink, { "data-testid": "sidenav-assistant-link", className: !enableChatButton ? `${prefix}--bmrg-advantage-sidenav__inactive-link` : "", disabled: Boolean(!enableChatButton), isActive: assistantLink ? windowLocation.href.includes(assistantLink) : '', renderIcon: ChatBot, href: enableChatButton && assistantLink, onClick: enableChatButton ? handleAssistantClick : (e) => e.preventDefault() }, `Start a ${defaultAssistantLink ? "" : "New "}Chat`));
145
+ // assistantLink &&
146
+ React.createElement(SideNavLink, { "data-testid": "sidenav-assistant-link", className: !enableChatButton ? `${prefix}--bmrg-advantage-sidenav__inactive-link` : "", disabled: Boolean(!enableChatButton),
147
+ // isActive={assistantLink }
148
+ renderIcon: ChatBot,
149
+ // href={enableChatButton}
150
+ onClick: enableChatButton ? handleAssistantClick : (e) => e.preventDefault() }, "Chat d"));
151
+ const catalogNavlink = navigation?.platform?.catalog?.url;
152
+ const adminNavlink = navigation?.platform?.admin?.url;
153
+ const showSecondDivider = (!isPartnerUser && showChatButton) ||
154
+ toolsLink ||
155
+ agentAssistantStudioLink ||
156
+ agentAssistantLibraryLink ||
157
+ documentCollectionsLink;
125
158
  return (React.createElement(SideNav, { "aria-label": "sidenav-container", className: cx(`${prefix}--bmrg-advantage-sidenav-container`, className, {
126
159
  "--closed": !isMenuOpen,
127
- }), "data-testid": "sidenav-container", isRail: true, expanded: isMenuOpen, onToggle: () => setActiveSubmenu(""), onMouseEnter: () => setActiveMenu(true), onMouseLeave: () => {
160
+ }), "data-testid": "sidenav-container", isRail: true, expanded: isMenuOpen, onMouseEnter: () => setActiveMenu(true), onMouseLeave: () => {
128
161
  setActiveMenu(false);
129
- setActiveSubmenu("");
130
162
  }, ...rest }, React.createElement(SideNavItems, null,
131
- isMenuOpen && navLinks?.length ? (React.createElement("div", null,
132
- navLinks.map((link) => (React.createElement(SideNavLink, { href: link.url, target: link.isExternal ? "_blank" : undefined, rel: link.isExternal ? "noopener noreferrer" : undefined }, link.name))),
133
- React.createElement(SideNavDivider, null))) : null,
134
- React.createElement("div", { onMouseEnter: () => setActiveSubmenu("") },
163
+ React.createElement("div", null,
135
164
  homeLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-home-link", isActive: `${baseEnvUrl}/${app}/`.includes(windowLocation.href), renderIcon: Home, href: homeLink, onClick: (e) => {
136
165
  if (isLaunchpad) {
137
166
  handleLaunchpadLink(e);
@@ -139,115 +168,57 @@ function AdvantageSideNav(props) {
139
168
  }
140
169
  handleHomeClick();
141
170
  } }, "Home")) : null,
142
- !isPartnerUser &&
143
- // assistantLink &&
144
- showChatButton &&
145
- (showChatTooltip ? (React.createElement(TooltipHover, { className: `${prefix}--bmrg-side-nav__tooltip`, content: tooltipMessage, direction: "right" },
146
- React.createElement("span", null, assistantSideNavLink))) : (assistantSideNavLink)),
147
- assistantSideNavLink,
148
- regionalModalIsOpen && React.createElement(ComposedModal, { className: `${prefix}--teamSelectionModalContainer`, open: regionalModalIsOpen, onClose: () => setRegionalModalIsOpen(false), onKeyDown: (e) => e.stopPropagation(), "data-testid": "select-team-chat-modal" },
149
- React.createElement(ModalHeader, { title: "Select Team to Start a New Chat", closeModal: () => setRegionalModalIsOpen(false) }),
150
- React.createElement(ModalBody, { className: `${prefix}--teamSelectModalBody` },
151
- React.createElement(ComboBox, { items: teamList, disabled: !teamList?.length, id: "select-team-chat-modal-dropdown", selectedItem: selectedTeam, size: "md", "data-testid": "select-team-chat-modal-dropdown", itemToString: (item) => item?.name, label: "Choose a team", onChange: ({ selectedItem }) => setSelectedTeam(selectedItem) })),
152
- React.createElement(ModalFooter, null,
153
- React.createElement(Button, { kind: "secondary", "data-testid": "select-team-chat-modal-cancel-button", onClick: () => setRegionalModalIsOpen(false) }, "Cancel"),
154
- React.createElement(Button, { "data-modal-primary-focus": true, kind: "primary", disabled: !selectedTeam, "data-testid": "select-team-chat-modal-continue-button", onClick: () => {
155
- if (selectedTeam) {
156
- handleRegionalNewStartNewChat(selectedTeam);
157
- setRegionalModalIsOpen(false);
158
- // closeModal();
159
- }
160
- } }, "Continue"))),
161
- !isPartnerUser && joinCreateTrigger ? (React.createElement(SideNavLink, { "data-testid": "sidenav-create-join-trigger", renderIcon: AddAlt, onClick: (e) => {
171
+ teamSwitcherTeam ? (React.createElement(SideNavLink, { title: teamSwitcherTeam.isAccount ? "Account Page" : "Team Page", name: teamSwitcherTeam.name, "data-testid": "sidenav-team-link", id: teamSwitcherTeam.id, isActive: windowLocation.href.includes(teamSwitcherTeam.id), className: `${prefix}--bmrg-advantage-sidenav-team`, renderIcon: UserMultiple, href: `${baseEnvUrl}/${app}/teams/${teamSwitcherTeam.id}`, onClick: (e) => {
172
+ if (isLaunchpad) {
173
+ handleLaunchpadLink(e);
174
+ history.push(`/teams/${teamSwitcherTeam.id}`);
175
+ }
176
+ handleTeamClick({
177
+ team: teamSwitcherTeam,
178
+ type: teamSwitcherTeam.isPersonal
179
+ ? "personal"
180
+ : teamSwitcherTeam.isAccount
181
+ ? "account"
182
+ : teamSwitcherTeam.isproject
183
+ ? "project"
184
+ : "standard",
185
+ });
186
+ } },
187
+ React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-teams__title` }, teamSwitcherTeam.isAccount ? "Account Page" : "Team Page"))) : !isPartnerUser && joinCreateTrigger ? (React.createElement(SideNavLink, { "data-testid": "sidenav-create-join-trigger", renderIcon: AddAlt, onClick: (e) => {
162
188
  joinCreateTrigger(e);
163
189
  handleCreateJoinClick();
164
- } }, joinButtontitle)) : null),
165
- children ? (React.createElement(React.Fragment, null,
166
- React.createElement(SideNavDivider, null),
167
- children)) : null,
168
- userTeamsLoading && isMenuOpen ? (React.createElement(React.Fragment, null,
190
+ } }, joinButtontitle)) : null,
169
191
  React.createElement(SideNavDivider, null),
170
- React.createElement("div", { className: `${prefix}--bmrg-advantage-sidenav-loading-container` },
171
- React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` }),
172
- React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` }),
173
- React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` })))) : null,
174
- ((!Boolean(standardTeamsList?.length) && !Boolean(accounts?.length) && !userTeamsLoading) ||
175
- userTeamsError) &&
176
- isMenuOpen ? (React.createElement(React.Fragment, null,
177
- React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-no-teams__text` }, noTeamsMessage))) : null,
178
- Boolean(standardTeamsList?.length) ? (React.createElement(React.Fragment, null,
179
- React.createElement(SideNavDivider, null),
180
- React.createElement(SideNavMenu, { className: cx(`${prefix}--bmrg-advantage-sidenav-menu`, {
181
- "--active-closed": !isMenuOpen && standardTeamsList.some((t) => windowLocation.href.includes(t.id)),
182
- }), 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
183
- ? standardTeamsList?.map((team, i) => {
184
- const topPosition = document?.getElementById(team.id)?.getBoundingClientRect()?.top ?? 0;
185
- const teamDisplayName = Boolean(team.displayName) ? team.displayName : team.name;
186
- return (React.createElement(React.Fragment, null,
187
- React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-team-item` },
188
- 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) => {
189
- if (isLaunchpad) {
190
- handleLaunchpadLink(e);
191
- history.push(`/teams/${team.id}`);
192
- }
193
- handleTeamClick({ team, type: team.isPersonal ? "personal" : "standard" });
194
- } },
195
- React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-teams__title` }, teamDisplayName),
196
- Boolean(team?.services?.length) ? React.createElement(ChevronRight, null) : null),
197
- Boolean(team?.services?.length) && team.id === activeSubmenu ? (React.createElement("ul", { className: cx(`${prefix}--bmrg-advantage-sidenav-submenu`, {
198
- "--open": team.id === activeSubmenu,
199
- }), style: { top: `${window.scrollY + topPosition}px` } },
200
- React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-submenu-wrapper` },
201
- React.createElement("ul", { className: `${prefix}--bmrg-advantage-sidenav-services-submenu` },
202
- 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) => {
203
- if (isLaunchpad) {
204
- handleLaunchpadLink(e);
205
- history.push(`/teams/${team.id}`);
206
- }
207
- handleTeamClick({ team, type: team.isPersonal ? "personal" : "standard" });
208
- } }, "Team Page"),
209
- 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)));
210
- })
211
- : null))) : null,
212
- Boolean(accounts?.length) ? (React.createElement(React.Fragment, null,
192
+ // assistantLink &&
193
+ showChatButton &&
194
+ (showChatTooltip ? (React.createElement(TooltipHover, { className: `${prefix}--bmrg-side-nav__tooltip`, content: tooltipMessage, direction: "right" },
195
+ React.createElement("span", null, assistantSideNavLink))) : (assistantSideNavLink)),
196
+ toolsLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-tools-link", renderIcon: Api, href: toolsLink, onClick: (e) => {
197
+ handleToolsClick();
198
+ } }, "Tools")) : null,
199
+ agentAssistantStudioLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-agent-assistant-studio-link", isActive: windowLocation.href.includes(`/launchpad/agent-assistant-studio`) ||
200
+ windowLocation.href.includes(`/launchpad/agenticapps`), renderIcon: IntentRequestCreate, href: agentAssistantStudioLink, onClick: (e) => {
201
+ if (isLaunchpad) {
202
+ handleLaunchpadLink(e);
203
+ history.push(agentAssistantStudioLink);
204
+ }
205
+ handleAgentAssistantStudioClick();
206
+ } }, "Agent & Assistant Studio")) : null,
207
+ agentAssistantLibraryLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-agent-assistant-library-link", renderIcon: Folders, href: agentAssistantLibraryLink, onClick: (e) => {
208
+ handleAgentAssistantLibraryClick();
209
+ } }, "Agent & Assistant Library")) : null,
210
+ documentCollectionsLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-document-collections-link", renderIcon: DocumentMultiple_02, href: documentCollectionsLink, onClick: (e) => {
211
+ handleDocumentCollectionsClick();
212
+ } }, "Document Collections")) : null,
213
+ showSecondDivider ? React.createElement(SideNavDivider, null) : null,
214
+ catalogNavlink ? (React.createElement(SideNavLink, { href: catalogNavlink, renderIcon: Catalog }, "Catalog")) : null,
215
+ settingsLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-settings-link", renderIcon: Settings, href: settingsLink, onClick: (e) => {
216
+ handleSettingsClick();
217
+ } }, "Settings")) : null,
218
+ adminNavlink ? (React.createElement(SideNavLink, { href: adminNavlink, renderIcon: LicenseThirdParty }, "Admin")) : null),
219
+ children ? (React.createElement(React.Fragment, null,
213
220
  React.createElement(SideNavDivider, null),
214
- React.createElement(SideNavMenu, { className: cx(`${prefix}--bmrg-advantage-sidenav-menu`, {
215
- "--active-closed": !isMenuOpen &&
216
- accounts.some((t) => {
217
- const pIds = t?.projectTeams?.map((project) => project.id) ?? [];
218
- return windowLocation.href.includes(t.id) || pIds.some((id) => windowLocation.href.includes(id));
219
- }),
220
- }), renderIcon: GroupAccount, title: "Accounts", "data-testid": "sidenav-accounts", id: "sidenav-accounts", ref: accountsMenuRef, "aria-expanded": isMenuOpen, isSideNavExpanded: isMenuOpen }, isMenuOpen
221
- ? accounts?.map((team, i) => {
222
- const topPosition = document?.getElementById(team.id)?.getBoundingClientRect()?.top ?? 0;
223
- const teamDisplayName = Boolean(team.displayName) ? team.displayName : team.name;
224
- const projectIds = team?.projectTeams?.map((project) => project.id) ?? [];
225
- const isAccountActive = windowLocation.href.includes(team.id) ||
226
- projectIds.some((id) => windowLocation.href.includes(id));
227
- return (React.createElement(React.Fragment, null,
228
- React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-team-item` },
229
- 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) => {
230
- if (isLaunchpad) {
231
- handleLaunchpadLink(e);
232
- history.push(`/teams/${team.id}`);
233
- }
234
- handleTeamClick({ team, type: "account" });
235
- } },
236
- React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-teams__title` }, teamDisplayName),
237
- Boolean(team?.projectTeams?.length) ? React.createElement(ChevronRight, null) : null),
238
- Boolean(team?.projectTeams?.length) && team.id === activeSubmenu ? (React.createElement("ul", { className: cx(`${prefix}--bmrg-advantage-sidenav-submenu`, {
239
- "--open": team.id === activeSubmenu,
240
- }), style: { top: `${window.scrollY + topPosition}px` } },
241
- React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-submenu-wrapper` },
242
- 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) => {
243
- if (isLaunchpad) {
244
- handleLaunchpadLink(e);
245
- history.push(`/teams/${accTeam.id}`);
246
- }
247
- handleTeamClick({ team: accTeam, type: "project" });
248
- } }, accTeam.name))) ?? null)))) : null)));
249
- })
250
- : null))) : null)));
221
+ children)) : null)));
251
222
  }
252
223
 
253
224
  export { AdvantageSideNav, AdvantageSideNav as default };
@@ -1,19 +1,22 @@
1
1
  import React from 'react';
2
+ import { useQuery } from 'react-query';
2
3
  import { Theme, Header as Header$1, SkipToContent, HeaderName, HeaderNavigation, HeaderMenuItem, HeaderGlobalBar, HeaderPanel, HeaderMenuButton, SideNav, SideNavItems, SideNavLink } from '@carbon/react';
3
4
  import { Wikis, Checkmark, Collaborate, NotificationNew, Notification, Help, UserAvatar, Close, Switcher, OpenPanelFilledRight } from '@carbon/react/icons';
4
5
  import HeaderAppSwitcher from './HeaderAppSwitcher.js';
6
+ import HeaderTeamSwitcher from './HeaderTeamSwitcher.js';
5
7
  import HeaderMenu from './HeaderMenu.js';
6
8
  import NotificationsContainer from '../Notifications/NotificationsContainer.js';
7
9
  import PlatformNotificationsContainer from '../PlatformNotifications/PlatformNotificationsContainer.js';
8
10
  import UserRequests from './UserRequests.js';
9
11
  import useHeaderMenu from '../../hooks/useHeaderMenu.js';
10
12
  import useWindowSize from '../../hooks/useWindowSize.js';
13
+ import { resolver, serviceUrl } from '../../config/servicesConfig.js';
11
14
  import { prefix } from '../../internal/settings.js';
12
15
 
13
16
  /*
14
17
  IBM Confidential
15
18
  694970X, 69497O0
16
- © Copyright IBM Corp. 2022, 2024
19
+ © Copyright IBM Corp. 2022, 2025
17
20
  */
18
21
  const MenuListId = {
19
22
  Notifcations: "header-notifications-dialog",
@@ -24,6 +27,7 @@ const MenuListId = {
24
27
  Support: "header-support-menu",
25
28
  instanceSwitcher: "header-instanceSwitcher-menu",
26
29
  Switcher: "header-switcher-menu",
30
+ TeamSwitcher: "header-team-switcher-menu",
27
31
  };
28
32
  const MenuButtonId = {
29
33
  Notifcations: "header-notifications-dialog-button",
@@ -34,6 +38,7 @@ const MenuButtonId = {
34
38
  Support: "header-support-menu-button",
35
39
  InstanceSwitcher: "header-instanceSwitcher-menu-button",
36
40
  Switcher: "header-switcher-menu-button",
41
+ TeamSwitcher: "header-team-switcher-menu-button",
37
42
  };
38
43
  const MenuAriaLabelRecord = {
39
44
  Notifcations: "Notifications dialog",
@@ -44,11 +49,19 @@ const MenuAriaLabelRecord = {
44
49
  instanceSwitcher: "Instance Switcher Menu",
45
50
  Support: "Support menu",
46
51
  Switcher: "Switcher menu",
52
+ TeamSwitcher: "Team Switcher menu",
47
53
  };
48
54
  const headerButtonClassNames = "cds--btn--icon-only cds--header__action cds--btn cds--btn--primary cds--btn--icon-only cds--btn cds--btn--primary";
49
55
  const instanceCheckMarkContainerClass = "instance-checkmark-style-container";
50
56
  function Header(props) {
51
- const { productName, baseEnvUrl, baseServicesUrl, carbonTheme = "g10", className, navLinks, platform, prefixName = "", rightPanel, skipToContentProps, templateMeteringEvent, triggerEvent, userTeams, } = props;
57
+ const { analyticsHelpers, productName, baseEnvUrl, baseServicesUrl, carbonTheme = "g10", className, createJoinTeamTrigger, history, isLaunchpad = false, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, navLinks, platform, prefixName = "", rightPanel, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, user, userTeams, } = props;
58
+ const hasUserTeams = Boolean(userTeams);
59
+ const userTeamsUrl = serviceUrl.getUserTeamsServices({ baseServicesUrl });
60
+ const teamsQuery = useQuery({
61
+ queryKey: userTeamsUrl,
62
+ queryFn: resolver.query(userTeamsUrl, null),
63
+ enabled: !hasUserTeams && Boolean(baseServicesUrl),
64
+ });
52
65
  return (React.createElement(React.Fragment, null,
53
66
  React.createElement(Theme, { theme: carbonTheme },
54
67
  React.createElement(Header$1, { "aria-label": "App navigation header", className: className },
@@ -59,12 +72,13 @@ function Header(props) {
59
72
  ? navLinks.map((link) => (React.createElement(HeaderMenuItem, { "aria-label": `Link for ${link.name}`, "data-testid": "header-menu-link", href: link.url, isCurrentPage: window?.location?.href && link.url ? window.location.href.startsWith(link.url) : false, key: link.name, target: link.isExternal ? "_blank" : undefined, rel: link.isExternal ? "noopener noreferrer" : undefined }, link.name)))
60
73
  : null),
61
74
  React.createElement(HeaderGlobalBar, null,
75
+ React.createElement(HeaderTeamSwitcher, { analyticsHelpers: analyticsHelpers, baseServicesUrl: baseServicesUrl, createJoinTeamTrigger: createJoinTeamTrigger, history: history, isLaunchpad: isLaunchpad, isLoadingTeamSwitcher: isLoadingTeamSwitcher, isSuccessTeamSwitcher: isSuccessTeamSwitcher, setIsSuccessTeamSwitcher: setIsSuccessTeamSwitcher, menuAriaLabelRecord: MenuAriaLabelRecord.TeamSwitcher, menuButtonId: MenuButtonId.TeamSwitcher, menuListId: MenuListId.TeamSwitcher, navigationPlatform: platform, teamsQuery: teamsQuery, trackEvent: trackEvent, user: user, userTeams: userTeams }),
62
76
  props?.instanceSwitcherEnabled && (React.createElement(InstanceSwitcherMenu, { enabled: Boolean(props.instanceSwitcherEnabled), menuItems: platform?.instances })),
63
77
  React.createElement(RequestsMenu, { baseEnvUrl: baseEnvUrl, enabled: Boolean(props.requestSummary), summary: props.requestSummary }),
64
78
  React.createElement(NotificationsMenu, { baseEnvUrl: baseEnvUrl, baseServicesUrl: baseServicesUrl, enabled: Boolean(props.enableNotifications), countEnabled: Boolean(props.enableNotificationsCount) }),
65
79
  React.createElement(SupportMenu, { enabled: Array.isArray(props.supportMenuItems) && props.supportMenuItems.length > 0, menuItems: props.supportMenuItems }),
66
80
  React.createElement(ProfileMenu, { enabled: Array.isArray(props.profileMenuItems) && props.profileMenuItems.length > 0, menuItems: props.profileMenuItems }),
67
- React.createElement(AppSwitcherMenu, { baseEnvUrl: baseEnvUrl, baseServicesUrl: baseServicesUrl, enabled: props.enableAppSwitcher, templateMeteringEvent: templateMeteringEvent, triggerEvent: triggerEvent, userTeams: userTeams }),
81
+ React.createElement(AppSwitcherMenu, { baseEnvUrl: baseEnvUrl, baseServicesUrl: baseServicesUrl, enabled: props.enableAppSwitcher, teamsQuery: teamsQuery, templateMeteringEvent: templateMeteringEvent, triggerEvent: triggerEvent, userTeams: userTeams }),
68
82
  React.createElement(RightPanelMenu, { enabled: Boolean(rightPanel && Object.keys(rightPanel).length), ...rightPanel })))),
69
83
  React.createElement(NotificationsContainer, { enableMultiContainer: true, containerId: `${prefix}--bmrg-header-notifications` })));
70
84
  }
@@ -145,7 +159,7 @@ function AppSwitcherMenu(props) {
145
159
  }
146
160
  return (React.createElement("div", { ref: ref },
147
161
  React.createElement("button", { "aria-controls": MenuListId.Switcher, "aria-expanded": isOpen, "aria-haspopup": "menu", "aria-label": MenuAriaLabelRecord.Switcher, className: headerButtonClassNames, "data-testid": "header-appswitcher-link", id: MenuButtonId.Switcher, onClick: toggleActive }, isOpen ? React.createElement(Close, { size: 20 }) : React.createElement(Switcher, { size: 20 })),
148
- React.createElement(HeaderAppSwitcher, { baseEnvUrl: props.baseEnvUrl, baseServicesUrl: props.baseServicesUrl, id: MenuListId.Switcher, isOpen: isOpen, templateMeteringEvent: props.templateMeteringEvent, triggerEvent: props.triggerEvent, userTeams: props.userTeams })));
162
+ React.createElement(HeaderAppSwitcher, { baseEnvUrl: props.baseEnvUrl, baseServicesUrl: props.baseServicesUrl, id: MenuListId.Switcher, isOpen: isOpen, teamsQuery: props.teamsQuery, templateMeteringEvent: props.templateMeteringEvent, triggerEvent: props.triggerEvent, userTeams: props.userTeams })));
149
163
  }
150
164
  function RightPanelMenu(props) {
151
165
  const { isOpen, toggleActive, ref } = useHeaderMenu(MenuButtonId.RightPanel);
@@ -1,10 +1,8 @@
1
1
  import React from 'react';
2
- import { useQuery } from 'react-query';
3
2
  import { HeaderPanel, SkeletonText, SwitcherDivider, SideNavMenu, SideNavMenuItem } from '@carbon/react';
4
3
  import { Launch } from '@carbon/react/icons';
5
4
  import Error from '../ErrorMessage/ErrorMessage.js';
6
5
  import cx from 'classnames';
7
- import { resolver, serviceUrl } from '../../config/servicesConfig.js';
8
6
  import { prefix } from '../../internal/settings.js';
9
7
 
10
8
  /*
@@ -19,14 +17,8 @@ const externalProps = {
19
17
  const panelClassName = `${prefix}--bmrg-header-switcher-panel`;
20
18
  const contentClassName = `${prefix}--bmrg-header-switcher`;
21
19
  const skeletonClassName = `${prefix}--bmrg-header-switcher__skeleton`;
22
- function HeaderAppSwitcher({ baseServicesUrl, baseEnvUrl, id, isOpen, templateMeteringEvent, triggerEvent, userTeams }) {
20
+ function HeaderAppSwitcher({ baseServicesUrl, baseEnvUrl, id, isOpen, teamsQuery, templateMeteringEvent, triggerEvent, userTeams, }) {
23
21
  const hasUserTeams = Boolean(userTeams);
24
- const userTeamsUrl = serviceUrl.getUserTeamsServices({ baseServicesUrl });
25
- const teamsQuery = useQuery({
26
- queryKey: userTeamsUrl,
27
- queryFn: resolver.query(userTeamsUrl, null),
28
- enabled: !hasUserTeams
29
- });
30
22
  if (userTeams?.isLoading || teamsQuery?.isLoading) {
31
23
  return (React.createElement(HeaderPanel, { "aria-label": "App Switcher", className: panelClassName, expanded: isOpen, id: id, role: "menu" },
32
24
  React.createElement("div", { className: cx(contentClassName, "--is-loading", { "--is-hidden": !isOpen }) },
@@ -69,7 +61,7 @@ function HeaderAppSwitcher({ baseServicesUrl, baseEnvUrl, id, isOpen, templateMe
69
61
  }
70
62
  return null;
71
63
  }
72
- function TeamServiceListMenu({ baseEnvUrl, isAccount, isMember, team, templateMeteringEvent, triggerEvent }) {
64
+ function TeamServiceListMenu({ baseEnvUrl, isAccount, isMember, team, templateMeteringEvent, triggerEvent, }) {
73
65
  const { name, displayName, services } = team;
74
66
  const nameToDisplay = displayName ? displayName : name;
75
67
  const isNameTruncated = nameToDisplay?.length > 30;