Compare commits

...
62 Commits
Author SHA1 Message Date
Lauri Ojansivu 2342c27ced v5.30 2021-06-03 23:29:01 +03:00
Lauri Ojansivu 80f6004404 Updated translations. 2021-06-03 23:20:51 +03:00
Lauri Ojansivu a94946c77c Updated ChangeLog. 2021-06-03 23:18:12 +03:00
Lauri Ojansivu 659a65b8b9 Moved Keyboard Shortcuts from bottom to top of sidebar.
Thanks to ClaudiaK21 and xet7 !
2021-06-03 23:15:13 +03:00
Lauri Ojansivu c4b55e862f Updated ChangeLog. 2021-06-03 22:33:04 +03:00
Lauri Ojansivu f8a75930b3 Updated ChangeLog. 2021-06-03 22:09:05 +03:00
Lauri Ojansivu 3a04b1b787 Updated ChangeLog. 2021-06-03 21:49:13 +03:00
Lauri Ojansivu ad61a15611 Updated translations. 2021-06-03 21:47:52 +03:00
Lauri Ojansivu d21bc0c277 Merge branch 'helioguardabaxo-master' 2021-06-03 21:26:55 +03:00
helioguardabaxo fa3d117372 Add Feature: Planning Poker 2021-06-03 12:01:15 -03:00
Lauri Ojansivu 26249f5928 Updated ChangeLog. 2021-06-01 18:55:25 +03:00
Lauri Ojansivu b7e6600e88 Merge pull request #3833 from Emile840/master
Fix bug #3832 'Default language is still used although this one has b…
2021-06-01 18:53:25 +03:00
Emile NDAGIJIMANA 6e46cad56c Fix bug #3832 'Default language is still used although this one has been modified previously' 2021-06-01 15:55:42 +02:00
Lauri Ojansivu e7340c5021 Reverted PR https://github.com/wekan/wekan/pull/3831
The default wekan logo appears briefly before displaying the custom logo

Thanks to xet7 !

Related #3832
2021-06-01 16:44:23 +03:00
Lauri Ojansivu 05d6c5f15a Updated translations. 2021-06-01 16:28:49 +03:00
Lauri Ojansivu 428442b310 Updated ChangeLog. 2021-06-01 16:20:52 +03:00
Lauri Ojansivu 753d247cf6 Merge pull request #3831 from Emile840/master
Fix bug #3830 '[Login page] The default wekan logo appears briefly before d…
2021-06-01 16:16:04 +03:00
Lauri Ojansivu 802f544cd5 Updated ChangeLog. 2021-06-01 12:46:35 +03:00
Lauri Ojansivu bf62a947fb Fixed Python API example: Edit card, etc.
Thanks to Lucky-Shi and xet7 !

Fixes #3767
2021-06-01 12:41:54 +03:00
Emile NDAGIJIMANA 5b08ae12a6 Fix bug '[Login page] The default wekan logo appears briefly before displaying the custom logo #3830' 2021-05-31 15:36:57 +02:00
Lauri Ojansivu 46e881bea3 v5.29 2021-05-29 01:06:44 +03:00
Lauri Ojansivu 5d1714dbd5 Updated ChangeLog. 2021-05-29 00:56:24 +03:00
Lauri Ojansivu bd1de94312 Fixed Importing JSON exports fails.
Thanks to KeptnArgo and xet7 !

Fixes #3742
2021-05-29 00:52:36 +03:00
Lauri Ojansivu 06937d0aa0 Updated translations. 2021-05-29 00:29:03 +03:00
Lauri Ojansivu 9e39731133 Updated ChangeLog. 2021-05-29 00:26:09 +03:00
Lauri Ojansivu 3908cd5413 Fix: Impersonate user can now export Excel/CSV/TSV/JSON.
Impersonate user and export Excel/CSV/TSV/JSON is now logged into
database table impersonatedUsers.

Thanks to xet7 !

Fixes #3827,
fixes #3284
2021-05-29 00:19:12 +03:00
Lauri Ojansivu 6be1a33093 Updated dependencies.
Thanks to developers of dependencies!
2021-05-29 00:15:42 +03:00
Lauri Ojansivu c656cbf6ae Updated translations. 2021-05-25 17:42:28 +03:00
Lauri Ojansivu 83045a6512 Updated ChangeLog. 2021-05-18 12:59:07 +03:00
Lauri Ojansivu 199485640f Merge pull request #3813 from spasche/typos
Fix typos
2021-05-18 12:43:18 +03:00
Sylvain Pasche 2e41ff1121 Fix typos. 2021-05-17 23:41:36 +02:00
Lauri Ojansivu 487c6fae8d Updated ChangeLog. 2021-05-16 17:10:34 +03:00
Lauri Ojansivu ea64b17b82 Reworded issue template about can not login.
Thanks to xet7 !
2021-05-16 13:34:49 +03:00
Lauri Ojansivu 6d0578fd5a Added Forgot Password page to GitHub issue template.
Thanks to xet7 !
2021-05-16 13:27:56 +03:00
Lauri Ojansivu 76a4deda78 Updated ChangeLog. 2021-05-12 19:33:05 +03:00
Lauri Ojansivu 595abd303c Merge pull request #3799 from Enishowk/feature/excel_parentNameExport
Feature/excel parent card name export
2021-05-12 19:30:43 +03:00
Lauri Ojansivu 5dd6466c0a Removed not working GitHub workflow.
Thanks to xet7 !
2021-05-10 20:26:23 +03:00
Lauri Ojansivu 38655ee478 Merge branch 'master' of github.com:wekan/wekan 2021-05-09 07:53:08 +03:00
Lauri Ojansivu 23ca25a1ca Updated translations. 2021-05-09 07:52:45 +03:00
Enishowk 120cb4820e fix: typo 2021-05-07 18:58:24 +02:00
Enishowk 3ee0add6f6 feat: add parent name column in excel export 2021-05-07 18:54:59 +02:00
Lauri Ojansivu 8911fe5c8d Try to fix Snap: Removed linting packages.
Thanks to xet7 !
2021-05-07 18:12:49 +03:00
Lauri Ojansivu 1d9346513e Update dependencies.
Thanks to developers of dependencies !
2021-05-07 17:46:22 +03:00
Lauri Ojansivu 62150ce6c4 Updated dependencies.
Thanks to developers of dependencies!
2021-05-07 17:09:31 +03:00
Lauri Ojansivu b2d4135dca v5.28 2021-05-07 16:23:55 +03:00
Lauri Ojansivu 49e3e01ece Updated translations. 2021-05-07 13:20:53 +03:00
Lauri Ojansivu 23c2ff0e29 Updated ChangeLog. 2021-05-07 12:53:18 +03:00
Lauri Ojansivu a550c255e6 Updated dependencies.
Thanks to developers of dependencies !
2021-05-07 12:51:54 +03:00
Lauri Ojansivu 6b897faaa8 Updated ChangeLog. 2021-05-07 12:34:10 +03:00
Lauri Ojansivu 48255f6f1e Updated dependencies.
Thanks to developers of dependencies !
2021-05-07 12:32:44 +03:00
Lauri Ojansivu 45bc3bd3db Updated ChangeLog. 2021-05-07 02:23:40 +03:00
Lauri Ojansivu 5ab20a9257 Added markdown-it-mermaid for some charts support in all input fields. Replaced xss with dompurify.
Thanks to xuguotong and xet7 !

Fixes #3794
2021-05-07 02:13:20 +03:00
Lauri Ojansivu 88e4918208 Updated ChangeLog. 2021-05-06 18:29:44 +03:00
Lauri Ojansivu 521ef8b6da Updated dependencies.
Thanks to developers of dependencies !
2021-05-06 18:26:32 +03:00
Lauri Ojansivu 0d86dfa571 Updated translations. 2021-05-06 18:14:05 +03:00
Lauri Ojansivu 472350e56f Merge branch 'listenerri-patch-1' 2021-05-06 18:00:06 +03:00
listenerri 68569b9640 Update cardDate.js 2021-05-06 10:08:01 +08:00
Lauri Ojansivu 823f11d5dd v5.27 2021-04-29 13:39:08 +03:00
Lauri Ojansivu ae19018831 Updated translations. 2021-04-29 13:33:13 +03:00
Lauri Ojansivu d5b09c7b3e Updated dependencies. 2021-04-29 13:32:25 +03:00
Lauri Ojansivu d3b4aa4dc7 Updated ChangeLog. 2021-04-29 13:29:06 +03:00
Lauri Ojansivu c2da477735 Fixed Non-ASCII attachment filename will crash when downloading.
Thanks to xet7 !

Fixes #2759
2021-04-29 13:26:49 +03:00
367 changed files with 51487 additions and 13206 deletions

No files matched your search

+3
View File
@@ -1,5 +1,8 @@
## Issue
If you can not login for any reason:
- https://github.com/wekan/wekan/wiki/Forgot-Password
Email settings:
- https://github.com/wekan/wekan/wiki/Troubleshooting-Mail
-12
View File
@@ -1,12 +0,0 @@
on: [push]
jobs:
zap_scan:
runs-on: ubuntu-latest
name: Scan the webapplication
steps:
- name: OWASP ZAP Scan
runs-on: ubuntu-latest
uses: zaproxy/action-baseline@v0.4.0
with:
target: 'https://boards.wekan.team/sign-in'
+3 -3
View File
@@ -17,7 +17,7 @@ es5-shim@4.8.0
# Collections
aldeed:collection2
cfs:standard-packages
wekan-cfs-standard-packages
cottz:publish-relations
dburles:collection-helpers
idmontie:migrations
@@ -75,7 +75,7 @@ horka:swipebox
dynamic-import@0.6.0
accounts-password@1.7.0
cfs:gridfs
wekan-cfs-gridfs
rzymek:fullcalendar
momentjs:moment@2.22.2
browser-policy-framing@1.1.0
@@ -91,7 +91,7 @@ meteorhacks:aggregate@1.3.0
wekan-markdown
konecty:mongo-counter
percolate:synced-cron
cfs:filesystem
wekan-cfs-filesystem
tmeasday:check-npm-versions
steffo:meteor-accounts-saml
rajit:bootstrap3-datepicker-fi
+26 -25
View File
@@ -1,7 +1,7 @@
3stack:presence@1.1.2
accounts-base@1.9.0
accounts-oauth@1.2.0
accounts-password@1.7.0
accounts-password@1.7.1
aldeed:collection2@2.10.0
aldeed:collection2-core@1.2.0
aldeed:schema-deny@1.1.0
@@ -23,24 +23,7 @@ browser-policy-framing@1.1.0
caching-compiler@1.2.2
caching-html-compiler@1.2.0
callback-hook@1.3.0
cfs:access-point@0.1.49
cfs:base-package@0.0.30
cfs:collection@0.5.5
cfs:collection-filters@0.2.4
cfs:data-man@0.0.6
cfs:file@0.1.17
cfs:filesystem@0.1.2
cfs:gridfs@0.0.34
cfs:http-methods@0.0.32
cfs:http-publish@0.0.13
cfs:power-queue@0.9.11
cfs:reactive-list@0.0.9
cfs:reactive-property@0.0.4
cfs:standard-packages@0.5.10
cfs:storage-adapter@0.2.4
cfs:tempstore@0.1.6
cfs:upload-http@0.0.20
cfs:worker@0.1.5
check@1.3.1
chuangbo:cookie@1.1.0
coagmano:stylus@1.1.0
@@ -49,7 +32,7 @@ coffeescript-compiler@2.4.1
cottz:publish-relations@2.0.8
dburles:collection-helpers@1.1.0
ddp@1.4.0
ddp-client@2.4.0
ddp-client@2.4.1
ddp-common@1.4.0
ddp-rate-limiter@1.0.9
ddp-server@2.3.3
@@ -72,8 +55,8 @@ horka:swipebox@1.0.2
hot-code-push@1.0.4
html-tools@1.1.1
htmljs@1.1.0
http@1.4.3
id-map@1.1.0
http@1.4.4
id-map@1.1.1
idmontie:migrations@1.0.3
inter-process-messaging@0.1.1
jquery@1.11.11
@@ -109,10 +92,10 @@ modern-browsers@0.1.5
modules@0.16.0
modules-runtime@0.12.0
momentjs:moment@2.29.1
mongo@1.11.0
mongo@1.11.1
mongo-decimal@0.1.2
mongo-dev-server@1.1.0
mongo-id@1.0.7
mongo-id@1.0.8
mongo-livedata@1.0.12
mousetrap:mousetrap@1.4.6_1
mquandalle:autofocus@1.0.0
@@ -191,7 +174,7 @@ rajit:bootstrap3-datepicker-zh-cn@1.7.1
rajit:bootstrap3-datepicker-zh-tw@1.7.1
random@1.2.0
rate-limit@1.0.9
react-fast-refresh@0.1.0
react-fast-refresh@0.1.1
reactive-dict@1.3.0
reactive-var@1.0.11
reload@1.3.1
@@ -208,7 +191,7 @@ simple:json-routes@2.1.0
simple:rest-accounts-password@1.1.2
simple:rest-bearer-token-parser@1.0.1
simple:rest-json-error-handler@1.0.1
socket-stream-client@0.3.2
socket-stream-client@0.3.3
softwarerero:accounts-t9n@1.3.11
spacebars@1.1.0
spacebars-compiler@1.2.1
@@ -238,6 +221,24 @@ webapp@1.10.1
webapp-hashing@1.1.0
wekan-accounts-cas@0.1.0
wekan-accounts-oidc@1.0.10
wekan-cfs-access-point@0.1.50
wekan-cfs-base-package@0.0.30
wekan-cfs-collection@0.5.5
wekan-cfs-collection-filters@0.2.4
wekan-cfs-data-man@0.0.6
wekan-cfs-file@0.1.17
wekan-cfs-filesystem@0.1.2
wekan-cfs-gridfs@0.0.34
wekan-cfs-http-methods@0.0.32
wekan-cfs-http-publish@0.0.13
wekan-cfs-power-queue@0.9.11
wekan-cfs-reactive-list@0.0.9
wekan-cfs-reactive-property@0.0.4
wekan-cfs-standard-packages@0.5.10
wekan-cfs-storage-adapter@0.2.4
wekan-cfs-tempstore@0.1.6
wekan-cfs-upload-http@0.0.21
wekan-cfs-worker@0.1.5
wekan-ldap@0.0.2
wekan-markdown@1.0.9
wekan-oidc@1.0.12
+88
View File
@@ -1,3 +1,91 @@
[Mac ChangeLog](https://github.com/wekan/wekan/wiki/Mac)
# v5.30 2021-06-03 Wekan release
This release adds the following new features:
- [Planning Poker / Scrum Poker](https://github.com/wekan/wekan/pull/3836),
see https://github.com/wekan/wekan/wiki/Planning-Poker .
Thanks to helioguardabaxo.
and fixes the following bugs:
- [Fixed Python API example: Edit card, etc](https://github.com/wekan/wekan/commit/bf62a947fbfa7d387074550288376e682fd6ad47).
Thanks to Lucky-Shi and xet7.
- [Default language is still used although this one has been modified previously](https://github.com/wekan/wekan/pull/3833).
Thanks to Emile840.
- [Moved Keyboard Shortcuts from bottom to top of Sidebar](https://github.com/wekan/wekan/commit/659a65b8b919a49ba0beef5cc53d8e61e0f794aa).
Thanks to ClaudiaK21 and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.29 2021-05-29 Wekan release
This release adds the following new features:
- [Excel parent card name export](https://github.com/wekan/wekan/pull/3799).
Thanks to marcungeschikts and Enishowk.
and adds the following updates:
- Updated dependencies
[Part 1](https://github.com/wekan/wekan/commit/62150ce6c406359fba068552b4526c60faf392bb),
[Part 2](https://github.com/wekan/wekan/commit/1d9346513e4f378379b9f5192e8dad5535287f8a),
[Part 3](https://github.com/wekan/wekan/commit/6be1a330936c89fcf478efe98dd15244a98d266d).
Thanks to developers of dependencies.
- Added updated `Forgot Password` page to GitHub issue template
[Part 1](https://github.com/wekan/wekan/commit/6d0578fd5ad5f13f5ff9a285577e35fd62bba95f),
[Part 2](https://github.com/wekan/wekan/commit/ea64b17b82cd52320c0495e16385f11031dfbe3a).
Thanks to xet7.
and fixes the following bugs:
- [Try to fix Snap: Removed linting packages](https://github.com/wekan/wekan/commit/8911fe5c8de941808585a7d3462305d5b3d2763d).
Thanks to xet7.
- [Removed not working GitHub workflow](https://github.com/wekan/wekan/commit/5dd6466c0aa7479015c72519f36c2485b16e3341).
Thanks to xet7.
- [Fix typos](https://github.com/wekan/wekan/pull/3813).
Thanks to spasche.
- [Fix: Impersonate user can now export Excel/CSV/TSV/JSON.
Impersonate user and export Excel/CSV/TSV/JSON is now logged into database table
impersonatedUsers](https://github.com/wekan/wekan/commit/3908cd5413b775d1ee549f0a95304cf9998d3855).
Thanks to xet7.
- [Fixed Importing JSON exports fails](https://github.com/wekan/wekan/commit/bd1de94312e428e56d6cf5f343098475573cba0b).
Thanks to KeptnArgo and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.28 2021-05-07 Wekan release
This release adds the following new features:
- [Mermaid Diagram](https://github.com/wekan/wekan/wiki/Mermaid-Diagram).
Thanks to xuguotong and xet7.
and adds the following updates:
- Updated dependencies
[Part 1](https://github.com/wekan/wekan/commit/521ef8b6dad4f00662f22702331193c16b91b482),
[Part 2](https://github.com/wekan/wekan/commit/48255f6f1e4a0caf0be006196f28295d0825eb95),
[Part 3](https://github.com/wekan/wekan/commit/a550c255e6c3bd2d609a1a45a213cdae7ab4f74d).
Thanks to developers of dependencies.
and fixes the following bugs:
- [Fix: BG color of StartDate](https://github.com/wekan/wekan/pull/3793).
Thanks to listenerri.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.27 2021-04-29 Wekan release
This release fixes the following bugs:
- [Fixed Non-ASCII attachment filename will crash when downloading](https://github.com/wekan/wekan/commit/c2da47773552a61d45b010a095f73d2e441f687c).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v5.26 2021-04-28 Wekan release
This release adds the following new features:
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v5.26.0"
appVersion: "v5.30.0"
files:
userUploads:
- README.md
+48 -8
View File
@@ -28,12 +28,16 @@ if arguments == 0:
print(" python3 api.py board BOARDID # Info of BOARDID")
print(" python3 api.py swimlanes BOARDID # Swimlanes of BOARDID")
print(" python3 api.py lists BOARDID # Lists of BOARDID")
print(" python3 api.py list BOARDID LISTID # Info of LISTID")
print(" python3 api.py createlist BOARDID LISTTITLE # Create list")
print(" python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION")
print(" python3 api.py editcard BOARDID LISTID CARDID NEWCARDTITLE NEWCARDDESCRIPTION")
print(" python3 api.py listattachments BOARDID # List attachments")
# TODO:
# print(" python3 api.py attachmentdownload BOARDID ATTACHMENTID # One attachment as file")
# print(" python3 api.py attachmentsdownload BOARDID # All attachments as files")
# print(" python3 api.py attachmentjson BOARDID ATTACHMENTID # One attachment as JSON base64")
# print(" python3 api.py attachmentbinary BOARDID ATTACHMENTID # One attachment as binary file")
# print(" python3 api.py attachmentdownload BOARDID ATTACHMENTID # One attachment as file")
# print(" python3 api.py attachmentsdownload BOARDID # All attachments as files")
exit
# ------- SETTINGS START -------------
@@ -61,13 +65,15 @@ chmod +x api.py
=== Wekan API Python CLI: Shows IDs for addcard ===
AUTHORID is USERID that writes card.
Syntax:
python3 api.py users # All users
python3 api.py boards USERID # Boards of USERID
python3 api.py board BOARDID # Info of BOARDID
python3 api.py swimlanes BOARDID # Swimlanes of BOARDID
python3 api.py lists BOARDID # Lists of BOARDID
python3 api.py users # All users
python3 api.py boards USERID # Boards of USERID
python3 api.py board BOARDID # Info of BOARDID
python3 api.py swimlanes BOARDID # Swimlanes of BOARDID
python3 api.py lists BOARDID # Lists of BOARDID
python3 api.py list BOARDID LISTID # Info of LISTID
python3 api.py createlist BOARDID LISTTITLE # Create list
python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION
python3 api.py editcard BOARDID LISTID CARDID NEWCARDTITLE NEWCARDDESCRIPTION
python3 api.py listattachments BOARDID # List attachments
python3 api.py attachmentjson BOARDID ATTACHMENTID # One attachment as JSON base64
python3 api.py attachmentbinary BOARDID ATTACHMENTID # One attachment as binary file
@@ -162,6 +168,27 @@ if arguments == 7:
print(body.text)
# ------- WRITE TO CARD END -----------
if arguments == 6:
if sys.argv[1] == 'editcard':
# ------- LIST OF BOARD START -----------
boardid = sys.argv[2]
listid = sys.argv[3]
cardid = sys.argv[4]
newcardtitle = sys.argv[5]
newcarddescription = sys.argv[6]
edcard = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid
print(edcard)
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
put_data = {'title': '{}'.format(newcardtitle), 'description': '{}'.format(newcarddescription)}
body = requests.put(edcard, data=put_data, headers=headers)
print("=== EDIT CARD ===\n")
body = requests.get(edcard, headers=headers)
data2 = body.text.replace('}',"}\n")
print(data2)
# ------- LISTS OF BOARD END -----------
if arguments == 3:
if sys.argv[1] == 'createlist':
@@ -177,6 +204,19 @@ if arguments == 3:
print(body.text)
# ------- CREATE LIST END -----------
if sys.argv[1] == 'list':
# ------- LIST OF BOARD START -----------
boardid = sys.argv[2]
listid = sys.argv[3]
listone = wekanurl + apiboards + boardid + s + l + s + listid
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
print("=== INFO OF ONE LIST ===\n")
body = requests.get(listone, headers=headers)
data2 = body.text.replace('}',"}\n")
print(data2)
# ------- LISTS OF BOARD END -----------
if arguments == 2:
# ------- BOARDS LIST START -----------
@@ -217,7 +257,7 @@ if arguments == 2:
# ------- LISTS OF BOARD START -----------
boardid = sys.argv[2]
attachments = wekanurl + apiboards + boardid
lists = wekanurl + apiboards + boardid + s + l
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
print("=== LISTS ===\n")
body = requests.get(lists, headers=headers)
+12 -8
View File
@@ -1,4 +1,4 @@
import sanitizeXss from 'xss';
import DOMPurify from 'dompurify';
const activitiesPerPage = 500;
@@ -162,11 +162,15 @@ BlazeComponent.extendComponent({
{
href: source.url,
},
sanitizeXss(source.system),
DOMPurify.sanitize(source.system, {
ALLOW_UNKNOWN_PROTOCOLS: true,
}),
),
);
} else {
return sanitizeXss(source.system);
return DOMPurify.sanitize(source.system, {
ALLOW_UNKNOWN_PROTOCOLS: true,
});
}
}
return null;
@@ -190,10 +194,10 @@ BlazeComponent.extendComponent({
href: attachment.url({ download: true }),
target: '_blank',
},
sanitizeXss(attachment.name()),
DOMPurify.sanitize(attachment.name()),
),
)) ||
sanitizeXss(this.currentData().activity.attachmentName)
DOMPurify.sanitize(this.currentData().activity.attachmentName)
);
},
@@ -232,7 +236,7 @@ BlazeComponent.extendComponent({
Template.activity.helpers({
sanitize(value) {
return sanitizeXss(value);
return DOMPurify.sanitize(value, { ALLOW_UNKNOWN_PROTOCOLS: true });
},
});
@@ -246,7 +250,7 @@ function createCardLink(card) {
href: card.originRelativeUrl(),
class: 'action-card',
},
sanitizeXss(card.title),
DOMPurify.sanitize(card.title, { ALLOW_UNKNOWN_PROTOCOLS: true }),
),
)
);
@@ -263,7 +267,7 @@ function createBoardLink(board, list) {
href: board.originRelativeUrl(),
class: 'action-board',
},
sanitizeXss(text),
DOMPurify.sanitize(text, { ALLOW_UNKNOWN_PROTOCOLS: true }),
),
)
);
+9
View File
@@ -22,6 +22,15 @@ Template.boardListHeaderBar.helpers({
BlazeComponent.extendComponent({
onCreated() {
Meteor.subscribe('setting');
let currUser = Meteor.user();
let userLanguage;
if(currUser && currUser.profile){
userLanguage = currUser.profile.language
}
if (userLanguage) {
TAPi18n.setLanguage(userLanguage);
T9n.setLanguage(userLanguage);
}
},
onRendered() {
+28 -1
View File
@@ -187,7 +187,7 @@ class CardStartDate extends CardDate {
// if dueAt or endAt exist & are > startAt, startAt doesn't need to be flagged
if ((endAt && theDate.isAfter(endAt)) || (dueAt && theDate.isAfter(dueAt)))
classes += 'long-overdue';
else if (theDate.isBefore(now, 'minute')) classes += 'almost-due';
else if (theDate.isAfter(now)) classes += '';
else classes += 'current';
return classes;
}
@@ -354,3 +354,30 @@ class VoteEndDate extends CardDate {
}
}
VoteEndDate.register('voteEndDate');
class PokerEndDate extends CardDate {
onCreated() {
super.onCreated();
const self = this;
self.autorun(() => {
self.date.set(moment(self.data().getPokerEnd()));
});
}
classes() {
const classes = 'end-date' + ' ';
return classes;
}
showDate() {
return this.date.get().format('l LT');
}
showTitle() {
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
}
events() {
return super.events().concat({
'click .js-edit-date': Popup.open('editPokerEndDate'),
});
}
}
PokerEndDate.register('pokerEndDate');
+229
View File
@@ -243,6 +243,205 @@ template(name="cardDetails")
i.fa.fa-thumbs-down
| {{_ 'vote-against'}}
if getPokerQuestion
hr
.poker-title
div.flex
h3
i.fa.fa-thumbs-up
| {{_ 'poker-question'}}
if getPokerEnd
+pokerEndDate
div.flex
.poker-result
if expiredPoker
unless ($and currentBoard.isPublic pokerAllowNonBoardMembers )
.card-label.card-label-gray {{ pokerCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
if showPlanningPokerButtons
.poker-result
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-one(class="{{#if $eq pokerState 'one'}}poker-voted{{/if}}") {{_ 'poker-one'}}
if $eq pokerState "one"
i.fa.fa-check
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-two(class="{{#if $eq pokerState 'two'}}poker-voted{{/if}}") {{_ 'poker-two'}}
if $eq pokerState "two"
i.fa.fa-check
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-three(class="{{#if $eq pokerState 'three'}}poker-voted{{/if}}") {{_ 'poker-three'}}
if $eq pokerState "three"
i.fa.fa-check
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-five(class="{{#if $eq pokerState 'five'}}poker-voted{{/if}}") {{_ 'poker-five'}}
if $eq pokerState "five"
i.fa.fa-check
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-eight(class="{{#if $eq pokerState 'eight'}}poker-voted{{/if}}") {{_ 'poker-eight'}}
if $eq pokerState "eight"
i.fa.fa-check
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-thirteen(class="{{#if $eq pokerState 'thirteen'}}poker-voted{{/if}}") {{_ 'poker-thirteen'}}
if $eq pokerState "thirteen"
i.fa.fa-check
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-twenty(class="{{#if $eq pokerState 'twenty'}}poker-voted{{/if}}") {{_ 'poker-twenty'}}
if $eq pokerState "twenty"
i.fa.fa-check
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-forty(class="{{#if $eq pokerState 'forty'}}poker-voted{{/if}}") {{_ 'poker-forty'}}
if $eq pokerState "forty"
i.fa.fa-check
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-one-hundred(class="{{#if $eq pokerState 'oneHundred'}}poker-voted{{/if}}") {{_ 'poker-oneHundred'}}
if $eq pokerState "oneHundred"
i.fa.fa-check
.poker-deck
.poker-card
span.inner.js-poker.js-poker-vote-unsure(class="{{#if $eq pokerState 'unsure'}}poker-voted{{/if}}") {{_ 'poker-unsure'}}
if $eq pokerState "unsure"
i.fa.fa-check
if currentUser.isBoardAdmin
button.card-details-blue.js-poker-finish(class="{{#if $eq voteState false}}poker-voted{{/if}}") {{_ 'poker-finish'}}
if expiredPoker
.poker-table
.poker-table-side-left
.poker-table-heading-left
.poker-table-row
.poker-table-cell
.poker-table-cell
| {{_ 'poker-result-votes' }}
.poker-table-cell.poker-table-cell-who
| {{_ 'poker-result-who' }}
.poker-table-body
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 1}}winner{{else}}loser{{/if}}") {{_ 'poker-one'}}
.poker-table-cell {{ pokerCountOne }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberOne
a.name
+userAvatar(userId=m._id noRemove=true)
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 2}}winner{{else}}loser{{/if}}") {{_ 'poker-two'}}
.poker-table-cell {{ pokerCountTwo }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberTwo
a.name
+userAvatar(userId=m._id noRemove=true)
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 3}}winner{{else}}loser{{/if}}") {{_ 'poker-three'}}
.poker-table-cell {{ pokerCountThree }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberThree
a.name
+userAvatar(userId=m._id noRemove=true)
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 5}}winner{{else}}loser{{/if}}") {{_ 'poker-five'}}
.poker-table-cell {{ pokerCountFive }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberFive
a.name
+userAvatar(userId=m._id noRemove=true)
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 8}}winner{{else}}loser{{/if}}") {{_ 'poker-eight'}}
.poker-table-cell {{ pokerCountEight }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberEight
a.name
+userAvatar(userId=m._id noRemove=true)
.poker-table-side-right
.poker-table-heading-right
.poker-table-row
.poker-table-cell
.poker-table-cell
| {{_ 'poker-result-votes' }}
.poker-table-cell.poker-table-cell-who
| {{_ 'poker-result-who' }}
.poker-table-body
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 13}}winner{{else}}loser{{/if}}") {{_ 'poker-thirteen'}}
.poker-table-cell {{ pokerCountThirteen }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberThirteen
a.name
+userAvatar(userId=m._id noRemove=true)
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 20}}winner{{else}}loser{{/if}}") {{_ 'poker-twenty'}}
.poker-table-cell {{ pokerCountTwenty }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberTwenty
a.name
+userAvatar(userId=m._id noRemove=true)
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 40}}winner{{else}}loser{{/if}}") {{_ 'poker-forty'}}
.poker-table-cell {{ pokerCountForty }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberForty
a.name
+userAvatar(userId=m._id noRemove=true)
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 100}}winner{{else}}loser{{/if}}") {{_ 'poker-oneHundred'}}
.poker-table-cell {{ pokerCountOneHundred }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberOneHundred
a.name
+userAvatar(userId=m._id noRemove=true)
.poker-table-row
.poker-table-cell
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 'unsure'}}winner{{else}}loser{{/if}}") {{_ 'poker-unsure'}}
.poker-table-cell {{ pokerCountUnsure }}
.poker-table-cell.poker-table-cell-who
.poker-result
each m in pokerMemberUnsure
a.name
+userAvatar(userId=m._id noRemove=true)
if currentUser.isBoardAdmin
div.estimation-add
button.card-details-red.js-poker-replay(class="{{#if $eq voteState false}}voted{{/if}}") {{_ 'poker-replay'}}
div.estimation-add
button.js-poker-estimation
i.fa.fa-plus
| {{_ 'set-estimation'}}
input(type=text,autofocus value=getPokerEstimation,id="pokerEstimation")
//- XXX We should use "editable" to avoid repetiting ourselves
if canModifyCard
unless currentUser.isWorker
@@ -362,6 +561,10 @@ template(name="cardDetailsActionsPopup")
a.js-start-voting
i.fa.fa-thumbs-up
| {{_ 'card-edit-voting'}}
li
a.js-start-planning-poker
i.fa.fa-thumbs-up
| {{_ 'card-edit-planning-poker'}}
if currentUser.isBoardAdmin
li
a.js-custom-fields
@@ -621,3 +824,29 @@ template(name="negativeVoteMembersPopup")
span.full-name
= m.profile.fullname
| (<span class="username">{{ m.username }}</span>)
template(name="deletePokerPopup")
p {{_ "poker-delete-pop"}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
template(name="cardStartPlanningPokerPopup")
form.edit-poker-question
.fields
.check-div
a.flex(class="{{#if getPokerQuestion}}is-disabled{{else}}js-toggle-poker-allow-non-members{{/if}}")
.materialCheckBox#poker-allow-non-members(name="poker-allow-non-members" class="{{#if pokerAllowNonBoardMembers}}is-checked{{/if}}")
span {{_ 'allowNonBoardMembers'}}
.check-div.flex
i.fa.fa-hourglass-end
a.js-end-date
span
| {{_ 'card-end'}}
unless getPokerEnd
i.fa.fa-plus
if getPokerEnd
+pokerEndDate
button.primary.js-submit {{_ 'save'}}
if getPokerQuestion
if currentUser.isBoardAdmin
button.js-remove-poker.negate.wide.right {{_ 'delete'}}
+174
View File
@@ -140,6 +140,15 @@ BlazeComponent.extendComponent({
);
},
showPlanningPokerButtons() {
const card = this.currentData();
return (
(currentUser.isBoardMember() ||
(currentUser && card.pokerAllowNonBoardMembers())) &&
!card.expiredPoker()
);
},
onRendered() {
if (Meteor.settings.public.CARD_OPENED_WEBHOOK_ENABLED) {
// Send Webhook but not create Activities records ---
@@ -407,6 +416,80 @@ BlazeComponent.extendComponent({
}
this.data().setVote(Meteor.userId(), newState);
},
'click .js-poker'(e) {
let newState = null;
if ($(e.target).hasClass('js-poker-vote-one')) {
newState = 'one';
this.data().setPoker(Meteor.userId(), newState);
}
if ($(e.target).hasClass('js-poker-vote-two')) {
newState = 'two';
this.data().setPoker(Meteor.userId(), newState);
}
if ($(e.target).hasClass('js-poker-vote-three')) {
newState = 'three';
this.data().setPoker(Meteor.userId(), newState);
}
if ($(e.target).hasClass('js-poker-vote-five')) {
newState = 'five';
this.data().setPoker(Meteor.userId(), newState);
}
if ($(e.target).hasClass('js-poker-vote-eight')) {
newState = 'eight';
this.data().setPoker(Meteor.userId(), newState);
}
if ($(e.target).hasClass('js-poker-vote-thirteen')) {
newState = 'thirteen';
this.data().setPoker(Meteor.userId(), newState);
}
if ($(e.target).hasClass('js-poker-vote-twenty')) {
newState = 'twenty';
this.data().setPoker(Meteor.userId(), newState);
}
if ($(e.target).hasClass('js-poker-vote-forty')) {
newState = 'forty';
this.data().setPoker(Meteor.userId(), newState);
}
if ($(e.target).hasClass('js-poker-vote-one-hundred')) {
newState = 'oneHundred';
this.data().setPoker(Meteor.userId(), newState);
}
if ($(e.target).hasClass('js-poker-vote-unsure')) {
newState = 'unsure';
this.data().setPoker(Meteor.userId(), newState);
}
},
'click .js-poker-finish'(e) {
if ($(e.target).hasClass('js-poker-finish')) {
e.preventDefault();
const now = moment().format('YYYY-MM-DD HH:mm');
this.data().setPokerEnd(now);
}
},
'click .js-poker-replay'(e) {
if ($(e.target).hasClass('js-poker-replay')) {
e.preventDefault();
this.currentCard = this.currentData();
this.currentCard.replayPoker();
this.data().unsetPokerEnd();
this.data().unsetPokerEstimation();
}
},
'click .js-poker-estimation'(event) {
event.preventDefault();
const ruleTitle = this.find('#pokerEstimation').value;
if (ruleTitle !== undefined && ruleTitle !== '') {
this.find('#pokerEstimation').value = '';
if (ruleTitle) {
this.data().setPokerEstimation(parseInt(ruleTitle, 10));
} else {
this.data().setPokerEstimation('');
}
}
},
},
];
},
@@ -477,6 +560,7 @@ Template.cardDetailsActionsPopup.events({
'click .js-labels': Popup.open('cardLabels'),
'click .js-attachments': Popup.open('cardAttachments'),
'click .js-start-voting': Popup.open('cardStartVoting'),
'click .js-start-planning-poker': Popup.open('cardStartPlanningPoker'),
'click .js-custom-fields': Popup.open('cardCustomFields'),
'click .js-received-date': Popup.open('editCardReceivedDate'),
'click .js-start-date': Popup.open('editCardStartDate'),
@@ -976,6 +1060,96 @@ BlazeComponent.extendComponent({
}
}.register('editVoteEndDatePopup'));
BlazeComponent.extendComponent({
onCreated() {
this.currentCard = this.currentData();
this.pokerQuestion = new ReactiveVar(this.currentCard.pokerQuestion);
},
events() {
return [
{
'click .js-end-date': Popup.open('editPokerEndDate'),
'submit .edit-poker-question'(evt) {
evt.preventDefault();
const pokerQuestion = true;
const allowNonBoardMembers = $('#poker-allow-non-members').hasClass(
'is-checked',
);
const endString = this.currentCard.getPokerEnd();
this.currentCard.setPokerQuestion(
pokerQuestion,
allowNonBoardMembers,
);
if (endString) {
this.currentCard.setPokerEnd(endString);
}
Popup.close();
},
'click .js-remove-poker': Popup.afterConfirm('deletePoker', () => {
event.preventDefault();
this.currentCard.unsetPoker();
Popup.close();
}),
'click a.js-toggle-poker-allow-non-members'(event) {
event.preventDefault();
$('#poker-allow-non-members').toggleClass('is-checked');
},
},
];
},
}).register('cardStartPlanningPokerPopup');
// editPokerEndDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getPokerEnd() && this.date.set(moment(this.data().getPokerEnd()));
}
events() {
return [
{
'submit .edit-date'(evt) {
evt.preventDefault();
// if no time was given, init with 12:00
const time =
evt.target.time.value ||
moment(new Date().setHours(12, 0, 0)).format('LT');
const dateString = `${evt.target.date.value} ${time}`;
const newDate = moment(dateString, 'L LT', true);
if (newDate.isValid()) {
// if active poker - store it
if (this.currentData().getPokerQuestion()) {
this._storeDate(newDate.toDate());
Popup.close();
} else {
this.currentData().poker = { end: newDate.toDate() }; // set poker end temp
Popup.back();
}
} else {
this.error.set('invalid-date');
evt.target.date.focus();
}
},
'click .js-delete-date'(evt) {
evt.preventDefault();
this._deleteDate();
Popup.close();
},
},
];
}
_storeDate(newDate) {
this.card.setPokerEnd(newDate);
}
_deleteDate() {
this.card.unsetPokerEnd();
}
}.register('editPokerEndDatePopup'));
// Close the card details pane by pressing escape
EscapeActions.register(
'detailsPane',
+128
View File
@@ -357,3 +357,131 @@ card-details-color(background, color...)
display: flex
.js-show-positive-votes
cursor: pointer
.poker-voted
opacity: .7
.poker-title
display: flex
justify-content: space-between
.js-edit-date
align-self: baseline
margin-left: 5px
.poker-result
display: flex
flex-flow: row wrap
.js-show-positive-poker-votes
cursor: pointer
.poker-deck
display: grid
flex-direction: column
text-align: center
.poker-card-result
width: 32px
font-size: 1em
font-weight: bold
padding: 4px 2px 4px 2px
cursor: default
.winner
font-weight: bold
outline: #2d2d2d solid 2px
.loser
opacity: .5
.responsive-table
overflow-x: auto
.poker-table
display: table
width: 100%
padding-top: 10px
.poker-table-row
display: table-row
.poker-table-heading
background-color: #EEE
display: table-header-group
.poker-table-cell
display: table-cell
padding: 0 0 5px 2px
border-bottom: 1px solid #d2d0d0
text-align: center
min-width: 45px
.poker-table-cell-who
width: 150px
vertical-align: middle
.poker-table-heading-left,
.poker-table-heading-right
display: table-header-group
font-weight: bold
border-top: 1px solid #808080
@media (max-width: 400px)
.poker-table-heading-right
display: none
.poker-table-body
display: table-row-group
.poker-table-side-left,
.poker-table-side-right
display: inline-block
.poker-table-side-right
padding-left: 10px
@media (max-width: 400px)
.poker-table-side-right
padding-left: 0px
.estimation-add
display: block
overflow: auto
margin-top: 15px
margin-bottom: 5px
input
display: inline-block
float: right
margin: auto
margin-right: 10px
width: 100px
button
display: inline-block
float: right
margin: auto
.poker-card
width:48px
height:72px
float:left
background:#fff
border-radius:5px
display:table
box-sizing:border-box
padding:5px
margin:3px
font-size:20px
font-weight: bold
text-shadow: #2d2d2d 1px 1px 0
box-shadow:0 0 5px #aaaaaa
text-align:center
position:relative
cursor: pointer
.inner
display:table-cell
vertical-align:middle
border-radius:5px
overflow:hidden
background-color: #cecece
+5
View File
@@ -121,6 +121,11 @@ template(name="minicard")
span.badge-text {{ voteCountPositive }}
span.badge-icon.fa.fa-thumbs-down(class="{{#if $eq voteState false}}text-red{{/if}}")
span.badge-text {{ voteCountNegative }}
if getPokerQuestion
.badge.badge-state-image-only(title=getPokerQuestion)
span.badge-icon.fa.fa-check(class="{{#if pokerState}}text-green{{/if}}")
if expiredPoker
span.badge-text {{ getPokerEstimation }}
if attachments.count
.badge
span.badge-icon.fa.fa-paperclip
+12 -5
View File
@@ -216,7 +216,7 @@ Template.editor.onRendered(() => {
var pastedData = clipboardData.getData('Text');
//if pasted data is an image, exit
if( !pastedData.length ){
if (!pastedData.length) {
e.preventDefault();
return;
}
@@ -241,7 +241,7 @@ Template.editor.onRendered(() => {
//the function is called before the text is really pasted.
updatePastedText(thisNote);
}, 10);
}
},
},
dialogsInBody: true,
spellCheck: true,
@@ -273,10 +273,12 @@ Template.editor.onRendered(() => {
}
});
import sanitizeXss from 'xss';
import DOMPurify from 'dompurify';
// Additional safeAttrValue function to allow for other specific protocols
// See https://github.com/leizongmin/js-xss/issues/52#issuecomment-241354114
/*
function mySafeAttrValue(tag, name, value, cssFilter) {
// only when the tag is 'a' and attribute is 'href'
// then use your custom function
@@ -302,6 +304,7 @@ function mySafeAttrValue(tag, name, value, cssFilter) {
return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
}
}
*/
// XXX I believe we should compute a HTML rendered field on the server that
// would handle markdown and user mentions. We can simply have two
@@ -317,7 +320,9 @@ Blaze.Template.registerHelper(
let content = Blaze.toHTML(view.templateContentBlock);
const currentBoard = Boards.findOne(Session.get('currentBoard'));
if (!currentBoard)
return HTML.Raw(sanitizeXss(content, { safeAttrValue: mySafeAttrValue }));
return HTML.Raw(
DOMPurify.sanitize(content, { ALLOW_UNKNOWN_PROTOCOLS: true }),
);
const knowedUsers = currentBoard.members.map(member => {
const u = Users.findOne(member.userId);
if (u) {
@@ -361,7 +366,9 @@ Blaze.Template.registerHelper(
content = content.replace(fullMention, Blaze.toHTML(link));
}
return HTML.Raw(sanitizeXss(content, { safeAttrValue: mySafeAttrValue }));
return HTML.Raw(
DOMPurify.sanitize(content, { ALLOW_UNKNOWN_PROTOCOLS: true }),
);
}),
);
+6 -4
View File
@@ -5,10 +5,6 @@ template(name="sidebar")
// title="{{showTongueTitle}}")
// i.fa.fa-navicon
.sidebar-shadow
.sidebar-content.sidebar-shortcuts
a.board-header-btn.js-shortcuts
i.fa.fa-keyboard-o
span {{_ 'keyboard-shortcuts' }}
.sidebar-content.js-board-sidebar-content
//a.hide-btn.js-hide-sidebar
// i.fa.fa-navicon
@@ -39,6 +35,12 @@ template(name="membersWidget")
h3
i.fa.fa-users
| {{_ 'members'}}
.sidebar-shortcuts
a.board-header-btn.js-shortcuts
i.fa.fa-keyboard-o
span {{_ 'keyboard-shortcuts' }}
unless currentUser.isCommentOnly
unless currentUser.isWorker
a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right
+3 -4
View File
@@ -100,13 +100,12 @@
margin-right: 10px
.sidebar-shortcuts
margin: 0
position: absolute
margin-left: 40%
padding: 0
top: auto
text-align: center
top: 7px
font-size: 0.8em
line-height: 1.6em
vertical-align: middle
color: darken(white, 40%)
.board-sidebar
+39 -10
View File
@@ -23,21 +23,30 @@ class DateFilter {
// past builds a filter for all dates before now
past() {
if (this._filterState == 'past') { this.reset(); return; }
if (this._filterState == 'past') {
this.reset();
return;
}
this._filter = { $lte: moment().toDate() };
this._updateState('past');
}
// today is a convenience method for calling relativeDay with 0
today() {
if (this._filterState == 'today') { this.reset(); return; }
if (this._filterState == 'today') {
this.reset();
return;
}
this.relativeDay(0);
this._updateState('today');
}
// tomorrow is a convenience method for calling relativeDay with 1
tomorrow() {
if (this._filterState == 'tomorrow') { this.reset(); return; }
if (this._filterState == 'tomorrow') {
this.reset();
return;
}
this.relativeDay(1);
this._updateState('tomorrow');
}
@@ -50,10 +59,18 @@ class DateFilter {
// relativeDay builds a filter starting from now and including all
// days up to today +/- offset.
relativeDay(offset) {
if (this._filterState == 'day') { this.reset(); return; }
if (this._filterState == 'day') {
this.reset();
return;
}
var startDay = moment().startOf('day').toDate(),
endDay = moment().endOf('day').add(offset, 'day').toDate();
var startDay = moment()
.startOf('day')
.toDate(),
endDay = moment()
.endOf('day')
.add(offset, 'day')
.toDate();
if (offset >= 0) {
this._filter = { $gte: startDay, $lte: endDay };
@@ -68,7 +85,10 @@ class DateFilter {
// weeks up to today +/- offset. This considers the user's preferred
// start of week day (as defined by Meteor).
relativeWeek(offset) {
if (this._filterState == 'week') { this.reset(); return; }
if (this._filterState == 'week') {
this.reset();
return;
}
// getStartDayOfWeek returns the offset from Sunday of the user's
// preferred starting day of the week. This date should be added
@@ -78,8 +98,14 @@ class DateFilter {
const weekStartDay = currentUser ? currentUser.getStartDayOfWeek() : 1;
// Moments are mutable so they must be cloned before modification
var thisWeekStart = moment().startOf('day').startOf('week').add(weekStartDay, 'days');
var thisWeekEnd = thisWeekStart.clone().add(offset, 'week').endOf('day');
var thisWeekStart = moment()
.startOf('day')
.startOf('week')
.add(weekStartDay, 'days');
var thisWeekEnd = thisWeekStart
.clone()
.add(offset, 'week')
.endOf('day');
var startDate = thisWeekStart.toDate();
var endDate = thisWeekEnd.toDate();
@@ -94,7 +120,10 @@ class DateFilter {
// noDate builds a filter for items where date is not set
noDate() {
if (this._filterState == 'noDate') { this.reset(); return; }
if (this._filterState == 'noDate') {
this.reset();
return;
}
this._filter = null;
this._updateState('noDate');
}
+5 -5
View File
@@ -68,7 +68,7 @@ version: '2'
# docker exec -it wekan-db bash
# # 3) and data directory
# cd /data
# # 4) Remove previos dump
# # 4) Remove previous dump
# rm -rf dump
# # 5) Exit db container
# exit
@@ -281,7 +281,7 @@ services:
#- NOTIFY_DUE_AT_HOUR_OF_DAY=8
#-----------------------------------------------------------------
# ==== EMAIL NOTIFICATION TIMEOUT, ms =====
# Defaut: 30000 ms = 30s
# Default: 30000 ms = 30s
#- EMAIL_NOTIFICATION_TIMEOUT=30000
#-----------------------------------------------------------------
# ==== CORS =====
@@ -348,7 +348,7 @@ services:
#- OAUTH2_USERNAME_MAP=email
# The claim name you want to map to the full name field:
#- OAUTH2_FULLNAME_MAP=name
# Tthe claim name you want to map to the email field:
# The claim name you want to map to the email field:
#- OAUTH2_EMAIL_MAP=email
#-----------------------------------------------------------------
# ==== OAUTH2 Nextcloud ====
@@ -374,7 +374,7 @@ services:
#- OAUTH2_USERNAME_MAP=id
# The claim name you want to map to the full name field:
#- OAUTH2_FULLNAME_MAP=display-name
# Tthe claim name you want to map to the email field:
# The claim name you want to map to the email field:
#- OAUTH2_EMAIL_MAP=email
#-----------------------------------------------------------------
# ==== OAUTH2 KEYCLOAK ====
@@ -526,7 +526,7 @@ services:
# The attribute inside a group object listing its members. Example: member
#- LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE=
#
# The format of the value of LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE. Example: 'dn' if the users dn ist saved as value into the attribute.
# The format of the value of LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE. Example: 'dn' if the users dn is saved as value into the attribute.
#- LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT=
#
# The group name (id) that matches all users.
+6 -6
View File
@@ -4,11 +4,11 @@
var Meteor = Package.meteor.Meteor;
var global = Package.meteor.global;
var meteorEnv = Package.meteor.meteorEnv;
var FS = Package['cfs:base-package'].FS;
var FS = Package['wekan-cfs-base-package'].FS;
var check = Package.check.check;
var Match = Package.check.Match;
var EJSON = Package.ejson.EJSON;
var HTTP = Package['cfs:http-methods'].HTTP;
var HTTP = Package['wekan-cfs-http-methods'].HTTP;
/* Package-scope variables */
var rootUrlPathPrefix, baseUrl, getHeaders, getHeadersByCollection, _existingMountPoints, mountUrls;
@@ -25,7 +25,7 @@ var rootUrlPathPrefix, baseUrl, getHeaders, getHeadersByCollection, _existingMou
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/cfs:access-point/access-point-common.js //
// packages/wekan-cfs-access-point/access-point-common.js //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
@@ -217,7 +217,7 @@ FS.File.prototype.url = function(options) {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/cfs:access-point/access-point-handlers.js //
// packages/wekan-cfs-access-point/access-point-handlers.js //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
@@ -537,7 +537,7 @@ FS.HTTP.Handlers.PutUpdate = function httpPutUpdateHandler(ref) {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/cfs:access-point/access-point-server.js //
// packages/wekan-cfs-access-point/access-point-server.js //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
@@ -909,6 +909,6 @@ Meteor.startup(function () {
/* Exports */
if (typeof Package === 'undefined') Package = {};
Package['cfs:access-point'] = {};
Package['wekan-cfs-access-point'] = {};
})();
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+26 -4
View File
@@ -178,6 +178,27 @@
"vote-against": "ضد",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "حذف البطاقة ?",
"cardDetailsActionsPopup-title": "إجراءات على البطاقة",
"cardLabelsPopup-title": "علامات",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "بطاقات",
"cards-count": "بطاقات",
"cards-count-one": "بطاقة",
"casSignIn": "تسجيل الدخول مع CAS",
"cardType-card": "بطاقة",
"cardType-linkedCard": "البطاقة المرتبطة",
@@ -1000,10 +1022,10 @@
"custom-field-stringtemplate-format": "Format (use %{value} as placeholder)",
"custom-field-stringtemplate-separator": "Separator (use &#32; or &nbsp; for a space)",
"custom-field-stringtemplate-item-placeholder": "Press enter to add more items",
"creator": "Creator",
"filesReportTitle": "Files Report",
"orphanedFilesReportTitle": "Orphaned Files Report",
"reports": "Reports",
"creator": "المنشئ",
"filesReportTitle": "تقارير الملفات",
"orphanedFilesReportTitle": "تقارير الملفات المعزولة",
"reports": "تقارير",
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane"
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "против",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Желаете да изтриете картата?",
"cardDetailsActionsPopup-title": "Опции",
"cardLabelsPopup-title": "Етикети",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Карти",
"cards-count": "Карти",
"cards-count-one": "Карта",
"casSignIn": "Sign In with CAS",
"cardType-card": "Карта",
"cardType-linkedCard": "Свързана карта",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Diverkañ ar gartenn ?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Kartennoù",
"cards-count": "Kartennoù",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Esborrar fitxa?",
"cardDetailsActionsPopup-title": "Accions de fitxes",
"cardLabelsPopup-title": "Etiquetes",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Fitxes",
"cards-count": "Fitxes",
"cards-count-one": "Fitxa",
"casSignIn": "Sign In with CAS",
"cardType-card": "Fitxa",
"cardType-linkedCard": "Linked Card",
+72 -50
View File
@@ -178,6 +178,27 @@
"vote-against": "proti",
"deleteVotePopup-title": "Smazat hlas?",
"vote-delete-pop": "Smazání je nevratné. Ztratíte vše spojené s tímto hlasováním.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Smazat kartu?",
"cardDetailsActionsPopup-title": "Akce karty",
"cardLabelsPopup-title": "Štítky",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Vytvořit šablonu",
"cards": "Karty",
"cards-count": "Karty",
"cards-count-one": "Karta",
"casSignIn": "Přihlásit pomocí CAS",
"cardType-card": "Karta",
"cardType-linkedCard": "Propojená karta",
@@ -344,12 +366,12 @@
"list-label-short-sort": "(M)",
"filter": "Filtr",
"filter-cards": "Filtrovat karty nebo seznamy",
"filter-dates-label": "Filter by date",
"filter-no-due-date": "No due date",
"filter-overdue": "Overdue",
"filter-due-today": "Due today",
"filter-due-this-week": "Due this week",
"filter-due-tomorrow": "Due tomorrow",
"filter-dates-label": "Filtrovat podle data",
"filter-no-due-date": "Bez termínu",
"filter-overdue": "po termínu",
"filter-due-today": "Termín dnes",
"filter-due-this-week": "Termín tento týden",
"filter-due-tomorrow": "Termín zítra",
"list-filter-label": "Filtrovat seznam podle názvu",
"filter-clear": "Vyčistit filtr",
"filter-labels-label": "Filtrovat podle štítku",
@@ -538,7 +560,7 @@
"custom-login-logo-image-url": "URL vlastního loga přihlášení",
"custom-login-logo-link-url": "URL odkazu vlastního loga přihlášení",
"text-below-custom-login-logo": "Text pod vlastním logem přihlášení",
"automatic-linked-url-schemes": "Custom URL Schemes which should automatically be clickable. One URL Scheme per line",
"automatic-linked-url-schemes": "Vlastní URL schémata, která by automaticky měla být klikatelná.\nJedno schéma na řádek",
"username": "Uživatelské jméno",
"import-usernames": "Importovat uživatelská jména",
"view-it": "Zobrazit",
@@ -906,7 +928,7 @@
"operator-member-abbrev": "m",
"operator-assignee": "řešitel",
"operator-assignee-abbrev": "a",
"operator-creator": "creator",
"operator-creator": "tvůrce",
"operator-status": "stav",
"operator-due": "do",
"operator-created": "vytvořeno",
@@ -940,7 +962,7 @@
"operator-number-expected": "operátor __operator__ očekával číslo, ale dostal '__value__'",
"operator-sort-invalid": "pořadí '%s' není platné",
"operator-status-invalid": "'%s' není platný stav",
"operator-has-invalid": "%s is not a valid existence check",
"operator-has-invalid": "'%s' není platná kontrola existence",
"operator-limit-invalid": "není platný limit. Limit musí být pozitivní číslo.",
"next-page": "Následující stránka",
"previous-page": "Předchozí stránka",
@@ -948,29 +970,29 @@
"globalSearch-instructions-heading": "Vyhledat instrukce",
"globalSearch-instructions-description": "Vyhledávání lze za účelem zacílení doplnit o operátory. Operátory jsou zadávány napsáním názvu operátoru a hodnoty, které jsou odděleny dvojtečkou. Například specifikace operátoru `list:Blocked` omezí vyhledávání na karty obsažené ve sloupci *Blocked*. Pokud hodnota obsahuje mezerynebo speciální znaky, musí se nacházet v uvozovkách (např. `__operator_list__:\"To Review\"`).",
"globalSearch-instructions-operators": "Dostupné operátory:",
"globalSearch-instructions-operator-board": "`__operator_board__:<title>` - cards in boards matching the specified *<title>*",
"globalSearch-instructions-operator-list": "`__operator_list__:<title>` - cards in lists matching the specified *<title>*",
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<title>` - cards in swimlanes matching the specified *<title>*",
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - cards with a comment containing *<text>*.",
"globalSearch-instructions-operator-label": "`__operator_label__:<color>` `__operator_label__:<name>` - cards that have a label matching *<color>* or *<name>",
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name|color>` - shorthand for `__operator_label__:<color>` or `__operator_label__:<name>`",
"globalSearch-instructions-operator-user": "`__operator_user__:<username>` - cards where *<username>* is a *member* or *assignee*",
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - shorthand for `user:<username>`",
"globalSearch-instructions-operator-member": "`__operator_member__:<username>` - cards where *<username>* is a *member*",
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:<username>` - cards where *<username>* is an *assignee*",
"globalSearch-instructions-operator-creator": "`__operator_creator__:<username>` - cards where *<username>* is the card's creator",
"globalSearch-instructions-operator-due": "`__operator_due__:<n>` - cards which are due up to *<n>* days from now. `__operator_due__:__predicate_overdue__ lists all cards past their due date.",
"globalSearch-instructions-operator-created": "`__operator_created__:<n>` - cards which were created *<n>* days ago or less",
"globalSearch-instructions-operator-modified": "`__operator_modified__:<n>` - cards which were modified *<n>* days ago or less",
"globalSearch-instructions-operator-status": "`__operator_status__:<status>` - where *<status>* is one of the following:",
"globalSearch-instructions-status-archived": "`__predicate_archived__` - archived cards",
"globalSearch-instructions-status-all": "`__predicate_all__` - all archived and unarchived cards",
"globalSearch-instructions-status-ended": "`__predicate_ended__` - cards with an end date",
"globalSearch-instructions-status-public": "`__predicate_public__` - cards only in public boards",
"globalSearch-instructions-status-private": "`__predicate_private__` - cards only in private boards",
"globalSearch-instructions-operator-has": "`__operator_has__:<field>` - where *<field>* is one of `__predicate_attachment__`, `__predicate_checklist__`, `__predicate_description__`, `__predicate_start__`, `__predicate_due__`, `__predicate_end__`, `__predicate_assignee__` or `__predicate_member__`. Placing a `-` in front of *<field>* searches for the absence of a value in that field (e.g. `has:-due` searches for cards without a due date).",
"globalSearch-instructions-operator-sort": "`__operator_sort__:<sort-name>` - where *<sort-name>* is one of `__predicate_due__`, `__predicate_created__` or `__predicate_modified__`. For a descending sort, place a `-` in front of the sort name.",
"globalSearch-instructions-operator-limit": "`__operator_limit__:<n>` - where *<n>* is a positive integer expressing the number of cards to be displayed per page.",
"globalSearch-instructions-operator-board": "`__operator_board__:<title>` - karty v tablech odpovídajících zadanému *<title>*",
"globalSearch-instructions-operator-list": "`__operator_list__:<title>` - karty ve sloupcích odpovídajících zadanému *<title>*",
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<title>` - karty v drahách odpovídajících zadanému *<title>*",
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - karty s komentářem obsahujícím *<text>*.",
"globalSearch-instructions-operator-label": "`__operator_label__:<color>` `__operator_label__:<name>` - karty, které mají štítek *<color>* nebo *<name>",
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name|color>` - zkratka pro `__operator_label__:<color>` nebo `__operator_label__:<name>`",
"globalSearch-instructions-operator-user": "`__operator_user__:<username>` - karty, kde *<username>* je *member* nebo *assignee*",
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - zkratka pro `user:<username>`",
"globalSearch-instructions-operator-member": "`__operator_member__:<username>` - karty, kde *<username>* je *member*",
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:<username>` - karty, kde *<username>* je *assignee*",
"globalSearch-instructions-operator-creator": "`__operator_creator__:<username>` - karty, kde *<username>* je tvůrcem",
"globalSearch-instructions-operator-due": "`__operator_due__:<n>` - karty, které jsou *<n>* dny před termínem. `__operator_due__:__predicate_overdue__ zobrazí všechny karty po termínu.",
"globalSearch-instructions-operator-created": "`__operator_created__:<n>` - karty, které byly vytvořeny před *<n>* nebo méně dny",
"globalSearch-instructions-operator-modified": "`__operator_modified__:<n>` - katry, které byly upraveny před *<n>* nebo méně dny ",
"globalSearch-instructions-operator-status": "`__operator_status__:<status>` - kde *<status>* je jedno z následujících:",
"globalSearch-instructions-status-archived": "`__predicate_archived__` - archivované karty",
"globalSearch-instructions-status-all": "`__predicate_all__` - všechny archivované a nearchivované karty",
"globalSearch-instructions-status-ended": "`__predicate_ended__` - karty s datem dokončení",
"globalSearch-instructions-status-public": "`__predicate_public__` - karty na veřejných tablech",
"globalSearch-instructions-status-private": "`__predicate_private__` - karty jen na soukromých tablech",
"globalSearch-instructions-operator-has": "`__operator_has__:<field>` - kde *<field>* je jedno z `__predicate_attachment__`, `__predicate_checklist__`, `__predicate_description__`, `__predicate_start__`, `__predicate_due__`, `__predicate_end__`, `__predicate_assignee__` nebo `__predicate_member__`. Zadáním `-` před *<field>* vyhledáte karty, které dané políčko nemají zadané (např. `has:-due` vyhledá karty bez zadaného termínu).",
"globalSearch-instructions-operator-sort": "`__operator_sort__:<sort-name>` - kde *<sort-name>* je jedno z `__predicate_due__`, `__predicate_created__` nebo `__predicate_modified__`. Pro sestupné řazení zadejte před název `-`.",
"globalSearch-instructions-operator-limit": "`__operator_limit__:<n>` - kde *<n>* je kladné celé číslo vyjadřující počet karet zobrazených na jedné stránce.",
"globalSearch-instructions-notes-1": "Lze zadat více operátorů současně.",
"globalSearch-instructions-notes-2": "Podobné operátory jsou spojeny pomocí *OR*. Jsou zobrazeny karty odpovídající kterékoli v podmínek.\n`__operator_list__:Available __operator_list__:Blocked` zobrazí karty obsažené v jakémkoli sloupci s názvem *Blocked* nebo *Available*.",
"globalSearch-instructions-notes-3": "Odlišné operátory jsou spojeny pomocí *AND*. Jsou zobrazeny pouze karty, které odpovídají všem definovaným operátorům. `__operator_list__:Available __operator_label__:red` zobrazí pouze karty ve sloupci *Available* with a štítkem *red*.",
@@ -986,25 +1008,25 @@
"sort-cards": "Třídit",
"cardsSortPopup-title": "Třídit",
"due-date": "Požadovaný termín",
"server-error": "Server Error",
"server-error-troubleshooting": "Please submit the error generated by the server.\nFor a snap installation, run: `sudo snap logs wekan.wekan`\nFor a Docker installation, run: `sudo docker logs wekan-app`",
"server-error": "Chyba na serveru",
"server-error-troubleshooting": "Odešlete prosím chybu, kterou server vygeneroval.\nV případě instalace přes snap spusťte: `sudo snap logs wekan.wekan`\nV případě instalace přes Docker spusťte: `sudo docker logs wekan-app`",
"title-alphabetically": "Nadpis (Abecedně)",
"created-at-newest-first": "Vyvtořeno (Od nejnovějších)",
"created-at-oldest-first": "Vytvořeno (Od nejstarších)",
"links-heading": "Links",
"hide-system-messages-of-all-users": "Hide system messages of all users",
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
"move-swimlane": "Move Swimlane",
"moveSwimlanePopup-title": "Move Swimlane",
"custom-field-stringtemplate": "String Template",
"custom-field-stringtemplate-format": "Format (use %{value} as placeholder)",
"custom-field-stringtemplate-separator": "Separator (use &#32; or &nbsp; for a space)",
"custom-field-stringtemplate-item-placeholder": "Press enter to add more items",
"creator": "Creator",
"filesReportTitle": "Files Report",
"orphanedFilesReportTitle": "Orphaned Files Report",
"reports": "Reports",
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane"
"links-heading": "Odkazy",
"hide-system-messages-of-all-users": "Skrýt systémové zprávy všech uživatelů",
"now-system-messages-of-all-users-are-hidden": "Systémové zprávy všech uživatelů jsou nyní skryté",
"move-swimlane": "Přesunout dráhu",
"moveSwimlanePopup-title": "Přesunout dráhu",
"custom-field-stringtemplate": "Šablona řetězce",
"custom-field-stringtemplate-format": "Formát (jako placeholder použijte %{value})",
"custom-field-stringtemplate-separator": "Oddělovač (pro mezeru použijte &#32; nebo &nbsp;)",
"custom-field-stringtemplate-item-placeholder": "Stiskněte enter pro přidání více položek",
"creator": "Tvůrce",
"filesReportTitle": "Report souborů",
"orphanedFilesReportTitle": "Report osiřelých souborů",
"reports": "Reporty",
"rulesReportTitle": "Report pravidel",
"copy-swimlane": "Kopírovat dráhu",
"copySwimlanePopup-title": "Kopírovat dráhu"
}
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "går imod",
"deleteVotePopup-title": "Slet afstemning?",
"vote-delete-pop": "Sletning er permanent. Du mister alle handlinger knyttet til denne afstemning.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Slet kort?",
"cardDetailsActionsPopup-title": "Handlinger for kort",
"cardLabelsPopup-title": "Etiketter",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Opret skabelon",
"cards": "Kort",
"cards-count": "Kort",
"cards-count-one": "Kort",
"casSignIn": "Log ind med CAS",
"cardType-card": "Kort",
"cardType-linkedCard": "Sammenkædet kort",
+1031 -1009
View File
File diff suppressed because it is too large. Load diff
+1031 -1009
View File
File diff suppressed because it is too large. Load diff
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "εναντίον",
"deleteVotePopup-title": "Διαγραφή ψήφου;",
"vote-delete-pop": "Μόνιμη Διαγραφή. Θα χάσετε όλες τις ενέργειες που σχετίζονται με αυτή την ψήφο.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Διαγραφή Κάρτας;",
"cardDetailsActionsPopup-title": "Ενέργειες κάρτας",
"cardLabelsPopup-title": "Ετικέτες",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Δημιουργία προτύπου",
"cards": "Κάρτες",
"cards-count": "Κάρτες",
"cards-count-one": "Κάρτα",
"casSignIn": "Σύνδεση χρήστη με CAS",
"cardType-card": "Κάρτα",
"cardType-linkedCard": "Συνδεδεμένη Κάρτα",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Etikedoj",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Kartoj",
"cards-count": "Kartoj",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "¿Borrar Tarjeta?",
"cardDetailsActionsPopup-title": "Acciones de la Tarjeta",
"cardLabelsPopup-title": "Etiquetas",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Crear plantilla",
"cards": "Tarjetas",
"cards-count": "Tarjetas",
"cards-count-one": "Tarjeta",
"casSignIn": "Ingresar con CAS",
"cardType-card": "Tarjeta",
"cardType-linkedCard": "Tarjeta Vinculada",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "contrarios",
"deleteVotePopup-title": "¿Borrar voto?",
"vote-delete-pop": "El Borrado es permanente. Perderá todas las acciones asociadas con este voto.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "¿Eliminar la tarjeta?",
"cardDetailsActionsPopup-title": "Acciones de la tarjeta",
"cardLabelsPopup-title": "Etiquetas",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Crear plantilla",
"cards": "Tarjetas",
"cards-count": "Tarjetas",
"cards-count-one": "Tarjeta",
"casSignIn": "Iniciar sesión con CAS",
"cardType-card": "Tarjeta",
"cardType-linkedCard": "Tarjeta enlazada",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "contrarios",
"deleteVotePopup-title": "¿Borrar voto?",
"vote-delete-pop": "El borrado es permanente. Perderá todas las acciones asociadas con este voto.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "¿Eliminar la tarjeta?",
"cardDetailsActionsPopup-title": "Acciones de la tarjeta",
"cardLabelsPopup-title": "Etiquetas",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Crear plantilla",
"cards": "Tarjetas",
"cards-count": "Tarjetas",
"cards-count-one": "Tarjeta",
"casSignIn": "Iniciar sesión con CAS",
"cardType-card": "Tarjeta",
"cardType-linkedCard": "Tarjeta enlazada",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+80 -58
View File
@@ -178,6 +178,27 @@
"vote-against": "contrarios",
"deleteVotePopup-title": "¿Borrar voto?",
"vote-delete-pop": "El Borrado es permanente. Perderá todas las acciones asociadas con este voto.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "¿Eliminar la tarjeta?",
"cardDetailsActionsPopup-title": "Acciones de la tarjeta",
"cardLabelsPopup-title": "Etiquetas",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Crear plantilla",
"cards": "Tarjetas",
"cards-count": "Tarjetas",
"cards-count-one": "Tarjeta",
"casSignIn": "Iniciar sesión con CAS",
"cardType-card": "Tarjeta",
"cardType-linkedCard": "Tarjeta enlazada",
@@ -322,15 +344,15 @@
"error-user-notAllowSelf": "No puedes invitarte a ti mismo",
"error-user-notCreated": "El usuario no ha sido creado",
"error-username-taken": "Este nombre de usuario ya está en uso",
"error-orgname-taken": "This organization name is already taken",
"error-teamname-taken": "This team name is already taken",
"error-orgname-taken": "Este nombre de organización ya está en uso",
"error-teamname-taken": "Este nombre de equipo ya está en uso",
"error-email-taken": "Esta dirección de correo ya está en uso",
"export-board": "Exportar el tablero",
"export-board-json": "Exportar tablero a JSON",
"export-board-csv": "Exportar tablero a CSV",
"export-board-tsv": "Exportar tablero a TSV",
"export-board-excel": "Export board to Excel",
"user-can-not-export-excel": "User can not export Excel",
"export-board-excel": "Exportar tablero a Excel",
"user-can-not-export-excel": "El usuario no puede exportar Excel",
"export-board-html": "Exportar tablero a HTML",
"exportBoardPopup-title": "Exportar el tablero",
"sort": "Ordenar",
@@ -344,12 +366,12 @@
"list-label-short-sort": "(M)",
"filter": "Filtrar",
"filter-cards": "Filtrar tarjetas o listas",
"filter-dates-label": "Filter by date",
"filter-no-due-date": "No due date",
"filter-overdue": "Overdue",
"filter-due-today": "Due today",
"filter-due-this-week": "Due this week",
"filter-due-tomorrow": "Due tomorrow",
"filter-dates-label": "Filtrar por fecha",
"filter-no-due-date": "Sin fecha de vencimiento",
"filter-overdue": "Atrasado",
"filter-due-today": "Vence hoy",
"filter-due-this-week": "Vence esta semana",
"filter-due-tomorrow": "Vence mañana",
"list-filter-label": "Filtrar listas por título",
"filter-clear": "Limpiar el filtro",
"filter-labels-label": "Filtrar por etiqueta",
@@ -540,7 +562,7 @@
"text-below-custom-login-logo": "Text below Custom Login Logo",
"automatic-linked-url-schemes": "Custom URL Schemes which should automatically be clickable. One URL Scheme per line",
"username": "Nombre de usuario",
"import-usernames": "Import Usernames",
"import-usernames": "Importar Usuarios",
"view-it": "Verla",
"warn-list-archived": "advertencia: esta tarjeta está en una lista en el Archivo",
"watch": "Vigilar",
@@ -612,8 +634,8 @@
"minutes": "minutos",
"seconds": "segundos",
"show-field-on-card": "Mostrar este campo en la tarjeta",
"automatically-field-on-card": "Add field to new cards",
"always-field-on-card": "Add field to all cards",
"automatically-field-on-card": "Añadir campo a las tarjetas nuevas",
"always-field-on-card": "Añadir campo a todas las tarjetas",
"showLabel-field-on-card": "Mostrar etiquetas de campos en la minitarjeta.",
"yes": "Sí",
"no": "No",
@@ -684,7 +706,7 @@
"r-removed-from": "eliminado de",
"r-the-board": "el tablero",
"r-list": "la lista",
"list": "List",
"list": "Lista",
"set-filter": "Filtrar",
"r-moved-to": "Movido a",
"r-moved-from": "Movido desde",
@@ -790,8 +812,8 @@
"display-authentication-method": "Mostrar el método de autenticación",
"default-authentication-method": "Método de autenticación por defecto",
"duplicate-board": "Duplicar tablero",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"org-number": "El número de organizaciones es:",
"team-number": "El número de equipos es:",
"people-number": "El número de personas es:",
"swimlaneDeletePopup-title": "¿Eliminar el carril de flujo?",
"swimlane-delete-pop": "Todas las acciones serán eliminadas del historial de actividades y no se podrá recuperar el carril de flujo. Esta acción no puede deshacerse.",
@@ -825,10 +847,10 @@
"addmore-detail": "Añadir una descripción detallada",
"show-on-card": "Mostrar en la tarjeta",
"new": "Nuevo",
"editOrgPopup-title": "Edit Organization",
"newOrgPopup-title": "New Organization",
"editTeamPopup-title": "Edit Team",
"newTeamPopup-title": "New Team",
"editOrgPopup-title": "Editar Organización",
"newOrgPopup-title": "Nueva Organización",
"editTeamPopup-title": "Editar Equipo",
"newTeamPopup-title": "Nuevo Equipo",
"editUserPopup-title": "Editar el usuario",
"newUserPopup-title": "Nuevo usuario",
"notifications": "Notificaciones",
@@ -856,18 +878,18 @@
"delete-linked-card-before-this-card": "No puede borrar esta tarjeta antes de borrar la tarjeta enlazada que tiene",
"delete-linked-cards-before-this-list": "No puede borrar esta lista antes de borrar las tarjetas enlazadas que apuntan a tarjetas en esta lista",
"hide-checked-items": "Ocultar elementos marcados",
"task": "Task",
"task": "Tarea",
"create-task": "Create Task",
"ok": "Vale",
"organizations": "Organizations",
"teams": "Teams",
"organizations": "Organizaciones",
"teams": "Equipos",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person",
"my-cards": "My Cards",
"person": "Persona",
"my-cards": "Mis Tarjetas",
"card": "Tarjeta",
"board": "Board",
"board": "Tablero",
"context-separator": "/",
"myCardsSortChange-title": "My Cards Sort",
"myCardsSortChangePopup-title": "My Cards Sort",
@@ -876,7 +898,7 @@
"dueCards-title": "Due Cards",
"dueCardsViewChange-title": "Due Cards View",
"dueCardsViewChangePopup-title": "Due Cards View",
"dueCardsViewChange-choice-me": "Me",
"dueCardsViewChange-choice-me": "Yo",
"dueCardsViewChange-choice-all": "Todos los usuarios",
"dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.",
"broken-cards": "Broken Cards",
@@ -906,44 +928,44 @@
"operator-member-abbrev": "m",
"operator-assignee": "Asignar",
"operator-assignee-abbrev": "a",
"operator-creator": "creator",
"operator-status": "status",
"operator-creator": "creador",
"operator-status": "estado",
"operator-due": "vencimiento",
"operator-created": "created",
"operator-modified": "modified",
"operator-created": "creado",
"operator-modified": "modificado",
"operator-sort": "sort",
"operator-comment": "comment",
"operator-has": "has",
"operator-limit": "limit",
"predicate-archived": "archived",
"predicate-open": "open",
"operator-limit": "límite",
"predicate-archived": "archivado",
"predicate-open": "abierto",
"predicate-ended": "ended",
"predicate-all": "all",
"predicate-all": "todo",
"predicate-overdue": "overdue",
"predicate-week": "week",
"predicate-month": "month",
"predicate-quarter": "quarter",
"predicate-year": "year",
"predicate-week": "semana",
"predicate-month": "mes",
"predicate-quarter": "cuarto",
"predicate-year": "año",
"predicate-due": "vencimiento",
"predicate-modified": "modified",
"predicate-created": "created",
"predicate-attachment": "attachment",
"predicate-description": "description",
"predicate-modified": "modificado",
"predicate-created": "creado",
"predicate-attachment": "adjunto",
"predicate-description": "descripción",
"predicate-checklist": "lista de verificación",
"predicate-start": "comienza",
"predicate-end": "finalizado",
"predicate-assignee": "Asignar",
"predicate-member": "miembro",
"predicate-public": "public",
"predicate-private": "private",
"predicate-public": "público",
"predicate-private": "privado",
"operator-unknown-error": "%s no es un operador",
"operator-number-expected": "operator __operator__ expected a number, got '__value__'",
"operator-sort-invalid": "sort of '%s' is invalid",
"operator-status-invalid": "'%s' is not a valid status",
"operator-status-invalid": "'%s' no es un estado válido",
"operator-has-invalid": "%s is not a valid existence check",
"operator-limit-invalid": "%s is not a valid limit. Limit should be a positive integer.",
"next-page": "Next Page",
"previous-page": "Previous Page",
"operator-limit-invalid": "%s no es un límite válido. El límite ha de ser un entero positivo.",
"next-page": "Página Siguiente",
"previous-page": "Página Anterior",
"heading-notes": "Notas",
"globalSearch-instructions-heading": "Buscar instrucciones.",
"globalSearch-instructions-description": "Searches can include operators to refine the search. Operators are specified by writing the operator name and value separated by a colon. For example, an operator specification of `list:Blocked` would limit the search to cards that are contained in a list named *Blocked*. If the value contains spaces or special characters it must be enclosed in quotation marks (e.g. `__operator_list__:\"To Review\"`).",
@@ -986,21 +1008,21 @@
"sort-cards": "Sort Cards",
"cardsSortPopup-title": "Sort Cards",
"due-date": "Due Date",
"server-error": "Server Error",
"server-error": "Error del Servidor",
"server-error-troubleshooting": "Please submit the error generated by the server.\nFor a snap installation, run: `sudo snap logs wekan.wekan`\nFor a Docker installation, run: `sudo docker logs wekan-app`",
"title-alphabetically": "Title (Alphabetically)",
"created-at-newest-first": "Created At (Newest First)",
"created-at-oldest-first": "Created At (Oldest First)",
"links-heading": "Links",
"hide-system-messages-of-all-users": "Hide system messages of all users",
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
"title-alphabetically": "Título (Alfabéticamente)",
"created-at-newest-first": "Creación (Nuevos Primero)",
"created-at-oldest-first": "Creación (Antiguos Primero)",
"links-heading": "Enlaces",
"hide-system-messages-of-all-users": "Ocultar los mensajes de sistema de todos los usuarios",
"now-system-messages-of-all-users-are-hidden": "Los mensajes de sistema de todos los usuarios están ahora ocultos",
"move-swimlane": "Move Swimlane",
"moveSwimlanePopup-title": "Move Swimlane",
"custom-field-stringtemplate": "String Template",
"custom-field-stringtemplate-format": "Format (use %{value} as placeholder)",
"custom-field-stringtemplate-separator": "Separator (use &#32; or &nbsp; for a space)",
"custom-field-stringtemplate-item-placeholder": "Press enter to add more items",
"creator": "Creator",
"custom-field-stringtemplate-item-placeholder": "Pulsa intro para añadir más elementos",
"creator": "Creador",
"filesReportTitle": "Files Report",
"orphanedFilesReportTitle": "Orphaned Files Report",
"reports": "Reports",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Ezabatu txartela?",
"cardDetailsActionsPopup-title": "Txartel-ekintzak",
"cardLabelsPopup-title": "Etiketak",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Txartelak",
"cards-count": "Txartelak",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+68 -46
View File
@@ -1,51 +1,51 @@
{
"accept": "پذیرش",
"act-activity-notify": "Activity Notification",
"act-addAttachment": "added attachment __attachment__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteAttachment": "deleted attachment __attachment__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addSubtask": "added subtask __subtask__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addLabel": "Added label __label__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addedLabel": "Added label __label__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-removeLabel": "Removed label __label__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-removedLabel": "Removed label __label__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addChecklist": "added checklist __checklist__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addChecklistItem": "added checklist item __checklistItem__ to checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-removeChecklist": "removed checklist __checklist__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-removeChecklistItem": "removed checklist item __checklistItem__ from checklist __checkList__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-checkedItem": "checked __checklistItem__ of checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncheckedItem": "unchecked __checklistItem__ of 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-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created 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-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "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-archivedSwimlane": "Swimlane __swimlane__ at board __board__ moved to Archive",
"act-importBoard": "imported 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-joinMember": "added member __member__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-moveCard": "moved card __card__ at board __board__ from list __oldList__ at swimlane __oldSwimlane__ to list __list__ at swimlane __swimlane__",
"act-moveCardToOtherBoard": "moved card __card__ from list __oldList__ at swimlane __oldSwimlane__ at board __oldBoard__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-removeBoardMember": "removed member __member__ from board __board__",
"act-restoredCard": "restored card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-unjoinMember": "removed member __member__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"accept": "پذیرفتن",
"act-activity-notify": "اعلان فعالیت",
"act-addAttachment": "افزودن پیوست __attachment__ به کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-deleteAttachment": "پاک کردن پیوست __attachment__ از کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-addSubtask": "فزودن کار فرعی __subtask__ به کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-addLabel": "افزودن برچسب __label__ به کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-addedLabel": "برچسب اضافه شده __label__ به کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-removeLabel": "برداشتن برچسب __label__ از کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-removedLabel": "برچسب برداشته شده __label__ از کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-addChecklist": "افزودن چک لیست __checklist__ به کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-addChecklistItem": "آیتم اضافه شده به چک لیست __checklistItem__ در چک لیست __checklist__ در کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-removeChecklist": "حذف چک لیست __checklist__ از کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-removeChecklistItem": "آیتم حذف شده از چک لیست __checklistItem__ در چک لیست __checkList__ در کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-checkedItem": "بررسی شده __checklistItem__ از چک لیست __checklist__ در کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-uncheckedItem": "بررسی نشده __checklistItem__ از چک لیست __checklist__ در کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-completeChecklist": "چک لیست کامل شده __checklist__ در کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-uncompleteChecklist": "چک لیست ناتمام __checklist__ در کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-addComment": "افزودن نظر روی کارت __card__: __comment__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-editComment": "اصلاح نظر روی کارت __card__: __comment__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-deleteComment": "حذف نظر از کارت __card__: __comment__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-createBoard": "برد ساخته شده __board__",
"act-createSwimlane": "created swimlane __swimlane__ در برد __board__",
"act-createCard": "ایجاد کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-createCustomField": "ساخت فیلد اختصاصی __customField__ در برد __board__",
"act-deleteCustomField": "حذف فیلد اختصاصی __customField__ در برد __board__",
"act-setCustomField": "اصلاح فیلد اختصاصی __customField__: __customFieldValue__ در کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-createList": "ایجاد لیست __list__ در برد __board__",
"act-addBoardMember": "افزودن عضو __member__ به برد __board__",
"act-archivedBoard": "برد __board__ به آرشیو منتقل شد",
"act-archivedCard": "کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__ به آرشیو منتقل شد",
"act-archivedList": "لیست __list__ at swimlane __swimlane__ در برد __board__ به آرشیو منتقل شد",
"act-archivedSwimlane": "Swimlane __swimlane__ در برد __board__ به آرشیو منتقل شد",
"act-importBoard": "وارد کردن برد __board__",
"act-importCard": "وارد کردن کارت __card__ به لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-importList": "وارد کردن لیست __list__ to swimlane __swimlane__ در برد __board__",
"act-joinMember": "عضو کردن __member__ به کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-moveCard": "انتقال کارت __card__ در برد __board__ از لیست __oldList__ at swimlane __oldSwimlane__ به لیست __list__ at swimlane __swimlane__",
"act-moveCardToOtherBoard": "انتقال کارت به برد دیگر __card__ از لیست __oldList__ at swimlane __oldSwimlane__ در برد __oldBoard__ به لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-removeBoardMember": "حذف عضویت __member__ از برد __board__",
"act-restoredCard": "کارت بازگردانی شده __card__ به لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-unjoinMember": "حذف عضو __member__ از کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"act-withBoardTitle": "__board__",
"act-withCardTitle": "[__board__] __card__",
"actions": "Actions",
"activities": "Activities",
"activity": "Activity",
"activity-added": "added %s to %s",
"actions": "اقدامات",
"activities": "فعالیت ها",
"activity": "فعالیت",
"activity-added": "افزودن %s به %s",
"activity-archived": "%s moved to Archive",
"activity-attached": "attached %s to %s",
"activity-created": "created %s",
@@ -71,7 +71,7 @@
"add": "Add",
"activity-checked-item-card": "checked %s in checklist %s",
"activity-unchecked-item-card": "unchecked %s in checklist %s",
"activity-checklist-completed-card": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"activity-checklist-completed-card": "completed checklist __checklist__ در کارت __card__ در لیست __list__ at swimlane __swimlane__ در برد __board__",
"activity-checklist-uncompleted-card": "uncompleted the checklist %s",
"activity-editComment": "edited comment %s",
"activity-deleteComment": "deleted comment %s",
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+77 -55
View File
@@ -178,6 +178,27 @@
"vote-against": "بر خلاف",
"deleteVotePopup-title": "رای‌گیری حذف شود؟",
"vote-delete-pop": "حذف کردن به صورت دائمی هست و قابل برگشت نیست. تمام اطلاعات مرتبط با این رای‌گیری حذف خواهدشد.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "آیا می خواهید کارت را حذف کنید؟",
"cardDetailsActionsPopup-title": "اعمال کارت",
"cardLabelsPopup-title": "لیبل ها",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "ایجاد قالب",
"cards": "کارت‌ها",
"cards-count": "کارت‌ها",
"cards-count-one": "کارت",
"casSignIn": "ورود با استفاده از CAS",
"cardType-card": "کارت",
"cardType-linkedCard": "کارت‌های لینک‌شده",
@@ -344,12 +366,12 @@
"list-label-short-sort": "(M)",
"filter": "فیلتر",
"filter-cards": "فیلتر کارت‌ها یا لیست‌ها",
"filter-dates-label": "Filter by date",
"filter-no-due-date": "No due date",
"filter-overdue": "Overdue",
"filter-due-today": "Due today",
"filter-due-this-week": "Due this week",
"filter-due-tomorrow": "Due tomorrow",
"filter-dates-label": "فیلتر با تاریخ",
"filter-no-due-date": "بدون تاریخ مقرر",
"filter-overdue": "منقضی شده",
"filter-due-today": "مقتضی امروز",
"filter-due-this-week": "مقتضی این هفته",
"filter-due-tomorrow": "مقتضی فردا",
"list-filter-label": "فیلتر لیست بر اساس عنوان",
"filter-clear": "حذف فیلتر",
"filter-labels-label": "فیلتر کردن با لیبل",
@@ -873,13 +895,13 @@
"myCardsSortChangePopup-title": "نظم کارت های من",
"myCardsSortChange-choice-board": "بر اساس برد",
"myCardsSortChange-choice-dueat": "بر اساس تاریخ انجام",
"dueCards-title": "Due Cards",
"dueCardsViewChange-title": "Due Cards View",
"dueCardsViewChangePopup-title": "Due Cards View",
"dueCards-title": "کارتهای سررسید",
"dueCardsViewChange-title": "نمایش کارتهای سررسید",
"dueCardsViewChangePopup-title": "نمایش کارتهای سررسید",
"dueCardsViewChange-choice-me": "من",
"dueCardsViewChange-choice-all": "All Users",
"dueCardsViewChange-choice-all": "تمام کاربران",
"dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.",
"broken-cards": "Broken Cards",
"broken-cards": "کارت های شکسته",
"board-title-not-found": "Board '%s' not found.",
"swimlane-title-not-found": "Swimlane '%s' not found.",
"list-title-not-found": "List '%s' not found.",
@@ -894,7 +916,7 @@
"n-n-of-n-cards-found": "__start__-__end__ of __total__ Cards Found",
"operator-board": "برد",
"operator-board-abbrev": "b",
"operator-swimlane": "swimlane",
"operator-swimlane": "مسیر",
"operator-swimlane-abbrev": "s",
"operator-list": "لیست",
"operator-list-abbrev": "l",
@@ -904,46 +926,46 @@
"operator-user-abbrev": "@",
"operator-member": "عضو",
"operator-member-abbrev": "m",
"operator-assignee": "assignee",
"operator-assignee": "محول‌شده",
"operator-assignee-abbrev": "a",
"operator-creator": "creator",
"operator-status": "status",
"operator-due": "ناشی از",
"operator-created": "created",
"operator-modified": "modified",
"operator-sort": "sort",
"operator-comment": "comment",
"operator-has": "has",
"operator-limit": "limit",
"predicate-archived": "archived",
"predicate-open": "open",
"predicate-ended": "ended",
"predicate-all": "all",
"predicate-overdue": "overdue",
"predicate-week": "week",
"predicate-month": "month",
"predicate-quarter": "quarter",
"predicate-year": "year",
"operator-created": "ایجاد شده",
"operator-modified": "ویرایش شده",
"operator-sort": "مرتب سازی",
"operator-comment": "نظر",
"operator-has": "دارد",
"operator-limit": "حد",
"predicate-archived": "بایگانی شده",
"predicate-open": "باز",
"predicate-ended": "پایان یافته",
"predicate-all": "همه",
"predicate-overdue": "منقضی شده",
"predicate-week": "هفته",
"predicate-month": "ماه",
"predicate-quarter": "فصل",
"predicate-year": "سال",
"predicate-due": "ناشی از",
"predicate-modified": "modified",
"predicate-created": "created",
"predicate-attachment": "attachment",
"predicate-description": "description",
"predicate-modified": "ویرایش شده",
"predicate-created": "ایجاد شده",
"predicate-attachment": "ضمیمه",
"predicate-description": "توضیحات",
"predicate-checklist": "چک‌لیست",
"predicate-start": "شروع",
"predicate-end": "پایان",
"predicate-assignee": "assignee",
"predicate-assignee": "محول‌شده",
"predicate-member": "عضو",
"predicate-public": "public",
"predicate-private": "private",
"operator-unknown-error": "%s is not an operator",
"predicate-public": "عمومی",
"predicate-private": "خصوصی",
"operator-unknown-error": "%s اپراتور نیست",
"operator-number-expected": "operator __operator__ expected a number, got '__value__'",
"operator-sort-invalid": "sort of '%s' is invalid",
"operator-status-invalid": "'%s' is not a valid status",
"operator-has-invalid": "%s is not a valid existence check",
"operator-limit-invalid": "%s is not a valid limit. Limit should be a positive integer.",
"next-page": "Next Page",
"previous-page": "Previous Page",
"next-page": "صفحه بعد",
"previous-page": "صفحه قبلی",
"heading-notes": "یادداشت ها",
"globalSearch-instructions-heading": "دستورالعمل جستجو",
"globalSearch-instructions-description": "Searches can include operators to refine the search. Operators are specified by writing the operator name and value separated by a colon. For example, an operator specification of `list:Blocked` would limit the search to cards that are contained in a list named *Blocked*. If the value contains spaces or special characters it must be enclosed in quotation marks (e.g. `__operator_list__:\"To Review\"`).",
@@ -983,28 +1005,28 @@
"label-colors": "رنگ لیبل",
"label-names": "اسامی لیبل",
"archived-at": "بایگانی شده در",
"sort-cards": "Sort Cards",
"cardsSortPopup-title": "Sort Cards",
"sort-cards": "مرتب‌سازی کارت‌ها",
"cardsSortPopup-title": "مرتب‌سازی کارت‌ها",
"due-date": "تاریخ اجرا",
"server-error": "Server Error",
"server-error": "خطای سرور",
"server-error-troubleshooting": "Please submit the error generated by the server.\nFor a snap installation, run: `sudo snap logs wekan.wekan`\nFor a Docker installation, run: `sudo docker logs wekan-app`",
"title-alphabetically": "تیتر (به صورت الفبا)",
"created-at-newest-first": "ساخته شده در تاریخ (با اولویت جدید تر)",
"created-at-oldest-first": "ساخته شده در تاریخ (با اولویت قدیمی تر)",
"links-heading": "Links",
"hide-system-messages-of-all-users": "Hide system messages of all users",
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
"move-swimlane": "Move Swimlane",
"moveSwimlanePopup-title": "Move Swimlane",
"custom-field-stringtemplate": "String Template",
"links-heading": "پیوندها",
"hide-system-messages-of-all-users": "مخفی‌سازی پیام‌های تمام کاربران",
"now-system-messages-of-all-users-are-hidden": "اکنون پیام‌های همه کاربران مخفی است",
"move-swimlane": "انتقال مسیر",
"moveSwimlanePopup-title": "انتقال مسیر",
"custom-field-stringtemplate": "قالب رشته",
"custom-field-stringtemplate-format": "Format (use %{value} as placeholder)",
"custom-field-stringtemplate-separator": "Separator (use &#32; or &nbsp; for a space)",
"custom-field-stringtemplate-item-placeholder": "Press enter to add more items",
"creator": "Creator",
"filesReportTitle": "Files Report",
"orphanedFilesReportTitle": "Orphaned Files Report",
"reports": "Reports",
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane"
"custom-field-stringtemplate-item-placeholder": "برای افزودن موارد بیشتر ، Enter را فشار دهید",
"creator": "سازنده",
"filesReportTitle": "گزارش پرونده‌ها",
"orphanedFilesReportTitle": "گزارش پرونده‌های یتیم",
"reports": "گزارش‌ها",
"rulesReportTitle": "گزارش قوانین",
"copy-swimlane": "کپی از مسیر",
"copySwimlanePopup-title": "کپی از مسیر"
}
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "vastaan",
"deleteVotePopup-title": "Poista ääni?",
"vote-delete-pop": "Poistaminen on lopullista. Menetät kaikki tähän äänestykseen liitetyt toimet.",
"cardStartPlanningPokerPopup-title": "Aloita suunnittelupokeri",
"card-edit-planning-poker": "Muokkaa suunnittelupokeria",
"editPokerEndDatePopup-title": "Muuta suunnittelupokerin loppumispäivää",
"poker-question": "Suunnittelupokeri",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Lopeta",
"poker-result-votes": "Äänet",
"poker-result-who": "Kuka",
"poker-replay": "Toista",
"set-estimation": "Aseta arvio",
"deletePokerPopup-title": "Poista suunnittelupokeri?",
"poker-delete-pop": "Poistaminen on lopullista. Menetät kaikki tähän suunnittelupokeriin liitetyt toimet.",
"cardDeletePopup-title": "Poista kortti?",
"cardDetailsActionsPopup-title": "Korttitoimet",
"cardLabelsPopup-title": "Nimilaput",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Luo malli",
"cards": "Kortit",
"cards-count": "korttia",
"cards-count-one": "Kortti",
"casSignIn": "CAS-kirjautuminen",
"cardType-card": "Kortti",
"cardType-linkedCard": "Linkitetty kortti",
+1031 -1009
View File
File diff suppressed because it is too large. Load diff
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Etiquetas",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Tarxetas",
"cards-count": "Tarxetas",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+1031 -1009
View File
File diff suppressed because it is too large. Load diff
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "के प्रतिकूल",
"deleteVotePopup-title": "मतदान हटाएं?",
"vote-delete-pop": "हटाना स्थायी है। आप इस मतदान से जुड़े सभी कार्यों को खो देंगे।",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "मिटाएँ कार्ड?",
"cardDetailsActionsPopup-title": "कार्ड क्रियाएँ",
"cardLabelsPopup-title": "नामपत्र",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "खाका बनाएं",
"cards": "कार्ड्स",
"cards-count": "कार्ड्स",
"cards-count-one": "कार्ड",
"casSignIn": "सीएएस के साथ साइन इन करें",
"cardType-card": "कार्ड",
"cardType-linkedCard": "जुड़े हुए कार्ड",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "je protiv",
"deleteVotePopup-title": "Obrisati glasovanje?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Obrisati karticu?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Oznake",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Dodati predložak",
"cards": "Kartice",
"cards-count": "Kartice",
"cards-count-one": "Kartica",
"casSignIn": "Prijavite se s CAS-om",
"cardType-card": "Kartica",
"cardType-linkedCard": "Povezane kartice",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "ellene",
"deleteVotePopup-title": "Törlöd a szavazást?",
"vote-delete-pop": "A Törlés végleges. Minden eseményt elvesztesz, ami ehhez kapcsolódik.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Törlöd a kártyát?",
"cardDetailsActionsPopup-title": "Kártyaműveletek",
"cardLabelsPopup-title": "Címkék",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Sablon létrehozása",
"cards": "Kártyák",
"cards-count": "Kártyák",
"cards-count-one": "Kártya",
"casSignIn": "Bejelentkezés CAS metódussal",
"cardType-card": "Kártya",
"cardType-linkedCard": "Kapcsolt Kártya",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Hapus kartu",
"cardDetailsActionsPopup-title": "Aksi Kartu",
"cardLabelsPopup-title": "Daftar Label",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Daftar Kartu",
"cards-count": "Daftar Kartu",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Aha",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "contro",
"deleteVotePopup-title": "Eliminare il voto?",
"vote-delete-pop": "L'eliminazione è permanente. Tutte le azioni associate a questa votazione andranno perse.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Eliminare scheda?",
"cardDetailsActionsPopup-title": "Azioni scheda",
"cardLabelsPopup-title": "Etichette",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Crea un template",
"cards": "Schede",
"cards-count": "Schede",
"cards-count-one": "Scheda",
"casSignIn": "Entra con CAS",
"cardType-card": "Scheda",
"cardType-linkedCard": "Scheda collegata",
+30 -8
View File
@@ -178,6 +178,27 @@
"vote-against": "反対",
"deleteVotePopup-title": "投票を削除しますか?",
"vote-delete-pop": "投票は取り消しできません。この投票に関係するすべてのアクションがなくなります。",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "カードを削除しますか?",
"cardDetailsActionsPopup-title": "カード操作",
"cardLabelsPopup-title": "ラベル",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "テンプレートの作成",
"cards": "カード",
"cards-count": "カード",
"cards-count-one": "カード",
"casSignIn": "CASでサインインする",
"cardType-card": "カード",
"cardType-linkedCard": "リンクされたカード",
@@ -344,12 +366,12 @@
"list-label-short-sort": "(M)",
"filter": "フィルター",
"filter-cards": "カードまたはリストをフィルタ",
"filter-dates-label": "Filter by date",
"filter-no-due-date": "No due date",
"filter-overdue": "Overdue",
"filter-due-today": "Due today",
"filter-due-this-week": "Due this week",
"filter-due-tomorrow": "Due tomorrow",
"filter-dates-label": "日付によるフィルタ",
"filter-no-due-date": "期限なし",
"filter-overdue": "期限切れ",
"filter-due-today": "本日期限",
"filter-due-this-week": "今週期限",
"filter-due-tomorrow": "明日期限",
"list-filter-label": "タイトルでリストをフィルタ",
"filter-clear": "フィルターの解除",
"filter-labels-label": "ラベルによるフィルタ",
@@ -1005,6 +1027,6 @@
"orphanedFilesReportTitle": "孤立ファイルレポート",
"reports": "レポート",
"rulesReportTitle": "ルールレポート",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane"
"copy-swimlane": "スイムレーンをコピーする",
"copySwimlanePopup-title": "スイムレーンをコピーする"
}
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "წავშალოთ ბარათი? ",
"cardDetailsActionsPopup-title": "ბარათის მოქმედებები",
"cardLabelsPopup-title": "ნიშნები",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "ბარათები",
"cards-count": "ბარათები",
"cards-count-one": "Card",
"casSignIn": "შესვლა CAS-ით",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+28 -6
View File
@@ -124,7 +124,7 @@
"attachmentDeletePopup-title": "첨부 파일을 삭제합니까?",
"attachments": "첨부 파일",
"auto-watch": "생성한 보드를 자동으로 감시합니다.",
"avatar-too-big": "The avatar is too large (520KB max)",
"avatar-too-big": "아바타가 너무 큽니다. (최대 520KB)",
"back": "뒤로",
"board-change-color": "보드 색 변경",
"board-nb-stars": "%s개의 별",
@@ -136,18 +136,18 @@
"boardChangeVisibilityPopup-title": "표시 여부 변경",
"boardChangeWatchPopup-title": "감시상태 변경",
"boardMenuPopup-title": "보드 메뉴",
"boardChangeViewPopup-title": "Board View",
"boardChangeViewPopup-title": "보드 화면",
"boards": "보드",
"board-view": "Board View",
"board-view": "보드 화면",
"board-view-cal": "달력",
"board-view-swimlanes": "Swimlanes",
"board-view-collapse": "Collapse",
"board-view-gantt": "Gantt",
"board-view-gantt": "간트",
"board-view-lists": "목록들",
"bucket-example": "예: “프로젝트 이름“ 입력",
"cancel": "취소",
"card-archived": "This card is moved to Archive.",
"board-archived": "This board is moved to Archive.",
"card-archived": "이 카드는 보관함으로 이동 되었습니다.",
"board-archived": "이 보드는 보관함으로 이동 되었습니다.",
"card-comments-title": "이 카드에 %s 코멘트가 있습니다.",
"card-delete-notice": "영구 삭제입니다. 이 카드와 관련된 모든 작업들을 잃게됩니다.",
"card-delete-pop": "모든 작업이 활동 내역에서 제거되며 카드를 다시 열 수 없습니다. 복구가 안되니 주의하시기 바랍니다.",
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "투표를 삭제합니까?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "카드를 삭제합니까?",
"cardDetailsActionsPopup-title": "카드 액션",
"cardLabelsPopup-title": "라벨",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "템플릿 생성",
"cards": "카드",
"cards-count": "카드",
"cards-count-one": "카드",
"casSignIn": "Sign In with CAS",
"cardType-card": "카드",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "pret",
"deleteVotePopup-title": "Dzēst balsojumu?",
"vote-delete-pop": "Dzēšana ir neatgriezeniska. Jūs zaudēsiet visas darbības saistītas ar šo balsojumu.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Dzēst kartiņu?",
"cardDetailsActionsPopup-title": "Kartiņas darbības",
"cardLabelsPopup-title": "Birkas",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Izveidot sagatavi",
"cards": "Kartiņas",
"cards-count": "Kartiņas",
"cards-count-one": "Kartiņa",
"casSignIn": "Pierakstīties ar CAS",
"cardType-card": "Kartiņa",
"cardType-linkedCard": "Saistīta kartiņa",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Желаете да изтриете картата?",
"cardDetailsActionsPopup-title": "Опции",
"cardLabelsPopup-title": "Етикети",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Картички",
"cards-count": "Картички",
"cards-count-one": "Карта",
"casSignIn": "Sign In with CAS",
"cardType-card": "Карта",
"cardType-linkedCard": "Поврзана карта",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+1031 -1009
View File
File diff suppressed because it is too large. Load diff
+1031 -1009
View File
File diff suppressed because it is too large. Load diff
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Suprimir la carta?",
"cardDetailsActionsPopup-title": "Accions sus la carta",
"cardLabelsPopup-title": "Etiquetas",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Crear un modèl",
"cards": "Cartas",
"cards-count": "Cartas",
"cards-count-one": "Carta",
"casSignIn": "Vos connectar amb CAS",
"cardType-card": "Carta",
"cardType-linkedCard": "Carta ligada",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+34 -12
View File
@@ -178,6 +178,27 @@
"vote-against": "przeciwko",
"deleteVotePopup-title": "Usunąć głos?",
"vote-delete-pop": "Usunięcie jest nieodwracalne. Stracisz wszystkie zdarzenia związane z tym głosowaniem.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Usunąć kartę?",
"cardDetailsActionsPopup-title": "Działania na karcie",
"cardLabelsPopup-title": "Etykiety",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Utwórz szablon",
"cards": "Karty",
"cards-count": "kart",
"cards-count-one": "karty",
"casSignIn": "Zaloguj się poprzez CAS",
"cardType-card": "karty",
"cardType-linkedCard": "Podpięta karta",
@@ -958,7 +980,7 @@
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - skrócona forma dla `użytkownik:<username>`",
"globalSearch-instructions-operator-member": "`__operator_member__:<username>` - karty, których *użytkownikiem* jest *<username>*",
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:<username>` - karty, do których *przypisany* jest użytkownik *<username>*",
"globalSearch-instructions-operator-creator": "`__operator_creator__:<username>` - cards where *<username>* is the card's creator",
"globalSearch-instructions-operator-creator": "`__operator_creator__:<username>` - karty, których twórcą jest *<username>*",
"globalSearch-instructions-operator-due": "`__operator_due__:<n>` - karty, których termin mija w ciągu *<n>* lub mniej dni od teraz. `__operator_due__:__predicate_overdue__ wyświetla wszystkie karty, których termin minął.",
"globalSearch-instructions-operator-created": "`__operator_created__:<n>` - karty utworzone *<n>* lub mniej dni temu",
"globalSearch-instructions-operator-modified": "`__operator_modified__:<n>` - karty zmodyfikowane *<n>* lub mniej dni temu",
@@ -996,15 +1018,15 @@
"now-system-messages-of-all-users-are-hidden": "Odtąd powiadomienia systemowe wszystkich użytkowników będą ukryte",
"move-swimlane": "Przenieś ścieżkę",
"moveSwimlanePopup-title": "Przenieś ścieżkę",
"custom-field-stringtemplate": "String Template",
"custom-field-stringtemplate-format": "Format (use %{value} as placeholder)",
"custom-field-stringtemplate-separator": "Separator (use &#32; or &nbsp; for a space)",
"custom-field-stringtemplate-item-placeholder": "Press enter to add more items",
"creator": "Creator",
"filesReportTitle": "Files Report",
"orphanedFilesReportTitle": "Orphaned Files Report",
"reports": "Reports",
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane"
"custom-field-stringtemplate": "Wzór ciągu znaków",
"custom-field-stringtemplate-format": "Format (wstaw %{value} w miejsce zmiennych)",
"custom-field-stringtemplate-separator": "Separator (użyj &#32; lub &nbsp; jako odstępu)",
"custom-field-stringtemplate-item-placeholder": "Wciśnij Enter, aby dodać więcej elementów",
"creator": "Twórca",
"filesReportTitle": "Wykaz plików",
"orphanedFilesReportTitle": "Wykaz osieroconych plików",
"reports": "Wykazy",
"rulesReportTitle": "Wykaz reguł",
"copy-swimlane": "Skopiuj ścieżkę",
"copySwimlanePopup-title": "Kopiowanie ścieżki"
}
+1031 -1009
View File
File diff suppressed because it is too large. Load diff
+34 -12
View File
@@ -178,6 +178,27 @@
"vote-against": "contra",
"deleteVotePopup-title": "Apagar votação?",
"vote-delete-pop": "Apagar é permanente. Irá perder todas as ações associadas a este voto.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Apagar Cartão?",
"cardDetailsActionsPopup-title": "Acções do Cartão",
"cardLabelsPopup-title": "Etiquetas",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Criar Modelo",
"cards": "Cartões",
"cards-count": "Cartões",
"cards-count-one": "Cartão",
"casSignIn": "Entrar com CAS",
"cardType-card": "Cartão",
"cardType-linkedCard": "Cartão Ligado",
@@ -879,9 +901,9 @@
"dueCardsViewChange-choice-me": "Eu",
"dueCardsViewChange-choice-all": "Todos os Utilizadores",
"dueCardsViewChange-choice-all-description": "Mostra todos os cartões incompletos com data *Limite* de quadros onde o utilizador tem permissões.",
"broken-cards": "Broken Cards",
"broken-cards": "Cartões Defeituosos",
"board-title-not-found": "Quadro '%s' não encontrado.",
"swimlane-title-not-found": "Swimlane '%s' not found.",
"swimlane-title-not-found": "Pista '%s' não encontrada.",
"list-title-not-found": "Lista '%s' não encontrada.",
"label-not-found": "Etiqueta '%s' não encontrada.",
"label-color-not-found": "Cor de Etiqueta %s não encontrada",
@@ -894,8 +916,8 @@
"n-n-of-n-cards-found": "__start__-__end__ de __total__ Cartões Encontrados",
"operator-board": "quadro",
"operator-board-abbrev": "q",
"operator-swimlane": "swimlane",
"operator-swimlane-abbrev": "s",
"operator-swimlane": "pista",
"operator-swimlane-abbrev": "p",
"operator-list": "lista",
"operator-list-abbrev": "l",
"operator-label": "etiqueta",
@@ -948,9 +970,9 @@
"globalSearch-instructions-heading": "Instruções de Pesquisa",
"globalSearch-instructions-description": "Pesquisas podem incluir operadores para afinar a pesquisa. Operadores são definidos por escrever o nome do operador e o valor separados por dois pontos. Por exemplo, um operador definido como 'list:Blocked' vai limitar a pesquisa a cartões que pertençam a uma lista chamada *Blocked*. Se o valor conter espaços ou caracteres especiais, eles devem ser envolvidos em aspas (e.x. `__operator_list__:\"A Rever\"`).",
"globalSearch-instructions-operators": "Operadores disponíveis:",
"globalSearch-instructions-operator-board": "`__operator_board__:<title>` - cards in boards matching the specified *<title>*",
"globalSearch-instructions-operator-list": "`__operator_list__:<title>` - cards in lists matching the specified *<title>*",
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<title>` - cards in swimlanes matching the specified *<title>*",
"globalSearch-instructions-operator-board": "`__operator_board__:<title>` - cartões em quadros que respeitam o filtro *<title>*",
"globalSearch-instructions-operator-list": "`__operator_list__:<title>` - cartões em listas que respeitam o filtro *<title>*",
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<title>` - cartões em pistas que respeitam o filtro *<title>*",
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - cartões com um comentário que contem *<text>*.",
"globalSearch-instructions-operator-label": "`__operator_label__:<color>` `__operator_label__:<name>` - cartões que tenham uma etiqueta igual a *<color>* ou *<name>",
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name|color>` - abreviatura de `__operator_label__:` ou `__operator_label__:`",
@@ -994,9 +1016,9 @@
"links-heading": "Links",
"hide-system-messages-of-all-users": "Omitir mensagens de sistema de todos os utilizadores",
"now-system-messages-of-all-users-are-hidden": "Todas as mensagens de sistema são omitidas a todos os utilizadores",
"move-swimlane": "Move Swimlane",
"moveSwimlanePopup-title": "Move Swimlane",
"custom-field-stringtemplate": "String Template",
"move-swimlane": "Mover Pista",
"moveSwimlanePopup-title": "Mover Pista",
"custom-field-stringtemplate": "Texto Modelo",
"custom-field-stringtemplate-format": "Formato (use %{value} como substituto)",
"custom-field-stringtemplate-separator": "Separador (use &#32; ou &nbsp; para um espaço)",
"custom-field-stringtemplate-item-placeholder": "Pressione enter para adicionar mais itens",
@@ -1005,6 +1027,6 @@
"orphanedFilesReportTitle": "Relatórios de Ficheiros Soltos",
"reports": "Relatórios",
"rulesReportTitle": "Relatório de Regras",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane"
"copy-swimlane": "Copiar Pista",
"copySwimlanePopup-title": "Copiar Pista"
}
+32 -10
View File
@@ -1,15 +1,15 @@
{
"accept": "Aceptă",
"act-activity-notify": "Activity Notification",
"act-addAttachment": "added attachment __attachment__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteAttachment": "deleted attachment __attachment__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addSubtask": "added subtask __subtask__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addLabel": "Added label __label__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addedLabel": "Added label __label__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-removeLabel": "Removed label __label__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-removedLabel": "Removed label __label__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addChecklist": "added checklist __checklist__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addChecklistItem": "added checklist item __checklistItem__ to checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-activity-notify": "Notificări de activitate",
"act-addAttachment": "atașament adăugat__atașament__pe card__card__în listă__listă__în culoar__culoar__pe tablă__tablă",
"act-deleteAttachment": "atașament șters__atașament__de pe card__card__din listă__listă__din culoar__culoar__de pe tablă__tabla",
"act-addSubtask": "subdiviziune sarcină adăugata__subdiviziune sarcină__pe card__card__în listă__listă__în culoar__culoar__pe tablă__tablă",
"act-addLabel": "etichetă adaugată__etichetă__pe card__card__în listă___listă__în culoar__culoar__pe tablă__tablă",
"act-addedLabel": "etichetă adaugată__etichetă__pe card__card__în listă___listă__în culoar__culoar__pe tablă__tablă",
"act-removeLabel": "etichetă îndepărtată__etichetă__de pe card__card__la listă__la culoar__culoar__la panou__panou",
"act-removedLabel": "etichetă îndepărtată__etichetă__de pe card__card__la listă__la culoar__culoar__la panou__panou",
"act-addChecklist": "listă de verificare adăugată__listă de verificare__pe card_card__la listă__listă__la culoar__culoar__la panou__panou",
"act-addChecklistItem": "element listă de verificare adăugat__elementlistădeverificare__în lista de verificare__listă de verificare__la card__card__la listă__listă__la culoar__culoar__la panou__panou",
"act-removeChecklist": "removed checklist __checklist__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-removeChecklistItem": "removed checklist item __checklistItem__ from checklist __checkList__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-checkedItem": "checked __checklistItem__ of checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+1031 -1009
View File
File diff suppressed because it is too large. Load diff
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Zmazať kartu?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Karty",
"cards-count": "Karty",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Briši kartico?",
"cardDetailsActionsPopup-title": "Dejanja kartice",
"cardLabelsPopup-title": "Oznake",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Ustvari predlogo",
"cards": "Kartice",
"cards-count": "Kartic",
"cards-count-one": "Kartica",
"casSignIn": "Vpiši se s CAS",
"cardType-card": "Kartica",
"cardType-linkedCard": "Povezana kartica",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "protiv",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Obrisati karticu?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Oznake",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Napravi šemu",
"cards": "Kartice",
"cards-count": "Kartice",
"cards-count-one": "Kartica",
"casSignIn": "Sign In with CAS",
"cardType-card": "Kartica",
"cardType-linkedCard": "Povezana kartica",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "emot",
"deleteVotePopup-title": "Radera omröstning?",
"vote-delete-pop": "Radering är permanent. Du kommer förlora alla händelser kopplade till denna röstning.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Radera kort?",
"cardDetailsActionsPopup-title": "Korthändelser",
"cardLabelsPopup-title": "Etiketter",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Skapa mall",
"cards": "Kort",
"cards-count": "Kort",
"cards-count-one": "Kort",
"casSignIn": "Logga in med CAS",
"cardType-card": "Kort",
"cardType-linkedCard": "Länkat kort",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "ลบการ์ดนี้หรือไม่",
"cardDetailsActionsPopup-title": "การดำเนินการการ์ด",
"cardLabelsPopup-title": "ป้ายกำกับ",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "การ์ด",
"cards-count": "การ์ด",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "red",
"deleteVotePopup-title": "Seçim silinsin mi?",
"vote-delete-pop": "Silme kalıcı bir işlemdir. Bu seçimle ilgili tüm eylemleri yitireceksiniz.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Kart Silinsin mi?",
"cardDetailsActionsPopup-title": "Kart işlemleri",
"cardLabelsPopup-title": "Etiketler",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Şablon oluştur",
"cards": "Kartlar",
"cards-count": "Kartlar",
"cards-count-one": "Kart",
"casSignIn": "CAS ile giriş yapın",
"cardType-card": "Kart",
"cardType-linkedCard": "Bağlantılı kart",
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Видалити картку?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Картки",
"cards-count": "Картки",
"cards-count-one": "Картка",
"casSignIn": "Sign In with CAS",
"cardType-card": "Картка",
"cardType-linkedCard": "Linked Card",
+49 -27
View File
@@ -178,6 +178,27 @@
"vote-against": "phản đối",
"deleteVotePopup-title": "Xoá bình chọn?",
"vote-delete-pop": "Việc xóa là vĩnh viễn. Bạn sẽ mất tất cả các hành động liên quan đến phiếu bầu này.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Xoá Thẻ",
"cardDetailsActionsPopup-title": "Hành động thẻ",
"cardLabelsPopup-title": "Nhãn",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Tạo mẫu",
"cards": "Thẻ",
"cards-count": "Thẻ",
"cards-count-one": "Thẻ",
"casSignIn": "Đăng nhập bằng CAS",
"cardType-card": "Thẻ",
"cardType-linkedCard": "Thẻ đã liên kết",
@@ -344,12 +366,12 @@
"list-label-short-sort": "(M)",
"filter": "Bộ lọc",
"filter-cards": "Lọc thẻ hoặc danh sách",
"filter-dates-label": "Filter by date",
"filter-no-due-date": "No due date",
"filter-overdue": "Overdue",
"filter-due-today": "Due today",
"filter-due-this-week": "Due this week",
"filter-due-tomorrow": "Due tomorrow",
"filter-dates-label": "Lọc theo ngày",
"filter-no-due-date": "Không có ngày đến hạn",
"filter-overdue": "Quá hạn",
"filter-due-today": "Đến hạn hôm nay",
"filter-due-this-week": "Đến hạn trong tuần này",
"filter-due-tomorrow": "Đến hạn vào ngày mai",
"list-filter-label": "Lọc danh sách theo tiêu đề",
"filter-clear": "Xóa bộ lọc",
"filter-labels-label": "Lọc theo nhãn",
@@ -644,7 +666,7 @@
"default": "Mặc định",
"queue": "Hàng đợi",
"subtask-settings": "Cài đặt Nhiệm vụ phụ",
"card-settings": "Cài đặt Card",
"card-settings": "Cài đặt Thẻ",
"boardSubtaskSettingsPopup-title": "Cài đặt Bảng Nhiệm vụ phụ",
"boardCardSettingsPopup-title": "Cài đặt thẻ",
"deposit-subtasks-board": "Gửi các nhiệm vụ phụ vào bảng này:",
@@ -906,7 +928,7 @@
"operator-member-abbrev": "m",
"operator-assignee": "người được giao",
"operator-assignee-abbrev": "a",
"operator-creator": "creator",
"operator-creator": "người tạo",
"operator-status": "trạng thái",
"operator-due": "đến hạn",
"operator-created": "đã tạo",
@@ -953,12 +975,12 @@
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<title>` - thẻ trong làn ngang phù hợp với *<title>*",
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - thẻ có nhận xét chứa *<text>*.",
"globalSearch-instructions-operator-label": "`__operator_label__:<color>` `__operator_label__:<name>` - thẻ có nhãn phù hợp *<color>* hoặc *<name>",
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name|color>` - shorthand for `__operator_label__:<color>` or `__operator_label__:<name>`",
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name|color>` - viết tắt cho `__operator_label__:<color>` hoặc `__operator_label__:<name>`",
"globalSearch-instructions-operator-user": "`__operator_user__:<username>` - thẻ trong đó *<username>* là *thành viên* hoặc *người được giao*",
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - viết tắt cho `người dùng:<username>`",
"globalSearch-instructions-operator-member": "`__operator_member__:<username>` - thẻ trong đó *<username>* là *thành viên*",
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:<username>` - thẻ trong đó *<username>* là *người được giao*",
"globalSearch-instructions-operator-creator": "`__operator_creator__:<username>` - cards where *<username>* is the card's creator",
"globalSearch-instructions-operator-creator": "`__operator_creator__:<username>` - thẻ trong đó *<username>* là người tạo thẻ",
"globalSearch-instructions-operator-due": "`__operator_due__:<n>` - thẻ có thời hạn lên đến *<n>* ngày kể từ bây giờ. `__operator_due__:__predicate_overdue__ liệt kê tất cả các thẻ đã quá hạn sử dụng.",
"globalSearch-instructions-operator-created": "`__operator_created__:<n>` - thẻ đã được tạo *<n>* ngày trước hoặc ít hơn",
"globalSearch-instructions-operator-modified": "`__operator_modified__:<n>` - thẻ đã được sửa đổi *<n>* ngày trước hoặc ít hơn",
@@ -986,25 +1008,25 @@
"sort-cards": "Sắp xếp thẻ",
"cardsSortPopup-title": "Sắp xếp thẻ",
"due-date": "Ngày đến hạn",
"server-error": "Server Error",
"server-error-troubleshooting": "Please submit the error generated by the server.\nFor a snap installation, run: `sudo snap logs wekan.wekan`\nFor a Docker installation, run: `sudo docker logs wekan-app`",
"server-error": "Lỗi máy chủ",
"server-error-troubleshooting": "Vui lòng gửi lỗi do máy chủ tạo ra.\nĐể cài đặt nhanh, hãy chạy: `sudo snap logs wekan.wekan`\nĐể cài đặt Docker, hãy chạy: `sudo docker logs wekan-app`",
"title-alphabetically": "Tiêu đề (theo thứ tự bảng chữ cái)",
"created-at-newest-first": "Được tạo lúc (Mới nhất đầu tiên)",
"created-at-oldest-first": "Được tạo lúc (Cũ nhất trước)",
"links-heading": "Links",
"hide-system-messages-of-all-users": "Hide system messages of all users",
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
"move-swimlane": "Move Swimlane",
"moveSwimlanePopup-title": "Move Swimlane",
"links-heading": "Liên kết",
"hide-system-messages-of-all-users": "Ẩn thông báo hệ thống của tất cả người dùng",
"now-system-messages-of-all-users-are-hidden": "Bây giờ thông báo hệ thống của tất cả người dùng bị ẩn",
"move-swimlane": "Di chuyển Làn ngang",
"moveSwimlanePopup-title": "Di chuyển Làn ngang",
"custom-field-stringtemplate": "String Template",
"custom-field-stringtemplate-format": "Format (use %{value} as placeholder)",
"custom-field-stringtemplate-separator": "Separator (use &#32; or &nbsp; for a space)",
"custom-field-stringtemplate-item-placeholder": "Press enter to add more items",
"creator": "Creator",
"filesReportTitle": "Files Report",
"orphanedFilesReportTitle": "Orphaned Files Report",
"reports": "Reports",
"rulesReportTitle": "Rules Report",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane"
"custom-field-stringtemplate-format": "Định dạng (sử dụng %{value} làm trình giữ chỗ)",
"custom-field-stringtemplate-separator": "Dấu phân cách (sử dụng &#32; hoặc &nbsp; cho một khoảng trắng)",
"custom-field-stringtemplate-item-placeholder": "Nhấn enter để thêm các mục khác",
"creator": "Người tạo",
"filesReportTitle": "Tệp báo cáo",
"orphanedFilesReportTitle": "Tệp báo cáo mồ côi",
"reports": "Báo cáo",
"rulesReportTitle": "Quy tắc Báo cáo",
"copy-swimlane": "Sao chép Làn ngang",
"copySwimlanePopup-title": "Sao chép Làn ngang"
}
+25 -3
View File
@@ -178,6 +178,27 @@
"vote-against": "反对",
"deleteVotePopup-title": "删除投票?",
"vote-delete-pop": "永久删除。此操作会将所有数据删除掉。",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "彻底删除卡片?",
"cardDetailsActionsPopup-title": "卡片操作",
"cardLabelsPopup-title": "标签",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "新建模板",
"cards": "卡片",
"cards-count": "卡片",
"cards-count-one": "卡片",
"casSignIn": "用CAS登录",
"cardType-card": "卡片",
"cardType-linkedCard": "已链接卡片",
@@ -951,7 +973,7 @@
"globalSearch-instructions-operator-board": "看板:看板中的卡片<title>必须匹配相应的*<title>*",
"globalSearch-instructions-operator-list": "列表:列表内的卡片<title>必须匹配对应的*<title>*",
"globalSearch-instructions-operator-swimlane": "泳道:泳道中的卡片<title>必须匹配相应的*<title>*",
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - cards with a comment containing *<text>*.",
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - 卡片评论包含 *<text>*.",
"globalSearch-instructions-operator-label": "标签:【标签<color>】卡片<name>要匹配*<color>*或*<name>*",
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name|color>` - shorthand for `__operator_label__:<color>` or `__operator_label__:<name>`",
"globalSearch-instructions-operator-user": "`__operator_user__:<username>` - cards where *<username>* is a *member* or *assignee*",
@@ -1005,6 +1027,6 @@
"orphanedFilesReportTitle": "孤立文件报告",
"reports": "报告",
"rulesReportTitle": "规则报告",
"copy-swimlane": "Copy Swimlane",
"copySwimlanePopup-title": "Copy Swimlane"
"copy-swimlane": "复制泳道",
"copySwimlanePopup-title": "复制泳道"
}
+22
View File
@@ -178,6 +178,27 @@
"vote-against": "against",
"deleteVotePopup-title": "Delete vote?",
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "Delete Card?",
"cardDetailsActionsPopup-title": "Card Actions",
"cardLabelsPopup-title": "Labels",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "Create template",
"cards": "Cards",
"cards-count": "Cards",
"cards-count-one": "Card",
"casSignIn": "Sign In with CAS",
"cardType-card": "Card",
"cardType-linkedCard": "Linked Card",
+32 -10
View File
@@ -178,6 +178,27 @@
"vote-against": "反對",
"deleteVotePopup-title": "刪除投票?",
"vote-delete-pop": "永久刪除是無法復原的,你將會失去這張卡片的所有相關操作記錄。",
"cardStartPlanningPokerPopup-title": "Start a Planning Poker",
"card-edit-planning-poker": "Edit Planning Poker",
"editPokerEndDatePopup-title": "Change Planning Poker vote end date",
"poker-question": "Planning Poker",
"poker-one": "1",
"poker-two": "2",
"poker-three": "3",
"poker-five": "5",
"poker-eight": "8",
"poker-thirteen": "13",
"poker-twenty": "20",
"poker-forty": "40",
"poker-oneHundred": "100",
"poker-unsure": "?",
"poker-finish": "Finish",
"poker-result-votes": "Votes",
"poker-result-who": "Who",
"poker-replay": "Replay",
"set-estimation": "Set Estimation",
"deletePokerPopup-title": "Delete planning poker?",
"poker-delete-pop": "Deleting is permanent. You will lose all actions associated with this planning poker.",
"cardDeletePopup-title": "徹底刪除卡片?",
"cardDetailsActionsPopup-title": "卡片操作",
"cardLabelsPopup-title": "標籤",
@@ -186,6 +207,7 @@
"cardTemplatePopup-title": "建立範本",
"cards": "卡片",
"cards-count": "卡片",
"cards-count-one": "卡片",
"casSignIn": "以 CAS 登入",
"cardType-card": "卡片",
"cardType-linkedCard": "已連結卡片",
@@ -344,12 +366,12 @@
"list-label-short-sort": "(M)",
"filter": "篩選",
"filter-cards": "篩選卡片或清單",
"filter-dates-label": "Filter by date",
"filter-no-due-date": "No due date",
"filter-overdue": "Overdue",
"filter-due-today": "Due today",
"filter-due-this-week": "Due this week",
"filter-due-tomorrow": "Due tomorrow",
"filter-dates-label": "篩選: 日期",
"filter-no-due-date": "沒有到期日",
"filter-overdue": "逾期",
"filter-due-today": "今天到期",
"filter-due-this-week": "本週到期",
"filter-due-tomorrow": "明天到期",
"list-filter-label": "篩選清單依據標題",
"filter-clear": "清除篩選條件",
"filter-labels-label": "篩選: 標籤",
@@ -906,7 +928,7 @@
"operator-member-abbrev": "m",
"operator-assignee": "代理人",
"operator-assignee-abbrev": "a",
"operator-creator": "creator",
"operator-creator": "建立者",
"operator-status": "狀態",
"operator-due": "至",
"operator-created": "已建立",
@@ -914,9 +936,9 @@
"operator-sort": "排序",
"operator-comment": "評論",
"operator-has": "擁有",
"operator-limit": "limit",
"operator-limit": "限制",
"predicate-archived": "已封存",
"predicate-open": "open",
"predicate-open": "開啟",
"predicate-ended": "已結束",
"predicate-all": "全部",
"predicate-overdue": "逾期",
@@ -986,7 +1008,7 @@
"sort-cards": "排序卡片",
"cardsSortPopup-title": "排序卡片",
"due-date": "到期日",
"server-error": "Server Error",
"server-error": "伺服器錯誤",
"server-error-troubleshooting": "Please submit the error generated by the server.\nFor a snap installation, run: `sudo snap logs wekan.wekan`\nFor a Docker installation, run: `sudo docker logs wekan-app`",
"title-alphabetically": "標題 (按字母順序)",
"created-at-newest-first": "創建於(最新優先)",
+691 -2
View File
@@ -271,6 +271,7 @@ Cards.attachSchema(
type: Number,
decimal: true,
defaultValue: 0,
optional: true,
},
subtaskSort: {
/**
@@ -337,6 +338,113 @@ Cards.attachSchema(
type: Boolean,
defaultValue: false,
},
poker: {
/**
* poker object, see below
*/
type: Object,
optional: true,
},
'poker.question': {
type: Boolean,
defaultValue: false,
},
'poker.one': {
/**
* poker card one
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.two': {
/**
* poker card two
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.three': {
/**
* poker card three
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.five': {
/**
* poker card five
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.eight': {
/**
* poker card eight
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.thirteen': {
/**
* poker card thirteen
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.twenty': {
/**
* poker card twenty
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.forty': {
/**
* poker card forty
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.oneHundred': {
/**
* poker card oneHundred
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.unsure': {
/**
* poker card unsure
*/
type: [String],
optional: true,
defaultValue: [],
},
'poker.end': {
type: Date,
optional: true,
defaultValue: null,
},
'poker.allowNonBoardMembers': {
type: Boolean,
defaultValue: false,
},
'poker.estimation': {
/**
* poker estimation value
*/
type: Number,
optional: true,
},
}),
);
@@ -650,10 +758,10 @@ Cards.helpers({
allSubtasks() {
return Cards.find({
parentId: this._id
parentId: this._id,
});
},
subtasksCount() {
const subtasks = this.subtasks();
return subtasks.count();
@@ -1278,6 +1386,191 @@ Cards.helpers({
return null;
},
getPokerQuestion() {
if (this.isLinkedCard()) {
const card = Cards.findOne({ _id: this.linkedId });
if (card === undefined) {
return null;
} else if (card && card.poker) {
return card.poker.question;
} else {
return null;
}
} else if (this.isLinkedBoard()) {
const board = Boards.findOne({ _id: this.linkedId });
if (board === undefined) {
return null;
} else if (board && board.poker) {
return board.poker.question;
} else {
return null;
}
} else if (this.poker) {
return this.poker.question;
} else {
return null;
}
},
getPokerEstimation() {
if (this.poker) {
return this.poker.estimation;
} else {
return null;
}
},
getPokerEnd() {
if (this.isLinkedCard()) {
const card = Cards.findOne({ _id: this.linkedId });
if (card === undefined) {
return null;
} else if (card && card.poker) {
return card.poker.end;
} else {
return null;
}
} else if (this.isLinkedBoard()) {
const board = Boards.findOne({ _id: this.linkedId });
if (board === undefined) {
return null;
} else if (board && board.poker) {
return board.poker.end;
} else {
return null;
}
} else if (this.poker) {
return this.poker.end;
} else {
return null;
}
},
expiredPoker() {
let end = this.getPokerEnd();
if (end) {
end = moment(end);
return end.isBefore(new Date());
}
return false;
},
pokerMemberOne() {
if (this.poker && this.poker.one)
return Users.find({ _id: { $in: this.poker.one } });
return [];
},
pokerMemberTwo() {
if (this.poker && this.poker.two)
return Users.find({ _id: { $in: this.poker.two } });
return [];
},
pokerMemberThree() {
if (this.poker && this.poker.three)
return Users.find({ _id: { $in: this.poker.three } });
return [];
},
pokerMemberFive() {
if (this.poker && this.poker.five)
return Users.find({ _id: { $in: this.poker.five } });
return [];
},
pokerMemberEight() {
if (this.poker && this.poker.eight)
return Users.find({ _id: { $in: this.poker.eight } });
return [];
},
pokerMemberThirteen() {
if (this.poker && this.poker.thirteen)
return Users.find({ _id: { $in: this.poker.thirteen } });
return [];
},
pokerMemberTwenty() {
if (this.poker && this.poker.twenty)
return Users.find({ _id: { $in: this.poker.twenty } });
return [];
},
pokerMemberForty() {
if (this.poker && this.poker.forty)
return Users.find({ _id: { $in: this.poker.forty } });
return [];
},
pokerMemberOneHundred() {
if (this.poker && this.poker.oneHundred)
return Users.find({ _id: { $in: this.poker.oneHundred } });
return [];
},
pokerMemberUnsure() {
if (this.poker && this.poker.unsure)
return Users.find({ _id: { $in: this.poker.unsure } });
return [];
},
pokerState() {
const userId = Meteor.userId();
let state;
if (this.poker) {
if (this.poker.one) {
state = _.contains(this.poker.one, userId);
if (state === true) {
return 'one';
}
}
if (this.poker.two) {
state = _.contains(this.poker.two, userId);
if (state === true) {
return 'two';
}
}
if (this.poker.three) {
state = _.contains(this.poker.three, userId);
if (state === true) {
return 'three';
}
}
if (this.poker.five) {
state = _.contains(this.poker.five, userId);
if (state === true) {
return 'five';
}
}
if (this.poker.eight) {
state = _.contains(this.poker.eight, userId);
if (state === true) {
return 'eight';
}
}
if (this.poker.thirteen) {
state = _.contains(this.poker.thirteen, userId);
if (state === true) {
return 'thirteen';
}
}
if (this.poker.twenty) {
state = _.contains(this.poker.twenty, userId);
if (state === true) {
return 'twenty';
}
}
if (this.poker.forty) {
state = _.contains(this.poker.forty, userId);
if (state === true) {
return 'forty';
}
}
if (this.poker.oneHundred) {
state = _.contains(this.poker.oneHundred, userId);
if (state === true) {
return 'oneHundred';
}
}
if (this.poker.unsure) {
state = _.contains(this.poker.unsure, userId);
if (state === true) {
return 'unsure';
}
}
}
return null;
},
getId() {
if (this.isLinked()) {
return this.linkedId;
@@ -1432,6 +1725,101 @@ Cards.helpers({
voteCount() {
return this.voteCountPositive() + this.voteCountNegative();
},
pokerAllowNonBoardMembers() {
if (this.poker) return this.poker.allowNonBoardMembers;
return null;
},
pokerCountOne() {
if (this.poker && this.poker.one) return this.poker.one.length;
return null;
},
pokerCountTwo() {
if (this.poker && this.poker.two) return this.poker.two.length;
return null;
},
pokerCountThree() {
if (this.poker && this.poker.three) return this.poker.three.length;
return null;
},
pokerCountFive() {
if (this.poker && this.poker.five) return this.poker.five.length;
return null;
},
pokerCountEight() {
if (this.poker && this.poker.eight) return this.poker.eight.length;
return null;
},
pokerCountThirteen() {
if (this.poker && this.poker.thirteen) return this.poker.thirteen.length;
return null;
},
pokerCountTwenty() {
if (this.poker && this.poker.twenty) return this.poker.twenty.length;
return null;
},
pokerCountForty() {
if (this.poker && this.poker.forty) return this.poker.forty.length;
return null;
},
pokerCountOneHundred() {
if (this.poker && this.poker.oneHundred) return this.poker.oneHundred.length;
return null;
},
pokerCountUnsure() {
if (this.poker && this.poker.unsure) return this.poker.unsure.length;
return null;
},
pokerCount() {
return (
this.pokerCountOne() +
this.pokerCountTwo() +
this.pokerCountThree() +
this.pokerCountFive() +
this.pokerCountEight() +
this.pokerCountThirteen() +
this.pokerCountTwenty() +
this.pokerCountForty() +
this.pokerCountOneHundred() +
this.pokerCountUnsure()
);
},
pokerWinner() {
const pokerListMaps = [];
let pokerWinnersListMap = [];
if (this.expiredPoker()) {
const one = { count: this.pokerCountOne(), pokerCard: 1 };
const two = { count: this.pokerCountTwo(), pokerCard: 2 };
const three = { count: this.pokerCountThree(), pokerCard: 3 };
const five = { count: this.pokerCountFive(), pokerCard: 5 };
const eight = { count: this.pokerCountEight(), pokerCard: 8 };
const thirteen = { count: this.pokerCountThirteen(), pokerCard: 13 };
const twenty = { count: this.pokerCountTwenty(), pokerCard: 20 };
const forty = { count: this.pokerCountForty(), pokerCard: 40 };
const oneHundred = { count: this.pokerCountOneHundred(), pokerCard: 100 };
const unsure = { count: this.pokerCountUnsure(), pokerCard: 'Unsure' };
pokerListMaps.push(one);
pokerListMaps.push(two);
pokerListMaps.push(three);
pokerListMaps.push(five);
pokerListMaps.push(eight);
pokerListMaps.push(thirteen);
pokerListMaps.push(twenty);
pokerListMaps.push(forty);
pokerListMaps.push(oneHundred);
pokerListMaps.push(unsure);
pokerListMaps.sort(function(a, b) {
return b.count - a.count;
});
const max = pokerListMaps[0].count;
pokerWinnersListMap = pokerListMaps.filter(task => task.count >= max);
pokerWinnersListMap.sort(function(a, b) {
return b.pokerCard - a.pokerCard;
});
}
return pokerWinnersListMap[0].pokerCard;
},
});
Cards.mutations({
@@ -1869,6 +2257,279 @@ Cards.mutations({
};
}
},
setPokerQuestion(question, allowNonBoardMembers) {
return {
$set: {
poker: {
question,
allowNonBoardMembers,
one: [],
two: [],
three: [],
five: [],
eight: [],
thirteen: [],
twenty: [],
forty: [],
oneHundred: [],
unsure: [],
},
},
};
},
setPokerEstimation(estimation) {
return {
$set: { 'poker.estimation': estimation },
};
},
unsetPokerEstimation() {
return {
$unset: { 'poker.estimation': '' },
};
},
unsetPoker() {
return {
$unset: {
poker: '',
},
};
},
setPokerEnd(end) {
return {
$set: { 'poker.end': end },
};
},
unsetPokerEnd() {
return {
$unset: { 'poker.end': '' },
};
},
setPoker(userId, state) {
switch (state) {
case 'one':
// poker one
return {
$pull: {
'poker.two': userId,
'poker.three': userId,
'poker.five': userId,
'poker.eight': userId,
'poker.thirteen': userId,
'poker.twenty': userId,
'poker.forty': userId,
'poker.oneHundred': userId,
'poker.unsure': userId,
},
$addToSet: {
'poker.one': userId,
},
};
case 'two':
// poker two
return {
$pull: {
'poker.one': userId,
'poker.three': userId,
'poker.five': userId,
'poker.eight': userId,
'poker.thirteen': userId,
'poker.twenty': userId,
'poker.forty': userId,
'poker.oneHundred': userId,
'poker.unsure': userId,
},
$addToSet: {
'poker.two': userId,
},
};
case 'three':
// poker three
return {
$pull: {
'poker.one': userId,
'poker.two': userId,
'poker.five': userId,
'poker.eight': userId,
'poker.thirteen': userId,
'poker.twenty': userId,
'poker.forty': userId,
'poker.oneHundred': userId,
'poker.unsure': userId,
},
$addToSet: {
'poker.three': userId,
},
};
case 'five':
// poker five
return {
$pull: {
'poker.one': userId,
'poker.two': userId,
'poker.three': userId,
'poker.eight': userId,
'poker.thirteen': userId,
'poker.twenty': userId,
'poker.forty': userId,
'poker.oneHundred': userId,
'poker.unsure': userId,
},
$addToSet: {
'poker.five': userId,
},
};
case 'eight':
// poker eight
return {
$pull: {
'poker.one': userId,
'poker.two': userId,
'poker.three': userId,
'poker.five': userId,
'poker.thirteen': userId,
'poker.twenty': userId,
'poker.forty': userId,
'poker.oneHundred': userId,
'poker.unsure': userId,
},
$addToSet: {
'poker.eight': userId,
},
};
case 'thirteen':
// poker thirteen
return {
$pull: {
'poker.one': userId,
'poker.two': userId,
'poker.three': userId,
'poker.five': userId,
'poker.eight': userId,
'poker.twenty': userId,
'poker.forty': userId,
'poker.oneHundred': userId,
'poker.unsure': userId,
},
$addToSet: {
'poker.thirteen': userId,
},
};
case 'twenty':
// poker twenty
return {
$pull: {
'poker.one': userId,
'poker.two': userId,
'poker.three': userId,
'poker.five': userId,
'poker.eight': userId,
'poker.thirteen': userId,
'poker.forty': userId,
'poker.oneHundred': userId,
'poker.unsure': userId,
},
$addToSet: {
'poker.twenty': userId,
},
};
case 'forty':
// poker forty
return {
$pull: {
'poker.one': userId,
'poker.two': userId,
'poker.three': userId,
'poker.five': userId,
'poker.eight': userId,
'poker.thirteen': userId,
'poker.twenty': userId,
'poker.oneHundred': userId,
'poker.unsure': userId,
},
$addToSet: {
'poker.forty': userId,
},
};
case 'oneHundred':
// poker one hundred
return {
$pull: {
'poker.one': userId,
'poker.two': userId,
'poker.three': userId,
'poker.five': userId,
'poker.eight': userId,
'poker.thirteen': userId,
'poker.twenty': userId,
'poker.forty': userId,
'poker.unsure': userId,
},
$addToSet: {
'poker.oneHundred': userId,
},
};
case 'unsure':
// poker unsure
return {
$pull: {
'poker.one': userId,
'poker.two': userId,
'poker.three': userId,
'poker.five': userId,
'poker.eight': userId,
'poker.thirteen': userId,
'poker.twenty': userId,
'poker.forty': userId,
'poker.oneHundred': userId,
},
$addToSet: {
'poker.unsure': userId,
},
};
default:
// Remove pokers
return {
$pull: {
'poker.one': userId,
'poker.two': userId,
'poker.three': userId,
'poker.five': userId,
'poker.eight': userId,
'poker.thirteen': userId,
'poker.twenty': userId,
'poker.forty': userId,
'poker.oneHundred': userId,
'poker.unsure': userId,
},
};
}
},
replayPoker() {
return {
$set: {
'poker.one': [],
'poker.two': [],
'poker.three': [],
'poker.five': [],
'poker.eight': [],
'poker.thirteen': [],
'poker.twelve': [],
'poker.forty': [],
'poker.oneHundred': [],
'poker.unsure': [],
},
};
},
});
//FUNCTIONS FOR creation of Activities
@@ -2592,6 +3253,9 @@ if (Meteor.isServer) {
* @param {string} vote.question the vote question
* @param {boolean} vote.public show who voted what
* @param {boolean} vote.allowNonBoardMembers allow all logged in users to vote?
* @param {Object} [poker] the poker object
* @param {string} poker.question the vote question
* @param {boolean} poker.allowNonBoardMembers allow all logged in users to vote?
* @return_type {_id: string}
*/
JsonRoutes.add(
@@ -2697,6 +3361,31 @@ if (Meteor.isServer) {
{ $set: { vote: newVote } },
);
}
if (req.body.hasOwnProperty('poker')) {
const newPoker = req.body.poker;
newPoker.one = [];
newPoker.two = [];
newPoker.three = [];
newPoker.five = [];
newPoker.eight = [];
newPoker.thirteen = [];
newPoker.twenty = [];
newPoker.forty = [];
newPoker.oneHundred = [];
newPoker.unsure = [];
if (!newPoker.hasOwnProperty('allowNonBoardMembers'))
newPoker.allowNonBoardMembers = false;
Cards.direct.update(
{
_id: paramCardId,
listId: paramListId,
boardId: paramBoardId,
archived: false,
},
{ $set: { poker: newPoker } },
);
}
if (req.body.hasOwnProperty('labelIds')) {
let newlabelIds = req.body.labelIds;
if (_.isString(newlabelIds)) {
+65 -19
View File
@@ -22,21 +22,35 @@ if (Meteor.isServer) {
* @param {string} boardId the ID of the board we are exporting
* @param {string} authToken the loginToken
*/
JsonRoutes.add('get', '/api/boards/:boardId/export', function(req, res) {
JsonRoutes.add('get', '/api/boards/:boardId/export', function (req, res) {
const boardId = req.params.boardId;
let user = null;
let impersonateDone = false;
let adminId = null;
const loginToken = req.query.authToken;
if (loginToken) {
const hashToken = Accounts._hashLoginToken(loginToken);
user = Meteor.users.findOne({
'services.resume.loginTokens.hashedToken': hashToken,
});
adminId = user._id.toString();
impersonateDone = ImpersonatedUsers.findOne({
adminId: adminId,
});
} else if (!Meteor.settings.public.sandstorm) {
Authentication.checkUserId(req.userId);
user = Users.findOne({ _id: req.userId, isAdmin: true });
}
const exporter = new Exporter(boardId);
if (exporter.canExport(user)) {
if (exporter.canExport(user) || impersonateDone) {
if (impersonateDone) {
ImpersonatedUsers.insert({
adminId: adminId,
boardId: boardId,
reason: 'exportJSON',
});
}
JsonRoutes.sendResult(res, {
code: 200,
data: exporter.build(),
@@ -71,22 +85,36 @@ if (Meteor.isServer) {
JsonRoutes.add(
'get',
'/api/boards/:boardId/attachments/:attachmentId/export',
function(req, res) {
function (req, res) {
const boardId = req.params.boardId;
const attachmentId = req.params.attachmentId;
let user = null;
let impersonateDone = false;
let adminId = null;
const loginToken = req.query.authToken;
if (loginToken) {
const hashToken = Accounts._hashLoginToken(loginToken);
user = Meteor.users.findOne({
'services.resume.loginTokens.hashedToken': hashToken,
});
adminId = user._id.toString();
impersonateDone = ImpersonatedUsers.findOne({
adminId: adminId,
});
} else if (!Meteor.settings.public.sandstorm) {
Authentication.checkUserId(req.userId);
user = Users.findOne({ _id: req.userId, isAdmin: true });
}
const exporter = new Exporter(boardId, attachmentId);
if (exporter.canExport(user)) {
if (exporter.canExport(user) || impersonateDone) {
if (impersonateDone) {
ImpersonatedUsers.insert({
adminId: adminId,
boardId: boardId,
attachmentId: attachmentId,
reason: 'exportJSONattachment',
});
}
JsonRoutes.sendResult(res, {
code: 200,
data: exporter.build(),
@@ -114,15 +142,21 @@ if (Meteor.isServer) {
* @param {string} authToken the loginToken
* @param {string} delimiter delimiter to use while building export. Default is comma ','
*/
Picker.route('/api/boards/:boardId/export/csv', function(params, req, res) {
Picker.route('/api/boards/:boardId/export/csv', function (params, req, res) {
const boardId = params.boardId;
let user = null;
let impersonateDone = false;
let adminId = null;
const loginToken = params.query.authToken;
if (loginToken) {
const hashToken = Accounts._hashLoginToken(loginToken);
user = Meteor.users.findOne({
'services.resume.loginTokens.hashedToken': hashToken,
});
adminId = user._id.toString();
impersonateDone = ImpersonatedUsers.findOne({
adminId: adminId,
});
} else if (!Meteor.settings.public.sandstorm) {
Authentication.checkUserId(req.userId);
user = Users.findOne({
@@ -131,19 +165,31 @@ if (Meteor.isServer) {
});
}
const exporter = new Exporter(boardId);
//if (exporter.canExport(user)) {
body = params.query.delimiter
? exporter.buildCsv(params.query.delimiter)
: exporter.buildCsv();
//'Content-Length': body.length,
res.writeHead(200, {
'Content-Type': params.query.delimiter ? 'text/csv' : 'text/tsv',
});
res.write(body);
res.end();
//} else {
// res.writeHead(403);
// res.end('Permission Error');
//}
if (exporter.canExport(user) || impersonateDone) {
if (impersonateDone) {
// TODO: Checking for CSV or TSV export type does not work:
// let exportType = 'export' + params.query.delimiter ? 'CSV' : 'TSV';
// So logging export to CSV:
let exportType = 'exportCSV';
ImpersonatedUsers.insert({
adminId: adminId,
boardId: boardId,
reason: exportType,
});
}
body = params.query.delimiter
? exporter.buildCsv(params.query.delimiter)
: exporter.buildCsv();
//'Content-Length': body.length,
res.writeHead(200, {
'Content-Type': params.query.delimiter ? 'text/csv' : 'text/tsv',
});
res.write(body);
res.end();
} else {
res.writeHead(403);
res.end('Permission Error');
}
});
}
+62 -41
View File
@@ -21,16 +21,21 @@ if (Meteor.isServer) {
* @param {string} authToken the loginToken
*/
const Excel = require('exceljs');
Picker.route('/api/boards/:boardId/exportExcel', function(params, req, res) {
Picker.route('/api/boards/:boardId/exportExcel', function (params, req, res) {
const boardId = params.boardId;
let user = null;
let impersonateDone = false;
let adminId = null;
const loginToken = params.query.authToken;
if (loginToken) {
const hashToken = Accounts._hashLoginToken(loginToken);
user = Meteor.users.findOne({
'services.resume.loginTokens.hashedToken': hashToken,
});
adminId = user._id.toString();
impersonateDone = ImpersonatedUsers.findOne({
adminId: adminId,
});
} else if (!Meteor.settings.public.sandstorm) {
Authentication.checkUserId(req.userId);
user = Users.findOne({
@@ -39,7 +44,14 @@ if (Meteor.isServer) {
});
}
const exporterExcel = new ExporterExcel(boardId);
if (exporterExcel.canExport(user)) {
if (exporterExcel.canExport(user) || impersonateDone) {
if (impersonateDone) {
ImpersonatedUsers.insert({
adminId: adminId,
boardId: boardId,
reason: 'exportExcel',
});
}
exporterExcel.build(res);
} else {
res.end(TAPi18n.__('user-can-not-export-excel'));
@@ -108,7 +120,7 @@ export class ExporterExcel {
result.subtaskItems = [];
result.triggers = [];
result.actions = [];
result.cards.forEach(card => {
result.cards.forEach((card) => {
result.checklists.push(
...Checklists.find({
cardId: card._id,
@@ -125,7 +137,7 @@ export class ExporterExcel {
}).fetch(),
);
});
result.rules.forEach(rule => {
result.rules.forEach((rule) => {
result.triggers.push(
...Triggers.find(
{
@@ -149,32 +161,32 @@ export class ExporterExcel {
// 1- only exports users that are linked somehow to that board
// 2- do not export any sensitive information
const users = {};
result.members.forEach(member => {
result.members.forEach((member) => {
users[member.userId] = true;
});
result.lists.forEach(list => {
result.lists.forEach((list) => {
users[list.userId] = true;
});
result.cards.forEach(card => {
result.cards.forEach((card) => {
users[card.userId] = true;
if (card.members) {
card.members.forEach(memberId => {
card.members.forEach((memberId) => {
users[memberId] = true;
});
}
if (card.assignees) {
card.assignees.forEach(memberId => {
card.assignees.forEach((memberId) => {
users[memberId] = true;
});
}
});
result.comments.forEach(comment => {
result.comments.forEach((comment) => {
users[comment.userId] = true;
});
result.activities.forEach(activity => {
result.activities.forEach((activity) => {
users[activity.userId] = true;
});
result.checklists.forEach(checklist => {
result.checklists.forEach((checklist) => {
users[checklist.userId] = true;
});
const byUserIds = {
@@ -194,7 +206,7 @@ export class ExporterExcel {
};
result.users = Users.find(byUserIds, userFields)
.fetch()
.map(user => {
.map((user) => {
// user avatar is stored as a relative url, we export absolute
if ((user.profile || {}).avatarUrl) {
user.profile.avatarUrl = FlowRouter.url(user.profile.avatarUrl);
@@ -235,7 +247,7 @@ export class ExporterExcel {
},
{
key: 'b',
width: 20,
width: 40,
},
{
key: 'c',
@@ -243,25 +255,11 @@ export class ExporterExcel {
},
{
key: 'd',
width: 20,
style: {
font: {
name: TAPi18n.__('excel-font'),
size: '10',
},
numFmt: 'yyyy/mm/dd hh:mm:ss',
},
width: 40,
},
{
key: 'e',
width: 20,
style: {
font: {
name: TAPi18n.__('excel-font'),
size: '10',
},
numFmt: 'yyyy/mm/dd hh:mm:ss',
},
},
{
key: 'f',
@@ -321,6 +319,13 @@ export class ExporterExcel {
{
key: 'k',
width: 20,
style: {
font: {
name: TAPi18n.__('excel-font'),
size: '10',
},
numFmt: 'yyyy/mm/dd hh:mm:ss',
},
},
{
key: 'l',
@@ -346,6 +351,10 @@ export class ExporterExcel {
key: 'q',
width: 20,
},
{
key: 'r',
width: 20,
},
];
//add title line
@@ -385,17 +394,17 @@ export class ExporterExcel {
//get kanban swimlanes info
const jswimlane = {};
for (const kswimlane in result.swimlanes) {
jswimlane[result.swimlanes[kswimlane]._id] = result.swimlanes[kswimlane].title;
jswimlane[result.swimlanes[kswimlane]._id] =
result.swimlanes[kswimlane].title;
}
//get kanban label info
const jlabel = {};
var isFirst = 1;
for (const klabel in result.labels){
console.log(klabel);
if (isFirst == 0){
for (const klabel in result.labels) {
// console.log(klabel);
if (isFirst == 0) {
jlabel[result.labels[klabel]._id] = `,${result.labels[klabel].name}`;
}
else{
} else {
isFirst = 0;
jlabel[result.labels[klabel]._id] = result.labels[klabel].name;
}
@@ -430,7 +439,7 @@ export class ExporterExcel {
size: 10,
bold: true,
};
ws.mergeCells('F3:Q3');
ws.mergeCells('F3:R3');
ws.getCell('B3').style = {
font: {
name: TAPi18n.__('excel-font'),
@@ -509,6 +518,7 @@ export class ExporterExcel {
TAPi18n.__('number'),
TAPi18n.__('title'),
TAPi18n.__('description'),
TAPi18n.__('parent-card'),
TAPi18n.__('owner'),
TAPi18n.__('createdAt'),
TAPi18n.__('last-modified-at'),
@@ -542,6 +552,7 @@ export class ExporterExcel {
allBorder('O5');
allBorder('P5');
allBorder('Q5');
allBorder('R5');
cellCenter('A5');
cellCenter('B5');
cellCenter('C5');
@@ -559,6 +570,7 @@ export class ExporterExcel {
cellCenter('O5');
cellCenter('P5');
cellCenter('Q5');
cellCenter('R5');
ws.getRow(5).font = {
name: TAPi18n.__('excel-font'),
size: 12,
@@ -586,6 +598,13 @@ export class ExporterExcel {
jclabel += jlabel[jcard.labelIds[jl]];
jclabel += ' ';
}
//get parent name
if (jcard.parentId) {
const parentCard = result.cards.find(
(card) => card._id === jcard.parentId,
);
jcard.parentCardTitle = parentCard ? parentCard.title : '';
}
//add card detail
const t = Number(i) + 1;
@@ -593,6 +612,7 @@ export class ExporterExcel {
t.toString(),
jcard.title,
jcard.description,
jcard.parentCardTitle,
jmeml[jcard.userId],
addTZhours(jcard.createdAt),
addTZhours(jcard.dateLastActivity),
@@ -627,6 +647,7 @@ export class ExporterExcel {
allBorder(`O${y}`);
allBorder(`P${y}`);
allBorder(`Q${y}`);
allBorder(`R${y}`);
cellCenter(`A${y}`);
ws.getCell(`B${y}`).alignment = {
wrapText: true,
@@ -634,17 +655,17 @@ export class ExporterExcel {
ws.getCell(`C${y}`).alignment = {
wrapText: true,
};
ws.getCell(`L${y}`).alignment = {
wrapText: true,
};
ws.getCell(`M${y}`).alignment = {
wrapText: true,
};
ws.getCell(`N${y}`).alignment = {
wrapText: true,
};
ws.getCell(`O${y}`).alignment = {
wrapText: true,
};
}
workbook.xlsx.write(res).then(function() {});
workbook.xlsx.write(res).then(function () {});
}
canExport(user) {
+28 -30
View File
@@ -38,7 +38,7 @@ export class Exporter {
// [Old] for attachments we only export IDs and absolute url to original doc
// [New] Encode attachment to base64
const getBase64Data = function(doc, callback) {
const getBase64Data = function (doc, callback) {
let buffer = Buffer.allocUnsafe(0);
buffer.fill(0);
@@ -49,14 +49,14 @@ export class Exporter {
);
const tmpWriteable = fs.createWriteStream(tmpFile);
const readStream = doc.createReadStream();
readStream.on('data', function(chunk) {
readStream.on('data', function (chunk) {
buffer = Buffer.concat([buffer, chunk]);
});
readStream.on('error', function() {
readStream.on('error', function () {
callback(null, null);
});
readStream.on('end', function() {
readStream.on('end', function () {
// done
fs.unlink(tmpFile, () => {
//ignored
@@ -72,7 +72,7 @@ export class Exporter {
: byBoard;
result.attachments = Attachments.find(byBoardAndAttachment)
.fetch()
.map(attachment => {
.map((attachment) => {
let filebase64 = null;
filebase64 = getBase64DataSync(attachment);
@@ -105,7 +105,7 @@ export class Exporter {
result.subtaskItems = [];
result.triggers = [];
result.actions = [];
result.cards.forEach(card => {
result.cards.forEach((card) => {
result.checklists.push(
...Checklists.find({
cardId: card._id,
@@ -122,7 +122,7 @@ export class Exporter {
}).fetch(),
);
});
result.rules.forEach(rule => {
result.rules.forEach((rule) => {
result.triggers.push(
...Triggers.find(
{
@@ -146,27 +146,27 @@ export class Exporter {
// 1- only exports users that are linked somehow to that board
// 2- do not export any sensitive information
const users = {};
result.members.forEach(member => {
result.members.forEach((member) => {
users[member.userId] = true;
});
result.lists.forEach(list => {
result.lists.forEach((list) => {
users[list.userId] = true;
});
result.cards.forEach(card => {
result.cards.forEach((card) => {
users[card.userId] = true;
if (card.members) {
card.members.forEach(memberId => {
card.members.forEach((memberId) => {
users[memberId] = true;
});
}
});
result.comments.forEach(comment => {
result.comments.forEach((comment) => {
users[comment.userId] = true;
});
result.activities.forEach(activity => {
result.activities.forEach((activity) => {
users[activity.userId] = true;
});
result.checklists.forEach(checklist => {
result.checklists.forEach((checklist) => {
users[checklist.userId] = true;
});
const byUserIds = {
@@ -187,7 +187,7 @@ export class Exporter {
};
result.users = Users.find(byUserIds, userFields)
.fetch()
.map(user => {
.map((user) => {
// user avatar is stored as a relative url, we export absolute
if ((user.profile || {}).avatarUrl) {
user.profile.avatarUrl = FlowRouter.url(user.profile.avatarUrl);
@@ -259,14 +259,14 @@ export class Exporter {
);
const customFieldMap = {};
let i = 0;
result.customFields.forEach(customField => {
result.customFields.forEach((customField) => {
customFieldMap[customField._id] = {
position: i,
type: customField.type,
};
if (customField.type === 'dropdown') {
let options = '';
customField.settings.dropdownItems.forEach(item => {
customField.settings.dropdownItems.forEach((item) => {
options = options === '' ? item.name : `${`${options}/${item.name}`}`;
});
columnHeaders.push(
@@ -308,7 +308,7 @@ export class Exporter {
TAPi18n.__('archived'),
*/
result.cards.forEach(card => {
result.cards.forEach((card) => {
const currentRow = [];
currentRow.push(card.title);
currentRow.push(card.description);
@@ -324,19 +324,19 @@ export class Exporter {
currentRow.push(card.requestedBy ? card.requestedBy : ' ');
currentRow.push(card.assignedBy ? card.assignedBy : ' ');
let usernames = '';
card.members.forEach(memberId => {
card.members.forEach((memberId) => {
const user = result.users.find(({ _id }) => _id === memberId);
usernames = `${usernames + user.username} `;
});
currentRow.push(usernames.trim());
let assignees = '';
card.assignees.forEach(assigneeId => {
card.assignees.forEach((assigneeId) => {
const user = result.users.find(({ _id }) => _id === assigneeId);
assignees = `${assignees + user.username} `;
});
currentRow.push(assignees.trim());
let labels = '';
card.labelIds.forEach(labelId => {
card.labelIds.forEach((labelId) => {
const label = result.labels.find(({ _id }) => _id === labelId);
labels = `${labels + label.name}-${label.color} `;
});
@@ -354,11 +354,11 @@ export class Exporter {
if (card.vote && card.vote.question !== '') {
let positiveVoters = '';
let negativeVoters = '';
card.vote.positive.forEach(userId => {
card.vote.positive.forEach((userId) => {
const user = result.users.find(({ _id }) => _id === userId);
positiveVoters = `${positiveVoters + user.username} `;
});
card.vote.negative.forEach(userId => {
card.vote.negative.forEach((userId) => {
const user = result.users.find(({ _id }) => _id === userId);
negativeVoters = `${negativeVoters + user.username} `;
});
@@ -378,12 +378,11 @@ export class Exporter {
currentRow.push(card.archived ? 'true' : 'false');
//Custom fields
const customFieldValuesToPush = new Array(result.customFields.length);
card.customFields.forEach(field => {
card.customFields.forEach((field) => {
if (field.value !== null) {
if (customFieldMap[field._id].type === 'date') {
customFieldValuesToPush[
customFieldMap[field._id].position
] = moment(field.value).format();
customFieldValuesToPush[customFieldMap[field._id].position] =
moment(field.value).format();
} else if (customFieldMap[field._id].type === 'dropdown') {
const dropdownOptions = result.customFields.find(
({ _id }) => _id === field._id,
@@ -391,9 +390,8 @@ export class Exporter {
const fieldValue = dropdownOptions.find(
({ _id }) => _id === field.value,
).name;
customFieldValuesToPush[
customFieldMap[field._id].position
] = fieldValue;
customFieldValuesToPush[customFieldMap[field._id].position] =
fieldValue;
} else {
customFieldValuesToPush[customFieldMap[field._id].position] =
field.value;
+79
View File
@@ -0,0 +1,79 @@
ImpersonatedUsers = new Mongo.Collection('impersonatedUsers');
/**
* A Impersonated User in wekan
*/
ImpersonatedUsers.attachSchema(
new SimpleSchema({
adminId: {
/**
* the admin userid that impersonates
*/
type: String,
optional: true,
},
userId: {
/**
* the userId that is impersonated
*/
type: String,
optional: true,
},
boardId: {
/**
* the boardId that was exported by anyone that has sometime impersonated
*/
type: String,
optional: true,
},
attachmentId: {
/**
* the attachmentId that was exported by anyone that has sometime impersonated
*/
type: String,
optional: true,
},
reason: {
/**
* the reason why impersonated, like exportJSON
*/
type: String,
optional: true,
},
createdAt: {
/**
* creation date of the impersonation
*/
type: Date,
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert) {
return new Date();
} else if (this.isUpsert) {
return {
$setOnInsert: new Date(),
};
} else {
this.unset();
}
},
},
modifiedAt: {
/**
* modified date of the impersonation
*/
type: Date,
denyUpdate: false,
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert || this.isUpsert || this.isUpdate) {
return new Date();
} else {
this.unset();
}
},
},
}),
);
export default ImpersonatedUsers;
+6 -1
View File
@@ -157,9 +157,14 @@ export class TrelloCreator {
// You must call parseActions before calling this one.
createBoardAndLabels(trelloBoard) {
let color = 'blue';
if (this.getColor(trelloBoard.prefs.background) !== undefined) {
color = this.getColor(trelloBoard.prefs.background);
}
const boardToCreate = {
archived: trelloBoard.closed,
color: this.getColor(trelloBoard.prefs.background),
color: color,
// very old boards won't have a creation activity so no creation date
createdAt: this._now(this.createdAt.board),
labels: [],
+358 -147
View File
@@ -1,4 +1,5 @@
import { SyncedCron } from 'meteor/percolate:synced-cron';
import ImpersonatedUsers from './impersonatedUsers';
// Sandstorm context is detected using the METEOR_SETTINGS environment variable
// in the package definition.
@@ -67,7 +68,9 @@ Users.attachSchema(
if (this.isInsert) {
return new Date();
} else if (this.isUpsert) {
return { $setOnInsert: new Date() };
return {
$setOnInsert: new Date(),
};
} else {
this.unset();
}
@@ -350,7 +353,9 @@ Users.attachSchema(
Users.allow({
update(userId, doc) {
const user = Users.findOne({ _id: userId });
const user = Users.findOne({
_id: userId,
});
if ((user && user.isAdmin) || (Meteor.user() && Meteor.user().isAdmin))
return true;
if (!user) {
@@ -359,10 +364,18 @@ Users.allow({
return doc._id === userId;
},
remove(userId, doc) {
const adminsNumber = Users.find({ isAdmin: true }).count();
const adminsNumber = Users.find({
isAdmin: true,
}).count();
const { isAdmin } = Users.findOne(
{ _id: userId },
{ fields: { isAdmin: 1 } },
{
_id: userId,
},
{
fields: {
isAdmin: 1,
},
},
);
// Prevents remove of the only one administrator
@@ -440,7 +453,7 @@ if (Meteor.isClient) {
});
}
Users.parseImportUsernames = usernamesString => {
Users.parseImportUsernames = (usernamesString) => {
return usernamesString.trim().split(new RegExp('\\s*[,;]\\s*'));
};
@@ -454,17 +467,30 @@ Users.helpers({
boards() {
return Boards.find(
{ 'members.userId': this._id },
{ sort: { sort: 1 /* boards default sorting */ } },
{
'members.userId': this._id,
},
{
sort: {
sort: 1 /* boards default sorting */,
},
},
);
},
starredBoards() {
const { starredBoards = [] } = this.profile || {};
return Boards.find(
{ archived: false, _id: { $in: starredBoards } },
{
sort: { sort: 1 /* boards default sorting */ },
archived: false,
_id: {
$in: starredBoards,
},
},
{
sort: {
sort: 1 /* boards default sorting */,
},
},
);
},
@@ -477,9 +503,16 @@ Users.helpers({
invitedBoards() {
const { invitedBoards = [] } = this.profile || {};
return Boards.find(
{ archived: false, _id: { $in: invitedBoards } },
{
sort: { sort: 1 /* boards default sorting */ },
archived: false,
_id: {
$in: invitedBoards,
},
},
{
sort: {
sort: 1 /* boards default sorting */,
},
},
);
},
@@ -611,7 +644,9 @@ Users.helpers({
},
remove() {
User.remove({ _id: this._id });
User.remove({
_id: this._id,
});
},
});
@@ -714,7 +749,9 @@ Users.mutations({
addNotification(activityId) {
return {
$addToSet: {
'profile.notifications': { activity: activityId },
'profile.notifications': {
activity: activityId,
},
},
};
},
@@ -722,7 +759,9 @@ Users.mutations({
removeNotification(activityId) {
return {
$pull: {
'profile.notifications': { activity: activityId },
'profile.notifications': {
activity: activityId,
},
},
};
},
@@ -744,15 +783,27 @@ Users.mutations({
},
setAvatarUrl(avatarUrl) {
return { $set: { 'profile.avatarUrl': avatarUrl } };
return {
$set: {
'profile.avatarUrl': avatarUrl,
},
};
},
setShowCardsCountAt(limit) {
return { $set: { 'profile.showCardsCountAt': limit } };
return {
$set: {
'profile.showCardsCountAt': limit,
},
};
},
setStartDayOfWeek(startDay) {
return { $set: { 'profile.startDayOfWeek': startDay } };
return {
$set: {
'profile.startDayOfWeek': startDay,
},
};
},
setBoardView(view) {
@@ -801,15 +852,33 @@ if (Meteor.isServer) {
if (Meteor.user() && Meteor.user().isAdmin) {
// If setting is missing, add it
Users.update(
{ 'profile.hiddenSystemMessages': { $exists: false } },
{ $set: { 'profile.hiddenSystemMessages': true } },
{ multi: true },
{
'profile.hiddenSystemMessages': {
$exists: false,
},
},
{
$set: {
'profile.hiddenSystemMessages': true,
},
},
{
multi: true,
},
);
// If setting is false, set it to true
Users.update(
{ 'profile.hiddenSystemMessages': false },
{ $set: { 'profile.hiddenSystemMessages': true } },
{ multi: true },
{
'profile.hiddenSystemMessages': false,
},
{
$set: {
'profile.hiddenSystemMessages': true,
},
},
{
multi: true,
},
);
return true;
} else {
@@ -836,8 +905,12 @@ if (Meteor.isServer) {
check(email, String);
check(importUsernames, Array);
const nUsersWithUsername = Users.find({ username }).count();
const nUsersWithEmail = Users.find({ email }).count();
const nUsersWithUsername = Users.find({
username,
}).count();
const nUsersWithEmail = Users.find({
email,
}).count();
if (nUsersWithUsername > 0) {
throw new Meteor.Error('username-already-taken');
} else if (nUsersWithEmail > 0) {
@@ -851,7 +924,11 @@ if (Meteor.isServer) {
email: email.toLowerCase(),
from: 'admin',
});
const user = Users.findOne(username) || Users.findOne({ username });
const user =
Users.findOne(username) ||
Users.findOne({
username,
});
if (user) {
Users.update(user._id, {
$set: {
@@ -868,11 +945,17 @@ if (Meteor.isServer) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(username, String);
check(userId, String);
const nUsersWithUsername = Users.find({ username }).count();
const nUsersWithUsername = Users.find({
username,
}).count();
if (nUsersWithUsername > 0) {
throw new Meteor.Error('username-already-taken');
} else {
Users.update(userId, { $set: { username } });
Users.update(userId, {
$set: {
username,
},
});
}
}
},
@@ -883,8 +966,14 @@ if (Meteor.isServer) {
}
check(email, String);
const existingUser = Users.findOne(
{ 'emails.address': email },
{ fields: { _id: 1 } },
{
'emails.address': email,
},
{
fields: {
_id: 1,
},
},
);
if (existingUser) {
throw new Meteor.Error('email-already-taken');
@@ -963,7 +1052,9 @@ if (Meteor.isServer) {
board &&
board.members &&
_.contains(_.pluck(board.members, 'userId'), inviter._id) &&
_.where(board.members, { userId: inviter._id })[0].isActive;
_.where(board.members, {
userId: inviter._id,
})[0].isActive;
// GitHub issue 2060
//_.where(board.members, { userId: inviter._id })[0].isAdmin;
if (!allowInvite) throw new Meteor.Error('error-board-notAMember');
@@ -973,22 +1064,39 @@ if (Meteor.isServer) {
const posAt = username.indexOf('@');
let user = null;
if (posAt >= 0) {
user = Users.findOne({ emails: { $elemMatch: { address: username } } });
user = Users.findOne({
emails: {
$elemMatch: {
address: username,
},
},
});
} else {
user = Users.findOne(username) || Users.findOne({ username });
user =
Users.findOne(username) ||
Users.findOne({
username,
});
}
if (user) {
if (user._id === inviter._id)
throw new Meteor.Error('error-user-notAllowSelf');
} else {
if (posAt <= 0) throw new Meteor.Error('error-user-doesNotExist');
if (Settings.findOne({ disableRegistration: true })) {
if (
Settings.findOne({
disableRegistration: true,
})
) {
throw new Meteor.Error('error-user-notCreated');
}
// Set in lowercase email before creating account
const email = username.toLowerCase();
username = email.substring(0, posAt);
const newUserId = Accounts.createUser({ username, email });
const newUserId = Accounts.createUser({
username,
email,
});
if (!newUserId) throw new Meteor.Error('error-user-notCreated');
// assume new user speak same language with inviter
if (inviter.profile && inviter.profile.language) {
@@ -1032,7 +1140,10 @@ if (Meteor.isServer) {
} catch (e) {
throw new Meteor.Error('email-fail', e.message);
}
return { username: user.username, email: user.emails[0].address };
return {
username: user.username,
email: user.emails[0].address,
};
},
impersonate(userId) {
check(userId, String);
@@ -1042,8 +1153,16 @@ if (Meteor.isServer) {
if (!Meteor.user().isAdmin)
throw new Meteor.Error(403, 'Permission denied');
ImpersonatedUsers.insert({ adminId: Meteor.user()._id, userId: userId, reason: 'clickedImpersonate' });
this.setUserId(userId);
},
isImpersonated(userId) {
check(userId, String);
const isImpersonated = ImpersonatedUsers.findOne({
userId: userId,
});
return isImpersonated;
},
});
Accounts.onCreateUser((options, user) => {
const userCount = Users.find().count();
@@ -1059,7 +1178,12 @@ if (Meteor.isServer) {
}
email = email.toLowerCase();
user.username = user.services.oidc.username;
user.emails = [{ address: email, verified: true }];
user.emails = [
{
address: email,
verified: true,
},
];
const initials = user.services.oidc.fullname
.split(/\s+/)
.reduce((memo, word) => {
@@ -1075,7 +1199,14 @@ if (Meteor.isServer) {
// see if any existing user has this email address or username, otherwise create new
const existingUser = Meteor.users.findOne({
$or: [{ 'emails.address': email }, { username: user.username }],
$or: [
{
'emails.address': email,
},
{
username: user.username,
},
],
});
if (!existingUser) return user;
@@ -1087,8 +1218,12 @@ if (Meteor.isServer) {
existingUser.profile = user.profile;
existingUser.authenticationMethod = user.authenticationMethod;
Meteor.users.remove({ _id: user._id });
Meteor.users.remove({ _id: existingUser._id }); // is going to be created again
Meteor.users.remove({
_id: user._id,
});
Meteor.users.remove({
_id: existingUser._id,
}); // is going to be created again
return existingUser;
}
@@ -1127,13 +1262,17 @@ if (Meteor.isServer) {
"The invitation code doesn't exist",
);
} else {
user.profile = { icode: options.profile.invitationcode };
user.profile = {
icode: options.profile.invitationcode,
};
user.profile.boardView = 'board-view-swimlanes';
// Deletes the invitation code after the user was created successfully.
setTimeout(
Meteor.bindEnvironment(() => {
InvitationCodes.remove({ _id: invitationCode._id });
InvitationCodes.remove({
_id: invitationCode._id,
});
}),
200,
);
@@ -1153,7 +1292,7 @@ const addCronJob = _.debounce(
SyncedCron.add({
name: 'notification_cleanup',
schedule: parser => parser.text('every 1 days'),
schedule: (parser) => parser.text('every 1 days'),
job: () => {
for (const user of Users.find()) {
if (!user.profile || !user.profile.notifications) continue;
@@ -1178,15 +1317,19 @@ const addCronJob = _.debounce(
if (Meteor.isServer) {
// Let mongoDB ensure username unicity
Meteor.startup(() => {
allowedSortValues.forEach(value => {
allowedSortValues.forEach((value) => {
Lists._collection._ensureIndex(value);
});
Users._collection._ensureIndex({ modifiedAt: -1 });
Users._collection._ensureIndex({
modifiedAt: -1,
});
Users._collection._ensureIndex(
{
username: 1,
},
{ unique: true },
{
unique: true,
},
);
Meteor.defer(() => {
addCronJob();
@@ -1215,7 +1358,7 @@ if (Meteor.isServer) {
// counter.
// We need to run this code on the server only, otherwise the incrementation
// will be done twice.
Users.after.update(function(userId, user, fieldNames) {
Users.after.update(function (userId, user, fieldNames) {
// The `starredBoards` list is hosted on the `profile` field. If this
// field hasn't been modificated we don't need to run this hook.
if (!_.contains(fieldNames, 'profile')) return;
@@ -1233,8 +1376,12 @@ if (Meteor.isServer) {
// b. We use it to find deleted and newly inserted ids by using it in one
// direction and then in the other.
function incrementBoards(boardsIds, inc) {
boardsIds.forEach(boardId => {
Boards.update(boardId, { $inc: { stars: inc } });
boardsIds.forEach((boardId) => {
Boards.update(boardId, {
$inc: {
stars: inc,
},
});
});
}
@@ -1258,23 +1405,23 @@ if (Meteor.isServer) {
fakeUserId.withValue(doc._id, () => {
/*
// Insert the Welcome Board
Boards.insert({
title: TAPi18n.__('welcome-board'),
permission: 'private',
}, fakeUser, (err, boardId) => {
// Insert the Welcome Board
Boards.insert({
title: TAPi18n.__('welcome-board'),
permission: 'private',
}, fakeUser, (err, boardId) => {
Swimlanes.insert({
title: TAPi18n.__('welcome-swimlane'),
boardId,
sort: 1,
}, fakeUser);
Swimlanes.insert({
title: TAPi18n.__('welcome-swimlane'),
boardId,
sort: 1,
}, fakeUser);
['welcome-list1', 'welcome-list2'].forEach((title, titleIndex) => {
Lists.insert({title: TAPi18n.__(title), boardId, sort: titleIndex}, fakeUser);
});
});
*/
['welcome-list1', 'welcome-list2'].forEach((title, titleIndex) => {
Lists.insert({title: TAPi18n.__(title), boardId, sort: titleIndex}, fakeUser);
});
});
*/
const Future = require('fibers/future');
const future1 = new Future();
@@ -1290,7 +1437,9 @@ if (Meteor.isServer) {
(err, boardId) => {
// Insert the reference to our templates board
Users.update(fakeUserId.get(), {
$set: { 'profile.templatesBoardId': boardId },
$set: {
'profile.templatesBoardId': boardId,
},
});
// Insert the card templates swimlane
@@ -1305,7 +1454,9 @@ if (Meteor.isServer) {
(err, swimlaneId) => {
// Insert the reference to out card templates swimlane
Users.update(fakeUserId.get(), {
$set: { 'profile.cardTemplatesSwimlaneId': swimlaneId },
$set: {
'profile.cardTemplatesSwimlaneId': swimlaneId,
},
});
future1.return();
},
@@ -1323,7 +1474,9 @@ if (Meteor.isServer) {
(err, swimlaneId) => {
// Insert the reference to out list templates swimlane
Users.update(fakeUserId.get(), {
$set: { 'profile.listTemplatesSwimlaneId': swimlaneId },
$set: {
'profile.listTemplatesSwimlaneId': swimlaneId,
},
});
future2.return();
},
@@ -1341,7 +1494,9 @@ if (Meteor.isServer) {
(err, swimlaneId) => {
// Insert the reference to out board templates swimlane
Users.update(fakeUserId.get(), {
$set: { 'profile.boardTemplatesSwimlaneId': swimlaneId },
$set: {
'profile.boardTemplatesSwimlaneId': swimlaneId,
},
});
future3.return();
},
@@ -1358,7 +1513,9 @@ if (Meteor.isServer) {
Users.after.insert((userId, doc) => {
// HACK
doc = Users.findOne({ _id: doc._id });
doc = Users.findOne({
_id: doc._id,
});
if (doc.createdThroughApi) {
// The admin user should be able to create a user despite disabling registration because
// it is two different things (registration and creation).
@@ -1366,7 +1523,11 @@ if (Meteor.isServer) {
// the disableRegistration check.
// Issue : https://github.com/wekan/wekan/issues/1232
// PR : https://github.com/wekan/wekan/pull/1251
Users.update(doc._id, { $set: { createdThroughApi: '' } });
Users.update(doc._id, {
$set: {
createdThroughApi: '',
},
});
return;
}
@@ -1382,7 +1543,7 @@ if (Meteor.isServer) {
if (!invitationCode) {
throw new Meteor.Error('error-invitation-code-not-exist');
} else {
invitationCode.boardsToBeInvited.forEach(boardId => {
invitationCode.boardsToBeInvited.forEach((boardId) => {
const board = Boards.findOne(boardId);
board.addMember(doc._id);
});
@@ -1390,8 +1551,16 @@ if (Meteor.isServer) {
doc.profile = {};
}
doc.profile.invitedBoards = invitationCode.boardsToBeInvited;
Users.update(doc._id, { $set: { profile: doc.profile } });
InvitationCodes.update(invitationCode._id, { $set: { valid: false } });
Users.update(doc._id, {
$set: {
profile: doc.profile,
},
});
InvitationCodes.update(invitationCode._id, {
$set: {
valid: false,
},
});
}
}
});
@@ -1400,12 +1569,14 @@ if (Meteor.isServer) {
// USERS REST API
if (Meteor.isServer) {
// Middleware which checks that API is enabled.
JsonRoutes.Middleware.use(function(req, res, next) {
JsonRoutes.Middleware.use(function (req, res, next) {
const api = req.url.startsWith('/api');
if ((api === true && process.env.WITH_API === 'true') || api === false) {
return next();
} else {
res.writeHead(301, { Location: '/' });
res.writeHead(301, {
Location: '/',
});
return res.end();
}
});
@@ -1416,10 +1587,12 @@ if (Meteor.isServer) {
* @summary returns the current user
* @return_type Users
*/
JsonRoutes.add('GET', '/api/user', function(req, res) {
JsonRoutes.add('GET', '/api/user', function (req, res) {
try {
Authentication.checkLoggedIn(req.userId);
const data = Meteor.users.findOne({ _id: req.userId });
const data = Meteor.users.findOne({
_id: req.userId,
});
delete data.services;
// get all boards where the user is member of
@@ -1429,11 +1602,14 @@ if (Meteor.isServer) {
'members.userId': req.userId,
},
{
fields: { _id: 1, members: 1 },
fields: {
_id: 1,
members: 1,
},
},
);
boards = boards.map(b => {
const u = b.members.find(m => m.userId === req.userId);
boards = boards.map((b) => {
const u = b.members.find((m) => m.userId === req.userId);
delete u.userId;
u.boardId = b._id;
return u;
@@ -1461,13 +1637,16 @@ if (Meteor.isServer) {
* @return_type [{ _id: string,
* username: string}]
*/
JsonRoutes.add('GET', '/api/users', function(req, res) {
JsonRoutes.add('GET', '/api/users', function (req, res) {
try {
Authentication.checkUserId(req.userId);
JsonRoutes.sendResult(res, {
code: 200,
data: Meteor.users.find({}).map(function(doc) {
return { _id: doc._id, username: doc.username };
data: Meteor.users.find({}).map(function (doc) {
return {
_id: doc._id,
username: doc.username,
};
}),
});
} catch (error) {
@@ -1488,13 +1667,17 @@ if (Meteor.isServer) {
* @param {string} userId the user ID or username
* @return_type Users
*/
JsonRoutes.add('GET', '/api/users/:userId', function(req, res) {
JsonRoutes.add('GET', '/api/users/:userId', function (req, res) {
try {
Authentication.checkUserId(req.userId);
let id = req.params.userId;
let user = Meteor.users.findOne({ _id: id });
let user = Meteor.users.findOne({
_id: id,
});
if (!user) {
user = Meteor.users.findOne({ username: id });
user = Meteor.users.findOne({
username: id,
});
id = user._id;
}
@@ -1505,11 +1688,14 @@ if (Meteor.isServer) {
'members.userId': id,
},
{
fields: { _id: 1, members: 1 },
fields: {
_id: 1,
members: 1,
},
},
);
boards = boards.map(b => {
const u = b.members.find(m => m.userId === id);
boards = boards.map((b) => {
const u = b.members.find((m) => m.userId === id);
delete u.userId;
u.boardId = b._id;
return u;
@@ -1545,12 +1731,14 @@ if (Meteor.isServer) {
* @return_type {_id: string,
* title: string}
*/
JsonRoutes.add('PUT', '/api/users/:userId', function(req, res) {
JsonRoutes.add('PUT', '/api/users/:userId', function (req, res) {
try {
Authentication.checkUserId(req.userId);
const id = req.params.userId;
const action = req.body.action;
let data = Meteor.users.findOne({ _id: id });
let data = Meteor.users.findOne({
_id: id,
});
if (data !== undefined) {
if (action === 'takeOwnership') {
data = Boards.find(
@@ -1558,8 +1746,12 @@ if (Meteor.isServer) {
'members.userId': id,
'members.isAdmin': true,
},
{ sort: { sort: 1 /* boards default sorting */ } },
).map(function(board) {
{
sort: {
sort: 1 /* boards default sorting */,
},
},
).map(function (board) {
if (board.hasMember(req.userId)) {
board.removeMember(req.userId);
}
@@ -1572,7 +1764,9 @@ if (Meteor.isServer) {
} else {
if (action === 'disableLogin' && id !== req.userId) {
Users.update(
{ _id: id },
{
_id: id,
},
{
$set: {
loginDisabled: true,
@@ -1581,9 +1775,20 @@ if (Meteor.isServer) {
},
);
} else if (action === 'enableLogin') {
Users.update({ _id: id }, { $set: { loginDisabled: '' } });
Users.update(
{
_id: id,
},
{
$set: {
loginDisabled: '',
},
},
);
}
data = Meteor.users.findOne({ _id: id });
data = Meteor.users.findOne({
_id: id,
});
}
}
JsonRoutes.sendResult(res, {
@@ -1617,53 +1822,57 @@ if (Meteor.isServer) {
* @return_type {_id: string,
* title: string}
*/
JsonRoutes.add('POST', '/api/boards/:boardId/members/:userId/add', function(
req,
res,
) {
try {
Authentication.checkUserId(req.userId);
const userId = req.params.userId;
const boardId = req.params.boardId;
const action = req.body.action;
const { isAdmin, isNoComments, isCommentOnly } = req.body;
let data = Meteor.users.findOne({ _id: userId });
if (data !== undefined) {
if (action === 'add') {
data = Boards.find({
_id: boardId,
}).map(function(board) {
if (!board.hasMember(userId)) {
board.addMember(userId);
function isTrue(data) {
return data.toLowerCase() === 'true';
JsonRoutes.add(
'POST',
'/api/boards/:boardId/members/:userId/add',
function (req, res) {
try {
Authentication.checkUserId(req.userId);
const userId = req.params.userId;
const boardId = req.params.boardId;
const action = req.body.action;
const { isAdmin, isNoComments, isCommentOnly } = req.body;
let data = Meteor.users.findOne({
_id: userId,
});
if (data !== undefined) {
if (action === 'add') {
data = Boards.find({
_id: boardId,
}).map(function (board) {
if (!board.hasMember(userId)) {
board.addMember(userId);
function isTrue(data) {
return data.toLowerCase() === 'true';
}
board.setMemberPermission(
userId,
isTrue(isAdmin),
isTrue(isNoComments),
isTrue(isCommentOnly),
userId,
);
}
board.setMemberPermission(
userId,
isTrue(isAdmin),
isTrue(isNoComments),
isTrue(isCommentOnly),
userId,
);
}
return {
_id: board._id,
title: board.title,
};
});
return {
_id: board._id,
title: board.title,
};
});
}
}
JsonRoutes.sendResult(res, {
code: 200,
data: query,
});
} catch (error) {
JsonRoutes.sendResult(res, {
code: 200,
data: error,
});
}
JsonRoutes.sendResult(res, {
code: 200,
data: query,
});
} catch (error) {
JsonRoutes.sendResult(res, {
code: 200,
data: error,
});
}
});
},
);
/**
* @operation remove_board_member
@@ -1682,18 +1891,20 @@ if (Meteor.isServer) {
JsonRoutes.add(
'POST',
'/api/boards/:boardId/members/:userId/remove',
function(req, res) {
function (req, res) {
try {
Authentication.checkUserId(req.userId);
const userId = req.params.userId;
const boardId = req.params.boardId;
const action = req.body.action;
let data = Meteor.users.findOne({ _id: userId });
let data = Meteor.users.findOne({
_id: userId,
});
if (data !== undefined) {
if (action === 'remove') {
data = Boards.find({
_id: boardId,
}).map(function(board) {
}).map(function (board) {
if (board.hasMember(userId)) {
board.removeMember(userId);
}
@@ -1729,7 +1940,7 @@ if (Meteor.isServer) {
* @param {string} password the password of the new user
* @return_type {_id: string}
*/
JsonRoutes.add('POST', '/api/users/', function(req, res) {
JsonRoutes.add('POST', '/api/users/', function (req, res) {
try {
Authentication.checkUserId(req.userId);
const id = Accounts.createUser({
@@ -1762,7 +1973,7 @@ if (Meteor.isServer) {
* @param {string} userId the ID of the user to delete
* @return_type {_id: string}
*/
JsonRoutes.add('DELETE', '/api/users/:userId', function(req, res) {
JsonRoutes.add('DELETE', '/api/users/:userId', function (req, res) {
try {
Authentication.checkUserId(req.userId);
const id = req.params.userId;
@@ -1800,7 +2011,7 @@ if (Meteor.isServer) {
* @param {string} userId the ID of the user to create token for.
* @return_type {_id: string}
*/
JsonRoutes.add('POST', '/api/createtoken/:userId', function(req, res) {
JsonRoutes.add('POST', '/api/createtoken/:userId', function (req, res) {
try {
Authentication.checkUserId(req.userId);
const id = req.params.userId;
+8698 -4416
View File
File diff suppressed because it is too large. Load diff
+18 -56
View File
@@ -1,35 +1,8 @@
{
"name": "wekan",
"version": "v5.26.0",
"version": "v5.30.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {
"lint": "eslint --cache --ext .js --ignore-path .eslintignore .",
"lint:eslint:fix": "eslint --ext .js --ignore-path .eslintignore --fix .",
"lint:staged": "lint-staged",
"prettify": "prettier --write '**/*.js' '**/*.jsx'",
"test": "npm run lint"
},
"lint-staged": {
"*.js": [
"meteor npm run prettify",
"meteor npm run lint:eslint:fix",
"git add --force"
],
"*.jsx": [
"meteor npm run prettify",
"meteor npm run lint:eslint:fix",
"git add --force"
],
"*.json": [
"prettier --write",
"git add --force"
]
},
"pre-commit": "lint:staged",
"eslintConfig": {
"extends": "@meteorjs/eslint-config-meteor"
},
"repository": {
"type": "git",
"url": "git+https://github.com/wekan/wekan.git"
@@ -40,44 +13,33 @@
},
"homepage": "https://wekan.github.io",
"devDependencies": {
"babel-eslint": "^10.1.0",
"eslint": "^5.16.0",
"eslint-config-meteor": "0.0.9",
"eslint-config-prettier": "^3.6.0",
"eslint-import-resolver-meteor": "^0.4.0",
"eslint-plugin-import": "^2.20.0",
"eslint-plugin-meteor": "^5.1.0",
"eslint-plugin-prettier": "^3.1.2",
"lint-staged": "^7.3.0",
"pre-commit": "^1.2.2",
"prettier": "^1.19.1",
"prettier-eslint": "^9.0.2"
"flatted": "^3.1.1"
},
"dependencies": {
"@babel/core": "^7.9.6",
"@babel/runtime": "^7.9.6",
"@root/request": "^1.6.1",
"ajv": "^6.12.4",
"@babel/core": "^7.14.0",
"@babel/runtime": "^7.14.0",
"@liradb2000/markdown-it-mermaid": "^0.4.2",
"ajv": "^6.12.6",
"babel-runtime": "^6.26.0",
"bcrypt": "^5.0.0",
"bson": "^4.0.3",
"bunyan": "^1.8.12",
"bcryptjs": "^2.4.3",
"bson": "^4.3.0",
"bunyan": "^1.8.15",
"core-js": "^2.6.12",
"dompurify": "^2.2.8",
"es6-promise": "^4.2.4",
"exceljs": "^4.2.1",
"fibers": "^5.0.0",
"flatted": "^3.0.4",
"gridfs-stream": "https://github.com/wekan/gridfs-stream/tarball/master",
"jszip": "^3.4.0",
"ldapjs": "^2.1.1",
"markdown-it": "^12.0.2",
"jszip": "^3.6.0",
"ldapjs": "^2.2.4",
"markdown-it": "^12.0.6",
"markdown-it-emoji": "^2.0.0",
"meteor-node-stubs": "^1.0.3",
"mongodb": "^3.6.2",
"mongodb": "^3.6.6",
"os": "^0.1.1",
"page": "^1.11.5",
"papaparse": "^5.2.0",
"qs": "^6.9.4",
"source-map-support": "^0.5.19",
"xss": "^1.0.8"
"papaparse": "^5.3.0",
"qs": "^6.10.1",
"source-map-support": "^0.5.19"
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions';
checkNpmVersions({
'xss': '1.0.8',
'dompurify': '2.2.8',
}, 'my:xss');
+10 -3
View File
@@ -1,4 +1,5 @@
import sanitizeXss from 'xss';
import DOMPurify from 'dompurify';
var Markdown = require('markdown-it')({
html: true,
linkify: true,
@@ -6,7 +7,9 @@ var Markdown = require('markdown-it')({
breaks: true,
});
import markdownItMermaid from "@liradb2000/markdown-it-mermaid";
/*
// Static URL Scheme Listing
var urlschemes = [
"aodroplink",
@@ -19,7 +22,7 @@ var urlschemes = [
"mailspring"
];
// Better would be a field in the admin backend to set this dynamically
// Better would be a field in the admin backend to set this dynamically
// instead of putting all known or wanted url schemes here hard into code
// but i was not able to access those settings
// var urlschemes = currentSetting.automaticLinkedUrlSchemes.split('\n');
@@ -44,14 +47,18 @@ function mySafeAttrValue(tag, name, value, cssFilter) {
// use the default safeAttrValue function to process all non cbthunderlinks
return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
}
// } else if (tag === 'svg') {
// return `<img src="data:image/svg+xml;base64,` + atob(value) + `"></img>`;
} else {
// use the default safeAttrValue function to process it
return sanitizeXss.safeAttrValue(tag, name, value, cssFilter);
}
};
*/
var emoji = require('markdown-it-emoji');
Markdown.use(emoji);
Markdown.use(markdownItMermaid);
if (Package.ui) {
const Template = Package.templating.Template;
@@ -66,6 +73,6 @@ if (Package.ui) {
text = Blaze._toText(self.templateContentBlock, HTML.TEXTMODE.STRING);
}
return HTML.Raw(sanitizeXss(Markdown.render(text), { safeAttrValue: mySafeAttrValue }));
return HTML.Raw(DOMPurify.sanitize(Markdown.render(text), {ALLOW_UNKNOWN_PROTOCOLS: true}));
}));
}
@@ -0,0 +1,5 @@
language: node_js
node_js:
- "0.10"
before_install:
- "curl -L http://git.io/s0Zu-w | /bin/sh"
@@ -0,0 +1,288 @@
# Changelog
## [v0.1.50] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.1.46)
#### 21/1/19 by Harry Adel
- Bump to version 0.1.50
- *Merged pull-request:* "filename conversion for FS.HTTP.Handlers.Get" [#9](https://github.com/zcfs/Meteor-CollectionFS/pull/994) ([yatusiter](https://github.com/yatusiter))
## [v0.1.46] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.1.46)
#### 30/3/15 by Eric Dobbertin
- Bump to version 0.1.46
- *Merged pull-request:* [#611](https://github.com/zcfs/Meteor-CollectionFS/issues/611)
- Exposed request handlers on `FS.HTTP.Handlers` object so that app can override
## [v0.1.43] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.1.43)
#### 20/12/14 by Morten Henriksen
- add changelog
- Bump to version 0.1.43
- *Fixed bug:* "Doesn't work in IE 8" [#10](https://github.com/zcfs/Meteor-cfs-access-point/issues/10)
- *Merged pull-request:* "rootUrlPathPrefix fix for cordova" [#9](https://github.com/zcfs/Meteor-cfs-access-point/issues/9) ([dmitriyles](https://github.com/dmitriyles))
- *Merged pull-request:* "Support for expiration token" [#1](https://github.com/zcfs/Meteor-cfs-access-point/issues/1) ([tanis2000](https://github.com/tanis2000))
Patches by GitHub users [@dmitriyles](https://github.com/dmitriyles), [@tanis2000](https://github.com/tanis2000).
## [v0.1.42] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.1.42)
#### 17/12/14 by Morten Henriksen
## [v0.1.41] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.1.41)
#### 17/12/14 by Morten Henriksen
- mbr update, remove versions.json
- Cordova rootUrlPathPrefix fix
- Bump to version 0.1.41
## [v0.1.40] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.1.40)
#### 17/12/14 by Morten Henriksen
- mbr fixed warnings
- fixes to GET handler
- add back tests
- support apps in server subdirectories; closes #8
- 0.9.1 support
## [v0.0.39] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.39)
#### 28/08/14 by Morten Henriksen
- Meteor Package System Update
## [v0.0.38] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.38)
#### 27/08/14 by Eric Dobbertin
## [v0.0.37] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.37)
#### 26/08/14 by Eric Dobbertin
- change package name to lowercase
## [v0.0.36] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.36)
#### 06/08/14 by Eric Dobbertin
- pass correct arg
## [v0.0.35] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.35)
#### 06/08/14 by Eric Dobbertin
- move to correct place
## [v0.0.34] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.34)
#### 05/08/14 by Eric Dobbertin
- *Merged pull-request:* "Added contentLength for ranges and inline content" [#5](https://github.com/zcfs/Meteor-cfs-access-point/issues/5) ([maomorales](https://github.com/maomorales))
- Content-Length and Last-Modified headers
Patches by GitHub user [@maomorales](https://github.com/maomorales).
## [v0.0.33] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.33)
#### 31/07/14 by Eric Dobbertin
- *Merged pull-request:* "Force browser to download with filename passed in url" [#3](https://github.com/zcfs/Meteor-cfs-access-point/issues/3) ([elbowz](https://github.com/elbowz))
- Force browser to download with filename passed in url
Patches by GitHub user [@elbowz](https://github.com/elbowz).
## [v0.0.32] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.32)
#### 28/07/14 by Eric Dobbertin
- support collection-specific GET headers
- update API docs
## [v0.0.31] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.31)
#### 06/07/14 by Eric Dobbertin
- allow override filename
## [v0.0.30] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.30)
#### 30/04/14 by Eric Dobbertin
- ignore auth on server so that url method can be called on the server
## [v0.0.29] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.29)
#### 30/04/14 by Eric Dobbertin
- rework the new authtoken stuff to make it easier to debug and cleaner
## [v0.0.28] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.28)
#### 29/04/14 by Eric Dobbertin
- generate api docs
- adjustments to use new FS.File API functions, plus have `url` function omit query string whenever possible
- *Merged pull-request:* "Support for expiration token" [#1](https://github.com/zcfs/Meteor-cfs-access-point/issues/1) ([tanis2000](https://github.com/tanis2000))
- Switched to HTTP.call() to get the server time
- Better check for options.auth being a number. Check to see if we have Buffer() available on the server side. New check to make sure we have the token. Switched Metheor.method to HTTP.methods for the getServerTime() function.
- Expiration is now optional. If auth is set to a number, that is the number of seconds the token is valid for.
- Added time sync with the server for token generation.
- Added code to pass a token with a set expiration date from the client. Added token check on the server side.
Patches by GitHub user [@tanis2000](https://github.com/tanis2000).
## [v0.0.27] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.27)
#### 08/04/14 by Eric Dobbertin
- clean up/fix whole-file upload handler
## [v0.0.26] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.26)
#### 07/04/14 by Eric Dobbertin
- add URL options to get temporary images while uploading and storing
## [v0.0.25] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.25)
#### 03/04/14 by Eric Dobbertin
- * allow `setBaseUrl` to be called either outside of Meteor.startup or inside * move encodeParams helper to FS.Utility
## [v0.0.24] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.24)
#### 03/04/14 by Eric Dobbertin
- properly remount URLs
- when uploading chunks, check the insert allow/deny since it's part of inserting
## [v0.0.23] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.23)
#### 31/03/14 by Eric Dobbertin
- use latest releases
## [v0.0.22] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.22)
#### 29/03/14 by Morten Henriksen
- remove underscore deps
## [v0.0.21] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.21)
#### 25/03/14 by Morten Henriksen
- add comments about shareId
## [v0.0.20] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.20)
#### 23/03/14 by Morten Henriksen
- Rollback to specific git dependency
- Try modified test script
- deps are already in collectionFS
## [v0.0.19] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.19)
#### 22/03/14 by Morten Henriksen
- try to fix travis test by using general package references
## [v0.0.18] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.18)
#### 22/03/14 by Morten Henriksen
- If the read stream fails we send an error to the client
## [v0.0.17] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.17)
#### 21/03/14 by Morten Henriksen
- remove smart lock
- commit smart.lock, trying to get tests to pass on travis
- some minor pkg adjustments; trying to get tests to pass on travis
## [v0.0.16] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.16)
#### 18/03/14 by Morten Henriksen
- Rollback to using the direct storage adapter - makes more sense when serving files
- shift to new http.methods streaming api
- move server side DDP access points to cfs-download-ddp pkg; update API docs
- fix typo...
- return something useful
- convert to streaming
- Add streaming WIP
- fix/adjust some tests; minor improvements to some handlers
- Add unmount and allow mount to use default selector function
- Refactor access point - wip
## [v0.0.15] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.15)
#### 05/03/14 by Morten Henriksen
- Refactor note, encode stuff should be prefixed into FS.Utility
- FS.File.url add user deps when auth is used
- fix url method
- query string fix
- move PUT access points for HTTP upload into this package; mount DELETE on /record/ as well as /files/; some fixes and improvements to handlers
## [v0.0.14] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.14)
#### 03/03/14 by Eric Dobbertin
- better error; return Buffer instead of converting to Uint8Array
## [v0.0.13] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.13)
#### 02/03/14 by Eric Dobbertin
- more tests, make everything work, add unpublish method
- Merge branch 'master' of https://github.com/zcfs/Meteor-cfs-access-point
## [v0.0.12] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.12)
#### 01/03/14 by Eric Dobbertin
- add travis-ci image
- rework URLs a bit, use http-publish package to publish FS.Collection listing, and add a test for this (!)
- add http-publish dependency
- del should be delete
## [v0.0.11] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.11)
#### 28/02/14 by Eric Dobbertin
- move some code to other packages; redo the HTTP GET/DEL methods
## [v0.0.10] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.10)
#### 28/02/14 by Eric Dobbertin
- move DDP upload methods to new cfs-upload-ddp package
## [v0.0.9] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.9)
#### 21/02/14 by Eric Dobbertin
- new URL syntax; use the store's file key instead of ID; also fix allow/deny checks with insecure
## [v0.0.8] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.8)
#### 20/02/14 by Eric Dobbertin
- support HTTP PUT of new file and fix PUT of existing file
## [v0.0.7] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.7)
#### 17/02/14 by Morten Henriksen
- add http-methods dependency
## [v0.0.6] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.6)
#### 16/02/14 by Morten Henriksen
## [v0.0.5] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.5)
#### 16/02/14 by Morten Henriksen
- a few fixes and improvements
- need to actually mount it
- attempt at switching to generic HTTP access point; also add support for chunked http downloads (range header)
## [v0.0.4] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.4)
#### 15/02/14 by Morten Henriksen
- Merge branch 'master' of https://github.com/zcfs/Meteor-cfs-access-point
- corrected typo
- added debugging
- call HTTP.methods on server only
- run client side, too, for side effects
- rework for additional abstraction; also DDP methods don't need to be per-collection so they no longer are
## [v0.0.3] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.3)
#### 13/02/14 by Morten Henriksen
## [v0.0.2] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.2)
#### 13/02/14 by Morten Henriksen
## [v0.0.1] (https://github.com/zcfs/Meteor-cfs-access-point/tree/v0.0.1)
#### 13/02/14 by Morten Henriksen
- init commit
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 [@raix](https://github.com/raix) and [@aldeed](https://github.com/aldeed), aka Morten N.O. Nørgaard Henriksen, mh@gi-software.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+32
View File
@@ -0,0 +1,32 @@
wekan-cfs-access-point [![Build Status](https://travis-ci.org/CollectionFS/Meteor-cfs-access-point.png?branch=master)](https://travis-ci.org/CollectionFS/Meteor-cfs-access-point)
=========================
This is a Meteor package used by
[CollectionFS](https://github.com/zcfs/Meteor-CollectionFS).
You don't need to manually add this package to your app. It is added when you
add the `wekan-cfs-standard-packages` package. You could potentially use your own access point
package instead.
## Define a URL for Collection Listing
To define a URL that accepts GET requests and returns a list of published
files in a FS.Collection:
```js
Images = new FS.Collection("images", {
stores: [myStore]
});
FS.HTTP.publish(Images, function () {
// `this` provides a context similar to Meteor.publish
return Images.find();
});
```
The URL will be '/cfs/record/images', where the `cfs` piece is configurable
using the `FS.HTTP.setBaseUrl` method.
## API Documentation
[Here](api.md)
@@ -0,0 +1,58 @@
FS.HTTP.setHeadersForGet = function setHeadersForGet() {
// Client Stub
};
FS.HTTP.now = function() {
return new Date(new Date() + FS.HTTP._serverTimeDiff);
};
// Returns the localstorage if its found and working
// TODO: check if this works in IE
// could use Meteor._localStorage - just needs a rewrite
FS.HTTP._storage = function() {
var storage,
fail,
uid;
try {
uid = "test";
(storage = window.localStorage).setItem(uid, uid);
fail = (storage.getItem(uid) !== uid);
storage.removeItem(uid);
if (fail) {
storage = false;
}
} catch(e) {
console.log("Error initializing storage for FS.HTTP");
console.log(e);
}
return storage;
};
// get our storage if found
FS.HTTP.storage = FS.HTTP._storage();
FS.HTTP._prefix = 'fsHTTP.';
FS.HTTP._serverTimeDiff = 0; // Time difference in ms
if (FS.HTTP.storage) {
// Initialize the FS.HTTP._serverTimeDiff
FS.HTTP._serverTimeDiff = (1*FS.HTTP.storage.getItem(FS.HTTP._prefix+'timeDiff')) || 0;
// At client startup we figure out the time difference between server and
// client time - this includes lag and timezone
Meteor.startup(function() {
// Call the server method an get server time
HTTP.get(rootUrlPathPrefix + '/cfs/servertime', function(error, result) {
if (!error) {
// Update our server time diff
var dateNew = new Date(+result.content);
FS.HTTP._serverTimeDiff = dateNew - new Date();// - lag or/and timezone
// Update the localstorage
FS.HTTP.storage.setItem(FS.HTTP._prefix + 'timeDiff', FS.HTTP._serverTimeDiff);
} else {
console.log(error.message);
}
}); // EO Server call
});
}
Loaded 100 of 367 files, more files were not shown because too many files have changed in this diff. Show more