Compare commits

...
267 Commits
Author SHA1 Message Date
Lauri Ojansivu 8c23d12487 v2.94 2019-06-29 10:11:14 -04:00
Lauri Ojansivu 31e801cc39 - [LDAP: Check if email attribute is an array, that has many email addresses](https://github.com/wekan/wekan/pull/2519).
Thanks to tdemaret and xet7 !
2019-06-29 10:02:23 -04:00
Lauri Ojansivu a2587f94da Update translations. 2019-06-29 09:04:01 -04:00
Lauri Ojansivu 40b782788a Merge branch 'justinr1234-linting' into meteor-1.8 2019-06-29 08:38:52 -04:00
Lauri Ojansivu 45163e2d2d Fix rebuild-wekan.sh 2019-06-29 08:37:14 -04:00
Lauri Ojansivu b711cbae94 Fixes to rebuild-wekan.sh 2019-06-29 08:21:55 -04:00
Lauri Ojansivu b84dc20ded Merge branch 'linting' of https://github.com/justinr1234/wekan into justinr1234-linting 2019-06-29 07:47:57 -04:00
Lauri Ojansivu 100288b3e1 Update translations. 2019-06-29 07:46:25 -04:00
Justin Reynolds 3eb4d2c341 Prettier & eslint project style update 2019-06-28 12:56:51 -05:00
Lauri Ojansivu a0a482aa8e Merge branch 'justinr1234-created-modified' into meteor-1.8 2019-06-27 15:27:14 -04:00
Justin Reynolds 3d63b6006b Auto linting on commit 2019-06-27 09:19:29 -05:00
Justin Reynolds 7d86af2b00 Add prettier 2019-06-27 09:13:22 -05:00
Justin Reynolds c60e80d25b Add createdAt and modifiedAt to all collections 2019-06-27 09:13:20 -05:00
Lauri Ojansivu fb728baf0c Merge branch 'edge' into meteor-1.8 2019-06-27 05:04:23 +03:00
Lauri Ojansivu 436db99a5b v2.92 2019-06-27 05:02:50 +03:00
Lauri Ojansivu ac9b2f7c8f Update translations. 2019-06-27 04:28:16 +03:00
Lauri Ojansivu f0f0634e83 Update translation. 2019-06-27 04:24:38 +03:00
Lauri Ojansivu d6d4629b5a Update changelog. 2019-06-27 04:14:43 +03:00
Lauri Ojansivu 5283ba9ebb - Fix Outgoing Webhook messages for Checlists, Checklist Items, Card comments, Add/Remove CustomField to board.
Not yet fixed is Outgoing Webhook message about setting CustomField value.

Thanks to xet7 !

Related #1969
2019-06-27 04:06:21 +03:00
Lauri Ojansivu 0c352ab143 Merge branch 'edge' into meteor-1.8 2019-06-27 00:54:06 +03:00
Lauri Ojansivu 7c89336ea9 v2.91 2019-06-27 00:52:20 +03:00
Lauri Ojansivu bca1a2f95b Update changelog. 2019-06-26 23:14:16 +03:00
Lauri Ojansivu 6a2f120d00 Fix Attachment Outgoing Webhook missing list and swimlane name.
Thanks to xet7 !

Related #1969,
Closes #2170
2019-06-26 23:06:50 +03:00
Lauri Ojansivu e8ccfb6743 Update translations. 2019-06-26 22:14:51 +03:00
Lauri Ojansivu 69333ea64f Merge branch 'edge' into meteor-1.8 2019-06-21 21:30:15 +03:00
Lauri Ojansivu 8f5e2c4af3 v2.90 2019-06-21 21:28:30 +03:00
Lauri Ojansivu e5c0d0ea18 Revert v2.89 setting every Sandstorm Wekan user as admin.
Thanks to xet7.

Related #2405
2019-06-21 21:23:42 +03:00
Lauri Ojansivu a35712c708 Merge branch 'edge' into meteor-1.8 2019-06-21 21:00:06 +03:00
Lauri Ojansivu 47e64c269c v2.89 2019-06-21 20:58:30 +03:00
Lauri Ojansivu cd69b03ac1 Update translations. 2019-06-21 20:55:36 +03:00
Lauri Ojansivu 5afaa5bce6 Update changelog. 2019-06-21 20:53:58 +03:00
Lauri Ojansivu 60d62a6ae3 - Sandstorm Wekan: Set everyone as Admin. Please test does this help with
[Problem with the user management: can't add users or give wekan admin rights](https://github.com/wekan/wekan/issues/2405).

Thanks to xet7 !

Related #2405
2019-06-21 20:46:05 +03:00
Lauri Ojansivu 4f46adc389 - If board does not exist, redirect to All Boards page, at all Wekan platforms.
So now at Sandstorm when loading Wekan grain, if first Sandstorm board is found,
  it is opened. If first Sandstorm board is not found (it's deleted or archived),
  then redirect automatically to All Boards page.

Closes #3132
2019-06-21 20:09:18 +03:00
Lauri Ojansivu f2bc6f773b Merge branch 'edge' into meteor-1.8 2019-06-21 18:12:21 +03:00
Lauri Ojansivu d2dfcf36d9 v2.88 2019-06-21 18:11:19 +03:00
Lauri Ojansivu 353768b4b5 Update translations. 2019-06-21 18:07:45 +03:00
Lauri Ojansivu 11ad8c7b30 Merge branch 'edge' into meteor-1.8 2019-06-21 12:51:21 +03:00
Lauri Ojansivu 4f3e83b363 v2.87 2019-06-21 12:50:13 +03:00
Lauri Ojansivu 263ec64453 Update changelog. 2019-06-21 12:46:19 +03:00
Lauri Ojansivu 140dc6db25 Update translations. 2019-06-21 12:22:29 +03:00
Lauri Ojansivu 47a7097044 Merge pull request #2508 from road42/bug/card_move_to_top_bottom_fix
Inferface: Can move cardToTop/Bottom. Fixes #2289
2019-06-21 11:54:01 +03:00
Lauri Ojansivu b8e774107a Merge pull request #2507 from road42/bug/english_language_fix_card_trigger
English language update. Fixes #2456
2019-06-21 11:53:44 +03:00
Lauri Ojansivu 3d3c78260b Merge pull request #2506 from road42/feature/rule_card_action_setdate
Adds rule feature: cardAction - SetDate #2504
2019-06-21 11:53:20 +03:00
Christoph Jahn e8f4c4d8b8 Inferface: Can move cardToTop/Bottom. Fixes #2289 2019-06-21 10:11:40 +02:00
Christoph Jahn 2156b28445 English language fixed #2456 2019-06-21 09:11:42 +02:00
Christoph Jahn a9fc74a9b4 Adds rule feature: cardAction - SetDate #2504 2019-06-21 07:24:21 +02:00
Lauri Ojansivu e0a1651784 Merge branch 'edge' into meteor-1.8 2019-06-19 22:58:01 +03:00
Lauri Ojansivu 02de9164f0 v2.86 2019-06-19 22:56:46 +03:00
Lauri Ojansivu 140a2d7915 Update changelog. 2019-06-19 22:50:49 +03:00
Lauri Ojansivu 17c4c96c29 - [Fix Wekan unable to Select Text from Description edit box](https://github.com/wekan/wekan/issues/2451)
by removing feature of card description submit on click outside. This is because when selecting text
  and dragging up did trigger submit of description, so description was closed and selecting text failed.
  This did affect all Chromium-based browsers: Chrome, Chromium, Chromium Edge.

Thanks to xet7 !

Closes #2451
2019-06-19 22:39:29 +03:00
Lauri Ojansivu 2e1162ed73 Merge branch 'edge' into meteor-1.8 2019-06-19 11:43:23 +03:00
Lauri Ojansivu 56e5585730 v2.85 2019-06-19 11:41:59 +03:00
Lauri Ojansivu 51a0dd8861 [Fixed bug: rule doesn't move card to top/bottom](https://github.com/wekan/wekan/pull/2502).
Thanks to road42 !

Closes #2501
2019-06-19 11:36:13 +03:00
Lauri Ojansivu 8bfd94474a Merge pull request #2502 from road42/bug/rule_action_card_move_fix
Fixed bug (rule doesn't move card to top/bottom) #2501
2019-06-19 11:33:34 +03:00
Christoph Jahn 6789e8564a Fixed bug #2501
card.move needs boardId as first parameter
2019-06-19 06:57:58 +02:00
Lauri Ojansivu 8b6856fc89 Merge branch 'edge' into meteor-1.8 2019-06-18 23:45:33 +03:00
Lauri Ojansivu b48c6a5b9c v2.84 2019-06-18 23:43:49 +03:00
Lauri Ojansivu b39b9f5463 Update changelog. 2019-06-18 21:28:32 +03:00
Lauri Ojansivu e72f186a36 Merge branch 'road42-devel' into devel 2019-06-18 21:25:33 +03:00
Christoph Jahn c3d495e7c6 Show buttons for isBoardAdmin 2019-06-17 21:05:21 +02:00
Lauri Ojansivu 70e5b71bdd Merge branch 'meteor-1.8' of github.com:wekan/wekan into meteor-1.8 2019-06-17 21:58:58 +03:00
Lauri Ojansivu a84c8f518b Merge branch 'edge' into meteor-1.8 2019-06-17 21:58:38 +03:00
Lauri Ojansivu 98c6ea467a v2.83 2019-06-17 21:55:16 +03:00
Lauri Ojansivu 6e73abde50 Update changelog. 2019-06-17 21:51:59 +03:00
Lauri Ojansivu 7ff6f24a90 Fix Bug: Unable to click board submenu on mobile.
Thanks to xet7 !

Closes #2261
2019-06-17 21:47:02 +03:00
Lauri Ojansivu 6790c22794 Update dependencies. 2019-06-15 12:58:14 -04:00
Lauri Ojansivu 60a9b4b934 Merge branch 'edge' into meteor-1.8 2019-06-14 16:31:48 +03:00
Lauri Ojansivu 8368461b57 v2.82 2019-06-14 16:30:34 +03:00
Lauri Ojansivu 7dc8a2d659 [Fix OIDC Docker login. Empty string results to empty array at wekan/server/authentication.js](https://github.com/wekan/wekan/commit/bddbaa7bc2f3cfe8553a2265e168231ab51876f3).
Thanks to xet7 !

Closes #2206
2019-06-14 16:27:40 +03:00
Lauri Ojansivu bddbaa7bc2 - Fix OIDC Docker login. Empty string results to empty array at wekan/server/authentication.js
Thanks to xet7 !

Closes #2206
2019-06-14 16:23:18 +03:00
Lauri Ojansivu 434fa3226a Merge branch 'edge' into meteor-1.8 2019-06-13 19:31:02 +03:00
Lauri Ojansivu f9abfe5244 v2.81 2019-06-13 19:29:41 +03:00
Lauri Ojansivu 97d57b05ad Update changelog. 2019-06-13 19:28:08 +03:00
Lauri Ojansivu 4334fbbb9d - Change OAuth2 whitelist default to empty string at snap, so it would be used as array on wekan/server/authentication.js.
Thanks to xet7 !
2019-06-13 19:24:50 +03:00
Lauri Ojansivu e689feddcb Merge branch 'edge' into meteor-1.8 2019-06-13 19:01:30 +03:00
Lauri Ojansivu 595c657b57 Add missing text. 2019-06-13 19:00:18 +03:00
Lauri Ojansivu 375fda0eff Merge branch 'edge' into meteor-1.8 2019-06-13 18:23:24 +03:00
Lauri Ojansivu ed04769947 v2.80 2019-06-13 18:21:51 +03:00
Lauri Ojansivu 44dbd462b1 Default whitelist array, not string.
Thanks to xet7 !
2019-06-13 18:18:03 +03:00
Lauri Ojansivu 38a238df80 Merge branch 'edge' into meteor-1.8 2019-06-12 06:37:34 +03:00
Lauri Ojansivu f154c03385 Merge branch 'edge' into meteor-1.8 2019-06-11 17:48:08 +03:00
Lauri Ojansivu 526e10865f Merge branch 'edge' into meteor-1.8 2019-05-22 21:48:52 +03:00
Lauri Ojansivu e38988126a Merge branch 'edge' into meteor-1.8 2019-05-14 21:34:30 +03:00
Lauri Ojansivu 4903f3a814 Merge branch 'edge' into meteor-1.8 2019-05-14 16:56:35 +03:00
Lauri Ojansivu 663384e62f Merge branch 'edge' into meteor-1.8 2019-05-13 10:51:44 +03:00
Lauri Ojansivu e246099794 Merge branch 'edge' into meteor-1.8 2019-05-12 20:52:49 +03:00
Lauri Ojansivu 0b3343674b Merge branch 'edge' into meteor-1.8 2019-05-11 23:53:39 +03:00
Lauri Ojansivu 1d33701af0 Merge branch 'edge' into meteor-1.8 2019-05-11 00:09:08 +03:00
Lauri Ojansivu df69ade422 Merge branch 'edge' into meteor-1.8 2019-05-10 23:20:17 +03:00
Lauri Ojansivu ac0f13ad18 Merge branch 'edge' into meteor-1.8 2019-05-10 21:03:03 +03:00
Lauri Ojansivu 34b1654077 Merge branch 'edge' into meteor-1.8 2019-05-09 16:37:18 +03:00
Lauri Ojansivu 5dcd1b630e Merge branch 'meteor-1.8' of github.com:wekan/wekan into meteor-1.8 2019-05-09 16:34:33 +03:00
Lauri Ojansivu 9fe4aedec1 Update packages. 2019-05-09 08:48:02 -04:00
Lauri Ojansivu b6d7c71cc8 Merge branch 'edge' into meteor-1.8 2019-05-09 14:27:34 +03:00
Lauri Ojansivu 778cd22e72 Merge pull request #2396 from justinr1234/wekan-profile-checks
Fix missing profile checks
2019-05-09 14:25:06 +03:00
Justin Reynolds daf314b037 Fix missing profile checks 2019-05-08 16:54:15 -05:00
Lauri Ojansivu 97ff2bd2fa Merge branch 'edge' into meteor-1.8 2019-04-24 16:13:29 +03:00
Lauri Ojansivu 4282906833 Merge branch 'edge' into meteor-1.8 2019-04-24 14:41:37 +03:00
Lauri Ojansivu b1cfd8229a Merge branch 'meteor-1.8' of github.com:wekan/wekan into meteor-1.8 2019-04-23 19:52:07 +03:00
Lauri Ojansivu 202f4235d7 Merge branch 'edge' into meteor-1.8 2019-04-23 19:51:53 +03:00
Lauri Ojansivu 1fff4e0eed Upgrade pip also. 2019-04-23 15:10:05 +03:00
Lauri Ojansivu 9d2227bffb Merge branch 'edge' into meteor-1.8 2019-04-23 14:42:58 +03:00
Lauri Ojansivu d9e361cf1b Merge branch 'edge' into meteor-1.8 2019-04-23 14:09:39 +03:00
Lauri Ojansivu 070de69ebe Fix build scripts. 2019-04-20 15:11:20 -04:00
Lauri Ojansivu a72d730373 Remove extra check. 2019-04-20 14:20:37 -04:00
Lauri Ojansivu a1efe50659 Fix repo url. 2019-04-20 14:17:55 -04:00
Lauri Ojansivu 30e3b448fd Update docker-compose.yml to use meteor-1.8 branch with MongoDB 4.0.9. 2019-04-20 13:56:32 -04:00
Lauri Ojansivu 29d895742c Fix snap npm permissions. 2019-04-20 13:45:23 -04:00
Lauri Ojansivu c23047a59f Update to MongoDB 4.0.9 on Snap. 2019-04-20 13:34:55 -04:00
Lauri Ojansivu 4aa26e292e Try to fix snap. 2019-04-20 13:31:36 -04:00
Lauri Ojansivu 0a20795ea4 Fix python3 pip and setuptools error. 2019-04-20 13:31:03 -04:00
Lauri Ojansivu c3a27f6d17 Fixes to get Dockerfile built on ubuntu:disco. 2019-04-20 13:13:00 -04:00
Lauri Ojansivu 4c9a90a461 Update version. 2019-04-20 12:09:42 -04:00
Lauri Ojansivu eb58d335c0 Merge branch 'edge' into meteor-1.8 2019-04-20 17:12:41 +03:00
Lauri Ojansivu 2f2c4723a6 Merge pull request #2347 from justinr1234/meteor18
Additional Meteor 1.8.1 changes
2019-04-20 16:52:33 +03:00
Lauri Ojansivu 02819ca169 Merge branch 'edge' into meteor-1.8 2019-04-20 16:51:57 +03:00
Justin Reynolds a1ae4d7ef0 Additional Meteor 1.8.1 changes 2019-04-19 10:16:37 -05:00
Lauri Ojansivu 53d42a17ff Update compatible mongodb version to 4.0.6 2019-04-12 19:26:24 +00:00
Lauri Ojansivu cc21da6266 Fix quotes. 2019-04-12 18:55:24 +00:00
Lauri Ojansivu ab05af79ec Update packages, and remove broken one about mousewheel. 2019-04-12 18:40:50 +00:00
Lauri Ojansivu c46c5e9c8f Fix rebuild script. 2019-04-12 18:03:07 +00:00
Lauri Ojansivu 9c50b81c70 Update packages. 2019-04-12 18:01:02 +00:00
Lauri Ojansivu 144771bebf Merge branch 'meteor-1.8' of github.com:wekan/wekan into meteor-1.8 2019-04-12 17:02:12 +00:00
Lauri Ojansivu 422aabd562 Update to Meteor 1.8.1 2019-04-12 17:01:44 +00:00
Lauri Ojansivu 076dda8bd3 Merge branch 'edge' into meteor-1.8 2019-04-08 10:33:24 +03:00
Lauri Ojansivu f2f13450b5 Merge branch 'edge' into meteor-1.8 2019-04-06 14:17:09 +03:00
Lauri Ojansivu 4356aaff23 Merge branch 'edge' into meteor-1.8 2019-04-06 13:56:09 +03:00
Lauri Ojansivu 0b9afcb443 Merge branch 'edge' into meteor-1.8 2019-04-02 15:28:30 +03:00
Lauri Ojansivu 5e7e9e8c0d Change to MongoDB 4.0.7 legacy versions without curl to get it working. 2019-03-27 19:02:57 +02:00
Lauri Ojansivu 5841a3abea Merge branch 'edge' into meteor-1.8 2019-03-27 17:53:06 +02:00
Lauri Ojansivu d753fc06c9 Use mongodb for Ubuntu 16.04 2019-03-26 00:25:40 +02:00
Lauri Ojansivu a85d652db4 Try to fix meteor-1.8 snap build. 2019-03-25 20:09:31 +02:00
Lauri Ojansivu a9e6bf62bd Merge branch 'edge' into meteor-1.8 2019-03-25 19:12:48 +02:00
Lauri Ojansivu 0674ce19fe Revert to original snapcraft.yaml. 2019-03-25 17:18:01 +02:00
Lauri Ojansivu 3fc251c1f6 Merge branch 'meteor-1.8' of github.com:wekan/wekan into meteor-1.8 2019-03-25 17:15:36 +02:00
Lauri Ojansivu 67c3f663a1 Merge branch 'edge' into meteor-1.8 2019-03-25 17:15:18 +02:00
Lauri Ojansivu 2050796a33 Try to build meteor-1.8 snap. 2019-03-25 08:59:52 +00:00
Lauri Ojansivu 7c4c467e46 Update packages. 2019-03-25 08:25:36 +00:00
Lauri Ojansivu 4f4f3e4593 Merge branch 'edge' into meteor-1.8 2019-03-23 21:35:55 +02:00
Lauri Ojansivu 5160d59d79 Merge branch 'edge' into meteor-1.8 2019-03-23 21:14:05 +02:00
Lauri Ojansivu ab4774a59a Merge branch 'edge' into meteor-1.8 2019-03-22 13:10:31 +02:00
Lauri Ojansivu b0d1ccc311 Merge branch 'edge' into meteor-1.8 2019-03-21 02:42:14 +02:00
Lauri Ojansivu 8c2ebde3d5 Merge branch 'edge' into meteor-1.8 2019-03-21 01:23:20 +02:00
Lauri Ojansivu 508e8c87be Merge branch 'edge' into meteor-1.8 2019-03-21 01:12:57 +02:00
Lauri Ojansivu 365e8455e6 Merge branch 'edge' into meteor-1.8 2019-03-21 00:40:46 +02:00
Lauri Ojansivu 393684fb19 Merge branch 'edge' into meteor-1.8 2019-03-15 11:09:21 +02:00
Lauri Ojansivu 909a23e529 Merge branch 'edge' into meteor-1.8 2019-03-14 00:41:55 +02:00
Lauri Ojansivu b68a2e2b41 Merge branch 'edge' into meteor-1.8 2019-03-13 15:56:54 +02:00
Lauri Ojansivu 33f09f0887 Merge branch 'edge' into meteor-1.8 2019-03-11 23:40:24 +02:00
Lauri Ojansivu aee05a549f v2.44
Merge branch 'edge' into meteor-1.8
2019-03-11 20:26:23 +02:00
Lauri Ojansivu 0155c7d8ce Merge branch 'edge' into meteor-1.8 2019-03-08 19:17:33 +02:00
Lauri Ojansivu 64fca5893e Merge branch 'edge' into meteor-1.8 2019-03-07 01:54:00 +02:00
Lauri Ojansivu 221831e4e5 Merge branch 'edge' into meteor-1.8 2019-03-07 00:05:46 +02:00
Lauri Ojansivu cb755af2ee Merge branch 'edge' into meteor-1.8 2019-03-06 20:58:01 +02:00
Lauri Ojansivu f71f3126db Merge branch 'edge' into meteor-1.8 2019-03-06 18:23:37 +02:00
Lauri Ojansivu 42a2767211 Merge branch 'edge' into meteor-1.8 2019-03-06 17:32:20 +02:00
Lauri Ojansivu e410205886 Merge branch 'edge' into meteor-1.8 2019-03-06 03:15:51 +02:00
Lauri Ojansivu 07433b8005 Merge branch 'edge' into meteor-1.8 2019-03-04 19:57:14 +00:00
Lauri Ojansivu 58575706fe Update stylus. 2019-03-04 19:56:22 +00:00
Lauri Ojansivu ebba71077e Fix escaping special character as advised at
https://github.com/jquery/jquery/issues/2885

Thanks to xet7 !
2019-03-04 10:31:05 +00:00
Lauri Ojansivu 6c0df108c7 Merge branch 'edge' into meteor-1.8 2019-03-04 12:10:11 +02:00
Lauri Ojansivu 5f3ffcb0eb Merge branch 'edge' into meteor-1.8 2019-03-04 10:17:14 +02:00
Lauri Ojansivu 265d57b9f4 Update packages.
Thanks to xet7 !
2019-03-04 10:02:54 +02:00
Lauri Ojansivu 42e85f693c Upgrade to Meteor 1.8.0.2.
Thanks to xet7 !
2019-03-04 09:56:12 +02:00
Lauri Ojansivu 30dacb0369 Change Dockerfile to use ubuntu:cosmic base.
Thanks to xet7 !
2019-03-04 09:48:59 +02:00
Lauri Ojansivu 304d5e6256 Merge branch 'edge' into meteor-1.8 2019-03-03 22:40:24 +02:00
Lauri Ojansivu 597de31116 Merge branch 'edge' into meteor-1.8 2019-03-02 17:33:01 +02:00
Lauri Ojansivu 425b3d98b3 Merge branch 'edge' into meteor-1.8 2019-03-01 15:44:16 +02:00
Lauri Ojansivu c2fb8b5be8 Merge branch 'edge' into meteor-1.8 2019-03-01 07:11:59 +02:00
Lauri Ojansivu 1ba299585c Merge branch 'edge' into meteor-1.8 2019-02-28 23:32:58 +02:00
Lauri Ojansivu 174ad1a987 Merge branch 'edge' into meteor-1.8 2019-02-28 23:03:16 +02:00
Lauri Ojansivu 199246ea6c Merge branch 'edge' into meteor-1.8 2019-02-28 12:42:49 +02:00
Lauri Ojansivu eeb8d4b3de Merge branch 'edge' into meteor-1.8 2019-02-28 00:54:29 +02:00
Lauri Ojansivu 82a728df71 Merge branch 'edge' into meteor-1.8 2019-02-27 21:03:54 +02:00
Lauri Ojansivu 3f067c793c Merge branch 'devel' into meteor-1.8 2019-02-27 17:29:39 +02:00
Lauri Ojansivu 2489cc5b91 Merge branch 'devel' into meteor-1.8 2019-02-27 16:27:15 +02:00
Lauri Ojansivu 1c832a24b7 Merge branch 'devel' into meteor-1.8 2019-02-27 06:21:23 +02:00
Lauri Ojansivu e40198cd26 Merge branch 'devel' into meteor-1.8 2019-02-25 20:04:47 +02:00
Lauri Ojansivu c81556b64c Merge branch 'edge' into meteor-1.8 2019-02-23 19:55:50 +02:00
Lauri Ojansivu 60546d2ce3 Merge branch 'edge' into meteor-1.8 2019-02-23 19:24:51 +02:00
Lauri Ojansivu fa0b4d7edd Merge branch 'edge' into meteor-1.8 2019-02-17 18:16:11 +02:00
Lauri Ojansivu d5593e059b Merge branch 'edge' into meteor-1.8 2019-02-13 03:17:04 +02:00
Lauri Ojansivu 93ae4e504e Merge branch 'edge' into meteor-1.8 2019-02-12 03:26:56 +02:00
Lauri Ojansivu fcac5d1033 Merge branch 'edge' into meteor-1.8 2019-02-11 16:46:12 +02:00
Lauri Ojansivu f69392566a Merge branch 'edge' into meteor-1.8 2019-02-09 00:06:05 +02:00
Lauri Ojansivu 8e3689a11d Merge branch 'edge' into meteor-1.8 2019-02-08 20:58:04 +02:00
Lauri Ojansivu 5804a204fe Merge branch 'edge' into meteor-1.8 2019-02-04 21:48:58 +02:00
Lauri Ojansivu 09682111d6 Merge branch 'edge' into meteor-1.8 2019-02-03 15:47:05 +02:00
Lauri Ojansivu 3a845d13f8 Merge branch 'edge' into meteor-1.8 2019-02-03 05:19:58 +02:00
Lauri Ojansivu 2cb4df9e0b Merge branch 'edge' into meteor-1.8 2019-02-03 03:09:02 +02:00
Lauri Ojansivu daa602ed9e Merge branch 'edge' into meteor-1.8 2019-02-03 02:33:03 +02:00
Lauri Ojansivu eabf24d750 Merge branch 'edge' into meteor-1.8 2019-02-03 02:26:23 +02:00
Lauri Ojansivu e2475ad73f Merge branch 'edge' into meteor-1.8 2019-02-02 21:56:40 +02:00
Lauri Ojansivu 4f79e84399 Merge branch 'devel' into meteor-1.8 2019-02-02 21:03:12 +02:00
Lauri Ojansivu e4c0638f72 Merge branch 'edge' into meteor-1.8 2019-02-01 17:16:22 +02:00
Lauri Ojansivu e774f71205 Merge branch 'edge' into meteor-1.8 2019-01-31 19:33:39 +02:00
Lauri Ojansivu b2986ca289 Merge branch 'edge' into meteor-1.8 2019-01-31 14:28:53 +02:00
Lauri Ojansivu 271853e155 Merge branch 'edge' into meteor-1.8 2019-01-30 18:53:02 +02:00
Lauri Ojansivu a2a3d316d5 Merge branch 'edge' into meteor-1.8 2019-01-30 18:19:07 +02:00
Lauri Ojansivu 33b75f2f23 Merge branch 'edge' into meteor-1.8 2019-01-30 16:07:41 +02:00
Lauri Ojansivu 929ca9cbd9 Merge branch 'edge' into meteor-1.8 2019-01-30 02:20:35 +02:00
Lauri Ojansivu ea3bcf4320 Merge branch 'edge' into meteor-1.8 2019-01-29 18:57:57 +02:00
Lauri Ojansivu 0b018bfad5 Merge branch 'edge' into meteor-1.8 2019-01-28 18:31:26 +02:00
Lauri Ojansivu c360afb341 Merge branch 'edge' into meteor-1.8 2019-01-28 17:27:50 +02:00
Lauri Ojansivu 2dba189830 Merge branch 'edge' into meteor-1.8 2019-01-28 02:59:32 +02:00
Lauri Ojansivu d40d5652ba Merge branch 'edge' into meteor-1.8 2019-01-27 19:13:01 +02:00
Lauri Ojansivu d40ad94384 Merge branch 'edge' into meteor-1.8 2019-01-27 18:29:02 +02:00
Lauri Ojansivu 8e2f44bbc0 Merge branch 'edge' into meteor-1.8 2019-01-26 20:22:17 +02:00
Lauri Ojansivu 87df11434b Merge branch 'edge' into meteor-1.8 2019-01-25 23:07:43 +02:00
Lauri Ojansivu 95c178cee3 Merge branch 'edge' into meteor-1.8 2019-01-25 22:20:00 +02:00
Lauri Ojansivu 46a468b06d Merge branch 'edge' into meteor-1.8 2019-01-22 17:33:27 +02:00
Lauri Ojansivu 8d4eef6649 Merge branch 'edge' into meteor-1.8 2019-01-13 20:14:23 +02:00
Lauri Ojansivu 9421c0ba05 Merge branch 'edge' into meteor-1.8 2019-01-06 13:30:19 +02:00
Lauri Ojansivu 1c827f9830 Merge branch 'edge' into meteor-1.8 2019-01-04 20:08:55 +02:00
Lauri Ojansivu 4114d08961 Merge branch 'edge' into meteor-1.8 2019-01-04 12:18:24 +02:00
Lauri Ojansivu 98917523fc Merge branch 'edge' into meteor-1.8 2019-01-01 14:10:10 +02:00
Lauri Ojansivu e9a3601d2e - Upgrade to Meteor 1.8.0.1.
Thanks to xet7 !
2018-12-29 19:47:59 +02:00
Lauri Ojansivu 3c53b3de15 - Change to meteor v1.8, finally got it working, at least it started.
Note that if MongoDB does not start, you could try fixing meteor's local database with
  command from https://github.com/meteor/meteor/issues/9591#issuecomment-367351465 that for
  Linux is `cd ~ && .meteor/packages/meteor-tool/1.8.0/mt-os.linux.x86_64/dev_bundle/mongodb/bin/mongod --dbpath ./repos/wekan/.meteor/local/db --repair`
  but that did not work for me, so I needed to move away (or delete) repos/wekan/.meteor/local/db file
  so that it was created again and with command `mongo` database could start correctly.

Thanks to xet7 !
2018-12-29 19:29:14 +02:00
Lauri Ojansivu 8becd9aad3 - Update some packages. Error about tap:i18n still exists.
Thanks to xet7 !
2018-12-29 16:41:20 +02:00
Lauri Ojansivu 5eadc0c850 Merge branch 'edge' into meteor-1.8 2018-12-28 17:33:28 +02:00
Lauri Ojansivu 89d0da5eee - Update dependencies. But this Meteor 1.8.x version still does not work
because of tap:18n bug.

Thanks to xet7 !
2018-12-28 17:20:34 +02:00
Lauri Ojansivu 03fbc1cd70 Merge branch 'edge' into meteor-1.8 2018-12-27 00:36:41 +02:00
Lauri Ojansivu 738e07c424 Merge branch 'edge' into meteor-1.8 2018-12-26 23:58:42 +02:00
Lauri Ojansivu 4fb81bd686 Merge branch 'edge' into meteor-1.8 2018-12-26 22:50:25 +02:00
Lauri Ojansivu aff8b562d6 Merge branch 'edge' into meteor-1.8 2018-12-24 23:56:54 +02:00
Lauri Ojansivu 236c99b39f Merge branch 'edge' into meteor-1.8 2018-12-24 18:27:49 +02:00
Lauri Ojansivu 5488b68b9b - Update meteor.
Thanks to xet7 !
2018-12-24 14:03:31 +02:00
Lauri Ojansivu 6d18fb689f - Update dependency package versions.
Thanks to xet7 !
2018-12-24 13:56:29 +02:00
Lauri Ojansivu 9d7e9e9869 Merge branch 'edge' into meteor-1.8 2018-12-22 21:42:11 +02:00
Lauri Ojansivu 6d15fd29ee Merge branch 'edge' into meteor-1.8 2018-12-22 19:05:33 +02:00
Lauri Ojansivu d78e067246 Merge branch 'edge' into meteor-1.8 2018-12-22 18:58:35 +02:00
Lauri Ojansivu 5b227b2b4f Merge branch 'edge' into meteor-1.8 2018-12-21 22:24:21 +02:00
Lauri Ojansivu 16fe2be04d Merge branch 'edge' into meteor-1.8 2018-12-19 19:59:11 +02:00
Lauri Ojansivu 61c0292089 Merge branch 'edge' into meteor-1.8 2018-12-18 20:23:43 +02:00
Lauri Ojansivu c8173fd9f9 Merge branch 'edge' into meteor-1.8 2018-12-16 19:11:05 +02:00
Lauri Ojansivu 72f8baf6b3 Merge branch 'edge' into meteor-1.8 2018-12-16 12:01:42 +02:00
Lauri Ojansivu e135af8c37 Merge branch 'edge' into meteor-1.8 2018-12-16 00:43:25 +02:00
Lauri Ojansivu 61eb0e7acd Merge branch 'edge' into meteor-1.8 2018-12-15 22:45:36 +02:00
Lauri Ojansivu 0b841f2e05 Merge branch 'edge' into meteor-1.8 2018-12-15 22:03:10 +02:00
Lauri Ojansivu 9662267628 Merge branch 'edge' into meteor-1.8 2018-12-15 20:53:47 +02:00
Lauri Ojansivu 34f2e4466e Merge branch 'edge' into meteor-1.8 2018-12-14 23:34:06 +02:00
Lauri Ojansivu 73f288cd9b Merge branch 'edge' into meteor-1.8 2018-12-13 20:15:16 +02:00
Lauri Ojansivu 622f1360bb Merge branch 'edge' into meteor-1.8 2018-12-13 14:41:42 +02:00
Lauri Ojansivu 4ecdf7558f Merge branch 'edge' into meteor-1.8 2018-12-09 01:45:24 +02:00
Lauri Ojansivu 25fac166cf Merge branch 'edge' into meteor-1.8 2018-12-09 00:51:50 +02:00
Lauri Ojansivu 66d1546081 Merge branch 'edge' into meteor-1.8 2018-12-07 05:23:00 +02:00
Lauri Ojansivu 181b564bf3 Upgrade to meteor 1.8.1-beta.8
Thanks to xet7 !
2018-12-07 04:14:34 +02:00
Lauri Ojansivu 872e503ff8 Merge branch 'edge' into meteor-1.8 2018-12-06 02:01:36 +02:00
Lauri Ojansivu 38012903b8 Merge branch 'edge' into meteor-1.8 2018-12-05 08:59:59 +02:00
Lauri Ojansivu 6ab699d650 Merge branch 'edge' into meteor-1.8 2018-12-04 22:34:22 +02:00
Lauri Ojansivu af6513ccc7 Merge branch 'edge' into meteor-1.8 2018-12-03 18:26:01 +02:00
Lauri Ojansivu 30fe263bfe Merge branch 'edge' into meteor-1.8 2018-12-03 16:32:05 +02:00
Lauri Ojansivu 51cf57025d Merge branch 'meteor-1.8' of github.com:wekan/wekan into meteor-1.8 2018-11-23 16:39:43 +02:00
Lauri Ojansivu 28884cb409 Merge branch 'devel' into meteor-1.8 2018-11-23 16:39:28 +02:00
Lauri Ojansivu 6e29152b76 Merge branch 'edge' into meteor-1.8 2018-11-20 22:52:24 +02:00
Lauri Ojansivu 0defff70af Merge branch 'edge' into meteor-1.8 2018-11-20 12:26:02 +02:00
Lauri Ojansivu d93efd9e9b Merge branch 'edge' into meteor-1.8 2018-11-20 02:46:35 +02:00
Lauri Ojansivu eab46523ee Merge branch 'edge' into meteor-1.8 2018-11-19 23:29:49 +02:00
Lauri Ojansivu c4473f3515 Merge branch 'edge' into meteor-1.8 2018-11-19 23:12:46 +02:00
Lauri Ojansivu 8b3f8ac501 Merge branch 'edge' into meteor-1.8 2018-11-19 15:09:10 +02:00
Lauri Ojansivu fb2e8b4a31 Merge branch 'devel' into meteor-1.8 2018-11-17 17:44:11 +02:00
Lauri Ojansivu 871e229fae Merge branch 'edge' into meteor-1.8 2018-11-17 16:58:27 +02:00
Lauri Ojansivu e1b3f38315 Merge branch 'edge' into meteor-1.8 2018-11-17 15:22:47 +02:00
Lauri Ojansivu b8b1512e26 Merge branch 'edge' into meteor-1.8 2018-11-17 14:51:22 +02:00
Lauri Ojansivu 3300c69a03 Merge branch 'edge' into meteor-1.8 2018-11-09 21:58:31 +02:00
Lauri Ojansivu 09a95dfef6 v1.69.2 2018-11-05 15:46:43 +02:00
Lauri Ojansivu ea141f62d7 Update meteor 2018-11-05 15:43:35 +02:00
194 changed files with 15491 additions and 12214 deletions

No files matched your search

+17
View File
@@ -8,3 +8,20 @@ end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
[*.{js,html}]
charset = utf-8
end_of_line = lf
indent_brace_style = 1TBS
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
quote_type = auto
spaces_around_operators = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
+1
View File
@@ -0,0 +1 @@
packages/*
+34 -12
View File
@@ -1,16 +1,19 @@
{
"extends": "eslint:recommended",
"extends": [
"eslint:recommended",
"plugin:meteor/recommended",
"prettier",
"prettier/standard"
],
"env": {
"es6": true,
"node": true,
"browser": true
"browser": true,
"meteor": true
},
"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module",
"ecmaFeatures": {
"experimentalObjectRestSpread": true
}
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"strict": 0,
@@ -20,7 +23,7 @@
"consistent-return": 2,
"dot-notation": 2,
"eqeqeq": 2,
"indent": [2, 2],
"indent": 0,
"no-cond-assign": 2,
"no-constant-condition": 2,
"no-eval": 2,
@@ -28,11 +31,12 @@
"no-unneeded-ternary": 2,
"radix": 2,
"semi": [2, "always"],
"camelcase": [2, {"properties": "never"}],
"camelcase": [2, { "properties": "never" }],
"comma-spacing": 2,
"comma-style": 2,
"eol-last": 2,
"linebreak-style": [2, "unix"],
"meteor/audit-argument-checks": 0,
"new-parens": 2,
"no-lonely-if": 2,
"no-multiple-empty-lines": 2,
@@ -43,7 +47,6 @@
"quotes": [2, "single"],
"semi-spacing": 2,
"space-unary-ops": 2,
"arrow-parens": 2,
"arrow-spacing": 2,
"no-class-assign": 2,
"no-dupe-class-members": 2,
@@ -52,8 +55,27 @@
"prefer-const": 2,
"prefer-spread": 2,
"prefer-template": 2,
"no-unused-vars" : "warn"
"no-unused-vars": "warn",
"prettier/prettier": [
"error",
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"trailingComma": "all"
}
],
"meteor/no-session": 0
},
"settings": {
"import/resolver": {
"meteor": {
"extensions": [".js", ".jsx"]
}
}
},
"plugins": ["prettier", "meteor"],
"globals": {
"Meteor": false,
"Session": false,
@@ -100,7 +122,7 @@
"Attachments": true,
"Boards": true,
"CardComments": true,
"DatePicker" : true,
"DatePicker": true,
"Cards": true,
"CustomFields": true,
"Lists": true,
+1
View File
@@ -16,3 +16,4 @@ notices-for-facebook-graph-api-2
1.4.1-add-shell-server-package
1.4.3-split-account-service-packages
1.5-add-dynamic-import-package
1.7-split-underscore-from-meteor-base
+22 -21
View File
@@ -3,17 +3,16 @@
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
meteor-base@1.2.0
meteor-base@1.4.0
# Build system
ecmascript
stylus@2.513.13
standard-minifier-css@1.3.5
standard-minifier-js@2.2.0
ecmascript@0.12.4
standard-minifier-css@1.5.3
standard-minifier-js@2.4.1
mquandalle:jade
# Polyfills
es5-shim@4.6.15
es5-shim@4.8.0
# Collections
aldeed:collection2
@@ -23,7 +22,7 @@ dburles:collection-helpers
idmontie:migrations
matb33:collection-hooks
matteodem:easy-search
mongo@1.3.1
mongo@1.6.2
mquandalle:collection-mutations
# Account system
@@ -36,12 +35,12 @@ wekan-accounts-cas
wekan-accounts-oidc
# Utilities
check@1.2.5
check@1.3.1
jquery@1.11.10
random@1.0.10
reactive-dict@1.2.0
session@1.1.7
tracker@1.1.3
random@1.1.0
reactive-dict@1.3.0
session@1.2.0
tracker@1.2.0
underscore@1.0.10
3stack:presence
alethes:pages
@@ -49,13 +48,11 @@ arillo:flow-router-helpers
audit-argument-checks@1.0.7
kadira:blaze-layout
kadira:dochead
meteorhacks:picker
meteorhacks:subs-manager
mquandalle:autofocus
ongoworks:speakingurl
raix:handlebar-helpers
tap:i18n
http@1.3.0
http@1.4.2
# UI components
blaze
@@ -70,25 +67,29 @@ templates:tabs
verron:autosize
simple:json-routes
rajit:bootstrap3-datepicker
shell-server@0.3.0
shell-server@0.4.0
simple:rest-accounts-password
useraccounts:core
email@1.2.3
horka:swipebox
dynamic-import@0.2.0
dynamic-import@0.5.1
staringatlights:fast-render
mixmax:smart-disconnect
accounts-password@1.5.0
accounts-password@1.5.1
cfs:gridfs
rzymek:fullcalendar
momentjs:moment@2.22.2
browser-policy-framing
browser-policy-framing@1.1.0
mquandalle:moment
msavin:usercache
wekan-scrollbar
mquandalle:perfect-scrollbar
mdg:meteor-apm-agent
meteorhacks:unblock
mdg:meteor-apm-agent@3.2.0-rc.0!
coagmano:stylus
lucasantoniassi:accounts-lockout
meteorhacks:subs-manager
meteorhacks:picker
lamhieu:unblock
meteorhacks:aggregate@1.3.0
wekan-markdown
+1 -1
View File
@@ -1 +1 @@
METEOR@1.6.0.1
METEOR@1.8.1
+81 -76
View File
@@ -1,29 +1,29 @@
3stack:presence@1.1.2
accounts-base@1.4.0
accounts-oauth@1.1.15
accounts-password@1.5.0
accounts-base@1.4.4
accounts-oauth@1.1.16
accounts-password@1.5.1
aldeed:collection2@2.10.0
aldeed:collection2-core@1.2.0
aldeed:schema-deny@1.1.0
aldeed:schema-index@1.1.1
aldeed:simple-schema@1.5.3
aldeed:simple-schema@1.5.4
alethes:pages@1.8.6
allow-deny@1.1.0
arillo:flow-router-helpers@0.5.2
audit-argument-checks@1.0.7
autoupdate@1.3.12
babel-compiler@6.24.7
babel-runtime@1.1.1
base64@1.0.10
binary-heap@1.0.10
blaze@2.3.2
autoupdate@1.6.0
babel-compiler@7.3.4
babel-runtime@1.3.0
base64@1.0.11
binary-heap@1.0.11
blaze@2.3.3
blaze-tools@1.0.10
boilerplate-generator@1.3.1
boilerplate-generator@1.6.0
browser-policy-common@1.0.11
browser-policy-framing@1.1.0
caching-compiler@1.1.9
caching-html-compiler@1.1.2
callback-hook@1.0.10
caching-compiler@1.2.1
caching-html-compiler@1.1.3
callback-hook@1.1.0
cfs:access-point@0.1.49
cfs:base-package@0.0.30
cfs:collection@0.5.5
@@ -36,78 +36,82 @@ cfs:http-publish@0.0.13
cfs:power-queue@0.9.11
cfs:reactive-list@0.0.9
cfs:reactive-property@0.0.4
cfs:standard-packages@0.5.9
cfs:storage-adapter@0.2.3
cfs:tempstore@0.1.5
cfs:standard-packages@0.5.10
cfs:storage-adapter@0.2.4
cfs:tempstore@0.1.6
cfs:upload-http@0.0.20
cfs:worker@0.1.4
check@1.2.5
cfs:worker@0.1.5
check@1.3.1
chuangbo:cookie@1.1.0
coffeescript@1.12.7_3
coffeescript-compiler@1.12.7_3
coagmano:stylus@2.0.0
coffeescript@1.0.17
cottz:publish-relations@2.0.8
dburles:collection-helpers@1.1.0
ddp@1.4.0
ddp-client@2.2.0
ddp-common@1.3.0
ddp-client@2.3.3
ddp-common@1.4.0
ddp-rate-limiter@1.0.7
ddp-server@2.1.1
ddp-server@2.3.0
deps@1.0.12
diff-sequence@1.0.7
dynamic-import@0.2.1
ecmascript@0.9.0
ecmascript-runtime@0.5.0
ecmascript-runtime-client@0.5.0
ecmascript-runtime-server@0.5.0
diff-sequence@1.1.1
dynamic-import@0.5.1
ecmascript@0.12.7
ecmascript-runtime@0.7.0
ecmascript-runtime-client@0.8.0
ecmascript-runtime-server@0.7.1
ejson@1.1.0
email@1.2.3
es5-shim@4.6.15
es5-shim@4.8.0
fastclick@1.0.13
fetch@0.1.1
fortawesome:fontawesome@4.7.0
geojson-utils@1.0.10
horka:swipebox@1.0.2
hot-code-push@1.0.4
html-tools@1.0.11
htmljs@1.0.11
http@1.3.0
id-map@1.0.9
http@1.4.2
id-map@1.1.0
idmontie:migrations@1.0.3
jquery@1.11.10
inter-process-messaging@0.1.0
jquery@1.11.11
kadira:blaze-layout@2.3.0
kadira:dochead@1.5.0
kadira:flow-router@2.12.1
kenton:accounts-sandstorm@0.7.0
lamhieu:meteorx@2.0.1
lamhieu:unblock@1.0.0
launch-screen@1.1.1
livedata@1.0.18
localstorage@1.2.0
logging@1.1.19
logging@1.1.20
lucasantoniassi:accounts-lockout@1.0.0
matb33:collection-hooks@0.8.4
matteodem:easy-search@1.6.4
mdg:meteor-apm-agent@3.1.2
mdg:meteor-apm-agent@3.2.3
mdg:validation-error@0.5.1
meteor@1.8.2
meteor-base@1.2.0
meteor@1.9.3
meteor-base@1.4.0
meteor-platform@1.2.6
meteorhacks:aggregate@1.3.0
meteorhacks:collection-utils@1.2.0
meteorhacks:meteorx@1.4.1
meteorhacks:picker@1.0.3
meteorhacks:subs-manager@1.6.4
meteorhacks:unblock@1.1.0
meteorspark:util@0.2.0
minifier-css@1.2.16
minifier-js@2.2.2
minifier-css@1.4.2
minifier-js@2.4.1
minifiers@1.1.8-faster-rebuild.0
minimongo@1.4.3
minimongo@1.4.5
mixmax:smart-disconnect@0.0.4
mobile-status-bar@1.0.14
modules@0.11.0
modules-runtime@0.9.1
momentjs:moment@2.22.2
mongo@1.3.1
modern-browsers@0.1.4
modules@0.13.0
modules-runtime@0.10.3
momentjs:moment@2.24.0
mongo@1.6.2
mongo-decimal@0.1.1
mongo-dev-server@1.1.0
mongo-id@1.0.6
mongo-id@1.0.7
mongo-livedata@1.0.12
mousetrap:mousetrap@1.4.6_1
mquandalle:autofocus@1.0.0
@@ -119,70 +123,71 @@ mquandalle:jquery-ui-drag-drop-sort@0.2.0
mquandalle:moment@1.0.1
mquandalle:mousetrap-bindglobal@0.0.1
mquandalle:perfect-scrollbar@0.6.5_2
msavin:usercache@1.0.0
msavin:usercache@1.8.0
npm-bcrypt@0.9.3
npm-mongo@2.2.33
oauth@1.2.1
oauth2@1.2.0
npm-mongo@3.1.2
oauth@1.2.8
oauth2@1.2.1
observe-sequence@1.0.16
ongoworks:speakingurl@1.1.0
ordered-dict@1.0.9
ordered-dict@1.1.0
peerlibrary:assert@0.2.5
peerlibrary:base-component@0.16.0
peerlibrary:blaze-components@0.15.1
peerlibrary:computed-field@0.7.0
peerlibrary:reactive-field@0.3.0
promise@0.10.0
peerlibrary:computed-field@0.9.0
peerlibrary:reactive-field@0.5.0
promise@0.11.2
raix:eventemitter@0.1.3
raix:handlebar-helpers@0.2.5
rajit:bootstrap3-datepicker@1.7.1
random@1.0.10
rate-limit@1.0.8
reactive-dict@1.2.0
rajit:bootstrap3-datepicker@1.7.1_1
random@1.1.0
rate-limit@1.0.9
reactive-dict@1.3.0
reactive-var@1.0.11
reload@1.1.11
retry@1.0.9
routepolicy@1.0.12
reload@1.3.0
retry@1.1.0
routepolicy@1.1.0
rzymek:fullcalendar@3.8.0
server-render@0.3.1
service-configuration@1.0.11
session@1.1.7
session@1.2.0
sha@1.0.9
shell-server@0.3.1
shell-server@0.4.0
simple:authenticate-user-by-token@1.0.1
simple:json-routes@2.1.0
simple:rest-accounts-password@1.1.2
simple:rest-bearer-token-parser@1.0.1
simple:rest-json-error-handler@1.0.1
socket-stream-client@0.2.2
softwarerero:accounts-t9n@1.3.11
spacebars@1.0.15
spacebars-compiler@1.1.3
srp@1.0.10
standard-minifier-css@1.3.5
standard-minifier-js@2.2.3
staringatlights:fast-render@2.16.5
staringatlights:inject-data@2.0.5
stylus@2.513.13
srp@1.0.12
standard-minifier-css@1.5.3
standard-minifier-js@2.4.1
staringatlights:fast-render@3.2.0
staringatlights:inject-data@2.3.0
tap:i18n@1.8.2
templates:tabs@2.3.0
templating@1.3.2
templating-compiler@1.3.3
templating-runtime@1.3.2
templating-tools@1.1.2
tracker@1.1.3
tracker@1.2.0
ui@1.0.13
underscore@1.0.10
url@1.1.0
url@1.2.0
useraccounts:core@1.14.2
useraccounts:flow-routing@1.14.2
useraccounts:unstyled@1.14.2
verron:autosize@3.0.8
webapp@1.4.0
webapp@1.7.4
webapp-hashing@1.0.9
wekan-accounts-cas@0.1.0
wekan-accounts-oidc@1.0.10
wekan-ldap@0.0.2
wekan-markdown@1.0.7
wekan-oidc@1.0.12
wekan-scrollbar@3.1.3
wekan-accounts-cas@0.1.0
wekan-ldap@0.0.2
yasaricli:slugify@0.0.7
zimme:active-route@2.3.2
+7
View File
@@ -0,0 +1,7 @@
packages/
node_modules/
.build/
.meteor/
.vscode/
.tx/
.github/
+8
View File
@@ -0,0 +1,8 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "all"
}
+153 -1
View File
@@ -1,3 +1,155 @@
# v2.94 2019-06-29 Wekan release
This release adds the following updates:
- [Prettier & eslint project style update](https://github.com/wekan/wekan/pull/2520).
Thanks to justinr1234.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.93 2019-06-28 Wekan release
This release fixes the following bugs:
- [LDAP: Check if email attribute is an array, that has many email addresses](https://github.com/wekan/wekan/pull/2519).
Thanks to tdemaret and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.92 2019-06-27 Wekan release
This release fixes the following bugs:
- [Fix Outgoing Webhook messages for Checlists, Checklist Items, Card comments, Add/Remove CustomField to board](https://github.com/wekan/wekan/commit/5283ba9ebbedf11540ffef1d4d87891c5ce9efc7).
Not yet fixed is Outgoing Webhook message about setting CustomField value.
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.91 2019-06-27 Wekan release
This release fixes the following bugs:
- [Fix Attachment Outgoing Webhook missing list and swimlane name](https://github.com/wekan/wekan/commit/6a2f120d00b5ce9089ad2e12d01edb1ed9f94800).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.90 2019-06-21 Wekan release
This release reverts the following Sandstorm changes:
- [Revert v2.89 setting every Sandstorm Wekan user as admin](https://github.com/wekan/wekan/commit/e5c0d0ea18fe74a47afdfe101160280854e2c74f).
Thanks to xet7. [Related #2405](https://github.com/wekan/wekan/issues/2405).
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.89 2019-06-21 Wekan release
This release adds the following Sandstorm features:
- [Sandstorm Wekan: Set everyone as Admin](https://github.com/wekan/wekan/commit/60d62a6ae3a79059e68b2cd1d554d67b7d50b6aa).
Please test does this help with [Problem with the user management: can't add users or give wekan admin rights](https://github.com/wekan/wekan/issues/2405).
Thanks to xet7.
- [If board does not exist, redirect to All Boards page, at all Wekan platforms](https://github.com/wekan/wekan/commit/4f46adc389126597266d71110f9754841f86857c).
So now at Sandstorm when loading Wekan grain, if first Sandstorm board is found,
it is opened. If first Sandstorm board is not found (it's deleted or archived),
then redirect automatically to All Boards page. [Closes #3132](https://github.com/wekan/wekan/issues/3132).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.88 2019-06-21 Wekan release
This release adds the following updates:
- Update translations.
Thanks to translators for their translations.
# v2.87 2019-06-21 Wekan release
This release adds the following new features:
- [Rule cardAction - SetDate](https://github.com/wekan/wekan/pull/2506).
Thanks to road42.
and fixes the following bugs:
- [Fix Move card to top/bottom of list](https://github.com/wekan/wekan/pull/2508).
Thanks to road42.
- [Translation fixes](https://github.com/wekan/wekan/pull/2507).
Thanks to road42.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.86 2019-06-19 Wekan release
This release fixes the following bugs:
- [Fix Wekan unable to Select Text from Description edit box](https://github.com/wekan/wekan/issues/2451)
by removing feature of card description submit on click outside. This is because when selecting text
and dragging up did trigger submit of description, so description was closed and selecting text failed.
This did affect all Chromium-based browsers: Chrome, Chromium, Chromium Edge.
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.85 2019-06-19 Wekan release
This release fixes the following bugs:
- [Fixed bug: rule doesn't move card to top/bottom](https://github.com/wekan/wekan/pull/2502).
Thanks to road42.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.84 2019-06-18 Wekan release
This release fixes the following bugs:
- [Buttons for adding rules to a board where missing for isBoardAdmin](https://github.com/wekan/wekan/pull/2500).
Thanks to road42.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.83 2019-06-17 Wekan release
This release fixes the following bugs:
- [Fix Bug: Unable to click board submenu on mobile](https://github.com/wekan/wekan/commit/7ff6f24a90374ae95edbb87b37e0c235e7aee434).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.82 2019-06-14 Wekan release
This release fixes the following bugs:
- [Fix OIDC Docker login. Empty string results to empty array at wekan/server/authentication.js](https://github.com/wekan/wekan/commit/bddbaa7bc2f3cfe8553a2265e168231ab51876f3).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.81 2019-06-13 Wekan release
This release fixes the following bugs:
- [Change OAuth2 whitelist default to empty string at snap, so it would be used as array on
wekan/server/authentication.js](https://github.com/wekan/wekan/commit/4334fbbb9dacf45b0262019526a9697b015049a1).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.80 2019-06-13 Wekan release
This release fixes the following bugs:
- [Fix OAuth2 typos in snap-src/bin/config](https://github.com/wekan/wekan/commit/44dbd462b19e613fcb47161d44e4046d5d91a319).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v2.79 2019-06-13 Wekan release
This release fixes the following bugs:
@@ -239,7 +391,7 @@ and adds the following updates:
because [it was found old version was in use](https://github.com/wekan/wekan/issues/2334).
Thanks to shaygover and xet7.
- [Upgrade to Node 8.16.0](https://github.com/wekan/wekan/commit/6117097a93bfb11c8bd4c87a23c44a50e22ceb87).
Thanks to Node developers and xet7.
Thanks to Node developers and xet7.
- [Upgrade Docker base image to ubuntu:disco](https://github.com/wekan/wekan/commit/bd14ee3b1f450ddc6dec26ccc8da702b839942e5).
Thanks to Ubuntu developers and xet7.
+8 -8
View File
@@ -7,7 +7,7 @@ LABEL maintainer="wekan"
ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential python3 python3-pip git ca-certificates gcc-8" \
DEBUG=false \
NODE_VERSION=v8.16.0 \
METEOR_RELEASE=1.6.0.1 \
METEOR_RELEASE=1.8.1 \
USE_EDGE=false \
METEOR_EDGE=1.5-beta.17 \
NPM_VERSION=latest \
@@ -40,7 +40,7 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential pyth
OAUTH2_ID_MAP="" \
OAUTH2_USERNAME_MAP="" \
OAUTH2_FULLNAME_MAP="" \
OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[] \
OAUTH2_ID_TOKEN_WHITELIST_FIELDS="" \
OAUTH2_REQUEST_PERMISSIONS='openid profile email' \
OAUTH2_EMAIL_MAP="" \
LDAP_ENABLE=false \
@@ -180,20 +180,20 @@ RUN \
\
# Change user to wekan and install meteor
cd /home/wekan/ && \
chown wekan:wekan --recursive /home/wekan && \
chown wekan --recursive /home/wekan && \
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 && \
echo "Starting meteor ${METEOR_RELEASE} installation... \n" && \
chown wekan:wekan /home/wekan/install_meteor.sh && \
chown wekan /home/wekan/install_meteor.sh && \
\
# 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} git://github.com/meteor/meteor.git /home/wekan/.meteor; \
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
@@ -218,7 +218,7 @@ RUN \
# extract the OpenAPI specification
npm install -g api2html@0.3.3 && \
mkdir -p /home/wekan/python && \
chown wekan:wekan --recursive /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 && \
@@ -233,8 +233,8 @@ RUN \
gosu wekan:wekan /home/wekan/.meteor/meteor 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 && \
chown wekan:wekan /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
#rm /home/wekan/app_build/bundle/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs && \
chown wekan /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac
#https://github.com/wekan/wekan/commit/7eeabf14be3c63fae2226e561ef8a0c1390c8d3c
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v2.79.0"
appVersion: "v2.94.0"
files:
userUploads:
- README.md
+90 -58
View File
@@ -13,7 +13,7 @@ BlazeComponent.extendComponent({
let thisId, searchId;
if (mode === 'linkedcard' || mode === 'linkedboard') {
thisId = Session.get('currentCard');
searchId = Cards.findOne({_id: thisId}).linkedId;
searchId = Cards.findOne({ _id: thisId }).linkedId;
mode = mode.replace('linked', '');
} else {
thisId = Session.get(`current${capitalizedMode}`);
@@ -22,8 +22,7 @@ BlazeComponent.extendComponent({
const limit = this.page.get() * activitiesPerPage;
const user = Meteor.user();
const hideSystem = user ? user.hasHiddenSystemMessages() : false;
if (searchId === null)
return;
if (searchId === null) return;
this.subscribe('activities', mode, searchId, limit, hideSystem, () => {
this.loadNextPageLocked = false;
@@ -50,9 +49,9 @@ BlazeComponent.extendComponent({
}
},
checkItem(){
checkItem() {
const checkItemId = this.currentData().checklistItemId;
const checkItem = ChecklistItems.findOne({_id:checkItemId});
const checkItem = ChecklistItems.findOne({ _id: checkItemId });
return checkItem.title;
},
@@ -66,42 +65,58 @@ BlazeComponent.extendComponent({
cardLink() {
const card = this.currentData().card();
return card && Blaze.toHTML(HTML.A({
href: card.absoluteUrl(),
'class': 'action-card',
}, card.title));
return (
card &&
Blaze.toHTML(
HTML.A(
{
href: card.absoluteUrl(),
class: 'action-card',
},
card.title,
),
)
);
},
lastLabel(){
lastLabel() {
const lastLabelId = this.currentData().labelId;
if (!lastLabelId)
return null;
const lastLabel = Boards.findOne(Session.get('currentBoard')).getLabelById(lastLabelId);
if(lastLabel.name === undefined || lastLabel.name === ''){
if (!lastLabelId) return null;
const lastLabel = Boards.findOne(Session.get('currentBoard')).getLabelById(
lastLabelId,
);
if (lastLabel.name === undefined || lastLabel.name === '') {
return lastLabel.color;
}else{
} else {
return lastLabel.name;
}
},
lastCustomField(){
const lastCustomField = CustomFields.findOne(this.currentData().customFieldId);
if (!lastCustomField)
return null;
lastCustomField() {
const lastCustomField = CustomFields.findOne(
this.currentData().customFieldId,
);
if (!lastCustomField) return null;
return lastCustomField.name;
},
lastCustomFieldValue(){
const lastCustomField = CustomFields.findOne(this.currentData().customFieldId);
if (!lastCustomField)
return null;
lastCustomFieldValue() {
const lastCustomField = CustomFields.findOne(
this.currentData().customFieldId,
);
if (!lastCustomField) return null;
const value = this.currentData().value;
if (lastCustomField.settings.dropdownItems && lastCustomField.settings.dropdownItems.length > 0) {
const dropDownValue = _.find(lastCustomField.settings.dropdownItems, (item) => {
return item._id === value;
});
if (dropDownValue)
return dropDownValue.name;
if (
lastCustomField.settings.dropdownItems &&
lastCustomField.settings.dropdownItems.length > 0
) {
const dropDownValue = _.find(
lastCustomField.settings.dropdownItems,
item => {
return item._id === value;
},
);
if (dropDownValue) return dropDownValue.name;
}
return value;
},
@@ -112,11 +127,16 @@ BlazeComponent.extendComponent({
sourceLink() {
const source = this.currentData().source;
if(source) {
if(source.url) {
return Blaze.toHTML(HTML.A({
href: source.url,
}, source.system));
if (source) {
if (source.url) {
return Blaze.toHTML(
HTML.A(
{
href: source.url,
},
source.system,
),
);
} else {
return source.system;
}
@@ -133,38 +153,50 @@ BlazeComponent.extendComponent({
attachmentLink() {
const attachment = this.currentData().attachment();
// trying to display url before file is stored generates js errors
return attachment && attachment.url({ download: true }) && Blaze.toHTML(HTML.A({
href: attachment.url({ download: true }),
target: '_blank',
}, attachment.name()));
return (
attachment &&
attachment.url({ download: true }) &&
Blaze.toHTML(
HTML.A(
{
href: attachment.url({ download: true }),
target: '_blank',
},
attachment.name(),
),
)
);
},
customField() {
const customField = this.currentData().customField();
if (!customField)
return null;
if (!customField) return null;
return customField.name;
},
events() {
return [{
// XXX We should use Popup.afterConfirmation here
'click .js-delete-comment'() {
const commentId = this.currentData().commentId;
CardComments.remove(commentId);
return [
{
// XXX We should use Popup.afterConfirmation here
'click .js-delete-comment'() {
const commentId = this.currentData().commentId;
CardComments.remove(commentId);
},
'submit .js-edit-comment'(evt) {
evt.preventDefault();
const commentText = this.currentComponent()
.getValue()
.trim();
const commentId = Template.parentData().commentId;
if (commentText) {
CardComments.update(commentId, {
$set: {
text: commentText,
},
});
}
},
},
'submit .js-edit-comment'(evt) {
evt.preventDefault();
const commentText = this.currentComponent().getValue().trim();
const commentId = Template.parentData().commentId;
if (commentText) {
CardComments.update(commentId, {
$set: {
text: commentText,
},
});
}
},
}];
];
},
}).register('activities');
+41 -35
View File
@@ -14,39 +14,41 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-new-comment:not(.focus)'() {
commentFormIsOpen.set(true);
return [
{
'click .js-new-comment:not(.focus)'() {
commentFormIsOpen.set(true);
},
'submit .js-new-comment-form'(evt) {
const input = this.getInput();
const text = input.val().trim();
const card = this.currentData();
let boardId = card.boardId;
let cardId = card._id;
if (card.isLinkedCard()) {
boardId = Cards.findOne(card.linkedId).boardId;
cardId = card.linkedId;
}
if (text) {
CardComments.insert({
text,
boardId,
cardId,
});
resetCommentInput(input);
Tracker.flush();
autosize.update(input);
}
evt.preventDefault();
},
// Pressing Ctrl+Enter should submit the form
'keydown form textarea'(evt) {
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
this.find('button[type=submit]').click();
}
},
},
'submit .js-new-comment-form'(evt) {
const input = this.getInput();
const text = input.val().trim();
const card = this.currentData();
let boardId = card.boardId;
let cardId = card._id;
if (card.isLinkedCard()) {
boardId = Cards.findOne(card.linkedId).boardId;
cardId = card.linkedId;
}
if (text) {
CardComments.insert({
text,
boardId,
cardId,
});
resetCommentInput(input);
Tracker.flush();
autosize.update(input);
}
evt.preventDefault();
},
// Pressing Ctrl+Enter should submit the form
'keydown form textarea'(evt) {
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
this.find('button[type=submit]').click();
}
},
}];
];
},
}).register('commentForm');
@@ -69,7 +71,8 @@ Tracker.autorun(() => {
});
});
EscapeActions.register('inlinedForm',
EscapeActions.register(
'inlinedForm',
() => {
const draftKey = {
fieldName: 'cardComment',
@@ -84,7 +87,10 @@ EscapeActions.register('inlinedForm',
}
resetCommentInput(commentInput);
},
() => { return commentFormIsOpen.get(); }, {
() => {
return commentFormIsOpen.get();
},
{
noClickEscapeOn: '.js-new-comment',
}
},
);
+36 -27
View File
@@ -4,36 +4,45 @@ BlazeComponent.extendComponent({
},
archivedBoards() {
return Boards.find({ archived: true }, {
sort: ['title'],
});
return Boards.find(
{ archived: true },
{
sort: ['title'],
},
);
},
events() {
return [{
'click .js-restore-board'() {
// TODO : Make isSandstorm variable global
const isSandstorm = Meteor.settings && Meteor.settings.public &&
Meteor.settings.public.sandstorm;
if (isSandstorm && Session.get('currentBoard')) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
currentBoard.archive();
}
const board = this.currentData();
board.restore();
Utils.goBoardId(board._id);
return [
{
'click .js-restore-board'() {
// TODO : Make isSandstorm variable global
const isSandstorm =
Meteor.settings &&
Meteor.settings.public &&
Meteor.settings.public.sandstorm;
if (isSandstorm && Session.get('currentBoard')) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
currentBoard.archive();
}
const board = this.currentData();
board.restore();
Utils.goBoardId(board._id);
},
'click .js-delete-board': Popup.afterConfirm('boardDelete', function() {
Popup.close();
const isSandstorm =
Meteor.settings &&
Meteor.settings.public &&
Meteor.settings.public.sandstorm;
if (isSandstorm && Session.get('currentBoard')) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
Boards.remove(currentBoard._id);
}
Boards.remove(this._id);
FlowRouter.go('home');
}),
},
'click .js-delete-board': Popup.afterConfirm('boardDelete', function() {
Popup.close();
const isSandstorm = Meteor.settings && Meteor.settings.public &&
Meteor.settings.public.sandstorm;
if (isSandstorm && Session.get('currentBoard')) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
Boards.remove(currentBoard._id);
}
Boards.remove(this._id);
FlowRouter.go('home');
}),
}];
];
},
}).register('archivedBoards');
+2 -1
View File
@@ -7,7 +7,8 @@ template(name="board")
+boardBody
else
//- XXX We need a better error message in case the board has been archived
+message(label="board-not-found")
//+message(label="board-not-found")
{{goHome}}
else
+spinner
+86 -54
View File
@@ -12,8 +12,7 @@ BlazeComponent.extendComponent({
// unfortunatly, Blaze doesn't have this notion.
this.autorun(() => {
const currentBoardId = Session.get('currentBoard');
if (!currentBoardId)
return;
if (!currentBoardId) return;
const handle = subManager.subscribe('board', currentBoardId, false);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
@@ -27,6 +26,9 @@ BlazeComponent.extendComponent({
return Utils.isMiniScreen() && Session.get('currentCard');
},
goHome() {
FlowRouter.go('home');
},
}).register('board');
BlazeComponent.extendComponent({
@@ -43,7 +45,7 @@ BlazeComponent.extendComponent({
if (nullSortSwimlanes.count() > 0) {
const swimlanes = currentBoardData.swimlanes();
let count = 0;
swimlanes.forEach((s) => {
swimlanes.forEach(s => {
Swimlanes.update(s._id, {
$set: {
sort: count,
@@ -58,7 +60,7 @@ BlazeComponent.extendComponent({
if (nullSortLists.count() > 0) {
const lists = currentBoardData.lists();
let count = 0;
lists.forEach((l) => {
lists.forEach(l => {
Lists.update(l._id, {
$set: {
sort: count,
@@ -106,12 +108,15 @@ BlazeComponent.extendComponent({
// resize all swimlanes + headers to be a total of 150 px per row
// this could be achieved by setIsDragging(true) but we want immediate
// result
ui.item.siblings('.js-swimlane').css('height', `${swimlaneWhileSortingHeight - 26}px`);
ui.item
.siblings('.js-swimlane')
.css('height', `${swimlaneWhileSortingHeight - 26}px`);
// set the new scroll height after the resize and insertion of
// the placeholder. We want the element under the cursor to stay
// at the same place on the screen
ui.item.parent().get(0).scrollTop = ui.placeholder.get(0).offsetTop + parentOffset.top - evt.pageY;
ui.item.parent().get(0).scrollTop =
ui.placeholder.get(0).offsetTop + parentOffset.top - evt.pageY;
},
beforeStop(evt, ui) {
const parentOffset = ui.item.parent().offset();
@@ -120,7 +125,8 @@ BlazeComponent.extendComponent({
// compute the new scroll height after the resize and removal of
// the placeholder
const scrollTop = ui.placeholder.get(0).offsetTop + parentOffset.top - evt.pageY;
const scrollTop =
ui.placeholder.get(0).offsetTop + parentOffset.top - evt.pageY;
// then reset the original view of the swimlane
siblings.removeClass('moving-swimlane');
@@ -150,11 +156,14 @@ BlazeComponent.extendComponent({
sort(evt, ui) {
// get the mouse position in the sortable
const parentOffset = ui.item.parent().offset();
const cursorY = evt.pageY - parentOffset.top + ui.item.parent().scrollTop();
const cursorY =
evt.pageY - parentOffset.top + ui.item.parent().scrollTop();
// compute the intended index of the placeholder (we need to skip the
// slots between the headers and the list of cards)
const newplaceholderIndex = Math.floor(cursorY / swimlaneWhileSortingHeight);
const newplaceholderIndex = Math.floor(
cursorY / swimlaneWhileSortingHeight,
);
let destPlaceholderIndex = (newplaceholderIndex + 1) * 2;
// if we are scrolling far away from the bottom of the list
@@ -165,9 +174,17 @@ BlazeComponent.extendComponent({
// update the placeholder position in the DOM tree
if (destPlaceholderIndex !== ui.placeholder.index()) {
if (destPlaceholderIndex < boardComponent.origPlaceholderIndex) {
ui.placeholder.insertBefore(ui.placeholder.siblings().slice(destPlaceholderIndex - 2, destPlaceholderIndex - 1));
ui.placeholder.insertBefore(
ui.placeholder
.siblings()
.slice(destPlaceholderIndex - 2, destPlaceholderIndex - 1),
);
} else {
ui.placeholder.insertAfter(ui.placeholder.siblings().slice(destPlaceholderIndex - 1, destPlaceholderIndex));
ui.placeholder.insertAfter(
ui.placeholder
.siblings()
.slice(destPlaceholderIndex - 1, destPlaceholderIndex),
);
}
}
},
@@ -177,7 +194,11 @@ BlazeComponent.extendComponent({
enableClickOnTouch('.js-swimlane:not(.placeholder)');
function userIsMember() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
}
// If there is no data in the board (ie, no lists) we autofocus the list
@@ -191,45 +212,49 @@ BlazeComponent.extendComponent({
isViewSwimlanes() {
const currentUser = Meteor.user();
if (!currentUser) return false;
return ((currentUser.profile || {}).boardView === 'board-view-swimlanes');
return (currentUser.profile || {}).boardView === 'board-view-swimlanes';
},
isViewLists() {
const currentUser = Meteor.user();
if (!currentUser) return true;
return ((currentUser.profile || {}).boardView === 'board-view-lists');
return (currentUser.profile || {}).boardView === 'board-view-lists';
},
isViewCalendar() {
const currentUser = Meteor.user();
if (!currentUser) return false;
return ((currentUser.profile || {}).boardView === 'board-view-cal');
return (currentUser.profile || {}).boardView === 'board-view-cal';
},
openNewListForm() {
if (this.isViewSwimlanes()) {
this.childComponents('swimlane')[0]
.childComponents('addListAndSwimlaneForm')[0].open();
.childComponents('addListAndSwimlaneForm')[0]
.open();
} else if (this.isViewLists()) {
this.childComponents('listsGroup')[0]
.childComponents('addListForm')[0].open();
.childComponents('addListForm')[0]
.open();
}
},
events() {
return [{
// XXX The board-overlay div should probably be moved to the parent
// component.
'mouseenter .board-overlay'() {
if (this.mouseHasEnterCardDetails) {
this.showOverlay.set(false);
}
return [
{
// 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;
}
},
},
'mouseup'() {
if (this._isDragging) {
this._isDragging = false;
}
},
}];
];
},
// XXX Flow components allow us to avoid creating these two setter methods by
@@ -241,23 +266,24 @@ BlazeComponent.extendComponent({
scrollLeft(position = 0) {
const swimlanes = this.$('.js-swimlanes');
swimlanes && swimlanes.animate({
scrollLeft: position,
});
swimlanes &&
swimlanes.animate({
scrollLeft: position,
});
},
scrollTop(position = 0) {
const swimlanes = this.$('.js-swimlanes');
swimlanes && swimlanes.animate({
scrollTop: position,
});
swimlanes &&
swimlanes.animate({
scrollTop: position,
});
},
}).register('boardBody');
BlazeComponent.extendComponent({
onRendered() {
this.autorun(function(){
this.autorun(function() {
$('#calendar-view').fullCalendar('refetchEvents');
});
},
@@ -269,7 +295,8 @@ BlazeComponent.extendComponent({
timezone: 'local',
header: {
left: 'title today prev,next',
center: 'agendaDay,listDay,timelineDay agendaWeek,listWeek,timelineWeek month,timelineMonth timelineYear',
center:
'agendaDay,listDay,timelineDay agendaWeek,listWeek,timelineWeek month,timelineMonth timelineYear',
right: '',
},
// height: 'parent', nope, doesn't work as the parent might be small
@@ -279,7 +306,7 @@ BlazeComponent.extendComponent({
nowIndicator: true,
businessHours: {
// days of week. an array of zero-based day of week integers (0=Sunday)
dow: [ 1, 2, 3, 4, 5 ], // Monday - Friday
dow: [1, 2, 3, 4, 5], // Monday - Friday
start: '8:00',
end: '18:00',
},
@@ -287,20 +314,25 @@ BlazeComponent.extendComponent({
events(start, end, timezone, callback) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const events = [];
currentBoard.cardsInInterval(start.toDate(), end.toDate()).forEach(function(card){
events.push({
id: card._id,
title: card.title,
start: card.startAt,
end: card.endAt,
allDay: Math.abs(card.endAt.getTime() - card.startAt.getTime()) / 1000 === 24*3600,
url: FlowRouter.url('card', {
boardId: currentBoard._id,
slug: currentBoard.slug,
cardId: card._id,
}),
currentBoard
.cardsInInterval(start.toDate(), end.toDate())
.forEach(function(card) {
events.push({
id: card._id,
title: card.title,
start: card.startAt,
end: card.endAt,
allDay:
Math.abs(card.endAt.getTime() - card.startAt.getTime()) /
1000 ===
24 * 3600,
url: FlowRouter.url('card', {
boardId: currentBoard._id,
slug: currentBoard.slug,
cardId: card._id,
}),
});
});
});
callback(events);
},
eventResize(event, delta, revertFunc) {
@@ -335,6 +367,6 @@ BlazeComponent.extendComponent({
isViewCalendar() {
const currentUser = Meteor.user();
if (!currentUser) return false;
return ((currentUser.profile || {}).boardView === 'board-view-cal');
return (currentUser.profile || {}).boardView === 'board-view-cal';
},
}).register('calendarView');
+119 -87
View File
@@ -45,15 +45,21 @@ Template.boardMenuPopup.helpers({
});
Template.boardChangeTitlePopup.events({
submit(evt, tpl) {
const newTitle = tpl.$('.js-board-name').val().trim();
const newDesc = tpl.$('.js-board-desc').val().trim();
submit(event, templateInstance) {
const newTitle = templateInstance
.$('.js-board-name')
.val()
.trim();
const newDesc = templateInstance
.$('.js-board-desc')
.val()
.trim();
if (newTitle) {
this.rename(newTitle);
this.setDescription(newDesc);
Popup.close();
}
evt.preventDefault();
event.preventDefault();
},
});
@@ -76,67 +82,79 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-edit-board-title': Popup.open('boardChangeTitle'),
'click .js-star-board'() {
Meteor.user().toggleBoardStar(Session.get('currentBoard'));
return [
{
'click .js-edit-board-title': Popup.open('boardChangeTitle'),
'click .js-star-board'() {
Meteor.user().toggleBoardStar(Session.get('currentBoard'));
},
'click .js-open-board-menu': Popup.open('boardMenu'),
'click .js-change-visibility': Popup.open('boardChangeVisibility'),
'click .js-watch-board': Popup.open('boardChangeWatch'),
'click .js-open-archived-board'() {
Modal.open('archivedBoards');
},
'click .js-toggle-board-view'() {
const currentUser = Meteor.user();
if (
(currentUser.profile || {}).boardView === 'board-view-swimlanes'
) {
currentUser.setBoardView('board-view-cal');
} else if (
(currentUser.profile || {}).boardView === 'board-view-lists'
) {
currentUser.setBoardView('board-view-swimlanes');
} else if (
(currentUser.profile || {}).boardView === 'board-view-cal'
) {
currentUser.setBoardView('board-view-lists');
} else {
currentUser.setBoardView('board-view-swimlanes');
}
},
'click .js-toggle-sidebar'() {
Sidebar.toggle();
},
'click .js-open-filter-view'() {
Sidebar.setView('filter');
},
'click .js-filter-reset'(event) {
event.stopPropagation();
Sidebar.setView();
Filter.reset();
},
'click .js-open-search-view'() {
Sidebar.setView('search');
},
'click .js-open-rules-view'() {
Modal.openWide('rulesMain');
},
'click .js-multiselection-activate'() {
const currentCard = Session.get('currentCard');
MultiSelection.activate();
if (currentCard) {
MultiSelection.add(currentCard);
}
},
'click .js-multiselection-reset'(event) {
event.stopPropagation();
MultiSelection.disable();
},
'click .js-log-in'() {
FlowRouter.go('atSignIn');
},
},
'click .js-open-board-menu': Popup.open('boardMenu'),
'click .js-change-visibility': Popup.open('boardChangeVisibility'),
'click .js-watch-board': Popup.open('boardChangeWatch'),
'click .js-open-archived-board'() {
Modal.open('archivedBoards');
},
'click .js-toggle-board-view'() {
const currentUser = Meteor.user();
if ((currentUser.profile || {}).boardView === 'board-view-swimlanes') {
currentUser.setBoardView('board-view-cal');
} else if ((currentUser.profile || {}).boardView === 'board-view-lists') {
currentUser.setBoardView('board-view-swimlanes');
} else if ((currentUser.profile || {}).boardView === 'board-view-cal') {
currentUser.setBoardView('board-view-lists');
} else {
currentUser.setBoardView('board-view-swimlanes');
}
},
'click .js-toggle-sidebar'() {
Sidebar.toggle();
},
'click .js-open-filter-view'() {
Sidebar.setView('filter');
},
'click .js-filter-reset'(evt) {
evt.stopPropagation();
Sidebar.setView();
Filter.reset();
},
'click .js-open-search-view'() {
Sidebar.setView('search');
},
'click .js-open-rules-view'() {
Modal.openWide('rulesMain');
},
'click .js-multiselection-activate'() {
const currentCard = Session.get('currentCard');
MultiSelection.activate();
if (currentCard) {
MultiSelection.add(currentCard);
}
},
'click .js-multiselection-reset'(evt) {
evt.stopPropagation();
MultiSelection.disable();
},
'click .js-log-in'() {
FlowRouter.go('atSignIn');
},
}];
];
},
}).register('boardHeaderBar');
Template.boardHeaderBar.helpers({
canModifyBoard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
});
@@ -164,15 +182,17 @@ const CreateBoard = BlazeComponent.extendComponent({
this.visibilityMenuIsOpen.set(!this.visibilityMenuIsOpen.get());
},
onSubmit(evt) {
evt.preventDefault();
onSubmit(event) {
event.preventDefault();
const title = this.find('.js-new-board-title').value;
const visibility = this.visibility.get();
this.boardId.set(Boards.insert({
title,
permission: visibility,
}));
this.boardId.set(
Boards.insert({
title,
permission: visibility,
}),
);
Swimlanes.insert({
title: 'Default',
@@ -183,26 +203,28 @@ const CreateBoard = BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-select-visibility'() {
this.setVisibility(this.currentData());
return [
{
'click .js-select-visibility'() {
this.setVisibility(this.currentData());
},
'click .js-change-visibility': this.toggleVisibilityMenu,
'click .js-import': Popup.open('boardImportBoard'),
submit: this.onSubmit,
'click .js-import-board': Popup.open('chooseBoardSource'),
'click .js-board-template': Popup.open('searchElement'),
},
'click .js-change-visibility': this.toggleVisibilityMenu,
'click .js-import': Popup.open('boardImportBoard'),
submit: this.onSubmit,
'click .js-import-board': Popup.open('chooseBoardSource'),
'click .js-board-template': Popup.open('searchElement'),
}];
];
},
}).register('createBoardPopup');
(class HeaderBarCreateBoard extends CreateBoard {
onSubmit(evt) {
super.onSubmit(evt);
onSubmit(event) {
super.onSubmit(event);
// Immediately star boards crated with the headerbar popup.
Meteor.user().toggleBoardStar(this.boardId.get());
}
}).register('headerBarCreateBoardPopup');
}.register('headerBarCreateBoardPopup'));
BlazeComponent.extendComponent({
visibilityCheck() {
@@ -218,9 +240,11 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-select-visibility': this.selectBoardVisibility,
}];
return [
{
'click .js-select-visibility': this.selectBoardVisibility,
},
];
},
}).register('boardChangeVisibilityPopup');
@@ -235,13 +259,21 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-select-watch'() {
const level = this.currentData();
Meteor.call('watch', 'board', Session.get('currentBoard'), level, (err, ret) => {
if (!err && ret) Popup.close();
});
return [
{
'click .js-select-watch'() {
const level = this.currentData();
Meteor.call(
'watch',
'board',
Session.get('currentBoard'),
level,
(err, ret) => {
if (!err && ret) Popup.close();
},
);
},
},
}];
];
},
}).register('boardChangeWatchPopup');
+50 -44
View File
@@ -21,11 +21,14 @@ BlazeComponent.extendComponent({
},
boards() {
return Boards.find({
archived: false,
'members.userId': Meteor.userId(),
type: 'board',
}, { sort: ['title'] });
return Boards.find(
{
archived: false,
'members.userId': Meteor.userId(),
type: 'board',
},
{ sort: ['title'] },
);
},
isStarred() {
const user = Meteor.user();
@@ -48,46 +51,49 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-add-board': Popup.open('createBoard'),
'click .js-star-board'(evt) {
const boardId = this.currentData()._id;
Meteor.user().toggleBoardStar(boardId);
evt.preventDefault();
},
'click .js-clone-board'(evt) {
Meteor.call('cloneBoard',
this.currentData()._id,
Session.get('fromBoard'),
(err, res) => {
if (err) {
this.setError(err.error);
} else {
Session.set('fromBoard', null);
Utils.goBoardId(res);
return [
{
'click .js-add-board': Popup.open('createBoard'),
'click .js-star-board'(evt) {
const boardId = this.currentData()._id;
Meteor.user().toggleBoardStar(boardId);
evt.preventDefault();
},
'click .js-clone-board'(evt) {
Meteor.call(
'cloneBoard',
this.currentData()._id,
Session.get('fromBoard'),
(err, res) => {
if (err) {
this.setError(err.error);
} else {
Session.set('fromBoard', null);
Utils.goBoardId(res);
}
},
);
evt.preventDefault();
},
'click .js-archive-board'(evt) {
const boardId = this.currentData()._id;
Meteor.call('archiveBoard', boardId);
evt.preventDefault();
},
'click .js-accept-invite'() {
const boardId = this.currentData()._id;
Meteor.user().removeInvite(boardId);
},
'click .js-decline-invite'() {
const boardId = this.currentData()._id;
Meteor.call('quitBoard', boardId, (err, ret) => {
if (!err && ret) {
Meteor.user().removeInvite(boardId);
FlowRouter.go('home');
}
}
);
evt.preventDefault();
});
},
},
'click .js-archive-board'(evt) {
const boardId = this.currentData()._id;
Meteor.call('archiveBoard', boardId);
evt.preventDefault();
},
'click .js-accept-invite'() {
const boardId = this.currentData()._id;
Meteor.user().removeInvite(boardId);
},
'click .js-decline-invite'() {
const boardId = this.currentData()._id;
Meteor.call('quitBoard', boardId, (err, ret) => {
if (!err && ret) {
Meteor.user().removeInvite(boardId);
FlowRouter.go('home');
}
});
},
}];
];
},
}).register('boardList');
+21 -20
View File
@@ -1,10 +1,11 @@
Template.attachmentsGalery.events({
'click .js-add-attachment': Popup.open('cardAttachments'),
'click .js-confirm-delete': Popup.afterConfirm('attachmentDelete',
'click .js-confirm-delete': Popup.afterConfirm(
'attachmentDelete',
function() {
Attachments.remove(this._id);
Popup.close();
}
},
),
// If we let this event bubble, FlowRouter will handle it and empty the page
// content, see #101.
@@ -17,8 +18,8 @@ Template.attachmentsGalery.events({
'click .js-remove-cover'() {
Cards.findOne(this.cardId).unsetCover();
},
'click .js-preview-image'(evt) {
Popup.open('previewAttachedImage').call(this, evt);
'click .js-preview-image'(event) {
Popup.open('previewAttachedImage').call(this, event);
// when multiple thumbnails, if click one then another very fast,
// we might get a wrong width from previous img.
// when popup reused, onRendered() won't be called, so we cannot get there.
@@ -31,37 +32,37 @@ Template.attachmentsGalery.events({
// if the image is too large, we resize & center the popup.
if (w > 300) {
$('div.pop-over').css({
width: (w + 20),
width: w + 20,
position: 'absolute',
left: (window.innerWidth - w)/2,
top: (window.innerHeight - h)/2,
left: (window.innerWidth - w) / 2,
top: (window.innerHeight - h) / 2,
});
}
};
const url = $(evt.currentTarget).attr('src');
if (img.src === url && img.complete)
rePosPopup();
else
img.onload = rePosPopup;
const url = $(event.currentTarget).attr('src');
if (img.src === url && img.complete) rePosPopup();
else img.onload = rePosPopup;
},
});
Template.previewAttachedImagePopup.events({
'click .js-large-image-clicked'(){
'click .js-large-image-clicked'() {
Popup.close();
},
});
Template.cardAttachmentsPopup.events({
'change .js-attach-file'(evt) {
'change .js-attach-file'(event) {
const card = this;
FS.Utility.eachFile(evt, (f) => {
FS.Utility.eachFile(event, f => {
const file = new FS.File(f);
if (card.isLinkedCard()) {
file.boardId = Cards.findOne(card.linkedId).boardId;
file.cardId = card.linkedId;
} else {
file.boardId = card.boardId;
file.swimlaneId = card.swimlaneId;
file.listId = card.listId;
file.cardId = card._id;
}
file.userId = Meteor.userId();
@@ -75,9 +76,9 @@ Template.cardAttachmentsPopup.events({
Popup.close();
});
},
'click .js-computer-upload'(evt, tpl) {
tpl.find('.js-attach-file').click();
evt.preventDefault();
'click .js-computer-upload'(event, templateInstance) {
templateInstance.find('.js-attach-file').click();
event.preventDefault();
},
'click .js-upload-clipboard-image': Popup.open('previewClipboardImage'),
});
@@ -86,7 +87,7 @@ let pastedResults = null;
Template.previewClipboardImagePopup.onRendered(() => {
// we can paste image from clipboard
$(document.body).pasteImageReader((results) => {
$(document.body).pasteImageReader(results => {
if (results.dataURL.startsWith('data:image/')) {
$('img.preview-clipboard-image').attr('src', results.dataURL);
pastedResults = results;
@@ -94,7 +95,7 @@ Template.previewClipboardImagePopup.onRendered(() => {
});
// we can also drag & drop image file to it
$(document.body).dropImageReader((results) => {
$(document.body).dropImageReader(results => {
if (results.dataURL.startsWith('data:image/')) {
$('img.preview-clipboard-image').attr('src', results.dataURL);
pastedResults = results;
+51 -44
View File
@@ -7,22 +7,21 @@ Template.cardCustomFieldsPopup.helpers({
});
Template.cardCustomFieldsPopup.events({
'click .js-select-field'(evt) {
'click .js-select-field'(event) {
const card = Cards.findOne(Session.get('currentCard'));
const customFieldId = this._id;
card.toggleCustomField(customFieldId);
evt.preventDefault();
event.preventDefault();
},
'click .js-settings'(evt) {
'click .js-settings'(event) {
EscapeActions.executeUpTo('detailsPane');
Sidebar.setView('customFields');
evt.preventDefault();
event.preventDefault();
},
});
// cardCustomField
const CardCustomField = BlazeComponent.extendComponent({
getTemplate() {
return `cardCustomField-${this.data().definition.type}`;
},
@@ -34,52 +33,55 @@ const CardCustomField = BlazeComponent.extendComponent({
},
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
});
CardCustomField.register('cardCustomField');
// cardCustomField-text
(class extends CardCustomField {
onCreated() {
super.onCreated();
}
events() {
return [{
'submit .js-card-customfield-text'(evt) {
evt.preventDefault();
const value = this.currentComponent().getValue();
this.card.setCustomField(this.customFieldId, value);
return [
{
'submit .js-card-customfield-text'(event) {
event.preventDefault();
const value = this.currentComponent().getValue();
this.card.setCustomField(this.customFieldId, value);
},
},
}];
];
}
}).register('cardCustomField-text');
}.register('cardCustomField-text'));
// cardCustomField-number
(class extends CardCustomField {
onCreated() {
super.onCreated();
}
events() {
return [{
'submit .js-card-customfield-number'(evt) {
evt.preventDefault();
const value = parseInt(this.find('input').value, 10);
this.card.setCustomField(this.customFieldId, value);
return [
{
'submit .js-card-customfield-number'(event) {
event.preventDefault();
const value = parseInt(this.find('input').value, 10);
this.card.setCustomField(this.customFieldId, value);
},
},
}];
];
}
}).register('cardCustomField-number');
}.register('cardCustomField-number'));
// cardCustomField-date
(class extends CardCustomField {
onCreated() {
super.onCreated();
const self = this;
@@ -108,8 +110,10 @@ CardCustomField.register('cardCustomField');
}
classes() {
if (this.date.get().isBefore(this.now.get(), 'minute') &&
this.now.get().isBefore(this.data().value)) {
if (
this.date.get().isBefore(this.now.get(), 'minute') &&
this.now.get().isBefore(this.data().value)
) {
return 'current';
}
return '';
@@ -120,12 +124,13 @@ CardCustomField.register('cardCustomField');
}
events() {
return [{
'click .js-edit-date': Popup.open('cardCustomField-date'),
}];
return [
{
'click .js-edit-date': Popup.open('cardCustomField-date'),
},
];
}
}).register('cardCustomField-date');
}.register('cardCustomField-date'));
// cardCustomField-datePopup
(class extends DatePicker {
@@ -144,11 +149,10 @@ CardCustomField.register('cardCustomField');
_deleteDate() {
this.card.setCustomField(this.customFieldId, '');
}
}).register('cardCustomField-datePopup');
}.register('cardCustomField-datePopup'));
// cardCustomField-dropdown
(class extends CardCustomField {
onCreated() {
super.onCreated();
this._items = this.data().definition.settings.dropdownItems;
@@ -160,20 +164,23 @@ CardCustomField.register('cardCustomField');
}
selectedItem() {
const selected = this._items.find((item) => {
const selected = this._items.find(item => {
return item._id === this.data().value;
});
return (selected) ? selected.name : TAPi18n.__('custom-field-dropdown-unknown');
return selected
? selected.name
: TAPi18n.__('custom-field-dropdown-unknown');
}
events() {
return [{
'submit .js-card-customfield-dropdown'(evt) {
evt.preventDefault();
const value = this.find('select').value;
this.card.setCustomField(this.customFieldId, value);
return [
{
'submit .js-card-customfield-dropdown'(event) {
event.preventDefault();
const value = this.find('select').value;
this.card.setCustomField(this.customFieldId, value);
},
},
}];
];
}
}).register('cardCustomField-dropdown');
}.register('cardCustomField-dropdown'));
+93 -89
View File
@@ -11,15 +11,20 @@ BlazeComponent.extendComponent({
},
onRendered() {
const $picker = this.$('.js-datepicker').datepicker({
todayHighlight: true,
todayBtn: 'linked',
language: TAPi18n.getLanguage(),
}).on('changeDate', function(evt) {
this.find('#date').value = moment(evt.date).format('L');
this.error.set('');
this.find('#time').focus();
}.bind(this));
const $picker = this.$('.js-datepicker')
.datepicker({
todayHighlight: true,
todayBtn: 'linked',
language: TAPi18n.getLanguage(),
})
.on(
'changeDate',
function(evt) {
this.find('#date').value = moment(evt.date).format('L');
this.error.set('');
this.find('#time').focus();
}.bind(this),
);
if (this.date.get().isValid()) {
$picker.datepicker('update', this.date.get().toDate());
@@ -27,13 +32,11 @@ BlazeComponent.extendComponent({
},
showDate() {
if (this.date.get().isValid())
return this.date.get().format('L');
if (this.date.get().isValid()) return this.date.get().format('L');
return '';
},
showTime() {
if (this.date.get().isValid())
return this.date.get().format('LT');
if (this.date.get().isValid()) return this.date.get().format('LT');
return '';
},
dateFormat() {
@@ -44,51 +47,58 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'keyup .js-date-field'() {
// parse for localized date format in strict mode
const dateMoment = moment(this.find('#date').value, 'L', true);
if (dateMoment.isValid()) {
this.error.set('');
this.$('.js-datepicker').datepicker('update', dateMoment.toDate());
}
},
'keyup .js-time-field'() {
// parse for localized time format in strict mode
const dateMoment = moment(this.find('#time').value, 'LT', true);
if (dateMoment.isValid()) {
this.error.set('');
}
},
'submit .edit-date'(evt) {
evt.preventDefault();
return [
{
'keyup .js-date-field'() {
// parse for localized date format in strict mode
const dateMoment = moment(this.find('#date').value, 'L', true);
if (dateMoment.isValid()) {
this.error.set('');
this.$('.js-datepicker').datepicker('update', dateMoment.toDate());
}
},
'keyup .js-time-field'() {
// parse for localized time format in strict mode
const dateMoment = moment(this.find('#time').value, 'LT', true);
if (dateMoment.isValid()) {
this.error.set('');
}
},
'submit .edit-date'(evt) {
evt.preventDefault();
// if no time was given, init with 12:00
const time = evt.target.time.value || moment(new Date().setHours(12, 0, 0)).format('LT');
// if no time was given, init with 12:00
const time =
evt.target.time.value ||
moment(new Date().setHours(12, 0, 0)).format('LT');
const dateString = `${evt.target.date.value} ${time}`;
const newDate = moment(dateString, 'L LT', true);
if (newDate.isValid()) {
this._storeDate(newDate.toDate());
const dateString = `${evt.target.date.value} ${time}`;
const newDate = moment(dateString, 'L LT', true);
if (newDate.isValid()) {
this._storeDate(newDate.toDate());
Popup.close();
} else {
this.error.set('invalid-date');
evt.target.date.focus();
}
},
'click .js-delete-date'(evt) {
evt.preventDefault();
this._deleteDate();
Popup.close();
}
else {
this.error.set('invalid-date');
evt.target.date.focus();
}
},
},
'click .js-delete-date'(evt) {
evt.preventDefault();
this._deleteDate();
Popup.close();
},
}];
];
},
});
Template.dateBadge.helpers({
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
});
@@ -96,7 +106,8 @@ Template.dateBadge.helpers({
(class extends DatePicker {
onCreated() {
super.onCreated();
this.data().getReceived() && this.date.set(moment(this.data().getReceived()));
this.data().getReceived() &&
this.date.set(moment(this.data().getReceived()));
}
_storeDate(date) {
@@ -106,8 +117,7 @@ Template.dateBadge.helpers({
_deleteDate() {
this.card.setReceived(null);
}
}).register('editCardReceivedDatePopup');
}.register('editCardReceivedDatePopup'));
// editCardStartDatePopup
(class extends DatePicker {
@@ -119,7 +129,10 @@ Template.dateBadge.helpers({
onRendered() {
super.onRendered();
if (moment.isDate(this.card.getReceived())) {
this.$('.js-datepicker').datepicker('setStartDate', this.card.getReceived());
this.$('.js-datepicker').datepicker(
'setStartDate',
this.card.getReceived(),
);
}
}
@@ -130,7 +143,7 @@ Template.dateBadge.helpers({
_deleteDate() {
this.card.setStart(null);
}
}).register('editCardStartDatePopup');
}.register('editCardStartDatePopup'));
// editCardDueDatePopup
(class extends DatePicker {
@@ -153,7 +166,7 @@ Template.dateBadge.helpers({
_deleteDate() {
this.card.setDue(null);
}
}).register('editCardDueDatePopup');
}.register('editCardDueDatePopup'));
// editCardEndDatePopup
(class extends DatePicker {
@@ -176,8 +189,7 @@ Template.dateBadge.helpers({
_deleteDate() {
this.card.setEnd(null);
}
}).register('editCardEndDatePopup');
}.register('editCardEndDatePopup'));
// Display received, start, due & end dates
const CardDate = BlazeComponent.extendComponent({
@@ -224,17 +236,20 @@ class CardReceivedDate extends CardDate {
const startAt = this.data().getStart();
const theDate = this.date.get();
// if dueAt, endAt and startAt exist & are > receivedAt, receivedAt doesn't need to be flagged
if (((startAt) && (theDate.isAfter(dueAt))) ||
((endAt) && (theDate.isAfter(endAt))) ||
((dueAt) && (theDate.isAfter(dueAt))))
if (
(startAt && theDate.isAfter(dueAt)) ||
(endAt && theDate.isAfter(endAt)) ||
(dueAt && theDate.isAfter(dueAt))
)
classes += 'long-overdue';
else
classes += 'current';
else classes += 'current';
return classes;
}
showTitle() {
return `${TAPi18n.__('card-received-on')} ${this.date.get().format('LLLL')}`;
return `${TAPi18n.__('card-received-on')} ${this.date
.get()
.format('LLLL')}`;
}
events() {
@@ -261,13 +276,10 @@ class CardStartDate extends CardDate {
const theDate = this.date.get();
const now = this.now.get();
// if dueAt or endAt exist & are > startAt, startAt doesn't need to be flagged
if (((endAt) && (theDate.isAfter(endAt))) ||
((dueAt) && (theDate.isAfter(dueAt))))
if ((endAt && theDate.isAfter(endAt)) || (dueAt && theDate.isAfter(dueAt)))
classes += 'long-overdue';
else if (theDate.isBefore(now, 'minute'))
classes += 'almost-due';
else
classes += 'current';
else if (theDate.isBefore(now, 'minute')) classes += 'almost-due';
else classes += 'current';
return classes;
}
@@ -298,17 +310,12 @@ class CardDueDate extends CardDate {
const theDate = this.date.get();
const now = this.now.get();
// if the due date is after the end date, green - done early
if ((endAt) && (theDate.isAfter(endAt)))
classes += 'current';
if (endAt && theDate.isAfter(endAt)) classes += 'current';
// if there is an end date, don't need to flag the due date
else if (endAt)
classes += '';
else if (now.diff(theDate, 'days') >= 2)
classes += 'long-overdue';
else if (now.diff(theDate, 'minute') >= 0)
classes += 'due';
else if (now.diff(theDate, 'days') >= -1)
classes += 'almost-due';
else if (endAt) classes += '';
else if (now.diff(theDate, 'days') >= 2) classes += 'long-overdue';
else if (now.diff(theDate, 'minute') >= 0) classes += 'due';
else if (now.diff(theDate, 'days') >= -1) classes += 'almost-due';
return classes;
}
@@ -337,12 +344,9 @@ class CardEndDate extends CardDate {
let classes = 'end-date' + ' ';
const dueAt = this.data().getDue();
const theDate = this.date.get();
if (theDate.diff(dueAt, 'days') >= 2)
classes += 'long-overdue';
else if (theDate.diff(dueAt, 'days') >= 0)
classes += 'due';
else if (theDate.diff(dueAt, 'days') >= -2)
classes += 'almost-due';
if (theDate.diff(dueAt, 'days') >= 2) classes += 'long-overdue';
else if (theDate.diff(dueAt, 'days') >= 0) classes += 'due';
else if (theDate.diff(dueAt, 'days') >= -2) classes += 'almost-due';
return classes;
}
@@ -362,22 +366,22 @@ CardEndDate.register('cardEndDate');
showDate() {
return this.date.get().format('l');
}
}).register('minicardReceivedDate');
}.register('minicardReceivedDate'));
(class extends CardStartDate {
showDate() {
return this.date.get().format('l');
}
}).register('minicardStartDate');
}.register('minicardStartDate'));
(class extends CardDueDate {
showDate() {
return this.date.get().format('l');
}
}).register('minicardDueDate');
}.register('minicardDueDate'));
(class extends CardEndDate {
showDate() {
return this.date.get().format('l');
}
}).register('minicardEndDate');
}.register('minicardEndDate'));
+223 -170
View File
@@ -27,7 +27,7 @@ BlazeComponent.extendComponent({
onCreated() {
this.currentBoard = Boards.findOne(Session.get('currentBoard'));
this.isLoaded = new ReactiveVar(false);
const boardBody = this.parentComponent().parentComponent();
const boardBody = this.parentComponent().parentComponent();
//in Miniview parent is Board, not BoardBody.
if (boardBody !== null) {
boardBody.showOverlay.set(true);
@@ -48,7 +48,11 @@ BlazeComponent.extendComponent({
},
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
scrollParentContainer() {
@@ -80,18 +84,17 @@ BlazeComponent.extendComponent({
const cardContainerScrollTop = $cardContainer.scrollTop();
let topOffset = false;
if(cardViewStartTop !== 100){
if (cardViewStartTop !== 100) {
topOffset = cardViewStartTop - 100;
}
if(topOffset !== false) {
if (topOffset !== false) {
bodyBoardComponent.scrollTop(cardContainerScrollTop + topOffset);
}
},
presentParentTask() {
let result = this.currentBoard.presentParentTask;
if ((result === null) || (result === undefined)) {
if (result === null || result === undefined) {
result = 'no-parent';
}
return result;
@@ -116,7 +119,13 @@ BlazeComponent.extendComponent({
onRendered() {
if (!Utils.isMiniScreen()) {
Meteor.setTimeout(() => {
$('.card-details').mCustomScrollbar({theme:'minimal-dark', setWidth: false, setLeft: 0, scrollbarPosition: 'outside', mouseWheel: true });
$('.card-details').mCustomScrollbar({
theme: 'minimal-dark',
setWidth: false,
setLeft: 0,
scrollbarPosition: 'outside',
mouseWheel: true,
});
this.scrollParentContainer();
}, 500);
}
@@ -212,7 +221,7 @@ BlazeComponent.extendComponent({
},
onDestroyed() {
const parentComponent = this.parentComponent().parentComponent();
const parentComponent = this.parentComponent().parentComponent();
//on mobile view parent is Board, not board body.
if (parentComponent === null) return;
parentComponent.showOverlay.set(false);
@@ -228,56 +237,64 @@ BlazeComponent.extendComponent({
},
};
return [{
...events,
'click .js-close-card-details' () {
Utils.goBoardId(this.data().boardId);
return [
{
...events,
'click .js-close-card-details'() {
Utils.goBoardId(this.data().boardId);
},
'click .js-open-card-details-menu': Popup.open('cardDetailsActions'),
'submit .js-card-description'(event) {
event.preventDefault();
const description = this.currentComponent().getValue();
this.data().setDescription(description);
},
'submit .js-card-details-title'(event) {
event.preventDefault();
const title = this.currentComponent()
.getValue()
.trim();
if (title) {
this.data().setTitle(title);
}
},
'submit .js-card-details-assigner'(event) {
event.preventDefault();
const assigner = this.currentComponent()
.getValue()
.trim();
if (assigner) {
this.data().setAssignedBy(assigner);
}
},
'submit .js-card-details-requester'(event) {
event.preventDefault();
const requester = this.currentComponent()
.getValue()
.trim();
if (requester) {
this.data().setRequestedBy(requester);
}
},
'click .js-member': Popup.open('cardMember'),
'click .js-add-members': Popup.open('cardMembers'),
'click .js-add-labels': Popup.open('cardLabels'),
'click .js-received-date': Popup.open('editCardReceivedDate'),
'click .js-start-date': Popup.open('editCardStartDate'),
'click .js-due-date': Popup.open('editCardDueDate'),
'click .js-end-date': Popup.open('editCardEndDate'),
'mouseenter .js-card-details'() {
const parentComponent = this.parentComponent().parentComponent();
//on mobile view parent is Board, not BoardBody.
if (parentComponent === null) return;
parentComponent.showOverlay.set(true);
parentComponent.mouseHasEnterCardDetails = true;
},
'click #toggleButton'() {
Meteor.call('toggleSystemMessages');
},
},
'click .js-open-card-details-menu': Popup.open('cardDetailsActions'),
'submit .js-card-description' (evt) {
evt.preventDefault();
const description = this.currentComponent().getValue();
this.data().setDescription(description);
},
'submit .js-card-details-title' (evt) {
evt.preventDefault();
const title = this.currentComponent().getValue().trim();
if (title) {
this.data().setTitle(title);
}
},
'submit .js-card-details-assigner'(evt) {
evt.preventDefault();
const assigner = this.currentComponent().getValue().trim();
if (assigner) {
this.data().setAssignedBy(assigner);
}
},
'submit .js-card-details-requester'(evt) {
evt.preventDefault();
const requester = this.currentComponent().getValue().trim();
if (requester) {
this.data().setRequestedBy(requester);
}
},
'click .js-member': Popup.open('cardMember'),
'click .js-add-members': Popup.open('cardMembers'),
'click .js-add-labels': Popup.open('cardLabels'),
'click .js-received-date': Popup.open('editCardReceivedDate'),
'click .js-start-date': Popup.open('editCardStartDate'),
'click .js-due-date': Popup.open('editCardDueDate'),
'click .js-end-date': Popup.open('editCardEndDate'),
'mouseenter .js-card-details' () {
const parentComponent = this.parentComponent().parentComponent();
//on mobile view parent is Board, not BoardBody.
if (parentComponent === null) return;
parentComponent.showOverlay.set(true);
parentComponent.mouseHasEnterCardDetails = true;
},
'click #toggleButton'() {
Meteor.call('toggleSystemMessages');
},
}];
];
},
}).register('cardDetails');
@@ -297,7 +314,9 @@ BlazeComponent.extendComponent({
close(isReset = false) {
if (this.isOpen.get() && !isReset) {
const draft = this.getValue().trim();
if (draft !== Cards.findOne(Session.get('currentCard')).getDescription()) {
if (
draft !== Cards.findOne(Session.get('currentCard')).getDescription()
) {
UnsavedEdits.set(this._getUnsavedEditKey(), this.getValue());
}
}
@@ -311,12 +330,14 @@ BlazeComponent.extendComponent({
events() {
const parentEvents = InlinedForm.prototype.events()[0];
return [{
...parentEvents,
'click .js-close-inlined-form': this.reset,
}];
return [
{
...parentEvents,
'click .js-close-inlined-form': this.reset,
},
];
}
}).register('inlinedCardDescription');
}.register('inlinedCardDescription'));
Template.cardDetailsActionsPopup.helpers({
isWatching() {
@@ -324,7 +345,11 @@ Template.cardDetailsActionsPopup.helpers({
},
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
});
@@ -342,23 +367,31 @@ Template.cardDetailsActionsPopup.events({
'click .js-copy-card': Popup.open('copyCard'),
'click .js-copy-checklist-cards': Popup.open('copyChecklistToManyCards'),
'click .js-set-card-color': Popup.open('setCardColor'),
'click .js-move-card-to-top' (evt) {
evt.preventDefault();
const minOrder = _.min(this.list().cards(this.swimlaneId).map((c) => c.sort));
this.move(this.swimlaneId, this.listId, minOrder - 1);
'click .js-move-card-to-top'(event) {
event.preventDefault();
const minOrder = _.min(
this.list()
.cards(this.swimlaneId)
.map(c => c.sort),
);
this.move(this.boardId, this.swimlaneId, this.listId, minOrder - 1);
},
'click .js-move-card-to-bottom' (evt) {
evt.preventDefault();
const maxOrder = _.max(this.list().cards(this.swimlaneId).map((c) => c.sort));
this.move(this.swimlaneId, this.listId, maxOrder + 1);
'click .js-move-card-to-bottom'(event) {
event.preventDefault();
const maxOrder = _.max(
this.list()
.cards(this.swimlaneId)
.map(c => c.sort),
);
this.move(this.boardId, this.swimlaneId, this.listId, maxOrder + 1);
},
'click .js-archive' (evt) {
evt.preventDefault();
'click .js-archive'(event) {
event.preventDefault();
this.archive();
Popup.close();
},
'click .js-more': Popup.open('cardMore'),
'click .js-toggle-watch-card' () {
'click .js-toggle-watch-card'() {
const currentCard = this;
const level = currentCard.findWatcher(Meteor.userId()) ? null : 'watching';
Meteor.call('watch', 'card', currentCard._id, level, (err, ret) => {
@@ -367,15 +400,15 @@ Template.cardDetailsActionsPopup.events({
},
});
Template.editCardTitleForm.onRendered(function () {
Template.editCardTitleForm.onRendered(function() {
autosize(this.$('.js-edit-card-title'));
});
Template.editCardTitleForm.events({
'keydown .js-edit-card-title' (evt) {
'keydown .js-edit-card-title'(event) {
// If enter key was pressed, submit the data
// Unless the shift key is also being pressed
if (evt.keyCode === 13 && !evt.shiftKey) {
if (event.keyCode === 13 && !event.shiftKey) {
$('.js-submit-edit-card-title-form').click();
}
},
@@ -386,9 +419,9 @@ Template.editCardRequesterForm.onRendered(function() {
});
Template.editCardRequesterForm.events({
'keydown .js-edit-card-requester'(evt) {
'keydown .js-edit-card-requester'(event) {
// If enter key was pressed, submit the data
if (evt.keyCode === 13) {
if (event.keyCode === 13) {
$('.js-submit-edit-card-requester-form').click();
}
},
@@ -399,16 +432,16 @@ Template.editCardAssignerForm.onRendered(function() {
});
Template.editCardAssignerForm.events({
'keydown .js-edit-card-assigner'(evt) {
'keydown .js-edit-card-assigner'(event) {
// If enter key was pressed, submit the data
if (evt.keyCode === 13) {
if (event.keyCode === 13) {
$('.js-submit-edit-card-assigner-form').click();
}
},
});
Template.moveCardPopup.events({
'click .js-done' () {
'click .js-done'() {
// XXX We should *not* get the currentCard from the global state, but
// instead from a “component” state.
const card = Cards.findOne(Session.get('currentCard'));
@@ -429,13 +462,16 @@ BlazeComponent.extendComponent({
},
boards() {
const boards = Boards.find({
archived: false,
'members.userId': Meteor.userId(),
_id: {$ne: Meteor.user().getTemplatesBoardId()},
}, {
sort: ['title'],
});
const boards = Boards.find(
{
archived: false,
'members.userId': Meteor.userId(),
_id: { $ne: Meteor.user().getTemplatesBoardId() },
},
{
sort: ['title'],
},
);
return boards;
},
@@ -450,12 +486,14 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'change .js-select-boards'(evt) {
this.selectedBoardId.set($(evt.currentTarget).val());
subManager.subscribe('board', this.selectedBoardId.get(), false);
return [
{
'change .js-select-boards'(event) {
this.selectedBoardId.set($(event.currentTarget).val());
subManager.subscribe('board', this.selectedBoardId.get(), false);
},
},
}];
];
},
}).register('boardsAndLists');
@@ -471,7 +509,9 @@ Template.copyCardPopup.events({
const textarea = $('#copy-card-title');
const title = textarea.val().trim();
// insert new card to the bottom of new list
card.sort = Lists.findOne(card.listId).cards().count();
card.sort = Lists.findOne(card.listId)
.cards()
.count();
if (title) {
card.title = title;
@@ -489,7 +529,7 @@ Template.copyCardPopup.events({
});
Template.copyChecklistToManyCardsPopup.events({
'click .js-done' () {
'click .js-done'() {
const card = Cards.findOne(Session.get('currentCard'));
const oldId = card._id;
card._id = null;
@@ -502,11 +542,13 @@ Template.copyChecklistToManyCardsPopup.events({
const textarea = $('#copy-card-title');
const titleEntry = textarea.val().trim();
// insert new card to the bottom of new list
card.sort = Lists.findOne(card.listId).cards().count();
card.sort = Lists.findOne(card.listId)
.cards()
.count();
if (titleEntry) {
const titleList = JSON.parse(titleEntry);
for (let i = 0; i < titleList.length; i++){
for (let i = 0; i < titleList.length; i++) {
const obj = titleList[i];
card.title = obj.title;
card.description = obj.description;
@@ -519,12 +561,12 @@ Template.copyChecklistToManyCardsPopup.events({
Filter.addException(_id);
// copy checklists
Checklists.find({cardId: oldId}).forEach((ch) => {
Checklists.find({ cardId: oldId }).forEach(ch => {
ch.copy(_id);
});
// copy subtasks
cursor = Cards.find({parentId: oldId});
cursor = Cards.find({ parentId: oldId });
cursor.forEach(function() {
'use strict';
const subtask = arguments[0];
@@ -534,7 +576,7 @@ Template.copyChecklistToManyCardsPopup.events({
});
// copy card comments
CardComments.find({cardId: oldId}).forEach((cmt) => {
CardComments.find({ cardId: oldId }).forEach(cmt => {
cmt.copy(_id);
});
}
@@ -550,7 +592,7 @@ BlazeComponent.extendComponent({
},
colors() {
return cardColors.map((color) => ({ color, name: '' }));
return cardColors.map(color => ({ color, name: '' }));
},
isSelected(color) {
@@ -561,19 +603,21 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
return [
{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
'click .js-submit'() {
this.currentCard.setColor(this.currentColor.get());
Popup.close();
},
'click .js-remove-color'() {
this.currentCard.setColor(null);
Popup.close();
},
},
'click .js-submit' () {
this.currentCard.setColor(this.currentColor.get());
Popup.close();
},
'click .js-remove-color'() {
this.currentCard.setColor(null);
Popup.close();
},
}];
];
},
}).register('setCardColorPopup');
@@ -592,15 +636,18 @@ BlazeComponent.extendComponent({
},
boards() {
const boards = Boards.find({
archived: false,
'members.userId': Meteor.userId(),
_id: {
$ne: Meteor.user().getTemplatesBoardId(),
const boards = Boards.find(
{
archived: false,
'members.userId': Meteor.userId(),
_id: {
$ne: Meteor.user().getTemplatesBoardId(),
},
},
}, {
sort: ['title'],
});
{
sort: ['title'],
},
);
return boards;
},
@@ -609,7 +656,7 @@ BlazeComponent.extendComponent({
if (this.parentBoard.get()) {
return Cards.find({
boardId: this.parentBoard.get(),
_id: {$ne: currentId},
_id: { $ne: currentId },
});
} else {
return [];
@@ -642,63 +689,69 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-copy-card-link-to-clipboard' () {
// Clipboard code from:
// https://stackoverflow.com/questions/6300213/copy-selected-text-to-the-clipboard-without-using-flash-must-be-cross-browser
const StringToCopyElement = document.getElementById('cardURL');
StringToCopyElement.select();
if (document.execCommand('copy')) {
StringToCopyElement.blur();
} else {
document.getElementById('cardURL').selectionStart = 0;
document.getElementById('cardURL').selectionEnd = 999;
document.execCommand('copy');
if (window.getSelection) {
if (window.getSelection().empty) { // Chrome
window.getSelection().empty();
} else if (window.getSelection().removeAllRanges) { // Firefox
window.getSelection().removeAllRanges();
return [
{
'click .js-copy-card-link-to-clipboard'() {
// Clipboard code from:
// https://stackoverflow.com/questions/6300213/copy-selected-text-to-the-clipboard-without-using-flash-must-be-cross-browser
const StringToCopyElement = document.getElementById('cardURL');
StringToCopyElement.select();
if (document.execCommand('copy')) {
StringToCopyElement.blur();
} else {
document.getElementById('cardURL').selectionStart = 0;
document.getElementById('cardURL').selectionEnd = 999;
document.execCommand('copy');
if (window.getSelection) {
if (window.getSelection().empty) {
// Chrome
window.getSelection().empty();
} else if (window.getSelection().removeAllRanges) {
// Firefox
window.getSelection().removeAllRanges();
}
} else if (document.selection) {
// IE?
document.selection.empty();
}
} else if (document.selection) { // IE?
document.selection.empty();
}
}
},
'click .js-delete': Popup.afterConfirm('cardDelete', function() {
Popup.close();
Cards.remove(this._id);
Utils.goBoardId(this.boardId);
}),
'change .js-field-parent-board'(event) {
const selection = $(event.currentTarget).val();
const list = $('.js-field-parent-card');
if (selection === 'none') {
this.parentBoard.set(null);
} else {
subManager.subscribe('board', $(event.currentTarget).val(), false);
this.parentBoard.set(selection);
list.prop('disabled', false);
}
this.setParentCardId(null);
},
'change .js-field-parent-card'(event) {
const selection = $(event.currentTarget).val();
this.setParentCardId(selection);
},
},
'click .js-delete': Popup.afterConfirm('cardDelete', function () {
Popup.close();
Cards.remove(this._id);
Utils.goBoardId(this.boardId);
}),
'change .js-field-parent-board'(evt) {
const selection = $(evt.currentTarget).val();
const list = $('.js-field-parent-card');
if (selection === 'none') {
this.parentBoard.set(null);
} else {
subManager.subscribe('board', $(evt.currentTarget).val(), false);
this.parentBoard.set(selection);
list.prop('disabled', false);
}
this.setParentCardId(null);
},
'change .js-field-parent-card'(evt) {
const selection = $(evt.currentTarget).val();
this.setParentCardId(selection);
},
}];
];
},
}).register('cardMorePopup');
// Close the card details pane by pressing escape
EscapeActions.register('detailsPane',
EscapeActions.register(
'detailsPane',
() => {
Utils.goBoardId(Session.get('currentBoard'));
},
() => {
return !Session.equals('currentCard', null);
}, {
},
{
noClickEscapeOn: '.js-card-details,.board-sidebar,#header',
}
},
);
+37 -25
View File
@@ -20,29 +20,31 @@ BlazeComponent.extendComponent({
this.card.setSpentTime(null);
},
events() {
return [{
//TODO : need checking this portion
'submit .edit-time'(evt) {
evt.preventDefault();
return [
{
//TODO : need checking this portion
'submit .edit-time'(evt) {
evt.preventDefault();
const spentTime = parseFloat(evt.target.time.value);
const isOvertime = this.card.getIsOvertime();
const spentTime = parseFloat(evt.target.time.value);
const isOvertime = this.card.getIsOvertime();
if (spentTime >= 0) {
this.storeTime(spentTime, isOvertime);
if (spentTime >= 0) {
this.storeTime(spentTime, isOvertime);
Popup.close();
} else {
this.error.set('invalid-time');
evt.target.time.focus();
}
},
'click .js-delete-time'(evt) {
evt.preventDefault();
this.deleteTime();
Popup.close();
} else {
this.error.set('invalid-time');
evt.target.time.focus();
}
},
'click a.js-toggle-overtime': this.toggleOvertime,
},
'click .js-delete-time'(evt) {
evt.preventDefault();
this.deleteTime();
Popup.close();
},
'click a.js-toggle-overtime': this.toggleOvertime,
}];
];
},
}).register('editCardSpentTimePopup');
@@ -56,23 +58,33 @@ BlazeComponent.extendComponent({
},
showTitle() {
if (this.data().getIsOvertime()) {
return `${TAPi18n.__('overtime')} ${this.data().getSpentTime()} ${TAPi18n.__('hours')}`;
return `${TAPi18n.__(
'overtime',
)} ${this.data().getSpentTime()} ${TAPi18n.__('hours')}`;
} else {
return `${TAPi18n.__('card-spent')} ${this.data().getSpentTime()} ${TAPi18n.__('hours')}`;
return `${TAPi18n.__(
'card-spent',
)} ${this.data().getSpentTime()} ${TAPi18n.__('hours')}`;
}
},
showTime() {
return this.data().getSpentTime();
},
events() {
return [{
'click .js-edit-time': Popup.open('editCardSpentTime'),
}];
return [
{
'click .js-edit-time': Popup.open('editCardSpentTime'),
},
];
},
}).register('cardSpentTime');
Template.timeBadge.helpers({
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
});
+45 -25
View File
@@ -64,20 +64,22 @@ BlazeComponent.extendComponent({
},
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
}).register('checklistDetail');
BlazeComponent.extendComponent({
addChecklist(event) {
event.preventDefault();
const textarea = this.find('textarea.js-add-checklist-item');
const title = textarea.value.trim();
let cardId = this.currentData().cardId;
const card = Cards.findOne(cardId);
if (card.isLinked())
cardId = card.linkedId;
if (card.isLinked()) cardId = card.linkedId;
if (title) {
Checklists.insert({
@@ -86,7 +88,9 @@ BlazeComponent.extendComponent({
sort: card.checklists().count(),
});
setTimeout(() => {
this.$('.add-checklist-item').last().click();
this.$('.add-checklist-item')
.last()
.click();
}, 100);
}
textarea.value = '';
@@ -113,7 +117,11 @@ BlazeComponent.extendComponent({
},
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
deleteChecklist() {
@@ -167,37 +175,43 @@ BlazeComponent.extendComponent({
events() {
const events = {
'click .toggle-delete-checklist-dialog'(event) {
if($(event.target).hasClass('js-delete-checklist')){
if ($(event.target).hasClass('js-delete-checklist')) {
this.checklistToDelete = this.currentData().checklist; //Store data context
}
this.toggleDeleteDialog.set(!this.toggleDeleteDialog.get());
},
};
return [{
...events,
'submit .js-add-checklist': this.addChecklist,
'submit .js-edit-checklist-title': this.editChecklist,
'submit .js-add-checklist-item': this.addChecklistItem,
'submit .js-edit-checklist-item': this.editChecklistItem,
'click .js-delete-checklist-item': this.deleteItem,
'click .confirm-checklist-delete': this.deleteChecklist,
keydown: this.pressKey,
}];
return [
{
...events,
'submit .js-add-checklist': this.addChecklist,
'submit .js-edit-checklist-title': this.editChecklist,
'submit .js-add-checklist-item': this.addChecklistItem,
'submit .js-edit-checklist-item': this.editChecklistItem,
'click .js-delete-checklist-item': this.deleteItem,
'click .confirm-checklist-delete': this.deleteChecklist,
keydown: this.pressKey,
},
];
},
}).register('checklists');
Template.checklistDeleteDialog.onCreated(() => {
const $cardDetails = this.$('.card-details');
this.scrollState = { position: $cardDetails.scrollTop(), //save current scroll position
this.scrollState = {
position: $cardDetails.scrollTop(), //save current scroll position
top: false, //required for smooth scroll animation
};
//Callback's purpose is to only prevent scrolling after animation is complete
$cardDetails.animate({ scrollTop: 0 }, 500, () => { this.scrollState.top = true; });
$cardDetails.animate({ scrollTop: 0 }, 500, () => {
this.scrollState.top = true;
});
//Prevent scrolling while dialog is open
$cardDetails.on('scroll', () => {
if(this.scrollState.top) { //If it's already in position, keep it there. Otherwise let animation scroll
if (this.scrollState.top) {
//If it's already in position, keep it there. Otherwise let animation scroll
$cardDetails.scrollTop(0);
}
});
@@ -206,12 +220,16 @@ Template.checklistDeleteDialog.onCreated(() => {
Template.checklistDeleteDialog.onDestroyed(() => {
const $cardDetails = this.$('.card-details');
$cardDetails.off('scroll'); //Reactivate scrolling
$cardDetails.animate( { scrollTop: this.scrollState.position });
$cardDetails.animate({ scrollTop: this.scrollState.position });
});
Template.checklistItemDetail.helpers({
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
});
@@ -224,8 +242,10 @@ BlazeComponent.extendComponent({
}
},
events() {
return [{
'click .js-checklist-item .check-box': this.toggleItem,
}];
return [
{
'click .js-checklist-item .check-box': this.toggleItem,
},
];
},
}).register('checklistItemDetail');
+25 -17
View File
@@ -9,7 +9,7 @@ BlazeComponent.extendComponent({
},
labels() {
return labelColors.map((color) => ({ color, name: '' }));
return labelColors.map(color => ({ color, name: '' }));
},
isSelected(color) {
@@ -17,11 +17,13 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
return [
{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
},
}];
];
},
}).register('formLabel');
@@ -38,19 +40,19 @@ Template.createLabelPopup.helpers({
});
Template.cardLabelsPopup.events({
'click .js-select-label'(evt) {
'click .js-select-label'(event) {
const card = Cards.findOne(Session.get('currentCard'));
const labelId = this._id;
card.toggleLabel(labelId);
evt.preventDefault();
event.preventDefault();
},
'click .js-edit-label': Popup.open('editLabel'),
'click .js-add-label': Popup.open('createLabel'),
});
Template.formLabel.events({
'click .js-palette-color'(evt) {
const $this = $(evt.currentTarget);
'click .js-palette-color'(event) {
const $this = $(event.currentTarget);
// hide selected ll colors
$('.js-palette-select').addClass('hide');
@@ -62,11 +64,14 @@ Template.formLabel.events({
Template.createLabelPopup.events({
// Create the new label
'submit .create-label'(evt, tpl) {
evt.preventDefault();
'submit .create-label'(event, templateInstance) {
event.preventDefault();
const board = Boards.findOne(Session.get('currentBoard'));
const name = tpl.$('#labelName').val().trim();
const color = Blaze.getData(tpl.find('.fa-check')).color;
const name = templateInstance
.$('#labelName')
.val()
.trim();
const color = Blaze.getData(templateInstance.find('.fa-check')).color;
board.addLabel(name, color);
Popup.back();
},
@@ -78,11 +83,14 @@ Template.editLabelPopup.events({
board.removeLabel(this._id);
Popup.back(2);
}),
'submit .edit-label'(evt, tpl) {
evt.preventDefault();
'submit .edit-label'(event, templateInstance) {
event.preventDefault();
const board = Boards.findOne(Session.get('currentBoard'));
const name = tpl.$('#labelName').val().trim();
const color = Blaze.getData(tpl.find('.fa-check')).color;
const name = templateInstance
.$('#labelName')
.val()
.trim();
const color = Blaze.getData(templateInstance.find('.fa-check')).color;
board.editLabel(this._id, name, color);
Popup.back();
},
+8 -7
View File
@@ -8,13 +8,14 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-linked-link' () {
if (this.data().isLinkedCard())
Utils.goCardId(this.data().linkedId);
else if (this.data().isLinkedBoard())
Utils.goBoardId(this.data().linkedId);
return [
{
'click .js-linked-link'() {
if (this.data().isLinkedCard()) Utils.goCardId(this.data().linkedId);
else if (this.data().isLinkedBoard())
Utils.goBoardId(this.data().linkedId);
},
},
}];
];
},
}).register('minicard');
+37 -19
View File
@@ -1,11 +1,14 @@
BlazeComponent.extendComponent({
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
}).register('subtaskDetail');
BlazeComponent.extendComponent({
addSubtask(event) {
event.preventDefault();
const textarea = this.find('textarea.js-add-subtask-item');
@@ -38,9 +41,10 @@ BlazeComponent.extendComponent({
// See https://github.com/wekan/wekan/issues/80
Filter.addException(_id);
setTimeout(() => {
this.$('.add-subtask-item').last().click();
this.$('.add-subtask-item')
.last()
.click();
}, 100);
}
textarea.value = '';
@@ -48,7 +52,11 @@ BlazeComponent.extendComponent({
},
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
deleteSubtask() {
@@ -85,13 +93,13 @@ BlazeComponent.extendComponent({
events() {
const events = {
'click .toggle-delete-subtask-dialog'(event) {
if($(event.target).hasClass('js-delete-subtask')){
if ($(event.target).hasClass('js-delete-subtask')) {
this.subtaskToDelete = this.currentData().subtask; //Store data context
}
this.toggleDeleteDialog.set(!this.toggleDeleteDialog.get());
},
'click .js-view-subtask'(event) {
if($(event.target).hasClass('js-view-subtask')){
if ($(event.target).hasClass('js-view-subtask')) {
const subtask = this.currentData().subtask;
const board = subtask.board();
FlowRouter.go('card', {
@@ -103,27 +111,33 @@ BlazeComponent.extendComponent({
},
};
return [{
...events,
'submit .js-add-subtask': this.addSubtask,
'submit .js-edit-subtask-title': this.editSubtask,
'click .confirm-subtask-delete': this.deleteSubtask,
keydown: this.pressKey,
}];
return [
{
...events,
'submit .js-add-subtask': this.addSubtask,
'submit .js-edit-subtask-title': this.editSubtask,
'click .confirm-subtask-delete': this.deleteSubtask,
keydown: this.pressKey,
},
];
},
}).register('subtasks');
Template.subtaskDeleteDialog.onCreated(() => {
const $cardDetails = this.$('.card-details');
this.scrollState = { position: $cardDetails.scrollTop(), //save current scroll position
this.scrollState = {
position: $cardDetails.scrollTop(), //save current scroll position
top: false, //required for smooth scroll animation
};
//Callback's purpose is to only prevent scrolling after animation is complete
$cardDetails.animate({ scrollTop: 0 }, 500, () => { this.scrollState.top = true; });
$cardDetails.animate({ scrollTop: 0 }, 500, () => {
this.scrollState.top = true;
});
//Prevent scrolling while dialog is open
$cardDetails.on('scroll', () => {
if(this.scrollState.top) { //If it's already in position, keep it there. Otherwise let animation scroll
if (this.scrollState.top) {
//If it's already in position, keep it there. Otherwise let animation scroll
$cardDetails.scrollTop(0);
}
});
@@ -132,12 +146,16 @@ Template.subtaskDeleteDialog.onCreated(() => {
Template.subtaskDeleteDialog.onDestroyed(() => {
const $cardDetails = this.$('.card-details');
$cardDetails.off('scroll'); //Reactivate scrolling
$cardDetails.animate( { scrollTop: this.scrollState.position });
$cardDetails.animate({ scrollTop: this.scrollState.position });
});
Template.subtaskItemDetail.helpers({
canModifyCard() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
});
+47 -38
View File
@@ -56,7 +56,7 @@ BlazeComponent.extendComponent({
const membersMapping = this.membersToMap.get();
if (membersMapping) {
const mappingById = {};
membersMapping.forEach((member) => {
membersMapping.forEach(member => {
if (member.wekanId) {
mappingById[member.id] = member.wekanId;
}
@@ -64,7 +64,8 @@ BlazeComponent.extendComponent({
additionalData.membersMapping = mappingById;
}
this.membersToMap.set([]);
Meteor.call('importBoard',
Meteor.call(
'importBoard',
this.importedData.get(),
additionalData,
this.importSource,
@@ -76,7 +77,7 @@ BlazeComponent.extendComponent({
Session.set('fromBoard', null);
Utils.goBoardId(res);
}
}
},
);
},
@@ -84,12 +85,12 @@ BlazeComponent.extendComponent({
const importSource = Session.get('importSource');
let membersToMap;
switch (importSource) {
case 'trello':
membersToMap = trelloMembersMapper.getMembersToMap(dataObject);
break;
case 'wekan':
membersToMap = wekanMembersMapper.getMembersToMap(dataObject);
break;
case 'trello':
membersToMap = trelloMembersMapper.getMembersToMap(dataObject);
break;
case 'wekan':
membersToMap = wekanMembersMapper.getMembersToMap(dataObject);
break;
}
return membersToMap;
},
@@ -109,22 +110,26 @@ BlazeComponent.extendComponent({
},
events() {
return [{
submit(evt) {
return this.parentComponent().importData(evt);
return [
{
submit(evt) {
return this.parentComponent().importData(evt);
},
},
}];
];
},
}).register('importTextarea');
BlazeComponent.extendComponent({
onCreated() {
this.autorun(() => {
this.parentComponent().membersToMap.get().forEach(({ wekanId }) => {
if (wekanId) {
this.subscribe('user-miniprofile', wekanId);
}
});
this.parentComponent()
.membersToMap.get()
.forEach(({ wekanId }) => {
if (wekanId) {
this.subscribe('user-miniprofile', wekanId);
}
});
});
},
@@ -149,23 +154,23 @@ BlazeComponent.extendComponent({
_setPropertyForMember(property, value, memberId, unset = false) {
const listOfMembers = this.members();
let finder = null;
if(memberId) {
finder = (member) => member.id === memberId;
if (memberId) {
finder = member => member.id === memberId;
} else {
finder = (member) => member.selected;
finder = member => member.selected;
}
listOfMembers.forEach((member) => {
if(finder(member)) {
if(value !== null) {
listOfMembers.forEach(member => {
if (finder(member)) {
if (value !== null) {
member[property] = value;
} else {
delete member[property];
}
if(!unset) {
if (!unset) {
// we shortcut if we don't care about unsetting the others
return false;
}
} else if(unset) {
} else if (unset) {
delete member[property];
}
return true;
@@ -186,9 +191,9 @@ BlazeComponent.extendComponent({
const allMembers = this.members();
let finder = null;
if (memberId) {
finder = (user) => user.id === memberId;
finder = user => user.id === memberId;
} else {
finder = (user) => user.selected;
finder = user => user.selected;
}
return allMembers.find(finder);
},
@@ -197,7 +202,7 @@ BlazeComponent.extendComponent({
return this._setPropertyForMember('wekanId', wekanId, null);
},
unmapMember(memberId){
unmapMember(memberId) {
return this._setPropertyForMember('wekanId', null, memberId);
},
@@ -208,7 +213,7 @@ BlazeComponent.extendComponent({
onMapMember(evt) {
const memberToMap = this.currentData();
if(memberToMap.wekan) {
if (memberToMap.wekan) {
// todo xxx ask for confirmation?
this.unmapMember(memberToMap.id);
} else {
@@ -218,10 +223,12 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'submit': this.onSubmit,
'click .js-select-member': this.onMapMember,
}];
return [
{
submit: this.onSubmit,
'click .js-select-member': this.onMapMember,
},
];
},
}).register('importMapMembers');
@@ -230,14 +237,16 @@ BlazeComponent.extendComponent({
this.find('.js-map-member input').focus();
},
onSelectUser(){
onSelectUser() {
Popup.getOpenerComponent().mapSelectedMember(this.currentData()._id);
Popup.back();
},
events() {
return [{
'click .js-select-import': this.onSelectUser,
}];
return [
{
'click .js-select-import': this.onSelectUser,
},
];
},
}).register('importMapMembersAddPopup');
@@ -4,7 +4,7 @@ export function getMembersToMap(data) {
// imported member
const membersToMap = data.members;
// auto-map based on username
membersToMap.forEach((importedMember) => {
membersToMap.forEach(importedMember => {
const wekanUser = Users.findOne({ username: importedMember.username });
if (wekanUser) {
importedMember.wekanId = wekanUser._id;
@@ -5,10 +5,10 @@ export function getMembersToMap(data) {
const membersToMap = data.members;
const users = data.users;
// auto-map based on username
membersToMap.forEach((importedMember) => {
membersToMap.forEach(importedMember => {
importedMember.id = importedMember.userId;
delete importedMember.userId;
const user = users.filter((user) => {
const user = users.filter(user => {
return user._id === importedMember.id;
})[0];
if (user.profile && user.profile.fullname) {
+32 -10
View File
@@ -21,14 +21,18 @@ BlazeComponent.extendComponent({
const boardComponent = this.parentComponent().parentComponent();
function userIsMember() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
}
const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)';
const $cards = this.$('.js-minicards');
if(window.matchMedia('(max-width: 1199px)').matches) {
$( '.js-minicards' ).sortable({
if (window.matchMedia('(max-width: 1199px)').matches) {
$('.js-minicards').sortable({
handle: '.handle',
});
}
@@ -42,10 +46,16 @@ BlazeComponent.extendComponent({
if (MultiSelection.isActive()) {
const andNOthers = $cards.find('.js-minicard.is-checked').length - 1;
if (andNOthers > 0) {
helper.append($(Blaze.toHTML(HTML.DIV(
{ 'class': 'and-n-other' },
TAPi18n.__('and-n-other-card', { count: andNOthers })
))));
helper.append(
$(
Blaze.toHTML(
HTML.DIV(
{ class: 'and-n-other' },
TAPi18n.__('and-n-other-card', { count: andNOthers }),
),
),
),
);
}
}
return helper;
@@ -70,9 +80,16 @@ BlazeComponent.extendComponent({
const currentBoard = Boards.findOne(Session.get('currentBoard'));
let swimlaneId = '';
const boardView = (Meteor.user().profile || {}).boardView;
if (boardView === 'board-view-swimlanes' || currentBoard.isTemplatesBoard())
if (
boardView === 'board-view-swimlanes' ||
currentBoard.isTemplatesBoard()
)
swimlaneId = Blaze.getData(ui.item.parents('.swimlane').get(0))._id;
else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal') || !boardView)
else if (
boardView === 'board-view-lists' ||
boardView === 'board-view-cal' ||
!boardView
)
swimlaneId = currentBoard.getDefaultSwimline()._id;
// Normally the jquery-ui sortable library moves the dragged DOM element
@@ -86,7 +103,12 @@ BlazeComponent.extendComponent({
if (MultiSelection.isActive()) {
Cards.find(MultiSelection.getMongoSelector()).forEach((card, i) => {
card.move(currentBoard._id, swimlaneId, listId, sortIndex.base + i * sortIndex.increment);
card.move(
currentBoard._id,
swimlaneId,
listId,
sortIndex.base + i * sortIndex.increment,
);
});
} else {
const cardDomElement = ui.item.get(0);
+317 -229
View File
@@ -16,7 +16,7 @@ BlazeComponent.extendComponent({
options.position = options.position || 'top';
const forms = this.childComponents('inlinedForm');
let form = forms.find((component) => {
let form = forms.find(component => {
return component.data().position === options.position;
});
if (!form && forms.length > 0) {
@@ -52,11 +52,12 @@ BlazeComponent.extendComponent({
let cardType = 'cardType-card';
if (title) {
if (board.isTemplatesBoard()) {
swimlaneId = this.parentComponent().parentComponent().data()._id; // Always swimlanes view
swimlaneId = this.parentComponent()
.parentComponent()
.data()._id; // Always swimlanes view
const swimlane = Swimlanes.findOne(swimlaneId);
// If this is the card templates swimlane, insert a card template
if (swimlane.isCardTemplatesSwimlane())
cardType = 'template-card';
if (swimlane.isCardTemplatesSwimlane()) cardType = 'template-card';
// If this is the board templates swimlane, insert a board template and a linked card
else if (swimlane.isBoardTemplatesSwimlane()) {
linkedId = Boards.insert({
@@ -71,8 +72,14 @@ BlazeComponent.extendComponent({
cardType = 'cardType-linkedBoard';
}
} else if (boardView === 'board-view-swimlanes')
swimlaneId = this.parentComponent().parentComponent().data()._id;
else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal') || !boardView)
swimlaneId = this.parentComponent()
.parentComponent()
.data()._id;
else if (
boardView === 'board-view-lists' ||
boardView === 'board-view-cal' ||
!boardView
)
swimlaneId = board.getDefaultSwimline()._id;
const _id = Cards.insert({
@@ -91,7 +98,9 @@ BlazeComponent.extendComponent({
// if the displayed card count is less than the total cards in the list,
// we need to increment the displayed card count to prevent the spinner
// to appear
const cardCount = this.data().cards(this.idOrNull(swimlaneId)).count();
const cardCount = this.data()
.cards(this.idOrNull(swimlaneId))
.count();
if (this.cardlimit.get() < cardCount) {
this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter);
}
@@ -149,8 +158,12 @@ BlazeComponent.extendComponent({
idOrNull(swimlaneId) {
const currentUser = Meteor.user();
if ((currentUser.profile || {}).boardView === 'board-view-swimlanes' ||
this.data().board().isTemplatesBoard())
if (
(currentUser.profile || {}).boardView === 'board-view-swimlanes' ||
this.data()
.board()
.isTemplatesBoard()
)
return swimlaneId;
return undefined;
},
@@ -161,8 +174,7 @@ BlazeComponent.extendComponent({
listId: this.currentData()._id,
archived: false,
};
if (swimlaneId)
selector.swimlaneId = swimlaneId;
if (swimlaneId) selector.swimlaneId = swimlaneId;
return Cards.find(Filter.mongoSelector(selector), {
sort: ['sort'],
limit,
@@ -175,21 +187,32 @@ BlazeComponent.extendComponent({
},
canSeeAddCard() {
return !this.reachedWipLimit() && Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
!this.reachedWipLimit() &&
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
reachedWipLimit() {
const list = Template.currentData();
return !list.getWipLimit('soft') && list.getWipLimit('enabled') && list.getWipLimit('value') <= list.cards().count();
return (
!list.getWipLimit('soft') &&
list.getWipLimit('enabled') &&
list.getWipLimit('value') <= list.cards().count()
);
},
events() {
return [{
'click .js-minicard': this.clickOnMiniCard,
'click .js-toggle-multi-selection': this.toggleMultiSelection,
'click .open-minicard-composer': this.scrollToBottom,
submit: this.addCard,
}];
return [
{
'click .js-minicard': this.clickOnMiniCard,
'click .js-toggle-multi-selection': this.toggleMultiSelection,
'click .open-minicard-composer': this.scrollToBottom,
submit: this.addCard,
},
];
},
}).register('listBody');
@@ -212,10 +235,15 @@ BlazeComponent.extendComponent({
const currentBoardId = Session.get('currentBoard');
arr = [];
_.forEach(Boards.findOne(currentBoardId).customFields().fetch(), function(field){
if(field.automaticallyOnCard)
arr.push({_id: field._id, value: null});
});
_.forEach(
Boards.findOne(currentBoardId)
.customFields()
.fetch(),
function(field) {
if (field.automaticallyOnCard)
arr.push({ _id: field._id, value: null });
},
);
this.customFields.set(arr);
},
@@ -227,7 +255,7 @@ BlazeComponent.extendComponent({
getLabels() {
const currentBoardId = Session.get('currentBoard');
return Boards.findOne(currentBoardId).labels.filter((label) => {
return Boards.findOne(currentBoardId).labels.filter(label => {
return this.labels.get().indexOf(label._id) > -1;
});
},
@@ -257,18 +285,20 @@ BlazeComponent.extendComponent({
}
BlazeComponent.getComponentForElement(nextList).openForm({
position:this.data().position,
position: this.data().position,
});
}
},
events() {
return [{
keydown: this.pressKey,
'click .js-link': Popup.open('linkCard'),
'click .js-search': Popup.open('searchElement'),
'click .js-card-template': Popup.open('searchElement'),
}];
return [
{
keydown: this.pressKey,
'click .js-link': Popup.open('linkCard'),
'click .js-search': Popup.open('searchElement'),
'click .js-card-template': Popup.open('searchElement'),
},
];
},
onRendered() {
@@ -277,66 +307,75 @@ BlazeComponent.extendComponent({
autosize($textarea);
$textarea.escapeableTextComplete([
// User mentions
{
match: /\B@([\w.]*)$/,
search(term, callback) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
callback($.map(currentBoard.activeMembers(), (member) => {
const user = Users.findOne(member.userId);
return user.username.indexOf(term) === 0 ? user : null;
}));
$textarea.escapeableTextComplete(
[
// User mentions
{
match: /\B@([\w.]*)$/,
search(term, callback) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
callback(
$.map(currentBoard.activeMembers(), member => {
const user = Users.findOne(member.userId);
return user.username.indexOf(term) === 0 ? user : null;
}),
);
},
template(user) {
return user.username;
},
replace(user) {
toggleValueInReactiveArray(editor.members, user._id);
return '';
},
index: 1,
},
template(user) {
return user.username;
},
replace(user) {
toggleValueInReactiveArray(editor.members, user._id);
return '';
},
index: 1,
},
// Labels
// Labels
{
match: /\B#(\w*)$/,
search(term, callback) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
callback(
$.map(currentBoard.labels, label => {
if (
label.name.indexOf(term) > -1 ||
label.color.indexOf(term) > -1
) {
return label;
}
return null;
}),
);
},
template(label) {
return Blaze.toHTMLWithData(Template.autocompleteLabelLine, {
hasNoName: !label.name,
colorName: label.color,
labelName: label.name || label.color,
});
},
replace(label) {
toggleValueInReactiveArray(editor.labels, label._id);
return '';
},
index: 1,
},
],
{
match: /\B#(\w*)$/,
search(term, callback) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
callback($.map(currentBoard.labels, (label) => {
if (label.name.indexOf(term) > -1 ||
label.color.indexOf(term) > -1) {
return label;
}
return null;
}));
// When the autocomplete menu is shown we want both a press of both `Tab`
// or `Enter` to validation the auto-completion. We also need to stop the
// event propagation to prevent the card from submitting (on `Enter`) or
// going on the next column (on `Tab`).
onKeydown(evt, commands) {
if (evt.keyCode === 9 || evt.keyCode === 13) {
evt.stopPropagation();
return commands.KEY_ENTER;
}
return null;
},
template(label) {
return Blaze.toHTMLWithData(Template.autocompleteLabelLine, {
hasNoName: !label.name,
colorName: label.color,
labelName: label.name || label.color,
});
},
replace(label) {
toggleValueInReactiveArray(editor.labels, label._id);
return '';
},
index: 1,
},
], {
// When the autocomplete menu is shown we want both a press of both `Tab`
// or `Enter` to validation the auto-completion. We also need to stop the
// event propagation to prevent the card from submitting (on `Enter`) or
// going on the next column (on `Tab`).
onKeydown(evt, commands) {
if (evt.keyCode === 9 || evt.keyCode === 13) {
evt.stopPropagation();
return commands.KEY_ENTER;
}
return null;
},
});
);
},
}).register('addCardForm');
@@ -354,24 +393,29 @@ BlazeComponent.extendComponent({
const list = $(Popup._getTopStack().openerElement).closest('.js-list');
this.listId = Blaze.getData(list[0])._id;
// Swimlane where to insert card
const swimlane = $(Popup._getTopStack().openerElement).closest('.js-swimlane');
const swimlane = $(Popup._getTopStack().openerElement).closest(
'.js-swimlane',
);
this.swimlaneId = '';
const boardView = (Meteor.user().profile || {}).boardView;
if (boardView === 'board-view-swimlanes')
this.swimlaneId = Blaze.getData(swimlane[0])._id;
else if (boardView === 'board-view-lists' || !boardView)
this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
this.swimlaneId = Swimlanes.findOne({ boardId: this.boardId })._id;
},
boards() {
const boards = Boards.find({
archived: false,
'members.userId': Meteor.userId(),
_id: {$ne: Session.get('currentBoard')},
type: 'board',
}, {
sort: ['title'],
});
const boards = Boards.find(
{
archived: false,
'members.userId': Meteor.userId(),
_id: { $ne: Session.get('currentBoard') },
type: 'board',
},
{
sort: ['title'],
},
);
return boards;
},
@@ -379,7 +423,7 @@ BlazeComponent.extendComponent({
if (!this.selectedBoardId.get()) {
return [];
}
const swimlanes = Swimlanes.find({boardId: this.selectedBoardId.get()});
const swimlanes = Swimlanes.find({ boardId: this.selectedBoardId.get() });
if (swimlanes.count())
this.selectedSwimlaneId.set(swimlanes.fetch()[0]._id);
return swimlanes;
@@ -389,9 +433,8 @@ BlazeComponent.extendComponent({
if (!this.selectedBoardId.get()) {
return [];
}
const lists = Lists.find({boardId: this.selectedBoardId.get()});
if (lists.count())
this.selectedListId.set(lists.fetch()[0]._id);
const lists = Lists.find({ boardId: this.selectedBoardId.get() });
if (lists.count()) this.selectedListId.set(lists.fetch()[0]._id);
return lists;
},
@@ -399,73 +442,84 @@ BlazeComponent.extendComponent({
if (!this.board) {
return [];
}
const ownCardsIds = this.board.cards().map((card) => { return card.linkedId || card._id; });
const ownCardsIds = this.board.cards().map(card => {
return card.linkedId || card._id;
});
return Cards.find({
boardId: this.selectedBoardId.get(),
swimlaneId: this.selectedSwimlaneId.get(),
listId: this.selectedListId.get(),
archived: false,
linkedId: {$nin: ownCardsIds},
_id: {$nin: ownCardsIds},
type: {$nin: ['template-card']},
linkedId: { $nin: ownCardsIds },
_id: { $nin: ownCardsIds },
type: { $nin: ['template-card'] },
});
},
events() {
return [{
'change .js-select-boards'(evt) {
subManager.subscribe('board', $(evt.currentTarget).val(), false);
this.selectedBoardId.set($(evt.currentTarget).val());
},
'change .js-select-swimlanes'(evt) {
this.selectedSwimlaneId.set($(evt.currentTarget).val());
},
'change .js-select-lists'(evt) {
this.selectedListId.set($(evt.currentTarget).val());
},
'click .js-done' (evt) {
// LINK CARD
evt.stopPropagation();
evt.preventDefault();
const linkedId = $('.js-select-cards option:selected').val();
if (!linkedId) {
return [
{
'change .js-select-boards'(evt) {
subManager.subscribe('board', $(evt.currentTarget).val(), false);
this.selectedBoardId.set($(evt.currentTarget).val());
},
'change .js-select-swimlanes'(evt) {
this.selectedSwimlaneId.set($(evt.currentTarget).val());
},
'change .js-select-lists'(evt) {
this.selectedListId.set($(evt.currentTarget).val());
},
'click .js-done'(evt) {
// LINK CARD
evt.stopPropagation();
evt.preventDefault();
const linkedId = $('.js-select-cards option:selected').val();
if (!linkedId) {
Popup.close();
return;
}
const _id = Cards.insert({
title: $('.js-select-cards option:selected').text(), //dummy
listId: this.listId,
swimlaneId: this.swimlaneId,
boardId: this.boardId,
sort: Lists.findOne(this.listId)
.cards()
.count(),
type: 'cardType-linkedCard',
linkedId,
});
Filter.addException(_id);
Popup.close();
return;
}
const _id = Cards.insert({
title: $('.js-select-cards option:selected').text(), //dummy
listId: this.listId,
swimlaneId: this.swimlaneId,
boardId: this.boardId,
sort: Lists.findOne(this.listId).cards().count(),
type: 'cardType-linkedCard',
linkedId,
});
Filter.addException(_id);
Popup.close();
},
'click .js-link-board' (evt) {
//LINK BOARD
evt.stopPropagation();
evt.preventDefault();
const impBoardId = $('.js-select-boards option:selected').val();
if (!impBoardId || Cards.findOne({linkedId: impBoardId, archived: false})) {
},
'click .js-link-board'(evt) {
//LINK BOARD
evt.stopPropagation();
evt.preventDefault();
const impBoardId = $('.js-select-boards option:selected').val();
if (
!impBoardId ||
Cards.findOne({ linkedId: impBoardId, archived: false })
) {
Popup.close();
return;
}
const _id = Cards.insert({
title: $('.js-select-boards option:selected').text(), //dummy
listId: this.listId,
swimlaneId: this.swimlaneId,
boardId: this.boardId,
sort: Lists.findOne(this.listId)
.cards()
.count(),
type: 'cardType-linkedBoard',
linkedId: impBoardId,
});
Filter.addException(_id);
Popup.close();
return;
}
const _id = Cards.insert({
title: $('.js-select-boards option:selected').text(), //dummy
listId: this.listId,
swimlaneId: this.swimlaneId,
boardId: this.boardId,
sort: Lists.findOne(this.listId).cards().count(),
type: 'cardType-linkedBoard',
linkedId: impBoardId,
});
Filter.addException(_id);
Popup.close();
},
},
}];
];
},
}).register('linkCardPopup');
@@ -475,11 +529,20 @@ BlazeComponent.extendComponent({
},
onCreated() {
this.isCardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-card-template');
this.isListTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-list-template');
this.isSwimlaneTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-open-add-swimlane-menu');
this.isBoardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-add-board');
this.isTemplateSearch = this.isCardTemplateSearch ||
this.isCardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass(
'js-card-template',
);
this.isListTemplateSearch = $(Popup._getTopStack().openerElement).hasClass(
'js-list-template',
);
this.isSwimlaneTemplateSearch = $(
Popup._getTopStack().openerElement,
).hasClass('js-open-add-swimlane-menu');
this.isBoardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass(
'js-add-board',
);
this.isTemplateSearch =
this.isCardTemplateSearch ||
this.isListTemplateSearch ||
this.isSwimlaneTemplateSearch ||
this.isBoardTemplateSearch;
@@ -491,7 +554,12 @@ BlazeComponent.extendComponent({
board = Boards.findOne({
archived: false,
'members.userId': Meteor.userId(),
_id: {$nin: [Session.get('currentBoard'), (Meteor.user().profile || {}).templatesBoardId]},
_id: {
$nin: [
Session.get('currentBoard'),
(Meteor.user().profile || {}).templatesBoardId,
],
},
});
}
if (!board) {
@@ -509,11 +577,12 @@ BlazeComponent.extendComponent({
subManager.subscribe('board', this.boardId, false);
this.swimlaneId = '';
// Swimlane where to insert card
const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane');
const swimlane = $(Popup._getTopStack().openerElement).parents(
'.js-swimlane',
);
if ((Meteor.user().profile || {}).boardView === 'board-view-swimlanes')
this.swimlaneId = Blaze.getData(swimlane[0])._id;
else
this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
else this.swimlaneId = Swimlanes.findOne({ boardId: this.boardId })._id;
// List where to insert card
const list = $(Popup._getTopStack().openerElement).closest('.js-list');
this.listId = Blaze.getData(list[0])._id;
@@ -522,14 +591,17 @@ BlazeComponent.extendComponent({
},
boards() {
const boards = Boards.find({
archived: false,
'members.userId': Meteor.userId(),
_id: {$ne: Session.get('currentBoard')},
type: 'board',
}, {
sort: ['title'],
});
const boards = Boards.find(
{
archived: false,
'members.userId': Meteor.userId(),
_id: { $ne: Session.get('currentBoard') },
type: 'board',
},
{
sort: ['title'],
},
);
return boards;
},
@@ -546,7 +618,7 @@ BlazeComponent.extendComponent({
return board.searchSwimlanes(this.term.get());
} else if (this.isBoardTemplateSearch) {
const boards = board.searchBoards(this.term.get());
boards.forEach((board) => {
boards.forEach(board => {
subManager.subscribe('board', board.linkedId, false);
});
return boards;
@@ -556,60 +628,69 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'change .js-select-boards'(evt) {
subManager.subscribe('board', $(evt.currentTarget).val(), false);
this.selectedBoardId.set($(evt.currentTarget).val());
},
'submit .js-search-term-form'(evt) {
evt.preventDefault();
this.term.set(evt.target.searchTerm.value);
},
'click .js-minicard'(evt) {
// 0. Common
const title = $('.js-element-title').val().trim();
if (!title)
return;
const element = Blaze.getData(evt.currentTarget);
element.title = title;
let _id = '';
if (!this.isTemplateSearch || this.isCardTemplateSearch) {
// Card insertion
// 1. Common
element.sort = Lists.findOne(this.listId).cards().count();
// 1.A From template
if (this.isTemplateSearch) {
element.type = 'cardType-card';
element.linkedId = '';
_id = element.copy(this.boardId, this.swimlaneId, this.listId);
// 1.B Linked card
} else {
delete element._id;
element.type = 'cardType-linkedCard';
element.linkedId = element.linkedId || element._id;
_id = Cards.insert(element);
return [
{
'change .js-select-boards'(evt) {
subManager.subscribe('board', $(evt.currentTarget).val(), false);
this.selectedBoardId.set($(evt.currentTarget).val());
},
'submit .js-search-term-form'(evt) {
evt.preventDefault();
this.term.set(evt.target.searchTerm.value);
},
'click .js-minicard'(evt) {
// 0. Common
const title = $('.js-element-title')
.val()
.trim();
if (!title) return;
const element = Blaze.getData(evt.currentTarget);
element.title = title;
let _id = '';
if (!this.isTemplateSearch || this.isCardTemplateSearch) {
// Card insertion
// 1. Common
element.sort = Lists.findOne(this.listId)
.cards()
.count();
// 1.A From template
if (this.isTemplateSearch) {
element.type = 'cardType-card';
element.linkedId = '';
_id = element.copy(this.boardId, this.swimlaneId, this.listId);
// 1.B Linked card
} else {
delete element._id;
element.type = 'cardType-linkedCard';
element.linkedId = element.linkedId || element._id;
_id = Cards.insert(element);
}
Filter.addException(_id);
// List insertion
} else if (this.isListTemplateSearch) {
element.sort = Swimlanes.findOne(this.swimlaneId)
.lists()
.count();
element.type = 'list';
_id = element.copy(this.boardId, this.swimlaneId);
} else if (this.isSwimlaneTemplateSearch) {
element.sort = Boards.findOne(this.boardId)
.swimlanes()
.count();
element.type = 'swimlalne';
_id = element.copy(this.boardId);
} else if (this.isBoardTemplateSearch) {
board = Boards.findOne(element.linkedId);
board.sort = Boards.find({ archived: false }).count();
board.type = 'board';
board.title = element.title;
delete board.slug;
_id = board.copy();
}
Filter.addException(_id);
// List insertion
} else if (this.isListTemplateSearch) {
element.sort = Swimlanes.findOne(this.swimlaneId).lists().count();
element.type = 'list';
_id = element.copy(this.boardId, this.swimlaneId);
} else if (this.isSwimlaneTemplateSearch) {
element.sort = Boards.findOne(this.boardId).swimlanes().count();
element.type = 'swimlalne';
_id = element.copy(this.boardId);
} else if (this.isBoardTemplateSearch) {
board = Boards.findOne(element.linkedId);
board.sort = Boards.find({archived: false}).count();
board.type = 'board';
board.title = element.title;
delete board.slug;
_id = board.copy();
}
Popup.close();
Popup.close();
},
},
}];
];
},
}).register('searchElementPopup');
@@ -622,15 +703,23 @@ BlazeComponent.extendComponent({
const boardView = (Meteor.user().profile || {}).boardView;
if (boardView === 'board-view-swimlanes')
this.swimlaneId = this.parentComponent().parentComponent().parentComponent().data()._id;
this.swimlaneId = this.parentComponent()
.parentComponent()
.parentComponent()
.data()._id;
},
onRendered() {
this.spinner = this.find('.sk-spinner-list');
this.container = this.$(this.spinner).parents('.js-perfect-scrollbar')[0];
$(this.container).on(`scroll.spinner_${this.swimlaneId}_${this.listId}`, () => this.updateList());
$(window).on(`resize.spinner_${this.swimlaneId}_${this.listId}`, () => this.updateList());
$(this.container).on(
`scroll.spinner_${this.swimlaneId}_${this.listId}`,
() => this.updateList(),
);
$(window).on(`resize.spinner_${this.swimlaneId}_${this.listId}`, () =>
this.updateList(),
);
this.updateList();
},
@@ -660,5 +749,4 @@ BlazeComponent.extendComponent({
return bottomViewPosition > threshold;
},
}).register('spinnerList');
+84 -52
View File
@@ -6,12 +6,18 @@ Meteor.startup(() => {
BlazeComponent.extendComponent({
canSeeAddCard() {
const list = Template.currentData();
return !list.getWipLimit('enabled') || list.getWipLimit('soft') || !this.reachedWipLimit();
return (
!list.getWipLimit('enabled') ||
list.getWipLimit('soft') ||
!this.reachedWipLimit()
);
},
editTitle(evt) {
evt.preventDefault();
const newTitle = this.childComponents('inlinedForm')[0].getValue().trim();
editTitle(event) {
event.preventDefault();
const newTitle = this.childComponents('inlinedForm')[0]
.getValue()
.trim();
const list = this.currentData();
if (newTitle) {
list.rename(newTitle.trim());
@@ -32,14 +38,19 @@ BlazeComponent.extendComponent({
let swimlaneId = '';
const boardView = (Meteor.user().profile || {}).boardView;
if (boardView === 'board-view-swimlanes')
swimlaneId = this.parentComponent().parentComponent().data()._id;
swimlaneId = this.parentComponent()
.parentComponent()
.data()._id;
return list.cards(swimlaneId).count();
},
reachedWipLimit() {
const list = Template.currentData();
return list.getWipLimit('enabled') && list.getWipLimit('value') <= list.cards().count();
return (
list.getWipLimit('enabled') &&
list.getWipLimit('value') <= list.cards().count()
);
},
showCardsCountForList(count) {
@@ -48,20 +59,24 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-open-list-menu': Popup.open('listAction'),
'click .js-add-card' (evt) {
const listDom = $(evt.target).parents(`#js-list-${this.currentData()._id}`)[0];
const listComponent = BlazeComponent.getComponentForElement(listDom);
listComponent.openForm({
position: 'top',
});
return [
{
'click .js-open-list-menu': Popup.open('listAction'),
'click .js-add-card'(event) {
const listDom = $(event.target).parents(
`#js-list-${this.currentData()._id}`,
)[0];
const listComponent = BlazeComponent.getComponentForElement(listDom);
listComponent.openForm({
position: 'top',
});
},
'click .js-unselect-list'() {
Session.set('currentList', null);
},
submit: this.editTitle,
},
'click .js-unselect-list'() {
Session.set('currentList', null);
},
submit: this.editTitle,
}];
];
},
}).register('listHeader');
@@ -76,22 +91,22 @@ Template.listActionPopup.helpers({
});
Template.listActionPopup.events({
'click .js-list-subscribe' () {},
'click .js-list-subscribe'() {},
'click .js-set-color-list': Popup.open('setListColor'),
'click .js-select-cards' () {
const cardIds = this.allCards().map((card) => card._id);
'click .js-select-cards'() {
const cardIds = this.allCards().map(card => card._id);
MultiSelection.add(cardIds);
Popup.close();
},
'click .js-toggle-watch-list' () {
'click .js-toggle-watch-list'() {
const currentList = this;
const level = currentList.findWatcher(Meteor.userId()) ? null : 'watching';
Meteor.call('watch', 'list', currentList._id, level, (err, ret) => {
if (!err && ret) Popup.close();
});
},
'click .js-close-list' (evt) {
evt.preventDefault();
'click .js-close-list'(event) {
event.preventDefault();
this.archive();
Popup.close();
},
@@ -102,10 +117,17 @@ Template.listActionPopup.events({
BlazeComponent.extendComponent({
applyWipLimit() {
const list = Template.currentData();
const limit = parseInt(Template.instance().$('.wip-limit-value').val(), 10);
const limit = parseInt(
Template.instance()
.$('.wip-limit-value')
.val(),
10,
);
if(limit < list.cards().count() && !list.getWipLimit('soft')){
Template.instance().$('.wip-limit-error').click();
if (limit < list.cards().count() && !list.getWipLimit('soft')) {
Template.instance()
.$('.wip-limit-error')
.click();
} else {
Meteor.call('applyWipLimit', list._id, limit);
Popup.back();
@@ -115,7 +137,10 @@ BlazeComponent.extendComponent({
enableSoftLimit() {
const list = Template.currentData();
if(list.getWipLimit('soft') && list.getWipLimit('value') < list.cards().count()){
if (
list.getWipLimit('soft') &&
list.getWipLimit('value') < list.cards().count()
) {
list.setWipLimit(list.cards().count());
}
Meteor.call('enableSoftLimit', Template.currentData()._id);
@@ -124,7 +149,10 @@ BlazeComponent.extendComponent({
enableWipLimit() {
const list = Template.currentData();
// Prevent user from using previously stored wipLimit.value if it is less than the current number of cards in the list
if(!list.getWipLimit('enabled') && list.getWipLimit('value') < list.cards().count()){
if (
!list.getWipLimit('enabled') &&
list.getWipLimit('value') < list.cards().count()
) {
list.setWipLimit(list.cards().count());
}
Meteor.call('enableWipLimit', list._id);
@@ -138,24 +166,26 @@ BlazeComponent.extendComponent({
return Template.currentData().getWipLimit('enabled');
},
wipLimitValue(){
wipLimitValue() {
return Template.currentData().getWipLimit('value');
},
events() {
return [{
'click .js-enable-wip-limit': this.enableWipLimit,
'click .wip-limit-apply': this.applyWipLimit,
'click .wip-limit-error': Popup.open('wipLimitError'),
'click .materialCheckBox': this.enableSoftLimit,
}];
return [
{
'click .js-enable-wip-limit': this.enableWipLimit,
'click .wip-limit-apply': this.applyWipLimit,
'click .wip-limit-error': Popup.open('wipLimitError'),
'click .materialCheckBox': this.enableSoftLimit,
},
];
},
}).register('setWipLimitPopup');
Template.listMorePopup.events({
'click .js-delete': Popup.afterConfirm('listDelete', function () {
'click .js-delete': Popup.afterConfirm('listDelete', function() {
Popup.close();
this.allCards().map((card) => Cards.remove(card._id));
this.allCards().map(card => Cards.remove(card._id));
Lists.remove(this._id);
Utils.goBoardId(this.boardId);
}),
@@ -168,7 +198,7 @@ BlazeComponent.extendComponent({
},
colors() {
return listsColors.map((color) => ({ color, name: '' }));
return listsColors.map(color => ({ color, name: '' }));
},
isSelected(color) {
@@ -176,18 +206,20 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
return [
{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
'click .js-submit'() {
this.currentList.setColor(this.currentColor.get());
Popup.close();
},
'click .js-remove-color'() {
this.currentList.setColor(null);
Popup.close();
},
},
'click .js-submit' () {
this.currentList.setColor(this.currentColor.get());
Popup.close();
},
'click .js-remove-color'() {
this.currentList.setColor(null);
Popup.close();
},
}];
];
},
}).register('setListColorPopup');
+63 -54
View File
@@ -9,10 +9,15 @@ Template.editor.onRendered(() => {
match: /\B@([\w.]*)$/,
search(term, callback) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
callback(currentBoard.activeMembers().map((member) => {
const username = Users.findOne(member.userId).username;
return username.includes(term) ? username : null;
}).filter(Boolean));
callback(
currentBoard
.activeMembers()
.map(member => {
const username = Users.findOne(member.userId).username;
return username.includes(term) ? username : null;
})
.filter(Boolean),
);
},
template(value) {
return value;
@@ -33,69 +38,73 @@ import sanitizeXss from 'xss';
// compiled version to most users -- who don't need to edit.
// In the meantime, all the transformation are done on the client using the
// Blaze API.
const at = HTML.CharRef({html: '&commat;', str: '@'});
Blaze.Template.registerHelper('mentions', new Template('mentions', function() {
const view = this;
let content = Blaze.toHTML(view.templateContentBlock);
const currentBoard = Boards.findOne(Session.get('currentBoard'));
if (!currentBoard)
const at = HTML.CharRef({ html: '&commat;', str: '@' });
Blaze.Template.registerHelper(
'mentions',
new Template('mentions', function() {
const view = this;
let content = Blaze.toHTML(view.templateContentBlock);
const currentBoard = Boards.findOne(Session.get('currentBoard'));
if (!currentBoard) return HTML.Raw(sanitizeXss(content));
const knowedUsers = currentBoard.members.map(member => {
const u = Users.findOne(member.userId);
if (u) {
member.username = u.username;
}
return member;
});
const mentionRegex = /\B@([\w.]*)/gi;
let currentMention;
while ((currentMention = mentionRegex.exec(content)) !== null) {
const [fullMention, username] = currentMention;
const knowedUser = _.findWhere(knowedUsers, { username });
if (!knowedUser) {
continue;
}
const linkValue = [' ', at, knowedUser.username];
let linkClass = 'atMention js-open-member';
if (knowedUser.userId === Meteor.userId()) {
linkClass += ' me';
}
const link = HTML.A(
{
class: linkClass,
// XXX Hack. Since we stringify this render function result below with
// `Blaze.toHTML` we can't rely on blaze data contexts to pass the
// `userId` to the popup as usual, and we need to store it in the DOM
// using a data attribute.
'data-userId': knowedUser.userId,
},
linkValue,
);
content = content.replace(fullMention, Blaze.toHTML(link));
}
return HTML.Raw(sanitizeXss(content));
const knowedUsers = currentBoard.members.map((member) => {
const u = Users.findOne(member.userId);
if(u){
member.username = u.username;
}
return member;
});
const mentionRegex = /\B@([\w.]*)/gi;
let currentMention;
while ((currentMention = mentionRegex.exec(content)) !== null) {
const [fullMention, username] = currentMention;
const knowedUser = _.findWhere(knowedUsers, { username });
if (!knowedUser) {
continue;
}
const linkValue = [' ', at, knowedUser.username];
let linkClass = 'atMention js-open-member';
if (knowedUser.userId === Meteor.userId()) {
linkClass += ' me';
}
const link = HTML.A({
'class': linkClass,
// XXX Hack. Since we stringify this render function result below with
// `Blaze.toHTML` we can't rely on blaze data contexts to pass the
// `userId` to the popup as usual, and we need to store it in the DOM
// using a data attribute.
'data-userId': knowedUser.userId,
}, linkValue);
content = content.replace(fullMention, Blaze.toHTML(link));
}
return HTML.Raw(sanitizeXss(content));
}));
}),
);
Template.viewer.events({
// Viewer sometimes have click-able wrapper around them (for instance to edit
// the corresponding text). Clicking a link shouldn't fire these actions, stop
// we stop these event at the viewer component level.
'click a'(evt, tpl) {
evt.stopPropagation();
'click a'(event, templateInstance) {
event.stopPropagation();
// XXX We hijack the build-in browser action because we currently don't have
// `_blank` attributes in viewer links, and the transformer function is
// handled by a third party package that we can't configure easily. Fix that
// by using directly `_blank` attribute in the rendered HTML.
evt.preventDefault();
event.preventDefault();
const userId = evt.currentTarget.dataset.userid;
const userId = event.currentTarget.dataset.userid;
if (userId) {
Popup.open('member').call({ userId }, evt, tpl);
}
else {
const href = evt.currentTarget.href;
Popup.open('member').call({ userId }, event, templateInstance);
} else {
const href = event.currentTarget.href;
if (href) {
window.open(href, '_blank');
}
+2 -2
View File
@@ -20,13 +20,13 @@ Template.header.helpers({
},
hasAnnouncement() {
const announcements = Announcements.findOne();
const announcements = Announcements.findOne();
return announcements && announcements.enabled;
},
announcement() {
$('.announcement').show();
const announcements = Announcements.findOne();
const announcements = Announcements.findOne();
return announcements && announcements.body;
},
});
+40 -32
View File
@@ -1,6 +1,6 @@
BlazeLayout.setRoot('body');
const i18nTagToT9n = (i18nTag) => {
const i18nTagToT9n = i18nTag => {
// t9n/i18n tags are same now, see: https://github.com/softwarerero/meteor-accounts-t9n/pull/129
// but we keep this conversion function here, to be aware that that they are different system.
return i18nTag;
@@ -21,20 +21,23 @@ const validator = {
};
Template.userFormsLayout.onCreated(function() {
const instance = this;
instance.currentSetting = new ReactiveVar();
instance.isLoading = new ReactiveVar(false);
const templateInstance = this;
templateInstance.currentSetting = new ReactiveVar();
templateInstance.isLoading = new ReactiveVar(false);
Meteor.subscribe('setting', {
onReady() {
instance.currentSetting.set(Settings.findOne());
templateInstance.currentSetting.set(Settings.findOne());
return this.stop();
},
});
});
Template.userFormsLayout.onRendered(() => {
AccountsTemplates.state.form.keys = new Proxy(AccountsTemplates.state.form.keys, validator);
AccountsTemplates.state.form.keys = new Proxy(
AccountsTemplates.state.form.keys,
validator,
);
const i18nTag = navigator.language;
if (i18nTag) {
@@ -89,18 +92,17 @@ Template.userFormsLayout.helpers({
});
Template.userFormsLayout.events({
'change .js-userform-set-language'(evt) {
const i18nTag = $(evt.currentTarget).val();
'change .js-userform-set-language'(event) {
const i18nTag = $(event.currentTarget).val();
T9n.setLanguage(i18nTagToT9n(i18nTag));
evt.preventDefault();
event.preventDefault();
},
'click #at-btn'(event, instance) {
'click #at-btn'(event, templateInstance) {
if (FlowRouter.getRouteName() === 'atSignIn') {
instance.isLoading.set(true);
authentication(event, instance)
.then(() => {
instance.isLoading.set(false);
});
templateInstance.isLoading.set(true);
authentication(event, templateInstance).then(() => {
templateInstance.isLoading.set(false);
});
}
},
});
@@ -111,13 +113,16 @@ Template.defaultLayout.events({
},
});
async function authentication(event, instance) {
async function authentication(event, templateInstance) {
const match = $('#at-field-username_and_email').val();
const password = $('#at-field-password').val();
if (!match || !password) return undefined;
const result = await getAuthenticationMethod(instance.currentSetting.get(), match);
const result = await getAuthenticationMethod(
templateInstance.currentSetting.get(),
match,
);
if (result === 'password') return undefined;
@@ -126,26 +131,29 @@ async function authentication(event, instance) {
event.stopImmediatePropagation();
switch (result) {
case 'ldap':
return new Promise((resolve) => {
Meteor.loginWithLDAP(match, password, function() {
resolve(FlowRouter.go('/'));
case 'ldap':
return new Promise(resolve => {
Meteor.loginWithLDAP(match, password, function() {
resolve(FlowRouter.go('/'));
});
});
});
case 'cas':
return new Promise((resolve) => {
Meteor.loginWithCas(match, password, function() {
resolve(FlowRouter.go('/'));
case 'cas':
return new Promise(resolve => {
Meteor.loginWithCas(match, password, function() {
resolve(FlowRouter.go('/'));
});
});
});
default:
return undefined;
default:
return undefined;
}
}
function getAuthenticationMethod({displayAuthenticationMethod, defaultAuthenticationMethod}, match) {
function getAuthenticationMethod(
{ displayAuthenticationMethod, defaultAuthenticationMethod },
match,
) {
if (displayAuthenticationMethod) {
return $('.select-authentication').val();
}
@@ -153,7 +161,7 @@ function getAuthenticationMethod({displayAuthenticationMethod, defaultAuthentica
}
function getUserAuthenticationMethod(defaultAuthenticationMethod, match) {
return new Promise((resolve) => {
return new Promise(resolve => {
try {
Meteor.subscribe('user-authenticationMethod', match, {
onReady() {
@@ -166,7 +174,7 @@ function getUserAuthenticationMethod(defaultAuthenticationMethod, match) {
resolve(authenticationMethod);
},
});
} catch(error) {
} catch (error) {
resolve(defaultAuthenticationMethod);
}
});
+11 -9
View File
@@ -18,15 +18,17 @@ Mixins.InfiniteScrolling = BlazeComponent.extendComponent({
},
events() {
return [{
scroll(evt) {
const domElement = evt.currentTarget;
let altitude = domElement.scrollTop + domElement.offsetHeight;
altitude += peakAnticipation;
if (altitude >= this.callFirstWith(null, 'getNextPeak')) {
this.mixinParent().callFirstWith(null, 'reachNextPeak');
}
return [
{
scroll(evt) {
const domElement = evt.currentTarget;
let altitude = domElement.scrollTop + domElement.offsetHeight;
altitude += peakAnticipation;
if (altitude >= this.callFirstWith(null, 'getNextPeak')) {
this.mixinParent().callFirstWith(null, 'reachNextPeak');
}
},
},
}];
];
},
});
+158 -161
View File
@@ -1,168 +1,165 @@
BlazeComponent.extendComponent({
onCreated() {
},
onCreated() {},
events() {
return [{
'click .js-create-card-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const cardName = this.find('#card-name').value;
const listName = this.find('#list-name').value;
const swimlaneName = this.find('#swimlane-name2').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'createCard',
swimlaneName,
cardName,
listName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
return [
{
'click .js-create-card-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const cardName = this.find('#card-name').value;
const listName = this.find('#list-name').value;
const swimlaneName = this.find('#swimlane-name2').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'createCard',
swimlaneName,
cardName,
listName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
'click .js-add-swimlane-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const swimlaneName = this.find('#swimlane-name').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addSwimlane',
swimlaneName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
'click .js-add-spec-move-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#move-spec-action').value;
const listTitle = this.find('#listName').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'top') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'moveCardToTop',
listTitle,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'bottom') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'moveCardToBottom',
listTitle,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-gen-move-action'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const boardId = Session.get('currentBoard');
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#move-gen-action').value;
if (actionSelected === 'top') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'moveCardToTop',
listTitle: '*',
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'bottom') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'moveCardToBottom',
listTitle: '*',
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-arch-action'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const boardId = Session.get('currentBoard');
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#arch-action').value;
if (actionSelected === 'archive') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'archive',
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'unarchive') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'unarchive',
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
},
'click .js-add-swimlane-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const swimlaneName = this.find('#swimlane-name').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addSwimlane',
swimlaneName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
'click .js-add-spec-move-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#move-spec-action').value;
const listTitle = this.find('#listName').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'top') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'moveCardToTop',
listTitle,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'bottom') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'moveCardToBottom',
listTitle,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-gen-move-action' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const boardId = Session.get('currentBoard');
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#move-gen-action').value;
if (actionSelected === 'top') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'moveCardToTop',
'listTitle': '*',
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'bottom') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'moveCardToBottom',
'listTitle': '*',
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-arch-action' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const boardId = Session.get('currentBoard');
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#arch-action').value;
if (actionSelected === 'archive') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'archive',
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'unarchive') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'unarchive',
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
}];
];
},
}).register('boardActions');
/* eslint-no-undef */
@@ -1,11 +1,44 @@
template(name="cardActions")
div.trigger-item
div.trigger-content
div.trigger-dropdown
select(id="setdate-action")
option(value="setDate") {{{_'r-set'}}}
option(value="updateDate") {{{_'r-update'}}}
div.trigger-text
| {{{_'r-datefield'}}}
div.trigger-dropdown
select(id="setdate-datefield")
option(value="startAt") {{{_'r-df-start-at'}}}
option(value="dueAt") {{{_'r-df-due-at'}}}
option(value="endAt") {{{_'r-df-end-at'}}}
option(value="receivedAt") {{{_'r-df-received-at'}}}
div.trigger-text
| {{{_'r-to-current-datetime'}}}
div.trigger-button.js-set-date-action.js-goto-rules
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
| {{{_'r-remove-value-from'}}}
| {{{_'r-datefield'}}}
div.trigger-dropdown
select(id="setdate-removedatefieldvalue")
option(value="startAt") {{{_'r-df-start-at'}}}
option(value="dueAt") {{{_'r-df-due-at'}}}
option(value="endAt") {{{_'r-df-end-at'}}}
option(value="receivedAt") {{{_'r-df-received-at'}}}
div.trigger-button.js-remove-datevalue-action.js-goto-rules
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-dropdown
select(id="label-action")
option(value="add") {{{_'r-add'}}}
option(value="remove") {{{_'r-remove'}}}
div.trigger-text
div.trigger-text
| {{{_'r-label'}}}
div.trigger-dropdown
select(id="label-id")
@@ -21,16 +54,16 @@ template(name="cardActions")
select(id="member-action")
option(value="add") {{{_'r-add'}}}
option(value="remove") {{{_'r-remove'}}}
div.trigger-text
div.trigger-text
| {{{_'r-member'}}}
div.trigger-dropdown
input(id="member-name",type=text,placeholder="{{{_'r-name'}}}")
input(id="member-name",type=text,placeholder="{{{_'r-name'}}}")
div.trigger-button.js-add-member-action.js-goto-rules
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
div.trigger-text
| {{{_'r-remove-all'}}}
div.trigger-button.js-add-removeall-action.js-goto-rules
i.fa.fa-plus
+163 -112
View File
@@ -14,7 +14,7 @@ BlazeComponent.extendComponent({
},
cardColorButtonText() {
return `color-${ this.cardColorButtonValue.get() }`;
return `color-${this.cardColorButtonValue.get()}`;
},
labels() {
@@ -28,61 +28,24 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-add-label-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#label-action').value;
const labelId = this.find('#label-id').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'add') {
return [
{
'click .js-set-date-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addLabel',
labelId,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'remove') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'removeLabel',
labelId,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
const actionSelected = this.find('#setdate-action').value;
const dateFieldSelected = this.find('#setdate-datefield').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
},
'click .js-add-member-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#member-action').value;
const username = this.find('#member-name').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'add') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addMember',
username,
actionType: actionSelected,
dateField: dateFieldSelected,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
@@ -90,12 +53,118 @@ BlazeComponent.extendComponent({
boardId,
desc,
});
}
if (actionSelected === 'remove') {
},
'click .js-remove-datevalue-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const triggerId = Triggers.insert(trigger);
const dateFieldSelected = this.find('#setdate-removedatefieldvalue')
.value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const actionId = Actions.insert({
actionType: 'removeDate',
dateField: dateFieldSelected,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
desc,
});
},
'click .js-add-label-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#label-action').value;
const labelId = this.find('#label-id').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'add') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addLabel',
labelId,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'remove') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'removeLabel',
labelId,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-member-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#member-action').value;
const username = this.find('#member-name').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'add') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addMember',
username,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
desc,
});
}
if (actionSelected === 'remove') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'removeMember',
username,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-removeall-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const triggerId = Triggers.insert(trigger);
const desc = Utils.getTriggerActionDesc(event, this);
const boardId = Session.get('currentBoard');
const actionId = Actions.insert({
actionType: 'removeMember',
username,
username: '*',
boardId,
desc,
});
@@ -105,58 +174,38 @@ BlazeComponent.extendComponent({
actionId,
boardId,
});
}
},
'click .js-show-color-palette'(event) {
const funct = Popup.open('setCardActionsColor');
const colorButton = this.find('#color-action');
if (colorButton.value === '') {
colorButton.value = 'green';
}
funct.call(this, event);
},
'click .js-set-color-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const selectedColor = this.cardColorButtonValue.get();
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'setColor',
selectedColor,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
},
'click .js-add-removeall-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const triggerId = Triggers.insert(trigger);
const desc = Utils.getTriggerActionDesc(event, this);
const boardId = Session.get('currentBoard');
const actionId = Actions.insert({
actionType: 'removeMember',
'username': '*',
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
'click .js-show-color-palette'(event){
const funct = Popup.open('setCardActionsColor');
const colorButton = this.find('#color-action');
if (colorButton.value === '') {
colorButton.value = 'green';
}
funct.call(this, event);
},
'click .js-set-color-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const selectedColor = this.cardColorButtonValue.get();
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'setColor',
selectedColor,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
}];
];
},
}).register('cardActions');
BlazeComponent.extendComponent({
@@ -167,7 +216,7 @@ BlazeComponent.extendComponent({
},
colors() {
return cardColors.map((color) => ({ color, name: '' }));
return cardColors.map(color => ({ color, name: '' }));
},
isSelected(color) {
@@ -175,14 +224,16 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
return [
{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
'click .js-submit'() {
this.colorButtonValue.set(this.currentColor.get());
Popup.close();
},
},
'click .js-submit' () {
this.colorButtonValue.set(this.currentColor.get());
Popup.close();
},
}];
];
},
}).register('setCardActionsColorPopup');
@@ -3,149 +3,148 @@ BlazeComponent.extendComponent({
this.subscribe('allRules');
},
events() {
return [{
'click .js-add-checklist-items-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const checklistName = this.find('#checklist-name-3').value;
const checklistItems = this.find('#checklist-items').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addChecklistWithItems',
checklistName,
checklistItems,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
return [
{
'click .js-add-checklist-items-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const checklistName = this.find('#checklist-name-3').value;
const checklistItems = this.find('#checklist-items').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addChecklistWithItems',
checklistName,
checklistItems,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
'click .js-add-checklist-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#check-action').value;
const checklistName = this.find('#checklist-name').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'add') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addChecklist',
checklistName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'remove') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'removeChecklist',
checklistName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-checkall-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#checkall-action').value;
const checklistName = this.find('#checklist-name2').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'check') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'checkAll',
checklistName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'uncheck') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'uncheckAll',
checklistName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-check-item-action'(event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const checkItemName = this.find('#checkitem-name');
const checklistName = this.find('#checklist-name3');
const actionSelected = this.find('#check-item-action').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'check') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'checkItem',
checklistName,
checkItemName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'uncheck') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'uncheckItem',
checklistName,
checkItemName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
},
'click .js-add-checklist-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#check-action').value;
const checklistName = this.find('#checklist-name').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'add') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addChecklist',
checklistName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'remove') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'removeChecklist',
checklistName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-checkall-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const actionSelected = this.find('#checkall-action').value;
const checklistName = this.find('#checklist-name2').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'check') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'checkAll',
checklistName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'uncheck') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'uncheckAll',
checklistName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
'click .js-add-check-item-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const checkItemName = this.find('#checkitem-name');
const checklistName = this.find('#checklist-name3');
const actionSelected = this.find('#check-item-action').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
if (actionSelected === 'check') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'checkItem',
checklistName,
checkItemName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
if (actionSelected === 'uncheck') {
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'uncheckItem',
checklistName,
checkItemName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
}
},
}];
];
},
}).register('checklistActions');
+28 -29
View File
@@ -1,35 +1,34 @@
BlazeComponent.extendComponent({
onCreated() {
},
onCreated() {},
events() {
return [{
'click .js-mail-action' (event) {
const emailTo = this.find('#email-to').value;
const emailSubject = this.find('#email-subject').value;
const emailMsg = this.find('#email-msg').value;
const trigger = this.data().triggerVar.get();
const ruleName = this.data().ruleName.get();
const triggerId = Triggers.insert(trigger);
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const actionId = Actions.insert({
actionType: 'sendEmail',
emailTo,
emailSubject,
emailMsg,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
return [
{
'click .js-mail-action'(event) {
const emailTo = this.find('#email-to').value;
const emailSubject = this.find('#email-subject').value;
const emailMsg = this.find('#email-msg').value;
const trigger = this.data().triggerVar.get();
const ruleName = this.data().ruleName.get();
const triggerId = Triggers.insert(trigger);
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const actionId = Actions.insert({
actionType: 'sendEmail',
emailTo,
emailSubject,
emailMsg,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
},
}];
];
},
}).register('mailActions');
-2
View File
@@ -3,7 +3,6 @@ BlazeComponent.extendComponent({
this.subscribe('allRules');
this.subscribe('allTriggers');
this.subscribe('allActions');
},
trigger() {
@@ -34,5 +33,4 @@ BlazeComponent.extendComponent({
events() {
return [{}];
},
}).register('ruleDetails');
+15 -13
View File
@@ -40,19 +40,21 @@ BlazeComponent.extendComponent({
// console.log(this.data());
},
events() {
return [{
'click .js-set-board-actions'(){
this.setBoardActions();
return [
{
'click .js-set-board-actions'() {
this.setBoardActions();
},
'click .js-set-card-actions'() {
this.setCardActions();
},
'click .js-set-mail-actions'() {
this.setMailActions();
},
'click .js-set-checklist-actions'() {
this.setChecklistActions();
},
},
'click .js-set-card-actions'() {
this.setCardActions();
},
'click .js-set-mail-actions'() {
this.setMailActions();
},
'click .js-set-checklist-actions'() {
this.setChecklistActions();
},
}];
];
},
}).register('rulesActions');
+11 -1
View File
@@ -17,6 +17,10 @@ template(name="rulesList")
button.js-delete-rule
i.fa.fa-trash-o
| {{{_ 'r-delete-rule'}}}
else if currentUser.isBoardAdmin
button.js-delete-rule
i.fa.fa-trash-o
| {{{_ 'r-delete-rule'}}}
else
li.no-items-message {{{_ 'r-no-rules' }}}
if currentUser.isAdmin
@@ -24,4 +28,10 @@ template(name="rulesList")
button.js-goto-trigger
i.fa.fa-plus
| {{{_ 'r-add-rule'}}}
input(type=text,placeholder="{{{_ 'r-new-rule-name' }}}",id="ruleTitle")
input(type=text,placeholder="{{{_ 'r-new-rule-name' }}}",id="ruleTitle")
else if currentUser.isBoardAdmin
div.rules-add
button.js-goto-trigger
i.fa.fa-plus
| {{{_ 'r-add-rule'}}}
input(type=text,placeholder="{{{_ 'r-new-rule-name' }}}",id="ruleTitle")
+70 -66
View File
@@ -9,12 +9,12 @@ BlazeComponent.extendComponent({
setTrigger() {
this.rulesCurrentTab.set('trigger');
},
sanitizeObject(obj){
Object.keys(obj).forEach((key) => {
if(obj[key] === '' || obj[key] === undefined){
sanitizeObject(obj) {
Object.keys(obj).forEach(key => {
if (obj[key] === '' || obj[key] === undefined) {
obj[key] = '*';
}}
);
}
});
},
setRulesList() {
this.rulesCurrentTab.set('rulesList');
@@ -29,69 +29,73 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-delete-rule' () {
const rule = this.currentData();
Rules.remove(rule._id);
Actions.remove(rule.actionId);
Triggers.remove(rule.triggerId);
},
'click .js-goto-trigger' (event) {
event.preventDefault();
const ruleTitle = this.find('#ruleTitle').value;
if(ruleTitle !== undefined && ruleTitle !== ''){
this.find('#ruleTitle').value = '';
this.ruleName.set(ruleTitle);
this.setTrigger();
}
},
'click .js-goto-action' (event) {
event.preventDefault();
// Add user to the trigger
const username = $(event.currentTarget.offsetParent).find('.user-name').val();
let trigger = this.triggerVar.get();
trigger.userId = '*';
if(username !== undefined ){
const userFound = Users.findOne({username});
if(userFound !== undefined){
trigger.userId = userFound._id;
this.triggerVar.set(trigger);
return [
{
'click .js-delete-rule'() {
const rule = this.currentData();
Rules.remove(rule._id);
Actions.remove(rule.actionId);
Triggers.remove(rule.triggerId);
},
'click .js-goto-trigger'(event) {
event.preventDefault();
const ruleTitle = this.find('#ruleTitle').value;
if (ruleTitle !== undefined && ruleTitle !== '') {
this.find('#ruleTitle').value = '';
this.ruleName.set(ruleTitle);
this.setTrigger();
}
}
// Sanitize trigger
trigger = this.triggerVar.get();
this.sanitizeObject(trigger);
this.triggerVar.set(trigger);
this.setAction();
},
'click .js-show-user-field' (event) {
event.preventDefault();
$(event.currentTarget.offsetParent).find('.user-details').removeClass('hide-element');
},
'click .js-goto-rules' (event) {
event.preventDefault();
this.setRulesList();
},
'click .js-goback' (event) {
event.preventDefault();
if(this.rulesCurrentTab.get() === 'trigger' || this.rulesCurrentTab.get() === 'ruleDetails' ){
},
'click .js-goto-action'(event) {
event.preventDefault();
// Add user to the trigger
const username = $(event.currentTarget.offsetParent)
.find('.user-name')
.val();
let trigger = this.triggerVar.get();
trigger.userId = '*';
if (username !== undefined) {
const userFound = Users.findOne({ username });
if (userFound !== undefined) {
trigger.userId = userFound._id;
this.triggerVar.set(trigger);
}
}
// Sanitize trigger
trigger = this.triggerVar.get();
this.sanitizeObject(trigger);
this.triggerVar.set(trigger);
this.setAction();
},
'click .js-show-user-field'(event) {
event.preventDefault();
$(event.currentTarget.offsetParent)
.find('.user-details')
.removeClass('hide-element');
},
'click .js-goto-rules'(event) {
event.preventDefault();
this.setRulesList();
}
if(this.rulesCurrentTab.get() === 'action'){
this.setTrigger();
}
},
'click .js-goback'(event) {
event.preventDefault();
if (
this.rulesCurrentTab.get() === 'trigger' ||
this.rulesCurrentTab.get() === 'ruleDetails'
) {
this.setRulesList();
}
if (this.rulesCurrentTab.get() === 'action') {
this.setTrigger();
}
},
'click .js-goto-details'(event) {
event.preventDefault();
const rule = this.currentData();
this.ruleId.set(rule._id);
this.setRuleDetails();
},
},
'click .js-goto-details' (event) {
event.preventDefault();
const rule = this.currentData();
this.ruleId.set(rule._id);
this.setRuleDetails();
},
}];
];
},
}).register('rulesMain');
+12 -10
View File
@@ -38,16 +38,18 @@ BlazeComponent.extendComponent({
// console.log(this.data());
},
events() {
return [{
'click .js-set-board-triggers' () {
this.setBoardTriggers();
return [
{
'click .js-set-board-triggers'() {
this.setBoardTriggers();
},
'click .js-set-card-triggers'() {
this.setCardTriggers();
},
'click .js-set-checklist-triggers'() {
this.setChecklistTriggers();
},
},
'click .js-set-card-triggers' () {
this.setCardTriggers();
},
'click .js-set-checklist-triggers' () {
this.setChecklistTriggers();
},
}];
];
},
}).register('rulesTriggers');
@@ -4,116 +4,118 @@ BlazeComponent.extendComponent({
this.currentPopupTriggerId = 'def';
this.cardTitleFilters = {};
},
setNameFilter(name){
this.cardTitleFilters[this.currentPopupTriggerId] = name;
setNameFilter(name) {
this.cardTitleFilters[this.currentPopupTriggerId] = name;
},
events() {
return [{
'click .js-open-card-title-popup'(event){
const funct = Popup.open('boardCardTitle');
const divId = $(event.currentTarget.parentNode.parentNode).attr('id');
//console.log('current popup');
//console.log(this.currentPopupTriggerId);
this.currentPopupTriggerId = divId;
funct.call(this, event);
},
'click .js-add-create-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const listName = this.find('#create-list-name').value;
const swimlaneName = this.find('#create-swimlane-name').value;
const boardId = Session.get('currentBoard');
const divId = $(event.currentTarget.parentNode).attr('id');
const cardTitle = this.cardTitleFilters[divId];
// move to generic funciont
datas.triggerVar.set({
activityType: 'createCard',
boardId,
cardTitle,
swimlaneName,
listName,
desc,
});
},
'click .js-add-moved-trigger' (event) {
const datas = this.data();
const desc = Utils.getTriggerActionDesc(event, this);
const swimlaneName = this.find('#create-swimlane-name-2').value;
const actionSelected = this.find('#move-action').value;
const listName = this.find('#move-list-name').value;
const boardId = Session.get('currentBoard');
const divId = $(event.currentTarget.parentNode).attr('id');
const cardTitle = this.cardTitleFilters[divId];
if (actionSelected === 'moved-to') {
return [
{
'click .js-open-card-title-popup'(event) {
const funct = Popup.open('boardCardTitle');
const divId = $(event.currentTarget.parentNode.parentNode).attr('id');
//console.log('current popup');
//console.log(this.currentPopupTriggerId);
this.currentPopupTriggerId = divId;
funct.call(this, event);
},
'click .js-add-create-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const listName = this.find('#create-list-name').value;
const swimlaneName = this.find('#create-swimlane-name').value;
const boardId = Session.get('currentBoard');
const divId = $(event.currentTarget.parentNode).attr('id');
const cardTitle = this.cardTitleFilters[divId];
// move to generic funciont
datas.triggerVar.set({
activityType: 'moveCard',
activityType: 'createCard',
boardId,
cardTitle,
swimlaneName,
listName,
cardTitle,
swimlaneName,
'oldListName': '*',
desc,
});
}
if (actionSelected === 'moved-from') {
},
'click .js-add-moved-trigger'(event) {
const datas = this.data();
const desc = Utils.getTriggerActionDesc(event, this);
const swimlaneName = this.find('#create-swimlane-name-2').value;
const actionSelected = this.find('#move-action').value;
const listName = this.find('#move-list-name').value;
const boardId = Session.get('currentBoard');
const divId = $(event.currentTarget.parentNode).attr('id');
const cardTitle = this.cardTitleFilters[divId];
if (actionSelected === 'moved-to') {
datas.triggerVar.set({
activityType: 'moveCard',
boardId,
listName,
cardTitle,
swimlaneName,
oldListName: '*',
desc,
});
}
if (actionSelected === 'moved-from') {
datas.triggerVar.set({
activityType: 'moveCard',
boardId,
cardTitle,
swimlaneName,
listName: '*',
oldListName: listName,
desc,
});
}
},
'click .js-add-gen-moved-trigger'(event) {
const datas = this.data();
const desc = Utils.getTriggerActionDesc(event, this);
const boardId = Session.get('currentBoard');
datas.triggerVar.set({
activityType: 'moveCard',
boardId,
cardTitle,
swimlaneName,
'listName': '*',
'oldListName': listName,
swimlaneName: '*',
listName: '*',
oldListName: '*',
desc,
});
}
},
'click .js-add-arc-trigger'(event) {
const datas = this.data();
const desc = Utils.getTriggerActionDesc(event, this);
const actionSelected = this.find('#arch-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'archived') {
datas.triggerVar.set({
activityType: 'archivedCard',
boardId,
desc,
});
}
if (actionSelected === 'unarchived') {
datas.triggerVar.set({
activityType: 'restoredCard',
boardId,
desc,
});
}
},
},
'click .js-add-gen-moved-trigger' (event){
const datas = this.data();
const desc = Utils.getTriggerActionDesc(event, this);
const boardId = Session.get('currentBoard');
datas.triggerVar.set({
'activityType': 'moveCard',
boardId,
'swimlaneName': '*',
'listName':'*',
'oldListName': '*',
desc,
});
},
'click .js-add-arc-trigger' (event) {
const datas = this.data();
const desc = Utils.getTriggerActionDesc(event, this);
const actionSelected = this.find('#arch-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'archived') {
datas.triggerVar.set({
activityType: 'archivedCard',
boardId,
desc,
});
}
if (actionSelected === 'unarchived') {
datas.triggerVar.set({
activityType: 'restoredCard',
boardId,
desc,
});
}
},
}];
];
},
}).register('boardTriggers');
Template.boardCardTitlePopup.events({
submit(evt, tpl) {
const title = tpl.$('.js-card-filter-name').val().trim();
submit(event, templateInstance) {
const title = templateInstance
.$('.js-card-filter-name')
.val()
.trim();
Popup.getOpenerComponent().setNameFilter(title);
evt.preventDefault();
event.preventDefault();
Popup.close();
},
});
@@ -22,7 +22,7 @@ template(name="cardTriggers")
div.trigger-item
div.trigger-content
div.trigger-text
| {{_'r-when-the-label-is'}}
| {{_'r-when-the-label'}}
div.trigger-dropdown
select(id="spec-label")
each labels
+114 -112
View File
@@ -7,7 +7,7 @@ BlazeComponent.extendComponent({
for (let i = 0; i < labels.length; i++) {
if (labels[i].name === '' || labels[i].name === undefined) {
labels[i].name = labels[i].color;
labels[i].translatedname = `${TAPi18n.__(`color-${ labels[i].color}`)}`;
labels[i].translatedname = `${TAPi18n.__(`color-${labels[i].color}`)}`;
} else {
labels[i].translatedname = labels[i].name;
}
@@ -15,117 +15,119 @@ BlazeComponent.extendComponent({
return labels;
},
events() {
return [{
'click .js-add-gen-label-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#label-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'addedLabel',
boardId,
'labelId': '*',
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removedLabel',
boardId,
'labelId': '*',
desc,
});
}
return [
{
'click .js-add-gen-label-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#label-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'addedLabel',
boardId,
labelId: '*',
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removedLabel',
boardId,
labelId: '*',
desc,
});
}
},
'click .js-add-spec-label-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#spec-label-action').value;
const labelId = this.find('#spec-label').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'addedLabel',
boardId,
labelId,
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removedLabel',
boardId,
labelId,
desc,
});
}
},
'click .js-add-gen-member-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#gen-member-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'joinMember',
boardId,
username: '*',
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'unjoinMember',
boardId,
username: '*',
desc,
});
}
},
'click .js-add-spec-member-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#spec-member-action').value;
const username = this.find('#spec-member').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'joinMember',
boardId,
username,
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'unjoinMember',
boardId,
username,
desc,
});
}
},
'click .js-add-attachment-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#attach-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'addAttachment',
boardId,
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'deleteAttachment',
boardId,
desc,
});
}
},
},
'click .js-add-spec-label-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#spec-label-action').value;
const labelId = this.find('#spec-label').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'addedLabel',
boardId,
labelId,
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removedLabel',
boardId,
labelId,
desc,
});
}
},
'click .js-add-gen-member-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#gen-member-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'joinMember',
boardId,
'username': '*',
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'unjoinMember',
boardId,
'username': '*',
desc,
});
}
},
'click .js-add-spec-member-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#spec-member-action').value;
const username = this.find('#spec-member').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'joinMember',
boardId,
username,
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'unjoinMember',
boardId,
username,
desc,
});
}
},
'click .js-add-attachment-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#attach-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'added') {
datas.triggerVar.set({
activityType: 'addAttachment',
boardId,
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'deleteAttachment',
boardId,
desc,
});
}
},
}];
];
},
}).register('cardTriggers');
@@ -3,144 +3,145 @@ BlazeComponent.extendComponent({
this.subscribe('allRules');
},
events() {
return [{
'click .js-add-gen-check-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#gen-check-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'created') {
datas.triggerVar.set({
activityType: 'addChecklist',
boardId,
'checklistName': '*',
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removeChecklist',
boardId,
'checklistName': '*',
desc,
});
}
},
'click .js-add-spec-check-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#spec-check-action').value;
const checklistId = this.find('#check-name').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'created') {
datas.triggerVar.set({
activityType: 'addChecklist',
boardId,
'checklistName': checklistId,
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removeChecklist',
boardId,
'checklistName': checklistId,
desc,
});
}
},
'click .js-add-gen-comp-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
return [
{
'click .js-add-gen-check-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#gen-check-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'created') {
datas.triggerVar.set({
activityType: 'addChecklist',
boardId,
checklistName: '*',
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removeChecklist',
boardId,
checklistName: '*',
desc,
});
}
},
'click .js-add-spec-check-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#spec-check-action').value;
const checklistId = this.find('#check-name').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'created') {
datas.triggerVar.set({
activityType: 'addChecklist',
boardId,
checklistName: checklistId,
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removeChecklist',
boardId,
checklistName: checklistId,
desc,
});
}
},
'click .js-add-gen-comp-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#gen-comp-check-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'completed') {
datas.triggerVar.set({
activityType: 'completeChecklist',
boardId,
'checklistName': '*',
desc,
});
}
if (actionSelected === 'uncompleted') {
datas.triggerVar.set({
activityType: 'uncompleteChecklist',
boardId,
'checklistName': '*',
desc,
});
}
const datas = this.data();
const actionSelected = this.find('#gen-comp-check-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'completed') {
datas.triggerVar.set({
activityType: 'completeChecklist',
boardId,
checklistName: '*',
desc,
});
}
if (actionSelected === 'uncompleted') {
datas.triggerVar.set({
activityType: 'uncompleteChecklist',
boardId,
checklistName: '*',
desc,
});
}
},
'click .js-add-spec-comp-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#spec-comp-check-action').value;
const checklistId = this.find('#spec-comp-check-name').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'completed') {
datas.triggerVar.set({
activityType: 'completeChecklist',
boardId,
checklistName: checklistId,
desc,
});
}
if (actionSelected === 'uncompleted') {
datas.triggerVar.set({
activityType: 'uncompleteChecklist',
boardId,
checklistName: checklistId,
desc,
});
}
},
'click .js-add-gen-check-item-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#check-item-gen-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'checked') {
datas.triggerVar.set({
activityType: 'checkedItem',
boardId,
checklistItemName: '*',
desc,
});
}
if (actionSelected === 'unchecked') {
datas.triggerVar.set({
activityType: 'uncheckedItem',
boardId,
checklistItemName: '*',
desc,
});
}
},
'click .js-add-spec-check-item-trigger'(event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#check-item-spec-action').value;
const checklistItemId = this.find('#check-item-name').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'checked') {
datas.triggerVar.set({
activityType: 'checkedItem',
boardId,
checklistItemName: checklistItemId,
desc,
});
}
if (actionSelected === 'unchecked') {
datas.triggerVar.set({
activityType: 'uncheckedItem',
boardId,
checklistItemName: checklistItemId,
desc,
});
}
},
},
'click .js-add-spec-comp-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#spec-comp-check-action').value;
const checklistId = this.find('#spec-comp-check-name').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'completed') {
datas.triggerVar.set({
activityType: 'completeChecklist',
boardId,
'checklistName': checklistId,
desc,
});
}
if (actionSelected === 'uncompleted') {
datas.triggerVar.set({
activityType: 'uncompleteChecklist',
boardId,
'checklistName': checklistId,
desc,
});
}
},
'click .js-add-gen-check-item-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#check-item-gen-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'checked') {
datas.triggerVar.set({
activityType: 'checkedItem',
boardId,
'checklistItemName': '*',
desc,
});
}
if (actionSelected === 'unchecked') {
datas.triggerVar.set({
activityType: 'uncheckedItem',
boardId,
'checklistItemName': '*',
desc,
});
}
},
'click .js-add-spec-check-item-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#check-item-spec-action').value;
const checklistItemId = this.find('#check-item-name').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'checked') {
datas.triggerVar.set({
activityType: 'checkedItem',
boardId,
'checklistItemName': checklistItemId,
desc,
});
}
if (actionSelected === 'unchecked') {
datas.triggerVar.set({
activityType: 'uncheckedItem',
boardId,
'checklistItemName': checklistItemId,
desc,
});
}
},
}];
];
},
}).register('checklistTriggers');
@@ -6,9 +6,11 @@ Template.connectionMethod.onCreated(function() {
// TODO : add a management of different languages
// (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
this.authenticationMethods.set([
{value: 'password'},
{ value: 'password' },
// Gets only the authentication methods availables
...Object.entries(result).filter((e) => e[1]).map((e) => ({value: e[0]})),
...Object.entries(result)
.filter(e => e[1])
.map(e => ({ value: e[0] })),
]);
}
@@ -24,7 +26,9 @@ Template.connectionMethod.onCreated(function() {
Template.connectionMethod.onRendered(() => {
// Moves the select boxe in the first place of the at-pwd-form div
$('.at-form-authentication').detach().prependTo('.at-pwd-form');
$('.at-form-authentication')
.detach()
.prependTo('.at-pwd-form');
});
Template.connectionMethod.helpers({
+69 -51
View File
@@ -29,19 +29,23 @@ BlazeComponent.extendComponent({
});
},
events() {
return [{
'click #searchButton'() {
this.filterPeople();
},
'keydown #searchInput'(event) {
if (event.keyCode === 13 && !event.shiftKey) {
return [
{
'click #searchButton'() {
this.filterPeople();
}
},
'keydown #searchInput'(event) {
if (event.keyCode === 13 && !event.shiftKey) {
this.filterPeople();
}
},
},
}];
];
},
filterPeople() {
const value = $('#searchInput').first().val();
const value = $('#searchInput')
.first()
.val();
if (value === '') {
this.findUsersOptions.set({});
} else {
@@ -79,7 +83,7 @@ BlazeComponent.extendComponent({
},
peopleList() {
const users = Users.find(this.findUsersOptions.get(), {
fields: {_id: true},
fields: { _id: true },
});
this.number.set(users.count());
return users;
@@ -105,9 +109,11 @@ Template.editUserPopup.onCreated(function() {
// TODO : add a management of different languages
// (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
this.authenticationMethods.set([
{value: 'password'},
{ value: 'password' },
// Gets only the authentication methods availables
...Object.entries(result).filter((e) => e[1]).map((e) => ({value: e[0]})),
...Object.entries(result)
.filter(e => e[1])
.map(e => ({ value: e[0] })),
]);
}
});
@@ -136,69 +142,79 @@ Template.editUserPopup.helpers({
});
BlazeComponent.extendComponent({
onCreated() {
},
onCreated() {},
user() {
return Users.findOne(this.userId);
},
events() {
return [{
'click a.edit-user': Popup.open('editUser'),
}];
return [
{
'click a.edit-user': Popup.open('editUser'),
},
];
},
}).register('peopleRow');
Template.editUserPopup.events({
submit(evt, tpl) {
evt.preventDefault();
submit(event, templateInstance) {
event.preventDefault();
const user = Users.findOne(this.userId);
const fullname = tpl.find('.js-profile-fullname').value.trim();
const username = tpl.find('.js-profile-username').value.trim();
const password = tpl.find('.js-profile-password').value;
const isAdmin = tpl.find('.js-profile-isadmin').value.trim();
const isActive = tpl.find('.js-profile-isactive').value.trim();
const email = tpl.find('.js-profile-email').value.trim();
const authentication = tpl.find('.js-authenticationMethod').value.trim();
const fullname = templateInstance.find('.js-profile-fullname').value.trim();
const username = templateInstance.find('.js-profile-username').value.trim();
const password = templateInstance.find('.js-profile-password').value;
const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
const isActive = templateInstance.find('.js-profile-isactive').value.trim();
const email = templateInstance.find('.js-profile-email').value.trim();
const authentication = templateInstance
.find('.js-authenticationMethod')
.value.trim();
const isChangePassword = password.length > 0;
const isChangeUserName = username !== user.username;
const isChangeEmail = email.toLowerCase() !== user.emails[0].address.toLowerCase();
const isChangeEmail =
email.toLowerCase() !== user.emails[0].address.toLowerCase();
Users.update(this.userId, {
$set: {
'profile.fullname': fullname,
'isAdmin': isAdmin === 'true',
'loginDisabled': isActive === 'true',
'authenticationMethod': authentication,
isAdmin: isAdmin === 'true',
loginDisabled: isActive === 'true',
authenticationMethod: authentication,
},
});
if(isChangePassword){
if (isChangePassword) {
Meteor.call('setPassword', password, this.userId);
}
if (isChangeUserName && isChangeEmail) {
Meteor.call('setUsernameAndEmail', username, email.toLowerCase(), this.userId, function (error) {
const usernameMessageElement = tpl.$('.username-taken');
const emailMessageElement = tpl.$('.email-taken');
if (error) {
const errorElement = error.error;
if (errorElement === 'username-already-taken') {
usernameMessageElement.show();
emailMessageElement.hide();
} else if (errorElement === 'email-already-taken') {
Meteor.call(
'setUsernameAndEmail',
username,
email.toLowerCase(),
this.userId,
function(error) {
const usernameMessageElement = templateInstance.$('.username-taken');
const emailMessageElement = templateInstance.$('.email-taken');
if (error) {
const errorElement = error.error;
if (errorElement === 'username-already-taken') {
usernameMessageElement.show();
emailMessageElement.hide();
} else if (errorElement === 'email-already-taken') {
usernameMessageElement.hide();
emailMessageElement.show();
}
} else {
usernameMessageElement.hide();
emailMessageElement.show();
emailMessageElement.hide();
Popup.close();
}
} else {
usernameMessageElement.hide();
emailMessageElement.hide();
Popup.close();
}
});
},
);
} else if (isChangeUserName) {
Meteor.call('setUsername', username, this.userId, function (error) {
const usernameMessageElement = tpl.$('.username-taken');
Meteor.call('setUsername', username, this.userId, function(error) {
const usernameMessageElement = templateInstance.$('.username-taken');
if (error) {
const errorElement = error.error;
if (errorElement === 'username-already-taken') {
@@ -210,8 +226,10 @@ Template.editUserPopup.events({
}
});
} else if (isChangeEmail) {
Meteor.call('setEmail', email.toLowerCase(), this.userId, function (error) {
const emailMessageElement = tpl.$('.email-taken');
Meteor.call('setEmail', email.toLowerCase(), this.userId, function(
error,
) {
const emailMessageElement = templateInstance.$('.email-taken');
if (error) {
const errorElement = error.error;
if (errorElement === 'email-already-taken') {
+90 -53
View File
@@ -25,7 +25,9 @@ BlazeComponent.extendComponent({
checkField(selector) {
const value = $(selector).val();
if (!value || value.trim() === '') {
$(selector).parents('li.smtp-form').addClass('has-error');
$(selector)
.parents('li.smtp-form')
.addClass('has-error');
throw Error('blank field');
} else {
return value;
@@ -37,18 +39,23 @@ BlazeComponent.extendComponent({
},
boards() {
return Boards.find({
archived: false,
'members.userId': Meteor.userId(),
'members.isAdmin': true,
}, {
sort: ['title'],
});
return Boards.find(
{
archived: false,
'members.userId': Meteor.userId(),
'members.isAdmin': true,
},
{
sort: ['title'],
},
);
},
toggleRegistration() {
this.setLoading(true);
const registrationClosed = this.currentSetting().disableRegistration;
Settings.update(Settings.findOne()._id, {$set: {disableRegistration: !registrationClosed}});
Settings.update(Settings.findOne()._id, {
$set: { disableRegistration: !registrationClosed },
});
this.setLoading(false);
if (registrationClosed) {
$('.invite-people').slideUp();
@@ -90,13 +97,19 @@ BlazeComponent.extendComponent({
},
inviteThroughEmail() {
const emails = $('#email-to-invite').val().toLowerCase().trim().split('\n').join(',').split(',');
const emails = $('#email-to-invite')
.val()
.toLowerCase()
.trim()
.split('\n')
.join(',')
.split(',');
const boardsToInvite = [];
$('.js-toggle-board-choose .materialCheckBox.is-checked').each(function () {
$('.js-toggle-board-choose .materialCheckBox.is-checked').each(function() {
boardsToInvite.push($(this).data('id'));
});
const validEmails = [];
emails.forEach((email) => {
emails.forEach(email => {
if (email && SimpleSchema.RegEx.Email.test(email.trim())) {
validEmails.push(email.trim());
}
@@ -119,14 +132,22 @@ BlazeComponent.extendComponent({
try {
const host = this.checkField('#mail-server-host');
const port = this.checkField('#mail-server-port');
const username = $('#mail-server-username').val().trim();
const password = $('#mail-server-password').val().trim();
const username = $('#mail-server-username')
.val()
.trim();
const password = $('#mail-server-password')
.val()
.trim();
const from = this.checkField('#mail-server-from');
const tls = $('#mail-server-tls.is-checked').length > 0;
Settings.update(Settings.findOne()._id, {
$set: {
'mailServer.host': host, 'mailServer.port': port, 'mailServer.username': username,
'mailServer.password': password, 'mailServer.enableTLS': tls, 'mailServer.from': from,
'mailServer.host': host,
'mailServer.port': port,
'mailServer.username': username,
'mailServer.password': password,
'mailServer.enableTLS': tls,
'mailServer.from': from,
},
});
} catch (e) {
@@ -134,19 +155,25 @@ BlazeComponent.extendComponent({
} finally {
this.setLoading(false);
}
},
saveLayout() {
this.setLoading(true);
$('li').removeClass('has-error');
const productName = $('#product-name').val().trim();
const hideLogoChange = ($('input[name=hideLogo]:checked').val() === 'true');
const displayAuthenticationMethod = ($('input[name=displayAuthenticationMethod]:checked').val() === 'true');
const productName = $('#product-name')
.val()
.trim();
const hideLogoChange = $('input[name=hideLogo]:checked').val() === 'true';
const displayAuthenticationMethod =
$('input[name=displayAuthenticationMethod]:checked').val() === 'true';
const defaultAuthenticationMethod = $('#defaultAuthenticationMethod').val();
const customHTMLafterBodyStart = $('#customHTMLafterBodyStart').val().trim();
const customHTMLbeforeBodyEnd = $('#customHTMLbeforeBodyEnd').val().trim();
const customHTMLafterBodyStart = $('#customHTMLafterBodyStart')
.val()
.trim();
const customHTMLbeforeBodyEnd = $('#customHTMLbeforeBodyEnd')
.val()
.trim();
try {
Settings.update(Settings.findOne()._id, {
@@ -166,7 +193,6 @@ BlazeComponent.extendComponent({
}
DocHead.setTitle(productName);
},
sendSMTPTestEmail() {
@@ -183,31 +209,35 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click a.js-toggle-registration': this.toggleRegistration,
'click a.js-toggle-tls': this.toggleTLS,
'click a.js-setting-menu': this.switchMenu,
'click a.js-toggle-board-choose': this.checkBoard,
'click button.js-email-invite': this.inviteThroughEmail,
'click button.js-save': this.saveMailServerInfo,
'click button.js-send-smtp-test-email': this.sendSMTPTestEmail,
'click a.js-toggle-hide-logo': this.toggleHideLogo,
'click button.js-save-layout': this.saveLayout,
'click a.js-toggle-display-authentication-method': this.toggleDisplayAuthenticationMethod,
}];
return [
{
'click a.js-toggle-registration': this.toggleRegistration,
'click a.js-toggle-tls': this.toggleTLS,
'click a.js-setting-menu': this.switchMenu,
'click a.js-toggle-board-choose': this.checkBoard,
'click button.js-email-invite': this.inviteThroughEmail,
'click button.js-save': this.saveMailServerInfo,
'click button.js-send-smtp-test-email': this.sendSMTPTestEmail,
'click a.js-toggle-hide-logo': this.toggleHideLogo,
'click button.js-save-layout': this.saveLayout,
'click a.js-toggle-display-authentication-method': this
.toggleDisplayAuthenticationMethod,
},
];
},
}).register('setting');
BlazeComponent.extendComponent({
saveAccountsChange() {
const allowEmailChange = ($('input[name=allowEmailChange]:checked').val() === 'true');
const allowUserNameChange = ($('input[name=allowUserNameChange]:checked').val() === 'true');
const allowEmailChange =
$('input[name=allowEmailChange]:checked').val() === 'true';
const allowUserNameChange =
$('input[name=allowUserNameChange]:checked').val() === 'true';
AccountSettings.update('accounts-allowEmailChange', {
$set: {'booleanValue': allowEmailChange},
$set: { booleanValue: allowEmailChange },
});
AccountSettings.update('accounts-allowUserNameChange', {
$set: {'booleanValue': allowUserNameChange},
$set: { booleanValue: allowUserNameChange },
});
},
@@ -219,9 +249,11 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click button.js-accounts-save': this.saveAccountsChange,
}];
return [
{
'click button.js-accounts-save': this.saveAccountsChange,
},
];
},
}).register('accountSettings');
@@ -239,9 +271,11 @@ BlazeComponent.extendComponent({
},
saveMessage() {
const message = $('#admin-announcement').val().trim();
const message = $('#admin-announcement')
.val()
.trim();
Announcements.update(Announcements.findOne()._id, {
$set: {'body': message},
$set: { body: message },
});
},
@@ -249,7 +283,7 @@ BlazeComponent.extendComponent({
this.setLoading(true);
const isActive = this.currentSetting().enabled;
Announcements.update(Announcements.findOne()._id, {
$set: {'enabled': !isActive},
$set: { enabled: !isActive },
});
this.setLoading(false);
if (isActive) {
@@ -260,14 +294,15 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click a.js-toggle-activemessage': this.toggleActive,
'click button.js-announcement-save': this.saveMessage,
}];
return [
{
'click a.js-toggle-activemessage': this.toggleActive,
'click button.js-announcement-save': this.saveMessage,
},
];
},
}).register('announcementSettings');
Template.selectAuthenticationMethod.onCreated(function() {
this.authenticationMethods = new ReactiveVar([]);
@@ -276,9 +311,11 @@ Template.selectAuthenticationMethod.onCreated(function() {
// TODO : add a management of different languages
// (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
this.authenticationMethods.set([
{value: 'password'},
{ value: 'password' },
// Gets only the authentication methods availables
...Object.entries(result).filter((e) => e[1]).map((e) => ({value: e[0]})),
...Object.entries(result)
.filter(e => e[1])
.map(e => ({ value: e[0] })),
]);
}
});
+2 -2
View File
@@ -10,8 +10,8 @@ template(name="sidebar")
i.fa.fa-keyboard-o
span {{_ 'keyboard-shortcuts' }}
.sidebar-content.js-board-sidebar-content.js-perfect-scrollbar
a.hide-btn.js-hide-sidebar
i.fa.fa-navicon
//a.hide-btn.js-hide-sidebar
// i.fa.fa-navicon
unless isDefaultView
h2
a.fa.fa-chevron-left.js-back-home
+192 -131
View File
@@ -91,29 +91,34 @@ BlazeComponent.extendComponent({
},
showTongueTitle() {
if (this.isOpen())
return `${TAPi18n.__('sidebar-close')}`;
else
return `${TAPi18n.__('sidebar-open')}`;
if (this.isOpen()) return `${TAPi18n.__('sidebar-close')}`;
else return `${TAPi18n.__('sidebar-open')}`;
},
events() {
return [{
'click .js-hide-sidebar': this.hide,
'click .js-toggle-sidebar': this.toggle,
'click .js-back-home': this.setView,
'click .js-shortcuts'() {
FlowRouter.go('shortcuts');
return [
{
'click .js-hide-sidebar': this.hide,
'click .js-toggle-sidebar': this.toggle,
'click .js-back-home': this.setView,
'click .js-shortcuts'() {
FlowRouter.go('shortcuts');
},
},
}];
];
},
}).register('sidebar');
Blaze.registerHelper('Sidebar', () => Sidebar);
EscapeActions.register('sidebarView',
() => { Sidebar.setView(defaultView); },
() => { return Sidebar && Sidebar.getView() !== defaultView; }
EscapeActions.register(
'sidebarView',
() => {
Sidebar.setView(defaultView);
},
() => {
return Sidebar && Sidebar.getView() !== defaultView;
},
);
Template.memberPopup.helpers({
@@ -122,13 +127,13 @@ Template.memberPopup.helpers({
},
memberType() {
const type = Users.findOne(this.userId).isBoardAdmin() ? 'admin' : 'normal';
if(type === 'normal'){
if (type === 'normal') {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const commentOnly = currentBoard.hasCommentOnly(this.userId);
const noComments = currentBoard.hasNoComments(this.userId);
if(commentOnly){
if (commentOnly) {
return TAPi18n.__('comment-only').toLowerCase();
} else if(noComments) {
} else if (noComments) {
return TAPi18n.__('no-comments').toLowerCase();
} else {
return TAPi18n.__(type).toLowerCase();
@@ -197,7 +202,7 @@ Template.memberPopup.events({
'click .js-remove-member': Popup.afterConfirm('removeMember', function() {
const boardId = Session.get('currentBoard');
const memberId = this.userId;
Cards.find({ boardId, members: memberId }).forEach((card) => {
Cards.find({ boardId, members: memberId }).forEach(card => {
card.unassignMember(memberId);
});
Boards.findOne(boardId).removeMember(memberId);
@@ -274,38 +279,40 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'submit'(evt) {
evt.preventDefault();
const url = evt.target.url.value;
const boardId = Session.get('currentBoard');
let id = null;
let integration = null;
if (evt.target.id) {
id = evt.target.id.value;
integration = this.integration(id);
if (url) {
Integrations.update(integration._id, {
$set: {
url: `${url}`,
},
return [
{
submit(evt) {
evt.preventDefault();
const url = evt.target.url.value;
const boardId = Session.get('currentBoard');
let id = null;
let integration = null;
if (evt.target.id) {
id = evt.target.id.value;
integration = this.integration(id);
if (url) {
Integrations.update(integration._id, {
$set: {
url: `${url}`,
},
});
} else {
Integrations.remove(integration._id);
}
} else if (url) {
Integrations.insert({
userId: Meteor.userId(),
enabled: true,
type: 'outgoing-webhooks',
url: `${url}`,
boardId: `${boardId}`,
activities: ['all'],
});
} else {
Integrations.remove(integration._id);
}
} else if (url) {
Integrations.insert({
userId: Meteor.userId(),
enabled: true,
type: 'outgoing-webhooks',
url: `${url}`,
boardId: `${boardId}`,
activities: ['all'],
});
}
Popup.close();
Popup.close();
},
},
}];
];
},
}).register('outgoingWebhooksPopup');
@@ -375,14 +382,16 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-select-background'(evt) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const newColor = this.currentData().toString();
currentBoard.setColor(newColor);
evt.preventDefault();
return [
{
'click .js-select-background'(evt) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const newColor = this.currentData().toString();
currentBoard.setColor(newColor);
evt.preventDefault();
},
},
}];
];
},
}).register('boardChangeColorPopup');
@@ -400,25 +409,34 @@ BlazeComponent.extendComponent({
},
isNullBoardSelected() {
return (this.currentBoard.subtasksDefaultBoardId === null) || (this.currentBoard.subtasksDefaultBoardId === undefined);
return (
this.currentBoard.subtasksDefaultBoardId === null ||
this.currentBoard.subtasksDefaultBoardId === undefined
);
},
boards() {
return Boards.find({
archived: false,
'members.userId': Meteor.userId(),
}, {
sort: ['title'],
});
return Boards.find(
{
archived: false,
'members.userId': Meteor.userId(),
},
{
sort: ['title'],
},
);
},
lists() {
return Lists.find({
boardId: this.currentBoard._id,
archived: false,
}, {
sort: ['title'],
});
return Lists.find(
{
boardId: this.currentBoard._id,
archived: false,
},
{
sort: ['title'],
},
);
},
hasLists() {
@@ -431,54 +449,74 @@ BlazeComponent.extendComponent({
presentParentTask() {
let result = this.currentBoard.presentParentTask;
if ((result === null) || (result === undefined)) {
if (result === null || result === undefined) {
result = 'no-parent';
}
return result;
},
events() {
return [{
'click .js-field-has-subtasks'(evt) {
evt.preventDefault();
this.currentBoard.allowsSubtasks = !this.currentBoard.allowsSubtasks;
this.currentBoard.setAllowsSubtasks(this.currentBoard.allowsSubtasks);
$('.js-field-has-subtasks .materialCheckBox').toggleClass('is-checked', this.currentBoard.allowsSubtasks);
$('.js-field-has-subtasks').toggleClass('is-checked', this.currentBoard.allowsSubtasks);
$('.js-field-deposit-board').prop('disabled', !this.currentBoard.allowsSubtasks);
},
'change .js-field-deposit-board'(evt) {
let value = evt.target.value;
if (value === 'null') {
value = null;
}
this.currentBoard.setSubtasksDefaultBoardId(value);
evt.preventDefault();
},
'change .js-field-deposit-list'(evt) {
this.currentBoard.setSubtasksDefaultListId(evt.target.value);
evt.preventDefault();
},
'click .js-field-show-parent-in-minicard'(evt) {
const value = evt.target.id || $(evt.target).parent()[0].id || $(evt.target).parent()[0].parent()[0].id;
const options = [
'prefix-with-full-path',
'prefix-with-parent',
'subtext-with-full-path',
'subtext-with-parent',
'no-parent'];
options.forEach(function(element) {
if (element !== value) {
$(`#${element} .materialCheckBox`).toggleClass('is-checked', false);
$(`#${element}`).toggleClass('is-checked', false);
return [
{
'click .js-field-has-subtasks'(evt) {
evt.preventDefault();
this.currentBoard.allowsSubtasks = !this.currentBoard.allowsSubtasks;
this.currentBoard.setAllowsSubtasks(this.currentBoard.allowsSubtasks);
$('.js-field-has-subtasks .materialCheckBox').toggleClass(
'is-checked',
this.currentBoard.allowsSubtasks,
);
$('.js-field-has-subtasks').toggleClass(
'is-checked',
this.currentBoard.allowsSubtasks,
);
$('.js-field-deposit-board').prop(
'disabled',
!this.currentBoard.allowsSubtasks,
);
},
'change .js-field-deposit-board'(evt) {
let value = evt.target.value;
if (value === 'null') {
value = null;
}
});
$(`#${value} .materialCheckBox`).toggleClass('is-checked', true);
$(`#${value}`).toggleClass('is-checked', true);
this.currentBoard.setPresentParentTask(value);
evt.preventDefault();
this.currentBoard.setSubtasksDefaultBoardId(value);
evt.preventDefault();
},
'change .js-field-deposit-list'(evt) {
this.currentBoard.setSubtasksDefaultListId(evt.target.value);
evt.preventDefault();
},
'click .js-field-show-parent-in-minicard'(evt) {
const value =
evt.target.id ||
$(evt.target).parent()[0].id ||
$(evt.target)
.parent()[0]
.parent()[0].id;
const options = [
'prefix-with-full-path',
'prefix-with-parent',
'subtext-with-full-path',
'subtext-with-parent',
'no-parent',
];
options.forEach(function(element) {
if (element !== value) {
$(`#${element} .materialCheckBox`).toggleClass(
'is-checked',
false,
);
$(`#${element}`).toggleClass('is-checked', false);
}
});
$(`#${value} .materialCheckBox`).toggleClass('is-checked', true);
$(`#${value}`).toggleClass('is-checked', true);
this.currentBoard.setPresentParentTask(value);
evt.preventDefault();
},
},
}];
];
},
}).register('boardSubtaskSettingsPopup');
@@ -528,35 +566,46 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'keyup input'() {
this.setError('');
return [
{
'keyup input'() {
this.setError('');
},
'click .js-select-member'() {
const userId = this.currentData()._id;
const currentBoard = Boards.findOne(Session.get('currentBoard'));
if (!currentBoard.hasMember(userId)) {
this.inviteUser(userId);
}
},
'click .js-email-invite'() {
const idNameEmail = $('.js-search-member input').val();
if (idNameEmail.indexOf('@') < 0 || this.isValidEmail(idNameEmail)) {
this.inviteUser(idNameEmail);
} else this.setError('email-invalid');
},
},
'click .js-select-member'() {
const userId = this.currentData()._id;
const currentBoard = Boards.findOne(Session.get('currentBoard'));
if (!currentBoard.hasMember(userId)) {
this.inviteUser(userId);
}
},
'click .js-email-invite'() {
const idNameEmail = $('.js-search-member input').val();
if (idNameEmail.indexOf('@')<0 || this.isValidEmail(idNameEmail)) {
this.inviteUser(idNameEmail);
} else this.setError('email-invalid');
},
}];
];
},
}).register('addMemberPopup');
Template.changePermissionsPopup.events({
'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only'(event) {
'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only'(
event,
) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const memberId = this.userId;
const isAdmin = $(event.currentTarget).hasClass('js-set-admin');
const isCommentOnly = $(event.currentTarget).hasClass('js-set-comment-only');
const isCommentOnly = $(event.currentTarget).hasClass(
'js-set-comment-only',
);
const isNoComments = $(event.currentTarget).hasClass('js-set-no-comments');
currentBoard.setMemberPermission(memberId, isAdmin, isNoComments, isCommentOnly);
currentBoard.setMemberPermission(
memberId,
isAdmin,
isNoComments,
isCommentOnly,
);
Popup.back(1);
},
});
@@ -569,21 +618,33 @@ Template.changePermissionsPopup.helpers({
isNormal() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return !currentBoard.hasAdmin(this.userId) && !currentBoard.hasNoComments(this.userId) && !currentBoard.hasCommentOnly(this.userId);
return (
!currentBoard.hasAdmin(this.userId) &&
!currentBoard.hasNoComments(this.userId) &&
!currentBoard.hasCommentOnly(this.userId)
);
},
isNoComments() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return !currentBoard.hasAdmin(this.userId) && currentBoard.hasNoComments(this.userId);
return (
!currentBoard.hasAdmin(this.userId) &&
currentBoard.hasNoComments(this.userId)
);
},
isCommentOnly() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return !currentBoard.hasAdmin(this.userId) && currentBoard.hasCommentOnly(this.userId);
return (
!currentBoard.hasAdmin(this.userId) &&
currentBoard.hasCommentOnly(this.userId)
);
},
isLastAdmin() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return currentBoard.hasAdmin(this.userId) && (currentBoard.activeAdmins() === 1);
return (
currentBoard.hasAdmin(this.userId) && currentBoard.activeAdmins() === 1
);
},
});
+70 -63
View File
@@ -10,12 +10,11 @@ BlazeComponent.extendComponent({
// unfortunatly, Blaze doesn't have this notion.
this.autorun(() => {
const currentBoardId = Session.get('currentBoard');
if (!currentBoardId)
return;
if (!currentBoardId) return;
const handle = subManager.subscribe('board', currentBoardId, true);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
this.isArchiveReady.set( handle.ready() );
this.isArchiveReady.set(handle.ready());
});
});
});
@@ -59,74 +58,82 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-restore-card'() {
const card = this.currentData();
if(card.canBeRestored()){
card.restore();
}
},
'click .js-restore-all-cards'() {
this.archivedCards().forEach((card) => {
if(card.canBeRestored()){
return [
{
'click .js-restore-card'() {
const card = this.currentData();
if (card.canBeRestored()) {
card.restore();
}
});
},
},
'click .js-restore-all-cards'() {
this.archivedCards().forEach(card => {
if (card.canBeRestored()) {
card.restore();
}
});
},
'click .js-delete-card': Popup.afterConfirm('cardDelete', function() {
const cardId = this._id;
Cards.remove(cardId);
Popup.close();
}),
'click .js-delete-all-cards': Popup.afterConfirm('cardDelete', () => {
this.archivedCards().forEach((card) => {
Cards.remove(card._id);
});
Popup.close();
}),
'click .js-delete-card': Popup.afterConfirm('cardDelete', function() {
const cardId = this._id;
Cards.remove(cardId);
Popup.close();
}),
'click .js-delete-all-cards': Popup.afterConfirm('cardDelete', () => {
this.archivedCards().forEach(card => {
Cards.remove(card._id);
});
Popup.close();
}),
'click .js-restore-list'() {
const list = this.currentData();
list.restore();
},
'click .js-restore-all-lists'() {
this.archivedLists().forEach((list) => {
'click .js-restore-list'() {
const list = this.currentData();
list.restore();
});
},
},
'click .js-restore-all-lists'() {
this.archivedLists().forEach(list => {
list.restore();
});
},
'click .js-delete-list': Popup.afterConfirm('listDelete', function() {
this.remove();
Popup.close();
}),
'click .js-delete-all-lists': Popup.afterConfirm('listDelete', () => {
this.archivedLists().forEach((list) => {
list.remove();
});
Popup.close();
}),
'click .js-delete-list': Popup.afterConfirm('listDelete', function() {
this.remove();
Popup.close();
}),
'click .js-delete-all-lists': Popup.afterConfirm('listDelete', () => {
this.archivedLists().forEach(list => {
list.remove();
});
Popup.close();
}),
'click .js-restore-swimlane'() {
const swimlane = this.currentData();
swimlane.restore();
},
'click .js-restore-all-swimlanes'() {
this.archivedSwimlanes().forEach((swimlane) => {
'click .js-restore-swimlane'() {
const swimlane = this.currentData();
swimlane.restore();
});
},
},
'click .js-restore-all-swimlanes'() {
this.archivedSwimlanes().forEach(swimlane => {
swimlane.restore();
});
},
'click .js-delete-swimlane': Popup.afterConfirm('swimlaneDelete', function() {
this.remove();
Popup.close();
}),
'click .js-delete-all-swimlanes': Popup.afterConfirm('swimlaneDelete', () => {
this.archivedSwimlanes().forEach((swimlane) => {
swimlane.remove();
});
Popup.close();
}),
}];
'click .js-delete-swimlane': Popup.afterConfirm(
'swimlaneDelete',
function() {
this.remove();
Popup.close();
},
),
'click .js-delete-all-swimlanes': Popup.afterConfirm(
'swimlaneDelete',
() => {
this.archivedSwimlanes().forEach(swimlane => {
swimlane.remove();
});
Popup.close();
},
),
},
];
},
}).register('archivesSidebar');
+112 -97
View File
@@ -1,37 +1,43 @@
BlazeComponent.extendComponent({
customFields() {
return CustomFields.find({
boardIds: {$in: [Session.get('currentBoard')]},
boardIds: { $in: [Session.get('currentBoard')] },
});
},
events() {
return [{
'click .js-open-create-custom-field': Popup.open('createCustomField'),
'click .js-edit-custom-field': Popup.open('editCustomField'),
}];
return [
{
'click .js-open-create-custom-field': Popup.open('createCustomField'),
'click .js-edit-custom-field': Popup.open('editCustomField'),
},
];
},
}).register('customFieldsSidebar');
const CreateCustomFieldPopup = BlazeComponent.extendComponent({
_types: ['text', 'number', 'date', 'dropdown'],
onCreated() {
this.type = new ReactiveVar((this.data().type) ? this.data().type : this._types[0]);
this.dropdownItems = new ReactiveVar((this.data().settings && this.data().settings.dropdownItems) ? this.data().settings.dropdownItems : []);
this.type = new ReactiveVar(
this.data().type ? this.data().type : this._types[0],
);
this.dropdownItems = new ReactiveVar(
this.data().settings && this.data().settings.dropdownItems
? this.data().settings.dropdownItems
: [],
);
},
types() {
const currentType = this.data().type;
return this._types.
map((type) => {return {
return this._types.map(type => {
return {
value: type,
name: TAPi18n.__(`custom-field-${type}`),
selected: type === currentType,
};});
};
});
},
isTypeNotSelected(type) {
@@ -40,113 +46,122 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({
getDropdownItems() {
const items = this.dropdownItems.get();
Array.from(this.findAll('.js-field-settings-dropdown input')).forEach((el, index) => {
//console.log('each item!', index, el.value);
if (!items[index]) items[index] = {
_id: Random.id(6),
};
items[index].name = el.value.trim();
});
Array.from(this.findAll('.js-field-settings-dropdown input')).forEach(
(el, index) => {
//console.log('each item!', index, el.value);
if (!items[index])
items[index] = {
_id: Random.id(6),
};
items[index].name = el.value.trim();
},
);
return items;
},
getSettings() {
const settings = {};
switch (this.type.get()) {
case 'dropdown': {
const dropdownItems = this.getDropdownItems().filter((item) => !!item.name.trim());
settings.dropdownItems = dropdownItems;
break;
}
case 'dropdown': {
const dropdownItems = this.getDropdownItems().filter(
item => !!item.name.trim(),
);
settings.dropdownItems = dropdownItems;
break;
}
}
return settings;
},
events() {
return [{
'change .js-field-type'(evt) {
const value = evt.target.value;
this.type.set(value);
},
'keydown .js-dropdown-item.last'(evt) {
if (evt.target.value.trim() && evt.keyCode === 13) {
const items = this.getDropdownItems();
this.dropdownItems.set(items);
evt.target.value = '';
}
},
'click .js-field-show-on-card'(evt) {
let $target = $(evt.target);
if(!$target.hasClass('js-field-show-on-card')){
$target = $target.parent();
}
$target.find('.materialCheckBox').toggleClass('is-checked');
$target.toggleClass('is-checked');
},
'click .js-field-automatically-on-card'(evt) {
let $target = $(evt.target);
if(!$target.hasClass('js-field-automatically-on-card')){
$target = $target.parent();
}
$target.find('.materialCheckBox').toggleClass('is-checked');
$target.toggleClass('is-checked');
},
'click .js-field-showLabel-on-card'(evt) {
let $target = $(evt.target);
if(!$target.hasClass('js-field-showLabel-on-card')){
$target = $target.parent();
}
$target.find('.materialCheckBox').toggleClass('is-checked');
$target.toggleClass('is-checked');
},
'click .primary'(evt) {
evt.preventDefault();
return [
{
'change .js-field-type'(evt) {
const value = evt.target.value;
this.type.set(value);
},
'keydown .js-dropdown-item.last'(evt) {
if (evt.target.value.trim() && evt.keyCode === 13) {
const items = this.getDropdownItems();
this.dropdownItems.set(items);
evt.target.value = '';
}
},
'click .js-field-show-on-card'(evt) {
let $target = $(evt.target);
if (!$target.hasClass('js-field-show-on-card')) {
$target = $target.parent();
}
$target.find('.materialCheckBox').toggleClass('is-checked');
$target.toggleClass('is-checked');
},
'click .js-field-automatically-on-card'(evt) {
let $target = $(evt.target);
if (!$target.hasClass('js-field-automatically-on-card')) {
$target = $target.parent();
}
$target.find('.materialCheckBox').toggleClass('is-checked');
$target.toggleClass('is-checked');
},
'click .js-field-showLabel-on-card'(evt) {
let $target = $(evt.target);
if (!$target.hasClass('js-field-showLabel-on-card')) {
$target = $target.parent();
}
$target.find('.materialCheckBox').toggleClass('is-checked');
$target.toggleClass('is-checked');
},
'click .primary'(evt) {
evt.preventDefault();
const data = {
name: this.find('.js-field-name').value.trim(),
type: this.type.get(),
settings: this.getSettings(),
showOnCard: this.find('.js-field-show-on-card.is-checked') !== null,
showLabelOnMiniCard: this.find('.js-field-showLabel-on-card.is-checked') !== null,
automaticallyOnCard: this.find('.js-field-automatically-on-card.is-checked') !== null,
};
const data = {
name: this.find('.js-field-name').value.trim(),
type: this.type.get(),
settings: this.getSettings(),
showOnCard: this.find('.js-field-show-on-card.is-checked') !== null,
showLabelOnMiniCard:
this.find('.js-field-showLabel-on-card.is-checked') !== null,
automaticallyOnCard:
this.find('.js-field-automatically-on-card.is-checked') !== null,
};
// insert or update
if (!this.data()._id) {
data.boardIds = [Session.get('currentBoard')];
CustomFields.insert(data);
} else {
CustomFields.update(this.data()._id, {$set: data});
}
// insert or update
if (!this.data()._id) {
data.boardIds = [Session.get('currentBoard')];
CustomFields.insert(data);
} else {
CustomFields.update(this.data()._id, { $set: data });
}
Popup.back();
Popup.back();
},
'click .js-delete-custom-field': Popup.afterConfirm(
'deleteCustomField',
function() {
const customField = CustomFields.findOne(this._id);
if (customField.boardIds.length > 1) {
CustomFields.update(customField._id, {
$pull: {
boardIds: Session.get('currentBoard'),
},
});
} else {
CustomFields.remove(customField._id);
}
Popup.close();
},
),
},
'click .js-delete-custom-field': Popup.afterConfirm('deleteCustomField', function() {
const customField = CustomFields.findOne(this._id);
if (customField.boardIds.length > 1) {
CustomFields.update(customField._id, {
$pull: {
boardIds: Session.get('currentBoard'),
},
});
} else {
CustomFields.remove(customField._id);
}
Popup.close();
}),
}];
];
},
});
CreateCustomFieldPopup.register('createCustomFieldPopup');
(class extends CreateCustomFieldPopup {
template() {
return 'createCustomFieldPopup';
}
}).register('editCustomFieldPopup');
}.register('editCustomFieldPopup'));
/*Template.deleteCustomFieldPopup.events({
'submit'(evt) {
+78 -76
View File
@@ -1,106 +1,108 @@
BlazeComponent.extendComponent({
events() {
return [{
'click .js-toggle-label-filter'(evt) {
evt.preventDefault();
Filter.labelIds.toggle(this.currentData()._id);
Filter.resetExceptions();
return [
{
'click .js-toggle-label-filter'(evt) {
evt.preventDefault();
Filter.labelIds.toggle(this.currentData()._id);
Filter.resetExceptions();
},
'click .js-toggle-member-filter'(evt) {
evt.preventDefault();
Filter.members.toggle(this.currentData()._id);
Filter.resetExceptions();
},
'click .js-toggle-custom-fields-filter'(evt) {
evt.preventDefault();
Filter.customFields.toggle(this.currentData()._id);
Filter.resetExceptions();
},
'change .js-field-advanced-filter'(evt) {
evt.preventDefault();
Filter.advanced.set(
this.find('.js-field-advanced-filter').value.trim(),
);
Filter.resetExceptions();
},
'click .js-clear-all'(evt) {
evt.preventDefault();
Filter.reset();
},
'click .js-filter-to-selection'(evt) {
evt.preventDefault();
const selectedCards = Cards.find(Filter.mongoSelector()).map(c => {
return c._id;
});
MultiSelection.add(selectedCards);
},
},
'click .js-toggle-member-filter'(evt) {
evt.preventDefault();
Filter.members.toggle(this.currentData()._id);
Filter.resetExceptions();
},
'click .js-toggle-custom-fields-filter'(evt) {
evt.preventDefault();
Filter.customFields.toggle(this.currentData()._id);
Filter.resetExceptions();
},
'change .js-field-advanced-filter'(evt) {
evt.preventDefault();
Filter.advanced.set(this.find('.js-field-advanced-filter').value.trim());
Filter.resetExceptions();
},
'click .js-clear-all'(evt) {
evt.preventDefault();
Filter.reset();
},
'click .js-filter-to-selection'(evt) {
evt.preventDefault();
const selectedCards = Cards.find(Filter.mongoSelector()).map((c) => {
return c._id;
});
MultiSelection.add(selectedCards);
},
}];
];
},
}).register('filterSidebar');
function mutateSelectedCards(mutationName, ...args) {
Cards.find(MultiSelection.getMongoSelector()).forEach((card) => {
Cards.find(MultiSelection.getMongoSelector()).forEach(card => {
card[mutationName](...args);
});
}
BlazeComponent.extendComponent({
mapSelection(kind, _id) {
return Cards.find(MultiSelection.getMongoSelector()).map((card) => {
return Cards.find(MultiSelection.getMongoSelector()).map(card => {
const methodName = kind === 'label' ? 'hasLabel' : 'isAssigned';
return card[methodName](_id);
});
},
allSelectedElementHave(kind, _id) {
if (MultiSelection.isEmpty())
return false;
else
return _.every(this.mapSelection(kind, _id));
if (MultiSelection.isEmpty()) return false;
else return _.every(this.mapSelection(kind, _id));
},
someSelectedElementHave(kind, _id) {
if (MultiSelection.isEmpty())
return false;
else
return _.some(this.mapSelection(kind, _id));
if (MultiSelection.isEmpty()) return false;
else return _.some(this.mapSelection(kind, _id));
},
events() {
return [{
'click .js-toggle-label-multiselection'(evt) {
const labelId = this.currentData()._id;
const mappedSelection = this.mapSelection('label', labelId);
return [
{
'click .js-toggle-label-multiselection'(evt) {
const labelId = this.currentData()._id;
const mappedSelection = this.mapSelection('label', labelId);
if (_.every(mappedSelection)) {
mutateSelectedCards('removeLabel', labelId);
} else if (_.every(mappedSelection, (bool) => !bool)) {
mutateSelectedCards('addLabel', labelId);
} else {
const popup = Popup.open('disambiguateMultiLabel');
// XXX We need to have a better integration between the popup and the
// UI components systems.
popup.call(this.currentData(), evt);
}
if (_.every(mappedSelection)) {
mutateSelectedCards('removeLabel', labelId);
} else if (_.every(mappedSelection, bool => !bool)) {
mutateSelectedCards('addLabel', labelId);
} else {
const popup = Popup.open('disambiguateMultiLabel');
// XXX We need to have a better integration between the popup and the
// UI components systems.
popup.call(this.currentData(), evt);
}
},
'click .js-toggle-member-multiselection'(evt) {
const memberId = this.currentData()._id;
const mappedSelection = this.mapSelection('member', memberId);
if (_.every(mappedSelection)) {
mutateSelectedCards('unassignMember', memberId);
} else if (_.every(mappedSelection, bool => !bool)) {
mutateSelectedCards('assignMember', memberId);
} else {
const popup = Popup.open('disambiguateMultiMember');
// XXX We need to have a better integration between the popup and the
// UI components systems.
popup.call(this.currentData(), evt);
}
},
'click .js-move-selection': Popup.open('moveSelection'),
'click .js-archive-selection'() {
mutateSelectedCards('archive');
EscapeActions.executeUpTo('multiselection');
},
},
'click .js-toggle-member-multiselection'(evt) {
const memberId = this.currentData()._id;
const mappedSelection = this.mapSelection('member', memberId);
if (_.every(mappedSelection)) {
mutateSelectedCards('unassignMember', memberId);
} else if (_.every(mappedSelection, (bool) => !bool)) {
mutateSelectedCards('assignMember', memberId);
} else {
const popup = Popup.open('disambiguateMultiMember');
// XXX We need to have a better integration between the popup and the
// UI components systems.
popup.call(this.currentData(), evt);
}
},
'click .js-move-selection': Popup.open('moveSelection'),
'click .js-archive-selection'() {
mutateSelectedCards('archive');
EscapeActions.executeUpTo('multiselection');
},
}];
];
},
}).register('multiselectionSidebar');
+7 -5
View File
@@ -9,11 +9,13 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'submit .js-search-term-form'(evt) {
evt.preventDefault();
this.term.set(evt.target.searchTerm.value);
return [
{
'submit .js-search-term-form'(evt) {
evt.preventDefault();
this.term.set(evt.target.searchTerm.value);
},
},
}];
];
},
}).register('searchSidebar');
+62 -48
View File
@@ -6,9 +6,11 @@ Meteor.startup(() => {
});
BlazeComponent.extendComponent({
editTitle(evt) {
evt.preventDefault();
const newTitle = this.childComponents('inlinedForm')[0].getValue().trim();
editTitle(event) {
event.preventDefault();
const newTitle = this.childComponents('inlinedForm')[0]
.getValue()
.trim();
const swimlane = this.currentData();
if (newTitle) {
swimlane.rename(newTitle.trim());
@@ -16,18 +18,20 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-open-swimlane-menu': Popup.open('swimlaneAction'),
'click .js-open-add-swimlane-menu': Popup.open('swimlaneAdd'),
submit: this.editTitle,
}];
return [
{
'click .js-open-swimlane-menu': Popup.open('swimlaneAction'),
'click .js-open-add-swimlane-menu': Popup.open('swimlaneAdd'),
submit: this.editTitle,
},
];
},
}).register('swimlaneHeader');
Template.swimlaneActionPopup.events({
'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'),
'click .js-close-swimlane' (evt) {
evt.preventDefault();
'click .js-close-swimlane'(event) {
event.preventDefault();
this.archive();
Popup.close();
},
@@ -39,34 +43,42 @@ BlazeComponent.extendComponent({
},
events() {
return [{
submit(evt) {
evt.preventDefault();
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const nextSwimlane = currentBoard.nextSwimlane(this.currentSwimlane);
const titleInput = this.find('.swimlane-name-input');
const title = titleInput.value.trim();
const sortValue = calculateIndexData(this.currentSwimlane, nextSwimlane, 1);
const swimlaneType = (currentBoard.isTemplatesBoard())?'template-swimlane':'swimlane';
return [
{
submit(event) {
event.preventDefault();
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const nextSwimlane = currentBoard.nextSwimlane(this.currentSwimlane);
const titleInput = this.find('.swimlane-name-input');
const title = titleInput.value.trim();
const sortValue = calculateIndexData(
this.currentSwimlane,
nextSwimlane,
1,
);
const swimlaneType = currentBoard.isTemplatesBoard()
? 'template-swimlane'
: 'swimlane';
if (title) {
Swimlanes.insert({
title,
boardId: Session.get('currentBoard'),
sort: sortValue.base,
type: swimlaneType,
});
if (title) {
Swimlanes.insert({
title,
boardId: Session.get('currentBoard'),
sort: sortValue.base,
type: swimlaneType,
});
titleInput.value = '';
titleInput.focus();
}
// XXX ideally, we should move the popup to the newly
// created swimlane so a user can add more than one swimlane
// with a minimum of interactions
Popup.close();
titleInput.value = '';
titleInput.focus();
}
// XXX ideally, we should move the popup to the newly
// created swimlane so a user can add more than one swimlane
// with a minimum of interactions
Popup.close();
},
'click .js-swimlane-template': Popup.open('searchElement'),
},
'click .js-swimlane-template': Popup.open('searchElement'),
}];
];
},
}).register('swimlaneAddPopup');
@@ -77,7 +89,7 @@ BlazeComponent.extendComponent({
},
colors() {
return swimlaneColors.map((color) => ({ color, name: '' }));
return swimlaneColors.map(color => ({ color, name: '' }));
},
isSelected(color) {
@@ -85,18 +97,20 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
return [
{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
'click .js-submit'() {
this.currentSwimlane.setColor(this.currentColor.get());
Popup.close();
},
'click .js-remove-color'() {
this.currentSwimlane.setColor(null);
Popup.close();
},
},
'click .js-submit' () {
this.currentSwimlane.setColor(this.currentColor.get());
Popup.close();
},
'click .js-remove-color'() {
this.currentSwimlane.setColor(null);
Popup.close();
},
}];
];
},
}).register('setSwimlaneColorPopup');
+100 -61
View File
@@ -2,16 +2,27 @@ const { calculateIndex, enableClickOnTouch } = Utils;
function currentListIsInThisSwimlane(swimlaneId) {
const currentList = Lists.findOne(Session.get('currentList'));
return currentList && (currentList.swimlaneId === swimlaneId || currentList.swimlaneId === '');
return (
currentList &&
(currentList.swimlaneId === swimlaneId || currentList.swimlaneId === '')
);
}
function currentCardIsInThisList(listId, swimlaneId) {
const currentCard = Cards.findOne(Session.get('currentCard'));
const currentUser = Meteor.user();
if (currentUser && currentUser.profile && currentUser.profile.boardView === 'board-view-swimlanes')
return currentCard && currentCard.listId === listId && currentCard.swimlaneId === swimlaneId;
else // Default view: board-view-lists
return currentCard && currentCard.listId === listId;
if (
currentUser &&
currentUser.profile &&
currentUser.profile.boardView === 'board-view-swimlanes'
)
return (
currentCard &&
currentCard.listId === listId &&
currentCard.swimlaneId === swimlaneId
);
// Default view: board-view-lists
else return currentCard && currentCard.listId === listId;
// https://github.com/wekan/wekan/issues/1623
// https://github.com/ChronikEwok/wekan/commit/cad9b20451bb6149bfb527a99b5001873b06c3de
// TODO: In public board, if you would like to switch between List/Swimlane view, you could
@@ -79,7 +90,11 @@ function initSortable(boardComponent, $listsDom) {
enableClickOnTouch('.js-list:not(.js-list-composer)');
function userIsMember() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
}
// Disable drag-dropping while in multi-selection mode, or if the current user
@@ -87,8 +102,11 @@ function initSortable(boardComponent, $listsDom) {
boardComponent.autorun(() => {
const $listDom = $listsDom;
if ($listDom.data('sortable')) {
$listsDom.sortable('option', 'disabled',
MultiSelection.isActive() || !userIsMember());
$listsDom.sortable(
'option',
'disabled',
MultiSelection.isActive() || !userIsMember(),
);
}
});
}
@@ -124,47 +142,60 @@ BlazeComponent.extendComponent({
},
events() {
return [{
// Click-and-drag action
'mousedown .board-canvas'(evt) {
// Translating the board canvas using the click-and-drag action can
// conflict with the build-in browser mechanism to select text. We
// define a list of elements in which we disable the dragging because
// the user will legitimately expect to be able to select some text with
// his mouse.
const noDragInside = ['a', 'input', 'textarea', 'p', '.js-list-header'];
if ($(evt.target).closest(noDragInside.join(',')).length === 0 && this.$('.swimlane').prop('clientHeight') > evt.offsetY) {
this._isDragging = true;
this._lastDragPositionX = evt.clientX;
}
return [
{
// Click-and-drag action
'mousedown .board-canvas'(evt) {
// Translating the board canvas using the click-and-drag action can
// conflict with the build-in browser mechanism to select text. We
// define a list of elements in which we disable the dragging because
// the user will legitimately expect to be able to select some text with
// his mouse.
const noDragInside = [
'a',
'input',
'textarea',
'p',
'.js-list-header',
];
if (
$(evt.target).closest(noDragInside.join(',')).length === 0 &&
this.$('.swimlane').prop('clientHeight') > evt.offsetY
) {
this._isDragging = true;
this._lastDragPositionX = evt.clientX;
}
},
mouseup() {
if (this._isDragging) {
this._isDragging = false;
}
},
mousemove(evt) {
if (this._isDragging) {
// Update the canvas position
this.listsDom.scrollLeft -= evt.clientX - this._lastDragPositionX;
this._lastDragPositionX = evt.clientX;
// Disable browser text selection while dragging
evt.stopPropagation();
evt.preventDefault();
// Don't close opened card or inlined form at the end of the
// click-and-drag.
EscapeActions.executeUpTo('popup-close');
EscapeActions.preventNextClick();
}
},
},
'mouseup'() {
if (this._isDragging) {
this._isDragging = false;
}
},
'mousemove'(evt) {
if (this._isDragging) {
// Update the canvas position
this.listsDom.scrollLeft -= evt.clientX - this._lastDragPositionX;
this._lastDragPositionX = evt.clientX;
// Disable browser text selection while dragging
evt.stopPropagation();
evt.preventDefault();
// Don't close opened card or inlined form at the end of the
// click-and-drag.
EscapeActions.executeUpTo('popup-close');
EscapeActions.preventNextClick();
}
},
}];
];
},
}).register('swimlane');
BlazeComponent.extendComponent({
onCreated() {
this.currentBoard = Boards.findOne(Session.get('currentBoard'));
this.isListTemplatesSwimlane = this.currentBoard.isTemplatesBoard() && this.currentData().isListTemplatesSwimlane();
this.isListTemplatesSwimlane =
this.currentBoard.isTemplatesBoard() &&
this.currentData().isListTemplatesSwimlane();
this.currentSwimlane = this.currentData();
},
@@ -174,32 +205,40 @@ BlazeComponent.extendComponent({
},
events() {
return [{
submit(evt) {
evt.preventDefault();
const titleInput = this.find('.list-name-input');
const title = titleInput.value.trim();
if (title) {
Lists.insert({
title,
boardId: Session.get('currentBoard'),
sort: $('.list').length,
type: (this.isListTemplatesSwimlane)?'template-list':'list',
swimlaneId: (this.currentBoard.isTemplatesBoard())?this.currentSwimlane._id:'',
});
return [
{
submit(evt) {
evt.preventDefault();
const titleInput = this.find('.list-name-input');
const title = titleInput.value.trim();
if (title) {
Lists.insert({
title,
boardId: Session.get('currentBoard'),
sort: $('.list').length,
type: this.isListTemplatesSwimlane ? 'template-list' : 'list',
swimlaneId: this.currentBoard.isTemplatesBoard()
? this.currentSwimlane._id
: '',
});
titleInput.value = '';
titleInput.focus();
}
titleInput.value = '';
titleInput.focus();
}
},
'click .js-list-template': Popup.open('searchElement'),
},
'click .js-list-template': Popup.open('searchElement'),
}];
];
},
}).register('addListForm');
Template.swimlane.helpers({
canSeeAddList() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
return (
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly()
);
},
});
+46 -47
View File
@@ -22,14 +22,11 @@ Template.userAvatar.helpers({
presenceStatusClassName() {
const user = Users.findOne(this.userId);
const userPresence = presences.findOne({ userId: this.userId });
if (user && user.isInvitedTo(Session.get('currentBoard')))
return 'pending';
else if (!userPresence)
return 'disconnected';
if (user && user.isInvitedTo(Session.get('currentBoard'))) return 'pending';
else if (!userPresence) return 'disconnected';
else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
return 'active';
else
return 'idle';
else return 'idle';
},
});
@@ -45,7 +42,7 @@ Template.userAvatarInitials.helpers({
viewPortWidth() {
const user = Users.findOne(this.userId);
return (user && user.getInitials().length || 1) * 12;
return ((user && user.getInitials().length) || 1) * 12;
},
});
@@ -64,7 +61,7 @@ BlazeComponent.extendComponent({
},
uploadedAvatars() {
return Avatars.find({userId: Meteor.userId()});
return Avatars.find({ userId: Meteor.userId() });
},
isSelected() {
@@ -89,46 +86,48 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-upload-avatar'() {
this.$('.js-upload-avatar-input').click();
},
'change .js-upload-avatar-input'(evt) {
let file, fileUrl;
return [
{
'click .js-upload-avatar'() {
this.$('.js-upload-avatar-input').click();
},
'change .js-upload-avatar-input'(event) {
let file, fileUrl;
FS.Utility.eachFile(evt, (f) => {
try {
file = Avatars.insert(new FS.File(f));
fileUrl = file.url(this.avatarUrlOptions());
} catch (e) {
this.setError('avatar-too-big');
FS.Utility.eachFile(event, f => {
try {
file = Avatars.insert(new FS.File(f));
fileUrl = file.url(this.avatarUrlOptions());
} catch (e) {
this.setError('avatar-too-big');
}
});
if (fileUrl) {
this.setError('');
const fetchAvatarInterval = window.setInterval(() => {
$.ajax({
url: fileUrl,
success: () => {
this.setAvatar(file.url(this.avatarUrlOptions()));
window.clearInterval(fetchAvatarInterval);
},
});
}, 100);
}
});
if (fileUrl) {
this.setError('');
const fetchAvatarInterval = window.setInterval(() => {
$.ajax({
url: fileUrl,
success: () => {
this.setAvatar(file.url(this.avatarUrlOptions()));
window.clearInterval(fetchAvatarInterval);
},
});
}, 100);
}
},
'click .js-select-avatar'() {
const avatarUrl = this.currentData().url(this.avatarUrlOptions());
this.setAvatar(avatarUrl);
},
'click .js-select-initials'() {
this.setAvatar('');
},
'click .js-delete-avatar'() {
Avatars.remove(this.currentData()._id);
},
},
'click .js-select-avatar'() {
const avatarUrl = this.currentData().url(this.avatarUrlOptions());
this.setAvatar(avatarUrl);
},
'click .js-select-initials'() {
this.setAvatar('');
},
'click .js-delete-avatar'() {
Avatars.remove(this.currentData()._id);
},
}];
];
},
}).register('changeAvatarPopup');
@@ -146,11 +145,11 @@ Template.cardMembersPopup.helpers({
});
Template.cardMembersPopup.events({
'click .js-select-member'(evt) {
'click .js-select-member'(event) {
const card = Cards.findOne(Session.get('currentCard'));
const memberId = this.userId;
card.toggleMember(memberId);
evt.preventDefault();
event.preventDefault();
},
});
+48 -36
View File
@@ -18,8 +18,8 @@ Template.memberMenuPopup.events({
'click .js-change-avatar': Popup.open('changeAvatar'),
'click .js-change-password': Popup.open('changePassword'),
'click .js-change-language': Popup.open('changeLanguage'),
'click .js-logout'(evt) {
evt.preventDefault();
'click .js-logout'(event) {
event.preventDefault();
AccountsTemplates.logout();
},
@@ -38,12 +38,12 @@ Template.editProfilePopup.helpers({
});
Template.editProfilePopup.events({
submit(evt, tpl) {
evt.preventDefault();
const fullname = tpl.find('.js-profile-fullname').value.trim();
const username = tpl.find('.js-profile-username').value.trim();
const initials = tpl.find('.js-profile-initials').value.trim();
const email = tpl.find('.js-profile-email').value.trim();
submit(event, templateInstance) {
event.preventDefault();
const fullname = templateInstance.find('.js-profile-fullname').value.trim();
const username = templateInstance.find('.js-profile-username').value.trim();
const initials = templateInstance.find('.js-profile-initials').value.trim();
const email = templateInstance.find('.js-profile-email').value.trim();
let isChangeUserName = false;
let isChangeEmail = false;
Users.update(Meteor.userId(), {
@@ -53,29 +53,36 @@ Template.editProfilePopup.events({
},
});
isChangeUserName = username !== Meteor.user().username;
isChangeEmail = email.toLowerCase() !== Meteor.user().emails[0].address.toLowerCase();
isChangeEmail =
email.toLowerCase() !== Meteor.user().emails[0].address.toLowerCase();
if (isChangeUserName && isChangeEmail) {
Meteor.call('setUsernameAndEmail', username, email.toLowerCase(), Meteor.userId(), function (error) {
const usernameMessageElement = tpl.$('.username-taken');
const emailMessageElement = tpl.$('.email-taken');
if (error) {
const errorElement = error.error;
if (errorElement === 'username-already-taken') {
usernameMessageElement.show();
emailMessageElement.hide();
} else if (errorElement === 'email-already-taken') {
Meteor.call(
'setUsernameAndEmail',
username,
email.toLowerCase(),
Meteor.userId(),
function(error) {
const usernameMessageElement = templateInstance.$('.username-taken');
const emailMessageElement = templateInstance.$('.email-taken');
if (error) {
const errorElement = error.error;
if (errorElement === 'username-already-taken') {
usernameMessageElement.show();
emailMessageElement.hide();
} else if (errorElement === 'email-already-taken') {
usernameMessageElement.hide();
emailMessageElement.show();
}
} else {
usernameMessageElement.hide();
emailMessageElement.show();
emailMessageElement.hide();
Popup.back();
}
} else {
usernameMessageElement.hide();
emailMessageElement.hide();
Popup.back();
}
});
},
);
} else if (isChangeUserName) {
Meteor.call('setUsername', username, Meteor.userId(), function (error) {
const messageElement = tpl.$('.username-taken');
Meteor.call('setUsername', username, Meteor.userId(), function(error) {
const messageElement = templateInstance.$('.username-taken');
if (error) {
messageElement.show();
} else {
@@ -84,8 +91,10 @@ Template.editProfilePopup.events({
}
});
} else if (isChangeEmail) {
Meteor.call('setEmail', email.toLowerCase(), Meteor.userId(), function (error) {
const messageElement = tpl.$('.email-taken');
Meteor.call('setEmail', email.toLowerCase(), Meteor.userId(), function(
error,
) {
const messageElement = templateInstance.$('.email-taken');
if (error) {
messageElement.show();
} else {
@@ -104,7 +113,7 @@ Template.editProfilePopup.events({
// XXX For some reason the useraccounts autofocus isnt working in this case.
// See https://github.com/meteor-useraccounts/core/issues/384
Template.changePasswordPopup.onRendered(function () {
Template.changePasswordPopup.onRendered(function() {
this.find('#at-field-current_password').focus();
});
@@ -123,7 +132,7 @@ Template.changeLanguagePopup.helpers({
name = 'Occitan';
}
return { tag, name };
}).sort(function (a, b) {
}).sort(function(a, b) {
if (a.name === b.name) {
return 0;
} else {
@@ -138,13 +147,13 @@ Template.changeLanguagePopup.helpers({
});
Template.changeLanguagePopup.events({
'click .js-set-language'(evt) {
'click .js-set-language'(event) {
Users.update(Meteor.userId(), {
$set: {
'profile.language': this.tag,
},
});
evt.preventDefault();
event.preventDefault();
},
});
@@ -161,9 +170,12 @@ Template.changeSettingsPopup.events({
'click .js-toggle-system-messages'() {
Meteor.call('toggleSystemMessages');
},
'click .js-apply-show-cards-at'(evt, tpl) {
evt.preventDefault();
const minLimit = parseInt(tpl.$('#show-cards-count-at').val(), 10);
'click .js-apply-show-cards-at'(event, templateInstance) {
event.preventDefault();
const minLimit = parseInt(
templateInstance.$('#show-cards-count-at').val(),
10,
);
if (!isNaN(minLimit)) {
Meteor.call('changeLimitToShowCardsCount', minLimit);
Popup.back();
+1 -1
View File
@@ -25,7 +25,7 @@ Blaze.registerHelper('currentList', () => {
}
});
Blaze.registerHelper('getUser', (userId) => Users.findOne(userId));
Blaze.registerHelper('getUser', userId => Users.findOne(userId));
Blaze.registerHelper('concat', (...args) => args.slice(0, -1).join(''));
+1 -4
View File
@@ -27,10 +27,7 @@ function copyTitleInAriaLabel(attributes) {
// which is a little bit hacky -- but still reasonable with our ES6 usage. If we
// end up switching to React we will probably create lower level small
// components to handle that without overwriting any build-in function.
const {
A: superA,
I: superI,
} = HTML;
const { A: superA, I: superI } = HTML;
HTML.A = (attributes, ...others) => {
return superA(copyTitleInAriaLabel(enforceHref(attributes)), ...others);
+10 -10
View File
@@ -3,11 +3,11 @@
function whichTransitionEvent() {
const el = document.createElement('fakeelement');
const transitions = {
transition:'transitionend',
OTransition:'oTransitionEnd',
MSTransition:'msTransitionEnd',
MozTransition:'transitionend',
WebkitTransition:'webkitTransitionEnd',
transition: 'transitionend',
OTransition: 'oTransitionEnd',
MSTransition: 'msTransitionEnd',
MozTransition: 'transitionend',
WebkitTransition: 'webkitTransitionEnd',
};
for (const t in transitions) {
@@ -21,11 +21,11 @@ function whichTransitionEvent() {
function whichAnimationEvent() {
const el = document.createElement('fakeelement');
const transitions = {
animation:'animationend',
OAnimation:'oAnimationEnd',
MSTransition:'msAnimationEnd',
MozAnimation:'animationend',
WebkitAnimation:'webkitAnimationEnd',
animation: 'animationend',
OAnimation: 'oAnimationEnd',
MSTransition: 'msAnimationEnd',
MozAnimation: 'animationend',
WebkitAnimation: 'webkitAnimationEnd',
};
for (const t in transitions) {
+54 -48
View File
@@ -10,15 +10,20 @@ DatePicker = BlazeComponent.extendComponent({
},
onRendered() {
const $picker = this.$('.js-datepicker').datepicker({
todayHighlight: true,
todayBtn: 'linked',
language: TAPi18n.getLanguage(),
}).on('changeDate', function(evt) {
this.find('#date').value = moment(evt.date).format('L');
this.error.set('');
this.find('#time').focus();
}.bind(this));
const $picker = this.$('.js-datepicker')
.datepicker({
todayHighlight: true,
todayBtn: 'linked',
language: TAPi18n.getLanguage(),
})
.on(
'changeDate',
function(evt) {
this.find('#date').value = moment(evt.date).format('L');
this.error.set('');
this.find('#time').focus();
}.bind(this),
);
if (this.date.get().isValid()) {
$picker.datepicker('update', this.date.get().toDate());
@@ -26,13 +31,11 @@ DatePicker = BlazeComponent.extendComponent({
},
showDate() {
if (this.date.get().isValid())
return this.date.get().format('L');
if (this.date.get().isValid()) return this.date.get().format('L');
return '';
},
showTime() {
if (this.date.get().isValid())
return this.date.get().format('LT');
if (this.date.get().isValid()) return this.date.get().format('LT');
return '';
},
dateFormat() {
@@ -43,44 +46,47 @@ DatePicker = BlazeComponent.extendComponent({
},
events() {
return [{
'keyup .js-date-field'() {
// parse for localized date format in strict mode
const dateMoment = moment(this.find('#date').value, 'L', true);
if (dateMoment.isValid()) {
this.error.set('');
this.$('.js-datepicker').datepicker('update', dateMoment.toDate());
}
},
'keyup .js-time-field'() {
// parse for localized time format in strict mode
const dateMoment = moment(this.find('#time').value, 'LT', true);
if (dateMoment.isValid()) {
this.error.set('');
}
},
'submit .edit-date'(evt) {
evt.preventDefault();
return [
{
'keyup .js-date-field'() {
// parse for localized date format in strict mode
const dateMoment = moment(this.find('#date').value, 'L', true);
if (dateMoment.isValid()) {
this.error.set('');
this.$('.js-datepicker').datepicker('update', dateMoment.toDate());
}
},
'keyup .js-time-field'() {
// parse for localized time format in strict mode
const dateMoment = moment(this.find('#time').value, 'LT', true);
if (dateMoment.isValid()) {
this.error.set('');
}
},
'submit .edit-date'(evt) {
evt.preventDefault();
// if no time was given, init with 12:00
const time = evt.target.time.value || moment(new Date().setHours(12, 0, 0)).format('LT');
// if no time was given, init with 12:00
const time =
evt.target.time.value ||
moment(new Date().setHours(12, 0, 0)).format('LT');
const dateString = `${evt.target.date.value} ${time}`;
const newDate = moment(dateString, 'L LT', true);
if (newDate.isValid()) {
this._storeDate(newDate.toDate());
const dateString = `${evt.target.date.value} ${time}`;
const newDate = moment(dateString, 'L LT', true);
if (newDate.isValid()) {
this._storeDate(newDate.toDate());
Popup.close();
} else {
this.error.set('invalid-date');
evt.target.date.focus();
}
},
'click .js-delete-date'(evt) {
evt.preventDefault();
this._deleteDate();
Popup.close();
}
else {
this.error.set('invalid-date');
evt.target.date.focus();
}
},
},
'click .js-delete-date'(evt) {
evt.preventDefault();
this._deleteDate();
Popup.close();
},
}];
];
},
});
+8 -5
View File
@@ -11,7 +11,10 @@
$.event.fix = (function(originalFix) {
return function(event) {
event = originalFix.apply(this, arguments);
if (event.type.indexOf('drag') === 0 || event.type.indexOf('drop') === 0) {
if (
event.type.indexOf('drag') === 0 ||
event.type.indexOf('drop') === 0
) {
event.dataTransfer = event.originalEvent.dataTransfer;
}
return event;
@@ -23,7 +26,7 @@
matchType: /image.*/,
};
return $.fn.dropImageReader = function(options) {
return ($.fn.dropImageReader = function(options) {
if (typeof options === 'function') {
options = {
callback: options,
@@ -40,9 +43,9 @@
return $(element).bind('drop', function(event) {
stopFn(event);
const files = event.dataTransfer.files;
for(let i=0; i<files.length; i++) {
for (let i = 0; i < files.length; i++) {
const f = files[i];
if(f.type.match(options.matchType)) {
if (f.type.match(options.matchType)) {
const reader = new FileReader();
reader.onload = function(evt) {
return options.callback.call(element, {
@@ -58,5 +61,5 @@
}
});
});
};
});
})(jQuery);
+25 -23
View File
@@ -33,13 +33,19 @@ EscapeActions = {
const noClickEscapeOn = options.noClickEscapeOn;
this._actions = _.sortBy([...this._actions, {
priority,
condition,
action,
noClickEscapeOn,
enabledOnClick,
}], (action) => action.priority);
this._actions = _.sortBy(
[
...this._actions,
{
priority,
condition,
action,
noClickEscapeOn,
enabledOnClick,
},
],
action => action.priority,
);
},
executeLowest() {
@@ -80,10 +86,8 @@ EscapeActions = {
},
_stopClick(action, clickTarget) {
if (!_.isString(action.noClickEscapeOn))
return false;
else
return $(clickTarget).closest(action.noClickEscapeOn).length > 0;
if (!_.isString(action.noClickEscapeOn)) return false;
else return $(clickTarget).closest(action.noClickEscapeOn).length > 0;
},
_execute(options) {
@@ -95,14 +99,11 @@ EscapeActions = {
let executedAtLeastOne = false;
let maxPriority;
if (!maxLabel)
maxPriority = Infinity;
else
maxPriority = this.hierarchy.indexOf(maxLabel);
if (!maxLabel) maxPriority = Infinity;
else maxPriority = this.hierarchy.indexOf(maxLabel);
for (const currentAction of this._actions) {
if (currentAction.priority > maxPriority)
return executedAtLeastOne;
if (currentAction.priority > maxPriority) return executedAtLeastOne;
if (isClick && this._stopClick(currentAction, clickTarget))
return executedAtLeastOne;
@@ -111,8 +112,7 @@ EscapeActions = {
if (isEnabled && currentAction.condition()) {
currentAction.action();
executedAtLeastOne = true;
if (!multipleActions)
return executedAtLeastOne;
if (!multipleActions) return executedAtLeastOne;
}
}
return executedAtLeastOne;
@@ -128,13 +128,15 @@ Mousetrap.bindGlobal('esc', () => {
// On a left click on the document, we try to exectute one escape action (eg,
// close the popup). We don't execute any action if the user has clicked on a
// link or a button.
$(document).on('click', (evt) => {
if (evt.button === 0 &&
$(evt.target).closest('a,button,.is-editable').length === 0) {
$(document).on('click', evt => {
if (
evt.button === 0 &&
$(evt.target).closest('a,button,.is-editable').length === 0
) {
EscapeActions.clickExecute(evt.target, 'multiselection');
}
});
$(document).on('click', 'a[href=\\#]', (evt) => {
$(document).on('click', 'a[href=\\#]', evt => {
evt.preventDefault();
});
+228 -236
View File
@@ -71,18 +71,19 @@ class SetFilter {
_getEmptySelector() {
this._dep.depend();
let includeEmpty = false;
this._selectedElements.forEach((el) => {
this._selectedElements.forEach(el => {
if (el === undefined) {
includeEmpty = true;
}
});
return includeEmpty ? {
$eq: [],
} : null;
return includeEmpty
? {
$eq: [],
}
: null;
}
}
// Advanced filter forms a MongoSelector from a users String.
// Build by: Ignatz 19.05.2018 (github feuerball11)
class AdvancedFilter {
@@ -128,7 +129,8 @@ class AdvancedFilter {
current += char;
continue;
}
if (char === '\'') {
// eslint-disable-next-line quotes
if (char === "'") {
string = !string;
if (string) wasString = true;
continue;
@@ -139,8 +141,8 @@ class AdvancedFilter {
}
if (char === ' ' && !string) {
commands.push({
'cmd': current,
'string': wasString,
cmd: current,
string: wasString,
regex,
});
wasString = false;
@@ -151,8 +153,8 @@ class AdvancedFilter {
}
if (current !== '') {
commands.push({
'cmd': current,
'string': wasString,
cmd: current,
string: wasString,
regex,
});
}
@@ -161,16 +163,19 @@ class AdvancedFilter {
_fieldNameToId(field) {
const found = CustomFields.findOne({
'name': field,
name: field,
});
return found._id;
}
_fieldValueToId(field, value) {
const found = CustomFields.findOne({
'name': field,
name: field,
});
if (found.settings.dropdownItems && found.settings.dropdownItems.length > 0) {
if (
found.settings.dropdownItems &&
found.settings.dropdownItems.length > 0
) {
for (let i = 0; i < found.settings.dropdownItems.length; i++) {
if (found.settings.dropdownItems[i].name === value) {
return found.settings.dropdownItems[i]._id;
@@ -202,37 +207,32 @@ class AdvancedFilter {
for (let i = 0; i < commands.length; i++) {
if (commands[i].cmd) {
switch (commands[i].cmd) {
case '(':
{
level++;
if (start === -1) start = i;
continue;
}
case ')':
{
level--;
commands.splice(i, 1);
i--;
continue;
}
default:
{
if (level > 0) {
subcommands.push(commands[i]);
case '(': {
level++;
if (start === -1) start = i;
continue;
}
case ')': {
level--;
commands.splice(i, 1);
i--;
continue;
}
}
default: {
if (level > 0) {
subcommands.push(commands[i]);
commands.splice(i, 1);
i--;
continue;
}
}
}
}
}
if (start !== -1) {
this._processSubCommands(subcommands);
if (subcommands.length === 1)
commands.splice(start, 0, subcommands[0]);
else
commands.splice(start, 0, subcommands);
if (subcommands.length === 1) commands.splice(start, 0, subcommands[0]);
else commands.splice(start, 0, subcommands);
}
this._processConditions(commands);
this._processLogicalOperators(commands);
@@ -242,149 +242,139 @@ class AdvancedFilter {
for (let i = 0; i < commands.length; i++) {
if (!commands[i].string && commands[i].cmd) {
switch (commands[i].cmd) {
case '=':
case '==':
case '===':
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
if (commands[i + 1].regex) {
const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
let regex = null;
if (match.length > 2)
regex = new RegExp(match[1], match[2]);
else
regex = new RegExp(match[1]);
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': regex,
};
} else {
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$in: [this._fieldValueToId(field, str), parseInt(str, 10)],
},
};
}
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '!=':
case '!==':
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
if (commands[i + 1].regex) {
const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
let regex = null;
if (match.length > 2)
regex = new RegExp(match[1], match[2]);
else
regex = new RegExp(match[1]);
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$not: regex,
},
};
} else {
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$not: {
case '=':
case '==':
case '===': {
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
if (commands[i + 1].regex) {
const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
let regex = null;
if (match.length > 2) regex = new RegExp(match[1], match[2]);
else regex = new RegExp(match[1]);
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': regex,
};
} else {
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$in: [this._fieldValueToId(field, str), parseInt(str, 10)],
},
};
}
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '!=':
case '!==': {
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
if (commands[i + 1].regex) {
const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
let regex = null;
if (match.length > 2) regex = new RegExp(match[1], match[2]);
else regex = new RegExp(match[1]);
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$not: regex,
},
};
} else {
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$not: {
$in: [this._fieldValueToId(field, str), parseInt(str, 10)],
},
},
};
}
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '>':
case 'gt':
case 'Gt':
case 'GT': {
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$gt: parseInt(str, 10),
},
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '>=':
case '>==':
case 'gte':
case 'Gte':
case 'GTE': {
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$gte: parseInt(str, 10),
},
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '<':
case 'lt':
case 'Lt':
case 'LT': {
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$lt: parseInt(str, 10),
},
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '<=':
case '<==':
case 'lte':
case 'Lte':
case 'LTE': {
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$lte: parseInt(str, 10),
},
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '>':
case 'gt':
case 'Gt':
case 'GT':
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$gt: parseInt(str, 10),
},
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '>=':
case '>==':
case 'gte':
case 'Gte':
case 'GTE':
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$gte: parseInt(str, 10),
},
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '<':
case 'lt':
case 'Lt':
case 'LT':
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$lt: parseInt(str, 10),
},
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case '<=':
case '<==':
case 'lte':
case 'Lte':
case 'LTE':
{
const field = commands[i - 1].cmd;
const str = commands[i + 1].cmd;
commands[i] = {
'customFields._id': this._fieldNameToId(field),
'customFields.value': {
$lte: parseInt(str, 10),
},
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
}
}
}
@@ -394,54 +384,51 @@ class AdvancedFilter {
for (let i = 0; i < commands.length; i++) {
if (!commands[i].string && commands[i].cmd) {
switch (commands[i].cmd) {
case 'or':
case 'Or':
case 'OR':
case '|':
case '||':
{
const op1 = commands[i - 1];
const op2 = commands[i + 1];
commands[i] = {
$or: [op1, op2],
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case 'and':
case 'And':
case 'AND':
case '&':
case '&&':
{
const op1 = commands[i - 1];
const op2 = commands[i + 1];
commands[i] = {
$and: [op1, op2],
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case 'not':
case 'Not':
case 'NOT':
case '!':
{
const op1 = commands[i + 1];
commands[i] = {
$not: op1,
};
commands.splice(i + 1, 1);
//changed = true;
i--;
break;
}
case 'or':
case 'Or':
case 'OR':
case '|':
case '||': {
const op1 = commands[i - 1];
const op2 = commands[i + 1];
commands[i] = {
$or: [op1, op2],
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case 'and':
case 'And':
case 'AND':
case '&':
case '&&': {
const op1 = commands[i - 1];
const op2 = commands[i + 1];
commands[i] = {
$and: [op1, op2],
};
commands.splice(i - 1, 1);
commands.splice(i, 1);
//changed = true;
i--;
break;
}
case 'not':
case 'Not':
case 'NOT':
case '!': {
const op1 = commands[i + 1];
commands[i] = {
$not: op1,
};
commands.splice(i + 1, 1);
//changed = true;
i--;
break;
}
}
}
}
@@ -452,7 +439,6 @@ class AdvancedFilter {
const commands = this._filterToCommands();
return this._arrayToSelector(commands);
}
}
// The global Filter object.
@@ -477,23 +463,26 @@ Filter = {
_exceptionsDep: new Tracker.Dependency(),
isActive() {
return _.any(this._fields, (fieldName) => {
return this[fieldName]._isActive();
}) || this.advanced._isActive();
return (
_.any(this._fields, fieldName => {
return this[fieldName]._isActive();
}) || this.advanced._isActive()
);
},
_getMongoSelector() {
if (!this.isActive())
return {};
if (!this.isActive()) return {};
const filterSelector = {};
const emptySelector = {};
let includeEmptySelectors = false;
this._fields.forEach((fieldName) => {
this._fields.forEach(fieldName => {
const filter = this[fieldName];
if (filter._isActive()) {
if (filter.subField !== '') {
filterSelector[`${fieldName}.${filter.subField}`] = filter._getMongoSelector();
filterSelector[
`${fieldName}.${filter.subField}`
] = filter._getMongoSelector();
} else {
filterSelector[fieldName] = filter._getMongoSelector();
}
@@ -513,11 +502,15 @@ Filter = {
const selectors = [exceptionsSelector];
if (_.any(this._fields, (fieldName) => {
return this[fieldName]._isActive();
})) selectors.push(filterSelector);
if (
_.any(this._fields, fieldName => {
return this[fieldName]._isActive();
})
)
selectors.push(filterSelector);
if (includeEmptySelectors) selectors.push(emptySelector);
if (this.advanced._isActive()) selectors.push(this.advanced._getMongoSelector());
if (this.advanced._isActive())
selectors.push(this.advanced._getMongoSelector());
return {
$or: selectors,
@@ -526,8 +519,7 @@ Filter = {
mongoSelector(additionalSelector) {
const filterSelector = this._getMongoSelector();
if (_.isUndefined(additionalSelector))
return filterSelector;
if (_.isUndefined(additionalSelector)) return filterSelector;
else
return {
$and: [filterSelector, additionalSelector],
@@ -535,7 +527,7 @@ Filter = {
},
reset() {
this._fields.forEach((fieldName) => {
this._fields.forEach(fieldName => {
const filter = this[fieldName];
filter.reset();
});
+1 -1
View File
@@ -12,7 +12,7 @@ Meteor.startup(() => {
}
if (!language) {
if(navigator.languages) {
if (navigator.languages) {
language = navigator.languages[0];
} else {
language = navigator.language || navigator.userLanguage;
+37 -29
View File
@@ -48,43 +48,51 @@ InlinedForm = BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-close-inlined-form': this.close,
'click .js-open-inlined-form': this.open,
return [
{
'click .js-close-inlined-form': this.close,
'click .js-open-inlined-form': this.open,
// Pressing Ctrl+Enter should submit the form
'keydown form textarea'(evt) {
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
this.find('button[type=submit]').click();
}
},
// Pressing Ctrl+Enter should submit the form
'keydown form textarea'(evt) {
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
this.find('button[type=submit]').click();
}
},
// Close the inlined form when after its submission
submit() {
if (this.currentData().autoclose !== false) {
Tracker.afterFlush(() => {
this.close();
});
}
// Close the inlined form when after its submission
submit() {
if (this.currentData().autoclose !== false) {
Tracker.afterFlush(() => {
this.close();
});
}
},
},
}];
];
},
}).register('inlinedForm');
// Press escape to close the currently opened inlinedForm
EscapeActions.register('inlinedForm',
() => { currentlyOpenedForm.get().close(); },
() => { return currentlyOpenedForm.get() !== null; }, {
EscapeActions.register(
'inlinedForm',
() => {
currentlyOpenedForm.get().close();
},
() => {
return currentlyOpenedForm.get() !== null;
},
{
enabledOnClick: false,
}
},
);
// submit on click outside
document.addEventListener('click', function(evt) {
const openedForm = currentlyOpenedForm.get();
const isClickOutside = $(evt.target).closest('.js-inlined-form').length === 0;
if (openedForm && isClickOutside) {
$('.js-inlined-form button[type=submit]').click();
openedForm.close();
}
}, true);
//document.addEventListener('click', function(evt) {
// const openedForm = currentlyOpenedForm.get();
// const isClickOutside = $(evt.target).closest('.js-inlined-form').length === 0;
// if (openedForm && isClickOutside) {
// $('.js-inlined-form button[type=submit]').click();
// openedForm.close();
// }
//}, true);
+39 -28
View File
@@ -40,8 +40,10 @@ Mousetrap.bind(['down', 'up'], (evt, key) => {
return;
}
const nextFunc = (key === 'down' ? 'next' : 'prev');
const nextCard = $('.js-minicard.is-selected')[nextFunc]('.js-minicard').get(0);
const nextFunc = key === 'down' ? 'next' : 'prev';
const nextCard = $('.js-minicard.is-selected')
[nextFunc]('.js-minicard')
.get(0);
if (nextCard) {
const nextCardId = Blaze.getData(nextCard)._id;
Utils.goCardId(nextCardId);
@@ -49,7 +51,7 @@ Mousetrap.bind(['down', 'up'], (evt, key) => {
});
// XXX This shortcut should also work when hovering over a card in board view
Mousetrap.bind('space', (evt) => {
Mousetrap.bind('space', evt => {
if (!Session.get('currentCard')) {
return;
}
@@ -69,29 +71,38 @@ Mousetrap.bind('space', (evt) => {
});
Template.keyboardShortcuts.helpers({
mapping: [{
keys: ['W'],
action: 'shortcut-toggle-sidebar',
}, {
keys: ['Q'],
action: 'shortcut-filter-my-cards',
}, {
keys: ['F'],
action: 'shortcut-toggle-filterbar',
}, {
keys: ['X'],
action: 'shortcut-clear-filters',
}, {
keys: ['?'],
action: 'shortcut-show-shortcuts',
}, {
keys: ['ESC'],
action: 'shortcut-close-dialog',
}, {
keys: ['@'],
action: 'shortcut-autocomplete-members',
}, {
keys: ['SPACE'],
action: 'shortcut-assign-self',
}],
mapping: [
{
keys: ['W'],
action: 'shortcut-toggle-sidebar',
},
{
keys: ['Q'],
action: 'shortcut-filter-my-cards',
},
{
keys: ['F'],
action: 'shortcut-toggle-filterbar',
},
{
keys: ['X'],
action: 'shortcut-clear-filters',
},
{
keys: ['?'],
action: 'shortcut-show-shortcuts',
},
{
keys: ['ESC'],
action: 'shortcut-close-dialog',
},
{
keys: ['@'],
action: 'shortcut-autocomplete-members',
},
{
keys: ['SPACE'],
action: 'shortcut-assign-self',
},
],
});
+8 -8
View File
@@ -1,6 +1,6 @@
const closedValue = null;
window.Modal = new class {
window.Modal = new (class {
constructor() {
this._currentModal = new ReactiveVar(closedValue);
this._onCloseGoTo = '';
@@ -21,7 +21,7 @@ window.Modal = new class {
return this.getTemplateName() !== closedValue;
}
isWide(){
isWide() {
return this._isWideModal;
}
@@ -32,23 +32,23 @@ window.Modal = new class {
}
}
openWide(modalName, { header = '', onCloseGoTo = ''} = {}) {
openWide(modalName, { header = '', onCloseGoTo = '' } = {}) {
this._currentModal.set({ header, modalName });
this._onCloseGoTo = onCloseGoTo;
this._isWideModal = true;
}
open(modalName, { header = '', onCloseGoTo = ''} = {}) {
open(modalName, { header = '', onCloseGoTo = '' } = {}) {
this._currentModal.set({ header, modalName });
this._onCloseGoTo = onCloseGoTo;
}
}();
})();
Blaze.registerHelper('Modal', Modal);
EscapeActions.register('modalWindow',
EscapeActions.register(
'modalWindow',
() => Modal.close(),
() => Modal.isOpen(),
{ noClickEscapeOn: '.modal-container' }
{ noClickEscapeOn: '.modal-container' },
);
+27 -21
View File
@@ -1,6 +1,4 @@
function getCardsBetween(idA, idB) {
function pluckId(doc) {
return doc._id;
}
@@ -15,7 +13,7 @@ function getCardsBetween(idA, idB) {
}).map(pluckId);
}
const cards = _.sortBy([Cards.findOne(idA), Cards.findOne(idB)], (c) => {
const cards = _.sortBy([Cards.findOne(idA), Cards.findOne(idB)], c => {
return c.sort;
});
@@ -31,17 +29,21 @@ function getCardsBetween(idA, idB) {
};
} else {
selector = {
$or: [{
listId: cards[0].listId,
sort: { $lte: cards[0].sort },
}, {
listId: {
$in: getListsStrictlyBetween(cards[0].listId, cards[1].listId),
$or: [
{
listId: cards[0].listId,
sort: { $lte: cards[0].sort },
},
}, {
listId: cards[1].listId,
sort: { $gte: cards[1].sort },
}],
{
listId: {
$in: getListsStrictlyBetween(cards[0].listId, cards[1].listId),
},
},
{
listId: cards[1].listId,
sort: { $gte: cards[1].sort },
},
],
archived: false,
};
}
@@ -133,14 +135,12 @@ MultiSelection = {
const selectedCards = this._selectedCards.get();
cardIds.forEach((cardId) => {
cardIds.forEach(cardId => {
const indexOfCard = selectedCards.indexOf(cardId);
if (options.remove && indexOfCard > -1)
selectedCards.splice(indexOfCard, 1);
else if (options.add)
selectedCards.push(cardId);
else if (options.add) selectedCards.push(cardId);
});
this._selectedCards.set(selectedCards);
@@ -153,9 +153,15 @@ MultiSelection = {
Blaze.registerHelper('MultiSelection', MultiSelection);
EscapeActions.register('multiselection',
() => { MultiSelection.disable(); },
() => { return MultiSelection.isActive(); }, {
EscapeActions.register(
'multiselection',
() => {
MultiSelection.disable();
},
() => {
return MultiSelection.isActive();
},
{
noClickEscapeOn: '.js-minicard,.js-board-sidebar-content',
}
},
);
+11 -5
View File
@@ -11,7 +11,10 @@
$.event.fix = (function(originalFix) {
return function(event) {
event = originalFix.apply(this, arguments);
if (event.type.indexOf('copy') === 0 || event.type.indexOf('paste') === 0) {
if (
event.type.indexOf('copy') === 0 ||
event.type.indexOf('paste') === 0
) {
event.clipboardData = event.originalEvent.clipboardData;
}
return event;
@@ -23,7 +26,7 @@
matchType: /image.*/,
};
return $.fn.pasteImageReader = function(options) {
return ($.fn.pasteImageReader = function(options) {
if (typeof options === 'function') {
options = {
callback: options,
@@ -35,8 +38,11 @@
return $(element).bind('paste', function(event) {
const types = event.clipboardData.types;
const items = event.clipboardData.items;
for(let i=0; i<types.length; i++) {
if(types[i].match(options.matchType) || items[i].type.match(options.matchType)) {
for (let i = 0; i < types.length; i++) {
if (
types[i].match(options.matchType) ||
items[i].type.match(options.matchType)
) {
const f = items[i].getAsFile();
const reader = new FileReader();
reader.onload = function(evt) {
@@ -53,5 +59,5 @@
}
});
});
};
});
})(jQuery);
+17 -14
View File
@@ -1,4 +1,4 @@
window.Popup = new class {
window.Popup = new (class {
constructor() {
// The template we use to render popups
this.template = Template.popup;
@@ -67,7 +67,7 @@ window.Popup = new class {
title: self._getTitle(popupName),
depth: self._stack.length,
offset: self._getOffset(openerElement),
dataContext: this.currentData && this.currentData() || this,
dataContext: (this.currentData && this.currentData()) || this,
});
// If there are no popup currently opened we use the Blaze API to render
@@ -80,11 +80,14 @@ window.Popup = new class {
// our internal dependency, and since we just changed the top element of
// our internal stack, the popup will be updated with the new data.
if (!self.isOpen()) {
self.current = Blaze.renderWithData(self.template, () => {
self._dep.depend();
return { ...self._getTopStack(), stack: self._stack };
}, document.body);
self.current = Blaze.renderWithData(
self.template,
() => {
self._dep.depend();
return { ...self._getTopStack(), stack: self._stack };
},
document.body,
);
} else {
self._dep.changed();
}
@@ -101,7 +104,7 @@ window.Popup = new class {
const self = this;
return function(evt, tpl) {
const context = this.currentData && this.currentData() || this;
const context = (this.currentData && this.currentData()) || this;
context.__afterConfirmAction = action;
self.open(name).call(context, evt, tpl);
};
@@ -136,7 +139,6 @@ window.Popup = new class {
const openerElement = this._getTopStack().openerElement;
$(openerElement).removeClass('is-active');
this._stack = [];
}
}
@@ -159,7 +161,7 @@ window.Popup = new class {
return () => {
Utils.windowResizeDep.depend();
if(Utils.isMiniScreen()) return { left:0, top:0 };
if (Utils.isMiniScreen()) return { left: 0, top: 0 };
const offset = $element.offset();
const popupWidth = 300 + 15;
@@ -188,18 +190,19 @@ window.Popup = new class {
return title !== translationKey ? title : defaultTitle;
};
}
}();
})();
// We close a potential opened popup on any left click on the document, or go
// one step back by pressing escape.
const escapeActions = ['back', 'close'];
escapeActions.forEach((actionName) => {
EscapeActions.register(`popup-${actionName}`,
escapeActions.forEach(actionName => {
EscapeActions.register(
`popup-${actionName}`,
() => Popup[actionName](),
() => Popup.isOpen(),
{
noClickEscapeOn: '.js-pop-over,.js-open-card-title-popup',
enabledOnClick: actionName === 'close',
}
},
);
});
+3 -6
View File
@@ -47,9 +47,6 @@ $.fn.escapeableTextComplete = function(strategies, options, ...otherArgs) {
});
};
EscapeActions.register('textcomplete',
() => {},
() => dropdownMenuIsOpened, {
noClickEscapeOn: '.textcomplete-dropdown',
}
);
EscapeActions.register('textcomplete', () => {}, () => dropdownMenuIsOpened, {
noClickEscapeOn: '.textcomplete-dropdown',
});
+3 -3
View File
@@ -34,13 +34,13 @@ UnsavedEdits = {
},
has({ fieldName, docId }) {
return Boolean(this.get({fieldName, docId}));
return Boolean(this.get({ fieldName, docId }));
},
set({ fieldName, docId }, value) {
const currentDoc = this._getCollectionDocument(fieldName, docId);
if (currentDoc) {
UnsavedEditCollection.update(currentDoc._id, { $set: { value }});
UnsavedEditCollection.update(currentDoc._id, { $set: { value } });
} else {
UnsavedEditCollection.insert({
fieldName,
@@ -58,7 +58,7 @@ UnsavedEdits = {
},
_getCollectionDocument(fieldName, docId) {
return UnsavedEditCollection.findOne({fieldName, docId});
return UnsavedEditCollection.findOne({ fieldName, docId });
},
};
+51 -27
View File
@@ -2,20 +2,26 @@ Utils = {
// XXX We should remove these two methods
goBoardId(_id) {
const board = Boards.findOne(_id);
return board && FlowRouter.go('board', {
id: board._id,
slug: board.slug,
});
return (
board &&
FlowRouter.go('board', {
id: board._id,
slug: board.slug,
})
);
},
goCardId(_id) {
const card = Cards.findOne(_id);
const board = Boards.findOne(card.boardId);
return board && FlowRouter.go('card', {
cardId: card._id,
boardId: board._id,
slug: board.slug,
});
return (
board &&
FlowRouter.go('card', {
cardId: card._id,
boardId: board._id,
slug: board.slug,
})
);
},
capitalize(string) {
@@ -104,13 +110,21 @@ Utils = {
return window.matchMedia(query).matches;
};
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch) {
if (
'ontouchstart' in window ||
(window.DocumentTouch && document instanceof window.DocumentTouch)
) {
return true;
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// https://git.io/vznFH
const query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
const query = [
'(',
prefixes.join('touch-enabled),('),
'heartz',
')',
].join('');
return mq(query);
})();
Utils.isTouchDevice = () => isTouchable;
@@ -120,7 +134,7 @@ Utils = {
calculateTouchDistance(touchA, touchB) {
return Math.sqrt(
Math.pow(touchA.screenX - touchB.screenX, 2) +
Math.pow(touchA.screenY - touchB.screenY, 2)
Math.pow(touchA.screenY - touchB.screenY, 2),
);
},
@@ -136,7 +150,11 @@ Utils = {
lastTouch = touches[touches.length - 1];
});
$(document).on('touchend', selector, function(e) {
if (touchStart && lastTouch && Utils.calculateTouchDistance(touchStart, lastTouch) <= 20) {
if (
touchStart &&
lastTouch &&
Utils.calculateTouchDistance(touchStart, lastTouch) <= 20
) {
e.preventDefault();
const clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent('click', true, true);
@@ -145,30 +163,30 @@ Utils = {
});
},
manageCustomUI(){
manageCustomUI() {
Meteor.call('getCustomUI', (err, data) => {
if (err && err.error[0] === 'var-not-exist'){
if (err && err.error[0] === 'var-not-exist') {
Session.set('customUI', false); // siteId || address server not defined
}
if (!err){
if (!err) {
Utils.setCustomUI(data);
}
});
},
setCustomUI(data){
setCustomUI(data) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
if (currentBoard) {
DocHead.setTitle(`${currentBoard.title } - ${ data.productName}`);
DocHead.setTitle(`${currentBoard.title} - ${data.productName}`);
} else {
DocHead.setTitle(`${data.productName}`);
}
},
setMatomo(data){
setMatomo(data) {
window._paq = window._paq || [];
window._paq.push(['setDoNotTrack', data.doNotTrack]);
if (data.withUserName){
if (data.withUserName) {
window._paq.push(['setUserId', Meteor.user().username]);
}
window._paq.push(['trackPageView']);
@@ -196,12 +214,12 @@ Utils = {
manageMatomo() {
const matomo = Session.get('matomo');
if (matomo === undefined){
if (matomo === undefined) {
Meteor.call('getMatomoConf', (err, data) => {
if (err && err.error[0] === 'var-not-exist'){
if (err && err.error[0] === 'var-not-exist') {
Session.set('matomo', false); // siteId || address server not defined
}
if (!err){
if (!err) {
Utils.setMatomo(data);
}
});
@@ -220,15 +238,21 @@ Utils = {
finalString += element.text().toLowerCase();
} else if (element.hasClass('user-details')) {
let username = element.find('input').val();
if(username === undefined || username === ''){
if (username === undefined || username === '') {
username = '*';
}
finalString += `${element.find('.trigger-text').text().toLowerCase() } ${ username}`;
finalString += `${element
.find('.trigger-text')
.text()
.toLowerCase()} ${username}`;
} else if (element.find('select').length > 0) {
finalString += element.find('select option:selected').text().toLowerCase();
finalString += element
.find('select option:selected')
.text()
.toLowerCase();
} else if (element.find('input').length > 0) {
let inputvalue = element.find('input').val();
if(inputvalue === undefined || inputvalue === ''){
if (inputvalue === undefined || inputvalue === '') {
inputvalue = '*';
}
finalString += inputvalue;
+38 -22
View File
@@ -1,20 +1,25 @@
const passwordField = AccountsTemplates.removeField('password');
const emailField = AccountsTemplates.removeField('email');
AccountsTemplates.addFields([{
_id: 'username',
type: 'text',
displayName: 'username',
required: true,
minLength: 2,
}, emailField, passwordField, {
_id: 'invitationcode',
type: 'text',
displayName: 'Invitation Code',
required: false,
minLength: 6,
template: 'invitationCode',
}]);
AccountsTemplates.addFields([
{
_id: 'username',
type: 'text',
displayName: 'username',
required: true,
minLength: 2,
},
emailField,
passwordField,
{
_id: 'invitationcode',
type: 'text',
displayName: 'Invitation Code',
required: false,
minLength: 6,
template: 'invitationCode',
},
]);
AccountsTemplates.configure({
defaultLayout: 'userFormsLayout',
@@ -34,7 +39,8 @@ AccountsTemplates.configure({
});
['signIn', 'signUp', 'resetPwd', 'forgotPwd', 'enrollAccount'].forEach(
(routeName) => AccountsTemplates.configureRoute(routeName));
routeName => AccountsTemplates.configureRoute(routeName),
);
// We display the form to change the password in a popup window that already
// have a title, so we unset the title automatically displayed by useraccounts.
@@ -56,15 +62,25 @@ AccountsTemplates.configureRoute('changePwd', {
});
if (Meteor.isServer) {
['resetPassword-subject', 'resetPassword-text', 'verifyEmail-subject', 'verifyEmail-text', 'enrollAccount-subject', 'enrollAccount-text'].forEach((str) => {
[
'resetPassword-subject',
'resetPassword-text',
'verifyEmail-subject',
'verifyEmail-text',
'enrollAccount-subject',
'enrollAccount-text',
].forEach(str => {
const [templateName, field] = str.split('-');
Accounts.emailTemplates[templateName][field] = (user, url) => {
return TAPi18n.__(`email-${str}`, {
url,
user: user.getName(),
siteName: Accounts.emailTemplates.siteName,
}, user.getLanguage());
return TAPi18n.__(
`email-${str}`,
{
url,
user: user.getName(),
siteName: Accounts.emailTemplates.siteName,
},
user.getLanguage(),
);
};
});
}
+10 -6
View File
@@ -1,7 +1,9 @@
let previousPath;
FlowRouter.triggers.exit([({path}) => {
previousPath = path;
}]);
FlowRouter.triggers.exit([
({ path }) => {
previousPath = path;
},
]);
FlowRouter.route('/', {
name: 'home',
@@ -192,9 +194,11 @@ const redirections = {
_.each(redirections, (newPath, oldPath) => {
FlowRouter.route(oldPath, {
triggersEnter: [(context, redirect) => {
redirect(FlowRouter.path(newPath, context.params));
}],
triggersEnter: [
(context, redirect) => {
redirect(FlowRouter.path(newPath, context.params));
},
],
});
});
+4 -4
View File
@@ -91,10 +91,10 @@ services:
#-------------------------------------------------------------------------------------
# ==== 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.4
image: mongo:4.0.9
# 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: mongo:3.2.21
#image: mongo:3.2.21
#-------------------------------------------------------------------------------------
container_name: wekan-db
restart: always
@@ -115,7 +115,7 @@ services:
#image: quay.io/wekan/wekan:meteor-1.8
# 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:master
image: quay.io/wekan/wekan:meteor-1.8
# 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
@@ -329,7 +329,7 @@ services:
# OAuth2 Token Endpoint.
#- OAUTH2_TOKEN_ENDPOINT=/oauth/token
# OAUTH2 ID Token Whitelist Fields.
#- OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
#- OAUTH2_ID_TOKEN_WHITELIST_FIELDS=""
# OAUTH2 Request Permissions.
#- OAUTH2_REQUEST_PERMISSIONS=openid profile email
# OAuth2 ID Mapping
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Възстановено от Архива",
"r-a-card": "карта",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+16 -3
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "dokončil(a) zaškrtávací seznam __checklist__ na kartě __card__ ve sloupci __list__ ve swimlane __swimlane__ na tablu __board__",
"act-uncompleteChecklist": "zrušil(a) dokončení zaškrtávacího seznamu __checklist__ na kartě __card__ ve sloupci __list__ ve swimlane __swimlane__ na tablu __board__",
"act-addComment": "přidal(a) komentář na kartě __card__: __comment__ ve sloupci __list__ ve swimlane __swimlane__ na tablu __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "přidal(a) tablo __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "přidal(a) kartu __card__ do sloupce __list__ ve swimlane __swimlane__ na tablu __board__",
"act-createCustomField": "vytvořil(a) vlastní pole __customField__ na kartu __card__ do sloupce __list__ ve swimlane __swimlane__ na tablu __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "přidal(a) sloupec __list__ do tabla __board__",
"act-addBoardMember": "přidal(a) člena __member__ do tabla __board__",
"act-archivedBoard": "Tablo __board__ přesunuto do Archivu",
@@ -432,7 +436,7 @@
"shortcut-show-shortcuts": "Otevřít tento seznam odkazů",
"shortcut-toggle-filterbar": "Přepnout lištu filtrování",
"shortcut-toggle-sidebar": "Přepnout lištu tabla",
"show-cards-minimum-count": "Zobrazit počet karet pokud sloupec obsahuje více než ",
"show-cards-minimum-count": "Zobrazit počet karet pokud sloupec obsahuje více než",
"sidebar-open": "Otevřít boční panel",
"sidebar-close": "Zavřít boční panel",
"signupPopup-title": "Vytvořit účet",
@@ -596,7 +600,7 @@
"r-unarchived": "Obnoveno z archivu",
"r-a-card": "karta",
"r-when-a-label-is": "Pokud nějaký štítek je",
"r-when-the-label-is": "Pokud tento štítek je",
"r-when-the-label": "Pokud tento štítek je",
"r-list-name": "název seznamu",
"r-when-a-member": "Pokud nějaký člen je",
"r-when-the-member": "Pokud tento člen je",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "Když je karta přesunuta do jiného sloupce",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+705 -692
View File
File diff suppressed because it is too large. Load diff
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -672,6 +676,15 @@
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-added-to": "added to",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+705 -692
View File
File diff suppressed because it is too large. Load diff
+15 -2
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -596,7 +600,7 @@
"r-unarchived": "Restored from Archive",
"r-a-card": "a card",
"r-when-a-label-is": "When a label is",
"r-when-the-label-is": "When the label is",
"r-when-the-label": "When the label",
"r-list-name": "list name",
"r-when-a-member": "When a member is",
"r-when-the-member": "When the member",
@@ -669,6 +673,15 @@
"r-board-note": "Note: leave a field empty to match every possible value.",
"r-checklist-note": "Note: checklist's items have to be written as comma separated values.",
"r-when-a-card-is-moved": "When a card is moved to another list",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
+16 -3
View File
@@ -17,10 +17,14 @@
"act-completeChecklist": "completed checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-uncompleteChecklist": "uncompleted checklist __checklist__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-addComment": "commented on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-editComment": "edited comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-deleteComment": "deleted comment on card __card__: __comment__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createBoard": "created board __board__",
"act-createSwimlane": "created swimlane __swimlane__ to board __board__",
"act-createCard": "created card __card__ to list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createCustomField": "created custom field __customField__ at board __board__",
"act-deleteCustomField": "deleted custom field __customField__ at board __board__",
"act-setCustomField": "edited custom field __customField__: __customFieldValue__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__",
"act-createList": "added list __list__ to board __board__",
"act-addBoardMember": "added member __member__ to board __board__",
"act-archivedBoard": "Board __board__ moved to Archive",
@@ -507,7 +511,7 @@
"boardCardTitlePopup-title": "فیلتر موضوع کارت",
"new-outgoing-webhook": "New Outgoing Webhook",
"no-name": "(ناشناخته)",
"Node_version": "نسخه Node ",
"Node_version": "نسخه Node",
"OS_Arch": "OS Arch",
"OS_Cpus": "OS CPU Count",
"OS_Freemem": "OS Free Memory",
@@ -596,7 +600,7 @@
"r-unarchived": "بازگردانی از آرشیو",
"r-a-card": "کارت",
"r-when-a-label-is": "زمانی که لیبل هست",
"r-when-the-label-is": "زمانی که لیبل هست",
"r-when-the-label": "زمانی که لیبل هست",
"r-list-name": "نام لیست",
"r-when-a-member": "زمانی که کاربر هست",
"r-when-the-member": "زمانی که کاربر",
@@ -669,6 +673,15 @@
"r-board-note": "نکته: برای نمایش موارد ممکن کادر را خالی بگذارید.",
"r-checklist-note": "نکته: چک‌لیست‌ها باید توسط کاما از یک‌دیگر جدا شوند.",
"r-when-a-card-is-moved": "دمانی که یک کارت به لیست دیگری منتقل شد",
"r-set": "Set",
"r-update": "Update",
"r-datefield": "date field",
"r-df-start-at": "start",
"r-df-due-at": "due",
"r-df-end-at": "end",
"r-df-received-at": "received",
"r-to-current-datetime": "to current date/time",
"r-remove-value-from": "Remove value from",
"ldap": "LDAP",
"oauth2": "OAuth2",
"cas": "CAS",
Loaded 100 of 194 files, more files were not shown because too many files have changed in this diff. Show more