Browse Source

fix(polls/web) check for duplicate poll options (#14541)

factor2
Hazoom 1 year ago
parent
commit
bb49c92cc4
No account linked to committer's email address
59 changed files with 242 additions and 4 deletions
  1. 5
    0
      lang/main-af.json
  2. 3
    0
      lang/main-ar.json
  3. 5
    0
      lang/main-be.json
  4. 5
    0
      lang/main-bg.json
  5. 3
    0
      lang/main-ca.json
  6. 3
    0
      lang/main-cs.json
  7. 5
    0
      lang/main-da.json
  8. 3
    0
      lang/main-de.json
  9. 3
    0
      lang/main-dsb.json
  10. 3
    0
      lang/main-el.json
  11. 3
    0
      lang/main-eo.json
  12. 3
    0
      lang/main-es.json
  13. 3
    0
      lang/main-esUS.json
  14. 5
    0
      lang/main-et.json
  15. 5
    0
      lang/main-eu.json
  16. 3
    0
      lang/main-fa.json
  17. 5
    0
      lang/main-fi.json
  18. 3
    0
      lang/main-fr.json
  19. 5
    0
      lang/main-frCA.json
  20. 5
    0
      lang/main-gl.json
  21. 5
    0
      lang/main-he.json
  22. 5
    0
      lang/main-hi.json
  23. 3
    0
      lang/main-hr.json
  24. 3
    0
      lang/main-hsb.json
  25. 3
    0
      lang/main-hu.json
  26. 5
    0
      lang/main-hy.json
  27. 3
    0
      lang/main-is.json
  28. 3
    0
      lang/main-it.json
  29. 3
    0
      lang/main-ja.json
  30. 3
    0
      lang/main-kab.json
  31. 5
    0
      lang/main-ko.json
  32. 5
    0
      lang/main-lt.json
  33. 3
    0
      lang/main-lv.json
  34. 5
    0
      lang/main-ml.json
  35. 3
    0
      lang/main-mn.json
  36. 5
    0
      lang/main-mr.json
  37. 3
    0
      lang/main-nl.json
  38. 3
    0
      lang/main-oc.json
  39. 3
    0
      lang/main-pl.json
  40. 3
    0
      lang/main-pt.json
  41. 3
    0
      lang/main-ptBR.json
  42. 5
    0
      lang/main-ro.json
  43. 3
    0
      lang/main-ru.json
  44. 3
    0
      lang/main-sc.json
  45. 5
    0
      lang/main-sk.json
  46. 3
    0
      lang/main-sl.json
  47. 3
    0
      lang/main-sq.json
  48. 5
    0
      lang/main-sr.json
  49. 3
    0
      lang/main-sv.json
  50. 5
    0
      lang/main-te.json
  51. 3
    0
      lang/main-tr.json
  52. 3
    0
      lang/main-uk.json
  53. 5
    0
      lang/main-vi.json
  54. 3
    0
      lang/main-zhCN.json
  55. 3
    0
      lang/main-zhTW.json
  56. 3
    0
      lang/main.json
  57. 5
    1
      react/features/polls/components/AbstractPollCreate.tsx
  58. 12
    3
      react/features/polls/components/web/PollCreate.tsx
  59. 15
    0
      react/features/polls/functions.ts

+ 5
- 0
lang/main-af.json View File

@@ -432,6 +432,11 @@
432 432
     },
433 433
     "passwordDigitsOnly": "",
434 434
     "passwordSetRemotely": "",
435
+    "polls": {
436
+        "errors": {
437
+            "notUniqueOption": "Opsies moet uniek wees"
438
+        }
439
+    },
435 440
     "poweredby": "aangedryf deur",
436 441
     "presenceStatus": {
437 442
         "busy": "Besig",

+ 3
- 0
lang/main-ar.json View File

@@ -765,6 +765,9 @@
765 765
             "removeOption": "إزالة خيار",
766 766
             "send": "أرسل"
767 767
         },
768
+        "errors": {
769
+            "notUniqueOption": "يجب أن تكون الخيارات فريدة"
770
+        },
768 771
         "notification": {
769 772
             "description": "افتح علامة تبويب الاقتراع للتصويت",
770 773
             "title": "تمت إضافة اقتراع جديد إلى هذا المُلتقى"

+ 5
- 0
lang/main-be.json View File

@@ -478,6 +478,11 @@
478 478
     },
479 479
     "passwordDigitsOnly": "Да {{number}} лічбаў",
480 480
     "passwordSetRemotely": "устаноўлены іншым удзельнікам",
481
+    "polls": {
482
+        "errors": {
483
+            "notUniqueOption": "Варыянты павінны быць унікальнымі"
484
+        }
485
+    },
481 486
     "poweredby": "працуе на",
482 487
     "presenceStatus": {
483 488
         "busy": "Заняты",

+ 5
- 0
lang/main-bg.json View File

@@ -527,6 +527,11 @@
527 527
     },
528 528
     "passwordDigitsOnly": "До {{number}} цифри",
529 529
     "passwordSetRemotely": "зададена от друг участник",
530
+    "polls": {
531
+        "errors": {
532
+            "notUniqueOption": "Опциите трябва да са уникални"
533
+        }
534
+    },
530 535
     "poweredby": "с подкрепата на",
531 536
     "presenceStatus": {
532 537
         "busy": "Зает",

+ 3
- 0
lang/main-ca.json View File

@@ -772,6 +772,9 @@
772 772
             "removeOption": "Elimina l'opció",
773 773
             "send": "Envia"
774 774
         },
775
+        "errors": {
776
+            "notUniqueOption": "Les opcions han de ser úniques"
777
+        },
775 778
         "notification": {
776 779
             "description": "Obre la pestanya de les enquestes per a votar",
777 780
             "title": "S'ha afegit una nova enquesta en aquesta reunió"

+ 3
- 0
lang/main-cs.json View File

@@ -747,6 +747,9 @@
747 747
             "removeOption": "",
748 748
             "send": ""
749 749
         },
750
+        "errors": {
751
+            "notUniqueOption": "Možnosti musí být jedinečné"
752
+        },
750 753
         "notification": {
751 754
             "description": "",
752 755
             "title": ""

+ 5
- 0
lang/main-da.json View File

@@ -464,6 +464,11 @@
464 464
     },
465 465
     "passwordDigitsOnly": "Op til {{number}} tal",
466 466
     "passwordSetRemotely": "Sat af et andet medlem",
467
+    "polls": {
468
+        "errors": {
469
+            "notUniqueOption": "Valgmulighederne skal være unikke"
470
+        }
471
+    },
467 472
     "poweredby": "Powered by",
468 473
     "presenceStatus": {
469 474
         "busy": "Optaget",

+ 3
- 0
lang/main-de.json View File

@@ -867,6 +867,9 @@
867 867
             "removeOption": "Antwort entfernen",
868 868
             "send": "Erstellen"
869 869
         },
870
+        "errors": {
871
+            "notUniqueOption": "Optionen müssen einzigartig sein"
872
+        },
870 873
         "notification": {
871 874
             "description": "Öffnen Sie das Umfragen-Tab um abzustimmen",
872 875
             "title": "Dieser Konferenz wurde eine Umfrage hinzugefügt"

+ 3
- 0
lang/main-dsb.json View File

@@ -775,6 +775,9 @@
775 775
             "removeOption": "wótegrono wulašowaś",
776 776
             "send": "wótpósłaś"
777 777
         },
778
+        "errors": {
779
+            "notUniqueOption": "Opcije musy byś jedynsće"
780
+        },
778 781
         "notification": {
779 782
             "description": "Wótcyńśo kórtu wopšašowanjow, aby zgłosowali",
780 783
             "title": "Za tu konferencu jo nowe wopšašowanje pśigótowane"

+ 3
- 0
lang/main-el.json View File

@@ -792,6 +792,9 @@
792 792
             "removeOption": "Αφαιρέστε την επιλογή",
793 793
             "send": "Αποστολή"
794 794
         },
795
+        "errors": {
796
+            "notUniqueOption": "Οι επιλογές πρέπει να είναι μοναδικές"
797
+        },
795 798
         "notification": {
796 799
             "description": "Ανοίξτε τη σελίδα ψηφοφοριών για να ψηφίσετε",
797 800
             "title": "Μια νέα ψηφοφορία προστέθηκε στη σύσκεψη"

+ 3
- 0
lang/main-eo.json View File

@@ -864,6 +864,9 @@
864 864
             "removeOption": "Forigi opcion",
865 865
             "send": "Sendu"
866 866
         },
867
+        "errors": {
868
+            "notUniqueOption": "Ebloj devas esti unikaj"
869
+        },
867 870
         "notification": {
868 871
             "description": "Malfermu la enketan langeton por voĉdoni",
869 872
             "title": "Oni aldonis novan enketon en la kunveno"

+ 3
- 0
lang/main-es.json View File

@@ -815,6 +815,9 @@
815 815
             "removeOption": "Eliminar la opción",
816 816
             "send": "Enviar"
817 817
         },
818
+        "errors": {
819
+            "notUniqueOption": "Las opciones deben ser únicas"
820
+        },
818 821
         "notification": {
819 822
             "description": "Abre la pestaña de encuestas para votar",
820 823
             "title": "Se ha añadido una nueva encuesta a esta reunión"

+ 3
- 0
lang/main-esUS.json View File

@@ -691,6 +691,9 @@
691 691
             "removeOption": "Eliminar la opción",
692 692
             "send": "Enviar"
693 693
         },
694
+        "errors": {
695
+            "notUniqueOption": "Las opciones deben ser únicas"
696
+        },
694 697
         "notification": {
695 698
             "description": "Abre la pestaña de encuestas para votar",
696 699
             "title": "Se ha añadido una nueva encuesta a esta reunión"

+ 5
- 0
lang/main-et.json View File

@@ -467,6 +467,11 @@
467 467
     },
468 468
     "passwordDigitsOnly": "Kuni {{number}} tähemärki",
469 469
     "passwordSetRemotely": "määratud teise kasutaja poolt",
470
+    "polls": {
471
+        "errors": {
472
+            "notUniqueOption": "Valikud peavad olema ainulaadsed"
473
+        }
474
+    },
470 475
     "poweredby": "teieni toodud",
471 476
     "presenceStatus": {
472 477
         "busy": "Hõivatud",

+ 5
- 0
lang/main-eu.json View File

@@ -588,6 +588,11 @@
588 588
     },
589 589
     "passwordDigitsOnly": "{{number}} digitu arte",
590 590
     "passwordSetRemotely": "beste parte-hartzaile batek ezarrita",
591
+    "polls": {
592
+        "errors": {
593
+            "notUniqueOption": "Aukerak bakarrak izan behar dira"
594
+        }
595
+    },
591 596
     "poweredby": "garatzailea:",
592 597
     "prejoin": {
593 598
         "audioAndVideoError": "Errorea audio eta bideoan:",

+ 3
- 0
lang/main-fa.json View File

@@ -823,6 +823,9 @@
823 823
             "removeOption": "حذف گزینه",
824 824
             "send": "ارسال"
825 825
         },
826
+        "errors": {
827
+            "notUniqueOption": "گزینه ها باید منحصر به فرد باشند"
828
+        },
826 829
         "notification": {
827 830
             "description": "برای رأی‌دادن، زبانهٔ نظرسنجی‌ها را باز کنید",
828 831
             "title": "نظرسنجی جدیدی به این جلسه اضافه شد"

+ 5
- 0
lang/main-fi.json View File

@@ -438,6 +438,11 @@
438 438
     },
439 439
     "passwordDigitsOnly": "",
440 440
     "passwordSetRemotely": "",
441
+    "polls": {
442
+        "errors": {
443
+            "notUniqueOption": "Vaihtoehtojen on oltava ainutlaatuisia"
444
+        }
445
+    },
441 446
     "poweredby": "tukija:",
442 447
     "presenceStatus": {
443 448
         "busy": "Varattu",

+ 3
- 0
lang/main-fr.json View File

@@ -865,6 +865,9 @@
865 865
             "removeOption": "Supprimer l'option",
866 866
             "send": "Envoyer"
867 867
         },
868
+        "errors": {
869
+            "notUniqueOption": "Les options doivent être uniques"
870
+        },
868 871
         "notification": {
869 872
             "description": "Ouvrez l'onglet des sondages pour voter",
870 873
             "title": "Un nouveau sondage a été ajouté à la réunion"

+ 5
- 0
lang/main-frCA.json View File

@@ -449,6 +449,11 @@
449 449
     },
450 450
     "passwordDigitsOnly": "Jusqu'à {{number}} chiffres",
451 451
     "passwordSetRemotely": "réglé par un autre membre",
452
+    "polls": {
453
+        "errors": {
454
+            "notUniqueOption": "Les options doivent être uniques"
455
+        }
456
+    },
452 457
     "poweredby": "optimisé par",
453 458
     "presenceStatus": {
454 459
         "busy": "Occupé",

+ 5
- 0
lang/main-gl.json View File

@@ -454,6 +454,11 @@
454 454
     },
455 455
     "passwordDigitsOnly": "Ata {{number}} díxitos",
456 456
     "passwordSetRemotely": "estabelecida por outro participante",
457
+    "polls": {
458
+        "errors": {
459
+            "notUniqueOption": "As opcións deben ser únicas"
460
+        }
461
+    },
457 462
     "poweredby": "fornecido por",
458 463
     "presenceStatus": {
459 464
         "busy": "Ocupado",

+ 5
- 0
lang/main-he.json View File

@@ -477,6 +477,11 @@
477 477
     },
478 478
     "passwordDigitsOnly": "עד {{number}} ספרות",
479 479
     "passwordSetRemotely": "נקבע על ידי חבר אחר",
480
+    "polls": {
481
+        "errors": {
482
+            "notUniqueOption": "האפשרויות חייבות להיות ייחודיות"
483
+        }
484
+    },
480 485
     "poweredby": "מופעל על ידי",
481 486
     "presenceStatus": {
482 487
         "busy": "עסוק",

+ 5
- 0
lang/main-hi.json View File

@@ -565,6 +565,11 @@
565 565
     },
566 566
     "passwordDigitsOnly": "Up to {{number}} digits",
567 567
     "passwordSetRemotely": "दूसरे प्रतिभागी द्वारा निर्धारित",
568
+    "polls": {
569
+        "errors": {
570
+            "notUniqueOption": "विकल्प अद्वितीय होना चाहिए"
571
+        }
572
+    },
568 573
     "poweredby": "powered by",
569 574
     "prejoin": {
570 575
         "audioAndVideoError": "ऑडियो और वीडियो त्रुटि:",

+ 3
- 0
lang/main-hr.json View File

@@ -770,6 +770,9 @@
770 770
             "removeOption": "Ukloni opciju",
771 771
             "send": "Pošalji"
772 772
         },
773
+        "errors": {
774
+            "notUniqueOption": "Opcije moraju biti jedinstvene"
775
+        },
773 776
         "notification": {
774 777
             "description": "Za glasanje otvori karticu ankete",
775 778
             "title": "Ovom sastanku je dodana nova anketa"

+ 3
- 0
lang/main-hsb.json View File

@@ -755,6 +755,9 @@
755 755
             "removeOption": "wotmołwu wotstronić",
756 756
             "send": "zestajić"
757 757
         },
758
+        "errors": {
759
+            "notUniqueOption": "opcije dyrbja jasne być"
760
+        },
758 761
         "notification": {
759 762
             "description": "Za wobdźělenje wočińće tab za naprašowanje.",
760 763
             "title": "Tutej konferency bu naprašowanje přidate."

+ 3
- 0
lang/main-hu.json View File

@@ -623,6 +623,9 @@
623 623
             "removeOption": "Opció eltávolítása",
624 624
             "send": "Küldés"
625 625
         },
626
+        "errors": {
627
+            "notUniqueOption": "Az opcióknak egyedinek kell lenniük"
628
+        },
626 629
         "notification": {
627 630
             "description": "Szavazás megnyitása",
628 631
             "title": "Új szavazás létrehozva"

+ 5
- 0
lang/main-hy.json View File

@@ -427,6 +427,11 @@
427 427
     },
428 428
     "passwordDigitsOnly": "",
429 429
     "passwordSetRemotely": "Սահմանվել է մեկ այլ մասնակցի կողմից",
430
+    "polls": {
431
+        "errors": {
432
+            "notUniqueOption": "Ընտրանքները պետք է լինեն եզակի"
433
+        }
434
+    },
430 435
     "poweredby": "Հիմնված է",
431 436
     "presenceStatus": {
432 437
         "busy": "",

+ 3
- 0
lang/main-is.json View File

@@ -865,6 +865,9 @@
865 865
             "removeOption": "Fjarlægja valkost",
866 866
             "send": "Senda"
867 867
         },
868
+        "errors": {
869
+            "notUniqueOption": "Valkostir hljóta að vera einstök"
870
+        },
868 871
         "notification": {
869 872
             "description": "Opnaðu könnunarflipann til að greiða atkvæði",
870 873
             "title": "Nýrri könnun var bætt á þennan fund"

+ 3
- 0
lang/main-it.json View File

@@ -770,6 +770,9 @@
770 770
             "removeOption": "Elimina risposta",
771 771
             "send": "Invia"
772 772
         },
773
+        "errors": {
774
+            "notUniqueOption": "Le opzioni devono essere uniche"
775
+        },
773 776
         "notification": {
774 777
             "description": "Apri la scheda sondaggi per votare",
775 778
             "title": "Un nuovo sondaggio è stato aggiunto alla riunione"

+ 3
- 0
lang/main-ja.json View File

@@ -715,6 +715,9 @@
715 715
             "removeOption": "選択肢の削除",
716 716
             "send": "送信"
717 717
         },
718
+        "errors": {
719
+            "notUniqueOption": "オプションは一意でなければなりません"
720
+        },
718 721
         "notification": {
719 722
             "description": "投票するには投票タブを開いてください",
720 723
             "title": "新しい投票がこのミーティングに追加されました"

+ 3
- 0
lang/main-kab.json View File

@@ -667,6 +667,9 @@
667 667
             "removeOption": "Kkes aɣewwaṛ",
668 668
             "send": "Azen"
669 669
         },
670
+        "errors": {
671
+            "notUniqueOption": "tifranin ilaq ad ilin d imaynuten"
672
+        },
670 673
         "notification": {
671 674
             "description": "Ldi iccer n yisenqad i ufran",
672 675
             "title": "Asenqed amaynut yettwarna ɣer temlilt-a"

+ 5
- 0
lang/main-ko.json View File

@@ -497,6 +497,11 @@
497 497
     },
498 498
     "passwordDigitsOnly": "최대 {{number}} 자리",
499 499
     "passwordSetRemotely": "다른 참가자가 설정",
500
+    "polls": {
501
+        "errors": {
502
+            "notUniqueOption": "옵션은 고유해야합니다"
503
+        }
504
+    },
500 505
     "poweredby": "powered by",
501 506
     "presenceStatus": {
502 507
         "busy": "바쁨",

+ 5
- 0
lang/main-lt.json View File

@@ -467,6 +467,11 @@
467 467
     },
468 468
     "passwordDigitsOnly": "Daugiausia {{number}} skaičių",
469 469
     "passwordSetRemotely": "nustatytas kito naudotojo",
470
+    "polls": {
471
+        "errors": {
472
+            "notUniqueOption": "Parinktys turi būti unikalios"
473
+        }
474
+    },
470 475
     "poweredby": "pateikiamas",
471 476
     "presenceStatus": {
472 477
         "busy": "Užimtas",

+ 3
- 0
lang/main-lv.json View File

@@ -875,6 +875,9 @@
875 875
             "removeOption": "Noņemt opciju",
876 876
             "send": "Nosūtīt"
877 877
         },
878
+        "errors": {
879
+            "notUniqueOption": "Iespējām jābūt unikālām"
880
+        },
878 881
         "notification": {
879 882
             "description": "Lai balsotu, atveriet aptauju cilni",
880 883
             "title": "Šai sapulcei tika pievienota jauna aptauja"

+ 5
- 0
lang/main-ml.json View File

@@ -545,6 +545,11 @@
545 545
     },
546 546
     "passwordDigitsOnly": "{{number}} അക്കങ്ങൾ വരെ",
547 547
     "passwordSetRemotely": "മറ്റൊരു പങ്കാളി സജ്ജമാക്കിയത്",
548
+    "polls": {
549
+        "errors": {
550
+            "notUniqueOption": "ഓപ്ഷനുകൾ അദ്വിതീയമായിരിക്കണം"
551
+        }
552
+    },
548 553
     "poweredby": "powered by",
549 554
     "prejoin": {
550 555
         "audioAndVideoError": "ഓഡിയോ, വീഡിയോ പിശക്:",

+ 3
- 0
lang/main-mn.json View File

@@ -802,6 +802,9 @@
802 802
             "removeOption": "Сонголт хасах",
803 803
             "send": "Илгээх"
804 804
         },
805
+        "errors": {
806
+            "notUniqueOption": "Сонголтууд өвөрмөц байх ёстой"
807
+        },
805 808
         "notification": {
806 809
             "description": "Саналаа өгөхийн тулд санал асуулгын хавтсыг нээнэ үү",
807 810
             "title": "Уулзалтанд шинэ санал асуулга нэмэгдлээ"

+ 5
- 0
lang/main-mr.json View File

@@ -482,6 +482,11 @@
482 482
     },
483 483
     "passwordDigitsOnly": " पर्यंत {{number}} अंक",
484 484
     "passwordSetRemotely": "दुसर्‍या सहभागीने सेट केलेले",
485
+    "polls": {
486
+        "errors": {
487
+            "notUniqueOption": "पर्याय अद्वितीय असणे आवश्यक आहे"
488
+        }
489
+    },
485 490
     "poweredby": "द्वारा समर्थित",
486 491
     "prejoin": {
487 492
         "audioAndVideoError": "ऑडिओ आणि व्हिडिओ त्रुटी:",

+ 3
- 0
lang/main-nl.json View File

@@ -668,6 +668,9 @@
668 668
             "removeOption": "Verwijder optie",
669 669
             "send": "Verstuur"
670 670
         },
671
+        "errors": {
672
+            "notUniqueOption": "Opties moeten uniek zijn"
673
+        },
671 674
         "notification": {
672 675
             "description": "Open het peilingen tabblad om te stemmen",
673 676
             "title": "Een nieuwe peiling is aangemaakt in deze vergadering"

+ 3
- 0
lang/main-oc.json View File

@@ -714,6 +714,9 @@
714 714
             "removeOption": "Suprimir l'opcion",
715 715
             "send": "Enviar"
716 716
         },
717
+        "errors": {
718
+            "notUniqueOption": "Las opcions devon èsser unicas"
719
+        },
717 720
         "notification": {
718 721
             "description": "Dobrissètz l’onglet dels sondatge per votar",
719 722
             "title": "Un sondatge novèl es estat apondut a la conferéncia"

+ 3
- 0
lang/main-pl.json View File

@@ -803,6 +803,9 @@
803 803
             "removeOption": "Usuń opcję",
804 804
             "send": "Wyślij"
805 805
         },
806
+        "errors": {
807
+            "notUniqueOption": "Opcje muszą być wyjątkowe"
808
+        },
806 809
         "notification": {
807 810
             "description": "Otwórz kartę ankiet, aby zagłosować",
808 811
             "title": "Utworzono nową ankietę do tego spotkania"

+ 3
- 0
lang/main-pt.json View File

@@ -875,6 +875,9 @@
875 875
             "removeOption": "Remover opção",
876 876
             "send": "Enviar"
877 877
         },
878
+        "errors": {
879
+            "notUniqueOption": "As opções devem ser únicas"
880
+        },
878 881
         "notification": {
879 882
             "description": "Abrir o separador das sondagens para votar",
880 883
             "title": "Uma nova sondagem foi adicionada a esta reunião"

+ 3
- 0
lang/main-ptBR.json View File

@@ -864,6 +864,9 @@
864 864
             "removeOption": "Remover opção",
865 865
             "send": "Enviar"
866 866
         },
867
+        "errors": {
868
+            "notUniqueOption": "As opções devem ser exclusivas"
869
+        },
867 870
         "notification": {
868 871
             "description": "Abra a aba das votações para votar",
869 872
             "title": "Uma nova votação foi iniciada nesta conferência"

+ 5
- 0
lang/main-ro.json View File

@@ -471,6 +471,11 @@
471 471
     },
472 472
     "passwordDigitsOnly": "Până la {{number}} cifre",
473 473
     "passwordSetRemotely": "Setată de un alt membru",
474
+    "polls": {
475
+        "errors": {
476
+            "notUniqueOption": "Opțiunile trebuie să fie unice"
477
+        }
478
+    },
474 479
     "poweredby": "cu sprijinul",
475 480
     "presenceStatus": {
476 481
         "busy": "Ocupat",

+ 3
- 0
lang/main-ru.json View File

@@ -771,6 +771,9 @@
771 771
             "removeOption": "Удалить вариант",
772 772
             "send": "Отправлять"
773 773
         },
774
+        "errors": {
775
+            "notUniqueOption": "Варианты должны быть уникальными"
776
+        },
774 777
         "notification": {
775 778
             "description": "Откройте вкладку опросов, чтобы проголосовать",
776 779
             "title": "К этой встрече добавлен новый опрос"

+ 3
- 0
lang/main-sc.json View File

@@ -772,6 +772,9 @@
772 772
             "removeOption": "Boga s'optzione",
773 773
             "send": "Imbia"
774 774
         },
775
+        "errors": {
776
+            "notUniqueOption": "Sas optziones depent èssere ùnicas"
777
+        },
775 778
         "notification": {
776 779
             "description": "Aberi ischeda de sondàgiu pro votare",
777 780
             "title": "Sondàgiu nou agiuntu a sa riunione"

+ 5
- 0
lang/main-sk.json View File

@@ -547,6 +547,11 @@
547 547
     },
548 548
     "passwordDigitsOnly": "až {{number}} číslic",
549 549
     "passwordSetRemotely": "nastavené iným účastníkom",
550
+    "polls": {
551
+        "errors": {
552
+            "notUniqueOption": "Možnosti musia byť jedinečné"
553
+        }
554
+    },
550 555
     "poweredby": "založené na",
551 556
     "prejoin": {
552 557
         "audioAndVideoError": "Chyba zvuku a videa:",

+ 3
- 0
lang/main-sl.json View File

@@ -668,6 +668,9 @@
668 668
             "removeOption": "Odstrani možnost",
669 669
             "send": "Pošlji"
670 670
         },
671
+        "errors": {
672
+            "notUniqueOption": "Možnosti morajo biti edinstvene"
673
+        },
671 674
         "notification": {
672 675
             "description": "Odpri zavihek z anketami za glasovanje",
673 676
             "title": "V sestanek je bila dodana nova anketa"

+ 3
- 0
lang/main-sq.json View File

@@ -872,6 +872,9 @@
872 872
             "removeOption": "Hiqe mundësinë",
873 873
             "send": "Dërgoje"
874 874
         },
875
+        "errors": {
876
+            "notUniqueOption": "Opsionet duhet të jenë unike"
877
+        },
875 878
         "notification": {
876 879
             "description": "Që të votoni, hapni skedën e pyetësorëve",
877 880
             "title": "Te ky takim u shtua një pyetësor i ri"

+ 5
- 0
lang/main-sr.json View File

@@ -447,6 +447,11 @@
447 447
     },
448 448
     "passwordDigitsOnly": "",
449 449
     "passwordSetRemotely": "",
450
+    "polls": {
451
+        "errors": {
452
+            "notUniqueOption": "Опције морају бити јединствене"
453
+        }
454
+    },
450 455
     "poweredby": "",
451 456
     "prejoin": {
452 457
         "audioAndVideoError": "Грешка звука и видеа:",

+ 3
- 0
lang/main-sv.json View File

@@ -804,6 +804,9 @@
804 804
             "removeOption": "Ta bort alternativ",
805 805
             "send": "Skicka"
806 806
         },
807
+        "errors": {
808
+            "notUniqueOption": "Alternativ måste vara unika"
809
+        },
807 810
         "notification": {
808 811
             "description": "Öppna fliken omröstningar för att rösta",
809 812
             "title": "En ny omröstning har blivit tillagd till detta möte"

+ 5
- 0
lang/main-te.json View File

@@ -577,6 +577,11 @@
577 577
     },
578 578
     "passwordDigitsOnly": "{{number}} అంకెల వరకు",
579 579
     "passwordSetRemotely": "మరో సదస్యులు అమర్చారు",
580
+    "polls": {
581
+        "errors": {
582
+            "notUniqueOption": "ఎంపికలు ప్రత్యేకంగా ఉండాలి"
583
+        }
584
+    },
580 585
     "poweredby": "శక్తిమంతం",
581 586
     "prejoin": {
582 587
         "audioAndVideoError": "Audio and video error:",

+ 3
- 0
lang/main-tr.json View File

@@ -875,6 +875,9 @@
875 875
             "removeOption": "Seçeneği sil",
876 876
             "send": "Gönder"
877 877
         },
878
+        "errors": {
879
+            "notUniqueOption": "Seçenekler benzersiz olmalı"
880
+        },
878 881
         "notification": {
879 882
             "description": "Oy vermek için anketler sekmesini açın",
880 883
             "title": "Anket toplantıya eklendi"

+ 3
- 0
lang/main-uk.json View File

@@ -800,6 +800,9 @@
800 800
             "removeOption": "Вилучити",
801 801
             "send": "Надіслати"
802 802
         },
803
+        "errors": {
804
+            "notUniqueOption": "Параметри повинні бути унікальними"
805
+        },
803 806
         "notification": {
804 807
             "description": "Щоб проголосувати, відкрийте вкладку опитувань",
805 808
             "title": "Додано нове опитування"

+ 5
- 0
lang/main-vi.json View File

@@ -474,6 +474,11 @@
474 474
     },
475 475
     "passwordDigitsOnly": "",
476 476
     "passwordSetRemotely": "được thiết lập bởi một người khác",
477
+    "polls": {
478
+        "errors": {
479
+            "notUniqueOption": "Tùy chọn phải là duy nhất"
480
+        }
481
+    },
477 482
     "poweredby": "Được hỗ trợ bởi",
478 483
     "presenceStatus": {
479 484
         "busy": "Bận",

+ 3
- 0
lang/main-zhCN.json View File

@@ -845,6 +845,9 @@
845 845
             "removeOption": "移除选项",
846 846
             "send": "发送"
847 847
         },
848
+        "errors": {
849
+            "notUniqueOption": "选项必须是唯一的"
850
+        },
848 851
         "notification": {
849 852
             "description": "打开投票页面进行投票",
850 853
             "title": "本次会议有一项新的投票"

+ 3
- 0
lang/main-zhTW.json View File

@@ -863,6 +863,9 @@
863 863
             "removeOption": "移除選項",
864 864
             "send": "傳送"
865 865
         },
866
+        "errors": {
867
+            "notUniqueOption": "選項必須是唯一的"
868
+        },
866 869
         "notification": {
867 870
             "description": "開啟投票分頁以參與投票",
868 871
             "title": "此會議有一項新投票"

+ 3
- 0
lang/main.json View File

@@ -875,6 +875,9 @@
875 875
             "removeOption": "Remove option",
876 876
             "send": "Send"
877 877
         },
878
+        "errors": {
879
+            "notUniqueOption": "Options must be unique"
880
+        },
878 881
         "notification": {
879 882
             "description": "Open polls tab to vote",
880 883
             "title": "A new poll was added to this meeting"

+ 5
- 1
react/features/polls/components/AbstractPollCreate.tsx View File

@@ -6,6 +6,7 @@ import { createPollEvent } from '../../analytics/AnalyticsEvents';
6 6
 import { sendAnalytics } from '../../analytics/functions';
7 7
 import { IReduxState } from '../../app/types';
8 8
 import { COMMAND_NEW_POLL } from '../constants';
9
+import { hasIdenticalAnswers } from '../functions';
9 10
 
10 11
 /**
11 12
  * The type of the React {@code Component} props of inheriting component.
@@ -37,6 +38,8 @@ export type AbstractProps = InputProps & {
37 38
  * @param {React.AbstractComponent} Component - The concrete component.
38 39
  * @returns {React.AbstractComponent}
39 40
  */
41
+
42
+
40 43
 const AbstractPollCreate = (Component: ComponentType<AbstractProps>) => (props: InputProps) => {
41 44
 
42 45
     const { setCreateMode } = props;
@@ -102,7 +105,8 @@ const AbstractPollCreate = (Component: ComponentType<AbstractProps>) => (props:
102 105
     // Check if the poll create form can be submitted i.e. if the send button should be disabled.
103 106
     const isSubmitDisabled
104 107
         = question.trim().length <= 0 // If no question is provided
105
-        || answers.filter(answer => answer.trim().length > 0).length < 2; // If not enough options are provided
108
+        || answers.filter(answer => answer.trim().length > 0).length < 2 // If not enough options are provided
109
+        || hasIdenticalAnswers(answers); // If duplicate options are provided
106 110
 
107 111
     const { t } = useTranslation();
108 112
 

+ 12
- 3
react/features/polls/components/web/PollCreate.tsx View File

@@ -201,11 +201,19 @@ const PollCreate = ({
201 201
                     value = { question } />
202 202
             </div>
203 203
             <ol className = { classes.answerList }>
204
-                {answers.map((answer: any, i: number) =>
205
-                    (<li
204
+                {answers.map((answer: any, i: number) => {
205
+
206
+                    const isIdenticalAnswer = answers.slice(0, i).length === 0 ? false
207
+                        : answers.slice(0, i).some((prevAnswer: string) =>
208
+                            prevAnswer === answer && prevAnswer !== '' && answer !== '');
209
+
210
+                    return (<li
206 211
                         className = { classes.answer }
207 212
                         key = { i }>
208 213
                         <Input
214
+                            bottomLabel = { (isIdenticalAnswer ? t('polls.errors.notUniqueOption',
215
+                             { index: i + 1 }) : '') }
216
+                            error = { isIdenticalAnswer }
209 217
                             id = { `polls-answer-input-${i}` }
210 218
                             label = { t('polls.create.pollOption', { index: i + 1 }) }
211 219
                             maxLength = { CHAR_LIMIT }
@@ -223,7 +231,8 @@ const PollCreate = ({
223 231
                             type = 'button'>
224 232
                             { t('polls.create.removeOption') }
225 233
                         </button>}
226
-                    </li>)
234
+                    </li>);
235
+                }
227 236
                 )}
228 237
             </ol>
229 238
             <div className = { classes.addButtonContainer }>

+ 15
- 0
react/features/polls/functions.ts View File

@@ -45,3 +45,18 @@ export function getUnreadPollCount(state: IReduxState) {
45 45
 export function isSubmitAnswerDisabled(checkBoxStates: Array<boolean>) {
46 46
     return !checkBoxStates.find(checked => checked);
47 47
 }
48
+
49
+/**
50
+ * Check if the input array has identical answers.
51
+ *
52
+ * @param {Array<string>} currentAnswers - The array of current answers to compare.
53
+ * @returns {boolean} - Returns true if the answers are identical.
54
+ */
55
+export function hasIdenticalAnswers(currentAnswers: Array<string>): boolean {
56
+
57
+    const nonEmptyCurrentAnswers = currentAnswers.filter((answer: string): boolean => answer !== '');
58
+
59
+    const currentAnswersSet = new Set(nonEmptyCurrentAnswers);
60
+
61
+    return currentAnswersSet.size !== nonEmptyCurrentAnswers.length;
62
+}

Loading…
Cancel
Save