@boomerang-io/carbon-addons-boomerang-react 4.6.11-beta.3 → 4.6.11-beta.31

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
 
@@ -11,26 +11,66 @@ IBM Confidential
11
11
  694970X, 69497O0
12
12
  © Copyright IBM Corp. 2022, 2024
13
13
  */
14
+ const SideNavUrlKeys = {
15
+ Home: "home",
16
+ TeamPage: "teamPage",
17
+ Chat: "chat",
18
+ Tools: "tools",
19
+ AgentStudio: "agentStudio",
20
+ AgentLibrary: "agentLibrary",
21
+ DocumentCollections: "documentCollections",
22
+ Catalog: "catalog",
23
+ Settings: "settings",
24
+ Admin: "admin",
25
+ };
14
26
  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("");
27
+ const { app, appLink, agenticAppsPath = "", agentStudioPath = "", regionalTeam, enableChatButton = true, showChatButton = true, showSelectTeamPurpose = false, defaultAssistantLink, joinCreateTrigger, isLoading, isOpen, teams = [], triggerEvent, accounts = [], baseEnvUrl, className, navLinks, personalTeams = [], user, showChatTooltip, templateMeteringEvent, tooltipMessage, isLaunchpad = false, sideNavUrls, history, children, personalTeamEnabled, ...rest } = props;
17
28
  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);
21
29
  const isMenuOpen = isOpen || activeMenu;
22
30
  const windowLocation = window.location;
23
31
  const isPartnerUser = user?.type === USER_PLATFORM_ROLE.Partner;
32
+ const defaultTeamHasAssistantsAccess = user?.defaultTeamHasAssistantsAccess;
24
33
  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
34
  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([]);
35
+ const homeLink = sideNavUrls?.find((sideNavUrl) => sideNavUrl.key === SideNavUrlKeys.Home)?.url;
36
+ const chatLink = sideNavUrls?.find((sideNavUrl) => sideNavUrl.key === SideNavUrlKeys.Chat)?.url;
37
+ const toolsLink = sideNavUrls?.find((sideNavUrl) => sideNavUrl.key === SideNavUrlKeys.Tools)?.url;
38
+ const agentAssistantStudioLink = sideNavUrls?.find((sideNavUrl) => sideNavUrl.key === SideNavUrlKeys.AgentStudio)?.url;
39
+ const agentAssistantLibraryLink = sideNavUrls?.find((sideNavUrl) => sideNavUrl.key === SideNavUrlKeys.AgentLibrary)?.url;
40
+ const documentCollectionsLink = sideNavUrls?.find((sideNavUrl) => sideNavUrl.key === SideNavUrlKeys.DocumentCollections)?.url;
41
+ const catalogNavlink = sideNavUrls?.find((sideNavUrl) => sideNavUrl.key === SideNavUrlKeys.Catalog)?.url;
42
+ const settingsLink = sideNavUrls?.find((sideNavUrl) => sideNavUrl.key === SideNavUrlKeys.Settings)?.url;
43
+ const adminNavlink = sideNavUrls?.find((sideNavUrl) => sideNavUrl.key === SideNavUrlKeys.Admin)?.url;
44
+ // get current selected team
45
+ let teamSwitcherTeam = null;
46
+ if (Array.isArray(personalTeams) && personalTeams.length > 0) {
47
+ personalTeams.forEach((team) => {
48
+ if (team.id === user?.teamInstanceSwitcherDefault) {
49
+ teamSwitcherTeam = { ...team, isPersonal: true };
50
+ }
51
+ });
52
+ }
53
+ if (Array.isArray(teams) && teams.length > 0) {
54
+ teams.forEach((team) => {
55
+ if (team.id === user?.teamInstanceSwitcherDefault) {
56
+ teamSwitcherTeam = { ...team, isStandard: true };
57
+ }
58
+ });
59
+ }
60
+ if (Array.isArray(accounts) && accounts.length > 0) {
61
+ accounts.forEach((account) => {
62
+ if (account.id === user?.teamInstanceSwitcherDefault) {
63
+ teamSwitcherTeam = { ...account, isAccount: true };
64
+ }
65
+ else if (Array.isArray(account.projectTeams) && account.projectTeams.length > 0) {
66
+ account.projectTeams.forEach((projectTeam) => {
67
+ if (projectTeam.id === user?.teamInstanceSwitcherDefault) {
68
+ teamSwitcherTeam = { ...projectTeam, isProject: true };
69
+ }
70
+ });
71
+ }
72
+ });
73
+ }
34
74
  // Functions to track IBM Instrumentation on Segment
35
75
  const handleHomeClick = () => {
36
76
  triggerEvent &&
@@ -40,24 +80,57 @@ function AdvantageSideNav(props) {
40
80
  destinationPath: homeLink,
41
81
  });
42
82
  };
43
- const handleRegionalNewStartNewChat = (team) => {
44
- const assistantLink = `${appLink?.newChatRedirect()}?teamName=${team.name}&teamId=${team.id}`;
45
- window.open(assistantLink, "_self", "noopener,noreferrer");
83
+ const handleToolsClick = () => {
84
+ triggerEvent &&
85
+ triggerEvent({
86
+ action: "Clicked on SideNav Tools link",
87
+ category: "Sidenav",
88
+ destinationPath: toolsLink,
89
+ });
46
90
  };
47
- 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
- }
91
+ const handleAgentAssistantStudioClick = () => {
92
+ triggerEvent &&
93
+ triggerEvent({
94
+ action: "Clicked on SideNav Agent & Assistant Studio link",
95
+ category: "Sidenav",
96
+ destinationPath: agentAssistantStudioLink,
97
+ });
98
+ };
99
+ const handleAgentAssistantLibraryClick = () => {
100
+ triggerEvent &&
101
+ triggerEvent({
102
+ action: "Clicked on SideNav Agent & Assistant Library link",
103
+ category: "Sidenav",
104
+ destinationPath: agentAssistantLibraryLink,
105
+ });
106
+ };
107
+ const handleDocumentCollectionsClick = () => {
108
+ triggerEvent &&
109
+ triggerEvent({
110
+ action: "Clicked on SideNav Document Collections link",
111
+ category: "Sidenav",
112
+ destinationPath: documentCollectionsLink,
113
+ });
114
+ };
115
+ const handleSettingsClick = () => {
116
+ triggerEvent &&
117
+ triggerEvent({
118
+ action: "Clicked on SideNav Settings link",
119
+ category: "Sidenav",
120
+ destinationPath: settingsLink,
121
+ });
122
+ };
123
+ const handleChatClick = () => {
124
+ let redirectLink = chatLink
125
+ ? chatLink
126
+ : `${appLink.newChatRedirect()}?teamName=${teamSwitcherTeam.name}&teamId=${teamSwitcherTeam.id}`;
55
127
  triggerEvent &&
56
128
  triggerEvent({
57
- action: "Clicked on SideNav Assistant link",
129
+ action: "Clicked on SideNav Chat link",
58
130
  category: "Sidenav",
59
- destinationPath: assistantLink,
131
+ destinationPath: redirectLink,
60
132
  });
133
+ window.open(redirectLink, "_self", "noopener,noreferrer");
61
134
  };
62
135
  const handleCreateJoinClick = () => {
63
136
  triggerEvent &&
@@ -78,60 +151,27 @@ function AdvantageSideNav(props) {
78
151
  teamType: type,
79
152
  });
80
153
  };
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
154
  const handleLaunchpadLink = (event) => {
93
155
  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
156
  //@ts-ignore
106
157
  if (Boolean(hamburguerMenu) && hamburguerMenu.className.includes("active")) {
107
158
  //@ts-ignore
108
159
  Boolean(hamburguerMenu) && hamburguerMenu?.click();
109
160
  }
110
161
  setActiveMenu(false);
111
- setActiveSubmenu("");
112
162
  };
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
- 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`));
163
+ const chatSideNavLink = (React.createElement(SideNavLink, { "data-testid": "sidenav-chat-link", className: !enableChatButton ? `${prefix}--bmrg-advantage-sidenav__inactive-link` : "", disabled: Boolean(!enableChatButton), renderIcon: ChatBot, href: enableChatButton && chatLink, onClick: enableChatButton ? handleChatClick : (e) => e.preventDefault() }, "Chat"));
164
+ const showSecondDivider = (!isPartnerUser && showChatButton) ||
165
+ toolsLink ||
166
+ agentAssistantStudioLink ||
167
+ agentAssistantLibraryLink ||
168
+ documentCollectionsLink;
125
169
  return (React.createElement(SideNav, { "aria-label": "sidenav-container", className: cx(`${prefix}--bmrg-advantage-sidenav-container`, className, {
126
170
  "--closed": !isMenuOpen,
127
- }), "data-testid": "sidenav-container", isRail: true, expanded: isMenuOpen, onToggle: () => setActiveSubmenu(""), onMouseEnter: () => setActiveMenu(true), onMouseLeave: () => {
171
+ }), "data-testid": "sidenav-container", isRail: true, expanded: isMenuOpen, onMouseEnter: () => setActiveMenu(true), onMouseLeave: () => {
128
172
  setActiveMenu(false);
129
- setActiveSubmenu("");
130
173
  }, ...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("") },
174
+ React.createElement("div", null,
135
175
  homeLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-home-link", isActive: `${baseEnvUrl}/${app}/`.includes(windowLocation.href), renderIcon: Home, href: homeLink, onClick: (e) => {
136
176
  if (isLaunchpad) {
137
177
  handleLaunchpadLink(e);
@@ -139,116 +179,56 @@ function AdvantageSideNav(props) {
139
179
  }
140
180
  handleHomeClick();
141
181
  } }, "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
- React.createElement(TooltipHover, { className: `${prefix}--bmrg-side-nav__tooltip`, content: tooltipMessage, direction: "right" },
148
- React.createElement("span", null, assistantSideNavLink)),
149
- regionalModalIsOpen && React.createElement(ComposedModal, { className: `${prefix}--teamSelectionModalContainer`, open: regionalModalIsOpen, onClose: () => setRegionalModalIsOpen(false), onKeyDown: (e) => e.stopPropagation(), "data-testid": "select-team-chat-modal" },
150
- React.createElement(ModalHeader, { title: "Select Team to Start a New Chat", closeModal: () => setRegionalModalIsOpen(false) }),
151
- React.createElement(ModalBody, { className: `${prefix}--teamSelectModalBody` },
152
- 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) })),
153
- React.createElement(ModalFooter, null,
154
- React.createElement(Button, { kind: "secondary", "data-testid": "select-team-chat-modal-cancel-button", onClick: () => setRegionalModalIsOpen(false) }, "Cancel"),
155
- React.createElement(Button, { "data-modal-primary-focus": true, kind: "primary", disabled: !selectedTeam, "data-testid": "select-team-chat-modal-continue-button", onClick: () => {
156
- if (selectedTeam) {
157
- handleRegionalNewStartNewChat(selectedTeam);
158
- setRegionalModalIsOpen(false);
159
- // closeModal();
160
- }
161
- } }, "Continue"))),
162
- !isPartnerUser && joinCreateTrigger ? (React.createElement(SideNavLink, { "data-testid": "sidenav-create-join-trigger", renderIcon: AddAlt, onClick: (e) => {
182
+ 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) => {
183
+ if (isLaunchpad) {
184
+ handleLaunchpadLink(e);
185
+ history.push(`/teams/${teamSwitcherTeam.id}`);
186
+ }
187
+ handleTeamClick({
188
+ team: teamSwitcherTeam,
189
+ type: teamSwitcherTeam.isPersonal
190
+ ? "personal"
191
+ : teamSwitcherTeam.isAccount
192
+ ? "account"
193
+ : teamSwitcherTeam.isproject
194
+ ? "project"
195
+ : "standard",
196
+ });
197
+ } },
198
+ 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) => {
163
199
  joinCreateTrigger(e);
164
200
  handleCreateJoinClick();
165
- } }, joinButtontitle)) : null),
166
- children ? (React.createElement(React.Fragment, null,
201
+ } }, joinButtontitle)) : null,
167
202
  React.createElement(SideNavDivider, null),
168
- children)) : null,
169
- userTeamsLoading && isMenuOpen ? (React.createElement(React.Fragment, null,
170
- React.createElement(SideNavDivider, null),
171
- React.createElement("div", { className: `${prefix}--bmrg-advantage-sidenav-loading-container` },
172
- React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` }),
173
- React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` }),
174
- React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` })))) : null,
175
- ((!Boolean(standardTeamsList?.length) && !Boolean(accounts?.length) && !userTeamsLoading) ||
176
- userTeamsError) &&
177
- isMenuOpen ? (React.createElement(React.Fragment, null,
178
- React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-no-teams__text` }, noTeamsMessage))) : null,
179
- Boolean(standardTeamsList?.length) ? (React.createElement(React.Fragment, null,
180
- React.createElement(SideNavDivider, null),
181
- React.createElement(SideNavMenu, { className: cx(`${prefix}--bmrg-advantage-sidenav-menu`, {
182
- "--active-closed": !isMenuOpen && standardTeamsList.some((t) => windowLocation.href.includes(t.id)),
183
- }), 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
184
- ? standardTeamsList?.map((team, i) => {
185
- const topPosition = document?.getElementById(team.id)?.getBoundingClientRect()?.top ?? 0;
186
- const teamDisplayName = Boolean(team.displayName) ? team.displayName : team.name;
187
- return (React.createElement(React.Fragment, null,
188
- React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-team-item` },
189
- 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) => {
190
- if (isLaunchpad) {
191
- handleLaunchpadLink(e);
192
- history.push(`/teams/${team.id}`);
193
- }
194
- handleTeamClick({ team, type: team.isPersonal ? "personal" : "standard" });
195
- } },
196
- React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-teams__title` }, teamDisplayName),
197
- Boolean(team?.services?.length) ? React.createElement(ChevronRight, null) : null),
198
- Boolean(team?.services?.length) && team.id === activeSubmenu ? (React.createElement("ul", { className: cx(`${prefix}--bmrg-advantage-sidenav-submenu`, {
199
- "--open": team.id === activeSubmenu,
200
- }), style: { top: `${window.scrollY + topPosition}px` } },
201
- React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-submenu-wrapper` },
202
- React.createElement("ul", { className: `${prefix}--bmrg-advantage-sidenav-services-submenu` },
203
- 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) => {
204
- if (isLaunchpad) {
205
- handleLaunchpadLink(e);
206
- history.push(`/teams/${team.id}`);
207
- }
208
- handleTeamClick({ team, type: team.isPersonal ? "personal" : "standard" });
209
- } }, "Team Page"),
210
- 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)));
211
- })
212
- : null))) : null,
213
- Boolean(accounts?.length) ? (React.createElement(React.Fragment, null,
203
+ defaultTeamHasAssistantsAccess && personalTeamEnabled && showChatButton &&
204
+ (showChatTooltip ? (React.createElement(TooltipHover, { className: `${prefix}--bmrg-side-nav__tooltip`, content: tooltipMessage, direction: "right" },
205
+ React.createElement("span", null, chatSideNavLink))) : (chatSideNavLink)),
206
+ toolsLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-tools-link", renderIcon: Api, href: toolsLink, onClick: (e) => {
207
+ handleToolsClick();
208
+ } }, "Tools")) : null,
209
+ agentAssistantStudioLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-agent-assistant-studio-link", isActive: (agentStudioPath && windowLocation.href.includes(`/launchpad${agentStudioPath}`)) ||
210
+ (agenticAppsPath && windowLocation.href.includes(`/launchpad${agenticAppsPath}`)), renderIcon: IntentRequestCreate, href: agentAssistantStudioLink, onClick: (e) => {
211
+ if (isLaunchpad) {
212
+ handleLaunchpadLink(e);
213
+ history.push(agentStudioPath);
214
+ }
215
+ handleAgentAssistantStudioClick();
216
+ } }, "Agent & Assistant Studio")) : null,
217
+ agentAssistantLibraryLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-agent-assistant-library-link", renderIcon: Folders, href: agentAssistantLibraryLink, onClick: (e) => {
218
+ handleAgentAssistantLibraryClick();
219
+ } }, "Agent & Assistant Library")) : null,
220
+ documentCollectionsLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-document-collections-link", renderIcon: DocumentMultiple_02, href: documentCollectionsLink, onClick: (e) => {
221
+ handleDocumentCollectionsClick();
222
+ } }, "Document Collections")) : null,
223
+ showSecondDivider ? React.createElement(SideNavDivider, null) : null,
224
+ catalogNavlink ? (React.createElement(SideNavLink, { href: catalogNavlink, renderIcon: Catalog }, "Catalog")) : null,
225
+ settingsLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-settings-link", renderIcon: Settings, href: settingsLink, onClick: (e) => {
226
+ handleSettingsClick();
227
+ } }, "Settings")) : null,
228
+ adminNavlink ? (React.createElement(SideNavLink, { href: adminNavlink, renderIcon: LicenseThirdParty }, "Admin")) : null),
229
+ children ? (React.createElement(React.Fragment, null,
214
230
  React.createElement(SideNavDivider, null),
215
- React.createElement(SideNavMenu, { className: cx(`${prefix}--bmrg-advantage-sidenav-menu`, {
216
- "--active-closed": !isMenuOpen &&
217
- accounts.some((t) => {
218
- const pIds = t?.projectTeams?.map((project) => project.id) ?? [];
219
- return windowLocation.href.includes(t.id) || pIds.some((id) => windowLocation.href.includes(id));
220
- }),
221
- }), renderIcon: GroupAccount, title: "Accounts", "data-testid": "sidenav-accounts", id: "sidenav-accounts", ref: accountsMenuRef, "aria-expanded": isMenuOpen, isSideNavExpanded: isMenuOpen }, isMenuOpen
222
- ? accounts?.map((team, i) => {
223
- const topPosition = document?.getElementById(team.id)?.getBoundingClientRect()?.top ?? 0;
224
- const teamDisplayName = Boolean(team.displayName) ? team.displayName : team.name;
225
- const projectIds = team?.projectTeams?.map((project) => project.id) ?? [];
226
- const isAccountActive = windowLocation.href.includes(team.id) ||
227
- projectIds.some((id) => windowLocation.href.includes(id));
228
- return (React.createElement(React.Fragment, null,
229
- React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-team-item` },
230
- 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) => {
231
- if (isLaunchpad) {
232
- handleLaunchpadLink(e);
233
- history.push(`/teams/${team.id}`);
234
- }
235
- handleTeamClick({ team, type: "account" });
236
- } },
237
- React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-teams__title` }, teamDisplayName),
238
- Boolean(team?.projectTeams?.length) ? React.createElement(ChevronRight, null) : null),
239
- Boolean(team?.projectTeams?.length) && team.id === activeSubmenu ? (React.createElement("ul", { className: cx(`${prefix}--bmrg-advantage-sidenav-submenu`, {
240
- "--open": team.id === activeSubmenu,
241
- }), style: { top: `${window.scrollY + topPosition}px` } },
242
- React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-submenu-wrapper` },
243
- 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) => {
244
- if (isLaunchpad) {
245
- handleLaunchpadLink(e);
246
- history.push(`/teams/${accTeam.id}`);
247
- }
248
- handleTeamClick({ team: accTeam, type: "project" });
249
- } }, accTeam.name))) ?? null)))) : null)));
250
- })
251
- : null))) : null)));
231
+ children)) : null)));
252
232
  }
253
233
 
254
234
  export { AdvantageSideNav, AdvantageSideNav as default };
@@ -15,20 +15,17 @@ function Feedback(props) {
15
15
  React.createElement(ModalBody, null,
16
16
  React.createElement("div", { className: `${prefix}--bmrg-feedback` },
17
17
  React.createElement("p", null,
18
- "Share your thoughts and ideas on what we can do to improve the ",
19
- props.platformName,
20
- " platform and our onboarding process."),
21
- React.createElement("p", null,
22
- "To submit your idea, visit our portal at",
18
+ "Have an idea on how we can improve Consulting Advantage? Submit your idea",
23
19
  " " /* We need to force a space before the link tag */,
24
- React.createElement("a", { "aria-describedby": "new-window-aria-desc-0", href: props.sendIdeasUrl, target: "_blank", rel: "noopener noreferrer" }, props.sendIdeasUrl),
25
- "."),
20
+ React.createElement("a", { "aria-describedby": "new-window-aria-desc-0", href: props.sendIdeasUrl, target: "_blank", rel: "noopener noreferrer" }, "here"),
21
+ ". You\u2019ll be able to see other public ideas, vote on them, and track the status of your idea."),
26
22
  React.createElement("p", null,
27
- "For now, you must have an ",
28
- props.platformOrganization,
29
- " email address and you will need to register with a password during your first visit."),
30
- React.createElement("p", null, "You will have the opportunity to see other public ideas, vote on them and track the status of your idea."),
31
- React.createElement("p", null, "We look forward to your feedback!"))),
23
+ "Have an innovative new asset, assistant, or automation you've built outside of ICA?",
24
+ " " /* We need to force a space before the link tag */,
25
+ "Submit your idea ",
26
+ React.createElement("a", { "aria-describedby": "new-window-aria-desc-0", href: props.sendIdeasUrl, target: "_blank", rel: "noopener noreferrer" }, "here"),
27
+ " and you could win a BluePoints award."),
28
+ React.createElement("p", null, "We look forward to your feedback and ideas!\""))),
32
29
  React.createElement(ModalFooter, null,
33
30
  React.createElement(Button, { "data-modal-primary-focus": true, kind: "primary", onClick: props.closeModal }, "OK"))));
34
31
  }
@@ -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;