Compare commits

...
103 Commits
Author SHA1 Message Date
Lauri Ojansivu 46e47e3fc9 v4.69 2021-01-02 18:10:15 +02:00
Lauri Ojansivu d4b3dc7472 Update translations. 2021-01-02 17:54:13 +02:00
Lauri Ojansivu df47dcc3f3 Update ChangeLog. 2021-01-02 17:53:31 +02:00
Lauri Ojansivu bfc16fc544 Reorder My Cards to be first at menu.
Thanks to xet7 !
2021-01-02 17:50:05 +02:00
Lauri Ojansivu 991e1baffd Update translations. 2021-01-02 16:56:25 +02:00
Lauri Ojansivu cd54ced1b2 Update ChangeLog. 2021-01-02 16:55:58 +02:00
Lauri Ojansivu f88c3755e0 Merge branch 'jrsupplee-master' 2021-01-02 16:43:31 +02:00
Lauri Ojansivu 0592b0c56a Moved Public/Archive/Templates/etc options to click right top username Member Settings menu, where My Cards also is.
Thanks to xet7 !
2021-01-02 16:39:58 +02:00
John R. Supplee a0b72d0287 Merge branch 'master' of https://github.com/wekan/wekan 2021-01-02 00:17:31 +02:00
John R. Supplee 7a419c1563 My Cards development
* only find client side cards of the user
2021-01-02 00:17:03 +02:00
Lauri Ojansivu ea42a3763f Update translations. 2021-01-01 23:13:56 +02:00
John R. Supplee 0f6a60fa69 Merge branch 'master' of https://github.com/wekan/wekan 2021-01-01 22:04:04 +02:00
John R. Supplee a58b27e9b0 My Cards development
* always go to page
* use minicard for displaying cards
* change the icon for my cards menu option
2021-01-01 22:03:29 +02:00
Lauri Ojansivu cfdeaf2f5d Update ChangeLog. 2021-01-01 15:02:10 +02:00
Lauri Ojansivu b64cd358ed Teams/Organizations to Admin Panel. In Progress. Part 3.
Thanks to xet7 !

Related #802
2021-01-01 15:00:33 +02:00
Lauri Ojansivu 12034ab619 Update ChangeLog. 2021-01-01 14:59:58 +02:00
Lauri Ojansivu ad482d5cfb Teams/Organizations to Admin Panel. In Progress. Part 2.
Thanks to xet7 !

Related #802
2021-01-01 14:57:17 +02:00
John R. Supplee 885de88d35 more my cards
* add user menu entry (needs icon)
* format list
* add new translation slugs to English and Arabic
2021-01-01 01:06:42 +02:00
John R. Supplee 223fb78bd8 Merge branch 'master' of https://github.com/wekan/wekan 2020-12-31 19:15:59 +02:00
John R. Supplee 077e78d37c My Cards development
first prototype
2020-12-31 19:14:55 +02:00
Lauri Ojansivu e49d3923d0 Update ChangeLog. 2020-12-30 20:50:36 +02:00
Lauri Ojansivu 65795a673e Merge pull request #3412 from mfilser/master
Swimlane + and = Icons resized for better handling at mobile view
2020-12-30 20:46:46 +02:00
Martin Filser e39e0c9a85 Swimlane + and = Icons resized for better handling at mobile view 2020-12-30 19:40:10 +01:00
Lauri Ojansivu f35b042324 Update translations. 2020-12-30 19:15:03 +02:00
Lauri Ojansivu 9c8d5c2613 Merge branch 'mfilser-new_checklistitem_textarea_autoresize' 2020-12-30 19:12:40 +02:00
Martin Filser 03bfd9a2b5 New Checklistitems are now autoresized too
- also using for autoresize now:
  verron:autosize
2020-12-30 16:51:56 +01:00
Lauri Ojansivu 07aa1fd276 v4.68 2020-12-29 21:16:15 +02:00
Lauri Ojansivu 5aca681b36 Update translations. 2020-12-29 20:39:31 +02:00
Lauri Ojansivu 94f466102e Update ChangeLog. 2020-12-29 17:02:28 +02:00
Lauri Ojansivu 08866ae20b Merge pull request #3408 from mfilser/checklistitem_textarea_autoresize
Checklist-Items, Autoresize the textarea vertically to fit the user-input
2020-12-29 17:02:07 +02:00
Lauri Ojansivu f73bdcdfb6 Merge pull request #3407 from mfilser/master
Checklist-Items, Drag-Drop Handle now at the left side
2020-12-29 16:57:15 +02:00
Martin Filser 6410012384 Checklist-Items, Autoresize the textarea vertically to fit the user-input 2020-12-29 15:23:16 +01:00
Martin Filser 93a24aaef8 Checklist-Items, Drag-Drop Handle now at the left side
- Drag handle is not visible at long checklists, even with:
  padding-right: 20px
  Depending of all the screen sizes out there this is the most secure
  way to get around this and the drag handle is always visible

- first fix was at this commit: a8453657c9
2020-12-29 15:15:54 +01:00
Lauri Ojansivu 688a31877b v4.67 2020-12-29 15:53:35 +02:00
Lauri Ojansivu e9b9f204a5 Update translations. 2020-12-29 15:48:16 +02:00
Lauri Ojansivu dfee3a7a7c Update ChangeLog. 2020-12-29 15:38:22 +02:00
Lauri Ojansivu d03e2170dd Allow to edit email verified and initials at Admin Panel/People/People.
Thanks to xet7 !

Fixes #1426
2020-12-29 15:33:14 +02:00
Lauri Ojansivu d0cdc33c19 Update ChangeLog. 2020-12-29 13:39:39 +02:00
Lauri Ojansivu b7e1521e0d Merge branch 'mfilser-master' 2020-12-29 13:37:41 +02:00
Lauri Ojansivu ed12cfe160 Merge branch 'master' of https://github.com/mfilser/wekan into mfilser-master 2020-12-29 13:37:01 +02:00
Martin Filser 5578949bf5 Checklist Mini-Screen, appendTo: 'parent' not necessary anymore
- obsolete since commit c7808c5c03
2020-12-29 11:31:21 +01:00
Lauri Ojansivu 5603d159b3 Update ChangeLog. 2020-12-28 21:12:41 +02:00
Lauri Ojansivu 9e2093d6ae Teams/Organizations to Admin Panel. In Progress.
Thanks to xet7 !

Related #802
2020-12-28 21:08:27 +02:00
Lauri Ojansivu b7137e617e v4.66 2020-12-27 03:14:34 +02:00
Lauri Ojansivu 2c33f71ba7 Update translations. 2020-12-27 03:11:17 +02:00
Lauri Ojansivu 56c2c24638 Update ChangeLog. 2020-12-27 03:09:08 +02:00
Lauri Ojansivu a8453657c9 Fix Mobile miniscreen: Drag handle not visible in long checklist item text.
Thanks to xet7 !

Fixes #3402
2020-12-27 03:06:33 +02:00
Lauri Ojansivu 55ff74de95 v4.65 2020-12-26 12:52:56 +02:00
Lauri Ojansivu e2f7b1ec05 Update translations. 2020-12-26 12:48:33 +02:00
Lauri Ojansivu 1cd2d28a3b Update ChangeLog. 2020-12-26 12:46:30 +02:00
Lauri Ojansivu c7808c5c03 Fixed Drag and drop between checklists closes the card sometimes on Firefox.
xet7 thanks mfilser about [similar fix of appendTo parent](https://github.com/wekan/wekan/pull/3342)
that did work here too to fix this.

Thanks to mfilser and xet7 !

Fixes #2280
2020-12-26 12:38:24 +02:00
Lauri Ojansivu 3ed9f07015 v4.64 2020-12-24 17:08:56 +02:00
Lauri Ojansivu 676d2c46a1 Update translations. 2020-12-24 17:04:38 +02:00
Lauri Ojansivu b5f1a6b08b Update ChangeLog. 2020-12-24 14:09:50 +02:00
Lauri Ojansivu d9616b6d94 Merge branch 'jasontamez-master' 2020-12-24 14:07:46 +02:00
Jason Tamez 4812cb6412 attempt to fix a visual problem in Dark theme 2020-12-23 11:38:11 -06:00
Lauri Ojansivu 9e60a23845 v4.63 2020-12-21 18:42:25 +02:00
Lauri Ojansivu 6cca39af1b Update translations. 2020-12-21 18:37:24 +02:00
Lauri Ojansivu 7ffbe2ab5e Update ChangeLog. 2020-12-21 18:35:02 +02:00
Lauri Ojansivu 28850e5510 Fixed Remove Cover button gives JS error.
Thanks to tsukasa1989 and xet7 !

Fixes #3400
2020-12-21 18:32:00 +02:00
Lauri Ojansivu d62bed1536 v4.62 2020-12-18 05:58:33 +02:00
Lauri Ojansivu b19cf01a3a Update translations. 2020-12-18 05:52:27 +02:00
Lauri Ojansivu 39dece1e25 Update ChangeLog. 2020-12-18 05:48:41 +02:00
Lauri Ojansivu 61ae62a83a Board: When removing member from board, remove also from assignees.
Admin Panel/People: 1) Allow edit user that does not have email address.
2) When creating new user, require username and email address, and save also fullname.
3) Some in progress code for deleting user, that does not work correctly yet, so deleting user is not enabled yet.

Thanks to airtraxx and xet7.

Related #3396
2020-12-18 05:46:04 +02:00
Lauri Ojansivu 775f0d9fe6 Update ChangeLog. 2020-12-17 21:39:27 +02:00
Lauri Ojansivu 53a925cf7f Fix delete board button not visible.
Thanks to airtraxx and xet7 !

Related #3396
2020-12-17 21:37:18 +02:00
Lauri Ojansivu 6bf33a5578 Update ChangeLog. 2020-12-17 21:30:52 +02:00
Lauri Ojansivu 7f3c4acf62 Add some permission code, to see does it fix something.
Thanks to xet7 !

Related #3377
2020-12-17 21:27:02 +02:00
Lauri Ojansivu 8481c791d7 Update ChangeLog. 2020-12-17 18:59:36 +02:00
Lauri Ojansivu 9dd0fb88d6 Fix Move card from a board to another does not work anymore.
Thanks to lezioul and xet7 !

Fixes wekan/wekan-snap#141
2020-12-17 18:56:04 +02:00
Lauri Ojansivu 9b004d75c7 Update ChangeLog. 2020-12-17 17:56:11 +02:00
Lauri Ojansivu 86c7fbd717 Merge pull request #3395 from daniel-eder/fix/clone-board-binary-attachments
Treat unknown attachment types as binary on board import/clone
2020-12-17 17:36:02 +02:00
Daniel Eder 6bd7f40511 Treat unknown attachment types as binary on board import/clone
Fixes missing attachments and even missing
2020-12-17 11:10:30 +02:00
Lauri Ojansivu a82257f0b1 v4.61 2020-12-16 23:41:40 +02:00
Lauri Ojansivu ee26f32a20 Update translations. 2020-12-16 23:36:03 +02:00
Lauri Ojansivu 7df3d52635 Update ChangeLog. 2020-12-16 23:34:07 +02:00
Lauri Ojansivu f9ba17177e Allow normal user to delete checklist item.
Thanks to Samunosuke and xet7 !

Related #3377
2020-12-16 23:30:57 +02:00
Lauri Ojansivu ab4941390b Update translations. 2020-12-15 22:45:11 +02:00
Lauri Ojansivu 11d044ede9 Update ChangeLog. 2020-12-15 22:37:38 +02:00
Lauri Ojansivu 3c406d955e Removed cookie code that is not in use.
Thanks to xet7 !
2020-12-15 22:34:57 +02:00
Lauri Ojansivu ea37dd5e1d v4.60 2020-12-15 12:22:17 +02:00
Lauri Ojansivu fd7225d861 Update translations. 2020-12-15 12:14:02 +02:00
Lauri Ojansivu e0bd22e674 Update ChangeLog. 2020-12-15 12:11:43 +02:00
Lauri Ojansivu 89332cefc5 Merge branch 'master' of github.com:wekan/wekan 2020-12-15 12:09:09 +02:00
Lauri Ojansivu 5172f64b72 Update ChangeLog. 2020-12-15 12:08:53 +02:00
Lauri Ojansivu 6cb4b9fe4a Prevent normal user deleting or modifying too much.
Allow normal user to export board. Part 2.

Thanks to Samunosuke, pgh2357 and xet7 !

Related #3377
2020-12-15 12:05:54 +02:00
Lauri Ojansivu c978f55c56 Update ChangeLog. 2020-12-15 12:04:31 +02:00
Lauri Ojansivu 4a205fcfcb Prevent normal user deleting or modifying too much.
Allow normal user to export board.

Thanks to Samunosuke, pgh2357 and xet7 !

Related #3377
2020-12-15 11:52:57 +02:00
Lauri Ojansivu 2e1e703e35 Merge pull request #3393 from wekan/dependabot/npm_and_yarn/ini-1.3.7
Bump ini from 1.3.5 to 1.3.7
2020-12-12 17:38:08 +02:00
dependabot[bot] a75c162483 Bump ini from 1.3.5 to 1.3.7
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-11 19:53:26 +00:00
Lauri Ojansivu f6c0700633 v4.59 2020-12-10 12:16:44 +02:00
Lauri Ojansivu dece7ddf13 Update translations. 2020-12-10 12:11:13 +02:00
Lauri Ojansivu d06bcd9dcc Update ChangeLog. 2020-12-10 12:08:27 +02:00
Lauri Ojansivu ee7d82c006 Merge pull request #3389 from daniel-eder/fix/clone-board-checklist-items
Fix not all checklist items being imported/cloned
2020-12-10 12:06:28 +02:00
Daniel Eder b777f7f2af Fix not all checklist items being imported/cloned 2020-12-10 10:47:57 +02:00
Lauri Ojansivu fe87b9928c v4.58 2020-12-09 16:20:55 +02:00
Lauri Ojansivu fb36709047 Update translations. 2020-12-09 16:13:45 +02:00
Lauri Ojansivu 73aaccb6dd Update ChangeLog. 2020-12-09 16:10:39 +02:00
Lauri Ojansivu 1fe0059402 Merge branch 'daniel-eder-fix/clone-board' 2020-12-09 16:07:19 +02:00
Daniel Eder 0c12c45080 Fix missing subtasks when cloning board 2020-12-09 15:51:45 +02:00
Daniel Eder a6c48329ef Fix missing assignee assignment when cloning or importing board 2020-12-09 15:06:56 +02:00
Daniel Eder a3cd1b89ff Fix missing member assignments when cloning board 2020-12-09 15:02:50 +02:00
Daniel Eder 7a08f42edb Fix missing custom fields when cloning board 2020-12-09 14:01:33 +02:00
107 changed files with 40458 additions and 38006 deletions

No files matched your search

+165
View File
@@ -1,3 +1,168 @@
# v4.69 2021-01-02 Wekan release
This release adds the following new features:
- Teams/Organizations to Admin Panel. In Progress.
[Part 2](https://github.com/wekan/wekan/commit/ad482d5cfb72591f1b5c749c3c0156000dbf660a).
[Part 3](https://github.com/wekan/wekan/commit/b64cd358ed0af4395357423ad172b8dac9dc3178).
Thanks to xet7.
- [My Cards](https://github.com/wekan/wekan/pull/3413).
Thanks to jrsupplee.
and adds the following UI changes:
- [Moved Public/Archive/Templates/etc options to click right top username Member Settings menu, where My Cards also
is](https://github.com/wekan/wekan/commit/0592b0c56ac372c87dea17f0a090e7d7569430d1).
Thanks to xet7.
- [Reorder My Cards to be first at menu](https://github.com/wekan/wekan/commit/bfc16fc5442e8cc8c3cc03df992d5b1d1724338b).
Thanks to xet7.
and fixes the following bugs:
- [New Checklistitems are now autoresized too](https://github.com/wekan/wekan/pull/3411).
Thanks to mfilser.
- [Swimlane + and = Icons resized for better handling at mobile view](https://github.com/wekan/wekan/pull/3412).
Thanks to mfilser.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.68 2020-12-29 Wekan release
This release fixes the following bugs:
- [Checklist-Items, Drag-Drop Handle now at the left side](https://github.com/wekan/wekan/pull/3407).
Thanks to mfilser.
- [Checklist-Items, Autoresize the textarea vertically to fit the user-input](https://github.com/wekan/wekan/pull/3408).
Thanks to mfilser.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.67 2020-12-29 Wekan release
This release adds the following new features:
- Teams/Organizations to Admin Panel. In Progress.
[Part 1](https://github.com/wekan/wekan/commit/9e2093d6aed38e66fc4d63823315c9382e013a32).
Thanks to xet7.
and fixes the following bugs:
- [Checklist Mini-Screen, appendTo: 'parent' not necessary anymore](https://github.com/wekan/wekan/pull/3405).
Thanks to mfilser.
- [Allow to edit email verified and initials at Admin Panel/People/People](https://github.com/wekan/wekan/commit/d03e2170dd10741bd78722cc35b52cffa220a2e7).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.66 2020-12-27 Wekan release
This release fixes the following bugs:
- [Fix Mobile miniscreen: Drag handle not visible in long checklist item
text](https://github.com/wekan/wekan/commit/a8453657c95a4bde2ae86b4c77e55bb2174adf26).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.65 2020-12-26 Wekan release
This release fixes the following bugs:
- [Fixed Drag and drop between checklists closes the card sometimes on
Firefox](https://github.com/wekan/wekan/commit/c7808c5c03f98eae709e5ef89e8e17af4689cb2e).
xet7 thanks mfilser about [similar fix of appendTo parent](https://github.com/wekan/wekan/pull/3342)
that did work here too to fix this.
Thanks to mfilser and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.64 2020-12-24 Wekan release
This release fixes the following bugs:
- [Dark theme button background fix](https://github.com/wekan/wekan/pull/3401).
Thanks to jasontamez.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.63 2020-12-21 Wekan release
This release fixes the following bugs:
- [Fixed Remove Cover button gives JS error](https://github.com/wekan/wekan/commit/28850e5510f2aaefcae404efac1973c12f1cca65).
Thanks to tsukasa1989 and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.62 2020-12-18 Wekan release
This release fixes the following bugs:
- [Treat unknown attachment types as binary on board
import/clone](https://github.com/wekan/wekan/pull/3395).
Thanks to daniel-eder.
- [Fix Move card from a board to another does not work anymore](https://github.com/wekan/wekan/commit/9dd0fb88d6cb3378a8fc96aaf60214020efeaed1).
Thanks to lezioul and xet7.
- [Add some permission code, to see does it fix something](https://github.com/wekan/wekan/commit/7f3c4acf62deefa2f7b36b986e06336fd3b2754f).
Thanks to xet7.
- [Fix delete board button not visible](https://github.com/wekan/wekan/commit/53a925cf7ff95167cbf2f65f7c7e169e18b14b44).
Thanks to airtraxx and xet7.
- [Board: When removing member from board, remove also from assignees.
Admin Panel/People: 1) Allow edit user that does not have email address.
2) When creating new user, require username and email address, and save also fullname.
3) Some in progress code for deleting user, that does not work correctly yet, so deleting user is not enabled
yet](https://github.com/wekan/wekan/commit/61ae62a83aaddb2c6f679ce9d05b675c845ba8bf).
Thanks to airtraxx and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.61 2020-12-16 Wekan release
This release fixes the following bugs:
- [Removed cookie code that is not in use](https://github.com/wekan/wekan/commit/3c406d955ec602d4b86c164acb9e94e715086f8e).
Thanks to xet7.
- [Allow normal user to delete checklist item](https://github.com/wekan/wekan/commit/f9ba17177e8f1146be1e571f47d26c13a9337034).
Thanks to Samunosuke and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.60 2020-12-15 Wekan release
This release adds the following updates:
- Update dependencies.
[Part 1](https://github.com/wekan/wekan/commit/2e1e703e3591258462b3167f72e2b2319bf57bec),
[Part 2](https://github.com/wekan/wekan/commit/a75c162483795775db1631686f8e7017b42c87ca).
Thanks to developers of dependencies.
and fixes the following bugs:
- Prevent normal user deleting or modifying too much. Allow normal user to export board.
[Part1](https://github.com/wekan/wekan/commit/4a205fcfcb40438faead3bf8973b10b8e42974f0),
[Part2](https://github.com/wekan/wekan/commit/6cb4b9fe4a086202d642de54464088e0a1122ec0).
Thanks to Samunosuke, pgh2357 and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.59 2020-12-10 Wekan release
This release fixes the following bugs:
- [Fix not all checklist items being imported/cloned](https://github.com/wekan/wekan/pull/3389).
Thanks to daniel-eder.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.58 2020-12-09 Wekan release
This release fixes the following bugs:
- [Fix issues when duplicating board](https://github.com/wekan/wekan/pull/3387).
Thanks to daniel-eder.
Thanks to above GitHub users for their contributions and translators for their translations.
# v4.57 2020-12-08 Wekan release
This release adds the following new features:
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v4.57.0"
appVersion: "v4.69.0"
files:
userUploads:
- README.md
+4
View File
@@ -3,6 +3,10 @@ BlazeComponent.extendComponent({
this.subscribe('archivedBoards');
},
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
archivedBoards() {
return Boards.find(
{ archived: true },
+6 -1
View File
@@ -211,7 +211,12 @@ BlazeComponent.extendComponent({
}
// Disable drag-dropping if the current user is not a board member
$swimlanesDom.sortable('option', 'disabled', !userIsMember());
//$swimlanesDom.sortable('option', 'disabled', !userIsMember());
$swimlanesDom.sortable(
'option',
'disabled',
!Meteor.user().isBoardAdmin(),
);
});
function userIsMember() {
+2 -1
View File
@@ -15,7 +15,8 @@ setBoardColor(color)
.is-selected .minicard
border-left: 3px solid color
button[type=submit].primary, input[type=submit].primary
button[type=submit].primary, input[type=submit].primary,
.sidebar .sidebar-content .sidebar-btn
background-color: darken(color, 20%)
&.pop-over .pop-over-list li a:not(.disabled):hover,
+7 -7
View File
@@ -60,10 +60,10 @@ template(name="boardList")
template(name="boardListHeaderBar")
h1 {{_ title }}
.board-header-btns.right
a.board-header-btn.js-open-archived-board
i.fa.fa-archive
span {{_ 'archives'}}
a.board-header-btn(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}")
i.fa.fa-clone
span {{_ 'templates'}}
//.board-header-btns.right
// a.board-header-btn.js-open-archived-board
// i.fa.fa-archive
// span {{_ 'archives'}}
// a.board-header-btn(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}")
// i.fa.fa-clone
// span {{_ 'templates'}}
+4 -3
View File
@@ -46,9 +46,10 @@ template(name="attachmentsGalery")
| {{_ 'remove-cover'}}
else
| {{_ 'add-cover'}}
a.js-confirm-delete
i.fa.fa-close
| {{_ 'delete'}}
if currentUser.isBoardAdmin
a.js-confirm-delete
i.fa.fa-close
| {{_ 'delete'}}
if currentUser.isBoardMember
unless currentUser.isCommentOnly
+6
View File
@@ -45,6 +45,12 @@ Template.attachmentsGalery.events({
},
});
Template.attachmentsGalery.helpers({
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
});
Template.previewAttachedImagePopup.events({
'click .js-large-image-clicked'() {
Popup.close();
+14 -10
View File
@@ -354,10 +354,11 @@ template(name="cardDetailsActionsPopup")
a.js-start-voting
i.fa.fa-thumbs-up
| {{_ 'card-edit-voting'}}
li
a.js-custom-fields
i.fa.fa-list-alt
| {{_ 'card-edit-custom-fields'}}
if currentUser.isBoardAdmin
li
a.js-custom-fields
i.fa.fa-list-alt
| {{_ 'card-edit-custom-fields'}}
//li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}}
//li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
//li: a.js-due-date {{_ 'editCardDueDatePopup-title'}}
@@ -382,10 +383,11 @@ template(name="cardDetailsActionsPopup")
| {{_ 'moveCardToBottom-title'}}
hr
ul.pop-over-list
li
a.js-move-card
i.fa.fa-arrow-right
| {{_ 'moveCardPopup-title'}}
if currentUser.isBoardAdmin
li
a.js-move-card
i.fa.fa-arrow-right
| {{_ 'moveCardPopup-title'}}
unless currentUser.isWorker
li
a.js-copy-card
@@ -562,7 +564,8 @@ template(name="cardMorePopup")
br
| {{_ 'added'}}
span.date(title=card.createdAt) {{ moment createdAt 'LLL' }}
a.js-delete(title="{{_ 'card-delete-notice'}}") {{_ 'delete'}}
if currentUser.isBoardAdmin
a.js-delete(title="{{_ 'card-delete-notice'}}") {{_ 'delete'}}
template(name="setCardColorPopup")
form.edit-label
@@ -609,7 +612,8 @@ template(name="cardStartVotingPopup")
button.primary.js-submit {{_ 'save'}}
if getVoteQuestion
button.js-remove-vote.negate.wide.right {{_ 'delete'}}
if currentUser.isBoardAdmin
button.js-remove-vote.negate.wide.right {{_ 'delete'}}
template(name="positiveVoteMembersPopup")
ul.pop-over-list.js-card-member-list
+4
View File
@@ -567,6 +567,10 @@ Template.cardDetailsActionsPopup.helpers({
return this.findWatcher(Meteor.userId());
},
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
canModifyCard() {
return (
Meteor.user() &&
+2 -2
View File
@@ -102,9 +102,9 @@ template(name='checklistItemDetail')
if canModifyCard
.check-box-container
.check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
if isMiniScreenOrShowDesktopDragHandles
span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}")
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
if isMiniScreenOrShowDesktopDragHandles
span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}")
+viewer
= item.title
else
+10 -7
View File
@@ -6,7 +6,7 @@ function initSorting(items) {
helper: 'clone',
items: '.js-checklist-item:not(.placeholder)',
connectWith: '.js-checklist-items',
appendTo: '.board-canvas',
appendTo: 'parent',
distance: 7,
placeholder: 'checklist-item placeholder',
scroll: false,
@@ -55,15 +55,10 @@ BlazeComponent.extendComponent({
self.autorun(() => {
const $itemsDom = $(self.itemsDom);
if ($itemsDom.data('uiSortable') || $itemsDom.data('sortable')) {
$(self.itemsDom).sortable(
'option',
'disabled',
!userIsMember(),
);
$(self.itemsDom).sortable('option', 'disabled', !userIsMember());
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
$(self.itemsDom).sortable({
handle: 'span.fa.checklistitem-handle',
appendTo: 'parent',
});
}
}
@@ -228,6 +223,14 @@ Template.checklists.helpers({
},
});
Template.addChecklistItemForm.onRendered(() => {
autosize($('textarea.js-add-checklist-item'));
});
Template.editChecklistItemForm.onRendered(() => {
autosize($('textarea.js-edit-checklist-item'));
});
Template.checklistDeleteDialog.onCreated(() => {
const $cardDetails = this.$('.card-details');
this.scrollState = {
+3 -3
View File
@@ -134,7 +134,7 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
background-color: darken(white, 8%)
.check-box-container
padding-right: 1px;
padding-right: 10px;
.check-box
margin: 0.1em 0 0 0;
@@ -144,7 +144,6 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
.item-title
flex: 1
margin-left: 10px;
&.is-checked
color: #8c8c8c
font-style: italic
@@ -157,7 +156,8 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item
max-width: 420px
span.fa.checklistitem-handle
float: right
padding-top: 2px
padding-right: 10px;
.js-delete-checklist-item
margin: 0 0 0.5em 1.33em
+8 -6
View File
@@ -2,10 +2,10 @@ template(name="subtasks")
h3.card-details-item-title
i.fa.fa-sitemap
| {{_ 'subtasks'}}
if toggleDeleteDialog.get
.board-overlay#card-details-overlay
+subtaskDeleteDialog(subtask = subtaskToDelete)
if currentUser.isBoardAdmin
if toggleDeleteDialog.get
.board-overlay#card-details-overlay
+subtaskDeleteDialog(subtask = subtaskToDelete)
.card-subtasks-items
each subtask in currentCard.subtasks
@@ -28,7 +28,8 @@ template(name="subtaskDetail")
span
a.js-view-subtask(title="{{ subtask.title }}") {{_ "view-it"}}
if canModifyCard
a.js-delete-subtask.toggle-delete-subtask-dialog {{_ "delete"}}...
if currentUser.isBoardAdmin
a.js-delete-subtask.toggle-delete-subtask-dialog {{_ "delete"}}...
if canModifyCard
h2.title.js-open-inlined-form.is-editable
@@ -68,7 +69,8 @@ template(name="editSubtaskItemForm")
a.fa.fa-times-thin.js-close-inlined-form
span(title=createdAt) {{ moment createdAt }}
if canModifyCard
a.js-delete-subtask-item {{_ "delete"}}...
if currentUser.isBoardAdmin
a.js-delete-subtask-item {{_ "delete"}}...
template(name="subtasksItems")
.subtasks-items.js-subtasks-items
+6 -4
View File
@@ -43,8 +43,9 @@ template(name="listHeader")
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
if currentUser.isBoardAdmin
if showDesktopDragHandles
a.list-header-handle.handle.fa.fa-arrows.js-list-handle
template(name="editListTitleForm")
.list-composer
@@ -115,8 +116,9 @@ template(name="listMorePopup")
input.inline-input(type="text" readonly value="{{ rootUrl }}")
| {{_ 'added'}}
span.date(title=list.createdAt) {{ moment createdAt 'LLL' }}
unless currentUser.isWorker
a.js-delete {{_ 'delete'}}
//unless currentUser.isWorker
// if currentUser.isBoardAdmin
// a.js-delete {{_ 'delete'}}
template(name="listDeletePopup")
p {{_ "list-delete-pop"}}
+14
View File
@@ -104,6 +104,10 @@ BlazeComponent.extendComponent({
}).register('listHeader');
Template.listHeader.helpers({
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
showDesktopDragHandles() {
currentUser = Meteor.user();
if (currentUser) {
@@ -117,6 +121,10 @@ Template.listHeader.helpers({
});
Template.listActionPopup.helpers({
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
isWipLimitEnabled() {
return Template.currentData().getWipLimit('enabled');
},
@@ -254,6 +262,12 @@ Template.listMorePopup.events({
}),
});
Template.listHeader.helpers({
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
});
BlazeComponent.extendComponent({
onCreated() {
this.currentList = this.currentData();
+4 -4
View File
@@ -38,10 +38,10 @@ template(name="header")
span.fa.fa-home
| {{_ 'all-boards'}}
li.separator -
li
a(href="{{pathFor 'public'}}")
span.fa.fa-globe
| {{_ 'public'}}
//li
// a(href="{{pathFor 'public'}}")
// span.fa.fa-globe
// | {{_ 'public'}}
each currentUser.starredBoards
li.separator -
li(class="{{#if $.Session.equals 'currentBoard' _id}}current{{/if}}")
+28
View File
@@ -0,0 +1,28 @@
template(name="myCardsHeaderBar")
h1
a.back-btn(href="{{pathFor 'home'}}")
i.fa.fa-chevron-left
| {{_ 'my-cards'}}
template(name="myCardsModalTitle")
h2
i.fa.fa-keyboard-o
| {{_ 'my-cards'}}
template(name="myCards")
.wrapper
each board in cardsFind
.board-title
| {{_ 'board' }}:
= board.title
each swimlane in board.swimlanes
.swimlane-title
| {{_ 'swimlane' }}:
= swimlane.title
each list in swimlane.lists
.list-title
| {{_ 'list' }}:
= list.title
each card in list.cards
a.minicard-wrapper.card-title(href="{{pathFor 'card' boardId=board.id slug=board.slug cardId=card._id }}")
+minicard(card)
+154
View File
@@ -0,0 +1,154 @@
const subManager = new SubsManager();
Meteor.subscribe('myCards');
Meteor.subscribe('mySwimlanes');
Meteor.subscribe('myLists');
Template.myCardsHeaderBar.events({
'click .js-open-archived-board'() {
Modal.open('archivedBoards');
},
});
Template.myCardsHeaderBar.helpers({
title() {
return FlowRouter.getRouteName() === 'home' ? 'my-boards' : 'public';
},
templatesUser() {
return Meteor.user();
},
});
Template.myCards.helpers({
userId() {
return Meteor.userId();
},
});
BlazeComponent.extendComponent({
onCreated() {
Meteor.subscribe('setting');
// subManager.subscribe('myCards');
},
cardsFind() {
const userId = Meteor.userId();
const boards = [];
let board = null;
let swimlane = null;
let list = null;
const cursor = Cards.find(
{
archived: false,
$or: [{ members: userId }, { assignees: userId }],
},
{
sort: {
boardId: 1,
swimlaneId: 1,
listId: 1,
sort: 1,
},
},
);
// eslint-disable-next-line no-console
// console.log('cursor:', cursor);
let newBoard = false;
let newSwimlane = false;
let newList = false;
cursor.forEach(card => {
// eslint-disable-next-line no-console
// console.log('card:', card.title);
if (list === null || list.id !== card.listId) {
// eslint-disable-next-line no-console
// console.log('new list');
let l = Lists.findOne(card.listId);
if (!l) {
l = {
_id: card.listId,
title: 'undefined list',
};
}
// eslint-disable-next-line no-console
// console.log('list:', l);
list = {
id: l._id,
title: l.title,
cards: [card],
};
newList = true;
}
if (swimlane === null || card.swimlaneId !== swimlane.id) {
// eslint-disable-next-line no-console
// console.log('new swimlane');
let s = Swimlanes.findOne(card.swimlaneId);
if (!s) {
s = {
_id: card.swimlaneId,
title: 'undefined swimlane',
};
}
// eslint-disable-next-line no-console
// console.log('swimlane:', s);
swimlane = {
id: s._id,
title: s.title,
lists: [list],
};
newSwimlane = true;
}
if (board === null || card.boardId !== board.id) {
// eslint-disable-next-line no-console
// console.log('new board');
const b = Boards.findOne(card.boardId);
// eslint-disable-next-line no-console
// console.log('board:', b, b._id, b.title);
board = {
id: b._id,
title: b.title,
slug: b.slug,
swimlanes: [swimlane],
};
newBoard = true;
}
if (newBoard) {
boards.push(board);
} else if (newSwimlane) {
board.swimlanes.push(swimlane);
} else if (newList) {
swimlane.lists.push(list);
} else {
list.cards.push(card);
}
newBoard = false;
newSwimlane = false;
newList = false;
});
// eslint-disable-next-line no-console
// console.log('boards:', boards);
return boards;
},
events() {
return [
{
'click .js-my-card'(evt) {
const card = this.currentData().card;
// eslint-disable-next-line no-console
console.log('currentData():', this.currentData());
// eslint-disable-next-line no-console
console.log('card:', card);
if (card) {
Utils.goCardId(card._id);
}
evt.preventDefault();
},
},
];
},
}).register('myCards');
+40
View File
@@ -0,0 +1,40 @@
.my-cards-list
.my-cards-list-item
border-bottom: 1px solid darken(white, 25%)
padding: 10px 5px
&:last-child
border-bottom: none
.my-cards-list-item-keys
margin-top: 5px
float: right
kbd
padding: 5px 8px
margin: 5px
font-size: 18px
.my-cards-list-item-action
font-size: 1.4em
margin: 5px
.board-title
font-size: 1.4rem
font-weight: bold
.swimlane-title
font-size: 1.2rem
font-weight: bold
margin-left: 1em
margin-top: 10px
.list-title
margin-top: 5px
font-weight: bold
margin-left: 1.6rem
.card-title
margin-top: 5px
margin-left: 1.8rem
max-width: 350px;
+331 -25
View File
@@ -5,34 +5,102 @@ template(name="people")
else
.content-title.ext-box
.ext-box-left
span
i.fa.fa-users
| {{_ 'people'}}
input#searchInput(placeholder="{{_ 'search'}}")
button#searchButton
i.fa.fa-search
| {{_ 'search'}}
.ext-box-right
span {{_ 'people-number'}} #{peopleNumber}
if loading.get
+spinner
else if orgSetting.get
span
i.fa.fa-sitemap
| {{_ 'organizations'}}
input#searchOrgInput(placeholder="{{_ 'search'}}")
button#searchOrgButton
i.fa.fa-search
| {{_ 'search'}}
.ext-box-right
span {{_ 'org-number'}} #{orgNumber}
else if teamSetting.get
span
i.fa.fa-users
| {{_ 'teams'}}
input#searchTeamInput(placeholder="{{_ 'search'}}")
button#searchTeamButton
i.fa.fa-search
| {{_ 'search'}}
.ext-box-right
span {{_ 'team-number'}} #{teamNumber}
else if peopleSetting.get
span
i.fa.fa-user
| {{_ 'people'}}
input#searchInput(placeholder="{{_ 'search'}}")
button#searchButton
i.fa.fa-search
| {{_ 'search'}}
.ext-box-right
span {{_ 'people-number'}} #{peopleNumber}
.content-body
.side-menu
ul
li.active
a.js-setting-menu(data-id="people-setting")
a.js-org-menu(data-id="org-setting")
i.fa.fa-sitemap
| {{_ 'organizations'}}
li
a.js-team-menu(data-id="team-setting")
i.fa.fa-users
| {{_ 'teams'}}
li
a.js-people-menu(data-id="people-setting")
i.fa.fa-user
| {{_ 'people'}}
.main-body
if loading.get
+spinner
else if people.get
else if orgSetting.get
+orgGeneral
else if teamSetting.get
+teamGeneral
else if peopleSetting.get
+peopleGeneral
template(name="orgGeneral")
table
tbody
tr
th {{_ 'displayName'}}
th {{_ 'description'}}
th {{_ 'shortName'}}
th {{_ 'website'}}
th {{_ 'teams'}}
th {{_ 'createdAt'}}
th {{_ 'active'}}
th
+newOrgRow
each org in orgList
+orgRow(orgId=org._id)
template(name="teamGeneral")
table
tbody
tr
th {{_ 'displayName'}}
th {{_ 'description'}}
th {{_ 'shortName'}}
th {{_ 'website'}}
th {{_ 'createdAt'}}
th {{_ 'active'}}
th
+newTeamRow
each team in teamList
+teamRow(teamId=team._id)
template(name="peopleGeneral")
table
tbody
tr
th {{_ 'username'}}
th {{_ 'fullname'}}
th {{_ 'initials'}}
th {{_ 'admin'}}
th {{_ 'email'}}
th {{_ 'verified'}}
@@ -44,11 +112,93 @@ template(name="peopleGeneral")
each user in peopleList
+peopleRow(userId=user._id)
template(name="newOrgRow")
a.new-org
i.fa.fa-edit
| {{_ 'new'}}
template(name="newTeamRow")
a.new-team
i.fa.fa-edit
| {{_ 'new'}}
template(name="newUserRow")
a.new-user
i.fa.fa-edit
| {{_ 'new'}}
template(name="orgRow")
tr
if orgData.loginDisabled
td <s>{{ orgData.displayName }}</s>
else
td {{ orgData.displayName }}
if orgData.loginDisabled
td <s>{{ orgData.orgDesc }}</s>
else
td {{ orgData.desc }}
if orgData.loginDisabled
td <s>{{ orgData.name }}</s>
else
td {{ orgData.name }}
if orgData.loginDisabled
td <s>{{ orgData.website }}</s>
else
td {{ orgData.website }}
if orgData.loginDisabled
td <s>{{ orgData.teams }}</s>
else
td {{ orgData.teams }}
if orgData.loginDisabled
td <s>{{ moment orgData.createdAt 'LLL' }}</s>
else
td {{ moment orgData.createdAt 'LLL' }}
td
if orgData.loginDisabled
| {{_ 'no'}}
else
| {{_ 'yes'}}
td
a.edit-org
i.fa.fa-edit
| {{_ 'edit'}}
a.more-settings-org
i.fa.fa-ellipsis-h
template(name="teamRow")
tr
if teamData.loginDisabled
td <s>{{ teamData.displayName }}</s>
else
td {{ teamData.displayName }}
if teamData.loginDisabled
td <s>{{ teamData.desc }}</s>
else
td {{ teamData.desc }}
if teamData.loginDisabled
td <s>{{ teamData.dame }}</s>
else
td {{ teamData.name }}
if teamData.loginDisabled
td <s>{{ teamData.website }}</s>
else
td {{ teamData.website }}
if orgData.loginDisabled
td <s>{{ moment teamData.createdAt 'LLL' }}</s>
else
td {{ moment teamData.createdAt 'LLL' }}
td
if teamData.loginDisabled
| {{_ 'no'}}
else
| {{_ 'yes'}}
td
a.edit-team
i.fa.fa-edit
| {{_ 'edit'}}
a.more-settings-team
i.fa.fa-ellipsis-h
template(name="peopleRow")
tr
if userData.loginDisabled
@@ -59,6 +209,10 @@ template(name="peopleRow")
td <s>{{ userData.profile.fullname }}</s>
else
td {{ userData.profile.fullname }}
if userData.loginDisabled
td <s>{{ userData.profile.initials }}</s>
else
td {{ userData.profile.initials }}
if userData.loginDisabled
td
if userData.isAdmin
@@ -107,12 +261,61 @@ template(name="peopleRow")
a.more-settings-user
i.fa.fa-ellipsis-h
template(name="editOrgPopup")
form
label.hide.orgId(type="text" value=org._id)
label
| {{_ 'orgDisplayName'}}
input.js-orgDisplayName(type="text" value=org.displayName required)
span.error.hide.orgname-taken
| {{_ 'error-orgname-taken'}}
label
| {{_ 'orgDesc'}}
input.js-orgDesc(type="text" value=org.desc required)
label
| {{_ 'orgName'}}
input.js-orgName(type="text" value=org.name required)
label
| {{_ 'orgWebsite'}}
input.js-orgWebsite(type="text" value=org.website required)
label
| {{_ 'active'}}
select.select-active.js-org-isactive
option(value="false") {{_ 'yes'}}
option(value="true" selected="{{org.loginDisabled}}") {{_ 'no'}}
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="editTeamPopup")
form
label.hide.teamId(type="text" value=team._id)
label
| {{_ 'displayName'}}
input.js-teamDisplayName(type="text" value=team.displayName required)
span.error.hide.teamname-taken
| {{_ 'error-teamname-taken'}}
label
| {{_ 'description'}}
input.js-orgDesc(type="text" value=org.desc required)
label
| {{_ 'name'}}
input.js-orgName(type="text" value=org.name required)
label
| {{_ 'website'}}
input.js-orgWebsite(type="text" value=org.website required)
label
| {{_ 'active'}}
select.select-active.js-team-isactive
option(value="false") {{_ 'yes'}}
option(value="true" selected="{{team.loginDisabled}}") {{_ 'no'}}
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="editUserPopup")
form
label.hide.userId(type="text" value=user._id)
label
| {{_ 'fullname'}}
input.js-profile-fullname(type="text" value=user.profile.fullname)
label
| {{_ 'username'}}
span.error.hide.username-taken
@@ -120,7 +323,18 @@ template(name="editUserPopup")
if isLdap
input.js-profile-username(type="text" value=user.username readonly)
else
input.js-profile-username(type="text" value=user.username)
input.js-profile-username(type="text" value=user.username required)
label
| {{_ 'fullname'}}
input.js-profile-fullname(type="text" value=user.profile.fullname required)
label
| {{_ 'initials'}}
input.js-profile-initials(type="text" value=user.profile.initials)
label
| {{_ 'admin'}}
select.select-role.js-profile-isadmin
option(value="false") {{_ 'no'}}
option(value="true" selected="{{user.isAdmin}}") {{_ 'yes'}}
label
| {{_ 'email'}}
span.error.hide.email-taken
@@ -128,12 +342,12 @@ template(name="editUserPopup")
if isLdap
input.js-profile-email(type="email" value="{{user.emails.[0].address}}" readonly)
else
input.js-profile-email(type="email" value="{{user.emails.[0].address}}")
input.js-profile-email(type="email" value="{{user.emails.[0].address}}" required)
label
| {{_ 'admin'}}
select.select-role.js-profile-isadmin
| {{_ 'verified'}}
select.select-verified.js-profile-email-verified
option(value="false") {{_ 'no'}}
option(value="true" selected="{{user.isAdmin}}") {{_ 'yes'}}
option(value="true" selected="{{userData.emails.[0].verified}}") {{_ 'yes'}}
label
| {{_ 'active'}}
select.select-active.js-profile-isactive
@@ -153,15 +367,64 @@ template(name="editUserPopup")
input.js-profile-password(type="password")
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
// div
// input#deleteButton.primary.wide(type="button" value="{{_ 'delete'}}")
template(name="newOrgPopup")
form
//label.hide.userId(type="text" value=user._id)
label
| {{_ 'displayName'}}
input.js-displayName(type="text" value="" required)
label
| {{_ 'description'}}
input.js-desc(type="text" value="" required)
label
| {{_ 'shortName'}}
input.js-name(type="text" value="")
label
| {{_ 'teams'}}
input.js-teams(type="text" value="")
label
| {{_ 'website'}}
input.js-website(type="text" value="")
label
| {{_ 'active'}}
select.select-active.js-profile-isactive
option(value="false" selected="selected") {{_ 'yes'}}
option(value="true") {{_ 'no'}}
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="newTeamPopup")
form
//label.hide.teamId(type="text" value=team._id)
label
| {{_ 'displayName'}}
input.js-teamDisplayName(type="text" value="" required)
label
| {{_ 'description'}}
input.js-teamDesc(type="text" value="" required)
label
| {{_ 'shortName'}}
input.js-teamName(type="text" value="")
label
| {{_ 'website'}}
input.js-teamWebsite(type="text" value="")
label
| {{_ 'active'}}
select.select-active.js-profile-isactive
option(value="false" selected="selected") {{_ 'yes'}}
option(value="true") {{_ 'no'}}
hr
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="newUserPopup")
form
//label.hide.userId(type="text" value=user._id)
label
| {{_ 'fullname'}}
input.js-profile-fullname(type="text" value="")
input.js-profile-fullname(type="text" value="" required)
label
| {{_ 'username'}}
span.error.hide.username-taken
@@ -169,7 +432,7 @@ template(name="newUserPopup")
//if isLdap
// input.js-profile-username(type="text" value=user.username readonly)
//else
input.js-profile-username(type="text" value="")
input.js-profile-username(type="text" value="" required)
label
| {{_ 'email'}}
span.error.hide.email-taken
@@ -177,7 +440,7 @@ template(name="newUserPopup")
//if isLdap
// input.js-profile-email(type="email" value="{{user.emails.[0].address}}" readonly)
//else
input.js-profile-email(type="email" value="")
input.js-profile-email(type="email" value="" required)
label
| {{_ 'admin'}}
select.select-role.js-profile-isadmin
@@ -199,13 +462,56 @@ template(name="newUserPopup")
hr
label
| {{_ 'password'}}
input.js-profile-password(type="password")
input.js-profile-password(type="password" required)
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="settingsOrgPopup")
ul.pop-over-list
li
a.impersonate-org
i.fa.fa-user
| {{_ 'impersonate-org'}}
// Delete is not enabled yet, because it does leave empty user avatars
// to boards: boards members, card members and assignees have
// empty users. See:
// - wekan/client/components/settings/peopleBody.jade deleteButton
// - wekan/client/components/settings/peopleBody.js deleteButton
// - wekan/client/components/sidebar/sidebar.js Popup.afterConfirm('removeMember'
// that does now remove member from board, card members and assignees correctly,
// but that should be used to remove user from all boards similarly
// - wekan/models/users.js Delete is not enabled
//li
// br
// br
// hr
//li
// form
// label.hide.userId(type="text" value=user._id)
// div.buttonsContainer
// input#deleteButton.card-details-red.right.wide(type="button" value="{{_ 'delete'}}")
template(name="settingsUserPopup")
ul.pop-over-list
li
a.impersonate-user
i.fa.fa-user
| {{_ 'impersonate-user'}}
// Delete is not enabled yet, because it does leave empty user avatars
// to boards: boards members, card members and assignees have
// empty users. See:
// - wekan/client/components/settings/peopleBody.jade deleteButton
// - wekan/client/components/settings/peopleBody.js deleteButton
// - wekan/client/components/sidebar/sidebar.js Popup.afterConfirm('removeMember'
// that does now remove member from board, card members and assignees correctly,
// but that should be used to remove user from all boards similarly
// - wekan/models/users.js Delete is not enabled
//li
// br
// br
// hr
//li
// form
// label.hide.userId(type="text" value=user._id)
// div.buttonsContainer
// input#deleteButton.card-details-red.right.wide(type="button" value="{{_ 'delete'}}")
+331 -27
View File
@@ -1,3 +1,5 @@
const orgsPerPage = 25;
const teamsPerPage = 25;
const usersPerPage = 25;
BlazeComponent.extendComponent({
@@ -7,17 +9,45 @@ BlazeComponent.extendComponent({
onCreated() {
this.error = new ReactiveVar('');
this.loading = new ReactiveVar(false);
this.people = new ReactiveVar(true);
this.orgSetting = new ReactiveVar(true);
this.teamSetting = new ReactiveVar(true);
this.peopleSetting = new ReactiveVar(true);
this.findOrgsOptions = new ReactiveVar({});
this.findTeamsOptions = new ReactiveVar({});
this.findUsersOptions = new ReactiveVar({});
this.number = new ReactiveVar(0);
this.numberOrgs = new ReactiveVar(0);
this.numberTeams = new ReactiveVar(0);
this.numberPeople = new ReactiveVar(0);
this.page = new ReactiveVar(1);
this.loadNextPageLocked = false;
this.callFirstWith(null, 'resetNextPeak');
this.autorun(() => {
const limit = this.page.get() * usersPerPage;
const limitOrgs = this.page.get() * orgsPerPage;
const limitTeams = this.page.get() * teamsPerPage;
const limitUsers = this.page.get() * usersPerPage;
this.subscribe('people', this.findUsersOptions.get(), limit, () => {
this.subscribe('org', this.findOrgsOptions.get(), limitOrgs, () => {
this.loadNextPageLocked = false;
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
this.calculateNextPeak();
const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
if (nextPeakBefore === nextPeakAfter) {
this.callFirstWith(null, 'resetNextPeak');
}
});
this.subscribe('team', this.findTeamsOptions.get(), limitTeams, () => {
this.loadNextPageLocked = false;
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
this.calculateNextPeak();
const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
if (nextPeakBefore === nextPeakAfter) {
this.callFirstWith(null, 'resetNextPeak');
}
});
this.subscribe('people', this.findUsersOptions.get(), limitUsers, () => {
this.loadNextPageLocked = false;
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
this.calculateNextPeak();
@@ -31,6 +61,22 @@ BlazeComponent.extendComponent({
events() {
return [
{
'click #searchOrgButton'() {
this.filterOrg();
},
'keydown #searchOrgInput'(event) {
if (event.keyCode === 13 && !event.shiftKey) {
this.filterOrg();
}
},
'click #searchTeamButton'() {
this.filterTeam();
},
'keydown #searchTeamInput'(event) {
if (event.keyCode === 13 && !event.shiftKey) {
this.filterTeam();
}
},
'click #searchButton'() {
this.filterPeople();
},
@@ -39,9 +85,18 @@ BlazeComponent.extendComponent({
this.filterPeople();
}
},
'click #newOrgButton'() {
Popup.open('newOrg');
},
'click #newTeamButton'() {
Popup.open('newTeam');
},
'click #newUserButton'() {
Popup.open('newUser');
},
'click a.js-org-menu': this.switchMenu,
'click a.js-team-menu': this.switchMenu,
'click a.js-people-menu': this.switchMenu,
},
];
},
@@ -84,18 +139,63 @@ BlazeComponent.extendComponent({
setLoading(w) {
this.loading.set(w);
},
orgList() {
const orgs = Org.find(this.findOrgsOptions.get(), {
fields: { _id: true },
});
this.numberOrgs.set(org.count(false));
return orgs;
},
teamList() {
const teams = Team.find(this.findTeamsOptions.get(), {
fields: { _id: true },
});
this.numberTeams.set(team.count(false));
return teams;
},
peopleList() {
const users = Users.find(this.findUsersOptions.get(), {
fields: { _id: true },
});
this.number.set(users.count(false));
this.numberPeople.set(users.count(false));
return users;
},
orgNumber() {
return this.numberOrgs.get();
},
teamNumber() {
return this.numberTeams.get();
},
peopleNumber() {
return this.number.get();
return this.numberPeople.get();
},
switchMenu(event) {
const target = $(event.target);
if (!target.hasClass('active')) {
$('.side-menu li.active').removeClass('active');
target.parent().addClass('active');
const targetID = target.data('id');
this.orgSetting.set('org-setting' === targetID);
this.teamSetting.set('team-setting' === targetID);
this.peopleSetting.set('people-setting' === targetID);
}
},
}).register('people');
Template.orgRow.helpers({
orgData() {
const orgCollection = this.esSearch ? ESSearchResults : Org;
return orgCollection.findOne(this.orgId);
},
});
Template.teamRow.helpers({
teamData() {
const teamCollection = this.esSearch ? ESSearchResults : Team;
return teamCollection.findOne(this.teamId);
},
});
Template.peopleRow.helpers({
userData() {
const userCollection = this.esSearch ? ESSearchResults : Users;
@@ -122,6 +222,24 @@ Template.editUserPopup.onCreated(function() {
});
});
Template.editOrgPopup.helpers({
org() {
return Org.findOne(this.orgId);
},
errorMessage() {
return Template.instance().errorMessage.get();
},
});
Template.editTeamPopup.helpers({
team() {
return Team.findOne(this.teamId);
},
errorMessage() {
return Template.instance().errorMessage.get();
},
});
Template.editUserPopup.helpers({
user() {
return Users.findOne(this.userId);
@@ -144,6 +262,14 @@ Template.editUserPopup.helpers({
},
});
Template.newOrgPopup.onCreated(function() {
this.errorMessage = new ReactiveVar('');
});
Template.newTeamPopup.onCreated(function() {
this.errorMessage = new ReactiveVar('');
});
Template.newUserPopup.onCreated(function() {
this.authenticationMethods = new ReactiveVar([]);
this.errorMessage = new ReactiveVar('');
@@ -163,28 +289,76 @@ Template.newUserPopup.onCreated(function() {
});
});
Template.newUserPopup.helpers({
//user() {
// return Users.findOne(this.userId);
//},
authentications() {
return Template.instance().authenticationMethods.get();
Template.newOrgPopup.helpers({
org() {
return Org.findOne(this.orgId);
},
//isSelected(match) {
// const userId = Template.instance().data.userId;
// const selected = Users.findOne(userId).authenticationMethod;
// return selected === match;
//},
//isLdap() {
// const userId = Template.instance().data.userId;
// const selected = Users.findOne(userId).authenticationMethod;
// return selected === 'ldap';
//},
errorMessage() {
return Template.instance().errorMessage.get();
},
});
Template.newTeamPopup.helpers({
team() {
return Team.findOne(this.teamId);
},
errorMessage() {
return Template.instance().errorMessage.get();
},
});
Template.newUserPopup.helpers({
user() {
return Users.findOne(this.userId);
},
authentications() {
return Template.instance().authenticationMethods.get();
},
isSelected(match) {
const userId = Template.instance().data.userId;
const selected = Users.findOne(userId).authenticationMethod;
return selected === match;
},
isLdap() {
const userId = Template.instance().data.userId;
const selected = Users.findOne(userId).authenticationMethod;
return selected === 'ldap';
},
errorMessage() {
return Template.instance().errorMessage.get();
},
});
BlazeComponent.extendComponent({
onCreated() {},
org() {
return Org.findOne(this.orgId);
},
events() {
return [
{
'click a.edit-org': Popup.open('editOrg'),
'click a.more-settings-org': Popup.open('settingsOrg'),
},
];
},
}).register('orgRow');
BlazeComponent.extendComponent({
onCreated() {},
team() {
return Team.findOne(this.teamId);
},
events() {
return [
{
'click a.edit-team': Popup.open('editTeam'),
'click a.more-settings-team': Popup.open('settingsTeam'),
},
];
},
}).register('teamRow');
BlazeComponent.extendComponent({
onCreated() {},
user() {
@@ -200,6 +374,26 @@ BlazeComponent.extendComponent({
},
}).register('peopleRow');
BlazeComponent.extendComponent({
events() {
return [
{
'click a.new-org': Popup.open('newOrg'),
},
];
},
}).register('newOrgRow');
BlazeComponent.extendComponent({
events() {
return [
{
'click a.new-team': Popup.open('newTeam'),
},
];
},
}).register('newTeamRow');
BlazeComponent.extendComponent({
events() {
return [
@@ -214,20 +408,32 @@ Template.editUserPopup.events({
submit(event, templateInstance) {
event.preventDefault();
const user = Users.findOne(this.userId);
const fullname = templateInstance.find('.js-profile-fullname').value.trim();
const username = templateInstance.find('.js-profile-username').value.trim();
const fullname = templateInstance.find('.js-profile-fullname').value.trim();
const initials = templateInstance.find('.js-profile-initials').value.trim();
const password = templateInstance.find('.js-profile-password').value;
const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
const isActive = templateInstance.find('.js-profile-isactive').value.trim();
const email = templateInstance.find('.js-profile-email').value.trim();
const verified = templateInstance
.find('.js-profile-email-verified')
.value.trim();
const authentication = templateInstance
.find('.js-authenticationMethod')
.value.trim();
const isChangePassword = password.length > 0;
const isChangeUserName = username !== user.username;
const isChangeInitials = initials.length > 0;
const isChangeEmailVerified = verified !== user.emails[0].verified;
// If previously email address has not been set, it is undefined,
// check for undefined, and allow adding email address.
const isChangeEmail =
email.toLowerCase() !== user.emails[0].address.toLowerCase();
email.toLowerCase() !==
(typeof user.emails !== 'undefined'
? user.emails[0].address.toLowerCase()
: false);
Users.update(this.userId, {
$set: {
@@ -242,6 +448,14 @@ Template.editUserPopup.events({
Meteor.call('setPassword', password, this.userId);
}
if (isChangeEmailVerified) {
Meteor.call('setEmailVerified', email, verified === 'true', this.userId);
}
if (isChangeInitials) {
Meteor.call('setInitials', initials, this.userId);
}
if (isChangeUserName && isChangeEmail) {
Meteor.call(
'setUsernameAndEmail',
@@ -297,11 +511,47 @@ Template.editUserPopup.events({
});
} else Popup.close();
},
});
'click #deleteButton': Popup.afterConfirm('userDelete', function() {
Users.remove(this.userId);
Template.newOrgPopup.events({
submit(event, templateInstance) {
event.preventDefault();
const displayName = templateInstance.find('.js-displayName').value.trim();
const desc = templateInstance.find('.js-desc').value.trim();
const name = templateInstance.find('.js-name').value.trim();
const teams = templateInstance.find('.js-teams').value.trim();
const website = templateInstance.find('.js-website').value.trim();
const isActive = templateInstance.find('.js-profile-isactive').value.trim();
Meteor.call(
'setCreateOrg',
displayName,
desc,
name,
teams,
website,
isActive,
email.toLowerCase(),
function(error) {
const nameMessageElement = templateInstance.$('.name-taken');
if (error) {
const errorElement = error.error;
if (errorElement === 'name-already-taken') {
nameMessageElement.show();
emailMessageElement.hide();
} else if (errorElement === 'email-already-taken') {
usernameMessageElement.hide();
emailMessageElement.show();
}
} else {
usernameMessageElement.hide();
emailMessageElement.hide();
Popup.close();
}
},
);
Popup.close();
}),
},
});
Template.newUserPopup.events({
@@ -356,4 +606,58 @@ Template.settingsUserPopup.events({
}
});
},
'click #deleteButton'(event) {
event.preventDefault();
/*
// Delete is not enabled yet, because it does leave empty user avatars
// to boards: boards members, card members and assignees have
// empty users. See:
// - wekan/client/components/settings/peopleBody.jade deleteButton
// - wekan/client/components/settings/peopleBody.js deleteButton
// - wekan/client/components/sidebar/sidebar.js Popup.afterConfirm('removeMember'
// that does now remove member from board, card members and assignees correctly,
// but that should be used to remove user from all boards similarly
// - wekan/models/users.js Delete is not enabled
//
//console.log('user id: ' + this.userId);
//Popup.afterConfirm('userDelete', function(event) {
//Boards.find({ members: this.userId }).forEach(board => {
// console.log('board id: ' + board._id);
//Cards.find({ boardId: board._id, members: this.userId }).forEach(card => {
// card.unassignMember(this.userId);
//});
//Cards.find({ boardId: board._id, members: this.userId }).forEach(card => {
// card.unassignMember(this.userId);
//});
//Cards.find({ boardId: board._id, assignees: this.userId }).forEach(card => {
// card.unassignAssignee(this.userId);
//});
//Boards.findOne({ boardId: board._id }).removeMember(this.userId);
//});
//Users.remove(this.userId);
*/
Popup.close();
},
});
Template.settingsUserPopup.helpers({
user() {
return Users.findOne(this.userId);
},
authentications() {
return Template.instance().authenticationMethods.get();
},
isSelected(match) {
const userId = Template.instance().data.userId;
const selected = Users.findOne(userId).authenticationMethod;
return selected === match;
},
isLdap() {
const userId = Template.instance().data.userId;
const selected = Users.findOne(userId).authenticationMethod;
return selected === 'ldap';
},
errorMessage() {
return Template.instance().errorMessage.get();
},
});
+2 -2
View File
@@ -21,7 +21,7 @@ table
.ext-box-left
display: flex;
width: 40%
width: 100%
span
vertical-align: center;
@@ -47,5 +47,5 @@ table
div
margin: auto
.more-settings-user
.more-settings-user,.more-settings-team,.more-settings-org
margin-left: 10px;
+36 -31
View File
@@ -269,14 +269,16 @@ template(name="outgoingWebhooksPopup")
template(name="boardMenuPopup")
ul.pop-over-list
li
a.js-open-rules-view(title="{{_ 'rules'}}")
i.fa.fa-magic
| {{_ 'rules'}}
li
a.js-custom-fields
i.fa.fa-list-alt
| {{_ 'custom-fields'}}
if currentUser.isBoardAdmin
li
a.js-open-rules-view(title="{{_ 'rules'}}")
i.fa.fa-magic
| {{_ 'rules'}}
if currentUser.isBoardAdmin
li
a.js-custom-fields
i.fa.fa-list-alt
| {{_ 'custom-fields'}}
li
a.js-open-archives
i.fa.fa-archive
@@ -297,14 +299,14 @@ template(name="boardMenuPopup")
i.fa.fa-flag
| {{_ 'language'}}
unless isSandstorm
if currentUser.isBoardAdmin
hr
ul.pop-over-list
if withApi
li
a.js-export-board
i.fa.fa-share-alt
| {{_ 'export-board'}}
hr
ul.pop-over-list
if withApi
li
a.js-export-board
i.fa.fa-share-alt
| {{_ 'export-board'}}
if currentUser.isBoardAdmin
li
a.js-outgoing-webhooks
i.fa.fa-globe
@@ -317,7 +319,8 @@ template(name="boardMenuPopup")
a.js-subtask-settings
i.fa.fa-sitemap
| {{_ 'subtask-settings'}}
unless currentBoard.isTemplatesBoard
unless currentBoard.isTemplatesBoard
if currentUser.isBoardAdmin
hr
ul.pop-over-list
li
@@ -329,20 +332,22 @@ template(name="boardMenuPopup")
if isSandstorm
hr
ul.pop-over-list
li
a.js-export-board
i.fa.fa-share-alt
| {{_ 'export-board'}}
li
a.js-import-board
i.fa.fa-share-alt
i.fa.fa-sign-in
| {{_ 'import-board-c'}}
li
a.js-archive-board
i.fa.fa-arrow-right
i.fa.fa-archive
| {{_ 'archive-board'}}
if currentUser.isMember
li
a.js-export-board
i.fa.fa-share-alt
| {{_ 'export-board'}}
li
a.js-import-board
i.fa.fa-share-alt
i.fa.fa-sign-in
| {{_ 'import-board-c'}}
if currentUser.isBoardAdmin
li
a.js-archive-board
i.fa.fa-arrow-right
i.fa.fa-archive
| {{_ 'archive-board'}}
li
a.js-outgoing-webhooks
i.fa.fa-globe
+19
View File
@@ -155,6 +155,9 @@ Template.memberPopup.helpers({
user() {
return Users.findOne(this.userId);
},
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
memberType() {
const type = Users.findOne(this.userId).isBoardAdmin() ? 'admin' : 'normal';
if (type === 'normal') {
@@ -224,6 +227,9 @@ Template.boardMenuPopup.onCreated(function() {
});
Template.boardMenuPopup.helpers({
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
withApi() {
return Template.instance().apiEnabled.get();
},
@@ -249,11 +255,15 @@ Template.memberPopup.events({
},
'click .js-change-role': Popup.open('changePermissions'),
'click .js-remove-member': Popup.afterConfirm('removeMember', function() {
// This works from removing member from board, card members and assignees.
const boardId = Session.get('currentBoard');
const memberId = this.userId;
Cards.find({ boardId, members: memberId }).forEach(card => {
card.unassignMember(memberId);
});
Cards.find({ boardId, assignees: memberId }).forEach(card => {
card.unassignAssignee(memberId);
});
Boards.findOne(boardId).removeMember(memberId);
Popup.close();
}),
@@ -294,6 +304,9 @@ Template.membersWidget.helpers({
return false;
}
},
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
});
Template.membersWidget.events({
@@ -475,6 +488,12 @@ Template.labelsWidget.events({
'click .js-add-label': Popup.open('createLabel'),
});
Template.labelsWidget.helpers({
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
});
// Board members can assign people or labels by drag-dropping elements from the
// sidebar to the cards on the board. In order to re-initialize the jquery-ui
// plugin any time a draggable member or label is modified or removed we use a
+18 -12
View File
@@ -5,8 +5,9 @@ template(name="archivesSidebar")
unless isWorker
p.quiet
a.js-restore-all-cards {{_ 'restore-all'}}
| -
a.js-delete-all-cards {{_ 'delete-all'}}
if currentUser.isBoardAdmin
| -
a.js-delete-all-cards {{_ 'delete-all'}}
each archivedCards
.minicard-wrapper.js-minicard
+minicard(this)
@@ -14,8 +15,9 @@ template(name="archivesSidebar")
unless isWorker
p.quiet
a.js-restore-card {{_ 'restore'}}
| -
a.js-delete-card {{_ 'delete'}}
if currentUser.isBoardAdmin
| -
a.js-delete-card {{_ 'delete'}}
if cardIsInArchivedList
p.quiet.small ({{_ 'warn-list-archived'}})
else
@@ -25,8 +27,9 @@ template(name="archivesSidebar")
unless isWorker
p.quiet
a.js-restore-all-lists {{_ 'restore-all'}}
| -
a.js-delete-all-lists {{_ 'delete-all'}}
if currentUser.isBoardAdmin
| -
a.js-delete-all-lists {{_ 'delete-all'}}
ul.archived-lists
each archivedLists
li.archived-lists-item
@@ -35,8 +38,9 @@ template(name="archivesSidebar")
unless isWorker
p.quiet
a.js-restore-list {{_ 'restore'}}
| -
a.js-delete-list {{_ 'delete'}}
if currentUser.isBoardAdmin
| -
a.js-delete-list {{_ 'delete'}}
else
li.no-items-message {{_ 'no-archived-lists'}}
@@ -44,8 +48,9 @@ template(name="archivesSidebar")
unless isWorker
p.quiet
a.js-restore-all-swimlanes {{_ 'restore-all'}}
| -
a.js-delete-all-swimlanes {{_ 'delete-all'}}
if currentUser.isBoardAdmin
| -
a.js-delete-all-swimlanes {{_ 'delete-all'}}
ul.archived-lists
each archivedSwimlanes
li.archived-lists-item
@@ -54,8 +59,9 @@ template(name="archivesSidebar")
unless isWorker
p.quiet
a.js-restore-swimlane {{_ 'restore'}}
| -
a.js-delete-swimlane {{_ 'delete'}}
if currentUser.isBoardAdmin
| -
a.js-delete-swimlane {{_ 'delete'}}
else
li.no-items-message {{_ 'no-archived-swimlanes'}}
else
@@ -141,6 +141,9 @@ BlazeComponent.extendComponent({
}).register('archivesSidebar');
Template.archivesSidebar.helpers({
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
isWorker() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return (
@@ -155,7 +155,7 @@ template(name="multiselectionSidebar")
i.fa.fa-check
else if someSelectedElementHave 'member' _id
i.fa.fa-ellipsis-h
unless currentUser.isWorker
if currentUser.isBoardAdmin
hr
a.sidebar-btn.js-move-selection
i.fa.fa-share
@@ -134,6 +134,15 @@ BlazeComponent.extendComponent({
},
}).register('multiselectionSidebar');
Template.multiselectionSidebar.helpers({
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
isCommentOnly() {
return Meteor.user().isCommentOnly();
},
});
Template.disambiguateMultiLabelPopup.events({
'click .js-remove-label'() {
mutateSelectedCards('removeLabel', this._id);
@@ -15,8 +15,9 @@ template(name="swimlaneFixedHeader")
= title
.swimlane-header-menu
unless currentUser.isCommentOnly
a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon
a.fa.fa-navicon.js-open-swimlane-menu
if currentUser.isBoardAdmin
a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon
a.fa.fa-navicon.js-open-swimlane-menu
unless isMiniScreen
if showDesktopDragHandles
a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle
@@ -41,6 +41,12 @@ Template.swimlaneHeader.helpers({
},
});
Template.swimlaneFixedHeader.helpers({
isBoardAdmin() {
return Meteor.user().isBoardAdmin();
},
});
Template.swimlaneActionPopup.events({
'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'),
'click .js-close-swimlane'(event) {
@@ -50,6 +56,12 @@ Template.swimlaneActionPopup.events({
},
});
Template.swimlaneActionPopup.helpers({
isCommentOnly() {
return Meteor.user().isCommentOnly();
},
});
BlazeComponent.extendComponent({
onCreated() {
this.currentSwimlane = this.currentData();
+16 -15
View File
@@ -45,18 +45,19 @@ template(name="listsGroup")
template(name="addListForm")
unless currentUser.isWorker
.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'}}"
autocomplete="off" autofocus)
.edit-controls.clearfix
button.primary.confirm(type="submit") {{_ 'save'}}
unless currentBoard.isTemplatesBoard
unless currentBoard.isTemplateBoard
span.quiet
| {{_ 'or'}}
a.js-list-template {{_ 'template'}}
else
a.open-list-composer.js-open-inlined-form
i.fa.fa-plus
| {{_ 'add-list'}}
if currentUser.isBoardAdmin
.list-header-add
+inlinedForm(autoclose=false)
input.list-name-input.full-line(type="text" placeholder="{{_ 'add-list'}}"
autocomplete="off" autofocus)
.edit-controls.clearfix
button.primary.confirm(type="submit") {{_ 'save'}}
unless currentBoard.isTemplatesBoard
unless currentBoard.isTemplateBoard
span.quiet
| {{_ 'or'}}
a.js-list-template {{_ 'template'}}
else
a.open-list-composer.js-open-inlined-form
i.fa.fa-plus
| {{_ 'add-list'}}
+5 -3
View File
@@ -122,7 +122,8 @@ function initSortable(boardComponent, $listsDom) {
'option',
'disabled',
// Disable drag-dropping when user is not member/is worker
!userIsMember() || Meteor.user().isWorker(),
//!userIsMember() || Meteor.user().isWorker(),
!Meteor.user().isBoardAdmin(),
// Not disable drag-dropping while in multi-selection mode
// MultiSelection.isActive() || !userIsMember(),
);
@@ -274,12 +275,13 @@ Template.swimlane.helpers({
}
},
canSeeAddList() {
return (
return Meteor.user().isBoardAdmin();
/*
Meteor.user() &&
Meteor.user().isBoardMember() &&
!Meteor.user().isCommentOnly() &&
!Meteor.user().isWorker()
);
*/
},
});
+7 -1
View File
@@ -85,10 +85,16 @@
.swimlane-header-menu
position: absolute
padding: 5px 5px
font-size: 22px
.swimlane-header-plus-icon
margin-left: 5px
margin-right: 10px
padding-right: 20px
font-size: 22px
.swimlane-header-menu-icon
padding-right: 20px
font-size: 22px
.swimlane-header-handle
position: absolute
+28 -12
View File
@@ -13,6 +13,34 @@ template(name="headerUserBar")
template(name="memberMenuPopup")
ul.pop-over-list
with currentUser
li
a.js-my-cards(href="{{pathFor 'my-cards'}}")
i.fa.fa-list
| {{_ 'my-cards'}}
li
a(href="{{pathFor 'home'}}")
span.fa.fa-home
| {{_ 'all-boards'}}
li
a(href="{{pathFor 'public'}}")
span.fa.fa-globe
| {{_ 'public'}}
li
a.board-header-btn.js-open-archived-board
i.fa.fa-archive
span {{_ 'archives'}}
unless currentUser.isWorker
ul.pop-over-list
li
a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}")
i.fa.fa-clone
| {{_ 'templates'}}
if currentUser.isAdmin
li
a.js-go-setting(href="{{pathFor 'setting'}}")
i.fa.fa-lock
| {{_ 'admin-panel'}}
hr
li
a.js-edit-profile
i.fa.fa-user
@@ -34,18 +62,6 @@ template(name="memberMenuPopup")
a.js-change-language
i.fa.fa-flag
| {{_ 'changeLanguagePopup-title'}}
if currentUser.isAdmin
li
a.js-go-setting(href="{{pathFor 'setting'}}")
i.fa.fa-lock
| {{_ 'admin-panel'}}
unless currentUser.isWorker
hr
ul.pop-over-list
li
a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}")
i.fa.fa-clone
| {{_ 'templates'}}
unless isSandstorm
hr
ul.pop-over-list
+6
View File
@@ -25,6 +25,12 @@ Template.memberMenuPopup.helpers({
});
Template.memberMenuPopup.events({
'click .js-my-cards'() {
Popup.close();
},
'click .js-open-archived-board'() {
Modal.open('archivedBoards');
},
'click .js-edit-profile': Popup.open('editProfile'),
'click .js-change-settings': Popup.open('changeSettings'),
'click .js-change-avatar': Popup.open('changeAvatar'),
-2
View File
@@ -195,8 +195,6 @@ Utils = {
const currentUser = Meteor.user();
if (currentUser) {
return (currentUser.profile || {}).showDesktopDragHandles;
} else if (cookies.has('showDesktopDragHandles')) {
return true;
} else {
return false;
}
+26
View File
@@ -113,6 +113,32 @@ FlowRouter.route('/shortcuts', {
},
});
FlowRouter.route('/my-cards', {
name: 'my-cards',
action() {
const myCardsTemplate = 'myCards';
Filter.reset();
// EscapeActions.executeAll();
EscapeActions.executeUpTo('popup-close');
Utils.manageCustomUI();
Utils.manageMatomo();
// if (previousPath) {
// Modal.open(myCardsTemplate, {
// header: 'myCardsModalTitle',
// onCloseGoTo: previousPath,
// });
// } else {
BlazeLayout.render('defaultLayout', {
headerBar: 'myCardsHeaderBar',
content: myCardsTemplate,
});
// }
},
});
FlowRouter.route('/import/:source', {
name: 'import',
triggersEnter: [AccountsTemplates.ensureSignedIn],
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+17 -1
View File
@@ -774,6 +774,8 @@
"display-authentication-method": "Zobraz způsob ověřování",
"default-authentication-method": "Zobraz způsob ověřování",
"duplicate-board": "Duplikovat tablo",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "The number of people is:",
"swimlaneDeletePopup-title": "Smazat Swimlane ?",
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
@@ -807,6 +809,10 @@
"addmore-detail": "Přidat detailnější popis",
"show-on-card": "Zobrazit na kartě",
"new": "Nový",
"editOrgPopup-title": "Edit Organization",
"newOrgPopup-title": "New Organization",
"editTeamPopup-title": "Edit Team",
"newTeamPopup-title": "New Team",
"editUserPopup-title": "Editovat uživatele",
"newUserPopup-title": "Nový uživatel",
"notifications": "Upozornění",
@@ -836,5 +842,15 @@
"hide-checked-items": "Skrýt zvolené položky",
"task": "Úkol",
"create-task": "Vytvořit úkol",
"ok": "OK"
"ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person",
"my-cards": "My Cards",
"card": "Karta",
"list": "List",
"board": "Board"
}
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+17 -1
View File
@@ -774,6 +774,8 @@
"display-authentication-method": "Display Authentication Method",
"default-authentication-method": "Default Authentication Method",
"duplicate-board": "Duplicate Board",
"org-number": "The number of organizations is: ",
"team-number": "The number of teams is: ",
"people-number": "The number of people is: ",
"swimlaneDeletePopup-title": "Delete Swimlane ?",
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
@@ -807,6 +809,10 @@
"addmore-detail": "Add a more detailed description",
"show-on-card": "Show on Card",
"new": "New",
"editOrgPopup-title": "Edit Organization",
"newOrgPopup-title": "New Organization",
"editTeamPopup-title": "Edit Team",
"newTeamPopup-title": "New Team",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User",
"notifications": "Notifications",
@@ -836,5 +842,15 @@
"hide-checked-items": "Hide checked items",
"task": "Task",
"create-task": "Create Task",
"ok": "OK"
"ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person",
"my-cards": "My Cards",
"card": "Card",
"list": "List",
"board": "Board"
}
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+17 -1
View File
@@ -774,6 +774,8 @@
"display-authentication-method": "הצגת שיטת אימות",
"default-authentication-method": "שיטת אימות כבררת מחדל",
"duplicate-board": "שכפול לוח",
"org-number": "מספר הארגונים הוא:",
"team-number": "מספר הצוותים הוא:",
"people-number": "מספר האנשים הוא:",
"swimlaneDeletePopup-title": "למחוק מסלול?",
"swimlane-delete-pop": "כל הפעולות יוסרו מהזנת הפעילות ולא תהיה לך אפשרות לשחזר את המסלול. אי אפשר לחזור אחורה.",
@@ -807,6 +809,10 @@
"addmore-detail": "הוספת תיאור מפורט",
"show-on-card": "הצגה על הכרטיס",
"new": "חדש",
"editOrgPopup-title": "עריכת ארגון",
"newOrgPopup-title": "ארגון חדש",
"editTeamPopup-title": "עריכת צוות",
"newTeamPopup-title": "צוות חדש",
"editUserPopup-title": "עריכת משתמש",
"newUserPopup-title": "משתמש חדש",
"notifications": "הודעות",
@@ -836,5 +842,15 @@
"hide-checked-items": "הסתרת הפריטים שסומנו",
"task": "משימה",
"create-task": "צירת משימה",
"ok": "אישור"
"ok": "אישור",
"organizations": "ארגונים",
"teams": "צוותים",
"displayName": "שם התצוגה",
"shortName": "שם קצר",
"website": "אתר",
"person": "איש/ה",
"my-cards": "My Cards",
"card": "כרטיס",
"list": "List",
"board": "Board"
}
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+17 -1
View File
@@ -774,6 +774,8 @@
"display-authentication-method": "Display Authentication Method",
"default-authentication-method": "Default Authentication Method",
"duplicate-board": "보드 복사",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "The number of people is:",
"swimlaneDeletePopup-title": "Delete Swimlane ?",
"swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.",
@@ -807,6 +809,10 @@
"addmore-detail": "자세한 설명 추가",
"show-on-card": "Show on Card",
"new": "New",
"editOrgPopup-title": "Edit Organization",
"newOrgPopup-title": "New Organization",
"editTeamPopup-title": "Edit Team",
"newTeamPopup-title": "New Team",
"editUserPopup-title": "Edit User",
"newUserPopup-title": "New User",
"notifications": "알림",
@@ -836,5 +842,15 @@
"hide-checked-items": "선택된 항목 숨기기",
"task": "과제",
"create-task": "과제 생성",
"ok": "확인"
"ok": "확인",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person",
"my-cards": "My Cards",
"card": "카드",
"list": "List",
"board": "Board"
}
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+17 -1
View File
@@ -774,6 +774,8 @@
"display-authentication-method": "Toon Authenticatiemethode",
"default-authentication-method": "Standaard Authenticatiemethode",
"duplicate-board": "Dupliceer Bord",
"org-number": "Het aantal organisaties is:",
"team-number": "Het aantal teams is:",
"people-number": "Het aantal gebruikers is:",
"swimlaneDeletePopup-title": "Swimlane verwijderen?",
"swimlane-delete-pop": "Alle acties zullen verwijderd worden van de activiteiten feed en je kunt de swimlane niet terughalen. Er is geen herstelmogelijkheid.",
@@ -807,6 +809,10 @@
"addmore-detail": "Voeg een meer gedetailleerde beschrijving toe",
"show-on-card": "Toon op kaart",
"new": "Nieuw",
"editOrgPopup-title": "Bewerk organisatie",
"newOrgPopup-title": "Nieuwe organisatie",
"editTeamPopup-title": "Bewerk team",
"newTeamPopup-title": "Nieuw team",
"editUserPopup-title": "Wijzig gebruiker",
"newUserPopup-title": "Nieuwe gebruiker",
"notifications": "Meldingen",
@@ -836,5 +842,15 @@
"hide-checked-items": "Verberg aangevinkte items",
"task": "Taak",
"create-task": "Taak aanmaken",
"ok": "OK"
"ok": "OK",
"organizations": "Organisaties",
"teams": "Teams",
"displayName": "Schermnaam",
"shortName": "Korte naam",
"website": "Website",
"person": "Persoon",
"my-cards": "Mijn kaarten",
"card": "Kaart",
"list": "Lijst",
"board": "Bord"
}
+855 -839
View File
File diff suppressed because it is too large. Load diff
+17 -1
View File
@@ -774,6 +774,8 @@
"display-authentication-method": "Wyświetl metodę logowania",
"default-authentication-method": "Domyślna metoda logowania",
"duplicate-board": "Duplikuj tablicę",
"org-number": "Liczba organizacji:",
"team-number": "Liczba zespołów:",
"people-number": "Liczba użytkowników to:",
"swimlaneDeletePopup-title": "Usunąć ścieżkę?",
"swimlane-delete-pop": "Wszystkie zdarzenia dotyczące tej ścieżki zostaną usunięte z historii aktywności. Tej operacji nie można cofnąć. Usunięcie jest nieodwracalne.",
@@ -807,6 +809,10 @@
"addmore-detail": "Dodaj bardziej szczegółowy opis",
"show-on-card": "Pokaż na karcie",
"new": "Nowy",
"editOrgPopup-title": "Edit Organization",
"newOrgPopup-title": "New Organization",
"editTeamPopup-title": "Edit Team",
"newTeamPopup-title": "New Team",
"editUserPopup-title": "Edytuj użytkownika",
"newUserPopup-title": "Nowy użytkownik",
"notifications": "Powiadomienia",
@@ -836,5 +842,15 @@
"hide-checked-items": "Ukryj ukończone",
"task": "Zadanie",
"create-task": "Utwórz zadanie",
"ok": "OK"
"ok": "OK",
"organizations": "Organizacje",
"teams": "Zespoły",
"displayName": "Nazwa wyświetlana",
"shortName": "Nazwa skrócona",
"website": "Strona internetowa",
"person": "Osoba",
"my-cards": "My Cards",
"card": "karty",
"list": "List",
"board": "Board"
}
+17 -1
View File
@@ -774,6 +774,8 @@
"display-authentication-method": "Mostrar Método de Autenticação",
"default-authentication-method": "Método de Autenticação Padrão",
"duplicate-board": "Duplicar Quadro",
"org-number": "O número de organizações é:",
"team-number": "O número de times é:",
"people-number": "O número de pessoas é:",
"swimlaneDeletePopup-title": "Excluir Raia?",
"swimlane-delete-pop": "Todas as ações serão excluídas da lista de atividades e você não poderá recuperar a raia. Não há como desfazer.",
@@ -807,6 +809,10 @@
"addmore-detail": "Adicionar descrição detalhada",
"show-on-card": "Mostrar no Cartão",
"new": "Novo",
"editOrgPopup-title": "Editar Organização",
"newOrgPopup-title": "Nova Organização",
"editTeamPopup-title": "Editar Time",
"newTeamPopup-title": "Novo Time",
"editUserPopup-title": "Editar usuário",
"newUserPopup-title": "Novo usuário",
"notifications": "Notificações",
@@ -836,5 +842,15 @@
"hide-checked-items": "Esconder itens marcados",
"task": "Tarefa",
"create-task": "Criar Tarefa",
"ok": "OK"
"ok": "OK",
"organizations": "Organizações",
"teams": "Times",
"displayName": "Nome em exibição",
"shortName": "Nome curto",
"website": "Website",
"person": "Pessoa",
"my-cards": "My Cards",
"card": "Cartão",
"list": "List",
"board": "Board"
}
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+17 -1
View File
@@ -774,6 +774,8 @@
"display-authentication-method": "Показывать способ авторизации",
"default-authentication-method": "Способ авторизации по умолчанию",
"duplicate-board": "Клонировать доску",
"org-number": "Количество организаций:",
"team-number": "Количество команд:",
"people-number": "Количество человек:",
"swimlaneDeletePopup-title": "Удалить дорожку?",
"swimlane-delete-pop": "Все действия будут удалены из ленты активности участников, и вы не сможете восстановить дорожку. Данное действие необратимо.",
@@ -807,6 +809,10 @@
"addmore-detail": "Добавить более детальное описание",
"show-on-card": "Показать на карточке",
"new": "Новый",
"editOrgPopup-title": "Редактировать организацию",
"newOrgPopup-title": "Новая организация",
"editTeamPopup-title": "Редактировать команду",
"newTeamPopup-title": "Новая команда",
"editUserPopup-title": "Редактировать пользователя",
"newUserPopup-title": "Новый пользователь",
"notifications": "Уведомления",
@@ -836,5 +842,15 @@
"hide-checked-items": "Спрятать отмеченные",
"task": "Задача",
"create-task": "Создать задачу",
"ok": "Ok"
"ok": "Ok",
"organizations": "Организации",
"teams": "Команды",
"displayName": "Отображаемое название",
"shortName": "Короткое название",
"website": "Вебсайт",
"person": "Представитель",
"my-cards": "My Cards",
"card": "Карточка",
"list": "List",
"board": "Board"
}
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+855 -839
View File
File diff suppressed because it is too large. Load diff
+17 -1
View File
@@ -774,6 +774,8 @@
"display-authentication-method": "顯示認證方式",
"default-authentication-method": "預設認證方式",
"duplicate-board": "複製看板",
"org-number": "The number of organizations is:",
"team-number": "The number of teams is:",
"people-number": "人數是:",
"swimlaneDeletePopup-title": "是否刪除泳道?",
"swimlane-delete-pop": "所有動作將從活動來源中刪除,您將無法恢復泳道。此操作無法還原。",
@@ -807,6 +809,10 @@
"addmore-detail": "新增更多詳細描述",
"show-on-card": "在卡片上顯示",
"new": "新增",
"editOrgPopup-title": "Edit Organization",
"newOrgPopup-title": "New Organization",
"editTeamPopup-title": "Edit Team",
"newTeamPopup-title": "New Team",
"editUserPopup-title": "編輯使用者",
"newUserPopup-title": "新增使用者",
"notifications": "通知",
@@ -836,5 +842,15 @@
"hide-checked-items": "隱藏已勾選項目",
"task": "任務",
"create-task": "建立任務",
"ok": "OK"
"ok": "OK",
"organizations": "Organizations",
"teams": "Teams",
"displayName": "Display Name",
"shortName": "Short Name",
"website": "Website",
"person": "Person",
"my-cards": "My Cards",
"card": "卡片",
"list": "List",
"board": "Board"
}
+17 -3
View File
@@ -42,9 +42,23 @@ Meteor.methods({
check(currentBoardId, Match.Maybe(String));
const exporter = new Exporter(sourceBoardId);
const data = exporter.build();
const addData = {};
addData.membersMapping = getMembersToMap(data);
const creator = new WekanCreator(addData);
const additionalData = {};
//get the members to map
const membersMapping = getMembersToMap(data);
//now mirror the mapping done in finishImport in client/components/import/import.js:
if (membersMapping) {
const mappingById = {};
membersMapping.forEach(member => {
if (member.wekanId) {
mappingById[member.id] = member.wekanId;
}
});
additionalData.membersMapping = mappingById;
}
const creator = new WekanCreator(additionalData);
//data.title = `${data.title } - ${ TAPi18n.__('copy-tag')}`;
data.title = `${data.title}`;
return creator.create(data, currentBoardId);
+53 -33
View File
@@ -1,7 +1,7 @@
Org = new Mongo.Collection('org');
/**
* A Organization in wekan
* A Organization in Wekan. A Enterprise in Trello.
*/
Org.attachSchema(
new SimpleSchema({
@@ -18,76 +18,96 @@ Org.attachSchema(
}
},
},
version: {
displayName: {
/**
* the version of the organization
* the name to display for the organization
*/
type: Number,
type: String,
optional: true,
},
name: {
desc: {
/**
* name of the organization
* the description the organization
*/
type: String,
optional: true,
max: 190,
},
address1: {
name: {
/**
* address1 of the organization
* short name of the organization
*/
type: String,
optional: true,
max: 255,
},
address2: {
website: {
/**
* address2 of the organization
* website of the organization
*/
type: String,
optional: true,
max: 255,
},
city: {
teams: {
/**
* city of the organization
* List of teams of a organization
*/
type: String,
optional: true,
max: 255,
type: [Object],
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert && !this.isSet) {
return [
{
teamId: this.teamId,
isAdmin: true,
isActive: true,
isNoComments: false,
isCommentOnly: false,
isWorker: false,
},
];
}
},
},
state: {
'teams.$.teamId': {
/**
* state of the organization
* The uniq ID of the team
*/
type: String,
optional: true,
max: 255,
},
zipCode: {
'teams.$.isAdmin': {
/**
* zipCode of the organization
* Is the team an admin of the board?
*/
type: String,
optional: true,
max: 50,
type: Boolean,
},
country: {
'teams.$.isActive': {
/**
* country of the organization
* Is the team active?
*/
type: String,
optional: true,
max: 255,
type: Boolean,
},
billingEmail: {
'teams.$.isNoComments': {
/**
* billingEmail of the organization
* Is the team not allowed to make comments
*/
type: String,
type: Boolean,
optional: true,
},
'teams.$.isCommentOnly': {
/**
* Is the team only allowed to comment on the board
*/
type: Boolean,
optional: true,
},
'teams.$.isWorker': {
/**
* Is the team only allowed to move card, assign himself to card and comment
*/
type: Boolean,
optional: true,
max: 255,
},
createdAt: {
/**
+90
View File
@@ -0,0 +1,90 @@
Team = new Mongo.Collection('team');
/**
* A Team in Wekan. Organization in Trello.
*/
Team.attachSchema(
new SimpleSchema({
_id: {
/**
* the organization id
*/
type: Number,
optional: true,
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert && !this.isSet) {
return incrementCounter('counters', 'orgId', 1);
}
},
},
displayName: {
/**
* the name to display for the team
*/
type: String,
optional: true,
},
desc: {
/**
* the description the team
*/
type: String,
optional: true,
max: 190,
},
name: {
/**
* short name of the team
*/
type: String,
optional: true,
max: 255,
},
website: {
/**
* website of the team
*/
type: String,
optional: true,
max: 255,
},
createdAt: {
/**
* creation date of the team
*/
type: Date,
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert) {
return new Date();
} else if (this.isUpsert) {
return { $setOnInsert: new Date() };
} else {
this.unset();
}
},
},
modifiedAt: {
type: Date,
denyUpdate: false,
// eslint-disable-next-line consistent-return
autoValue() {
if (this.isInsert || this.isUpsert || this.isUpdate) {
return new Date();
} else {
this.unset();
}
},
},
}),
);
if (Meteor.isServer) {
// Index for Team name.
Meteor.startup(() => {
Team._collection._ensureIndex({ name: -1 });
});
}
export default Team;
+53 -2
View File
@@ -616,6 +616,15 @@ Users.mutations({
},
};
},
setName(value) {
return {
$set: {
'profile.fullname': value,
},
};
},
toggleDesktopHandles(value = false) {
return {
$set: {
@@ -752,7 +761,6 @@ if (Meteor.isServer) {
throw new Meteor.Error('email-already-taken');
} else {
Accounts.createUser({
fullname,
username,
password,
isAdmin,
@@ -760,6 +768,12 @@ if (Meteor.isServer) {
email: email.toLowerCase(),
from: 'admin',
});
user = Users.findOne(username) || Users.findOne({ username });
if (user) {
Users.update(user._id, {
$set: { 'profile.fullname': fullname },
});
}
}
}
},
@@ -822,6 +836,34 @@ if (Meteor.isServer) {
}
}
},
setEmailVerified(email, verified, userId) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(email, String);
check(verified, Boolean);
check(userId, String);
Users.update(userId, {
$set: {
emails: [
{
address: email,
verified,
},
],
},
});
}
},
setInitials(initials, userId) {
if (Meteor.user() && Meteor.user().isAdmin) {
check(initials, String);
check(userId, String);
Users.update(userId, {
$set: {
'profile.initials': initials,
},
});
}
},
// we accept userId, username, email
inviteUserToBoard(username, boardId) {
check(username, String);
@@ -1631,7 +1673,16 @@ if (Meteor.isServer) {
try {
Authentication.checkUserId(req.userId);
const id = req.params.userId;
Meteor.users.remove({ _id: id });
// Delete is not enabled yet, because it does leave empty user avatars
// to boards: boards members, card members and assignees have
// empty users. See:
// - wekan/client/components/settings/peopleBody.jade deleteButton
// - wekan/client/components/settings/peopleBody.js deleteButton
// - wekan/client/components/sidebar/sidebar.js Popup.afterConfirm('removeMember'
// that does now remove member from board, card members and assignees correctly,
// but that should be used to remove user from all boards similarly
// - wekan/models/users.js Delete is not enabled
// Meteor.users.remove({ _id: id });
JsonRoutes.sendResult(res, {
code: 200,
data: {
+127 -12
View File
@@ -15,6 +15,7 @@ export class WekanCreator {
cards: {},
lists: {},
swimlanes: {},
customFields: {},
};
// The object creator Wekan Id, indexed by the object Wekan id
// (so we only parse actions once!)
@@ -30,6 +31,8 @@ export class WekanCreator {
this.lists = {};
// Map of cards Wekan ID => Wekan ID
this.cards = {};
// Map of custom fields Wekan ID => Wekan ID
this.customFields = {};
// Map of comments Wekan ID => Wekan ID
this.commentIds = {};
// Map of attachments Wekan ID => Wekan ID
@@ -244,6 +247,7 @@ export class WekanCreator {
swimlaneId: false,
},
],
presentParentTask: boardToImport.presentParentTask,
// Standalone Export has modifiedAt missing, adding modifiedAt to fix it
modifiedAt: this._now(boardToImport.modifiedAt),
permission: boardToImport.permission,
@@ -352,10 +356,40 @@ export class WekanCreator {
cardToCreate.members = wekanMembers;
}
}
// add assignees
if (card.assignees) {
const wekanAssignees = [];
// we can't just map, as some members may not have been mapped
card.assignees.forEach(sourceMemberId => {
if (this.members[sourceMemberId]) {
const wekanId = this.members[sourceMemberId];
// we may map multiple Wekan members to the same wekan user
// in which case we risk adding the same user multiple times
if (!wekanAssignees.find(wId => wId === wekanId)) {
wekanAssignees.push(wekanId);
}
}
return true;
});
if (wekanAssignees.length > 0) {
cardToCreate.assignees = wekanAssignees;
}
}
// set color
if (card.color) {
cardToCreate.color = card.color;
}
// add custom fields
if (card.customFields) {
cardToCreate.customFields = card.customFields.map(field => {
return {
_id: this.customFields[field._id],
value: field.value,
};
});
}
// insert card
const cardId = Cards.direct.insert(cardToCreate);
// keep track of Wekan id => Wekan id
@@ -440,6 +474,12 @@ export class WekanCreator {
}
});
} else if (att.file) {
//If attribute type is null or empty string is set, assume binary stream
att.type =
!att.type || att.type.trim().length === 0
? 'application/octet-stream'
: att.type;
file.attachData(
Buffer.from(att.file, 'base64'),
{
@@ -481,6 +521,39 @@ export class WekanCreator {
return result;
}
/**
* Create the Wekan custom fields corresponding to the supplied Wekan
* custom fields.
* @param wekanCustomFields
* @param boardId
*/
createCustomFields(wekanCustomFields, boardId) {
wekanCustomFields.forEach((field, fieldIndex) => {
const fieldToCreate = {
boardIds: [boardId],
name: field.name,
type: field.type,
settings: field.settings,
showOnCard: field.showOnCard,
showLabelOnMiniCard: field.showLabelOnMiniCard,
automaticallyOnCard: field.automaticallyOnCard,
//use date "now" if now created at date is provided (e.g. for very old boards)
createdAt: this._now(this.createdAt.customFields[field._id]),
modifiedAt: field.modifiedAt,
};
//insert copy of custom field
const fieldId = CustomFields.direct.insert(fieldToCreate);
//set modified date to now
CustomFields.direct.update(fieldId, {
$set: {
modifiedAt: this._now(),
},
});
//store mapping of old id to new id
this.customFields[field._id] = fieldId;
});
}
// Create labels if they do not exist and load this.labels.
createLabels(wekanLabels, board) {
wekanLabels.forEach(label => {
@@ -560,6 +633,35 @@ export class WekanCreator {
});
}
createSubtasks(wekanCards) {
wekanCards.forEach(card => {
// get new id of card (in created / new board)
const cardIdInNewBoard = this.cards[card._id];
//If there is a mapped parent card, use the mapped card
// this means, the card and parent were in the same source board
//If there is no mapped parent card, use the original parent id,
// this should handle cases where source and parent are in different boards
// Note: This can only handle board cloning (within the same wekan instance).
// When importing boards between instances the IDs are definitely
// lost if source and parent are two different boards
// This is not the place to fix it, the entire subtask system needs to be rethought there.
const parentIdInNewBoard = this.cards[card.parentId]
? this.cards[card.parentId]
: card.parentId;
//if the parent card exists, proceed
if (Cards.findOne(parentIdInNewBoard)) {
//set parent id of the card in the new board to the new id of the parent
Cards.direct.update(cardIdInNewBoard, {
$set: {
parentId: parentIdInNewBoard,
},
});
}
});
}
createChecklists(wekanChecklists) {
const result = [];
wekanChecklists.forEach((checklist, checklistIndex) => {
@@ -620,18 +722,24 @@ export class WekanCreator {
createChecklistItems(wekanChecklistItems) {
wekanChecklistItems.forEach((checklistitem, checklistitemIndex) => {
// Create the checklistItem
const checklistItemTocreate = {
title: checklistitem.title,
checklistId: this.checklists[checklistitem.checklistId],
cardId: this.cards[checklistitem.cardId],
sort: checklistitem.sort ? checklistitem.sort : checklistitemIndex,
isFinished: checklistitem.isFinished,
};
const checklistItemId = ChecklistItems.direct.insert(
checklistItemTocreate,
);
this.checklistItems[checklistitem._id] = checklistItemId;
//Check if the checklist for this item (still) exists
//If a checklist was deleted, but items remain, the import would error out here
//Leading to no further checklist items being imported
if (this.checklists[checklistitem.checklistId]) {
// Create the checklistItem
const checklistItemTocreate = {
title: checklistitem.title,
checklistId: this.checklists[checklistitem.checklistId],
cardId: this.cards[checklistitem.cardId],
sort: checklistitem.sort ? checklistitem.sort : checklistitemIndex,
isFinished: checklistitem.isFinished,
};
const checklistItemId = ChecklistItems.direct.insert(
checklistItemTocreate,
);
this.checklistItems[checklistitem._id] = checklistItemId;
}
});
}
@@ -690,6 +798,11 @@ export class WekanCreator {
this.createdAt.swimlanes[swimlaneId] = activity.createdAt;
break;
}
case 'createCustomField': {
const customFieldId = activity.customFieldId;
this.createdAt.customFields[customFieldId] = activity.createdAt;
break;
}
}
});
}
@@ -840,7 +953,9 @@ export class WekanCreator {
const boardId = this.createBoardAndLabels(board);
this.createLists(board.lists, boardId);
this.createSwimlanes(board.swimlanes, boardId);
this.createCustomFields(board.customFields, boardId);
this.createCards(board.cards, boardId);
this.createSubtasks(board.cards);
this.createChecklists(board.checklists);
this.createChecklistItems(board.checklistItems);
this.importActivities(board.activities, boardId);
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v4.57.0",
"version": "v4.69.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2460,9 +2460,9 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
"integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ=="
},
"inquirer": {
"version": "6.5.2",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "wekan",
"version": "v4.57.0",
"version": "v4.69.0",
"description": "Open-Source kanban",
"private": true,
"scripts": {
+2 -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 v4.57">Wekan REST API v4.57</a>
<a href="#wekan-rest-api" class="toc-h1 toc-link" data-title="Wekan REST API v4.69">Wekan REST API v4.69</a>
</li>
@@ -2032,7 +2032,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 v4.57</h1>
<h1 id="wekan-rest-api">Wekan REST API v4.69</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>
Loaded 100 of 107 files, more files were not shown because too many files have changed in this diff. Show more