Преглед на файлове

Merge branch 'edge' into meteor-1.8

Lauri Ojansivu преди 6 години
родител
ревизия
f154c03385

+ 25 - 0
CHANGELOG.md

@@ -1,3 +1,28 @@
+# v2.76 2019-06-11 Wekan release
+
+This release adds the following new features:
+
+- [Add support for CORS headers "Access-control-allow-headers" and
+  "Access-control-expose-headers"](https://github.com/wekan/wekan/pull/2429).
+  Thanks to risacher and xet7.
+- [Support scopes in OAuth2, so that Authentication via OAuth2 with Google is now possible](https://github.com/wekan/wekan/pull/2483).
+  Thanks to moserben16.
+
+and fixes the following bugs:
+
+- [Fix Scope parsing Issue for OAuth2 Login with simple String](https://github.com/wekan/wekan/pulls/2427).
+  Thanks to DominikPf.
+- [Show attachment name in Outgoing Webhook when attachment is added to card](https://github.com/wekan/wekan/commit/992ecfefa2e46ee7321ec9b8bfc3400532e5645e).
+  Thanks to xet7. Related [#2285](https://github.com/wekan/wekan/issues/2285).
+- [Show attachment name in Outgoing Webhook when attachment is removed from card](https://github.com/wekan/wekan/commit/23ccb3b991be6d7196e59f7d68df17b8949df049).
+  Thanks to xet7. Related [#2285](https://github.com/wekan/wekan/issues/2285).
+- [Allow BoardAdmin to create board rules](https://github.com/wekan/wekan/pull/2433).
+  Thanks to road42.
+- [Fix typo](https://github.com/wekan/wekan/pull/2442).
+  Thanks to Jason-Cooke.
+
+Thanks to above GitHub users for their contributions and translators for their translations.
+
 # v2.75 2019-05-22 Wekan release
 # v2.75 2019-05-22 Wekan release
 
 
 This release adds the following new features:
 This release adds the following new features:

+ 3 - 1
Dockerfile

@@ -41,7 +41,7 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential pyth
     OAUTH2_USERNAME_MAP="" \
     OAUTH2_USERNAME_MAP="" \
     OAUTH2_FULLNAME_MAP="" \
     OAUTH2_FULLNAME_MAP="" \
     OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[] \
     OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[] \
-    OAUTH2_REQUEST_PERMISSIONS=['openid','profiles','email'] \
+    OAUTH2_REQUEST_PERMISSIONS='openid profiles email' \
     OAUTH2_EMAIL_MAP="" \
     OAUTH2_EMAIL_MAP="" \
     LDAP_ENABLE=false \
     LDAP_ENABLE=false \
     LDAP_PORT=389 \
     LDAP_PORT=389 \
@@ -99,6 +99,8 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential pyth
     LOGOUT_ON_HOURS="" \
     LOGOUT_ON_HOURS="" \
     LOGOUT_ON_MINUTES="" \
     LOGOUT_ON_MINUTES="" \
     CORS="" \
     CORS="" \
+    CORS_ALLOW_HEADERS="" \
+    CORS_EXPOSE_HEADERS="" \
     DEFAULT_AUTHENTICATION_METHOD=""
     DEFAULT_AUTHENTICATION_METHOD=""
 
 
 # Copy the app to the image
 # Copy the app to the image

+ 2 - 2
README.md

@@ -61,7 +61,7 @@ that by providing one-click installation on various platforms.
 - 64bit: Linux [Snap](https://github.com/wekan/wekan-snap/wiki/Install) or [Sandstorm](https://sandstorm.io) /
 - 64bit: Linux [Snap](https://github.com/wekan/wekan-snap/wiki/Install) or [Sandstorm](https://sandstorm.io) /
   [Mac](https://github.com/wekan/wekan/wiki/Mac) / [Windows](https://github.com/wekan/wekan/wiki/Install-Wekan-from-source-on-Windows).
   [Mac](https://github.com/wekan/wekan/wiki/Mac) / [Windows](https://github.com/wekan/wekan/wiki/Install-Wekan-from-source-on-Windows).
   [More Platforms](https://github.com/wekan/wekan/wiki/Platforms). [ARM progress](https://github.com/wekan/wekan/issues/1053#issuecomment-410919264).
   [More Platforms](https://github.com/wekan/wekan/wiki/Platforms). [ARM progress](https://github.com/wekan/wekan/issues/1053#issuecomment-410919264).
-- 1 GB RAM minimum free for Wekan. Production server should have miminum total 4 GB RAM.
+- 1 GB RAM minimum free for Wekan. Production server should have minimum total 4 GB RAM.
   For thousands of users, for example with [Docker](https://github.com/wekan/wekan/blob/devel/docker-compose.yml): 3 frontend servers,
   For thousands of users, for example with [Docker](https://github.com/wekan/wekan/blob/devel/docker-compose.yml): 3 frontend servers,
   each having 2 CPU and 2 wekan-app containers. One backend wekan-db server with many CPUs.  
   each having 2 CPU and 2 wekan-app containers. One backend wekan-db server with many CPUs.  
 - Enough disk space and alerts about low disk space. If you run out disk space, MongoDB database gets corrupted.
 - Enough disk space and alerts about low disk space. If you run out disk space, MongoDB database gets corrupted.
@@ -136,4 +136,4 @@ with [Meteor](https://www.meteor.com).
 [wekan_chat]: https://community.vanila.io/wekan
 [wekan_chat]: https://community.vanila.io/wekan
 
 
 
 
-[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwekan%2Fwekan.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fwekan%2Fwekan?ref=badge_large)
+[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwekan%2Fwekan.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fwekan%2Fwekan?ref=badge_large)

+ 1 - 1
Stackerfile.yml

@@ -1,5 +1,5 @@
 appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
 appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
-appVersion: "v2.75.0"
+appVersion: "v2.76.0"
 files:
 files:
   userUploads:
   userUploads:
     - README.md
     - README.md

+ 5 - 0
client/components/boards/boardHeader.jade

@@ -85,10 +85,15 @@ template(name="boardHeaderBar")
         if Filter.isActive
         if Filter.isActive
           a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}")
           a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}")
             i.fa.fa-times-thin
             i.fa.fa-times-thin
+            
       if currentUser.isAdmin
       if currentUser.isAdmin
         a.board-header-btn.js-open-rules-view(title="{{_ 'rules'}}")
         a.board-header-btn.js-open-rules-view(title="{{_ 'rules'}}")
           i.fa.fa-magic
           i.fa.fa-magic
           span {{_ 'rules'}}
           span {{_ 'rules'}}
+      else if currentUser.isBoardAdmin
+        a.board-header-btn.js-open-rules-view(title="{{_ 'rules'}}")
+          i.fa.fa-magic
+          span {{_ 'rules'}}
 
 
       a.board-header-btn.js-open-search-view(title="{{_ 'search'}}")
       a.board-header-btn.js-open-search-view(title="{{_ 'search'}}")
         i.fa.fa-search
         i.fa.fa-search

+ 5 - 1
docker-compose.yml

@@ -239,6 +239,10 @@ services:
       # ==== CORS =====
       # ==== CORS =====
       # CORS: Set Access-Control-Allow-Origin header.
       # CORS: Set Access-Control-Allow-Origin header.
       #- CORS=*
       #- CORS=*
+      # CORS_ALLOW_HEADERS: Set Access-Control-Allow-Headers header.  "Authorization,Content-Type" is required for cross-origin use of the API.
+      #- CORS_ALLOW_HEADERS=Authorization,Content-Type
+      # CORS_EXPOSE_HEADERS: Set Access-Control-Expose-Headers header.  This is not needed for typical CORS situations
+      #- CORS_EXPOSE_HEADERS=*
       #-----------------------------------------------------------------
       #-----------------------------------------------------------------
       # ==== MATOMO INTEGRATION ====
       # ==== MATOMO INTEGRATION ====
       # Optional: Integration with Matomo https://matomo.org that is installed to your server
       # Optional: Integration with Matomo https://matomo.org that is installed to your server
@@ -327,7 +331,7 @@ services:
       # OAUTH2 ID Token Whitelist Fields.
       # OAUTH2 ID Token Whitelist Fields.
       #- OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
       #- OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
       # OAUTH2 Request Permissions.
       # OAUTH2 Request Permissions.
-      #- OAUTH2_REQUEST_PERMISSIONS=['openid','profile','email']
+      #- OAUTH2_REQUEST_PERMISSIONS='openid profile email'
       # OAuth2 ID Mapping
       # OAuth2 ID Mapping
       #- OAUTH2_ID_MAP=
       #- OAUTH2_ID_MAP=
       # OAuth2 Username Mapping
       # OAuth2 Username Mapping

+ 2 - 2
i18n/it.i18n.json

@@ -685,9 +685,9 @@
     "default-authentication-method": "Metodo di autenticazione predefinito",
     "default-authentication-method": "Metodo di autenticazione predefinito",
     "duplicate-board": "Duplica bacheca",
     "duplicate-board": "Duplica bacheca",
     "people-number": "Il numero di persone è:",
     "people-number": "Il numero di persone è:",
-    "swimlaneDeletePopup-title": "Delete Swimlane ?",
+    "swimlaneDeletePopup-title": "Cancella diagramma swimlane ?",
     "swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
     "swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
     "restore-all": "Restore all",
     "restore-all": "Restore all",
-    "delete-all": "Delete all",
+    "delete-all": "Cancella tutto",
     "loading": "Loading, please wait."
     "loading": "Loading, please wait."
 }
 }

+ 315 - 315
i18n/pt.i18n.json

@@ -1,160 +1,160 @@
 {
 {
     "accept": "Aceitar",
     "accept": "Aceitar",
     "act-activity-notify": "Notificação de Actividade",
     "act-activity-notify": "Notificação de Actividade",
-    "act-addAttachment": "adicionado anexo __attachment__ ao cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-deleteAttachment": "excluido anexo __attachment__ do cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-addSubtask": "adicionada sub-tarefa __subtask__ ao cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-addLabel": "Adicionada etiqueta __label__ ao cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-addedLabel": "Adicionada etiqueta __label__ ao cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-removeLabel": "Removida etiqueta __label__ do cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-removedLabel": "Removida etiqueta __label__ do cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-addChecklist": "adicionada lista de verificação __checklist__ ao cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-addChecklistItem": "adicionado o item  __checklistItem__ a lista de verificação__checklist__ no cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-removeChecklist": "emovida a lista de verificação __checklist__ do cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-removeChecklistItem": "removido item __checklistItem__ da lista de verificação __checkList__ no cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-checkedItem": "marcado __checklistItem__ na lista de verificação __checklist__ no cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-uncheckedItem": "desmarcado __checklistItem__ na lista __checklist__ no cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-completeChecklist": "completada a lista de verificação __checklist__ no cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-uncompleteChecklist": "lista de verificação incompleta __checklist__ no cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-addComment": "comentou no cartão __card__: __comment__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-createBoard": "criado quadro __board__",
-    "act-createSwimlane": "criada a pista __swimlane__ no quadro __board__",
-    "act-createCard": "criado cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-createCustomField": "criado campo personalizado __customField__ no cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-createList": "adicionada lista __list__ ao quadro __board__",
-    "act-addBoardMember": "adicionado membro __member__ ao quadro __board__",
-    "act-archivedBoard": "Quadro __board__ foi Arquivado",
-    "act-archivedCard": "Cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__ foi Arquivado",
-    "act-archivedList": "Lista __list__ em pista __swimlane__ no quadro __board__ foi Arquivada",
-    "act-archivedSwimlane": "Pista __swimlane__ no quadro __board__ foi Arquivada",
-    "act-importBoard": "importado quadro __board__",
-    "act-importCard": "importado cartão  __card__ para lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-importList": "importada lista __list__ para pista __swimlane__ no quadro __board__",
-    "act-joinMember": "adicionado membro __member__ ao cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-moveCard": "movido cartão __card__ do quadro __board__ da pista  __oldSwimlane__ da lista __oldList__ para a pista __swimlane__ na lista __list__",
-    "act-moveCardToOtherBoard": "movido cartão __card__ da lista __oldList__ em pista __oldSwimlane__ no quadro __oldBoard__ para lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-removeBoardMember": "removido membro __member__ do quadro __board__",
-    "act-restoredCard": "restaurado cartão __card__ a lista __list__ em pista __swimlane__ no quadro __board__",
-    "act-unjoinMember": "removido membro __member__ do cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
+    "act-addAttachment": "adicionou o anexo __attachment__ ao cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-deleteAttachment": "apagou o anexo __attachment__ do cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-addSubtask": "adicionou a sub-tarefa __subtask__ ao cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-addLabel": "Adicionou a etiqueta __label__ ao cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-addedLabel": "Adicionou a etiqueta __label__ ao cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-removeLabel": "Removeu a etiqueta __label__ do cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-removedLabel": "Removeu a etiqueta __label__ do cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-addChecklist": "adicionoua lista de verificação __checklist__ ao cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-addChecklistItem": "adicionou o item __checklistItem__ à lista de verificação __checklist__ no cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-removeChecklist": "removeu a lista de verificação __checklist__ do cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-removeChecklistItem": "removeu o item __checklistItem__ da lista de verificação __checkList__ no cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-checkedItem": "marcou __checklistItem__ na lista de verificação __checklist__ no cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-uncheckedItem": "desmarcou __checklistItem__ na lista de verificação __checklist__ no cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-completeChecklist": "completou a lista de verificação __checklist__ no cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-uncompleteChecklist": "descompletou a lista de verificação __checklist__ no cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-addComment": "comentou no cartão __card__: __comment__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-createBoard": "criou o quadro __board__",
+    "act-createSwimlane": "criou a pista __swimlane__ no quadro __board__",
+    "act-createCard": "criou o cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-createCustomField": "criou o campo personalizado __customField__ no cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-createList": "adicionou a lista __list__ ao quadro __board__",
+    "act-addBoardMember": "adicionou o membro __member__ ao quadro __board__",
+    "act-archivedBoard": "O quadro __board__ foi movido para o Arquivo",
+    "act-archivedCard": "O cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__ foi movido para o Arquivo",
+    "act-archivedList": "A lista __list__ na pista __swimlane__ no quadro __board__ foi movida para o Arquivo",
+    "act-archivedSwimlane": "A pista __swimlane__ no quadro __board__ foi movida para o Arquivo",
+    "act-importBoard": "importou o quadro __board__",
+    "act-importCard": "importou o cartão  __card__ para a lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-importList": "importou a lista __list__ para pista __swimlane__ no quadro __board__",
+    "act-joinMember": "adicionou o membro __member__ ao cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-moveCard": "moveu o cartão __card__ do quadro __board__ da pista  __oldSwimlane__ da lista __oldList__ para a pista __swimlane__ na lista __list__",
+    "act-moveCardToOtherBoard": "moveuo cartão __card__ da lista __oldList__ na pista __oldSwimlane__ no quadro __oldBoard__ para a lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-removeBoardMember": "removeuo membro __member__ do quadro __board__",
+    "act-restoredCard": "restaurou o cartão __card__ para a lista __list__ na pista __swimlane__ no quadro __board__",
+    "act-unjoinMember": "removeu o membro __member__ do cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
     "act-withBoardTitle": "__board__",
     "act-withBoardTitle": "__board__",
     "act-withCardTitle": "[__board__] __card__",
     "act-withCardTitle": "[__board__] __card__",
-    "actions": "Ações",
-    "activities": "Atividades",
-    "activity": "Atividade",
+    "actions": "Acções",
+    "activities": "Actividades",
+    "activity": "Actividade",
     "activity-added": "adicionou %s a %s",
     "activity-added": "adicionou %s a %s",
-    "activity-archived": "%s foi Arquivado",
+    "activity-archived": "%s foi movido para o Arquivo",
     "activity-attached": "anexou %s a %s",
     "activity-attached": "anexou %s a %s",
     "activity-created": "criou %s",
     "activity-created": "criou %s",
-    "activity-customfield-created": "criado campo personalizado %s",
+    "activity-customfield-created": "criado o campo personalizado %s",
     "activity-excluded": "excluiu %s de %s",
     "activity-excluded": "excluiu %s de %s",
-    "activity-imported": "importado %s em %s de %s",
-    "activity-imported-board": "importado %s de %s",
+    "activity-imported": "importou %s para %s de %s",
+    "activity-imported-board": "importou %s de %s",
     "activity-joined": "juntou-se a %s",
     "activity-joined": "juntou-se a %s",
     "activity-moved": "moveu %s de %s para %s",
     "activity-moved": "moveu %s de %s para %s",
     "activity-on": "em %s",
     "activity-on": "em %s",
     "activity-removed": "removeu %s de %s",
     "activity-removed": "removeu %s de %s",
-    "activity-sent": "enviou %s de %s",
+    "activity-sent": "enviou %s para %s",
     "activity-unjoined": "saiu de %s",
     "activity-unjoined": "saiu de %s",
-    "activity-subtask-added": "Adicionar sub-tarefa à",
-    "activity-checked-item": "marcado %s na lista de verificação %s de %s",
-    "activity-unchecked-item": "desmarcado %s na lista de verificação %s de %s",
-    "activity-checklist-added": "Adicionada lista de verificação a %s",
-    "activity-checklist-removed": "removida a lista de verificação de %s",
-    "activity-checklist-completed": "completada a lista de verificação __checklist__ no cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "activity-checklist-uncompleted": "não-completada a lista de verificação %s de %s",
-    "activity-checklist-item-added": "adicionado o item de lista de verificação para '%s' em %s",
-    "activity-checklist-item-removed": "removida o item de lista de verificação de '%s' na %s",
-    "add": "Novo",
-    "activity-checked-item-card": "marcado %s na lista de verificação %s",
-    "activity-unchecked-item-card": "desmarcado %s na lista de verificação %s",
-    "activity-checklist-completed-card": "completada a lista de verificação __checklist__ no cartão __card__ na lista __list__ em pista __swimlane__ no quadro __board__",
-    "activity-checklist-uncompleted-card": "não-completada a lista de verificação %s",
-    "add-attachment": "Adicionar Anexos",
+    "activity-subtask-added": "adicionou a sub-tarefa a",
+    "activity-checked-item": "marcou %s na lista de verificação %s de %s",
+    "activity-unchecked-item": "desmarcou %s na lista de verificação %s de %s",
+    "activity-checklist-added": "adicionou a lista de verificação a %s",
+    "activity-checklist-removed": "removeu a lista de verificação de %s",
+    "activity-checklist-completed": "completou a lista de verificação __checklist__ no cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "activity-checklist-uncompleted": "descompletou a lista de verificação %s de %s",
+    "activity-checklist-item-added": "adicionou o item a '%s' em %s",
+    "activity-checklist-item-removed": "removeu o item de '%s' na %s",
+    "add": "Adicionar",
+    "activity-checked-item-card": "marcou %s na lista de verificação %s",
+    "activity-unchecked-item-card": "desmarcou %s na lista de verificação %s",
+    "activity-checklist-completed-card": "completou a lista de verificação __checklist__ no cartão __card__ na lista __list__ na pista __swimlane__ no quadro __board__",
+    "activity-checklist-uncompleted-card": "descompletou a lista de verificação %s",
+    "add-attachment": "Adicionar Anexo",
     "add-board": "Adicionar Quadro",
     "add-board": "Adicionar Quadro",
     "add-card": "Adicionar Cartão",
     "add-card": "Adicionar Cartão",
     "add-swimlane": "Adicionar Pista",
     "add-swimlane": "Adicionar Pista",
-    "add-subtask": "Adicionar sub-tarefa",
-    "add-checklist": "Adicionar lista de verificação",
+    "add-subtask": "Adicionar Sub-tarefa",
+    "add-checklist": "Adicionar Lista de Verificação",
     "add-checklist-item": "Adicionar um item à lista de verificação",
     "add-checklist-item": "Adicionar um item à lista de verificação",
     "add-cover": "Adicionar Capa",
     "add-cover": "Adicionar Capa",
     "add-label": "Adicionar Etiqueta",
     "add-label": "Adicionar Etiqueta",
     "add-list": "Adicionar Lista",
     "add-list": "Adicionar Lista",
     "add-members": "Adicionar Membros",
     "add-members": "Adicionar Membros",
-    "added": "Criado",
+    "added": "Adicionado",
     "addMemberPopup-title": "Membros",
     "addMemberPopup-title": "Membros",
     "admin": "Administrador",
     "admin": "Administrador",
     "admin-desc": "Pode ver e editar cartões, remover membros e alterar configurações do quadro.",
     "admin-desc": "Pode ver e editar cartões, remover membros e alterar configurações do quadro.",
     "admin-announcement": "Anúncio",
     "admin-announcement": "Anúncio",
-    "admin-announcement-active": "Anúncio ativo em todo o sistema",
+    "admin-announcement-active": "Anúncio Activo em Todo o Sistema",
     "admin-announcement-title": "Anúncio do Administrador",
     "admin-announcement-title": "Anúncio do Administrador",
     "all-boards": "Todos os quadros",
     "all-boards": "Todos os quadros",
     "and-n-other-card": "E __count__ outro cartão",
     "and-n-other-card": "E __count__ outro cartão",
     "and-n-other-card_plural": "E __count__ outros cartões",
     "and-n-other-card_plural": "E __count__ outros cartões",
     "apply": "Aplicar",
     "apply": "Aplicar",
-    "app-is-offline": "A carregar, por favor espere. Atualizar a página causará perda de dados. Se a carga não funcionar, por favor verifique se o servidor não caiu.",
+    "app-is-offline": "A carregar, por favor aguarde. Actualizar a página causará perda de dados. Se o carregamento não funcionar, por favor verifique se o servidor não parou.",
     "archive": "Mover para o Arquivo",
     "archive": "Mover para o Arquivo",
     "archive-all": "Mover Tudo para o Arquivo",
     "archive-all": "Mover Tudo para o Arquivo",
-    "archive-board": "Mover Quadro para o Arquivo",
-    "archive-card": "Mover Cartão para o Arquivo",
-    "archive-list": "Mover Lista para o Arquivo",
-    "archive-swimlane": "Mover Pista para Arquivo",
-    "archive-selection": "Mover seleção para o Arquivo",
-    "archiveBoardPopup-title": "Mover Quadro para o Arquivo?",
+    "archive-board": "Mover o Quadro para o Arquivo",
+    "archive-card": "Mover o Cartão para o Arquivo",
+    "archive-list": "Mover a Lista para o Arquivo",
+    "archive-swimlane": "Mover a Pista para o Arquivo",
+    "archive-selection": "Mover a selecção para o Arquivo",
+    "archiveBoardPopup-title": "Mover o Quadro para o Arquivo?",
     "archived-items": "Arquivo",
     "archived-items": "Arquivo",
     "archived-boards": "Quadros no Arquivo",
     "archived-boards": "Quadros no Arquivo",
     "restore-board": "Restaurar Quadro",
     "restore-board": "Restaurar Quadro",
     "no-archived-boards": "Sem Quadros no Arquivo.",
     "no-archived-boards": "Sem Quadros no Arquivo.",
-    "archives": "Arquivos",
+    "archives": "Arquivo",
     "template": "Modelo",
     "template": "Modelo",
     "templates": "Modelos",
     "templates": "Modelos",
     "assign-member": "Atribuir Membro",
     "assign-member": "Atribuir Membro",
     "attached": "anexado",
     "attached": "anexado",
     "attachment": "Anexo",
     "attachment": "Anexo",
-    "attachment-delete-pop": "Excluir um anexo é permanente. Não será possível recuperá-lo.",
-    "attachmentDeletePopup-title": "Excluir Anexo?",
+    "attachment-delete-pop": "Apagar um anexo é permanente. Não será possível recuperá-lo.",
+    "attachmentDeletePopup-title": "Apagar Anexo?",
     "attachments": "Anexos",
     "attachments": "Anexos",
-    "auto-watch": "Veja automaticamente os boards que são criados",
-    "avatar-too-big": "O avatar é muito grande (70KB max)",
+    "auto-watch": "Observar automaticamente os quadros quando são criados",
+    "avatar-too-big": "O avatar é muito grande (70KB máx)",
     "back": "Voltar",
     "back": "Voltar",
     "board-change-color": "Alterar cor",
     "board-change-color": "Alterar cor",
     "board-nb-stars": "%s estrelas",
     "board-nb-stars": "%s estrelas",
     "board-not-found": "Quadro não encontrado",
     "board-not-found": "Quadro não encontrado",
     "board-private-info": "Este quadro será <strong>privado</strong>.",
     "board-private-info": "Este quadro será <strong>privado</strong>.",
     "board-public-info": "Este quadro será <strong>público</strong>.",
     "board-public-info": "Este quadro será <strong>público</strong>.",
-    "boardChangeColorPopup-title": "Alterar Tela de Fundo",
+    "boardChangeColorPopup-title": "Alterar Imagem de Fundo do Quadro",
     "boardChangeTitlePopup-title": "Renomear Quadro",
     "boardChangeTitlePopup-title": "Renomear Quadro",
     "boardChangeVisibilityPopup-title": "Alterar Visibilidade",
     "boardChangeVisibilityPopup-title": "Alterar Visibilidade",
-    "boardChangeWatchPopup-title": "Alterar observação",
-    "boardMenuPopup-title": "Configurações do quadro",
+    "boardChangeWatchPopup-title": "Alterar Observação",
+    "boardMenuPopup-title": "Configurações do Quadro",
     "boards": "Quadros",
     "boards": "Quadros",
-    "board-view": "Visão de quadro",
+    "board-view": "Visão do Quadro",
     "board-view-cal": "Calendário",
     "board-view-cal": "Calendário",
     "board-view-swimlanes": "Pistas",
     "board-view-swimlanes": "Pistas",
     "board-view-lists": "Listas",
     "board-view-lists": "Listas",
-    "bucket-example": "\"Bucket List\", por exemplo",
+    "bucket-example": "\"Lista de Desejos\", por exemplo",
     "cancel": "Cancelar",
     "cancel": "Cancelar",
-    "card-archived": "Este cartão está Arquivado.",
-    "board-archived": "Este quadro está Arquivado.",
-    "card-comments-title": "Este cartão possui %s comentários.",
-    "card-delete-notice": "A exclusão será permanente. Perderá todas as ações associadas a este cartão.",
-    "card-delete-pop": "Todas as ações serão excluídas da lista de Atividades e não poderá reabrir o cartão. Não há como desfazer.",
+    "card-archived": "Este cartão no Arquivo.",
+    "board-archived": "Este quadro está no Arquivo.",
+    "card-comments-title": "Este cartão possui %s comentário.",
+    "card-delete-notice": "A remoção será permanente. Perderá todas as acções associadas a este cartão.",
+    "card-delete-pop": "Todas as acções serão removidas do feed de Actividade e não poderá reabrir o cartão. Não há como desfazer.",
     "card-delete-suggest-archive": "Pode mover um cartão para o Arquivo para removê-lo do quadro e preservar a atividade.",
     "card-delete-suggest-archive": "Pode mover um cartão para o Arquivo para removê-lo do quadro e preservar a atividade.",
-    "card-due": "Data fim",
-    "card-due-on": "Finaliza em",
+    "card-due": "Data limite",
+    "card-due-on": "Data limite em",
     "card-spent": "Tempo Gasto",
     "card-spent": "Tempo Gasto",
     "card-edit-attachments": "Editar anexos",
     "card-edit-attachments": "Editar anexos",
     "card-edit-custom-fields": "Editar campos personalizados",
     "card-edit-custom-fields": "Editar campos personalizados",
     "card-edit-labels": "Editar etiquetas",
     "card-edit-labels": "Editar etiquetas",
     "card-edit-members": "Editar membros",
     "card-edit-members": "Editar membros",
-    "card-labels-title": "Alterar etiquetas do cartão.",
+    "card-labels-title": "Alterar as etiquetas do cartão.",
     "card-members-title": "Acrescentar ou remover membros do quadro deste cartão.",
     "card-members-title": "Acrescentar ou remover membros do quadro deste cartão.",
-    "card-start": "Data início",
-    "card-start-on": "Começa em",
+    "card-start": "Data de início",
+    "card-start-on": "Inicia em",
     "cardAttachmentsPopup-title": "Anexar a partir de",
     "cardAttachmentsPopup-title": "Anexar a partir de",
-    "cardCustomField-datePopup-title": "Mudar data",
+    "cardCustomField-datePopup-title": "Alterar a data",
     "cardCustomFieldsPopup-title": "Editar campos personalizados",
     "cardCustomFieldsPopup-title": "Editar campos personalizados",
-    "cardDeletePopup-title": "Excluir Cartão?",
-    "cardDetailsActionsPopup-title": "Ações do cartão",
+    "cardDeletePopup-title": "Apagar Cartão?",
+    "cardDetailsActionsPopup-title": "Acções do Cartão",
     "cardLabelsPopup-title": "Etiquetas",
     "cardLabelsPopup-title": "Etiquetas",
     "cardMembersPopup-title": "Membros",
     "cardMembersPopup-title": "Membros",
     "cardMorePopup-title": "Mais",
     "cardMorePopup-title": "Mais",
@@ -163,25 +163,25 @@
     "cards-count": "Cartões",
     "cards-count": "Cartões",
     "casSignIn": "Entrar com CAS",
     "casSignIn": "Entrar com CAS",
     "cardType-card": "Cartão",
     "cardType-card": "Cartão",
-    "cardType-linkedCard": "Cartão ligado",
-    "cardType-linkedBoard": "Quadro ligado",
+    "cardType-linkedCard": "Cartão Ligado",
+    "cardType-linkedBoard": "Quadro Ligado",
     "change": "Alterar",
     "change": "Alterar",
-    "change-avatar": "Alterar Avatar",
-    "change-password": "Alterar Senha",
-    "change-permissions": "Alterar permissões",
-    "change-settings": "Altera configurações",
-    "changeAvatarPopup-title": "Alterar Avatar",
-    "changeLanguagePopup-title": "Alterar Idioma",
-    "changePasswordPopup-title": "Alterar Senha",
-    "changePermissionsPopup-title": "Alterar Permissões",
-    "changeSettingsPopup-title": "Altera configurações",
+    "change-avatar": "Alterar o Avatar",
+    "change-password": "Alterar a Senha",
+    "change-permissions": "Alterar as permissões",
+    "change-settings": "Alterar as Configurações",
+    "changeAvatarPopup-title": "Alterar o Avatar",
+    "changeLanguagePopup-title": "Alterar o Idioma",
+    "changePasswordPopup-title": "Alterar a Senha",
+    "changePermissionsPopup-title": "Alterar as Permissões",
+    "changeSettingsPopup-title": "Alterar as Configurações",
     "subtasks": "Sub-tarefas",
     "subtasks": "Sub-tarefas",
     "checklists": "Listas de verificação",
     "checklists": "Listas de verificação",
-    "click-to-star": "Marcar quadro como favorito.",
-    "click-to-unstar": "Remover quadro dos favoritos.",
+    "click-to-star": "Clique para marcar este quadro como favorito.",
+    "click-to-unstar": "Clique para remover este quadro dos favoritos.",
     "clipboard": "Área de Transferência ou arraste e solte",
     "clipboard": "Área de Transferência ou arraste e solte",
     "close": "Fechar",
     "close": "Fechar",
-    "close-board": "Fechar Quadro",
+    "close-board": "Fechar o Quadro",
     "close-board-pop": "Poderá restaurar o quadro clicando no botão “Arquivo” a partir do cabeçalho do Início.",
     "close-board-pop": "Poderá restaurar o quadro clicando no botão “Arquivo” a partir do cabeçalho do Início.",
     "color-black": "preto",
     "color-black": "preto",
     "color-blue": "azul",
     "color-blue": "azul",
@@ -209,105 +209,105 @@
     "color-white": "branco",
     "color-white": "branco",
     "color-yellow": "amarelo",
     "color-yellow": "amarelo",
     "unset-color": "Remover",
     "unset-color": "Remover",
-    "comment": "Comentário",
-    "comment-placeholder": "Escrever Comentário",
-    "comment-only": "Somente comentários",
+    "comment": "Comentar",
+    "comment-placeholder": "Escrever o Comentário",
+    "comment-only": "Apenas comentários",
     "comment-only-desc": "Pode comentar apenas em cartões.",
     "comment-only-desc": "Pode comentar apenas em cartões.",
     "no-comments": "Sem comentários",
     "no-comments": "Sem comentários",
-    "no-comments-desc": "Sem visualização de comentários e atividades.",
+    "no-comments-desc": "Não pode ver comentários nem actividades.",
     "computer": "Computador",
     "computer": "Computador",
-    "confirm-subtask-delete-dialog": "Tem certeza que deseja excluir a sub-tarefa?",
-    "confirm-checklist-delete-dialog": "Tem certeza que quer excluir a lista de verificação?",
-    "copy-card-link-to-clipboard": "Copiar link do cartão para a área de transferência",
+    "confirm-subtask-delete-dialog": "Tem certeza que deseja apagar a sub-tarefa?",
+    "confirm-checklist-delete-dialog": "Tem certeza que quer apagar a lista de verificação?",
+    "copy-card-link-to-clipboard": "Copiar a ligação do cartão para a área de transferência",
     "linkCardPopup-title": "Ligar Cartão",
     "linkCardPopup-title": "Ligar Cartão",
-    "searchElementPopup-title": "Buscar",
+    "searchElementPopup-title": "Procurar",
     "copyCardPopup-title": "Copiar o cartão",
     "copyCardPopup-title": "Copiar o cartão",
-    "copyChecklistToManyCardsPopup-title": "Copiar modelo de lista de verificação para vários cartões",
-    "copyChecklistToManyCardsPopup-instructions": "Títulos e descrições do cartão de destino neste formato JSON",
+    "copyChecklistToManyCardsPopup-title": "Copiar o Modelo de Lista de Verificação para Vários Cartões",
+    "copyChecklistToManyCardsPopup-instructions": "Títulos e Descrições de Cartões de Destino neste formato JSON",
     "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"Título do primeiro cartão\", \"description\":\"Descrição do primeiro cartão\"}, {\"title\":\"Título do segundo cartão\",\"description\":\"Descrição do segundo cartão\"},{\"title\":\"Título do último cartão\",\"description\":\"Descrição do último cartão\"} ]",
     "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"Título do primeiro cartão\", \"description\":\"Descrição do primeiro cartão\"}, {\"title\":\"Título do segundo cartão\",\"description\":\"Descrição do segundo cartão\"},{\"title\":\"Título do último cartão\",\"description\":\"Descrição do último cartão\"} ]",
     "create": "Criar",
     "create": "Criar",
     "createBoardPopup-title": "Criar Quadro",
     "createBoardPopup-title": "Criar Quadro",
     "chooseBoardSourcePopup-title": "Importar quadro",
     "chooseBoardSourcePopup-title": "Importar quadro",
     "createLabelPopup-title": "Criar Etiqueta",
     "createLabelPopup-title": "Criar Etiqueta",
-    "createCustomField": "Criar campo",
-    "createCustomFieldPopup-title": "Criar campo",
-    "current": "atual",
-    "custom-field-delete-pop": "Não existe desfazer. Isso irá excluir o campo personalizado de todos os cartões e destruir seu histórico",
-    "custom-field-checkbox": "Caixa de seleção",
+    "createCustomField": "Criar Campo",
+    "createCustomFieldPopup-title": "Criar Campo",
+    "current": "actual",
+    "custom-field-delete-pop": "Não existe desfazer. Isto irá remover este campo personalizado de todos os cartões e destruir o seu histórico",
+    "custom-field-checkbox": "Caixa de selecção",
     "custom-field-date": "Data",
     "custom-field-date": "Data",
-    "custom-field-dropdown": "Lista suspensa",
+    "custom-field-dropdown": "Lista Suspensa",
     "custom-field-dropdown-none": "(nada)",
     "custom-field-dropdown-none": "(nada)",
-    "custom-field-dropdown-options": "Lista de opções",
+    "custom-field-dropdown-options": "Opções da Lista",
     "custom-field-dropdown-options-placeholder": "Pressione enter para adicionar mais opções",
     "custom-field-dropdown-options-placeholder": "Pressione enter para adicionar mais opções",
     "custom-field-dropdown-unknown": "(desconhecido)",
     "custom-field-dropdown-unknown": "(desconhecido)",
     "custom-field-number": "Número",
     "custom-field-number": "Número",
     "custom-field-text": "Texto",
     "custom-field-text": "Texto",
-    "custom-fields": "Campos personalizados",
+    "custom-fields": "Campos Personalizados",
     "date": "Data",
     "date": "Data",
     "decline": "Rejeitar",
     "decline": "Rejeitar",
-    "default-avatar": "Avatar padrão",
-    "delete": "Excluir",
-    "deleteCustomFieldPopup-title": "Excluir campo personalizado?",
-    "deleteLabelPopup-title": "Excluir Etiqueta?",
+    "default-avatar": "Avatar por omissão",
+    "delete": "Apagar",
+    "deleteCustomFieldPopup-title": "Apagar o Campo Personalizado?",
+    "deleteLabelPopup-title": "Apagar a Etiqueta?",
     "description": "Descrição",
     "description": "Descrição",
-    "disambiguateMultiLabelPopup-title": "Desambiguar ações de etiquetas",
-    "disambiguateMultiMemberPopup-title": "Desambiguar ações de membros",
+    "disambiguateMultiLabelPopup-title": "Desambiguar Acção da Etiqueta",
+    "disambiguateMultiMemberPopup-title": "Desambiguar Acção do Membro",
     "discard": "Descartar",
     "discard": "Descartar",
     "done": "Feito",
     "done": "Feito",
-    "download": "Baixar",
+    "download": "Descarregar",
     "edit": "Editar",
     "edit": "Editar",
-    "edit-avatar": "Alterar Avatar",
-    "edit-profile": "Editar Perfil",
-    "edit-wip-limit": "Editar Limite WIP",
-    "soft-wip-limit": "Limite de WIP",
-    "editCardStartDatePopup-title": "Altera data de início",
-    "editCardDueDatePopup-title": "Altera data fim",
-    "editCustomFieldPopup-title": "Editar campo",
-    "editCardSpentTimePopup-title": "Editar tempo gasto",
-    "editLabelPopup-title": "Alterar Etiqueta",
-    "editNotificationPopup-title": "Editar Notificações",
-    "editProfilePopup-title": "Editar Perfil",
+    "edit-avatar": "Alterar o Avatar",
+    "edit-profile": "Editar o Perfil",
+    "edit-wip-limit": "Editar o Limite WIP",
+    "soft-wip-limit": "Limite Suave de WIP",
+    "editCardStartDatePopup-title": "Alterar a data de início",
+    "editCardDueDatePopup-title": "Alterar a data limite",
+    "editCustomFieldPopup-title": "Editar Campo",
+    "editCardSpentTimePopup-title": "Alterar o tempo gasto",
+    "editLabelPopup-title": "Alterar a Etiqueta",
+    "editNotificationPopup-title": "Editar a Notificação",
+    "editProfilePopup-title": "Editar o Perfil",
     "email": "E-mail",
     "email": "E-mail",
     "email-enrollAccount-subject": "Uma conta foi criada para si em __siteName__",
     "email-enrollAccount-subject": "Uma conta foi criada para si em __siteName__",
-    "email-enrollAccount-text": "Olá __user__\npara começar a utilizar o serviço basta clicar no link abaixo.\n__url__\nMuito Obrigado.",
-    "email-fail": "Falhou ao enviar e-mail",
-    "email-fail-text": "Erro ao tentar enviar e-mail",
+    "email-enrollAccount-text": "Olá __user__\nPara começar a utilizar o serviço, basta clicar na ligação abaixo.\n__url__\nObrigado.",
+    "email-fail": "Falhou a enviar o e-mail",
+    "email-fail-text": "Erro a tentar enviar o e-mail",
     "email-invalid": "E-mail inválido",
     "email-invalid": "E-mail inválido",
-    "email-invite": "Convite via E-mail",
-    "email-invite-subject": "__inviter__ lhe enviou um convite",
-    "email-invite-text": "Caro __user__\n__inviter__ convidou-o para se juntar ao quadro \"__board__\" como colaborador.\nPor favor prossiga através do link abaixo:\n__url__\nMuito obrigado.",
+    "email-invite": "Convidar via E-mail",
+    "email-invite-subject": "__inviter__ enviou-lhe um convite",
+    "email-invite-text": "Caro __user__\n__inviter__ convidou-o para se juntar ao quadro \"__board__\" para colaborar.\nPor favor prossiga através da ligação abaixo:\n__url__\nObrigado.",
     "email-resetPassword-subject": "Redefina sua senha em __siteName__",
     "email-resetPassword-subject": "Redefina sua senha em __siteName__",
-    "email-resetPassword-text": "Olá __user__\nPara redefinir sua senha, por favor clique no link abaixo.\n__url__\nMuito obrigado.",
+    "email-resetPassword-text": "Olá __user__\nPara redefinir a sua senha, por favor clique na ligação abaixo.\n__url__\nObrigado.",
     "email-sent": "E-mail enviado",
     "email-sent": "E-mail enviado",
-    "email-verifyEmail-subject": "Verifique seu endereço de e-mail em __siteName__",
-    "email-verifyEmail-text": "Olá __user__\nPara verificar sua conta de e-mail, clique no link abaixo.\n__url__\nObrigado.",
+    "email-verifyEmail-subject": "Verifique o seu endereço de e-mail em __siteName__",
+    "email-verifyEmail-text": "Olá __user__\nPara verificar a sua conta de e-mail, clique na ligação abaixo.\n__url__\nObrigado.",
     "enable-wip-limit": "Ativar Limite WIP",
     "enable-wip-limit": "Ativar Limite WIP",
     "error-board-doesNotExist": "Este quadro não existe",
     "error-board-doesNotExist": "Este quadro não existe",
-    "error-board-notAdmin": "Precisa ser administrador desse quadro para fazer isto",
-    "error-board-notAMember": "Precisa ser um membro desse quadro para fazer isto",
-    "error-json-malformed": "Seu texto não é um JSON válido",
-    "error-json-schema": "Seu JSON não inclui as informações no formato correto",
+    "error-board-notAdmin": "Precisa de ser administrador deste quadro para fazer isso",
+    "error-board-notAMember": "Precisa de ser um membro deste quadro para fazer isso",
+    "error-json-malformed": "O seu texto não é um JSON válido",
+    "error-json-schema": "O seu JSON não inclui as informações apropriadas no formato correto",
     "error-list-doesNotExist": "Esta lista não existe",
     "error-list-doesNotExist": "Esta lista não existe",
     "error-user-doesNotExist": "Este utilizador não existe",
     "error-user-doesNotExist": "Este utilizador não existe",
-    "error-user-notAllowSelf": "Não pode convidar a si mesmo",
+    "error-user-notAllowSelf": "Não se pode convidar a si mesmo",
     "error-user-notCreated": "Este utilizador não foi criado",
     "error-user-notCreated": "Este utilizador não foi criado",
     "error-username-taken": "Esse nome de utilizador já existe",
     "error-username-taken": "Esse nome de utilizador já existe",
-    "error-email-taken": "E-mail já está em uso",
+    "error-email-taken": "Endereço de e-mail já está em uso",
     "export-board": "Exportar quadro",
     "export-board": "Exportar quadro",
     "filter": "Filtrar",
     "filter": "Filtrar",
     "filter-cards": "Filtrar Cartões",
     "filter-cards": "Filtrar Cartões",
     "filter-clear": "Limpar filtro",
     "filter-clear": "Limpar filtro",
     "filter-no-label": "Sem etiquetas",
     "filter-no-label": "Sem etiquetas",
     "filter-no-member": "Sem membros",
     "filter-no-member": "Sem membros",
-    "filter-no-custom-fields": "Não há campos personalizados",
-    "filter-on": "Filtro está ativo",
+    "filter-no-custom-fields": "Sem Campos Personalizados",
+    "filter-on": "Filtro está activo",
     "filter-on-desc": "Está a filtrar cartões neste quadro. Clique aqui para editar o filtro.",
     "filter-on-desc": "Está a filtrar cartões neste quadro. Clique aqui para editar o filtro.",
-    "filter-to-selection": "Filtrar esta seleção",
-    "advanced-filter-label": "Filtro avançado",
-    "advanced-filter-description": "Filtros avançados permitem escrever uma \"string\" contendo os seguintes operadores: == != <= >= && || (). Um espaço é utilizado como separador entre os operadores. Pode filtrar para todos os campos personalizados escrevendo os nomes e valores. Exemplo: Campo1 == Valor1. Nota^Se o campo ou valor tiver espaços precisa encapsular eles em citações sozinhas. Exemplo: Campo1 == Eu\\sou. Também pode combinar múltiplas condições. Exemplo: C1 == V1 || C1 == V2. Normalmente todos os operadores são interpretados da esquerda para direita. Pode alterar a ordem colocando parênteses - como na expressão matemática. Exemplo: C1 == V1 && (C2 == V2 || C2 == V3). Também pode pesquisar campos de texto usando regex: C1 == /Tes.*/i",
+    "filter-to-selection": "Filtrar esta selecção",
+    "advanced-filter-label": "Filtro Avançado",
+    "advanced-filter-description": "Filtro Avançado permite escrever uma \"string\" contendo os seguintes operadores: == != <= >= && || ( ). Um espaço é usado como separador entre Operadores. Pode filtrar em todos os Campos Personalizados escreventos os seus nomes e valores. Por Exemplo: Campo1 == Valor1. Nota: Se os campos ou valores contiverem espaços, tem de os encapsular em apóstrofes. Por Exemplo: 'Campo 1' == 'Valor 1'. Para que caracteres de controlo únicos (' \\/) sejam ignorados, pode usar \\. Por exemplo: Campo1 == I\\'m. Pode também combinar múltiplas condições. Por Exemplo: F1 == V1 || F1 == V2. Normalmente todos os operadores são interpretados da esquerda para a direita. Pode alterar a ordem inserindo parênteses. Por Exemplo: F1 == V1 && ( F2 == V2 || F2 == V3 ). Pode também procurar em campos de texto utilizando uma expressão regular: F1 == /Tes.*/i",
     "fullname": "Nome Completo",
     "fullname": "Nome Completo",
-    "header-logo-title": "Voltar para a lista de quadros.",
-    "hide-system-messages": "Esconde mensagens de sistema",
+    "header-logo-title": "Voltar para a sua lista de quadros.",
+    "hide-system-messages": "Esconder mensagens de sistema",
     "headerBarCreateBoardPopup-title": "Criar Quadro",
     "headerBarCreateBoardPopup-title": "Criar Quadro",
     "home": "Início",
     "home": "Início",
     "import": "Importar",
     "import": "Importar",
@@ -316,67 +316,67 @@
     "import-board-c": "Importar quadro",
     "import-board-c": "Importar quadro",
     "import-board-title-trello": "Importar quadro do Trello",
     "import-board-title-trello": "Importar quadro do Trello",
     "import-board-title-wekan": "Importar quadro a partir de exportação prévia",
     "import-board-title-wekan": "Importar quadro a partir de exportação prévia",
-    "import-sandstorm-backup-warning": "Não exclua os dados importados do quadro original exportado ou do Trello antes de verificar se esse item fecha e abre novamente, ou se receber o erro Quadro não encontrado, que significa perda de dados.",
-    "import-sandstorm-warning": "O quadro importado irá excluir todos os dados existentes no quadro e irá sobrescrever com o quadro importado.",
+    "import-sandstorm-backup-warning": "Não apague os dados importados do quadro original exportado ou do Trello antes de verificar se esse item fecha e abre novamente, ou se receber o erro Quadro não encontrado, que significa perda de dados.",
+    "import-sandstorm-warning": "O quadro importado irá apagar todos os dados existentes no quadro e irá sobrescrever com o quadro importado.",
     "from-trello": "Do Trello",
     "from-trello": "Do Trello",
     "from-wekan": "A partir de exportação prévia",
     "from-wekan": "A partir de exportação prévia",
-    "import-board-instruction-trello": "No seu quadro do Trello, vá em 'Menu', depois em 'Mais', 'Imprimir e Exportar', 'Exportar JSON', então copie o texto emitido",
-    "import-board-instruction-wekan": "Em seu quadro vá para 'Menu', depois 'Exportar quadro' e copie o texto no arquivo baixado.",
+    "import-board-instruction-trello": "No seu quadro do Trello, vá em 'Menu', depois em 'Mais', 'Imprimir e Exportar', 'Exportar JSON', e copie o texto resultante.",
+    "import-board-instruction-wekan": "No seu quadro vá para 'Menu', depois 'Exportar quadro' e copie o texto no ficheiro descarregado.",
     "import-board-instruction-about-errors": "Se receber erros ao importar o quadro, às vezes a importação ainda funciona e o quadro está na página Todos os Quadros.",
     "import-board-instruction-about-errors": "Se receber erros ao importar o quadro, às vezes a importação ainda funciona e o quadro está na página Todos os Quadros.",
     "import-json-placeholder": "Cole seus dados JSON válidos aqui",
     "import-json-placeholder": "Cole seus dados JSON válidos aqui",
     "import-map-members": "Mapear membros",
     "import-map-members": "Mapear membros",
-    "import-members-map": "Seu quadro importado possui alguns membros. Por favor, mapeie os membros que deseja importar para seus utilizadors",
-    "import-show-user-mapping": "Revisar mapeamento dos membros",
+    "import-members-map": "O seu quadro importado possui alguns membros. Por favor, mapeie os membros que deseja importar para seus utilizadores",
+    "import-show-user-mapping": "Rever mapeamento dos membros",
     "import-user-select": "Escolha um utilizador existente que deseja usar como esse membro",
     "import-user-select": "Escolha um utilizador existente que deseja usar como esse membro",
-    "importMapMembersAddPopup-title": "Selecione membro",
+    "importMapMembersAddPopup-title": "Seleccione membro",
     "info": "Versão",
     "info": "Versão",
     "initials": "Iniciais",
     "initials": "Iniciais",
     "invalid-date": "Data inválida",
     "invalid-date": "Data inválida",
     "invalid-time": "Hora inválida",
     "invalid-time": "Hora inválida",
     "invalid-user": "Utilizador inválido",
     "invalid-user": "Utilizador inválido",
     "joined": "juntou-se",
     "joined": "juntou-se",
-    "just-invited": "Já foi convidado para este quadro",
+    "just-invited": "Acabou de ser convidado para este quadro",
     "keyboard-shortcuts": "Atalhos do teclado",
     "keyboard-shortcuts": "Atalhos do teclado",
     "label-create": "Criar Etiqueta",
     "label-create": "Criar Etiqueta",
-    "label-default": "%s etiqueta (padrão)",
-    "label-delete-pop": "Não será possível recuperá-la. A etiqueta será excluída de todos os cartões e seu histórico será destruído.",
+    "label-default": "%s etiqueta (omissão)",
+    "label-delete-pop": "Não há como desfazer. A etiqueta será apagada de todos os cartões e o seu histórico será destruído.",
     "labels": "Etiquetas",
     "labels": "Etiquetas",
     "language": "Idioma",
     "language": "Idioma",
     "last-admin-desc": "Não pode alterar funções porque deve existir pelo menos um administrador.",
     "last-admin-desc": "Não pode alterar funções porque deve existir pelo menos um administrador.",
     "leave-board": "Sair do Quadro",
     "leave-board": "Sair do Quadro",
     "leave-board-pop": "Tem a certeza de que pretende sair de __boardTitle__? Será removido de todos os cartões neste quadro.",
     "leave-board-pop": "Tem a certeza de que pretende sair de __boardTitle__? Será removido de todos os cartões neste quadro.",
-    "leaveBoardPopup-title": "Sair do Quadro?",
-    "link-card": "Vincular a este cartão",
+    "leaveBoardPopup-title": "Sair do Quadro ?",
+    "link-card": "Ligar a este cartão",
     "list-archive-cards": "Move todos os cartões nesta lista para o Arquivo",
     "list-archive-cards": "Move todos os cartões nesta lista para o Arquivo",
-    "list-archive-cards-pop": "Isto removerá todos os cartões desta lista para o quadro. Para visualizar cartões arquivados e trazê-los de volta para o quadro, clique em “Menu” > “Arquivo”.",
-    "list-move-cards": "Mover todos os cartões desta lista",
-    "list-select-cards": "Selecionar todos os cartões nesta lista",
+    "list-archive-cards-pop": "Isto irá remover todos os cartões nesta lista do quadro. Para ver os cartões no Arquivo e trazê-los de volta para o quadro, clique em “Menu” > “Arquivo”.",
+    "list-move-cards": "Mover todos os cartões nesta lista",
+    "list-select-cards": "Seleccionar todos os cartões nesta lista",
     "set-color-list": "Definir Cor",
     "set-color-list": "Definir Cor",
     "listActionPopup-title": "Listar Ações",
     "listActionPopup-title": "Listar Ações",
-    "swimlaneActionPopup-title": "Ações de Pista",
+    "swimlaneActionPopup-title": "Acções de Pista",
     "swimlaneAddPopup-title": "Adicionar uma Pista abaixo",
     "swimlaneAddPopup-title": "Adicionar uma Pista abaixo",
     "listImportCardPopup-title": "Importe um cartão do Trello",
     "listImportCardPopup-title": "Importe um cartão do Trello",
     "listMorePopup-title": "Mais",
     "listMorePopup-title": "Mais",
-    "link-list": "Vincular a esta lista",
-    "list-delete-pop": "Todas as ações serão excluídas da lista de atividades e não poderá recuperar a lista. Não há como desfazer.",
-    "list-delete-suggest-archive": "Pode mover uma lista para o Arquivo para removê-la do quadro e preservar a atividade.",
+    "link-list": "Ligar a esta lista",
+    "list-delete-pop": "Todas as acções serão removidas do feed de actividade e não poderá recuperar a lista. Não há como desfazer.",
+    "list-delete-suggest-archive": "Pode mover uma lista para o Arquivo para a remover do quadro e preservar a actividade.",
     "lists": "Listas",
     "lists": "Listas",
     "swimlanes": "Pistas",
     "swimlanes": "Pistas",
-    "log-out": "Sair",
+    "log-out": "Terminar a Sessão",
     "log-in": "Entrar",
     "log-in": "Entrar",
     "loginPopup-title": "Entrar",
     "loginPopup-title": "Entrar",
-    "memberMenuPopup-title": "Configuração de Membros",
+    "memberMenuPopup-title": "Configuração dos Membros",
     "members": "Membros",
     "members": "Membros",
     "menu": "Menu",
     "menu": "Menu",
-    "move-selection": "Mover seleção",
-    "moveCardPopup-title": "Mover Cartão",
-    "moveCardToBottom-title": "Mover para o final",
-    "moveCardToTop-title": "Mover para o topo",
-    "moveSelectionPopup-title": "Mover seleção",
-    "multi-selection": "Multi-Seleção",
-    "multi-selection-on": "Multi-seleção está ativo",
-    "muted": "Silenciar",
-    "muted-info": "Nunca receberá qualquer notificação desse quadro",
+    "move-selection": "Mover a selecção",
+    "moveCardPopup-title": "Mover o Cartão",
+    "moveCardToBottom-title": "Mover para o Fundo",
+    "moveCardToTop-title": "Mover para o Topo",
+    "moveSelectionPopup-title": "Mover a selecção",
+    "multi-selection": "Selecção Múltipla",
+    "multi-selection-on": "Selecção Múltipla está activa",
+    "muted": "Silenciado",
+    "muted-info": "Nunca será notificado de quaisquer alterações neste quadro",
     "my-boards": "Meus Quadros",
     "my-boards": "Meus Quadros",
     "name": "Nome",
     "name": "Nome",
     "no-archived-cards": "Sem cartões no Arquivo.",
     "no-archived-cards": "Sem cartões no Arquivo.",
@@ -385,29 +385,29 @@
     "no-results": "Nenhum resultado.",
     "no-results": "Nenhum resultado.",
     "normal": "Normal",
     "normal": "Normal",
     "normal-desc": "Pode ver e editar cartões. Não pode alterar configurações.",
     "normal-desc": "Pode ver e editar cartões. Não pode alterar configurações.",
-    "not-accepted-yet": "Convite ainda não aceito",
-    "notify-participate": "Receber atualizações de qualquer cartão que criar ou participar como membro",
-    "notify-watch": "Receber atualizações de qualquer quadro, lista ou cartões que estiver a observar",
+    "not-accepted-yet": "Convite ainda não aceite",
+    "notify-participate": "Receber actualizações de qualquer cartão que criar ou participar como membro",
+    "notify-watch": "Receber actualizações de qualquer quadro, lista ou cartões que estiver a observar",
     "optional": "opcional",
     "optional": "opcional",
     "or": "ou",
     "or": "ou",
-    "page-maybe-private": "Esta página pode ser privada. Poderá vê-la se estiver <a href='%s'>logado</a>.",
+    "page-maybe-private": "Esta página pode ser privada. Poderá vê-la se <a href='%s'>iniciar a sessão</a>.",
     "page-not-found": "Página não encontrada.",
     "page-not-found": "Página não encontrada.",
     "password": "Senha",
     "password": "Senha",
-    "paste-or-dragdrop": "para colar, ou arraste e solte o arquivo da imagem para cá (somente imagens)",
+    "paste-or-dragdrop": "para colar, ou arrastar e soltar o ficheiro da imagem para lá (somente imagens)",
     "participating": "Participando",
     "participating": "Participando",
     "preview": "Pré-visualizar",
     "preview": "Pré-visualizar",
     "previewAttachedImagePopup-title": "Pré-visualizar",
     "previewAttachedImagePopup-title": "Pré-visualizar",
     "previewClipboardImagePopup-title": "Pré-visualizar",
     "previewClipboardImagePopup-title": "Pré-visualizar",
     "private": "Privado",
     "private": "Privado",
-    "private-desc": "Este quadro é privado. Apenas seus membros podem acessar e editá-lo.",
+    "private-desc": "Este quadro é privado. Apenas o membros do quadro o podem visualizar e editar.",
     "profile": "Perfil",
     "profile": "Perfil",
     "public": "Público",
     "public": "Público",
-    "public-desc": "Este quadro é público. Ele é visível a qualquer pessoa com o link e será exibido em motores de busca como o Google. Apenas os seus membros podem editá-lo.",
-    "quick-access-description": "Clique na estrela para adicionar um atalho nesta barra.",
+    "public-desc": "Este quadro é público. Está visível para qualquer pessoa com a ligação e será exibido em motores de busca como o Google. Apenas os membros do quadro o podem editar.",
+    "quick-access-description": "Clique na estrela de um quadro para adicionar um atalho nesta barra.",
     "remove-cover": "Remover Capa",
     "remove-cover": "Remover Capa",
     "remove-from-board": "Remover do Quadro",
     "remove-from-board": "Remover do Quadro",
     "remove-label": "Remover Etiqueta",
     "remove-label": "Remover Etiqueta",
-    "listDeletePopup-title": "Excluir Lista?",
+    "listDeletePopup-title": "Apagar Lista ?",
     "remove-member": "Remover Membro",
     "remove-member": "Remover Membro",
     "remove-member-from-card": "Remover do Cartão",
     "remove-member-from-card": "Remover do Cartão",
     "remove-member-pop": "Remover __name__ (__username__) de __boardTitle__? O membro será removido de todos os cartões neste quadro e será notificado.",
     "remove-member-pop": "Remover __name__ (__username__) de __boardTitle__? O membro será removido de todos os cartões neste quadro e será notificado.",
@@ -415,63 +415,63 @@
     "rename": "Renomear",
     "rename": "Renomear",
     "rename-board": "Renomear Quadro",
     "rename-board": "Renomear Quadro",
     "restore": "Restaurar",
     "restore": "Restaurar",
-    "save": "Salvar",
-    "search": "Buscar",
+    "save": "Guardar",
+    "search": "Procurar",
     "rules": "Regras",
     "rules": "Regras",
-    "search-cards": "Pesquisa em títulos e descrições de cartões neste quadro",
-    "search-example": "Texto para procurar",
-    "select-color": "Selecionar Cor",
+    "search-cards": "Pesquisar nos títulos e descrições dos cartões deste quadro",
+    "search-example": "Texto a procurar?",
+    "select-color": "Seleccionar Cor",
     "set-wip-limit-value": "Defina um limite máximo para o número de tarefas nesta lista",
     "set-wip-limit-value": "Defina um limite máximo para o número de tarefas nesta lista",
     "setWipLimitPopup-title": "Definir Limite WIP",
     "setWipLimitPopup-title": "Definir Limite WIP",
-    "shortcut-assign-self": "Atribuir a si o cartão atual",
+    "shortcut-assign-self": "Atribuir a si o cartão actual",
     "shortcut-autocomplete-emoji": "Autocompletar emoji",
     "shortcut-autocomplete-emoji": "Autocompletar emoji",
-    "shortcut-autocomplete-members": "Preenchimento automático de membros",
-    "shortcut-clear-filters": "Limpar todos filtros",
-    "shortcut-close-dialog": "Fechar dialogo",
-    "shortcut-filter-my-cards": "Filtrar meus cartões",
-    "shortcut-show-shortcuts": "Mostrar lista de atalhos",
-    "shortcut-toggle-filterbar": "Alternar barra de filtro",
-    "shortcut-toggle-sidebar": "Fechar barra lateral.",
-    "show-cards-minimum-count": "Mostrar contador de cartões se a lista tiver mais de",
-    "sidebar-open": "Abrir barra lateral",
-    "sidebar-close": "Fechar barra lateral",
+    "shortcut-autocomplete-members": "Autocompletar membros",
+    "shortcut-clear-filters": "Limpar todos os filtros",
+    "shortcut-close-dialog": "Fechar Caixa de Dialogo",
+    "shortcut-filter-my-cards": "Filtrar os meus cartões",
+    "shortcut-show-shortcuts": "Mostrar esta lista de atalhos",
+    "shortcut-toggle-filterbar": "Alternar a Barra Lateral de Filtros",
+    "shortcut-toggle-sidebar": "Alternar a Barra Lateral do Quadro",
+    "show-cards-minimum-count": "Mostrar contagem de cartões se a lista tiver mais de",
+    "sidebar-open": "Abrir a Barra Lateral",
+    "sidebar-close": "Fechar a Barra Lateral",
     "signupPopup-title": "Criar uma Conta",
     "signupPopup-title": "Criar uma Conta",
-    "star-board-title": "Clique para marcar este quadro como favorito. Ele aparecerá no topo na lista dos seus quadros.",
+    "star-board-title": "Clique para marcar este quadro como favorito. O quadro irá aparecer no topo da sua lista de quadros.",
     "starred-boards": "Quadros Favoritos",
     "starred-boards": "Quadros Favoritos",
-    "starred-boards-description": "Quadros favoritos aparecem no topo da lista dos seus quadros.",
-    "subscribe": "Acompanhar",
-    "team": "Equipe",
+    "starred-boards-description": "Os quadros favoritos aparecem no topo da sua lista de quadros.",
+    "subscribe": "Subscrever",
+    "team": "Equipa",
     "this-board": "este quadro",
     "this-board": "este quadro",
     "this-card": "este cartão",
     "this-card": "este cartão",
-    "spent-time-hours": "Tempo gasto (Horas)",
-    "overtime-hours": "Tempo extras (Horas)",
-    "overtime": "Tempo extras",
-    "has-overtime-cards": "Tem cartões de horas extras",
-    "has-spenttime-cards": "Gastou cartões de tempo",
+    "spent-time-hours": "Tempo gasto (horas)",
+    "overtime-hours": "Horas extra (horas)",
+    "overtime": "Horas extra",
+    "has-overtime-cards": "Tem cartões com horas extra",
+    "has-spenttime-cards": "Tem cartões com tempo gasto",
     "time": "Tempo",
     "time": "Tempo",
     "title": "Título",
     "title": "Título",
-    "tracking": "Rastreamento",
-    "tracking-info": "Será notificado se houver qualquer alteração em cartões em que é o criador ou membro",
+    "tracking": "A seguir",
+    "tracking-info": "Será notificado de quaisquer alterações em cartões em que é o criador ou membro.",
     "type": "Tipo",
     "type": "Tipo",
-    "unassign-member": "Membro não associado",
-    "unsaved-description": "Possui uma descrição não salva",
+    "unassign-member": "Desatribuir membro",
+    "unsaved-description": "Possui uma descrição não guardada.",
     "unwatch": "Deixar de observar",
     "unwatch": "Deixar de observar",
-    "upload": "Carregar",
-    "upload-avatar": "Carregar um avatar",
-    "uploaded-avatar": "Avatar carregado",
+    "upload": "Enviar",
+    "upload-avatar": "Enviar um avatar",
+    "uploaded-avatar": "Enviado um avatar",
     "username": "Nome de utilizador",
     "username": "Nome de utilizador",
-    "view-it": "Visualizar",
-    "warn-list-archived": "aviso: este cartão está em uma lista no Arquivo",
+    "view-it": "Visualizá-lo",
+    "warn-list-archived": "aviso: este cartão está numa lista no Arquivo",
     "watch": "Observar",
     "watch": "Observar",
     "watching": "Observando",
     "watching": "Observando",
-    "watching-info": "Será notificado de qualquer alteração neste quadro",
+    "watching-info": "Será notificado de quaisquer alterações neste quadro",
     "welcome-board": "Quadro de Boas Vindas",
     "welcome-board": "Quadro de Boas Vindas",
     "welcome-swimlane": "Marco 1",
     "welcome-swimlane": "Marco 1",
     "welcome-list1": "Básico",
     "welcome-list1": "Básico",
     "welcome-list2": "Avançado",
     "welcome-list2": "Avançado",
-    "card-templates-swimlane": "Modelos de cartão",
-    "list-templates-swimlane": "Modelos de lista",
-    "board-templates-swimlane": "Modelos de quadro",
+    "card-templates-swimlane": "Modelos de Cartão",
+    "list-templates-swimlane": "Modelos de Lista",
+    "board-templates-swimlane": "Modelos de Quadro",
     "what-to-do": "O que gostaria de fazer?",
     "what-to-do": "O que gostaria de fazer?",
     "wipLimitErrorPopup-title": "Limite WIP Inválido",
     "wipLimitErrorPopup-title": "Limite WIP Inválido",
     "wipLimitErrorPopup-dialog-pt1": "O número de tarefas nesta lista excede o limite WIP definido.",
     "wipLimitErrorPopup-dialog-pt1": "O número de tarefas nesta lista excede o limite WIP definido.",
@@ -480,14 +480,14 @@
     "settings": "Configurações",
     "settings": "Configurações",
     "people": "Pessoas",
     "people": "Pessoas",
     "registration": "Registo",
     "registration": "Registo",
-    "disable-self-registration": "Desabilitar Cadastrar-se",
-    "invite": "Convite",
-    "invite-people": "Convide Pessoas",
-    "to-boards": "Para o/os quadro(s)",
-    "email-addresses": "Endereço de E-mail",
-    "smtp-host-description": "O endereço do servidor SMTP que envia seus e-mails.",
+    "disable-self-registration": "Desabilitar Auto-Registo",
+    "invite": "Convidar",
+    "invite-people": "Convidar Pessoas",
+    "to-boards": "Para o(s) quadro(s)",
+    "email-addresses": "Endereços de E-mail",
+    "smtp-host-description": "O endereço do servidor SMTP que envia os seus e-mails.",
     "smtp-port-description": "A porta que o servidor SMTP usa para enviar os e-mails.",
     "smtp-port-description": "A porta que o servidor SMTP usa para enviar os e-mails.",
-    "smtp-tls-description": "Habilitar suporte TLS para servidor SMTP",
+    "smtp-tls-description": "Habilitar suporte TLS para o servidor SMTP",
     "smtp-host": "Servidor SMTP",
     "smtp-host": "Servidor SMTP",
     "smtp-port": "Porta SMTP",
     "smtp-port": "Porta SMTP",
     "smtp-username": "Nome de utilizador",
     "smtp-username": "Nome de utilizador",
@@ -496,20 +496,20 @@
     "send-from": "De",
     "send-from": "De",
     "send-smtp-test": "Enviar um e-mail de teste para si mesmo",
     "send-smtp-test": "Enviar um e-mail de teste para si mesmo",
     "invitation-code": "Código do Convite",
     "invitation-code": "Código do Convite",
-    "email-invite-register-subject": "__inviter__ lhe enviou um convite",
-    "email-invite-register-text": "Caro __user__,\n\n__inviter__ convida-o para o quadro Kanban para colaborações.\n\nPor favor, siga o link abaixo:\n__url__ \n\nE seu código de convite é: __icode__\n\nObrigado.",
-    "email-smtp-test-subject": "E-mail de teste via SMTP",
+    "email-invite-register-subject": "__inviter__ enviou-lhe um convite",
+    "email-invite-register-text": "Caro __user__,\n\n__inviter__ convida-o para o quadro Kanban para colaborações.\n\nPor favor, siga a ligação abaixo:\n__url__ \n\nE seu código de convite é: __icode__\n\nObrigado.",
+    "email-smtp-test-subject": "E-mail de Teste de SMTP",
     "email-smtp-test-text": "Enviou um e-mail com sucesso",
     "email-smtp-test-text": "Enviou um e-mail com sucesso",
     "error-invitation-code-not-exist": "O código do convite não existe",
     "error-invitation-code-not-exist": "O código do convite não existe",
-    "error-notAuthorized": "Não está autorizado à ver esta página.",
-    "outgoing-webhooks": "Webhook de saída",
-    "outgoingWebhooksPopup-title": "Webhook de saída",
+    "error-notAuthorized": "Não tem autorização para ver esta página.",
+    "outgoing-webhooks": "Webhooks de saída",
+    "outgoingWebhooksPopup-title": "Webhooks de saída",
     "boardCardTitlePopup-title": "Filtro do Título do Cartão",
     "boardCardTitlePopup-title": "Filtro do Título do Cartão",
     "new-outgoing-webhook": "Novo Webhook de saída",
     "new-outgoing-webhook": "Novo Webhook de saída",
     "no-name": "(Desconhecido)",
     "no-name": "(Desconhecido)",
     "Node_version": "Versão do Node",
     "Node_version": "Versão do Node",
-    "OS_Arch": "Arquitetura do SO",
-    "OS_Cpus": "Quantidade de CPUS do SO",
+    "OS_Arch": "Arquitectura do SO",
+    "OS_Cpus": "Quantidade de CPUs do SO",
     "OS_Freemem": "Memória Disponível do SO",
     "OS_Freemem": "Memória Disponível do SO",
     "OS_Loadavg": "Carga Média do SO",
     "OS_Loadavg": "Carga Média do SO",
     "OS_Platform": "Plataforma do SO",
     "OS_Platform": "Plataforma do SO",
@@ -527,69 +527,69 @@
     "yes": "Sim",
     "yes": "Sim",
     "no": "Não",
     "no": "Não",
     "accounts": "Contas",
     "accounts": "Contas",
-    "accounts-allowEmailChange": "Permitir Mudança de e-mail",
-    "accounts-allowUserNameChange": "Permitir alteração de nome de utilizador",
+    "accounts-allowEmailChange": "Permitir Alteração do E-mail",
+    "accounts-allowUserNameChange": "Permitir Alteração de Nome de Utilizador",
     "createdAt": "Criado em",
     "createdAt": "Criado em",
     "verified": "Verificado",
     "verified": "Verificado",
-    "active": "Ativo",
+    "active": "Activo",
     "card-received": "Recebido",
     "card-received": "Recebido",
     "card-received-on": "Recebido em",
     "card-received-on": "Recebido em",
     "card-end": "Fim",
     "card-end": "Fim",
     "card-end-on": "Termina em",
     "card-end-on": "Termina em",
-    "editCardReceivedDatePopup-title": "Modificar data de recebimento",
-    "editCardEndDatePopup-title": "Mudar data de fim",
+    "editCardReceivedDatePopup-title": "Alterar data de recebimento",
+    "editCardEndDatePopup-title": "Alterar data de fim",
     "setCardColorPopup-title": "Definir cor",
     "setCardColorPopup-title": "Definir cor",
     "setCardActionsColorPopup-title": "Escolha uma cor",
     "setCardActionsColorPopup-title": "Escolha uma cor",
     "setSwimlaneColorPopup-title": "Escolha uma cor",
     "setSwimlaneColorPopup-title": "Escolha uma cor",
     "setListColorPopup-title": "Escolha uma cor",
     "setListColorPopup-title": "Escolha uma cor",
-    "assigned-by": "Atribuído por",
-    "requested-by": "Solicitado por",
-    "board-delete-notice": "Excluir é permanente. Irá perder todas as listas, cartões e ações associados nesse quadro.",
-    "delete-board-confirm-popup": "Todas as listas, cartões, etiquetas e atividades serão excluídos e não poderá recuperar o conteúdo do quadro. Não há como desfazer.",
-    "boardDeletePopup-title": "Excluir quadro?",
-    "delete-board": "Excluir quadro",
-    "default-subtasks-board": "Sub-tarefas para quadro __board__",
-    "default": "Padrão",
+    "assigned-by": "Atribuído Por",
+    "requested-by": "Solicitado Por",
+    "board-delete-notice": "Apagar é permanente. Irá perder todas as listas, cartões e acções associadas a este quadro.",
+    "delete-board-confirm-popup": "Todas as listas, cartões, etiquetas e actividades serão apagadas e não poderá recuperar o conteúdo do quadro. Não há como desfazer.",
+    "boardDeletePopup-title": "Apagar Quadro?",
+    "delete-board": "Apagar Quadro",
+    "default-subtasks-board": "Sub-tarefas para o quadro __board__",
+    "default": "Omissão",
     "queue": "Fila",
     "queue": "Fila",
-    "subtask-settings": "Configurações de sub-tarefas",
-    "boardSubtaskSettingsPopup-title": "Configurações das sub-tarefas do quadro",
+    "subtask-settings": "Configurações de Sub-tarefas",
+    "boardSubtaskSettingsPopup-title": "Configurações das Sub-tarefas do Quadro",
     "show-subtasks-field": "Cartões podem ter sub-tarefas",
     "show-subtasks-field": "Cartões podem ter sub-tarefas",
-    "deposit-subtasks-board": "Inserir sub-tarefas a este quadro:",
-    "deposit-subtasks-list": "Listas de sub-tarefas inseridas aqui:",
-    "show-parent-in-minicard": "Mostrar Pai do mini cartão:",
-    "prefix-with-full-path": "Prefixo com caminho completo",
-    "prefix-with-parent": "Prefixo com Pai",
-    "subtext-with-full-path": "Sub-texto com caminho completo",
-    "subtext-with-parent": "Sub-texto com Pai",
-    "change-card-parent": "Mudar Pai do cartão",
+    "deposit-subtasks-board": "Depositar sub-tarefas neste quadro:",
+    "deposit-subtasks-list": "Lista de destino para sub-tarefas depositadas aqui:",
+    "show-parent-in-minicard": "Mostrar pai no mini-cartão:",
+    "prefix-with-full-path": "Prefixar com o caminho completo",
+    "prefix-with-parent": "Prefixar com o pai",
+    "subtext-with-full-path": "Sub-texto com o caminho completo",
+    "subtext-with-parent": "Sub-texto com o pai",
+    "change-card-parent": "Alterar o pai do cartão",
     "parent-card": "Pai do cartão",
     "parent-card": "Pai do cartão",
-    "source-board": "Fonte do quadro",
-    "no-parent": "Não mostrar Pai",
-    "activity-added-label": "adicionada etiqueta '%s' para %s",
-    "activity-removed-label": "removida etiqueta '%s' de %s",
-    "activity-delete-attach": "excluído um anexo de %s",
-    "activity-added-label-card": "adicionada etiqueta '%s'",
-    "activity-removed-label-card": "removida etiqueta '%s'",
-    "activity-delete-attach-card": "excluído um anexo",
-    "activity-set-customfield": "definir campo personalizado '%s' para '%s' em %s",
-    "activity-unset-customfield": "redefinir campo personalizado '%s' em %s",
+    "source-board": "Quadro fonte",
+    "no-parent": "Não mostrar o pai",
+    "activity-added-label": "adicionou a etiqueta '%s' a %s",
+    "activity-removed-label": "removeu a etiqueta '%s' de %s",
+    "activity-delete-attach": "apagou um anexo de %s",
+    "activity-added-label-card": "adicionou a etiqueta '%s'",
+    "activity-removed-label-card": "removeu a etiqueta '%s'",
+    "activity-delete-attach-card": "apagou um anexo",
+    "activity-set-customfield": "definiu o campo personalizado '%s' para '%s' em %s",
+    "activity-unset-customfield": "removeu o campo personalizado '%s' de %s",
     "r-rule": "Regra",
     "r-rule": "Regra",
     "r-add-trigger": "Adicionar gatilho",
     "r-add-trigger": "Adicionar gatilho",
-    "r-add-action": "Adicionar ação",
-    "r-board-rules": "Quadro de regras",
+    "r-add-action": "Adicionar acção",
+    "r-board-rules": "Regras do quadro",
     "r-add-rule": "Adicionar regra",
     "r-add-rule": "Adicionar regra",
     "r-view-rule": "Ver regra",
     "r-view-rule": "Ver regra",
-    "r-delete-rule": "Excluir regra",
+    "r-delete-rule": "Apagar regra",
     "r-new-rule-name": "Título da nova regra",
     "r-new-rule-name": "Título da nova regra",
     "r-no-rules": "Sem regras",
     "r-no-rules": "Sem regras",
     "r-when-a-card": "Quando um cartão",
     "r-when-a-card": "Quando um cartão",
     "r-is": "é",
     "r-is": "é",
     "r-is-moved": "é movido",
     "r-is-moved": "é movido",
-    "r-added-to": "adicionado à",
+    "r-added-to": "adicionado a",
     "r-removed-from": "Removido de",
     "r-removed-from": "Removido de",
     "r-the-board": "o quadro",
     "r-the-board": "o quadro",
     "r-list": "lista",
     "r-list": "lista",
-    "set-filter": "Inserir Filtro",
+    "set-filter": "Definir Filtro",
     "r-moved-to": "Movido para",
     "r-moved-to": "Movido para",
     "r-moved-from": "Movido de",
     "r-moved-from": "Movido de",
     "r-archived": "Movido para o Arquivo",
     "r-archived": "Movido para o Arquivo",
@@ -597,24 +597,24 @@
     "r-a-card": "um cartão",
     "r-a-card": "um cartão",
     "r-when-a-label-is": "Quando uma etiqueta é",
     "r-when-a-label-is": "Quando uma etiqueta é",
     "r-when-the-label-is": "Quando a etiqueta é",
     "r-when-the-label-is": "Quando a etiqueta é",
-    "r-list-name": "listar nome",
+    "r-list-name": "listar o nome",
     "r-when-a-member": "Quando um membro é",
     "r-when-a-member": "Quando um membro é",
     "r-when-the-member": "Quando o membro",
     "r-when-the-member": "Quando o membro",
     "r-name": "nome",
     "r-name": "nome",
     "r-when-a-attach": "Quando um anexo",
     "r-when-a-attach": "Quando um anexo",
     "r-when-a-checklist": "Quando a lista de verificação é",
     "r-when-a-checklist": "Quando a lista de verificação é",
     "r-when-the-checklist": "Quando a lista de verificação",
     "r-when-the-checklist": "Quando a lista de verificação",
-    "r-completed": "Completado",
-    "r-made-incomplete": "Feito incompleto",
-    "r-when-a-item": "Quando o item da lista de verificação é",
+    "r-completed": "Completada",
+    "r-made-incomplete": "Tornado incompleta",
+    "r-when-a-item": "Quando um item de uma lista de verificação é",
     "r-when-the-item": "Quando o item da lista de verificação",
     "r-when-the-item": "Quando o item da lista de verificação",
     "r-checked": "Marcado",
     "r-checked": "Marcado",
     "r-unchecked": "Desmarcado",
     "r-unchecked": "Desmarcado",
     "r-move-card-to": "Mover cartão para",
     "r-move-card-to": "Mover cartão para",
     "r-top-of": "Topo de",
     "r-top-of": "Topo de",
-    "r-bottom-of": "Final de",
-    "r-its-list": "é lista",
-    "r-archive": "Mover para Arquivo",
+    "r-bottom-of": "Fundo de",
+    "r-its-list": "a sua lista",
+    "r-archive": "Mover para o Arquivo",
     "r-unarchive": "Restaurar do Arquivo",
     "r-unarchive": "Restaurar do Arquivo",
     "r-card": "cartão",
     "r-card": "cartão",
     "r-add": "Novo",
     "r-add": "Novo",
@@ -622,7 +622,7 @@
     "r-label": "etiqueta",
     "r-label": "etiqueta",
     "r-member": "membro",
     "r-member": "membro",
     "r-remove-all": "Remover todos os membros do cartão",
     "r-remove-all": "Remover todos os membros do cartão",
-    "r-set-color": "Definir cor para",
+    "r-set-color": "Definir a cor para",
     "r-checklist": "lista de verificação",
     "r-checklist": "lista de verificação",
     "r-check-all": "Marcar todos",
     "r-check-all": "Marcar todos",
     "r-uncheck-all": "Desmarcar todos",
     "r-uncheck-all": "Desmarcar todos",
@@ -637,13 +637,13 @@
     "r-rule-details": "Detalhes da regra",
     "r-rule-details": "Detalhes da regra",
     "r-d-move-to-top-gen": "Mover cartão para o topo da sua lista",
     "r-d-move-to-top-gen": "Mover cartão para o topo da sua lista",
     "r-d-move-to-top-spec": "Mover cartão para o topo da lista",
     "r-d-move-to-top-spec": "Mover cartão para o topo da lista",
-    "r-d-move-to-bottom-gen": "Mover cartão para o final da sua lista",
-    "r-d-move-to-bottom-spec": "Mover cartão para final da lista",
+    "r-d-move-to-bottom-gen": "Mover cartão para o fundo da sua lista",
+    "r-d-move-to-bottom-spec": "Mover cartão para fundo da lista",
     "r-d-send-email": "Enviar e-mail",
     "r-d-send-email": "Enviar e-mail",
     "r-d-send-email-to": "para",
     "r-d-send-email-to": "para",
     "r-d-send-email-subject": "assunto",
     "r-d-send-email-subject": "assunto",
     "r-d-send-email-message": "mensagem",
     "r-d-send-email-message": "mensagem",
-    "r-d-archive": "Mover cartão para Arquivo",
+    "r-d-archive": "Mover cartão para o Arquivo",
     "r-d-unarchive": "Restaurar cartão do Arquivo",
     "r-d-unarchive": "Restaurar cartão do Arquivo",
     "r-d-add-label": "Adicionar etiqueta",
     "r-d-add-label": "Adicionar etiqueta",
     "r-d-remove-label": "Remover etiqueta",
     "r-d-remove-label": "Remover etiqueta",
@@ -665,9 +665,9 @@
     "r-with-items": "com os itens",
     "r-with-items": "com os itens",
     "r-items-list": "item1,item2,item3",
     "r-items-list": "item1,item2,item3",
     "r-add-swimlane": "Adicionar pista",
     "r-add-swimlane": "Adicionar pista",
-    "r-swimlane-name": "Nome da pista",
-    "r-board-note": "Nota: deixe o campo vazio para corresponder à todos os valores possíveis",
-    "r-checklist-note": "Nota: itens de Checklists devem ser escritos separados por vírgulas",
+    "r-swimlane-name": "nome da pista",
+    "r-board-note": "Nota: deixe o campo vazio para corresponder a todos os valores possíveis.",
+    "r-checklist-note": "Nota: itens de listas de verificação devem ser escritos separados por vírgulas.",
     "r-when-a-card-is-moved": "Quando um cartão é movido de outra lista",
     "r-when-a-card-is-moved": "Quando um cartão é movido de outra lista",
     "ldap": "LDAP",
     "ldap": "LDAP",
     "oauth2": "OAuth2",
     "oauth2": "OAuth2",
@@ -680,14 +680,14 @@
     "add-custom-html-after-body-start": "Adicionar HTML Personalizado depois do início do <body>",
     "add-custom-html-after-body-start": "Adicionar HTML Personalizado depois do início do <body>",
     "add-custom-html-before-body-end": "Adicionar HTML Personalizado antes do fim do </body>",
     "add-custom-html-before-body-end": "Adicionar HTML Personalizado antes do fim do </body>",
     "error-undefined": "Ocorreu um erro",
     "error-undefined": "Ocorreu um erro",
-    "error-ldap-login": "Um erro ocorreu enquanto tentava entrar",
+    "error-ldap-login": "Ocorreu um erro ocorreu enquanto tentava entrar",
     "display-authentication-method": "Mostrar Método de Autenticação",
     "display-authentication-method": "Mostrar Método de Autenticação",
-    "default-authentication-method": "Método de Autenticação Padrão",
+    "default-authentication-method": "Método de Autenticação por Omissão",
     "duplicate-board": "Duplicar Quadro",
     "duplicate-board": "Duplicar Quadro",
     "people-number": "O número de pessoas é:",
     "people-number": "O número de pessoas é:",
-    "swimlaneDeletePopup-title": "Delete Swimlane ?",
-    "swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
-    "restore-all": "Restore all",
-    "delete-all": "Delete all",
-    "loading": "Loading, please wait."
+    "swimlaneDeletePopup-title": "Apagar Pista ?",
+    "swimlane-delete-pop": "Todas as acções serão removidas do feed de actividade e não será possível recuperar a pista. Não há como desfazer.",
+    "restore-all": "Restaurar todos",
+    "delete-all": "Apagar todos",
+    "loading": "A carregar, por favor aguarde."
 }
 }

+ 12 - 12
i18n/zh-TW.i18n.json

@@ -17,17 +17,17 @@
     "act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
     "act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
     "act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
     "act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
     "act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
     "act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
-    "act-createBoard": "created board __board__",
+    "act-createBoard": "新增看板 __board__ ",
     "act-createSwimlane": "created swimlane __swimlane__ to board __board__",
     "act-createSwimlane": "created swimlane __swimlane__ to board __board__",
     "act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
     "act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
     "act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
     "act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
-    "act-createList": "added list __list__ to board __board__",
+    "act-createList": "新增清單__list__至看板__board__",
     "act-addBoardMember": "added member __member__ to board __board__",
     "act-addBoardMember": "added member __member__ to board __board__",
-    "act-archivedBoard": "Board __board__ moved to Archive",
+    "act-archivedBoard": "看板 __board__ 已被封存",
     "act-archivedCard": "Card __card__ at list __list__ at swimlane __swimlane__ at board __board__ moved to Archive",
     "act-archivedCard": "Card __card__ at list __list__ at swimlane __swimlane__ at board __board__ moved to Archive",
     "act-archivedList": "List __list__ at swimlane __swimlane__ at board __board__ moved to Archive",
     "act-archivedList": "List __list__ at swimlane __swimlane__ at board __board__ moved to Archive",
     "act-archivedSwimlane": "Swimlane __swimlane__ at board __board__ moved to Archive",
     "act-archivedSwimlane": "Swimlane __swimlane__ at board __board__ moved to Archive",
-    "act-importBoard": "imported board __board__",
+    "act-importBoard": "看板 __board__ 已匯入",
     "act-importCard": "imported card  __card__ to list __list__ at swimlane __swimlane__ at board __board__",
     "act-importCard": "imported card  __card__ to list __list__ at swimlane __swimlane__ at board __board__",
     "act-importList": "imported list __list__ to swimlane __swimlane__ at board __board__",
     "act-importList": "imported list __list__ to swimlane __swimlane__ at board __board__",
     "act-joinMember": "added member __member__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
     "act-joinMember": "added member __member__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
@@ -379,8 +379,8 @@
     "muted-info": "您將不會收到有關這個看板的任何訊息",
     "muted-info": "您將不會收到有關這個看板的任何訊息",
     "my-boards": "我的看板",
     "my-boards": "我的看板",
     "name": "名稱",
     "name": "名稱",
-    "no-archived-cards": "No cards in Archive.",
-    "no-archived-lists": "No lists in Archive.",
+    "no-archived-cards": "沒有封存的卡片",
+    "no-archived-lists": "沒有封存的清單",
     "no-archived-swimlanes": "No swimlanes in Archive.",
     "no-archived-swimlanes": "No swimlanes in Archive.",
     "no-results": "無結果",
     "no-results": "無結果",
     "normal": "普通",
     "normal": "普通",
@@ -417,7 +417,7 @@
     "restore": "還原",
     "restore": "還原",
     "save": "儲存",
     "save": "儲存",
     "search": "搜尋",
     "search": "搜尋",
-    "rules": "Rules",
+    "rules": "規則",
     "search-cards": "Search from card titles and descriptions on this board",
     "search-cards": "Search from card titles and descriptions on this board",
     "search-example": "Text to search for?",
     "search-example": "Text to search for?",
     "select-color": "選擇顏色",
     "select-color": "選擇顏色",
@@ -443,16 +443,16 @@
     "team": "團隊",
     "team": "團隊",
     "this-board": "這個看板",
     "this-board": "這個看板",
     "this-card": "這個卡片",
     "this-card": "這個卡片",
-    "spent-time-hours": "Spent time (hours)",
-    "overtime-hours": "Overtime (hours)",
-    "overtime": "Overtime",
+    "spent-time-hours": "耗費時間 (小時)",
+    "overtime-hours": "超時 (小時)",
+    "overtime": "超時",
     "has-overtime-cards": "Has overtime cards",
     "has-overtime-cards": "Has overtime cards",
     "has-spenttime-cards": "Has spent time cards",
     "has-spenttime-cards": "Has spent time cards",
     "time": "時間",
     "time": "時間",
     "title": "標題",
     "title": "標題",
     "tracking": "追蹤",
     "tracking": "追蹤",
     "tracking-info": "你將會收到與你有關的卡片的所有變更通知",
     "tracking-info": "你將會收到與你有關的卡片的所有變更通知",
-    "type": "Type",
+    "type": "類型",
     "unassign-member": "取消分配成員",
     "unassign-member": "取消分配成員",
     "unsaved-description": "未儲存的描述",
     "unsaved-description": "未儲存的描述",
     "unwatch": "取消觀察",
     "unwatch": "取消觀察",
@@ -461,7 +461,7 @@
     "uploaded-avatar": "大頭貼已經上傳",
     "uploaded-avatar": "大頭貼已經上傳",
     "username": "使用者名稱",
     "username": "使用者名稱",
     "view-it": "檢視",
     "view-it": "檢視",
-    "warn-list-archived": "warning: this card is in an list at Archive",
+    "warn-list-archived": "警告: 卡片位在封存的清單中",
     "watch": "觀察",
     "watch": "觀察",
     "watching": "觀察中",
     "watching": "觀察中",
     "watching-info": "你將會收到關於這個看板所有的變更通知",
     "watching-info": "你將會收到關於這個看板所有的變更通知",

+ 2 - 1
models/activities.js

@@ -166,7 +166,8 @@ if (Meteor.isServer) {
     }
     }
     if (activity.attachmentId) {
     if (activity.attachmentId) {
       const attachment = activity.attachment();
       const attachment = activity.attachment();
-      params.attachment = attachment._id;
+      params.attachment = attachment.original.name;
+      params.attachmentId = attachment._id;
     }
     }
     if (activity.checklistId) {
     if (activity.checklistId) {
       const checklist = activity.checklist();
       const checklist = activity.checklist();

+ 8 - 4
models/attachments.js

@@ -88,18 +88,22 @@ if (Meteor.isServer) {
     }
     }
   });
   });
 
 
-  Attachments.files.after.remove((userId, doc) => {
-    Activities.remove({
-      attachmentId: doc._id,
-    });
+  Attachments.files.before.remove((userId, doc) => {
     Activities.insert({
     Activities.insert({
       userId,
       userId,
       type: 'card',
       type: 'card',
       activityType: 'deleteAttachment',
       activityType: 'deleteAttachment',
+      attachmentId: doc._id,
       boardId: doc.boardId,
       boardId: doc.boardId,
       cardId: doc.cardId,
       cardId: doc.cardId,
       listId: doc.listId,
       listId: doc.listId,
       swimlaneId: doc.swimlaneId,
       swimlaneId: doc.swimlaneId,
     });
     });
   });
   });
+
+  Attachments.files.after.remove((userId, doc) => {
+    Activities.remove({
+      attachmentId: doc._id,
+    });
+  });
 }
 }

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "wekan",
   "name": "wekan",
-  "version": "v2.75.0",
+  "version": "v2.76.0",
   "description": "Open-Source kanban",
   "description": "Open-Source kanban",
   "private": true,
   "private": true,
   "scripts": {
   "scripts": {

+ 2 - 3
packages/wekan-oidc/oidc_client.js

@@ -18,10 +18,9 @@ Oidc.requestCredential = function (options, credentialRequestCompleteCallback) {
       new ServiceConfiguration.ConfigError('Service oidc not configured.'));
       new ServiceConfiguration.ConfigError('Service oidc not configured.'));
     return;
     return;
   }
   }
-  
+
   var credentialToken = Random.secret();
   var credentialToken = Random.secret();
   var loginStyle = OAuth._loginStyle('oidc', config, options);
   var loginStyle = OAuth._loginStyle('oidc', config, options);
-  var scope = config.requestPermissions || ['openid', 'profile', 'email'];
 
 
   // options
   // options
   options = options || {};
   options = options || {};
@@ -29,7 +28,7 @@ Oidc.requestCredential = function (options, credentialRequestCompleteCallback) {
   options.response_type = options.response_type || 'code';
   options.response_type = options.response_type || 'code';
   options.redirect_uri = OAuth._redirectUri('oidc', config);
   options.redirect_uri = OAuth._redirectUri('oidc', config);
   options.state = OAuth._stateParam(loginStyle, credentialToken, options.redirectUrl);
   options.state = OAuth._stateParam(loginStyle, credentialToken, options.redirectUrl);
-  options.scope = scope.join(' ');
+  options.scope = config.requestPermissions || 'openid profile email';
 
 
   if (config.loginStyle && config.loginStyle == 'popup') {
   if (config.loginStyle && config.loginStyle == 'popup') {
     options.display = 'popup';
     options.display = 'popup';

+ 7 - 1
packages/wekan-oidc/oidc_server.js

@@ -49,7 +49,12 @@ if (Meteor.release) {
 var getToken = function (query) {
 var getToken = function (query) {
   var debug = process.env.DEBUG || false;
   var debug = process.env.DEBUG || false;
   var config = getConfiguration();
   var config = getConfiguration();
-  var serverTokenEndpoint = config.serverUrl + config.tokenEndpoint;
+  if(config.tokenEndpoint.includes('https://')){
+    var serverTokenEndpoint = config.tokenEndpoint;
+  }else{
+    var serverTokenEndpoint = config.serverUrl + config.tokenEndpoint;
+  }
+  var requestPermissions = config.requestPermissions;
   var response;
   var response;
 
 
   try {
   try {
@@ -66,6 +71,7 @@ var getToken = function (query) {
           client_secret: OAuth.openSecret(config.secret),
           client_secret: OAuth.openSecret(config.secret),
           redirect_uri: OAuth._redirectUri('oidc', config),
           redirect_uri: OAuth._redirectUri('oidc', config),
           grant_type: 'authorization_code',
           grant_type: 'authorization_code',
+          scope: requestPermissions,
           state: query.state
           state: query.state
         }
         }
       }
       }

+ 5 - 1
releases/virtualbox/start-wekan.sh

@@ -38,6 +38,10 @@
         #---------------------------------------------
         #---------------------------------------------
         # CORS: Set Access-Control-Allow-Origin header. Example: *
         # CORS: Set Access-Control-Allow-Origin header. Example: *
         #export CORS=*
         #export CORS=*
+        # To enable the Set Access-Control-Allow-Headers header. "Authorization,Content-Type" is required for cross-origin use of the API.
+        #export CORS_ALLOW_HEADERS=Authorization,Content-Type
+        # To enable the Set Access-Control-Expose-Headers header.  This is not needed for typical CORS situations. Example: *
+        #export CORS_EXPOSE_HEADERS=*
         #---------------------------------------------
         #---------------------------------------------
         ## Optional: Integration with Matomo https://matomo.org that is installed to your server
         ## Optional: Integration with Matomo https://matomo.org that is installed to your server
         ## The address of the server where Matomo is hosted:
         ## The address of the server where Matomo is hosted:
@@ -84,7 +88,7 @@
         # OAUTH2 ID Token Whitelist Fields.
         # OAUTH2 ID Token Whitelist Fields.
         #export OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
         #export OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
         # OAUTH2 Request Permissions.
         # OAUTH2 Request Permissions.
-        #export OAUTH2_REQUEST_PERMISSIONS=['openid','profile','email']
+        #export OAUTH2_REQUEST_PERMISSIONS='openid profile email'
         # The claim name you want to map to the unique ID field:
         # The claim name you want to map to the unique ID field:
         #export OAUTH2_ID_MAP=email
         #export OAUTH2_ID_MAP=email
         # The claim name you want to map to the username field:
         # The claim name you want to map to the username field:

+ 2 - 2
sandstorm-pkgdef.capnp

@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
     appTitle = (defaultText = "Wekan"),
     appTitle = (defaultText = "Wekan"),
     # The name of the app as it is displayed to the user.
     # The name of the app as it is displayed to the user.
 
 
-    appVersion = 277,
+    appVersion = 278,
     # Increment this for every release.
     # Increment this for every release.
 
 
-    appMarketingVersion = (defaultText = "2.75.0~2019-05-22"),
+    appMarketingVersion = (defaultText = "2.76.0~2019-06-11"),
     # Human-readable presentation of the app version.
     # Human-readable presentation of the app version.
 
 
     minUpgradableAppVersion = 0,
     minUpgradableAppVersion = 0,

+ 1 - 1
server/authentication.js

@@ -77,7 +77,7 @@ Meteor.startup(() => {
             userinfoEndpoint: process.env.OAUTH2_USERINFO_ENDPOINT,
             userinfoEndpoint: process.env.OAUTH2_USERINFO_ENDPOINT,
             tokenEndpoint: process.env.OAUTH2_TOKEN_ENDPOINT,
             tokenEndpoint: process.env.OAUTH2_TOKEN_ENDPOINT,
             idTokenWhitelistFields: process.env.OAUTH2_ID_TOKEN_WHITELIST_FIELDS || [],
             idTokenWhitelistFields: process.env.OAUTH2_ID_TOKEN_WHITELIST_FIELDS || [],
-            requestPermissions: process.env.OAUTH2_REQUEST_PERMISSIONS || ['openid','profile','email'],
+            requestPermissions: process.env.OAUTH2_REQUEST_PERMISSIONS || 'openid profile email',
           },
           },
         }
         }
       );
       );

+ 12 - 0
server/cors.js

@@ -7,5 +7,17 @@ Meteor.startup(() => {
       return next();
       return next();
     });
     });
   }
   }
+  if ( process.env.CORS_ALLOW_HEADERS ) {
+    WebApp.rawConnectHandlers.use(function(req, res, next) {
+      res.setHeader('Access-Control-Allow-Headers', process.env.CORS_ALLOW_HEADERS);
+      return next();
+    });
+  }
+  if ( process.env.CORS_EXPOSE_HEADERS ) {
+    WebApp.rawConnectHandlers.use(function(req, res, next) {
+      res.setHeader('Access-Control-Expose-Headers', process.env.CORS_EXPOSE_HEADERS);
+      return next();
+    });
+  }
 
 
 });
 });

+ 1 - 1
server/notifications/outgoing.js

@@ -18,7 +18,7 @@ Meteor.methods({
 
 
     // label activity did not work yet, see wekan/models/activities.js
     // label activity did not work yet, see wekan/models/activities.js
     const quoteParams = _.clone(params);
     const quoteParams = _.clone(params);
-    ['card', 'list', 'oldList', 'board', 'oldBoard', 'comment', 'checklist', 'swimlane', 'oldSwimlane', 'label'].forEach((key) => {
+    ['card', 'list', 'oldList', 'board', 'oldBoard', 'comment', 'checklist', 'swimlane', 'oldSwimlane', 'label', 'attachment'].forEach((key) => {
       if (quoteParams[key]) quoteParams[key] = `"${params[key]}"`;
       if (quoteParams[key]) quoteParams[key] = `"${params[key]}"`;
     });
     });
 
 

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
snap-src/bin/config


+ 11 - 1
snap-src/bin/wekan-help

@@ -68,6 +68,16 @@ echo -e "\t$ snap set $SNAP_NAME cors='*'"
 echo -e "\t-Disable the CORS:"
 echo -e "\t-Disable the CORS:"
 echo -e "\t$ snap set $SNAP_NAME cors=''"
 echo -e "\t$ snap set $SNAP_NAME cors=''"
 echo -e "\n"
 echo -e "\n"
+echo -e "To enable the Set Access-Control-Allow-Headers header. \"Authorization,Content-Type\" is required for cross-origin use of the API."
+echo -e "\t$ snap set $SNAP_NAME cors-allow-headers='Authorization,Content-Type'"
+echo -e "\t-Disable the Set Access-Control-Allow-Headers header. \"Authorization,Content-Type\" is required for cross-origin use of the API."
+echo -e "\t$ snap set $SNAP_NAME cors-allow-headers=''"
+echo -e "\n"
+echo -e "To enable the Set Access-Control-Expose-Headers header.  This is not needed for typical CORS situations. Example: *"
+echo -e "\t$ snap set $SNAP_NAME cors-expose-headers='*'"
+echo -e "\t-Disable the Set Access-Control-Expose-Headers header.  This is not needed for typical CORS situations. Example: ''"
+echo -e "\t$ snap set $SNAP_NAME cors-expose-headers=''"
+echo -e "\n"
 echo -e "Enable browser policy and allow one trusted URL that can have iframe that has Wekan embedded inside."
 echo -e "Enable browser policy and allow one trusted URL that can have iframe that has Wekan embedded inside."
 echo -e "\t\t Setting this to false is not recommended, it also disables all other browser policy protections"
 echo -e "\t\t Setting this to false is not recommended, it also disables all other browser policy protections"
 echo -e "\t\t and allows all iframing etc. See wekan/server/policy.js"
 echo -e "\t\t and allows all iframing etc. See wekan/server/policy.js"
@@ -138,7 +148,7 @@ echo -e "\t$ snap set $SNAP_NAME oauth2-id-token-whitelist-fields=''"
 echo -e "\n"
 echo -e "\n"
 echo -e "OAuth2 Request Permissions."
 echo -e "OAuth2 Request Permissions."
 echo -e "To enable the OAuth2 Request Permissions of Wekan:"
 echo -e "To enable the OAuth2 Request Permissions of Wekan:"
-echo -e "\t$ snap set $SNAP_NAME oauth2-request-permissions=\"['openid','profile','email']\""
+echo -e "\t$ snap set $SNAP_NAME oauth2-request-permissions=\"'openid profile email'\""
 echo -e "\t-Disable the OAuth2 Request Permissions of Wekan:"
 echo -e "\t-Disable the OAuth2 Request Permissions of Wekan:"
 echo -e "\t$ snap set $SNAP_NAME oauth2-request-permissions=''"
 echo -e "\t$ snap set $SNAP_NAME oauth2-request-permissions=''"
 echo -e "\n"
 echo -e "\n"

+ 8 - 1
start-wekan.bat

@@ -31,6 +31,13 @@ REM SET ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3
 REM SET ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60
 REM SET ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60
 REM SET ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15
 REM SET ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15
 
 
+REM # CORS: Set Access-Control-Allow-Origin header. Example: *
+REM SET CORS=*
+REM # To enable the Set Access-Control-Allow-Headers header. "Authorization,Content-Type" is required for cross-origin use of the API.
+REM SET CORS_ALLOW_HEADERS=Authorization,Content-Type
+REM # To enable the Set Access-Control-Expose-Headers header.  This is not needed for typical CORS situations. Example: *
+REM SET CORS_EXPOSE_HEADERS=*
+
 REM # Optional: Integration with Matomo https://matomo.org that is installed to your server
 REM # Optional: Integration with Matomo https://matomo.org that is installed to your server
 REM # The address of the server where Matomo is hosted.
 REM # The address of the server where Matomo is hosted.
 REM # example: - MATOMO_ADDRESS=https://example.com/matomo
 REM # example: - MATOMO_ADDRESS=https://example.com/matomo
@@ -96,7 +103,7 @@ REM # OAUTH2 ID Token Whitelist Fields.
 REM SET OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
 REM SET OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
 
 
 REM # OAUTH2 Request Permissions.
 REM # OAUTH2 Request Permissions.
-REM SET OAUTH2_REQUEST_PERMISSIONS=['openid','profile','email']
+REM SET OAUTH2_REQUEST_PERMISSIONS='openid profile email'
 
 
 REM # OAuth2 ID Mapping
 REM # OAuth2 ID Mapping
 REM SET OAUTH2_ID_MAP=
 REM SET OAUTH2_ID_MAP=

+ 5 - 1
start-wekan.sh

@@ -39,6 +39,10 @@
       #---------------------------------------------
       #---------------------------------------------
       # CORS: Set Access-Control-Allow-Origin header. Example: *
       # CORS: Set Access-Control-Allow-Origin header. Example: *
       #export CORS=*
       #export CORS=*
+      # To enable the Set Access-Control-Allow-Headers header. "Authorization,Content-Type" is required for cross-origin use of the API.
+      #export CORS_ALLOW_HEADERS=Authorization,Content-Type
+      # To enable the Set Access-Control-Expose-Headers header.  This is not needed for typical CORS situations. Example: *
+      #export CORS_EXPOSE_HEADERS=*
       #---------------------------------------------
       #---------------------------------------------
       ## Optional: Integration with Matomo https://matomo.org that is installed to your server
       ## Optional: Integration with Matomo https://matomo.org that is installed to your server
       ## The address of the server where Matomo is hosted:
       ## The address of the server where Matomo is hosted:
@@ -127,7 +131,7 @@
       # OAUTH2 ID Token Whitelist Fields.
       # OAUTH2 ID Token Whitelist Fields.
       #export OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
       #export OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
       # OAUTH2 Request Permissions.
       # OAUTH2 Request Permissions.
-      #export OAUTH2_REQUEST_PERMISSIONS=['openid','profile','email']
+      #export OAUTH2_REQUEST_PERMISSIONS='openid profile email'
       # OAuth2 ID Mapping
       # OAuth2 ID Mapping
       #export OAUTH2_ID_MAP=
       #export OAUTH2_ID_MAP=
       # OAuth2 Username Mapping
       # OAuth2 Username Mapping

Някои файлове не бяха показани, защото твърде много файлове са промени