@micha.bigler/ui-core-micha 3.5.1 → 3.7.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/DESIGN.md +1 -1
  3. package/README.md +2 -0
  4. package/WORK_ORDERS.md +8 -1
  5. package/dist/auth/UserMenu.js +23 -1
  6. package/dist/components/EmptyState.js +17 -0
  7. package/dist/components/UserListComponent.js +2 -1
  8. package/dist/i18n/authTranslations.js +238 -0
  9. package/dist/i18n/uiCoreTranslations.js +19 -0
  10. package/dist/index.js +2 -1
  11. package/dist/messaging/Composer.js +4 -2
  12. package/dist/messaging/MessageBubble.js +2 -1
  13. package/dist/messaging/ReadTicks.js +5 -3
  14. package/dist/messaging/linkifyText.js +39 -0
  15. package/dist/pages/PasswordInvitePage.js +23 -8
  16. package/dist/pages/SignUpPage.js +4 -4
  17. package/dist/theme/kitSxRegistry.js +5 -1
  18. package/dist/utils/auth-errors.js +1 -1
  19. package/package.json +1 -1
  20. package/src/auth/UserMenu.jsx +26 -1
  21. package/src/components/EmptyState.jsx +38 -0
  22. package/src/components/UserListComponent.jsx +2 -0
  23. package/src/i18n/authTranslations.ts +243 -0
  24. package/src/i18n/uiCoreTranslations.js +10 -0
  25. package/src/index.js +2 -1
  26. package/src/messaging/Composer.jsx +7 -3
  27. package/src/messaging/MessageBubble.jsx +2 -1
  28. package/src/messaging/ReadTicks.jsx +4 -3
  29. package/src/messaging/linkifyText.jsx +37 -0
  30. package/src/pages/PasswordInvitePage.jsx +36 -7
  31. package/src/pages/SignUpPage.jsx +79 -68
  32. package/src/theme/kitSxRegistry.js +9 -1
  33. package/src/utils/auth-errors.js +2 -2
  34. package/tests/EmptyState.test.jsx +62 -0
  35. package/tests/PasswordInvitePage.test.jsx +135 -0
  36. package/tests/SignUpPage.test.jsx +15 -2
  37. package/tests/UserListComponent.test.jsx +85 -0
  38. package/tests/UserMenu.test.jsx +40 -4
  39. package/tests/authErrors.test.js +43 -0
  40. package/tests/i18nGermanVariant.test.js +65 -0
  41. package/tests/messagingComposer.test.jsx +25 -0
  42. package/tests/messagingLinkify.test.jsx +51 -0
  43. package/tests/messagingReadTicksTooltip.test.jsx +36 -0
  44. package/tests/userScreenTranslations.test.jsx +165 -0
  45. package/work-orders/AUTH-8.md +184 -0
  46. package/work-orders/UCM-AUTH-9.md +207 -0
  47. package/work-orders/UCM-I18N-4.md +226 -0
  48. package/work-orders/UCM-MSG-20.md +192 -0
  49. package/work-orders/UCM-PRIM-2.md +114 -0
  50. package/work-orders/UCM-SHELL-7.md +134 -0
  51. package/work-orders/UCM-THEME-13.md +69 -0
  52. package/work-orders/UCM-THEME-14.md +140 -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."
@@ -204,6 +208,12 @@ export const authTranslations = {
204
208
  "en": "Passkey authentication was cancelled.",
205
209
  "sw": "Uthibitishaji wa Passkey umeghairiwa."
206
210
  },
211
+ "Auth.PASSKEY_CANCELLED": {
212
+ "de": "Der Passkey-Vorgang wurde abgebrochen.",
213
+ "fr": "L'opération avec le passkey a été annulée.",
214
+ "en": "The passkey operation was cancelled.",
215
+ "sw": "Operesheni ya Passkey imeghairiwa."
216
+ },
207
217
  "Auth.PASSKEY_LIST_FAILED": {
208
218
  "de": "Die gespeicherten Passkeys konnten nicht geladen werden.",
209
219
  "fr": "Les passkeys enregistrés n'ont pas pu être chargés.",
@@ -228,6 +238,12 @@ export const authTranslations = {
228
238
  "en": "Two-factor authentication failed.",
229
239
  "sw": "Uthibitishaji wa hatua mbili umeshindwa."
230
240
  },
241
+ "Auth.MFA_CHALLENGE_FAILED": {
242
+ "de": "Die Zwei-Faktor-Challenge konnte nicht angefordert werden.",
243
+ "fr": "Le défi d'authentification à deux facteurs n'a pas pu être demandé.",
244
+ "en": "The two-factor challenge could not be requested.",
245
+ "sw": "Changamoto ya uthibitishaji wa hatua mbili haikuweza kuombwa."
246
+ },
231
247
  "Auth.TOTP_REQUEST_FAILED": {
232
248
  "de": "Die TOTP-Einrichtung konnte nicht gestartet werden.",
233
249
  "fr": "La configuration TOTP n'a pas pu être démarrée.",
@@ -258,8 +274,15 @@ export const authTranslations = {
258
274
  "en": "Recovery codes could not be regenerated.",
259
275
  "sw": "Misimbo ya urejesho haikuweza kuundwa upya."
260
276
  },
277
+ "Auth.RECOVERY_LOGIN_FAILED": {
278
+ "de": "Die Anmeldung über den Wiederherstellungslink ist fehlgeschlagen.",
279
+ "fr": "La connexion via le lien de récupération a échoué.",
280
+ "en": "Recovery login failed.",
281
+ "sw": "Kuingia kwa njia ya urejeshaji kumeshindwa."
282
+ },
261
283
  "Auth.PAGE_CHANGE_PASSWORD_SUBTITLE": {
262
284
  "de": "Geben Sie Ihr aktuelles und ein neues Passwort ein.",
285
+ "de_informal": "Gib dein aktuelles und ein neues Passwort ein.",
263
286
  "fr": "Saisissez votre mot de passe actuel et un nouveau mot de passe.",
264
287
  "en": "Enter your current password and a new password.",
265
288
  "sw": "Ingiza nenosiri lako la sasa na nenosiri jipya."
@@ -272,6 +295,7 @@ export const authTranslations = {
272
295
  },
273
296
  "Auth.PAGE_CHECKING_LINK_TEXT": {
274
297
  "de": "Wir prüfen gerade die Gültigkeit Ihres Links.",
298
+ "de_informal": "Wir prüfen gerade die Gültigkeit deines Links.",
275
299
  "fr": "Nous vérifions la validité de votre lien.",
276
300
  "en": "We are validating your link.",
277
301
  "sw": "Tunathibitisha uhalali wa kiungo chako."
@@ -284,6 +308,7 @@ export const authTranslations = {
284
308
  },
285
309
  "Auth.PAGE_INVITE_SUBTITLE": {
286
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.",
287
312
  "fr": "Veuillez choisir un mot de passe pour accéder à votre compte.",
288
313
  "en": "Please choose a password to access your account.",
289
314
  "sw": "Tafadhali chagua nenosiri ili kufikia akaunti yako."
@@ -296,66 +321,77 @@ export const authTranslations = {
296
321
  },
297
322
  "Auth.PAGE_RESET_PASSWORD_SUBTITLE": {
298
323
  "de": "Bitte wählen Sie ein neues Passwort.",
324
+ "de_informal": "Bitte wähle ein neues Passwort.",
299
325
  "fr": "Veuillez choisir un nouveau mot de passe.",
300
326
  "en": "Please choose a new password.",
301
327
  "sw": "Tafadhali chagua nenosiri jipya."
302
328
  },
303
329
  "Auth.RESET_PASSWORD_SUCCESS_INVITE": {
304
330
  "de": "Das Passwort wurde gesetzt. Sie können sich nun anmelden.",
331
+ "de_informal": "Das Passwort wurde gesetzt. Du kannst dich nun anmelden.",
305
332
  "fr": "Le mot de passe a été défini. Vous pouvez maintenant vous connecter.",
306
333
  "en": "Password set successfully. You can now log in.",
307
334
  "sw": "Nenosiri limewekwa. Sasa unaweza kuingia."
308
335
  },
309
336
  "Auth.RESET_PASSWORD_SUCCESS_RESET": {
310
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.",
311
339
  "fr": "Le mot de passe a été modifié. Vous pouvez maintenant vous connecter.",
312
340
  "en": "Password changed successfully. You can now log in.",
313
341
  "sw": "Nenosiri limebadilishwa. Sasa unaweza kuingia."
314
342
  },
315
343
  "Auth.PAGE_RESET_REQUEST_SUBTITLE": {
316
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.",
317
346
  "fr": "Saisissez votre adresse e-mail pour recevoir le lien de réinitialisation.",
318
347
  "en": "Enter your email address to receive the reset link.",
319
348
  "sw": "Ingiza anwani yako ya barua pepe ili kupokea kiungo cha kuweka upya."
320
349
  },
321
350
  "Auth.EMAIL_REQUIRED": {
322
351
  "de": "Bitte geben Sie eine E-Mail-Adresse ein.",
352
+ "de_informal": "Bitte gib eine E-Mail-Adresse ein.",
323
353
  "fr": "Veuillez saisir une adresse e-mail.",
324
354
  "en": "Please enter an email address.",
325
355
  "sw": "Tafadhali ingiza anwani ya barua pepe."
326
356
  },
327
357
  "Auth.PAGE_SIGNUP_SUBTITLE": {
328
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.",
329
360
  "fr": "Choisissez une méthode d'inscription et saisissez les informations requises.",
330
361
  "en": "Choose a sign-up method and enter the required details.",
331
362
  "sw": "Chagua njia ya kujisajili na uingize taarifa zinazohitajika."
332
363
  },
333
364
  "Auth.PAGE_SIGNUP_SUBTITLE_ACCESS_CODE": {
334
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.",
335
367
  "fr": "Saisissez votre adresse e-mail et le code d'accès reçu.",
336
368
  "en": "Enter your email address and the access code you received.",
337
369
  "sw": "Ingiza anwani yako ya barua pepe na msimbo wa ufikiaji uliopokea."
338
370
  },
339
371
  "Auth.PAGE_SIGNUP_SUBTITLE_OPEN": {
340
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.",
341
374
  "fr": "Saisissez votre adresse e-mail pour vous inscrire directement.",
342
375
  "en": "Enter your email address to sign up directly.",
343
376
  "sw": "Ingiza anwani yako ya barua pepe ili kujisajili moja kwa moja."
344
377
  },
345
378
  "Auth.PAGE_SIGNUP_SUBTITLE_EMAIL_DOMAIN": {
346
379
  "de": "Verwenden Sie eine E-Mail-Adresse aus einer freigegebenen Domain.",
380
+ "de_informal": "Verwende eine E-Mail-Adresse aus einer freigegebenen Domain.",
347
381
  "fr": "Utilisez une adresse e-mail provenant d'un domaine autorisé.",
348
382
  "en": "Use an email address from an approved domain.",
349
383
  "sw": "Tumia anwani ya barua pepe kutoka kwenye domeni iliyoidhinishwa."
350
384
  },
351
385
  "Auth.PAGE_SIGNUP_SUBTITLE_QR": {
352
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.",
353
388
  "fr": "Ouvrez cette page via un lien QR valide, puis saisissez votre adresse e-mail.",
354
389
  "en": "Open this page from a valid QR link, then enter your email address.",
355
390
  "sw": "Fungua ukurasa huu kupitia kiungo halali cha QR, kisha ingiza anwani yako ya barua pepe."
356
391
  },
357
392
  "Auth.PAGE_SIGNUP_SUBTITLE_QR_READY": {
358
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.",
359
395
  "fr": "Saisissez votre adresse e-mail pour terminer l'inscription avec ce lien QR.",
360
396
  "en": "Enter your email address to complete sign-up with this QR link.",
361
397
  "sw": "Ingiza anwani yako ya barua pepe ili kukamilisha kujisajili kwa kutumia kiungo hiki cha QR."
@@ -416,6 +452,7 @@ export const authTranslations = {
416
452
  },
417
453
  "Auth.SIGNUP_ALREADY_HAVE_ACCOUNT": {
418
454
  "de": "Sie haben bereits ein Konto?",
455
+ "de_informal": "Du hast bereits ein Konto?",
419
456
  "fr": "Vous avez déjà un compte ?",
420
457
  "en": "Already have an account?",
421
458
  "sw": "Je, tayari una akaunti?"
@@ -428,6 +465,7 @@ export const authTranslations = {
428
465
  },
429
466
  "Auth.SIGNUP_ACCESS_CODE_REQUIRED": {
430
467
  "de": "Bitte geben Sie einen Zugangscode ein.",
468
+ "de_informal": "Bitte gib einen Zugangscode ein.",
431
469
  "fr": "Veuillez saisir un code d'accès.",
432
470
  "en": "Please enter an access code.",
433
471
  "sw": "Tafadhali ingiza msimbo wa ufikiaji."
@@ -446,6 +484,7 @@ export const authTranslations = {
446
484
  },
447
485
  "Auth.PAGE_LOGIN_SUBTITLE": {
448
486
  "de": "Melden Sie sich mit Ihrem Konto an.",
487
+ "de_informal": "Melde dich mit deinem Konto an.",
449
488
  "fr": "Connectez-vous avec votre compte.",
450
489
  "en": "Sign in with your account.",
451
490
  "sw": "Ingia na akaunti yako."
@@ -1094,6 +1133,7 @@ export const authTranslations = {
1094
1133
  },
1095
1134
  "Support.RECOVERY_APPROVE_CONFIRM_QUESTION": {
1096
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?",
1097
1137
  "fr": "Êtes-vous sûr de vouloir approuver cette demande de récupération ?",
1098
1138
  "en": "Are you sure you want to approve this recovery request?",
1099
1139
  "sw": "Una uhakika unataka kuidhinisha ombi hili la urejesho?"
@@ -1106,6 +1146,7 @@ export const authTranslations = {
1106
1146
  },
1107
1147
  "Support.RECOVERY_APPROVE_NOTE_HELP": {
1108
1148
  "de": "Beschreiben Sie kurz, warum Sie diese Anfrage bewilligen.",
1149
+ "de_informal": "Beschreibe kurz, warum du diese Anfrage bewilligst.",
1109
1150
  "fr": "Décrivez brièvement pourquoi vous approuvez cette demande.",
1110
1151
  "en": "Briefly describe why you are approving this request.",
1111
1152
  "sw": "Eleza kwa ufupi kwa nini unaidhinisha ombi hili."
@@ -1118,12 +1159,14 @@ export const authTranslations = {
1118
1159
  },
1119
1160
  "Auth.MFA_HELP_DIALOG_DESCRIPTION": {
1120
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.",
1121
1163
  "fr": "Décrivez brièvement pourquoi vous ne pouvez utiliser aucune des méthodes disponibles. Un membre du support examinera votre demande.",
1122
1164
  "en": "Briefly describe why you cannot use any of the available methods. A support person will review your request.",
1123
1165
  "sw": "Eleza kwa ufupi kwa nini huwezi kutumia yoyote ya mbinu zinazopatikana. Mtu wa usaidizi atakagua ombi lako."
1124
1166
  },
1125
1167
  "Auth.MFA_HELP_MESSAGE_LABEL": {
1126
1168
  "de": "Ihre Nachricht an den Support",
1169
+ "de_informal": "Deine Nachricht an den Support",
1127
1170
  "fr": "Votre message au support",
1128
1171
  "en": "Your message to support",
1129
1172
  "sw": "Ujumbe wako kwa usaidizi"
@@ -1142,6 +1185,7 @@ export const authTranslations = {
1142
1185
  },
1143
1186
  "Support.RECOVERY_NOTE_HELP": {
1144
1187
  "de": "Beschreiben Sie kurz, warum Sie diese Anfrage genehmigen oder ablehnen.",
1188
+ "de_informal": "Beschreibe kurz, warum du diese Anfrage genehmigst oder ablehnst.",
1145
1189
  "fr": "Décrivez brièvement pourquoi vous approuvez ou rejetez cette demande.",
1146
1190
  "en": "Briefly describe why you are approving or rejecting this request.",
1147
1191
  "sw": "Eleza kwa ufupi kwa nini unaidhinisha au kukataa ombi hili."
@@ -1172,6 +1216,7 @@ export const authTranslations = {
1172
1216
  },
1173
1217
  "Support.RECOVERY_REQUESTS_DESCRIPTION": {
1174
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.",
1175
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.",
1176
1221
  "en": "Users who cannot complete MFA can submit a request here. You can review the request and then approve or reject it.",
1177
1222
  "sw": "Watumiaji ambao hawawezi kukamilisha MFA wanaweza kutuma ombi hapa. Unaweza kukagua ombi na kisha kulikubali au kulikataa."
@@ -1280,12 +1325,14 @@ export const authTranslations = {
1280
1325
  },
1281
1326
  "Auth.MFA_IDENTIFIER_REQUIRED": {
1282
1327
  "de": "Bitte geben Sie eine E-Mail-Adresse an.",
1328
+ "de_informal": "Bitte gib eine E-Mail-Adresse an.",
1283
1329
  "fr": "Veuillez indiquer une adresse e-mail.",
1284
1330
  "en": "Please provide an email address.",
1285
1331
  "sw": "Tafadhali toa anwani ya barua pepe."
1286
1332
  },
1287
1333
  "Auth.MFA_HELP_REQUESTED": {
1288
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.",
1289
1336
  "fr": "Si un compte existe avec cette adresse e-mail, votre demande a été transmise au support.",
1290
1337
  "en": "If an account with this email exists, your request has been forwarded to support.",
1291
1338
  "sw": "Ikiwa akaunti iliyo na barua pepe hii ipo, ombi lako limetumwa kwa usaidizi."
@@ -1346,6 +1393,7 @@ export const authTranslations = {
1346
1393
  },
1347
1394
  "Auth.AUTH_FACTOR_HINT": {
1348
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.",
1349
1397
  "fr": "Définissez le nombre minimal de facteurs d'authentification requis pour la connexion.",
1350
1398
  "en": "Define the minimum number of authentication factors required for sign-in.",
1351
1399
  "sw": "Weka idadi ya chini ya vipengele vya uthibitishaji vinavyohitajika ili kuingia."
@@ -1376,6 +1424,7 @@ export const authTranslations = {
1376
1424
  },
1377
1425
  "Auth.REGISTRATION_METHODS_HINT": {
1378
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.",
1379
1428
  "fr": "Choisissez quels flux d'inscription et d'invitation sont actifs pour cette application.",
1380
1429
  "en": "Choose which signup and invite flows are active for this app.",
1381
1430
  "sw": "Chagua njia zipi za kujisajili na za mwaliko zimewashwa kwa programu hii."
@@ -1436,6 +1485,7 @@ export const authTranslations = {
1436
1485
  },
1437
1486
  "Auth.ALLOWED_EMAIL_DOMAINS_HINT": {
1438
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.",
1439
1489
  "fr": "Un domaine par ligne, p. ex. example.org. Vous pouvez laisser ce champ vide temporairement.",
1440
1490
  "en": "One domain per line, e.g. example.org. You can leave this empty temporarily.",
1441
1491
  "sw": "Domeni moja kwa kila mstari, kwa mfano example.org. Unaweza kuiacha tupu kwa muda."
@@ -1448,6 +1498,7 @@ export const authTranslations = {
1448
1498
  },
1449
1499
  "Auth.SIGNUP_QR_MANAGER_HINT": {
1450
1500
  "de": "Erzeugen und teilen Sie hier QR-Registrierungslinks.",
1501
+ "de_informal": "Erzeuge und teile hier QR-Registrierungslinks.",
1451
1502
  "fr": "Générez et partagez ici des liens d'inscription QR.",
1452
1503
  "en": "Generate and share QR signup links below.",
1453
1504
  "sw": "Tengeneza na ushiriki viungo vya usajili wa QR hapa chini."
@@ -1460,6 +1511,7 @@ export const authTranslations = {
1460
1511
  },
1461
1512
  "Auth.SIGNUP_QR_VALIDITY_HINT": {
1462
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.",
1463
1515
  "fr": "Définissez la validité par défaut des nouveaux liens d'inscription QR générés.",
1464
1516
  "en": "Set the default validity for newly generated QR signup links.",
1465
1517
  "sw": "Weka muda wa kawaida wa uhalali wa viungo vipya vya usajili wa QR."
@@ -1538,12 +1590,14 @@ export const authTranslations = {
1538
1590
  },
1539
1591
  "Auth.SIGNUP_QR_PDF_NOT_READY": {
1540
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.",
1541
1594
  "fr": "L'image QR n'est pas encore prête. Veuillez réessayer.",
1542
1595
  "en": "The QR image is not ready yet. Please try again.",
1543
1596
  "sw": "Picha ya QR bado haijawa tayari. Tafadhali jaribu tena."
1544
1597
  },
1545
1598
  "Auth.SIGNUP_QR_PDF_BLOCKED": {
1546
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.",
1547
1601
  "fr": "Fenêtre contextuelle bloquée. Veuillez autoriser les popups pour enregistrer la carte QR en PDF.",
1548
1602
  "en": "Popup blocked. Please allow popups to save the QR card as PDF.",
1549
1603
  "sw": "Dirisha ibukizi limezuiwa. Tafadhali ruhusu madirisha ibukizi ili kuhifadhi kadi ya QR kama PDF."
@@ -1646,6 +1700,7 @@ export const authTranslations = {
1646
1700
  },
1647
1701
  "Account.ACCESS_CODES_HINT": {
1648
1702
  "de": "Verwalten Sie Zugangscodes für die Selbstregistrierung.",
1703
+ "de_informal": "Verwalte Zugangscodes für die Selbstregistrierung.",
1649
1704
  "fr": "Gérer les codes d'accès pour l'auto-inscription.",
1650
1705
  "en": "Manage access codes for self-registration.",
1651
1706
  "sw": "Dhibiti misimbo ya ufikiaji kwa kujisajili mwenyewe."
@@ -1794,6 +1849,36 @@ export const authTranslations = {
1794
1849
  "en": "An account already exists for this email address. Please log in.",
1795
1850
  "sw": "Akaunti tayari ipo kwa anwani hii ya barua pepe. Tafadhali ingia."
1796
1851
  },
1852
+ "Auth.USER_LIST_FAILED": {
1853
+ "de": "Die Benutzerliste konnte nicht geladen werden.",
1854
+ "fr": "La liste des utilisateurs n'a pas pu être chargée.",
1855
+ "en": "The user list could not be loaded.",
1856
+ "sw": "Orodha ya watumiaji haikuweza kupakiwa."
1857
+ },
1858
+ "Auth.USER_DELETE_FAILED": {
1859
+ "de": "Der Benutzer konnte nicht gelöscht werden.",
1860
+ "fr": "L'utilisateur n'a pas pu être supprimé.",
1861
+ "en": "The user could not be deleted.",
1862
+ "sw": "Mtumiaji hakuweza kufutwa."
1863
+ },
1864
+ "Auth.USER_ROLE_UPDATE_FAILED": {
1865
+ "de": "Die Rolle des Benutzers konnte nicht aktualisiert werden.",
1866
+ "fr": "Le rôle de l'utilisateur n'a pas pu être mis à jour.",
1867
+ "en": "The user's role could not be updated.",
1868
+ "sw": "Jukumu la mtumiaji halikuweza kusasishwa."
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
+ },
1876
+ "Auth.USER_SUPPORT_UPDATE_FAILED": {
1877
+ "de": "Der Support-Status des Benutzers konnte nicht aktualisiert werden.",
1878
+ "fr": "Le statut de support de l'utilisateur n'a pas pu être mis à jour.",
1879
+ "en": "The user's support status could not be updated.",
1880
+ "sw": "Hali ya usaidizi ya mtumiaji haikuweza kusasishwa."
1881
+ },
1797
1882
  "Auth.SIGNUP_QR_MAX_REDEMPTIONS_LABEL": {
1798
1883
  "de": "Max. Verwendungen",
1799
1884
  "fr": "Utilisations max.",
@@ -1848,6 +1933,157 @@ export const authTranslations = {
1848
1933
  "en": "The password is incorrect.",
1849
1934
  "sw": "Nenosiri si sahihi."
1850
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
+ },
1851
2087
  // Raw backend auth error codes (allauth-headless + Django password validators).
1852
2088
  // Keyed by the exact code string so the existing `t(err.code)` call sites resolve
1853
2089
  // as a drop-in, without any component change. See AUTH-2.
@@ -1871,6 +2107,7 @@ export const authTranslations = {
1871
2107
  },
1872
2108
  "too_many_login_attempts": {
1873
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.",
1874
2111
  "fr": "Trop de tentatives de connexion échouées. Veuillez réessayer plus tard.",
1875
2112
  "en": "Too many failed login attempts. Please try again later.",
1876
2113
  "sw": "Majaribio mengi ya kuingia yameshindwa. Tafadhali jaribu tena baadaye."
@@ -1913,6 +2150,7 @@ export const authTranslations = {
1913
2150
  },
1914
2151
  "password_too_similar": {
1915
2152
  "de": "Das Passwort ist Ihren persönlichen Daten zu ähnlich.",
2153
+ "de_informal": "Das Passwort ist deinen persönlichen Daten zu ähnlich.",
1916
2154
  "fr": "Le mot de passe est trop similaire à vos informations personnelles.",
1917
2155
  "en": "The password is too similar to your personal information.",
1918
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, alignItems: "flex-end", 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, {}) }), _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) {
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
  }