Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
833f19a5cd | ||
|
|
174ffd0967 | ||
|
|
c4f0229373 | ||
|
|
a54bb91bba | ||
|
|
f78a8f2b55 | ||
|
|
be4b2a0504 | ||
|
|
c74934836f | ||
|
|
ec35c544b7 | ||
|
|
2bd48bc45c | ||
|
|
67ecee8322 | ||
|
|
a7b8611c70 | ||
|
|
dacaea7443 | ||
|
|
a7f7e00a14 | ||
|
|
5db3dcf8da | ||
|
|
66e011c71b | ||
|
|
d2ea240ed4 | ||
|
|
61bc6d3b7a | ||
|
|
f414fe447d | ||
|
|
98e3b0ce77 | ||
|
|
84ba42f42e | ||
|
|
7cc1ffcab2 | ||
|
|
669cd76018 | ||
|
|
8108158573 | ||
|
|
268f9de23c | ||
|
|
9fc7d0e825 | ||
|
|
ea1cdf52dd | ||
|
|
7cf6850cdf | ||
|
|
231fee52d2 | ||
|
|
1da198f3bc | ||
|
|
fff144a827 | ||
|
|
85ca2b1363 | ||
|
|
4d4399e95f | ||
|
|
05b153f9cc | ||
|
|
4aba290358 | ||
|
|
6a190589f5 | ||
|
|
6218da4c53 | ||
|
|
bdeb941682 | ||
|
|
2c042e7f11 | ||
|
|
8f899fca72 | ||
|
|
5f56ba4fb9 | ||
|
|
b50dd68030 | ||
|
|
95698911f9 | ||
|
|
156c8aa75b | ||
|
|
7df6f305c5 | ||
|
|
f34197b8d2 | ||
|
|
2483b8dbe3 | ||
|
|
0c8f13e1d9 | ||
|
|
85084e1808 | ||
|
|
d87920f556 | ||
|
|
4b5e6aa893 | ||
|
|
a5c1395c46 | ||
|
|
c48d5a73ca | ||
|
|
a68c928896 | ||
|
|
2eae236c5a | ||
|
|
0db5c1b8fa | ||
|
|
3632f4c8ab | ||
|
|
62bfe1da21 | ||
|
|
0291bcde17 | ||
|
|
e3e504310a | ||
|
|
ff23c54fd5 | ||
|
|
4cc2f7411c | ||
|
|
41e5478cb3 | ||
|
|
14d7e4d20c | ||
|
|
e24925c27f | ||
|
|
8ec98ef00c | ||
|
|
be44fb8aea | ||
|
|
f06098f3dd | ||
|
|
b30dc8d4f2 | ||
|
|
57f7af5f90 | ||
|
|
510a20133c | ||
|
|
3bd0f6f911 | ||
|
|
66b45ed35c | ||
|
|
34bd1e9c49 | ||
|
|
007c4fc003 | ||
|
|
ec80acf36b | ||
|
|
26ebe6d63a | ||
|
|
132bf89677 | ||
|
|
6d43e32f8c | ||
|
|
9066bd1a0f | ||
|
|
73da3e122e | ||
|
|
fbbcd47c4c | ||
|
|
21e0e68a02 | ||
|
|
21323b3755 | ||
|
|
6f2eb00c43 | ||
|
|
797ea29113 | ||
|
|
3bf8af4840 | ||
|
|
350807bc2d | ||
|
|
0fb313aec7 | ||
|
|
fe42eb1d01 | ||
|
|
1e9a481451 | ||
|
|
7f2f407e2a | ||
|
|
75c84e3b5d | ||
|
|
74a4926e83 | ||
|
|
41950ba4de | ||
|
|
583f32e5c5 | ||
|
|
2cedbcb9b3 | ||
|
|
075f1b5df4 | ||
|
|
2b1ba0b8f8 | ||
|
|
22319e8dfe | ||
|
|
72604d5d73 | ||
|
|
37ee7091f7 | ||
|
|
3c938252a7 | ||
|
|
09d0fb095f | ||
|
|
878b43ab31 | ||
|
|
b81193c41f | ||
|
|
3ad6e554dc | ||
|
|
c9037f55bc | ||
|
|
2c6b51857f | ||
|
|
398ae568a0 | ||
|
|
e17d41a15e | ||
|
|
8bf33a3fce | ||
|
|
e9f6473a00 | ||
|
|
c0d44a9e69 | ||
|
|
41cffc2418 | ||
|
|
d7c09df7d2 | ||
|
|
507f84df4c | ||
|
|
b39bbfc97a | ||
|
|
f85080ebd3 | ||
|
|
d14a96027a | ||
|
|
5fd86d29ba | ||
|
|
2461836ae8 | ||
|
|
15dbe227e8 | ||
|
|
f2a0ae0a2c | ||
|
|
46970ae424 | ||
|
|
f7bfa5c112 | ||
|
|
cad8ed89cc | ||
|
|
bae8180385 | ||
|
|
ea97d9dd02 | ||
|
|
27f73e692f | ||
|
|
e4d1e0d4cb | ||
|
|
6f90a8d027 | ||
|
|
7a03e0ef12 | ||
|
|
aa7ad516ee | ||
|
|
d05c4ea9ef | ||
|
|
72921f04bb | ||
|
|
9b4322c8c7 | ||
|
|
5db7988066 | ||
|
|
1634a14246 | ||
|
|
b7dfd17cbb | ||
|
|
7f16c55ff4 | ||
|
|
15e4d89d20 | ||
|
|
a276fe13a6 | ||
|
|
5042a1f853 | ||
|
|
2003d90467 | ||
|
|
12795c5995 | ||
|
|
5084cddf37 | ||
|
|
064d3dd5f7 | ||
|
|
a3201f4d28 | ||
|
|
bbefc67b54 | ||
|
|
bf24cf48fc | ||
|
|
2ff27674d0 | ||
|
|
c80cd9d0b0 | ||
|
|
c019a68fc5 | ||
|
|
12051a5164 | ||
|
|
5ca09cdf09 | ||
|
|
2c44f83453 | ||
|
|
a545f8c1a2 | ||
|
|
561a24c481 | ||
|
|
1ea6552cd1 | ||
|
|
96065d11a5 | ||
|
|
d82c72f1c1 | ||
|
|
202cc5a797 | ||
|
|
289e78dbd2 | ||
|
|
6dd63db16c | ||
|
|
fa00564883 | ||
|
|
c65ef9bb31 | ||
|
|
a33cad0d13 | ||
|
|
979a439078 | ||
|
|
bdd958b24b | ||
|
|
34b2168d0d | ||
|
|
2c90e7c585 | ||
|
|
2105f4d805 | ||
|
|
6a05f4fb4e | ||
|
|
0d10282dbe |
No files matched your search
+1
-1
@@ -8,7 +8,6 @@ npm-debug.log
|
||||
.vscode/
|
||||
.idea/
|
||||
.build/*
|
||||
package-lock.json
|
||||
**/parts/
|
||||
**/stage
|
||||
**/prime
|
||||
@@ -29,3 +28,4 @@ versions.json
|
||||
.Trashes
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
.eslintcache
|
||||
+3
-1
@@ -75,7 +75,6 @@ horka:swipebox
|
||||
dynamic-import@0.5.1
|
||||
staringatlights:fast-render
|
||||
|
||||
mixmax:smart-disconnect
|
||||
accounts-password@1.5.1
|
||||
cfs:gridfs
|
||||
rzymek:fullcalendar
|
||||
@@ -93,3 +92,6 @@ meteorhacks:picker
|
||||
lamhieu:unblock
|
||||
meteorhacks:aggregate@1.3.0
|
||||
wekan-markdown
|
||||
konecty:mongo-counter
|
||||
percolate:synced-cron
|
||||
easylogic:summernote
|
||||
+5
-2
@@ -55,6 +55,7 @@ ddp-server@2.3.0
|
||||
deps@1.0.12
|
||||
diff-sequence@1.1.1
|
||||
dynamic-import@0.5.1
|
||||
easylogic:summernote@0.8.8
|
||||
ecmascript@0.12.7
|
||||
ecmascript-runtime@0.7.0
|
||||
ecmascript-runtime-client@0.8.0
|
||||
@@ -79,6 +80,7 @@ kadira:blaze-layout@2.3.0
|
||||
kadira:dochead@1.5.0
|
||||
kadira:flow-router@2.12.1
|
||||
kenton:accounts-sandstorm@0.7.0
|
||||
konecty:mongo-counter@0.0.5_3
|
||||
lamhieu:meteorx@2.0.1
|
||||
lamhieu:unblock@1.0.0
|
||||
launch-screen@1.1.1
|
||||
@@ -102,13 +104,12 @@ minifier-css@1.4.2
|
||||
minifier-js@2.4.1
|
||||
minifiers@1.1.8-faster-rebuild.0
|
||||
minimongo@1.4.5
|
||||
mixmax:smart-disconnect@0.0.4
|
||||
mobile-status-bar@1.0.14
|
||||
modern-browsers@0.1.4
|
||||
modules@0.13.0
|
||||
modules-runtime@0.10.3
|
||||
momentjs:moment@2.24.0
|
||||
mongo@1.6.2
|
||||
mongo@1.6.3
|
||||
mongo-decimal@0.1.1
|
||||
mongo-dev-server@1.1.0
|
||||
mongo-id@1.0.7
|
||||
@@ -136,6 +137,7 @@ peerlibrary:base-component@0.16.0
|
||||
peerlibrary:blaze-components@0.15.1
|
||||
peerlibrary:computed-field@0.9.0
|
||||
peerlibrary:reactive-field@0.5.0
|
||||
percolate:synced-cron@1.3.2
|
||||
promise@0.11.2
|
||||
raix:eventemitter@0.1.3
|
||||
raix:handlebar-helpers@0.2.5
|
||||
@@ -174,6 +176,7 @@ templating-compiler@1.3.3
|
||||
templating-runtime@1.3.2
|
||||
templating-tools@1.1.2
|
||||
tracker@1.2.0
|
||||
twbs:bootstrap@3.3.6
|
||||
ui@1.0.13
|
||||
underscore@1.0.10
|
||||
url@1.2.0
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
dependencies:
|
||||
- libreadline-dev
|
||||
- libssl-dev
|
||||
- bsdtar
|
||||
targets:
|
||||
ubuntu-18.04:
|
||||
ubuntu-16.04:
|
||||
ubuntu-14.04:
|
||||
centos-6:
|
||||
centos-7:
|
||||
debian-10:
|
||||
sles-12:
|
||||
sles-11:
|
||||
+216
@@ -1,3 +1,219 @@
|
||||
# v3.03 2019-08-04 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Add RICHER_CARD_COMMENT_EDITOR=true to docker-compose.yml](https://github.com/wekan/wekan/commit/268f9de23c8167dca9499587ee31fb74edb6b83e).
|
||||
Thanks to xet7.
|
||||
- [Add popup to confirm deleting one account](https://github.com/wekan/wekan/pull/2573).
|
||||
Thanks to Akuket.
|
||||
- [Add admin setting to prevent users to self deleting their account](https://github.com/wekan/wekan/pull/2573).
|
||||
Thanks to Akuket.
|
||||
- [Add Packager.io DEB/RPM Wekan packages for Debian/Ubuntu/CentOS/SLES](https://packager.io/gh/wekan/wekan).
|
||||
Does not work yet, [debugging in progress here](https://github.com/wekan/wekan/issues/2582).
|
||||
Thanks to xet7 and sfahrenholz.
|
||||
- [Add setting field LDAP_USER_AUTHENTICATION_FIELD=uid](https://github.com/wekan/wekan/pull/2581).
|
||||
Thanks to Trekky12.
|
||||
|
||||
and adds the following upgrades:
|
||||
|
||||
- [Upgrade MongoDB to 4.0.11](https://github.com/wekan/wekan/commit/ec35c544b780e563a973fd887c5190f429431bfb).
|
||||
Thanks to xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Remove mixmax:smart-disconnect, previously it did disconnect Wekan when
|
||||
browser tab was not active, but because now users are working on multiple
|
||||
boards at different browser tabs and switching all time time, there was
|
||||
constant loading, so now after removing all tabs keeps active. This can
|
||||
increase server CPU usage](https://github.com/wekan/wekan/commit/669cd76018cbbfbd3ee58610a35959fa8a84ea36).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.02 2019-07-26 Wekan release
|
||||
|
||||
This release adds the following updates:
|
||||
|
||||
- [Updated Wekan on OpenShift](https://github.com/wekan/wekan/commit/85ca2b1363ed0bad8639ba7ed65c55e445816947).
|
||||
Thanks to xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Set LDAP_BACKGROUND_SYNC_INTERVAL='' (empty string) so it works](https://github.com/wekan/wekan/commit/fff144a8279ac36ce83e6b975f17f6dbc35f39d6)
|
||||
and [does not crash](https://github.com/wekan/wekan/issues/2354#issuecomment-515305722).
|
||||
Also updated wekan-postgresql docker-compose.yml to use devel branch docker image, because ToroDB requires MongoDB 3.2,
|
||||
it's not tested yet could newest master branch docker image work with MongoDB 3.2.
|
||||
Thanks to benh57 and xet7.
|
||||
|
||||
and tries to fix following bugs:
|
||||
|
||||
- [Try to fix Snap](https://github.com/wekan/wekan/commit/7cf6850cdf77ef51808784e3d275c5be86ff6c92).
|
||||
This [will be tested soon, does this work](https://github.com/wekan/wekan/issues/2533#issuecomment-515329490).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.01 2019-07-26 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Rich text editor at card comments, based on
|
||||
Summernote](https://github.com/wekan/wekan/pull/2560).
|
||||
Thanks to whowillcare.
|
||||
- [Add setting RICHER_CARD_COMMENT_EDITOR=true to
|
||||
Source/Snap/Docker/Sandstorm](https://github.com/wekan/wekan/commit/4aba290358455433c0fc676e8c9cf1bd627eddde).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v3.00 2019-07-25 Wekan release
|
||||
|
||||
This release:
|
||||
|
||||
- works with source, and docker-compose.yml at master branch.
|
||||
- Docker release uses Meteor 1.8.1 and MongoDB 4.0.10, so you need to backup your old MongoDB database and
|
||||
restore with --noIndexRestore as described at https://github.com/wekan/wekan/wiki/Backup
|
||||
- Snap and Sandstorm builds are not fixed yet, see progress at https://github.com/wekan/wekan/issues/2533
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Added label text to labels on minicard](https://github.com/wekan/wekan/commit/c48d5a73cab04db1a1e113e4367dc88573110438).
|
||||
Thanks to xet7.
|
||||
- [Allow to shrink attached/pasted image](https://github.com/wekan/wekan/pull/2544).
|
||||
Thanks to whowillcare.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- [Fix invites](https://github.com/wekan/wekan/pull/2549).
|
||||
Thanks to justinr1234.
|
||||
- [Makes LDAP background sync work. If the sync interval is unspecified, falls back to a hourly default](https://github.com/wekan/wekan/pull/2555).
|
||||
Thanks to pshunter.
|
||||
- [Prevent isCommentOnly user adding attachments, editing list names, moving lists,
|
||||
and seeing board settings menu. Show non-editable Custom Fields to isCommentOnly user](https://github.com/wekan/wekan/commit/a68c928896a94c377134f29a7183aa0b5a423720).
|
||||
Thanks to xet7.
|
||||
- [Many](https://github.com/wekan/wekan/pull/2546) [Snap](https://github.com/wekan/wekan/pull/2552) [fixes](https://github.com/wekan/wekan/pull/2553).
|
||||
In Progress. Thanks to justrinr1234.
|
||||
- [Fixed Dockerfile](https://github.com/wekan/wekan/commit/7df6f305c5cf41ac213623aeffaa7e48c981e0b6) and
|
||||
[docker-compose.yml](https://github.com/wekan/wekan/commit/95698911f92ca728dbaab69406fd09bcbf81339d).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v2.99 2019-07-17 Wekan release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Add Corteza theme. In progress](https://github.com/wekan/wekan/commit/289e78dbd29cca9d97d3b5787c3368583d43b40f).
|
||||
Thanks to xet7.
|
||||
- [Notify Due Days: System timelines will be showing any user modification for duat startat endat receivedat,
|
||||
also notification to the watchers and if any card is due, about due or past due](https://github.com/wekan/wekan/pull/2536).
|
||||
ENV variables: NOTIFY_DUE_DAYS_BEFORE_AND_AFTER (default is 2, if 0, will turn off notification for and dued cards),
|
||||
NOTIFY_DUE_AT_HOUR_OF_DAY (any number between 0 - 23, standing for at what hour of a day that the notification will
|
||||
be sent to the watchers). Also [bug fix for this, timeOldValue needs to set to "" in params when it's
|
||||
not set](https://github.com/wekan/wekan/pull/2541).
|
||||
Thanks to whowillcare.
|
||||
- [Notify Due Days: Add settings to Snap/Docker/Source. Rename env variables to NOTIFY_DUE_DAYS_BEFORE_AND_AFTER and
|
||||
NOTIFY_DUE_AT_HOUR_OF_DAY](https://github.com/wekan/wekan/commit/5084cddf37ba16ce0855f8575c39f5e62d1b7f67).
|
||||
Thanks to xet7.
|
||||
- [BIGEVENTS_PATTERN: When user being @ in comment, as long as it's not himself, a notification will be
|
||||
sent out no matter this user is watching the board or not](https://github.com/wekan/wekan/pull/2541).
|
||||
Introduced a system env var BIGEVENTS_PATTERN default as "due", so any activityType matches the pattern,
|
||||
system will send out notifications to all board members no matter they are watching or tracking
|
||||
the board or not. Owner of the Wekan server can disable the feature by setting this variable to "NONE"
|
||||
or change the pattern to any valid regex. i.e. '|' delimited activityType names.
|
||||
Thanks to whowillcare.
|
||||
- [Add BIGEVENTS_PATTERN to Source/Snap/Docker](https://github.com/wekan/wekan/commit/d7c09df7d2649bf2d2b61772c251f81793a6ed77).
|
||||
Thanks to xet7.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Update Meteor mongo package version](https://github.com/wekan/wekan/commit/96065d11a543852c1069cbab528bd08508b4a27c).
|
||||
Thanks to xet7.
|
||||
- [Update dependencies](https://github.com/wekan/wekan/commit/d82c72f1c1df908e92045e5034fa12b33fc7f70c).
|
||||
Thanks to xet7.
|
||||
|
||||
and fixes the following bugs:
|
||||
|
||||
- RELAX THEME: Use [only in this theme](https://github.com/wekan/wekan/commit/3ad6e554dceea822dee7390872260e872a792dcd)
|
||||
the aggressive [red color and big bold serif font style
|
||||
number](https://github.com/wekan/wekan/commit/bbc68309af0029f2bc4194db4c7e79689f888ea4#commitcomment-34216371) and
|
||||
[card details text emphasis](https://github.com/wekan/wekan/commit/48ebc5f11745b125ce01d08d60e2d8e3a9419a5f#commitcomment-34268095)
|
||||
Thanks to hever and xet7.
|
||||
- [Try to fix docker-compose.yml to use correct master branch that has
|
||||
meteor 1.8.1](https://github.com/wekan/wekan/commit/202cc5a797b6269ec422c6f2e532a49f09d4e30a).
|
||||
Thanks to xet7.
|
||||
- [Outgoing Webhooks setCustomField: Add board name, card name, custom field name to be
|
||||
visible](https://github.com/wekan/wekan/commit/2003d90467debeadf51b69630c80ee6040524f52).
|
||||
Still missing: custom field value, list name, swimlane name.
|
||||
Thanks to xet7.
|
||||
- [Don't remove boardoverlay when mouse leaves carddetails](https://github.com/wekan/wekan/pull/2540).
|
||||
This reduces Wekan board flashiness.
|
||||
Thanks to newhinton.
|
||||
- [Limit the board list to 2 or 1 for mobile clients](https://github.com/wekan/wekan/pull/2542).
|
||||
As a mobile user, the board size of in the home page too small, so the user is easily to
|
||||
click on archive or copy button by accident. Increase the board size to 50% for pixel
|
||||
greater than 360 and lesser than 800 and height to 8rem, 100% for any screen is even smaller.
|
||||
This will reduce the accident much more.
|
||||
Thanks to whowillcare.
|
||||
- [Add check for board member isActive](https://github.com/wekan/wekan/commit fe42eb1d014c06dfed8114a00b29eac9b08baec6).
|
||||
Thanks to xet7.
|
||||
|
||||
and has the following features in progress, not anything visible yet:
|
||||
|
||||
- [Teams/Organizations: Add beginnings of database structure](https://github.com/wekan/wekan/issues/802#issuecomment-505986270).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v2.98 2019-07-02 Wekan release
|
||||
|
||||
This release adds the following new features, thanks to xet7:
|
||||
|
||||
- [Add Wekan v2.95-v2.97 master branch features and fixes to meteor-1.8 branch](https://github.com/wekan/wekan/commit/34b2168d0dda253dedabbee47031873efa4ae446).
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v2.97 2019-07-01 Wekan release
|
||||
|
||||
This release [adds the following new features](https://github.com/wekan/wekan/commit/3e8cb8c6e1617ef03ebce045d3b93aeb2cf91228), thanks to xet7:
|
||||
|
||||
- Add background color names to background colors.
|
||||
- Add new background colors: moderatepink, strongcyan, limegreen.
|
||||
- Add new background colors with themes: dark, relax.
|
||||
|
||||
Note: Due Date etc on cards is visible on all background colors and themes. Hiding is not implemented yet.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v2.96 2019-07-01 Wekan release
|
||||
|
||||
This release removes the following features, that were added at Wekan v2.95:
|
||||
|
||||
- [Remove RELAX MODE and DARK MODE](https://github.com/wekan/wekan/commit/8477e94f3b8f531a4209f49758200009d274c1cf),
|
||||
because [they changed look of all existing boards](https://github.com/wekan/wekan/issues/1149#issuecomment-507255114).
|
||||
At some later Wekan release they will be added back as separate themes
|
||||
that can be selected, without changing existing boards.
|
||||
Thanks to chirrut2 and xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v2.95 2019-07-01 Wekan release
|
||||
|
||||
This release adds the following new features, thanks to xet7:
|
||||
|
||||
- [Make list header add card + button more black, to make it more visible](https://github.com/wekan/wekan/commit/b260d05a8b2f87c29dd998d42103d1220b20cc08).
|
||||
- [On minicard, make comment icon and number of comments have red color
|
||||
on white rounded background, so it is more visible when there is comments on card](https://github.com/wekan/wekan/commit/bbc68309af0029f2bc4194db4c7e79689f888ea4).
|
||||
- [Make card description text more visible with black borders and more white text area](https://github.com/wekan/wekan/commit/48ebc5f11745b125ce01d08d60e2d8e3a9419a5f).
|
||||
|
||||
and adds the following [themes to board background colors](https://github.com/wekan/wekan/commit/c04292e98832e3aa7952e8a7858d47a853f40aad), thanks to xet7:
|
||||
|
||||
- RELAX MODE, so when green background selected, list background is light green.
|
||||
- [DARK MODE](https://github.com/wekan/wekan/issues/1149), when dark backgroud color selected. Please test and send color visibility fixes as pull requests.
|
||||
- In RELAX MODE and DARK MODE, [hide card fields: received, start, due, end, members, requested, assigned](https://github.com/wekan/wekan/commit/b42ecb7948ad194433dc4460305174965106a751).
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v2.94 2019-06-29 Wekan release
|
||||
|
||||
This release adds the following updates:
|
||||
|
||||
+49
-33
@@ -4,14 +4,14 @@ LABEL maintainer="wekan"
|
||||
# Set the environment variables (defaults where required)
|
||||
# DOES NOT WORK: paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303
|
||||
# ENV BUILD_DEPS="paxctl"
|
||||
ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential python3 python3-pip git ca-certificates gcc-8" \
|
||||
ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 g++ build-essential git ca-certificates" \
|
||||
DEBUG=false \
|
||||
NODE_VERSION=v8.16.0 \
|
||||
METEOR_RELEASE=1.8.1 \
|
||||
USE_EDGE=false \
|
||||
METEOR_EDGE=1.5-beta.17 \
|
||||
NPM_VERSION=latest \
|
||||
FIBERS_VERSION=2.0.0 \
|
||||
FIBERS_VERSION=4.0.1 \
|
||||
ARCHITECTURE=linux-x64 \
|
||||
SRC_PATH=./ \
|
||||
WITH_API=true \
|
||||
@@ -21,6 +21,12 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential pyth
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 \
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 \
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 \
|
||||
RICHER_CARD_COMMENT_EDITOR=true \
|
||||
MAX_IMAGE_PIXEL="" \
|
||||
IMAGE_COMPRESS_RATIO="" \
|
||||
BIGEVENTS_PATTERN="" \
|
||||
NOTIFY_DUE_DAYS_BEFORE_AND_AFTER="" \
|
||||
NOTIFY_DUE_AT_HOUR_OF_DAY="" \
|
||||
EMAIL_NOTIFICATION_TIMEOUT=30000 \
|
||||
MATOMO_ADDRESS="" \
|
||||
MATOMO_SITE_ID="" \
|
||||
@@ -57,13 +63,14 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential pyth
|
||||
LDAP_AUTHENTIFICATION_PASSWORD="" \
|
||||
LDAP_LOG_ENABLED=false \
|
||||
LDAP_BACKGROUND_SYNC=false \
|
||||
LDAP_BACKGROUND_SYNC_INTERVAL=100 \
|
||||
LDAP_BACKGROUND_SYNC_INTERVAL="" \
|
||||
LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false \
|
||||
LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false \
|
||||
LDAP_ENCRYPTION=false \
|
||||
LDAP_CA_CERT="" \
|
||||
LDAP_REJECT_UNAUTHORIZED=false \
|
||||
LDAP_USER_AUTHENTICATION=false \
|
||||
LDAP_USER_AUTHENTICATION_FIELD=uid \
|
||||
LDAP_USER_SEARCH_FILTER="" \
|
||||
LDAP_USER_SEARCH_SCOPE="" \
|
||||
LDAP_USER_SEARCH_FIELD="" \
|
||||
@@ -113,7 +120,7 @@ RUN \
|
||||
\
|
||||
# OS dependencies
|
||||
apt-get update -y && apt-get install -y --no-install-recommends ${BUILD_DEPS} && \
|
||||
pip3 install -U pip setuptools wheel && \
|
||||
#pip3 install -U pip setuptools wheel && \
|
||||
\
|
||||
# Meteor installer doesn't work with the default tar binary, so using bsdtar while installing.
|
||||
# https://github.com/coreos/bugs/issues/1095#issuecomment-350574389
|
||||
@@ -169,33 +176,39 @@ RUN \
|
||||
mv node-${NODE_VERSION}-${ARCHITECTURE} /opt/nodejs && \
|
||||
ln -s /opt/nodejs/bin/node /usr/bin/node && \
|
||||
ln -s /opt/nodejs/bin/npm /usr/bin/npm && \
|
||||
mkdir -p /opt/nodejs/lib/node_modules/fibers/.node-gyp /root/.node-gyp/8.16.0 /home/wekan/.config && \
|
||||
chown wekan --recursive /home/wekan/.config && \
|
||||
\
|
||||
#DOES NOT WORK: paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303
|
||||
#paxctl -mC `which node` && \
|
||||
\
|
||||
# Install Node dependencies
|
||||
# Install Node dependencies. Python path for node-gyp.
|
||||
npm install -g npm@${NPM_VERSION} && \
|
||||
npm install -g node-gyp && \
|
||||
npm install -g fibers@${FIBERS_VERSION} && \
|
||||
#npm config set python python2.7 && \
|
||||
#npm install -g node-gyp && \
|
||||
#npm install -g fibers@${FIBERS_VERSION} && \
|
||||
\
|
||||
# Change user to wekan and install meteor
|
||||
cd /home/wekan/ && \
|
||||
chown wekan --recursive /home/wekan && \
|
||||
curl "https://install.meteor.com" -o /home/wekan/install_meteor.sh && \
|
||||
#curl "https://install.meteor.com" -o /home/wekan/install_meteor.sh && \
|
||||
#curl "https://install.meteor.com/?release=${METEOR_RELEASE}" -o /home/wekan/install_meteor.sh && \
|
||||
# OLD: sed -i "s|RELEASE=.*|RELEASE=${METEOR_RELEASE}\"\"|g" ./install_meteor.sh && \
|
||||
# Install Meteor forcing its progress
|
||||
sed -i 's/VERBOSITY="--silent"/VERBOSITY="--progress-bar"/' ./install_meteor.sh && \
|
||||
#sed -i 's/VERBOSITY="--silent"/VERBOSITY="--progress-bar"/' ./install_meteor.sh && \
|
||||
echo "Starting meteor ${METEOR_RELEASE} installation... \n" && \
|
||||
chown wekan /home/wekan/install_meteor.sh && \
|
||||
gosu wekan:wekan curl https://install.meteor.com/ | /bin/sh && \
|
||||
mv /root/.meteor /home/wekan/ && \
|
||||
chown wekan --recursive /home/wekan/.meteor && \
|
||||
\
|
||||
# Check if opting for a release candidate instead of major release
|
||||
if [ "$USE_EDGE" = false ]; then \
|
||||
gosu wekan:wekan sh /home/wekan/install_meteor.sh; \
|
||||
else \
|
||||
gosu wekan:wekan git clone --recursive --depth 1 -b release/METEOR@${METEOR_EDGE} https://github.com/meteor/meteor.git /home/wekan/.meteor; \
|
||||
fi; \
|
||||
\
|
||||
#if [ "$USE_EDGE" = false ]; then \
|
||||
#gosu wekan:wekan sh /home/wekan/install_meteor.sh; \
|
||||
# gosu wekan:wekan curl https://install.meteor.com/ | sh; \
|
||||
#else \
|
||||
# gosu wekan:wekan git clone --recursive --depth 1 -b release/METEOR@${METEOR_EDGE} https://github.com/meteor/meteor.git /home/wekan/.meteor; \
|
||||
#fi; \
|
||||
#\
|
||||
# Get additional packages
|
||||
#mkdir -p /home/wekan/app/packages && \
|
||||
#chown wekan:wekan --recursive /home/wekan && \
|
||||
@@ -216,21 +229,24 @@ RUN \
|
||||
gosu wekan:wekan /home/wekan/.meteor/meteor -- help; \
|
||||
\
|
||||
# extract the OpenAPI specification
|
||||
npm install -g api2html@0.3.3 && \
|
||||
mkdir -p /home/wekan/python && \
|
||||
chown wekan --recursive /home/wekan/python && \
|
||||
cd /home/wekan/python && \
|
||||
gosu wekan:wekan git clone --depth 1 -b master https://github.com/Kronuz/esprima-python && \
|
||||
cd /home/wekan/python/esprima-python && \
|
||||
python3 setup.py install --record files.txt && \
|
||||
cd /home/wekan/app &&\
|
||||
gosu wekan:wekan mkdir -p ./public/api && \
|
||||
gosu wekan:wekan python3 ./openapi/generate_openapi.py --release $(git describe --tags --abbrev=0) > ./public/api/wekan.yml && \
|
||||
gosu wekan:wekan /opt/nodejs/bin/api2html -c ./public/logo-header.png -o ./public/api/wekan.html ./public/api/wekan.yml; \
|
||||
#npm install -g api2html@0.3.3 && \
|
||||
#mkdir -p /home/wekan/python && \
|
||||
#chown wekan --recursive /home/wekan/python && \
|
||||
#cd /home/wekan/python && \
|
||||
#gosu wekan:wekan git clone --depth 1 -b master https://github.com/Kronuz/esprima-python && \
|
||||
#cd /home/wekan/python/esprima-python && \
|
||||
#python3 setup.py install --record files.txt && \
|
||||
#cd /home/wekan/app && \
|
||||
#mkdir -p /home/wekan/app/public/api && \
|
||||
#chown wekan --recursive /home/wekan/app && \
|
||||
#gosu wekan:wekan python3 ./openapi/generate_openapi.py --release $(git describe --tags --abbrev=0) > ./public/api/wekan.yml && \
|
||||
#gosu wekan:wekan /opt/nodejs/bin/api2html -c ./public/logo-header.png -o ./public/api/wekan.html ./public/api/wekan.yml; \
|
||||
# Build app
|
||||
cd /home/wekan/app && \
|
||||
gosu wekan:wekan /home/wekan/.meteor/meteor add standard-minifier-js && \
|
||||
gosu wekan:wekan /home/wekan/.meteor/meteor npm install && \
|
||||
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 && \
|
||||
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 && \
|
||||
#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 && \
|
||||
@@ -256,10 +272,10 @@ RUN \
|
||||
rm -R /var/lib/apt/lists/* && \
|
||||
rm -R /home/wekan/.meteor && \
|
||||
rm -R /home/wekan/app && \
|
||||
rm -R /home/wekan/app_build && \
|
||||
cat /home/wekan/python/esprima-python/files.txt | xargs rm -R && \
|
||||
rm -R /home/wekan/python && \
|
||||
rm /home/wekan/install_meteor.sh
|
||||
rm -R /home/wekan/app_build
|
||||
#cat /home/wekan/python/esprima-python/files.txt | xargs rm -R && \
|
||||
#rm -R /home/wekan/python
|
||||
#rm /home/wekan/install_meteor.sh
|
||||
|
||||
ENV PORT=8080
|
||||
EXPOSE $PORT
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v2.94.0"
|
||||
appVersion: "v3.03.0"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
||||
@@ -201,6 +201,19 @@ template(name="cardActivities")
|
||||
.activity-checklist(href="{{ card.absoluteUrl }}")
|
||||
+viewer
|
||||
= checklistItem.title
|
||||
if(currentData.timeKey)
|
||||
| {{{_ activityType }}}
|
||||
= ' '
|
||||
i(title=currentData.timeValue).activity-meta {{ moment currentData.timeValue 'LLL' }}
|
||||
if (currentData.timeOldValue)
|
||||
= ' '
|
||||
| {{{_ "previous_as" }}}
|
||||
= ' '
|
||||
i(title=currentData.timeOldValue).activity-meta {{ moment currentData.timeOldValue 'LLL' }}
|
||||
= ' @'
|
||||
else if(currentData.timeValue)
|
||||
| {{{_ activityType currentData.timeValue}}}
|
||||
|
||||
|
||||
if($eq activityType 'addComment')
|
||||
+inlinedForm(classNames='js-edit-comment')
|
||||
|
||||
@@ -54,7 +54,7 @@ BlazeComponent.extendComponent({
|
||||
|
||||
// XXX This should be a static method of the `commentForm` component
|
||||
function resetCommentInput(input) {
|
||||
input.val('');
|
||||
input.val('').trigger('input'); // without manually trigger, input event won't be fired
|
||||
input.blur();
|
||||
commentFormIsOpen.set(false);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ template(name="board")
|
||||
else
|
||||
+boardBody
|
||||
else
|
||||
//- XXX We need a better error message in case the board has been archived
|
||||
//+message(label="board-not-found")
|
||||
{{goHome}}
|
||||
//-- XXX We need a better error message in case the board has been archived
|
||||
//-- +message(label="board-not-found")
|
||||
| {{goHome}}
|
||||
else
|
||||
+spinner
|
||||
|
||||
|
||||
@@ -243,11 +243,6 @@ BlazeComponent.extendComponent({
|
||||
{
|
||||
// XXX The board-overlay div should probably be moved to the parent
|
||||
// component.
|
||||
'mouseenter .board-overlay'() {
|
||||
if (this.mouseHasEnterCardDetails) {
|
||||
this.showOverlay.set(false);
|
||||
}
|
||||
},
|
||||
mouseup() {
|
||||
if (this._isDragging) {
|
||||
this._isDragging = false;
|
||||
|
||||
@@ -87,3 +87,208 @@ setBoardColor(color)
|
||||
|
||||
.board-color-pumpkin
|
||||
setBoardColor(#E67E22)
|
||||
|
||||
.board-color-moderatepink
|
||||
setBoardColor(#CD5A91)
|
||||
|
||||
.board-color-strongcyan
|
||||
setBoardColor(#00AECC)
|
||||
|
||||
.board-color-limegreen
|
||||
setBoardColor(#4BBF6B)
|
||||
|
||||
.board-color-dark
|
||||
setBoardColor(#2C3E51)
|
||||
|
||||
/* Not hidden in dark mode.
|
||||
card fields: received, start, due, end, members, requested, assigned
|
||||
.card-details-item.card-details-item-received,
|
||||
.card-details-item.card-details-item-start,
|
||||
.card-details-item.card-details-item-due,
|
||||
.card-details-item.card-details-item-end,
|
||||
.card-details-item.card-details-item-members,
|
||||
.card-details-item.card-details-item-name { display:none; }
|
||||
.card-details-items:empty { display:none; }
|
||||
*/
|
||||
|
||||
// DARK MODE, when dark background mode selected.
|
||||
// Modified version from https://github.com/wekan/wekan/wiki/Custom-CSS-themes#dark-theme
|
||||
// In progress, please send pull requests to fix remaining visibility issues.
|
||||
.ui-sortable,
|
||||
.swimlane,
|
||||
.swimlane >.swimlane-header-wrap,
|
||||
.swimlane >.list.js-list,
|
||||
.swimlane >.list-composer.js-list-composer,
|
||||
.list-body,
|
||||
.list,
|
||||
.list-composer,
|
||||
.sidebar-content,
|
||||
.card-details
|
||||
background-color:#2C3E50
|
||||
|
||||
.card-details h3,
|
||||
.card-details-items,
|
||||
.card-checklist-items .ui-sortable,
|
||||
.card-subtasks-items,
|
||||
.activities,
|
||||
.material-toggle-switch
|
||||
color:#bbbbbb
|
||||
|
||||
.list-header
|
||||
background-color: #888888
|
||||
|
||||
.board-widget,
|
||||
.board-widget-labels,
|
||||
.board-widget-members
|
||||
color: #aaaaaa
|
||||
|
||||
/* popup menu titles (boards, swimlanes, lists, cards, labels) */
|
||||
.pop-over >.header
|
||||
display:none;
|
||||
|
||||
/* HIDE UNTIL HOVER -------------------------------------------------- */
|
||||
|
||||
/* header "+" button */
|
||||
#header-quick-access .fa-plus
|
||||
display:none
|
||||
#header-quick-access:hover .fa-plus
|
||||
display:inherit
|
||||
|
||||
/* "add card" links (use visibility rather than display so items don't jump) */
|
||||
.open-minicard-composer
|
||||
visibility:hidden
|
||||
|
||||
.list.js-list:hover .open-minicard-composer
|
||||
visibility:visible
|
||||
|
||||
.list-header-menu
|
||||
visibility:hidden
|
||||
|
||||
.list.js-list:hover .list-header-menu
|
||||
visibility:visible
|
||||
|
||||
/* "add list/swimlane" links (use visibility rather than display so items don't jump) */
|
||||
.list.js-list-composer >.list-header
|
||||
visibility:hidden
|
||||
|
||||
.list.js-list-composer:hover >.list-header
|
||||
visibility:visible
|
||||
|
||||
/* headers */
|
||||
#header-quick-access, #header
|
||||
background-color:rgba(0,0,0,.75) !important
|
||||
|
||||
#header .board-header-btn:hover
|
||||
background-color:rgba(255,255,255,0.3) !important
|
||||
|
||||
/* foregrounds: swimlanes, lists */
|
||||
.list >.list-header, .swimlane-header
|
||||
color:rgba(255,255,255,.7)
|
||||
|
||||
/* minicards */
|
||||
.minicard
|
||||
background-color:rgba(255,255,255,.4)
|
||||
|
||||
.minicard-wrapper.is-selected .minicard,
|
||||
.minicard:hover,
|
||||
.minicard-composer.js-composer,
|
||||
.open-minicard-composer:hover
|
||||
background-color:rgba(255,255,255,.8) !important
|
||||
color:#000
|
||||
|
||||
.minicard, .minicard .badge
|
||||
color:#fff
|
||||
|
||||
.minicard:hover .badge, .minicard-wrapper.is-selected .badge
|
||||
color:#000
|
||||
|
||||
/* cards */
|
||||
.card-details .card-details-header
|
||||
background-color:#ccc
|
||||
|
||||
/* sidebar */
|
||||
.sidebar-tongue, .sidebar-shadow
|
||||
background-color:#666 !important
|
||||
|
||||
.sidebar-content h3, .sidebar-content h2, .sidebar-content
|
||||
color:rgba(255,255,255,.7) !important
|
||||
|
||||
.board-color-relax
|
||||
setBoardColor(#27AE61)
|
||||
|
||||
// RELAX MODE: light green background, with green background color,
|
||||
// to help this theme users to relax.
|
||||
// Colors and emphasis are specific to this Wekan theme contributor's company.
|
||||
.ui-sortable
|
||||
background-color:#a7e366
|
||||
|
||||
.list-header
|
||||
background-color:#a7e366
|
||||
border-bottom: 6px solid #a7e366
|
||||
|
||||
.list-body
|
||||
background-color:#a7e366
|
||||
|
||||
.list
|
||||
border-left: 1px dotted #000000
|
||||
|
||||
// Card details text emphasis: black border and white background
|
||||
// to make it details text field easier to find for RELAX MODE users,
|
||||
// and focus attention.
|
||||
.card-details .card-details-items
|
||||
& ~ .js-open-inlined-form
|
||||
.viewer
|
||||
background-color #ffffff !important
|
||||
padding 15px !important
|
||||
border 1px solid #000000 !important
|
||||
|
||||
// When card has comment, emphasis on minicard:
|
||||
// bigger red comment icon and number of comments,
|
||||
// to make it easier notice card comments and focus attention.
|
||||
.minicard .badges .badge
|
||||
.badge-icon,
|
||||
.badge-text
|
||||
&.badge-comment
|
||||
display: block
|
||||
border-radius: 4px
|
||||
padding: 1px 3px
|
||||
margin-bottom: 0.3rem
|
||||
color: #ff0000
|
||||
background-color: #ffffff
|
||||
font-weight: bold
|
||||
font-size: 11pt
|
||||
|
||||
.board-color-corteza
|
||||
setBoardColor(#568BA2)
|
||||
|
||||
/*
|
||||
Wekan for Corteza https://cortezaproject.org
|
||||
|
||||
Theme to match Corteza colors from:
|
||||
https://github.com/cortezaproject/corteza-webapp-messaging/blob/master/src/assets/sass/variables.scss
|
||||
|
||||
// Paths
|
||||
$fonts_dir : './assets/fonts/';
|
||||
$icomoon-font-path: $fonts_dir + 'icomoon' !default;
|
||||
$icomoon-font-family: "icomoon" !default;
|
||||
|
||||
// Typography
|
||||
$regular: 'nunito_sansregular';
|
||||
$bold: 'nunito_sansbold';
|
||||
$semibold: 'nunito_sanssemibold';
|
||||
|
||||
// Color system
|
||||
$white: #fff !default;
|
||||
$black: #000 !default;
|
||||
$primary: #568ba2;
|
||||
$secondary: #90A3B1;
|
||||
$success: #719430;
|
||||
$warning: #F5D380;
|
||||
$danger: #E85568;
|
||||
$light: #F3F3F5;
|
||||
$dark: #1e2224;
|
||||
$currentmymessagebgcolor : #a7d0e3;
|
||||
*/
|
||||
|
||||
//.header-quick-access
|
||||
// backgroud-color: #568ba2
|
||||
@@ -82,13 +82,13 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
'click .js-accept-invite'() {
|
||||
const boardId = this.currentData()._id;
|
||||
Meteor.user().removeInvite(boardId);
|
||||
Meteor.call('acceptInvite', boardId);
|
||||
},
|
||||
'click .js-decline-invite'() {
|
||||
const boardId = this.currentData()._id;
|
||||
Meteor.call('quitBoard', boardId, (err, ret) => {
|
||||
if (!err && ret) {
|
||||
Meteor.user().removeInvite(boardId);
|
||||
Meteor.call('acceptInvite', boardId);
|
||||
FlowRouter.go('home');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -161,6 +161,7 @@ $spaceBetweenTiles = 16px
|
||||
padding-right: 6px
|
||||
|
||||
.background-box
|
||||
color: white
|
||||
border-radius: 3px
|
||||
background-size: cover
|
||||
display: block
|
||||
@@ -182,10 +183,11 @@ $spaceBetweenTiles = 16px
|
||||
overflow: scroll
|
||||
|
||||
li
|
||||
width: 33.3%
|
||||
width: 50%
|
||||
|
||||
.board-list-item
|
||||
overflow: hidden
|
||||
height: 8rem
|
||||
|
||||
.board-list-item-sub-name
|
||||
position: relative
|
||||
@@ -194,4 +196,4 @@ $spaceBetweenTiles = 16px
|
||||
|
||||
@media screen and (max-width: 360px)
|
||||
li
|
||||
width: 50%
|
||||
width: 100%
|
||||
@@ -37,17 +37,19 @@ template(name="attachmentsGalery")
|
||||
i.fa.fa-download
|
||||
| {{_ 'download'}}
|
||||
if currentUser.isBoardMember
|
||||
if isImage
|
||||
a(class="{{#if $eq ../coverId _id}}js-remove-cover{{else}}js-add-cover{{/if}}")
|
||||
i.fa.fa-thumb-tack
|
||||
if($eq ../coverId _id)
|
||||
| {{_ 'remove-cover'}}
|
||||
else
|
||||
| {{_ 'add-cover'}}
|
||||
a.js-confirm-delete
|
||||
i.fa.fa-close
|
||||
| {{_ 'delete'}}
|
||||
unless currentUser.isCommentOnly
|
||||
if isImage
|
||||
a(class="{{#if $eq ../coverId _id}}js-remove-cover{{else}}js-add-cover{{/if}}")
|
||||
i.fa.fa-thumb-tack
|
||||
if($eq ../coverId _id)
|
||||
| {{_ 'remove-cover'}}
|
||||
else
|
||||
| {{_ 'add-cover'}}
|
||||
a.js-confirm-delete
|
||||
i.fa.fa-close
|
||||
| {{_ 'delete'}}
|
||||
|
||||
if currentUser.isBoardMember
|
||||
li.attachment-item.add-attachment
|
||||
a.js-add-attachment {{_ 'add-attachment' }}
|
||||
unless currentUser.isCommentOnly
|
||||
li.attachment-item.add-attachment
|
||||
a.js-add-attachment {{_ 'add-attachment' }}
|
||||
@@ -54,7 +54,7 @@ Template.previewAttachedImagePopup.events({
|
||||
Template.cardAttachmentsPopup.events({
|
||||
'change .js-attach-file'(event) {
|
||||
const card = this;
|
||||
FS.Utility.eachFile(event, f => {
|
||||
const processFile = f => {
|
||||
const file = new FS.File(f);
|
||||
if (card.isLinkedCard()) {
|
||||
file.boardId = Cards.findOne(card.linkedId).boardId;
|
||||
@@ -66,7 +66,6 @@ Template.cardAttachmentsPopup.events({
|
||||
file.cardId = card._id;
|
||||
}
|
||||
file.userId = Meteor.userId();
|
||||
|
||||
const attachment = Attachments.insert(file);
|
||||
|
||||
if (attachment && attachment._id && attachment.isImage()) {
|
||||
@@ -74,6 +73,42 @@ Template.cardAttachmentsPopup.events({
|
||||
}
|
||||
|
||||
Popup.close();
|
||||
};
|
||||
|
||||
FS.Utility.eachFile(event, f => {
|
||||
if (
|
||||
MAX_IMAGE_PIXEL > 0 &&
|
||||
typeof f.type === 'string' &&
|
||||
f.type.match(/^image/)
|
||||
) {
|
||||
// is image
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
const dataurl = e && e.target && e.target.result;
|
||||
if (dataurl !== undefined) {
|
||||
shrinkImage({
|
||||
dataurl,
|
||||
maxSize: MAX_IMAGE_PIXEL,
|
||||
ratio: COMPRESS_RATIO,
|
||||
toBlob: true,
|
||||
callback(blob) {
|
||||
if (blob === false) {
|
||||
processFile(f);
|
||||
} else {
|
||||
blob.name = f.name;
|
||||
processFile(blob);
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// couldn't process it let other function handle it?
|
||||
processFile(f);
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(f);
|
||||
} else {
|
||||
processFile(f);
|
||||
}
|
||||
});
|
||||
},
|
||||
'click .js-computer-upload'(event, templateInstance) {
|
||||
@@ -83,30 +118,96 @@ Template.cardAttachmentsPopup.events({
|
||||
'click .js-upload-clipboard-image': Popup.open('previewClipboardImage'),
|
||||
});
|
||||
|
||||
const MAX_IMAGE_PIXEL = Meteor.settings.public.MAX_IMAGE_PIXEL;
|
||||
const COMPRESS_RATIO = Meteor.settings.public.IMAGE_COMPRESS_RATIO;
|
||||
let pastedResults = null;
|
||||
const shrinkImage = function(options) {
|
||||
// shrink image to certain size
|
||||
const dataurl = options.dataurl,
|
||||
callback = options.callback,
|
||||
toBlob = options.toBlob;
|
||||
let canvas = document.createElement('canvas'),
|
||||
image = document.createElement('img');
|
||||
const maxSize = options.maxSize || 1024;
|
||||
const ratio = options.ratio || 1.0;
|
||||
const next = function(result) {
|
||||
image = null;
|
||||
canvas = null;
|
||||
if (typeof callback === 'function') {
|
||||
callback(result);
|
||||
}
|
||||
};
|
||||
image.onload = function() {
|
||||
let width = this.width,
|
||||
height = this.height;
|
||||
let changed = false;
|
||||
if (width > height) {
|
||||
if (width > maxSize) {
|
||||
height *= maxSize / width;
|
||||
width = maxSize;
|
||||
changed = true;
|
||||
}
|
||||
} else if (height > maxSize) {
|
||||
width *= maxSize / height;
|
||||
height = maxSize;
|
||||
changed = true;
|
||||
}
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
canvas.getContext('2d').drawImage(this, 0, 0, width, height);
|
||||
if (changed === true) {
|
||||
const type = 'image/jpeg';
|
||||
if (toBlob) {
|
||||
canvas.toBlob(next, type, ratio);
|
||||
} else {
|
||||
next(canvas.toDataURL(type, ratio));
|
||||
}
|
||||
} else {
|
||||
next(changed);
|
||||
}
|
||||
};
|
||||
image.onerror = function() {
|
||||
next(false);
|
||||
};
|
||||
image.src = dataurl;
|
||||
};
|
||||
|
||||
Template.previewClipboardImagePopup.onRendered(() => {
|
||||
// we can paste image from clipboard
|
||||
$(document.body).pasteImageReader(results => {
|
||||
const handle = results => {
|
||||
if (results.dataURL.startsWith('data:image/')) {
|
||||
$('img.preview-clipboard-image').attr('src', results.dataURL);
|
||||
pastedResults = results;
|
||||
const direct = results => {
|
||||
$('img.preview-clipboard-image').attr('src', results.dataURL);
|
||||
pastedResults = results;
|
||||
};
|
||||
if (MAX_IMAGE_PIXEL) {
|
||||
// if has size limitation on image we shrink it before uploading
|
||||
shrinkImage({
|
||||
dataurl: results.dataURL,
|
||||
maxSize: MAX_IMAGE_PIXEL,
|
||||
ratio: COMPRESS_RATIO,
|
||||
callback(changed) {
|
||||
if (changed !== false && !!changed) {
|
||||
results.dataURL = changed;
|
||||
}
|
||||
direct(results);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$(document.body).pasteImageReader(handle);
|
||||
|
||||
// we can also drag & drop image file to it
|
||||
$(document.body).dropImageReader(results => {
|
||||
if (results.dataURL.startsWith('data:image/')) {
|
||||
$('img.preview-clipboard-image').attr('src', results.dataURL);
|
||||
pastedResults = results;
|
||||
}
|
||||
});
|
||||
$(document.body).dropImageReader(handle);
|
||||
});
|
||||
|
||||
Template.previewClipboardImagePopup.events({
|
||||
'click .js-upload-pasted-image'() {
|
||||
const results = pastedResults;
|
||||
if (results && results.file) {
|
||||
window.oPasted = pastedResults;
|
||||
const card = this;
|
||||
const file = new FS.File(results.file);
|
||||
if (!results.name) {
|
||||
|
||||
@@ -31,6 +31,10 @@ template(name="cardCustomField-text")
|
||||
= value
|
||||
else
|
||||
| {{_ 'edit'}}
|
||||
else
|
||||
+viewer
|
||||
= value
|
||||
|
||||
|
||||
template(name="cardCustomField-number")
|
||||
if canModifyCard
|
||||
@@ -45,6 +49,9 @@ template(name="cardCustomField-number")
|
||||
= value
|
||||
else
|
||||
| {{_ 'edit'}}
|
||||
else
|
||||
if value
|
||||
= value
|
||||
|
||||
template(name="cardCustomField-date")
|
||||
if canModifyCard
|
||||
@@ -55,6 +62,11 @@ template(name="cardCustomField-date")
|
||||
| {{showDate}}
|
||||
else
|
||||
| {{_ 'edit'}}
|
||||
else
|
||||
if value
|
||||
div.card-date
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
|
||||
template(name="cardCustomField-dropdown")
|
||||
if canModifyCard
|
||||
@@ -79,3 +91,7 @@ template(name="cardCustomField-dropdown")
|
||||
= selectedItem
|
||||
else
|
||||
| {{_ 'edit'}}
|
||||
else
|
||||
if value
|
||||
+viewer
|
||||
= selectedItem
|
||||
@@ -126,7 +126,7 @@ input[type="submit"].attachment-add-link-submit
|
||||
|
||||
@media screen and (max-width: 800px)
|
||||
.card-details
|
||||
width: calc(100% - 40px)
|
||||
width: calc(100% - 1px)
|
||||
padding: 0px 20px 0px 20px
|
||||
margin: 0px
|
||||
transition: none
|
||||
@@ -134,7 +134,7 @@ input[type="submit"].attachment-add-link-submit
|
||||
.card-details-canvas
|
||||
width: 100%
|
||||
padding-left: 0px;
|
||||
|
||||
|
||||
.card-details-header
|
||||
.close-card-details
|
||||
margin-right: 0px
|
||||
|
||||
@@ -8,7 +8,9 @@ template(name="minicard")
|
||||
if labels
|
||||
.minicard-labels
|
||||
each labels
|
||||
.minicard-label(class="card-label-{{color}}" title="{{name}}")
|
||||
span.card-label(class="card-label-{{color}}" title=name)
|
||||
+viewer
|
||||
= name
|
||||
.minicard-title
|
||||
.handle
|
||||
.fa.fa-arrows
|
||||
@@ -74,7 +76,10 @@ template(name="minicard")
|
||||
if comments.count
|
||||
.badge(title="{{_ 'card-comments-title' comments.count }}")
|
||||
span.badge-icon.fa.fa-comment-o.badge-comment
|
||||
span.badge-text= comments.count
|
||||
= ' '
|
||||
= comments.count
|
||||
//span.badge-comment.badge-text
|
||||
//| {{_ 'comment'}}
|
||||
if getDescription
|
||||
.badge.badge-state-image-only(title=getDescription)
|
||||
span.badge-icon.fa.fa-align-left
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
.badge-text
|
||||
vertical-align: middle
|
||||
&.badge-comment
|
||||
margin-bottom: 0.1rem
|
||||
margin-bottom: 0.1rem
|
||||
|
||||
.badge-text
|
||||
font-size: 0.9em
|
||||
|
||||
@@ -103,6 +103,10 @@
|
||||
color: #8c8c8c
|
||||
font-size: 0.8em
|
||||
|
||||
.list-header .list-header-plus-icon, .js-open-list-menu, .list-header-menu a
|
||||
color #4d4d4d
|
||||
padding-left 4px
|
||||
|
||||
.list-body
|
||||
flex: 1 1 auto
|
||||
flex-direction: column
|
||||
|
||||
@@ -9,7 +9,7 @@ template(name="listHeader")
|
||||
if currentList
|
||||
a.list-header-left-icon.fa.fa-angle-left.js-unselect-list
|
||||
h2.list-header-name(
|
||||
class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
|
||||
class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}js-open-inlined-form is-editable{{/unless}}{{/if}}")
|
||||
+viewer
|
||||
= title
|
||||
if wipLimit.enabled
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
Template.editor.onRendered(() => {
|
||||
const $textarea = this.$('textarea');
|
||||
|
||||
autosize($textarea);
|
||||
|
||||
$textarea.escapeableTextComplete([
|
||||
const textareaSelector = 'textarea';
|
||||
const enableRicherEditor =
|
||||
Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR || true;
|
||||
const mentions = [
|
||||
// User mentions
|
||||
{
|
||||
match: /\B@([\w.]*)$/,
|
||||
@@ -27,7 +26,163 @@ Template.editor.onRendered(() => {
|
||||
},
|
||||
index: 1,
|
||||
},
|
||||
]);
|
||||
];
|
||||
const enableTextarea = function() {
|
||||
const $textarea = this.$(textareaSelector);
|
||||
autosize($textarea);
|
||||
$textarea.escapeableTextComplete(mentions);
|
||||
};
|
||||
if (enableRicherEditor) {
|
||||
const isSmall = Utils.isMiniScreen();
|
||||
const toolbar = isSmall
|
||||
? [
|
||||
['view', ['fullscreen']],
|
||||
['table', ['table']],
|
||||
['font', ['bold', 'underline']],
|
||||
//['fontsize', ['fontsize']],
|
||||
['color', ['color']],
|
||||
]
|
||||
: [
|
||||
['style', ['style']],
|
||||
['font', ['bold', 'underline', 'clear']],
|
||||
['fontsize', ['fontsize']],
|
||||
['fontname', ['fontname']],
|
||||
['color', ['color']],
|
||||
['para', ['ul', 'ol', 'paragraph']],
|
||||
['table', ['table']],
|
||||
//['insert', ['link', 'picture', 'video']], // iframe tag will be sanitized TODO if iframe[class=note-video-clip] can be added into safe list, insert video can be enabled
|
||||
//['insert', ['link', 'picture']], // modal popup has issue somehow :(
|
||||
['view', ['fullscreen', 'help']],
|
||||
];
|
||||
const cleanPastedHTML = function(input) {
|
||||
const badTags = [
|
||||
'style',
|
||||
'script',
|
||||
'applet',
|
||||
'embed',
|
||||
'noframes',
|
||||
'noscript',
|
||||
'meta',
|
||||
'link',
|
||||
'button',
|
||||
'form',
|
||||
].join('|');
|
||||
const badPatterns = new RegExp(
|
||||
`(?:${[
|
||||
`<(${badTags})s*[^>][\\s\\S]*?<\\/\\1>`,
|
||||
`<(${badTags})[^>]*?\\/>`,
|
||||
].join('|')})`,
|
||||
'gi',
|
||||
);
|
||||
let output = input;
|
||||
// remove bad Tags
|
||||
output = output.replace(badPatterns, '');
|
||||
// remove attributes ' style="..."'
|
||||
const badAttributes = new RegExp(
|
||||
`(?:${[
|
||||
'on\\S+=([\'"]?).*?\\1',
|
||||
'href=([\'"]?)javascript:.*?\\2',
|
||||
'style=([\'"]?).*?\\3',
|
||||
'target=\\S+',
|
||||
].join('|')})`,
|
||||
'gi',
|
||||
);
|
||||
output = output.replace(badAttributes, '');
|
||||
output = output.replace(/(<a )/gi, '$1target=_ '); // always to new target
|
||||
return output;
|
||||
};
|
||||
const editor = '.editor';
|
||||
const selectors = [
|
||||
`.js-new-comment-form ${editor}`,
|
||||
`.js-edit-comment ${editor}`,
|
||||
].join(','); // only new comment and edit comment
|
||||
const inputs = $(selectors);
|
||||
if (inputs.length === 0) {
|
||||
// only enable richereditor to new comment or edit comment no others
|
||||
enableTextarea();
|
||||
} else {
|
||||
const placeholder = inputs.attr('placeholder') || '';
|
||||
const mSummernotes = [];
|
||||
const getSummernote = function(input) {
|
||||
const idx = inputs.index(input);
|
||||
if (idx > -1) {
|
||||
return mSummernotes[idx];
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
inputs.each(function(idx, input) {
|
||||
mSummernotes[idx] = $(input).summernote({
|
||||
placeholder,
|
||||
callbacks: {
|
||||
onInit(object) {
|
||||
const originalInput = this;
|
||||
$(originalInput).on('input', function() {
|
||||
// when comment is submitted, the original textarea will be set to '', so shall we
|
||||
if (!this.value) {
|
||||
const sn = getSummernote(this);
|
||||
sn && sn.summernote('reset');
|
||||
object && object.editingArea.find('.note-placeholder').show();
|
||||
}
|
||||
});
|
||||
const jEditor = object && object.editable;
|
||||
const toolbar = object && object.toolbar;
|
||||
if (jEditor !== undefined) {
|
||||
jEditor.escapeableTextComplete(mentions);
|
||||
}
|
||||
if (toolbar !== undefined) {
|
||||
const fBtn = toolbar.find('.btn-fullscreen');
|
||||
fBtn.on('click', function() {
|
||||
const $this = $(this),
|
||||
isActive = $this.hasClass('active');
|
||||
$('.minicards').toggle(!isActive); // mini card is still showing when editor is in fullscreen mode, we hide here manually
|
||||
});
|
||||
}
|
||||
},
|
||||
onPaste() {
|
||||
// clear up unwanted tag info when user pasted in text
|
||||
const thisNote = this;
|
||||
const updatePastedText = function(object) {
|
||||
const someNote = getSummernote(object);
|
||||
const original = someNote.summernote('code');
|
||||
const cleaned = cleanPastedHTML(original); //this is where to call whatever clean function you want. I have mine in a different file, called CleanPastedHTML.
|
||||
someNote.summernote('reset'); //clear original
|
||||
someNote.summernote('pasteHTML', cleaned); //this sets the displayed content editor to the cleaned pasted code.
|
||||
};
|
||||
setTimeout(function() {
|
||||
//this kinda sucks, but if you don't do a setTimeout,
|
||||
//the function is called before the text is really pasted.
|
||||
updatePastedText(thisNote);
|
||||
}, 10);
|
||||
},
|
||||
},
|
||||
dialogsInBody: true,
|
||||
disableDragAndDrop: true,
|
||||
toolbar,
|
||||
popover: {
|
||||
image: [
|
||||
[
|
||||
'image',
|
||||
['resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone'],
|
||||
],
|
||||
['float', ['floatLeft', 'floatRight', 'floatNone']],
|
||||
['remove', ['removeMedia']],
|
||||
],
|
||||
table: [
|
||||
['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']],
|
||||
['delete', ['deleteRow', 'deleteCol', 'deleteTable']],
|
||||
],
|
||||
air: [
|
||||
['color', ['color']],
|
||||
['font', ['bold', 'underline', 'clear']],
|
||||
],
|
||||
},
|
||||
height: 200,
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
enableTextarea();
|
||||
}
|
||||
});
|
||||
|
||||
import sanitizeXss from 'xss';
|
||||
|
||||
@@ -2,6 +2,35 @@
|
||||
|
||||
global-reset()
|
||||
|
||||
*
|
||||
-webkit-box-sizing: unset
|
||||
box-sizing: unset
|
||||
|
||||
.note-popover .popover-content .note-color-palette div .note-color-btn, .panel-heading.note-toolbar .note-color-palette div .note-color-btn
|
||||
background: none
|
||||
|
||||
a:focus
|
||||
outline: unset
|
||||
outline-offset: unset
|
||||
|
||||
a:hover,a:focus
|
||||
color: unset
|
||||
text-decoration: unset
|
||||
|
||||
.badge
|
||||
display: unset
|
||||
min-width: unset
|
||||
padding: unset
|
||||
font-size: unset
|
||||
font-weight: unset
|
||||
line-height: unset
|
||||
color: unset
|
||||
text-align: unset
|
||||
white-space: unset
|
||||
vertical-align: unset
|
||||
background-color: unset
|
||||
border-radius: unset
|
||||
|
||||
html, body, input, select, textarea, button
|
||||
font: 14px Roboto, "Helvetica Neue", Arial, Helvetica, sans-serif
|
||||
line-height: 18px
|
||||
|
||||
@@ -243,8 +243,8 @@ Template.editUserPopup.events({
|
||||
} else Popup.close();
|
||||
},
|
||||
|
||||
'click #deleteButton'() {
|
||||
'click #deleteButton': Popup.afterConfirm('userDelete', function() {
|
||||
Users.remove(this.userId);
|
||||
Popup.close();
|
||||
},
|
||||
}),
|
||||
});
|
||||
@@ -44,7 +44,7 @@ template(name="general")
|
||||
ul
|
||||
li
|
||||
.title {{_ 'invite-people'}}
|
||||
textarea#email-to-invite.form-control(rows='5', placeholder="{{_ 'email-addresses'}}")
|
||||
textarea#email-to-invite.wekan-form-control(rows='5', placeholder="{{_ 'email-addresses'}}")
|
||||
li
|
||||
.title {{_ 'to-boards'}}
|
||||
.bg-white
|
||||
@@ -63,20 +63,20 @@ template(name='email')
|
||||
.title {{_ 'smtp-host'}}
|
||||
.description {{_ 'smtp-host-description'}}
|
||||
.form-group
|
||||
input.form-control#mail-server-host(type="text", placeholder="smtp.domain.com" value="{{currentSetting.mailServer.host}}")
|
||||
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.form-control#mail-server-port(type="text", placeholder="25" value="{{currentSetting.mailServer.port}}")
|
||||
input.wekan-form-control#mail-server-port(type="text", placeholder="25" value="{{currentSetting.mailServer.port}}")
|
||||
li.smtp-form
|
||||
.title {{_ 'smtp-username'}}
|
||||
.form-group
|
||||
input.form-control#mail-server-username(type="text", placeholder="{{_ 'username'}}" value="{{currentSetting.mailServer.username}}")
|
||||
input.wekan-form-control#mail-server-username(type="text", placeholder="{{_ 'username'}}" value="{{currentSetting.mailServer.username}}")
|
||||
li.smtp-form
|
||||
.title {{_ 'smtp-password'}}
|
||||
.form-group
|
||||
input.form-control#mail-server-password(type="password", placeholder="{{_ 'password'}}" value="{{currentSetting.mailServer.password}}")
|
||||
input.wekan-form-control#mail-server-password(type="password", placeholder="{{_ 'password'}}" value="{{currentSetting.mailServer.password}}")
|
||||
li.smtp-form
|
||||
.title {{_ 'smtp-tls'}}
|
||||
.form-group
|
||||
@@ -88,7 +88,7 @@ template(name='email')
|
||||
li.smtp-form
|
||||
.title {{_ 'send-from'}}
|
||||
.form-group
|
||||
input.form-control#mail-server-from(type="email", placeholder="no-reply@domain.com" value="{{currentSetting.mailServer.from}}")
|
||||
input.wekan-form-control#mail-server-from(type="email", placeholder="no-reply@domain.com" value="{{currentSetting.mailServer.from}}")
|
||||
|
||||
li
|
||||
button.js-save.primary {{_ 'save'}}
|
||||
@@ -101,17 +101,25 @@ template(name='accountSettings')
|
||||
li.accounts-form
|
||||
.title {{_ 'accounts-allowEmailChange'}}
|
||||
.form-group.flex
|
||||
input.form-control#accounts-allowEmailChange(type="radio" name="allowEmailChange" value="true" checked="{{#if allowEmailChange}}checked{{/if}}")
|
||||
input.wekan-form-control#accounts-allowEmailChange(type="radio" name="allowEmailChange" value="true" checked="{{#if allowEmailChange}}checked{{/if}}")
|
||||
span {{_ 'yes'}}
|
||||
input.form-control#accounts-allowEmailChange(type="radio" name="allowEmailChange" value="false" checked="{{#unless allowEmailChange}}checked{{/unless}}")
|
||||
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.form-control#accounts-allowUserNameChange(type="radio" name="allowUserNameChange" value="true" checked="{{#if allowUserNameChange}}checked{{/if}}")
|
||||
input.wekan-form-control#accounts-allowUserNameChange(type="radio" name="allowUserNameChange" value="true" checked="{{#if allowUserNameChange}}checked{{/if}}")
|
||||
span {{_ 'yes'}}
|
||||
input.form-control#accounts-allowUserNameChange(type="radio" name="allowUserNameChange" value="false" checked="{{#unless allowUserNameChange}}checked{{/unless}}")
|
||||
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'}}
|
||||
@@ -128,7 +136,7 @@ template(name='announcementSettings')
|
||||
ul
|
||||
li
|
||||
.title {{_ 'admin-announcement-title'}}
|
||||
textarea#admin-announcement.form-control= currentSetting.body
|
||||
textarea#admin-announcement.wekan-form-control= currentSetting.body
|
||||
li
|
||||
button.js-announcement-save.primary {{_ 'save'}}
|
||||
|
||||
@@ -137,16 +145,16 @@ template(name='layoutSettings')
|
||||
//li.layout-form
|
||||
.title {{_ 'hide-logo'}}
|
||||
.form-group.flex
|
||||
input.form-control#hide-logo(type="radio" name="hideLogo" value="true" checked="{{#if currentSetting.hideLogo}}checked{{/if}}")
|
||||
input.wekan-form-control#hide-logo(type="radio" name="hideLogo" value="true" checked="{{#if currentSetting.hideLogo}}checked{{/if}}")
|
||||
span {{_ 'yes'}}
|
||||
input.form-control#hide-logo(type="radio" name="hideLogo" value="false" checked="{{#unless currentSetting.hideLogo}}checked{{/unless}}")
|
||||
input.wekan-form-control#hide-logo(type="radio" name="hideLogo" value="false" checked="{{#unless currentSetting.hideLogo}}checked{{/unless}}")
|
||||
span {{_ 'no'}}
|
||||
li.layout-form
|
||||
.title {{_ 'display-authentication-method'}}
|
||||
.form-group.flex
|
||||
input.form-control#display-authentication-method(type="radio" name="displayAuthenticationMethod" value="true" checked="{{#if currentSetting.displayAuthenticationMethod}}checked{{/if}}")
|
||||
input.wekan-form-control#display-authentication-method(type="radio" name="displayAuthenticationMethod" value="true" checked="{{#if currentSetting.displayAuthenticationMethod}}checked{{/if}}")
|
||||
span {{_ 'yes'}}
|
||||
input.form-control#display-authentication-method(type="radio" name="displayAuthenticationMethod" value="false" checked="{{#unless currentSetting.displayAuthenticationMethod}}checked{{/unless}}")
|
||||
input.wekan-form-control#display-authentication-method(type="radio" name="displayAuthenticationMethod" value="false" checked="{{#unless currentSetting.displayAuthenticationMethod}}checked{{/unless}}")
|
||||
span {{_ 'no'}}
|
||||
li.layout-form
|
||||
.title {{_ 'default-authentication-method'}}
|
||||
@@ -154,13 +162,13 @@ template(name='layoutSettings')
|
||||
li.layout-form
|
||||
.title {{_ 'custom-product-name'}}
|
||||
.form-group
|
||||
input.form-control#product-name(type="text", placeholder="" value="{{currentSetting.productName}}")
|
||||
input.wekan-form-control#product-name(type="text", placeholder="" value="{{currentSetting.productName}}")
|
||||
li.layout-form
|
||||
.title {{_ 'add-custom-html-after-body-start'}}
|
||||
textarea#customHTMLafterBodyStart.form-control= currentSetting.customHTMLafterBodyStart
|
||||
textarea#customHTMLafterBodyStart.wekan-form-control= currentSetting.customHTMLafterBodyStart
|
||||
li.layout-form
|
||||
.title {{_ 'add-custom-html-before-body-end'}}
|
||||
textarea#customHTMLbeforeBodyEnd.form-control= currentSetting.customHTMLbeforeBodyEnd
|
||||
textarea#customHTMLbeforeBodyEnd.wekan-form-control= currentSetting.customHTMLbeforeBodyEnd
|
||||
li
|
||||
button.js-save-layout.primary {{_ 'save'}}
|
||||
|
||||
|
||||
@@ -233,12 +233,17 @@ BlazeComponent.extendComponent({
|
||||
$('input[name=allowEmailChange]:checked').val() === 'true';
|
||||
const allowUserNameChange =
|
||||
$('input[name=allowUserNameChange]:checked').val() === 'true';
|
||||
const allowUserDelete =
|
||||
$('input[name=allowUserDelete]:checked').val() === 'true';
|
||||
AccountSettings.update('accounts-allowEmailChange', {
|
||||
$set: { booleanValue: allowEmailChange },
|
||||
});
|
||||
AccountSettings.update('accounts-allowUserNameChange', {
|
||||
$set: { booleanValue: allowUserNameChange },
|
||||
});
|
||||
AccountSettings.update('accounts-allowUserDelete', {
|
||||
$set: { booleanValue: allowUserDelete },
|
||||
});
|
||||
},
|
||||
|
||||
allowEmailChange() {
|
||||
@@ -247,6 +252,9 @@ BlazeComponent.extendComponent({
|
||||
allowUserNameChange() {
|
||||
return AccountSettings.findOne('accounts-allowUserNameChange').booleanValue;
|
||||
},
|
||||
allowUserDelete() {
|
||||
return AccountSettings.findOne('accounts-allowUserDelete').booleanValue;
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
|
||||
@@ -105,14 +105,14 @@
|
||||
.bg-white
|
||||
background #f9fbfc;
|
||||
|
||||
.form-control.has-error
|
||||
.wekan-form-control.has-error
|
||||
border-color: #a94442;
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
|
||||
|
||||
li.has-error
|
||||
color #a94442
|
||||
.form-group
|
||||
.form-control
|
||||
.wekan-form-control
|
||||
border-color: #a94442;
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
|
||||
|
||||
@@ -34,8 +34,9 @@ template(name="membersWidget")
|
||||
h3
|
||||
i.fa.fa-user
|
||||
| {{_ 'members'}}
|
||||
a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right
|
||||
i.board-header-btn-icon.fa.fa-cog
|
||||
unless currentUser.isCommentOnly
|
||||
a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right
|
||||
i.board-header-btn-icon.fa.fa-cog
|
||||
|
||||
.board-widget-content
|
||||
each currentBoard.activeMembers
|
||||
@@ -61,6 +62,7 @@ template(name="boardChangeColorPopup")
|
||||
each backgroundColors
|
||||
.board-background-select.js-select-background
|
||||
span.background-box(class="board-color-{{this}}")
|
||||
span {{this}}
|
||||
if isSelected
|
||||
i.fa.fa-check
|
||||
|
||||
|
||||
@@ -9,14 +9,16 @@ template(name="swimlane")
|
||||
each lists
|
||||
+miniList(this)
|
||||
if currentUser.isBoardMember
|
||||
+addListForm
|
||||
unless currentUser.isCommentOnly
|
||||
+addListForm
|
||||
else
|
||||
each lists
|
||||
+list(this)
|
||||
if currentCardIsInThisList _id ../_id
|
||||
+cardDetails(currentCard)
|
||||
if currentUser.isBoardMember
|
||||
+addListForm
|
||||
unless currentUser.isCommentOnly
|
||||
+addListForm
|
||||
|
||||
template(name="listsGroup")
|
||||
.swimlane.list-group.js-lists
|
||||
@@ -27,14 +29,16 @@ template(name="listsGroup")
|
||||
each lists
|
||||
+miniList(this)
|
||||
if currentUser.isBoardMember
|
||||
+addListForm
|
||||
unless currentUser.isCommentOnly
|
||||
+addListForm
|
||||
else
|
||||
each lists
|
||||
+list(this)
|
||||
if currentCardIsInThisList _id null
|
||||
+cardDetails(currentCard)
|
||||
if currentUser.isBoardMember
|
||||
+addListForm
|
||||
unless currentUser.isCommentOnly
|
||||
+addListForm
|
||||
|
||||
template(name="addListForm")
|
||||
.list.list-composer.js-list-composer
|
||||
|
||||
@@ -55,8 +55,9 @@ template(name="editProfilePopup")
|
||||
input.js-profile-email(type="email" value="{{emails.[0].address}}" readonly)
|
||||
div.buttonsContainer
|
||||
input.primary.wide(type="submit" value="{{_ 'save'}}")
|
||||
div
|
||||
input#deleteButton.primary.wide(type="button" value="{{_ 'delete'}}")
|
||||
if allowUserDelete
|
||||
div
|
||||
input#deleteButton.primary.wide(type="button" value="{{_ 'delete'}}")
|
||||
|
||||
template(name="changePasswordPopup")
|
||||
+atForm(state='changePwd')
|
||||
@@ -82,3 +83,8 @@ template(name="changeSettingsPopup")
|
||||
| {{_ 'show-cards-minimum-count'}}
|
||||
input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="0" max="99" onkeydown="return false")
|
||||
input.js-apply-show-cards-at.left(type="submit" value="{{_ 'apply'}}")
|
||||
|
||||
|
||||
template(name="userDeletePopup")
|
||||
p {{_ 'delete-user-confirm-popup'}}
|
||||
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
|
||||
@@ -35,6 +35,9 @@ Template.editProfilePopup.helpers({
|
||||
allowUserNameChange() {
|
||||
return AccountSettings.findOne('accounts-allowUserNameChange').booleanValue;
|
||||
},
|
||||
allowUserDelete() {
|
||||
return AccountSettings.findOne('accounts-allowUserDelete').booleanValue;
|
||||
},
|
||||
});
|
||||
|
||||
Template.editProfilePopup.events({
|
||||
@@ -104,11 +107,11 @@ Template.editProfilePopup.events({
|
||||
});
|
||||
} else Popup.back();
|
||||
},
|
||||
'click #deleteButton'() {
|
||||
Users.remove(Meteor.userId());
|
||||
'click #deleteButton': Popup.afterConfirm('userDelete', function() {
|
||||
Popup.close();
|
||||
Users.remove(Meteor.userId());
|
||||
AccountsTemplates.logout();
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
// XXX For some reason the useraccounts autofocus isnt working in this case.
|
||||
|
||||
+56
-10
@@ -9,6 +9,8 @@ version: '2'
|
||||
# https://github.com/wekan/wekan/wiki/Forgot-Password
|
||||
#---------------------------------------------------------------------------------------------------------
|
||||
# ==== Upgrading Wekan to new version =====
|
||||
# NOTE: MongoDB has changed from 3.x to 4.x, in that case you need backup/restore with --noIndexRestore
|
||||
# see https://github.com/wekan/wekan/wiki/Backup
|
||||
# 1) Stop Wekan:
|
||||
# docker-compose stop
|
||||
# 2) Download new version:
|
||||
@@ -90,9 +92,9 @@ services:
|
||||
wekandb:
|
||||
#-------------------------------------------------------------------------------------
|
||||
# ==== MONGODB AND METEOR VERSION ====
|
||||
# a) For Wekan Meteor 1.8.x version at meteor-1.8 branch, use mongo 4.x
|
||||
image: mongo:4.0.9
|
||||
# b) For Wekan Meteor 1.6.x version at master/devel/edge branches.
|
||||
# a) For Wekan Meteor 1.8.x version at master branch, use mongo 4.x
|
||||
image: mongo:4.0.11
|
||||
# b) For Wekan Meteor 1.6.x version at devel branch.
|
||||
# Only for Snap and Sandstorm while they are not upgraded yet to Meteor 1.8.x
|
||||
#image: mongo:3.2.21
|
||||
#-------------------------------------------------------------------------------------
|
||||
@@ -110,17 +112,18 @@ services:
|
||||
wekan:
|
||||
#-------------------------------------------------------------------------------------
|
||||
# ==== MONGODB AND METEOR VERSION ====
|
||||
# a) For Wekan Meteor 1.8.x version at meteor-1.8 branch,
|
||||
# NOTE: Quay is currently not updated, use Docker Hub image below c)
|
||||
# a) For Wekan Meteor 1.8.x version at master branch,
|
||||
# using https://quay.io/wekan/wekan automatic builds
|
||||
#image: quay.io/wekan/wekan:meteor-1.8
|
||||
#image: quay.io/wekan/wekan:master
|
||||
# b) For Wekan Meteor 1.6.x version at master/devel/edge branches.
|
||||
# Only for Snap and Sandstorm while they are not upgraded yet to Meteor 1.8.x
|
||||
image: quay.io/wekan/wekan:meteor-1.8
|
||||
#image: quay.io/wekan/wekan:master
|
||||
# c) Using specific Meteor 1.6.x version tag:
|
||||
# image: quay.io/wekan/wekan:v1.95
|
||||
# c) Using Docker Hub automatic builds https://hub.docker.com/r/wekanteam/wekan
|
||||
# image: wekanteam/wekan:meteor-1.8
|
||||
# image: wekanteam/wekan:v1.95
|
||||
image: wekanteam/wekan
|
||||
# image: wekanteam/wekan:v2.99
|
||||
#-------------------------------------------------------------------------------------
|
||||
container_name: wekan-app
|
||||
restart: always
|
||||
@@ -232,6 +235,44 @@ services:
|
||||
#- ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60
|
||||
#- ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15
|
||||
#---------------------------------------------------------------
|
||||
# ==== RICH TEXT EDITOR IN CARD COMMENTS ====
|
||||
# https://github.com/wekan/wekan/pull/2560
|
||||
- RICHER_CARD_COMMENT_EDITOR=true
|
||||
#---------------------------------------------------------------
|
||||
# ==== Allow to shrink attached/pasted image ====
|
||||
# https://github.com/wekan/wekan/pull/2544
|
||||
#-MAX_IMAGE_PIXEL=1024
|
||||
#-IMAGE_COMPRESS_RATIO=80
|
||||
#---------------------------------------------------------------
|
||||
# ==== BIGEVENTS DUE ETC NOTIFICATIONS =====
|
||||
# https://github.com/wekan/wekan/pull/2541
|
||||
# Introduced a system env var BIGEVENTS_PATTERN default as "due",
|
||||
# so any activityType matches the pattern, system will send out
|
||||
# notifications to all board members no matter they are watching
|
||||
# or tracking the board or not. Owner of the wekan server can
|
||||
# disable the feature by setting this variable to "NONE" or
|
||||
# change the pattern to any valid regex. i.e. '|' delimited
|
||||
# activityType names.
|
||||
# a) Default
|
||||
#- BIGEVENTS_PATTERN=due
|
||||
# b) All
|
||||
#- BIGEVENTS_PATTERN=received|start|due|end
|
||||
# c) Disabled
|
||||
#- BIGEVENTS_PATTERN=NONE
|
||||
#---------------------------------------------------------------
|
||||
# ==== EMAIL DUE DATE NOTIFICATION =====
|
||||
# https://github.com/wekan/wekan/pull/2536
|
||||
# System timelines will be showing any user modification for
|
||||
# dueat startat endat receivedat, also notification to
|
||||
# the watchers and if any card is due, about due or past due.
|
||||
#
|
||||
# Notify due days, default 2 days before and after. 0 = due notifications disabled. Default: 2
|
||||
#- NOTIFY_DUE_DAYS_BEFORE_AND_AFTER=2
|
||||
#
|
||||
# Notify due at hour of day. Default every morning at 8am. Can be 0-23.
|
||||
# If env variable has parsing error, use default. Notification sent to watchers.
|
||||
#- NOTIFY_DUE_AT_HOUR_OF_DAY=8
|
||||
#-----------------------------------------------------------------
|
||||
# ==== EMAIL NOTIFICATION TIMEOUT, ms =====
|
||||
# Defaut: 30000 ms = 30s
|
||||
#- EMAIL_NOTIFICATION_TIMEOUT=30000
|
||||
@@ -392,8 +433,10 @@ services:
|
||||
# If the sync of the users should be done in the background
|
||||
#- LDAP_BACKGROUND_SYNC=false
|
||||
#
|
||||
# At which interval does the background task sync in milliseconds
|
||||
#- LDAP_BACKGROUND_SYNC_INTERVAL=100
|
||||
# At which interval does the background task sync in milliseconds.
|
||||
# Leave this unset, so it uses default, and does not crash.
|
||||
# https://github.com/wekan/wekan/issues/2354#issuecomment-515305722
|
||||
- LDAP_BACKGROUND_SYNC_INTERVAL=''
|
||||
#
|
||||
#- LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false
|
||||
#
|
||||
@@ -411,6 +454,9 @@ services:
|
||||
# Option to login to the LDAP server with the user's own username and password, instead of an administrator key. Default: false (use administrator key).
|
||||
#- LDAP_USER_AUTHENTICATION="true"
|
||||
#
|
||||
# Which field is used to find the user for the user authentication. Default: uid.
|
||||
#- LDAP_USER_AUTHENTICATION_FIELD="uid"
|
||||
#
|
||||
# Optional extra LDAP filters. Don't forget the outmost enclosing parentheses if needed
|
||||
#- LDAP_USER_SEARCH_FILTER=
|
||||
#
|
||||
|
||||
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+21
-2
@@ -699,8 +699,27 @@
|
||||
"duplicate-board": "Board duplizieren",
|
||||
"people-number": "Anzahl der Personen:",
|
||||
"swimlaneDeletePopup-title": "Swimlane löschen?",
|
||||
"swimlane-delete-pop": "Alle Aktionen werden aus dem Aktivitätenfeed entfernt und die Swimlane kann nicht wiederhergestellt werden. Es gibt kein Rückgängig!",
|
||||
"swimlane-delete-pop": "Alle Aktionen werden aus dem Aktivitätenfeed entfernt und die Swimlane kann nicht wiederhergestellt werden. Die Aktion kann nicht rückgängig gemacht werden.",
|
||||
"restore-all": "Alles wiederherstellen",
|
||||
"delete-all": "Alles löschen",
|
||||
"loading": "Laden, bitte warten."
|
||||
"loading": "Laden, bitte warten.",
|
||||
"previous_as": "letzter Zeitpunkt war",
|
||||
"act-a-dueAt": "hat Fälligkeit geändert auf\nWann: __timeValue__\nWo: __card__\nvorheriger Fälligkeitszeitpunkt war __timeOldValue__",
|
||||
"act-a-endAt": "hat Ende auf __timeValue__ von (__timeOldValue__) geändert",
|
||||
"act-a-startAt": "hat Start auf __timeValue__ von (__timeOldValue__) geändert",
|
||||
"act-a-receivedAt": "hat Empfangszeit auf __timeValue__ von (__timeOldValue__) geändert",
|
||||
"a-dueAt": "hat Fälligkeit geändert auf",
|
||||
"a-endAt": "hat Ende geändert auf",
|
||||
"a-startAt": "hat Startzeit geändert auf",
|
||||
"a-receivedAt": "hat Empfangszeit geändert auf",
|
||||
"almostdue": "aktuelles Fälligkeitsdatum %s bevorstehend",
|
||||
"pastdue": "aktuelles Fälligkeitsdatum %s überschritten",
|
||||
"duenow": "aktuelles Fälligkeitsdatum %s heute",
|
||||
"act-withDue": "__card__ fällige Erinnerungen [__board__]",
|
||||
"act-almostdue": "erinnernd an das aktuelle Fälligkeitszeitpunkt (__timeValue__) von __card__ ist bevorstehend",
|
||||
"act-pastdue": "erinnernd an das aktuelle Fälligkeitszeitpunkt (__timeValue__) von __card__ ist vorbei",
|
||||
"act-duenow": "erinnernd an das aktuelle Fälligkeitszeitpunkt (__timeValue__) von __card__ ist jetzt",
|
||||
"act-atUserComment": "Du wurdest erwähnt in [__board__] __card__",
|
||||
"delete-user-confirm-popup": "Sind Sie sicher, dass Sie diesen Account löschen wollen? Die Aktion kann nicht rückgängig gemacht werden.",
|
||||
"accounts-allowUserDelete": "Erlaube Benutzern ihren eigenen Account zu löschen"
|
||||
}
|
||||
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+726
-707
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+28
-9
@@ -589,10 +589,10 @@
|
||||
"r-when-a-card": "Cuando una tarjeta",
|
||||
"r-is": "es",
|
||||
"r-is-moved": "es movida",
|
||||
"r-added-to": "es agregada a",
|
||||
"r-removed-from": "Eliminado de",
|
||||
"r-added-to": "agregada a",
|
||||
"r-removed-from": "eliminado de",
|
||||
"r-the-board": "el tablero",
|
||||
"r-list": "lista",
|
||||
"r-list": "la lista",
|
||||
"set-filter": "Filtrar",
|
||||
"r-moved-to": "Movido a",
|
||||
"r-moved-from": "Movido desde",
|
||||
@@ -614,13 +614,13 @@
|
||||
"r-when-the-item": "Cuando el elemento de la lista de verificación es",
|
||||
"r-checked": "Marcado",
|
||||
"r-unchecked": "Desmarcado",
|
||||
"r-move-card-to": "Mover la tarjeta a",
|
||||
"r-move-card-to": "Mover la tarjeta",
|
||||
"r-top-of": "Arriba de",
|
||||
"r-bottom-of": "Abajo de",
|
||||
"r-its-list": "su lista",
|
||||
"r-archive": "Archivar",
|
||||
"r-unarchive": "Restaurar del Archivo",
|
||||
"r-card": "tarjeta",
|
||||
"r-card": "la tarjeta",
|
||||
"r-add": "Añadir",
|
||||
"r-remove": "Eliminar",
|
||||
"r-label": "etiqueta",
|
||||
@@ -651,9 +651,9 @@
|
||||
"r-d-unarchive": "Restaurar tarjeta del Archivo",
|
||||
"r-d-add-label": "Añadir etiqueta",
|
||||
"r-d-remove-label": "Eliminar etiqueta",
|
||||
"r-create-card": "Crear nueva tarjeta",
|
||||
"r-create-card": "Crear una nueva tarjeta",
|
||||
"r-in-list": "en la lista",
|
||||
"r-in-swimlane": "en carril",
|
||||
"r-in-swimlane": "en el carril",
|
||||
"r-d-add-member": "Añadir miembro",
|
||||
"r-d-remove-member": "Eliminar miembro",
|
||||
"r-d-remove-all-member": "Eliminar todos los miembros",
|
||||
@@ -668,7 +668,7 @@
|
||||
"r-add-checklist": "Añadir una lista de verificación",
|
||||
"r-with-items": "con items",
|
||||
"r-items-list": "item1,item2,item3",
|
||||
"r-add-swimlane": "Agregar carril",
|
||||
"r-add-swimlane": "Agregar el carril",
|
||||
"r-swimlane-name": "nombre del carril",
|
||||
"r-board-note": "Nota: deje un campo vacío para que coincida con todos los valores posibles",
|
||||
"r-checklist-note": "Nota: los ítems de la lista tienen que escribirse como valores separados por coma.",
|
||||
@@ -702,5 +702,24 @@
|
||||
"swimlane-delete-pop": "Todas las acciones serán eliminadas del historial de actividades y no se podrá recuperar el carril de flujo. Esta acción no puede deshacerse.",
|
||||
"restore-all": "Restaurar todas",
|
||||
"delete-all": "Borrar todas",
|
||||
"loading": "Cargando. Por favor, espere."
|
||||
"loading": "Cargando. Por favor, espere.",
|
||||
"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-withDue": "__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__] __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"
|
||||
}
|
||||
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+20
-1
@@ -702,5 +702,24 @@
|
||||
"swimlane-delete-pop": "כל הפעולות יוסרו מהזנת הפעילות ולא תהיה לך אפשרות לשחזר את המסלול. אי אפשר לחזור אחורה.",
|
||||
"restore-all": "לשחזר הכול",
|
||||
"delete-all": "למחוק הכול",
|
||||
"loading": "העמוד בטעינה, אנא המתינו."
|
||||
"loading": "העמוד בטעינה, אנא המתינו.",
|
||||
"previous_as": "הזמן הקודם היה",
|
||||
"act-a-dueAt": "זמן יעד שונה ל: \n__timeValue__\nבכרטיס: __card__\n זמן היעד הקודם היה __timeOldValue__",
|
||||
"act-a-endAt": "מועד הסיום השתנה לכדי __timeValue__ לעומת (__timeOldValue__)",
|
||||
"act-a-startAt": "מועד ההתחלה השתנה לכדי __timeValue__ לעומת (__timeOldValue__)",
|
||||
"act-a-receivedAt": "מועד הקבלה השתנה לכדי __timeValue__ לעומת (__timeOldValue__)",
|
||||
"a-dueAt": "מועד היעד השתנה לכדי",
|
||||
"a-endAt": "מועד הסיום השתנה לכדי",
|
||||
"a-startAt": "מועד ההתחלה השתנה לכדי",
|
||||
"a-receivedAt": "מועד הקבלה השתנה לכדי",
|
||||
"almostdue": "מועד היעד הנוכחי %s מתקרב",
|
||||
"pastdue": "מועד היעד הנוכחי %s חלף",
|
||||
"duenow": "מועד היעד הנוכחי %s הוא היום",
|
||||
"act-withDue": "__card__ תזכורות למועדי יעד [__board__]",
|
||||
"act-almostdue": "הזכירה שמועד היעד הנוכחי (__timeValue__) של __card__ מתקרב",
|
||||
"act-pastdue": "הזכירה שמועד היעד הנוכחי (__timeValue__) של __card__ חלף",
|
||||
"act-duenow": "הזכירה שמועד היעד הנוכחי (__timeValue__) של __card__ הוא עכשיו",
|
||||
"act-atUserComment": "אוזכרת תחת [__board__] __card__",
|
||||
"delete-user-confirm-popup": "למחוק את החשבון הזה? אי אפשר לבטל.",
|
||||
"accounts-allowUserDelete": "לאפשר למשתמשים למחוק את החשבונות של עצמם"
|
||||
}
|
||||
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+82
-63
@@ -1,45 +1,45 @@
|
||||
{
|
||||
"accept": "Akceptuj",
|
||||
"act-activity-notify": "Powiadomienia aktywności",
|
||||
"act-addAttachment": "Dodano załącznik __attachment__ do karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-deleteAttachment": "Usunięto załącznik __attachment__ na karcie __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addSubtask": "Dodane podzadanie __subtask__ na karcie __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addLabel": "Dodano etykietę __label__ do karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addedLabel": "Dodano etykietę __label__ do karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removeLabel": "Usunięto etykietę __label__ z karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removedLabel": "Usunięto etykietę __label__ z karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addChecklist": "Dodano listę zadań __checklist__ do karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addChecklistItem": "Dodano element listy zadań __checklistItem__ do listy zadań __checklist__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removeChecklist": "Usunięto listę zadań __checklist__ z karty __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removeChecklistItem": "Usunięto element listy zadań __checklistItem__ z listy zadań __checkList__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-checkedItem": "Zaznaczono __checklistItem__ na liście zadań __checklist__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-uncheckedItem": "Odznaczono __checklistItem__ na liście __checklist__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-completeChecklist": "Wykonano wszystkie zadania z listy __checklist__ na karcie __card__ na liście __list__ na diagramie czynności__ na tablicy __board__",
|
||||
"act-uncompleteChecklist": "Wycofano ukończenie wykonania listy __checklist__ na karcie __card__ na liście __list__ na diagramie czynności__ na tablicy __board__",
|
||||
"act-addComment": "Dodano komentarz na karcie __card__: __comment__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-editComment": "edytowano komentarz na karcie __card__: __comment__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-deleteComment": "usunięto komentarz na karcie __card__: __comment__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-createBoard": "Utworzono tablicę __board__",
|
||||
"act-createSwimlane": "utworzono diagram czynności __swimlane__ na tablicy __board__",
|
||||
"act-createCard": "Utworzono kartę __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-createCustomField": "utworzono niestandardowe pole __customField__ na tablicy __board__",
|
||||
"act-deleteCustomField": "usunięto niestandardowe pole __customField__ na tablicy __board__",
|
||||
"act-setCustomField": "zmodyfikowano niestandardowe pole __customField__: __customFieldValue__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-createList": "Dodano listę __list__ do tablicy __board__",
|
||||
"act-addBoardMember": "Dodano użytykownika __member__ do tablicy __board__",
|
||||
"act-addAttachment": "dodał(a) załącznik __attachment__ do karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-deleteAttachment": "usunął/usunęła załącznik __attachment__ na karcie __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addSubtask": "dodał(a) podzadanie __subtask__ na karcie __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addLabel": "dodał(a) etykietę __label__ do karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addedLabel": "dodał(a) etykietę __label__ do karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removeLabel": "usunął/usunęła etykietę __label__ z karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removedLabel": "usunął/usunęła etykietę __label__ z karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addChecklist": "dodał(a) listę zadań __checklist__ do karty __card__ na liście __list__ w diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-addChecklistItem": "dodał(a) element listy zadań __checklistItem__ do listy zadań __checklist__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removeChecklist": "usunął/usunęła listę zadań __checklist__ z karty __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removeChecklistItem": "usunął/usunęła element listy zadań __checklistItem__ z listy zadań __checkList__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-checkedItem": "zaznaczył(a) __checklistItem__ na liście zadań __checklist__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-uncheckedItem": "odznaczył(a) __checklistItem__ na liście __checklist__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-completeChecklist": "wykonał(a) wszystkie zadania z listy __checklist__ na karcie __card__ na liście __list__ na diagramie czynności__ na tablicy __board__",
|
||||
"act-uncompleteChecklist": "wycofał(a) ukończenie wykonania listy __checklist__ na karcie __card__ na liście __list__ na diagramie czynności__ na tablicy __board__",
|
||||
"act-addComment": "dodał(a) komentarz na karcie __card__: __comment__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-editComment": "edytował(a) komentarz na karcie __card__: __comment__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-deleteComment": "usunął/usunęła komentarz na karcie __card__: __comment__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-createBoard": "utworzył(a) tablicę __board__",
|
||||
"act-createSwimlane": "utworzył(a) diagram czynności __swimlane__ na tablicy __board__",
|
||||
"act-createCard": "utworzył(a) kartę __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-createCustomField": "utworzył(a) niestandardowe pole __customField__ na tablicy __board__",
|
||||
"act-deleteCustomField": "usunął/usunęła niestandardowe pole __customField__ na tablicy __board__",
|
||||
"act-setCustomField": "zmienił(a) niestandardowe pole __customField__: __customFieldValue__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-createList": "dodał(a) listę __list__ do tablicy __board__",
|
||||
"act-addBoardMember": "dodał(a) użytykownika __member__ do tablicy __board__",
|
||||
"act-archivedBoard": "Tablica __board__ została przeniesiona do Archiwum",
|
||||
"act-archivedCard": "Karta __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__ została przeniesiona do Archiwum",
|
||||
"act-archivedList": "Lista __list__ na diagramie czynności __swimlane__ na tablicy __board__ została przeniesiona do Archiwum",
|
||||
"act-archivedSwimlane": "Diagram czynności __swimlane__ na tablicy __board__ został przeniesiony do Archiwum",
|
||||
"act-importBoard": "Zaimportowano tablicę __board__",
|
||||
"act-importCard": "Zaimportowano kartę __card__ do listy __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-importList": "Zaimportowano listę __list__ na diagram czynności __swimlane__ do tablicy __board__",
|
||||
"act-joinMember": "Dodano użytkownika __member__ do karty __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-archivedCard": "przeniósł/przeniosła kartę __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__ do Archiwum",
|
||||
"act-archivedList": "przeniósł/przeniosła listę __list__ na diagramie czynności __swimlane__ na tablicy __board__ do Archiwum",
|
||||
"act-archivedSwimlane": "przeniósł/przeniosła diagram czynności __swimlane__ na tablicy __board__ do Archiwum",
|
||||
"act-importBoard": "zaimportował(a) tablicę __board__",
|
||||
"act-importCard": "zaimportował(a) kartę __card__ do listy __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-importList": "zaimportował(a) listę __list__ na diagram czynności __swimlane__ do tablicy __board__",
|
||||
"act-joinMember": "dodał(a) użytkownika __member__ do karty __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-moveCard": "przeniósł/a kartę __card__ na tablicy __board__ z listy __oldList__ na diagramie czynności __oldSwimlane__ na listę __list__ na diagramie czynności __swimlane__",
|
||||
"act-moveCardToOtherBoard": "przeniósł/a kartę __card__ z listy __oldList__ na diagramie czynności __oldSwimlane__ na tablicy __oldBoard__ do listy __listy__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removeBoardMember": "Usunięto użytkownika __member__ z tablicy __board__",
|
||||
"act-restoredCard": "Przywrócono kartę __card__ na listę __list__ na diagram czynności__ na tablicy __board__",
|
||||
"act-unjoinMember": "Usunięto użytkownika __member__ z karty __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-removeBoardMember": "usunął/usunęła użytkownika __member__ z tablicy __board__",
|
||||
"act-restoredCard": "przywrócił(a) kartę __card__ na listę __list__ na diagram czynności__ na tablicy __board__",
|
||||
"act-unjoinMember": "usunął/usunęła użytkownika __member__ z karty __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"act-withBoardTitle": "__board__",
|
||||
"act-withCardTitle": "[__board__] __card__",
|
||||
"actions": "Akcje",
|
||||
@@ -48,36 +48,36 @@
|
||||
"activity-added": "dodał(a) %s z %s",
|
||||
"activity-archived": "%s została przeniesiona do Archiwum",
|
||||
"activity-attached": "załączono %s z %s",
|
||||
"activity-created": "utworzono %s",
|
||||
"activity-customfield-created": "utworzono niestandardowe pole %s",
|
||||
"activity-created": "utworzył(a) %s",
|
||||
"activity-customfield-created": "utworzył(a) niestandardowe pole %s",
|
||||
"activity-excluded": "wyłączono %s z %s",
|
||||
"activity-imported": "zaimportowano %s to %s z %s",
|
||||
"activity-imported-board": "zaimportowano %s z %s",
|
||||
"activity-joined": "dołączono %s",
|
||||
"activity-moved": "przeniósł/przeniosła % z %s to %s",
|
||||
"activity-moved": "przeniesiono % z %s to %s",
|
||||
"activity-on": "w %s",
|
||||
"activity-removed": "usunięto %s z %s",
|
||||
"activity-sent": "wysłano %s z %s",
|
||||
"activity-unjoined": "odłączono %s",
|
||||
"activity-subtask-added": "dodał(a) podzadanie do %s",
|
||||
"activity-subtask-added": "dodano podzadanie do %s",
|
||||
"activity-checked-item": "zaznaczono %s w liście zadań%s z %s",
|
||||
"activity-unchecked-item": "odznaczono %s w liście zadań %s z %s",
|
||||
"activity-checklist-added": "dodał(a) listę zadań do %s",
|
||||
"activity-checklist-removed": "usunięto listę zadań z %s",
|
||||
"activity-checklist-completed": "Wykonano wszystkie zadania z listy __checklist__ na karcie __card__ na liście __list__ na diagramie czynności__ na tablicy __board__",
|
||||
"activity-checklist-removed": "usunął/usunęła listę zadań z %s",
|
||||
"activity-checklist-completed": "wykonał(a) wszystkie zadania z listy __checklist__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"activity-checklist-uncompleted": "nieukończono listy zadań %s z %s",
|
||||
"activity-checklist-item-added": "dodał(a) zadanie '%s' do %s",
|
||||
"activity-checklist-item-removed": "usunięto element z listy zadań '%s' w %s",
|
||||
"activity-checklist-item-removed": "usunął/usunęła element z listy zadań '%s' w %s",
|
||||
"add": "Dodaj",
|
||||
"activity-checked-item-card": "zaznaczono %s w liście zadań %s",
|
||||
"activity-unchecked-item-card": "odznaczono %s w liście zadań %s",
|
||||
"activity-checklist-completed-card": "Wykonano wszystkie zadania z listy __checklist__ na karcie __card__ na liście __list__ na diagramie czynności__ na tablicy __board__",
|
||||
"activity-checklist-uncompleted-card": "nieukończono listy zadań %s",
|
||||
"activity-checklist-completed-card": "wykonał(a) wszystkie zadania z listy __checklist__ na karcie __card__ na liście __list__ na diagramie czynności __swimlane__ na tablicy __board__",
|
||||
"activity-checklist-uncompleted-card": "wycofano ukończenie listy zadań %s",
|
||||
"add-attachment": "Dodaj załącznik",
|
||||
"add-board": "Dodaj tablicę",
|
||||
"add-card": "Dodaj kartę",
|
||||
"add-swimlane": "Dodaj diagram czynności",
|
||||
"add-subtask": "Dodano podzadanie",
|
||||
"add-subtask": "Dodaj podzadanie",
|
||||
"add-checklist": "Dodaj listę kontrolną",
|
||||
"add-checklist-item": "Dodaj element do listy kontrolnej",
|
||||
"add-cover": "Dodaj okładkę",
|
||||
@@ -118,7 +118,7 @@
|
||||
"attachmentDeletePopup-title": "Usunąć załącznik?",
|
||||
"attachments": "Załączniki",
|
||||
"auto-watch": "Automatycznie obserwuj tablice gdy zostaną stworzone",
|
||||
"avatar-too-big": "Awatar jest za duży (maksymalnie 70Kb)",
|
||||
"avatar-too-big": "Awatar jest za duży (maksymalnie 70KB)",
|
||||
"back": "Wstecz",
|
||||
"board-change-color": "Zmień kolor",
|
||||
"board-nb-stars": "%s odznaczeń",
|
||||
@@ -128,7 +128,7 @@
|
||||
"boardChangeColorPopup-title": "Zmień tło tablicy",
|
||||
"boardChangeTitlePopup-title": "Zmień nazwę tablicy",
|
||||
"boardChangeVisibilityPopup-title": "Zmień widoczność tablicy",
|
||||
"boardChangeWatchPopup-title": "Zmień sposób powiadamiania",
|
||||
"boardChangeWatchPopup-title": "Zmień sposób wysyłania powiadomień",
|
||||
"boardMenuPopup-title": "Ustawienia tablicy",
|
||||
"boards": "Tablice",
|
||||
"board-view": "Widok tablicy",
|
||||
@@ -154,7 +154,7 @@
|
||||
"card-members-title": "Dodaj lub usuń członków tablicy z karty.",
|
||||
"card-start": "Rozpoczęcie",
|
||||
"card-start-on": "Zaczyna się o",
|
||||
"cardAttachmentsPopup-title": "Załącz z",
|
||||
"cardAttachmentsPopup-title": "Dodaj załącznik z",
|
||||
"cardCustomField-datePopup-title": "Zmień datę",
|
||||
"cardCustomFieldsPopup-title": "Edytuj niestandardowe pola",
|
||||
"cardDeletePopup-title": "Usunąć kartę?",
|
||||
@@ -183,7 +183,7 @@
|
||||
"checklists": "Listy zadań",
|
||||
"click-to-star": "Kliknij by odznaczyć tę tablicę.",
|
||||
"click-to-unstar": "Kliknij by usunąć odznaczenie tej tablicy.",
|
||||
"clipboard": "Schowek lub przeciągnij & upuść",
|
||||
"clipboard": "Schowka lub poprzez przeciągnij & upuść",
|
||||
"close": "Zamknij",
|
||||
"close-board": "Zamknij tablicę",
|
||||
"close-board-pop": "Będziesz w stanie przywrócić tablicę poprzez kliknięcie przycisku \"Archiwizuj\" w nagłówku strony domowej.",
|
||||
@@ -219,7 +219,7 @@
|
||||
"comment-only-desc": "Może tylko komentować w kartach.",
|
||||
"no-comments": "Bez komentarzy",
|
||||
"no-comments-desc": "Nie widzi komentarzy i aktywności.",
|
||||
"computer": "Komputer",
|
||||
"computer": "Komputera",
|
||||
"confirm-subtask-delete-dialog": "Czy jesteś pewien, że chcesz usunąć to podzadanie?",
|
||||
"confirm-checklist-delete-dialog": "Czy jesteś pewien, że chcesz usunąć listę zadań?",
|
||||
"copy-card-link-to-clipboard": "Skopiuj łącze karty do schowka",
|
||||
@@ -337,9 +337,9 @@
|
||||
"initials": "Inicjały",
|
||||
"invalid-date": "Błędna data",
|
||||
"invalid-time": "Błędny czas",
|
||||
"invalid-user": "Zła nazwa użytkownika",
|
||||
"invalid-user": "Niepoprawna nazwa użytkownika",
|
||||
"joined": "dołączył",
|
||||
"just-invited": "Właśnie zostałeś zaproszony do tej tablicy",
|
||||
"just-invited": "Zostałeś zaproszony do tej tablicy",
|
||||
"keyboard-shortcuts": "Skróty klawiaturowe",
|
||||
"label-create": "Utwórz etykietę",
|
||||
"label-default": "'%s' etykieta (domyślna)",
|
||||
@@ -380,7 +380,7 @@
|
||||
"multi-selection": "Wielokrotne zaznaczenie",
|
||||
"multi-selection-on": "Wielokrotne zaznaczenie jest włączone",
|
||||
"muted": "Wycisz",
|
||||
"muted-info": "Nie zostaniesz powiadomiony o zmianach w tej tablicy",
|
||||
"muted-info": "Nie dostaniesz powiadomienia o zmianach w tej tablicy.",
|
||||
"my-boards": "Moje tablice",
|
||||
"name": "Nazwa",
|
||||
"no-archived-cards": "Brak kart w Archiwum.",
|
||||
@@ -455,7 +455,7 @@
|
||||
"time": "Czas",
|
||||
"title": "Tytuł",
|
||||
"tracking": "Śledzenie",
|
||||
"tracking-info": "Zostaniesz poinformowany o zmianach kart, w których bierzesz udział jako twórca lub członek.",
|
||||
"tracking-info": "Dostaniesz powiadomienie o zmianach kart, w których bierzesz udział jako twórca lub członek.",
|
||||
"type": "Typ",
|
||||
"unassign-member": "Nieprzypisany członek",
|
||||
"unsaved-description": "Masz niezapisany opis.",
|
||||
@@ -468,7 +468,7 @@
|
||||
"warn-list-archived": "Ostrzeżenie: ta karta jest na liście będącej w Archiwum",
|
||||
"watch": "Obserwuj",
|
||||
"watching": "Obserwujesz",
|
||||
"watching-info": "Będziesz poinformowany o każdej zmianie na tej tablicy",
|
||||
"watching-info": "Dostaniesz powiadomienie o każdej zmianie na tej tablicy.",
|
||||
"welcome-board": "Tablica powitalna",
|
||||
"welcome-swimlane": "Kamień milowy 1",
|
||||
"welcome-list1": "Podstawy",
|
||||
@@ -570,11 +570,11 @@
|
||||
"source-board": "Tablica źródłowa",
|
||||
"no-parent": "Nie pokazuj rodzica",
|
||||
"activity-added-label": "dodał(a) etykietę '%s' z '%s'",
|
||||
"activity-removed-label": "usunięto etykietę '%s' z '%s'",
|
||||
"activity-delete-attach": "usunięto załącznik z %s",
|
||||
"activity-removed-label": "usunął/usunęła etykietę '%s' z '%s'",
|
||||
"activity-delete-attach": "usunął/usunęła załącznik z %s",
|
||||
"activity-added-label-card": "dodał(a) etykietę '%s'",
|
||||
"activity-removed-label-card": "usunięto etykietę '%s'",
|
||||
"activity-delete-attach-card": "usunięto załącznik",
|
||||
"activity-removed-label-card": "usunął/usunęła etykietę '%s'",
|
||||
"activity-delete-attach-card": "usunął/usunęła załącznik",
|
||||
"activity-set-customfield": "ustawiono niestandardowe pole '%s' do '%s' na '%s'",
|
||||
"activity-unset-customfield": "wyczyszczono niestandardowe pole '%s' na '%s'",
|
||||
"r-rule": "Reguła",
|
||||
@@ -590,7 +590,7 @@
|
||||
"r-is": "jest",
|
||||
"r-is-moved": "jest przenoszona",
|
||||
"r-added-to": "dodana do",
|
||||
"r-removed-from": "Usunięto z",
|
||||
"r-removed-from": "usunął/usunęła z",
|
||||
"r-the-board": "tablicy",
|
||||
"r-list": "lista",
|
||||
"set-filter": "Ustaw filtr",
|
||||
@@ -681,7 +681,7 @@
|
||||
"r-df-end-at": "zakończenie",
|
||||
"r-df-received-at": "odebrano",
|
||||
"r-to-current-datetime": "o aktualnej dacie/godzinie",
|
||||
"r-remove-value-from": "Usunięto wartość z",
|
||||
"r-remove-value-from": "usunął/usunęła wartość z",
|
||||
"ldap": "LDAP",
|
||||
"oauth2": "OAuth2",
|
||||
"cas": "CAS",
|
||||
@@ -702,5 +702,24 @@
|
||||
"swimlane-delete-pop": "Wszystkie akcje będą usunięte z widoku aktywności, nie można będzie przywrócić diagramu czynności. Usunięcie jest nieodwracalne.",
|
||||
"restore-all": "Przywróć wszystkie",
|
||||
"delete-all": "Usuń wszystkie",
|
||||
"loading": "Ładowanie, proszę czekać."
|
||||
"loading": "Ładowanie, proszę czekać.",
|
||||
"previous_as": "ostatni czas był",
|
||||
"act-a-dueAt": "zmienił(a) czas zakończenia na: __timeValue__ w karcie __card__, poprzedni czas: __timeOldValue__",
|
||||
"act-a-endAt": "zmienił(a) czas zakończenia na __timeValue__ z __timeOldValue__",
|
||||
"act-a-startAt": "zmienił(a) czas rozpoczęcia na __timeValue__ z __timeOldValue__",
|
||||
"act-a-receivedAt": "zmienił(a) czas odebrania zadania na __timeValue__ z __timeOldValue__",
|
||||
"a-dueAt": "zmieniono czas zakończenia na",
|
||||
"a-endAt": "zmieniono czas zakończenia na",
|
||||
"a-startAt": "zmieniono czas startu na",
|
||||
"a-receivedAt": "zmieniono czas odebrania zadania na",
|
||||
"almostdue": "aktualny termin ukończenia %s dobiega końca",
|
||||
"pastdue": "aktualny termin ukończenia %s jest w przeszłości",
|
||||
"duenow": "aktualny termin ukończenia %s jest dzisiaj",
|
||||
"act-withDue": "__card__ ma przypomnienia zakończenia terminu [__board__]",
|
||||
"act-almostdue": "przypomina o zbliżającej się dacie ukończenia (__timeValue__) karty __card__",
|
||||
"act-pastdue": "przypomina o ubiegłej dacie ukończenia (__timeValue__) karty __card__",
|
||||
"act-duenow": "przypomina o ubiegającej teraz dacie ukończenia (__timeValue__) karty __card__",
|
||||
"act-atUserComment": "Zostałeś wspomniany na __board__ (__card__)",
|
||||
"delete-user-confirm-popup": "Czy jesteś pewien, że chcesz usunąć te konto? Nie można tego wycofać.",
|
||||
"accounts-allowUserDelete": "Pozwól użytkownikom na usuwanie własnych kont"
|
||||
}
|
||||
+28
-9
@@ -143,8 +143,8 @@
|
||||
"card-delete-notice": "A exclusão será permanente. Você perderá todas as ações associadas a este cartão.",
|
||||
"card-delete-pop": "Todas as ações serão excluidas da lista de Atividades e vocês não poderá re-abrir o cartão. Não há como desfazer.",
|
||||
"card-delete-suggest-archive": "Você pode mover um cartão para o Arquivo-morto para removê-lo do quadro e preservar a atividade.",
|
||||
"card-due": "Data fim",
|
||||
"card-due-on": "Finaliza em",
|
||||
"card-due": "Prazo final",
|
||||
"card-due-on": "Prazo final em",
|
||||
"card-spent": "Tempo Gasto",
|
||||
"card-edit-attachments": "Editar anexos",
|
||||
"card-edit-custom-fields": "Editar campos customizados",
|
||||
@@ -265,7 +265,7 @@
|
||||
"edit-wip-limit": "Editar Limite WIP",
|
||||
"soft-wip-limit": "Limite de WIP",
|
||||
"editCardStartDatePopup-title": "Altera data de início",
|
||||
"editCardDueDatePopup-title": "Altera data fim",
|
||||
"editCardDueDatePopup-title": "Altera prazo final",
|
||||
"editCustomFieldPopup-title": "Editar campo",
|
||||
"editCardSpentTimePopup-title": "Editar tempo gasto",
|
||||
"editLabelPopup-title": "Alterar Etiqueta",
|
||||
@@ -538,10 +538,10 @@
|
||||
"active": "Ativo",
|
||||
"card-received": "Recebido",
|
||||
"card-received-on": "Recebido em",
|
||||
"card-end": "Fim",
|
||||
"card-end-on": "Termina em",
|
||||
"card-end": "Concluído",
|
||||
"card-end-on": "Concluído em",
|
||||
"editCardReceivedDatePopup-title": "Modificar data de recebimento",
|
||||
"editCardEndDatePopup-title": "Mudar data de fim",
|
||||
"editCardEndDatePopup-title": "Mudar data de conclusão",
|
||||
"setCardColorPopup-title": "Definir cor",
|
||||
"setCardActionsColorPopup-title": "Escolha uma cor",
|
||||
"setSwimlaneColorPopup-title": "Escolha uma cor",
|
||||
@@ -677,8 +677,8 @@
|
||||
"r-update": "Atualizar",
|
||||
"r-datefield": "campo data",
|
||||
"r-df-start-at": "início",
|
||||
"r-df-due-at": "data fim",
|
||||
"r-df-end-at": "fim",
|
||||
"r-df-due-at": "prazo final",
|
||||
"r-df-end-at": "concluído",
|
||||
"r-df-received-at": "recebido",
|
||||
"r-to-current-datetime": "para data/hora atuais",
|
||||
"r-remove-value-from": "Remover valores do",
|
||||
@@ -702,5 +702,24 @@
|
||||
"swimlane-delete-pop": "Todas as ações serão excluídas da lista de atividades e você não poderá recuperar a raia. Não há como desfazer.",
|
||||
"restore-all": "Restaurar tudo",
|
||||
"delete-all": "Excluir tudo",
|
||||
"loading": "Carregando, aguarde por favor."
|
||||
"loading": "Carregando, aguarde por favor.",
|
||||
"previous_as": "ultima vez foi",
|
||||
"act-a-dueAt": "prazo final modificado para \nQuando: __timeValue__\nOnde: __card__\n prazo final anterior era __timeOldValue__",
|
||||
"act-a-endAt": "hora de conclusão modificada de (__timeOldValue__) para __timeValue__ ",
|
||||
"act-a-startAt": "hora de início modificada de (__timeOldValue__) para __timeValue__ ",
|
||||
"act-a-receivedAt": "hora de recebido modificada de (__timeOldValue__) para __timeValue__ ",
|
||||
"a-dueAt": "prazo final modificado para",
|
||||
"a-endAt": "hora de conclusão modificada para",
|
||||
"a-startAt": "hora de início modificada para",
|
||||
"a-receivedAt": "hora de recebido modificada para",
|
||||
"almostdue": "prazo final atual %s está próximo",
|
||||
"pastdue": "prazo final atual %s venceu",
|
||||
"duenow": "prazo final atual %s é hoje",
|
||||
"act-withDue": "__card__ lembrete de prazos finais [__board__]",
|
||||
"act-almostdue": "está lembrando que o prazo final atual (__timeValue__) do __card__ está próximo",
|
||||
"act-pastdue": "está lembrando que o prazo final atual (__timeValue__) do __card__ venceu",
|
||||
"act-duenow": "está lembrando que o prazo final (__timeValue__) do __card__ é agora",
|
||||
"act-atUserComment": "Você foi mencionado no [__board__] __card__",
|
||||
"delete-user-confirm-popup": "Você realmente quer apagar esta conta? Não há como desfazer.",
|
||||
"accounts-allowUserDelete": "Permitir que usuários apaguem a própria conta"
|
||||
}
|
||||
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+724
-705
File diff suppressed because it is too large.
Load diff
+20
-1
@@ -702,5 +702,24 @@
|
||||
"swimlane-delete-pop": "所有活动将从活动源中删除,您将无法恢复泳道。此操作无法撤销。",
|
||||
"restore-all": "全部恢复",
|
||||
"delete-all": "全部删除",
|
||||
"loading": "加载中,请稍等。"
|
||||
"loading": "加载中,请稍等。",
|
||||
"previous_as": "上次是",
|
||||
"act-a-dueAt": "修改到期时间:\n时间:__timeValue__\n位置:__card__\n上一个到期日是 __timeOldValue__",
|
||||
"act-a-endAt": "修改结束时间从 (__timeOldValue__) 至 __timeValue__",
|
||||
"act-a-startAt": "修改开始时间从 (__timeOldValue__) 至 __timeValue__",
|
||||
"act-a-receivedAt": "修改接收时间从 (__timeOldValue__) 至 __timeValue__",
|
||||
"a-dueAt": "修改到期时间",
|
||||
"a-endAt": "修改结束时间",
|
||||
"a-startAt": "修改开始时间",
|
||||
"a-receivedAt": "修改接收时间",
|
||||
"almostdue": "当前到期时间%s即将到来",
|
||||
"pastdue": "当前到期时间%s已过",
|
||||
"duenow": "当前到期时间%s为今天",
|
||||
"act-withDue": "__card__ 到期提醒[__board__]",
|
||||
"act-almostdue": "__card__ 的当前到期提醒(__timeValue__) 正在接近",
|
||||
"act-pastdue": "__card__ 的当前到期提醒(__timeValue__) 已经过去了",
|
||||
"act-duenow": "__card__ 的当前到期提醒(__timeValue__) 现在到期",
|
||||
"act-atUserComment": "您在 [__board__] __card__中被提到",
|
||||
"delete-user-confirm-popup": "确实要删除此帐户吗?此操作无法撤销。",
|
||||
"accounts-allowUserDelete": "允许用户自行删除其帐户"
|
||||
}
|
||||
+724
-705
File diff suppressed because it is too large.
Load diff
+20
-1
@@ -702,5 +702,24 @@
|
||||
"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": "全部還原",
|
||||
"delete-all": "全部刪除",
|
||||
"loading": "讀取中,請稍後"
|
||||
"loading": "讀取中,請稍後",
|
||||
"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-withDue": "__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__] __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"
|
||||
}
|
||||
@@ -68,6 +68,15 @@ if (Meteor.isServer) {
|
||||
},
|
||||
},
|
||||
);
|
||||
AccountSettings.upsert(
|
||||
{ _id: 'accounts-allowUserDelete' },
|
||||
{
|
||||
$setOnInsert: {
|
||||
booleanValue: false,
|
||||
sort: 0,
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+48
-2
@@ -171,6 +171,26 @@ if (Meteor.isServer) {
|
||||
if (activity.commentId) {
|
||||
const comment = activity.comment();
|
||||
params.comment = comment.text;
|
||||
if (board) {
|
||||
const atUser = /(?:^|\s+)@(\S+)(?:\s+|$)/g;
|
||||
const comment = params.comment;
|
||||
if (comment.match(atUser)) {
|
||||
const commenter = params.user;
|
||||
while (atUser.exec(comment)) {
|
||||
const username = RegExp.$1;
|
||||
if (commenter === username) {
|
||||
// it's person at himself, ignore it?
|
||||
continue;
|
||||
}
|
||||
const user = Users.findOne(username) || Users.findOne({ username });
|
||||
const uid = user && user._id;
|
||||
if (board.hasMember(uid)) {
|
||||
title = 'act-atUserComment';
|
||||
watchers = _.union(watchers, [uid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
params.commentId = comment._id;
|
||||
}
|
||||
if (activity.attachmentId) {
|
||||
@@ -189,7 +209,9 @@ if (Meteor.isServer) {
|
||||
if (activity.customFieldId) {
|
||||
const customField = activity.customField();
|
||||
params.customField = customField.name;
|
||||
params.customFieldValue = customField.text;
|
||||
params.customFieldValue = Activities.findOne({
|
||||
customFieldId: customField._id,
|
||||
}).value;
|
||||
}
|
||||
// Label activity did not work yet, unable to edit labels when tried this.
|
||||
//if (activity.labelId) {
|
||||
@@ -197,7 +219,32 @@ if (Meteor.isServer) {
|
||||
// params.label = label.name;
|
||||
// params.labelId = activity.labelId;
|
||||
//}
|
||||
if (
|
||||
(!activity.timeKey || activity.timeKey === 'dueAt') &&
|
||||
activity.timeValue
|
||||
) {
|
||||
// due time reminder
|
||||
title = 'act-withDue';
|
||||
}
|
||||
['timeValue', 'timeOldValue'].forEach(key => {
|
||||
// copy time related keys & values to params
|
||||
const value = activity[key];
|
||||
if (value) params[key] = value;
|
||||
});
|
||||
if (board) {
|
||||
const BIGEVENTS = process.env.BIGEVENTS_PATTERN || 'due'; // if environment BIGEVENTS_PATTERN is set or default, any activityType matching it is important
|
||||
try {
|
||||
const atype = activity.activityType;
|
||||
if (new RegExp(BIGEVENTS).exec(atype)) {
|
||||
watchers = _.union(
|
||||
watchers,
|
||||
board.activeMembers().map(member => member.userId),
|
||||
); // notify all active members for important events system defined or default to all activity related to due date
|
||||
}
|
||||
} catch (e) {
|
||||
// passed env var BIGEVENTS_PATTERN is not a valid regex
|
||||
}
|
||||
|
||||
const watchingUsers = _.pluck(
|
||||
_.where(board.watchers, { level: 'watching' }),
|
||||
'userId',
|
||||
@@ -212,7 +259,6 @@ if (Meteor.isServer) {
|
||||
_.intersection(participants, trackingUsers),
|
||||
);
|
||||
}
|
||||
|
||||
Notifications.getUsers(watchers).forEach(user => {
|
||||
Notifications.notify(user, title, description, params);
|
||||
});
|
||||
|
||||
+21
-1
@@ -238,7 +238,13 @@ Boards.attachSchema(
|
||||
'pomegranate',
|
||||
'pumpkin',
|
||||
'wisteria',
|
||||
'moderatepink',
|
||||
'strongcyan',
|
||||
'limegreen',
|
||||
'midnight',
|
||||
'dark',
|
||||
'relax',
|
||||
'corteza',
|
||||
],
|
||||
// eslint-disable-next-line consistent-return
|
||||
autoValue() {
|
||||
@@ -946,6 +952,19 @@ if (Meteor.isServer) {
|
||||
} else throw new Meteor.Error('error-board-notAMember');
|
||||
} else throw new Meteor.Error('error-board-doesNotExist');
|
||||
},
|
||||
acceptInvite(boardId) {
|
||||
check(boardId, String);
|
||||
const board = Boards.findOne(boardId);
|
||||
if (!board) {
|
||||
throw new Meteor.Error('error-board-doesNotExist');
|
||||
}
|
||||
|
||||
Meteor.users.update(Meteor.userId(), {
|
||||
$pull: {
|
||||
'profile.invitedBoards': boardId,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Meteor.methods({
|
||||
@@ -1223,7 +1242,8 @@ if (Meteor.isServer) {
|
||||
* @description This allows to create a board.
|
||||
*
|
||||
* The color has to be chosen between `belize`, `nephritis`, `pomegranate`,
|
||||
* `pumpkin`, `wisteria`, `midnight`:
|
||||
* `pumpkin`, `wisteria`, `moderatepink`, `strongcyan`,
|
||||
* `limegreen`, `midnight`, `dark`, `relax`, `corteza`:
|
||||
*
|
||||
* <img src="https://wekan.github.io/board-colors.png" width="40%" alt="Wekan logo" />
|
||||
*
|
||||
|
||||
+90
-1
@@ -1553,6 +1553,61 @@ function cardRemover(userId, doc) {
|
||||
});
|
||||
}
|
||||
|
||||
const findDueCards = days => {
|
||||
const seekDue = ($from, $to, activityType) => {
|
||||
Cards.find({
|
||||
dueAt: { $gte: $from, $lt: $to },
|
||||
}).forEach(card => {
|
||||
const username = Users.findOne(card.userId).username;
|
||||
const activity = {
|
||||
userId: card.userId,
|
||||
username,
|
||||
activityType,
|
||||
boardId: card.boardId,
|
||||
cardId: card._id,
|
||||
cardTitle: card.title,
|
||||
listId: card.listId,
|
||||
timeValue: card.dueAt,
|
||||
swimlaneId: card.swimlaneId,
|
||||
};
|
||||
Activities.insert(activity);
|
||||
});
|
||||
};
|
||||
const now = new Date(),
|
||||
aday = 3600 * 24 * 1e3,
|
||||
then = day => new Date(now.setHours(0, 0, 0, 0) + day * aday);
|
||||
seekDue(then(1), then(days), 'almostdue');
|
||||
seekDue(then(0), then(1), 'duenow');
|
||||
seekDue(then(-days), now, 'pastdue');
|
||||
};
|
||||
const addCronJob = _.debounce(
|
||||
Meteor.bindEnvironment(function findDueCardsDebounced() {
|
||||
const notifydays =
|
||||
parseInt(process.env.NOTIFY_DUE_DAYS_BEFORE_AND_AFTER, 10) || 2; // default as 2 days before and after
|
||||
if (!(notifydays > 0 && notifydays < 15)) {
|
||||
// notifying due is disabled
|
||||
return;
|
||||
}
|
||||
const notifyitvl = process.env.NOTIFY_DUE_AT_HOUR_OF_DAY; //passed in the itvl has to be a number standing for the hour of current time
|
||||
const defaultitvl = 8; // default every morning at 8am, if the passed env variable has parsing error use default
|
||||
const itvl = parseInt(notifyitvl, 10) || defaultitvl;
|
||||
const scheduler = (job => () => {
|
||||
const now = new Date();
|
||||
const hour = 3600 * 1e3;
|
||||
if (now.getHours() === itvl) {
|
||||
if (typeof job === 'function') {
|
||||
job();
|
||||
}
|
||||
}
|
||||
Meteor.setTimeout(scheduler, hour);
|
||||
})(() => {
|
||||
findDueCards(notifydays);
|
||||
});
|
||||
scheduler();
|
||||
}),
|
||||
500,
|
||||
);
|
||||
|
||||
if (Meteor.isServer) {
|
||||
// Cards are often fetched within a board, so we create an index to make these
|
||||
// queries more efficient.
|
||||
@@ -1565,12 +1620,17 @@ if (Meteor.isServer) {
|
||||
// With a huge database, this result in a very slow app and high CPU on the mongodb side.
|
||||
// To correct it, add Index to parentId:
|
||||
Cards._collection._ensureIndex({ parentId: 1 });
|
||||
// let notifydays = parseInt(process.env.NOTIFY_DUE_DAYS_BEFORE_AND_AFTER) || 2; // default as 2 days b4 and after
|
||||
// let notifyitvl = parseInt(process.env.NOTIFY_DUE_AT_HOUR_OF_DAY) || 3600 * 24 * 1e3; // default interval as one day
|
||||
// Meteor.call("findDueCards",notifydays,notifyitvl);
|
||||
Meteor.defer(() => {
|
||||
addCronJob();
|
||||
});
|
||||
});
|
||||
|
||||
Cards.after.insert((userId, doc) => {
|
||||
cardCreation(userId, doc);
|
||||
});
|
||||
|
||||
// New activity for card (un)archivage
|
||||
Cards.after.update((userId, doc, fieldNames) => {
|
||||
cardState(userId, doc, fieldNames);
|
||||
@@ -1600,6 +1660,35 @@ if (Meteor.isServer) {
|
||||
cardCustomFields(userId, doc, fieldNames, modifier);
|
||||
});
|
||||
|
||||
// Add a new activity if modify time related field like dueAt startAt etc
|
||||
Cards.before.update((userId, doc, fieldNames, modifier) => {
|
||||
const dla = 'dateLastActivity';
|
||||
const fields = fieldNames.filter(name => name !== dla);
|
||||
const timingaction = ['receivedAt', 'dueAt', 'startAt', 'endAt'];
|
||||
const action = fields[0];
|
||||
if (fields.length > 0 && _.contains(timingaction, action)) {
|
||||
// add activities for user change these attributes
|
||||
const value = modifier.$set[action];
|
||||
const oldvalue = doc[action] || '';
|
||||
const activityType = `a-${action}`;
|
||||
const card = Cards.findOne(doc._id);
|
||||
const username = Users.findOne(userId).username;
|
||||
const activity = {
|
||||
userId,
|
||||
username,
|
||||
activityType,
|
||||
boardId: doc.boardId,
|
||||
cardId: doc._id,
|
||||
cardTitle: doc.title,
|
||||
timeKey: action,
|
||||
timeValue: value,
|
||||
timeOldValue: oldvalue,
|
||||
listId: card.listId,
|
||||
swimlaneId: card.swimlaneId,
|
||||
};
|
||||
Activities.insert(activity);
|
||||
}
|
||||
});
|
||||
// Remove all activities associated with a card if we remove the card
|
||||
// Remove also card_comments / checklists / attachments
|
||||
Cards.before.remove((userId, doc) => {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Counters = new Mongo.Collection('counters');
|
||||
@@ -165,11 +165,15 @@ function customFieldDeletion(userId, doc) {
|
||||
// instead it shows undefined, and no listId and swimlaneId.
|
||||
function customFieldEdit(userId, doc) {
|
||||
const card = Cards.findOne(doc.cardId);
|
||||
const customFieldValue = Activities.findOne({ customFieldId: doc._id }).value;
|
||||
const boardId = card.boardId;
|
||||
//boardId: doc.boardIds[0], // We are creating a customField, it has only one boardId
|
||||
Activities.insert({
|
||||
userId,
|
||||
activityType: 'editCustomField',
|
||||
boardId: doc.boardIds[0], // We are creating a customField, it has only one boardId
|
||||
activityType: 'setCustomField',
|
||||
boardId,
|
||||
customFieldId: doc._id,
|
||||
customFieldValue,
|
||||
listId: card.listId,
|
||||
swimlaneId: card.swimlaneId,
|
||||
});
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
Org = new Mongo.Collection('org');
|
||||
|
||||
/**
|
||||
* A Organization in wekan
|
||||
*/
|
||||
Org.attachSchema(
|
||||
new SimpleSchema({
|
||||
_id: {
|
||||
/**
|
||||
* the organization id
|
||||
*/
|
||||
type: Number,
|
||||
optional: true,
|
||||
// eslint-disable-next-line consistent-return
|
||||
autoValue() {
|
||||
if (this.isInsert && !this.isSet) {
|
||||
return incrementCounter('counters', 'orgId', 1);
|
||||
}
|
||||
},
|
||||
},
|
||||
version: {
|
||||
/**
|
||||
* the version of the organization
|
||||
*/
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
name: {
|
||||
/**
|
||||
* name of the organization
|
||||
*/
|
||||
type: String,
|
||||
optional: true,
|
||||
max: 190,
|
||||
},
|
||||
address1: {
|
||||
/**
|
||||
* address1 of the organization
|
||||
*/
|
||||
type: String,
|
||||
optional: true,
|
||||
max: 255,
|
||||
},
|
||||
address2: {
|
||||
/**
|
||||
* address2 of the organization
|
||||
*/
|
||||
type: String,
|
||||
optional: true,
|
||||
max: 255,
|
||||
},
|
||||
city: {
|
||||
/**
|
||||
* city of the organization
|
||||
*/
|
||||
type: String,
|
||||
optional: true,
|
||||
max: 255,
|
||||
},
|
||||
state: {
|
||||
/**
|
||||
* state of the organization
|
||||
*/
|
||||
type: String,
|
||||
optional: true,
|
||||
max: 255,
|
||||
},
|
||||
zipCode: {
|
||||
/**
|
||||
* zipCode of the organization
|
||||
*/
|
||||
type: String,
|
||||
optional: true,
|
||||
max: 50,
|
||||
},
|
||||
country: {
|
||||
/**
|
||||
* country of the organization
|
||||
*/
|
||||
type: String,
|
||||
optional: true,
|
||||
max: 255,
|
||||
},
|
||||
billingEmail: {
|
||||
/**
|
||||
* billingEmail of the organization
|
||||
*/
|
||||
type: String,
|
||||
optional: true,
|
||||
max: 255,
|
||||
},
|
||||
createdAt: {
|
||||
/**
|
||||
* creation date of the organization
|
||||
*/
|
||||
type: Date,
|
||||
// eslint-disable-next-line consistent-return
|
||||
autoValue() {
|
||||
if (this.isInsert) {
|
||||
return new Date();
|
||||
} else {
|
||||
this.unset();
|
||||
}
|
||||
},
|
||||
},
|
||||
modifiedAt: {
|
||||
type: Date,
|
||||
denyUpdate: false,
|
||||
// eslint-disable-next-line consistent-return
|
||||
autoValue() {
|
||||
if (this.isInsert || this.isUpsert || this.isUpdate) {
|
||||
return new Date();
|
||||
} else {
|
||||
this.unset();
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
if (Meteor.isServer) {
|
||||
// Index for Organization name.
|
||||
Meteor.startup(() => {
|
||||
Org._collection._ensureIndex({ name: -1 });
|
||||
});
|
||||
}
|
||||
|
||||
export default Org;
|
||||
@@ -0,0 +1,80 @@
|
||||
OrgUser = new Mongo.Collection('orgUser');
|
||||
|
||||
/**
|
||||
* A Organization User in wekan
|
||||
*/
|
||||
OrgUser.attachSchema(
|
||||
new SimpleSchema({
|
||||
_id: {
|
||||
/**
|
||||
* the organization user's id
|
||||
*/
|
||||
type: Number,
|
||||
optional: true,
|
||||
// eslint-disable-next-line consistent-return
|
||||
autoValue() {
|
||||
if (this.isInsert && !this.isSet) {
|
||||
return incrementCounter('counters', 'orgUserId', 1);
|
||||
}
|
||||
},
|
||||
},
|
||||
orgId: {
|
||||
/**
|
||||
* the organization id
|
||||
*/
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
userId: {
|
||||
/**
|
||||
* the user id
|
||||
*/
|
||||
type: Number,
|
||||
optional: true,
|
||||
},
|
||||
role: {
|
||||
/**
|
||||
* the role of user
|
||||
*/
|
||||
type: String,
|
||||
optional: true,
|
||||
max: 20,
|
||||
},
|
||||
createdAt: {
|
||||
/**
|
||||
* creation date of the organization user
|
||||
*/
|
||||
type: Date,
|
||||
// eslint-disable-next-line consistent-return
|
||||
autoValue() {
|
||||
if (this.isInsert) {
|
||||
return new Date();
|
||||
} else {
|
||||
this.unset();
|
||||
}
|
||||
},
|
||||
},
|
||||
modifiedAt: {
|
||||
type: Date,
|
||||
denyUpdate: false,
|
||||
// eslint-disable-next-line consistent-return
|
||||
autoValue() {
|
||||
if (this.isInsert || this.isUpsert || this.isUpdate) {
|
||||
return new Date();
|
||||
} else {
|
||||
this.unset();
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
if (Meteor.isServer) {
|
||||
// Index for Organization User.
|
||||
Meteor.startup(() => {
|
||||
OrgUser._collection._ensureIndex({ orgId: -1 });
|
||||
OrgUser._collection._ensureIndex({ orgId: -1, userId: -1 });
|
||||
});
|
||||
}
|
||||
|
||||
export default OrgUser;
|
||||
@@ -484,9 +484,9 @@ export class TrelloCreator {
|
||||
green: 'nephritis',
|
||||
red: 'pomegranate',
|
||||
purple: 'wisteria',
|
||||
pink: 'pomegranate',
|
||||
lime: 'nephritis',
|
||||
sky: 'belize',
|
||||
pink: 'moderatepink',
|
||||
lime: 'limegreen',
|
||||
sky: 'strongcyan',
|
||||
grey: 'midnight',
|
||||
};
|
||||
const wekanColor = mapColors[trelloColorCode];
|
||||
|
||||
+4
-4
@@ -352,17 +352,17 @@ parameters:
|
||||
name: VOLUME_CAPACITY
|
||||
required: true
|
||||
value: 1Gi
|
||||
- description: Version of MongoDB image to be used (2.4, 2.6, 3.2 or latest).
|
||||
- description: Version of MongoDB image to be used (3.6, 4.0.10).
|
||||
displayName: Version of MongoDB Image
|
||||
name: MONGODB_VERSION
|
||||
required: true
|
||||
value: '3.2'
|
||||
value: '4.0.10'
|
||||
- name: WEKAN_SERVICE_NAME
|
||||
displayName: Wekan Service Name
|
||||
value: wekan
|
||||
required: true
|
||||
- name: WEKAN_IMAGE
|
||||
displayName: WeKan Docker Image
|
||||
value: quay.io/wekan/wekan:latest
|
||||
displayName: Wekan Docker Image
|
||||
value: wekanteam/wekan:latest
|
||||
description: The metabase docker image to use
|
||||
required: true
|
||||
Generated
+4973
File diff suppressed because it is too large.
Load diff
+5
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wekan",
|
||||
"version": "v2.94.0",
|
||||
"version": "v3.03.0",
|
||||
"description": "Open-Source kanban",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -45,7 +45,7 @@
|
||||
"eslint-config-prettier": "^3.6.0",
|
||||
"eslint-import-resolver-meteor": "^0.4.0",
|
||||
"eslint-plugin-import": "^2.18.0",
|
||||
"eslint-plugin-meteor": "^4.2.2",
|
||||
"eslint-plugin-meteor": "^5.1.0",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
"lint-staged": "^7.3.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
@@ -53,7 +53,8 @@
|
||||
"prettier-eslint": "^8.8.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.3",
|
||||
"@babel/runtime": "^7.5.4",
|
||||
"ajv": "^5.0.0",
|
||||
"bcrypt": "^3.0.2",
|
||||
"bson": "^4.0.0",
|
||||
"bunyan": "^1.8.12",
|
||||
@@ -64,6 +65,6 @@
|
||||
"page": "^1.8.6",
|
||||
"qs": "^6.5.2",
|
||||
"source-map-support": "^0.5.12",
|
||||
"xss": "^1.0.3"
|
||||
"xss": "^1.0.6"
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ Package.onUse(function(api) {
|
||||
|
||||
api.use('accounts-base', 'server');
|
||||
api.use('accounts-password', 'server');
|
||||
|
||||
api.use('percolate:synced-cron', 'server');
|
||||
api.addFiles('client/loginHelper.js', 'client');
|
||||
|
||||
api.mainModule('server/index.js', 'server');
|
||||
|
||||
@@ -27,6 +27,7 @@ export default class LDAP {
|
||||
BaseDN : this.constructor.settings_get('LDAP_BASEDN'),
|
||||
Internal_Log_Level : this.constructor.settings_get('INTERNAL_LOG_LEVEL'),
|
||||
User_Authentication : this.constructor.settings_get('LDAP_USER_AUTHENTICATION'),
|
||||
User_Authentication_Field : this.constructor.settings_get('LDAP_USER_AUTHENTICATION_FIELD'),
|
||||
User_Attributes : this.constructor.settings_get('LDAP_USER_ATTRIBUTES'),
|
||||
User_Search_Filter : this.constructor.settings_get('LDAP_USER_SEARCH_FILTER'),
|
||||
User_Search_Scope : this.constructor.settings_get('LDAP_USER_SEARCH_SCOPE'),
|
||||
@@ -226,7 +227,7 @@ export default class LDAP {
|
||||
|
||||
if (!this.options.BaseDN) throw new Error('BaseDN is not provided');
|
||||
|
||||
const userDn = `uid=${username},${this.options.BaseDN}`;
|
||||
const userDn = `${this.options.User_Authentication_Field}=${username},${this.options.BaseDN}`;
|
||||
|
||||
this.bindSync(userDn, password);
|
||||
this.domainBinded = true;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import _ from 'underscore';
|
||||
import SyncedCron from 'meteor/percolate:synced-cron';
|
||||
import LDAP from './ldap';
|
||||
import { log_debug, log_info, log_warn, log_error } from './logger';
|
||||
|
||||
@@ -418,30 +419,35 @@ function sync() {
|
||||
const jobName = 'LDAP_Sync';
|
||||
|
||||
const addCronJob = _.debounce(Meteor.bindEnvironment(function addCronJobDebounced() {
|
||||
let sc=SyncedCron.SyncedCron; //Why ?? something must be wrong in the import
|
||||
if (LDAP.settings_get('LDAP_BACKGROUND_SYNC') !== true) {
|
||||
log_info('Disabling LDAP Background Sync');
|
||||
if (SyncedCron.nextScheduledAtDate(jobName)) {
|
||||
SyncedCron.remove(jobName);
|
||||
if (sc.nextScheduledAtDate(jobName)) {
|
||||
sc.remove(jobName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (LDAP.settings_get('LDAP_BACKGROUND_SYNC_INTERVAL')) {
|
||||
log_info('Enabling LDAP Background Sync');
|
||||
SyncedCron.add({
|
||||
name: jobName,
|
||||
schedule: (parser) => parser.text(LDAP.settings_get('LDAP_BACKGROUND_SYNC_INTERVAL')),
|
||||
job() {
|
||||
sync();
|
||||
},
|
||||
});
|
||||
SyncedCron.start();
|
||||
}
|
||||
log_info('Enabling LDAP Background Sync');
|
||||
sc.add({
|
||||
name: jobName,
|
||||
schedule: function(parser) {
|
||||
if (LDAP.settings_get('LDAP_BACKGROUND_SYNC_INTERVAL')) {
|
||||
return parser.text(LDAP.settings_get('LDAP_BACKGROUND_SYNC_INTERVAL'));
|
||||
}
|
||||
else {
|
||||
return parser.recur().on(0).minute();
|
||||
}},
|
||||
job: function() {
|
||||
sync();
|
||||
},
|
||||
});
|
||||
sc.start();
|
||||
|
||||
}), 500);
|
||||
|
||||
Meteor.startup(() => {
|
||||
Meteor.defer(() => {
|
||||
LDAP.settings_get('LDAP_BACKGROUND_SYNC', addCronJob);
|
||||
LDAP.settings_get('LDAP_BACKGROUND_SYNC_INTERVAL', addCronJob);
|
||||
if(LDAP.settings_get('LDAP_BACKGROUND_SYNC')){addCronJob();}
|
||||
});
|
||||
});
|
||||
+15766
File diff suppressed because it is too large.
Load diff
Loaded 100 of 123 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user