@micha.bigler/ui-core-micha 3.6.0 → 3.8.0
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/CHANGELOG.md +7 -0
- package/DESIGN.md +9 -1
- package/README.md +2 -0
- package/WORK_ORDERS.md +8 -0
- package/dist/auth/UserMenu.js +23 -1
- package/dist/components/EmptyState.js +17 -0
- package/dist/components/UserListComponent.js +2 -1
- package/dist/i18n/authTranslations.js +196 -0
- package/dist/i18n/uiCoreTranslations.js +19 -0
- package/dist/index.js +2 -1
- package/dist/messaging/Composer.js +4 -2
- package/dist/messaging/MessageBubble.js +2 -1
- package/dist/messaging/ReadTicks.js +5 -3
- package/dist/messaging/linkifyText.js +39 -0
- package/dist/pages/PasswordInvitePage.js +23 -8
- package/dist/pages/SignUpPage.js +4 -4
- package/dist/theme/createAppTheme.js +62 -9
- package/dist/theme/kitSxRegistry.js +5 -1
- package/dist/theme/tokens.js +1 -1
- package/package.json +1 -1
- package/src/auth/UserMenu.jsx +26 -1
- package/src/components/EmptyState.jsx +38 -0
- package/src/components/UserListComponent.jsx +2 -0
- package/src/i18n/authTranslations.ts +197 -0
- package/src/i18n/uiCoreTranslations.js +10 -0
- package/src/index.js +2 -1
- package/src/messaging/Composer.jsx +7 -3
- package/src/messaging/MessageBubble.jsx +2 -1
- package/src/messaging/ReadTicks.jsx +4 -3
- package/src/messaging/linkifyText.jsx +37 -0
- package/src/pages/PasswordInvitePage.jsx +36 -7
- package/src/pages/SignUpPage.jsx +79 -68
- package/src/theme/createAppTheme.js +68 -4
- package/src/theme/kitSxRegistry.js +9 -1
- package/src/theme/tokens.js +1 -1
- package/tests/EmptyState.test.jsx +62 -0
- package/tests/PasswordInvitePage.test.jsx +135 -0
- package/tests/SignUpPage.test.jsx +15 -2
- package/tests/UserListComponent.test.jsx +85 -0
- package/tests/UserMenu.test.jsx +40 -4
- package/tests/createAppThemePageContrast.test.js +108 -0
- package/tests/i18nGermanVariant.test.js +65 -0
- package/tests/messagingComposer.test.jsx +25 -0
- package/tests/messagingLinkify.test.jsx +51 -0
- package/tests/messagingReadTicksTooltip.test.jsx +36 -0
- package/tests/userScreenTranslations.test.jsx +165 -0
- package/work-orders/UCM-AUTH-9.md +207 -0
- package/work-orders/UCM-I18N-4.md +226 -0
- package/work-orders/UCM-MSG-20.md +192 -0
- package/work-orders/UCM-PRIM-2.md +114 -0
- package/work-orders/UCM-SHELL-7.md +134 -0
- package/work-orders/UCM-THEME-13.md +69 -0
- package/work-orders/UCM-THEME-14.md +142 -0
- package/work-orders/UCM-THEME-15.md +356 -0
|
@@ -56,6 +56,7 @@ export const authTranslations = {
|
|
|
56
56
|
},
|
|
57
57
|
"Auth.INVITE_PERMISSION_DENIED": {
|
|
58
58
|
"de": "Sie haben keine Berechtigung, Einladungen zu versenden.",
|
|
59
|
+
"de_informal": "Du hast keine Berechtigung, Einladungen zu versenden.",
|
|
59
60
|
"fr": "Vous n'avez pas l'autorisation d'envoyer des invitations.",
|
|
60
61
|
"en": "You do not have permission to send invitations.",
|
|
61
62
|
"sw": "Huna ruhusa ya kutuma mialiko."
|
|
@@ -104,6 +105,7 @@ export const authTranslations = {
|
|
|
104
105
|
},
|
|
105
106
|
"Auth.RESET_LINK_VALID": {
|
|
106
107
|
"de": "Der Link ist gültig. Sie können ein neues Passwort setzen.",
|
|
108
|
+
"de_informal": "Der Link ist gültig. Du kannst ein neues Passwort setzen.",
|
|
107
109
|
"fr": "Le lien est valide. Vous pouvez définir un nouveau mot de passe.",
|
|
108
110
|
"en": "The link is valid. You can set a new password.",
|
|
109
111
|
"sw": "Viungo ni sahihi. Unaweza kuweka nenosiri jipya."
|
|
@@ -116,6 +118,7 @@ export const authTranslations = {
|
|
|
116
118
|
},
|
|
117
119
|
"Auth.RESET_PASSWORD_REQUIRED": {
|
|
118
120
|
"de": "Bitte geben Sie ein neues Passwort ein.",
|
|
121
|
+
"de_informal": "Bitte gib ein neues Passwort ein.",
|
|
119
122
|
"fr": "Veuillez saisir un nouveau mot de passe.",
|
|
120
123
|
"en": "Please enter a new password.",
|
|
121
124
|
"sw": "Tafadhali ingiza nenosiri jipya."
|
|
@@ -134,6 +137,7 @@ export const authTranslations = {
|
|
|
134
137
|
},
|
|
135
138
|
"Auth.GENERIC_ERROR": {
|
|
136
139
|
"de": "Es ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.",
|
|
140
|
+
"de_informal": "Es ist ein Fehler aufgetreten. Bitte versuche es erneut.",
|
|
137
141
|
"fr": "Une erreur s'est produite. Veuillez réessayer.",
|
|
138
142
|
"en": "An error occurred. Please try again.",
|
|
139
143
|
"sw": "Hitilafu imetokea. Tafadhali jaribu tena."
|
|
@@ -278,6 +282,7 @@ export const authTranslations = {
|
|
|
278
282
|
},
|
|
279
283
|
"Auth.PAGE_CHANGE_PASSWORD_SUBTITLE": {
|
|
280
284
|
"de": "Geben Sie Ihr aktuelles und ein neues Passwort ein.",
|
|
285
|
+
"de_informal": "Gib dein aktuelles und ein neues Passwort ein.",
|
|
281
286
|
"fr": "Saisissez votre mot de passe actuel et un nouveau mot de passe.",
|
|
282
287
|
"en": "Enter your current password and a new password.",
|
|
283
288
|
"sw": "Ingiza nenosiri lako la sasa na nenosiri jipya."
|
|
@@ -290,6 +295,7 @@ export const authTranslations = {
|
|
|
290
295
|
},
|
|
291
296
|
"Auth.PAGE_CHECKING_LINK_TEXT": {
|
|
292
297
|
"de": "Wir prüfen gerade die Gültigkeit Ihres Links.",
|
|
298
|
+
"de_informal": "Wir prüfen gerade die Gültigkeit deines Links.",
|
|
293
299
|
"fr": "Nous vérifions la validité de votre lien.",
|
|
294
300
|
"en": "We are validating your link.",
|
|
295
301
|
"sw": "Tunathibitisha uhalali wa kiungo chako."
|
|
@@ -302,6 +308,7 @@ export const authTranslations = {
|
|
|
302
308
|
},
|
|
303
309
|
"Auth.PAGE_INVITE_SUBTITLE": {
|
|
304
310
|
"de": "Bitte wählen Sie ein Passwort, um auf Ihr Konto zuzugreifen.",
|
|
311
|
+
"de_informal": "Bitte wähle ein Passwort, um auf dein Konto zuzugreifen.",
|
|
305
312
|
"fr": "Veuillez choisir un mot de passe pour accéder à votre compte.",
|
|
306
313
|
"en": "Please choose a password to access your account.",
|
|
307
314
|
"sw": "Tafadhali chagua nenosiri ili kufikia akaunti yako."
|
|
@@ -314,66 +321,77 @@ export const authTranslations = {
|
|
|
314
321
|
},
|
|
315
322
|
"Auth.PAGE_RESET_PASSWORD_SUBTITLE": {
|
|
316
323
|
"de": "Bitte wählen Sie ein neues Passwort.",
|
|
324
|
+
"de_informal": "Bitte wähle ein neues Passwort.",
|
|
317
325
|
"fr": "Veuillez choisir un nouveau mot de passe.",
|
|
318
326
|
"en": "Please choose a new password.",
|
|
319
327
|
"sw": "Tafadhali chagua nenosiri jipya."
|
|
320
328
|
},
|
|
321
329
|
"Auth.RESET_PASSWORD_SUCCESS_INVITE": {
|
|
322
330
|
"de": "Das Passwort wurde gesetzt. Sie können sich nun anmelden.",
|
|
331
|
+
"de_informal": "Das Passwort wurde gesetzt. Du kannst dich nun anmelden.",
|
|
323
332
|
"fr": "Le mot de passe a été défini. Vous pouvez maintenant vous connecter.",
|
|
324
333
|
"en": "Password set successfully. You can now log in.",
|
|
325
334
|
"sw": "Nenosiri limewekwa. Sasa unaweza kuingia."
|
|
326
335
|
},
|
|
327
336
|
"Auth.RESET_PASSWORD_SUCCESS_RESET": {
|
|
328
337
|
"de": "Das Passwort wurde geändert. Sie können sich nun anmelden.",
|
|
338
|
+
"de_informal": "Das Passwort wurde geändert. Du kannst dich nun anmelden.",
|
|
329
339
|
"fr": "Le mot de passe a été modifié. Vous pouvez maintenant vous connecter.",
|
|
330
340
|
"en": "Password changed successfully. You can now log in.",
|
|
331
341
|
"sw": "Nenosiri limebadilishwa. Sasa unaweza kuingia."
|
|
332
342
|
},
|
|
333
343
|
"Auth.PAGE_RESET_REQUEST_SUBTITLE": {
|
|
334
344
|
"de": "Geben Sie Ihre E-Mail-Adresse ein, um den Link zum Zurücksetzen zu erhalten.",
|
|
345
|
+
"de_informal": "Gib deine E-Mail-Adresse ein, um den Link zum Zurücksetzen zu erhalten.",
|
|
335
346
|
"fr": "Saisissez votre adresse e-mail pour recevoir le lien de réinitialisation.",
|
|
336
347
|
"en": "Enter your email address to receive the reset link.",
|
|
337
348
|
"sw": "Ingiza anwani yako ya barua pepe ili kupokea kiungo cha kuweka upya."
|
|
338
349
|
},
|
|
339
350
|
"Auth.EMAIL_REQUIRED": {
|
|
340
351
|
"de": "Bitte geben Sie eine E-Mail-Adresse ein.",
|
|
352
|
+
"de_informal": "Bitte gib eine E-Mail-Adresse ein.",
|
|
341
353
|
"fr": "Veuillez saisir une adresse e-mail.",
|
|
342
354
|
"en": "Please enter an email address.",
|
|
343
355
|
"sw": "Tafadhali ingiza anwani ya barua pepe."
|
|
344
356
|
},
|
|
345
357
|
"Auth.PAGE_SIGNUP_SUBTITLE": {
|
|
346
358
|
"de": "Wählen Sie eine Registrierungsart und geben Sie die benötigten Angaben ein.",
|
|
359
|
+
"de_informal": "Wähle eine Registrierungsart und gib die benötigten Angaben ein.",
|
|
347
360
|
"fr": "Choisissez une méthode d'inscription et saisissez les informations requises.",
|
|
348
361
|
"en": "Choose a sign-up method and enter the required details.",
|
|
349
362
|
"sw": "Chagua njia ya kujisajili na uingize taarifa zinazohitajika."
|
|
350
363
|
},
|
|
351
364
|
"Auth.PAGE_SIGNUP_SUBTITLE_ACCESS_CODE": {
|
|
352
365
|
"de": "Geben Sie Ihre E-Mail-Adresse und den erhaltenen Zugangscode ein.",
|
|
366
|
+
"de_informal": "Gib deine E-Mail-Adresse und den erhaltenen Zugangscode ein.",
|
|
353
367
|
"fr": "Saisissez votre adresse e-mail et le code d'accès reçu.",
|
|
354
368
|
"en": "Enter your email address and the access code you received.",
|
|
355
369
|
"sw": "Ingiza anwani yako ya barua pepe na msimbo wa ufikiaji uliopokea."
|
|
356
370
|
},
|
|
357
371
|
"Auth.PAGE_SIGNUP_SUBTITLE_OPEN": {
|
|
358
372
|
"de": "Geben Sie Ihre E-Mail-Adresse ein, um sich direkt zu registrieren.",
|
|
373
|
+
"de_informal": "Gib deine E-Mail-Adresse ein, um dich direkt zu registrieren.",
|
|
359
374
|
"fr": "Saisissez votre adresse e-mail pour vous inscrire directement.",
|
|
360
375
|
"en": "Enter your email address to sign up directly.",
|
|
361
376
|
"sw": "Ingiza anwani yako ya barua pepe ili kujisajili moja kwa moja."
|
|
362
377
|
},
|
|
363
378
|
"Auth.PAGE_SIGNUP_SUBTITLE_EMAIL_DOMAIN": {
|
|
364
379
|
"de": "Verwenden Sie eine E-Mail-Adresse aus einer freigegebenen Domain.",
|
|
380
|
+
"de_informal": "Verwende eine E-Mail-Adresse aus einer freigegebenen Domain.",
|
|
365
381
|
"fr": "Utilisez une adresse e-mail provenant d'un domaine autorisé.",
|
|
366
382
|
"en": "Use an email address from an approved domain.",
|
|
367
383
|
"sw": "Tumia anwani ya barua pepe kutoka kwenye domeni iliyoidhinishwa."
|
|
368
384
|
},
|
|
369
385
|
"Auth.PAGE_SIGNUP_SUBTITLE_QR": {
|
|
370
386
|
"de": "Öffnen Sie diese Seite über einen gültigen QR-Link und geben Sie dann Ihre E-Mail-Adresse ein.",
|
|
387
|
+
"de_informal": "Öffne diese Seite über einen gültigen QR-Link und gib dann deine E-Mail-Adresse ein.",
|
|
371
388
|
"fr": "Ouvrez cette page via un lien QR valide, puis saisissez votre adresse e-mail.",
|
|
372
389
|
"en": "Open this page from a valid QR link, then enter your email address.",
|
|
373
390
|
"sw": "Fungua ukurasa huu kupitia kiungo halali cha QR, kisha ingiza anwani yako ya barua pepe."
|
|
374
391
|
},
|
|
375
392
|
"Auth.PAGE_SIGNUP_SUBTITLE_QR_READY": {
|
|
376
393
|
"de": "Geben Sie Ihre E-Mail-Adresse ein, um die Registrierung mit diesem QR-Link abzuschließen.",
|
|
394
|
+
"de_informal": "Gib deine E-Mail-Adresse ein, um die Registrierung mit diesem QR-Link abzuschließen.",
|
|
377
395
|
"fr": "Saisissez votre adresse e-mail pour terminer l'inscription avec ce lien QR.",
|
|
378
396
|
"en": "Enter your email address to complete sign-up with this QR link.",
|
|
379
397
|
"sw": "Ingiza anwani yako ya barua pepe ili kukamilisha kujisajili kwa kutumia kiungo hiki cha QR."
|
|
@@ -434,6 +452,7 @@ export const authTranslations = {
|
|
|
434
452
|
},
|
|
435
453
|
"Auth.SIGNUP_ALREADY_HAVE_ACCOUNT": {
|
|
436
454
|
"de": "Sie haben bereits ein Konto?",
|
|
455
|
+
"de_informal": "Du hast bereits ein Konto?",
|
|
437
456
|
"fr": "Vous avez déjà un compte ?",
|
|
438
457
|
"en": "Already have an account?",
|
|
439
458
|
"sw": "Je, tayari una akaunti?"
|
|
@@ -446,6 +465,7 @@ export const authTranslations = {
|
|
|
446
465
|
},
|
|
447
466
|
"Auth.SIGNUP_ACCESS_CODE_REQUIRED": {
|
|
448
467
|
"de": "Bitte geben Sie einen Zugangscode ein.",
|
|
468
|
+
"de_informal": "Bitte gib einen Zugangscode ein.",
|
|
449
469
|
"fr": "Veuillez saisir un code d'accès.",
|
|
450
470
|
"en": "Please enter an access code.",
|
|
451
471
|
"sw": "Tafadhali ingiza msimbo wa ufikiaji."
|
|
@@ -464,6 +484,7 @@ export const authTranslations = {
|
|
|
464
484
|
},
|
|
465
485
|
"Auth.PAGE_LOGIN_SUBTITLE": {
|
|
466
486
|
"de": "Melden Sie sich mit Ihrem Konto an.",
|
|
487
|
+
"de_informal": "Melde dich mit deinem Konto an.",
|
|
467
488
|
"fr": "Connectez-vous avec votre compte.",
|
|
468
489
|
"en": "Sign in with your account.",
|
|
469
490
|
"sw": "Ingia na akaunti yako."
|
|
@@ -1112,6 +1133,7 @@ export const authTranslations = {
|
|
|
1112
1133
|
},
|
|
1113
1134
|
"Support.RECOVERY_APPROVE_CONFIRM_QUESTION": {
|
|
1114
1135
|
"de": "Sind Sie sicher, dass Sie diese Wiederherstellungsanfrage bewilligen möchten?",
|
|
1136
|
+
"de_informal": "Bist du sicher, dass du diese Wiederherstellungsanfrage bewilligen möchtest?",
|
|
1115
1137
|
"fr": "Êtes-vous sûr de vouloir approuver cette demande de récupération ?",
|
|
1116
1138
|
"en": "Are you sure you want to approve this recovery request?",
|
|
1117
1139
|
"sw": "Una uhakika unataka kuidhinisha ombi hili la urejesho?"
|
|
@@ -1124,6 +1146,7 @@ export const authTranslations = {
|
|
|
1124
1146
|
},
|
|
1125
1147
|
"Support.RECOVERY_APPROVE_NOTE_HELP": {
|
|
1126
1148
|
"de": "Beschreiben Sie kurz, warum Sie diese Anfrage bewilligen.",
|
|
1149
|
+
"de_informal": "Beschreibe kurz, warum du diese Anfrage bewilligst.",
|
|
1127
1150
|
"fr": "Décrivez brièvement pourquoi vous approuvez cette demande.",
|
|
1128
1151
|
"en": "Briefly describe why you are approving this request.",
|
|
1129
1152
|
"sw": "Eleza kwa ufupi kwa nini unaidhinisha ombi hili."
|
|
@@ -1136,12 +1159,14 @@ export const authTranslations = {
|
|
|
1136
1159
|
},
|
|
1137
1160
|
"Auth.MFA_HELP_DIALOG_DESCRIPTION": {
|
|
1138
1161
|
"de": "Beschreiben Sie kurz, warum Sie keine der verfügbaren Methoden verwenden können. Eine Supportperson wird Ihre Anfrage prüfen.",
|
|
1162
|
+
"de_informal": "Beschreibe kurz, warum du keine der verfügbaren Methoden verwenden kannst. Eine Supportperson wird deine Anfrage prüfen.",
|
|
1139
1163
|
"fr": "Décrivez brièvement pourquoi vous ne pouvez utiliser aucune des méthodes disponibles. Un membre du support examinera votre demande.",
|
|
1140
1164
|
"en": "Briefly describe why you cannot use any of the available methods. A support person will review your request.",
|
|
1141
1165
|
"sw": "Eleza kwa ufupi kwa nini huwezi kutumia yoyote ya mbinu zinazopatikana. Mtu wa usaidizi atakagua ombi lako."
|
|
1142
1166
|
},
|
|
1143
1167
|
"Auth.MFA_HELP_MESSAGE_LABEL": {
|
|
1144
1168
|
"de": "Ihre Nachricht an den Support",
|
|
1169
|
+
"de_informal": "Deine Nachricht an den Support",
|
|
1145
1170
|
"fr": "Votre message au support",
|
|
1146
1171
|
"en": "Your message to support",
|
|
1147
1172
|
"sw": "Ujumbe wako kwa usaidizi"
|
|
@@ -1160,6 +1185,7 @@ export const authTranslations = {
|
|
|
1160
1185
|
},
|
|
1161
1186
|
"Support.RECOVERY_NOTE_HELP": {
|
|
1162
1187
|
"de": "Beschreiben Sie kurz, warum Sie diese Anfrage genehmigen oder ablehnen.",
|
|
1188
|
+
"de_informal": "Beschreibe kurz, warum du diese Anfrage genehmigst oder ablehnst.",
|
|
1163
1189
|
"fr": "Décrivez brièvement pourquoi vous approuvez ou rejetez cette demande.",
|
|
1164
1190
|
"en": "Briefly describe why you are approving or rejecting this request.",
|
|
1165
1191
|
"sw": "Eleza kwa ufupi kwa nini unaidhinisha au kukataa ombi hili."
|
|
@@ -1190,6 +1216,7 @@ export const authTranslations = {
|
|
|
1190
1216
|
},
|
|
1191
1217
|
"Support.RECOVERY_REQUESTS_DESCRIPTION": {
|
|
1192
1218
|
"de": "Benutzer, die die MFA nicht abschliessen können, können hier eine Anfrage stellen. Sie können die Anfrage prüfen und anschliessend akzeptieren oder ablehnen.",
|
|
1219
|
+
"de_informal": "Benutzer, die die MFA nicht abschliessen können, können hier eine Anfrage stellen. Du kannst die Anfrage prüfen und anschliessend akzeptieren oder ablehnen.",
|
|
1193
1220
|
"fr": "Les utilisateurs qui ne peuvent pas terminer la MFA peuvent envoyer ici une demande. Vous pouvez examiner la demande puis l’accepter ou la refuser.",
|
|
1194
1221
|
"en": "Users who cannot complete MFA can submit a request here. You can review the request and then approve or reject it.",
|
|
1195
1222
|
"sw": "Watumiaji ambao hawawezi kukamilisha MFA wanaweza kutuma ombi hapa. Unaweza kukagua ombi na kisha kulikubali au kulikataa."
|
|
@@ -1298,12 +1325,14 @@ export const authTranslations = {
|
|
|
1298
1325
|
},
|
|
1299
1326
|
"Auth.MFA_IDENTIFIER_REQUIRED": {
|
|
1300
1327
|
"de": "Bitte geben Sie eine E-Mail-Adresse an.",
|
|
1328
|
+
"de_informal": "Bitte gib eine E-Mail-Adresse an.",
|
|
1301
1329
|
"fr": "Veuillez indiquer une adresse e-mail.",
|
|
1302
1330
|
"en": "Please provide an email address.",
|
|
1303
1331
|
"sw": "Tafadhali toa anwani ya barua pepe."
|
|
1304
1332
|
},
|
|
1305
1333
|
"Auth.MFA_HELP_REQUESTED": {
|
|
1306
1334
|
"de": "Falls ein Konto mit dieser E-Mail existiert, wurde Ihre Anfrage an den Support weitergeleitet.",
|
|
1335
|
+
"de_informal": "Falls ein Konto mit dieser E-Mail existiert, wurde deine Anfrage an den Support weitergeleitet.",
|
|
1307
1336
|
"fr": "Si un compte existe avec cette adresse e-mail, votre demande a été transmise au support.",
|
|
1308
1337
|
"en": "If an account with this email exists, your request has been forwarded to support.",
|
|
1309
1338
|
"sw": "Ikiwa akaunti iliyo na barua pepe hii ipo, ombi lako limetumwa kwa usaidizi."
|
|
@@ -1364,6 +1393,7 @@ export const authTranslations = {
|
|
|
1364
1393
|
},
|
|
1365
1394
|
"Auth.AUTH_FACTOR_HINT": {
|
|
1366
1395
|
"de": "Legen Sie fest, wie viele Authentifizierungsfaktoren mindestens für die Anmeldung erforderlich sind.",
|
|
1396
|
+
"de_informal": "Lege fest, wie viele Authentifizierungsfaktoren mindestens für die Anmeldung erforderlich sind.",
|
|
1367
1397
|
"fr": "Définissez le nombre minimal de facteurs d'authentification requis pour la connexion.",
|
|
1368
1398
|
"en": "Define the minimum number of authentication factors required for sign-in.",
|
|
1369
1399
|
"sw": "Weka idadi ya chini ya vipengele vya uthibitishaji vinavyohitajika ili kuingia."
|
|
@@ -1394,6 +1424,7 @@ export const authTranslations = {
|
|
|
1394
1424
|
},
|
|
1395
1425
|
"Auth.REGISTRATION_METHODS_HINT": {
|
|
1396
1426
|
"de": "Wählen Sie aus, welche Registrierungs- und Einladungswege für diese App aktiv sind.",
|
|
1427
|
+
"de_informal": "Wähle aus, welche Registrierungs- und Einladungswege für diese App aktiv sind.",
|
|
1397
1428
|
"fr": "Choisissez quels flux d'inscription et d'invitation sont actifs pour cette application.",
|
|
1398
1429
|
"en": "Choose which signup and invite flows are active for this app.",
|
|
1399
1430
|
"sw": "Chagua njia zipi za kujisajili na za mwaliko zimewashwa kwa programu hii."
|
|
@@ -1454,6 +1485,7 @@ export const authTranslations = {
|
|
|
1454
1485
|
},
|
|
1455
1486
|
"Auth.ALLOWED_EMAIL_DOMAINS_HINT": {
|
|
1456
1487
|
"de": "Eine Domain pro Zeile, z. B. example.org. Sie können das Feld vorübergehend leer lassen.",
|
|
1488
|
+
"de_informal": "Eine Domain pro Zeile, z. B. example.org. Du kannst das Feld vorübergehend leer lassen.",
|
|
1457
1489
|
"fr": "Un domaine par ligne, p. ex. example.org. Vous pouvez laisser ce champ vide temporairement.",
|
|
1458
1490
|
"en": "One domain per line, e.g. example.org. You can leave this empty temporarily.",
|
|
1459
1491
|
"sw": "Domeni moja kwa kila mstari, kwa mfano example.org. Unaweza kuiacha tupu kwa muda."
|
|
@@ -1466,6 +1498,7 @@ export const authTranslations = {
|
|
|
1466
1498
|
},
|
|
1467
1499
|
"Auth.SIGNUP_QR_MANAGER_HINT": {
|
|
1468
1500
|
"de": "Erzeugen und teilen Sie hier QR-Registrierungslinks.",
|
|
1501
|
+
"de_informal": "Erzeuge und teile hier QR-Registrierungslinks.",
|
|
1469
1502
|
"fr": "Générez et partagez ici des liens d'inscription QR.",
|
|
1470
1503
|
"en": "Generate and share QR signup links below.",
|
|
1471
1504
|
"sw": "Tengeneza na ushiriki viungo vya usajili wa QR hapa chini."
|
|
@@ -1478,6 +1511,7 @@ export const authTranslations = {
|
|
|
1478
1511
|
},
|
|
1479
1512
|
"Auth.SIGNUP_QR_VALIDITY_HINT": {
|
|
1480
1513
|
"de": "Legen Sie die Standard-Gültigkeit für neu erzeugte QR-Registrierungslinks fest.",
|
|
1514
|
+
"de_informal": "Lege die Standard-Gültigkeit für neu erzeugte QR-Registrierungslinks fest.",
|
|
1481
1515
|
"fr": "Définissez la validité par défaut des nouveaux liens d'inscription QR générés.",
|
|
1482
1516
|
"en": "Set the default validity for newly generated QR signup links.",
|
|
1483
1517
|
"sw": "Weka muda wa kawaida wa uhalali wa viungo vipya vya usajili wa QR."
|
|
@@ -1556,12 +1590,14 @@ export const authTranslations = {
|
|
|
1556
1590
|
},
|
|
1557
1591
|
"Auth.SIGNUP_QR_PDF_NOT_READY": {
|
|
1558
1592
|
"de": "Das QR-Bild ist noch nicht bereit. Bitte versuchen Sie es erneut.",
|
|
1593
|
+
"de_informal": "Das QR-Bild ist noch nicht bereit. Bitte versuche es erneut.",
|
|
1559
1594
|
"fr": "L'image QR n'est pas encore prête. Veuillez réessayer.",
|
|
1560
1595
|
"en": "The QR image is not ready yet. Please try again.",
|
|
1561
1596
|
"sw": "Picha ya QR bado haijawa tayari. Tafadhali jaribu tena."
|
|
1562
1597
|
},
|
|
1563
1598
|
"Auth.SIGNUP_QR_PDF_BLOCKED": {
|
|
1564
1599
|
"de": "Popup blockiert. Bitte erlauben Sie Popups, um die QR-Karte als PDF zu speichern.",
|
|
1600
|
+
"de_informal": "Popup blockiert. Bitte erlaube Popups, um die QR-Karte als PDF zu speichern.",
|
|
1565
1601
|
"fr": "Fenêtre contextuelle bloquée. Veuillez autoriser les popups pour enregistrer la carte QR en PDF.",
|
|
1566
1602
|
"en": "Popup blocked. Please allow popups to save the QR card as PDF.",
|
|
1567
1603
|
"sw": "Dirisha ibukizi limezuiwa. Tafadhali ruhusu madirisha ibukizi ili kuhifadhi kadi ya QR kama PDF."
|
|
@@ -1664,6 +1700,7 @@ export const authTranslations = {
|
|
|
1664
1700
|
},
|
|
1665
1701
|
"Account.ACCESS_CODES_HINT": {
|
|
1666
1702
|
"de": "Verwalten Sie Zugangscodes für die Selbstregistrierung.",
|
|
1703
|
+
"de_informal": "Verwalte Zugangscodes für die Selbstregistrierung.",
|
|
1667
1704
|
"fr": "Gérer les codes d'accès pour l'auto-inscription.",
|
|
1668
1705
|
"en": "Manage access codes for self-registration.",
|
|
1669
1706
|
"sw": "Dhibiti misimbo ya ufikiaji kwa kujisajili mwenyewe."
|
|
@@ -1830,6 +1867,12 @@ export const authTranslations = {
|
|
|
1830
1867
|
"en": "The user's role could not be updated.",
|
|
1831
1868
|
"sw": "Jukumu la mtumiaji halikuweza kusasishwa."
|
|
1832
1869
|
},
|
|
1870
|
+
"UserList.ROLE_UPDATE_SUCCESS": {
|
|
1871
|
+
"de": "Die Rolle wurde aktualisiert.",
|
|
1872
|
+
"fr": "Le rôle a été mis à jour.",
|
|
1873
|
+
"en": "Role updated.",
|
|
1874
|
+
"sw": "Jukumu limesasishwa."
|
|
1875
|
+
},
|
|
1833
1876
|
"Auth.USER_SUPPORT_UPDATE_FAILED": {
|
|
1834
1877
|
"de": "Der Support-Status des Benutzers konnte nicht aktualisiert werden.",
|
|
1835
1878
|
"fr": "Le statut de support de l'utilisateur n'a pas pu être mis à jour.",
|
|
@@ -1890,6 +1933,157 @@ export const authTranslations = {
|
|
|
1890
1933
|
"en": "The password is incorrect.",
|
|
1891
1934
|
"sw": "Nenosiri si sahihi."
|
|
1892
1935
|
},
|
|
1936
|
+
"UserList.DELETE_CONFIRM": {
|
|
1937
|
+
"de": "Möchten Sie diesen Benutzer wirklich löschen?",
|
|
1938
|
+
"de_informal": "Möchtest du diesen Benutzer wirklich löschen?",
|
|
1939
|
+
"fr": "Voulez-vous vraiment supprimer cet utilisateur ?",
|
|
1940
|
+
"en": "Are you sure you want to delete this user?",
|
|
1941
|
+
"sw": "Je, una uhakika unataka kumfuta mtumiaji huyu?"
|
|
1942
|
+
},
|
|
1943
|
+
"Common.OPERATION_FAILED": {
|
|
1944
|
+
"de": "Vorgang fehlgeschlagen.",
|
|
1945
|
+
"fr": "L’opération a échoué.",
|
|
1946
|
+
"en": "Operation failed.",
|
|
1947
|
+
"sw": "Uendeshaji umeshindwa."
|
|
1948
|
+
},
|
|
1949
|
+
"UserList.NEW": {
|
|
1950
|
+
"de": "Neu",
|
|
1951
|
+
"fr": "Nouveau",
|
|
1952
|
+
"en": "New",
|
|
1953
|
+
"sw": "Mpya"
|
|
1954
|
+
},
|
|
1955
|
+
"UserList.SUCCESSFUL_LOGIN": {
|
|
1956
|
+
"de": "Erfolgreiche Anmeldung",
|
|
1957
|
+
"fr": "Connexion réussie",
|
|
1958
|
+
"en": "Successful Login",
|
|
1959
|
+
"sw": "Kuingia kwa mafanikio"
|
|
1960
|
+
},
|
|
1961
|
+
"UserList.ROLE": {
|
|
1962
|
+
"de": "Rolle",
|
|
1963
|
+
"fr": "Rôle",
|
|
1964
|
+
"en": "Role",
|
|
1965
|
+
"sw": "Jukumu"
|
|
1966
|
+
},
|
|
1967
|
+
"Common.ACTIONS": {
|
|
1968
|
+
"de": "Aktionen",
|
|
1969
|
+
"fr": "Actions",
|
|
1970
|
+
"en": "Actions",
|
|
1971
|
+
"sw": "Vitendo"
|
|
1972
|
+
},
|
|
1973
|
+
"UserList.TITLE": {
|
|
1974
|
+
"de": "Alle Benutzer",
|
|
1975
|
+
"fr": "Tous les utilisateurs",
|
|
1976
|
+
"en": "All Users",
|
|
1977
|
+
"sw": "Watumiaji wote"
|
|
1978
|
+
},
|
|
1979
|
+
"Common.SEARCH": {
|
|
1980
|
+
"de": "Suche",
|
|
1981
|
+
"fr": "Rechercher",
|
|
1982
|
+
"en": "Search",
|
|
1983
|
+
"sw": "Tafuta"
|
|
1984
|
+
},
|
|
1985
|
+
"UserList.SEARCH_PLACEHOLDER": {
|
|
1986
|
+
"de": "Benutzer suchen...",
|
|
1987
|
+
"fr": "Rechercher des utilisateurs...",
|
|
1988
|
+
"en": "Search users...",
|
|
1989
|
+
"sw": "Tafuta watumiaji..."
|
|
1990
|
+
},
|
|
1991
|
+
"UserList.NO_USERS": {
|
|
1992
|
+
"de": "Keine Benutzer gefunden.",
|
|
1993
|
+
"fr": "Aucun utilisateur trouvé.",
|
|
1994
|
+
"en": "No users found.",
|
|
1995
|
+
"sw": "Hakuna watumiaji waliopatikana."
|
|
1996
|
+
},
|
|
1997
|
+
"UserList.ROWS_PER_PAGE": {
|
|
1998
|
+
"de": "Zeilen pro Seite:",
|
|
1999
|
+
"fr": "Lignes par page :",
|
|
2000
|
+
"en": "Rows per page:",
|
|
2001
|
+
"sw": "Safu kwa ukurasa:"
|
|
2002
|
+
},
|
|
2003
|
+
"Auth.INVITE_SENT_SUCCESS": {
|
|
2004
|
+
"de": "Einladung gesendet.",
|
|
2005
|
+
"fr": "Invitation envoyée.",
|
|
2006
|
+
"en": "Invitation sent.",
|
|
2007
|
+
"sw": "Mwaliko umetumwa."
|
|
2008
|
+
},
|
|
2009
|
+
"Auth.INVITE_TITLE": {
|
|
2010
|
+
"de": "Neuen Benutzer einladen",
|
|
2011
|
+
"fr": "Inviter un nouvel utilisateur",
|
|
2012
|
+
"en": "Invite a new user",
|
|
2013
|
+
"sw": "Mwalike mtumiaji mpya"
|
|
2014
|
+
},
|
|
2015
|
+
"Account.BULK_INVITE_NO_EMAILS": {
|
|
2016
|
+
"de": "Keine gültigen E-Mail-Adressen in der CSV-Datei gefunden.",
|
|
2017
|
+
"fr": "Aucune adresse e-mail valide trouvée dans le fichier CSV.",
|
|
2018
|
+
"en": "No valid email addresses found in CSV.",
|
|
2019
|
+
"sw": "Hakuna anwani halali za barua pepe zilizopatikana kwenye CSV."
|
|
2020
|
+
},
|
|
2021
|
+
"Account.BULK_INVITE_PARSE_FAILED": {
|
|
2022
|
+
"de": "CSV-Datei konnte nicht gelesen werden.",
|
|
2023
|
+
"fr": "Impossible de lire le fichier CSV.",
|
|
2024
|
+
"en": "Could not read CSV file.",
|
|
2025
|
+
"sw": "Imeshindikana kusoma faili ya CSV."
|
|
2026
|
+
},
|
|
2027
|
+
"Account.BULK_INVITE_DONE": {
|
|
2028
|
+
"de": "{{ok}} / {{total}} Einladungen gesendet.",
|
|
2029
|
+
"fr": "{{ok}} / {{total}} invitations envoyées.",
|
|
2030
|
+
"en": "{{ok}} / {{total}} invites sent.",
|
|
2031
|
+
"sw": "Mialiko {{ok}} / {{total}} imetumwa."
|
|
2032
|
+
},
|
|
2033
|
+
"Account.BULK_INVITE_TITLE": {
|
|
2034
|
+
"de": "Masseneinladung per CSV",
|
|
2035
|
+
"fr": "Invitations groupées par CSV",
|
|
2036
|
+
"en": "Bulk Invite via CSV",
|
|
2037
|
+
"sw": "Mialiko ya wingi kupitia CSV"
|
|
2038
|
+
},
|
|
2039
|
+
"Account.BULK_INVITE_HINT": {
|
|
2040
|
+
"de": "CSV-Datei mit E-Mail-Adressen hochladen. Header \"email\" wird unterstützt.",
|
|
2041
|
+
"fr": "Téléversez un fichier CSV contenant des adresses e-mail. L’en-tête \"email\" est pris en charge.",
|
|
2042
|
+
"en": "Upload a CSV file containing email addresses. Header \"email\" is supported.",
|
|
2043
|
+
"sw": "Pakia faili ya CSV yenye anwani za barua pepe. Kichwa \"email\" kinatumika."
|
|
2044
|
+
},
|
|
2045
|
+
"Account.BULK_INVITE_UPLOAD": {
|
|
2046
|
+
"de": "CSV hochladen",
|
|
2047
|
+
"fr": "Téléverser un CSV",
|
|
2048
|
+
"en": "Upload CSV",
|
|
2049
|
+
"sw": "Pakia CSV"
|
|
2050
|
+
},
|
|
2051
|
+
"Account.BULK_INVITE_SEND": {
|
|
2052
|
+
"de": "Einladungen senden",
|
|
2053
|
+
"fr": "Envoyer les invitations",
|
|
2054
|
+
"en": "Send Invites",
|
|
2055
|
+
"sw": "Tuma mialiko"
|
|
2056
|
+
},
|
|
2057
|
+
"Account.BULK_INVITE_COUNT": {
|
|
2058
|
+
"de": "{{count}} E-Mail-Adressen geladen",
|
|
2059
|
+
"fr": "{{count}} adresses e-mail chargées",
|
|
2060
|
+
"en": "{{count}} emails loaded",
|
|
2061
|
+
"sw": "Anwani {{count}} za barua pepe zimepakiwa"
|
|
2062
|
+
},
|
|
2063
|
+
"Common.STATUS": {
|
|
2064
|
+
"de": "Status",
|
|
2065
|
+
"fr": "Statut",
|
|
2066
|
+
"en": "Status",
|
|
2067
|
+
"sw": "Hali"
|
|
2068
|
+
},
|
|
2069
|
+
"Common.DETAILS": {
|
|
2070
|
+
"de": "Details",
|
|
2071
|
+
"fr": "Détails",
|
|
2072
|
+
"en": "Details",
|
|
2073
|
+
"sw": "Maelezo"
|
|
2074
|
+
},
|
|
2075
|
+
"Account.BULK_INVITE_PROGRESS": {
|
|
2076
|
+
"de": "{{done}} / {{total}} verarbeitet",
|
|
2077
|
+
"fr": "{{done}} / {{total}} traitées",
|
|
2078
|
+
"en": "{{done}} / {{total}} processed",
|
|
2079
|
+
"sw": "{{done}} / {{total}} zimechakatwa"
|
|
2080
|
+
},
|
|
2081
|
+
"Account.BULK_INVITE_SUCCESS_COUNT": {
|
|
2082
|
+
"de": "{{count}} erfolgreich",
|
|
2083
|
+
"fr": "{{count}} réussies",
|
|
2084
|
+
"en": "{{count}} successful",
|
|
2085
|
+
"sw": "{{count}} zimefaulu"
|
|
2086
|
+
},
|
|
1893
2087
|
// Raw backend auth error codes (allauth-headless + Django password validators).
|
|
1894
2088
|
// Keyed by the exact code string so the existing `t(err.code)` call sites resolve
|
|
1895
2089
|
// as a drop-in, without any component change. See AUTH-2.
|
|
@@ -1913,6 +2107,7 @@ export const authTranslations = {
|
|
|
1913
2107
|
},
|
|
1914
2108
|
"too_many_login_attempts": {
|
|
1915
2109
|
"de": "Zu viele fehlgeschlagene Anmeldeversuche. Bitte versuchen Sie es später erneut.",
|
|
2110
|
+
"de_informal": "Zu viele fehlgeschlagene Anmeldeversuche. Bitte versuche es später erneut.",
|
|
1916
2111
|
"fr": "Trop de tentatives de connexion échouées. Veuillez réessayer plus tard.",
|
|
1917
2112
|
"en": "Too many failed login attempts. Please try again later.",
|
|
1918
2113
|
"sw": "Majaribio mengi ya kuingia yameshindwa. Tafadhali jaribu tena baadaye."
|
|
@@ -1955,6 +2150,7 @@ export const authTranslations = {
|
|
|
1955
2150
|
},
|
|
1956
2151
|
"password_too_similar": {
|
|
1957
2152
|
"de": "Das Passwort ist Ihren persönlichen Daten zu ähnlich.",
|
|
2153
|
+
"de_informal": "Das Passwort ist deinen persönlichen Daten zu ähnlich.",
|
|
1958
2154
|
"fr": "Le mot de passe est trop similaire à vos informations personnelles.",
|
|
1959
2155
|
"en": "The password is too similar to your personal information.",
|
|
1960
2156
|
"sw": "Nenosiri linafanana sana na taarifa zako binafsi."
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
1
12
|
import { authTranslations } from './authTranslations';
|
|
2
13
|
import { chartsTranslations } from './chartsTranslations';
|
|
3
14
|
import { messagingTranslations } from './messagingTranslations';
|
|
@@ -6,3 +17,11 @@ import { onboardingTranslations } from './onboardingTranslations';
|
|
|
6
17
|
import { sectionNavTranslations } from './sectionNavTranslations';
|
|
7
18
|
import { userMenuTranslations } from './userMenuTranslations';
|
|
8
19
|
export const uiCoreTranslations = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, authTranslations), chartsTranslations), messagingTranslations), notificationsTranslations), onboardingTranslations), sectionNavTranslations), userMenuTranslations);
|
|
20
|
+
export function createUiCoreTranslations({ germanVariant = 'formal' } = {}) {
|
|
21
|
+
return Object.fromEntries(Object.entries(uiCoreTranslations).map(([key, value]) => {
|
|
22
|
+
const { de_informal } = value, rest = __rest(value, ["de_informal"]);
|
|
23
|
+
if (germanVariant === 'informal' && de_informal)
|
|
24
|
+
return [key, Object.assign(Object.assign({}, rest), { de: de_informal })];
|
|
25
|
+
return [key, rest];
|
|
26
|
+
}));
|
|
27
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ export { QrSignupManager } from './components/QrSignupManager';
|
|
|
39
39
|
export { MobileBottomNav } from './components/MobileBottomNav';
|
|
40
40
|
export { default as StatTile } from './components/StatTile';
|
|
41
41
|
export { default as SoftChip } from './components/SoftChip';
|
|
42
|
+
export { default as EmptyState } from './components/EmptyState';
|
|
42
43
|
// --- 6. Charts ---
|
|
43
44
|
export { ChartFrame } from './components/charts/ChartFrame';
|
|
44
45
|
export { BarChart } from './components/charts/BarChart';
|
|
@@ -89,4 +90,4 @@ export { notificationsTranslations } from './i18n/notificationsTranslations';
|
|
|
89
90
|
export { onboardingTranslations } from './i18n/onboardingTranslations';
|
|
90
91
|
export { chartsTranslations } from './i18n/chartsTranslations';
|
|
91
92
|
export { messagingTranslations } from './i18n/messagingTranslations';
|
|
92
|
-
export { uiCoreTranslations } from './i18n/uiCoreTranslations';
|
|
93
|
+
export { createUiCoreTranslations, uiCoreTranslations } from './i18n/uiCoreTranslations';
|
|
@@ -10,6 +10,8 @@ import { useTranslation } from 'react-i18next';
|
|
|
10
10
|
import { compressImageForUpload } from './composerImageCompression';
|
|
11
11
|
import { extractApiErrorMessage, useMessaging } from './MessagingProvider';
|
|
12
12
|
export const COMPOSER_EMOJI_BUTTON_SX = { fontSize: '1.15rem' };
|
|
13
|
+
export const COMPOSER_MESSAGE_FIELD_SX = { flex: 1, minWidth: 120 };
|
|
14
|
+
export const COMPOSER_SEND_BUTTON_SX = { flexShrink: 0 };
|
|
13
15
|
// A wider, Composer-only set (MSG-6i) -- deliberately separate from
|
|
14
16
|
// ReactionBar's own QUICK_EMOJIS (5, curated for fast reactions). Mobile
|
|
15
17
|
// users already have a full native emoji keyboard for free-form text; this
|
|
@@ -165,8 +167,8 @@ export function Composer({ conversationId, conversation, replyTarget = null, onR
|
|
|
165
167
|
setSending(false);
|
|
166
168
|
}
|
|
167
169
|
};
|
|
168
|
-
return _jsxs(Stack, { component: "form", spacing: 1, onSubmit: (event) => { event.preventDefault(); submit(); }, "aria-label": t('MessagingComposer.LABEL'), children: [replyTarget && _jsx(Alert, { severity: "info", onClose: () => onReplyTargetChange === null || onReplyTargetChange === void 0 ? void 0 : onReplyTargetChange(null), children: t('MessagingComposer.REPLYING_TO', { sender: ((_a = replyTarget.sender) === null || _a === void 0 ? void 0 : _a.display_name) || t('MessagingThread.UNKNOWN_SENDER') }) }), error && _jsx(Alert, { severity: "error", role: "alert", children: error }), files.length > 0 && _jsx(Stack, { direction: "row", spacing: 0.5, flexWrap: "wrap", "aria-label": t('MessagingComposer.STAGED_FILES'), children: files.map((file, index) => _jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.25, sx: { border: 1, borderColor: 'divider', borderRadius: 1, p: 0.25 }, children: [previews[index] && _jsx(Box, { component: "img", src: previews[index], alt: file.name, width: 36, height: 36, sx: { objectFit: 'cover' } }), _jsx(Typography, { variant: "caption", children: file.name }), _jsx(IconButton, { type: "button", size: "small", "aria-label": t('MessagingComposer.REMOVE_ATTACHMENT', { name: file.name }), onClick: () => removeFile(index), children: _jsx(CloseIcon, { fontSize: "inherit" }) })] }, `${file.name}-${index}`)) }), files.length > 0 && _jsx(Typography, { variant: "caption", children: t('MessagingComposer.FILES_SELECTED', { count: files.length }) }), _jsxs(Stack, { direction: "row", spacing: 1,
|
|
170
|
+
return _jsxs(Stack, { component: "form", spacing: 1, onSubmit: (event) => { event.preventDefault(); submit(); }, "aria-label": t('MessagingComposer.LABEL'), children: [replyTarget && _jsx(Alert, { severity: "info", onClose: () => onReplyTargetChange === null || onReplyTargetChange === void 0 ? void 0 : onReplyTargetChange(null), children: t('MessagingComposer.REPLYING_TO', { sender: ((_a = replyTarget.sender) === null || _a === void 0 ? void 0 : _a.display_name) || t('MessagingThread.UNKNOWN_SENDER') }) }), error && _jsx(Alert, { severity: "error", role: "alert", children: error }), files.length > 0 && _jsx(Stack, { direction: "row", spacing: 0.5, flexWrap: "wrap", "aria-label": t('MessagingComposer.STAGED_FILES'), children: files.map((file, index) => _jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.25, sx: { border: 1, borderColor: 'divider', borderRadius: 1, p: 0.25 }, children: [previews[index] && _jsx(Box, { component: "img", src: previews[index], alt: file.name, width: 36, height: 36, sx: { objectFit: 'cover' } }), _jsx(Typography, { variant: "caption", children: file.name }), _jsx(IconButton, { type: "button", size: "small", "aria-label": t('MessagingComposer.REMOVE_ATTACHMENT', { name: file.name }), onClick: () => removeFile(index), children: _jsx(CloseIcon, { fontSize: "inherit" }) })] }, `${file.name}-${index}`)) }), files.length > 0 && _jsx(Typography, { variant: "caption", children: t('MessagingComposer.FILES_SELECTED', { count: files.length }) }), _jsxs(Stack, { direction: "row", spacing: 1, children: [_jsx("input", { ref: inputRef, hidden: true, type: "file", multiple: true, onChange: (event) => setFiles(Array.from(event.target.files || [])) }), _jsx(IconButton, { type: "button", "aria-label": t('MessagingComposer.ADD_ATTACHMENT'), onClick: () => { var _a; return (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, children: _jsx(AttachFileIcon, {}) }), _jsx(IconButton, { type: "button", "aria-label": t('MessagingComposer.ADD_EMOJI'), onClick: (event) => setEmojiAnchor(event.currentTarget), children: _jsx(EmojiEmotionsOutlinedIcon, {}) }), _jsx(IconButton, { type: "button", "aria-label": t('MessagingPoll.CREATE'), disabled: pollOpen || files.some(isImage), onClick: () => setPollOpen(true), children: _jsx(PollOutlinedIcon, {}) }), canAnnounce && _jsx(IconButton, { type: "button", "aria-label": t('MessagingAnnouncement.CREATE'), onClick: () => setAnnouncementOpen(true), children: _jsx(CampaignOutlinedIcon, {}) })] }), _jsxs(Stack, { direction: "row", spacing: 1, alignItems: "flex-end", children: [_jsx(TextField, { inputRef: messageInputRef, fullWidth: true, multiline: true, minRows: 2, value: body, onChange: (event) => setBody(event.target.value), onKeyDown: (event) => { if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {
|
|
169
171
|
event.preventDefault();
|
|
170
172
|
submit();
|
|
171
|
-
} }, label: t('MessagingComposer.MESSAGE'), disabled: sending }), _jsx(Button, { type: "submit", variant: "contained", disabled: sending || (!body.trim() && !files.length), children: t('MessagingComposer.SEND') })] }), sending && files.length > 0 && _jsxs(Stack, { spacing: 0.5, role: "status", children: [_jsxs(Stack, { direction: "row", spacing: 1, alignItems: "center", children: [uploadProgress == null ? _jsx(CircularProgress, { size: 16 }) : _jsx(CircularProgress, { size: 16, variant: "determinate", value: uploadProgress }), _jsx(Typography, { variant: "caption", children: t('MessagingComposer.UPLOADING') })] }), uploadProgress != null && _jsx(LinearProgress, { variant: "determinate", value: uploadProgress })] }), failed && _jsx(Button, { type: "button", onClick: () => submit(failed.requestId, true), disabled: sending, children: t('MessagingComposer.RETRY') }), _jsx(Popover, { anchorEl: emojiAnchor, open: Boolean(emojiAnchor), onClose: () => setEmojiAnchor(null), anchorOrigin: { vertical: 'bottom', horizontal: 'left' }, transformOrigin: { vertical: 'top', horizontal: 'left' }, children: _jsx(Box, { role: "group", "aria-label": t('MessagingComposer.EMOJI_PICKER'), sx: { display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 0.25, p: 0.5, maxWidth: 280 }, children: COMPOSER_EMOJIS.map((emoji) => (_jsx(IconButton, { type: "button", size: "small", onClick: () => insertEmoji(emoji), sx: COMPOSER_EMOJI_BUTTON_SX, children: emoji }, emoji))) }) }), _jsxs(Dialog, { open: pollOpen, onClose: () => !sending && setPollOpen(false), fullWidth: true, maxWidth: "sm", children: [_jsx(DialogTitle, { children: t('MessagingPoll.CREATE') }), _jsx(DialogContent, { children: _jsxs(Stack, { spacing: 1, sx: { pt: 1 }, children: [_jsx(TextField, { label: t('MessagingPoll.QUESTION'), value: pollQuestion, onChange: (event) => setPollQuestion(event.target.value), autoFocus: true }), pollOptions.map((option, index) => _jsx(TextField, { label: t('MessagingPoll.OPTION', { count: index + 1 }), value: option, onChange: (event) => setPollOptions((current) => current.map((value, optionIndex) => optionIndex === index ? event.target.value : value)) }, index)), _jsx(Button, { type: "button", disabled: pollOptions.length >= 10, onClick: () => setPollOptions((current) => [...current, '']), children: t('MessagingPoll.ADD_OPTION') }), _jsx(FormControlLabel, { control: _jsx(Checkbox, { checked: allowMultiple, onChange: (event) => setAllowMultiple(event.target.checked) }), label: t('MessagingPoll.ALLOW_MULTIPLE') })] }) }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: () => setPollOpen(false), children: t('MessagingPoll.CANCEL') }), _jsx(Button, { variant: "contained", onClick: submitPoll, disabled: sending, children: t('MessagingPoll.CREATE') })] })] }), canAnnounce && _jsxs(Dialog, { open: announcementOpen, onClose: () => !sending && setAnnouncementOpen(false), fullWidth: true, maxWidth: "sm", children: [_jsx(DialogTitle, { children: t('MessagingAnnouncement.CREATE') }), _jsx(DialogContent, { children: _jsxs(Stack, { spacing: 1, sx: { pt: 1 }, children: [_jsx(TextField, { label: t('MessagingAnnouncement.TITLE'), value: announcementTitle, onChange: (event) => setAnnouncementTitle(event.target.value), autoFocus: true }), _jsx(TextField, { label: t('MessagingAnnouncement.BODY'), value: announcementBody, onChange: (event) => setAnnouncementBody(event.target.value), multiline: true, minRows: 2 })] }) }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: () => setAnnouncementOpen(false), children: t('MessagingAnnouncement.CANCEL') }), _jsx(Button, { variant: "contained", onClick: submitAnnouncement, disabled: sending, children: t('MessagingAnnouncement.SEND') })] })] })] });
|
|
173
|
+
} }, label: t('MessagingComposer.MESSAGE'), disabled: sending, sx: COMPOSER_MESSAGE_FIELD_SX }), _jsx(Button, { type: "submit", variant: "contained", disabled: sending || (!body.trim() && !files.length), sx: COMPOSER_SEND_BUTTON_SX, children: t('MessagingComposer.SEND') })] }), sending && files.length > 0 && _jsxs(Stack, { spacing: 0.5, role: "status", children: [_jsxs(Stack, { direction: "row", spacing: 1, alignItems: "center", children: [uploadProgress == null ? _jsx(CircularProgress, { size: 16 }) : _jsx(CircularProgress, { size: 16, variant: "determinate", value: uploadProgress }), _jsx(Typography, { variant: "caption", children: t('MessagingComposer.UPLOADING') })] }), uploadProgress != null && _jsx(LinearProgress, { variant: "determinate", value: uploadProgress })] }), failed && _jsx(Button, { type: "button", onClick: () => submit(failed.requestId, true), disabled: sending, children: t('MessagingComposer.RETRY') }), _jsx(Popover, { anchorEl: emojiAnchor, open: Boolean(emojiAnchor), onClose: () => setEmojiAnchor(null), anchorOrigin: { vertical: 'bottom', horizontal: 'left' }, transformOrigin: { vertical: 'top', horizontal: 'left' }, children: _jsx(Box, { role: "group", "aria-label": t('MessagingComposer.EMOJI_PICKER'), sx: { display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 0.25, p: 0.5, maxWidth: 280 }, children: COMPOSER_EMOJIS.map((emoji) => (_jsx(IconButton, { type: "button", size: "small", onClick: () => insertEmoji(emoji), sx: COMPOSER_EMOJI_BUTTON_SX, children: emoji }, emoji))) }) }), _jsxs(Dialog, { open: pollOpen, onClose: () => !sending && setPollOpen(false), fullWidth: true, maxWidth: "sm", children: [_jsx(DialogTitle, { children: t('MessagingPoll.CREATE') }), _jsx(DialogContent, { children: _jsxs(Stack, { spacing: 1, sx: { pt: 1 }, children: [_jsx(TextField, { label: t('MessagingPoll.QUESTION'), value: pollQuestion, onChange: (event) => setPollQuestion(event.target.value), autoFocus: true }), pollOptions.map((option, index) => _jsx(TextField, { label: t('MessagingPoll.OPTION', { count: index + 1 }), value: option, onChange: (event) => setPollOptions((current) => current.map((value, optionIndex) => optionIndex === index ? event.target.value : value)) }, index)), _jsx(Button, { type: "button", disabled: pollOptions.length >= 10, onClick: () => setPollOptions((current) => [...current, '']), children: t('MessagingPoll.ADD_OPTION') }), _jsx(FormControlLabel, { control: _jsx(Checkbox, { checked: allowMultiple, onChange: (event) => setAllowMultiple(event.target.checked) }), label: t('MessagingPoll.ALLOW_MULTIPLE') })] }) }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: () => setPollOpen(false), children: t('MessagingPoll.CANCEL') }), _jsx(Button, { variant: "contained", onClick: submitPoll, disabled: sending, children: t('MessagingPoll.CREATE') })] })] }), canAnnounce && _jsxs(Dialog, { open: announcementOpen, onClose: () => !sending && setAnnouncementOpen(false), fullWidth: true, maxWidth: "sm", children: [_jsx(DialogTitle, { children: t('MessagingAnnouncement.CREATE') }), _jsx(DialogContent, { children: _jsxs(Stack, { spacing: 1, sx: { pt: 1 }, children: [_jsx(TextField, { label: t('MessagingAnnouncement.TITLE'), value: announcementTitle, onChange: (event) => setAnnouncementTitle(event.target.value), autoFocus: true }), _jsx(TextField, { label: t('MessagingAnnouncement.BODY'), value: announcementBody, onChange: (event) => setAnnouncementBody(event.target.value), multiline: true, minRows: 2 })] }) }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: () => setAnnouncementOpen(false), children: t('MessagingAnnouncement.CANCEL') }), _jsx(Button, { variant: "contained", onClick: submitAnnouncement, disabled: sending, children: t('MessagingAnnouncement.SEND') })] })] })] });
|
|
172
174
|
}
|
|
@@ -8,6 +8,7 @@ import { AttachmentList } from './AttachmentList';
|
|
|
8
8
|
import { extractApiErrorMessage, useOptionalMessaging } from './MessagingProvider';
|
|
9
9
|
import { ReactionBar } from './ReactionBar';
|
|
10
10
|
import { PollCard } from './PollCard';
|
|
11
|
+
import { linkifyText } from './linkifyText';
|
|
11
12
|
export const MESSAGE_BUBBLE_ROOT_SX = {
|
|
12
13
|
position: 'relative',
|
|
13
14
|
p: 1.25,
|
|
@@ -155,5 +156,5 @@ export function MessageBubble({ message, replyTo, conversation, onReply, onJumpT
|
|
|
155
156
|
bgcolor: isOwn ? (theme) => alpha(theme.palette.primary.light, 0.24) : 'background.paper',
|
|
156
157
|
borderColor: isOwn ? (theme) => alpha(theme.palette.primary.main, 0.35) : 'divider',
|
|
157
158
|
},
|
|
158
|
-
], children: [canOpenMenu && _jsx(IconButton, { className: "message-actions", size: "small", "aria-label": t('MessagingActions.MENU'), onClick: openMenu, sx: MESSAGE_BUBBLE_ACTION_SX, children: _jsx(MoreVertIcon, { fontSize: "small" }) }), _jsxs(Stack, { spacing: 0.75, children: [replyTo && _jsx(ButtonBase, { type: "button", onClick: () => onJumpToMessage === null || onJumpToMessage === void 0 ? void 0 : onJumpToMessage(replyTo.id), sx: { display: 'block', width: '100%', px: 0.75, py: 0.5, textAlign: 'left', borderLeft: 3, borderColor: 'primary.main', bgcolor: 'action.hover', borderRadius: 0.5 }, children: _jsxs(Stack, { spacing: 0, alignItems: "flex-start", children: [_jsx(Typography, { variant: "caption", color: "text.secondary", children: t('MessagingThread.REPLY_TO', { sender: senderName(replyTo) || t('MessagingThread.UNKNOWN_SENDER') }) }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: quoteLabel(replyTo, t) })] }) }), (conversation === null || conversation === void 0 ? void 0 : conversation.kind) !== 'direct' && _jsx(Typography, { variant: "subtitle2", children: senderName(message) || t('MessagingThread.UNKNOWN_SENDER') }), !deleted && message.kind === 'announcement' && message.title && _jsx(Typography, { variant: "subtitle1", fontWeight: 700, children: message.title }), !deleted && message.kind === 'announcement' && message.link_target && onAnnouncementLink && _jsx(Button, { type: "button", size: "small", onClick: () => onAnnouncementLink(message.link_target), children: t('MessagingAnnouncement.OPEN_LINK') }), error && _jsx(Alert, { severity: "error", role: "alert", children: error }), editing ? _jsxs(Stack, { spacing: 0.75, children: [_jsx(TextField, { label: t('MessagingActions.EDIT'), value: draft, onChange: (event) => setDraft(event.target.value), multiline: true, minRows: 2, autoFocus: true, disabled: saving }), _jsxs(Stack, { direction: "row", spacing: 1, children: [_jsx(Button, { type: "button", onClick: saveEdit, disabled: saving, children: t('MessagingActions.SAVE') }), _jsx(Button, { type: "button", onClick: () => setEditing(false), disabled: saving, children: t('MessagingActions.CANCEL') })] })] }) : _jsx(Typography, { sx: { whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' }, children: deleted ? t('MessagingThread.DELETED') : (message.kind === 'announcement' ? message.body : (message.body || message.title)) || '' }), !deleted && _jsxs(Stack, { spacing: 0.75, children: [attachments.length > 0 && _jsx(AttachmentList, { attachments: attachments }), message.poll && _jsx(PollCard, { message: message })] }), hasMeta && _jsxs(Stack, { "data-testid": "message-meta", direction: "row", spacing: 0.5, justifyContent: "flex-end", alignItems: "center", flexWrap: "wrap", sx: { color: 'text.disabled', minWidth: 0, '& .MuiSvgIcon-root': { fontSize: '1rem' } }, children: [message.created_at && _jsx(Typography, { component: "span", variant: "caption", color: "inherit", sx: { whiteSpace: 'nowrap' }, children: new Date(message.created_at).toLocaleTimeString(i18n === null || i18n === void 0 ? void 0 : i18n.language, { hour: '2-digit', minute: '2-digit' }) }), message.edited_at && !deleted && _jsx(Typography, { component: "span", variant: "caption", color: "inherit", children: t('MessagingThread.EDITED') }), children] })] })] }), !deleted && (reactions.length > 0 || reactionPickerVisible) && _jsx(ReactionBar, { message: message, expanded: reactionPickerVisible, onExpandedChange: setReactionPickerVisible, sx: { mt: 0.5, ml: 0.75 } }), _jsxs(Menu, { anchorEl: menuAnchor, open: Boolean(menuAnchor), onClose: closeMenu, children: [_jsx(MenuItem, { onClick: startReply, children: t('MessagingThread.REPLY') }), _jsx(MenuItem, { onClick: startReact, children: t('MessagingReactions.ADD') }), canAct && _jsx(MenuItem, { onClick: startEdit, children: t('MessagingActions.EDIT') }), canAct && _jsx(MenuItem, { onClick: () => { setConfirmingDelete(true); closeMenu(); }, children: t('MessagingActions.DELETE') }), _jsx(MenuItem, { onClick: copyMessage, children: t('MessagingActions.COPY') })] }), _jsxs(Dialog, { open: confirmingDelete, onClose: () => !saving && setConfirmingDelete(false), children: [_jsx(DialogTitle, { children: t('MessagingActions.DELETE_CONFIRM_TITLE') }), _jsx(DialogContent, { children: t('MessagingActions.DELETE_CONFIRM_BODY') }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: () => setConfirmingDelete(false), disabled: saving, children: t('MessagingActions.CANCEL') }), _jsx(Button, { onClick: confirmDelete, disabled: saving, color: "error", children: t('MessagingActions.DELETE') })] })] })] }));
|
|
159
|
+
], children: [canOpenMenu && _jsx(IconButton, { className: "message-actions", size: "small", "aria-label": t('MessagingActions.MENU'), onClick: openMenu, sx: MESSAGE_BUBBLE_ACTION_SX, children: _jsx(MoreVertIcon, { fontSize: "small" }) }), _jsxs(Stack, { spacing: 0.75, children: [replyTo && _jsx(ButtonBase, { type: "button", onClick: () => onJumpToMessage === null || onJumpToMessage === void 0 ? void 0 : onJumpToMessage(replyTo.id), sx: { display: 'block', width: '100%', px: 0.75, py: 0.5, textAlign: 'left', borderLeft: 3, borderColor: 'primary.main', bgcolor: 'action.hover', borderRadius: 0.5 }, children: _jsxs(Stack, { spacing: 0, alignItems: "flex-start", children: [_jsx(Typography, { variant: "caption", color: "text.secondary", children: t('MessagingThread.REPLY_TO', { sender: senderName(replyTo) || t('MessagingThread.UNKNOWN_SENDER') }) }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: quoteLabel(replyTo, t) })] }) }), (conversation === null || conversation === void 0 ? void 0 : conversation.kind) !== 'direct' && _jsx(Typography, { variant: "subtitle2", children: senderName(message) || t('MessagingThread.UNKNOWN_SENDER') }), !deleted && message.kind === 'announcement' && message.title && _jsx(Typography, { variant: "subtitle1", fontWeight: 700, children: message.title }), !deleted && message.kind === 'announcement' && message.link_target && onAnnouncementLink && _jsx(Button, { type: "button", size: "small", onClick: () => onAnnouncementLink(message.link_target), children: t('MessagingAnnouncement.OPEN_LINK') }), error && _jsx(Alert, { severity: "error", role: "alert", children: error }), editing ? _jsxs(Stack, { spacing: 0.75, children: [_jsx(TextField, { label: t('MessagingActions.EDIT'), value: draft, onChange: (event) => setDraft(event.target.value), multiline: true, minRows: 2, autoFocus: true, disabled: saving }), _jsxs(Stack, { direction: "row", spacing: 1, children: [_jsx(Button, { type: "button", onClick: saveEdit, disabled: saving, children: t('MessagingActions.SAVE') }), _jsx(Button, { type: "button", onClick: () => setEditing(false), disabled: saving, children: t('MessagingActions.CANCEL') })] })] }) : _jsx(Typography, { sx: { whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' }, children: deleted ? t('MessagingThread.DELETED') : linkifyText((message.kind === 'announcement' ? message.body : (message.body || message.title)) || '') }), !deleted && _jsxs(Stack, { spacing: 0.75, children: [attachments.length > 0 && _jsx(AttachmentList, { attachments: attachments }), message.poll && _jsx(PollCard, { message: message })] }), hasMeta && _jsxs(Stack, { "data-testid": "message-meta", direction: "row", spacing: 0.5, justifyContent: "flex-end", alignItems: "center", flexWrap: "wrap", sx: { color: 'text.disabled', minWidth: 0, '& .MuiSvgIcon-root': { fontSize: '1rem' } }, children: [message.created_at && _jsx(Typography, { component: "span", variant: "caption", color: "inherit", sx: { whiteSpace: 'nowrap' }, children: new Date(message.created_at).toLocaleTimeString(i18n === null || i18n === void 0 ? void 0 : i18n.language, { hour: '2-digit', minute: '2-digit' }) }), message.edited_at && !deleted && _jsx(Typography, { component: "span", variant: "caption", color: "inherit", children: t('MessagingThread.EDITED') }), children] })] })] }), !deleted && (reactions.length > 0 || reactionPickerVisible) && _jsx(ReactionBar, { message: message, expanded: reactionPickerVisible, onExpandedChange: setReactionPickerVisible, sx: { mt: 0.5, ml: 0.75 } }), _jsxs(Menu, { anchorEl: menuAnchor, open: Boolean(menuAnchor), onClose: closeMenu, children: [_jsx(MenuItem, { onClick: startReply, children: t('MessagingThread.REPLY') }), _jsx(MenuItem, { onClick: startReact, children: t('MessagingReactions.ADD') }), canAct && _jsx(MenuItem, { onClick: startEdit, children: t('MessagingActions.EDIT') }), canAct && _jsx(MenuItem, { onClick: () => { setConfirmingDelete(true); closeMenu(); }, children: t('MessagingActions.DELETE') }), _jsx(MenuItem, { onClick: copyMessage, children: t('MessagingActions.COPY') })] }), _jsxs(Dialog, { open: confirmingDelete, onClose: () => !saving && setConfirmingDelete(false), children: [_jsx(DialogTitle, { children: t('MessagingActions.DELETE_CONFIRM_TITLE') }), _jsx(DialogContent, { children: t('MessagingActions.DELETE_CONFIRM_BODY') }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: () => setConfirmingDelete(false), disabled: saving, children: t('MessagingActions.CANCEL') }), _jsx(Button, { onClick: confirmDelete, disabled: saving, color: "error", children: t('MessagingActions.DELETE') })] })] })] }));
|
|
159
160
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import DoneAllOutlinedIcon from '@mui/icons-material/DoneAllOutlined';
|
|
3
3
|
import DoneOutlinedIcon from '@mui/icons-material/DoneOutlined';
|
|
4
|
-
import { ButtonBase, List, ListItem, Popover, Typography } from '@mui/material';
|
|
4
|
+
import { ButtonBase, List, ListItem, Popover, Tooltip, Typography } from '@mui/material';
|
|
5
5
|
import { useEffect, useState } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { useMessaging } from './MessagingProvider';
|
|
@@ -49,6 +49,8 @@ export function ReadTicks({ messageId, conversation }) {
|
|
|
49
49
|
const hasCounts = typeof status.read_count === 'number' && typeof status.recipient_count === 'number';
|
|
50
50
|
if (!hasCounts && (conversation === null || conversation === void 0 ? void 0 : conversation.kind) !== 'direct')
|
|
51
51
|
return null;
|
|
52
|
+
if (hasCounts && status.recipient_count === 0)
|
|
53
|
+
return null;
|
|
52
54
|
// The server never returns DM detail; enforce the same carve-out defensively.
|
|
53
55
|
const detail = (conversation === null || conversation === void 0 ? void 0 : conversation.kind) === 'direct' ? null : recipientDetail;
|
|
54
56
|
const recipients = (detail === null || detail === void 0 ? void 0 : detail.map((recipient) => recipient.display_name || recipient.username || recipient.user_id).filter(Boolean)) || [];
|
|
@@ -71,8 +73,8 @@ export function ReadTicks({ messageId, conversation }) {
|
|
|
71
73
|
const label = t('MessagingReadTicks.READ_RATIO', { read: status.read_count, total: status.recipient_count });
|
|
72
74
|
const ratio = _jsxs(Typography, { component: "span", variant: "caption", color: "inherit", children: [status.read_count, "/", status.recipient_count] });
|
|
73
75
|
if (!recipients.length)
|
|
74
|
-
return _jsx("span", { role: "img", "aria-label": label, children: ratio });
|
|
75
|
-
return _jsxs(_Fragment, { children: [_jsx(ButtonBase, { "aria-label": label, "aria-haspopup": "dialog", "aria-expanded": Boolean(anchorEl), onClick: (event) => setAnchorEl(event.currentTarget), sx: { display: 'inline-flex' }, children: ratio }), _jsx(Popover, { open: Boolean(anchorEl), anchorEl: anchorEl, onClose: () => setAnchorEl(null), children: _jsx(List, { "aria-label": t('MessagingReadTicks.RECIPIENTS'), children: recipients.map((recipient) => _jsx(ListItem, { children: recipient }, recipient)) }) })] });
|
|
76
|
+
return _jsx(Tooltip, { title: label, describeChild: true, children: _jsx("span", { role: "img", "aria-label": label, children: ratio }) });
|
|
77
|
+
return _jsxs(_Fragment, { children: [_jsx(Tooltip, { title: label, describeChild: true, children: _jsx(ButtonBase, { "aria-label": label, "aria-haspopup": "dialog", "aria-expanded": Boolean(anchorEl), onClick: (event) => setAnchorEl(event.currentTarget), sx: { display: 'inline-flex' }, children: ratio }) }), _jsx(Popover, { open: Boolean(anchorEl), anchorEl: anchorEl, onClose: () => setAnchorEl(null), children: _jsx(List, { "aria-label": t('MessagingReadTicks.RECIPIENTS'), children: recipients.map((recipient) => _jsx(ListItem, { children: recipient }, recipient)) }) })] });
|
|
76
78
|
}
|
|
77
79
|
const label = allRead ? t('MessagingReadTicks.ALL_READ') : t('MessagingReadTicks.SENT');
|
|
78
80
|
const StatusIcon = allRead ? DoneAllOutlinedIcon : DoneOutlinedIcon;
|