@redacto.io/consent-sdk-react 10.0.0-beta.2 → 10.0.0-beta.4

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 (42) hide show
  1. package/.turbo/turbo-build.log +9 -9
  2. package/CHANGELOG.md +31 -0
  3. package/dist/index.js +0 -54
  4. package/dist/index.mjs +0 -54
  5. package/dist/privacy-center.js +566 -821
  6. package/dist/privacy-center.mjs +416 -671
  7. package/package.json +1 -1
  8. package/src/RedactoNoticeAssisted/i18n.ts +0 -55
  9. package/src/RedactoNoticeConsent/language-codes.ts +0 -2
  10. package/src/RedactoPrivacyCenter/components/AppShell/AppShell.tsx +28 -0
  11. package/src/RedactoPrivacyCenter/components/AppShell/UserMenu.tsx +47 -45
  12. package/src/RedactoPrivacyCenter/components/SelectUser.tsx +15 -1
  13. package/src/RedactoPrivacyCenter/lib/constants.ts +0 -1
  14. package/src/RedactoPrivacyCenter/lib/locales.ts +0 -3
  15. package/src/RedactoPrivacyCenter/locales/as/translation.json +2 -1
  16. package/src/RedactoPrivacyCenter/locales/bn/translation.json +2 -1
  17. package/src/RedactoPrivacyCenter/locales/brx/translation.json +2 -1
  18. package/src/RedactoPrivacyCenter/locales/doi/translation.json +2 -1
  19. package/src/RedactoPrivacyCenter/locales/en/translation.json +3 -1
  20. package/src/RedactoPrivacyCenter/locales/gom/translation.json +2 -1
  21. package/src/RedactoPrivacyCenter/locales/gu/translation.json +2 -1
  22. package/src/RedactoPrivacyCenter/locales/hi/translation.json +2 -1
  23. package/src/RedactoPrivacyCenter/locales/kn/translation.json +2 -1
  24. package/src/RedactoPrivacyCenter/locales/ks/translation.json +2 -1
  25. package/src/RedactoPrivacyCenter/locales/mai/translation.json +2 -1
  26. package/src/RedactoPrivacyCenter/locales/ml/translation.json +2 -1
  27. package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +2 -1
  28. package/src/RedactoPrivacyCenter/locales/mr/translation.json +2 -1
  29. package/src/RedactoPrivacyCenter/locales/ne/translation.json +2 -1
  30. package/src/RedactoPrivacyCenter/locales/or/translation.json +2 -1
  31. package/src/RedactoPrivacyCenter/locales/pa/translation.json +2 -1
  32. package/src/RedactoPrivacyCenter/locales/sa/translation.json +2 -1
  33. package/src/RedactoPrivacyCenter/locales/sat/translation.json +2 -1
  34. package/src/RedactoPrivacyCenter/locales/sd/translation.json +2 -1
  35. package/src/RedactoPrivacyCenter/locales/ta/translation.json +2 -1
  36. package/src/RedactoPrivacyCenter/locales/te/translation.json +2 -1
  37. package/src/RedactoPrivacyCenter/locales/ur/translation.json +2 -1
  38. package/src/RedactoPrivacyCenter/styles/injectStyles.ts +18 -2
  39. package/src/RedactoPrivacyCenter/styles/pcStyles.ts +17 -0
  40. package/src/RedactoPrivacyCenter/ui/PCAvatar.test.tsx +83 -0
  41. package/src/RedactoPrivacyCenter/ui/PCAvatar.tsx +33 -9
  42. package/src/RedactoPrivacyCenter/locales/bho/translation.json +0 -342
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redacto.io/consent-sdk-react",
3
- "version": "10.0.0-beta.2",
3
+ "version": "10.0.0-beta.4",
4
4
  "main": "dist/index.cjs",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -1248,60 +1248,6 @@ const as: StaticStrings = {
1248
1248
  close: "বন্ধ কৰক",
1249
1249
  };
1250
1250
 
1251
- const bho: StaticStrings = {
1252
- useEmailInstead: "ईमेल इस्तेमाल करीं",
1253
- useMobileInstead: "मोबाइल इस्तेमाल करीं",
1254
- emailAddress: "ईमेल पता",
1255
- otpHelperEmail: "हमनी एह ईमेल पर एक बेर इस्तेमाल होखे वाला पासवर्ड भेजब।",
1256
- changeEmail: "ईमेल बदलीं",
1257
- expandDetails: "{name} के विवरण फैलाईं",
1258
- collapseDetails: "{name} के विवरण समेटीं",
1259
- selectAllFor: "{name} खातिर सभ डेटा तत्व चुनीं",
1260
- selectElement: "{name} चुनीं",
1261
- selectElementRequired: "{name} चुनीं (जरूरी)",
1262
- required: "जरूरी",
1263
- logoAlt: "लोगो",
1264
- selectLanguage: "भाषा चुनीं",
1265
- selectLanguageCurrent: "भाषा चुनीं. मौजूदा भाषा: {lang}",
1266
- opensInNewTab: "नया टैब में खुलेला",
1267
- audioStart: "ऑडियो प्लेबैक शुरू करीं",
1268
- audioPause: "ऑडियो प्लेबैक रोकीं",
1269
- talkbackStart: "टॉकबैक शुरू करीं",
1270
- talkbackPause: "टॉकबैक रोकीं",
1271
- mobileNumber: "मोबाइल नंबर",
1272
- otpHelper: "हमनी एह नंबर पर एक बेर इस्तेमाल होखे वाला पासवर्ड भेजब।",
1273
- otpSentTo: "ओटीपी (OTP) भेजल गइल",
1274
- changeMobile: "मोबाइल नंबर बदलीं",
1275
- enterNDigitOtp: "{count}-अंक के ओटीपी (OTP) डालीं",
1276
- otpDigit: "ओटीपी (OTP) अंक {index}",
1277
- resendIn: "{seconds} सेकंड में ओटीपी (OTP) फेर से भेजीं",
1278
- sending: "भेजल जा रहल बा…",
1279
- resendOtp: "ओटीपी (OTP) फेर से भेजीं",
1280
- getOtp: "ओटीपी (OTP) पाईं",
1281
- verifying: "सत्यापित कइल जा रहल बा…",
1282
- verifyOtp: "ओटीपी (OTP) सत्यापित करीं",
1283
- sendOtp: "ओटीपी (OTP) भेजीं",
1284
- confirmOtp: "ओटीपी (OTP) के पुष्टि करीं",
1285
- verifyWithOtp: "ओटीपी (OTP) से सत्यापित करीं",
1286
- editSelections: "चुनाव में बदलाव करीं",
1287
- otpIncorrect:
1288
- "रउरा डालल सत्यापन कोड गलत बा। कृपया जाँच करीं आ फेर से कोशिश करीं।",
1289
- otpExpired: "रउरा सत्यापन कोड के मियाद खतम हो गइल बा। कृपया नया कोड मांगीं।",
1290
- otpNotFound: "सत्यापन कोड ना मिलल। कृपया नया कोड मांगीं।",
1291
- otpVerifyFailed: "ओटीपी (OTP) के सत्यापन ना हो सकल। कृपया फेर से कोशिश करीं।",
1292
- otpSendFailed: "ओटीपी (OTP) ना भेजल जा सकल। कृपया फेर से कोशिश करीं।",
1293
- consentConfirmed: "सहमति के पुष्टि भइल",
1294
- recordedUnder: "ओटीपी (OTP) सत्यापित · {regulation} के तहत दर्ज भइल",
1295
- recordedUnderAt:
1296
- "ओटीपी (OTP) सत्यापित · {regulation} के तहत {time} बजे दर्ज भइल",
1297
- consentReferenceId: "सहमति संदर्भ आईडी",
1298
- proceed: "आगे बढ़ीं",
1299
- loadingNotice: "नोटिस लोड हो रहल बा",
1300
- loadFailedTitle: "सहमति नोटिस लोड ना हो सकल",
1301
- tryAgain: "कृपया फेर से कोसिस करीं।",
1302
- close: "बंद करीं",
1303
- };
1304
-
1305
1251
  const brx: StaticStrings = {
1306
1252
  useEmailInstead: "इमेल बाहाय",
1307
1253
  useMobileInstead: "मबाइल बाहाय",
@@ -1435,7 +1381,6 @@ export const STATIC_STRINGS: Record<string, StaticStrings> = {
1435
1381
  te,
1436
1382
  ur,
1437
1383
  as,
1438
- bho,
1439
1384
  brx,
1440
1385
  doi,
1441
1386
  };
@@ -6,7 +6,6 @@ export const LANGUAGE_NATIVE_LABELS: Record<string, string> = {
6
6
  English: "English",
7
7
  Assamese: "অসমীয়া (Assamese)",
8
8
  Bengali: "বাংলা (Bengali)",
9
- Bhojpuri: "भोजपुरी (Bhojpuri)",
10
9
  Bodo: "बड़ो (Bodo)",
11
10
  Dogri: "डोगरी (Dogri)",
12
11
  Gujarati: "ગુજરાતી (Gujarati)",
@@ -44,7 +43,6 @@ const LANGUAGE_NAME_TO_BCP47: Record<string, string> = {
44
43
  English: "en",
45
44
  Assamese: "as",
46
45
  Bengali: "bn",
47
- Bhojpuri: "bho",
48
46
  Bodo: "brx",
49
47
  Dogri: "doi",
50
48
  Gujarati: "gu",
@@ -214,6 +214,34 @@ export default function AppShell({
214
214
  var(--pc-bg-shell) 100%
215
215
  );
216
216
  }
217
+ .pc-shell-user-menu-identity {
218
+ display: flex;
219
+ flex-direction: column;
220
+ gap: 2px;
221
+ min-width: 0;
222
+ flex: 1;
223
+ }
224
+ .pc-shell-user-menu-identity-email {
225
+ font-size: 13px;
226
+ font-weight: 600;
227
+ color: var(--pc-text-primary);
228
+ line-height: 1.3;
229
+ overflow: hidden;
230
+ text-overflow: ellipsis;
231
+ white-space: nowrap;
232
+ min-width: 0;
233
+ }
234
+ .pc-shell-user-menu-identity-id {
235
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
236
+ font-size: 11px;
237
+ font-weight: 500;
238
+ color: var(--pc-text-secondary);
239
+ line-height: 1.3;
240
+ overflow: hidden;
241
+ text-overflow: ellipsis;
242
+ white-space: nowrap;
243
+ min-width: 0;
244
+ }
217
245
  .pc-popover.pc-shell-user-menu-popover {
218
246
  border-radius: 12px !important;
219
247
  overflow: hidden !important;
@@ -1,11 +1,12 @@
1
1
  import { useEffect, useState, type CSSProperties } from 'react';
2
- import { ChevronDown, Users } from 'lucide-react';
2
+ import { Users } from 'lucide-react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { PCAvatar, PCPopover } from '../../ui';
5
5
  import { useBranding } from '../../context/BrandingContext';
6
6
  import { useOrganization } from '../../context/OrganizationContext';
7
7
  import { useProfileSwitch } from '../../context/ProfileSwitchContext';
8
- import { getVar } from '../../lib/utils';
8
+ import { useAuth } from '../../context/AuthContext';
9
+ import { decodeJwtToken, getVar } from '../../lib/utils';
9
10
  import { usePrivacyCenterExitAction } from './usePrivacyCenterExitAction';
10
11
 
11
12
  type UserMenuProps = {
@@ -35,6 +36,7 @@ export function UserMenu({ onBack }: UserMenuProps) {
35
36
  const { t } = useTranslation();
36
37
  const branding = useBranding();
37
38
  const { organization } = useOrganization();
39
+ const { accessToken } = useAuth();
38
40
  const [email, setEmail] = useState('');
39
41
 
40
42
  useEffect(() => {
@@ -45,20 +47,20 @@ export function UserMenu({ onBack }: UserMenuProps) {
45
47
  usePrivacyCenterExitAction(onBack);
46
48
  const { canSwitch, switchProfile } = useProfileSwitch();
47
49
 
50
+ // The signed-in principal's org_user_id — unique per profile, unlike the
51
+ // email a shared contact reuses across profiles — so the menu can show which
52
+ // profile is active. Read from the (live) token, which re-scopes on switch.
53
+ const orgUserId =
54
+ (decodeJwtToken(accessToken)?.user_data?.org_user_id as string) || '';
55
+
48
56
  const displayName = branding?.brand_name || organization?.name || '';
49
57
  const triggerAvatarName = email ? initialsFromEmail(email) : displayName || '?';
50
58
 
51
- const triggerStyle: CSSProperties = {
52
- display: 'inline-flex',
53
- alignItems: 'center',
54
- gap: 6,
55
- padding: '4px 6px 4px 4px',
56
- borderRadius: 9999,
57
- background: 'transparent',
58
- border: `1px solid ${getVar('--pc-border-color')}`,
59
- color: getVar('--pc-text-secondary'),
60
- cursor: 'pointer',
61
- transition: 'background 150ms ease, border-color 150ms ease, box-shadow 150ms ease',
59
+ // The .pc-navbar-avatar-btn control draws the ring and surface, so the avatar fills
60
+ // it and draws neither (see `framed={false}` below).
61
+ const avatarFillStyle: CSSProperties = {
62
+ width: '100%',
63
+ height: '100%',
62
64
  };
63
65
 
64
66
  // Shared style for the popover's action rows (switch profile, back/sign out).
@@ -81,24 +83,25 @@ export function UserMenu({ onBack }: UserMenuProps) {
81
83
  };
82
84
 
83
85
  const trigger = (
84
- <div
85
- style={triggerStyle}
86
- role="presentation"
87
- onMouseEnter={(e) => {
88
- (e.currentTarget as HTMLDivElement).style.boxShadow =
89
- '0 0 0 2px color-mix(in srgb, var(--pc-primary) 18%, transparent)';
90
- }}
91
- onMouseLeave={(e) => {
92
- (e.currentTarget as HTMLDivElement).style.boxShadow = 'none';
93
- }}
94
- >
86
+ <button type="button" aria-label={t('accountMenu')} className="pc-navbar-avatar-btn">
95
87
  {branding?.icon_url ? (
96
- <PCAvatar src={branding.icon_url} name={triggerAvatarName} size="sm" color="info" />
88
+ <PCAvatar
89
+ src={branding.icon_url}
90
+ name={triggerAvatarName}
91
+ size="md"
92
+ color="info"
93
+ framed={false}
94
+ style={avatarFillStyle}
95
+ />
97
96
  ) : (
98
- <PCAvatar name={triggerAvatarName} size="sm" color="info" />
97
+ <PCAvatar
98
+ name={triggerAvatarName}
99
+ size="md"
100
+ color="info"
101
+ style={avatarFillStyle}
102
+ />
99
103
  )}
100
- <ChevronDown size={14} strokeWidth={2} />
101
- </div>
104
+ </button>
102
105
  );
103
106
 
104
107
  const content = (
@@ -155,7 +158,7 @@ export function UserMenu({ onBack }: UserMenuProps) {
155
158
  </div>
156
159
 
157
160
  {/* Identity card */}
158
- {email && (
161
+ {(email || orgUserId) && (
159
162
  <div
160
163
  style={{
161
164
  padding: '12px 16px',
@@ -168,22 +171,21 @@ export function UserMenu({ onBack }: UserMenuProps) {
168
171
  : 'none',
169
172
  }}
170
173
  >
171
- <PCAvatar name={initialsFromEmail(email)} size="sm" color="info" />
172
- <div
173
- title={email}
174
- style={{
175
- fontSize: 13,
176
- fontWeight: 600,
177
- color: getVar('--pc-text-primary'),
178
- lineHeight: 1.3,
179
- overflow: 'hidden',
180
- textOverflow: 'ellipsis',
181
- whiteSpace: 'nowrap',
182
- minWidth: 0,
183
- flex: 1,
184
- }}
185
- >
186
- {email}
174
+ <PCAvatar name={triggerAvatarName} size="sm" color="info" />
175
+ <div className="pc-shell-user-menu-identity">
176
+ {email ? (
177
+ <div title={email} className="pc-shell-user-menu-identity-email">
178
+ {email}
179
+ </div>
180
+ ) : null}
181
+ {orgUserId ? (
182
+ <div
183
+ title={orgUserId}
184
+ className="pc-shell-user-menu-identity-id"
185
+ >
186
+ {t('userIdLabel', { id: orgUserId })}
187
+ </div>
188
+ ) : null}
187
189
  </div>
188
190
  </div>
189
191
  )}
@@ -40,8 +40,17 @@ export const SelectUser = ({
40
40
  const principalUuid = candidate.uuid || '';
41
41
  const primaryLabel =
42
42
  candidate.primary_email || candidate.primary_mobile || candidate.uuid;
43
- const secondaryLabel =
43
+ const secondaryContact =
44
44
  candidate.primary_mobile || candidate.primary_email || '';
45
+ // Don't echo the same value on both lines — an email-only principal
46
+ // otherwise renders its email twice, which is exactly the "identical
47
+ // rows" problem. The org_user_id below is the real differentiator.
48
+ const secondaryLabel =
49
+ secondaryContact !== primaryLabel ? secondaryContact : '';
50
+ // org_user_id is unique per principal (ledger-enforced within the
51
+ // org/workspace), so it's the reliable way to tell shared-contact
52
+ // profiles apart when the email/mobile are identical.
53
+ const orgUserId = candidate.org_user_id || '';
45
54
  const isBusy = busyOrgUserId === principalUuid;
46
55
  return (
47
56
  <button
@@ -60,6 +69,11 @@ export const SelectUser = ({
60
69
  {secondaryLabel}
61
70
  </span>
62
71
  ) : null}
72
+ {orgUserId ? (
73
+ <span className="pc-select-user__item-id">
74
+ {t('userIdLabel', { id: orgUserId })}
75
+ </span>
76
+ ) : null}
63
77
  </span>
64
78
  {isBusy ? (
65
79
  <span className="pc-select-user__item-status">
@@ -40,7 +40,6 @@ export const languageOptions = [
40
40
  { value: 'mni-Mtei', label: 'ꯃꯩꯇꯩꯂꯣꯟ (Manipuri)' },
41
41
  { value: 'gom', label: 'कोंकणी (Goan Konkani)' },
42
42
  { value: 'sa', label: 'संस्कृतम् (Sanskrit)' },
43
- { value: 'bho', label: 'भोजपुरी (Bhojpuri)' },
44
43
  { value: 'brx', label: 'बड़ो (Bodo)' },
45
44
  { value: 'ks', label: 'كٲشُر (Kashmiri)' },
46
45
  { value: 'sat', label: 'ᱥᱟᱱᱛᱟᱲᱤ (Santali)' },
@@ -2,7 +2,6 @@
2
2
  import enTranslation from '../locales/en/translation.json';
3
3
  import asTranslation from '../locales/as/translation.json';
4
4
  import bnTranslation from '../locales/bn/translation.json';
5
- import bhoTranslation from '../locales/bho/translation.json';
6
5
  import brxTranslation from '../locales/brx/translation.json';
7
6
  import doiTranslation from '../locales/doi/translation.json';
8
7
  import gomTranslation from '../locales/gom/translation.json';
@@ -28,7 +27,6 @@ const activityFetchErrorTranslations: Record<string, string> = {
28
27
  en: 'Failed to fetch activity data',
29
28
  as: 'কাৰ্যকলাপৰ তথ্য আনিবলৈ ব্যৰ্থ',
30
29
  bn: 'কার্যকলাপের ডেটা আনতে ব্যর্থ',
31
- bho: 'गतिविधि डेटा लावे में विफल',
32
30
  brx: 'खामानि डाटा लाङो दिहुनायाव असफल',
33
31
  doi: 'गतिविधि डेटा लावै मे असफल',
34
32
  gom: 'क्रियाकलाप डेटा आणपांत अयशस्वी',
@@ -68,7 +66,6 @@ const translations: Record<string, Record<string, any>> = {
68
66
  en: { translation: withSharedActivityErrors('en', enTranslation) },
69
67
  as: { translation: withSharedActivityErrors('as', asTranslation) },
70
68
  bn: { translation: withSharedActivityErrors('bn', bnTranslation) },
71
- bho: { translation: withSharedActivityErrors('bho', bhoTranslation) },
72
69
  brx: { translation: withSharedActivityErrors('brx', brxTranslation) },
73
70
  doi: { translation: withSharedActivityErrors('doi', doiTranslation) },
74
71
  gom: { translation: withSharedActivityErrors('gom', gomTranslation) },
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "ছাইন ইন হৈ আছে…",
339
339
  "couldNotSwitchProfile": "সেই প্ৰ'ফাইললৈ সলনি কৰিব পৰা নগ'ল। অনুগ্ৰহ কৰি পুনৰ চেষ্টা কৰক।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "ব্যৱহাৰকাৰী আইডি: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "সাইন ইন হচ্ছে…",
339
339
  "couldNotSwitchProfile": "সেই প্রোফাইলে স্যুইচ করা যায়নি। অনুগ্রহ করে আবার চেষ্টা করুন।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "ব্যবহারকারীর আইডি: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "साइन इन जायगासिनो दं…",
339
339
  "couldNotSwitchProfile": "बै प्रफाइलआव स्विच खालामनो हायाखै। अननानै फिन नाजा।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "यूजर आईडी: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "साइन इन होआ करदा ऐ…",
339
339
  "couldNotSwitchProfile": "ओह् प्रोफाइल पर स्विच नेईं होई सकेआ। कृपा करियै दुबारा कोशिश करो।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "प्रयोगकर्ता आईडी: {{id}}"
342
343
  }
@@ -352,5 +352,7 @@
352
352
  "signingInEllipsis": "Signing in…",
353
353
  "couldNotSwitchProfile": "Could not switch to that profile. Please try again.",
354
354
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
355
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
355
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
356
+ "userIdLabel": "User ID: {{id}}",
357
+ "accountMenu": "Account menu"
356
358
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "साइन इन जावन आसा…",
339
339
  "couldNotSwitchProfile": "त्या प्रोफायलाचेर स्विच करूंक जालें ना. उपकार करून परत यत्न करात.",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "वापरपी आयडी: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "સાઇન ઇન થઈ રહ્યું છે…",
339
339
  "couldNotSwitchProfile": "તે પ્રોફાઇલ પર સ્વિચ કરી શકાયું નહીં. કૃપા કરીને ફરી પ્રયાસ કરો.",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "વપરાશકર્તા આઈડી: {{id}}"
342
343
  }
@@ -341,5 +341,6 @@
341
341
  "signingInEllipsis": "साइन इन हो रहा है…",
342
342
  "couldNotSwitchProfile": "उस प्रोफ़ाइल पर स्विच नहीं किया जा सका। कृपया पुनः प्रयास करें।",
343
343
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
344
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
344
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
345
+ "userIdLabel": "उपयोगकर्ता आईडी: {{id}}"
345
346
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "ಸೈನ್ ಇನ್ ಆಗುತ್ತಿದೆ…",
339
339
  "couldNotSwitchProfile": "ಆ ಪ್ರೊಫೈಲ್‌ಗೆ ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "ಬಳಕೆದಾರ ಐಡಿ: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "سائن اِن گژھان چھُ…",
339
339
  "couldNotSwitchProfile": "تہِ پروفائلس منٛز سوِچ کرُن آو نہ۔ مہربانی کرِتھ دوبارٕ کوشش کریو۔",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "صارف آئی ڈی: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "साइन इन भ' रहल अछि…",
339
339
  "couldNotSwitchProfile": "ओ प्रोफाइल पर स्विच नहि भ' सकल। कृपया फेर सँ प्रयास करू।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "उपयोगकर्ता आइडी: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "സൈൻ ഇൻ ചെയ്യുന്നു…",
339
339
  "couldNotSwitchProfile": "ആ പ്രൊഫൈലിലേക്ക് മാറാൻ കഴിഞ്ഞില്ല. വീണ്ടും ശ്രമിക്കുക.",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "ഉപയോക്തൃ ഐഡി: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "সাইন ইন তৌরি…",
339
339
  "couldNotSwitchProfile": "প্রোফাইল অদুদা হোংদোকপা ঙমদ্রে। চানবীদুনা অমুক হন্না হোৎনবিয়ু।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "ꯃꯤꯑꯣꯏꯕ ꯑꯥꯏꯗꯤ: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "साइन इन करत आहे…",
339
339
  "couldNotSwitchProfile": "त्या प्रोफाइलवर स्विच करता आले नाही. कृपया पुन्हा प्रयत्न करा.",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "वापरकर्ता आयडी: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "साइन इन हुँदैछ…",
339
339
  "couldNotSwitchProfile": "त्यो प्रोफाइलमा स्विच गर्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "प्रयोगकर्ता आईडी: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "ସାଇନ୍ ଇନ୍ ହେଉଛି…",
339
339
  "couldNotSwitchProfile": "ସେହି ପ୍ରୋଫାଇଲକୁ ସ୍ୱିଚ୍ କରାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି ପୁନର୍ବାର ଚେଷ୍ଟା କରନ୍ତୁ।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "ବ୍ୟବହାରକାରୀ ଆଇଡି: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "ਸਾਈਨ ਇਨ ਹੋ ਰਿਹਾ ਹੈ…",
339
339
  "couldNotSwitchProfile": "ਉਸ ਪ੍ਰੋਫਾਈਲ 'ਤੇ ਸਵਿੱਚ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "ਉਪਯੋਗਕਰਤਾ ਆਈਡੀ: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "प्रवेशः क्रियते…",
339
339
  "couldNotSwitchProfile": "तां प्रोफ़ाइलं प्रति परिवर्तनं न शक्यते स्म। कृपया पुनः प्रयत्नं करोतु।",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "उपयोक्तृ-आयडी: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "ᱥᱟᱭᱤᱱ ᱤᱱ ᱮᱫᱟᱭ…",
339
339
  "couldNotSwitchProfile": "ᱚᱱᱟ ᱯᱨᱳᱯᱷᱟᱭᱤᱞ ᱛᱮ ᱥᱩᱭᱪ ᱵᱟᱝ ᱦᱩᱭ ᱞᱮᱱᱟ᱾ ᱫᱟᱭᱟ ᱠᱟᱛᱮ ᱫᱩᱠᱟᱹᱛᱮ ᱠᱩᱨᱩᱢᱩᱴᱩ ᱢᱮ᱾",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "ᱵᱮᱵᱷᱟᱨᱤᱭᱟᱹ ᱟᱭᱰᱤ: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "سائن ان ٿي رهيو آهي…",
339
339
  "couldNotSwitchProfile": "ان پروفائل تي سوئچ نه ٿي سگهيو. مهرباني ڪري ٻيهر ڪوشش ڪريو.",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "يوزر آئيڊي: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "உள்நுழைகிறது…",
339
339
  "couldNotSwitchProfile": "அந்தச் சுயவிவரத்திற்கு மாற முடியவில்லை. மீண்டும் முயற்சிக்கவும்.",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "பயனர் ஐடி: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "సైన్ ఇన్ అవుతోంది…",
339
339
  "couldNotSwitchProfile": "ఆ ప్రొఫైల్‌కు మారడం సాధ్యం కాలేదు. దయచేసి మళ్లీ ప్రయత్నించండి.",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "వినియోగదారు ఐడి: {{id}}"
342
343
  }
@@ -338,5 +338,6 @@
338
338
  "signingInEllipsis": "سائن ان ہو رہا ہے…",
339
339
  "couldNotSwitchProfile": "اس پروفائل پر سوئچ نہیں کیا جا سکا۔ براہ کرم دوبارہ کوشش کریں۔",
340
340
  "purposeNotRevocable": "This purpose can't be withdrawn directly.",
341
- "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it."
341
+ "purposeNotRevocableError": "This purpose can't be withdrawn directly. Please raise a request to remove it.",
342
+ "userIdLabel": "صارف آئی ڈی: {{id}}"
342
343
  }
@@ -747,6 +747,17 @@ export const injectPCStyles = () => {
747
747
  white-space: nowrap;
748
748
  max-width: 100%;
749
749
  }
750
+ .pc-select-user__item-id {
751
+ margin-top: 0.125rem;
752
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
753
+ font-size: 0.6875rem;
754
+ color: var(--pc-text-secondary);
755
+ line-height: 1.25;
756
+ overflow: hidden;
757
+ text-overflow: ellipsis;
758
+ white-space: nowrap;
759
+ max-width: 100%;
760
+ }
750
761
  .pc-select-user__item-status {
751
762
  font-size: 0.75rem;
752
763
  font-weight: 600;
@@ -2744,7 +2755,10 @@ export const injectPCStyles = () => {
2744
2755
  border-radius: 9999px;
2745
2756
  }
2746
2757
 
2747
- .pc-notification-bell-btn {
2758
+ /* Circular navbar controls: the bell and the org-logo menu button. Same size
2759
+ token, ring and hover, so the topbar cluster reads as one set of controls. */
2760
+ .pc-notification-bell-btn,
2761
+ .pc-navbar-avatar-btn {
2748
2762
  display: flex;
2749
2763
  align-items: center;
2750
2764
  justify-content: center;
@@ -2766,7 +2780,8 @@ export const injectPCStyles = () => {
2766
2780
  height: 14px;
2767
2781
  }
2768
2782
 
2769
- .pc-notification-bell-btn:hover {
2783
+ .pc-notification-bell-btn:hover,
2784
+ .pc-navbar-avatar-btn:hover {
2770
2785
  background-color: var(--pc-bg-hover);
2771
2786
  border-color: var(--pc-border-color-hover);
2772
2787
  }
@@ -2829,6 +2844,7 @@ export const injectPCStyles = () => {
2829
2844
  /* Keyboard focus rings for Notification Hub interactive controls */
2830
2845
  .pc-notification-cta:focus-visible,
2831
2846
  .pc-notification-bell-btn:focus-visible:not(:disabled),
2847
+ .pc-navbar-avatar-btn:focus-visible:not(:disabled),
2832
2848
  .pc-notification-filter-tab:focus-visible:not(:disabled),
2833
2849
  .pc-notification-pagination-btn:focus-visible:not(:disabled),
2834
2850
  .pc-notification-link-btn:focus-visible:not(:disabled),