@learningpool/ui 1.15.5 → 1.16.1

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.
Files changed (84) hide show
  1. package/assets/Images.js +7 -18
  2. package/components/atoms/Autocomplete/Autocomplete.js +3 -14
  3. package/components/atoms/Button/Button.js +2 -13
  4. package/components/atoms/Checkbox/Checkbox.js +3 -26
  5. package/components/atoms/IconButton/IconButton.js +2 -13
  6. package/components/atoms/Radio/Radio.js +3 -26
  7. package/components/atoms/Select/Select.js +3 -26
  8. package/components/atoms/Slider/Slider.js +3 -26
  9. package/components/atoms/Switch/Switch.js +3 -26
  10. package/components/atoms/TextField/TextField.js +2 -13
  11. package/components/atoms/ToggleButton/ToggleButton.js +3 -26
  12. package/components/datadisplay/Avatar/Avatar.js +13 -28
  13. package/components/datadisplay/Chip/Chip.js +3 -26
  14. package/components/datadisplay/List/List.js +2 -13
  15. package/components/feedback/Alert/Alert.js +3 -26
  16. package/components/landmarks/Header/Header.js +15 -41
  17. package/components/landmarks/Header/HeaderActionButtons.d.ts +1 -2
  18. package/components/landmarks/Header/HeaderActionButtons.js +22 -33
  19. package/components/landmarks/Header/HeaderStyles.js +54 -11
  20. package/components/navigation/Drawer/Drawer.js +5 -31
  21. package/components/navigation/MobileNavigation/MobileNavigation.js +70 -82
  22. package/components/navigation/MobileNavigation/MobileNavigationAvatar.js +75 -83
  23. package/components/navigation/MobileNavigation/MobileNavigationAvatarStyles.d.ts +102 -52
  24. package/components/navigation/MobileNavigation/MobileNavigationAvatarStyles.js +71 -13
  25. package/components/navigation/MobileNavigation/MobileNavigationDrawer.d.ts +1 -1
  26. package/components/navigation/MobileNavigation/MobileNavigationDrawer.js +41 -68
  27. package/components/navigation/MobileNavigation/MobileNavigationDrawerStyles.d.ts +34 -18
  28. package/components/navigation/MobileNavigation/MobileNavigationDrawerStyles.js +133 -20
  29. package/components/navigation/MobileNavigation/MobileNavigationItem/MobileNavigationItem.js +22 -45
  30. package/components/navigation/MobileNavigation/MobileNavigationItem/MobileNavigationItemFlyoutMenu.js +8 -19
  31. package/components/navigation/MobileNavigation/MobileNavigationItem/MobileNavigationItemFlyoutMenuStyles.js +151 -52
  32. package/components/navigation/MobileNavigation/MobileNavigationItem/MobileNavigationItemStyles.js +171 -50
  33. package/components/navigation/MobileNavigation/MobileNavigationMotion.js +11 -11
  34. package/components/navigation/MobileNavigation/MobileNavigationNotchIndicator.js +11 -15
  35. package/components/navigation/MobileNavigation/MobileNavigationSearch.d.ts +1 -2
  36. package/components/navigation/MobileNavigation/MobileNavigationSearch.js +25 -34
  37. package/components/navigation/MobileNavigation/MobileNavigationSearchStyles.d.ts +34 -18
  38. package/components/navigation/MobileNavigation/MobileNavigationSearchStyles.js +47 -9
  39. package/components/navigation/MobileNavigation/MobileNavigationStyles.js +262 -66
  40. package/components/navigation/MobileNavigation/MobileNavigationToggleSearchX.js +21 -20
  41. package/components/navigation/MobileNavigation/MobileNavigationToggleX.js +21 -20
  42. package/components/navigation/VerticalNavigation/VerticalNavigation.js +150 -185
  43. package/components/navigation/VerticalNavigation/VerticalNavigationAvatar.js +50 -61
  44. package/components/navigation/VerticalNavigation/VerticalNavigationAvatarStyles.d.ts +102 -52
  45. package/components/navigation/VerticalNavigation/VerticalNavigationAvatarStyles.js +86 -14
  46. package/components/navigation/VerticalNavigation/VerticalNavigationItem/VerticalNavigationItem.js +27 -51
  47. package/components/navigation/VerticalNavigation/VerticalNavigationItem/VerticalNavigationItemFlyoutMenu.js +15 -28
  48. package/components/navigation/VerticalNavigation/VerticalNavigationItem/VerticalNavigationItemFlyoutMenuStyles.js +135 -39
  49. package/components/navigation/VerticalNavigation/VerticalNavigationItem/VerticalNavigationItemStyles.js +167 -29
  50. package/components/navigation/VerticalNavigation/VerticalNavigationMotion.js +11 -11
  51. package/components/navigation/VerticalNavigation/VerticalNavigationStyles.d.ts +34 -18
  52. package/components/navigation/VerticalNavigation/VerticalNavigationStyles.js +236 -42
  53. package/components/navigation/helpers.d.ts +1 -2
  54. package/components/navigation/helpers.js +28 -32
  55. package/components/pages/ErrorPage/ErrorPage.js +6 -17
  56. package/components/pages/ErrorPage/ErrorPageStyles.js +13 -18
  57. package/components/pages/SideInSide/SideInSide.js +12 -23
  58. package/components/pages/SideInSide/SideInSideStyles.js +6 -6
  59. package/components/stream/AppHub/AppHub.js +13 -42
  60. package/components/stream/AppHub/AppHubAdvertStyles.js +24 -8
  61. package/components/stream/AppHub/AppHubBannerAdvert.d.ts +1 -2
  62. package/components/stream/AppHub/AppHubBannerAdvert.js +9 -20
  63. package/components/stream/AppHub/AppHubCustom.js +8 -19
  64. package/components/stream/AppHub/AppHubCustomStyles.d.ts +1 -1
  65. package/components/stream/AppHub/AppHubCustomStyles.js +78 -18
  66. package/components/stream/AppHub/AppHubProduct.js +26 -48
  67. package/components/stream/AppHub/AppHubProductStyles.js +104 -19
  68. package/components/stream/AppHub/AppHubStyles.js +31 -11
  69. package/components/stream/AppHub/constants.d.ts +1 -2
  70. package/components/stream/AppHub/constants.js +14 -14
  71. package/components/stream/AppSwitcher/AppSwitcher.js +225 -316
  72. package/components/stream/AppSwitcher/AppSwitcherItem.js +11 -22
  73. package/components/stream/AppSwitcher/AppSwitcherStyles.js +337 -42
  74. package/components/stream/AppSwitcher/AppSwitcherStylesStandalone.js +255 -21
  75. package/components/stream/AppSwitcher/PromotionalCampaignItem.js +7 -19
  76. package/components/stream/AppSwitcher/constants.js +3 -3
  77. package/lang/en-us.js +1 -1
  78. package/package.json +7 -2
  79. package/utils/constants.d.ts +7 -0
  80. package/utils/constants.js +11 -4
  81. package/utils/dataAttributes.js +1 -1
  82. package/utils/helpers.js +33 -40
  83. package/utils/hooks.js +10 -11
  84. package/utils/theme.js +26 -19
@@ -1,51 +1,4 @@
1
- var __assign = (this && this.__assign) || function () {
2
- __assign = Object.assign || function(t) {
3
- for (var s, i = 1, n = arguments.length; i < n; i++) {
4
- s = arguments[i];
5
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
- t[p] = s[p];
7
- }
8
- return t;
9
- };
10
- return __assign.apply(this, arguments);
11
- };
12
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
- return new (P || (P = Promise))(function (resolve, reject) {
15
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
- step((generator = generator.apply(thisArg, _arguments || [])).next());
19
- });
20
- };
21
- var __generator = (this && this.__generator) || function (thisArg, body) {
22
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
- function verb(n) { return function (v) { return step([n, v]); }; }
25
- function step(op) {
26
- if (f) throw new TypeError("Generator is already executing.");
27
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
- if (y = 0, t) op = [op[0] & 2, t.value];
30
- switch (op[0]) {
31
- case 0: case 1: t = op; break;
32
- case 4: _.label++; return { value: op[1], done: false };
33
- case 5: _.label++; y = op[1]; op = [0]; continue;
34
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
- default:
36
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
- if (t[2]) _.ops.pop();
41
- _.trys.pop(); continue;
42
- }
43
- op = body.call(thisArg, _);
44
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
- }
47
- };
48
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
49
2
  import { useState, useEffect } from 'react';
50
3
  import PropTypes from 'prop-types';
51
4
  import jwtDecode from 'jwt-decode';
@@ -56,9 +9,10 @@ import { Constants } from './constants';
56
9
  import { defaultAttributes } from '../../../utils/dataAttributes';
57
10
  import ChevronRightIcon from '@mui/icons-material/ChevronRight';
58
11
  import PromotionalCampaignItem from './PromotionalCampaignItem';
59
- var addUtmParams = function (baseUrl, source, medium, campaign) {
12
+ import { EVENT_KEYS } from '../../../utils/constants';
13
+ const addUtmParams = (baseUrl, source, medium, campaign) => {
60
14
  try {
61
- var url = new URL(baseUrl);
15
+ const url = new URL(baseUrl);
62
16
  url.searchParams.append('utm_source', source);
63
17
  url.searchParams.append('utm_medium', medium);
64
18
  url.searchParams.append('utm_campaign', campaign);
@@ -69,92 +23,76 @@ var addUtmParams = function (baseUrl, source, medium, campaign) {
69
23
  return baseUrl;
70
24
  }
71
25
  };
72
- var AppSwitcher = function (props) {
73
- var _a;
74
- var isAppSwitcherOpen = props.isAppSwitcherOpen, handleToggleAppSwitcher = props.handleToggleAppSwitcher, isDrawerOpen = props.isDrawerOpen, localization = props.localization, dataAttributes = props.dataAttributes, _b = props.apiKey, apiKey = _b === void 0 ? '' : _b, baseUrl = props.baseUrl;
75
- var token = props.token;
26
+ const AppSwitcher = (props) => {
27
+ const { isAppSwitcherOpen, handleToggleAppSwitcher, isDrawerOpen, localization, dataAttributes, apiKey = '', baseUrl } = props;
28
+ let { token } = props;
76
29
  // Holds the applications which are displayed.
77
- var _c = useState([]), applications = _c[0], setApplications = _c[1];
30
+ const [applications, setApplications] = useState([]);
78
31
  // Holds the latest promotional campaign advert.
79
- var _d = useState(null), promotionalCampaigns = _d[0], setPromotionalCampaigns = _d[1];
32
+ const [promotionalCampaigns, setPromotionalCampaigns] = useState(null);
80
33
  // Controls which tab is active.
81
- var _e = useState(Constants.Tabs.ListApplications), activeTab = _e[0], setActiveTab = _e[1];
34
+ const [activeTab, setActiveTab] = useState(Constants.Tabs.ListApplications);
82
35
  // Holds the list of filtered organisations (on the second tab).
83
- var _f = useState([]), filteredOrgs = _f[0], setFilteredOrgs = _f[1];
36
+ const [filteredOrgs, setFilteredOrgs] = useState([]);
84
37
  // Holds a reference to the active application (on the second tab).
85
- var _g = useState(null), activeApplication = _g[0], setActiveApplication = _g[1];
38
+ const [activeApplication, setActiveApplication] = useState(null);
86
39
  // Stores any org filter text (on the second tab).
87
- var _h = useState(''), searchString = _h[0], setSearchString = _h[1];
40
+ const [searchString, setSearchString] = useState('');
88
41
  // Holds the number of valid promotional campaigns.
89
- var _j = useState((promotionalCampaigns === null || promotionalCampaigns === void 0 ? void 0 : promotionalCampaigns.length) || 0), validCampaignCount = _j[0], setValidCampaignCount = _j[1];
42
+ const [validCampaignCount, setValidCampaignCount] = useState(promotionalCampaigns?.length || 0);
90
43
  // Decrease the valid campaign count if an image fails to load.
91
- var handleCampaignImageError = function () {
92
- setValidCampaignCount(function (prev) { return Math.max(0, prev - 1); });
44
+ const handleCampaignImageError = () => {
45
+ setValidCampaignCount(prev => Math.max(0, prev - 1));
93
46
  };
94
- var messages = __assign(__assign({}, Constants.DefaultMessages), localization);
95
- var dataIds = __assign(__assign({}, defaultAttributes), dataAttributes);
96
- var userId = (_a = props.userId) !== null && _a !== void 0 ? _a : '';
47
+ const messages = { ...Constants.DefaultMessages, ...localization };
48
+ const dataIds = { ...defaultAttributes, ...dataAttributes };
49
+ let userId = props.userId ?? '';
97
50
  /**
98
51
  * Queries the Hub/Home API to fetch latest promotional campaign.
99
52
  * @returns {Promise<IApplication[]>} Get a Promotional Campaign to show.
100
53
  */
101
- var getLatestPromotionalCampaign = function () { return __awaiter(void 0, void 0, void 0, function () {
102
- var response, responseData, data, error_1;
103
- return __generator(this, function (_a) {
104
- switch (_a.label) {
105
- case 0:
106
- // If the access token has changed the endpoint should be called again.
107
- if (!token || typeof token !== 'string') {
108
- return [2 /*return*/, null];
109
- }
110
- _a.label = 1;
111
- case 1:
112
- _a.trys.push([1, 4, , 5]);
113
- return [4 /*yield*/, fetch("".concat(baseUrl !== null && baseUrl !== void 0 ? baseUrl : Constants.BaseUrl, "/promotional-campaigns?onlyLatest=true&isActive=true"), {
114
- method: 'get',
115
- headers: new Headers({
116
- Authorization: "Bearer ".concat(token),
117
- 'x-api-key': apiKey
118
- })
119
- })];
120
- case 2:
121
- response = _a.sent();
122
- if (!response.ok) {
123
- console.error('Unable to retrieve latest promotional campaign from Hub API, returned statuscode:', response.status);
124
- return [2 /*return*/, null];
125
- }
126
- return [4 /*yield*/, response.json()];
127
- case 3:
128
- responseData = _a.sent();
129
- data = responseData.records;
130
- // Store the latest access token
131
- window.localStorage.setItem(Constants.LocalStorageKey.Token, token);
132
- return [2 /*return*/, (data === null || data === void 0 ? void 0 : data.map(function (_a) {
133
- var id = _a.id, name = _a.name, appSwitcherImageUrl = _a.appSwitcherImageUrl, hubImageUrl = _a.hubImageUrl, altText = _a.altText, basePromoUrl = _a.basePromoUrl, isActive = _a.isActive;
134
- return ({
135
- id: id,
136
- name: name,
137
- appSwitcherImageUrl: appSwitcherImageUrl,
138
- hubImageUrl: hubImageUrl,
139
- altText: altText,
140
- basePromoUrl: basePromoUrl,
141
- isActive: isActive
142
- });
143
- })) || null];
144
- case 4:
145
- error_1 = _a.sent();
146
- console.error('Unable to retrieve and display latest promotional campaign from Hub API', error_1);
147
- return [2 /*return*/, null];
148
- case 5: return [2 /*return*/];
54
+ const getLatestPromotionalCampaign = async () => {
55
+ // If the access token has changed the endpoint should be called again.
56
+ if (!token || typeof token !== 'string') {
57
+ return null;
58
+ }
59
+ try {
60
+ const response = await fetch(`${baseUrl ?? Constants.BaseUrl}/promotional-campaigns?onlyLatest=true&isActive=true`, {
61
+ method: 'get',
62
+ headers: new Headers({
63
+ Authorization: `Bearer ${token}`,
64
+ 'x-api-key': apiKey
65
+ })
66
+ });
67
+ if (!response.ok) {
68
+ console.error('Unable to retrieve latest promotional campaign from Hub API, returned statuscode:', response.status);
69
+ return null;
149
70
  }
150
- });
151
- }); };
71
+ const responseData = await response.json();
72
+ const data = responseData.records;
73
+ // Store the latest access token
74
+ window.localStorage.setItem(Constants.LocalStorageKey.Token, token);
75
+ return data?.map(({ id, name, appSwitcherImageUrl, hubImageUrl, altText, basePromoUrl, isActive }) => ({
76
+ id,
77
+ name,
78
+ appSwitcherImageUrl,
79
+ hubImageUrl,
80
+ altText,
81
+ basePromoUrl,
82
+ isActive
83
+ })) || null;
84
+ }
85
+ catch (error) {
86
+ console.error('Unable to retrieve and display latest promotional campaign from Hub API', error);
87
+ return null;
88
+ }
89
+ };
152
90
  /**
153
91
  * Handles closing of the application dialog.
154
92
  */
155
- var handleDialogClose = function () {
93
+ const handleDialogClose = () => {
156
94
  handleToggleAppSwitcher();
157
- setTimeout(function () {
95
+ setTimeout(() => {
158
96
  setSearchString('');
159
97
  setActiveApplication(null);
160
98
  setActiveTab(Constants.Tabs.ListApplications);
@@ -164,7 +102,7 @@ var AppSwitcher = function (props) {
164
102
  * Updates the search/filter text.
165
103
  * @param event {React.ChangeEvent}
166
104
  */
167
- var handleSearchChange = function (event) {
105
+ const handleSearchChange = (event) => {
168
106
  setSearchString(event.target.value);
169
107
  };
170
108
  /**
@@ -173,13 +111,13 @@ var AppSwitcher = function (props) {
173
111
  * @param applicationId {number | undefined} - Unique identifier of the application.
174
112
  * @returns {void}
175
113
  */
176
- var handleGoToAppClick = function (event, applicationId) {
177
- event === null || event === void 0 ? void 0 : event.preventDefault();
178
- event === null || event === void 0 ? void 0 : event.stopPropagation();
114
+ const handleGoToAppClick = (event, applicationId) => {
115
+ event?.preventDefault();
116
+ event?.stopPropagation();
179
117
  if (!applicationId) {
180
118
  return;
181
119
  }
182
- var selectedApplication = applications.find(function (a) { return a.applicationId === applicationId; });
120
+ const selectedApplication = applications.find(a => a.applicationId === applicationId);
183
121
  if (!selectedApplication) {
184
122
  return;
185
123
  }
@@ -192,222 +130,196 @@ var AppSwitcher = function (props) {
192
130
  * @param internalName {string | null | undefined } - Internal name of the application.
193
131
  * @returns {ReactElement | null } SVG containing the application logo retrieved from the CDN.
194
132
  */
195
- var renderApplicationLogo = function (internalName, logoVariant) {
133
+ const renderApplicationLogo = (internalName, logoVariant) => {
196
134
  if (!internalName) {
197
135
  return _jsx(_Fragment, {});
198
136
  }
199
- var urlToIcon = "".concat(Constants.AssetsUrl).concat(internalName, "/logo/latest/").concat(logoVariant !== null && logoVariant !== void 0 ? logoVariant : LogoVariants.Default, ".svg");
137
+ const urlToIcon = `${Constants.AssetsUrl}${internalName}/logo/latest/${logoVariant ?? LogoVariants.Default}.svg`;
200
138
  return (_jsx("svg", { children: _jsx("image", { xlinkHref: urlToIcon, width: "60", height: "60" }) }));
201
139
  };
202
140
  /**
203
141
  * Queries the Steam Home API to fetch a list of applications.
204
142
  * @returns {Promise<IApplication[]>} A list of applications the user has access to.
205
143
  */
206
- var getApplicationsForUser = function () { return __awaiter(void 0, void 0, void 0, function () {
207
- var decodedToken, response, data;
208
- return __generator(this, function (_a) {
209
- switch (_a.label) {
210
- case 0:
211
- if (!(token && typeof token === 'string' && token !== window.localStorage.getItem(Constants.LocalStorageKey.Token))) return [3 /*break*/, 3];
212
- if (!userId) {
213
- decodedToken = jwtDecode(token);
214
- userId = decodedToken[Constants.HomeAttributes.UserId];
215
- }
216
- return [4 /*yield*/, fetch("".concat(baseUrl !== null && baseUrl !== void 0 ? baseUrl : Constants.BaseUrl, "/users/").concat(userId, "/application-instances"), {
217
- method: 'get',
218
- headers: new Headers({
219
- Authorization: "Bearer ".concat(token),
220
- 'x-api-key': apiKey
144
+ const getApplicationsForUser = async () => {
145
+ // If the access token has changed the endpoint should be called again.
146
+ if (token && typeof token === 'string' && token !== window.localStorage.getItem(Constants.LocalStorageKey.Token)) {
147
+ if (!userId) {
148
+ // Extract user identifier from the JWT.
149
+ const decodedToken = jwtDecode(token);
150
+ userId = decodedToken[Constants.HomeAttributes.UserId];
151
+ }
152
+ const response = await fetch(`${baseUrl ?? Constants.BaseUrl}/users/${userId}/application-instances`, {
153
+ method: 'get',
154
+ headers: new Headers({
155
+ Authorization: `Bearer ${token}`,
156
+ 'x-api-key': apiKey
157
+ })
158
+ });
159
+ if (response.status !== 200) {
160
+ console.error('Unable to retrieve user applications from Stream Home');
161
+ return [];
162
+ }
163
+ const data = await response.json();
164
+ // Store the latest access token.
165
+ window.localStorage.setItem(Constants.LocalStorageKey.Token, token);
166
+ return data.map((application) => {
167
+ const { applicationId, applicationName, shortName, internalName, customName, url } = application;
168
+ return {
169
+ applicationId,
170
+ applicationName,
171
+ shortName,
172
+ internalName,
173
+ customName,
174
+ url: url || ''
175
+ };
176
+ });
177
+ }
178
+ else {
179
+ return [];
180
+ }
181
+ };
182
+ useEffect(() => {
183
+ const loadData = async () => {
184
+ let applicationInstances = [];
185
+ let userApplications = [];
186
+ if (!token) {
187
+ const parsedQueryString = queryString.parse(window.location.search);
188
+ if (parsedQueryString.token && typeof parsedQueryString.token === 'string') {
189
+ token = parsedQueryString.token;
190
+ }
191
+ else {
192
+ // Check the 'hash'.
193
+ const match = window.location.hash.match(/token=(.*)/);
194
+ token = (match && match.length === 2 && match[1]) || '';
195
+ }
196
+ }
197
+ if (!props.applications || props.applications.length === 0) {
198
+ applicationInstances = await getApplicationsForUser();
199
+ }
200
+ else {
201
+ // A hard-coded list of applications has been passed to the component.
202
+ applicationInstances = props.applications;
203
+ }
204
+ if (Array.isArray(applicationInstances) && applicationInstances.length) {
205
+ // Get a distinct list of applications the user has access to.
206
+ const uniqueApplicationIds = applicationInstances.map((item) => item.applicationId).filter((value, index, self) => self.indexOf(value) === index);
207
+ // Iterate over these to build up the userApplications array.
208
+ uniqueApplicationIds.forEach(applicationId => {
209
+ const applications = applicationInstances.filter(instance => instance.applicationId === applicationId);
210
+ if (applications.length > 1) {
211
+ // This is an application with multiple orgs/tenants the user has access to.
212
+ userApplications.push({
213
+ applicationId,
214
+ applicationName: applications[0].applicationName,
215
+ shortName: applications[0].shortName,
216
+ customName: applications[0].customName,
217
+ internalName: applications[0].internalName,
218
+ url: '',
219
+ children: applications.map(a => {
220
+ return {
221
+ name: a.customName ?? a.applicationName,
222
+ url: a.url
223
+ };
221
224
  })
222
- })];
223
- case 1:
224
- response = _a.sent();
225
- if (response.status !== 200) {
226
- console.error('Unable to retrieve user applications from Stream Home');
227
- return [2 /*return*/, []];
225
+ });
228
226
  }
229
- return [4 /*yield*/, response.json()
230
- // Store the latest access token.
231
- ];
232
- case 2:
233
- data = _a.sent();
234
- // Store the latest access token.
235
- window.localStorage.setItem(Constants.LocalStorageKey.Token, token);
236
- return [2 /*return*/, data.map(function (application) {
237
- var applicationId = application.applicationId, applicationName = application.applicationName, shortName = application.shortName, internalName = application.internalName, customName = application.customName, url = application.url;
238
- return {
239
- applicationId: applicationId,
240
- applicationName: applicationName,
241
- shortName: shortName,
242
- internalName: internalName,
243
- customName: customName,
244
- url: url || ''
245
- };
246
- })];
247
- case 3: return [2 /*return*/, []];
227
+ else {
228
+ // This is a standalone application.
229
+ userApplications.push({
230
+ applicationId: applications[0].applicationId,
231
+ applicationName: applications[0].applicationName,
232
+ shortName: applications[0].shortName,
233
+ customName: applications[0].customName,
234
+ internalName: applications[0].internalName,
235
+ url: applications[0].url
236
+ });
237
+ }
238
+ });
239
+ // Serialize and cache the applications returned.
240
+ window.localStorage.setItem(Constants.LocalStorageKey.Applications, JSON.stringify(userApplications));
248
241
  }
249
- });
250
- }); };
251
- useEffect(function () {
252
- var loadData = function () { return __awaiter(void 0, void 0, void 0, function () {
253
- var applicationInstances, userApplications, parsedQueryString, match, uniqueApplicationIds, localApplications;
254
- return __generator(this, function (_a) {
255
- switch (_a.label) {
256
- case 0:
257
- applicationInstances = [];
258
- userApplications = [];
259
- if (!token) {
260
- parsedQueryString = queryString.parse(window.location.search);
261
- if (parsedQueryString.token && typeof parsedQueryString.token === 'string') {
262
- token = parsedQueryString.token;
263
- }
264
- else {
265
- match = window.location.hash.match(/token=(.*)/);
266
- token = (match && match.length === 2 && match[1]) || '';
267
- }
268
- }
269
- if (!(!props.applications || props.applications.length === 0)) return [3 /*break*/, 2];
270
- return [4 /*yield*/, getApplicationsForUser()];
271
- case 1:
272
- applicationInstances = _a.sent();
273
- return [3 /*break*/, 3];
274
- case 2:
275
- // A hard-coded list of applications has been passed to the component.
276
- applicationInstances = props.applications;
277
- _a.label = 3;
278
- case 3:
279
- if (Array.isArray(applicationInstances) && applicationInstances.length) {
280
- uniqueApplicationIds = applicationInstances.map(function (item) { return item.applicationId; }).filter(function (value, index, self) { return self.indexOf(value) === index; });
281
- // Iterate over these to build up the userApplications array.
282
- uniqueApplicationIds.forEach(function (applicationId) {
283
- var applications = applicationInstances.filter(function (instance) { return instance.applicationId === applicationId; });
284
- if (applications.length > 1) {
285
- // This is an application with multiple orgs/tenants the user has access to.
286
- userApplications.push({
287
- applicationId: applicationId,
288
- applicationName: applications[0].applicationName,
289
- shortName: applications[0].shortName,
290
- customName: applications[0].customName,
291
- internalName: applications[0].internalName,
292
- url: '',
293
- children: applications.map(function (a) {
294
- var _a;
295
- return {
296
- name: (_a = a.customName) !== null && _a !== void 0 ? _a : a.applicationName,
297
- url: a.url
298
- };
299
- })
300
- });
301
- }
302
- else {
303
- // This is a standalone application.
304
- userApplications.push({
305
- applicationId: applications[0].applicationId,
306
- applicationName: applications[0].applicationName,
307
- shortName: applications[0].shortName,
308
- customName: applications[0].customName,
309
- internalName: applications[0].internalName,
310
- url: applications[0].url
311
- });
312
- }
313
- });
314
- // Serialize and cache the applications returned.
315
- window.localStorage.setItem(Constants.LocalStorageKey.Applications, JSON.stringify(userApplications));
316
- }
317
- else {
318
- localApplications = window.localStorage.getItem(Constants.LocalStorageKey.Applications);
319
- if (localApplications) {
320
- // Recreate the application state from local storage.
321
- userApplications = JSON.parse(localApplications);
322
- }
323
- }
324
- // Store the user's applications.
325
- setApplications(userApplications);
326
- return [2 /*return*/];
242
+ else {
243
+ const localApplications = window.localStorage.getItem(Constants.LocalStorageKey.Applications);
244
+ if (localApplications) {
245
+ // Recreate the application state from local storage.
246
+ userApplications = JSON.parse(localApplications);
327
247
  }
328
- });
329
- }); };
248
+ }
249
+ // Store the user's applications.
250
+ setApplications(userApplications);
251
+ };
330
252
  loadData()
331
253
  .catch(console.error);
332
254
  }, [token, userId, props.applications]);
333
- useEffect(function () {
334
- var loadPromotionalCampaigns = function () { return __awaiter(void 0, void 0, void 0, function () {
335
- var promotionalCampaigns_1, localPromotionalCampaignsJson, parsedCampaigns, error_2;
336
- return __generator(this, function (_a) {
337
- switch (_a.label) {
338
- case 0:
339
- _a.trys.push([0, 5, , 6]);
340
- promotionalCampaigns_1 = null;
341
- if (!(props.promotionalCampaigns && props.promotionalCampaigns.length > 0)) return [3 /*break*/, 1];
342
- promotionalCampaigns_1 = props.promotionalCampaigns;
343
- return [3 /*break*/, 4];
344
- case 1:
345
- if (!(token && typeof token === 'string' &&
346
- token !== window.localStorage.getItem(Constants.LocalStorageKey.Token))) return [3 /*break*/, 3];
347
- return [4 /*yield*/, getLatestPromotionalCampaign()];
348
- case 2:
349
- // Fetch from API if token has changed
350
- promotionalCampaigns_1 = _a.sent();
351
- return [3 /*break*/, 4];
352
- case 3:
353
- localPromotionalCampaignsJson = window.localStorage.getItem(Constants.LocalStorageKey.PromotionalCampaigns);
354
- if (localPromotionalCampaignsJson) {
355
- try {
356
- parsedCampaigns = JSON.parse(localPromotionalCampaignsJson);
357
- if (Array.isArray(parsedCampaigns)) {
358
- promotionalCampaigns_1 = parsedCampaigns;
359
- }
360
- }
361
- catch (error) {
362
- console.error('Error parsing stored campaigns:', error);
255
+ useEffect(() => {
256
+ const loadPromotionalCampaigns = async () => {
257
+ try {
258
+ let promotionalCampaigns = null;
259
+ // Use props if available
260
+ if (props.promotionalCampaigns && props.promotionalCampaigns.length > 0) {
261
+ promotionalCampaigns = props.promotionalCampaigns;
262
+ }
263
+ else if (token && typeof token === 'string' &&
264
+ token !== window.localStorage.getItem(Constants.LocalStorageKey.Token)) {
265
+ // Fetch from API if token has changed
266
+ promotionalCampaigns = await getLatestPromotionalCampaign();
267
+ }
268
+ else {
269
+ // Check localStorage
270
+ const localPromotionalCampaignsJson = window.localStorage.getItem(Constants.LocalStorageKey.PromotionalCampaigns);
271
+ if (localPromotionalCampaignsJson) {
272
+ try {
273
+ const parsedCampaigns = JSON.parse(localPromotionalCampaignsJson);
274
+ if (Array.isArray(parsedCampaigns)) {
275
+ promotionalCampaigns = parsedCampaigns;
363
276
  }
364
277
  }
365
- _a.label = 4;
366
- case 4:
367
- // Update state and cache if we have campaigns
368
- if (Array.isArray(promotionalCampaigns_1) && promotionalCampaigns_1.length > 0) {
369
- setPromotionalCampaigns(promotionalCampaigns_1);
370
- setValidCampaignCount(promotionalCampaigns_1.length);
371
- window.localStorage.setItem(Constants.LocalStorageKey.PromotionalCampaigns, JSON.stringify(promotionalCampaigns_1));
372
- }
373
- else {
374
- setPromotionalCampaigns(null);
278
+ catch (error) {
279
+ console.error('Error parsing stored campaigns:', error);
375
280
  }
376
- return [3 /*break*/, 6];
377
- case 5:
378
- error_2 = _a.sent();
379
- console.error('Error loading promotional campaigns:', error_2);
380
- setPromotionalCampaigns(null);
381
- return [3 /*break*/, 6];
382
- case 6: return [2 /*return*/];
281
+ }
383
282
  }
384
- });
385
- }); };
283
+ // Update state and cache if we have campaigns
284
+ if (Array.isArray(promotionalCampaigns) && promotionalCampaigns.length > 0) {
285
+ setPromotionalCampaigns(promotionalCampaigns);
286
+ setValidCampaignCount(promotionalCampaigns.length);
287
+ window.localStorage.setItem(Constants.LocalStorageKey.PromotionalCampaigns, JSON.stringify(promotionalCampaigns));
288
+ }
289
+ else {
290
+ setPromotionalCampaigns(null);
291
+ }
292
+ }
293
+ catch (error) {
294
+ console.error('Error loading promotional campaigns:', error);
295
+ setPromotionalCampaigns(null);
296
+ }
297
+ };
386
298
  loadPromotionalCampaigns()
387
299
  .catch(console.error);
388
300
  }, [token, props.promotionalCampaigns]);
389
- useEffect(function () {
301
+ useEffect(() => {
390
302
  if (isAppSwitcherOpen) {
391
303
  document.addEventListener('mousedown', handleAppSwitcherClose);
392
304
  }
393
- return function () {
305
+ return () => {
394
306
  document.removeEventListener('mousedown', handleAppSwitcherClose);
395
307
  };
396
308
  }, [isAppSwitcherOpen]);
397
- useEffect(function () { return document.addEventListener('keydown', handleKeyDown); });
398
- var handleAppSwitcherClose = function (event) {
399
- var appSwitcherButton = document.getElementById(defaultAttributes.VerticalNavigationAppSwitcherToggle);
309
+ useEffect(() => document.addEventListener('keydown', handleKeyDown));
310
+ const handleAppSwitcherClose = (event) => {
311
+ const appSwitcherButton = document.getElementById(defaultAttributes.VerticalNavigationAppSwitcherToggle);
400
312
  // Allow the appswitcher button to handle closing instead of closing it here.
401
- if (appSwitcherButton === null || appSwitcherButton === void 0 ? void 0 : appSwitcherButton.contains(event.target)) {
313
+ if (appSwitcherButton?.contains(event.target)) {
402
314
  return;
403
315
  }
404
316
  // Close the dialog when clicking outside the panel.
405
317
  handleDialogClose();
406
318
  };
407
- var handleKeyDown = function (event) {
408
- if (isAppSwitcherOpen && event && event.type === 'keydown') {
319
+ const handleKeyDown = (event) => {
320
+ if (isAppSwitcherOpen && event && event.type === EVENT_KEYS.Keydown) {
409
321
  // Close AppSwitcher if Escape key is pressed
410
- if (event.key === 'Escape') {
322
+ if (event.key === EVENT_KEYS.Escape) {
411
323
  handleDialogClose();
412
324
  // Doesn't return focus but we need to investigate MUI again
413
325
  // so that should handle it
@@ -417,26 +329,23 @@ var AppSwitcher = function (props) {
417
329
  if (!props.applications && (!token || !apiKey)) {
418
330
  return null;
419
331
  }
420
- var _k = props.hidePromotionalCampaign, hidePromotionalCampaign = _k === void 0 ? false : _k;
421
- return (_jsxs(AppSwitcherPanel, __assign({ id: "app-switcher-menu", style: {
332
+ const { hidePromotionalCampaign = false } = props;
333
+ return (_jsxs(AppSwitcherPanel, { id: "app-switcher-menu", style: {
422
334
  display: isAppSwitcherOpen ? 'block' : 'none',
423
335
  left: isDrawerOpen ? Constants.DrawerWidth.Expanded : Constants.DrawerWidth.Collapsed - 3
424
- }, role: 'dialog', "aria-label": "App Switcher", onKeyDown: handleKeyDown, "data-id": dataIds.AppSwitcherContainer, hasPromotionalCampaign: validCampaignCount > 0, onMouseDown: function (event) { return event.stopPropagation(); } }, { children: [activeTab === Constants.Tabs.ListApplications
425
- ? (_jsxs("div", { children: [!hidePromotionalCampaign && promotionalCampaigns && promotionalCampaigns.length > 0 && (_jsx("div", __assign({ className: "promotional-campaigns-container" }, { children: promotionalCampaigns.map(function (campaign) { return (_jsx(PromotionalCampaignItem, { imageUrl: campaign.appSwitcherImageUrl, altText: campaign.altText || messages['app-switcher-alt-text'], linkUrl: addUtmParams(campaign.basePromoUrl, document.title || 'app_switcher', 'app_switcher_advert', campaign.name), onImageError: handleCampaignImageError }, campaign.id)); }) }))), _jsxs(AppListHeader, __assign({ "data-id": dataIds.AppSwitcherHeader }, { children: [messages['your-apps'], !props.hideStreamHomeButton &&
426
- _jsx(StyleHomeButton, __assign({ "aria-label": messages['go-to-hub'], endIcon: _jsx(ChevronRightIcon, {}), onClick: function (e) { var _a; return window.open((_a = props.StreamHomeUrl) !== null && _a !== void 0 ? _a : Constants.DefaultStreamHomeUrl); } }, { children: messages['go-to-hub'] }))] })), _jsx(MenuContent, __assign({ style: {
336
+ }, role: 'dialog', "aria-label": "App Switcher", onKeyDown: handleKeyDown, "data-id": dataIds.AppSwitcherContainer, hasPromotionalCampaign: validCampaignCount > 0, onMouseDown: (event) => event.stopPropagation(), children: [activeTab === Constants.Tabs.ListApplications
337
+ ? (_jsxs("div", { children: [!hidePromotionalCampaign && promotionalCampaigns && promotionalCampaigns.length > 0 && (_jsx("div", { className: "promotional-campaigns-container", children: promotionalCampaigns.map((campaign) => (_jsx(PromotionalCampaignItem, { imageUrl: campaign.appSwitcherImageUrl, altText: campaign.altText || messages['app-switcher-alt-text'], linkUrl: addUtmParams(campaign.basePromoUrl, document.title || 'app_switcher', 'app_switcher_advert', campaign.name), onImageError: handleCampaignImageError }, campaign.id))) })), _jsxs(AppListHeader, { "data-id": dataIds.AppSwitcherHeader, children: [messages['your-apps'], !props.hideStreamHomeButton &&
338
+ _jsx(StyleHomeButton, { "aria-label": messages['go-to-hub'], endIcon: _jsx(ChevronRightIcon, {}), onClick: e => window.open(props.StreamHomeUrl ?? Constants.DefaultStreamHomeUrl), children: messages['go-to-hub'] })] }), _jsx(MenuContent, { style: {
427
339
  display: activeTab === 1 ? 'flex' : 'none'
428
- }, "data-id": dataIds.AppSwitcherList }, { children: applications.map(function (_a) {
429
- var applicationId = _a.applicationId, applicationName = _a.applicationName, shortName = _a.shortName, customName = _a.customName, internalName = _a.internalName, url = _a.url, children = _a.children;
430
- return (_jsxs(AppListItem, __assign({ "data-id": dataIds.AppSwitcherItem }, { children: [url && (_jsx(AppSwitcherItem, { internalName: internalName, shortName: shortName, customName: customName, url: url, handleGoToAppClick: handleGoToAppClick })), !url && (_jsx(AppSwitcherItem, { internalName: internalName, shortName: shortName, customName: customName, handleGoToAppClick: handleGoToAppClick, applicationId: applicationId })), children && (_jsx(AppOrganisationCount, __assign({ "data-id": dataIds.AppSwitcherOrgCount }, { children: children.length })))] }), applicationId));
431
- }) }))] }))
340
+ }, "data-id": dataIds.AppSwitcherList, children: applications.map(({ applicationId, applicationName, shortName, customName, internalName, url, children }) => (_jsxs(AppListItem, { "data-id": dataIds.AppSwitcherItem, children: [url && (_jsx(AppSwitcherItem, { internalName: internalName, shortName: shortName, customName: customName, url: url, handleGoToAppClick: handleGoToAppClick })), !url && (_jsx(AppSwitcherItem, { internalName: internalName, shortName: shortName, customName: customName, handleGoToAppClick: handleGoToAppClick, applicationId: applicationId })), children && (_jsx(AppOrganisationCount, { "data-id": dataIds.AppSwitcherOrgCount, children: children.length }))] }, applicationId))) })] }))
432
341
  : null, activeTab === Constants.Tabs.ListOrgs
433
- ? (_jsxs(SearchContent, __assign({ style: {
342
+ ? (_jsxs(SearchContent, { style: {
434
343
  display: activeTab === 2 ? 'flex' : 'none'
435
- }, "data-id": dataIds.AppSwitcherOrgPanel }, { children: [_jsxs(BackButton, __assign({ onClick: function () {
344
+ }, "data-id": dataIds.AppSwitcherOrgPanel, children: [_jsxs(BackButton, { onClick: () => {
436
345
  setActiveTab(Constants.Tabs.ListApplications);
437
346
  setSearchString('');
438
- }, "data-id": dataIds.AppSwitcherOrgBackButton }, { children: [_jsx(StyledSVG, __assign({ className: "MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiBox-root css-1om0hkc", focusable: "false", "aria-hidden": "true", viewBox: "0 0 24 24", "data-testid": "ChevronLeftIcon" }, { children: _jsx("path", { d: "M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) })), messages['back-to']] })), _jsxs(SelectedOrganisation, __assign({ "data-id": dataIds.AppSwitcherOrgHeader }, { children: [renderApplicationLogo(activeApplication === null || activeApplication === void 0 ? void 0 : activeApplication.internalName, LogoVariants.Solid), _jsx("span", { children: activeApplication ? activeApplication.applicationName : '' })] })), _jsx(SearchBox, { id: "app-switcher-search-org", type: 'text', value: searchString, onChange: handleSearchChange, placeholder: messages.search, "data-id": dataIds.AppSwitcherOrgSearch }), _jsx(OrganisationList, __assign({ "data-id": dataIds.AppSwitcherOrgList }, { children: filteredOrgs === null || filteredOrgs === void 0 ? void 0 : filteredOrgs.filter(function (o) { return o.name.toLowerCase().includes(searchString.toLowerCase()); }).map(function (org, i) { return (_jsxs(OrganisationLink, __assign({ href: org.url, target: "_blank", "data-id": dataIds.AppSwitcherOrgItem }, { children: [org.name, _jsx(StyledSVG, __assign({ className: "MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiBox-root css-1om0hkc", focusable: "false", "aria-hidden": "true", viewBox: "0 0 24 24", "data-testid": "ChevronRightIcon" }, { children: _jsx("path", { d: "M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) }))] }), i)); }) }))] })))
439
- : null] })));
347
+ }, "data-id": dataIds.AppSwitcherOrgBackButton, children: [_jsx(StyledSVG, { className: "MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiBox-root css-1om0hkc", focusable: "false", "aria-hidden": "true", viewBox: "0 0 24 24", "data-testid": "ChevronLeftIcon", children: _jsx("path", { d: "M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z" }) }), messages['back-to']] }), _jsxs(SelectedOrganisation, { "data-id": dataIds.AppSwitcherOrgHeader, children: [renderApplicationLogo(activeApplication?.internalName, LogoVariants.Solid), _jsx("span", { children: activeApplication ? activeApplication.applicationName : '' })] }), _jsx(SearchBox, { id: "app-switcher-search-org", type: 'text', value: searchString, onChange: handleSearchChange, placeholder: messages.search, "data-id": dataIds.AppSwitcherOrgSearch }), _jsx(OrganisationList, { "data-id": dataIds.AppSwitcherOrgList, children: filteredOrgs?.filter(o => o.name.toLowerCase().includes(searchString.toLowerCase())).map((org, i) => (_jsxs(OrganisationLink, { href: org.url, target: "_blank", "data-id": dataIds.AppSwitcherOrgItem, children: [org.name, _jsx(StyledSVG, { className: "MuiSvgIcon-root MuiSvgIcon-fontSizeMedium MuiBox-root css-1om0hkc", focusable: "false", "aria-hidden": "true", viewBox: "0 0 24 24", "data-testid": "ChevronRightIcon", children: _jsx("path", { d: "M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) })] }, i))) })] }))
348
+ : null] }));
440
349
  };
441
350
  AppSwitcher.propTypes = {
442
351
  token: PropTypes.string,