@boomerang-io/carbon-addons-boomerang-react 4.6.14-beta.1 → 4.6.14-beta.11

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.
@@ -62,7 +62,7 @@ const MenuAriaLabelRecord = {
62
62
  const headerButtonClassNames = "cds--btn--icon-only cds--header__action cds--btn cds--btn--primary cds--btn--icon-only cds--btn cds--btn--primary";
63
63
  const instanceCheckMarkContainerClass = "instance-checkmark-style-container";
64
64
  function Header(props) {
65
- const { analyticsHelpers, productName, baseEnvUrl, baseServicesUrl, carbonTheme = "g10", className, createJoinTeamTrigger, history, isLaunchpad = false, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, navLinks, platform, prefixName = "", refetchUser, refetchNavigation, rightPanel, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, user, userTeams, userTeamsAssets, } = props;
65
+ const { analyticsHelpers, productName, baseEnvUrl, baseServicesUrl, carbonTheme = "g10", className, createJoinTeamTrigger, enableTeamSwitcher = true, history, isLaunchpad = false, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, navLinks, platform, prefixName = "", refetchUser, refetchNavigation, rightPanel, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, user, userTeams, userTeamsAssets, } = props;
66
66
  const hasUserTeams = Boolean(userTeams);
67
67
  const userTeamsUrl = servicesConfig.serviceUrl.getUserTeamsServices({ baseServicesUrl });
68
68
  const teamsQuery = reactQuery.useQuery({
@@ -70,6 +70,7 @@ function Header(props) {
70
70
  queryFn: servicesConfig.resolver.query(userTeamsUrl, null),
71
71
  enabled: !hasUserTeams && Boolean(baseServicesUrl),
72
72
  });
73
+ const showTeamSwitcher = enableTeamSwitcher && Boolean(user);
73
74
  return (React__default.default.createElement(React__default.default.Fragment, null,
74
75
  React__default.default.createElement(react.Theme, { theme: carbonTheme },
75
76
  React__default.default.createElement(react.Header, { "aria-label": "App navigation header", className: className },
@@ -80,7 +81,7 @@ function Header(props) {
80
81
  ? navLinks.map((link) => (React__default.default.createElement(react.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)))
81
82
  : null),
82
83
  React__default.default.createElement(react.HeaderGlobalBar, null,
83
- React__default.default.createElement(HeaderTeamSwitcher.default, { 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, refetchUser: refetchUser, refetchNavigation: refetchNavigation, teamsQuery: teamsQuery, trackEvent: trackEvent, user: user, userTeams: userTeams }),
84
+ showTeamSwitcher ? (React__default.default.createElement(HeaderTeamSwitcher.default, { 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, refetchUser: refetchUser, refetchNavigation: refetchNavigation, teamsQuery: teamsQuery, trackEvent: trackEvent, user: user, userTeams: userTeams })) : null,
84
85
  props?.instanceSwitcherEnabled && (React__default.default.createElement(InstanceSwitcherMenu, { enabled: Boolean(props.instanceSwitcherEnabled), menuItems: platform?.instances })),
85
86
  React__default.default.createElement(RequestsMenu, { baseEnvUrl: baseEnvUrl, enabled: Boolean(props.requestSummary), summary: props.requestSummary }),
86
87
  React__default.default.createElement(NotificationsMenu, { baseEnvUrl: baseEnvUrl, baseServicesUrl: baseServicesUrl, enabled: Boolean(props.enableNotifications), countEnabled: Boolean(props.enableNotificationsCount) }),
@@ -11,6 +11,7 @@ var HeaderMenu = require('./HeaderMenu.js');
11
11
  var servicesConfig = require('../../config/servicesConfig.js');
12
12
  var settings = require('../../internal/settings.js');
13
13
  var UserType = require('../../constants/UserType.js');
14
+ var TeamTypes = require('../../constants/TeamTypes.js');
14
15
 
15
16
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
17
 
@@ -97,6 +98,12 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
97
98
  await mutateUserProfile({ baseServicesUrl, body });
98
99
  }
99
100
  };
101
+ const handleNoTeamsToSelect = async () => {
102
+ const body = {
103
+ teamInstanceSwitcherDefault: null,
104
+ };
105
+ await mutateUserProfile({ baseServicesUrl, body });
106
+ };
100
107
  if (userHasTeams) {
101
108
  if (!userTeamInstanceSwitcherDefault) {
102
109
  if (userHasPersonalTeam) {
@@ -128,6 +135,21 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
128
135
  const newSelectedTeam = allTeams.find((team) => team.id === userTeamInstanceSwitcherDefault);
129
136
  handleSelectTeam({ team: newSelectedTeam });
130
137
  }
138
+ // if teams data loaded but there are no teams
139
+ }
140
+ else if (Boolean(userTeamInstanceSwitcherDefault) &&
141
+ ((hasUserTeams &&
142
+ userTeams?.data?.accountTeams?.length === 0 &&
143
+ userTeams?.data?.standardTeams?.length === 0 &&
144
+ userTeams?.data?.personalTeam?.length === 0) ||
145
+ (!hasUserTeams &&
146
+ teamsQuery?.data?.accountTeams?.length === 0 &&
147
+ teamsQuery?.data?.standardTeams?.length === 0 &&
148
+ teamsQuery?.data?.personalTeam?.length === 0))) {
149
+ handleNoTeamsToSelect();
150
+ }
151
+ else if (userTeamInstanceSwitcherDefault === null) {
152
+ setSelectedTeam(null);
131
153
  }
132
154
  }, [
133
155
  baseServicesUrl,
@@ -205,33 +227,58 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
205
227
  standardTeams = teamsQuery?.data?.standardTeams ?? [];
206
228
  personalTeam = teamsQuery?.data?.personalTeam ?? [];
207
229
  }
208
- let sortedAccountTeamsWithNamesToDisplay = [];
209
- let sortedStandardTeamsWithNamesToDisplay = [];
230
+ let newPersonalTeam = personalTeam.length > 0
231
+ ? personalTeam.map((personalTeam) => ({
232
+ ...personalTeam,
233
+ type: TeamTypes.TEAM_TYPES.PERSONAL,
234
+ nameToDisplay: personalTeam.displayName ? personalTeam.displayName : personalTeam.name,
235
+ }))
236
+ : [];
237
+ let newAccountTeams = [];
238
+ let newStandardTeams = [];
210
239
  if (accountTeams?.length > 0) {
211
- const newAccountTeams = accountTeams.map((team) => {
240
+ newAccountTeams = accountTeams.map((team) => {
212
241
  let newProjectTeams = [];
213
242
  if (team.projectTeams && team.projectTeams.length > 0) {
214
- newProjectTeams = team.projectTeams?.map((team) => ({
215
- ...team,
216
- nameToDisplay: team.displayName ? team.displayName : team.name,
217
- }));
243
+ newProjectTeams = team.projectTeams?.map((projectTeam) => {
244
+ return {
245
+ ...projectTeam,
246
+ nameToDisplay: projectTeam.displayName ? projectTeam.displayName : projectTeam.name,
247
+ };
248
+ });
218
249
  }
219
250
  return {
220
251
  ...team,
221
252
  nameToDisplay: team.displayName ? team.displayName : team.name,
253
+ type: TeamTypes.TEAM_TYPES.ACCOUNT,
222
254
  projectTeams: sortBy__default.default(newProjectTeams, ["nameToDisplay"]),
223
255
  };
224
256
  });
225
- sortedAccountTeamsWithNamesToDisplay = sortBy__default.default(newAccountTeams, ["nameToDisplay"]);
226
257
  }
227
258
  if (standardTeams?.length > 0) {
228
- const newStandardTeams = standardTeams.map((team) => {
259
+ newStandardTeams = standardTeams.map((team) => {
229
260
  return {
230
261
  ...team,
262
+ type: TeamTypes.TEAM_TYPES.STANDARD,
231
263
  nameToDisplay: team.displayName ? team.displayName : team.name,
232
264
  };
233
265
  });
234
- sortedStandardTeamsWithNamesToDisplay = sortBy__default.default(newStandardTeams, ["nameToDisplay"]);
266
+ }
267
+ let allTeams = newPersonalTeam.concat(newAccountTeams, newStandardTeams);
268
+ const order = { [TeamTypes.TEAM_TYPES.PERSONAL]: 1, [TeamTypes.TEAM_TYPES.ACCOUNT]: 2, [TeamTypes.TEAM_TYPES.STANDARD]: 3 };
269
+ allTeams = sortBy__default.default(allTeams, [(team) => order[team.type], "nameToDisplay"]);
270
+ if (selectedTeam) {
271
+ const selectedTeamIndex = allTeams.findIndex((team, index) => {
272
+ if (team.id === selectedTeam.id) {
273
+ return true;
274
+ }
275
+ else if (Array.isArray(team.projectTeams) && team.projectTeams?.length > 0) {
276
+ return team.projectTeams.some((projectTeam) => projectTeam.id === selectedTeam.id);
277
+ }
278
+ return false;
279
+ });
280
+ const [removedTeam] = allTeams.splice(selectedTeamIndex, 1);
281
+ allTeams.unshift(removedTeam);
235
282
  }
236
283
  let selectedTeamName = selectedTeam?.displayName
237
284
  ? selectedTeam.displayName
@@ -253,29 +300,22 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
253
300
  React__default.default.createElement("div", { className: headerTeamSwitcherCreateTeamButtonClassname },
254
301
  React__default.default.createElement("span", { className: headerTeamSwitcherCreateTeamButtonTextClassname }, createTeamButtonText),
255
302
  React__default.default.createElement(icons.AddAlt, { className: headerTeamSwitcherCreateTeamButtonIconClassname })))),
256
- personalTeam.length > 0
257
- ? personalTeam.map((team) => {
258
- const teamName = team.displayName ? team.displayName : team.name;
259
- const isTeamSelected = team.id === selectedTeam?.id;
260
- return (React__default.default.createElement("div", { key: team.id, id: `${team.id}-personal-menu-item-id` },
261
- React__default.default.createElement(react.HeaderMenuItem, { key: team.id, id: `${team.id}-personal-menu-item`, "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => {
262
- handleTeamClick({ team, type: "personal" });
263
- },
264
- // eslint-disable-next-line no-script-url
265
- href: "javascript:void(0)", "data-testid": "header-team-switcher-menu-item" },
266
- React__default.default.createElement("div", { className: headerDropdownMenuItemClassname },
267
- React__default.default.createElement("span", { title: teamName, className: headerDropdownMenuItemTextClassname }, teamName),
268
- isTeamSelected ? React__default.default.createElement(icons.CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null))));
269
- })
270
- : null,
271
- accountTeams.length > 0
272
- ? sortedAccountTeamsWithNamesToDisplay.map((team) => {
303
+ allTeams.map((team) => {
304
+ const isTeamSelected = team.id === selectedTeam?.id;
305
+ if (team.type === TeamTypes.TEAM_TYPES.ACCOUNT) {
273
306
  const isSubmenuOpen = team.id === openAccountSubmenuId;
274
- const isProjectTeamSelected = team.projectTeams &&
275
- team.projectTeams.length > 0 &&
276
- team.projectTeams.some((team) => team.id === selectedTeam?.id);
277
- const isTeamSelected = team.id === selectedTeam?.id;
307
+ const projectTeams = team.projectTeams;
308
+ const existProjectTeams = Array.isArray(projectTeams) && projectTeams.length > 0;
309
+ let selectedProjectTeamIndex = -1;
310
+ if (existProjectTeams) {
311
+ selectedProjectTeamIndex = projectTeams.findIndex((team) => team.id === selectedTeam?.id);
312
+ }
313
+ const isProjectTeamSelected = selectedProjectTeamIndex >= 0;
278
314
  const isMenuSelected = isTeamSelected || isProjectTeamSelected;
315
+ if (existProjectTeams && isProjectTeamSelected) {
316
+ const [removedTeam] = projectTeams.splice(selectedProjectTeamIndex, 1);
317
+ projectTeams.unshift(removedTeam);
318
+ }
279
319
  return (React__default.default.createElement("div", { key: team.id, id: `${team.id}-account-menu` },
280
320
  React__default.default.createElement(react.HeaderMenuItem, { "aria-expanded": isSubmenuOpen, "aria-selected": isMenuSelected, className: headerDropdownMenuItemAccountContainerClassname, onClick: (e) => handleOpenAccountSubmenu({ e, id: team.id }),
281
321
  // eslint-disable-next-line no-script-url
@@ -283,7 +323,7 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
283
323
  React__default.default.createElement("div", { className: headerDropdownMenuItemAccountClassname },
284
324
  React__default.default.createElement("div", { className: headerDropdownMenuItemTextIconClassname },
285
325
  React__default.default.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, team.nameToDisplay),
286
- isMenuSelected ? (React__default.default.createElement(icons.CheckmarkFilled, { className: headerDropdownMenuItemIconClassname })) : null),
326
+ isMenuSelected ? React__default.default.createElement(icons.CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null),
287
327
  React__default.default.createElement("div", { className: headerDropdownMenuItemAccountIconsClassname },
288
328
  React__default.default.createElement(icons.GroupAccount, { className: headerDropdownMenuItemAccountGroupIconClassname }),
289
329
  React__default.default.createElement(icons.ChevronDown, { className: headerDropdownMenuItemAccountChevronIconClassname })))),
@@ -295,9 +335,9 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
295
335
  href: "javascript:void(0)" },
296
336
  React__default.default.createElement("div", { className: headerDropdownMenuItemClassname, style: { paddingLeft: "1rem" } },
297
337
  React__default.default.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, "Account Page"),
298
- isTeamSelected ? (React__default.default.createElement(icons.CheckmarkFilled, { className: headerDropdownMenuItemIconClassname })) : null)),
299
- team.projectTeams && team.projectTeams.length > 0
300
- ? team.projectTeams.map((team) => {
338
+ isTeamSelected ? React__default.default.createElement(icons.CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null)),
339
+ projectTeams && projectTeams.length > 0
340
+ ? projectTeams.map((team) => {
301
341
  const isTeamSelected = team.id === selectedTeam?.id;
302
342
  return (React__default.default.createElement("div", { key: team.id, id: `${team.id}-project-menu-item` },
303
343
  React__default.default.createElement(react.HeaderMenuItem, { "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => {
@@ -310,22 +350,19 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
310
350
  isTeamSelected ? (React__default.default.createElement(icons.CheckmarkFilled, { className: headerDropdownMenuItemIconClassname })) : null))));
311
351
  })
312
352
  : null)));
313
- })
314
- : null,
315
- standardTeams.length > 0
316
- ? sortedStandardTeamsWithNamesToDisplay.map((team) => {
317
- const isTeamSelected = team.id === selectedTeam?.id;
318
- return (React__default.default.createElement("div", { key: team.id, id: `${team.id}-standard-menu-item` },
353
+ }
354
+ else {
355
+ return (React__default.default.createElement("div", { key: team.id, id: `${team.id}-${team.type}-menu-item` },
319
356
  React__default.default.createElement(react.HeaderMenuItem, { "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => {
320
- handleTeamClick({ team, type: "standard" });
357
+ handleTeamClick({ team, type: team.type ?? "" });
321
358
  }, "data-testid": "header-team-switcher-menu-item",
322
359
  // eslint-disable-next-line no-script-url
323
360
  href: "javascript:void(0)" },
324
361
  React__default.default.createElement("div", { className: headerDropdownMenuItemClassname },
325
362
  React__default.default.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, team.nameToDisplay),
326
363
  isTeamSelected ? React__default.default.createElement(icons.CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null))));
327
- })
328
- : null))));
364
+ }
365
+ })))));
329
366
  }
330
367
  return null;
331
368
  }
@@ -34,12 +34,13 @@ function determineIfConfigIsDifferent(teams, initialTeams) {
34
34
  }
35
35
  return isConfigDifferent;
36
36
  }
37
- function ProfileSettings({ baseServicesUrl, src, userName, isOpen, closeModal }) {
37
+ function ProfileSettings({ baseServicesUrl, refetchUser, refetchUserTeams, refetchNavigation, src, userName, isOpen, closeModal, }) {
38
38
  const queryClient = reactQuery.useQueryClient();
39
39
  const [initialTeams, setInitialTeams] = React.useState([]);
40
40
  const [teams, setTeams] = React.useState([]);
41
41
  const userUrl = servicesConfig.serviceUrl.getLaunchpadUser({ baseServicesUrl });
42
42
  const profileUrl = servicesConfig.serviceUrl.resourceUserProfile({ baseServicesUrl });
43
+ const userTeamsUrl = servicesConfig.serviceUrl.getUserTeamsServices({ baseServicesUrl });
43
44
  const { data: user, isLoading: userIsLoading, error: userError, } = reactQuery.useQuery({
44
45
  queryKey: userUrl,
45
46
  queryFn: servicesConfig.resolver.query(userUrl),
@@ -48,6 +49,22 @@ function ProfileSettings({ baseServicesUrl, src, userName, isOpen, closeModal })
48
49
  onSuccess: () => {
49
50
  queryClient.invalidateQueries(userUrl);
50
51
  queryClient.invalidateQueries(profileUrl);
52
+ queryClient.invalidateQueries(userTeamsUrl);
53
+ if (refetchUser) {
54
+ setTimeout(() => {
55
+ refetchUser();
56
+ }, 1000);
57
+ }
58
+ if (refetchUserTeams) {
59
+ setTimeout(() => {
60
+ refetchUserTeams();
61
+ }, 1000);
62
+ }
63
+ if (refetchNavigation) {
64
+ setTimeout(() => {
65
+ refetchNavigation();
66
+ }, 1000);
67
+ }
51
68
  },
52
69
  });
53
70
  // Only disable when we have a user and we know that there aren' any lower level groups to manage
@@ -63,6 +80,7 @@ function ProfileSettings({ baseServicesUrl, src, userName, isOpen, closeModal })
63
80
  }
64
81
  async function handleSubmit() {
65
82
  const body = {
83
+ teamInstanceSwitcherDefault: null,
66
84
  lowerLevelGroups: teams,
67
85
  };
68
86
  try {
@@ -104,9 +122,9 @@ function ProfileSettings({ baseServicesUrl, src, userName, isOpen, closeModal })
104
122
  return (React__default.default.createElement(react.ComposedModal, { "aria-label": "Profile Settings", className: `${settings.prefix}--bmrg-profile-settings-container ${settings.prefix}--bmrg-header-modal`, open: isOpen, onClose: handleClose, preventCloseOnClickOutside: true },
105
123
  React__default.default.createElement(react.ModalHeader, { closeModal: handleClose, title: `User profile - ${userName}` }),
106
124
  React__default.default.createElement(react.ModalBody, { style: { maxHeight: "31.5rem" } },
107
- React__default.default.createElement("p", { className: `${settings.prefix}--bmrg-profile-settings__title` }, "More user profile settings will be here eventually, but for now you can choose which Teams are shown in your sidebar in Launchpad."),
108
- React__default.default.createElement("h2", { className: `${settings.prefix}--bmrg-profile-settings__subtitle` }, "Teams visible in Launchpad sidebar"),
109
- React__default.default.createElement("p", { className: `${settings.prefix}--bmrg-profile-settings__description` }, "Choose Teams to show or hide in your Launchpad sidebar and Catalog (useful for sensitive demos). You will not be able to access or view unchecked Teams from the sidebar, and cannot add items to them from Catalog."),
125
+ React__default.default.createElement("p", { className: `${settings.prefix}--bmrg-profile-settings__title` }, "More user profile settings will be here eventually, but for now you can choose which Teams are shown in your team switcher in Launchpad."),
126
+ React__default.default.createElement("h2", { className: `${settings.prefix}--bmrg-profile-settings__subtitle` }, "Teams visible in Launchpad team switcher"),
127
+ React__default.default.createElement("p", { className: `${settings.prefix}--bmrg-profile-settings__description` }, "Choose Teams to show or hide in your Launchpad team switcher and Catalog (useful for sensitive demos). You will not be able to access or view unchecked Teams from the team switcher, and cannot add items to them from Catalog."),
110
128
  userIsLoading ? (React__default.default.createElement(react.StructuredListSkeleton, null)) : userError ? (React__default.default.createElement(ErrorMessage.default, { style: { color: "#F2F4F8", padding: "1rem" } })) : teams?.length > 0 ? (React__default.default.createElement(react.StructuredListWrapper, { className: `${settings.prefix}--bmrg-profile-settings-list` },
111
129
  React__default.default.createElement(react.StructuredListHead, null,
112
130
  React__default.default.createElement(react.StructuredListRow, { head: true },
@@ -26,11 +26,11 @@ IBM Confidential
26
26
  694970X, 69497O0
27
27
  © Copyright IBM Corp. 2022, 2024
28
28
  */
29
- function UIShell({ analyticsHelpers, baseEnvUrl, carbonTheme = "g10", config, createJoinTeamTrigger, history, isLaunchpad = false, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, leftPanel, platformName, productName, profileMenuItems = [], supportMenuItems = [], renderPrivacyRedirect = true, renderPrivacyStatement = true, rightPanel, handleShowTutorial, refetchUser, refetchNavigation, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, tutorialScreenToShow, user, userTeams, userTeamsAssets, enableIcaMacs, }) {
29
+ function UIShell({ analyticsHelpers, baseEnvUrl, carbonTheme = "g10", config, createJoinTeamTrigger, enableTeamSwitcher = true, history, isLaunchpad = false, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, leftPanel, platformName, productName, profileMenuItems = [], supportMenuItems = [], renderPrivacyRedirect = true, renderPrivacyStatement = true, rightPanel, handleShowTutorial, refetchUser, refetchUserTeams, refetchNavigation, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, tutorialScreenToShow, user, userTeams, userTeamsAssets, enableIcaMacs, }) {
30
30
  // Support base header .e.g for an error state
31
31
  if (!config) {
32
32
  return (React__default.default.createElement(reactQuery.QueryClientProvider, { client: servicesConfig.queryClient },
33
- React__default.default.createElement(Header.default, { baseEnvUrl: baseEnvUrl ?? "", baseServicesUrl: "", carbonTheme: carbonTheme, enableAppSwitcher: false, enableNotifications: false, enableNotificationsCount: false, productName: productName || platformName || "", user: user })));
33
+ React__default.default.createElement(Header.default, { baseEnvUrl: baseEnvUrl ?? "", baseServicesUrl: "", carbonTheme: carbonTheme, enableAppSwitcher: false, enableNotifications: false, enableNotificationsCount: false, enableTeamSwitcher: enableTeamSwitcher, productName: productName || platformName || "", user: user })));
34
34
  }
35
35
  const { features, navigation, platform, platformMessage } = config;
36
36
  const names = getProductAndPlatformNames({ productName, platformName, platform });
@@ -71,8 +71,8 @@ function UIShell({ analyticsHelpers, baseEnvUrl, carbonTheme = "g10", config, cr
71
71
  */
72
72
  const isPrivacyStatementDisabled = renderPrivacyStatement === false || features?.["consent.enabled"] === false;
73
73
  return (React__default.default.createElement(reactQuery.QueryClientProvider, { client: servicesConfig.queryClient },
74
- React__default.default.createElement(Header.default, { analyticsHelpers: analyticsHelpers, baseEnvUrl: platform.baseEnvUrl, baseServicesUrl: platform.baseServicesUrl, carbonTheme: carbonTheme, createJoinTeamTrigger: createJoinTeamTrigger, enableAppSwitcher: isAppSwitcherEnabled, instanceSwitcherEnabled: instanceSwitcherEnabled, enableNotifications: isNotificationsEnabled, enableNotificationsCount: isNotificationsCountEnabled, leftPanel: leftPanel, navLinks: navigation, platform: platform, platformMessage: platformMessage, prefixName: names.platformName, productName: names.productName, rightPanel: rightPanel, requestSummary: user?.requestSummary, skipToContentProps: skipToContentProps, templateMeteringEvent: templateMeteringEvent, triggerEvent: triggerEvent, profileMenuItems: [
75
- isUserEnabled && (React__default.default.createElement(ProfileSettings.ProfileSettingsMenuItem, { key: "profile-settings", baseServicesUrl: platform.baseServicesUrl, src: `${platform.baseServicesUrl}/users/image/${user?.email}`, userName: user?.displayName ?? user?.name })),
74
+ React__default.default.createElement(Header.default, { analyticsHelpers: analyticsHelpers, baseEnvUrl: platform.baseEnvUrl, baseServicesUrl: platform.baseServicesUrl, carbonTheme: carbonTheme, createJoinTeamTrigger: createJoinTeamTrigger, enableAppSwitcher: isAppSwitcherEnabled, instanceSwitcherEnabled: instanceSwitcherEnabled, enableNotifications: isNotificationsEnabled, enableNotificationsCount: isNotificationsCountEnabled, enableTeamSwitcher: enableTeamSwitcher, leftPanel: leftPanel, navLinks: navigation, platform: platform, platformMessage: platformMessage, prefixName: names.platformName, productName: names.productName, rightPanel: rightPanel, requestSummary: user?.requestSummary, skipToContentProps: skipToContentProps, templateMeteringEvent: templateMeteringEvent, triggerEvent: triggerEvent, profileMenuItems: [
75
+ isUserEnabled && (React__default.default.createElement(ProfileSettings.ProfileSettingsMenuItem, { key: "profile-settings", baseServicesUrl: platform.baseServicesUrl, src: `${platform.baseServicesUrl}/users/image/${user?.email}`, userName: user?.displayName ?? user?.name, refetchUser: refetchUser, refetchUserTeams: refetchUserTeams, refetchNavigation: refetchNavigation })),
76
76
  isSendMailEnabled && (React__default.default.createElement(HeaderMenuItem.default, { key: "email-preferences", href: `${platform.baseEnvUrl}/launchpad/email-preferences`, icon: React__default.default.createElement(icons.Email, null), kind: "internal", text: "Email Preferences", type: "link" })),
77
77
  !isPrivacyStatementDisabled && (React__default.default.createElement(PrivacyStatement.PrivacyStatementMenuItem, { key: "privacy-statement", baseServicesUrl: platform.baseServicesUrl, platformEmail: platform?.platformEmail })),
78
78
  ...profileMenuItems,
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ /*
4
+ IBM Confidential
5
+ 694970X, 69497O0
6
+ © Copyright IBM Corp. 2022, 2024
7
+ */
8
+ const TEAM_TYPES = {
9
+ ACCOUNT: "account",
10
+ PERSONAL: "personal",
11
+ PROJECT: "project",
12
+ STANDARD: "standard",
13
+ };
14
+
15
+ exports.TEAM_TYPES = TEAM_TYPES;
@@ -54,7 +54,7 @@ const MenuAriaLabelRecord = {
54
54
  const headerButtonClassNames = "cds--btn--icon-only cds--header__action cds--btn cds--btn--primary cds--btn--icon-only cds--btn cds--btn--primary";
55
55
  const instanceCheckMarkContainerClass = "instance-checkmark-style-container";
56
56
  function Header(props) {
57
- const { analyticsHelpers, productName, baseEnvUrl, baseServicesUrl, carbonTheme = "g10", className, createJoinTeamTrigger, history, isLaunchpad = false, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, navLinks, platform, prefixName = "", refetchUser, refetchNavigation, rightPanel, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, user, userTeams, userTeamsAssets, } = props;
57
+ const { analyticsHelpers, productName, baseEnvUrl, baseServicesUrl, carbonTheme = "g10", className, createJoinTeamTrigger, enableTeamSwitcher = true, history, isLaunchpad = false, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, navLinks, platform, prefixName = "", refetchUser, refetchNavigation, rightPanel, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, user, userTeams, userTeamsAssets, } = props;
58
58
  const hasUserTeams = Boolean(userTeams);
59
59
  const userTeamsUrl = serviceUrl.getUserTeamsServices({ baseServicesUrl });
60
60
  const teamsQuery = useQuery({
@@ -62,6 +62,7 @@ function Header(props) {
62
62
  queryFn: resolver.query(userTeamsUrl, null),
63
63
  enabled: !hasUserTeams && Boolean(baseServicesUrl),
64
64
  });
65
+ const showTeamSwitcher = enableTeamSwitcher && Boolean(user);
65
66
  return (React.createElement(React.Fragment, null,
66
67
  React.createElement(Theme, { theme: carbonTheme },
67
68
  React.createElement(Header$1, { "aria-label": "App navigation header", className: className },
@@ -72,7 +73,7 @@ function Header(props) {
72
73
  ? 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)))
73
74
  : null),
74
75
  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, refetchUser: refetchUser, refetchNavigation: refetchNavigation, teamsQuery: teamsQuery, trackEvent: trackEvent, user: user, userTeams: userTeams }),
76
+ showTeamSwitcher ? (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, refetchUser: refetchUser, refetchNavigation: refetchNavigation, teamsQuery: teamsQuery, trackEvent: trackEvent, user: user, userTeams: userTeams })) : null,
76
77
  props?.instanceSwitcherEnabled && (React.createElement(InstanceSwitcherMenu, { enabled: Boolean(props.instanceSwitcherEnabled), menuItems: platform?.instances })),
77
78
  React.createElement(RequestsMenu, { baseEnvUrl: baseEnvUrl, enabled: Boolean(props.requestSummary), summary: props.requestSummary }),
78
79
  React.createElement(NotificationsMenu, { baseEnvUrl: baseEnvUrl, baseServicesUrl: baseServicesUrl, enabled: Boolean(props.enableNotifications), countEnabled: Boolean(props.enableNotificationsCount) }),
@@ -7,6 +7,7 @@ import HeaderMenu$1 from './HeaderMenu.js';
7
7
  import { resolver } from '../../config/servicesConfig.js';
8
8
  import { prefix } from '../../internal/settings.js';
9
9
  import { USER_PLATFORM_ROLE } from '../../constants/UserType.js';
10
+ import { TEAM_TYPES } from '../../constants/TeamTypes.js';
10
11
 
11
12
  /*
12
13
  IBM Confidential
@@ -88,6 +89,12 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
88
89
  await mutateUserProfile({ baseServicesUrl, body });
89
90
  }
90
91
  };
92
+ const handleNoTeamsToSelect = async () => {
93
+ const body = {
94
+ teamInstanceSwitcherDefault: null,
95
+ };
96
+ await mutateUserProfile({ baseServicesUrl, body });
97
+ };
91
98
  if (userHasTeams) {
92
99
  if (!userTeamInstanceSwitcherDefault) {
93
100
  if (userHasPersonalTeam) {
@@ -119,6 +126,21 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
119
126
  const newSelectedTeam = allTeams.find((team) => team.id === userTeamInstanceSwitcherDefault);
120
127
  handleSelectTeam({ team: newSelectedTeam });
121
128
  }
129
+ // if teams data loaded but there are no teams
130
+ }
131
+ else if (Boolean(userTeamInstanceSwitcherDefault) &&
132
+ ((hasUserTeams &&
133
+ userTeams?.data?.accountTeams?.length === 0 &&
134
+ userTeams?.data?.standardTeams?.length === 0 &&
135
+ userTeams?.data?.personalTeam?.length === 0) ||
136
+ (!hasUserTeams &&
137
+ teamsQuery?.data?.accountTeams?.length === 0 &&
138
+ teamsQuery?.data?.standardTeams?.length === 0 &&
139
+ teamsQuery?.data?.personalTeam?.length === 0))) {
140
+ handleNoTeamsToSelect();
141
+ }
142
+ else if (userTeamInstanceSwitcherDefault === null) {
143
+ setSelectedTeam(null);
122
144
  }
123
145
  }, [
124
146
  baseServicesUrl,
@@ -196,33 +218,58 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
196
218
  standardTeams = teamsQuery?.data?.standardTeams ?? [];
197
219
  personalTeam = teamsQuery?.data?.personalTeam ?? [];
198
220
  }
199
- let sortedAccountTeamsWithNamesToDisplay = [];
200
- let sortedStandardTeamsWithNamesToDisplay = [];
221
+ let newPersonalTeam = personalTeam.length > 0
222
+ ? personalTeam.map((personalTeam) => ({
223
+ ...personalTeam,
224
+ type: TEAM_TYPES.PERSONAL,
225
+ nameToDisplay: personalTeam.displayName ? personalTeam.displayName : personalTeam.name,
226
+ }))
227
+ : [];
228
+ let newAccountTeams = [];
229
+ let newStandardTeams = [];
201
230
  if (accountTeams?.length > 0) {
202
- const newAccountTeams = accountTeams.map((team) => {
231
+ newAccountTeams = accountTeams.map((team) => {
203
232
  let newProjectTeams = [];
204
233
  if (team.projectTeams && team.projectTeams.length > 0) {
205
- newProjectTeams = team.projectTeams?.map((team) => ({
206
- ...team,
207
- nameToDisplay: team.displayName ? team.displayName : team.name,
208
- }));
234
+ newProjectTeams = team.projectTeams?.map((projectTeam) => {
235
+ return {
236
+ ...projectTeam,
237
+ nameToDisplay: projectTeam.displayName ? projectTeam.displayName : projectTeam.name,
238
+ };
239
+ });
209
240
  }
210
241
  return {
211
242
  ...team,
212
243
  nameToDisplay: team.displayName ? team.displayName : team.name,
244
+ type: TEAM_TYPES.ACCOUNT,
213
245
  projectTeams: sortBy(newProjectTeams, ["nameToDisplay"]),
214
246
  };
215
247
  });
216
- sortedAccountTeamsWithNamesToDisplay = sortBy(newAccountTeams, ["nameToDisplay"]);
217
248
  }
218
249
  if (standardTeams?.length > 0) {
219
- const newStandardTeams = standardTeams.map((team) => {
250
+ newStandardTeams = standardTeams.map((team) => {
220
251
  return {
221
252
  ...team,
253
+ type: TEAM_TYPES.STANDARD,
222
254
  nameToDisplay: team.displayName ? team.displayName : team.name,
223
255
  };
224
256
  });
225
- sortedStandardTeamsWithNamesToDisplay = sortBy(newStandardTeams, ["nameToDisplay"]);
257
+ }
258
+ let allTeams = newPersonalTeam.concat(newAccountTeams, newStandardTeams);
259
+ const order = { [TEAM_TYPES.PERSONAL]: 1, [TEAM_TYPES.ACCOUNT]: 2, [TEAM_TYPES.STANDARD]: 3 };
260
+ allTeams = sortBy(allTeams, [(team) => order[team.type], "nameToDisplay"]);
261
+ if (selectedTeam) {
262
+ const selectedTeamIndex = allTeams.findIndex((team, index) => {
263
+ if (team.id === selectedTeam.id) {
264
+ return true;
265
+ }
266
+ else if (Array.isArray(team.projectTeams) && team.projectTeams?.length > 0) {
267
+ return team.projectTeams.some((projectTeam) => projectTeam.id === selectedTeam.id);
268
+ }
269
+ return false;
270
+ });
271
+ const [removedTeam] = allTeams.splice(selectedTeamIndex, 1);
272
+ allTeams.unshift(removedTeam);
226
273
  }
227
274
  let selectedTeamName = selectedTeam?.displayName
228
275
  ? selectedTeam.displayName
@@ -244,29 +291,22 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
244
291
  React.createElement("div", { className: headerTeamSwitcherCreateTeamButtonClassname },
245
292
  React.createElement("span", { className: headerTeamSwitcherCreateTeamButtonTextClassname }, createTeamButtonText),
246
293
  React.createElement(AddAlt, { className: headerTeamSwitcherCreateTeamButtonIconClassname })))),
247
- personalTeam.length > 0
248
- ? personalTeam.map((team) => {
249
- const teamName = team.displayName ? team.displayName : team.name;
250
- const isTeamSelected = team.id === selectedTeam?.id;
251
- return (React.createElement("div", { key: team.id, id: `${team.id}-personal-menu-item-id` },
252
- React.createElement(HeaderMenuItem, { key: team.id, id: `${team.id}-personal-menu-item`, "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => {
253
- handleTeamClick({ team, type: "personal" });
254
- },
255
- // eslint-disable-next-line no-script-url
256
- href: "javascript:void(0)", "data-testid": "header-team-switcher-menu-item" },
257
- React.createElement("div", { className: headerDropdownMenuItemClassname },
258
- React.createElement("span", { title: teamName, className: headerDropdownMenuItemTextClassname }, teamName),
259
- isTeamSelected ? React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null))));
260
- })
261
- : null,
262
- accountTeams.length > 0
263
- ? sortedAccountTeamsWithNamesToDisplay.map((team) => {
294
+ allTeams.map((team) => {
295
+ const isTeamSelected = team.id === selectedTeam?.id;
296
+ if (team.type === TEAM_TYPES.ACCOUNT) {
264
297
  const isSubmenuOpen = team.id === openAccountSubmenuId;
265
- const isProjectTeamSelected = team.projectTeams &&
266
- team.projectTeams.length > 0 &&
267
- team.projectTeams.some((team) => team.id === selectedTeam?.id);
268
- const isTeamSelected = team.id === selectedTeam?.id;
298
+ const projectTeams = team.projectTeams;
299
+ const existProjectTeams = Array.isArray(projectTeams) && projectTeams.length > 0;
300
+ let selectedProjectTeamIndex = -1;
301
+ if (existProjectTeams) {
302
+ selectedProjectTeamIndex = projectTeams.findIndex((team) => team.id === selectedTeam?.id);
303
+ }
304
+ const isProjectTeamSelected = selectedProjectTeamIndex >= 0;
269
305
  const isMenuSelected = isTeamSelected || isProjectTeamSelected;
306
+ if (existProjectTeams && isProjectTeamSelected) {
307
+ const [removedTeam] = projectTeams.splice(selectedProjectTeamIndex, 1);
308
+ projectTeams.unshift(removedTeam);
309
+ }
270
310
  return (React.createElement("div", { key: team.id, id: `${team.id}-account-menu` },
271
311
  React.createElement(HeaderMenuItem, { "aria-expanded": isSubmenuOpen, "aria-selected": isMenuSelected, className: headerDropdownMenuItemAccountContainerClassname, onClick: (e) => handleOpenAccountSubmenu({ e, id: team.id }),
272
312
  // eslint-disable-next-line no-script-url
@@ -274,7 +314,7 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
274
314
  React.createElement("div", { className: headerDropdownMenuItemAccountClassname },
275
315
  React.createElement("div", { className: headerDropdownMenuItemTextIconClassname },
276
316
  React.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, team.nameToDisplay),
277
- isMenuSelected ? (React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname })) : null),
317
+ isMenuSelected ? React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null),
278
318
  React.createElement("div", { className: headerDropdownMenuItemAccountIconsClassname },
279
319
  React.createElement(GroupAccount, { className: headerDropdownMenuItemAccountGroupIconClassname }),
280
320
  React.createElement(ChevronDown, { className: headerDropdownMenuItemAccountChevronIconClassname })))),
@@ -286,9 +326,9 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
286
326
  href: "javascript:void(0)" },
287
327
  React.createElement("div", { className: headerDropdownMenuItemClassname, style: { paddingLeft: "1rem" } },
288
328
  React.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, "Account Page"),
289
- isTeamSelected ? (React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname })) : null)),
290
- team.projectTeams && team.projectTeams.length > 0
291
- ? team.projectTeams.map((team) => {
329
+ isTeamSelected ? React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null)),
330
+ projectTeams && projectTeams.length > 0
331
+ ? projectTeams.map((team) => {
292
332
  const isTeamSelected = team.id === selectedTeam?.id;
293
333
  return (React.createElement("div", { key: team.id, id: `${team.id}-project-menu-item` },
294
334
  React.createElement(HeaderMenuItem, { "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => {
@@ -301,22 +341,19 @@ function HeaderTeamSwitcher({ analyticsHelpers, baseServicesUrl, createJoinTeamT
301
341
  isTeamSelected ? (React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname })) : null))));
302
342
  })
303
343
  : null)));
304
- })
305
- : null,
306
- standardTeams.length > 0
307
- ? sortedStandardTeamsWithNamesToDisplay.map((team) => {
308
- const isTeamSelected = team.id === selectedTeam?.id;
309
- return (React.createElement("div", { key: team.id, id: `${team.id}-standard-menu-item` },
344
+ }
345
+ else {
346
+ return (React.createElement("div", { key: team.id, id: `${team.id}-${team.type}-menu-item` },
310
347
  React.createElement(HeaderMenuItem, { "aria-selected": isTeamSelected, className: headerDropdownMenuItemContainerClassname, onClick: () => {
311
- handleTeamClick({ team, type: "standard" });
348
+ handleTeamClick({ team, type: team.type ?? "" });
312
349
  }, "data-testid": "header-team-switcher-menu-item",
313
350
  // eslint-disable-next-line no-script-url
314
351
  href: "javascript:void(0)" },
315
352
  React.createElement("div", { className: headerDropdownMenuItemClassname },
316
353
  React.createElement("span", { title: team.nameToDisplay, className: headerDropdownMenuItemTextClassname }, team.nameToDisplay),
317
354
  isTeamSelected ? React.createElement(CheckmarkFilled, { className: headerDropdownMenuItemIconClassname }) : null))));
318
- })
319
- : null))));
355
+ }
356
+ })))));
320
357
  }
321
358
  return null;
322
359
  }
@@ -25,12 +25,13 @@ function determineIfConfigIsDifferent(teams, initialTeams) {
25
25
  }
26
26
  return isConfigDifferent;
27
27
  }
28
- function ProfileSettings({ baseServicesUrl, src, userName, isOpen, closeModal }) {
28
+ function ProfileSettings({ baseServicesUrl, refetchUser, refetchUserTeams, refetchNavigation, src, userName, isOpen, closeModal, }) {
29
29
  const queryClient = useQueryClient();
30
30
  const [initialTeams, setInitialTeams] = useState([]);
31
31
  const [teams, setTeams] = useState([]);
32
32
  const userUrl = serviceUrl.getLaunchpadUser({ baseServicesUrl });
33
33
  const profileUrl = serviceUrl.resourceUserProfile({ baseServicesUrl });
34
+ const userTeamsUrl = serviceUrl.getUserTeamsServices({ baseServicesUrl });
34
35
  const { data: user, isLoading: userIsLoading, error: userError, } = useQuery({
35
36
  queryKey: userUrl,
36
37
  queryFn: resolver.query(userUrl),
@@ -39,6 +40,22 @@ function ProfileSettings({ baseServicesUrl, src, userName, isOpen, closeModal })
39
40
  onSuccess: () => {
40
41
  queryClient.invalidateQueries(userUrl);
41
42
  queryClient.invalidateQueries(profileUrl);
43
+ queryClient.invalidateQueries(userTeamsUrl);
44
+ if (refetchUser) {
45
+ setTimeout(() => {
46
+ refetchUser();
47
+ }, 1000);
48
+ }
49
+ if (refetchUserTeams) {
50
+ setTimeout(() => {
51
+ refetchUserTeams();
52
+ }, 1000);
53
+ }
54
+ if (refetchNavigation) {
55
+ setTimeout(() => {
56
+ refetchNavigation();
57
+ }, 1000);
58
+ }
42
59
  },
43
60
  });
44
61
  // Only disable when we have a user and we know that there aren' any lower level groups to manage
@@ -54,6 +71,7 @@ function ProfileSettings({ baseServicesUrl, src, userName, isOpen, closeModal })
54
71
  }
55
72
  async function handleSubmit() {
56
73
  const body = {
74
+ teamInstanceSwitcherDefault: null,
57
75
  lowerLevelGroups: teams,
58
76
  };
59
77
  try {
@@ -95,9 +113,9 @@ function ProfileSettings({ baseServicesUrl, src, userName, isOpen, closeModal })
95
113
  return (React.createElement(ComposedModal, { "aria-label": "Profile Settings", className: `${prefix}--bmrg-profile-settings-container ${prefix}--bmrg-header-modal`, open: isOpen, onClose: handleClose, preventCloseOnClickOutside: true },
96
114
  React.createElement(ModalHeader, { closeModal: handleClose, title: `User profile - ${userName}` }),
97
115
  React.createElement(ModalBody, { style: { maxHeight: "31.5rem" } },
98
- React.createElement("p", { className: `${prefix}--bmrg-profile-settings__title` }, "More user profile settings will be here eventually, but for now you can choose which Teams are shown in your sidebar in Launchpad."),
99
- React.createElement("h2", { className: `${prefix}--bmrg-profile-settings__subtitle` }, "Teams visible in Launchpad sidebar"),
100
- React.createElement("p", { className: `${prefix}--bmrg-profile-settings__description` }, "Choose Teams to show or hide in your Launchpad sidebar and Catalog (useful for sensitive demos). You will not be able to access or view unchecked Teams from the sidebar, and cannot add items to them from Catalog."),
116
+ React.createElement("p", { className: `${prefix}--bmrg-profile-settings__title` }, "More user profile settings will be here eventually, but for now you can choose which Teams are shown in your team switcher in Launchpad."),
117
+ React.createElement("h2", { className: `${prefix}--bmrg-profile-settings__subtitle` }, "Teams visible in Launchpad team switcher"),
118
+ React.createElement("p", { className: `${prefix}--bmrg-profile-settings__description` }, "Choose Teams to show or hide in your Launchpad team switcher and Catalog (useful for sensitive demos). You will not be able to access or view unchecked Teams from the team switcher, and cannot add items to them from Catalog."),
101
119
  userIsLoading ? (React.createElement(StructuredListSkeleton, null)) : userError ? (React.createElement(Error, { style: { color: "#F2F4F8", padding: "1rem" } })) : teams?.length > 0 ? (React.createElement(StructuredListWrapper, { className: `${prefix}--bmrg-profile-settings-list` },
102
120
  React.createElement(StructuredListHead, null,
103
121
  React.createElement(StructuredListRow, { head: true },
@@ -18,11 +18,11 @@ IBM Confidential
18
18
  694970X, 69497O0
19
19
  © Copyright IBM Corp. 2022, 2024
20
20
  */
21
- function UIShell({ analyticsHelpers, baseEnvUrl, carbonTheme = "g10", config, createJoinTeamTrigger, history, isLaunchpad = false, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, leftPanel, platformName, productName, profileMenuItems = [], supportMenuItems = [], renderPrivacyRedirect = true, renderPrivacyStatement = true, rightPanel, handleShowTutorial, refetchUser, refetchNavigation, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, tutorialScreenToShow, user, userTeams, userTeamsAssets, enableIcaMacs, }) {
21
+ function UIShell({ analyticsHelpers, baseEnvUrl, carbonTheme = "g10", config, createJoinTeamTrigger, enableTeamSwitcher = true, history, isLaunchpad = false, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, leftPanel, platformName, productName, profileMenuItems = [], supportMenuItems = [], renderPrivacyRedirect = true, renderPrivacyStatement = true, rightPanel, handleShowTutorial, refetchUser, refetchUserTeams, refetchNavigation, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, tutorialScreenToShow, user, userTeams, userTeamsAssets, enableIcaMacs, }) {
22
22
  // Support base header .e.g for an error state
23
23
  if (!config) {
24
24
  return (React.createElement(QueryClientProvider, { client: queryClient },
25
- React.createElement(Header, { baseEnvUrl: baseEnvUrl ?? "", baseServicesUrl: "", carbonTheme: carbonTheme, enableAppSwitcher: false, enableNotifications: false, enableNotificationsCount: false, productName: productName || platformName || "", user: user })));
25
+ React.createElement(Header, { baseEnvUrl: baseEnvUrl ?? "", baseServicesUrl: "", carbonTheme: carbonTheme, enableAppSwitcher: false, enableNotifications: false, enableNotificationsCount: false, enableTeamSwitcher: enableTeamSwitcher, productName: productName || platformName || "", user: user })));
26
26
  }
27
27
  const { features, navigation, platform, platformMessage } = config;
28
28
  const names = getProductAndPlatformNames({ productName, platformName, platform });
@@ -63,8 +63,8 @@ function UIShell({ analyticsHelpers, baseEnvUrl, carbonTheme = "g10", config, cr
63
63
  */
64
64
  const isPrivacyStatementDisabled = renderPrivacyStatement === false || features?.["consent.enabled"] === false;
65
65
  return (React.createElement(QueryClientProvider, { client: queryClient },
66
- React.createElement(Header, { analyticsHelpers: analyticsHelpers, baseEnvUrl: platform.baseEnvUrl, baseServicesUrl: platform.baseServicesUrl, carbonTheme: carbonTheme, createJoinTeamTrigger: createJoinTeamTrigger, enableAppSwitcher: isAppSwitcherEnabled, instanceSwitcherEnabled: instanceSwitcherEnabled, enableNotifications: isNotificationsEnabled, enableNotificationsCount: isNotificationsCountEnabled, leftPanel: leftPanel, navLinks: navigation, platform: platform, platformMessage: platformMessage, prefixName: names.platformName, productName: names.productName, rightPanel: rightPanel, requestSummary: user?.requestSummary, skipToContentProps: skipToContentProps, templateMeteringEvent: templateMeteringEvent, triggerEvent: triggerEvent, profileMenuItems: [
67
- isUserEnabled && (React.createElement(ProfileSettingsMenuItem, { key: "profile-settings", baseServicesUrl: platform.baseServicesUrl, src: `${platform.baseServicesUrl}/users/image/${user?.email}`, userName: user?.displayName ?? user?.name })),
66
+ React.createElement(Header, { analyticsHelpers: analyticsHelpers, baseEnvUrl: platform.baseEnvUrl, baseServicesUrl: platform.baseServicesUrl, carbonTheme: carbonTheme, createJoinTeamTrigger: createJoinTeamTrigger, enableAppSwitcher: isAppSwitcherEnabled, instanceSwitcherEnabled: instanceSwitcherEnabled, enableNotifications: isNotificationsEnabled, enableNotificationsCount: isNotificationsCountEnabled, enableTeamSwitcher: enableTeamSwitcher, leftPanel: leftPanel, navLinks: navigation, platform: platform, platformMessage: platformMessage, prefixName: names.platformName, productName: names.productName, rightPanel: rightPanel, requestSummary: user?.requestSummary, skipToContentProps: skipToContentProps, templateMeteringEvent: templateMeteringEvent, triggerEvent: triggerEvent, profileMenuItems: [
67
+ isUserEnabled && (React.createElement(ProfileSettingsMenuItem, { key: "profile-settings", baseServicesUrl: platform.baseServicesUrl, src: `${platform.baseServicesUrl}/users/image/${user?.email}`, userName: user?.displayName ?? user?.name, refetchUser: refetchUser, refetchUserTeams: refetchUserTeams, refetchNavigation: refetchNavigation })),
68
68
  isSendMailEnabled && (React.createElement(HeaderMenuItem, { key: "email-preferences", href: `${platform.baseEnvUrl}/launchpad/email-preferences`, icon: React.createElement(Email, null), kind: "internal", text: "Email Preferences", type: "link" })),
69
69
  !isPrivacyStatementDisabled && (React.createElement(PrivacyStatementMenuItem, { key: "privacy-statement", baseServicesUrl: platform.baseServicesUrl, platformEmail: platform?.platformEmail })),
70
70
  ...profileMenuItems,
@@ -0,0 +1,13 @@
1
+ /*
2
+ IBM Confidential
3
+ 694970X, 69497O0
4
+ © Copyright IBM Corp. 2022, 2024
5
+ */
6
+ const TEAM_TYPES = {
7
+ ACCOUNT: "account",
8
+ PERSONAL: "personal",
9
+ PROJECT: "project",
10
+ STANDARD: "standard",
11
+ };
12
+
13
+ export { TEAM_TYPES };
@@ -366,6 +366,7 @@ type Props$G = {
366
366
  className?: string;
367
367
  createJoinTeamTrigger?: Function;
368
368
  enableAppSwitcher?: boolean;
369
+ enableTeamSwitcher?: boolean;
369
370
  instanceSwitcherEnabled?: boolean;
370
371
  enableNotifications?: boolean;
371
372
  enableNotificationsCount?: boolean;
@@ -1436,6 +1437,7 @@ type Props = {
1436
1437
  };
1437
1438
  platformMessage?: any;
1438
1439
  };
1440
+ enableTeamSwitcher?: boolean;
1439
1441
  history?: any;
1440
1442
  isLaunchpad?: boolean;
1441
1443
  isLoadingTeamSwitcher?: boolean;
@@ -1456,6 +1458,7 @@ type Props = {
1456
1458
  component: React.ReactNode;
1457
1459
  };
1458
1460
  refetchUser?: Function;
1461
+ refetchUserTeams?: Function;
1459
1462
  refetchNavigation?: Function;
1460
1463
  skipToContentProps?: {
1461
1464
  href?: string;
@@ -1481,6 +1484,6 @@ type Props = {
1481
1484
  handleShowTutorial?: Function;
1482
1485
  tutorialScreenToShow?: string;
1483
1486
  };
1484
- declare function UIShell({ analyticsHelpers, baseEnvUrl, carbonTheme, config, createJoinTeamTrigger, history, isLaunchpad, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, leftPanel, platformName, productName, profileMenuItems, supportMenuItems, renderPrivacyRedirect, renderPrivacyStatement, rightPanel, handleShowTutorial, refetchUser, refetchNavigation, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, tutorialScreenToShow, user, userTeams, userTeamsAssets, enableIcaMacs, }: Props): React.JSX.Element;
1487
+ declare function UIShell({ analyticsHelpers, baseEnvUrl, carbonTheme, config, createJoinTeamTrigger, enableTeamSwitcher, history, isLaunchpad, isLoadingTeamSwitcher, isSuccessTeamSwitcher, setIsSuccessTeamSwitcher, leftPanel, platformName, productName, profileMenuItems, supportMenuItems, renderPrivacyRedirect, renderPrivacyStatement, rightPanel, handleShowTutorial, refetchUser, refetchUserTeams, refetchNavigation, skipToContentProps, templateMeteringEvent, trackEvent, triggerEvent, tutorialScreenToShow, user, userTeams, userTeamsAssets, enableIcaMacs, }: Props): React.JSX.Element;
1485
1488
 
1486
1489
  export { AdvantageSideNav, AutoSuggestBmrg as AutoSuggest, Avatar, CheckboxListComponent as CheckboxList, ComboBoxComponent as ComboBox, ComboBoxMultiSelect, ComposedModal, ConfirmModal, CreatableComponent as Creatable, DataDrivenInput, DateInputComponent as DateInput, DecisionButtons, DelayedRender, DynamicFormik, DynamicInput, Error, Error403, Error404, ErrorBoundary, ErrorDragon, ErrorFullPage, Error as ErrorMessage, ErrorPage, ErrorPageCore, FeatureHeader, FeatureHeaderSubtitle, FeatureHeaderTitle, FeatureNavTab, FeatureNavTabs, FeatureSideNav, FeatureSideNavFooter, FeatureSideNavHeader, FeatureSideNavLink, FeatureSideNavLinks, FlowModalContainer as FlowModal, FlowModalForm, FormInput, Header, _default as HeaderMenuItem, ImageModal, InputGovernor, Loading, MemberBar, Modal, ModalConfirmEdit, FlowModalContainer as ModalFlow, FlowModalForm as ModalFlowForm, ModalForm, ModalFunctionChildrenProps, ModalTrigger, NotificationsContainer, PlatformBanner, PlatformNotificationsContainer, Portal, PrivacyStatement, ProtectedRoute, RadioGroupComponent as RadioGroup, RichTextAreaComponent as RichTextArea, SimpleTeamService, Team, TextAreaComponent as TextArea, TextInputComponent as TextInput, ToastNotification, ToggleComponent as Toggle, TooltipHover, UIShell, User, UserTeams, notify };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@boomerang-io/carbon-addons-boomerang-react",
3
3
  "description": "Carbon Addons for Boomerang apps",
4
- "version": "4.6.14-beta.1",
4
+ "version": "4.6.14-beta.11",
5
5
  "author": {
6
6
  "name": "Tim Bula",
7
7
  "email": "timrbula@gmail.com"
@@ -4,7 +4,6 @@ IBM Confidential
4
4
  © Copyright IBM Corp. 2022, 2024
5
5
  */
6
6
 
7
-
8
7
  @use "../../global/config" as *;
9
8
  @use "../../global/utils";
10
9
  @use "../../global/themes/shell-tokens" as shell;
@@ -29,6 +28,7 @@ IBM Confidential
29
28
 
30
29
  .#{$prefix}--modal-content {
31
30
  color: shell.$bmrg-theme-primary;
31
+ mask-image: none !important;
32
32
  .#{$prefix}--bmrg-profile-settings__title {
33
33
  color: shell.$bmrg-theme-primary;
34
34
  font-size: utils.rem(14px);