Compare commits

...
926 Commits
Author SHA1 Message Date
Lauri Ojansivu 79745d1892 v2.78 2019-06-12 06:34:46 +03:00
Lauri Ojansivu 8b31c0768c Try to fix OIDC login.
Thanks to xet7 !
2019-06-12 06:29:57 +03:00
Lauri Ojansivu 25e294fd92 v2.77 2019-06-11 20:27:17 +03:00
Lauri Ojansivu 017d2deeee Fix Snap build.
Thanks to xet7 !
2019-06-11 20:20:29 +03:00
Lauri Ojansivu e1e20275a6 v2.76 2019-06-11 17:03:01 +03:00
Lauri Ojansivu 3c4f8f6796 Support scopes in OAuth2, so Authentication via OAuth2 with Google is now possible.
Thanks to moserben16 !

Closes #2454
2019-06-11 16:56:45 +03:00
Lauri Ojansivu 406a9492fd Merge branch 'moserben16-patch-1' into devel 2019-06-11 16:51:36 +03:00
Lauri Ojansivu c859cd2278 Merge branch 'patch-1' of https://github.com/moserben16/wekan into moserben16-patch-1 2019-06-11 16:36:14 +03:00
Lauri Ojansivu cd70d9d09e Update changelog. 2019-06-11 16:34:36 +03:00
Lauri Ojansivu 86e7e1c600 More CORS headers settings related to https://github.com/wekan/wekan/pull/2429
Thanks to xet7 !
2019-06-11 16:32:42 +03:00
Lauri Ojansivu e540148d09 Update changelog. 2019-06-11 16:10:34 +03:00
Lauri Ojansivu 30b108ab36 Merge pull request #2442 from Jason-Cooke/patch-1
docs: fix typo
2019-06-11 16:07:58 +03:00
Lauri Ojansivu ec535aaa9c Update changelog. 2019-06-11 16:02:53 +03:00
Lauri Ojansivu bb108b2144 Merge branch 'road42-devel' into edge 2019-06-11 16:00:44 +03:00
Lauri Ojansivu f3c76ac60b Update ChangeLog. 2019-06-11 15:56:41 +03:00
Lauri Ojansivu 23ccb3b991 Show attachment name in Outgoing Webhook when attachment is removed from card.
Thanks to xet7 !

Related #2285
2019-06-11 13:11:35 +03:00
Lauri Ojansivu 992ecfefa2 Show attachment name in Outgoing Webhook when attachment is added to card.
Thanks to xet7 !

Related #2285
2019-06-11 10:53:50 +03:00
benji fd390d2560 Update oidc_server.js
with this fix, Authentication via OAuth2 with Google is possible.
1.) token endpoint and userinfo-endpoint in Google are different, so you have to check that,
2.) request the scopes of the environment variable "process.env.OAUTH2_REQUEST_PERMISSIONS"
with this small little fix the login with google in oauth2-protocol gets possible :-)
I would be very happy about a master-merge

thank you in advance
2019-06-11 09:23:12 +02:00
Lauri Ojansivu 3f1ac6b5db Update translations. 2019-06-10 18:57:07 +03:00
Lauri Ojansivu d8f112278b Additional CORS headers settings, added earlier. In progress. 2019-06-10 18:29:33 +03:00
Christoph Jahn 0704cfb8b6 isAdmin and isBoardAdmin should add rules 2019-06-08 22:04:09 +02:00
Jason Cooke 5e806c3879 docs: fix typo 2019-06-01 09:57:45 +12:00
Christoph Jahn 27b0fd35b4 Allow BoardAdmin to create board rules. #2431 2019-05-28 17:41:39 +02:00
Lauri Ojansivu 5c1818fc9a Update changelog. 2019-05-24 22:38:23 +03:00
Lauri Ojansivu a7fb9662e3 Merge branch 'risacher-master' into edge 2019-05-24 22:35:35 +03:00
Daniel Risacher cb00cfc1b7 Add support for more CORS headers 2019-05-24 12:39:54 -04:00
Lauri Ojansivu d7bc8d100d Update changelog. 2019-05-23 11:47:50 +03:00
Lauri Ojansivu d067b3976c Merge pull request #2427 from DominikPf/OAuth2-fix
Fix Scope parsing Issue for OAuth2 Login with simple String
2019-05-23 11:43:10 +03:00
DominikPf 892ee60527 Fix Scope parsing Issue for OAuth2 Login 2019-05-23 10:28:08 +02:00
Lauri Ojansivu d83cb75f95 v2.75 2019-05-22 21:47:49 +03:00
Lauri Ojansivu 697aaa895d Update translations. 2019-05-22 21:44:23 +03:00
Lauri Ojansivu 8add28d328 Update changelog. 2019-05-22 21:42:59 +03:00
Lauri Ojansivu 634df8f6f2 - Fix: OAuth2 Requested Scopes are wrong / cannot be configured.
Thanks to DominikPf and xet7 !

Closes #2412
2019-05-22 21:37:01 +03:00
Lauri Ojansivu d194cc7a5a - [CAS allowed LDAP groups](https://github.com/wekan/meteor-accounts-cas/pull/4).
Thanks to ppoulard !

Please test.

Related #2356
2019-05-22 20:15:24 +03:00
Lauri Ojansivu 0834f6ed1e v2.74 2019-05-14 21:33:12 +03:00
Lauri Ojansivu 9d5e288bca Update changelog. 2019-05-14 21:29:46 +03:00
Lauri Ojansivu 0fe40ad9ec - Add missing [wekan-ldap#40](https://github.com/wekan/wekan-ldap/pull/40) code about LDAP_SYNC_ADMIN_STATUS.
Thanks to JulianJacobi, n-st, chirrut2 and xet7 !

Closes #2351
2019-05-14 21:24:11 +03:00
Lauri Ojansivu 0765278195 v2.73 2019-05-14 16:48:18 +03:00
Lauri Ojansivu f782b9c298 Update translations (fi). 2019-05-14 16:42:05 +03:00
Lauri Ojansivu e611685e50 Fix lint errors. 2019-05-14 16:37:41 +03:00
Lauri Ojansivu 3edef95c4e - [Few fixes for Dockerfile](https://github.com/wekan/wekan/pulls/2407).
Thanks to bentiss !
2019-05-14 16:31:13 +03:00
Lauri Ojansivu 9b902e1ca0 Merge pull request #2407 from bentiss/dockerfile-fixes
Few fixes for Dockerfile
2019-05-14 16:28:51 +03:00
Lauri Ojansivu fc835815d8 - [Card count placement and export API functionality back](https://github.com/wekan/wekan/pulls/2406).
Thanks to bentiss.

Closes #2403,
closes #2328
2019-05-14 16:27:15 +03:00
Lauri Ojansivu da083c2e20 Merge pull request #2406 from bentiss/fixes
card count placement and export API functionality back
2019-05-14 16:25:05 +03:00
Lauri Ojansivu 6ee17ab080 - Fixed [#2338](https://github.com/wekan/wekan/issues/2338) -> [Slow opening of big boards with too many archived items](https://github.com/wekan/wekan/pull/2402).
If some Wekan users see errors with this, please empty your browser cache.
  Thanks to nerminator.

Closes #2338
2019-05-14 16:23:52 +03:00
Benjamin Tissoires 1e34585548 Dockerfile: no need to change the permissions once again
we carefully used gosu where needed, so there is no need to re-run a
check on the permissions.
2019-05-14 10:33:41 +02:00
Benjamin Tissoires 76cd5a2844 Dockerfile: use gosu for creating the openapi files 2019-05-14 10:33:41 +02:00
Benjamin Tissoires ffd1b93abf Dockerfile: bump api2html to version 0.3.3 2019-05-14 10:33:41 +02:00
Benjamin Tissoires 1eea102f26 openAPI: also handle export statement in the scripts
The files are actually modules, not plain scripts, and thus we are allowed
to use `export`. Without `parseModule`, the script would silently fail
when parsing `export.js` and the export function will not be present.
2019-05-14 10:10:21 +02:00
Benjamin Tissoires 94c1367684 Restore export API
Commit 477d71e0b9 was based on an older version of export.js, which
means it reverted a few changes that were made previously.

Fixes #2328
2019-05-14 09:37:56 +02:00
Benjamin Tissoires 9bf19f81a4 Fix card count position
When introducing markdown in the title (b795115042), the card
count got pushed outside of the List Header.

Add its own style (by manually merge small and quiet), and restore its
original placement.

Fixes #2403
2019-05-14 09:37:34 +02:00
Lauri Ojansivu 21de0ec396 Merge pull request #2402 from nerminator/feature/performance_archive
Fixed #2338 -> Slow opening of big boards with too many archived items
2019-05-13 12:56:12 +03:00
wekan ab4fec0f3c Fixed #2338 -> Slow opening of big boards with too many archived items 2019-05-13 11:01:50 +02:00
Lauri Ojansivu b983479476 v2.72 2019-05-13 10:49:41 +03:00
Lauri Ojansivu f6e5e514ef Merge pull request #2401 from guyzyl/devel
Added BIDI support to "Add Card" #884
2019-05-13 10:42:42 +03:00
Guy Zylberberg ddd828083e Added BIDI support to "Add Card" #884 2019-05-13 00:37:40 +03:00
Lauri Ojansivu e079b4df17 v2.71 2019-05-12 20:49:27 +03:00
Lauri Ojansivu 4e5ff17e18 Update translations. 2019-05-12 20:43:23 +03:00
Lauri Ojansivu 86e1a9cd5d Update changelog. 2019-05-12 20:40:32 +03:00
Lauri Ojansivu 8a0efffdf8 Merge pull request #2400 from atilaromero/devel
Add partentId support on card web API
2019-05-12 20:27:50 +03:00
Lauri Ojansivu c21f710a70 Fix typo. 2019-05-12 19:15:49 +03:00
Atila Romero f3382abe3b Add partentId support on card web API 2019-05-12 10:26:08 -03:00
Lauri Ojansivu d6c86f3cba v2.70 2019-05-11 23:50:47 +03:00
Lauri Ojansivu 3a6516f0cb Update changelog. 2019-05-11 23:47:11 +03:00
Lauri Ojansivu b795115042 - [View markdown on List names, Custom Fields (Text and Dropdown), Label names,
All Boards view Board names and Board descriptions](https://github.com/wekan/wekan/issues/2334).

Thanks to shaygover and xet7 !

Related #2334
2019-05-11 23:40:18 +03:00
Lauri Ojansivu 52fe845d24 v2.69 2019-05-11 00:07:37 +03:00
Lauri Ojansivu b2b6bb2d39 Update changelog. 2019-05-11 00:05:34 +03:00
Lauri Ojansivu db40ca25ac - Fix translation name in Wekan menu: oc to Occitan.
Thanks to xet7 !
2019-05-11 00:02:40 +03:00
Lauri Ojansivu 3eef42eee0 v2.68 2019-05-10 23:18:12 +03:00
Lauri Ojansivu 38d0ad74a9 Update changelog. 2019-05-10 23:13:20 +03:00
Lauri Ojansivu 3bbc805ee4 Option to login to the LDAP server with the user's own username and password, instead of an administrator key. Default: false (use administrator key).
With new setting: LDAP_USER_AUTHENTICATION=true
Added to Snap, Docker and Source.

Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/2399
2019-05-10 23:04:51 +03:00
Lauri Ojansivu c37a454bd5 Merge branch 'thiagofernando-devel' into devel 2019-05-10 22:23:15 +03:00
Lauri Ojansivu 6f98be5608 Merge branch 'devel' of https://github.com/thiagofernando/wekan into thiagofernando-devel 2019-05-10 22:21:50 +03:00
Lauri Ojansivu ab4dab2ade v2.67 2019-05-10 21:01:34 +03:00
Lauri Ojansivu 88ffddfeba Update changelog. 2019-05-10 20:58:35 +03:00
Thiago Fernando 36f148a7cb Update loginHandler.js
additional option to login in ldap server with user account
2019-05-10 14:58:19 -03:00
Thiago Fernando fd1af07e43 Update ldap.js 2019-05-10 14:56:07 -03:00
Lauri Ojansivu fca87b53f0 Update changelog. 2019-05-10 20:55:35 +03:00
Thiago Fernando ce0473480b Merge pull request #1 from wekan/devel
ldap changes
2019-05-10 14:54:25 -03:00
Lauri Ojansivu 828f6ea321 - Add Feature: Move board to Archive button at each board at All Boards page.
Thanks to xet7 !

Related #2389
2019-05-10 20:50:53 +03:00
Lauri Ojansivu 7ff4067e88 v2.66 2019-05-09 16:32:34 +03:00
Lauri Ojansivu 491d27638a Delete user feature. 2019-05-09 16:24:13 +03:00
Lauri Ojansivu e1b016cf3d Prevent data loss.
Thanks to xet7 !
2019-05-09 16:17:53 +03:00
Lauri Ojansivu c850669777 Merge pull request #2384 from Akuket/origin/edge
Delete user feature
2019-05-09 16:06:17 +03:00
Lauri Ojansivu 04c7372a4e Update changelog. 2019-05-09 16:02:54 +03:00
Lauri Ojansivu 64ee60a008 Fix missing profile checks.
Thanks to justinr1234 !
2019-05-09 14:32:38 +03:00
Lauri Ojansivu 434ed895ed Merge pull request #2395 from guyzyl/devel
Fixed RTL issue #884
2019-05-09 14:24:35 +03:00
Guy Zylberberg 1bdc1017d6 Fixed RTL issue #884 2019-05-08 21:30:38 +03:00
Lauri Ojansivu 6218d8c7ed Update translations. 2019-05-08 18:20:49 +03:00
Lauri Ojansivu c250554177 Update translations. Add Chinese (Hong Kong). 2019-05-06 20:57:01 +03:00
Lauri Ojansivu de772a8c3b Update changelog. 2019-04-29 01:18:17 +03:00
Lauri Ojansivu 23f1cf5f49 Update translations. 2019-04-29 01:17:52 +03:00
Lauri Ojansivu 723fa11a74 Merge pull request #2385 from faust64/patch-1
fix(oidc): can not log in
2019-04-26 23:08:45 +03:00
Lauri Ojansivu 94b602e167 Update translations. 2019-04-26 23:07:38 +03:00
Samuel b17359ec6f fix(oidc): can not log in
Trying to configure wekan authenticating against LemonLDAP-NG, I used to read about errors like the following:

```
XXX: getUserInfo response:  { sub: 'demoone' }
XXX: userinfo: { sub: 'demoone' }
{"line":"431","file":"oauth.js","message":"Error in OAuth Server: id is not defined","time":{"$date":1556286530412},"level":"warn"}
Exception while invoking method 'login' { stack: 'ReferenceError: id is not defined\n    at Object.handleOauthRequest (packages/wekan-oidc.js:39:68)\n    at OAuth._requestHandlers.(anonymous function) (packages/oauth2.js:27:31)\n    at middleware (packages/oauth.js:203:5)\n    at packages/oauth.js:176:5',
source: 'method' }
```

Looking at the sources, that error message seems to be right: we have several references to `id`, `uid`, `displayName` or `email`, which are not defined. Probably a typo, assuming we meant these to be strings.

Applying that patch, I confirm I can finally log in:

```
XXX: getUserInfo response:  { sub: 'demoone' }
XXX: userinfo: { sub: 'demoone' }
XXX: serviceData: { id: undefined,
  username: undefined,
  fullname: undefined,
  accessToken: 'e57dc4e9e81cc98c279db3ed08b1c72f',
  expiresAt: 1556298699213,
  email: undefined }
XXX: profile: { name: undefined, email: undefined }
```

All the credit goes to @pcurie .
2019-04-26 18:21:42 +02:00
guillaume cdef8a33e4 Delete user feature 2019-04-26 17:53:48 +02:00
Lauri Ojansivu 11a91bfc78 Update translations. 2019-04-24 16:12:29 +03:00
Lauri Ojansivu aeb3dd0220 v2.65 2019-04-24 14:40:04 +03:00
Lauri Ojansivu 9647a33209 Update translations. 2019-04-24 14:01:38 +03:00
Lauri Ojansivu 2d966863e3 Merge branch 'Akuket-edge' into edge 2019-04-24 13:51:00 +03:00
Lauri Ojansivu a66632f767 Update translations. 2019-04-24 13:41:29 +03:00
Lauri Ojansivu 1c2ee631f4 Update changelog. 2019-04-24 13:37:19 +03:00
guillaume 259ff3436f fix lints 2019-04-24 12:35:00 +02:00
Lauri Ojansivu a750ecaafd - Remove from card menu, because they also exist at card:
members, labels, attachments, dates received/start/due/end.

Thanks to sfahrenholz, jrsupplee and xet7 !

Closes #2242,
related https://community.vanila.io/?t=517527b6-3d84-4e9d-b2ec-6f560a9cfdf7
2019-04-24 13:32:36 +03:00
guillaume 8b3601248d Loading authentication page 2019-04-24 12:28:11 +02:00
Lauri Ojansivu 6420020309 v2.64 2019-04-23 19:49:07 +03:00
Lauri Ojansivu 65d86a42d7 Update translations (es). 2019-04-23 19:45:54 +03:00
Lauri Ojansivu 4eaffdc6a4 [Board Archive: Delete Card/List/Swimlane](https://github.com/wekan/wekan/pull/2376).
Thanks to Akuket !

Closes #1625
2019-04-23 19:43:02 +03:00
Lauri Ojansivu 454e8a3962 Update translations. 2019-04-23 19:38:23 +03:00
Lauri Ojansivu 11e8a9d5c4 Merge branch 'Akuket-feature/removeArchived' into edge 2019-04-23 19:30:23 +03:00
guillaume 8137f2692f remove feature 2019-04-23 18:00:09 +02:00
Lauri Ojansivu 6933424fca Remove python2 from Dockerfile, to make Docker image smaller.
Thanks to xet7 !
2019-04-23 15:10:47 +03:00
Lauri Ojansivu ff8a10c231 v2.63 2019-04-23 14:41:33 +03:00
Lauri Ojansivu 6a94500170 Remove caddy plugins http.filter, http.ipfilter and http.realip from caddy
because they are currently broken, preventing download of caddy
during Wekan Snap build.

Thanks to xet7 !
2019-04-23 14:35:41 +03:00
Lauri Ojansivu 41eb47bc15 v2.62 2019-04-23 14:08:13 +03:00
Lauri Ojansivu 211f772447 Merge pull request #2374 from hupptechnologies/center-card-list-view
Issue : Mobile UI Center cards in list view #2371
2019-04-23 14:02:04 +03:00
Lauri Ojansivu 6d6e3fd127 Update translations. 2019-04-23 14:00:12 +03:00
hupptechnologies 14ef0ab6d1 Issue : Mobile UI Center cards in list view #2371
Resolved #2371
2019-04-23 15:09:09 +05:30
Lauri Ojansivu 8434069539 v2.61 2019-04-20 17:11:14 +03:00
Lauri Ojansivu c7621f251f Fix release build script. package repos are included to Wekan now. 2019-04-20 17:04:59 +03:00
Lauri Ojansivu a5122cc076 Update translations. 2019-04-20 16:47:54 +03:00
Lauri Ojansivu 5993d6862b Change enter => search 2019-04-20 16:46:26 +03:00
Lauri Ojansivu 348b612f98 Fix rebuild script. 2019-04-20 16:34:16 +03:00
Lauri Ojansivu f714b59c88 Uncomment not needed lines. 2019-04-20 16:31:10 +03:00
Lauri Ojansivu b627499acd Merge branch 'Akuket-edge' into edge 2019-04-20 16:29:08 +03:00
Lauri Ojansivu 43beccc2eb Update translations. 2019-04-20 16:28:03 +03:00
Lauri Ojansivu b8275b3404 Merge branch 'edge' of https://github.com/Akuket/wekan into Akuket-edge 2019-04-20 16:22:20 +03:00
Lauri Ojansivu 6e4da08164 LDAP issues now at main Wekan repo. 2019-04-20 16:21:21 +03:00
Lauri Ojansivu f2ac52bcdf Update changelog. 2019-04-20 16:20:00 +03:00
Lauri Ojansivu 46e976513b Move https://github.com/wekan/wekan-postgresql to
wekan/torodb-postgresql at https://github.com/wekan/wekan

Thanks to xet7 !
2019-04-20 16:05:54 +03:00
Lauri Ojansivu 816ccf6509 Update package names. 2019-04-20 15:24:09 +03:00
Lauri Ojansivu 73e265d8fd Include to Wekan packages directory contents, so that meteor command would build all directly.
This also simplifies build scripts.

Thanks to xet7 !
2019-04-20 15:18:33 +03:00
Lauri Ojansivu 6117097a93 - Upgrade to Node 8.16.0
- Change git repo urls from git:// to https://

Thanks to xet7 !
2019-04-20 14:52:37 +03:00
Lauri Ojansivu fee732dba1 Fix repo urls. 2019-04-20 14:47:33 +03:00
Lauri Ojansivu 1138e8062f Fix repo url. 2019-04-20 14:46:11 +03:00
Lauri Ojansivu 123cf0d7b8 Fix typos in directory names. 2019-04-20 14:03:35 +03:00
Lauri Ojansivu bd14ee3b1f Ubuntu base image to ubuntu:disco
Thanks to Ubuntu and xet7 !
2019-04-20 13:44:14 +03:00
guillaume e63eee0c68 fix lints 2019-04-19 16:39:14 +02:00
guillaume 070feb4b66 Number of users 2019-04-19 16:17:17 +02:00
guillaume 308417852c Search user in admin panel 2019-04-19 14:57:52 +02:00
Lauri Ojansivu 9c3a976250 - Remove [extra](https://github.com/wekan/wekan/pull/2332) [quotes](https://github.com/wekan/wekan/pull/2333) from docker-compose.yml.
Thanks to hibare !
2019-04-18 13:42:00 +03:00
Lauri Ojansivu 688973bae5 [Fix Full width of lists and space before first list](https://github.com/wekan/wekan/pull/2343).
Thanks to hupptehcnologies !

Closes #2336
2019-04-18 13:38:37 +03:00
Lauri Ojansivu d93b0be0d4 Add missing packages back. 2019-04-18 13:36:14 +03:00
Lauri Ojansivu 773abbae13 Merge pull request #2343 from hupptechnologies/improve-mobile-ui
Issue: Full width of lists and space before first list #2336
2019-04-18 13:35:20 +03:00
Lauri Ojansivu 0f3579fd7b Merge branch 'devel' into improve-mobile-ui 2019-04-18 13:34:40 +03:00
Lauri Ojansivu db7b7158fa Merge branch 'master' into devel 2019-04-18 13:30:49 +03:00
Lauri Ojansivu b5a61f2dd8 Merge pull request #2333 from hibare/devel
Removed quotes
2019-04-18 13:30:23 +03:00
Lauri Ojansivu 8347f15de2 Merge pull request #2332 from hibare/master
Removed quotes
2019-04-18 13:30:05 +03:00
Lauri Ojansivu 26309fad10 Update translations. 2019-04-18 13:26:46 +03:00
Lauri Ojansivu ba4d8b0b35 Update to newest GitHub flawored markdown.
Thanks to shaygover and xet7 !

Related #2334
2019-04-18 13:23:48 +03:00
hupp-mac-4 dc11e0c79c Issue: Full width of lists and space before first list #2336
Resolved #2336
2019-04-18 15:41:23 +05:30
Lauri Ojansivu a13d931cfd Change to correct issue number as noticed typo at #2295 2019-04-18 13:10:49 +03:00
Lauri Ojansivu fea2ad3d7d Test newest markdown. 2019-04-18 10:57:59 +03:00
Shubham Hibare b8c10def8e Removed quotes 2019-04-12 00:44:54 +05:30
Shubham Hibare 80afc28719 Removed quotes 2019-04-12 00:43:59 +05:30
Lauri Ojansivu 561cd77e68 Replace header login example variable names.
Related #2019
2019-04-08 12:01:26 +03:00
Lauri Ojansivu d8554ec67e Combine to same line. 2019-04-08 10:58:49 +03:00
Lauri Ojansivu a43237d4f9 v2.60 2019-04-08 10:31:48 +03:00
Lauri Ojansivu 6af7d782d4 Update translations. 2019-04-08 10:29:29 +03:00
Lauri Ojansivu 6d2b778ac5 [Fix: Description of Board is out of visible after Feature "Duplicate Board"](https://github.com/wekan/wekan/issues/2324).
Thanks to sfahrenholz and xet7 !

Closes #2324
2019-04-08 09:07:58 +03:00
Lauri Ojansivu eada773048 [Fix: Description of Board is out of visible after Feature "Duplicate Board"](https://github.com/wekan/wekan/issues/2324).
Thanks to sfahrenholz and xet7 !

Closes #2324
2019-04-08 09:03:55 +03:00
Lauri Ojansivu 9bff4e061e Update translations. 2019-04-07 18:27:17 +03:00
Lauri Ojansivu 753ce8e119 v2.59 2019-04-06 14:15:40 +03:00
Lauri Ojansivu 4be6719db4 - [Add variables for activity notifications, Fixes #2285](https://github.com/wekan/wekan/pull/2320).
Thanks to rinnaz !

Closes #2285
2019-04-06 14:07:55 +03:00
Lauri Ojansivu a6e1dc4269 Merge pull request #2320 from rinnaz/fix/issue-2285
Add variables for activity notifications Fixes #2285
2019-04-06 14:04:09 +03:00
Lauri Ojansivu ad241b9f84 v2.58 2019-04-06 13:54:32 +03:00
Lauri Ojansivu 53e76288cb [Add Duplicate Board tooltip, and remove adding text "Copy" to duplicated board](https://github.com/wekan/wekan/commit/0f15b6d1982c383f76e8411cb501ff27e8febd42).
Thanks to xet7 !
2019-04-06 13:52:05 +03:00
Lauri Ojansivu 0f15b6d198 - Add Duplicate Board tooltip, and remove adding text "Copy" to duplicated board.
Thanks to xet7 !
2019-04-06 13:47:15 +03:00
windblow 143e93f483 Add variables for activity notifications Fixes #2285 2019-04-06 12:45:31 +03:00
Lauri Ojansivu 93a5bb2baa Add the following new features:
- [Duplicate Board](https://github.com/wekan/wekan/issues/2257). Related #2225.
  Thanks to Angtrim. Closes #2257.

and fix the following bugs:

- [Fix Swimlane Rules don't work](https://github.com/wekan/wekan/issues/2225).
  Thanks to Angtrim.
2019-04-06 09:19:33 +03:00
Lauri Ojansivu ebfc8e5a1b Fix lint errors.
Thanks to xet7 !
2019-04-06 09:00:13 +03:00
Lauri Ojansivu 972b9b6e91 Remove extra files.
Thanks to xet7 !
2019-04-06 08:50:56 +03:00
Lauri Ojansivu 56cccc6781 Merge remote-tracking branch 'Angtrim/feature-duplicate' into edge 2019-04-06 08:46:40 +03:00
Lauri Ojansivu b680bb5372 - [Remove not needed ARGS from Dockerfile to reduce amount of Docker layers](https://github.com/wekan/wekan/issues/2301).
Thanks to folhabranca !

Closes #2301
2019-04-06 08:14:37 +03:00
Lauri Ojansivu 217b3ae488 Remove not needed ARGS from Dockerfile to reduce amount of Docker layers.
Thanks to folhabranca !

Closes #2301
2019-04-06 08:11:08 +03:00
Lauri Ojansivu 959392f815 [Center reduce left margin in card view on mobile browser](https://github.com/wekan/wekan/pull/2314).
Thanks to hupptechnologies !
2019-04-06 07:57:30 +03:00
Lauri Ojansivu d1e13e48fe Restore original meteor packages and versions.
Thanks to xet7 !
2019-04-06 07:47:08 +03:00
Lauri Ojansivu 1c04502963 Merge branch 'devel' of github.com:wekan/wekan into devel 2019-04-06 07:45:16 +03:00
Lauri Ojansivu 34da23783e Merge pull request #2314 from hupptechnologies/card-view-on-mobile-browser
Issue: Center reduce left margin in card view on mobile browser #2188
2019-04-06 07:45:03 +03:00
Lauri Ojansivu 2b603cfbb5 Merge branch 'edge' into devel 2019-04-06 07:44:03 +03:00
Lauri Ojansivu a1fe22c08c [Add proper variables for unjoin card](https://github.com/wekan/wekan/pull/2313).
Thanks to chotaire.
2019-04-06 07:43:14 +03:00
Lauri Ojansivu bc04ae24a7 Merge pull request #2313 from chotaire/edge
Add proper variables for unjoin card
2019-04-05 22:10:05 +03:00
Angelo Gallarello 48216e1653 Minor fixes 2019-04-05 10:38:39 +02:00
hupptechnologies 8aca82a593 Issue: Center (or reduce left margin) in card view on mobile browser #2188
Resolved #2188
2019-04-05 13:27:41 +05:30
chotaire 68d8cbe68a Merge pull request #1 from chotaire/chotaire-patch-1
Add proper variables for unjoin card
2019-04-05 03:03:57 +02:00
chotaire 4bc3acb14d Add proper variables for unjoin card 2019-04-05 02:59:35 +02:00
Lauri Ojansivu a974ec9dee Update translations. 2019-04-04 20:22:25 +03:00
Lauri Ojansivu e91c43466d Merge pull request #2303 from fossabot/devel
Add license scan report and status
2019-04-02 16:36:29 +03:00
fossabot dfc4ab6dd8 Add license scan report and status
Signed-off-by: fossabot <badges@fossa.io>
2019-04-02 06:32:34 -07:00
Lauri Ojansivu 9f5ffde2dd v2.57 2019-04-02 15:26:40 +03:00
Lauri Ojansivu 678bef2360 Update changelog. 2019-04-02 15:19:21 +03:00
Lauri Ojansivu 3b12cdc179 Merge branch 'bentiss-spinners-no-IntersectionObserver' into devel 2019-04-02 15:15:34 +03:00
Benjamin Tissoires 261754f18b list: do not use IntersectionObserver to reduce CPU usage
Switch back to a custom spinner detection, as the IntersectionObserver
is eating a lot of CPU resources on idle.

This should also take care of #2250 properly: the previous `onDestroyed()`
was removing the resize and scroll callbacks, but they were not unique
enough, and they were shared across swimlanes. So if a list had 2 swimlanes
with spinners, when one was removed, the other was not triggering its
callbacks anymore.

Related: #2294
2019-04-01 23:54:35 +02:00
Lauri Ojansivu 980db9cb0c Merge branch 'edge' of github.com:wekan/wekan into edge 2019-03-30 19:07:05 +02:00
Lauri Ojansivu a80cd455de - [Add back zoom fixes of #2250](https://github.com/wekan/wekan/issues/2250).
Thanks to xet7 !
2019-03-30 19:06:09 +02:00
Lauri Ojansivu 289e3d6286 More deps. 2019-03-30 14:34:32 +02:00
Lauri Ojansivu 4b181620d8 Added nodejs to install dependencies.
Thanks to xet7 !
2019-03-30 14:30:04 +02:00
Lauri Ojansivu 088ec7fd94 [Add proper variables for join card](https://github.com/wekan/wekan/commit/289f1fe1340c85eb2af19825f4972e9057a86b7a),
fixes [Incorrect variable replacement on email notifications](https://github.com/wekan/wekan/issues/2295).

Thanks to justinr1234 !

Closes #2295
2019-03-29 14:39:35 +02:00
Lauri Ojansivu 289f1fe134 Merge pull request #2291 from justinr1234/patch-3
Add proper variables for join card Fixes #2285
2019-03-29 14:35:06 +02:00
Lauri Ojansivu 6b9ac52af6 Update translations. 2019-03-29 14:34:24 +02:00
Lauri Ojansivu 0e422eb70d [Revert spinner etc fixes of Wekan v2.56, because of some new bugs](https://github.com/wekan/wekan/issues/2250).
Thanks to gerroon !

Related #2250
2019-03-29 14:31:26 +02:00
Lauri Ojansivu df32545b07 Revert spinner etc fixes of Wekan v2.56, because of some new bugs.
Thanks to gerroon !

Related #2250
2019-03-29 14:27:37 +02:00
justinr1234 bab340a849 Add proper variables for join card Fixes #2285 2019-03-28 19:38:02 -05:00
Lauri Ojansivu 494d44f8bb v2.56 2019-03-27 17:51:54 +02:00
Lauri Ojansivu ad1a81e8a0 Update translations. 2019-03-27 17:46:09 +02:00
Lauri Ojansivu b0d507c2dd [Fixes the following bugs](https://github.com/wekan/wekan/pull/2287):
- [#2250 -> the spinner could be shown on startup and never goes away](https://github.com/wekan/wekan/issues/2250).
- The code will now only load extra cards that will be in the current viewport.
- When 2 users were interacting on the same board, there was a situation where the spinner could show up on the other user, without being able to load the extra cards.
- The code is now much simpler, thanks to the IntersectionObserver, and all of this for fewer lines of code :)

Thanks to bentiss with Apache I-CLA !

Closes #2250
2019-03-27 17:38:54 +02:00
Lauri Ojansivu 619e5e944b Merge branch 'bentiss-fix-infinite-scroll' into edge 2019-03-27 17:33:53 +02:00
Benjamin Tissoires e2d0faa539 list: disconnect infinite-scroll observer to prevent memory leak 2019-03-26 16:28:25 +01:00
Benjamin Tissoires cbb6c82113 list: move the spinner into its own blaze component
This way, when a list is at the maximum number of cards shown and adding
a new card would make the spinner appear, the list would load the next
N items.

This can happen if user A and B are both looking at the same board,
B adds a new cards, and A will see the spinner and will not be able to
remove it.
2019-03-26 16:27:52 +01:00
Benjamin Tissoires 00376b43f8 list: make sure the spinner of infinite scrolling doesn't show on load
When loading a board on a high resolution screen, there is a chance there
is not enough cards displayed and the spinner is still there, spinning
forever.

Add an idle callback that checks if the spinner is still there, and while
it is there, extend the number of cards to show.

Fixes #2250
2019-03-26 16:26:59 +01:00
Benjamin Tissoires fb163a2493 list: simplify infinite scrolling
Use IntersectionObserver instead of custom made one.
This adds the benefit of not loading any extra cards if the list is
not shown on screen
2019-03-26 16:25:49 +01:00
Lauri Ojansivu 14c493fc63 v2.55 2019-03-25 19:11:35 +02:00
Lauri Ojansivu 625682a4da - Use older api2html@0.3.0 to fix broken snap and docker build,
because newer api2html caused
  [breaking change](https://github.com/tobilg/api2html/commit/a9a41bca18db3f9ec61395d7262eff071a995783)
  at api2html/bin/api2html.js:23 has error about "php: "PHP".

Thanks to bentiss with Apache I-CLA !

Closes #2286
2019-03-25 18:57:35 +02:00
Lauri Ojansivu eec8f45de5 v2.54 2019-03-25 17:11:29 +02:00
Lauri Ojansivu 0855e3e32f Update translations. 2019-03-25 17:04:29 +02:00
Lauri Ojansivu fab3ce46b8 - Fix typos.
- Fix Outgoing Webhook message about created new swimlane.

Related #1969
2019-03-25 17:02:36 +02:00
Lauri Ojansivu 08c8ebc100 - Fix typos.
- Fix Outgoing Webhook message about created new swimlane.

Related #1969
2019-03-25 16:59:12 +02:00
Lauri Ojansivu 0039fe09be Removed commented out text. 2019-03-24 17:44:03 +02:00
Lauri Ojansivu 97beed6fd1 v2.53 2019-03-23 21:34:43 +02:00
Lauri Ojansivu 994314cfa3 Fix filenames and urls. 2019-03-23 21:30:41 +02:00
Lauri Ojansivu db6dbe34c3 Fix docker-compose.yml 2019-03-23 21:13:03 +02:00
Lauri Ojansivu fa7ef361e2 Update translations. 2019-03-23 13:17:36 +02:00
Lauri Ojansivu 296349a83b v2.52 2019-03-22 13:08:36 +02:00
Lauri Ojansivu 563458e0b5 Update translations. 2019-03-22 12:03:25 +02:00
Lauri Ojansivu 169301fa18 Update translations. 2019-03-22 09:25:18 +02:00
Lauri Ojansivu 0363e6f122 Remove extra title quotes, so that Custom Product Name comes visible.
Thanks to xet7 !
2019-03-22 01:35:53 +02:00
Lauri Ojansivu c259324185 Fix cloning repos. 2019-03-21 23:58:58 +02:00
Lauri Ojansivu 57767d9906 Update translations. 2019-03-21 23:48:36 +02:00
Lauri Ojansivu 1a26f9fb82 Update translations. 2019-03-21 22:35:13 +02:00
Lauri Ojansivu 19ab7db239 Add vanila community link. 2019-03-21 22:34:41 +02:00
Lauri Ojansivu ded430c155 - [Add LDAP config example, remove extra text](https://github.com/wekan/wekan/commit/506acda70b5e78737c52455e5eee9c8758243196).
Thanks to xet7 !
2019-03-21 22:24:35 +02:00
Lauri Ojansivu 506acda70b - Add LDAP config example, remove extra text.
Thanks to xet7 !
2019-03-21 22:22:46 +02:00
Lauri Ojansivu d173844f98 OAUTH2_LOGIN_STYLE popup or redirect, part 2 and 3. 2019-03-21 21:41:18 +02:00
Lauri Ojansivu 7919ae3628 - OAUTH2_LOGIN_STYLE popup or redirect, part 2.
Thanks to xet7 !
2019-03-21 21:37:38 +02:00
Lauri Ojansivu 188d42dcd6 [Add option to redirect OIDC OAuth2 login](https://github.com/wekan/wekan-ldap/commit/82a894ac20ba9e7c6fdf053cff1721cab709bf8a).
Thanks to xet7 !
2019-03-21 20:59:45 +02:00
Lauri Ojansivu 7735394373 - [Fix IFTTT email sending](https://github.com/wekan/wekan/pull/2279).
Thanks to justinr1234.

Related #1972
2019-03-21 20:38:06 +02:00
Lauri Ojansivu 30bf8a1724 Merge pull request #2279 from justinr1234/patch-2
Fix IFTTT email sending
2019-03-21 20:35:38 +02:00
Lauri Ojansivu 0310560938 More whitelabeling. 2019-03-21 20:32:07 +02:00
Lauri Ojansivu 2969161afb - More whitelabeling.
Thanks to xet7 !
2019-03-21 20:27:21 +02:00
Lauri Ojansivu a6213d4a6f Update translations. 2019-03-21 20:21:21 +02:00
justinr1234 12268bd065 Fix IFTTT email sending 2019-03-21 10:22:57 -05:00
Lauri Ojansivu 35a66c3550 Fix typo. 2019-03-21 02:41:21 +02:00
Lauri Ojansivu 402a974a70 v2.51 2019-03-21 01:22:09 +02:00
Lauri Ojansivu 079cd95e0e Merge pull request #2269 from andresmanelli/fix_2268
Fix #2268
2019-03-21 01:13:33 +02:00
Lauri Ojansivu e9f5aaa397 v2.50 2019-03-21 01:11:48 +02:00
Lauri Ojansivu ca0236fdfd [Fix](https://github.com/wekan/wekan/pull/2269) [Unable to change card title in Template](https://github.com/wekan/wekan/issues/2268)
and [Fix Unable to create a new board from a template](https://github.com/wekan/wekan/issues/2267).

Thanks to andresmanelli !

Closes 2268,
closes #2267
2019-03-21 00:56:18 +02:00
Lauri Ojansivu da3edb35cc v2.49 2019-03-21 00:39:35 +02:00
Andrés Manelli ef6054b859 Fix #2268 2019-03-20 23:32:52 +01:00
Lauri Ojansivu 1046976c08 [Fix Cards disappear when rearranged on template board](https://github.com/wekan/wekan/issues/2266).
Thanks to andresmanelli !

Closes #2266
2019-03-21 00:23:35 +02:00
Lauri Ojansivu f8cbbfc2cd Merge pull request #2270 from andresmanelli/fix_2266
Fix #2266
2019-03-21 00:21:19 +02:00
Lauri Ojansivu f083fc0d7b Update changelog. 2019-03-21 00:13:31 +02:00
Lauri Ojansivu 72cb820f1f Merge branch 'andresmanelli-fix_subtasks' into edge 2019-03-21 00:12:06 +02:00
Lauri Ojansivu d5d33247fb Merge branch 'fix_subtasks' of https://github.com/andresmanelli/wekan into andresmanelli-fix_subtasks 2019-03-20 23:50:43 +02:00
Lauri Ojansivu 9f95a10591 Update translations. 2019-03-20 21:45:56 +02:00
Lauri Ojansivu 5ca083105c Update changelog. 2019-03-20 21:36:19 +02:00
Lauri Ojansivu 6bc8d8dd56 git push origin edgeMerge branch 'andresmanelli-edge' into edge 2019-03-20 21:24:45 +02:00
Lauri Ojansivu dce89bcfa8 Merge branch 'edge' of https://github.com/andresmanelli/wekan into andresmanelli-edge 2019-03-20 19:30:44 +02:00
Lauri Ojansivu e5370ce859 Merge branch 'devel' of github.com:wekan/wekan into devel 2019-03-20 19:29:32 +02:00
Lauri Ojansivu 6f35d73fe8 Update changelog. 2019-03-20 19:28:56 +02:00
Lauri Ojansivu af2fb5f399 Merge pull request #2272 from justinr1234/patch-1
Don't swallow email errors
2019-03-20 19:26:00 +02:00
Lauri Ojansivu e976565550 Update changelog. 2019-03-20 19:25:28 +02:00
justinr1234 7a6b4adcc1 Disable eslint for console error 2019-03-18 23:50:15 -05:00
justinr1234 ec30665bc4 Don't swallow email errors
Fixes #2246
2019-03-18 23:06:18 -05:00
Andrés Manelli 9651d62b96 Fix #2266 2019-03-18 22:55:56 +01:00
Andrés Manelli a6e3c8984d Fix dissapearing subtasks 2019-03-17 16:37:06 +01:00
Andrés Manelli 777d9ac353 Lint fix 2019-03-16 23:15:30 +01:00
Andrés Manelli d01fccd949 - Fix card copy & move between boards with customFields
- Fix card copy & move between boards with labels with same name
- Fix activities for labels when copying and moving card
- Fix activities for customFields when copying and moving card
2019-03-16 22:49:45 +01:00
Andrés Manelli 4cd0d1c397 Migrate customFields 2019-03-16 22:49:45 +01:00
Lauri Ojansivu bf3ec060f7 Merge pull request #2263 from inoio/devel
make emails for invitations lowercase, compatible with AccountsTemplates
2019-03-16 16:24:02 +02:00
Ole Langbehn 40a3267615 make emails for invitations all lowercase for compatibility with AccountsTemplates
Email addresses for invitations are stored case sensitive in mongo,
together with the invitation codes. When someone tries to sign up due to
an invitation, in the sign up form, due to AccountsTemplates defaults,
the email address is lowercased on blur of the textbox. When they then
try to sign in, they get an error about the invitation code not existing.
This makes it impossible to successfully invite people using
non-lowercased email addresses.

This patch lowercases the emails on the client side when inviting them.

Other possibilities would be to lowercase them on the server side before
storing them to mongodb, making a case insensitive search on mongodb, or
making the email input field in the sign up form not lowercase the email
string.

This patch was chosen in favor of the other possibilities because of its
simplicity.
2019-03-16 14:32:39 +01:00
Lauri Ojansivu ff19d6744e v2.48 2019-03-15 11:08:07 +02:00
Lauri Ojansivu c26af16688 Update translations. 2019-03-15 11:03:52 +02:00
Lauri Ojansivu 216b3cfe01 Fix LDAP login.
Thanks to xet7 !

Closes wekan/wekan-ldap#43,
closes wekan/wekan-snap#85
2019-03-15 10:59:54 +02:00
Lauri Ojansivu fd70556c82 v2.47 2019-03-14 00:39:24 +02:00
Lauri Ojansivu 0fee20cc12 Update changelog. 2019-03-14 00:27:46 +02:00
Lauri Ojansivu 32f6de1eec Try to fix [LDAP Login: "Login forbidden", ReferenceError: req is not defined](https://github.com/wekan/wekan-ldap/issues/44).
Please test.

Thanks to xet7 !

Closes wekan/wekan-ldap#44
2019-03-14 00:25:40 +02:00
Lauri Ojansivu 8671f08a0e Remove ordering of cards by stars/color/description, so that cards would not reorder all the time.
Thanks to xet7 !

Closes #2241
2019-03-14 00:16:39 +02:00
Lauri Ojansivu 299484f7b2 v2.46 2019-03-13 15:55:52 +02:00
Lauri Ojansivu d16086fcdb Update changelog. 2019-03-13 15:40:20 +02:00
Lauri Ojansivu 1968b7da31 Revert hiding of Subtask boards, because of feedback from Wekan users,
that need Subtask boards to be visible.

Thanks to xet7 !
2019-03-13 15:35:34 +02:00
Lauri Ojansivu 95a40a45e5 Update translations. 2019-03-13 00:30:07 +02:00
Lauri Ojansivu 0ad7f080b7 Merge branch 'devel' of github.com:wekan/wekan into devel 2019-03-12 23:01:31 +02:00
Lauri Ojansivu aca3048036 Update changelog. 2019-03-12 23:01:18 +02:00
Lauri Ojansivu 1158cd42cc Merge pull request #2253 from justinr1234/devel
Fix watchers undefined #2252
2019-03-12 22:57:38 +02:00
Justin Reynolds 0e2b7458d7 Fix watchers undefined #2252 2019-03-12 12:04:59 -05:00
Lauri Ojansivu cf7d740004 v2.45 2019-03-11 23:39:05 +02:00
Lauri Ojansivu dc4c4d9ade Merge pull request #2248 from andresmanelli/circular_migration
Rename migration to re run
2019-03-11 23:32:46 +02:00
Andrés Manelli a347ae3676 Rename migration to re run 2019-03-11 22:30:16 +01:00
Lauri Ojansivu 7da2a8a15e v2.44 2019-03-11 20:23:27 +02:00
Lauri Ojansivu 0002559d6e Update translations. 2019-03-11 20:20:45 +02:00
Lauri Ojansivu afda0ed4da Try to get ordering of All Boards working so that it does
not keep reordering.

Thanks to bentiss, with Apache I-CLA.

Related #2241
2019-03-11 19:56:17 +02:00
Lauri Ojansivu 473f389bbe [Changed brute force protection package from eluck:accounts-lockout to lucasantoniassi:accounts-lockout that is maintained and works.
Added Snap/Docker/Source settings](https://github.com/wekan/wekan/commit/b7c000b78b9af253fb115bbfa5ef0d4c0681abbb).

Thanks to xet7.
2019-03-11 19:53:13 +02:00
Lauri Ojansivu b7c000b78b Changed brute force protection package from eluck:accounts-lockout to
lucasantoniassi:accounts-lockout that is maintained and works.
Added Snap/Docker/Source settings.

Thanks to xet7 !

Closes #1572,
closes #1821
2019-03-11 19:47:23 +02:00
Lauri Ojansivu 4ac8247db0 [Fix imports](https://github.com/wekan/wekan/pull/2245).
Thanks to bentiss with Apache I-CLA.
2019-03-11 19:40:03 +02:00
Lauri Ojansivu 0471d1ac97 Merge branch 'edge' of github.com:wekan/wekan into edge 2019-03-11 19:37:52 +02:00
Lauri Ojansivu c0221dafde Update changelog. 2019-03-11 19:37:40 +02:00
Lauri Ojansivu 8f337f17e4 - Order All Boards by starred, color, board name and board description. Part 2.
Thanks to xet7 !
2019-03-11 19:32:58 +02:00
Lauri Ojansivu de5a63f7b2 Merge pull request #2245 from bentiss/fix-imports
Fix imports
2019-03-11 19:28:03 +02:00
Lauri Ojansivu 52a744b443 Update changelog. 2019-03-11 19:16:53 +02:00
Lauri Ojansivu 4be5fa598e Merge pull request #2244 from bentiss/edge
customFields: fix leftover from lint
2019-03-11 19:04:13 +02:00
Benjamin Tissoires d03a7e7a98 wekan-import: also import each swimlane color 2019-03-11 11:47:01 +01:00
Benjamin Tissoires ebc4d6fdbd wekan-import: also import each card color 2019-03-11 11:42:22 +01:00
Benjamin Tissoires 35ffd02814 Fix import error 500
while running an import from a previously exported board, we encounter
the following error:

Exception while invoking method 'importBoard' Error: Did not check() all arguments during call to 'importBoard'
    at ArgumentChecker.throwUnlessAllArgumentsHaveBeenChecked (packages/check.js:483:13)
    at Object._failIfArgumentsAreNotAllChecked (packages/check.js:131:16)
    at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1765:18)
    at DDP._CurrentMethodInvocation.withValue (packages/ddp-server/livedata_server.js:719:19)
    at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1186:15)
    at DDPServer._CurrentWriteFence.withValue (packages/ddp-server/livedata_server.js:717:46)
    at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1186:15)
    at Promise (packages/ddp-server/livedata_server.js:715:46)
    at new Promise (<anonymous>)
    at Session.method (packages/ddp-server/livedata_server.js:689:23)
    at packages/mdg_meteor-apm-agent.js:2617:38
    at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1186:15)
    at Session.sessionProto.protocol_handlers.method (packages/mdg_meteor-apm-agent.js:2616:44)
    at packages/ddp-server/livedata_server.js:559:43

Commit 4cf9813449 removed the checks as the original board might
not have all the required fields, but we actually still need to run
a general check on all parameters
2019-03-11 11:42:05 +01:00
Benjamin Tissoires 4c72479d12 customFields: fix leftover from lint
Looks like I forgot to use the camelCase notation here, and this leads
to an exception while updating a custom field.
2019-03-11 10:12:19 +01:00
Lauri Ojansivu 907c761f71 Update translations. 2019-03-10 21:35:55 +02:00
Lauri Ojansivu 97206aa8f6 Update changelog. 2019-03-10 21:31:40 +02:00
Andrés Manelli 2ec1664408 Fix removed checklistItem activity => dangling activities created 2019-03-08 21:13:41 +01:00
Andrés Manelli 97822f35fd Avoid set self as parent card, for real 2019-03-08 20:41:32 +01:00
Lauri Ojansivu c5e72d1a2b Merge branch 'edge' of github.com:wekan/wekan into edge 2019-03-08 20:51:57 +02:00
Lauri Ojansivu 117c9e069e Update changelog. 2019-03-08 20:51:43 +02:00
Lauri Ojansivu 951a9f81d6 Merge pull request #2239 from bentiss/customFields-activities
Activities: register customFields changes in the activities
2019-03-08 20:48:49 +02:00
Lauri Ojansivu 6f30c33f11 Add language: Occitan. 2019-03-08 20:47:05 +02:00
Lauri Ojansivu 8050117adf Add language: Occintan.
Thanks to translators !
2019-03-08 20:45:39 +02:00
Lauri Ojansivu 98031aacce v2.43 2019-03-08 19:12:11 +02:00
Lauri Ojansivu 2781ce6fa0 Update translations. 2019-03-08 19:02:31 +02:00
Lauri Ojansivu 08db39d76a Fix lint errors.
Thanks to xet7 !

Related #2019
2019-03-08 19:00:56 +02:00
Lauri Ojansivu da267e1488 [HTTP header automatic login](https://github.com/wekan/wekan/commit/ff825d6123ecfd033ccb08ce97c11cefee676104)
for [3rd party authentication server method](https://github.com/wekan/wekan/issues/2019) like siteminder, and any webserver that
handles authentication and based on it adds HTTP headers to be used for login. Please test.

Thanks to xet7 !

Related #2019
2019-03-08 18:55:36 +02:00
Lauri Ojansivu ff825d6123 [HTTP header automatic login. Not tested yet.](https://github.com/wekan/wekan/issues/2019).
Thanks to xet7 !

Related #2019
2019-03-08 18:40:43 +02:00
Benjamin Tissoires 6d6bb8fc57 Activities: register customFields changed in the activities
This stores the updates to the custom fields in the activities side bar.

Only manual updates to the custom fields are currently registered.
2019-03-08 11:32:59 +01:00
Lauri Ojansivu 7836ab83d0 - Order All Boards by Starred, Color and Title and Description.
Thanks to xet7 !

Closes #1990,
Related #252
2019-03-08 10:44:20 +02:00
Lauri Ojansivu 8568728152 - [Hide Subtask boards from All Boards](https://github.com/wekan/wekan/issues/1990).
- Order All Boards by Starred, Color and Title.

Thanks to xet7 !

Closes #1990,
Related #641
2019-03-08 09:41:36 +02:00
Lauri Ojansivu 8783983945 Update changelog. 2019-03-07 17:20:25 +02:00
Lauri Ojansivu 4055f451fd Reverts the following change of v2.42, because it did not fix anything:
- [Tried to fix snap mongodb-control not starting database](https://github.com/wekan/wekan/commit/2c5628b5fbcc25427021d0b22e74577a71149c21).

Thanks to xet7.
2019-03-07 17:17:21 +02:00
Lauri Ojansivu 31777ce804 Update changelog. 2019-03-07 11:27:06 +02:00
Lauri Ojansivu 97a9e92969 Merge remote-tracking branch 'andresmanelli/edge' into edge 2019-03-07 02:03:34 +02:00
Lauri Ojansivu c5ca414e8f v2.42 2019-03-07 01:52:53 +02:00
Lauri Ojansivu 2c5628b5fb Fix mongodb-control.
Thanks to xet7 and qurqar[m].
2019-03-07 01:48:42 +02:00
Andrés Manelli a338e937e5 Add migration to fix circular references 2019-03-07 00:13:21 +01:00
Lauri Ojansivu 1089572d66 v2.41 2019-03-07 00:04:50 +02:00
Lauri Ojansivu ddb2460187 [Fix: Card was selected as parent card (circular reference) and now board can be not opened anymore](https://github.com/wekan/wekan/issues/2202)
with [Avoid setting same card as parentCard. Avoid listing templates board in copy/move/more menus](https://github.com/wekan/wekan/commit/745f39ed20169f56b99c0339f2043f8c4ed43873).

Thanks to andresmanelli.

Closes #2202
2019-03-06 23:48:36 +02:00
Andrés Manelli 745f39ed20 Avoid setting same card as parentCard.
Avoid listing templates board in copy/move/more menus
2019-03-06 20:57:19 +01:00
Lauri Ojansivu 18cccd514f Fix typos. 2019-03-06 20:56:58 +02:00
Lauri Ojansivu 9c0eba4f00 v2.40 2019-03-06 18:21:26 +02:00
Lauri Ojansivu f19625d835 Fix manifest and icon urls, part 2.
Thanks to xet7 !
2019-03-06 18:18:34 +02:00
Lauri Ojansivu c4754d9f85 v2.39 2019-03-06 17:31:15 +02:00
Lauri Ojansivu acdc5dc1f4 Update translations. 2019-03-06 17:23:33 +02:00
Lauri Ojansivu 4927609af0 Update changelog. 2019-03-06 17:20:47 +02:00
Lauri Ojansivu e845fe3e71 Fix manifest and icon paths.
Thanks to xet7 !

Closes #2168,
closes #1692
2019-03-06 17:15:36 +02:00
Lauri Ojansivu d807efd4f8 Update translations. 2019-03-06 03:14:13 +02:00
Lauri Ojansivu 5f76695298 Update release scripts. 2019-03-06 03:12:27 +02:00
Lauri Ojansivu aadb1f3109 v2.38 2019-03-06 03:07:50 +02:00
Lauri Ojansivu cb986912c4 [Added support for LDAP admin status sync](https://github.com/wekan/wekan-ldap/pull/40).
Examples: LDAP_SYNC_ADMIN_STATUS=true, LDAP_SYNC_ADMIN_GROUP=group1,group2 (https://github.com/wekan/wekan/commit/7e451d9033eb6162cd37de3e5ffabdc22e272948).
Thanks to JulianJacobi and xet7.
2019-03-06 02:55:13 +02:00
Lauri Ojansivu 7e451d9033 [Add support for admin status sync](https://github.com/wekan/wekan-ldap/pull/40).
Examples: LDAP_SYNC_ADMIN_STATUS=true, LDAP_SYNC_ADMIN_GROUP=group1,group2

Thanks to JulianJacobi and xet7 !
2019-03-06 02:47:27 +02:00
Lauri Ojansivu a024b6d692 Update changelog. 2019-03-06 02:00:31 +02:00
Lauri Ojansivu a45ccf1db7 [Remove phantomjs binary from Docker/Snap/Stackerfile to reduce size](https://github.com/wekan/wekan/issues/2229).
Thanks to soohwa !

Closes #2229
2019-03-06 01:56:32 +02:00
Lauri Ojansivu 30bf430a91 - [Use ubuntu:cosmic base in Dockerfile](https://github.com/wekan/wekan/commit/df00776e6ca47080435eca9a31a16fd24c0770ed). Thanks to xet7. 2019-03-06 01:44:47 +02:00
Lauri Ojansivu df00776e6c Use ubuntu:cosmic base in Dockerfile.
Thanks to xet7 !
2019-03-06 01:42:30 +02:00
Lauri Ojansivu 1dc0d0c12e Update changelog. 2019-03-06 01:34:58 +02:00
Lauri Ojansivu 002fd411ea [Fix: LDAP Authentication with Recursive Group Filtering Does Not Work on Snap](https://github.com/wekan/wekan/issues/2228).
Thanks to apages2 !

Closes #2228,
closes wekan/wekan-ldap#23
2019-03-06 01:27:40 +02:00
Lauri Ojansivu 6311cf0c5a Update translations. 2019-03-06 01:23:40 +02:00
Lauri Ojansivu d71543beb6 - [Fix card deletion from archive](https://github.com/wekan/wekan/commit/77754cf32f28498e550a46325d90eb41f08f8552).
- [Fix card move with wrong swimlaneId](https://github.com/wekan/wekan/commit/1bef3a3f8ff4eac43bf97cc8b86d85e618b0e2ef).
  NOTE: This does not yet fix card move with Custom Field, it will be fixed later.

Thanks to andresmanelli !

Closes wekan/wekan-snap#83,
closes #2224,
closes #2230,
related #2233
2019-03-06 01:05:15 +02:00
Lauri Ojansivu 5a9837f676 Merge remote-tracking branch 'andresmanelli/edge' into edge 2019-03-06 00:58:49 +02:00
Andrés Manelli 77754cf32f Fix card deletion from archive 2019-03-05 22:48:29 +01:00
Lauri Ojansivu 43a74fb99b Merge remote-tracking branch 'andresmanelli/edge' into edge 2019-03-05 23:38:47 +02:00
Andrés Manelli 1bef3a3f8f Fix card move with wrong swimlaneId 2019-03-05 22:35:45 +01:00
Lauri Ojansivu b6b6be34f6 Update translations. 2019-03-04 21:29:04 +02:00
Lauri Ojansivu f1cde3e873 - [Added a Helm Chart to the project](https://github.com/wekan/wekan/pull/2227).
Thanks to TechnoTaff !
2019-03-04 21:27:35 +02:00
Lauri Ojansivu dcd6ae2e01 Merge pull request #2227 from TechnoTaff/devel
Added a Helm Chart to the project
2019-03-04 21:21:51 +02:00
Stephen Randall 8984172ff6 Readme updates 2019-03-04 16:44:12 +00:00
Stephen Randall 87a5e7f030 Merge branch 'devel' of https://github.com/TechnoTaff/wekan into devel 2019-03-04 16:29:29 +00:00
Stephen Randall 115d07da5a Added some notes 2019-03-04 16:28:44 +00:00
Steve Randall e67ed023cd Create .gitkeep 2019-03-04 16:26:34 +00:00
Steve Randall 1f1d753791 Delete requirements.lock 2019-03-04 16:13:34 +00:00
Steve Randall 34fcce60af Delete mongodb-replicaset-3.6.4.tgz 2019-03-04 16:13:11 +00:00
Stephen Randall e7a90d9a7c Added helm chart v1 2019-03-04 15:55:20 +00:00
Lauri Ojansivu 9d6d5e1a14 v2.37 2019-03-04 12:08:55 +02:00
Lauri Ojansivu 763cf81c97 [Fix Adding Labels to cards is not possible anymore](https://github.com/wekan/wekan/issues/2223).
Thanks to xet7 !

Closes #2223
2019-03-04 12:04:12 +02:00
Lauri Ojansivu 0b64a46bdc Update translations. 2019-03-04 08:55:42 +02:00
Lauri Ojansivu d417bf058d v2.36 2019-03-03 22:39:09 +02:00
Lauri Ojansivu 46088bfbb5 Update translations. 2019-03-03 22:33:17 +02:00
Lauri Ojansivu a6ea622f78 Update changelog. 2019-03-03 22:32:00 +02:00
Lauri Ojansivu 847ed8570b [Combine hamburger menus at right](https://github.com/wekan/wekan/issues/2219).
Thanks to xet7 !

Related #2219
2019-03-03 22:27:05 +02:00
Lauri Ojansivu 3a9ab817a9 Update translations. 2019-03-03 20:43:12 +02:00
Lauri Ojansivu 2a5c2ed192 [Forked salleman-oidc](https://github.com/wekan/wekan/commit/8867bec8e65f1ef6be0c731918e8eefcacb7acb0)
to https://github.com/wekan/meteor-accounts-oidc where salleman also has write access,
xet7 can make changes directly and GitHub issues are enabled.

Thanks to xet7 !
2019-03-03 20:40:37 +02:00
Lauri Ojansivu 8867bec8e6 Forked salleman-oidc to https://github.com/wekan/meteor-accounts-oidc
where salleman also has write access, xet7 can make changes directly
and GitHub issues are enabled.

Thanks to xet7 !
2019-03-03 20:36:44 +02:00
Lauri Ojansivu 262da85399 Update translations. 2019-03-03 18:10:52 +02:00
Lauri Ojansivu 51a70f2164 Fix translation. 2019-03-03 18:07:14 +02:00
Lauri Ojansivu 0854a658d8 Fix typos in translation. 2019-03-03 17:55:34 +02:00
Lauri Ojansivu d99056ced5 Fix translation. 2019-03-03 17:41:11 +02:00
Lauri Ojansivu 4a5473b4e7 Update translation. 2019-03-03 17:38:23 +02:00
Lauri Ojansivu d3f368efd7 Fix typos in translation. 2019-03-03 17:30:57 +02:00
Lauri Ojansivu ca052566de Fix translation. 2019-03-03 17:19:01 +02:00
Lauri Ojansivu c101e262d6 Fix translation. 2019-03-03 16:52:55 +02:00
Lauri Ojansivu 1f942301ad Fix translation. 2019-03-03 16:45:33 +02:00
Lauri Ojansivu b6db1e12b7 - [Add more Webhook translations](https://github.com/wekan/wekan/issues/1969).
In progress.

Thanks to xet7 !
2019-03-03 16:40:35 +02:00
Lauri Ojansivu 3bfc6ea8d7 [Add more Webhook translations](https://github.com/wekan/wekan/issues/1969).
In progress.

Thanks to xet7 !

Related #1969
2019-03-03 16:33:43 +02:00
Lauri Ojansivu ec30dd4788 Update changelog. 2019-03-03 10:45:50 +02:00
Lauri Ojansivu 990ebbdbcb Update translations. 2019-03-03 10:36:58 +02:00
Lauri Ojansivu 99a856be97 Change board menu:
- Board menu (hamburger icon) to Board Settings (Cog icon)
- Sidebar arrows icons to hamburger icon

Thanks to xet7 !

Related #2219
2019-03-03 10:31:30 +02:00
Lauri Ojansivu 260d0641df Rename Board Menu to Board Settings.
Thanks to xet7 !
2019-03-03 10:26:18 +02:00
Lauri Ojansivu 16963859e1 Update translations. 2019-03-02 17:32:06 +02:00
Lauri Ojansivu 010a201d0c Update readme. 2019-03-02 17:27:34 +02:00
Lauri Ojansivu 95014e6348 Update readme. 2019-03-02 17:26:00 +02:00
Lauri Ojansivu 724912ec48 Update readme. 2019-03-02 17:24:26 +02:00
Lauri Ojansivu 46d8a11c51 Remove outdated team page. 2019-03-02 17:15:18 +02:00
Lauri Ojansivu 065cd05c96 Update readme. 2019-03-02 17:13:50 +02:00
Lauri Ojansivu a4564bed3a v2.35 2019-03-01 15:42:23 +02:00
Lauri Ojansivu 4ef3e587cb [Add Filter fix back](https://github.com/wekan/wekan/issues/2213),
because there was no bug in filter fix.
2019-03-01 14:48:25 +02:00
Lauri Ojansivu d6259836e0 - [Add Filter fix back](https://github.com/wekan/wekan/issues/2213),
because there was no bug in filter fix.

Thanks to xet7 !

Closes #2213,
related #2209
2019-03-01 14:41:09 +02:00
Lauri Ojansivu ef246cfef3 v2.34 2019-03-01 07:10:50 +02:00
Lauri Ojansivu 90dd0ddb94 Revert [Filter fix](https://github.com/wekan/wekan/issues/2213) because of
[mongodb data tampered](https://github.com/wekan/wekan-snap/issues/83).

Thanks to xet7 !
2019-03-01 07:05:49 +02:00
Lauri Ojansivu bd2c54398b v2.33 2019-02-28 23:31:39 +02:00
Lauri Ojansivu e65776f9f0 [Upgrade Node.js to v8.15.1](https://github.com/wekan/wekan/commit/5cafdd9878ab4b6123024ec33279ccdae75f554f).
Thanks to Node.js developers and xet7 !
2019-02-28 23:29:13 +02:00
Lauri Ojansivu 5cafdd9878 Upgrade node to v8.15.1
Thanks to xet7 !
2019-02-28 23:25:03 +02:00
Lauri Ojansivu 49882a05d1 v2.32 2019-02-28 23:01:56 +02:00
Lauri Ojansivu 8e36a2bc83 [Fix filtering in swimlane view](https://github.com/wekan/wekan/commit/49229e1723de14cdc66dc6480624bba426d35e36)
that was [broken since v2.29](https://github.com/wekan/wekan/issues/2213).

Thanks to andresmanelli !

Closes #2213,
Related #2209
2019-02-28 22:57:40 +02:00
Lauri Ojansivu 24e47195e5 - [Fix](https://github.com/wekan/wekan/commit/49229e1723de14cdc66dc6480624bba426d35e36)
[Filtering in swimlane view is broken since v2.29](https://github.com/wekan/wekan/issues/2213).

Thanks to andresmanelli !

Related #2209
2019-02-28 22:45:37 +02:00
Lauri Ojansivu 4b37958140 Merge branch 'devel' into edge 2019-02-28 22:39:02 +02:00
Lauri Ojansivu 3edff32bde [Performance improvements](https://github.com/wekan/wekan/pull/2214), thanks to justinr1234:
- New indexes for queries that were missing an index;
- Bulk querying documents to reduce the number of mongo queries when loading a board;
- Ensure oplog is being used to query the database by providing a `sort` key when `limit` is used querying the `boards` collection.
2019-02-28 22:37:28 +02:00
Lauri Ojansivu 78c5e0f7ef Merge branch 'justinr1234-wekan-perf-improvements' into devel 2019-02-28 22:32:33 +02:00
Andrés Manelli 49229e1723 Fix filter in swimlanes view 2019-02-28 20:46:50 +01:00
Lauri Ojansivu 14e2bfd1bf Merge branch 'wekan-perf-improvements' of https://github.com/justinr1234/wekan into justinr1234-wekan-perf-improvements 2019-02-28 21:19:50 +02:00
Justin Reynolds 3c49e2d0ed Performance Enhancements 2019-02-28 11:44:29 -06:00
Lauri Ojansivu d5bc66c9a4 v2.31 2019-02-28 12:41:07 +02:00
Lauri Ojansivu 4f6977668b Update translations. 2019-02-28 12:37:36 +02:00
Lauri Ojansivu 17826c28e5 - [Fix copy card](https://github.com/wekan/wekan/issues/2210).
Thanks to andresmanelli !

Closes #2210,
Related #2209
2019-02-28 12:34:48 +02:00
Lauri Ojansivu a3d71dd694 Merge remote-tracking branch 'andresmanelli/edge' into edge 2019-02-28 12:29:14 +02:00
Andrés Manelli a5c39342ba Fix card copy 2019-02-28 08:10:33 +01:00
Lauri Ojansivu ad75c541cf v2.30 2019-02-28 00:52:36 +02:00
Lauri Ojansivu cd46cbeb8f Add new [Template features](https://github.com/wekan/wekan/issues/2209):
- [Fix popup title. Add element title modification](https://github.com/wekan/wekan/commit/888e1ad5d3e32be53283aa32198057f669f3d706);
- [Copy template attachments](https://github.com/wekan/wekan/commit/abb71083215462d91b084c4de13af0b130638e4d);
- [Standarize copy functions. Match labels by name](https://github.com/wekan/wekan/commit/da21a2a410c9b905de89d66236748e0c8f5357ea).

Thanks to andresmanelli !

Related #2209
2019-02-28 00:44:13 +02:00
Andrés Manelli 888e1ad5d3 Fix popup title
Add element title modification
2019-02-27 21:50:08 +01:00
Andrés Manelli abb7108321 Copy template attachments 2019-02-27 21:50:08 +01:00
Andrés Manelli da21a2a410 Standarize copy functions. Match labels by name 2019-02-27 21:50:08 +01:00
Lauri Ojansivu 904b5bf0f5 v2.29 2019-02-27 21:01:32 +02:00
Lauri Ojansivu d21aa97219 Update translations. 2019-02-27 20:39:56 +02:00
Andrés Manelli 6ee75fbdba Fix templates board not found 2019-02-27 19:34:53 +01:00
Lauri Ojansivu c3b2a0c955 Merge branch 'devel' into edge 2019-02-27 17:29:21 +02:00
Lauri Ojansivu 0ac42c145e Fix typo. 2019-02-27 17:28:44 +02:00
Lauri Ojansivu 4a77bc930f Merge branch 'devel' into edge 2019-02-27 16:26:48 +02:00
Lauri Ojansivu 29c3080eb6 v2.28 2019-02-27 16:21:31 +02:00
Lauri Ojansivu 57516177a0 Update ChangeLog. 2019-02-27 16:17:21 +02:00
Lauri Ojansivu 34d8235551 Add the following new Sandstorm features and fixes:
- All Boards page [so it's possible to go back from subtask board](https://github.com/wekan/wekan/issues/2082)
- Board favorites
- New Sandstorm board first user is Admin and [has IFTTT Rules](https://github.com/wekan/wekan/issues/2125)
  and Standalone Wekan Admin Panel. Probably some Admin Panel features do not work yet. Please keep backup of your grains before testig Admin Panel.
- Linked Cards and Linked Boards.
- Some not needed options like Logout etc have been hidden from top bar right menu.
- [Import board now works. "Board not found" is not problem anymore](https://github.com/wekan/wekan/issues/1430), because you can go to All Boards page to change to imported board.

and removes the following features:

- Remove Welcome Board from Standalone Wekan, [to fix Welcome board not translated](https://github.com/wekan/wekan/issues/1601).
  Sandstorm Wekan does not have Welcome Board.

Thanks to xet7 !

Closes #2125,
closes #2082,
closes #1430,
closes #1601,
related #2205,
related #2070,
related #1695,
related #1192.
2019-02-27 16:14:14 +02:00
Lauri Ojansivu 8d51245161 Merge branch 'devel' into edge 2019-02-27 06:20:30 +02:00
Lauri Ojansivu 55ad98ecc4 v2.27 2019-02-27 06:18:51 +02:00
Lauri Ojansivu ed04181bb9 Update translations. 2019-02-27 06:16:37 +02:00
Lauri Ojansivu 868fba55cd Update changelog. 2019-02-27 06:14:15 +02:00
Lauri Ojansivu 05351c0ac1 - Fix OIDC error "a.join is not a function" b reverting
configurable OAUTH2_ID_TOKEN_WHITELIST_FIELDS and
  OAUTH2_REQUEST_PERMISSIONS from Wekan v2.22-2.26.

Thanks to xet7 !

Closes #2206,
Related #1874,
Related #1722
2019-02-27 06:02:00 +02:00
Lauri Ojansivu a707129146 Removed console.log. 2019-02-26 16:51:24 +02:00
Lauri Ojansivu 2f3138207c Update translations. 2019-02-26 00:28:01 +02:00
Andrés Manelli dc7286a0ef Fix list view issues. Allow creation of boards from templates 2019-02-25 22:48:32 +01:00
Lauri Ojansivu 5e66119bf0 v2.26 2019-02-25 20:03:36 +02:00
Lauri Ojansivu b751fd11e4 - [Fix OAuth2 requestPermissions](https://github.com/wekan/wekan/commit/5e238bfbfea16940ae29647ae347bbdc0d78efb0).
This maybe makes [Auth0 login possible](https://github.com/wekan/wekan/issues/1722) with OIDC.
  Thanks to GitHub user xet7.
2019-02-25 19:51:17 +02:00
Lauri Ojansivu 5e238bfbfe - Fix OAuth2 requestPermissions.
Thanks to xet7 !

Closes #1722
2019-02-25 19:45:41 +02:00
Lauri Ojansivu 7e20a3cac6 - Add setting [EMAIL_NOTIFICATION_TIMEOUT](https://github.com/wekan/wekan/issues/2203).
Defaut 30000 ms (30s). Thanks to GitHub users ngru and xet7.
2019-02-25 18:13:43 +02:00
Lauri Ojansivu 7c1d6e4d2e - Add setting EMAIL_NOTIFICATION_TIMEOUT. Defaut 30000 ms (30s).
Thanks to xet7 !

Closes #2203
2019-02-25 18:10:36 +02:00
Lauri Ojansivu 13c2157e36 Update translations. 2019-02-25 06:14:43 +02:00
Andrés Manelli 7033315cd3 Add migrations 2019-02-24 12:55:34 +01:00
Andrés Manelli 775476f97c Fix miniscreen render 2019-02-24 11:54:52 +01:00
Andrés Manelli eb62c9ce6a Fix lint errors 2019-02-24 00:13:35 +01:00
Andrés Manelli 60be4df76e Allow swimlane creation from template
Mix lists with same name to avoid duplicates
2019-02-24 00:05:00 +01:00
Andrés Manelli f888cfd565 Allow list creation from template 2019-02-24 00:05:00 +01:00
Andrés Manelli 044126188d Allow card creation from template 2019-02-24 00:05:00 +01:00
Andrés Manelli 0fec711545 Prepare to create card from template 2019-02-24 00:05:00 +01:00
Andrés Manelli 7a6afb8aea Add template search in Add Card menu
Archive all cards in list when list is archived
Remove default board in link popup
Only list non-template boards in card link and search
2019-02-24 00:05:00 +01:00
Andrés Manelli 1e72177991 Avoid links on a template-board
Allow creation of template boards with a linked card
Avoid changing the name of the template-container swimlanes
2019-02-24 00:05:00 +01:00
Andrés Manelli cdf070189e Remove links from templates board for the moment
Insert the correct template type in templates board
Allow independant lists in templates board
Add some helpers
2019-02-24 00:05:00 +01:00
Andrés Manelli 64bf455b29 Save template swimlanes in profile. Fix swimlane view for templates board. Avoid deleting template containers 2019-02-24 00:05:00 +01:00
Andrés Manelli 0a53ee87b9 Add first draft of data model and user interface. No actions. 2019-02-24 00:05:00 +01:00
Lauri Ojansivu ef85b71ee4 v2.25 2019-02-23 19:54:37 +02:00
Lauri Ojansivu ac0133e8fa - Revert file permission changes from v2.24 LDAP changes that
caused snap version to not build.

Thanks to xet7 !
2019-02-23 19:51:33 +02:00
Lauri Ojansivu 25ba6df007 v2.24 2019-02-23 19:23:36 +02:00
Lauri Ojansivu 6d750897a8 - [Add LDAP email] matching support](https://github.com/wekan/wekan-ldap/pull/39) and
[related env variables](https://github.com/wekan/wekan/pull/2198).
  Thanks to GitHub user stevenpwaters.
2019-02-23 19:18:43 +02:00
Lauri Ojansivu a7747c537b Merge pull request #2198 from stevenpwaters/devel
Add LDAP email environment variables
2019-02-23 19:07:16 +02:00
Lauri Ojansivu 65b6a21938 - Add missing text .env to wekan/server/authentication.js.
Thanks to Vanila Chat user .gitignore.
2019-02-23 19:04:02 +02:00
Lauri Ojansivu 4e6e78ccd2 - Add missing text .env
Thanks to Vanila Chat user .gitignore !
2019-02-23 19:00:29 +02:00
Lauri Ojansivu fd5d6546b2 Update translations. 2019-02-23 18:52:44 +02:00
Steven Waters 402d484182 Added LDAP email environment variables
Support for LDAP matching existing accounts with e-mail address.
2019-02-21 09:02:47 +00:00
Lauri Ojansivu 4bf0914f1e v2.23 2019-02-17 18:13:54 +02:00
Lauri Ojansivu 96519296e1 Update translations (sv). 2019-02-15 18:47:21 +02:00
Lauri Ojansivu 03d06685b0 - [Fix authentication dropdown](https://github.com/wekan/wekan/pull/2191).
Thanks to Akuket.
2019-02-15 18:45:41 +02:00
Lauri Ojansivu 7d57c56b17 Merge pull request #2191 from Akuket/feature-improve-authentication
Fix authentication dropdown
2019-02-15 18:41:38 +02:00
guillaume 4ce766853c Fix authentication dropdown 2019-02-15 17:06:05 +01:00
Lauri Ojansivu dc7bbd848c v2.22 2019-02-13 03:14:18 +02:00
Lauri Ojansivu 81744e6523 - Add [configurable](https://github.com/wekan/wekan/issues/1874#issuecomment-462759627)
settings [OAUTH2_ID_TOKEN_WHITELIST_FIELDS and
  OAUTH2_REQUEST_PERMISSIONS](https://github.com/wekan/wekan/commit/b66f471e530d41a3f12e4bfc29548313e9a73c35).
  Thanks to xet7.
2019-02-13 03:07:31 +02:00
Lauri Ojansivu b66f471e53 - Add configurable settings OAUTH2_ID_TOKEN_WHITELIST_FIELDS
and OAUTH2_REQUEST_PERMISSIONS.

Thanks to xet7.

Related #1874
2019-02-13 03:01:10 +02:00
Lauri Ojansivu 202b8a92af - Add Kadira integration. Thanks to GavinLilly.
Closes #2152
2019-02-13 02:24:21 +02:00
Lauri Ojansivu 1e98f6b781 Merge branch 'edge' into devel 2019-02-13 02:15:19 +02:00
Lauri Ojansivu f53e8fbd21 Merge pull request #2187 from GavinLilly/kadira-integration
Kadira integration
2019-02-13 02:13:46 +02:00
Gavin Lilly 8e95871534 Adding wekan-ldap back in to build in the Dockerfile 2019-02-13 00:01:47 +00:00
Gavin Lilly 595a2d2baa Cleaning up docker-compose for merge 2019-02-13 00:00:34 +00:00
Gavin Lilly 227772bc33 Added back wekan-ldap after it's fixed in a separate change 2019-02-12 23:56:40 +00:00
Lauri Ojansivu 2ca98e477d - Fix2: Remove overlap of side bar button with card/list menu button on mobile browser
Thanks to xet7 !

Closes #2183
2019-02-13 01:04:30 +02:00
Angelo Gallarello 477d71e0b9 Fixes 2019-02-12 23:40:12 +01:00
Lauri Ojansivu 677bfc3f6b - Fix: Remove overlap of side bar button with card/list menu button on mobile browser
Thanks to xet7 !

Closes #2183
2019-02-13 00:01:38 +02:00
Lauri Ojansivu c7721b048d - Fix indenting textline. 2019-02-12 23:46:25 +02:00
Lauri Ojansivu 1417f091fe Update translations. 2019-02-12 23:38:24 +02:00
Lauri Ojansivu d22964bcfd v2.21 2019-02-12 03:24:32 +02:00
Lauri Ojansivu 59314ab17d - Add OIDC claim mapping parameters to docker-compose.yml/Snap/Source.
Thanks to xet7 !
2019-02-12 03:09:30 +02:00
Gavin Lilly 5c083d99e2 Moved to meteor-apm-agent and removed Wekan LDAP to test if working 2019-02-11 23:16:37 +00:00
Gavin Lilly d3abb0756e Pulled Wekan-LDAP locally for debug 2019-02-11 20:12:53 +00:00
Lauri Ojansivu 4de9848e34 Merge pull request #2182 from danpatdav/oidc
Add parameters for OIDC claim mapping
2019-02-11 20:30:01 +02:00
Daniel Davis bdbbb12f96 Added parameters for OIDC claim mapping
These mapping parameters take advantage of new code in salleman-oidc 1.0.12 to override the default claim names provided by the userinfo endpoint.
2019-02-11 10:48:20 -06:00
Gavin Lilly c1ea3f49ca Merge branch 'devel' of github.com:wekan/wekan into devel 2019-02-11 16:43:57 +00:00
Gavin Lilly 905c45f225 Replaced Kadira by meteor-apm-agent 2019-02-11 16:43:52 +00:00
Daniel Davis 352e5c6cb0 Bump salleman-oidc to 1.0.12 2019-02-11 10:41:24 -06:00
Lauri Ojansivu 2d291c8f5e v2.20 2019-02-11 16:45:11 +02:00
Lauri Ojansivu 86630fa1e0 Update changelog. 2019-02-11 16:38:23 +02:00
Lauri Ojansivu 8e02170dd1 - Add option DEBUG=true for docker-compose.yml/Snap/Source.
Thanks to xet7 !
2019-02-11 16:32:24 +02:00
Lauri Ojansivu 9edf95ec93 Merge pull request #2181 from danpatdav/debug-oidc
Added debug flag and bumped salleman package version
2019-02-11 16:11:15 +02:00
Lauri Ojansivu 2add875a38 Update translations. 2019-02-11 16:09:39 +02:00
Daniel Davis b20309f7aa Syntax 2019-02-11 07:46:24 -06:00
Gavin Lilly 8996df5c09 Added Kadira using meteor add method 2019-02-09 23:37:01 +00:00
Gavin Lilly 7b5f02b4c8 Added Kadira packages and env settings in Docker Compose 2019-02-09 23:22:22 +00:00
Lauri Ojansivu fc0287a829 Update translations. 2019-02-09 21:22:36 +02:00
Lauri Ojansivu ed8bca5394 Update translations (es). 2019-02-09 00:04:51 +02:00
Lauri Ojansivu 9458f4011d v2.19 2019-02-09 00:02:49 +02:00
Lauri Ojansivu f1bd36a3b8 - Remove oplog. Need to think how to do it properly.
Thanks to xet7 !
2019-02-08 23:58:13 +02:00
Lauri Ojansivu f060e02fc0 v2.18 2019-02-08 20:56:45 +02:00
Lauri Ojansivu 0fa2e5d3a0 Add commit link to changelog. 2019-02-08 20:52:28 +02:00
Lauri Ojansivu 6d0055ecb5 Add issue link to changelog. 2019-02-08 20:49:39 +02:00
Lauri Ojansivu 2d3ce9c290 Add commit link to changelog. 2019-02-08 20:48:05 +02:00
Lauri Ojansivu 796b276d02 Update changelog. 2019-02-08 20:37:30 +02:00
Lauri Ojansivu ed98b5c807 Update changelog. 2019-02-08 20:09:42 +02:00
Lauri Ojansivu f1da7dcb0c Merge pull request #2174 from bentiss/fix-sw-reordering
Fix swimlanes sorting
2019-02-08 19:49:50 +02:00
Lauri Ojansivu 35a539eee2 Update translations. 2019-02-08 19:48:12 +02:00
Lauri Ojansivu 79ffb7d502 - Add oplog to snap mongodb.
Thanks to xet7 !
2019-02-08 19:43:21 +02:00
Benjamin Tissoires a2e6f621a2 Fix swimlanes sorting
Since 7cc185ac "Properly fix horizontal rendering on Chrome and Firefox"

The rendering of the new design of the swimlanes was correct, but this
commit broke the reordering capability. Having the swimlane header at
the same level than the lists of cards makes the whole sortable
pattern fail.

2 solutions:
- revert to only have 1 div per swimlane. But this introduces the firefox
  bug mentioned in 7cc185ac, so not ideal
- force the sortable pattern to do what we want.

To force the sortable pattern, we need:
- add in the helper a clone of the list of cards (to not just move the
  header)
- make sure the placeholder never get placed between the header and the
  list of cards in a swimlane
- fix the finding of the next and previous list of cards.

For all of this to be successful, we need to resize the swimlanes to a
known value. This can lead to some visual jumps with scrolling when you
drag or drop the swimlanea. I tried to remedy that by computing the new
scroll value. Still not ideal however, as there are still some jumps when
dropping.

Fixes #2159
2019-02-08 17:37:20 +01:00
Lauri Ojansivu 96e97143f2 Update translations. 2019-02-08 13:06:35 +02:00
Lauri Ojansivu 4126a1a808 Translate also Admin Panel/Layout/Display Authentication Method and Default Authentication Method. Thanks to Akuket and xet7 ! 2019-02-08 12:46:07 +02:00
Lauri Ojansivu 3ce902123f Lint also async. Thanks to Akuket ! 2019-02-08 12:44:48 +02:00
Lauri Ojansivu 7125357a44 Merge remote-tracking branch 'upstream/feature-improve-authentication' into feature-improve-authentication 2019-02-08 12:33:39 +02:00
guillaume ec453b89b8 Fix lints 2019-02-07 11:38:04 +01:00
Daniel Davis 303404acc6 Bumped salleman packages to 1.0.11
1.0.11 includes new debugging code
2019-02-06 10:18:05 -06:00
Daniel Davis f11d42e72d Add a debug argument
Implementing this for OIDC debugging, but I think it will be broadly useful for runtime debugging.
2019-02-06 10:12:32 -06:00
Lauri Ojansivu 329c8d64a8 v2.17 2019-02-04 21:47:50 +02:00
Lauri Ojansivu 698ce8f0e6 Update translations (sv). 2019-02-04 21:07:36 +02:00
Lauri Ojansivu b06e11ba09 Merge pull request #2164 from gil0109/edge
Fix trailing spaces for OIDC fix
2019-02-04 20:23:41 +02:00
Karim Gillani d689a7408b Fix trailing spaces 2019-02-04 09:36:21 -08:00
Lauri Ojansivu c899218fb9 Merge pull request #2162 from gil0109/edge
OIDC BoardView Fix
2019-02-04 19:30:24 +02:00
Karim Gillani c42f2a05d2 OIDC BoardView Fix 2019-02-04 08:24:10 -08:00
Lauri Ojansivu 70ed552e1a Update translations. 2019-02-03 15:45:00 +02:00
Lauri Ojansivu 9a07649b8a v2.16 2019-02-03 05:18:50 +02:00
Lauri Ojansivu 9a6ac544dd - Fix Sandstorm open card on public board, part 2.
Thanks to ChronikEwok !
2019-02-03 05:12:50 +02:00
Lauri Ojansivu 06a1e26655 Add missing text. 2019-02-03 03:06:54 +02:00
Lauri Ojansivu 626e7c2c61 v2.15 2019-02-03 02:31:51 +02:00
Lauri Ojansivu a7aeb491ba Update changelog. 2019-02-03 02:25:14 +02:00
Lauri Ojansivu 7ba8f72d7b - [Fix: Not displaying card content of public board: Snap, Docker and Sandstorm Shared Wekan Board
Link](https://github.com/wekan/wekan/issues/1623) with
  [code from ChronikEwok](https://github.com/ChronikEwok/wekan/commit/cad9b20451bb6149bfb527a99b5001873b06c3de).

Thanks to ChronikEwok !

Closes #1623
2019-02-03 02:18:35 +02:00
Lauri Ojansivu d0f74d7a99 Add missing text. 2019-02-02 21:55:50 +02:00
Lauri Ojansivu 7f33fa5368 v2.14 2019-02-02 21:00:16 +02:00
Lauri Ojansivu 0ab97266f6 - [Fix Sandstorm export board from web](https://github.com/wekan/wekan/issues/2157).
- [Fix Error when logging in to Wekan REST API when using Sandstorm Wekan](https://github.com/wekan/wekan/issues/1279).
  Sandstorm API works this way: Make API key, and from that key copy API URL and API KEY to below. It saves Wekan board to file.
  `curl http://Bearer:APIKEY@api-12345.local.sandstorm.io:6080/api/boards/sandstorm/export?authToken=#APIKEY > wekanboard.json`
  If later API key does not work, you need to remove it and make a new one.

Thanks to xet7 !
2019-02-02 20:57:47 +02:00
Lauri Ojansivu 32f896f19d - [Fix Sandstorm export board from web](https://github.com/wekan/wekan/issues/2157).
- [Fix Error when logging in to Wekan REST API when using Sandstorm Wekan](https://github.com/wekan/wekan/issues/1279).
  Sandstorm API works this way: Make API key, and from that key copy API URL and API KEY to below. It saves Wekan board to file.
  `curl http://Bearer:APIKEY@api-12345.local.sandstorm.io:6080/api/boards/sandstorm/export?authToken=#APIKEY > wekanboard.json`
  If later API key does not work, you need to remove it and make a new one.

Closes #2157,
closes #1279
2019-02-02 20:52:09 +02:00
Lauri Ojansivu de9965213a - Fix lint errors.
Thanks to xet7 !
2019-02-01 21:26:04 +02:00
guillaume c2118f4830 Improve authentication 2019-02-01 19:00:44 +01:00
Lauri Ojansivu 6f0e0748e1 v2.13 2019-02-01 17:15:15 +02:00
Lauri Ojansivu 8e5fc13ba4 Update changelog with latest changes from bentiss. 2019-02-01 17:09:05 +02:00
Lauri Ojansivu 7a35099fb9 - When writing to minicard, press Shift-Enter on minicard to go to next line below,
to continue writing on same minicard 2nd line.

Thanks to bentiss!
2019-02-01 17:03:59 +02:00
Lauri Ojansivu d08bee6817 Merge branch 'bentiss-infinite-scrolling' into edge 2019-02-01 16:54:41 +02:00
Lauri Ojansivu 4fc96904d6 Merge branch 'infinite-scrolling' of https://github.com/bentiss/wekan into bentiss-infinite-scrolling 2019-02-01 16:05:46 +02:00
Benjamin Tissoires 66bc1f28dd Use infinite-scrolling on lists
This allows to reduce the loading time of a big board.

Note that there is an infinite scroll implementation in the mixins,
but this doesn't fit well as the cards in the list can have arbitrary
height.

The idea to rely on the visibility of a spinner is based on
http://www.meteorpedia.com/read/Infinite_Scrolling
2019-02-01 14:58:02 +01:00
Benjamin Tissoires 30d082e709 Use infinite-scrolling on lists
This allows to reduce the loading time of a big board.

Note that there is an infinite scroll implementation in the mixins,
but this doesn't fit well as the cards in the list can have arbitrary
height.

The idea to rely on the visibility of a spinner is based on
http://www.meteorpedia.com/read/Infinite_Scrolling
2019-02-01 13:53:45 +01:00
Lauri Ojansivu 1b11123797 v2.12 2019-01-31 19:32:27 +02:00
Lauri Ojansivu 654c2add0d - [Bumped the salleman oidc packages versions to include an upstream bug fix](https://github.com/wekan/wekan/commit/361faa6646556de68ad78dc90d9eb9f78956ce0f).
Thanks to danpatdav !
2019-01-31 19:19:47 +02:00
Lauri Ojansivu 6d179d6d3d Merge pull request #2149 from danpatdav/salleman-1.0.10
Bumped the salleman oidc packages versions to include an upstream bug…
2019-01-31 19:10:03 +02:00
Daniel Davis 361faa6646 Bumped the salleman oidc packages versions to include an upstream bug fix 2019-01-31 11:45:55 -05:00
Lauri Ojansivu 7fc22ba0b7 v2.11 2019-01-31 14:27:36 +02:00
Lauri Ojansivu 9c82e6ab68 Update translations. 2019-01-31 14:23:57 +02:00
Lauri Ojansivu 78c18d4ffe Update changelog. 2019-01-31 14:23:23 +02:00
Lauri Ojansivu 978dafc62b - Fix: Bug: Not logged in public board page has calendar.
Thanks to xet7 !

Closes #2061
2019-01-31 14:19:14 +02:00
Lauri Ojansivu 8919d8fb7d Fix typo. 2019-01-30 18:52:14 +02:00
Lauri Ojansivu cdb7dd9175 Fix typo. 2019-01-30 18:49:38 +02:00
Lauri Ojansivu d6b7c17402 v2.10 2019-01-30 18:17:15 +02:00
Lauri Ojansivu 7e247c14b2 Update translations (mk). 2019-01-30 18:07:23 +02:00
Lauri Ojansivu e6af48fc4a Update changelog with latest changes. 2019-01-30 18:04:44 +02:00
Lauri Ojansivu 9703843602 - Revert [Sandstorm API changes](https://github.com/wekan/wekan/commit/be03a191c4321c2f80116c0ee1ae6c826d882535
that were done at [Wekan v2.05](https://github.com/wekan/wekan/blob/devel/CHANGELOG.md#v205-2019-01-27-wekan-release)
  to fix #2143.

Thanks to pantraining and xet7 !

Closes #2143
2019-01-30 17:56:53 +02:00
Lauri Ojansivu d53a7ce5f1 Update translations. 2019-01-30 16:06:31 +02:00
Lauri Ojansivu 6e4a6515e0 - Translations: Add Macedonian. 2019-01-30 02:18:27 +02:00
Lauri Ojansivu bf304ffde5 - Translations: Add Macedonian. 2019-01-30 02:16:55 +02:00
Lauri Ojansivu 7cefe9d367 Update translations. 2019-01-29 18:56:11 +02:00
Lauri Ojansivu 12cccc25cc v2.09 2019-01-28 18:29:46 +02:00
Lauri Ojansivu 34f62cb3b3 - [Fix vertical automatic scrolling when opening a card](https://github.com/wekan/wekan/commit/820d3270935dc89f046144a7bbf2c8277e2484bc).
Thanks to bentiss !
2019-01-28 18:23:28 +02:00
Lauri Ojansivu 820d327093 Merge pull request #2140 from bentiss/scrolling-fixes
automatic scroll: fix vertical automatic scrolling when opening a card
2019-01-28 18:12:51 +02:00
Lauri Ojansivu 04279342a4 v2.08 2019-01-28 17:26:18 +02:00
Benjamin Tissoires 1cfe084cc2 automatic scroll: fix vertical automatic scrolling when opening a card
We actually want the vertical scrolling to be fixed when opening the
card details.
I am not sure where the `100` value comes from, but this makes the
scrolling happy on the swimlane view and on the lists view.
2019-01-28 16:21:43 +01:00
Lauri Ojansivu 4629cc1b19 Update translations. 2019-01-28 17:08:47 +02:00
Lauri Ojansivu b4e87466ba Merge branch 'bentiss-horizontal-fixes' into edge 2019-01-28 17:06:56 +02:00
Benjamin Tissoires ae82f43078 make the max height of the swimlane not too big
We should take a full screen minus the header height
2019-01-28 15:34:12 +01:00
Benjamin Tissoires 7cc185ac57 Properly fix horizontal rendering on Chrome and Firefox
This reverts commit 74cf9e2573 "- Fix Firefox left-rigth scrollbar."

This reverts commit 9dd8216dfb.
"- Fix cards below swimlane title in Firefox by making
[previous fix](https://github.com/wekan/wekan/pull/2132/commits/f7c6b7fce237a6dbdbbd6d728cfb11ad3f4378eb)"

And this partially reverts commit dd88eb4cc

The root of the issue was that I was adding a new div and nesting
the list of lists in this new list. This resulted in some
weird behavior that Firefox could not handled properly
Revert to a code colser to v2.02, by just having the
swimlane header in a separate line, and keep only one
flex element.

fixes #2137
2019-01-28 15:33:47 +01:00
Lauri Ojansivu 4d37e1d640 v2.07 2019-01-28 02:58:02 +02:00
Lauri Ojansivu 74cf9e2573 - Fix Firefox left-rigth scrollbar.
Thanks to xet7 !

Closes #2137
2019-01-28 02:50:25 +02:00
Lauri Ojansivu 3c2de2a38d v2.06 2019-01-27 19:11:57 +02:00
Lauri Ojansivu 9dd8216dfb - Fix cards below swimlane title in Firefox by making [previous fix](https://github.com/wekan/wekan/pull/2132/commits/f7c6b7fce237a6dbdbbd6d728cfb11ad3f4378eb)
Firefox-only.

Thanks to xet7 !
2019-01-27 19:03:50 +02:00
Lauri Ojansivu 905ddafe41 v2.05 2019-01-27 18:27:21 +02:00
Lauri Ojansivu 62a0e57f38 Update translations. 2019-01-27 18:18:20 +02:00
Lauri Ojansivu be03a191c4 - Try to have some progress on Wekan Sandstorm API. I did not get it fully working yet.
Thanks to xet7.
2019-01-27 18:16:27 +02:00
Lauri Ojansivu cf7d3b5a7e - Add back scrollbars that [were hidden when trying to fix another
bug](https://github.com/wekan/wekan/pull/2132/commits/f7c6b7fce237a6dbdbbd6d728cfb11ad3f4378eb).

Thanks to xet7 !

Closes #2134
2019-01-27 18:09:53 +02:00
Lauri Ojansivu 939d8a7078 v2.04 2019-01-26 20:20:54 +02:00
Lauri Ojansivu db62a51d5a Update translations. 2019-01-26 19:48:28 +02:00
Lauri Ojansivu 9ebf5751fd Merge pull request #2132 from bentiss/edge
Fix for v2.03
2019-01-26 19:45:56 +02:00
Benjamin Tissoires f7c6b7fce2 ui: fix rendering issue on firefox
When a list have more cards that can fit in the screen, the members icons
are drawn on top of the swimlane below and the scrollbar is not available.

According to https://github.com/utatti/perfect-scrollbar the container
must have an `overflow: hidden` css style.

When changing the swimlane header from vertical to horizontal, dd88eb4cc1
broke this which led to this weird bug.
2019-01-26 17:38:51 +01:00
Benjamin Tissoires 850b34ce33 ifttt: card actions: simplify the logic for setting the color
Jade allows a simpler approach than my initial manual update.
Just declare the correct ReactiveVar and accessor, and done.
2019-01-26 17:38:51 +01:00
Lauri Ojansivu 1a64a88d3d Waiting for bugfix. 2019-01-25 23:06:34 +02:00
Lauri Ojansivu be8f00ab8a v2.03 2019-01-25 22:18:39 +02:00
Lauri Ojansivu ddedb8a48b Update translations (de). 2019-01-25 22:14:09 +02:00
Lauri Ojansivu ba392362ee Update ChangeLog for all that huge amount of contributions from bentiss. 2019-01-25 22:09:40 +02:00
Lauri Ojansivu 8fbd47e199 Merge pull request #2130 from bentiss/color-lists
lists-color: only colorize the bottom border
2019-01-25 20:02:26 +02:00
Lauri Ojansivu 6aaf0c812a Update translations. 2019-01-25 19:25:46 +02:00
Benjamin Tissoires 33977b2282 lists-color: only colorize the bottom border
And make the background clearer to visually separate the header from
the list of cards
2019-01-25 18:13:37 +01:00
Lauri Ojansivu 37f70bdf0f Merge branch 'devel' into edge 2019-01-25 19:13:08 +02:00
Lauri Ojansivu 5d6203f5f9 Merge pull request #2128 from bentiss/color-lists
Color lists
2019-01-25 19:05:44 +02:00
Lauri Ojansivu 082aabc735 Merge pull request #2127 from bentiss/fix-set-member
api: fix set_board_member_permission
2019-01-25 19:05:26 +02:00
Lauri Ojansivu ba15526516 Merge pull request #2126 from bentiss/color-swimlanes
Color for swimlanes
2019-01-25 19:05:09 +02:00
Lauri Ojansivu 4a2576fbc2 Merge pull request #2121 from bentiss/color
Color picker in IFTTT
2019-01-25 19:04:45 +02:00
Benjamin Tissoires 97d95b4bcb ui: lists: make sure all lists boxes are the same height
When `Show card count` is enabled, the lists with the card counts have
two lines of text while the lists without have only one.

This results in the box around the list headers are not of the same size
and this is visible when setting a color to the list.
2019-01-25 15:58:52 +01:00
Benjamin Tissoires d0a9d8c581 colors: add per list color
Hamburger menu only.

Note that I am definitively not responsible for the resulting Christmas
tree.

fixes #328
2019-01-25 15:56:40 +01:00
Benjamin Tissoires 78c779faaf client: lists headers: use padding instead of margin
No visual changes but allows to set a background color to the list header.
2019-01-25 14:25:28 +01:00
Benjamin Tissoires 8d81aca439 api: fix set_board_member_permission
If the data is passed as a boolean, through json, data.toLowerCase()
raises an error.

Also define query which we are returning in case of success.
2019-01-25 14:15:08 +01:00
Benjamin Tissoires 6c3dbc3c6f api: new_card: add the card at the end of the list
If we keep the `0` value, the card might be inserted in the middle of the
list, making it hard to find it later on.

Always append the card at the end of the list by setting a sort value
based on the number of cards in the list.
2019-01-25 12:44:27 +01:00
Benjamin Tissoires b5411841cf api: fix the sort field when inserting a swimlane or a list
This has the side effect of always inserting the element at the end.
2019-01-25 11:04:56 +01:00
Benjamin Tissoires 5c6a725712 Make sure Swimlanes and Lists have a populated sort field
When moving around the swimlanes or the lists, if one element has a sort
with a null value, the computation of the new sort value is aborted,
meaning that there are glitches in the UI.

This happens on the first swimlane created with the new board, or when
a swimlane or a list gets added through the API.
2019-01-25 11:04:56 +01:00
Benjamin Tissoires 03efeaeb1a Add colors to swimlanes
fixes #1688
2019-01-25 11:04:40 +01:00
Benjamin Tissoires c075187088 swimlane: insert the new swimlane after the one we clicked on 2019-01-24 20:52:03 +01:00
Benjamin Tissoires 416b17062e Remove the 'Add Swimlane' entry and replace it by a plus sign
Still need to create the swimlane right after the one that has been
created
2019-01-24 20:51:38 +01:00
Benjamin Tissoires dd88eb4cc1 swimlane-view: have the swimlane header horizontal
This allows to use the header as a separator between swimlanes.

This will be most useful when we can set the background color of these
headers.
2019-01-24 20:50:42 +01:00
Benjamin Tissoires 5fa0821e07 card colors: remove unused variables 2019-01-24 20:50:42 +01:00
Benjamin Tissoires 6e9bad5772 IFTTT: card colors: add an actual white entry
To unset the color through the IFTTT, we need a white entry.
However, we do not want to show the white enry in the hamburger
`Set Color` entry.

We can also give the `white` capability to the API, it won't hurt
and be more straightforward.
2019-01-24 16:51:06 +01:00
Benjamin Tissoires 5769d438a0 rules: set card color: use the color picker 2019-01-24 16:51:06 +01:00
Benjamin Tissoires 8a48ff96ef set card colors: properly set the title of the popups 2019-01-24 16:51:06 +01:00
Benjamin Tissoires 0782c97d4f card colors: force overwrite of text color
This allows to show checks on the color with the correct color instead
of plain white.
2019-01-24 09:32:38 +01:00
Lauri Ojansivu 542cc75dc4 Update translations (tr). 2019-01-22 19:27:32 +02:00
Lauri Ojansivu 1b445ad789 v2.02 2019-01-22 17:31:57 +02:00
Lauri Ojansivu 9baed4256a Update translations (he). 2019-01-22 17:28:19 +02:00
Lauri Ojansivu 2b4df7e8c7 Update changelog. 2019-01-22 17:26:48 +02:00
Lauri Ojansivu 6e28dec712 Merge pull request #2119 from bentiss/fix-color-translation
Fix: Translate and add colors to IFTTT Rules dropdown."
2019-01-22 16:45:29 +02:00
Benjamin Tissoires ba9f0ca672 Fix: Translate and add colors to IFTTT Rules dropdown."
This fixes commit 44e4df2492.

When the label has a name, not setting `translatedname` results in a
blank item in the IFTTT label trigger.
2019-01-22 15:40:54 +01:00
Lauri Ojansivu 7261ccdc90 Update translations. 2019-01-22 16:32:43 +02:00
Lauri Ojansivu 6fbadbe5bc Merge pull request #2118 from bentiss/export
Allow to call export from the API
2019-01-22 16:29:42 +02:00
Benjamin Tissoires 26d7ba72aa api: export board: allow authentication through generic authentication
This allows to retrieve the full export of the board from the API.
When the board is big, retrieving individual cards is heavy for both
the server and the number of requests.

Allowing the API to directly call on export and then treat the data
makes the whole process smoother.
2019-01-22 15:14:01 +01:00
Lauri Ojansivu 44e4df2492 - Translate and add colors to IFTTT Rules dropdown.
Thanks to xet7 !
2019-01-22 15:22:31 +02:00
Lauri Ojansivu d8482b533a Merge pull request #2117 from bentiss/color
Set the card color with the color picker
2019-01-22 14:57:00 +02:00
Benjamin Tissoires 2082480ddd Set the card color with the color picker
When triggered from the hamburger
2019-01-22 13:45:08 +01:00
Lauri Ojansivu e8c4e394fd Update translations. 2019-01-22 14:01:07 +02:00
Lauri Ojansivu 0c5052ebae Merge pull request #2116 from bentiss/color
Add per card color
2019-01-22 13:02:14 +02:00
Lauri Ojansivu d3b2ae1975 Update translations. 2019-01-22 12:12:18 +02:00
Benjamin Tissoires f4f0f489eb add action: set card color 2019-01-22 11:10:29 +01:00
Benjamin Tissoires 3368ebf067 color: add option in hamburger to change the card color
Currently only dropdown, no palette

Fixes: #428
2019-01-22 11:10:29 +01:00
Benjamin Tissoires b0ac10d94a Add the ability to change the card background
Currently the only way to set it is via the REST API
2019-01-22 11:10:29 +01:00
Lauri Ojansivu c87a8b86ae - Added missing translation for 'days'
Thanks to Chartman123 !

Closes #2114
2019-01-21 16:26:55 +02:00
Lauri Ojansivu d5d71d7097 Update upcase/lowercase. 2019-01-20 00:53:59 +02:00
Lauri Ojansivu c960a8b909 - [OpenAPI and generating of REST API Docs](https://github.com/wekan/wekan/pull/1965).
Thanks to bentiss.
2019-01-19 21:14:32 +02:00
Lauri Ojansivu 3257f78d24 Merge branch 'bentiss-openapi' into devel 2019-01-19 21:09:42 +02:00
Lauri Ojansivu a9133bf933 Merge branch 'openapi' of https://github.com/bentiss/wekan into bentiss-openapi 2019-01-19 20:55:14 +02:00
Lauri Ojansivu 8e8147b5ac - Fix License to 2019. https://github.com/wekan/wekan/pull/2112
Thanks to ajRiverav !
2019-01-19 20:45:43 +02:00
Lauri Ojansivu 711f4de3d7 Merge pull request #2112 from ajRiverav/devel
update license to year 2019
2019-01-19 20:43:42 +02:00
Lauri Ojansivu 68998e062e Update translations. 2019-01-19 20:42:41 +02:00
AJ Rivera f40d1f6bd5 update license to year 2019 2019-01-18 17:25:48 -04:00
Benjamin Tissoires 048c3cd14d snap: also generate the html doc of the REST API
Same for snap: embed the documentation of the REST API
in the snap.
2019-01-18 19:33:08 +01:00
Benjamin Tissoires 08ca353205 openapi: generate the HTML documentation too and embed it in the image
Aligning with the requirement to run the container without
external resources: embed the documentation of the REST API
directly in the Docker image.
2019-01-18 19:33:08 +01:00
Benjamin Tissoires c83cdc9335 Add openapi in snaps
Same thing than in the Dockerfile, snaps need
to embed the current openapi yaml file.
2019-01-18 17:07:18 +01:00
Benjamin Tissoires e91e3c076d snapcraft add nodejs and npm as build dependencies
When pulling the docker container snapcore/snapcraft
to build the snap, those 2 packages are not present
by default leading to a failure in the snap creation.

Note: it is good to call `apt-get update` before
`snapcraft` or the build will fail.
2019-01-18 17:05:41 +01:00
Benjamin Tissoires 8be7eec2ca openapi: make the code python 3.5 compatible
It is common to use Ubuntu 16.04 to build snaps. For example,
the official docker container to build snaps is using this old
distribution.

However, Ubuntu 16.04 ships Python 3.5.X which is not compatible
with the f-strings in generate_openapi.py. This is sad, because
we need to use the `.format()` syntax to make it compatible.
2019-01-18 17:03:12 +01:00
Benjamin Tissoires acc4493517 Generate the OpenAPI in the Dockerfile
When we build the docker container, we need to generate the openapi
description in it so the geenrated API actually matches the code
the container is running.
2019-01-18 17:03:05 +01:00
Benjamin Tissoires ff467402c0 RESTAPI: Add some JSDoc
So we can have a decent REST API documentation generated.
2019-01-18 17:02:56 +01:00
Benjamin Tissoires 49d3eb5a3f Add OpenAPI description of the REST API
The API is generated by a custom script that parses the models directory.
Once the API is generated, tools like https://editor.swagger.io/ or
Python bravado can parse the file and generate a language friendly API.

Note that the tool generate an OpenAPI 2.0 version because bravado
doesn't handle OpenAPI 3.0.

The script also parses the JSDoc with a custom parser to allow
customization of the description of the fields.
2019-01-18 17:01:11 +01:00
Benjamin Tissoires 889aa6d652 Revert "models: boards: add PUT members entry point"
This reverts commit f61942e5cb.

Adding a member is actually already handled by
POST', '/api/boards/:boardId/members/:userId/add'

So this function is purely duplicated.

Not to mention that the '/add' one allows to set permissions
so this one in this commit is less interesting.
2019-01-18 17:01:03 +01:00
Lauri Ojansivu 78e0457843 Update translations (ca). 2019-01-15 15:47:46 +02:00
Lauri Ojansivu 7f568faef6 Fix typo.
Thanks to xorander00 !

Closes #2101
2019-01-13 20:12:57 +02:00
Lauri Ojansivu be045f3156 Fix typo.
Thanks to xorander00 !

Closes #2101
2019-01-13 20:10:20 +02:00
Lauri Ojansivu 3b5e81d514 Update translations. 2019-01-11 16:34:02 +02:00
Lauri Ojansivu 346bdf2ca8 v2.01 2019-01-06 13:29:04 +02:00
Lauri Ojansivu 501289786c Update translations (cs and he). 2019-01-06 13:26:10 +02:00
Lauri Ojansivu 24ffe223be v2.00 2019-01-04 20:07:22 +02:00
Lauri Ojansivu 32c561d78e Update translations. 2019-01-04 20:03:16 +02:00
Lauri Ojansivu ff65b37336 v1.99 2019-01-04 12:17:05 +02:00
Lauri Ojansivu 3f698ca012 Update translations. 2019-01-04 12:07:03 +02:00
Lauri Ojansivu 785bc2556e - Merge duplicate translation.
Thanks to xet7 !
2019-01-04 11:26:38 +02:00
Lauri Ojansivu e198282b4d - Remove duplicate translation.
Thanks to xet7 !
2019-01-04 11:18:26 +02:00
Lauri Ojansivu 24e59c378b Merge branch 'edge' into devel 2019-01-04 11:14:18 +02:00
Lauri Ojansivu c1b4aae573 Merge branch 'Angtrim-feature-rules' into devel 2019-01-04 11:12:54 +02:00
Lauri Ojansivu f5339ef97f - Fix lint errors.
Thanks to xet7 !
2019-01-04 11:00:33 +02:00
Lauri Ojansivu 2b53fae16f Merge branch 'feature-rules' of https://github.com/Angtrim/wekan into Angtrim-feature-rules 2019-01-04 09:23:54 +02:00
Lauri Ojansivu 1d3466c7a0 Update translations (pt-BR). 2019-01-04 09:05:57 +02:00
Angelo Gallarello 4d8b2029d2 Fixed errors 2019-01-02 22:51:00 +01:00
Angelo Gallarello 8ad0da2109 Added create card action 2019-01-02 22:32:08 +01:00
Angelo Gallarello 12827ef0a6 Added notes 2019-01-02 15:52:58 +01:00
Angelo Gallarello 4c399a41f7 Add action: create checklist with items 2019-01-02 15:42:10 +01:00
Angelo Gallarello 25968a35cc Finished triggers improvements 2019-01-02 14:45:45 +01:00
Lauri Ojansivu 548d095223 - Add find.sh bash script that ignores extra directories when searching.
xet7 uses this a lot when developing.

Thanks to xet7 !
2019-01-02 13:22:21 +02:00
Lauri Ojansivu 1683bcb3e5 v1.98 2019-01-01 14:08:44 +02:00
Lauri Ojansivu 991843acb0 - [Mobile fixes](https://github.com/wekan/wekan/pull/2084), thanks to hupptechnologies:
- Move home button / avatar bar from bottom to top. So at top first is home button / avatar, then others.
  - When clicking Move Card, go to correct page position. Currently it's at empty page position, and there is
    need to scroll page up to see Move Card options. It should work similarly like Copy Card, that is visible.
  - Also check that other buttons go to visible page.
2019-01-01 14:03:24 +02:00
Lauri Ojansivu 8b85437b6b Merge branch 'hupptechnologies-wekan-mobile-use-issue' into devel 2019-01-01 13:59:34 +02:00
Lauri Ojansivu 6259f0de70 - Add removed packages back.
Thanks to xet7 !
2019-01-01 13:42:13 +02:00
Lauri Ojansivu d86bc1d84d Merge branch 'wekan-mobile-use-issue' of https://github.com/hupptechnologies/wekan into hupptechnologies-wekan-mobile-use-issue 2019-01-01 13:41:26 +02:00
Lauri Ojansivu 88bdb0815d Update translations (cs). 2019-01-01 13:40:22 +02:00
hupptechnologies 97f64fe5e6 Issue: Hard to use Wekan on mobile because of UI/UX issues #953
Resolved #953
2019-01-01 16:35:18 +05:30
Angelo Gallarello 196fef3a1b Added popup 2018-12-31 00:45:11 +01:00
Angelo Gallarello a2d756074f Added swimlane trigger 2018-12-30 22:08:34 +01:00
Angelo Gallarello b2f23d619d Triggers by username, updated desc 2018-12-29 17:36:57 +01:00
Angelo Gallarello 9d1d66b0f5 Added triggers by username 2018-12-29 16:59:50 +01:00
Lauri Ojansivu c61e44d55b - Add optional Nginx reverse proxy config to docker-compose.yml and nginx directory.
Thanks to MyTheValentinus !
2018-12-28 17:26:30 +02:00
Lauri Ojansivu 76c5c283b9 - docker-compose.yml back to MongoDB 3.2.21 because 3.2.22 MongoDB container does not exist yet.
Thanks to xet7 !
2018-12-27 00:35:39 +02:00
Lauri Ojansivu 2d88afb77e - docker-compose.yml back to MongoDB 3.2.21 because 3.2.22 MongoDB container does not exist yet.
Thanks to xet7 !
2018-12-26 23:57:00 +02:00
Lauri Ojansivu 7fd09761cb v1.97 2018-12-26 22:49:14 +02:00
Lauri Ojansivu cb53c53c2b - Use Node 8.15.0 and MongoDB 3.2.22.
- Stacksmith: back to Meteor 1.6.x based Wekan, because Meteor 1.8.x based is currently broken.

Thanks to xet7 !
2018-12-26 22:32:25 +02:00
Lauri Ojansivu 77ff6349f6 - Use Node 8.15.0 and MongoDB 3.2.22.
- Stacksmith: back to Meteor 1.6.x based Wekan, because Meteor 1.8.x based is currently broken.

Thanks to xet7 !
2018-12-26 22:29:04 +02:00
Lauri Ojansivu 879ad4001d Update translations (he). 2018-12-26 11:40:31 +02:00
Lauri Ojansivu e1436ab964 Update rebuild script. 2018-12-24 23:54:57 +02:00
Lauri Ojansivu 007bea0a4b Update rebuild script. 2018-12-24 23:50:43 +02:00
Lauri Ojansivu 67b76558fc v1.96 2018-12-24 18:26:33 +02:00
Lauri Ojansivu f60429efdf - Comment out docker build from source part of docker-compose.yml
Thanks to xet7 !
2018-12-24 18:24:32 +02:00
Lauri Ojansivu f140e20c6f - Revert "Improve authentication" and "Default Authentication Method"
to make login work again.
- Fixes to docker-compose.yml so that Wekan Meteor 1.6.x version would work.
  Most likely Meteor 1.8.x version is still broken.

Thanks to xet7 !
2018-12-24 18:22:30 +02:00
Lauri Ojansivu c502ab9500 - Revert "Improve authentication" and "Default Authentication Method"
to make login work again.
- Fixes to docker-compose.yml so that Wekan Meteor 1.6.x version would work.
  Most likely Meteor 1.8.x version is still broken.

Thanks to xet7 !
2018-12-24 18:18:41 +02:00
Lauri Ojansivu 425ae55422 Update translations (fa). 2018-12-24 16:41:36 +02:00
Lauri Ojansivu e9006a234b - Fix docker-compose.yml to use Meteor 1.6.x based Wekan,
because currently Meteor 1.8.x based version is broken.

Thanks to xet7 !
2018-12-24 16:29:53 +02:00
Lauri Ojansivu ef6aa4e415 - Move wekan-postgresql back to https://github.com/wekan/wekan-postgresql
because there is many differences in database settings.

Thanks to xet7 !
2018-12-22 21:40:34 +02:00
Lauri Ojansivu 1901c3c798 Fix typo. 2018-12-22 19:04:43 +02:00
Lauri Ojansivu 6cb046f29e Update translations (de). 2018-12-22 18:57:23 +02:00
Lauri Ojansivu e7e67e300b - [Combine all docker-compose.yml files](https://github.com/wekan/wekan/commit/3f948ba49ba7266c436ff138716bdcae9e879903). Thanks to xet7. 2018-12-22 18:46:45 +02:00
Lauri Ojansivu 3f948ba49b - Combine all docker-compose.yml files.
Thanks to xet7 !
2018-12-22 18:44:08 +02:00
Lauri Ojansivu 96f33e4052 v1.95 2018-12-21 22:23:12 +02:00
Lauri Ojansivu 68d60f4f64 - Upgrade to node v8.14.1
Thanks to xet7 !
2018-12-21 22:12:54 +02:00
Lauri Ojansivu f7153da83d - Upgrade to node v8.14.1
Thanks to xet7 !
2018-12-21 22:11:43 +02:00
Lauri Ojansivu 16d53897c7 - [Drag handles and long press on mobile when using desktop mode of mobile
browser](https://github.com/wekan/wekan/pull/2067). Thanks to hupptechnologies.
2018-12-21 21:56:30 +02:00
Lauri Ojansivu 32d405bca4 Merge branch 'hupptechnologies-ui-feature-drag-handler' into devel 2018-12-21 21:52:42 +02:00
Lauri Ojansivu 2f747fc09d - Added removed packages back.
Thanks to xet7 !
2018-12-21 21:10:00 +02:00
Lauri Ojansivu 32d5a1d3f7 Merge branch 'ui-feature-drag-handler' of https://github.com/hupptechnologies/wekan into hupptechnologies-ui-feature-drag-handler 2018-12-21 21:09:31 +02:00
Lauri Ojansivu db44b8ea54 Merge branch 'Akuket-devel' into devel 2018-12-21 20:53:31 +02:00
Lauri Ojansivu 1f512c8ba1 - [Improve authentication](https://github.com/wekan/wekan/pull/2065): remove login dropdown,
and add setting `DEFAULT_AUTHENTICATION_METHOD=ldap` or
  `sudo snap set wekan default-authentication-method='ldap'`. Thanks to Akuket. Closes wekan/wekan-ldap#31
2018-12-21 20:52:48 +02:00
Lauri Ojansivu 417dc9dc42 Fix lint errors. 2018-12-21 20:36:26 +02:00
Lauri Ojansivu bd66ea8acc Update translations (ru). 2018-12-21 20:16:35 +02:00
Lauri Ojansivu dba9d13b00 Update translations. 2018-12-21 20:11:32 +02:00
Lauri Ojansivu 1e034a794f - Update translated text. 2018-12-21 19:47:34 +02:00
Lauri Ojansivu a261c66f34 Merge branch 'devel' of https://github.com/Akuket/wekan into Akuket-devel 2018-12-21 19:34:32 +02:00
hupptechnologies b94bd73d33 Uncommect packages 2018-12-20 14:43:21 +05:30
hupptechnologies a9be6b17b9 Issue : UI feature suggestion: drag handles and long press #1772
Resolved #1772
2018-12-20 14:42:46 +05:30
Lauri Ojansivu ac6f8e8551 - Output Meteor 1.8.x version in build log.
Thanks to xet7 !
2018-12-19 19:55:30 +02:00
Lauri Ojansivu 23fb2bfc7f - Use meteor 1.8.x, because Stacksmith uses MongoDB 4.0.3.
Thanks to xet7 !
2018-12-19 19:42:40 +02:00
guillaume ff1c3722a8 Patch currentBoard doesn't exist when logout 2018-12-19 17:22:16 +01:00
guillaume 1712368f6a Improves UI for ldap error messages 2018-12-19 17:21:27 +01:00
guillaume d7529bf6b5 Add help message for the new env var in snap 2018-12-19 13:53:05 +01:00
guillaume 6b145bb3cc Add a new env var to select the default authentication method 2018-12-19 13:42:51 +01:00
guillaume 72e905675d Removes the dropdown for the authentication method 2018-12-19 13:41:21 +01:00
Lauri Ojansivu 2fbcf7e9b6 v1.94 2018-12-18 20:22:11 +02:00
Lauri Ojansivu 0ade4dbf00 - Use wekan/wekan repo.
Thanks to xet7 !
2018-12-18 20:05:10 +02:00
Lauri Ojansivu d70ad9d733 - Comment out extra node version.
Thanks to xet7 !
2018-12-18 19:42:04 +02:00
Lauri Ojansivu 51a19878dd Merge pull request #2064 from j-fuentes/devel
Add Bitnami Stacksmith
2018-12-18 19:40:44 +02:00
Lauri Ojansivu ddca6a1ad8 Update translations. 2018-12-18 19:27:23 +02:00
Jose Fuentes cac74122f2 Wait for DB on boot 2018-12-17 13:09:32 +01:00
Lauri Ojansivu 991b2b9721 Update translations (he). 2018-12-17 01:15:44 +02:00
Lauri Ojansivu b6663acf91 Update translations. 2018-12-16 23:48:43 +02:00
Lauri Ojansivu 7f74e72cea - Trying to get custom HTML working as described at
https://guide.meteor.com/v1.3/blaze.html#rendering-html
  Still does not work yet.

Thanks to xet7 !
2018-12-16 23:46:04 +02:00
Lauri Ojansivu bd1df642fa - Maybe custom html should be here. But it still does not work yet.
Thanks to xet7 !
2018-12-16 22:50:23 +02:00
Lauri Ojansivu 575b0241e4 Update translations. 2018-12-16 22:27:45 +02:00
Lauri Ojansivu f1ed6304a4 - Admin Panel / Layout / Custom HTML after <body> start, and Custom HTML before </body> end.
In progress, does not work yet.

Thanks to xet7 !
2018-12-16 22:21:16 +02:00
Lauri Ojansivu a42d9871bd v1.93 2018-12-16 19:09:16 +02:00
Lauri Ojansivu 7a2ea7cace Fix typo. 2018-12-16 19:03:49 +02:00
Lauri Ojansivu fb39811d95 Update translations. 2018-12-16 19:02:09 +02:00
Lauri Ojansivu 78e88f4c42 - Remove Wekan_version translation string.
Thanks to xet7 !
2018-12-16 18:36:50 +02:00
Lauri Ojansivu db63af5f7a - In tranlations, only show name "Wekan" in Admin Panel Wekan version.
Elsewhere use general descriptions for whitelabeling.

Thanks to xet7 !
2018-12-16 18:27:47 +02:00
Lauri Ojansivu c3e04da796 - Update translations (ru). 2018-12-16 18:14:18 +02:00
Lauri Ojansivu 2a59043ef1 v1.92 2018-12-16 11:58:44 +02:00
Lauri Ojansivu 3d76a35a68 - Fix [favicon paths for non-suburl cases](https://github.com/wekan/wekan/commit/c1733fc89c4c73a1ab3f4054d0a9ebff7741a804).
Thanks to xet7 !

Related #1692
2018-12-16 11:45:12 +02:00
Lauri Ojansivu c1733fc89c - Fix favicon paths for non-suburl cases.
Thanks to xet7 !

Related #1692
2018-12-16 11:41:10 +02:00
Lauri Ojansivu 388c1bec45 - Fix [Card scrollbar ignores mousewheel](https://github.com/wekan/wekan-scrollbar/commit/94a40da51627c6322afca50a5b1f4aa55c7ce7bf).
Thanks to rinnaz and xet7 !

Closes #2058
2018-12-16 11:14:16 +02:00
Lauri Ojansivu a2869e9d2a - Fix [Popup class declares member name _current but use current instead](https://github.com/wekan/wekan/issues/2059).
Thanks to peishaofeng !

Closes #2059
2018-12-16 11:10:06 +02:00
Lauri Ojansivu 3e5ff42474 - Fix [Popup class declares member name _current but use current instead](https://github.com/wekan/wekan/issues/2059).
Thanks to peishaofeng !

Closes #2059
2018-12-16 11:06:29 +02:00
Lauri Ojansivu 9366eaf374 - Fix typo.
Thanks to xet7 !
2018-12-16 00:42:13 +02:00
Lauri Ojansivu cb4c93a632 v1.91 2018-12-15 22:44:25 +02:00
Lauri Ojansivu adaffd7189 - [Add back mquandalle:perfect-scrollbar package so that Firefox and Chrome
stop complaning in browser dev tools console](https://github.com/wekan/wekan/issues/2057).

Thanks uusijani and xet7 !

Closes #2057
2018-12-15 22:41:10 +02:00
Lauri Ojansivu 821dc22e80 - Add back mquandalle:perfect-scrollbar package so that Firefox and Chrome
stop complaning in browser dev tools console.

Thanks to uusijani and xet7 !

Closes #2057
2018-12-15 22:36:15 +02:00
Lauri Ojansivu b0a71e96cc v1.90 2018-12-15 22:01:57 +02:00
Lauri Ojansivu 40e156992a - [Remove not working duplicate saveMailServerInfo](https://github.com/wekan/wekan/commit/ab031d9da134aa13490a26dbe97ad2d7d01d534a),
to remove error from browser dev tools console.

Thanks to xet7 !
2018-12-15 21:59:29 +02:00
Lauri Ojansivu ab031d9da1 - Remove not working duplicate saveMailServerInfo, to remove
error from browser dev tools console.

Thanks to xet7 !
2018-12-15 21:55:20 +02:00
Lauri Ojansivu 209a76c5ce v1.89 2018-12-15 20:52:11 +02:00
Lauri Ojansivu 4bd74b5817 - Admin Panel / Layout / Custom Product Name [now changes webpage title](https://github.com/wekan/wekan/commit/dbb1a86ca377e551063cc04c5189fad4aa9148c0).
Related #1196

Thanks to xet7 !
2018-12-15 20:46:47 +02:00
Lauri Ojansivu dbb1a86ca3 - Admin Panel / Layout / Custom Product Name now changes webpage title.
Thanks to xet7 !

Related #1196
2018-12-15 20:39:01 +02:00
Lauri Ojansivu c066883dbd v1.88 2018-12-14 23:31:17 +02:00
Lauri Ojansivu 0b6b6dc7fd - Fix: [Scrollbar used](https://github.com/wekan/wekan/issues/2056) [remote file from CDN](https://github.com/MaazAli/Meteor-Malihu-Custom-Scrollbar/blob/master/jquery.mCustomScrollbar.js#L50),
so forked package to https://github.com/wekan/wekan-scrollbar and included
  non-minified file locally to Wekan, so that using scrollbar works without direct connection
  to Internet. Wekan should not load any external files by default, as was case before
  new scrollbar, and is again now [after this fix](https://github.com/wekan/wekan/commit/c546464d9f56117a8bf580512cd62fc1102559c3).

Thanks to xet7 !

Closes #2056
2018-12-14 23:27:22 +02:00
Lauri Ojansivu c546464d9f - Because scrollbar uses [remote file from CDN](https://github.com/MaazAli/Meteor-Malihu-Custom-Scrollbar/blob/master/jquery.mCustomScrollbar.js#L50),
fork package to https://github.com/wekan/wekan-scrollbar and include
  non-minified file locally to Wekan, so that using scrollbar works without direct connection
  to Internet. Wekan should not load any external files by default, as was case before
  new scrollbar, and is again now after this fix.

Closes #2056
2018-12-14 23:13:15 +02:00
Jose Fuentes 7b3e2c58e2 Pipefail error 2018-12-14 11:06:00 +01:00
Jose Fuentes d6127082e9 Add stacksmith scripts 2018-12-13 20:27:35 +01:00
Lauri Ojansivu 67a5fdaf96 v1.87 2018-12-13 20:13:50 +02:00
Lauri Ojansivu af9156b18a Update translations (es). 2018-12-13 20:12:03 +02:00
Lauri Ojansivu 7af20fd2d9 - Fix Reference error.
Thanks to Akuket !
2018-12-13 20:10:00 +02:00
Lauri Ojansivu 2a5a428bc0 - Fix Reference error.
Thanks to Akuket !
2018-12-13 20:07:55 +02:00
Lauri Ojansivu 4b7d47465a v1.86 2018-12-13 14:40:16 +02:00
Lauri Ojansivu 5f4e2d8e06 - Fix [Cannot login with new LDAP account when auto-registration disabled (request invitation code)](https://github.com/wekan/wekan-ldap/issues/29);
- Fix [Unable to create new account from LDAP](https://github.com/wekan/wekan-ldap/issues/32).

Thanks to Akuket !
2018-12-13 14:34:11 +02:00
Lauri Ojansivu f8ef8507b5 - Fix [Cannot login with new LDAP account when auto-registration disabled (request invitation code)](https://github.com/wekan/wekan-ldap/issues/29);
- Fix [Unable to create new account from LDAP](https://github.com/wekan/wekan-ldap/issues/32).

Thanks to Akuket !

Closes wekan/wekan-ldap#29,
closes wekan/wekan-ldap#32
2018-12-13 14:27:34 +02:00
Lauri Ojansivu 2ae143e6da Update translations. 2018-12-13 14:10:55 +02:00
Lauri Ojansivu 38e8f52293 Add missing text about bugs fixes. 2018-12-09 01:44:08 +02:00
Lauri Ojansivu b143fc9297 v1.85 2018-12-09 00:49:07 +02:00
Lauri Ojansivu dd10f78401 Merge branch 'hupptechnologies-scrollbar-closes-card-chrome' into devel 2018-12-09 00:44:47 +02:00
Lauri Ojansivu 90208b774a - Fix [Clicking the scrollbar closes the card on Chrome](https://github.com/wekan/wekan/issues/1404)
by changing [mquandalle:perfect-scrollbar to malihu-jquery-custom-scrollbar](https://github.com/wekan/wekan/pull/2050).
  that works also when clicking scrollbar in Chrome. Also added back required packages that were removed in PR.

Thanks to hupptechnologies and xet7 !
2018-12-09 00:43:21 +02:00
Lauri Ojansivu bc35d9fe1a - Fix [Clicking the scrollbar closes the card on Chrome](https://github.com/wekan/wekan/issues/1404)
by changing [mquandalle:perfect-scrollbar to malihu-jquery-custom-scrollbar](https://github.com/wekan/wekan/pull/2050).
  that works also when clicking scrollbar in Chrome. Also added back required packages that were removed in PR.

Thanks to hupptechnologies and xet7 !

Closes #1404
2018-12-09 00:33:36 +02:00
Lauri Ojansivu 472d637c9f Merge branch 'scrollbar-closes-card-chrome' of https://github.com/hupptechnologies/wekan into hupptechnologies-scrollbar-closes-card-chrome 2018-12-09 00:21:35 +02:00
Lauri Ojansivu 20c86613a7 Update translations (ru). 2018-12-09 00:16:48 +02:00
hupptechnologies 5ac69ed7de Fix lineter issue 2018-12-08 18:05:59 +05:30
hupptechnologies 0620fe5e11 Issue : Clicking the scrollbar closes the card on Chrome #1404
Resolved #1404
2018-12-08 17:53:26 +05:30
hupptechnologies 44a819226f Merge branch 'devel' into edge 2018-12-08 17:20:56 +05:30
Lauri Ojansivu cf2cf7898a - Fix lint warning.
Thanks to xet7 !
2018-12-07 06:18:46 +02:00
Lauri Ojansivu ee212b69a9 v1.84 2018-12-07 05:20:06 +02:00
Lauri Ojansivu 87d91560f8 Update translations (ru). 2018-12-07 05:11:08 +02:00
Lauri Ojansivu bccca00aaf - Fix 2/8: IFTTT Rule action/trigger ["Remove all members from the card"](https://github.com/wekan/wekan/issues/1972).
Thanks to BurakTuran9 !
2018-12-07 05:07:22 +02:00
Lauri Ojansivu d6e36ed50a - Fix: IFTTT Rule "Remove all members from the card" doesn't work.
Thanks to BurakTuran9 !

Related #1972
2018-12-07 04:57:51 +02:00
Lauri Ojansivu 83f7fa768d v1.83 2018-12-06 01:59:37 +02:00
Lauri Ojansivu 2d49006aee - Fix IFTTT Rule action/trigger part 1 of 7: [When a checklist is completed](https://github.com/wekan/wekan/issues/1972).
And partial incomplete fix to when all of checklist is set as uncompleted. Help in fixing welcome.

Thanks to BurakTuran9 and xet7 !

Related #1972
2018-12-06 01:55:02 +02:00
Lauri Ojansivu c2e58dcb62 - Partial fix to unchecked rule, and tips for fixing.
Related #1972
2018-12-06 01:49:57 +02:00
Lauri Ojansivu f154c5e521 Update translations. 2018-12-05 15:45:42 +02:00
Lauri Ojansivu eadbebb4fa - Fix IFTTT Rule action/trigger: When a checklist is completed/made incomplete.
Thanks to BurakTuran9 !

Related #1972
2018-12-05 15:45:10 +02:00
Lauri Ojansivu 40cf1c7549 - Fix IFTTT Rule action/trigger: When a checklist is completed/made incomplete.
Thanks to BurakTuran9 !

Related #1972
2018-12-05 15:21:24 +02:00
Lauri Ojansivu 9c4e305a84 v1.82 2018-12-05 08:53:40 +02:00
Lauri Ojansivu 167197fcda - Partially #2045 revert, continue.
Thanks to xet7 !
2018-12-05 08:47:48 +02:00
Lauri Ojansivu e3a40aca6f This release fixes the following bugs:
- Partially #2045 revert [Improve authentication](https://github.com/wekan/wekan/issues/2016),
  adding back password/LDAP dropdown, because login did now work.
  NOTE: This was added in v1.71, reverted at v1.73 because login did not work, added back at v1.79,
  and then reverted partially at v1.82 because login did not work.
  Related LDAP logout timer does not work yet.

Thanks to xet7 !
2018-12-05 08:20:59 +02:00
Lauri Ojansivu 0611e0c4bd Add text about fixing bugs. 2018-12-04 22:32:30 +02:00
Lauri Ojansivu d6857693bb v1.81 2018-12-04 22:30:54 +02:00
Lauri Ojansivu b5ccf7a58f - Remove extra commas , and add missing backslash \.
Maybe after that login, logout and CORS works.

Thanks to xet7 !

Related #2045,
related wekan/wekan-snap#69
2018-12-04 22:23:49 +02:00
Lauri Ojansivu bfca1822a0 - Remove extra commas , and add missing backslash \.
Maybe after that login, logout and CORS works.

Thanks to xet7 !

Related #2045,
related wekan/wekan-snap#69
2018-12-04 22:20:24 +02:00
Lauri Ojansivu 30151de269 v1.80 2018-12-03 18:22:41 +02:00
Lauri Ojansivu fe7c4528d7 - Upgrade Node from v8.12 to v8.14
- Revert non-working architectures that were added at v1.79, so now Wekan is just amd64 as before.

Thanks to xet7 !
2018-12-03 18:19:25 +02:00
Lauri Ojansivu 40367995e7 v1.79 2018-12-03 16:29:58 +02:00
Lauri Ojansivu b75fafc5f2 - Add CORS https://enable-cors.org/server_meteor.html
- Add missing LDAP and TIMER environment variables.

Thanks to xet7 !

Closes wekan/wekan-snap#69
2018-12-03 16:20:04 +02:00
Lauri Ojansivu b788deb002 - Add CORS https://enable-cors.org/server_meteor.html
- Add missing LDAP and TIMER environment variables.

Thanks to xet7 !

Closes wekan/wekan-snap#69
2018-12-03 16:05:24 +02:00
Lauri Ojansivu fa6b2e5679 - Improve authentication. Thanks to Akuket. 2018-12-03 11:31:03 +02:00
Lauri Ojansivu 70fd1ce57d Fix lint errors. 2018-12-03 11:18:54 +02:00
Lauri Ojansivu 97158de70f Merge branch 'Akuket-devel' into edge 2018-12-02 23:30:10 +02:00
Lauri Ojansivu 926faf0031 Merge branch 'devel' of https://github.com/Akuket/wekan into Akuket-devel 2018-12-02 23:28:39 +02:00
Lauri Ojansivu 228996412c - Fix wrong dates in ChangeLog.
Thanks to kelvinhammond !
2018-12-02 23:24:32 +02:00
Lauri Ojansivu c9c1464c79 Merge pull request #2041 from kelvinhammond/patch-1
Updated CHANGELOG.md - Fixed 2018-20-24 dates
2018-12-02 23:22:58 +02:00
Lauri Ojansivu 30c80f167c Update translations. 2018-12-02 23:19:51 +02:00
Lauri Ojansivu af9ca9b6c4 - Build snap also on i386, armhf and arm64. Ignore if it fails.
Most likely armhf and arm64 does not build yet, I will add fixes later.

Thanks to xet7 !
2018-12-02 23:17:14 +02:00
Lauri Ojansivu 3e03f557cf - Build snap also on i386, armhf and arm64. Ignore if it fails.
Most likely armhf and arm64 does not build yet, I will add fixes later.

Thanks to xet7 !

Related #1503,
related wekan/wekan-snap#46
2018-12-02 23:12:45 +02:00
Kelvin f19dc77d2c Updated CHANGELOG.md - Fixed 2018-20-24 dates 2018-12-01 23:43:37 -05:00
hupptechnologies 1bad630641 autoamted local change 2018-11-27 12:57:03 +05:30
hupptechnologies 8a9a82fc80 Pull code 2018-11-24 16:30:12 +05:30
guillaume 745bd7e806 finish prepare for test 2018-11-23 18:04:05 +01:00
Lauri Ojansivu cdb44da71e - Fix: Message box for deleting subtask unreachable.
Thanks to hupptechnologies. Closes #1800
2018-11-23 16:37:34 +02:00
Lauri Ojansivu 064a2deaaf - Fix: Message box for deleting subtask unreachable.
Thanks to hupptechnologies !

Closes #1800
2018-11-23 16:30:18 +02:00
Lauri Ojansivu a085ed1e1b Update translations. 2018-11-22 23:41:50 +02:00
guillaume f23448be33 revert changes for patch authentication 2018-11-22 18:00:21 +01:00
Lauri Ojansivu a27c16e434 v1.78 2018-11-20 22:50:44 +02:00
Lauri Ojansivu d5be48b905 Update translations. 2018-11-20 22:49:04 +02:00
Lauri Ojansivu 7432af67c1 v1.77 2018-11-20 22:45:42 +02:00
Lauri Ojansivu 24b61cf772 v1.76 2018-11-20 12:24:38 +02:00
Lauri Ojansivu cc64ef903f - Add [LDAP_FULLNAME_FIELD](https://github.com/wekan/wekan-ldap/issues/10) to
[configs](https://github.com/wekan/wekan/commit/8e3f53021775069dba125efd4b7200d0d70a1ed1)
  and other options that were not in all config files. Thanks to alkemyst and xet7.
2018-11-20 12:19:05 +02:00
Lauri Ojansivu 8e3f530217 - Add [LDAP_FULLNAME_FIELD](https://github.com/wekan/wekan-ldap/issues/10). Thanks to alkemyst and xet7.
Closes wekan/wekan-ldap#21,
closes wekan/wekan-ldap#10
2018-11-20 12:11:37 +02:00
Lauri Ojansivu f9b272c223 - Fix: When saving Custom Layout, save also SMTP settings. Thanks to xet7. 2018-11-20 11:38:39 +02:00
Lauri Ojansivu f0232fb5cb - Fix: When saving Admin Panel / Layout, save also SMTP settings.
Thanks to xet7 !
2018-11-20 11:35:14 +02:00
Lauri Ojansivu f84bad13b4 v1.75 2018-11-20 02:45:03 +02:00
Lauri Ojansivu b72a68705c Update translations. 2018-11-20 02:42:14 +02:00
Lauri Ojansivu dd6ba152a0 Admin Panel / Layout: Hide Logo: Yes / No. This does hide Wekan logo on Login page and Board page. Thanks to xet7. 2018-11-20 02:38:00 +02:00
Lauri Ojansivu cb9ced756f - [Fix Snap database-list-backups command](https://github.com/wekan/wekan-snap/issues/26). Thanks to WaryWolf.
Closes wekan/wekan-snap#26
2018-11-19 23:28:37 +02:00
Lauri Ojansivu dbf3a48b5f Update GitHub issue template for LDAP and Snap issues elsewhere. 2018-11-19 23:11:37 +02:00
Lauri Ojansivu b5d1799f5a v1.74.1
- Full Name from LDAP server via environment variable. Thanks to alkemyst.

Closes wekan/wekan-ldap#10
2018-11-18 20:15:18 +02:00
Lauri Ojansivu d4ec0cc647 v1.74 2018-11-17 17:41:31 +02:00
Lauri Ojansivu 21a8c7cc45 v1.73 2018-11-17 16:57:12 +02:00
Lauri Ojansivu aa691b0af1 - Revert Improve authentication to [fix Login failure](https://github.com/wekan/wekan/issues/2004).
Thanks to xet7 !

Closes #2004
2018-11-17 16:50:42 +02:00
Lauri Ojansivu 7a75d82114 v1.72 2018-11-17 15:20:33 +02:00
Lauri Ojansivu 4daf69e4b6 Update translations. 2018-11-17 15:15:50 +02:00
Lauri Ojansivu 960b33c3d9 v1.71 2018-11-17 00:30:49 +02:00
Lauri Ojansivu 685eb0f22c - [Improve shell scripts](https://github.com/wekan/wekan/pull/2002). Thanks to warnerjon12. 2018-11-16 22:00:50 +02:00
Lauri Ojansivu 81a51c8dfc Merge branch 'warnerjon12-devel' into devel 2018-11-16 21:55:32 +02:00
Lauri Ojansivu 75c1dff1f8 Merge branch 'devel' of https://github.com/warnerjon12/wekan into warnerjon12-devel 2018-11-16 21:54:16 +02:00
Lauri Ojansivu cb24b85191 Improve authentication. Thanks to Akuket. 2018-11-16 21:48:53 +02:00
Lauri Ojansivu 3aec8087f7 Fix lint errors. 2018-11-16 21:32:01 +02:00
Lauri Ojansivu 39ff51ef96 Merge branch 'Akuket-devel' into devel 2018-11-16 21:28:19 +02:00
Lauri Ojansivu 033a9482fc Merge branch 'devel' of https://github.com/Akuket/wekan into Akuket-devel 2018-11-16 21:26:07 +02:00
Lauri Ojansivu 017017623f Fix typo. 2018-11-16 21:22:41 +02:00
Lauri Ojansivu 4b53a532bd Update readme for clarity. 2018-11-16 21:17:06 +02:00
Lauri Ojansivu 6df296da47 - Rename Recycle Bin to Archive.
Thanks to xet7 !
2018-11-16 21:14:10 +02:00
Lauri Ojansivu 9f5d04de27 - Add language: Danish.
Thanks to translators.
2018-11-16 21:12:06 +02:00
Lauri Ojansivu c11b91d32a - Update translations.
- Add language: Swahili / Kiswahili.

Thanks to translators.
2018-11-16 21:04:58 +02:00
Lauri Ojansivu e266902ba9 Update translations. 2018-11-13 13:39:30 +02:00
Lauri Ojansivu b919eb23ab Rename Recycle Bin to Archive.
Closes #1784,
closes #1489
2018-11-13 12:17:46 +02:00
Jonathan Warner 22a9e783c9 Revised shell scripts to check for wekan repository
The scripts used to assume that ~/repos/wekan was a local wekan repo.
They now check that the active directory is a wekan repo.
2018-11-12 05:45:51 -07:00
Jonathan Warner d4e75165dd Revised rebuild-wekan.sh to work correctly with npm
The use of sudo npm is bugged. This is a workaround patch.
Fixes issue #2001
2018-11-12 05:45:42 -07:00
Lauri Ojansivu 73daf191ae Update translations. 2018-11-11 20:20:19 +02:00
Lauri Ojansivu 329471e7e3 Fix typo. 2018-11-10 04:12:56 +02:00
Lauri Ojansivu 644e2c334f Fix IRC link ;) 2018-11-10 03:36:26 +02:00
Lauri Ojansivu 16d925e588 Reorganize readme. 2018-11-10 02:47:01 +02:00
Lauri Ojansivu 0daa6d3f7b Update readme for clarity. 2018-11-10 02:41:27 +02:00
Lauri Ojansivu e3b3e8b8c6 v1.70 2018-11-09 21:44:50 +02:00
Lauri Ojansivu ddef1ea89c Update translations. 2018-11-09 21:18:17 +02:00
Lauri Ojansivu 8ddf136928 Update changelog based on previous commits. 2018-11-09 20:54:27 +02:00
guillaume 893329d9c6 patch authentication 2018-11-09 17:46:02 +01:00
guillaume cb091c8a54 Merge https://github.com/wekan/wekan into devel 2018-11-09 14:12:17 +01:00
Lauri Ojansivu 043f9813ef Update translations. 2018-11-08 23:41:11 +02:00
Lauri Ojansivu 717891bee9 Merge remote-tracking branch 'origin/edge' into devel 2018-11-08 23:18:10 +02:00
Lauri Ojansivu 508f47f940 - Fix typo. 2018-11-08 23:17:26 +02:00
Lauri Ojansivu e4c0623cf7 Merge branch 'tugal-devel' into devel 2018-11-08 23:15:21 +02:00
Lauri Ojansivu 4cf9813449 - Some fixes to Wekan import:
- isCommentOnly and isNoComments are now optional
  - Turn off import error checking, so something is imported anyway, and import does not stop at error.
  - Now most of Sandstorm export do import to Standalone Wekan, but some of imported cards, dates etc are missing.
  - Sandstorm Import Wekan board warning messages are now translateable.

Thanks to xet7 !

Closes #1945,
closes #1616,
closes #1903
2018-11-08 22:49:08 +02:00
Lauri Ojansivu d44fb6bedd Update translations. 2018-11-07 23:20:10 +02:00
Nunes Nelson f2dd725eff custom fields upgrade -- correct 2018-11-07 18:23:28 +01:00
guillaume 3646a9c259 Logout with timer 2018-11-06 17:48:12 +01:00
guillaume 8c497efb46 patch authentication 2018-11-06 11:28:35 +01:00
Nunes Nelson a82aa87850 custom fields upgrade 2018-11-05 21:46:57 +01:00
Lauri Ojansivu 68e5909c96 - Add more options to start-wekan.bat 2018-11-04 18:47:18 +02:00
Lauri Ojansivu 4c2857b6e8 Add build scripts. 2018-11-04 18:32:08 +02:00
Lauri Ojansivu 6f2275e8cb v1.69 2018-11-03 18:18:02 +02:00
Lauri Ojansivu d42d7a89fb Update translations. 2018-11-03 18:13:41 +02:00
Lauri Ojansivu cba8b56cb5 v1.68 2018-11-03 11:00:16 +02:00
Lauri Ojansivu ece009f556 Update translations (hi). 2018-11-03 10:58:17 +02:00
Lauri Ojansivu 53ed1f1a2c v1.67 2018-11-03 10:41:33 +02:00
Lauri Ojansivu 22a09f3e7d - Hide Linked Card and Linked Board on Sandstorm, because they are only
useful when having multiple boards, and at Sandstorm
  there is only one board per grain. Thanks to ocdtrekkie and xet7.

Closes #1982
2018-11-03 10:37:22 +02:00
Lauri Ojansivu dda36f4eb3 - Hide Linked Card and Linked Board on Sandstorm, because they are only
useful when having multiple boards, and at Sandstorm
  there is only one board per grain. Thanks to ocdtrekkie and xet7.

Closes #1982
2018-11-03 10:25:31 +02:00
Lauri Ojansivu 8c6c089363 - Add Hindi language. Thanks to saurabharch. 2018-11-03 09:53:58 +02:00
Lauri Ojansivu 997a902ae4 Add hindi language. 2018-11-03 09:51:53 +02:00
Lauri Ojansivu defcfed272 v1.66 2018-10-31 22:03:30 +02:00
Lauri Ojansivu 0f1b157bda Update translations. 2018-10-31 21:59:41 +02:00
Lauri Ojansivu 7188879567 - [Fix typo about ldaps](https://github.com/wekan/wekan/pull/1980).
Documentation said to set LDAP_ENCRYPTION to true if we want to use
  ldaps, but the code in wekan-ldap does not check if it is set to true,
  but if the value equals to 'ssl' instead. Thanks to imkwx.
2018-10-31 21:58:13 +02:00
Lauri Ojansivu c753d40f6c - Fix typo about ldaps.
Documentation said to set LDAP_ENCRYPTION to true if we want to use
  ldaps, but the code in wekan-ldap does not check if it is set to true,
  but if the value equals to 'ssl' instead. Thanks to imkwx.
2018-10-31 21:57:05 +02:00
Lauri Ojansivu 706436b638 Merge pull request #1980 from imkwx/devel
Fix typo about ldaps
2018-10-31 20:29:30 +02:00
Robin BRUCKER 13aab4d410 Fix typo about ldaps
Documentation said to set LDAP_ENCRYPTION to true if we want to use
ldaps, but the code in wekan-ldap does not check if it is set to true,
but if the value equals to 'ssl' instead.
2018-10-31 18:59:16 +01:00
Lauri Ojansivu a06fd63690 Fix syntax. 2018-10-30 16:32:58 +02:00
Lauri Ojansivu 07369b9784 Update translations. 2018-10-30 00:07:35 +02:00
Lauri Ojansivu 415e28b471 - Fix typos in CHANGELOG.md, thanks to loginKing !
https://github.com/wekan/wekan/pull/1975
2018-10-30 00:05:24 +02:00
Lauri Ojansivu f62d0530ec Merge pull request #1975 from loginKing/patch-1
Update CHANGELOG.md
2018-10-30 00:03:26 +02:00
loginKing d12561aae9 Update CHANGELOG.md 2018-10-29 16:09:10 +08:00
Lauri Ojansivu d1ab38e57e - Typo fix etc. 2018-10-26 17:15:24 +03:00
Lauri Ojansivu 27bc03d452 docker-compose.yml and docker-compose-build.yml:
- Remove single quotes, because settings are quoted automatically.
- Comment out most settings that have default values.

Thanks to xet7 !
2018-10-26 17:10:14 +03:00
Lauri Ojansivu 9cff76f110 Update translations. 2018-10-26 16:55:19 +03:00
Lauri Ojansivu a5a487caf8 Merge pull request #1974 from Hillside502/patch-1
Update CHANGELOG.md
2018-10-26 15:14:20 +03:00
Hillside502 9cfef8c337 Update CHANGELOG.md
typo
2018-10-26 09:22:08 +00:00
Lauri Ojansivu 46e2679f82 v1.65 2018-10-25 18:30:25 +03:00
Lauri Ojansivu 08383ed22d Update translations (bg). 2018-10-25 18:25:10 +03:00
Lauri Ojansivu 3602d59125 This release adds the [following new features](https://github.com/wekan/wekan/pull/1967), with Apache I-CLA:
- UI: list headers: show the card count smaller in grey color below list name
- UI: lists: only output the number of cards for each swimlane

Thanks to bentiss !
2018-10-25 18:23:03 +03:00
Lauri Ojansivu c72b3a870e Merge branch 'bentiss-ui-fixes' into edge 2018-10-25 18:12:13 +03:00
Lauri Ojansivu 078bab405b Merge branch 'ui-fixes' of https://github.com/bentiss/wekan into bentiss-ui-fixes 2018-10-25 17:31:56 +03:00
Benjamin Tissoires e57269ed57 UI: lists: only output the number of cards for each swimlane 2018-10-25 16:18:02 +02:00
Benjamin Tissoires 05e0fb8fbe UI: list headers: show the card count smaller
The card count was at the same level than the title, which made
reading the list title harder. Use the quiet and small class
to put it in the following line and not make it jump out of the screen
2018-10-25 16:17:30 +02:00
Lauri Ojansivu 500ba88781 v1.64.2 2018-10-25 13:22:42 +03:00
Lauri Ojansivu 7f941840cb - Additional fix to [Impossible to connect to LDAP if UserDN contain space(s)](https://github.com/wekan/wekan/issues/1970).
Thanks to Akuket and xet7 !
2018-10-25 13:19:27 +03:00
Lauri Ojansivu b4670f12a5 v1.64.1 2018-10-25 13:16:15 +03:00
Lauri Ojansivu 2a4eb0bcc2 - Fix: [Impossible to connect to LDAP if UserDN contain space(s)](https://github.com/wekan/wekan/issues/1970).
Thanks to Akuket and xet7 !

Closes #1970
2018-10-25 13:15:15 +03:00
Lauri Ojansivu f2b64c1aaa Remove console.log 2018-10-25 13:09:25 +03:00
Lauri Ojansivu 05b9e825bb - Try to fix: Impossible to connect to LDAP if UserDN contain space(s) #1970
Thanks to Akuket and xet7 !
2018-10-25 12:38:30 +03:00
Lauri Ojansivu 187b4632e6 v1.64 2018-10-24 22:10:58 +03:00
Lauri Ojansivu ce2b8a8d1a Update translations. 2018-10-24 20:09:02 +03:00
600 changed files with 61977 additions and 7105 deletions

No files matched your search

+1 -1
View File
@@ -6,7 +6,7 @@
"browser": true
},
"parserOptions": {
"ecmaVersion": 6,
"ecmaVersion": 2017,
"sourceType": "module",
"ecmaFeatures": {
"experimentalObjectRestSpread": true
+5
View File
@@ -1,5 +1,10 @@
## Issue
Add these issues to elsewhere:
- Snap: https://github.com/wekan/wekan-snap/issues
Other Wekan issues can be added here.
**Server Setup Information**:
* Did you test in newest Wekan?:
+13 -1
View File
@@ -8,7 +8,6 @@ npm-debug.log
.vscode/
.idea/
.build/*
packages/
package-lock.json
**/parts/
**/stage
@@ -17,3 +16,16 @@ package-lock.json
snap/.snapcraft/
.idea
.DS_Store
.DS_Store?
.build*
*.browserify.js.cached
*.browserify.js.map
.build*
versions.json
.versions
.npm
.build*
._*
.Trashes
Thumbs.db
ehthumbs.db
+9 -6
View File
@@ -31,7 +31,9 @@ kenton:accounts-sandstorm
service-configuration@1.0.11
useraccounts:unstyled
useraccounts:flow-routing
salleman:accounts-oidc
wekan-ldap
wekan-accounts-cas
wekan-accounts-oidc
# Utilities
check@1.2.5
@@ -63,9 +65,7 @@ mousetrap:mousetrap
mquandalle:jquery-textcomplete
mquandalle:jquery-ui-drag-drop-sort
mquandalle:mousetrap-bindglobal
mquandalle:perfect-scrollbar
peerlibrary:blaze-components@=0.15.1
perak:markdown
templates:tabs
verron:autosize
simple:json-routes
@@ -81,11 +81,14 @@ staringatlights:fast-render
mixmax:smart-disconnect
accounts-password@1.5.0
cfs:gridfs
eluck:accounts-lockout
rzymek:fullcalendar
momentjs:moment@2.22.2
browser-policy-framing
mquandalle:moment
msavin:usercache
wekan:wekan-ldap
wekan:accounts-cas
wekan-scrollbar
mquandalle:perfect-scrollbar
mdg:meteor-apm-agent
meteorhacks:unblock
lucasantoniassi:accounts-lockout
wekan-markdown
+9 -6
View File
@@ -60,7 +60,6 @@ ecmascript-runtime@0.5.0
ecmascript-runtime-client@0.5.0
ecmascript-runtime-server@0.5.0
ejson@1.1.0
eluck:accounts-lockout@0.9.0
email@1.2.3
es5-shim@4.6.15
fastclick@1.0.13
@@ -82,8 +81,10 @@ launch-screen@1.1.1
livedata@1.0.18
localstorage@1.2.0
logging@1.1.19
lucasantoniassi:accounts-lockout@1.0.0
matb33:collection-hooks@0.8.4
matteodem:easy-search@1.6.4
mdg:meteor-apm-agent@3.1.2
mdg:validation-error@0.5.1
meteor@1.8.2
meteor-base@1.2.0
@@ -93,6 +94,7 @@ meteorhacks:collection-utils@1.2.0
meteorhacks:meteorx@1.4.1
meteorhacks:picker@1.0.3
meteorhacks:subs-manager@1.6.4
meteorhacks:unblock@1.1.0
meteorspark:util@0.2.0
minifier-css@1.2.16
minifier-js@2.2.2
@@ -130,7 +132,6 @@ peerlibrary:base-component@0.16.0
peerlibrary:blaze-components@0.15.1
peerlibrary:computed-field@0.7.0
peerlibrary:reactive-field@0.3.0
perak:markdown@1.0.5
promise@0.10.0
raix:eventemitter@0.1.3
raix:handlebar-helpers@0.2.5
@@ -143,8 +144,6 @@ reload@1.1.11
retry@1.0.9
routepolicy@1.0.12
rzymek:fullcalendar@3.8.0
salleman:accounts-oidc@1.0.9
salleman:oidc@1.0.9
service-configuration@1.0.11
session@1.1.7
sha@1.0.9
@@ -179,7 +178,11 @@ useraccounts:unstyled@1.14.2
verron:autosize@3.0.8
webapp@1.4.0
webapp-hashing@1.0.9
wekan:accounts-cas@0.1.0
wekan:wekan-ldap@0.0.2
wekan-accounts-oidc@1.0.10
wekan-markdown@1.0.7
wekan-oidc@1.0.12
wekan-scrollbar@3.1.3
wekan-accounts-cas@0.1.0
wekan-ldap@0.0.2
yasaricli:slugify@0.0.7
zimme:active-route@2.3.2
+1 -1
View File
@@ -39,7 +39,7 @@ host = https://www.transifex.com
# tap:i18n requires us to use `-` separator in the language identifiers whereas
# Transifex uses a `_` separator, without an option to customize it on one side
# or the other, so we need to do a Manual mapping.
lang_map = bg_BG:bg, en_GB:en-GB, es_AR:es-AR, el_GR:el, fi_FI:fi, hu_HU:hu, id_ID:id, mn_MN:mn, no:nb, lv_LV:lv, pt_BR:pt-BR, ro_RO:ro, zh_CN:zh-CN, zh_TW:zh-TW
lang_map = bg_BG:bg, en_GB:en-GB, es_AR:es-AR, el_GR:el, fi_FI:fi, hu_HU:hu, id_ID:id, mn_MN:mn, no:nb, lv_LV:lv, pt_BR:pt-BR, ro_RO:ro, zh_CN:zh-CN, zh_TW:zh-TW, zh_HK:zh-HK
[wekan.application]
file_filter = i18n/<lang>.i18n.json
+1433 -12
View File
File diff suppressed because it is too large. Load diff
+71 -76
View File
@@ -1,75 +1,12 @@
FROM debian:buster-slim
FROM ubuntu:disco
LABEL maintainer="wekan"
# Declare Arguments
ARG NODE_VERSION
ARG METEOR_RELEASE
ARG METEOR_EDGE
ARG USE_EDGE
ARG NPM_VERSION
ARG FIBERS_VERSION
ARG ARCHITECTURE
ARG SRC_PATH
ARG WITH_API
ARG MATOMO_ADDRESS
ARG MATOMO_SITE_ID
ARG MATOMO_DO_NOT_TRACK
ARG MATOMO_WITH_USERNAME
ARG BROWSER_POLICY_ENABLED
ARG TRUSTED_URL
ARG WEBHOOKS_ATTRIBUTES
ARG OAUTH2_ENABLED
ARG OAUTH2_CLIENT_ID
ARG OAUTH2_SECRET
ARG OAUTH2_SERVER_URL
ARG OAUTH2_AUTH_ENDPOINT
ARG OAUTH2_USERINFO_ENDPOINT
ARG OAUTH2_TOKEN_ENDPOINT
ARG LDAP_ENABLE
ARG LDAP_PORT
ARG LDAP_HOST
ARG LDAP_BASEDN
ARG LDAP_LOGIN_FALLBACK
ARG LDAP_RECONNECT
ARG LDAP_TIMEOUT
ARG LDAP_IDLE_TIMEOUT
ARG LDAP_CONNECT_TIMEOUT
ARG LDAP_AUTHENTIFICATION
ARG LDAP_AUTHENTIFICATION_USERDN
ARG LDAP_AUTHENTIFICATION_PASSWORD
ARG LDAP_LOG_ENABLED
ARG LDAP_BACKGROUND_SYNC
ARG LDAP_BACKGROUND_SYNC_INTERVAL
ARG LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED
ARG LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS
ARG LDAP_ENCRYPTION
ARG LDAP_CA_CERT
ARG LDAP_REJECT_UNAUTHORIZED
ARG LDAP_USER_SEARCH_FILTER
ARG LDAP_USER_SEARCH_SCOPE
ARG LDAP_USER_SEARCH_FIELD
ARG LDAP_SEARCH_PAGE_SIZE
ARG LDAP_SEARCH_SIZE_LIMIT
ARG LDAP_GROUP_FILTER_ENABLE
ARG LDAP_GROUP_FILTER_OBJECTCLASS
ARG LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE
ARG LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE
ARG LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT
ARG LDAP_GROUP_FILTER_GROUP_NAME
ARG LDAP_UNIQUE_IDENTIFIER_FIELD
ARG LDAP_UTF8_NAMES_SLUGIFY
ARG LDAP_USERNAME_FIELD
ARG LDAP_MERGE_EXISTING_USERS
ARG LDAP_SYNC_USER_DATA
ARG LDAP_SYNC_USER_DATA_FIELDMAP
ARG LDAP_SYNC_GROUP_ROLES
ARG LDAP_DEFAULT_DOMAIN
# Set the environment variables (defaults where required)
# DOES NOT WORK: paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303
# ENV BUILD_DEPS="paxctl"
ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential python git ca-certificates gcc-7" \
NODE_VERSION=v8.12.0 \
ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential python3 python3-pip git ca-certificates gcc-8" \
DEBUG=false \
NODE_VERSION=v8.16.0 \
METEOR_RELEASE=1.6.0.1 \
USE_EDGE=false \
METEOR_EDGE=1.5-beta.17 \
@@ -78,6 +15,13 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential pyth
ARCHITECTURE=linux-x64 \
SRC_PATH=./ \
WITH_API=true \
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 \
ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60 \
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15 \
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 \
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 \
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 \
EMAIL_NOTIFICATION_TIMEOUT=30000 \
MATOMO_ADDRESS="" \
MATOMO_SITE_ID="" \
MATOMO_DO_NOT_TRACK=true \
@@ -86,12 +30,19 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential pyth
TRUSTED_URL="" \
WEBHOOKS_ATTRIBUTES="" \
OAUTH2_ENABLED=false \
OAUTH2_LOGIN_STYLE=redirect \
OAUTH2_CLIENT_ID="" \
OAUTH2_SECRET="" \
OAUTH2_SERVER_URL="" \
OAUTH2_AUTH_ENDPOINT="" \
OAUTH2_USERINFO_ENDPOINT="" \
OAUTH2_TOKEN_ENDPOINT="" \
OAUTH2_ID_MAP="" \
OAUTH2_USERNAME_MAP="" \
OAUTH2_FULLNAME_MAP="" \
OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[] \
OAUTH2_REQUEST_PERMISSIONS='openid profiles email' \
OAUTH2_EMAIL_MAP="" \
LDAP_ENABLE=false \
LDAP_PORT=389 \
LDAP_HOST="" \
@@ -112,6 +63,7 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential pyth
LDAP_ENCRYPTION=false \
LDAP_CA_CERT="" \
LDAP_REJECT_UNAUTHORIZED=false \
LDAP_USER_AUTHENTICATION=false \
LDAP_USER_SEARCH_FILTER="" \
LDAP_USER_SEARCH_SCOPE="" \
LDAP_USER_SEARCH_FIELD="" \
@@ -126,11 +78,30 @@ ENV BUILD_DEPS="apt-utils bsdtar gnupg gosu wget curl bzip2 build-essential pyth
LDAP_UNIQUE_IDENTIFIER_FIELD="" \
LDAP_UTF8_NAMES_SLUGIFY=true \
LDAP_USERNAME_FIELD="" \
LDAP_FULLNAME_FIELD="" \
LDAP_MERGE_EXISTING_USERS=false \
LDAP_EMAIL_FIELD="" \
LDAP_EMAIL_MATCH_ENABLE=false \
LDAP_EMAIL_MATCH_REQUIRE=false \
LDAP_EMAIL_MATCH_VERIFIED=false \
LDAP_SYNC_USER_DATA=false \
LDAP_SYNC_USER_DATA_FIELDMAP="" \
LDAP_SYNC_GROUP_ROLES="" \
LDAP_DEFAULT_DOMAIN=""
LDAP_DEFAULT_DOMAIN="" \
LDAP_SYNC_ADMIN_STATUS="" \
LDAP_SYNC_ADMIN_GROUPS="" \
HEADER_LOGIN_ID="" \
HEADER_LOGIN_FIRSTNAME="" \
HEADER_LOGIN_LASTNAME="" \
HEADER_LOGIN_EMAIL="" \
LOGOUT_WITH_TIMER=false \
LOGOUT_IN="" \
LOGOUT_ON_HOURS="" \
LOGOUT_ON_MINUTES="" \
CORS="" \
CORS_ALLOW_HEADERS="" \
CORS_EXPOSE_HEADERS="" \
DEFAULT_AUTHENTICATION_METHOD=""
# Copy the app to the image
COPY ${SRC_PATH} /home/wekan/app
@@ -142,6 +113,7 @@ RUN \
\
# OS dependencies
apt-get update -y && apt-get install -y --no-install-recommends ${BUILD_DEPS} && \
pip3 install -U pip setuptools wheel && \
\
# Meteor installer doesn't work with the default tar binary, so using bsdtar while installing.
# https://github.com/coreos/bugs/issues/1095#issuecomment-350574389
@@ -159,7 +131,7 @@ RUN \
# Also see beginning of wekan/server/authentication.js
# import Fiber from "fibers";
# Fiber.poolSize = 1e9;
# OLD: Download node version 8.12.0 prerelease that has fix included, => Official 8.12.0 has been released
# OLD: Download node version 8.12.0 prerelease that has fix included, => Official 8.12.0 has been released
# Description at https://releases.wekan.team/node.txt
#wget https://releases.wekan.team/node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz && \
#echo "1ed54adb8497ad8967075a0b5d03dd5d0a502be43d4a4d84e5af489c613d7795 node-v8.12.0-linux-x64.tar.gz" >> SHASUMS256.txt.asc && \
@@ -225,23 +197,43 @@ RUN \
fi; \
\
# Get additional packages
mkdir -p /home/wekan/app/packages && \
chown wekan:wekan --recursive /home/wekan && \
cd /home/wekan/app/packages && \
gosu wekan:wekan git clone --depth 1 -b master git://github.com/wekan/flow-router.git kadira-flow-router && \
gosu wekan:wekan git clone --depth 1 -b master git://github.com/meteor-useraccounts/core.git meteor-useraccounts-core && \
gosu wekan:wekan git clone --depth 1 -b master git://github.com/wekan/meteor-accounts-cas.git && \
gosu wekan:wekan git clone --depth 1 -b master git://github.com/wekan/wekan-ldap.git && \
#mkdir -p /home/wekan/app/packages && \
#chown wekan:wekan --recursive /home/wekan && \
# REPOS BELOW ARE INCLUDED TO WEKAN REPO
#cd /home/wekan/app/packages && \
#gosu wekan:wekan git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router && \
#gosu wekan:wekan git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core && \
#gosu wekan:wekan git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-cas.git && \
#gosu wekan:wekan git clone --depth 1 -b master https://github.com/wekan/wekan-ldap.git && \
#gosu wekan:wekan git clone --depth 1 -b master https://github.com/wekan/wekan-scrollbar.git && \
#gosu wekan:wekan git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-oidc.git && \
#gosu wekan:wekan git clone --depth 1 -b master --recurse-submodules https://github.com/wekan/markdown.git && \
#gosu wekan:wekan mv meteor-accounts-oidc/packages/switch_accounts-oidc wekan-accounts-oidc && \
#gosu wekan:wekan mv meteor-accounts-oidc/packages/switch_oidc wekan-oidc && \
#gosu wekan:wekan rm -rf meteor-accounts-oidc && \
sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' /home/wekan/app/packages/meteor-useraccounts-core/package.js && \
cd /home/wekan/.meteor && \
gosu wekan:wekan /home/wekan/.meteor/meteor -- help; \
\
# extract the OpenAPI specification
npm install -g api2html@0.3.3 && \
mkdir -p /home/wekan/python && \
chown wekan:wekan --recursive /home/wekan/python && \
cd /home/wekan/python && \
gosu wekan:wekan git clone --depth 1 -b master https://github.com/Kronuz/esprima-python && \
cd /home/wekan/python/esprima-python && \
python3 setup.py install --record files.txt && \
cd /home/wekan/app &&\
gosu wekan:wekan mkdir -p ./public/api && \
gosu wekan:wekan python3 ./openapi/generate_openapi.py --release $(git describe --tags --abbrev=0) > ./public/api/wekan.yml && \
gosu wekan:wekan /opt/nodejs/bin/api2html -c ./public/logo-header.png -o ./public/api/wekan.html ./public/api/wekan.yml; \
# Build app
cd /home/wekan/app && \
gosu wekan:wekan /home/wekan/.meteor/meteor add standard-minifier-js && \
gosu wekan:wekan /home/wekan/.meteor/meteor npm install && \
gosu wekan:wekan /home/wekan/.meteor/meteor build --directory /home/wekan/app_build && \
cp /home/wekan/app/fix-download-unicode/cfs_access-point.txt /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
rm /home/wekan/app_build/bundle/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs && \
chown wekan:wekan /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac
@@ -260,10 +252,13 @@ RUN \
# Cleanup
apt-get remove --purge -y ${BUILD_DEPS} && \
apt-get autoremove -y && \
npm uninstall -g api2html &&\
rm -R /var/lib/apt/lists/* && \
rm -R /home/wekan/.meteor && \
rm -R /home/wekan/app && \
rm -R /home/wekan/app_build && \
cat /home/wekan/python/esprima-python/files.txt | xargs rm -R && \
rm -R /home/wekan/python && \
rm /home/wekan/install_meteor.sh
ENV PORT=8080
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2018 The Wekan Team
Copyright (c) 2014-2019 The Wekan Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+104 -62
View File
@@ -1,4 +1,103 @@
# Wekan
# Wekan - Open Source kanban
[![Contributors](https://img.shields.io/github/contributors/wekan/wekan.svg "Contributors")](https://github.com/wekan/wekan/graphs/contributors)
[![Docker Repository on Quay](https://quay.io/repository/wekan/wekan/status "Docker Repository on Quay")](https://quay.io/repository/wekan/wekan)
[![Docker Hub container status](https://img.shields.io/docker/build/wekanteam/wekan.svg "Docker Hub container status")](https://hub.docker.com/r/wekanteam/wekan)
[![Docker Hub pulls](https://img.shields.io/docker/pulls/wekanteam/wekan.svg "Docker Hub Pulls")](https://hub.docker.com/r/wekanteam/wekan)
[![Wekan Build Status][travis_badge]][travis_status]
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/02137ecec4e34c5aa303f57637196a93 "Codacy Badge")](https://www.codacy.com/app/xet7/wekan?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=wekan/wekan&amp;utm_campaign=Badge_Grade)
[![Code Climate](https://codeclimate.com/github/wekan/wekan/badges/gpa.svg "Code Climate")](https://codeclimate.com/github/wekan/wekan)
[![Project Dependencies](https://david-dm.org/wekan/wekan.svg "Project Dependencies")](https://david-dm.org/wekan/wekan)
[![Code analysis at Open Hub](https://img.shields.io/badge/code%20analysis-at%20Open%20Hub-brightgreen.svg "Code analysis at Open Hub")](https://www.openhub.net/p/wekan)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwekan%2Fwekan.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fwekan%2Fwekan?ref=badge_shield)
## [Translate Wekan at Transifex](https://transifex.com/wekan/wekan)
Translations to non-English languages are accepted only at [Transifex](https://transifex.com/wekan/wekan) using webbrowser.
New English strings of new features can be added as PRs to edge branch file wekan/i18n/en.i18n.json .
## [Wekan feature requests and bugs](https://github.com/wekan/wekan/issues)
Please add most of your questions as GitHub issue: [Wekan feature requests and bugs](https://github.com/wekan/wekan/issues).
It's better than at chat where details get lost when chat scrolls up.
## Chat
[![Wekan Chat][vanila_badge]][wekan_chat] - Most Wekan community and developers are here. Works on webbrowser
and PWA app that can be added as icon on Android and bookmark on iOS, used like native app.
[Wekan IRC FAQ](https://github.com/wekan/wekan/wiki/IRC-FAQ)
## FAQ
**NOTE**:
- Please read the [FAQ](https://github.com/wekan/wekan/wiki/FAQ) first
- Please don't feed the trolls and spammers that are mentioned in the FAQ :)
## About Wekan
Wekan is an completely [Open Source][open_source] and [Free software][free_software]
collaborative kanban board application with MIT license.
Whether you’re maintaining a personal todo list, planning your holidays with some friends,
or working in a team on your next revolutionary idea, Kanban boards are an unbeatable tool
to keep your things organized. They give you a visual overview of the current state of your project,
and make you productive by allowing you to focus on the few items that matter the most.
Since Wekan is a free software, you don’t have to trust us with your data and can
install Wekan on your own computer or server. In fact we encourage you to do
that by providing one-click installation on various platforms.
- Wekan is used in [most countries of the world](https://snapcraft.io/wekan).
- Wekan largest user has 13k users using Wekan in their company.
- Wekan has been [translated](https://transifex.com/wekan/wekan) to about 50 languages.
- [Features][features]: Wekan has real-time user interface.
- [Platforms][platforms]: Wekan supports many platforms.
Wekan is critical part of new platforms Wekan is currently being integrated to.
- [Integrations][integrations]: Current possible integrations and future plans.
## Requirements
- 64bit: Linux [Snap](https://github.com/wekan/wekan-snap/wiki/Install) or [Sandstorm](https://sandstorm.io) /
[Mac](https://github.com/wekan/wekan/wiki/Mac) / [Windows](https://github.com/wekan/wekan/wiki/Install-Wekan-from-source-on-Windows).
[More Platforms](https://github.com/wekan/wekan/wiki/Platforms). [ARM progress](https://github.com/wekan/wekan/issues/1053#issuecomment-410919264).
- 1 GB RAM minimum free for Wekan. Production server should have minimum total 4 GB RAM.
For thousands of users, for example with [Docker](https://github.com/wekan/wekan/blob/devel/docker-compose.yml): 3 frontend servers,
each having 2 CPU and 2 wekan-app containers. One backend wekan-db server with many CPUs.
- Enough disk space and alerts about low disk space. If you run out disk space, MongoDB database gets corrupted.
- SECURITY: Updating to newest Wekan version very often. Please check you do not have automatic updates of Sandstorm or Snap turned off.
Old versions have security issues because of old versions Node.js etc. Only newest Wekan is supported.
Wekan on Sandstorm is not usually affected by any Standalone Wekan (Snap/Docker/Source) security issues.
- [Reporting all new bugs immediately](https://github.com/wekan/wekan/issues).
New features and fixes are added to Wekan [many times a day](https://github.com/wekan/wekan/blob/devel/CHANGELOG.md).
- [Backups](https://github.com/wekan/wekan/wiki/Backup) of Wekan database once a day miminum.
Bugs, updates, users deleting list or card, harddrive full, harddrive crash etc can eat your data. There is no undo yet.
Some bug can cause Wekan board to not load at all, requiring manual fixing of database content.
## Roadmap
[Roadmap Milestones](https://github.com/wekan/wekan/milestones)
[Developer Documentation][dev_docs]
- There is many companies and individuals contributing code to Wekan, to add features and bugfixes
[many times a day](https://github.com/wekan/wekan/blob/devel/CHANGELOG.md).
- [Please add Add new Feature Requests and Bug Reports immediately](https://github.com/wekan/wekan/issues).
- [Commercial Support](https://wekan.team).
- [Bounties](https://wekan.team/bounties/index.html).
We also welcome sponsors for features and bugfixes.
By working directly with Wekan you get the benefit of active maintenance and new features added by growing Wekan developer community.
## Demo
[Wekan demo][roadmap_wefork]
## Screenshot
[More screenshots at Features page](https://github.com/wekan/wekan/wiki/Features)
[![Screenshot of Wekan][screenshot_wefork]][roadmap_wefork]
## Stable
@@ -11,66 +110,6 @@
- edge branch. All new fixes and features are added to here first. [Testing Edge](https://github.com/wekan/wekan-snap/wiki/Snap-Developer-Docs).
[![Translate Wekan at Transifex](https://img.shields.io/badge/Translate%20Wekan-at%20Transifex-brightgreen.svg "Freenode IRC")](https://transifex.com/wekan/wekan)
[![Wekan Vanila Chat][vanila_badge]][vanila_chat]
[![IRC #wekan](https://img.shields.io/badge/IRC%20%23wekan-on%20Freenode-brightgreen.svg "Freenode IRC")](http://webchat.freenode.net?channels=%23wekan&uio=d4)
[![Contributors](https://img.shields.io/github/contributors/wekan/wekan.svg "Contributors")](https://github.com/wekan/wekan/graphs/contributors)
[![Docker Repository on Quay](https://quay.io/repository/wekan/wekan/status "Docker Repository on Quay")](https://quay.io/repository/wekan/wekan)
[![Docker Hub container status](https://img.shields.io/docker/build/wekanteam/wekan.svg "Docker Hub container status")](https://hub.docker.com/r/wekanteam/wekan)
[![Docker Hub pulls](https://img.shields.io/docker/pulls/wekanteam/wekan.svg "Docker Hub Pulls")](https://hub.docker.com/r/wekanteam/wekan)
[![Wekan Build Status][travis_badge]][travis_status]
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/02137ecec4e34c5aa303f57637196a93 "Codacy Badge")](https://www.codacy.com/app/xet7/wekan?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=wekan/wekan&amp;utm_campaign=Badge_Grade)
[![Code Climate](https://codeclimate.com/github/wekan/wekan/badges/gpa.svg "Code Climate")](https://codeclimate.com/github/wekan/wekan)
[![Project Dependencies](https://david-dm.org/wekan/wekan.svg "Project Dependencies")](https://david-dm.org/wekan/wekan)
[![Code analysis at Open Hub](https://img.shields.io/badge/code%20analysis-at%20Open%20Hub-brightgreen.svg "Code analysis at Open Hub")](https://www.openhub.net/p/wekan)
**NOTE**:
- Please read the [FAQ](https://github.com/wekan/wekan/wiki/FAQ) first
- Please don't feed the trolls and spammers that are mentioned in the FAQ :)
Wekan is an completely [Open Source][open_source] and [Free software][free_software]
collaborative kanban board application with MIT license.
Whether you’re maintaining a personal todo list, planning your holidays with some friends, or working in a team on your next revolutionary idea, Kanban boards are an unbeatable tool to keep your things organized. They give you a visual overview of the current state of your project, and make you productive by allowing you to focus on the few items that matter the most.
Since Wekan is a free software, you don’t have to trust us with your data and can
install Wekan on your own computer or server. In fact we encourage you to do
that by providing one-click installation on various platforms.
- [Features][features]: Wekan has real-time user interface. Not all features are implemented, yet.
- [Platforms][platforms]: Wekan supports many platforms and plan is to add more. This will be the first place to look if you want to **install** it, test out and learn more in depth.
- [Integrations][integrations]: Current possible integrations and future plans.
- [Team](https://github.com/wekan/wekan/wiki/Team): The people who spends their time and make wekan into what it is right now.
## Roadmap
[Roadmap](https://github.com/wekan/wekan/wiki/Roadmap)
Upcoming Wekan App Development Platform will make possible many use cases. If you don't find your feature or integration in
GitHub issues and [Features][features] or [Integrations][integrations] page at wiki, please add them.
We are very welcoming to new developers and teams to submit new pull requests to devel branch to make this Wekan App Development Platform possible faster. Please see [Developer Documentation][dev_docs] to get started.
We also welcome sponsors for features and bugfixes. By working directly with Wekan you get the benefit of active maintenance and new features added by growing Wekan developer community.
Actual work happens at [Wekan GitHub issues][wekan_issues].
See [Development links on Wekan wiki](https://github.com/wekan/wekan/wiki#Development) bottom of the page for more info.
If you want to know what is going on exactly this moment, you can check out the [project page](https://github.com/wekan/wekan/projects/2).
## Demo
[Wekan demo][roadmap_wefork]
## Screenshot
[More screenshots at Features page](https://github.com/wekan/wekan/wiki/Features)
[![Screenshot of Wekan][screenshot_wefork]][roadmap_wefork]
## License
Wekan is released under the very permissive [MIT license](LICENSE), and made
@@ -94,4 +133,7 @@ with [Meteor](https://www.meteor.com).
[open_source]: https://en.wikipedia.org/wiki/Open-source_software
[free_software]: https://en.wikipedia.org/wiki/Free_software
[vanila_badge]: https://vanila.io/img/join-chat-button2.png
[vanila_chat]: https://chat.vanila.io/channel/wekan
[wekan_chat]: https://community.vanila.io/wekan
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwekan%2Fwekan.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fwekan%2Fwekan?ref=badge_large)
+9
View File
@@ -0,0 +1,9 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v2.78.0"
files:
userUploads:
- README.md
userScripts:
build: stacksmith/user-scripts/build.sh
boot: stacksmith/user-scripts/boot.sh
run: stacksmith/user-scripts/run.sh
+14 -1
View File
@@ -99,6 +99,9 @@ template(name="boardActivities")
else
| {{{_ 'activity-added' memberLink cardLink}}}.
if($eq activityType 'moveCardBoard')
| {{{_ 'activity-moved' cardLink oldBoardName boardName}}}.
if($eq activityType 'moveCard')
| {{{_ 'activity-moved' cardLink oldList.title list.title}}}.
@@ -114,6 +117,12 @@ template(name="boardActivities")
if($eq activityType 'removedLabel')
| {{{_ 'activity-removed-label' lastLabel cardLink}}}.
if($eq activityType 'setCustomField')
| {{{_ 'activity-set-customfield' lastCustomField lastCustomFieldValue cardLink}}}.
if($eq activityType 'unsetCustomField')
| {{{_ 'activity-unset-customfield' lastCustomField cardLink}}}.
if($eq activityType 'unjoinMember')
if($eq user._id member._id)
| {{{_ 'activity-unjoined' cardLink}}}.
@@ -129,7 +138,7 @@ template(name="cardActivities")
p.activity-desc
+memberName(user=user)
if($eq activityType 'createCard')
| {{_ 'activity-added' cardLabel list.title}}.
| {{_ 'activity-added' cardLabel listName}}.
if($eq activityType 'importCard')
| {{{_ 'activity-imported' cardLabel list.title sourceLink}}}.
if($eq activityType 'joinMember')
@@ -170,6 +179,10 @@ template(name="cardActivities")
| {{_ 'activity-sent' cardLabel boardLabel}}.
if($eq activityType 'moveCard')
| {{_ 'activity-moved' cardLabel oldList.title list.title}}.
if($eq activityType 'moveCardBoard')
| {{{_ 'activity-moved' cardLink oldBoardName boardName}}}.
if($eq activityType 'addAttachment')
| {{{_ 'activity-attached' attachmentLink cardLabel}}}.
if attachment.isImage
@@ -74,6 +74,8 @@ BlazeComponent.extendComponent({
lastLabel(){
const lastLabelId = this.currentData().labelId;
if (!lastLabelId)
return null;
const lastLabel = Boards.findOne(Session.get('currentBoard')).getLabelById(lastLabelId);
if(lastLabel.name === undefined || lastLabel.name === ''){
return lastLabel.color;
@@ -82,6 +84,28 @@ BlazeComponent.extendComponent({
}
},
lastCustomField(){
const lastCustomField = CustomFields.findOne(this.currentData().customFieldId);
if (!lastCustomField)
return null;
return lastCustomField.name;
},
lastCustomFieldValue(){
const lastCustomField = CustomFields.findOne(this.currentData().customFieldId);
if (!lastCustomField)
return null;
const value = this.currentData().value;
if (lastCustomField.settings.dropdownItems && lastCustomField.settings.dropdownItems.length > 0) {
const dropDownValue = _.find(lastCustomField.settings.dropdownItems, (item) => {
return item._id === value;
});
if (dropDownValue)
return dropDownValue.name;
}
return value;
},
listLabel() {
return this.currentData().list().title;
},
@@ -117,6 +141,8 @@ BlazeComponent.extendComponent({
customField() {
const customField = this.currentData().customField();
if (!customField)
return null;
return customField.name;
},
-6
View File
@@ -1,9 +1,3 @@
Template.boardListHeaderBar.events({
'click .js-open-archived-board'() {
Modal.open('archivedBoards');
},
});
BlazeComponent.extendComponent({
onCreated() {
this.subscribe('archivedBoards');
+14 -8
View File
@@ -20,16 +20,22 @@ template(name="boardBody")
class="{{#if draggingActive.get}}is-dragging-active{{/if}}")
if showOverlay.get
.board-overlay
if isViewSwimlanes
if currentBoard.isTemplatesBoard
each currentBoard.swimlanes
+swimlane(this)
if isViewLists
+listsGroup
if isViewCalendar
else if isViewSwimlanes
each currentBoard.swimlanes
+swimlane(this)
else if isViewLists
+listsGroup(currentBoard)
else if isViewCalendar
+calendarView
else
+listsGroup(currentBoard)
template(name="calendarView")
.calendar-view.swimlane
if currentCard
+cardDetails(currentCard)
+fullcalendar(calendarOptions)
if isViewCalendar
.calendar-view.swimlane
if currentCard
+cardDetails(currentCard)
+fullcalendar(calendarOptions)
+113 -9
View File
@@ -1,5 +1,6 @@
const subManager = new SubsManager();
const { calculateIndex, enableClickOnTouch } = Utils;
const swimlaneWhileSortingHeight = 150;
BlazeComponent.extendComponent({
onCreated() {
@@ -13,7 +14,7 @@ BlazeComponent.extendComponent({
const currentBoardId = Session.get('currentBoard');
if (!currentBoardId)
return;
const handle = subManager.subscribe('board', currentBoardId);
const handle = subManager.subscribe('board', currentBoardId, false);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
this.isBoardReady.set(handle.ready());
@@ -35,6 +36,37 @@ BlazeComponent.extendComponent({
this._isDragging = false;
// Used to set the overlay
this.mouseHasEnterCardDetails = false;
// fix swimlanes sort field if there are null values
const currentBoardData = Boards.findOne(Session.get('currentBoard'));
const nullSortSwimlanes = currentBoardData.nullSortSwimlanes();
if (nullSortSwimlanes.count() > 0) {
const swimlanes = currentBoardData.swimlanes();
let count = 0;
swimlanes.forEach((s) => {
Swimlanes.update(s._id, {
$set: {
sort: count,
},
});
count += 1;
});
}
// fix lists sort field if there are null values
const nullSortLists = currentBoardData.nullSortLists();
if (nullSortLists.count() > 0) {
const lists = currentBoardData.lists();
let count = 0;
lists.forEach((l) => {
Lists.update(l._id, {
$set: {
sort: count,
},
});
count += 1;
});
}
},
onRendered() {
const boardComponent = this;
@@ -43,21 +75,64 @@ BlazeComponent.extendComponent({
$swimlanesDom.sortable({
tolerance: 'pointer',
appendTo: '.board-canvas',
helper: 'clone',
helper(evt, item) {
const helper = $(`<div class="swimlane"
style="flex-direction: column;
height: ${swimlaneWhileSortingHeight}px;
width: $(boardComponent.width)px;
overflow: hidden;"/>`);
helper.append(item.clone());
// Also grab the list of lists of cards
const list = item.next();
helper.append(list.clone());
return helper;
},
handle: '.js-swimlane-header',
items: '.js-swimlane:not(.placeholder)',
items: '.swimlane:not(.placeholder)',
placeholder: 'swimlane placeholder',
distance: 7,
start(evt, ui) {
const listDom = ui.placeholder.next('.js-swimlane');
const parentOffset = ui.item.parent().offset();
ui.placeholder.height(ui.helper.height());
EscapeActions.executeUpTo('popup-close');
listDom.addClass('moving-swimlane');
boardComponent.setIsDragging(true);
ui.placeholder.insertAfter(ui.placeholder.next());
boardComponent.origPlaceholderIndex = ui.placeholder.index();
// resize all swimlanes + headers to be a total of 150 px per row
// this could be achieved by setIsDragging(true) but we want immediate
// result
ui.item.siblings('.js-swimlane').css('height', `${swimlaneWhileSortingHeight - 26}px`);
// set the new scroll height after the resize and insertion of
// the placeholder. We want the element under the cursor to stay
// at the same place on the screen
ui.item.parent().get(0).scrollTop = ui.placeholder.get(0).offsetTop + parentOffset.top - evt.pageY;
},
beforeStop(evt, ui) {
const parentOffset = ui.item.parent().offset();
const siblings = ui.item.siblings('.js-swimlane');
siblings.css('height', '');
// compute the new scroll height after the resize and removal of
// the placeholder
const scrollTop = ui.placeholder.get(0).offsetTop + parentOffset.top - evt.pageY;
// then reset the original view of the swimlane
siblings.removeClass('moving-swimlane');
// and apply the computed scrollheight
ui.item.parent().get(0).scrollTop = scrollTop;
},
stop(evt, ui) {
// To attribute the new index number, we need to get the DOM element
// of the previous and the following card -- if any.
const prevSwimlaneDom = ui.item.prev('.js-swimlane').get(0);
const nextSwimlaneDom = ui.item.next('.js-swimlane').get(0);
const prevSwimlaneDom = ui.item.prevAll('.js-swimlane').get(0);
const nextSwimlaneDom = ui.item.nextAll('.js-swimlane').get(0);
const sortIndex = calculateIndex(prevSwimlaneDom, nextSwimlaneDom, 1);
$swimlanesDom.sortable('cancel');
@@ -72,6 +147,30 @@ BlazeComponent.extendComponent({
boardComponent.setIsDragging(false);
},
sort(evt, ui) {
// get the mouse position in the sortable
const parentOffset = ui.item.parent().offset();
const cursorY = evt.pageY - parentOffset.top + ui.item.parent().scrollTop();
// compute the intended index of the placeholder (we need to skip the
// slots between the headers and the list of cards)
const newplaceholderIndex = Math.floor(cursorY / swimlaneWhileSortingHeight);
let destPlaceholderIndex = (newplaceholderIndex + 1) * 2;
// if we are scrolling far away from the bottom of the list
if (destPlaceholderIndex >= ui.item.parent().get(0).childElementCount) {
destPlaceholderIndex = ui.item.parent().get(0).childElementCount - 1;
}
// update the placeholder position in the DOM tree
if (destPlaceholderIndex !== ui.placeholder.index()) {
if (destPlaceholderIndex < boardComponent.origPlaceholderIndex) {
ui.placeholder.insertBefore(ui.placeholder.siblings().slice(destPlaceholderIndex - 2, destPlaceholderIndex - 1));
} else {
ui.placeholder.insertAfter(ui.placeholder.siblings().slice(destPlaceholderIndex - 1, destPlaceholderIndex));
}
}
},
});
// ugly touch event hotfix
@@ -92,19 +191,19 @@ BlazeComponent.extendComponent({
isViewSwimlanes() {
const currentUser = Meteor.user();
if (!currentUser) return false;
return (currentUser.profile.boardView === 'board-view-swimlanes');
return ((currentUser.profile || {}).boardView === 'board-view-swimlanes');
},
isViewLists() {
const currentUser = Meteor.user();
if (!currentUser) return true;
return (currentUser.profile.boardView === 'board-view-lists');
return ((currentUser.profile || {}).boardView === 'board-view-lists');
},
isViewCalendar() {
const currentUser = Meteor.user();
if (!currentUser) return true;
return (currentUser.profile.boardView === 'board-view-cal');
if (!currentUser) return false;
return ((currentUser.profile || {}).boardView === 'board-view-cal');
},
openNewListForm() {
@@ -233,4 +332,9 @@ BlazeComponent.extendComponent({
},
};
},
isViewCalendar() {
const currentUser = Meteor.user();
if (!currentUser) return false;
return ((currentUser.profile || {}).boardView === 'board-view-cal');
},
}).register('calendarView');
+1 -1
View File
@@ -50,6 +50,6 @@ position()
display: flex
flex-direction: column
margin: 0
padding: 0 40px 0px 0
padding: 0 0px 0px 0
overflow-x: hidden
overflow-y: auto
+71 -186
View File
@@ -7,71 +7,69 @@ template(name="boardHeaderBar")
.board-header-btns.left
unless isMiniScreen
unless isSandstorm
if currentBoard
if currentUser
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
if showStarCounter
span
= currentBoard.stars
if currentBoard
if currentUser
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
if showStarCounter
span
= currentBoard.stars
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
i.fa.fa-eye
if $eq watchLevel "tracking"
i.fa.fa-bell
if $eq watchLevel "muted"
i.fa.fa-bell-slash
span {{_ watchLevel}}
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
i.fa.fa-eye
if $eq watchLevel "tracking"
i.fa.fa-bell
if $eq watchLevel "muted"
i.fa.fa-bell-slash
span {{_ watchLevel}}
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
.board-header-btns.right
if currentBoard
if isMiniScreen
unless isSandstorm
if currentUser
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
if showStarCounter
span
= currentBoard.stars
if currentUser
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
if showStarCounter
span
= currentBoard.stars
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
i.fa.fa-eye
if $eq watchLevel "tracking"
i.fa.fa-bell
if $eq watchLevel "muted"
i.fa.fa-bell-slash
span {{_ watchLevel}}
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
i.fa.fa-eye
if $eq watchLevel "tracking"
i.fa.fa-bell
if $eq watchLevel "muted"
i.fa.fa-bell-slash
span {{_ watchLevel}}
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
if isSandstorm
if currentUser
@@ -87,19 +85,25 @@ template(name="boardHeaderBar")
if Filter.isActive
a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}")
i.fa.fa-times-thin
if currentUser.isAdmin
a.board-header-btn.js-open-rules-view(title="{{_ 'rules'}}")
i.fa.fa-magic
span {{_ 'rules'}}
else if currentUser.isBoardAdmin
a.board-header-btn.js-open-rules-view(title="{{_ 'rules'}}")
i.fa.fa-magic
span {{_ 'rules'}}
a.board-header-btn.js-open-search-view(title="{{_ 'search'}}")
i.fa.fa-search
span {{_ 'search'}}
a.board-header-btn.js-toggle-board-view(
title="{{_ 'board-view'}}")
i.fa.fa-th-large
span {{_ currentUser.profile.boardView}}
unless currentBoard.isTemplatesBoard
a.board-header-btn.js-toggle-board-view(
title="{{_ 'board-view'}}")
i.fa.fa-th-large
span {{#if currentUser.profile.boardView}}{{_ currentUser.profile.boardView}}{{else}}{{_ 'board-view-lists'}}{{/if}}
if canModifyBoard
a.board-header-btn.js-multiselection-activate(
@@ -112,40 +116,8 @@ template(name="boardHeaderBar")
i.fa.fa-times-thin
.separator
a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}")
i.board-header-btn-icon.fa.fa-navicon
template(name="boardMenuPopup")
ul.pop-over-list
li: a.js-custom-fields {{_ 'custom-fields'}}
li: a.js-open-archives {{_ 'archived-items'}}
if currentUser.isBoardAdmin
li: a.js-change-board-color {{_ 'board-change-color'}}
//-
XXX Language should be handled by sandstorm, but for now display a
language selection link in the board menu. This link is normally present
in the header bar that is not displayed on sandstorm.
if isSandstorm
li: a.js-change-language {{_ 'language'}}
unless isSandstorm
if currentUser.isBoardAdmin
hr
ul.pop-over-list
li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}}
li: a.js-archive-board {{_ 'archive-board'}}
li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}}
hr
ul.pop-over-list
li: a.js-subtask-settings {{_ 'subtask-settings'}}
if isSandstorm
hr
ul.pop-over-list
li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}}
li: a.js-import-board {{_ 'import-board-c'}}
hr
ul.pop-over-list
li: a.js-subtask-settings {{_ 'subtask-settings'}}
a.board-header-btn.js-toggle-sidebar
i.fa.fa-navicon
template(name="boardVisibilityList")
ul.pop-over-list
@@ -196,64 +168,6 @@ template(name="boardChangeWatchPopup")
i.fa.fa-check
span.sub-name {{_ 'muted-info'}}
template(name="boardChangeColorPopup")
.board-backgrounds-list.clearfix
each backgroundColors
.board-background-select.js-select-background
span.background-box(class="board-color-{{this}}")
if isSelected
i.fa.fa-check
template(name="boardSubtaskSettingsPopup")
form.board-subtask-settings
h3 {{_ 'show-parent-in-minicard'}}
a#prefix-with-full-path.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}")
span {{_ 'prefix-with-full-path'}}
a#prefix-with-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}")
span {{_ 'prefix-with-parent'}}
a#subtext-with-full-path.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}")
span {{_ 'subtext-with-full-path'}}
a#subtext-with-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}")
span {{_ 'subtext-with-parent'}}
a#no-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}")
span {{_ 'no-parent'}}
div
hr
div.check-div
a.flex.js-field-has-subtasks(class="{{#if allowsSubtasks}}is-checked{{/if}}")
.materialCheckBox(class="{{#if allowsSubtasks}}is-checked{{/if}}")
span {{_ 'show-subtasks-field'}}
label
| {{_ 'deposit-subtasks-board'}}
select.js-field-deposit-board(disabled="{{#unless allowsSubtasks}}disabled{{/unless}}")
each boards
if isBoardSelected
option(value=_id selected="selected") {{title}}
else
option(value=_id) {{title}}
if isNullBoardSelected
option(value='null' selected="selected") {{_ 'custom-field-dropdown-none'}}
else
option(value='null') {{_ 'custom-field-dropdown-none'}}
div
hr
label
| {{_ 'deposit-subtasks-list'}}
select.js-field-deposit-list(disabled="{{#unless hasLists}}disabled{{/unless}}")
each lists
if isListSelected
option(value=_id selected="selected") {{title}}
else
option(value=_id) {{title}}
template(name="createBoard")
form
label
@@ -275,50 +189,21 @@ template(name="createBoard")
input.primary.wide(type="submit" value="{{_ 'create'}}")
span.quiet
| {{_ 'or'}}
a.js-import-board {{_ 'import-board'}}
template(name="chooseBoardSource")
ul.pop-over-list
li
a(href="{{pathFor '/import/trello'}}") {{_ 'from-trello'}}
li
a(href="{{pathFor '/import/wekan'}}") {{_ 'from-wekan'}}
a.js-import-board {{_ 'import'}}
span.quiet
| /
a.js-board-template {{_ 'template'}}
template(name="boardChangeTitlePopup")
form
label
| {{_ 'title'}}
input.js-board-name(type="text" value=title autofocus)
input.js-board-name(type="text" value=title autofocus dir="auto")
label
| {{_ 'description'}}
textarea.js-board-desc= description
textarea.js-board-desc(dir="auto")= description
input.primary.wide(type="submit" value="{{_ 'rename'}}")
template(name="boardCreateRulePopup")
p {{_ 'close-board-pop'}}
button.js-confirm.negate.full(type="submit") {{_ 'archive'}}
template(name="archiveBoardPopup")
p {{_ 'close-board-pop'}}
button.js-confirm.negate.full(type="submit") {{_ 'archive'}}
template(name="outgoingWebhooksPopup")
each integrations
form.integration-form
if title
h4 {{title}}
else
h4 {{_ 'no-name'}}
label
| URL
input.js-outgoing-webhooks-url(type="text" name="url" value=url)
input(type="hidden" value=_id name="id")
input.primary.wide(type="submit" value="{{_ 'save'}}")
form.integration-form
h4
| {{_ 'new-outgoing-webhook'}}
label
| URL
input.js-outgoing-webhooks-url(type="text" name="url" autofocus)
input.primary.wide(type="submit" value="{{_ 'save'}}")
+9 -174
View File
@@ -89,14 +89,19 @@ BlazeComponent.extendComponent({
},
'click .js-toggle-board-view'() {
const currentUser = Meteor.user();
if (currentUser.profile.boardView === 'board-view-swimlanes') {
if ((currentUser.profile || {}).boardView === 'board-view-swimlanes') {
currentUser.setBoardView('board-view-cal');
} else if (currentUser.profile.boardView === 'board-view-lists') {
} else if ((currentUser.profile || {}).boardView === 'board-view-lists') {
currentUser.setBoardView('board-view-swimlanes');
} else if (currentUser.profile.boardView === 'board-view-cal') {
} else if ((currentUser.profile || {}).boardView === 'board-view-cal') {
currentUser.setBoardView('board-view-lists');
} else {
currentUser.setBoardView('board-view-swimlanes');
}
},
'click .js-toggle-sidebar'() {
Sidebar.toggle();
},
'click .js-open-filter-view'() {
Sidebar.setView('filter');
},
@@ -135,124 +140,6 @@ Template.boardHeaderBar.helpers({
},
});
BlazeComponent.extendComponent({
backgroundColors() {
return Boards.simpleSchema()._schema.color.allowedValues;
},
isSelected() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return currentBoard.color === this.currentData().toString();
},
events() {
return [{
'click .js-select-background'(evt) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const newColor = this.currentData().toString();
currentBoard.setColor(newColor);
evt.preventDefault();
},
}];
},
}).register('boardChangeColorPopup');
BlazeComponent.extendComponent({
onCreated() {
this.currentBoard = Boards.findOne(Session.get('currentBoard'));
},
allowsSubtasks() {
return this.currentBoard.allowsSubtasks;
},
isBoardSelected() {
return this.currentBoard.subtasksDefaultBoardId === this.currentData()._id;
},
isNullBoardSelected() {
return (this.currentBoard.subtasksDefaultBoardId === null) || (this.currentBoard.subtasksDefaultBoardId === undefined);
},
boards() {
return Boards.find({
archived: false,
'members.userId': Meteor.userId(),
}, {
sort: ['title'],
});
},
lists() {
return Lists.find({
boardId: this.currentBoard._id,
archived: false,
}, {
sort: ['title'],
});
},
hasLists() {
return this.lists().count() > 0;
},
isListSelected() {
return this.currentBoard.subtasksDefaultBoardId === this.currentData()._id;
},
presentParentTask() {
let result = this.currentBoard.presentParentTask;
if ((result === null) || (result === undefined)) {
result = 'no-parent';
}
return result;
},
events() {
return [{
'click .js-field-has-subtasks'(evt) {
evt.preventDefault();
this.currentBoard.allowsSubtasks = !this.currentBoard.allowsSubtasks;
this.currentBoard.setAllowsSubtasks(this.currentBoard.allowsSubtasks);
$('.js-field-has-subtasks .materialCheckBox').toggleClass('is-checked', this.currentBoard.allowsSubtasks);
$('.js-field-has-subtasks').toggleClass('is-checked', this.currentBoard.allowsSubtasks);
$('.js-field-deposit-board').prop('disabled', !this.currentBoard.allowsSubtasks);
},
'change .js-field-deposit-board'(evt) {
let value = evt.target.value;
if (value === 'null') {
value = null;
}
this.currentBoard.setSubtasksDefaultBoardId(value);
evt.preventDefault();
},
'change .js-field-deposit-list'(evt) {
this.currentBoard.setSubtasksDefaultListId(evt.target.value);
evt.preventDefault();
},
'click .js-field-show-parent-in-minicard'(evt) {
const value = evt.target.id || $(evt.target).parent()[0].id || $(evt.target).parent()[0].parent()[0].id;
const options = [
'prefix-with-full-path',
'prefix-with-parent',
'subtext-with-full-path',
'subtext-with-parent',
'no-parent'];
options.forEach(function(element) {
if (element !== value) {
$(`#${element} .materialCheckBox`).toggleClass('is-checked', false);
$(`#${element}`).toggleClass('is-checked', false);
}
});
$(`#${value} .materialCheckBox`).toggleClass('is-checked', true);
$(`#${value}`).toggleClass('is-checked', true);
this.currentBoard.setPresentParentTask(value);
evt.preventDefault();
},
}];
},
}).register('boardSubtaskSettingsPopup');
const CreateBoard = BlazeComponent.extendComponent({
template() {
return 'createBoard';
@@ -304,16 +191,11 @@ const CreateBoard = BlazeComponent.extendComponent({
'click .js-import': Popup.open('boardImportBoard'),
submit: this.onSubmit,
'click .js-import-board': Popup.open('chooseBoardSource'),
'click .js-board-template': Popup.open('searchElement'),
}];
},
}).register('createBoardPopup');
BlazeComponent.extendComponent({
template() {
return 'chooseBoardSource';
},
}).register('chooseBoardSourcePopup');
(class HeaderBarCreateBoard extends CreateBoard {
onSubmit(evt) {
super.onSubmit(evt);
@@ -363,50 +245,3 @@ BlazeComponent.extendComponent({
}];
},
}).register('boardChangeWatchPopup');
BlazeComponent.extendComponent({
integrations() {
const boardId = Session.get('currentBoard');
return Integrations.find({ boardId: `${boardId}` }).fetch();
},
integration(id) {
const boardId = Session.get('currentBoard');
return Integrations.findOne({ _id: id, boardId: `${boardId}` });
},
events() {
return [{
'submit'(evt) {
evt.preventDefault();
const url = evt.target.url.value;
const boardId = Session.get('currentBoard');
let id = null;
let integration = null;
if (evt.target.id) {
id = evt.target.id.value;
integration = this.integration(id);
if (url) {
Integrations.update(integration._id, {
$set: {
url: `${url}`,
},
});
} else {
Integrations.remove(integration._id);
}
} else if (url) {
Integrations.insert({
userId: Meteor.userId(),
enabled: true,
type: 'outgoing-webhooks',
url: `${url}`,
boardId: `${boardId}`,
activities: ['all'],
});
}
Popup.close();
},
}];
},
}).register('outgoingWebhooksPopup');
+15 -4
View File
@@ -18,17 +18,25 @@ template(name="boardList")
else
a.js-open-board.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}")
span.details
span.board-list-item-name= title
span.board-list-item-name
+viewer
= title
i.fa.js-star-board(
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
title="{{_ 'star-board-title'}}")
p.board-list-item-desc
+viewer
= description
if hasSpentTimeCards
i.fa.js-has-spenttime-cards(
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
p.board-list-item-desc= description
i.fa.js-clone-board(
class="fa-clone"
title="{{_ 'duplicate-board'}}")
i.fa.js-archive-board(
class="fa-archive"
title="{{_ 'archive-board'}}")
template(name="boardListHeaderBar")
h1 {{_ 'my-boards'}}
@@ -36,3 +44,6 @@ template(name="boardListHeaderBar")
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'}}
+39 -6
View File
@@ -1,5 +1,20 @@
const subManager = new SubsManager();
Template.boardListHeaderBar.events({
'click .js-open-archived-board'() {
Modal.open('archivedBoards');
},
});
Template.boardListHeaderBar.helpers({
templatesBoardId() {
return Meteor.user().getTemplatesBoardId();
},
templatesBoardSlug() {
return Meteor.user().getTemplatesBoardSlug();
},
});
BlazeComponent.extendComponent({
onCreated() {
Meteor.subscribe('setting');
@@ -9,23 +24,21 @@ BlazeComponent.extendComponent({
return Boards.find({
archived: false,
'members.userId': Meteor.userId(),
}, {
sort: ['title'],
});
type: 'board',
}, { sort: ['title'] });
},
isStarred() {
const user = Meteor.user();
return user && user.hasStarred(this.currentData()._id);
},
hasOvertimeCards() {
subManager.subscribe('board', this.currentData()._id);
subManager.subscribe('board', this.currentData()._id, false);
return this.currentData().hasOvertimeCards();
},
hasSpentTimeCards() {
subManager.subscribe('board', this.currentData()._id);
subManager.subscribe('board', this.currentData()._id, false);
return this.currentData().hasSpentTimeCards();
},
@@ -42,6 +55,26 @@ BlazeComponent.extendComponent({
Meteor.user().toggleBoardStar(boardId);
evt.preventDefault();
},
'click .js-clone-board'(evt) {
Meteor.call('cloneBoard',
this.currentData()._id,
Session.get('fromBoard'),
(err, res) => {
if (err) {
this.setError(err.error);
} else {
Session.set('fromBoard', null);
Utils.goBoardId(res);
}
}
);
evt.preventDefault();
},
'click .js-archive-board'(evt) {
const boardId = this.currentData()._id;
Meteor.call('archiveBoard', boardId);
evt.preventDefault();
},
'click .js-accept-invite'() {
const boardId = this.currentData()._id;
Meteor.user().removeInvite(boardId);
+28
View File
@@ -94,13 +94,41 @@ $spaceBetweenTiles = 16px
.is-star-active
color: white
.fa-clone
position: absolute;
bottom: 0
font-size: 14px
height: 18px
line-height: 18px
opacity: 0
right: 0
padding: 9px 9px
transition-duration: .15s
transition-property: color, font-size, background
.fa-archive
position: absolute;
bottom: 0
font-size: 14px
height: 18px
line-height: 18px
opacity: 0
left: 0
padding: 9px 9px
transition-duration: .15s
transition-property: color, font-size, background
li:hover a
&:hover
.fa-star,
.fa-clone,
.fa-archive,
.fa-star-o
color: white
.fa-star,
.fa-clone,
.fa-archive,
.fa-star-o
color: white
opacity: .75
+8
View File
@@ -0,0 +1,8 @@
template(name="miniboard")
.minicard(
class="minicard-{{colorClass}}")
.minicard-title
.handle
.fa.fa-arrows
+viewer
= title
@@ -4,9 +4,10 @@ template(name="cardCustomFieldsPopup")
li.item(class="")
a.name.js-select-field(href="#")
span.full-name
+viewer
= name
if hasCustomField
i.fa.fa-check
i.fa.fa-check
hr
a.quiet-button.full.js-settings
i.fa.fa-cog
@@ -61,9 +62,13 @@ template(name="cardCustomField-dropdown")
select.inline
each items
if($eq data.value this._id)
option(value=_id selected="selected") {{name}}
option(value=_id selected="selected")
+viewer
= name
else
option(value=_id) {{name}}
option(value=_id)
+viewer
= name
.edit-controls.clearfix
button.primary(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
@@ -73,4 +78,4 @@ template(name="cardCustomField-dropdown")
+viewer
= selectedItem
else
| {{_ 'edit'}}
| {{_ 'edit'}}
+33 -21
View File
@@ -1,6 +1,6 @@
template(name="cardDetails")
section.card-details.js-card-details.js-perfect-scrollbar: .card-details-canvas
.card-details-header
.card-details-header(class='{{#if colorClass}}card-details-{{colorClass}}{{/if}}')
+inlinedForm(classNames="js-card-details-title")
+editCardTitleForm
else
@@ -77,7 +77,9 @@ template(name="cardDetails")
h3.card-details-item-title {{_ 'labels'}}
a(class="{{#if canModifyCard}}js-add-labels{{else}}is-disabled{{/if}}" title="{{_ 'card-labels-title'}}")
each labels
span.card-label(class="card-label-{{color}}" title=name)= name
span.card-label(class="card-label-{{color}}" title=name)
+viewer
= name
if canModifyCard
a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}")
i.fa.fa-plus
@@ -86,7 +88,8 @@ template(name="cardDetails")
each customFieldsWD
.card-details-item.card-details-item-customfield
h3.card-details-item-title
= definition.name
+viewer
= definition.name
+cardCustomField
.card-details-items
@@ -197,20 +200,20 @@ template(name="cardDetails")
+activities(card=this mode="card")
template(name="editCardTitleForm")
textarea.js-edit-card-title(rows='1' autofocus)
textarea.js-edit-card-title(rows='1' autofocus dir="auto")
= getTitle
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-title-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
template(name="editCardRequesterForm")
input.js-edit-card-requester(type='text' autofocus value=getRequestedBy)
input.js-edit-card-requester(type='text' autofocus value=getRequestedBy dir="auto")
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-requester-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
template(name="editCardAssignerForm")
input.js-edit-card-assigner(type='text' autofocus value=getAssignedBy)
input.js-edit-card-assigner(type='text' autofocus value=getAssignedBy dir="auto")
.edit-controls.clearfix
button.primary.confirm.js-submit-edit-card-assigner-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
@@ -221,15 +224,16 @@ template(name="cardDetailsActionsPopup")
if canModifyCard
hr
ul.pop-over-list
li: a.js-members {{_ 'card-edit-members'}}
li: a.js-labels {{_ 'card-edit-labels'}}
li: a.js-attachments {{_ 'card-edit-attachments'}}
//li: a.js-members {{_ 'card-edit-members'}}
//li: a.js-labels {{_ 'card-edit-labels'}}
//li: a.js-attachments {{_ 'card-edit-attachments'}}
li: a.js-custom-fields {{_ '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'}}
li: a.js-end-date {{_ 'editCardEndDatePopup-title'}}
//li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}}
//li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
//li: a.js-due-date {{_ 'editCardDueDatePopup-title'}}
//li: a.js-end-date {{_ 'editCardEndDatePopup-title'}}
li: a.js-spent-time {{_ 'editCardSpentTimePopup-title'}}
li: a.js-set-card-color {{_ 'setCardColorPopup-title'}}
hr
ul.pop-over-list
li: a.js-move-card-to-top {{_ 'moveCardToTop-title'}}
@@ -260,7 +264,7 @@ template(name="copyChecklistToManyCardsPopup")
template(name="boardsAndLists")
label {{_ 'boards'}}:
select.js-select-boards
select.js-select-boards(autofocus)
each boards
if $eq _id currentBoard._id
option(value="{{_id}}" selected) {{_ 'current'}}
@@ -298,40 +302,48 @@ template(name="cardMorePopup")
span {{_ 'link-card'}}
= ' '
i.fa.colorful(class="{{#if board.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
input.inline-input(type="text" id="cardURL" readonly value="{{ absoluteUrl }}")
input.inline-input(type="text" id="cardURL" readonly value="{{ absoluteUrl }}" autofocus="autofocus")
button.js-copy-card-link-to-clipboard(class="btn") {{_ 'copy-card-link-to-clipboard'}}
span.clearfix
br
h2 {{_ 'change-card-parent'}}
label {{_ 'source-board'}}:
select.js-field-parent-board
if isTopLevel
option(value="none" selected) {{_ 'custom-field-dropdown-none'}}
else
option(value="none") {{_ 'custom-field-dropdown-none'}}
each boards
if isParentBoard
option(value="{{_id}}" selected) {{title}}
else
option(value="{{_id}}") {{title}}
if isTopLevel
option(value="none" selected) {{_ 'custom-field-dropdown-none'}}
else
option(value="none") {{_ 'custom-field-dropdown-none'}}
label {{_ 'parent-card'}}:
select.js-field-parent-card
if isTopLevel
option(value="none" selected) {{_ 'custom-field-dropdown-none'}}
else
option(value="none") {{_ 'custom-field-dropdown-none'}}
each cards
if isParentCard
option(value="{{_id}}" selected) {{title}}
else
option(value="{{_id}}") {{title}}
option(value="none") {{_ 'custom-field-dropdown-none'}}
br
| {{_ 'added'}}
span.date(title=card.createdAt) {{ moment createdAt 'LLL' }}
a.js-delete(title="{{_ 'card-delete-notice'}}") {{_ 'delete'}}
template(name="setCardColorPopup")
form.edit-label
.palette-colors: each colors
unless $eq color 'white'
span.card-label.palette-color.js-palette-color(class="card-details-{{color}}")
if(isSelected color)
i.fa.fa-check
button.primary.confirm.js-submit {{_ 'save'}}
button.js-remove-color.negate.wide.right {{_ 'unset-color'}}
template(name="cardDeletePopup")
p {{_ "card-delete-pop"}}
+84 -89
View File
@@ -1,6 +1,11 @@
const subManager = new SubsManager();
const { calculateIndexData, enableClickOnTouch } = Utils;
let cardColors;
Meteor.startup(() => {
cardColors = Cards.simpleSchema()._schema.color.allowedValues;
});
BlazeComponent.extendComponent({
mixins() {
return [Mixins.InfiniteScrolling, Mixins.PerfectScrollbar];
@@ -73,14 +78,13 @@ BlazeComponent.extendComponent({
//Scroll top
const cardViewStartTop = $cardView.offset().top;
const cardContainerScrollTop = $cardContainer.scrollTop();
let topOffset = false;
if(cardViewStartTop < 0){
topOffset = 0;
} else if(cardViewStartTop - cardContainerScrollTop > 100) {
topOffset = cardViewStartTop - cardContainerScrollTop - 100;
if(cardViewStartTop !== 100){
topOffset = cardViewStartTop - 100;
}
if(topOffset !== false) {
bodyBoardComponent.scrollTop(topOffset);
bodyBoardComponent.scrollTop(cardContainerScrollTop + topOffset);
}
},
@@ -112,6 +116,7 @@ BlazeComponent.extendComponent({
onRendered() {
if (!Utils.isMiniScreen()) {
Meteor.setTimeout(() => {
$('.card-details').mCustomScrollbar({theme:'minimal-dark', setWidth: false, setLeft: 0, scrollbarPosition: 'outside', mouseWheel: true });
this.scrollParentContainer();
}, 500);
}
@@ -336,6 +341,7 @@ Template.cardDetailsActionsPopup.events({
'click .js-move-card': Popup.open('moveCard'),
'click .js-copy-card': Popup.open('copyCard'),
'click .js-copy-checklist-cards': Popup.open('copyChecklistToManyCards'),
'click .js-set-card-color': Popup.open('setCardColor'),
'click .js-move-card-to-top' (evt) {
evt.preventDefault();
const minOrder = _.min(this.list().cards(this.swimlaneId).map((c) => c.sort));
@@ -406,17 +412,19 @@ Template.moveCardPopup.events({
// XXX We should *not* get the currentCard from the global state, but
// instead from a “component” state.
const card = Cards.findOne(Session.get('currentCard'));
const bSelect = $('.js-select-boards')[0];
const boardId = bSelect.options[bSelect.selectedIndex].value;
const lSelect = $('.js-select-lists')[0];
const newListId = lSelect.options[lSelect.selectedIndex].value;
const listId = lSelect.options[lSelect.selectedIndex].value;
const slSelect = $('.js-select-swimlanes')[0];
card.swimlaneId = slSelect.options[slSelect.selectedIndex].value;
card.move(card.swimlaneId, newListId, 0);
const swimlaneId = slSelect.options[slSelect.selectedIndex].value;
card.move(boardId, swimlaneId, listId, 0);
Popup.close();
},
});
BlazeComponent.extendComponent({
onCreated() {
subManager.subscribe('board', Session.get('currentBoard'));
subManager.subscribe('board', Session.get('currentBoard'), false);
this.selectedBoardId = new ReactiveVar(Session.get('currentBoard'));
},
@@ -424,6 +432,7 @@ BlazeComponent.extendComponent({
const boards = Boards.find({
archived: false,
'members.userId': Meteor.userId(),
_id: {$ne: Meteor.user().getTemplatesBoardId()},
}, {
sort: ['title'],
});
@@ -444,38 +453,21 @@ BlazeComponent.extendComponent({
return [{
'change .js-select-boards'(evt) {
this.selectedBoardId.set($(evt.currentTarget).val());
subManager.subscribe('board', this.selectedBoardId.get());
subManager.subscribe('board', this.selectedBoardId.get(), false);
},
}];
},
}).register('boardsAndLists');
function cloneCheckList(_id, checklist) {
'use strict';
const checklistId = checklist._id;
checklist.cardId = _id;
checklist._id = null;
const newChecklistId = Checklists.insert(checklist);
ChecklistItems.find({checklistId}).forEach(function(item) {
item._id = null;
item.checklistId = newChecklistId;
item.cardId = _id;
ChecklistItems.insert(item);
});
}
Template.copyCardPopup.events({
'click .js-done'() {
const card = Cards.findOne(Session.get('currentCard'));
const oldId = card._id;
card._id = null;
const lSelect = $('.js-select-lists')[0];
card.listId = lSelect.options[lSelect.selectedIndex].value;
listId = lSelect.options[lSelect.selectedIndex].value;
const slSelect = $('.js-select-swimlanes')[0];
card.swimlaneId = slSelect.options[slSelect.selectedIndex].value;
const swimlaneId = slSelect.options[slSelect.selectedIndex].value;
const bSelect = $('.js-select-boards')[0];
card.boardId = bSelect.options[bSelect.selectedIndex].value;
const boardId = bSelect.options[bSelect.selectedIndex].value;
const textarea = $('#copy-card-title');
const title = textarea.val().trim();
// insert new card to the bottom of new list
@@ -484,38 +476,13 @@ Template.copyCardPopup.events({
if (title) {
card.title = title;
card.coverId = '';
const _id = Cards.insert(card);
const _id = card.copy(boardId, swimlaneId, listId);
// In case the filter is active we need to add the newly inserted card in
// the list of exceptions -- cards that are not filtered. Otherwise the
// card will disappear instantly.
// See https://github.com/wekan/wekan/issues/80
Filter.addException(_id);
// copy checklists
let cursor = Checklists.find({cardId: oldId});
cursor.forEach(function() {
cloneCheckList(_id, arguments[0]);
});
// copy subtasks
cursor = Cards.find({parentId: oldId});
cursor.forEach(function() {
'use strict';
const subtask = arguments[0];
subtask.parentId = _id;
subtask._id = null;
/* const newSubtaskId = */ Cards.insert(subtask);
});
// copy card comments
cursor = CardComments.find({cardId: oldId});
cursor.forEach(function () {
'use strict';
const comment = arguments[0];
comment.cardId = _id;
comment._id = null;
CardComments.insert(comment);
});
Popup.close();
}
},
@@ -552,9 +519,8 @@ Template.copyChecklistToManyCardsPopup.events({
Filter.addException(_id);
// copy checklists
let cursor = Checklists.find({cardId: oldId});
cursor.forEach(function() {
cloneCheckList(_id, arguments[0]);
Checklists.find({cardId: oldId}).forEach((ch) => {
ch.copy(_id);
});
// copy subtasks
@@ -568,13 +534,8 @@ Template.copyChecklistToManyCardsPopup.events({
});
// copy card comments
cursor = CardComments.find({cardId: oldId});
cursor.forEach(function () {
'use strict';
const comment = arguments[0];
comment.cardId = _id;
comment._id = null;
CardComments.insert(comment);
CardComments.find({cardId: oldId}).forEach((cmt) => {
cmt.copy(_id);
});
}
Popup.close();
@@ -585,11 +546,48 @@ Template.copyChecklistToManyCardsPopup.events({
BlazeComponent.extendComponent({
onCreated() {
this.currentCard = this.currentData();
this.currentColor = new ReactiveVar(this.currentCard.color);
},
colors() {
return cardColors.map((color) => ({ color, name: '' }));
},
isSelected(color) {
if (this.currentColor.get() === null) {
return color === 'white';
}
return this.currentColor.get() === color;
},
events() {
return [{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
'click .js-submit' () {
this.currentCard.setColor(this.currentColor.get());
Popup.close();
},
'click .js-remove-color'() {
this.currentCard.setColor(null);
Popup.close();
},
}];
},
}).register('setCardColorPopup');
BlazeComponent.extendComponent({
onCreated() {
this.currentCard = this.currentData();
this.parentBoard = new ReactiveVar(null);
this.parentCard = this.currentCard.parentCard();
if (this.parentCard) {
this.parentBoard = this.parentCard.board();
const list = $('.js-field-parent-card');
list.val(this.parentCard._id);
this.parentBoard.set(this.parentCard.board()._id);
} else {
this.parentBoard = null;
this.parentBoard.set(null);
}
},
@@ -597,6 +595,9 @@ BlazeComponent.extendComponent({
const boards = Boards.find({
archived: false,
'members.userId': Meteor.userId(),
_id: {
$ne: Meteor.user().getTemplatesBoardId(),
},
}, {
sort: ['title'],
});
@@ -604,8 +605,12 @@ BlazeComponent.extendComponent({
},
cards() {
if (this.parentBoard) {
return this.parentBoard.cards();
const currentId = Session.get('currentCard');
if (this.parentBoard.get()) {
return Cards.find({
boardId: this.parentBoard.get(),
_id: {$ne: currentId},
});
} else {
return [];
}
@@ -613,8 +618,8 @@ BlazeComponent.extendComponent({
isParentBoard() {
const board = this.currentData();
if (this.parentBoard) {
return board._id === this.parentBoard;
if (this.parentBoard.get()) {
return board._id === this.parentBoard.get();
}
return false;
},
@@ -628,11 +633,10 @@ BlazeComponent.extendComponent({
},
setParentCardId(cardId) {
if (cardId === 'null') {
cardId = null;
this.parentCard = null;
} else {
if (cardId) {
this.parentCard = Cards.findOne(cardId);
} else {
this.parentCard = null;
}
this.currentCard.setParentId(cardId);
},
@@ -669,23 +673,14 @@ BlazeComponent.extendComponent({
'change .js-field-parent-board'(evt) {
const selection = $(evt.currentTarget).val();
const list = $('.js-field-parent-card');
list.empty();
if (selection === 'none') {
this.parentBoard = null;
list.prop('disabled', true);
this.parentBoard.set(null);
} else {
this.parentBoard = Boards.findOne(selection);
this.parentBoard.cards().forEach(function(card) {
list.append(
$('<option></option>').val(card._id).html(card.title)
);
});
subManager.subscribe('board', $(evt.currentTarget).val(), false);
this.parentBoard.set(selection);
list.prop('disabled', false);
}
list.append(
`<option value='none' selected='selected'>${TAPi18n.__('custom-field-dropdown-none')}</option>`
);
this.setParentCardId('null');
this.setParentCardId(null);
},
'change .js-field-parent-card'(evt) {
const selection = $(evt.currentTarget).val();
+93 -3
View File
@@ -1,9 +1,9 @@
@import 'nib'
.card-details
padding: 0 20px
padding: 0
flex-shrink: 0
flex-basis: 470px
flex-basis: 510px
will-change: flex-basis
overflow-y: scroll
overflow-x: hidden
@@ -14,8 +14,16 @@
box-shadow: 0 0 7px 0 darken(white, 30%)
transition: flex-basis 0.1s
.mCustomScrollBox
padding-left: 0
.ps-scrollbar-y-rail
pointer-event: all
position: absolute;
.card-details-canvas
width: 470px
padding-left: 20px;
.card-details-header
margin: 0 -20px 5px
@@ -125,10 +133,92 @@ input[type="submit"].attachment-add-link-submit
.card-details-canvas
width: 100%
padding-left: 0px;
.card-details-header
.close-card-details
margin-right: 0px
.card-details-menu
margin-right: 10px
card-details-color(background, color...)
background: background !important
if color
color: color !important //overwrite text for better visibility
.card-details-white
card-details-color(unset, #000) //Black text for better visibility
border: 1px solid #eee
.card-details-green
card-details-color(#3cb500, #ffffff) //White text for better visibility
.card-details-yellow
card-details-color(#fad900, #000) //Black text for better visibility
.card-details-orange
card-details-color(#ff9f19, #000) //Black text for better visibility
.card-details-red
card-details-color(#eb4646, #ffffff) //White text for better visibility
.card-details-purple
card-details-color(#a632db, #ffffff) //White text for better visibility
.card-details-blue
card-details-color(#0079bf, #ffffff) //White text for better visibility
.card-details-pink
card-details-color(#ff78cb, #000) //Black text for better visibility
.card-details-sky
card-details-color(#00c2e0, #ffffff) //White text for better visibility
.card-details-black
card-details-color(#4d4d4d, #ffffff) //White text for better visibility
.card-details-lime
card-details-color(#51e898, #000) //Black text for better visibility
.card-details-silver
card-details-color(#c0c0c0, #000) //Black text for better visibility
.card-details-peachpuff
card-details-color(#ffdab9, #000) //Black text for better visibility
.card-details-crimson
card-details-color(#dc143c, #ffffff) //White text for better visibility
.card-details-plum
card-details-color(#dda0dd, #000) //Black text for better visibility
.card-details-darkgreen
card-details-color(#006400, #ffffff) //White text for better visibility
.card-details-slateblue
card-details-color(#6a5acd, #ffffff) //White text for better visibility
.card-details-magenta
card-details-color(#ff00ff, #ffffff) //White text for better visibility
.card-details-gold
card-details-color(#ffd700, #000) //Black text for better visibility
.card-details-navy
card-details-color(#000080, #ffffff) //White text for better visibility
.card-details-gray
card-details-color(#808080, #ffffff) //White text for better visibility
.card-details-saddlebrown
card-details-color(#8b4513, #ffffff) //White text for better visibility
.card-details-paleturquoise
card-details-color(#afeeee, #000) //Black text for better visibility
.card-details-mistyrose
card-details-color(#ffe4e1, #000) //Black text for better visibility
.card-details-indigo
card-details-color(#4b0082, #ffffff) //White text for better visibility
+1 -1
View File
@@ -56,7 +56,7 @@ template(name="addChecklistItemForm")
a.fa.fa-times-thin.js-close-inlined-form
template(name="editChecklistItemForm")
textarea.js-edit-checklist-item(rows='1' autofocus)
textarea.js-edit-checklist-item(rows='1' autofocus dir="auto")
if $eq type 'item'
= item.title
else
+2 -1
View File
@@ -31,7 +31,8 @@ template(name="cardLabelsPopup")
a.card-label-edit-button.fa.fa-pencil.js-edit-label
span.card-label.card-label-selectable.js-select-label(class="card-label-{{color}}"
class="{{# if isLabelSelected ../_id }}active{{/if}}")
= name
+viewer
= name
if(isLabelSelected ../_id)
i.card-label-selectable-icon.fa.fa-check
if currentUser.isBoardAdmin
+8 -3
View File
@@ -1,7 +1,8 @@
template(name="minicard")
.minicard(
class="{{#if isLinkedCard}}linked-card{{/if}}"
class="{{#if isLinkedBoard}}linked-board{{/if}}")
class="{{#if isLinkedBoard}}linked-board{{/if}}"
class="minicard-{{colorClass}}")
if cover
.minicard-cover(style="background-image: url('{{cover.url}}');")
if labels
@@ -9,6 +10,8 @@ template(name="minicard")
each labels
.minicard-label(class="card-label-{{color}}" title="{{name}}")
.minicard-title
.handle
.fa.fa-arrows
if $eq 'prefix-with-full-path' currentBoard.presentParentTask
.parent-prefix
| {{ parentString ' > ' }}
@@ -53,8 +56,10 @@ template(name="minicard")
each customFieldsWD
if definition.showOnCard
.minicard-custom-field
.minicard-custom-field-item
= definition.name
if definition.showLabelOnMiniCard
.minicard-custom-field-item
+viewer
= definition.name
.minicard-custom-field-item
+viewer
= trueValue
+96
View File
@@ -94,6 +94,19 @@
.minicard-custom-field-item
max-width:50%;
flex-grow:1;
.handle
width: 20px;
height: 20px;
position: absolute;
right: 5px;
top: 5px;
display:none;
@media only screen and (max-width: 1199px) {
display:block;
}
.fa-arrows
font-size:20px;
color: #ccc;
.minicard-title
p:last-child
margin-bottom: 0
@@ -189,3 +202,86 @@
border-top-right-radius: 0
z-index: 15
box-shadow: 0 1px 2px rgba(0,0,0,.15)
minicard-color(background, color...)
background-color: background
if color
color: color //overwrite text for better visibility
&:hover:not(.minicard-composer),
.is-selected &,
.draggable-hover-card &
background: darken(background, 3%)
.draggable-hover-card &
background: darken(background, 7%)
.minicard-green
minicard-color(#3cb500, #ffffff) //White text for better visibility
.minicard-yellow
minicard-color(#fad900)
.minicard-orange
minicard-color(#ff9f19)
.minicard-red
minicard-color(#eb4646, #ffffff) //White text for better visibility
.minicard-purple
minicard-color(#a632db, #ffffff) //White text for better visibility
.minicard-blue
minicard-color(#0079bf, #ffffff) //White text for better visibility
.minicard-pink
minicard-color(#ff78cb)
.minicard-sky
minicard-color(#00c2e0, #ffffff) //White text for better visibility
.minicard-black
minicard-color(#4d4d4d, #ffffff) //White text for better visibility
.minicard-lime
minicard-color(#51e898)
.minicard-silver
minicard-color(#c0c0c0)
.minicard-peachpuff
minicard-color(#ffdab9)
.minicard-crimson
minicard-color(#dc143c, #ffffff) //White text for better visibility
.minicard-plum
minicard-color(#dda0dd)
.minicard-darkgreen
minicard-color(#006400, #ffffff) //White text for better visibility
.minicard-slateblue
minicard-color(#6a5acd, #ffffff) //White text for better visibility
.minicard-magenta
minicard-color(#ff00ff, #ffffff) //White text for better visibility
.minicard-gold
minicard-color(#ffd700)
.minicard-navy
minicard-color(#000080, #ffffff) //White text for better visibility
.minicard-gray
minicard-color(#808080, #ffffff) //White text for better visibility
.minicard-saddlebrown
minicard-color(#8b4513, #ffffff) //White text for better visibility
.minicard-paleturquoise
minicard-color(#afeeee)
.minicard-mistyrose
minicard-color(#ffe4e1)
.minicard-indigo
minicard-color(#4b0082, #ffffff) //White text for better visibility
+3 -3
View File
@@ -50,13 +50,13 @@ template(name="subtaskDeleteDialog")
button.toggle-delete-subtask-dialog(type="button") {{_ 'cancel'}}
template(name="addSubtaskItemForm")
textarea.js-add-subtask-item(rows='1' autofocus)
textarea.js-add-subtask-item(rows='1' autofocus dir="auto")
.edit-controls.clearfix
button.primary.confirm.js-submit-add-subtask-item-form(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
template(name="editSubtaskItemForm")
textarea.js-edit-subtask-item(rows='1' autofocus)
textarea.js-edit-subtask-item(rows='1' autofocus dir="auto")
if $eq type 'item'
= item.title
else
@@ -76,7 +76,7 @@ template(name="subtasksItems")
else
+subtaskItemDetail(item = item subtasks = subtasks)
if canModifyCard
+inlinedForm(autoclose=false classNames="js-add-subtask-item" subtasks = subtasks)
+inlinedForm(autoclose=false classNames="js-add-subtask-item" subtasks = subtasks dir="auto")
+addSubtaskItemForm
else
a.add-subtask-item.js-open-inlined-form
+2 -2
View File
@@ -12,11 +12,11 @@ template(name="import")
template(name="importTextarea")
form
p: label(for='import-textarea') {{_ instruction}}
p: label(for='import-textarea') {{_ instruction}} {{_ 'import-board-instruction-about-errors'}}
textarea.js-import-json(placeholder="{{_ 'import-json-placeholder'}}" autofocus)
| {{jsonText}}
if isSandstorm
h1.warning DANGER !!! THIS DESTROYS YOUR IMPORTED DATA, CAUSES BOARD NOT FOUND ERROR WHEN YOU OPEN THIS GRAIN AGAIN https://github.com/wekan/wekan/issues/1430
h1.warning {{_ 'import-sandstorm-backup-warning'}}
p.warning {{_ 'import-sandstorm-warning'}}
input.primary.wide(type="submit" value="{{_ 'import'}}")
+16 -3
View File
@@ -26,6 +26,13 @@ BlazeComponent.extendComponent({
const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)';
const $cards = this.$('.js-minicards');
if(window.matchMedia('(max-width: 1199px)').matches) {
$( '.js-minicards' ).sortable({
handle: '.handle',
});
}
$cards.sortable({
connectWith: '.js-minicards:not(.js-list-full)',
tolerance: 'pointer',
@@ -60,7 +67,13 @@ BlazeComponent.extendComponent({
const nCards = MultiSelection.isActive() ? MultiSelection.count() : 1;
const sortIndex = calculateIndex(prevCardDom, nextCardDom, nCards);
const listId = Blaze.getData(ui.item.parents('.list').get(0))._id;
const swimlaneId = Blaze.getData(ui.item.parents('.swimlane').get(0))._id;
const currentBoard = Boards.findOne(Session.get('currentBoard'));
let swimlaneId = '';
const boardView = (Meteor.user().profile || {}).boardView;
if (boardView === 'board-view-swimlanes' || currentBoard.isTemplatesBoard())
swimlaneId = Blaze.getData(ui.item.parents('.swimlane').get(0))._id;
else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal') || !boardView)
swimlaneId = currentBoard.getDefaultSwimline()._id;
// Normally the jquery-ui sortable library moves the dragged DOM element
// to its new position, which disrupts Blaze reactive updates mechanism
@@ -73,12 +86,12 @@ BlazeComponent.extendComponent({
if (MultiSelection.isActive()) {
Cards.find(MultiSelection.getMongoSelector()).forEach((card, i) => {
card.move(swimlaneId, listId, sortIndex.base + i * sortIndex.increment);
card.move(currentBoard._id, swimlaneId, listId, sortIndex.base + i * sortIndex.increment);
});
} else {
const cardDomElement = ui.item.get(0);
const card = Blaze.getData(cardDomElement);
card.move(swimlaneId, listId, sortIndex.base);
card.move(currentBoard._id, swimlaneId, listId, sortIndex.base);
}
boardComponent.setIsDragging(false);
},
+123 -9
View File
@@ -10,7 +10,6 @@
// transparent, because that won't work during a list drag.
background: darken(white, 13%)
border-left: 1px solid darken(white, 20%)
border-bottom: 1px solid #CCC
padding: 0
float: left
@@ -44,12 +43,24 @@
background: white
margin: -3px 0 8px
.list-header
.list-header-card-count
height: 35px
.list-header-add
flex: 0 0 auto
margin: 20px 12px 4px
padding: 20px 12px 4px
position: relative
min-height: 20px
.list-header
flex: 0 0 auto
padding: 20px 12px 4px
position: relative
min-height: 20px
background-color: #e4e4e4;
border-bottom: 6px solid #e4e4e4;
&.ui-sortable-handle
cursor: grab
@@ -68,16 +79,18 @@
text-overflow: ellipsis
word-wrap: break-word
.list-header-watch-icon
padding-left: 10px
color: #a6a6a6
.list-header-menu
position: absolute
padding: 7px
padding: 27px 19px
margin-top: 1px
top: -@padding
right: -@padding
top: -7px
right: -7px
.list-header-plus-icon
color: #a6a6a6
@@ -86,6 +99,10 @@
.highlight
color: #ce1414
.cardCount
color: #8c8c8c
font-size: 0.8em
.list-body
flex: 1 1 auto
flex-direction: column
@@ -143,9 +160,12 @@
float: left
@media screen and (max-width: 800px)
.list-header-menu
margin-right: 30px
.mini-list
flex: 0 0 60px
height: 60px
height: auto
width: 100%
border-left: 0px
border-bottom: 1px solid darken(white, 20%)
@@ -154,6 +174,8 @@
display: block
width: 100%
border-left: 0px
&:first-child
margin-left: 0px
&.ui-sortable-helper
flex: 0 0 60px
@@ -172,8 +194,16 @@
border-left: 0px
border-bottom: 1px solid darken(white, 20%)
.list-header
.list-body
padding: 15px 19px;
.list-header
padding: 0 12px 0px
border-bottom: 0px solid #e4e4e4
height: 60px
margin-top: 10px
display: flex
align-items: center
.list-header-left-icon
display: inline
padding: 7px
@@ -185,8 +215,10 @@
.list-header-menu-icon
position: absolute
padding: 7px
top: -@padding
top: 50%
transform: translateY(-50%)
right: 17px
font-size: 20px
.link-board-wrapper
display: flex
@@ -198,3 +230,85 @@
.search-card-results
max-height: 250px
overflow: hidden
.sk-spinner-list
margin-top: unset !important
list-header-color(background, color...)
border-bottom: 6px solid background
.list-header-white
list-header-color(#ffffff, #4d4d4d) //Black text for better visibility
border: 1px solid #eee
.list-header-green
list-header-color(#3cb500, #ffffff) //White text for better visibility
.list-header-yellow
list-header-color(#fad900, #4d4d4d) //Black text for better visibility
.list-header-orange
list-header-color(#ff9f19, #4d4d4d) //Black text for better visibility
.list-header-red
list-header-color(#eb4646, #ffffff) //White text for better visibility
.list-header-purple
list-header-color(#a632db, #ffffff) //White text for better visibility
.list-header-blue
list-header-color(#0079bf, #ffffff) //White text for better visibility
.list-header-pink
list-header-color(#ff78cb, #4d4d4d) //Black text for better visibility
.list-header-sky
list-header-color(#00c2e0, #ffffff) //White text for better visibility
.list-header-black
list-header-color(#4d4d4d, #ffffff) //White text for better visibility
.list-header-lime
list-header-color(#51e898, #4d4d4d) //Black text for better visibility
.list-header-silver
list-header-color(unset, #4d4d4d) //Black text for better visibility
.list-header-peachpuff
list-header-color(#ffdab9, #4d4d4d) //Black text for better visibility
.list-header-crimson
list-header-color(#dc143c, #ffffff) //White text for better visibility
.list-header-plum
list-header-color(#dda0dd, #4d4d4d) //Black text for better visibility
.list-header-darkgreen
list-header-color(#006400, #ffffff) //White text for better visibility
.list-header-slateblue
list-header-color(#6a5acd, #ffffff) //White text for better visibility
.list-header-magenta
list-header-color(#ff00ff, #ffffff) //White text for better visibility
.list-header-gold
list-header-color(#ffd700, #4d4d4d) //Black text for better visibility
.list-header-navy
list-header-color(#000080, #ffffff) //White text for better visibility
.list-header-gray
list-header-color(#808080, #ffffff) //White text for better visibility
.list-header-saddlebrown
list-header-color(#8b4513, #ffffff) //White text for better visibility
.list-header-paleturquoise
list-header-color(#afeeee, #4d4d4d) //Black text for better visibility
.list-header-mistyrose
list-header-color(#ffe4e1, #4d4d4d) //Black text for better visibility
.list-header-indigo
list-header-color(#4b0082, #ffffff) //White text for better visibility
+62 -25
View File
@@ -4,7 +4,7 @@ template(name="listBody")
if cards.count
+inlinedForm(autoclose=false position="top")
+addCardForm(listId=_id position="top")
each (cards (idOrNull ../../_id))
each (cardsWithLimit (idOrNull ../../_id))
a.minicard-wrapper.js-minicard(href=absoluteUrl
class="{{#if cardIsSelected}}is-selected{{/if}}"
class="{{#if MultiSelection.isSelected _id}}is-checked{{/if}}")
@@ -12,6 +12,9 @@ template(name="listBody")
.materialCheckBox.multi-selection-checkbox.js-toggle-multi-selection(
class="{{#if MultiSelection.isSelected _id}}is-checked{{/if}}")
+minicard(this)
if (showSpinner (idOrNull ../../_id))
+spinnerList
if canSeeAddCard
+inlinedForm(autoclose=false position="bottom")
+addCardForm(listId=_id position="bottom")
@@ -20,13 +23,23 @@ template(name="listBody")
i.fa.fa-plus
| {{_ 'add-card'}}
template(name="spinnerList")
.sk-spinner.sk-spinner-wave.sk-spinner-list(
class=currentBoard.colorClass
id="showMoreResults")
.sk-rect1
.sk-rect2
.sk-rect3
.sk-rect4
.sk-rect5
template(name="addCardForm")
.minicard.minicard-composer.js-composer
if getLabels
.minicard-labels
each getLabels
.minicard-label(class="card-label-{{color}}" title="{{name}}")
textarea.minicard-composer-textarea.js-card-title(autofocus)
textarea.minicard-composer-textarea.js-card-title(autofocus dir="auto")
if members.get
.minicard-members.js-minicard-composer-members
each members.get
@@ -34,13 +47,19 @@ template(name="addCardForm")
.add-controls.clearfix
button.primary.confirm(type="submit") {{_ 'add'}}
span.quiet
| {{_ 'or'}}
a.js-link {{_ 'link'}}
span.quiet
| &nbsp;
| /
a.js-search {{_ 'search'}}
unless currentBoard.isTemplatesBoard
unless currentBoard.isTemplateBoard
span.quiet
| {{_ 'or'}}
a.js-link {{_ 'link'}}
span.quiet
| &nbsp;
| /
a.js-search {{_ 'search'}}
span.quiet
| &nbsp;
| /
a.js-card-template {{_ 'template'}}
template(name="autocompleteLabelLine")
.minicard-label(class="card-label-{{colorName}}" title=labelName)
@@ -50,11 +69,9 @@ template(name="linkCardPopup")
label {{_ 'boards'}}:
.link-board-wrapper
select.js-select-boards
option(value="")
each boards
if $eq _id currentBoard._id
option(value="{{_id}}" selected) {{_ 'current'}}
else
option(value="{{_id}}") {{title}}
option(value="{{_id}}") {{title}}
input.primary.confirm.js-link-board(type="button" value="{{_ 'link'}}")
label {{_ 'swimlanes'}}:
@@ -75,19 +92,39 @@ template(name="linkCardPopup")
.edit-controls.clearfix
input.primary.confirm.js-done(type="button" value="{{_ 'link'}}")
template(name="searchCardPopup")
label {{_ 'boards'}}:
.link-board-wrapper
select.js-select-boards
each boards
if $eq _id currentBoard._id
option(value="{{_id}}" selected) {{_ 'current'}}
else
template(name="searchElementPopup")
form
label
| {{_ 'title'}}
input.js-element-title(type="text" placeholder="{{_ 'title'}}" autofocus required dir="auto")
unless isTemplateSearch
label {{_ 'boards'}}:
.link-board-wrapper
select.js-select-boards
option(value="")
each boards
option(value="{{_id}}") {{title}}
form.js-search-term-form
input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus)
input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus dir="auto")
.list-body.js-perfect-scrollbar.search-card-results
.minicards.clearfix.js-minicards
each results
a.minicard-wrapper.js-minicard
+minicard(this)
if isBoardTemplateSearch
each results
a.minicard-wrapper.js-minicard
+miniboard(this)
if isListTemplateSearch
each results
a.minicard-wrapper.js-minicard
+minilist(this)
if isSwimlaneTemplateSearch
each results
a.minicard-wrapper.js-minicard
+miniswimlane(this)
if isCardTemplateSearch
each results
a.minicard-wrapper.js-minicard
+minicard(this)
unless isTemplateSearch
each results
a.minicard-wrapper.js-minicard
+minicard(this)
+237 -71
View File
@@ -1,6 +1,12 @@
const subManager = new SubsManager();
const InfiniteScrollIter = 10;
BlazeComponent.extendComponent({
onCreated() {
// for infinite scrolling
this.cardlimit = new ReactiveVar(InfiniteScrollIter);
},
mixins() {
return [Mixins.PerfectScrollbar];
},
@@ -39,26 +45,57 @@ BlazeComponent.extendComponent({
const labelIds = formComponent.labels.get();
const customFields = formComponent.customFields.get();
const boardId = this.data().board();
const board = this.data().board();
let linkedId = '';
let swimlaneId = '';
const boardView = Meteor.user().profile.boardView;
if (boardView === 'board-view-swimlanes')
swimlaneId = this.parentComponent().parentComponent().data()._id;
else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal'))
swimlaneId = boardId.getDefaultSwimline()._id;
const boardView = (Meteor.user().profile || {}).boardView;
let cardType = 'cardType-card';
if (title) {
if (board.isTemplatesBoard()) {
swimlaneId = this.parentComponent().parentComponent().data()._id; // Always swimlanes view
const swimlane = Swimlanes.findOne(swimlaneId);
// If this is the card templates swimlane, insert a card template
if (swimlane.isCardTemplatesSwimlane())
cardType = 'template-card';
// If this is the board templates swimlane, insert a board template and a linked card
else if (swimlane.isBoardTemplatesSwimlane()) {
linkedId = Boards.insert({
title,
permission: 'private',
type: 'template-board',
});
Swimlanes.insert({
title: TAPi18n.__('default'),
boardId: linkedId,
});
cardType = 'cardType-linkedBoard';
}
} else if (boardView === 'board-view-swimlanes')
swimlaneId = this.parentComponent().parentComponent().data()._id;
else if ((boardView === 'board-view-lists') || (boardView === 'board-view-cal') || !boardView)
swimlaneId = board.getDefaultSwimline()._id;
const _id = Cards.insert({
title,
members,
labelIds,
customFields,
listId: this.data()._id,
boardId: boardId._id,
boardId: board._id,
sort: sortIndex,
swimlaneId,
type: 'cardType-card',
type: cardType,
linkedId,
});
// if the displayed card count is less than the total cards in the list,
// we need to increment the displayed card count to prevent the spinner
// to appear
const cardCount = this.data().cards(this.idOrNull(swimlaneId)).count();
if (this.cardlimit.get() < cardCount) {
this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter);
}
// In case the filter is active we need to add the newly inserted card in
// the list of exceptions -- cards that are not filtered. Otherwise the
// card will disappear instantly.
@@ -90,9 +127,9 @@ BlazeComponent.extendComponent({
const methodName = evt.shiftKey ? 'toggleRange' : 'toggle';
MultiSelection[methodName](this.currentData()._id);
// If the card is already selected, we want to de-select it.
// XXX We should probably modify the minicard href attribute instead of
// overwriting the event in case the card is already selected.
// If the card is already selected, we want to de-select it.
// XXX We should probably modify the minicard href attribute instead of
// overwriting the event in case the card is already selected.
} else if (Session.equals('currentCard', this.currentData()._id)) {
evt.stopImmediatePropagation();
evt.preventDefault();
@@ -112,11 +149,31 @@ BlazeComponent.extendComponent({
idOrNull(swimlaneId) {
const currentUser = Meteor.user();
if (currentUser.profile.boardView === 'board-view-swimlanes')
if ((currentUser.profile || {}).boardView === 'board-view-swimlanes' ||
this.data().board().isTemplatesBoard())
return swimlaneId;
return undefined;
},
cardsWithLimit(swimlaneId) {
const limit = this.cardlimit.get();
const selector = {
listId: this.currentData()._id,
archived: false,
};
if (swimlaneId)
selector.swimlaneId = swimlaneId;
return Cards.find(Filter.mongoSelector(selector), {
sort: ['sort'],
limit,
});
},
showSpinner(swimlaneId) {
const list = Template.currentData();
return list.cards(swimlaneId).count() > this.cardlimit.get();
},
canSeeAddCard() {
return !this.reachedWipLimit() && Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
},
@@ -152,6 +209,14 @@ BlazeComponent.extendComponent({
this.labels = new ReactiveVar([]);
this.members = new ReactiveVar([]);
this.customFields = new ReactiveVar([]);
const currentBoardId = Session.get('currentBoard');
arr = [];
_.forEach(Boards.findOne(currentBoardId).customFields().fetch(), function(field){
if(field.automaticallyOnCard)
arr.push({_id: field._id, value: null});
});
this.customFields.set(arr);
},
reset() {
@@ -169,7 +234,7 @@ BlazeComponent.extendComponent({
pressKey(evt) {
// Pressing Enter should submit the card
if (evt.keyCode === 13) {
if (evt.keyCode === 13 && !evt.shiftKey) {
evt.preventDefault();
const $form = $(evt.currentTarget).closest('form');
// XXX For some reason $form.submit() does not work (it's probably a bug
@@ -178,8 +243,8 @@ BlazeComponent.extendComponent({
// work.
$form.find('button[type=submit]').click();
// Pressing Tab should open the form of the next column, and Maj+Tab go
// in the reverse order
// Pressing Tab should open the form of the next column, and Maj+Tab go
// in the reverse order
} else if (evt.keyCode === 9) {
evt.preventDefault();
const isReverse = evt.shiftKey;
@@ -201,7 +266,8 @@ BlazeComponent.extendComponent({
return [{
keydown: this.pressKey,
'click .js-link': Popup.open('linkCard'),
'click .js-search': Popup.open('searchCard'),
'click .js-search': Popup.open('searchElement'),
'click .js-card-template': Popup.open('searchElement'),
}];
},
@@ -239,7 +305,7 @@ BlazeComponent.extendComponent({
const currentBoard = Boards.findOne(Session.get('currentBoard'));
callback($.map(currentBoard.labels, (label) => {
if (label.name.indexOf(term) > -1 ||
label.color.indexOf(term) > -1) {
label.color.indexOf(term) > -1) {
return label;
}
return null;
@@ -276,23 +342,13 @@ BlazeComponent.extendComponent({
BlazeComponent.extendComponent({
onCreated() {
// Prefetch first non-current board id
const boardId = Boards.findOne({
archived: false,
'members.userId': Meteor.userId(),
_id: {$ne: Session.get('currentBoard')},
}, {
sort: ['title'],
})._id;
// Subscribe to this board
subManager.subscribe('board', boardId);
this.selectedBoardId = new ReactiveVar(boardId);
this.selectedBoardId = new ReactiveVar('');
this.selectedSwimlaneId = new ReactiveVar('');
this.selectedListId = new ReactiveVar('');
this.boardId = Session.get('currentBoard');
// In order to get current board info
subManager.subscribe('board', this.boardId);
subManager.subscribe('board', this.boardId, false);
this.board = Boards.findOne(this.boardId);
// List where to insert card
const list = $(Popup._getTopStack().openerElement).closest('.js-list');
@@ -300,10 +356,10 @@ BlazeComponent.extendComponent({
// Swimlane where to insert card
const swimlane = $(Popup._getTopStack().openerElement).closest('.js-swimlane');
this.swimlaneId = '';
const boardView = Meteor.user().profile.boardView;
const boardView = (Meteor.user().profile || {}).boardView;
if (boardView === 'board-view-swimlanes')
this.swimlaneId = Blaze.getData(swimlane[0])._id;
else if (boardView === 'board-view-lists')
else if (boardView === 'board-view-lists' || !boardView)
this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
},
@@ -312,6 +368,7 @@ BlazeComponent.extendComponent({
archived: false,
'members.userId': Meteor.userId(),
_id: {$ne: Session.get('currentBoard')},
type: 'board',
}, {
sort: ['title'],
});
@@ -319,7 +376,7 @@ BlazeComponent.extendComponent({
},
swimlanes() {
if (!this.selectedBoardId) {
if (!this.selectedBoardId.get()) {
return [];
}
const swimlanes = Swimlanes.find({boardId: this.selectedBoardId.get()});
@@ -329,7 +386,7 @@ BlazeComponent.extendComponent({
},
lists() {
if (!this.selectedBoardId) {
if (!this.selectedBoardId.get()) {
return [];
}
const lists = Lists.find({boardId: this.selectedBoardId.get()});
@@ -350,13 +407,14 @@ BlazeComponent.extendComponent({
archived: false,
linkedId: {$nin: ownCardsIds},
_id: {$nin: ownCardsIds},
type: {$nin: ['template-card']},
});
},
events() {
return [{
'change .js-select-boards'(evt) {
subManager.subscribe('board', $(evt.currentTarget).val());
subManager.subscribe('board', $(evt.currentTarget).val(), false);
this.selectedBoardId.set($(evt.currentTarget).val());
},
'change .js-select-swimlanes'(evt) {
@@ -417,35 +475,49 @@ BlazeComponent.extendComponent({
},
onCreated() {
// Prefetch first non-current board id
let board = Boards.findOne({
archived: false,
'members.userId': Meteor.userId(),
_id: {$ne: Session.get('currentBoard')},
});
this.isCardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-card-template');
this.isListTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-list-template');
this.isSwimlaneTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-open-add-swimlane-menu');
this.isBoardTemplateSearch = $(Popup._getTopStack().openerElement).hasClass('js-add-board');
this.isTemplateSearch = this.isCardTemplateSearch ||
this.isListTemplateSearch ||
this.isSwimlaneTemplateSearch ||
this.isBoardTemplateSearch;
let board = {};
if (this.isTemplateSearch) {
board = Boards.findOne((Meteor.user().profile || {}).templatesBoardId);
} else {
// Prefetch first non-current board id
board = Boards.findOne({
archived: false,
'members.userId': Meteor.userId(),
_id: {$nin: [Session.get('currentBoard'), (Meteor.user().profile || {}).templatesBoardId]},
});
}
if (!board) {
Popup.close();
return;
}
const boardId = board._id;
// Subscribe to this board
subManager.subscribe('board', boardId);
subManager.subscribe('board', boardId, false);
this.selectedBoardId = new ReactiveVar(boardId);
this.boardId = Session.get('currentBoard');
// In order to get current board info
subManager.subscribe('board', this.boardId);
board = Boards.findOne(this.boardId);
// List where to insert card
const list = $(Popup._getTopStack().openerElement).closest('.js-list');
this.listId = Blaze.getData(list[0])._id;
// Swimlane where to insert card
const swimlane = $(Popup._getTopStack().openerElement).closest('.js-swimlane');
this.swimlaneId = '';
if (board.view === 'board-view-swimlanes')
this.swimlaneId = Blaze.getData(swimlane[0])._id;
else
this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
if (!this.isBoardTemplateSearch) {
this.boardId = Session.get('currentBoard');
// In order to get current board info
subManager.subscribe('board', this.boardId, false);
this.swimlaneId = '';
// Swimlane where to insert card
const swimlane = $(Popup._getTopStack().openerElement).parents('.js-swimlane');
if ((Meteor.user().profile || {}).boardView === 'board-view-swimlanes')
this.swimlaneId = Blaze.getData(swimlane[0])._id;
else
this.swimlaneId = Swimlanes.findOne({boardId: this.boardId})._id;
// List where to insert card
const list = $(Popup._getTopStack().openerElement).closest('.js-list');
this.listId = Blaze.getData(list[0])._id;
}
this.term = new ReactiveVar('');
},
@@ -454,6 +526,7 @@ BlazeComponent.extendComponent({
archived: false,
'members.userId': Meteor.userId(),
_id: {$ne: Session.get('currentBoard')},
type: 'board',
}, {
sort: ['title'],
});
@@ -465,13 +538,27 @@ BlazeComponent.extendComponent({
return [];
}
const board = Boards.findOne(this.selectedBoardId.get());
return board.searchCards(this.term.get(), false);
if (!this.isTemplateSearch || this.isCardTemplateSearch) {
return board.searchCards(this.term.get(), false);
} else if (this.isListTemplateSearch) {
return board.searchLists(this.term.get());
} else if (this.isSwimlaneTemplateSearch) {
return board.searchSwimlanes(this.term.get());
} else if (this.isBoardTemplateSearch) {
const boards = board.searchBoards(this.term.get());
boards.forEach((board) => {
subManager.subscribe('board', board.linkedId, false);
});
return boards;
} else {
return [];
}
},
events() {
return [{
'change .js-select-boards'(evt) {
subManager.subscribe('board', $(evt.currentTarget).val());
subManager.subscribe('board', $(evt.currentTarget).val(), false);
this.selectedBoardId.set($(evt.currentTarget).val());
},
'submit .js-search-term-form'(evt) {
@@ -479,20 +566,99 @@ BlazeComponent.extendComponent({
this.term.set(evt.target.searchTerm.value);
},
'click .js-minicard'(evt) {
// LINK CARD
const card = Blaze.getData(evt.currentTarget);
const _id = Cards.insert({
title: card.title, //dummy
listId: this.listId,
swimlaneId: this.swimlaneId,
boardId: this.boardId,
sort: Lists.findOne(this.listId).cards().count(),
type: 'cardType-linkedCard',
linkedId: card.linkedId || card._id,
});
Filter.addException(_id);
// 0. Common
const title = $('.js-element-title').val().trim();
if (!title)
return;
const element = Blaze.getData(evt.currentTarget);
element.title = title;
let _id = '';
if (!this.isTemplateSearch || this.isCardTemplateSearch) {
// Card insertion
// 1. Common
element.sort = Lists.findOne(this.listId).cards().count();
// 1.A From template
if (this.isTemplateSearch) {
element.type = 'cardType-card';
element.linkedId = '';
_id = element.copy(this.boardId, this.swimlaneId, this.listId);
// 1.B Linked card
} else {
delete element._id;
element.type = 'cardType-linkedCard';
element.linkedId = element.linkedId || element._id;
_id = Cards.insert(element);
}
Filter.addException(_id);
// List insertion
} else if (this.isListTemplateSearch) {
element.sort = Swimlanes.findOne(this.swimlaneId).lists().count();
element.type = 'list';
_id = element.copy(this.boardId, this.swimlaneId);
} else if (this.isSwimlaneTemplateSearch) {
element.sort = Boards.findOne(this.boardId).swimlanes().count();
element.type = 'swimlalne';
_id = element.copy(this.boardId);
} else if (this.isBoardTemplateSearch) {
board = Boards.findOne(element.linkedId);
board.sort = Boards.find({archived: false}).count();
board.type = 'board';
board.title = element.title;
delete board.slug;
_id = board.copy();
}
Popup.close();
},
}];
},
}).register('searchCardPopup');
}).register('searchElementPopup');
BlazeComponent.extendComponent({
onCreated() {
this.cardlimit = this.parentComponent().cardlimit;
this.listId = this.parentComponent().data()._id;
this.swimlaneId = '';
const boardView = (Meteor.user().profile || {}).boardView;
if (boardView === 'board-view-swimlanes')
this.swimlaneId = this.parentComponent().parentComponent().parentComponent().data()._id;
},
onRendered() {
this.spinner = this.find('.sk-spinner-list');
this.container = this.$(this.spinner).parents('.js-perfect-scrollbar')[0];
$(this.container).on(`scroll.spinner_${this.swimlaneId}_${this.listId}`, () => this.updateList());
$(window).on(`resize.spinner_${this.swimlaneId}_${this.listId}`, () => this.updateList());
this.updateList();
},
onDestroyed() {
$(this.container).off(`scroll.spinner_${this.swimlaneId}_${this.listId}`);
$(window).off(`resize.spinner_${this.swimlaneId}_${this.listId}`);
},
updateList() {
if (this.spinnerInView()) {
this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter);
window.requestIdleCallback(() => this.updateList());
}
},
spinnerInView() {
const parentViewHeight = this.container.clientHeight;
const bottomViewPosition = this.container.scrollTop + parentViewHeight;
const threshold = this.spinner.offsetTop;
// spinner deleted
if (!this.spinner.offsetTop) {
return false;
}
return bottomViewPosition > threshold;
},
}).register('spinnerList');
+20 -5
View File
@@ -1,5 +1,7 @@
template(name="listHeader")
.list-header.js-list-header
.list-header.js-list-header(
class="{{#if limitToShowCardsCount}}list-header-card-count{{/if}}"
class="{{#if colorClass}}list-header-{{colorClass}}{{/if}}")
+inlinedForm
+editListTitleForm
else
@@ -8,16 +10,16 @@ template(name="listHeader")
a.list-header-left-icon.fa.fa-angle-left.js-unselect-list
h2.list-header-name(
class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
= title
+viewer
= title
if wipLimit.enabled
|&nbsp;(
span(class="{{#if reachedWipLimit}}highlight{{/if}}") {{cards.count}}
|/#{wipLimit.value})
if showCardsCountForList cards.count
= cards.count
span
| {{_ 'cards-count'}}
|&nbsp;
span(class="cardCount") {{cardsCount}} {{_ 'cards-count'}}
if isMiniScreen
if currentList
if isWatching
@@ -50,6 +52,9 @@ template(name="listActionPopup")
li: a.js-toggle-watch-list {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}}
unless currentUser.isCommentOnly
hr
ul.pop-over-list
li: a.js-set-color-list {{_ 'set-color-list'}}
hr
ul.pop-over-list
if cards.count
li: a.js-select-cards {{_ 'list-select-cards'}}
@@ -112,3 +117,13 @@ template(name="wipLimitErrorPopup")
p {{_ 'wipLimitErrorPopup-dialog-pt1'}}
p {{_ 'wipLimitErrorPopup-dialog-pt2'}}
button.full.js-back-view(type="submit") {{_ 'cancel'}}
template(name="setListColorPopup")
form.edit-label
.palette-colors: each colors
// note: we use the swimlane palette to have more than just the border
span.card-label.palette-color.js-palette-color(class="swimlane-{{color}}")
if(isSelected color)
i.fa.fa-check
button.primary.confirm.js-submit {{_ 'save'}}
button.js-remove-color.negate.wide.right {{_ 'unset-color'}}
+47
View File
@@ -1,3 +1,8 @@
let listsColors;
Meteor.startup(() => {
listsColors = Lists.simpleSchema()._schema.color.allowedValues;
});
BlazeComponent.extendComponent({
canSeeAddCard() {
const list = Template.currentData();
@@ -22,6 +27,16 @@ BlazeComponent.extendComponent({
return Meteor.user().getLimitToShowCardsCount();
},
cardsCount() {
const list = Template.currentData();
let swimlaneId = '';
const boardView = (Meteor.user().profile || {}).boardView;
if (boardView === 'board-view-swimlanes')
swimlaneId = this.parentComponent().parentComponent().data()._id;
return list.cards(swimlaneId).count();
},
reachedWipLimit() {
const list = Template.currentData();
return list.getWipLimit('enabled') && list.getWipLimit('value') <= list.cards().count();
@@ -62,6 +77,7 @@ Template.listActionPopup.helpers({
Template.listActionPopup.events({
'click .js-list-subscribe' () {},
'click .js-set-color-list': Popup.open('setListColor'),
'click .js-select-cards' () {
const cardIds = this.allCards().map((card) => card._id);
MultiSelection.add(cardIds);
@@ -144,3 +160,34 @@ Template.listMorePopup.events({
Utils.goBoardId(this.boardId);
}),
});
BlazeComponent.extendComponent({
onCreated() {
this.currentList = this.currentData();
this.currentColor = new ReactiveVar(this.currentList.color);
},
colors() {
return listsColors.map((color) => ({ color, name: '' }));
},
isSelected(color) {
return this.currentColor.get() === color;
},
events() {
return [{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
'click .js-submit' () {
this.currentList.setColor(this.currentColor.get());
Popup.close();
},
'click .js-remove-color'() {
this.currentList.setColor(null);
Popup.close();
},
}];
},
}).register('setListColorPopup');
+8
View File
@@ -0,0 +1,8 @@
template(name="minilist")
.minicard(
class="minicard-{{colorClass}}")
.minicard-title
.handle
.fa.fa-arrows
+viewer
= title
+2 -1
View File
@@ -1,5 +1,6 @@
template(name="editor")
textarea.editor(
dir="auto"
class="{{class}}"
id=id
autofocus=autofocus
@@ -7,7 +8,7 @@ template(name="editor")
+Template.contentBlock
template(name="viewer")
.viewer
.viewer(dir="auto")
+mentions
+markdown
{{> UI.contentBlock }}
+3 -1
View File
@@ -36,7 +36,10 @@ import sanitizeXss from 'xss';
const at = HTML.CharRef({html: '&commat;', str: '@'});
Blaze.Template.registerHelper('mentions', new Template('mentions', function() {
const view = this;
let content = Blaze.toHTML(view.templateContentBlock);
const currentBoard = Boards.findOne(Session.get('currentBoard'));
if (!currentBoard)
return HTML.Raw(sanitizeXss(content));
const knowedUsers = currentBoard.members.map((member) => {
const u = Users.findOne(member.userId);
if(u){
@@ -45,7 +48,6 @@ Blaze.Template.registerHelper('mentions', new Template('mentions', function() {
return member;
});
const mentionRegex = /\B@([\w.]*)/gi;
let content = Blaze.toHTML(view.templateContentBlock);
let currentMention;
while ((currentMention = mentionRegex.exec(content)) !== null) {
+34 -36
View File
@@ -4,39 +4,38 @@ template(name="header")
list all starred boards with a link to go there. This is inspired by the
Reddit "subreddit" bar.
The first link goes to the boards page.
unless isSandstorm
if currentUser
#header-quick-access(class=currentBoard.colorClass)
if isMiniScreen
ul
li
a(href="{{pathFor 'home'}}")
span.fa.fa-home
if currentUser
#header-quick-access(class=currentBoard.colorClass)
if isMiniScreen
ul
li
a(href="{{pathFor 'home'}}")
span.fa.fa-home
if currentList
each currentBoard.lists
li(class="{{#if $.Session.equals 'currentList' _id}}current{{/if}}")
a.js-select-list
= title
#header-new-board-icon
else
ul
li
a(href="{{pathFor 'home'}}")
span.fa.fa-home
| {{_ 'all-boards'}}
each currentUser.starredBoards
li.separator -
li(class="{{#if $.Session.equals 'currentBoard' _id}}current{{/if}}")
a(href="{{pathFor 'board' id=_id slug=slug}}")
if currentList
each currentBoard.lists
li(class="{{#if $.Session.equals 'currentList' _id}}current{{/if}}")
a.js-select-list
= title
else
li.current {{_ 'quick-access-description'}}
#header-new-board-icon
else
ul
li
a(href="{{pathFor 'home'}}")
span.fa.fa-home
| {{_ 'all-boards'}}
each currentUser.starredBoards
li.separator -
li(class="{{#if $.Session.equals 'currentBoard' _id}}current{{/if}}")
a(href="{{pathFor 'board' id=_id slug=slug}}")
= title
else
li.current {{_ 'quick-access-description'}}
a#header-new-board-icon.js-create-board
i.fa.fa-plus(title="Create a new board")
a#header-new-board-icon.js-create-board
i.fa.fa-plus(title="Create a new board")
+headerUserBar
+headerUserBar
#header(class=currentBoard.colorClass)
//-
@@ -46,17 +45,16 @@ template(name="header")
#header-main-bar(class="{{#if wrappedHeader}}wrapper{{/if}}")
+Template.dynamic(template=headerBar)
unless hideLogo
//unless hideLogo
//-
On sandstorm, the logo shouldn't be clickable, because we only have one
page/document on it, and we don't want to see the home page containing
the list of all boards.
if isSandstorm
.wekan-logo
img(src="{{pathFor '/wekan-logo-header.png'}}" alt="Wekan")
else
a.wekan-logo(href="{{pathFor 'home'}}" title="{{_ 'header-logo-title'}}")
img(src="{{pathFor '/wekan-logo-header.png'}}" alt="Wekan")
// unless currentSetting.hideLogo
// a.wekan-logo(href="{{pathFor 'home'}}" title="{{_ 'header-logo-title'}}")
// img(src="{{pathFor '/logo-header.png'}}" alt="")
if appIsOffline
+offlineWarning
+5
View File
@@ -1,11 +1,16 @@
Meteor.subscribe('user-admin');
Meteor.subscribe('boards');
Meteor.subscribe('setting');
Template.header.helpers({
wrappedHeader() {
return !Session.get('currentBoard');
},
currentSetting() {
return Settings.findOne();
},
hideLogo() {
return Utils.isMiniScreen() && Session.get('currentBoard');
},
-2
View File
@@ -188,8 +188,6 @@
width: 100%
padding: 10px 0px
z-index: 30
position: absolute
bottom: 0px
ul
width: calc(100% - 60px)
+29 -18
View File
@@ -1,7 +1,6 @@
head
title Wekan
meta(name="viewport"
content="maximum-scale=1.0,width=device-width,initial-scale=1.0,user-scalable=0")
title
meta(name="viewport" content="maximum-scale=1.0,width=device-width,initial-scale=1.0,user-scalable=0")
meta(http-equiv="X-UA-Compatible" content="IE=edge")
//- XXX We should use pathFor in the following `href` to support the case
where the application is deployed with a path prefix, but it seems to be
@@ -9,31 +8,32 @@ head
packages.
link(rel="shortcut icon" href="/wekan-favicon.png")
link(rel="apple-touch-icon" href="/wekan-favicon.png")
link(rel="mask-icon" href="/wekan-150.svg")
link(rel="mask-icon" href="/wekan-logo-150.svg")
link(rel="manifest" href="/wekan-manifest.json")
template(name="userFormsLayout")
section.auth-layout
h1.at-form-landing-logo
img(src="{{pathFor '/wekan-logo.png'}}" alt="Wekan")
section.auth-dialog
+Template.dynamic(template=content)
+connectionMethod
if isCas
.at-form
button#cas(class='at-btn submit' type='submit') {{casSignInLabel}}
div.at-form-lang
select.select-lang.js-userform-set-language
each languages
if isCurrentLanguage
option(value="{{tag}}" selected="selected") {{name}}
else
option(value="{{tag}}") {{name}}
if isLoading
+loader
else
+Template.dynamic(template=content)
if currentSetting.displayAuthenticationMethod
+connectionMethod(authenticationMethod=currentSetting.defaultAuthenticationMethod)
div.at-form-lang
select.select-lang.js-userform-set-language
each languages
if isCurrentLanguage
option(value="{{tag}}" selected="selected") {{name}}
else
option(value="{{tag}}") {{name}}
template(name="defaultLayout")
+header
#content
| {{{afterBodyStart}}}
+Template.dynamic(template=content)
| {{{beforeBodyEnd}}}
if (Modal.isOpen)
#modal
.overlay
@@ -59,3 +59,14 @@ template(name="message")
unless currentUser
with(pathFor route='atSignIn')
p {{{_ 'page-maybe-private' this}}}
template(name="loader")
h1.loadingText {{_ 'loading'}}
.lds-roller
div
div
div
div
div
div
div
+99 -54
View File
@@ -20,6 +20,19 @@ const validator = {
},
};
Template.userFormsLayout.onCreated(function() {
const instance = this;
instance.currentSetting = new ReactiveVar();
instance.isLoading = new ReactiveVar(false);
Meteor.subscribe('setting', {
onReady() {
instance.currentSetting.set(Settings.findOne());
return this.stop();
},
});
});
Template.userFormsLayout.onRendered(() => {
AccountsTemplates.state.form.keys = new Proxy(AccountsTemplates.state.form.keys, validator);
@@ -31,6 +44,22 @@ Template.userFormsLayout.onRendered(() => {
});
Template.userFormsLayout.helpers({
currentSetting() {
return Template.instance().currentSetting.get();
},
isLoading() {
return Template.instance().isLoading.get();
},
afterBodyStart() {
return currentSetting.customHTMLafterBodyStart;
},
beforeBodyEnd() {
return currentSetting.customHTMLbeforeBodyEnd;
},
languages() {
return _.map(TAPi18n.getLanguages(), (lang, code) => {
const tag = code;
@@ -39,6 +68,8 @@ Template.userFormsLayout.helpers({
name = 'Brezhoneg';
} else if (lang.name === 'ig') {
name = 'Igbo';
} else if (lang.name === 'oc') {
name = 'Occitan';
}
return { tag, name };
}).sort(function(a, b) {
@@ -55,17 +86,6 @@ Template.userFormsLayout.helpers({
const curLang = T9n.getLanguage() || 'en';
return t9nTag === curLang;
},
/*
isCas() {
return Meteor.settings.public &&
Meteor.settings.public.cas &&
Meteor.settings.public.cas.loginUrl;
},
casSignInLabel() {
return TAPi18n.__('casSignIn', {}, T9n.getLanguage() || 'en');
},
*/
});
Template.userFormsLayout.events({
@@ -74,49 +94,13 @@ Template.userFormsLayout.events({
T9n.setLanguage(i18nTagToT9n(i18nTag));
evt.preventDefault();
},
'click button#cas'() {
Meteor.loginWithCas(function() {
if (FlowRouter.getRouteName() === 'atSignIn') {
FlowRouter.go('/');
}
});
},
'click #at-btn'(event) {
/* All authentication method can be managed/called here.
!! DON'T FORGET to correctly fill the fields of the user during its creation if necessary authenticationMethod : String !!
*/
const authenticationMethodSelected = $('.select-authentication').val();
// Local account
if (authenticationMethodSelected === 'password') {
return;
}
// Stop submit #at-pwd-form
event.preventDefault();
event.stopImmediatePropagation();
const email = $('#at-field-username_and_email').val();
const password = $('#at-field-password').val();
// Ldap account
if (authenticationMethodSelected === 'ldap') {
// Check if the user can use the ldap connection
Meteor.subscribe('user-authenticationMethod', email, {
onReady() {
const user = Users.findOne();
if (user === undefined || user.authenticationMethod === 'ldap') {
// Use the ldap connection package
Meteor.loginWithLDAP(email, password, function(error) {
if (!error) {
// Connection
return FlowRouter.go('/');
}
return error;
});
}
return this.stop();
},
});
'click #at-btn'(event, instance) {
if (FlowRouter.getRouteName() === 'atSignIn') {
instance.isLoading.set(true);
authentication(event, instance)
.then(() => {
instance.isLoading.set(false);
});
}
},
});
@@ -126,3 +110,64 @@ Template.defaultLayout.events({
Modal.close();
},
});
async function authentication(event, instance) {
const match = $('#at-field-username_and_email').val();
const password = $('#at-field-password').val();
if (!match || !password) return undefined;
const result = await getAuthenticationMethod(instance.currentSetting.get(), match);
if (result === 'password') return undefined;
// Stop submit #at-pwd-form
event.preventDefault();
event.stopImmediatePropagation();
switch (result) {
case 'ldap':
return new Promise((resolve) => {
Meteor.loginWithLDAP(match, password, function() {
resolve(FlowRouter.go('/'));
});
});
case 'cas':
return new Promise((resolve) => {
Meteor.loginWithCas(match, password, function() {
resolve(FlowRouter.go('/'));
});
});
default:
return undefined;
}
}
function getAuthenticationMethod({displayAuthenticationMethod, defaultAuthenticationMethod}, match) {
if (displayAuthenticationMethod) {
return $('.select-authentication').val();
}
return getUserAuthenticationMethod(defaultAuthenticationMethod, match);
}
function getUserAuthenticationMethod(defaultAuthenticationMethod, match) {
return new Promise((resolve) => {
try {
Meteor.subscribe('user-authenticationMethod', match, {
onReady() {
const user = Users.findOne();
const authenticationMethod = user
? user.authenticationMethod
: defaultAuthenticationMethod;
resolve(authenticationMethod);
},
});
} catch(error) {
resolve(defaultAuthenticationMethod);
}
});
}
+104 -4
View File
@@ -61,7 +61,7 @@ body
display: block
float: right
font-size: 24px
.modal-content-wide
width: 800px
min-height: 0px
@@ -290,7 +290,7 @@ kbd
// Implement a thiner close icon as suggested in
// https://github.com/FortAwesome/Font-Awesome/issues/1540#issuecomment-68689950
.fa.fa-times-thin:before
content: '\00d7';
content: '\00d7'
.fa.fa-globe.colorful, .fa.fa-bell.colorful
color: #4caf50
@@ -385,8 +385,8 @@ a
@media screen and (max-width: 800px)
#content
margin: 1px 0px 49px 0px
height: calc(100% - 96px)
margin: 1px 0px 0px 0px
height: calc(100% - 0px)
> .wrapper
margin-top: 0px
@@ -399,3 +399,103 @@ a
height: 37px
margin: 8px 10px 0 0
width: 50px
.select-authentication
width: 100%
.auth-layout
display: flex
flex-direction: column
align-items: center
justify-content: center
height: 100%
.auth-dialog
margin: 0 !important
.loadingText
text-align: center
.lds-roller
display: block
margin: auto
position: relative
width: 64px
height: 64px
div
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite
transform-origin: 32px 32px
div:after
content: " "
display: block
position: absolute
width: 6px
height: 6px
border-radius: 50%
background: #dedede
margin: -3px 0 0 -3px
div:nth-child(1)
animation-delay: -0.036s
div:nth-child(1):after
top: 50px
left: 50px
div:nth-child(2)
animation-delay: -0.072s
div:nth-child(2):after
top: 54px
left: 45px
div:nth-child(3)
animation-delay: -0.108s
div:nth-child(3):after
top: 57px
left: 39px
div:nth-child(4)
animation-delay: -0.144s
div:nth-child(4):after
top: 58px
left: 32px
div:nth-child(5)
animation-delay: -0.18s
div:nth-child(5):after
top: 57px
left: 25px
div:nth-child(6)
animation-delay: -0.216s
div:nth-child(6):after
top: 54px
left: 19px
div:nth-child(7)
animation-delay: -0.252s
div:nth-child(7):after
top: 50px
left: 14px
div:nth-child(8)
animation-delay: -0.288s
div:nth-child(8):after
top: 45px
left: 10px
@keyframes lds-roller
0%
transform: rotate(0deg)
100%
transform: rotate(360deg)
@@ -36,7 +36,33 @@ template(name="boardActions")
div.trigger-text
| {{_'r-card'}}
div.trigger-button.js-add-arch-action.js-goto-rules
i.fa.fa-plus
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
| {{_'r-add-swimlane'}}
div.trigger-dropdown
input(id="swimlane-name",type=text,placeholder="{{_'r-name'}}")
div.trigger-button.js-add-swimlane-action.js-goto-rules
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
| {{_'r-create-card'}}
div.trigger-dropdown
input(id="card-name",type=text,placeholder="{{_'r-name'}}")
div.trigger-text
| {{_'r-in-list'}}
div.trigger-dropdown
input(id="list-name",type=text,placeholder="{{_'r-name'}}")
div.trigger-text
| {{_'r-in-swimlane'}}
div.trigger-dropdown
input(id="swimlane-name2",type=text,placeholder="{{_'r-name'}}")
div.trigger-button.js-create-card-action.js-goto-rules
i.fa.fa-plus
@@ -5,6 +5,52 @@ BlazeComponent.extendComponent({
events() {
return [{
'click .js-create-card-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const cardName = this.find('#card-name').value;
const listName = this.find('#list-name').value;
const swimlaneName = this.find('#swimlane-name2').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'createCard',
swimlaneName,
cardName,
listName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
'click .js-add-swimlane-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const swimlaneName = this.find('#swimlane-name').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addSwimlane',
swimlaneName,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
'click .js-add-spec-move-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
@@ -35,9 +35,21 @@ template(name="cardActions")
div.trigger-button.js-add-removeall-action.js-goto-rules
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
| {{{_'r-set-color'}}}
button.trigger-button.trigger-button-color.js-show-color-palette(
id="color-action"
class="card-details-{{cardColorButton}}")
| {{{_ cardColorButtonText }}}
div.trigger-button.js-set-color-action.js-goto-rules
i.fa.fa-plus
template(name="setCardActionsColorPopup")
form.edit-label
.palette-colors: each colors
span.card-label.palette-color.js-palette-color(class="card-details-{{color}}")
if(isSelected color)
i.fa.fa-check
button.primary.confirm.js-submit {{_ 'save'}}
@@ -1,6 +1,20 @@
let cardColors;
Meteor.startup(() => {
cardColors = Cards.simpleSchema()._schema.color.allowedValues;
});
BlazeComponent.extendComponent({
onCreated() {
this.subscribe('allRules');
this.cardColorButtonValue = new ReactiveVar('green');
},
cardColorButton() {
return this.cardColorButtonValue.get();
},
cardColorButtonText() {
return `color-${ this.cardColorButtonValue.get() }`;
},
labels() {
@@ -112,7 +126,63 @@ BlazeComponent.extendComponent({
boardId,
});
},
'click .js-show-color-palette'(event){
const funct = Popup.open('setCardActionsColor');
const colorButton = this.find('#color-action');
if (colorButton.value === '') {
colorButton.value = 'green';
}
funct.call(this, event);
},
'click .js-set-color-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const selectedColor = this.cardColorButtonValue.get();
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'setColor',
selectedColor,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
}];
},
}).register('cardActions');
BlazeComponent.extendComponent({
onCreated() {
this.currentAction = this.currentData();
this.colorButtonValue = Popup.getOpenerComponent().cardColorButtonValue;
this.currentColor = new ReactiveVar(this.colorButtonValue.get());
},
colors() {
return cardColors.map((color) => ({ color, name: '' }));
},
isSelected(color) {
return this.currentColor.get() === color;
},
events() {
return [{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
'click .js-submit' () {
this.colorButtonValue.set(this.currentColor.get());
Popup.close();
},
}];
},
}).register('setCardActionsColorPopup');
@@ -43,6 +43,25 @@ template(name="checklistActions")
div.trigger-button.js-add-check-item-action.js-goto-rules
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
| {{{_'r-add-checklist'}}}
div.trigger-dropdown
input(id="checklist-name-3",type=text,placeholder="{{{_'r-name'}}}")
div.trigger-text
| {{{_'r-with-items'}}}
div.trigger-dropdown
input(id="checklist-items",type=text,placeholder="{{{_'r-items-list'}}}")
div.trigger-button.js-add-checklist-items-action.js-goto-rules
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
| {{{_'r-checklist-note'}}}
@@ -4,6 +4,29 @@ BlazeComponent.extendComponent({
},
events() {
return [{
'click .js-add-checklist-items-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
const checklistName = this.find('#checklist-name-3').value;
const checklistItems = this.find('#checklist-items').value;
const boardId = Session.get('currentBoard');
const desc = Utils.getTriggerActionDesc(event, this);
const triggerId = Triggers.insert(trigger);
const actionId = Actions.insert({
actionType: 'addChecklistWithItems',
checklistName,
checklistItems,
boardId,
desc,
});
Rules.insert({
title: ruleName,
triggerId,
actionId,
boardId,
});
},
'click .js-add-checklist-action' (event) {
const ruleName = this.data().ruleName.get();
const trigger = this.data().triggerVar.get();
+24 -1
View File
@@ -10,7 +10,10 @@
display: inline-block
float: left
margin: revert
.hide-element
display:none !important
.user-details
display:inline-block
.rules-btns-group
position: absolute
right: 0
@@ -120,6 +123,15 @@
.trigger-text
font-size: 16px
display:inline-block
.trigger-inline-button
font-size: 16px
display: inline;
padding: 6px;
border: 1px solid #eee
border-radius: 4px
box-shadow: inset -1px -1px 3px rgba(0,0,0,.05)
&:hover, &.is-active
box-shadow: 0 0 0 2px darken(white, 60%) inset
.trigger-text.trigger-text-email
margin-left: 5px;
margin-top: 10px;
@@ -160,6 +172,17 @@
box-shadow: 0 0 0 2px darken(white, 60%) inset
.trigger-button.trigger-button-email
top:30px
.trigger-button.trigger-button-person
right:-40px
.trigger-button.trigger-button-color
top: unset
position: unset
transform: unset
font-size: 16px
width:auto
padding-left: 10px
padding-right: 10px
height:40px
.trigger-item.trigger-item-mail
height:300px
+28 -1
View File
@@ -9,7 +9,13 @@ BlazeComponent.extendComponent({
setTrigger() {
this.rulesCurrentTab.set('trigger');
},
sanitizeObject(obj){
Object.keys(obj).forEach((key) => {
if(obj[key] === '' || obj[key] === undefined){
obj[key] = '*';
}}
);
},
setRulesList() {
this.rulesCurrentTab.set('rulesList');
},
@@ -42,8 +48,27 @@ BlazeComponent.extendComponent({
},
'click .js-goto-action' (event) {
event.preventDefault();
// Add user to the trigger
const username = $(event.currentTarget.offsetParent).find('.user-name').val();
let trigger = this.triggerVar.get();
trigger.userId = '*';
if(username !== undefined ){
const userFound = Users.findOne({username});
if(userFound !== undefined){
trigger.userId = userFound._id;
this.triggerVar.set(trigger);
}
}
// Sanitize trigger
trigger = this.triggerVar.get();
this.sanitizeObject(trigger);
this.triggerVar.set(trigger);
this.setAction();
},
'click .js-show-user-field' (event) {
event.preventDefault();
$(event.currentTarget.offsetParent).find('.user-details').removeClass('hide-element');
},
'click .js-goto-rules' (event) {
event.preventDefault();
this.setRulesList();
@@ -68,3 +93,5 @@ BlazeComponent.extendComponent({
},
}).register('rulesMain');
@@ -1,43 +1,58 @@
template(name="boardTriggers")
div.trigger-item
div.trigger-item#trigger-two
div.trigger-content
div.trigger-text
| {{_'r-when-a-card-is'}}
div.trigger-dropdown
select(id="gen-action")
option(value="created") {{_'r-added-to'}}
option(value="removed") {{_'r-removed-from'}}
| {{_'r-when-a-card'}}
div.trigger-inline-button.js-open-card-title-popup
i.fa.fa-filter
div.trigger-text
| {{_'r-the-board'}}
div.trigger-button.js-add-gen-trigger.js-goto-action
i.fa.fa-plus
div.trigger-item
div.trigger-content
| {{_'r-is'}}
div.trigger-text
| {{_'r-when-a-card-is'}}
div.trigger-dropdown
select(id="create-action")
option(value="created") {{_'r-added-to'}}
option(value="removed") {{_'r-removed-from'}}
| {{_'r-added-to'}}
div.trigger-text
| {{_'r-list'}}
div.trigger-dropdown
input(id="create-list-name",type=text,placeholder="{{_'r-list-name'}}")
input(id="create-list-name",type=text,placeholder="{{_'r-list-name'}}")
div.trigger-text
| {{_'r-in-swimlane'}}
div.trigger-dropdown
input(id="create-swimlane-name",type=text,placeholder="{{_'r-swimlane-name'}}")
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-create-trigger.js-goto-action
i.fa.fa-plus
div.trigger-item
div.trigger-item#trigger-three
div.trigger-content
div.trigger-text
| {{_'r-when-a-card-is-moved'}}
| {{_'r-when-a-card'}}
div.trigger-inline-button.js-open-card-title-popup
i.fa.fa-filter
div.trigger-text
| {{_'r-is-moved'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-gen-moved-trigger.js-goto-action
i.fa.fa-plus
div.trigger-item
div.trigger-item#trigger-four
div.trigger-content
div.trigger-text
| {{_'r-when-a-card-is'}}
| {{_'r-when-a-card'}}
div.trigger-inline-button.js-open-card-title-popup
i.fa.fa-filter
div.trigger-text
| {{_'r-is'}}
div.trigger-dropdown
select(id="move-action")
option(value="moved-to") {{_'r-moved-to'}}
@@ -45,21 +60,54 @@ template(name="boardTriggers")
div.trigger-text
| {{_'r-list'}}
div.trigger-dropdown
input(id="move-list-name",type=text,placeholder="{{_'r-list-name'}}")
input(id="move-list-name",type=text,placeholder="{{_'r-list-name'}}")
div.trigger-text
| {{_'r-in-swimlane'}}
div.trigger-dropdown
input(id="create-swimlane-name-2",type=text,placeholder="{{_'r-swimlane-name'}}")
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-moved-trigger.js-goto-action
i.fa.fa-plus
div.trigger-item
div.trigger-item#trigger-five
div.trigger-content
div.trigger-text
| {{_'r-when-a-card-is'}}
| {{_'r-when-a-card'}}
div.trigger-inline-button.js-open-card-title-popup
i.fa.fa-filter
div.trigger-text
| {{_'r-is'}}
div.trigger-dropdown
select(id="arch-action")
option(value="archived") {{_'r-archived'}}
option(value="unarchived") {{_'r-unarchived'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-arch-trigger.js-goto-action
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
| {{{_'r-board-note'}}}
template(name="boardCardTitlePopup")
form
label
| Card Title Filter
input.js-card-filter-name(type="text" value=title autofocus)
input.js-card-filter-button.primary.wide(type="submit" value="{{_ 'set-filter'}}")
@@ -1,67 +1,57 @@
BlazeComponent.extendComponent({
onCreated() {
this.provaVar = new ReactiveVar('');
this.currentPopupTriggerId = 'def';
this.cardTitleFilters = {};
},
setNameFilter(name){
this.cardTitleFilters[this.currentPopupTriggerId] = name;
},
events() {
return [{
'click .js-add-gen-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#gen-action').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'created') {
datas.triggerVar.set({
activityType: 'createCard',
boardId,
'listName': '*',
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removeCard',
boardId,
desc,
});
}
'click .js-open-card-title-popup'(event){
const funct = Popup.open('boardCardTitle');
const divId = $(event.currentTarget.parentNode.parentNode).attr('id');
//console.log('current popup');
//console.log(this.currentPopupTriggerId);
this.currentPopupTriggerId = divId;
funct.call(this, event);
},
'click .js-add-create-trigger' (event) {
const desc = Utils.getTriggerActionDesc(event, this);
const datas = this.data();
const actionSelected = this.find('#create-action').value;
const listName = this.find('#create-list-name').value;
const swimlaneName = this.find('#create-swimlane-name').value;
const boardId = Session.get('currentBoard');
if (actionSelected === 'created') {
datas.triggerVar.set({
activityType: 'createCard',
boardId,
listName,
desc,
});
}
if (actionSelected === 'removed') {
datas.triggerVar.set({
activityType: 'removeCard',
boardId,
listName,
desc,
});
}
const divId = $(event.currentTarget.parentNode).attr('id');
const cardTitle = this.cardTitleFilters[divId];
// move to generic funciont
datas.triggerVar.set({
activityType: 'createCard',
boardId,
cardTitle,
swimlaneName,
listName,
desc,
});
},
'click .js-add-moved-trigger' (event) {
const datas = this.data();
const desc = Utils.getTriggerActionDesc(event, this);
const swimlaneName = this.find('#create-swimlane-name-2').value;
const actionSelected = this.find('#move-action').value;
const listName = this.find('#move-list-name').value;
const boardId = Session.get('currentBoard');
const divId = $(event.currentTarget.parentNode).attr('id');
const cardTitle = this.cardTitleFilters[divId];
if (actionSelected === 'moved-to') {
datas.triggerVar.set({
activityType: 'moveCard',
boardId,
listName,
cardTitle,
swimlaneName,
'oldListName': '*',
desc,
});
@@ -70,6 +60,8 @@ BlazeComponent.extendComponent({
datas.triggerVar.set({
activityType: 'moveCard',
boardId,
cardTitle,
swimlaneName,
'listName': '*',
'oldListName': listName,
desc,
@@ -82,8 +74,9 @@ BlazeComponent.extendComponent({
const boardId = Session.get('currentBoard');
datas.triggerVar.set({
activityType: 'moveCard',
'activityType': 'moveCard',
boardId,
'swimlaneName': '*',
'listName':'*',
'oldListName': '*',
desc,
@@ -114,3 +107,13 @@ BlazeComponent.extendComponent({
},
}).register('boardTriggers');
Template.boardCardTitlePopup.events({
submit(evt, tpl) {
const title = tpl.$('.js-card-filter-name').val().trim();
Popup.getOpenerComponent().setNameFilter(title);
evt.preventDefault();
Popup.close();
},
});
@@ -1,79 +1,114 @@
template(name="cardTriggers")
div.trigger-item
div.trigger-content
div.trigger-text
div.trigger-text
| {{_'r-when-a-label-is'}}
div.trigger-dropdown
select(id="label-action")
option(value="added") {{_'r-added-to'}}
option(value="removed") {{_'r-removed-from'}}
div.trigger-text
div.trigger-text
| {{_'r-a-card'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-gen-label-trigger.js-goto-action
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
div.trigger-text
| {{_'r-when-the-label-is'}}
div.trigger-dropdown
select(id="spec-label")
each labels
option(value="#{_id}")
= name
div.trigger-text
option(value="#{_id}" style="background-color: #{name}")
= translatedname
div.trigger-text
| {{_'r-is'}}
div.trigger-dropdown
select(id="spec-label-action")
option(value="added") {{_'r-added-to'}}
option(value="removed") {{_'r-removed-from'}}
div.trigger-text
div.trigger-text
| {{_'r-a-card'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-spec-label-trigger.js-goto-action
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
div.trigger-text
| {{_'r-when-a-member'}}
div.trigger-dropdown
select(id="gen-member-action")
option(value="added") {{_'r-added-to'}}
option(value="removed") {{_'r-removed-from'}}
div.trigger-text
div.trigger-text
| {{_'r-a-card'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-gen-member-trigger.js-goto-action
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
div.trigger-text
| {{_'r-when-the-member'}}
div.trigger-dropdown
input(id="spec-member",type=text,placeholder="{{_'r-name'}}")
div.trigger-text
input(id="spec-member",type=text,placeholder="{{_'r-name'}}")
div.trigger-text
| {{_'r-is'}}
div.trigger-dropdown
select(id="spec-member-action")
option(value="added") {{_'r-added-to'}}
option(value="removed") {{_'r-removed-from'}}
div.trigger-text
div.trigger-text
| {{_'r-a-card'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-spec-member-trigger.js-goto-action
i.fa.fa-plus
div.trigger-item
div.trigger-content
div.trigger-text
div.trigger-text
| {{_'r-when-a-attach'}}
div.trigger-text
div.trigger-text
| {{_'r-is'}}
div.trigger-dropdown
select(id="attach-action")
option(value="added") {{_'r-added-to'}}
option(value="removed") {{_'r-removed-from'}}
div.trigger-text
div.trigger-text
| {{_'r-a-card'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-attachment-trigger.js-goto-action
i.fa.fa-plus
@@ -6,7 +6,10 @@ BlazeComponent.extendComponent({
const labels = Boards.findOne(Session.get('currentBoard')).labels;
for (let i = 0; i < labels.length; i++) {
if (labels[i].name === '' || labels[i].name === undefined) {
labels[i].name = labels[i].color.toUpperCase();
labels[i].name = labels[i].color;
labels[i].translatedname = `${TAPi18n.__(`color-${ labels[i].color}`)}`;
} else {
labels[i].translatedname = labels[i].name;
}
}
return labels;
@@ -9,6 +9,13 @@ template(name="checklistTriggers")
option(value="removed") {{_'r-removed-from'}}
div.trigger-text
| {{_'r-a-card'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-gen-check-trigger.js-goto-action
i.fa.fa-plus
@@ -27,6 +34,13 @@ template(name="checklistTriggers")
option(value="removed") {{_'r-removed-from'}}
div.trigger-text
| {{_'r-a-card'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-spec-check-trigger.js-goto-action
i.fa.fa-plus
@@ -38,6 +52,13 @@ template(name="checklistTriggers")
select(id="gen-comp-check-action")
option(value="completed") {{_'r-completed'}}
option(value="uncompleted") {{_'r-made-incomplete'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-gen-comp-trigger.js-goto-action
i.fa.fa-plus
@@ -53,6 +74,13 @@ template(name="checklistTriggers")
select(id="spec-comp-check-action")
option(value="completed") {{_'r-completed'}}
option(value="uncompleted") {{_'r-made-incomplete'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-spec-comp-trigger.js-goto-action
i.fa.fa-plus
@@ -64,6 +92,13 @@ template(name="checklistTriggers")
select(id="check-item-gen-action")
option(value="checked") {{_'r-checked'}}
option(value="unchecked") {{_'r-unchecked'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-gen-check-item-trigger.js-goto-action
i.fa.fa-plus
@@ -79,5 +114,12 @@ template(name="checklistTriggers")
select(id="check-item-spec-action")
option(value="checked") {{_'r-checked'}}
option(value="unchecked") {{_'r-unchecked'}}
div.trigger-button.trigger-button-person.js-show-user-field
i.fa.fa-user
div.user-details.hide-element
div.trigger-text
| {{_'r-by'}}
div.trigger-dropdown
input(class="user-name",type=text,placeholder="{{_'username'}}")
div.trigger-button.js-add-spec-check-item-trigger.js-goto-action
i.fa.fa-plus
@@ -2,5 +2,8 @@ template(name='connectionMethod')
div.at-form-authentication
label {{_ 'authentication-method'}}
select.select-authentication
each authentications
option(value="{{value}}") {{_ value}}
each authentications
if isSelected value
option(value="{{value}}" selected) {{_ value}}
else
option(value="{{value}}") {{_ value}}
@@ -31,4 +31,7 @@ Template.connectionMethod.helpers({
authentications() {
return Template.instance().authenticationMethods.get();
},
isSelected(match) {
return Template.instance().data.authenticationMethod === match;
},
});
@@ -17,7 +17,7 @@ template(name='statistics')
table
tbody
tr
th {{_ 'Wekan_version'}}
th Wekan {{_ 'info'}}
td {{statistics.version}}
tr
th {{_ 'Node_version'}}
+11 -3
View File
@@ -3,8 +3,13 @@ template(name="people")
unless currentUser.isAdmin
| {{_ 'error-notAuthorized'}}
else
.content-title
span {{_ 'people'}}
.content-title.ext-box
.ext-box-left
span {{_ 'people'}}
input#searchInput(placeholder="{{_ 'search'}}")
button#searchButton {{_ 'search'}}
.ext-box-right
span {{_ 'people-number'}} #{peopleNumber}
.content-body
.side-menu
ul
@@ -102,5 +107,8 @@ template(name="editUserPopup")
label
| {{_ 'password'}}
input.js-profile-password(type="password")
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
div
input#deleteButton.primary.wide(type="button" value="{{_ 'delete'}}")
input.primary.wide(type="submit" value="{{_ 'save'}}")
+44 -1
View File
@@ -8,6 +8,8 @@ BlazeComponent.extendComponent({
this.error = new ReactiveVar('');
this.loading = new ReactiveVar(false);
this.people = new ReactiveVar(true);
this.findUsersOptions = new ReactiveVar({});
this.number = new ReactiveVar(0);
this.page = new ReactiveVar(1);
this.loadNextPageLocked = false;
@@ -26,6 +28,33 @@ BlazeComponent.extendComponent({
});
});
},
events() {
return [{
'click #searchButton'() {
this.filterPeople();
},
'keydown #searchInput'(event) {
if (event.keyCode === 13 && !event.shiftKey) {
this.filterPeople();
}
},
}];
},
filterPeople() {
const value = $('#searchInput').first().val();
if (value === '') {
this.findUsersOptions.set({});
} else {
const regex = new RegExp(value, 'i');
this.findUsersOptions.set({
$or: [
{ username: regex },
{ 'profile.fullname': regex },
{ 'emails.address': regex },
],
});
}
},
loadNextPage() {
if (this.loadNextPageLocked === false) {
this.page.set(this.page.get() + 1);
@@ -49,9 +78,14 @@ BlazeComponent.extendComponent({
this.loading.set(w);
},
peopleList() {
return Users.find({}, {
const users = Users.find(this.findUsersOptions.get(), {
fields: {_id: true},
});
this.number.set(users.count());
return users;
},
peopleNumber() {
return this.number.get();
},
}).register('people');
@@ -64,6 +98,7 @@ Template.peopleRow.helpers({
Template.editUserPopup.onCreated(function() {
this.authenticationMethods = new ReactiveVar([]);
this.errorMessage = new ReactiveVar('');
Meteor.call('getAuthenticationsEnabled', (_, result) => {
if (result) {
@@ -95,6 +130,9 @@ Template.editUserPopup.helpers({
const selected = Users.findOne(userId).authenticationMethod;
return selected === 'ldap';
},
errorMessage() {
return Template.instance().errorMessage.get();
},
});
BlazeComponent.extendComponent({
@@ -186,4 +224,9 @@ Template.editUserPopup.events({
});
} else Popup.close();
},
'click #deleteButton'() {
Users.remove(this.userId);
Popup.close();
},
});
@@ -13,3 +13,36 @@ table
tr:nth-child(even)
background-color: #dddddd;
.ext-box
display: flex;
flex-direction: row;
height: 34px;
.ext-box-left
display: flex;
width: 40%
span
vertical-align: center;
line-height: 34px;
margin-right: 10px;
input, button
margin: 0 10px 0 0;
padding: 0;
button
min-width: 60px;
.content-wrapper
margin-top: 10px
.buttonsContainer
display: flex
input
margin: 0
div
margin: auto
+33 -2
View File
@@ -134,10 +134,41 @@ template(name='announcementSettings')
template(name='layoutSettings')
ul#layout-setting.setting-detail
//li.layout-form
.title {{_ 'hide-logo'}}
.form-group.flex
input.form-control#hide-logo(type="radio" name="hideLogo" value="true" checked="{{#if currentSetting.hideLogo}}checked{{/if}}")
span {{_ 'yes'}}
input.form-control#hide-logo(type="radio" name="hideLogo" value="false" checked="{{#unless currentSetting.hideLogo}}checked{{/unless}}")
span {{_ 'no'}}
li.layout-form
.title {{_ 'display-authentication-method'}}
.form-group.flex
input.form-control#display-authentication-method(type="radio" name="displayAuthenticationMethod" value="true" checked="{{#if currentSetting.displayAuthenticationMethod}}checked{{/if}}")
span {{_ 'yes'}}
input.form-control#display-authentication-method(type="radio" name="displayAuthenticationMethod" value="false" checked="{{#unless currentSetting.displayAuthenticationMethod}}checked{{/unless}}")
span {{_ 'no'}}
li.layout-form
.title {{_ 'default-authentication-method'}}
+selectAuthenticationMethod(authenticationMethod=currentSetting.defaultAuthenticationMethod)
li.layout-form
.title {{_ 'custom-product-name'}}
.form-group
input.form-control#product-name(type="text", placeholder="Wekan" value="{{currentSetting.productName}}")
input.form-control#product-name(type="text", placeholder="" value="{{currentSetting.productName}}")
li.layout-form
.title {{_ 'add-custom-html-after-body-start'}}
textarea#customHTMLafterBodyStart.form-control= currentSetting.customHTMLafterBodyStart
li.layout-form
.title {{_ 'add-custom-html-before-body-end'}}
textarea#customHTMLbeforeBodyEnd.form-control= currentSetting.customHTMLbeforeBodyEnd
li
button.js-save-layout.primary {{_ 'save'}}
template(name='selectAuthenticationMethod')
select#defaultAuthenticationMethod
each authentications
if isSelected value
option(value="{{value}}" selected) {{_ value}}
else
option(value="{{value}}") {{_ value}}
+50 -6
View File
@@ -59,6 +59,12 @@ BlazeComponent.extendComponent({
toggleTLS() {
$('#mail-server-tls').toggleClass('is-checked');
},
toggleHideLogo() {
$('#hide-logo').toggleClass('is-checked');
},
toggleDisplayAuthenticationMethod() {
$('#display-authentication-method').toggleClass('is-checked');
},
switchMenu(event) {
const target = $(event.target);
if (!target.hasClass('active')) {
@@ -84,7 +90,7 @@ BlazeComponent.extendComponent({
},
inviteThroughEmail() {
const emails = $('#email-to-invite').val().trim().split('\n').join(',').split(',');
const emails = $('#email-to-invite').val().toLowerCase().trim().split('\n').join(',').split(',');
const boardsToInvite = [];
$('.js-toggle-board-choose .materialCheckBox.is-checked').each(function () {
boardsToInvite.push($(this).data('id'));
@@ -135,11 +141,22 @@ BlazeComponent.extendComponent({
this.setLoading(true);
$('li').removeClass('has-error');
const productName = $('#product-name').val().trim();
const hideLogoChange = ($('input[name=hideLogo]:checked').val() === 'true');
const displayAuthenticationMethod = ($('input[name=displayAuthenticationMethod]:checked').val() === 'true');
const defaultAuthenticationMethod = $('#defaultAuthenticationMethod').val();
const customHTMLafterBodyStart = $('#customHTMLafterBodyStart').val().trim();
const customHTMLbeforeBodyEnd = $('#customHTMLbeforeBodyEnd').val().trim();
try {
const productName = $('#product-name').val().trim();
Settings.update(Settings.findOne()._id, {
$set: {
productName,
hideLogo: hideLogoChange,
customHTMLafterBodyStart,
customHTMLbeforeBodyEnd,
displayAuthenticationMethod,
defaultAuthenticationMethod,
},
});
} catch (e) {
@@ -148,21 +165,20 @@ BlazeComponent.extendComponent({
this.setLoading(false);
}
DocHead.setTitle(productName);
},
sendSMTPTestEmail() {
Meteor.call('sendSMTPTestEmail', (err, ret) => {
if (!err && ret) { /* eslint-disable no-console */
if (!err && ret) {
const message = `${TAPi18n.__(ret.message)}: ${ret.email}`;
console.log(message);
alert(message);
} else {
const reason = err.reason || '';
const message = `${TAPi18n.__(err.error)}\n${reason}`;
console.log(message, err);
alert(message);
}
/* eslint-enable no-console */
});
},
@@ -175,7 +191,9 @@ BlazeComponent.extendComponent({
'click button.js-email-invite': this.inviteThroughEmail,
'click button.js-save': this.saveMailServerInfo,
'click button.js-send-smtp-test-email': this.sendSMTPTestEmail,
'click a.js-toggle-hide-logo': this.toggleHideLogo,
'click button.js-save-layout': this.saveLayout,
'click a.js-toggle-display-authentication-method': this.toggleDisplayAuthenticationMethod,
}];
},
}).register('setting');
@@ -248,3 +266,29 @@ BlazeComponent.extendComponent({
}];
},
}).register('announcementSettings');
Template.selectAuthenticationMethod.onCreated(function() {
this.authenticationMethods = new ReactiveVar([]);
Meteor.call('getAuthenticationsEnabled', (_, result) => {
if (result) {
// TODO : add a management of different languages
// (ex {value: ldap, text: TAPi18n.__('ldap', {}, T9n.getLanguage() || 'en')})
this.authenticationMethods.set([
{value: 'password'},
// Gets only the authentication methods availables
...Object.entries(result).filter((e) => e[1]).map((e) => ({value: e[0]})),
]);
}
});
});
Template.selectAuthenticationMethod.helpers({
authentications() {
return Template.instance().authenticationMethods.get();
},
isSelected(match) {
return Template.instance().data.authenticationMethod === match;
},
});
@@ -52,6 +52,10 @@
.main-body
padding: 0.1em 1em
-webkit-user-select: auto // Safari 3.1+
-moz-user-select: auto // Firefox 2+
-ms-user-select: auto // IE 10+
user-select: auto // Standard syntax
ul
li
+15 -16
View File
@@ -4,22 +4,21 @@ template(name="settingHeaderBar")
.setting-header-btns.left
unless isMiniScreen
unless isSandstorm
if currentUser
a.setting-header-btn.settings(href="{{pathFor 'setting'}}")
i.fa(class="fa-cog")
span {{_ 'settings'}}
if currentUser
a.setting-header-btn.settings(href="{{pathFor 'setting'}}")
i.fa(class="fa-cog")
span {{_ 'settings'}}
a.setting-header-btn.people(href="{{pathFor 'people'}}")
i.fa(class="fa-users")
span {{_ 'people'}}
a.setting-header-btn.people(href="{{pathFor 'people'}}")
i.fa(class="fa-users")
span {{_ 'people'}}
a.setting-header-btn.informations(href="{{pathFor 'information'}}")
i.fa(class="fa-info-circle")
span {{_ 'info'}}
a.setting-header-btn.informations(href="{{pathFor 'information'}}")
i.fa(class="fa-info-circle")
span {{_ 'info'}}
else
a.setting-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
else
a.setting-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
+144 -16
View File
@@ -1,9 +1,9 @@
template(name="sidebar")
.board-sidebar.sidebar(class="{{#if isOpen}}is-open{{/if}}")
a.sidebar-tongue.js-toggle-sidebar(
class="{{#if isTongueHidden}}is-hidden{{/if}}",
title="{{showTongueTitle}}")
i.fa.fa-angle-left
//a.sidebar-tongue.js-toggle-sidebar(
// class="{{#if isTongueHidden}}is-hidden{{/if}}",
// title="{{showTongueTitle}}")
// i.fa.fa-navicon
.sidebar-shadow
.sidebar-content.sidebar-shortcuts
a.board-header-btn.js-shortcuts
@@ -11,7 +11,7 @@ template(name="sidebar")
span {{_ 'keyboard-shortcuts' }}
.sidebar-content.js-board-sidebar-content.js-perfect-scrollbar
a.hide-btn.js-hide-sidebar
i.fa.fa-angle-right
i.fa.fa-navicon
unless isDefaultView
h2
a.fa.fa-chevron-left.js-back-home
@@ -34,6 +34,9 @@ template(name="membersWidget")
h3
i.fa.fa-user
| {{_ 'members'}}
a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right
i.board-header-btn-icon.fa.fa-cog
.board-widget-content
each currentBoard.activeMembers
+userAvatar(userId=this.userId showStatus=true)
@@ -53,6 +56,130 @@ template(name="membersWidget")
button.js-member-invite-accept.primary {{_ 'accept'}}
button.js-member-invite-decline {{_ 'decline'}}
template(name="boardChangeColorPopup")
.board-backgrounds-list.clearfix
each backgroundColors
.board-background-select.js-select-background
span.background-box(class="board-color-{{this}}")
if isSelected
i.fa.fa-check
template(name="boardSubtaskSettingsPopup")
form.board-subtask-settings
h3 {{_ 'show-parent-in-minicard'}}
a#prefix-with-full-path.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}")
span {{_ 'prefix-with-full-path'}}
a#prefix-with-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}")
span {{_ 'prefix-with-parent'}}
a#subtext-with-full-path.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}")
span {{_ 'subtext-with-full-path'}}
a#subtext-with-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}")
span {{_ 'subtext-with-parent'}}
a#no-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}")
.materialCheckBox(class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}")
span {{_ 'no-parent'}}
div
hr
div.check-div
a.flex.js-field-has-subtasks(class="{{#if allowsSubtasks}}is-checked{{/if}}")
.materialCheckBox(class="{{#if allowsSubtasks}}is-checked{{/if}}")
span {{_ 'show-subtasks-field'}}
label
| {{_ 'deposit-subtasks-board'}}
select.js-field-deposit-board(disabled="{{#unless allowsSubtasks}}disabled{{/unless}}")
each boards
if isBoardSelected
option(value=_id selected="selected") {{title}}
else
option(value=_id) {{title}}
if isNullBoardSelected
option(value='null' selected="selected") {{_ 'custom-field-dropdown-none'}}
else
option(value='null') {{_ 'custom-field-dropdown-none'}}
div
hr
label
| {{_ 'deposit-subtasks-list'}}
select.js-field-deposit-list(disabled="{{#unless hasLists}}disabled{{/unless}}")
each lists
if isListSelected
option(value=_id selected="selected") {{title}}
else
option(value=_id) {{title}}
template(name="chooseBoardSource")
ul.pop-over-list
li
a(href="{{pathFor '/import/trello'}}") {{_ 'from-trello'}}
li
a(href="{{pathFor '/import/wekan'}}") {{_ 'from-wekan'}}
template(name="archiveBoardPopup")
p {{_ 'close-board-pop'}}
button.js-confirm.negate.full(type="submit") {{_ 'archive'}}
template(name="outgoingWebhooksPopup")
each integrations
form.integration-form
if title
h4 {{title}}
else
h4 {{_ 'no-name'}}
label
| URL
input.js-outgoing-webhooks-url(type="text" name="url" value=url)
input(type="hidden" value=_id name="id")
input.primary.wide(type="submit" value="{{_ 'save'}}")
form.integration-form
h4
| {{_ 'new-outgoing-webhook'}}
label
| URL
input.js-outgoing-webhooks-url(type="text" name="url" autofocus)
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="boardMenuPopup")
ul.pop-over-list
li: a.js-custom-fields {{_ 'custom-fields'}}
li: a.js-open-archives {{_ 'archived-items'}}
if currentUser.isBoardAdmin
li: a.js-change-board-color {{_ 'board-change-color'}}
//-
XXX Language should be handled by sandstorm, but for now display a
language selection link in the board menu. This link is normally present
in the header bar that is not displayed on sandstorm.
if isSandstorm
li: a.js-change-language {{_ 'language'}}
unless isSandstorm
if currentUser.isBoardAdmin
hr
ul.pop-over-list
li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}}
unless currentBoard.isTemplatesBoard
li: a.js-archive-board {{_ 'archive-board'}}
li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}}
hr
ul.pop-over-list
li: a.js-subtask-settings {{_ 'subtask-settings'}}
if isSandstorm
hr
ul.pop-over-list
li: a(href="{{exportUrl}}", download="{{exportFilename}}") {{_ 'export-board'}}
li: a.js-import-board {{_ 'import-board-c'}}
li: a.js-archive-board {{_ 'archive-board'}}
li: a.js-outgoing-webhooks {{_ 'outgoing-webhooks'}}
hr
ul.pop-over-list
li: a.js-subtask-settings {{_ 'subtask-settings'}}
template(name="labelsWidget")
.board-widget.board-widget-labels
h3
@@ -62,7 +189,9 @@ template(name="labelsWidget")
each currentBoard.labels
a.card-label(class="card-label-{{color}}"
class="{{#if currentUser.isNotCommentOnly}}js-label{{/if}}")
span.card-label-name= name
span.card-label-name
+viewer
= name
if currentUser.isBoardAdmin
a.card-label.add-label.js-add-label
i.fa.fa-plus
@@ -83,17 +212,16 @@ template(name="memberPopup")
ul.pop-over-list
li
a.js-filter-member {{_ 'filter-cards'}}
unless isSandstorm
if currentUser.isBoardAdmin
li
a.js-change-role
| {{_ 'change-permissions'}}
span.quiet (#{memberType})
if currentUser.isBoardAdmin
li
if $eq currentUser._id userId
a.js-leave-member {{_ 'leave-board'}}
else if currentUser.isBoardAdmin
a.js-remove-member {{_ 'remove-from-board'}}
a.js-change-role
| {{_ 'change-permissions'}}
span.quiet (#{memberType})
li
if $eq currentUser._id userId
a.js-leave-member {{_ 'leave-board'}}
else if currentUser.isBoardAdmin
a.js-remove-member {{_ 'remove-from-board'}}
template(name="removeMemberPopup")
+224
View File
@@ -142,6 +142,52 @@ Template.memberPopup.helpers({
},
});
Template.boardMenuPopup.events({
'click .js-rename-board': Popup.open('boardChangeTitle'),
'click .js-custom-fields'() {
Sidebar.setView('customFields');
Popup.close();
},
'click .js-open-archives'() {
Sidebar.setView('archives');
Popup.close();
},
'click .js-change-board-color': Popup.open('boardChangeColor'),
'click .js-change-language': Popup.open('changeLanguage'),
'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
currentBoard.archive();
// XXX We should have some kind of notification on top of the page to
// confirm that the board was successfully archived.
FlowRouter.go('home');
}),
'click .js-delete-board': Popup.afterConfirm('deleteBoard', function() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
Popup.close();
Boards.remove(currentBoard._id);
FlowRouter.go('home');
}),
'click .js-outgoing-webhooks': Popup.open('outgoingWebhooks'),
'click .js-import-board': Popup.open('chooseBoardSource'),
'click .js-subtask-settings': Popup.open('boardSubtaskSettings'),
});
Template.boardMenuPopup.helpers({
exportUrl() {
const params = {
boardId: Session.get('currentBoard'),
};
const queryParams = {
authToken: Accounts._storedLoginToken(),
};
return FlowRouter.path('/api/boards/:boardId/export', params, queryParams);
},
exportFilename() {
const boardId = Session.get('currentBoard');
return `wekan-export-board-${boardId}.json`;
},
});
Template.memberPopup.events({
'click .js-filter-member'() {
Filter.members.toggle(this.userId);
@@ -190,7 +236,14 @@ Template.membersWidget.helpers({
Template.membersWidget.events({
'click .js-member': Popup.open('member'),
'click .js-open-board-menu': Popup.open('boardMenu'),
'click .js-manage-board-members': Popup.open('addMember'),
'click .js-import': Popup.open('boardImportBoard'),
submit: this.onSubmit,
'click .js-import-board': Popup.open('chooseBoardSource'),
'click .js-open-archived-board'() {
Modal.open('archivedBoards');
},
'click .sandstorm-powerbox-request-identity'() {
window.sandstormRequestIdentity();
},
@@ -209,6 +262,59 @@ Template.membersWidget.events({
},
});
BlazeComponent.extendComponent({
integrations() {
const boardId = Session.get('currentBoard');
return Integrations.find({ boardId: `${boardId}` }).fetch();
},
integration(id) {
const boardId = Session.get('currentBoard');
return Integrations.findOne({ _id: id, boardId: `${boardId}` });
},
events() {
return [{
'submit'(evt) {
evt.preventDefault();
const url = evt.target.url.value;
const boardId = Session.get('currentBoard');
let id = null;
let integration = null;
if (evt.target.id) {
id = evt.target.id.value;
integration = this.integration(id);
if (url) {
Integrations.update(integration._id, {
$set: {
url: `${url}`,
},
});
} else {
Integrations.remove(integration._id);
}
} else if (url) {
Integrations.insert({
userId: Meteor.userId(),
enabled: true,
type: 'outgoing-webhooks',
url: `${url}`,
boardId: `${boardId}`,
activities: ['all'],
});
}
Popup.close();
},
}];
},
}).register('outgoingWebhooksPopup');
BlazeComponent.extendComponent({
template() {
return 'chooseBoardSource';
},
}).register('chooseBoardSourcePopup');
Template.labelsWidget.events({
'click .js-label': Popup.open('editLabel'),
'click .js-add-label': Popup.open('createLabel'),
@@ -258,6 +364,124 @@ function draggableMembersLabelsWidgets() {
Template.membersWidget.onRendered(draggableMembersLabelsWidgets);
Template.labelsWidget.onRendered(draggableMembersLabelsWidgets);
BlazeComponent.extendComponent({
backgroundColors() {
return Boards.simpleSchema()._schema.color.allowedValues;
},
isSelected() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return currentBoard.color === this.currentData().toString();
},
events() {
return [{
'click .js-select-background'(evt) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const newColor = this.currentData().toString();
currentBoard.setColor(newColor);
evt.preventDefault();
},
}];
},
}).register('boardChangeColorPopup');
BlazeComponent.extendComponent({
onCreated() {
this.currentBoard = Boards.findOne(Session.get('currentBoard'));
},
allowsSubtasks() {
return this.currentBoard.allowsSubtasks;
},
isBoardSelected() {
return this.currentBoard.subtasksDefaultBoardId === this.currentData()._id;
},
isNullBoardSelected() {
return (this.currentBoard.subtasksDefaultBoardId === null) || (this.currentBoard.subtasksDefaultBoardId === undefined);
},
boards() {
return Boards.find({
archived: false,
'members.userId': Meteor.userId(),
}, {
sort: ['title'],
});
},
lists() {
return Lists.find({
boardId: this.currentBoard._id,
archived: false,
}, {
sort: ['title'],
});
},
hasLists() {
return this.lists().count() > 0;
},
isListSelected() {
return this.currentBoard.subtasksDefaultBoardId === this.currentData()._id;
},
presentParentTask() {
let result = this.currentBoard.presentParentTask;
if ((result === null) || (result === undefined)) {
result = 'no-parent';
}
return result;
},
events() {
return [{
'click .js-field-has-subtasks'(evt) {
evt.preventDefault();
this.currentBoard.allowsSubtasks = !this.currentBoard.allowsSubtasks;
this.currentBoard.setAllowsSubtasks(this.currentBoard.allowsSubtasks);
$('.js-field-has-subtasks .materialCheckBox').toggleClass('is-checked', this.currentBoard.allowsSubtasks);
$('.js-field-has-subtasks').toggleClass('is-checked', this.currentBoard.allowsSubtasks);
$('.js-field-deposit-board').prop('disabled', !this.currentBoard.allowsSubtasks);
},
'change .js-field-deposit-board'(evt) {
let value = evt.target.value;
if (value === 'null') {
value = null;
}
this.currentBoard.setSubtasksDefaultBoardId(value);
evt.preventDefault();
},
'change .js-field-deposit-list'(evt) {
this.currentBoard.setSubtasksDefaultListId(evt.target.value);
evt.preventDefault();
},
'click .js-field-show-parent-in-minicard'(evt) {
const value = evt.target.id || $(evt.target).parent()[0].id || $(evt.target).parent()[0].parent()[0].id;
const options = [
'prefix-with-full-path',
'prefix-with-parent',
'subtext-with-full-path',
'subtext-with-parent',
'no-parent'];
options.forEach(function(element) {
if (element !== value) {
$(`#${element} .materialCheckBox`).toggleClass('is-checked', false);
$(`#${element}`).toggleClass('is-checked', false);
}
});
$(`#${value} .materialCheckBox`).toggleClass('is-checked', true);
$(`#${value}`).toggleClass('is-checked', true);
this.currentBoard.setPresentParentTask(value);
evt.preventDefault();
},
}];
},
}).register('boardSubtaskSettingsPopup');
BlazeComponent.extendComponent({
onCreated() {
this.error = new ReactiveVar('');
+51 -33
View File
@@ -1,38 +1,56 @@
template(name="archivesSidebar")
+basicTabs(tabs=tabs)
+tabContent(slug="cards")
each archivedCards
.minicard-wrapper.js-minicard
+minicard(this)
if currentUser.isBoardMember
if isArchiveReady.get
+basicTabs(tabs=tabs)
+tabContent(slug="cards")
p.quiet
a.js-restore-card {{_ 'restore'}}
a.js-restore-all-cards {{_ 'restore-all'}}
| -
a.js-delete-card {{_ 'delete'}}
if cardIsInArchivedList
p.quiet.small ({{_ 'warn-list-archived'}})
else
p.no-items-message {{_ 'no-archived-cards'}}
+tabContent(slug="lists")
ul.archived-lists
each archivedLists
li.archived-lists-item
a.js-delete-all-cards {{_ 'delete-all'}}
each archivedCards
.minicard-wrapper.js-minicard
+minicard(this)
if currentUser.isBoardMember
button.js-restore-list
i.fa.fa-undo
= title
else
li.no-items-message {{_ 'no-archived-lists'}}
p.quiet
a.js-restore-card {{_ 'restore'}}
| -
a.js-delete-card {{_ 'delete'}}
if cardIsInArchivedList
p.quiet.small ({{_ 'warn-list-archived'}})
else
p.no-items-message {{_ 'no-archived-cards'}}
+tabContent(slug="swimlanes")
ul.archived-lists
each archivedSwimlanes
li.archived-lists-item
if currentUser.isBoardMember
button.js-restore-swimlane
i.fa.fa-undo
= title
else
li.no-items-message {{_ 'no-archived-swimlanes'}}
+tabContent(slug="lists")
p.quiet
a.js-restore-all-lists {{_ 'restore-all'}}
| -
a.js-delete-all-lists {{_ 'delete-all'}}
ul.archived-lists
each archivedLists
li.archived-lists-item
= title
if currentUser.isBoardMember
p.quiet
a.js-restore-list {{_ 'restore'}}
| -
a.js-delete-list {{_ 'delete'}}
else
li.no-items-message {{_ 'no-archived-lists'}}
+tabContent(slug="swimlanes")
p.quiet
a.js-restore-all-swimlanes {{_ 'restore-all'}}
| -
a.js-delete-all-swimlanes {{_ 'delete-all'}}
ul.archived-lists
each archivedSwimlanes
li.archived-lists-item
= title
if currentUser.isBoardMember
p.quiet
a.js-restore-swimlane {{_ 'restore'}}
| -
a.js-delete-swimlane {{_ 'delete'}}
else
li.no-items-message {{_ 'no-archived-swimlanes'}}
else
+spinner
@@ -1,4 +1,26 @@
const subManager = new SubsManager();
BlazeComponent.extendComponent({
onCreated() {
this.isArchiveReady = new ReactiveVar(false);
// The pattern we use to manually handle data loading is described here:
// https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/using-subs-manager
// XXX The boardId should be readed from some sort the component "props",
// unfortunatly, Blaze doesn't have this notion.
this.autorun(() => {
const currentBoardId = Session.get('currentBoard');
if (!currentBoardId)
return;
const handle = subManager.subscribe('board', currentBoardId, true);
Tracker.nonreactive(() => {
Tracker.autorun(() => {
this.isArchiveReady.set( handle.ready() );
});
});
});
},
tabs() {
return [
{ name: TAPi18n.__('cards'), slug: 'cards' },
@@ -44,19 +66,67 @@ BlazeComponent.extendComponent({
card.restore();
}
},
'click .js-restore-all-cards'() {
this.archivedCards().forEach((card) => {
if(card.canBeRestored()){
card.restore();
}
});
},
'click .js-delete-card': Popup.afterConfirm('cardDelete', function() {
const cardId = this._id;
Cards.remove(cardId);
Popup.close();
}),
'click .js-delete-all-cards': Popup.afterConfirm('cardDelete', () => {
this.archivedCards().forEach((card) => {
Cards.remove(card._id);
});
Popup.close();
}),
'click .js-restore-list'() {
const list = this.currentData();
list.restore();
},
'click .js-restore-all-lists'() {
this.archivedLists().forEach((list) => {
list.restore();
});
},
'click .js-delete-list': Popup.afterConfirm('listDelete', function() {
this.remove();
Popup.close();
}),
'click .js-delete-all-lists': Popup.afterConfirm('listDelete', () => {
this.archivedLists().forEach((list) => {
list.remove();
});
Popup.close();
}),
'click .js-restore-swimlane'() {
const swimlane = this.currentData();
swimlane.restore();
},
'click .js-restore-all-swimlanes'() {
this.archivedSwimlanes().forEach((swimlane) => {
swimlane.restore();
});
},
'click .js-delete-swimlane': Popup.afterConfirm('swimlaneDelete', function() {
this.remove();
Popup.close();
}),
'click .js-delete-all-swimlanes': Popup.afterConfirm('swimlaneDelete', () => {
this.archivedSwimlanes().forEach((swimlane) => {
swimlane.remove();
});
Popup.close();
}),
}];
},
}).register('archivesSidebar');
@@ -6,7 +6,9 @@ template(name="customFieldsSidebar")
div.minicard
a.fa.fa-pencil.js-edit-custom-field.minicard-edit-button
div.minicard-title
| {{ name }} ({{ type }})
+viewer
=name
| ({{ type }})
if currentUser.isBoardMember
hr
@@ -41,6 +43,16 @@ template(name="createCustomFieldPopup")
.materialCheckBox(class="{{#if showOnCard}}is-checked{{/if}}")
span {{_ 'show-field-on-card'}}
a.flex.js-field-automatically-on-card(class="{{#if automaticallyOnCard}}is-checked{{/if}}")
.materialCheckBox(class="{{#if automaticallyOnCard}}is-checked{{/if}}")
span {{_ 'automatically-field-on-card'}}
a.flex.js-field-showLabel-on-card(class="{{#if showLabelOnMiniCard}}is-checked{{/if}}")
.materialCheckBox(class="{{#if showLabelOnMiniCard}}is-checked{{/if}}")
span {{_ 'showLabel-field-on-card'}}
button.primary.wide.left(type="button")
| {{_ 'save'}}
if _id
@@ -2,7 +2,7 @@ BlazeComponent.extendComponent({
customFields() {
return CustomFields.find({
boardId: Session.get('currentBoard'),
boardIds: {$in: [Session.get('currentBoard')]},
});
},
@@ -83,19 +83,37 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({
$target.find('.materialCheckBox').toggleClass('is-checked');
$target.toggleClass('is-checked');
},
'click .js-field-automatically-on-card'(evt) {
let $target = $(evt.target);
if(!$target.hasClass('js-field-automatically-on-card')){
$target = $target.parent();
}
$target.find('.materialCheckBox').toggleClass('is-checked');
$target.toggleClass('is-checked');
},
'click .js-field-showLabel-on-card'(evt) {
let $target = $(evt.target);
if(!$target.hasClass('js-field-showLabel-on-card')){
$target = $target.parent();
}
$target.find('.materialCheckBox').toggleClass('is-checked');
$target.toggleClass('is-checked');
},
'click .primary'(evt) {
evt.preventDefault();
const data = {
boardId: Session.get('currentBoard'),
name: this.find('.js-field-name').value.trim(),
type: this.type.get(),
settings: this.getSettings(),
showOnCard: this.find('.js-field-show-on-card.is-checked') !== null,
showLabelOnMiniCard: this.find('.js-field-showLabel-on-card.is-checked') !== null,
automaticallyOnCard: this.find('.js-field-automatically-on-card.is-checked') !== null,
};
// insert or update
if (!this.data()._id) {
data.boardIds = [Session.get('currentBoard')];
CustomFields.insert(data);
} else {
CustomFields.update(this.data()._id, {$set: data});
@@ -104,8 +122,16 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({
Popup.back();
},
'click .js-delete-custom-field': Popup.afterConfirm('deleteCustomField', function() {
const customFieldId = this._id;
CustomFields.remove(customFieldId);
const customField = CustomFields.findOne(this._id);
if (customField.boardIds.length > 1) {
CustomFields.update(customField._id, {
$pull: {
boardIds: Session.get('currentBoard'),
},
});
} else {
CustomFields.remove(customField._id);
}
Popup.close();
}),
}];
@@ -1,6 +1,6 @@
template(name="searchSidebar")
form.js-search-term-form
input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus)
input(type="text" name="searchTerm" placeholder="{{_ 'search-example'}}" autofocus dir="auto")
.list-body.js-perfect-scrollbar
.minicards.clearfix.js-minicards
each (results)
@@ -0,0 +1,8 @@
template(name="miniswimlane")
.minicard(
class="minicard-{{colorClass}}")
.minicard-title
.handle
.fa.fa-arrows
+viewer
= title
+47 -10
View File
@@ -1,14 +1,21 @@
template(name="swimlaneHeader")
.swimlane-header-wrap.js-swimlane-header
+inlinedForm
+editSwimlaneTitleForm
.swimlane-header-wrap.js-swimlane-header(class='{{#if colorClass}}swimlane-{{colorClass}}{{/if}}')
if this.isTemplateContainer
+swimlaneFixedHeader(this)
else
.swimlane-header(
class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
= title
.swimlane-header-menu
unless currentUser.isCommentOnly
a.fa.fa-navicon.js-open-swimlane-menu
+inlinedForm
+editSwimlaneTitleForm
else
+swimlaneFixedHeader(this)
template(name="swimlaneFixedHeader")
.swimlane-header(
class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
= 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
template(name="editSwimlaneTitleForm")
.list-composer
@@ -20,4 +27,34 @@ template(name="editSwimlaneTitleForm")
template(name="swimlaneActionPopup")
unless currentUser.isCommentOnly
ul.pop-over-list
li: a.js-close-swimlane {{_ 'archive-swimlane'}}
li: a.js-set-swimlane-color {{_ 'select-color'}}
unless this.isTemplateContainer
hr
ul.pop-over-list
li: a.js-close-swimlane {{_ 'archive-swimlane'}}
template(name="swimlaneAddPopup")
unless currentUser.isCommentOnly
form
input.swimlane-name-input.full-line(type="text" placeholder="{{_ 'add-swimlane'}}"
autocomplete="off" autofocus)
.edit-controls.clearfix
button.primary.confirm(type="submit") {{_ 'add'}}
unless currentBoard.isTemplatesBoard
unless currentBoard.isTemplateBoard
span.quiet
| {{_ 'or'}}
a.js-swimlane-template {{_ 'template'}}
template(name="setSwimlaneColorPopup")
form.edit-label
.palette-colors: each colors
span.card-label.palette-color.js-palette-color(class="card-details-{{color}}")
if(isSelected color)
i.fa.fa-check
button.primary.confirm.js-submit {{_ 'save'}}
button.js-remove-color.negate.wide.right {{_ 'unset-color'}}
template(name="swimlaneDeletePopup")
p {{_ "swimlane-delete-pop"}}
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
@@ -1,3 +1,10 @@
const { calculateIndexData } = Utils;
let swimlaneColors;
Meteor.startup(() => {
swimlaneColors = Swimlanes.simpleSchema()._schema.color.allowedValues;
});
BlazeComponent.extendComponent({
editTitle(evt) {
evt.preventDefault();
@@ -11,15 +18,85 @@ BlazeComponent.extendComponent({
events() {
return [{
'click .js-open-swimlane-menu': Popup.open('swimlaneAction'),
'click .js-open-add-swimlane-menu': Popup.open('swimlaneAdd'),
submit: this.editTitle,
}];
},
}).register('swimlaneHeader');
Template.swimlaneActionPopup.events({
'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'),
'click .js-close-swimlane' (evt) {
evt.preventDefault();
this.archive();
Popup.close();
},
});
BlazeComponent.extendComponent({
onCreated() {
this.currentSwimlane = this.currentData();
},
events() {
return [{
submit(evt) {
evt.preventDefault();
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const nextSwimlane = currentBoard.nextSwimlane(this.currentSwimlane);
const titleInput = this.find('.swimlane-name-input');
const title = titleInput.value.trim();
const sortValue = calculateIndexData(this.currentSwimlane, nextSwimlane, 1);
const swimlaneType = (currentBoard.isTemplatesBoard())?'template-swimlane':'swimlane';
if (title) {
Swimlanes.insert({
title,
boardId: Session.get('currentBoard'),
sort: sortValue.base,
type: swimlaneType,
});
titleInput.value = '';
titleInput.focus();
}
// XXX ideally, we should move the popup to the newly
// created swimlane so a user can add more than one swimlane
// with a minimum of interactions
Popup.close();
},
'click .js-swimlane-template': Popup.open('searchElement'),
}];
},
}).register('swimlaneAddPopup');
BlazeComponent.extendComponent({
onCreated() {
this.currentSwimlane = this.currentData();
this.currentColor = new ReactiveVar(this.currentSwimlane.color);
},
colors() {
return swimlaneColors.map((color) => ({ color, name: '' }));
},
isSelected(color) {
return this.currentColor.get() === color;
},
events() {
return [{
'click .js-palette-color'() {
this.currentColor.set(this.currentData().color);
},
'click .js-submit' () {
this.currentSwimlane.setColor(this.currentColor.get());
Popup.close();
},
'click .js-remove-color'() {
this.currentSwimlane.setColor(null);
Popup.close();
},
}];
},
}).register('setSwimlaneColorPopup');
+15 -35
View File
@@ -1,21 +1,22 @@
template(name="swimlane")
.swimlane.js-lists.js-swimlane
.swimlane
+swimlaneHeader
.swimlane.js-lists.js-swimlane
if isMiniScreen
if currentList
if currentListIsInThisSwimlane _id
+list(currentList)
else
each currentBoard.lists
unless currentList
each lists
+miniList(this)
if currentUser.isBoardMember
+addListForm
else
each currentBoard.lists
each lists
+list(this)
if currentCardIsInThisList _id ../_id
+cardDetails(currentCard)
if currentUser.isBoardMember
+addListAndSwimlaneForm
+addListForm
template(name="listsGroup")
.swimlane.list-group.js-lists
@@ -23,52 +24,31 @@ template(name="listsGroup")
if currentList
+list(currentList)
else
each currentBoard.lists
each lists
+miniList(this)
if currentUser.isBoardMember
+addListForm
else
each currentBoard.lists
each lists
+list(this)
if currentCardIsInThisList _id null
+cardDetails(currentCard)
if currentUser.isBoardMember
+addListForm
template(name="addListAndSwimlaneForm")
.list.list-composer.js-list-composer
.list-header
+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'}}
a.fa.fa-times-thin.js-close-inlined-form
else
a.open-list-composer.js-open-inlined-form
i.fa.fa-plus
| {{_ 'add-list'}}
.list-header
+inlinedForm(autoclose=false)
input.swimlane-name-input.full-line(type="text" placeholder="{{_ 'add-swimlane'}}"
autocomplete="off" autofocus)
.edit-controls.clearfix
button.primary.confirm(type="submit") {{_ 'save'}}
a.fa.fa-times-thin.js-close-inlined-form
else
a.open-list-composer.js-open-inlined-form
i.fa.fa-plus
| {{_ 'add-swimlane'}}
template(name="addListForm")
.list.list-composer.js-list-composer
.list-header
.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'}}
a.fa.fa-times-thin.js-close-inlined-form
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
+29 -49
View File
@@ -1,16 +1,25 @@
const { calculateIndex, enableClickOnTouch } = Utils;
function currentListIsInThisSwimlane(swimlaneId) {
const currentList = Lists.findOne(Session.get('currentList'));
return currentList && (currentList.swimlaneId === swimlaneId || currentList.swimlaneId === '');
}
function currentCardIsInThisList(listId, swimlaneId) {
const currentCard = Cards.findOne(Session.get('currentCard'));
const currentUser = Meteor.user();
if (currentUser.profile.boardView === 'board-view-lists')
return currentCard && currentCard.listId === listId;
else if (currentUser.profile.boardView === 'board-view-swimlanes')
if (currentUser && currentUser.profile && currentUser.profile.boardView === 'board-view-swimlanes')
return currentCard && currentCard.listId === listId && currentCard.swimlaneId === swimlaneId;
else if (currentUser.profile.boardView === 'board-view-cal')
return currentCard;
else
return false;
else // Default view: board-view-lists
return currentCard && currentCard.listId === listId;
// https://github.com/wekan/wekan/issues/1623
// https://github.com/ChronikEwok/wekan/commit/cad9b20451bb6149bfb527a99b5001873b06c3de
// TODO: In public board, if you would like to switch between List/Swimlane view, you could
// 1) If there is no view cookie, save to cookie board-view-lists
// board-view-lists / board-view-swimlanes / board-view-cal
// 2) If public user changes clicks board-view-lists then change view and
// then change view and save cookie with view value
// without using currentuser above, because currentuser is null.
}
function initSortable(boardComponent, $listsDom) {
@@ -110,6 +119,10 @@ BlazeComponent.extendComponent({
return currentCardIsInThisList(listId, swimlaneId);
},
currentListIsInThisSwimlane(swimlaneId) {
return currentListIsInThisSwimlane(swimlaneId);
},
events() {
return [{
// Click-and-drag action
@@ -149,6 +162,12 @@ BlazeComponent.extendComponent({
}).register('swimlane');
BlazeComponent.extendComponent({
onCreated() {
this.currentBoard = Boards.findOne(Session.get('currentBoard'));
this.isListTemplatesSwimlane = this.currentBoard.isTemplatesBoard() && this.currentData().isListTemplatesSwimlane();
this.currentSwimlane = this.currentData();
},
// Proxy
open() {
this.childComponents('inlinedForm')[0].open();
@@ -165,58 +184,19 @@ BlazeComponent.extendComponent({
title,
boardId: Session.get('currentBoard'),
sort: $('.list').length,
type: (this.isListTemplatesSwimlane)?'template-list':'list',
swimlaneId: (this.currentBoard.isTemplatesBoard())?this.currentSwimlane._id:'',
});
titleInput.value = '';
titleInput.focus();
}
},
'click .js-list-template': Popup.open('searchElement'),
}];
},
}).register('addListForm');
BlazeComponent.extendComponent({
// Proxy
open() {
this.childComponents('inlinedForm')[0].open();
},
events() {
return [{
submit(evt) {
evt.preventDefault();
let titleInput = this.find('.list-name-input');
if (titleInput) {
const title = titleInput.value.trim();
if (title) {
Lists.insert({
title,
boardId: Session.get('currentBoard'),
sort: $('.list').length,
});
titleInput.value = '';
titleInput.focus();
}
} else {
titleInput = this.find('.swimlane-name-input');
const title = titleInput.value.trim();
if (title) {
Swimlanes.insert({
title,
boardId: Session.get('currentBoard'),
sort: $('.swimlane').length,
});
titleInput.value = '';
titleInput.focus();
}
}
},
}];
},
}).register('addListAndSwimlaneForm');
Template.swimlane.helpers({
canSeeAddList() {
return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
+94 -11
View File
@@ -7,7 +7,7 @@
display: flex
flex-direction: row
overflow: 0;
max-height: 100%
max-height: calc(100% - 26px)
&.placeholder
background-color: rgba(0, 0, 0, .2)
@@ -27,20 +27,15 @@
.swimlane-header-wrap
display: flex;
flex-direction: row;
flex: 0 0 50px;
padding-bottom: 30px;
border-bottom: 1px solid #CCC
flex: 1 0 100%;
background-color: #ccc;
.swimlane-header
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
transform: rotate(180deg);
font-size: 14px;
line-height: 50px;
margin-top: 50px;
padding: 5px 5px
font-weight: bold;
min-height: 9px;
width: 50px;
width: 100%;
overflow: hidden;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
@@ -49,7 +44,95 @@
.swimlane-header-menu
position: absolute
padding: 20px 20px
padding: 5px 5px
.swimlane-header-plus-icon
margin-left: 5px
margin-right: 10px
.list-group
height: 100%
.moving-swimlane
display: none
swimlane-color(background, color...)
background: background !important
if color
color: color !important //overwrite text for better visibility
.swimlane-white
swimlane-color(#ffffff, #4d4d4d) //Black text for better visibility
border: 1px solid #eee
.swimlane-green
swimlane-color(#3cb500, #ffffff) //White text for better visibility
.swimlane-yellow
swimlane-color(#fad900, #4d4d4d) //Black text for better visibility
.swimlane-orange
swimlane-color(#ff9f19, #4d4d4d) //Black text for better visibility
.swimlane-red
swimlane-color(#eb4646, #ffffff) //White text for better visibility
.swimlane-purple
swimlane-color(#a632db, #ffffff) //White text for better visibility
.swimlane-blue
swimlane-color(#0079bf, #ffffff) //White text for better visibility
.swimlane-pink
swimlane-color(#ff78cb, #4d4d4d) //Black text for better visibility
.swimlane-sky
swimlane-color(#00c2e0, #ffffff) //White text for better visibility
.swimlane-black
swimlane-color(#4d4d4d, #ffffff) //White text for better visibility
.swimlane-lime
swimlane-color(#51e898, #4d4d4d) //Black text for better visibility
.swimlane-silver
swimlane-color(unset, #4d4d4d) //Black text for better visibility
.swimlane-peachpuff
swimlane-color(#ffdab9, #4d4d4d) //Black text for better visibility
.swimlane-crimson
swimlane-color(#dc143c, #ffffff) //White text for better visibility
.swimlane-plum
swimlane-color(#dda0dd, #4d4d4d) //Black text for better visibility
.swimlane-darkgreen
swimlane-color(#006400, #ffffff) //White text for better visibility
.swimlane-slateblue
swimlane-color(#6a5acd, #ffffff) //White text for better visibility
.swimlane-magenta
swimlane-color(#ff00ff, #ffffff) //White text for better visibility
.swimlane-gold
swimlane-color(#ffd700, #4d4d4d) //Black text for better visibility
.swimlane-navy
swimlane-color(#000080, #ffffff) //White text for better visibility
.swimlane-gray
swimlane-color(#808080, #ffffff) //White text for better visibility
.swimlane-saddlebrown
swimlane-color(#8b4513, #ffffff) //White text for better visibility
.swimlane-paleturquoise
swimlane-color(#afeeee, #4d4d4d) //Black text for better visibility
.swimlane-mistyrose
swimlane-color(#ffe4e1, #4d4d4d) //Black text for better visibility
.swimlane-indigo
swimlane-color(#4b0082, #ffffff) //White text for better visibility
+17 -8
View File
@@ -4,10 +4,11 @@ template(name="headerUserBar")
.header-user-bar-avatar
+userAvatar(userId=currentUser._id)
unless isMiniScreen
if currentUser.profile.fullname
= currentUser.profile.fullname
else
= currentUser.username
unless isSandstorm
if currentUser.profile.fullname
= currentUser.profile.fullname
else
= currentUser.username
template(name="memberMenuPopup")
ul.pop-over-list
@@ -15,13 +16,18 @@ template(name="memberMenuPopup")
li: a.js-edit-profile {{_ 'edit-profile'}}
li: a.js-change-settings {{_ 'change-settings'}}
li: a.js-change-avatar {{_ 'edit-avatar'}}
li: a.js-change-password {{_ 'changePasswordPopup-title'}}
li: a.js-change-language {{_ 'changeLanguagePopup-title'}}
unless isSandstorm
li: a.js-change-password {{_ 'changePasswordPopup-title'}}
li: a.js-change-language {{_ 'changeLanguagePopup-title'}}
if currentUser.isAdmin
li: a.js-go-setting(href="{{pathFor 'setting'}}") {{_ 'admin-panel'}}
hr
ul.pop-over-list
li: a.js-logout {{_ 'log-out'}}
li: a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") {{_ 'templates'}}
unless isSandstorm
hr
ul.pop-over-list
li: a.js-logout {{_ 'log-out'}}
template(name="editProfilePopup")
form
@@ -47,7 +53,10 @@ template(name="editProfilePopup")
input.js-profile-email(type="email" value="{{emails.[0].address}}")
else
input.js-profile-email(type="email" value="{{emails.[0].address}}" readonly)
input.primary.wide(type="submit" value="{{_ 'save'}}")
div.buttonsContainer
input.primary.wide(type="submit" value="{{_ 'save'}}")
div
input#deleteButton.primary.wide(type="button" value="{{_ 'delete'}}")
template(name="changePasswordPopup")
+atForm(state='changePwd')
+16
View File
@@ -3,6 +3,15 @@ Template.headerUserBar.events({
'click .js-change-avatar': Popup.open('changeAvatar'),
});
Template.memberMenuPopup.helpers({
templatesBoardId() {
return Meteor.user().getTemplatesBoardId();
},
templatesBoardSlug() {
return Meteor.user().getTemplatesBoardSlug();
},
});
Template.memberMenuPopup.events({
'click .js-edit-profile': Popup.open('editProfile'),
'click .js-change-settings': Popup.open('changeSettings'),
@@ -86,6 +95,11 @@ Template.editProfilePopup.events({
});
} else Popup.back();
},
'click #deleteButton'() {
Users.remove(Meteor.userId());
Popup.close();
AccountsTemplates.logout();
},
});
// XXX For some reason the useraccounts autofocus isnt working in this case.
@@ -105,6 +119,8 @@ Template.changeLanguagePopup.helpers({
name = 'Brezhoneg';
} else if (lang.name === 'ig') {
name = 'Igbo';
} else if (lang.name === 'oc') {
name = 'Occitan';
}
return { tag, name };
}).sort(function (a, b) {
+1 -1
View File
@@ -135,6 +135,6 @@ $(document).on('click', (evt) => {
}
});
$(document).on('click', 'a[href=#]', (evt) => {
$(document).on('click', 'a[href=\\#]', (evt) => {
evt.preventDefault();
});
+5 -7
View File
@@ -4,9 +4,9 @@ window.Popup = new class {
this.template = Template.popup;
// We only want to display one popup at a time and we keep the view object
// in this `Popup._current` variable. If there is no popup currently opened
// in this `Popup.current` variable. If there is no popup currently opened
// the value is `null`.
this._current = null;
this.current = null;
// It's possible to open a sub-popup B from a popup A. In that case we keep
// the data of popup A so we can return back to it. Every time we open a new
@@ -27,11 +27,9 @@ window.Popup = new class {
open(name) {
const self = this;
const popupName = `${name}Popup`;
function clickFromPopup(evt) {
return $(evt.target).closest('.js-pop-over').length !== 0;
}
return function(evt) {
// If a popup is already opened, clicking again on the opener element
// should close it -- and interrupt the current `open` function.
@@ -57,7 +55,6 @@ window.Popup = new class {
self._stack = [];
openerElement = evt.currentTarget;
}
$(openerElement).addClass('is-active');
evt.preventDefault();
@@ -139,6 +136,7 @@ window.Popup = new class {
const openerElement = this._getTopStack().openerElement;
$(openerElement).removeClass('is-active');
this._stack = [];
}
}
@@ -186,7 +184,7 @@ window.Popup = new class {
// positives.
const title = TAPi18n.__(translationKey);
// when popup showed as full of small screen, we need a default header to clearly see [X] button
const defaultTitle = Utils.isMiniScreen() ? 'Wekan' : false;
const defaultTitle = Utils.isMiniScreen() ? '' : false;
return title !== translationKey ? title : defaultTitle;
};
}
@@ -200,7 +198,7 @@ escapeActions.forEach((actionName) => {
() => Popup[actionName](),
() => Popup.isOpen(),
{
noClickEscapeOn: '.js-pop-over',
noClickEscapeOn: '.js-pop-over,.js-open-card-title-popup',
enabledOnClick: actionName === 'close',
}
);
+31 -1
View File
@@ -145,6 +145,26 @@ Utils = {
});
},
manageCustomUI(){
Meteor.call('getCustomUI', (err, data) => {
if (err && err.error[0] === 'var-not-exist'){
Session.set('customUI', false); // siteId || address server not defined
}
if (!err){
Utils.setCustomUI(data);
}
});
},
setCustomUI(data){
const currentBoard = Boards.findOne(Session.get('currentBoard'));
if (currentBoard) {
DocHead.setTitle(`${currentBoard.title } - ${ data.productName}`);
} else {
DocHead.setTitle(`${data.productName}`);
}
},
setMatomo(data){
window._paq = window._paq || [];
window._paq.push(['setDoNotTrack', data.doNotTrack]);
@@ -198,10 +218,20 @@ Utils = {
const element = tempInstance.$(triggerEls[i]);
if (element.hasClass('trigger-text')) {
finalString += element.text().toLowerCase();
} else if (element.hasClass('user-details')) {
let username = element.find('input').val();
if(username === undefined || username === ''){
username = '*';
}
finalString += `${element.find('.trigger-text').text().toLowerCase() } ${ username}`;
} else if (element.find('select').length > 0) {
finalString += element.find('select option:selected').text().toLowerCase();
} else if (element.find('input').length > 0) {
finalString += element.find('input').val();
let inputvalue = element.find('input').val();
if(inputvalue === undefined || inputvalue === ''){
inputvalue = '*';
}
finalString += inputvalue;
}
// Add space
if (i !== length - 1) {
+16 -11
View File
@@ -14,6 +14,7 @@ FlowRouter.route('/', {
Filter.reset();
EscapeActions.executeAll();
Utils.manageCustomUI();
Utils.manageMatomo();
BlazeLayout.render('defaultLayout', {
@@ -40,6 +41,7 @@ FlowRouter.route('/b/:id/:slug', {
EscapeActions.executeUpTo('popup-close');
}
Utils.manageCustomUI();
Utils.manageMatomo();
BlazeLayout.render('defaultLayout', {
@@ -57,6 +59,7 @@ FlowRouter.route('/b/:boardId/:slug/:cardId', {
Session.set('currentBoard', params.boardId);
Session.set('currentCard', params.cardId);
Utils.manageCustomUI();
Utils.manageMatomo();
BlazeLayout.render('defaultLayout', {
@@ -122,6 +125,7 @@ FlowRouter.route('/setting', {
},
],
action() {
Utils.manageCustomUI();
BlazeLayout.render('defaultLayout', {
headerBar: 'settingHeaderBar',
content: 'setting',
@@ -199,20 +203,21 @@ _.each(redirections, (newPath, oldPath) => {
// using the `kadira:dochead` package. Currently we only use it to display the
// board title if we are in a board page (see #364) but we may want to support
// some <meta> tags in the future.
const appTitle = 'Wekan';
//const appTitle = Utils.manageCustomUI();
// XXX The `Meteor.startup` should not be necessary -- we don't need to wait for
// the complete DOM to be ready to call `DocHead.setTitle`. But the problem is
// that the global variable `Boards` is undefined when this file loads so we
// wait a bit until hopefully all files are loaded. This will be fixed in a
// clean way once Meteor will support ES6 modules -- hopefully in Meteor 1.3.
Meteor.isClient && Meteor.startup(() => {
Tracker.autorun(() => {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const titleStack = [appTitle];
if (currentBoard) {
titleStack.push(currentBoard.title);
}
DocHead.setTitle(titleStack.reverse().join(' - '));
});
});
//Meteor.isClient && Meteor.startup(() => {
// Tracker.autorun(() => {
// const currentBoard = Boards.findOne(Session.get('currentBoard'));
// const titleStack = [appTitle];
// if (currentBoard) {
// titleStack.push(currentBoard.title);
// }
// DocHead.setTitle(titleStack.reverse().join(' - '));
// });
//});
-219
View File
@@ -1,219 +0,0 @@
version: '2'
# Using prebuilt image: docker-compose up -d --no-build
services:
wekandb:
image: mongo:3.2.21
container_name: wekan-db
restart: always
command: mongod --smallfiles --oplogSize 128
networks:
- wekan-tier
expose:
- 27017
volumes:
- wekan-db:/data/db
- wekan-db-dump:/dump
wekan:
image: quay.io/wekan/wekan
container_name: wekan-app
restart: always
networks:
- wekan-tier
build:
context: .
dockerfile: Dockerfile
args:
- NODE_VERSION=${NODE_VERSION}
- METEOR_RELEASE=${METEOR_RELEASE}
- NPM_VERSION=${NPM_VERSION}
- ARCHITECTURE=${ARCHITECTURE}
- SRC_PATH=${SRC_PATH}
- METEOR_EDGE=${METEOR_EDGE}
- USE_EDGE=${USE_EDGE}
ports:
# Docker outsideport:insideport
- 80:8080
environment:
- MONGO_URL=mongodb://wekandb:27017/wekan
- ROOT_URL=http://localhost
# Wekan Export Board works when WITH_API='true'.
# If you disable Wekan API with 'false', Export Board does not work.
- WITH_API=true
# Optional: Integration with Matomo https://matomo.org that is installed to your server
# The address of the server where Matomo is hosted.
# example: - MATOMO_ADDRESS=https://example.com/matomo
- MATOMO_ADDRESS=''
# The value of the site ID given in Matomo server for Wekan
# example: - MATOMO_SITE_ID=12345
- MATOMO_SITE_ID=''
# The option do not track which enables users to not be tracked by matomo
# example: - MATOMO_DO_NOT_TRACK=false
- MATOMO_DO_NOT_TRACK=true
# The option that allows matomo to retrieve the username:
# example: MATOMO_WITH_USERNAME=true
- MATOMO_WITH_USERNAME=false
# Enable browser policy and allow one trusted URL that can have iframe that has Wekan embedded inside.
# Setting this to false is not recommended, it also disables all other browser policy protections
# and allows all iframing etc. See wekan/server/policy.js
- BROWSER_POLICY_ENABLED=true
# When browser policy is enabled, HTML code at this Trusted URL can have iframe that embeds Wekan inside.
- TRUSTED_URL=''
# What to send to Outgoing Webhook, or leave out. Example, that includes all that are default: cardId,listId,oldListId,boardId,comment,user,card,commentId .
# example: WEBHOOKS_ATTRIBUTES=cardId,listId,oldListId,boardId,comment,user,card,commentId
- WEBHOOKS_ATTRIBUTES=''
# Enable the OAuth2 connection
# example: OAUTH2_ENABLED=true
- OAUTH2_ENABLED=false
# OAuth2 docs: https://github.com/wekan/wekan/wiki/OAuth2
# OAuth2 Client ID, for example from Rocket.Chat. Example: abcde12345
# example: OAUTH2_CLIENT_ID=abcde12345
- OAUTH2_CLIENT_ID=''
# OAuth2 Secret, for example from Rocket.Chat: Example: 54321abcde
# example: OAUTH2_SECRET=54321abcde
- OAUTH2_SECRET=''
# OAuth2 Server URL, for example Rocket.Chat. Example: https://chat.example.com
# example: OAUTH2_SERVER_URL=https://chat.example.com
- OAUTH2_SERVER_URL=''
# OAuth2 Authorization Endpoint. Example: /oauth/authorize
# example: OAUTH2_AUTH_ENDPOINT=/oauth/authorize
- OAUTH2_AUTH_ENDPOINT=''
# OAuth2 Userinfo Endpoint. Example: /oauth/userinfo
# example: OAUTH2_USERINFO_ENDPOINT=/oauth/userinfo
- OAUTH2_USERINFO_ENDPOINT=''
# OAuth2 Token Endpoint. Example: /oauth/token
# example: OAUTH2_TOKEN_ENDPOINT=/oauth/token
- OAUTH2_TOKEN_ENDPOINT=''
# LDAP_ENABLE : Enable or not the connection by the LDAP
# example : LDAP_ENABLE=true
- LDAP_ENABLE=false
# LDAP_PORT : The port of the LDAP server
# example : LDAP_PORT=389
- LDAP_PORT=389
# LDAP_HOST : The host server for the LDAP server
# example : LDAP_HOST=localhost
- LDAP_HOST=''
# LDAP_BASEDN : The base DN for the LDAP Tree
# example : LDAP_BASEDN=ou=user,dc=example,dc=org
- LDAP_BASEDN=''
# LDAP_LOGIN_FALLBACK : Fallback on the default authentication method
# example : LDAP_LOGIN_FALLBACK=true
- LDAP_LOGIN_FALLBACK=false
# LDAP_RECONNECT : Reconnect to the server if the connection is lost
# example : LDAP_RECONNECT=false
- LDAP_RECONNECT=true
# LDAP_TIMEOUT : Overall timeout, in milliseconds
# example : LDAP_TIMEOUT=12345
- LDAP_TIMEOUT=10000
# LDAP_IDLE_TIMEOUT : Specifies the timeout for idle LDAP connections in milliseconds
# example : LDAP_IDLE_TIMEOUT=12345
- LDAP_IDLE_TIMEOUT=10000
# LDAP_CONNECT_TIMEOUT : Connection timeout, in milliseconds
# example : LDAP_CONNECT_TIMEOUT=12345
- LDAP_CONNECT_TIMEOUT=10000
# LDAP_AUTHENTIFICATION : If the LDAP needs a user account to search
# example : LDAP_AUTHENTIFICATION=true
- LDAP_AUTHENTIFICATION=false
# LDAP_AUTHENTIFICATION_USERDN : The search user DN
# example : LDAP_AUTHENTIFICATION_USERDN=cn=admin,dc=example,dc=org
- LDAP_AUTHENTIFICATION_USERDN=''
# LDAP_AUTHENTIFICATION_PASSWORD : The password for the search user
# example : AUTHENTIFICATION_PASSWORD=admin
- LDAP_AUTHENTIFICATION_PASSWORD=''
# LDAP_LOG_ENABLED : Enable logs for the module
# example : LDAP_LOG_ENABLED=true
- LDAP_LOG_ENABLED=false
# LDAP_BACKGROUND_SYNC : If the sync of the users should be done in the background
# example : LDAP_BACKGROUND_SYNC=true
- LDAP_BACKGROUND_SYNC=false
# LDAP_BACKGROUND_SYNC_INTERVAL : At which interval does the background task sync in milliseconds
# example : LDAP_BACKGROUND_SYNC_INTERVAL=12345
- LDAP_BACKGROUND_SYNC_INTERVAL=100
# LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED :
# example : LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=true
- LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false
# LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS :
# example : LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=true
- LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false
# LDAP_ENCRYPTION : If using LDAPS
# example : LDAP_ENCRYPTION=true
- LDAP_ENCRYPTION=false
# LDAP_CA_CERT : The certification for the LDAPS server
# example : LDAP_CA_CERT=-----BEGIN CERTIFICATE-----MIIE+zCCA+OgAwIBAgIkAhwR/6TVLmdRY6hHxvUFWc0+Enmu/Hu6cj+G2FIdAgIC...-----END CERTIFICATE-----
- LDAP_CA_CERT=''
# LDAP_REJECT_UNAUTHORIZED : Reject Unauthorized Certificate
# example : LDAP_REJECT_UNAUTHORIZED=true
- LDAP_REJECT_UNAUTHORIZED=false
# LDAP_USER_SEARCH_FILTER : Optional extra LDAP filters. Don't forget the outmost enclosing parentheses if needed
# example : LDAP_USER_SEARCH_FILTER=
- LDAP_USER_SEARCH_FILTER=''
# LDAP_USER_SEARCH_SCOPE : base (search only in the provided DN), one (search only in the provided DN and one level deep), or sub (search the whole subtree).
# example : LDAP_USER_SEARCH_SCOPE=one
- LDAP_USER_SEARCH_SCOPE=''
# LDAP_USER_SEARCH_FIELD : Which field is used to find the user
# example : LDAP_USER_SEARCH_FIELD=uid
- LDAP_USER_SEARCH_FIELD=''
# LDAP_SEARCH_PAGE_SIZE : Used for pagination (0=unlimited)
# example : LDAP_SEARCH_PAGE_SIZE=12345
- LDAP_SEARCH_PAGE_SIZE=0
# LDAP_SEARCH_SIZE_LIMIT : The limit number of entries (0=unlimited)
# example : LDAP_SEARCH_SIZE_LIMIT=12345
- LDAP_SEARCH_SIZE_LIMIT=0
# LDAP_GROUP_FILTER_ENABLE : Enable group filtering
# example : LDAP_GROUP_FILTER_ENABLE=true
- LDAP_GROUP_FILTER_ENABLE=false
# LDAP_GROUP_FILTER_OBJECTCLASS : The object class for filtering
# example : LDAP_GROUP_FILTER_OBJECTCLASS=group
- LDAP_GROUP_FILTER_OBJECTCLASS=''
# LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE :
# example :
- LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE=''
# LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE :
# example :
- LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE=''
# LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT :
# example :
- LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT=''
# LDAP_GROUP_FILTER_GROUP_NAME :
# example :
- LDAP_GROUP_FILTER_GROUP_NAME=''
# LDAP_UNIQUE_IDENTIFIER_FIELD : This field is sometimes class GUID (Globally Unique Identifier)
# example : LDAP_UNIQUE_IDENTIFIER_FIELD=guid
- LDAP_UNIQUE_IDENTIFIER_FIELD=''
# LDAP_UTF8_NAMES_SLUGIFY : Convert the username to utf8
# example : LDAP_UTF8_NAMES_SLUGIFY=false
- LDAP_UTF8_NAMES_SLUGIFY=true
# LDAP_USERNAME_FIELD : Which field contains the ldap username
# example : LDAP_USERNAME_FIELD=username
- LDAP_USERNAME_FIELD=''
# LDAP_MERGE_EXISTING_USERS :
# example : LDAP_MERGE_EXISTING_USERS=true
- LDAP_MERGE_EXISTING_USERS=false
# LDAP_SYNC_USER_DATA :
# example : LDAP_SYNC_USER_DATA=true
- LDAP_SYNC_USER_DATA=false
# LDAP_SYNC_USER_DATA_FIELDMAP :
# example : LDAP_SYNC_USER_DATA_FIELDMAP={\"cn\":\"name\", \"mail\":\"email\"}
- LDAP_SYNC_USER_DATA_FIELDMAP=''
# LDAP_SYNC_GROUP_ROLES :
# example :
- LDAP_SYNC_GROUP_ROLES=''
# LDAP_DEFAULT_DOMAIN : The default domain of the ldap it is used to create email if the field is not map correctly with the LDAP_SYNC_USER_DATA_FIELDMAP
# example :
- LDAP_DEFAULT_DOMAIN=''
depends_on:
- wekandb
volumes:
wekan-db:
driver: local
wekan-db-dump:
driver: local
networks:
wekan-tier:
driver: bridge
+515 -151
View File
@@ -1,9 +1,101 @@
version: '2'
# Note: Do not add single quotes '' to variables. Having spaces still works without quotes where required.
#---------------------------------------------------------------------------------------------------------
# ==== CREATING USERS AND LOGGING IN TO WEKAN ====
# https://github.com/wekan/wekan/wiki/Adding-users
#---------------------------------------------------------------------------------------------------------
# ==== FORGOT PASSWORD ====
# https://github.com/wekan/wekan/wiki/Forgot-Password
#---------------------------------------------------------------------------------------------------------
# ==== Upgrading Wekan to new version =====
# 1) Stop Wekan:
# docker-compose stop
# 2) Download new version:
# docker-compose pull wekan
# 3) If you have more networks for VPN etc as described at bottom of
# this config, download for them too:
# docker-compose pull wekan2
# 4) Start Wekan:
# docker-compose start
#----------------------------------------------------------------------------------
# ==== OPTIONAL: DEDICATED DOCKER USER ====
# 1) Optionally create a dedicated user for Wekan, for example:
# sudo useradd -d /home/wekan -m -s /bin/bash wekan
# 2) Add this user to the docker group, then logout+login or reboot:
# sudo usermod -aG docker wekan
# 3) Then login as user wekan.
# 4) Create this file /home/wekan/docker-compose.yml with your modifications.
#----------------------------------------------------------------------------------
# ==== RUN DOCKER AS SERVICE ====
# 1a) Running Docker as service, on Systemd like Debian 9, Ubuntu 16.04, CentOS 7:
# sudo systemctl enable docker
# sudo systemctl start docker
# 1b) Running Docker as service, on init.d like Debian 8, Ubuntu 14.04, CentOS 6:
# sudo update-rc.d docker defaults
# sudo service docker start
# ----------------------------------------------------------------------------------
# ==== USAGE OF THIS docker-compose.yml ====
# 1) For seeing does Wekan work, try this and check with your webbroser:
# docker-compose up
# 2) Stop Wekan and start Wekan in background:
# docker-compose stop
# docker-compose up -d
# 3) See running Docker containers:
# docker ps
# 4) Stop Docker containers:
# docker-compose stop
# ----------------------------------------------------------------------------------
# ===== INSIDE DOCKER CONTAINERS, AND BACKUP/RESTORE ====
# https://github.com/wekan/wekan/wiki/Backup
# If really necessary, repair MongoDB: https://github.com/wekan/wekan-mongodb/issues/6#issuecomment-424004116
# 1) Going inside containers:
# a) Wekan app, does not contain data
# docker exec -it wekan-app bash
# b) MongoDB, contains all data
# docker exec -it wekan-db bash
# 2) Copying database to outside of container:
# docker exec -it wekan-db bash
# cd /data
# mongodump
# exit
# docker cp wekan-db:/data/dump .
# 3) Restoring database
# # 1) Stop wekan
# docker stop wekan-app
# # 2) Go inside database container
# docker exec -it wekan-db bash
# # 3) and data directory
# cd /data
# # 4) Remove previos dump
# rm -rf dump
# # 5) Exit db container
# exit
# # 6) Copy dump to inside docker container
# docker cp dump wekan-db:/data/
# # 7) Go inside database container
# docker exec -it wekan-db bash
# # 8) and data directory
# cd /data
# # 9) Restore
# mongorestore --drop
# # 10) Exit db container
# exit
# # 11) Start wekan
# docker start wekan-app
#-------------------------------------------------------------------------
services:
wekandb:
#-------------------------------------------------------------------------------------
# ==== MONGODB AND METEOR VERSION ====
# a) For Wekan Meteor 1.8.x version at meteor-1.8 branch, use mongo 4.x
#image: mongo:4.0.4
# b) For Wekan Meteor 1.6.x version at master/devel/edge branches.
# Only for Snap and Sandstorm while they are not upgraded yet to Meteor 1.8.x
image: mongo:3.2.21
#-------------------------------------------------------------------------------------
container_name: wekan-db
restart: always
command: mongod --smallfiles --oplogSize 128
@@ -16,185 +108,457 @@ services:
- wekan-db-dump:/dump
wekan:
image: quay.io/wekan/wekan
#-------------------------------------------------------------------------------------
# ==== MONGODB AND METEOR VERSION ====
# a) For Wekan Meteor 1.8.x version at meteor-1.8 branch,
# using https://quay.io/wekan/wekan automatic builds
#image: quay.io/wekan/wekan:meteor-1.8
# b) For Wekan Meteor 1.6.x version at master/devel/edge branches.
# Only for Snap and Sandstorm while they are not upgraded yet to Meteor 1.8.x
image: quay.io/wekan/wekan:master
# c) Using specific Meteor 1.6.x version tag:
# image: quay.io/wekan/wekan:v1.95
# c) Using Docker Hub automatic builds https://hub.docker.com/r/wekanteam/wekan
# image: wekanteam/wekan:meteor-1.8
# image: wekanteam/wekan:v1.95
#-------------------------------------------------------------------------------------
container_name: wekan-app
restart: always
networks:
- wekan-tier
#-------------------------------------------------------------------------------------
# ==== BUILD wekan-app DOCKER CONTAINER FROM SOURCE, if you uncomment these ====
# ==== and use commands: docker-compose up -d --build
#build:
# context: .
# dockerfile: Dockerfile
# args:
# - NODE_VERSION=${NODE_VERSION}
# - METEOR_RELEASE=${METEOR_RELEASE}
# - NPM_VERSION=${NPM_VERSION}
# - ARCHITECTURE=${ARCHITECTURE}
# - SRC_PATH=${SRC_PATH}
# - METEOR_EDGE=${METEOR_EDGE}
# - USE_EDGE=${USE_EDGE}
#-------------------------------------------------------------------------------------
ports:
# Docker outsideport:insideport
# Docker outsideport:insideport. Do not add anything extra here.
# For example, if you want to have wekan on port 3001,
# use 3001:8080 . Do not add any extra address etc here, that way it does not work.
# remove port mapping if you use nginx reverse proxy, port 8080 is already exposed to wekan-tier network
- 80:8080
environment:
- MONGO_URL=mongodb://wekandb:27017/wekan
- ROOT_URL=http://localhost
# Wekan Export Board works when WITH_API='true'.
# If you disable Wekan API with 'false', Export Board does not work.
#---------------------------------------------------------------
# ==== ROOT_URL SETTING ====
# Change ROOT_URL to your real Wekan URL, for example:
# If you have Caddy/Nginx/Apache providing SSL
# - https://example.com
# - https://boards.example.com
# This can be problematic with avatars https://github.com/wekan/wekan/issues/1776
# - https://example.com/wekan
# If without https, can be only wekan node, no need for Caddy/Nginx/Apache if you don't need them
# - http://example.com
# - http://boards.example.com
# - http://192.168.1.100 <=== using at local LAN
- ROOT_URL=http://localhost # <=== using only at same laptop/desktop where Wekan is installed
#---------------------------------------------------------------
# ==== EMAIL SETTINGS ====
# Email settings are required in both MAIL_URL and Admin Panel,
# see https://github.com/wekan/wekan/wiki/Troubleshooting-Mail
# For SSL in email, change smtp:// to smtps://
# NOTE: Special characters need to be url-encoded in MAIL_URL.
# You can encode those characters for example at: https://www.urlencoder.org
#- MAIL_URL=smtp://user:pass@mailserver.example.com:25/
- MAIL_URL=smtp://<mail_url>:25/?ignoreTLS=true&tls={rejectUnauthorized:false}
- MAIL_FROM=Wekan Notifications <noreply.wekan@mydomain.com>
#---------------------------------------------------------------
# ==== OPTIONAL: MONGO OPLOG SETTINGS =====
# https://github.com/wekan/wekan-mongodb/issues/2#issuecomment-378343587
# We've fixed our CPU usage problem today with an environment
# change around Wekan. I wasn't aware during implementation
# that if you're using more than 1 instance of Wekan
# (or any MeteorJS based tool) you're supposed to set
# MONGO_OPLOG_URL as an environment variable.
# Without setting it, Meteor will perform a pull-and-diff
# update of it's dataset. With it, Meteor will update from
# the OPLOG. See here
# https://blog.meteor.com/tuning-meteor-mongo-livedata-for-scalability-13fe9deb8908
# After setting
# MONGO_OPLOG_URL=mongodb://<username>:<password>@<mongoDbURL>/local?authSource=admin&replicaSet=rsWekan
# the CPU usage for all Wekan instances dropped to an average
# of less than 10% with only occasional spikes to high usage
# (I guess when someone is doing a lot of work)
# - MONGO_OPLOG_URL=mongodb://<username>:<password>@<mongoDbURL>/local?authSource=admin&replicaSet=rsWekan
#---------------------------------------------------------------
# ==== OPTIONAL: KADIRA PERFORMANCE MONITORING FOR METEOR ====
# https://github.com/edemaine/kadira-compose
# https://github.com/meteor/meteor-apm-agent
# https://blog.meteor.com/kadira-apm-is-now-open-source-490469ffc85f
#- APM_OPTIONS_ENDPOINT=http://<kadira-ip>:11011
#- APM_APP_ID=
#- APM_APP_SECRET=
#---------------------------------------------------------------
# ==== OPTIONAL: LOGS AND STATS ====
# https://github.com/wekan/wekan/wiki/Logs
#
# Daily export of Wekan changes as JSON to Logstash and ElasticSearch / Kibana (ELK)
# https://github.com/wekan/wekan-logstash
#
# Statistics Python script for Wekan Dashboard
# https://github.com/wekan/wekan-stats
#
# Console, file, and zulip logger on database changes https://github.com/wekan/wekan/pull/1010
# with fix to replace console.log by winston logger https://github.com/wekan/wekan/pull/1033
# but there could be bug https://github.com/wekan/wekan/issues/1094
#
# There is Feature Request: Logging date and time of all activity with summary reports,
# and requesting reason for changing card to other column https://github.com/wekan/wekan/issues/1598
#---------------------------------------------------------------
# ==== WEKAN API AND EXPORT BOARD ====
# Wekan Export Board works when WITH_API=true.
# https://github.com/wekan/wekan/wiki/REST-API
# https://github.com/wekan/wekan-gogs
# If you disable Wekan API with false, Export Board does not work.
- WITH_API=true
#---------------------------------------------------------------
# ==== PASSWORD BRUTE FORCE PROTECTION ====
#https://atmospherejs.com/lucasantoniassi/accounts-lockout
#Defaults below. Uncomment to change. wekan/server/accounts-lockout.js
#- ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3
#- ACCOUNTS_LOCKOUT_KNOWN_USERS_PERIOD=60
#- ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURE_WINDOW=15
#- ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3
#- ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60
#- ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15
#---------------------------------------------------------------
# ==== EMAIL NOTIFICATION TIMEOUT, ms =====
# Defaut: 30000 ms = 30s
#- EMAIL_NOTIFICATION_TIMEOUT=30000
#-----------------------------------------------------------------
# ==== CORS =====
# CORS: Set Access-Control-Allow-Origin header.
#- CORS=*
# CORS_ALLOW_HEADERS: Set Access-Control-Allow-Headers header. "Authorization,Content-Type" is required for cross-origin use of the API.
#- CORS_ALLOW_HEADERS=Authorization,Content-Type
# CORS_EXPOSE_HEADERS: Set Access-Control-Expose-Headers header. This is not needed for typical CORS situations
#- CORS_EXPOSE_HEADERS=*
#-----------------------------------------------------------------
# ==== MATOMO INTEGRATION ====
# Optional: Integration with Matomo https://matomo.org that is installed to your server
# The address of the server where Matomo is hosted.
# example: - MATOMO_ADDRESS=https://example.com/matomo
- MATOMO_ADDRESS=''
#- MATOMO_ADDRESS=https://example.com/matomo
# The value of the site ID given in Matomo server for Wekan
# example: - MATOMO_SITE_ID=12345
- MATOMO_SITE_ID=''
#- MATOMO_SITE_ID=1
# The option do not track which enables users to not be tracked by matomo
# example: - MATOMO_DO_NOT_TRACK=false
- MATOMO_DO_NOT_TRACK=true
#- MATOMO_DO_NOT_TRACK=true
# The option that allows matomo to retrieve the username:
# example: MATOMO_WITH_USERNAME=true
- MATOMO_WITH_USERNAME=false
#- MATOMO_WITH_USERNAME=true
#-----------------------------------------------------------------
# ==== BROWSER POLICY AND TRUSTED IFRAME URL ====
# Enable browser policy and allow one trusted URL that can have iframe that has Wekan embedded inside.
# Setting this to false is not recommended, it also disables all other browser policy protections
# and allows all iframing etc. See wekan/server/policy.js
- BROWSER_POLICY_ENABLED=true
# When browser policy is enabled, HTML code at this Trusted URL can have iframe that embeds Wekan inside.
- TRUSTED_URL=''
#- TRUSTED_URL=https://intra.example.com
#-----------------------------------------------------------------
# ==== OUTGOING WEBHOOKS ====
# What to send to Outgoing Webhook, or leave out. Example, that includes all that are default: cardId,listId,oldListId,boardId,comment,user,card,commentId .
# example: WEBHOOKS_ATTRIBUTES=cardId,listId,oldListId,boardId,comment,user,card,commentId
- WEBHOOKS_ATTRIBUTES=''
#- WEBHOOKS_ATTRIBUTES=cardId,listId,oldListId,boardId,comment,user,card,commentId
#-----------------------------------------------------------------
# ==== Debug OIDC OAuth2 etc ====
#- DEBUG=true
#-----------------------------------------------------------------
# ==== OAUTH2 AZURE ====
# https://github.com/wekan/wekan/wiki/Azure
# 1) Register the application with Azure. Make sure you capture
# the application ID as well as generate a secret key.
# 2) Configure the environment variables. This differs slightly
# by installation type, but make sure you have the following:
#- OAUTH2_ENABLED=true
# OAuth2 login style: popup or redirect.
#- OAUTH2_LOGIN_STYLE=redirect
# Application GUID captured during app registration:
#- OAUTH2_CLIENT_ID=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
# Secret key generated during app registration:
#- OAUTH2_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#- OAUTH2_SERVER_URL=https://login.microsoftonline.com/
#- OAUTH2_AUTH_ENDPOINT=/oauth2/v2.0/authorize
#- OAUTH2_USERINFO_ENDPOINT=https://graph.microsoft.com/oidc/userinfo
#- OAUTH2_TOKEN_ENDPOINT=/oauth2/v2.0/token
# The claim name you want to map to the unique ID field:
#- OAUTH2_ID_MAP=email
# The claim name you want to map to the username field:
#- OAUTH2_USERNAME_MAP=email
# The claim name you want to map to the full name field:
#- OAUTH2_FULLNAME_MAP=name
# Tthe claim name you want to map to the email field:
#- OAUTH2_EMAIL_MAP=email
#-----------------------------------------------------------------
# ==== OAUTH2 KEYCLOAK ====
# https://github.com/wekan/wekan/wiki/Keycloak <== MAPPING INFO, REQUIRED
#- OAUTH2_ENABLED=true
# OAuth2 login style: popup or redirect.
#- OAUTH2_LOGIN_STYLE=redirect
#- OAUTH2_CLIENT_ID=<Keycloak create Client ID>
#- OAUTH2_SERVER_URL=<Keycloak server name>/auth
#- OAUTH2_AUTH_ENDPOINT=/realms/<keycloak realm>/protocol/openid-connect/auth
#- OAUTH2_USERINFO_ENDPOINT=/realms/<keycloak realm>/protocol/openid-connect/userinfo
#- OAUTH2_TOKEN_ENDPOINT=/realms/<keycloak realm>/protocol/openid-connect/token
#- OAUTH2_SECRET=<keycloak client secret>
#-----------------------------------------------------------------
# ==== OAUTH2 DOORKEEPER ====
# https://github.com/wekan/wekan/issues/1874
# https://github.com/wekan/wekan/wiki/OAuth2
# Enable the OAuth2 connection
# example: OAUTH2_ENABLED=true
- OAUTH2_ENABLED=false
#- OAUTH2_ENABLED=true
# OAuth2 docs: https://github.com/wekan/wekan/wiki/OAuth2
# OAuth2 Client ID, for example from Rocket.Chat. Example: abcde12345
# example: OAUTH2_CLIENT_ID=abcde12345
- OAUTH2_CLIENT_ID=''
# OAuth2 Secret, for example from Rocket.Chat: Example: 54321abcde
# example: OAUTH2_SECRET=54321abcde
- OAUTH2_SECRET=''
# OAuth2 Server URL, for example Rocket.Chat. Example: https://chat.example.com
# example: OAUTH2_SERVER_URL=https://chat.example.com
- OAUTH2_SERVER_URL=''
# OAuth2 Authorization Endpoint. Example: /oauth/authorize
# example: OAUTH2_AUTH_ENDPOINT=/oauth/authorize
- OAUTH2_AUTH_ENDPOINT=''
# OAuth2 Userinfo Endpoint. Example: /oauth/userinfo
# example: OAUTH2_USERINFO_ENDPOINT=/oauth/userinfo
- OAUTH2_USERINFO_ENDPOINT=''
# OAuth2 Token Endpoint. Example: /oauth/token
# example: OAUTH2_TOKEN_ENDPOINT=/oauth/token
- OAUTH2_TOKEN_ENDPOINT=''
# LDAP_ENABLE : Enable or not the connection by the LDAP
# example : LDAP_ENABLE=true
- LDAP_ENABLE=false
# LDAP_PORT : The port of the LDAP server
# example : LDAP_PORT=389
- LDAP_PORT=389
# LDAP_HOST : The host server for the LDAP server
# example : LDAP_HOST=localhost
- LDAP_HOST=''
# LDAP_BASEDN : The base DN for the LDAP Tree
# example : LDAP_BASEDN=ou=user,dc=example,dc=org
- LDAP_BASEDN=''
# LDAP_LOGIN_FALLBACK : Fallback on the default authentication method
# example : LDAP_LOGIN_FALLBACK=true
- LDAP_LOGIN_FALLBACK=false
# LDAP_RECONNECT : Reconnect to the server if the connection is lost
# example : LDAP_RECONNECT=false
- LDAP_RECONNECT=true
# LDAP_TIMEOUT : Overall timeout, in milliseconds
# example : LDAP_TIMEOUT=12345
- LDAP_TIMEOUT=10000
# LDAP_IDLE_TIMEOUT : Specifies the timeout for idle LDAP connections in milliseconds
# example : LDAP_IDLE_TIMEOUT=12345
- LDAP_IDLE_TIMEOUT=10000
# LDAP_CONNECT_TIMEOUT : Connection timeout, in milliseconds
# example : LDAP_CONNECT_TIMEOUT=12345
- LDAP_CONNECT_TIMEOUT=10000
# LDAP_AUTHENTIFICATION : If the LDAP needs a user account to search
# example : LDAP_AUTHENTIFICATION=true
- LDAP_AUTHENTIFICATION=false
# LDAP_AUTHENTIFICATION_USERDN : The search user DN
# example : LDAP_AUTHENTIFICATION_USERDN=cn=admin,dc=example,dc=org
- LDAP_AUTHENTIFICATION_USERDN=''
# LDAP_AUTHENTIFICATION_PASSWORD : The password for the search user
# example : AUTHENTIFICATION_PASSWORD=admin
- LDAP_AUTHENTIFICATION_PASSWORD=''
# LDAP_LOG_ENABLED : Enable logs for the module
# example : LDAP_LOG_ENABLED=true
- LDAP_LOG_ENABLED=false
# LDAP_BACKGROUND_SYNC : If the sync of the users should be done in the background
# example : LDAP_BACKGROUND_SYNC=true
- LDAP_BACKGROUND_SYNC=false
# LDAP_BACKGROUND_SYNC_INTERVAL : At which interval does the background task sync in milliseconds
# example : LDAP_BACKGROUND_SYNC_INTERVAL=12345
- LDAP_BACKGROUND_SYNC_INTERVAL=100
# LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED :
# example : LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=true
- LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false
# LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS :
# example : LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=true
- LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false
# LDAP_ENCRYPTION : If using LDAPS
# example : LDAP_ENCRYPTION=true
- LDAP_ENCRYPTION=false
# LDAP_CA_CERT : The certification for the LDAPS server
# example : LDAP_CA_CERT=-----BEGIN CERTIFICATE-----MIIE+zCCA+OgAwIBAgIkAhwR/6TVLmdRY6hHxvUFWc0+Enmu/Hu6cj+G2FIdAgIC...-----END CERTIFICATE-----
- LDAP_CA_CERT=''
# LDAP_REJECT_UNAUTHORIZED : Reject Unauthorized Certificate
# example : LDAP_REJECT_UNAUTHORIZED=true
- LDAP_REJECT_UNAUTHORIZED=false
# LDAP_USER_SEARCH_FILTER : Optional extra LDAP filters. Don't forget the outmost enclosing parentheses if needed
# example : LDAP_USER_SEARCH_FILTER=
- LDAP_USER_SEARCH_FILTER=''
# LDAP_USER_SEARCH_SCOPE : base (search only in the provided DN), one (search only in the provided DN and one level deep), or sub (search the whole subtree)
# example : LDAP_USER_SEARCH_SCOPE=one
- LDAP_USER_SEARCH_SCOPE=''
# LDAP_USER_SEARCH_FIELD : Which field is used to find the user
# example : LDAP_USER_SEARCH_FIELD=uid
- LDAP_USER_SEARCH_FIELD=''
# LDAP_SEARCH_PAGE_SIZE : Used for pagination (0=unlimited)
# example : LDAP_SEARCH_PAGE_SIZE=12345
- LDAP_SEARCH_PAGE_SIZE=0
# LDAP_SEARCH_SIZE_LIMIT : The limit number of entries (0=unlimited)
# example : LDAP_SEARCH_SIZE_LIMIT=12345
- LDAP_SEARCH_SIZE_LIMIT=0
# LDAP_GROUP_FILTER_ENABLE : Enable group filtering
# example : LDAP_GROUP_FILTER_ENABLE=true
- LDAP_GROUP_FILTER_ENABLE=false
# LDAP_GROUP_FILTER_OBJECTCLASS : The object class for filtering
# example : LDAP_GROUP_FILTER_OBJECTCLASS=group
- LDAP_GROUP_FILTER_OBJECTCLASS=''
# LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE :
# example :
- LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE=''
# LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE :
# example :
- LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE=''
# LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT :
# example :
- LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT=''
# LDAP_GROUP_FILTER_GROUP_NAME :
# example :
- LDAP_GROUP_FILTER_GROUP_NAME=''
# LDAP_UNIQUE_IDENTIFIER_FIELD : This field is sometimes class GUID (Globally Unique Identifier)
# example : LDAP_UNIQUE_IDENTIFIER_FIELD=guid
- LDAP_UNIQUE_IDENTIFIER_FIELD=''
# OAuth2 login style: popup or redirect.
#- OAUTH2_LOGIN_STYLE=redirect
# OAuth2 Client ID.
#- OAUTH2_CLIENT_ID=abcde12345
# OAuth2 Secret.
#- OAUTH2_SECRET=54321abcde
# OAuth2 Server URL.
#- OAUTH2_SERVER_URL=https://chat.example.com
# OAuth2 Authorization Endpoint.
#- OAUTH2_AUTH_ENDPOINT=/oauth/authorize
# OAuth2 Userinfo Endpoint.
#- OAUTH2_USERINFO_ENDPOINT=/oauth/userinfo
# OAuth2 Token Endpoint.
#- OAUTH2_TOKEN_ENDPOINT=/oauth/token
# OAUTH2 ID Token Whitelist Fields.
#- OAUTH2_ID_TOKEN_WHITELIST_FIELDS=[]
# OAUTH2 Request Permissions.
#- OAUTH2_REQUEST_PERMISSIONS='openid profile email'
# OAuth2 ID Mapping
#- OAUTH2_ID_MAP=
# OAuth2 Username Mapping
#- OAUTH2_USERNAME_MAP=
# OAuth2 Fullname Mapping
#- OAUTH2_FULLNAME_MAP=
# OAuth2 Email Mapping
#- OAUTH2_EMAIL_MAP=
#-----------------------------------------------------------------
# ==== LDAP: UNCOMMENT ALL TO ENABLE LDAP ====
# https://github.com/wekan/wekan/wiki/LDAP
# For Snap settings see https://github.com/wekan/wekan-snap/wiki/Supported-settings-keys
# Most settings work both on Snap and Docker below.
# Note: Do not add single quotes '' to variables. Having spaces still works without quotes where required.
#
# The default authentication method used if a user does not exist to create and authenticate. Can be set as ldap.
#- DEFAULT_AUTHENTICATION_METHOD=ldap
#
# Enable or not the connection by the LDAP
#- LDAP_ENABLE=true
#
# The port of the LDAP server
#- LDAP_PORT=389
#
# The host server for the LDAP server
#- LDAP_HOST=localhost
#
# The base DN for the LDAP Tree
#- LDAP_BASEDN=ou=user,dc=example,dc=org
#
# Fallback on the default authentication method
#- LDAP_LOGIN_FALLBACK=false
#
# Reconnect to the server if the connection is lost
#- LDAP_RECONNECT=true
#
# Overall timeout, in milliseconds
#- LDAP_TIMEOUT=10000
#
# Specifies the timeout for idle LDAP connections in milliseconds
#- LDAP_IDLE_TIMEOUT=10000
#
# Connection timeout, in milliseconds
#- LDAP_CONNECT_TIMEOUT=10000
#
# If the LDAP needs a user account to search
#- LDAP_AUTHENTIFICATION=true
#
# The search user DN
#- LDAP_AUTHENTIFICATION_USERDN=cn=wekan_adm,ou=serviceaccounts,ou=admin,ou=prod,dc=mydomain,dc=com
#
# The password for the search user
#- LDAP_AUTHENTIFICATION_PASSWORD=pwd
#
# Enable logs for the module
#- LDAP_LOG_ENABLED=true
#
# If the sync of the users should be done in the background
#- LDAP_BACKGROUND_SYNC=false
#
# At which interval does the background task sync in milliseconds
#- LDAP_BACKGROUND_SYNC_INTERVAL=100
#
#- LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false
#
#- LDAP_BACKGROUND_SYNC_IMPORT_NEW_USERS=false
#
# If using LDAPS: LDAP_ENCRYPTION=ssl
#- LDAP_ENCRYPTION=false
#
# The certification for the LDAPS server. Certificate needs to be included in this docker-compose.yml file.
#- LDAP_CA_CERT=-----BEGIN CERTIFICATE-----MIIE+G2FIdAgIC...-----END CERTIFICATE-----
#
# Reject Unauthorized Certificate
#- LDAP_REJECT_UNAUTHORIZED=false
#
# Option to login to the LDAP server with the user's own username and password, instead of an administrator key. Default: false (use administrator key).
#- LDAP_USER_AUTHENTICATION="true"
#
# Optional extra LDAP filters. Don't forget the outmost enclosing parentheses if needed
#- LDAP_USER_SEARCH_FILTER=
#
# base (search only in the provided DN), one (search only in the provided DN and one level deep), or sub (search the whole subtree)
#- LDAP_USER_SEARCH_SCOPE=one
#
# Which field is used to find the user, like uid / sAMAccountName
#- LDAP_USER_SEARCH_FIELD=sAMAccountName
#
# Used for pagination (0=unlimited)
#- LDAP_SEARCH_PAGE_SIZE=0
#
# The limit number of entries (0=unlimited)
#- LDAP_SEARCH_SIZE_LIMIT=0
#
# Enable group filtering
#- LDAP_GROUP_FILTER_ENABLE=false
#
# The object class for filtering. Example: group
#- LDAP_GROUP_FILTER_OBJECTCLASS=
#
#- LDAP_GROUP_FILTER_GROUP_ID_ATTRIBUTE=
#
#- LDAP_GROUP_FILTER_GROUP_MEMBER_ATTRIBUTE=
#
#- LDAP_GROUP_FILTER_GROUP_MEMBER_FORMAT=
#
#- LDAP_GROUP_FILTER_GROUP_NAME=
#
# LDAP_UNIQUE_IDENTIFIER_FIELD : This field is sometimes class GUID (Globally Unique Identifier). Example: guid
#- LDAP_UNIQUE_IDENTIFIER_FIELD=
#
# LDAP_UTF8_NAMES_SLUGIFY : Convert the username to utf8
# example : LDAP_UTF8_NAMES_SLUGIFY=false
- LDAP_UTF8_NAMES_SLUGIFY=true
# LDAP_USERNAME_FIELD : Which field contains the ldap username
# example : LDAP_USERNAME_FIELD=username
- LDAP_USERNAME_FIELD=''
# LDAP_MERGE_EXISTING_USERS :
# example : LDAP_MERGE_EXISTING_USERS=true
- LDAP_MERGE_EXISTING_USERS=false
# LDAP_SYNC_USER_DATA :
# example : LDAP_SYNC_USER_DATA=true
- LDAP_SYNC_USER_DATA=false
# LDAP_SYNC_USER_DATA_FIELDMAP :
# example : LDAP_SYNC_USER_DATA_FIELDMAP={\"cn\":\"name\", \"mail\":\"email\"}
- LDAP_SYNC_USER_DATA_FIELDMAP=''
# LDAP_SYNC_GROUP_ROLES :
#- LDAP_UTF8_NAMES_SLUGIFY=true
#
# LDAP_USERNAME_FIELD : Which field contains the ldap username. username / sAMAccountName
#- LDAP_USERNAME_FIELD=sAMAccountName
#
# LDAP_FULLNAME_FIELD : Which field contains the ldap fullname. fullname / sAMAccountName
#- LDAP_FULLNAME_FIELD=fullname
#
#- LDAP_MERGE_EXISTING_USERS=false
#
# Allow existing account matching by e-mail address when username does not match
#- LDAP_EMAIL_MATCH_ENABLE=true
#
# LDAP_EMAIL_MATCH_REQUIRE : require existing account matching by e-mail address when username does match
#- LDAP_EMAIL_MATCH_REQUIRE=true
#
# LDAP_EMAIL_MATCH_VERIFIED : require existing account email address to be verified for matching
#- LDAP_EMAIL_MATCH_VERIFIED=true
#
# LDAP_EMAIL_FIELD : which field contains the LDAP e-mail address
#- LDAP_EMAIL_FIELD=mail
#-----------------------------------------------------------------
#- LDAP_SYNC_USER_DATA=false
#
#- LDAP_SYNC_USER_DATA_FIELDMAP={"cn":"name", "mail":"email"}
#
#- LDAP_SYNC_GROUP_ROLES=''
#
# The default domain of the ldap it is used to create email if the field is not map correctly with the LDAP_SYNC_USER_DATA_FIELDMAP
# example :
- LDAP_SYNC_GROUP_ROLES=''
# LDAP_DEFAULT_DOMAIN : The default domain of the ldap it is used to create email if the field is not map correctly with the LDAP_SYNC_USER_DATA_FIELDMAP
# example :
- LDAP_DEFAULT_DOMAIN=''
#- LDAP_DEFAULT_DOMAIN=mydomain.com
#
# Enable/Disable syncing of admin status based on ldap groups:
#- LDAP_SYNC_ADMIN_STATUS=true
#
# Comma separated list of admin group names to sync.
#- LDAP_SYNC_ADMIN_GROUPS=group1,group2
#---------------------------------------------------------------------
# Login to LDAP automatically with HTTP header.
# In below example for siteminder, at right side of = is header name.
#- HEADER_LOGIN_ID=HEADERUID
#- HEADER_LOGIN_FIRSTNAME=HEADERFIRSTNAME
#- HEADER_LOGIN_LASTNAME=HEADERLASTNAME
#- HEADER_LOGIN_EMAIL=HEADEREMAILADDRESS
#---------------------------------------------------------------------
# ==== LOGOUT TIMER, probably does not work yet ====
# LOGOUT_WITH_TIMER : Enables or not the option logout with timer
# example : LOGOUT_WITH_TIMER=true
#- LOGOUT_WITH_TIMER=
#
# LOGOUT_IN : The number of days
# example : LOGOUT_IN=1
#- LOGOUT_IN=
#
# LOGOUT_ON_HOURS : The number of hours
# example : LOGOUT_ON_HOURS=9
#- LOGOUT_ON_HOURS=
#
# LOGOUT_ON_MINUTES : The number of minutes
# example : LOGOUT_ON_MINUTES=55
#- LOGOUT_ON_MINUTES=
#-------------------------------------------------------------------
depends_on:
- wekandb
#---------------------------------------------------------------------------------
# ==== OPTIONAL: SHARE DATABASE TO OFFICE LAN AND REMOTE VPN ====
# When using Wekan both at office LAN and remote VPN:
# 1) Have above Wekan docker container config with LAN IP address
# 2) Copy all of above wekan container config below, look above of this part above and all config below it,
# before above depends_on: part:
#
# wekan:
# #-------------------------------------------------------------------------------------
# # ==== MONGODB AND METEOR VERSION ====
# # a) For Wekan Meteor 1.8.x version at meteor-1.8 branch, .....
#
#
# and change name to different name like wekan2 or wekanvpn, and change ROOT_URL to server VPN IP
# address.
# 3) This way both Wekan containers can use same MongoDB database
# and see the same Wekan boards.
# 4) You could also add 3rd Wekan container for 3rd network etc.
# EXAMPLE:
# wekan2:
# ....COPY CONFIG FROM ABOVE TO HERE...
# environment:
# - ROOT_URL='http://10.10.10.10'
# ...COPY CONFIG FROM ABOVE TO HERE...
#---------------------------------------------------------------------------------
# OPTIONAL NGINX CONFIG FOR REVERSE PROXY
# nginx:
# image: nginx
# container_name: nginx
# restart: always
# networks:
# - wekan-tier
# depends_on:
# - wekan
# ports:
# - 80:80
# - 443:443
# volumes:
# - ./nginx/ssl:/etc/nginx/ssl/:ro
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
## Alternative volume config:
## volumes:
## - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
## - ./nginx/ssl/ssl.conf:/etc/nginx/conf.d/ssl/ssl.conf:ro
## - ./nginx/ssl/testvm-ehu.crt:/etc/nginx/conf.d/ssl/certs/mycert.crt:ro
## - ./nginx/ssl/testvm-ehu.key:/etc/nginx/conf.d/ssl/certs/mykey.key:ro
## - ./nginx/ssl/pphrase:/etc/nginx/conf.d/ssl/pphrase:ro
volumes:
wekan-db:
driver: local
Executable
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
# Find text from all subdirectories
# and ignore all temporary directories:
# - node-modules = installed node modules
# - .build = Wekan bundle that is combined from source. Do not edit these, these are deleted and recreated.
# - .meteor = Meteor version, packages etc at .meteor/local
# - .git = git history
# If less or more that 1 parameter, show usage.
if (( $# != 1 )); then
echo 'Usage: ./find.sh text-to-find'
exit 0
fi
find . | grep -v node_modules | grep -v .build | grep -v .meteor | grep -v .git | xargs grep --no-messages $1 | less
+22
View File
@@ -0,0 +1,22 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
OWNERS
+13
View File
@@ -0,0 +1,13 @@
name: wekan
version: 1.0.0
appVersion: 2.x.x
kubeVersion: "^1.8.0-0"
description: Open Source kanban
home: https://wekan.github.io/
icon: https://wekan.github.io/wekan-logo.svg
sources:
- https://github.com/wekan/wekan
maintainers:
- name: technotaff
email: github@randall.cc
engine: gotpl
+4
View File
@@ -0,0 +1,4 @@
approvers:
- technotaff
reviewers:
- technotaff
+58
View File
@@ -0,0 +1,58 @@
# Helm Chart for Wekan
## Features
o Uses a MongoDB replica set by default - this allows fault-tolerant
and scalable MongoDB deployment (or just set the replicas to 1 for
a single server install)
o Optional Horizontal Pod Autoscaler (HPA), so that your Wekan pods
will scale automatically with increased CPU load.
## The configurable values (values.yaml)
Scaling Wekan:
```yaml
## Configuration for wekan component
##
replicaCount: 1
```
**replicaCount** Will set the initial number of replicas for the Wekan pod (and container)
```yaml
## Configure an horizontal pod autoscaler
##
autoscaling:
enabled: true
config:
minReplicas: 1
maxReplicas: 16
## Note: when setting this, a `resources.request.cpu` is required. You
## likely want to set it to `1` or some lower value.
##
targetCPUUtilizationPercentage: 80
```
This section (if *enabled* is set to **true**) will enable the Kubernetes Horizontal Pod Autoscaler (HPA).
**minReplicas:** this is the minimum number of pods to scale down to (We recommend setting this to the same value as **replicaCount**).
**maxReplicas:** this is the maximum number of pods to scale up to.
**targetCPUUtilizationPercentage:** This is the CPU at which the HPA will scale-out the number of Wekan pods.
```yaml
mongodb-replicaset:
enabled: true
replicas: 3
replicaSetName: rs0
securityContext:
runAsUser: 1000
fsGroup: 1000
runAsNonRoot: true
```
This section controls the scale of the MongoDB redundant Replica Set.
**replicas:** This is the number of MongoDB instances to include in the set. You can set this to 1 for a single server - this will still allow you to scale-up later with a helm upgrade.
+1
View File
@@ -0,0 +1 @@
+5
View File
@@ -0,0 +1,5 @@
dependencies:
- name: mongodb-replicaset
version: 3.6.x
repository: "https://kubernetes-charts.storage.googleapis.com/"
condition: mongodb-replicaset.enabled
+19
View File
@@ -0,0 +1,19 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range .Values.ingress.hosts }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "wekan.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w {{ template "wekan.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "wekan.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "wekan.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:8080
{{- end }}
Loaded 100 of 600 files, more files were not shown because too many files have changed in this diff. Show more