varminer-app-header 2.6.3 → 2.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AppHeader.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +111 -62
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +111 -62
- package/dist/index.js.map +1 -1
- package/dist/utils/localStorage.d.ts +2 -1
- package/dist/utils/localStorage.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -128,21 +128,80 @@ function setHeaderAuth(auth) {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
/**
|
|
131
|
-
* User display data:
|
|
131
|
+
* User display data: prefers linn-i-am-userDetails (IAM), falls back to
|
|
132
|
+
* persist:userdb → profileInformation.userDetails, then authDetails.auth.user.
|
|
132
133
|
*/
|
|
133
134
|
const getUserDataFromStorage = () => {
|
|
135
|
+
// Primary source: IAM app sets this after OTP verification
|
|
134
136
|
const iamUser = getStoredUserDetails();
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
137
|
+
if (iamUser) {
|
|
138
|
+
const name = [iamUser.firstName, iamUser.lastName].filter(Boolean).join(" ").trim();
|
|
139
|
+
const role = iamUser.roles?.length ? iamUser.roles[0] : iamUser.workInfo?.jobTitle ?? "";
|
|
140
|
+
return {
|
|
141
|
+
name: name || "",
|
|
142
|
+
email: iamUser.email || "",
|
|
143
|
+
role: role || "",
|
|
144
|
+
avatar: undefined,
|
|
145
|
+
initials: name ? name.split(/\s+/).map((s) => s[0]).join("").slice(0, 2).toUpperCase() : undefined,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// Fallback: read from persist:userdb which is written by the IAM/login app
|
|
149
|
+
try {
|
|
150
|
+
const raw = localStorage.getItem("persist:userdb");
|
|
151
|
+
if (!raw)
|
|
152
|
+
return null;
|
|
153
|
+
const outer = JSON.parse(raw);
|
|
154
|
+
const parseNested = (v) => {
|
|
155
|
+
if (typeof v === "string") {
|
|
156
|
+
try {
|
|
157
|
+
return JSON.parse(v);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return v;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return v;
|
|
164
|
+
};
|
|
165
|
+
// profileInformation.userDetails has firstName, lastName, email, roles[]
|
|
166
|
+
const profileInfo = parseNested(outer.profileInformation);
|
|
167
|
+
const userDetails = profileInfo?.userDetails;
|
|
168
|
+
if (userDetails && (userDetails.firstName || userDetails.lastName || userDetails.email)) {
|
|
169
|
+
const first = userDetails.firstName || "";
|
|
170
|
+
const last = userDetails.lastName || "";
|
|
171
|
+
const name = [first, last].filter(Boolean).join(" ").trim();
|
|
172
|
+
const roles = userDetails.roles;
|
|
173
|
+
const role = roles?.length ? roles[0] : userDetails.jobTitle ?? "";
|
|
174
|
+
return {
|
|
175
|
+
name,
|
|
176
|
+
email: userDetails.email || "",
|
|
177
|
+
role: role || "",
|
|
178
|
+
avatar: undefined,
|
|
179
|
+
initials: name ? name.split(/\s+/).map((s) => s[0]).join("").slice(0, 2).toUpperCase() : undefined,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// authDetails.auth.user has firstname/lastname (lowercase n) or firstName/lastName (camelCase) + activeRole
|
|
183
|
+
const authDetailsRaw = parseNested(outer.authDetails);
|
|
184
|
+
const auth = authDetailsRaw?.auth;
|
|
185
|
+
const userObj = auth?.user;
|
|
186
|
+
const firstFromUser = (userObj?.firstname ?? userObj?.firstName ?? userObj?.given_name ?? userObj?.first_name) || "";
|
|
187
|
+
const lastFromUser = (userObj?.lastname ?? userObj?.lastName ?? userObj?.family_name ?? userObj?.last_name) || "";
|
|
188
|
+
const emailFromUser = (userObj?.email ?? userObj?.emailAddress) || (auth?.email ?? auth?.sub) || "";
|
|
189
|
+
if (auth && (firstFromUser || lastFromUser || emailFromUser)) {
|
|
190
|
+
const name = [firstFromUser, lastFromUser].filter(Boolean).join(" ").trim();
|
|
191
|
+
const role = auth.activeRole || auth.role || "";
|
|
192
|
+
return {
|
|
193
|
+
name,
|
|
194
|
+
email: emailFromUser,
|
|
195
|
+
role,
|
|
196
|
+
avatar: undefined,
|
|
197
|
+
initials: name ? name.split(/\s+/).map((s) => s[0]).join("").slice(0, 2).toUpperCase() : undefined,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// ignore parse errors
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
146
205
|
};
|
|
147
206
|
const getNotificationCountFromStorage = () => {
|
|
148
207
|
const userDbString = localStorage.getItem("persist:userdb");
|
|
@@ -297,49 +356,7 @@ const getAllDataFromStorage = () => {
|
|
|
297
356
|
console.error("Error parsing header persist:", err);
|
|
298
357
|
}
|
|
299
358
|
}
|
|
300
|
-
// Fallback:
|
|
301
|
-
const tryParsePersistForAuth = (raw) => {
|
|
302
|
-
if (!raw)
|
|
303
|
-
return null;
|
|
304
|
-
try {
|
|
305
|
-
const outer = JSON.parse(raw);
|
|
306
|
-
const parseNested = (v) => typeof v === "string" ? (() => { try {
|
|
307
|
-
return JSON.parse(v);
|
|
308
|
-
}
|
|
309
|
-
catch {
|
|
310
|
-
return v;
|
|
311
|
-
} })() : v;
|
|
312
|
-
for (const key of Object.keys(outer)) {
|
|
313
|
-
const parsed = parseNested(outer[key]);
|
|
314
|
-
if (parsed?.accessToken || parsed?.access_token || parsed?.token || parsed?.refreshToken)
|
|
315
|
-
return parsed;
|
|
316
|
-
if (parsed?.auth && typeof parsed.auth === "object") {
|
|
317
|
-
const a = parsed.auth;
|
|
318
|
-
if (a.accessToken || a.access_token || a.token)
|
|
319
|
-
return a;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
catch {
|
|
324
|
-
/* ignore */
|
|
325
|
-
}
|
|
326
|
-
return null;
|
|
327
|
-
};
|
|
328
|
-
const iamPersist = localStorage.getItem("persist:linn-i-am");
|
|
329
|
-
const iamAuth = tryParsePersistForAuth(iamPersist);
|
|
330
|
-
if (iamAuth) {
|
|
331
|
-
const token = (iamAuth.accessToken ?? iamAuth.access_token ?? iamAuth.token);
|
|
332
|
-
if (token) {
|
|
333
|
-
const decodedToken = decodeJWT(token);
|
|
334
|
-
return {
|
|
335
|
-
...emptyStorageResult(),
|
|
336
|
-
auth: iamAuth,
|
|
337
|
-
decodedToken: decodedToken ? Object.fromEntries(Object.entries(decodedToken).map(([k, v]) => [k, v ?? null])) : null,
|
|
338
|
-
rawData: iamAuth,
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
// Fallback: read access token from persist:userdb (e.g. legacy or shared auth)
|
|
359
|
+
// Fallback: read access token from persist:userdb
|
|
343
360
|
const userDbString = localStorage.getItem("persist:userdb");
|
|
344
361
|
if (!userDbString) {
|
|
345
362
|
return emptyStorageResult();
|
|
@@ -540,7 +557,6 @@ function getTokenFromUserDbPersist(parsed) {
|
|
|
540
557
|
function getAccessTokenForRequest() {
|
|
541
558
|
const keysToTry = [
|
|
542
559
|
PERSIST_HEADER_KEY,
|
|
543
|
-
"persist:linn-i-am",
|
|
544
560
|
"persist:userdb",
|
|
545
561
|
"token",
|
|
546
562
|
"accessToken",
|
|
@@ -806,6 +822,35 @@ const AppHeader = ({ language: languageProp, accessToken: accessTokenProp, objec
|
|
|
806
822
|
let userName = "";
|
|
807
823
|
let userEmail = "";
|
|
808
824
|
let userRole = "";
|
|
825
|
+
// === DEBUG ===
|
|
826
|
+
const _allLSKeys = [];
|
|
827
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
828
|
+
const k = localStorage.key(i);
|
|
829
|
+
if (k)
|
|
830
|
+
_allLSKeys.push(k);
|
|
831
|
+
}
|
|
832
|
+
const _dbgRaw = {};
|
|
833
|
+
_allLSKeys.forEach(k => {
|
|
834
|
+
const v = localStorage.getItem(k);
|
|
835
|
+
if (v) {
|
|
836
|
+
try {
|
|
837
|
+
_dbgRaw[k] = JSON.parse(v);
|
|
838
|
+
}
|
|
839
|
+
catch {
|
|
840
|
+
_dbgRaw[k] = v;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
else {
|
|
844
|
+
_dbgRaw[k] = null;
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
console.warn("▶▶▶ [AppHeader DEBUG] ALL localStorage keys:", _allLSKeys);
|
|
848
|
+
console.warn("▶▶▶ [AppHeader DEBUG] ALL localStorage values:", _dbgRaw);
|
|
849
|
+
console.warn("▶▶▶ [AppHeader DEBUG] linn-i-am-userDetails:", localStorage.getItem("linn-i-am-userDetails"));
|
|
850
|
+
console.warn("▶▶▶ [AppHeader DEBUG] persist:userdb (raw):", localStorage.getItem("persist:userdb"));
|
|
851
|
+
console.warn("▶▶▶ [AppHeader DEBUG] getAllDataFromStorage():", allData);
|
|
852
|
+
console.warn("▶▶▶ [AppHeader DEBUG] getUserDataFromStorage():", getUserDataFromStorage());
|
|
853
|
+
// === END DEBUG ===
|
|
809
854
|
const buildNameFromFirstLast = (obj) => {
|
|
810
855
|
if (!obj || typeof obj !== "object")
|
|
811
856
|
return "";
|
|
@@ -830,8 +875,9 @@ const AppHeader = ({ language: languageProp, accessToken: accessTokenProp, objec
|
|
|
830
875
|
}
|
|
831
876
|
if (allData.auth) {
|
|
832
877
|
const auth = allData.auth;
|
|
833
|
-
|
|
834
|
-
|
|
878
|
+
const authUser = auth.user;
|
|
879
|
+
userEmail = userEmail || auth.email || auth.sub || authUser?.email || authUser?.emailAddress || "";
|
|
880
|
+
userName = userName || auth.name || buildNameFromFirstLast(auth) || buildNameFromFirstLast(authUser) || "";
|
|
835
881
|
userRole = userRole || auth.role || auth.activeRole || "";
|
|
836
882
|
}
|
|
837
883
|
if (allData.userDetails) {
|
|
@@ -874,13 +920,15 @@ const AppHeader = ({ language: languageProp, accessToken: accessTokenProp, objec
|
|
|
874
920
|
const initialsVal = storedUser?.initials ??
|
|
875
921
|
allData.auth?.initials ??
|
|
876
922
|
allData.profile?.initials;
|
|
877
|
-
|
|
923
|
+
const resolvedUser = {
|
|
878
924
|
name: userName || "",
|
|
879
925
|
email: userEmail || "",
|
|
880
926
|
role: userRole || "",
|
|
881
927
|
avatar: typeof avatarSrc === "string" ? avatarSrc : undefined,
|
|
882
928
|
initials: typeof initialsVal === "string" ? initialsVal : undefined,
|
|
883
929
|
};
|
|
930
|
+
console.warn("▶▶▶ [AppHeader DEBUG] Resolved user state (name/email/role):", resolvedUser);
|
|
931
|
+
return resolvedUser;
|
|
884
932
|
});
|
|
885
933
|
const [notificationCount, setNotificationCount] = React.useState(() => {
|
|
886
934
|
const count = getNotificationCountFromStorage();
|
|
@@ -948,8 +996,9 @@ const AppHeader = ({ language: languageProp, accessToken: accessTokenProp, objec
|
|
|
948
996
|
}
|
|
949
997
|
if (allData.auth) {
|
|
950
998
|
const auth = allData.auth;
|
|
951
|
-
|
|
952
|
-
|
|
999
|
+
const authUser = auth.user;
|
|
1000
|
+
userEmail = userEmail || auth.email || auth.sub || authUser?.email || authUser?.emailAddress || "";
|
|
1001
|
+
userName = userName || auth.name || buildNameFromFirstLast(auth) || buildNameFromFirstLast(authUser) || "";
|
|
953
1002
|
userRole = userRole || auth.role || auth.activeRole || "";
|
|
954
1003
|
userAvatar = userAvatar || auth.avatar || undefined;
|
|
955
1004
|
userInitials = userInitials || auth.initials || undefined;
|
|
@@ -1160,7 +1209,7 @@ const AppHeader = ({ language: languageProp, accessToken: accessTokenProp, objec
|
|
|
1160
1209
|
width: "100%",
|
|
1161
1210
|
maxWidth: 360,
|
|
1162
1211
|
pointerEvents: "none",
|
|
1163
|
-
}, component: "div", "aria-hidden": "true", tabIndex: -1, children: jsxRuntime.jsxs(material.ListItem, { alignItems: "flex-start", className: "profile-menu-item", children: [jsxRuntime.jsx(material.ListItemAvatar, { children: isOnlineStatus ? (jsxRuntime.jsx(OnlineBadge, { overlap: "circular", anchorOrigin: { vertical: "bottom", horizontal: "right" }, variant: "dot", title: t.online, "aria-label": `${t.online} status badge`, "data-testid": "online-badge", children: jsxRuntime.jsx(material.Avatar, { sx: { bgcolor: colors.deepOrange[500] }, alt: user.name, title: user.name, src: user.avatar, children: getInitials() }) })) : (jsxRuntime.jsx(OfflineBadge, { overlap: "circular", anchorOrigin: { vertical: "bottom", horizontal: "right" }, variant: "dot", title: t.offline, "aria-label": `${t.offline} status badge`, "data-testid": "offline-badge", children: jsxRuntime.jsx(material.Avatar, { sx: { bgcolor: colors.deepOrange[500] }, alt: user.name, title: user.name, src: user.avatar, children: getInitials() }) })) }), jsxRuntime.jsx(material.ListItemText, { primary: jsxRuntime.jsx(material.Typography, { className: "profile-name", component: "span", children: user.name || user.email }), secondary: jsxRuntime.jsxs(React.Fragment, { children: [user.name && user.email ? (jsxRuntime.jsx(material.Typography, { className: "profile-email", component: "
|
|
1212
|
+
}, component: "div", "aria-hidden": "true", tabIndex: -1, children: jsxRuntime.jsxs(material.ListItem, { alignItems: "flex-start", className: "profile-menu-item", children: [jsxRuntime.jsx(material.ListItemAvatar, { children: isOnlineStatus ? (jsxRuntime.jsx(OnlineBadge, { overlap: "circular", anchorOrigin: { vertical: "bottom", horizontal: "right" }, variant: "dot", title: t.online, "aria-label": `${t.online} status badge`, "data-testid": "online-badge", children: jsxRuntime.jsx(material.Avatar, { sx: { bgcolor: colors.deepOrange[500] }, alt: user.name, title: user.name, src: user.avatar, children: getInitials() }) })) : (jsxRuntime.jsx(OfflineBadge, { overlap: "circular", anchorOrigin: { vertical: "bottom", horizontal: "right" }, variant: "dot", title: t.offline, "aria-label": `${t.offline} status badge`, "data-testid": "offline-badge", children: jsxRuntime.jsx(material.Avatar, { sx: { bgcolor: colors.deepOrange[500] }, alt: user.name, title: user.name, src: user.avatar, children: getInitials() }) })) }), jsxRuntime.jsx(material.ListItemText, { primaryTypographyProps: { component: "span" }, secondaryTypographyProps: { component: "span" }, primary: jsxRuntime.jsx(material.Typography, { className: "profile-name", component: "span", children: user.name || user.email }), secondary: jsxRuntime.jsxs(React.Fragment, { children: [user.name && user.email ? (jsxRuntime.jsx(material.Typography, { className: "profile-email", component: "span", display: "block", children: user.email })) : null, jsxRuntime.jsxs(material.Typography, { className: "profile-role", component: "span", display: "block", children: [t.role, ": ", user.role] })] }) })] }) }));
|
|
1164
1213
|
const renderMenu = (jsxRuntime.jsxs(material.Menu, { anchorEl: anchorEl, id: "account-menu", open: open, onClose: handleClose, onClick: handleClose, slotProps: {
|
|
1165
1214
|
paper: {
|
|
1166
1215
|
elevation: 0,
|