Merge branch 'master' of github.com:mattermost/mattermost-server into MM-50966-in-product-expansion
Этот коммит содержится в:
@@ -1,3 +1,3 @@
|
||||
save-exact=true
|
||||
legacy-peer-deps=true
|
||||
global-style=true
|
||||
global-style=true
|
||||
|
||||
@@ -17,7 +17,7 @@ stop: ## Stops webpack
|
||||
ifeq ($(OS),Windows_NT)
|
||||
wmic process where "Caption='node.exe' and CommandLine like '%webpack%'" call terminate
|
||||
else
|
||||
@pkill -f webpack || true
|
||||
-@pkill -f webpack || true
|
||||
endif
|
||||
|
||||
.PHONY: restart
|
||||
|
||||
@@ -112,7 +112,6 @@
|
||||
"Categories.CreateCategoryDialog.UpdateText": "تحديث",
|
||||
"CenterPanel.Login": "تسجيل الدخول",
|
||||
"CenterPanel.Share": "مشاركة",
|
||||
"CloudMessage.cloud-server": "احصل علي خادم سحابي خاص بك مجاني.",
|
||||
"ColorOption.selectColor": "اختر {color} اللون",
|
||||
"Comment.delete": "حذف",
|
||||
"CommentsList.send": "إرسال",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"AdminBadge.SystemAdmin": "Administrator",
|
||||
"AdminBadge.TeamAdmin": "Teamadministrator",
|
||||
"AppBar.Tooltip": "Verknüpfte Boards umschalten",
|
||||
"Attachment.Attachment-title": "Anhang",
|
||||
"AttachmentBlock.DeleteAction": "Löschen",
|
||||
@@ -22,7 +24,7 @@
|
||||
"BoardMember.schemeCommenter": "Kommentator",
|
||||
"BoardMember.schemeEditor": "Bearbeiter",
|
||||
"BoardMember.schemeNone": "Keine",
|
||||
"BoardMember.schemeViewer": "Viewer",
|
||||
"BoardMember.schemeViewer": "Leser",
|
||||
"BoardMember.unlinkChannel": "Verknüpfung aufheben",
|
||||
"BoardPage.newVersion": "Eine neue Version von Boards ist verfügbar, klicke hier, um neu zu laden.",
|
||||
"BoardPage.syncFailed": "Das Board kann gelöscht oder der Zugang entzogen werden.",
|
||||
@@ -115,7 +117,6 @@
|
||||
"CenterPanel.Login": "Anmeldung",
|
||||
"CenterPanel.Share": "Teilen",
|
||||
"ChannelIntro.CreateBoard": "Erstelle ein Board",
|
||||
"CloudMessage.cloud-server": "Hole deine eigenen freien Cloud Server.",
|
||||
"ColorOption.selectColor": "Wähle Farbe {color}",
|
||||
"Comment.delete": "Löschen",
|
||||
"CommentsList.send": "Abschicken",
|
||||
@@ -138,6 +139,7 @@
|
||||
"ContentBlock.moveDown": "Nach unten bewegen",
|
||||
"ContentBlock.moveUp": "Nach oben bewegen",
|
||||
"ContentBlock.text": "Text",
|
||||
"DateFilter.empty": "Leer",
|
||||
"DateRange.clear": "Leeren",
|
||||
"DateRange.empty": "Leer",
|
||||
"DateRange.endDate": "Enddatum",
|
||||
@@ -156,10 +158,14 @@
|
||||
"Filter.ends-with": "endet mit",
|
||||
"Filter.includes": "beinhaltet",
|
||||
"Filter.is": "ist",
|
||||
"Filter.is-after": "ist nach",
|
||||
"Filter.is-before": "ist vor",
|
||||
"Filter.is-empty": "ist leer",
|
||||
"Filter.is-not-empty": "ist nicht leer",
|
||||
"Filter.is-not-set": "ist nicht gesetzt",
|
||||
"Filter.is-set": "ist gesetzt",
|
||||
"Filter.isafter": "ist nach",
|
||||
"Filter.isbefore": "ist vor",
|
||||
"Filter.not-contains": "enthält nicht",
|
||||
"Filter.not-ends-with": "endet nicht mit",
|
||||
"Filter.not-includes": "beinhaltet nicht",
|
||||
@@ -306,6 +312,7 @@
|
||||
"ValueSelector.valueSelector": "Werteselektor",
|
||||
"ValueSelectorLabel.openMenu": "Menü öffnen",
|
||||
"VersionMessage.help": "Finde raus, was es Neues in dieser Version gibt.",
|
||||
"VersionMessage.learn-more": "Erfahre mehr",
|
||||
"View.AddView": "Ansicht hinzufügen",
|
||||
"View.Board": "Board",
|
||||
"View.DeleteView": "Ansicht löschen",
|
||||
@@ -360,6 +367,9 @@
|
||||
"WelcomePage.StartUsingIt.Text": "Verwende es",
|
||||
"Workspace.editing-board-template": "Du bearbeitest eine Board Vorlage.",
|
||||
"badge.guest": "Gast",
|
||||
"boardPage.confirm-join-button": "Teilnehmen",
|
||||
"boardPage.confirm-join-text": "Du bist dabei einem privaten Board zu betreten, ohne dass du explizit durch den Board-Administrator hinzugefügt wurdest. Bist du sicher, dass du diesem privaten Board beitreten willst?",
|
||||
"boardPage.confirm-join-title": "Privatem Board beitreten",
|
||||
"boardSelector.confirm-link-board": "Verknüpfe Board mit Kanal",
|
||||
"boardSelector.confirm-link-board-button": "Ja, verknüpfe Board",
|
||||
"boardSelector.confirm-link-board-subtext": "Wenn du \"{boardName}\" mit diesem Kanal verknüpfst, werden alle Mitglieder des Kanals (aktuelle und neue) das Board bearbeiten können. Dies schließt Mitglieder aus, die Gast sind. Du kannst die Verknüpfung eine Boards mit einem Kanal jederzeit entfernen.",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"AdminBadge.SystemAdmin": "Admin",
|
||||
"AdminBadge.TeamAdmin": "Team Admin",
|
||||
"AppBar.Tooltip": "Toggle Linked Boards",
|
||||
"AppBar.Tooltip": "Toggle linked boards",
|
||||
"Attachment.Attachment-title": "Attachment",
|
||||
"AttachmentBlock.DeleteAction": "delete",
|
||||
"AttachmentBlock.addElement": "add {type}",
|
||||
@@ -453,4 +453,4 @@
|
||||
"tutorial_tip.ok": "Next",
|
||||
"tutorial_tip.out": "Opt out of these tips.",
|
||||
"tutorial_tip.seen": "Seen this before?"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"AppBar.Tooltip": "Toggle linked boards",
|
||||
"AdminBadge.SystemAdmin": "Admin",
|
||||
"AdminBadge.TeamAdmin": "Team Admin",
|
||||
"AppBar.Tooltip": "Toggle Linked Boards",
|
||||
"Attachment.Attachment-title": "Attachment",
|
||||
"AttachmentBlock.DeleteAction": "delete",
|
||||
"AttachmentBlock.addElement": "add {type}",
|
||||
@@ -115,7 +117,6 @@
|
||||
"CenterPanel.Login": "Login",
|
||||
"CenterPanel.Share": "Share",
|
||||
"ChannelIntro.CreateBoard": "Create a board",
|
||||
"CloudMessage.cloud-server": "Get your own free cloud server.",
|
||||
"ColorOption.selectColor": "Select {color} Colour",
|
||||
"Comment.delete": "Delete",
|
||||
"CommentsList.send": "Send",
|
||||
@@ -138,6 +139,7 @@
|
||||
"ContentBlock.moveDown": "Move down",
|
||||
"ContentBlock.moveUp": "Move up",
|
||||
"ContentBlock.text": "text",
|
||||
"DateFilter.empty": "Empty",
|
||||
"DateRange.clear": "Clear",
|
||||
"DateRange.empty": "Empty",
|
||||
"DateRange.endDate": "End date",
|
||||
@@ -156,10 +158,14 @@
|
||||
"Filter.ends-with": "ends with",
|
||||
"Filter.includes": "includes",
|
||||
"Filter.is": "is",
|
||||
"Filter.is-after": "is after",
|
||||
"Filter.is-before": "is before",
|
||||
"Filter.is-empty": "is empty",
|
||||
"Filter.is-not-empty": "is not empty",
|
||||
"Filter.is-not-set": "is not set",
|
||||
"Filter.is-set": "is set",
|
||||
"Filter.isafter": "is after",
|
||||
"Filter.isbefore": "is before",
|
||||
"Filter.not-contains": "does not contain",
|
||||
"Filter.not-ends-with": "does not end with",
|
||||
"Filter.not-includes": "doesn't include",
|
||||
@@ -306,6 +312,7 @@
|
||||
"ValueSelector.valueSelector": "Value selector",
|
||||
"ValueSelectorLabel.openMenu": "Open menu",
|
||||
"VersionMessage.help": "Check out what's new in this version.",
|
||||
"VersionMessage.learn-more": "Learn more",
|
||||
"View.AddView": "Add view",
|
||||
"View.Board": "Board",
|
||||
"View.DeleteView": "Delete view",
|
||||
@@ -360,6 +367,9 @@
|
||||
"WelcomePage.StartUsingIt.Text": "Start using it",
|
||||
"Workspace.editing-board-template": "You're editing a board template.",
|
||||
"badge.guest": "Guest",
|
||||
"boardPage.confirm-join-button": "Join",
|
||||
"boardPage.confirm-join-text": "You are about to join a private board without explicitly being added by the board admin. Are you sure you wish to join this private board?",
|
||||
"boardPage.confirm-join-title": "Join private board",
|
||||
"boardSelector.confirm-link-board": "Link board to channel",
|
||||
"boardSelector.confirm-link-board-button": "Link board",
|
||||
"boardSelector.confirm-link-board-subtext": "When you link '\\{boardName}'\\ to the channel, all members of the channel (existing and new) will be able to edit it. This excludes members who are guests. You can unlink a board from a channel at any time.",
|
||||
|
||||
@@ -102,7 +102,6 @@
|
||||
"Categories.CreateCategoryDialog.UpdateText": "Mettre à jour",
|
||||
"CenterPanel.Login": "Connexion",
|
||||
"CenterPanel.Share": "Partager",
|
||||
"CloudMessage.cloud-server": "Obtenez votre propre serveur cloud gratuitement.",
|
||||
"ColorOption.selectColor": "Choisir la couleur {color}",
|
||||
"Comment.delete": "Supprimer",
|
||||
"CommentsList.send": "Envoyer",
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
"Categories.CreateCategoryDialog.UpdateText": "עדכון",
|
||||
"CenterPanel.Login": "כניסה",
|
||||
"CenterPanel.Share": "שיתוף",
|
||||
"CloudMessage.cloud-server": "קבל שרת ענן בחינם.",
|
||||
"ColorOption.selectColor": "בחירת צבע {color}",
|
||||
"Comment.delete": "מחיקה",
|
||||
"CommentsList.send": "שליחה",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"AdminBadge.SystemAdmin": "Administrator",
|
||||
"AdminBadge.TeamAdmin": "Tim administratora",
|
||||
"AppBar.Tooltip": "Uklj./Isklj. povezane ploče",
|
||||
"Attachment.Attachment-title": "Prilog",
|
||||
"AttachmentBlock.DeleteAction": "izbriši",
|
||||
@@ -115,7 +117,6 @@
|
||||
"CenterPanel.Login": "Prijava",
|
||||
"CenterPanel.Share": "Dijeli",
|
||||
"ChannelIntro.CreateBoard": "Stvori ploču",
|
||||
"CloudMessage.cloud-server": "Nabavi vlastiti besplatni poslužitelj u oblaku.",
|
||||
"ColorOption.selectColor": "Odaberi boju {color}",
|
||||
"Comment.delete": "Izbriši",
|
||||
"CommentsList.send": "Pošalji",
|
||||
@@ -138,6 +139,7 @@
|
||||
"ContentBlock.moveDown": "Pomakni dolje",
|
||||
"ContentBlock.moveUp": "Pomakni gore",
|
||||
"ContentBlock.text": "tekst",
|
||||
"DateFilter.empty": "Prazno",
|
||||
"DateRange.clear": "Isprazni",
|
||||
"DateRange.empty": "Prazno",
|
||||
"DateRange.endDate": "Datum kraja",
|
||||
@@ -156,10 +158,14 @@
|
||||
"Filter.ends-with": "završava sa",
|
||||
"Filter.includes": "uključuje",
|
||||
"Filter.is": "je",
|
||||
"Filter.is-after": "je nakon",
|
||||
"Filter.is-before": "je prije",
|
||||
"Filter.is-empty": "je prazno",
|
||||
"Filter.is-not-empty": "nije prazno",
|
||||
"Filter.is-not-set": "nije postavljeno",
|
||||
"Filter.is-set": "je postavljeno",
|
||||
"Filter.isafter": "je nakon",
|
||||
"Filter.isbefore": "je prije",
|
||||
"Filter.not-contains": "ne sadrži",
|
||||
"Filter.not-ends-with": "ne završava sa",
|
||||
"Filter.not-includes": "ne uključuje",
|
||||
@@ -306,6 +312,7 @@
|
||||
"ValueSelector.valueSelector": "Selektor vrijednosti",
|
||||
"ValueSelectorLabel.openMenu": "Otvori izbornik",
|
||||
"VersionMessage.help": "Provjeri što je novo u ovoj verziji.",
|
||||
"VersionMessage.learn-more": "Saznaj više",
|
||||
"View.AddView": "Dodaj prikaz",
|
||||
"View.Board": "Ploča",
|
||||
"View.DeleteView": "Izbriši prikaz",
|
||||
@@ -360,6 +367,9 @@
|
||||
"WelcomePage.StartUsingIt.Text": "Počni ga koristiti",
|
||||
"Workspace.editing-board-template": "Uređuješ predložak ploče.",
|
||||
"badge.guest": "Gost",
|
||||
"boardPage.confirm-join-button": "Pridruži se",
|
||||
"boardPage.confirm-join-text": "Pridružit ćeš se privatnoj ploči bez da te je administrator ploče izričito dodao. Stvarno se želiš pridružiti ovoj privatnoj ploči?",
|
||||
"boardPage.confirm-join-title": "Pridruži se privatnoj ploči",
|
||||
"boardSelector.confirm-link-board": "Poveži ploču s kanalom",
|
||||
"boardSelector.confirm-link-board-button": "Da, poveži ploču",
|
||||
"boardSelector.confirm-link-board-subtext": "Kad povežeš ploču „{boardName}” s kanalom, svi članovi kanala (postojeći i novi) moći će je uređivati. To ne vrijedi za članove koji su gosti. Vezu između ploče i kanala možeš raskinuti u bilo kojem trenutku.",
|
||||
|
||||
@@ -114,7 +114,6 @@
|
||||
"Categories.CreateCategoryDialog.UpdateText": "Frissítés",
|
||||
"CenterPanel.Login": "Bejelentkezés",
|
||||
"CenterPanel.Share": "Megosztás",
|
||||
"CloudMessage.cloud-server": "Szerezze be saját ingyenes felhőszerverét.",
|
||||
"ColorOption.selectColor": "{color} szín kiválasztása",
|
||||
"Comment.delete": "Törlés",
|
||||
"CommentsList.send": "Küldés",
|
||||
|
||||
@@ -100,7 +100,6 @@
|
||||
"Categories.CreateCategoryDialog.UpdateText": "Aggiorna",
|
||||
"CenterPanel.Login": "Login",
|
||||
"CenterPanel.Share": "Condividi",
|
||||
"CloudMessage.cloud-server": "Ottieni il tuo server cloud gratuito.",
|
||||
"ColorOption.selectColor": "Seleziona{color} Colore",
|
||||
"Comment.delete": "Elimina",
|
||||
"CommentsList.send": "Invia",
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
"CenterPanel.Login": "ログイン",
|
||||
"CenterPanel.Share": "共有",
|
||||
"ChannelIntro.CreateBoard": "Boardを作成する",
|
||||
"CloudMessage.cloud-server": "専用の無料クラウドサーバーを入手する。",
|
||||
"ColorOption.selectColor": "{color} 色を選択",
|
||||
"Comment.delete": "削除",
|
||||
"CommentsList.send": "送信",
|
||||
|
||||
@@ -102,7 +102,6 @@
|
||||
"Categories.CreateCategoryDialog.UpdateText": "განახლება",
|
||||
"CenterPanel.Login": "შესვლა",
|
||||
"CenterPanel.Share": "გაზიარება",
|
||||
"CloudMessage.cloud-server": "მიიღეთ თქვენი საკუთარი უფასო Cloud სერვერი.",
|
||||
"ColorOption.selectColor": "აირჩიეთ {color} ფერი",
|
||||
"Comment.delete": "წაშლა",
|
||||
"CommentsList.send": "გაგზავნა",
|
||||
|
||||
@@ -114,7 +114,6 @@
|
||||
"Categories.CreateCategoryDialog.UpdateText": "업데이트",
|
||||
"CenterPanel.Login": "로그인",
|
||||
"CenterPanel.Share": "공유",
|
||||
"CloudMessage.cloud-server": "무료 클라우드 서버를 구입하십시오.",
|
||||
"ColorOption.selectColor": "{color} 색 선택하기",
|
||||
"Comment.delete": "삭제하기",
|
||||
"CommentsList.send": "보내기",
|
||||
|
||||
1
webapp/boards/i18n/lt.json
Обычный файл
1
webapp/boards/i18n/lt.json
Обычный файл
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -115,7 +115,6 @@
|
||||
"CenterPanel.Login": "Logg inn",
|
||||
"CenterPanel.Share": "Del",
|
||||
"ChannelIntro.CreateBoard": "Opprett tavle",
|
||||
"CloudMessage.cloud-server": "Få din egen gratis skytjener.",
|
||||
"ColorOption.selectColor": "Velg {color} farge",
|
||||
"Comment.delete": "Slett",
|
||||
"CommentsList.send": "Send",
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
"CenterPanel.Login": "Aanmelden",
|
||||
"CenterPanel.Share": "Delen",
|
||||
"ChannelIntro.CreateBoard": "Een bord aanmaken",
|
||||
"CloudMessage.cloud-server": "Krijg jouw eigen gratis cloud server.",
|
||||
"ColorOption.selectColor": "Selecteer {color} Kleur",
|
||||
"Comment.delete": "Verwijderen",
|
||||
"CommentsList.send": "Verzenden",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"AppBar.Tooltip": "Przełączanie podlinkowanych tablic",
|
||||
"AdminBadge.SystemAdmin": "Administrator",
|
||||
"AdminBadge.TeamAdmin": "Administrator Zespołu",
|
||||
"AppBar.Tooltip": "Przełączanie Podlinkowanych Tablic",
|
||||
"Attachment.Attachment-title": "Załącznik",
|
||||
"AttachmentBlock.DeleteAction": "usuń",
|
||||
"AttachmentBlock.addElement": "dodaj {type}",
|
||||
@@ -115,7 +117,6 @@
|
||||
"CenterPanel.Login": "Logowanie",
|
||||
"CenterPanel.Share": "Udostępnij",
|
||||
"ChannelIntro.CreateBoard": "Utwórz tablicę",
|
||||
"CloudMessage.cloud-server": "Uzyskaj własny, bezpłatny serwer w chmurze.",
|
||||
"ColorOption.selectColor": "Wybierz Kolor {color}",
|
||||
"Comment.delete": "Usuń",
|
||||
"CommentsList.send": "Wyślij",
|
||||
@@ -138,6 +139,7 @@
|
||||
"ContentBlock.moveDown": "Przenieś w dół",
|
||||
"ContentBlock.moveUp": "Przenieś w górę",
|
||||
"ContentBlock.text": "tekst",
|
||||
"DateFilter.empty": "Puste",
|
||||
"DateRange.clear": "Wyczyść",
|
||||
"DateRange.empty": "Puste",
|
||||
"DateRange.endDate": "Data końcowa",
|
||||
@@ -156,10 +158,14 @@
|
||||
"Filter.ends-with": "kończy się na",
|
||||
"Filter.includes": "zawiera",
|
||||
"Filter.is": "jest",
|
||||
"Filter.is-after": "jest po",
|
||||
"Filter.is-before": "jest przed",
|
||||
"Filter.is-empty": "jest pusty",
|
||||
"Filter.is-not-empty": "nie jest pusty",
|
||||
"Filter.is-not-set": "nie jest ustawiony",
|
||||
"Filter.is-set": "jest ustawiony",
|
||||
"Filter.isafter": "jest po",
|
||||
"Filter.isbefore": "jest przed",
|
||||
"Filter.not-contains": "nie zawiera",
|
||||
"Filter.not-ends-with": "nie kończy się na",
|
||||
"Filter.not-includes": "nie zawiera",
|
||||
@@ -306,6 +312,7 @@
|
||||
"ValueSelector.valueSelector": "Selektor wartości",
|
||||
"ValueSelectorLabel.openMenu": "Otwórz menu",
|
||||
"VersionMessage.help": "Sprawdź co nowego w tej wersji.",
|
||||
"VersionMessage.learn-more": "Dowiedź się więcej",
|
||||
"View.AddView": "Dodaj widok",
|
||||
"View.Board": "Tablica",
|
||||
"View.DeleteView": "Usuń widok",
|
||||
@@ -360,6 +367,9 @@
|
||||
"WelcomePage.StartUsingIt.Text": "Zacznij używać",
|
||||
"Workspace.editing-board-template": "Edytujesz szablon tablicy.",
|
||||
"badge.guest": "Gość",
|
||||
"boardPage.confirm-join-button": "Dołącz",
|
||||
"boardPage.confirm-join-text": "Zamierzasz dołączyć do prywatnej tablicy bez wyraźnego dodania przez administratora forum. Czy na pewno chcesz dołączyć do tego prywatnego forum?",
|
||||
"boardPage.confirm-join-title": "Dołącz do prywatnej tablicy",
|
||||
"boardSelector.confirm-link-board": "Połączenie tablicy z kanałem",
|
||||
"boardSelector.confirm-link-board-button": "Tak, podlinkuj tablicę",
|
||||
"boardSelector.confirm-link-board-subtext": "Kiedy połączysz \"{boardName}\" z kanałem, wszyscy członkowie kanału (istniejący i nowi) będą mogli go edytować. Nie dotyczy to członków, którzy są gośćmi. W każdej chwili możesz odłączyć tablicę od kanału.",
|
||||
|
||||
@@ -1,12 +1,96 @@
|
||||
{
|
||||
"AdminBadge.SystemAdmin": "Administrador",
|
||||
"AppBar.Tooltip": "Alternar quadros vinculados",
|
||||
"Attachment.Attachment-title": "Anexo",
|
||||
"AttachmentBlock.DeleteAction": "Apagar",
|
||||
"AttachmentBlock.addElement": "Adicionar {tipo}",
|
||||
"AttachmentBlock.addElement": "Adicionar {type}",
|
||||
"AttachmentBlock.delete": "Anexo apagado.",
|
||||
"AttachmentBlock.failed": "Este arquivo não pôde ser carregado pois ultrapassou o tamanho limite.",
|
||||
"AttachmentBlock.upload": "Carregando anexo.",
|
||||
"AttachmentBlock.uploadSuccess": "Anexo carregado.",
|
||||
"AttachmentElement.delete-confirmation-dialog-button-text": "Apagar",
|
||||
"AttachmentElement.download": "Baixar"
|
||||
"AttachmentElement.download": "Baixar",
|
||||
"BoardComponent.add-a-group": "+ Adicionar um grupo",
|
||||
"BoardComponent.delete": "Apagar",
|
||||
"BoardComponent.hidden-columns": "Colunas escondidas",
|
||||
"BoardComponent.hide": "Esconder",
|
||||
"BoardComponent.new": "+ Novo",
|
||||
"BoardComponent.no-property": "Não {property}",
|
||||
"BoardComponent.show": "Mostrar",
|
||||
"BoardMember.schemeAdmin": "Admin",
|
||||
"BoardMember.schemeCommenter": "Comentador",
|
||||
"BoardMember.schemeEditor": "Editor",
|
||||
"BoardMember.schemeNone": "Nenhum",
|
||||
"BoardMember.unlinkChannel": "Desvincular",
|
||||
"BoardPage.newVersion": "Está disponível uma nova versão do Boards, clique aqui para recarregar.",
|
||||
"BoardPage.syncFailed": "O Board pode ter sido apagado ou o acesso revogado.",
|
||||
"BoardTemplateSelector.add-template": "Criar novo modelo",
|
||||
"BoardTemplateSelector.create-empty-board": "Criar um board vazio",
|
||||
"BoardTemplateSelector.delete-template": "Apagar",
|
||||
"BoardTemplateSelector.edit-template": "Editar",
|
||||
"BoardTemplateSelector.plugin.no-content-title": "Criar um board",
|
||||
"BoardTemplateSelector.title": "Criar um board",
|
||||
"BoardTemplateSelector.use-this-template": "Usar este modelo",
|
||||
"BoardsSwitcher.Title": "Encontrar boards",
|
||||
"Calculations.Options.average.displayName": "Média",
|
||||
"Calculations.Options.average.label": "Média",
|
||||
"Calculations.Options.countUniqueValue.displayName": "Único",
|
||||
"Calculations.Options.countValue.displayName": "Valores",
|
||||
"Calculations.Options.dateRange.displayName": "Intervalo",
|
||||
"Calculations.Options.dateRange.label": "Intervalo",
|
||||
"Calculations.Options.latest.label": "Mais recente",
|
||||
"Calculations.Options.max.displayName": "Máx",
|
||||
"Calculations.Options.max.label": "Máximo",
|
||||
"Calculations.Options.min.displayName": "Mínimo",
|
||||
"Calculations.Options.min.label": "Mínimo",
|
||||
"Calculations.Options.none.label": "Nenhum",
|
||||
"Calculations.Options.range.displayName": "Intervalo",
|
||||
"Calculations.Options.range.label": "Intervalo",
|
||||
"Calculations.Options.sum.displayName": "Soma",
|
||||
"Calculations.Options.sum.label": "Soma",
|
||||
"CalendarCard.untitled": "Sem título",
|
||||
"CardActionsMenu.copiedLink": "Copiado!",
|
||||
"CardActionsMenu.copyLink": "Copiar link",
|
||||
"CardActionsMenu.delete": "Apagar",
|
||||
"CardActionsMenu.duplicate": "Duplicar",
|
||||
"CardBadges.title-comments": "Comentários",
|
||||
"CardDetail.Attach": "Anexar",
|
||||
"CardDetail.Follow": "Seguir",
|
||||
"CardDetail.Following": "Seguindo",
|
||||
"CardDetail.add-content": "Adicionar conteúdo",
|
||||
"CardDetail.add-icon": "Adicionar ícone",
|
||||
"CardDetail.add-property": "+ Adicionar uma propriedade",
|
||||
"CardDetail.limited-button": "Atualizar",
|
||||
"CardDetail.new-comment-placeholder": "Adicionar um comentário...",
|
||||
"CardDetailProperty.delete-action-button": "Apagar",
|
||||
"CardDialog.delete-confirmation-dialog-button-text": "Apagar",
|
||||
"Categories.CreateCategoryDialog.CancelText": "Cancelar",
|
||||
"Categories.CreateCategoryDialog.CreateText": "Criar",
|
||||
"Categories.CreateCategoryDialog.UpdateText": "Atualizar",
|
||||
"CenterPanel.Login": "Entrar",
|
||||
"CenterPanel.Share": "Compartilhar",
|
||||
"Comment.delete": "Apagar",
|
||||
"CommentsList.send": "Enviar",
|
||||
"ConfirmPerson.empty": "Vazio",
|
||||
"ConfirmPerson.search": "Procurar...",
|
||||
"ConfirmationDialog.cancel-action": "Cancelar",
|
||||
"ConfirmationDialog.confirm-action": "Confirmar",
|
||||
"ContentBlock.Delete": "Apagar",
|
||||
"ContentBlock.DeleteAction": "apagar",
|
||||
"ContentBlock.addElement": "adicionar {type}",
|
||||
"ContentBlock.editText": "Editar texto...",
|
||||
"ContentBlock.image": "imagem",
|
||||
"ContentBlock.moveDown": "Mover pra baixo",
|
||||
"ContentBlock.moveUp": "Mover pra cima",
|
||||
"ContentBlock.text": "texto",
|
||||
"DateFilter.empty": "Vazio",
|
||||
"DateRange.clear": "Limpar",
|
||||
"DateRange.empty": "Vazio",
|
||||
"DateRange.today": "Hoje",
|
||||
"DeleteBoardDialog.confirm-cancel": "Cancelar",
|
||||
"DeleteBoardDialog.confirm-delete": "Apagar",
|
||||
"EditableDayPicker.today": "Hoje",
|
||||
"shareBoard.members-select-group": "Membros",
|
||||
"shareBoard.unknown-channel-display-name": "Canal desconhecido",
|
||||
"tutorial_tip.ok": "Próximo"
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
{
|
||||
"AppBar.Tooltip": "Ativar boards vinculados",
|
||||
"AdminBadge.SystemAdmin": "Administrador",
|
||||
"AdminBadge.TeamAdmin": "Administrador de equipe",
|
||||
"AppBar.Tooltip": "Ativar Boards Vinculados",
|
||||
"Attachment.Attachment-title": "Anexo",
|
||||
"AttachmentBlock.DeleteAction": "apagar",
|
||||
"AttachmentBlock.DeleteAction": "excluir",
|
||||
"AttachmentBlock.addElement": "adicionar {type}",
|
||||
"AttachmentBlock.delete": "Anexo apagado.",
|
||||
"AttachmentBlock.failed": "Este arquivo não pôde ser carregado pois ultrapassou o tamanho limite.",
|
||||
"AttachmentBlock.upload": "Carregando anexo.",
|
||||
"AttachmentBlock.uploadSuccess": "Anexo enviado.",
|
||||
"AttachmentElement.delete-confirmation-dialog-button-text": "Apagar",
|
||||
"AttachmentElement.delete-confirmation-dialog-button-text": "Excluir",
|
||||
"AttachmentElement.download": "Baixar",
|
||||
"AttachmentElement.upload-percentage": "Enviando...({uploadPercent}%)",
|
||||
"BoardComponent.add-a-group": "+ Adicione um grupo",
|
||||
"BoardComponent.delete": "Excluir",
|
||||
@@ -13,7 +18,7 @@
|
||||
"BoardComponent.hide": "Ocultar",
|
||||
"BoardComponent.new": "Novo",
|
||||
"BoardComponent.no-property": "Sem {property}",
|
||||
"BoardComponent.no-property-title": "Itens com um {property} vazio irão aqui. Esta coluna não pode ser removida.",
|
||||
"BoardComponent.no-property-title": "Itens com um valor {property} vazio aparecerão aqui. Esta coluna não pode ser excluída.",
|
||||
"BoardComponent.show": "Exibir",
|
||||
"BoardMember.schemeAdmin": "Administrador",
|
||||
"BoardMember.schemeCommenter": "Comentarista",
|
||||
@@ -28,7 +33,7 @@
|
||||
"BoardTemplateSelector.delete-template": "Excluir",
|
||||
"BoardTemplateSelector.description": "Adicione um quadro à barra lateral usando qualquer um dos modelos definidos abaixo ou comece do zero.",
|
||||
"BoardTemplateSelector.edit-template": "Editar",
|
||||
"BoardTemplateSelector.plugin.no-content-description": "Adicionar um quadro a barra lateral usando qualquer dos templates definidos abaixo ou começar do zero.",
|
||||
"BoardTemplateSelector.plugin.no-content-description": "Adicione um board à barra lateral usando um dos templates disponíveis abaixo ou comece do zero.",
|
||||
"BoardTemplateSelector.plugin.no-content-title": "Criar um board",
|
||||
"BoardTemplateSelector.title": "Criar um board",
|
||||
"BoardTemplateSelector.use-this-template": "Use este template",
|
||||
@@ -38,16 +43,16 @@
|
||||
"BoardsUnfurl.Updated": "Atualizado {time}",
|
||||
"Calculations.Options.average.displayName": "Média",
|
||||
"Calculations.Options.average.label": "Média",
|
||||
"Calculations.Options.count.displayName": "Contagem",
|
||||
"Calculations.Options.count.label": "Contagem",
|
||||
"Calculations.Options.countChecked.displayName": "Verificado",
|
||||
"Calculations.Options.countChecked.label": "Contagem verificada",
|
||||
"Calculations.Options.countUnchecked.displayName": "Não verificado",
|
||||
"Calculations.Options.countUnchecked.label": "Contagem não verificada",
|
||||
"Calculations.Options.count.displayName": "Total",
|
||||
"Calculations.Options.count.label": "Total",
|
||||
"Calculations.Options.countChecked.displayName": "Confirmado",
|
||||
"Calculations.Options.countChecked.label": "Total de itens confirmados",
|
||||
"Calculations.Options.countUnchecked.displayName": "Não confirmado",
|
||||
"Calculations.Options.countUnchecked.label": "Total de itens não confirmados",
|
||||
"Calculations.Options.countUniqueValue.displayName": "Único",
|
||||
"Calculations.Options.countUniqueValue.label": "Contagem valores únicos",
|
||||
"Calculations.Options.countUniqueValue.label": "Total de valores únicos",
|
||||
"Calculations.Options.countValue.displayName": "Valores",
|
||||
"Calculations.Options.countValue.label": "Contagem de valor",
|
||||
"Calculations.Options.countValue.label": "Valor total",
|
||||
"Calculations.Options.dateRange.displayName": "Período",
|
||||
"Calculations.Options.dateRange.label": "Alcance",
|
||||
"Calculations.Options.earliest.displayName": "Mais antigo",
|
||||
@@ -85,7 +90,7 @@
|
||||
"CardDetail.add-icon": "Adicionar ícone",
|
||||
"CardDetail.add-property": "+ Adicionar propriedade",
|
||||
"CardDetail.addCardText": "adicionar texto ao card",
|
||||
"CardDetail.limited-body": "Atualize para nosso plano Professional ou Enterprise para visualizar cartões arquivados, ter visualizações ilimitadas por quadros, cartões ilimitados e mais.",
|
||||
"CardDetail.limited-body": "Atualize para nosso plano Professional ou Enterprise.",
|
||||
"CardDetail.limited-button": "Upgrade",
|
||||
"CardDetail.limited-title": "Este cartão está oculto",
|
||||
"CardDetail.moveContent": "Mover conteúdo do cartão",
|
||||
@@ -100,10 +105,11 @@
|
||||
"CardDetailProperty.property-deleted": "{propertyName} excluído com êxito!",
|
||||
"CardDetailProperty.property-name-change-subtext": "digite de \"{oldPropType}\" para \"{newPropType}\"",
|
||||
"CardDetial.limited-link": "Saiba mais sobre nossos planos.",
|
||||
"CardDialog.delete-confirmation-dialog-attachment": "Confirmar exclusão de anexo",
|
||||
"CardDialog.delete-confirmation-dialog-button-text": "Excluir",
|
||||
"CardDialog.delete-confirmation-dialog-heading": "Confirmar exclusão do card!",
|
||||
"CardDialog.delete-confirmation-dialog-heading": "Confirmar exclusão do cartão",
|
||||
"CardDialog.editing-template": "Você está editando um template.",
|
||||
"CardDialog.nocard": "Esse card não existe ou não está acessível.",
|
||||
"CardDialog.nocard": "Esse cartão não existe ou não está acessível.",
|
||||
"Categories.CreateCategoryDialog.CancelText": "Cancelar",
|
||||
"Categories.CreateCategoryDialog.CreateText": "Criar",
|
||||
"Categories.CreateCategoryDialog.Placeholder": "Nomeie sua categoria",
|
||||
@@ -111,7 +117,6 @@
|
||||
"CenterPanel.Login": "Login",
|
||||
"CenterPanel.Share": "Compartilhar",
|
||||
"ChannelIntro.CreateBoard": "Criar um board",
|
||||
"CloudMessage.cloud-server": "Obtenha seu próprio cloud server de graça.",
|
||||
"ColorOption.selectColor": "Selecione {color} Cor",
|
||||
"Comment.delete": "Excluir",
|
||||
"CommentsList.send": "Enviar",
|
||||
@@ -125,21 +130,23 @@
|
||||
"ContentBlock.checkbox": "caixa de seleção",
|
||||
"ContentBlock.divider": "Divisor",
|
||||
"ContentBlock.editCardCheckbox": "Caixa de seleção marcada",
|
||||
"ContentBlock.editCardCheckboxText": "editar texto do card",
|
||||
"ContentBlock.editCardText": "editar texto do card",
|
||||
"ContentBlock.editCardCheckboxText": "editar texto do cartão",
|
||||
"ContentBlock.editCardText": "editar texto do cartão",
|
||||
"ContentBlock.editText": "Editar texto...",
|
||||
"ContentBlock.image": "imagem",
|
||||
"ContentBlock.insertAbove": "Inserir acima",
|
||||
"ContentBlock.moveBlock": "mover conteúdo do cartão",
|
||||
"ContentBlock.moveDown": "Mover para baixo",
|
||||
"ContentBlock.moveUp": "Mover para cima",
|
||||
"ContentBlock.text": "texto",
|
||||
"DateFilter.empty": "Vazio",
|
||||
"DateRange.clear": "Limpar",
|
||||
"DateRange.empty": "Vazio",
|
||||
"DateRange.endDate": "data de término",
|
||||
"DateRange.today": "Hoje",
|
||||
"DeleteBoardDialog.confirm-cancel": "Cancelar",
|
||||
"DeleteBoardDialog.confirm-delete": "Excluir",
|
||||
"DeleteBoardDialog.confirm-info": "Tem certeza que você quer deletar um board \"{boardTitle}\"? Excluir irá apagar todos os cards no board.",
|
||||
"DeleteBoardDialog.confirm-info": "Tem certeza que quer excluir o quadro \"{boardTitle}\"? Excluí-lo irá apagar todos os cartões no quadro.",
|
||||
"DeleteBoardDialog.confirm-info-template": "Tem certeza que deseja excluir o board template “{boardTitle}”?",
|
||||
"DeleteBoardDialog.confirm-tite": "Confirmar exclusão do board",
|
||||
"DeleteBoardDialog.confirm-tite-template": "Confirmar exclusão do template de board",
|
||||
@@ -151,10 +158,14 @@
|
||||
"Filter.ends-with": "termina com",
|
||||
"Filter.includes": "Inclui",
|
||||
"Filter.is": "é",
|
||||
"Filter.is-after": "está depois",
|
||||
"Filter.is-before": "está antes",
|
||||
"Filter.is-empty": "está vazio",
|
||||
"Filter.is-not-empty": "Não está vazio",
|
||||
"Filter.is-not-set": "não está definido",
|
||||
"Filter.is-set": "está definido",
|
||||
"Filter.isafter": "está depois",
|
||||
"Filter.isbefore": "está antes",
|
||||
"Filter.not-contains": "não contém",
|
||||
"Filter.not-ends-with": "não termina com",
|
||||
"Filter.not-includes": "Não inclui",
|
||||
@@ -163,6 +174,7 @@
|
||||
"FilterByText.placeholder": "filtrar texto",
|
||||
"FilterComponent.add-filter": "+ Adicionar filtro",
|
||||
"FilterComponent.delete": "Excluir",
|
||||
"FilterValue.empty": "(vazio)",
|
||||
"FindBoardsDialog.IntroText": "Procurar por quadros",
|
||||
"FindBoardsDialog.NoResultsFor": "Sem resultado para \"{searchQuery}\"",
|
||||
"FindBoardsDialog.NoResultsSubtext": "Verifique a digitação ou tente outra busca.",
|
||||
@@ -175,20 +187,20 @@
|
||||
"KanbanCard.untitled": "Sem nome",
|
||||
"MentionSuggestion.is-not-board-member": "(não membro do board)",
|
||||
"Mutator.new-board-from-template": "novo board do template",
|
||||
"Mutator.new-card-from-template": "novo card à partir de um template",
|
||||
"Mutator.new-template-from-card": "novo template à partir de um card",
|
||||
"Mutator.new-card-from-template": "novo cartão à partir de um template",
|
||||
"Mutator.new-template-from-card": "novo template à partir de um cartão",
|
||||
"OnboardingTour.AddComments.Body": "Você pode comentar questões, e até mesmo @mencionar seus usuários companheiros de Mattermost para conseguir suas atenções.",
|
||||
"OnboardingTour.AddComments.Title": "Adicionar comentários",
|
||||
"OnboardingTour.AddDescription.Body": "Adicione uma descrição para que seus companheiros de time saibam sobre o que é o cartão.",
|
||||
"OnboardingTour.AddDescription.Title": "Adicionar descrição",
|
||||
"OnboardingTour.AddProperties.Body": "Adicione várias propriedades aos cartões para torna-los mais poderosos!",
|
||||
"OnboardingTour.AddProperties.Body": "Adicione várias propriedades aos cartões para torná-los mais poderosos.",
|
||||
"OnboardingTour.AddProperties.Title": "Adicionar propriedades",
|
||||
"OnboardingTour.AddView.Body": "Crie uma nova view aquei para organizar seu board usando diferentes layouts.",
|
||||
"OnboardingTour.AddView.Title": "Adicionar nova visualização",
|
||||
"OnboardingTour.CopyLink.Body": "Você pode compartilhar seus cartões com companheiros de times copiando e colando o link em um canal, mensagem direta, ou mensagem de grupo.",
|
||||
"OnboardingTour.CopyLink.Title": "Copiar link",
|
||||
"OnboardingTour.OpenACard.Body": "Abra um cartão para explorar formas poderosas que os Boards podem ajudar a organizar seu trabalho.",
|
||||
"OnboardingTour.OpenACard.Title": "Abrir um card",
|
||||
"OnboardingTour.OpenACard.Title": "Abrir um cartão",
|
||||
"OnboardingTour.ShareBoard.Body": "Você pode compartilhar seu board internament, com seu time, ou public para permitir visibilidade fora da sua organização.",
|
||||
"OnboardingTour.ShareBoard.Title": "Compartilhar quadro",
|
||||
"PersonProperty.board-members": "Membros do Board",
|
||||
@@ -248,6 +260,7 @@
|
||||
"Sidebar.invite-users": "Convidar usuários",
|
||||
"Sidebar.logout": "Sair",
|
||||
"Sidebar.new-category.badge": "Novo",
|
||||
"Sidebar.new-category.drag-boards-cta": "Solte quadros aqui...",
|
||||
"Sidebar.no-boards-in-category": "Nenhum board",
|
||||
"Sidebar.product-tour": "Tour pelo produto",
|
||||
"Sidebar.random-icons": "Ícones aleatórios",
|
||||
@@ -271,6 +284,7 @@
|
||||
"SidebarTour.SidebarCategories.Link": "Saiba mais",
|
||||
"SidebarTour.SidebarCategories.Title": "Categorias de barra lateral",
|
||||
"SiteStats.total_boards": "Total de boards",
|
||||
"SiteStats.total_cards": "Total de cartões",
|
||||
"TableComponent.add-icon": "Adicionar Ícone",
|
||||
"TableComponent.name": "Nome",
|
||||
"TableComponent.plus-new": "+ Novo",
|
||||
@@ -281,6 +295,7 @@
|
||||
"TableHeaderMenu.insert-right": "Inserir à direita",
|
||||
"TableHeaderMenu.sort-ascending": "Ordem ascendente",
|
||||
"TableHeaderMenu.sort-descending": "Ordem descendente",
|
||||
"TableRow.DuplicateCard": "duplicar cartão",
|
||||
"TableRow.MoreOption": "Mais ações",
|
||||
"TableRow.open": "Abrir",
|
||||
"TopBar.give-feedback": "Dar feedback",
|
||||
@@ -297,6 +312,7 @@
|
||||
"ValueSelector.valueSelector": "Selecionador de valor",
|
||||
"ValueSelectorLabel.openMenu": "Abrir menu",
|
||||
"VersionMessage.help": "Verifique o que é novo nesta versão.",
|
||||
"VersionMessage.learn-more": "Saiba mais",
|
||||
"View.AddView": "Adicionar visualização",
|
||||
"View.Board": "Quadro",
|
||||
"View.DeleteView": "Excluir visualização",
|
||||
@@ -313,7 +329,7 @@
|
||||
"ViewHeader.delete-template": "Excluir",
|
||||
"ViewHeader.display-by": "Exibir por: {property}",
|
||||
"ViewHeader.edit-template": "Editar",
|
||||
"ViewHeader.empty-card": "Card vazio",
|
||||
"ViewHeader.empty-card": "Cartão vazio",
|
||||
"ViewHeader.export-board-archive": "Exportar arquivo do painel",
|
||||
"ViewHeader.export-complete": "Exportação completa!",
|
||||
"ViewHeader.export-csv": "Exportar para CSV",
|
||||
@@ -323,7 +339,7 @@
|
||||
"ViewHeader.new": "Novo",
|
||||
"ViewHeader.properties": "Propriedades",
|
||||
"ViewHeader.properties-menu": "Menu de propriedades",
|
||||
"ViewHeader.search-text": "Pesquisar cards",
|
||||
"ViewHeader.search-text": "Pesquisar cartões",
|
||||
"ViewHeader.select-a-template": "Selecionar um modelo",
|
||||
"ViewHeader.set-default-template": "Definir como padrão",
|
||||
"ViewHeader.sort": "Ordenar",
|
||||
@@ -333,9 +349,9 @@
|
||||
"ViewLimitDialog.Heading": "Limite de views por board alcaçado",
|
||||
"ViewLimitDialog.PrimaryButton.Title.Admin": "Upgrade",
|
||||
"ViewLimitDialog.PrimaryButton.Title.RegularUser": "Notificar Admin",
|
||||
"ViewLimitDialog.Subtext.Admin": "Atualize para nosso plano Profissional ou Enterprise para ter visualizações ilimitados por boards, cards ilimitados e mais.",
|
||||
"ViewLimitDialog.Subtext.Admin": "Atualize para nosso plano Profissional ou Enterprise.",
|
||||
"ViewLimitDialog.Subtext.Admin.PricingPageLink": "Saiba mais sobre nossos planos.",
|
||||
"ViewLimitDialog.Subtext.RegularUser": "Nofique seu Admin para atualizar para nosso plano Professional ou Enterprise para ter visualizações ilimitadas, cards ilimitados e mais.",
|
||||
"ViewLimitDialog.Subtext.RegularUser": "Notifique seu administrador para atualizar para nosso plano Professional ou Enterprise.",
|
||||
"ViewLimitDialog.UpgradeImg.AltText": "Atualizar imagem",
|
||||
"ViewLimitDialog.notifyAdmin.Success": "Seu administrador foi notificado",
|
||||
"ViewTitle.hide-description": "esconder descrição",
|
||||
@@ -351,6 +367,9 @@
|
||||
"WelcomePage.StartUsingIt.Text": "Começar a usar",
|
||||
"Workspace.editing-board-template": "Você está editando um modelo de quadro.",
|
||||
"badge.guest": "Convidado",
|
||||
"boardPage.confirm-join-button": "Ingressar",
|
||||
"boardPage.confirm-join-text": "Você está prestes a ingressar em um board privado sem ter sido explicitamente adicionado pelo administrador do quadro. Você tem certeza de que deseja ingressar neste board privado?",
|
||||
"boardPage.confirm-join-title": "Ingressar board privado",
|
||||
"boardSelector.confirm-link-board": "Linkar board para canal",
|
||||
"boardSelector.confirm-link-board-button": "Sim, linkar board",
|
||||
"boardSelector.confirm-link-board-subtext": "Quando você vincula \"{boardName}\" a um canal, todos os membros daquele canal (existentes e novos) poderão editá-lo. Isto excluirá os membros que são convidados. Você pode desvincular um board de um canal a qualquer hora.",
|
||||
@@ -363,12 +382,13 @@
|
||||
"calendar.month": "Mês",
|
||||
"calendar.today": "HOJE",
|
||||
"calendar.week": "Semana",
|
||||
"centerPanel.undefined": "Sem {propertyName}",
|
||||
"centerPanel.unknown-user": "Usuário desconhecido",
|
||||
"cloudMessage.learn-more": "Saiba mais",
|
||||
"createImageBlock.failed": "Não foi possível enviar o arquivo. Limite de tamanho alcançado.",
|
||||
"createImageBlock.failed": "Não foi possível enviar o arquivo, pois o tamanho ultrapassou o limite permitido.",
|
||||
"default-properties.badges": "Comentários e descrição",
|
||||
"default-properties.title": "Título",
|
||||
"error.back-to-home": "Volta para Home",
|
||||
"error.back-to-home": "Volta para o início",
|
||||
"error.back-to-team": "Volta para o time",
|
||||
"error.board-not-found": "Quadro não encontrado.",
|
||||
"error.go-login": "Log in",
|
||||
@@ -380,31 +400,34 @@
|
||||
"generic.previous": "Anterior",
|
||||
"guest-no-board.subtitle": "Você não tem acesso a nenhum board neste time ainda, por favor aguarde até alguém adicionar você a algum board.",
|
||||
"guest-no-board.title": "Nenhum board ainda",
|
||||
"imagePaste.upload-failed": "Alguns arquivos não foram enviados. Tamanho limite alcançado",
|
||||
"limitedCard.title": "Cards ocultos",
|
||||
"imagePaste.upload-failed": "Alguns arquivos não foram enviados, pois o tamanho ultrapassou o limite permitido.",
|
||||
"limitedCard.title": "Cartões ocultos",
|
||||
"login.log-in-button": "Entrar",
|
||||
"login.log-in-title": "Entrar",
|
||||
"login.register-button": "ou criar uma conta se você ainda não tiver uma",
|
||||
"new_channel_modal.create_board.empty_board_description": "Criar um novo quadro vazio",
|
||||
"new_channel_modal.create_board.empty_board_title": "Quadro vazio",
|
||||
"new_channel_modal.create_board.select_template_placeholder": "Selecionar um modelo",
|
||||
"new_channel_modal.create_board.title": "Criar um quadro para este canal",
|
||||
"notification-box-card-limit-reached.close-tooltip": "Soneca por 10 dias",
|
||||
"notification-box-card-limit-reached.contact-link": "notificar seu admin",
|
||||
"notification-box-card-limit-reached.link": "Atualizar para um plano pago",
|
||||
"notification-box-card-limit-reached.title": "{cards} cards ocultos do board",
|
||||
"notification-box-cards-hidden.title": "Esta ação ocultou outro card",
|
||||
"notification-box-card-limit-reached.title": "{cards} cartões ocultos do board",
|
||||
"notification-box-cards-hidden.title": "Esta ação ocultou outro cartão",
|
||||
"notification-box.card-limit-reached.not-admin.text": "Para acessar cartões arquivados, você pode {contactLink} para atualizar para um plano pago.",
|
||||
"notification-box.card-limit-reached.text": "Limite de cartão alcançado, para visualizar cartões mais antigos, {link}",
|
||||
"person.add-user-to-board": "Adicionar {username} ao board",
|
||||
"person.add-user-to-board-confirm-button": "Adicionar ao board",
|
||||
"person.add-user-to-board-permissions": "Permissões",
|
||||
"person.add-user-to-board-question": "Você quer adicionar {username} ao board?",
|
||||
"person.add-user-to-board-warning": "{username} não é um membro de um board, e não será notificado.",
|
||||
"person.add-user-to-board-warning": "{username} não é um membro do quadro e não receberá nenhuma notificação sobre ele.",
|
||||
"register.login-button": "ou entre se você já tem uma conta",
|
||||
"register.signup-title": "Registrar uma conta",
|
||||
"rhs-board-non-admin-msg": "Você não é admin de um board",
|
||||
"rhs-board-non-admin-msg": "Você não é um adminstrador do quadro",
|
||||
"rhs-boards.add": "Adicionar",
|
||||
"rhs-boards.dm": "DM",
|
||||
"rhs-boards.gm": "GM",
|
||||
"rhs-boards.header.dm": "esta Direct Message",
|
||||
"rhs-boards.header.dm": "esta mensagem direta",
|
||||
"rhs-boards.header.gm": "esta mensagem de grupo",
|
||||
"rhs-boards.last-update-at": "Última atualização em: {datetime}",
|
||||
"rhs-boards.link-boards-to-channel": "Vincular boards para {channelName}",
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
"CenterPanel.Login": "Логин",
|
||||
"CenterPanel.Share": "Поделиться",
|
||||
"ChannelIntro.CreateBoard": "Создать доску",
|
||||
"CloudMessage.cloud-server": "Получите свой бесплатный облачный сервер.",
|
||||
"ColorOption.selectColor": "Выберите цвет {color}",
|
||||
"Comment.delete": "Удалить",
|
||||
"CommentsList.send": "Отправить",
|
||||
|
||||
@@ -113,7 +113,6 @@
|
||||
"CenterPanel.Login": "Prihlásiť sa",
|
||||
"CenterPanel.Share": "Zdieľať",
|
||||
"ChannelIntro.CreateBoard": "Vytvoriť nástenku",
|
||||
"CloudMessage.cloud-server": "Získajte vlastný cloudový server zadarmo.",
|
||||
"ColorOption.selectColor": "Vyberte {color} farbu",
|
||||
"Comment.delete": "Odstrániť",
|
||||
"CommentsList.send": "Odoslať",
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
"CenterPanel.Login": "Logga in",
|
||||
"CenterPanel.Share": "Dela",
|
||||
"ChannelIntro.CreateBoard": "Skapa en board",
|
||||
"CloudMessage.cloud-server": "Skaffa din egen molnserver gratis.",
|
||||
"ColorOption.selectColor": "Välj {color} färg",
|
||||
"Comment.delete": "Radera",
|
||||
"CommentsList.send": "Skicka",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"AdminBadge.SystemAdmin": "Yönetici",
|
||||
"AdminBadge.TeamAdmin": "Takım yöneticisi",
|
||||
"AppBar.Tooltip": "Bağlantılı panoları aç/kapat",
|
||||
"Attachment.Attachment-title": "Ek dosya",
|
||||
"AttachmentBlock.DeleteAction": "sil",
|
||||
@@ -115,7 +117,6 @@
|
||||
"CenterPanel.Login": "Oturum aç",
|
||||
"CenterPanel.Share": "Paylaş",
|
||||
"ChannelIntro.CreateBoard": "Bir pano ekle",
|
||||
"CloudMessage.cloud-server": "Kendi ücretsiz bulut sunucunuzu edinin.",
|
||||
"ColorOption.selectColor": "{color} rengi seçin",
|
||||
"Comment.delete": "Sil",
|
||||
"CommentsList.send": "Gönder",
|
||||
@@ -138,6 +139,7 @@
|
||||
"ContentBlock.moveDown": "Alta taşı",
|
||||
"ContentBlock.moveUp": "Üste taşı",
|
||||
"ContentBlock.text": "metin",
|
||||
"DateFilter.empty": "Boş",
|
||||
"DateRange.clear": "Temizle",
|
||||
"DateRange.empty": "Boş",
|
||||
"DateRange.endDate": "Bitiş tarihi",
|
||||
@@ -156,10 +158,14 @@
|
||||
"Filter.ends-with": "şununla biten",
|
||||
"Filter.includes": "şunu içeren",
|
||||
"Filter.is": "şu olan",
|
||||
"Filter.is-after": "şundan sonra",
|
||||
"Filter.is-before": "şundan önce",
|
||||
"Filter.is-empty": "boş olan",
|
||||
"Filter.is-not-empty": "boş olmayan",
|
||||
"Filter.is-not-set": "şuna ayarlanmamış olan",
|
||||
"Filter.is-set": "şuna ayarlanmış olan",
|
||||
"Filter.isafter": "şundan sonra",
|
||||
"Filter.isbefore": "şundan önce",
|
||||
"Filter.not-contains": "şunu içermeyen",
|
||||
"Filter.not-ends-with": "şununla bitmeyen",
|
||||
"Filter.not-includes": "şunu içermeyen",
|
||||
@@ -221,7 +227,7 @@
|
||||
"PropertyType.UpdatedTime": "Son güncelleme zamanı",
|
||||
"PropertyType.Url": "Adres",
|
||||
"PropertyValueElement.empty": "Boş",
|
||||
"RegistrationLink.confirmRegenerateToken": "Bu işlem daha önce paylaşılmış bağlantıları geçersiz kılacak. Devam etmek istiyor musunuz?",
|
||||
"RegistrationLink.confirmRegenerateToken": "Bu işlem daha önce paylaşılmış bağlantıları geçersiz kılacak. İlerlemek istiyor musunuz?",
|
||||
"RegistrationLink.copiedLink": "Kopyalandı!",
|
||||
"RegistrationLink.copyLink": "Bağlantıyı kopyala",
|
||||
"RegistrationLink.description": "Başkalarının hesap ekleyebilmesi için bu bağlantıyı paylaş:",
|
||||
@@ -232,7 +238,7 @@
|
||||
"ShareBoard.ShareInternal": "İçeride paylaş",
|
||||
"ShareBoard.ShareInternalDescription": "İzni olan kullanıcılar bu bağlantıyı kullanabilecek.",
|
||||
"ShareBoard.Title": "Panoyu paylaş",
|
||||
"ShareBoard.confirmRegenerateToken": "Bu işlem daha önce paylaşılmış bağlantıları geçersiz kılacak. Devam etmek istiyor musunuz?",
|
||||
"ShareBoard.confirmRegenerateToken": "Bu işlem daha önce paylaşılmış bağlantıları geçersiz kılacak. İlerlemek istiyor musunuz?",
|
||||
"ShareBoard.copiedLink": "Kopyalandı!",
|
||||
"ShareBoard.copyLink": "Bağlantıyı kopyala",
|
||||
"ShareBoard.regenerate": "Kodu yeniden oluştur",
|
||||
@@ -306,6 +312,7 @@
|
||||
"ValueSelector.valueSelector": "Değer seçici",
|
||||
"ValueSelectorLabel.openMenu": "Menüyü aç",
|
||||
"VersionMessage.help": "Bu sürümdeki yeniliklere bakın.",
|
||||
"VersionMessage.learn-more": "Ayrıntılı bilgi alın",
|
||||
"View.AddView": "Görünüm ekle",
|
||||
"View.Board": "Pano",
|
||||
"View.DeleteView": "Görünümü sil",
|
||||
@@ -360,6 +367,9 @@
|
||||
"WelcomePage.StartUsingIt.Text": "Kullanmaya başlayın",
|
||||
"Workspace.editing-board-template": "Bir pano kalıbını düzenliyorsunuz.",
|
||||
"badge.guest": "Konuk",
|
||||
"boardPage.confirm-join-button": "Katıl",
|
||||
"boardPage.confirm-join-text": "Bir özel kanala, pano yöneticisi tarafından açıkça eklenmeden katılmak üzeresiniz. Bu özel kanala katılmak istediğinize emin misiniz?",
|
||||
"boardPage.confirm-join-title": "Özel kanala katıl",
|
||||
"boardSelector.confirm-link-board": "Panoyu kanala bağla",
|
||||
"boardSelector.confirm-link-board-button": "Evet, panoyu bağla",
|
||||
"boardSelector.confirm-link-board-subtext": "\"{boardName}\" panosunu kanala bağladığınızda, kanalın tüm üyeleri (var olan ve yeni) panoyu düzenleyebilir. Bu işlem konuk üyeleri kaldırır. Bir pano ile bir kanalın bağlantısını istediğiniz zaman kaldırabilirsiniz.",
|
||||
@@ -395,6 +405,10 @@
|
||||
"login.log-in-button": "Oturum aç",
|
||||
"login.log-in-title": "Oturum açın",
|
||||
"login.register-button": "ya da hesabınız yoksa bir hesap açın",
|
||||
"new_channel_modal.create_board.empty_board_description": "Yeni boş bir pano oluştur",
|
||||
"new_channel_modal.create_board.empty_board_title": "Boş pano",
|
||||
"new_channel_modal.create_board.select_template_placeholder": "Bir kalıp seçin",
|
||||
"new_channel_modal.create_board.title": "Bu kanal için bir pano oluştur",
|
||||
"notification-box-card-limit-reached.close-tooltip": "10 gün için sustur",
|
||||
"notification-box-card-limit-reached.contact-link": "yöneticinizi bilgilendirin",
|
||||
"notification-box-card-limit-reached.link": "Ücretli bir tarifeye geçin",
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
"CenterPanel.Login": "Логін",
|
||||
"CenterPanel.Share": "Поділитися",
|
||||
"ChannelIntro.CreateBoard": "Створити дошку",
|
||||
"CloudMessage.cloud-server": "Отримайте власний безкоштовний хмарний сервер.",
|
||||
"ColorOption.selectColor": "Виберіть колір {color}",
|
||||
"Comment.delete": "Видалити",
|
||||
"CommentsList.send": "Надіслати",
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
"CenterPanel.Login": "登录",
|
||||
"CenterPanel.Share": "分享",
|
||||
"ChannelIntro.CreateBoard": "创建一个板块",
|
||||
"CloudMessage.cloud-server": "获得自己的免费云服务器。",
|
||||
"ColorOption.selectColor": "选择{color}",
|
||||
"Comment.delete": "删除",
|
||||
"CommentsList.send": "发送",
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
"CenterPanel.Login": "登入",
|
||||
"CenterPanel.Share": "分享",
|
||||
"ChannelIntro.CreateBoard": "建立看板",
|
||||
"CloudMessage.cloud-server": "獲得免費的雲端伺服器.",
|
||||
"ColorOption.selectColor": "{color} 選擇顏色",
|
||||
"Comment.delete": "刪除",
|
||||
"CommentsList.send": "發送",
|
||||
|
||||
@@ -102,12 +102,11 @@
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/react-transition-group": "4.4.4",
|
||||
"@types/redux-mock-store": "1.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "5.16.0",
|
||||
"@typescript-eslint/parser": "5.16.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.57.1",
|
||||
"@typescript-eslint/parser": "5.57.1",
|
||||
"babel-eslint": "10.1.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "6.7.1",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint-import-resolver-webpack": "0.13.2",
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-formatjs": "4.9.0",
|
||||
|
||||
@@ -873,7 +873,7 @@ exports[`src/components/workspace return workspace readonly and showcard 1`] = `
|
||||
>
|
||||
<div
|
||||
class="octo-board-header-cell KanbanColumnHeader"
|
||||
draggable="true"
|
||||
draggable="false"
|
||||
style="opacity: 1;"
|
||||
>
|
||||
<span
|
||||
@@ -901,7 +901,7 @@ exports[`src/components/workspace return workspace readonly and showcard 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="octo-board-header-cell KanbanColumnHeader"
|
||||
draggable="true"
|
||||
draggable="false"
|
||||
style="opacity: 1;"
|
||||
>
|
||||
<span
|
||||
@@ -1927,7 +1927,7 @@ exports[`src/components/workspace should match snapshot with readonly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="octo-board-header-cell KanbanColumnHeader"
|
||||
draggable="true"
|
||||
draggable="false"
|
||||
style="opacity: 1;"
|
||||
>
|
||||
<span
|
||||
@@ -1955,7 +1955,7 @@ exports[`src/components/workspace should match snapshot with readonly 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="octo-board-header-cell KanbanColumnHeader"
|
||||
draggable="true"
|
||||
draggable="false"
|
||||
style="opacity: 1;"
|
||||
>
|
||||
<span
|
||||
|
||||
@@ -206,7 +206,7 @@ const BoardTemplateSelector = (props: Props) => {
|
||||
>
|
||||
<FormattedMessage
|
||||
id='BoardTemplateSelector.create-empty-board'
|
||||
defaultMessage='Create empty board'
|
||||
defaultMessage='Create an empty board'
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -91,7 +91,7 @@ const BoardsSwitcher = (props: Props): JSX.Element => {
|
||||
<Search/>
|
||||
<div>
|
||||
<span>
|
||||
{intl.formatMessage({id: 'BoardsSwitcher.Title', defaultMessage: 'Find Boards'})}
|
||||
{intl.formatMessage({id: 'BoardsSwitcher.Title', defaultMessage: 'Find boards'})}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -147,7 +147,7 @@ const CalendarFullView = (props: Props): JSX.Element|null => {
|
||||
|
||||
const confirmDialogProps: ConfirmationDialogBoxProps = useMemo(() => {
|
||||
return {
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete!'}),
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete'}),
|
||||
confirmButtonText: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-button-text', defaultMessage: 'Delete'}),
|
||||
onConfirm: handleDeleteCard,
|
||||
onClose: () => {
|
||||
|
||||
@@ -255,7 +255,7 @@ const CardDetail = (props: Props): JSX.Element|null => {
|
||||
<p className='CardDetail__limited-body'>
|
||||
<FormattedMessage
|
||||
id='CardDetail.limited-body'
|
||||
defaultMessage='Upgrade to our Professional or Enterprise plan to view archived cards, have unlimited views per boards, unlimited cards and more.'
|
||||
defaultMessage='Upgrade to our Professional or Enterprise plan.'
|
||||
/>
|
||||
<br/>
|
||||
<a
|
||||
@@ -362,7 +362,7 @@ const CardDetail = (props: Props): JSX.Element|null => {
|
||||
newBlock.title = block.value.value
|
||||
newBlock.fields = {...newBlock.fields, value: block.value.checked}
|
||||
}
|
||||
mutator.updateBlock(card.boardId, newBlock, originalContentBlock, intl.formatMessage({id: 'ContentBlock.editCardText', defaultMessage: 'edit card content'}))
|
||||
mutator.updateBlock(card.boardId, newBlock, originalContentBlock, intl.formatMessage({id: 'ContentBlock.editCardText', defaultMessage: 'edit card text'}))
|
||||
return block
|
||||
}}
|
||||
onBlockMoved={async (block: BlockData, beforeBlock: BlockData|null, afterBlock: BlockData|null): Promise<void> => {
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function useImagePaste(boardId: string, cardId: string, contentOr
|
||||
}
|
||||
|
||||
if (someFilesNotUploaded) {
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'imagePaste.upload-failed', defaultMessage: 'Some files not uploaded. File size limit reached'}), severity: 'normal'})
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'imagePaste.upload-failed', defaultMessage: "Some files weren't uploaded because the file size limit has been reached."}), severity: 'normal'})
|
||||
}
|
||||
|
||||
const afterRedo = async (newBlocks: Block[]) => {
|
||||
|
||||
@@ -97,7 +97,7 @@ const CardDialog = (props: Props): JSX.Element => {
|
||||
}
|
||||
|
||||
const confirmDialogProps: ConfirmationDialogBoxProps = {
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete!'}),
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete'}),
|
||||
confirmButtonText: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-button-text', defaultMessage: 'Delete'}),
|
||||
onConfirm: handleDeleteCard,
|
||||
onClose: () => {
|
||||
@@ -161,7 +161,7 @@ const CardDialog = (props: Props): JSX.Element => {
|
||||
dispatch(updateAttachments([attachmentBlock]))
|
||||
if (attachment.size > clientConfig.maxFileSize) {
|
||||
removeUploadingAttachment(uploadingBlock)
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.failed', defaultMessage: 'Unable to upload the file. Attachment size limit reached.'}), severity: 'normal'})
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.failed', defaultMessage: "This file couldn't be uploaded as the file size limit has been reached."}), severity: 'normal'})
|
||||
} else {
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.upload', defaultMessage: 'Attachment uploading.'}), severity: 'normal'})
|
||||
const xhr = await octoClient.uploadAttachment(boardId, attachment)
|
||||
@@ -183,11 +183,11 @@ const CardDialog = (props: Props): JSX.Element => {
|
||||
const block = createAttachmentBlock()
|
||||
block.fields.attachmentId = attachmentId || ''
|
||||
block.title = attachment.name
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.uploadSuccess', defaultMessage: 'Attachment uploaded successfull.'}), severity: 'normal'})
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.uploadSuccess', defaultMessage: 'Attachment uploaded.'}), severity: 'normal'})
|
||||
resolve(block)
|
||||
} else {
|
||||
removeUploadingAttachment(uploadingBlock)
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.failed', defaultMessage: 'Unable to upload the file. Attachment size limit reached.'}), severity: 'normal'})
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.failed', defaultMessage: "This file couldn't be uploaded as the file size limit has been reached."}), severity: 'normal'})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,7 +217,7 @@ const CardDialog = (props: Props): JSX.Element => {
|
||||
}
|
||||
const description = intl.formatMessage({id: 'AttachmentBlock.DeleteAction', defaultMessage: 'delete'})
|
||||
await mutator.deleteBlock(block, description)
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.delete', defaultMessage: 'Attachment Deleted Successfully.'}), severity: 'normal'})
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'AttachmentBlock.delete', defaultMessage: 'Attachment deleted.'}), severity: 'normal'})
|
||||
}, [card?.boardId, card?.id, card?.fields.contentOrder])
|
||||
|
||||
const attachBtn = (): React.ReactNode => {
|
||||
|
||||
@@ -29,7 +29,14 @@ jest.mock('react-router-dom', () => {
|
||||
return {
|
||||
...originalModule,
|
||||
useRouteMatch: jest.fn(() => {
|
||||
return {url: '/board/view'}
|
||||
return {
|
||||
params: {
|
||||
teamId: 'team1',
|
||||
boardId: 'boardId1',
|
||||
viewId: 'viewId1',
|
||||
cardId: 'cardId1',
|
||||
},
|
||||
}
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -76,7 +76,7 @@ const ConfirmAddUserForNotifications = (props: Props): JSX.Element => {
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='person.add-user-to-board-warning'
|
||||
defaultMessage='{username} is not a member of the board, and will not receive any notifications about it.'
|
||||
defaultMessage="{username} isn't a member of the board, and won't receive any notifications about it."
|
||||
values={{username: props.user.username}}
|
||||
/>
|
||||
</p>
|
||||
|
||||
@@ -94,7 +94,7 @@ const AttachmentElement = (props: Props): JSX.Element|null => {
|
||||
}
|
||||
|
||||
const confirmDialogProps: ConfirmationDialogBoxProps = {
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-attachment', defaultMessage: 'Confirm Attachment delete!'}),
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-attachment', defaultMessage: 'Confirm attachment delete'}),
|
||||
confirmButtonText: intl.formatMessage({id: 'AttachmentElement.delete-confirmation-dialog-button-text', defaultMessage: 'Delete'}),
|
||||
onConfirm: deleteAttachment,
|
||||
onClose: () => {
|
||||
|
||||
@@ -70,7 +70,7 @@ contentRegistry.registerContentType({
|
||||
block.fields.fileId = fileId || ''
|
||||
resolve(block)
|
||||
} else {
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'createImageBlock.failed', defaultMessage: 'Unable to upload the file. File size limit reached.'}), severity: 'normal'})
|
||||
sendFlashMessage({content: intl.formatMessage({id: 'createImageBlock.failed', defaultMessage: "This file couldn't be uploaded as the file size limit has been reached."}), severity: 'normal'})
|
||||
}
|
||||
},
|
||||
'.jpg,.jpeg,.png,.gif')
|
||||
|
||||
@@ -51,7 +51,7 @@ const GalleryCard = (props: Props) => {
|
||||
|
||||
const confirmDialogProps: ConfirmationDialogBoxProps = useMemo(() => {
|
||||
return {
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete!'}),
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete'}),
|
||||
confirmButtonText: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-button-text', defaultMessage: 'Delete'}),
|
||||
onConfirm: handleDeleteCard,
|
||||
onClose: () => {
|
||||
|
||||
@@ -469,7 +469,7 @@ exports[`src/components/kanban/kanbanColumnHeader should match snapshot readonly
|
||||
<div>
|
||||
<div
|
||||
class="octo-board-header-cell KanbanColumnHeader"
|
||||
draggable="true"
|
||||
draggable="false"
|
||||
style="opacity: 1;"
|
||||
>
|
||||
<span
|
||||
|
||||
@@ -59,7 +59,7 @@ const KanbanCard = (props: Props) => {
|
||||
|
||||
const confirmDialogProps: ConfirmationDialogBoxProps = useMemo(() => {
|
||||
return {
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete!'}),
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete'}),
|
||||
confirmButtonText: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-button-text', defaultMessage: 'Delete'}),
|
||||
onConfirm: handleDeleteCard,
|
||||
onClose: () => {
|
||||
|
||||
@@ -52,8 +52,12 @@ const defaultProperty: IPropertyTemplate = {
|
||||
export default function KanbanColumnHeader(props: Props): JSX.Element {
|
||||
const intl = useIntl()
|
||||
const {board, activeView, group, groupByProperty} = props
|
||||
let readonly = props.readonly
|
||||
if(!readonly){
|
||||
readonly = !useHasCurrentBoardPermissions([Permission.ManageBoardProperties])
|
||||
}
|
||||
|
||||
const [groupTitle, setGroupTitle] = useState(group.option.value)
|
||||
const canEditBoardProperties = useHasCurrentBoardPermissions([Permission.ManageBoardProperties])
|
||||
const canEditOption = groupByProperty?.type !== 'person' && group.option.id
|
||||
|
||||
const headerRef = useRef<HTMLDivElement>(null)
|
||||
@@ -79,7 +83,7 @@ export default function KanbanColumnHeader(props: Props): JSX.Element {
|
||||
setGroupTitle(group.option.value)
|
||||
}, [group.option.value])
|
||||
|
||||
if (canEditBoardProperties) {
|
||||
if (!readonly) {
|
||||
drop(drag(headerRef))
|
||||
}
|
||||
|
||||
@@ -97,13 +101,13 @@ export default function KanbanColumnHeader(props: Props): JSX.Element {
|
||||
ref={headerRef}
|
||||
style={{opacity: isDragging ? 0.5 : 1}}
|
||||
className={className}
|
||||
draggable={!props.readonly && canEditBoardProperties}
|
||||
draggable={!readonly}
|
||||
>
|
||||
{!group.option.id &&
|
||||
<Label
|
||||
title={intl.formatMessage({
|
||||
id: 'BoardComponent.no-property-title',
|
||||
defaultMessage: 'Items with an empty {property} property will go here. This column cannot be removed.',
|
||||
defaultMessage: "Items with an empty {property} property will go here. This column can't be removed.",
|
||||
}, {property: groupByProperty!.name})}
|
||||
>
|
||||
<FormattedMessage
|
||||
@@ -133,7 +137,7 @@ export default function KanbanColumnHeader(props: Props): JSX.Element {
|
||||
onCancel={() => {
|
||||
setGroupTitle(group.option.value)
|
||||
}}
|
||||
readonly={props.readonly || !canEditBoardProperties}
|
||||
readonly={readonly}
|
||||
spellCheck={true}
|
||||
/>
|
||||
</Label>}
|
||||
@@ -145,7 +149,7 @@ export default function KanbanColumnHeader(props: Props): JSX.Element {
|
||||
onMenuClose={props.onCalculationMenuClose}
|
||||
onMenuOpen={props.onCalculationMenuOpen}
|
||||
cardProperties={board.cardProperties}
|
||||
readonly={props.readonly || !canEditBoardProperties}
|
||||
readonly={readonly}
|
||||
onChange={(data: {calculation: string, propertyId: string}) => {
|
||||
if (data.calculation === calculationValue && data.propertyId === calculationProperty.id) {
|
||||
return
|
||||
|
||||
@@ -40,7 +40,7 @@ const AddPropertiesTourStep = (): JSX.Element | null => {
|
||||
const screen = (
|
||||
<FormattedMessage
|
||||
id='OnboardingTour.AddProperties.Body'
|
||||
defaultMessage='Add various properties to cards to make them more powerful!'
|
||||
defaultMessage='Add various properties to cards to make them more powerful.'
|
||||
/>
|
||||
)
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ const RHSChannelBoardItem = (props: Props) => {
|
||||
onClick={() => {
|
||||
onUnlinkBoard(props.board)
|
||||
}}
|
||||
subText={intl.formatMessage({id: 'rhs-board-non-admin-msg', defaultMessage:'You are not an admin of the board'})}
|
||||
subText={intl.formatMessage({id: 'rhs-board-non-admin-msg', defaultMessage: "You're not an admin of the board"})}
|
||||
/>
|
||||
</BoardPermissionGate>
|
||||
</Menu>
|
||||
|
||||
@@ -92,10 +92,10 @@ const RHSChannelBoards = () => {
|
||||
|
||||
if (currentChannel.type === 'D') {
|
||||
channelName = intl.formatMessage({id: 'rhs-boards.dm', defaultMessage: 'DM'})
|
||||
headerChannelName = intl.formatMessage({id: 'rhs-boards.header.dm', defaultMessage: 'this Direct Message'})
|
||||
headerChannelName = intl.formatMessage({id: 'rhs-boards.header.dm', defaultMessage: 'this direct message'})
|
||||
} else if (currentChannel.type === 'G') {
|
||||
channelName = intl.formatMessage({id: 'rhs-boards.gm', defaultMessage: 'GM'})
|
||||
headerChannelName = intl.formatMessage({id: 'rhs-boards.header.gm', defaultMessage: 'this Group Message'})
|
||||
headerChannelName = intl.formatMessage({id: 'rhs-boards.header.gm', defaultMessage: 'this group message'})
|
||||
}
|
||||
|
||||
if (channelBoards.length === 0) {
|
||||
|
||||
@@ -983,11 +983,11 @@ exports[`src/components/shareBoard/shareBoard return shareBoard and click Regene
|
||||
>
|
||||
<a
|
||||
class="shareUrl"
|
||||
href="http://localhost:8065/team/team-id/shared/1/1?r=anotherToken"
|
||||
href="http://localhost:8065/boards/public/team/team-id/shared/1/1?r=anotherToken"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
http://localhost:8065/team/team-id/shared/1/1?r=anotherToken
|
||||
http://localhost:8065/boards/public/team/team-id/shared/1/1?r=anotherToken
|
||||
</a>
|
||||
<div
|
||||
class="octo-tooltip tooltip-top"
|
||||
@@ -3188,11 +3188,11 @@ exports[`src/components/shareBoard/shareBoard return shareBoard, and click switc
|
||||
>
|
||||
<a
|
||||
class="shareUrl"
|
||||
href="http://localhost:8065/team/team-id/shared/1/1?r=oneToken"
|
||||
href="http://localhost:8065/boards/public/team/team-id/shared/1/1?r=oneToken"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
http://localhost:8065/team/team-id/shared/1/1?r=oneToken
|
||||
http://localhost:8065/boards/public/team/team-id/shared/1/1?r=oneToken
|
||||
</a>
|
||||
<div
|
||||
class="octo-tooltip tooltip-top"
|
||||
@@ -3461,11 +3461,11 @@ exports[`src/components/shareBoard/shareBoard return shareBoardComponent and cli
|
||||
>
|
||||
<a
|
||||
class="shareUrl"
|
||||
href="http://localhost:8065/team/team-id/shared/1/1?r=aToken"
|
||||
href="http://localhost:8065/boards/public/team/team-id/shared/1/1?r=aToken"
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
http://localhost:8065/team/team-id/shared/1/1?r=aToken
|
||||
http://localhost:8065/boards/public/team/team-id/shared/1/1?r=aToken
|
||||
</a>
|
||||
<div
|
||||
class="octo-tooltip tooltip-top"
|
||||
|
||||
@@ -259,7 +259,7 @@ export default function ShareBoardDialog(props: Props): JSX.Element {
|
||||
viewId: match.params.viewId,
|
||||
teamId: match.params.teamId,
|
||||
})
|
||||
shareUrl.pathname = newPath
|
||||
shareUrl.pathname = `/boards/public${newPath}`
|
||||
|
||||
const boardPath = generatePath('/team/:teamId/:boardId/:viewId', {
|
||||
boardId: match.params.boardId,
|
||||
@@ -278,7 +278,7 @@ export default function ShareBoardDialog(props: Props): JSX.Element {
|
||||
const shareTemplateTitle = (
|
||||
<FormattedMessage
|
||||
id={'ShareTemplate.Title'}
|
||||
defaultMessage={'Share Template'}
|
||||
defaultMessage={'Share template'}
|
||||
/>
|
||||
)
|
||||
|
||||
|
||||
@@ -21,10 +21,12 @@ jest.mock('react-router-dom', () => {
|
||||
...originalModule,
|
||||
useRouteMatch: jest.fn(() => {
|
||||
return {
|
||||
teamId: 'team1',
|
||||
boardId: 'boardId1',
|
||||
viewId: 'viewId1',
|
||||
cardId: 'cardId1',
|
||||
params: {
|
||||
teamId: 'team1',
|
||||
boardId: 'boardId1',
|
||||
viewId: 'viewId1',
|
||||
cardId: 'cardId1',
|
||||
},
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import React, {useCallback} from 'react'
|
||||
import {FormattedMessage} from 'react-intl'
|
||||
import {generatePath, useRouteMatch, useHistory} from 'react-router-dom'
|
||||
import {generatePath, useRouteMatch} from 'react-router-dom'
|
||||
|
||||
import Button from 'src/widgets/buttons/button'
|
||||
import TelemetryClient, {TelemetryActions, TelemetryCategory} from 'src/telemetry/telemetryClient'
|
||||
@@ -12,14 +12,17 @@ import './shareBoardLoginButton.scss'
|
||||
|
||||
const ShareBoardLoginButton = () => {
|
||||
const match = useRouteMatch<{teamId: string, boardId: string, viewId?: string, cardId?: string}>()
|
||||
const history = useHistory()
|
||||
|
||||
const redirectQueryParam = 'r=' + encodeURIComponent(generatePath('/:boardId?/:viewId?/:cardId?', match.params))
|
||||
const loginPath = '/login?' + redirectQueryParam
|
||||
// Mattermost login doesn't respect the redirect query parameter
|
||||
// if the user is already logged in, so we send the user to the
|
||||
// board and if they are not logged in, the webapp will take care
|
||||
// of the redirection
|
||||
const baseURL = window.location.href.split('/boards/public')[0]
|
||||
const loginPath = `${baseURL}/${generatePath('/boards/team/:teamId/:boardId?/:viewId?/:cardId?', match.params)}`
|
||||
|
||||
const onLoginClick = useCallback(() => {
|
||||
TelemetryClient.trackEvent(TelemetryCategory, TelemetryActions.ShareBoardLogin)
|
||||
history.push(loginPath)
|
||||
location.assign(loginPath)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
||||
@@ -52,19 +52,22 @@ const TeamPermissionsRow = (): JSX.Element => {
|
||||
}
|
||||
}
|
||||
|
||||
let currentRoleName = intl.formatMessage({id: 'BoardMember.schemeNone', defaultMessage: 'None'})
|
||||
if (board.type === BoardTypeOpen && board.minimumRole === MemberRole.Admin) {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeAdmin', defaultMessage: 'Admin'})
|
||||
} else if (board.type === BoardTypeOpen && board.minimumRole === MemberRole.Editor) {
|
||||
if (board.isTemplate) {
|
||||
let currentRoleName = intl.formatMessage({id: 'BoardMember.schemeAdmin', defaultMessage: 'Admin'})
|
||||
if (board.type === BoardTypeOpen) {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeEditor', defaultMessage: 'Editor'})
|
||||
if (board.minimumRole === MemberRole.Editor) {
|
||||
if (board.isTemplate) {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeViewer', defaultMessage: 'Viewer'})
|
||||
} else {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeEditor', defaultMessage: 'Editor'})
|
||||
}
|
||||
} else if (board.minimumRole === MemberRole.Commenter) {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeCommenter', defaultMessage: 'Commenter'})
|
||||
} else if (board.minimumRole === MemberRole.Viewer) {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeViewer', defaultMessage: 'Viewer'})
|
||||
} else {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeEditor', defaultMessage: 'Editor'})
|
||||
}
|
||||
} else if (board.type === BoardTypeOpen && board.minimumRole === MemberRole.Commenter) {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeCommenter', defaultMessage: 'Commenter'})
|
||||
} else if (board.type === BoardTypeOpen && board.minimumRole === MemberRole.Viewer) {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeViewer', defaultMessage: 'Viewer'})
|
||||
} else {
|
||||
currentRoleName = intl.formatMessage({id: 'BoardMember.schemeNone', defaultMessage: 'None'})
|
||||
}
|
||||
|
||||
const confirmationDialog = (
|
||||
@@ -99,7 +102,7 @@ const TeamPermissionsRow = (): JSX.Element => {
|
||||
icon='mattermost'
|
||||
className='user-item__img'
|
||||
/>
|
||||
<div className='ml-3'><strong>{intl.formatMessage({id: 'ShareBoard.teamPermissionsText', defaultMessage: 'Everyone at {teamName} Team'}, {teamName: team?.title})}</strong></div>
|
||||
<div className='ml-3'><strong>{intl.formatMessage({id: 'ShareBoard.teamPermissionsText', defaultMessage: 'Everyone at {teamName} team'}, {teamName: team?.title})}</strong></div>
|
||||
</div>
|
||||
<div>
|
||||
<BoardPermissionGate permissions={[Permission.ManageBoardType]}>
|
||||
|
||||
@@ -86,7 +86,7 @@ const TableGroupHeaderRow = (props: Props): JSX.Element => {
|
||||
<Label
|
||||
title={intl.formatMessage({
|
||||
id: 'BoardComponent.no-property-title',
|
||||
defaultMessage: 'Items with an empty {property} property will go here. This column cannot be removed.',
|
||||
defaultMessage: "Items with an empty {property} property will go here. This column can't be removed.",
|
||||
}, {property: groupByProperty?.name})}
|
||||
>
|
||||
<FormattedMessage
|
||||
|
||||
@@ -131,7 +131,7 @@ const TableRow = (props: Props) => {
|
||||
|
||||
const confirmDialogProps: ConfirmationDialogBoxProps = useMemo(() => {
|
||||
return {
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete!'}),
|
||||
heading: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-heading', defaultMessage: 'Confirm card delete'}),
|
||||
confirmButtonText: intl.formatMessage({id: 'CardDialog.delete-confirmation-dialog-button-text', defaultMessage: 'Delete'}),
|
||||
onConfirm: handleDeleteCard,
|
||||
onClose: () => {
|
||||
|
||||
@@ -59,9 +59,12 @@ const ViewHeader = (props: Props) => {
|
||||
const [showFilter, setShowFilter] = useState(false)
|
||||
const [lockFilterOnClose, setLockFilterOnClose] = useState(false)
|
||||
const intl = useIntl()
|
||||
const canEditBoardProperties = useHasCurrentBoardPermissions([Permission.ManageBoardProperties])
|
||||
|
||||
const {board, activeView, views, groupByProperty, cards, dateDisplayProperty} = props
|
||||
let readonly = props.readonly
|
||||
if(!readonly){
|
||||
readonly = !useHasCurrentBoardPermissions([Permission.ManageBoardProperties])
|
||||
}
|
||||
|
||||
const withGroupBy = activeView.fields.viewType === 'board' || activeView.fields.viewType === 'table'
|
||||
const withDisplayBy = activeView.fields.viewType === 'calendar'
|
||||
@@ -137,7 +140,7 @@ const ViewHeader = (props: Props) => {
|
||||
}}
|
||||
onChange={setViewTitle}
|
||||
saveOnEsc={true}
|
||||
readonly={props.readonly || !canEditBoardProperties}
|
||||
readonly={readonly}
|
||||
spellCheck={true}
|
||||
autoExpand={false}
|
||||
/>
|
||||
@@ -148,7 +151,7 @@ const ViewHeader = (props: Props) => {
|
||||
board={board}
|
||||
activeView={activeView}
|
||||
views={views}
|
||||
readonly={props.readonly || !canEditBoardProperties}
|
||||
readonly={readonly}
|
||||
allowCreateView={allowCreateView}
|
||||
/>
|
||||
</MenuWrapper>
|
||||
@@ -159,7 +162,7 @@ const ViewHeader = (props: Props) => {
|
||||
|
||||
<div className='octo-spacer'/>
|
||||
|
||||
{!props.readonly && canEditBoardProperties &&
|
||||
{!readonly &&
|
||||
<>
|
||||
{/* Card properties */}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ export const ViewLimitModal = (props: Props): JSX.Element => {
|
||||
const regularUserSubtext = (
|
||||
<FormattedMessage
|
||||
id='ViewLimitDialog.Subtext.RegularUser'
|
||||
defaultMessage='Notify your Admin to upgrade to our Professional or Enterprise plan to have unlimited views per boards, unlimited cards, and more.'
|
||||
defaultMessage='Notify your Admin to upgrade to our Professional or Enterprise plan.'
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -56,7 +56,7 @@ export const ViewLimitModal = (props: Props): JSX.Element => {
|
||||
<React.Fragment>
|
||||
<FormattedMessage
|
||||
id='ViewLimitDialog.Subtext.Admin'
|
||||
defaultMessage='Upgrade to our Professional or Enterprise plan to have unlimited views per boards, unlimited cards, and more.'
|
||||
defaultMessage='Upgrade to our Professional or Enterprise plan.'
|
||||
/>
|
||||
<a
|
||||
href='https://mattermost.com/pricing/'
|
||||
|
||||
@@ -34,9 +34,11 @@ const ViewTitle = (props: Props) => {
|
||||
}, [board.id, board.icon])
|
||||
const onShowDescription = useCallback(() => mutator.showBoardDescription(board.id, Boolean(board.showDescription), true), [board.id, board.showDescription])
|
||||
const onHideDescription = useCallback(() => mutator.showBoardDescription(board.id, Boolean(board.showDescription), false), [board.id, board.showDescription])
|
||||
const canEditBoardProperties = useHasCurrentBoardPermissions([Permission.ManageBoardProperties])
|
||||
|
||||
const readonly = props.readonly || !canEditBoardProperties
|
||||
let readonly = props.readonly
|
||||
if(!readonly){
|
||||
readonly = !useHasCurrentBoardPermissions([Permission.ManageBoardProperties])
|
||||
}
|
||||
|
||||
const intl = useIntl()
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ jest.mock('react-router-dom', () => {
|
||||
useRouteMatch: jest.fn(() => {
|
||||
return {
|
||||
params: {
|
||||
teamId: board.teamId,
|
||||
boardId: board.id,
|
||||
viewId: activeView.id,
|
||||
},
|
||||
|
||||
@@ -49,7 +49,7 @@ function errorDefFromId(id: ErrorId | null): ErrorDef {
|
||||
case ErrorId.TeamUndefined: {
|
||||
errDef.title = intl.formatMessage({id: 'error.team-undefined', defaultMessage: 'Not a valid team.'})
|
||||
errDef.button1Enabled = true
|
||||
errDef.button1Text = intl.formatMessage({id: 'error.back-to-home', defaultMessage: 'Back to Home'})
|
||||
errDef.button1Text = intl.formatMessage({id: 'error.back-to-home', defaultMessage: 'Back to home'})
|
||||
errDef.button1Redirect = (): string => {
|
||||
UserSettings.setLastTeamID(null)
|
||||
return window.location.origin
|
||||
@@ -93,7 +93,7 @@ function errorDefFromId(id: ErrorId | null): ErrorDef {
|
||||
default: {
|
||||
errDef.title = intl.formatMessage({id: 'error.unknown', defaultMessage: 'An error occurred.'})
|
||||
errDef.button1Enabled = true
|
||||
errDef.button1Text = intl.formatMessage({id: 'error.back-to-home', defaultMessage: 'Back to Home'})
|
||||
errDef.button1Text = intl.formatMessage({id: 'error.back-to-home', defaultMessage: 'Back to home'})
|
||||
errDef.button1Redirect = '/'
|
||||
errDef.button1Fill = true
|
||||
errDef.button1ClearHistory = true
|
||||
|
||||
@@ -12,13 +12,12 @@ export const useHasPermissions = (teamId: string, boardId: string, permissions:
|
||||
return false
|
||||
}
|
||||
|
||||
const member = useAppSelector(getMyBoardMembership(boardId))
|
||||
const board = useAppSelector(getBoard(boardId))
|
||||
|
||||
if (!board) {
|
||||
return false
|
||||
}
|
||||
|
||||
const member = useAppSelector(getMyBoardMembership(boardId))
|
||||
if (!member) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ windowAny.baseURL = '/plugins/boards'
|
||||
windowAny.frontendBaseURL = '/boards'
|
||||
|
||||
import App from 'src/app'
|
||||
import PublicApp, {publicBaseURL} from 'src/public/app'
|
||||
|
||||
import store from 'src/store'
|
||||
import WithWebSockets from 'src/components/withWebSockets'
|
||||
@@ -175,10 +176,44 @@ const MainApp = (props: Props) => {
|
||||
)
|
||||
}
|
||||
|
||||
const PublicMainApp = () => {
|
||||
useEffect(() => {
|
||||
document.body.classList.add('focalboard-body')
|
||||
const root = document.getElementById('root')
|
||||
if (root) {
|
||||
while (root.firstElementChild) {
|
||||
if( root.firstElementChild.id === 'focalboard-app'){
|
||||
break
|
||||
}
|
||||
root.removeChild(root.firstElementChild)
|
||||
}
|
||||
root.classList.add('focalboard-plugin-root')
|
||||
}
|
||||
|
||||
return () => {
|
||||
document.body.classList.remove('focalboard-body')
|
||||
if (root) {
|
||||
root.classList.remove('focalboard-plugin-root')
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<ReduxProvider store={store}>
|
||||
<div id='focalboard-app'>
|
||||
<PublicApp />
|
||||
</div>
|
||||
<div id='focalboard-root-portal' />
|
||||
</ReduxProvider>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
}
|
||||
|
||||
const HeaderComponent = () => {
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<GlobalHeader history={browserHistory}/>
|
||||
<GlobalHeader history={browserHistory} />
|
||||
</ErrorBoundary>
|
||||
)
|
||||
}
|
||||
@@ -243,8 +278,6 @@ export default class Plugin {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
const initCurrentChannelId = mmStore.getState().entities.channels.currentChannelId
|
||||
const initCurrentChannel = mmStore.getState().entities.channels.channels[initCurrentChannelId]
|
||||
let lastViewedChannelId = initCurrentChannelId
|
||||
@@ -274,7 +307,9 @@ export default class Plugin {
|
||||
prevTeamId = currentTeamId
|
||||
store.dispatch(setTeam(currentTeamId))
|
||||
octoClient.teamId = currentTeamId
|
||||
store.dispatch(initialLoad())
|
||||
if(!window.location.pathname.includes(publicBaseURL())){
|
||||
store.dispatch(initialLoad())
|
||||
}
|
||||
}
|
||||
|
||||
if (currentTeamId && currentTeamId !== prevTeamId) {
|
||||
@@ -336,6 +371,9 @@ export default class Plugin {
|
||||
HeaderComponent,
|
||||
() => null,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
PublicMainApp,
|
||||
)
|
||||
|
||||
const goToFocalboardTemplate = () => {
|
||||
@@ -350,7 +388,7 @@ export default class Plugin {
|
||||
}
|
||||
|
||||
if (this.registry.registerAppBarComponent) {
|
||||
this.registry.registerAppBarComponent(appBarIcon, () => mmStore.dispatch(toggleRHSPlugin), intl.formatMessage({id: 'AppBar.Tooltip', defaultMessage: 'Toggle Linked Boards'}))
|
||||
this.registry.registerAppBarComponent(appBarIcon, () => mmStore.dispatch(toggleRHSPlugin), intl.formatMessage({id: 'AppBar.Tooltip', defaultMessage: 'Toggle linked boards'}))
|
||||
}
|
||||
|
||||
if (this.registry.registerActionAfterChannelCreation) {
|
||||
@@ -404,13 +442,13 @@ export default class Plugin {
|
||||
if(siteStats){
|
||||
return {
|
||||
boards_count: {
|
||||
name: intl.formatMessage({id: 'SiteStats.total_boards', defaultMessage: 'Total Boards'}),
|
||||
name: intl.formatMessage({id: 'SiteStats.total_boards', defaultMessage: 'Total boards'}),
|
||||
id: 'total_boards',
|
||||
icon: 'icon-product-boards',
|
||||
value: siteStats.board_count,
|
||||
},
|
||||
cards_count: {
|
||||
name: intl.formatMessage({id: 'SiteStats.total_cards', defaultMessage: 'Total Cards'}),
|
||||
name: intl.formatMessage({id: 'SiteStats.total_cards', defaultMessage: 'Total cards'}),
|
||||
id: 'total_cards',
|
||||
icon: 'icon-products',
|
||||
value: siteStats.card_count,
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`properties/number should match snapshot for number with empty value 1`] = `
|
||||
<div>
|
||||
<input
|
||||
class="Editable octo-propertyvalue"
|
||||
placeholder=""
|
||||
style="width: 100%;"
|
||||
title=""
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
70
webapp/boards/src/properties/number/number.test.tsx
Обычный файл
70
webapp/boards/src/properties/number/number.test.tsx
Обычный файл
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {ComponentProps} from 'react'
|
||||
import {screen} from '@testing-library/react'
|
||||
import {mocked} from 'jest-mock'
|
||||
|
||||
import {setup, wrapIntl} from 'src/testUtils'
|
||||
import {TestBlockFactory} from 'src/test/testBlockFactory'
|
||||
import mutator from 'src/mutator'
|
||||
|
||||
import {Board, IPropertyTemplate} from 'src/blocks/board'
|
||||
import {Card} from 'src/blocks/card'
|
||||
|
||||
import NumberProperty from './property'
|
||||
import NumberEditor from './number'
|
||||
|
||||
jest.mock('src/components/flashMessages')
|
||||
jest.mock('src/mutator')
|
||||
|
||||
const mockedMutator = mocked(mutator)
|
||||
|
||||
describe('properties/number', () => {
|
||||
let board: Board
|
||||
let card: Card
|
||||
let propertyTemplate: IPropertyTemplate
|
||||
let baseProps: ComponentProps<typeof NumberEditor>
|
||||
|
||||
beforeEach(() => {
|
||||
board = TestBlockFactory.createBoard()
|
||||
card = TestBlockFactory.createCard()
|
||||
propertyTemplate = board.cardProperties[0]
|
||||
|
||||
baseProps = {
|
||||
property: new NumberProperty(),
|
||||
card,
|
||||
board,
|
||||
propertyTemplate,
|
||||
propertyValue: '',
|
||||
readOnly: false,
|
||||
showEmptyPlaceholder: false,
|
||||
}
|
||||
})
|
||||
|
||||
it('should match snapshot for number with empty value', () => {
|
||||
const {container} = setup(
|
||||
wrapIntl((
|
||||
<NumberEditor
|
||||
{...baseProps}
|
||||
/>
|
||||
))
|
||||
)
|
||||
expect(container).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should fire change event when valid number value is entered', async () => {
|
||||
const {user} = setup(
|
||||
wrapIntl(
|
||||
<NumberEditor
|
||||
{...baseProps}
|
||||
/>
|
||||
)
|
||||
)
|
||||
const value = '42'
|
||||
const input = screen.getByRole('textbox')
|
||||
await user.type(input, `${value}{Enter}`)
|
||||
|
||||
expect(mockedMutator.changePropertyValue).toHaveBeenCalledWith(board.id, card, propertyTemplate.id, `${value}`)
|
||||
})
|
||||
})
|
||||
@@ -10,7 +10,7 @@ const Number = (props: PropertyProps): JSX.Element => {
|
||||
return (
|
||||
<BaseTextEditor
|
||||
{...props}
|
||||
validator={() => !isNaN(parseInt(props.propertyValue as string, 10))}
|
||||
validator={() => props.propertyValue === '' || !isNaN(parseInt(props.propertyValue as string, 10))}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
61
webapp/boards/src/public/app.tsx
Обычный файл
61
webapp/boards/src/public/app.tsx
Обычный файл
@@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React from 'react'
|
||||
import {Router, Switch} from 'react-router-dom'
|
||||
|
||||
import {IntlProvider} from 'react-intl'
|
||||
import {DndProvider} from 'react-dnd'
|
||||
import {HTML5Backend} from 'react-dnd-html5-backend'
|
||||
import {TouchBackend} from 'react-dnd-touch-backend'
|
||||
import {createBrowserHistory} from 'history'
|
||||
|
||||
import BoardPage from 'src/pages/boardPage/boardPage'
|
||||
import FBRoute from 'src/route'
|
||||
|
||||
import {getMessages} from 'src/i18n'
|
||||
import FlashMessages from 'src/components/flashMessages'
|
||||
import NewVersionBanner from 'src/components/newVersionBanner'
|
||||
import {Utils} from 'src/utils'
|
||||
import {getLanguage} from 'src/store/language'
|
||||
import {useAppSelector} from 'src/store/hooks'
|
||||
|
||||
export const publicBaseURL = () => {
|
||||
return Utils.getFrontendBaseURL() + '/public'
|
||||
}
|
||||
|
||||
const PublicRouter = () => {
|
||||
const history = createBrowserHistory({basename: publicBaseURL()})
|
||||
|
||||
return (
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<FBRoute path={['/team/:teamId/shared/:boardId?/:viewId?/:cardId?', '/shared/:boardId?/:viewId?/:cardId?']}>
|
||||
<BoardPage readonly={true}/>
|
||||
</FBRoute>
|
||||
</Switch>
|
||||
</Router>
|
||||
)
|
||||
}
|
||||
|
||||
const PublicApp = (): JSX.Element => {
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<DndProvider backend={Utils.isMobile() ? TouchBackend : HTML5Backend}>
|
||||
<FlashMessages milliseconds={2000}/>
|
||||
<div id='frame'>
|
||||
<div id='main'>
|
||||
<NewVersionBanner/>
|
||||
<PublicRouter/>
|
||||
</div>
|
||||
</div>
|
||||
</DndProvider>
|
||||
</IntlProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(PublicApp)
|
||||
4
webapp/boards/src/types/mattermost-webapp/index.d.ts
поставляемый
4
webapp/boards/src/types/mattermost-webapp/index.d.ts
поставляемый
@@ -14,7 +14,9 @@ export interface PluginRegistry {
|
||||
registerCustomRoute(route: string, component: ReactResolvable): any
|
||||
registerProductRoute(route: string, component: ReactResolvable): any
|
||||
unregisterComponent(componentId: string): any
|
||||
registerProduct(baseURL: string, switcherIcon: string, switcherText: string, switcherLinkURL: string, mainComponent: ReactResolvable, headerCentreComponent: ReactResolvable, headerRightComponent: ReactResolvable, showTeamSidebar: boolean): any
|
||||
registerProduct(baseURL: string, switcherIcon: string, switcherText: string, switcherLinkURL: string,
|
||||
mainComponent: ReactResolvable, headerCentreComponent: ReactResolvable, headerRightComponent: ReactResolvable,
|
||||
showTeamSidebar: boolean, showAppBar: boolean, wrapped: boolean, publicComponent: ReactResolvable | null): any
|
||||
registerPostWillRenderEmbedComponent(match: (embed: {type: string, data: any}) => void, component: any, toggleable: boolean): any
|
||||
registerWebSocketEventHandler(event: string, handler: (e: any) => void): any
|
||||
unregisterWebSocketEventHandler(event: string): any
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"plugin:react-hooks/recommended"
|
||||
],
|
||||
"plugins": [
|
||||
"@babel/eslint-plugin",
|
||||
"@babel",
|
||||
"mattermost",
|
||||
"import",
|
||||
"no-only-tests",
|
||||
@@ -80,11 +80,22 @@
|
||||
"react/style-prop-object": [2, {
|
||||
"allow": ["Timestamp"]
|
||||
}],
|
||||
"no-restricted-imports": ["error", {
|
||||
"paths": [
|
||||
{"name": "react-bootstrap", "importNames": ["OverlayTrigger"], "message": "Please use OverlayTrigger from '/components/overlay_trigger' instead"}
|
||||
]
|
||||
}],
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"patterns": [
|
||||
{
|
||||
"group": ["react-bootstrap"],
|
||||
"importNames": ["OverlayTrigger"],
|
||||
"message": "Please use OverlayTrigger from '/components/overlay_trigger' instead."
|
||||
},
|
||||
{
|
||||
"group": ["@mattermost/compass-components/*"],
|
||||
"message": "compass-components is now archived"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"max-lines": ["warn", {"max": 800, "skipBlankLines": true, "skipComments": true}],
|
||||
"formatjs/no-multiple-whitespaces": ["error"]
|
||||
},
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
},
|
||||
"version": "7.9.0",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"npm": ">=7.0.0",
|
||||
"node": ">=16.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom": "1.0.0",
|
||||
"@floating-ui/react-dom-interactions": "0.10.3",
|
||||
@@ -123,14 +119,12 @@
|
||||
"@types/bootstrap": "4.5.0",
|
||||
"@types/country-list": "2.1.0",
|
||||
"@types/enzyme": "3.10.11",
|
||||
"@types/highlight.js": "10.1.0",
|
||||
"@types/jest": "26.0.24",
|
||||
"@types/katex": "0.11.0",
|
||||
"@types/lodash": "4.14.182",
|
||||
"@types/luxon": "3.0.2",
|
||||
"@types/mark.js": "8.11.6",
|
||||
"@types/marked": "0.7.4",
|
||||
"@types/moment-timezone": "0.5.30",
|
||||
"@types/node": "16.3.1",
|
||||
"@types/react": "17.0.2",
|
||||
"@types/react-beautiful-dnd": "13.1.2",
|
||||
@@ -153,8 +147,8 @@
|
||||
"@types/styled-components": "5.1.24",
|
||||
"@types/tinycolor2": "1.4.3",
|
||||
"@types/webpack-env": "1.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.41.0",
|
||||
"@typescript-eslint/parser": "5.41.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.57.1",
|
||||
"@typescript-eslint/parser": "5.57.1",
|
||||
"babel-loader": "8.2.3",
|
||||
"babel-plugin-lodash": "3.3.4",
|
||||
"babel-plugin-styled-components": "1.12.0",
|
||||
@@ -167,14 +161,13 @@
|
||||
"enzyme": "3.11.0",
|
||||
"enzyme-adapter-react-17-updated": "1.0.2",
|
||||
"enzyme-to-json": "3.6.2",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-import-resolver-webpack": "0.13.2",
|
||||
"eslint-plugin-formatjs": "4.3.4",
|
||||
"eslint-plugin-formatjs": "4.9.1",
|
||||
"eslint-plugin-header": "3.1.1",
|
||||
"eslint-plugin-import": "2.23.4",
|
||||
"eslint-plugin-import": "2.27.5",
|
||||
"eslint-plugin-mattermost": "github:mattermost/eslint-plugin-mattermost#5b0c972eacf19286e4c66221b39113bf8728a99e",
|
||||
"eslint-plugin-no-only-tests": "2.6.0",
|
||||
"eslint-plugin-react": "7.31.10",
|
||||
"eslint-plugin-no-only-tests": "3.1.0",
|
||||
"eslint-plugin-react": "7.32.2",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"external-remotes-plugin": "1.0.0",
|
||||
"file-loader": "6.2.0",
|
||||
|
||||
@@ -14,13 +14,12 @@ import {
|
||||
searchFilesWithParams,
|
||||
} from 'mattermost-redux/actions/search';
|
||||
import * as PostActions from 'mattermost-redux/actions/posts';
|
||||
import {getCurrentUserId, getCurrentUserMentionKeys} from 'mattermost-redux/selectors/entities/users';
|
||||
import {getCurrentUserMentionKeys} from 'mattermost-redux/selectors/entities/users';
|
||||
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getCurrentChannelId, getCurrentChannelNameForSearchShortcut, getChannel as getChannelSelector} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getPost} from 'mattermost-redux/selectors/entities/posts';
|
||||
import {makeGetUserTimezone} from 'mattermost-redux/selectors/entities/timezone';
|
||||
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
|
||||
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
|
||||
import {Action, ActionResult, DispatchFunc, GenericAction, GetStateFunc} from 'mattermost-redux/types/actions';
|
||||
import {Post} from '@mattermost/types/posts';
|
||||
|
||||
@@ -174,9 +173,7 @@ export function performSearch(terms: string, isMentionSearch?: boolean) {
|
||||
}
|
||||
|
||||
// timezone offset in seconds
|
||||
const userId = getCurrentUserId(getState());
|
||||
const userTimezone = makeGetUserTimezone()(getState(), userId);
|
||||
const userCurrentTimezone = getUserCurrentTimezone(userTimezone);
|
||||
const userCurrentTimezone = getCurrentTimezone(getState());
|
||||
const timezoneOffset = ((userCurrentTimezone && (userCurrentTimezone.length > 0)) ? getUtcOffsetForTimeZone(userCurrentTimezone) : getBrowserUtcOffset()) * 60;
|
||||
const messagesPromise = dispatch(searchPostsWithParams(isMentionSearch ? '' : teamId, {terms, is_or_search: Boolean(isMentionSearch), include_deleted_channels: viewArchivedChannels, time_zone_offset: timezoneOffset, page: 0, per_page: 20}));
|
||||
const filesPromise = dispatch(searchFilesWithParams(teamId, {terms: termsWithExtensionsFilters, is_or_search: Boolean(isMentionSearch), include_deleted_channels: viewArchivedChannels, time_zone_offset: timezoneOffset, page: 0, per_page: 20}));
|
||||
|
||||
@@ -49,7 +49,7 @@ export default class AboutBuildModal extends React.PureComponent<Props, State> {
|
||||
|
||||
doHide = () => {
|
||||
this.setState({show: false});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const config = this.props.config;
|
||||
|
||||
@@ -32,11 +32,11 @@ export default class AccessHistoryModal extends React.PureComponent<Props, State
|
||||
|
||||
public onShow = () => { // public for testing
|
||||
this.props.actions.getUserAudits(this.props.currentUserId, 0, 200);
|
||||
}
|
||||
};
|
||||
|
||||
public onHide = () => { // public for testing
|
||||
this.setState({show: false});
|
||||
}
|
||||
};
|
||||
|
||||
public componentDidMount() {
|
||||
this.onShow();
|
||||
|
||||
@@ -23,7 +23,7 @@ export default class Accordion extends React.PureComponent<Props, State> {
|
||||
|
||||
setExpanded = (expandedKey: string) => {
|
||||
this.setState({expandedKey});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
||||
@@ -39,7 +39,6 @@ exports[`components/actions_menu/ActionsMenu has actions - marketplace disabled
|
||||
className="post-menu__item post-menu__item--active"
|
||||
id="center_actions_button_post_id_1"
|
||||
key="more-actions-button"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
@@ -107,7 +106,6 @@ exports[`components/actions_menu/ActionsMenu has actions - marketplace enabled a
|
||||
className="post-menu__item post-menu__item--active"
|
||||
id="center_actions_button_post_id_1"
|
||||
key="more-actions-button"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
@@ -194,7 +192,6 @@ exports[`components/actions_menu/ActionsMenu no actions - sysadmin - menu should
|
||||
className="post-menu__item post-menu__item--active"
|
||||
id="center_actions_button_post_id_1"
|
||||
key="more-actions-button"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
<i
|
||||
|
||||
@@ -38,12 +38,7 @@ describe('components/actions_menu/ActionsMenu', () => {
|
||||
isSysAdmin: true,
|
||||
pluginMenuItems: [],
|
||||
post: TestHelper.getPostMock({id: 'post_id_1', is_pinned: false, type: '' as PostType}),
|
||||
showTutorialTip: false,
|
||||
components: {},
|
||||
handleOpenTip: jest.fn(),
|
||||
handleNextTip: jest.fn(),
|
||||
handleDismissTip: jest.fn(),
|
||||
showPulsatingDot: false,
|
||||
location: 'center',
|
||||
canOpenMarketplace: false,
|
||||
actions: {
|
||||
|
||||
@@ -17,7 +17,6 @@ import {AppCallResponseTypes} from 'mattermost-redux/constants/apps';
|
||||
import {HandleBindingClick, PostEphemeralCallResponseForPost, OpenAppsModal} from 'types/apps';
|
||||
import {Locations, Constants, ModalIdentifiers} from 'utils/constants';
|
||||
import Permissions from 'mattermost-redux/constants/permissions';
|
||||
import {ActionsTutorialTip} from 'components/actions_menu/actions_menu_tutorial_tip';
|
||||
import {ModalData} from 'types/actions';
|
||||
import MarketplaceModal, {OpenedFromType} from 'components/plugin_marketplace/marketplace_modal';
|
||||
import OverlayTrigger from 'components/overlay_trigger';
|
||||
@@ -44,11 +43,6 @@ export type Props = {
|
||||
pluginMenuItems?: PluginComponent[];
|
||||
post: Post;
|
||||
teamId: string;
|
||||
handleOpenTip: () => void;
|
||||
handleNextTip: (e: React.MouseEvent) => void;
|
||||
handleDismissTip: () => void;
|
||||
showPulsatingDot?: boolean;
|
||||
showTutorialTip: boolean;
|
||||
canOpenMarketplace: boolean;
|
||||
|
||||
/**
|
||||
@@ -98,7 +92,7 @@ export class ActionMenuClass extends React.PureComponent<Props, State> {
|
||||
appBindings: [],
|
||||
location: Locations.CENTER,
|
||||
pluginMenuItems: [],
|
||||
}
|
||||
};
|
||||
private buttonRef: React.RefObject<HTMLButtonElement>;
|
||||
|
||||
constructor(props: Props) {
|
||||
@@ -121,7 +115,7 @@ export class ActionMenuClass extends React.PureComponent<Props, State> {
|
||||
defaultMessage='Message actions'
|
||||
/>
|
||||
</Tooltip>
|
||||
)
|
||||
);
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
if (this.props.isMenuOpen && !prevProps.isMenuOpen) {
|
||||
@@ -143,7 +137,7 @@ export class ActionMenuClass extends React.PureComponent<Props, State> {
|
||||
this.setState({appBindings: data});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleOpenMarketplace = (): void => {
|
||||
const openedFrom: OpenedFromType = 'actions_menu';
|
||||
@@ -203,7 +197,7 @@ export class ActionMenuClass extends React.PureComponent<Props, State> {
|
||||
this.props.actions.postEphemeralCallResponseForPost(callResp, errorMessage, post);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
visitMarketplaceTip(): React.ReactElement {
|
||||
return (
|
||||
@@ -236,14 +230,6 @@ export class ActionMenuClass extends React.PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
handleActionsIconClick = (e: React.MouseEvent) => {
|
||||
if (this.props.showPulsatingDot || this.props.showTutorialTip) {
|
||||
this.props.handleOpenTip();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
renderDivider = (suffix: string): React.ReactNode => {
|
||||
return (
|
||||
<li
|
||||
@@ -277,7 +263,7 @@ export class ActionMenuClass extends React.PureComponent<Props, State> {
|
||||
this.setState({
|
||||
openUp: (spaceOnTop > spaceOnBottom),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render(): React.ReactNode {
|
||||
const isSystemMessage = PostUtils.isSystemMessage(this.props.post);
|
||||
@@ -413,17 +399,8 @@ export class ActionMenuClass extends React.PureComponent<Props, State> {
|
||||
})}
|
||||
type='button'
|
||||
aria-expanded='false'
|
||||
onClick={this.handleActionsIconClick}
|
||||
>
|
||||
<i className={'icon icon-apps'}/>
|
||||
{this.props.showPulsatingDot &&
|
||||
<ActionsTutorialTip
|
||||
showTip={this.props.showTutorialTip}
|
||||
handleNext={this.props.handleNextTip}
|
||||
handleOpen={this.props.handleOpenTip}
|
||||
handleDismiss={this.props.handleDismissTip}
|
||||
/>
|
||||
}
|
||||
</button>
|
||||
</OverlayTrigger>
|
||||
<Menu
|
||||
|
||||
@@ -37,11 +37,6 @@ describe('components/actions_menu/ActionsMenu returning empty ("")', () => {
|
||||
},
|
||||
appBindings: [],
|
||||
pluginMenuItems: [],
|
||||
handleOpenTip: jest.fn(),
|
||||
handleNextTip: jest.fn(),
|
||||
handleDismissTip: jest.fn(),
|
||||
showPulsatingDot: false,
|
||||
showTutorialTip: false,
|
||||
appsEnabled: false,
|
||||
isSysAdmin: true,
|
||||
canOpenMarketplace: false,
|
||||
|
||||
@@ -37,11 +37,6 @@ describe('components/actions_menu/ActionsMenu on mobile view', () => {
|
||||
},
|
||||
appBindings: [],
|
||||
pluginMenuItems: [],
|
||||
handleOpenTip: jest.fn(),
|
||||
handleNextTip: jest.fn(),
|
||||
handleDismissTip: jest.fn(),
|
||||
showPulsatingDot: false,
|
||||
showTutorialTip: false,
|
||||
appsEnabled: false,
|
||||
isSysAdmin: true,
|
||||
canOpenMarketplace: false,
|
||||
|
||||
@@ -6,7 +6,7 @@ import {Link, useRouteMatch, useLocation, matchPath} from 'react-router-dom';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import Icon from '@mattermost/compass-components/foundations/icon';
|
||||
import Icon from '@mattermost/compass-components/foundations/icon'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import {insightsAreEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getIsRhsOpen, getRhsState} from 'selectors/rhs';
|
||||
|
||||
@@ -5,7 +5,7 @@ import React, {memo, useCallback} from 'react';
|
||||
|
||||
import ReactSelect, {ValueType} from 'react-select';
|
||||
|
||||
import Icon from '@mattermost/compass-components/foundations/icon/Icon';
|
||||
import Icon from '@mattermost/compass-components/foundations/icon/Icon'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
|
||||
@@ -11,14 +11,13 @@ import {TopChannel, TopChannelGraphData} from '@mattermost/types/insights';
|
||||
import {CircleSkeletonLoader, RectangleSkeletonLoader} from '@mattermost/components';
|
||||
|
||||
import {getCurrentRelativeTeamUrl, getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentTimezone} from 'mattermost-redux/selectors/entities/timezone';
|
||||
import {getMyTopChannels, getTopChannelsForTeam} from 'mattermost-redux/actions/insights';
|
||||
|
||||
import Constants, {InsightsScopes} from 'utils/constants';
|
||||
|
||||
import {trackEvent} from 'actions/telemetry_actions';
|
||||
|
||||
import {getCurrentUserTimezone} from 'selectors/general';
|
||||
|
||||
import OverlayTrigger from 'components/overlay_trigger';
|
||||
import Tooltip from 'components/tooltip';
|
||||
|
||||
@@ -38,7 +37,7 @@ const TopChannels = (props: WidgetHocProps) => {
|
||||
|
||||
const currentTeamId = useSelector(getCurrentTeamId);
|
||||
const currentTeamUrl = useSelector(getCurrentRelativeTeamUrl);
|
||||
const timeZone = useSelector(getCurrentUserTimezone);
|
||||
const timeZone = useSelector(getCurrentTimezone);
|
||||
|
||||
const getTopTeamChannels = useCallback(async () => {
|
||||
if (props.filterType === InsightsScopes.TEAM) {
|
||||
|
||||
@@ -53,7 +53,7 @@ type State = {
|
||||
export default class ActivityLogModal extends React.PureComponent<Props, State> {
|
||||
static propTypes = {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
@@ -73,15 +73,15 @@ export default class ActivityLogModal extends React.PureComponent<Props, State>
|
||||
this.props.actions.revokeSession(this.props.currentUserId, altId).then(() => {
|
||||
this.props.actions.getSessions(this.props.currentUserId);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onShow = () => {
|
||||
this.props.actions.getSessions(this.props.currentUserId);
|
||||
}
|
||||
};
|
||||
|
||||
onHide = () => {
|
||||
this.setState({show: false});
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.onShow();
|
||||
|
||||
@@ -56,11 +56,11 @@ export default class ActivityLog extends React.PureComponent<Props, State> {
|
||||
|
||||
handleMoreInfo = (): void => {
|
||||
this.setState({moreInfo: true});
|
||||
}
|
||||
};
|
||||
|
||||
submitRevoke = (e: React.MouseEvent): void => {
|
||||
this.props.submitRevoke(this.props.currentSession.id, e);
|
||||
}
|
||||
};
|
||||
|
||||
isMobileSession = (session: Session): boolean => {
|
||||
return Boolean(session.device_id && (session.device_id.includes('apple') || session.device_id.includes('android')));
|
||||
|
||||
@@ -110,7 +110,7 @@ export default class AddGroupsToChannelModal extends React.PureComponent<Props,
|
||||
handleHide = () => {
|
||||
this.props.actions.setModalSearchTerm('');
|
||||
this.setState({show: false});
|
||||
}
|
||||
};
|
||||
|
||||
handleResponse = (err?: ServerError) => {
|
||||
let addError = null;
|
||||
@@ -122,7 +122,7 @@ export default class AddGroupsToChannelModal extends React.PureComponent<Props,
|
||||
saving: false,
|
||||
addError,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleSubmit = async () => {
|
||||
const groupIDs = this.state.values.map((v) => v.id);
|
||||
@@ -147,7 +147,7 @@ export default class AddGroupsToChannelModal extends React.PureComponent<Props,
|
||||
this.handleHide();
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
addValue = (value: GroupValue) => {
|
||||
const values = Object.assign([], this.state.values);
|
||||
@@ -157,13 +157,13 @@ export default class AddGroupsToChannelModal extends React.PureComponent<Props,
|
||||
}
|
||||
|
||||
this.setState({values});
|
||||
}
|
||||
};
|
||||
|
||||
setGroupsLoadingState = (loadingState: boolean) => {
|
||||
this.setState({
|
||||
loadingGroups: loadingState,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handlePageChange = (page: number, prevPage: number) => {
|
||||
if (page > prevPage) {
|
||||
@@ -172,15 +172,15 @@ export default class AddGroupsToChannelModal extends React.PureComponent<Props,
|
||||
this.setGroupsLoadingState(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleDelete = (values: GroupValue[]) => {
|
||||
this.setState({values});
|
||||
}
|
||||
};
|
||||
|
||||
search = (term: string) => {
|
||||
this.props.actions.setModalSearchTerm(term);
|
||||
}
|
||||
};
|
||||
|
||||
renderOption = (option: GroupValue, isSelected: boolean, onAdd: (value: GroupValue) => void, onMouseMove?: (value: GroupValue) => void) => {
|
||||
const rowSelected = isSelected ? 'more-modal__row--selected' : '';
|
||||
@@ -222,7 +222,7 @@ export default class AddGroupsToChannelModal extends React.PureComponent<Props,
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
renderValue(props: { data: Partial<Value> }) {
|
||||
return props.data.display_name;
|
||||
|
||||
@@ -105,12 +105,12 @@ export default class AddGroupsToTeamModal extends React.PureComponent<Props, Sta
|
||||
public handleHide = () => {
|
||||
this.props.actions.setModalSearchTerm('');
|
||||
this.setState({show: false});
|
||||
}
|
||||
};
|
||||
|
||||
// public for tests
|
||||
public handleExit = (): void => {
|
||||
this.props.onExited();
|
||||
}
|
||||
};
|
||||
|
||||
// public for tests
|
||||
public handleResponse = (err?: Error): void => {
|
||||
@@ -123,7 +123,7 @@ export default class AddGroupsToTeamModal extends React.PureComponent<Props, Sta
|
||||
saving: false,
|
||||
addError,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// public for tests
|
||||
public handleSubmit = async () => {
|
||||
@@ -148,7 +148,7 @@ export default class AddGroupsToTeamModal extends React.PureComponent<Props, Sta
|
||||
this.handleHide();
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
// public for tests
|
||||
public addValue = (value: GroupValue): void => {
|
||||
@@ -159,13 +159,13 @@ export default class AddGroupsToTeamModal extends React.PureComponent<Props, Sta
|
||||
}
|
||||
|
||||
this.setState({values});
|
||||
}
|
||||
};
|
||||
|
||||
private setGroupsLoadingState = (loadingState: boolean) => {
|
||||
this.setState({
|
||||
loadingGroups: loadingState,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// public for tests
|
||||
public handlePageChange = (page: number, prevPage: number): void => {
|
||||
@@ -175,7 +175,7 @@ export default class AddGroupsToTeamModal extends React.PureComponent<Props, Sta
|
||||
this.setGroupsLoadingState(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// public for tests
|
||||
public handleDelete = (values: GroupValue[]): void => this.setState({values});
|
||||
@@ -224,7 +224,7 @@ export default class AddGroupsToTeamModal extends React.PureComponent<Props, Sta
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// public for tests
|
||||
public renderValue = (props: { data: Value }): string | undefined => props.data.display_name;
|
||||
|
||||
@@ -114,7 +114,7 @@ export default class AddUserToChannelModal extends React.PureComponent<Props, St
|
||||
|
||||
enableChannelProvider = () => {
|
||||
this.suggestionProviders[0].disableDispatches = false;
|
||||
}
|
||||
};
|
||||
|
||||
focusTextbox = () => {
|
||||
if (this.channelSearchBox == null) {
|
||||
@@ -126,30 +126,30 @@ export default class AddUserToChannelModal extends React.PureComponent<Props, St
|
||||
textbox.focus();
|
||||
placeCaretAtEnd(textbox);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onInputChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({text: e.target.value, selectedChannelId: null});
|
||||
}
|
||||
};
|
||||
|
||||
onHide = () => {
|
||||
this.setState({show: false});
|
||||
}
|
||||
};
|
||||
|
||||
onExited = () => {
|
||||
this.props.onExited();
|
||||
}
|
||||
};
|
||||
|
||||
setSearchBoxRef = (input: SuggestionBoxComponent) => {
|
||||
this.channelSearchBox = input;
|
||||
this.focusTextbox();
|
||||
}
|
||||
};
|
||||
|
||||
handleSubmitError = (error: {message: string}) => {
|
||||
if (error) {
|
||||
this.setState({submitError: error.message, saving: false});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
didSelectChannel = (selection: {channel: Channel}) => {
|
||||
const channel = selection.channel;
|
||||
@@ -165,7 +165,7 @@ export default class AddUserToChannelModal extends React.PureComponent<Props, St
|
||||
this.props.actions.getChannelMember(channel.id, userId).then(() => {
|
||||
this.setState({checkingForMembership: false});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleSubmit = (e: FormEvent) => {
|
||||
if (e && e.preventDefault) {
|
||||
@@ -192,7 +192,7 @@ export default class AddUserToChannelModal extends React.PureComponent<Props, St
|
||||
this.onHide();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
isUserMemberOfChannel = (channelId: string | null) => {
|
||||
const user = this.props.user;
|
||||
@@ -207,7 +207,7 @@ export default class AddUserToChannelModal extends React.PureComponent<Props, St
|
||||
}
|
||||
|
||||
return Boolean(memberships[channelId][user.id]);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const user = this.props.user;
|
||||
|
||||
@@ -173,7 +173,7 @@ export default class AddUserToGroupMultiSelect extends React.PureComponent<Props
|
||||
return '';
|
||||
}
|
||||
return option.username;
|
||||
}
|
||||
};
|
||||
|
||||
renderOption = (option: UserProfileValue, isSelected: boolean, onAdd: (user: UserProfileValue) => void, onMouseMove: (user: UserProfileValue) => void) => {
|
||||
return (
|
||||
@@ -241,5 +241,5 @@ export default class AddUserToGroupMultiSelect extends React.PureComponent<Props
|
||||
numRemainingText={numRemainingText}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,11 +78,11 @@ export default class AddUsersToTeamModal extends React.PureComponent<Props, Stat
|
||||
public componentDidMount = async () => {
|
||||
await this.props.actions.getProfilesNotInTeam(this.props.team.id, false, 0, USERS_PER_PAGE * 2);
|
||||
this.setUsersLoadingState(false);
|
||||
}
|
||||
};
|
||||
|
||||
private setUsersLoadingState = (loading: boolean) => {
|
||||
this.setState({loading});
|
||||
}
|
||||
};
|
||||
|
||||
public search = async (term: string) => {
|
||||
this.setUsersLoadingState(true);
|
||||
@@ -95,17 +95,17 @@ export default class AddUsersToTeamModal extends React.PureComponent<Props, Stat
|
||||
await this.props.actions.getProfilesNotInTeam(this.props.team.id, false, 0, USERS_PER_PAGE * 2);
|
||||
}
|
||||
this.setState({loading: false, searchResults, search});
|
||||
}
|
||||
};
|
||||
|
||||
public handleHide = () => {
|
||||
this.setState({show: false});
|
||||
}
|
||||
};
|
||||
|
||||
private handleExit = () => {
|
||||
if (this.props.onExited) {
|
||||
this.props.onExited();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private renderOption = (option: UserProfileValue, isSelected: boolean, onAdd: (user: UserProfileValue) => void, onMouseMove: (user: UserProfileValue) => void) => {
|
||||
let rowSelected = '';
|
||||
@@ -139,15 +139,15 @@ export default class AddUsersToTeamModal extends React.PureComponent<Props, Stat
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private renderValue = (value: { data: UserProfileValue }): string => {
|
||||
return value.data?.username || '';
|
||||
}
|
||||
};
|
||||
|
||||
private renderAriaLabel = (option: UserProfileValue): string => {
|
||||
return option?.username || '';
|
||||
}
|
||||
};
|
||||
|
||||
private handleAdd = (value: UserProfileValue) => {
|
||||
const values: UserProfileValue[] = [...this.state.values];
|
||||
@@ -155,11 +155,11 @@ export default class AddUsersToTeamModal extends React.PureComponent<Props, Stat
|
||||
values.push(value);
|
||||
}
|
||||
this.setState({values});
|
||||
}
|
||||
};
|
||||
|
||||
private handleDelete = (values: UserProfileValue[]) => {
|
||||
this.setState({values});
|
||||
}
|
||||
};
|
||||
|
||||
private handlePageChange = (page: number, prevPage: number) => {
|
||||
if (page > prevPage) {
|
||||
@@ -173,7 +173,7 @@ export default class AddUsersToTeamModal extends React.PureComponent<Props, Stat
|
||||
private handleSubmit = () => {
|
||||
this.props.onAddCallback(this.state.values);
|
||||
this.handleHide();
|
||||
}
|
||||
};
|
||||
|
||||
public render = (): JSX.Element => {
|
||||
const numRemainingText = (
|
||||
@@ -259,5 +259,5 @@ export default class AddUsersToTeamModal extends React.PureComponent<Props, Stat
|
||||
</Modal.Body>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ export default class AdminConsole extends React.PureComponent<Props, State> {
|
||||
|
||||
private onFilterChange = (filter: string) => {
|
||||
this.setState({filter});
|
||||
}
|
||||
};
|
||||
|
||||
private mainRolesLoaded(roles: Record<string, Role>) {
|
||||
return (
|
||||
@@ -186,7 +186,7 @@ export default class AdminConsole extends React.PureComponent<Props, State> {
|
||||
{<Redirect to={`${this.props.match.url}/${defaultUrl}`}/>}
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
public render(): JSX.Element | null {
|
||||
const {
|
||||
|
||||
@@ -5746,7 +5746,6 @@ const AdminDefinition = {
|
||||
sectionTitle: t('admin.sidebar.products'),
|
||||
sectionTitleDefault: 'Products',
|
||||
isHidden: it.any(
|
||||
it.configIsFalse('FeatureFlags', 'BoardsProduct'),
|
||||
it.not(it.userHasReadPermissionOnSomeResources(RESOURCE_KEYS.PRODUCTS)),
|
||||
),
|
||||
boards: {
|
||||
|
||||
@@ -69,7 +69,7 @@ export default abstract class AdminSettings <Props extends BaseProps, State exte
|
||||
|
||||
private closeTooltip = () => {
|
||||
this.setState({errorTooltip: false});
|
||||
}
|
||||
};
|
||||
|
||||
private openTooltip = (e: React.MouseEvent) => {
|
||||
const elm: HTMLElement|null = e.currentTarget.querySelector('.control-label');
|
||||
@@ -77,7 +77,7 @@ export default abstract class AdminSettings <Props extends BaseProps, State exte
|
||||
const isElipsis = elm.offsetWidth < elm.scrollWidth;
|
||||
this.setState({errorTooltip: isElipsis});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
protected handleChange = (id: string, value: boolean) => {
|
||||
this.setState((prevState) => ({
|
||||
@@ -95,7 +95,7 @@ export default abstract class AdminSettings <Props extends BaseProps, State exte
|
||||
e.preventDefault();
|
||||
|
||||
this.doSubmit();
|
||||
}
|
||||
};
|
||||
|
||||
protected doSubmit = async (callback?: () => void) => {
|
||||
this.setState({
|
||||
|
||||
@@ -1072,6 +1072,37 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
|
||||
title="Plugin 0"
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="products"
|
||||
icon={
|
||||
<ProductsIcon
|
||||
className="category-icon fa"
|
||||
color="currentColor"
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
key="products"
|
||||
parentLink="/admin_console"
|
||||
sectionClass=""
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Products"
|
||||
id="admin.sidebar.products"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminSidebarSection
|
||||
definitionKey="products.boards"
|
||||
key="products.boards"
|
||||
name="products/boards"
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Boards"
|
||||
id="admin.sidebar.boards"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="integrations"
|
||||
icon={
|
||||
@@ -1775,6 +1806,37 @@ exports[`components/AdminSidebar should match snapshot with workspace optimizati
|
||||
title="Plugin 0"
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="products"
|
||||
icon={
|
||||
<ProductsIcon
|
||||
className="category-icon fa"
|
||||
color="currentColor"
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
key="products"
|
||||
parentLink="/admin_console"
|
||||
sectionClass=""
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Products"
|
||||
id="admin.sidebar.products"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminSidebarSection
|
||||
definitionKey="products.boards"
|
||||
key="products.boards"
|
||||
name="products/boards"
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Boards"
|
||||
id="admin.sidebar.boards"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="integrations"
|
||||
icon={
|
||||
@@ -2533,6 +2595,37 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
|
||||
title="Plugin 0"
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="products"
|
||||
icon={
|
||||
<ProductsIcon
|
||||
className="category-icon fa"
|
||||
color="currentColor"
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
key="products"
|
||||
parentLink="/admin_console"
|
||||
sectionClass=""
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Products"
|
||||
id="admin.sidebar.products"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminSidebarSection
|
||||
definitionKey="products.boards"
|
||||
key="products.boards"
|
||||
name="products/boards"
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Boards"
|
||||
id="admin.sidebar.boards"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="integrations"
|
||||
icon={
|
||||
@@ -3236,6 +3329,37 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
|
||||
title="Plugin 0"
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="products"
|
||||
icon={
|
||||
<ProductsIcon
|
||||
className="category-icon fa"
|
||||
color="currentColor"
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
key="products"
|
||||
parentLink="/admin_console"
|
||||
sectionClass=""
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Products"
|
||||
id="admin.sidebar.products"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminSidebarSection
|
||||
definitionKey="products.boards"
|
||||
key="products.boards"
|
||||
name="products/boards"
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Boards"
|
||||
id="admin.sidebar.boards"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="integrations"
|
||||
icon={
|
||||
@@ -4038,6 +4162,37 @@ exports[`components/AdminSidebar should match snapshot, with license (with all f
|
||||
title="Plugin 0"
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="products"
|
||||
icon={
|
||||
<ProductsIcon
|
||||
className="category-icon fa"
|
||||
color="currentColor"
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
key="products"
|
||||
parentLink="/admin_console"
|
||||
sectionClass=""
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Products"
|
||||
id="admin.sidebar.products"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminSidebarSection
|
||||
definitionKey="products.boards"
|
||||
key="products.boards"
|
||||
name="products/boards"
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Boards"
|
||||
id="admin.sidebar.boards"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="integrations"
|
||||
icon={
|
||||
@@ -4973,6 +5128,37 @@ exports[`components/AdminSidebar should match snapshot, with license (without an
|
||||
title="Plugin 0"
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="products"
|
||||
icon={
|
||||
<ProductsIcon
|
||||
className="category-icon fa"
|
||||
color="currentColor"
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
key="products"
|
||||
parentLink="/admin_console"
|
||||
sectionClass=""
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Products"
|
||||
id="admin.sidebar.products"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminSidebarSection
|
||||
definitionKey="products.boards"
|
||||
key="products.boards"
|
||||
name="products/boards"
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Boards"
|
||||
id="admin.sidebar.boards"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</AdminSidebarCategory>
|
||||
<AdminSidebarCategory
|
||||
definitionKey="integrations"
|
||||
icon={
|
||||
|
||||
@@ -57,11 +57,11 @@ const renderScrollThumbVertical = (props: Props) => (
|
||||
|
||||
class AdminSidebar extends React.PureComponent<Props, State> {
|
||||
searchRef: React.RefObject<HTMLInputElement>;
|
||||
idx: Index | null
|
||||
idx: Index | null;
|
||||
|
||||
static defaultProps = {
|
||||
plugins: {},
|
||||
}
|
||||
};
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
@@ -130,7 +130,7 @@ class AdminSidebar extends React.PureComponent<Props, State> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
updateTitle = () => {
|
||||
let currentSiteName = '';
|
||||
@@ -139,7 +139,7 @@ class AdminSidebar extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
document.title = localizeMessage('sidebar_right_menu.console', 'System Console') + currentSiteName;
|
||||
}
|
||||
};
|
||||
|
||||
visibleSections = () => {
|
||||
const {config, license, buildEnterpriseReady, consoleAccess, adminDefinition, cloud} = this.props;
|
||||
@@ -166,7 +166,7 @@ class AdminSidebar extends React.PureComponent<Props, State> {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
renderRootMenu = (definition: typeof AdminDefinition) => {
|
||||
const {config, license, buildEnterpriseReady, consoleAccess, cloud, subscriptionProduct} = this.props;
|
||||
@@ -249,11 +249,11 @@ class AdminSidebar extends React.PureComponent<Props, State> {
|
||||
return null;
|
||||
});
|
||||
return sidebarSections;
|
||||
}
|
||||
};
|
||||
|
||||
isPluginPresentInSections = (plugin: PluginRedux) => {
|
||||
return this.state.sections && this.state.sections.indexOf(`plugin_${plugin.id}`) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
renderPluginsMenu = () => {
|
||||
const {config, plugins} = this.props;
|
||||
@@ -279,12 +279,12 @@ class AdminSidebar extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
handleClearFilter = () => {
|
||||
this.setState({sections: null, filter: ''});
|
||||
this.props.onFilterChange('');
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {showTaskList} = this.props;
|
||||
|
||||
@@ -226,9 +226,9 @@ export const InvoiceInfo = ({invoice, product, fullCharges, partialCharges, hasM
|
||||
currency='USD'
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='admin.billing.subscriptions.billing_summary.lastInvoice.userCount'
|
||||
defaultMessage=' x {users} users'
|
||||
values={{users: charge.quantity}}
|
||||
id='admin.billing.subscriptions.billing_summary.lastInvoice.seatCount'
|
||||
defaultMessage=' x {seats} seats'
|
||||
values={{seats: charge.quantity}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@@ -309,9 +309,9 @@ export const InvoiceInfo = ({invoice, product, fullCharges, partialCharges, hasM
|
||||
>
|
||||
<div className='BillingSummary__lastInvoice-chargeDescription'>
|
||||
<FormattedMessage
|
||||
id='admin.billing.subscriptions.billing_summary.lastInvoice.userCountPartial'
|
||||
defaultMessage='{users} users'
|
||||
values={{users: charge.quantity}}
|
||||
id='admin.billing.subscriptions.billing_summary.lastInvoice.seatCountPartial'
|
||||
defaultMessage='{seats} seats'
|
||||
values={{seats: charge.quantity}}
|
||||
/>
|
||||
</div>
|
||||
<div className='BillingSummary__lastInvoice-chargeAmount'>
|
||||
|
||||
@@ -15,8 +15,6 @@ import {isCloudLicense} from 'utils/license_utils';
|
||||
|
||||
import {getCloudSubscription, getSubscriptionProduct} from 'mattermost-redux/selectors/entities/cloud';
|
||||
|
||||
import ExternalLink from 'components/external_link';
|
||||
|
||||
import DeleteWorkspaceModal from './delete_workspace_modal';
|
||||
|
||||
export default function DeleteWorkspaceCTA() {
|
||||
@@ -80,17 +78,15 @@ export default function DeleteWorkspaceCTA() {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<ExternalLink
|
||||
href=''
|
||||
location='delete_workspace_cta'
|
||||
className='cancelSubscriptionSection__contactUs'
|
||||
<button
|
||||
className='btn cancelSubscriptionSection__contactUs'
|
||||
onClick={handleOnClickDelete}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='admin.billing.subscription.deleteWorkspaceSection.delete'
|
||||
defaultMessage='Delete Workspace'
|
||||
/>
|
||||
</ExternalLink>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -51,28 +51,28 @@ describe('InvoiceUserCount', () => {
|
||||
[1, InvoiceLineItemType.Full],
|
||||
[1, InvoiceLineItemType.Partial],
|
||||
),
|
||||
expected: '1 metered users, 1 users at full rate, 1 users with partial charges',
|
||||
expected: '1 metered seats, 1 seats at full rate, 1 seats with partial charges',
|
||||
},
|
||||
{
|
||||
name: 'Supports cloud invoices with only metered line items',
|
||||
invoice: makeInvoice(
|
||||
[12.34, InvoiceLineItemType.Metered],
|
||||
),
|
||||
expected: '12.34 users',
|
||||
expected: '12.34 seats',
|
||||
},
|
||||
{
|
||||
name: 'Shows minimum decimal necessary',
|
||||
invoice: makeInvoice(
|
||||
[12.499, InvoiceLineItemType.Metered],
|
||||
),
|
||||
expected: '12.5 users',
|
||||
expected: '12.5 seats',
|
||||
},
|
||||
{
|
||||
name: 'hides insignificant decimals',
|
||||
invoice: makeInvoice(
|
||||
[12.002, InvoiceLineItemType.Metered],
|
||||
),
|
||||
expected: '12 users',
|
||||
expected: '12 seats',
|
||||
},
|
||||
{
|
||||
name: 'Supports cloud invoices with only non-metered line items',
|
||||
@@ -80,7 +80,7 @@ describe('InvoiceUserCount', () => {
|
||||
[1, InvoiceLineItemType.Full],
|
||||
[249, InvoiceLineItemType.Partial],
|
||||
),
|
||||
expected: '1 users at full rate, 249 users with partial charges',
|
||||
expected: '1 seats at full rate, 249 seats with partial charges',
|
||||
},
|
||||
{
|
||||
name: 'Shows default of 0 full users, 0 partial users when there are no users',
|
||||
@@ -89,19 +89,19 @@ describe('InvoiceUserCount', () => {
|
||||
[0, InvoiceLineItemType.Full],
|
||||
[0, InvoiceLineItemType.Partial],
|
||||
),
|
||||
expected: '0 users at full rate, 0 users with partial charges',
|
||||
expected: '0 seats at full rate, 0 seats with partial charges',
|
||||
},
|
||||
{
|
||||
name: 'Shows default of 0 full users, 0 partial users when there are no line items in invoice',
|
||||
invoice: makeInvoice(),
|
||||
expected: '0 users at full rate, 0 users with partial charges',
|
||||
expected: '0 seats at full rate, 0 seats with partial charges',
|
||||
},
|
||||
{
|
||||
name: 'Shows 3 full userswhen there are on prem users',
|
||||
invoice: makeInvoice(
|
||||
[3, InvoiceLineItemType.OnPremise],
|
||||
),
|
||||
expected: '3 users',
|
||||
expected: '3 seats',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ export default function InvoiceUserCount({invoice}: {invoice: Invoice}): JSX.Ele
|
||||
if (onPremUsers) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='admin.billing.history.onPremUsers'
|
||||
defaultMessage='{num} users'
|
||||
id='admin.billing.history.onPremSeats'
|
||||
defaultMessage='{num} seats'
|
||||
values={{
|
||||
|
||||
// should always be a whole number, but truncate just in case
|
||||
@@ -32,12 +32,12 @@ export default function InvoiceUserCount({invoice}: {invoice: Invoice}): JSX.Ele
|
||||
if (fullUsers || partialUsers) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='admin.billing.history.fractionalAndRatedUsers'
|
||||
defaultMessage='{fractionalUsers} metered users, {fullUsers} users at full rate, {partialUsers} users with partial charges'
|
||||
id='admin.billing.history.fractionalAndRatedSeats'
|
||||
defaultMessage='{fractionalSeats} metered seats, {fullSeats} seats at full rate, {partialSeats} seats with partial charges'
|
||||
values={{
|
||||
fractionalUsers: numberToFixedDynamic(meteredUsers, 2),
|
||||
fullUsers: fullUsers.toFixed(0),
|
||||
partialUsers: partialUsers.toFixed(0),
|
||||
fractionalSeats: numberToFixedDynamic(meteredUsers, 2),
|
||||
fullSeats: fullUsers.toFixed(0),
|
||||
partialSeats: partialUsers.toFixed(0),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -45,10 +45,10 @@ export default function InvoiceUserCount({invoice}: {invoice: Invoice}): JSX.Ele
|
||||
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='admin.billing.history.fractionalUsers'
|
||||
defaultMessage='{fractionalUsers} users'
|
||||
id='admin.billing.history.fractionalSeats'
|
||||
defaultMessage='{fractionalSeats} seats'
|
||||
values={{
|
||||
fractionalUsers: numberToFixedDynamic(meteredUsers, 2),
|
||||
fractionalSeats: numberToFixedDynamic(meteredUsers, 2),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -56,11 +56,11 @@ export default function InvoiceUserCount({invoice}: {invoice: Invoice}): JSX.Ele
|
||||
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='admin.billing.history.usersAndRates'
|
||||
defaultMessage='{fullUsers} users at full rate, {partialUsers} users with partial charges'
|
||||
id='admin.billing.history.seatsAndRates'
|
||||
defaultMessage='{fullSeats} seats at full rate, {partialSeats} seats with partial charges'
|
||||
values={{
|
||||
fullUsers: fullUsers.toFixed(0),
|
||||
partialUsers: partialUsers.toFixed(0),
|
||||
fullSeats: fullUsers.toFixed(0),
|
||||
partialSeats: partialUsers.toFixed(0),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ export default class BleveSettings extends AdminSettings {
|
||||
config.BleveSettings.EnableAutocomplete = this.state.enableAutocomplete;
|
||||
|
||||
return config;
|
||||
}
|
||||
};
|
||||
|
||||
getStateFromConfig(config) {
|
||||
return {
|
||||
@@ -55,17 +55,17 @@ export default class BleveSettings extends AdminSettings {
|
||||
}
|
||||
|
||||
this.handleChange(id, value);
|
||||
}
|
||||
};
|
||||
|
||||
handleSaved = () => {
|
||||
this.setState({
|
||||
canPurgeAndIndex: this.state.enableIndexing && this.state.indexDir !== '',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
canSave = () => {
|
||||
return this.state.canSave;
|
||||
}
|
||||
};
|
||||
|
||||
getExtraInfo(job) {
|
||||
if (job.status === JobStatuses.IN_PROGRESS) {
|
||||
@@ -246,5 +246,5 @@ export default class BleveSettings extends AdminSettings {
|
||||
/>
|
||||
</SettingsGroup>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ export default class BooleanSetting extends React.PureComponent<Props> {
|
||||
|
||||
private handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.props.onChange(this.props.id, e.target.value === 'true');
|
||||
}
|
||||
};
|
||||
|
||||
public render() {
|
||||
let helpText;
|
||||
|
||||
@@ -29,7 +29,7 @@ export default class ClusterSettings extends AdminSettings {
|
||||
config.ClusterSettings.GossipPort = this.parseIntNonZero(this.state.GossipPort, 8074);
|
||||
config.ClusterSettings.StreamingPort = this.parseIntNonZero(this.state.StreamingPort, 8075);
|
||||
return config;
|
||||
}
|
||||
};
|
||||
|
||||
getStateFromConfig(config) {
|
||||
const settings = config.ClusterSettings;
|
||||
@@ -62,7 +62,7 @@ export default class ClusterSettings extends AdminSettings {
|
||||
});
|
||||
|
||||
this.handleChange(id, value);
|
||||
}
|
||||
};
|
||||
|
||||
renderSettings = () => {
|
||||
const licenseEnabled = this.props.license.IsLicensed === 'true' && this.props.license.Cluster === 'true';
|
||||
@@ -309,7 +309,7 @@ export default class ClusterSettings extends AdminSettings {
|
||||
/>
|
||||
</SettingsGroup>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const style = {
|
||||
|
||||
@@ -15,7 +15,7 @@ export default class ClusterTable extends React.PureComponent {
|
||||
static propTypes = {
|
||||
clusterInfos: PropTypes.array.isRequired,
|
||||
reload: PropTypes.func.isRequired,
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
var versionMismatch = (
|
||||
|
||||
@@ -28,7 +28,7 @@ export default class ClusterTableContainer extends React.PureComponent {
|
||||
},
|
||||
null,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.load();
|
||||
@@ -53,7 +53,7 @@ export default class ClusterTableContainer extends React.PureComponent {
|
||||
});
|
||||
|
||||
this.load();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.state.clusterInfos == null) {
|
||||
|
||||
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Ссылка в новой задаче
Block a user