summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.eslintrc.json3
-rw-r--r--.meteor/packages6
-rw-r--r--.meteor/versions8
-rw-r--r--CHANGELOG.md323
-rw-r--r--Dockerfile55
-rw-r--r--README.md56
-rw-r--r--SECURITY.md8
-rw-r--r--app.json2
-rw-r--r--client/components/activities/activities.js16
-rw-r--r--client/components/activities/comments.js11
-rw-r--r--client/components/boards/boardArchive.js3
-rw-r--r--client/components/cards/attachments.js9
-rw-r--r--client/components/cards/cardDate.js106
-rw-r--r--client/components/cards/cardDate.styl4
-rw-r--r--client/components/cards/cardDetails.jade107
-rw-r--r--client/components/cards/cardDetails.js2
-rw-r--r--client/components/cards/cardDetails.styl9
-rw-r--r--client/components/cards/cardTime.jade8
-rw-r--r--client/components/cards/cardTime.js19
-rw-r--r--client/components/cards/checklists.js4
-rw-r--r--client/components/cards/minicard.jade51
-rw-r--r--client/components/cards/minicard.js11
-rw-r--r--client/components/cards/minicard.styl12
-rw-r--r--client/components/cards/subtasks.js1
-rw-r--r--client/components/forms/forms.styl3
-rw-r--r--client/components/lists/list.js1
-rw-r--r--client/components/lists/list.styl11
-rw-r--r--client/components/lists/listBody.jade54
-rw-r--r--client/components/lists/listBody.js228
-rw-r--r--client/components/main/header.jade3
-rw-r--r--client/components/main/layouts.jade1
-rw-r--r--client/components/settings/invitationCode.js17
-rw-r--r--client/components/settings/settingBody.jade2
-rw-r--r--client/components/sidebar/sidebar.jade15
-rw-r--r--client/components/sidebar/sidebar.js15
-rw-r--r--client/components/users/userAvatar.jade2
-rw-r--r--client/components/users/userAvatar.js5
-rw-r--r--client/lib/filter.js156
-rw-r--r--client/lib/utils.js47
-rw-r--r--config/models.js4
-rw-r--r--config/router.js6
-rw-r--r--docker-compose.yml49
-rw-r--r--i18n/ar.i18n.json9
-rw-r--r--i18n/bg.i18n.json9
-rw-r--r--i18n/br.i18n.json9
-rw-r--r--i18n/ca.i18n.json9
-rw-r--r--i18n/cs.i18n.json9
-rw-r--r--i18n/de.i18n.json61
-rw-r--r--i18n/el.i18n.json9
-rw-r--r--i18n/en-GB.i18n.json9
-rw-r--r--i18n/en.i18n.json9
-rw-r--r--i18n/eo.i18n.json9
-rw-r--r--i18n/es-AR.i18n.json9
-rw-r--r--i18n/es.i18n.json65
-rw-r--r--i18n/eu.i18n.json9
-rw-r--r--i18n/fa.i18n.json79
-rw-r--r--i18n/fi.i18n.json9
-rw-r--r--i18n/fr.i18n.json61
-rw-r--r--i18n/gl.i18n.json9
-rw-r--r--i18n/he.i18n.json77
-rw-r--r--i18n/hu.i18n.json9
-rw-r--r--i18n/hy.i18n.json9
-rw-r--r--i18n/id.i18n.json9
-rw-r--r--i18n/ig.i18n.json9
-rw-r--r--i18n/it.i18n.json61
-rw-r--r--i18n/ja.i18n.json9
-rw-r--r--i18n/ka.i18n.json935
-rw-r--r--i18n/km.i18n.json9
-rw-r--r--i18n/ko.i18n.json9
-rw-r--r--i18n/lv.i18n.json9
-rw-r--r--i18n/mn.i18n.json9
-rw-r--r--i18n/nb.i18n.json9
-rw-r--r--i18n/nl.i18n.json9
-rw-r--r--i18n/pl.i18n.json89
-rw-r--r--i18n/pt-BR.i18n.json73
-rw-r--r--i18n/pt.i18n.json9
-rw-r--r--i18n/ro.i18n.json9
-rw-r--r--i18n/ru.i18n.json31
-rw-r--r--i18n/sr.i18n.json9
-rw-r--r--i18n/sv.i18n.json39
-rw-r--r--i18n/ta.i18n.json9
-rw-r--r--i18n/th.i18n.json9
-rw-r--r--i18n/tr.i18n.json23
-rw-r--r--i18n/uk.i18n.json9
-rw-r--r--i18n/vi.i18n.json9
-rw-r--r--i18n/zh-CN.i18n.json65
-rw-r--r--i18n/zh-TW.i18n.json9
-rw-r--r--models/activities.js3
-rw-r--r--models/boards.js77
-rw-r--r--models/cards.js546
-rw-r--r--models/export.js10
-rw-r--r--models/lists.js6
-rw-r--r--models/settings.js46
-rw-r--r--models/swimlanes.js6
-rw-r--r--models/trelloCreator.js2
-rw-r--r--models/users.js55
-rw-r--r--models/wekanCreator.js1
-rw-r--r--openshift/README.md19
-rw-r--r--openshift/wekan.yml374
-rw-r--r--package.json9
-rw-r--r--public/old-wekan-logo.pngbin0 -> 8433 bytes
-rw-r--r--public/wekan-logo.pngbin8433 -> 10342 bytes
-rw-r--r--sandstorm-pkgdef.capnp20
-rw-r--r--sandstorm.js3
-rw-r--r--scalingo.json4
-rw-r--r--server/authentication.js23
-rw-r--r--server/lib/utils.js10
-rw-r--r--server/migrations.js12
-rw-r--r--server/notifications/outgoing.js9
-rw-r--r--server/policy.js34
-rw-r--r--server/publications/boards.js12
-rw-r--r--snap-src/Caddyfile13
-rwxr-xr-xsnap-src/bin/caddy-control2
-rwxr-xr-xsnap-src/bin/config61
-rwxr-xr-xsnap-src/bin/wekan-help69
-rw-r--r--snapcraft.yaml30
116 files changed, 3695 insertions, 1161 deletions
diff --git a/.eslintrc.json b/.eslintrc.json
index 1adaa623..65d7602b 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -121,7 +121,8 @@
"allowIsBoardAdmin": true,
"allowIsBoardMember": true,
"allowIsBoardMemberByCard": true,
- "allowIsBoardMemberNonComment": true,
+ "allowIsBoardMemberCommentOnly": true,
+ "allowIsBoardMemberNoComments": true,
"Emoji": true,
"Checklists": true,
"Settings": true,
diff --git a/.meteor/packages b/.meteor/packages
index 2ea5e19f..d428111c 100644
--- a/.meteor/packages
+++ b/.meteor/packages
@@ -31,6 +31,7 @@ kenton:accounts-sandstorm
service-configuration@1.0.11
useraccounts:unstyled
useraccounts:flow-routing
+salleman:accounts-oidc
# Utilities
check@1.2.5
@@ -49,7 +50,6 @@ kadira:dochead
meteorhacks:picker
meteorhacks:subs-manager
mquandalle:autofocus
-mquandalle:moment
ongoworks:speakingurl
raix:handlebar-helpers
tap:i18n
@@ -81,8 +81,10 @@ staringatlights:fast-render
mixmax:smart-disconnect
accounts-password@1.5.0
cfs:gridfs
-browser-policy
eluck:accounts-lockout
rzymek:fullcalendar
momentjs:moment@2.22.2
atoy40:accounts-cas
+browser-policy-framing
+mquandalle:moment
+msavin:usercache
diff --git a/.meteor/versions b/.meteor/versions
index 9de09a74..f1f52d23 100644
--- a/.meteor/versions
+++ b/.meteor/versions
@@ -1,5 +1,6 @@
3stack:presence@1.1.2
accounts-base@1.4.0
+accounts-oauth@1.1.15
accounts-password@1.5.0
aldeed:collection2@2.10.0
aldeed:collection2-core@1.2.0
@@ -19,9 +20,7 @@ binary-heap@1.0.10
blaze@2.3.2
blaze-tools@1.0.10
boilerplate-generator@1.3.1
-browser-policy@1.1.0
browser-policy-common@1.0.11
-browser-policy-content@1.1.0
browser-policy-framing@1.1.0
caching-compiler@1.1.9
caching-html-compiler@1.1.2
@@ -119,8 +118,11 @@ mquandalle:jquery-ui-drag-drop-sort@0.2.0
mquandalle:moment@1.0.1
mquandalle:mousetrap-bindglobal@0.0.1
mquandalle:perfect-scrollbar@0.6.5_2
+msavin:usercache@1.0.0
npm-bcrypt@0.9.3
npm-mongo@2.2.33
+oauth@1.2.1
+oauth2@1.2.0
observe-sequence@1.0.16
ongoworks:speakingurl@1.1.0
ordered-dict@1.0.9
@@ -142,6 +144,8 @@ reload@1.1.11
retry@1.0.9
routepolicy@1.0.12
rzymek:fullcalendar@3.8.0
+salleman:accounts-oidc@1.0.9
+salleman:oidc@1.0.9
service-configuration@1.0.11
session@1.1.7
sha@1.0.9
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f8aa04fd..c5e5f325 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,330 @@
-# Upcoming Wekan release
+# v1.46 2018-09-15 Wekan release
-This release fixes the following mobile bugs:
+This release adds the following new features:
+
+- [Upgrade MongoDB to 3.2.21](https://github.com/wekan/wekan/commit/0cb3aee803781e4241c38a3e1e700703d063035a);
+- [Add source-map-support](https://github.com/wekan/wekan/issues/1889);
+- [Allow Announcement to be markdown](https://github.com/wekan/wekan/issues/1892).
+ Note: xet7 did not yet figure out how to keep announcement on one line
+ when markdown was added, so now Font Awesome icons are above and below.
+
+and fixes the following bugs:
+
+- [Turn of http/2 in Caddyfile](https://github.com/wekan/wekan/commit/f1ab46d5178b6fb7e9c4e43628eec358026d287a)
+ so that Firefox Inspect Console does not [show errors about wss](https://github.com/wekan/wekan/issues/934)
+ websocket config. Chrome web console supports http/2.
+ Note: If you are already using Caddy and have modified your Caddyfile, you need to edit your Caddyfile manually.
+- [Partially fix: Cannot move card from one swimline to the other if moving in the same list](https://github.com/wekan/wekan/issues/1887);
+- [Fix: Linking cards from empty board is possible and makes current board not load anymore](https://github.com/wekan/wekan/issues/1885).
+
+Thanks to GitHub users andresmanelli, HLFH and xet7 for their contributions.
+
+# v1.45 2018-09-09 Wekan release
+
+This release fixes the following bugs:
+
+- [Fix lint error](https://github.com/wekan/wekan/commit/45c0343f45b4cfc06d83cf357ffb50d6fca2f23b).
+
+Thanks to GitHub user xet7 for contributions.
+
+# v1.44 2018-09-09 Wekan release
+
+This release adds the following new features:
+
+- REST API: [Add startAt/dueAt/endAt etc](https://github.com/wekan/wekan/commit/1e0fdf8abc10130ea3c50b13ae97396223ce7fa9).
+ Docs at https://github.com/wekan/wekan/wiki/REST-API-Cards
+- [Fix cards export and add customFields export](https://github.com/wekan/wekan/pull/1886).
+
+Thanks to GitHub users ymeramees and xet7 for their contributions.
+
+# v1.43 2018-09-06 Wekan release
+
+This release fixes the following bugs:
+
+- [Fix "No Comments" permission on Wekan and Trello import](https://github.com/wekan/wekan/commit/0a001d505d81961e6bd6715d885fffee0adb702d).
+
+Thanks to GitHub user xet7 for contributions.
+
+# v1.42 2018-09-06 Wekan release
+
+This release adds the following new features:
+
+- REST API: [Create board options to be modifiable](https://github.com/wekan/wekan/commit/9cea76e4efaacaebcb2e9f0690dfeb4ef6d62527),
+ like permissions, public/private board - now private by default,
+ and board background color.
+ Docs at https://github.com/wekan/wekan/wiki/REST-API-Boards
+- [Add swimlaneId in activity. Create default swimlaneId in API](https://github.com/wekan/wekan/pull/1876).
+
+Thanks to GitHub users andresmanelli and xet7 for their contributions.
+
+# v1.41 2018-09-05 Wekan release
+
+This release tries to fix the following bugs:
+
+- [Try to fix Wekan Sandstorm API](https://github.com/wekan/wekan/issues/1279#issuecomment-418440401).
+
+Thanks to GitHub users ocdtrekkie and xet7 for their contributions.
+
+# v1.40 2018-09-04 Wekan release
+
+This release adds the following new features:
+
+- [Add permission "No comments"](https://github.com/wekan/wekan/commit/77efcf71376d3da6c19ad1a4910567263e83c0ca).
+ It is like normal user, but [does not show comments and activities](https://github.com/wekan/wekan/issues/1861).
+
+Thanks to GitHub user xet7 for contributions.
+
+# v1.39 2018-08-29 Wekan release
+
+This release fixes the following bugs:
+
+- [Only allow ifCanModify users to add dates on cards](https://github.com/wekan/wekan/pull/1867).
+
+Thanks to GitHub user rjevnikar for contributions.
+
+# v1.38 2018-08-29 Wekan release
+
+This release adds the following new features:
+
+- Add [msavin:userCache](https://github.com/msavin/userCache) to speedup Wekan.
+ See [meteor forums post](https://forums.meteor.com/t/introducing-a-new-approach-to-meteor-user-this-simple-trick-can-save-you-millions-of-database-requests/45336/7).
+
+and fixes the following bugs:
+
+- [Fix Delete Board](https://github.com/wekan/wekan/commit/534b20fedac9162d2d316bd74eff743d636f2b3d).
+
+Thanks to GitHub users msavin, rjevnikar and xet7 for their contributions.
+
+# v1.37 2018-08-28 Wekan release
+
+This release fixes the following bugs:
+
+- [Add Missing Index on cards.parentId since Swimlane integration
+ to speedup Wekan](https://github.com/wekan/wekan/issues/1863);
+- [Update OpenShift template to add Route and parameterize](https://github.com/wekan/wekan/pull/1865);
+- [Fix typos in Wekan snap help](https://github.com/wekan/wekan/commit/0c5fc6d7fd899a6bc67a446ab43e53290d8571e4).
+
+Thanks to GitHub users Clement87, InfoSec812 and xet7 for their contributions.
+
+# v1.36 2018-08-25 Wekan release
+
+This release adds the following new features:
+
+- [OAuth2 Login on Standalone Wekan](https://github.com/wekan/wekan/wiki/OAuth2). For example, Rocket.Chat can provide OAuth2 login to Wekan.
+ Also, if you have Rocket.Chat using LDAP/SAML/Google/etc for logging into Rocket.Chat, then same users can login to Wekan when
+ Rocket.Chat is providing OAuth2 login to Wekan.
+
+and fixes the following bugs:
+
+- [Move labels back to original place at minicard](https://github.com/wekan/wekan/issues/1842);
+- [Fix typos in security documentation](https://github.com/wekan/wekan/pull/1857).
+
+Thanks to GitHub users hever, salleman33, tlevine and xet7 for their contributions.
+
+# v1.35 2018-08-23 Wekan release
+
+This release adds the following new features:
+
+Add Caddy plugins:
+- [http.filter](https://caddyserver.com/docs/http.filter)
+ for changing Wekan UI on the fly, for example custom logo,
+ or changing to all different CSS file to have custom theme;
+- [http.ipfilter](https://caddyserver.com/docs/http.ipfilter)
+ to block requests by ip address;
+- [http.realip](https://caddyserver.com/docs/http.realip)
+ for showing real X-Forwarded-For IP to behind proxy;
+- Turn off Caddy telemetry.
+
+Add configuring webhooks:
+- [Make the attributes that the webhook sends configurable](https://github.com/wekan/wekan/pull/1852).
+
+Thanks to Caddy contributors, and Github users omarsy and xet7 for their contributions.
+
+# v1.34 2018-08-22 Wekan release
+
+This release add the following new features:
+
+- [Add Favicon for pinned tab on Safari browser](https://github.com/wekan/wekan/issues/1795).
+
+and fixes the following bugs:
+
+- [Restored SMTP settings at Admin Panel, and disabled showing password](https://github.com/wekan/wekan/issues/1790);
+- [Move color labels on minicard to bottom of minicard](https://github.com/wekan/wekan/issues/1842);
+- [Fix and improve linked cards](https://github.com/wekan/wekan/pull/1849);
+- [Allow Sandstorm to serve Wekan HTTP API](https://github.com/wekan/wekan/pull/1851);
+
+Thanks to GitHub users andresmanelli, ocdtrekkie, therampagerado, woodyart and xet7 for their contributions.
+
+# v1.33 2018-08-16 Wekan release
+
+This release fixes the following bugs:
+
+- [Change default value of label ids](https://github.com/wekan/wekan/pull/1837).
+
+Thanks to GitHub user omarsy for contributions.
+
+# v1.32 2018-08-16 Wekan release
+
+This release fixes the following bugs:
+
+- [Content Policy: Allow inline scripts, otherwise there is errors in browser/inspect/console](https://github.com/wekan/wekan/commit/807c6ce09e4b5d49049d343d73bbca24fa84d527);
+- [Use only framing policy, not all of content policy](https://github.com/wekan/wekan/commit/b3005f828dbf69bdf174d4bcd7654310fa9e0968);
+- [Set default matomo settings to disabled](https://github.com/wekan/wekan/commit/807c6ce09e4b5d49049d343d73bbca24fa84d527);
+- Fix [hidden](https://github.com/wekan/wekan/commit/be00465e67931f2a5655ed47f6e075ed1c589f54)
+ [system](https://github.com/wekan/wekan/commit/9fc3de8502919f9aeb18c9f8ea3b0678b66ce176) [messages](https://github.com/wekan/wekan/issues/1830);
+- Fix [Requested By](https://github.com/wekan/wekan/commit/e55d7e4f72a4b425c4aca5ba04a7be1fc642649b) and
+ [Assigned By](https://github.com/wekan/wekan/commit/5c33a8534186920be642be8e2ac17743a54f16db) [fields](https://github.com/wekan/wekan/issues/1830);
+- [Fix Date and Time Formats are only US in every language](https://github.com/wekan/wekan/commit/b3005f828dbf69bdf174d4bcd7654310fa9e0968).
+
+Thanks to GitHub users andresmanelli and xet7 for their contributions.
+
+# v1.31 2018-08-14 Wekan release
+
+This release fixes the following bugs:
+
+- [Export of Board does not work on Docker](https://github.com/wekan/wekan/issues/1820).
+
+Thanks to GitHub user xet7 for contributions.
+
+# v1.30 2018-08-14 Wekan release
+
+This release add the following new features:
+
+- [When Content Policy is enabled, allow one URL to have iframe that embeds Wekan](https://github.com/wekan/wekan/commit/b9929dc68297539a94d21950995e26e06745a263);
+- [Add option to turn off Content Policy](https://github.com/wekan/wekan/commit/b9929dc68297539a94d21950995e26e06745a263);
+- [Allow always in Wekan markdown `<img src="any-image-url-here">`](https://github.com/wekan/wekan/commit/b9929dc68297539a94d21950995e26e06745a263).
+
+and fixes the following bugs:
+
+- [Fix Import from Trello error 400](https://github.com/wekan/wekan/commit/2f557ae3a558c654cc6f3befff22f5ee4ea6c3d9).
+
+Thanks to GitHub user xet7 for contributions.
+
+# v1.29 2018-08-12 Wekan release
+
+This release fixes the following bugs:
+
+- [Revert Fix lint errors, that caused breakage](https://github.com/wekan/wekan/commit/b015b5b7240f5fb5a715843dce5d35907345eb4a).
+
+Thanks to GitHub user xet7 for contributions.
+
+# v1.28 2018-08-12 Wekan release
+
+This release fixes the following bugs:
+
+- [Fix lint errors](https://github.com/wekan/wekan/commit/f5515cb95fc93882e5e1098d6043267b9260b9d7).
+
+Thanks to GitHub user xet7 for contributions.
+
+# v1.27 2018-08-12 Wekan release
+
+This release add the following new features:
+
+- [Linked Cards and Linked Boards](https://github.com/wekan/wekan/pull/1592).
+
+Thanks to GitHub user andresmanelli for contributions.
+
+# v1.26 2018-08-09 Wekan release
+
+This release fixes the following bugs:
+
+- [Set WITH_API=true setting on Sandstorm, and so that export works](https://github.com/wekan/wekan/commit/a300b73d56750a1a5645767d375be60839314e84);
+- [Set Matomo blank settings on Sandstorm](https://github.com/wekan/wekan/commit/acd105e61b9dca5a78354047bbc23b0a01e71d8c).
+
+Thanks to GitHub user xet7 for contributions.
+
+# v1.25 2018-08-09 Wekan release
+
+This release fixes the following bugs:
+
+- [Fix showing only the cards of the current board in calendar view](https://github.com/wekan/wekan/pull/1822).
+
+Thanks to GitHub user Yanonix for contributions.
+
+# v1.24 2018-08-09 Wekan release
+
+This release add the following new features:
+
+- [Update node to v8.12.0 prerelease build](https://github.com/wekan/wekan/commit/04d7c47f4ca990311079be8dd6dc383448ee342f).
+
+and fixes the following bugs:
+
+- [Enable Wekan API by default, so that Export Board to JSON works](https://github.com/wekan/wekan/commit/b2eeff96977592deaeb23a8171fc3b13f8c6c5dc);
+- [Fix the flagging of dates](https://github.com/wekan/wekan/pull/1814);
+- [Use new WITH_API and Matomo env variables at Dockerfile](https://github.com/wekan/wekan/issues/1820);
+- For OpenShift compliance, [change](https://github.com/wekan/wekan/commit/53d545eeef7e796bd910f7cce666686ca05de544)
+ [run user](https://github.com/wekan/wekan/pull/1816)
+ and [Docker internal port to 8080](https://github.com/wekan/wekan/commit/95b21943ee7a9fa5a27efe5276307febc2fbad94).
+
+Thanks to GitHub users rjevnikar, tdemaret, xadagaras and xet7 for their contributions.
+
+# v1.23 2018-07-30 Wekan release
+
+This release tries to fix the following bugs:
+
+- Checking for [existing](https://github.com/wekan/wekan/commit/a48f560a85860451914dbaad8cae6ff5120a0c38)
+ [directories](https://github.com/wekan/wekan/commit/5bfb6c6411c928bfffa7ed6fe829f030e3ea57da) when
+ building snap etc, trying to [get snap to build somehow](https://github.com/wekan/wekan-snap/issues/58).
+ This is just a test, does it build this time correctly.
+
+Thanks to GitHub user xet7 for contributions.
+
+# v1.22 2018-07-30 Wekan release
+
+This release adds the following new features:
+
+- [Backup script now uses mongodump from snap to
+ do backups](https://github.com/wekan/wekan/wiki/Backup);
+- [Integration of Matomo](https://github.com/wekan/wekan/pull/1806);
+- [Enable/Disable API with env var](https://github.com/wekan/wekan/pull/1799).
+
+Thanks to GitHub user Akuket and xet7 for their contributions.
+
+# v1.21 2018-07-18 Wekan release
+
+This release adds the following new features:
+
+- [Add logo from Wekan website to login logo](https://github.com/wekan/wekan/commit/4eed23afe06d5fab8d45ba3decc7c1d3b85efbd8).
+
+and fixes the following bugs:
+
+- [Allow to resend invites](https://github.com/wekan/wekan/pull/1785).
+
+Thanks to GitHub users Akuket and xet7 for their contributions.
+
+# v1.20 2018-07-18 Wekan release
+
+This release fixes the following bugs:
+
+- [Remove SMTP settings from Admin Panel, because they are set in environment
+ variable settings like source/snap/docker already, and password was
+ exposed in plain text](https://github.com/wekan/wekan/issues/1783);
+- [Added info how to limit snap to root
+ user](https://github.com/wekan/wekan-snap/wiki/Limit-snap-to-root-user-only);
+- [Add scrolling to long cards](https://github.com/wekan/wekan/pull/1782).
+
+Thanks to GitHub users jnso, LyR33x and xet7 for their contributions.
+
+# v1.19 2018-07-16 Wekan release
+
+This release adds the following new features:
+
+- [Build from source on macOS](https://github.com/wekan/wekan/wiki/Mac);
+- [Wekan integration with OpenShift](https://github.com/wekan/wekan/pull/1765);
+- [Snap Caddy: set -agree flag for Let's Encrypt](https://github.com/wekan/wekan-snap/issues/54).
+
+and fixes the following mobile bugs:
- [Fix missing utility function](https://github.com/wekan/wekan/commit/5c774070617357c25c7bb35b43f4b122eb4b3e34);
- [Avoid default behavior](https://github.com/wekan/wekan/commit/9c204d9bbe4845bc3e352e839615dfb782a753f4);
- [Hotfix more sortable elements](https://github.com/wekan/wekan/commit/616dade81c25b10fc409aee1bcc9a93ddbfee81b);
- [Hotfix for mobile device](https://github.com/wekan/wekan/commit/43d86d7d5d3f3b34b0500f6d5d3afe7bd86b0060).
-Thanks to GitHub user Haocen for contributions.
+and fixes the following bugs:
+
+- [Fix invitation code](https://github.com/wekan/wekan/pull/1777).
+
+Thanks to GitHub users adyachok, Akuket, halunk3, Haocen and xet7 for their contributions.
# v1.18 2018-07-06 Wekan release
diff --git a/Dockerfile b/Dockerfile
index 6d68867d..eae85b1e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
FROM debian:buster-slim
-MAINTAINER wekan
+LABEL maintainer="wekan"
# Declare Arguments
ARG NODE_VERSION
@@ -10,19 +10,47 @@ ARG NPM_VERSION
ARG FIBERS_VERSION
ARG ARCHITECTURE
ARG SRC_PATH
+ARG WITH_API
+ARG MATOMO_ADDRESS
+ARG MATOMO_SITE_ID
+ARG MATOMO_DO_NOT_TRACK
+ARG MATOMO_WITH_USERNAME
+ARG BROWSER_POLICY_ENABLED
+ARG TRUSTED_URL
+ARG WEBHOOKS_ATTRIBUTES
+ARG OAUTH2_CLIENT_ID
+ARG OAUTH2_SECRET
+ARG OAUTH2_SERVER_URL
+ARG OAUTH2_AUTH_ENDPOINT
+ARG OAUTH2_USERINFO_ENDPOINT
+ARG OAUTH2_TOKEN_ENDPOINT
# Set the environment variables (defaults where required)
# DOES NOT WORK: paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303
# ENV BUILD_DEPS="paxctl"
-ENV BUILD_DEPS="apt-utils gnupg gosu wget curl bzip2 build-essential python git ca-certificates gcc-7"
-ENV NODE_VERSION ${NODE_VERSION:-v8.11.3}
-ENV METEOR_RELEASE ${METEOR_RELEASE:-1.6.0.1}
-ENV USE_EDGE ${USE_EDGE:-false}
-ENV METEOR_EDGE ${METEOR_EDGE:-1.5-beta.17}
-ENV NPM_VERSION ${NPM_VERSION:-latest}
-ENV FIBERS_VERSION ${FIBERS_VERSION:-2.0.0}
-ENV ARCHITECTURE ${ARCHITECTURE:-linux-x64}
-ENV SRC_PATH ${SRC_PATH:-./}
+ENV BUILD_DEPS="apt-utils gnupg gosu wget curl bzip2 build-essential python git ca-certificates gcc-7" \
+ NODE_VERSION=v8.12.0 \
+ METEOR_RELEASE=1.6.0.1 \
+ USE_EDGE=false \
+ METEOR_EDGE=1.5-beta.17 \
+ NPM_VERSION=latest \
+ FIBERS_VERSION=2.0.0 \
+ ARCHITECTURE=linux-x64 \
+ SRC_PATH=./ \
+ WITH_API=true \
+ MATOMO_ADDRESS="" \
+ MATOMO_SITE_ID="" \
+ MATOMO_DO_NOT_TRACK=true \
+ MATOMO_WITH_USERNAME=false \
+ BROWSER_POLICY_ENABLED=true \
+ TRUSTED_URL="" \
+ WEBHOOKS_ATTRIBUTES="" \
+ OAUTH2_CLIENT_ID="" \
+ OAUTH2_SECRET="" \
+ OAUTH2_SERVER_URL="" \
+ OAUTH2_AUTH_ENDPOINT="" \
+ OAUTH2_USERINFO_ENDPOINT="" \
+ OAUTH2_TOKEN_ENDPOINT=""
# Copy the app to the image
COPY ${SRC_PATH} /home/wekan/app
@@ -45,10 +73,10 @@ RUN \
# Also see beginning of wekan/server/authentication.js
# import Fiber from "fibers";
# Fiber.poolSize = 1e9;
- # Download node version 8.11.1 that has fix included, node binary copied from Sandstorm
+ # Download node version 8.12.0 prerelease that has fix included,
# Description at https://releases.wekan.team/node.txt
wget https://releases.wekan.team/node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz && \
- echo "40e7990489c13a1ed1173d8fe03af258c6ed964b92a4bd59a0927ac5931054aa node-v8.11.3-linux-x64.tar.gz" >> SHASUMS256.txt.asc && \
+ echo "1ed54adb8497ad8967075a0b5d03dd5d0a502be43d4a4d84e5af489c613d7795 node-v8.12.0-linux-x64.tar.gz" >> SHASUMS256.txt.asc && \
\
# Verify nodejs authenticity
grep ${NODE_VERSION}-${ARCHITECTURE}.tar.gz SHASUMS256.txt.asc | shasum -a 256 -c - && \
@@ -144,7 +172,8 @@ RUN \
rm -R /home/wekan/app_build && \
rm /home/wekan/install_meteor.sh
-ENV PORT=80
+ENV PORT=8080
EXPOSE $PORT
+USER wekan
CMD ["node", "/build/main.js"]
diff --git a/README.md b/README.md
index 8255e352..a57a144c 100644
--- a/README.md
+++ b/README.md
@@ -14,55 +14,41 @@
[![Code Climate](https://codeclimate.com/github/wekan/wekan/badges/gpa.svg "Code Climate")](https://codeclimate.com/github/wekan/wekan)
[![Project Dependencies](https://david-dm.org/wekan/wekan.svg "Project Dependencies")](https://david-dm.org/wekan/wekan)
[![Code analysis at Open Hub](https://img.shields.io/badge/code%20analysis-at%20Open%20Hub-brightgreen.svg "Code analysis at Open Hub")](https://www.openhub.net/p/wekan)
-[![Greenkeeper badge](https://badges.greenkeeper.io/wekan/wekan.svg)](https://greenkeeper.io/)
-Please read [FAQ](https://github.com/wekan/wekan/wiki/FAQ).
-Please don't feed the trolls and spammers that are mentioned in the FAQ :)
+**NOTE**:
+- Please read the [FAQ](https://github.com/wekan/wekan/wiki/FAQ) first
+- Please don't feed the trolls and spammers that are mentioned in the FAQ :)
Wekan is an completely [Open Source][open_source] and [Free software][free_software]
collaborative kanban board application with MIT license.
-Whether you’re maintaining a personal todo list, planning your holidays with
-some friends, or working in a team on your next revolutionary idea, Kanban
-boards are an unbeatable tool to keep your things organized. They give you a
-visual overview of the current state of your project, and make you productive by
-allowing you to focus on the few items that matter the most.
+Whether you’re maintaining a personal todo list, planning your holidays with some friends, or working in a team on your next revolutionary idea, Kanban boards are an unbeatable tool to keep your things organized. They give you a visual overview of the current state of your project, and make you productive by allowing you to focus on the few items that matter the most.
-Wekan has real-time user interface. Not all features are implemented.
-
-[Features][features]
-
-Wekan supports many [Platforms][platforms], and plan is to add more.
-
-[Integrations][integrations]
-
-[Team](https://github.com/wekan/wekan/wiki/Team)
+Since Wekan is a free software, you don’t have to trust us with your data and can
+install Wekan on your own computer or server. In fact we encourage you to do
+that by providing one-click installation on various platforms.
-You don’t have to trust us with your data and can install Wekan on your own
-computer or server. In fact we encourage you to do that by providing
-one-click installation on various platforms.
+- [Features][features]: Wekan has real-time user interface. Not all features are implemented, yet.
+- [Platforms][platforms]: Wekan supports many platforms and plan is to add more. This will be the first place to look if you want to **install** it, test out and learn more in depth.
+- [Integrations][integrations]: Current possible integrations and future plans.
+- [Team](https://github.com/wekan/wekan/wiki/Team): The people who spends their time and make wekan into what it is right now.
## Roadmap
[Roadmap](https://github.com/wekan/wekan/wiki/Roadmap)
-Upcoming Wekan App Development Platform will make possible
-many use cases. If you don't find your feature or integration in
-GitHub issues and [Features][features] or [Integrations][integrations]
-page at wiki, please add them.
+Upcoming Wekan App Development Platform will make possible many use cases. If you don't find your feature or integration in
+GitHub issues and [Features][features] or [Integrations][integrations] page at wiki, please add them.
-We are very welcoming to new developers and teams to submit new pull
-requests to devel branch to make this Wekan App Development Platform possible
-faster. Please see [Developer Documentation][dev_docs] to get started.
-We also welcome sponsors for features, although we don't have any yet.
-By working directly with Wekan you get the benefit of active maintenance
-and new features added by growing Wekan developer community.
+We are very welcoming to new developers and teams to submit new pull requests to devel branch to make this Wekan App Development Platform possible faster. Please see [Developer Documentation][dev_docs] to get started.
+
+We also welcome sponsors for features and bugfixes. By working directly with Wekan you get the benefit of active maintenance and new features added by growing Wekan developer community.
Actual work happens at [Wekan GitHub issues][wekan_issues].
-See [Development links on Wekan
-wiki](https://github.com/wekan/wekan/wiki#Development)
-bottom of the page for more info.
+See [Development links on Wekan wiki](https://github.com/wekan/wekan/wiki#Development) bottom of the page for more info.
+
+If you want to know what is going on exactly this moment, you can check out the [project page](https://github.com/wekan/wekan/projects/2).
## Demo
@@ -74,10 +60,6 @@ bottom of the page for more info.
[![Screenshot of Wekan][screenshot_wefork]][roadmap_wefork]
-Since Wekan is a free software, you don’t have to trust us with your data and can
-install Wekan on your own computer or server. In fact we encourage you to do
-that by providing one-click installation on various platforms.
-
## License
Wekan is released under the very permissive [MIT license](LICENSE), and made
diff --git a/SECURITY.md b/SECURITY.md
index 4e73c281..03f5e7da 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,4 +1,4 @@
-Security is very important to us. If discover any issue regarding security, please disclose
+Security is very important to us. If you discover any issue regarding security, please disclose
the information responsibly by sending an email to security (at) wekan.team and not by
creating a GitHub issue. We will respond swiftly to fix verifiable security issues.
@@ -28,8 +28,8 @@ added to the Wekan Hall of Fame.
## Which domains are in scope?
-No any public domains, because all those are donated to Wekan Open Source project,
-and we don't have any permissions to do security scans on those donated servers.
+No public domains, because all those are donated to Wekan Open Source project,
+and we don't have any permissions to do security scans on those donated servers
Please don't perform research that could impact other users. Secondly, please keep
the reports short and succinct. If we fail to understand the logics of your bug, we will tell you.
@@ -39,7 +39,7 @@ and scan it's vulnerabilities there.
## About Wekan versions
-There is only 2 versions of Wekan: Standalone Wekan, and Sandstorm Wekan.
+There are only 2 versions of Wekan: Standalone Wekan, and Sandstorm Wekan.
### Standalone Wekan Security
diff --git a/app.json b/app.json
index 6d3ce917..3921dec9 100644
--- a/app.json
+++ b/app.json
@@ -1,6 +1,6 @@
{
"name": "Wekan",
- "description": "The open-source Trello-like kanban",
+ "description": "The open-source kanban",
"repository": "https://github.com/wekan/wekan",
"logo": "https://raw.githubusercontent.com/wekan/wekan/master/meta/icons/wekan-150.png",
"keywords": ["productivity", "tool", "team", "kanban"],
diff --git a/client/components/activities/activities.js b/client/components/activities/activities.js
index f1414e44..6633a91a 100644
--- a/client/components/activities/activities.js
+++ b/client/components/activities/activities.js
@@ -8,16 +8,24 @@ BlazeComponent.extendComponent({
const sidebar = this.parentComponent(); // XXX for some reason not working
sidebar.callFirstWith(null, 'resetNextPeak');
this.autorun(() => {
- const mode = this.data().mode;
+ let mode = this.data().mode;
const capitalizedMode = Utils.capitalize(mode);
- const id = Session.get(`current${capitalizedMode}`);
+ let thisId, searchId;
+ if (mode === 'linkedcard' || mode === 'linkedboard') {
+ thisId = Session.get('currentCard');
+ searchId = Cards.findOne({_id: thisId}).linkedId;
+ mode = mode.replace('linked', '');
+ } else {
+ thisId = Session.get(`current${capitalizedMode}`);
+ searchId = thisId;
+ }
const limit = this.page.get() * activitiesPerPage;
const user = Meteor.user();
const hideSystem = user ? user.hasHiddenSystemMessages() : false;
- if (id === null)
+ if (searchId === null)
return;
- this.subscribe('activities', mode, id, limit, hideSystem, () => {
+ this.subscribe('activities', mode, searchId, limit, hideSystem, () => {
this.loadNextPageLocked = false;
// If the sibear peak hasn't increased, that mean that there are no more
diff --git a/client/components/activities/comments.js b/client/components/activities/comments.js
index 9b6aedd6..34b6402c 100644
--- a/client/components/activities/comments.js
+++ b/client/components/activities/comments.js
@@ -21,11 +21,18 @@ BlazeComponent.extendComponent({
'submit .js-new-comment-form'(evt) {
const input = this.getInput();
const text = input.val().trim();
+ const card = this.currentData();
+ let boardId = card.boardId;
+ let cardId = card._id;
+ if (card.isLinkedCard()) {
+ boardId = Cards.findOne(card.linkedId).boardId;
+ cardId = card.linkedId;
+ }
if (text) {
CardComments.insert({
text,
- boardId: this.currentData().boardId,
- cardId: this.currentData()._id,
+ boardId,
+ cardId,
});
resetCommentInput(input);
Tracker.flush();
diff --git a/client/components/boards/boardArchive.js b/client/components/boards/boardArchive.js
index dbebdd70..8f4d5434 100644
--- a/client/components/boards/boardArchive.js
+++ b/client/components/boards/boardArchive.js
@@ -37,8 +37,7 @@ BlazeComponent.extendComponent({
const currentBoard = Boards.findOne(Session.get('currentBoard'));
Boards.remove(currentBoard._id);
}
- const board = this.currentData();
- Boards.remove(board._id);
+ Boards.remove(this._id);
FlowRouter.go('home');
}),
}];
diff --git a/client/components/cards/attachments.js b/client/components/cards/attachments.js
index bc7d3979..5cac930d 100644
--- a/client/components/cards/attachments.js
+++ b/client/components/cards/attachments.js
@@ -57,8 +57,13 @@ Template.cardAttachmentsPopup.events({
const card = this;
FS.Utility.eachFile(evt, (f) => {
const file = new FS.File(f);
- file.boardId = card.boardId;
- file.cardId = card._id;
+ if (card.isLinkedCard()) {
+ file.boardId = Cards.findOne(card.linkedId).boardId;
+ file.cardId = card.linkedId;
+ } else {
+ file.boardId = card.boardId;
+ file.cardId = card._id;
+ }
file.userId = Meteor.userId();
const attachment = Attachments.insert(file);
diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js
index b0f2baa3..182705d5 100644
--- a/client/components/cards/cardDate.js
+++ b/client/components/cards/cardDate.js
@@ -96,7 +96,7 @@ Template.dateBadge.helpers({
(class extends DatePicker {
onCreated() {
super.onCreated();
- this.data().receivedAt && this.date.set(moment(this.data().receivedAt));
+ this.data().getReceived() && this.date.set(moment(this.data().getReceived()));
}
_storeDate(date) {
@@ -104,7 +104,7 @@ Template.dateBadge.helpers({
}
_deleteDate() {
- this.card.unsetReceived();
+ this.card.setReceived(null);
}
}).register('editCardReceivedDatePopup');
@@ -113,13 +113,13 @@ Template.dateBadge.helpers({
(class extends DatePicker {
onCreated() {
super.onCreated();
- this.data().startAt && this.date.set(moment(this.data().startAt));
+ this.data().getStart() && this.date.set(moment(this.data().getStart()));
}
onRendered() {
super.onRendered();
- if (moment.isDate(this.card.receivedAt)) {
- this.$('.js-datepicker').datepicker('setStartDate', this.card.receivedAt);
+ if (moment.isDate(this.card.getReceived())) {
+ this.$('.js-datepicker').datepicker('setStartDate', this.card.getReceived());
}
}
@@ -128,7 +128,7 @@ Template.dateBadge.helpers({
}
_deleteDate() {
- this.card.unsetStart();
+ this.card.setStart(null);
}
}).register('editCardStartDatePopup');
@@ -136,13 +136,13 @@ Template.dateBadge.helpers({
(class extends DatePicker {
onCreated() {
super.onCreated();
- this.data().dueAt && this.date.set(moment(this.data().dueAt));
+ this.data().getDue() && this.date.set(moment(this.data().getDue()));
}
onRendered() {
super.onRendered();
- if (moment.isDate(this.card.startAt)) {
- this.$('.js-datepicker').datepicker('setStartDate', this.card.startAt);
+ if (moment.isDate(this.card.getStart())) {
+ this.$('.js-datepicker').datepicker('setStartDate', this.card.getStart());
}
}
@@ -151,7 +151,7 @@ Template.dateBadge.helpers({
}
_deleteDate() {
- this.card.unsetDue();
+ this.card.setDue(null);
}
}).register('editCardDueDatePopup');
@@ -159,13 +159,13 @@ Template.dateBadge.helpers({
(class extends DatePicker {
onCreated() {
super.onCreated();
- this.data().endAt && this.date.set(moment(this.data().endAt));
+ this.data().getEnd() && this.date.set(moment(this.data().getEnd()));
}
onRendered() {
super.onRendered();
- if (moment.isDate(this.card.startAt)) {
- this.$('.js-datepicker').datepicker('setStartDate', this.card.startAt);
+ if (moment.isDate(this.card.getStart())) {
+ this.$('.js-datepicker').datepicker('setStartDate', this.card.getStart());
}
}
@@ -174,7 +174,7 @@ Template.dateBadge.helpers({
}
_deleteDate() {
- this.card.unsetEnd();
+ this.card.setEnd(null);
}
}).register('editCardEndDatePopup');
@@ -213,19 +213,23 @@ class CardReceivedDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
- self.date.set(moment(self.data().receivedAt));
+ self.date.set(moment(self.data().getReceived()));
});
}
classes() {
let classes = 'received-date ';
- const dueAt = this.data().dueAt;
- if (dueAt) {
- if (this.date.get().isBefore(this.now.get(), 'minute') &&
- this.now.get().isBefore(dueAt)) {
- classes += 'current';
- }
- }
+ const dueAt = this.data().getDue();
+ const endAt = this.data().getEnd();
+ const startAt = this.data().getStart();
+ const theDate = this.date.get();
+ // if dueAt, endAt and startAt exist & are > receivedAt, receivedAt doesn't need to be flagged
+ if (((startAt) && (theDate.isAfter(dueAt))) ||
+ ((endAt) && (theDate.isAfter(endAt))) ||
+ ((dueAt) && (theDate.isAfter(dueAt))))
+ classes += 'long-overdue';
+ else
+ classes += 'current';
return classes;
}
@@ -246,19 +250,24 @@ class CardStartDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
- self.date.set(moment(self.data().startAt));
+ self.date.set(moment(self.data().getStart()));
});
}
classes() {
let classes = 'start-date' + ' ';
- const dueAt = this.data().dueAt;
- if (dueAt) {
- if (this.date.get().isBefore(this.now.get(), 'minute') &&
- this.now.get().isBefore(dueAt)) {
- classes += 'current';
- }
- }
+ const dueAt = this.data().getDue();
+ const endAt = this.data().getEnd();
+ const theDate = this.date.get();
+ const now = this.now.get();
+ // 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
+ classes += 'current';
return classes;
}
@@ -279,24 +288,21 @@ class CardDueDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
- self.date.set(moment(self.data().dueAt));
+ self.date.set(moment(self.data().getDue()));
});
}
classes() {
let classes = 'due-date' + ' ';
-
- // if endAt exists & is < dueAt, dueAt doesn't need to be flagged
- const endAt = this.data().endAt;
+ const endAt = this.data().getEnd();
const theDate = this.date.get();
const now = this.now.get();
-
- if ((endAt !== 0) &&
- (endAt !== null) &&
- (endAt !== '') &&
- (endAt !== undefined) &&
- (theDate.isBefore(endAt)))
+ // if the due date is after the end date, green - done early
+ if ((endAt) && (theDate.isAfter(endAt)))
classes += 'current';
+ // if there is an end date, don't need to flag the due date
+ else if (endAt)
+ classes += '';
else if (now.diff(theDate, 'days') >= 2)
classes += 'long-overdue';
else if (now.diff(theDate, 'minute') >= 0)
@@ -323,22 +329,20 @@ class CardEndDate extends CardDate {
super.onCreated();
const self = this;
self.autorun(() => {
- self.date.set(moment(self.data().endAt));
+ self.date.set(moment(self.data().getEnd()));
});
}
classes() {
let classes = 'end-date' + ' ';
- const dueAt = this.data.dueAt;
- if (dueAt) {
- const diff = dueAt.diff(this.date.get(), 'days');
- if (diff >= 2)
- classes += 'long-overdue';
- else if (diff > 0)
- classes += 'due';
- else if (diff <= 0)
- classes += 'current';
- }
+ const dueAt = this.data().getDue();
+ const theDate = this.date.get();
+ if (theDate.diff(dueAt, 'days') >= 2)
+ classes += 'long-overdue';
+ else if (theDate.diff(dueAt, 'days') >= 0)
+ classes += 'due';
+ else if (theDate.diff(dueAt, 'days') >= -2)
+ classes += 'almost-due';
return classes;
}
diff --git a/client/components/cards/cardDate.styl b/client/components/cards/cardDate.styl
index 9775e82b..62cfdcd9 100644
--- a/client/components/cards/cardDate.styl
+++ b/client/components/cards/cardDate.styl
@@ -43,12 +43,12 @@
&.start-date
time
&::before
- content: "\f08b" // symbol: fa-sign-out
+ content: "\f251" // symbol: fa-hourglass-start
&.received-date
time
&::before
- content: "\f251" // symbol: fa-hourglass-start
+ content: "\f08b" // symbol: fa-sign-out
time
&::before
diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade
index aaad7c7c..33d6d3b7 100644
--- a/client/components/cards/cardDetails.jade
+++ b/client/components/cards/cardDetails.jade
@@ -10,7 +10,7 @@ template(name="cardDetails")
h2.card-details-title.js-card-title(
class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}")
+viewer
- = title
+ = getTitle
if isWatching
i.fa.fa-eye.card-details-watch
.card-details-path
@@ -19,43 +19,54 @@ template(name="cardDetails")
a.js-parent-card(href=linkForCard) {{title}}
// else
{{_ 'top-level-card'}}
+ if isLinkedCard
+ h3.linked-card-location
+ +viewer
+ | {{getBoardTitle}} > {{getTitle}}
- if archived
- p.warning {{_ 'card-archived'}}
+ if getArchived
+ if isLinkedBoard
+ p.warning {{_ 'board-archived'}}
+ else
+ p.warning {{_ 'card-archived'}}
.card-details-items
.card-details-item.card-details-item-received
h3.card-details-item-title {{_ 'card-received'}}
- if receivedAt
+ if getReceived
+cardReceivedDate
else
- a.js-received-date {{_ 'add'}}
+ if canModifyCard
+ a.js-received-date {{_ 'add'}}
.card-details-item.card-details-item-start
h3.card-details-item-title {{_ 'card-start'}}
- if startAt
+ if getStart
+cardStartDate
else
- a.js-start-date {{_ 'add'}}
+ if canModifyCard
+ a.js-start-date {{_ 'add'}}
.card-details-item.card-details-item-due
h3.card-details-item-title {{_ 'card-due'}}
- if dueAt
+ if getDue
+cardDueDate
else
- a.js-due-date {{_ 'add'}}
+ if canModifyCard
+ a.js-due-date {{_ 'add'}}
.card-details-item.card-details-item-end
h3.card-details-item-title {{_ 'card-end'}}
- if endAt
+ if getEnd
+cardEndDate
else
- a.js-end-date {{_ 'add'}}
+ if canModifyCard
+ a.js-end-date {{_ 'add'}}
.card-details-items
.card-details-item.card-details-item-members
h3.card-details-item-title {{_ 'members'}}
- each members
+ each getMembers
+userAvatar(userId=this cardId=../_id)
| {{! XXX Hack to hide syntaxic coloration /// }}
if canModifyCard
@@ -79,9 +90,9 @@ template(name="cardDetails")
+cardCustomField
.card-details-items
- if spentTime
+ if getSpentTime
.card-details-item.card-details-item-spent
- if isOvertime
+ if getIsOvertime
h3.card-details-item-title {{_ 'overtime-hours'}}
else
h3.card-details-item-title {{_ 'spent-time-hours'}}
@@ -92,15 +103,15 @@ template(name="cardDetails")
h3.card-details-item-title {{_ 'description'}}
+inlinedCardDescription(classNames="card-description js-card-description")
+editor(autofocus=true)
- | {{getUnsavedValue 'cardDescription' _id description}}
+ | {{getUnsavedValue 'cardDescription' _id getDescription}}
.edit-controls.clearfix
button.primary(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
else
a.js-open-inlined-form
- if description
+ if getDescription
+viewer
- = description
+ = getDescription
else
| {{_ 'edit'}}
if (hasUnsavedValue 'cardDescription' _id)
@@ -109,10 +120,10 @@ template(name="cardDetails")
a.js-open-inlined-form {{_ 'view-it'}}
= ' - '
a.js-close-inlined-form {{_ 'discard'}}
- else if description
+ else if getDescription
h3.card-details-item-title {{_ 'description'}}
+viewer
- = description
+ = getDescription
.card-details-items
.card-details-item.card-details-item-name
@@ -122,14 +133,14 @@ template(name="cardDetails")
+editCardRequesterForm
else
a.js-open-inlined-form
- if requestedBy
+ if getRequestedBy
+viewer
- = requestedBy
+ = getRequestedBy
else
| {{_ 'add'}}
- else if requestedBy
+ else if getRequestedBy
+viewer
- = requestedBy
+ = getRequestedBy
.card-details-item.card-details-item-name
h3.card-details-item-title {{_ 'assigned-by'}}
@@ -138,14 +149,14 @@ template(name="cardDetails")
+editCardAssignerForm
else
a.js-open-inlined-form
- if assignedBy
+ if getAssignedBy
+viewer
- = assignedBy
+ = getAssignedBy
else
| {{_ 'add'}}
- else if requestedBy
+ else if getRequestedBy
+viewer
- = assignedBy
+ = getAssignedBy
hr
+checklists(cardId = _id)
@@ -162,36 +173,44 @@ template(name="cardDetails")
+attachmentsGalery
hr
- .activity-title
- h3 {{ _ 'activity'}}
- if currentUser.isBoardMember
- .material-toggle-switch
- span.toggle-switch-title {{_ 'hide-system-messages'}}
- if hiddenSystemMessages
- input.toggle-switch(type="checkbox" id="toggleButton" checked="checked")
- else
- input.toggle-switch(type="checkbox" id="toggleButton")
- label.toggle-label(for="toggleButton")
+ unless currentUser.isNoComments
+ .activity-title
+ h3 {{ _ 'activity'}}
+ if currentUser.isBoardMember
+ .material-toggle-switch
+ span.toggle-switch-title {{_ 'hide-system-messages'}}
+ if hiddenSystemMessages
+ input.toggle-switch(type="checkbox" id="toggleButton" checked="checked")
+ else
+ input.toggle-switch(type="checkbox" id="toggleButton")
+ label.toggle-label(for="toggleButton")
if currentUser.isBoardMember
- +commentForm
- if isLoaded.get
- +activities(card=this mode="card")
+ unless currentUser.isNoComments
+ +commentForm
+ unless currentUser.isNoComments
+ if isLoaded.get
+ if isLinkedCard
+ +activities(card=this mode="linkedcard")
+ else if isLinkedBoard
+ +activities(card=this mode="linkedboard")
+ else
+ +activities(card=this mode="card")
template(name="editCardTitleForm")
textarea.js-edit-card-title(rows='1' autofocus)
- = title
+ = getTitle
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-title-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
template(name="editCardRequesterForm")
- input.js-edit-card-requester(type='text' autofocus value=requestedBy)
+ input.js-edit-card-requester(type='text' autofocus value=getRequestedBy)
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-requester-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
template(name="editCardAssignerForm")
- input.js-edit-card-assigner(type='text' autofocus value=assignedBy)
+ input.js-edit-card-assigner(type='text' autofocus value=getAssignedBy)
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-assigner-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
@@ -230,7 +249,7 @@ template(name="moveCardPopup")
template(name="copyCardPopup")
label(for='copy-card-title') {{_ 'title'}}:
textarea#copy-card-title.minicard-composer-textarea.js-card-title(autofocus)
- = title
+ = getTitle
+boardsAndLists
template(name="copyChecklistToManyCardsPopup")
diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js
index b41bfc17..2cd399c1 100644
--- a/client/components/cards/cardDetails.js
+++ b/client/components/cards/cardDetails.js
@@ -274,7 +274,7 @@ BlazeComponent.extendComponent({
close(isReset = false) {
if (this.isOpen.get() && !isReset) {
const draft = this.getValue().trim();
- if (draft !== Cards.findOne(Session.get('currentCard')).description) {
+ if (draft !== Cards.findOne(Session.get('currentCard')).getDescription()) {
UnsavedEdits.set(this._getUnsavedEditKey(), this.getValue());
}
}
diff --git a/client/components/cards/cardDetails.styl b/client/components/cards/cardDetails.styl
index 11660593..1e290305 100644
--- a/client/components/cards/cardDetails.styl
+++ b/client/components/cards/cardDetails.styl
@@ -5,7 +5,8 @@
flex-shrink: 0
flex-basis: 470px
will-change: flex-basis
- overflow: hidden
+ overflow-y: scroll
+ overflow-x: hidden
background: darken(white, 3%)
border-radius: bottom 3px
z-index: 20 !important
@@ -46,6 +47,12 @@
margin: 7px 0 0
padding: 0
+ .linked-card-location
+ font-style: italic
+ font-size: 1em
+ margin-bottom: 0
+ & p
+ margin-bottom: 0
form.inlined-form
margin-top: 5px
diff --git a/client/components/cards/cardTime.jade b/client/components/cards/cardTime.jade
index dcfc92f0..8af8c414 100644
--- a/client/components/cards/cardTime.jade
+++ b/client/components/cards/cardTime.jade
@@ -3,10 +3,10 @@ template(name="editCardSpentTime")
form.edit-time
.fields
label(for="time") {{_ 'time'}}
- input.js-time-field#time(type="number" step="0.01" name="time" value="{{card.spentTime}}" placeholder=timeFormat autofocus)
+ input.js-time-field#time(type="number" step="0.01" name="time" value="{{card.getSpentTime}}" placeholder=timeFormat autofocus)
label(for="overtime") {{_ 'overtime'}}
a.js-toggle-overtime
- .materialCheckBox#overtime(class="{{#if card.isOvertime}}is-checked{{/if}}" name="overtime")
+ .materialCheckBox#overtime(class="{{#if getIsOvertime}}is-checked{{/if}}" name="overtime")
if error.get
.warning {{_ error.get}}
@@ -15,8 +15,8 @@ template(name="editCardSpentTime")
template(name="timeBadge")
if canModifyCard
- a.js-edit-time.card-time(title="{{showTitle}}" class="{{#if isOvertime}}card-label-red{{else}}card-label-green{{/if}}")
+ a.js-edit-time.card-time(title="{{showTitle}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}")
| {{showTime}}
else
- a.card-time(title="{{showTitle}}" class="{{#if isOvertime}}card-label-red{{else}}card-label-green{{/if}}")
+ a.card-time(title="{{showTitle}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}")
| {{showTime}}
diff --git a/client/components/cards/cardTime.js b/client/components/cards/cardTime.js
index eadcc88e..80b7fc84 100644
--- a/client/components/cards/cardTime.js
+++ b/client/components/cards/cardTime.js
@@ -7,17 +7,17 @@ BlazeComponent.extendComponent({
this.card = this.data();
},
toggleOvertime() {
- this.card.isOvertime = !this.card.isOvertime;
+ this.card.setIsOvertime(!this.card.getIsOvertime());
$('#overtime .materialCheckBox').toggleClass('is-checked');
$('#overtime').toggleClass('is-checked');
},
storeTime(spentTime, isOvertime) {
this.card.setSpentTime(spentTime);
- this.card.setOvertime(isOvertime);
+ this.card.setIsOvertime(isOvertime);
},
deleteTime() {
- this.card.unsetSpentTime();
+ this.card.setSpentTime(null);
},
events() {
return [{
@@ -26,7 +26,7 @@ BlazeComponent.extendComponent({
evt.preventDefault();
const spentTime = parseFloat(evt.target.time.value);
- const isOvertime = this.card.isOvertime;
+ const isOvertime = this.card.getIsOvertime();
if (spentTime >= 0) {
this.storeTime(spentTime, isOvertime);
@@ -55,17 +55,14 @@ BlazeComponent.extendComponent({
self.time = ReactiveVar();
},
showTitle() {
- if (this.data().isOvertime) {
- return `${TAPi18n.__('overtime')} ${this.data().spentTime} ${TAPi18n.__('hours')}`;
+ if (this.data().getIsOvertime()) {
+ return `${TAPi18n.__('overtime')} ${this.data().getSpentTime()} ${TAPi18n.__('hours')}`;
} else {
- return `${TAPi18n.__('card-spent')} ${this.data().spentTime} ${TAPi18n.__('hours')}`;
+ return `${TAPi18n.__('card-spent')} ${this.data().getSpentTime()} ${TAPi18n.__('hours')}`;
}
},
showTime() {
- return this.data().spentTime;
- },
- isOvertime() {
- return this.data().isOvertime;
+ return this.data().getSpentTime();
},
events() {
return [{
diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js
index e014abba..5d789351 100644
--- a/client/components/cards/checklists.js
+++ b/client/components/cards/checklists.js
@@ -74,8 +74,10 @@ BlazeComponent.extendComponent({
event.preventDefault();
const textarea = this.find('textarea.js-add-checklist-item');
const title = textarea.value.trim();
- const cardId = this.currentData().cardId;
+ let cardId = this.currentData().cardId;
const card = Cards.findOne(cardId);
+ if (card.isLinked())
+ cardId = card.linkedId;
if (title) {
Checklists.insert({
diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade
index 3f7e0940..5c609802 100644
--- a/client/components/cards/minicard.jade
+++ b/client/components/cards/minicard.jade
@@ -1,5 +1,7 @@
template(name="minicard")
- .minicard
+ .minicard(
+ class="{{#if isLinkedCard}}linked-card{{/if}}"
+ class="{{#if isLinkedBoard}}linked-board{{/if}}")
if cover
.minicard-cover(style="background-image: url('{{cover.url}}');")
if labels
@@ -13,8 +15,16 @@ template(name="minicard")
if $eq 'prefix-with-parent' currentBoard.presentParentTask
.parent-prefix
| {{ parentCardName }}
+ if isLinkedBoard
+ a.js-linked-link
+ span.linked-icon.fa.fa-folder
+ else if isLinkedCard
+ a.js-linked-link
+ span.linked-icon.fa.fa-id-card
+ if getArchived
+ span.linked-icon.linked-archived.fa.fa-archive
+viewer
- | {{ title }}
+ = getTitle
if $eq 'subtext-with-full-path' currentBoard.presentParentTask
.parent-subtext
| {{ parentString ' > ' }}
@@ -23,23 +33,19 @@ template(name="minicard")
| {{ parentCardName }}
.dates
- if receivedAt
- unless startAt
- unless dueAt
- unless endAt
+ if getReceived
+ unless getStart
+ unless getDue
+ unless getEnd
.date
+minicardReceivedDate
- if startAt
+ if getStart
.date
+minicardStartDate
- if dueAt
- unless endAt
- .date
- +minicardDueDate
- if endAt
+ if getDue
.date
- +minicardEndDate
- if spentTime
+ +minicardDueDate
+ if getSpentTime
.date
+cardSpentTime
@@ -53,18 +59,19 @@ template(name="minicard")
+viewer
= trueValue
- if members
+ if getMembers
.minicard-members.js-minicard-members
- each members
+ each getMembers
+userAvatar(userId=this)
.badges
- if comments.count
- .badge(title="{{_ 'card-comments-title' comments.count }}")
- span.badge-icon.fa.fa-comment-o.badge-comment
- span.badge-text= comments.count
- if description
- .badge.badge-state-image-only(title=description)
+ unless currentUser.isNoComments
+ if comments.count
+ .badge(title="{{_ 'card-comments-title' comments.count }}")
+ span.badge-icon.fa.fa-comment-o.badge-comment
+ span.badge-text= comments.count
+ if getDescription
+ .badge.badge-state-image-only(title=getDescription)
span.badge-icon.fa.fa-align-left
if attachments.count
.badge
diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js
index a98b5730..da7f9e01 100644
--- a/client/components/cards/minicard.js
+++ b/client/components/cards/minicard.js
@@ -6,4 +6,15 @@ BlazeComponent.extendComponent({
template() {
return 'minicard';
},
+
+ events() {
+ return [{
+ 'click .js-linked-link' () {
+ if (this.data().isLinkedCard())
+ Utils.goCardId(this.data().linkedId);
+ else if (this.data().isLinkedBoard())
+ Utils.goBoardId(this.data().linkedId);
+ },
+ }];
+ },
}).register('minicard');
diff --git a/client/components/cards/minicard.styl b/client/components/cards/minicard.styl
index 5624787c..8fec7238 100644
--- a/client/components/cards/minicard.styl
+++ b/client/components/cards/minicard.styl
@@ -44,6 +44,16 @@
transition: transform 0.2s,
border-radius 0.2s
+ &.linked-board
+ &.linked-card
+ .linked-icon
+ display: inline-block
+ margin-right: 11px
+ vertical-align: baseline
+ font-size: 0.9em
+ .linked-archived
+ color: #937760
+
.is-selected &
transform: translateX(11px)
border-bottom-right-radius: 0
@@ -87,6 +97,8 @@
.minicard-title
p:last-child
margin-bottom: 0
+ .viewer
+ display: inline-block
.dates
display: flex;
flex-direction: row;
diff --git a/client/components/cards/subtasks.js b/client/components/cards/subtasks.js
index 9c6f265e..1651d449 100644
--- a/client/components/cards/subtasks.js
+++ b/client/components/cards/subtasks.js
@@ -29,6 +29,7 @@ BlazeComponent.extendComponent({
boardId: targetBoard._id,
sort: sortIndex,
swimlaneId,
+ type: 'cardType-card',
});
// In case the filter is active we need to add the newly inserted card in
diff --git a/client/components/forms/forms.styl b/client/components/forms/forms.styl
index 4fff1e02..892a6e74 100644
--- a/client/components/forms/forms.styl
+++ b/client/components/forms/forms.styl
@@ -226,9 +226,12 @@ textarea
.edit-controls,
.add-controls
+ display: flex
+ align-items: baseline
margin-top: 0
button[type=submit]
+ input[type=button]
float: left
height: 32px
margin-top: -2px
diff --git a/client/components/lists/list.js b/client/components/lists/list.js
index 267af31c..00908faa 100644
--- a/client/components/lists/list.js
+++ b/client/components/lists/list.js
@@ -47,6 +47,7 @@ BlazeComponent.extendComponent({
items: itemsSelector,
placeholder: 'minicard-wrapper placeholder',
start(evt, ui) {
+ ui.helper.css('z-index', 1000);
ui.placeholder.height(ui.helper.height());
EscapeActions.executeUpTo('popup-close');
boardComponent.setIsDragging(true);
diff --git a/client/components/lists/list.styl b/client/components/lists/list.styl
index fa32ff6d..72cb19f4 100644
--- a/client/components/lists/list.styl
+++ b/client/components/lists/list.styl
@@ -187,3 +187,14 @@
padding: 7px
top: -@padding
right: 17px
+
+.link-board-wrapper
+ display: flex
+ align-items: baseline
+
+ .js-link-board
+ margin-left: 15px
+
+.search-card-results
+ max-height: 250px
+ overflow: hidden
diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade
index 32c6b278..f2b3e941 100644
--- a/client/components/lists/listBody.jade
+++ b/client/components/lists/listBody.jade
@@ -34,8 +34,60 @@ template(name="addCardForm")
.add-controls.clearfix
button.primary.confirm(type="submit") {{_ 'add'}}
- a.fa.fa-times-thin.js-close-inlined-form
+ span.quiet
+ | {{_ 'or'}}
+ a.js-link {{_ 'link'}}
+ span.quiet
+ | &nbsp;
+ | /
+ a.js-search {{_ 'search'}}
template(name="autocompleteLabelLine")
.minicard-label(class="card-label-{{colorName}}" title=labelName)
span(class="{{#if hasNoName}}quiet{{/if}}")= labelName
+
+template(name="linkCardPopup")
+ label {{_ 'boards'}}:
+ .link-board-wrapper
+ select.js-select-boards
+ each boards
+ if $eq _id currentBoard._id
+ option(value="{{_id}}" selected) {{_ 'current'}}
+ else
+ option(value="{{_id}}") {{title}}
+ input.primary.confirm.js-link-board(type="button" value="{{_ 'link'}}")
+
+ label {{_ 'swimlanes'}}:
+ select.js-select-swimlanes
+ each swimlanes
+ option(value="{{_id}}") {{title}}
+
+ label {{_ 'lists'}}:
+ select.js-select-lists
+ each lists
+ option(value="{{_id}}") {{title}}
+
+ label {{_ 'cards'}}:
+ select.js-select-cards
+ each cards
+ option(value="{{getId}}") {{getTitle}}
+
+ .edit-controls.clearfix
+ input.primary.confirm.js-done(type="button" value="{{_ 'link'}}")
+
+template(name="searchCardPopup")
+ label {{_ 'boards'}}:
+ .link-board-wrapper
+ select.js-select-boards
+ each boards
+ if $eq _id currentBoard._id
+ option(value="{{_id}}" selected) {{_ 'current'}}
+ else
+ option(value="{{_id}}") {{title}}
+ form.js-search-term-form
+ input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus)
+ .list-body.js-perfect-scrollbar.search-card-results
+ .minicards.clearfix.js-minicards
+ each results
+ a.minicard-wrapper.js-minicard
+ +minicard(this)
diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js
index b93b7e67..ce8396b9 100644
--- a/client/components/lists/listBody.js
+++ b/client/components/lists/listBody.js
@@ -1,3 +1,5 @@
+const subManager = new SubsManager();
+
BlazeComponent.extendComponent({
mixins() {
return [Mixins.PerfectScrollbar];
@@ -55,6 +57,7 @@ BlazeComponent.extendComponent({
boardId: boardId._id,
sort: sortIndex,
swimlaneId,
+ type: 'cardType-card',
});
// In case the filter is active we need to add the newly inserted card in
// the list of exceptions -- cards that are not filtered. Otherwise the
@@ -199,6 +202,8 @@ BlazeComponent.extendComponent({
events() {
return [{
keydown: this.pressKey,
+ 'click .js-link': Popup.open('linkCard'),
+ 'click .js-search': Popup.open('searchCard'),
}];
},
@@ -270,3 +275,226 @@ BlazeComponent.extendComponent({
});
},
}).register('addCardForm');
+
+BlazeComponent.extendComponent({
+ onCreated() {
+ // Prefetch first non-current board id
+ const boardId = Boards.findOne({
+ archived: false,
+ 'members.userId': Meteor.userId(),
+ _id: {$ne: Session.get('currentBoard')},
+ }, {
+ sort: ['title'],
+ })._id;
+ // Subscribe to this board
+ subManager.subscribe('board', boardId);
+ this.selectedBoardId = new ReactiveVar(boardId);
+ this.selectedSwimlaneId = new ReactiveVar('');
+ this.selectedListId = new ReactiveVar('');
+
+ this.boardId = Session.get('currentBoard');
+ // In order to get current board info
+ subManager.subscribe('board', this.boardId);
+ this.board = Boards.findOne(this.boardId);
+ // List where to insert card
+ const list = $(Popup._getTopStack().openerElement).closest('.js-list');
+ this.listId = Blaze.getData(list[0])._id;
+ // Swimlane where to insert card
+ const swimlane = $(Popup._getTopStack().openerElement).closest('.js-swimlane');
+ this.swimlaneId = '';
+ const boardView = Meteor.user().profile.boardView;
+ if (boardView === 'board-view-swimlanes')
+ this.swimlaneId = Blaze.getData(swimlane[0])._id;
+ else if (boardView === 'board-view-lists')
+ this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
+ },
+
+ boards() {
+ const boards = Boards.find({
+ archived: false,
+ 'members.userId': Meteor.userId(),
+ _id: {$ne: Session.get('currentBoard')},
+ }, {
+ sort: ['title'],
+ });
+ return boards;
+ },
+
+ swimlanes() {
+ if (!this.selectedBoardId) {
+ return [];
+ }
+ const swimlanes = Swimlanes.find({boardId: this.selectedBoardId.get()});
+ if (swimlanes.count())
+ this.selectedSwimlaneId.set(swimlanes.fetch()[0]._id);
+ return swimlanes;
+ },
+
+ lists() {
+ if (!this.selectedBoardId) {
+ return [];
+ }
+ const lists = Lists.find({boardId: this.selectedBoardId.get()});
+ if (lists.count())
+ this.selectedListId.set(lists.fetch()[0]._id);
+ return lists;
+ },
+
+ cards() {
+ if (!this.board) {
+ return [];
+ }
+ const ownCardsIds = this.board.cards().map((card) => { return card.linkedId || card._id; });
+ return Cards.find({
+ boardId: this.selectedBoardId.get(),
+ swimlaneId: this.selectedSwimlaneId.get(),
+ listId: this.selectedListId.get(),
+ archived: false,
+ linkedId: {$nin: ownCardsIds},
+ _id: {$nin: ownCardsIds},
+ });
+ },
+
+ events() {
+ return [{
+ 'change .js-select-boards'(evt) {
+ subManager.subscribe('board', $(evt.currentTarget).val());
+ this.selectedBoardId.set($(evt.currentTarget).val());
+ },
+ 'change .js-select-swimlanes'(evt) {
+ this.selectedSwimlaneId.set($(evt.currentTarget).val());
+ },
+ 'change .js-select-lists'(evt) {
+ this.selectedListId.set($(evt.currentTarget).val());
+ },
+ 'click .js-done' (evt) {
+ // LINK CARD
+ evt.stopPropagation();
+ evt.preventDefault();
+ const linkedId = $('.js-select-cards option:selected').val();
+ if (!linkedId) {
+ Popup.close();
+ return;
+ }
+ const _id = Cards.insert({
+ title: $('.js-select-cards option:selected').text(), //dummy
+ listId: this.listId,
+ swimlaneId: this.swimlaneId,
+ boardId: this.boardId,
+ sort: Lists.findOne(this.listId).cards().count(),
+ type: 'cardType-linkedCard',
+ linkedId,
+ });
+ Filter.addException(_id);
+ Popup.close();
+ },
+ 'click .js-link-board' (evt) {
+ //LINK BOARD
+ evt.stopPropagation();
+ evt.preventDefault();
+ const impBoardId = $('.js-select-boards option:selected').val();
+ if (!impBoardId || Cards.findOne({linkedId: impBoardId, archived: false})) {
+ Popup.close();
+ return;
+ }
+ const _id = Cards.insert({
+ title: $('.js-select-boards option:selected').text(), //dummy
+ listId: this.listId,
+ swimlaneId: this.swimlaneId,
+ boardId: this.boardId,
+ sort: Lists.findOne(this.listId).cards().count(),
+ type: 'cardType-linkedBoard',
+ linkedId: impBoardId,
+ });
+ Filter.addException(_id);
+ Popup.close();
+ },
+ }];
+ },
+}).register('linkCardPopup');
+
+BlazeComponent.extendComponent({
+ mixins() {
+ return [Mixins.PerfectScrollbar];
+ },
+
+ onCreated() {
+ // Prefetch first non-current board id
+ let board = Boards.findOne({
+ archived: false,
+ 'members.userId': Meteor.userId(),
+ _id: {$ne: Session.get('currentBoard')},
+ });
+ if (!board) {
+ Popup.close();
+ return;
+ }
+ const boardId = board._id;
+ // Subscribe to this board
+ subManager.subscribe('board', boardId);
+ this.selectedBoardId = new ReactiveVar(boardId);
+
+ this.boardId = Session.get('currentBoard');
+ // In order to get current board info
+ subManager.subscribe('board', this.boardId);
+ board = Boards.findOne(this.boardId);
+ // List where to insert card
+ const list = $(Popup._getTopStack().openerElement).closest('.js-list');
+ this.listId = Blaze.getData(list[0])._id;
+ // Swimlane where to insert card
+ const swimlane = $(Popup._getTopStack().openerElement).closest('.js-swimlane');
+ this.swimlaneId = '';
+ if (board.view === 'board-view-swimlanes')
+ this.swimlaneId = Blaze.getData(swimlane[0])._id;
+ else
+ this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
+ this.term = new ReactiveVar('');
+ },
+
+ boards() {
+ const boards = Boards.find({
+ archived: false,
+ 'members.userId': Meteor.userId(),
+ _id: {$ne: Session.get('currentBoard')},
+ }, {
+ sort: ['title'],
+ });
+ return boards;
+ },
+
+ results() {
+ if (!this.selectedBoardId) {
+ return [];
+ }
+ const board = Boards.findOne(this.selectedBoardId.get());
+ return board.searchCards(this.term.get(), false);
+ },
+
+ events() {
+ return [{
+ 'change .js-select-boards'(evt) {
+ subManager.subscribe('board', $(evt.currentTarget).val());
+ this.selectedBoardId.set($(evt.currentTarget).val());
+ },
+ 'submit .js-search-term-form'(evt) {
+ evt.preventDefault();
+ this.term.set(evt.target.searchTerm.value);
+ },
+ 'click .js-minicard'(evt) {
+ // LINK CARD
+ const card = Blaze.getData(evt.currentTarget);
+ const _id = Cards.insert({
+ title: card.title, //dummy
+ listId: this.listId,
+ swimlaneId: this.swimlaneId,
+ boardId: this.boardId,
+ sort: Lists.findOne(this.listId).cards().count(),
+ type: 'cardType-linkedCard',
+ linkedId: card.linkedId || card._id,
+ });
+ Filter.addException(_id);
+ Popup.close();
+ },
+ }];
+ },
+}).register('searchCardPopup');
diff --git a/client/components/main/header.jade b/client/components/main/header.jade
index dd071b3e..2751c0cc 100644
--- a/client/components/main/header.jade
+++ b/client/components/main/header.jade
@@ -66,7 +66,8 @@ template(name="header")
.announcement
p
i.fa.fa-bullhorn
- | #{announcement}
+ +viewer
+ | #{announcement}
i.fa.fa-times-circle.js-close-announcement
template(name="offlineWarning")
diff --git a/client/components/main/layouts.jade b/client/components/main/layouts.jade
index ff2d8d0a..ac7da3af 100644
--- a/client/components/main/layouts.jade
+++ b/client/components/main/layouts.jade
@@ -9,6 +9,7 @@ head
packages.
link(rel="shortcut icon" href="/wekan-favicon.png")
link(rel="apple-touch-icon" href="/wekan-favicon.png")
+ link(rel="mask-icon" href="/wekan-150.svg")
link(rel="manifest" href="/wekan-manifest.json")
template(name="userFormsLayout")
diff --git a/client/components/settings/invitationCode.js b/client/components/settings/invitationCode.js
index a403d8ab..fa355179 100644
--- a/client/components/settings/invitationCode.js
+++ b/client/components/settings/invitationCode.js
@@ -1,6 +1,13 @@
-Template.invitationCode.onRendered(() => {
- const setting = Settings.findOne();
- if (!setting || !setting.disableRegistration) {
- $('#invitationcode').hide();
- }
+Template.invitationCode.onRendered(function() {
+ Meteor.subscribe('setting', {
+ onReady() {
+ const setting = Settings.findOne();
+
+ if (!setting || !setting.disableRegistration) {
+ $('#invitationcode').hide();
+ }
+
+ return this.stop();
+ },
+ });
});
diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade
index 5bc7972d..dcf71f4d 100644
--- a/client/components/settings/settingBody.jade
+++ b/client/components/settings/settingBody.jade
@@ -72,7 +72,7 @@ template(name='email')
li.smtp-form
.title {{_ 'smtp-password'}}
.form-group
- input.form-control#mail-server-password(type="text", placeholder="{{_ 'password'}}" value="{{currentSetting.mailServer.password}}")
+ input.form-control#mail-server-password(type="text", placeholder="{{_ 'password'}}" value="")
li.smtp-form
.title {{_ 'smtp-tls'}}
.form-group
diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade
index 6085c2ad..ec88ce7e 100644
--- a/client/components/sidebar/sidebar.jade
+++ b/client/components/sidebar/sidebar.jade
@@ -23,10 +23,11 @@ template(name='homeSidebar')
hr
+labelsWidget
hr
- h3
- i.fa.fa-comments-o
- | {{_ 'activities'}}
- +activities(mode="board")
+ unless currentUser.isNoComments
+ h3
+ i.fa.fa-comments-o
+ | {{_ 'activities'}}
+ +activities(mode="board")
template(name="membersWidget")
.board-widget.board-widget-members
@@ -146,6 +147,12 @@ template(name="changePermissionsPopup")
i.fa.fa-check
span.sub-name {{_ 'normal-desc'}}
li
+ a(class="{{#if isLastAdmin}}disabled{{else}}js-set-no-comments{{/if}}")
+ | {{_ 'no-comments'}}
+ if isNoComments
+ i.fa.fa-check
+ span.sub-name {{_ 'no-comments-desc'}}
+ li
a(class="{{#if isLastAdmin}}disabled{{else}}js-set-comment-only{{/if}}")
| {{_ 'comment-only'}}
if isCommentOnly
diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js
index 5a9de74b..5d34c4a8 100644
--- a/client/components/sidebar/sidebar.js
+++ b/client/components/sidebar/sidebar.js
@@ -126,8 +126,11 @@ Template.memberPopup.helpers({
if(type === 'normal'){
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const commentOnly = currentBoard.hasCommentOnly(this.userId);
+ const noComments = currentBoard.hasNoComments(this.userId);
if(commentOnly){
return TAPi18n.__('comment-only').toLowerCase();
+ } else if(noComments) {
+ return TAPi18n.__('no-comments').toLowerCase();
} else {
return TAPi18n.__(type).toLowerCase();
}
@@ -324,12 +327,13 @@ BlazeComponent.extendComponent({
}).register('addMemberPopup');
Template.changePermissionsPopup.events({
- 'click .js-set-admin, click .js-set-normal, click .js-set-comment-only'(event) {
+ 'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only'(event) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const memberId = this.userId;
const isAdmin = $(event.currentTarget).hasClass('js-set-admin');
const isCommentOnly = $(event.currentTarget).hasClass('js-set-comment-only');
- currentBoard.setMemberPermission(memberId, isAdmin, isCommentOnly);
+ const isNoComments = $(event.currentTarget).hasClass('js-set-no-comments');
+ currentBoard.setMemberPermission(memberId, isAdmin, isNoComments, isCommentOnly);
Popup.back(1);
},
});
@@ -342,7 +346,12 @@ Template.changePermissionsPopup.helpers({
isNormal() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
- return !currentBoard.hasAdmin(this.userId) && !currentBoard.hasCommentOnly(this.userId);
+ return !currentBoard.hasAdmin(this.userId) && !currentBoard.hasNoComments(this.userId) && !currentBoard.hasCommentOnly(this.userId);
+ },
+
+ isNoComments() {
+ const currentBoard = Boards.findOne(Session.get('currentBoard'));
+ return !currentBoard.hasAdmin(this.userId) && currentBoard.hasNoComments(this.userId);
},
isCommentOnly() {
diff --git a/client/components/users/userAvatar.jade b/client/components/users/userAvatar.jade
index 83e2c8d0..ebfa48ba 100644
--- a/client/components/users/userAvatar.jade
+++ b/client/components/users/userAvatar.jade
@@ -1,7 +1,7 @@
template(name="userAvatar")
a.member.js-member(title="{{userData.profile.fullname}} ({{userData.username}})")
if userData.profile.avatarUrl
- img.avatar.avatar-image(src=userData.profile.avatarUrl)
+ img.avatar.avatar-image(src="{{userData.profile.avatarUrl}}")
else
+userAvatarInitials(userId=userData._id)
diff --git a/client/components/users/userAvatar.js b/client/components/users/userAvatar.js
index be7a85d2..91cad237 100644
--- a/client/components/users/userAvatar.js
+++ b/client/components/users/userAvatar.js
@@ -134,8 +134,9 @@ BlazeComponent.extendComponent({
Template.cardMembersPopup.helpers({
isCardMember() {
- const cardId = Template.parentData()._id;
- const cardMembers = Cards.findOne(cardId).members || [];
+ const card = Template.parentData();
+ const cardMembers = card.getMembers();
+
return _.contains(cardMembers, this.userId);
},
diff --git a/client/lib/filter.js b/client/lib/filter.js
index a4e58692..c3c1b070 100644
--- a/client/lib/filter.js
+++ b/client/lib/filter.js
@@ -3,7 +3,6 @@
// RangeFilter, dateFilter, etc.). We then define a global `Filter` object whose
// goal is to filter complete documents by using the local filters for each
// fields.
-
function showFilterSidebar() {
Sidebar.setView('filter');
}
@@ -64,7 +63,9 @@ class SetFilter {
_getMongoSelector() {
this._dep.depend();
- return { $in: this._selectedElements };
+ return {
+ $in: this._selectedElements,
+ };
}
_getEmptySelector() {
@@ -75,7 +76,9 @@ class SetFilter {
includeEmpty = true;
}
});
- return includeEmpty ? { $eq: [] } : null;
+ return includeEmpty ? {
+ $eq: [],
+ } : null;
}
}
@@ -119,7 +122,7 @@ class AdvancedFilter {
current += char;
continue;
}
- if (char === '/'){
+ if (char === '/') {
string = !string;
if (string) regex = true;
current += char;
@@ -135,7 +138,11 @@ class AdvancedFilter {
continue;
}
if (char === ' ' && !string) {
- commands.push({ 'cmd': current, 'string': wasString, regex});
+ commands.push({
+ 'cmd': current,
+ 'string': wasString,
+ regex,
+ });
wasString = false;
current = '';
continue;
@@ -143,25 +150,29 @@ class AdvancedFilter {
current += char;
}
if (current !== '') {
- commands.push({ 'cmd': current, 'string': wasString, regex});
+ commands.push({
+ 'cmd': current,
+ 'string': wasString,
+ regex,
+ });
}
return commands;
}
_fieldNameToId(field) {
- const found = CustomFields.findOne({ 'name': field });
+ const found = CustomFields.findOne({
+ 'name': field,
+ });
return found._id;
}
- _fieldValueToId(field, value)
- {
- const found = CustomFields.findOne({ 'name': field });
- if (found.settings.dropdownItems && found.settings.dropdownItems.length > 0)
- {
- for (let i = 0; i < found.settings.dropdownItems.length; i++)
- {
- if (found.settings.dropdownItems[i].name === value)
- {
+ _fieldValueToId(field, value) {
+ const found = CustomFields.findOne({
+ 'name': field,
+ });
+ if (found.settings.dropdownItems && found.settings.dropdownItems.length > 0) {
+ for (let i = 0; i < found.settings.dropdownItems.length; i++) {
+ if (found.settings.dropdownItems[i].name === value) {
return found.settings.dropdownItems[i]._id;
}
}
@@ -173,10 +184,15 @@ class AdvancedFilter {
try {
//let changed = false;
this._processSubCommands(commands);
+ } catch (e) {
+ return this._lastValide;
}
- catch (e) { return this._lastValide; }
- this._lastValide = { $or: commands };
- return { $or: commands };
+ this._lastValide = {
+ $or: commands,
+ };
+ return {
+ $or: commands,
+ };
}
_processSubCommands(commands) {
@@ -232,19 +248,24 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
- if (commands[i + 1].regex)
- {
+ if (commands[i + 1].regex) {
const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
let regex = null;
if (match.length > 2)
regex = new RegExp(match[1], match[2]);
else
regex = new RegExp(match[1]);
- commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': regex };
- }
- else
- {
- commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': {$in: [this._fieldValueToId(field, str), parseInt(str, 10)]} };
+ commands[i] = {
+ 'customFields._id': this._fieldNameToId(field),
+ 'customFields.value': regex,
+ };
+ } else {
+ commands[i] = {
+ 'customFields._id': this._fieldNameToId(field),
+ 'customFields.value': {
+ $in: [this._fieldValueToId(field, str), parseInt(str, 10)],
+ },
+ };
}
commands.splice(i - 1, 1);
commands.splice(i, 1);
@@ -257,19 +278,28 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
- if (commands[i + 1].regex)
- {
+ if (commands[i + 1].regex) {
const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
let regex = null;
if (match.length > 2)
regex = new RegExp(match[1], match[2]);
else
regex = new RegExp(match[1]);
- commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $not: regex } };
- }
- else
- {
- commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $not: {$in: [this._fieldValueToId(field, str), parseInt(str, 10)]} } };
+ commands[i] = {
+ 'customFields._id': this._fieldNameToId(field),
+ 'customFields.value': {
+ $not: regex,
+ },
+ };
+ } else {
+ commands[i] = {
+ 'customFields._id': this._fieldNameToId(field),
+ 'customFields.value': {
+ $not: {
+ $in: [this._fieldValueToId(field, str), parseInt(str, 10)],
+ },
+ },
+ };
}
commands.splice(i - 1, 1);
commands.splice(i, 1);
@@ -284,7 +314,12 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
- commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gt: parseInt(str, 10) } };
+ commands[i] = {
+ 'customFields._id': this._fieldNameToId(field),
+ 'customFields.value': {
+ $gt: parseInt(str, 10),
+ },
+ };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
@@ -299,7 +334,12 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
- commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gte: parseInt(str, 10) } };
+ commands[i] = {
+ 'customFields._id': this._fieldNameToId(field),
+ 'customFields.value': {
+ $gte: parseInt(str, 10),
+ },
+ };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
@@ -313,7 +353,12 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
- commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lt: parseInt(str, 10) } };
+ commands[i] = {
+ 'customFields._id': this._fieldNameToId(field),
+ 'customFields.value': {
+ $lt: parseInt(str, 10),
+ },
+ };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
@@ -328,14 +373,18 @@ class AdvancedFilter {
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
- commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lte: parseInt(str, 10) } };
+ commands[i] = {
+ 'customFields._id': this._fieldNameToId(field),
+ 'customFields.value': {
+ $lte: parseInt(str, 10),
+ },
+ };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
-
}
}
}
@@ -353,7 +402,9 @@ class AdvancedFilter {
{
const op1 = commands[i - 1];
const op2 = commands[i + 1];
- commands[i] = { $or: [op1, op2] };
+ commands[i] = {
+ $or: [op1, op2],
+ };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
@@ -368,27 +419,29 @@ class AdvancedFilter {
{
const op1 = commands[i - 1];
const op2 = commands[i + 1];
- commands[i] = { $and: [op1, op2] };
+ commands[i] = {
+ $and: [op1, op2],
+ };
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
-
case 'not':
case 'Not':
case 'NOT':
case '!':
{
const op1 = commands[i + 1];
- commands[i] = { $not: op1 };
+ commands[i] = {
+ $not: op1,
+ };
commands.splice(i + 1, 1);
//changed = true;
i--;
break;
}
-
}
}
}
@@ -441,8 +494,7 @@ Filter = {
if (filter._isActive()) {
if (filter.subField !== '') {
filterSelector[`${fieldName}.${filter.subField}`] = filter._getMongoSelector();
- }
- else {
+ } else {
filterSelector[fieldName] = filter._getMongoSelector();
}
emptySelector[fieldName] = filter._getEmptySelector();
@@ -452,7 +504,11 @@ Filter = {
}
});
- const exceptionsSelector = { _id: { $in: this._exceptions } };
+ const exceptionsSelector = {
+ _id: {
+ $in: this._exceptions,
+ },
+ };
this._exceptionsDep.depend();
const selectors = [exceptionsSelector];
@@ -463,7 +519,9 @@ Filter = {
if (includeEmptySelectors) selectors.push(emptySelector);
if (this.advanced._isActive()) selectors.push(this.advanced._getMongoSelector());
- return { $or: selectors };
+ return {
+ $or: selectors,
+ };
},
mongoSelector(additionalSelector) {
@@ -471,7 +529,9 @@ Filter = {
if (_.isUndefined(additionalSelector))
return filterSelector;
else
- return { $and: [filterSelector, additionalSelector] };
+ return {
+ $and: [filterSelector, additionalSelector],
+ };
},
reset() {
diff --git a/client/lib/utils.js b/client/lib/utils.js
index 44ca3a4a..a15dac39 100644
--- a/client/lib/utils.js
+++ b/client/lib/utils.js
@@ -145,6 +145,51 @@ Utils = {
});
},
+<<<<<<< HEAD
+ setMatomo(data){
+ window._paq = window._paq || [];
+ window._paq.push(['setDoNotTrack', data.doNotTrack]);
+ if (data.withUserName){
+ window._paq.push(['setUserId', Meteor.user().username]);
+ }
+ window._paq.push(['trackPageView']);
+ window._paq.push(['enableLinkTracking']);
+
+ (function() {
+ window._paq.push(['setTrackerUrl', `${data.address}piwik.php`]);
+ window._paq.push(['setSiteId', data.siteId]);
+
+ const script = document.createElement('script');
+ Object.assign(script, {
+ id: 'scriptMatomo',
+ type: 'text/javascript',
+ async: 'true',
+ defer: 'true',
+ src: `${data.address}piwik.js`,
+ });
+
+ const s = document.getElementsByTagName('script')[0];
+ s.parentNode.insertBefore(script, s);
+ })();
+
+ Session.set('matomo', true);
+ },
+
+ manageMatomo() {
+ const matomo = Session.get('matomo');
+ if (matomo === undefined){
+ Meteor.call('getMatomoConf', (err, data) => {
+ if (err && err.error[0] === 'var-not-exist'){
+ Session.set('matomo', false); // siteId || address server not defined
+ }
+ if (!err){
+ Utils.setMatomo(data);
+ }
+ });
+ } else if (matomo) {
+ window._paq.push(['trackPageView']);
+ }
+
getTriggerActionDesc(event, tempInstance) {
const jqueryEl = tempInstance.$(event.currentTarget.parentNode);
const triggerEls = jqueryEl.find(".trigger-content").children();
@@ -171,4 +216,4 @@ Utils = {
// resized. This is used to reactively re-calculate the popup position in case
// of a window resize. This is the equivalent of a "Signal" in some other
// programming environments (eg, elm).
-$(window).on('resize', () => Utils.windowResizeDep.changed()); \ No newline at end of file
+$(window).on('resize', () => Utils.windowResizeDep.changed());
diff --git a/config/models.js b/config/models.js
new file mode 100644
index 00000000..f70faae3
--- /dev/null
+++ b/config/models.js
@@ -0,0 +1,4 @@
+module.exports.models = {
+ connection: 'mongodb',
+ migrate: 'safe',
+};
diff --git a/config/router.js b/config/router.js
index 1f80004a..91d08897 100644
--- a/config/router.js
+++ b/config/router.js
@@ -14,6 +14,8 @@ FlowRouter.route('/', {
Filter.reset();
EscapeActions.executeAll();
+ Utils.manageMatomo();
+
BlazeLayout.render('defaultLayout', {
headerBar: 'boardListHeaderBar',
content: 'boardList',
@@ -38,6 +40,8 @@ FlowRouter.route('/b/:id/:slug', {
EscapeActions.executeUpTo('popup-close');
}
+ Utils.manageMatomo();
+
BlazeLayout.render('defaultLayout', {
headerBar: 'boardHeaderBar',
content: 'board',
@@ -53,6 +57,8 @@ FlowRouter.route('/b/:boardId/:slug/:cardId', {
Session.set('currentBoard', params.boardId);
Session.set('currentCard', params.cardId);
+ Utils.manageMatomo();
+
BlazeLayout.render('defaultLayout', {
headerBar: 'boardHeaderBar',
content: 'board',
diff --git a/docker-compose.yml b/docker-compose.yml
index eb82c3aa..7509bbc9 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,7 +3,7 @@ version: '2'
services:
wekandb:
- image: mongo:3.2.20
+ image: mongo:3.2.21
container_name: wekan-db
restart: always
command: mongod --smallfiles --oplogSize 128
@@ -33,10 +33,55 @@ services:
- METEOR_EDGE=${METEOR_EDGE}
- USE_EDGE=${USE_EDGE}
ports:
- - 80:80
+ # Docker outsideport:insideport
+ - 80:8080
environment:
- MONGO_URL=mongodb://wekandb:27017/wekan
- ROOT_URL=http://localhost
+ # Wekan Export Board works when WITH_API='true'.
+ # If you disable Wekan API with 'false', Export Board does not work.
+ - WITH_API=true
+ # Optional: Integration with Matomo https://matomo.org that is installed to your server
+ # The address of the server where Matomo is hosted.
+ # example: - MATOMO_ADDRESS=https://example.com/matomo
+ - MATOMO_ADDRESS=''
+ # The value of the site ID given in Matomo server for Wekan
+ # example: - MATOMO_SITE_ID=12345
+ - MATOMO_SITE_ID=''
+ # The option do not track which enables users to not be tracked by matomo
+ # example: - MATOMO_DO_NOT_TRACK=false
+ - MATOMO_DO_NOT_TRACK=true
+ # The option that allows matomo to retrieve the username:
+ # example: MATOMO_WITH_USERNAME=true
+ - MATOMO_WITH_USERNAME=false
+ # Enable browser policy and allow one trusted URL that can have iframe that has Wekan embedded inside.
+ # Setting this to false is not recommended, it also disables all other browser policy protections
+ # and allows all iframing etc. See wekan/server/policy.js
+ - BROWSER_POLICY_ENABLED=true
+ # When browser policy is enabled, HTML code at this Trusted URL can have iframe that embeds Wekan inside.
+ - TRUSTED_URL=''
+ # What to send to Outgoing Webhook, or leave out. Example, that includes all that are default: cardId,listId,oldListId,boardId,comment,user,card,commentId .
+ # example: WEBHOOKS_ATTRIBUTES=cardId,listId,oldListId,boardId,comment,user,card,commentId
+ - WEBHOOKS_ATTRIBUTES=''
+ # OAuth2 docs: https://github.com/wekan/wekan/wiki/OAuth2
+ # OAuth2 Client ID, for example from Rocket.Chat. Example: abcde12345
+ # example: OAUTH2_CLIENT_ID=abcde12345
+ - OAUTH2_CLIENT_ID=''
+ # OAuth2 Secret, for example from Rocket.Chat: Example: 54321abcde
+ # example: OAUTH2_SECRET=54321abcde
+ - OAUTH2_SECRET=''
+ # OAuth2 Server URL, for example Rocket.Chat. Example: https://chat.example.com
+ # example: OAUTH2_SERVER_URL=https://chat.example.com
+ - OAUTH2_SERVER_URL=''
+ # OAuth2 Authorization Endpoint. Example: /oauth/authorize
+ # example: OAUTH2_AUTH_ENDPOINT=/oauth/authorize
+ - OAUTH2_AUTH_ENDPOINT=''
+ # OAuth2 Userinfo Endpoint. Example: /oauth/userinfo
+ # example: OAUTH2_USERINFO_ENDPOINT=/oauth/userinfo
+ - OAUTH2_USERINFO_ENDPOINT=''
+ # OAuth2 Token Endpoint. Example: /oauth/token
+ # example: OAUTH2_TOKEN_ENDPOINT=/oauth/token
+ - OAUTH2_TOKEN_ENDPOINT=''
depends_on:
- wekandb
diff --git a/i18n/ar.i18n.json b/i18n/ar.i18n.json
index 53fa803b..9af2581e 100644
--- a/i18n/ar.i18n.json
+++ b/i18n/ar.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "مثل « todo list » على سبيل المثال",
"cancel": "إلغاء",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "%s تعليقات لهذه البطاقة",
"card-delete-notice": "هذا حذف أبديّ . سوف تفقد كل الإجراءات المنوطة بهذه البطاقة",
"card-delete-pop": "سيتم إزالة جميع الإجراءات من تبعات النشاط، وأنك لن تكون قادرا على إعادة فتح البطاقة. لا يوجد التراجع.",
@@ -135,6 +136,9 @@
"cards": "بطاقات",
"cards-count": "بطاقات",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "تعديل الصورة الشخصية",
"change-password": "تغيير كلمة المرور",
@@ -167,10 +171,14 @@
"comment-placeholder": "أكتب تعليق",
"comment-only": "التعليق فقط",
"comment-only-desc": "يمكن التعليق على بطاقات فقط.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "حاسوب",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "نسخ رابط البطاقة إلى الحافظة",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "نسخ البطاقة",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "إنشاء لوحة",
"home": "الرئيسية",
"import": "Import",
+ "link": "Link",
"import-board": "استيراد لوحة",
"import-board-c": "استيراد لوحة",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/bg.i18n.json b/i18n/bg.i18n.json
index c8ca3b35..b4ce62f0 100644
--- a/i18n/bg.i18n.json
+++ b/i18n/bg.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "Картата е преместена в Кошчето.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Тази карта има %s коментар.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Карти",
"cards-count": "Карти",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Промени",
"change-avatar": "Промени аватара",
"change-password": "Промени паролата",
@@ -167,10 +171,14 @@
"comment-placeholder": "Напиши коментар",
"comment-only": "Само коментар",
"comment-only-desc": "Може да коментира само в карти.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Компютър",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Копирай връзката на картата в клипборда",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Копирай картата",
"copyChecklistToManyCardsPopup-title": "Копирай чеклисти в други карти",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Начало",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/br.i18n.json b/i18n/br.i18n.json
index 7b511bf1..f92f6fb4 100644
--- a/i18n/br.i18n.json
+++ b/i18n/br.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Kartennoù",
"cards-count": "Kartennoù",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Kemmañ ger-tremen",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/ca.i18n.json b/i18n/ca.i18n.json
index bf891c90..90344870 100644
--- a/i18n/ca.i18n.json
+++ b/i18n/ca.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Igual que “Bucket List”, per exemple",
"cancel": "Cancel·la",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Aquesta fitxa té %s comentaris.",
"card-delete-notice": "L'esborrat és permanent. Perdreu totes les accions associades a aquesta fitxa.",
"card-delete-pop": "Totes les accions s'eliminaran de l'activitat i no podreu tornar a obrir la fitxa. No es pot desfer.",
@@ -135,6 +136,9 @@
"cards": "Fitxes",
"cards-count": "Fitxes",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Canvia",
"change-avatar": "Canvia Avatar",
"change-password": "Canvia la clau",
@@ -167,10 +171,14 @@
"comment-placeholder": "Escriu un comentari",
"comment-only": "Només comentaris",
"comment-only-desc": "Només pots fer comentaris a les fitxes",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Ordinador",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copia l'enllaç de la ftixa al porta-retalls",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copia la fitxa",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Títols de fitxa i Descripcions de destí en aquest format JSON",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Crea tauler",
"home": "Inici",
"import": "importa",
+ "link": "Link",
"import-board": "Importa tauler",
"import-board-c": "Importa tauler",
"import-board-title-trello": "Importa tauler des de Trello",
diff --git a/i18n/cs.i18n.json b/i18n/cs.i18n.json
index daf21326..fc0d93ea 100644
--- a/i18n/cs.i18n.json
+++ b/i18n/cs.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Například \"Než mě odvedou\"",
"cancel": "Zrušit",
"card-archived": "Karta byla přesunuta do koše.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Tato karta má %s komentářů.",
"card-delete-notice": "Smazání je trvalé. Přijdete o všechny akce asociované s touto kartou.",
"card-delete-pop": "Všechny akce budou odstraněny z kanálu aktivity a nebude možné kartu znovu otevřít. Toto nelze vrátit zpět.",
@@ -135,6 +136,9 @@
"cards": "Karty",
"cards-count": "Karty",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Změnit",
"change-avatar": "Změnit avatar",
"change-password": "Změnit heslo",
@@ -167,10 +171,14 @@
"comment-placeholder": "Text komentáře",
"comment-only": "Pouze komentáře",
"comment-only-desc": "Může přidávat komentáře pouze do karet.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Počítač",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Kopírovat adresu karty do mezipaměti",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Kopírovat kartu",
"copyChecklistToManyCardsPopup-title": "Kopírovat checklist do více karet",
"copyChecklistToManyCardsPopup-instructions": "Názvy a popisy cílové karty v tomto formátu JSON",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Vytvořit tablo",
"home": "Domů",
"import": "Import",
+ "link": "Link",
"import-board": "Importovat tablo",
"import-board-c": "Importovat tablo",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/de.i18n.json b/i18n/de.i18n.json
index 614d4b80..bb1cc334 100644
--- a/i18n/de.i18n.json
+++ b/i18n/de.i18n.json
@@ -2,7 +2,7 @@
"accept": "Akzeptieren",
"act-activity-notify": "[Wekan] Aktivitätsbenachrichtigung",
"act-addAttachment": "hat __attachment__ an __card__ angehängt",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "hat die Teilaufgabe __checklist__ zu __card__ hinzugefügt",
"act-addChecklist": "hat die Checkliste __checklist__ zu __card__ hinzugefügt",
"act-addChecklistItem": "hat __checklistItem__ zur Checkliste __checklist__ in __card__ hinzugefügt",
"act-addComment": "hat __card__ kommentiert: __comment__",
@@ -42,7 +42,7 @@
"activity-removed": "hat %s von %s entfernt",
"activity-sent": "hat %s an %s gesendet",
"activity-unjoined": "hat %s verlassen",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "Teilaufgabe zu %s hinzugefügt",
"activity-checklist-added": "hat eine Checkliste zu %s hinzugefügt",
"activity-checklist-item-added": "hat eine Checklistenposition zu '%s' in %s hinzugefügt",
"add": "Hinzufügen",
@@ -50,7 +50,7 @@
"add-board": "neues Board",
"add-card": "Karte hinzufügen",
"add-swimlane": "Swimlane hinzufügen",
- "add-subtask": "Add Subtask",
+ "add-subtask": "Teilaufgabe hinzufügen",
"add-checklist": "Checkliste hinzufügen",
"add-checklist-item": "Position zu einer Checkliste hinzufügen",
"add-cover": "Cover hinzufügen",
@@ -109,6 +109,7 @@
"bucket-example": "z.B. \"Löffelliste\"",
"cancel": "Abbrechen",
"card-archived": "Diese Karte wurde in den Papierkorb verschoben",
+ "board-archived": "Dieses Board wurde in den Papierkorb verschoben.",
"card-comments-title": "Diese Karte hat %s Kommentar(e).",
"card-delete-notice": "Löschen kann nicht rückgängig gemacht werden. Alle Aktionen, die dieser Karte zugeordnet sind, werden ebenfalls gelöscht.",
"card-delete-pop": "Alle Aktionen werden aus dem Aktivitätsfeed entfernt und die Karte kann nicht wiedereröffnet werden. Die Aktion kann nicht rückgängig gemacht werden.",
@@ -134,7 +135,10 @@
"cardMorePopup-title": "Mehr",
"cards": "Karten",
"cards-count": "Karten",
- "casSignIn": "Sign In with CAS",
+ "casSignIn": "Mit CAS anmelden",
+ "cardType-card": "Karte",
+ "cardType-linkedCard": "Verknüpfte Karte",
+ "cardType-linkedBoard": "Verknüpftes Board",
"change": "Ändern",
"change-avatar": "Profilbild ändern",
"change-password": "Passwort ändern",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "Passwort ändern",
"changePermissionsPopup-title": "Berechtigungen ändern",
"changeSettingsPopup-title": "Einstellungen ändern",
- "subtasks": "Subtasks",
+ "subtasks": "Teilaufgaben",
"checklists": "Checklisten",
"click-to-star": "Klicken Sie, um das Board mit einem Stern zu markieren.",
"click-to-unstar": "Klicken Sie, um den Stern vom Board zu entfernen.",
@@ -165,12 +169,16 @@
"color-yellow": "gelb",
"comment": "Kommentar",
"comment-placeholder": "Kommentar schreiben",
- "comment-only": "Nur kommentierbar",
- "comment-only-desc": "Kann Karten nur Kommentieren",
+ "comment-only": "Nur Kommentare",
+ "comment-only-desc": "Kann Karten nur kommentieren.",
+ "no-comments": "Keine Kommentare",
+ "no-comments-desc": "Kann keine Kommentare und Aktivitäten sehen.",
"computer": "Computer",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "Wollen Sie die Teilaufgabe wirklich löschen?",
+ "confirm-checklist-delete-dialog": "Wollen Sie die Checkliste wirklich löschen?",
"copy-card-link-to-clipboard": "Kopiere Link zur Karte in die Zwischenablage",
+ "linkCardPopup-title": "Karte verknüpfen",
+ "searchCardPopup-title": "Karte suchen",
"copyCardPopup-title": "Karte kopieren",
"copyChecklistToManyCardsPopup-title": "Checklistenvorlage in mehrere Karten kopieren",
"copyChecklistToManyCardsPopup-instructions": "Titel und Beschreibungen der Zielkarten im folgenden JSON-Format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Board erstellen",
"home": "Home",
"import": "Importieren",
+ "link": "Verknüpfung",
"import-board": "Board importieren",
"import-board-c": "Board importieren",
"import-board-title-trello": "Board von Trello importieren",
@@ -482,21 +491,21 @@
"delete-board-confirm-popup": "Alle Listen, Karten, Labels und Akivitäten werden gelöscht und Sie können die Inhalte des Boards nicht wiederherstellen! Die Aktion kann nicht rückgängig gemacht werden.",
"boardDeletePopup-title": "Board löschen?",
"delete-board": "Board löschen",
- "default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
- "queue": "Queue",
- "subtask-settings": "Subtasks Settings",
- "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
- "show-subtasks-field": "Cards can have subtasks",
- "deposit-subtasks-board": "Deposit subtasks to this board:",
- "deposit-subtasks-list": "Landing list for subtasks deposited here:",
- "show-parent-in-minicard": "Show parent in minicard:",
- "prefix-with-full-path": "Prefix with full path",
- "prefix-with-parent": "Prefix with parent",
- "subtext-with-full-path": "Subtext with full path",
- "subtext-with-parent": "Subtext with parent",
- "change-card-parent": "Change card's parent",
- "parent-card": "Parent card",
- "source-board": "Source board",
- "no-parent": "Don't show parent"
+ "default-subtasks-board": "Teilaufgabe für __board__ Board",
+ "default": "Standard",
+ "queue": "Warteschlange",
+ "subtask-settings": "Einstellungen für Teilaufgaben",
+ "boardSubtaskSettingsPopup-title": "Boardeinstellungen für Teilaufgaben",
+ "show-subtasks-field": "Karten können Teilaufgaben haben",
+ "deposit-subtasks-board": "Teilaufgaben in diesem Board ablegen:",
+ "deposit-subtasks-list": "Zielliste für hier abgelegte Teilaufgaben:",
+ "show-parent-in-minicard": "Übergeordnetes Element auf Minikarte anzeigen:",
+ "prefix-with-full-path": "Vollständiger Pfad über Titel",
+ "prefix-with-parent": "Über Titel",
+ "subtext-with-full-path": "Vollständiger Pfad unter Titel",
+ "subtext-with-parent": "Unter Titel",
+ "change-card-parent": "Übergeordnete Karte ändern",
+ "parent-card": "Übergeordnete Karte",
+ "source-board": "Quellboard",
+ "no-parent": "Nicht anzeigen"
} \ No newline at end of file
diff --git a/i18n/el.i18n.json b/i18n/el.i18n.json
index 13844004..bf2500b3 100644
--- a/i18n/el.i18n.json
+++ b/i18n/el.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Ακύρωση",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Κάρτες",
"cards-count": "Κάρτες",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Αλλαγή",
"change-avatar": "Change Avatar",
"change-password": "Αλλαγή Κωδικού",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Υπολογιστής",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Εισαγωγή",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/en-GB.i18n.json b/i18n/en-GB.i18n.json
index 937fc657..7e268f4a 100644
--- a/i18n/en-GB.i18n.json
+++ b/i18n/en-GB.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index be11d0e1..395940c6 100644
--- a/i18n/en.i18n.json
+++ b/i18n/en.i18n.json
@@ -119,6 +119,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -145,6 +146,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn" : "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -177,10 +181,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -271,6 +279,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/eo.i18n.json b/i18n/eo.i18n.json
index ef7c6476..a8e7001f 100644
--- a/i18n/eo.i18n.json
+++ b/i18n/eo.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Kartoj",
"cards-count": "Kartoj",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Ŝanĝi",
"change-avatar": "Change Avatar",
"change-password": "Ŝangi pasvorton",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Komputilo",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Krei tavolon",
"home": "Hejmo",
"import": "Importi",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/es-AR.i18n.json b/i18n/es-AR.i18n.json
index 64935585..dd5946cd 100644
--- a/i18n/es-AR.i18n.json
+++ b/i18n/es-AR.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Como \"Lista de Contenedores\" por ejemplo",
"cancel": "Cancelar",
"card-archived": "Esta tarjeta es movida a la Papelera de Reciclaje",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Esta tarjeta tiene %s comentario.",
"card-delete-notice": "Borrar es permanente. Perderás todas las acciones asociadas con esta tarjeta.",
"card-delete-pop": "Todas las acciones van a ser eliminadas del agregador de actividad y no podrás re-abrir la tarjeta. No hay deshacer.",
@@ -135,6 +136,9 @@
"cards": "Tarjetas",
"cards-count": "Tarjetas",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Cambiar",
"change-avatar": "Cambiar Avatar",
"change-password": "Cambiar Contraseña",
@@ -167,10 +171,14 @@
"comment-placeholder": "Comentar",
"comment-only": "Comentar solamente",
"comment-only-desc": "Puede comentar en tarjetas solamente.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computadora",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copiar enlace a tarjeta en el portapapeles",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copiar Tarjeta",
"copyChecklistToManyCardsPopup-title": "Copiar Plantilla Checklist a Muchas Tarjetas",
"copyChecklistToManyCardsPopup-instructions": "Títulos y Descripciones de la Tarjeta Destino en este formato JSON",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Crear Tablero",
"home": "Inicio",
"import": "Importar",
+ "link": "Link",
"import-board": "importar tablero",
"import-board-c": "Importar tablero",
"import-board-title-trello": "Importar tablero de Trello",
diff --git a/i18n/es.i18n.json b/i18n/es.i18n.json
index 6f2d6cd6..ce6133d7 100644
--- a/i18n/es.i18n.json
+++ b/i18n/es.i18n.json
@@ -2,7 +2,7 @@
"accept": "Aceptar",
"act-activity-notify": "[Wekan] Notificación de actividad",
"act-addAttachment": "ha adjuntado __attachment__ a __card__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "ha añadido la subtarea __checklist__ a __card__",
"act-addChecklist": "ha añadido la lista de verificación __checklist__ a __card__",
"act-addChecklistItem": "ha añadido __checklistItem__ a la lista de verificación __checklist__ en __card__",
"act-addComment": "ha comentado en __card__: __comment__",
@@ -20,9 +20,9 @@
"act-importList": "ha importado __list__",
"act-joinMember": "ha añadido a __member__ a __card__",
"act-moveCard": "ha movido __card__ desde __oldList__ a __list__",
- "act-removeBoardMember": "ha desvinculado a __member__ de __board__",
+ "act-removeBoardMember": "ha eliminado a __member__ de __board__",
"act-restoredCard": "ha restaurado __card__ en __board__",
- "act-unjoinMember": "ha desvinculado a __member__ de __card__",
+ "act-unjoinMember": "ha eliminado a __member__ de __card__",
"act-withBoardTitle": "[Wekan] __board__",
"act-withCardTitle": "[__board__] __card__",
"actions": "Acciones",
@@ -42,7 +42,7 @@
"activity-removed": "ha eliminado %s de %s",
"activity-sent": "ha enviado %s a %s",
"activity-unjoined": "se ha desvinculado de %s",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "ha añadido la subtarea a %s",
"activity-checklist-added": "ha añadido una lista de verificación a %s",
"activity-checklist-item-added": "ha añadido el elemento de la lista de verificación a '%s' en %s",
"add": "Añadir",
@@ -50,7 +50,7 @@
"add-board": "Añadir tablero",
"add-card": "Añadir una tarjeta",
"add-swimlane": "Añadir un carril de flujo",
- "add-subtask": "Add Subtask",
+ "add-subtask": "Añadir subtarea",
"add-checklist": "Añadir una lista de verificación",
"add-checklist-item": "Añadir un elemento a la lista de verificación",
"add-cover": "Añadir portada",
@@ -103,12 +103,13 @@
"boardMenuPopup-title": "Menú del tablero",
"boards": "Tableros",
"board-view": "Vista del tablero",
- "board-view-cal": "Calendar",
+ "board-view-cal": "Calendario",
"board-view-swimlanes": "Carriles",
"board-view-lists": "Listas",
"bucket-example": "Como “Cosas por hacer” por ejemplo",
"cancel": "Cancelar",
"card-archived": "Esta tarjeta se ha enviado a la papelera de reciclaje.",
+ "board-archived": "Este tablero se ha enviado a la papelera de reciclaje.",
"card-comments-title": "Esta tarjeta tiene %s comentarios.",
"card-delete-notice": "la eliminación es permanente. Perderás todas las acciones asociadas a esta tarjeta.",
"card-delete-pop": "Se eliminarán todas las acciones del historial de actividades y no se podrá volver a abrir la tarjeta. Esta acción no puede deshacerse.",
@@ -134,7 +135,10 @@
"cardMorePopup-title": "Más",
"cards": "Tarjetas",
"cards-count": "Tarjetas",
- "casSignIn": "Sign In with CAS",
+ "casSignIn": "Iniciar sesión con CAS",
+ "cardType-card": "Tarjeta",
+ "cardType-linkedCard": "Tarjeta enlazada",
+ "cardType-linkedBoard": "Tablero enlazado",
"change": "Cambiar",
"change-avatar": "Cambiar el avatar",
"change-password": "Cambiar la contraseña",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "Cambiar la contraseña",
"changePermissionsPopup-title": "Cambiar los permisos",
"changeSettingsPopup-title": "Cambiar las preferencias",
- "subtasks": "Subtasks",
+ "subtasks": "Subtareas",
"checklists": "Lista de verificación",
"click-to-star": "Haz clic para destacar este tablero.",
"click-to-unstar": "Haz clic para dejar de destacar este tablero.",
@@ -167,10 +171,14 @@
"comment-placeholder": "Escribir comentario",
"comment-only": "Sólo comentarios",
"comment-only-desc": "Solo puedes comentar en las tarjetas.",
+ "no-comments": "No hay comentarios",
+ "no-comments-desc": "No se pueden mostrar comentarios ni actividades.",
"computer": "el ordenador",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "¿Seguro que quieres eliminar la subtarea?",
+ "confirm-checklist-delete-dialog": "¿Seguro que quieres eliminar la lista de verificación?",
"copy-card-link-to-clipboard": "Copiar el enlace de la tarjeta al portapapeles",
+ "linkCardPopup-title": "Enlazar tarjeta",
+ "searchCardPopup-title": "Buscar tarjeta",
"copyCardPopup-title": "Copiar la tarjeta",
"copyChecklistToManyCardsPopup-title": "Copiar la plantilla de la lista de verificación en varias tarjetas",
"copyChecklistToManyCardsPopup-instructions": "Títulos y descripciones de las tarjetas de destino en formato JSON",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Crear tablero",
"home": "Inicio",
"import": "Importar",
+ "link": "Enlace",
"import-board": "importar un tablero",
"import-board-c": "Importar un tablero",
"import-board-title-trello": "Importar un tablero desde Trello",
@@ -310,7 +319,7 @@
"log-out": "Finalizar la sesión",
"log-in": "Iniciar sesión",
"loginPopup-title": "Iniciar sesión",
- "memberMenuPopup-title": "Mis preferencias",
+ "memberMenuPopup-title": "Preferencias de miembro",
"members": "Miembros",
"menu": "Menú",
"move-selection": "Mover la selección",
@@ -482,21 +491,21 @@
"delete-board-confirm-popup": "Se eliminarán todas las listas, tarjetas, etiquetas y actividades, y no podrás recuperar los contenidos del tablero. Esta acción no puede deshacerse.",
"boardDeletePopup-title": "¿Borrar el tablero?",
"delete-board": "Borrar el tablero",
- "default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
- "queue": "Queue",
- "subtask-settings": "Subtasks Settings",
- "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
- "show-subtasks-field": "Cards can have subtasks",
- "deposit-subtasks-board": "Deposit subtasks to this board:",
- "deposit-subtasks-list": "Landing list for subtasks deposited here:",
- "show-parent-in-minicard": "Show parent in minicard:",
- "prefix-with-full-path": "Prefix with full path",
- "prefix-with-parent": "Prefix with parent",
- "subtext-with-full-path": "Subtext with full path",
- "subtext-with-parent": "Subtext with parent",
- "change-card-parent": "Change card's parent",
- "parent-card": "Parent card",
- "source-board": "Source board",
- "no-parent": "Don't show parent"
+ "default-subtasks-board": "Subtareas para el tablero __board__",
+ "default": "Por defecto",
+ "queue": "Cola",
+ "subtask-settings": "Subtareas del tablero",
+ "boardSubtaskSettingsPopup-title": "Configuración de las subtareas del tablero",
+ "show-subtasks-field": "Las tarjetas pueden tener subtareas",
+ "deposit-subtasks-board": "Depositar subtareas en este tablero:",
+ "deposit-subtasks-list": "Lista de destino para subtareas depositadas aquí:",
+ "show-parent-in-minicard": "Mostrar el padre en una minitarjeta:",
+ "prefix-with-full-path": "Prefijo con ruta completa",
+ "prefix-with-parent": "Prefijo con el padre",
+ "subtext-with-full-path": "Subtexto con ruta completa",
+ "subtext-with-parent": "Subtexto con el padre",
+ "change-card-parent": "Cambiar la tarjeta padre",
+ "parent-card": "Tarjeta padre",
+ "source-board": "Tablero de origen",
+ "no-parent": "No mostrar la tarjeta padre"
} \ No newline at end of file
diff --git a/i18n/eu.i18n.json b/i18n/eu.i18n.json
index 08729670..ae0d904a 100644
--- a/i18n/eu.i18n.json
+++ b/i18n/eu.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Esaterako \"Pertz zerrenda\"",
"cancel": "Utzi",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Txartel honek iruzkin %s dauka.",
"card-delete-notice": "Ezabaketa behin betiko da. Txartel honi lotutako ekintza guztiak galduko dituzu.",
"card-delete-pop": "Ekintza guztiak ekintza jariotik kenduko dira eta ezin izango duzu txartela berrireki. Ez dago desegiterik.",
@@ -135,6 +136,9 @@
"cards": "Txartelak",
"cards-count": "Txartelak",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Aldatu",
"change-avatar": "Aldatu avatarra",
"change-password": "Aldatu pasahitza",
@@ -167,10 +171,14 @@
"comment-placeholder": "Idatzi iruzkin bat",
"comment-only": "Iruzkinak besterik ez",
"comment-only-desc": "Iruzkinak txarteletan soilik egin ditzake",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Ordenagailua",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Kopiatu txartela arbelera",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Kopiatu txartela",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Sortu arbela",
"home": "Hasiera",
"import": "Inportatu",
+ "link": "Link",
"import-board": "inportatu arbela",
"import-board-c": "Inportatu arbela",
"import-board-title-trello": "Inportatu arbela Trellotik",
diff --git a/i18n/fa.i18n.json b/i18n/fa.i18n.json
index 2cd998be..94ba2498 100644
--- a/i18n/fa.i18n.json
+++ b/i18n/fa.i18n.json
@@ -2,7 +2,7 @@
"accept": "پذیرش",
"act-activity-notify": "[wekan] اطلاع فعالیت",
"act-addAttachment": "پیوست __attachment__ به __card__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "زیر وظیفه __checklist__ به __card__ اضافه شد",
"act-addChecklist": "سیاهه __checklist__ به __card__ افزوده شد",
"act-addChecklistItem": "__checklistItem__ به سیاهه __checklist__ در __card__ افزوده شد",
"act-addComment": "درج نظر برای __card__: __comment__",
@@ -11,10 +11,10 @@
"act-createCustomField": "فیلد __customField__ ایجاد شد",
"act-createList": "__list__ به __board__ اضافه شد",
"act-addBoardMember": "__member__ به __board__ اضافه شد",
- "act-archivedBoard": "__board__ به سطل زباله ریخته شد",
- "act-archivedCard": "__card__ به سطل زباله منتقل شد",
- "act-archivedList": "__list__ به سطل زباله منتقل شد",
- "act-archivedSwimlane": "__swimlane__ به سطل زباله منتقل شد",
+ "act-archivedBoard": "__board__ به بازیافتی ریخته شد",
+ "act-archivedCard": "__card__ به بازیافتی منتقل شد",
+ "act-archivedList": "__list__ به بازیافتی منتقل شد",
+ "act-archivedSwimlane": "__swimlane__ به بازیافتی منتقل شد",
"act-importBoard": "__board__ وارد شده",
"act-importCard": "__card__ وارد شده",
"act-importList": "__list__ وارد شده",
@@ -26,10 +26,10 @@
"act-withBoardTitle": "[Wekan] __board__",
"act-withCardTitle": "[__board__] __card__",
"actions": "اعمال",
- "activities": "فعالیت ها",
+ "activities": "فعالیت‌ها",
"activity": "فعالیت",
"activity-added": "%s به %s اضافه شد",
- "activity-archived": "%s به سطل زباله منتقل شد",
+ "activity-archived": "%s به بازیافتی منتقل شد",
"activity-attached": "%s به %s پیوست شد",
"activity-created": "%s ایجاد شد",
"activity-customfield-created": "%s فیلدشخصی ایجاد شد",
@@ -42,7 +42,7 @@
"activity-removed": "%s از %s حذف شد",
"activity-sent": "ارسال %s به %s",
"activity-unjoined": "قطع اتصال %s",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "زیروظیفه به %s اضافه شد",
"activity-checklist-added": "سیاهه به %s اضافه شد",
"activity-checklist-item-added": "added checklist item to '%s' in %s",
"add": "افزودن",
@@ -50,7 +50,7 @@
"add-board": "افزودن برد",
"add-card": "افزودن کارت",
"add-swimlane": "Add Swimlane",
- "add-subtask": "Add Subtask",
+ "add-subtask": "افزودن زیر وظیفه",
"add-checklist": "افزودن چک لیست",
"add-checklist-item": "افزودن مورد به سیاهه",
"add-cover": "جلد کردن",
@@ -69,7 +69,7 @@
"and-n-other-card_plural": "و __count__ کارت دیگر",
"apply": "اعمال",
"app-is-offline": "Wekan در حال بارگذاری است. لطفا صبر کنید. نوسازی صفحه، منجر به از دست رفتن داده‌ها می‌شود. اگر Wekan بارگذاری نشد، لطفا بررسی کنید که سرور Wekan متوقف نشده باشد.",
- "archive": "ریختن به سطل زباله",
+ "archive": "انتقال به بازیافتی",
"archive-all": "ریختن همه به سطل زباله",
"archive-board": "ریختن تخته به سطل زباله",
"archive-card": "ریختن کارت به سطل زباله",
@@ -103,18 +103,19 @@
"boardMenuPopup-title": "منوی تخته",
"boards": "تخته‌ها",
"board-view": "نمایش تخته",
- "board-view-cal": "Calendar",
+ "board-view-cal": "تقویم",
"board-view-swimlanes": "Swimlanes",
"board-view-lists": "فهرست‌ها",
"bucket-example": "برای مثال چیزی شبیه \"لیست سبدها\"",
"cancel": "انصراف",
"card-archived": "این کارت به سطل زباله ریخته شده است",
+ "board-archived": "این تخته به بازیافتی انتقال یافت.",
"card-comments-title": "این کارت دارای %s نظر است.",
"card-delete-notice": "حذف دائمی. تمامی موارد مرتبط با این کارت از بین خواهند رفت.",
"card-delete-pop": "همه اقدامات از این پردازه (خوراک) حذف خواهد شد و امکان بازگرداندن کارت وجود نخواهد داشت.",
- "card-delete-suggest-archive": "You can move a card to Recycle Bin to remove it from the board and preserve the activity.",
- "card-due": "ناشی از",
- "card-due-on": "مقتضی بر",
+ "card-delete-suggest-archive": "شما میتوانید این کارت را به سطل بازیافت انتقال دهید تا از تخته پاک و فعالیت ها حفظ شود",
+ "card-due": "تا",
+ "card-due-on": "تا",
"card-spent": "زمان صرف شده",
"card-edit-attachments": "ویرایش ضمائم",
"card-edit-custom-fields": "ویرایش فیلدهای شخصی",
@@ -134,7 +135,10 @@
"cardMorePopup-title": "بیشتر",
"cards": "کارت‌ها",
"cards-count": "کارت‌ها",
- "casSignIn": "Sign In with CAS",
+ "casSignIn": "ورود با استفاده از CAS",
+ "cardType-card": "کارت",
+ "cardType-linkedCard": "کارت‌های مرتبط",
+ "cardType-linkedBoard": "تخته‌های مرتبط",
"change": "تغییر",
"change-avatar": "تغییر تصویر",
"change-password": "تغییر کلمه عبور",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "تغییر کلمه عبور",
"changePermissionsPopup-title": "تغییر دسترسی‌ها",
"changeSettingsPopup-title": "تغییر تنظیمات",
- "subtasks": "Subtasks",
+ "subtasks": "زیر وظیفه",
"checklists": "سیاهه‌ها",
"click-to-star": "با کلیک کردن ستاره بدهید",
"click-to-unstar": "با کلیک کردن ستاره را کم کنید",
@@ -167,10 +171,14 @@
"comment-placeholder": "درج نظر",
"comment-only": "فقط نظر",
"comment-only-desc": "فقط می‌تواند روی کارت‌ها نظر دهد.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "رایانه",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "از حذف این زیر وظیفه اطمینان دارید؟",
+ "confirm-checklist-delete-dialog": "مطمئنا چک لیست پاک شود؟",
"copy-card-link-to-clipboard": "درج پیوند کارت در حافظه",
+ "linkCardPopup-title": "ارتباط دادن کارت",
+ "searchCardPopup-title": "جستجوی کارت",
"copyCardPopup-title": "کپی کارت",
"copyChecklistToManyCardsPopup-title": "کپی قالب کارت به کارت‌های متعدد",
"copyChecklistToManyCardsPopup-instructions": "عنوان و توضیحات کارت مقصد در این قالب JSON",
@@ -186,10 +194,10 @@
"custom-field-checkbox": "جعبه انتخابی",
"custom-field-date": "تاریخ",
"custom-field-dropdown": "لیست افتادنی",
- "custom-field-dropdown-none": "(none)",
+ "custom-field-dropdown-none": "(هیچ)",
"custom-field-dropdown-options": "لیست امکانات",
"custom-field-dropdown-options-placeholder": "کلید Enter را جهت افزودن امکانات بیشتر فشار دهید",
- "custom-field-dropdown-unknown": "(unknown)",
+ "custom-field-dropdown-unknown": "(ناشناخته)",
"custom-field-number": "عدد",
"custom-field-text": "متن",
"custom-fields": "فیلدهای شخصی",
@@ -211,7 +219,7 @@
"edit-wip-limit": "Edit WIP Limit",
"soft-wip-limit": "Soft WIP Limit",
"editCardStartDatePopup-title": "تغییر تاریخ آغاز",
- "editCardDueDatePopup-title": "تغییر تاریخ بدلیل",
+ "editCardDueDatePopup-title": "تغییر تاریخ پایان",
"editCustomFieldPopup-title": "ویرایش فیلد",
"editCardSpentTimePopup-title": "تغییر زمان صرف شده",
"editLabelPopup-title": "تغیر برچسب",
@@ -253,7 +261,7 @@
"filter-on": "صافی ـFilterـ فعال است",
"filter-on-desc": "شما صافی ـFilterـ برای کارتهای تخته را روشن کرده اید. جهت ویرایش کلیک نمایید.",
"filter-to-selection": "صافی ـFilterـ برای موارد انتخابی",
- "advanced-filter-label": "Advanced Filter",
+ "advanced-filter-label": "صافی پیشرفته",
"advanced-filter-description": "Advanced Filter allows to write a string containing following operators: == != <= >= && || ( ) A space is used as a separator between the Operators. You can filter for all Custom Fields by typing their names and values. For Example: Field1 == Value1. Note: If fields or values contains spaces, you need to encapsulate them into single quotes. For Example: 'Field 1' == 'Value 1'. For single control characters (' \\/) to be skipped, you can use \\. For example: Field1 == I\\'m. Also you can combine multiple conditions. For Example: F1 == V1 || F1 == V2. Normally all operators are interpreted from left to right. You can change the order by placing brackets. For Example: F1 == V1 && ( F2 == V2 || F2 == V3 ). Also you can search text fields using regex: F1 == /Tes.*/i",
"fullname": "نام و نام خانوادگی",
"header-logo-title": "بازگشت به صفحه تخته.",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "ایجاد تخته",
"home": "خانه",
"import": "وارد کردن",
+ "link": "ارتباط",
"import-board": "وارد کردن تخته",
"import-board-c": "وارد کردن تخته",
"import-board-title-trello": "وارد کردن تخته از Trello",
@@ -294,7 +303,7 @@
"leave-board-pop": "Are you sure you want to leave __boardTitle__? You will be removed from all cards on this board.",
"leaveBoardPopup-title": "Leave Board ?",
"link-card": "ارجاع به این کارت",
- "list-archive-cards": "Move all cards in this list to Recycle Bin",
+ "list-archive-cards": "همه‌ کارت‌های این لیست را به بازیافتی انتقال بده",
"list-archive-cards-pop": "This will remove all the cards in this list from the board. To view cards in Recycle Bin and bring them back to the board, click “Menu” > “Recycle Bin”.",
"list-move-cards": "انتقال تمام کارت های این لیست",
"list-select-cards": "انتخاب تمام کارت های این لیست",
@@ -304,7 +313,7 @@
"listMorePopup-title": "بیشتر",
"link-list": "پیوند به این فهرست",
"list-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the list. There is no undo.",
- "list-delete-suggest-archive": "You can move a list to Recycle Bin to remove it from the board and preserve the activity.",
+ "list-delete-suggest-archive": "با انتقال سیاهه به سطل ذباله می‌توانید ضمن حفظ فعالیت، سیاهه را از تخته حذف کنید.",
"lists": "لیست ها",
"swimlanes": "Swimlanes",
"log-out": "خروج",
@@ -324,8 +333,8 @@
"muted-info": "شما هیچگاه از تغییرات این تخته مطلع نخواهید شد",
"my-boards": "تخته‌های من",
"name": "نام",
- "no-archived-cards": "No cards in Recycle Bin.",
- "no-archived-lists": "No lists in Recycle Bin.",
+ "no-archived-cards": "کارتی در سطل ذباله نیست.",
+ "no-archived-lists": "سیاهه‌ای در سطل ذباله نیست.",
"no-archived-swimlanes": "No swimlanes in Recycle Bin.",
"no-results": "بدون نتیجه",
"normal": "عادی",
@@ -396,7 +405,7 @@
"title": "عنوان",
"tracking": "پیگردی",
"tracking-info": "شما از هرگونه تغییر در کارتهایی که بعنوان ایجاد کننده ویا عضو آن هستید، آگاه خواهید شد",
- "type": "Type",
+ "type": "نوع",
"unassign-member": "عدم انتصاب کاربر",
"unsaved-description": "شما توضیحات ذخیره نشده دارید.",
"unwatch": "عدم دیده بانی",
@@ -405,7 +414,7 @@
"uploaded-avatar": "تصویر ارسال شد",
"username": "نام کاربری",
"view-it": "مشاهده",
- "warn-list-archived": "warning: this card is in an list at Recycle Bin",
+ "warn-list-archived": "هشدار: این کارت در سیاهه‌ای داخل سطح ذباله است",
"watch": "دیده بانی",
"watching": "درحال دیده بانی",
"watching-info": "شما از هر تغییری دراین تخته آگاه خواهید شد",
@@ -466,7 +475,7 @@
"no": "خیر",
"accounts": "حساب‌ها",
"accounts-allowEmailChange": "اجازه تغییر رایانامه",
- "accounts-allowUserNameChange": "Allow Username Change",
+ "accounts-allowUserNameChange": "اجازه تغییر نام کاربری",
"createdAt": "ساخته شده در",
"verified": "معتبر",
"active": "فعال",
@@ -476,15 +485,15 @@
"card-end-on": "پایان در",
"editCardReceivedDatePopup-title": "تغییر تاریخ رسید",
"editCardEndDatePopup-title": "تغییر تاریخ پایان",
- "assigned-by": "Assigned By",
- "requested-by": "Requested By",
+ "assigned-by": "محول شده توسط",
+ "requested-by": "تقاضا شده توسط",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
- "boardDeletePopup-title": "Delete Board?",
- "delete-board": "Delete Board",
+ "boardDeletePopup-title": "حذف تخته؟",
+ "delete-board": "حذف تخته",
"default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
- "queue": "Queue",
+ "default": "پیش‌فرض",
+ "queue": "صف",
"subtask-settings": "Subtasks Settings",
"boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
"show-subtasks-field": "Cards can have subtasks",
diff --git a/i18n/fi.i18n.json b/i18n/fi.i18n.json
index 2b1e9286..4de354aa 100644
--- a/i18n/fi.i18n.json
+++ b/i18n/fi.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Kuten “Laatikko lista” esimerkiksi",
"cancel": "Peruuta",
"card-archived": "Tämä kortti on siirretty roskakoriin.",
+ "board-archived": "Tämä taulu on siirretty roskakoriin.",
"card-comments-title": "Tässä kortissa on %s kommenttia.",
"card-delete-notice": "Poistaminen on lopullista. Menetät kaikki toimet jotka on liitetty tähän korttiin.",
"card-delete-pop": "Kaikki toimet poistetaan toimintasyötteestä ja et tule pystymään uudelleenavaamaan korttia. Tätä ei voi peruuttaa.",
@@ -135,6 +136,9 @@
"cards": "Kortit",
"cards-count": "korttia",
"casSignIn": "CAS kirjautuminen",
+ "cardType-card": "Kortti",
+ "cardType-linkedCard": "Linkitetty kortti",
+ "cardType-linkedBoard": "Linkitetty taulu",
"change": "Muokkaa",
"change-avatar": "Muokkaa profiilikuvaa",
"change-password": "Vaihda salasana",
@@ -167,10 +171,14 @@
"comment-placeholder": "Kirjoita kommentti",
"comment-only": "Vain kommentointi",
"comment-only-desc": "Voi vain kommentoida kortteja",
+ "no-comments": "Ei kommentteja",
+ "no-comments-desc": "Ei voi nähdä kommentteja ja toimintaa.",
"computer": "Tietokone",
"confirm-subtask-delete-dialog": "Oletko varma että haluat poistaa alitehtävän?",
"confirm-checklist-delete-dialog": "Oletko varma että haluat poistaa tarkistuslistan?",
"copy-card-link-to-clipboard": "Kopioi kortin linkki leikepöydälle",
+ "linkCardPopup-title": "Linkitä kortti",
+ "searchCardPopup-title": "Etsi kortti",
"copyCardPopup-title": "Kopioi kortti",
"copyChecklistToManyCardsPopup-title": "Kopioi tarkistuslistan malli monille korteille",
"copyChecklistToManyCardsPopup-instructions": "Kohde korttien otsikot ja kuvaukset JSON muodossa",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Luo taulu",
"home": "Koti",
"import": "Tuo",
+ "link": "Linkitä",
"import-board": "tuo taulu",
"import-board-c": "Tuo taulu",
"import-board-title-trello": "Tuo taulu Trellosta",
diff --git a/i18n/fr.i18n.json b/i18n/fr.i18n.json
index c783490d..19d0c2d6 100644
--- a/i18n/fr.i18n.json
+++ b/i18n/fr.i18n.json
@@ -2,7 +2,7 @@
"accept": "Accepter",
"act-activity-notify": "[Wekan] Notification d'activité",
"act-addAttachment": "a joint __attachment__ à __card__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "a ajouté une sous-tâche __checklist__ à __card__",
"act-addChecklist": "a ajouté la checklist __checklist__ à __card__",
"act-addChecklistItem": "a ajouté l'élément __checklistItem__ à la checklist __checklist__ de __card__",
"act-addComment": "a commenté __card__ : __comment__",
@@ -42,7 +42,7 @@
"activity-removed": "a supprimé %s de %s",
"activity-sent": "a envoyé %s vers %s",
"activity-unjoined": "a quitté %s",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "a ajouté une sous-tâche à %s",
"activity-checklist-added": "a ajouté une checklist à %s",
"activity-checklist-item-added": "a ajouté un élément à la checklist '%s' dans %s",
"add": "Ajouter",
@@ -50,7 +50,7 @@
"add-board": "Ajouter un tableau",
"add-card": "Ajouter une carte",
"add-swimlane": "Ajouter un couloir",
- "add-subtask": "Add Subtask",
+ "add-subtask": "Ajouter une sous-tâche",
"add-checklist": "Ajouter une checklist",
"add-checklist-item": "Ajouter un élément à la checklist",
"add-cover": "Ajouter la couverture",
@@ -109,6 +109,7 @@
"bucket-example": "Comme « todo list » par exemple",
"cancel": "Annuler",
"card-archived": "Cette carte est déplacée vers la corbeille.",
+ "board-archived": "Ce tableau a été déplacé dans la Corbeille.",
"card-comments-title": "Cette carte a %s commentaires.",
"card-delete-notice": "La suppression est permanente. Vous perdrez toutes les actions associées à cette carte.",
"card-delete-pop": "Toutes les actions vont être supprimées du suivi d'activités et vous ne pourrez plus utiliser cette carte. Cette action est irréversible.",
@@ -134,7 +135,10 @@
"cardMorePopup-title": "Plus",
"cards": "Cartes",
"cards-count": "Cartes",
- "casSignIn": "Sign In with CAS",
+ "casSignIn": "Se connecter avec CAS",
+ "cardType-card": "Carte",
+ "cardType-linkedCard": "Carte liée",
+ "cardType-linkedBoard": "Tableau lié",
"change": "Modifier",
"change-avatar": "Modifier l'avatar",
"change-password": "Modifier le mot de passe",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "Modifier le mot de passe",
"changePermissionsPopup-title": "Modifier les permissions",
"changeSettingsPopup-title": "Modifier les paramètres",
- "subtasks": "Subtasks",
+ "subtasks": "Sous-tâches",
"checklists": "Checklists",
"click-to-star": "Cliquez pour ajouter ce tableau aux favoris.",
"click-to-unstar": "Cliquez pour retirer ce tableau des favoris.",
@@ -167,10 +171,14 @@
"comment-placeholder": "Écrire un commentaire",
"comment-only": "Commentaire uniquement",
"comment-only-desc": "Ne peut que commenter des cartes.",
+ "no-comments": "Aucun commentaire",
+ "no-comments-desc": "Ne peut pas voir les commentaires et les activités.",
"computer": "Ordinateur",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "Êtes-vous sûr de vouloir supprimer la sous-tâche ?",
+ "confirm-checklist-delete-dialog": "Êtes-vous sûr de vouloir supprimer la checklist ?",
"copy-card-link-to-clipboard": "Copier le lien vers la carte dans le presse-papier",
+ "linkCardPopup-title": "Lier une Carte",
+ "searchCardPopup-title": "Chercher une Carte",
"copyCardPopup-title": "Copier la carte",
"copyChecklistToManyCardsPopup-title": "Copier le modèle de checklist vers plusieurs cartes",
"copyChecklistToManyCardsPopup-instructions": "Titres et descriptions des cartes de destination dans ce format JSON",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Créer un tableau",
"home": "Accueil",
"import": "Importer",
+ "link": "Lien",
"import-board": "importer un tableau",
"import-board-c": "Importer un tableau",
"import-board-title-trello": "Importer le tableau depuis Trello",
@@ -456,7 +465,7 @@
"OS_Platform": "OS Plate-forme",
"OS_Release": "OS Version",
"OS_Totalmem": "OS Mémoire totale",
- "OS_Type": "OS Type",
+ "OS_Type": "Type d'OS",
"OS_Uptime": "OS Durée de fonctionnement",
"hours": "heures",
"minutes": "minutes",
@@ -466,7 +475,7 @@
"no": "Non",
"accounts": "Comptes",
"accounts-allowEmailChange": "Autoriser le changement d'adresse mail",
- "accounts-allowUserNameChange": "Permettre la modification de l'identifiant",
+ "accounts-allowUserNameChange": "Autoriser le changement d'identifiant",
"createdAt": "Créé le",
"verified": "Vérifié",
"active": "Actif",
@@ -478,25 +487,25 @@
"editCardEndDatePopup-title": "Changer la date de fin",
"assigned-by": "Assigné par",
"requested-by": "Demandé par",
- "board-delete-notice": "La suppression est définitive. Vous perdrez toutes vos listes, cartes et actions associées à ce tableau.",
+ "board-delete-notice": "La suppression est définitive. Vous perdrez toutes les listes, cartes et actions associées à ce tableau.",
"delete-board-confirm-popup": "Toutes les listes, cartes, étiquettes et activités seront supprimées et vous ne pourrez pas retrouver le contenu du tableau. Il n'y a pas d'annulation possible.",
"boardDeletePopup-title": "Supprimer le tableau ?",
"delete-board": "Supprimer le tableau",
- "default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
+ "default-subtasks-board": "Sous-tâches du tableau __board__",
+ "default": "Défaut",
"queue": "Queue",
- "subtask-settings": "Subtasks Settings",
- "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
- "show-subtasks-field": "Cards can have subtasks",
- "deposit-subtasks-board": "Deposit subtasks to this board:",
- "deposit-subtasks-list": "Landing list for subtasks deposited here:",
- "show-parent-in-minicard": "Show parent in minicard:",
- "prefix-with-full-path": "Prefix with full path",
- "prefix-with-parent": "Prefix with parent",
- "subtext-with-full-path": "Subtext with full path",
- "subtext-with-parent": "Subtext with parent",
- "change-card-parent": "Change card's parent",
- "parent-card": "Parent card",
- "source-board": "Source board",
- "no-parent": "Don't show parent"
+ "subtask-settings": "Paramètres des sous-tâches",
+ "boardSubtaskSettingsPopup-title": "Paramètres des sous-tâches du tableau",
+ "show-subtasks-field": "Les cartes peuvent avoir des sous-tâches",
+ "deposit-subtasks-board": "Déposer des sous-tâches dans ce tableau :",
+ "deposit-subtasks-list": "Liste de destination pour les sous-tâches déposées ici :",
+ "show-parent-in-minicard": "Voir la carte parente dans la mini-carte :",
+ "prefix-with-full-path": "Préfixer avec le chemin complet",
+ "prefix-with-parent": "Préfixer avec le parent",
+ "subtext-with-full-path": "Sous-titre avec le chemin complet",
+ "subtext-with-parent": "Sous-titre avec le parent",
+ "change-card-parent": "Changer le parent de la carte",
+ "parent-card": "Carte parente",
+ "source-board": "Tableau source",
+ "no-parent": "Ne pas afficher le parent"
} \ No newline at end of file
diff --git a/i18n/gl.i18n.json b/i18n/gl.i18n.json
index aec06426..47616c07 100644
--- a/i18n/gl.i18n.json
+++ b/i18n/gl.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancelar",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Tarxetas",
"cards-count": "Tarxetas",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Cambiar",
"change-avatar": "Cambiar o avatar",
"change-password": "Cambiar o contrasinal",
@@ -167,10 +171,14 @@
"comment-placeholder": "Escribir un comentario",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computador",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Crear taboleiro",
"home": "Inicio",
"import": "Importar",
+ "link": "Link",
"import-board": "importar taboleiro",
"import-board-c": "Importar taboleiro",
"import-board-title-trello": "Importar taboleiro de Trello",
diff --git a/i18n/he.i18n.json b/i18n/he.i18n.json
index c035fd1e..501651fc 100644
--- a/i18n/he.i18n.json
+++ b/i18n/he.i18n.json
@@ -2,7 +2,7 @@
"accept": "אישור",
"act-activity-notify": "[Wekan] הודעת פעילות",
"act-addAttachment": " __attachment__ צורף לכרטיס __card__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "נוספה תת־משימה __checklist__ אל __card__",
"act-addChecklist": "רשימת משימות __checklist__ נוספה ל __card__",
"act-addChecklistItem": " __checklistItem__ נוסף לרשימת משימות __checklist__ בכרטיס __card__",
"act-addComment": "התקבלה תגובה על הכרטיס __card__:‏ __comment__",
@@ -42,7 +42,7 @@
"activity-removed": "%s הוסר מ%s",
"activity-sent": "%s נשלח ל%s",
"activity-unjoined": "בטל צירוף %s",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "נוספה תת־משימה אל %s",
"activity-checklist-added": "נוספה רשימת משימות אל %s",
"activity-checklist-item-added": "נוסף פריט רשימת משימות אל ‚%s‘ תחת %s",
"add": "הוספה",
@@ -50,7 +50,7 @@
"add-board": "הוספת לוח",
"add-card": "הוספת כרטיס",
"add-swimlane": "הוספת מסלול",
- "add-subtask": "Add Subtask",
+ "add-subtask": "הוסף תת משימה",
"add-checklist": "הוספת רשימת מטלות",
"add-checklist-item": "הוספת פריט לרשימת משימות",
"add-cover": "הוספת כיסוי",
@@ -65,8 +65,8 @@
"admin-announcement-active": "הכרזת מערכת פעילה",
"admin-announcement-title": "הכרזה ממנהל המערכת",
"all-boards": "כל הלוחות",
- "and-n-other-card": "וכרטיס אחר",
- "and-n-other-card_plural": "ו־__count__ כרטיסים אחרים",
+ "and-n-other-card": "וכרטיס נוסף",
+ "and-n-other-card_plural": "ו־__count__ כרטיסים נוספים",
"apply": "החלה",
"app-is-offline": "Wekan בטעינה, נא להמתין. רענון העמוד עשוי להוביל לאובדן מידע. אם הטעינה של Wekan נעצרה, נא לבדוק ששרת ה־Wekan לא נעצר.",
"archive": "העברה לסל המחזור",
@@ -103,12 +103,13 @@
"boardMenuPopup-title": "תפריט לוח",
"boards": "לוחות",
"board-view": "תצוגת לוח",
- "board-view-cal": "Calendar",
+ "board-view-cal": "לוח שנה",
"board-view-swimlanes": "מסלולים",
"board-view-lists": "רשימות",
"bucket-example": "כמו למשל „רשימת המשימות“",
"cancel": "ביטול",
"card-archived": "כרטיס זה הועבר לסל המחזור",
+ "board-archived": "הלוח עבר לסל המחזור",
"card-comments-title": "לכרטיס זה %s תגובות.",
"card-delete-notice": "מחיקה היא סופית. כל הפעולות המשויכות לכרטיס זה תלכנה לאיוד.",
"card-delete-pop": "כל הפעולות יוסרו מלוח הפעילות ולא תהיה אפשרות לפתוח מחדש את הכרטיס. אין דרך חזרה.",
@@ -134,7 +135,10 @@
"cardMorePopup-title": "עוד",
"cards": "כרטיסים",
"cards-count": "כרטיסים",
- "casSignIn": "Sign In with CAS",
+ "casSignIn": "כניסה עם CAS",
+ "cardType-card": "כרטיס",
+ "cardType-linkedCard": "כרטיס מקושר",
+ "cardType-linkedBoard": "לוח מקושר",
"change": "שינוי",
"change-avatar": "החלפת תמונת משתמש",
"change-password": "החלפת ססמה",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "החלפת ססמה",
"changePermissionsPopup-title": "שינוי הרשאות",
"changeSettingsPopup-title": "שינוי הגדרות",
- "subtasks": "Subtasks",
+ "subtasks": "תתי משימות",
"checklists": "רשימות",
"click-to-star": "יש ללחוץ להוספת הלוח למועדפים.",
"click-to-unstar": "יש ללחוץ להסרת הלוח מהמועדפים.",
@@ -165,12 +169,16 @@
"color-yellow": "צהוב",
"comment": "לפרסם",
"comment-placeholder": "כתיבת הערה",
- "comment-only": "הערה בלבד",
- "comment-only-desc": "ניתן להעיר על כרטיסים בלבד.",
+ "comment-only": "תגובה בלבד",
+ "comment-only-desc": "ניתן להגיב על כרטיסים בלבד.",
+ "no-comments": " אין תגובות",
+ "no-comments-desc": "לא ניתן לצפות בתגובות ובפעילויות.",
"computer": "מחשב",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "האם למחוק את תת המשימה?",
+ "confirm-checklist-delete-dialog": "למחוק את רשימת המשימות?",
"copy-card-link-to-clipboard": "העתקת קישור הכרטיס ללוח הגזירים",
+ "linkCardPopup-title": "קישור כרטיס",
+ "searchCardPopup-title": "חיפוש כרטיס",
"copyCardPopup-title": "העתק כרטיס",
"copyChecklistToManyCardsPopup-title": "העתקת תבנית רשימת מטלות למגוון כרטיסים",
"copyChecklistToManyCardsPopup-instructions": "כותרות ותיאורים של כרטיסי יעד בתצורת JSON זו",
@@ -242,7 +250,7 @@
"error-user-notAllowSelf": "אינך יכול להזמין את עצמך",
"error-user-notCreated": "משתמש זה לא נוצר",
"error-username-taken": "המשתמש כבר קיים במערכת",
- "error-email-taken": "כתובת הדוא\"ל כבר נמצאת בשימוש",
+ "error-email-taken": "כתובת הדוא״ל כבר נמצאת בשימוש",
"export-board": "ייצוא לוח",
"filter": "מסנן",
"filter-cards": "סינון כרטיסים",
@@ -254,13 +262,14 @@
"filter-on-desc": "מסנן כרטיסים פעיל בלוח זה. יש ללחוץ כאן לעריכת המסנן.",
"filter-to-selection": "סינון לבחירה",
"advanced-filter-label": "מסנן מתקדם",
- "advanced-filter-description": "המסנן המתקדם מאפשר לך לכתוב מחרוזת שמכילה את הפעולות הבאות: == != <= >= && || ( ) רווח מכהן כמפריד בין הפעולות. ניתן לסנן את כל השדות המותאמים אישית על ידי הקלדת שמם והערך שלהם. למשל: שדה1 == ערך1. לתשומת לבך: אם שדות או ערכים מכילים רווח, יש לעטוף אותם במירכא מכל צד. למשל: 'שדה 1' == 'ערך 1'. ניתן גם לשלב מגוון תנאים. למשל: F1 == V1 || F1 == V2. על פי רוב כל הפעולות מפוענחות משמאל לימין. ניתן לשנות את הסדר על ידי הצבת סוגריים. למשל: ( F1 == V1 && ( F2 == V2 || F2 == V3 ",
+ "advanced-filter-description": "המסנן המתקדם מאפשר לך לכתוב מחרוזת שמכילה את הפעולות הבאות: == != <= >= && || ( ) רווח מכהן כמפריד בין הפעולות. ניתן לסנן את כל השדות המותאמים אישית על ידי הקלדת שמם והערך שלהם. למשל: שדה1 == ערך1. לתשומת לבך: אם שדות או ערכים מכילים רווח, יש לעטוף אותם במירכא מכל צד. למשל: 'שדה 1' == 'ערך 1'. ניתן גם לשלב מגוון תנאים. למשל: F1 == V1 || F1 == V2. על פי רוב כל הפעולות מפוענחות משמאל לימין. ניתן לשנות את הסדר על ידי הצבת סוגריים. למשל: ( F1 == V1 && ( F2 == V2 || F2 == V3. כמו כן, ניתן לחפש בשדה טקסט באופן הבא: F1 == /Tes.*/i",
"fullname": "שם מלא",
"header-logo-title": "חזרה לדף הלוחות שלך.",
"hide-system-messages": "הסתרת הודעות מערכת",
"headerBarCreateBoardPopup-title": "יצירת לוח",
"home": "בית",
"import": "יבוא",
+ "link": "קישור",
"import-board": "ייבוא לוח",
"import-board-c": "יבוא לוח",
"import-board-title-trello": "ייבוא לוח מטרלו",
@@ -315,8 +324,8 @@
"menu": "תפריט",
"move-selection": "העברת הבחירה",
"moveCardPopup-title": "העברת כרטיס",
- "moveCardToBottom-title": "העברת כרטיס לתחתית הרשימה",
- "moveCardToTop-title": "העברת כרטיס לראש הרשימה ",
+ "moveCardToBottom-title": "העברה לתחתית הרשימה",
+ "moveCardToTop-title": "העברה לראש הרשימה ",
"moveSelectionPopup-title": "העברת בחירה",
"multi-selection": "בחירה מרובה",
"multi-selection-on": "בחירה מרובה פועלת",
@@ -438,7 +447,7 @@
"send-smtp-test": "שליחת דוא״ל בדיקה לעצמך",
"invitation-code": "קוד הזמנה",
"email-invite-register-subject": "נשלחה אליך הזמנה מאת __inviter__",
- "email-invite-register-text": "__user__ יקר,\n\nקיבלת הזמנה מאת __inviter__ לשתף פעולה ב־Wekan.\n\nנא ללחוץ על הקישור:\n__url__\n\nקוד ההזמנה שלך הוא: __icode__\n\nתודה.",
+ "email-invite-register-text": "__user__ היקר,\n\nקיבלת הזמנה מאת __inviter__ לשתף פעולה ב־Wekan.\n\nנא ללחוץ על הקישור:\n__url__\n\nקוד ההזמנה שלך הוא: __icode__\n\nתודה.",
"email-smtp-test-subject": "הודעת בדיקה דרך SMTP מאת Wekan",
"email-smtp-test-text": "שלחת הודעת דוא״ל בהצלחה",
"error-invitation-code-not-exist": "קוד ההזמנה אינו קיים",
@@ -482,21 +491,21 @@
"delete-board-confirm-popup": "כל הרשימות, הכרטיסים, התווית והפעולות יימחקו ולא תהיה לך דרך לשחזר את תכני הלוח. אין אפשרות לבטל.",
"boardDeletePopup-title": "למחוק את הלוח?",
"delete-board": "מחיקת לוח",
- "default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
- "queue": "Queue",
- "subtask-settings": "Subtasks Settings",
- "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
- "show-subtasks-field": "Cards can have subtasks",
- "deposit-subtasks-board": "Deposit subtasks to this board:",
- "deposit-subtasks-list": "Landing list for subtasks deposited here:",
- "show-parent-in-minicard": "Show parent in minicard:",
- "prefix-with-full-path": "Prefix with full path",
- "prefix-with-parent": "Prefix with parent",
- "subtext-with-full-path": "Subtext with full path",
- "subtext-with-parent": "Subtext with parent",
- "change-card-parent": "Change card's parent",
- "parent-card": "Parent card",
- "source-board": "Source board",
- "no-parent": "Don't show parent"
+ "default-subtasks-board": "תת־משימות עבור הלוח __board__",
+ "default": "ברירת מחדל",
+ "queue": "תור",
+ "subtask-settings": "הגדרות תתי משימות",
+ "boardSubtaskSettingsPopup-title": "הגדרות תת־משימות בלוח",
+ "show-subtasks-field": "לכרטיסים יכולות להיות תת־משימות",
+ "deposit-subtasks-board": "הפקדת תת־משימות ללוח הזה:",
+ "deposit-subtasks-list": "רשימות נחיתה עבור תת־משימות שהופקדו כאן:",
+ "show-parent-in-minicard": "הצגת ההורה במיני כרטיס:",
+ "prefix-with-full-path": "קידומת עם נתיב מלא",
+ "prefix-with-parent": "קידומת עם הורה",
+ "subtext-with-full-path": "טקסט סמוי עם נתיב מלא",
+ "subtext-with-parent": "טקסט סמוי עם הורה",
+ "change-card-parent": "החלפת הורה הכרטיס",
+ "parent-card": "כרטיס הורה",
+ "source-board": "לוח מקור",
+ "no-parent": "לא להציג את ההורה"
} \ No newline at end of file
diff --git a/i18n/hu.i18n.json b/i18n/hu.i18n.json
index 3e3f3903..270f1754 100644
--- a/i18n/hu.i18n.json
+++ b/i18n/hu.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Mint például „Bakancslista”",
"cancel": "Mégse",
"card-archived": "Ez a kártya a lomtárba került.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Ez a kártya %s hozzászólást tartalmaz.",
"card-delete-notice": "A törlés végleges. Az összes műveletet elveszíti, amely ehhez a kártyához tartozik.",
"card-delete-pop": "Az összes művelet el lesz távolítva a tevékenységlistából, és nem lesz képes többé újra megnyitni a kártyát. Nincs visszaállítási lehetőség.",
@@ -135,6 +136,9 @@
"cards": "Kártyák",
"cards-count": "Kártyák",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Változtatás",
"change-avatar": "Avatár megváltoztatása",
"change-password": "Jelszó megváltoztatása",
@@ -167,10 +171,14 @@
"comment-placeholder": "Megjegyzés írása",
"comment-only": "Csak megjegyzés",
"comment-only-desc": "Csak megjegyzést írhat a kártyákhoz.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Számítógép",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Kártya hivatkozásának másolása a vágólapra",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Kártya másolása",
"copyChecklistToManyCardsPopup-title": "Ellenőrzőlista sablon másolása több kártyára",
"copyChecklistToManyCardsPopup-instructions": "A célkártyák címe és a leírások ebben a JSON formátumban",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Tábla létrehozása",
"home": "Kezdőlap",
"import": "Importálás",
+ "link": "Link",
"import-board": "tábla importálása",
"import-board-c": "Tábla importálása",
"import-board-title-trello": "Tábla importálása a Trello oldalról",
diff --git a/i18n/hy.i18n.json b/i18n/hy.i18n.json
index a56db758..da4584dd 100644
--- a/i18n/hy.i18n.json
+++ b/i18n/hy.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/id.i18n.json b/i18n/id.i18n.json
index 06076aa5..94c9ad79 100644
--- a/i18n/id.i18n.json
+++ b/i18n/id.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Contohnya seperti “Bucket List” ",
"cancel": "Batal",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Kartu ini punya %s komentar",
"card-delete-notice": "Menghapus sama dengan permanen. Anda akan kehilangan semua aksi yang terhubung ke kartu ini",
"card-delete-pop": "Semua aksi akan dihapus dari aktivitas dan anda tidak bisa lagi buka kartu ini",
@@ -135,6 +136,9 @@
"cards": "Daftar Kartu",
"cards-count": "Daftar Kartu",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Ubah",
"change-avatar": "Ubah Avatar",
"change-password": "Ubah Kata Sandi",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Hanya komentar",
"comment-only-desc": "Bisa komen hanya di kartu",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Komputer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Buat Panel",
"home": "Beranda",
"import": "Impor",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Impor panel dari Trello",
diff --git a/i18n/ig.i18n.json b/i18n/ig.i18n.json
index 5b759739..16ddfea4 100644
--- a/i18n/ig.i18n.json
+++ b/i18n/ig.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Gbanwe",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/it.i18n.json b/i18n/it.i18n.json
index 7968967d..ceed7d7a 100644
--- a/i18n/it.i18n.json
+++ b/i18n/it.i18n.json
@@ -2,7 +2,7 @@
"accept": "Accetta",
"act-activity-notify": "[Wekan] Notifiche attività",
"act-addAttachment": "ha allegato __attachment__ a __card__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "ha aggiunto il sotto compito__checklist__in_card__",
"act-addChecklist": "aggiunta checklist __checklist__ a __card__",
"act-addChecklistItem": "aggiunto __checklistItem__ alla checklist __checklist__ di __card__",
"act-addComment": "ha commentato su __card__: __comment__",
@@ -42,7 +42,7 @@
"activity-removed": "rimosso %s da %s",
"activity-sent": "inviato %s a %s",
"activity-unjoined": "ha abbandonato %s",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "aggiunto il sottocompito a 1%s",
"activity-checklist-added": "aggiunta checklist a %s",
"activity-checklist-item-added": "Aggiunto l'elemento checklist a '%s' in %s",
"add": "Aggiungere",
@@ -50,7 +50,7 @@
"add-board": "Aggiungi Bacheca",
"add-card": "Aggiungi Scheda",
"add-swimlane": "Aggiungi Corsia",
- "add-subtask": "Add Subtask",
+ "add-subtask": "Aggiungi sotto-compito",
"add-checklist": "Aggiungi Checklist",
"add-checklist-item": "Aggiungi un elemento alla checklist",
"add-cover": "Aggiungi copertina",
@@ -103,12 +103,13 @@
"boardMenuPopup-title": "Menu bacheca",
"boards": "Bacheche",
"board-view": "Visualizza bacheca",
- "board-view-cal": "Calendar",
+ "board-view-cal": "Calendario",
"board-view-swimlanes": "Corsie",
"board-view-lists": "Liste",
"bucket-example": "Per esempio come \"una lista di cose da fare\"",
"cancel": "Cancella",
"card-archived": "Questa scheda è stata spostata nel cestino.",
+ "board-archived": "Questa bacheca è stata spostata nel cestino.",
"card-comments-title": "Questa scheda ha %s commenti.",
"card-delete-notice": "L'eliminazione è permanente. Tutte le azioni associate a questa scheda andranno perse.",
"card-delete-pop": "Tutte le azioni saranno rimosse dal flusso attività e non sarai in grado di riaprire la scheda. Non potrai tornare indietro.",
@@ -134,7 +135,10 @@
"cardMorePopup-title": "Altro",
"cards": "Schede",
"cards-count": "Schede",
- "casSignIn": "Sign In with CAS",
+ "casSignIn": "Entra con CAS",
+ "cardType-card": "Scheda",
+ "cardType-linkedCard": "Scheda collegata",
+ "cardType-linkedBoard": "Bacheca collegata",
"change": "Cambia",
"change-avatar": "Cambia avatar",
"change-password": "Cambia password",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "Cambia password",
"changePermissionsPopup-title": "Cambia permessi",
"changeSettingsPopup-title": "Cambia impostazioni",
- "subtasks": "Subtasks",
+ "subtasks": "Sotto-compiti",
"checklists": "Checklist",
"click-to-star": "Clicca per stellare questa bacheca",
"click-to-unstar": "Clicca per togliere la stella da questa bacheca",
@@ -167,10 +171,14 @@
"comment-placeholder": "Scrivi Commento",
"comment-only": "Solo commenti",
"comment-only-desc": "Puoi commentare solo le schede.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "Sei sicuro di voler eliminare il sotto-compito?",
+ "confirm-checklist-delete-dialog": "Sei sicuro di voler eliminare la checklist?",
"copy-card-link-to-clipboard": "Copia link della scheda sulla clipboard",
+ "linkCardPopup-title": "Collega scheda",
+ "searchCardPopup-title": "Cerca scheda",
"copyCardPopup-title": "Copia Scheda",
"copyChecklistToManyCardsPopup-title": "Copia template checklist su più schede",
"copyChecklistToManyCardsPopup-instructions": "Titolo e la descrizione della scheda di destinazione in questo formato JSON",
@@ -254,13 +262,14 @@
"filter-on-desc": "Stai filtrando le schede su questa bacheca. Clicca qui per modificare il filtro,",
"filter-to-selection": "Seleziona",
"advanced-filter-label": "Filtro avanzato",
- "advanced-filter-description": "Advanced Filter allows to write a string containing following operators: == != <= >= && || ( ) A space is used as a separator between the Operators. You can filter for all Custom Fields by typing their names and values. For Example: Field1 == Value1. Note: If fields or values contains spaces, you need to encapsulate them into single quotes. For Example: 'Field 1' == 'Value 1'. For single control characters (' \\/) to be skipped, you can use \\. For example: Field1 == I\\'m. Also you can combine multiple conditions. For Example: F1 == V1 || F1 == V2. Normally all operators are interpreted from left to right. You can change the order by placing brackets. For Example: F1 == V1 && ( F2 == V2 || F2 == V3 ). Also you can search text fields using regex: F1 == /Tes.*/i",
+ "advanced-filter-description": "Il filtro avanzato permette di scrivere una stringa contenente i seguenti operatori: == != <= >= && || ( ) Uno spazio è usato come separatore tra gli operatori. Si può filtrare per tutti i campi personalizzati, scrivendo i loro nomi e valori. Per esempio: Campo1 == Valore1. Nota: Se i campi o i valori contengono spazi, è necessario incapsularli all'interno di paici singoli. Per esempio: 'Campo 1' == 'Valore 1'. Per i singoli caratteri di controllo (' V) che devono essere ignorati, si può usare \\. Per esempio: C1 == Campo1 == L'\\ho. Si possono anche combinare condizioni multiple. Per esempio: C1 == V1 || C1 ==V2. Di norma tutti gli operatori vengono lettti da sinistra a destra. Si può cambiare l'ordine posizionando delle parentesi. Per esempio: C1 == V1 && ( C2 == V2 || C2 == V3) . Inoltre è possibile cercare nei campi di testo usando le espressioni regolari (n.d.t. regex): F1 ==/Tes.*/i",
"fullname": "Nome completo",
"header-logo-title": "Torna alla tua bacheca.",
"hide-system-messages": "Nascondi i messaggi di sistema",
"headerBarCreateBoardPopup-title": "Crea bacheca",
"home": "Home",
"import": "Importa",
+ "link": "Collegamento",
"import-board": "Importa bacheca",
"import-board-c": "Importa bacheca",
"import-board-title-trello": "Importa una bacheca da Trello",
@@ -482,21 +491,21 @@
"delete-board-confirm-popup": "Tutte le liste, schede, etichette e azioni saranno rimosse e non sarai più in grado di recuperare il contenuto della bacheca. L'azione non è annullabile.",
"boardDeletePopup-title": "Eliminare la bacheca?",
"delete-board": "Elimina bacheca",
- "default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
- "queue": "Queue",
- "subtask-settings": "Subtasks Settings",
- "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
- "show-subtasks-field": "Cards can have subtasks",
- "deposit-subtasks-board": "Deposit subtasks to this board:",
- "deposit-subtasks-list": "Landing list for subtasks deposited here:",
- "show-parent-in-minicard": "Show parent in minicard:",
- "prefix-with-full-path": "Prefix with full path",
- "prefix-with-parent": "Prefix with parent",
- "subtext-with-full-path": "Subtext with full path",
- "subtext-with-parent": "Subtext with parent",
- "change-card-parent": "Change card's parent",
- "parent-card": "Parent card",
- "source-board": "Source board",
- "no-parent": "Don't show parent"
+ "default-subtasks-board": "Sottocompiti per la bacheca __board__",
+ "default": "Predefinito",
+ "queue": "Coda",
+ "subtask-settings": "Impostazioni sotto-compiti",
+ "boardSubtaskSettingsPopup-title": "Impostazioni sotto-compiti della bacheca",
+ "show-subtasks-field": "Le schede posso avere dei sotto-compiti",
+ "deposit-subtasks-board": "Deposita i sotto compiti in questa bacheca",
+ "deposit-subtasks-list": "Lista di destinaizoni per questi sotto-compiti",
+ "show-parent-in-minicard": "Mostra genirotri nelle mini schede:",
+ "prefix-with-full-path": "Prefisso con percorso completo",
+ "prefix-with-parent": "Prefisso con genitore",
+ "subtext-with-full-path": "Sottotesto con percorso completo",
+ "subtext-with-parent": "Sotto-testo con genitore",
+ "change-card-parent": "Cambia la scheda genitore",
+ "parent-card": "Scheda genitore",
+ "source-board": "Bacheca d'origine",
+ "no-parent": "Non mostrare i genitori"
} \ No newline at end of file
diff --git a/i18n/ja.i18n.json b/i18n/ja.i18n.json
index c70b0d35..fc1b8ace 100644
--- a/i18n/ja.i18n.json
+++ b/i18n/ja.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "例:バケットリスト",
"cancel": "キャンセル",
"card-archived": "このカードはゴミ箱に移動されます",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "%s 件のコメントがあります。",
"card-delete-notice": "削除は取り消しできません。このカードに関係するすべてのアクションがなくなります。",
"card-delete-pop": "すべての内容がアクティビティから削除されます。この削除は元に戻すことができません。",
@@ -135,6 +136,9 @@
"cards": "カード",
"cards-count": "カード",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "変更",
"change-avatar": "アバターの変更",
"change-password": "パスワードの変更",
@@ -167,10 +171,14 @@
"comment-placeholder": "コメントを書く",
"comment-only": "コメントのみ",
"comment-only-desc": "カードにのみコメント可能",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "コンピューター",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "カードへのリンクをクリップボードにコピー",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "カードをコピー",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "ボードの作成",
"home": "ホーム",
"import": "インポート",
+ "link": "Link",
"import-board": "ボードをインポート",
"import-board-c": "ボードをインポート",
"import-board-title-trello": "Trelloからボードをインポート",
diff --git a/i18n/ka.i18n.json b/i18n/ka.i18n.json
index f2b32e0f..02d70a38 100644
--- a/i18n/ka.i18n.json
+++ b/i18n/ka.i18n.json
@@ -1,493 +1,502 @@
{
- "accept": "Accept",
- "act-activity-notify": "[Wekan] Activity Notification",
- "act-addAttachment": "attached __attachment__ to __card__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
- "act-addChecklist": "added checklist __checklist__ to __card__",
- "act-addChecklistItem": "added __checklistItem__ to checklist __checklist__ on __card__",
- "act-addComment": "commented on __card__: __comment__",
- "act-createBoard": "created __board__",
- "act-createCard": "added __card__ to __list__",
- "act-createCustomField": "created custom field __customField__",
- "act-createList": "added __list__ to __board__",
- "act-addBoardMember": "added __member__ to __board__",
- "act-archivedBoard": "__board__ moved to Recycle Bin",
- "act-archivedCard": "__card__ moved to Recycle Bin",
- "act-archivedList": "__list__ moved to Recycle Bin",
- "act-archivedSwimlane": "__swimlane__ moved to Recycle Bin",
- "act-importBoard": "imported __board__",
- "act-importCard": "imported __card__",
- "act-importList": "imported __list__",
- "act-joinMember": "added __member__ to __card__",
- "act-moveCard": "moved __card__ from __oldList__ to __list__",
- "act-removeBoardMember": "removed __member__ from __board__",
- "act-restoredCard": "restored __card__ to __board__",
- "act-unjoinMember": "removed __member__ from __card__",
- "act-withBoardTitle": "[Wekan] __board__",
- "act-withCardTitle": "[__board__] __card__",
- "actions": "Actions",
- "activities": "Activities",
- "activity": "Activity",
- "activity-added": "added %s to %s",
- "activity-archived": "%s moved to Recycle Bin",
- "activity-attached": "attached %s to %s",
- "activity-created": "created %s",
+ "accept": "დათანხმება",
+ "act-activity-notify": "[ვეკანი] აქტივობის შეტყობინება",
+ "act-addAttachment": "მიბმულია__მიბმა __ბარათზე__",
+ "act-addSubtask": "დამატებულია ქვესაქმიანობა__ჩამონათვალი__ ბარათზე__",
+ "act-addChecklist": "დაამატა ჩამონათვალი__ჩამონათვალი__ ბარათზე__",
+ "act-addChecklistItem": "დაამატა __ჩამონათვალის ელემენტი__ ჩამონათვალში __ჩამონათვალი __ბარათზე__",
+ "act-addComment": "დააკომენტარა__ბარათზე__: __კომენტარი__",
+ "act-createBoard": "შექმნილია __დაფა__",
+ "act-createCard": "დაამატა __ბარათი__ ჩამონათვალში__",
+ "act-createCustomField": "შექმნა სტანდარტული ველი __სტანდარტული ველი__",
+ "act-createList": "დაამატა __ჩამონათვალი__ დაფაზე__",
+ "act-addBoardMember": "დაამატა __წევრი__ დაფაზე__",
+ "act-archivedBoard": "__board__ გადატანილია სანაგვე ურნაში",
+ "act-archivedCard": "__ბარათი__ გადატანილია სანაგვე ურნაში",
+ "act-archivedList": "__list__ გადატანილია სანაგვე ურნაში",
+ "act-archivedSwimlane": "__swimlane__ გადატანილია სანაგვე ურნაში",
+ "act-importBoard": "იმპორტირებულია__დაფა__",
+ "act-importCard": "იმპორტირებულია __ბარათი__",
+ "act-importList": "იმპორტირებულია __სია__",
+ "act-joinMember": "დაამატა __წევრი__ ბარათზე__",
+ "act-moveCard": "გადაიტანა __ბარათი __oldList__ დან__ ჩამონათვალ__ში__",
+ "act-removeBoardMember": "წაშალა__წევრი__ დაფიდან__",
+ "act-restoredCard": "აღადგინა __ბარათი __დაფა__ზე__",
+ "act-unjoinMember": "წაშალა__წევრი__ ბარათი __დან__",
+ "act-withBoardTitle": "[Wekan] __დაფა__",
+ "act-withCardTitle": "[__დაფა__] __ბარათი__",
+ "actions": "მოქმედებები",
+ "activities": "აქტივეობები",
+ "activity": "აქტივობები",
+ "activity-added": "დამატებულია %s ზე %s",
+ "activity-archived": "%s-მა გადაინაცვლა წაშლილებში",
+ "activity-attached": "მიბმულია %s %s-დან",
+ "activity-created": "შექმნილია %s",
"activity-customfield-created": "created custom field %s",
"activity-excluded": "excluded %s from %s",
"activity-imported": "imported %s into %s from %s",
- "activity-imported-board": "imported %s from %s",
- "activity-joined": "joined %s",
+ "activity-imported-board": "იმპორტირებულია%s %s-დან",
+ "activity-joined": "შეუერთდა %s",
"activity-moved": "moved %s from %s to %s",
- "activity-on": "on %s",
- "activity-removed": "removed %s from %s",
- "activity-sent": "sent %s to %s",
- "activity-unjoined": "unjoined %s",
- "activity-subtask-added": "added subtask to %s",
- "activity-checklist-added": "added checklist to %s",
- "activity-checklist-item-added": "added checklist item to '%s' in %s",
- "add": "Add",
- "add-attachment": "Add Attachment",
- "add-board": "Add Board",
- "add-card": "Add Card",
- "add-swimlane": "Add Swimlane",
- "add-subtask": "Add Subtask",
- "add-checklist": "Add Checklist",
- "add-checklist-item": "Add an item to checklist",
- "add-cover": "Add Cover",
- "add-label": "Add Label",
- "add-list": "Add List",
- "add-members": "Add Members",
- "added": "Added",
- "addMemberPopup-title": "Members",
- "admin": "Admin",
- "admin-desc": "Can view and edit cards, remove members, and change settings for the board.",
- "admin-announcement": "Announcement",
- "admin-announcement-active": "Active System-Wide Announcement",
- "admin-announcement-title": "Announcement from Administrator",
- "all-boards": "All boards",
- "and-n-other-card": "And __count__ other card",
- "and-n-other-card_plural": "And __count__ other cards",
- "apply": "Apply",
- "app-is-offline": "Wekan is loading, please wait. Refreshing the page will cause data loss. If Wekan does not load, please check that Wekan server has not stopped.",
- "archive": "Move to Recycle Bin",
- "archive-all": "Move All to Recycle Bin",
- "archive-board": "Move Board to Recycle Bin",
- "archive-card": "Move Card to Recycle Bin",
- "archive-list": "Move List to Recycle Bin",
- "archive-swimlane": "Move Swimlane to Recycle Bin",
- "archive-selection": "Move selection to Recycle Bin",
- "archiveBoardPopup-title": "Move Board to Recycle Bin?",
- "archived-items": "Recycle Bin",
- "archived-boards": "Boards in Recycle Bin",
- "restore-board": "Restore Board",
- "no-archived-boards": "No Boards in Recycle Bin.",
- "archives": "Recycle Bin",
- "assign-member": "Assign member",
- "attached": "attached",
- "attachment": "Attachment",
- "attachment-delete-pop": "Deleting an attachment is permanent. There is no undo.",
- "attachmentDeletePopup-title": "Delete Attachment?",
- "attachments": "Attachments",
- "auto-watch": "Automatically watch boards when they are created",
- "avatar-too-big": "The avatar is too large (70KB max)",
- "back": "Back",
- "board-change-color": "Change color",
- "board-nb-stars": "%s stars",
- "board-not-found": "Board not found",
- "board-private-info": "This board will be <strong>private</strong>.",
- "board-public-info": "This board will be <strong>public</strong>.",
- "boardChangeColorPopup-title": "Change Board Background",
- "boardChangeTitlePopup-title": "Rename Board",
- "boardChangeVisibilityPopup-title": "Change Visibility",
- "boardChangeWatchPopup-title": "Change Watch",
- "boardMenuPopup-title": "Board Menu",
- "boards": "Boards",
- "board-view": "Board View",
- "board-view-cal": "Calendar",
- "board-view-swimlanes": "Swimlanes",
- "board-view-lists": "Lists",
- "bucket-example": "Like “Bucket List” for example",
- "cancel": "Cancel",
- "card-archived": "This card is moved to Recycle Bin.",
- "card-comments-title": "This card has %s comment.",
- "card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
- "card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
- "card-delete-suggest-archive": "You can move a card to Recycle Bin to remove it from the board and preserve the activity.",
- "card-due": "Due",
- "card-due-on": "Due on",
- "card-spent": "Spent Time",
- "card-edit-attachments": "Edit attachments",
- "card-edit-custom-fields": "Edit custom fields",
- "card-edit-labels": "Edit labels",
- "card-edit-members": "Edit members",
- "card-labels-title": "Change the labels for the card.",
- "card-members-title": "Add or remove members of the board from the card.",
- "card-start": "Start",
- "card-start-on": "Starts on",
- "cardAttachmentsPopup-title": "Attach From",
- "cardCustomField-datePopup-title": "Change date",
- "cardCustomFieldsPopup-title": "Edit custom fields",
- "cardDeletePopup-title": "Delete Card?",
- "cardDetailsActionsPopup-title": "Card Actions",
- "cardLabelsPopup-title": "Labels",
- "cardMembersPopup-title": "Members",
- "cardMorePopup-title": "More",
- "cards": "Cards",
- "cards-count": "Cards",
- "casSignIn": "Sign In with CAS",
- "change": "Change",
- "change-avatar": "Change Avatar",
- "change-password": "Change Password",
- "change-permissions": "Change permissions",
- "change-settings": "Change Settings",
- "changeAvatarPopup-title": "Change Avatar",
- "changeLanguagePopup-title": "Change Language",
- "changePasswordPopup-title": "Change Password",
- "changePermissionsPopup-title": "Change Permissions",
- "changeSettingsPopup-title": "Change Settings",
- "subtasks": "Subtasks",
- "checklists": "Checklists",
- "click-to-star": "Click to star this board.",
- "click-to-unstar": "Click to unstar this board.",
- "clipboard": "Clipboard or drag & drop",
- "close": "Close",
- "close-board": "Close Board",
+ "activity-on": " %s-ზე",
+ "activity-removed": "წაიშალა %s %s-დან",
+ "activity-sent": "გაიგზავნა %s %s-ში",
+ "activity-unjoined": "არ შემოუერთდა %s",
+ "activity-subtask-added": "დაამატა ქვესაქმიანობა %s",
+ "activity-checklist-added": "დაემატა ჩამონათვალი %s-ს",
+ "activity-checklist-item-added": "დამატებულია ჩამონათვალის ელემენტები '%s' %s-ში",
+ "add": "დამატება",
+ "add-attachment": "მიბმული ფაილის დამატება",
+ "add-board": "დაფის დამატება",
+ "add-card": "ბარათის დამატება",
+ "add-swimlane": "ბილიკის დამატება",
+ "add-subtask": "ქვესაქმიანობის დამატება",
+ "add-checklist": "კატალოგის დამატება",
+ "add-checklist-item": "დაამატეთ საგანი ჩამონათვალს",
+ "add-cover": "გარეკანის დამატება",
+ "add-label": "ნიშნის დამატება",
+ "add-list": "ჩამონათვალის დამატება",
+ "add-members": "წევრების დამატება",
+ "added": "-მა დაამატა",
+ "addMemberPopup-title": "წევრები",
+ "admin": "ადმინი",
+ "admin-desc": "შეუძლია ნახოს და შეასწოროს ბარათები, წაშალოს წევრები და შეცვალოს დაფის პარამეტრები. ",
+ "admin-announcement": "განცხადება",
+ "admin-announcement-active": "აქტიური სისტემა-ფართო განცხადება",
+ "admin-announcement-title": "შეტყობინება ადმინისტრატორისთვის",
+ "all-boards": "ყველა დაფა",
+ "and-n-other-card": "და __count__ სხვა ბარათი",
+ "and-n-other-card_plural": "და __count__ სხვა ბარათები",
+ "apply": "გამოყენება",
+ "app-is-offline": "Wekan იტვირთება, გთხოვთ დაელოდოთ. გვერდის განახლებამ შეიძლება გამოიწვიოს მონაცემების დაკარგვა. იმ შემთხვევაში თუ Wekan არ იტვირთება, შეამოწმეთ სერვერი მუშაობს თუ არა. ",
+ "archive": "სანაგვე ურნაში გადატანა",
+ "archive-all": "ყველას სანაგვე ურნაში გადატანა",
+ "archive-board": "გადავიტანოთ დაფა სანაგვე ურნაში ",
+ "archive-card": "გადავიტანოთ ბარათი სანაგვე ურნაში ",
+ "archive-list": "გავიტანოთ ჩამონათვალი სანაგვე ურნაში ",
+ "archive-swimlane": "გადავიტანოთ ბილიკი სანაგვე ურნაში ",
+ "archive-selection": "გადავიტანოთ მონიშნული სანაგვე ურნაში ",
+ "archiveBoardPopup-title": "გადავიტანოთ დაფა სანაგვე ურნაში ",
+ "archived-items": "სანაგვე ურნა",
+ "archived-boards": "დაფები სანაგვე ურნაში ",
+ "restore-board": "ბარათის აღდგენა",
+ "no-archived-boards": "სანაგვე ურნაში დაფები არ მოიძებნა.",
+ "archives": "სანაგვე ურნა",
+ "assign-member": "უფლებამოსილი წევრი",
+ "attached": "მიბმული",
+ "attachment": "მიბმული ფიალი",
+ "attachment-delete-pop": "მიბმული ფაილის წაშლა მუდმივია. შეუძლებელია მისი უკან დაბრუნება. ",
+ "attachmentDeletePopup-title": "გსურთ მიბმული ფაილის წაშლა? ",
+ "attachments": "მიბმული ფაილები",
+ "auto-watch": "დაფის ავტომატური ნახვა მას შემდეგ რაც ის შეიქმნება",
+ "avatar-too-big": "დიდი მოცულობის სურათი (მაქსიმუმ 70KB)",
+ "back": "უკან",
+ "board-change-color": "ფერის შეცვლა",
+ "board-nb-stars": "%s ვარსკვლავი",
+ "board-not-found": "დაფა არ მოიძებნა",
+ "board-private-info": "ეს დაფა იქნება <strong>პირადი</strong>.",
+ "board-public-info": "ეს დაფა იქნება <strong>საჯარო</strong>.",
+ "boardChangeColorPopup-title": "დაფის ფონის ცვლილება",
+ "boardChangeTitlePopup-title": "დაფის სახელის ცვლილება",
+ "boardChangeVisibilityPopup-title": "ხილვადობის შეცვლა",
+ "boardChangeWatchPopup-title": "საათის შეცვლა",
+ "boardMenuPopup-title": "დაფის მენიუ",
+ "boards": "დაფები",
+ "board-view": "დაფის ნახვა",
+ "board-view-cal": "კალენდარი",
+ "board-view-swimlanes": "ბილიკები",
+ "board-view-lists": "ჩამონათვალი",
+ "bucket-example": "მაგალითად “Bucket List” ",
+ "cancel": "გაუქმება",
+ "card-archived": "ბარათი გადატანილია სანაგვე ურნაში ",
+ "board-archived": "This board is moved to Recycle Bin.",
+ "card-comments-title": "ამ ბარათს ჰქონდა%s კომენტარი.",
+ "card-delete-notice": "წაშლის შემთხვევაში ამ ბარათთან ასცირებული ყველა მოქმედება დაიკარგება.",
+ "card-delete-pop": "ყველა მოქმედება წაიშლება აქტივობების ველიდან და თქვენ აღარ შეგეძლებათ ბარათის ხელახლა გახსნა. დაბრუნება შეუძლებელია.",
+ "card-delete-suggest-archive": "თქვენ შეგიძლიათ გადაიტანოთ ბარათი სანაგვე ურნაში რათა წაშალოთ ის დაფიდან და დაიცვათ აქტივობა. ",
+ "card-due": "საბოლოო ვადა ",
+ "card-due-on": "საბოლოო ვადა",
+ "card-spent": "დახარჯული დრო",
+ "card-edit-attachments": "მიბმული ფაილის შესწორება",
+ "card-edit-custom-fields": "მომხმარებლის ველის შესწორება",
+ "card-edit-labels": "ნიშნის შესწორება",
+ "card-edit-members": "მომხმარებლების შესწორება",
+ "card-labels-title": "ნიშნის შეცვლა ბარათისთვის.",
+ "card-members-title": "დაამატეთ ან წაშალეთ დაფის წევრი ბარათიდან. ",
+ "card-start": "დაწყება",
+ "card-start-on": "დაიწყება",
+ "cardAttachmentsPopup-title": "მიბმა შემდეგი წყაროდან: ",
+ "cardCustomField-datePopup-title": "დროის ცვლილება",
+ "cardCustomFieldsPopup-title": "მომხმარებლის ველის შესწორება",
+ "cardDeletePopup-title": "წავშალოთ ბარათი? ",
+ "cardDetailsActionsPopup-title": "ბარათის მოქმედებები",
+ "cardLabelsPopup-title": "ნიშნები",
+ "cardMembersPopup-title": "წევრები",
+ "cardMorePopup-title": "მეტი",
+ "cards": "ბარათები",
+ "cards-count": "ბარათები",
+ "casSignIn": "შესვლა CAS-ით",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
+ "change": "ცვლილება",
+ "change-avatar": "სურათის შეცვლა",
+ "change-password": "პაროლის შეცვლა",
+ "change-permissions": "პარამეტრების შეცვლა",
+ "change-settings": "პარამეტრების შეცვლა",
+ "changeAvatarPopup-title": "სურათის შეცვლა",
+ "changeLanguagePopup-title": "ენის შეცვლა",
+ "changePasswordPopup-title": "პაროლის შეცვლა",
+ "changePermissionsPopup-title": "უფლებების შეცვლა",
+ "changeSettingsPopup-title": "პარამეტრების შეცვლა",
+ "subtasks": "ქვეამოცანა",
+ "checklists": "კატალოგი",
+ "click-to-star": "დააჭირეთ დაფის ვარსკვლავით მოსანიშნად",
+ "click-to-unstar": "დააკლიკეთ დაფიდან ვარსკვლავის მოსახსნელად. ",
+ "clipboard": "Clipboard ან drag & drop",
+ "close": "დახურვა",
+ "close-board": "დაფის დახურვა",
"close-board-pop": "You will be able to restore the board by clicking the “Recycle Bin” button from the home header.",
- "color-black": "black",
- "color-blue": "blue",
- "color-green": "green",
- "color-lime": "lime",
- "color-orange": "orange",
- "color-pink": "pink",
- "color-purple": "purple",
- "color-red": "red",
- "color-sky": "sky",
- "color-yellow": "yellow",
- "comment": "Comment",
- "comment-placeholder": "Write Comment",
- "comment-only": "Comment only",
- "comment-only-desc": "Can comment on cards only.",
- "computer": "Computer",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
- "copy-card-link-to-clipboard": "Copy card link to clipboard",
- "copyCardPopup-title": "Copy Card",
+ "color-black": "შავი",
+ "color-blue": "ლურჯი",
+ "color-green": "მწვანე",
+ "color-lime": "ღია ყვითელი",
+ "color-orange": "ნარინჯისფერი",
+ "color-pink": "ვარდისფერი",
+ "color-purple": "იასამნისფერი",
+ "color-red": "წითელი ",
+ "color-sky": "ცისფერი",
+ "color-yellow": "ყვითელი",
+ "comment": "კომენტარი",
+ "comment-placeholder": "დაწერეთ კომენტარი",
+ "comment-only": "მხოლოდ კომენტარები",
+ "comment-only-desc": "თქვენ შეგიძლიათ კომენტარის გაკეთება მხოლოდ ბარათებზე.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
+ "computer": "კომპიუტერი",
+ "confirm-subtask-delete-dialog": "დარწმუნებული ხართ, რომ გსურთ ქვესაქმიანობის წაშლა? ",
+ "confirm-checklist-delete-dialog": "დარწმუნებული ხართ, რომ გსურთ კატალოგის წაშლა ? ",
+ "copy-card-link-to-clipboard": "დააკოპირეთ ბარათის ბმული clipboard-ზე",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
+ "copyCardPopup-title": "ბარათის ასლი",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
- "copyChecklistToManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]",
- "create": "Create",
- "createBoardPopup-title": "Create Board",
- "chooseBoardSourcePopup-title": "Import board",
- "createLabelPopup-title": "Create Label",
- "createCustomField": "Create Field",
- "createCustomFieldPopup-title": "Create Field",
- "current": "current",
- "custom-field-delete-pop": "There is no undo. This will remove this custom field from all cards and destroy its history.",
- "custom-field-checkbox": "Checkbox",
- "custom-field-date": "Date",
- "custom-field-dropdown": "Dropdown List",
- "custom-field-dropdown-none": "(none)",
- "custom-field-dropdown-options": "List Options",
- "custom-field-dropdown-options-placeholder": "Press enter to add more options",
- "custom-field-dropdown-unknown": "(unknown)",
- "custom-field-number": "Number",
- "custom-field-text": "Text",
- "custom-fields": "Custom Fields",
- "date": "Date",
- "decline": "Decline",
- "default-avatar": "Default avatar",
- "delete": "Delete",
- "deleteCustomFieldPopup-title": "Delete Custom Field?",
- "deleteLabelPopup-title": "Delete Label?",
- "description": "Description",
- "disambiguateMultiLabelPopup-title": "Disambiguate Label Action",
- "disambiguateMultiMemberPopup-title": "Disambiguate Member Action",
- "discard": "Discard",
- "done": "Done",
- "download": "Download",
- "edit": "Edit",
- "edit-avatar": "Change Avatar",
- "edit-profile": "Edit Profile",
- "edit-wip-limit": "Edit WIP Limit",
- "soft-wip-limit": "Soft WIP Limit",
- "editCardStartDatePopup-title": "Change start date",
- "editCardDueDatePopup-title": "Change due date",
- "editCustomFieldPopup-title": "Edit Field",
- "editCardSpentTimePopup-title": "Change spent time",
- "editLabelPopup-title": "Change Label",
- "editNotificationPopup-title": "Edit Notification",
- "editProfilePopup-title": "Edit Profile",
- "email": "Email",
+ "copyChecklistToManyCardsPopup-format": "[ {\"სათაური\": \"პირველი ბარათის სათაური\", \"აღწერა\":\"პირველი ბარათის აღწერა\"}, {\"სათაური\":\"მეორე ბარათის სათაური\",\"აღწერა\":\"მეორე ბარათის აღწერა\"},{\"სათაური\":\"ბოლო ბარათის სათაური\",\"აღწერა\":\"ბოლო ბარათის აღწერა\"} ]",
+ "create": "შექმნა",
+ "createBoardPopup-title": "დაფის შექმნა",
+ "chooseBoardSourcePopup-title": "დაფის იმპორტი",
+ "createLabelPopup-title": "ნიშნის შექმნა",
+ "createCustomField": "ველის შექმნა",
+ "createCustomFieldPopup-title": "ველის შექმნა",
+ "current": "მიმდინარე",
+ "custom-field-delete-pop": "ქმედება გამოიწვევს მომხმარებლის ველის წაშლას ყველა ბარათიდან და გაანადგურებს მის ისტორიას, რის შემდეგაც შეუძლებელი იქნება მისი უკან დაბრუნება. ",
+ "custom-field-checkbox": "მოსანიშნი გრაფა",
+ "custom-field-date": "თარიღი",
+ "custom-field-dropdown": "ჩამოსაშლელი სია",
+ "custom-field-dropdown-none": "(ცარიელი)",
+ "custom-field-dropdown-options": "პარამეტრების სია",
+ "custom-field-dropdown-options-placeholder": "დამატებითი პარამეტრების სანახავად დააჭირეთ enter-ს. ",
+ "custom-field-dropdown-unknown": "(უცნობი)",
+ "custom-field-number": "რიცხვი",
+ "custom-field-text": "ტექსტი",
+ "custom-fields": "მომხმარებლის ველი",
+ "date": "თარიღი",
+ "decline": "უარყოფა",
+ "default-avatar": "სტანდარტული ავატარი",
+ "delete": "წაშლა",
+ "deleteCustomFieldPopup-title": "წავშალოთ მომხმარებლის ველი? ",
+ "deleteLabelPopup-title": "ნამდვილად გსურთ ნიშნის წაშლა? ",
+ "description": "აღწერა",
+ "disambiguateMultiLabelPopup-title": "გაუგებარი ნიშნის მოქმედება",
+ "disambiguateMultiMemberPopup-title": "გაუგებარი წევრის მოქმედება",
+ "discard": "უარყოფა",
+ "done": "დასრულებული",
+ "download": "ჩამოტვირთვა",
+ "edit": "შესწორება",
+ "edit-avatar": "სურათის შეცვლა",
+ "edit-profile": "პროფილის შესწორება",
+ "edit-wip-limit": " WIP ლიმიტის შესწორება",
+ "soft-wip-limit": "მსუბუქი WIP შეზღუდვა ",
+ "editCardStartDatePopup-title": "დაწყების დროის შეცვლა",
+ "editCardDueDatePopup-title": "შეცვალეთ დედლაინი",
+ "editCustomFieldPopup-title": "ველების შესწორება",
+ "editCardSpentTimePopup-title": "დახარჯული დროის შეცვლა",
+ "editLabelPopup-title": "ნიშნის შეცვლა",
+ "editNotificationPopup-title": "შეტყობინებების შესწორება",
+ "editProfilePopup-title": "პროფილის შესწორება",
+ "email": "ელ.ფოსტა",
"email-enrollAccount-subject": "An account created for you on __siteName__",
- "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.",
- "email-fail": "Sending email failed",
- "email-fail-text": "Error trying to send email",
- "email-invalid": "Invalid email",
- "email-invite": "Invite via Email",
- "email-invite-subject": "__inviter__ sent you an invitation",
- "email-invite-text": "Dear __user__,\n\n__inviter__ invites you to join board \"__board__\" for collaborations.\n\nPlease follow the link below:\n\n__url__\n\nThanks.",
- "email-resetPassword-subject": "Reset your password on __siteName__",
- "email-resetPassword-text": "Hello __user__,\n\nTo reset your password, simply click the link below.\n\n__url__\n\nThanks.",
- "email-sent": "Email sent",
- "email-verifyEmail-subject": "Verify your email address on __siteName__",
- "email-verifyEmail-text": "Hello __user__,\n\nTo verify your account email, simply click the link below.\n\n__url__\n\nThanks.",
- "enable-wip-limit": "Enable WIP Limit",
- "error-board-doesNotExist": "This board does not exist",
- "error-board-notAdmin": "You need to be admin of this board to do that",
- "error-board-notAMember": "You need to be a member of this board to do that",
- "error-json-malformed": "Your text is not valid JSON",
- "error-json-schema": "Your JSON data does not include the proper information in the correct format",
- "error-list-doesNotExist": "This list does not exist",
- "error-user-doesNotExist": "This user does not exist",
- "error-user-notAllowSelf": "You can not invite yourself",
- "error-user-notCreated": "This user is not created",
- "error-username-taken": "This username is already taken",
- "error-email-taken": "Email has already been taken",
- "export-board": "Export board",
- "filter": "Filter",
- "filter-cards": "Filter Cards",
- "filter-clear": "Clear filter",
- "filter-no-label": "No label",
- "filter-no-member": "No member",
- "filter-no-custom-fields": "No Custom Fields",
- "filter-on": "Filter is on",
- "filter-on-desc": "You are filtering cards on this board. Click here to edit filter.",
- "filter-to-selection": "Filter to selection",
- "advanced-filter-label": "Advanced Filter",
- "advanced-filter-description": "Advanced Filter allows to write a string containing following operators: == != <= >= && || ( ) A space is used as a separator between the Operators. You can filter for all Custom Fields by typing their names and values. For Example: Field1 == Value1. Note: If fields or values contains spaces, you need to encapsulate them into single quotes. For Example: 'Field 1' == 'Value 1'. For single control characters (' \\/) to be skipped, you can use \\. For example: Field1 == I\\'m. Also you can combine multiple conditions. For Example: F1 == V1 || F1 == V2. Normally all operators are interpreted from left to right. You can change the order by placing brackets. For Example: F1 == V1 && ( F2 == V2 || F2 == V3 ). Also you can search text fields using regex: F1 == /Tes.*/i",
- "fullname": "Full Name",
- "header-logo-title": "Go back to your boards page.",
- "hide-system-messages": "Hide system messages",
- "headerBarCreateBoardPopup-title": "Create Board",
- "home": "Home",
- "import": "Import",
- "import-board": "import board",
- "import-board-c": "Import board",
- "import-board-title-trello": "Import board from Trello",
- "import-board-title-wekan": "Import board from Wekan",
- "import-sandstorm-warning": "Imported board will delete all existing data on board and replace it with imported board.",
- "from-trello": "From Trello",
- "from-wekan": "From Wekan",
- "import-board-instruction-trello": "In your Trello board, go to 'Menu', then 'More', 'Print and Export', 'Export JSON', and copy the resulting text.",
- "import-board-instruction-wekan": "In your Wekan board, go to 'Menu', then 'Export board', and copy the text in the downloaded file.",
- "import-json-placeholder": "Paste your valid JSON data here",
- "import-map-members": "Map members",
- "import-members-map": "Your imported board has some members. Please map the members you want to import to Wekan users",
- "import-show-user-mapping": "Review members mapping",
- "import-user-select": "Pick the Wekan user you want to use as this member",
- "importMapMembersAddPopup-title": "Select Wekan member",
- "info": "Version",
- "initials": "Initials",
- "invalid-date": "Invalid date",
- "invalid-time": "Invalid time",
- "invalid-user": "Invalid user",
- "joined": "joined",
- "just-invited": "You are just invited to this board",
- "keyboard-shortcuts": "Keyboard shortcuts",
- "label-create": "Create Label",
- "label-default": "%s label (default)",
- "label-delete-pop": "There is no undo. This will remove this label from all cards and destroy its history.",
- "labels": "Labels",
- "language": "Language",
- "last-admin-desc": "You can’t change roles because there must be at least one admin.",
- "leave-board": "Leave Board",
- "leave-board-pop": "Are you sure you want to leave __boardTitle__? You will be removed from all cards on this board.",
- "leaveBoardPopup-title": "Leave Board ?",
- "link-card": "Link to this card",
- "list-archive-cards": "Move all cards in this list to Recycle Bin",
+ "email-enrollAccount-text": "მოგესალმებით __user__,\n\nამ სერვისის გამოსაყენებლად დააკლიკეთ ქვედა ბმულს.\n\n__url__\n\nმადლობა.",
+ "email-fail": "ელ.ფოსტის გაგზავნა ვერ მოხერხდა",
+ "email-fail-text": "ელ.ფოსტის გაგზავნისას დაფიქსირდა შეცდომა",
+ "email-invalid": "არასწორი ელ.ფოსტა",
+ "email-invite": "მოწვევა ელ.ფოსტის მეშვეობით",
+ "email-invite-subject": "__inviter__ გამოგიგზავნათ მოწვევა",
+ "email-invite-text": "ძვირფასო __user__,\n\n__inviter__ გიწვევთ დაფაზე \"__board__\" თანამშრომლობისთვის.\n\nგთხოვთ მიყვეთ ქვემოთ მოცემულ ბმულს:\n\n__url__\n\nმადლობა.",
+ "email-resetPassword-subject": "შეცვალეთ თქვენი პაროლი __siteName-ზე__",
+ "email-resetPassword-text": "გამარჯობა__user__,\n\nპაროლის შესაცვლელად დააკლიკეთ ქვედა ბმულს .\n\n__url__\n\nმადლობა.",
+ "email-sent": "ელ.ფოსტა გაგზავნილია",
+ "email-verifyEmail-subject": "შეამოწმეთ ელ.ფოსტის მისამართი __siteName-ზე__",
+ "email-verifyEmail-text": "გამარჯობა __user__,\n\nანგარიშის ელ.ფოსტის შესამოწმებლად დააკლიკეთ ქვედა ბმულს.\n\n__url__\n\nმადლობა.",
+ "enable-wip-limit": "გავააქტიუროთ WIP ლიმიტი",
+ "error-board-doesNotExist": "მსგავსი დაფა არ არსებობს",
+ "error-board-notAdmin": "ამის გასაკეთებლად საჭიროა იყოთ დაფის ადმინისტრატორი",
+ "error-board-notAMember": "ამის გასაკეთებლად საჭიროა იყოთ დაფის წევრი",
+ "error-json-malformed": "შენი ტექსტი არ არის ვალიდური JSON",
+ "error-json-schema": "თქვენი JSON მონაცემები არ შეიცავს ზუსტ ინფორმაციას სწორ ფორმატში ",
+ "error-list-doesNotExist": "ეს ცხრილი არ არსებობს",
+ "error-user-doesNotExist": "მსგავსი მომხმარებელი არ არსებობს",
+ "error-user-notAllowSelf": "თქვენ არ შეგიძლიათ საკუთარი თავის მოწვევა",
+ "error-user-notCreated": "მომხმარებელი არ შეიქმნა",
+ "error-username-taken": "არსებობს მსგავსი მომხმარებელი",
+ "error-email-taken": "უკვე არსებობს მსგავსი ელ.ფოსტა",
+ "export-board": "დაფის ექსპორტი",
+ "filter": "ფილტრი",
+ "filter-cards": "ბარათების გაფილტვრა",
+ "filter-clear": "ფილტრის გასუფთავება",
+ "filter-no-label": "ნიშანი არ გვაქვს",
+ "filter-no-member": "არ არის წევრები ",
+ "filter-no-custom-fields": "არა მომხმარებლის ველი",
+ "filter-on": "ფილტრი ჩართულია",
+ "filter-on-desc": "თქვენ ფილტრავთ ბარათებს ამ დაფაზე. დააკლიკეთ აქ ფილტრაციის შესწორებისთვის. ",
+ "filter-to-selection": "მონიშნულის გაფილტვრა",
+ "advanced-filter-label": "გაფართოებული ფილტრაცია",
+ "advanced-filter-description": "გაფართოებული ფილტრაცია, უფლებას გაძლევთ დაწეროთ მწკრივი რომლებიც შეიცავენ შემდეგ ოპერაციებს : == != <= >= && || ( ) space გამოიყენება როგორც გამმიჯნავი ოპერაციებს შორის. თქვენ შეგიძლიათ გაფილტროთ მომხმარებლის ველი მათი სახელებისა და ღირებულებების მიხედვით. მაგალითად: Field1 == Value1. გაითვალისწინეთ რომ თუ ველი ან ღირებულება შეიცავს space-ს თქვენ დაგჭირდებათ მათი მოთავსება ერთ ციტატაში მაგ: 'Field 1' == 'Value 1'. ერთი კონტროლის სიმბოლოებისთვის (' \\/) გამოტოვება, შეგიძლიათ გამოიყენოთ \\. მაგ: Field1 == I\\'m. აგრეთვე თქვენ შეგიძლიათ შეურიოთ რამოდენიმე კომბინაცია. მაგალითად: F1 == V1 || F1 == V2. როგორც წესი ყველა ოპერაცია ინტერპრეტირებულია მარცხნიდან მარჯვნივ. თქვენ შეგიძლიათ შეცვალოთ რიგითობა ფრჩხილების შეცვლით მაგალითად: F1 == V1 && ( F2 == V2 || F2 == V3 ). აგრეთვე შეგიძლიათ მოძებნოთ ტექსტის ველები რეგექსით F1 == /Tes.*/i",
+ "fullname": "სახელი და გვარი",
+ "header-logo-title": "დაბრუნდით უკან დაფების გვერდზე.",
+ "hide-system-messages": "დამალეთ სისტემური შეტყობინებები",
+ "headerBarCreateBoardPopup-title": "დაფის შექმნა",
+ "home": "სახლი",
+ "import": "იმპორტირება",
+ "link": "Link",
+ "import-board": " დაფის იმპორტი",
+ "import-board-c": "დაფის იმპორტი",
+ "import-board-title-trello": "დაფის იმპორტი Trello-დან",
+ "import-board-title-wekan": "დაფის იმპორტი Wekan-დან",
+ "import-sandstorm-warning": "იმპორტირებული დაფა წაშლის ყველა არსებულ მონაცემს დაფაზე და შეანაცვლებს მას იმპორტირებული დაფა. ",
+ "from-trello": "Trello-დან",
+ "from-wekan": "Wekan-დან",
+ "import-board-instruction-trello": "თქვენს Trello დაფაზე, შედით \"მენიუ\"-ში, შემდეგ დააკლიკეთ \"მეტი\", \"ამოპრინტერება და ექსპორტი\", \"JSON-ის ექსპორტი\" და დააკოპირეთ შედეგი. ",
+ "import-board-instruction-wekan": "თქვენს Wekan დაფაზე, შედით \"მენიუ\"-ში შემდეგ დააკლიკეთ \"დაფის ექსპორტი\" და დააკოპირეთ ტექსტი ჩამოტვირთულ ფაილში.",
+ "import-json-placeholder": "მოათავსეთ თქვენი ვალიდური JSON მონაცემები აქ. ",
+ "import-map-members": "რუკის წევრები",
+ "import-members-map": "თქვენს იმპორტირებულ დაფას ჰყავს მომხმარებლები. გთხოვთ დაამატოთ ის წევრები რომლის იმპორტიც გსურთ Wekan მომხმარებლებში",
+ "import-show-user-mapping": "მომხმარებლის რუკების განხილვა",
+ "import-user-select": "აირჩიეთ Wekan მომხმარებელი, რომელიც გსურთ რომ გახდეს წევრი",
+ "importMapMembersAddPopup-title": "მონიშნეთ Wekan მომხმარებელი",
+ "info": "ვერსია",
+ "initials": "ინიციალები",
+ "invalid-date": "არასწორი თარიღი",
+ "invalid-time": "არასწორი დრო",
+ "invalid-user": "არასწორი მომხმარებელი",
+ "joined": "შემოუერთდა",
+ "just-invited": "თქვენ მოწვეული ხართ ამ დაფაზე",
+ "keyboard-shortcuts": "კლავიატურის კომბინაციები",
+ "label-create": "ნიშნის შექმნა",
+ "label-default": "%s ნიშანი (default)",
+ "label-delete-pop": "იმ შემთხვევაში თუ წაშლით ნიშანს, ყველა ბარათიდან ისტორია ავტომატურად წაიშლება და შეუძლებელი იქნება მისი უკან დაბრუნება.",
+ "labels": "ნიშნები",
+ "language": "ენა",
+ "last-admin-desc": "თქვენ ვერ შეცვლით როლებს რადგან უნდა არსებობდეს ერთი ადმინი მაინც.",
+ "leave-board": "დატოვეთ დაფა",
+ "leave-board-pop": "დარწმუნებული ხართ, რომ გინდათ დატოვოთ __boardTitle__? თქვენ წაიშლებით ამ დაფის ყველა ბარათიდან. ",
+ "leaveBoardPopup-title": "გსურთ დაფის დატოვება? ",
+ "link-card": "დააკავშირეთ ამ ბარათთან",
+ "list-archive-cards": "ყველა ბარათის სანაგვე ურნაში გადატანა",
"list-archive-cards-pop": "This will remove all the cards in this list from the board. To view cards in Recycle Bin and bring them back to the board, click “Menu” > “Recycle Bin”.",
- "list-move-cards": "Move all cards in this list",
- "list-select-cards": "Select all cards in this list",
- "listActionPopup-title": "List Actions",
- "swimlaneActionPopup-title": "Swimlane Actions",
- "listImportCardPopup-title": "Import a Trello card",
- "listMorePopup-title": "More",
- "link-list": "Link to this list",
- "list-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the list. There is no undo.",
- "list-delete-suggest-archive": "You can move a list to Recycle Bin to remove it from the board and preserve the activity.",
- "lists": "Lists",
- "swimlanes": "Swimlanes",
- "log-out": "Log Out",
- "log-in": "Log In",
- "loginPopup-title": "Log In",
- "memberMenuPopup-title": "Member Settings",
- "members": "Members",
- "menu": "Menu",
- "move-selection": "Move selection",
- "moveCardPopup-title": "Move Card",
- "moveCardToBottom-title": "Move to Bottom",
- "moveCardToTop-title": "Move to Top",
- "moveSelectionPopup-title": "Move selection",
- "multi-selection": "Multi-Selection",
- "multi-selection-on": "Multi-Selection is on",
- "muted": "Muted",
- "muted-info": "You will never be notified of any changes in this board",
- "my-boards": "My Boards",
- "name": "Name",
- "no-archived-cards": "No cards in Recycle Bin.",
- "no-archived-lists": "No lists in Recycle Bin.",
- "no-archived-swimlanes": "No swimlanes in Recycle Bin.",
- "no-results": "No results",
- "normal": "Normal",
- "normal-desc": "Can view and edit cards. Can't change settings.",
- "not-accepted-yet": "Invitation not accepted yet",
- "notify-participate": "Receive updates to any cards you participate as creater or member",
- "notify-watch": "Receive updates to any boards, lists, or cards you’re watching",
- "optional": "optional",
- "or": "or",
- "page-maybe-private": "This page may be private. You may be able to view it by <a href='%s'>logging in</a>.",
- "page-not-found": "Page not found.",
- "password": "Password",
- "paste-or-dragdrop": "to paste, or drag & drop image file to it (image only)",
- "participating": "Participating",
- "preview": "Preview",
- "previewAttachedImagePopup-title": "Preview",
- "previewClipboardImagePopup-title": "Preview",
- "private": "Private",
- "private-desc": "This board is private. Only people added to the board can view and edit it.",
- "profile": "Profile",
- "public": "Public",
- "public-desc": "This board is public. It's visible to anyone with the link and will show up in search engines like Google. Only people added to the board can edit.",
- "quick-access-description": "Star a board to add a shortcut in this bar.",
- "remove-cover": "Remove Cover",
- "remove-from-board": "Remove from Board",
- "remove-label": "Remove Label",
- "listDeletePopup-title": "Delete List ?",
- "remove-member": "Remove Member",
- "remove-member-from-card": "Remove from Card",
+ "list-move-cards": "გადაიტანე ყველა ბარათი ამ სიაში",
+ "list-select-cards": "მონიშნე ყველა ბარათი ამ სიაში",
+ "listActionPopup-title": "მოქმედებების სია",
+ "swimlaneActionPopup-title": "ბილიკის მოქმედებები",
+ "listImportCardPopup-title": "Trello ბარათის იმპორტი",
+ "listMorePopup-title": "მეტი",
+ "link-list": "დააკავშირეთ ამ ჩამონათვალთან",
+ "list-delete-pop": "ყველა მოქმედება წაიშლება აქტივობების ველიდან და თქვენ ვეღარ შეძლებთ მის აღდგენას ჩამონათვალში",
+ "list-delete-suggest-archive": "თქვენ შეგიძლიათ გადაიტანოთ ჩამონათვალი სანაგვე ურნაში, იმისთვის, რომ წაშალოთ დაფიდან და შეინახოთ აქტივობა. ",
+ "lists": "ჩამონათვალი",
+ "swimlanes": "ბილიკები",
+ "log-out": "გამოსვლა",
+ "log-in": "შესვლა",
+ "loginPopup-title": "შესვლა",
+ "memberMenuPopup-title": "მომხმარებლის პარამეტრები",
+ "members": "წევრები",
+ "menu": "მენიუ",
+ "move-selection": "მონიშნულის მოძრაობა",
+ "moveCardPopup-title": "ბარათის გადატანა",
+ "moveCardToBottom-title": "ქვევით ჩამოწევა",
+ "moveCardToTop-title": "ზევით აწევა",
+ "moveSelectionPopup-title": "მონიშნულის მოძრაობა",
+ "multi-selection": "რამდენიმეს მონიშვნა",
+ "multi-selection-on": "რამდენიმეს მონიშვნა ჩართულია",
+ "muted": "ხმა გათიშულია",
+ "muted-info": "თქვენ აღარ მიიღებთ შეტყობინებას ამ დაფაზე მიმდინარე ცვლილებების შესახებ. ",
+ "my-boards": "ჩემი დაფები",
+ "name": "სახელი",
+ "no-archived-cards": "სანაგვე ურნაში ბარათები არ მოიძებნა.",
+ "no-archived-lists": "სანაგვე ურნაში ჩამონათვალი არ მოიძებნა. ",
+ "no-archived-swimlanes": "სანაგვე ურნაში ბილიკები არ მოიძებნა.",
+ "no-results": "შედეგის გარეშე",
+ "normal": "ნორმალური",
+ "normal-desc": "შეუძლია ნახოს და შეასწოროს ბარათები. ამ პარამეტრების შეცვლა შეუძლებელია. ",
+ "not-accepted-yet": "მოწვევა ჯერ არ დადასტურებულა",
+ "notify-participate": "მიიღეთ განახლებები ნებისმიერ ბარათზე, რომელშიც მონაწილეობთ, როგორც შემქმნელი ან წევრი. ",
+ "notify-watch": "მიიღეთ განახლებები ყველა დაფაზე, ჩამონათვალზე ან ბარათებზე, რომელსაც თქვენ აკვირდებით",
+ "optional": "არჩევითი",
+ "or": "ან",
+ "page-maybe-private": "ეს გვერდი შესაძლოა იყოს კერძო. თქვენ შეგეძლებათ მისი ნახვა <a href='%s'>logging in</a> მეშვეობით.",
+ "page-not-found": "გვერდი არ მოიძებნა.",
+ "password": "პაროლი",
+ "paste-or-dragdrop": "ჩასმისთვის, ან drag & drop-ისთვის ჩააგდეთ სურათი აქ (მხოლოდ სურათი)",
+ "participating": "მონაწილეობა",
+ "preview": "წინასწარ ნახვა",
+ "previewAttachedImagePopup-title": "წინასწარ ნახვა",
+ "previewClipboardImagePopup-title": "წინასწარ ნახვა",
+ "private": "კერძო",
+ "private-desc": "ეს არის კერძო დაფა. დაფაზე წვდომის, ნახვის და რედაქტირების უფლება აქვთ მხოლოდ მასზე დამატებულ წევრებს. ",
+ "profile": "პროფილი",
+ "public": "საჯარო",
+ "public-desc": "ეს დაფა არის საჯარო. ის ხილვადია ყველასთვის და შესაძლოა გამოჩნდეს საძიებო სისტემებში. შესწორების უფლება აქვს მხოლოდ მასზე დამატებულ პირებს. ",
+ "quick-access-description": "მონიშნეთ დაფა ვარსკვლავით იმისთვის, რომ დაამატოთ სწრაფი ბმული ამ ნაწილში.",
+ "remove-cover": "გარეკანის წაშლა",
+ "remove-from-board": "დაფიდან წაშლა",
+ "remove-label": "ნიშნის წაშლა",
+ "listDeletePopup-title": "ნამდვილად გსურთ სიის წაშლა? ",
+ "remove-member": "წევრის წაშლა",
+ "remove-member-from-card": "ბარათიდან წაშლა",
"remove-member-pop": "Remove __name__ (__username__) from __boardTitle__? The member will be removed from all cards on this board. They will receive a notification.",
- "removeMemberPopup-title": "Remove Member?",
- "rename": "Rename",
- "rename-board": "Rename Board",
- "restore": "Restore",
- "save": "Save",
- "search": "Search",
- "search-cards": "Search from card titles and descriptions on this board",
- "search-example": "Text to search for?",
- "select-color": "Select Color",
- "set-wip-limit-value": "Set a limit for the maximum number of tasks in this list",
- "setWipLimitPopup-title": "Set WIP Limit",
- "shortcut-assign-self": "Assign yourself to current card",
- "shortcut-autocomplete-emoji": "Autocomplete emoji",
- "shortcut-autocomplete-members": "Autocomplete members",
- "shortcut-clear-filters": "Clear all filters",
- "shortcut-close-dialog": "Close Dialog",
- "shortcut-filter-my-cards": "Filter my cards",
+ "removeMemberPopup-title": "ნამდვილად გსურთ წევრის წაშლა? ",
+ "rename": "სახელის შეცვლა",
+ "rename-board": "დაფის სახელის ცვლილება",
+ "restore": "აღდგენა",
+ "save": "დამახსოვრება",
+ "search": "ძებნა",
+ "search-cards": "მოძებნეთ ბარათის სახელით და აღწერით ამ დაფაზე",
+ "search-example": "საძიებო ტექსტი",
+ "select-color": "ფერის მონიშვნა",
+ "set-wip-limit-value": "დააყენეთ შეზღუდვა დავალებების მაქსიმალურ რაოდენობაზე ",
+ "setWipLimitPopup-title": "დააყენეთ WIP ლიმიტი",
+ "shortcut-assign-self": "მონიშნეთ საკუთარი თავი აღნიშნულ ბარათზე",
+ "shortcut-autocomplete-emoji": "emoji-ის ავტომატური შევსება",
+ "shortcut-autocomplete-members": "მომხმარებლების ავტომატური შევსება",
+ "shortcut-clear-filters": "ყველა ფილტრის გასუფთავება",
+ "shortcut-close-dialog": "დიალოგის დახურვა",
+ "shortcut-filter-my-cards": "ჩემი ბარათების გაფილტვრა",
"shortcut-show-shortcuts": "Bring up this shortcuts list",
- "shortcut-toggle-filterbar": "Toggle Filter Sidebar",
- "shortcut-toggle-sidebar": "Toggle Board Sidebar",
- "show-cards-minimum-count": "Show cards count if list contains more than",
- "sidebar-open": "Open Sidebar",
- "sidebar-close": "Close Sidebar",
- "signupPopup-title": "Create an Account",
- "star-board-title": "Click to star this board. It will show up at top of your boards list.",
- "starred-boards": "Starred Boards",
+ "shortcut-toggle-filterbar": "ფილტრაციის გვერდითა ღილაკი",
+ "shortcut-toggle-sidebar": "გვერდით მენიუს ჩართვა/გამორთვა",
+ "show-cards-minimum-count": "აჩვენეთ ბარათების დათვლილი რაოდენობა თუ ჩამონათვალი შეიცავს უფრო მეტს ვიდრე ",
+ "sidebar-open": "გახსენით მცირე სტატია",
+ "sidebar-close": "დახურეთ მცირე სტატია",
+ "signupPopup-title": "ანგარიშის შექმნა",
+ "star-board-title": "დააკლიკეთ დაფის ვარსკვლავით მონიშვნისთვის. ეს ქმედება დაგეხმარებათ გამოაჩინოთ დაფა ჩამონათვალში ზედა პოზიციებზე. ",
+ "starred-boards": "ვარსკვლავიანი დაფები",
"starred-boards-description": "Starred boards show up at the top of your boards list.",
- "subscribe": "Subscribe",
- "team": "Team",
- "this-board": "this board",
- "this-card": "this card",
- "spent-time-hours": "Spent time (hours)",
- "overtime-hours": "Overtime (hours)",
- "overtime": "Overtime",
- "has-overtime-cards": "Has overtime cards",
- "has-spenttime-cards": "Has spent time cards",
- "time": "Time",
- "title": "Title",
- "tracking": "Tracking",
- "tracking-info": "You will be notified of any changes to those cards you are involved as creator or member.",
- "type": "Type",
- "unassign-member": "Unassign member",
- "unsaved-description": "You have an unsaved description.",
- "unwatch": "Unwatch",
- "upload": "Upload",
- "upload-avatar": "Upload an avatar",
- "uploaded-avatar": "Uploaded an avatar",
- "username": "Username",
- "view-it": "View it",
- "warn-list-archived": "warning: this card is in an list at Recycle Bin",
- "watch": "Watch",
- "watching": "Watching",
- "watching-info": "You will be notified of any change in this board",
- "welcome-board": "Welcome Board",
- "welcome-swimlane": "Milestone 1",
- "welcome-list1": "Basics",
- "welcome-list2": "Advanced",
- "what-to-do": "What do you want to do?",
- "wipLimitErrorPopup-title": "Invalid WIP Limit",
+ "subscribe": "გამოწერა",
+ "team": "ჯგუფი",
+ "this-board": "ეს დაფა",
+ "this-card": "ეს ბარათი",
+ "spent-time-hours": "დახარჯული დრო (საათები)",
+ "overtime-hours": "ზედმეტი დრო (საათები) ",
+ "overtime": "ზედმეტი დრო",
+ "has-overtime-cards": "აქვს ვადაგადაცდილებული ბარათები",
+ "has-spenttime-cards": "აქვს გახარჯული დროის ბარათები",
+ "time": "დრო",
+ "title": "სათაური",
+ "tracking": "მონიტორინგი",
+ "tracking-info": "თქვენ მოგივათ შეტყობინება ამ ბარათებში განხორციელებული ნებისმიერი ცვლილებების შესახებ, როგორც შემქმნელს ან წევრს. ",
+ "type": "ტიპი",
+ "unassign-member": "არაუფლებამოსილი წევრი",
+ "unsaved-description": "თქვან გაქვთ დაუმახსოვრებელი აღწერა. ",
+ "unwatch": "ნახვის გამორთვა",
+ "upload": "ატვირთვა",
+ "upload-avatar": "სურათის ატვირთვა",
+ "uploaded-avatar": "სურათი ატვირთულია",
+ "username": "მომხმარებლის სახელი",
+ "view-it": "ნახვა",
+ "warn-list-archived": "გაფრთხილება: ეს ბარათი არის ჩამონათვალში სანაგვე ურნაში",
+ "watch": "ნახვა",
+ "watching": "ნახვის პროცესი",
+ "watching-info": "თქვენ მოგივათ შეტყობინება ამ დაფაზე არსებული ნებისმიერი ცვლილების შესახებ. ",
+ "welcome-board": "მისასალმებელი დაფა",
+ "welcome-swimlane": "ეტაპი 1 ",
+ "welcome-list1": "ბაზისური ",
+ "welcome-list2": "დაწინაურებული",
+ "what-to-do": "რისი გაკეთება გსურთ? ",
+ "wipLimitErrorPopup-title": "არასწორი WIP ლიმიტი",
"wipLimitErrorPopup-dialog-pt1": "The number of tasks in this list is higher than the WIP limit you've defined.",
"wipLimitErrorPopup-dialog-pt2": "Please move some tasks out of this list, or set a higher WIP limit.",
- "admin-panel": "Admin Panel",
- "settings": "Settings",
- "people": "People",
- "registration": "Registration",
- "disable-self-registration": "Disable Self-Registration",
- "invite": "Invite",
- "invite-people": "Invite People",
- "to-boards": "To board(s)",
- "email-addresses": "Email Addresses",
+ "admin-panel": "ადმინის პანელი",
+ "settings": "პარამეტრები",
+ "people": "ხალხი",
+ "registration": "რეგისტრაცია",
+ "disable-self-registration": "თვით რეგისტრაციის გამორთვა",
+ "invite": "მოწვევა",
+ "invite-people": "ხალხის მოწვევა",
+ "to-boards": "დაფა(ებ)ზე",
+ "email-addresses": "ელ.ფოსტის მისამართები",
"smtp-host-description": "The address of the SMTP server that handles your emails.",
"smtp-port-description": "The port your SMTP server uses for outgoing emails.",
- "smtp-tls-description": "Enable TLS support for SMTP server",
+ "smtp-tls-description": "ჩართეთ TLS მხარდაჭერა SMTP სერვერისთვის",
"smtp-host": "SMTP Host",
"smtp-port": "SMTP Port",
- "smtp-username": "Username",
- "smtp-password": "Password",
- "smtp-tls": "TLS support",
- "send-from": "From",
- "send-smtp-test": "Send a test email to yourself",
- "invitation-code": "Invitation Code",
- "email-invite-register-subject": "__inviter__ sent you an invitation",
- "email-invite-register-text": "Dear __user__,\n\n__inviter__ invites you to Wekan for collaborations.\n\nPlease follow the link below:\n__url__\n\nAnd your invitation code is: __icode__\n\nThanks.",
+ "smtp-username": "მომხმარებლის სახელი",
+ "smtp-password": "პაროლი",
+ "smtp-tls": "TLS მხარდაჭერა",
+ "send-from": "დან",
+ "send-smtp-test": "გაუგზავნეთ სატესტო ელ.ფოსტა საკუთარ თავს",
+ "invitation-code": "მოწვევის კოდი",
+ "email-invite-register-subject": "__inviter__ გამოგიგზავნათ მოწვევა",
+ "email-invite-register-text": "ძვირგასო __user__,\n\n__inviter__ გიწვევთ Wekan-ში თანამშრომლობისთვის.\n\nგთხოვთ მიყვეთ ქვემოთ მოცემულ ბმულს:\n__url__\n\nდა ჩაწეროთ თქვენი მოწვევის კოდი: __icode__\n\nმადლობა.",
"email-smtp-test-subject": "SMTP Test Email From Wekan",
- "email-smtp-test-text": "You have successfully sent an email",
- "error-invitation-code-not-exist": "Invitation code doesn't exist",
- "error-notAuthorized": "You are not authorized to view this page.",
- "outgoing-webhooks": "Outgoing Webhooks",
- "outgoingWebhooksPopup-title": "Outgoing Webhooks",
+ "email-smtp-test-text": "თქვენ წარმატებით გააგზავნეთ ელ.ფოსტა.",
+ "error-invitation-code-not-exist": "მსგავსი მოსაწვევი კოდი არ არსებობს",
+ "error-notAuthorized": "თქვენ არ გაქვთ ამ გვერდის ნახვის უფლება",
+ "outgoing-webhooks": "გამავალი Webhook",
+ "outgoingWebhooksPopup-title": "გამავალი Webhook",
"new-outgoing-webhook": "New Outgoing Webhook",
- "no-name": "(Unknown)",
- "Wekan_version": "Wekan version",
- "Node_version": "Node version",
+ "no-name": "(უცნობი)",
+ "Wekan_version": "Wekan ვერსია",
+ "Node_version": "Node ვერსია",
"OS_Arch": "OS Arch",
"OS_Cpus": "OS CPU Count",
- "OS_Freemem": "OS Free Memory",
+ "OS_Freemem": "OS თავისუფალი მეხსიერება",
"OS_Loadavg": "OS Load Average",
- "OS_Platform": "OS Platform",
- "OS_Release": "OS Release",
- "OS_Totalmem": "OS Total Memory",
- "OS_Type": "OS Type",
+ "OS_Platform": "OS პლატფორმა",
+ "OS_Release": "OS რელიზი",
+ "OS_Totalmem": "OS მთლიანი მეხსიერება",
+ "OS_Type": "OS ტიპი",
"OS_Uptime": "OS Uptime",
- "hours": "hours",
- "minutes": "minutes",
- "seconds": "seconds",
- "show-field-on-card": "Show this field on card",
- "yes": "Yes",
- "no": "No",
- "accounts": "Accounts",
- "accounts-allowEmailChange": "Allow Email Change",
- "accounts-allowUserNameChange": "Allow Username Change",
- "createdAt": "Created at",
- "verified": "Verified",
- "active": "Active",
- "card-received": "Received",
- "card-received-on": "Received on",
- "card-end": "End",
- "card-end-on": "Ends on",
+ "hours": "საათები",
+ "minutes": "წუთები",
+ "seconds": "წამები",
+ "show-field-on-card": "აჩვენეთ ეს ველი ბარათზე",
+ "yes": "დიახ",
+ "no": "არა",
+ "accounts": "ანგარიშები",
+ "accounts-allowEmailChange": "ელ.ფოსტის ცვლილების უფლების დაშვება",
+ "accounts-allowUserNameChange": "მომხმარებლის სახელის ცვლილების უფლების დაშვება ",
+ "createdAt": "შექმნილია",
+ "verified": "შემოწმებული",
+ "active": "აქტიური",
+ "card-received": "მიღებული",
+ "card-received-on": "მიღებულია",
+ "card-end": "დასასრული",
+ "card-end-on": "დასრულდება : ",
"editCardReceivedDatePopup-title": "Change received date",
- "editCardEndDatePopup-title": "Change end date",
- "assigned-by": "Assigned By",
- "requested-by": "Requested By",
- "board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
- "delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
- "boardDeletePopup-title": "Delete Board?",
- "delete-board": "Delete Board",
- "default-subtasks-board": "Subtasks for __board__ board",
+ "editCardEndDatePopup-title": "შეცვალეთ საბოლოო თარიღი",
+ "assigned-by": "უფლებამოსილების გამცემი ",
+ "requested-by": "მომთხოვნი",
+ "board-delete-notice": "წაშლის შემთხვევაში თქვენ დაკარგავთ ამ დაფასთან ასოცირებულ ყველა მონაცემს მათ შორის : ჩამონათვალს, ბარათებს და მოქმედებებს. ",
+ "delete-board-confirm-popup": "ყველა ჩამონათვალი, ბარათი, ნიშანი და აქტივობა წაიშლება და თქვენ ვეღარ შეძლებთ მის აღდგენას. ",
+ "boardDeletePopup-title": "წავშალოთ დაფა? ",
+ "delete-board": "დაფის წაშლა",
+ "default-subtasks-board": "ქვესაქმიანობა __board__ დაფისთვის",
"default": "Default",
- "queue": "Queue",
- "subtask-settings": "Subtasks Settings",
+ "queue": "რიგი",
+ "subtask-settings": "ქვესაქმიანობების პარამეტრები",
"boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
- "show-subtasks-field": "Cards can have subtasks",
+ "show-subtasks-field": "ბარათებს შესაძლოა ჰქონდეს ქვესაქმიანობები",
"deposit-subtasks-board": "Deposit subtasks to this board:",
"deposit-subtasks-list": "Landing list for subtasks deposited here:",
"show-parent-in-minicard": "Show parent in minicard:",
@@ -497,6 +506,6 @@
"subtext-with-parent": "Subtext with parent",
"change-card-parent": "Change card's parent",
"parent-card": "Parent card",
- "source-board": "Source board",
+ "source-board": "ძირითადი დაფა",
"no-parent": "Don't show parent"
} \ No newline at end of file
diff --git a/i18n/km.i18n.json b/i18n/km.i18n.json
index e0838ffc..013e1b46 100644
--- a/i18n/km.i18n.json
+++ b/i18n/km.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/ko.i18n.json b/i18n/ko.i18n.json
index ddcc3c0c..36de4299 100644
--- a/i18n/ko.i18n.json
+++ b/i18n/ko.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "예: “프로젝트 이름“ 입력",
"cancel": "취소",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "이 카드에 %s 코멘트가 있습니다.",
"card-delete-notice": "영구 삭제입니다. 이 카드와 관련된 모든 작업들을 잃게됩니다.",
"card-delete-pop": "모든 작업이 활동 내역에서 제거되며 카드를 다시 열 수 없습니다. 복구가 안되니 주의하시기 바랍니다.",
@@ -135,6 +136,9 @@
"cards": "카드",
"cards-count": "카드",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "변경",
"change-avatar": "아바타 변경",
"change-password": "암호 변경",
@@ -167,10 +171,14 @@
"comment-placeholder": "댓글 입력",
"comment-only": "댓글만 입력 가능",
"comment-only-desc": "카드에 댓글만 달수 있습니다.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "내 컴퓨터",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "클립보드에 카드의 링크가 복사되었습니다.",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "카드 복사",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "보드 생성",
"home": "홈",
"import": "가져오기",
+ "link": "Link",
"import-board": "보드 가져오기",
"import-board-c": "보드 가져오기",
"import-board-title-trello": "Trello에서 보드 가져오기",
diff --git a/i18n/lv.i18n.json b/i18n/lv.i18n.json
index abeec5ad..061b9c14 100644
--- a/i18n/lv.i18n.json
+++ b/i18n/lv.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/mn.i18n.json b/i18n/mn.i18n.json
index f2f093b3..f2478d17 100644
--- a/i18n/mn.i18n.json
+++ b/i18n/mn.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Аватар өөрчлөх",
"change-password": "Нууц үг солих",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Самбар үүсгэх",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/nb.i18n.json b/i18n/nb.i18n.json
index 72bd0430..b479ee48 100644
--- a/i18n/nb.i18n.json
+++ b/i18n/nb.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Som \"Bucket List\" for eksempel",
"cancel": "Avbryt",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Dette kortet har %s kommentar.",
"card-delete-notice": "Sletting er permanent. Du vil miste alle hendelser knyttet til dette kortet.",
"card-delete-pop": "Alle handlinger vil fjernes fra feeden for aktiviteter og du vil ikke kunne åpne kortet på nytt. Det er ingen mulighet å angre.",
@@ -135,6 +136,9 @@
"cards": "Kort",
"cards-count": "Kort",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Endre",
"change-avatar": "Endre avatar",
"change-password": "Endre passord",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/nl.i18n.json b/i18n/nl.i18n.json
index 6a54b9c5..58d65723 100644
--- a/i18n/nl.i18n.json
+++ b/i18n/nl.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Zoals \"Bucket List\" bijvoorbeeld",
"cancel": "Annuleren",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Deze kaart heeft %s reactie.",
"card-delete-notice": "Verwijdering is permanent. Als je dit doet, verlies je alle informatie die op deze kaart is opgeslagen.",
"card-delete-pop": "Alle acties worden verwijderd van de activiteiten feed, en er zal geen mogelijkheid zijn om de kaart opnieuw te openen. Deze actie kan je niet ongedaan maken.",
@@ -135,6 +136,9 @@
"cards": "Kaarten",
"cards-count": "Kaarten",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Wijzig",
"change-avatar": "Wijzig avatar",
"change-password": "Wijzig wachtwoord",
@@ -167,10 +171,14 @@
"comment-placeholder": "Schrijf reactie",
"comment-only": "Alleen reageren",
"comment-only-desc": "Kan alleen op kaarten reageren.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Kopieer kaart link naar klembord",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Kopieer kaart",
"copyChecklistToManyCardsPopup-title": "Checklist sjabloon kopiëren naar meerdere kaarten",
"copyChecklistToManyCardsPopup-instructions": "Doel kaart titels en omschrijvingen in dit JSON formaat",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Bord aanmaken",
"home": "Voorpagina",
"import": "Importeer",
+ "link": "Link",
"import-board": "Importeer bord",
"import-board-c": "Importeer bord",
"import-board-title-trello": "Importeer bord van Trello",
diff --git a/i18n/pl.i18n.json b/i18n/pl.i18n.json
index a12a5389..086dd348 100644
--- a/i18n/pl.i18n.json
+++ b/i18n/pl.i18n.json
@@ -2,27 +2,27 @@
"accept": "Akceptuj",
"act-activity-notify": "[Wekan] Powiadomienia - aktywności",
"act-addAttachment": "załączono __attachement__ do __karty__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "dodano podzadanie __checklist__ do __card__",
"act-addChecklist": "dodano listę zadań __checklist__ to __card__",
"act-addChecklistItem": "dodano __checklistItem__ do listy zadań __checklist__ na karcie __card__",
- "act-addComment": "commented on __card__: __comment__",
- "act-createBoard": "created __board__",
- "act-createCard": "added __card__ to __list__",
- "act-createCustomField": "created custom field __customField__",
- "act-createList": "added __list__ to __board__",
- "act-addBoardMember": "added __member__ to __board__",
- "act-archivedBoard": "__board__ moved to Recycle Bin",
- "act-archivedCard": "__card__ moved to Recycle Bin",
- "act-archivedList": "__list__ moved to Recycle Bin",
- "act-archivedSwimlane": "__swimlane__ moved to Recycle Bin",
- "act-importBoard": "imported __board__",
- "act-importCard": "imported __card__",
- "act-importList": "imported __list__",
- "act-joinMember": "added __member__ to __card__",
- "act-moveCard": "moved __card__ from __oldList__ to __list__",
- "act-removeBoardMember": "removed __member__ from __board__",
- "act-restoredCard": "restored __card__ to __board__",
- "act-unjoinMember": "removed __member__ from __card__",
+ "act-addComment": "skomentowano __card__: __comment__",
+ "act-createBoard": "utworzono __board__",
+ "act-createCard": "dodano __card__ do __list__",
+ "act-createCustomField": "dodano niestandardowe pole __customField__",
+ "act-createList": "dodano __list__ do __board__",
+ "act-addBoardMember": "dodano __member__ do __board__",
+ "act-archivedBoard": "__board__ została przeniesiona do kosza",
+ "act-archivedCard": "__card__ została przeniesiona do Kosza",
+ "act-archivedList": "__list__ została przeniesiona do Kosza",
+ "act-archivedSwimlane": "__swimlane__ została przeniesiona do Kosza",
+ "act-importBoard": "zaimportowano __board__",
+ "act-importCard": "zaimportowano __card__",
+ "act-importList": "zaimportowano __list__",
+ "act-joinMember": "dodano __member_ do __card__",
+ "act-moveCard": "przeniesiono __card__ z __oldList__ do __list__",
+ "act-removeBoardMember": "usunięto __member__ z __board__",
+ "act-restoredCard": "przywrócono __card__ do __board__",
+ "act-unjoinMember": "usunięto __member__ z __card__",
"act-withBoardTitle": "[Wekan] __board__",
"act-withCardTitle": "[__board__] __card__",
"actions": "Akcje",
@@ -32,7 +32,7 @@
"activity-archived": "%s przeniesiono do Kosza",
"activity-attached": "załączono %s z %s",
"activity-created": "utworzono %s",
- "activity-customfield-created": "created custom field %s",
+ "activity-customfield-created": "utworzono niestandardowe pole %s",
"activity-excluded": "wyłączono %s z %s",
"activity-imported": "zaimportowano %s to %s z %s",
"activity-imported-board": "zaimportowano %s z %s",
@@ -42,15 +42,15 @@
"activity-removed": "usunięto %s z %s",
"activity-sent": "wysłano %s z %s",
"activity-unjoined": "odłączono %s",
- "activity-subtask-added": "added subtask to %s",
- "activity-checklist-added": "added checklist to %s",
- "activity-checklist-item-added": "added checklist item to '%s' in %s",
+ "activity-subtask-added": "dodano podzadanie do %s",
+ "activity-checklist-added": "dodano listę zadań do %s",
+ "activity-checklist-item-added": "dodano zadanie '%s' do %s",
"add": "Dodaj",
"add-attachment": "Dodaj załącznik",
"add-board": "Dodaj tablicę",
"add-card": "Dodaj kartę",
"add-swimlane": "Add Swimlane",
- "add-subtask": "Add Subtask",
+ "add-subtask": "Dodano Podzadanie",
"add-checklist": "Dodaj listę kontrolną",
"add-checklist-item": "Dodaj element do listy kontrolnej",
"add-cover": "Dodaj okładkę",
@@ -62,33 +62,33 @@
"admin": "Admin",
"admin-desc": "Może widzieć i edytować karty, usuwać członków oraz zmieniać ustawienia tablicy.",
"admin-announcement": "Ogłoszenie",
- "admin-announcement-active": "Active System-Wide Announcement",
+ "admin-announcement-active": "Aktywne Ogólnosystemowe Ogłoszenie ",
"admin-announcement-title": "Ogłoszenie od Administratora",
"all-boards": "Wszystkie tablice",
"and-n-other-card": "And __count__ other card",
"and-n-other-card_plural": "And __count__ other cards",
"apply": "Zastosuj",
- "app-is-offline": "Wekan is loading, please wait. Refreshing the page will cause data loss. If Wekan does not load, please check that Wekan server has not stopped.",
+ "app-is-offline": "Wekan jest aktualnie ładowany, proszę czekać. Odświeżenie strony spowoduję utratę danych. Jeżeli Wekan się nie ładuje, prosimy o upewnienie się czy serwer Wekan nie został zatrzymany.",
"archive": "Przenieś do Kosza",
- "archive-all": "Move All to Recycle Bin",
- "archive-board": "Move Board to Recycle Bin",
- "archive-card": "Move Card to Recycle Bin",
- "archive-list": "Move List to Recycle Bin",
+ "archive-all": "Przenieś Wszystkie do Kosza",
+ "archive-board": "Przenieś Tablicę do Kosza",
+ "archive-card": "Przenieś Kartę do Kosza",
+ "archive-list": "Przenieś Listę do Kosza",
"archive-swimlane": "Move Swimlane to Recycle Bin",
- "archive-selection": "Move selection to Recycle Bin",
- "archiveBoardPopup-title": "Move Board to Recycle Bin?",
- "archived-items": "Recycle Bin",
- "archived-boards": "Boards in Recycle Bin",
+ "archive-selection": "Przenieś zaznaczenie do Kosza",
+ "archiveBoardPopup-title": "Przenieść Tablicę do Kosza?",
+ "archived-items": "Kosz",
+ "archived-boards": "Tablice w Koszu",
"restore-board": "Przywróć tablicę",
- "no-archived-boards": "No Boards in Recycle Bin.",
- "archives": "Recycle Bin",
+ "no-archived-boards": "Brak Tablic w Koszu.",
+ "archives": "Kosz",
"assign-member": "Dodaj członka",
"attached": "załączono",
"attachment": "Załącznik",
"attachment-delete-pop": "Usunięcie załącznika jest nieodwracalne.",
"attachmentDeletePopup-title": "Usunąć załącznik?",
"attachments": "Załączniki",
- "auto-watch": "Automatically watch boards when they are created",
+ "auto-watch": "Automatycznie obserwuj tablice gdy zostaną stworzone",
"avatar-too-big": "Awatar jest za duży (maksymalnie 70Kb)",
"back": "Wstecz",
"board-change-color": "Zmień kolor",
@@ -103,16 +103,17 @@
"boardMenuPopup-title": "Menu tablicy",
"boards": "Tablice",
"board-view": "Board View",
- "board-view-cal": "Calendar",
+ "board-view-cal": "Kalendarz",
"board-view-swimlanes": "Swimlanes",
"board-view-lists": "Listy",
"bucket-example": "Like “Bucket List” for example",
"cancel": "Anuluj",
- "card-archived": "This card is moved to Recycle Bin.",
+ "card-archived": "Ta Karta została przeniesiona do Kosza.",
+ "board-archived": "Ta Tablica została przeniesiona do Kosza.",
"card-comments-title": "Ta karta ma %s komentarzy.",
"card-delete-notice": "Usunięcie jest trwałe. Stracisz wszystkie akcje powiązane z tą kartą.",
"card-delete-pop": "Wszystkie akcje będą usunięte z widoku aktywności, nie można będzie ponownie otworzyć karty. Usunięcie jest nieodwracalne.",
- "card-delete-suggest-archive": "You can move a card to Recycle Bin to remove it from the board and preserve the activity.",
+ "card-delete-suggest-archive": "Możesz przenieść Kartę do Kosza by usunąć ją z tablicy i zachować aktywności.",
"card-due": "Due",
"card-due-on": "Due on",
"card-spent": "Spent Time",
@@ -135,6 +136,9 @@
"cards": "Karty",
"cards-count": "Karty",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Zmień",
"change-avatar": "Zmień Avatar",
"change-password": "Zmień hasło",
@@ -167,10 +171,14 @@
"comment-placeholder": "Dodaj komentarz",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Komputer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Skopiuj kartę",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Utwórz tablicę",
"home": "Strona główna",
"import": "Importu",
+ "link": "Link",
"import-board": "importuj tablice",
"import-board-c": "Import tablicy",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/pt-BR.i18n.json b/i18n/pt-BR.i18n.json
index 6135ae54..0176fb6a 100644
--- a/i18n/pt-BR.i18n.json
+++ b/i18n/pt-BR.i18n.json
@@ -2,7 +2,7 @@
"accept": "Aceitar",
"act-activity-notify": "[Wekan] Notificação de Atividade",
"act-addAttachment": "anexo __attachment__ de __card__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "Subtarefa adicionada__checklist__ao__cartão",
"act-addChecklist": "added checklist __checklist__ no __card__",
"act-addChecklistItem": "adicionado __checklistitem__ para a lista de checagem __checklist__ em __card__",
"act-addComment": "comentou em __card__: __comment__",
@@ -42,7 +42,7 @@
"activity-removed": "removeu %s de %s",
"activity-sent": "enviou %s de %s",
"activity-unjoined": "saiu de %s",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "Adcionar subtarefa à",
"activity-checklist-added": "Adicionado lista de verificação a %s",
"activity-checklist-item-added": "adicionado o item de checklist para '%s' em %s",
"add": "Novo",
@@ -50,7 +50,7 @@
"add-board": "Adicionar Quadro",
"add-card": "Adicionar Cartão",
"add-swimlane": "Adicionar Swimlane",
- "add-subtask": "Add Subtask",
+ "add-subtask": "Adicionar subtarefa",
"add-checklist": "Adicionar Checklist",
"add-checklist-item": "Adicionar um item à lista de verificação",
"add-cover": "Adicionar Capa",
@@ -103,12 +103,13 @@
"boardMenuPopup-title": "Menu do Quadro",
"boards": "Quadros",
"board-view": "Visão de quadro",
- "board-view-cal": "Calendar",
+ "board-view-cal": "Calendário",
"board-view-swimlanes": "Swimlanes",
"board-view-lists": "Listas",
"bucket-example": "\"Bucket List\", por exemplo",
"cancel": "Cancelar",
"card-archived": "Este cartão foi movido para a lixeira",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Este cartão possui %s comentários.",
"card-delete-notice": "A exclusão será permanente. Você perderá todas as ações associadas a este cartão.",
"card-delete-pop": "Todas as ações serão removidas da lista de Atividades e vocês não poderá re-abrir o cartão. Não há como desfazer.",
@@ -134,7 +135,10 @@
"cardMorePopup-title": "Mais",
"cards": "Cartões",
"cards-count": "Cartões",
- "casSignIn": "Sign In with CAS",
+ "casSignIn": "Entrar com CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Alterar",
"change-avatar": "Alterar Avatar",
"change-password": "Alterar Senha",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "Alterar Senha",
"changePermissionsPopup-title": "Alterar Permissões",
"changeSettingsPopup-title": "Altera configurações",
- "subtasks": "Subtasks",
+ "subtasks": "Subtarefas",
"checklists": "Checklists",
"click-to-star": "Marcar quadro como favorito.",
"click-to-unstar": "Remover quadro dos favoritos.",
@@ -167,10 +171,14 @@
"comment-placeholder": "Escrever Comentário",
"comment-only": "Somente comentários",
"comment-only-desc": "Pode comentar apenas em cartões.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computador",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "Tem certeza que deseja deletar a subtarefa?",
+ "confirm-checklist-delete-dialog": "Tem certeza que quer deletar o checklist?",
"copy-card-link-to-clipboard": "Copiar link do cartão para a área de transferência",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copiar o cartão",
"copyChecklistToManyCardsPopup-title": "Copiar modelo de checklist para vários cartões",
"copyChecklistToManyCardsPopup-instructions": "Títulos e descrições do cartão de destino neste formato JSON",
@@ -254,13 +262,14 @@
"filter-on-desc": "Você está filtrando cartões neste quadro. Clique aqui para editar o filtro.",
"filter-to-selection": "Filtrar esta seleção",
"advanced-filter-label": "Filtro avançado",
- "advanced-filter-description": "Advanced Filter allows to write a string containing following operators: == != <= >= && || ( ) A space is used as a separator between the Operators. You can filter for all Custom Fields by typing their names and values. For Example: Field1 == Value1. Note: If fields or values contains spaces, you need to encapsulate them into single quotes. For Example: 'Field 1' == 'Value 1'. For single control characters (' \\/) to be skipped, you can use \\. For example: Field1 == I\\'m. Also you can combine multiple conditions. For Example: F1 == V1 || F1 == V2. Normally all operators are interpreted from left to right. You can change the order by placing brackets. For Example: F1 == V1 && ( F2 == V2 || F2 == V3 ). Also you can search text fields using regex: F1 == /Tes.*/i",
+ "advanced-filter-description": "Filtros avançados permitem escrever uma \"string\" contendo os seguintes operadores: == != <= >= && || (). Um espaco é utilizado como separador entre os operadores. Você pode filtrar para todos os campos personalizados escrevendo os nomes e valores. Exemplo: Campo1 == Valor1. Nota^Se o campo ou valor tiver espaços você precisa encapsular eles em citações sozinhas. Exemplo: Campo1 == Eu\\sou. Também você pode combinar múltiplas condições. Exemplo: C1 == V1 || C1 == V2. Normalmente todos os operadores são interpretados da esquerda para direita. Você pode alterar a ordem colocando parênteses - como ma expressão matemática. Exemplo: C1 == V1 && (C2 == V2 || C2 == V3). Você tamb~em pode pesquisar campos de texto usando regex: C1 == /Tes.*/i",
"fullname": "Nome Completo",
"header-logo-title": "Voltar para a lista de quadros.",
"hide-system-messages": "Esconde mensagens de sistema",
"headerBarCreateBoardPopup-title": "Criar Quadro",
"home": "Início",
"import": "Importar",
+ "link": "Link",
"import-board": "importar quadro",
"import-board-c": "Importar quadro",
"import-board-title-trello": "Importar board do Trello",
@@ -476,27 +485,27 @@
"card-end-on": "Termina em",
"editCardReceivedDatePopup-title": "Modificar data de recebimento",
"editCardEndDatePopup-title": "Mudar data de fim",
- "assigned-by": "Assigned By",
- "requested-by": "Requested By",
- "board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
- "delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
- "boardDeletePopup-title": "Delete Board?",
- "delete-board": "Delete Board",
- "default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
- "queue": "Queue",
- "subtask-settings": "Subtasks Settings",
- "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
- "show-subtasks-field": "Cards can have subtasks",
- "deposit-subtasks-board": "Deposit subtasks to this board:",
- "deposit-subtasks-list": "Landing list for subtasks deposited here:",
- "show-parent-in-minicard": "Show parent in minicard:",
- "prefix-with-full-path": "Prefix with full path",
- "prefix-with-parent": "Prefix with parent",
- "subtext-with-full-path": "Subtext with full path",
- "subtext-with-parent": "Subtext with parent",
- "change-card-parent": "Change card's parent",
- "parent-card": "Parent card",
- "source-board": "Source board",
- "no-parent": "Don't show parent"
+ "assigned-by": "Atribuído por",
+ "requested-by": "Solicitado por",
+ "board-delete-notice": "Deletar é permanente. Você perderá todas as listas, cartões e ações associados nesse painel.",
+ "delete-board-confirm-popup": "Todas as listas, cartões, etiquetas e atividades serão deletadas e você não poderá recuperar o conteúdo do painel. Não há como desfazer.",
+ "boardDeletePopup-title": "Deletar painel?",
+ "delete-board": "Deletar painel",
+ "default-subtasks-board": "Subtarefas para __painel__ painel",
+ "default": "Padrão",
+ "queue": "Fila",
+ "subtask-settings": "Configurações de subtarefas",
+ "boardSubtaskSettingsPopup-title": "Configurações das subtarefas do painel",
+ "show-subtasks-field": "Cartões podem ter subtarefas",
+ "deposit-subtasks-board": "Inserir subtarefas à este painel:",
+ "deposit-subtasks-list": "Listas de subtarefas inseridas aqui:",
+ "show-parent-in-minicard": "Mostrar Pai do mini cartão:",
+ "prefix-with-full-path": "Prefixo com caminho completo",
+ "prefix-with-parent": "Prefixo com Pai",
+ "subtext-with-full-path": "Subtexto com caminho completo",
+ "subtext-with-parent": "Subtexto com Pai",
+ "change-card-parent": "Mudar Pai do cartão",
+ "parent-card": "Pai do cartão",
+ "source-board": "Painel de fonte",
+ "no-parent": "Não mostrar Pai"
} \ No newline at end of file
diff --git a/i18n/pt.i18n.json b/i18n/pt.i18n.json
index 0d6df67e..954f7654 100644
--- a/i18n/pt.i18n.json
+++ b/i18n/pt.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cartões",
"cards-count": "Cartões",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Alterar",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computador",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/ro.i18n.json b/i18n/ro.i18n.json
index 8146ee3b..e70aeaf3 100644
--- a/i18n/ro.i18n.json
+++ b/i18n/ro.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/ru.i18n.json b/i18n/ru.i18n.json
index 577d7b43..980c0816 100644
--- a/i18n/ru.i18n.json
+++ b/i18n/ru.i18n.json
@@ -8,9 +8,9 @@
"act-addComment": "прокомментировал __card__: __comment__",
"act-createBoard": "создал __board__",
"act-createCard": "добавил __card__ в __list__",
- "act-createCustomField": "Расширенный фильтр позволяет написать строку, содержащую следующие операторы: ==! = <=> = && || () Пространство используется как разделитель между Операторами. Вы можете фильтровать все пользовательские поля, введя их имена и значения. Например: Field1 == Value1. Примечание. Если поля или значения содержат пробелы, вам необходимо инкапсулировать их в одинарные кавычки. Например: «Поле 1» == «Значение 1». Также вы можете комбинировать несколько условий. Например: F1 == V1 || F1 = V2. Обычно все операторы интерпретируются слева направо. Вы можете изменить порядок, разместив скобки. Например: F1 == V1 и (F2 == V2 || F2 == V3)",
- "act-createList": "добавил __list__ для __board__",
- "act-addBoardMember": "добавил __member__ в __board__",
+ "act-createCustomField": "создано настраиваемое поле __customField__",
+ "act-createList": "добавил __list__ на __board__",
+ "act-addBoardMember": "добавил __member__ на __board__",
"act-archivedBoard": "Доска __board__ перемещена в Корзину",
"act-archivedCard": "Карточка __card__ перемещена в Корзину",
"act-archivedList": "Список __list__ перемещён в Корзину",
@@ -42,7 +42,7 @@
"activity-removed": "удалил %s из %s",
"activity-sent": "отправил %s в %s",
"activity-unjoined": "вышел из %s",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "добавил подзадачу в %s",
"activity-checklist-added": "добавил контрольный список в %s",
"activity-checklist-item-added": "добавил пункт контрольного списка в '%s' в карточке %s",
"add": "Создать",
@@ -50,7 +50,7 @@
"add-board": "Добавить доску",
"add-card": "Добавить карту",
"add-swimlane": "Добавить дорожку",
- "add-subtask": "Add Subtask",
+ "add-subtask": "Добавить подзадачу",
"add-checklist": "Добавить контрольный список",
"add-checklist-item": "Добавить пункт в контрольный список",
"add-cover": "Прикрепить",
@@ -103,12 +103,13 @@
"boardMenuPopup-title": "Меню доски",
"boards": "Доски",
"board-view": "Вид доски",
- "board-view-cal": "Calendar",
+ "board-view-cal": "Календарь",
"board-view-swimlanes": "Дорожки",
"board-view-lists": "Списки",
"bucket-example": "Например “Список дел”",
"cancel": "Отмена",
"card-archived": "Эта карточка перемещена в Корзину",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Комментарии (%s)",
"card-delete-notice": "Это действие невозможно будет отменить. Все изменения, которые вы вносили в карточку будут потеряны.",
"card-delete-pop": "Все действия будут удалены из ленты активности участников и вы не сможете заново открыть карточку. Действие необратимо",
@@ -135,6 +136,9 @@
"cards": "Карточки",
"cards-count": "Карточки",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Изменить",
"change-avatar": "Изменить аватар",
"change-password": "Изменить пароль",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "Изменить пароль",
"changePermissionsPopup-title": "Изменить настройки доступа",
"changeSettingsPopup-title": "Изменить Настройки",
- "subtasks": "Subtasks",
+ "subtasks": "Подзадачи",
"checklists": "Контрольные списки",
"click-to-star": "Добавить в «Избранное»",
"click-to-unstar": "Удалить из «Избранного»",
@@ -167,10 +171,14 @@
"comment-placeholder": "Написать комментарий",
"comment-only": "Только комментирование",
"comment-only-desc": "Может комментировать только карточки.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Загрузить с компьютера",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "Вы уверены, что хотите удалить подзадачу?",
+ "confirm-checklist-delete-dialog": "Вы уверены, что хотите удалить чеклист?",
"copy-card-link-to-clipboard": "Копировать ссылку на карточку в буфер обмена",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Копировать карточку",
"copyChecklistToManyCardsPopup-title": "Копировать шаблон контрольного списка в несколько карточек",
"copyChecklistToManyCardsPopup-instructions": "Названия и описания целевых карт в формате JSON",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Создать доску",
"home": "Главная",
"import": "Импорт",
+ "link": "Link",
"import-board": "импортировать доску",
"import-board-c": "Импортировать доску",
"import-board-title-trello": "Импортировать доску из Trello",
@@ -482,10 +491,10 @@
"delete-board-confirm-popup": "Все списки, карточки, ярлыки и действия будут удалены, и вы не сможете восстановить содержимое доски. Отменить нельзя.",
"boardDeletePopup-title": "Удалить доску?",
"delete-board": "Удалить доску",
- "default-subtasks-board": "Subtasks for __board__ board",
+ "default-subtasks-board": "Подзадача для доски __board__ ",
"default": "Default",
"queue": "Queue",
- "subtask-settings": "Subtasks Settings",
+ "subtask-settings": "Настройки подзадач",
"boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
"show-subtasks-field": "Cards can have subtasks",
"deposit-subtasks-board": "Deposit subtasks to this board:",
diff --git a/i18n/sr.i18n.json b/i18n/sr.i18n.json
index db8e9792..395fd05c 100644
--- a/i18n/sr.i18n.json
+++ b/i18n/sr.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Na primer \"Lista zadataka\"",
"cancel": "Otkaži",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Ova kartica ima %s komentar.",
"card-delete-notice": "Brisanje je trajno. Izgubićeš sve akcije povezane sa ovom karticom.",
"card-delete-pop": "Sve akcije će biti uklonjene sa liste aktivnosti i kartica neće moći biti ponovo otvorena. Nema vraćanja unazad.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Uvezi tablu iz Trella",
diff --git a/i18n/sv.i18n.json b/i18n/sv.i18n.json
index 7d0fa978..efd18987 100644
--- a/i18n/sv.i18n.json
+++ b/i18n/sv.i18n.json
@@ -2,7 +2,7 @@
"accept": "Acceptera",
"act-activity-notify": "[Wekan] Aktivitetsavisering",
"act-addAttachment": "bifogade __attachment__ to __card__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "lade till deluppgift __checklist__ till __card__",
"act-addChecklist": "lade till checklist __checklist__ till __card__",
"act-addChecklistItem": "lade till __checklistItem__ till checklistan __checklist__ on __card__",
"act-addComment": "kommenterade __card__: __comment__",
@@ -42,7 +42,7 @@
"activity-removed": "tog bort %s från %s",
"activity-sent": "skickade %s till %s",
"activity-unjoined": "gick ur %s",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "lade till deluppgift till %s",
"activity-checklist-added": "lade kontrollista till %s",
"activity-checklist-item-added": "lade checklista objekt till '%s' i %s",
"add": "Lägg till",
@@ -50,7 +50,7 @@
"add-board": "Lägg till anslagstavla",
"add-card": "Lägg till kort",
"add-swimlane": "Lägg till simbana",
- "add-subtask": "Add Subtask",
+ "add-subtask": "Lägg till deluppgift",
"add-checklist": "Lägg till checklista",
"add-checklist-item": "Lägg till ett objekt till kontrollista",
"add-cover": "Lägg till omslag",
@@ -103,12 +103,13 @@
"boardMenuPopup-title": "Anslagstavla meny",
"boards": "Anslagstavlor",
"board-view": "Anslagstavelsvy",
- "board-view-cal": "Calendar",
+ "board-view-cal": "Kalender",
"board-view-swimlanes": "Simbanor",
"board-view-lists": "Listor",
"bucket-example": "Gilla \"att-göra-innan-jag-dör-lista\" till exempel",
"cancel": "Avbryt",
"card-archived": "Detta kort flyttas till papperskorgen.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Detta kort har %s kommentar.",
"card-delete-notice": "Ta bort är permanent. Du kommer att förlora alla åtgärder i samband med detta kort.",
"card-delete-pop": "Alla åtgärder kommer att tas bort från aktivitetsflöde och du kommer inte att kunna öppna kortet igen. Det går inte att ångra.",
@@ -134,7 +135,10 @@
"cardMorePopup-title": "Mera",
"cards": "Kort",
"cards-count": "Kort",
- "casSignIn": "Sign In with CAS",
+ "casSignIn": "Logga in med CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Ändra",
"change-avatar": "Ändra avatar",
"change-password": "Ändra lösenord",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "Ändra lösenord",
"changePermissionsPopup-title": "Ändra behörigheter",
"changeSettingsPopup-title": "Ändra inställningar",
- "subtasks": "Subtasks",
+ "subtasks": "Deluppgifter",
"checklists": "Kontrollistor",
"click-to-star": "Klicka för att stjärnmärka denna anslagstavla.",
"click-to-unstar": "Klicka för att ta bort stjärnmärkningen från denna anslagstavla.",
@@ -167,10 +171,14 @@
"comment-placeholder": "Skriv kommentar",
"comment-only": "Kommentera endast",
"comment-only-desc": "Kan endast kommentera kort.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Dator",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "Är du säker på att du vill radera deluppgift?",
+ "confirm-checklist-delete-dialog": "Är du säker på att du vill radera checklista?",
"copy-card-link-to-clipboard": "Kopiera kortlänk till urklipp",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Kopiera kort",
"copyChecklistToManyCardsPopup-title": "Kopiera checklist-mallen till flera kort",
"copyChecklistToManyCardsPopup-instructions": "Destinationskorttitlar och beskrivningar i detta JSON-format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Skapa anslagstavla",
"home": "Hem",
"import": "Importera",
+ "link": "Link",
"import-board": "importera anslagstavla",
"import-board-c": "Importera anslagstavla",
"import-board-title-trello": "Importera anslagstavla från Trello",
@@ -482,13 +491,13 @@
"delete-board-confirm-popup": "Alla listor, kort, etiketter och aktiviteter kommer tas bort och du kommer inte kunna återställa anslagstavlans innehåll. Det går inte att ångra.",
"boardDeletePopup-title": "Ta bort anslagstavla?",
"delete-board": "Ta bort anslagstavla",
- "default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
- "queue": "Queue",
- "subtask-settings": "Subtasks Settings",
- "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
- "show-subtasks-field": "Cards can have subtasks",
- "deposit-subtasks-board": "Deposit subtasks to this board:",
+ "default-subtasks-board": "Deluppgifter för __board__ board",
+ "default": "Standard",
+ "queue": "Kö",
+ "subtask-settings": "Deluppgift inställningar",
+ "boardSubtaskSettingsPopup-title": "Deluppgiftsinställningar för anslagstavla",
+ "show-subtasks-field": "Kort kan ha deluppgifter",
+ "deposit-subtasks-board": "Insättnings deluppgifter på denna anslagstavla:",
"deposit-subtasks-list": "Landing list for subtasks deposited here:",
"show-parent-in-minicard": "Show parent in minicard:",
"prefix-with-full-path": "Prefix with full path",
diff --git a/i18n/ta.i18n.json b/i18n/ta.i18n.json
index f2b32e0f..006fa2df 100644
--- a/i18n/ta.i18n.json
+++ b/i18n/ta.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Cancel",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/th.i18n.json b/i18n/th.i18n.json
index 86e3a65d..1c2e3ecf 100644
--- a/i18n/th.i18n.json
+++ b/i18n/th.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "ตัวอย่างเช่น “ระบบที่ต้องทำ”",
"cancel": "ยกเลิก",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "การ์ดนี้มี %s ความเห็น.",
"card-delete-notice": "เป็นการลบถาวร คุณจะสูญเสียข้อมูลที่เกี่ยวข้องกับการ์ดนี้ทั้งหมด",
"card-delete-pop": "การดำเนินการทั้งหมดจะถูกลบจาก feed กิจกรรมและคุณไม่สามารถเปิดได้อีกครั้งหรือยกเลิกการทำ",
@@ -135,6 +136,9 @@
"cards": "การ์ด",
"cards-count": "การ์ด",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "เปลี่ยน",
"change-avatar": "เปลี่ยนภาพ",
"change-password": "เปลี่ยนรหัสผ่าน",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "คอมพิวเตอร์",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "สร้างบอร์ด",
"home": "หน้าหลัก",
"import": "นำเข้า",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "นำเข้าบอร์ดจาก Trello",
diff --git a/i18n/tr.i18n.json b/i18n/tr.i18n.json
index c1e2d7f8..382c7b2c 100644
--- a/i18n/tr.i18n.json
+++ b/i18n/tr.i18n.json
@@ -50,7 +50,7 @@
"add-board": "Pano Ekle",
"add-card": "Kart Ekle",
"add-swimlane": "Kulvar Ekle",
- "add-subtask": "Add Subtask",
+ "add-subtask": "Alt Görev Ekle",
"add-checklist": "Yapılacak Listesi Ekle",
"add-checklist-item": "Yapılacak listesine yeni bir öğe ekle",
"add-cover": "Kapak resmi ekle",
@@ -103,12 +103,13 @@
"boardMenuPopup-title": "Pano menüsü",
"boards": "Panolar",
"board-view": "Pano Görünümü",
- "board-view-cal": "Calendar",
+ "board-view-cal": "Takvim",
"board-view-swimlanes": "Kulvarlar",
"board-view-lists": "Listeler",
"bucket-example": "Örn: \"Marketten Alacaklarım\"",
"cancel": "İptal",
"card-archived": "Bu kart Geri Dönüşüm Kutusu'na taşındı",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Bu kartta %s yorum var.",
"card-delete-notice": "Silme işlemi kalıcıdır. Bu kartla ilişkili tüm eylemleri kaybedersiniz.",
"card-delete-pop": "Son hareketler alanındaki tüm veriler silinecek, ayrıca bu kartı yeniden açamayacaksın. Bu işlemin geri dönüşü yok.",
@@ -135,6 +136,9 @@
"cards": "Kartlar",
"cards-count": "Kartlar",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Değiştir",
"change-avatar": "Avatar Değiştir",
"change-password": "Parola Değiştir",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "Parola Değiştir",
"changePermissionsPopup-title": "Yetkileri Değiştirme",
"changeSettingsPopup-title": "Ayarları değiştir",
- "subtasks": "Subtasks",
+ "subtasks": "Alt Görevler",
"checklists": "Yapılacak Listeleri",
"click-to-star": "Bu panoyu yıldızlamak için tıkla.",
"click-to-unstar": "Bu panunun yıldızını kaldırmak için tıkla.",
@@ -167,10 +171,14 @@
"comment-placeholder": "Yorum Yaz",
"comment-only": "Sadece yorum",
"comment-only-desc": "Sadece kartlara yorum yazabilir.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Bilgisayar",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Kartın linkini kopyala",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Kartı Kopyala",
"copyChecklistToManyCardsPopup-title": "Yapılacaklar Listesi şemasını birden çok karta kopyala",
"copyChecklistToManyCardsPopup-instructions": "Hedef Kart Başlıkları ve Açıklamaları bu JSON formatında",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Pano Oluşturma",
"home": "Ana Sayfa",
"import": "İçeri aktar",
+ "link": "Bağlantı",
"import-board": "panoyu içe aktar",
"import-board-c": "Panoyu içe aktar",
"import-board-title-trello": "Trello'dan panoyu içeri aktar",
@@ -476,15 +485,15 @@
"card-end-on": "Bitiş zamanı",
"editCardReceivedDatePopup-title": "Giriş tarihini değiştir",
"editCardEndDatePopup-title": "Bitiş tarihini değiştir",
- "assigned-by": "Assigned By",
- "requested-by": "Requested By",
+ "assigned-by": "Atamayı yapan",
+ "requested-by": "Talep Eden",
"board-delete-notice": "Deleting is permanent. You will lose all lists, cards and actions associated with this board.",
"delete-board-confirm-popup": "All lists, cards, labels, and activities will be deleted and you won't be able to recover the board contents. There is no undo.",
"boardDeletePopup-title": "Delete Board?",
"delete-board": "Delete Board",
"default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
- "queue": "Queue",
+ "default": "Varsayılan",
+ "queue": "Sıra",
"subtask-settings": "Subtasks Settings",
"boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
"show-subtasks-field": "Cards can have subtasks",
diff --git a/i18n/uk.i18n.json b/i18n/uk.i18n.json
index d2b27f81..8aa2c694 100644
--- a/i18n/uk.i18n.json
+++ b/i18n/uk.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Відміна",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "This card has %s comment.",
"card-delete-notice": "Deleting is permanent. You will lose all actions associated with this card.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/vi.i18n.json b/i18n/vi.i18n.json
index 43852935..7dabc338 100644
--- a/i18n/vi.i18n.json
+++ b/i18n/vi.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "Like “Bucket List” for example",
"cancel": "Hủy",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "Thẻ này có %s bình luận.",
"card-delete-notice": "Hành động xóa là không thể khôi phục. Bạn sẽ mất hết các hoạt động liên quan đến thẻ này.",
"card-delete-pop": "All actions will be removed from the activity feed and you won't be able to re-open the card. There is no undo.",
@@ -135,6 +136,9 @@
"cards": "Cards",
"cards-count": "Cards",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "Change",
"change-avatar": "Change Avatar",
"change-password": "Change Password",
@@ -167,10 +171,14 @@
"comment-placeholder": "Write Comment",
"comment-only": "Comment only",
"comment-only-desc": "Can comment on cards only.",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "Computer",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "Copy card link to clipboard",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "Create Board",
"home": "Home",
"import": "Import",
+ "link": "Link",
"import-board": "import board",
"import-board-c": "Import board",
"import-board-title-trello": "Import board from Trello",
diff --git a/i18n/zh-CN.i18n.json b/i18n/zh-CN.i18n.json
index bbc060fb..d663bb82 100644
--- a/i18n/zh-CN.i18n.json
+++ b/i18n/zh-CN.i18n.json
@@ -2,7 +2,7 @@
"accept": "接受",
"act-activity-notify": "[Wekan] 活动通知",
"act-addAttachment": "添加附件 __attachment__ 至卡片 __card__",
- "act-addSubtask": "added subtask __checklist__ to __card__",
+ "act-addSubtask": "添加清单 __checklist__ 到__card__",
"act-addChecklist": "添加清单 __checklist__ 到 __card__",
"act-addChecklistItem": "向 __card__ 中的清单 __checklist__ 添加 __checklistItem__",
"act-addComment": "在 __card__ 发布评论: __comment__",
@@ -42,7 +42,7 @@
"activity-removed": "从 %s 中移除 %s",
"activity-sent": "发送 %s 至 %s",
"activity-unjoined": "已解除 %s 关联",
- "activity-subtask-added": "added subtask to %s",
+ "activity-subtask-added": "添加子任务到%s",
"activity-checklist-added": "已经将清单添加到 %s",
"activity-checklist-item-added": "添加清单项至'%s' 于 %s",
"add": "添加",
@@ -50,7 +50,7 @@
"add-board": "添加看板",
"add-card": "添加卡片",
"add-swimlane": "添加泳道图",
- "add-subtask": "Add Subtask",
+ "add-subtask": "添加子任务",
"add-checklist": "添加待办清单",
"add-checklist-item": "扩充清单",
"add-cover": "添加封面",
@@ -103,12 +103,13 @@
"boardMenuPopup-title": "看板菜单",
"boards": "看板",
"board-view": "看板视图",
- "board-view-cal": "Calendar",
+ "board-view-cal": "日历",
"board-view-swimlanes": "泳道图",
"board-view-lists": "列表",
"bucket-example": "例如 “目标清单”",
"cancel": "取消",
"card-archived": "此卡片已经被移入回收站。",
+ "board-archived": "将看板移动到回收站",
"card-comments-title": "该卡片有 %s 条评论",
"card-delete-notice": "彻底删除的操作不可恢复,你将会丢失该卡片相关的所有操作记录。",
"card-delete-pop": "所有的活动将从活动摘要中被移除且您将无法重新打开该卡片。此操作无法撤销。",
@@ -134,7 +135,10 @@
"cardMorePopup-title": "更多",
"cards": "卡片",
"cards-count": "卡片",
- "casSignIn": "Sign In with CAS",
+ "casSignIn": "用CAS登录",
+ "cardType-card": "卡片",
+ "cardType-linkedCard": "已链接卡片",
+ "cardType-linkedBoard": "已链接看板",
"change": "变更",
"change-avatar": "更改头像",
"change-password": "更改密码",
@@ -145,7 +149,7 @@
"changePasswordPopup-title": "更改密码",
"changePermissionsPopup-title": "更改权限",
"changeSettingsPopup-title": "更改设置",
- "subtasks": "Subtasks",
+ "subtasks": "子任务",
"checklists": "清单",
"click-to-star": "点此来标记该看板",
"click-to-unstar": "点此来去除该看板的标记",
@@ -167,10 +171,14 @@
"comment-placeholder": "添加评论",
"comment-only": "仅能评论",
"comment-only-desc": "只能在卡片上评论。",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "从本机上传",
- "confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
- "confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
+ "confirm-subtask-delete-dialog": "确定要删除子任务吗?",
+ "confirm-checklist-delete-dialog": "确定要删除清单吗?",
"copy-card-link-to-clipboard": "复制卡片链接到剪贴板",
+ "linkCardPopup-title": "链接卡片",
+ "searchCardPopup-title": "搜索卡片",
"copyCardPopup-title": "复制卡片",
"copyChecklistToManyCardsPopup-title": "复制清单模板至多个卡片",
"copyChecklistToManyCardsPopup-instructions": "以JSON格式表示目标卡片的标题和描述",
@@ -200,8 +208,8 @@
"deleteCustomFieldPopup-title": "删除自定义字段?",
"deleteLabelPopup-title": "删除标签?",
"description": "描述",
- "disambiguateMultiLabelPopup-title": "标签消歧 [?]",
- "disambiguateMultiMemberPopup-title": "成员消歧 [?]",
+ "disambiguateMultiLabelPopup-title": "消除标签歧义",
+ "disambiguateMultiMemberPopup-title": "消除成员歧义",
"discard": "放弃",
"done": "完成",
"download": "下载",
@@ -209,7 +217,7 @@
"edit-avatar": "更改头像",
"edit-profile": "编辑资料",
"edit-wip-limit": "编辑最大任务数",
- "soft-wip-limit": "软在制品限制",
+ "soft-wip-limit": "最大任务数软限制",
"editCardStartDatePopup-title": "修改起始日期",
"editCardDueDatePopup-title": "修改截止日期",
"editCustomFieldPopup-title": "编辑字段",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "创建看板",
"home": "首页",
"import": "导入",
+ "link": "链接",
"import-board": "导入看板",
"import-board-c": "导入看板",
"import-board-title-trello": "从Trello导入看板",
@@ -482,21 +491,21 @@
"delete-board-confirm-popup": "所有列表、卡片、标签和活动都回被删除,将无法恢复看板内容。不支持撤销。",
"boardDeletePopup-title": "删除看板?",
"delete-board": "删除看板",
- "default-subtasks-board": "Subtasks for __board__ board",
- "default": "Default",
- "queue": "Queue",
- "subtask-settings": "Subtasks Settings",
- "boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
- "show-subtasks-field": "Cards can have subtasks",
- "deposit-subtasks-board": "Deposit subtasks to this board:",
- "deposit-subtasks-list": "Landing list for subtasks deposited here:",
- "show-parent-in-minicard": "Show parent in minicard:",
- "prefix-with-full-path": "Prefix with full path",
- "prefix-with-parent": "Prefix with parent",
- "subtext-with-full-path": "Subtext with full path",
- "subtext-with-parent": "Subtext with parent",
- "change-card-parent": "Change card's parent",
- "parent-card": "Parent card",
- "source-board": "Source board",
- "no-parent": "Don't show parent"
+ "default-subtasks-board": "__board__ 看板的子任务",
+ "default": "缺省",
+ "queue": "队列",
+ "subtask-settings": "子任务设置",
+ "boardSubtaskSettingsPopup-title": "看板子任务设置",
+ "show-subtasks-field": "卡片包含子任务",
+ "deposit-subtasks-board": "将子任务放入以下看板:",
+ "deposit-subtasks-list": "将子任务放入以下列表:",
+ "show-parent-in-minicard": "显示上一级卡片:",
+ "prefix-with-full-path": "完整路径前缀",
+ "prefix-with-parent": "上级前缀",
+ "subtext-with-full-path": "子标题显示完整路径",
+ "subtext-with-parent": "子标题显示上级",
+ "change-card-parent": "修改卡片的上级",
+ "parent-card": "上级卡片",
+ "source-board": "源看板",
+ "no-parent": "不显示上级"
} \ No newline at end of file
diff --git a/i18n/zh-TW.i18n.json b/i18n/zh-TW.i18n.json
index e8bcbd2c..6a60d8b7 100644
--- a/i18n/zh-TW.i18n.json
+++ b/i18n/zh-TW.i18n.json
@@ -109,6 +109,7 @@
"bucket-example": "例如 “目標清單”",
"cancel": "取消",
"card-archived": "This card is moved to Recycle Bin.",
+ "board-archived": "This board is moved to Recycle Bin.",
"card-comments-title": "該卡片有 %s 則評論",
"card-delete-notice": "徹底刪除的操作不可復原,你將會遺失該卡片相關的所有操作記錄。",
"card-delete-pop": "所有的動作將從活動動態中被移除且您將無法重新打開該卡片。此操作無法復原。",
@@ -135,6 +136,9 @@
"cards": "卡片",
"cards-count": "卡片",
"casSignIn": "Sign In with CAS",
+ "cardType-card": "Card",
+ "cardType-linkedCard": "Linked Card",
+ "cardType-linkedBoard": "Linked Board",
"change": "變更",
"change-avatar": "更改大頭貼",
"change-password": "更改密碼",
@@ -167,10 +171,14 @@
"comment-placeholder": "新增評論",
"comment-only": "只可以發表評論",
"comment-only-desc": "只可以對卡片發表評論",
+ "no-comments": "No comments",
+ "no-comments-desc": "Can not see comments and activities.",
"computer": "從本機上傳",
"confirm-subtask-delete-dialog": "Are you sure you want to delete subtask?",
"confirm-checklist-delete-dialog": "Are you sure you want to delete checklist?",
"copy-card-link-to-clipboard": "將卡片連結複製到剪貼板",
+ "linkCardPopup-title": "Link Card",
+ "searchCardPopup-title": "Search Card",
"copyCardPopup-title": "Copy Card",
"copyChecklistToManyCardsPopup-title": "Copy Checklist Template to Many Cards",
"copyChecklistToManyCardsPopup-instructions": "Destination Card Titles and Descriptions in this JSON format",
@@ -261,6 +269,7 @@
"headerBarCreateBoardPopup-title": "建立看板",
"home": "首頁",
"import": "匯入",
+ "link": "Link",
"import-board": "匯入看板",
"import-board-c": "匯入看板",
"import-board-title-trello": "匯入在 Trello 的看板",
diff --git a/models/activities.js b/models/activities.js
index fe24c9c4..c14760c2 100644
--- a/models/activities.js
+++ b/models/activities.js
@@ -128,6 +128,9 @@ if (Meteor.isServer) {
params.url = card.absoluteUrl();
params.cardId = activity.cardId;
}
+ if (activity.swimlaneId) {
+ params.swimlaneId = activity.swimlaneId;
+ }
if (activity.commentId) {
const comment = activity.comment();
params.comment = comment.text;
diff --git a/models/boards.js b/models/boards.js
index c77c9de2..641ecdb9 100644
--- a/models/boards.js
+++ b/models/boards.js
@@ -110,6 +110,7 @@ Boards.attachSchema(new SimpleSchema({
userId: this.userId,
isAdmin: true,
isActive: true,
+ isNoComments: false,
isCommentOnly: false,
}];
}
@@ -124,6 +125,9 @@ Boards.attachSchema(new SimpleSchema({
'members.$.isActive': {
type: Boolean,
},
+ 'members.$.isNoComments': {
+ type: Boolean,
+ },
'members.$.isCommentOnly': {
type: Boolean,
},
@@ -177,6 +181,28 @@ Boards.attachSchema(new SimpleSchema({
optional: true,
defaultValue: 'no-parent',
},
+ startAt: {
+ type: Date,
+ optional: true,
+ },
+ dueAt: {
+ type: Date,
+ optional: true,
+ },
+ endAt: {
+ type: Date,
+ optional: true,
+ },
+ spentTime: {
+ type: Number,
+ decimal: true,
+ optional: true,
+ },
+ isOvertime: {
+ type: Boolean,
+ defaultValue: false,
+ optional: true,
+ },
}));
@@ -212,6 +238,10 @@ Boards.helpers({
return this.permission === 'public';
},
+ cards() {
+ return Cards.find({ boardId: this._id, archived: false }, { sort: { title: 1 } });
+ },
+
lists() {
return Lists.find({ boardId: this._id, archived: false }, { sort: { sort: 1 } });
},
@@ -220,10 +250,6 @@ Boards.helpers({
return Swimlanes.find({ boardId: this._id, archived: false }, { sort: { sort: 1 } });
},
- cards() {
- return Cards.find({ boardId: this._id, archived: false }, { sort: { sort: 1 } });
- },
-
hasOvertimeCards(){
const card = Cards.findOne({isOvertime: true, boardId: this._id, archived: false} );
return card !== undefined;
@@ -274,6 +300,10 @@ Boards.helpers({
return !!_.findWhere(this.members, { userId: memberId, isActive: true, isAdmin: true });
},
+ hasNoComments(memberId) {
+ return !!_.findWhere(this.members, { userId: memberId, isActive: true, isAdmin: false, isNoComments: true });
+ },
+
hasCommentOnly(memberId) {
return !!_.findWhere(this.members, { userId: memberId, isActive: true, isAdmin: false, isCommentOnly: true });
},
@@ -298,22 +328,22 @@ Boards.helpers({
return _id;
},
- searchCards(term) {
+ searchCards(term, excludeLinked) {
check(term, Match.OneOf(String, null, undefined));
- let query = { boardId: this._id };
+ const query = { boardId: this._id };
+ if (excludeLinked) {
+ query.linkedId = null;
+ }
const projection = { limit: 10, sort: { createdAt: -1 } };
if (term) {
const regex = new RegExp(term, 'i');
- query = {
- boardId: this._id,
- $or: [
- { title: regex },
- { description: regex },
- ],
- };
+ query.$or = [
+ { title: regex },
+ { description: regex },
+ ];
}
return Cards.find(query, projection);
@@ -376,6 +406,7 @@ Boards.helpers({
cardsInInterval(start, end) {
return Cards.find({
+ boardId: this._id,
$or: [
{
startAt: {
@@ -482,6 +513,7 @@ Boards.mutations({
userId: memberId,
isAdmin: false,
isActive: true,
+ isNoComments: false,
isCommentOnly: false,
},
},
@@ -509,7 +541,7 @@ Boards.mutations({
};
},
- setMemberPermission(memberId, isAdmin, isCommentOnly) {
+ setMemberPermission(memberId, isAdmin, isNoComments, isCommentOnly) {
const memberIndex = this.memberIndex(memberId);
// do not allow change permission of self
@@ -520,6 +552,7 @@ Boards.mutations({
return {
$set: {
[`members.${memberIndex}.isAdmin`]: isAdmin,
+ [`members.${memberIndex}.isNoComments`]: isNoComments,
[`members.${memberIndex}.isCommentOnly`]: isCommentOnly,
},
};
@@ -817,18 +850,24 @@ if (Meteor.isServer) {
members: [
{
userId: req.body.owner,
- isAdmin: true,
- isActive: true,
- isCommentOnly: false,
+ isAdmin: req.body.isAdmin || true,
+ isActive: req.body.isActive || true,
+ isNoComments: req.body.isNoComments || false,
+ isCommentOnly: req.body.isCommentOnly || false,
},
],
- permission: 'public',
- color: 'belize',
+ permission: req.body.permission || 'private',
+ color: req.body.color || 'belize',
+ });
+ const swimlaneId = Swimlanes.insert({
+ title: TAPi18n.__('default'),
+ boardId: id,
});
JsonRoutes.sendResult(res, {
code: 200,
data: {
_id: id,
+ defaultSwimlaneId: swimlaneId,
},
});
}
diff --git a/models/cards.js b/models/cards.js
index efc25a8f..2595e934 100644
--- a/models/cards.js
+++ b/models/cards.js
@@ -6,6 +6,8 @@ Cards = new Mongo.Collection('cards');
Cards.attachSchema(new SimpleSchema({
title: {
type: String,
+ optional: true,
+ defaultValue: '',
},
archived: {
type: Boolean,
@@ -22,6 +24,8 @@ Cards.attachSchema(new SimpleSchema({
},
listId: {
type: String,
+ optional: true,
+ defaultValue: '',
},
swimlaneId: {
type: String,
@@ -31,10 +35,14 @@ Cards.attachSchema(new SimpleSchema({
// difficult to manage and less efficient.
boardId: {
type: String,
+ optional: true,
+ defaultValue: '',
},
coverId: {
type: String,
optional: true,
+ defaultValue: '',
+
},
createdAt: {
type: Date,
@@ -49,15 +57,19 @@ Cards.attachSchema(new SimpleSchema({
customFields: {
type: [Object],
optional: true,
+ defaultValue: [],
},
'customFields.$': {
type: new SimpleSchema({
_id: {
type: String,
+ optional: true,
+ defaultValue: '',
},
value: {
type: Match.OneOf(String, Number, Boolean, Date),
optional: true,
+ defaultValue: '',
},
}),
},
@@ -70,22 +82,27 @@ Cards.attachSchema(new SimpleSchema({
description: {
type: String,
optional: true,
+ defaultValue: '',
},
requestedBy: {
type: String,
optional: true,
+ defaultValue: '',
},
assignedBy: {
type: String,
optional: true,
+ defaultValue: '',
},
labelIds: {
type: [String],
optional: true,
+ defaultValue: [],
},
members: {
type: [String],
optional: true,
+ defaultValue: [],
},
receivedAt: {
type: Date,
@@ -107,6 +124,7 @@ Cards.attachSchema(new SimpleSchema({
type: Number,
decimal: true,
optional: true,
+ defaultValue: 0,
},
isOvertime: {
type: Boolean,
@@ -126,6 +144,7 @@ Cards.attachSchema(new SimpleSchema({
sort: {
type: Number,
decimal: true,
+ defaultValue: '',
},
subtaskSort: {
type: Number,
@@ -133,6 +152,15 @@ Cards.attachSchema(new SimpleSchema({
defaultValue: -1,
optional: true,
},
+ type: {
+ type: String,
+ defaultValue: '',
+ },
+ linkedId: {
+ type: String,
+ optional: true,
+ defaultValue: '',
+ },
}));
Cards.allow({
@@ -174,37 +202,33 @@ Cards.helpers({
},
isAssigned(memberId) {
- return _.contains(this.members, memberId);
+ return _.contains(this.getMembers(), memberId);
},
activities() {
- return Activities.find({
- cardId: this._id
- }, {
- sort: {
- createdAt: -1
- }
- });
+ if (this.isLinkedCard()) {
+ return Activities.find({cardId: this.linkedId}, {sort: {createdAt: -1}});
+ } else if (this.isLinkedBoard()) {
+ return Activities.find({boardId: this.linkedId}, {sort: {createdAt: -1}});
+ } else {
+ return Activities.find({cardId: this._id}, {sort: {createdAt: -1}});
+ }
},
comments() {
- return CardComments.find({
- cardId: this._id
- }, {
- sort: {
- createdAt: -1
- }
- });
+ if (this.isLinkedCard()) {
+ return CardComments.find({cardId: this.linkedId}, {sort: {createdAt: -1}});
+ } else {
+ return CardComments.find({cardId: this._id}, {sort: {createdAt: -1}});
+ }
},
attachments() {
- return Attachments.find({
- cardId: this._id
- }, {
- sort: {
- uploadedAt: -1
- }
- });
+ if (this.isLinkedCard()) {
+ return Attachments.find({cardId: this.linkedId}, {sort: {uploadedAt: -1}});
+ } else {
+ return Attachments.find({cardId: this._id}, {sort: {uploadedAt: -1}});
+ }
},
cover() {
@@ -215,13 +239,11 @@ Cards.helpers({
},
checklists() {
- return Checklists.find({
- cardId: this._id
- }, {
- sort: {
- sort: 1
- }
- });
+ if (this.isLinkedCard()) {
+ return Checklists.find({cardId: this.linkedId}, {sort: { sort: 1 } });
+ } else {
+ return Checklists.find({cardId: this._id}, {sort: { sort: 1 } });
+ }
},
checklistItemCount() {
@@ -418,6 +440,396 @@ Cards.helpers({
isTopLevel() {
return this.parentId === '';
},
+
+ isLinkedCard() {
+ return this.type === 'cardType-linkedCard';
+ },
+
+ isLinkedBoard() {
+ return this.type === 'cardType-linkedBoard';
+ },
+
+ isLinked() {
+ return this.isLinkedCard() || this.isLinkedBoard();
+ },
+
+ setDescription(description) {
+ if (this.isLinkedCard()) {
+ return Cards.update({_id: this.linkedId}, {$set: {description}});
+ } else if (this.isLinkedBoard()) {
+ return Boards.update({_id: this.linkedId}, {$set: {description}});
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {description}}
+ );
+ }
+ },
+
+ getDescription() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({_id: this.linkedId});
+ if (card && card.description)
+ return card.description;
+ else
+ return null;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({_id: this.linkedId});
+ if (board && board.description)
+ return board.description;
+ else
+ return null;
+ } else if (this.description) {
+ return this.description;
+ } else {
+ return null;
+ }
+ },
+
+ getMembers() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({_id: this.linkedId});
+ return card.members;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({_id: this.linkedId});
+ return board.activeMembers().map((member) => {
+ return member.userId;
+ });
+ } else {
+ return this.members;
+ }
+ },
+
+ assignMember(memberId) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ { $addToSet: { members: memberId }}
+ );
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({_id: this.linkedId});
+ return board.addMember(memberId);
+ } else {
+ return Cards.update(
+ { _id: this._id },
+ { $addToSet: { members: memberId}}
+ );
+ }
+ },
+
+ unassignMember(memberId) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ { $pull: { members: memberId }}
+ );
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({_id: this.linkedId});
+ return board.removeMember(memberId);
+ } else {
+ return Cards.update(
+ { _id: this._id },
+ { $pull: { members: memberId}}
+ );
+ }
+ },
+
+ toggleMember(memberId) {
+ if (this.getMembers() && this.getMembers().indexOf(memberId) > -1) {
+ return this.unassignMember(memberId);
+ } else {
+ return this.assignMember(memberId);
+ }
+ },
+
+ getReceived() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({_id: this.linkedId});
+ return card.receivedAt;
+ } else {
+ return this.receivedAt;
+ }
+ },
+
+ setReceived(receivedAt) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ {_id: this.linkedId},
+ {$set: {receivedAt}}
+ );
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {receivedAt}}
+ );
+ }
+ },
+
+ getStart() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({_id: this.linkedId});
+ return card.startAt;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({_id: this.linkedId});
+ return board.startAt;
+ } else {
+ return this.startAt;
+ }
+ },
+
+ setStart(startAt) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ {$set: {startAt}}
+ );
+ } else if (this.isLinkedBoard()) {
+ return Boards.update(
+ {_id: this.linkedId},
+ {$set: {startAt}}
+ );
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {startAt}}
+ );
+ }
+ },
+
+ getDue() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({_id: this.linkedId});
+ return card.dueAt;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({_id: this.linkedId});
+ return board.dueAt;
+ } else {
+ return this.dueAt;
+ }
+ },
+
+ setDue(dueAt) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ {$set: {dueAt}}
+ );
+ } else if (this.isLinkedBoard()) {
+ return Boards.update(
+ {_id: this.linkedId},
+ {$set: {dueAt}}
+ );
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {dueAt}}
+ );
+ }
+ },
+
+ getEnd() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({_id: this.linkedId});
+ return card.endAt;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({_id: this.linkedId});
+ return board.endAt;
+ } else {
+ return this.endAt;
+ }
+ },
+
+ setEnd(endAt) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ {$set: {endAt}}
+ );
+ } else if (this.isLinkedBoard()) {
+ return Boards.update(
+ {_id: this.linkedId},
+ {$set: {endAt}}
+ );
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {endAt}}
+ );
+ }
+ },
+
+ getIsOvertime() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({ _id: this.linkedId });
+ return card.isOvertime;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({ _id: this.linkedId});
+ return board.isOvertime;
+ } else {
+ return this.isOvertime;
+ }
+ },
+
+ setIsOvertime(isOvertime) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ {$set: {isOvertime}}
+ );
+ } else if (this.isLinkedBoard()) {
+ return Boards.update(
+ {_id: this.linkedId},
+ {$set: {isOvertime}}
+ );
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {isOvertime}}
+ );
+ }
+ },
+
+ getSpentTime() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({ _id: this.linkedId });
+ return card.spentTime;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({ _id: this.linkedId});
+ return board.spentTime;
+ } else {
+ return this.spentTime;
+ }
+ },
+
+ setSpentTime(spentTime) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ {$set: {spentTime}}
+ );
+ } else if (this.isLinkedBoard()) {
+ return Boards.update(
+ {_id: this.linkedId},
+ {$set: {spentTime}}
+ );
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {spentTime}}
+ );
+ }
+ },
+
+ getId() {
+ if (this.isLinked()) {
+ return this.linkedId;
+ } else {
+ return this._id;
+ }
+ },
+
+ getTitle() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({ _id: this.linkedId });
+ return card.title;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({ _id: this.linkedId});
+ return board.title;
+ } else {
+ return this.title;
+ }
+ },
+
+ getBoardTitle() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({ _id: this.linkedId });
+ const board = Boards.findOne({ _id: card.boardId });
+ return board.title;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({ _id: this.linkedId});
+ return board.title;
+ } else {
+ const board = Boards.findOne({ _id: this.boardId });
+ return board.title;
+ }
+ },
+
+ setTitle(title) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ {$set: {title}}
+ );
+ } else if (this.isLinkedBoard()) {
+ return Boards.update(
+ {_id: this.linkedId},
+ {$set: {title}}
+ );
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {title}}
+ );
+ }
+ },
+
+ getArchived() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({ _id: this.linkedId });
+ return card.archived;
+ } else if (this.isLinkedBoard()) {
+ const board = Boards.findOne({ _id: this.linkedId});
+ return board.archived;
+ } else {
+ return this.archived;
+ }
+ },
+
+ setRequestedBy(requestedBy) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ {$set: {requestedBy}}
+ );
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {requestedBy}}
+ );
+ }
+ },
+
+ getRequestedBy() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({ _id: this.linkedId });
+ return card.requestedBy;
+ } else {
+ return this.requestedBy;
+ }
+ },
+
+ setAssignedBy(assignedBy) {
+ if (this.isLinkedCard()) {
+ return Cards.update(
+ { _id: this.linkedId },
+ {$set: {assignedBy}}
+ );
+ } else {
+ return Cards.update(
+ {_id: this._id},
+ {$set: {assignedBy}}
+ );
+ }
+ },
+
+ getAssignedBy() {
+ if (this.isLinkedCard()) {
+ const card = Cards.findOne({ _id: this.linkedId });
+ return card.assignedBy;
+ } else {
+ return this.assignedBy;
+ }
+ },
});
Cards.mutations({
@@ -521,6 +933,8 @@ Cards.mutations({
}
},
+<<<<<<< HEAD
+=======
assignMember(memberId) {
return {
$addToSet: {
@@ -545,6 +959,7 @@ Cards.mutations({
}
},
+>>>>>>> 36c04edb9f7cf16fb450b76598c4957968d4674b
assignCustomField(customFieldId) {
return {
$addToSet: {
@@ -605,6 +1020,8 @@ Cards.mutations({
};
},
+<<<<<<< HEAD
+=======
setReceived(receivedAt) {
return {
$set: {
@@ -694,6 +1111,7 @@ Cards.mutations({
};
},
+>>>>>>> 36c04edb9f7cf16fb450b76598c4957968d4674b
setParentId(parentId) {
return {
$set: {
@@ -701,13 +1119,13 @@ Cards.mutations({
}
};
},
-
});
//FUNCTIONS FOR creation of Activities
-function cardMove(userId, doc, fieldNames, oldListId) {
- if (_.contains(fieldNames, 'listId') && doc.listId !== oldListId) {
+function cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId) {
+ if ((_.contains(fieldNames, 'listId') && doc.listId !== oldListId) ||
+ (_.contains(fieldNames, 'swimlaneId') && doc.swimlaneId !== oldSwimlaneId)){
Activities.insert({
userId,
oldListId,
@@ -716,6 +1134,8 @@ function cardMove(userId, doc, fieldNames, oldListId) {
listId: doc.listId,
boardId: doc.boardId,
cardId: doc._id,
+ swimlaneId: doc.swimlaneId,
+ oldSwimlaneId,
});
}
}
@@ -821,6 +1241,7 @@ function cardCreation(userId, doc) {
listName: Lists.findOne(doc.listId).title,
listId: doc.listId,
cardId: doc._id,
+ swimlaneId: doc.swimlaneId,
});
}
@@ -846,10 +1267,13 @@ if (Meteor.isServer) {
// Cards are often fetched within a board, so we create an index to make these
// queries more efficient.
Meteor.startup(() => {
- Cards._collection._ensureIndex({
- boardId: 1,
- createdAt: -1
- });
+ Cards._collection._ensureIndex({boardId: 1, createdAt: -1});
+ // https://github.com/wekan/wekan/issues/1863
+ // Swimlane added a new field in the cards collection of mongodb named parentId.
+ // When loading a board, mongodb is searching for every cards, the id of the parent (in the swinglanes collection).
+ // With a huge database, this result in a very slow app and high CPU on the mongodb side.
+ // To correct it, add Index to parentId:
+ Cards._collection._ensureIndex({parentId: 1});
});
Cards.after.insert((userId, doc) => {
@@ -864,7 +1288,8 @@ if (Meteor.isServer) {
//New activity for card moves
Cards.after.update(function(userId, doc, fieldNames) {
const oldListId = this.previous.listId;
- cardMove(userId, doc, fieldNames, oldListId);
+ const oldSwimlaneId = this.previous.swimlaneId;
+ cardMove(userId, doc, fieldNames, oldListId, oldSwimlaneId);
});
// Add a new activity if we add or remove a member to the card
@@ -1025,6 +1450,51 @@ if (Meteor.isServer) {
}
});
}
+ if (req.body.hasOwnProperty('requestedBy')) {
+ const newrequestedBy = req.body.requestedBy;
+ Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false},
+ {$set: {requestedBy: newrequestedBy}});
+ }
+ if (req.body.hasOwnProperty('assignedBy')) {
+ const newassignedBy = req.body.assignedBy;
+ Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false},
+ {$set: {assignedBy: newassignedBy}});
+ }
+ if (req.body.hasOwnProperty('receivedAt')) {
+ const newreceivedAt = req.body.receivedAt;
+ Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false},
+ {$set: {receivedAt: newreceivedAt}});
+ }
+ if (req.body.hasOwnProperty('startAt')) {
+ const newstartAt = req.body.startAt;
+ Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false},
+ {$set: {startAt: newstartAt}});
+ }
+ if (req.body.hasOwnProperty('dueAt')) {
+ const newdueAt = req.body.dueAt;
+ Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false},
+ {$set: {dueAt: newdueAt}});
+ }
+ if (req.body.hasOwnProperty('endAt')) {
+ const newendAt = req.body.endAt;
+ Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false},
+ {$set: {endAt: newendAt}});
+ }
+ if (req.body.hasOwnProperty('spentTime')) {
+ const newspentTime = req.body.spentTime;
+ Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false},
+ {$set: {spentTime: newspentTime}});
+ }
+ if (req.body.hasOwnProperty('isOverTime')) {
+ const newisOverTime = req.body.isOverTime;
+ Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false},
+ {$set: {isOverTime: newisOverTime}});
+ }
+ if (req.body.hasOwnProperty('customFields')) {
+ const newcustomFields = req.body.customFields;
+ Cards.direct.update({_id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false},
+ {$set: {customFields: newcustomFields}});
+ }
JsonRoutes.sendResult(res, {
code: 200,
data: {
@@ -1056,4 +1526,4 @@ if (Meteor.isServer) {
});
});
-} \ No newline at end of file
+}
diff --git a/models/export.js b/models/export.js
index f4ea6789..c65ebf52 100644
--- a/models/export.js
+++ b/models/export.js
@@ -47,9 +47,8 @@ class Exporter {
}
build() {
- const byBoard = {
- boardId: this._boardId
- };
+ const byBoard = { boardId: this._boardId };
+ const byBoardNoLinked = { boardId: this._boardId, linkedId: '' };
// we do not want to retrieve boardId in related elements
const noBoardId = {
fields: {
@@ -65,8 +64,9 @@ class Exporter {
}
}));
result.lists = Lists.find(byBoard, noBoardId).fetch();
- result.cards = Cards.find(byBoard, noBoardId).fetch();
+ result.cards = Cards.find(byBoardNoLinked, noBoardId).fetch();
result.swimlanes = Swimlanes.find(byBoard, noBoardId).fetch();
+ result.customFields = CustomFields.find(byBoard, noBoardId).fetch();
result.comments = CardComments.find(byBoard, noBoardId).fetch();
result.activities = Activities.find(byBoard, noBoardId).fetch();
result.rules = Rules.find(byBoard, noBoardId).fetch();
@@ -182,4 +182,4 @@ class Exporter {
const board = Boards.findOne(this._boardId);
return board && board.isVisibleBy(user);
}
-} \ No newline at end of file
+}
diff --git a/models/lists.js b/models/lists.js
index ceda9ad1..bf5aae3c 100644
--- a/models/lists.js
+++ b/models/lists.js
@@ -63,13 +63,13 @@ Lists.attachSchema(new SimpleSchema({
Lists.allow({
insert(userId, doc) {
- return allowIsBoardMemberNonComment(userId, Boards.findOne(doc.boardId));
+ return allowIsBoardMemberCommentOnly(userId, Boards.findOne(doc.boardId));
},
update(userId, doc) {
- return allowIsBoardMemberNonComment(userId, Boards.findOne(doc.boardId));
+ return allowIsBoardMemberCommentOnly(userId, Boards.findOne(doc.boardId));
},
remove(userId, doc) {
- return allowIsBoardMemberNonComment(userId, Boards.findOne(doc.boardId));
+ return allowIsBoardMemberCommentOnly(userId, Boards.findOne(doc.boardId));
},
fetch: ['boardId'],
});
diff --git a/models/settings.js b/models/settings.js
index 34f693d9..3b9b4eae 100644
--- a/models/settings.js
+++ b/models/settings.js
@@ -96,6 +96,14 @@ if (Meteor.isServer) {
return (min + Math.round(rand * range));
}
+ function getEnvVar(name){
+ const value = process.env[name];
+ if (value){
+ return value;
+ }
+ throw new Meteor.Error(['var-not-exist', `The environment variable ${name} does not exist`]);
+ }
+
function sendInvitationEmail (_id){
const icode = InvitationCodes.findOne(_id);
const author = Users.findOne(Meteor.userId());
@@ -124,20 +132,33 @@ if (Meteor.isServer) {
sendInvitation(emails, boards) {
check(emails, [String]);
check(boards, [String]);
+
const user = Users.findOne(Meteor.userId());
if(!user.isAdmin){
throw new Meteor.Error('not-allowed');
}
emails.forEach((email) => {
if (email && SimpleSchema.RegEx.Email.test(email)) {
- const code = getRandomNum(100000, 999999);
- InvitationCodes.insert({code, email, boardsToBeInvited: boards, createdAt: new Date(), authorId: Meteor.userId()}, function(err, _id){
- if (!err && _id) {
- sendInvitationEmail(_id);
- } else {
- throw new Meteor.Error('invitation-generated-fail', err.message);
- }
- });
+ // Checks if the email is already link to an account.
+ const userExist = Users.findOne({email});
+ if (userExist){
+ throw new Meteor.Error('user-exist', `The user with the email ${email} has already an account.`);
+ }
+ // Checks if the email is already link to an invitation.
+ const invitation = InvitationCodes.findOne({email});
+ if (invitation){
+ InvitationCodes.update(invitation, {$set : {boardsToBeInvited: boards}});
+ sendInvitationEmail(invitation._id);
+ }else {
+ const code = getRandomNum(100000, 999999);
+ InvitationCodes.insert({code, email, boardsToBeInvited: boards, createdAt: new Date(), authorId: Meteor.userId()}, function(err, _id){
+ if (!err && _id) {
+ sendInvitationEmail(_id);
+ } else {
+ throw new Meteor.Error('invitation-generated-fail', err.message);
+ }
+ });
+ }
}
});
},
@@ -167,5 +188,14 @@ if (Meteor.isServer) {
email: user.emails[0].address,
};
},
+
+ getMatomoConf(){
+ return {
+ address: getEnvVar('MATOMO_ADDRESS'),
+ siteId: getEnvVar('MATOMO_SITE_ID'),
+ doNotTrack: process.env.MATOMO_DO_NOT_TRACK || false,
+ withUserName: process.env.MATOMO_WITH_USERNAME || false,
+ };
+ },
});
}
diff --git a/models/swimlanes.js b/models/swimlanes.js
index 72ef3f36..3559bcd2 100644
--- a/models/swimlanes.js
+++ b/models/swimlanes.js
@@ -46,13 +46,13 @@ Swimlanes.attachSchema(new SimpleSchema({
Swimlanes.allow({
insert(userId, doc) {
- return allowIsBoardMemberNonComment(userId, Boards.findOne(doc.boardId));
+ return allowIsBoardMemberCommentOnly(userId, Boards.findOne(doc.boardId));
},
update(userId, doc) {
- return allowIsBoardMemberNonComment(userId, Boards.findOne(doc.boardId));
+ return allowIsBoardMemberCommentOnly(userId, Boards.findOne(doc.boardId));
},
remove(userId, doc) {
- return allowIsBoardMemberNonComment(userId, Boards.findOne(doc.boardId));
+ return allowIsBoardMemberCommentOnly(userId, Boards.findOne(doc.boardId));
},
fetch: ['boardId'],
});
diff --git a/models/trelloCreator.js b/models/trelloCreator.js
index 30f0bc2b..b5a255cc 100644
--- a/models/trelloCreator.js
+++ b/models/trelloCreator.js
@@ -150,6 +150,7 @@ export class TrelloCreator {
userId: Meteor.userId(),
isAdmin: true,
isActive: true,
+ isNoComments: false,
isCommentOnly: false,
swimlaneId: false,
}],
@@ -177,6 +178,7 @@ export class TrelloCreator {
userId: wekanId,
isAdmin: this.getAdmin(trelloMembership.memberType),
isActive: true,
+ isNoComments: false,
isCommentOnly: false,
swimlaneId: false,
});
diff --git a/models/users.js b/models/users.js
index 5a7fbbe5..01673e4f 100644
--- a/models/users.js
+++ b/models/users.js
@@ -151,6 +151,16 @@ if (Meteor.isClient) {
return board && board.hasMember(this._id);
},
+ isNotNoComments() {
+ const board = Boards.findOne(Session.get('currentBoard'));
+ return board && board.hasMember(this._id) && !board.hasNoComments(this._id);
+ },
+
+ isNoComments() {
+ const board = Boards.findOne(Session.get('currentBoard'));
+ return board && board.hasNoComments(this._id);
+ },
+
isNotCommentOnly() {
const board = Boards.findOne(Session.get('currentBoard'));
return board && board.hasMember(this._id) && !board.hasCommentOnly(this._id);
@@ -478,6 +488,30 @@ if (Meteor.isServer) {
return user;
}
+ if (user.services.oidc) {
+ const email = user.services.oidc.email.toLowerCase();
+
+ user.username = user.services.oidc.username;
+ user.emails = [{ address: email, verified: true }];
+ const initials = user.services.oidc.fullname.match(/\b[a-zA-Z]/g).join('').toUpperCase();
+ user.profile = { initials, fullname: user.services.oidc.fullname };
+
+ // 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}]});
+ if (!existingUser)
+ return user;
+
+ // copy across new service info
+ const service = _.keys(user.services)[0];
+ existingUser.services[service] = user.services[service];
+ existingUser.emails = user.emails;
+ existingUser.username = user.username;
+ existingUser.profile = user.profile;
+
+ Meteor.users.remove({_id: existingUser._id}); // remove existing record
+ return existingUser;
+ }
+
if (options.from === 'admin') {
user.createdThroughApi = true;
return user;
@@ -501,9 +535,13 @@ if (Meteor.isServer) {
} else {
user.profile = {icode: options.profile.invitationcode};
user.profile.boardView = 'board-view-lists';
- }
- return user;
+ // Deletes the invitation code after the user was created successfully.
+ setTimeout(Meteor.bindEnvironment(() => {
+ InvitationCodes.remove({'_id': invitationCode._id});
+ }), 200);
+ return user;
+ }
});
}
@@ -618,9 +656,20 @@ if (Meteor.isServer) {
});
}
-
// USERS REST API
if (Meteor.isServer) {
+ // Middleware which checks that API is enabled.
+ JsonRoutes.Middleware.use(function (req, res, next) {
+ const api = req.url.search('api');
+ if (api === 1 && process.env.WITH_API === 'true' || api === -1){
+ return next();
+ }
+ else {
+ res.writeHead(301, {Location: '/'});
+ return res.end();
+ }
+ });
+
JsonRoutes.add('GET', '/api/user', function(req, res) {
try {
Authentication.checkLoggedIn(req.userId);
diff --git a/models/wekanCreator.js b/models/wekanCreator.js
index 33a2767a..6841a6ae 100644
--- a/models/wekanCreator.js
+++ b/models/wekanCreator.js
@@ -188,6 +188,7 @@ export class WekanCreator {
wekanId: Meteor.userId(),
isActive: true,
isAdmin: true,
+ isNoComments: false,
isCommentOnly: false,
swimlaneId: false,
}],
diff --git a/openshift/README.md b/openshift/README.md
new file mode 100644
index 00000000..a97657f3
--- /dev/null
+++ b/openshift/README.md
@@ -0,0 +1,19 @@
+# Wekan on OpenShift
+
+OpenShift Template for Wekan backed by MongoDB
+
+#### Create Template
+```sh
+oc create -f wekan.yml
+```
+
+#### Delete Instance Resources
+Clean up all resources created. Note label filters assume single instance of template deployed in the current namespace.
+
+```sh
+oc delete all -l app=wekan
+oc delete pods -l app=wekan
+oc delete persistentvolumeclaim -l app=wekan
+oc delete serviceaccount -l app=wekan
+oc delete secret -l app=wekan
+```
diff --git a/openshift/wekan.yml b/openshift/wekan.yml
new file mode 100644
index 00000000..0bc96ce8
--- /dev/null
+++ b/openshift/wekan.yml
@@ -0,0 +1,374 @@
+---
+apiVersion: v1
+kind: Template
+labels:
+ template: wekan-mongodb-persistent-template
+message: |-
+ The following service(s) have been created in your project: ${WEKAN_SERVICE_NAME}.
+metadata:
+ annotations:
+ description: |-
+ This template provides a Wekan instance backed by a standalone MongoDB
+ server. The database is stored on persistent storage.
+ iconClass: pficon-trend-up
+ openshift.io/display-name: Wekan backed by MongoDB
+ openshift.io/documentation-url: https://wekan.github.io/
+ openshift.io/long-description: This template provides a Wekan platform
+ with a MongoDB database created. The database is stored on persistent storage. The
+ database name, username, and password are chosen via parameters when provisioning
+ this service.
+ tags: wekan,kanban,mongodb
+ name: wekan-mongodb-persistent
+objects:
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: ${WEKAN_SERVICE_NAME}
+ labels:
+ app: wekan
+ service: ${WEKAN_SERVICE_NAME}
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ annotations:
+ template.openshift.io/expose-admin_password: "{.data['database-admin-password']}"
+ template.openshift.io/expose-database_name: "{.data['database-name']}"
+ template.openshift.io/expose-password: "{.data['database-password']}"
+ template.openshift.io/expose-username: "{.data['database-user']}"
+ name: "${DATABASE_SERVICE_NAME}"
+ labels:
+ app: wekan
+ service: ${WEKAN_SERVICE_NAME}
+ stringData:
+ database-admin-password: "${MONGODB_ADMIN_PASSWORD}"
+ database-name: "${MONGODB_DATABASE}"
+ database-password: "${MONGODB_PASSWORD}"
+ database-user: "${MONGODB_USER}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ template.openshift.io/expose-uri: http://{.spec.clusterIP}:{.spec.ports[?(.name=="wekan")].port}
+ name: "${WEKAN_SERVICE_NAME}"
+ labels:
+ app: wekan
+ service: ${WEKAN_SERVICE_NAME}
+ spec:
+ ports:
+ - name: wekan
+ nodePort: 0
+ port: 8080
+ protocol: TCP
+ targetPort: 8080
+ selector:
+ name: "${WEKAN_SERVICE_NAME}"
+ sessionAffinity: None
+ type: ClusterIP
+ status:
+ loadBalancer: {}
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ template.openshift.io/expose-uri: mongodb://{.spec.clusterIP}:{.spec.ports[?(.name=="mongo")].port}
+ name: "${DATABASE_SERVICE_NAME}"
+ labels:
+ app: wekan
+ service: ${WEKAN_SERVICE_NAME}
+ spec:
+ ports:
+ - name: mongo
+ nodePort: 0
+ port: 27017
+ protocol: TCP
+ targetPort: 27017
+ selector:
+ name: "${DATABASE_SERVICE_NAME}"
+ sessionAffinity: None
+ type: ClusterIP
+ status:
+ loadBalancer: {}
+- apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: "${DATABASE_SERVICE_NAME}"
+ labels:
+ app: wekan
+ service: ${WEKAN_SERVICE_NAME}
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: "${VOLUME_CAPACITY}"
+- apiVersion: image.openshift.io/v1
+ kind: ImageStream
+ metadata:
+ labels:
+ app: wekan
+ name: ${WEKAN_SERVICE_NAME}
+ spec:
+ tags:
+ - from:
+ kind: DockerImage
+ name: ${WEKAN_IMAGE}
+ generation: 2
+ name: latest
+ referencePolicy:
+ type: Source
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: ${WEKAN_SERVICE_NAME}
+ labels:
+ app: wekan
+ service: ${WEKAN_SERVICE_NAME}
+ spec:
+ replicas: 1
+ selector:
+ app: wekan
+ deploymentconfig: ${WEKAN_SERVICE_NAME}
+ strategy:
+ type: Recreate
+ template:
+ metadata:
+ labels:
+ app: wekan
+ service: ${WEKAN_SERVICE_NAME}
+ deploymentconfig: ${WEKAN_SERVICE_NAME}
+ template: wekan
+ name: ${WEKAN_SERVICE_NAME}
+ spec:
+ containers:
+ - name: ${WEKAN_SERVICE_NAME}
+ image: ${WEKAN_IMAGE}
+ imagePullPolicy: Always
+ env:
+ - name: MONGO_URL
+ value: mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@${DATABASE_SERVICE_NAME}:27017/${MONGODB_DATABASE}
+ - name: ROOT_URL
+ value: https://${FQDN}/
+ - name: PORT
+ value: "8080"
+ ports:
+ - containerPort: 8080
+ name: ${WEKAN_SERVICE_NAME}
+ protocol: TCP
+ terminationMessagePath: /dev/termination-log
+ livenessProbe:
+ failureThreshold: 30
+ httpGet:
+ path: /
+ port: 8080
+ initialDelaySeconds: 240
+ timeoutSeconds: 3
+ readinessProbe:
+ httpGet:
+ path: /
+ port: 8080
+ initialDelaySeconds: 3
+ timeoutSeconds: 3
+ dnsPolicy: ClusterFirst
+ restartPolicy: Always
+ serviceAccount: ${WEKAN_SERVICE_NAME}
+ serviceAccountName: ${WEKAN_SERVICE_NAME}
+ terminationGracePeriodSeconds: 30
+ triggers:
+ - type: ConfigChange
+ - type: ImageChange
+ imageChangeParams:
+ automatic: true
+ containerNames:
+ - ${WEKAN_SERVICE_NAME}
+ from:
+ kind: ImageStreamTag
+ name: ${WEKAN_SERVICE_NAME}:latest
+ lastTriggeredImage: ""
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ annotations:
+ template.alpha.openshift.io/wait-for-ready: 'true'
+ name: "${DATABASE_SERVICE_NAME}"
+ labels:
+ app: wekan
+ service: ${WEKAN_SERVICE_NAME}
+ spec:
+ replicas: 1
+ selector:
+ name: "${DATABASE_SERVICE_NAME}"
+ strategy:
+ type: Recreate
+ template:
+ metadata:
+ labels:
+ name: "${DATABASE_SERVICE_NAME}"
+ spec:
+ containers:
+ - capabilities: {}
+ env:
+ - name: MONGODB_USER
+ valueFrom:
+ secretKeyRef:
+ key: database-user
+ name: "${DATABASE_SERVICE_NAME}"
+ - name: MONGODB_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ key: database-password
+ name: "${DATABASE_SERVICE_NAME}"
+ - name: MONGODB_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ key: database-admin-password
+ name: "${DATABASE_SERVICE_NAME}"
+ - name: MONGODB_DATABASE
+ valueFrom:
+ secretKeyRef:
+ key: database-name
+ name: "${DATABASE_SERVICE_NAME}"
+ image: " "
+ imagePullPolicy: IfNotPresent
+ livenessProbe:
+ initialDelaySeconds: 30
+ tcpSocket:
+ port: 27017
+ timeoutSeconds: 1
+ name: mongodb
+ ports:
+ - containerPort: 27017
+ protocol: TCP
+ readinessProbe:
+ exec:
+ command:
+ - "/bin/sh"
+ - "-i"
+ - "-c"
+ - mongo 127.0.0.1:27017/$MONGODB_DATABASE -u $MONGODB_USER -p $MONGODB_PASSWORD
+ --eval="quit()"
+ initialDelaySeconds: 3
+ timeoutSeconds: 1
+ resources:
+ limits:
+ memory: "${MEMORY_LIMIT}"
+ securityContext:
+ capabilities: {}
+ privileged: false
+ terminationMessagePath: "/dev/termination-log"
+ volumeMounts:
+ - mountPath: "/var/lib/mongodb/data"
+ name: "${DATABASE_SERVICE_NAME}-data"
+ dnsPolicy: ClusterFirst
+ restartPolicy: Always
+ volumes:
+ - name: "${DATABASE_SERVICE_NAME}-data"
+ persistentVolumeClaim:
+ claimName: "${DATABASE_SERVICE_NAME}"
+ triggers:
+ - imageChangeParams:
+ automatic: true
+ containerNames:
+ - mongodb
+ from:
+ kind: ImageStreamTag
+ name: mongodb:${MONGODB_VERSION}
+ namespace: "openshift"
+ lastTriggeredImage: ''
+ type: ImageChange
+ - type: ConfigChange
+ status: {}
+- apiVersion: route.openshift.io/v1
+ kind: Route
+ metadata:
+ labels:
+ app: wekan
+ service: wekan
+ template: wekan-mongodb-persistent-template
+ name: wekan
+ namespace: ${NAMESPACE}
+ spec:
+ host: ${FQDN}
+ port:
+ targetPort: wekan
+ tls:
+ termination: edge
+ to:
+ kind: Service
+ name: wekan
+ weight: 100
+ wildcardPolicy: None
+ status:
+ ingress:
+ - conditions:
+ - lastTransitionTime: '2018-08-28T14:45:21Z'
+ status: 'True'
+ type: Admitted
+ host: ${FQDN}
+ routerName: router
+ wildcardPolicy: None
+parameters:
+- description: The Fully Qualified Hostname (FQDN) of the application
+ displayName: FQDN
+ name: FQDN
+ required: true
+- description: Maximum amount of memory the container can use.
+ displayName: Memory Limit
+ name: MEMORY_LIMIT
+ required: true
+ value: 512Mi
+- description: The OpenShift Namespace where the ImageStream resides.
+ displayName: Namespace
+ name: NAMESPACE
+ value: openshift
+- description: The name of the OpenShift Service exposed for the database.
+ displayName: Database Service Name
+ name: DATABASE_SERVICE_NAME
+ required: true
+ value: mongodb
+- description: Username for MongoDB user that will be used for accessing the database.
+ displayName: MongoDB Connection Username
+ from: user[A-Z0-9]{3}
+ generate: expression
+ name: MONGODB_USER
+ required: true
+- description: Password for the MongoDB connection user.
+ displayName: MongoDB Connection Password
+ from: "[a-zA-Z0-9]{16}"
+ generate: expression
+ name: MONGODB_PASSWORD
+ required: true
+- description: Name of the MongoDB database accessed.
+ displayName: MongoDB Database Name
+ name: MONGODB_DATABASE
+ required: true
+ value: wekan
+- description: Password for the database admin user.
+ displayName: MongoDB Admin Password
+ from: "[a-zA-Z0-9]{16}"
+ generate: expression
+ name: MONGODB_ADMIN_PASSWORD
+ required: true
+- description: Volume space available for data, e.g. 512Mi, 2Gi.
+ displayName: Volume Capacity
+ name: VOLUME_CAPACITY
+ required: true
+ value: 1Gi
+- description: Version of MongoDB image to be used (2.4, 2.6, 3.2 or latest).
+ displayName: Version of MongoDB Image
+ name: MONGODB_VERSION
+ required: true
+ value: '3.2'
+- name: WEKAN_SERVICE_NAME
+ displayName: WeKan Service Name
+ value: wekan
+ required: true
+- name: WEKAN_IMAGE
+ displayName: WeKan Docker Image
+ value: quay.io/wekan/wekan:latest
+ description: The metabase docker image to use
+ required: true
+- name: WEKAN_SERVICE_NAME
+ displayName: WeKan Service Name
+ value: wekan
+ required: true
+
diff --git a/package.json b/package.json
index a773b645..0244ea0e 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "wekan",
- "version": "1.18.0",
- "description": "The open-source Trello-like kanban",
+ "version": "1.46.0",
+ "description": "The open-source kanban",
"private": true,
"scripts": {
"lint": "eslint --ignore-pattern 'packages/*' .",
@@ -28,6 +28,9 @@
"es6-promise": "^4.2.4",
"meteor-node-stubs": "^0.4.1",
"os": "^0.1.1",
- "xss": "^0.3.8"
+ "page": "^1.8.6",
+ "qs": "^6.5.2",
+ "source-map-support": "^0.5.9",
+ "xss": "^1.0.3"
}
}
diff --git a/public/old-wekan-logo.png b/public/old-wekan-logo.png
new file mode 100644
index 00000000..6a2740f2
--- /dev/null
+++ b/public/old-wekan-logo.png
Binary files differ
diff --git a/public/wekan-logo.png b/public/wekan-logo.png
index 6a2740f2..b553239e 100644
--- a/public/wekan-logo.png
+++ b/public/wekan-logo.png
Binary files differ
diff --git a/sandstorm-pkgdef.capnp b/sandstorm-pkgdef.capnp
index c894cce2..efe16ffd 100644
--- a/sandstorm-pkgdef.capnp
+++ b/sandstorm-pkgdef.capnp
@@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
appTitle = (defaultText = "Wekan"),
# The name of the app as it is displayed to the user.
- appVersion = 103,
+ appVersion = 131,
# Increment this for every release.
- appMarketingVersion = (defaultText = "1.18.0~2018-07-06"),
+ appMarketingVersion = (defaultText = "1.46.0~2018-09-15"),
# Human-readable presentation of the app version.
minUpgradableAppVersion = 0,
@@ -226,7 +226,7 @@ const pkgdef :Spk.PackageDefinition = (
verbPhrase = (defaultText = "removed from card"),
), ],
),
-
+ apiPath = "/",
saveIdentityCaps = true,
),
);
@@ -237,6 +237,20 @@ const myCommand :Spk.Manifest.Command = (
environ = [
# Note that this defines the *entire* environment seen by your app.
(key = "PATH", value = "/usr/local/bin:/usr/bin:/bin"),
+ (key = "WITH_API", value = "true"),
+ (key = "MATOMO_ADDRESS", value=""),
+ (key = "MATOMO_SITE_ID", value=""),
+ (key = "MATOMO_DO_NOT_TRACK", value="true"),
+ (key = "MATOMO_WITH_USERNAME", value="false"),
+ (key = "BROWSER_POLICY_ENABLED", value="true"),
+ (key = "TRUSTED_URL", value=""),
+ (key = "WEBHOOKS_ATTRIBUTES", value=""),
+ (key = "OAUTH2_CLIENT_ID", value=""),
+ (key = "OAUTH2_SECRET", value=""),
+ (key = "OAUTH2_SERVER_URL", value=""),
+ (key = "OAUTH2_AUTH_ENDPOINT", value=""),
+ (key = "OAUTH2_USERINFO_ENDPOINT", value=""),
+ (key = "OAUTH2_TOKEN_ENDPOINT", value=""),
(key = "SANDSTORM", value = "1"),
(key = "METEOR_SETTINGS", value = "{\"public\": {\"sandstorm\": true}}")
]
diff --git a/sandstorm.js b/sandstorm.js
index d34bc015..37dced92 100644
--- a/sandstorm.js
+++ b/sandstorm.js
@@ -208,7 +208,8 @@ if (isSandstorm && Meteor.isServer) {
const isActive = permissions.indexOf('participate') > -1;
const isAdmin = permissions.indexOf('configure') > -1;
const isCommentOnly = false;
- const permissionDoc = { userId, isActive, isAdmin, isCommentOnly };
+ const isNoComments = false;
+ const permissionDoc = { userId, isActive, isAdmin, isNoComments, isCommentOnly };
const boardMembers = Boards.findOne(sandstormBoard._id).members;
const memberIndex = _.pluck(boardMembers, 'userId').indexOf(userId);
diff --git a/scalingo.json b/scalingo.json
index 57acbacc..78601a45 100644
--- a/scalingo.json
+++ b/scalingo.json
@@ -1,8 +1,8 @@
{
"name": "wekan",
- "description": "The open-source Trello-like kanban (build with Meteor)",
+ "description": "The open-source kanban (built with Meteor)",
"repository": "https://github.com/wekan/wekan/",
"logo": "https://raw.githubusercontent.com/wekan/wekan/master/meta/icons/wekan-150.png",
- "website": "https://wekan.io",
+ "website": "https://wekan.github.io",
"addons": ["scalingo-mongodb"]
}
diff --git a/server/authentication.js b/server/authentication.js
index 8059f176..6310e8df 100644
--- a/server/authentication.js
+++ b/server/authentication.js
@@ -62,5 +62,28 @@ Meteor.startup(() => {
Authentication.checkAdminOrCondition(userId, normalAccess);
};
+ if (Meteor.isServer) {
+
+ if(process.env.OAUTH2_CLIENT_ID !== '') {
+
+ ServiceConfiguration.configurations.upsert( // eslint-disable-line no-undef
+ { service: 'oidc' },
+ {
+ $set: {
+ loginStyle: 'redirect',
+ clientId: process.env.OAUTH2_CLIENT_ID,
+ secret: process.env.OAUTH2_SECRET,
+ serverUrl: process.env.OAUTH2_SERVER_URL,
+ authorizationEndpoint: process.env.OAUTH2_AUTH_ENDPOINT,
+ userinfoEndpoint: process.env.OAUTH2_USERINFO_ENDPOINT,
+ tokenEndpoint: process.env.OAUTH2_TOKEN_ENDPOINT,
+ idTokenWhitelistFields: [],
+ requestPermissions: ['openid'],
+ },
+ }
+ );
+ }
+ }
+
});
diff --git a/server/lib/utils.js b/server/lib/utils.js
index 17e63514..c155cda5 100644
--- a/server/lib/utils.js
+++ b/server/lib/utils.js
@@ -6,11 +6,15 @@ allowIsBoardMember = function(userId, board) {
return board && board.hasMember(userId);
};
-allowIsBoardMemberNonComment = function(userId, board) {
- return board && board.hasMember(userId) && !board.hasCommentOnly(userId);
+allowIsBoardMemberCommentOnly = function(userId, board) {
+ return board && board.hasMember(userId) && !board.hasCommentOnly(userId);
+};
+
+allowIsBoardMemberNoComments = function(userId, board) {
+ return board && board.hasMember(userId) && !board.hasNoComments(userId);
};
allowIsBoardMemberByCard = function(userId, card) {
const board = card.board();
return board && board.hasMember(userId);
-}; \ No newline at end of file
+};
diff --git a/server/migrations.js b/server/migrations.js
index 6135f1be..91c34be2 100644
--- a/server/migrations.js
+++ b/server/migrations.js
@@ -213,6 +213,18 @@ Migrations.add('add-profile-view', () => {
});
});
+Migrations.add('add-card-types', () => {
+ Cards.find().forEach((card) => {
+ Cards.direct.update(
+ { _id: card._id },
+ { $set: {
+ type: 'cardType-card',
+ linkedId: null } },
+ noValidate
+ );
+ });
+});
+
Migrations.add('add-custom-fields-to-cards', () => {
Cards.update({
customFields: {
diff --git a/server/notifications/outgoing.js b/server/notifications/outgoing.js
index 779d41a0..aac8749e 100644
--- a/server/notifications/outgoing.js
+++ b/server/notifications/outgoing.js
@@ -8,6 +8,8 @@ const postCatchError = Meteor.wrapAsync((url, options, resolve) => {
});
});
+const webhooksAtbts = ( (process.env.WEBHOOKS_ATTRIBUTES && process.env.WEBHOOKS_ATTRIBUTES.split(',') ) || ['cardId', 'listId', 'oldListId', 'boardId', 'comment', 'user', 'card', 'commentId', 'swimlaneId']);
+
Meteor.methods({
outgoingWebhooks(integrations, description, params) {
check(integrations, Array);
@@ -19,7 +21,7 @@ Meteor.methods({
if (quoteParams[key]) quoteParams[key] = `"${params[key]}"`;
});
- const userId = (params.userId)?params.userId:integrations[0].userId;
+ const userId = (params.userId) ? params.userId : integrations[0].userId;
const user = Users.findOne(userId);
const text = `${params.user} ${TAPi18n.__(description, quoteParams, user.getLanguage())}\n${params.url}`;
@@ -29,10 +31,7 @@ Meteor.methods({
text: `${text}`,
};
- [ 'cardId', 'listId', 'oldListId',
- 'boardId', 'comment', 'user',
- 'card', 'commentId',
- ].forEach((key) => {
+ webhooksAtbts.forEach((key) => {
if (params[key]) value[key] = params[key];
});
value.description = description;
diff --git a/server/policy.js b/server/policy.js
new file mode 100644
index 00000000..02a42cd4
--- /dev/null
+++ b/server/policy.js
@@ -0,0 +1,34 @@
+import { BrowserPolicy } from 'meteor/browser-policy-common';
+
+Meteor.startup(() => {
+
+ if ( process.env.BROWSER_POLICY_ENABLED === 'true' ) {
+ // Trusted URL that can embed Wekan in iFrame.
+ const trusted = process.env.TRUSTED_URL;
+ BrowserPolicy.framing.disallow();
+ //Allow inline scripts, otherwise there is errors in browser/inspect/console
+ //BrowserPolicy.content.disallowInlineScripts();
+ //BrowserPolicy.content.disallowEval();
+ //BrowserPolicy.content.allowInlineStyles();
+ //BrowserPolicy.content.allowFontDataUrl();
+ BrowserPolicy.framing.restrictToOrigin(trusted);
+ //BrowserPolicy.content.allowScriptOrigin(trusted);
+ }
+ else {
+ // Disable browser policy and allow all framing and including.
+ // Use only at internal LAN, not at Internet.
+ BrowserPolicy.framing.allowAll();
+ //BrowserPolicy.content.allowDataUrlForAll();
+ }
+
+ // Allow all images from anywhere
+ //BrowserPolicy.content.allowImageOrigin('*');
+
+ // If Matomo URL is set, allow it.
+ const matomoUrl = process.env.MATOMO_ADDRESS;
+ if (matomoUrl){
+ //BrowserPolicy.content.allowScriptOrigin(matomoUrl);
+ //BrowserPolicy.content.allowImageOrigin(matomoUrl);
+ }
+
+});
diff --git a/server/publications/boards.js b/server/publications/boards.js
index 5d095c17..fb4c8c84 100644
--- a/server/publications/boards.js
+++ b/server/publications/boards.js
@@ -98,7 +98,17 @@ Meteor.publishRelations('board', function(boardId) {
//
// And in the meantime our code below works pretty well -- it's not even a
// hack!
- this.cursor(Cards.find({ boardId }), function(cardId) {
+ this.cursor(Cards.find({ boardId }), function(cardId, card) {
+ if (card.type === 'cardType-linkedCard') {
+ const impCardId = card.linkedId;
+ this.cursor(Cards.find({ _id: impCardId }));
+ this.cursor(CardComments.find({ cardId: impCardId }));
+ this.cursor(Attachments.find({ cardId: impCardId }));
+ this.cursor(Checklists.find({ cardId: impCardId }));
+ this.cursor(ChecklistItems.find({ cardId: impCardId }));
+ } else if (card.type === 'cardType-linkedBoard') {
+ this.cursor(Boards.find({ _id: card.linkedId}));
+ }
this.cursor(CardComments.find({ cardId }));
this.cursor(Attachments.find({ cardId }));
this.cursor(Checklists.find({ cardId }));
diff --git a/snap-src/Caddyfile b/snap-src/Caddyfile
index 07ed4143..2a9867d8 100644
--- a/snap-src/Caddyfile
+++ b/snap-src/Caddyfile
@@ -3,3 +3,16 @@ proxy / localhost:3001 {
websocket
transparent
}
+
+## SSL/TLS example. Firefox Inspect Console does not support http/2, so turning it off
+## so that Firefox would not show wss websocket errors. Chrome console supports http/2.
+#
+#wekan.example.com {
+# tls {
+# alpn http/1.1
+# }
+# proxy / localhost:3001 {
+# websocket
+# transparent
+# }
+#}
diff --git a/snap-src/bin/caddy-control b/snap-src/bin/caddy-control
index 46d36c6b..1905603c 100755
--- a/snap-src/bin/caddy-control
+++ b/snap-src/bin/caddy-control
@@ -4,7 +4,7 @@
source $SNAP/bin/wekan-read-settings
if [ "$CADDY_ENABLED" = "true" ]; then
- env LC_ALL=C caddy -conf=$SNAP_COMMON/Caddyfile -host=localhost:${CADDY_PORT}
+ env LC_ALL=C caddy -conf=$SNAP_COMMON/Caddyfile -host=localhost:${CADDY_PORT} -agree
else
echo "caddy is disabled. Stop service"
snapctl stop --disable ${SNAP_NAME}.caddy
diff --git a/snap-src/bin/config b/snap-src/bin/config
index 813c3d3f..ffc39459 100755
--- a/snap-src/bin/config
+++ b/snap-src/bin/config
@@ -3,7 +3,7 @@
# All supported keys are defined here together with descriptions and default values
# list of supported keys
-keys="MONGODB_BIND_UNIX_SOCKET MONGODB_BIND_IP MONGODB_PORT MAIL_URL MAIL_FROM ROOT_URL PORT DISABLE_MONGODB CADDY_ENABLED CADDY_BIND_PORT"
+keys="MONGODB_BIND_UNIX_SOCKET MONGODB_BIND_IP MONGODB_PORT MAIL_URL MAIL_FROM ROOT_URL PORT DISABLE_MONGODB CADDY_ENABLED CADDY_BIND_PORT WITH_API MATOMO_ADDRESS MATOMO_SITE_ID MATOMO_DO_NOT_TRACK MATOMO_WITH_USERNAME BROWSER_POLICY_ENABLED TRUSTED_URL WEBHOOKS_ATTRIBUTES OAUTH2_CLIENT_ID OAUTH2_SECRET OAUTH2_SERVER_URL OAUTH2_AUTH_ENDPOINT OAUTH2_USERINFO_ENDPOINT OAUTH2_TOKEN_ENDPOINT"
# default values
DESCRIPTION_MONGODB_BIND_UNIX_SOCKET="mongodb binding unix socket:\n"\
@@ -47,3 +47,62 @@ KEY_CADDY_ENABLED="caddy-enabled"
DESCRIPTION_CADDY_BIND_PORT="Port on which caddy will expect proxy, value set here will be set in $SNAP_COMMON/Caddyfile"
DEFAULT_CADDY_BIND_PORT="3001"
KEY_CADDY_BIND_PORT="caddy-bind-port"
+
+DESCRIPTION_WITH_API="Enable/disable the api of wekan"
+DEFAULT_WITH_API="true"
+KEY_WITH_API="with-api"
+
+DESCRIPTION_MATOMO_ADDRESS="The address of the server where matomo is hosted"
+DEFAULT_MATOMO_ADDRESS=""
+KEY_MATOMO_ADDRESS="matomo-address"
+
+DESCRIPTION_MATOMO_SITE_ID="The value of the site ID given in matomo server for wekan"
+DEFAULT_MATOMO_SITE_ID=""
+KEY_MATOMO_SITE_ID="matomo-site-id"
+
+DESCRIPTION_MATOMO_DO_NOT_TRACK="The option do not track which enables users to not be tracked by matomo"
+DEFAULT_MATOMO_DO_NOT_TRACK="true"
+KEY_MATOMO_DO_NOT_TRACK="matomo-do-not-track"
+
+DESCRIPTION_MATOMO_WITH_USERNAME="The option that allows matomo to retrieve the username"
+DEFAULT_MATOMO_WITH_USERNAME="false"
+KEY_MATOMO_WITH_USERNAME="matomo-with-username"
+
+DESCRIPTION_BROWSER_POLICY_ENABLED="Enable browser policy and allow one trusted URL that can have iframe that has Wekan embedded inside.\n"\
+"\t\t\t Setting this to false is not recommended, it also disables all other browser policy protections\n"\
+"\t\t\t and allows all iframing etc. See wekan/server/policy.js"
+DEFAULT_BROWSER_POLICY_ENABLED="true"
+KEY_BROWSER_POLICY_ENABLED="browser-policy-enabled"
+
+DESCRIPTION_TRUSTED_URL="When browser policy is enabled, HTML code at this Trusted URL can have iframe that embeds Wekan inside."
+DEFAULT_TRUSTED_URL=""
+KEY_TRUSTED_URL="trusted-url"
+
+DESCRIPTION_WEBHOOKS_ATTRIBUTES="What to send to Outgoing Webhook, or leave out. Example, that includes all that are default: cardId,listId,oldListId,boardId,comment,user,card,commentId ."
+DEFAULT_WEBHOOKS_ATTRIBUTES=""
+KEY_WEBHOOKS_ATTRIBUTES="webhooks-attributes"
+
+DESCRIPTION_OAUTH2_CLIENT_ID="OAuth2 Client ID, for example from Rocket.Chat. Example: abcde12345"
+DEFAULT_OAUTH2_CLIENT_ID=""
+KEY_OAUTH2_CLIENT_ID="oauth2-client-id"
+
+DESCRIPTION_OAUTH2_SECRET="OAuth2 Secret, for example from Rocket.Chat: Example: 54321abcde"
+DEFAULT_OAUTH2_SECRET=""
+KEY_OAUTH2_SECRET="oauth2-secret"
+
+DESCRIPTION_OAUTH2_SERVER_URL="OAuth2 Server URL, for example Rocket.Chat. Example: https://chat.example.com"
+DEFAULT_OAUTH2_SERVER_URL=""
+KEY_OAUTH2_SERVER_URL="oauth2-server-url"
+
+DESCRIPTION_OAUTH2_AUTH_ENDPOINT="OAuth2 authorization endpoint. Example: /oauth/authorize"
+DEFAULT_OAUTH2_AUTH_ENDPOINT=""
+KEY_OAUTH2_AUTH_ENDPOINT="oauth2-auth-endpoint"
+
+DESCRIPTION_OAUTH2_USERINFO_ENDPOINT="OAuth2 userinfo endpoint. Example: /oauth/userinfo"
+DEFAULT_OAUTH2_USERINFO_ENDPOINT=""
+KEY_OAUTH2_USERINFO_ENDPOINT="oauth2-userinfo-endpoint"
+
+DESCRIPTION_OAUTH2_TOKEN_ENDPOINT="OAuth2 token endpoint. Example: /oauth/token"
+DEFAULT_OAUTH2_TOKEN_ENDPOINT=""
+KEY_OAUTH2_TOKEN_ENDPOINT="oauth2-token-endpoint"
+
diff --git a/snap-src/bin/wekan-help b/snap-src/bin/wekan-help
index ee565500..95814d36 100755
--- a/snap-src/bin/wekan-help
+++ b/snap-src/bin/wekan-help
@@ -7,7 +7,7 @@ if [ "$CADDY_ENABLED" = "true" ]; then
export PORT=${CADDY_PORT} &>/dev/null
fi
-echo -e "Wekan: The open-source Trello-like kanban.\n"
+echo -e "Wekan: The open-source kanban.\n"
echo -e "Make sure you have connected all interfaces, check more by calling $ snap interfaces ${SNAP_NAME}"
echo -e "\n"
echo -e "${SNAP_NAME} has multiple services, to check status use systemctl"
@@ -28,6 +28,73 @@ echo -e "\t\t-connect mongodb-plug with slot from snap providing mongodb"
echo -e "\t\t-disable mongodb in $SNAP_NAME by calling: $ snap set $SNAP_NAME set disable-mongodb='true'"
echo -e "\t\t-set mongodb-bind-unix-socket to point to serving mongodb. Use relative path inside shared directory, e.g run/mongodb-27017.sock"
echo -e "\n"
+echo -e "To enable the API of wekan:"
+echo -e "\t$ snap set $SNAP_NAME WITH_API='true'"
+echo -e "\t-Disable the API:"
+echo -e "\t$ snap set $SNAP_NAME WITH_API='false'"
+echo -e "\n"
+echo -e "Enable browser policy and allow one trusted URL that can have iframe that has Wekan embedded inside."
+echo -e "\t\t Setting this to false is not recommended, it also disables all other browser policy protections"
+echo -e "\t\t and allows all iframing etc. See wekan/server/policy.js"
+echo -e "To enable the Content Policy of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME CONTENT_POLICY_ENABLED='true'"
+echo -e "\t-Disable the Content Policy of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME CONTENT_POLICY_ENABLED='false'"
+echo -e "\n"
+echo -e "When browser policy is enabled, HTML code at this URL can have iframe that embeds Wekan inside."
+echo -e "To enable the Trusted URL of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME TRUSTED_URL='https://example.com'"
+echo -e "\t-Disable the Trusted URL of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME TRUSTED_URL=''"
+echo -e "\n"
+echo -e "What to send to Outgoing Webhook, or leave out. Example, that includes all that are default: cardId,listId,oldListId,boardId,comment,user,card,commentId ."
+echo -e "To enable the Webhooks Attributes of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME WEBHOOKS_ATTRIBUTES='cardId,listId,oldListId,boardId,comment,user,card,commentId'"
+echo -e "\t-Disable the Webhooks Attributes of Wekan to send all default ones:"
+echo -e "\t$ snap set $SNAP_NAME WEBHOOKS_ATTRIBUTES=''"
+echo -e "\n"
+echo -e "OAuth2 Client ID, for example from Rocket.Chat. Example: abcde12345"
+echo -e "To enable the OAuth2 Client ID of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_CLIENT_ID='54321abcde'"
+echo -e "\t-Disable the OAuth2 Client ID of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_CLIENT_ID=''"
+echo -e "\n"
+echo -e "OAuth2 Secret, for example from Rocket.Chat. Example: 54321abcde"
+echo -e "To enable the OAuth2 Secret of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_SECRET='54321abcde'"
+echo -e "\t-Disable the OAuth2 Secret of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_SECRET=''"
+echo -e "\n"
+echo -e "OAuth2 Server URL, for example Rocket.Chat. Example: https://chat.example.com"
+echo -e "To enable the OAuth2 Server URL of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_SERVER_URL='https://chat.example.com'"
+echo -e "\t-Disable the OAuth2 Server URL of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_SERVER_URL=''"
+echo -e "\n"
+echo -e "OAuth2 Server URL, for example Rocket.Chat. Example: https://chat.example.com"
+echo -e "To enable the OAuth2 Server URL of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_SERVER_URL='https://chat.example.com'"
+echo -e "\t-Disable the OAuth2 Server URL of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_SERVER_URL=''"
+echo -e "\n"
+echo -e "OAuth2 Authorization Endpoint. Example: /oauth/authorize"
+echo -e "To enable the OAuth2 Authorization Endpoint of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_AUTH_ENDPOINT='/oauth/authorize'"
+echo -e "\t-Disable the OAuth2 Authorization Endpoint of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_AUTH_ENDPOINT=''"
+echo -e "\n"
+echo -e "OAuth2 Userinfo Endpoint. Example: /oauth/userinfo"
+echo -e "To enable the OAuth2 Userinfo Endpoint of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_USERINFO_ENDPOINT='/oauth/authorize'"
+echo -e "\t-Disable the OAuth2 Userinfo Endpoint of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_USERINFO_ENDPOINT=''"
+echo -e "\n"
+echo -e "OAuth2 Token Endpoint. Example: /oauth/token"
+echo -e "To enable the OAuth2 Token Endpoint of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_TOKEN_ENDPOINT='/oauth/token'"
+echo -e "\t-Disable the OAuth2 Token Endpoint of Wekan:"
+echo -e "\t$ snap set $SNAP_NAME OAUTH2_TOKEN_ENDPOINT=''"
+echo -e "\n"
# parse config file for supported settings keys
echo -e "wekan supports settings keys"
echo -e "values can be changed by calling\n$ snap set $SNAP_NAME <key name>='<key value>'"
diff --git a/snapcraft.yaml b/snapcraft.yaml
index a25299aa..b91a2754 100644
--- a/snapcraft.yaml
+++ b/snapcraft.yaml
@@ -1,7 +1,7 @@
name: wekan
version: 0
version-script: git describe --dirty --tags | cut -c 2-
-summary: The open-source Trello-like kanban
+summary: The open-source kanban
description: |
Wekan is an open-source and collaborative kanban board application.
@@ -65,7 +65,7 @@ apps:
parts:
mongodb:
- source: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.2.20.tgz
+ source: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.2.21.tgz
plugin: dump
stage-packages: [libssl1.0.0]
filesets:
@@ -108,9 +108,9 @@ parts:
# Also see beginning of wekan/server/authentication.js
# import Fiber from "fibers";
# Fiber.poolSize = 1e9;
- # Download node version 8.11.3 that has fix included, node binary copied from Sandstorm
+ # Download node version 8.12.0 prerelease build,
# Description at https://releases.wekan.team/node.txt
- echo "5263dc1c571885921179b11a1c6eb9ca82a95a89b69c15b366f885e9b5a32d66 node" >> node-SHASUMS256.txt.asc
+ echo "375bd8db50b9c692c0bbba6e96d4114cd29bee3770f901c1ff2249d1038f1348 node" >> node-SHASUMS256.txt.asc
curl https://releases.wekan.team/node -o node
# Verify Fibers patched node authenticity
echo "Fibers 100% CPU issue patched node authenticity:"
@@ -128,12 +128,20 @@ parts:
chmod +x install_meteor.sh
sh install_meteor.sh
rm install_meteor.sh
- mkdir packages
- cd packages
- git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router
- git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core
- sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' meteor-useraccounts-core/package.js
- cd ..
+ if [ ! -d "packages" ]; then
+ mkdir packages
+ fi
+ if [ ! -d "packages/kadira-flow-router" ]; then
+ cd packages
+ git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router
+ cd ..
+ fi
+ if [ ! -d "packages/meteor-useraccounts-core" ]; then
+ cd packages
+ git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core
+ sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' meteor-useraccounts-core/package.js
+ cd ..
+ fi
rm -rf package-lock.json .build
meteor add standard-minifier-js --allow-superuser
meteor npm install --allow-superuser
@@ -168,7 +176,7 @@ parts:
caddy:
plugin: dump
- source: https://caddyserver.com/download/linux/amd64?license=personal
+ source: https://caddyserver.com/download/linux/amd64?plugins=http.filter,http.ipfilter,http.realip&license=personal&telemetry=off
source-type: tar
organize:
caddy: bin/caddy