@boomerang-io/carbon-addons-boomerang-react 4.6.11-beta.8 → 4.6.11-beta.9
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.
- package/dist/cjs/components/AdvantageSideNav/AdvantageSideNav.js +129 -140
- package/dist/cjs/components/Header/Header.js +18 -4
- package/dist/cjs/components/Header/HeaderAppSwitcher.js +2 -10
- package/dist/cjs/components/Header/HeaderTeamSwitcher.js +324 -0
- package/dist/cjs/components/UIShell/UIShell.js +9 -4
- package/dist/esm/components/AdvantageSideNav/AdvantageSideNav.js +131 -142
- package/dist/esm/components/Header/Header.js +18 -4
- package/dist/esm/components/Header/HeaderAppSwitcher.js +2 -10
- package/dist/esm/components/Header/HeaderTeamSwitcher.js +315 -0
- package/dist/esm/components/UIShell/UIShell.js +10 -5
- package/dist/types/index.d.ts +102 -1
- package/package.json +1 -1
- package/scss/components/Header/_headerTeamSwitcher.scss +195 -0
- package/scss/global/index.scss +7 -8
|
@@ -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, Dropdown, ModalFooter, Button
|
|
3
|
+
import { SideNavLink, SideNav, SideNavItems, SideNavDivider, ComposedModal, ModalHeader, ModalBody, Dropdown, ModalFooter, Button } from '@carbon/react';
|
|
4
4
|
import TooltipHover from '../TooltipHover/TooltipHover.js';
|
|
5
|
-
import { ChatBot, Home, AddAlt,
|
|
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,8 +12,7 @@ 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,
|
|
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
17
|
const [teamList, setTeamList] = React.useState(null);
|
|
19
18
|
const [regionalModalIsOpen, setRegionalModalIsOpen] = React.useState(false);
|
|
@@ -22,15 +21,37 @@ function AdvantageSideNav(props) {
|
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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 &&
|
|
@@ -44,6 +65,46 @@ function AdvantageSideNav(props) {
|
|
|
44
65
|
const assistantLink = `${appLink?.newChatRedirect()}?teamName=${team.name}&teamId=${team.id}`;
|
|
45
66
|
window.open(assistantLink, "_self", "noopener,noreferrer");
|
|
46
67
|
};
|
|
68
|
+
const handleToolsClick = () => {
|
|
69
|
+
triggerEvent &&
|
|
70
|
+
triggerEvent({
|
|
71
|
+
action: "Clicked on SideNav Tools link",
|
|
72
|
+
category: "Sidenav",
|
|
73
|
+
destinationPath: toolsLink,
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
const handleAgentAssistantStudioClick = () => {
|
|
77
|
+
triggerEvent &&
|
|
78
|
+
triggerEvent({
|
|
79
|
+
action: "Clicked on SideNav Agent & Assistant Studio link",
|
|
80
|
+
category: "Sidenav",
|
|
81
|
+
destinationPath: agentAssistantStudioLink,
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
const handleAgentAssistantLibraryClick = () => {
|
|
85
|
+
triggerEvent &&
|
|
86
|
+
triggerEvent({
|
|
87
|
+
action: "Clicked on SideNav Agent & Assistant Library link",
|
|
88
|
+
category: "Sidenav",
|
|
89
|
+
destinationPath: agentAssistantLibraryLink,
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
const handleDocumentCollectionsClick = () => {
|
|
93
|
+
triggerEvent &&
|
|
94
|
+
triggerEvent({
|
|
95
|
+
action: "Clicked on SideNav Document Collections link",
|
|
96
|
+
category: "Sidenav",
|
|
97
|
+
destinationPath: documentCollectionsLink,
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
const handleSettingsClick = () => {
|
|
101
|
+
triggerEvent &&
|
|
102
|
+
triggerEvent({
|
|
103
|
+
action: "Clicked on SideNav Settings link",
|
|
104
|
+
category: "Sidenav",
|
|
105
|
+
destinationPath: settingsLink,
|
|
106
|
+
});
|
|
107
|
+
};
|
|
47
108
|
const handleAssistantClick = () => {
|
|
48
109
|
if (regionalTeam?.length > 1) {
|
|
49
110
|
setRegionalModalIsOpen(true);
|
|
@@ -78,60 +139,31 @@ function AdvantageSideNav(props) {
|
|
|
78
139
|
teamType: type,
|
|
79
140
|
});
|
|
80
141
|
};
|
|
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
142
|
const handleLaunchpadLink = (event) => {
|
|
93
143
|
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
144
|
//@ts-ignore
|
|
106
145
|
if (Boolean(hamburguerMenu) && hamburguerMenu.className.includes("active")) {
|
|
107
146
|
//@ts-ignore
|
|
108
147
|
Boolean(hamburguerMenu) && hamburguerMenu?.click();
|
|
109
148
|
}
|
|
110
149
|
setActiveMenu(false);
|
|
111
|
-
setActiveSubmenu("");
|
|
112
150
|
};
|
|
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
151
|
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) :
|
|
152
|
+
// assistantLink &&
|
|
153
|
+
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() }, "Chat"));
|
|
154
|
+
const catalogNavlink = navigation?.navigation?.find((navlink) => navlink.name === "Catalog");
|
|
155
|
+
const adminNavlink = navigation?.navigation?.find((navlink) => navlink.name === "Admin");
|
|
156
|
+
const showSecondDivider = (!isPartnerUser && showChatButton) ||
|
|
157
|
+
toolsLink ||
|
|
158
|
+
agentAssistantStudioLink ||
|
|
159
|
+
agentAssistantLibraryLink ||
|
|
160
|
+
documentCollectionsLink;
|
|
125
161
|
return (React.createElement(SideNav, { "aria-label": "sidenav-container", className: cx(`${prefix}--bmrg-advantage-sidenav-container`, className, {
|
|
126
162
|
"--closed": !isMenuOpen,
|
|
127
|
-
}), "data-testid": "sidenav-container", isRail: true, expanded: isMenuOpen,
|
|
163
|
+
}), "data-testid": "sidenav-container", isRail: true, expanded: isMenuOpen, onMouseEnter: () => setActiveMenu(true), onMouseLeave: () => {
|
|
128
164
|
setActiveMenu(false);
|
|
129
|
-
setActiveSubmenu("");
|
|
130
165
|
}, ...rest }, React.createElement(SideNavItems, null,
|
|
131
|
-
|
|
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("") },
|
|
166
|
+
React.createElement("div", null,
|
|
135
167
|
homeLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-home-link", isActive: `${baseEnvUrl}/${app}/`.includes(windowLocation.href), renderIcon: Home, href: homeLink, onClick: (e) => {
|
|
136
168
|
if (isLaunchpad) {
|
|
137
169
|
handleLaunchpadLink(e);
|
|
@@ -139,12 +171,56 @@ function AdvantageSideNav(props) {
|
|
|
139
171
|
}
|
|
140
172
|
handleHomeClick();
|
|
141
173
|
} }, "Home")) : null,
|
|
174
|
+
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) => {
|
|
175
|
+
if (isLaunchpad) {
|
|
176
|
+
handleLaunchpadLink(e);
|
|
177
|
+
history.push(`/teams/${teamSwitcherTeam.id}`);
|
|
178
|
+
}
|
|
179
|
+
handleTeamClick({
|
|
180
|
+
team: teamSwitcherTeam,
|
|
181
|
+
type: teamSwitcherTeam.isPersonal
|
|
182
|
+
? "personal"
|
|
183
|
+
: teamSwitcherTeam.isAccount
|
|
184
|
+
? "account"
|
|
185
|
+
: teamSwitcherTeam.isproject
|
|
186
|
+
? "project"
|
|
187
|
+
: "standard",
|
|
188
|
+
});
|
|
189
|
+
} },
|
|
190
|
+
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) => {
|
|
191
|
+
joinCreateTrigger(e);
|
|
192
|
+
handleCreateJoinClick();
|
|
193
|
+
} }, joinButtontitle)) : null,
|
|
194
|
+
React.createElement(SideNavDivider, null),
|
|
142
195
|
!isPartnerUser &&
|
|
143
196
|
// assistantLink &&
|
|
144
197
|
showChatButton &&
|
|
145
198
|
(showChatTooltip ? (React.createElement(TooltipHover, { className: `${prefix}--bmrg-side-nav__tooltip`, content: tooltipMessage, direction: "right" },
|
|
146
199
|
React.createElement("span", null, assistantSideNavLink))) : (assistantSideNavLink)),
|
|
147
|
-
|
|
200
|
+
toolsLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-tools-link", renderIcon: Api, href: toolsLink, onClick: (e) => {
|
|
201
|
+
handleToolsClick();
|
|
202
|
+
} }, "Tools")) : null,
|
|
203
|
+
agentAssistantStudioLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-agent-assistant-studio-link", isActive: windowLocation.href.includes(`/launchpad/agent-assistant-studio`) ||
|
|
204
|
+
windowLocation.href.includes(`/launchpad/agenticapps`), renderIcon: IntentRequestCreate, href: agentAssistantStudioLink, onClick: (e) => {
|
|
205
|
+
if (isLaunchpad) {
|
|
206
|
+
handleLaunchpadLink(e);
|
|
207
|
+
history.push(agentAssistantStudioLink);
|
|
208
|
+
}
|
|
209
|
+
handleAgentAssistantStudioClick();
|
|
210
|
+
} }, "Agent & Assistant Studio")) : null,
|
|
211
|
+
agentAssistantLibraryLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-agent-assistant-library-link", renderIcon: Folders, href: agentAssistantLibraryLink, onClick: (e) => {
|
|
212
|
+
handleAgentAssistantLibraryClick();
|
|
213
|
+
} }, "Agent & Assistant Library")) : null,
|
|
214
|
+
documentCollectionsLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-document-collections-link", renderIcon: DocumentMultiple_02, href: documentCollectionsLink, onClick: (e) => {
|
|
215
|
+
handleDocumentCollectionsClick();
|
|
216
|
+
} }, "Document Collections")) : null,
|
|
217
|
+
showSecondDivider ? React.createElement(SideNavDivider, null) : null,
|
|
218
|
+
catalogNavlink ? (React.createElement(SideNavLink, { href: catalogNavlink.url, renderIcon: Catalog }, catalogNavlink.name)) : null,
|
|
219
|
+
settingsLink ? (React.createElement(SideNavLink, { "data-testid": "sidenav-settings-link", renderIcon: Settings, href: settingsLink, onClick: (e) => {
|
|
220
|
+
handleSettingsClick();
|
|
221
|
+
} }, "Settings")) : null,
|
|
222
|
+
adminNavlink ? (React.createElement(SideNavLink, { href: adminNavlink.url, renderIcon: LicenseThirdParty }, adminNavlink.name)) : null,
|
|
223
|
+
regionalModalIsOpen && (React.createElement(ComposedModal, { className: `${prefix}--teamSelectionModalContainer`, open: regionalModalIsOpen, onClose: () => setRegionalModalIsOpen(false), onKeyDown: (e) => e.stopPropagation(), "data-testid": "select-team-chat-modal" },
|
|
148
224
|
React.createElement(ModalHeader, { title: "Select Team to Start a New Chat", closeModal: () => setRegionalModalIsOpen(false) }),
|
|
149
225
|
React.createElement(ModalBody, { className: `${prefix}--teamSelectModalBody` },
|
|
150
226
|
React.createElement(Dropdown, { 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) })),
|
|
@@ -156,97 +232,10 @@ function AdvantageSideNav(props) {
|
|
|
156
232
|
setRegionalModalIsOpen(false);
|
|
157
233
|
// closeModal();
|
|
158
234
|
}
|
|
159
|
-
} }, "Continue"))),
|
|
160
|
-
!isPartnerUser && joinCreateTrigger ? (React.createElement(SideNavLink, { "data-testid": "sidenav-create-join-trigger", renderIcon: AddAlt, onClick: (e) => {
|
|
161
|
-
joinCreateTrigger(e);
|
|
162
|
-
handleCreateJoinClick();
|
|
163
|
-
} }, joinButtontitle)) : null),
|
|
235
|
+
} }, "Continue"))))),
|
|
164
236
|
children ? (React.createElement(React.Fragment, null,
|
|
165
237
|
React.createElement(SideNavDivider, null),
|
|
166
|
-
children)) : null
|
|
167
|
-
userTeamsLoading && isMenuOpen ? (React.createElement(React.Fragment, null,
|
|
168
|
-
React.createElement(SideNavDivider, null),
|
|
169
|
-
React.createElement("div", { className: `${prefix}--bmrg-advantage-sidenav-loading-container` },
|
|
170
|
-
React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` }),
|
|
171
|
-
React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` }),
|
|
172
|
-
React.createElement(SkeletonPlaceholder, { className: `${prefix}--bmrg-advantage-sidenav-loading` })))) : null,
|
|
173
|
-
((!Boolean(standardTeamsList?.length) && !Boolean(accounts?.length) && !userTeamsLoading) ||
|
|
174
|
-
userTeamsError) &&
|
|
175
|
-
isMenuOpen ? (React.createElement(React.Fragment, null,
|
|
176
|
-
React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-no-teams__text` }, noTeamsMessage))) : null,
|
|
177
|
-
Boolean(standardTeamsList?.length) ? (React.createElement(React.Fragment, null,
|
|
178
|
-
React.createElement(SideNavDivider, null),
|
|
179
|
-
React.createElement(SideNavMenu, { className: cx(`${prefix}--bmrg-advantage-sidenav-menu`, {
|
|
180
|
-
"--active-closed": !isMenuOpen && standardTeamsList.some((t) => windowLocation.href.includes(t.id)),
|
|
181
|
-
}), 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
|
|
182
|
-
? standardTeamsList?.map((team, i) => {
|
|
183
|
-
const topPosition = document?.getElementById(team.id)?.getBoundingClientRect()?.top ?? 0;
|
|
184
|
-
const teamDisplayName = Boolean(team.displayName) ? team.displayName : team.name;
|
|
185
|
-
return (React.createElement(React.Fragment, null,
|
|
186
|
-
React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-team-item` },
|
|
187
|
-
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) => {
|
|
188
|
-
if (isLaunchpad) {
|
|
189
|
-
handleLaunchpadLink(e);
|
|
190
|
-
history.push(`/teams/${team.id}`);
|
|
191
|
-
}
|
|
192
|
-
handleTeamClick({ team, type: team.isPersonal ? "personal" : "standard" });
|
|
193
|
-
} },
|
|
194
|
-
React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-teams__title` }, teamDisplayName),
|
|
195
|
-
Boolean(team?.services?.length) ? React.createElement(ChevronRight, null) : null),
|
|
196
|
-
Boolean(team?.services?.length) && team.id === activeSubmenu ? (React.createElement("ul", { className: cx(`${prefix}--bmrg-advantage-sidenav-submenu`, {
|
|
197
|
-
"--open": team.id === activeSubmenu,
|
|
198
|
-
}), style: { top: `${window.scrollY + topPosition}px` } },
|
|
199
|
-
React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-submenu-wrapper` },
|
|
200
|
-
React.createElement("ul", { className: `${prefix}--bmrg-advantage-sidenav-services-submenu` },
|
|
201
|
-
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) => {
|
|
202
|
-
if (isLaunchpad) {
|
|
203
|
-
handleLaunchpadLink(e);
|
|
204
|
-
history.push(`/teams/${team.id}`);
|
|
205
|
-
}
|
|
206
|
-
handleTeamClick({ team, type: team.isPersonal ? "personal" : "standard" });
|
|
207
|
-
} }, "Team Page"),
|
|
208
|
-
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)));
|
|
209
|
-
})
|
|
210
|
-
: null))) : null,
|
|
211
|
-
Boolean(accounts?.length) ? (React.createElement(React.Fragment, null,
|
|
212
|
-
React.createElement(SideNavDivider, null),
|
|
213
|
-
React.createElement(SideNavMenu, { className: cx(`${prefix}--bmrg-advantage-sidenav-menu`, {
|
|
214
|
-
"--active-closed": !isMenuOpen &&
|
|
215
|
-
accounts.some((t) => {
|
|
216
|
-
const pIds = t?.projectTeams?.map((project) => project.id) ?? [];
|
|
217
|
-
return windowLocation.href.includes(t.id) || pIds.some((id) => windowLocation.href.includes(id));
|
|
218
|
-
}),
|
|
219
|
-
}), renderIcon: GroupAccount, title: "Accounts", "data-testid": "sidenav-accounts", id: "sidenav-accounts", ref: accountsMenuRef, "aria-expanded": isMenuOpen, isSideNavExpanded: isMenuOpen }, isMenuOpen
|
|
220
|
-
? accounts?.map((team, i) => {
|
|
221
|
-
const topPosition = document?.getElementById(team.id)?.getBoundingClientRect()?.top ?? 0;
|
|
222
|
-
const teamDisplayName = Boolean(team.displayName) ? team.displayName : team.name;
|
|
223
|
-
const projectIds = team?.projectTeams?.map((project) => project.id) ?? [];
|
|
224
|
-
const isAccountActive = windowLocation.href.includes(team.id) ||
|
|
225
|
-
projectIds.some((id) => windowLocation.href.includes(id));
|
|
226
|
-
return (React.createElement(React.Fragment, null,
|
|
227
|
-
React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-team-item` },
|
|
228
|
-
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) => {
|
|
229
|
-
if (isLaunchpad) {
|
|
230
|
-
handleLaunchpadLink(e);
|
|
231
|
-
history.push(`/teams/${team.id}`);
|
|
232
|
-
}
|
|
233
|
-
handleTeamClick({ team, type: "account" });
|
|
234
|
-
} },
|
|
235
|
-
React.createElement("p", { className: `${prefix}--bmrg-advantage-sidenav-teams__title` }, teamDisplayName),
|
|
236
|
-
Boolean(team?.projectTeams?.length) ? React.createElement(ChevronRight, null) : null),
|
|
237
|
-
Boolean(team?.projectTeams?.length) && team.id === activeSubmenu ? (React.createElement("ul", { className: cx(`${prefix}--bmrg-advantage-sidenav-submenu`, {
|
|
238
|
-
"--open": team.id === activeSubmenu,
|
|
239
|
-
}), style: { top: `${window.scrollY + topPosition}px` } },
|
|
240
|
-
React.createElement("li", { className: `${prefix}--bmrg-advantage-sidenav-submenu-wrapper` },
|
|
241
|
-
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) => {
|
|
242
|
-
if (isLaunchpad) {
|
|
243
|
-
handleLaunchpadLink(e);
|
|
244
|
-
history.push(`/teams/${accTeam.id}`);
|
|
245
|
-
}
|
|
246
|
-
handleTeamClick({ team: accTeam, type: "project" });
|
|
247
|
-
} }, accTeam.name))) ?? null)))) : null)));
|
|
248
|
-
})
|
|
249
|
-
: null))) : null)));
|
|
238
|
+
children)) : null)));
|
|
250
239
|
}
|
|
251
240
|
|
|
252
241
|
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,
|
|
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;
|