Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4cadc5f4f3 | ||
|
|
8dfb6916c5 | ||
|
|
6066be944a | ||
|
|
e9f8279dbe | ||
|
|
454d3b5bbe | ||
|
|
fe185dd38a | ||
|
|
522b14d96d | ||
|
|
d98b489263 | ||
|
|
47ecc654b8 | ||
|
|
b9a4ae654e | ||
|
|
c40668be3f | ||
|
|
a9d77b975e | ||
|
|
085bf3b6e6 | ||
|
|
91dae9795e | ||
|
|
42081db0d8 | ||
|
|
3af417209c | ||
|
|
b6f60c08e5 | ||
|
|
03d7940829 | ||
|
|
0b263cf582 | ||
|
|
8ef60a06ad | ||
|
|
91eb4b941d | ||
|
|
2171690d22 | ||
|
|
6819303047 | ||
|
|
88e19bd011 | ||
|
|
09b9f690b1 | ||
|
|
7a9c397264 | ||
|
|
c2b7525864 | ||
|
|
e2ecd490ff | ||
|
|
1d3673e9d3 | ||
|
|
5bd85f975c | ||
|
|
89ab99b551 | ||
|
|
01de3f187c | ||
|
|
dcd7925571 | ||
|
|
34b6aa0858 | ||
|
|
73fb62e941 | ||
|
|
55ced412a0 | ||
|
|
04a8d85836 | ||
|
|
392b701956 | ||
|
|
dee098c125 | ||
|
|
56e26a65ae | ||
|
|
69509d597f | ||
|
|
bc7b18abe7 | ||
|
|
4a95cb42cd | ||
|
|
db311f677b | ||
|
|
685fb98e59 | ||
|
|
6dd98285a6 | ||
|
|
e225d29d7a | ||
|
|
eff7d123f2 | ||
|
|
4d62fe83f4 | ||
|
|
a37ca01703 | ||
|
|
ba05f383ca | ||
|
|
4ea4913d72 | ||
|
|
856f3bf864 | ||
|
|
238b0f0725 | ||
|
|
a79a5c7299 | ||
|
|
59580e4b0f | ||
|
|
7e05e02137 | ||
|
|
d4a1611b86 | ||
|
|
77abde7836 | ||
|
|
4c60916191 | ||
|
|
634eec7eb6 | ||
|
|
4ccbbc78cf | ||
|
|
4e1c0fdce8 | ||
|
|
9fa1d846e6 | ||
|
|
969dca292e | ||
|
|
84fde1ecfc | ||
|
|
db9ee59d9f | ||
|
|
20a2ea3e7a | ||
|
|
39b4ada26d | ||
|
|
3ddfe7c1fd | ||
|
|
f7955d5fd7 | ||
|
|
f115afb64e | ||
|
|
3145ec65a3 | ||
|
|
e2f690d0db | ||
|
|
e6c8c04394 | ||
|
|
a7741df5e4 | ||
|
|
912577cab3 | ||
|
|
cec43a63a7 | ||
|
|
10c9fc25a9 | ||
|
|
16665bccf9 | ||
|
|
103cfb936d | ||
|
|
4bb8f3ab27 | ||
|
|
36a4740429 | ||
|
|
ed54c09b48 | ||
|
|
6eb90238b1 | ||
|
|
aad300613d | ||
|
|
a2f8e54b67 | ||
|
|
c9a10efe5c | ||
|
|
7e2f802169 | ||
|
|
9df5a0f530 | ||
|
|
16971ff1d8 | ||
|
|
bef544ddc8 | ||
|
|
2c1f40357d | ||
|
|
ea544caf83 | ||
|
|
be9e98b2a1 | ||
|
|
59a3ac1f37 | ||
|
|
be22ca332b | ||
|
|
983e34ef80 | ||
|
|
c9830bc262 | ||
|
|
fc21c6d1d6 | ||
|
|
960f332dce | ||
|
|
d532a3591f | ||
|
|
03a9f4766a | ||
|
|
96f3e3a958 | ||
|
|
a249ffc805 | ||
|
|
5f53f8cc01 | ||
|
|
ca3f621572 | ||
|
|
a0e1b6f918 | ||
|
|
c76d44b5c7 | ||
|
|
ccc9efb270 | ||
|
|
2ebc34e901 | ||
|
|
04566d3f40 | ||
|
|
1083a92816 | ||
|
|
bb7490a32b | ||
|
|
9e8399612b | ||
|
|
df54863e72 | ||
|
|
8f340326b0 | ||
|
|
42975bc8ab | ||
|
|
adb5487cdc | ||
|
|
4aad9ca498 | ||
|
|
972d023e95 | ||
|
|
acabef4652 | ||
|
|
f77651ba05 | ||
|
|
23e349d277 | ||
|
|
37d9a6659a | ||
|
|
8796c46810 | ||
|
|
0ebb427a00 | ||
|
|
4960891bd9 | ||
|
|
43482d9e48 | ||
|
|
299410f8b4 | ||
|
|
07aa20a3cd | ||
|
|
ee323d97b4 | ||
|
|
d6b447f70a | ||
|
|
06cae36199 | ||
|
|
183404a5f8 | ||
|
|
6def7d6f70 | ||
|
|
097cae1f8c | ||
|
|
ba00311dd4 | ||
|
|
203fafdf7c | ||
|
|
62e90723d1 | ||
|
|
77372ccce1 | ||
|
|
849b608933 | ||
|
|
fdb4980b68 | ||
|
|
ff4f5e6c04 | ||
|
|
0bb3b67075 | ||
|
|
e16b06b44a | ||
|
|
ac9b23f00f | ||
|
|
f562bdd801 | ||
|
|
0c05942b45 | ||
|
|
9db3c93116 | ||
|
|
ce1f3365bb | ||
|
|
4ed5c3e4b8 | ||
|
|
9061180983 | ||
|
|
be970e4cea | ||
|
|
8f978c23b4 | ||
|
|
5f53c71b0c | ||
|
|
58020863a8 | ||
|
|
3ce3612047 | ||
|
|
44c9eebc4c | ||
|
|
cf6cc0e59d | ||
|
|
2b1fc8d07f | ||
|
|
e7d7ddd698 | ||
|
|
1d6bfc5dd6 | ||
|
|
0ccdbdcbe9 | ||
|
|
463346b867 | ||
|
|
f293700db3 | ||
|
|
b4e343369a | ||
|
|
da1d94775c | ||
|
|
28582b7e77 | ||
|
|
0f4a97f3a6 | ||
|
|
0f75234ed2 | ||
|
|
bc2556139a | ||
|
|
c1f52a5e5a | ||
|
|
ab24b3262c | ||
|
|
42994efa9d | ||
|
|
28aebaa06b | ||
|
|
44cf82caab | ||
|
|
a44ca39eb8 | ||
|
|
3f70c395e1 | ||
|
|
04383c0302 | ||
|
|
55d022eefc | ||
|
|
7d3917adb7 | ||
|
|
7eeeab8486 | ||
|
|
88a46ef59a | ||
|
|
e4a9dc25ec | ||
|
|
dfb563a330 | ||
|
|
329256712b | ||
|
|
16dbb88ee3 | ||
|
|
626f435edf | ||
|
|
d4dd5d7a61 | ||
|
|
de13b8b9ba | ||
|
|
0aabb0b364 | ||
|
|
3605072650 | ||
|
|
6272aabefb | ||
|
|
bf2446614c | ||
|
|
65b8220fe5 | ||
|
|
e0b544fc7e | ||
|
|
d296918fcd | ||
|
|
c9a2d439e5 | ||
|
|
73f36bcf33 | ||
|
|
a1bda1169e | ||
|
|
8f5089fd46 | ||
|
|
ae8b17e0fb | ||
|
|
3453690fc2 | ||
|
|
bc1f607c8e | ||
|
|
e0382139b6 | ||
|
|
65d280da8a | ||
|
|
e618070068 | ||
|
|
8181074238 | ||
|
|
b0e4aedd3d | ||
|
|
faa101224a | ||
|
|
eb7fc0fb26 | ||
|
|
a63a61e7fc | ||
|
|
223cc07139 | ||
|
|
62b0d371ee | ||
|
|
884b678bd0 | ||
|
|
2930e9cadb | ||
|
|
6103265488 | ||
|
|
c1f5dfc02e | ||
|
|
8e911a42f5 | ||
|
|
f41c1153d2 | ||
|
|
ff03171f55 | ||
|
|
5fe58dc9ae | ||
|
|
0c1cff52b2 | ||
|
|
8e29a52d71 | ||
|
|
12a0e73587 | ||
|
|
a3229ea965 | ||
|
|
43f40c4085 | ||
|
|
250e79f53c | ||
|
|
c8b2c19010 | ||
|
|
fe1add57f1 | ||
|
|
332f830cc2 | ||
|
|
ccd69dfcf7 | ||
|
|
7e13d09c3c | ||
|
|
71c0c62ee8 | ||
|
|
c599e60e75 | ||
|
|
f2241ba3de | ||
|
|
85fb240b69 | ||
|
|
71725f1b26 | ||
|
|
64d4c3f971 | ||
|
|
4c24b042d0 | ||
|
|
a43736b5c6 | ||
|
|
874c2a6212 | ||
|
|
94492b01cd | ||
|
|
ab6f8397ce | ||
|
|
b105088c28 | ||
|
|
1070805a0f | ||
|
|
799ae886c5 | ||
|
|
1276b23817 | ||
|
|
6ecb5b5c64 | ||
|
|
cbadf5e57c | ||
|
|
3a2deb0039 | ||
|
|
0480c2195c | ||
|
|
fde6a65933 | ||
|
|
6f6249690b | ||
|
|
c23aca78ba | ||
|
|
a195b52d34 | ||
|
|
09a13ef75f | ||
|
|
70e7534933 | ||
|
|
c95edbe25a | ||
|
|
4f9b4059a6 | ||
|
|
9be19bf811 | ||
|
|
0a728f805b | ||
|
|
c7276ee614 | ||
|
|
b419e17cac | ||
|
|
b9405bfb64 | ||
|
|
5d8856a1c7 | ||
|
|
076fd7e83c | ||
|
|
5073c0e9ad | ||
|
|
d95df7245c | ||
|
|
41360ceb71 | ||
|
|
042594ffca | ||
|
|
a8a9ee91bf | ||
|
|
726be664c8 | ||
|
|
c02b71e0e1 | ||
|
|
9cbef4ba4b | ||
|
|
24035329b8 | ||
|
|
457977f954 | ||
|
|
373dc5cadb | ||
|
|
a35cfe660e | ||
|
|
db666eec65 | ||
|
|
5b51a36c62 | ||
|
|
586473aaa7 | ||
|
|
2226ece4b7 | ||
|
|
950e41e8f7 | ||
|
|
49df8f4b43 | ||
|
|
2e9ad941c0 | ||
|
|
dec21f34e9 | ||
|
|
c8605b0cdf | ||
|
|
3d6d191d59 | ||
|
|
8f61278b33 | ||
|
|
5723c0c96f | ||
|
|
2830bdc075 | ||
|
|
37ab621a7e | ||
|
|
f9f286e896 | ||
|
|
e47545aa91 | ||
|
|
799417e0e8 | ||
|
|
cea5f0a30c | ||
|
|
ce61e80261 | ||
|
|
ec23124242 | ||
|
|
678cc56836 | ||
|
|
adf94b5e21 | ||
|
|
d4e40c376a | ||
|
|
3cbf678671 | ||
|
|
c7ec07ed47 | ||
|
|
754d7d099b | ||
|
|
c4cc3f176e | ||
|
|
79a2921e1d | ||
|
|
d64a61bab9 | ||
|
|
0ee78865e1 | ||
|
|
2c29b150c5 | ||
|
|
0801a2fbc4 | ||
|
|
af7ef25c9d | ||
|
|
f852474b56 | ||
|
|
54cfe5984b | ||
|
|
1bc07b1b4a | ||
|
|
b8d52a5aa8 | ||
|
|
af58b1039e | ||
|
|
a124f1dc38 | ||
|
|
fa3e6267fd | ||
|
|
011f86f368 | ||
|
|
0f6edc477e | ||
|
|
bade652c02 | ||
|
|
03ab067d3a | ||
|
|
e3a29ae82f | ||
|
|
3a9ce0f6ce | ||
|
|
d6d40b35a5 | ||
|
|
8baecb5911 | ||
|
|
3bb8fe9076 | ||
|
|
b93d66ce0b | ||
|
|
b71fde7ff3 | ||
|
|
5c7b060f19 | ||
|
|
1f544fff52 | ||
|
|
019520a793 | ||
|
|
29c22efed0 | ||
|
|
650519683c | ||
|
|
bcf5a586c7 | ||
|
|
5d8f5beb2a | ||
|
|
7e58627eaf | ||
|
|
89be0f80b9 | ||
|
|
e8b6b78dfa | ||
|
|
d5ea44a760 | ||
|
|
0638d43cae | ||
|
|
c5d133aaff | ||
|
|
067c2a6fe0 | ||
|
|
9e73a72b8b | ||
|
|
ae23b7611d | ||
|
|
e34a284036 | ||
|
|
116aae0828 | ||
|
|
f33c31aa83 | ||
|
|
c7a742d1de | ||
|
|
d0df3a2915 | ||
|
|
1c494803b0 | ||
|
|
0bd0a70564 | ||
|
|
5cd6470358 | ||
|
|
a7d0576736 | ||
|
|
76e9e2076e | ||
|
|
dcec5b5cb0 | ||
|
|
b4352ada27 | ||
|
|
76047e5351 | ||
|
|
60fedad3fe | ||
|
|
d57eb6a2fc | ||
|
|
c33d39f5d0 | ||
|
|
81aa17f3f0 | ||
|
|
8475201db8 | ||
|
|
40907ef1d8 | ||
|
|
b79fc53265 | ||
|
|
2972351e79 | ||
|
|
c82de08886 | ||
|
|
7806945965 | ||
|
|
9a6a0b0047 | ||
|
|
e0c94e3cbb | ||
|
|
9f328bdee3 | ||
|
|
7a96adf957 | ||
|
|
2111e19d59 | ||
|
|
d93cf08a27 | ||
|
|
a24b64f7ca | ||
|
|
625577f145 | ||
|
|
e13fa0d2d1 | ||
|
|
d470281a5e | ||
|
|
6021438e2e | ||
|
|
737b425aca | ||
|
|
d2a35453ef | ||
|
|
77160a76e8 | ||
|
|
f012a67182 | ||
|
|
2c5e4fad79 | ||
|
|
1486f5f620 | ||
|
|
eb1209cb00 | ||
|
|
bcdaf77a9c | ||
|
|
e8e97838ef | ||
|
|
bec3f309bd | ||
|
|
39bfbbbe0a | ||
|
|
57a98e7a5d | ||
|
|
ea697f2238 | ||
|
|
fd20a9218f | ||
|
|
b47794cbc1 | ||
|
|
c3ce44562e | ||
|
|
4f7803c384 | ||
|
|
6e313d1760 | ||
|
|
0f7a8a25ad | ||
|
|
c692b7847b | ||
|
|
207893fee8 | ||
|
|
9ec3574ff6 | ||
|
|
b0522836e6 |
No files matched your search
@@ -10,7 +10,7 @@ ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ENV \
|
||||
DEBUG=false \
|
||||
NODE_VERSION=v12.20.1 \
|
||||
NODE_VERSION=v12.22.0 \
|
||||
METEOR_RELEASE=1.10.2 \
|
||||
USE_EDGE=false \
|
||||
METEOR_EDGE=1.5-beta.17 \
|
||||
@@ -19,6 +19,7 @@ ENV \
|
||||
ARCHITECTURE=linux-x64 \
|
||||
SRC_PATH=./ \
|
||||
WITH_API=true \
|
||||
RESULTS_PER_PAGE="" \
|
||||
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 \
|
||||
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 \
|
||||
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 \
|
||||
|
||||
@@ -81,7 +81,7 @@ parts:
|
||||
wekan:
|
||||
source: .
|
||||
plugin: nodejs
|
||||
node-engine: 12.20.1
|
||||
node-engine: 12.22.0
|
||||
node-packages:
|
||||
- node-gyp
|
||||
- node-pre-gyp
|
||||
|
||||
@@ -5,7 +5,7 @@ echo " with 'sudo dpkg-reconfigure locales' , so that MongoDB works correct
|
||||
echo " You can still use any other locale as your main locale."
|
||||
|
||||
#Below script installs newest node 8.x for Debian/Ubuntu/Mint.
|
||||
#NODE_VERSION=12.18.2
|
||||
#NODE_VERSION=12.21.0
|
||||
#X64NODE="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz"
|
||||
|
||||
function pause(){
|
||||
@@ -80,7 +80,7 @@ do
|
||||
curl -0 -L https://npmjs.org/install.sh | sudo sh
|
||||
sudo chown -R $(id -u):$(id -g) $HOME/.npm
|
||||
sudo npm -g install n
|
||||
sudo n 12.18.2
|
||||
sudo n 12.21.0
|
||||
#curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
|
||||
#sudo apt-get install -y nodejs
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
|
||||
@@ -83,7 +83,7 @@ parts:
|
||||
wekan:
|
||||
source: .
|
||||
plugin: nodejs
|
||||
node-engine: 12.20.1
|
||||
node-engine: 12.22.0
|
||||
node-packages:
|
||||
- node-gyp
|
||||
- node-pre-gyp
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
## Issue
|
||||
|
||||
Email settings:
|
||||
- https://github.com/wekan/wekan/wiki/Troubleshooting-Mail
|
||||
|
||||
Add these issues to elsewhere:
|
||||
- Snap: https://github.com/wekan/wekan-snap/issues
|
||||
- LDAP: https://github.com/wekan/wekan-ldap/issues
|
||||
- SECURITY ISSUES: https://github.com/wekan/wekan/blob/master/SECURITY.md
|
||||
- UCS: https://github.com/wekan/univention/issues
|
||||
|
||||
Other Wekan issues can be added here.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
zap_scan:
|
||||
runs-on: ubuntu-latest
|
||||
name: Scan the webapplication
|
||||
steps:
|
||||
- name: OWASP ZAP Scan
|
||||
runs-on: ubuntu-latest
|
||||
uses: zaproxy/action-baseline@v0.4.0
|
||||
with:
|
||||
target: 'https://boards.wekan.team/sign-in'
|
||||
@@ -31,5 +31,4 @@ Thumbs.db
|
||||
ehthumbs.db
|
||||
.eslintcache
|
||||
.meteor/local
|
||||
.meteor-1.6-snap/.meteor/local
|
||||
.devcontainer/docker-compose.extend.yml
|
||||
+1
-1
@@ -91,7 +91,6 @@ meteorhacks:aggregate@1.3.0
|
||||
wekan-markdown
|
||||
konecty:mongo-counter
|
||||
percolate:synced-cron
|
||||
easylogic:summernote
|
||||
cfs:filesystem
|
||||
tmeasday:check-npm-versions
|
||||
steffo:meteor-accounts-saml
|
||||
@@ -145,3 +144,4 @@ rajit:bootstrap3-datepicker-zh-cn
|
||||
rajit:bootstrap3-datepicker-zh-tw
|
||||
staringatlights:fast-render
|
||||
spacebars
|
||||
easylogic:summernote
|
||||
+1
-1
@@ -1 +1 @@
|
||||
METEOR@2.0
|
||||
METEOR@2.1
|
||||
+1
-1
@@ -3,7 +3,7 @@ sudo: required
|
||||
|
||||
env:
|
||||
TRAVIS_DOCKER_COMPOSE_VERSION: 1.24.0
|
||||
TRAVIS_NODE_VERSION: 12.20.1
|
||||
TRAVIS_NODE_VERSION: 12.22.0
|
||||
TRAVIS_NPM_VERSION: latest
|
||||
|
||||
before_install:
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ host = https://www.transifex.com
|
||||
# tap:i18n requires us to use `-` separator in the language identifiers whereas
|
||||
# Transifex uses a `_` separator, without an option to customize it on one side
|
||||
# or the other, so we need to do a Manual mapping.
|
||||
lang_map = ar_EG:ar-EG, bg_BG:bg, en_GB:en-GB, es_AR:es-AR, es_CL:es-CL, es_PE:es-PE, es_MX:es-MX, es_TX:es-TX, es_PY:es-PY, el_GR:el, fi_FI:fi, hu_HU:hu, id_ID:id, mn_MN:mn, no:nb, lv_LV:lv, pt_BR:pt-BR, ro_RO:ro, sl_SI:sl, zh_CN:zh-CN, zh_TW:zh-TW, zh_HK:zh-HK
|
||||
lang_map = ar_EG:ar-EG, bg_BG:bg, en_GB:en-GB, es_AR:es-AR, es_CL:es-CL, es_419:es-LA, es_PE:es-PE, es_MX:es-MX, es_TX:es-TX, es_PY:es-PY, el_GR:el, fa_IR:fa-IR, fi_FI:fi, hu_HU:hu, id_ID:id, mn_MN:mn, no:nb, lv_LV:lv, pt_BR:pt-BR, ro_RO:ro, sl_SI:sl, zh_CN:zh-CN, zh_TW:zh-TW, zh_HK:zh-HK
|
||||
|
||||
[wekan.application]
|
||||
file_filter = i18n/<lang>.i18n.json
|
||||
|
||||
+478
@@ -1,3 +1,481 @@
|
||||
# v5.17 2021-04-01 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Fix Link dialog closes card when clicking in dialog](https://github.com/wekan/wekan/commit/454d3b5bbeed6cef8ecface7e6094cabfcc4847c).
|
||||
Thanks to ryanMushy.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Added stable tag release script](https://github.com/wekan/wekan/commit/8dfb6916c5180f5d074748840d51dd04f9adb2bb).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.16 2021-04-01 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Added stable tag](https://github.com/wekan/wekan/commit/c40668be3fb9c35d44698f49ab06fec5bcabbe1b).
|
||||
Thanks to rynr and xet7.
|
||||
- [Added back Summernote editor. Removed emoji picker](https://github.com/wekan/wekan/commit/47ecc654b825a875074dfd4826c36e2c5c55f599).
|
||||
Thanks to ryanMushy and xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.15 2021-03-31 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Fixed card sort reset](https://github.com/wekan/wekan/pull/3686).
|
||||
Thanks to ednamaeG.
|
||||
- [Fix bug in My Cards and Global Search](https://github.com/wekan/wekan/pull/3687).
|
||||
Thanks to jrsupplee.
|
||||
- [Fix bug in Due Cards introduced by last bug fix](https://github.com/wekan/wekan/pull/3688).
|
||||
Thanks to jrsupplee.
|
||||
- [Fixed Bug: Move Swimlane to Archive does not work anymore. Fixed lint in
|
||||
router.js](https://github.com/wekan/wekan/commit/0b263cf582a9649ef72efbd289927105a27583af).
|
||||
Thanks to marcungeschikts and xet7.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- Updated sandstorm release script and added new node update script
|
||||
[Part 1](https://github.com/wekan/wekan/commit/34b6aa0858678da937eacf9a87878bbcb476fd4b),
|
||||
[Part 2](https://github.com/wekan/wekan/commit/01de3f187c90af3ac94215ba7e8c7e780c98768d),
|
||||
[Part 3](https://github.com/wekan/wekan/commit/1d3673e9d320926127b46383321023f149287d6d),
|
||||
[Part 4](https://github.com/wekan/wekan/commit/09b9f690b162ae2797d1996e82c96ed8b8c74221),
|
||||
[Part 5](https://github.com/wekan/wekan/commit/6819303047eab17b03a0c28108fd9a2cfde23d20).
|
||||
Thanks to xet7.
|
||||
- Updated to Node.js v12.22.0
|
||||
[Part 1](https://github.com/wekan/wekan/commit/7a9c3972642601e9d89d5e7a3816643f91448c63),
|
||||
[Part 2](https://github.com/wekan/wekan/commit/c2b7525864048694c39f9cbe8f8c4cd96e36f7aa).
|
||||
Thanks to Node.js developers.
|
||||
- Fixed release website script
|
||||
[Part 1](https://github.com/wekan/wekan/commit/b6f60c08e55c2620fe6724ae2b5da0d9dfc9ec31),
|
||||
[Part 2](https://github.com/wekan/wekan/commit/91dae9795ebd1a98b8ed12c68b78ad90a6983402).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.14 2021-03-29 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Clean-up Global Search, Due Cards, and My Cards. New environment variable `RESULTS_PER_PAGE` for search
|
||||
results](https://github.com/wekan/wekan/pull/3676).
|
||||
Thanks to jrsupplee.
|
||||
- [Added environment variable `RESULTS_PER_PAGE` to all Wekan platforms](https://github.com/wekan/wekan/commit/ba05f383ca29211c5474e06c5ba6673e712afe7a).
|
||||
Thanks to xet7.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Updated release scripts](https://github.com/wekan/wekan/commit/59580e4b0f711ca55e8cb0d73803a4ff8b56352d).
|
||||
Thanks to xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Require signed-in user for My Cards, Due Cards, and global search](https://github.com/wekan/wekan/pull/3677).
|
||||
Thanks to jrsupplee.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.13 2021-03-28 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Fixed Sandstorm Wekan attachments upload](https://github.com/wekan/wekan/commit/d4a1611b86521cd5913277cfa2c86c43958eec7b).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.12 2021-03-28 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Fix HTTP not defined](https://github.com/wekan/wekan/commit/4c609161915cc46ebfccad3d9e7ffdecdef1f85c).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.11 2021-03-28 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Added emoji picker to card description edit and card comment edit.
|
||||
Removed and disabled Summernote wysiwyg editor, package-lock.json
|
||||
etc](https://github.com/wekan/wekan/commit/84fde1ecfc81e89ed1895cab3bcb328e4f166a87).
|
||||
Thanks to xet7.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Updated dependencies. Fixed lint](https://github.com/wekan/wekan/commit/4e1c0fdce82e3b4add8c4ffd1832752181573e88).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.10 2021-03-28 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Move swimlane from one board to another](https://github.com/wekan/wekan/pull/3674).
|
||||
Thanks to jrsupplee.
|
||||
- [Added translatable Move Swimlane popup title](https://github.com/wekan/wekan/commit/16665bccf912c5e907739c35f7ef5a376c81740e).
|
||||
Thanks to xet7.
|
||||
- [REST API: Export one attachment](https://github.com/wekan/wekan/pull/3673).
|
||||
Thanks to vagnernascimento.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Updated package-lock.json](https://github.com/wekan/wekan/commit/3145ec65a3defb8ac8d97aed7e43595f661f7100).
|
||||
Thanks to developers of dependencies.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.09 2021-03-26 Wekan release
|
||||
|
||||
This release adds the following improvements:
|
||||
|
||||
- [Replace edit icon by plus-square on new links](https://github.com/wekan/wekan/pull/3671).
|
||||
Thanks to sim51.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix openapi docs generation](https://github.com/wekan/wekan/pull/3672).
|
||||
Thanks to bentiss.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.08 2021-03-26 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Admin Panel/Settings/Accounts: Hide system messages of all users](https://github.com/wekan/wekan/commit/a249ffc8054189d8e3db9b4c8f082cc7ce7dcb52).
|
||||
Thanks to bbyszio, r4nc0r and xet7.
|
||||
|
||||
and adds the following improvements:
|
||||
|
||||
- [Add Trello attached links to the card description](https://github.com/wekan/wekan/pull/3669).
|
||||
Thanks to jrsupplee.
|
||||
- [Added package-lock.json and updated .gitignore](https://github.com/wekan/wekan/commit/d532a3591f338cec9a3839d43d9a1e9d69f59dc2).
|
||||
Thanks to xet7.
|
||||
|
||||
and adds the following new translations:
|
||||
|
||||
- [Added translation: español de América Latina](https://github.com/wekan/wekan/commit/ccc9efb2703efda4e199a861920b9ec88e634b59).
|
||||
Thanks to translators.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix typos in translations](https://github.com/wekan/wekan/commit/a0e1b6f918dbb252a13db05d6b9e1f832c28654f).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.07 2021-03-19 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Fixed sort cards feature](https://github.com/wekan/wekan/pull/3662).
|
||||
Thanks to ednamaeG.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.06 2021-03-18 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Fixed Bug: Calendar & parent cards URLs used absolute URLs](https://github.com/wekan/wekan/pull/3648).
|
||||
Thanks to Majed6.
|
||||
- [Fixed Bug: copy to clipboard uses pathname](https://github.com/wekan/wekan/pull/3661).
|
||||
Thanks to Majed6.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.05 2021-03-11 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Change URL scheme recognition for allowing abasurl to link](https://github.com/wekan/wekan/pull/3641).
|
||||
Thanks to tod31 and chrisi51.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.04 2021-03-07 Wekan release
|
||||
|
||||
This release adds the following speed improvements:
|
||||
|
||||
- [Speed improvement: Delete presences older than one week, and add database index to presences
|
||||
serverId](https://github.com/wekan/wekan/commit/9db3c931161adfbeb6fc52d3e4cf621fb9a4955f).
|
||||
Thanks to xet7.
|
||||
|
||||
and adds the following new features:
|
||||
|
||||
- [Added autolinking settings in Admin Panel](https://github.com/wekan/wekan/pull/3633).
|
||||
Thanks to chrisi51.
|
||||
- [Add custom field editing to the REST API](https://github.com/wekan/wekan/pull/3593).
|
||||
Thanks to dudeofawesome.
|
||||
- [Related to custom field editing, Fixed generating API docs and Wekan Custom Fields
|
||||
REST API](https://github.com/wekan/wekan/commit/0bb3b670753c6ba20b0ad63f63d273036f609ee5).
|
||||
Thanks to xet7.
|
||||
|
||||
and adds back the following platforms:
|
||||
|
||||
- [OpenPower Minicloud emergency maintenance has finished, so can now build Wekan for
|
||||
ppc64le](https://github.com/wekan/wekan/commit/ac9b23f00f10b0170b8693e1e997bfb54f807adc).
|
||||
Thanks to OpenPower Minicloud.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Try to fix Snap: Removed fibers multi arch from Snap, because Snap build servers do not build correctly with
|
||||
it](https://github.com/wekan/wekan/commit/a44ca39eb84508441f0f8bdac852745f417f12e7).
|
||||
Thanks to xet7.
|
||||
- [Fix search on labels server error](https://github.com/wekan/wekan/pull/3634).
|
||||
Thanks to jrsupplee.
|
||||
- [Fixed Bug: inconsistent use of relative/absolute URLs](https://github.com/wekan/wekan/pull/3635).
|
||||
Thanks to Majed6.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.03 2021-03-03 Wekan release
|
||||
|
||||
This release adds the following changes:
|
||||
|
||||
- [Hide email settings from Sandstorm Wekan Admin Panel](https://github.com/wekan/wekan/commit/626f435edf75fac68448ba2e14c62acb749f9c9b).
|
||||
Thanks to ocdtrekkie and xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Revert Removed extra imports of Meteor. Hopefully fixes email notifications and rules
|
||||
on old cars not working](https://github.com/wekan/wekan/commit/e4a9dc25ecc230829afea07dbb3915b96115f7f7).
|
||||
Thanks to xet7.
|
||||
- [Fixed Bug: Link at board title can not be edited](https://github.com/wekan/wekan/commit/7d3917adb79be09356d32612585029392bac1e49).
|
||||
Thanks to jonesrussell42, aiac, bbyszio and xet7.
|
||||
|
||||
Thanks to above GitHub and Wekan vanila.io community users for their contributions and translators for their translations.
|
||||
|
||||
# v5.02 2021-03-02 Wekan release
|
||||
|
||||
This release adds the following improvements:
|
||||
|
||||
- [Added sort to edit card REST API](https://github.com/wekan/wekan/pull/3618).
|
||||
Thanks to ChrisMagnuson.
|
||||
- [Add attachmentId to the Webhook data](https://github.com/wekan/wekan/pull/3620).
|
||||
Thanks to n8ores.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix SMTP port lost after upgrade. STMP settings are made only with environment variables on non-Sandstorm platforms.
|
||||
Note: Sending email on Sandstorm Wekan does not work yet](https://github.com/wekan/wekan/commit/65b8220fe53349695a335bdb8b9692f82d4b3329).
|
||||
Thanks to jrsupplee and xet7.
|
||||
- [Removed extra imports of Meteor](https://github.com/wekan/wekan/commit/de13b8b9bafbfb186a037ae20e845846b296ac69).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.01 2021-02-26 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Fix typo in activities code. Fixes can not edit Custom Field](https://github.com/wekan/wekan/pull/3610).
|
||||
Thanks to n8ores.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v5.00 2021-02-25 Wekan release
|
||||
|
||||
This release fixes the following bugs:
|
||||
|
||||
- [Fixed Unable to remove old Board, reappears](https://github.com/wekan/wekan/commit/332f830cc2e44ab66ca891690b09a425b9fd7e68).
|
||||
Thanks to chirrut2, uusijani, cimm, anicolaides, Philipoo0 and xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.99 2021-02-25 Wekan release
|
||||
|
||||
This release fixes the following CRITICAL SECURITY ISSUES:
|
||||
|
||||
- [Fixed SMTP password visible to Admin at Admin Panel by using browser inspect
|
||||
to see behind asterisks](https://github.com/wekan/wekan/commit/71725f1b262b385162b2544f10658a0bc22f6b41).
|
||||
Thanks to Georg Krause and xet7.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Update wekan/releases/up.sh script: Can not build ppc64le version because OpenPower Minicloud
|
||||
is having emergency maintenance](https://github.com/wekan/wekan/commit/a43736b5c6196c65770d8ae17af927406dce2c43).
|
||||
Thanks to xet7.
|
||||
- [Updated to Meteor 2.1](https://github.com/wekan/wekan/commit/f2241ba3de82e393161ee1c456e1a947c6bdb5fc).
|
||||
Thanks to Meteor developers.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.98 2021-02-24 Wekan release
|
||||
|
||||
This release adds the following CRITICAL SECURITY FIXES:
|
||||
|
||||
- [Updated Node.js to v12.21.0](https://github.com/wekan/wekan/commit/fde6a6593379277d601408ec83f6f5a4347afef0).
|
||||
Thanks to Node.js developers.
|
||||
|
||||
and adds the following new features:
|
||||
|
||||
- [Added sort feature for viewing of cards](https://github.com/wekan/wekan/pull/3586).
|
||||
Thanks to ednamaeG.
|
||||
- [Made sort cards feature translatable](https://github.com/wekan/wekan/commit/09a13ef75f478b0fc02ae3cdbfe918367664aa0c).
|
||||
Thanks to xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix development script to escape character](https://github.com/wekan/wekan/commit/2e9ad941c0b63b384ee215548a3f31b4a635b28b).
|
||||
Thanks to xet7.
|
||||
- [Fix bugs with customFields in Webhooks](https://github.com/wekan/wekan/pull/3584).
|
||||
Thanks to n8ores.
|
||||
|
||||
and adds the following improvements:
|
||||
|
||||
- [Global Search Updates](https://github.com/wekan/wekan/pull/3597).
|
||||
Thanks to jrsupplee.
|
||||
- [Updated GitHub issue template links](https://github.com/wekan/wekan/commit/c23aca78babd51857271134aed9247615b87b895).
|
||||
Thanks to atlantsecurity and xet7.
|
||||
- [Admin Panel/People/People/New User: Added Initials](https://github.com/wekan/wekan/commit/3a2deb00399eb213472ef169826bd15ad655e490).
|
||||
Thanks to xet7.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Update release-bundle.sh script: Can not build ppc64le version because OpenPower Minicloud
|
||||
is having emergency maintenance](https://github.com/wekan/wekan/commit/799ae886c5fedad3bafa18a14f8fbbca7ad2c227).
|
||||
Thanks to xet7.
|
||||
- [Update release.sh script: Also build Sandstorm version of Wekan with same
|
||||
script](https://github.com/wekan/wekan/commit/b105088c2858bc04120551a8a8e5a75f187041e5).
|
||||
Thanks to xet7.
|
||||
|
||||
and adds the following new translations:
|
||||
|
||||
- [Added translation: Persian (Iran)](https://github.com/wekan/wekan/commit/0a728f805b336588741ca93f2ecbd1ca31ee53f2).
|
||||
Thanks to translators.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.97 2021-02-24 Wekan release
|
||||
|
||||
Release skipped, because not all required files had new version number updated yet.
|
||||
|
||||
# v4.96 2021-02-13 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Add /api/boards_count endpoint for statistics](https://github.com/wekan/wekan/pull/3556).
|
||||
Thanks to pichouk.
|
||||
- [Added possibility to specify hours in single digits in 24 hour format](https://github.com/wekan/wekan/pull/3557).
|
||||
Thanks to lindhork.
|
||||
- [Added replacement from comma to dot](https://github.com/wekan/wekan/pull/3564).
|
||||
Thanks to lindhork.
|
||||
|
||||
and adds the following improvements:
|
||||
|
||||
- [Checklistitems are now inserted always at the end of the checklist](https://github.com/wekan/wekan/pull/3551).
|
||||
Thanks to mfilser.
|
||||
- [Teams/Organizations: Added more code to Admin Panel for saving and editing. In Progress, does not work yet](https://github.com/wekan/wekan/commit/1bc07b1b4a3e8cd1a177f3f1776ed8e189bc627a).
|
||||
Thanks to xet7.
|
||||
- [Mobile View, list header is now always at top and only lists/cards view have a scroll area](https://github.com/wekan/wekan/pull/3563).
|
||||
Thanks to mfilser.
|
||||
- [Added ChangeLog update script](https://github.com/wekan/wekan/commit/c7ec07ed4748fe9b00f622af7472fd291cf1a3ce).
|
||||
Thanks to xet7.
|
||||
- [Helm: Made SecretEnv a secret and added default mongodb name as Wekan](https://github.com/wekan/wekan/pull/3570).
|
||||
Thanks to meerkampdvv.
|
||||
- [Checklist drag handle now at the left side (same place as for the checklist items)](https://github.com/wekan/wekan/pull/3571).
|
||||
Thanks to mfilser.
|
||||
- [Lists, show also 0 cards at column description](https://github.com/wekan/wekan/pull/3572).
|
||||
Thanks to mfilser.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Updated Node.js to v12.20.2](https://github.com/wekan/wekan/commit/011f86f368a83c2e70f597c11ec60ec857e0fab0).
|
||||
Thanks to Node.js developers.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Minicard, remove red line below member avatar icon](https://github.com/wekan/wekan/pull/3560).
|
||||
Thanks to mfilser.
|
||||
- [Added padding](https://github.com/wekan/wekan/pull/3559).
|
||||
Thanks to lindhork.
|
||||
- [Changed default behaviour for BIGEVENTS that no activity matches it](https://github.com/wekan/wekan/pull/3561).
|
||||
Thanks to bronger.
|
||||
- [Modern theme: Remove font color when the card has a color](https://github.com/wekan/wekan/pull/3569).
|
||||
Thanks to helioguardabaxo.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.95 2021-02-08 Wekan release
|
||||
|
||||
This release adds back the following features:
|
||||
|
||||
- [Added back Custom Fields sorting, because it now does not prevent loading boards](https://github.com/wekan/wekan/pull/3547).
|
||||
Thanks to mfilser.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Updated dependencies](https://github.com/wekan/wekan/commit/1c494803b091d987e26ccb783432434e7fee15a5).
|
||||
Thanks to xet7.
|
||||
- [Fix typo](https://github.com/wekan/wekan/commit/0bd0a70564d3dda67706deb1bbfbd1d5a96f811f).
|
||||
Thanks to xet7.
|
||||
- Updated release scripts
|
||||
[Part 1](https://github.com/wekan/wekan/commit/d0df3a2915d08b255d7ab92f9bcac195a1e7f442),
|
||||
[Part 2](https://github.com/wekan/wekan/commit/e34a2840366351c0e069515ac2210db3911dbc0f).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.94 2021-02-08 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Settings, "Show cards count" now works at mobile view too](https://github.com/wekan/wekan/pull/3545).
|
||||
Thanks to mfilser.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Updated dependencies](https://github.com/wekan/wekan/commit/b4352ada27545fadc425ca7024532aede3cc1a6f).
|
||||
Thanks to developers of dependencies.
|
||||
- [Update release scripts](https://github.com/wekan/wekan/commit/dcec5b5cb05ac9e0dfae8f360def169f5f9b6fa2).
|
||||
Thanks to xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix bug in adding new users](https://github.com/wekan/wekan/pull/3544).
|
||||
Thanks to jrsupplee.
|
||||
- [Fixed Board does not load, by disabling Custom Fields sorting](https://github.com/wekan/wekan/commit/d57eb6a2fc73c7b25c957ad42b5f7a06f680e1a1).
|
||||
Thanks to marcungeschikts, olivierlambert and xet7.
|
||||
- [Fixed lint](https://github.com/wekan/wekan/commit/60fedad3fe384a2b0652941e57ecaa5fc4b7897a).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# 4.93 2021-02-06 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Add the ability to call get_user operation with username](https://github.com/wekan/wekan/pull/3530).
|
||||
Thanks to magicbelette.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Updated Ubuntu base image in Dockerfile](https://github.com/wekan/wekan/commit/bcdaf77a9c675530cfa21d038e8abd7c62aef70d).
|
||||
Thanks to Ubuntu and xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Set the language on `TAPi18n` when user selects language](https://github.com/wekan/wekan/pull/3525).
|
||||
Thanks to jrsupplee.
|
||||
- [Fix bug in `uniqueTitle`](https://github.com/wekan/wekan/pull/3526).
|
||||
Thanks to jrsupplee.
|
||||
- [Fixed file permissions in build scripts](https://github.com/wekan/wekan/commit/ea697f2238842893953dee76bed03ffd5b4a107e).
|
||||
Thanks to xet7.
|
||||
- [Red line below the avatar now correctly on FireFox](https://github.com/wekan/wekan/pull/3532).
|
||||
Thanks to mfilser.
|
||||
- [Notifications, enable line wrapping](https://github.com/wekan/wekan/pull/3533).
|
||||
Thanks to mfilser.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v4.92 2021-02-03 Wekan release
|
||||
|
||||
This release adds the following improvements:
|
||||
|
||||
+8
-5
@@ -1,4 +1,4 @@
|
||||
FROM quay.io/wekan/ubuntu:groovy-20201125.2
|
||||
FROM quay.io/wekan/ubuntu:groovy-20210115
|
||||
LABEL maintainer="wekan"
|
||||
|
||||
# 2020-12-03:
|
||||
@@ -12,7 +12,7 @@ ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-essential git ca-certificates python3" \
|
||||
DEBUG=false \
|
||||
NODE_VERSION=v12.20.1 \
|
||||
NODE_VERSION=v12.22.0 \
|
||||
METEOR_RELEASE=1.10.2 \
|
||||
USE_EDGE=false \
|
||||
METEOR_EDGE=1.5-beta.17 \
|
||||
@@ -21,6 +21,7 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
|
||||
ARCHITECTURE=linux-x64 \
|
||||
SRC_PATH=./ \
|
||||
WITH_API=true \
|
||||
RESULTS_PER_PAGE="" \
|
||||
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 \
|
||||
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 \
|
||||
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 \
|
||||
@@ -274,11 +275,12 @@ RUN \
|
||||
mkdir -p /home/wekan/.npm && \
|
||||
chown wekan --recursive /home/wekan/.npm /home/wekan/.config /home/wekan/.meteor && \
|
||||
#gosu wekan:wekan /home/wekan/.meteor/meteor add standard-minifier-js && \
|
||||
chmod u+w *.json && \
|
||||
gosu wekan:wekan npm install && \
|
||||
gosu wekan:wekan /home/wekan/.meteor/meteor build --directory /home/wekan/app_build && \
|
||||
cp /home/wekan/app/fix-download-unicode/cfs_access-point.txt /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
|
||||
#cp /home/wekan/app/fix-download-unicode/cfs_access-point.txt /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
|
||||
#rm /home/wekan/app_build/bundle/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs && \
|
||||
chown wekan /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
|
||||
#chown wekan /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
|
||||
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
|
||||
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac
|
||||
#https://github.com/wekan/wekan/commit/7eeabf14be3c63fae2226e561ef8a0c1390c8d3c
|
||||
@@ -291,10 +293,11 @@ RUN \
|
||||
#find . -name "*phantomjs*" | xargs rm -rf && \
|
||||
#
|
||||
cd /home/wekan/app_build/bundle/programs/server/ && \
|
||||
chmod u+w *.json && \
|
||||
gosu wekan:wekan npm install && \
|
||||
#gosu wekan:wekan npm install bcrypt && \
|
||||
# Remove legacy webbroser bundle, so that Wekan works also at Android Firefox, iOS Safari, etc.
|
||||
rm -rf /home/wekan/app_build/bundle/programs/web.browser.legacy && \
|
||||
rm -rf /home/wekan/app_build/bundle/programs/web.browser.legacy && \
|
||||
mv /home/wekan/app_build/bundle /build && \
|
||||
\
|
||||
# Put back the original tar
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ FROM amd64/alpine:3.7 AS builder
|
||||
ENV QEMU_VERSION=v4.2.0-6 \
|
||||
QEMU_ARCHITECTURE=aarch64 \
|
||||
NODE_ARCHITECTURE=linux-arm64 \
|
||||
NODE_VERSION=v12.20.1 \
|
||||
NODE_VERSION=v12.22.0 \
|
||||
WEKAN_VERSION=3.96 \
|
||||
WEKAN_ARCHITECTURE=arm64
|
||||
|
||||
@@ -40,7 +40,7 @@ LABEL maintainer="wekan"
|
||||
# Set the environment variables (defaults where required)
|
||||
ENV QEMU_ARCHITECTURE=aarch64 \
|
||||
NODE_ARCHITECTURE=linux-arm64 \
|
||||
NODE_VERSION=v12.20.1 \
|
||||
NODE_VERSION=v12.22.0 \
|
||||
NODE_ENV=production \
|
||||
NPM_VERSION=latest \
|
||||
WITH_API=true \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[](https://gitpod.io/#https://github.com/wekan/wekan)
|
||||
[](https://gitpod.io/#https://github.com/wekan/wekan)
|
||||
|
||||
# Wekan - Open Source kanban
|
||||
|
||||
@@ -32,7 +32,7 @@ It's better than at chat where details get lost when chat scrolls up.
|
||||
|
||||
## FAQ
|
||||
|
||||
**NOTE**:
|
||||
**NOTE**:
|
||||
- Please read the [FAQ](https://github.com/wekan/wekan/wiki/FAQ) first
|
||||
- Please don't feed the [trolls](https://github.com/wekan/wekan/wiki/FAQ#why-am-i-called-a-troll) and [spammers](https://github.com/wekan/wekan/wiki/FAQ#why-am-i-called-a-spammer) that are mentioned in the FAQ :)
|
||||
|
||||
@@ -52,7 +52,7 @@ that by providing one-click installation on various platforms.
|
||||
|
||||
- Wekan is used in [most countries of the world](https://snapcraft.io/wekan).
|
||||
- Wekan largest user has 13k users using Wekan in their company.
|
||||
- Wekan has been [translated](https://transifex.com/wekan/wekan) to about 60 languages.
|
||||
- Wekan has been [translated](https://transifex.com/wekan/wekan) to about 62 languages.
|
||||
- [Features][features]: Wekan has real-time user interface.
|
||||
- [Platforms][platforms]: Wekan supports many platforms.
|
||||
Wekan is critical part of new platforms Wekan is currently being integrated to.
|
||||
@@ -64,7 +64,7 @@ that by providing one-click installation on various platforms.
|
||||
[More Platforms](https://github.com/wekan/wekan/wiki/Platforms), bundle for RasPi3 ARM and other CPUs where Node.js and MongoDB exists.
|
||||
- 1 GB RAM minimum free for Wekan. Production server should have minimum total 4 GB RAM.
|
||||
For thousands of users, for example with [Docker](https://github.com/wekan/wekan/blob/master/docker-compose.yml): 3 frontend servers,
|
||||
each having 2 CPU and 2 wekan-app containers. One backend wekan-db server with many CPUs.
|
||||
each having 2 CPU and 2 wekan-app containers. One backend wekan-db server with many CPUs.
|
||||
- Enough disk space and alerts about low disk space. If you run out disk space, MongoDB database gets corrupted.
|
||||
- SECURITY: Updating to newest Wekan version very often. Please check you do not have automatic updates of Sandstorm or Snap turned off.
|
||||
Old versions have security issues because of old versions Node.js etc. Only newest Wekan is supported.
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v4.92.0"
|
||||
appVersion: "v5.17.0"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
||||
@@ -82,7 +82,7 @@ template(name="activity")
|
||||
+viewer
|
||||
= activity.checklist.title
|
||||
else
|
||||
a.activity-checklist(href="{{ activity.card.absoluteUrl }}")
|
||||
a.activity-checklist(href="{{ activity.card.originRelativeUrl }}")
|
||||
+viewer
|
||||
= activity.checklist.title
|
||||
|
||||
@@ -103,7 +103,7 @@ template(name="activity")
|
||||
|
||||
if($eq activity.activityType 'addChecklistItem')
|
||||
| {{{_ 'activity-checklist-item-added' (sanitize activity.checklist.title) cardLink}}}.
|
||||
.activity-checklist(href="{{ activity.card.absoluteUrl }}")
|
||||
.activity-checklist(href="{{ activity.card.originRelativeUrl }}")
|
||||
+viewer
|
||||
= activity.checklistItem.title
|
||||
|
||||
@@ -139,7 +139,7 @@ template(name="activity")
|
||||
//- if we are not in card mode we only display a summary of the comment
|
||||
if($eq activity.activityType 'addComment')
|
||||
| {{{_ 'activity-on' cardLink}}}
|
||||
a.activity-comment(href="{{ activity.card.absoluteUrl }}")
|
||||
a.activity-comment(href="{{ activity.card.originRelativeUrl }}")
|
||||
+viewer
|
||||
= activity.comment.text
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ function createCardLink(card) {
|
||||
Blaze.toHTML(
|
||||
HTML.A(
|
||||
{
|
||||
href: card.absoluteUrl(),
|
||||
href: card.originRelativeUrl(),
|
||||
class: 'action-card',
|
||||
},
|
||||
sanitizeXss(card.title),
|
||||
@@ -260,7 +260,7 @@ function createBoardLink(board, list) {
|
||||
Blaze.toHTML(
|
||||
HTML.A(
|
||||
{
|
||||
href: board.absoluteUrl(),
|
||||
href: board.originRelativeUrl(),
|
||||
class: 'action-board',
|
||||
},
|
||||
sanitizeXss(text),
|
||||
|
||||
@@ -360,7 +360,7 @@ BlazeComponent.extendComponent({
|
||||
end: end || card.endAt,
|
||||
allDay:
|
||||
Math.abs(end.getTime() - start.getTime()) / 1000 === 24 * 3600,
|
||||
url: FlowRouter.url('card', {
|
||||
url: FlowRouter.path('card', {
|
||||
boardId: currentBoard._id,
|
||||
slug: currentBoard.slug,
|
||||
cardId: card._id,
|
||||
|
||||
@@ -654,7 +654,6 @@ setBoardClear(color1,color2)
|
||||
|
||||
/* Card changes */
|
||||
.minicard
|
||||
background: #FFF
|
||||
padding: 15px 15px 10px
|
||||
box-shadow: 0 3px 8px rgba(0,0,0,.05)
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
template(name="boardHeaderBar")
|
||||
h1.header-board-menu
|
||||
with currentBoard
|
||||
a(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}")
|
||||
+viewer
|
||||
= title
|
||||
+viewer
|
||||
= title
|
||||
|
||||
.board-header-btns.left
|
||||
unless isMiniScreen
|
||||
if currentBoard
|
||||
if currentUser
|
||||
with currentBoard
|
||||
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
|
||||
i.fa.fa-pencil-square-o
|
||||
|
||||
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
|
||||
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
|
||||
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
|
||||
@@ -31,6 +34,12 @@ template(name="boardHeaderBar")
|
||||
if $eq watchLevel "muted"
|
||||
i.fa.fa-bell-slash
|
||||
span {{_ watchLevel}}
|
||||
a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}")
|
||||
i.fa.fa-sort
|
||||
span {{#if isSortActive }}{{_ 'Sort is on'}}{{else}}{{_ 'sort-cards'}}{{/if}}
|
||||
if isSortActive
|
||||
a.board-header-btn-close.js-sort-reset(title="Remove Sort")
|
||||
i.fa.fa-times-thin
|
||||
|
||||
else
|
||||
a.board-header-btn.js-log-in(
|
||||
@@ -42,6 +51,10 @@ template(name="boardHeaderBar")
|
||||
if currentBoard
|
||||
if isMiniScreen
|
||||
if currentUser
|
||||
with currentBoard
|
||||
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
|
||||
i.fa.fa-pencil-square-o
|
||||
|
||||
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
|
||||
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
|
||||
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
|
||||
@@ -247,3 +260,19 @@ template(name="boardChangeTitlePopup")
|
||||
template(name="boardCreateRulePopup")
|
||||
p {{_ 'close-board-pop'}}
|
||||
button.js-confirm.negate.full(type="submit") {{_ 'archive'}}
|
||||
|
||||
|
||||
template(name="cardsSortPopup")
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.js-sort-due {{_ 'due-date'}}
|
||||
hr
|
||||
li
|
||||
a.js-sort-title {{_ 'title-alphabetically'}}
|
||||
hr
|
||||
li
|
||||
a.js-sort-created-desc {{_ 'created-at-newest-first'}}
|
||||
hr
|
||||
li
|
||||
a.js-sort-created-asc {{_ 'created-at-oldest-first'}}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
const DOWNCLS = 'fa-sort-down';
|
||||
const UPCLS = 'fa-sort-up';
|
||||
*/
|
||||
const sortCardsBy = new ReactiveVar('');
|
||||
Template.boardMenuPopup.events({
|
||||
'click .js-rename-board': Popup.open('boardChangeTitle'),
|
||||
'click .js-custom-fields'() {
|
||||
@@ -110,6 +111,7 @@ BlazeComponent.extendComponent({
|
||||
'click .js-open-filter-view'() {
|
||||
Sidebar.setView('filter');
|
||||
},
|
||||
'click .js-sort-cards': Popup.open('cardsSort'),
|
||||
/*
|
||||
'click .js-open-sort-view'(evt) {
|
||||
const target = evt.target;
|
||||
@@ -127,6 +129,9 @@ BlazeComponent.extendComponent({
|
||||
Sidebar.setView();
|
||||
Filter.reset();
|
||||
},
|
||||
'click .js-sort-reset'() {
|
||||
Session.set('sortBy', '');
|
||||
},
|
||||
'click .js-open-search-view'() {
|
||||
Sidebar.setView('search');
|
||||
},
|
||||
@@ -160,6 +165,9 @@ Template.boardHeaderBar.helpers({
|
||||
boardView() {
|
||||
return Utils.boardView();
|
||||
},
|
||||
isSortActive() {
|
||||
return Session.get('sortBy') ? true : false;
|
||||
},
|
||||
});
|
||||
|
||||
Template.boardChangeViewPopup.events({
|
||||
@@ -368,3 +376,44 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
}).register('listsortPopup');
|
||||
*/
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-sort-due'() {
|
||||
const sortBy = {
|
||||
dueAt: 1,
|
||||
};
|
||||
Session.set('sortBy', sortBy);
|
||||
sortCardsBy.set(TAPi18n.__('due-date'));
|
||||
Popup.close();
|
||||
},
|
||||
'click .js-sort-title'() {
|
||||
const sortBy = {
|
||||
title: 1,
|
||||
};
|
||||
Session.set('sortBy', sortBy);
|
||||
sortCardsBy.set(TAPi18n.__('title'));
|
||||
Popup.close();
|
||||
},
|
||||
'click .js-sort-created-asc'() {
|
||||
const sortBy = {
|
||||
createdAt: 1,
|
||||
};
|
||||
Session.set('sortBy', sortBy);
|
||||
sortCardsBy.set(TAPi18n.__('date-created-newest-first'));
|
||||
Popup.close();
|
||||
},
|
||||
'click .js-sort-created-desc'() {
|
||||
const sortBy = {
|
||||
createdAt: -1,
|
||||
};
|
||||
Session.set('sortBy', sortBy);
|
||||
sortCardsBy.set(TAPi18n.__('date-created-oldest-first'));
|
||||
Popup.close();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('cardsSortPopup');
|
||||
@@ -121,7 +121,8 @@ CardCustomField.register('cardCustomField');
|
||||
{
|
||||
'submit .js-card-customfield-currency'(event) {
|
||||
event.preventDefault();
|
||||
const value = Number(this.find('input').value, 10);
|
||||
// To allow input separated by comma, the comma is replaced by a period.
|
||||
const value = Number(this.find('input').value.replace(/,/i, '.'), 10);
|
||||
this.card.setCustomField(this.customFieldId, value);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
// Helper function to replace HH with H for 24 hours format, because H allows also single-digit hours
|
||||
function adjustedTimeFormat() {
|
||||
return moment
|
||||
.localeData()
|
||||
.longDateFormat('LT')
|
||||
.replace(/HH/i, 'H');
|
||||
}
|
||||
|
||||
// Edit received, start, due & end dates
|
||||
BlazeComponent.extendComponent({
|
||||
template() {
|
||||
@@ -59,7 +67,11 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
'keyup .js-time-field'() {
|
||||
// parse for localized time format in strict mode
|
||||
const dateMoment = moment(this.find('#time').value, 'LT', true);
|
||||
const dateMoment = moment(
|
||||
this.find('#time').value,
|
||||
adjustedTimeFormat(),
|
||||
true,
|
||||
);
|
||||
if (dateMoment.isValid()) {
|
||||
this.error.set('');
|
||||
}
|
||||
@@ -71,16 +83,30 @@ BlazeComponent.extendComponent({
|
||||
const time =
|
||||
evt.target.time.value ||
|
||||
moment(new Date().setHours(12, 0, 0)).format('LT');
|
||||
|
||||
const newTime = moment(time, adjustedTimeFormat(), true);
|
||||
const newDate = moment(evt.target.date.value, 'L', true);
|
||||
const dateString = `${evt.target.date.value} ${time}`;
|
||||
const newDate = moment(dateString, 'L LT', true);
|
||||
if (newDate.isValid()) {
|
||||
this._storeDate(newDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
const newCompleteDate = moment(
|
||||
dateString,
|
||||
'L ' + adjustedTimeFormat(),
|
||||
true,
|
||||
);
|
||||
if (!newTime.isValid()) {
|
||||
this.error.set('invalid-time');
|
||||
evt.target.time.focus();
|
||||
}
|
||||
if (!newDate.isValid()) {
|
||||
this.error.set('invalid-date');
|
||||
evt.target.date.focus();
|
||||
}
|
||||
if (newCompleteDate.isValid()) {
|
||||
this._storeDate(newCompleteDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
if (!this.error) {
|
||||
this.error.set('invalid');
|
||||
}
|
||||
}
|
||||
},
|
||||
'click .js-delete-date'(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
@@ -3,5 +3,5 @@ template(name="descriptionForm")
|
||||
.new-description.js-new-description(
|
||||
class="{{#if descriptionFormIsOpen}}is-open{{/if}}")
|
||||
form.js-new-description-form
|
||||
+editor(class="js-new-description-input" data-meteor-emoji-large="true" autofocus="autofocus")
|
||||
+editor(class="js-new-description-input" autofocus="autofocus")
|
||||
| {{getUnsavedValue 'cardDescription' _id getDescription}}
|
||||
@@ -8,11 +8,10 @@ template(name="cardDetails")
|
||||
a.fa.fa-times-thin.close-card-details.js-close-card-details
|
||||
if currentUser.isBoardMember
|
||||
a.fa.fa-navicon.card-details-menu.js-open-card-details-menu
|
||||
input.inline-input(type="text" id="cardURL_copy" value="{{ absoluteUrl }}")
|
||||
input.inline-input(type="text" id="cardURL_copy" value="{{ originRelativeUrl }}")
|
||||
a.fa.fa-link.card-copy-button.js-copy-link(
|
||||
class="fa-link"
|
||||
title="{{_ 'copy-card-link-to-clipboard'}}"
|
||||
value="{{ absoluteUrl }}"
|
||||
)
|
||||
if isMiniScreen
|
||||
a.fa.fa-times-thin.close-card-details-mobile-web.js-close-card-details
|
||||
@@ -533,7 +532,7 @@ template(name="cardMorePopup")
|
||||
span {{_ 'link-card'}}
|
||||
= ' '
|
||||
i.fa.colorful(class="{{#if board.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
|
||||
input.inline-input(type="text" id="cardURL" readonly value="{{ absoluteUrl }}" autofocus="autofocus")
|
||||
input.inline-input(type="text" id="cardURL" readonly value="{{ originRelativeUrl }}" autofocus="autofocus")
|
||||
button.js-copy-card-link-to-clipboard(class="btn" id="clipboard") {{_ 'copy-card-link-to-clipboard'}}
|
||||
span.clearfix
|
||||
br
|
||||
|
||||
@@ -114,7 +114,7 @@ BlazeComponent.extendComponent({
|
||||
if (card) {
|
||||
const board = Boards.findOne(card.boardId);
|
||||
if (board) {
|
||||
result = FlowRouter.url('card', {
|
||||
result = FlowRouter.path('card', {
|
||||
boardId: card.boardId,
|
||||
slug: board.slug,
|
||||
cardId: card._id,
|
||||
@@ -291,6 +291,8 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
'click .js-copy-link'() {
|
||||
StringToCopyElement = document.getElementById('cardURL_copy');
|
||||
StringToCopyElement.value =
|
||||
window.location.origin + window.location.pathname;
|
||||
StringToCopyElement.select();
|
||||
if (document.execCommand('copy')) {
|
||||
StringToCopyElement.blur();
|
||||
|
||||
@@ -111,7 +111,7 @@ BlazeComponent.extendComponent({
|
||||
title,
|
||||
checklistId: checklist._id,
|
||||
cardId: checklist.cardId,
|
||||
sort: checklist.itemCount(),
|
||||
sort: Utils.calculateIndexData(checklist.lastItem()).base,
|
||||
});
|
||||
}
|
||||
// We keep the form opened, empty it.
|
||||
|
||||
@@ -44,8 +44,8 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
|
||||
|
||||
span.fa.checklist-handle
|
||||
padding-right: 20px
|
||||
padding-top: 6px
|
||||
float: right
|
||||
padding-top: 3px
|
||||
float: left
|
||||
|
||||
|
||||
.js-confirm-checklist-delete
|
||||
|
||||
@@ -90,7 +90,6 @@ template(name="minicard")
|
||||
.minicard-assignees.js-minicard-assignees
|
||||
each getAssignees
|
||||
+userAvatar(userId=this)
|
||||
hr(class="assigneehr" title="{{_ 'assignee'}}")
|
||||
|
||||
if getMembers
|
||||
.minicard-members.js-minicard-members
|
||||
|
||||
@@ -166,17 +166,14 @@
|
||||
.minicard-assignees
|
||||
float: right
|
||||
margin-left: 5px
|
||||
|
||||
.assigneehr
|
||||
border-top: 1px solid red
|
||||
margin-bottom: 4px
|
||||
margin-bottom: 4px
|
||||
|
||||
.member
|
||||
float: right
|
||||
border-radius: 50%
|
||||
height: 28px
|
||||
width: @height
|
||||
margin: 0px 0px 4px 0px
|
||||
margin-bottom: 4px
|
||||
|
||||
.assignee
|
||||
float: right
|
||||
@@ -187,6 +184,9 @@
|
||||
+ .badges
|
||||
margin-top: 5px
|
||||
|
||||
.minicard-assignees
|
||||
border-bottom: 1px solid red
|
||||
|
||||
.minicard-members:empty,
|
||||
.minicard-assignees:empty
|
||||
display: none
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
template(name="resultCard")
|
||||
.result-card-wrapper
|
||||
a.minicard-wrapper.card-title(href=absoluteUrl)
|
||||
a.minicard-wrapper.card-title(href=originRelativeUrl)
|
||||
+minicard(this)
|
||||
//= card.title
|
||||
ul.result-card-context-list
|
||||
li.result-card-context(title="{{_ 'board'}}")
|
||||
.result-card-block-wrapper
|
||||
+viewer
|
||||
= getBoard.title
|
||||
if boardId
|
||||
+viewer
|
||||
= getBoard.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
if getBoard.archived
|
||||
i.fa.fa-archive
|
||||
li.result-card-context.result-card-context-separator
|
||||
@@ -16,8 +20,12 @@ template(name="resultCard")
|
||||
= ' '
|
||||
li.result-card-context(title="{{_ 'swimlane'}}")
|
||||
.result-card-block-wrapper
|
||||
+viewer
|
||||
= getSwimlane.title
|
||||
if swimlaneId
|
||||
+viewer
|
||||
= getSwimlane.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
if getSwimlane.archived
|
||||
i.fa.fa-archive
|
||||
li.result-card-context.result-card-context-separator
|
||||
@@ -26,7 +34,11 @@ template(name="resultCard")
|
||||
= ' '
|
||||
li.result-card-context(title="{{_ 'list'}}")
|
||||
.result-card-block-wrapper
|
||||
+viewer
|
||||
= getList.title
|
||||
if listId
|
||||
+viewer
|
||||
= getList.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
if getList.archived
|
||||
i.fa.fa-archive
|
||||
@@ -180,7 +180,8 @@
|
||||
border-bottom: 1px solid darken(white, 20%)
|
||||
|
||||
.list
|
||||
display: block
|
||||
display: contents
|
||||
flex-basis: auto
|
||||
width: 100%
|
||||
border-left: 0px
|
||||
&:first-child
|
||||
|
||||
@@ -5,7 +5,7 @@ template(name="listBody")
|
||||
+inlinedForm(autoclose=false position="top")
|
||||
+addCardForm(listId=_id position="top")
|
||||
each (cardsWithLimit (idOrNull ../../_id))
|
||||
a.minicard-wrapper.js-minicard(href=absoluteUrl
|
||||
a.minicard-wrapper.js-minicard(href=originRelativeUrl
|
||||
class="{{#if cardIsSelected}}is-selected{{/if}}"
|
||||
class="{{#if MultiSelection.isSelected _id}}is-checked{{/if}}")
|
||||
if MultiSelection.isActive
|
||||
|
||||
@@ -168,13 +168,16 @@ BlazeComponent.extendComponent({
|
||||
|
||||
cardsWithLimit(swimlaneId) {
|
||||
const limit = this.cardlimit.get();
|
||||
const defaultSort = { sort: 1 };
|
||||
const sortBy = Session.get('sortBy') ? Session.get('sortBy') : defaultSort;
|
||||
const selector = {
|
||||
listId: this.currentData()._id,
|
||||
archived: false,
|
||||
};
|
||||
if (swimlaneId) selector.swimlaneId = swimlaneId;
|
||||
return Cards.find(Filter.mongoSelector(selector), {
|
||||
sort: ['sort'],
|
||||
// sort: ['sort'],
|
||||
sort: sortBy,
|
||||
limit,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -82,7 +82,7 @@ BlazeComponent.extendComponent({
|
||||
|
||||
showCardsCountForList(count) {
|
||||
const limit = this.limitToShowCardsCount();
|
||||
return limit > 0 && count > limit;
|
||||
return limit >= 0 && count >= limit;
|
||||
},
|
||||
|
||||
events() {
|
||||
|
||||
@@ -3,39 +3,15 @@ template(name="brokenCardsHeaderBar")
|
||||
| {{_ 'broken-cards'}}
|
||||
|
||||
template(name="brokenCards")
|
||||
.wrapper
|
||||
.broken-cards-wrapper
|
||||
each card in brokenCardsList
|
||||
.broken-cards-card-wrapper
|
||||
.broken-cards-card-title
|
||||
= card.title
|
||||
ul.broken-cards-context-list
|
||||
li.broken-cards-context(title="{{_ 'board'}}")
|
||||
if card.boardId
|
||||
+viewer
|
||||
= card.getBoard.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
li.broken-cards-context.broken-cards-context-separator
|
||||
= ' '
|
||||
| {{_ 'context-separator'}}
|
||||
= ' '
|
||||
li.broken-cards-context(title="{{_ 'swimlane'}}")
|
||||
if card.swimlaneId
|
||||
+viewer
|
||||
= card.getSwimlane.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
li.broken-cards-context
|
||||
= ' '
|
||||
| {{_ 'context-separator'}}
|
||||
= ' '
|
||||
li.broken-cards-context(title="{{_ 'list'}}")
|
||||
if card.listId
|
||||
+viewer
|
||||
= card.getList.title
|
||||
else
|
||||
.broken-cards-null
|
||||
| NULL
|
||||
if currentUser
|
||||
if searching.get
|
||||
+spinner
|
||||
else if hasResults.get
|
||||
.global-search-results-list-wrapper
|
||||
if hasQueryErrors.get
|
||||
div
|
||||
each msg in errorMessages
|
||||
span.global-search-error-messages
|
||||
= msg
|
||||
else
|
||||
+resultsPaged(this)
|
||||
@@ -1,3 +1,5 @@
|
||||
import { CardSearchPagedComponent } from '../../lib/cardSearch';
|
||||
|
||||
BlazeComponent.extendComponent({}).register('brokenCardsHeaderBar');
|
||||
|
||||
Template.brokenCards.helpers({
|
||||
@@ -6,23 +8,11 @@ Template.brokenCards.helpers({
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
class BrokenCardsComponent extends CardSearchPagedComponent {
|
||||
onCreated() {
|
||||
Meteor.subscribe('setting');
|
||||
Meteor.subscribe('brokenCards');
|
||||
},
|
||||
super.onCreated();
|
||||
|
||||
brokenCardsList() {
|
||||
const selector = {
|
||||
$or: [
|
||||
{ boardId: { $in: [null, ''] } },
|
||||
{ swimlaneId: { $in: [null, ''] } },
|
||||
{ listId: { $in: [null, ''] } },
|
||||
{ permission: 'public' },
|
||||
{ members: { $elemMatch: { userId: user._id, isActive: true } } },
|
||||
],
|
||||
};
|
||||
|
||||
return Cards.find(selector);
|
||||
},
|
||||
}).register('brokenCards');
|
||||
Meteor.subscribe('brokenCards', this.sessionId);
|
||||
}
|
||||
}
|
||||
BrokenCardsComponent.register('brokenCards');
|
||||
@@ -22,13 +22,17 @@ template(name="dueCardsModalTitle")
|
||||
|
||||
template(name="dueCards")
|
||||
if currentUser
|
||||
if isPageReady.get
|
||||
.wrapper
|
||||
.due-cards-dueat-list-wrapper
|
||||
each card in dueCardsList
|
||||
+resultCard(card)
|
||||
else
|
||||
if searching.get
|
||||
+spinner
|
||||
else if hasResults.get
|
||||
.global-search-results-list-wrapper
|
||||
if hasQueryErrors.get
|
||||
div
|
||||
each msg in errorMessages
|
||||
span.global-search-error-messages
|
||||
= msg
|
||||
else
|
||||
+resultsPaged(this)
|
||||
|
||||
template(name="dueCardsViewChangePopup")
|
||||
if currentUser
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
const subManager = new SubsManager();
|
||||
import { CardSearchPagedComponent } from '../../lib/cardSearch';
|
||||
import {
|
||||
OPERATOR_HAS,
|
||||
OPERATOR_SORT,
|
||||
OPERATOR_USER,
|
||||
ORDER_DESCENDING,
|
||||
PREDICATE_DUE_AT,
|
||||
} from '../../../config/search-const';
|
||||
import { QueryParams } from '../../../config/query-classes';
|
||||
|
||||
// const subManager = new SubsManager();
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
dueCardsView() {
|
||||
@@ -40,106 +50,51 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
}).register('dueCardsViewChangePopup');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
class DueCardsComponent extends CardSearchPagedComponent {
|
||||
onCreated() {
|
||||
this.isPageReady = new ReactiveVar(false);
|
||||
super.onCreated();
|
||||
|
||||
this.autorun(() => {
|
||||
const handle = subManager.subscribe(
|
||||
'dueCards',
|
||||
Utils.dueCardsView() === 'all',
|
||||
);
|
||||
Tracker.nonreactive(() => {
|
||||
Tracker.autorun(() => {
|
||||
this.isPageReady.set(handle.ready());
|
||||
});
|
||||
});
|
||||
const queryParams = new QueryParams();
|
||||
queryParams.addPredicate(OPERATOR_HAS, {
|
||||
field: PREDICATE_DUE_AT,
|
||||
exists: true,
|
||||
});
|
||||
Meteor.subscribe('setting');
|
||||
},
|
||||
// queryParams[OPERATOR_LIMIT] = 5;
|
||||
queryParams.addPredicate(OPERATOR_SORT, {
|
||||
name: PREDICATE_DUE_AT,
|
||||
order: ORDER_DESCENDING,
|
||||
});
|
||||
|
||||
if (Utils.dueCardsView() !== 'all') {
|
||||
queryParams.addPredicate(OPERATOR_USER, Meteor.user().username);
|
||||
}
|
||||
|
||||
this.runGlobalSearch(queryParams.getQueryParams());
|
||||
}
|
||||
|
||||
dueCardsView() {
|
||||
// eslint-disable-next-line no-console
|
||||
//console.log('sort:', Utils.dueCardsView());
|
||||
return Utils.dueCardsView();
|
||||
},
|
||||
}
|
||||
|
||||
sortByBoard() {
|
||||
return this.dueCardsView() === 'board';
|
||||
},
|
||||
}
|
||||
|
||||
dueCardsList() {
|
||||
const allUsers = Utils.dueCardsView() === 'all';
|
||||
|
||||
const user = Meteor.user();
|
||||
|
||||
const archivedBoards = [];
|
||||
Boards.find({ archived: true }).forEach(board => {
|
||||
archivedBoards.push(board._id);
|
||||
});
|
||||
|
||||
const permiitedBoards = [];
|
||||
let selector = {
|
||||
archived: false,
|
||||
};
|
||||
// for every user including admin allow her to see cards only from public boards
|
||||
// or those where she is a member
|
||||
//if (!user.isAdmin) {
|
||||
selector.$or = [
|
||||
{ permission: 'public' },
|
||||
{ members: { $elemMatch: { userId: user._id, isActive: true } } },
|
||||
];
|
||||
//}
|
||||
Boards.find(selector).forEach(board => {
|
||||
permiitedBoards.push(board._id);
|
||||
});
|
||||
|
||||
const archivedSwimlanes = [];
|
||||
Swimlanes.find({ archived: true }).forEach(swimlane => {
|
||||
archivedSwimlanes.push(swimlane._id);
|
||||
});
|
||||
|
||||
const archivedLists = [];
|
||||
Lists.find({ archived: true }).forEach(list => {
|
||||
archivedLists.push(list._id);
|
||||
});
|
||||
|
||||
selector = {
|
||||
archived: false,
|
||||
boardId: {
|
||||
$nin: archivedBoards,
|
||||
$in: permiitedBoards,
|
||||
},
|
||||
swimlaneId: { $nin: archivedSwimlanes },
|
||||
listId: { $nin: archivedLists },
|
||||
dueAt: { $ne: null },
|
||||
endAt: null,
|
||||
};
|
||||
|
||||
if (!allUsers) {
|
||||
selector.$or = [{ members: user._id }, { assignees: user._id }];
|
||||
const results = this.getResults();
|
||||
console.log('results:', results);
|
||||
const cards = [];
|
||||
if (results) {
|
||||
results.forEach(card => {
|
||||
cards.push(card);
|
||||
});
|
||||
}
|
||||
|
||||
const cards = [];
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('cards selector:', selector);
|
||||
Cards.find(selector).forEach(card => {
|
||||
cards.push(card);
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log(
|
||||
// 'board:',
|
||||
// card.board(),
|
||||
// 'swimlane:',
|
||||
// card.swimlane(),
|
||||
// 'list:',
|
||||
// card.list(),
|
||||
// );
|
||||
});
|
||||
|
||||
cards.sort((a, b) => {
|
||||
const x = a.dueAt === null ? Date('2100-12-31') : a.dueAt;
|
||||
const y = b.dueAt === null ? Date('2100-12-31') : b.dueAt;
|
||||
const x = a.dueAt === null ? new Date('2100-12-31') : a.dueAt;
|
||||
const y = b.dueAt === null ? new Date('2100-12-31') : b.dueAt;
|
||||
|
||||
if (x > y) return 1;
|
||||
else if (x < y) return -1;
|
||||
@@ -148,7 +103,9 @@ BlazeComponent.extendComponent({
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('cards:', cards);
|
||||
console.log('cards:', cards);
|
||||
return cards;
|
||||
},
|
||||
}).register('dueCards');
|
||||
}
|
||||
}
|
||||
|
||||
DueCardsComponent.register('dueCards');
|
||||
@@ -10,11 +10,29 @@ template(name="globalSearchModalTitle")
|
||||
i.fa.fa-keyboard-o
|
||||
| {{_ 'globalSearch-title'}}
|
||||
|
||||
template(name="resultsPaged")
|
||||
h1
|
||||
= resultsHeading.get
|
||||
a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
|
||||
each card in results.get
|
||||
+resultCard(card)
|
||||
table.global-search-footer
|
||||
tr
|
||||
td.global-search-previous-page
|
||||
if hasPreviousPage.get
|
||||
button.js-previous-page
|
||||
| {{_ 'previous-page' }}
|
||||
td.global-search-next-page(align="right")
|
||||
if hasNextPage.get
|
||||
button.js-next-page
|
||||
| {{_ 'next-page' }}
|
||||
|
||||
template(name="globalSearch")
|
||||
if currentUser
|
||||
.wrapper
|
||||
form.global-search-instructions.js-search-query-form
|
||||
form.global-search-page.js-search-query-form
|
||||
input.global-search-query-input(
|
||||
style="{# if hasResults.get #}display: inline-block;{#/if#}"
|
||||
id="global-search-input"
|
||||
type="text"
|
||||
name="searchQuery"
|
||||
@@ -22,73 +40,47 @@ template(name="globalSearch")
|
||||
value="{{ query.get }}"
|
||||
autofocus dir="auto"
|
||||
)
|
||||
a.js-new-search.fa.fa-eraser
|
||||
if searching.get
|
||||
+spinner
|
||||
else if hasResults.get
|
||||
.global-search-results-list-wrapper
|
||||
if hasQueryErrors.get
|
||||
div
|
||||
ul
|
||||
each msg in errorMessages
|
||||
span.global-search-error-messages
|
||||
li.global-search-error-messages
|
||||
= msg
|
||||
else
|
||||
h1
|
||||
= resultsHeading.get
|
||||
a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
|
||||
each card in results.get
|
||||
+resultCard(card)
|
||||
table.global-search-footer
|
||||
tr
|
||||
td.global-search-previous-page
|
||||
if hasPreviousPage.get
|
||||
button.js-previous-page
|
||||
| {{_ 'previous-page' }}
|
||||
td.global-search-next-page(align="right")
|
||||
if hasNextPage.get
|
||||
button.js-next-page
|
||||
| {{_ 'next-page' }}
|
||||
+resultsPaged(this)
|
||||
else if serverError.get
|
||||
.global-search-page
|
||||
.global-search-help
|
||||
h1 {{_ 'server-error' }}
|
||||
+viewer
|
||||
| {{_ 'server-error-troubleshooting' }}
|
||||
else
|
||||
.global-search-instructions
|
||||
h2 {{_ 'boards' }}
|
||||
.lists-wrapper
|
||||
each title in myBoardNames.get
|
||||
span.card-label.list-title.js-board-title
|
||||
= title
|
||||
h2 {{_ 'lists' }}
|
||||
.lists-wrapper
|
||||
each title in myLists.get
|
||||
span.card-label.list-title.js-list-title
|
||||
= title
|
||||
h2 {{_ 'label-colors' }}
|
||||
.palette-colors: each label in labelColors
|
||||
span.card-label.palette-color.js-label-color(class="card-label-{{label.color}}")
|
||||
= label.name
|
||||
if myLabelNames.get.length
|
||||
h2 {{_ 'label-names' }}
|
||||
.global-search-page
|
||||
.global-search-help
|
||||
h2 {{_ 'boards' }}
|
||||
.lists-wrapper
|
||||
each name in myLabelNames.get
|
||||
span.card-label.list-title.js-label-name
|
||||
= name
|
||||
+viewer
|
||||
= searchInstructions
|
||||
|
||||
template(name="globalSearchViewChangePopup")
|
||||
if currentUser
|
||||
ul.pop-over-list
|
||||
li
|
||||
with "globalSearchViewChange-choice-me"
|
||||
a.js-global-search-view-me
|
||||
i.fa.fa-user.colorful
|
||||
| {{_ 'globalSearchViewChange-choice-me'}}
|
||||
if $eq Utils.globalSearchView "me"
|
||||
i.fa.fa-check
|
||||
li
|
||||
with "globalSearchViewChange-choice-all"
|
||||
a.js-global-search-view-all
|
||||
i.fa.fa-users.colorful
|
||||
| {{_ 'globalSearchViewChange-choice-all'}}
|
||||
span.sub-name
|
||||
+viewer
|
||||
| {{_ 'globalSearchViewChange-choice-all-description' }}
|
||||
if $eq Utils.globalSearchView "all"
|
||||
i.fa.fa-check
|
||||
each title in myBoardNames.get
|
||||
span.card-label.list-title.js-board-title
|
||||
= title
|
||||
h2 {{_ 'lists' }}
|
||||
.lists-wrapper
|
||||
each title in myLists.get
|
||||
span.card-label.list-title.js-list-title
|
||||
= title
|
||||
h2 {{_ 'label-colors' }}
|
||||
.palette-colors: each label in labelColors
|
||||
span.card-label.palette-color.js-label-color(class="card-label-{{label.color}}")
|
||||
= label.name
|
||||
if myLabelNames.get.length
|
||||
h2 {{_ 'label-names' }}
|
||||
.lists-wrapper
|
||||
each name in myLabelNames.get
|
||||
span.card-label.list-title.js-label-name
|
||||
= name
|
||||
.global-search-instructions
|
||||
+viewer
|
||||
= searchInstructions
|
||||
@@ -1,4 +1,8 @@
|
||||
const subManager = new SubsManager();
|
||||
import { CardSearchPagedComponent } from '../../lib/cardSearch';
|
||||
import Boards from '../../../models/boards';
|
||||
import { Query, QueryErrors } from '../../../config/query-classes';
|
||||
|
||||
// const subManager = new SubsManager();
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
events() {
|
||||
@@ -16,45 +20,14 @@ Template.globalSearch.helpers({
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-due-cards-view-me'() {
|
||||
Utils.setDueCardsView('me');
|
||||
Popup.close();
|
||||
},
|
||||
|
||||
'click .js-due-cards-view-all'() {
|
||||
Utils.setDueCardsView('all');
|
||||
Popup.close();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('globalSearchViewChangePopup');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
class GlobalSearchComponent extends CardSearchPagedComponent {
|
||||
onCreated() {
|
||||
this.searching = new ReactiveVar(false);
|
||||
this.hasResults = new ReactiveVar(false);
|
||||
this.hasQueryErrors = new ReactiveVar(false);
|
||||
this.query = new ReactiveVar('');
|
||||
this.resultsHeading = new ReactiveVar('');
|
||||
this.searchLink = new ReactiveVar(null);
|
||||
super.onCreated();
|
||||
this.myLists = new ReactiveVar([]);
|
||||
this.myLabelNames = new ReactiveVar([]);
|
||||
this.myBoardNames = new ReactiveVar([]);
|
||||
this.results = new ReactiveVar([]);
|
||||
this.hasNextPage = new ReactiveVar(false);
|
||||
this.hasPreviousPage = new ReactiveVar(false);
|
||||
this.parsingErrors = new QueryErrors();
|
||||
this.queryParams = null;
|
||||
this.parsingErrors = [];
|
||||
this.resultsCount = 0;
|
||||
this.totalHits = 0;
|
||||
this.queryErrors = null;
|
||||
this.colorMap = null;
|
||||
this.resultsPerPage = 25;
|
||||
|
||||
Meteor.call('myLists', (err, data) => {
|
||||
if (!err) {
|
||||
@@ -73,428 +46,71 @@ BlazeComponent.extendComponent({
|
||||
this.myBoardNames.set(data);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
onRendered() {
|
||||
Meteor.subscribe('setting');
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
//console.log('lang:', TAPi18n.getLanguage());
|
||||
this.colorMap = Boards.colorMap();
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('colorMap:', this.colorMap);
|
||||
|
||||
if (Session.get('globalQuery')) {
|
||||
this.searchAllBoards(Session.get('globalQuery'));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
resetSearch() {
|
||||
this.searching.set(false);
|
||||
this.results.set([]);
|
||||
this.hasResults.set(false);
|
||||
this.hasQueryErrors.set(false);
|
||||
this.resultsHeading.set('');
|
||||
this.parsingErrors = [];
|
||||
this.resultsCount = 0;
|
||||
this.totalHits = 0;
|
||||
this.queryErrors = null;
|
||||
},
|
||||
|
||||
getSessionData() {
|
||||
return SessionData.findOne({
|
||||
userId: Meteor.userId(),
|
||||
sessionId: SessionData.getSessionId(),
|
||||
});
|
||||
},
|
||||
|
||||
getResults() {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('getting results');
|
||||
if (this.queryParams) {
|
||||
const sessionData = this.getSessionData();
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('selector:', sessionData.getSelector());
|
||||
// console.log('session data:', sessionData);
|
||||
const cards = Cards.find({ _id: { $in: sessionData.cards } });
|
||||
this.queryErrors = sessionData.errors;
|
||||
if (this.queryErrors.length) {
|
||||
this.hasQueryErrors.set(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (cards) {
|
||||
this.totalHits = sessionData.totalHits;
|
||||
this.resultsCount = cards.count();
|
||||
this.resultsStart = sessionData.lastHit - this.resultsCount + 1;
|
||||
this.resultsEnd = sessionData.lastHit;
|
||||
this.resultsHeading.set(this.getResultsHeading());
|
||||
this.results.set(cards);
|
||||
this.hasNextPage.set(sessionData.lastHit < sessionData.totalHits);
|
||||
this.hasPreviousPage.set(
|
||||
sessionData.lastHit - sessionData.resultsCount > 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
this.resultsCount = 0;
|
||||
return null;
|
||||
},
|
||||
super.resetSearch();
|
||||
this.parsingErrors = new QueryErrors();
|
||||
}
|
||||
|
||||
errorMessages() {
|
||||
if (this.parsingErrors.length) {
|
||||
return this.parsingErrorMessages();
|
||||
if (this.parsingErrors.hasErrors()) {
|
||||
return this.parsingErrors.errorMessages();
|
||||
}
|
||||
return this.queryErrorMessages();
|
||||
},
|
||||
}
|
||||
|
||||
parsingErrorMessages() {
|
||||
const messages = [];
|
||||
this.parsingErrors.errorMessages();
|
||||
}
|
||||
|
||||
if (this.parsingErrors.length) {
|
||||
this.parsingErrors.forEach(err => {
|
||||
messages.push(TAPi18n.__(err.tag, err.value));
|
||||
});
|
||||
}
|
||||
|
||||
return messages;
|
||||
},
|
||||
|
||||
queryErrorMessages() {
|
||||
messages = [];
|
||||
|
||||
this.queryErrors.forEach(err => {
|
||||
let value = err.color ? TAPi18n.__(`color-${err.value}`) : err.value;
|
||||
if (!value) {
|
||||
value = err.value;
|
||||
}
|
||||
messages.push(TAPi18n.__(err.tag, value));
|
||||
});
|
||||
|
||||
return messages;
|
||||
},
|
||||
|
||||
searchAllBoards(query) {
|
||||
query = query.trim();
|
||||
searchAllBoards(queryText) {
|
||||
queryText = queryText.trim();
|
||||
// eslint-disable-next-line no-console
|
||||
//console.log('query:', query);
|
||||
//console.log('queryText:', queryText);
|
||||
|
||||
this.query.set(query);
|
||||
this.query.set(queryText);
|
||||
|
||||
this.resetSearch();
|
||||
|
||||
if (!query) {
|
||||
if (!queryText) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.searching.set(true);
|
||||
|
||||
const reOperator1 = new RegExp(
|
||||
'^((?<operator>[\\p{Letter}\\p{Mark}]+):|(?<abbrev>[#@]))(?<value>[\\p{Letter}\\p{Mark}]+)(\\s+|$)',
|
||||
'iu',
|
||||
);
|
||||
const reOperator2 = new RegExp(
|
||||
'^((?<operator>[\\p{Letter}\\p{Mark}]+):|(?<abbrev>[#@]))(?<quote>["\']*)(?<value>.*?)\\k<quote>(\\s+|$)',
|
||||
'iu',
|
||||
);
|
||||
const reText = new RegExp('^(?<text>\\S+)(\\s+|$)', 'u');
|
||||
const reQuotedText = new RegExp(
|
||||
'^(?<quote>["\'])(?<text>.*?)\\k<quote>(\\s+|$)',
|
||||
'u',
|
||||
);
|
||||
|
||||
const operators = {
|
||||
'operator-board': 'boards',
|
||||
'operator-board-abbrev': 'boards',
|
||||
'operator-swimlane': 'swimlanes',
|
||||
'operator-swimlane-abbrev': 'swimlanes',
|
||||
'operator-list': 'lists',
|
||||
'operator-list-abbrev': 'lists',
|
||||
'operator-label': 'labels',
|
||||
'operator-label-abbrev': 'labels',
|
||||
'operator-user': 'users',
|
||||
'operator-user-abbrev': 'users',
|
||||
'operator-member': 'members',
|
||||
'operator-member-abbrev': 'members',
|
||||
'operator-assignee': 'assignees',
|
||||
'operator-assignee-abbrev': 'assignees',
|
||||
'operator-status': 'status',
|
||||
'operator-due': 'dueAt',
|
||||
'operator-created': 'createdAt',
|
||||
'operator-modified': 'modifiedAt',
|
||||
'operator-comment': 'comments',
|
||||
};
|
||||
|
||||
const predicates = {
|
||||
due: {
|
||||
'predicate-overdue': 'overdue',
|
||||
},
|
||||
durations: {
|
||||
'predicate-week': 'week',
|
||||
'predicate-month': 'month',
|
||||
'predicate-quarter': 'quarter',
|
||||
'predicate-year': 'year',
|
||||
},
|
||||
status: {
|
||||
'predicate-archived': 'archived',
|
||||
'predicate-all': 'all',
|
||||
'predicate-ended': 'ended',
|
||||
},
|
||||
sorts: {
|
||||
'predicate-due': 'dueAt',
|
||||
'predicate-created': 'createdAt',
|
||||
'predicate-modified': 'modifiedAt',
|
||||
},
|
||||
};
|
||||
const predicateTranslations = {};
|
||||
Object.entries(predicates).forEach(([category, catPreds]) => {
|
||||
predicateTranslations[category] = {};
|
||||
Object.entries(catPreds).forEach(([tag, value]) => {
|
||||
predicateTranslations[category][TAPi18n.__(tag)] = value;
|
||||
});
|
||||
});
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('predicateTranslations:', predicateTranslations);
|
||||
|
||||
const operatorMap = {};
|
||||
Object.entries(operators).forEach(([key, value]) => {
|
||||
operatorMap[TAPi18n.__(key).toLowerCase()] = value;
|
||||
});
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('operatorMap:', operatorMap);
|
||||
|
||||
const params = {
|
||||
limit: this.resultsPerPage,
|
||||
boards: [],
|
||||
swimlanes: [],
|
||||
lists: [],
|
||||
users: [],
|
||||
members: [],
|
||||
assignees: [],
|
||||
labels: [],
|
||||
status: [],
|
||||
dueAt: null,
|
||||
createdAt: null,
|
||||
modifiedAt: null,
|
||||
comments: [],
|
||||
};
|
||||
|
||||
let text = '';
|
||||
while (query) {
|
||||
m = query.match(reOperator1);
|
||||
if (!m) {
|
||||
m = query.match(reOperator2);
|
||||
if (m) {
|
||||
query = query.replace(reOperator2, '');
|
||||
}
|
||||
} else {
|
||||
query = query.replace(reOperator1, '');
|
||||
}
|
||||
if (m) {
|
||||
let op;
|
||||
if (m.groups.operator) {
|
||||
op = m.groups.operator.toLowerCase();
|
||||
} else {
|
||||
op = m.groups.abbrev.toLowerCase();
|
||||
}
|
||||
if (operatorMap.hasOwnProperty(op)) {
|
||||
let value = m.groups.value;
|
||||
if (operatorMap[op] === 'labels') {
|
||||
if (value in this.colorMap) {
|
||||
value = this.colorMap[value];
|
||||
// console.log('found color:', value);
|
||||
}
|
||||
} else if (
|
||||
['dueAt', 'createdAt', 'modifiedAt'].includes(operatorMap[op])
|
||||
) {
|
||||
let days = parseInt(value, 10);
|
||||
let duration = null;
|
||||
if (isNaN(days)) {
|
||||
if (predicateTranslations.durations[value]) {
|
||||
duration = predicateTranslations.durations[value];
|
||||
value = moment();
|
||||
} else if (predicateTranslations.due[value] === 'overdue') {
|
||||
value = moment();
|
||||
duration = 'days';
|
||||
days = 0;
|
||||
} else {
|
||||
this.parsingErrors.push({
|
||||
tag: 'operator-number-expected',
|
||||
value: { operator: op, value },
|
||||
});
|
||||
value = null;
|
||||
}
|
||||
} else {
|
||||
value = moment();
|
||||
}
|
||||
if (value) {
|
||||
if (operatorMap[op] === 'dueAt') {
|
||||
value = value.add(days, duration ? duration : 'days').format();
|
||||
} else {
|
||||
value = value
|
||||
.subtract(days, duration ? duration : 'days')
|
||||
.format();
|
||||
}
|
||||
}
|
||||
} else if (operatorMap[op] === 'sort') {
|
||||
if (!predicateTranslations.sorts[value]) {
|
||||
this.parsingErrors.push({
|
||||
tag: 'operator-sort-invalid',
|
||||
value,
|
||||
});
|
||||
} else {
|
||||
value = predicateTranslations.sorts[value];
|
||||
}
|
||||
} else if (operatorMap[op] === 'status') {
|
||||
if (!predicateTranslations.status[value]) {
|
||||
this.parsingErrors.push({
|
||||
tag: 'operator-status-invalid',
|
||||
value,
|
||||
});
|
||||
} else {
|
||||
value = predicateTranslations.status[value];
|
||||
}
|
||||
}
|
||||
if (Array.isArray(params[operatorMap[op]])) {
|
||||
params[operatorMap[op]].push(value);
|
||||
} else {
|
||||
params[operatorMap[op]] = value;
|
||||
}
|
||||
} else {
|
||||
this.parsingErrors.push({
|
||||
tag: 'operator-unknown-error',
|
||||
value: op,
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
m = query.match(reQuotedText);
|
||||
if (!m) {
|
||||
m = query.match(reText);
|
||||
if (m) {
|
||||
query = query.replace(reText, '');
|
||||
}
|
||||
} else {
|
||||
query = query.replace(reQuotedText, '');
|
||||
}
|
||||
if (m) {
|
||||
text += (text ? ' ' : '') + m.groups.text;
|
||||
}
|
||||
}
|
||||
const query = new Query();
|
||||
query.buildParams(queryText);
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('text:', text);
|
||||
params.text = text;
|
||||
// console.log('params:', query.getParams());
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('params:', params);
|
||||
this.queryParams = query.getQueryParams().getParams();
|
||||
|
||||
this.queryParams = params;
|
||||
|
||||
if (this.parsingErrors.length) {
|
||||
if (query.hasErrors()) {
|
||||
this.searching.set(false);
|
||||
this.queryErrors = this.parsingErrorMessages();
|
||||
this.queryErrors = query.errors();
|
||||
this.hasResults.set(true);
|
||||
this.hasQueryErrors.set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
this.autorun(() => {
|
||||
const handle = Meteor.subscribe(
|
||||
'globalSearch',
|
||||
SessionData.getSessionId(),
|
||||
params,
|
||||
);
|
||||
Tracker.nonreactive(() => {
|
||||
Tracker.autorun(() => {
|
||||
if (handle.ready()) {
|
||||
this.getResults();
|
||||
this.searching.set(false);
|
||||
this.hasResults.set(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
nextPage() {
|
||||
sessionData = this.getSessionData();
|
||||
|
||||
const params = {
|
||||
limit: this.resultsPerPage,
|
||||
selector: sessionData.getSelector(),
|
||||
skip: sessionData.lastHit,
|
||||
};
|
||||
|
||||
this.autorun(() => {
|
||||
const handle = Meteor.subscribe(
|
||||
'globalSearch',
|
||||
SessionData.getSessionId(),
|
||||
params,
|
||||
);
|
||||
Tracker.nonreactive(() => {
|
||||
Tracker.autorun(() => {
|
||||
if (handle.ready()) {
|
||||
this.getResults();
|
||||
this.searching.set(false);
|
||||
this.hasResults.set(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
previousPage() {
|
||||
sessionData = this.getSessionData();
|
||||
|
||||
const params = {
|
||||
limit: this.resultsPerPage,
|
||||
selector: sessionData.getSelector(),
|
||||
skip:
|
||||
sessionData.lastHit - sessionData.resultsCount - this.resultsPerPage,
|
||||
};
|
||||
|
||||
this.autorun(() => {
|
||||
const handle = Meteor.subscribe(
|
||||
'globalSearch',
|
||||
SessionData.getSessionId(),
|
||||
params,
|
||||
);
|
||||
Tracker.nonreactive(() => {
|
||||
Tracker.autorun(() => {
|
||||
if (handle.ready()) {
|
||||
this.getResults();
|
||||
this.searching.set(false);
|
||||
this.hasResults.set(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getResultsHeading() {
|
||||
if (this.resultsCount === 0) {
|
||||
return TAPi18n.__('no-cards-found');
|
||||
} else if (this.resultsCount === 1) {
|
||||
return TAPi18n.__('one-card-found');
|
||||
} else if (this.resultsCount === this.totalHits) {
|
||||
return TAPi18n.__('n-cards-found', this.resultsCount);
|
||||
}
|
||||
|
||||
return TAPi18n.__('n-n-of-n-cards-found', {
|
||||
start: this.resultsStart,
|
||||
end: this.resultsEnd,
|
||||
total: this.totalHits,
|
||||
});
|
||||
},
|
||||
|
||||
getSearchHref() {
|
||||
const baseUrl = window.location.href.replace(/([?#].*$|\s*$)/, '');
|
||||
return `${baseUrl}?q=${encodeURIComponent(this.query.get())}`;
|
||||
},
|
||||
this.runGlobalSearch(query.getQueryParams());
|
||||
}
|
||||
|
||||
searchInstructions() {
|
||||
tags = {
|
||||
const tags = {
|
||||
operator_board: TAPi18n.__('operator-board'),
|
||||
operator_list: TAPi18n.__('operator-list'),
|
||||
operator_swimlane: TAPi18n.__('operator-swimlane'),
|
||||
@@ -511,6 +127,9 @@ BlazeComponent.extendComponent({
|
||||
operator_created: TAPi18n.__('operator-created'),
|
||||
operator_modified: TAPi18n.__('operator-modified'),
|
||||
operator_status: TAPi18n.__('operator-status'),
|
||||
operator_has: TAPi18n.__('operator-has'),
|
||||
operator_sort: TAPi18n.__('operator-sort'),
|
||||
operator_limit: TAPi18n.__('operator-limit'),
|
||||
predicate_overdue: TAPi18n.__('predicate-overdue'),
|
||||
predicate_archived: TAPi18n.__('predicate-archived'),
|
||||
predicate_all: TAPi18n.__('predicate-all'),
|
||||
@@ -519,74 +138,60 @@ BlazeComponent.extendComponent({
|
||||
predicate_month: TAPi18n.__('predicate-month'),
|
||||
predicate_quarter: TAPi18n.__('predicate-quarter'),
|
||||
predicate_year: TAPi18n.__('predicate-year'),
|
||||
predicate_attachment: TAPi18n.__('predicate-attachment'),
|
||||
predicate_description: TAPi18n.__('predicate-description'),
|
||||
predicate_checklist: TAPi18n.__('predicate-checklist'),
|
||||
predicate_public: TAPi18n.__('predicate-public'),
|
||||
predicate_private: TAPi18n.__('predicate-private'),
|
||||
predicate_due: TAPi18n.__('predicate-due'),
|
||||
predicate_created: TAPi18n.__('predicate-created'),
|
||||
predicate_modified: TAPi18n.__('predicate-modified'),
|
||||
predicate_start: TAPi18n.__('predicate-start'),
|
||||
predicate_end: TAPi18n.__('predicate-end'),
|
||||
predicate_assignee: TAPi18n.__('predicate-assignee'),
|
||||
predicate_member: TAPi18n.__('predicate-member'),
|
||||
};
|
||||
|
||||
text = `# ${TAPi18n.__('globalSearch-instructions-heading')}`;
|
||||
text += `\n${TAPi18n.__('globalSearch-instructions-description', tags)}`;
|
||||
text += `\n${TAPi18n.__('globalSearch-instructions-operators', tags)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-board',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-list',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-swimlane',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-comment',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-label',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-hash',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-user',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-operator-at', tags)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-member',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-assignee',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-operator-due', tags)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-created',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-operator-modified',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__(
|
||||
'globalSearch-instructions-status-archived',
|
||||
tags,
|
||||
)}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-status-all', tags)}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-status-ended', tags)}`;
|
||||
|
||||
text += `\n## ${TAPi18n.__('heading-notes')}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-1', tags)}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-2', tags)}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-3', tags)}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-3-2', tags)}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-4', tags)}`;
|
||||
text += `\n* ${TAPi18n.__('globalSearch-instructions-notes-5', tags)}`;
|
||||
let text = '';
|
||||
[
|
||||
['# ', 'globalSearch-instructions-heading'],
|
||||
['\n', 'globalSearch-instructions-description'],
|
||||
['\n\n', 'globalSearch-instructions-operators'],
|
||||
['\n* ', 'globalSearch-instructions-operator-board'],
|
||||
['\n* ', 'globalSearch-instructions-operator-list'],
|
||||
['\n* ', 'globalSearch-instructions-operator-swimlane'],
|
||||
['\n* ', 'globalSearch-instructions-operator-comment'],
|
||||
['\n* ', 'globalSearch-instructions-operator-label'],
|
||||
['\n* ', 'globalSearch-instructions-operator-hash'],
|
||||
['\n* ', 'globalSearch-instructions-operator-user'],
|
||||
['\n* ', 'globalSearch-instructions-operator-at'],
|
||||
['\n* ', 'globalSearch-instructions-operator-member'],
|
||||
['\n* ', 'globalSearch-instructions-operator-assignee'],
|
||||
['\n* ', 'globalSearch-instructions-operator-due'],
|
||||
['\n* ', 'globalSearch-instructions-operator-created'],
|
||||
['\n* ', 'globalSearch-instructions-operator-modified'],
|
||||
['\n* ', 'globalSearch-instructions-operator-status'],
|
||||
['\n * ', 'globalSearch-instructions-status-archived'],
|
||||
['\n * ', 'globalSearch-instructions-status-public'],
|
||||
['\n * ', 'globalSearch-instructions-status-private'],
|
||||
['\n * ', 'globalSearch-instructions-status-all'],
|
||||
['\n * ', 'globalSearch-instructions-status-ended'],
|
||||
['\n* ', 'globalSearch-instructions-operator-has'],
|
||||
['\n* ', 'globalSearch-instructions-operator-sort'],
|
||||
['\n* ', 'globalSearch-instructions-operator-limit'],
|
||||
['\n## ', 'heading-notes'],
|
||||
['\n* ', 'globalSearch-instructions-notes-1'],
|
||||
['\n* ', 'globalSearch-instructions-notes-2'],
|
||||
['\n* ', 'globalSearch-instructions-notes-3'],
|
||||
['\n* ', 'globalSearch-instructions-notes-3-2'],
|
||||
['\n* ', 'globalSearch-instructions-notes-4'],
|
||||
['\n* ', 'globalSearch-instructions-notes-5'],
|
||||
].forEach(([prefix, instruction]) => {
|
||||
text += `${prefix}${TAPi18n.__(instruction, tags)}`;
|
||||
});
|
||||
|
||||
return text;
|
||||
},
|
||||
}
|
||||
|
||||
labelColors() {
|
||||
return Boards.simpleSchema()._schema['labels.$.color'].allowedValues.map(
|
||||
@@ -594,23 +199,16 @@ BlazeComponent.extendComponent({
|
||||
return { color, name: TAPi18n.__(`color-${color}`) };
|
||||
},
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
...super.events()[0],
|
||||
'submit .js-search-query-form'(evt) {
|
||||
evt.preventDefault();
|
||||
this.searchAllBoards(evt.target.searchQuery.value);
|
||||
},
|
||||
'click .js-next-page'(evt) {
|
||||
evt.preventDefault();
|
||||
this.nextPage();
|
||||
},
|
||||
'click .js-previous-page'(evt) {
|
||||
evt.preventDefault();
|
||||
this.previousPage();
|
||||
},
|
||||
'click .js-label-color'(evt) {
|
||||
evt.preventDefault();
|
||||
const input = document.getElementById('global-search-input');
|
||||
@@ -651,7 +249,16 @@ BlazeComponent.extendComponent({
|
||||
);
|
||||
document.getElementById('global-search-input').focus();
|
||||
},
|
||||
'click .js-new-search'(evt) {
|
||||
evt.preventDefault();
|
||||
const input = document.getElementById('global-search-input');
|
||||
input.value = '';
|
||||
this.query.set('');
|
||||
this.hasResults.set(false);
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('globalSearch');
|
||||
}
|
||||
}
|
||||
|
||||
GlobalSearchComponent.register('globalSearch');
|
||||
@@ -71,17 +71,17 @@
|
||||
.global-search-error-messages
|
||||
color: darkred
|
||||
|
||||
.global-search-instructions
|
||||
.global-search-page
|
||||
width: 40%
|
||||
min-width: 400px
|
||||
margin-right: auto
|
||||
margin-left: auto
|
||||
line-height: 150%
|
||||
|
||||
.global-search-instructions h1
|
||||
.global-search-page h1
|
||||
margin-top: 2rem;
|
||||
|
||||
.global-search-instructions h2
|
||||
.global-search-page h2
|
||||
margin-top: 1rem;
|
||||
|
||||
.global-search-query-input
|
||||
@@ -100,7 +100,7 @@ code
|
||||
color: black
|
||||
background-color: lightgrey
|
||||
padding: 0.1rem !important
|
||||
font-size: 0.7rem !important
|
||||
font-size: 0.8rem !important
|
||||
|
||||
.list-title
|
||||
background-color: darkgray
|
||||
@@ -116,3 +116,6 @@ code
|
||||
.global-search-previous-page
|
||||
border: none
|
||||
text-align: left;
|
||||
|
||||
.global-search-instructions li
|
||||
margin-bottom: 0.3rem
|
||||
@@ -11,7 +11,7 @@ template(name="header")
|
||||
a(href="{{pathFor 'home'}}")
|
||||
span.fa.fa-home
|
||||
|
||||
ul
|
||||
ul.header-quick-access-list
|
||||
if currentList
|
||||
each currentBoard.lists
|
||||
li(class="{{#if $.Session.equals 'currentList' _id}}current{{/if}}")
|
||||
@@ -37,11 +37,11 @@ template(name="header")
|
||||
img(src="{{currentSetting.customTopLeftCornerLogoImageUrl}}" height="{{#if currentSetting.customTopLeftCornerLogoHeight}}#{currentSetting.customTopLeftCornerLogoHeight}{{else}}27{{/if}}" width="auto" margin="0" padding="0")
|
||||
unless currentSetting.customTopLeftCornerLogoImageUrl
|
||||
img(src="{{pathFor '/logo-header.png'}}" alt="")
|
||||
span
|
||||
span.allBoards
|
||||
a(href="{{pathFor 'home'}}")
|
||||
span.fa.fa-home
|
||||
| {{_ 'all-boards'}}
|
||||
ul
|
||||
ul.header-quick-access-list
|
||||
//li
|
||||
// a(href="{{pathFor 'public'}}")
|
||||
// span.fa.fa-globe
|
||||
@@ -51,7 +51,7 @@ template(name="header")
|
||||
a(href="{{pathFor 'board' id=_id slug=slug}}")
|
||||
= title
|
||||
else
|
||||
li.current {{_ 'quick-access-description'}}
|
||||
li.current.empty {{_ 'quick-access-description'}}
|
||||
|
||||
// Next line is used only for spacing at header,
|
||||
// there is no visible clickable icon.
|
||||
|
||||
@@ -102,6 +102,9 @@
|
||||
z-index: 21
|
||||
padding: 10px 0px
|
||||
|
||||
.allBoards
|
||||
padding: 0 0 0 10px
|
||||
|
||||
#header-user-bar,
|
||||
#header-new-board-icon,
|
||||
ul li
|
||||
@@ -113,7 +116,7 @@
|
||||
a:hover, a.is-active
|
||||
color: white
|
||||
|
||||
ul
|
||||
ul.header-quick-access-list
|
||||
transition: opacity 0.2s
|
||||
overflow-x: auto
|
||||
overflow-y: hidden
|
||||
@@ -135,6 +138,9 @@
|
||||
&.current
|
||||
color: darken(white, 5%)
|
||||
|
||||
&.current.empty
|
||||
padding: 12px 10px 12px 10px
|
||||
|
||||
&:first-child .fa-home,&:nth-child(3) .fa-globe
|
||||
margin-right: 5px
|
||||
|
||||
@@ -210,7 +216,8 @@
|
||||
.fa-home
|
||||
font-size: 26px
|
||||
margin-top: -2px
|
||||
margin-right: 20px
|
||||
margin-right: 10px
|
||||
margin-left: 10px
|
||||
|
||||
#header-new-board-icon
|
||||
display: none
|
||||
|
||||
@@ -77,20 +77,45 @@ Template.userFormsLayout.helpers({
|
||||
} else if (lang.name === 'ar-EG') {
|
||||
// ar-EG = Arabic (Egypt), simply Masri (مَصرى, [ˈmɑsˤɾi], Egyptian, Masr refers to Cairo)
|
||||
name = 'مَصرى';
|
||||
} else if (lang.name === 'es-PY') {
|
||||
name = 'Español de Paraguayo';
|
||||
} else if (lang.name === 'fa-IR') {
|
||||
// fa-IR = Persian (Iran)
|
||||
name = 'فارسی/پارسی (ایران)';
|
||||
} else if (lang.name === 'fr-BE') {
|
||||
name = 'Français (Belgique)';
|
||||
} else if (lang.name === 'fr-CA') {
|
||||
name = 'Français (Canada)';
|
||||
} else if (lang.name === 'fr-CA') {
|
||||
name = 'Français (Canada)';
|
||||
} else if (lang.name === 'ig') {
|
||||
name = 'Igbo';
|
||||
} else if (lang.name === 'lv') {
|
||||
name = 'Latviešu';
|
||||
} else if (lang.name === 'latviešu valoda') {
|
||||
name = 'Latviešu';
|
||||
} else if (lang.name === 'Español') {
|
||||
name = 'español';
|
||||
} else if (lang.name === 'es_419') {
|
||||
name = 'español de América Latina';
|
||||
} else if (lang.name === 'es-419') {
|
||||
name = 'español de América Latina';
|
||||
} else if (lang.name === 'Español de América Latina') {
|
||||
name = 'español de América Latina';
|
||||
} else if (lang.name === 'es-LA') {
|
||||
name = 'español de América Latina';
|
||||
} else if (lang.name === 'Español de Argentina') {
|
||||
name = 'español de Argentina';
|
||||
} else if (lang.name === 'Español de Chile') {
|
||||
name = 'español de Chile';
|
||||
} else if (lang.name === 'Español de Colombia') {
|
||||
name = 'español de Colombia';
|
||||
} else if (lang.name === 'Español de México') {
|
||||
name = 'español de México';
|
||||
} else if (lang.name === 'es-PY') {
|
||||
name = 'español de Paraguayo';
|
||||
} else if (lang.name === 'Español de Paraguayo') {
|
||||
name = 'español de Paraguayo';
|
||||
} else if (lang.name === 'Español de Perú') {
|
||||
name = 'español de Perú';
|
||||
} else if (lang.name === 'Español de Puerto Rico') {
|
||||
name = 'español de Puerto Rico';
|
||||
} else if (lang.name === 'oc') {
|
||||
name = 'Occitan';
|
||||
} else if (lang.name === 'st') {
|
||||
|
||||
@@ -24,14 +24,16 @@ template(name="myCardsModalTitle")
|
||||
|
||||
template(name="myCards")
|
||||
if currentUser
|
||||
if isPageReady.get
|
||||
if searching.get
|
||||
+spinner
|
||||
else
|
||||
.wrapper
|
||||
if $eq myCardsSort 'board'
|
||||
each board in myCardsList
|
||||
.my-cards-board-wrapper
|
||||
.my-cards-board-title(class=board.colorClass, id="header")
|
||||
a(href=board.absoluteUrl)
|
||||
+viewer
|
||||
a(href=board.originRelativeUrl)
|
||||
+viewer
|
||||
= board.title
|
||||
each swimlane in board.mySwimlanes
|
||||
.my-cards-swimlane-title(class="{{#if swimlane.colorClass}}{{ swimlane.colorClass }}{{else}}swimlane-default-color{{/if}}")
|
||||
@@ -44,14 +46,12 @@ template(name="myCards")
|
||||
= list.title
|
||||
each card in list.myCards
|
||||
.my-cards-card-wrapper
|
||||
a.minicard-wrapper(href=card.absoluteUrl)
|
||||
a.minicard-wrapper(href=card.originRelativeUrl)
|
||||
+minicard(card)
|
||||
else
|
||||
.my-cards-dueat-list-wrapper
|
||||
each card in myDueCardsList
|
||||
+resultCard(card)
|
||||
else
|
||||
+spinner
|
||||
|
||||
template(name="myCardsSortChangePopup")
|
||||
if currentUser
|
||||
|
||||
+111
-153
@@ -1,4 +1,14 @@
|
||||
const subManager = new SubsManager();
|
||||
import { CardSearchPagedComponent } from '../../lib/cardSearch';
|
||||
import { QueryParams } from '../../../config/query-classes';
|
||||
import {
|
||||
OPERATOR_LIMIT,
|
||||
OPERATOR_SORT,
|
||||
OPERATOR_USER,
|
||||
ORDER_DESCENDING,
|
||||
PREDICATE_DUE_AT,
|
||||
} from '../../../config/search-const';
|
||||
|
||||
// const subManager = new SubsManager();
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
myCardsSort() {
|
||||
@@ -42,182 +52,147 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
}).register('myCardsSortChangePopup');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
class MyCardsComponent extends CardSearchPagedComponent {
|
||||
onCreated() {
|
||||
this.isPageReady = new ReactiveVar(false);
|
||||
super.onCreated();
|
||||
|
||||
this.autorun(() => {
|
||||
const handle = subManager.subscribe('myCards');
|
||||
Tracker.nonreactive(() => {
|
||||
Tracker.autorun(() => {
|
||||
this.isPageReady.set(handle.ready());
|
||||
});
|
||||
});
|
||||
const queryParams = new QueryParams();
|
||||
queryParams.addPredicate(OPERATOR_USER, Meteor.user().username);
|
||||
queryParams.addPredicate(OPERATOR_SORT, {
|
||||
name: PREDICATE_DUE_AT,
|
||||
order: ORDER_DESCENDING,
|
||||
});
|
||||
queryParams.addPredicate(OPERATOR_LIMIT, 100);
|
||||
|
||||
this.runGlobalSearch(queryParams);
|
||||
Meteor.subscribe('setting');
|
||||
},
|
||||
}
|
||||
|
||||
myCardsSort() {
|
||||
// eslint-disable-next-line no-console
|
||||
//console.log('sort:', Utils.myCardsSort());
|
||||
return Utils.myCardsSort();
|
||||
},
|
||||
}
|
||||
|
||||
sortByBoard() {
|
||||
return this.myCardsSort() === 'board';
|
||||
},
|
||||
}
|
||||
|
||||
myCardsList() {
|
||||
const userId = Meteor.userId();
|
||||
const boards = [];
|
||||
let board = null;
|
||||
let swimlane = null;
|
||||
let list = null;
|
||||
|
||||
const cursor = Cards.find(
|
||||
{
|
||||
$or: [{ members: userId }, { assignees: userId }],
|
||||
archived: false,
|
||||
},
|
||||
{
|
||||
sort: {
|
||||
boardId: 1,
|
||||
swimlaneId: 1,
|
||||
listId: 1,
|
||||
sort: 1,
|
||||
},
|
||||
},
|
||||
);
|
||||
const cursor = this.getResults();
|
||||
|
||||
let newBoard = false;
|
||||
let newSwimlane = false;
|
||||
let newList = false;
|
||||
if (cursor) {
|
||||
let newBoard = false;
|
||||
let newSwimlane = false;
|
||||
let newList = false;
|
||||
|
||||
cursor.forEach(card => {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('card:', card.title);
|
||||
if (list === null || card.listId !== list._id) {
|
||||
cursor.forEach(card => {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('new list');
|
||||
list = card.getList();
|
||||
if (list.archived) {
|
||||
list = null;
|
||||
return;
|
||||
// console.log('card:', card.title);
|
||||
if (list === null || card.listId !== list._id) {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('new list');
|
||||
list = card.getList();
|
||||
if (list.archived) {
|
||||
list = null;
|
||||
return;
|
||||
}
|
||||
list.myCards = [card];
|
||||
newList = true;
|
||||
}
|
||||
list.myCards = [card];
|
||||
newList = true;
|
||||
}
|
||||
if (swimlane === null || card.swimlaneId !== swimlane._id) {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('new swimlane');
|
||||
swimlane = card.getSwimlane();
|
||||
if (swimlane.archived) {
|
||||
swimlane = null;
|
||||
return;
|
||||
if (swimlane === null || card.swimlaneId !== swimlane._id) {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('new swimlane');
|
||||
swimlane = card.getSwimlane();
|
||||
if (swimlane.archived) {
|
||||
swimlane = null;
|
||||
return;
|
||||
}
|
||||
swimlane.myLists = [list];
|
||||
newSwimlane = true;
|
||||
}
|
||||
swimlane.myLists = [list];
|
||||
newSwimlane = true;
|
||||
}
|
||||
if (board === null || card.boardId !== board._id) {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('new board');
|
||||
board = card.getBoard();
|
||||
if (board.archived) {
|
||||
board = null;
|
||||
return;
|
||||
if (board === null || card.boardId !== board._id) {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('new board');
|
||||
board = card.getBoard();
|
||||
if (board.archived) {
|
||||
board = null;
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('board:', b, b._id, b.title);
|
||||
board.mySwimlanes = [swimlane];
|
||||
newBoard = true;
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('board:', b, b._id, b.title);
|
||||
board.mySwimlanes = [swimlane];
|
||||
newBoard = true;
|
||||
}
|
||||
|
||||
if (newBoard) {
|
||||
boards.push(board);
|
||||
} else if (newSwimlane) {
|
||||
board.mySwimlanes.push(swimlane);
|
||||
} else if (newList) {
|
||||
swimlane.myLists.push(list);
|
||||
} else {
|
||||
list.myCards.push(card);
|
||||
}
|
||||
if (newBoard) {
|
||||
boards.push(board);
|
||||
} else if (newSwimlane) {
|
||||
board.mySwimlanes.push(swimlane);
|
||||
} else if (newList) {
|
||||
swimlane.myLists.push(list);
|
||||
} else {
|
||||
list.myCards.push(card);
|
||||
}
|
||||
|
||||
newBoard = false;
|
||||
newSwimlane = false;
|
||||
newList = false;
|
||||
});
|
||||
newBoard = false;
|
||||
newSwimlane = false;
|
||||
newList = false;
|
||||
});
|
||||
|
||||
// sort the data structure
|
||||
boards.forEach(board => {
|
||||
board.mySwimlanes.forEach(swimlane => {
|
||||
swimlane.myLists.forEach(list => {
|
||||
list.myCards.sort((a, b) => {
|
||||
// sort the data structure
|
||||
boards.forEach(board => {
|
||||
board.mySwimlanes.forEach(swimlane => {
|
||||
swimlane.myLists.forEach(list => {
|
||||
list.myCards.sort((a, b) => {
|
||||
return a.sort - b.sort;
|
||||
});
|
||||
});
|
||||
swimlane.myLists.sort((a, b) => {
|
||||
return a.sort - b.sort;
|
||||
});
|
||||
});
|
||||
swimlane.myLists.sort((a, b) => {
|
||||
board.mySwimlanes.sort((a, b) => {
|
||||
return a.sort - b.sort;
|
||||
});
|
||||
});
|
||||
board.mySwimlanes.sort((a, b) => {
|
||||
return a.sort - b.sort;
|
||||
|
||||
boards.sort((a, b) => {
|
||||
let x = a.sort;
|
||||
let y = b.sort;
|
||||
|
||||
// show the template board last
|
||||
if (a.type === 'template-container') {
|
||||
x = 99999999;
|
||||
} else if (b.type === 'template-container') {
|
||||
y = 99999999;
|
||||
}
|
||||
return x - y;
|
||||
});
|
||||
});
|
||||
|
||||
boards.sort((a, b) => {
|
||||
let x = a.sort;
|
||||
let y = b.sort;
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('boards:', boards);
|
||||
return boards;
|
||||
}
|
||||
|
||||
// show the template board last
|
||||
if (a.type === 'template-container') {
|
||||
x = 99999999;
|
||||
} else if (b.type === 'template-container') {
|
||||
y = 99999999;
|
||||
}
|
||||
return x - y;
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('boards:', boards);
|
||||
return boards;
|
||||
},
|
||||
return [];
|
||||
}
|
||||
|
||||
myDueCardsList() {
|
||||
const userId = Meteor.userId();
|
||||
|
||||
const cursor = Cards.find(
|
||||
{
|
||||
$or: [{ members: userId }, { assignees: userId }],
|
||||
archived: false,
|
||||
},
|
||||
{
|
||||
sort: {
|
||||
dueAt: -1,
|
||||
boardId: 1,
|
||||
swimlaneId: 1,
|
||||
listId: 1,
|
||||
sort: 1,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('cursor:', cursor);
|
||||
|
||||
const cursor = this.getResults();
|
||||
const cards = [];
|
||||
cursor.forEach(card => {
|
||||
if (
|
||||
!card.getBoard().archived &&
|
||||
!card.getSwimlane().archived &&
|
||||
!card.getList().archived
|
||||
) {
|
||||
cards.push(card);
|
||||
}
|
||||
cards.push(card);
|
||||
});
|
||||
|
||||
cards.sort((a, b) => {
|
||||
const x = a.dueAt === null ? Date('2100-12-31') : a.dueAt;
|
||||
const y = b.dueAt === null ? Date('2100-12-31') : b.dueAt;
|
||||
const x = a.dueAt === null ? new Date('2100-12-31') : a.dueAt;
|
||||
const y = b.dueAt === null ? new Date('2100-12-31') : b.dueAt;
|
||||
|
||||
if (x > y) return 1;
|
||||
else if (x < y) return -1;
|
||||
@@ -228,23 +203,6 @@ BlazeComponent.extendComponent({
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('cursor:', cards);
|
||||
return cards;
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
// 'click .js-my-card'(evt) {
|
||||
// const card = this.currentData().card;
|
||||
// // eslint-disable-next-line no-console
|
||||
// console.log('currentData():', this.currentData());
|
||||
// // eslint-disable-next-line no-console
|
||||
// console.log('card:', card);
|
||||
// if (card) {
|
||||
// Utils.goCardId(card._id);
|
||||
// }
|
||||
// evt.preventDefault();
|
||||
// },
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('myCards');
|
||||
}
|
||||
}
|
||||
MyCardsComponent.register('myCards');
|
||||
@@ -29,10 +29,7 @@
|
||||
color: #bbb
|
||||
|
||||
.details
|
||||
|
||||
.activity
|
||||
display: flex
|
||||
|
||||
a.member
|
||||
margin: 0px 0px 0px 0px
|
||||
padding: 0px
|
||||
|
||||
Vendored
BIN
Binary file not shown.
@@ -74,7 +74,6 @@ template(name="orgGeneral")
|
||||
th {{_ 'description'}}
|
||||
th {{_ 'shortName'}}
|
||||
th {{_ 'website'}}
|
||||
th {{_ 'teams'}}
|
||||
th {{_ 'createdAt'}}
|
||||
th {{_ 'active'}}
|
||||
th
|
||||
@@ -118,41 +117,37 @@ template(name="peopleGeneral")
|
||||
|
||||
template(name="newOrgRow")
|
||||
a.new-org
|
||||
i.fa.fa-edit
|
||||
i.fa.fa-plus-square
|
||||
| {{_ 'new'}}
|
||||
|
||||
template(name="newTeamRow")
|
||||
a.new-team
|
||||
i.fa.fa-edit
|
||||
i.fa.fa-plus-square
|
||||
| {{_ 'new'}}
|
||||
|
||||
template(name="newUserRow")
|
||||
a.new-user
|
||||
i.fa.fa-edit
|
||||
i.fa.fa-plus-square
|
||||
| {{_ 'new'}}
|
||||
|
||||
template(name="orgRow")
|
||||
tr
|
||||
if orgData.loginDisabled
|
||||
td <s>{{ orgData.displayName }}</s>
|
||||
td <s>{{ orgData.orgDisplayName }}</s>
|
||||
else
|
||||
td {{ orgData.displayName }}
|
||||
td {{ orgData.orgDisplayName }}
|
||||
if orgData.loginDisabled
|
||||
td <s>{{ orgData.orgDesc }}</s>
|
||||
else
|
||||
td {{ orgData.desc }}
|
||||
td {{ orgData.orgDesc }}
|
||||
if orgData.loginDisabled
|
||||
td <s>{{ orgData.name }}</s>
|
||||
td <s>{{ orgData.orgName }}</s>
|
||||
else
|
||||
td {{ orgData.name }}
|
||||
td {{ orgData.orgName }}
|
||||
if orgData.loginDisabled
|
||||
td <s>{{ orgData.website }}</s>
|
||||
td <s>{{ orgData.orgWebsite }}</s>
|
||||
else
|
||||
td {{ orgData.website }}
|
||||
if orgData.loginDisabled
|
||||
td <s>{{ orgData.teams }}</s>
|
||||
else
|
||||
td {{ orgData.teams }}
|
||||
td {{ orgData.orgWebsite }}
|
||||
if orgData.loginDisabled
|
||||
td <s>{{ moment orgData.createdAt 'LLL' }}</s>
|
||||
else
|
||||
@@ -172,21 +167,21 @@ template(name="orgRow")
|
||||
template(name="teamRow")
|
||||
tr
|
||||
if teamData.loginDisabled
|
||||
td <s>{{ teamData.displayName }}</s>
|
||||
td <s>{{ teamData.teamDisplayName }}</s>
|
||||
else
|
||||
td {{ teamData.displayName }}
|
||||
td {{ teamData.teamDisplayName }}
|
||||
if teamData.loginDisabled
|
||||
td <s>{{ teamData.desc }}</s>
|
||||
td <s>{{ teamData.teamDesc }}</s>
|
||||
else
|
||||
td {{ teamData.desc }}
|
||||
td {{ teamData.teamDesc }}
|
||||
if teamData.loginDisabled
|
||||
td <s>{{ teamData.dame }}</s>
|
||||
td <s>{{ teamData.teamName }}</s>
|
||||
else
|
||||
td {{ teamData.name }}
|
||||
td {{ teamData.teamName }}
|
||||
if teamData.loginDisabled
|
||||
td <s>{{ teamData.website }}</s>
|
||||
td <s>{{ teamData.teamWebsite }}</s>
|
||||
else
|
||||
td {{ teamData.website }}
|
||||
td {{ teamData.teamWebsite }}
|
||||
if orgData.loginDisabled
|
||||
td <s>{{ moment teamData.createdAt 'LLL' }}</s>
|
||||
else
|
||||
@@ -273,19 +268,19 @@ template(name="editOrgPopup")
|
||||
form
|
||||
label.hide.orgId(type="text" value=org._id)
|
||||
label
|
||||
| {{_ 'orgDisplayName'}}
|
||||
| {{_ 'displayName'}}
|
||||
input.js-orgDisplayName(type="text" value=org.displayName required)
|
||||
span.error.hide.orgname-taken
|
||||
| {{_ 'error-orgname-taken'}}
|
||||
label
|
||||
| {{_ 'orgDesc'}}
|
||||
input.js-orgDesc(type="text" value=org.desc required)
|
||||
| {{_ 'description'}}
|
||||
input.js-orgDesc(type="text" value=org.orgDesc required)
|
||||
label
|
||||
| {{_ 'orgName'}}
|
||||
input.js-orgName(type="text" value=org.name required)
|
||||
| {{_ 'shortName'}}
|
||||
input.js-orgShortName(type="text" value=org.orgShortName required)
|
||||
label
|
||||
| {{_ 'orgWebsite'}}
|
||||
input.js-orgWebsite(type="text" value=org.website required)
|
||||
| {{_ 'website'}}
|
||||
input.js-orgWebsite(type="text" value=org.orgWebsite required)
|
||||
label
|
||||
| {{_ 'active'}}
|
||||
select.select-active.js-org-isactive
|
||||
@@ -300,18 +295,18 @@ template(name="editTeamPopup")
|
||||
label.hide.teamId(type="text" value=team._id)
|
||||
label
|
||||
| {{_ 'displayName'}}
|
||||
input.js-teamDisplayName(type="text" value=team.displayName required)
|
||||
input.js-teamDisplayName(type="text" value=team.teamDisplayName required)
|
||||
span.error.hide.teamname-taken
|
||||
| {{_ 'error-teamname-taken'}}
|
||||
label
|
||||
| {{_ 'description'}}
|
||||
input.js-orgDesc(type="text" value=org.desc required)
|
||||
input.js-teamDesc(type="text" value=team.teamDesc required)
|
||||
label
|
||||
| {{_ 'name'}}
|
||||
input.js-orgName(type="text" value=org.name required)
|
||||
| {{_ 'shortName'}}
|
||||
input.js-teamShortName(type="text" value=team.teamShortName required)
|
||||
label
|
||||
| {{_ 'website'}}
|
||||
input.js-orgWebsite(type="text" value=org.website required)
|
||||
input.js-teamWebsite(type="text" value=team.teamWebsite required)
|
||||
label
|
||||
| {{_ 'active'}}
|
||||
select.select-active.js-team-isactive
|
||||
@@ -337,7 +332,7 @@ template(name="editUserPopup")
|
||||
input.js-profile-fullname(type="text" value=user.profile.fullname required)
|
||||
label
|
||||
| {{_ 'initials'}}
|
||||
input.js-profile-initials(type="text" value=user.profile.initials)
|
||||
input.js-profile-initials(type="text" value=user.profile.initials required)
|
||||
label
|
||||
| {{_ 'admin'}}
|
||||
select.select-role.js-profile-isadmin
|
||||
@@ -384,22 +379,19 @@ template(name="newOrgPopup")
|
||||
//label.hide.userId(type="text" value=user._id)
|
||||
label
|
||||
| {{_ 'displayName'}}
|
||||
input.js-displayName(type="text" value="" required)
|
||||
input.js-orgDisplayName(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'description'}}
|
||||
input.js-desc(type="text" value="" required)
|
||||
input.js-orgDesc(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'shortName'}}
|
||||
input.js-name(type="text" value="")
|
||||
label
|
||||
| {{_ 'teams'}}
|
||||
input.js-teams(type="text" value="")
|
||||
input.js-orgName(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'website'}}
|
||||
input.js-website(type="text" value="")
|
||||
input.js-orgWebsite(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'active'}}
|
||||
select.select-active.js-profile-isactive
|
||||
select.select-active.js-org-isactive
|
||||
option(value="false" selected="selected") {{_ 'yes'}}
|
||||
option(value="true") {{_ 'no'}}
|
||||
hr
|
||||
@@ -417,13 +409,13 @@ template(name="newTeamPopup")
|
||||
input.js-teamDesc(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'shortName'}}
|
||||
input.js-teamName(type="text" value="")
|
||||
input.js-teamName(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'website'}}
|
||||
input.js-teamWebsite(type="text" value="")
|
||||
input.js-teamWebsite(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'active'}}
|
||||
select.select-active.js-profile-isactive
|
||||
select.select-active.js-team-isactive
|
||||
option(value="false" selected="selected") {{_ 'yes'}}
|
||||
option(value="true") {{_ 'no'}}
|
||||
hr
|
||||
@@ -444,6 +436,9 @@ template(name="newUserPopup")
|
||||
// input.js-profile-username(type="text" value=user.username readonly)
|
||||
//else
|
||||
input.js-profile-username(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'initials'}}
|
||||
input.js-profile-initials(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'email'}}
|
||||
span.error.hide.email-taken
|
||||
|
||||
@@ -404,6 +404,88 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
}).register('newUserRow');
|
||||
|
||||
Template.editOrgPopup.events({
|
||||
submit(event, templateInstance) {
|
||||
event.preventDefault();
|
||||
const org = Orgs.findOne(this.orgId);
|
||||
|
||||
const orgDisplayName = templateInstance
|
||||
.find('.js-orgDisplayName')
|
||||
.value.trim();
|
||||
const orgDesc = templateInstance.find('.js-orgDesc').value.trim();
|
||||
const orgShortName = templateInstance.find('.js-orgShortName').value.trim();
|
||||
const orgWebsite = templateInstance.find('.js-orgWebsite').value.trim();
|
||||
const orgIsActive = templateInstance.find('.js-org-isactive').value.trim();
|
||||
|
||||
const isChangeOrgDisplayName = orgDisplayName !== org.orgDisplayName;
|
||||
const isChangeOrgDesc = orgDesc !== org.orgDesc;
|
||||
const isChangeOrgShortName = orgShortName !== org.orgShortName;
|
||||
const isChangeOrgWebsite = orgWebsite !== org.orgWebsite;
|
||||
const isChangeOrgIsActive = orgIsActive !== org.orgIsActive;
|
||||
|
||||
if (isChangeOrgDisplayName) {
|
||||
Meteor.call('setOrgDisplayName', org, orgDisplayName);
|
||||
}
|
||||
|
||||
if (isChangeOrgDesc) {
|
||||
Meteor.call('setOrgDesc', org, orgDesc);
|
||||
}
|
||||
|
||||
if (isChangeOrgShortName) {
|
||||
Meteor.call('setOrgShortName', org, orgShortName);
|
||||
}
|
||||
|
||||
if (isChangeOrgIsActive) {
|
||||
Meteor.call('setOrgIsActive', org, orgIsActive);
|
||||
}
|
||||
|
||||
Popup.close();
|
||||
},
|
||||
});
|
||||
|
||||
Template.editTeamPopup.events({
|
||||
submit(event, templateInstance) {
|
||||
event.preventDefault();
|
||||
const team = Teams.findOne(this.teamId);
|
||||
|
||||
const teamDisplayName = templateInstance
|
||||
.find('.js-teamDisplayName')
|
||||
.value.trim();
|
||||
const teamDesc = templateInstance.find('.js-teamDesc').value.trim();
|
||||
const teamShortName = templateInstance
|
||||
.find('.js-teamShortName')
|
||||
.value.trim();
|
||||
const teamWebsite = templateInstance.find('.js-teamWebsite').value.trim();
|
||||
const teamIsActive = templateInstance
|
||||
.find('.js-team-isactive')
|
||||
.value.trim();
|
||||
|
||||
const isChangeTeamDisplayName = teamDisplayName !== team.teamDisplayName;
|
||||
const isChangeTeamDesc = teamDesc !== team.teamDesc;
|
||||
const isChangeTeamShortName = teamShortName !== team.teamShortName;
|
||||
const isChangeTeamWebsite = teamWebsite !== team.teamWebsite;
|
||||
const isChangeTeamIsActive = teamIsActive !== team.teamIsActive;
|
||||
|
||||
if (isChangeTeamDisplayName) {
|
||||
Meteor.call('setTeamDisplayName', team, teamDisplayName);
|
||||
}
|
||||
|
||||
if (isChangeTeamDesc) {
|
||||
Meteor.call('setTeamDesc', team, teamDesc);
|
||||
}
|
||||
|
||||
if (isChangeTeamShortName) {
|
||||
Meteor.call('setTeamShortName', team, teamShortName);
|
||||
}
|
||||
|
||||
if (isChangeTeamIsActive) {
|
||||
Meteor.call('setTeamIsActive', team, teamIsActive);
|
||||
}
|
||||
|
||||
Popup.close();
|
||||
},
|
||||
});
|
||||
|
||||
Template.editUserPopup.events({
|
||||
submit(event, templateInstance) {
|
||||
event.preventDefault();
|
||||
@@ -520,39 +602,48 @@ Template.editUserPopup.events({
|
||||
Template.newOrgPopup.events({
|
||||
submit(event, templateInstance) {
|
||||
event.preventDefault();
|
||||
const displayName = templateInstance.find('.js-displayName').value.trim();
|
||||
const desc = templateInstance.find('.js-desc').value.trim();
|
||||
const name = templateInstance.find('.js-name').value.trim();
|
||||
const teams = templateInstance.find('.js-teams').value.trim();
|
||||
const website = templateInstance.find('.js-website').value.trim();
|
||||
const isActive = templateInstance.find('.js-profile-isactive').value.trim();
|
||||
const orgDisplayName = templateInstance
|
||||
.find('.js-orgDisplayName')
|
||||
.value.trim();
|
||||
const orgDesc = templateInstance.find('.js-orgDesc').value.trim();
|
||||
const orgShortName = templateInstance.find('.js-orgShortName').value.trim();
|
||||
const orgWebsite = templateInstance.find('.js-orgWebsite').value.trim();
|
||||
const orgIsActive = templateInstance.find('.js-org-isactive').value.trim();
|
||||
|
||||
Meteor.call(
|
||||
'setCreateOrg',
|
||||
displayName,
|
||||
desc,
|
||||
name,
|
||||
teams,
|
||||
website,
|
||||
isActive,
|
||||
email.toLowerCase(),
|
||||
function(error) {
|
||||
const nameMessageElement = templateInstance.$('.name-taken');
|
||||
if (error) {
|
||||
const errorElement = error.error;
|
||||
if (errorElement === 'name-already-taken') {
|
||||
nameMessageElement.show();
|
||||
emailMessageElement.hide();
|
||||
} else if (errorElement === 'email-already-taken') {
|
||||
usernameMessageElement.hide();
|
||||
emailMessageElement.show();
|
||||
}
|
||||
} else {
|
||||
usernameMessageElement.hide();
|
||||
emailMessageElement.hide();
|
||||
Popup.close();
|
||||
}
|
||||
},
|
||||
orgDisplayName,
|
||||
orgDesc,
|
||||
orgShortName,
|
||||
orgWebsite,
|
||||
orgIsActive,
|
||||
);
|
||||
Popup.close();
|
||||
},
|
||||
});
|
||||
|
||||
Template.newTeamPopup.events({
|
||||
submit(event, templateInstance) {
|
||||
event.preventDefault();
|
||||
const teamDisplayName = templateInstance
|
||||
.find('.js-teamDisplayName')
|
||||
.value.trim();
|
||||
const teamDesc = templateInstance.find('.js-teamDesc').value.trim();
|
||||
const teamShortName = templateInstance
|
||||
.find('.js-teamShortName')
|
||||
.value.trim();
|
||||
const teamWebsite = templateInstance.find('.js-teamWebsite').value.trim();
|
||||
const teamIsActive = templateInstance
|
||||
.find('.js-team-isactive')
|
||||
.value.trim();
|
||||
|
||||
Meteor.call(
|
||||
'setCreateTeam',
|
||||
teamDisplayName,
|
||||
teamDesc,
|
||||
teamShortName,
|
||||
teamWebsite,
|
||||
teamIsActive,
|
||||
);
|
||||
Popup.close();
|
||||
},
|
||||
@@ -563,18 +654,20 @@ Template.newUserPopup.events({
|
||||
event.preventDefault();
|
||||
const fullname = templateInstance.find('.js-profile-fullname').value.trim();
|
||||
const username = templateInstance.find('.js-profile-username').value.trim();
|
||||
const initials = templateInstance.find('.js-profile-initials').value.trim();
|
||||
const password = templateInstance.find('.js-profile-password').value;
|
||||
const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
|
||||
const isActive = templateInstance.find('.js-profile-isactive').value.trim();
|
||||
const email = templateInstance.find('.js-profile-email').value.trim();
|
||||
const importUsernames = templateInstance
|
||||
.find('.js-import-usernames')
|
||||
.value.trim();
|
||||
const importUsernames = Users.parseImportUsernames(
|
||||
templateInstance.find('.js-import-usernames').value,
|
||||
);
|
||||
|
||||
Meteor.call(
|
||||
'setCreateUser',
|
||||
fullname,
|
||||
username,
|
||||
initials,
|
||||
password,
|
||||
isAdmin,
|
||||
isActive,
|
||||
|
||||
@@ -13,10 +13,11 @@ template(name="setting")
|
||||
a.js-setting-menu(data-id="registration-setting")
|
||||
i.fa.fa-sign-in
|
||||
| {{_ 'registration'}}
|
||||
li
|
||||
a.js-setting-menu(data-id="email-setting")
|
||||
i.fa.fa-envelope
|
||||
| {{_ 'email'}}
|
||||
unless isSandstorm
|
||||
li
|
||||
a.js-setting-menu(data-id="email-setting")
|
||||
i.fa.fa-envelope
|
||||
| {{_ 'email'}}
|
||||
li
|
||||
a.js-setting-menu(data-id="account-setting")
|
||||
i.fa.fa-users
|
||||
@@ -39,7 +40,8 @@ template(name="setting")
|
||||
else if generalSetting.get
|
||||
+general
|
||||
else if emailSetting.get
|
||||
+email
|
||||
unless isSandstorm
|
||||
+email
|
||||
else if accountSetting.get
|
||||
+accountSettings
|
||||
else if announcementSetting.get
|
||||
@@ -80,45 +82,48 @@ template(name="general")
|
||||
|
||||
template(name='email')
|
||||
ul#email-setting.setting-detail
|
||||
li.smtp-form
|
||||
.title {{_ 'smtp-host'}}
|
||||
.description {{_ 'smtp-host-description'}}
|
||||
.form-group
|
||||
input.wekan-form-control#mail-server-host(type="text", placeholder="smtp.domain.com" value="{{currentSetting.mailServer.host}}")
|
||||
li.smtp-form
|
||||
.title {{_ 'smtp-port'}}
|
||||
.description {{_ 'smtp-port-description'}}
|
||||
.form-group
|
||||
input.wekan-form-control#mail-server-port(type="text", placeholder="25" value="{{currentSetting.mailServer.port}}")
|
||||
li.smtp-form
|
||||
.title {{_ 'smtp-username'}}
|
||||
.form-group
|
||||
input.wekan-form-control#mail-server-username(type="text", placeholder="{{_ 'username'}}" value="{{currentSetting.mailServer.username}}")
|
||||
li.smtp-form
|
||||
.title {{_ 'smtp-password'}}
|
||||
.form-group
|
||||
input.wekan-form-control#mail-server-password(type="password", placeholder="{{_ 'password'}}" value="{{currentSetting.mailServer.password}}")
|
||||
li.smtp-form
|
||||
.title {{_ 'smtp-tls'}}
|
||||
.form-group
|
||||
a.flex.js-toggle-tls
|
||||
.materialCheckBox#mail-server-tls(class="{{#if currentSetting.mailServer.enableTLS}}is-checked{{/if}}")
|
||||
|
||||
span {{_ 'smtp-tls-description'}}
|
||||
|
||||
li.smtp-form
|
||||
.title {{_ 'send-from'}}
|
||||
.form-group
|
||||
input.wekan-form-control#mail-server-from(type="email", placeholder="no-reply@domain.com" value="{{currentSetting.mailServer.from}}")
|
||||
|
||||
li
|
||||
button.js-save.primary {{_ 'save'}}
|
||||
//if isSandstorm
|
||||
// li.smtp-form
|
||||
// .title {{_ 'smtp-host'}}
|
||||
// .description {{_ 'smtp-host-description'}}
|
||||
// .form-group
|
||||
// input.wekan-form-control#mail-server-host(type="text", placeholder="smtp.domain.com" value="{{currentSetting.mailServer.host}}")
|
||||
// li.smtp-form
|
||||
// .title {{_ 'smtp-port'}}
|
||||
// .description {{_ 'smtp-port-description'}}
|
||||
// .form-group
|
||||
// input.wekan-form-control#mail-server-port(type="text", placeholder="25" value="{{currentSetting.mailServer.port}}")
|
||||
// li.smtp-form
|
||||
// .title {{_ 'smtp-username'}}
|
||||
// .form-group
|
||||
// input.wekan-form-control#mail-server-username(type="text", placeholder="{{_ 'username'}}" value="{{currentSetting.mailServer.username}}")
|
||||
// li.smtp-form
|
||||
// .title {{_ 'smtp-password'}}
|
||||
// .form-group
|
||||
// input.wekan-form-control#mail-server-password(type="password", placeholder="{{_ 'password'}}" value="")
|
||||
// li.smtp-form
|
||||
// .title {{_ 'smtp-tls'}}
|
||||
// .form-group
|
||||
// a.flex.js-toggle-tls
|
||||
// .materialCheckBox#mail-server-tls(class="{{#if currentSetting.mailServer.enableTLS}}is-checked{{/if}}")
|
||||
//
|
||||
// span {{_ 'smtp-tls-description'}}
|
||||
//
|
||||
// li.smtp-form
|
||||
// .title {{_ 'send-from'}}
|
||||
// .form-group
|
||||
// input.wekan-form-control#mail-server-from(type="email", placeholder="no-reply@domain.com" value="{{currentSetting.mailServer.from}}")
|
||||
//
|
||||
// li
|
||||
// button.js-save.primary {{_ 'save'}}
|
||||
|
||||
li
|
||||
button.js-send-smtp-test-email.primary {{_ 'send-smtp-test'}}
|
||||
|
||||
template(name='accountSettings')
|
||||
ul#account-setting.setting-detail
|
||||
li
|
||||
button.js-all-hide-system-messages.primary {{_ 'hide-system-messages-of-all-users'}}
|
||||
li.accounts-form
|
||||
.title {{_ 'accounts-allowEmailChange'}}
|
||||
.form-group.flex
|
||||
@@ -126,23 +131,18 @@ template(name='accountSettings')
|
||||
span {{_ 'yes'}}
|
||||
input.wekan-form-control#accounts-allowEmailChange(type="radio" name="allowEmailChange" value="false" checked="{{#unless allowEmailChange}}checked{{/unless}}")
|
||||
span {{_ 'no'}}
|
||||
li
|
||||
li.accounts-form
|
||||
.title {{_ 'accounts-allowUserNameChange'}}
|
||||
.form-group.flex
|
||||
input.wekan-form-control#accounts-allowUserNameChange(type="radio" name="allowUserNameChange" value="true" checked="{{#if allowUserNameChange}}checked{{/if}}")
|
||||
span {{_ 'yes'}}
|
||||
input.wekan-form-control#accounts-allowUserNameChange(type="radio" name="allowUserNameChange" value="false" checked="{{#unless allowUserNameChange}}checked{{/unless}}")
|
||||
span {{_ 'no'}}
|
||||
li
|
||||
li.accounts-form
|
||||
.title {{_ 'accounts-allowUserDelete'}}
|
||||
.form-group.flex
|
||||
input.wekan-form-control#accounts-allowUserDelete(type="radio" name="allowUserDelete" value="true" checked="{{#if allowUserDelete}}checked{{/if}}")
|
||||
span {{_ 'yes'}}
|
||||
input.wekan-form-control#accounts-allowUserDelete(type="radio" name="allowUserDelete" value="false" checked="{{#unless allowUserDelete}}checked{{/unless}}")
|
||||
span {{_ 'no'}}
|
||||
li
|
||||
button.js-accounts-save.primary {{_ 'save'}}
|
||||
|
||||
template(name='announcementSettings')
|
||||
@@ -208,6 +208,10 @@ template(name='layoutSettings')
|
||||
.title {{_ 'custom-top-left-corner-logo-height'}}
|
||||
.form-group
|
||||
input.wekan-form-control#custom-top-left-corner-logo-height(type="text", placeholder="" value="{{currentSetting.customTopLeftCornerLogoHeight}}")
|
||||
li.layout-form
|
||||
.title {{_ 'automatic-linked-url-schemes'}}
|
||||
.form-group
|
||||
textarea#automatic-linked-url-schemes.wekan-form-control= currentSetting.automaticLinkedUrlSchemes
|
||||
li
|
||||
button.js-save-layout.primary {{_ 'save'}}
|
||||
|
||||
|
||||
@@ -176,6 +176,9 @@ BlazeComponent.extendComponent({
|
||||
const textBelowCustomLoginLogo = $('#text-below-custom-login-logo')
|
||||
.val()
|
||||
.trim();
|
||||
const automaticLinkedUrlSchemes = $('#automatic-linked-url-schemes')
|
||||
.val()
|
||||
.trim();
|
||||
const customTopLeftCornerLogoImageUrl = $(
|
||||
'#custom-top-left-corner-logo-image-url',
|
||||
)
|
||||
@@ -209,6 +212,7 @@ BlazeComponent.extendComponent({
|
||||
customTopLeftCornerLogoHeight,
|
||||
displayAuthenticationMethod,
|
||||
defaultAuthenticationMethod,
|
||||
automaticLinkedUrlSchemes,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
@@ -270,7 +274,6 @@ BlazeComponent.extendComponent({
|
||||
$set: { booleanValue: allowUserDelete },
|
||||
});
|
||||
},
|
||||
|
||||
allowEmailChange() {
|
||||
return AccountSettings.findOne('accounts-allowEmailChange').booleanValue;
|
||||
},
|
||||
@@ -280,12 +283,31 @@ BlazeComponent.extendComponent({
|
||||
allowUserDelete() {
|
||||
return AccountSettings.findOne('accounts-allowUserDelete').booleanValue;
|
||||
},
|
||||
allHideSystemMessages() {
|
||||
Meteor.call('setAllUsersHideSystemMessages', (err, ret) => {
|
||||
if (!err && ret) {
|
||||
if (ret === true) {
|
||||
const message = `${TAPi18n.__(
|
||||
'now-system-messages-of-all-users-are-hidden',
|
||||
)}`;
|
||||
alert(message);
|
||||
}
|
||||
} else {
|
||||
const reason = err.reason || '';
|
||||
const message = `${TAPi18n.__(err.error)}\n${reason}`;
|
||||
alert(message);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click button.js-accounts-save': this.saveAccountsChange,
|
||||
},
|
||||
{
|
||||
'click button.js-all-hide-system-messages': this.allHideSystemMessages,
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('accountSettings');
|
||||
|
||||
@@ -31,30 +31,39 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
|
||||
archivedCards() {
|
||||
return Cards.find({
|
||||
archived: true,
|
||||
boardId: Session.get('currentBoard'),
|
||||
}, {
|
||||
sort: { archivedAt: -1, modifiedAt: -1 },
|
||||
});
|
||||
return Cards.find(
|
||||
{
|
||||
archived: true,
|
||||
boardId: Session.get('currentBoard'),
|
||||
},
|
||||
{
|
||||
sort: { archivedAt: -1, modifiedAt: -1 },
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
archivedLists() {
|
||||
return Lists.find({
|
||||
archived: true,
|
||||
boardId: Session.get('currentBoard'),
|
||||
}, {
|
||||
sort: { archivedAt: -1, modifiedAt: -1 },
|
||||
});
|
||||
return Lists.find(
|
||||
{
|
||||
archived: true,
|
||||
boardId: Session.get('currentBoard'),
|
||||
},
|
||||
{
|
||||
sort: { archivedAt: -1, modifiedAt: -1 },
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
archivedSwimlanes() {
|
||||
return Swimlanes.find({
|
||||
archived: true,
|
||||
boardId: Session.get('currentBoard'),
|
||||
}, {
|
||||
sort: { archivedAt: -1, modifiedAt: -1 },
|
||||
});
|
||||
return Swimlanes.find(
|
||||
{
|
||||
archived: true,
|
||||
boardId: Session.get('currentBoard'),
|
||||
},
|
||||
{
|
||||
sort: { archivedAt: -1, modifiedAt: -1 },
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
cardIsInArchivedList() {
|
||||
|
||||
@@ -4,9 +4,9 @@ template(name="searchSidebar")
|
||||
.list-body
|
||||
.minilists.clearfix.js-minilists
|
||||
each (lists)
|
||||
a.minilist-wrapper.js-minilist(href=absoluteUrl)
|
||||
a.minilist-wrapper.js-minilist(href=originRelativeUrl)
|
||||
+minilist(this)
|
||||
.minicards.clearfix.js-minicards
|
||||
each (results)
|
||||
a.minicard-wrapper.js-minicard(href=absoluteUrl)
|
||||
a.minicard-wrapper.js-minicard(href=originRelativeUrl)
|
||||
+minicard(this)
|
||||
@@ -39,6 +39,8 @@ template(name="swimlaneActionPopup")
|
||||
hr
|
||||
ul.pop-over-list
|
||||
li: a.js-close-swimlane {{_ 'archive-swimlane'}}
|
||||
ul.pop-over-list
|
||||
li: a.js-move-swimlane {{_ 'move-swimlane'}}
|
||||
|
||||
template(name="swimlaneAddPopup")
|
||||
unless currentUser.isCommentOnly
|
||||
|
||||
@@ -54,9 +54,10 @@ Template.swimlaneActionPopup.events({
|
||||
this.archive();
|
||||
Popup.close();
|
||||
},
|
||||
'click .js-move-swimlane': Popup.open('moveSwimlane'),
|
||||
});
|
||||
|
||||
Template.swimlaneActionPopup.helpers({
|
||||
Template.swimlaneActionPopup.events({
|
||||
isCommentOnly() {
|
||||
return Meteor.user().isCommentOnly();
|
||||
},
|
||||
|
||||
@@ -61,3 +61,13 @@ template(name="addListForm")
|
||||
a.open-list-composer.js-open-inlined-form
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-list'}}
|
||||
|
||||
template(name="moveSwimlanePopup")
|
||||
unless currentUser.isWorker
|
||||
label {{_ 'boards'}}:
|
||||
select.js-select-boards(autofocus)
|
||||
each toBoard in toBoards
|
||||
option(value="{{toBoard._id}}") {{toBoard.title}}
|
||||
|
||||
.edit-controls.clearfix
|
||||
button.primary.confirm.js-done {{_ 'done'}}
|
||||
@@ -323,3 +323,46 @@ BlazeComponent.extendComponent({
|
||||
initSortable(boardComponent, $listsDom);
|
||||
},
|
||||
}).register('listsGroup');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.currentSwimlane = this.currentData();
|
||||
},
|
||||
|
||||
board() {
|
||||
return Boards.findOne(Session.get('currentBoard'));
|
||||
},
|
||||
|
||||
toBoards() {
|
||||
const boards = Boards.find(
|
||||
{
|
||||
archived: false,
|
||||
'members.userId': Meteor.userId(),
|
||||
type: 'board',
|
||||
_id: { $ne: this.board()._id },
|
||||
},
|
||||
{
|
||||
sort: { title: 1 },
|
||||
},
|
||||
);
|
||||
|
||||
return boards;
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-done'() {
|
||||
const swimlane = Swimlanes.findOne(this.currentSwimlane._id);
|
||||
const bSelect = $('.js-select-boards')[0];
|
||||
let boardId;
|
||||
if (bSelect) {
|
||||
boardId = bSelect.options[bSelect.selectedIndex].value;
|
||||
Meteor.call('moveSwimlane', this.currentSwimlane._id, boardId);
|
||||
}
|
||||
Popup.close();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('moveSwimlanePopup');
|
||||
@@ -9,7 +9,6 @@ avatar-radius = 50%
|
||||
float: left
|
||||
height: 30px
|
||||
width: @height
|
||||
margin: 0 4px 4px 0
|
||||
cursor: pointer
|
||||
user-select: none
|
||||
z-index: 1
|
||||
|
||||
@@ -143,7 +143,7 @@ template(name="changeSettingsPopup")
|
||||
label.bold.clear
|
||||
i.fa.fa-sort-numeric-asc
|
||||
| {{_ 'show-cards-minimum-count'}}
|
||||
input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false")
|
||||
input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="-1")
|
||||
label.bold.clear
|
||||
i.fa.fa-calendar
|
||||
| {{_ 'start-day-of-week'}}
|
||||
|
||||
@@ -168,10 +168,32 @@ Template.changeLanguagePopup.helpers({
|
||||
let name = lang.name;
|
||||
if (lang.name === 'br') {
|
||||
name = 'Brezhoneg';
|
||||
} else if (lang.name === 'ar-EG') {
|
||||
// ar-EG = Arabic (Egypt), simply Masri (مَصرى, [ˈmɑsˤɾi], Egyptian, Masr refers to Cairo)
|
||||
name = 'مَصرى';
|
||||
} else if (lang.name === 'fa-IR') {
|
||||
// fa-IR = Persian (Iran)
|
||||
name = 'فارسی/پارسی (ایران)';
|
||||
} else if (lang.name === 'fr-BE') {
|
||||
name = 'Français (Belgique)';
|
||||
} else if (lang.name === 'fr-CA') {
|
||||
name = 'Français (Canada)';
|
||||
} else if (lang.name === 'ig') {
|
||||
name = 'Igbo';
|
||||
} else if (lang.name === 'lv') {
|
||||
name = 'Latviešu';
|
||||
} else if (lang.name === 'latviešu valoda') {
|
||||
name = 'Latviešu';
|
||||
} else if (lang.name === 'Español') {
|
||||
name = 'español';
|
||||
} else if (lang.name === 'es_419') {
|
||||
name = 'español de América Latina';
|
||||
} else if (lang.name === 'es-419') {
|
||||
name = 'español de América Latina';
|
||||
} else if (lang.name === 'Español de América Latina') {
|
||||
name = 'español de América Latina';
|
||||
} else if (lang.name === 'es-LA') {
|
||||
name = 'español de América Latina';
|
||||
} else if (lang.name === 'Español de Argentina') {
|
||||
name = 'español de Argentina';
|
||||
} else if (lang.name === 'Español de Chile') {
|
||||
@@ -182,12 +204,16 @@ Template.changeLanguagePopup.helpers({
|
||||
name = 'español de México';
|
||||
} else if (lang.name === 'es-PY') {
|
||||
name = 'español de Paraguayo';
|
||||
} else if (lang.name === 'Español de Paraguayo') {
|
||||
name = 'español de Paraguayo';
|
||||
} else if (lang.name === 'Español de Perú') {
|
||||
name = 'español de Perú';
|
||||
} else if (lang.name === 'Español de Puerto Rico') {
|
||||
name = 'español de Puerto Rico';
|
||||
} else if (lang.name === 'oc') {
|
||||
name = 'Occitan';
|
||||
} else if (lang.name === 'st') {
|
||||
name = 'Sãotomense';
|
||||
} else if (lang.name === '繁体中文(台湾)') {
|
||||
name = '繁體中文(台灣)';
|
||||
}
|
||||
@@ -213,6 +239,7 @@ Template.changeLanguagePopup.events({
|
||||
'profile.language': this.tag,
|
||||
},
|
||||
});
|
||||
TAPi18n.setLanguage(this.tag);
|
||||
event.preventDefault();
|
||||
},
|
||||
});
|
||||
@@ -270,6 +297,13 @@ Template.changeSettingsPopup.helpers({
|
||||
});
|
||||
|
||||
Template.changeSettingsPopup.events({
|
||||
'keypress/paste #show-cards-count-at'() {
|
||||
let keyCode = event.keyCode;
|
||||
let charCode = String.fromCharCode(keyCode);
|
||||
let regex = new RegExp('[-0-9]');
|
||||
let ret = regex.test(charCode);
|
||||
return ret;
|
||||
},
|
||||
'click .js-toggle-desktop-drag-handles'() {
|
||||
currentUser = Meteor.user();
|
||||
if (currentUser) {
|
||||
@@ -292,7 +326,7 @@ Template.changeSettingsPopup.events({
|
||||
},
|
||||
'click .js-apply-user-settings'(event, templateInstance) {
|
||||
event.preventDefault();
|
||||
const minLimit = parseInt(
|
||||
let minLimit = parseInt(
|
||||
templateInstance.$('#show-cards-count-at').val(),
|
||||
10,
|
||||
);
|
||||
@@ -301,6 +335,9 @@ Template.changeSettingsPopup.events({
|
||||
10,
|
||||
);
|
||||
const currentUser = Meteor.user();
|
||||
if (isNaN(minLimit) || minLimit < -1) {
|
||||
minLimit = -1;
|
||||
}
|
||||
if (!isNaN(minLimit)) {
|
||||
if (currentUser) {
|
||||
Meteor.call('changeLimitToShowCardsCount', minLimit);
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
import Cards from '../../models/cards';
|
||||
import SessionData from '../../models/usersessiondata';
|
||||
|
||||
export class CardSearchPagedComponent extends BlazeComponent {
|
||||
onCreated() {
|
||||
this.searching = new ReactiveVar(false);
|
||||
this.hasResults = new ReactiveVar(false);
|
||||
this.hasQueryErrors = new ReactiveVar(false);
|
||||
this.query = new ReactiveVar('');
|
||||
this.resultsHeading = new ReactiveVar('');
|
||||
this.searchLink = new ReactiveVar(null);
|
||||
this.results = new ReactiveVar([]);
|
||||
this.hasNextPage = new ReactiveVar(false);
|
||||
this.hasPreviousPage = new ReactiveVar(false);
|
||||
this.resultsCount = 0;
|
||||
this.totalHits = 0;
|
||||
this.queryErrors = null;
|
||||
this.resultsPerPage = 25;
|
||||
this.sessionId = SessionData.getSessionId();
|
||||
this.subscriptionHandle = null;
|
||||
this.serverError = new ReactiveVar(false);
|
||||
|
||||
const that = this;
|
||||
this.subscriptionCallbacks = {
|
||||
onReady() {
|
||||
that.getResults();
|
||||
that.searching.set(false);
|
||||
that.hasResults.set(true);
|
||||
that.serverError.set(false);
|
||||
},
|
||||
onError(error) {
|
||||
that.searching.set(false);
|
||||
that.hasResults.set(false);
|
||||
that.serverError.set(true);
|
||||
console.log('Error.reason:', error.reason);
|
||||
console.log('Error.message:', error.message);
|
||||
console.log('Error.stack:', error.stack);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
resetSearch() {
|
||||
this.searching.set(false);
|
||||
this.results.set([]);
|
||||
this.hasResults.set(false);
|
||||
this.hasQueryErrors.set(false);
|
||||
this.resultsHeading.set('');
|
||||
this.serverError.set(false);
|
||||
this.resultsCount = 0;
|
||||
this.totalHits = 0;
|
||||
this.queryErrors = null;
|
||||
}
|
||||
|
||||
getSessionData(sessionId) {
|
||||
return SessionData.findOne({
|
||||
sessionId: sessionId ? sessionId : SessionData.getSessionId(),
|
||||
});
|
||||
}
|
||||
|
||||
getResults() {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('getting results');
|
||||
const sessionData = this.getSessionData();
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('selector:', sessionData.getSelector());
|
||||
console.log('session data:', sessionData);
|
||||
const cards = [];
|
||||
sessionData.cards.forEach(cardId => {
|
||||
cards.push(Cards.findOne({ _id: cardId }));
|
||||
});
|
||||
this.queryErrors = sessionData.errors;
|
||||
if (this.queryErrors.length) {
|
||||
// console.log('queryErrors:', this.queryErrorMessages());
|
||||
this.hasQueryErrors.set(true);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (cards) {
|
||||
this.totalHits = sessionData.totalHits;
|
||||
this.resultsCount = cards.length;
|
||||
this.resultsStart = sessionData.lastHit - this.resultsCount + 1;
|
||||
this.resultsEnd = sessionData.lastHit;
|
||||
this.resultsHeading.set(this.getResultsHeading());
|
||||
this.results.set(cards);
|
||||
this.hasNextPage.set(sessionData.lastHit < sessionData.totalHits);
|
||||
this.hasPreviousPage.set(
|
||||
sessionData.lastHit - sessionData.resultsCount > 0,
|
||||
);
|
||||
return cards;
|
||||
}
|
||||
|
||||
this.resultsCount = 0;
|
||||
return null;
|
||||
}
|
||||
|
||||
stopSubscription() {
|
||||
if (this.subscriptionHandle) {
|
||||
this.subscriptionHandle.stop();
|
||||
}
|
||||
}
|
||||
|
||||
runGlobalSearch(queryParams) {
|
||||
this.searching.set(true);
|
||||
this.stopSubscription();
|
||||
this.subscriptionHandle = Meteor.subscribe(
|
||||
'globalSearch',
|
||||
this.sessionId,
|
||||
queryParams.params,
|
||||
queryParams.text,
|
||||
this.subscriptionCallbacks,
|
||||
);
|
||||
}
|
||||
|
||||
queryErrorMessages() {
|
||||
const messages = [];
|
||||
|
||||
this.queryErrors.forEach(err => {
|
||||
let value = err.color ? TAPi18n.__(`color-${err.value}`) : err.value;
|
||||
if (!value) {
|
||||
value = err.value;
|
||||
}
|
||||
messages.push(TAPi18n.__(err.tag, value));
|
||||
});
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
nextPage() {
|
||||
this.searching.set(true);
|
||||
this.stopSubscription();
|
||||
this.subscriptionHandle = Meteor.subscribe(
|
||||
'nextPage',
|
||||
this.sessionId,
|
||||
this.subscriptionCallbacks,
|
||||
);
|
||||
}
|
||||
|
||||
previousPage() {
|
||||
this.searching.set(true);
|
||||
this.stopSubscription();
|
||||
this.subscriptionHandle = Meteor.subscribe(
|
||||
'previousPage',
|
||||
this.sessionId,
|
||||
this.subscriptionCallbacks,
|
||||
);
|
||||
}
|
||||
|
||||
getResultsHeading() {
|
||||
if (this.resultsCount === 0) {
|
||||
return TAPi18n.__('no-cards-found');
|
||||
} else if (this.resultsCount === 1) {
|
||||
return TAPi18n.__('one-card-found');
|
||||
} else if (this.resultsCount === this.totalHits) {
|
||||
return TAPi18n.__('n-cards-found', this.resultsCount);
|
||||
}
|
||||
|
||||
return TAPi18n.__('n-n-of-n-cards-found', {
|
||||
start: this.resultsStart,
|
||||
end: this.resultsEnd,
|
||||
total: this.totalHits,
|
||||
});
|
||||
}
|
||||
|
||||
getSearchHref() {
|
||||
const baseUrl = window.location.href.replace(/([?#].*$|\s*$)/, '');
|
||||
return `${baseUrl}?q=${encodeURIComponent(this.query.get())}`;
|
||||
}
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-next-page'(evt) {
|
||||
evt.preventDefault();
|
||||
this.nextPage();
|
||||
},
|
||||
'click .js-previous-page'(evt) {
|
||||
evt.preventDefault();
|
||||
this.previousPage();
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,11 @@
|
||||
// Helper function to replace HH with H for 24 hours format, because H allows also single-digit hours
|
||||
function adjustedTimeFormat() {
|
||||
return moment
|
||||
.localeData()
|
||||
.longDateFormat('LT')
|
||||
.replace(/HH/i, 'H');
|
||||
}
|
||||
|
||||
DatePicker = BlazeComponent.extendComponent({
|
||||
template() {
|
||||
return 'datepicker';
|
||||
@@ -77,7 +85,11 @@ DatePicker = BlazeComponent.extendComponent({
|
||||
},
|
||||
'keyup .js-time-field'() {
|
||||
// parse for localized time format in strict mode
|
||||
const dateMoment = moment(this.find('#time').value, 'LT', true);
|
||||
const dateMoment = moment(
|
||||
this.find('#time').value,
|
||||
adjustedTimeFormat(),
|
||||
true,
|
||||
);
|
||||
if (dateMoment.isValid()) {
|
||||
this.error.set('');
|
||||
}
|
||||
@@ -89,16 +101,30 @@ DatePicker = BlazeComponent.extendComponent({
|
||||
const time =
|
||||
evt.target.time.value ||
|
||||
moment(new Date().setHours(12, 0, 0)).format('LT');
|
||||
|
||||
const newTime = moment(time, adjustedTimeFormat(), true);
|
||||
const newDate = moment(evt.target.date.value, 'L', true);
|
||||
const dateString = `${evt.target.date.value} ${time}`;
|
||||
const newDate = moment(dateString, 'L LT', true);
|
||||
if (newDate.isValid()) {
|
||||
this._storeDate(newDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
const newCompleteDate = moment(
|
||||
dateString,
|
||||
'L ' + adjustedTimeFormat(),
|
||||
true,
|
||||
);
|
||||
if (!newTime.isValid()) {
|
||||
this.error.set('invalid-time');
|
||||
evt.target.time.focus();
|
||||
}
|
||||
if (!newDate.isValid()) {
|
||||
this.error.set('invalid-date');
|
||||
evt.target.date.focus();
|
||||
}
|
||||
if (newCompleteDate.isValid()) {
|
||||
this._storeDate(newCompleteDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
if (!this.error) {
|
||||
this.error.set('invalid');
|
||||
}
|
||||
}
|
||||
},
|
||||
'click .js-delete-date'(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
+1
-1
@@ -50,5 +50,5 @@ EscapeActions.register(
|
||||
'modalWindow',
|
||||
() => Modal.close(),
|
||||
() => Modal.isOpen(),
|
||||
{ noClickEscapeOn: '.modal-container' },
|
||||
{ noClickEscapeOn: '.modal-container,.model-content' },
|
||||
);
|
||||
@@ -0,0 +1,506 @@
|
||||
import {
|
||||
OPERATOR_ASSIGNEE,
|
||||
OPERATOR_BOARD,
|
||||
OPERATOR_COMMENT,
|
||||
OPERATOR_CREATED_AT,
|
||||
OPERATOR_DUE,
|
||||
OPERATOR_HAS,
|
||||
OPERATOR_LABEL,
|
||||
OPERATOR_LIMIT,
|
||||
OPERATOR_LIST,
|
||||
OPERATOR_MEMBER,
|
||||
OPERATOR_MODIFIED_AT,
|
||||
OPERATOR_SORT,
|
||||
OPERATOR_STATUS,
|
||||
OPERATOR_SWIMLANE,
|
||||
OPERATOR_UNKNOWN,
|
||||
OPERATOR_USER,
|
||||
ORDER_ASCENDING,
|
||||
ORDER_DESCENDING,
|
||||
PREDICATE_ALL,
|
||||
PREDICATE_ARCHIVED,
|
||||
PREDICATE_ASSIGNEES,
|
||||
PREDICATE_ATTACHMENT,
|
||||
PREDICATE_CHECKLIST,
|
||||
PREDICATE_CREATED_AT,
|
||||
PREDICATE_DESCRIPTION,
|
||||
PREDICATE_DUE_AT,
|
||||
PREDICATE_END_AT,
|
||||
PREDICATE_ENDED,
|
||||
PREDICATE_MEMBERS,
|
||||
PREDICATE_MODIFIED_AT,
|
||||
PREDICATE_MONTH,
|
||||
PREDICATE_OPEN,
|
||||
PREDICATE_OVERDUE,
|
||||
PREDICATE_PRIVATE,
|
||||
PREDICATE_PUBLIC,
|
||||
PREDICATE_QUARTER,
|
||||
PREDICATE_START_AT,
|
||||
PREDICATE_WEEK,
|
||||
PREDICATE_YEAR,
|
||||
} from './search-const';
|
||||
import Boards from '../models/boards';
|
||||
import moment from 'moment';
|
||||
|
||||
export class QueryParams {
|
||||
text = '';
|
||||
|
||||
constructor(params = {}, text = '') {
|
||||
this.params = params;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
hasOperator(operator) {
|
||||
return (
|
||||
this.params[operator] !== undefined && this.params[operator].length > 0
|
||||
);
|
||||
}
|
||||
|
||||
addPredicate(operator, predicate) {
|
||||
if (!this.hasOperator(operator)) {
|
||||
this.params[operator] = [];
|
||||
}
|
||||
this.params[operator].push(predicate);
|
||||
}
|
||||
|
||||
setPredicate(operator, predicate) {
|
||||
this.params[operator] = predicate;
|
||||
}
|
||||
|
||||
getPredicate(operator) {
|
||||
return this.params[operator][0];
|
||||
}
|
||||
|
||||
getPredicates(operator) {
|
||||
return this.params[operator];
|
||||
}
|
||||
|
||||
getParams() {
|
||||
return this.params;
|
||||
}
|
||||
}
|
||||
|
||||
export class QueryErrors {
|
||||
operatorTagMap = [
|
||||
[OPERATOR_BOARD, 'board-title-not-found'],
|
||||
[OPERATOR_SWIMLANE, 'swimlane-title-not-found'],
|
||||
[
|
||||
OPERATOR_LABEL,
|
||||
label => {
|
||||
if (Boards.labelColors().includes(label)) {
|
||||
return {
|
||||
tag: 'label-color-not-found',
|
||||
value: label,
|
||||
color: true,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
tag: 'label-not-found',
|
||||
value: label,
|
||||
color: false,
|
||||
};
|
||||
}
|
||||
},
|
||||
],
|
||||
[OPERATOR_LIST, 'list-title-not-found'],
|
||||
[OPERATOR_COMMENT, 'comment-not-found'],
|
||||
[OPERATOR_USER, 'user-username-not-found'],
|
||||
[OPERATOR_ASSIGNEE, 'user-username-not-found'],
|
||||
[OPERATOR_MEMBER, 'user-username-not-found'],
|
||||
];
|
||||
|
||||
constructor() {
|
||||
this._errors = {};
|
||||
|
||||
this.operatorTags = {};
|
||||
this.operatorTagMap.forEach(([operator, tag]) => {
|
||||
this.operatorTags[operator] = tag;
|
||||
});
|
||||
|
||||
this.colorMap = Boards.colorMap();
|
||||
}
|
||||
|
||||
addError(operator, error) {
|
||||
if (!this._errors[operator]) {
|
||||
this._errors[operator] = [];
|
||||
}
|
||||
this._errors[operator].push(error);
|
||||
}
|
||||
|
||||
addNotFound(operator, value) {
|
||||
if (typeof this.operatorTags[operator] === 'function') {
|
||||
this.addError(operator, this.operatorTags[operator](value));
|
||||
} else {
|
||||
this.addError(operator, { tag: this.operatorTags[operator], value });
|
||||
}
|
||||
}
|
||||
|
||||
hasErrors() {
|
||||
return Object.entries(this._errors).length > 0;
|
||||
}
|
||||
|
||||
errors() {
|
||||
const errs = [];
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
Object.entries(this._errors).forEach(([, errors]) => {
|
||||
errors.forEach(err => {
|
||||
errs.push(err);
|
||||
});
|
||||
});
|
||||
return errs;
|
||||
}
|
||||
|
||||
errorMessages() {
|
||||
const messages = [];
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
Object.entries(this._errors).forEach(([, errors]) => {
|
||||
errors.forEach(err => {
|
||||
messages.push(TAPi18n.__(err.tag, err.value));
|
||||
});
|
||||
});
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
|
||||
export class Query {
|
||||
selector = {};
|
||||
projection = {};
|
||||
|
||||
constructor(selector, projection) {
|
||||
this._errors = new QueryErrors();
|
||||
this.queryParams = new QueryParams();
|
||||
this.colorMap = Boards.colorMap();
|
||||
|
||||
if (selector) {
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
if (projection) {
|
||||
this.projection = projection;
|
||||
}
|
||||
}
|
||||
|
||||
hasErrors() {
|
||||
return this._errors.hasErrors();
|
||||
}
|
||||
|
||||
errors() {
|
||||
return this._errors.errors();
|
||||
}
|
||||
|
||||
errorMessages() {
|
||||
return this._errors.errorMessages();
|
||||
}
|
||||
|
||||
getQueryParams() {
|
||||
return this.queryParams;
|
||||
}
|
||||
|
||||
addPredicate(operator, predicate) {
|
||||
this.queryParams.addPredicate(operator, predicate);
|
||||
}
|
||||
|
||||
buildParams(queryText) {
|
||||
queryText = queryText.trim();
|
||||
// eslint-disable-next-line no-console
|
||||
//console.log('query:', query);
|
||||
|
||||
if (!queryText) {
|
||||
return;
|
||||
}
|
||||
|
||||
const reOperator1 = new RegExp(
|
||||
'^((?<operator>[\\p{Letter}\\p{Mark}]+):|(?<abbrev>[#@]))(?<value>[\\p{Letter}\\p{Mark}]+)(\\s+|$)',
|
||||
'iu',
|
||||
);
|
||||
const reOperator2 = new RegExp(
|
||||
'^((?<operator>[\\p{Letter}\\p{Mark}]+):|(?<abbrev>[#@]))(?<quote>["\']*)(?<value>.*?)\\k<quote>(\\s+|$)',
|
||||
'iu',
|
||||
);
|
||||
const reText = new RegExp('^(?<text>\\S+)(\\s+|$)', 'u');
|
||||
const reQuotedText = new RegExp(
|
||||
'^(?<quote>["\'])(?<text>.*?)\\k<quote>(\\s+|$)',
|
||||
'u',
|
||||
);
|
||||
const reNegatedOperator = new RegExp('^-(?<operator>.*)$');
|
||||
|
||||
const operators = {
|
||||
'operator-board': OPERATOR_BOARD,
|
||||
'operator-board-abbrev': OPERATOR_BOARD,
|
||||
'operator-swimlane': OPERATOR_SWIMLANE,
|
||||
'operator-swimlane-abbrev': OPERATOR_SWIMLANE,
|
||||
'operator-list': OPERATOR_LIST,
|
||||
'operator-list-abbrev': OPERATOR_LIST,
|
||||
'operator-label': OPERATOR_LABEL,
|
||||
'operator-label-abbrev': OPERATOR_LABEL,
|
||||
'operator-user': OPERATOR_USER,
|
||||
'operator-user-abbrev': OPERATOR_USER,
|
||||
'operator-member': OPERATOR_MEMBER,
|
||||
'operator-member-abbrev': OPERATOR_MEMBER,
|
||||
'operator-assignee': OPERATOR_ASSIGNEE,
|
||||
'operator-assignee-abbrev': OPERATOR_ASSIGNEE,
|
||||
'operator-status': OPERATOR_STATUS,
|
||||
'operator-due': OPERATOR_DUE,
|
||||
'operator-created': OPERATOR_CREATED_AT,
|
||||
'operator-modified': OPERATOR_MODIFIED_AT,
|
||||
'operator-comment': OPERATOR_COMMENT,
|
||||
'operator-has': OPERATOR_HAS,
|
||||
'operator-sort': OPERATOR_SORT,
|
||||
'operator-limit': OPERATOR_LIMIT,
|
||||
};
|
||||
|
||||
const predicates = {
|
||||
due: {
|
||||
'predicate-overdue': PREDICATE_OVERDUE,
|
||||
},
|
||||
durations: {
|
||||
'predicate-week': PREDICATE_WEEK,
|
||||
'predicate-month': PREDICATE_MONTH,
|
||||
'predicate-quarter': PREDICATE_QUARTER,
|
||||
'predicate-year': PREDICATE_YEAR,
|
||||
},
|
||||
status: {
|
||||
'predicate-archived': PREDICATE_ARCHIVED,
|
||||
'predicate-all': PREDICATE_ALL,
|
||||
'predicate-open': PREDICATE_OPEN,
|
||||
'predicate-ended': PREDICATE_ENDED,
|
||||
'predicate-public': PREDICATE_PUBLIC,
|
||||
'predicate-private': PREDICATE_PRIVATE,
|
||||
},
|
||||
sorts: {
|
||||
'predicate-due': PREDICATE_DUE_AT,
|
||||
'predicate-created': PREDICATE_CREATED_AT,
|
||||
'predicate-modified': PREDICATE_MODIFIED_AT,
|
||||
},
|
||||
has: {
|
||||
'predicate-description': PREDICATE_DESCRIPTION,
|
||||
'predicate-checklist': PREDICATE_CHECKLIST,
|
||||
'predicate-attachment': PREDICATE_ATTACHMENT,
|
||||
'predicate-start': PREDICATE_START_AT,
|
||||
'predicate-end': PREDICATE_END_AT,
|
||||
'predicate-due': PREDICATE_DUE_AT,
|
||||
'predicate-assignee': PREDICATE_ASSIGNEES,
|
||||
'predicate-member': PREDICATE_MEMBERS,
|
||||
},
|
||||
};
|
||||
const predicateTranslations = {};
|
||||
Object.entries(predicates).forEach(([category, catPreds]) => {
|
||||
predicateTranslations[category] = {};
|
||||
Object.entries(catPreds).forEach(([tag, value]) => {
|
||||
predicateTranslations[category][TAPi18n.__(tag)] = value;
|
||||
});
|
||||
});
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('predicateTranslations:', predicateTranslations);
|
||||
|
||||
const operatorMap = {};
|
||||
Object.entries(operators).forEach(([key, value]) => {
|
||||
operatorMap[TAPi18n.__(key).toLowerCase()] = value;
|
||||
});
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('operatorMap:', operatorMap);
|
||||
|
||||
let text = '';
|
||||
while (queryText) {
|
||||
let m = queryText.match(reOperator1);
|
||||
if (!m) {
|
||||
m = queryText.match(reOperator2);
|
||||
if (m) {
|
||||
queryText = queryText.replace(reOperator2, '');
|
||||
}
|
||||
} else {
|
||||
queryText = queryText.replace(reOperator1, '');
|
||||
}
|
||||
if (m) {
|
||||
let op;
|
||||
if (m.groups.operator) {
|
||||
op = m.groups.operator.toLowerCase();
|
||||
} else {
|
||||
op = m.groups.abbrev.toLowerCase();
|
||||
}
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (operatorMap.hasOwnProperty(op)) {
|
||||
const operator = operatorMap[op];
|
||||
let value = m.groups.value;
|
||||
if (operator === OPERATOR_LABEL) {
|
||||
if (value in this.colorMap) {
|
||||
value = this.colorMap[value];
|
||||
// console.log('found color:', value);
|
||||
}
|
||||
} else if (
|
||||
[OPERATOR_DUE, OPERATOR_CREATED_AT, OPERATOR_MODIFIED_AT].includes(
|
||||
operator,
|
||||
)
|
||||
) {
|
||||
const days = parseInt(value, 10);
|
||||
let duration = null;
|
||||
if (isNaN(days)) {
|
||||
// duration was specified as text
|
||||
if (predicateTranslations.durations[value]) {
|
||||
duration = predicateTranslations.durations[value];
|
||||
let date = null;
|
||||
switch (duration) {
|
||||
case PREDICATE_WEEK:
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const week = moment().week();
|
||||
if (week === 52) {
|
||||
date = moment(1, 'W');
|
||||
date.set('year', date.year() + 1);
|
||||
} else {
|
||||
date = moment(week + 1, 'W');
|
||||
}
|
||||
break;
|
||||
case PREDICATE_MONTH:
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const month = moment().month();
|
||||
// .month() is zero indexed
|
||||
if (month === 11) {
|
||||
date = moment(1, 'M');
|
||||
date.set('year', date.year() + 1);
|
||||
} else {
|
||||
date = moment(month + 2, 'M');
|
||||
}
|
||||
break;
|
||||
case PREDICATE_QUARTER:
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const quarter = moment().quarter();
|
||||
if (quarter === 4) {
|
||||
date = moment(1, 'Q');
|
||||
date.set('year', date.year() + 1);
|
||||
} else {
|
||||
date = moment(quarter + 1, 'Q');
|
||||
}
|
||||
break;
|
||||
case PREDICATE_YEAR:
|
||||
date = moment(moment().year() + 1, 'YYYY');
|
||||
break;
|
||||
}
|
||||
if (date) {
|
||||
value = {
|
||||
operator: '$lt',
|
||||
value: date.format('YYYY-MM-DD'),
|
||||
};
|
||||
}
|
||||
} else if (
|
||||
operator === OPERATOR_DUE &&
|
||||
value === PREDICATE_OVERDUE
|
||||
) {
|
||||
value = {
|
||||
operator: '$lt',
|
||||
value: moment().format('YYYY-MM-DD'),
|
||||
};
|
||||
} else {
|
||||
this.errors.addError(OPERATOR_DUE, {
|
||||
tag: 'operator-number-expected',
|
||||
value: { operator: op, value },
|
||||
});
|
||||
continue;
|
||||
}
|
||||
} else if (operator === OPERATOR_DUE) {
|
||||
value = {
|
||||
operator: '$lt',
|
||||
value: moment(moment().format('YYYY-MM-DD'))
|
||||
.add(days + 1, duration ? duration : 'days')
|
||||
.format(),
|
||||
};
|
||||
} else {
|
||||
value = {
|
||||
operator: '$gte',
|
||||
value: moment(moment().format('YYYY-MM-DD'))
|
||||
.subtract(days, duration ? duration : 'days')
|
||||
.format(),
|
||||
};
|
||||
}
|
||||
} else if (operator === OPERATOR_SORT) {
|
||||
let negated = false;
|
||||
const m = value.match(reNegatedOperator);
|
||||
if (m) {
|
||||
value = m.groups.operator;
|
||||
negated = true;
|
||||
}
|
||||
if (!predicateTranslations.sorts[value]) {
|
||||
this.errors.addError(OPERATOR_SORT, {
|
||||
tag: 'operator-sort-invalid',
|
||||
value,
|
||||
});
|
||||
continue;
|
||||
} else {
|
||||
value = {
|
||||
name: predicateTranslations.sorts[value],
|
||||
order: negated ? ORDER_DESCENDING : ORDER_ASCENDING,
|
||||
};
|
||||
}
|
||||
} else if (operator === OPERATOR_STATUS) {
|
||||
if (!predicateTranslations.status[value]) {
|
||||
this.errors.addError(OPERATOR_STATUS, {
|
||||
tag: 'operator-status-invalid',
|
||||
value,
|
||||
});
|
||||
continue;
|
||||
} else {
|
||||
value = predicateTranslations.status[value];
|
||||
}
|
||||
} else if (operator === OPERATOR_HAS) {
|
||||
let negated = false;
|
||||
const m = value.match(reNegatedOperator);
|
||||
if (m) {
|
||||
value = m.groups.operator;
|
||||
negated = true;
|
||||
}
|
||||
if (!predicateTranslations.has[value]) {
|
||||
this.errors.addError(OPERATOR_HAS, {
|
||||
tag: 'operator-has-invalid',
|
||||
value,
|
||||
});
|
||||
continue;
|
||||
} else {
|
||||
value = {
|
||||
field: predicateTranslations.has[value],
|
||||
exists: !negated,
|
||||
};
|
||||
}
|
||||
} else if (operator === OPERATOR_LIMIT) {
|
||||
const limit = parseInt(value, 10);
|
||||
if (isNaN(limit) || limit < 1) {
|
||||
this.errors.addError(OPERATOR_LIMIT, {
|
||||
tag: 'operator-limit-invalid',
|
||||
value,
|
||||
});
|
||||
continue;
|
||||
} else {
|
||||
value = limit;
|
||||
}
|
||||
}
|
||||
|
||||
this.queryParams.addPredicate(operator, value);
|
||||
} else {
|
||||
this.errors.addError(OPERATOR_UNKNOWN, {
|
||||
tag: 'operator-unknown-error',
|
||||
value: op,
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
m = queryText.match(reQuotedText);
|
||||
if (!m) {
|
||||
m = queryText.match(reText);
|
||||
if (m) {
|
||||
queryText = queryText.replace(reText, '');
|
||||
}
|
||||
} else {
|
||||
queryText = queryText.replace(reQuotedText, '');
|
||||
}
|
||||
if (m) {
|
||||
text += (text ? ' ' : '') + m.groups.text;
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('text:', text);
|
||||
this.queryParams.text = text;
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('queryParams:', this.queryParams);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ FlowRouter.route('/', {
|
||||
Session.set('currentCard', null);
|
||||
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
EscapeActions.executeAll();
|
||||
|
||||
Utils.manageCustomUI();
|
||||
@@ -35,6 +36,7 @@ FlowRouter.route('/public', {
|
||||
Session.set('currentCard', null);
|
||||
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
EscapeActions.executeAll();
|
||||
|
||||
Utils.manageCustomUI();
|
||||
@@ -59,6 +61,7 @@ FlowRouter.route('/b/:id/:slug', {
|
||||
// want to excape every current actions (filters, etc.)
|
||||
if (previousBoard !== currentBoard) {
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
EscapeActions.executeAll();
|
||||
} else {
|
||||
EscapeActions.executeUpTo('popup-close');
|
||||
@@ -115,8 +118,10 @@ FlowRouter.route('/shortcuts', {
|
||||
|
||||
FlowRouter.route('/my-cards', {
|
||||
name: 'my-cards',
|
||||
triggersEnter: [AccountsTemplates.ensureSignedIn],
|
||||
action() {
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
// EscapeActions.executeAll();
|
||||
EscapeActions.executeUpTo('popup-close');
|
||||
|
||||
@@ -133,8 +138,10 @@ FlowRouter.route('/my-cards', {
|
||||
|
||||
FlowRouter.route('/due-cards', {
|
||||
name: 'due-cards',
|
||||
triggersEnter: [AccountsTemplates.ensureSignedIn],
|
||||
action() {
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
// EscapeActions.executeAll();
|
||||
EscapeActions.executeUpTo('popup-close');
|
||||
|
||||
@@ -151,8 +158,10 @@ FlowRouter.route('/due-cards', {
|
||||
|
||||
FlowRouter.route('/global-search', {
|
||||
name: 'global-search',
|
||||
triggersEnter: [AccountsTemplates.ensureSignedIn],
|
||||
action() {
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
// EscapeActions.executeAll();
|
||||
EscapeActions.executeUpTo('popup-close');
|
||||
|
||||
@@ -179,6 +188,7 @@ FlowRouter.route('/broken-cards', {
|
||||
const brokenCardsTemplate = 'brokenCards';
|
||||
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
// EscapeActions.executeAll();
|
||||
EscapeActions.executeUpTo('popup-close');
|
||||
|
||||
@@ -205,6 +215,7 @@ FlowRouter.route('/import/:source', {
|
||||
Session.set('importSource', params.source);
|
||||
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
EscapeActions.executeAll();
|
||||
BlazeLayout.render('defaultLayout', {
|
||||
headerBar: 'importHeaderBar',
|
||||
@@ -223,6 +234,7 @@ FlowRouter.route('/setting', {
|
||||
Session.set('currentCard', null);
|
||||
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
EscapeActions.executeAll();
|
||||
},
|
||||
],
|
||||
@@ -245,6 +257,7 @@ FlowRouter.route('/information', {
|
||||
Session.set('currentCard', null);
|
||||
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
EscapeActions.executeAll();
|
||||
},
|
||||
],
|
||||
@@ -266,6 +279,7 @@ FlowRouter.route('/people', {
|
||||
Session.set('currentCard', null);
|
||||
|
||||
Filter.reset();
|
||||
Session.set('sortBy', '');
|
||||
EscapeActions.executeAll();
|
||||
},
|
||||
],
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
export const DEFAULT_LIMIT = 25;
|
||||
export const OPERATOR_ASSIGNEE = 'assignee';
|
||||
export const OPERATOR_COMMENT = 'comment';
|
||||
export const OPERATOR_CREATED_AT = 'createdAt';
|
||||
export const OPERATOR_DUE = 'dueAt';
|
||||
export const OPERATOR_BOARD = 'board';
|
||||
export const OPERATOR_HAS = 'has';
|
||||
export const OPERATOR_LABEL = 'label';
|
||||
export const OPERATOR_LIMIT = 'limit';
|
||||
export const OPERATOR_LIST = 'list';
|
||||
export const OPERATOR_MEMBER = 'member';
|
||||
export const OPERATOR_MODIFIED_AT = 'modifiedAt';
|
||||
export const OPERATOR_SORT = 'sort';
|
||||
export const OPERATOR_STATUS = 'status';
|
||||
export const OPERATOR_SWIMLANE = 'swimlane';
|
||||
export const OPERATOR_UNKNOWN = 'unknown';
|
||||
export const OPERATOR_USER = 'user';
|
||||
export const ORDER_ASCENDING = 'asc';
|
||||
export const ORDER_DESCENDING = 'des';
|
||||
export const PREDICATE_ALL = 'all';
|
||||
export const PREDICATE_ARCHIVED = 'archived';
|
||||
export const PREDICATE_ASSIGNEES = 'assignees';
|
||||
export const PREDICATE_ATTACHMENT = 'attachment';
|
||||
export const PREDICATE_CHECKLIST = 'checklist';
|
||||
export const PREDICATE_CREATED_AT = 'createdAt';
|
||||
export const PREDICATE_DESCRIPTION = 'description';
|
||||
export const PREDICATE_DUE_AT = 'dueAt';
|
||||
export const PREDICATE_END_AT = 'endAt';
|
||||
export const PREDICATE_ENDED = 'ended';
|
||||
export const PREDICATE_MEMBERS = 'members';
|
||||
export const PREDICATE_MODIFIED_AT = 'modifiedAt';
|
||||
export const PREDICATE_MONTH = 'month';
|
||||
export const PREDICATE_OPEN = 'open';
|
||||
export const PREDICATE_OVERDUE = 'overdue';
|
||||
export const PREDICATE_PRIVATE = 'private';
|
||||
export const PREDICATE_PUBLIC = 'public';
|
||||
export const PREDICATE_QUARTER = 'quarter';
|
||||
export const PREDICATE_START_AT = 'startAt';
|
||||
export const PREDICATE_SYSTEM = 'system';
|
||||
export const PREDICATE_WEEK = 'week';
|
||||
export const PREDICATE_YEAR = 'year';
|
||||
+6
-3
@@ -118,11 +118,11 @@ services:
|
||||
#-------------------------------------------------------------------------------------
|
||||
# ==== MONGODB AND METEOR VERSION ====
|
||||
# a) Quay automatic builds do work work, https://quay.io/wekan/wekan
|
||||
# image: quay.io/wekan/wekan
|
||||
image: quay.io/wekan/wekan:stable
|
||||
# b) Using specific version tag:
|
||||
# image: quay.io/wekan/wekan:v4.52
|
||||
# c) Docker Hub builds do work https://hub.docker.com/r/wekanteam/wekan
|
||||
image: wekanteam/wekan
|
||||
# image: wekanteam/wekan
|
||||
#-------------------------------------------------------------------------------------
|
||||
container_name: wekan-app
|
||||
restart: always
|
||||
@@ -209,6 +209,9 @@ services:
|
||||
# There is Feature Request: Logging date and time of all activity with summary reports,
|
||||
# and requesting reason for changing card to other column https://github.com/wekan/wekan/issues/1598
|
||||
#---------------------------------------------------------------
|
||||
# ==== NUMBER OF SEARCH RESULTS PER PAGE BY DEFAULT ====
|
||||
#- RESULTS_PER_PAGE=20
|
||||
#---------------------------------------------------------------
|
||||
# ==== WEKAN API AND EXPORT BOARD ====
|
||||
# Wekan Export Board works when WITH_API=true.
|
||||
# https://github.com/wekan/wekan/wiki/REST-API
|
||||
@@ -309,7 +312,7 @@ services:
|
||||
#- TRUSTED_URL=https://intra.example.com
|
||||
#-----------------------------------------------------------------
|
||||
# ==== OUTGOING WEBHOOKS ====
|
||||
# What to send to Outgoing Webhook, or leave out. Example, that includes all that are default: cardId,listId,oldListId,boardId,comment,user,card,commentId .
|
||||
# What to send to Outgoing Webhook, or leave out. If commented out the default values will be: cardId,listId,oldListId,boardId,comment,user,card,commentId,swimlaneId,customerField,customFieldValue
|
||||
#- WEBHOOKS_ATTRIBUTES=cardId,listId,oldListId,boardId,comment,user,card,commentId
|
||||
#-----------------------------------------------------------------
|
||||
# ==== Debug OIDC OAuth2 etc ====
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: wekan
|
||||
version: 1.0.2
|
||||
version: 1.0.3
|
||||
apiVersion: v1
|
||||
description: Open Source kanban
|
||||
home: https://wekan.github.io/
|
||||
|
||||
@@ -81,7 +81,7 @@ else use user-provided URL.
|
||||
{{- $release := .Release.Name -}}
|
||||
{{- $replicaSetName := (index .Values "mongodb" "replicaSetName") -}}
|
||||
{{- $mongodbSvcName := include "wekan.mongodb.svcname" . -}}
|
||||
mongodb://{{- range $v := until $count }}{{ $release }}-mongodb-{{ $v }}.{{ $mongodbSvcName }}:27017{{ if ne $v (sub $count 1) }},{{- end -}}{{- end -}}?replicaSet={{ $replicaSetName }}
|
||||
mongodb://{{- range $v := until $count }}{{ $release }}-mongodb-{{ $v }}.{{ $mongodbSvcName }}:27017{{ if ne $v (sub $count 1) }},{{- end -}}{{- end -}}/{{ .Values.dbname }}?replicaSet={{ $replicaSetName }}
|
||||
{{- else -}}
|
||||
{{- index .Values "mongodb" "url" -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -46,7 +46,10 @@ spec:
|
||||
{{- range $key := .Values.secretEnv }}
|
||||
{{- if .value }}
|
||||
- name: {{ .name }}
|
||||
value: {{ .value | quote }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ template "wekan.fullname" $ }}-secret
|
||||
key: {{ .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{{ if .Values.secretEnv }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ template "wekan.fullname" $ }}-secret
|
||||
type: Opaque
|
||||
data:
|
||||
{{- range $key := .Values.secretEnv }}
|
||||
{{ $key.name }}: {{ $key.value | b64enc }}
|
||||
{{- end}}
|
||||
{{ end }}
|
||||
@@ -21,6 +21,7 @@ image:
|
||||
##
|
||||
|
||||
replicaCount: 1
|
||||
dbname: wekan
|
||||
|
||||
## Specify additional environmental variables for the Deployment
|
||||
##
|
||||
@@ -32,9 +33,9 @@ env:
|
||||
## Deployment. These can e.g. be provided by a Secret and allow
|
||||
## to store passwords separately
|
||||
##
|
||||
secretEnv:
|
||||
- name: ""
|
||||
value: ""
|
||||
secretEnv: {}
|
||||
# - name: ""
|
||||
# value: ""
|
||||
|
||||
service:
|
||||
type: NodePort
|
||||
|
||||
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+55
-19
@@ -322,6 +322,8 @@
|
||||
"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-orgname-taken": "This organization name is already taken",
|
||||
"error-teamname-taken": "This team name is already taken",
|
||||
"error-email-taken": "Email has already been taken",
|
||||
"export-board": "Export board",
|
||||
"export-board-json": "Export board to JSON",
|
||||
@@ -530,6 +532,7 @@
|
||||
"custom-login-logo-image-url": "Custom Login Logo Image URL",
|
||||
"custom-login-logo-link-url": "Custom Login Logo Link URL",
|
||||
"text-below-custom-login-logo": "Text below Custom Login Logo",
|
||||
"automatic-linked-url-schemes": "Custom URL Schemes which should automatically be clickable. One URL Scheme per line",
|
||||
"username": "Username",
|
||||
"import-usernames": "Import Usernames",
|
||||
"view-it": "View it",
|
||||
@@ -904,7 +907,10 @@
|
||||
"operator-modified": "modified",
|
||||
"operator-sort": "sort",
|
||||
"operator-comment": "comment",
|
||||
"operator-has": "has",
|
||||
"operator-limit": "limit",
|
||||
"predicate-archived": "archived",
|
||||
"predicate-open": "open",
|
||||
"predicate-ended": "ended",
|
||||
"predicate-all": "all",
|
||||
"predicate-overdue": "overdue",
|
||||
@@ -915,42 +921,72 @@
|
||||
"predicate-due": "due",
|
||||
"predicate-modified": "modified",
|
||||
"predicate-created": "created",
|
||||
"predicate-attachment": "attachment",
|
||||
"predicate-description": "description",
|
||||
"predicate-checklist": "checklist",
|
||||
"predicate-start": "start",
|
||||
"predicate-end": "end",
|
||||
"predicate-assignee": "assignee",
|
||||
"predicate-member": "member",
|
||||
"predicate-public": "public",
|
||||
"predicate-private": "private",
|
||||
"operator-unknown-error": "%s is not an operator",
|
||||
"operator-number-expected": "operator __operator__ expected a number, got '__value__'",
|
||||
"operator-sort-invalid": "sort of '%s' is invalid",
|
||||
"operator-status-invalid": "'%s' is not a valid status",
|
||||
"operator-has-invalid": "%s is not a valid existence check",
|
||||
"operator-limit-invalid": "%s is not a valid limit. Limit should be a positive integer.",
|
||||
"next-page": "Next Page",
|
||||
"previous-page": "Previous Page",
|
||||
"heading-notes": "Notes",
|
||||
"globalSearch-instructions-heading": "Search Instructions",
|
||||
"globalSearch-instructions-description": "Searches can include operators to refine the search. Operators are specified by writing the operator name and value separated by a colon. For example, an operator specification of `list:Blocked` would limit the search to cards that are contained in a list named *Blocked*. If the value contains spaces or special characters it must be enclosed in quotation marks (e.g. `__operator_list__:\"To Review\"`).",
|
||||
"globalSearch-instructions-operators": "Available operators:",
|
||||
"globalSearch-instructions-operator-board": "`__operator_board__:title` - cards in boards matching the specified title",
|
||||
"globalSearch-instructions-operator-list": "`__operator_list__:title` - cards in lists matching the specified title",
|
||||
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:title` - cards in swimlanes matching the specified title",
|
||||
"globalSearch-instructions-operator-comment": "`__operator_comment__:text` - cards with with a comment containing *text*.",
|
||||
"globalSearch-instructions-operator-label": "`__operator_label__:color` `__operator_label__:name` - cards that have a label matching the given color or name",
|
||||
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__label` - shorthand for `__operator_label__:label`",
|
||||
"globalSearch-instructions-operator-user": "`__operator_user__:username` - cards where the specified user is a *member* or *assignee*",
|
||||
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - shorthand for `user:username`",
|
||||
"globalSearch-instructions-operator-member": "`__operator_member__:username` - cards where the specified user is a *member*",
|
||||
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:username` - cards where the specified user is an *assignee*",
|
||||
"globalSearch-instructions-operator-due": "`__operator_due__:n` - cards which are due *n* days from now. `__operator_due__:__predicate_overdue__ lists all cards past their due date.",
|
||||
"globalSearch-instructions-operator-created": "`__operator_created__:n` - cards which which were created *n* days ago",
|
||||
"globalSearch-instructions-operator-modified": "`__operator_modified__:n` - cards which which were modified *n* days ago",
|
||||
"globalSearch-instructions-status-archived": "`__operator_status__:__predicate_archived__` - cards that are archived.",
|
||||
"globalSearch-instructions-status-all": "`__operator_status__:__predicate_all__` - all archived and unarchived cards.",
|
||||
"globalSearch-instructions-status-ended": "`__operator_status__:__predicate_ended__` - cards with an end date.",
|
||||
"globalSearch-instructions-operator-board": "`__operator_board__:<title>` - cards in boards matching the specified *<title>*",
|
||||
"globalSearch-instructions-operator-list": "`__operator_list__:<title>` - cards in lists matching the specified *<title>*",
|
||||
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<title>` - cards in swimlanes matching the specified *<title>*",
|
||||
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - cards with a comment containing *<text>*.",
|
||||
"globalSearch-instructions-operator-label": "`__operator_label__:<color>` `__operator_label__:<name>` - cards that have a label matching *<color>* or *<name>",
|
||||
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name|color>` - shorthand for `__operator_label__:<color>` or `__operator_label__:<name>`",
|
||||
"globalSearch-instructions-operator-user": "`__operator_user__:<username>` - cards where *<username>* is a *member* or *assignee*",
|
||||
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - shorthand for `user:<username>`",
|
||||
"globalSearch-instructions-operator-member": "`__operator_member__:<username>` - cards where *<username>* is a *member*",
|
||||
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:<username>` - cards where *<username>* is an *assignee*",
|
||||
"globalSearch-instructions-operator-due": "`__operator_due__:<n>` - cards which are due up to *<n>* days from now. `__operator_due__:__predicate_overdue__ lists all cards past their due date.",
|
||||
"globalSearch-instructions-operator-created": "`__operator_created__:<n>` - cards which were created *<n>* days ago or less",
|
||||
"globalSearch-instructions-operator-modified": "`__operator_modified__:<n>` - cards which were modified *<n>* days ago or less",
|
||||
"globalSearch-instructions-operator-status": "`__operator_status__:<status>` - where *<status>* is one of the following:",
|
||||
"globalSearch-instructions-status-archived": "`__predicate_archived__` - archived cards",
|
||||
"globalSearch-instructions-status-all": "`__predicate_all__` - all archived and unarchived cards",
|
||||
"globalSearch-instructions-status-ended": "`__predicate_ended__` - cards with an end date",
|
||||
"globalSearch-instructions-status-public": "`__predicate_public__` - cards only in public boards",
|
||||
"globalSearch-instructions-status-private": "`__predicate_private__` - cards only in private boards",
|
||||
"globalSearch-instructions-operator-has": "`__operator_has__:<field>` - where *<field>* is one of `__predicate_attachment__`, `__predicate_checklist__`, `__predicate_description__`, `__predicate_start__`, `__predicate_due__`, `__predicate_end__`, `__predicate_assignee__` or `__predicate_member__`. Placing a `-` in front of *<field>* searches for the absence of a value in that field (e.g. `has:-due` searches for cards without a due date).",
|
||||
"globalSearch-instructions-operator-sort": "`__operator_sort__:<sort-name>` - where *<sort-name>* is one of `__predicate_due__`, `__predicate_created__` or `__predicate_modified__`. For a descending sort, place a `-` in front of the sort name.",
|
||||
"globalSearch-instructions-operator-limit": "`__operator_limit__:<n>` - where *<n>* is a positive integer expressing the number of cards to be displayed per page.",
|
||||
"globalSearch-instructions-notes-1": "Multiple operators may be specified.",
|
||||
"globalSearch-instructions-notes-2": "Similar operators are *OR*ed together. Cards that match any of the conditions will be returned.\n`__operator_list__:Available __operator_list__:Blocked` would return cards contained in any list named *Blocked* or *Available*.",
|
||||
"globalSearch-instructions-notes-3": "Differing operators are *AND*ed together. Only cards that match all of the differing operators are returned. `__operator_list__:Available __operator_label__:red` returns only cards in the list *Available* with a *red* label.",
|
||||
"globalSearch-instructions-notes-3-2": "Days can be specified as an integer or using `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` or `__predicate_year__`",
|
||||
"globalSearch-instructions-notes-3-2": "Days can be specified as a positive or negative integer or using `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` or `__predicate_year__` for the current period.",
|
||||
"globalSearch-instructions-notes-4": "Text searches are case insensitive.",
|
||||
"globalSearch-instructions-notes-5": "Currently archived cards are not searched.",
|
||||
"globalSearch-instructions-notes-5": "By default archived cards are not searched.",
|
||||
"link-to-search": "Link to this search",
|
||||
"excel-font": "Arial",
|
||||
"number": "Number",
|
||||
"label-colors": "Label Colors",
|
||||
"label-names": "Label Names",
|
||||
"archived-at": "archived at"
|
||||
"archived-at": "archived at",
|
||||
"sort-cards": "Sort Cards",
|
||||
"cardsSortPopup-title": "Sort Cards",
|
||||
"due-date": "Due Date",
|
||||
"server-error": "Server Error",
|
||||
"server-error-troubleshooting": "Please submit the error generated by the server.\nFor a snap installation, run: `sudo snap logs wekan.wekan`\nFor a Docker installation, run: `sudo docker logs wekan-app`",
|
||||
"title-alphabetically": "Title (Alphabetically)",
|
||||
"created-at-newest-first": "Created At (Newest First)",
|
||||
"created-at-oldest-first": "Created At (Oldest First)",
|
||||
"links-heading": "Links",
|
||||
"hide-system-messages-of-all-users": "Hide system messages of all users",
|
||||
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
|
||||
"move-swimlane": "Move Swimlane",
|
||||
"moveSwimlanePopup-title": "Move Swimlane"
|
||||
}
|
||||
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,991 @@
|
||||
{
|
||||
"accept": "Accept",
|
||||
"act-activity-notify": "Activity Notification",
|
||||
"act-addAttachment": "added attachment __attachment__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-deleteAttachment": "deleted attachment __attachment__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addSubtask": "added subtask __subtask__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addLabel": "Added label __label__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addedLabel": "Added label __label__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removeLabel": "Removed label __label__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removedLabel": "Removed label __label__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addChecklist": "added checklist __checklist__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addChecklistItem": "added checklist item __checklistItem__ to checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removeChecklist": "removed checklist __checklist__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removeChecklistItem": "removed checklist item __checklistItem__ from checklist __checkList__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-checkedItem": "checked __checklistItem__ of checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-uncheckedItem": "unchecked __checklistItem__ of checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-createBoard": "created board __board__",
|
||||
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
|
||||
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-createCustomField": "created custom field __customField__ at board __board__",
|
||||
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
|
||||
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-createList": "added list __list__ to board __board__",
|
||||
"act-addBoardMember": "added member __member__ to board __board__",
|
||||
"act-archivedBoard": "Board __board__ moved to Archive",
|
||||
"act-archivedCard": "Card __card__ at list __list__ at swimlane __swimlane__ at board __board__ moved to Archive",
|
||||
"act-archivedList": "List __list__ at swimlane __swimlane__ at board __board__ moved to Archive",
|
||||
"act-archivedSwimlane": "Swimlane __swimlane__ at board __board__ moved to Archive",
|
||||
"act-importBoard": "imported board __board__",
|
||||
"act-importCard": "imported card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-importList": "imported list __list__ to swimlane __swimlane__ at board __board__",
|
||||
"act-joinMember": "added member __member__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-moveCard": "moved card __card__ at board __board__ from list __oldList__ at swimlane __oldSwimlane__ to list __list__ at swimlane __swimlane__",
|
||||
"act-moveCardToOtherBoard": "moved card __card__ from list __oldList__ at swimlane __oldSwimlane__ at board __oldBoard__ to list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removeBoardMember": "removed member __member__ from board __board__",
|
||||
"act-restoredCard": "restored card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-unjoinMember": "removed member __member__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-withBoardTitle": "__board__",
|
||||
"act-withCardTitle": "[__board__] __card__",
|
||||
"actions": "Actions",
|
||||
"activities": "Activities",
|
||||
"activity": "Activity",
|
||||
"activity-added": "added %s to %s",
|
||||
"activity-archived": "%s moved to Archive",
|
||||
"activity-attached": "attached %s to %s",
|
||||
"activity-created": "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-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-checked-item": "checked %s in checklist %s of %s",
|
||||
"activity-unchecked-item": "unchecked %s in checklist %s of %s",
|
||||
"activity-checklist-added": "added checklist to %s",
|
||||
"activity-checklist-removed": "removed a checklist from %s",
|
||||
"activity-checklist-completed": "completed checklist %s of %s",
|
||||
"activity-checklist-uncompleted": "uncompleted the checklist %s of %s",
|
||||
"activity-checklist-item-added": "added checklist item to '%s' in %s",
|
||||
"activity-checklist-item-removed": "removed a checklist item from '%s' in %s",
|
||||
"add": "Add",
|
||||
"activity-checked-item-card": "checked %s in checklist %s",
|
||||
"activity-unchecked-item-card": "unchecked %s in checklist %s",
|
||||
"activity-checklist-completed-card": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"activity-checklist-uncompleted-card": "uncompleted the checklist %s",
|
||||
"activity-editComment": "edited comment %s",
|
||||
"activity-deleteComment": "deleted comment %s",
|
||||
"activity-receivedDate": "edited received date to %s of %s",
|
||||
"activity-startDate": "edited start date to %s of %s",
|
||||
"activity-dueDate": "edited due date to %s of %s",
|
||||
"activity-endDate": "edited end date to %s of %s",
|
||||
"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": "Loading, please wait. Refreshing the page will cause data loss. If loading does not work, please check that server has not stopped.",
|
||||
"archive": "Move to Archive",
|
||||
"archive-all": "Move All to Archive",
|
||||
"archive-board": "Move Board to Archive",
|
||||
"archive-card": "Move Card to Archive",
|
||||
"archive-list": "Move List to Archive",
|
||||
"archive-swimlane": "Move Swimlane to Archive",
|
||||
"archive-selection": "Move selection to Archive",
|
||||
"archiveBoardPopup-title": "Move Board to Archive?",
|
||||
"archived-items": "Archive",
|
||||
"archived-boards": "Boards in Archive",
|
||||
"restore-board": "Restore Board",
|
||||
"no-archived-boards": "No Boards in Archive.",
|
||||
"archives": "Archive",
|
||||
"template": "Template",
|
||||
"templates": "Templates",
|
||||
"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 (520KB 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 Settings",
|
||||
"boardChangeViewPopup-title": "Board View",
|
||||
"boards": "Boards",
|
||||
"board-view": "Board View",
|
||||
"board-view-cal": "Calendar",
|
||||
"board-view-swimlanes": "Swimlanes",
|
||||
"board-view-collapse": "Collapse",
|
||||
"board-view-gantt": "Gantt",
|
||||
"board-view-lists": "Lists",
|
||||
"bucket-example": "Like “Bucket List” for example",
|
||||
"cancel": "Cancel",
|
||||
"card-archived": "This card is moved to Archive.",
|
||||
"board-archived": "This board is moved to Archive.",
|
||||
"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 Archive 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",
|
||||
"cardStartVotingPopup-title": "Start a vote",
|
||||
"positiveVoteMembersPopup-title": "Proponents",
|
||||
"negativeVoteMembersPopup-title": "Opponents",
|
||||
"card-edit-voting": "Edit voting",
|
||||
"editVoteEndDatePopup-title": "Change vote end date",
|
||||
"allowNonBoardMembers": "Allow all logged in users",
|
||||
"vote-question": "Voting question",
|
||||
"vote-public": "Show who voted what",
|
||||
"vote-for-it": "for it",
|
||||
"vote-against": "against",
|
||||
"deleteVotePopup-title": "Delete vote?",
|
||||
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
|
||||
"cardDeletePopup-title": "Delete Card?",
|
||||
"cardDetailsActionsPopup-title": "Card Actions",
|
||||
"cardLabelsPopup-title": "Labels",
|
||||
"cardMembersPopup-title": "Members",
|
||||
"cardMorePopup-title": "More",
|
||||
"cardTemplatePopup-title": "Create template",
|
||||
"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",
|
||||
"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",
|
||||
"close-board-pop": "You will be able to restore the board by clicking the “Archive” button from the home header.",
|
||||
"color-black": "black",
|
||||
"color-blue": "blue",
|
||||
"color-crimson": "crimson",
|
||||
"color-darkgreen": "darkgreen",
|
||||
"color-gold": "gold",
|
||||
"color-gray": "gray",
|
||||
"color-green": "green",
|
||||
"color-indigo": "indigo",
|
||||
"color-lime": "lime",
|
||||
"color-magenta": "magenta",
|
||||
"color-mistyrose": "mistyrose",
|
||||
"color-navy": "navy",
|
||||
"color-orange": "orange",
|
||||
"color-paleturquoise": "paleturquoise",
|
||||
"color-peachpuff": "peachpuff",
|
||||
"color-pink": "pink",
|
||||
"color-plum": "plum",
|
||||
"color-purple": "purple",
|
||||
"color-red": "red",
|
||||
"color-saddlebrown": "saddlebrown",
|
||||
"color-silver": "silver",
|
||||
"color-sky": "sky",
|
||||
"color-slateblue": "slateblue",
|
||||
"color-white": "white",
|
||||
"color-yellow": "yellow",
|
||||
"unset-color": "Unset",
|
||||
"comment": "Comment",
|
||||
"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.",
|
||||
"worker": "Worker",
|
||||
"worker-desc": "Can only move cards, assign itself to card and comment.",
|
||||
"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",
|
||||
"searchElementPopup-title": "Search",
|
||||
"copyCardPopup-title": "Copy Card",
|
||||
"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-currency": "Currency",
|
||||
"custom-field-currency-option": "Currency Code",
|
||||
"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",
|
||||
"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-csv-schema": "Your CSV(Comma Separated Values)/TSV (Tab Separated Values) 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-orgname-taken": "This organization name is already taken",
|
||||
"error-teamname-taken": "This team name is already taken",
|
||||
"error-email-taken": "Email has already been taken",
|
||||
"export-board": "Export board",
|
||||
"export-board-json": "Export board to JSON",
|
||||
"export-board-csv": "Export board to CSV",
|
||||
"export-board-tsv": "Export board to TSV",
|
||||
"export-board-excel": "Export board to Excel",
|
||||
"user-can-not-export-excel": "User can not export Excel",
|
||||
"export-board-html": "Export board to HTML",
|
||||
"exportBoardPopup-title": "Export board",
|
||||
"sort": "Sort",
|
||||
"sort-desc": "Click to Sort List",
|
||||
"list-sort-by": "Sort the List By:",
|
||||
"list-label-modifiedAt": "Last Access Time",
|
||||
"list-label-title": "Name of the List",
|
||||
"list-label-sort": "Your Manual Order",
|
||||
"list-label-short-modifiedAt": "(L)",
|
||||
"list-label-short-title": "(N)",
|
||||
"list-label-short-sort": "(M)",
|
||||
"filter": "Filter",
|
||||
"filter-cards": "Filter Cards or Lists",
|
||||
"list-filter-label": "Filter List by Title",
|
||||
"filter-clear": "Clear filter",
|
||||
"filter-labels-label": "Filter by label",
|
||||
"filter-no-label": "No label",
|
||||
"filter-member-label": "Filter by member",
|
||||
"filter-no-member": "No member",
|
||||
"filter-assignee-label": "Filter by assignee",
|
||||
"filter-no-assignee": "No assignee",
|
||||
"filter-custom-fields-label": "Filter by Custom Fields",
|
||||
"filter-no-custom-fields": "No Custom Fields",
|
||||
"filter-show-archive": "Show archived lists",
|
||||
"filter-hide-empty": "Hide empty lists",
|
||||
"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",
|
||||
"other-filters-label": "Other Filters",
|
||||
"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",
|
||||
"impersonate-user": "Impersonate user",
|
||||
"link": "Link",
|
||||
"import-board": "import board",
|
||||
"import-board-c": "Import board",
|
||||
"import-board-title-trello": "Import board from Trello",
|
||||
"import-board-title-wekan": "Import board from previous export",
|
||||
"import-board-title-csv": "Import board from CSV/TSV",
|
||||
"from-trello": "From Trello",
|
||||
"from-wekan": "From previous export",
|
||||
"from-csv": "From CSV/TSV",
|
||||
"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-csv": "Paste in your Comma Separated Values(CSV)/ Tab Separated Values (TSV) .",
|
||||
"import-board-instruction-wekan": "In your board, go to 'Menu', then 'Export board', and copy the text in the downloaded file.",
|
||||
"import-board-instruction-about-errors": "If you get errors when importing board, sometimes importing still works, and board is at All Boards page.",
|
||||
"import-json-placeholder": "Paste your valid JSON data here",
|
||||
"import-csv-placeholder": "Paste your valid CSV/TSV 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 your users",
|
||||
"import-members-map-note": "Note: Unmapped members will be assigned to the current user.",
|
||||
"import-show-user-mapping": "Review members mapping",
|
||||
"import-user-select": "Pick your existing user you want to use as this member",
|
||||
"importMapMembersAddPopup-title": "Select 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 Archive",
|
||||
"list-archive-cards-pop": "This will remove all the cards in this list from the board. To view cards in Archive and bring them back to the board, click “Menu” > “Archive”.",
|
||||
"list-move-cards": "Move all cards in this list",
|
||||
"list-select-cards": "Select all cards in this list",
|
||||
"set-color-list": "Set Color",
|
||||
"listActionPopup-title": "List Actions",
|
||||
"settingsUserPopup-title": "User Settings",
|
||||
"swimlaneActionPopup-title": "Swimlane Actions",
|
||||
"swimlaneAddPopup-title": "Add a Swimlane below",
|
||||
"listImportCardPopup-title": "Import a Trello card",
|
||||
"listImportCardsTsvPopup-title": "Import Excel CSV/TSV",
|
||||
"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 Archive 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-label": "Set label for selection",
|
||||
"multi-selection-member": "Set member for 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 Archive.",
|
||||
"no-archived-lists": "No lists in Archive.",
|
||||
"no-archived-swimlanes": "No swimlanes in Archive.",
|
||||
"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",
|
||||
"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",
|
||||
"rules": "Rules",
|
||||
"search-cards": "Search from card/list titles, descriptions and custom fields on this board",
|
||||
"search-example": "Write text you search and press Enter",
|
||||
"select-color": "Select Color",
|
||||
"select-board": "Select Board",
|
||||
"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",
|
||||
"shortcut-show-shortcuts": "Bring up this shortcuts list",
|
||||
"shortcut-toggle-filterbar": "Toggle Filter Sidebar",
|
||||
"shortcut-toggle-searchbar": "Toggle Search 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",
|
||||
"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",
|
||||
"custom-top-left-corner-logo-image-url": "Custom Top Left Corner Logo Image URL",
|
||||
"custom-top-left-corner-logo-link-url": "Custom Top Left Corner Logo Link URL",
|
||||
"custom-top-left-corner-logo-height": "Custom Top Left Corner Logo Height. Default: 27",
|
||||
"custom-login-logo-image-url": "Custom Login Logo Image URL",
|
||||
"custom-login-logo-link-url": "Custom Login Logo Link URL",
|
||||
"text-below-custom-login-logo": "Text below Custom Login Logo",
|
||||
"automatic-linked-url-schemes": "Custom URL Schemes which should automatically be clickable. One URL Scheme per line",
|
||||
"username": "Username",
|
||||
"import-usernames": "Import Usernames",
|
||||
"view-it": "View it",
|
||||
"warn-list-archived": "warning: this card is in an list at Archive",
|
||||
"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",
|
||||
"card-templates-swimlane": "Card Templates",
|
||||
"list-templates-swimlane": "List Templates",
|
||||
"board-templates-swimlane": "Board Templates",
|
||||
"what-to-do": "What do you want to do?",
|
||||
"wipLimitErrorPopup-title": "Invalid WIP Limit",
|
||||
"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",
|
||||
"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-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 kanban board for collaborations.\n\nPlease follow the link below:\n__url__\n\nAnd your invitation code is: __icode__\n\nThanks.",
|
||||
"email-smtp-test-subject": "SMTP Test Email",
|
||||
"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.",
|
||||
"webhook-title": "Webhook Name",
|
||||
"webhook-token": "Token (Optional for Authentication)",
|
||||
"outgoing-webhooks": "Outgoing Webhooks",
|
||||
"bidirectional-webhooks": "Two-Way Webhooks",
|
||||
"outgoingWebhooksPopup-title": "Outgoing Webhooks",
|
||||
"boardCardTitlePopup-title": "Card Title Filter",
|
||||
"disable-webhook": "Disable This Webhook",
|
||||
"global-webhook": "Global Webhooks",
|
||||
"new-outgoing-webhook": "New Outgoing Webhook",
|
||||
"no-name": "(Unknown)",
|
||||
"Node_version": "Node version",
|
||||
"Meteor_version": "Meteor version",
|
||||
"MongoDB_version": "MongoDB version",
|
||||
"MongoDB_storage_engine": "MongoDB storage engine",
|
||||
"MongoDB_Oplog_enabled": "MongoDB Oplog enabled",
|
||||
"OS_Arch": "OS Arch",
|
||||
"OS_Cpus": "OS CPU Count",
|
||||
"OS_Freemem": "OS Free Memory",
|
||||
"OS_Loadavg": "OS Load Average",
|
||||
"OS_Platform": "OS Platform",
|
||||
"OS_Release": "OS Release",
|
||||
"OS_Totalmem": "OS Total Memory",
|
||||
"OS_Type": "OS Type",
|
||||
"OS_Uptime": "OS Uptime",
|
||||
"days": "days",
|
||||
"hours": "hours",
|
||||
"minutes": "minutes",
|
||||
"seconds": "seconds",
|
||||
"show-field-on-card": "Show this field on card",
|
||||
"automatically-field-on-card": "Add field to new cards",
|
||||
"always-field-on-card": "Add field to all cards",
|
||||
"showLabel-field-on-card": "Show field label on minicard",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"accounts": "Accounts",
|
||||
"accounts-allowEmailChange": "Allow Email Change",
|
||||
"accounts-allowUserNameChange": "Allow Username Change",
|
||||
"createdAt": "Created at",
|
||||
"modifiedAt": "Modified at",
|
||||
"verified": "Verified",
|
||||
"active": "Active",
|
||||
"card-received": "Received",
|
||||
"card-received-on": "Received on",
|
||||
"card-end": "End",
|
||||
"card-end-on": "Ends on",
|
||||
"editCardReceivedDatePopup-title": "Change received date",
|
||||
"editCardEndDatePopup-title": "Change end date",
|
||||
"setCardColorPopup-title": "Set color",
|
||||
"setCardActionsColorPopup-title": "Choose a color",
|
||||
"setSwimlaneColorPopup-title": "Choose a color",
|
||||
"setListColorPopup-title": "Choose a color",
|
||||
"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",
|
||||
"card-settings": "Card Settings",
|
||||
"boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
|
||||
"boardCardSettingsPopup-title": "Card Settings",
|
||||
"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",
|
||||
"activity-added-label": "added label '%s' to %s",
|
||||
"activity-removed-label": "removed label '%s' from %s",
|
||||
"activity-delete-attach": "deleted an attachment from %s",
|
||||
"activity-added-label-card": "added label '%s'",
|
||||
"activity-removed-label-card": "removed label '%s'",
|
||||
"activity-delete-attach-card": "deleted an attachment",
|
||||
"activity-set-customfield": "set custom field '%s' to '%s' in %s",
|
||||
"activity-unset-customfield": "unset custom field '%s' in %s",
|
||||
"r-rule": "Rule",
|
||||
"r-add-trigger": "Add trigger",
|
||||
"r-add-action": "Add action",
|
||||
"r-board-rules": "Board rules",
|
||||
"r-add-rule": "Add rule",
|
||||
"r-view-rule": "View rule",
|
||||
"r-delete-rule": "Delete rule",
|
||||
"r-new-rule-name": "New rule title",
|
||||
"r-no-rules": "No rules",
|
||||
"r-trigger": "Trigger",
|
||||
"r-action": "Action",
|
||||
"r-when-a-card": "When a card",
|
||||
"r-is": "is",
|
||||
"r-is-moved": "is moved",
|
||||
"r-added-to": "Added to",
|
||||
"r-removed-from": "Removed from",
|
||||
"r-the-board": "the board",
|
||||
"r-list": "list",
|
||||
"list": "List",
|
||||
"set-filter": "Set Filter",
|
||||
"r-moved-to": "Moved to",
|
||||
"r-moved-from": "Moved from",
|
||||
"r-archived": "Moved to Archive",
|
||||
"r-unarchived": "Restored from Archive",
|
||||
"r-a-card": "a card",
|
||||
"r-when-a-label-is": "When a label is",
|
||||
"r-when-the-label": "When the label",
|
||||
"r-list-name": "list name",
|
||||
"r-when-a-member": "When a member is",
|
||||
"r-when-the-member": "When the member",
|
||||
"r-name": "name",
|
||||
"r-when-a-attach": "When an attachment",
|
||||
"r-when-a-checklist": "When a checklist is",
|
||||
"r-when-the-checklist": "When the checklist",
|
||||
"r-completed": "Completed",
|
||||
"r-made-incomplete": "Made incomplete",
|
||||
"r-when-a-item": "When a checklist item is",
|
||||
"r-when-the-item": "When the checklist item",
|
||||
"r-checked": "Checked",
|
||||
"r-unchecked": "Unchecked",
|
||||
"r-move-card-to": "Move card to",
|
||||
"r-top-of": "Top of",
|
||||
"r-bottom-of": "Bottom of",
|
||||
"r-its-list": "its list",
|
||||
"r-archive": "Move to Archive",
|
||||
"r-unarchive": "Restore from Archive",
|
||||
"r-card": "card",
|
||||
"r-add": "Add",
|
||||
"r-remove": "Remove",
|
||||
"r-label": "label",
|
||||
"r-member": "member",
|
||||
"r-remove-all": "Remove all members from the card",
|
||||
"r-set-color": "Set color to",
|
||||
"r-checklist": "checklist",
|
||||
"r-check-all": "Check all",
|
||||
"r-uncheck-all": "Uncheck all",
|
||||
"r-items-check": "items of checklist",
|
||||
"r-check": "Check",
|
||||
"r-uncheck": "Uncheck",
|
||||
"r-item": "item",
|
||||
"r-of-checklist": "of checklist",
|
||||
"r-send-email": "Send an email",
|
||||
"r-to": "to",
|
||||
"r-of": "of",
|
||||
"r-subject": "subject",
|
||||
"r-rule-details": "Rule details",
|
||||
"r-d-move-to-top-gen": "Move card to top of its list",
|
||||
"r-d-move-to-top-spec": "Move card to top of list",
|
||||
"r-d-move-to-bottom-gen": "Move card to bottom of its list",
|
||||
"r-d-move-to-bottom-spec": "Move card to bottom of list",
|
||||
"r-d-send-email": "Send email",
|
||||
"r-d-send-email-to": "to",
|
||||
"r-d-send-email-subject": "subject",
|
||||
"r-d-send-email-message": "message",
|
||||
"r-d-archive": "Move card to Archive",
|
||||
"r-d-unarchive": "Restore card from Archive",
|
||||
"r-d-add-label": "Add label",
|
||||
"r-d-remove-label": "Remove label",
|
||||
"r-create-card": "Create new card",
|
||||
"r-in-list": "in list",
|
||||
"r-in-swimlane": "in swimlane",
|
||||
"r-d-add-member": "Add member",
|
||||
"r-d-remove-member": "Remove member",
|
||||
"r-d-remove-all-member": "Remove all member",
|
||||
"r-d-check-all": "Check all items of a list",
|
||||
"r-d-uncheck-all": "Uncheck all items of a list",
|
||||
"r-d-check-one": "Check item",
|
||||
"r-d-uncheck-one": "Uncheck item",
|
||||
"r-d-check-of-list": "of checklist",
|
||||
"r-d-add-checklist": "Add checklist",
|
||||
"r-d-remove-checklist": "Remove checklist",
|
||||
"r-by": "by",
|
||||
"r-add-checklist": "Add checklist",
|
||||
"r-with-items": "with items",
|
||||
"r-items-list": "item1,item2,item3",
|
||||
"r-add-swimlane": "Add swimlane",
|
||||
"r-swimlane-name": "swimlane name",
|
||||
"r-board-note": "Note: leave a field empty to match every possible value.",
|
||||
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
|
||||
"r-when-a-card-is-moved": "When a card is moved to another list",
|
||||
"r-set": "Set",
|
||||
"r-update": "Update",
|
||||
"r-datefield": "date field",
|
||||
"r-df-start-at": "start",
|
||||
"r-df-due-at": "due",
|
||||
"r-df-end-at": "end",
|
||||
"r-df-received-at": "received",
|
||||
"r-to-current-datetime": "to current date/time",
|
||||
"r-remove-value-from": "Remove value from",
|
||||
"ldap": "LDAP",
|
||||
"oauth2": "OAuth2",
|
||||
"cas": "CAS",
|
||||
"authentication-method": "Authentication method",
|
||||
"authentication-type": "Authentication type",
|
||||
"custom-product-name": "Custom Product Name",
|
||||
"layout": "Layout",
|
||||
"hide-logo": "Hide Logo",
|
||||
"add-custom-html-after-body-start": "Add Custom HTML after <body> start",
|
||||
"add-custom-html-before-body-end": "Add Custom HTML before </body> end",
|
||||
"error-undefined": "Something went wrong",
|
||||
"error-ldap-login": "An error occurred while trying to login",
|
||||
"display-authentication-method": "Display Authentication Method",
|
||||
"default-authentication-method": "Default Authentication Method",
|
||||
"duplicate-board": "Duplicate Board",
|
||||
"org-number": "The number of organizations is:",
|
||||
"team-number": "The number of teams is:",
|
||||
"people-number": "The number of people is:",
|
||||
"swimlaneDeletePopup-title": "Delete Swimlane ?",
|
||||
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
|
||||
"restore-all": "Restore all",
|
||||
"delete-all": "Delete all",
|
||||
"loading": "Loading, please wait.",
|
||||
"previous_as": "last time was",
|
||||
"act-a-dueAt": "modified due time to \nWhen: __timeValue__\nWhere: __card__\n previous due was __timeOldValue__",
|
||||
"act-a-endAt": "modified ending time to __timeValue__ from (__timeOldValue__)",
|
||||
"act-a-startAt": "modified starting time to __timeValue__ from (__timeOldValue__)",
|
||||
"act-a-receivedAt": "modified received time to __timeValue__ from (__timeOldValue__)",
|
||||
"a-dueAt": "modified due time to be",
|
||||
"a-endAt": "modified ending time to be",
|
||||
"a-startAt": "modified starting time to be",
|
||||
"a-receivedAt": "modified received time to be",
|
||||
"almostdue": "current due time %s is approaching",
|
||||
"pastdue": "current due time %s is past",
|
||||
"duenow": "current due time %s is today",
|
||||
"act-newDue": "__list__/__card__ has 1st due reminder [__board__]",
|
||||
"act-withDue": "__list__/__card__ due reminders [__board__]",
|
||||
"act-almostdue": "was reminding the current due (__timeValue__) of __card__ is approaching",
|
||||
"act-pastdue": "was reminding the current due (__timeValue__) of __card__ is past",
|
||||
"act-duenow": "was reminding the current due (__timeValue__) of __card__ is now",
|
||||
"act-atUserComment": "You were mentioned in [__board__] __list__/__card__",
|
||||
"delete-user-confirm-popup": "Are you sure you want to delete this account? There is no undo.",
|
||||
"accounts-allowUserDelete": "Allow users to self delete their account",
|
||||
"hide-minicard-label-text": "Hide minicard label text",
|
||||
"show-desktop-drag-handles": "Show desktop drag handles",
|
||||
"assignee": "Assignee",
|
||||
"cardAssigneesPopup-title": "Assignee",
|
||||
"addmore-detail": "Add a more detailed description",
|
||||
"show-on-card": "Show on Card",
|
||||
"new": "New",
|
||||
"editOrgPopup-title": "Edit Organization",
|
||||
"newOrgPopup-title": "New Organization",
|
||||
"editTeamPopup-title": "Edit Team",
|
||||
"newTeamPopup-title": "New Team",
|
||||
"editUserPopup-title": "Edit User",
|
||||
"newUserPopup-title": "New User",
|
||||
"notifications": "Notifications",
|
||||
"view-all": "View All",
|
||||
"filter-by-unread": "Filter by Unread",
|
||||
"mark-all-as-read": "Mark all as read",
|
||||
"remove-all-read": "Remove all read",
|
||||
"allow-rename": "Allow Rename",
|
||||
"allowRenamePopup-title": "Allow Rename",
|
||||
"start-day-of-week": "Set day of the week start",
|
||||
"monday": "Monday",
|
||||
"tuesday": "Tuesday",
|
||||
"wednesday": "Wednesday",
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"saturday": "Saturday",
|
||||
"sunday": "Sunday",
|
||||
"status": "Status",
|
||||
"swimlane": "Swimlane",
|
||||
"owner": "Owner",
|
||||
"last-modified-at": "Last modified at",
|
||||
"last-activity": "Last activity",
|
||||
"voting": "Voting",
|
||||
"archived": "Archived",
|
||||
"delete-linked-card-before-this-card": "You can not delete this card before first deleting linked card that has",
|
||||
"delete-linked-cards-before-this-list": "You can not delete this list before first deleting linked cards that are pointing to cards in this list",
|
||||
"hide-checked-items": "Hide checked items",
|
||||
"task": "Task",
|
||||
"create-task": "Create Task",
|
||||
"ok": "OK",
|
||||
"organizations": "Organizations",
|
||||
"teams": "Teams",
|
||||
"displayName": "Display Name",
|
||||
"shortName": "Short Name",
|
||||
"website": "Website",
|
||||
"person": "Person",
|
||||
"my-cards": "My Cards",
|
||||
"card": "Card",
|
||||
"board": "Board",
|
||||
"context-separator": "/",
|
||||
"myCardsSortChange-title": "My Cards Sort",
|
||||
"myCardsSortChangePopup-title": "My Cards Sort",
|
||||
"myCardsSortChange-choice-board": "By Board",
|
||||
"myCardsSortChange-choice-dueat": "By Due Date",
|
||||
"dueCards-title": "Due Cards",
|
||||
"dueCardsViewChange-title": "Due Cards View",
|
||||
"dueCardsViewChangePopup-title": "Due Cards View",
|
||||
"dueCardsViewChange-choice-me": "Me",
|
||||
"dueCardsViewChange-choice-all": "All Users",
|
||||
"dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.",
|
||||
"broken-cards": "Broken Cards",
|
||||
"board-title-not-found": "Board '%s' not found.",
|
||||
"swimlane-title-not-found": "Swimlane '%s' not found.",
|
||||
"list-title-not-found": "List '%s' not found.",
|
||||
"label-not-found": "Label '%s' not found.",
|
||||
"label-color-not-found": "Label color %s not found.",
|
||||
"user-username-not-found": "Username '%s' not found.",
|
||||
"comment-not-found": "Card with comment containing text '%s' not found.",
|
||||
"globalSearch-title": "Search All Boards",
|
||||
"no-cards-found": "No Cards Found",
|
||||
"one-card-found": "One Card Found",
|
||||
"n-cards-found": "%s Cards Found",
|
||||
"n-n-of-n-cards-found": "__start__-__end__ of __total__ Cards Found",
|
||||
"operator-board": "board",
|
||||
"operator-board-abbrev": "b",
|
||||
"operator-swimlane": "swimlane",
|
||||
"operator-swimlane-abbrev": "s",
|
||||
"operator-list": "list",
|
||||
"operator-list-abbrev": "l",
|
||||
"operator-label": "label",
|
||||
"operator-label-abbrev": "#",
|
||||
"operator-user": "user",
|
||||
"operator-user-abbrev": "@",
|
||||
"operator-member": "member",
|
||||
"operator-member-abbrev": "m",
|
||||
"operator-assignee": "assignee",
|
||||
"operator-assignee-abbrev": "a",
|
||||
"operator-status": "status",
|
||||
"operator-due": "due",
|
||||
"operator-created": "created",
|
||||
"operator-modified": "modified",
|
||||
"operator-sort": "sort",
|
||||
"operator-comment": "comment",
|
||||
"operator-has": "has",
|
||||
"operator-limit": "limit",
|
||||
"predicate-archived": "archived",
|
||||
"predicate-open": "open",
|
||||
"predicate-ended": "ended",
|
||||
"predicate-all": "all",
|
||||
"predicate-overdue": "overdue",
|
||||
"predicate-week": "week",
|
||||
"predicate-month": "month",
|
||||
"predicate-quarter": "quarter",
|
||||
"predicate-year": "year",
|
||||
"predicate-due": "due",
|
||||
"predicate-modified": "modified",
|
||||
"predicate-created": "created",
|
||||
"predicate-attachment": "attachment",
|
||||
"predicate-description": "description",
|
||||
"predicate-checklist": "checklist",
|
||||
"predicate-start": "start",
|
||||
"predicate-end": "end",
|
||||
"predicate-assignee": "assignee",
|
||||
"predicate-member": "member",
|
||||
"predicate-public": "public",
|
||||
"predicate-private": "private",
|
||||
"operator-unknown-error": "%s is not an operator",
|
||||
"operator-number-expected": "operator __operator__ expected a number, got '__value__'",
|
||||
"operator-sort-invalid": "sort of '%s' is invalid",
|
||||
"operator-status-invalid": "'%s' is not a valid status",
|
||||
"operator-has-invalid": "%s is not a valid existence check",
|
||||
"operator-limit-invalid": "%s is not a valid limit. Limit should be a positive integer.",
|
||||
"next-page": "Next Page",
|
||||
"previous-page": "Previous Page",
|
||||
"heading-notes": "Notes",
|
||||
"globalSearch-instructions-heading": "Search Instructions",
|
||||
"globalSearch-instructions-description": "Searches can include operators to refine the search. Operators are specified by writing the operator name and value separated by a colon. For example, an operator specification of `list:Blocked` would limit the search to cards that are contained in a list named *Blocked*. If the value contains spaces or special characters it must be enclosed in quotation marks (e.g. `__operator_list__:\"To Review\"`).",
|
||||
"globalSearch-instructions-operators": "Available operators:",
|
||||
"globalSearch-instructions-operator-board": "`__operator_board__:<title>` - cards in boards matching the specified *<title>*",
|
||||
"globalSearch-instructions-operator-list": "`__operator_list__:<title>` - cards in lists matching the specified *<title>*",
|
||||
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<title>` - cards in swimlanes matching the specified *<title>*",
|
||||
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - cards with a comment containing *<text>*.",
|
||||
"globalSearch-instructions-operator-label": "`__operator_label__:<color>` `__operator_label__:<name>` - cards that have a label matching *<color>* or *<name>",
|
||||
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name|color>` - shorthand for `__operator_label__:<color>` or `__operator_label__:<name>`",
|
||||
"globalSearch-instructions-operator-user": "`__operator_user__:<username>` - cards where *<username>* is a *member* or *assignee*",
|
||||
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - shorthand for `user:<username>`",
|
||||
"globalSearch-instructions-operator-member": "`__operator_member__:<username>` - cards where *<username>* is a *member*",
|
||||
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:<username>` - cards where *<username>* is an *assignee*",
|
||||
"globalSearch-instructions-operator-due": "`__operator_due__:<n>` - cards which are due up to *<n>* days from now. `__operator_due__:__predicate_overdue__ lists all cards past their due date.",
|
||||
"globalSearch-instructions-operator-created": "`__operator_created__:<n>` - cards which were created *<n>* days ago or less",
|
||||
"globalSearch-instructions-operator-modified": "`__operator_modified__:<n>` - cards which were modified *<n>* days ago or less",
|
||||
"globalSearch-instructions-operator-status": "`__operator_status__:<status>` - where *<status>* is one of the following:",
|
||||
"globalSearch-instructions-status-archived": "`__predicate_archived__` - archived cards",
|
||||
"globalSearch-instructions-status-all": "`__predicate_all__` - all archived and unarchived cards",
|
||||
"globalSearch-instructions-status-ended": "`__predicate_ended__` - cards with an end date",
|
||||
"globalSearch-instructions-status-public": "`__predicate_public__` - cards only in public boards",
|
||||
"globalSearch-instructions-status-private": "`__predicate_private__` - cards only in private boards",
|
||||
"globalSearch-instructions-operator-has": "`__operator_has__:<field>` - where *<field>* is one of `__predicate_attachment__`, `__predicate_checklist__`, `__predicate_description__`, `__predicate_start__`, `__predicate_due__`, `__predicate_end__`, `__predicate_assignee__` or `__predicate_member__`. Placing a `-` in front of *<field>* searches for the absence of a value in that field (e.g. `has:-due` searches for cards without a due date).",
|
||||
"globalSearch-instructions-operator-sort": "`__operator_sort__:<sort-name>` - where *<sort-name>* is one of `__predicate_due__`, `__predicate_created__` or `__predicate_modified__`. For a descending sort, place a `-` in front of the sort name.",
|
||||
"globalSearch-instructions-operator-limit": "`__operator_limit__:<n>` - where *<n>* is a positive integer expressing the number of cards to be displayed per page.",
|
||||
"globalSearch-instructions-notes-1": "Multiple operators may be specified.",
|
||||
"globalSearch-instructions-notes-2": "Similar operators are *OR*ed together. Cards that match any of the conditions will be returned.\n`__operator_list__:Available __operator_list__:Blocked` would return cards contained in any list named *Blocked* or *Available*.",
|
||||
"globalSearch-instructions-notes-3": "Differing operators are *AND*ed together. Only cards that match all of the differing operators are returned. `__operator_list__:Available __operator_label__:red` returns only cards in the list *Available* with a *red* label.",
|
||||
"globalSearch-instructions-notes-3-2": "Days can be specified as a positive or negative integer or using `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` or `__predicate_year__` for the current period.",
|
||||
"globalSearch-instructions-notes-4": "Text searches are case insensitive.",
|
||||
"globalSearch-instructions-notes-5": "By default archived cards are not searched.",
|
||||
"link-to-search": "Link to this search",
|
||||
"excel-font": "Arial",
|
||||
"number": "Number",
|
||||
"label-colors": "Label Colors",
|
||||
"label-names": "Label Names",
|
||||
"archived-at": "archived at",
|
||||
"sort-cards": "Sort Cards",
|
||||
"cardsSortPopup-title": "Sort Cards",
|
||||
"due-date": "Due Date",
|
||||
"server-error": "Server Error",
|
||||
"server-error-troubleshooting": "Please submit the error generated by the server.\nFor a snap installation, run: `sudo snap logs wekan.wekan`\nFor a Docker installation, run: `sudo docker logs wekan-app`",
|
||||
"title-alphabetically": "Title (Alphabetically)",
|
||||
"created-at-newest-first": "Created At (Newest First)",
|
||||
"created-at-oldest-first": "Created At (Oldest First)",
|
||||
"links-heading": "Links",
|
||||
"hide-system-messages-of-all-users": "Hide system messages of all users",
|
||||
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
|
||||
"move-swimlane": "Move Swimlane",
|
||||
"moveSwimlanePopup-title": "Move Swimlane"
|
||||
}
|
||||
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,991 @@
|
||||
{
|
||||
"accept": "پذیرش",
|
||||
"act-activity-notify": "Activity Notification",
|
||||
"act-addAttachment": "added attachment __attachment__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-deleteAttachment": "deleted attachment __attachment__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addSubtask": "added subtask __subtask__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addLabel": "Added label __label__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addedLabel": "Added label __label__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removeLabel": "Removed label __label__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removedLabel": "Removed label __label__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addChecklist": "added checklist __checklist__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addChecklistItem": "added checklist item __checklistItem__ to checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removeChecklist": "removed checklist __checklist__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removeChecklistItem": "removed checklist item __checklistItem__ from checklist __checkList__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-checkedItem": "checked __checklistItem__ of checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-uncheckedItem": "unchecked __checklistItem__ of checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-createBoard": "created board __board__",
|
||||
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
|
||||
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-createCustomField": "created custom field __customField__ at board __board__",
|
||||
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
|
||||
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-createList": "added list __list__ to board __board__",
|
||||
"act-addBoardMember": "added member __member__ to board __board__",
|
||||
"act-archivedBoard": "Board __board__ moved to Archive",
|
||||
"act-archivedCard": "Card __card__ at list __list__ at swimlane __swimlane__ at board __board__ moved to Archive",
|
||||
"act-archivedList": "List __list__ at swimlane __swimlane__ at board __board__ moved to Archive",
|
||||
"act-archivedSwimlane": "Swimlane __swimlane__ at board __board__ moved to Archive",
|
||||
"act-importBoard": "imported board __board__",
|
||||
"act-importCard": "imported card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-importList": "imported list __list__ to swimlane __swimlane__ at board __board__",
|
||||
"act-joinMember": "added member __member__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-moveCard": "moved card __card__ at board __board__ from list __oldList__ at swimlane __oldSwimlane__ to list __list__ at swimlane __swimlane__",
|
||||
"act-moveCardToOtherBoard": "moved card __card__ from list __oldList__ at swimlane __oldSwimlane__ at board __oldBoard__ to list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-removeBoardMember": "removed member __member__ from board __board__",
|
||||
"act-restoredCard": "restored card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-unjoinMember": "removed member __member__ from card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"act-withBoardTitle": "__board__",
|
||||
"act-withCardTitle": "[__board__] __card__",
|
||||
"actions": "Actions",
|
||||
"activities": "Activities",
|
||||
"activity": "Activity",
|
||||
"activity-added": "added %s to %s",
|
||||
"activity-archived": "%s moved to Archive",
|
||||
"activity-attached": "attached %s to %s",
|
||||
"activity-created": "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-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-checked-item": "checked %s in checklist %s of %s",
|
||||
"activity-unchecked-item": "unchecked %s in checklist %s of %s",
|
||||
"activity-checklist-added": "added checklist to %s",
|
||||
"activity-checklist-removed": "removed a checklist from %s",
|
||||
"activity-checklist-completed": "completed checklist %s of %s",
|
||||
"activity-checklist-uncompleted": "uncompleted the checklist %s of %s",
|
||||
"activity-checklist-item-added": "added checklist item to '%s' in %s",
|
||||
"activity-checklist-item-removed": "removed a checklist item from '%s' in %s",
|
||||
"add": "Add",
|
||||
"activity-checked-item-card": "checked %s in checklist %s",
|
||||
"activity-unchecked-item-card": "unchecked %s in checklist %s",
|
||||
"activity-checklist-completed-card": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
|
||||
"activity-checklist-uncompleted-card": "uncompleted the checklist %s",
|
||||
"activity-editComment": "edited comment %s",
|
||||
"activity-deleteComment": "deleted comment %s",
|
||||
"activity-receivedDate": "edited received date to %s of %s",
|
||||
"activity-startDate": "edited start date to %s of %s",
|
||||
"activity-dueDate": "edited due date to %s of %s",
|
||||
"activity-endDate": "edited end date to %s of %s",
|
||||
"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": "Loading, please wait. Refreshing the page will cause data loss. If loading does not work, please check that server has not stopped.",
|
||||
"archive": "Move to Archive",
|
||||
"archive-all": "Move All to Archive",
|
||||
"archive-board": "Move Board to Archive",
|
||||
"archive-card": "Move Card to Archive",
|
||||
"archive-list": "Move List to Archive",
|
||||
"archive-swimlane": "Move Swimlane to Archive",
|
||||
"archive-selection": "Move selection to Archive",
|
||||
"archiveBoardPopup-title": "Move Board to Archive?",
|
||||
"archived-items": "Archive",
|
||||
"archived-boards": "Boards in Archive",
|
||||
"restore-board": "Restore Board",
|
||||
"no-archived-boards": "No Boards in Archive.",
|
||||
"archives": "Archive",
|
||||
"template": "Template",
|
||||
"templates": "Templates",
|
||||
"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 (520KB 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 Settings",
|
||||
"boardChangeViewPopup-title": "Board View",
|
||||
"boards": "Boards",
|
||||
"board-view": "Board View",
|
||||
"board-view-cal": "Calendar",
|
||||
"board-view-swimlanes": "Swimlanes",
|
||||
"board-view-collapse": "Collapse",
|
||||
"board-view-gantt": "Gantt",
|
||||
"board-view-lists": "Lists",
|
||||
"bucket-example": "Like “Bucket List” for example",
|
||||
"cancel": "Cancel",
|
||||
"card-archived": "This card is moved to Archive.",
|
||||
"board-archived": "This board is moved to Archive.",
|
||||
"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 Archive 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",
|
||||
"cardStartVotingPopup-title": "Start a vote",
|
||||
"positiveVoteMembersPopup-title": "Proponents",
|
||||
"negativeVoteMembersPopup-title": "Opponents",
|
||||
"card-edit-voting": "Edit voting",
|
||||
"editVoteEndDatePopup-title": "Change vote end date",
|
||||
"allowNonBoardMembers": "Allow all logged in users",
|
||||
"vote-question": "Voting question",
|
||||
"vote-public": "Show who voted what",
|
||||
"vote-for-it": "for it",
|
||||
"vote-against": "against",
|
||||
"deleteVotePopup-title": "Delete vote?",
|
||||
"vote-delete-pop": "Deleting is permanent. You will lose all actions associated with this vote.",
|
||||
"cardDeletePopup-title": "Delete Card?",
|
||||
"cardDetailsActionsPopup-title": "Card Actions",
|
||||
"cardLabelsPopup-title": "Labels",
|
||||
"cardMembersPopup-title": "Members",
|
||||
"cardMorePopup-title": "More",
|
||||
"cardTemplatePopup-title": "Create template",
|
||||
"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",
|
||||
"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",
|
||||
"close-board-pop": "You will be able to restore the board by clicking the “Archive” button from the home header.",
|
||||
"color-black": "black",
|
||||
"color-blue": "blue",
|
||||
"color-crimson": "crimson",
|
||||
"color-darkgreen": "darkgreen",
|
||||
"color-gold": "gold",
|
||||
"color-gray": "gray",
|
||||
"color-green": "green",
|
||||
"color-indigo": "indigo",
|
||||
"color-lime": "lime",
|
||||
"color-magenta": "magenta",
|
||||
"color-mistyrose": "mistyrose",
|
||||
"color-navy": "navy",
|
||||
"color-orange": "orange",
|
||||
"color-paleturquoise": "paleturquoise",
|
||||
"color-peachpuff": "peachpuff",
|
||||
"color-pink": "pink",
|
||||
"color-plum": "plum",
|
||||
"color-purple": "purple",
|
||||
"color-red": "red",
|
||||
"color-saddlebrown": "saddlebrown",
|
||||
"color-silver": "silver",
|
||||
"color-sky": "sky",
|
||||
"color-slateblue": "slateblue",
|
||||
"color-white": "white",
|
||||
"color-yellow": "yellow",
|
||||
"unset-color": "Unset",
|
||||
"comment": "Comment",
|
||||
"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.",
|
||||
"worker": "Worker",
|
||||
"worker-desc": "Can only move cards, assign itself to card and comment.",
|
||||
"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",
|
||||
"searchElementPopup-title": "Search",
|
||||
"copyCardPopup-title": "Copy Card",
|
||||
"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-currency": "Currency",
|
||||
"custom-field-currency-option": "Currency Code",
|
||||
"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",
|
||||
"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-csv-schema": "Your CSV(Comma Separated Values)/TSV (Tab Separated Values) 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-orgname-taken": "This organization name is already taken",
|
||||
"error-teamname-taken": "This team name is already taken",
|
||||
"error-email-taken": "Email has already been taken",
|
||||
"export-board": "Export board",
|
||||
"export-board-json": "Export board to JSON",
|
||||
"export-board-csv": "Export board to CSV",
|
||||
"export-board-tsv": "Export board to TSV",
|
||||
"export-board-excel": "Export board to Excel",
|
||||
"user-can-not-export-excel": "User can not export Excel",
|
||||
"export-board-html": "Export board to HTML",
|
||||
"exportBoardPopup-title": "Export board",
|
||||
"sort": "Sort",
|
||||
"sort-desc": "Click to Sort List",
|
||||
"list-sort-by": "Sort the List By:",
|
||||
"list-label-modifiedAt": "Last Access Time",
|
||||
"list-label-title": "Name of the List",
|
||||
"list-label-sort": "Your Manual Order",
|
||||
"list-label-short-modifiedAt": "(L)",
|
||||
"list-label-short-title": "(N)",
|
||||
"list-label-short-sort": "(M)",
|
||||
"filter": "Filter",
|
||||
"filter-cards": "Filter Cards or Lists",
|
||||
"list-filter-label": "Filter List by Title",
|
||||
"filter-clear": "Clear filter",
|
||||
"filter-labels-label": "Filter by label",
|
||||
"filter-no-label": "No label",
|
||||
"filter-member-label": "Filter by member",
|
||||
"filter-no-member": "No member",
|
||||
"filter-assignee-label": "Filter by assignee",
|
||||
"filter-no-assignee": "No assignee",
|
||||
"filter-custom-fields-label": "Filter by Custom Fields",
|
||||
"filter-no-custom-fields": "No Custom Fields",
|
||||
"filter-show-archive": "Show archived lists",
|
||||
"filter-hide-empty": "Hide empty lists",
|
||||
"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",
|
||||
"other-filters-label": "Other Filters",
|
||||
"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",
|
||||
"impersonate-user": "Impersonate user",
|
||||
"link": "Link",
|
||||
"import-board": "import board",
|
||||
"import-board-c": "Import board",
|
||||
"import-board-title-trello": "Import board from Trello",
|
||||
"import-board-title-wekan": "Import board from previous export",
|
||||
"import-board-title-csv": "Import board from CSV/TSV",
|
||||
"from-trello": "From Trello",
|
||||
"from-wekan": "From previous export",
|
||||
"from-csv": "From CSV/TSV",
|
||||
"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-csv": "Paste in your Comma Separated Values(CSV)/ Tab Separated Values (TSV) .",
|
||||
"import-board-instruction-wekan": "In your board, go to 'Menu', then 'Export board', and copy the text in the downloaded file.",
|
||||
"import-board-instruction-about-errors": "If you get errors when importing board, sometimes importing still works, and board is at All Boards page.",
|
||||
"import-json-placeholder": "Paste your valid JSON data here",
|
||||
"import-csv-placeholder": "Paste your valid CSV/TSV 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 your users",
|
||||
"import-members-map-note": "Note: Unmapped members will be assigned to the current user.",
|
||||
"import-show-user-mapping": "Review members mapping",
|
||||
"import-user-select": "Pick your existing user you want to use as this member",
|
||||
"importMapMembersAddPopup-title": "Select 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 Archive",
|
||||
"list-archive-cards-pop": "This will remove all the cards in this list from the board. To view cards in Archive and bring them back to the board, click “Menu” > “Archive”.",
|
||||
"list-move-cards": "Move all cards in this list",
|
||||
"list-select-cards": "Select all cards in this list",
|
||||
"set-color-list": "Set Color",
|
||||
"listActionPopup-title": "List Actions",
|
||||
"settingsUserPopup-title": "User Settings",
|
||||
"swimlaneActionPopup-title": "Swimlane Actions",
|
||||
"swimlaneAddPopup-title": "Add a Swimlane below",
|
||||
"listImportCardPopup-title": "Import a Trello card",
|
||||
"listImportCardsTsvPopup-title": "Import Excel CSV/TSV",
|
||||
"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 Archive 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-label": "Set label for selection",
|
||||
"multi-selection-member": "Set member for 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 Archive.",
|
||||
"no-archived-lists": "No lists in Archive.",
|
||||
"no-archived-swimlanes": "No swimlanes in Archive.",
|
||||
"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",
|
||||
"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",
|
||||
"rules": "Rules",
|
||||
"search-cards": "Search from card/list titles, descriptions and custom fields on this board",
|
||||
"search-example": "Write text you search and press Enter",
|
||||
"select-color": "Select Color",
|
||||
"select-board": "Select Board",
|
||||
"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",
|
||||
"shortcut-show-shortcuts": "Bring up this shortcuts list",
|
||||
"shortcut-toggle-filterbar": "Toggle Filter Sidebar",
|
||||
"shortcut-toggle-searchbar": "Toggle Search 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",
|
||||
"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",
|
||||
"custom-top-left-corner-logo-image-url": "Custom Top Left Corner Logo Image URL",
|
||||
"custom-top-left-corner-logo-link-url": "Custom Top Left Corner Logo Link URL",
|
||||
"custom-top-left-corner-logo-height": "Custom Top Left Corner Logo Height. Default: 27",
|
||||
"custom-login-logo-image-url": "Custom Login Logo Image URL",
|
||||
"custom-login-logo-link-url": "Custom Login Logo Link URL",
|
||||
"text-below-custom-login-logo": "Text below Custom Login Logo",
|
||||
"automatic-linked-url-schemes": "Custom URL Schemes which should automatically be clickable. One URL Scheme per line",
|
||||
"username": "Username",
|
||||
"import-usernames": "Import Usernames",
|
||||
"view-it": "View it",
|
||||
"warn-list-archived": "warning: this card is in an list at Archive",
|
||||
"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",
|
||||
"card-templates-swimlane": "Card Templates",
|
||||
"list-templates-swimlane": "List Templates",
|
||||
"board-templates-swimlane": "Board Templates",
|
||||
"what-to-do": "What do you want to do?",
|
||||
"wipLimitErrorPopup-title": "Invalid WIP Limit",
|
||||
"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",
|
||||
"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-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 kanban board for collaborations.\n\nPlease follow the link below:\n__url__\n\nAnd your invitation code is: __icode__\n\nThanks.",
|
||||
"email-smtp-test-subject": "SMTP Test Email",
|
||||
"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.",
|
||||
"webhook-title": "Webhook Name",
|
||||
"webhook-token": "Token (Optional for Authentication)",
|
||||
"outgoing-webhooks": "Outgoing Webhooks",
|
||||
"bidirectional-webhooks": "Two-Way Webhooks",
|
||||
"outgoingWebhooksPopup-title": "Outgoing Webhooks",
|
||||
"boardCardTitlePopup-title": "Card Title Filter",
|
||||
"disable-webhook": "Disable This Webhook",
|
||||
"global-webhook": "Global Webhooks",
|
||||
"new-outgoing-webhook": "New Outgoing Webhook",
|
||||
"no-name": "(Unknown)",
|
||||
"Node_version": "Node version",
|
||||
"Meteor_version": "Meteor version",
|
||||
"MongoDB_version": "MongoDB version",
|
||||
"MongoDB_storage_engine": "MongoDB storage engine",
|
||||
"MongoDB_Oplog_enabled": "MongoDB Oplog enabled",
|
||||
"OS_Arch": "OS Arch",
|
||||
"OS_Cpus": "OS CPU Count",
|
||||
"OS_Freemem": "OS Free Memory",
|
||||
"OS_Loadavg": "OS Load Average",
|
||||
"OS_Platform": "OS Platform",
|
||||
"OS_Release": "OS Release",
|
||||
"OS_Totalmem": "OS Total Memory",
|
||||
"OS_Type": "OS Type",
|
||||
"OS_Uptime": "OS Uptime",
|
||||
"days": "days",
|
||||
"hours": "hours",
|
||||
"minutes": "minutes",
|
||||
"seconds": "seconds",
|
||||
"show-field-on-card": "Show this field on card",
|
||||
"automatically-field-on-card": "Add field to new cards",
|
||||
"always-field-on-card": "Add field to all cards",
|
||||
"showLabel-field-on-card": "Show field label on minicard",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"accounts": "Accounts",
|
||||
"accounts-allowEmailChange": "Allow Email Change",
|
||||
"accounts-allowUserNameChange": "Allow Username Change",
|
||||
"createdAt": "Created at",
|
||||
"modifiedAt": "Modified at",
|
||||
"verified": "Verified",
|
||||
"active": "Active",
|
||||
"card-received": "Received",
|
||||
"card-received-on": "Received on",
|
||||
"card-end": "End",
|
||||
"card-end-on": "Ends on",
|
||||
"editCardReceivedDatePopup-title": "Change received date",
|
||||
"editCardEndDatePopup-title": "Change end date",
|
||||
"setCardColorPopup-title": "Set color",
|
||||
"setCardActionsColorPopup-title": "Choose a color",
|
||||
"setSwimlaneColorPopup-title": "Choose a color",
|
||||
"setListColorPopup-title": "Choose a color",
|
||||
"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",
|
||||
"card-settings": "Card Settings",
|
||||
"boardSubtaskSettingsPopup-title": "Board Subtasks Settings",
|
||||
"boardCardSettingsPopup-title": "Card Settings",
|
||||
"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",
|
||||
"activity-added-label": "added label '%s' to %s",
|
||||
"activity-removed-label": "removed label '%s' from %s",
|
||||
"activity-delete-attach": "deleted an attachment from %s",
|
||||
"activity-added-label-card": "added label '%s'",
|
||||
"activity-removed-label-card": "removed label '%s'",
|
||||
"activity-delete-attach-card": "deleted an attachment",
|
||||
"activity-set-customfield": "set custom field '%s' to '%s' in %s",
|
||||
"activity-unset-customfield": "unset custom field '%s' in %s",
|
||||
"r-rule": "Rule",
|
||||
"r-add-trigger": "Add trigger",
|
||||
"r-add-action": "Add action",
|
||||
"r-board-rules": "Board rules",
|
||||
"r-add-rule": "Add rule",
|
||||
"r-view-rule": "View rule",
|
||||
"r-delete-rule": "Delete rule",
|
||||
"r-new-rule-name": "New rule title",
|
||||
"r-no-rules": "No rules",
|
||||
"r-trigger": "Trigger",
|
||||
"r-action": "Action",
|
||||
"r-when-a-card": "When a card",
|
||||
"r-is": "is",
|
||||
"r-is-moved": "is moved",
|
||||
"r-added-to": "Added to",
|
||||
"r-removed-from": "Removed from",
|
||||
"r-the-board": "the board",
|
||||
"r-list": "list",
|
||||
"list": "List",
|
||||
"set-filter": "Set Filter",
|
||||
"r-moved-to": "Moved to",
|
||||
"r-moved-from": "Moved from",
|
||||
"r-archived": "Moved to Archive",
|
||||
"r-unarchived": "Restored from Archive",
|
||||
"r-a-card": "a card",
|
||||
"r-when-a-label-is": "When a label is",
|
||||
"r-when-the-label": "When the label",
|
||||
"r-list-name": "list name",
|
||||
"r-when-a-member": "When a member is",
|
||||
"r-when-the-member": "When the member",
|
||||
"r-name": "name",
|
||||
"r-when-a-attach": "When an attachment",
|
||||
"r-when-a-checklist": "When a checklist is",
|
||||
"r-when-the-checklist": "When the checklist",
|
||||
"r-completed": "Completed",
|
||||
"r-made-incomplete": "Made incomplete",
|
||||
"r-when-a-item": "When a checklist item is",
|
||||
"r-when-the-item": "When the checklist item",
|
||||
"r-checked": "Checked",
|
||||
"r-unchecked": "Unchecked",
|
||||
"r-move-card-to": "Move card to",
|
||||
"r-top-of": "Top of",
|
||||
"r-bottom-of": "Bottom of",
|
||||
"r-its-list": "its list",
|
||||
"r-archive": "Move to Archive",
|
||||
"r-unarchive": "Restore from Archive",
|
||||
"r-card": "card",
|
||||
"r-add": "Add",
|
||||
"r-remove": "Remove",
|
||||
"r-label": "label",
|
||||
"r-member": "member",
|
||||
"r-remove-all": "Remove all members from the card",
|
||||
"r-set-color": "Set color to",
|
||||
"r-checklist": "checklist",
|
||||
"r-check-all": "Check all",
|
||||
"r-uncheck-all": "Uncheck all",
|
||||
"r-items-check": "items of checklist",
|
||||
"r-check": "Check",
|
||||
"r-uncheck": "Uncheck",
|
||||
"r-item": "item",
|
||||
"r-of-checklist": "of checklist",
|
||||
"r-send-email": "Send an email",
|
||||
"r-to": "to",
|
||||
"r-of": "of",
|
||||
"r-subject": "subject",
|
||||
"r-rule-details": "Rule details",
|
||||
"r-d-move-to-top-gen": "Move card to top of its list",
|
||||
"r-d-move-to-top-spec": "Move card to top of list",
|
||||
"r-d-move-to-bottom-gen": "Move card to bottom of its list",
|
||||
"r-d-move-to-bottom-spec": "Move card to bottom of list",
|
||||
"r-d-send-email": "Send email",
|
||||
"r-d-send-email-to": "to",
|
||||
"r-d-send-email-subject": "subject",
|
||||
"r-d-send-email-message": "message",
|
||||
"r-d-archive": "Move card to Archive",
|
||||
"r-d-unarchive": "Restore card from Archive",
|
||||
"r-d-add-label": "Add label",
|
||||
"r-d-remove-label": "Remove label",
|
||||
"r-create-card": "Create new card",
|
||||
"r-in-list": "in list",
|
||||
"r-in-swimlane": "in swimlane",
|
||||
"r-d-add-member": "Add member",
|
||||
"r-d-remove-member": "Remove member",
|
||||
"r-d-remove-all-member": "Remove all member",
|
||||
"r-d-check-all": "Check all items of a list",
|
||||
"r-d-uncheck-all": "Uncheck all items of a list",
|
||||
"r-d-check-one": "Check item",
|
||||
"r-d-uncheck-one": "Uncheck item",
|
||||
"r-d-check-of-list": "of checklist",
|
||||
"r-d-add-checklist": "Add checklist",
|
||||
"r-d-remove-checklist": "Remove checklist",
|
||||
"r-by": "by",
|
||||
"r-add-checklist": "Add checklist",
|
||||
"r-with-items": "with items",
|
||||
"r-items-list": "item1,item2,item3",
|
||||
"r-add-swimlane": "Add swimlane",
|
||||
"r-swimlane-name": "swimlane name",
|
||||
"r-board-note": "Note: leave a field empty to match every possible value.",
|
||||
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
|
||||
"r-when-a-card-is-moved": "When a card is moved to another list",
|
||||
"r-set": "Set",
|
||||
"r-update": "Update",
|
||||
"r-datefield": "date field",
|
||||
"r-df-start-at": "start",
|
||||
"r-df-due-at": "due",
|
||||
"r-df-end-at": "end",
|
||||
"r-df-received-at": "received",
|
||||
"r-to-current-datetime": "to current date/time",
|
||||
"r-remove-value-from": "Remove value from",
|
||||
"ldap": "LDAP",
|
||||
"oauth2": "OAuth2",
|
||||
"cas": "CAS",
|
||||
"authentication-method": "Authentication method",
|
||||
"authentication-type": "Authentication type",
|
||||
"custom-product-name": "Custom Product Name",
|
||||
"layout": "Layout",
|
||||
"hide-logo": "Hide Logo",
|
||||
"add-custom-html-after-body-start": "Add Custom HTML after <body> start",
|
||||
"add-custom-html-before-body-end": "Add Custom HTML before </body> end",
|
||||
"error-undefined": "Something went wrong",
|
||||
"error-ldap-login": "An error occurred while trying to login",
|
||||
"display-authentication-method": "Display Authentication Method",
|
||||
"default-authentication-method": "Default Authentication Method",
|
||||
"duplicate-board": "Duplicate Board",
|
||||
"org-number": "The number of organizations is:",
|
||||
"team-number": "The number of teams is:",
|
||||
"people-number": "The number of people is:",
|
||||
"swimlaneDeletePopup-title": "Delete Swimlane ?",
|
||||
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
|
||||
"restore-all": "Restore all",
|
||||
"delete-all": "Delete all",
|
||||
"loading": "Loading, please wait.",
|
||||
"previous_as": "last time was",
|
||||
"act-a-dueAt": "modified due time to \nWhen: __timeValue__\nWhere: __card__\n previous due was __timeOldValue__",
|
||||
"act-a-endAt": "modified ending time to __timeValue__ from (__timeOldValue__)",
|
||||
"act-a-startAt": "modified starting time to __timeValue__ from (__timeOldValue__)",
|
||||
"act-a-receivedAt": "modified received time to __timeValue__ from (__timeOldValue__)",
|
||||
"a-dueAt": "modified due time to be",
|
||||
"a-endAt": "modified ending time to be",
|
||||
"a-startAt": "modified starting time to be",
|
||||
"a-receivedAt": "modified received time to be",
|
||||
"almostdue": "current due time %s is approaching",
|
||||
"pastdue": "current due time %s is past",
|
||||
"duenow": "current due time %s is today",
|
||||
"act-newDue": "__list__/__card__ has 1st due reminder [__board__]",
|
||||
"act-withDue": "__list__/__card__ due reminders [__board__]",
|
||||
"act-almostdue": "was reminding the current due (__timeValue__) of __card__ is approaching",
|
||||
"act-pastdue": "was reminding the current due (__timeValue__) of __card__ is past",
|
||||
"act-duenow": "was reminding the current due (__timeValue__) of __card__ is now",
|
||||
"act-atUserComment": "You were mentioned in [__board__] __list__/__card__",
|
||||
"delete-user-confirm-popup": "Are you sure you want to delete this account? There is no undo.",
|
||||
"accounts-allowUserDelete": "Allow users to self delete their account",
|
||||
"hide-minicard-label-text": "Hide minicard label text",
|
||||
"show-desktop-drag-handles": "Show desktop drag handles",
|
||||
"assignee": "Assignee",
|
||||
"cardAssigneesPopup-title": "Assignee",
|
||||
"addmore-detail": "Add a more detailed description",
|
||||
"show-on-card": "Show on Card",
|
||||
"new": "New",
|
||||
"editOrgPopup-title": "Edit Organization",
|
||||
"newOrgPopup-title": "New Organization",
|
||||
"editTeamPopup-title": "Edit Team",
|
||||
"newTeamPopup-title": "New Team",
|
||||
"editUserPopup-title": "Edit User",
|
||||
"newUserPopup-title": "New User",
|
||||
"notifications": "Notifications",
|
||||
"view-all": "View All",
|
||||
"filter-by-unread": "Filter by Unread",
|
||||
"mark-all-as-read": "Mark all as read",
|
||||
"remove-all-read": "Remove all read",
|
||||
"allow-rename": "Allow Rename",
|
||||
"allowRenamePopup-title": "Allow Rename",
|
||||
"start-day-of-week": "Set day of the week start",
|
||||
"monday": "Monday",
|
||||
"tuesday": "Tuesday",
|
||||
"wednesday": "Wednesday",
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"saturday": "Saturday",
|
||||
"sunday": "Sunday",
|
||||
"status": "Status",
|
||||
"swimlane": "Swimlane",
|
||||
"owner": "Owner",
|
||||
"last-modified-at": "Last modified at",
|
||||
"last-activity": "Last activity",
|
||||
"voting": "Voting",
|
||||
"archived": "Archived",
|
||||
"delete-linked-card-before-this-card": "You can not delete this card before first deleting linked card that has",
|
||||
"delete-linked-cards-before-this-list": "You can not delete this list before first deleting linked cards that are pointing to cards in this list",
|
||||
"hide-checked-items": "Hide checked items",
|
||||
"task": "Task",
|
||||
"create-task": "Create Task",
|
||||
"ok": "OK",
|
||||
"organizations": "Organizations",
|
||||
"teams": "Teams",
|
||||
"displayName": "Display Name",
|
||||
"shortName": "Short Name",
|
||||
"website": "Website",
|
||||
"person": "Person",
|
||||
"my-cards": "My Cards",
|
||||
"card": "Card",
|
||||
"board": "Board",
|
||||
"context-separator": "/",
|
||||
"myCardsSortChange-title": "My Cards Sort",
|
||||
"myCardsSortChangePopup-title": "My Cards Sort",
|
||||
"myCardsSortChange-choice-board": "By Board",
|
||||
"myCardsSortChange-choice-dueat": "By Due Date",
|
||||
"dueCards-title": "Due Cards",
|
||||
"dueCardsViewChange-title": "Due Cards View",
|
||||
"dueCardsViewChangePopup-title": "Due Cards View",
|
||||
"dueCardsViewChange-choice-me": "Me",
|
||||
"dueCardsViewChange-choice-all": "All Users",
|
||||
"dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.",
|
||||
"broken-cards": "Broken Cards",
|
||||
"board-title-not-found": "Board '%s' not found.",
|
||||
"swimlane-title-not-found": "Swimlane '%s' not found.",
|
||||
"list-title-not-found": "List '%s' not found.",
|
||||
"label-not-found": "Label '%s' not found.",
|
||||
"label-color-not-found": "Label color %s not found.",
|
||||
"user-username-not-found": "Username '%s' not found.",
|
||||
"comment-not-found": "Card with comment containing text '%s' not found.",
|
||||
"globalSearch-title": "Search All Boards",
|
||||
"no-cards-found": "No Cards Found",
|
||||
"one-card-found": "One Card Found",
|
||||
"n-cards-found": "%s Cards Found",
|
||||
"n-n-of-n-cards-found": "__start__-__end__ of __total__ Cards Found",
|
||||
"operator-board": "board",
|
||||
"operator-board-abbrev": "b",
|
||||
"operator-swimlane": "swimlane",
|
||||
"operator-swimlane-abbrev": "s",
|
||||
"operator-list": "list",
|
||||
"operator-list-abbrev": "l",
|
||||
"operator-label": "label",
|
||||
"operator-label-abbrev": "#",
|
||||
"operator-user": "user",
|
||||
"operator-user-abbrev": "@",
|
||||
"operator-member": "member",
|
||||
"operator-member-abbrev": "m",
|
||||
"operator-assignee": "assignee",
|
||||
"operator-assignee-abbrev": "a",
|
||||
"operator-status": "status",
|
||||
"operator-due": "due",
|
||||
"operator-created": "created",
|
||||
"operator-modified": "modified",
|
||||
"operator-sort": "sort",
|
||||
"operator-comment": "comment",
|
||||
"operator-has": "has",
|
||||
"operator-limit": "limit",
|
||||
"predicate-archived": "archived",
|
||||
"predicate-open": "open",
|
||||
"predicate-ended": "ended",
|
||||
"predicate-all": "all",
|
||||
"predicate-overdue": "overdue",
|
||||
"predicate-week": "week",
|
||||
"predicate-month": "month",
|
||||
"predicate-quarter": "quarter",
|
||||
"predicate-year": "year",
|
||||
"predicate-due": "due",
|
||||
"predicate-modified": "modified",
|
||||
"predicate-created": "created",
|
||||
"predicate-attachment": "attachment",
|
||||
"predicate-description": "description",
|
||||
"predicate-checklist": "checklist",
|
||||
"predicate-start": "start",
|
||||
"predicate-end": "end",
|
||||
"predicate-assignee": "assignee",
|
||||
"predicate-member": "member",
|
||||
"predicate-public": "public",
|
||||
"predicate-private": "private",
|
||||
"operator-unknown-error": "%s is not an operator",
|
||||
"operator-number-expected": "operator __operator__ expected a number, got '__value__'",
|
||||
"operator-sort-invalid": "sort of '%s' is invalid",
|
||||
"operator-status-invalid": "'%s' is not a valid status",
|
||||
"operator-has-invalid": "%s is not a valid existence check",
|
||||
"operator-limit-invalid": "%s is not a valid limit. Limit should be a positive integer.",
|
||||
"next-page": "Next Page",
|
||||
"previous-page": "Previous Page",
|
||||
"heading-notes": "Notes",
|
||||
"globalSearch-instructions-heading": "Search Instructions",
|
||||
"globalSearch-instructions-description": "Searches can include operators to refine the search. Operators are specified by writing the operator name and value separated by a colon. For example, an operator specification of `list:Blocked` would limit the search to cards that are contained in a list named *Blocked*. If the value contains spaces or special characters it must be enclosed in quotation marks (e.g. `__operator_list__:\"To Review\"`).",
|
||||
"globalSearch-instructions-operators": "Available operators:",
|
||||
"globalSearch-instructions-operator-board": "`__operator_board__:<title>` - cards in boards matching the specified *<title>*",
|
||||
"globalSearch-instructions-operator-list": "`__operator_list__:<title>` - cards in lists matching the specified *<title>*",
|
||||
"globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<title>` - cards in swimlanes matching the specified *<title>*",
|
||||
"globalSearch-instructions-operator-comment": "`__operator_comment__:<text>` - cards with a comment containing *<text>*.",
|
||||
"globalSearch-instructions-operator-label": "`__operator_label__:<color>` `__operator_label__:<name>` - cards that have a label matching *<color>* or *<name>",
|
||||
"globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<name|color>` - shorthand for `__operator_label__:<color>` or `__operator_label__:<name>`",
|
||||
"globalSearch-instructions-operator-user": "`__operator_user__:<username>` - cards where *<username>* is a *member* or *assignee*",
|
||||
"globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - shorthand for `user:<username>`",
|
||||
"globalSearch-instructions-operator-member": "`__operator_member__:<username>` - cards where *<username>* is a *member*",
|
||||
"globalSearch-instructions-operator-assignee": "`__operator_assignee__:<username>` - cards where *<username>* is an *assignee*",
|
||||
"globalSearch-instructions-operator-due": "`__operator_due__:<n>` - cards which are due up to *<n>* days from now. `__operator_due__:__predicate_overdue__ lists all cards past their due date.",
|
||||
"globalSearch-instructions-operator-created": "`__operator_created__:<n>` - cards which were created *<n>* days ago or less",
|
||||
"globalSearch-instructions-operator-modified": "`__operator_modified__:<n>` - cards which were modified *<n>* days ago or less",
|
||||
"globalSearch-instructions-operator-status": "`__operator_status__:<status>` - where *<status>* is one of the following:",
|
||||
"globalSearch-instructions-status-archived": "`__predicate_archived__` - archived cards",
|
||||
"globalSearch-instructions-status-all": "`__predicate_all__` - all archived and unarchived cards",
|
||||
"globalSearch-instructions-status-ended": "`__predicate_ended__` - cards with an end date",
|
||||
"globalSearch-instructions-status-public": "`__predicate_public__` - cards only in public boards",
|
||||
"globalSearch-instructions-status-private": "`__predicate_private__` - cards only in private boards",
|
||||
"globalSearch-instructions-operator-has": "`__operator_has__:<field>` - where *<field>* is one of `__predicate_attachment__`, `__predicate_checklist__`, `__predicate_description__`, `__predicate_start__`, `__predicate_due__`, `__predicate_end__`, `__predicate_assignee__` or `__predicate_member__`. Placing a `-` in front of *<field>* searches for the absence of a value in that field (e.g. `has:-due` searches for cards without a due date).",
|
||||
"globalSearch-instructions-operator-sort": "`__operator_sort__:<sort-name>` - where *<sort-name>* is one of `__predicate_due__`, `__predicate_created__` or `__predicate_modified__`. For a descending sort, place a `-` in front of the sort name.",
|
||||
"globalSearch-instructions-operator-limit": "`__operator_limit__:<n>` - where *<n>* is a positive integer expressing the number of cards to be displayed per page.",
|
||||
"globalSearch-instructions-notes-1": "Multiple operators may be specified.",
|
||||
"globalSearch-instructions-notes-2": "Similar operators are *OR*ed together. Cards that match any of the conditions will be returned.\n`__operator_list__:Available __operator_list__:Blocked` would return cards contained in any list named *Blocked* or *Available*.",
|
||||
"globalSearch-instructions-notes-3": "Differing operators are *AND*ed together. Only cards that match all of the differing operators are returned. `__operator_list__:Available __operator_label__:red` returns only cards in the list *Available* with a *red* label.",
|
||||
"globalSearch-instructions-notes-3-2": "Days can be specified as a positive or negative integer or using `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` or `__predicate_year__` for the current period.",
|
||||
"globalSearch-instructions-notes-4": "Text searches are case insensitive.",
|
||||
"globalSearch-instructions-notes-5": "By default archived cards are not searched.",
|
||||
"link-to-search": "Link to this search",
|
||||
"excel-font": "Arial",
|
||||
"number": "Number",
|
||||
"label-colors": "Label Colors",
|
||||
"label-names": "Label Names",
|
||||
"archived-at": "archived at",
|
||||
"sort-cards": "Sort Cards",
|
||||
"cardsSortPopup-title": "Sort Cards",
|
||||
"due-date": "Due Date",
|
||||
"server-error": "Server Error",
|
||||
"server-error-troubleshooting": "Please submit the error generated by the server.\nFor a snap installation, run: `sudo snap logs wekan.wekan`\nFor a Docker installation, run: `sudo docker logs wekan-app`",
|
||||
"title-alphabetically": "Title (Alphabetically)",
|
||||
"created-at-newest-first": "Created At (Newest First)",
|
||||
"created-at-oldest-first": "Created At (Oldest First)",
|
||||
"links-heading": "Links",
|
||||
"hide-system-messages-of-all-users": "Hide system messages of all users",
|
||||
"now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
|
||||
"move-swimlane": "Move Swimlane",
|
||||
"moveSwimlanePopup-title": "Move Swimlane"
|
||||
}
|
||||
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
+990
-953
File diff suppressed because it is too large.
Load diff
Loaded 100 of 201 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user