Compare commits

...
97 Commits
Author SHA1 Message Date
Lauri Ojansivu 16cc4d7cbd v3.52 2019-11-14 03:08:46 +02:00
Lauri Ojansivu 730352a48d Update changelog. 2019-11-14 03:03:05 +02:00
Lauri Ojansivu 5b41d72e8d Add database migration for assignee.
Thanks to ocdtrekkie and xet7 !
2019-11-14 03:00:14 +02:00
Lauri Ojansivu 33b8952c0b v3.51 2019-11-14 01:03:26 +02:00
Lauri Ojansivu 12483350a1 Update ChangeLog. 2019-11-14 00:58:36 +02:00
Lauri Ojansivu bbc3ab3f99 Change sorting to work on desktop drag handle page instead,
where it seems to work better.

Thanks to xet7 !
2019-11-14 00:55:11 +02:00
Lauri Ojansivu a9e53ec088 v3.50 2019-11-13 21:57:45 +02:00
Lauri Ojansivu 704808a6cb Update translations. 2019-11-13 21:56:53 +02:00
Lauri Ojansivu 5b2f439500 Update API docs. 2019-11-13 21:50:19 +02:00
Lauri Ojansivu 688bc063e5 Update ChangeLog. 2019-11-13 21:48:33 +02:00
Lauri Ojansivu 1eb3d25b40 Update Node.js to v8.16.2.
Thanks to xet7 !
2019-11-13 21:46:33 +02:00
Lauri Ojansivu 7206e2528f Update ChangeLog. 2019-11-13 21:28:17 +02:00
Lauri Ojansivu e1029816df Fix typo. 2019-11-13 21:26:06 +02:00
Lauri Ojansivu 639c95bade Fix typo. 2019-11-13 21:25:15 +02:00
Lauri Ojansivu 0907936d2b Update ChangeLog. 2019-11-13 19:44:18 +02:00
Lauri Ojansivu cdc988c7b1 Merge branch 'master' of github.com:wekan/wekan 2019-11-13 19:41:35 +02:00
Lauri Ojansivu 274a997e62 Fix card, list and swimlane move.
Allow moving cards in multiselect mode.

Closes #2771,
closes #2743,
closes #2704,
related #2081
2019-11-13 19:40:48 +02:00
Lauri Ojansivu 537a48bede Fix card, list and swimlane move.
Closes #2771,
closes #2743,
closes #2704,
related #2081
2019-11-13 19:33:13 +02:00
Lauri Ojansivu 82f0924914 Update translations. 2019-11-13 15:34:29 +02:00
Lauri Ojansivu 7214be488b Close card button now visible on mobile.
Thanks to xet7 !

Closes #2261,
closes #2637
2019-11-08 00:32:10 +02:00
Lauri Ojansivu 36b5965dd0 Close card button now visible on mobile.
Closes #2261
2019-11-08 00:21:04 +02:00
Lauri Ojansivu 3a00a59ffb Update translations. 2019-11-07 23:38:09 +02:00
Lauri Ojansivu 6b855ac045 Update ChangeLog:
More mobile drag handles, and optional desktop drag handles, In Progress.

Thanks to xet7 !

Related #2081
2019-11-07 23:19:06 +02:00
Lauri Ojansivu 9bba0ea283 Done: Assignee field like Jira.
Thanks to xet7 !

Closes #2452
2019-11-07 23:05:44 +02:00
Lauri Ojansivu de7509dc60 Assignee field like Jira #2452 , Done.
Update REST API docs, there can only be one assignee in array.

Thanks to xet7 !
2019-11-07 22:46:55 +02:00
Lauri Ojansivu 9fd14f7ecb Assignee field like Jira #2452 , in progress.
Now assignee is visible also at minicard.

Thanks to xet7 !
2019-11-07 06:04:23 +02:00
Lauri Ojansivu 3cf09efb13 Assignee field like Jira #2452 , in progress.
When there is one selected assignee on card, don't show + button
for adding more assignees, because there can only be one assignee.

Thanks to xet7 !
2019-11-07 00:14:50 +02:00
Lauri Ojansivu 22083787f9 Try to fix prettify. 2019-11-07 00:04:05 +02:00
Lauri Ojansivu 1728298659 Assignee field like Jira #2452 , in progress.
Prevent more than one assignee.

Thanks to xet7 !
2019-11-06 23:36:43 +02:00
Lauri Ojansivu 865c8305cb Update translations. 2019-11-05 23:58:11 +02:00
Lauri Ojansivu 31dbdc835d Assignee field like Jira #2452 , in progress.
Add assignee popup title.

Thanks to xet7 !
2019-11-05 23:53:02 +02:00
Lauri Ojansivu 56efb5c410 Assignee field like Jira #2452 , in progress.
In add assignee popup, avatars are now visible.

Thanks to xet7 !
2019-11-05 23:42:22 +02:00
Lauri Ojansivu ebdb3a0cc3 Fix prettier. 2019-11-05 23:26:07 +02:00
Lauri Ojansivu 473af2f5e2 Update API docs. 2019-11-05 22:10:01 +02:00
Lauri Ojansivu 1d2ab299b0 Update translations. 2019-11-05 22:03:03 +02:00
Lauri Ojansivu f2eda9d7ed Update ChangeLog. 2019-11-05 16:35:52 +02:00
Lauri Ojansivu 52129ed714 Merge pull request #2782 from jymcheong/master
fixed #2780
2019-11-05 16:30:51 +02:00
Lauri Ojansivu e868f9dcee Merge pull request #2783 from bentiss/openapi_gen
Openapi gen fixes
2019-11-05 16:30:14 +02:00
Benjamin Tissoires 3f059ec1e0 generate_openapi: fix enums when they are declared as const
Fixes: #2781
2019-11-05 12:58:06 +01:00
Benjamin Tissoires 8cb3974eff generate_openapi: print a more useful error
...when we can not parse a SchemaProperty
2019-11-05 12:54:58 +01:00
Benjamin Tissoires 7d62d0920c generate_openapi: add a little bit more verbosity when we get an Error 2019-11-05 12:01:04 +01:00
Benjamin Tissoires b787854289 generate_openapi.py: use the logging module
Instead of dealing with custom writes to stderr, it's always better
to rely on standard libraries.
2019-11-05 11:06:40 +01:00
jymcheong d84ea7d16f fixed #2780
https://github.com/wekan/wekan/issues/2780
2019-11-05 11:04:35 +08:00
Lauri Ojansivu 7318e42080 Comment out already existing directory. 2019-11-04 22:53:10 +02:00
Lauri Ojansivu 9f11ea0cc6 Update dependencies. 2019-11-04 22:50:29 +02:00
Lauri Ojansivu 2ec15602d2 Fix desktop swimlane drag handle position.
Thanks to xet7 !

Related #2081
2019-11-04 11:13:10 +02:00
Lauri Ojansivu 6a89605477 Some drag handle fixes.
Thanks to xet7 !

Related #2081
2019-11-04 10:52:52 +02:00
Lauri Ojansivu dff261efee Update translations. 2019-11-04 10:07:51 +02:00
Lauri Ojansivu 931f0d508a Update ChangeLog. 2019-11-04 10:06:13 +02:00
Lauri Ojansivu ea823ab68f Assignee field like Jira #2452 , in progress. 2019-11-04 10:00:28 +02:00
Lauri Ojansivu b56ddf9df9 Fix prettier 2019-11-04 09:59:40 +02:00
Lauri Ojansivu 9a468dfce5 Merge pull request #2779 from bandresen/cardDate_receivedAtfix_and_endDatechange
Card date received-date fix and end-date coloring change (simplify)
2019-11-04 09:52:31 +02:00
Lauri Ojansivu db3476c8ec Merge pull request #2778 from liske/fixes/rest-deletes-all-cards-2624
REST API: fix deletion of a single board card (closes wekan#2624)
2019-11-04 09:51:14 +02:00
Benjamin Andresen 7a5401d5f0 cardDate: endDate coloring change
if no due-date timestamp is set => Gray
if end-date timestamp is younger than due-date timestamp => Green
if end-date timestamp is older than due-date timestamp => Red

resolves #2741
2019-11-04 08:10:11 +01:00
Benjamin Andresen d3ca816762 cardDate: fix ReceivedDate startAt coloring 2019-11-04 08:08:51 +01:00
Thomas Liske b7492e4a11 REST API: fix deletion of a single board card (closes wekan#2624) 2019-11-04 06:08:40 +01:00
Lauri Ojansivu 32ce2b51d8 Assignee field like Jira #2452 , in progress.
Added features:
- When selecting new assignee (+) icon, list shows names who to add.

TODO:
- When selecting new assignee (+) icon, list does not yet show avatars who to add.

Thanks to xet7 !
2019-11-02 16:38:16 +02:00
Lauri Ojansivu e033959278 Update translations. 2019-11-02 16:18:55 +02:00
Lauri Ojansivu 3e8f9ef1a5 Assignee field like Jira #2452 , in progress.
Added features:
- Assignee can now be added and removed.
- Avatar icon is at card and assignee details

TODO:
- When selecting new assignee (+) icon, list does not yet show avatars and names who to add.
  There is empty avatar without name.

Thanks to xet7 !
2019-11-02 16:12:40 +02:00
Lauri Ojansivu 92efb8bec4 Update translations. 2019-10-31 17:08:23 +02:00
Lauri Ojansivu 9e1aaf163f Assignee field like Jira #2452 , in progress.
Assignee can not be removed yet, it removes member, wrong link in popup.

Thanks to xet7 !
2019-10-31 02:21:50 +02:00
Lauri Ojansivu 3f19091a91 Update ChangeLog. 2019-10-30 21:18:11 +02:00
Lauri Ojansivu ae6eb706c7 Update ChangeLog. 2019-10-30 21:14:23 +02:00
Lauri Ojansivu 806df30ba3 Revert creating new list to left, now creates again to right. Thanks to whowillcare !
Revert New List item moved from right to left. Thanks to derbolle and xet7 !

Closes #2772
2019-10-30 20:45:30 +02:00
Lauri Ojansivu 6a88c2f289 Merge branch 'whowillcare-master' 2019-10-30 20:38:52 +02:00
Lauri Ojansivu acc6bc0758 Merge branch 'master' of https://github.com/whowillcare/wekan into whowillcare-master 2019-10-30 20:33:53 +02:00
Lauri Ojansivu f3bc92904c Change list sorting to be visible only at DesktopDragHandle mode. 2019-10-30 18:48:54 +02:00
Sam X. Chen 3308d90a3a Fix: List last modify time will be affected by cards dueAt, endAt 2019-10-30 12:26:39 -04:00
Lauri Ojansivu 5bb99ba096 Add back miniscreen add list style. 2019-10-30 18:09:56 +02:00
Lauri Ojansivu 6ac7523d9d Update translations. 2019-10-30 17:45:24 +02:00
Lauri Ojansivu 758bbab441 Revert New List item moved from right to left.
Thanks to derbolle and xet7 !

Closes #2772
2019-10-30 17:33:02 +02:00
Sam X. Chen b26504f414 Fix: lists filter didn't get added into filter active checklist 2019-10-30 09:45:50 -04:00
Sam X. Chen e195c731de Change the radom to random typo in export.js 2019-10-29 17:45:06 -04:00
Lauri Ojansivu 00d581245c Fix typo on exporting subtasks.
Thanks to xiorcala !

Closes #2770
2019-10-29 22:02:30 +02:00
Lauri Ojansivu 7faff44825 Update translations. 2019-10-29 19:13:00 +02:00
Lauri Ojansivu 6fc9dd1323 Merge pull request #2763 from liske/changes/sensible-card-times
Enhancement: set card times more sensible using the 'Today' button in…
2019-10-29 19:12:35 +02:00
Lauri Ojansivu 7d6d3af54a Add Features: allowing lists to be sorted by modifiedAt when not in draggable mode.
Bug Fix #2093: the broken should be prior to file attachment feature introduced, and tested export board is working.

Thanks to whowillcare !

( xet7 merged this pull request manually from https://github.com/wekan/wekan/pull/2756 )

Closes #2093
2019-10-29 19:05:44 +02:00
Thomas Liske 064c4d7ca7 Lintian fixes. 2019-10-28 08:25:55 +01:00
Thomas Liske 0fb15888bc Enhancement: set card times more sensible using the 'Today' button in datepicker 2019-10-24 13:08:41 +02:00
Sam X. Chen 32f50e1658 Add Feature: allow user to search Lists in Board 2019-10-19 00:28:49 -04:00
Sam X. Chen d2d4840758 Add Feature: allowing user to filter list in Filter function not just cards 2019-10-18 18:06:34 -04:00
Sam X. Chen bc2a20f04e Add Feature: allow user to sort Lists in Board by his own preference, boardadmin can star list 2019-10-18 16:44:09 -04:00
Sam X. Chen 2737d6b23f Bug Fix:2093, need to clean up the temporary file 2019-10-11 11:56:44 -04:00
Sam X. Chen f53c624b0f Buf Fix #2093: the broken should be prior to file attachment feature introduced 2019-10-11 11:01:10 -04:00
Sam X. Chen 77f8b76d4e Add Features: allowing lists to be sorted by modifiedAt when not in draggable mode 2019-10-10 22:57:40 -04:00
Lauri Ojansivu 13a2bd6380 Update package-lock.json 2019-10-09 19:11:32 +03:00
Lauri Ojansivu bec9903f46 v3.49 2019-10-09 18:20:02 +03:00
Lauri Ojansivu 36e006fa4e Fix prettier. 2019-10-09 18:09:14 +03:00
Lauri Ojansivu 5b415c851b v3.48 2019-10-09 17:44:12 +03:00
Lauri Ojansivu 95fb392692 Update ChangeLog. 2019-10-09 17:36:49 +03:00
Lauri Ojansivu f2453834ac Merge pull request #2754 from moserben16/master
Update attachments.js
2019-10-09 17:33:56 +03:00
benji 3064cdd371 Update attachments.js
added else condition to check if MAX_IMAGE_PIXEL is not set, so that it is possible to  upload attachments using drag-and-drop or Ctrl+V without setting the environmental-variable.
If this change is not allowed, please document in the wiki, that this is necessary for a fully-running wekan-instance
2019-10-09 14:24:45 +02:00
Lauri Ojansivu 417fed8605 v3.47 2019-10-09 14:15:12 +03:00
Lauri Ojansivu 4eca27498c Update translations. 2019-10-09 14:01:39 +03:00
Lauri Ojansivu d962ecd77f Update ChangeLog. 2019-10-09 14:00:05 +03:00
Lauri Ojansivu 6feb35c079 Merge pull request #2751 from liske/fixes/rest-card-members
REST API: fix handling of members property on card creation
2019-10-09 13:56:11 +03:00
Thomas Liske ea90ce8784 REST API: fix handling of members property on card creation 2019-10-09 07:23:21 +02:00
106 changed files with 38384 additions and 36485 deletions

No files matched your search

+1 -1
View File
@@ -6,7 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive
ENV \
DEBUG=false \
NODE_VERSION=8.16.1 \
NODE_VERSION=8.16.2 \
METEOR_RELEASE=1.8.1 \
USE_EDGE=false \
METEOR_EDGE=1.5-beta.17 \
+1 -1
View File
@@ -89,7 +89,7 @@ livedata@1.0.18
localstorage@1.2.0
logging@1.1.20
lucasantoniassi:accounts-lockout@1.0.0
matb33:collection-hooks@0.8.4
matb33:collection-hooks@0.9.1
matteodem:easy-search@1.6.4
mdg:meteor-apm-agent@3.2.3
mdg:validation-error@0.5.1
+1 -1
View File
@@ -3,7 +3,7 @@ sudo: required
env:
TRAVIS_DOCKER_COMPOSE_VERSION: 1.24.0
TRAVIS_NODE_VERSION: 8.16.1
TRAVIS_NODE_VERSION: 8.16.2
TRAVIS_NPM_VERSION: 6.4.1
before_install:
+122
View File
@@ -1,3 +1,125 @@
# v3.52 2019-11-14 Wekan release
This release fixes the following bugs:
- [Add database migration for assignee](https://github.com/wekan/wekan/commit/5b41d72e8de93833e1788962427422cff62c09a2).
Thanks to ocdtrekkie and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.51 2019-11-14 Wekan release
This release fixes the following bugs:
- [Change sorting lists to work on desktop drag handle page instead,
where it seems to work better](https://github.com/wekan/wekan/commit/bbc3ab3f994c5a61a4414bc64b05f5a03d259e46).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.50 2019-11-13 Wekan release
This release adds the following new features:
- [Allowing lists to be sorted by modifiedAt when not in draggable
mode](https://github.com/wekan/wekan/commits/77f8b76d4e13c35ea3451622176bbb69a4d39a32).
Thanks to whowillcare.
- Allow user to sort Lists in Board by his own preference boardadmin can star
list [1](https://github.com/wekan/wekan/commit/bc2a20f04e32607f8488a9cecd815647fb43e40e),
[2](https://github.com/wekan/wekan/commit/bc2a20f04e32607f8488a9cecd815647fb43e40e).
Thanks to whowillcare.
- [Allowing user to filter list in Filter function not just cards
commit](https://github.com/wekan/wekan/commit/d2d4840758b0f5aed7feb4f6a459bb2b2d1a3f0b).
Thanks to whowillcare.
- [Allow user to search Lists in Board](https://github.com/wekan/wekan/commit/32f50e16586696ec7d100ce0438d1030ae1f606e).
Thanks to whowillcare.
- Enhancement: [Set card times more sensible using the 'Today' button in
datepicker](https://github.com/wekan/wekan/pull/2747).
Thanks to liske.
- [At card, added Assignee field like Jira, and REST API for it](https://github.com/wekan/wekan/issues/2452).
Parts:
[Add assignee](https://github.com/wekan/wekan/commit/9e1aaf163f3bd0b3c2d2aee8225d111f83b3d421),
[Remove Assignee. Avatar icon is at card and assignee details](https://github.com/wekan/wekan/commit/3e8f9ef1a5275a5e9b691c7e74dc73b97a43689a),
[When selecting new assignee (+) icon, list shows names who to add](https://github.com/wekan/wekan/commit/32ce2b51d8bff5e8851732394a8bae3c56f8b0b6),
[More progress](https://github.com/wekan/wekan/commit/ea823ab68fd5243c8485177e44a074be836836b8),
[In add assignee popup, avatars are now visible](https://github.com/wekan/wekan/commit/56efb5c41075151eeb259d99990a7e86695b2b69),
[Add assignee popup title](https://github.com/wekan/wekan/commit/31dbdc835d5a092b8360a4dbe93e9fbcce068855),
[Prevent more than one assignee](https://github.com/wekan/wekan/commit/1728298659521ee8e6fc94fedad3160030b9a2c3),
[When there is one selected assignee on card, don't show + button for adding more assignees, because there can only be one
assignee](https://github.com/wekan/wekan/commit/3cf09efb13438d66db6cf739591c679ea538d812),
[Now assignee is visible also at minicard](https://github.com/wekan/wekan/commit/9fd14f7ecb593d3debf5adff8f6c61adb0c3feca),
[Update REST API docs, there can only be one assignee in array](https://github.com/wekan/wekan/commit/de7509dc60257667192054e320b381f9dd0f0a31).
Thanks to xet7.
- [More mobile drag handles, and optional desktop drag handles](https://github.com/wekan/wekan/issues/2081): In Progress.
Parts:
[Some drag handle fixes](https://github.com/wekan/wekan/commit/6a8960547729148bd3085cb469f9e93d510ed66c),
[Fix desktop swimlane drag handle position](https://github.com/wekan/wekan/commit/2ec15602d284122fce1a45bed352d0d4050162e2),
[Fix card, list and swimlane move. Allow moving cards in multiselect mode](https://github.com/wekan/wekan/commit/537a48bede250155b30ec264904ba320625bab73).
Thanks to xet7.
and adds the following updates:
- [Update Node.js to v8.16.2](https://github.com/wekan/wekan/commit/1eb3d25b40797fdab41d7dd59405cfcea81dcc61).
Thanks to xet7.
and fixes the following bugs:
- Bug Fix [#2093](https://github.com/wekan/wekan/issues/2093), need to [clean up the
temporary file](https://github.com/wekan/wekan/commit/2737d6b23f3a0fd2314236a85fbdee536df745a2).
Thanks to whowillcare.
- Bug Fix [#2093](https://github.com/wekan/wekan/issues/2093): the broken [should be prior to file attachment feature introduced](https://github.com/wekan/wekan/commit/f53c624b0f6c6ebcc20c378a153e5cda8d73463c).
Thanks to whowillcare.
- [Fix typo on exporting subtasks](https://github.com/wekan/wekan/commit/00d581245c1fe6a01ef372ca87d8a25bc7b937e4).
Thanks to xiorcala.
- [Change the radom to random typo in export.js](https://github.com/wekan/wekan/commit/e195c731de88aba4026c239f4552ae821d522ec7).
Thanks to whowillcare.
- Fix: [List last modify time will be affected by cards dueAt, endAt](https://github.com/wekan/wekan/commit/3308d90a3a6a1ddeed33966767937cd2c2c90cb5).
Thanks to whowillcare.
- Revert creating new list to left, now creates again to right. Thanks to whowillcare.
Revert New List item moved from right to left. Thanks to derbolle and xet7.
[1](https://github.com/wekan/wekan/commit/806df30ba3499cef193eaf1b437cdef65282510f).
- REST API: [Fix deletion of a single board card](https://github.com/wekan/wekan/pull/2778).
Thanks to liske.
- [cardDate: endDate coloring change](https://github.com/wekan/wekan/pull/2779).
If no due-date timestamp is set => Gray.
If end-date timestamp is younger than due-date timestamp => Green.
If end-date timestamp is older than due-date timestamp => Red.
Thanks to bandresen.
- [Fixed Card Open Webhook Error](https://github.com/wekan/wekan/issues/2780).
Thanks to jymcheong.
- [Fixed OpenAPI docs generation](https://github.com/wekan/wekan/pull/2783).
Thanks to bentiss.
- [Fixed close card button not visible on mobile web](https://github.com/wekan/wekan/36b5965dd07e3f0fd90069353310739c394c220f).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.49 2019-10-09 Wekan release
This release fixes the following bugs:
- [Fix prettier errors](https://github.com/wekan/wekan/commits/36e006fa4e78fe94e627625d1cc589654668f22a).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.48 2019-10-09 Wekan release
This release fixes the following bugs:
- [Make possible to upload attachments using drag-and-drop or Ctrl+V without setting the environmental-variable MAX_IMAGE_PIXEL](https://github.com/wekan/wekan/pull/2754).
Thanks to moserben16.
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.47 2019-10-09 Wekan release
This release fixes the following bugs:
- [REST API: fix handling of members property on card creation](https://github.com/wekan/wekan/pull/2751).
Thanks to above GitHub users for their contributions and translators for their translations.
# v3.46 2019-10-07 Wekan release
This release fixes the following bugs:
+1 -1
View File
@@ -6,7 +6,7 @@ LABEL maintainer="wekan"
# ENV BUILD_DEPS="paxctl"
ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 g++ build-essential git ca-certificates" \
DEBUG=false \
NODE_VERSION=v8.16.1 \
NODE_VERSION=v8.16.2 \
METEOR_RELEASE=1.8.1 \
USE_EDGE=false \
METEOR_EDGE=1.5-beta.17 \
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v3.46.0"
appVersion: "v3.52.0"
files:
userUploads:
- README.md
+18 -1
View File
@@ -89,7 +89,6 @@ BlazeComponent.extendComponent({
helper.append(list.clone());
return helper;
},
handle: '.js-swimlane-header',
items: '.swimlane:not(.placeholder)',
placeholder: 'swimlane placeholder',
distance: 7,
@@ -193,6 +192,24 @@ BlazeComponent.extendComponent({
// ugly touch event hotfix
enableClickOnTouch('.js-swimlane:not(.placeholder)');
this.autorun(() => {
if (
Utils.isMiniScreen() ||
(!Utils.isMiniScreen() && Meteor.user().hasShowDesktopDragHandles())
) {
$swimlanesDom.sortable({
handle: '.js-swimlane-header-handle',
});
} else {
$swimlanesDom.sortable({
handle: '.swimlane-header',
});
}
// Disable drag-dropping if the current user is not a board member or is comment only
$swimlanesDom.sortable('option', 'disabled', !userIsMember());
});
function userIsMember() {
return (
Meteor.user() &&
+18
View File
@@ -77,6 +77,10 @@ template(name="boardHeaderBar")
i.fa.fa-archive
span {{_ 'archives'}}
if showSort
a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}")
i.fa(class="{{directionClass}}")
span {{_ 'sort'}}{{_ listSortShortDesc}}
a.board-header-btn.js-open-filter-view(
title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}"
class="{{#if Filter.isActive}}emphasis{{/if}}")
@@ -194,6 +198,20 @@ template(name="createBoard")
| /
a.js-board-template {{_ 'template'}}
template(name="listsortPopup")
h2
| {{_ 'list-sort-by'}}
hr
ul.pop-over-list
each value in allowedSortValues
li
a.js-sort-by(name="{{value.name}}")
if $eq sortby value.name
i(class="fa {{Direction}}")
| {{_ value.label }}{{_ value.shortLabel}}
if $eq sortby value.name
i(class="fa fa-check")
template(name="boardChangeTitlePopup")
form
label
+101 -1
View File
@@ -1,3 +1,5 @@
const DOWNCLS = 'fa-sort-down';
const UPCLS = 'fa-sort-up';
Template.boardMenuPopup.events({
'click .js-rename-board': Popup.open('boardChangeTitle'),
'click .js-custom-fields'() {
@@ -80,7 +82,25 @@ BlazeComponent.extendComponent({
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return currentBoard && currentBoard.stars >= 2;
},
showSort() {
return Meteor.user().hasSortBy();
},
directionClass() {
return this.currentDirection() === -1 ? DOWNCLS : UPCLS;
},
changeDirection() {
const direction = 0 - this.currentDirection() === -1 ? '-' : '';
Meteor.call('setListSortBy', direction + this.currentListSortBy());
},
currentDirection() {
return Meteor.user().getListSortByDirection();
},
currentListSortBy() {
return Meteor.user().getListSortBy();
},
listSortShortDesc() {
return `list-label-short-${this.currentListSortBy()}`;
},
events() {
return [
{
@@ -118,6 +138,16 @@ BlazeComponent.extendComponent({
'click .js-open-filter-view'() {
Sidebar.setView('filter');
},
'click .js-open-sort-view'(evt) {
const target = evt.target;
if (target.tagName === 'I') {
// click on the text, popup choices
this.changeDirection();
} else {
// change the sort order
Popup.open('listsort')(evt);
}
},
'click .js-filter-reset'(event) {
event.stopPropagation();
Sidebar.setView();
@@ -277,3 +307,73 @@ BlazeComponent.extendComponent({
];
},
}).register('boardChangeWatchPopup');
BlazeComponent.extendComponent({
onCreated() {
//this.sortBy = new ReactiveVar();
////this.sortDirection = new ReactiveVar();
//this.setSortBy();
this.downClass = DOWNCLS;
this.upClass = UPCLS;
},
allowedSortValues() {
const types = [];
const pushed = {};
Meteor.user()
.getListSortTypes()
.forEach(type => {
const key = type.replace(/^-/, '');
if (pushed[key] === undefined) {
types.push({
name: key,
label: `list-label-${key}`,
shortLabel: `list-label-short-${key}`,
});
pushed[key] = 1;
}
});
return types;
},
Direction() {
return Meteor.user().getListSortByDirection() === -1
? this.downClass
: this.upClass;
},
sortby() {
return Meteor.user().getListSortBy();
},
setSortBy(type = null) {
const user = Meteor.user();
if (type === null) {
type = user._getListSortBy();
} else {
let value = '';
if (type.map) {
// is an array
value = (type[1] === -1 ? '-' : '') + type[0];
}
Meteor.call('setListSortBy', value);
}
//this.sortBy.set(type[0]);
//this.sortDirection.set(type[1]);
},
events() {
return [
{
'click .js-sort-by'(evt) {
evt.preventDefault();
const target = evt.target;
const sortby = target.getAttribute('name');
const down = !!target.querySelector(`.${this.upClass}`);
const direction = down ? -1 : 1;
this.setSortBy([sortby, direction]);
if (Utils.isMiniScreen) {
Popup.close();
}
},
},
];
},
}).register('listsortPopup');
+2
View File
@@ -131,6 +131,8 @@ Template.previewClipboardImagePopup.onRendered(() => {
direct(results);
},
});
} else {
direct(results);
}
}
};
+8 -8
View File
@@ -105,7 +105,7 @@ Template.dateBadge.helpers({
// editCardReceivedDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated();
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getReceived() &&
this.date.set(moment(this.data().getReceived()));
}
@@ -122,7 +122,7 @@ Template.dateBadge.helpers({
// editCardStartDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated();
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getStart() && this.date.set(moment(this.data().getStart()));
}
@@ -148,7 +148,7 @@ Template.dateBadge.helpers({
// editCardDueDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated();
super.onCreated('1970-01-01 17:00:00');
this.data().getDue() && this.date.set(moment(this.data().getDue()));
}
@@ -171,7 +171,7 @@ Template.dateBadge.helpers({
// editCardEndDatePopup
(class extends DatePicker {
onCreated() {
super.onCreated();
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
this.data().getEnd() && this.date.set(moment(this.data().getEnd()));
}
@@ -237,7 +237,7 @@ class CardReceivedDate extends CardDate {
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)) ||
(startAt && theDate.isAfter(startAt)) ||
(endAt && theDate.isAfter(endAt)) ||
(dueAt && theDate.isAfter(dueAt))
)
@@ -344,9 +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 (!dueAt) classes += '';
else if (theDate.isBefore(dueAt)) classes += 'current';
else if (theDate.isAfter(dueAt)) classes += 'due';
return classes;
}
+66 -3
View File
@@ -4,9 +4,14 @@ template(name="cardDetails")
+inlinedForm(classNames="js-card-details-title")
+editCardTitleForm
else
a.fa.fa-times-thin.close-card-details.js-close-card-details
if currentUser.isBoardMember
a.fa.fa-navicon.card-details-menu.js-open-card-details-menu
unless isMiniScreen
a.fa.fa-times-thin.close-card-details.js-close-card-details
if currentUser.isBoardMember
a.fa.fa-navicon.card-details-menu.js-open-card-details-menu
if isMiniScreen
a.fa.fa-times-thin.close-card-details-mobile-web.js-close-card-details
if currentUser.isBoardMember
a.fa.fa-navicon.card-details-menu-mobile-web.js-open-card-details-menu
h2.card-details-title.js-card-title(
class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}")
+viewer
@@ -73,6 +78,16 @@ template(name="cardDetails")
a.member.add-member.card-details-item-add-button.js-add-members(title="{{_ 'card-members-title'}}")
i.fa.fa-plus
.card-details-item.card-details-item-assignees
h3.card-details-item-title {{_ 'assignee'}}
each getAssignees
+userAvatarAssignee(userId=this cardId=../_id)
| {{! XXX Hack to hide syntaxic coloration /// }}
if canModifyCard
unless assigneeSelected
a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}")
i.fa.fa-plus
.card-details-item.card-details-item-labels
h3.card-details-item-title {{_ 'labels'}}
a(class="{{#if canModifyCard}}js-add-labels{{else}}is-disabled{{/if}}" title="{{_ 'card-labels-title'}}")
@@ -296,6 +311,54 @@ template(name="cardMembersPopup")
if isCardMember
i.fa.fa-check
template(name="cardAssigneesPopup")
ul.pop-over-list.js-card-assignee-list
each board.activeMembers
li.item(class="{{#if isCardAssignee}}active{{/if}}")
a.name.js-select-assignee(href="#")
+userAvatar(userId=user._id)
span.full-name
= user.profile.fullname
| (<span class="username">{{ user.username }}</span>)
if isCardAssignee
i.fa.fa-check
template(name="userAvatarAssignee")
a.assignee.js-assignee(title="{{userData.profile.fullname}} ({{userData.username}})")
if userData.profile.avatarUrl
img.avatar.avatar-image(src="{{userData.profile.avatarUrl}}")
else
+userAvatarAssigneeInitials(userId=userData._id)
if showStatus
span.assignee-presence-status(class=presenceStatusClassName)
span.member-type(class=memberType)
unless isSandstorm
if showEdit
if $eq currentUser._id userData._id
a.edit-avatar.js-change-avatar
i.fa.fa-pencil
template(name="cardAssigneePopup")
.board-assignee-menu
.mini-profile-info
+userAvatar(userId=user._id showEdit=true)
.info
h3= user.profile.fullname
p.quiet @{{ user.username }}
ul.pop-over-list
if currentUser.isNotCommentOnly
li: a.js-remove-assignee {{_ 'remove-member-from-card'}}
if $eq currentUser._id user._id
with currentUser
li: a.js-edit-profile {{_ 'edit-profile'}}
template(name="userAvatarAssigneeInitials")
svg.avatar.avatar-assignee-initials(viewBox="0 0 {{viewPortWidth}} 15")
text(x="50%" y="13" text-anchor="middle")= initials
template(name="cardMorePopup")
p.quiet
span.clearfix
+142 -10
View File
@@ -121,11 +121,6 @@ BlazeComponent.extendComponent({
// Send Webhook but not create Activities records ---
const card = this.currentData();
const userId = Meteor.userId();
//console.log(`userId: ${userId}`);
//console.log(`cardId: ${card._id}`);
//console.log(`boardId: ${card.boardId}`);
//console.log(`listId: ${card.listId}`);
//console.log(`swimlaneId: ${card.swimlaneId}`);
const params = {
userId,
cardId: card._id,
@@ -134,16 +129,25 @@ BlazeComponent.extendComponent({
user: Meteor.user().username,
url: '',
};
//console.log('looking for integrations...');
const integrations = Integrations.find({
boardId: card.boardId,
type: 'outgoing-webhooks',
boardId: { $in: [card.boardId, Integrations.Const.GLOBAL_WEBHOOK_ID] },
enabled: true,
activities: { $in: ['CardDetailsRendered', 'all'] },
}).fetch();
//console.log(`Investigation length: ${integrations.length}`);
if (integrations.length > 0) {
Meteor.call('outgoingWebhooks', integrations, 'CardSelected', params);
integrations.forEach(integration => {
Meteor.call(
'outgoingWebhooks',
integration,
'CardSelected',
params,
() => {
return;
},
);
});
}
//-------------
}
@@ -309,6 +313,8 @@ BlazeComponent.extendComponent({
},
'click .js-member': Popup.open('cardMember'),
'click .js-add-members': Popup.open('cardMembers'),
'click .js-assignee': Popup.open('cardAssignee'),
'click .js-add-assignees': Popup.open('cardAssignees'),
'click .js-add-labels': Popup.open('cardLabels'),
'click .js-received-date': Popup.open('editCardReceivedDate'),
'click .js-start-date': Popup.open('editCardStartDate'),
@@ -342,6 +348,58 @@ BlazeComponent.extendComponent({
},
}).register('cardDetails');
Template.cardDetails.helpers({
userData() {
// We need to handle a special case for the search results provided by the
// `matteodem:easy-search` package. Since these results gets published in a
// separate collection, and not in the standard Meteor.Users collection as
// expected, we use a component parameter ("property") to distinguish the
// two cases.
const userCollection = this.esSearch ? ESSearchResults : Users;
return userCollection.findOne(this.userId, {
fields: {
profile: 1,
username: 1,
},
});
},
assigneeSelected() {
if (this.getAssignees().length === 0) {
return false;
} else {
return true;
}
},
memberType() {
const user = Users.findOne(this.userId);
return user && user.isBoardAdmin() ? 'admin' : 'normal';
},
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';
else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
return 'active';
else return 'idle';
},
});
Template.userAvatarAssigneeInitials.helpers({
initials() {
const user = Users.findOne(this.userId);
return user && user.getInitials();
},
viewPortWidth() {
const user = Users.findOne(this.userId);
return ((user && user.getInitials().length) || 1) * 12;
},
});
// We extends the normal InlinedForm component to support UnsavedEdits draft
// feature.
(class extends InlinedForm {
@@ -399,6 +457,7 @@ Template.cardDetailsActionsPopup.helpers({
Template.cardDetailsActionsPopup.events({
'click .js-members': Popup.open('cardMembers'),
'click .js-assignees': Popup.open('cardAssignees'),
'click .js-labels': Popup.open('cardLabels'),
'click .js-attachments': Popup.open('cardAttachments'),
'click .js-custom-fields': Popup.open('cardCustomFields'),
@@ -806,3 +865,76 @@ EscapeActions.register(
noClickEscapeOn: '.js-card-details,.board-sidebar,#header',
},
);
Template.cardAssigneesPopup.events({
'click .js-select-assignee'(event) {
const card = Cards.findOne(Session.get('currentCard'));
const assigneeId = this.userId;
card.toggleAssignee(assigneeId);
event.preventDefault();
},
});
Template.cardAssigneesPopup.helpers({
isCardAssignee() {
const card = Template.parentData();
const cardAssignees = card.getAssignees();
return _.contains(cardAssignees, this.userId);
},
user() {
return Users.findOne(this.userId);
},
});
Template.cardAssigneePopup.helpers({
userData() {
// We need to handle a special case for the search results provided by the
// `matteodem:easy-search` package. Since these results gets published in a
// separate collection, and not in the standard Meteor.Users collection as
// expected, we use a component parameter ("property") to distinguish the
// two cases.
const userCollection = this.esSearch ? ESSearchResults : Users;
return userCollection.findOne(this.userId, {
fields: {
profile: 1,
username: 1,
},
});
},
memberType() {
const user = Users.findOne(this.userId);
return user && user.isBoardAdmin() ? 'admin' : 'normal';
},
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';
else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
return 'active';
else return 'idle';
},
isCardAssignee() {
const card = Template.parentData();
const cardAssignees = card.getAssignees();
return _.contains(cardAssignees, this.userId);
},
user() {
return Users.findOne(this.userId);
},
});
Template.cardAssigneePopup.events({
'click .js-remove-assignee'() {
Cards.findOne(this.cardId).unassignAssignee(this.userId);
Popup.close();
},
'click .js-edit-profile': Popup.open('editProfile'),
});
+89 -1
View File
@@ -1,5 +1,80 @@
@import 'nib'
// Assignee, code copied from wekan/client/users/userAvatar.styl
avatar-radius = 50%
.assignee
border-radius: 3px
display: block
position: relative
float: left
height: 30px
width: @height
margin: 0 4px 4px 0
cursor: pointer
user-select: none
z-index: 1
text-decoration: none
border-radius: avatar-radius
.avatar
overflow: hidden
border-radius: avatar-radius
&.avatar-assignee-initials
height: 70%
width: @height
padding: 15%
background-color: #dbdbdb
color: #444444
position: absolute
&.avatar-image
height: 100%
width: @height
.assignee-presence-status
background-color: #b3b3b3
border: 1px solid #fff
border-radius: 50%
height: 7px
width: @height
position: absolute
right: -1px
bottom: -1px
border: 1px solid white
z-index: 15
&.active
background: #64c464
border-color: #daf1da
&.idle
background: #e4e467
border-color: #f7f7d4
&.disconnected
background: #bdbdbd
border-color: #ededed
&.pending
background: #e44242
border-color: #f1dada
&.add-assignee
display: flex
align-items: center
justify-content: center
box-shadow: 0 0 0 2px darken(white, 25%) inset
&:hover, &.is-active
box-shadow: 0 0 0 2px darken(white, 60%) inset
// Other card details
.card-details
padding: 0
flex-shrink: 0
@@ -32,7 +107,9 @@
border-bottom: 1px solid darken(white, 14%)
.close-card-details,
.card-details-menu
.card-details-menu,
.close-card-details-mobile-web,
.card-details-menu-mobile-web
float: right
.close-card-details
@@ -40,10 +117,20 @@
padding: 5px
margin-right: -8px
.close-card-details-mobile-web
font-size: 24px
padding: 5px
margin-right: 40px
.card-details-menu
font-size: 17px
padding: 10px
.card-details-menu-mobile-web
font-size: 17px
padding: 10px
margin-right: 30px
.card-details-watch
font-size: 17px
padding-left: 7px
@@ -93,6 +180,7 @@
margin-right: 0
&.card-details-item-labels,
&.card-details-item-members,
&.card-details-item-assignees,
&.card-details-item-received,
&.card-details-item-start,
&.card-details-item-due,
+15 -2
View File
@@ -3,6 +3,13 @@ template(name="minicard")
class="{{#if isLinkedCard}}linked-card{{/if}}"
class="{{#if isLinkedBoard}}linked-board{{/if}}"
class="minicard-{{colorClass}}")
if isMiniScreen
.handle
.fa.fa-arrows
unless isMiniScreen
if showDesktopDragHandles
.handle
.fa.fa-arrows
if cover
.minicard-cover(style="background-image: url('{{cover.url}}');")
if labels
@@ -15,8 +22,6 @@ template(name="minicard")
if hiddenMinicardLabelText
.minicard-label(class="card-label-{{color}}" title="{{name}}")
.minicard-title
.handle
.fa.fa-arrows
if $eq 'prefix-with-full-path' currentBoard.presentParentTask
.parent-prefix
| {{ parentString ' > ' }}
@@ -53,6 +58,8 @@ template(name="minicard")
if getDue
.date
+minicardDueDate
if getEnd
+minicardEndDate
if getSpentTime
.date
+cardSpentTime
@@ -69,6 +76,12 @@ template(name="minicard")
+viewer
= trueValue
if getAssignees
.minicard-assignees.js-minicard-assignees
each getAssignees
+userAvatar(userId=this)
hr
if getMembers
.minicard-members.js-minicard-members
each getMembers
+3
View File
@@ -26,6 +26,9 @@ BlazeComponent.extendComponent({
}).register('minicard');
Template.minicard.helpers({
showDesktopDragHandles() {
return Meteor.user().hasShowDesktopDragHandles();
},
hiddenMinicardLabelText() {
return Meteor.user().hasHiddenMinicardLabelText();
},
+13 -6
View File
@@ -105,8 +105,7 @@
right: 5px;
top: 5px;
display:none;
// @media only screen and (max-width: 1199px) {
@media only screen and (max-width: 800px) {
@media only screen {
display:block;
}
.fa-arrows
@@ -128,7 +127,7 @@
.badges
float: left
margin-top: 7px
color: darken(white, 80%)
color: darken(white, 50%)
&:empty
display: none
@@ -161,9 +160,10 @@
padding-left: 0px
line-height: 12px
.minicard-members
.minicard-members,
.minicard-assignees
float: right
margin: 2px -8px -2px 0
margin: 2px -8px 12px 0
.member
float: right
@@ -171,10 +171,17 @@
height: 28px
width: @height
.assignee
float: right
border-radius: 50%
height: 28px
width: @height
+ .badges
margin-top: 10px
.minicard-members:empty
.minicard-members:empty,
.minicard-assignees:empty
display: none
&.minicard-composer
+20 -7
View File
@@ -31,12 +31,6 @@ BlazeComponent.extendComponent({
const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)';
const $cards = this.$('.js-minicards');
if (Utils.isMiniScreen()) {
$('.js-minicards').sortable({
handle: '.handle',
});
}
$cards.sortable({
connectWith: '.js-minicards:not(.js-list-full)',
tolerance: 'pointer',
@@ -122,8 +116,21 @@ BlazeComponent.extendComponent({
// ugly touch event hotfix
enableClickOnTouch(itemsSelector);
// Disable drag-dropping if the current user is not a board member or is comment only
this.autorun(() => {
if (
Utils.isMiniScreen() ||
(!Utils.isMiniScreen() && Meteor.user().hasShowDesktopDragHandles())
) {
$cards.sortable({
handle: '.handle',
});
} else {
$cards.sortable({
handle: '.minicard',
});
}
// Disable drag-dropping if the current user is not a board member or is comment only
$cards.sortable('option', 'disabled', !userIsMember());
});
@@ -155,6 +162,12 @@ BlazeComponent.extendComponent({
},
}).register('list');
Template.list.helpers({
showDesktopDragHandles() {
return Meteor.user().hasShowDesktopDragHandles();
},
});
Template.miniList.events({
'click .js-select-list'() {
const listId = this._id;
+21 -5
View File
@@ -84,17 +84,16 @@
padding-left: 10px
color: #a6a6a6
.list-header-menu
position: absolute
padding: 27px 19px
margin-top: 1px
top: -7px
right: -7px
right: 3px
.list-header-plus-icon
color: #a6a6a6
margin-right: 10px
margin-right: 15px
.highlight
color: #ce1414
@@ -165,7 +164,16 @@
@media screen and (max-width: 800px)
.list-header-menu
margin-right: 30px
position: absolute
padding: 27px 19px
margin-top: 1px
top: -7px
margin-right: 7px
right: -3px
.list-header
.list-header-name
margin-left: 1.4rem
.mini-list
flex: 0 0 60px
@@ -221,9 +229,17 @@
padding: 7px
top: 50%
transform: translateY(-50%)
right: 17px
right: 47px
font-size: 20px
.list-header-handle
position: absolute
padding: 7px
top: 50%
transform: translateY(-50%)
right: 10px
font-size: 24px
.link-board-wrapper
display: flex
align-items: baseline
+7
View File
@@ -9,6 +9,7 @@ template(name="listHeader")
if currentList
a.list-header-left-icon.fa.fa-angle-left.js-unselect-list
h2.list-header-name(
title="{{ moment modifiedAt 'LLL' }}"
class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}js-open-inlined-form is-editable{{/unless}}{{/if}}")
+viewer
= title
@@ -29,16 +30,22 @@ template(name="listHeader")
if canSeeAddCard
a.js-add-card.fa.fa-plus.list-header-plus-icon
a.fa.fa-navicon.js-open-list-menu
a.list-header-handle.handle.fa.fa-arrows.js-list-handle
else
a.list-header-menu-icon.fa.fa-angle-right.js-select-list
a.list-header-handle.handle.fa.fa-arrows.js-list-handle
else if currentUser.isBoardMember
if isWatching
i.list-header-watch-icon.fa.fa-eye
div.list-header-menu
unless currentUser.isCommentOnly
if isBoardAdmin
a.fa.js-list-star.list-header-plus-icon(class="fa-star{{#unless starred}}-o{{/unless}}")
if canSeeAddCard
a.js-add-card.fa.fa-plus.list-header-plus-icon
a.fa.fa-navicon.js-open-list-menu
if showDesktopDragHandles
a.list-header-handle.handle.fa.fa-arrows.js-list-handle
template(name="editListTitleForm")
.list-composer
+24
View File
@@ -13,6 +13,20 @@ BlazeComponent.extendComponent({
);
},
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
starred(check = undefined) {
const list = Template.currentData();
const status = list.isStarred();
if (check === undefined) {
// just check
return status;
} else {
list.star(!status);
return !status;
}
},
editTitle(event) {
event.preventDefault();
const newTitle = this.childComponents('inlinedForm')[0]
@@ -61,6 +75,10 @@ BlazeComponent.extendComponent({
events() {
return [
{
'click .js-list-star'(event) {
event.preventDefault();
this.starred(!this.starred());
},
'click .js-open-list-menu': Popup.open('listAction'),
'click .js-add-card'(event) {
const listDom = $(event.target).parents(
@@ -80,6 +98,12 @@ BlazeComponent.extendComponent({
},
}).register('listHeader');
Template.listHeader.helpers({
showDesktopDragHandles() {
return Meteor.user().hasShowDesktopDragHandles();
},
});
Template.listActionPopup.helpers({
isWipLimitEnabled() {
return Template.currentData().getWipLimit('enabled');
+4 -2
View File
@@ -130,7 +130,8 @@ $popupWidth = 300px
.popup-container-depth-{depth}
transform: translateX(- depth * $popupWidth)
.select-members-list
.select-members-list,
.select-avatars-list
margin-bottom: 8px
.pop-over-list
@@ -230,7 +231,8 @@ $popupWidth = 300px
min-height: 56px
position: relative
.member
.member,
.avatar
position: absolute
top: 2px
left: 2px
@@ -4,6 +4,10 @@
and #each x in y constructors to fix this.
template(name="filterSidebar")
ul.sidebar-list
span {{_ 'list-filter-label'}}
form.js-list-filter
input(type="text")
ul.sidebar-list
li(class="{{#if Filter.labelIds.isSelected undefined}}active{{/if}}")
a.name.js-toggle-label-filter
@@ -4,6 +4,10 @@ BlazeComponent.extendComponent({
events() {
return [
{
'submit .js-list-filter'(evt) {
evt.preventDefault();
Filter.lists.set(this.find('.js-list-filter input').value.trim());
},
'click .js-toggle-label-filter'(evt) {
evt.preventDefault();
Filter.labelIds.toggle(this.currentData()._id);
@@ -2,6 +2,10 @@ template(name="searchSidebar")
form.js-search-term-form
input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus dir="auto")
.list-body.js-perfect-scrollbar
.minilists.clearfix.js-minilists
each (lists)
a.minilist-wrapper.js-minilist(href=absoluteUrl)
+minilist(this)
.minicards.clearfix.js-minicards
each (results)
a.minicard-wrapper.js-minicard(href=absoluteUrl)
@@ -8,6 +8,11 @@ BlazeComponent.extendComponent({
return currentBoard.searchCards(this.term.get());
},
lists() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return currentBoard.searchLists(this.term.get());
},
events() {
return [
{
@@ -16,6 +16,13 @@ template(name="swimlaneFixedHeader")
unless currentUser.isCommentOnly
a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon
a.fa.fa-navicon.js-open-swimlane-menu
unless isMiniScreen
unless showDesktopDragHandles
a.swimlane-header.handle.fa.fa-arrows.js-swimlane-header-handle
if showDesktopDragHandles
a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle
if isMiniScreen
a.swimlane-header-miniscreen-handle.handle.fa.fa-arrows.js-swimlane-header-handle
template(name="editSwimlaneTitleForm")
.list-composer
@@ -28,6 +28,12 @@ BlazeComponent.extendComponent({
},
}).register('swimlaneHeader');
Template.swimlaneHeader.helpers({
showDesktopDragHandles() {
return Meteor.user().hasShowDesktopDragHandles();
},
});
Template.swimlaneActionPopup.events({
'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'),
'click .js-close-swimlane'(event) {
+1 -1
View File
@@ -42,7 +42,7 @@ template(name="listsGroup")
+addListForm
template(name="addListForm")
.list.list-composer.js-list-composer
.list.list-composer.js-list-composer(class="{{#if isMiniScreen}}mini-list{{/if}}")
.list-header-add
+inlinedForm(autoclose=false)
input.list-name-input.full-line(type="text" placeholder="{{_ 'add-list'}}"
+34 -11
View File
@@ -56,7 +56,6 @@ function initSortable(boardComponent, $listsDom) {
$listsDom.sortable({
tolerance: 'pointer',
helper: 'clone',
handle: '.js-list-header',
items: '.js-list:not(.js-list-composer)',
placeholder: 'list placeholder',
distance: 7,
@@ -97,15 +96,29 @@ function initSortable(boardComponent, $listsDom) {
);
}
// Disable drag-dropping while in multi-selection mode, or if the current user
// is not a board member
boardComponent.autorun(() => {
if (
Utils.isMiniScreen() ||
(!Utils.isMiniScreen() && Meteor.user().hasShowDesktopDragHandles())
) {
$listsDom.sortable({
handle: '.js-list-handle',
});
} else {
$listsDom.sortable({
handle: '.js-list-header',
});
}
const $listDom = $listsDom;
if ($listDom.data('sortable')) {
$listsDom.sortable(
'option',
'disabled',
MultiSelection.isActive() || !userIsMember(),
// Disable drag-dropping when user is not member
!userIsMember(),
// Not disable drag-dropping while in multi-selection mode
// MultiSelection.isActive() || !userIsMember(),
);
}
});
@@ -151,13 +164,15 @@ BlazeComponent.extendComponent({
// 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',
];
const noDragInside = ['a', 'input', 'textarea', 'p'].concat(
Utils.isMiniScreen() ||
(!Utils.isMiniScreen() &&
Meteor.user().hasShowDesktopDragHandles())
? ['.js-list-handle', '.js-swimlane-header-handle']
: ['.js-list-header'],
);
if (
$(evt.target).closest(noDragInside.join(',')).length === 0 &&
this.$('.swimlane').prop('clientHeight') > evt.offsetY
@@ -233,6 +248,9 @@ BlazeComponent.extendComponent({
}).register('addListForm');
Template.swimlane.helpers({
showDesktopDragHandles() {
return Meteor.user().hasShowDesktopDragHandles();
},
canSeeAddList() {
return (
Meteor.user() &&
@@ -253,6 +271,11 @@ BlazeComponent.extendComponent({
return false;
}
}
if (Filter.lists._isActive()) {
if (!list.title.match(Filter.lists.getRegexSelector())) {
return false;
}
}
if (Filter.hideEmpty.isSelected()) {
const swimlaneId = this.parentComponent()
.parentComponent()
@@ -50,6 +50,22 @@
margin-left: 5px
margin-right: 10px
.swimlane-header-handle
position: absolute
padding: 7px
top: 50%
transform: translateY(-50%)
left: 230px
font-size: 18px
.swimlane-header-miniscreen-handle
position: absolute
padding: 7px
top: 50%
transform: translateY(-50%)
left: 87vw
font-size: 24px
.list-group
height: 100%
+5
View File
@@ -78,6 +78,11 @@ template(name="changeSettingsPopup")
| {{_ 'hide-system-messages'}}
if hiddenSystemMessages
i.fa.fa-check
li
a.js-toggle-desktop-drag-handles
| {{_ 'show-desktop-drag-handles'}}
if showDesktopDragHandles
i.fa.fa-check
li
label.bold
| {{_ 'show-cards-minimum-count'}}
+6
View File
@@ -161,6 +161,9 @@ Template.changeLanguagePopup.events({
});
Template.changeSettingsPopup.helpers({
showDesktopDragHandles() {
return Meteor.user().hasShowDesktopDragHandles();
},
hiddenSystemMessages() {
return Meteor.user().hasHiddenSystemMessages();
},
@@ -170,6 +173,9 @@ Template.changeSettingsPopup.helpers({
});
Template.changeSettingsPopup.events({
'click .js-toggle-desktop-drag-handles'() {
Meteor.call('toggleDesktopDragHandles');
},
'click .js-toggle-system-messages'() {
Meteor.call('toggleSystemMessages');
},
+3 -2
View File
@@ -3,10 +3,11 @@ DatePicker = BlazeComponent.extendComponent({
return 'datepicker';
},
onCreated() {
onCreated(defaultTime = '1970-01-01 08:00:00') {
this.error = new ReactiveVar('');
this.card = this.data();
this.date = new ReactiveVar(moment.invalid());
this.defaultTime = defaultTime;
},
onRendered() {
@@ -26,7 +27,7 @@ DatePicker = BlazeComponent.extendComponent({
if (!timeInput.value) {
const currentHour = evt.date.getHours();
const defaultMoment = moment(
currentHour > 0 ? evt.date : '1970-01-01 08:00:00',
currentHour > 0 ? evt.date : this.defaultTime,
); // default to 8:00 am local time
timeInput.value = defaultMoment.format('LT');
}
+13 -1
View File
@@ -439,6 +439,14 @@ class AdvancedFilter {
const commands = this._filterToCommands();
return this._arrayToSelector(commands);
}
getRegexSelector() {
// generate a regex for filter list
this._dep.depend();
return new RegExp(
`^.*${this._filter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}.*$`,
'i',
);
}
}
// The global Filter object.
@@ -455,6 +463,7 @@ Filter = {
hideEmpty: new SetFilter(),
customFields: new SetFilter('_id'),
advanced: new AdvancedFilter(),
lists: new AdvancedFilter(), // we need the ability to filter list by name as well
_fields: ['labelIds', 'members', 'archive', 'hideEmpty', 'customFields'],
@@ -468,7 +477,9 @@ Filter = {
return (
_.any(this._fields, fieldName => {
return this[fieldName]._isActive();
}) || this.advanced._isActive()
}) ||
this.advanced._isActive() ||
this.lists._isActive()
);
},
@@ -533,6 +544,7 @@ Filter = {
const filter = this[fieldName];
filter.reset();
});
this.lists.reset();
this.advanced.reset();
this.resetExceptions();
},
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+15 -3
View File
@@ -300,8 +300,18 @@
"error-username-taken": "This username is already taken",
"error-email-taken": "Email has already been taken",
"export-board": "Export board",
"sort": "Sort",
"sort-desc": "Click to Sort List",
"list-sort-by": "Sort the List By:",
"list-label-modifiedAt": "Last Access Time",
"list-label-title": "Name of the List",
"list-label-sort": "Your Manual Order",
"list-label-short-modifiedAt": "(L)",
"list-label-short-title": "(N)",
"list-label-short-sort": "(M)",
"filter": "Filter",
"filter-cards": "Filter Cards",
"filter-cards": "Filter Cards or Lists",
"list-filter-label": "Filter List by Title",
"filter-clear": "Clear filter",
"filter-no-label": "No label",
"filter-no-member": "No member",
@@ -426,7 +436,7 @@
"save": "Save",
"search": "Search",
"rules": "Rules",
"search-cards": "Search from card titles and descriptions on this board",
"search-cards": "Search from card/list titles and descriptions on this board",
"search-example": "Text to search for?",
"select-color": "Select Color",
"set-wip-limit-value": "Set a limit for the maximum number of tasks in this list",
@@ -740,5 +750,7 @@
"delete-user-confirm-popup": "Are you sure you want to delete this account? There is no undo.",
"accounts-allowUserDelete": "Allow users to self delete their account",
"hide-minicard-label-text": "Hide minicard label text",
"show-desktop-drag-handles": "Show desktop drag handles"
"show-desktop-drag-handles": "Show desktop drag handles",
"assignee": "Assignee",
"cardAssigneesPopup-title": "Assignee"
}
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+15 -3
View File
@@ -300,8 +300,18 @@
"error-username-taken": "Ce nom d'utilisateur est déjà utilisé",
"error-email-taken": "Cette adresse mail est déjà utilisée",
"export-board": "Exporter le tableau",
"sort": "Tri",
"sort-desc": "Cliquez pour trier la liste",
"list-sort-by": "Trier la liste par:",
"list-label-modifiedAt": "Dernier accès",
"list-label-title": "Nom de liste",
"list-label-sort": "Votre manuel",
"list-label-short-modifiedAt": "(D)",
"list-label-short-title": "(N)",
"list-label-short-sort": "(M)",
"filter": "Filtrer",
"filter-cards": "Filtrer les cartes",
"filter-cards": "Filtrer les cartes ou listes",
"list-filter-label": "Filtrer la liste par titre",
"filter-clear": "Supprimer les filtres",
"filter-no-label": "Aucune étiquette",
"filter-no-member": "Aucun participant",
@@ -426,7 +436,7 @@
"save": "Enregistrer",
"search": "Chercher",
"rules": "Règles",
"search-cards": "Rechercher parmi les titres et descriptions des cartes de ce tableau",
"search-cards": "Chercher selon les titres de carte/liste et descriptions de ce tableau",
"search-example": "Texte à rechercher ?",
"select-color": "Sélectionner une couleur",
"set-wip-limit-value": "Définit une limite maximale au nombre de cartes de cette liste",
@@ -737,5 +747,7 @@
"delete-user-confirm-popup": "Êtes-vous sûr de vouloir supprimer ce compte ? Cette opération ne peut pas être annulée. ",
"accounts-allowUserDelete": "Autoriser les utilisateurs à supprimer leur compte",
"hide-minicard-label-text": "Cacher le label de la minicarte",
"show-desktop-drag-handles": "Voir les poignées de déplacement du bureau"
"show-desktop-drag-handles": "Voir les poignées de déplacement du bureau",
"assignee": "Cessionnaire",
"cardAssigneesPopup-title": "Cessionnaire"
}
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+48 -36
View File
@@ -89,7 +89,7 @@
"added": "Dodano",
"addMemberPopup-title": "Člani",
"admin": "Administrator",
"admin-desc": "Lahko gleda in ureja kartice, odstrani člane in spreminja nastavitve table.",
"admin-desc": "Lahko gleda in ureja kartice, odstrani člane ter spreminja nastavitve table.",
"admin-announcement": "Najava",
"admin-announcement-active": "Aktivna vse-sistemska najava",
"admin-announcement-title": "Najava od administratorja",
@@ -100,12 +100,12 @@
"app-is-offline": "Nalaganje, prosimo počakajte. Osveževanje strani bo povzročilo izgubo podatkov. Če nalaganje ne deluje, preverite, ali se strežnik ni ustavil.",
"archive": "Premakni v arhiv",
"archive-all": "Premakni vse v arhiv",
"archive-board": "Premakni tablo v arhiv",
"archive-card": "Premakni kartico v arhiv",
"archive-list": "Premakni seznam v arhiv",
"archive-swimlane": "Premakni plavalno stezo v arhiv",
"archive-selection": "Premakni označeno v arhiv",
"archiveBoardPopup-title": "Premakni tablo v arhiv?",
"archive-board": "Arhiviraj tablo",
"archive-card": "Arhiviraj kartico",
"archive-list": "Arhiviraj seznam",
"archive-swimlane": "Arhiviraj plavalno stezo",
"archive-selection": "Arhiviraj označeno",
"archiveBoardPopup-title": "Arhiviraj tablo?",
"archived-items": "Arhiv",
"archived-boards": "Table v arhivu",
"restore-board": "Obnovi tablo",
@@ -142,8 +142,8 @@
"card-archived": "Kartica je premaknjena v arhiv.",
"board-archived": "Tabla je premaknjena v arhiv.",
"card-comments-title": "Ta kartica ima %s komentar.",
"card-delete-notice": "Brisanje je trajno. Izgubili boste vsa dejanja povezana s to kartico.",
"card-delete-pop": "Vsa dejanja bodo odstranjena iz vira dejavnosti in kartice ne boste mogli znova odpreti. Razveljavitve ni.",
"card-delete-notice": "Brisanje je trajno. Izgubili boste vsa dejanja, povezana s kartico.",
"card-delete-pop": "Vsa dejanja bodo odstranjena iz zgodovine dejavnosti. Kartice ne boste mogli znova odpreti. Razveljavitve ni.",
"card-delete-suggest-archive": "Kartico lahko premaknete v arhiv, da jo odstranite s table in ohranite dejavnost.",
"card-due": "Rok",
"card-due-on": "Rok",
@@ -188,7 +188,7 @@
"clipboard": "Odložišče ali povleci & spusti",
"close": "Zapri",
"close-board": "Zapri tablo",
"close-board-pop": "Tablo boste lahko obnovili s klikom na gumb »Arhiviraj« na začetni glavi.",
"close-board-pop": "Tablo boste lahko obnovili s klikom na gumb »Arhiviraj« na vstopni strani.",
"color-black": "črna",
"color-blue": "modra",
"color-crimson": "temno rdeča",
@@ -229,7 +229,7 @@
"searchElementPopup-title": "Išči",
"copyCardPopup-title": "Kopiraj kartico",
"copyChecklistToManyCardsPopup-title": "Kopiraj predlogo kontrolnega seznama na več kartic",
"copyChecklistToManyCardsPopup-instructions": "Naslovi ciljnih kartic in opisi v tem JSON formatu",
"copyChecklistToManyCardsPopup-instructions": "Naslovi ciljnih kartic in opisi v JSON formatu",
"copyChecklistToManyCardsPopup-format": "[ {\"naslov\": \"Naslov prve kartice\", \"opis\":\"Opis prve kartice\"}, {\"naslov\":\"Opis druge kartice\",\"opis\":\"Opis druge kartice\"},{\"naslov\":\"Naslov zadnje kartice\",\"opis\":\"Opis zadnje kartice\"} ]",
"create": "Ustvari",
"createBoardPopup-title": "Ustvari tablo",
@@ -289,8 +289,8 @@
"email-verifyEmail-text": "Pozdravljeni __user__,\n\nDa preverite e-poštni naslov za vaš uporabniški račun, kliknite na spodnjo povezavo.\n\n__url__\n\nHvala.",
"enable-wip-limit": "Vklopi omejitev št. kartic",
"error-board-doesNotExist": "Ta tabla ne obstaja",
"error-board-notAdmin": "Če želite to narediti, morate biti skrbnik te table",
"error-board-notAMember": "Če želite to narediti, morate biti član te table",
"error-board-notAdmin": "Nimate administrativnih pravic za tablo.",
"error-board-notAMember": "Niste član table.",
"error-json-malformed": "Vaše besedilo ni veljaven JSON",
"error-json-schema": "Vaši JSON podatki ne vsebujejo pravilnih informacij v ustreznem formatu",
"error-list-doesNotExist": "Seznam ne obstaja",
@@ -300,8 +300,18 @@
"error-username-taken": "To up. ime že obstaja",
"error-email-taken": "E-poštni naslov je že zaseden",
"export-board": "Izvozi tablo",
"sort": "Sortiraj",
"sort-desc": "Klikni za sortiranje seznama",
"list-sort-by": "Sortiraj po:",
"list-label-modifiedAt": "Nazadnje dostopano",
"list-label-title": "Ime seznama",
"list-label-sort": "Ročno nastavljen vrstni red",
"list-label-short-modifiedAt": "(N)",
"list-label-short-title": "(I)",
"list-label-short-sort": "(R)",
"filter": "Filtriraj",
"filter-cards": "Filtriraj kartice",
"filter-cards": "Filtriraj kartice ali sezname",
"list-filter-label": "Filtriraj seznam po imenu",
"filter-clear": "Počisti filter",
"filter-no-label": "Brez oznake",
"filter-no-member": "Brez člana",
@@ -344,19 +354,19 @@
"invalid-user": "Neveljaven uporabnik",
"joined": "se je pridružil",
"just-invited": "Povabljeni ste k tej tabli",
"keyboard-shortcuts": "Bližnjične tipke",
"keyboard-shortcuts": "Bližnjice",
"label-create": "Ustvari Oznako",
"label-default": "%s oznaka (privzeto)",
"label-delete-pop": "Razveljavitve ni. To bo odstranilo to oznako iz vseh kartic in izbrisalo njeno zgodovino.",
"label-delete-pop": "Razveljavitve ni. To bo odstranilo oznako iz vseh kartic in izbrisalo njeno zgodovino.",
"labels": "Oznake",
"language": "Jezik",
"last-admin-desc": "Ne morete zamenjati vlog, ker mora obstajati vsaj en admin.",
"leave-board": "Zapusti tablo",
"leave-board-pop": "Ste prepričani, da želite zapustiti tablo __boardTitle__? Odstranjeni boste iz vseh kartic na tej tabli.",
"leaveBoardPopup-title": "Zapusti tablo ?",
"link-card": "Poveži s to kartico",
"list-archive-cards": "Premakni vse kartice v tem seznamu v arhiv",
"list-archive-cards-pop": "To bo odstranilo vse kartice tega seznama iz table. Da si ogledate kartice v arhivu in jih vrnete na tablo, kliknite \"Meni\" > \"arhiv\".",
"link-card": "Poveži s kartico",
"list-archive-cards": "Arhiviraj vse kartice v seznamu",
"list-archive-cards-pop": "To bo odstranilo vse kartice tega seznama. Za ogled in vrnitev kartic iz arhiva na tablo, kliknite \"Meni\" > \"arhiv\".",
"list-move-cards": "Premakni vse kartice na seznamu",
"list-select-cards": "Izberi vse kartice na seznamu",
"set-color-list": "Nastavi barvo",
@@ -365,7 +375,7 @@
"swimlaneAddPopup-title": "Dodaj plavalno stezo spodaj",
"listImportCardPopup-title": "Uvozi Trello kartico",
"listMorePopup-title": "Več",
"link-list": "Poveži s tem seznamom",
"link-list": "Poveži s seznamom",
"list-delete-pop": "Vsa dejanja bodo odstranjena iz vira dejavnosti in seznama ne boste mogli obnoviti. Razveljavitve ni.",
"list-delete-suggest-archive": "Lahko premaknete seznam v arhiv, da ga odstranite iz table in ohranite dejavnosti.",
"lists": "Seznami",
@@ -384,7 +394,7 @@
"multi-selection": "Multi-Izbira",
"multi-selection-on": "Multi-Izbira je omogočena",
"muted": "Utišano",
"muted-info": "O spremembah na tej tabli nikoli ne boste obveščeni",
"muted-info": "O spremembah na tej tabli ne boste prejemali obvestil.",
"my-boards": "Moje Table",
"name": "Ime",
"no-archived-cards": "Ni kartic v arhivu",
@@ -398,7 +408,7 @@
"notify-watch": "Prejemajte posodobitve opazovanih tabel, seznamov ali kartic",
"optional": "opcijsko",
"or": "ali",
"page-maybe-private": "Ta stran je mogoče privatna. Verjetno si jo lahko ogledate po<a href='%s'>prijavi</a>.",
"page-maybe-private": "Ta stran je morda privatna. Verjetno si jo lahko ogledate po<a href='%s'>prijavi</a>.",
"page-not-found": "Stran ne obstaja.",
"password": "Geslo",
"paste-or-dragdrop": "prilepi ali povleci & spusti datoteko slike (samo slika)",
@@ -407,10 +417,10 @@
"previewAttachedImagePopup-title": "Predogled",
"previewClipboardImagePopup-title": "Predogled",
"private": "Zasebno",
"private-desc": "Ta tabla je zasebna. Samo dodani uporabniki lahko vidijo ali urejajo vsebino.",
"private-desc": "Ta tabla je zasebna. Vsebino lahko vidijo ali urejajo samo dodani uporabniki.",
"profile": "Profil",
"public": "Javno",
"public-desc": "Ta tabla je javna. Vidna je vsakomur s povezavo do table in bo prikazana v zadetkih iskalnikov kot Google. Samo uporabniki table jo lahko urejajo.",
"public-desc": "Ta tabla je javna. Vidna je vsakomur s povezavo do table in bo prikazana v zadetkih iskalnikov kot Google. Urejajo jo lahko samo člani table.",
"quick-access-description": "Če tablo označite z zvezdico, bo tukaj dodana bližnjica.",
"remove-cover": "Odstrani ovitek",
"remove-from-board": "Odstrani iz table",
@@ -426,30 +436,30 @@
"save": "Shrani",
"search": "Išči",
"rules": "Pravila",
"search-cards": "Išči po imenih kartic in opisih na tej tabli",
"search-cards": "Išči po imenih seznamov/kartic in opisov v tej tabli",
"search-example": "Besedilo za iskanje?",
"select-color": "Izberi barvo",
"set-wip-limit-value": "Nastavi omejitev maksimalnega števila opravil v tem seznamu",
"setWipLimitPopup-title": "Nastavi omejitev št. kartic",
"set-wip-limit-value": "Omeji maksimalno število opravil v seznamu",
"setWipLimitPopup-title": "Omeji število kartic",
"shortcut-assign-self": "Dodeli sebe k trenutni kartici",
"shortcut-autocomplete-emoji": "Samodokončaj emoji",
"shortcut-autocomplete-members": "Samodokončaj člane",
"shortcut-clear-filters": "Počisti vse filtre",
"shortcut-close-dialog": "Zapri dialog",
"shortcut-filter-my-cards": "Filtriraj moje kartice",
"shortcut-show-shortcuts": "Prikaži ta seznam bližnjic",
"shortcut-show-shortcuts": "Prikaži seznam bližnjic",
"shortcut-toggle-filterbar": "Preklopi stransko vrstico za filter",
"shortcut-toggle-sidebar": "Preklopi stransko vrstico table",
"show-cards-minimum-count": "Prikaži število kartic, če seznam vsebuje več kot",
"sidebar-open": "Odpri stransko vrstico",
"sidebar-close": "Zapri stransko vrstico",
"signupPopup-title": "Ustvari up. račun",
"star-board-title": "Kliknite, da označite to tablo z zvezdico. Prikazana bo na vrhu vašega seznama tabel.",
"star-board-title": "Označite tablo z zvezdico, da bo prikazana na vrhu v seznamu tabel.",
"starred-boards": "Table z zvezdico",
"starred-boards-description": "Table z zvezdico se prikažejo na vrhu vašega seznama tabel.",
"subscribe": "Naročite se",
"team": "Skupina",
"this-board": "to tablo",
"this-board": "tablo",
"this-card": "kartico",
"spent-time-hours": "Porabljen čas (ure)",
"overtime-hours": "Presežen čas (ure)",
@@ -459,7 +469,7 @@
"time": "Čas",
"title": "Naslov",
"tracking": "Sledenje",
"tracking-info": "Obveščeni boste o vseh spremembah kartic, kjer sodelujete kot lastnik ali član.",
"tracking-info": "Obveščeni boste o vseh spremembah nad karticami, kjer ste lastnik ali član.",
"type": "Tip",
"unassign-member": "Odjavi člana",
"unsaved-description": "Imate neshranjen opis.",
@@ -468,7 +478,7 @@
"upload-avatar": "Naloži avatar",
"uploaded-avatar": "Naložil avatar",
"username": "Up. ime",
"view-it": "Oglej",
"view-it": "Poglej",
"warn-list-archived": "opozorilo: ta kartica je v seznamu v arhivu",
"watch": "Opazuj",
"watching": "Opazuje",
@@ -482,7 +492,7 @@
"board-templates-swimlane": "Predloge table",
"what-to-do": "Kaj želite storiti?",
"wipLimitErrorPopup-title": "Neveljaven limit št. kartic",
"wipLimitErrorPopup-dialog-pt1": "Število opravil v tem seznamu je višje od definiranega limita št. kartic.",
"wipLimitErrorPopup-dialog-pt1": "Število opravil v seznamu je višje od limita št. kartic.",
"wipLimitErrorPopup-dialog-pt2": "Prosimo premaknite nekaj opravil iz tega seznama ali nastavite višji limit št. kartic.",
"admin-panel": "Skrbniška plošča",
"settings": "Nastavitve",
@@ -570,8 +580,8 @@
"queue": "Čakalna vrsta",
"subtask-settings": "Nastavitve podopravil",
"boardSubtaskSettingsPopup-title": "Nastavitve podopravil table",
"show-subtasks-field": "Dovoli pod-poravila na karticah",
"deposit-subtasks-board": "Deponiraj podopravila na tole tablo:",
"show-subtasks-field": "Dovoli podopravila na karticah",
"deposit-subtasks-board": "Deponiraj podopravila na tablo:",
"deposit-subtasks-list": "Ciljni seznam za deponirana podopravila:",
"show-parent-in-minicard": "Pokaži starša na mini-kartici:",
"prefix-with-full-path": "Predpona s celotno potjo",
@@ -737,5 +747,7 @@
"delete-user-confirm-popup": "Ali ste prepričani, da želite izbrisati ta račun? Razveljavitve ni.",
"accounts-allowUserDelete": "Dovoli uporabnikom, da sami izbrišejo svoj račun",
"hide-minicard-label-text": "Skrij besedilo oznak na karticah",
"show-desktop-drag-handles": "Pokaži ročke za povleko na namizju"
"show-desktop-drag-handles": "Pokaži ročke za povleko na namizju",
"assignee": "Dodeljen član",
"cardAssigneesPopup-title": "Dodeljen član"
}
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+752 -740
View File
File diff suppressed because it is too large. Load diff
+17
View File
@@ -409,6 +409,23 @@ Boards.helpers({
},
lists() {
const enabled = Meteor.user().hasSortBy();
return enabled ? this.newestLists() : this.draggableLists();
},
newestLists() {
// sorted lists from newest to the oldest, by its creation date or its cards' last modification date
const value = Meteor.user()._getListSortBy();
const sortKey = { starred: -1, [value[0]]: value[1] }; // [["starred",-1],value];
return Lists.find(
{
boardId: this._id,
archived: false,
},
{ sort: sortKey },
);
},
draggableLists() {
return Lists.find({ boardId: this._id }, { sort: { sort: 1 } });
},
+190 -3
View File
@@ -203,6 +203,15 @@ Cards.attachSchema(
optional: true,
defaultValue: [],
},
assignees: {
/**
* who is assignee of the card (user ID),
* maximum one ID of assignee in array.
*/
type: [String],
optional: true,
defaultValue: [],
},
receivedAt: {
/**
* Date the card was received
@@ -411,6 +420,10 @@ Cards.helpers({
return _.contains(this.getMembers(), memberId);
},
isAssignee(assigneeId) {
return _.contains(this.getAssignees(), assigneeId);
},
activities() {
if (this.isLinkedCard()) {
return Activities.find(
@@ -745,6 +758,20 @@ Cards.helpers({
}
},
getAssignees() {
if (this.isLinkedCard()) {
const card = Cards.findOne({ _id: this.linkedId });
return card.assignees;
} else if (this.isLinkedBoard()) {
const board = Boards.findOne({ _id: this.linkedId });
return board.activeMembers().map(assignee => {
return assignee.userId;
});
} else {
return this.assignees;
}
},
assignMember(memberId) {
if (this.isLinkedCard()) {
return Cards.update(
@@ -762,6 +789,23 @@ Cards.helpers({
}
},
assignAssignee(assigneeId) {
if (this.isLinkedCard()) {
return Cards.update(
{ _id: this.linkedId },
{ $addToSet: { assignees: assigneeId } },
);
} else if (this.isLinkedBoard()) {
const board = Boards.findOne({ _id: this.linkedId });
return board.addAssignee(assigneeId);
} else {
return Cards.update(
{ _id: this._id },
{ $addToSet: { assignees: assigneeId } },
);
}
},
unassignMember(memberId) {
if (this.isLinkedCard()) {
return Cards.update(
@@ -776,6 +820,23 @@ Cards.helpers({
}
},
unassignAssignee(assigneeId) {
if (this.isLinkedCard()) {
return Cards.update(
{ _id: this.linkedId },
{ $pull: { assignees: assigneeId } },
);
} else if (this.isLinkedBoard()) {
const board = Boards.findOne({ _id: this.linkedId });
return board.removeAssignee(assigneeId);
} else {
return Cards.update(
{ _id: this._id },
{ $pull: { assignees: assigneeId } },
);
}
},
toggleMember(memberId) {
if (this.getMembers() && this.getMembers().indexOf(memberId) > -1) {
return this.unassignMember(memberId);
@@ -784,6 +845,14 @@ Cards.helpers({
}
},
toggleAssignee(assigneeId) {
if (this.getAssignees() && this.getAssignees().indexOf(assigneeId) > -1) {
return this.unassignAssignee(assigneeId);
} else {
return this.assignAssignee(assigneeId);
}
},
getReceived() {
if (this.isLinkedCard()) {
const card = Cards.findOne({ _id: this.linkedId });
@@ -1126,6 +1195,19 @@ Cards.mutations({
};
},
assignAssignee(assigneeId) {
// If there is not any assignee, allow one assignee, not more.
if (this.getAssignees().length === 0) {
return {
$addToSet: {
assignees: assigneeId,
},
};
} else {
return false;
}
},
unassignMember(memberId) {
return {
$pull: {
@@ -1134,6 +1216,14 @@ Cards.mutations({
};
},
unassignAssignee(assigneeId) {
return {
$pull: {
assignees: assigneeId,
},
};
},
toggleMember(memberId) {
if (this.members && this.members.indexOf(memberId) > -1) {
return this.unassignMember(memberId);
@@ -1142,6 +1232,14 @@ Cards.mutations({
}
},
toggleAssignee(assigneeId) {
if (this.assignees && this.assignees.indexOf(assigneeId) > -1) {
return this.unassignAssignee(assigneeId);
} else {
return this.assignAssignee(assigneeId);
}
},
assignCustomField(customFieldId) {
return {
$addToSet: {
@@ -1436,6 +1534,46 @@ function cardMembers(userId, doc, fieldNames, modifier) {
}
}
function cardAssignees(userId, doc, fieldNames, modifier) {
if (!_.contains(fieldNames, 'assignees')) return;
let assigneeId;
// Say hello to the new assignee
if (modifier.$addToSet && modifier.$addToSet.assignees) {
assigneeId = modifier.$addToSet.assignees;
const username = Users.findOne(assigneeId).username;
if (!_.contains(doc.assignees, assigneeId)) {
Activities.insert({
userId,
username,
activityType: 'joinAssignee',
boardId: doc.boardId,
cardId: doc._id,
assigneeId,
listId: doc.listId,
swimlaneId: doc.swimlaneId,
});
}
}
// Say goodbye to the former assignee
if (modifier.$pull && modifier.$pull.assignees) {
assigneeId = modifier.$pull.assignees;
const username = Users.findOne(assigneeId).username;
// Check that the former assignee is assignee of the card
if (_.contains(doc.assignees, assigneeId)) {
Activities.insert({
userId,
username,
activityType: 'unjoinAssignee',
boardId: doc.boardId,
cardId: doc._id,
assigneeId,
listId: doc.listId,
swimlaneId: doc.swimlaneId,
});
}
}
}
function cardLabels(userId, doc, fieldNames, modifier) {
if (!_.contains(fieldNames, 'labelIds')) return;
let labelId;
@@ -1673,6 +1811,12 @@ if (Meteor.isServer) {
updateActivities(doc, fieldNames, modifier);
});
// Add a new activity if we add or remove a assignee to the card
Cards.before.update((userId, doc, fieldNames, modifier) => {
cardAssignees(userId, doc, fieldNames, modifier);
updateActivities(doc, fieldNames, modifier);
});
// Add a new activity if we add or remove a label to the card
Cards.before.update((userId, doc, fieldNames, modifier) => {
cardLabels(userId, doc, fieldNames, modifier);
@@ -1695,6 +1839,26 @@ if (Meteor.isServer) {
const oldvalue = doc[action] || '';
const activityType = `a-${action}`;
const card = Cards.findOne(doc._id);
const list = card.list();
if (list) {
// change list modifiedAt, when user modified the key values in timingaction array, if it's endAt, put the modifiedAt of list back to one year ago for sorting purpose
const modifiedAt = new Date(
new Date(value).getTime() -
(action === 'endAt' ? 365 * 24 * 3600 * 1e3 : 0),
); // set it as 1 year before
const boardId = list.boardId;
Lists.direct.update(
{
_id: list._id,
},
{
$set: {
modifiedAt,
boardId,
},
},
);
}
const username = Users.findOne(userId).username;
const activity = {
userId,
@@ -1832,6 +1996,7 @@ if (Meteor.isServer) {
* @param {string} description the description of the new card
* @param {string} swimlaneId the swimlane ID of the new card
* @param {string} [members] the member IDs list of the new card
* @param {string} [assignees] the array of maximum one ID of assignee of the new card
* @return_type {_id: string}
*/
JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function(
@@ -1853,6 +2018,7 @@ if (Meteor.isServer) {
_id: req.body.authorId,
});
const members = req.body.members || [req.body.authorId];
const assignees = req.body.assignees;
if (typeof check !== 'undefined') {
const id = Cards.direct.insert({
title: req.body.title,
@@ -1864,6 +2030,7 @@ if (Meteor.isServer) {
swimlaneId: req.body.swimlaneId,
sort: currentCards.count(),
members,
assignees,
});
JsonRoutes.sendResult(res, {
code: 200,
@@ -1915,6 +2082,7 @@ if (Meteor.isServer) {
* @param {string} [labelIds] the new list of label IDs attached to the card
* @param {string} [swimlaneId] the new swimlane ID of the card
* @param {string} [members] the new list of member IDs attached to the card
* @param {string} [assignees] the array of maximum one ID of assignee attached to the card
* @param {string} [requestedBy] the new requestedBy field of the card
* @param {string} [assignedBy] the new assignedBy field of the card
* @param {string} [receivedAt] the new receivedAt field of the card
@@ -2175,6 +2343,25 @@ if (Meteor.isServer) {
{ $set: { members: newmembers } },
);
}
if (req.body.hasOwnProperty('assignees')) {
let newassignees = req.body.assignees;
if (_.isString(newassignees)) {
if (newassignees === '') {
newassignees = null;
} else {
newassignees = [newassignees];
}
}
Cards.direct.update(
{
_id: paramCardId,
listId: paramListId,
boardId: paramBoardId,
archived: false,
},
{ $set: { assignees: newassignees } },
);
}
if (req.body.hasOwnProperty('swimlaneId')) {
const newParamSwimlaneId = req.body.swimlaneId;
Cards.direct.update(
@@ -2217,14 +2404,14 @@ if (Meteor.isServer) {
const paramListId = req.params.listId;
const paramCardId = req.params.cardId;
const card = Cards.findOne({
_id: paramCardId,
});
Cards.direct.remove({
_id: paramCardId,
listId: paramListId,
boardId: paramBoardId,
});
const card = Cards.find({
_id: paramCardId,
});
cardRemover(req.body.authorId, card);
JsonRoutes.sendResult(res, {
code: 200,
+16 -1
View File
@@ -50,12 +50,18 @@ if (Meteor.isServer) {
});
}
// exporter maybe is broken since Gridfs introduced, add fs and path
export class Exporter {
constructor(boardId) {
this._boardId = boardId;
}
build() {
const fs = Npm.require('fs');
const os = Npm.require('os');
const path = Npm.require('path');
const byBoard = { boardId: this._boardId };
const byBoardNoLinked = {
boardId: this._boardId,
@@ -106,7 +112,7 @@ export class Exporter {
);
result.subtaskItems.push(
...Cards.find({
parentid: card._id,
parentId: card._id,
}).fetch(),
);
});
@@ -134,6 +140,11 @@ export class Exporter {
const getBase64Data = function(doc, callback) {
let buffer = new Buffer(0);
// callback has the form function (err, res) {}
const tmpFile = path.join(
os.tmpdir(),
`tmpexport${process.pid}${Math.random()}`,
);
const tmpWriteable = fs.createWriteStream(tmpFile);
const readStream = doc.createReadStream();
readStream.on('data', function(chunk) {
buffer = Buffer.concat([buffer, chunk]);
@@ -143,8 +154,12 @@ export class Exporter {
});
readStream.on('end', function() {
// done
fs.unlink(tmpFile, () => {
//ignored
});
callback(null, buffer.toString('base64'));
});
readStream.pipe(tmpWriteable);
};
const getBase64DataSync = Meteor.wrapAsync(getBase64Data);
result.attachments = Attachments.find(byBoard)
+25 -1
View File
@@ -11,6 +11,15 @@ Lists.attachSchema(
*/
type: String,
},
starred: {
/**
* if a list is stared
* then we put it on the top
*/
type: Boolean,
optional: true,
defaultValue: false,
},
archived: {
/**
* is the list archived
@@ -81,10 +90,14 @@ Lists.attachSchema(
denyUpdate: false,
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert || this.isUpsert || this.isUpdate) {
// this is redundant with updatedAt
/*if (this.isInsert || this.isUpsert || this.isUpdate) {
return new Date();
} else {
this.unset();
}*/
if (!this.isSet) {
return new Date();
}
},
},
@@ -252,6 +265,14 @@ Lists.helpers({
return this.type === 'template-list';
},
isStarred() {
return this.starred === true;
},
absoluteUrl() {
const card = Cards.findOne({ listId: this._id });
return card && card.absoluteUrl();
},
remove() {
Lists.remove({ _id: this._id });
},
@@ -261,6 +282,9 @@ Lists.mutations({
rename(title) {
return { $set: { title } };
},
star(enable = true) {
return { $set: { starred: !!enable } };
},
archive() {
if (this.isTemplateList()) {
+15
View File
@@ -174,6 +174,21 @@ Swimlanes.helpers({
},
lists() {
const enabled = Meteor.user().hasSortBy();
return enabled ? this.newestLists() : this.draggableLists();
},
newestLists() {
// sorted lists from newest to the oldest, by its creation date or its cards' last modification date
return Lists.find(
{
boardId: this.boardId,
swimlaneId: { $in: [this._id, ''] },
archived: false,
},
{ sort: { modifiedAt: -1 } },
);
},
draggableLists() {
return Lists.find(
{
boardId: this.boardId,
+82
View File
@@ -4,6 +4,16 @@ const isSandstorm =
Meteor.settings && Meteor.settings.public && Meteor.settings.public.sandstorm;
Users = Meteor.users;
const allowedSortValues = [
'-modifiedAt',
'modifiedAt',
'-title',
'title',
'-sort',
'sort',
];
const defaultSortBy = allowedSortValues[0];
/**
* A User in wekan
*/
@@ -109,6 +119,13 @@ Users.attachSchema(
type: String,
optional: true,
},
'profile.showDesktopDragHandles': {
/**
* does the user want to hide system messages?
*/
type: Boolean,
optional: true,
},
'profile.hiddenSystemMessages': {
/**
* does the user want to hide system messages?
@@ -184,6 +201,15 @@ Users.attachSchema(
'board-view-cal',
],
},
'profile.listSortBy': {
/**
* default sort list for user
*/
type: String,
optional: true,
defaultValue: defaultSortBy,
allowedValues: allowedSortValues,
},
'profile.templatesBoardId': {
/**
* Reference to the templates board
@@ -358,6 +384,31 @@ Users.helpers({
return _.contains(invitedBoards, boardId);
},
_getListSortBy() {
const profile = this.profile || {};
const sortBy = profile.listSortBy || defaultSortBy;
const keyPattern = /^(-{0,1})(.*$)/;
const ret = [];
if (keyPattern.exec(sortBy)) {
ret[0] = RegExp.$2;
ret[1] = RegExp.$1 ? -1 : 1;
}
return ret;
},
hasSortBy() {
// if user has dragHandle, then we can let user to choose sort list by different order
return this.hasShowDesktopDragHandles();
},
getListSortBy() {
return this._getListSortBy()[0];
},
getListSortTypes() {
return allowedSortValues;
},
getListSortByDirection() {
return this._getListSortBy()[1];
},
hasTag(tag) {
const { tags = [] } = this.profile || {};
return _.contains(tags, tag);
@@ -368,6 +419,11 @@ Users.helpers({
return _.contains(notifications, activityId);
},
hasShowDesktopDragHandles() {
const profile = this.profile || {};
return profile.showDesktopDragHandles || false;
},
hasHiddenSystemMessages() {
const profile = this.profile || {};
return profile.hiddenSystemMessages || false;
@@ -473,6 +529,21 @@ Users.mutations({
else this.addTag(tag);
},
setListSortBy(value) {
return {
$set: {
'profile.listSortBy': value,
},
};
},
toggleDesktopHandles(value = false) {
return {
$set: {
'profile.showDesktopDragHandles': !value,
},
};
},
toggleSystem(value = false) {
return {
$set: {
@@ -549,6 +620,14 @@ Meteor.methods({
Users.update(userId, { $set: { username } });
}
},
setListSortBy(value) {
check(value, String);
Meteor.user().setListSortBy(value);
},
toggleDesktopDragHandles() {
const user = Meteor.user();
user.toggleDesktopHandles(user.hasShowDesktopDragHandles());
},
toggleSystemMessages() {
const user = Meteor.user();
user.toggleSystem(user.hasHiddenSystemMessages());
@@ -776,6 +855,9 @@ if (Meteor.isServer) {
if (Meteor.isServer) {
// Let mongoDB ensure username unicity
Meteor.startup(() => {
allowedSortValues.forEach(value => {
Lists._collection._ensureIndex(value);
});
Users._collection._ensureIndex({ modifiedAt: -1 });
Users._collection._ensureIndex(
{
+138 -40
View File
@@ -3,9 +3,15 @@
import argparse
import esprima
import json
import logging
import os
import re
import sys
import traceback
logger = logging.getLogger(__name__)
err_context = 3
def get_req_body_elems(obj, elems):
@@ -156,16 +162,25 @@ class EntryPoint(object):
def compute_path(self):
return self._path.value.rstrip('/')
def error(self, message):
def log(self, message, level):
if self._raw_doc is None:
sys.stderr.write('in {},\n'.format(self.schema.name))
sys.stderr.write('{}\n'.format(message))
logger.log(level, 'in {},'.format(self.schema.name))
logger.log(level, message)
return
sys.stderr.write('in {}, lines {}-{}\n'.format(self.schema.name,
self._raw_doc.loc.start.line,
self._raw_doc.loc.end.line))
sys.stderr.write('{}\n'.format(self._raw_doc.value))
sys.stderr.write('{}\n'.format(message))
logger.log(level, 'in {}, lines {}-{}'.format(self.schema.name,
self._raw_doc.loc.start.line,
self._raw_doc.loc.end.line))
logger.log(level, self._raw_doc.value)
logger.log(level, message)
def error(self, message):
return self.log(message, logging.ERROR)
def warn(self, message):
return self.log(message, logging.WARNING)
def info(self, message):
return self.log(message, logging.INFO)
@property
def doc(self):
@@ -235,7 +250,7 @@ class EntryPoint(object):
if name.startswith('{'):
param_type = name.strip('{}')
if param_type not in ['string', 'number', 'boolean', 'integer', 'array', 'file']:
self.error('Warning, unknown type {}\n allowed values: string, number, boolean, integer, array, file'.format(param_type))
self.warn('unknown type {}\n allowed values: string, number, boolean, integer, array, file'.format(param_type))
try:
name, desc = desc.split(maxsplit=1)
except ValueError:
@@ -248,7 +263,7 @@ class EntryPoint(object):
# we should not have 2 identical parameter names
if tag in params:
self.error('Warning, overwriting parameter {}'.format(name))
self.warn('overwriting parameter {}'.format(name))
params[name] = (param_type, optional, desc)
@@ -278,7 +293,7 @@ class EntryPoint(object):
# we should not have 2 identical tags but @param or @tag
if tag in self._doc:
self.error('Warning, overwriting tag {}'.format(tag))
self.warn('overwriting tag {}'.format(tag))
self._doc[tag] = data
@@ -301,7 +316,7 @@ class EntryPoint(object):
current_data = ''
line = data
else:
self.error('Unknown tag {}, ignoring'.format(tag))
self.info('Unknown tag {}, ignoring'.format(tag))
current_data += line + '\n'
@@ -441,7 +456,7 @@ class EntryPoint(object):
class SchemaProperty(object):
def __init__(self, statement, schema):
def __init__(self, statement, schema, context):
self.schema = schema
self.statement = statement
self.name = statement.key.name or statement.key.value
@@ -449,22 +464,75 @@ class SchemaProperty(object):
self.blackbox = False
self.required = True
for p in statement.value.properties:
if p.key.name == 'type':
if p.value.type == 'Identifier':
self.type = p.value.name.lower()
elif p.value.type == 'ArrayExpression':
self.type = 'array'
self.elements = [e.name.lower() for e in p.value.elements]
try:
if p.key.name == 'type':
if p.value.type == 'Identifier':
self.type = p.value.name.lower()
elif p.value.type == 'ArrayExpression':
self.type = 'array'
self.elements = [e.name.lower() for e in p.value.elements]
elif p.key.name == 'allowedValues':
self.type = 'enum'
self.enum = [e.value.lower() for e in p.value.elements]
elif p.key.name == 'allowedValues':
self.type = 'enum'
if p.value.type == 'ArrayExpression':
self.enum = [e.value.lower() for e in p.value.elements]
elif p.value.type == 'Identifier':
# tree wide lookout for the identifier
def find_variable(elem, match):
if isinstance(elem, list):
for value in elem:
ret = find_variable(value, match)
if ret is not None:
return ret
elif p.key.name == 'blackbox':
self.blackbox = True
try:
items = elem.items()
except AttributeError:
return None
except TypeError:
return None
elif p.key.name == 'optional' and p.value.value:
self.required = False
if (elem.type == 'VariableDeclarator' and
elem.id.name == match):
return elem
for type, value in items:
ret = find_variable(value, match)
if ret is not None:
return ret
return None
elem = find_variable(context.program.body, p.value.name)
if elem.init.type != 'ArrayExpression':
raise TypeError('can not find "{}"'.format(p.value.name))
self.enum = [e.value.lower() for e in elem.init.elements]
elif p.key.name == 'blackbox':
self.blackbox = True
elif p.key.name == 'optional' and p.value.value:
self.required = False
except Exception:
input = ''
for line in range(p.loc.start.line - err_context, p.loc.end.line + 1 + err_context):
if line < p.loc.start.line or line > p.loc.end.line:
input += '. '
else:
input += '>>'
input += context.text_at(line, line)
input = ''.join(input)
logger.error('{}:{}-{} can not parse {}:\n{}'.format(context.path,
p.loc.start.line,
p.loc.end.line,
p.type,
input))
logger.error('esprima tree:\n{}'.format(p))
logger.error(traceback.format_exc())
sys.exit(1)
self._doc = None
self._raw_doc = None
@@ -574,7 +642,7 @@ class SchemaProperty(object):
class Schemas(object):
def __init__(self, data=None, jsdocs=None, name=None):
def __init__(self, context, data=None, jsdocs=None, name=None):
self.name = name
self._data = data
self.fields = None
@@ -585,7 +653,7 @@ class Schemas(object):
self.name = data.expression.callee.object.name
content = data.expression.arguments[0].arguments[0]
self.fields = [SchemaProperty(p, self) for p in content.properties]
self.fields = [SchemaProperty(p, self, context) for p in content.properties]
self._doc = None
self._raw_doc = None
@@ -665,6 +733,27 @@ class Schemas(object):
print(' - {}'.format(f))
class Context(object):
def __init__(self, path):
self.path = path
with open(path) as f:
self._txt = f.readlines()
data = ''.join(self._txt)
self.program = esprima.parseModule(data,
options={
'comment': True,
'loc': True
})
def txt_for(self, statement):
return self.text_at(statement.loc.start.line, statement.loc.end.line)
def text_at(self, begin, end):
return ''.join(self._txt[begin - 1:end])
def parse_schemas(schemas_dir):
schemas = {}
@@ -674,17 +763,19 @@ def parse_schemas(schemas_dir):
files.sort()
for filename in files:
path = os.path.join(root, filename)
with open(path) as f:
data = ''.join(f.readlines())
try:
# if the file failed, it's likely it doesn't contain a schema
program = esprima.parseModule(data, options={'comment': True, 'loc': True})
except:
continue
try:
# if the file failed, it's likely it doesn't contain a schema
context = Context(path)
except:
continue
current_schema = None
jsdocs = [c for c in program.comments
if c.type == 'Block' and c.value.startswith('*\n')]
program = context.program
current_schema = None
jsdocs = [c for c in program.comments
if c.type == 'Block' and c.value.startswith('*\n')]
try:
for statement in program.body:
@@ -697,7 +788,7 @@ def parse_schemas(schemas_dir):
statement.expression.arguments[0].type == 'NewExpression' and
statement.expression.arguments[0].callee.name == 'SimpleSchema'):
schema = Schemas(statement, jsdocs)
schema = Schemas(context, statement, jsdocs)
current_schema = schema.name
schemas[current_schema] = schema
@@ -717,7 +808,7 @@ def parse_schemas(schemas_dir):
if len(data) > 0:
if current_schema is None:
current_schema = filename
schemas[current_schema] = Schemas(name=current_schema)
schemas[current_schema] = Schemas(context, name=current_schema)
schema_entry_points = [EntryPoint(schemas[current_schema], d)
for d in data]
@@ -730,6 +821,13 @@ def parse_schemas(schemas_dir):
if j.loc.end.line + 1 == operation.loc.start.line]
if bool(jsdoc):
entry_point.doc = jsdoc[0]
except TypeError:
logger.warning(context.txt_for(statement))
logger.error('{}:{}-{} can not parse {}'.format(path,
statement.loc.start.line,
statement.loc.end.line,
statement.type))
raise
return schemas, entry_points
+35 -58
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.46.0",
"version": "v3.52.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -392,11 +392,6 @@
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
},
"buffer-shims": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
"integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E="
},
"bunyan": {
"version": "1.8.12",
"resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz",
@@ -2499,6 +2494,12 @@
"object-visit": "^1.0.0"
}
},
"memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
"optional": true
},
"meteor-node-stubs": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-0.4.1.tgz",
@@ -3119,62 +3120,20 @@
"optional": true
},
"mongodb": {
"version": "2.2.36",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.36.tgz",
"integrity": "sha512-P2SBLQ8Z0PVx71ngoXwo12+FiSfbNfGOClAao03/bant5DgLNkOPAck5IaJcEk4gKlQhDEURzfR3xuBG1/B+IA==",
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.3.3.tgz",
"integrity": "sha512-MdRnoOjstmnrKJsK8PY0PjP6fyF/SBS4R8coxmhsfEU7tQ46/J6j+aSHF2n4c2/H8B+Hc/Klbfp8vggZfI0mmA==",
"requires": {
"es6-promise": "3.2.1",
"mongodb-core": "2.1.20",
"readable-stream": "2.2.7"
},
"dependencies": {
"es6-promise": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
"integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q="
},
"process-nextick-args": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
},
"readable-stream": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz",
"integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=",
"requires": {
"buffer-shims": "~1.0.0",
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "~1.0.0",
"process-nextick-args": "~1.0.6",
"string_decoder": "~1.0.0",
"util-deprecate": "~1.0.1"
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"mongodb-core": {
"version": "2.1.20",
"resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz",
"integrity": "sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ==",
"requires": {
"bson": "~1.0.4",
"require_optional": "~1.0.0"
"bson": "^1.1.1",
"require_optional": "^1.0.1",
"safe-buffer": "^5.1.2",
"saslprep": "^1.0.0"
},
"dependencies": {
"bson": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz",
"integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg=="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz",
"integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg=="
}
}
},
@@ -4327,6 +4286,15 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
"optional": true,
"requires": {
"sparse-bitfield": "^3.0.3"
}
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
@@ -4571,6 +4539,15 @@
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"dev": true
},
"sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
"optional": true,
"requires": {
"memory-pager": "^1.0.2"
}
},
"spawn-sync": {
"version": "1.0.15",
"resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v3.46.0",
"version": "v3.52.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {
@@ -63,7 +63,7 @@
"gridfs-stream": "^0.5.3",
"ldapjs": "^1.0.2",
"meteor-node-stubs": "^0.4.1",
"mongodb": "^2.2.19",
"mongodb": "^3.3.3",
"os": "^0.1.1",
"page": "^1.8.6",
"qs": "^6.8.0",
+85 -2
View File
@@ -1524,7 +1524,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<ul class="toc-list-h1">
<li>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v3.46">Wekan REST API v3.46</a>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v3.52">Wekan REST API v3.52</a>
</li>
@@ -2017,7 +2017,7 @@ var n=this.pipeline.run(e.tokenizer(t)),r=new e.Vector,i=[],o=this._fields.reduc
<div class="page-wrapper">
<div class="dark-box"></div>
<div class="content">
<h1 id="wekan-rest-api">Wekan REST API v3.46</h1>
<h1 id="wekan-rest-api">Wekan REST API v3.52</h1>
<blockquote>
<p>Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.</p>
</blockquote>
@@ -9359,6 +9359,7 @@ System.out.println(response.toString());
</blockquote>
<pre class="highlight tab tab-json"><code>{
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"starred"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"boardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"swimlaneId"</span>: <span class="hljs-string">"string"</span>,
@@ -9879,6 +9880,7 @@ $.ajax({
<span class="hljs-keyword">const</span> inputBody = <span class="hljs-string">'{
"authorId": "string",
"members": "string",
"assignees": "string",
"title": "string",
"description": "string",
"swimlaneId": "string"
@@ -9981,6 +9983,7 @@ System.out.println(response.toString());
</blockquote>
<pre class="highlight tab tab-yaml"><code><span class="hljs-attr">authorId:</span> <span class="hljs-string">string</span>
<span class="hljs-attr">members:</span> <span class="hljs-string">string</span>
<span class="hljs-attr">assignees:</span> <span class="hljs-string">string</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">string</span>
<span class="hljs-attr">description:</span> <span class="hljs-string">string</span>
<span class="hljs-attr">swimlaneId:</span> <span class="hljs-string">string</span>
@@ -10034,6 +10037,13 @@ System.out.println(response.toString());
<td>the member IDs list of the new card</td>
</tr>
<tr>
<td>» assignees</td>
<td>body</td>
<td>string</td>
<td>false</td>
<td>the array of maximum one ID of assignee of the new card</td>
</tr>
<tr>
<td>» title</td>
<td>body</td>
<td>string</td>
@@ -10339,6 +10349,7 @@ $.ajax({
"isOverTime": "string",
"customFields": "string",
"members": "string",
"assignees": "string",
"swimlaneId": "string"
}'</span>;
<span class="hljs-keyword">const</span> headers = {
@@ -10449,6 +10460,7 @@ System.out.println(response.toString());
<span class="hljs-attr">isOverTime:</span> <span class="hljs-string">string</span>
<span class="hljs-attr">customFields:</span> <span class="hljs-string">string</span>
<span class="hljs-attr">members:</span> <span class="hljs-string">string</span>
<span class="hljs-attr">assignees:</span> <span class="hljs-string">string</span>
<span class="hljs-attr">swimlaneId:</span> <span class="hljs-string">string</span>
</code></pre>
@@ -10612,6 +10624,13 @@ System.out.println(response.toString());
<td>the members value</td>
</tr>
<tr>
<td>» assignees</td>
<td>body</td>
<td>string</td>
<td>true</td>
<td>the assignees value</td>
</tr>
<tr>
<td>» swimlaneId</td>
<td>body</td>
<td>string</td>
@@ -11602,6 +11621,7 @@ System.out.println(response.toString());
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"fullname"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"showDesktopDragHandles"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"hiddenSystemMessages"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"hiddenMinicardLabelText"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"initials"</span>: <span class="hljs-string">"string"</span>,
@@ -11618,6 +11638,7 @@ System.out.println(response.toString());
],
<span class="hljs-attr">"icode"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"boardView"</span>: <span class="hljs-string">"board-view-lists"</span>,
<span class="hljs-attr">"listSortBy"</span>: <span class="hljs-string">"-modifiedat"</span>,
<span class="hljs-attr">"templatesBoardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"cardTemplatesSwimlaneId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"listTemplatesSwimlaneId"</span>: <span class="hljs-string">"string"</span>,
@@ -12255,6 +12276,7 @@ System.out.println(response.toString());
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"fullname"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"showDesktopDragHandles"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"hiddenSystemMessages"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"hiddenMinicardLabelText"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"initials"</span>: <span class="hljs-string">"string"</span>,
@@ -12271,6 +12293,7 @@ System.out.println(response.toString());
],
<span class="hljs-attr">"icode"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"boardView"</span>: <span class="hljs-string">"board-view-lists"</span>,
<span class="hljs-attr">"listSortBy"</span>: <span class="hljs-string">"-modifiedat"</span>,
<span class="hljs-attr">"templatesBoardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"cardTemplatesSwimlaneId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"listTemplatesSwimlaneId"</span>: <span class="hljs-string">"string"</span>,
@@ -14159,6 +14182,9 @@ UserSecurity
<span class="hljs-attr">"members"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"assignees"</span>: [
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"receivedAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"startAt"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"dueAt"</span>: <span class="hljs-string">"string"</span>,
@@ -14305,6 +14331,13 @@ UserSecurity
<td>list of members (user IDs)</td>
</tr>
<tr>
<td>assignees</td>
<td>[string]|null</td>
<td>false</td>
<td>none</td>
<td>who is assignee of the card (user ID), maximum one ID of assignee in array.</td>
</tr>
<tr>
<td>receivedAt</td>
<td>string|null</td>
<td>false</td>
@@ -14917,6 +14950,7 @@ UserSecurity
<p><a id="schemalists"></a></p>
<pre class="highlight tab tab-json"><code>{
<span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"starred"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"archived"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"boardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"swimlaneId"</span>: <span class="hljs-string">"string"</span>,
@@ -14955,6 +14989,13 @@ UserSecurity
<td>the title of the list</td>
</tr>
<tr>
<td>starred</td>
<td>boolean|null</td>
<td>false</td>
<td>none</td>
<td>if a list is stared then we put it on the top</td>
</tr>
<tr>
<td>archived</td>
<td>boolean</td>
<td>true</td>
@@ -15395,6 +15436,7 @@ UserSecurity
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"fullname"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"showDesktopDragHandles"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"hiddenSystemMessages"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"hiddenMinicardLabelText"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"initials"</span>: <span class="hljs-string">"string"</span>,
@@ -15411,6 +15453,7 @@ UserSecurity
],
<span class="hljs-attr">"icode"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"boardView"</span>: <span class="hljs-string">"board-view-lists"</span>,
<span class="hljs-attr">"listSortBy"</span>: <span class="hljs-string">"-modifiedat"</span>,
<span class="hljs-attr">"templatesBoardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"cardTemplatesSwimlaneId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"listTemplatesSwimlaneId"</span>: <span class="hljs-string">"string"</span>,
@@ -15561,6 +15604,7 @@ UserSecurity
<span class="hljs-string">"string"</span>
],
<span class="hljs-attr">"fullname"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"showDesktopDragHandles"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"hiddenSystemMessages"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"hiddenMinicardLabelText"</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">"initials"</span>: <span class="hljs-string">"string"</span>,
@@ -15577,6 +15621,7 @@ UserSecurity
],
<span class="hljs-attr">"icode"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"boardView"</span>: <span class="hljs-string">"board-view-lists"</span>,
<span class="hljs-attr">"listSortBy"</span>: <span class="hljs-string">"-modifiedat"</span>,
<span class="hljs-attr">"templatesBoardId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"cardTemplatesSwimlaneId"</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">"listTemplatesSwimlaneId"</span>: <span class="hljs-string">"string"</span>,
@@ -15618,6 +15663,13 @@ UserSecurity
<td>full name of the user</td>
</tr>
<tr>
<td>showDesktopDragHandles</td>
<td>boolean</td>
<td>false</td>
<td>none</td>
<td>does the user want to hide system messages?</td>
</tr>
<tr>
<td>hiddenSystemMessages</td>
<td>boolean</td>
<td>false</td>
@@ -15688,6 +15740,13 @@ UserSecurity
<td>boardView field of the user</td>
</tr>
<tr>
<td>listSortBy</td>
<td>string</td>
<td>false</td>
<td>none</td>
<td>default sort list for user</td>
</tr>
<tr>
<td>templatesBoardId</td>
<td>string</td>
<td>true</td>
@@ -15738,6 +15797,30 @@ UserSecurity
<td>boardView</td>
<td>board-view-cal</td>
</tr>
<tr>
<td>listSortBy</td>
<td>-modifiedat</td>
</tr>
<tr>
<td>listSortBy</td>
<td>modifiedat</td>
</tr>
<tr>
<td>listSortBy</td>
<td>-title</td>
</tr>
<tr>
<td>listSortBy</td>
<td>title</td>
</tr>
<tr>
<td>listSortBy</td>
<td>-sort</td>
</tr>
<tr>
<td>listSortBy</td>
<td>sort</td>
</tr>
</tbody>
</table>
+42 -1
View File
@@ -1,7 +1,7 @@
swagger: '2.0'
info:
title: Wekan REST API
version: v3.46
version: v3.52
description: |
The REST API allows you to control and extend Wekan with ease.
@@ -1273,6 +1273,12 @@ paths:
the member IDs list of the new card
type: string
required: false
- name: assignees
in: formData
description: |
the array of maximum one ID of assignee of the new card
type: string
required: false
- name: title
in: formData
description: |
@@ -1438,6 +1444,11 @@ paths:
description: the members value
type: string
required: true
- name: assignees
in: formData
description: the assignees value
type: string
required: true
- name: swimlaneId
in: formData
description: the swimlaneId value
@@ -2354,6 +2365,15 @@ definitions:
type: string
x-nullable: true
x-nullable: true
assignees:
description: |
who is assignee of the card (user ID),
maximum one ID of assignee in array.
type: array
items:
type: string
x-nullable: true
x-nullable: true
receivedAt:
description: |
Date the card was received
@@ -2611,6 +2631,12 @@ definitions:
description: |
the title of the list
type: string
starred:
description: |
if a list is stared
then we put it on the top
type: boolean
x-nullable: true
archived:
description: |
is the list archived
@@ -2870,6 +2896,10 @@ definitions:
description: |
full name of the user
type: string
showDesktopDragHandles:
description: |
does the user want to hide system messages?
type: boolean
hiddenSystemMessages:
description: |
does the user want to hide system messages?
@@ -2923,6 +2953,17 @@ definitions:
- board-view-lists
- board-view-swimlanes
- board-view-cal
listSortBy:
description: |
default sort list for user
type: string
enum:
- -modifiedat
- modifiedat
- -title
- title
- -sort
- sort
templatesBoardId:
description: |
Reference to the templates board
+2 -2
View File
@@ -13,8 +13,8 @@ REM Install chocolatey
choco install -y git curl python2 dotnet4.5.2 nano mongodb-3 mongoclient meteor
curl -O https://nodejs.org/dist/v8.16.1/node-v8.16.1-x64.msi
call node-v8.16.1-x64.msi
curl -O https://nodejs.org/dist/v8.16.2/node-v8.16.2-x64.msi
call node-v8.16.2-x64.msi
call npm config -g set msvs_version 2015
call meteor npm config -g set msvs_version 2015
+1 -1
View File
@@ -79,7 +79,7 @@ do
curl -0 -L https://npmjs.org/install.sh | sudo sh
sudo chown -R $(id -u):$(id -g) $HOME/.npm
sudo npm -g install n
sudo n 8.16.1
sudo n 8.16.2
#curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
#sudo apt-get install -y nodejs
elif [[ "$OSTYPE" == "darwin"* ]]; then
Loaded 100 of 106 files, more files were not shown because too many files have changed in this diff. Show more