Compare commits

...
564 Commits
Author SHA1 Message Date
Lauri Ojansivu cd0cd64849 v7.99 2025-10-11 06:13:27 +03:00
Lauri Ojansivu aab671398c Improve automatic Snap upgrades.
Thanks to xet7 !
2025-10-11 05:52:41 +03:00
Lauri Ojansivu d64aeb25d5 Updated ChangeLog. 2025-10-11 04:57:24 +03:00
Lauri Ojansivu aa4fa83127 Updated ChangeLog. 2025-10-11 04:50:23 +03:00
Lauri Ojansivu 81c3dc1d95 Security Fix JVN#15385465: CWE-79 XSS, that affected WeKan 7.94.
Thanks to Sho Sugiyama and xet7 !
2025-10-11 04:47:17 +03:00
Lauri Ojansivu 746eecf3d8 Updated ChangeLog. 2025-10-11 04:25:26 +03:00
Lauri Ojansivu cd948fb576 Added missing metadata fields to snapcraft.yaml .
Thanks to xet7 !
2025-10-11 04:20:28 +03:00
Lauri Ojansivu 4ec4e19e63 Try to fix Snap automatic upgrade.
Thanks to xet7 !
2025-10-11 04:02:02 +03:00
Lauri Ojansivu d88d197de9 Updated release scripts of snapcraft pack command syntax.
Thanks to xet7 !
2025-10-11 03:11:32 +03:00
Lauri Ojansivu 2a24918a9c Snap: Removed double mongo3 that's already at migratemongo.
Thanks to xet7 !
2025-10-11 03:09:33 +03:00
Lauri Ojansivu d2a85b41e4 v7.98 2025-10-11 02:07:44 +03:00
Lauri Ojansivu 9bcd991a61 Updated ChangeLog. 2025-10-11 02:02:10 +03:00
Lauri Ojansivu 1a7bd65e59 Fixed showing translations always, regardsless of is ROOT_URL set correctly or not.
Thanks to xet7 !
2025-10-11 01:57:08 +03:00
Lauri Ojansivu f8ee929cf7 Updated ChangeLog. 2025-10-11 01:46:01 +03:00
Lauri Ojansivu 734165f3c7 Fix sizes of drag handles at desktop mode.
Thanks to xet7 !
2025-10-11 01:44:38 +03:00
Lauri Ojansivu 8f9ef1bde8 Updated ChangeLog. 2025-10-11 01:24:31 +03:00
Lauri Ojansivu 2119c6ab0c Fix DOMPurify paths. Part 4.
Thanks to xet7 !
2025-10-11 01:23:18 +03:00
Lauri Ojansivu a85479f73c Updated ChangeLog. 2025-10-11 01:09:58 +03:00
Lauri Ojansivu 21ba0a9606 Fix DOMPurify paths. Part 3.
Thanks to xet7 !
2025-10-11 01:08:39 +03:00
Lauri Ojansivu 82ba0f9593 Updated ChangeLog. 2025-10-11 01:03:22 +03:00
Lauri Ojansivu 7769124401 Fix DOMPurify paths. Part 2.
Thanks to xet7 !
2025-10-11 00:58:00 +03:00
Lauri Ojansivu d9c978e7fc Merge branch 'main' of github.com:wekan/wekan 2025-10-11 00:50:14 +03:00
Lauri Ojansivu 90899f0928 Fix DOMPurify paths.
Thanks to xet7 !
2025-10-11 00:49:43 +03:00
Lauri Ojansivu f0421da517 Updated translations. 2025-10-11 00:41:06 +03:00
Lauri Ojansivu 573d4bf2cb Updated ChangeLog. 2025-10-11 00:31:46 +03:00
Lauri Ojansivu f1e1fd3593 Add Snap automatic upgrades. Part 2.
Thanks to xet7 !
2025-10-11 00:29:46 +03:00
Lauri Ojansivu c387c5bc34 Updated ChangeLog. 2025-10-11 00:27:04 +03:00
Lauri Ojansivu 0549bc0b0c Add Snap automatic upgrades.
Thanks to xet7 !
2025-10-11 00:25:16 +03:00
Lauri Ojansivu c2a3e11324 Updated ChangeLog. 2025-10-10 23:50:49 +03:00
Lauri Ojansivu 107e2ac900 Add support for Docker/Compose Secrets for passwords to Docker/Snap/Bundle platforms.
Thanks to Roemer and xet7 !

Fixes #5724
2025-10-10 23:46:48 +03:00
Lauri Ojansivu 3b60bdea14 Updated ChangeLog. 2025-10-10 23:22:59 +03:00
Lauri Ojansivu f6591d7820 Security Fix usd-2022-0041: CWE-284 Improper Access Control.
Thanks to Christian Pöschl of usd AG and xet7 !
2025-10-10 23:19:58 +03:00
Lauri Ojansivu 6bbd622066 Updated ChangeLog. 2025-10-10 23:16:26 +03:00
Lauri Ojansivu ee79cab7b2 Security Fix JVN#86586539: Stored XSS.
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7.
2025-10-10 23:14:06 +03:00
Lauri Ojansivu a0b94065c5 Updated ChangeLog. 2025-10-10 23:09:28 +03:00
Lauri Ojansivu e1fa607f87 Security Fix JVN#74210258: Stored XSS.
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7 !
2025-10-10 23:06:06 +03:00
Lauri Ojansivu 2e91a359f5 Updated ChangeLog. 2025-10-10 23:02:37 +03:00
Lauri Ojansivu 9720e703fd Security Fix JVN#14269684: Broken access control.
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7 !
2025-10-10 22:59:20 +03:00
Lauri Ojansivu f88898d5b8 Updated ChangeLog. 2025-10-10 22:22:43 +03:00
Lauri Ojansivu 30c1597b65 Security Fix FG-VD-22-078: Prevent SVG Billion Laughs Attack.
Thanks to Nguyen Thanh Nguyen of Fortinet's FortiGuard Labs and xet7 !
2025-10-10 22:16:47 +03:00
Lauri Ojansivu 5bc5171220 Updated ChangeLog. 2025-10-10 22:12:25 +03:00
Lauri Ojansivu d0f118e7af Security Fix: Computational Resource Abuse in Export endpoints.
Thanks to Anynymous Security Researcher and xet7 !
2025-10-10 22:09:27 +03:00
Lauri Ojansivu c481443667 Updated ChangeLog. 2025-10-10 22:04:30 +03:00
Lauri Ojansivu b87cff1289 Security Fix: IDOR CWE-639 that affected WeKan 7.80-7.93.
Thanks to apitech.fr and xet7 !
2025-10-10 21:59:04 +03:00
Lauri Ojansivu 0c080830bc Updated ChangeLog. 2025-10-10 21:48:27 +03:00
Lauri Ojansivu cdd7d69c66 Drag any files from file manager to minicard or opened card. Part 2.
Thanks to xet7 !

Fixes #2936
2025-10-10 21:46:07 +03:00
Lauri Ojansivu c1cbcdcc72 Updated ChangeLog. 2025-10-10 21:21:12 +03:00
Lauri Ojansivu 1c84b19f24 Show console.log 'Legacy attachments route loaded' only when environment variable DEBUG=true.
Thanks to xet7 !
2025-10-10 21:19:00 +03:00
Lauri Ojansivu 2c73dae019 Merge branch 'main' of github.com:wekan/wekan 2025-10-10 21:16:29 +03:00
Lauri Ojansivu d285850a04 Updated ChangeLog. 2025-10-10 21:15:55 +03:00
Lauri Ojansivu 719ef87efc Make possible for lists to have different names at different swimlanes. Make possible to drag list from one swimlane to another swimlane.
Thanks to xet7 !
2025-10-10 21:14:44 +03:00
Lauri Ojansivu 039b9abf5e Updated translations 2025-10-10 20:37:22 +03:00
Lauri Ojansivu 39daf56811 Updated ChangeLog. 2025-10-10 19:12:09 +03:00
Lauri Ojansivu a8de2f224f Use attachments from old CollectionFS database structure, when not yet migrated to Meteor-Files/ostrio-files, without needing to migrate database structure.
Thanks to xet7 !
2025-10-10 19:07:04 +03:00
Lauri Ojansivu dda013844c Updated ChangeLog. 2025-10-10 18:55:13 +03:00
Lauri Ojansivu 3e9481c5bd Drag any files from file manager to minicard or opened card.
Thanks to xet7 !

Fixes #2936
2025-10-10 18:52:30 +03:00
Lauri Ojansivu 85ac03a892 Updated ChangeLog. 2025-10-09 05:54:04 +03:00
Lauri Ojansivu 752699d1c2 Mobile one board per row. Board zoom size percent. Board toggle mobile/desktop mode. In Progress.
Thanks to xet7 !

Related #5902
2025-10-09 05:48:41 +03:00
Lauri Ojansivu 339ca581ab Merge branch 'main' of github.com:wekan/wekan 2025-10-09 02:07:00 +03:00
Lauri Ojansivu 20e9cf1144 Text and icons from fixed sizes to scaleable sizes. Thanks to xet7. 2025-10-09 02:06:26 +03:00
Lauri Ojansivu 9737884c4b Text and icon from fixed sized to scaleable sizes. Thanks to xet7. 2025-10-09 02:06:16 +03:00
Lauri Ojansivu 2f5670e830 v7.97 2025-10-08 23:57:08 +03:00
Lauri Ojansivu 108b18cebf Updated ChangeLog. 2025-10-08 23:48:26 +03:00
Lauri Ojansivu 814ac22a0d Updated ChangeLog. 2025-10-08 23:43:55 +03:00
Lauri Ojansivu 3814a218c2 Removed white box that appeared when clicking something.
Thanks to xet7 !

Fixes #5899
2025-10-08 23:38:44 +03:00
Lauri Ojansivu 3fda90612d Some mobile fixes.
Thanks to xet7 !

Fixes #5899
2025-10-08 23:32:13 +03:00
Lauri Ojansivu 05762aa50c Updated ChangeLog. 2025-10-08 09:37:51 +03:00
Lauri Ojansivu 9a31371de0 Fixed translation of "Change Language" at login page.
Thanks to xet7 !
2025-10-08 09:36:39 +03:00
Lauri Ojansivu b9b7143185 Updated ChangeLog. 2025-10-08 09:21:26 +03:00
Lauri Ojansivu 972721bdb5 Merge branch 'seve12-main' 2025-10-08 09:17:53 +03:00
Lauri Ojansivu 3a48982916 v7.96 2025-10-08 08:44:09 +03:00
Lauri Ojansivu 6b3a6f9f7d Updated ChangeLog. 2025-10-08 08:44:09 +03:00
Lauri Ojansivu 48fddecb62 Updated to MongoDB 7.0.25 at Snap Candidate.
Thanks to MongoDB developers !
2025-10-08 08:44:09 +03:00
Lauri Ojansivu 7f0d1cc5b3 Updated ChangeLog. 2025-10-08 08:44:09 +03:00
Lauri Ojansivu 70e82be0b4 Hide extra keyboard shortcuts toggle. Thanks to xet7. 2025-10-08 08:44:09 +03:00
Lauri Ojansivu 5fc0809844 Updated ChangeLog. 2025-10-08 08:44:09 +03:00
Lauri Ojansivu c79990bcd9 Added missing screenshots from wekan.github.io history to wekan/docs/Features/ . Thanks to xet7 2025-10-08 08:44:09 +03:00
dependabot[bot] cd9e7412ea Bump docker/login-action from 3.5.0 to 3.6.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/184bdaa0721073962dff0199f1fb9940f07167d1...5e57cd118135c172c3672efd75eb46360885c0ef)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-08 08:44:09 +03:00
Lauri Ojansivu 3e472606b5 Fixed links at docs. Thanks to xet7 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 2966bc3204 Updated translations 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 5dc6093eec Updated email address 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 86fc60f5ba Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 8189a3f9ab Fixed find.sh script errors about unmatched single quotes and binary files that are now ignored.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu 76a65e2533 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Jean-Sébastien Guay ad2914934e Fix links in docker-compose.yml to point to doc in repo 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 2769ba2874 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 294f1e178e Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu c994d34bb8 Updated to MongoDB 7.0.24 at Snap Candidate.
Thanks to MongoDB developers !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu 42b5dd0751 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu f884d6d471 Added missing mobile drag drop image to docs from wekan.github.io git history.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu abe915a8d6 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu a2e8de2fd8 Updated release script for new command of uploading snap package to Snap Store.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu e34ca6a8a5 v7.95 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 596c9de603 Updated translations 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 4170361a1c Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 978a36ea77 Updated dependencies.
Thanks to developers of dependencies !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu 8745ef7de8 Reorganized docs 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 2ce929b7b3 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 2dcdfa2862 Added PGP public key for sending encrypted email.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu b18daac9c9 Updated ChangeLog. 2025-10-08 08:44:08 +03:00
sowwos 606041a00d docs(windows): clarify WRITABLE_PATH/attachments + LAN bind instructions (nits) 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 4ed5952a81 Updates 2025-10-08 08:44:08 +03:00
Lauri Ojansivu 37bfce2eb7 Added missing image to WeKan Multiverse page.
Thanks to xet7 !
2025-10-08 08:44:08 +03:00
Lauri Ojansivu 59541699ce Updated ChangeLog. 2025-10-08 08:44:08 +03:00
Lauri Ojansivu af73c16e37 More info about ToroDB, FerretDB, Turso, TigerBeetle, PostgreSQL, SQLite etc.
Thanks to xet7 !
2025-10-08 08:44:07 +03:00
Lauri Ojansivu 673b09b84b Updated ChangeLog. 2025-10-08 08:44:07 +03:00
Lauri Ojansivu 09f8edfead Fixed image link at docs.
Thanks to xet7 !
2025-10-08 08:44:07 +03:00
Lauri Ojansivu e1ebdeca4f Updated ChangeLog. 2025-10-08 08:44:07 +03:00
Lauri Ojansivu 31769aa4af Updated upgrade link.
Thanks to xet7 !
2025-10-08 08:44:07 +03:00
seve12 b32ad86ce7 fixed issue 5887 2025-10-07 22:23:19 +03:00
Lauri Ojansivu 7350473a65 v7.96 2025-10-07 01:14:42 +03:00
Lauri Ojansivu 1c87e337d6 Updated ChangeLog. 2025-10-07 01:06:21 +03:00
Lauri Ojansivu dec038e7ed Updated to MongoDB 7.0.25 at Snap Candidate.
Thanks to MongoDB developers !
2025-10-07 01:05:01 +03:00
Lauri Ojansivu ebe6f7813e Updated ChangeLog. 2025-10-07 00:45:05 +03:00
Lauri Ojansivu 706dbfacac Merge branch 'seve12-main' 2025-10-07 00:36:50 +03:00
Lauri Ojansivu 62ad588aa9 Hide extra keyboard shortcuts toggle. Thanks to xet7. 2025-10-07 00:35:17 +03:00
Lauri Ojansivu 3c776e2ab6 Merge branch 'main' of github.com:seve12/wekan into seve12-main 2025-10-07 00:19:46 +03:00
seve12 ab4e2d1ed6 fixed issue #5885 2025-10-06 16:34:49 +03:00
Lauri Ojansivu 5e90c4a142 Updated ChangeLog. 2025-10-02 20:15:35 +03:00
Lauri Ojansivu 9a7fa25ca3 Added missing screenshots from wekan.github.io history to wekan/docs/Features/ . Thanks to xet7 2025-10-02 20:05:38 +03:00
Lauri Ojansivu 65cb0641f3 Merge branch 'main' of github.com:wekan/wekan 2025-10-02 19:57:56 +03:00
Lauri Ojansivu 6f2b891214 Fixed links at docs. Thanks to xet7 2025-10-02 19:57:28 +03:00
Lauri Ojansivu 44d7ab83ec Merge pull request #5890 from wekan/dependabot/github_actions/docker/login-action-3.6.0
Bump docker/login-action from 3.5.0 to 3.6.0
2025-10-02 00:06:19 +03:00
dependabot[bot] b328cc3f6a Bump docker/login-action from 3.5.0 to 3.6.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/184bdaa0721073962dff0199f1fb9940f07167d1...5e57cd118135c172c3672efd75eb46360885c0ef)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-29 23:33:41 +00:00
seve12 836226a8d3 RICHER_CARD_COMMENT_EDITOR=true has no effect (no rich text toolbar shown) fixed! 2025-09-29 15:56:23 +03:00
Lauri Ojansivu 2083f6630a Updated translations 2025-09-28 00:42:45 +03:00
Lauri Ojansivu 25e1e9028f Updated email address 2025-09-28 00:38:04 +03:00
seve12 a5651c686f fix 22.9 Unable to download large PDF files attached to card issue fixed 2025-09-23 13:40:14 +03:00
Lauri Ojansivu 93f0e0b125 Updated ChangeLog. 2025-09-21 15:01:17 +03:00
Lauri Ojansivu 730bb6d166 Fixed find.sh script errors about unmatched single quotes and binary files that are now ignored.
Thanks to xet7 !
2025-09-21 14:59:00 +03:00
Lauri Ojansivu 855bac59bf Updated ChangeLog. 2025-09-19 23:46:32 +03:00
Lauri Ojansivu 870900b92a Merge pull request #5882 from Skylark13/main
Fix links in docker-compose.yml to point to doc in repo
2025-09-19 23:45:09 +03:00
Jean-Sébastien Guay a1d5802d36 Fix links in docker-compose.yml to point to doc in repo 2025-09-19 15:26:53 -04:00
Lauri Ojansivu 6e16fa3992 Updated ChangeLog. 2025-09-19 16:35:59 +03:00
Lauri Ojansivu ee3b49ce59 Updated ChangeLog. 2025-09-19 03:08:40 +03:00
Lauri Ojansivu 3253dd5010 Updated to MongoDB 7.0.24 at Snap Candidate.
Thanks to MongoDB developers !
2025-09-19 03:06:06 +03:00
Lauri Ojansivu a10d8e0438 Updated ChangeLog. 2025-09-19 01:56:18 +03:00
Lauri Ojansivu 5151814e98 Added missing mobile drag drop image to docs from wekan.github.io git history.
Thanks to xet7 !
2025-09-19 01:54:01 +03:00
Lauri Ojansivu 2e2a0f01f4 Updated ChangeLog. 2025-09-18 23:11:33 +03:00
Lauri Ojansivu dec9b82da0 Updated release script for new command of uploading snap package to Snap Store.
Thanks to xet7 !
2025-09-18 23:09:03 +03:00
Lauri Ojansivu 33f4db5871 v7.95 2025-09-18 21:59:50 +03:00
Lauri Ojansivu 9a086c0397 Updated translations 2025-09-18 21:43:38 +03:00
Lauri Ojansivu 013ddb8978 Updated ChangeLog. 2025-09-18 21:34:15 +03:00
Lauri Ojansivu c4161c5ce6 Updated dependencies.
Thanks to developers of dependencies !
2025-09-18 21:29:36 +03:00
seve12 392b8dd5b2 fix 17.9.2025 2025-09-17 22:34:46 +03:00
seve12 d19eb801f3 fixes 16.9.2025 2025-09-16 23:05:35 +03:00
seve12 ed416ca555 fixes 25.9 2025-09-15 19:31:18 +03:00
seve12 106009316f more fixes 2025-09-10 17:17:51 +03:00
seve12 cb10ad3a20 Fixed 9.2.4.6, 9.1.3.5 and 11.7 2025-09-10 13:04:37 +03:00
Lauri Ojansivu 2fad0099e4 Reorganized docs 2025-08-27 16:11:15 +03:00
Lauri Ojansivu 454416b0bd Updated ChangeLog. 2025-08-26 15:15:44 +03:00
Lauri Ojansivu dd80b7308b Added PGP public key for sending encrypted email.
Thanks to xet7 !
2025-08-26 15:14:19 +03:00
Lauri Ojansivu fe5c5f1bdc Updated ChangeLog. 2025-08-21 13:11:51 +03:00
Lauri Ojansivu 79074deb34 Merge pull request #5872 from sowwos/docs/windows-offline-clarify
This adds two actionable Windows notes to docs/Platforms/Propietary/Windows/Offline.md:  - Explain that WRITABLE_PATH and ATTACHMENTS_STORE_PATH must be set before start to avoid the attachments error   (“The 'path' argument must be of type string. Received undefined” from models/attachments.js). - Show how to expose the dev server on LAN on Windows (BIND_IP=0.0.0.0 + ROOT_URL=http://<LAN-IP>:4000).  Tested on Windows 11 with Meteor dev server. Follow-up to #5871 (closed as wrong file).
2025-08-21 13:07:59 +03:00
sowwos db0294c95e docs(windows): clarify WRITABLE_PATH/attachments + LAN bind instructions (nits) 2025-08-21 07:19:13 +03:00
Lauri Ojansivu 8f0fa88eac Updates 2025-08-20 03:20:49 +03:00
Lauri Ojansivu 946f7045e9 Added missing image to WeKan Multiverse page.
Thanks to xet7 !
2025-08-20 03:19:26 +03:00
Lauri Ojansivu dda8c90d44 Updated ChangeLog. 2025-08-20 02:26:20 +03:00
Lauri Ojansivu 701485d76a More info about ToroDB, FerretDB, Turso, TigerBeetle, PostgreSQL, SQLite etc.
Thanks to xet7 !
2025-08-20 02:24:38 +03:00
Lauri Ojansivu b25198b87e Updated ChangeLog. 2025-08-20 00:58:58 +03:00
Lauri Ojansivu ad7e3774c2 Fixed image link at docs.
Thanks to xet7 !
2025-08-20 00:57:40 +03:00
Lauri Ojansivu ee67dea96c Updated ChangeLog. 2025-08-20 00:43:26 +03:00
Lauri Ojansivu b3d3bf1593 Updated upgrade link.
Thanks to xet7 !
2025-08-20 00:41:22 +03:00
Lauri Ojansivu 53726fed24 Updated WeKan version to Dockerfile.
Thanks to xet7 !
2025-08-18 19:01:19 +03:00
Lauri Ojansivu 7d2ca2c811 v7.94 2025-08-18 18:54:35 +03:00
Lauri Ojansivu c0d10a0ec3 Updated ChangeLog. 2025-08-18 18:35:09 +03:00
Lauri Ojansivu 8e01e3c762 Upgraded to MongoDB 7.0.23 at Snap Candidate.
Thanks to MongoDB developers !
2025-08-18 18:30:21 +03:00
Lauri Ojansivu 04be599893 Updates 2025-08-18 18:15:51 +03:00
Lauri Ojansivu f6cb7fddf1 Updated ChangeLog. 2025-08-13 05:34:28 +03:00
Lauri Ojansivu a662283b7d Updates to design docs. 2025-08-13 05:32:26 +03:00
Lauri Ojansivu f34490fe28 Reorganized Design Docs 2025-08-13 05:30:35 +03:00
Lauri Ojansivu 1a98c86a37 Updated ChangeLog. 2025-08-12 16:55:06 +03:00
Lauri Ojansivu 97b5931a4f Updated dependencies.
Thanks to developers of dependencies !
2025-08-12 16:53:34 +03:00
Lauri Ojansivu 2a4dd9b693 Updated ChangeLog. 2025-08-12 16:04:41 +03:00
Lauri Ojansivu ecf31c3675 Updated MongoDB to 7.0.22.
Thanks to MongoDB developers !
2025-08-12 16:03:28 +03:00
Lauri Ojansivu 9b0d0a2b7c Updated ChangeLog. 2025-08-12 15:59:18 +03:00
Lauri Ojansivu e2ffca2e39 Merge pull request #5865 from wekan/dependabot/github_actions/actions/download-artifact-5
Bump actions/download-artifact from 4 to 5
2025-08-12 15:58:29 +03:00
Lauri Ojansivu a8435879cf Updated translations 2025-08-12 15:56:52 +03:00
Lauri Ojansivu e16695585a Updated ChangeLog. 2025-08-12 15:03:27 +03:00
Lauri Ojansivu a7bcfc6db7 Added docs for Windows SSL/TLS. Part 6.
Thanks to xet7 !

Related #5866
2025-08-12 15:01:56 +03:00
Lauri Ojansivu 21bed98d69 Updated ChangeLog. 2025-08-12 15:00:23 +03:00
Lauri Ojansivu 044793cc44 Added docs for Windows SSL/TLS. Part 5.
Thanks to xet7 !

Related #5866
2025-08-12 14:59:20 +03:00
Lauri Ojansivu 083a7050b9 Updated ChangeLog. 2025-08-12 14:55:13 +03:00
Lauri Ojansivu cc78e19740 Added docs for Windows SSL/TLS. Part 4.
Thanks to xet7 !

Related #5866
2025-08-12 14:53:09 +03:00
Lauri Ojansivu ee01a07b0a Added docs for Windows SSL/TLS. Part 3.
Thanks to xet7 !

Related #5866
2025-08-12 14:44:34 +03:00
Lauri Ojansivu ce528b1826 Added docs for Windows SSL/TLS. Part 2.
Thanks to xet7 !

Related #5866
2025-08-12 14:40:33 +03:00
Lauri Ojansivu 92c0543614 Added docs for Windows SSL/TLS.
Thanks to xet7 !

Related #5866
2025-08-12 14:33:55 +03:00
dependabot[bot] b6638f4a29 Bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 07:34:46 +00:00
Lauri Ojansivu 96be56a620 Merge pull request #5864 from wekan/dependabot/github_actions/actions/checkout-5
Bump actions/checkout from 4 to 5
2025-08-12 10:33:51 +03:00
dependabot[bot] 2e555e420a Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 03:02:57 +00:00
Lauri Ojansivu a849951c53 Update LXD docs 2025-08-09 23:03:09 +03:00
Lauri Ojansivu 435cb04717 Update PWA docs 2025-08-09 21:14:30 +03:00
Lauri Ojansivu 25a375261e Move docs PWA to Browsers directory 2025-08-09 21:09:27 +03:00
Lauri Ojansivu 1a1a44616f Revert accessibility changes temporarily.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/5857
2025-08-09 14:23:40 +03:00
Lauri Ojansivu e6347a305c Updated ChangeLog. 2025-08-09 12:00:39 +03:00
Lauri Ojansivu b137108ae1 Fixed uppercase K of WeKan.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/5857
2025-08-09 11:55:50 +03:00
Lauri Ojansivu 4ce7ff7cef Merge pull request #5857 from seve12/main
Accessibility:
- Added product name to page titles, settings and global search.
- More accessible header and layout templates, modal dialogs, DOM structure, color contrast.
2025-08-09 11:33:50 +03:00
seve12 184415a026 Enhance color contrast and accessibility for various UI elements 2025-08-09 04:29:30 +03:00
Lauri Ojansivu 3977adcb8f Updated translations 2025-08-08 12:38:15 +03:00
Lauri Ojansivu 1c47f98f59 Feature: Added brute force login protection settings to Admin Panel/People/Locked Users. Part 2.
Thanks to xet7 !
2025-08-08 12:36:17 +03:00
seve12 9f0c37352e Enhance accessibility for modal dialogs and improve DOM structure 2025-08-07 23:59:34 +03:00
seve12 7a20fa4805 Merge branch 'main' of https://github.com/seve12/wekan 2025-08-06 19:29:25 +03:00
seve12 6a713d9e8d Refactor header and layout templates for improved accessibility and consistency 2025-08-06 19:18:01 +03:00
Lauri Ojansivu 51b0544752 Updated translations. 2025-08-06 08:17:02 +03:00
seve12 1022a7aa3a Update settingBody.js 2025-08-05 20:23:52 +03:00
seve12 c048678844 Update router.js 2025-08-05 20:22:09 +03:00
seve12 f9fb02457c Merge branch 'main' of https://github.com/seve12/wekan 2025-08-05 20:07:50 +03:00
seve12 ce419ce64e Merge pull request #1 from seve12/severi
Improves accessibility by disabling custom Tab handling
2025-08-05 20:05:39 +03:00
severi12345 ecb6ff57fc Update page titles to include product name in settings and global search 2025-08-05 19:59:33 +03:00
Lauri Ojansivu 663866562f Updated ChangeLog. 2025-08-05 12:57:00 +03:00
Lauri Ojansivu dfdd0b6cbb Added info about Sandstorm Radicale Calendar and Contacts.
Thanks to xet7 !
2025-08-05 12:55:29 +03:00
Lauri Ojansivu c81ca82822 Updated translations. 2025-08-05 12:02:36 +03:00
Lauri Ojansivu 66b067eb49 Updated translations. 2025-08-05 11:26:23 +03:00
Lauri Ojansivu 4e9f2dc46a Updated ChangeLog. 2025-08-05 11:24:34 +03:00
Lauri Ojansivu f02d8b61b5 Merge pull request #5856 from wekan/dependabot/github_actions/docker/login-action-3.5.0
Bump docker/login-action from 3.4.0 to 3.5.0
2025-08-05 11:18:16 +03:00
Lauri Ojansivu 088de1877c Merge pull request #5855 from wekan/dependabot/github_actions/docker/metadata-action-5.8.0
Bump docker/metadata-action from 5.7.0 to 5.8.0
2025-08-05 11:17:59 +03:00
dependabot[bot] 4611abffed Bump docker/login-action from 3.4.0 to 3.5.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/74a5d142397b4f367a81961eba4e8cd7edddf772...184bdaa0721073962dff0199f1fb9940f07167d1)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 3.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 03:24:07 +00:00
dependabot[bot] f206f2f45c Bump docker/metadata-action from 5.7.0 to 5.8.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.7.0 to 5.8.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/902fa8ec7d6ecbf8d84d538b9b233a880e428804...c1e51972afc2121e065aed6d45c65596fe445f3f)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 5.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 03:17:28 +00:00
Lauri Ojansivu 9c5f5757be Updated translations. 2025-08-05 00:50:29 +03:00
Lauri Ojansivu ec2e0f6fed Updated ChangeLog. 2025-08-05 00:33:46 +03:00
Lauri Ojansivu ae0d059b6f Feature: Added brute force login protection settings to Admin Panel/People/Locked Users.
Added filtering of Admin Panel/People/People: All Users/Locked Users Only/Active/Not Active.
Added visual indicators: red lock icon for locked users, green check for active users, and red X for inactive users.
Added "Unlock All" button to quickly unlock all brute force locked users.
Added ability to toggle user active status directly from the People page.
Moved lockout settings from environment variables to database so admins can configure the lockout thresholds directly in the UI.

Thanks to xet7.
2025-08-05 00:31:43 +03:00
Lauri Ojansivu 0132b801b2 Updated translations. 2025-08-04 21:34:33 +03:00
Lauri Ojansivu 06ca564ec2 Updated ChangeLog. 2025-08-04 21:26:51 +03:00
Lauri Ojansivu d83ce5e633 Feature: Accessibility page at /accessibility. Settings at Admin Panel. When enabled, link at right sidebar.
Thanks to xet7 !
2025-08-04 21:22:14 +03:00
Lauri Ojansivu 5287319fde Updated translations. 2025-08-04 19:53:31 +03:00
Lauri Ojansivu c75a23e693 Updated ChangeLog. 2025-08-04 19:49:59 +03:00
Lauri Ojansivu 180bf930c1 Updated translations. 2025-08-04 19:46:24 +03:00
Lauri Ojansivu c16e99ba1e Added FerretDB/PostgreSQL to changelog. 2025-08-04 19:21:16 +03:00
Lauri Ojansivu b9887fc917 Fixed link at OpenShift docs.
Thanks to xet7 !

Related #5854
2025-08-04 19:17:17 +03:00
Lauri Ojansivu 96b36bd8ef Updated ChangeLog. 2025-08-04 18:24:27 +03:00
Lauri Ojansivu 0e32f666eb Comment out not used Tab code at accessibility related changes.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/5853
2025-08-04 18:17:24 +03:00
Lauri Ojansivu 1341fc6a98 Merge pull request #5853 from seve12/severi
Improves accessibility by disabling custom Tab handling
2025-08-04 18:12:46 +03:00
seve12 81c9e96bf3 Improves accessibility by disabling custom Tab handling
Comments out custom Tab key behavior to allow default browser focus movement, enhancing accessibility for keyboard users and assistive technologies.
2025-08-04 17:45:53 +03:00
Lauri Ojansivu 20f91ef893 Updated ChangeLog. 2025-08-01 02:29:49 +03:00
Lauri Ojansivu 1187254573 Updated security email address.
Thanks to xet7 !
2025-08-01 02:28:15 +03:00
Lauri Ojansivu f22fb4f4a9 Updated translations 2025-07-28 23:28:36 +03:00
Lauri Ojansivu a14762e005 Updated ChangeLog. 2025-07-19 20:16:31 +03:00
Lauri Ojansivu 9a91214043 Update CHANGELOG.md 2025-07-19 05:14:56 +03:00
Lauri Ojansivu 30795a46cf Update CHANGELOG.md 2025-07-19 05:10:55 +03:00
Lauri Ojansivu b0865c8d06 Update CHANGELOG.md 2025-07-19 05:03:37 +03:00
Lauri Ojansivu c2aabbc6db Update CHANGELOG.md 2025-07-19 05:02:01 +03:00
Lauri Ojansivu 4aad3dafd4 Update CHANGELOG.md 2025-07-19 04:58:25 +03:00
Lauri Ojansivu 62269a9902 Update CHANGELOG.md 2025-07-19 04:54:59 +03:00
Lauri Ojansivu 4bc2fd4a7f Update CHANGELOG.md 2025-07-19 04:52:48 +03:00
Lauri Ojansivu 0e43a08689 Update CHANGELOG.md platforms info at top. Thanks to xet7! 2025-07-19 04:51:15 +03:00
Lauri Ojansivu 77b1416413 Updated ChangeLog. 2025-07-19 01:29:59 +03:00
Lauri Ojansivu 200545822c Fixes for building at Mac M1 Air.
Thanks to xet7 !
2025-07-18 22:31:17 +03:00
Lauri Ojansivu ac33f2164f Removed not needed files. 2025-07-18 19:04:25 +03:00
Lauri Ojansivu e82ca8a1f4 Updated ChangeLog. 2025-07-18 15:19:57 +03:00
Lauri Ojansivu f894f9ef6d Fixed building Docker image. Pushed new Docker image to Docker Hub, Quay and GitHub.
Thanks to xet7 !

Fixes #5835
2025-07-18 15:17:36 +03:00
Lauri Ojansivu ccfd8ef566 Updated ChangeLog. 2025-07-18 08:55:51 +03:00
Lauri Ojansivu 6c6b66c802 Updated release website script.
Thanks to xet7 !
2025-07-18 08:53:41 +03:00
Lauri Ojansivu 2cb2e7cb10 v7.93 2025-07-18 08:30:28 +03:00
Lauri Ojansivu 8744f47a0e Updated ChangeLog. 2025-07-17 01:25:27 +03:00
Lauri Ojansivu b742b25f96 Merge pull request #5832 from Atry/edit_list
Add REST API endpoint to edit a list with various properties
2025-07-17 01:21:06 +03:00
Yang, Bo 6d7c20f397 Add API endpoint to edit a list with various properties 2025-07-16 22:09:58 +00:00
Lauri Ojansivu f3d384c1dd Updated ChangeLog. 2025-07-17 00:52:34 +03:00
Lauri Ojansivu 69ce79a7b9 Fixed Snap local build script.
Thanks to xet7 !
2025-07-17 00:50:18 +03:00
Lauri Ojansivu 1cd191f76b Updated ChangeLog. 2025-07-16 01:10:59 +03:00
Lauri Ojansivu afc3c29341 Merge pull request #5829 from Atry/get_card_by_id
Avoid calling `ReactiveCache.getCard` twice
2025-07-16 01:08:27 +03:00
Lauri Ojansivu fedb3040d1 Updated ChangeLog. 2025-07-16 00:59:16 +03:00
Yang, Bo 0a969c59d3 Avoid calling ReactiveCache.getCard twice 2025-07-15 14:58:21 -07:00
Lauri Ojansivu d9fb9f49fd Merge pull request #5828 from Atry/get-card-by-id
Add a REST API endpoint to retrieve a card by ID
2025-07-16 00:53:42 +03:00
Yang, Bo fc77d0d201 Add REST API endpoint to retrieve a card by ID 2025-07-15 21:40:43 +00:00
Lauri Ojansivu 56700d1d06 Updated ChangeLog. 2025-07-10 05:22:38 +03:00
Lauri Ojansivu 84259c5116 Merge pull request #5826 from Atry/rest-api-custom-field-return-type
fix: correct return type in API documentation for custom fields
2025-07-09 19:14:13 +03:00
Yang, Bo 6cc746df8b fix: correct return type in API documentation for custom fields 2025-07-09 15:43:20 +00:00
Lauri Ojansivu b3ad06692f Updated ChangeLog. 2025-07-08 14:18:54 +03:00
Lauri Ojansivu bb0814bb11 Update Python.md 2025-07-08 14:16:49 +03:00
Lauri Ojansivu 722faf8aaa Updated ChangeLog. 2025-07-07 23:06:17 +03:00
Lauri Ojansivu 159324858b Fixed release script of building Snap locally at Ubuntu.
Thanks to xet7 !
2025-07-07 23:03:36 +03:00
Lauri Ojansivu f73a370719 Updated ChangeLog. 2025-07-07 22:42:12 +03:00
Lauri Ojansivu dfc658b910 Added release script to switch between using kvm, snapcraft.io/multipass, waydroid and virtualbox.
Thanks to xet7 !
2025-07-07 22:41:15 +03:00
Lauri Ojansivu 0a52f470b7 Updated ChangeLog. 2025-07-07 22:19:44 +03:00
Lauri Ojansivu e4822d8bc4 Updated issue template about pull requests for fixes to docs.
Thanks to xet7 !
2025-07-07 22:17:57 +03:00
Lauri Ojansivu 9d1cab3ac2 Updated ChangeLog. 2025-07-07 22:15:18 +03:00
Lauri Ojansivu 6d16ec238a Updated image links at Azure docs 2025-07-07 20:29:48 +03:00
Lauri Ojansivu e0284f225b Updated Keycloak link 2025-07-07 20:25:59 +03:00
Lauri Ojansivu a5acd0801a Updated Azure link 2025-07-07 20:24:34 +03:00
Lauri Ojansivu d59337ae47 Updated docs 2025-07-07 19:44:24 +03:00
Lauri Ojansivu 2f27a3f839 Updated docs about migrating manually. Part 2. 2025-07-07 19:27:54 +03:00
Lauri Ojansivu 450b33f98a Updated docs about migrating manually 2025-07-07 19:26:43 +03:00
Lauri Ojansivu 9adf5027fa Updated docs about importing from Asana 2025-07-07 19:21:27 +03:00
Lauri Ojansivu 1610b84845 Updated docs about importing from Trello. Part 3. 2025-07-07 19:18:29 +03:00
Lauri Ojansivu 40b2cf88fc Updated docs about importing from Trello. Part 2. 2025-07-07 19:17:41 +03:00
Lauri Ojansivu 55ef6c0c56 Updated docs about importing from Trello 2025-07-07 19:15:51 +03:00
Lauri Ojansivu a9c67ac200 Fix docs link about CSV. Part 2. 2025-07-07 19:09:57 +03:00
Lauri Ojansivu 3892be47ac Fix docs link about CSV 2025-07-07 19:07:48 +03:00
Lauri Ojansivu a2654b2e29 Removed not working link from docs 2025-07-07 19:05:49 +03:00
Lauri Ojansivu a052cc8fa5 Updated docs about Kubernetes 2025-07-07 19:04:05 +03:00
Lauri Ojansivu 5d09100cb6 Update info about hashing 2025-07-07 19:00:10 +03:00
Lauri Ojansivu 76769d1b85 Fixed not working link 2025-07-07 18:56:34 +03:00
Lauri Ojansivu 2cf57250e8 Fix link to image at docs 2025-07-07 18:54:56 +03:00
Lauri Ojansivu 5d0a0c931f Removed old link Test Edge from docs index. 2025-07-07 18:50:56 +03:00
Lauri Ojansivu fa1adfec76 Formatting 2025-07-07 18:43:26 +03:00
Lauri Ojansivu 9271b07383 Fix link to image about PWA app icon install.
Thanks to stevenroose and xet7 !

Fixes #5824
2025-07-07 18:40:52 +03:00
Lauri Ojansivu 4fe955650a Added most often used links 2025-07-07 18:36:39 +03:00
Lauri Ojansivu 6b401000b9 Updated Snap platforms setting. 2025-07-05 20:11:13 +03:00
Lauri Ojansivu aa681cde88 Updated building Snap 2025-07-05 16:59:33 +03:00
Lauri Ojansivu 0921c6ea53 Updated ChangeLog. 2025-07-05 16:09:33 +03:00
Lauri Ojansivu 2df73bedee Updated rebuild-wekan.sh install deps for macOS. Part 2. 2025-07-05 15:30:12 +03:00
Lauri Ojansivu 938fe49b2c Update rebuild-wekan.sh install deps for macOS 2025-07-05 15:27:11 +03:00
Lauri Ojansivu 7e2e649a8e Updated ChangeLog. 2025-07-05 14:16:02 +03:00
Lauri Ojansivu 6e11aa27f8 Reorganized docs to fix building WeKan 2025-07-04 04:08:41 +03:00
Lauri Ojansivu 57ee624398 Updated issue template. 2025-07-04 03:18:44 +03:00
Lauri Ojansivu 3cba95b60a Updated issue template. 2025-07-01 19:08:43 +03:00
Lauri Ojansivu bd796ce642 Updated links at readme 2025-06-28 14:22:01 +03:00
Lauri Ojansivu 3a8473e632 Fix image link 2025-06-28 14:10:41 +03:00
Lauri Ojansivu 89480b61ce wekan.github.io to wekan.fi, and blog.wekan.team to wekan.fi/blog 2025-06-28 14:08:57 +03:00
Lauri Ojansivu c5e5bb613e Moved images from wekan.github.io to docs 2025-06-28 11:50:55 +03:00
Lauri Ojansivu b52d1ca6c4 wekan.team to wekan.fi 2025-06-28 10:59:38 +03:00
Lauri Ojansivu 790bafbb09 wekan.team to wekan.fi 2025-06-27 21:37:17 +03:00
Lauri Ojansivu c256ce6968 Update Browser-compatibility-matrix.md about Servo 2025-06-26 20:29:48 +03:00
Lauri Ojansivu 85465e0dfb Updated ChangeLog. 2025-06-26 05:45:11 +03:00
Lauri Ojansivu b7409c1d0b Removed old broken snap files.
Thanks to xet7 !
2025-06-26 05:43:30 +03:00
Lauri Ojansivu 4060d33bbc Updated ChangeLog. 2025-06-26 05:42:34 +03:00
Lauri Ojansivu 6526d99123 Upgraded Snap Candidate to have base core24, MongoDB 7 and Caddy 2.
Thanks to xet7 !
2025-06-26 05:39:37 +03:00
Lauri Ojansivu 1b44c848ad Updated ChangeLog. 2025-06-26 03:47:57 +03:00
Lauri Ojansivu e6980be061 Updated dependencies.
Thanks to developers of dependencies !
2025-06-26 03:46:39 +03:00
Lauri Ojansivu 81c77650b4 Updated translations. 2025-06-26 03:08:38 +03:00
Lauri Ojansivu 791e37dd9c Updated ChangeLog. 2025-06-26 03:01:59 +03:00
Lauri Ojansivu f926448bbb Added docs about using MongoDB at unsupported CPUs with Qemu.
Thanks to xet7 !

Related #4321,
related #5814
2025-06-26 03:00:04 +03:00
Lauri Ojansivu 7128f067d0 Updated ChangeLog. 2025-06-26 02:48:12 +03:00
Lauri Ojansivu 59ab6c1cd8 Snap Candidate: If CPU does not support AVX, use Qemu that supports AVX, so that MongoDB 6 works. Part 3.
Thanks to xet7 !

Fixes #4321
2025-06-26 02:41:11 +03:00
Lauri Ojansivu 89105b6e72 Updated ChangeLog. 2025-06-26 01:20:41 +03:00
Lauri Ojansivu 51e43f1c25 Specify meteor version, otherwise the latest meteor version is not compatible with node14. Part 2.
Thanks to xet7 !
2025-06-26 01:19:06 +03:00
Lauri Ojansivu 9b24d644a4 Merge pull request #5815 from Atry/board-rest-api-doc
feat: enhance API documentation and add board-related endpoints
2025-06-26 01:09:42 +03:00
Lauri Ojansivu 2549e0e4c8 Merge pull request #5816 from dassio/main
specify meteor version, otherwise the lastes meteor version is not compatible with node14
2025-06-26 01:08:43 +03:00
xiangbin.li d974fa638c specify meteor version, otherwise the lastes version is not compatiable with node_14 2025-06-24 03:36:20 +00:00
Yang, Bo f399b5119f feat: enhance API documentation and add board-related endpoints
Previously, boards.js contains a `?.` operator, which is not supported by esprima, therefore boards.js is skipped.

This PR fixes the API generation for borads.js by removing `?.`.

See https://github.com/jquery/esprima/issues/2112
2025-06-23 20:01:38 +00:00
Lauri Ojansivu 12d3fabdb7 Updates 2025-06-18 17:12:53 +03:00
Lauri Ojansivu d5727f5b15 Updated github issue template 2025-06-18 17:08:49 +03:00
Lauri Ojansivu 1908d04fd4 Updates 2025-06-18 17:04:59 +03:00
Lauri Ojansivu c7f8c828cb Updates 2025-06-18 17:01:38 +03:00
Lauri Ojansivu 054d0913fd Updates 2025-06-18 16:56:37 +03:00
Lauri Ojansivu ca7dc69c85 Fix links and add more info 2025-06-18 16:53:29 +03:00
Lauri Ojansivu b2ff51d99c Updates 2025-06-18 16:48:33 +03:00
Lauri Ojansivu abd4b6bd87 Updates 2025-06-18 16:45:04 +03:00
Lauri Ojansivu b92d07c9a6 Updated translations 2025-06-18 11:30:37 +03:00
Lauri Ojansivu c6204417a3 Updated translations 2025-06-18 11:27:23 +03:00
Lauri Ojansivu 3a23401443 Updated ChangeLog. 2025-06-18 11:07:15 +03:00
Lauri Ojansivu 12e6e46924 Update Browser-compatibility-matrix.md 2025-06-17 00:19:33 +03:00
Lauri Ojansivu be1b959519 Update Browser-compatibility-matrix.md 2025-06-17 00:18:04 +03:00
Lauri Ojansivu 7841c9e801 Update Browser-compatibility-matrix.md 2025-06-17 00:15:23 +03:00
Lauri Ojansivu bc486e2a7d Updated ChangeLog. 2025-06-16 14:58:15 +03:00
Lauri Ojansivu d01885e2ad Updated ChangeLog. 2025-06-16 14:47:50 +03:00
Lauri Ojansivu 358ffe0601 Merge pull request #5805 from walster001/main
CleanDark Theme Fixes
2025-06-16 14:45:19 +03:00
walster001 8d0bf1b758 Fix invisible scrollbar on CleanDark cards
Found that scrollbars were blending in with the card background largely due to transparency on the main board.
2025-06-16 00:39:10 +09:30
walster001 c7961cf2f4 Fix spacing 2025-06-16 00:22:20 +09:30
walster001 2ac374e578 Fix font colour contrast CleanDark
Fixes the visibility of card titles when card is opened for CleanDark theme as was inheriting black title from CleanLight theme. 
Title now is white to match and heavily contrast theme.
2025-06-16 00:18:50 +09:30
Lauri Ojansivu ad3306e19e Update Browser-compatibility-matrix.md 2025-06-14 22:37:10 +03:00
Lauri Ojansivu f54cbac370 Updated docs 2025-06-13 23:05:01 +03:00
Lauri Ojansivu 4bfc0140be Updated docs links 2025-06-13 22:36:59 +03:00
Lauri Ojansivu cc7459b983 Updated docs: Fixed links 2025-06-13 22:15:36 +03:00
Lauri Ojansivu 11415cd517 Updated Docs: Updated deep dive link 2025-06-13 21:45:38 +03:00
Lauri Ojansivu 9aa028f32d Updates 2025-06-13 21:39:46 +03:00
Lauri Ojansivu 2a415cbd26 Updated docs: Moved content from Home.md to README.md 2025-06-13 21:38:12 +03:00
Lauri Ojansivu 40a52da2d3 Updated docs: Removed footer 2025-06-13 21:34:45 +03:00
Lauri Ojansivu 31e043c1d7 Updated docs 2025-06-13 21:32:36 +03:00
Lauri Ojansivu 985afafed0 Snap Candidate back to MongoDB 6.0.24 2025-06-12 21:22:16 +03:00
Lauri Ojansivu 3a4d20ecb2 Updates 2025-06-12 20:28:52 +03:00
Lauri Ojansivu 35b524f179 Updated ChangeLog. 2025-06-12 20:15:19 +03:00
Lauri Ojansivu d2f17ef140 Upgrade to MongoDB 7.0.21 2025-06-12 20:13:49 +03:00
Lauri Ojansivu d99864ca95 v7.92 2025-06-12 19:30:59 +03:00
Lauri Ojansivu e6e1191f8a Updated ChangeLog. 2025-06-12 15:50:06 +03:00
Lauri Ojansivu 1f10c20874 Updated dependencies.
Thanks to developers of dependencies !
2025-06-12 15:48:55 +03:00
Lauri Ojansivu c699f7a940 Updated ChangeLog. 2025-06-12 15:47:50 +03:00
Lauri Ojansivu 7115c292c7 Updated dependencies.
Thanks to developers of dependencies !
2025-06-12 15:46:44 +03:00
Lauri Ojansivu 7744b14b48 Updated ChangeLog. 2025-06-12 15:44:50 +03:00
Lauri Ojansivu 6fed9e73d8 Merge pull request #5801 from Atry/fix-login-openapi
fix: properly document `/users/login`
2025-06-12 15:43:09 +03:00
Yang, Bo e14a3f9c2d fix: properly document /users/login 2025-06-12 02:18:19 +00:00
Lauri Ojansivu 7bf75b1ff7 Updated ChangeLog. 2025-06-11 19:54:05 +03:00
Lauri Ojansivu 6905e24199 Updated to MongoDB 6.0.24 at Snap Candidate.
Thanks to MongoDB developers!
2025-06-11 19:52:13 +03:00
Lauri Ojansivu 9eb25c09da Updated ChangeLog. 2025-06-06 03:58:51 +03:00
Lauri Ojansivu c97f5ffca3 Updated ChangeLog. 2025-06-03 01:11:26 +03:00
Lauri Ojansivu eb19168b5f Merge pull request #5795 from wekan/dependabot/github_actions/docker/build-push-action-6.18.0
Bump docker/build-push-action from 6.17.0 to 6.18.0
2025-06-03 01:09:31 +03:00
dependabot[bot] e421b68766 Bump docker/build-push-action from 6.17.0 to 6.18.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.17.0 to 6.18.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/1dc73863535b631f98b2378be8619f83b136f4a0...263435318d21b8e681c14492fe198d362a7d2c83)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-02 20:16:16 +00:00
Lauri Ojansivu 6b86625c56 Updated ChangeLog. 2025-06-02 19:15:46 +03:00
Lauri Ojansivu 254b6dd5c7 Merge pull request #5793 from walster001/main
Allow selection of card text via webkit/user-select attributes
2025-06-02 19:13:18 +03:00
walster001 7b545d12c7 Allow selection of card text via webkit/user-select attributes
Fixes open issue around webkit/user-select attributes. Modifies values to allow "text" values to be selected in cards and on the board.
2025-06-02 22:03:16 +09:30
Lauri Ojansivu 01ed20b400 v7.91 2025-05-25 01:05:10 +03:00
Lauri Ojansivu fad930833a Updated translations. 2025-05-25 00:31:15 +03:00
Lauri Ojansivu 9192fbee44 Updated ChangeLog. 2025-05-25 00:30:11 +03:00
Lauri Ojansivu aaa5f9885d Reverted https://github.com/wekan/wekan/pull/5774 about due date changes.
Thanks to xet7 !

Fixes #5782
2025-05-25 00:22:47 +03:00
Lauri Ojansivu 1979b1692d Reverted date format changes.
Thanks to xet7 !
2025-05-25 00:11:09 +03:00
valhalla-creator fc31eeca88 Update cardDate.js 2025-05-22 21:20:20 +01:00
valhalla-creator 6d4de76a9a Update datepicker.js 2025-05-22 21:19:39 +01:00
valhalla-creator 9245ba4a5b Update utils.js 2025-05-22 21:18:52 +01:00
valhalla-creator 973a788c21 Update datepicker.js 2025-05-22 21:13:22 +01:00
valhalla-creator 0d5df8d3cf Update cardDate.js 2025-05-22 21:12:44 +01:00
valhalla-creator b67a236657 Update utils.js 2025-05-22 21:11:28 +01:00
Lauri Ojansivu 170617d457 Merge pull request #5780 from wekan/dependabot/github_actions/docker/build-push-action-6.17.0
Bump docker/build-push-action from 6.16.0 to 6.17.0
2025-05-19 23:12:48 +03:00
dependabot[bot] cc2f359b6c Bump docker/build-push-action from 6.16.0 to 6.17.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.16.0 to 6.17.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/14487ce63c7a62a4a324b0bfb37086795e31c6c1...1dc73863535b631f98b2378be8619f83b136f4a0)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 20:08:52 +00:00
Lauri Ojansivu c0d44a8686 v7.90 2025-05-14 03:05:46 +03:00
Lauri Ojansivu a1700f38b1 Updated ChangeLog. 2025-05-14 01:14:08 +03:00
Lauri Ojansivu b82ba63532 Fix Lines in multiline markdown code block to not anymore have darker background.
Thanks to mueller-ma and xet7 !

Fixes #5689
2025-05-14 01:11:54 +03:00
Lauri Ojansivu dbd1324a90 Updated ChangeLog. 2025-05-14 00:15:37 +03:00
Lauri Ojansivu e52158b729 Changed start.bat default ROOT_URL=http://localhost , although it only works for local user.
Thanks to xet7 !
2025-05-14 00:13:52 +03:00
Lauri Ojansivu 68a717cf47 Updated ChangeLog. 2025-05-13 23:48:45 +03:00
Lauri Ojansivu c0a9780f80 Added missing quotes to Fix Due Date Problem in Non-English Numbers.
Thanks to xet7 !

Fixes https://github.com/wekan/wekan/pull/5774,
fixes #5752
2025-05-13 23:43:08 +03:00
Lauri Ojansivu 0520129a40 Updated ChangeLog. 2025-05-13 23:36:32 +03:00
Lauri Ojansivu 6b36e126ab Merge pull request #5774 from valhalla-creator/bugfix/fix-due-date
Bugfix/fix due date
2025-05-13 23:31:33 +03:00
valhalla-creator 3cb4662363 Update datepicker.js 2025-05-13 21:26:34 +01:00
valhalla-creator cef14f301f Update utils.js 2025-05-13 21:21:48 +01:00
valhalla-creator eca4a0c440 Update cardDate.js 2025-05-13 21:19:59 +01:00
Lauri Ojansivu cea04b2ada Updated ChangeLog. 2025-05-13 23:18:13 +03:00
Lauri Ojansivu b7d9af9ae7 v7.89 2025-05-13 22:45:44 +03:00
Lauri Ojansivu 0046b3c802 Merge pull request #5772 from oussama-madimagh/fix/css-compatibility
Fix: Add vendor prefixes for user-select and text-size-adjust for better browser compatibility
2025-05-13 22:37:32 +03:00
oussama-madimagh 25384c8ac3 Fix: Add vendor prefixes for user-select and text-size-adjust for better browser compatibility 2025-05-13 20:33:29 +01:00
Lauri Ojansivu 2eee72da8a Updated ChangeLog. 2025-05-13 22:00:50 +03:00
Lauri Ojansivu d65c422e3f Merge pull request #5769 from Adamsss001/feature/email-i18n
Add email notifications language localization feature
2025-05-13 21:50:53 +03:00
Omar Abid 2ab9bd3172 Add email notifications language localization feature 2025-05-13 19:45:08 +01:00
Lauri Ojansivu a0b5c2e88c Updated ChangeLog. 2025-05-13 19:42:41 +03:00
Lauri Ojansivu 0bd4108661 Upgraded to MongoDB 6.0.23 at Snap Candidate.
Thanks to MongoDB developers !
2025-05-13 19:37:42 +03:00
Lauri Ojansivu 7d1a1475ba Add missing code of fix insertion order of list.
Thanks to xet7 !

Fixes https://github.com/wekan/wekan/pull/5767,
fixes #5732
2025-05-13 18:54:14 +03:00
Lauri Ojansivu 6418263165 Merge branch 'correct-list-position' of github.com:valhalla-creator/wekan 2025-05-13 18:30:59 +03:00
Lauri Ojansivu b32c835cf9 Updated license 2025-05-13 17:00:54 +03:00
valhalla-creator a927685bc6 Update swimlanes.js 2025-05-12 22:33:42 +01:00
Lauri Ojansivu 6827d40e84 Updated ChangeLog. 2025-05-12 22:26:33 +03:00
Lauri Ojansivu 9aa12b0eb6 Updated Caddy docs.
Thanks to xet7 !
2025-05-12 22:25:18 +03:00
Lauri Ojansivu 8ca1a36d78 Updated ChangeLog. 2025-05-12 21:57:43 +03:00
Lauri Ojansivu 394f2eae69 Updated Browser Compatibility Matrix.
Thanks to xet7 !
2025-05-12 21:56:11 +03:00
Lauri Ojansivu 7588459c3e Updated translations. 2025-05-12 21:43:02 +03:00
Lauri Ojansivu 2c33f45a6a Updated translations. 2025-04-29 05:47:20 +03:00
Lauri Ojansivu 43cf0b66ac Merge pull request #5754 from wekan/dependabot/github_actions/docker/build-push-action-6.16.0
Bump docker/build-push-action from 6.15.0 to 6.16.0
2025-04-29 04:59:27 +03:00
dependabot[bot] c05f6fcff2 Bump docker/build-push-action from 6.15.0 to 6.16.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.15.0 to 6.16.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/471d1dc4e07e5cdedd4c2171150001c434f0b7a4...14487ce63c7a62a4a324b0bfb37086795e31c6c1)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 21:07:25 +00:00
Lauri Ojansivu a4eb32158b Updated ChangeLog. 2025-04-25 23:33:40 +03:00
Lauri Ojansivu 072ced9d0e Added script to build snap locally and push to snapcraft.io candidate and edge.
Thanks to xet7 !
2025-04-25 23:30:57 +03:00
Lauri Ojansivu c5fefc1414 v7.88 2025-04-25 22:12:37 +03:00
Lauri Ojansivu c825895ceb Reverted translation fix that sometimes did not work.
Thanks to xet7 !

Fixes #5751,
related https://github.com/wekan/wekan/pull/5748
2025-04-25 22:06:06 +03:00
Lauri Ojansivu 9488972ed8 Merge newest changes. 2025-04-25 21:07:22 +03:00
Lauri Ojansivu 1f4bed38f7 Merge pull request #5750 from walster001/main
Fix more contrasting issues
2025-04-25 21:02:50 +03:00
Lauri Ojansivu 747112957a v7.87 2025-04-25 20:59:20 +03:00
Lauri Ojansivu 18228096f9 Updated ChangeLog. 2025-04-25 20:56:07 +03:00
Lauri Ojansivu d0ea5bf500 Fix typos.
Thanks to xet7 !
2025-04-25 20:54:02 +03:00
walster001 74fe91fa3a Fix more contrasting issues
- Fix contrast issue with CleanDark & CleanLight buttons on theme selection menu.
2025-04-26 01:40:15 +09:30
Lauri Ojansivu d4e3075fcc v7.86 2025-04-25 19:00:08 +03:00
Lauri Ojansivu 413ae5f20e Updated translations. 2025-04-25 18:38:13 +03:00
Lauri Ojansivu e23f86f542 Updated ChangeLog. 2025-04-25 18:35:12 +03:00
Lauri Ojansivu b3c47dbe84 Merge pull request #5749 from walster001/main
Fix contrast issue checkbox
2025-04-25 18:32:28 +03:00
Lauri Ojansivu b10c2b9a15 Updated ChangeLog. 2025-04-25 18:31:35 +03:00
Lauri Ojansivu bb6910acd1 Merge branch 'nourguidara-fix-i18n-init-timing' 2025-04-25 18:29:43 +03:00
Lauri Ojansivu 76b000820e Updated ChangeLog. 2025-04-25 18:28:23 +03:00
Lauri Ojansivu 50b874629c Merge branch 'Rayene123-add-toggle-watch-icon-on-card' 2025-04-25 18:25:44 +03:00
Lauri Ojansivu 4d145ab4ad Added translations to questions about are you sure.
Thanks to xet7 !

Related https://github.com/wekan/wekan/pull/5745
2025-04-25 18:24:40 +03:00
Lauri Ojansivu 4d67a4641f Merge branch 'fix-i18n-init-timing' of github.com:nourguidara/wekan into nourguidara-fix-i18n-init-timing 2025-04-25 17:54:41 +03:00
Lauri Ojansivu bc2eab6f9d Merge branch 'add-toggle-watch-icon-on-card' of github.com:Rayene123/wekan into Rayene123-add-toggle-watch-icon-on-card 2025-04-25 17:49:14 +03:00
walster001 3ccce75863 Fix contrast issue checkbox
- Fixed contrasting issue with tick check on custom fields, also fixed the ugly green tick coming up on the checklists in cards by utilisation of the !important tag to override it with the checkbox colour for custom fields also.
2025-04-25 20:15:34 +09:30
nour guidara b390b266e2 bug fix in imports\i18n\index.js 2025-04-25 11:10:46 +01:00
Lauri Ojansivu 561af8926c Merge branch 'main' of github.com:wekan/wekan 2025-04-24 22:20:06 +03:00
Lauri Ojansivu 5717dc2cf4 Updated ChangeLog. 2025-04-24 22:19:45 +03:00
Lauri Ojansivu d0e64ad6d2 Merge pull request #5746 from nourguidara/nourguidara-patch-1
Improve impersonate user documentation in docs/Admin/Impersonate-user.md
2025-04-24 22:18:07 +03:00
Lauri Ojansivu 8e1a735ec7 Updates 2025-04-24 22:17:47 +03:00
nour guidara 1301d67295 Update Impersonate-user.md
Restored direct link to the original pull request (#3280) as requested
2025-04-24 20:14:41 +01:00
nour guidara 7c239f5218 Update Impersonate-user.md 2025-04-24 19:45:29 +01:00
Rayene123 61235c953c added a watch icon button when clicked toggle if a card is watched or not 2025-04-24 11:53:08 +01:00
Lauri Ojansivu ea65a0308d Merge pull request #5741 from Firas-Git/documentation/login-and-signup
Documentation/login and signup
2025-04-21 22:57:08 +03:00
Firas Saidi f840b07c02 documentation/login-and-signup 2025-04-21 20:50:23 +01:00
Lauri Ojansivu 8af719d39e v7.85 2025-04-21 16:30:58 +03:00
Lauri Ojansivu c1a4250bd2 Updated to MongoDB 6.0.22.
Thanks to MongoDB developers !
2025-04-21 16:28:41 +03:00
Lauri Ojansivu b4b442f8a8 Updated translations. 2025-04-21 16:13:56 +03:00
Lauri Ojansivu b7e76fcfa1 Updated ChangeLog. 2025-04-21 16:10:24 +03:00
Lauri Ojansivu 01950cc796 Fix board sidebar menu doesn't open in mobile.
Thanks to mimZD and xet7 !

Fixes #5736
2025-04-21 16:07:43 +03:00
Firas Saidi 14f2022e21 fix-5434 2025-04-10 11:16:38 +01:00
Lauri Ojansivu 23bac73559 Updated translations. 2025-04-05 17:39:29 +03:00
Lauri Ojansivu 2de9b94b01 Updated ChangeLog. 2025-03-31 21:50:47 +03:00
Lauri Ojansivu 05d1736f5f Update Browser-compatibility-matrix.md 2025-03-31 21:45:22 +03:00
Lauri Ojansivu db5346fc5c Update Browser-compatibility-matrix.md 2025-03-31 21:38:06 +03:00
Lauri Ojansivu f09f5bd737 Updated translations. 2025-03-29 21:35:45 +02:00
Lauri Ojansivu d96a1a5c9e v7.84 2025-03-23 17:33:57 +02:00
Lauri Ojansivu ad3cc9c087 Updated translations. 2025-03-22 21:39:15 +02:00
Lauri Ojansivu d0c7bf65a4 Updated ChangeLog. 2025-03-22 21:30:53 +02:00
Lauri Ojansivu bb6ac70f63 Updated dependencies.
Thanks to developers of dependencies !
2025-03-22 21:26:41 +02:00
Lauri Ojansivu c38b9da7d6 Merge pull request #5718 from wekan/dependabot/github_actions/docker/login-action-3.4.0
Bump docker/login-action from 3.3.0 to 3.4.0
2025-03-18 01:37:59 +02:00
dependabot[bot] 19153ca489 Bump docker/login-action from 3.3.0 to 3.4.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/9780b0c442fbb1117ed29e0efdff1e18412f7567...74a5d142397b4f367a81961eba4e8cd7edddf772)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-17 21:00:44 +00:00
Lauri Ojansivu 8e7a5e8cb5 Updated translations. 2025-03-15 22:31:43 +02:00
Lauri Ojansivu 1407059937 Updated ChangeLog. 2025-03-15 19:33:49 +02:00
Lauri Ojansivu a2911bc9c3 Fixed building OpenAPI docs.
Thanks to xet7 !

Fixes #5512
2025-03-15 19:32:16 +02:00
Lauri Ojansivu f99b735746 Updated ChangeLog. 2025-03-11 04:23:55 +02:00
Lauri Ojansivu 4510ddda15 Fix typo at Shortcuts.
Thanks to xet7 !
2025-03-11 04:19:45 +02:00
Lauri Ojansivu 028ec46f46 Updated ChangeLog. 2025-03-09 20:05:08 +02:00
Lauri Ojansivu c0e4e01deb Added developer docs about Login code.
Thanks to xet7 !

Fixes #5714
2025-03-09 20:03:42 +02:00
Lauri Ojansivu cfcf682134 Updated ChangeLog. 2025-03-09 19:08:20 +02:00
Lauri Ojansivu 27bd9817d7 Merge pull request #5712 from Rayene123/Time-on-Minicard-for-Start/End/Due-Date
Time on minicard for start/end/due date
2025-03-09 19:03:54 +02:00
Firas Saidi dc389a68ab bug_fixing 2025-03-09 16:23:37 +01:00
Rayene123 6d982cdfd9 formatted the date when storing it 2025-03-09 14:15:17 +00:00
Rayene123 827ee615c1 added the start , due , end hour 2025-03-09 14:12:20 +00:00
Lauri Ojansivu f5f0ba721e v7.83 2025-03-08 21:32:37 +02:00
Lauri Ojansivu 1344f85986 Updated ChangeLog. 2025-03-08 21:14:12 +02:00
Lauri Ojansivu e7462ada12 Reverted Docker changes of WeKan v7.68 to get WeKan Docker version working.
Thanks to xet7 !

Fixes #5697
2025-03-08 21:09:09 +02:00
Lauri Ojansivu 11199b6225 Updated ChangeLog. 2025-03-08 19:58:05 +02:00
Lauri Ojansivu 345aece0f2 Updated ChangeLog. 2025-03-08 19:55:49 +02:00
Lauri Ojansivu 912c84422b Merge branch 'Firas-Git-CopyCard_FixError' 2025-03-08 19:52:42 +02:00
Lauri Ojansivu b402676079 Removed siteurl from manifest to fix browser console error about not matching URL.
Thanks to xet7 !
2025-03-08 19:51:23 +02:00
Lauri Ojansivu 908a5fc60d Comment out error message of non-existing Custom Field.
Thanks to xet7 !

Related #5684
2025-03-08 19:50:00 +02:00
Lauri Ojansivu 38e57d3635 Merge branch 'CopyCard_FixError' of github.com:Firas-Git/wekan into Firas-Git-CopyCard_FixError 2025-03-08 19:46:19 +02:00
Firas Saidi 14167b19b9 cards file 2025-03-08 18:02:03 +01:00
Lauri Ojansivu fc548b426d Updated translations. 2025-03-08 17:45:02 +02:00
Zegden Rayen 094f13934c added the confirm pop up before cloning or archiving a board 2025-03-08 15:38:22 +00:00
Lauri Ojansivu 71acd9603e Updated ChangeLog. 2025-03-06 01:52:46 +02:00
Lauri Ojansivu 341f655ab7 Merge pull request #5704 from wekan/dependabot/github_actions/docker/build-push-action-6.15.0
Bump docker/build-push-action from 6.14.0 to 6.15.0
2025-03-05 19:33:04 +02:00
Lauri Ojansivu 0c5323c106 Merge pull request #5703 from wekan/dependabot/github_actions/docker/metadata-action-5.7.0
Bump docker/metadata-action from 5.6.1 to 5.7.0
2025-03-05 19:30:27 +02:00
dependabot[bot] 7f871fdf30 Bump docker/build-push-action from 6.14.0 to 6.15.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.14.0 to 6.15.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/0adf9959216b96bec444f325f1e493d4aa344497...471d1dc4e07e5cdedd4c2171150001c434f0b7a4)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 20:41:23 +00:00
dependabot[bot] 6347b40a02 Bump docker/metadata-action from 5.6.1 to 5.7.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.6.1 to 5.7.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/369eb591f429131d6889c46b94e711f089e6ca96...902fa8ec7d6ecbf8d84d538b9b233a880e428804)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 20:41:20 +00:00
Lauri Ojansivu bce84a432a Updated ChangeLog. 2025-03-02 12:03:22 +02:00
Lauri Ojansivu b6fc4deb63 Merge pull request #5702 from adam-fu/main
Adding Development information to readme
2025-03-02 12:00:54 +02:00
adam-fu 6b48f9e259 Adding Development information to readme 2025-03-02 06:43:29 +01:00
Lauri Ojansivu 44b7666426 Merge branch 'main' of github.com:wekan/wekan 2025-02-25 14:33:34 +02:00
Lauri Ojansivu ef70ed76a2 Updated changelog 2025-02-25 14:33:06 +02:00
Lauri Ojansivu a1a1b3d1ee Merge pull request #5696 from wekan/dependabot/github_actions/docker/build-push-action-6.14.0
Bump docker/build-push-action from 6.13.0 to 6.14.0
2025-02-24 23:21:55 +02:00
dependabot[bot] 0326757399 Bump docker/build-push-action from 6.13.0 to 6.14.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.13.0 to 6.14.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/ca877d9245402d1537745e0e356eab47c3520991...0adf9959216b96bec444f325f1e493d4aa344497)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-24 21:18:37 +00:00
Lauri Ojansivu edbc8ed92b v7.82 2025-02-24 20:21:33 +02:00
Lauri Ojansivu 07e9ec0617 Updated ChangeLog. 2025-02-24 15:12:07 +02:00
Lauri Ojansivu 18d0fa4327 Fixed building WeKan. Updated dompurify. Forked Meteor 2.14 version of meteor-node-stubs to update elliptic.
Thanks to delopers of depedencies and xet7 !

Fixes #5694
2025-02-24 14:56:54 +02:00
Lauri Ojansivu 666ee84033 Updated dependencies.
Thanks to developes of dependencies "
2025-02-23 15:55:20 +02:00
Lauri Ojansivu 120642f47d Updated ChangeLog. 2025-02-21 21:22:14 +02:00
Lauri Ojansivu 148b81262d Updated requirements at docs.
Thanks to mueller-ma !

Fixes #5692
2025-02-21 21:12:28 +02:00
Lauri Ojansivu c41467f76e Merge pull request #5691 from wekan/dependabot/npm_and_yarn/dompurify-3.2.4
Bump dompurify from 2.5.6 to 3.2.4
2025-02-15 15:47:49 +02:00
dependabot[bot] c83e83b8b1 Bump dompurify from 2.5.6 to 3.2.4
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 2.5.6 to 3.2.4.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/2.5.6...3.2.4)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-15 08:58:49 +00:00
Lauri Ojansivu 563a508e26 Added missing ) character.
Thanks to xet7 !
2025-02-11 22:12:57 +02:00
Lauri Ojansivu 1d8347cc23 Merge pull request #5682 from salleman33/devel
Update metrics.js
2025-02-11 17:28:33 +02:00
salleman 874abf2c41 Update metrics.js
Add possibility to use a token in place of ipaddress to access metrics route
2025-02-11 12:06:23 +01:00
Lauri Ojansivu 3e18f820ea v7.81 2025-02-07 16:13:52 +02:00
Lauri Ojansivu b571f1c953 Upgraded to MongoDB 6.0.20 at Snap Candidate.
Thanks to MongoDB developers!
2025-02-07 16:11:48 +02:00
Lauri Ojansivu fd69c7ceb8 Updated ChangeLog. 2025-02-05 04:41:42 +02:00
Lauri Ojansivu d15faa1890 Updated ChangeLog. 2025-01-29 14:15:31 +02:00
Lauri Ojansivu 0c7e12c5e7 Added Meteor 3.1 learning course to docs.
Thanks to producer of learning course !
2025-01-29 14:13:21 +02:00
Lauri Ojansivu 36a3077853 Fix misspelling of hours at env variable setting LDAP_BACKGROUND_SYNC_INTERVAL.
Thanks to hubermam !

Fixes #5665
2025-01-29 14:09:31 +02:00
Lauri Ojansivu 51bc23dbd9 Updated ChangeLog. 2025-01-29 13:40:34 +02:00
Lauri Ojansivu 0b1e0bd395 Fixed env variable METRICS_ACCEPTED_IP_ADDRESS to be same as at docs.
Thanks to salleman33 !

Fixes #5671
2025-01-29 13:38:40 +02:00
Lauri Ojansivu 151aafd114 Updated ChangeLog. 2025-01-29 10:23:12 +02:00
Lauri Ojansivu 16c8a65a1c Updated ChangeLog. 2025-01-29 10:22:08 +02:00
Lauri Ojansivu f3133e9cd8 Merge pull request #5670 from wekan/dependabot/github_actions/docker/build-push-action-6.13.0
Bump docker/build-push-action from 6.12.0 to 6.13.0
2025-01-29 10:14:55 +02:00
dependabot[bot] de84aa7674 Bump docker/build-push-action from 6.12.0 to 6.13.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.12.0 to 6.13.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/67a2d409c0a876cbe6b11854e3e25193efe4e62d...ca877d9245402d1537745e0e356eab47c3520991)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-27 20:17:17 +00:00
Lauri Ojansivu 1bdbfe86bb Merge pull request #5663 from wekan/dependabot/github_actions/helm/chart-releaser-action-1.7.0
Bump helm/chart-releaser-action from 1.6.0 to 1.7.0
2025-01-21 22:44:23 +02:00
Lauri Ojansivu 397b9f439e Merge pull request #5662 from wekan/dependabot/github_actions/docker/build-push-action-6.12.0
Bump docker/build-push-action from 6.11.0 to 6.12.0
2025-01-21 22:44:12 +02:00
dependabot[bot] 261e0aee0f Bump helm/chart-releaser-action from 1.6.0 to 1.7.0
Bumps [helm/chart-releaser-action](https://github.com/helm/chart-releaser-action) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/helm/chart-releaser-action/releases)
- [Commits](https://github.com/helm/chart-releaser-action/compare/v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: helm/chart-releaser-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 20:02:15 +00:00
dependabot[bot] a6d9bde658 Bump docker/build-push-action from 6.11.0 to 6.12.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.11.0 to 6.12.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/b32b51a8eda65d6793cd0494a773d4f6bcef32dc...67a2d409c0a876cbe6b11854e3e25193efe4e62d)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-20 20:02:13 +00:00
Lauri Ojansivu 8d0a07e1a8 Updated translations. 2025-01-19 23:06:23 +02:00
Lauri Ojansivu 659615e6f2 Merge pull request #5658 from wekan/dependabot/github_actions/docker/build-push-action-6.11.0
Bump docker/build-push-action from 6.10.0 to 6.11.0
2025-01-15 12:18:49 +02:00
dependabot[bot] 9f0b82c0d5 Bump docker/build-push-action from 6.10.0 to 6.11.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.10.0 to 6.11.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/48aba3b46d1b1fec4febb7c5d0c644b249a11355...b32b51a8eda65d6793cd0494a773d4f6bcef32dc)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-13 20:55:32 +00:00
Lauri Ojansivu 9a23dcc991 v7.80 2025-01-12 23:48:05 +02:00
Lauri Ojansivu 980d345305 Updated ChangeLog. 2025-01-12 23:19:51 +02:00
Lauri Ojansivu 41f76ee974 Updated translations. 2025-01-11 20:53:31 +02:00
Lauri Ojansivu 83a60e6303 Merge pull request #5655 from NadavTasher/bugfix/fix-assignment-of-removed-members
Fix assignee toggling keyboard shortcut to only toggle current board members
2025-01-03 17:32:58 +02:00
Nadav Tasher 7b23c85117 Fix assignee toggling keyboard shortcut to only toggle current board members 2025-01-03 17:15:40 +02:00
Lauri Ojansivu ff3900d100 Merge pull request #5654 from NadavTasher/bugfix/mouse-over-card-reactive-cache 2025-01-03 16:12:17 +02:00
Nadav Tasher e5e4b8ebfb Fix card issues with ReactiveCache when using keyboard shortcuts
When using ReactiveCache.getCard, a buggy instance of Card is returned.
The bug experienced is that .assignees and .members are not always up-to-date.

This can be reproduced by trying to hover over cards and triggering a keyboard
shortcut that interacts with a card.
2025-01-03 12:08:08 +02:00
Lauri Ojansivu 9516b75d65 Updated translations. 2025-01-02 19:39:08 +02:00
Lauri Ojansivu 6b1a92001a v7.79 2025-01-02 13:08:53 +02:00
Lauri Ojansivu e4e1fdb187 Updated ChangeLog. 2025-01-02 12:59:37 +02:00
Lauri Ojansivu 58ad80218a Updated translations. 2025-01-02 12:40:14 +02:00
Lauri Ojansivu 3322d3b33d Merge pull request #5652 from NadavTasher/feature/toggle-week-of-year-display
Feature - Add toggle for week-of-year in date displays (ISO 8601)
2025-01-02 12:07:23 +02:00
Lauri Ojansivu bd9d0c2d1b Updated translations. 2025-01-02 06:11:10 +02:00
Lauri Ojansivu 02b99e0555 Merge pull request #5653 from NadavTasher/feature/assign-members-by-numbers
Feature - Assign members using keyboard shortcut `Ctrl+Alt+[1-9]`
2025-01-02 06:01:32 +02:00
Nadav Tasher f803190dd2 Change shortcut help message 2025-01-01 22:54:51 +02:00
Nadav Tasher deb3a8389a Fix member index bug in keyboard shortcut 2025-01-01 22:26:59 +02:00
Nadav Tasher e7d02c12eb Added translation for new assigning keyboard shortcut 2025-01-01 22:23:21 +02:00
Nadav Tasher 169eaa180b Added support for assigning members to cards using Ctrl+Alt+Num 2025-01-01 22:22:57 +02:00
Nadav Tasher 08cde06ce5 Support show week of year toggle in cardCustomFields 2025-01-01 21:13:55 +02:00
Nadav Tasher 4607bfe454 Support week of year toggle in cardDate 2025-01-01 21:13:30 +02:00
Nadav Tasher de0eece27c Add show week of year translation 2025-01-01 21:13:03 +02:00
Nadav Tasher 25ad901fb3 Add show week of year toggle to sidebar 2025-01-01 21:12:38 +02:00
Nadav Tasher 99e579f47d Add week of year toggle state in user model 2025-01-01 21:12:04 +02:00
553 changed files with 34579 additions and 9162 deletions

No files matched your search

-257
View File
@@ -1,257 +0,0 @@
name: wekan
version: 0
version-script: git describe --tags | cut -c 2-
summary: The open-source kanban
description: |
Wekan is an open-source and collaborative kanban board application.
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.
Depending on target environment, some configuration settings might need to be adjusted.
For full list of configuration options call:
$ wekan.help
confinement: strict
grade: stable
architectures:
- amd64
plugs:
mongodb-plug:
interface: content
target: $SNAP_DATA/shared
hooks:
configure:
plugs:
- network
- network-bind
slots:
mongodb-slot:
interface: content
write:
- $SNAP_DATA/share
apps:
wekan:
command: wekan-control
daemon: simple
plugs: [network, network-bind]
mongodb:
command: mongodb-control
daemon: simple
plugs: [network, network-bind]
caddy:
command: caddy-control
daemon: simple
plugs: [network, network-bind]
help:
command: wekan-help
database-backup:
command: mongodb-backup
plugs: [network, network-bind]
database-list-backups:
command: ls -al $SNAP_COMMON/db-backups/
database-restore:
command: mongodb-restore
plugs: [network, network-bind]
parts:
mongodb:
source: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-4.2.6.tgz
plugin: dump
stage-packages: [libssl1.0.0, libcurl3]
filesets:
mongo:
- usr
- bin
- lib
stage:
- $mongo
prime:
- $mongo
wekan:
source: .
plugin: nodejs
node-engine: 14.21.3
node-packages:
- node-gyp
- node-pre-gyp
- fibers
build-packages:
- ca-certificates
- apt-utils
- python
- python3
- g++
- capnproto
- curl
- libcurl3
- execstack
- nodejs
- npm
stage-packages:
- libfontconfig1
override-build: |
echo "Cleaning environment first"
rm -rf ~/.meteor ~/.npm /usr/local/lib/node_modules
# Create the OpenAPI specification
rm -rf .build
## Use Meteor 1.8.x on Snap
#rm -rf .meteor
#mv .snap-meteor-1.8/.meteor .
#mv .snap-meteor-1.8/package.json .
#mv .snap-meteor-1.8/package-lock.json .
## Meteor 1.9.x has changes to Buffer() => Buffer.alloc(), so reverting those
#mv .snap-meteor-1.8/cfs_access-point.txt fix-download-unicode/
#mv .snap-meteor-1.8/export.js models/
#mv .snap-meteor-1.8/wekanCreator.js models/
#mv .snap-meteor-1.8/ldap.js packages/wekan-ldap/server/ldap.js
#mv .snap-meteor-1.8/oidc_server.js packages/wekan-oidc/oidc_server.js
rm -rf .snap-meteor-1.8
#mkdir -p .build/python
#cd .build/python
#git clone --depth 1 -b master https://github.com/Kronuz/esprima-python
#cd esprima-python
#python3 setup.py install
#cd ../../..
#mkdir -p ./public/api
#python3 ./openapi/generate_openapi.py --release $(git describe --tags --abbrev=0) > ./public/api/wekan.yml
# we temporary need api2html and mkdirp
#npm install -g api2html@0.3.0
#npm install -g mkdirp
#api2html -c ./public/logo-header.png -o ./public/api/wekan.html ./public/api/wekan.yml
#npm uninstall -g mkdirp
#npm uninstall -g api2html
# Node Fibers 100% CPU usage issue:
# https://github.com/wekan/wekan-mongodb/issues/2#issuecomment-381453161
# https://github.com/meteor/meteor/issues/9796#issuecomment-381676326
# https://github.com/sandstorm-io/sandstorm/blob/0f1fec013fe7208ed0fd97eb88b31b77e3c61f42/shell/server/00-startup.js#L99-L129
# Also see beginning of wekan/server/authentication.js
# import Fiber from "fibers";
# Fiber.poolSize = 1e9;
# OLD: Download node version 8.12.0 prerelease build => Official node 8.12.0 has been released
# Description at https://releases.wekan.team/node.txt
##echo "375bd8db50b9c692c0bbba6e96d4114cd29bee3770f901c1ff2249d1038f1348 node" >> node-SHASUMS256.txt.asc
##curl https://releases.wekan.team/node -o node
# Verify Fibers patched node authenticity
##echo "Fibers 100% CPU issue patched node authenticity:"
##grep node node-SHASUMS256.txt.asc | shasum -a 256 -c -
##rm -f node-SHASUMS256.txt.asc
##chmod +x node
##mv node `which node`
# DOES NOT WORK: paxctl fix.
# Removed from build-packages: - paxctl
#echo "Applying paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303"
#paxctl -mC `which node`
#echo "Installing npm"
#curl -L https://www.npmjs.com/install.sh | sh
echo "Installing meteor"
curl https://install.meteor.com/ -o install_meteor.sh
#sed -i "s|RELEASE=.*|RELEASE=\"1.8.1-beta.0\"|g" install_meteor.sh
chmod +x install_meteor.sh
sh install_meteor.sh
rm install_meteor.sh
# REPOS BELOW ARE INCLUDED TO WEKAN REPO
#if [ ! -d "packages" ]; then
# mkdir packages
#fi
#if [ ! -d "packages/kadira-flow-router" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router
# cd ..
#fi
#if [ ! -d "packages/meteor-useraccounts-core" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core
# sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' meteor-useraccounts-core/package.js
# cd ..
#fi
#if [ ! -d "packages/meteor-accounts-cas" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-cas.git meteor-accounts-cas
# cd ..
#fi
#if [ ! -d "packages/wekan-ldap" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/wekan-ldap.git
# cd ..
#fi
#if [ ! -d "packages/wekan-scrollbar" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/wekan-scrollbar.git
# cd ..
#fi
#if [ ! -d "packages/wekan_accounts-oidc" ]; then
# cd packages
# git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-oidc.git
# mv meteor-accounts-oidc/packages/switch_accounts-oidc wekan-accounts-oidc
# mv meteor-accounts-oidc/packages/switch_oidc wekan-oidc
# rm -rf meteor-accounts-oidc
# cd ..
#fi
#if [ ! -d "packages/markdown" ]; then
# cd packages
# git clone --depth 1 -b master --recurse-submodules https://github.com/wekan/markdown.git
# cd ..
#fi
rm -rf .build
meteor add standard-minifier-js --allow-superuser
meteor npm install --allow-superuser
meteor npm install --allow-superuser --save babel-runtime
meteor build .build --directory --allow-superuser
cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/packages/cfs_access-point.js
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac
#https://github.com/wekan/wekan/commit/7eeabf14be3c63fae2226e561ef8a0c1390c8d3c
#cd .build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt
#rm -rf node_modules/bcrypt
#meteor npm install --save bcrypt
# Change from npm-bcrypt directory back to .build/bundle/programs/server directory.
#cd ../../../../
# Change to directory .build/bundle/programs/server
cd .build/bundle/programs/server
npm install
npm install --allow-superuser --save babel-runtime
#meteor npm install --save bcrypt
# Change back to Wekan source directory
cd ../../../..
cp -r .build/bundle/* $SNAPCRAFT_PART_INSTALL/
cp .build/bundle/.node_version.txt $SNAPCRAFT_PART_INSTALL/
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/wekan
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-gyp/node_modules/tar/lib/.mkdir.js.swp
# Meteor 1.8.x additional .swp remove
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
organize:
README: README.wekan
prime:
- -lib/node_modules/node-pre-gyp/node_modules/tar/lib/.unpack.js.swp
helpers:
source: snap-src
plugin: dump
caddy:
plugin: dump
source: https://caddyserver.com/download/linux/amd64?license=personal&telemetry=off
source-type: tar
organize:
caddy: bin/caddy
CHANGES.txt: CADDY_CHANGES.txt
EULA.txt: CADDY_EULA.txt
LICENSES.txt: CADDY_LICENSES.txt
README.txt: CADDY_README.txt
stage:
- -init
-198
View File
@@ -1,198 +0,0 @@
#!/bin/bash
echo "Note: If you use other locale than en_US.UTF-8 , you need to additionally install en_US.UTF-8"
echo " with 'sudo dpkg-reconfigure locales' , so that MongoDB works correctly."
echo " You can still use any other locale as your main locale."
#Below script installs newest node 8.x for Debian/Ubuntu/Mint.
#NODE_VERSION=12.21.0
#X64NODE="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz"
function pause(){
read -p "$*"
}
function cprec(){
if [[ -d "$1" ]]; then
if [[ ! -d "$2" ]]; then
sudo mkdir -p "$2"
fi
for i in $(ls -A "$1"); do
cprec "$1/$i" "$2/$i"
done
else
sudo cp "$1" "$2"
fi
}
# sudo npm doesn't work right, so this is a workaround
function npm_call(){
TMPDIR="/tmp/tmp_npm_prefix"
if [[ -d "$TMPDIR" ]]; then
rm -rf $TMPDIR
fi
mkdir $TMPDIR
NPM_PREFIX="$(npm config get prefix)"
npm config set prefix $TMPDIR
npm "$@"
npm config set prefix "$NPM_PREFIX"
echo "Moving files to $NPM_PREFIX"
for i in $(ls -A $TMPDIR); do
cprec "$TMPDIR/$i" "$NPM_PREFIX/$i"
done
rm -rf $TMPDIR
}
#function wekan_repo_check(){
## UNCOMMENTING, IT'S NOT REQUIRED THAT /HOME/USERNAME IS /HOME/WEKAN
# git_remotes="$(git remote show 2>/dev/null)"
# res=""
# for i in $git_remotes; do
# res="$(git remote get-url $i | sed 's/.*wekan\/wekan.*/wekan\/wekan/')"
# if [[ "$res" == "wekan/wekan" ]]; then
# break
# fi
# done
#
# if [[ "$res" != "wekan/wekan" ]]; then
# echo "$PWD is not a wekan repository"
# exit;
# fi
#}
echo
PS3='Please enter your choice: '
options=("Install Wekan dependencies" "Build Wekan" "Run Meteor for dev on http://localhost:4000" "Run Meteor for dev on http://CURRENT-IP-ADDRESS:4000" "Run Meteor for dev on http://CUSTOM-IP-ADDRESS:PORT" "Quit")
select opt in "${options[@]}"
do
case $opt in
"Install Wekan dependencies")
if [[ "$OSTYPE" == "linux-gnu" ]]; then
echo "Linux";
# Debian, Ubuntu, Mint
sudo apt-get install -y build-essential gcc g++ make git curl wget
# npm nodejs
#sudo npm -g install npm
curl -0 -L https://npmjs.org/install.sh | sudo sh
sudo chown -R $(id -u):$(id -g) $HOME/.npm
sudo npm -g install n
sudo n 12.21.0
#curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
#sudo apt-get install -y nodejs
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo "macOS";
pause '1) Install XCode 2) Install Node 8.x from https://nodejs.org/en/ 3) Press [Enter] key to continue.'
elif [[ "$OSTYPE" == "cygwin" ]]; then
# POSIX compatibility layer and Linux environment emulation for Windows
echo "TODO: Add Cygwin";
exit;
elif [[ "$OSTYPE" == "msys" ]]; then
# Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
echo "TODO: Add msys on Windows";
exit;
elif [[ "$OSTYPE" == "win32" ]]; then
# I'm not sure this can happen.
echo "TODO: Add Windows";
exit;
elif [[ "$OSTYPE" == "freebsd"* ]]; then
echo "TODO: Add FreeBSD";
exit;
else
echo "Unknown"
echo ${OSTYPE}
exit;
fi
## Latest npm with Meteor 1.8.x
npm_call -g install npm
npm_call -g install node-gyp
# Latest fibers for Meteor 1.8.x
sudo mkdir -p /usr/local/lib/node_modules/fibers/.node-gyp
npm_call -g install fibers
# Install Meteor, if it's not yet installed
curl https://install.meteor.com | bash
sudo chown -R $(id -u):$(id -g) $HOME/.npm $HOME/.meteor
break
;;
"Build Wekan")
echo "Building Wekan."
#wekan_repo_check
# REPOS BELOW ARE INCLUDED TO WEKAN REPO
#rm -rf packages/kadira-flow-router packages/meteor-useraccounts-core packages/meteor-accounts-cas packages/wekan-ldap packages/wekan-ldap packages/wekan-scrfollbar packages/meteor-accounts-oidc packages/markdown
#mkdir packages
#cd packages
#git clone --depth 1 -b master https://github.com/wekan/flow-router.git kadira-flow-router
#git clone --depth 1 -b master https://github.com/meteor-useraccounts/core.git meteor-useraccounts-core
#git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-cas.git
#git clone --depth 1 -b master https://github.com/wekan/wekan-ldap.git
#git clone --depth 1 -b master https://github.com/wekan/wekan-scrollbar.git
#git clone --depth 1 -b master https://github.com/wekan/meteor-accounts-oidc.git
#git clone --depth 1 -b master --recurse-submodules https://github.com/wekan/markdown.git
#mv meteor-accounts-oidc/packages/switch_accounts-oidc wekan_accounts-oidc
#mv meteor-accounts-oidc/packages/switch_oidc wekan_oidc
#rm -rf meteor-accounts-oidc
#if [[ "$OSTYPE" == "darwin"* ]]; then
# echo "sed at macOS";
# sed -i '' 's/api\.versionsFrom/\/\/api.versionsFrom/' ~/repos/wekan/packages/meteor-useraccounts-core/package.js
#else
# echo "sed at ${OSTYPE}"
# sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' ~/repos/wekan/packages/meteor-useraccounts-core/package.js
#fi
#cd ..
sudo chown -R $(id -u):$(id -g) $HOME/.npm $HOME/.meteor
rm -rf node_modules .meteor/local
npm install
rm -rf .build
meteor build .build --directory
cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/packages/cfs_access-point.js
# Remove legacy webbroser bundle, so that Wekan works also at Android Firefox, iOS Safari, etc.
rm -rf .build/bundle/programs/web.browser.legacy
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac
#https://github.com/wekan/wekan/commit/7eeabf14be3c63fae2226e561ef8a0c1390c8d3c
#cd ~/repos/wekan/.build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt
#rm -rf node_modules/bcrypt
#meteor npm install bcrypt
cd .build/bundle/programs/server
rm -rf node_modules
npm install
#meteor npm install bcrypt
cd ../../../..
echo Done.
break
;;
"Run Meteor for dev on http://localhost:4000")
WITH_API=true RICHER_CARD_COMMENT_EDITOR=false ROOT_URL=http://localhost:4000 meteor run --exclude-archs web.browser.legacy,web.cordova --port 4000
break
;;
"Run Meteor for dev on http://CURRENT-IP-ADDRESS:4000")
IPADDRESS=$(ip a | grep 'noprefixroute' | grep 'inet ' | cut -d: -f2 | awk '{ print $2}' | cut -d '/' -f 1)
echo "Your IP address is $IPADDRESS"
WITH_API=true RICHER_CARD_COMMENT_EDITOR=false ROOT_URL=http://$IPADDRESS:4000 meteor run --exclude-archs web.browser.legacy,web.cordova --port 4000
break
;;
"Run Meteor for dev on http://CUSTOM-IP-ADDRESS:PORT")
ip address
echo "From above list, what is your IP address?"
read IPADDRESS
echo "On what port you would like to run Wekan?"
read PORT
echo "ROOT_URL=http://$IPADDRESS:$PORT"
WITH_API=true RICHER_CARD_COMMENT_EDITOR=false ROOT_URL=http://$IPADDRESS:$PORT meteor run --exclude-archs web.browser.legacy,web.cordova --port $PORT
break
;;
"Quit")
break
;;
*) echo invalid option;;
esac
done
-155
View File
@@ -1,155 +0,0 @@
name: wekan
version: git
summary: The open-source kanban
description: |
Wekan is an open-source and collaborative kanban board application.
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.
Depending on target environment, some configuration settings might need to be adjusted.
For full list of configuration options call:
$ wekan.help
confinement: strict
grade: stable
base: core18
architectures:
- amd64
plugs:
mongodb-plug:
interface: content
target: $SNAP_DATA/shared
hooks:
configure:
plugs:
- network
- network-bind
slots:
mongodb-slot:
interface: content
write:
- $SNAP_DATA/share
apps:
wekan:
command: wekan-control
daemon: simple
plugs: [network, network-bind]
mongodb:
command: mongodb-control
daemon: simple
plugs: [network, network-bind]
caddy:
command: caddy-control
daemon: simple
plugs: [network, network-bind]
help:
command: wekan-help
database-backup:
command: mongodb-backup
plugs: [network, network-bind]
database-list-backups:
command: ls -al $SNAP_COMMON/db-backups/
database-restore:
command: mongodb-restore
plugs: [network, network-bind]
parts:
mongodb:
source: https://repo.mongodb.org/apt/ubuntu/dists/xenial/mongodb-org/4.2/multiverse/binary-amd64/mongodb-org-server_4.2.2_amd64.deb
#https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.14.tgz
#https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.2.22.tgz
plugin: dump
stage-packages: [libssl1.0.0, libcurl3]
filesets:
mongo:
- usr
- bin
- lib
stage:
- $mongo
prime:
- $mongo
wekan:
source: .
plugin: nodejs
node-engine: 14.19.0
node-packages:
- node-gyp
- node-pre-gyp
- fibers
build-packages:
- ca-certificates
- apt-utils
- build-essential
- python
- python3
- g++
- capnproto
- curl
- libcurl3
- execstack
- nodejs
- npm
stage-packages:
- libfontconfig1
override-build: |
echo "Cleaning environment first"
rm -rf ~/.meteor ~/.npm /usr/local/lib/node_modules
rm -rf .build
echo "Installing meteor"
curl https://install.meteor.com/ -o install_meteor.sh
chmod +x install_meteor.sh
sh install_meteor.sh
rm install_meteor.sh
rm -rf .build
meteor add standard-minifier-js --allow-superuser
meteor npm install --allow-superuser
meteor npm install --allow-superuser --save babel-runtime
meteor build .build --directory --allow-superuser
cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/packages/cfs_access-point.js
cd .build/bundle/programs/server
npm install
npm install --allow-superuser --save babel-runtime
# Change back to Wekan source directory
cd ../../../..
cp -r .build/bundle/* $SNAPCRAFT_PART_INSTALL/
cp .build/bundle/.node_version.txt $SNAPCRAFT_PART_INSTALL/
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/wekan
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/npm/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/node-gyp/node_modules/tar/lib/.mkdir.js.swp
rm -f $SNAPCRAFT_PART_INSTALL/programs/server/node_modules/node-pre-gyp/node_modules/tar/lib/.mkdir.js.swp
organize:
README: README.wekan
prime:
- -lib/node_modules/node-pre-gyp/node_modules/tar/lib/.unpack.js.swp
helpers:
source: snap-src
plugin: dump
caddy:
plugin: dump
source: https://caddyserver.com/download/linux/amd64?license=personal&telemetry=off
source-type: tar
organize:
caddy: bin/caddy
CHANGES.txt: CADDY_CHANGES.txt
EULA.txt: CADDY_EULA.txt
LICENSES.txt: CADDY_LICENSES.txt
README.txt: CADDY_README.txt
stage:
- -init
-183
View File
@@ -1,183 +0,0 @@
name: wekan
version: '6.21'
base: core20
summary: Open Source kanban
description: |
WeKan ® is an Open Source and collaborative kanban board application.
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.
Depending on target environment, some configuration settings might need to be adjusted.
For full list of configuration options call:
$ wekan.help
confinement: strict
grade: stable
architectures:
- build-on: amd64
run-on: amd64
- build-on: arm64
run-on: arm64
- build-on: ppc64el
run-on: ppc64el
- build-on: s390x
run-on: s390x
plugs:
mongodb-plug:
interface: content
target: $SNAP_DATA/shared
hooks:
configure:
plugs:
- network
- network-bind
slots:
mongodb-slot:
interface: content
write:
- $SNAP_DATA/share
apps:
wekan:
command: wekan-control
daemon: simple
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
restart-condition: on-failure
mongodb:
command: mongodb-control
daemon: simple
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
restart-condition: on-failure
caddy:
command: caddy-control
daemon: simple
plugs: [network, network-bind]
help:
command: wekan-help
database-backup:
command: mongodb-backup
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
database-list-backups:
command: ls -al $SNAP_COMMON/db-backups/
database-restore:
command: mongodb-restore
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
parts:
mongodb:
plugin: dump
source:
- on amd64: https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/4.4/multiverse/binary-amd64/mongodb-org-server_4.4.13_amd64.deb
- on arm64: https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/4.4/multiverse/binary-arm64/mongodb-org-server_4.4.13_arm64.deb
- on ppc64el: https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/4.4/multiverse/binary-ppc64el/mongodb-org-server_4.4.13_ppc64el.deb
- on s390x: https://repo.mongodb.org/apt/ubuntu/dists/focal/mongodb-org/4.4/multiverse/binary-s390x/mongodb-org-server_4.4.13_s390x.deb
stage-packages:
- libssl1.1
- libcurl3-dev
- libcurl4-openssl-dev
filesets:
mongo:
- usr
- bin
- lib
stage:
- $mongo
prime:
- $mongo
wekan:
#plugin: npm
plugin: dump
source:
# Fixed URLs to some allowed GitHub releases URL.
# Non-GitHub build server file urls are not allowed at 2022-03-02 and later.
- on amd64: https://github.com/wekan/wekan/releases/download/v6.20/wekan-6.20-amd64.zip
- on arm64: https://github.com/wekan/wekan/releases/download/v6.20/wekan-6.20-arm64.zip
- on ppc64el: https://github.com/wekan/wekan/releases/download/v6.20/wekan-6.20-ppc64el.zip
- on s390x: https://github.com/wekan/wekan/releases/download/v6.20/wekan-6.20-s390x.zip
# npm-node-version: 14.19.1
# node-packages:
# - node-gyp
# - node-pre-gyp
# - fibers
# build-packages:
# - npm
# - build-essential
# - ca-certificates
# - apt-utils
# - python
# - python3
# - g++
# - capnproto
# - curl
# - execstack
# - nodejs
# - npm
# - p7zip-full
# stage-packages:
# - libfontconfig1
override-build: |
cp -r bundle/* $SNAPCRAFT_PART_INSTALL/
cp bundle/.node_version.txt $SNAPCRAFT_PART_INSTALL/
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/wekan
snapcraftctl build
organize:
README: README.wekan
prime:
- -lib/node_modules/node-pre-gyp/node_modules/tar/lib/.unpack.js.swp
- -lib/node_modules/weka*
helpers:
source: snap-src
plugin: dump
caddy:
plugin: dump
## Caddy v1 is not developed anymore. TODO: Sometime migrate to Caddy v2.
## https://caddy.community/t/caddyfile-v1-adapter/9129
## https://github.com/caddyserver/caddy/tree/v1
#source: https://caddyserver.com/download/linux/amd64?license=personal&telemetry=off
#source-type: tar
# Using last working binary that was downloaded from above URL to Wekan Snap,
# and .txt files from https://github.com/caddyserver/caddy/tree/v1/dist
source: https://wekan.github.io/caddy-v1-linux-amd64.7z
source-type: 7z
organize:
caddy: bin/caddy
CHANGES.txt: CADDY_CHANGES.txt
EULA.txt: CADDY_EULA.txt
LICENSES.txt: CADDY_LICENSES.txt
README.txt: CADDY_README.txt
stage:
- -init
caddy2:
plugin: dump
source:
# Fixed URLs to some allowed GitHub releases URL.
# Non-GitHub build server file urls are not allowed at 2022-03-02 and later.
- on amd64: https://github.com/wekan/wekan/releases/download/v6.20/caddy-v2-amd64.zip
- on arm64: https://github.com/wekan/wekan/releases/download/v6.20/caddy-v2-arm64.zip
- on ppc64el: https://github.com/wekan/wekan/releases/download/v6.20/caddy-v2-ppc64el.zip
- on s390x: https://github.com/wekan/wekan/releases/download/v6.20/caddy-v2-s390x.zip
source-type: zip
organize:
caddy: bin/caddy
CHANGES.txt: CADDY_CHANGES.txt
EULA.txt: CADDY_EULA.txt
LICENSES.txt: CADDY_LICENSES.txt
README.txt: CADDY_README.txt
stage:
- -init
+1 -1
View File
@@ -1,3 +1,3 @@
# These are supported funding model platforms
custom: ['https://wekan.team/commercial-support/']
custom: ['https://wekan.fi/commercial-support/']
+4 -3
View File
@@ -1,5 +1,9 @@
## Issue
UPGRADE: https://wekan.fi/upgrade/
Pull requests welcome to fix any broken links at docs directory, and organizing docs/Features and their screenshots to subdirectories of each feature.
Please report these issues elsewhere:
- SECURITY ISSUES, PGP EMAIL: https://github.com/wekan/wekan/blob/main/SECURITY.md
@@ -7,9 +11,6 @@ Please report these issues elsewhere:
If WeKan Snap is slow, try this: https://github.com/wekan/wekan/wiki/Cron
**[PLEASE UPGRADE](https://github.com/wekan/wekan/wiki/Backup)** to the newest
WeKan ® before reporting an issue, if possible.
Please search existing Open and Closed issues, most questions have already been answered.
If you can not login for any reason: https://github.com/wekan/wekan/wiki/Forgot-Password
+1 -1
View File
@@ -9,6 +9,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
+4 -4
View File
@@ -32,13 +32,13 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
@@ -48,14 +48,14 @@ jobs:
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
+1 -1
View File
@@ -15,6 +15,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Build the Docker image
run: docker build . --file Dockerfile --tag wekan:$(date +%s)
+2 -2
View File
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
@@ -25,6 +25,6 @@ jobs:
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.6.0
uses: helm/chart-releaser-action@v1.7.0
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+6 -6
View File
@@ -18,7 +18,7 @@ jobs:
# runs-on: ubuntu-latest
# steps:
# - name: checkout
# uses: actions/checkout@v4
# uses: actions/checkout@v5
#
# - name: setup node
# uses: actions/setup-node@v1
@@ -42,7 +42,7 @@ jobs:
# needs: [lintcode]
# steps:
# - name: checkout
# uses: actions/checkout@v4
# uses: actions/checkout@v5
#
# - name: setup node
# uses: actions/setup-node@v1
@@ -65,7 +65,7 @@ jobs:
# needs: [lintcode,lintstyle]
# steps:
# - name: checkout
# uses: actions/checkout@v4
# uses: actions/checkout@v5
#
# - name: setup node
# uses: actions/setup-node@v1
@@ -90,7 +90,7 @@ jobs:
# CHECKOUTS
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
# CACHING
- name: Install Meteor
@@ -147,10 +147,10 @@ jobs:
needs: [tests]
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Download coverage
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: coverage-folder
path: .coverage/
+12 -11
View File
@@ -1,12 +1,13 @@
{
"editor.tabSize": 2,
"editor.rulers": [80],
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"node_modules": true,
".meteor/local": true
}
}
"terminal.integrated.env.linux": {
"TERM": "xterm-256color"
},
"terminal.integrated.env.osx": {
"TERM": "xterm-256color"
},
"terminal.integrated.env.windows": {
"TERM": "xterm-256color"
},
"terminal.integrated.shell.linux": "/bin/bash",
"terminal.integrated.shellArgs.linux": ["-l"]
}
+629 -10
View File
@@ -1,19 +1,638 @@
[Mac ChangeLog](https://github.com/wekan/wekan/wiki/Mac)
Newest WeKan at these amd64 platforms:
Newest WeKan at these platforms:
- Windows and Linux bundle
- Snap Candidate
- Docker
- Kubernetes
- [bundle zip at releases](https://github.com/wekan/wekan/releases), docs at
- [Linux amd64, arm64, s390x](https://github.com/wekan/wekan/blob/main/docs/Platforms/FOSS/RaspberryPi/Raspberry-Pi.md)
- [Windows amd64, works also at Windows arm64](https://github.com/wekan/wekan/blob/main/docs/Platforms/Propietary/Windows/Offline.md)
- [Mac amd64, works also with Rosetta2 at Apple Silicon](https://github.com/wekan/wekan/blob/main/docs/Platforms/Propietary/Mac.md)
- https://wekan.fi/install/
- Snap Candidate amd64
- Docker amd64
- Kubernetes Docker amd64
- Bitnami MongoDB Docker images do not exist anymore. [MongoDump/MongoRestore to groundhog2k MongoDB images](https://github.com/wekan/charts/issues/45)
Fixing other platforms In Progress.
- Install info at Server part of webpage https://wekan.github.io
- Newest Node.js is at https://github.com/wekan/node-v14-esm/releases/tag/v14.21.4
- MongoDB 6.x
- Node.js 14.x at https://github.com/wekan/node-v14-esm/releases/tag/v14.21.4 and https://nodejs.org/dist/latest-v14.x/
- MongoDB 6.x and 7.x, or FerretDB/PostgreSQL https://blog.ferretdb.io/building-project-management-stack-wekan-ferretdb/
[How to upgrade WeKan](https://github.com/wekan/wekan/issues/4585)
[Upgrade WeKan](https://wekan.fi/upgrade/)
# v7.99 2025-10-11 WeKan ® release
This release fixed the following bugs:
- [Improve automatic Snap upgrades](https://github.com/wekan/wekan/commit/aab671398c7ee3d7ea4934c6c9c977ad630fa74f).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.98 2025-10-11 WeKan ® release
This release adds the following CRITICAL SECURITY FIXES:
- [Security Fix: IDOR CWE-639 that affected WeKan 7.80-7.93](https://github.com/wekan/wekan/commit/b87cff1289d2c98ef84d69e171f112ecedb4d843).
Thanks to Romain Korpas at apitech.fr and xet7.
- [Security Fix: Computational Resource Abuse in Export endpoints](https://github.com/wekan/wekan/commit/d0f118e7af0b2ede517d6d051226c38fa8e557b6).
Thanks to Anynymous Security Researcher and xet7.
- [Security Fix FG-VD-22-078: Prevent SVG Billion Laughs Attack](https://github.com/wekan/wekan/commit/30c1597b658b0ef50fd2efc56786e8b0f08ac72c).
Thanks to Nguyen Thanh Nguyen of Fortinet's FortiGuard Labs and xet7.
- [Security Fix usd-2022-0041: CWE-284 Improper Access Control](https://github.com/wekan/wekan/commit/f6591d7820e01075cba93612a5fdbf692fbe49dc).
Thanks to Christian Pöschl of usd AG and xet7.
- [Security Fix JVN#14269684: Broken access control](https://github.com/wekan/wekan/commit/9720e703fd9432bf0e1bfea2358f8c7ea078f1b1).
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7.
- [Security Fix JVN#74210258: Stored XSS](https://github.com/wekan/wekan/commit/e1fa607f87d821accb846f2deef1f388003848d1).
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7.
- [Security Fix JVN#86586539: Stored XSS](https://github.com/wekan/wekan/commit/ee79cab7b27f73fab62a00ec49add73fd6f7bcaa).
Thanks to Ryoya Koyama of Mitsui Bussan Secure Directions, Inc and xet7.
- [Security Fix JVN#15385465: CWE-79 XSS, that affected WeKan 7.94](https://github.com/wekan/wekan/commit/81c3dc1d956cd7040655940f6569653d7b98fa9a).
Thanks to Sho Sugiyama and xet7.
- Security Fix JVN#80785288: CWE-79 XSS, that affected WeKan 3.94 and v3.95. This was already previously fixed.
Thanks to xet7.
and adds the following new features:
- [Mobile one board per row. Board zoom size percent. Board toggle mobile/desktop mode. In Progress](https://github.com/wekan/wekan/commit/752699d1c2fb8ea9ff0f3ec9ae0b2b776443d826).
Thanks to xet7.
- [Drag any files from file manager to minicard or opened card.
[Part 1](https://github.com/wekan/wekan/commit/3e9481c5bd2c02ba501bd0a6ef1d1e6ce82bb1d9),
[Part 2](https://github.com/wekan/wekan/commit/cdd7d69c660d0b6ac06b7b75d4f59985b8a9322a).
Thanks to xet7.
- [Use attachments from old CollectionFS database structure, when not yet migrated to Meteor-Files/ostrio-files, without needing to migrate database structure](https://github.com/wekan/wekan/commit/a8de2f224f61d0e5c7061fefb1cdd4f45f3bb020).
Thanks to xet7.
- [Show console.log 'Legacy attachments route loaded' only when environment variable DEBUG=true](https://github.com/wekan/wekan/commit/1c84b19f246ebe6d3cad4f56726013147756d9c3).
Thanks to xet7.
- [Make possible for lists to have different names at different swimlanes. Make possible to drag list from one swimlane to another swimlane](https://github.com/wekan/wekan/commit/719ef87efceacfe91461a8eeca7cf74d11f4cc0a).
Thanks to xet7.
- [Add support for Docker/Compose Secrets for passwords to Docker/Snap/Bundle platforms](https://github.com/wekan/wekan/commit/107e2ac90043138ea8aa09aadd92f4af355289c0).
Thanks to Roemer and xet7.
- Add Snap automatic upgrades.
[Part 1](https://github.com/wekan/wekan/commit/0549bc0b0c7dd4a5db53d645662dd4362ef4d1f3),
[Part 2](https://github.com/wekan/wekan/commit/f1e1fd359364dbe6366501ac4f6a150d73509f17).
Thanks to xet7.
and fixes the following bugs:
- Fix DOMPurify paths.
[Part 1](https://github.com/wekan/wekan/commit/90899f0928274cbc30ed3d6df0227664efcd2584),
[Part 2](https://github.com/wekan/wekan/commit/77691244018f3a1e44c28973b40a363bf77f99b2),
[Part 3](https://github.com/wekan/wekan/commit/21ba0a96066a495e885fcf186f026cf1c7ddf45d),
[Part 4](https://github.com/wekan/wekan/commit/2119c6ab0c2d76c8a9b22fa712b35b38345fc040).
Thanks to xet7.
- [Fix sizes of drag handles at desktop mode](https://github.com/wekan/wekan/commit/734165f3c78e9ba9643826da62f78844273f18f6).
Thanks to xet7.
- [Fixed showing translations always, regardsless of is ROOT_URL set correctly or not](https://github.com/wekan/wekan/commit/1a7bd65e596a4a1030e2686a787186b6d1c61abe).
Thanks to xet7.
- [Snap: Removed double mongo3 that's already at migratemongo](https://github.com/wekan/wekan/commit/2a24918a9c31e541f4d6424b77cfd76a8d9f2b06).
Thanks to xet7.
- [Updated release scripts of snapcraft pack command syntax](https://github.com/wekan/wekan/commit/d88d197de964fd71e61ea6c932521f1e5abe7630).
Thanks to xet7.
- [Try to fix Snap automatic upgrade](https://github.com/wekan/wekan/commit/4ec4e19e637b86b05b11afd076fae09d3698b8de).
Thanks to xet7.
- [Added missing metadata fields to snapcraft.yaml](https://github.com/wekan/wekan/commit/cd948fb5765efdf5a7d792180a25ffa26bab2730).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.97 2025-10-08 WeKan ® release
This release fixes the following bugs:
- [Fixed Collapse button not there when using clearlight board theme](https://github.com/wekan/wekan/pull/5900).
Thanks to seve12.
- [Fixed translation of "Change Language" at login page](https://github.com/wekan/wekan/commit/9a31371de0e155d3144769f45a1fa216872935eb).
Thanks to xet7.
- [Some mobile and tablet fixes. Show drag handles at touch screens only. No toggle of drag handles anymore](https://github.com/wekan/wekan/commit/3fda90612d88fc5a8f1e17ae5c399745de06aada).
Thanks to xet7.
- [Removed white box that appeared when clicking something](https://github.com/wekan/wekan/commit/3814a218c2dab3ed9e8908c3a2de996ffebf6d9d).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.96 2025-10-07 WeKan ® release
This release adds the following updates:
- [Updated release script for new command of uploading snap package to Snap Store](https://github.com/wekan/wekan/commit/dec9b82da0d700aafd7e2b2063b5d5b07dd383c3).
Thanks to xet7.
- [Updated to MongoDB 7.0.25 at Snap Candidate](https://github.com/wekan/wekan/commit/dec038e7edce11e2ce59de974aa870d7266af33b).
Thanks to MongoDB developers.
and fixes the following bugs:
- [Added missing mobile drag drop image to docs from wekan.github.io git history](https://github.com/wekan/wekan/commit/5151814e98599c22fff98dc7c42fbf634004ab20).
Thanks to xet7.
- [Fix links in docker-compose.yml to point to doc in repo](https://github.com/wekan/wekan/pull/5882).
Thanks to Skylark13.
- [Fixed find.sh script errors about unmatched single quotes and binary files that are now ignored](https://github.com/wekan/wekan/commit/730bb6d166baa5530cc75b4c94ae46c8077884b0).
Thanks to xet7.
- [Fixed links at docs](https://github.com/wekan/wekan/commit/6f2b89121402df8ecba88295ad09f5c4179ab0ed).
Thanks to xet7.
- [Added missing screenshots from wekan.github.io history to wekan/docs/Features/](https://github.com/wekan/wekan/commit/9a7fa25ca33d4267e193f0f9bb97b09c490e44fe).
Thanks to xet7.
- [Some accessibility, saving, downloading and editor fixes](https://github.com/wekan/wekan/pull/5895).
Thanks to seve12.
- [Hide extra keyboard shortcuts toggle](https://github.com/wekan/wekan/commit/62ad588aa982cd4305a8817cf21f0818234f4354).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.95 2025-09-18 WeKan ® release
This release adds the following updates:
- [Updated upgrade link at repo readme](https://github.com/wekan/wekan/commit/b3d3bf159376d56048361a385f0b295667e2319c).
Thanks to xet7.
- [Fixed image link at docs](https://github.com/wekan/wekan/commit/ad7e3774c2b29265a8fbefdde7b9b83822af6def).
Thanks to xet7.
- [More info about ToroDB, FerretDB, Turso, TigerBeetle, PostgreSQL, SQLite etc](https://github.com/wekan/wekan/commit/701485d76aded5ee4fa17967d94918132a821af6).
Thanks to xet7.
- [Added missing image to WeKan Multiverse page](https://github.com/wekan/wekan/commit/946f7045e92e26bbe8d182634844ee5eebf73564).
Thanks to xet7.
- [Added more info to Windows Offline docs about WRITABLE_PATH and ATTACHMENTS_STORE_PATH](https://github.com/wekan/wekan/pull/5872).
Thanks to sowwos.
- [Added PGP public key for sending encrypted email](https://github.com/wekan/wekan/commit/dd80b7308bb6c66113c8e6009c442a44a29e477a).
Thanks to xet7.
- [Updated dependencies](https://github.com/wekan/wekan/commit/c4161c5ce69a35c76364b13bcc456905f6335162).
Thanks to developers of dependencies.
- [Replace bitnami mongodb Helm chart by groundhog2k one](https://github.com/wekan/charts/pull/44).
Thanks to ariep.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.94 2025-08-18 WeKan ® release
This release adds the following new features:
- [Feature: Accessibility page at /accessibility. Settings at Admin Panel. When enabled, link at right sidebar](https://github.com/wekan/wekan/commit/d83ce5e6335c175f2f4a384f6090c18c7f860555).
Thanks to xet7.
- [Feature: Added brute force login protection settings to Admin Panel/People/Locked Users](https://github.com/wekan/wekan/commit/ae0d059b6feb38a438ca21aa154c63b410641763).
Added filtering of Admin Panel/People/People: All Users/Locked Users Only/Active/Not Active.
Added visual indicators: red lock icon for locked users, green check for active users, and red X for inactive users.
Added "Unlock All" button to quickly unlock all brute force locked users.
Added ability to toggle user active status directly from the People page.
Moved lockout settings from environment variables to database so admins can configure the lockout thresholds directly in the UI.
Thanks to xet7.
- Added docs for Windows SSL/TLS.
[Part 1](https://github.com/wekan/wekan/commit/92c0543614fb92cf8217d8cc24a367296f3ade37),
[Part 2](https://github.com/wekan/wekan/commit/ce528b1826255ebf3ac9533dd8ed91bec8bbe8b1),
[Part 3](https://github.com/wekan/wekan/commit/ee01a07b0ac7c6b06054b3d7bfac8c38161adf19),
[Part 4](https://github.com/wekan/wekan/commit/cc78e19740ae1bf42f2bbb17f801fe2d4dac135d),
[Part 5](https://github.com/wekan/wekan/commit/044793cc4473bebc8eefa64a0df9e9a20115d049),
[Part 6](https://github.com/wekan/wekan/commit/a7bcfc6db7cc78892ed20cdf0d03f84094853687).
Thanks to xet7.
and adds the following updates:
- Update CHANGELOG.md platforms info at top.
[Part 1](https://github.com/wekan/wekan/commit/0e43a08689c0d47c816ce781e93650f0c37efe28),
[Part 2](https://github.com/wekan/wekan/commit/4bc2fd4a7fc166041a5c483aad73bf8079c3ae45),
[Part 3](https://github.com/wekan/wekan/commit/62269a99024744c789ac931921c96d5edae9d79e),
[Part 4](https://github.com/wekan/wekan/commit/4aad3dafd4530cc7779072fc9a550d8732f32558),
[Part 5](https://github.com/wekan/wekan/commit/c2aabbc6db9ffbb73d9f06edb73a15a9f4838df4),
[Part 6](https://github.com/wekan/wekan/commit/b0865c8d06a31d07b5b5df719871c298e1cf4ad8),
[Part 7](https://github.com/wekan/wekan/commit/30795a46cfb5f37837206a6de653913bfb631595),
[Part 8](https://github.com/wekan/wekan/commit/9a91214043d93307074cf33e54d40cb43c14ad62).
- [Updated security email address](https://github.com/wekan/wekan/commit/11872545734db82229e873b48f122d826457fec3).
Thanks to xet7.
- Updated GitHub Docker Actions.
[Part 1](https://github.com/wekan/wekan/pull/5855),
[Part 2](https://github.com/wekan/wekan/pull/5856),
[Part 3](https://github.com/wekan/wekan/pull/5864),
[Part 4](https://github.com/wekan/wekan/pull/5865).
Thanks to Dependabot.
- [Added info about Sandstorm Radicale Calendar and Contacts](https://github.com/wekan/wekan/commit/dfdd0b6cbbbb60bf6dba7a61f34dc52e74f98b41).
Thanks to xet7.
- [Updated dependencies](https://github.com/wekan/wekan/commit/97b5931a4f717541631dde55f2b834d037e1d82d).
Thanks to developers of dependencies.
- Reorganized Design Docs.
[Part 1](https://github.com/wekan/wekan/commit/f34490fe2820352c8303f0bac47ad7158592e8f0),
[Part 2](https://github.com/wekan/wekan/commit/a662283b7de91c0ef63195691e06b5cbc6cdff6c).
Thanks to xet7.
- [Added related link to design docs](https://github.com/wekan/wekan/commit/a662283b7de91c0ef63195691e06b5cbc6cdff6c).
Thanks to xet7.
- [Upgraded to MongoDB 7.0.23 at Snap Candidate](https://github.com/wekan/wekan/commit/8e01e3c762748269c2e60f9f349dac30f30971d7).
Thanks to MongoDB developers.
and fixes the following bugs:
- [Fixes for building at macOS](https://github.com/wekan/wekan/commit/200545822c5c778521f76525938fe777ed9666f0).
Thanks to xet7.
- [Improves accessibility by disabling custom Tab handling](https://github.com/wekan/wekan/pull/5853).
Thanks to seve12, co-maintainer of WeKan.
- [Comment out not used Tab code at accessibility related changes](https://github.com/wekan/wekan/commit/0e32f666eb30cc254177119907e6eae3c09ce0ca).
Thanks to xet7.
- [Fixed link at OpenShift docs](https://github.com/wekan/wekan/commit/b9887fc91758edb31259a8df7770a1d992bc9251).
Thanks to xet7.
- [Added FerretDB/PostgreSQL to changelog](https://github.com/wekan/wekan/commit/c16e99ba1ec7bc25a4e0449ea463ea8f4b02da11).
Thanks to xet7.
- [Accessibility](https://github.com/wekan/wekan/pull/5857):
Added product name to page titles, settings and global search.
More accessible header and layout templates, modal dialogs, DOM structure, color contrast.
Thanks to seve12.
- [Fixed uppercase K of WeKan](https://github.com/wekan/wekan/commit/b137108ae15a9c5685cca5f45cfa9480ec7d3510).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.93 2025-07-18 WeKan ® release
This release adds the following new features:
- [Enhance API documentation and add board-related endpoints](https://github.com/wekan/wekan/pull/5815).
Thanks to Atry.
- Snap Candidate: If CPU does not support AVX, use Qemu that supports AVX, so that MongoDB 6 works.
[Part 1](https://github.com/wekan/migratemongo/commit/e7ca69584f021c4de16062f7074f177cca7ab25c),
[Part 2](https://github.com/wekan/migratemongo/commit/e34efeeced9e293ff6ea12bf36486eab3ce3a3f5),
[Part 3](https://github.com/wekan/wekan/commit/59ab6c1cd8ca3d71616201b02de6536b15b2303d).
Thanks to xet7.
- [Added docs about using MongoDB at unsupported CPUs with Qemu](https://github.com/wekan/wekan/commit/f926448bbbbd570ad1e6a1015c755b12c6b229c0).
Thanks to xet7.
- [Helm Chart: Add podAnnotations support](https://github.com/wekan/charts/pull/42).
Thanks to adalinesimonian.
- [Added release script to switch between using kvm, snapcraft.io/multipass, waydroid and virtualbox](https://github.com/wekan/wekan/commit/dfc658b910f038fa6d6ae2e06c190eb8e6205a78).
Thanks to xet7.
- [Add a REST API endpoint to retrieve a card by ID](https://github.com/wekan/wekan/pull/5828).
Thanks to Atry.
- [Avoid calling ReactiveCache.getCard twice](https://github.com/wekan/wekan/pull/5829).
Thanks to Atry.
- [Add REST API endpoint to edit a list with various properties](https://github.com/wekan/wekan/pull/5832).
Thanks to Atry.
and adds the following major updates to links of WeKan websites, blog and docs:
- These changes are because most people at Finland expect Finnish company to be at .fi domain.
- It did take too much time at local computer shop to explain about domain being .team
- Most content have been moved to wekan.fi . For app stores https://wekan.fi/app/ there is still wekan.team used for app.
- Many wikis and images from wekan.github.io have been moved to wekan repo docs directory
- Pull requests welcome to fix any broken links at docs directory, and organizing docs/Features and their screenshots to subdirectories of each feature.
- [Updated issue template about pull requests for fixes to docs](https://github.com/wekan/wekan/commit/e4822d8bc4dd0c200b63983013625d2c3677e9f9).
Thanks to xet7.
- wekan.team to wekan.fi.
[Part 1](https://github.com/wekan/wekan/commit/790bafbb096a606cdb34a1d942478ae53174ff1c),
[Part 2](https://github.com/wekan/wekan/commit/b52d1ca6c47fbeeb3c5f93111809a1863478b833).
Thanks to xet7.
- [Moved images from wekan.github.io to repo wekan/docs](https://github.com/wekan/wekan/commit/c5e5bb613e9d0e8652bce24a1cecb620dd8e7cd4).
Thanks to xet7.
- [wekan.github.io to wekan.fi, and blog.wekan.team to wekan.fi/blog](https://github.com/wekan/wekan/commit/89480b61ce98d5a344108ad7c2ce9b3577fd3d7e>
Thanks to xet7.
- Update Browser-compatibility-matrix.md about
[Servo](https://github.com/wekan/wekan/commit/c256ce69688e47675245bf68f13d3025b2a7d7ab),
[uWolf](https://github.com/wekan/wekan/commit/ad3306e19e422b9b8ce70a13e862bc107fec1eba),
[TUI webbrowsers](https://github.com/wekan/wekan/commit/7841c9e801c737aab07e9bd68f8d84f9e4becc3e),
[Chawan](https://github.com/wekan/wekan/commit/be1b9595196e2072ec2259de9b81bc3b823722eb) and
[Elinks](https://github.com/wekan/wekan/commit/12e6e469249c9392181df20f51bcc684e2656960).
Thanks to xet7.
- Updated links, after moving many wikis to wekan repo docs directory:
[Part 1: Updated docs](https://github.com/wekan/wekan/commit/31e043c1d7c0d4031054234241f6a1b7479f2134),
[Part 2: Removed footer](https://github.com/wekan/wekan/commit/40a52da2d3fd472847b9bfd2696f3f9a72021b52),
[Part 3: Moved content from Home.md to README.md](https://github.com/wekan/wekan/commit/2a415cbd2661bd210fdd18626f1e606f73334bd2),
[Part 4: Updated links at readme](https://github.com/wekan/wekan/commit/9aa028f32dc7c186d55ada422b73a7e331de2cbb),
[Part 5: Updated deep dive link](https://github.com/wekan/wekan/commit/11415cd51781bde20375c6d98fccde17227136fd),
[Part 6: Fixed links](https://github.com/wekan/wekan/commit/cc7459b98395f15fd2c97992f74c279a93f8956a),
[Part 7: Updated links](https://github.com/wekan/wekan/commit/4bfc0140bef8504ba24b237a9c5c525a5bf3fb7d),
[Part 8: Reorganized docs file locations](https://github.com/wekan/wekan/commit/f54cbac37008fc99f19fb20930d2fa5ecb535a69),
[Part 9: Fix Discord image link and WeKan API link](https://github.com/wekan/wekan/commit/3a8473e6326bff2f17ada1bb48f0c7f38b356721),
[Part 10: Fix links about docs that were moved from wiki to readme](https://github.com/wekan/wekan/commit/bd796ce64248dc58ff4a192ca58796096dbef019),
[Part 11: Updated building Snap](https://github.com/wekan/wekan/commit/aa681cde88d17ee0fd957233c52297e9ab0047ce),
[Part 12: Updated Snap platforms setting](https://github.com/wekan/wekan/commit/6b401000b91dc46b810dfc27964246891b7cd68c),
[Part 13: Fix link to image about PWA app icon install. Thanks to stevenroose and xet7](https://github.com/wekan/wekan/commit/9271b07383c3544bd1368f95e79a7d4d637d5922),
[Part 14: Formatting](https://github.com/wekan/wekan/commit/fa1adfec768ad1d34f3fbd45e6332c6c0db87b05),
[Part 15: Removed old link Test Edge from docs index](https://github.com/wekan/wekan/commit/5d0a0c931f3d4ea2e65fcc412f1eeaa6cc2107d5),
[Part 16: Fix link to image at docs](https://github.com/wekan/wekan/commit/2cf57250e8bc6f6f220f0a0f8dc85a5196f80138),
[Part 17: Fixed not working link](https://github.com/wekan/wekan/commit/76769d1b855032ef17aeae3c82558cd301e2da0d),
[Part 18: Added most often used links](https://github.com/wekan/wekan/commit/4fe955650a11d77a06a319a2e707ae97d77b471f),
[Part 19: Update info about hashing](https://github.com/wekan/wekan/commit/5d09100cb6cf0cc686112587327c8cb993a559e4),
[Part 20: Updated docs about Kubernetes](https://github.com/wekan/wekan/commit/a052cc8fa5bffad652cf585cf5cab84e13afa442),
[Part 21: Removed not working link from docs](https://github.com/wekan/wekan/commit/a2654b2e2950974cf25e6acaa36a6d5a4285564c),
[Part 22: Fix docs link about CSV. Part 1](https://github.com/wekan/wekan/commit/3892be47ac0fc0ff3bdafcf44ce818eea47fe6b0),
[Part 23: Fix docs link about CSV. Part 2](https://github.com/wekan/wekan/commit/a9c67ac2006592ac575a5cb68fe575d8ac3f4d6a),
[Part 24: Updated docs about importing from Trello. Part 1](https://github.com/wekan/wekan/commit/55ef6c0c56b3b383edeb2984bcdfbf2ab7e74e6d),
[Part 25: Updated docs about importing from Trello. Part 2](https://github.com/wekan/wekan/commit/40b2cf88fc7c8a94fd9ad8690ca4ca68add68d5f),
[Part 26: Updated docs about importing from Trello. Part 3](https://github.com/wekan/wekan/commit/1610b84845f332eabc8e204a917ca5daa284d24d),
[Part 27: Updated docs about importing from Asana](https://github.com/wekan/wekan/commit/9adf5027fafbb9f44507dcc703a38de9b6215287),
[Part 28: Updated docs about migrating manually. Part 1](https://github.com/wekan/wekan/commit/450b33f98a8527423e6c5cee98bb5020a77e113f),
[Part 29: Updated docs about migrating manually. Part 2](https://github.com/wekan/wekan/commit/2f27a3f839a26a773b3a2cf8e7f93d3930b01b1a),
[Part 30: Updated docs](https://github.com/wekan/wekan/commit/d59337ae47876396c2571aa803bd57236abfc328),
[Part 31: Updated Azure link](https://github.com/wekan/wekan/commit/a5acd0801aa55b49243bdc1c001c226546537cb3),
[Part 32: Updated Keycloak link](https://github.com/wekan/wekan/commit/e0284f225b6567eb90ac0224fd348cf8e4e87229),
[Part 33: Updated image links at Azure docs](https://github.com/wekan/wekan/commit/6d16ec238a00f456494c84e08ea13eb166e42f6e),
[Part 34: Updated Python docs](https://github.com/wekan/wekan/commit/bb0814bb11bf00e73c3c48c9954792c6ca09e3be).
Thanks to xet7.
and adds the following updates:
- [Updated dependencies](https://github.com/wekan/wekan/commit/e6980be061a6ab54d592cd86f1079a7672a3e081).
Thanks to developers of dependencies.
- [Upgraded Snap Candidate to have base core24, MongoDB 7 and Caddy 2](https://github.com/wekan/wekan/commit/6526d99123b047fe4dfcf8f60a23f65d1261324c).
Thanks to xet7.
- [Removed old broken not used snap configuration files](https://github.com/wekan/wekan/commit/b7409c1d0b574b77f0fa95f7289d815671c1e224).
Thanks to xet7.
- [Updated release website script](https://github.com/wekan/wekan/commit/6c6b66c802e88e8dcc7d9215b9caad4c269861c5).
Thanks to xet7.
and fixes the following bugs:
- [CleanDark Theme Fixes](https://github.com/wekan/wekan/pull/5805).
Thanks to walster001.
- Specify meteor version, otherwise the latest meteor version is not compatible with node14.
[Part 1](https://github.com/wekan/wekan/pull/5816),
[Part 2](https://github.com/wekan/wekan/commit/51e43f1c254abee7ee12e8fdab8c52695e858fa2).
Thanks to dassio and xet7.
- [Reorganized docs to fix building WeKan](https://github.com/wekan/wekan/commit/6e11aa27f896e41c57980b45b59dc8248259421f).
Thanks to xet7.
- Fixed rebuild-wekan.sh install deps for macOS.
[Part 1](https://github.com/wekan/wekan/commit/938fe49b2c0dd523e3402b514b13ba5b605dac2b),
[Part 2](https://github.com/wekan/wekan/commit/2df73bedeebf6e6da2e4003bd236668e185f6701).
Thanks to xet7.
- [Fixed release script of building Snap locally at Ubuntu](https://github.com/wekan/wekan/commit/159324858bb2a72761082265558329eee0c0863d).
Thanks to xet7.
- [Fix: Correct return type in API documentation for Custom Fields](https://github.com/wekan/wekan/pull/5826).
Thanks to Atry.
- [Fixed Snap local build script](https://github.com/wekan/wekan/commit/69ce79a7b9e86b60482d42455701b58ae9926c69).
Thanks to xet7.
- [Fixed building Docker image. Pushed new Docker image to Docker Hub, Quay and GitHub](https://github.com/wekan/wekan/commit/f894f9ef6d8bad47260d0b648f18c36a5b208517).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.92 2025-06-12 WeKan ® release
This release adds the following updates:
- [Updated Docker build push action](https://github.com/wekan/wekan/pull/5795).
Thanks to dependabot.
- [Updated to MongoDB 6.0.24 at Snap Candidate](https://github.com/wekan/wekan/commit/6905e24199186274f37d8bbdfac313f957fdd54f).
Thanks to MongoDB developers.
- Updated dependencies.
[Part 1](https://github.com/wekan/wekan/commit/7115c292c7066d8d00778fa738bb11c2db467895),
[Part 2](https://github.com/wekan/wekan/commit/1f10c208744ec45e062db08a179b6e9a3b1bcd2e).
Thanks to developers of dependencies.
- [Upgrade to MongoDB 7.0.21](https://github.com/wekan/wekan/commit/d2f17ef1402335e4b3bd9de8864c68f97714febf).
Thanks to MongoDB developers.
- [Snap Candidate back to MongoDB 6.0.24, because 7.0.21 did not work](https://github.com/wekan/wekan/commit/985afafed0eb608fb95d4e54f846836b1fb0e800).
Thanks to xet7.
and fixes the following bugs:
- [Allow selection of card text via webkit/user-select attributes](https://github.com/wekan/wekan/pull/5793).
Thanks to walster001.
- [Helm Chart: Fix: quote host names](https://github.com/wekan/charts/pull/41).
Thanks to Atry.
- [Fix: properly document /users/login API](https://github.com/wekan/wekan/pull/5801).
Thanks to Atry.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.91 2025-05-25 WeKan ® release
This release adds the following updates:
- [Updated Docker build push action](https://github.com/wekan/wekan/pull/5780).
Thanks to dependabot.
and fixes the following bugs:
- Reverted due date fixes.
[Part 1](https://github.com/wekan/wekan/commit/1979b1692dcaf6fd909cabfb894635f1e6a66fa8),
[Part 2](https://github.com/wekan/wekan/commit/aaa5f9885d37a369606e61a759af37f444ec606d).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.90 2025-05-14 WeKan ® release
This release fixes the following bugs:
- [Fix Due Date Problem in Non-English Numbers](https://github.com/wekan/wekan/pull/5774).
Thanks to valhalla-creator.
- [Added missing quotes to Fix Due Date Problem in Non-English Numbers](https://github.com/wekan/wekan/commit/c0a9780f803ed445a93a274d13504a8f245c1885).
Thanks to xet7.
- [Changed start.bat default ROOT_URL=http://localhost , although it only works for local user](https://github.com/wekan/wekan/commit/e52158b729c8ba39a55fe52e38fd6b134b42548e).
Thanks to xet7.
- [Fix Lines in multiline markdown code block to not anymore have darker background](https://github.com/wekan/wekan/commit/b82ba63532b32ec3a0c860a380648cef6739db0f).
Thanks to mueller-ma and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.89 2025-05-13 WeKan ® release
Note: Docker image is only at ghcr.io (GitHub) and Docker Hub (wekanteam/wekan).
Quay.io is at read only mode, they are fixing something, so it's not possible to
push Docker image yet to quay.io .
This release adds the following new features:
- [Add email notifications language localization feature](https://github.com/wekan/wekan/pull/5769).
Thanks to Adamsss001.
and adds the following updates:
- [Added script to build snap locally and push to snapcraft.io candidate and edge](https://github.com/wekan/wekan/commit/072ced9d0e53dc6c8964e9b37fc7d1036962ca19).
Thanks to xet7.
- [Updated Browser Compatibility Matrix by adding Servo](https://github.com/wekan/wekan/commit/394f2eae69542067fde9e2511ffcef165d170d2d).
Thanks to xet7.
- [Updated Caddy docs](https://github.com/wekan/wekan/commit/9aa12b0eb62962bd107fe1aa87cdf5bad5a5905f).
Thanks to xet7.
- [Upgraded to MongoDB 6.0.23 at Snap Candidate](https://github.com/wekan/wekan/commit/0bd410866196bc2faa76b9c26c12f42617321a03).
Thanks to MongoDB developers.
and fixes the following bugs:
- [Fix list insertion order and prevent runtime error in "Add After" feature](https://github.com/wekan/wekan/pull/5767).
Thanks to valhalla-creator.
- [Add missing code of fix insertion order of list](https://github.com/wekan/wekan/commit/7d1a1475baefb3fd20da3df835c349a62b425041).
Thanks to xet7.
- [Fix: Add CSS vendor prefixes for user-select and text-size-adjust for better browser compatibility](https://github.com/wekan/wekan/pull/5772).
Thanks to oussama-madimagh.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.88 2025-04-25 WeKan ® release
This release fixes the following bugs:
- [Reverted translation fix that sometimes did not work](https://github.com/wekan/wekan/commit/c825895cebd24355d076741512c9aa16844393d9).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.87 2025-04-25 WeKan ® release
Note: This release does not work, there is bugs. Use newest release.
This release fixes the following bugs:
- [Fix typos](https://github.com/wekan/wekan/commit/d0ea5bf50067fd76359330986edbad8dd1fbcdcc).
Thanks to xet7.
- [Fix more contrasting issues](https://github.com/wekan/wekan/pull/5750).
Thanks to walster001.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.86 2025-04-25 WeKan ® release
Note: This release does not work, there is typos. Use newest release.
This release adds the following updates:
- [Improve impersonate user documentation in docs/Admin/Impersonate-user.md](https://github.com/wekan/wekan/pull/5746).
Thanks to nourguidara.
and fixes the following bugs:
- [Add toggle watch icon on card. Add questions are you sure to duplicate board and archive board](https://github.com/wekan/wekan/pull/5745).
Thanks to Rayene123.
- [Fix translations not working](https://github.com/wekan/wekan/pull/5748).
Thanks to nourguidara.
- [Fix contrast issue checkbox at Exodark theme](https://github.com/wekan/wekan/pull/5749).
Thanks to walster001.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.85 2025-04-21 WeKan ® release
This release adds the following updates:
- Updated Browser compatibility matrix, adding Iris browser at RISC OS Direct, and fixing links.
[Part1](https://github.com/wekan/wekan/commit/db5346fc5c7407160f381c0fcf4a87204206ed55),
[Part2](https://github.com/wekan/wekan/commit/05d1736f5f21e93e83b2e25029c6cab6c5106398).
Thanks to xet7.
- [Updated to MongoDB 6.0.22](https://github.com/wekan/wekan/commit/c1a4250bd2e26be5549704234a3cfb5306120352).
Thanks to MongoDB developers.
and fixes the following bugs:
- [Fix board sidebar menu doesn't open in mobile](https://github.com/wekan/wekan/commit/01950cc796697fa201ac9e4376cb204d308e8181).
Thanks to mimZD and xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.84 2025-03-23 WeKan ® release
This release adds the following new features:
- [Time on minicard for Start/End/Due Date](https://github.com/wekan/wekan/pull/5712).
Thanks to Rayene123.
and adds the following updates:
- [Added developer docs about Login code](https://github.com/wekan/wekan/commit/c0e4e01deb936653df69b4fd21598ac27cd349a0).
Thanks to xet7.
- Updated dependencies.
[Part 1](https://github.com/wekan/wekan/pull/5718),
[Part 2](https://github.com/wekan/wekan/commit/bb6ac70f63b6f3568b7c943417c698615936a956).
Thanks to developers of dependencies.
and fixes the following bugs:
- [Fixed typo at Shortcuts, now became visible translations of assignees visibility 1-9 shortcuts](https://github.com/wekan/wekan/commit/4510ddda1507bc775b9523d3673adba48d7a8385).
Thanks to xet7.
- [Fixed building OpenAPI docs](https://github.com/wekan/wekan/commit/a2911bc9c3bd94ef583388931d2cd354cc8657e3).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.83 2025-03-08 WeKan ® release
This release adds the following updates:
- [Adding Development information to readme](https://github.com/wekan/wekan/pull/5702).
Thanks to adam-fu.
- Updated GitHub actions.
[Part 1](https://github.com/wekan/wekan/pull/5703),
[Part 2](https://github.com/wekan/wekan/pull/5704).
and fixes the following bugs:
- [Removed siteurl from manifest to fix browser console error about not matching URL](https://github.com/wekan/wekan/commit/b402676079517e463ed291285f69c04126a00975).
Thanks to xet7.
- [Exception while invoking method 'copyCard' TypeError: Cannot read property 'name' of undefined](https://github.com/wekan/wekan/pull/5711).
Thanks to Firas-Git.
- [Comment out error message of non-existing Custom Field](https://github.com/wekan/wekan/commit/908a5fc60d5d574a36d4bfd496d3a16fd267ae75).
Thanks to xet7.
- [Reverted Docker changes of WeKan v7.68 to get WeKan Docker version working](https://github.com/wekan/wekan/commit/e7462ada12ec8edfd08d6c3b3a97a034211d51eb).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.82 2025-02-24 WeKan ® release
v7.82 Docker version is broken: https://github.com/wekan/wekan/issues/5697 . Snap Candidate works.
This release adds the following new features:
- [Add possibility to use a token in place of ipaddress to access metrics route](https://github.com/wekan/wekan/pull/5682).
Thanks to salleman33.
and adds the following updates:
- [Updated dependencies](https://github.com/wekan/wekan/pull/5691).
Thanks to dependabot.
- [Updated requirements at docs](https://github.com/wekan/wekan/commit/148b81262d0d143460e881d645fefa6740aae40d).
Thanks to mueller-ma.
- [Updated dependencies](https://github.com/wekan/wekan/commit/666ee8403388f7d5e1a30cf0e53bc46a70bf1c40).
Thanks to developes of dependencies.
- [Fixed building WeKan. Updated dompurify. Forked Meteor 2.14 version of meteor-node-stubs to update elliptic](https://github.com/wekan/wekan/commit/18d0fa43275cd2955dd6416213e316ca08a62255).
Thanks to developers of depedencies and xet7.
and fixes the following bugs:
- [Added missing ) character](https://github.com/wekan/wekan/commit/563a508e269be87eb713e2888409525e1ba82001).
Thanks to xet7.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.81 2025-02-07 WeKan ® release
This release adds the following new features:
- [Helm Chart: Added secretManaged value for enabling or disabling the creation of secret by Helm](https://github.com/wekan/charts/pull/39).
Thanks to salleman33.
and adds the following updates:
- [Updated Docker Actions](https://github.com/wekan/wekan/pull/5670).
Thanks to dependabot.
- [Added Meteor 3.1 learning course to docs](https://github.com/wekan/wekan/commit/0c7e12c5e7f322bdbaaa61100e66153dd0b92e4d).
Thanks to producer of learning course.
- [Upgraded to MongoDB 6.0.20 at Snap Candidate](https://github.com/wekan/wekan/commit/b571f1c9530b899db75bf28a03c18277a9b77cb8).
Thanks to MongoDB developers.
and fixes the following bugs:
- [Fixed env variable METRICS_ACCEPTED_IP_ADDRESS to be same as at docs](https://github.com/wekan/wekan/commit/0b1e0bd39569175668c195b63dde91bf0e6f1b24).
Thanks to salleman33.
- [Fixed misspelling of hours at env variable setting LDAP_BACKGROUND_SYNC_INTERVAL](https://github.com/wekan/wekan/commit/36a307785369337a788499065f64175971878930).
Thanks to hubermam.
- [Helm Chart: Restore pod security context in deployment](https://github.com/wekan/charts/pull/40).
Thanks to adalinesimonian.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.80 2025-01-12 WeKan ® release
This release fixes the following bugs:
- [Fix card updating issues with ReactiveCache when using keyboard shortcuts](https://github.com/wekan/wekan/pull/5654).
Thanks to NadavTasher.
- [Fix assignee toggling keyboard shortcut to only toggle current board members](https://github.com/wekan/wekan/pull/5655).
Thanks to NadavTasher.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.79 2025-01-02 WeKan ® release
This release adds the following new features:
- [Add toggle for week-of-year in date displays (ISO 8601)](https://github.com/wekan/wekan/pull/5652).
Thanks to NadavTasher.
- [Assign members using keyboard shortcut Ctrl+Alt+(1-9)](https://github.com/wekan/wekan/pull/5653).
Thanks to NadavTasher.
Thanks to above GitHub users for their contributions and translators for their translations.
# v7.78 2024-12-31 WeKan ® release
@@ -1918,7 +2537,7 @@ This release adds the following new features:
- [Count of attachments on minicard. (Badges renamed to Count of attachments)](https://github.com/wekan/wekan/pull/4940).
Thanks to helioguardabaxo.
- [Renamed Badge to Count of attachments on minicard. Changed icons to Cover image on minicard](https://github.com/wekan/wekan/commit/825742359ef0738b110ed0904853c604bdbd1bac).
Thanks to xet7.
Thanks to xet7.
- [Added conditional to show after list field only if board has at least one list. Now after list shows the last list by default](https://github.com/wekan/wekan/pull/4941).
Thanks to helioguardabaxo.
- [Changed Add List to be at left. Before it was at right](https://github.com/wekan/wekan/commit/467835192fbcd9d4016674fa2ee406258cc106e7).
+1 -1
View File
@@ -11,7 +11,7 @@ For all code at WeKan GitHub Organization https://github.com/wekan
## Private reports
- Email support@wekan.team
- Email support@wekan.fi
- Security issues: [SECURITY.md](SECURITY.md)
- License violations
- Anything private, sensitive or negative
+1 -1
View File
@@ -11,7 +11,7 @@ Not paid:
Paid by customers of WeKan Team:
- Commercial Support at https://wekan.team/commercial-support/
- Commercial Support at https://wekan.fi/commercial-support/
- Support
- Private Chat
- Features
+154 -96
View File
@@ -1,76 +1,31 @@
FROM scratch AS downloads
# Download NodeJS bundle
ADD https://static.meteor.com/dev-bundle-node-os/v14.21.4/node-v14.21.4-linux-x64.tar.gz node.tar.gz
# Download Meteor bundle
ADD https://static.meteor.com/packages-bootstrap/2.16/meteor-bootstrap-os.linux.x86_64.tar.gz meteor.tar.gz
FROM ubuntu:24.04 AS build
# Install node from official archive
RUN --mount=type=bind,from=downloads,source=node.tar.gz,target=node.tar.gz \
tar xzf node.tar.gz --strip-components=1 --keep-old-files --no-same-owner
# Install meteor from official archive
RUN --mount=type=bind,from=downloads,source=meteor.tar.gz,target=meteor.tar.gz \
tar xzf meteor.tar.gz -C $HOME --no-same-owner
# Update the npm version
RUN npm install -g npm@6.14.17
# Install several build dependencies
RUN apt update && \
apt install --yes --no-install-suggests --no-install-recommends ssh git g++ curl ca-certificates && \
rm -r /var/lib/apt/lists
# Change to temporary working directory
WORKDIR /workdir
# Copy package.json and package-lock.json to install application dependencies
COPY package.json .
COPY package-lock.json .
# Install build dependencies
RUN $HOME/.meteor/meteor npm install --production
# Copy meteor application configurations
COPY .meteor .meteor
# Copy application sources
COPY packages packages
COPY imports imports
COPY config config
COPY models models
COPY public public
COPY server server
COPY client client
# Build the application
RUN $HOME/.meteor/meteor build --directory /build --allow-superuser
# Enter server bundle directory
WORKDIR /build/bundle/programs/server
# Install server dependencies
RUN $HOME/.meteor/meteor npm install --production
# Enter installation directory of fibers
WORKDIR /build/bundle/programs/server/node_modules/fibers
# Build fibers integrations
RUN node build.js
FROM ubuntu:24.04 AS wekan
# Add metadata to image
FROM ubuntu:24.04
LABEL maintainer="wekan"
LABEL org.opencontainers.image.ref.name="ubuntu"
LABEL org.opencontainers.image.version="24.04"
LABEL org.opencontainers.image.source="https://github.com/wekan/wekan"
# Set default environment variables
ENV WITH_API=true \
# 2022-04-25:
# - gyp does not yet work with Ubuntu 22.04 ubuntu:rolling,
# so changing to 21.10. https://github.com/wekan/wekan/issues/4488
# 2021-09-18:
# - Above Ubuntu base image copied from Docker Hub ubuntu:hirsute-20210825
# to Quay to avoid Docker Hub rate limits.
ARG DEBIAN_FRONTEND=noninteractive
ENV BUILD_DEPS="apt-utils gnupg gosu wget bzip2 g++ curl libarchive-tools build-essential git ca-certificates python3 unzip"
ENV \
DEBUG=false \
NODE_VERSION=v14.21.4 \
METEOR_RELEASE=METEOR@2.14 \
USE_EDGE=false \
METEOR_EDGE=1.5-beta.17 \
NPM_VERSION=6.14.17 \
FIBERS_VERSION=4.0.1 \
ARCHITECTURE=linux-x64 \
SRC_PATH=./ \
WITH_API=true \
RESULTS_PER_PAGE="" \
DEFAULT_BOARD_ID="" \
ACCOUNTS_LOCKOUT_KNOWN_USERS_FAILURES_BEFORE=3 \
@@ -111,6 +66,7 @@ ENV WITH_API=true \
OAUTH2_LOGIN_STYLE=redirect \
OAUTH2_CLIENT_ID="" \
OAUTH2_SECRET="" \
OAUTH2_SECRET_FILE="" \
OAUTH2_SERVER_URL="" \
OAUTH2_AUTH_ENDPOINT="" \
OAUTH2_USERINFO_ENDPOINT="" \
@@ -136,6 +92,7 @@ ENV WITH_API=true \
LDAP_AUTHENTIFICATION=false \
LDAP_AUTHENTIFICATION_USERDN="" \
LDAP_AUTHENTIFICATION_PASSWORD="" \
LDAP_AUTHENTIFICATION_PASSWORD_FILE="" \
LDAP_LOG_ENABLED=false \
LDAP_BACKGROUND_SYNC=false \
LDAP_BACKGROUND_SYNC_INTERVAL="" \
@@ -201,38 +158,139 @@ ENV WITH_API=true \
ORACLE_OIM_ENABLED=false \
WAIT_SPINNER="" \
WRITABLE_PATH=/data \
S3=""
S3="" \
MAIL_SERVICE_PASSWORD_FILE="" \
MONGO_PASSWORD_FILE="" \
S3_SECRET_FILE=""
# Install node and application sources from build stage
RUN --mount=type=bind,from=downloads,source=node.tar.gz,target=node.tar.gz \
--mount=type=bind,from=build,source=/build,target=/build \
# Install NodeJS
tar xzf node.tar.gz --strip-components=1 --keep-old-files --no-same-owner && \
# Add the wekan user
useradd --uid 999 --user-group --system wekan && \
# Copy wekan bundle
cp -r /build/bundle /wekan && \
# Remove the web.browser.legacy platform
rm -r /wekan/programs/web.browser.legacy && \
# Change ownership of wekan directory
chown wekan:wekan -R /wekan && \
# Create the data directory
mkdir /data && \
# Change ownership of data directory
chown wekan:root -R /data
# NODE_OPTIONS="--max_old_space_size=4096"
#---------------------------------------------
# == at docker-compose.yml: AUTOLOGIN WITH OIDC/OAUTH2 ====
# https://github.com/wekan/wekan/wiki/autologin
#- OIDC_REDIRECTION_ENABLED=true
#---------------------------------------------------------------------
# Copy the app to the image
#COPY ${SRC_PATH} /home/wekan/app
# Install OS
RUN <<EOR
set -o xtrace
# Add non-root user wekan
useradd --user-group --system --home-dir /home/wekan wekan
# OS dependencies
apt-get update --assume-yes
apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS}
# Meteor installer doesn't work with the default tar binary, so using bsdtar while installing.
# https://github.com/coreos/bugs/issues/1095#issuecomment-350574389
cp $(which tar) $(which tar)~
ln -sf $(which bsdtar) $(which tar)
# Install NodeJS
cd /tmp
# Download nodejs
#wget "https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz"
wget "https://github.com/wekan/node-v14-esm/releases/download/v14.21.4/node-v14.21.4-linux-x64.tar.gz"
#wget "https://github.com/wekan/node-v14-esm/releases/download/${NODE_VERSION}/SHASUMS256.txt"
wget "https://github.com/wekan/node-v14-esm/releases/download/v14.21.4/SHASUMS256.txt"
# Verify nodejs authenticity
#grep "node-${NODE_VERSION}-${ARCHITECTURE}.tar.gz" "SHASUMS256.txt" | shasum -a 256 -c -
grep "node-v14.21.4-linux-x64.tar.gz" "SHASUMS256.txt" | shasum -a 256 -c -
rm -f "SHASUMS256.txt"
# Install Node
#tar xzf "node-$NODE_VERSION-$ARCHITECTURE.tar.gz" -C /usr/local --strip-components=1 --no-same-owner
tar xzf "node-v14.21.4-linux-x64.tar.gz" -C /usr/local --strip-components=1 --no-same-owner
#rm "node-$NODE_VERSION-$ARCHITECTURE.tar.gz" "SHASUMS256.txt"
rm "node-v14.21.4-linux-x64.tar.gz" "SHASUMS256.txt"
ln -s "/usr/local/bin/node" "/usr/local/bin/nodejs"
#mkdir -p "/opt/nodejs/lib/node_modules/fibers/.node-gyp" "/root/.node-gyp/${NODE_VERSION} /home/wekan/.config"
#mkdir -p "/opt/nodejs/lib/node_modules/fibers/.node-gyp" "/root/.node-gyp/v14.21.4 /home/wekan/.config"
# Install node dependencies
#npm install -g npm@${NPM_VERSION} --production
npm install -g npm@$6.14.17 --production
chown --recursive wekan:wekan /home/wekan/.config
# Install Meteor
cd /home/wekan
chown --recursive wekan:wekan /home/wekan
echo "Starting meteor ${METEOR_RELEASE} installation... \n"
#gosu wekan:wekan curl https://install.meteor.com/ | /bin/sh
# Specify Meteor version 2.14 to be compatible: https://github.com/wekan/wekan/pull/5816/files
#gosu wekan:wekan npm -g install meteor@2.14 --unsafe-perm
#mv /root/.meteor /home/wekan/
#chown --recursive wekan:wekan /home/wekan/.meteor
#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
# Build app (Production)
#cd /home/wekan/app
mkdir -p /home/wekan/app
cd /home/wekan/app
#mkdir -p /home/wekan/.npm
#chown --recursive wekan:wekan /home/wekan/.npm
#chmod u+w *.json
#gosu wekan:wekan meteor npm install --production
#gosu wekan:wekan /home/wekan/.meteor/meteor build --directory /home/wekan/app_build
#cd /home/wekan/app_build/bundle/programs/server/
#chmod u+w *.json
#gosu wekan:wekan meteor npm install --production
#cd node_modules/fibers
#node build.js
#cd ../..
# Remove legacy webbroser bundle, so that Wekan works also at Android Firefox, iOS Safari, etc.
#rm -rf /home/wekan/app_build/bundle/programs/web.browser.legacy
#mv /home/wekan/app_build/bundle /build
wget "https://github.com/wekan/wekan/releases/download/v7.99/wekan-7.99-amd64.zip"
unzip wekan-7.99-amd64.zip
rm wekan-7.99-amd64.zip
mv /home/wekan/app/bundle /build
# Put back the original tar
mv $(which tar)~ $(which tar)
# Cleanup
apt-get remove --purge --assume-yes ${BUILD_DEPS}
#npm uninstall -g api2html
apt-get autoremove --assume-yes
apt-get clean --assume-yes
rm -Rf /tmp/*
rm -Rf /var/lib/apt/lists/*
rm -Rf /var/cache/apt
rm -Rf /var/lib/apt/lists
rm -Rf /home/wekan/app_build
rm -Rf /home/wekan/app
rm -Rf /home/wekan/.meteor
mkdir /data
chown wekan --recursive /data
EOR
# Change to the wekan user
USER wekan
# Set the port to listen on
ENV PORT=8080
EXPOSE ${PORT}
EXPOSE $PORT
# Define the stop signal for node
STOPSIGNAL SIGINT
STOPSIGNAL SIGKILL
WORKDIR /home/wekan/app
# Declare a volume on /data
VOLUME /data
# Set startup command
CMD ["node", "/wekan/main.js"]
#---------------------------------------------------------------------
# https://github.com/wekan/wekan/issues/3585#issuecomment-1021522132
# Add more Node heap:
# NODE_OPTIONS="--max_old_space_size=4096"
# Add more stack:
# bash -c "ulimit -s 65500; exec node --stack-size=65500 main.js"
#---------------------------------------------------------------------
#
# CMD ["node", "/build/main.js"]
# CMD ["bash", "-c", "ulimit -s 65500; exec node --stack-size=65500 /build/main.js"]
# CMD ["bash", "-c", "ulimit -s 65500; exec node --stack-size=65500 --max-old-space-size=8192 /build/main.js"]
CMD ["bash", "-c", "ulimit -s 65500; exec node /build/main.js"]
+6 -1
View File
@@ -53,7 +53,12 @@ ENV QEMU_ARCHITECTURE=aarch64 \
WITH_API=true \
PORT=8080 \
ROOT_URL=http://localhost \
MONGO_URL=mongodb://127.0.0.1:27017/wekan
MONGO_URL=mongodb://127.0.0.1:27017/wekan \
LDAP_AUTHENTIFICATION_PASSWORD_FILE="" \
OAUTH2_SECRET_FILE="" \
MAIL_SERVICE_PASSWORD_FILE="" \
MONGO_PASSWORD_FILE="" \
S3_SECRET_FILE=""
# Copy qemu-static to image
COPY --from=builder qemu-${QEMU_ARCHITECTURE}-static /usr/bin
+6 -1
View File
@@ -56,7 +56,12 @@ ENV QEMU_ARCHITECTURE=s390x \
WITH_API=true \
PORT=8080 \
ROOT_URL=http://localhost \
MONGO_URL=mongodb://127.0.0.1:27017/wekan
MONGO_URL=mongodb://127.0.0.1:27017/wekan \
LDAP_AUTHENTIFICATION_PASSWORD_FILE="" \
OAUTH2_SECRET_FILE="" \
MAIL_SERVICE_PASSWORD_FILE="" \
MONGO_PASSWORD_FILE="" \
S3_SECRET_FILE=""
# Copy qemu-static to image
COPY --from=builder qemu-${QEMU_ARCHITECTURE}-static /usr/bin
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2024 The Wekan Team
Copyright (c) Lauri Ojansivu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+23 -26
View File
@@ -1,10 +1,8 @@
[Gitpod Ready-to-Code](https://gitpod.io/#https://github.com/wekan/wekan)
# WeKan ® - Open Source kanban
## Downloads
https://wekan.github.io / Install WeKan ® Server
https://wekan.fi/install/
## Docker Containers
@@ -16,7 +14,7 @@ docker-compose.yml at https://github.com/wekan/wekan/blob/main/docker-compose.ym
## Standards
- [WeKan and Standard for Public Code](https://wekan.github.io/standard-for-public-code/) assessment was made at 2023-11.
- [WeKan and Standard for Public Code](https://wekan.fi/standard-for-public-code/) assessment was made at 2023-11.
Currently Wekan meets 8 out of 16 criteria out of the box.
Some others could be met with small changes.
@@ -27,21 +25,19 @@ docker-compose.yml at https://github.com/wekan/wekan/blob/main/docker-compose.ym
- [Open Hub](https://www.openhub.net/p/wekan)
- [OSS Insight](https://ossinsight.io/analyze/wekan/wekan)
## [Translate WeKan ® at Transifex](https://app.transifex.com/wekan/)
## Translate WeKan ® at Transifex
Translations to non-English languages are accepted only at [Transifex](https://app.transifex.com/wekan/wekan) using webbrowser.
New English strings of new features can be added as PRs to master branch file wekan/imports/i18n/data/en.i18n.json .
## [WeKan ® feature requests and bugs](https://github.com/wekan/wekan/issues)
## WeKan ® feature requests and bugs
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
## Discussions
[Discussions][discussions] - WeKan Community GitHub Discussions, that are not [Feature Requests and Bugs](https://github.com/wekan/wekan/issues).
[WeKan IRC FAQ](https://github.com/wekan/wekan/wiki/IRC-FAQ)
[IRC](https://github.com/wekan/wekan/blob/main/docs/FAQ/IRC-FAQ.md)
## Docker: Latest tag has newest release
@@ -51,8 +47,8 @@ See bottom of https://github.com/wekan/wekan/issues/3874
## FAQ
**NOTE**:
- Please read the [FAQ](https://github.com/wekan/wekan/wiki/FAQ) first
- Please don't feed the [trolls](https://github.com/wekan/wekan/wiki/FAQ#why-am-i-called-a-troll) and [spammers](https://github.com/wekan/wekan/wiki/FAQ#why-am-i-called-a-spammer) that are mentioned in the FAQ :)
- Please read the [FAQ](https://github.com/wekan/wekan/blob/main/docs/FAQ/FAQ.md) first
- Please don't feed the [trolls](https://github.com/wekan/wekan/blob/main/docs/FAQ/FAQ.md#why-am-i-called-a-troll) and [spammers](https://github.com/wekan/wekan/blob/main/docs/FAQ/FAQ.md#why-am-i-called-a-spammer) that are mentioned in the FAQ :)
## About WeKan ®
@@ -72,14 +68,11 @@ that by providing one-click installation on various platforms.
- WeKan ® largest user has 30k users using WeKan ® in their company.
- WeKan ® has been [translated](https://app.transifex.com/wekan/) to about 105 languages.
- [Features][features]: WeKan ® has real-time user interface.
- [Platforms][platforms]: WeKan ® supports many platforms.
- [Platforms](https://wekan.fi/install/): WeKan ® supports many platforms.
WeKan ® is critical part of new platforms Wekan is currently being integrated to.
## 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), bundle for RasPi3 ARM and other CPUs where Node.js and MongoDB exists.
- 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/main/docker-compose.yml): 3 frontend servers,
each having 2 CPU and 2 wekan-app containers. One backend wekan-db server with many CPUs.
@@ -89,7 +82,7 @@ that by providing one-click installation on various platforms.
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/main/CHANGELOG.md).
- [Backups](https://github.com/wekan/wekan/wiki/Backup) of WeKan ® database once a day miminum.
- [Backups](https://github.com/wekan/wekan/blob/main/docs/Backup/Backup.md) 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.
@@ -102,14 +95,22 @@ that by providing one-click installation on various platforms.
- 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/main/CHANGELOG.md).
- [Please add Add new Feature Requests and Bug Reports immediately](https://github.com/wekan/wekan/issues).
- [Commercial Support](https://wekan.team/commercial-support/).
- [Commercial Support](https://wekan.fi/commercial-support/).
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.
## Getting Started with Development
The default branch uses [Meteor 2 with Node.js 14](https://wekan.fi/install/).
To contribute, [create a fork](https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Build-and-Create-Pull-Request.md#2-create-fork-of-httpsgithubcomwekanwekan-at-github-web-page) and run `./rebuild-wekan.sh` (or `./rebuild-wekan.bat` on Windows) as detailed [here](https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Build-and-Create-Pull-Request.md#3-select-option-1-to-install-dependencies-and-then-enter). Once you're ready, please test your code and [submit a pull request (PR)](https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Build-and-Create-Pull-Request.md#7-test).
Please refer to the [developer documentation](https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Developer-Documentation.md) for more information.
## Screenshot
[More screenshots at Features page](https://github.com/wekan/wekan/wiki/Features)
[More screenshots at Features page](https://github.com/wekan/wekan/tree/main/docs/Features)
[![Screenshot of WeKan ®][screenshot_wekan]][roadmap_wekan]
@@ -118,16 +119,12 @@ By working directly with WeKan ® you get the benefit of active maintenance and
WeKan ® is released under the very permissive [MIT license](LICENSE), and made
with [Meteor](https://www.meteor.com).
[platforms]: https://github.com/wekan/wekan/wiki/Platforms
[dev_docs]: https://github.com/wekan/wekan/wiki/Developer-Documentation
[screenshot_wekan]: https://wekan.github.io/wekan-dark-mode.png
[dev_docs]: https://github.com/wekan/wekan/blob/main/docs/DeveloperDocs/Developer-Documentation.md
[screenshot_wekan]: https://wekan.fi/wekan-dark-mode.png
[features]: https://github.com/wekan/wekan/wiki/Features
[roadmap_wekan]: https://boards.wekan.team/b/D2SzJKZDS4Z48yeQH/wekan-open-source-kanban-board-with-mit-license
[wekan_issues]: https://github.com/wekan/wekan/issues
[wekan_issues]: https://github.com/wekan/wekan/issues
[docker_image]: https://hub.docker.com/r/wekanteam/wekan/
[wekan_wiki]: https://github.com/wekan/wekan/wiki
[translate_wekan]: https://app.transifex.com/wekan/
[translate_wekan]: https://app.transifex.com/wekan/wekan/
[open_source]: https://en.wikipedia.org/wiki/Open-source_software
[free_software]: https://en.wikipedia.org/wiki/Free_software
[discussions]: https://github.com/wekan/wekan/discussions
+113
View File
@@ -0,0 +1,113 @@
# 🔐 WeKan — Login System Overview
This document provides a detailed overview of WeKan’s **login and authentication system**, covering client-side UI, server-side logic, external authentication methods, and potential upgrade paths.
---
## 🖥️ Login Web UI
WeKan's login interface is implemented using a combination of:
- `layouts.jade` – Login HTML structure
- `layouts.js` – Login logic and interactivity
- `layouts.css` – Styling and layout
📁 Source: [`client/components/main`](https://github.com/wekan/wekan/tree/main/client/components/main)
---
## ⚙️ Server-Side Authentication
Server-side login functionality is handled in:
- [`server/authentication.js`](https://github.com/wekan/wekan/blob/main/server/authentication.js)
Other related configurations:
- 🔧 Account config: [`config/accounts.js`](https://github.com/wekan/wekan/blob/main/config/accounts.js)
- 📨 Sign-up invitations: [`models/settings.js#L275`](https://github.com/wekan/wekan/blob/main/models/settings.js#L275)
- 👤 User creation logic: [`models/users.js#L1339`](https://github.com/wekan/wekan/blob/main/models/users.js#L1339)
---
## 👥 Meteor User Accounts
WeKan utilizes Meteor’s `accounts` system. Relevant resources:
- 📚 Meteor 2.x Accounts Docs: [v2-docs.meteor.com/api/accounts](https://v2-docs.meteor.com/api/accounts)
- 🔍 Meteor Packages:
- [`packages`](https://github.com/wekan/wekan/blob/main/.meteor/packages)
- [`versions`](https://github.com/wekan/wekan/blob/main/.meteor/versions)
- 📦 Meteor 2.14 core packages: [Meteor 2.14 packages](https://github.com/meteor/meteor/tree/release/METEOR%402.14/packages)
---
## 🔐 External Authentication (OIDC, LDAP, etc.)
WeKan supports external authentication methods via internal packages.
📁 See [`packages/`](https://github.com/wekan/wekan/tree/main/packages) for:
- OpenID Connect (OIDC)
- LDAP
- OAuth and other integrations
---
## 📦 NPM & AtmosphereJS Dependencies
- 🔗 `package.json`: [Dependencies list](https://github.com/wekan/wekan/blob/main/package.json)
- 🧩 WekanTeam scoped NPM packages: [@wekanteam on npm](https://www.npmjs.com/search?q=%40wekanteam)
- ☁️ AtmosphereJS Meteor packages: [atmospherejs.com](https://atmospherejs.com)
---
## 🚧 Meteor Version & Upgrade Notes
- 📌 Current Version: **Meteor 2.14**
- [`.meteor/release`](https://github.com/wekan/wekan/blob/main/.meteor/release)
- 🔧 Maintained with only **critical fixes** until ~Summer 2025
- 🚀 Migration to **Meteor 3** or a new framework is under consideration
📘 Meteor 3 API: [docs.meteor.com/api/accounts](https://docs.meteor.com/api/accounts)
---
## 🧪 Prototypes & Examples
### 🐘 PHP Prototype Sign-Up
Used in experimental versions:
- Step 1: [`sign-up1.php`](https://github.com/wekan/php/blob/main/page/sign-up1.php)
- Step 2: [`sign-up2.php`](https://github.com/wekan/php/blob/main/page/sign-up2.php)
- Main entry: [`index.php#L72-L83`](https://github.com/wekan/php/blob/main/public/index.php#L72-L83)
---
### 🎨 WeKan Studio Prototype
Sign-up logic in the **WeKan Studio** version:
- [`signUp.fmt`](https://github.com/wekan/wekanstudio/blob/main/srv/templates/login/signUp.fmt)
---
## 📎 Future Considerations
- Upgrading to **Meteor 3.x**
- Refactoring frontend logic to fix translation rendering order
- Exploring **simplified authentication systems** in future prototypes
---
## 🔗 Project Links
- 🔧 Main Repo: [github.com/wekan/wekan](https://github.com/wekan/wekan)
- 🌐 Website: [wekan.github.io](https://wekan.github.io)
- 📚 Documentation: [Wekan Wiki](https://github.com/wekan/wekan/wiki)
---
---
+5 -4
View File
@@ -1,11 +1,12 @@
About money, see [CONTRIBUTING.md](CONTRIBUTING.md)
Security is very important to us. If you discover any issue regarding security, please disclose
the information responsibly by sending an email to security@wekan.team and not by
creating a GitHub issue. We will respond swiftly to fix verifiable security issues.
the information responsibly by sending an email from Protonmail to security@wekan.fi
that is Protomail email address, or by using this PGP key
[security-at-wekan.fi.asc](security-at-wekan.fi.asc) to security@wekan.fi
and not by creating a GitHub issue. We will respond swiftly to fix verifiable security issues.
We thank you with a place at our hall of fame page, that is
at https://wekan.github.io/hall-of-fame
We thank you with a place at our hall of fame page, that is at https://wekan.fi/hall-of-fame
## How should reports be formatted?
+1 -1
View File
@@ -1,5 +1,5 @@
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
appVersion: "v7.78.0"
appVersion: "v7.99.0"
files:
userUploads:
- README.md
+14 -14
View File
@@ -1,16 +1,16 @@
.activity-title {
margin: 0 0.5em 0.8em;
margin: 0 0.7vw 1vh;
display: flex;
justify-content: space-between;
}
.reactions-popup .add-comment-reaction {
display: inline-block;
cursor: pointer;
border-radius: 5px;
font-size: 22px;
border-radius: 0.7vw;
font-size: clamp(18px, 4vw, 22px);
text-align: center;
line-height: 30px;
width: 40px;
line-height: 1.3;
width: 5vw;
}
.reactions-popup .add-comment-reaction:hover {
background-color: #b0c4de;
@@ -19,13 +19,13 @@
clear: both;
}
.activities .activity {
margin: 0.5px 0;
padding: 6px 0;
margin: 0.1vh 0;
padding: 0.8vh 0;
display: flex;
}
.activities .activity .member {
width: 32px;
height: 32px;
width: 4vw;
height: 4vw;
}
.activities .activity .activity-member {
font-weight: 700;
@@ -36,18 +36,18 @@
flex: 1;
align-self: center;
margin: 0;
margin-left: 3px;
margin-left: 0.4vw;
overflow: hidden;
word-break: break-word;
}
.activities .activity .activity-desc .activity-comment {
display: block;
border-radius: 3px;
border-radius: 0.4vw;
background: #fff;
text-decoration: none;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
margin-top: 5px;
padding: 5px;
box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.2);
margin-top: 0.7vh;
padding: 0.7vh 0.7vw;
}
.activities .activity .activity-desc .activity-checklist {
display: block;
+8 -11
View File
@@ -1,5 +1,6 @@
import { ReactiveCache } from '/imports/reactiveCache';
import DOMPurify from 'dompurify';
import { sanitizeHTML, sanitizeText } from '/imports/lib/secureDOMPurify';
import { TAPi18n } from '/imports/i18n';
const activitiesPerPage = 500;
@@ -216,15 +217,11 @@ BlazeComponent.extendComponent({
{
href: source.url,
},
DOMPurify.sanitize(source.system, {
ALLOW_UNKNOWN_PROTOCOLS: true,
}),
sanitizeHTML(source.system),
),
);
} else {
return DOMPurify.sanitize(source.system, {
ALLOW_UNKNOWN_PROTOCOLS: true,
});
return sanitizeHTML(source.system);
}
}
return null;
@@ -248,10 +245,10 @@ BlazeComponent.extendComponent({
href: `${attachment.link()}?download=true`,
target: '_blank',
},
DOMPurify.sanitize(attachment.name),
sanitizeText(attachment.name),
),
)) ||
DOMPurify.sanitize(this.currentData().activity.attachmentName)
sanitizeText(this.currentData().activity.attachmentName)
);
},
@@ -265,7 +262,7 @@ BlazeComponent.extendComponent({
Template.activity.helpers({
sanitize(value) {
return DOMPurify.sanitize(value, { ALLOW_UNKNOWN_PROTOCOLS: true });
return sanitizeHTML(value);
},
});
@@ -336,7 +333,7 @@ function createCardLink(card, board) {
href: card.originRelativeUrl(),
class: 'action-card',
},
DOMPurify.sanitize(text, { ALLOW_UNKNOWN_PROTOCOLS: true }),
sanitizeHTML(text),
),
)
);
@@ -353,7 +350,7 @@ function createBoardLink(board, list) {
href: board.originRelativeUrl(),
class: 'action-board',
},
DOMPurify.sanitize(text, { ALLOW_UNKNOWN_PROTOCOLS: true }),
sanitizeHTML(text),
),
)
);
+278 -1
View File
@@ -6,6 +6,27 @@
bottom: 0;
overflow-x: hidden;
overflow-y: hidden;
width: 100%;
min-width: 100%;
}
/* When zoom is 50% or lower, ensure full width like content */
.board-wrapper[style*="transform: scale(0.5)"] {
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
}
.board-wrapper[style*="transform: scale(0.4)"] {
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
}
.board-wrapper[style*="transform: scale(0.3)"] {
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
}
.board-wrapper .board-canvas {
position: absolute;
@@ -15,6 +36,219 @@
bottom: 0;
transition: margin 0.1s;
overflow-y: auto;
width: 100%;
min-width: 100%;
}
/* Ensure horizontal scrollbar is visible for high zoom levels */
.board-wrapper .board-canvas[style*="overflow-x: auto"] {
overflow-x: auto !important;
overflow-y: auto !important;
}
/* Style the scrollbar for better visibility */
.board-wrapper .board-canvas::-webkit-scrollbar {
height: 12px;
width: 12px;
}
.board-wrapper .board-canvas::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 6px;
}
.board-wrapper .board-canvas::-webkit-scrollbar-thumb {
background: #888;
border-radius: 6px;
}
.board-wrapper .board-canvas::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* Ensure content area can scroll horizontally for high zoom levels */
#content[style*="overflow-x: auto"] {
overflow-x: auto !important;
overflow-y: auto !important;
}
/* Style content area scrollbar */
#content::-webkit-scrollbar {
height: 12px;
width: 12px;
}
#content::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 6px;
}
#content::-webkit-scrollbar-thumb {
background: #888;
border-radius: 6px;
}
#content::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* Ensure scrollbars are always visible for high zoom levels */
#content[style*="overflow-x: auto"] {
position: relative;
}
#content[style*="overflow-x: auto"]::-webkit-scrollbar {
height: 12px;
width: 12px;
}
/* Force vertical scrollbar to always be visible */
#content[style*="overflow-y: auto"] {
overflow-y: scroll !important;
}
/* Mobile - make all text 2x bigger inside #content by default (icons stay same size) */
@media screen and (max-width: 800px),
screen and (max-device-width: 800px),
screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px),
screen and (max-width: 800px) and (orientation: portrait),
screen and (max-width: 800px) and (orientation: landscape) {
#content {
font-size: 2em !important; /* 2x bigger base font size for content area */
}
/* Make all text elements 2x bigger */
#content h1, #content h2, #content h3, #content h4, #content h5, #content h6,
#content p, #content span, #content div, #content a, #content button,
#content .minicard, #content .list-header-name, #content .board-header-btn,
#content .card-title, #content .card-details, #content .card-description,
#content .swimlane-header, #content .list-title, #content .card-text,
#content .member, #content .member-name, #content .member-initials,
#content .checklist-item, #content .checklist-title, #content .comment,
#content .activity, #content .activity-text, #content .activity-time,
#content .board-title, #content .board-description, #content .list-name,
#content .card-text, #content .card-title, #content .card-description,
#content .swimlane-title, #content .swimlane-description,
#content .board-header-title, #content .board-header-description,
#content .card-detail-title, #content .card-detail-description,
#content .list-header-title, #content .list-header-description,
#content .swimlane-header-title, #content .swimlane-header-description,
#content .minicard-title, #content .minicard-description,
#content .card-comment, #content .card-comment-text,
#content .checklist-item-text, #content .checklist-item-title,
#content .activity-item, #content .activity-item-text,
#content .board-member, #content .board-member-name,
#content .team-member, #content .team-member-name,
#content .org-member, #content .org-member-name,
#content .template-member, #content .template-member-name,
#content .user-name, #content .user-email, #content .user-role,
#content .setting-title, #content .setting-description,
#content .popup-title, #content .popup-description,
#content .modal-title, #content .modal-description,
#content .notification-title, #content .notification-text,
#content .announcement-title, #content .announcement-text,
#content .offline-warning-title, #content .offline-warning-text,
#content .error-title, #content .error-text,
#content .success-title, #content .success-text,
#content .info-title, #content .info-text,
#content .warning-title, #content .warning-text {
font-size: 1em !important; /* Use inherited 2x scaling */
}
/* Keep icons the same size (don't scale them) */
#content .fa, #content .icon, #content i {
font-size: 1em !important; /* Keep original icon size */
}
/* Reset specific icon sizes to prevent double scaling */
#content .fa-home, #content .fa-bars, #content .fa-search,
#content .fa-bell, #content .fa-user, #content .fa-cog,
#content .fa-plus, #content .fa-minus, #content .fa-edit,
#content .fa-trash, #content .fa-save, #content .fa-cancel,
#content .fa-arrow-left, #content .fa-arrow-right,
#content .fa-arrow-up, #content .fa-arrow-down,
#content .fa-check, #content .fa-times, #content .fa-close,
#content .fa-star, #content .fa-heart, #content .fa-thumbs-up,
#content .fa-thumbs-down, #content .fa-comment, #content .fa-reply,
#content .fa-share, #content .fa-download, #content .fa-upload,
#content .fa-copy, #content .fa-paste, #content .fa-cut,
#content .fa-undo, #content .fa-redo, #content .fa-refresh,
#content .fa-sync, #content .fa-spinner, #content .fa-loading,
#content .fa-info, #content .fa-question, #content .fa-exclamation,
#content .fa-warning, #content .fa-error, #content .fa-success,
#content .fa-check-circle, #content .fa-times-circle,
#content .fa-exclamation-circle, #content .fa-question-circle,
#content .fa-info-circle, #content .fa-warning-circle,
#content .fa-error-circle, #content .fa-success-circle {
font-size: 1em !important; /* Keep original icon size */
}
}
/* Fallback for iPhone devices using JavaScript detection */
.iphone-device #content {
font-size: 2em !important; /* 2x bigger base font size for content area */
}
.iphone-device #content h1, .iphone-device #content h2, .iphone-device #content h3, .iphone-device #content h4, .iphone-device #content h5, .iphone-device #content h6,
.iphone-device #content p, .iphone-device #content span, .iphone-device #content div, .iphone-device #content a, .iphone-device #content button,
.iphone-device #content .minicard, .iphone-device #content .list-header-name, .iphone-device #content .board-header-btn,
.iphone-device #content .card-title, .iphone-device #content .card-details, .iphone-device #content .card-description,
.iphone-device #content .swimlane-header, .iphone-device #content .list-title, .iphone-device #content .card-text,
.iphone-device #content .member, .iphone-device #content .member-name, .iphone-device #content .member-initials,
.iphone-device #content .checklist-item, .iphone-device #content .checklist-title, .iphone-device #content .comment,
.iphone-device #content .activity, .iphone-device #content .activity-text, .iphone-device #content .activity-time,
.iphone-device #content .board-title, .iphone-device #content .board-description, .iphone-device #content .list-name,
.iphone-device #content .card-text, .iphone-device #content .card-title, .iphone-device #content .card-description,
.iphone-device #content .swimlane-title, .iphone-device #content .swimlane-description,
.iphone-device #content .board-header-title, .iphone-device #content .board-header-description,
.iphone-device #content .card-detail-title, .iphone-device #content .card-detail-description,
.iphone-device #content .list-header-title, .iphone-device #content .list-header-description,
.iphone-device #content .swimlane-header-title, .iphone-device #content .swimlane-header-description,
.iphone-device #content .minicard-title, .iphone-device #content .minicard-description,
.iphone-device #content .card-comment, .iphone-device #content .card-comment-text,
.iphone-device #content .checklist-item-text, .iphone-device #content .checklist-item-title,
.iphone-device #content .activity-item, .iphone-device #content .activity-item-text,
.iphone-device #content .board-member, .iphone-device #content .board-member-name,
.iphone-device #content .team-member, .iphone-device #content .team-member-name,
.iphone-device #content .org-member, .iphone-device #content .org-member-name,
.iphone-device #content .template-member, .iphone-device #content .template-member-name,
.iphone-device #content .user-name, .iphone-device #content .user-email, .iphone-device #content .user-role,
.iphone-device #content .setting-title, .iphone-device #content .setting-description,
.iphone-device #content .popup-title, .iphone-device #content .popup-description,
.iphone-device #content .modal-title, .iphone-device #content .modal-description,
.iphone-device #content .notification-title, .iphone-device #content .notification-text,
.iphone-device #content .announcement-title, .iphone-device #content .announcement-text,
.iphone-device #content .offline-warning-title, .iphone-device #content .offline-warning-text,
.iphone-device #content .error-title, .iphone-device #content .error-text,
.iphone-device #content .success-title, .iphone-device #content .success-text,
.iphone-device #content .info-title, .iphone-device #content .info-text,
.iphone-device #content .warning-title, .iphone-device #content .warning-text {
font-size: 1em !important; /* Use inherited 2x scaling */
}
/* Keep icons the same size for iPhone devices */
.iphone-device #content .fa, .iphone-device #content .icon, .iphone-device #content i {
font-size: 1em !important; /* Keep original icon size */
}
/* Ensure scrollbars are positioned correctly */
#content[style*="overflow-x: auto"]::-webkit-scrollbar:vertical {
width: 12px;
}
#content[style*="overflow-x: auto"]::-webkit-scrollbar:horizontal {
height: 12px;
}
/* Force both scrollbars to always be visible for high zoom levels */
#content[style*="overflow-x: auto"][style*="overflow-y: auto"] {
overflow-x: scroll !important;
overflow-y: scroll !important;
}
/* Ensure the right scrollbar is always visible on the inner right edge */
#content[style*="overflow-y: auto"] {
scrollbar-gutter: stable;
}
.board-wrapper .board-canvas .board-overlay {
position: fixed;
@@ -33,15 +267,58 @@
.board-wrapper .board-canvas.is-dragging-active .minicard-wrapper.is-checked {
display: none;
}
/* Mobile view styles - applied when isMiniScreen is true (iPhone, etc.) */
.board-wrapper.mobile-view {
width: 100% !important;
min-width: 100% !important;
left: 0 !important;
right: 0 !important;
}
.board-wrapper.mobile-view .board-canvas {
width: 100% !important;
min-width: 100% !important;
left: 0 !important;
right: 0 !important;
}
.board-wrapper.mobile-view .board-canvas.mobile-view .swimlane {
border-bottom: 1px solid #ccc;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
overflow-x: hidden;
overflow-y: auto;
width: 100%;
min-width: 100%;
}
@media screen and (max-width: 800px) {
.board-wrapper {
width: 100% !important;
min-width: 100% !important;
left: 0 !important;
right: 0 !important;
}
.board-wrapper .board-canvas {
width: 100% !important;
min-width: 100% !important;
left: 0 !important;
right: 0 !important;
}
.board-wrapper .board-canvas .swimlane {
border-bottom: 1px solid #ccc;
display: flex;
flex-direction: column;
margin: 0;
padding: 0 0px 0px 0;
padding: 0;
overflow-x: hidden;
overflow-y: auto;
width: 100%;
min-width: 100%;
}
}
.calendar-event-green {
+3 -2
View File
@@ -16,13 +16,14 @@ template(name="boardBody")
if notDisplayThisBoard
| {{_ 'tableVisibilityMode-allowPrivateOnly'}}
else
.board-wrapper(class=currentBoard.colorClass)
.board-wrapper(class=currentBoard.colorClass class="{{#if isMiniScreen}}mobile-view{{/if}}")
.board-canvas.js-swimlanes(
class="{{#if hasSwimlanes}}dragscroll{{/if}}"
class="{{#if Sidebar.isOpen}}is-sibling-sidebar-open{{/if}}"
class="{{#if MultiSelection.isActive}}is-multiselection-active{{/if}}"
class="{{#if draggingActive.get}}is-dragging-active{{/if}}"
class="{{#unless isVerticalScrollbars}}no-scrollbars{{/unless}}")
class="{{#unless isVerticalScrollbars}}no-scrollbars{{/unless}}"
class="{{#if isMiniScreen}}mobile-view{{/if}}")
if showOverlay.get
.board-overlay
if currentBoard.isTemplatesBoard
+295 -1
View File
@@ -76,6 +76,188 @@ BlazeComponent.extendComponent({
}
},
onRendered() {
// Initialize user settings (zoom and mobile mode)
Utils.initializeUserSettings();
// Detect iPhone devices and add class for better CSS targeting
const isIPhone = /iPhone|iPod/.test(navigator.userAgent);
if (isIPhone) {
document.body.classList.add('iphone-device');
}
// Accessibility: Focus management for popups and menus
function focusFirstInteractive(container) {
if (!container) return;
// Find first focusable element
const focusable = container.querySelectorAll('button, [role="button"], a[href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
for (let i = 0; i < focusable.length; i++) {
if (!focusable[i].disabled && focusable[i].offsetParent !== null) {
focusable[i].focus();
break;
}
}
}
// Observe for new popups/menus and set focus
const popupObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1 && (node.classList.contains('popup') || node.classList.contains('modal') || node.classList.contains('menu'))) {
setTimeout(function() { focusFirstInteractive(node); }, 10);
}
});
});
});
popupObserver.observe(document.body, { childList: true, subtree: true });
// Remove tabindex from non-interactive elements (e.g., user abbreviations, labels)
document.querySelectorAll('.user-abbreviation, .user-label, .card-header-label, .edit-label, .private-label').forEach(function(el) {
if (el.hasAttribute('tabindex')) {
el.removeAttribute('tabindex');
}
});
/*
// Add a toggle button for keyboard shortcuts accessibility
if (!document.getElementById('wekan-shortcuts-toggle')) {
const toggleContainer = document.createElement('div');
toggleContainer.id = 'wekan-shortcuts-toggle';
toggleContainer.style.position = 'fixed';
toggleContainer.style.top = '10px';
toggleContainer.style.right = '10px';
toggleContainer.style.zIndex = '1000';
toggleContainer.style.background = '#fff';
toggleContainer.style.border = '2px solid #005fcc';
toggleContainer.style.borderRadius = '6px';
toggleContainer.style.padding = '8px 12px';
toggleContainer.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';
toggleContainer.style.fontSize = '16px';
toggleContainer.style.color = '#005fcc';
toggleContainer.setAttribute('role', 'region');
toggleContainer.setAttribute('aria-label', 'Keyboard Shortcuts Settings');
toggleContainer.innerHTML = `
<label for="shortcuts-toggle-checkbox" style="cursor:pointer;">
<input type="checkbox" id="shortcuts-toggle-checkbox" ${window.wekanShortcutsEnabled ? 'checked' : ''} style="margin-right:8px;" />
Enable keyboard shortcuts
</label>
`;
document.body.appendChild(toggleContainer);
const checkbox = document.getElementById('shortcuts-toggle-checkbox');
checkbox.addEventListener('change', function(e) {
window.toggleWekanShortcuts(e.target.checked);
});
}
*/
// Ensure toggle-buttons, color choices, reactions, renaming, and calendar controls are focusable and have ARIA roles
document.querySelectorAll('.js-toggle').forEach(function(el) {
el.setAttribute('tabindex', '0');
el.setAttribute('role', 'button');
// Short, descriptive label for favorite/star toggle
if (el.classList.contains('js-favorite-toggle')) {
el.setAttribute('aria-label', TAPi18n.__('favorite-toggle-label'));
} else {
el.setAttribute('aria-label', 'Toggle');
}
});
document.querySelectorAll('.js-color-choice').forEach(function(el) {
el.setAttribute('tabindex', '0');
el.setAttribute('role', 'button');
el.setAttribute('aria-label', 'Choose color');
});
document.querySelectorAll('.js-reaction').forEach(function(el) {
el.setAttribute('tabindex', '0');
el.setAttribute('role', 'button');
el.setAttribute('aria-label', 'React');
});
document.querySelectorAll('.js-rename-swimlane').forEach(function(el) {
el.setAttribute('tabindex', '0');
el.setAttribute('role', 'button');
el.setAttribute('aria-label', 'Rename swimlane');
});
document.querySelectorAll('.js-rename-list').forEach(function(el) {
el.setAttribute('tabindex', '0');
el.setAttribute('role', 'button');
el.setAttribute('aria-label', 'Rename list');
});
document.querySelectorAll('.fc-button').forEach(function(el) {
el.setAttribute('tabindex', '0');
el.setAttribute('role', 'button');
});
// Set the language attribute on the <html> element for accessibility
document.documentElement.lang = TAPi18n.getLanguage();
// Ensure the accessible name for the board view switcher matches the visible label "Swimlanes"
// This fixes WCAG 2.5.3: Label in Name
const swimlanesSwitcher = this.$('.js-board-view-swimlanes');
if (swimlanesSwitcher.length) {
swimlanesSwitcher.attr('aria-label', swimlanesSwitcher.text().trim() || 'Swimlanes');
}
// Add a highly visible focus indicator and improve contrast for interactive elements
if (!document.getElementById('wekan-accessible-focus-style')) {
const style = document.createElement('style');
style.id = 'wekan-accessible-focus-style';
style.innerHTML = `
/* Focus indicator */
button:focus, [role="button"]:focus, a:focus, input:focus, select:focus, textarea:focus, .dropdown-menu:focus, .js-board-view-swimlanes:focus, .js-add-card:focus {
outline: 3px solid #005fcc !important;
outline-offset: 2px !important;
}
/* Input borders */
input, textarea, select {
border: 2px solid #222 !important;
}
/* Plus icon for adding a new card */
.js-add-card {
color: #005fcc !important; /* dark blue for contrast */
cursor: pointer;
outline: none;
}
.js-add-card[tabindex] {
outline: none;
}
/* Hamburger menu */
.fa-bars, .icon-hamburger {
color: #222 !important;
}
/* Grey icons in card detail header */
.card-detail-header .fa, .card-detail-header .icon {
color: #444 !important;
}
/* Grey operating elements in card detail */
.card-detail .fa, .card-detail .icon {
color: #444 !important;
}
/* Blue bar in checklists */
.checklist-progress-bar {
background-color: #005fcc !important;
}
/* Green checkmark in checklists */
.checklist .fa-check {
color: #007a33 !important;
}
/* X-Button and arrow button in menus */
.close, .fa-arrow-left, .icon-arrow-left {
color: #005fcc !important;
}
/* Cross icon to move boards */
.js-move-board {
color: #005fcc !important;
}
/* Current date background */
.current-date {
background-color: #005fcc !important;
color: #fff !important;
}
`;
document.head.appendChild(style);
}
// Ensure plus/add elements are focusable and have ARIA roles
document.querySelectorAll('.js-add-card').forEach(function(el) {
el.setAttribute('tabindex', '0');
el.setAttribute('role', 'button');
el.setAttribute('aria-label', 'Add new card');
});
const boardComponent = this;
const $swimlanesDom = boardComponent.$('.js-swimlanes');
@@ -326,8 +508,109 @@ BlazeComponent.extendComponent({
},
}).register('boardBody');
// Accessibility: Allow users to enable/disable keyboard shortcuts
window.wekanShortcutsEnabled = true;
window.toggleWekanShortcuts = function(enabled) {
window.wekanShortcutsEnabled = !!enabled;
};
// Example: Wrap your character key shortcut handler like this
document.addEventListener('keydown', function(e) {
// Example: "W" key shortcut (replace with your actual shortcut logic)
if (!window.wekanShortcutsEnabled) return;
if (e.key === 'w' || e.key === 'W') {
// ...existing shortcut logic...
// e.g. open swimlanes view, etc.
}
});
// Keyboard accessibility for card actions (favorite, archive, duplicate, etc.)
document.addEventListener('keydown', function(e) {
if (!window.wekanShortcutsEnabled) return;
// Only proceed if focus is on a card action element
const active = document.activeElement;
if (active && active.classList.contains('js-card-action')) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
active.click();
}
// Move card up/down with arrow keys
if (e.key === 'ArrowUp') {
e.preventDefault();
if (active.dataset.cardId) {
Meteor.call('moveCardUp', active.dataset.cardId);
}
}
if (e.key === 'ArrowDown') {
e.preventDefault();
if (active.dataset.cardId) {
Meteor.call('moveCardDown', active.dataset.cardId);
}
}
}
// Make plus/add elements keyboard accessible
if (active && active.classList.contains('js-add-card')) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
active.click();
}
}
// Keyboard move for cards (alternative to drag & drop)
if (active && active.classList.contains('js-move-card')) {
if (e.key === 'ArrowUp') {
e.preventDefault();
if (active.dataset.cardId) {
Meteor.call('moveCardUp', active.dataset.cardId);
}
}
if (e.key === 'ArrowDown') {
e.preventDefault();
if (active.dataset.cardId) {
Meteor.call('moveCardDown', active.dataset.cardId);
}
}
}
// Ensure move card buttons are focusable and have ARIA roles
document.querySelectorAll('.js-move-card').forEach(function(el) {
el.setAttribute('tabindex', '0');
el.setAttribute('role', 'button');
el.setAttribute('aria-label', 'Move card');
});
// Make toggle-buttons, color choices, reactions, and X-buttons keyboard accessible
if (active && (active.classList.contains('js-toggle') || active.classList.contains('js-color-choice') || active.classList.contains('js-reaction') || active.classList.contains('close'))) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
active.click();
}
}
// Prevent scripts from removing focus when received
if (active) {
active.addEventListener('focus', function(e) {
// Do not remove focus
// No-op: This prevents F55 failure
}, { once: true });
}
// Make swimlane/list renaming keyboard accessible
if (active && (active.classList.contains('js-rename-swimlane') || active.classList.contains('js-rename-list'))) {
if (e.key === 'Enter') {
e.preventDefault();
active.click();
}
}
// Calendar navigation buttons
if (active && active.classList.contains('fc-button')) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
active.click();
}
}
});
BlazeComponent.extendComponent({
onRendered() {
// Set the language attribute on the <html> element for accessibility
document.documentElement.lang = TAPi18n.getLanguage();
this.autorun(function () {
$('#calendar-view').fullCalendar('refetchEvents');
});
@@ -341,11 +624,19 @@ BlazeComponent.extendComponent({
timezone: 'local',
weekNumbers: true,
header: {
left: 'title today prev,next',
left: 'title today prev,next',
center:
'agendaDay,listDay,timelineDay agendaWeek,listWeek,timelineWeek month,listMonth',
right: '',
},
buttonText: {
prev: TAPi18n.__('calendar-previous-month-label'), // e.g. "Previous month"
next: TAPi18n.__('calendar-next-month-label'), // e.g. "Next month"
},
ariaLabel: {
prev: TAPi18n.__('calendar-previous-month-label'),
next: TAPi18n.__('calendar-next-month-label'),
},
// height: 'parent', nope, doesn't work as the parent might be small
height: 'auto',
/* TODO: lists as resources: https://fullcalendar.io/docs/vertical-resource-view */
@@ -476,6 +767,9 @@ BlazeComponent.extendComponent({
document.body.appendChild(modalElement);
const openModal = function() {
modalElement.style.display = 'flex';
// Set focus to the input field for better keyboard accessibility
const input = modalElement.querySelector('#card-title-input');
if (input) input.focus();
};
const closeModal = function() {
modalElement.style.display = 'none';
+37 -23
View File
@@ -1,4 +1,4 @@
/* ===============
/* ===============
THEME - NEPHRITIS
=================*/
@@ -99,7 +99,7 @@ THEME - NEPHRITIS
/* === END NEPHRITIS THEME === */
/* ===============
/* ===============
THEME - Pomegranate
=================*/
@@ -200,7 +200,7 @@ THEME - Pomegranate
/* === END Pomegranate THEME === */
/* ===============
/* ===============
THEME - Belize
=================*/
@@ -301,7 +301,7 @@ THEME - Belize
/* === END Belize THEME === */
/* ===============
/* ===============
THEME - Wisteria
=================*/
@@ -402,7 +402,7 @@ THEME - Wisteria
/* === END Wisteria THEME === */
/* ===============
/* ===============
THEME - Midnight
=================*/
@@ -503,7 +503,7 @@ THEME - Midnight
/* === END Midnight THEME === */
/* ===============
/* ===============
THEME - Pumpkin
=================*/
@@ -604,7 +604,7 @@ THEME - Pumpkin
/* === END Pumpkin THEME === */
/* ===============
/* ===============
THEME - Moderate Pink
=================*/
@@ -705,7 +705,7 @@ THEME - Moderate Pink
/* === END Moderatepink THEME === */
/* ===============
/* ===============
THEME - Strong Cyan
=================*/
@@ -806,7 +806,7 @@ THEME - Strong Cyan
/* === END Strongcyan THEME === */
/* ===============
/* ===============
THEME - Lime Green
=================*/
@@ -907,7 +907,7 @@ THEME - Lime Green
/* === END Limegreen THEME === */
/* ===============
/* ===============
THEME - Dark
=================*/
@@ -1111,7 +1111,7 @@ THEME - Dark
/* === END Dark THEME === */
/* ===============
/* ===============
THEME - Relax
=================*/
@@ -1241,7 +1241,7 @@ THEME - Relax
/* === END Relax THEME === */
/* ===============
/* ===============
THEME - Corteza
=================*/
@@ -1342,7 +1342,7 @@ THEME - Corteza
/* === END Corteza THEME === */
/* ===============
/* ===============
THEME - Clear Blue
=================*/
@@ -1609,7 +1609,7 @@ THEME - Clear Blue
/* === END Clearblue THEME === */
/* ===============
/* ===============
THEME - Natural
=================*/
@@ -1719,7 +1719,7 @@ THEME - Natural
/* === END Natural THEME === */
/* ===============
/* ===============
THEME - Modern
=================*/
@@ -2006,7 +2006,7 @@ THEME - Modern
/* === END Modern THEME === */
/* ===============
/* ===============
THEME - Modern Dark
=================*/
@@ -2496,7 +2496,7 @@ THEME - Modern Dark
/* === END ModernDark THEME === */
/* ===============
/* ===============
THEME - Exodark
=================*/
@@ -2544,8 +2544,8 @@ THEME - Exodark
background: #1b1b1b;
}
.board-color-exodark .materialCheckBox.is-checked {
border-bottom: 2px solid #222;
border-right: 2px solid #222;
border-bottom: 2px solid #dbdbdb!important;/*Fix contrast of checkbox*/
border-right: 2px solid #dbdbdb!important;
}
.board-color-exodark .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e9e9e9;
@@ -2744,7 +2744,7 @@ THEME - Exodark
/* === END Exodark THEME === */
/* ===============
/* ===============
THEME - Clean Dark
=================*/
@@ -2811,6 +2811,7 @@ THEME - Clean Dark
.board-color-cleandark .card-details {
background: #23232B;
scrollbar-color: #ffffff #2e2e39;
border-radius: 20px;
box-shadow: none;
}
@@ -3179,10 +3180,17 @@ THEME - Clean Dark
margin-top: 8px;
}
/* ===============
.board-color-cleandark.background-box {
background-color:#23232B;
} /*Fixes contrast issues with background box in theme selection list*/
/* ===============
THEME - Clean Light
=================*/
/* Please note Clean Light theme elements also contain references to some cleandark theme elements so if unable to find code you're looking for under CleanDark it might be here. This should probably be cleaned up*/
.board-color-cleanlight.background-box {
background-color:#e0e0e0;
color:#010101!important;
} /*Fixes issues with text colour/background box being similar no contrast */
.board-color-cleanlight {
background: #E0E0E0;
@@ -3314,7 +3322,13 @@ THEME - Clean Light
.board-color-cleanlight .list .list-header .list-header-menu .js-collapse,
.board-color-cleandark .list .list-header .list-header-menu .js-collapse {
display: none;
/* Make collapse button visible in Clean Light / Clean Dark themes.
Previously this was hidden which caused the missing Collapse button
when using these themes. Use inline-block so it lines up with other
header controls. */
display: inline-block;
vertical-align: middle;
color: inherit;
}
.board-color-cleanlight .list-header-add,
@@ -3485,7 +3499,7 @@ THEME - Clean Light
.board-color-cleandark .card-details-header {
background: #2E2E39 !important;
color: rgba(255, 255, 255, 1);
color: #FFF !important;
}
.board-color-cleanlight .card-details-header .card-details-title,
+923 -7
View File
@@ -1,5 +1,5 @@
.integration-form {
padding: 5px;
padding: 0.7vh 0.7vw;
border-bottom: 1px solid #ccc;
}
.flex,
@@ -12,12 +12,928 @@
display: flex;
}
.option {
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-border-radius: 0.4vw;
border-radius: 0.4vw;
background: #fff;
text-decoration: none;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2);
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
margin-top: 5px;
padding: 5px;
-webkit-box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.2);
box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.2);
margin-top: 0.7vh;
padding: 0.7vh 0.7vw;
}
/* Zoom and Mobile Mode Controls */
.board-header-btns.center {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
}
.zoom-controls {
display: flex;
align-items: center;
gap: 0.5vw;
background: rgba(255, 255, 255, 0.9);
padding: 0.5vh 1vw;
border-radius: 0.5vw;
box-shadow: 0 0.2vh 0.5vh rgba(0,0,0,0.1);
}
.zoom-controls .board-header-btn {
padding: 0.5vh 0.8vw !important;
border-radius: 0.3vw !important;
background: #fff !important;
border: 1px solid #000 !important;
transition: all 0.2s ease !important;
color: #000 !important;
height: auto !important;
line-height: normal !important;
margin: 0 !important;
float: none !important;
overflow: visible !important;
}
.zoom-controls .board-header-btn i {
color: #000 !important;
float: none !important;
display: inline !important;
line-height: normal !important;
margin: 0 !important;
}
.zoom-controls .board-header-btn:hover {
background: #000 !important;
border-color: #000 !important;
color: #fff !important;
}
.zoom-controls .board-header-btn:hover i {
color: #fff !important;
}
.zoom-controls .board-header-btn.is-active {
background: #0079bf;
color: white;
border-color: #005a8a;
}
.zoom-controls .board-header-btn.is-active i {
color: white;
}
.zoom-level {
font-weight: bold;
color: #333;
min-width: 3vw;
text-align: center;
font-size: clamp(12px, 2vw, 14px);
cursor: pointer;
padding: 0.3vh 0.5vw;
border-radius: 0.3vw;
transition: all 0.2s ease;
}
.zoom-level:hover {
background: #f0f0f0;
color: #000;
}
/* Mobile Mode Styles */
.mobile-mode .board-wrapper {
width: 100%;
height: 100%;
}
.mobile-mode .board-canvas {
height: 100%;
}
.mobile-mode .minicard {
font-size: clamp(16px, 4vw, 20px);
padding: 1.2vh 1.5vw 0.5vh;
min-height: 3vh;
}
.mobile-mode .list-header-name {
font-size: clamp(18px, 4.5vw, 24px);
}
.mobile-mode .board-header-btn {
padding: 1vh 1.5vw;
font-size: clamp(14px, 3.5vw, 18px);
}
.mobile-mode .zoom-controls {
padding: 1vh 1.5vw;
gap: 1vw;
}
.mobile-mode .zoom-controls .board-header-btn {
padding: 1vh 1.5vw !important;
font-size: clamp(14px, 3.5vw, 18px) !important;
background: #fff !important;
border: 1px solid #000 !important;
color: #000 !important;
height: auto !important;
line-height: normal !important;
margin: 0 !important;
float: none !important;
overflow: visible !important;
}
.mobile-mode .zoom-controls .board-header-btn i {
color: #000 !important;
float: none !important;
display: inline !important;
line-height: normal !important;
margin: 0 !important;
}
.mobile-mode .zoom-controls .board-header-btn:hover {
background: #000 !important;
border-color: #000 !important;
color: #fff !important;
}
.mobile-mode .zoom-controls .board-header-btn:hover i {
color: #fff !important;
}
.mobile-mode .zoom-level {
font-size: clamp(14px, 3.5vw, 18px);
min-width: 4vw;
}
/* Comprehensive Mobile Mode Styles - Works on all screen sizes */
.mobile-mode .board-wrapper {
width: 100% !important;
height: 100% !important;
transform: none !important;
transform-origin: initial !important;
max-width: 100% !important;
}
.mobile-mode .board-canvas {
height: 100% !important;
overflow-x: hidden !important;
overflow-y: auto !important;
width: 100% !important;
max-width: 100% !important;
}
.mobile-mode .swimlane {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
margin-bottom: 2rem !important;
display: block !important;
float: none !important;
}
.mobile-mode .swimlane-header {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
font-size: clamp(18px, 2.5vw, 32px) !important;
padding: 1rem !important;
margin-bottom: 1rem !important;
display: block !important;
}
.mobile-mode .list {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
display: block !important;
float: none !important;
margin-bottom: 2rem !important;
border-left: none !important;
border-bottom: 2px solid #ccc !important;
clear: both !important;
}
.mobile-mode .list-header {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
padding: 1rem !important;
font-size: clamp(18px, 2.5vw, 32px) !important;
display: grid !important;
grid-template-columns: 30px 1fr auto auto !important;
gap: 10px !important;
align-items: center !important;
position: relative !important;
}
.mobile-mode .list-header .list-header-name {
font-size: clamp(18px, 2.5vw, 32px) !important;
font-weight: bold !important;
grid-row: 1 !important;
grid-column: 2 !important;
align-self: end !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .list-header .cardCount {
font-size: clamp(14px, 2vw, 24px) !important;
grid-row: 2 !important;
grid-column: 2 !important;
align-self: start !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .list-header .list-header-menu-icon {
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
grid-row: 1/3 !important;
grid-column: 3 !important;
padding: 14px !important;
font-size: clamp(24px, 3vw, 48px) !important;
text-align: center !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .list-header .list-header-handle {
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
grid-row: 1/3 !important;
grid-column: 4 !important;
padding: 14px !important;
font-size: clamp(28px, 3.5vw, 56px) !important;
text-align: center !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .list-body {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
padding: 1rem !important;
display: block !important;
}
.mobile-mode .minicard {
width: 100% !important;
min-width: 100% !important;
max-width: 100% !important;
font-size: clamp(16px, 2vw, 24px) !important;
padding: 1.2vh 1.5vw 0.5vh !important;
min-height: 3vh !important;
margin-bottom: 0.5rem !important;
display: block !important;
float: none !important;
}
.mobile-mode .minicard .minicard-title {
font-size: clamp(16px, 2vw, 24px) !important;
font-weight: bold !important;
}
.mobile-mode .minicard .minicard-members {
font-size: clamp(12px, 1.5vw, 18px) !important;
}
.mobile-mode .minicard .minicard-lists {
font-size: clamp(12px, 1.5vw, 18px) !important;
}
/* Desktop Mode Styles */
.desktop-mode .board-wrapper {
width: auto !important;
height: auto !important;
}
.desktop-mode .swimlane {
width: auto !important;
min-width: auto !important;
}
.desktop-mode .list {
width: auto !important;
min-width: auto !important;
display: flex !important;
float: left !important;
margin-bottom: 0 !important;
border-left: 1px solid #ccc !important;
border-bottom: none !important;
}
.desktop-mode .list-header {
width: auto !important;
min-width: auto !important;
padding: 2.5vh 1.5vw 0.5vh !important;
font-size: clamp(14px, 3vw, 18px) !important;
display: block !important;
}
.desktop-mode .list-header .list-header-name {
font-size: clamp(14px, 3vw, 18px) !important;
display: inline !important;
grid-row: auto !important;
grid-column: auto !important;
align-self: auto !important;
}
.desktop-mode .list-header .cardCount {
font-size: 12px !important;
grid-row: auto !important;
grid-column: auto !important;
align-self: auto !important;
}
.desktop-mode .list-header .list-header-menu-icon {
position: absolute !important;
right: 60px !important;
top: 50% !important;
transform: translateY(-50%) !important;
grid-row: auto !important;
grid-column: auto !important;
padding: 14px !important;
font-size: 40px !important;
}
.desktop-mode .list-header .list-header-handle {
position: absolute !important;
right: 10px !important;
top: 50% !important;
transform: translateY(-50%) !important;
grid-row: auto !important;
grid-column: auto !important;
padding: 7px !important;
font-size: clamp(16px, 3vw, 20px) !important;
}
.desktop-mode .list-body {
width: auto !important;
min-width: auto !important;
padding: 5px 11px !important;
}
.desktop-mode .minicard {
width: auto !important;
min-width: auto !important;
font-size: clamp(12px, 2.5vw, 16px) !important;
padding: 0.5vh 0.8vw !important;
min-height: auto !important;
margin-bottom: 9px !important;
}
.desktop-mode .minicard .minicard-title {
font-size: clamp(12px, 2.5vw, 16px) !important;
}
.desktop-mode .minicard .minicard-members {
font-size: 10px !important;
}
.desktop-mode .minicard .minicard-lists {
font-size: 10px !important;
}
/* Additional Mobile Mode Styles for Other Elements - Works on all screen sizes */
.mobile-mode .swimlane-header .swimlane-title {
font-size: clamp(18px, 2.5vw, 32px) !important;
font-weight: bold !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .swimlane-header .swimlane-description {
font-size: clamp(14px, 2vw, 24px) !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .board-header {
font-size: clamp(18px, 2.5vw, 32px) !important;
padding: 1rem !important;
width: 100% !important;
max-width: 100% !important;
}
.mobile-mode .board-header .board-header-title {
font-size: clamp(18px, 2.5vw, 32px) !important;
font-weight: bold !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .board-header .board-header-description {
font-size: clamp(14px, 2vw, 24px) !important;
display: block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .board-header .board-header-btn {
font-size: clamp(14px, 2vw, 24px) !important;
padding: 1vh 1.5vw !important;
display: inline-block !important;
visibility: visible !important;
opacity: 1 !important;
}
.mobile-mode .board-header .board-header-btn i {
font-size: clamp(14px, 2vw, 24px) !important;
display: inline !important;
visibility: visible !important;
opacity: 1 !important;
}
/* Force mobile mode visibility on all screen sizes */
.mobile-mode .list-header .fa-angle-right,
.mobile-mode .list-header .fa-arrows {
display: block !important;
visibility: visible !important;
opacity: 1 !important;
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
}
.mobile-mode .list-header .fa-angle-right {
grid-row: 1/3 !important;
grid-column: 3 !important;
padding: 14px !important;
font-size: clamp(24px, 3vw, 48px) !important;
text-align: center !important;
}
.mobile-mode .list-header .fa-arrows {
grid-row: 1/3 !important;
grid-column: 4 !important;
padding: 14px !important;
font-size: clamp(28px, 3.5vw, 56px) !important;
text-align: center !important;
}
/* Override any media queries that might hide elements in mobile mode */
.mobile-mode * {
max-width: none !important;
}
.mobile-mode .list,
.mobile-mode .swimlane,
.mobile-mode .board-wrapper,
.mobile-mode .board-canvas {
max-width: 100% !important;
width: 100% !important;
min-width: 100% !important;
}
/* Force mobile mode list styling on all screen sizes - override desktop CSS */
.mobile-mode .board-canvas {
display: block !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
overflow-x: hidden !important;
overflow-y: auto !important;
}
.mobile-mode .swimlane {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
}
.mobile-mode .swimlane .swimlane-header {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 0 1rem 0 !important;
padding: 1rem !important;
font-size: clamp(18px, 2.5vw, 32px) !important;
font-weight: bold !important;
border-bottom: 2px solid #ccc !important;
}
.mobile-mode .swimlane .lists {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
}
.mobile-mode .list {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
flex-basis: auto !important;
flex-grow: 0 !important;
flex-shrink: 0 !important;
position: static !important;
left: auto !important;
right: auto !important;
top: auto !important;
bottom: auto !important;
transform: none !important;
}
.mobile-mode .list:first-child {
margin-left: 0 !important;
margin-top: 0 !important;
}
.mobile-mode .list:last-child {
margin-right: 0 !important;
margin-bottom: 0 !important;
}
.mobile-mode .list.ui-sortable-helper {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
height: auto !important;
min-height: 60px !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
}
.mobile-mode .list.placeholder {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
height: auto !important;
min-height: 60px !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
}
/* Override any existing responsive CSS that might interfere with mobile mode */
.mobile-mode .board-canvas .swimlane .lists {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
overflow: visible !important;
}
.mobile-mode .board-canvas .swimlane .lists .list {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
flex-basis: auto !important;
flex-grow: 0 !important;
flex-shrink: 0 !important;
position: static !important;
left: auto !important;
right: auto !important;
top: auto !important;
bottom: auto !important;
transform: none !important;
}
/* Force mobile mode to override any media query styles */
@media screen and (min-width: 801px) {
.mobile-mode .board-canvas {
display: block !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
overflow-x: hidden !important;
overflow-y: auto !important;
}
.mobile-mode .swimlane {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
}
.mobile-mode .swimlane .lists {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 !important;
padding: 0 !important;
flex-direction: column !important;
flex-wrap: nowrap !important;
align-items: stretch !important;
justify-content: flex-start !important;
}
.mobile-mode .list {
display: block !important;
width: 100% !important;
max-width: 100% !important;
min-width: 100% !important;
margin: 0 0 2rem 0 !important;
padding: 0 !important;
float: none !important;
clear: both !important;
border-left: none !important;
border-right: none !important;
border-top: none !important;
border-bottom: 2px solid #ccc !important;
flex: none !important;
flex-basis: auto !important;
flex-grow: 0 !important;
flex-shrink: 0 !important;
position: static !important;
left: auto !important;
right: auto !important;
top: auto !important;
bottom: auto !important;
transform: none !important;
}
}
/* Hide desktop-only elements in mobile mode (like mobile media queries do) */
.mobile-mode .board-header-btn i.fa + span {
display: none !important;
}
.mobile-mode .board-header-btn span {
display: none !important;
}
.mobile-mode .board-header-btn .fa + span {
display: none !important;
}
.mobile-mode .board-header-btn .fa + .board-header-btn-text {
display: none !important;
}
.mobile-mode .board-header-btn .fa + .board-header-btn-label {
display: none !important;
}
/* Show only icons in mobile mode */
.mobile-mode .board-header-btn {
width: auto !important;
min-width: auto !important;
padding: 8px !important;
text-align: center !important;
}
.mobile-mode .board-header-btn i {
display: inline-block !important;
margin: 0 !important;
}
/* Hide desktop-specific elements that shouldn't show in mobile mode */
.mobile-mode .desktop-only,
.mobile-mode .board-header .desktop-only {
display: none !important;
}
.mobile-mode .board-header .board-header-btn.desktop-only {
display: none !important;
}
/* Hide desktop-specific board header buttons in mobile mode */
.mobile-mode .board-header-btns.left {
display: none !important;
}
.mobile-mode .board-header-btns.center {
display: none !important;
}
/* Show only the right section buttons in mobile mode, but hide text labels */
.mobile-mode .board-header-btns.right {
display: block !important;
}
.mobile-mode .board-header-btns.right .board-header-btn span {
display: none !important;
}
.mobile-mode .board-header-btns.right .board-header-btn .fa + span {
display: none !important;
}
.mobile-mode .board-header-btns.right .board-header-btn .fa + .board-header-btn-text {
display: none !important;
}
.mobile-mode .board-header-btns.right .board-header-btn .fa + .board-header-btn-label {
display: none !important;
}
/* Hide specific desktop-only buttons that shouldn't show in mobile mode */
.mobile-mode .board-header-btn.js-star-board span,
.mobile-mode .board-header-btn.js-change-visibility span,
.mobile-mode .board-header-btn.js-watch-board span,
.mobile-mode .board-header-btn.js-sort-cards span {
display: none !important;
}
/* Show only icons for mobile mode buttons */
.mobile-mode .board-header-btns.right .board-header-btn {
width: auto !important;
min-width: auto !important;
padding: 8px !important;
text-align: center !important;
margin: 0 2px !important;
}
.mobile-mode .board-header-btns.right .board-header-btn i {
display: inline-block !important;
margin: 0 !important;
}
/* Ensure mobile mode looks like small screen mobile view */
.mobile-mode .board-header {
height: 40px !important;
}
.mobile-mode .board-header .board-header-btns {
margin-top: 0px !important;
}
.mobile-mode .board-header .board-header-btn {
height: 32px !important;
line-height: 32px !important;
font-size: 15px !important;
}
.mobile-mode .board-header .board-header-btn i.fa {
line-height: 32px !important;
}
/* Copy mobile media query styles to mobile mode for consistent appearance */
.mobile-mode .board-header {
height: 40px !important;
padding: 0 !important;
margin: 0 !important;
}
.mobile-mode .board-header .board-header-btns {
margin-top: 0px !important;
height: 40px !important;
display: flex !important;
align-items: center !important;
justify-content: flex-end !important;
}
.mobile-mode .board-header .board-header-btn {
height: 32px !important;
line-height: 32px !important;
font-size: 15px !important;
margin: 0 2px !important;
padding: 4px 8px !important;
border-radius: 4px !important;
background: rgba(255, 255, 255, 0.1) !important;
border: 1px solid rgba(255, 255, 255, 0.2) !important;
color: #fff !important;
text-decoration: none !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
min-width: 32px !important;
width: auto !important;
}
.mobile-mode .board-header .board-header-btn:hover {
background: rgba(255, 255, 255, 0.2) !important;
border-color: rgba(255, 255, 255, 0.3) !important;
}
.mobile-mode .board-header .board-header-btn i.fa {
line-height: 32px !important;
font-size: 15px !important;
margin: 0 !important;
padding: 0 !important;
}
.mobile-mode .board-header .board-header-btn i.fa + span {
display: none !important;
}
.mobile-mode .board-header .board-header-btn span {
display: none !important;
}
/* Hide the board title in mobile mode to match mobile view */
.mobile-mode .header-board-menu {
display: none !important;
}
/* Ensure the board header takes full width in mobile mode */
.mobile-mode .board-header {
width: 100% !important;
max-width: 100% !important;
display: flex !important;
align-items: center !important;
justify-content: space-between !important;
padding: 0 10px !important;
}
/* Additional Desktop Mode Styles for Other Elements */
.desktop-mode .swimlane-header .swimlane-title {
font-size: clamp(14px, 3vw, 18px) !important;
}
.desktop-mode .swimlane-header .swimlane-description {
font-size: 12px !important;
}
.desktop-mode .board-header {
font-size: clamp(14px, 3vw, 18px) !important;
padding: 2.5vh 1.5vw 0.5vh !important;
}
.desktop-mode .board-header .board-header-title {
font-size: clamp(14px, 3vw, 18px) !important;
}
.desktop-mode .board-header .board-header-description {
font-size: 12px !important;
}
.desktop-mode .board-header .board-header-btn {
font-size: clamp(12px, 2.5vw, 16px) !important;
padding: 0.5vh 0.8vw !important;
}
.desktop-mode .board-header .board-header-btn i {
font-size: clamp(12px, 2.5vw, 16px) !important;
}
+3 -13
View File
@@ -17,7 +17,7 @@ template(name="boardHeaderBar")
i.fa.fa-pencil-square-o
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'}}")
title="{{#if isStarred}}{{_ 'star-board-short-unstar'}}{{else}}{{_ 'star-board-short-star'}}{{/if}}" aria-label="{{#if isStarred}}{{_ 'star-board-short-unstar'}}{{else}}{{_ 'star-board-short-star'}}{{/if}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
if showStarCounter
span
@@ -51,6 +51,8 @@ template(name="boardHeaderBar")
i.fa.fa-sign-in
span {{_ 'log-in'}}
.board-header-btns.center
.board-header-btns.right
if currentBoard
if isMiniScreen
@@ -62,15 +64,11 @@ template(name="boardHeaderBar")
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.js-watch-board(
title="{{_ watchLevel }}")
@@ -80,10 +78,8 @@ template(name="boardHeaderBar")
i.fa.fa-bell
if $eq watchLevel "muted"
i.fa.fa-bell-slash
span {{_ watchLevel}}
a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}")
i.fa.fa-sort
span {{#if isSortActive }}{{_ 'sort-is-on'}}{{else}}{{_ 'sort-cards'}}{{/if}}
if isSortActive
a.board-header-btn-close.js-sort-reset(title="{{_ 'remove-sort'}}")
i.fa.fa-times-thin
@@ -92,13 +88,11 @@ template(name="boardHeaderBar")
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
i.fa.fa-sign-in
span {{_ 'log-in'}}
if isSandstorm
if currentUser
a.board-header-btn.js-open-archived-board
i.fa.fa-archive
span {{_ 'archives'}}
//if showSort
// a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}")
@@ -109,14 +103,12 @@ template(name="boardHeaderBar")
title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}"
class="{{#if Filter.isActive}}emphasis{{/if}}")
i.fa.fa-filter
span {{#if Filter.isActive}}{{_ 'filter-on'}}{{else}}{{_ 'filter'}}{{/if}}
if Filter.isActive
a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}")
i.fa.fa-times-thin
a.board-header-btn.js-open-search-view(title="{{_ 'search'}}")
i.fa.fa-search
span {{_ 'search'}}
unless currentBoard.isTemplatesBoard
a.board-header-btn.js-toggle-board-view(
@@ -128,14 +120,12 @@ template(name="boardHeaderBar")
i.fa.fa-trello
if $eq boardView 'board-view-cal'
i.fa.fa-calendar
span {{#if boardView}}{{_ boardView}}{{else}}{{_ 'board-view-swimlanes'}}{{/if}}
if canModifyBoard
a.board-header-btn.js-multiselection-activate(
title="{{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}"
class="{{#if MultiSelection.isActive}}emphasis{{/if}}")
i.fa.fa-check-square-o
span {{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}
if MultiSelection.isActive
a.board-header-btn-close.js-multiselection-reset(title="{{_ 'filter-clear'}}")
i.fa.fa-times-thin
+2
View File
@@ -33,6 +33,8 @@ BlazeComponent.extendComponent({
return currentBoard && currentBoard.getWatchLevel(Meteor.userId());
},
isStarred() {
const boardId = Session.get('currentBoard');
const user = ReactiveCache.getCurrentUser();
+554 -7
View File
@@ -1,5 +1,86 @@
@import url("../../../css/reset.css") print, screen;
/* Board List Header with Zoom Controls */
.board-list-header {
display: flex;
justify-content: center;
margin: 1vh 0 2vh 0;
padding: 1vh 0;
}
.zoom-controls {
display: flex;
align-items: center;
gap: 0.5vw;
background: rgba(255, 255, 255, 0.9);
padding: 0.5vh 1vw;
border-radius: 0.5vw;
box-shadow: 0 0.2vh 0.5vh rgba(0,0,0,0.1);
}
.zoom-controls .board-header-btn {
padding: 0.5vh 0.8vw !important;
border-radius: 0.3vw !important;
background: #fff !important;
border: 1px solid #000 !important;
transition: all 0.2s ease !important;
text-decoration: none !important;
color: #000 !important;
display: flex !important;
align-items: center !important;
gap: 0.3vw !important;
height: auto !important;
line-height: normal !important;
margin: 0 !important;
float: none !important;
overflow: visible !important;
}
.zoom-controls .board-header-btn i {
color: #000 !important;
float: none !important;
display: inline !important;
line-height: normal !important;
margin: 0 !important;
}
.zoom-controls .board-header-btn:hover {
background: #000 !important;
border-color: #000 !important;
color: #fff !important;
}
.zoom-controls .board-header-btn:hover i {
color: #fff !important;
}
.zoom-controls .board-header-btn.is-active {
background: #0079bf;
color: white;
border-color: #005a8a;
}
.zoom-controls .board-header-btn.is-active i {
color: white;
}
.zoom-level {
font-weight: bold;
color: #333;
min-width: 3vw;
text-align: center;
font-size: clamp(12px, 2vw, 14px);
cursor: pointer;
padding: 0.3vh 0.5vw;
border-radius: 0.3vw;
transition: all 0.2s ease;
}
.zoom-level:hover {
background: #f0f0f0;
color: #000;
}
.board-list {
margin: 0 8px;
}
@@ -192,17 +273,131 @@
font-size: 25px;
color: #fff;
}
@media screen and (max-width: 800px) {
/* Mobile view styles - applied when isMiniScreen is true (iPhone, etc.) */
.board-list.mobile-view {
height: calc(100vh - 120px);
overflow-y: scroll !important;
overflow-x: hidden;
padding: 0 1rem;
margin: 0;
scrollbar-width: auto !important;
scrollbar-color: #888 #f1f1f1;
}
.board-list.mobile-view li {
width: 100%;
float: none;
display: block;
margin-bottom: 1rem;
padding-right: 50px; /* Space for drag handle */
}
.board-list.mobile-view .board-list-item {
overflow: visible;
height: 8rem;
width: 100%;
margin: 0;
padding-right: 50px; /* Ensure content doesn't overlap with drag handle */
}
.board-list.mobile-view .board-list-item .details {
padding-right: 50px; /* Extra space for drag handle */
width: 100%;
box-sizing: border-box;
}
.board-list.mobile-view .board-list-item-sub-name {
position: relative;
top: -100px;
left: -100px;
}
.board-list.mobile-view .board-handle {
position: absolute;
padding: 7px;
top: 50%;
transform: translateY(-50%);
right: 10px;
font-size: 24px;
color: #fff;
background: rgba(0,0,0,0.3);
border-radius: 50%;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
transition: background-color 0.2s ease;
}
.board-list.mobile-view .board-handle:hover {
background: rgba(255, 255, 0, 0.8) !important; /* Yellow hover */
}
/* Force scrollbar to be visible on mobile view */
.board-list.mobile-view::-webkit-scrollbar {
width: 12px !important;
display: block !important;
visibility: visible !important;
}
.board-list.mobile-view::-webkit-scrollbar-track {
background: #f1f1f1 !important;
border-radius: 6px !important;
display: block !important;
visibility: visible !important;
}
.board-list.mobile-view::-webkit-scrollbar-thumb {
background: #888 !important;
border-radius: 6px !important;
display: block !important;
visibility: visible !important;
}
.board-list.mobile-view::-webkit-scrollbar-thumb:hover {
background: #555 !important;
}
/* Force mobile view to have scrollable content */
.board-list.mobile-view {
min-height: 100vh; /* Force content to be tall enough to scroll */
}
.board-list.mobile-view::after {
content: '';
display: block;
height: 100px;
}
@media screen and (max-width: 800px),
screen and (max-device-width: 800px),
screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px),
screen and (max-width: 800px) and (orientation: portrait),
screen and (max-width: 800px) and (orientation: landscape) {
.board-list {
height: 100%;
overflow: scroll;
overflow-y: auto;
overflow-x: hidden;
padding: 0 1rem;
margin: 0;
}
.board-list li {
width: 50%;
width: 100%;
float: none;
display: block;
margin-bottom: 1rem;
padding-right: 50px; /* Space for drag handle */
}
.board-list .board-list-item {
overflow: hidden;
overflow: visible;
height: 8rem;
width: 100%;
margin: 0;
padding-right: 50px; /* Ensure content doesn't overlap with drag handle */
}
.board-list .board-list-item .details {
padding-right: 50px; /* Extra space for drag handle */
width: 100%;
box-sizing: border-box;
}
.board-list .board-list-item-sub-name {
position: relative;
@@ -216,19 +411,296 @@
transform: translateY(-50%);
right: 10px;
font-size: 24px;
color: #fff;
background: rgba(0,0,0,0.3);
border-radius: 50%;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
transition: background-color 0.2s ease;
}
.board-list .board-handle:hover {
background: rgba(255, 255, 0, 0.8) !important; /* Yellow hover */
}
}
/* Very small screens - ensure one board per row */
@media screen and (max-width: 360px) {
li {
width: 100%;
.board-list li {
width: 100% !important;
float: none !important;
display: block !important;
}
.board-handle {
.board-list .board-handle {
position: absolute;
padding: 7px;
top: 50%;
transform: translateY(-50%);
right: 10px;
font-size: 24px;
color: #fff;
background: rgba(0,0,0,0.3);
border-radius: 50%;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
}
/* Mobile - make all text and icons 2x bigger above #content on All Boards page */
@media screen and (max-width: 800px),
screen and (max-device-width: 800px),
screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px),
screen and (max-width: 800px) and (orientation: portrait),
screen and (max-width: 800px) and (orientation: landscape) {
.wrapper {
font-size: 2em !important; /* 2x bigger base font size for All Boards page */
}
.wrapper * {
font-size: inherit !important; /* Inherit the 2x scaling */
}
.wrapper .fa, .wrapper .icon {
font-size: 2em !important; /* 2x bigger icons */
}
.board-list-header {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.board-list-header h1 {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.AllBoardTeamsOrgs {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.AllBoardTeamsOrgs select {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.AllBoardTeamsOrgs input {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.AllBoardTeamsOrgs .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.board-list {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.board-list .board-list-item {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.board-list .board-list-item-name {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.board-list .board-list-item-desc {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.board-list .minicard-members {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.board-list .minicard-lists {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.board-list .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.board-list .board-handle {
font-size: 1em !important; /* Use inherited 2x scaling */
}
}
/* Fallback for iPhone devices using JavaScript detection - All Boards page */
.iphone-device .wrapper {
font-size: 2em !important; /* 2x bigger base font size for All Boards page */
}
.iphone-device .wrapper * {
font-size: inherit !important; /* Inherit the 2x scaling */
}
.iphone-device .wrapper .fa, .iphone-device .wrapper .icon {
font-size: 2em !important; /* 2x bigger icons */
}
.iphone-device .board-list-header {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .board-list-header h1 {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .AllBoardTeamsOrgs {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .AllBoardTeamsOrgs select {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .AllBoardTeamsOrgs input {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .AllBoardTeamsOrgs .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .board-list {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .board-list .board-list-item {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .board-list .board-list-item-name {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .board-list .board-list-item-desc {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .board-list .minicard-members {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .board-list .minicard-lists {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .board-list .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .board-list .board-handle {
font-size: 1em !important; /* Use inherited 2x scaling */
}
/* iPhone 12 Mini and very small screens - make everything much larger */
@media screen and (max-width: 400px) and (max-height: 900px) {
.board-list {
height: calc(100vh - 120px) !important;
overflow-y: scroll !important;
overflow-x: hidden !important;
-webkit-overflow-scrolling: touch;
padding: 0 0.5rem;
}
.board-list li {
width: 100% !important;
float: none !important;
display: block !important;
margin-bottom: 1.5rem !important;
}
.board-list .board-list-item {
height: 12rem !important; /* Much taller */
width: 100% !important;
margin: 0 !important;
padding: 1rem !important; /* More padding */
font-size: 18px !important; /* Much larger text */
line-height: 1.4 !important;
}
.board-list .board-list-item .board-list-item-name {
font-size: 20px !important; /* Larger board names */
font-weight: bold !important;
margin-bottom: 0.5rem !important;
}
.board-list .board-list-item .board-list-item-desc {
font-size: 16px !important; /* Larger descriptions */
line-height: 1.3 !important;
}
.board-list .board-list-item .minicard-members {
font-size: 14px !important; /* Larger member avatars */
}
.board-list .board-list-item .minicard-lists {
font-size: 14px !important; /* Larger list counters */
}
.board-list .board-handle {
position: absolute;
padding: 10px !important;
top: 50%;
transform: translateY(-50%);
right: 15px !important;
font-size: 28px !important; /* Much larger drag handle */
color: #fff;
background: rgba(0,0,0,0.4) !important;
border-radius: 50%;
width: 50px !important; /* Larger handle */
height: 50px !important;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
transition: background-color 0.2s ease;
}
.board-list .board-handle:hover {
background: rgba(255, 255, 0, 0.8) !important; /* Yellow hover */
}
/* Force scrollbar to be visible and larger */
.board-list::-webkit-scrollbar {
width: 16px !important; /* Much wider scrollbar */
display: block !important;
visibility: visible !important;
}
.board-list::-webkit-scrollbar-track {
background: #f1f1f1 !important;
border-radius: 8px !important;
display: block !important;
visibility: visible !important;
}
.board-list::-webkit-scrollbar-thumb {
background: #666 !important; /* Darker for better visibility */
border-radius: 8px !important;
display: block !important;
visibility: visible !important;
min-height: 50px !important; /* Minimum thumb size */
}
.board-list::-webkit-scrollbar-thumb:hover {
background: #333 !important;
}
/* Ensure scrollbar is always visible */
.board-list {
scrollbar-gutter: stable;
scrollbar-width: auto !important;
min-height: 100vh !important;
}
.board-list::after {
content: '';
display: block;
height: 200px !important; /* More space to ensure scrolling */
}
}
.AllBoardTeamsOrgs {
@@ -279,3 +751,78 @@
padding-right: 6px;
text-align: center;
}
/* Fix multiple scrollbars issue on mobile */
@media screen and (max-width: 800px),
screen and (max-device-width: 800px),
screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px),
screen and (max-width: 800px) and (orientation: portrait),
screen and (max-width: 800px) and (orientation: landscape) {
.wrapper {
overflow: hidden;
height: 100vh;
}
.board-list {
overflow-y: scroll !important;
overflow-x: hidden !important;
-webkit-overflow-scrolling: touch;
scrollbar-width: thin;
scrollbar-color: #888 #f1f1f1;
height: calc(100vh - 120px); /* Ensure there's content to scroll */
}
/* Force scrollbar to always be visible */
.board-list::-webkit-scrollbar {
width: 12px !important;
display: block !important;
visibility: visible !important;
}
.board-list::-webkit-scrollbar-track {
background: #f1f1f1 !important;
border-radius: 6px !important;
display: block !important;
visibility: visible !important;
}
.board-list::-webkit-scrollbar-thumb {
background: #888 !important;
border-radius: 6px !important;
display: block !important;
visibility: visible !important;
}
.board-list::-webkit-scrollbar-thumb:hover {
background: #555 !important;
}
/* Ensure scrollbar is always visible */
.board-list::-webkit-scrollbar-corner {
background: #f1f1f1 !important;
}
/* Force scrollbar to be visible */
.board-list {
scrollbar-gutter: stable;
scrollbar-width: auto !important;
min-height: 100vh; /* Force content to be tall enough to scroll */
}
/* Ensure there's always content to scroll */
.board-list::after {
content: '';
display: block;
height: 100px;
}
/* Ensure only one scrollbar is visible */
body {
overflow: hidden;
}
#content {
overflow: hidden;
}
}
+3 -1
View File
@@ -1,5 +1,7 @@
template(name="boardList")
.wrapper
.board-list-header
ul.AllBoardTeamsOrgs
li.AllBoardTeams
if userHasTeams
@@ -29,7 +31,7 @@ template(name="boardList")
input#filterBtn(type="button" value="{{_ 'filter'}}")
input#resetBtn(type="button" value="{{_ 'filter-clear'}}")
ul.board-list.clearfix.js-boards
ul.board-list.clearfix.js-boards(class="{{#if isMiniScreen}}mobile-view{{/if}}")
li.js-add-board
a.board-list-item.label(title="{{_ 'add-board'}}")
| {{_ 'add-board'}}
+35 -26
View File
@@ -22,6 +22,9 @@ Template.boardListHeaderBar.events({
},
});
Template.boardList.events({
});
Template.boardListHeaderBar.helpers({
title() {
//if (FlowRouter.getRouteName() === 'template-container') {
@@ -239,34 +242,40 @@ BlazeComponent.extendComponent({
evt.preventDefault();
},
'click .js-clone-board'(evt) {
let title = getSlug(ReactiveCache.getBoard(this.currentData()._id).title) || 'cloned-board';
Meteor.call(
'copyBoard',
this.currentData()._id,
{
sort: ReactiveCache.getBoards({ archived: false }).length,
type: 'board',
title: ReactiveCache.getBoard(this.currentData()._id).title,
},
(err, res) => {
if (err) {
console.error(err);
} else {
Session.set('fromBoard', null);
subManager.subscribe('board', res, false);
FlowRouter.go('board', {
id: res,
slug: title,
});
}
},
);
evt.preventDefault();
if (confirm(TAPi18n.__('duplicate-board-confirm'))) {
let title =
getSlug(ReactiveCache.getBoard(this.currentData()._id).title) ||
'cloned-board';
Meteor.call(
'copyBoard',
this.currentData()._id,
{
sort: ReactiveCache.getBoards({ archived: false }).length,
type: 'board',
title: ReactiveCache.getBoard(this.currentData()._id).title,
},
(err, res) => {
if (err) {
console.error(err);
} else {
Session.set('fromBoard', null);
subManager.subscribe('board', res, false);
FlowRouter.go('board', {
id: res,
slug: title,
});
}
},
);
evt.preventDefault();
}
},
'click .js-archive-board'(evt) {
const boardId = this.currentData()._id;
Meteor.call('archiveBoard', boardId);
evt.preventDefault();
if (confirm(TAPi18n.__('archive-board-confirm'))) {
const boardId = this.currentData()._id;
Meteor.call('archiveBoard', boardId);
evt.preventDefault();
}
},
'click .js-accept-invite'() {
const boardId = this.currentData()._id;
+136
View File
@@ -106,6 +106,142 @@
color: white;
cursor: pointer;
font-size: 4em;
}
/* Upload progress indicators for drag-and-drop uploads */
.minicard-upload-progress,
.card-details-upload-progress {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 4px;
padding: 12px;
margin: 8px 0;
font-size: 14px;
}
.upload-progress-header {
display: flex;
align-items: center;
margin-bottom: 8px;
font-weight: bold;
color: #495057;
}
.upload-progress-header i {
margin-right: 8px;
color: #007bff;
}
.upload-progress-item {
display: flex;
flex-direction: column;
margin-bottom: 8px;
padding: 8px;
background: white;
border-radius: 3px;
border: 1px solid #dee2e6;
}
.upload-progress-item.upload-error {
border-color: #dc3545;
background: #f8d7da;
}
.upload-progress-filename {
font-weight: 500;
margin-bottom: 4px;
color: #495057;
word-break: break-all;
}
.upload-progress-bar {
width: 100%;
height: 6px;
background: #e9ecef;
border-radius: 3px;
overflow: hidden;
margin-bottom: 4px;
}
.upload-progress-fill {
height: 100%;
background: linear-gradient(90deg, #007bff, #0056b3);
transition: width 0.3s ease;
border-radius: 3px;
}
.upload-progress-item.upload-error .upload-progress-fill {
background: #dc3545;
}
.upload-progress-error,
.upload-progress-success {
display: flex;
align-items: center;
font-size: 12px;
font-weight: 500;
}
.upload-progress-error {
color: #dc3545;
}
.upload-progress-success {
color: #28a745;
}
.upload-progress-error i,
.upload-progress-success i {
margin-right: 4px;
}
/* Minicard specific styles */
.minicard-upload-progress {
margin: 4px 0;
padding: 8px;
font-size: 12px;
}
.minicard-upload-progress .upload-progress-item {
padding: 6px;
margin-bottom: 6px;
}
.minicard-upload-progress .upload-progress-filename {
font-size: 11px;
}
/* Card details specific styles */
.card-details-upload-progress {
margin: 12px 0;
padding: 16px;
}
.card-details-upload-progress .upload-progress-header {
font-size: 16px;
margin-bottom: 12px;
}
.card-details-upload-progress .upload-progress-item {
padding: 12px;
margin-bottom: 10px;
}
.card-details-upload-progress .upload-progress-filename {
font-size: 14px;
}
/* Drag over state for minicards */
.minicard.is-dragging-over {
border: 2px dashed #007bff !important;
background: rgba(0, 123, 255, 0.1) !important;
}
/* Drag over state for card details */
.js-card-details.is-dragging-over {
border: 2px dashed #007bff !important;
background: rgba(0, 123, 255, 0.05) !important;
}
top: 0;
right: 8px;
position: absolute;
+106 -37
View File
@@ -1,6 +1,8 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { ObjectID } from 'bson';
import DOMPurify from 'dompurify';
import { sanitizeHTML, sanitizeText } from '/imports/lib/secureDOMPurify';
import uploadProgressManager from '../../lib/uploadProgressManager';
const filesize = require('filesize');
const prettyMilliseconds = require('pretty-ms');
@@ -268,7 +270,7 @@ Template.attachmentGallery.helpers({
return ret;
},
sanitize(value) {
return DOMPurify.sanitize(value);
return sanitizeHTML(value);
},
});
@@ -296,44 +298,13 @@ Template.cardAttachmentsPopup.events({
const files = event.currentTarget.files;
if (files) {
let uploads = [];
for (const file of files) {
const fileId = new ObjectID().toString();
let fileName = DOMPurify.sanitize(file.name);
const uploaders = handleFileUpload(card, files);
// If sanitized filename is not same as original filename,
// it could be XSS that is already fixed with sanitize,
// or just normal mistake, so it is not a problem.
// That is why here is no warning.
if (fileName !== file.name) {
// If filename is empty, only in that case add some filename
if (fileName.length === 0) {
fileName = 'Empty-filename-after-sanitize.txt';
}
}
const config = {
file: file,
fileId: fileId,
fileName: fileName,
meta: Utils.getCommonAttachmentMetaFrom(card),
chunkSize: 'dynamic',
};
config.meta.fileId = fileId;
const uploader = Attachments.insert(
config,
false,
);
uploaders.forEach(uploader => {
uploader.on('start', function() {
uploads.push(this);
templateInstance.uploads.set(uploads);
});
uploader.on('uploaded', (error, fileRef) => {
if (!error) {
if (fileRef.isImage) {
card.setCover(fileRef._id);
}
}
});
uploader.on('end', (error, fileRef) => {
uploads = uploads.filter(_upload => _upload.config.fileId != fileRef._id);
templateInstance.uploads.set(uploads);
@@ -341,8 +312,7 @@ Template.cardAttachmentsPopup.events({
Popup.back();
}
});
uploader.start();
}
});
}
},
'click .js-computer-upload'(event, templateInstance) {
@@ -356,6 +326,105 @@ const MAX_IMAGE_PIXEL = Utils.MAX_IMAGE_PIXEL;
const COMPRESS_RATIO = Utils.IMAGE_COMPRESS_RATIO;
let pastedResults = null;
// Shared upload logic for drag-and-drop functionality
export function handleFileUpload(card, files) {
if (!files || files.length === 0) {
return [];
}
// Check if board allows attachments
const board = card.board();
if (!board || !board.allowsAttachments) {
if (process.env.DEBUG === 'true') {
console.warn('Attachments not allowed on this board');
}
return [];
}
// Check if user can modify the card
if (!card.canModifyCard()) {
if (process.env.DEBUG === 'true') {
console.warn('User does not have permission to modify this card');
}
return [];
}
const uploads = [];
for (const file of files) {
// Basic file validation
if (!file || !file.name) {
if (process.env.DEBUG === 'true') {
console.warn('Invalid file object');
}
continue;
}
const fileId = new ObjectID().toString();
let fileName = sanitizeText(file.name);
// If sanitized filename is not same as original filename,
// it could be XSS that is already fixed with sanitize,
// or just normal mistake, so it is not a problem.
// That is why here is no warning.
if (fileName !== file.name) {
// If filename is empty, only in that case add some filename
if (fileName.length === 0) {
fileName = 'Empty-filename-after-sanitize.txt';
}
}
const config = {
file: file,
fileId: fileId,
fileName: fileName,
meta: Utils.getCommonAttachmentMetaFrom(card),
chunkSize: 'dynamic',
};
config.meta.fileId = fileId;
try {
const uploader = Attachments.insert(
config,
false,
);
// Add to progress manager for tracking
const uploadId = uploadProgressManager.addUpload(card._id, uploader, file);
uploader.on('uploaded', (error, fileRef) => {
if (!error) {
if (fileRef.isImage) {
card.setCover(fileRef._id);
if (process.env.DEBUG === 'true') {
console.log(`Set cover image for card ${card._id}: ${fileRef.name}`);
}
}
} else {
if (process.env.DEBUG === 'true') {
console.error('Upload error:', error);
}
}
});
uploader.on('error', (error) => {
if (process.env.DEBUG === 'true') {
console.error('Upload error:', error);
}
});
uploads.push(uploader);
uploader.start();
} catch (error) {
if (process.env.DEBUG === 'true') {
console.error('Failed to create uploader:', error);
}
}
}
return uploads;
}
Template.previewClipboardImagePopup.onRendered(() => {
// we can paste image from clipboard
const handle = results => {
@@ -498,7 +567,7 @@ BlazeComponent.extendComponent({
const name = this.$('.js-edit-attachment-name')[0]
.value
.trim() + this.data().extensionWithDot;
if (name === DOMPurify.sanitize(name)) {
if (name === sanitizeText(name)) {
Meteor.call('renameAttachment', this.data()._id, name);
}
Popup.back();
@@ -79,13 +79,14 @@ template(name="cardCustomField-currency")
template(name="cardCustomField-date")
if canModifyCard
a.js-edit-date(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
a.js-edit-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
if value
div.card-date
time(datetime="{{showISODate}}")
| {{showDate}}
b
| {{showWeek}}
if showWeekOfYear
b
| {{showWeek}}
else
| {{_ 'edit'}}
else
@@ -93,8 +94,9 @@ template(name="cardCustomField-date")
div.card-date
time(datetime="{{showISODate}}")
| {{showDate}}
b
| {{showWeek}}
if showWeekOfYear
b
| {{showWeek}}
template(name="cardCustomField-dropdown")
if canModifyCard
@@ -148,6 +148,10 @@ CardCustomField.register('cardCustomField');
return this.date.get().week().toString();
}
showWeekOfYear() {
return ReactiveCache.getCurrentUser().isShowWeekOfYear();
}
showDate() {
// this will start working once mquandalle:moment
// is updated to at least moment.js 2.10.5
+12 -9
View File
@@ -1,20 +1,23 @@
template(name="dateBadge")
if canModifyCard
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
b
| {{showWeek}}
if showWeekOfYear
b
| {{showWeek}}
else
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
b
| {{showWeek}}
if showWeekOfYear
b
| {{showWeek}}
template(name="dateCustomField")
a(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
a(title="{{showTitle}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
time(datetime="{{showISODate}}")
| {{showDate}}
b
| {{showWeek}}
if showWeekOfYear
b
| {{showWeek}}
+15 -7
View File
@@ -11,7 +11,7 @@ import { DatePicker } from '/client/lib/datepicker';
}
_storeDate(date) {
this.card.setReceived(date);
this.card.setReceived(moment(date).format('YYYY-MM-DD HH:mm'));
}
_deleteDate() {
@@ -37,7 +37,7 @@ import { DatePicker } from '/client/lib/datepicker';
}
_storeDate(date) {
this.card.setStart(date);
this.card.setStart(moment(date).format('YYYY-MM-DD HH:mm'));
}
_deleteDate() {
@@ -60,7 +60,7 @@ import { DatePicker } from '/client/lib/datepicker';
}
_storeDate(date) {
this.card.setDue(date);
this.card.setDue(moment(date).format('YYYY-MM-DD HH:mm'));
}
_deleteDate() {
@@ -83,7 +83,7 @@ import { DatePicker } from '/client/lib/datepicker';
}
_storeDate(date) {
this.card.setEnd(date);
this.card.setEnd(moment(date).format('YYYY-MM-DD HH:mm'));
}
_deleteDate() {
@@ -110,6 +110,10 @@ const CardDate = BlazeComponent.extendComponent({
return this.date.get().week().toString();
},
showWeekOfYear() {
return ReactiveCache.getCurrentUser().isShowWeekOfYear();
},
showDate() {
// this will start working once mquandalle:moment
// is updated to at least moment.js 2.10.5
@@ -283,6 +287,10 @@ class CardCustomFieldDate extends CardDate {
return this.date.get().week().toString();
}
showWeekOfYear() {
return ReactiveCache.getCurrentUser().isShowWeekOfYear();
}
showDate() {
// this will start working once mquandalle:moment
// is updated to at least moment.js 2.10.5
@@ -314,19 +322,19 @@ CardCustomFieldDate.register('cardCustomFieldDate');
(class extends CardStartDate {
showDate() {
return this.date.get().format('L');
return this.date.get().format('YYYY-MM-DD HH:mm');
}
}.register('minicardStartDate'));
(class extends CardDueDate {
showDate() {
return this.date.get().format('L');
return this.date.get().format('YYYY-MM-DD HH:mm');
}
}.register('minicardDueDate'));
(class extends CardEndDate {
showDate() {
return this.date.get().format('L');
return this.date.get().format('YYYY-MM-DD HH:mm');
}
}.register('minicardEndDate'));
+22 -14
View File
@@ -1,11 +1,11 @@
.assignee {
border-radius: 3px;
border-radius: 0.4vw;
display: block;
position: relative;
float: left;
height: 30px;
width: 30px;
margin: .3vh;
height: 4vw;
width: 4vw;
margin: 0.4vh;
cursor: pointer;
user-select: none;
z-index: 1;
@@ -34,11 +34,11 @@
background-color: #b3b3b3;
border: 1px solid #fff;
border-radius: 50%;
height: 7px;
width: 7px;
height: 1vw;
width: 1vw;
position: absolute;
right: -1px;
bottom: -1px;
right: -0.1vw;
bottom: -0.1vw;
border: 1px solid #fff;
z-index: 15;
}
@@ -70,23 +70,23 @@
}
.copied-tooltip {
display: none;
padding: 0px 10px;
padding: 0 1.3vw;
background-color: rgba(0,0,0,0.875);
color: #fff;
border-radius: 5px;
border-radius: 0.7vw;
}
.card-details {
padding: 0;
flex-shrink: 0;
flex-basis: 600px;
flex-basis: min(600px, 80vw);
will-change: flex-basis;
overflow-y: scroll;
overflow-x: hidden;
background: #f7f7f7;
border-radius: bottom 3px;
border-radius: bottom 0.4vw;
z-index: 30;
animation: flexGrowIn 0.1s;
box-shadow: 0 0 7px 0 #b3b3b3;
box-shadow: 0 0 0.9vh 0 #b3b3b3;
transition: flex-basis 0.1s;
box-sizing: border-box;
}
@@ -95,7 +95,7 @@
}
.card-details .card-details-canvas {
width: auto;
padding: 0 20px;
padding: 0 2.5vw;
}
.card-details .card-details-header {
margin: 0 -20px 5px;
@@ -596,3 +596,11 @@ input[type="submit"].attachment-add-link-submit {
overflow: hidden;
background-color: #cecece;
}
/* Drag and drop file upload visual feedback */
.js-card-details.is-dragging-over {
border: 2px dashed #0079bf;
background-color: #e3f2fd !important;
transform: scale(1.01);
transition: all 0.2s ease;
}
+20
View File
@@ -65,6 +65,26 @@ template(name="cardDetails")
else
p.warning {{_ 'card-archived'}}
// Upload progress indicator for drag-and-drop uploads
if hasActiveUploads
.card-details-upload-progress
.upload-progress-header
i.fa.fa-upload
span {{_ 'uploading-files'}} ({{uploadCount}})
each uploads
.upload-progress-item(class="{{#if $eq status 'error'}}upload-error{{/if}}")
.upload-progress-filename {{file.name}}
.upload-progress-bar
.upload-progress-fill(style="width: {{progress}}%")
if $eq status 'error'
.upload-progress-error
i.fa.fa-exclamation-triangle
span {{_ 'upload-failed'}}
else if $eq status 'completed'
.upload-progress-success
i.fa.fa-check
span {{_ 'upload-completed'}}
.card-details-left
.card-details-items
+65
View File
@@ -12,6 +12,8 @@ import CardComments from '/models/cardComments';
import { ALLOWED_COLORS } from '/config/const';
import { UserAvatar } from '../users/userAvatar';
import { DialogWithBoardSwimlaneList } from '/client/lib/dialogWithBoardSwimlaneList';
import { handleFileUpload } from './attachments';
import uploadProgressManager from '../../lib/uploadProgressManager';
const subManager = new SubsManager();
const { calculateIndexData } = Utils;
@@ -481,6 +483,59 @@ BlazeComponent.extendComponent({
}
}
},
// Drag and drop file upload handlers
'dragover .js-card-details'(event) {
event.preventDefault();
event.stopPropagation();
},
'dragenter .js-card-details'(event) {
event.preventDefault();
event.stopPropagation();
const card = this.data();
const board = card.board();
// Only allow drag-and-drop if user can modify card and board allows attachments
if (card.canModifyCard() && board && board.allowsAttachments) {
// Check if the drag contains files
const dataTransfer = event.originalEvent.dataTransfer;
if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) {
$(event.currentTarget).addClass('is-dragging-over');
}
}
},
'dragleave .js-card-details'(event) {
event.preventDefault();
event.stopPropagation();
$(event.currentTarget).removeClass('is-dragging-over');
},
'drop .js-card-details'(event) {
event.preventDefault();
event.stopPropagation();
$(event.currentTarget).removeClass('is-dragging-over');
const card = this.data();
const board = card.board();
// Check permissions
if (!card.canModifyCard() || !board || !board.allowsAttachments) {
return;
}
// Check if this is a file drop (not a checklist item reorder)
const dataTransfer = event.originalEvent.dataTransfer;
if (!dataTransfer || !dataTransfer.files || dataTransfer.files.length === 0) {
return;
}
// Check if the drop contains files (not just text/HTML)
if (!dataTransfer.types.includes('Files')) {
return;
}
const files = dataTransfer.files;
if (files && files.length > 0) {
handleFileUpload(card, files);
}
},
},
];
},
@@ -490,6 +545,16 @@ Template.cardDetails.helpers({
isPopup() {
let ret = !!Utils.getPopupCardId();
return ret;
},
// Upload progress helpers
hasActiveUploads() {
return uploadProgressManager.hasActiveUploads(this._id);
},
uploads() {
return uploadProgressManager.getUploadsForCard(this._id);
},
uploadCount() {
return uploadProgressManager.getUploadCountForCard(this._id);
}
});
Template.cardDetailsPopup.onDestroyed(() => {
+68 -60
View File
@@ -3,11 +3,11 @@
position: relative;
display: flex;
align-items: center;
margin-bottom: 9px;
margin-bottom: 1.2vh;
}
.minicard-wrapper.placeholder {
background: #ccc;
border-radius: 9px;
border-radius: 1.2vw;
}
.minicard-wrapper.ui-sortable-helper {
cursor: grabbing;
@@ -16,28 +16,28 @@
}
.minicard-wrapper.ui-sortable-helper .and-n-other {
width: 100%;
height: 16px;
padding: 4px;
height: 2.5vh;
padding: 0.5vh;
background-color: #f2f2f2;
text-align: center;
border-radius: 3px;
border-radius: 0.4vw;
}
.minicard-wrapper.ui-sortable-helper .multi-selection-checkbox {
display: none;
}
.minicard-wrapper .multi-selection-checkbox + .minicard {
margin-left: 8px;
margin-left: 1vw;
}
@media only screen {
.minicard {
padding: 6px 8px 2px;
padding: 0.8vh 1vw 0.3vh;
position: relative;
flex: 1;
flex-wrap: wrap;
background-color: #fff;
min-height: 20px;
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
border-radius: 2px;
min-height: 2.5vh;
box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.15);
border-radius: 0.3vw;
color: #4d4d4d;
overflow: hidden;
transition: transform 0.2s, border-radius 0.2s;
@@ -45,14 +45,14 @@
}
.minicard-details-menu-with-handle {
float: right;
font-size: 18px;
padding-right: 30px;
padding-left: 5px;
font-size: clamp(14px, 3vw, 18px);
padding-right: 4vw;
padding-left: 0.7vw;
}
.minicard-details-menu {
float: right;
font-size: 18px;
padding-left: 5px;
font-size: clamp(14px, 3vw, 18px);
padding-left: 0.7vw;
}
@media print {
.minicard-details-menu,
@@ -63,7 +63,7 @@
.minicard.linked-board .linked-icon,
.minicard.linked-card .linked-icon {
display: inline-block;
margin-right: 11px;
margin-right: 1.5vw;
vertical-align: baseline;
font-size: 0.9em;
}
@@ -72,11 +72,11 @@
color: #937760;
}
.is-selected .minicard {
transform: translateX(11px);
transform: translateX(1.5vw);
border-bottom-right-radius: 0;
border-top-right-radius: 0;
z-index: 25;
box-shadow: -2px 1px 2px rgba(0,0,0,0.2);
box-shadow: -0.3vw 0.2vh 0.3vh rgba(0,0,0,0.2);
}
.minicard:hover:not(.minicard-composer),
.is-selected .minicard,
@@ -90,20 +90,20 @@
background-position: center;
background-repeat: no-repeat;
background-size: contain;
height: 145px;
height: 20vh;
user-select: none;
margin: 6px -8px 6px -8px;
border-radius: top 2px;
margin: 0.8vh -1vw 0.8vh -1vw;
border-radius: top 0.3vw;
}
.minicard .minicard-labels {
float: none;
}
.minicard .minicard-labels .minicard-label {
width: 11px;
height: 11px;
border-radius: 2px;
margin-right: 3px;
margin-bottom: 3px;
width: 1.5vw;
height: 1.5vw;
border-radius: 0.3vw;
margin-right: 0.4vw;
margin-bottom: 0.4vh;
}
.minicard .minicard-labels-no-text {
display: flex;
@@ -119,22 +119,22 @@
flex-grow: 1;
display: block;
word-wrap: break-word;
max-width: 100px;
margin-right: 4px;
max-width: 13vw;
margin-right: 0.5vw;
}
.minicard .minicard-custom-field-item-fullwidth {
flex-grow: 1;
display: block;
word-wrap: break-word;
max-width: 100%;
margin-right: 4px;
margin-right: 0.5vw;
}
.minicard .handle {
width: 20px;
height: 20px;
width: 2.5vw;
height: 2.5vw;
position: absolute;
right: 5px;
top: 5px;
right: 0.7vw;
top: 0.7vh;
display: none;
}
@media only screen {
@@ -143,13 +143,13 @@
}
}
.minicard .handle .fa-arrows {
font-size: 20px;
font-size: clamp(16px, 3vw, 20px);
color: #ccc;
}
.minicard .minicard-title .card-number {
color: #b3b3b3;
display: inline-block;
margin-right: 5px;
margin-right: 0.7vw;
}
@media only screen {
.minicard .minicard-title p:last-child {
@@ -166,11 +166,11 @@
flex-wrap: wrap;
}
.minicard .date {
margin-right: 3px;
margin-right: 0.4vw;
}
.minicard .badges {
float: left;
margin-top: 7px;
margin-top: 1vh;
color: #808080;
}
.minicard .badges:empty {
@@ -178,14 +178,14 @@
}
.minicard .badges .badge {
float: left;
margin-right: 11px;
margin-bottom: 3px;
margin-right: 1.5vw;
margin-bottom: 0.4vh;
font-size: 0.9em;
}
.minicard .badges .badge.is-finished {
background: #3cb500;
padding: 0px 3px;
border-radius: 3px;
padding: 0 0.4vw;
border-radius: 0.4vw;
color: #fff;
}
.minicard .badges .badge:last-of-type {
@@ -201,41 +201,41 @@
}
.minicard .badges .badge .badge-text {
font-size: 0.9em;
padding-left: 2px;
line-height: 14px;
padding-left: 0.3vw;
line-height: 1.2;
}
.minicard .badges .badge .check-list-text {
padding-left: 0px;
line-height: 12px;
line-height: 1.1;
}
.minicard .minicard-members,
.minicard .minicard-assignees,
.minicard .minicard-creator {
float: right;
margin-left: 5px;
margin-bottom: 4px;
margin-left: 0.7vw;
margin-bottom: 0.5vh;
}
.minicard .minicard-members .member,
.minicard .minicard-assignees .member,
.minicard .minicard-creator .member {
float: right;
border-radius: 50%;
height: 28px;
width: 28px;
margin-bottom: 4px;
height: 3.5vw;
width: 3.5vw;
margin-bottom: 0.5vh;
}
.minicard .minicard-members .assignee,
.minicard .minicard-assignees .assignee,
.minicard .minicard-creator .assignee {
float: right;
border-radius: 50%;
height: 28px;
width: 28px;
height: 3.5vw;
width: 3.5vw;
}
.minicard .minicard-members + .badges,
.minicard .minicard-assignees + .badges,
.minicard .minicard-creator + .badges {
margin-top: 5px;
margin-top: 0.7vh;
}
.minicard .minicard-assignees {
border-bottom: 1px solid #f00;
@@ -248,13 +248,13 @@
display: none;
}
.minicard .minicard-description {
padding: 6px 0 0 8px;
padding: 0.8vh 0 0 1vw;
color: #000;
background-color: #eee;
width: 100%;
margin-bottom: 2px;
margin-left: -4px;
border-radius: 3px;
margin-bottom: 0.3vh;
margin-left: -0.5vw;
border-radius: 0.4vw;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
@@ -262,7 +262,7 @@
-webkit-box-orient: vertical;
}
.minicard.minicard-composer {
margin-bottom: 10px;
margin-bottom: 1.3vh;
}
.minicard.minicard-composer textarea.minicard-composer-textarea,
.minicard.minicard-composer textarea.minicard-composer-textarea:focus {
@@ -273,9 +273,9 @@
height: auto;
margin: 0;
padding: 0;
max-height: 162px;
min-height: 36px;
margin-bottom: 20px;
max-height: 22vh;
min-height: 5vh;
margin-bottom: 2.5vh;
overflow-y: auto;
}
.parent-prefix {
@@ -580,3 +580,11 @@
.text-green {
color: #008000;
}
/* Drag and drop file upload visual feedback */
.minicard.is-dragging-over {
border: 2px dashed #0079bf;
background-color: #e3f2fd !important;
transform: scale(1.02);
transition: all 0.2s ease;
}
+30
View File
@@ -31,6 +31,27 @@ template(name="minicard")
if cover
if currentBoard.allowsCoverAttachmentOnMinicard
.minicard-cover(style="background-image: url('{{cover.link 'original'}}?dummyReloadAfterSessionEstablished={{sess}}');")
// Upload progress indicator for drag-and-drop uploads
if hasActiveUploads
.minicard-upload-progress
.upload-progress-header
i.fa.fa-upload
span {{_ 'uploading-files'}} ({{uploadCount}})
each uploads
.upload-progress-item(class="{{#if $eq status 'error'}}upload-error{{/if}}")
.upload-progress-filename {{file.name}}
.upload-progress-bar
.upload-progress-fill(style="width: {{progress}}%")
if $eq status 'error'
.upload-progress-error
i.fa.fa-exclamation-triangle
span {{_ 'upload-failed'}}
else if $eq status 'completed'
.upload-progress-success
i.fa.fa-check
span {{_ 'upload-completed'}}
.minicard-title
if $eq 'prefix-with-full-path' currentBoard.presentParentTask
.parent-prefix
@@ -225,3 +246,12 @@ template(name="minicardDetailsActionsPopup")
a.js-link
i.fa.fa-link
| {{_ 'link-card'}}
li
a.js-toggle-watch-card
if isWatching
i.fa.fa-eye
| {{_ 'unwatch'}}
else
i.fa.fa-eye-slash
| {{_ 'watch'}}
+80 -1
View File
@@ -1,6 +1,8 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
import { CustomFieldStringTemplate } from '/client/lib/customFields'
import { CustomFieldStringTemplate } from '/client/lib/customFields';
import { handleFileUpload } from './attachments';
import uploadProgressManager from '../../lib/uploadProgressManager';
// Template.cards.events({
// 'click .member': Popup.open('cardMember')
@@ -46,6 +48,10 @@ BlazeComponent.extendComponent({
}
return ret;
},
isWatching() {
const card = this.currentData();
return card.findWatcher(Meteor.userId());
},
showMembers() {
// cache "board" to reduce the mini-mongodb access
@@ -103,6 +109,59 @@ BlazeComponent.extendComponent({
'click span.badge-icon.fa.fa-sort, click span.badge-text.check-list-sort' : Popup.open("editCardSortOrder"),
'click .minicard-labels' : this.cardLabelsPopup,
'click .js-open-minicard-details-menu': Popup.open('minicardDetailsActions'),
// Drag and drop file upload handlers
'dragover .minicard'(event) {
event.preventDefault();
event.stopPropagation();
},
'dragenter .minicard'(event) {
event.preventDefault();
event.stopPropagation();
const card = this.data();
const board = card.board();
// Only allow drag-and-drop if user can modify card and board allows attachments
if (card.canModifyCard() && board && board.allowsAttachments) {
// Check if the drag contains files
const dataTransfer = event.originalEvent.dataTransfer;
if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) {
$(event.currentTarget).addClass('is-dragging-over');
}
}
},
'dragleave .minicard'(event) {
event.preventDefault();
event.stopPropagation();
$(event.currentTarget).removeClass('is-dragging-over');
},
'drop .minicard'(event) {
event.preventDefault();
event.stopPropagation();
$(event.currentTarget).removeClass('is-dragging-over');
const card = this.data();
const board = card.board();
// Check permissions
if (!card.canModifyCard() || !board || !board.allowsAttachments) {
return;
}
// Check if this is a file drop (not a card reorder)
const dataTransfer = event.originalEvent.dataTransfer;
if (!dataTransfer || !dataTransfer.files || dataTransfer.files.length === 0) {
return;
}
// Check if the drop contains files (not just text/HTML)
if (!dataTransfer.types.includes('Files')) {
return;
}
const files = dataTransfer.files;
if (files && files.length > 0) {
handleFileUpload(card, files);
}
},
}
];
},
@@ -125,6 +184,19 @@ Template.minicard.helpers({
? Meteor.connection._lastSessionId
: null;
},
isWatching() {
return this.findWatcher(Meteor.userId());
},
// Upload progress helpers
hasActiveUploads() {
return uploadProgressManager.hasActiveUploads(this._id);
},
uploads() {
return uploadProgressManager.getUploadsForCard(this._id);
},
uploadCount() {
return uploadProgressManager.getUploadCountForCard(this._id);
}
});
BlazeComponent.extendComponent({
@@ -178,4 +250,11 @@ Template.minicardDetailsActionsPopup.events({
this.archive();
Utils.goBoardId(this.boardId);
}),
'click .js-toggle-watch-card'() {
const currentCard = this;
const level = currentCard.findWatcher(Meteor.userId()) ? null : 'watching';
Meteor.call('watch', 'card', currentCard._id, level, (err, ret) => {
if (!err && ret) Popup.back();
});
},
});
+44 -39
View File
@@ -5,11 +5,11 @@ button {
box-sizing: border-box;
background-color: #ebebeb;
border: 1px solid #ccc;
border-radius: 3px;
border-radius: 0.4vw;
display: block;
margin-bottom: 12px;
min-height: 34px;
padding: 7px;
margin-bottom: 1.5vh;
min-height: 4.5vh;
padding: 1vh 1vw;
}
select.full,
textarea.full,
@@ -31,17 +31,18 @@ button:focus {
outline: 0;
}
input[type="file"] {
margin-bottom: 16px;
margin-bottom: 2vh;
}
input[type="radio"] {
-webkit-appearance: radio;
appearance: radio;
min-height: inherit;
}
input[type="text"],
input[type="password"],
input[type="email"] {
transition: background 85ms ease-in, border-color 85ms ease-in;
width: 250px;
width: min(250px, 30vw);
}
input[type="text"].inline-input,
input[type="password"].inline-input,
@@ -49,10 +50,10 @@ input[type="email"].inline-input {
background: none;
border: 0;
margin: 0;
padding: 2px;
padding: 0.3vh;
min-height: 0;
height: 18px;
width: 200px;
height: 2.5vh;
width: min(200px, 25vw);
}
input[type="text"].full-line,
input[type="password"].full-line,
@@ -96,30 +97,31 @@ input[type="email"]:disabled,
textarea:disabled {
background-color: #dcdcdc;
border-color: #bfbfbf;
color: #8c8c8c;
color: #222;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
select {
max-height: 300px;
width: 256px;
margin-bottom: 8px;
max-height: 40vh;
width: min(256px, 32vw);
margin-bottom: 1vh;
}
select.inline {
width: 100%;
}
option[disabled] {
color: #8c8c8c;
color: #222;
}
textarea {
height: 150px;
height: 20vh;
transition: background 85ms ease-in, border-color 85ms ease-in;
resize: vertical;
width: 100%;
}
textarea.editor {
resize: none;
padding-bottom: 22px;
padding-bottom: 3vh;
}
.button {
border-radius: 3px;
@@ -134,14 +136,14 @@ button {
cursor: pointer;
display: inline-block;
font-weight: 700;
line-height: 22px;
padding: 7px 20px;
line-height: 1.3;
padding: 1vh 2.5vw;
text-align: center;
}
input[type="submit"] .wide,
button .wide {
padding-left: 30px;
padding-right: 30px;
padding-left: 4vw;
padding-right: 4vw;
}
input[type="submit"]:hover,
button:hover,
@@ -222,8 +224,8 @@ button.disabled:active,
}
fieldset {
border: 1px solid #bfbfbf;
padding: 15px;
margin-bottom: 15px;
padding: 2vh 2vw;
margin-bottom: 2vh;
}
input[type="hidden"] {
display: none;
@@ -231,18 +233,18 @@ input[type="hidden"] {
.radio-div,
.check-div {
display: block;
margin: 0 0 4px 20px;
min-height: 20px;
margin: 0 0 0.5vh 2.5vw;
min-height: 2.5vh;
position: relative;
}
.radio-div input,
.check-div input {
left: -18px;
left: -2.5vw;
min-height: 0;
margin: 0;
padding: 0;
position: absolute;
top: 2px;
top: 0.3vh;
}
.radio-div label,
.check-div label {
@@ -251,23 +253,23 @@ input[type="hidden"] {
label {
display: block;
font-weight: 700;
margin-bottom: 4px;
margin-bottom: 0.5vh;
}
label.form-error {
color: #ba1212;
color: #d32f2f;
}
input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder,
input::-moz-placeholder,
textarea::-moz-placeholder {
color: #8c8c8c;
color: #333 !important;
}
.edit-controls,
.add-controls {
display: flex;
align-items: center;
margin-top: 0px;
margin-bottom: 12px;
margin-bottom: 1.5vh;
}
@media print {
.add-controls {
@@ -279,13 +281,13 @@ textarea::-moz-placeholder {
.edit-controls input[type=button],
.add-controls input[type=button] {
float: left;
height: 32px;
height: 4.5vh;
margin-bottom: 0px;
}
.edit-controls .fa-times-thin,
.add-controls .fa-times-thin {
font-size: 26px;
margin: 3px 10px;
font-size: clamp(20px, 4vw, 26px);
margin: 0.5vh 1.5vw;
}
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
@@ -315,6 +317,7 @@ textarea::-moz-placeholder {
border-left: 2px solid transparent;
transform: rotate(40deg);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
transform-origin: 100% 100%;
}
.button-link {
@@ -322,6 +325,7 @@ textarea::-moz-placeholder {
background: linear-gradient(#fff, #f5f5f5);
border-radius: 3px;
box-sizing: border-box;
-webkit-user-select: none;
user-select: none;
border: 1px solid #e3e3e3;
border-bottom-color: #c2c2c2;
@@ -374,14 +378,14 @@ textarea::-moz-placeholder {
.button-link.setting.disabled {
background: #fff;
border-color: #e9e9e9;
color: #8c8c8c;
color: #222;
cursor: default;
}
.button-link.setting.disabled select {
display: none;
}
.button-link.setting.disabled:hover .label {
color: #8c8c8c;
color: #222;
}
.button-link.setting.disabled,
.button-link.setting.disabled:hover,
@@ -397,7 +401,7 @@ textarea::-moz-placeholder {
color: #a8a8a8;
}
.button-link.setting .label {
color: #8c8c8c;
color: #222;
display: block;
font-size: 12px;
line-height: 14px;
@@ -505,8 +509,9 @@ button.loud-text-button:hover {
.emphasis-button,
.quiet-button {
border-radius: 3px;
-webkit-user-select: none;
user-select: none;
color: #8c8c8c;
color: #222;
display: block;
margin: 2px 0;
padding: 6px 8px;
@@ -571,7 +576,7 @@ button.loud-text-button:hover {
top: 6px;
}
.big-link.none {
color: #8c8c8c;
color: #222;
text-decoration: none;
}
.big-link.none:hover {
@@ -601,7 +606,7 @@ button.loud-text-button:hover {
}
.show-more {
border-radius: 3px;
color: #8c8c8c;
color: #222;
display: block;
padding: 16px 8px 16px 40px;
margin: 8px 0;
+8 -8
View File
@@ -5,17 +5,17 @@
.map-members .mapping-list {
display: flex;
flex-wrap: wrap;
margin: 0 -4px;
margin: 0 -0.5vw;
}
.map-members .mapping-list .mapping-item {
max-width: 300px;
min-width: 200px;
padding: 6px;
margin: 5px;
max-width: min(300px, 40vw);
min-width: min(200px, 26vw);
padding: 0.8vh 0.8vw;
margin: 0.7vh;
flex: 1;
background: #fff;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
border-radius: 0.4vw;
box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.15);
}
.map-members .mapping-list .mapping-item:hover {
background: #f2f2f2;
@@ -37,7 +37,7 @@
}
.map-members .mapping-list .wekan {
display: inline-block;
width: 35px;
width: 4.5vw;
}
.map-members .mapping-list .wekan .member {
float: none;
+300 -24
View File
@@ -9,7 +9,7 @@
float: left;
}
[id^="swimlane-"] .list:first-child {
min-width: 20px;
min-width: 2.5vw;
}
.list.list-auto-width {
flex: 1;
@@ -33,7 +33,7 @@
background-color: rgba(0,0,0,0.2);
border-color: transparent;
box-shadow: none;
height: 100px;
height: 15vh;
}
.list.list-collapsed {
flex: none;
@@ -45,24 +45,24 @@
.list.list-composer .list-name-input,
.list .list-composer .list-name-input {
background: #fff;
margin: -3px 0 8px;
margin: -0.4vh 0 1vh;
}
.list-header-add {
flex: 0 0 auto;
padding: 12px;
padding: 1.5vh 1.5vw;
position: relative;
min-height: 20px;
min-height: 2.5vh;
}
.list-header {
flex: 0 0 auto;
padding: 20px 12px 4px;
padding: 2.5vh 1.5vw 0.5vh;
position: relative;
min-height: 20px;
min-height: 2.5vh;
background-color: #e4e4e4;
border-bottom: 6px solid #e4e4e4;
border-bottom: 0.8vh solid #e4e4e4;
}
.list-header.list-header-card-count {
min-height: 35px;
min-height: 4.5vh;
height: auto;
}
.list-header.ui-sortable-handle {
@@ -73,21 +73,21 @@
}
.list-header .list-header-name {
display: inline;
font-size: 16px;
line-height: 17px;
font-size: clamp(14px, 3vw, 18px);
line-height: 1.2;
margin: 0;
font-weight: bold;
min-height: 9px;
min-width: 30px;
min-height: 1.2vh;
min-width: 4vw;
overflow: hidden;
text-overflow: ellipsis;
word-wrap: break-word;
}
.list-rotated {
width: 10px;
height: 250px;
margin-top: -90px;
margin-left: -110px;
width: 1.3vw;
height: 35vh;
margin-top: -12vh;
margin-left: -14vw;
margin-right: 0;
transform: rotate(90deg);
position: relative;
@@ -214,11 +214,137 @@
#js-list-width-edit .list-width-error {
display: none;
}
/* Mobile view styles - applied when isMiniScreen is true (iPhone, etc.) */
.mini-list.mobile-view {
flex: 0 0 60px;
height: auto;
width: 100%;
min-width: 100%;
border-left: 0px;
border-bottom: 1px solid #ccc;
}
.list.mobile-view {
display: contents;
flex-basis: auto;
width: 100%;
min-width: 100%;
border-left: 0px;
}
.list.mobile-view:first-child {
margin-left: 0px;
}
.list.mobile-view.ui-sortable-helper {
flex: 0 0 60px;
height: 60px;
width: 100%;
border-left: 0px;
border-bottom: 1px solid #ccc;
}
.list.mobile-view.ui-sortable-helper .list-header.ui-sortable-handle {
cursor: grabbing;
}
.list.mobile-view.placeholder {
flex: 0 0 60px;
height: 60px;
width: 100%;
border-left: 0px;
border-bottom: 1px solid #ccc;
}
.list.mobile-view .list-body {
padding: 15px 19px;
width: 100%;
min-width: 100%;
}
.list.mobile-view .list-header {
/*Updated padding values for mobile devices, this should fix text grouping issue*/
padding: 20px 0px 20px 0px;
border-bottom: 0px solid #e4e4e4;
min-height: 30px;
margin-top: 10px;
align-items: center;
width: 100%;
min-width: 100%;
/* Force grid layout for iPhone */
display: grid !important;
grid-template-columns: 30px 1fr auto auto !important;
gap: 10px !important;
}
.list.mobile-view .list-header .list-header-left-icon {
padding: 7px;
padding-right: 27px;
margin-top: 1px;
top: -7px;
left: -7px;
}
.list.mobile-view .list-header .list-header-menu-icon {
padding: 14px;
font-size: 40px !important;
text-align: center;
/* Force positioning for iPhone */
position: absolute !important;
right: 60px !important;
top: 50% !important;
transform: translateY(-50%) !important;
z-index: 10;
}
.list.mobile-view .list-header .list-header-handle {
padding: 14px;
font-size: 48px !important;
text-align: center;
/* Force positioning for iPhone */
position: absolute !important;
right: 10px !important;
top: 50% !important;
transform: translateY(-50%) !important;
z-index: 10;
}
.list.mobile-view .list-header .list-header-left-icon {
display: grid;
grid-row: 1/3;
grid-column: 1;
}
.list.mobile-view .list-header .list-header-name {
grid-row: 1;
grid-column: 2;
align-self: end;
font-size: 20px !important;
font-weight: bold;
line-height: 1.2;
padding-bottom: 2px;
}
.list.mobile-view .list-header .cardCount {
grid-row: 2;
grid-column: 2;
align-self: start;
font-size: 16px !important;
line-height: 1.2;
}
.list.mobile-view .list-header .list-header-menu {
grid-row: 1/3;
grid-column: 3;
}
.list.mobile-view .list-header .list-header-menu-icon {
grid-row: 1/3;
grid-column: 3;
}
.list.mobile-view .list-header .list-header-handle {
grid-row: 1/3;
grid-column: 4;
}
.list.mobile-view .list-header .inlined-form {
grid-row: 1/3;
grid-column: 1/4;
}
.list.mobile-view .list-header .edit-controls {
align-items: initial;
}
@media screen and (max-width: 800px) {
.mini-list {
flex: 0 0 60px;
height: auto;
width: 100%;
min-width: 100%;
border-left: 0px;
border-bottom: 1px solid #ccc;
}
@@ -226,6 +352,7 @@
display: contents;
flex-basis: auto;
width: 100%;
min-width: 100%;
border-left: 0px;
}
.list:first-child {
@@ -250,6 +377,8 @@
}
.list-body {
padding: 15px 19px;
width: 100%;
min-width: 100%;
}
.list-header {
/*Updated padding values for mobile devices, this should fix text grouping issue*/
@@ -258,6 +387,8 @@
min-height: 30px;
margin-top: 10px;
align-items: center;
width: 100%;
min-width: 100%;
}
.list-header .list-header-left-icon {
padding: 7px;
@@ -267,24 +398,29 @@
left: -7px;
}
.list-header .list-header-menu-icon {
padding: 14px;
font-size: 40px;
text-align: center;
/* iOS Safari fallback positioning */
position: absolute;
padding: 7px;
right: 60px;
top: 50%;
transform: translateY(-50%);
right: 47px;
font-size: 20px;
}
.list-header .list-header-handle {
padding: 14px;
font-size: 48px;
text-align: center;
/* iOS Safari fallback positioning */
position: absolute;
padding: 7px;
right: 10px;
top: 50%;
transform: translateY(-50%);
right: 10px;
font-size: 24px;
}
.list-header {
display: grid;
grid-template-columns: 30px 5fr 1fr;
grid-template-columns: 30px 1fr auto auto;
gap: 10px;
}
.list-header .list-header-left-icon {
display: grid;
@@ -295,16 +431,30 @@
grid-row: 1;
grid-column: 2;
align-self: end;
font-size: 20px;
font-weight: bold;
line-height: 1.2;
padding-bottom: 2px;
}
.list-header .cardCount {
grid-row: 2;
grid-column: 2;
align-self: start;
font-size: 16px;
line-height: 1.2;
}
.list-header .list-header-menu {
grid-row: 1/3;
grid-column: 3;
}
.list-header .list-header-menu-icon {
grid-row: 1/3;
grid-column: 3;
}
.list-header .list-header-handle {
grid-row: 1/3;
grid-column: 4;
}
.list-header .inlined-form {
grid-row: 1/3;
grid-column: 1/4;
@@ -313,6 +463,132 @@
align-items: initial;
}
}
/* iPhone 12 Mini specific - fix icon positioning in stacked lists view */
@media screen and (device-width: 375px) and (device-height: 812px), /* iPhone 12 Mini exact */
screen and (max-width: 375px) and (max-height: 812px), /* iPhone 12 Mini viewport */
screen and (-webkit-min-device-pixel-ratio: 3) and (max-width: 375px) /* iPhone 12 Mini Retina */ {
.list.mobile-view .list-header {
/* Force grid layout for iPhone 12 Mini */
display: grid !important;
grid-template-columns: 30px 1fr auto auto !important;
gap: 10px !important;
align-items: center !important;
}
.list.mobile-view .list-header .list-header-menu-icon {
/* Remove absolute positioning for iPhone 12 Mini */
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
/* Use grid positioning */
grid-row: 1/3 !important;
grid-column: 3 !important;
padding: 14px !important;
font-size: 40px !important;
text-align: center !important;
}
.list.mobile-view .list-header .list-header-handle {
/* Remove absolute positioning for iPhone 12 Mini */
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
/* Use grid positioning */
grid-row: 1/3 !important;
grid-column: 4 !important;
padding: 14px !important;
font-size: 48px !important;
text-align: center !important;
}
.list.mobile-view .list-header .list-header-name {
grid-row: 1 !important;
grid-column: 2 !important;
align-self: end !important;
font-size: 20px !important;
font-weight: bold !important;
line-height: 1.2 !important;
padding-bottom: 2px !important;
}
.list.mobile-view .list-header .cardCount {
grid-row: 2 !important;
grid-column: 2 !important;
align-self: start !important;
font-size: 16px !important;
line-height: 1.2 !important;
}
.list.mobile-view .list-header .list-header-left-icon {
display: grid !important;
grid-row: 1/3 !important;
grid-column: 1 !important;
}
}
/* iPhone device JavaScript detection fallback - fix icon positioning */
.iphone-device .list.mobile-view .list-header {
/* Force grid layout for iPhone devices */
display: grid !important;
grid-template-columns: 30px 1fr auto auto !important;
gap: 10px !important;
align-items: center !important;
}
.iphone-device .list.mobile-view .list-header .list-header-menu-icon {
/* Remove absolute positioning for iPhone devices */
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
/* Use grid positioning */
grid-row: 1/3 !important;
grid-column: 3 !important;
padding: 14px !important;
font-size: 40px !important;
text-align: center !important;
}
.iphone-device .list.mobile-view .list-header .list-header-handle {
/* Remove absolute positioning for iPhone devices */
position: static !important;
right: auto !important;
top: auto !important;
transform: none !important;
/* Use grid positioning */
grid-row: 1/3 !important;
grid-column: 4 !important;
padding: 14px !important;
font-size: 48px !important;
text-align: center !important;
}
.iphone-device .list.mobile-view .list-header .list-header-name {
grid-row: 1 !important;
grid-column: 2 !important;
align-self: end !important;
font-size: 20px !important;
font-weight: bold !important;
line-height: 1.2 !important;
padding-bottom: 2px !important;
}
.iphone-device .list.mobile-view .list-header .cardCount {
grid-row: 2 !important;
grid-column: 2 !important;
align-self: start !important;
font-size: 16px !important;
line-height: 1.2 !important;
}
.iphone-device .list.mobile-view .list-header .list-header-left-icon {
display: grid !important;
grid-row: 1/3 !important;
grid-column: 1 !important;
}
.link-board-wrapper {
display: flex;
align-items: baseline;
+2 -2
View File
@@ -1,10 +1,10 @@
template(name='list')
.list.js-list(id="js-list-{{_id}}"
style="{{#unless collapsed}}min-width:{{listWidth}}px;max-width:{{listConstraint}}px;{{/unless}}"
class="{{#if collapsed}}list-collapsed{{/if}} {{#if autoWidth}}list-auto-width{{/if}}")
class="{{#if collapsed}}list-collapsed{{/if}} {{#if autoWidth}}list-auto-width{{/if}} {{#if isMiniScreen}}mobile-view{{/if}}")
+listHeader
+listBody
template(name='miniList')
a.mini-list.js-select-list.js-list(id="js-list-{{_id}}")
a.mini-list.js-select-list.js-list(id="js-list-{{_id}}" class="{{#if isMiniScreen}}mobile-view{{/if}}")
+listHeader
+9 -5
View File
@@ -314,7 +314,8 @@ BlazeComponent.extendComponent({
// 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();
// Prevent custom focus movement on Tab key for accessibility
// evt.preventDefault();
const isReverse = evt.shiftKey;
const list = $(`#js-list-${this.data().listId}`);
const listSelector = '.js-list:not(.js-list-composer)';
@@ -413,13 +414,16 @@ BlazeComponent.extendComponent({
// or `Enter` to validation the auto-completion. We also need to stop the
// event propagation to prevent the card from submitting (on `Enter`) or
// going on the next column (on `Tab`).
/*
onKeydown(evt, commands) {
if (evt.keyCode === 9 || evt.keyCode === 13) {
evt.stopPropagation();
return commands.KEY_ENTER;
}
// Prevent custom focus movement on Tab key for accessibility
// if (evt.keyCode === 9 || evt.keyCode === 13) {
// evt.stopPropagation();
// return commands.KEY_ENTER;
//}
return null;
},
*/
},
);
},
+43 -18
View File
@@ -1,27 +1,27 @@
.my-cards-board-wrapper {
border-radius: 0 0 4px 4px;
min-width: 400px;
margin-bottom: 2rem;
border-radius: 0 0 0.5vw 0.5vw;
min-width: min(400px, 52vw);
margin-bottom: 2.5vh;
margin-right: auto;
margin-left: auto;
border-width: 2px;
border-width: 0.3vw;
border-style: solid;
border-color: #a2a2a2;
}
.my-cards-board-title {
font-size: 1.4rem;
font-size: clamp(1.2rem, 3vw, 1.6rem);
font-weight: bold;
padding: 0.5rem;
padding: 0.7vh 0.7vw;
background-color: #808080;
color: #fff;
}
.my-cards-swimlane-title {
font-size: 1.1rem;
font-size: clamp(1rem, 2.5vw, 1.3rem);
font-weight: bold;
padding: 0.5rem;
padding-bottom: 0.4rem;
padding: 0.7vh 0.7vw;
padding-bottom: 0.5vh;
margin-top: 0;
margin-bottom: 0.5rem;
margin-bottom: 0.7vh;
text-align: center;
}
.swimlane-default-color {
@@ -29,23 +29,23 @@
}
.my-cards-list-title {
font-weight: bold;
font-size: 1.1rem;
font-size: clamp(1rem, 2.5vw, 1.3rem);
text-align: center;
margin-bottom: 0.7rem;
margin-bottom: 0.9vh;
}
.my-cards-list-wrapper {
margin: 1rem;
border-radius: 5px;
margin: 1.3vh 1.3vw;
border-radius: 0.7vw;
display: inline-grid;
min-width: 250px;
max-width: 350px;
min-width: min(250px, 32vw);
max-width: min(350px, 45vw);
}
.my-cards-card-wrapper {
margin-top: 0;
margin-bottom: 10px;
margin-bottom: 1.3vh;
}
.my-cards-dueat-list-wrapper {
max-width: 500px;
max-width: min(500px, 65vw);
margin-right: auto;
margin-left: auto;
}
@@ -72,3 +72,28 @@
border-radius: 5px;
margin-right: 5px;
}
/* Accessibility page styles */
.accessibility-page {
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
.accessibility-page h2 {
font-size: 24px;
margin-bottom: 20px;
color: #4d4d4d;
}
.accessibility-page-content {
background-color: #fff;
padding: 20px;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}
.accessibility-page-content p {
margin-bottom: 16px;
line-height: 1.6;
}
+12 -2
View File
@@ -1,8 +1,18 @@
template(name="accessibilityHeaderBar")
if currentUser
h1
| {{_ 'accessibility-title'}}
if isAccessibilityEnabled
= accessibilityTitle
else
| {{_ 'accessibility'}}
template(name="accessibility")
if currentUser
| {{_ 'accessibility-content'}}
.accessibility-page
if isAccessibilityEnabled
.accessibility-page-content
+viewer
| {{accessibilityContent}}
else
.accessibility-page-content
| {{_ 'accessibility-info-not-added-yet'}}
+27
View File
@@ -1,11 +1,38 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
// Shared helpers for both accessibility templates
const accessibilityHelpers = {
accessibilityTitle() {
const setting = AccessibilitySettings.findOne({});
return setting && setting.title ? setting.title : TAPi18n.__('accessibility-title');
},
accessibilityContent() {
const setting = AccessibilitySettings.findOne({});
return setting && setting.body ? setting.body : TAPi18n.__('accessibility-content');
},
isAccessibilityEnabled() {
const setting = AccessibilitySettings.findOne({});
return setting && setting.enabled;
}
};
// Main accessibility page component
BlazeComponent.extendComponent({
onCreated() {
this.error = new ReactiveVar('');
this.loading = new ReactiveVar(false);
Meteor.subscribe('setting');
Meteor.subscribe('accessibilitySettings');
},
...accessibilityHelpers
}).register('accessibility');
// Header bar component
BlazeComponent.extendComponent({
onCreated() {
Meteor.subscribe('accessibilitySettings');
},
...accessibilityHelpers
}).register('accessibilityHeaderBar');
+5 -5
View File
@@ -1,15 +1,15 @@
.broken-cards-card-wrapper {
margin-top: 0;
margin-bottom: 10px;
border-width: 3px !important;
margin-bottom: 1.3vh;
border-width: 0.4vw !important;
border-color: #808080 !important;
border-style: solid;
border-radius: 5px;
padding: 1.5rem;
border-radius: 0.7vw;
padding: 2vh 2vw;
background-color: #fff;
}
.broken-cards-wrapper {
max-width: 500px;
max-width: min(500px, 65vw);
margin-right: auto;
margin-left: auto;
}
+1 -1
View File
@@ -1,5 +1,5 @@
.due-cards-dueat-list-wrapper {
max-width: 500px;
max-width: min(500px, 65vw);
margin-right: auto;
margin-left: auto;
}
+7 -12
View File
@@ -79,7 +79,6 @@ BlazeComponent.extendComponent({
autosize($textarea);
$textarea.escapeableTextComplete(mentions);
};
/*
if (Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR === true || Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR === 'true') {
const isSmall = Utils.isMiniScreen();
const toolbar = isSmall
@@ -117,7 +116,7 @@ BlazeComponent.extendComponent({
].join('|');
const badPatterns = new RegExp(
`(?:${[
`<(${badTags})s*[^>][\\s\\S]*?<\\/\\1>`,
`<(${badTags})\\s*[^>][\\s\\S]*?<\\/\\1>`,
`<(${badTags})[^>]*?\\/>`,
].join('|')})`,
'gi',
@@ -128,9 +127,9 @@ BlazeComponent.extendComponent({
// remove attributes ' style="..."'
const badAttributes = new RegExp(
`(?:${[
'on\\S+=([\'"]?).*?\\1',
'href=([\'"]?)javascript:.*?\\2',
'style=([\'"]?).*?\\3',
'on\\S+=([\'\"]?).*?\\1',
'href=([\'\"]?)javascript:.*?\\2',
'style=([\'\"]?).*?\\3',
'target=\\S+',
].join('|')})`,
'gi',
@@ -300,7 +299,6 @@ BlazeComponent.extendComponent({
} else {
enableTextarea();
}
*/
enableTextarea();
},
events() {
@@ -327,6 +325,7 @@ BlazeComponent.extendComponent({
}).register('editor');
import DOMPurify from 'dompurify';
import { sanitizeHTML } from '/imports/lib/secureDOMPurify';
// Additional safeAttrValue function to allow for other specific protocols
// See https://github.com/leizongmin/js-xss/issues/52#issuecomment-241354114
@@ -373,9 +372,7 @@ Blaze.Template.registerHelper(
let content = Blaze.toHTML(view.templateContentBlock);
const currentBoard = Utils.getCurrentBoard();
if (!currentBoard)
return HTML.Raw(
DOMPurify.sanitize(content, { ALLOW_UNKNOWN_PROTOCOLS: true }),
);
return HTML.Raw(sanitizeHTML(content));
const knowedUsers = _.union(currentBoard.members.map(member => {
const u = ReactiveCache.getUser(member.userId);
if (u) {
@@ -419,9 +416,7 @@ Blaze.Template.registerHelper(
content = content.replace(fullMention, Blaze.toHTML(link));
}
return HTML.Raw(
DOMPurify.sanitize(content, { ALLOW_UNKNOWN_PROTOCOLS: true }),
);
return HTML.Raw(sanitizeHTML(content));
}),
);
+864 -6
View File
@@ -99,7 +99,36 @@
display: flex;
z-index: 1000;
padding: 10px 0px;
align-items: center;
flex-wrap: wrap; /* Allow wrapping on mobile */
min-height: 28px; /* Allow height to grow */
}
#header-quick-access .home-icon {
display: flex;
align-items: center;
margin-right: 1rem;
flex-shrink: 0;
}
#header-quick-access .home-icon a {
display: flex;
align-items: center;
text-decoration: none;
color: #fff;
padding: 4px 8px;
border-radius: 4px;
transition: background-color 0.2s ease;
}
#header-quick-access .home-icon a:hover {
background-color: rgba(255, 255, 255, 0.1);
}
#header-quick-access .home-icon .fa-home {
font-size: 16px;
margin-right: 4px;
}
#header-quick-access .allBoards {
font-size: 14px;
padding: 4px 15px;
@@ -196,6 +225,197 @@
margin: 4px 8px 0 0;
float: left;
}
/* Zoom Controls in Header */
#header-quick-access .zoom-controls {
display: flex;
align-items: center;
gap: 0.5vw;
background: rgba(255, 255, 255, 0.9);
padding: 0.5vh 1vw;
border-radius: 0.5vw;
box-shadow: 0 0.2vh 0.5vh rgba(0,0,0,0.1);
margin: 0 1vw;
float: left;
}
#header-quick-access .zoom-controls .board-header-btn {
padding: 0.5vh 0.8vw !important;
border-radius: 0.3vw !important;
background: #fff !important;
border: 1px solid #000 !important;
transition: all 0.2s ease !important;
color: #000 !important;
height: auto !important;
line-height: normal !important;
margin: 0 !important;
float: none !important;
overflow: visible !important;
text-decoration: none !important;
display: flex !important;
align-items: center !important;
gap: 0.3vw !important;
}
#header-quick-access .zoom-controls .board-header-btn i {
color: #000 !important;
float: none !important;
display: inline !important;
line-height: normal !important;
margin: 0 !important;
}
#header-quick-access .zoom-controls .board-header-btn:hover {
background: #000 !important;
border-color: #000 !important;
color: #fff !important;
}
#header-quick-access .zoom-controls .board-header-btn:hover i {
color: #fff !important;
}
#header-quick-access .zoom-controls .zoom-level {
font-weight: bold;
color: #333;
min-width: 3vw;
text-align: center;
font-size: clamp(12px, 2vw, 14px);
cursor: pointer;
padding: 0.3vh 0.5vw;
border-radius: 0.3vw;
transition: all 0.2s ease;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
#header-quick-access .zoom-controls .zoom-level:hover {
background: #f0f0f0;
color: #000;
}
#header-quick-access .zoom-controls .zoom-display {
display: inline-block;
}
#header-quick-access .zoom-controls .zoom-input {
background: #fff;
color: #000;
border: 1px solid #ccc;
border-radius: 0.3vw;
padding: 0.3vh 0.5vw;
font-weight: bold;
text-align: center;
width: 100%;
min-width: 3vw;
font-size: clamp(12px, 2vw, 14px);
}
/* Make zoom input wider on all mobile screens */
@media screen and (max-width: 800px) {
#header-quick-access .zoom-controls .zoom-input {
min-width: 50px !important; /* Wider on mobile */
width: 50px !important; /* Fixed width to show all numbers */
font-size: 14px !important; /* Slightly larger text */
}
}
#header-quick-access .zoom-controls .zoom-input:focus {
outline: 2px solid #005fcc;
outline-offset: 1px;
}
/* Mobile Mode Toggle in Header */
#header-quick-access .mobile-mode-toggle {
display: flex;
align-items: center;
margin: 0 1vw;
float: left;
}
#header-quick-access .mobile-mode-toggle .board-header-btn {
padding: 0.5vh 0.8vw !important;
border-radius: 0.3vw !important;
background: #fff !important;
border: 1px solid #000 !important;
transition: all 0.2s ease !important;
color: #000 !important;
height: auto !important;
line-height: normal !important;
margin: 0 !important;
float: none !important;
overflow: visible !important;
text-decoration: none !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
gap: 6px !important;
position: relative !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn i {
color: #666 !important;
float: none !important;
display: inline !important;
line-height: normal !important;
margin: 0 !important;
transition: all 0.2s ease !important;
font-size: clamp(14px, 2.8vw, 18px) !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn i.active {
color: #000 !important;
font-weight: bold !important;
transform: scale(1.1) !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn:hover {
background: #000 !important;
border-color: #000 !important;
color: #fff !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn:hover i {
color: #ccc !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn:hover i.active {
color: #fff !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn.mobile-active {
background: #fff !important;
border-color: #000 !important;
color: #000 !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn.mobile-active i.mobile-icon {
color: #000 !important;
font-weight: bold !important;
transform: scale(1.1) !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn.mobile-active i.desktop-icon {
color: #666 !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn.desktop-active {
background: #fff !important;
border-color: #000 !important;
color: #000 !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn.desktop-active i.mobile-icon {
color: #666 !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn.desktop-active i.desktop-icon {
color: #000 !important;
font-weight: bold !important;
transform: scale(1.1) !important;
}
#header-quick-access #header-user-bar .header-user-bar-name i.fa-chevron-down {
margin-right: 4px;
}
@@ -227,6 +447,650 @@
width: 100%;
z-index: 30;
}
/* Mobile home icon styling */
#header-quick-access .home-icon {
margin-right: 0.5rem;
}
#header-quick-access .home-icon .fa-home {
font-size: 16px;
margin-right: 4px;
}
#header-quick-access .home-icon a {
padding: 4px 8px;
font-size: 12px;
}
/* Ensure All Boards text is visible on mobile */
#header-quick-access .home-icon.allBoards {
display: flex;
align-items: center;
}
/* Adjust for very small screens */
@media screen and (max-width: 480px) {
#header-quick-access .home-icon a {
font-size: 11px;
padding: 3px 6px;
}
#header-quick-access .home-icon .fa-home {
font-size: 14px;
margin-right: 3px;
}
}
/* Mobile - make all text and icons 2x bigger above #content by default */
@media screen and (max-width: 800px),
screen and (max-device-width: 800px),
screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px),
screen and (max-width: 800px) and (orientation: portrait),
screen and (max-width: 800px) and (orientation: landscape) {
#header-quick-access {
height: auto !important; /* Allow height to grow */
min-height: 48px !important; /* Minimum height for mobile */
flex-wrap: wrap !important; /* Force wrapping */
align-items: flex-start !important; /* Align to top when wrapping */
padding: 8px 0px !important; /* Adjust padding for mobile */
}
#header-quick-access {
font-size: 2em !important; /* 2x bigger base font size */
}
#header-quick-access * {
font-size: inherit !important; /* Inherit the 2x scaling */
}
#header-quick-access .fa,
#header-quick-access .icon {
font-size: 2em !important; /* 2x bigger icons */
}
#header-quick-access .home-icon a {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .home-icon .fa-home {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .zoom-controls {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .zoom-controls .zoom-level {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .zoom-controls .zoom-input {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .mobile-mode-toggle .board-header-btn {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .mobile-mode-toggle .board-header-btn i {
font-size: 1em !important; /* Use inherited 2x scaling */
}
/* Mobile header wrapping and spacing */
#header-quick-access .home-icon {
flex-shrink: 0 !important;
margin-right: 0.5rem !important;
margin-bottom: 4px !important;
}
#header-quick-access .zoom-controls {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
}
#header-quick-access .mobile-mode-toggle {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
}
#header-quick-access #notifications {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
}
#header-quick-access #header-user-bar {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
}
#header-quick-access ul.header-quick-access-list {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
width: auto !important;
}
}
/* Mobile All Boards page - make logo row elements 2x bigger */
@media screen and (max-width: 800px),
screen and (max-device-width: 800px),
screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px),
screen and (max-width: 800px) and (orientation: portrait),
screen and (max-width: 800px) and (orientation: landscape) {
.wrapper ~ #header-quick-access,
body:not(.board-view) #header-quick-access {
font-size: 2em !important; /* 2x bigger base font size for logo row */
}
/* iPhone 12 Mini specific - 3x bigger for All Boards page */
@media screen and (device-width: 375px) and (device-height: 812px), /* iPhone 12 Mini exact */
screen and (max-width: 375px) and (max-height: 812px), /* iPhone 12 Mini viewport */
screen and (-webkit-min-device-pixel-ratio: 3) and (max-width: 375px) /* iPhone 12 Mini Retina */ {
.wrapper ~ #header-quick-access,
body:not(.board-view) #header-quick-access {
font-size: 3em !important; /* 3x bigger base font size for iPhone 12 Mini All Boards page */
}
}
.wrapper ~ #header-quick-access *,
body:not(.board-view) #header-quick-access * {
font-size: inherit !important; /* Inherit the 2x scaling */
}
.wrapper ~ #header-quick-access .fa,
.wrapper ~ #header-quick-access .icon,
body:not(.board-view) #header-quick-access .fa,
body:not(.board-view) #header-quick-access .icon {
font-size: 2em !important; /* 2x bigger icons in logo row */
}
.wrapper ~ #header-quick-access .home-icon a,
body:not(.board-view) #header-quick-access .home-icon a {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access .home-icon .fa-home,
body:not(.board-view) #header-quick-access .home-icon .fa-home {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access .zoom-controls,
body:not(.board-view) #header-quick-access .zoom-controls {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access .zoom-controls .zoom-level,
body:not(.board-view) #header-quick-access .zoom-controls .zoom-level {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access .zoom-controls .zoom-input,
body:not(.board-view) #header-quick-access .zoom-controls .zoom-input {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access .mobile-mode-toggle .board-header-btn,
body:not(.board-view) #header-quick-access .mobile-mode-toggle .board-header-btn {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access .mobile-mode-toggle .board-header-btn i,
body:not(.board-view) #header-quick-access .mobile-mode-toggle .board-header-btn i {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access #notifications,
body:not(.board-view) #header-quick-access #notifications {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access #notifications .fa,
body:not(.board-view) #header-quick-access #notifications .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access #header-user-bar,
body:not(.board-view) #header-quick-access #header-user-bar {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.wrapper ~ #header-quick-access #header-user-bar .fa,
body:not(.board-view) #header-quick-access #header-user-bar .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
}
/* iPhone 12 Mini specific - make header elements 3x bigger */
@media screen and (device-width: 375px) and (device-height: 812px), /* iPhone 12 Mini exact */
screen and (max-width: 375px) and (max-height: 812px), /* iPhone 12 Mini viewport */
screen and (-webkit-min-device-pixel-ratio: 3) and (max-width: 375px), /* iPhone 12 Mini Retina */
screen and (max-width: 375px) and (orientation: portrait), /* iPhone 12 Mini portrait */
screen and (max-width: 375px) and (orientation: landscape) /* iPhone 12 Mini landscape */ {
#header-quick-access {
font-size: 3em !important; /* 3x bigger base font size for iPhone 12 Mini */
height: auto !important; /* Allow height to grow */
min-height: 84px !important; /* Much taller minimum height for iPhone 12 Mini */
flex-wrap: wrap !important; /* Force wrapping */
align-items: flex-start !important; /* Align to top when wrapping */
padding: 18px 0px !important; /* More padding for iPhone 12 Mini */
}
#header-quick-access * {
font-size: inherit !important; /* Inherit the 2x scaling */
}
#header-quick-access .fa,
#header-quick-access .icon {
font-size: 3em !important; /* 3x bigger icons for iPhone 12 Mini */
}
#header-quick-access .home-icon a {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .home-icon .fa-home {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .zoom-controls {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .zoom-controls .zoom-level {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .zoom-controls .zoom-input {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .mobile-mode-toggle .board-header-btn {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access .mobile-mode-toggle .board-header-btn i {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access #notifications {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access #notifications .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access #header-user-bar {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access #header-user-bar .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
/* iPhone 12 Mini header wrapping and spacing */
#header-quick-access .home-icon {
flex-shrink: 0 !important;
margin-right: 0.5rem !important;
margin-bottom: 6px !important;
}
#header-quick-access .zoom-controls {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
}
#header-quick-access .mobile-mode-toggle {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
}
#header-quick-access #notifications {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
}
#header-quick-access #header-user-bar {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
}
#header-quick-access ul.header-quick-access-list {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
width: auto !important;
}
}
/* iPhone 12 Mini and very small screens - make header elements much larger */
@media screen and (max-width: 400px) and (max-height: 900px),
screen and (max-device-width: 400px) and (max-device-height: 900px),
screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 400px),
screen and (max-width: 400px) and (orientation: portrait),
screen and (max-width: 400px) and (orientation: landscape),
screen and (max-width: 430px) and (max-height: 950px), /* iPhone 12 Mini range */
screen and (max-width: 450px) and (max-height: 1000px), /* iPhone range */
screen and (-webkit-min-device-pixel-ratio: 3) and (max-width: 450px), /* Retina displays */
screen and (device-width: 375px) and (device-height: 812px), /* iPhone 12 Mini exact */
screen and (device-width: 390px) and (device-height: 844px), /* iPhone 12/13 */
screen and (device-width: 428px) and (device-height: 926px) /* iPhone 12 Pro Max */ {
#header-quick-access {
height: 40px !important; /* Taller header */
padding: 12px 0px !important;
}
#header-quick-access .home-icon a {
font-size: 16px !important; /* Much larger text */
padding: 8px 12px !important;
}
#header-quick-access .home-icon .fa-home {
font-size: 20px !important; /* Much larger icon */
margin-right: 6px !important;
}
#header-quick-access .home-icon {
margin-right: 1rem !important;
}
/* Make zoom controls larger */
#header-quick-access .zoom-controls {
padding: 0.8vh 1.5vw !important;
margin: 0 1.5vw !important;
}
#header-quick-access .zoom-controls .zoom-level {
font-size: 16px !important; /* Larger zoom text */
padding: 0.5vh 0.8vw !important;
min-width: 4vw !important;
}
#header-quick-access .zoom-controls .zoom-input {
font-size: 16px !important; /* Larger input text */
padding: 0.5vh 0.8vw !important;
min-width: 6vw !important; /* Much wider for mobile */
width: 60px !important; /* Fixed width to show all numbers */
}
/* Make mobile mode toggle larger */
#header-quick-access .mobile-mode-toggle .board-header-btn {
padding: 0.8vh 1.2vw !important;
font-size: 16px !important;
}
#header-quick-access .mobile-mode-toggle .board-header-btn i {
font-size: 18px !important;
}
}
/* Fallback for iPhone devices using JavaScript detection */
.iphone-device #header-quick-access {
font-size: 2em !important; /* 2x bigger base font size */
height: auto !important; /* Allow height to grow */
min-height: 48px !important; /* Minimum height for mobile */
flex-wrap: wrap !important; /* Force wrapping */
align-items: flex-start !important; /* Align to top when wrapping */
padding: 8px 0px !important; /* Adjust padding for mobile */
}
.iphone-device #header-quick-access * {
font-size: inherit !important; /* Inherit the 2x scaling */
}
.iphone-device #header-quick-access .fa,
.iphone-device #header-quick-access .icon {
font-size: 2em !important; /* 2x bigger icons */
}
.iphone-device #header-quick-access .home-icon a {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .home-icon .fa-home {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .zoom-controls {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .zoom-controls .zoom-level {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .zoom-controls .zoom-input {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .mobile-mode-toggle .board-header-btn {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .mobile-mode-toggle .board-header-btn i {
font-size: 1em !important; /* Use inherited 2x scaling */
}
/* iPhone device header wrapping and spacing */
.iphone-device #header-quick-access .home-icon {
flex-shrink: 0 !important;
margin-right: 0.5rem !important;
margin-bottom: 4px !important;
}
.iphone-device #header-quick-access .zoom-controls {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
}
.iphone-device #header-quick-access .mobile-mode-toggle {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
}
.iphone-device #header-quick-access #notifications {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
}
.iphone-device #header-quick-access #header-user-bar {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
}
.iphone-device #header-quick-access ul.header-quick-access-list {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 4px !important;
width: auto !important;
}
/* iPhone 12 Mini specific - JavaScript detection fallback */
.iphone-device #header-quick-access {
font-size: 3em !important; /* 3x bigger base font size for iPhone 12 Mini */
height: auto !important; /* Allow height to grow */
min-height: 84px !important; /* Much taller minimum height for iPhone 12 Mini */
flex-wrap: wrap !important; /* Force wrapping */
align-items: flex-start !important; /* Align to top when wrapping */
padding: 18px 0px !important; /* More padding for iPhone 12 Mini */
}
.iphone-device #header-quick-access * {
font-size: inherit !important; /* Inherit the 2x scaling */
}
.iphone-device #header-quick-access .fa,
.iphone-device #header-quick-access .icon {
font-size: 3em !important; /* 3x bigger icons for iPhone 12 Mini */
}
.iphone-device #header-quick-access .home-icon a {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .home-icon .fa-home {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .zoom-controls {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .zoom-controls .zoom-level {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .zoom-controls .zoom-input {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .mobile-mode-toggle .board-header-btn {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access .mobile-mode-toggle .board-header-btn i {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access #notifications {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access #notifications .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access #header-user-bar {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device #header-quick-access #header-user-bar .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
/* iPhone 12 Mini header wrapping and spacing - JavaScript fallback */
.iphone-device #header-quick-access .home-icon {
flex-shrink: 0 !important;
margin-right: 0.5rem !important;
margin-bottom: 6px !important;
}
.iphone-device #header-quick-access .zoom-controls {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
}
.iphone-device #header-quick-access .mobile-mode-toggle {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
}
.iphone-device #header-quick-access #notifications {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
}
.iphone-device #header-quick-access #header-user-bar {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
}
.iphone-device #header-quick-access ul.header-quick-access-list {
flex-shrink: 0 !important;
margin: 0 0.5rem !important;
margin-bottom: 6px !important;
width: auto !important;
}
/* iPhone 12 Mini All Boards page - make logo row elements 3x bigger */
.iphone-device .wrapper ~ #header-quick-access,
.iphone-device body:not(.board-view) #header-quick-access {
font-size: 3em !important; /* 3x bigger base font size for logo row */
}
.iphone-device .wrapper ~ #header-quick-access *,
.iphone-device body:not(.board-view) #header-quick-access * {
font-size: inherit !important; /* Inherit the 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access .fa,
.iphone-device .wrapper ~ #header-quick-access .icon,
.iphone-device body:not(.board-view) #header-quick-access .fa,
.iphone-device body:not(.board-view) #header-quick-access .icon {
font-size: 2em !important; /* 2x bigger icons in logo row */
}
.iphone-device .wrapper ~ #header-quick-access .home-icon a,
.iphone-device body:not(.board-view) #header-quick-access .home-icon a {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access .home-icon .fa-home,
.iphone-device body:not(.board-view) #header-quick-access .home-icon .fa-home {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access .zoom-controls,
.iphone-device body:not(.board-view) #header-quick-access .zoom-controls {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access .zoom-controls .zoom-level,
.iphone-device body:not(.board-view) #header-quick-access .zoom-controls .zoom-level {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access .zoom-controls .zoom-input,
.iphone-device body:not(.board-view) #header-quick-access .zoom-controls .zoom-input {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access .mobile-mode-toggle .board-header-btn,
.iphone-device body:not(.board-view) #header-quick-access .mobile-mode-toggle .board-header-btn {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access .mobile-mode-toggle .board-header-btn i,
.iphone-device body:not(.board-view) #header-quick-access .mobile-mode-toggle .board-header-btn i {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access #notifications,
.iphone-device body:not(.board-view) #header-quick-access #notifications {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access #notifications .fa,
.iphone-device body:not(.board-view) #header-quick-access #notifications .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access #header-user-bar,
.iphone-device body:not(.board-view) #header-quick-access #header-user-bar {
font-size: 1em !important; /* Use inherited 2x scaling */
}
.iphone-device .wrapper ~ #header-quick-access #header-user-bar .fa,
.iphone-device body:not(.board-view) #header-quick-access #header-user-bar .fa {
font-size: 1em !important; /* Use inherited 2x scaling */
}
#header-quick-access ul {
width: calc(100% - 60px);
margin-right: 10px;
@@ -237,12 +1101,6 @@
#header-quick-access ul li a {
height: 100%;
}
#header-quick-access span .fa-home {
font-size: 26px;
margin-top: -2px;
margin-right: 10px;
margin-left: 10px;
}
#header-quick-access #header-new-board-icon {
display: none;
}
+40 -33
View File
@@ -6,10 +6,31 @@ template(name="header")
The first link goes to the boards page.
if currentUser
#header-quick-access(class=currentBoard.colorClass)
// Home icon - always at left side of logo
span.home-icon.allBoards
a(href="{{pathFor 'home'}}")
span.fa.fa-home
| {{_ 'all-boards'}}
// Logo - always visible in desktop mode
unless currentSetting.hideLogo
if currentSetting.customTopLeftCornerLogoImageUrl
if currentSetting.customTopLeftCornerLogoLinkUrl
a(href="{{currentSetting.customTopLeftCornerLogoLinkUrl}}" alt="{{currentSetting.productName}}" title="{{currentSetting.productName}}")
img(src="{{currentSetting.customTopLeftCornerLogoImageUrl}}" height="{{#if currentSetting.customTopLeftCornerLogoHeight}}#{currentSetting.customTopLeftCornerLogoHeight}{{else}}27{{/if}}" width="auto" margin="0" padding="0")
unless currentSetting.customTopLeftCornerLogoLinkUrl
img(src="{{currentSetting.customTopLeftCornerLogoImageUrl}}" height="{{#if currentSetting.customTopLeftCornerLogoHeight}}#{currentSetting.customTopLeftCornerLogoHeight}{{else}}27{{/if}}" width="auto" margin="0" padding="0" alt="{{currentSetting.productName}}" title="{{currentSetting.productName}}")
unless currentSetting.customTopLeftCornerLogoImageUrl
div#headerIsSettingDatabaseCallDone
img(src="{{pathFor '/logo-header.png'}}" alt="{{currentSetting.productName}}" title="{{currentSetting.productName}}")
// Zoom controls - always visible
.zoom-controls
span.zoom-level.js-zoom-level-click(title="{{_ 'click-to-change-zoom'}}")
span.zoom-display {{zoomLevel}}%
input.zoom-input.js-zoom-input(type="number" value=zoomLevel min="50" max="300" step="10" style="display: none;")
if isMiniScreen
span
a(href="{{pathFor 'home'}}")
span.fa.fa-home
ul.header-quick-access-list
if currentList
each currentBoard.lists
@@ -23,32 +44,14 @@ template(name="header")
a(href="{{pathFor 'board' id=_id slug=slug}}")
+viewer
= title
a.js-toggle-desktop-drag-handles(title="{{_ 'show-desktop-drag-handles'}}" alt="{{_ 'show-desktop-drag-handles'}}")
i.fa.fa-arrows
if isShowDesktopDragHandles
i.fa.fa-check-square-o
unless isShowDesktopDragHandles
i.fa.fa-ban
//a.js-toggle-desktop-drag-handles(title="{{_ 'show-desktop-drag-handles'}}" alt="{{_ 'show-desktop-drag-handles'}}")
// i.fa.fa-arrows
// if isShowDesktopDragHandles
// i.fa.fa-check-square-o
// unless isShowDesktopDragHandles
// i.fa.fa-ban
#header-new-board-icon
else
//-
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.
unless currentSetting.hideLogo
if currentSetting.customTopLeftCornerLogoImageUrl
if currentSetting.customTopLeftCornerLogoLinkUrl
a(href="{{currentSetting.customTopLeftCornerLogoLinkUrl}}" alt="{{currentSetting.productName}}" title="{{currentSetting.productName}}")
img(src="{{currentSetting.customTopLeftCornerLogoImageUrl}}" height="{{#if currentSetting.customTopLeftCornerLogoHeight}}#{currentSetting.customTopLeftCornerLogoHeight}{{else}}27{{/if}}" width="auto" margin="0" padding="0")
unless currentSetting.customTopLeftCornerLogoLinkUrl
img(src="{{currentSetting.customTopLeftCornerLogoImageUrl}}" height="{{#if currentSetting.customTopLeftCornerLogoHeight}}#{currentSetting.customTopLeftCornerLogoHeight}{{else}}27{{/if}}" width="auto" margin="0" padding="0" alt="{{currentSetting.productName}}" title="{{currentSetting.productName}}")
unless currentSetting.customTopLeftCornerLogoImageUrl
div#headerIsSettingDatabaseCallDone
img(src="{{pathFor '/logo-header.png'}}" alt="{{currentSetting.productName}}" title="{{currentSetting.productName}}")
span.allBoards
a(href="{{pathFor 'home'}}")
span.fa.fa-home
| {{_ 'all-boards'}}
ul.header-quick-access-list
//li
// a(href="{{pathFor 'public'}}")
@@ -61,12 +64,12 @@ template(name="header")
= title
else
li.current.empty {{_ 'quick-access-description'}}
a.js-toggle-desktop-drag-handles(title="{{_ 'show-desktop-drag-handles'}}" alt="{{_ 'show-desktop-drag-handles'}}")
i.fa.fa-arrows
if isShowDesktopDragHandles
i.fa.fa-check-square-o
unless isShowDesktopDragHandles
i.fa.fa-ban
//a.js-toggle-desktop-drag-handles(title="{{_ 'show-desktop-drag-handles'}}" alt="{{_ 'show-desktop-drag-handles'}}")
// i.fa.fa-arrows
// if isShowDesktopDragHandles
// i.fa.fa-check-square-o
// unless isShowDesktopDragHandles
// i.fa.fa-ban
// Next line is used only for spacing at header,
// there is no visible clickable icon.
#header-new-board-icon
@@ -75,6 +78,10 @@ template(name="header")
//a#header-new-board-icon.js-create-board
// i.fa.fa-plus(title="Create a new board")
.mobile-mode-toggle
a.board-header-btn.js-mobile-mode-toggle(title="{{_ 'mobile-desktop-toggle'}}" class="{{#if mobileMode}}mobile-active{{else}}desktop-active{{/if}}")
i.fa.fa-mobile.mobile-icon(class="{{#if mobileMode}}active{{/if}}")
i.fa.fa-desktop.desktop-icon(class="{{#unless mobileMode}}active{{/unless}}")
+notifications
if currentSetting.customHelpLinkUrl
+56
View File
@@ -44,10 +44,66 @@ Template.header.helpers({
const announcements = Announcements.findOne();
return announcements && announcements.body;
},
zoomLevel() {
const sessionZoom = Session.get('wekan-zoom-level');
if (sessionZoom !== undefined) {
return Math.round(sessionZoom * 100);
}
return Math.round(Utils.getZoomLevel() * 100);
},
mobileMode() {
const sessionMode = Session.get('wekan-mobile-mode');
if (sessionMode !== undefined) {
return sessionMode;
}
return Utils.getMobileMode();
},
});
Template.header.events({
'click .js-create-board': Popup.open('headerBarCreateBoard'),
'click .js-zoom-level-click'(evt) {
const $zoomDisplay = $(evt.currentTarget).find('.zoom-display');
const $zoomInput = $(evt.currentTarget).find('.zoom-input');
// Hide display, show input
$zoomDisplay.hide();
$zoomInput.show().focus().select();
},
'keypress .js-zoom-input'(evt) {
if (evt.which === 13) { // Enter key
const newZoomPercent = parseInt(evt.target.value);
if (!isNaN(newZoomPercent) && newZoomPercent >= 50 && newZoomPercent <= 300) {
const newZoom = newZoomPercent / 100;
Utils.setZoomLevel(newZoom);
// Hide input, show display
const $zoomDisplay = $(evt.target).siblings('.zoom-display');
const $zoomInput = $(evt.target);
$zoomInput.hide();
$zoomDisplay.show();
} else {
alert('Please enter a zoom level between 50% and 300%');
evt.target.focus().select();
}
}
},
'blur .js-zoom-input'(evt) {
// When input loses focus, hide it and show display
const $zoomDisplay = $(evt.target).siblings('.zoom-display');
const $zoomInput = $(evt.target);
$zoomInput.hide();
$zoomDisplay.show();
},
'click .js-mobile-mode-toggle'() {
const currentMode = Utils.getMobileMode();
Utils.setMobileMode(!currentMode);
},
'click .js-close-announcement'() {
$('.announcement').hide();
},
+63 -55
View File
@@ -52,15 +52,19 @@ input,
select,
textarea,
button {
font: 14px Roboto, Poppins, "Helvetica Neue", Arial, Helvetica, sans-serif;
line-height: 18px;
font: clamp(12px, 2.5vw, 16px) Roboto, Poppins, "Helvetica Neue", Arial, Helvetica, sans-serif;
line-height: 1.3;
color: #4d4d4d;
}
html {
font-size: 100%;
max-height: 100%;
user-select: none;
-webkit-user-select: text;
user-select: text;
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
}
body {
background: #dedede;
@@ -81,8 +85,8 @@ body {
margin-top: 30vh;
}
#content > .wrapper {
margin-top: 10px;
padding: 15px;
margin-top: 1vh;
padding: 2vh 2vw;
}
#modal {
position: absolute;
@@ -95,56 +99,56 @@ body {
overflow-y: auto;
}
#modal .modal-content {
width: 500px;
min-height: 160px;
margin: 42px auto;
padding: 12px;
border-radius: 4px;
width: min(500px, 90vw);
min-height: 20vh;
margin: 5vh auto;
padding: 2vh 2vw;
border-radius: 0.5vw;
background: #dedede;
z-index: 110;
}
#modal .modal-content h2 {
margin-bottom: 25px;
margin-bottom: 3vh;
}
#modal .modal-content .modal-close-btn {
display: block;
float: right;
font-size: 24px;
font-size: clamp(18px, 4vw, 24px);
}
#modal .modal-content-wide {
width: 800px;
width: min(800px, 95vw);
min-height: 0px;
margin: 42px auto;
padding: 12px;
border-radius: 4px;
margin: 5vh auto;
padding: 2vh 2vw;
border-radius: 0.5vw;
background: #dedede;
z-index: 110;
}
#modal .modal-content-wide h2 {
margin-bottom: 25px;
margin-bottom: 3vh;
}
#modal .modal-content-wide .modal-close-btn {
display: block;
float: right;
font-size: 24px;
font-size: clamp(18px, 4vw, 24px);
}
h1 {
font-size: 22px;
font-size: clamp(18px, 4vw, 24px);
line-height: 1.2em;
margin: 0 0 10px;
margin: 0 0 1vh;
}
h2 {
font-size: 18px;
font-size: clamp(16px, 3.5vw, 20px);
line-height: 1.2em;
margin: 0 0 9px;
margin: 0 0 0.8vh;
}
h3,
h4,
h5,
h6 {
font-size: 16px;
font-size: clamp(14px, 3vw, 18px);
line-height: 1.25em;
margin: 0 0 6px;
margin: 0 0 0.6vh;
}
.quiet,
.quiet a {
@@ -156,14 +160,14 @@ h6 {
}
.no-items-message {
color: #666;
margin: 30px 0;
margin: 4vh 0;
text-align: center;
}
.warning {
background: #f0ecdb;
border-radius: 3px;
border-radius: 0.4vw;
color: #aa8f09;
padding: 6px 8px;
padding: 1vh 1.2vw;
}
.warning a {
color: #aa8f09;
@@ -188,7 +192,10 @@ strong {
font-weight: bold;
}
p {
-webkit-user-select: text;
user-select: text;
}
p a {
text-decoration: underline;
@@ -196,24 +203,24 @@ p a {
}
table,
p {
margin-bottom: 8px;
margin-bottom: 1vh;
}
pre {
margin: 15px 0;
margin: 2vh 0;
white-space: pre;
max-height: 516px;
max-height: 60vh;
}
pre,
code,
tt {
font-family: lucida console, monospace;
line-height: 1.25em;
line-height: 1.3em;
}
blockquote {
margin: 8px 0 8px 8px;
margin: 1vh 0 1vh 1vw;
border-left: 1px solid #ccc;
color: #666;
padding: 0 0 0 8px;
padding: 0 0 0 1vw;
}
hr {
height: 1px;
@@ -222,7 +229,7 @@ hr {
width: 100%;
background: #dbdbdb;
color: #dbdbdb;
margin: 15px 0;
margin: 2vh 0;
padding: 0;
}
table,
@@ -234,7 +241,7 @@ th {
}
td,
th {
padding: 5px;
padding: 0.8vh 0.8vw;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}
@@ -250,20 +257,20 @@ tbody {
}
dl,
dt {
margin-bottom: 8px;
margin-bottom: 1vh;
}
dd {
margin: 0 0 16px 24px;
margin: 0 0 2vh 3vw;
}
kbd {
padding: 1px 3px;
margin: 3px;
padding: 0.2vh 0.5vw;
margin: 0.5vh;
font-weight: bold;
background: #fafafa;
border-radius: 3px;
border-radius: 0.4vw;
border: 1px solid #e6e6e6;
color: unset;
box-shadow: 0px 2px 3px rgba(0,0,0,0.15);
box-shadow: 0px 0.3vh 0.5vh rgba(0,0,0,0.15);
}
.clear {
clear: both;
@@ -303,7 +310,7 @@ kbd {
padding-bottom: 0;
}
.wrapper {
width: calc(100% - 20px);
width: calc(100% - 2vw);
margin: 0 auto;
}
.relative {
@@ -394,23 +401,23 @@ a:not(.disabled).is-active i.fa {
}
.big-message {
display: block;
margin: 75px auto;
margin: 10vh auto;
text-align: center;
max-width: 600px;
max-width: min(600px, 90vw);
}
.big-message h1 {
font-size: 26px;
margin-bottom: 24px;
font-size: clamp(20px, 5vw, 28px);
margin-bottom: 3vh;
}
.big-message p {
font-size: 18px;
line-height: 22px;
font-size: clamp(16px, 3.5vw, 20px);
line-height: 1.3;
}
.gutter {
margin-left: 38px;
margin-left: 5vw;
}
.viewer {
min-height: 18px;
min-height: 2.5vh;
display: block;
word-wrap: break-word;
}
@@ -420,18 +427,19 @@ a:not(.disabled).is-active i.fa {
}
.viewer ol {
list-style-type: decimal;
padding-left: 20px;
padding-bottom: 10px;
padding-left: 3vw;
padding-bottom: 1.5vh;
}
.viewer ul {
list-style-type: initial;
padding-left: 20px;
padding-bottom: 10px;
padding-left: 3vw;
padding-bottom: 1.5vh;
}
.viewer em {
font-style: italic;
}
.viewer pre {
.viewer pre,
.viewer code {
padding: 10px 12px 7px;
background: #dedede;
overflow-y: auto;
+25 -20
View File
@@ -1,22 +1,24 @@
head
title
meta(name="viewport" content="width=device-width, initial-scale=1")
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
difficult to do that cleanly with Blaze -- at least without adding extra
packages.
link(rel="shortcut icon" type="image/x-icon" href="/favicon.ico")
link(rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png")
link(rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png")
link(rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png")
link(rel="manifest" crossOrigin="use-credentials" href="/site.webmanifest")
link(rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5")
meta(name="apple-mobile-web-app-title" content="Wekan")
meta(name="application-name" content="Wekan")
meta(name="msapplication-TileColor" content="#00aba9")
meta(name="theme-color" content="#ffffff")
//link(rel="stylesheet" type="text/css" class="__meteor-css__" href="css/html5-default-theme.css")
template(name="main")
html(lang="{{TAPi18n.getLanguage}}")
head
title
meta(name="viewport" content="width=device-width, initial-scale=1")
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
difficult to do that cleanly with Blaze -- at least without adding extra
packages.
link(rel="shortcut icon" type="image/x-icon" href="/favicon.ico")
link(rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png")
link(rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png")
link(rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png")
link(rel="manifest" crossOrigin="use-credentials" href="/site.webmanifest")
link(rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5")
meta(name="apple-mobile-web-app-title" content="Wekan")
meta(name="application-name" content="Wekan")
meta(name="msapplication-TileColor" content="#00aba9")
meta(name="theme-color" content="#ffffff")
//link(rel="stylesheet" type="text/css" class="__meteor-css__" href="css/html5-default-theme.css")
template(name="userFormsLayout")
section.auth-layout
@@ -48,6 +50,8 @@ template(name="userFormsLayout")
if isLoading
+loader
else
// ARIA live region for error messages
div#login-error-message(role="alert" aria-live="assertive" style="color: #d32f2f; margin-bottom: 1em;")
+Template.dynamic(template=content)
if currentSetting.displayAuthenticationMethod
+connectionMethod(authenticationMethod=currentSetting.defaultAuthenticationMethod)
@@ -59,7 +63,8 @@ template(name="userFormsLayout")
if getLegalNoticeWithWritTraduction
div
div.at-form-lang
select.select-lang.js-userform-set-language
label(for="userform-set-language-select") {{_ 'changeLanguagePopup-title'}}
select.select-lang.js-userform-set-language#userform-set-language-select(aria-label="{{_ 'changeLanguagePopup-title'}}")
each languages
if isCurrentLanguage
option(value="{{tag}}" selected="selected") {{name}}
+6
View File
@@ -86,6 +86,12 @@ Template.userFormsLayout.onRendered(() => {
validator,
);
EscapeActions.executeAll();
// Add autocomplete attribute to login input for WCAG compliance
const loginInput = document.querySelector('input[type="text"], input[type="email"]');
if (loginInput && loginInput.name && (loginInput.name.toLowerCase().includes('user') || loginInput.name.toLowerCase().includes('email'))) {
loginInput.setAttribute('autocomplete', 'username email');
}
});
});
+18 -18
View File
@@ -1,27 +1,27 @@
.my-cards-board-wrapper {
border-radius: 0 0 4px 4px;
min-width: 400px;
margin-bottom: 2rem;
border-radius: 0 0 0.5vw 0.5vw;
min-width: min(400px, 52vw);
margin-bottom: 2.5vh;
margin-right: auto;
margin-left: auto;
border-width: 2px;
border-width: 0.3vw;
border-style: solid;
border-color: #a2a2a2;
}
.my-cards-board-title {
font-size: 1.4rem;
font-size: clamp(1.2rem, 3vw, 1.6rem);
font-weight: bold;
padding: 0.5rem;
padding: 0.7vh 0.7vw;
background-color: #808080;
color: #fff;
}
.my-cards-swimlane-title {
font-size: 1.1rem;
font-size: clamp(1rem, 2.5vw, 1.3rem);
font-weight: bold;
padding: 0.5rem;
padding-bottom: 0.4rem;
padding: 0.7vh 0.7vw;
padding-bottom: 0.5vh;
margin-top: 0;
margin-bottom: 0.5rem;
margin-bottom: 0.7vh;
text-align: center;
}
.swimlane-default-color {
@@ -29,23 +29,23 @@
}
.my-cards-list-title {
font-weight: bold;
font-size: 1.1rem;
font-size: clamp(1rem, 2.5vw, 1.3rem);
text-align: center;
margin-bottom: 0.7rem;
margin-bottom: 0.9vh;
}
.my-cards-list-wrapper {
margin: 1rem;
border-radius: 5px;
margin: 1.3vh 1.3vw;
border-radius: 0.7vw;
display: inline-grid;
min-width: 250px;
max-width: 350px;
min-width: min(250px, 32vw);
max-width: min(350px, 45vw);
}
.my-cards-card-wrapper {
margin-top: 0;
margin-bottom: 10px;
margin-bottom: 1.3vh;
}
.my-cards-dueat-list-wrapper {
max-width: 500px;
max-width: min(500px, 65vw);
margin-right: auto;
margin-left: auto;
}
+22 -22
View File
@@ -1,16 +1,16 @@
.pop-over {
background: #fff;
border-radius: 3px;
border-radius: 0.4vw;
border: 1px solid #dbdbdb;
border-bottom-color: #c2c2c2;
box-shadow: 0 1px 6px rgba(0,0,0,0.3);
box-shadow: 0 0.2vh 0.8vh rgba(0,0,0,0.3);
position: absolute;
width: 300px;
width: min(300px, 40vw);
z-index: 99999;
margin-top: 5px;
margin-top: 0.7vh;
}
.pop-over hr {
margin: 4px 0px;
margin: 0.5vh 0px;
}
.pop-over p,
.pop-over textarea,
@@ -22,27 +22,27 @@
}
.pop-over select {
width: 100%;
margin-bottom: 14px;
margin-bottom: 1.8vh;
}
.pop-over textarea {
height: 72px;
height: 9vh;
}
.pop-over form a span {
padding: 0 0.5rem;
padding: 0 0.7vw;
}
.pop-over .header {
height: 36px;
height: 4.5vh;
position: relative;
margin-bottom: 8px;
margin-bottom: 1vh;
background: #f7f7f7;
border-bottom: 1px solid #dcdcdc;
color: #666;
}
.pop-over .header .header-title {
display: block;
line-height: 32px;
padding-top: 4px;
margin: 0 10px;
line-height: 4vh;
padding-top: 0.5vh;
margin: 0 1.3vw;
font-weight: bold;
overflow: hidden;
text-overflow: ellipsis;
@@ -51,18 +51,18 @@
.pop-over .header .back-btn {
float: left;
overflow: hidden;
width: 30px;
width: 4vw;
transition: width 0.2s;
}
.pop-over .header .back-btn i.fa {
margin: 10px;
margin-top: 12px;
margin: 1.3vw;
margin-top: 1.5vh;
}
.pop-over .header .back-btn.is-hidden {
width: 0;
}
.pop-over .header .close-btn {
padding: 10px 10px 10px 4px;
padding: 1.3vh 1.3vw 1.3vh 0.5vw;
position: absolute;
top: 0;
right: 0;
@@ -76,23 +76,23 @@
}
.pop-over .content-container {
width: 5000px;
max-height: 550px;
max-height: 70vh;
transition: transform 0.2s;
}
.pop-over .content-container .content {
width: 280px;
padding: 0 10px 10px;
width: min(280px, 37vw);
padding: 0 1.3vw 1.3vh;
float: left;
}
.pop-over .content-container .content.no-height {
height: 20px;
height: 2.5vh;
}
.pop-over .quiet {
/* padding: 6px 6px 4px;*/
}
.pop-over.search-over {
background: #f0f0f0;
min-height: 114px;
min-height: 14vh;
}
.pop-over.search-over .header {
display: none;
@@ -4,7 +4,7 @@
#notifications-drawer .notification {
display: flex;
float: none;
padding: 15px 8px 8px;
padding: 2vh 1vw 1vh;
color: #000;
border-bottom: 1px solid #dbdbdb;
}
@@ -12,18 +12,18 @@
display: none;
}
#notifications-drawer .notification .read-status {
width: 30px;
padding: 0px 10px 0px 0px;
width: 4vw;
padding: 0 1.3vw 0 0;
}
#notifications-drawer .notification .read-status input {
width: 24px;
height: 24px;
width: 3vw;
height: 3vw;
}
#notifications-drawer .notification .read-status .activity-type {
margin: 16px 0 0;
width: 17px;
height: 17px;
font-size: 17px;
margin: 2vh 0 0;
width: 2.2vw;
height: 2.2vw;
font-size: clamp(14px, 2.5vw, 17px);
display: block;
color: #bbb;
}
@@ -32,20 +32,20 @@
padding: 0px;
}
#notifications-drawer .notification .details .activity a.member svg {
padding: 3px;
padding: 0.4vw;
}
#notifications-drawer .notification .details .activity .activity-desc {
margin: 0px 0px 0px 5px;
margin: 0 0 0 0.7vw;
}
#notifications-drawer .notification .details .activity .activity-comment {
display: block;
width: 100%;
border-radius: 3px;
border-radius: 0.4vw;
background: #fff;
text-decoration: none;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
margin-top: 5px;
padding: 5px;
box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.2);
margin-top: 0.7vh;
padding: 0.7vh 0.7vw;
}
#notifications-drawer .notification .details .activity .activity-meta {
display: block;
+5 -5
View File
@@ -1,8 +1,8 @@
.rules-list {
overflow: hidden;
overflow-y: scroll;
max-height: 400px;
padding-right: 5px;
max-height: 50vh;
padding-right: 0.7vw;
}
.rules-lists-item {
display: block;
@@ -33,14 +33,14 @@
.rules-add {
display: block;
overflow: auto;
margin-top: 15px;
margin-bottom: 5px;
margin-top: 2vh;
margin-bottom: 0.7vh;
}
.rules-add input {
display: inline-block;
float: right;
margin: auto;
margin-right: 10px;
margin-right: 1.3vw;
}
.rules-add button {
display: inline-block;
@@ -0,0 +1,47 @@
.text-red {
color: #e74c3c;
}
td i.fa-lock.text-red,
li i.fa-lock.text-red {
margin-right: 5px;
}
.locked-users-table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
}
.locked-users-table th,
.locked-users-table td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.locked-users-table th {
background-color: #f2f2f2;
font-weight: bold;
}
.locked-users-table tr:hover {
background-color: #f5f5f5;
}
.loading-indicator {
padding: 10px;
text-align: center;
}
.loading-indicator i {
margin-right: 5px;
}
.locked-users-settings {
padding: 0 10px;
}
button.js-unlock-all-users {
margin-bottom: 20px;
}
@@ -0,0 +1,175 @@
import { ReactiveCache } from '/imports/reactiveCache';
import LockoutSettings from '/models/lockoutSettings';
BlazeComponent.extendComponent({
onCreated() {
this.lockedUsers = new ReactiveVar([]);
this.isLoadingLockedUsers = new ReactiveVar(false);
// Don't load immediately to prevent unnecessary spinner
// The data will be loaded when the tab is selected in peopleBody.js switchMenu
},
refreshLockedUsers() {
// Set loading state initially, but we'll hide it if no users are found
this.isLoadingLockedUsers.set(true);
Meteor.call('getLockedUsers', (err, users) => {
if (err) {
this.isLoadingLockedUsers.set(false);
const reason = err.reason || '';
const message = `${TAPi18n.__(err.error)}\n${reason}`;
alert(message);
return;
}
// If no users are locked, don't show loading spinner and set empty array
if (!users || users.length === 0) {
this.isLoadingLockedUsers.set(false);
this.lockedUsers.set([]);
return;
}
// Format the remaining time to be more human-readable
users.forEach(user => {
if (user.remainingLockTime > 60) {
const minutes = Math.floor(user.remainingLockTime / 60);
const seconds = user.remainingLockTime % 60;
user.remainingTimeFormatted = `${minutes}m ${seconds}s`;
} else {
user.remainingTimeFormatted = `${user.remainingLockTime}s`;
}
});
this.lockedUsers.set(users);
this.isLoadingLockedUsers.set(false);
});
},
unlockUser(event) {
const userId = $(event.currentTarget).data('user-id');
if (!userId) return;
if (confirm(TAPi18n.__('accounts-lockout-confirm-unlock'))) {
Meteor.call('unlockUser', userId, (err, result) => {
if (err) {
const reason = err.reason || '';
const message = `${TAPi18n.__(err.error)}\n${reason}`;
alert(message);
return;
}
if (result) {
alert(TAPi18n.__('accounts-lockout-user-unlocked'));
this.refreshLockedUsers();
}
});
}
},
unlockAllUsers() {
if (confirm(TAPi18n.__('accounts-lockout-confirm-unlock-all'))) {
Meteor.call('unlockAllUsers', (err, result) => {
if (err) {
const reason = err.reason || '';
const message = `${TAPi18n.__(err.error)}\n${reason}`;
alert(message);
return;
}
if (result) {
alert(TAPi18n.__('accounts-lockout-user-unlocked'));
this.refreshLockedUsers();
}
});
}
},
saveLockoutSettings() {
// Get values from form
const knownFailuresBeforeLockout = parseInt($('#known-failures-before-lockout').val(), 10) || 3;
const knownLockoutPeriod = parseInt($('#known-lockout-period').val(), 10) || 60;
const knownFailureWindow = parseInt($('#known-failure-window').val(), 10) || 15;
const unknownFailuresBeforeLockout = parseInt($('#unknown-failures-before-lockout').val(), 10) || 3;
const unknownLockoutPeriod = parseInt($('#unknown-lockout-period').val(), 10) || 60;
const unknownFailureWindow = parseInt($('#unknown-failure-window').val(), 10) || 15;
// Update the database
LockoutSettings.update('known-failuresBeforeLockout', {
$set: { value: knownFailuresBeforeLockout },
});
LockoutSettings.update('known-lockoutPeriod', {
$set: { value: knownLockoutPeriod },
});
LockoutSettings.update('known-failureWindow', {
$set: { value: knownFailureWindow },
});
LockoutSettings.update('unknown-failuresBeforeLockout', {
$set: { value: unknownFailuresBeforeLockout },
});
LockoutSettings.update('unknown-lockoutPeriod', {
$set: { value: unknownLockoutPeriod },
});
LockoutSettings.update('unknown-failureWindow', {
$set: { value: unknownFailureWindow },
});
// Reload the AccountsLockout configuration
Meteor.call('reloadAccountsLockout', (err, ret) => {
if (!err && ret) {
const message = TAPi18n.__('accounts-lockout-settings-updated');
alert(message);
} else {
const reason = err?.reason || '';
const message = `${TAPi18n.__(err?.error || 'error-updating-settings')}\n${reason}`;
alert(message);
}
});
},
knownFailuresBeforeLockout() {
return LockoutSettings.findOne('known-failuresBeforeLockout')?.value || 3;
},
knownLockoutPeriod() {
return LockoutSettings.findOne('known-lockoutPeriod')?.value || 60;
},
knownFailureWindow() {
return LockoutSettings.findOne('known-failureWindow')?.value || 15;
},
unknownFailuresBeforeLockout() {
return LockoutSettings.findOne('unknown-failuresBeforeLockout')?.value || 3;
},
unknownLockoutPeriod() {
return LockoutSettings.findOne('unknown-lockoutPeriod')?.value || 60;
},
unknownFailureWindow() {
return LockoutSettings.findOne('unknown-failureWindow')?.value || 15;
},
lockedUsers() {
return this.lockedUsers.get();
},
isLoadingLockedUsers() {
return this.isLoadingLockedUsers.get();
},
events() {
return [
{
'click button.js-refresh-locked-users': this.refreshLockedUsers,
'click button#refreshLockedUsers': this.refreshLockedUsers,
'click button.js-unlock-user': this.unlockUser,
'click button.js-unlock-all-users': this.unlockAllUsers,
'click button.js-lockout-save': this.saveLockoutSettings,
},
];
},
}).register('lockedUsersGeneral');
+91
View File
@@ -89,3 +89,94 @@ table tr:nth-child(even) {
#deleteAction {
margin-left: 5% !important;
}
.divLockedUsersFilter {
display: flex;
align-items: center;
margin: 0 15px;
}
.divLockedUsersFilter .flex-container {
display: flex;
align-items: center;
gap: 8px;
}
.divLockedUsersFilter .people-filter {
margin-bottom: 0;
color: #777;
line-height: 34px;
}
.divLockedUsersFilter .user-filter {
border: 1px solid #ccc;
border-radius: 2px;
padding: 4px 8px;
background-color: white;
}
.unlock-all-btn {
margin-left: 15px;
background-color: white;
color: #4d4d4d;
border: 1px solid rgba(0,0,0,.15);
border-radius: 2px;
padding: 0 10px;
cursor: pointer;
display: flex;
align-items: center;
gap: 5px;
height: 28px;
min-width: 90px;
/* box-shadow: 0 1px 6px rgba(0,0,0,.3); */
}
.unlock-all-btn:hover {
background-color: #f2f2f2;
}
.account-active-status {
width: 20px;
text-align: center;
}
.js-toggle-active-status {
cursor: pointer;
}
.unlock-all-success {
position: fixed;
top: 10%;
left: 50%;
transform: translateX(-50%);
background-color: #27ae60;
color: white;
padding: 10px 20px;
border-radius: 4px;
z-index: 9999;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
animation: fadeOut 3s ease-in forwards;
}
@keyframes fadeOut {
0% { opacity: 1; }
70% { opacity: 1; }
100% { opacity: 0; }
}
.account-status {
width: 20px;
text-align: center;
}
.text-green {
color: #27ae60;
}
.js-toggle-lock-status {
cursor: pointer;
}
.unlock-all-btn .fa {
color: #4d4d4d;
}
@@ -38,12 +38,28 @@ template(name="people")
button#searchButton
i.fa.fa-search
| {{_ 'search'}}
.divLockedUsersFilter
.flex-container
span.people-filter {{_ 'admin-people-filter-show'}}
select.user-filter#userFilterSelect
option(value="all") {{_ 'admin-people-filter-all'}}
option(value="locked") {{_ 'admin-people-filter-locked'}}
option(value="active") {{_ 'admin-people-filter-active'}}
option(value="inactive") {{_ 'admin-people-filter-inactive'}}
button#unlockAllUsers.unlock-all-btn
i.fa.fa-unlock
| {{_ 'accounts-lockout-unlock-all'}}
.ext-box-right
span {{#unless isMiniScreen}}{{_ 'people-number'}}{{/unless}} #{peopleNumber}
.divAddOrRemoveTeam#divAddOrRemoveTeam
button#addOrRemoveTeam
i.fa.fa-edit
| {{_ 'add'}} / {{_ 'delete'}} {{_ 'teams'}}
else if lockedUsersSetting.get
span
i.fa.fa-lock.text-red
unless isMiniScreen
| {{_ 'accounts-lockout-locked-users'}}
.content-body
.side-menu
@@ -60,6 +76,10 @@ template(name="people")
a.js-people-menu(data-id="people-setting")
i.fa.fa-user
| {{_ 'people'}}
li
a.js-locked-users-menu(data-id="locked-users-setting")
i.fa.fa-lock.text-red
| {{_ 'accounts-lockout-locked-users'}}
.main-body
if loading.get
+spinner
@@ -69,6 +89,8 @@ template(name="people")
+teamGeneral
else if peopleSetting.get
+peopleGeneral
else if lockedUsersSetting.get
+lockedUsersGeneral
template(name="orgGeneral")
@@ -114,6 +136,8 @@ template(name="peopleGeneral")
tr
th
+selectAllUser
th {{_ 'accounts-lockout-status'}}
th {{_ 'admin-people-active-status'}}
th {{_ 'username'}}
th {{_ 'fullname'}}
th {{_ 'initials'}}
@@ -232,8 +256,20 @@ template(name="peopleRow")
else
td
input.selectUserChkBox(type="checkbox", id="{{userData._id}}")
td.account-status
if isUserLocked
i.fa.fa-lock.text-red.js-toggle-lock-status(data-user-id=userData._id, data-is-locked="true", title="{{_ 'accounts-lockout-click-to-unlock'}}")
else
i.fa.fa-unlock.text-green.js-toggle-lock-status(data-user-id=userData._id, data-is-locked="false", title="{{_ 'accounts-lockout-user-unlocked'}}")
td.account-active-status
if userData.loginDisabled
i.fa.fa-ban.text-red.js-toggle-active-status(data-user-id=userData._id, data-is-active="false", title="{{_ 'admin-people-user-inactive'}}")
else
i.fa.fa-check-circle.text-green.js-toggle-active-status(data-user-id=userData._id, data-is-active="true", title="{{_ 'admin-people-user-active'}}")
if userData.loginDisabled
td.username <s>{{ userData.username }}</s>
else if isUserLocked
td.username {{ userData.username }}
else
td.username {{ userData.username }}
if userData.loginDisabled
@@ -645,3 +681,32 @@ template(name="settingsUserPopup")
// that does now remove member from board, card members and assignees correctly,
// but that should be used to remove user from all boards similarly
// - wekan/models/users.js Delete is not enabled
template(name="lockedUsersGeneral")
.locked-users-settings
h3 {{_ 'accounts-lockout-settings'}}
p {{_ 'accounts-lockout-info'}}
h4 {{_ 'accounts-lockout-known-users'}}
.title {{_ 'accounts-lockout-failures-before'}}
.form-group
input.wekan-form-control#known-failures-before-lockout(type="number", min="1", max="10", placeholder="3" value="{{knownFailuresBeforeLockout}}")
.title {{_ 'accounts-lockout-period'}}
.form-group
input.wekan-form-control#known-lockout-period(type="number", min="10", max="600", placeholder="60" value="{{knownLockoutPeriod}}")
.title {{_ 'accounts-lockout-failure-window'}}
.form-group
input.wekan-form-control#known-failure-window(type="number", min="1", max="60", placeholder="15" value="{{knownFailureWindow}}")
h4 {{_ 'accounts-lockout-unknown-users'}}
.title {{_ 'accounts-lockout-failures-before'}}
.form-group
input.wekan-form-control#unknown-failures-before-lockout(type="number", min="1", max="10", placeholder="3" value="{{unknownFailuresBeforeLockout}}")
.title {{_ 'accounts-lockout-period'}}
.form-group
input.wekan-form-control#unknown-lockout-period(type="number", min="10", max="600", placeholder="60" value="{{unknownLockoutPeriod}}")
.title {{_ 'accounts-lockout-failure-window'}}
.form-group
input.wekan-form-control#unknown-failure-window(type="number", min="1", max="60", placeholder="15" value="{{unknownFailureWindow}}")
button.js-lockout-save.primary {{_ 'save'}}
+170 -24
View File
@@ -1,4 +1,5 @@
import { ReactiveCache } from '/imports/reactiveCache';
import LockoutSettings from '/models/lockoutSettings';
const orgsPerPage = 25;
const teamsPerPage = 25;
@@ -14,14 +15,16 @@ BlazeComponent.extendComponent({
this.error = new ReactiveVar('');
this.loading = new ReactiveVar(false);
this.orgSetting = new ReactiveVar(true);
this.teamSetting = new ReactiveVar(true);
this.peopleSetting = new ReactiveVar(true);
this.teamSetting = new ReactiveVar(false);
this.peopleSetting = new ReactiveVar(false);
this.lockedUsersSetting = new ReactiveVar(false);
this.findOrgsOptions = new ReactiveVar({});
this.findTeamsOptions = new ReactiveVar({});
this.findUsersOptions = new ReactiveVar({});
this.numberOrgs = new ReactiveVar(0);
this.numberTeams = new ReactiveVar(0);
this.numberPeople = new ReactiveVar(0);
this.userFilterType = new ReactiveVar('all');
this.page = new ReactiveVar(1);
this.loadNextPageLocked = false;
@@ -92,6 +95,34 @@ BlazeComponent.extendComponent({
this.filterPeople();
}
},
'change #userFilterSelect'(event) {
const filterType = $(event.target).val();
this.userFilterType.set(filterType);
this.filterPeople();
},
'click #unlockAllUsers'(event) {
event.preventDefault();
if (confirm(TAPi18n.__('accounts-lockout-confirm-unlock-all'))) {
Meteor.call('unlockAllUsers', (error) => {
if (error) {
console.error('Error unlocking all users:', error);
} else {
// Show a brief success message
const message = document.createElement('div');
message.className = 'unlock-all-success';
message.textContent = TAPi18n.__('accounts-lockout-all-users-unlocked');
document.body.appendChild(message);
// Remove the message after a short delay
setTimeout(() => {
if (message.parentNode) {
message.parentNode.removeChild(message);
}
}, 3000);
}
});
}
},
'click #newOrgButton'() {
Popup.open('newOrg');
},
@@ -104,23 +135,50 @@ BlazeComponent.extendComponent({
'click a.js-org-menu': this.switchMenu,
'click a.js-team-menu': this.switchMenu,
'click a.js-people-menu': this.switchMenu,
'click a.js-locked-users-menu': this.switchMenu,
},
];
},
filterPeople() {
const value = $('#searchInput').first().val();
if (value === '') {
this.findUsersOptions.set({});
} else {
const filterType = this.userFilterType.get();
const currentTime = Number(new Date());
let query = {};
// Apply text search filter if there's a search value
if (value !== '') {
const regex = new RegExp(value, 'i');
this.findUsersOptions.set({
query = {
$or: [
{ username: regex },
{ 'profile.fullname': regex },
{ 'emails.address': regex },
],
});
};
}
// Apply filter based on selected option
switch (filterType) {
case 'locked':
// Show only locked users
query['services.accounts-lockout.unlockTime'] = { $gt: currentTime };
break;
case 'active':
// Show only active users (loginDisabled is false or undefined)
query['loginDisabled'] = { $ne: true };
break;
case 'inactive':
// Show only inactive users (loginDisabled is true)
query['loginDisabled'] = true;
break;
case 'all':
default:
// Show all users, no additional filter
break;
}
this.findUsersOptions.set(query);
},
loadNextPage() {
if (this.loadNextPageLocked === false) {
@@ -186,6 +244,16 @@ BlazeComponent.extendComponent({
this.orgSetting.set('org-setting' === targetID);
this.teamSetting.set('team-setting' === targetID);
this.peopleSetting.set('people-setting' === targetID);
this.lockedUsersSetting.set('locked-users-setting' === targetID);
// When switching to locked users tab, refresh the locked users list
if ('locked-users-setting' === targetID) {
// Find the lockedUsersGeneral component and call refreshLockedUsers
const lockedUsersComponent = Blaze.getView($('.main-body')[0])._templateInstance;
if (lockedUsersComponent && lockedUsersComponent.refreshLockedUsers) {
lockedUsersComponent.refreshLockedUsers();
}
}
}
},
}).register('people');
@@ -206,8 +274,36 @@ Template.peopleRow.helpers({
userData() {
return ReactiveCache.getUser(this.userId);
},
isUserLocked() {
const user = ReactiveCache.getUser(this.userId);
if (!user) return false;
// Check if user has accounts-lockout with unlockTime property
if (user.services &&
user.services['accounts-lockout'] &&
user.services['accounts-lockout'].unlockTime) {
// Check if unlockTime is in the future
const currentTime = Number(new Date());
return user.services['accounts-lockout'].unlockTime > currentTime;
}
return false;
}
});
// Initialize filter dropdown
Template.people.rendered = function() {
const template = this;
// Set the initial value of the dropdown
Tracker.afterFlush(function() {
if (template.findAll('#userFilterSelect').length) {
$('#userFilterSelect').val('all');
}
});
};
Template.editUserPopup.onCreated(function () {
this.authenticationMethods = new ReactiveVar([]);
this.errorMessage = new ReactiveVar('');
@@ -415,6 +511,49 @@ BlazeComponent.extendComponent({
else
document.getElementById("divAddOrRemoveTeam").style.display = 'none';
},
'click .js-toggle-active-status': function(ev) {
ev.preventDefault();
const userId = this.userId;
const user = ReactiveCache.getUser(userId);
if (!user) return;
// Toggle loginDisabled status
const isActive = !(user.loginDisabled === true);
// Update the user's active status
Users.update(userId, {
$set: {
loginDisabled: isActive
}
});
},
'click .js-toggle-lock-status': function(ev){
ev.preventDefault();
const userId = this.userId;
const user = ReactiveCache.getUser(userId);
if (!user) return;
// Check if user is currently locked
const isLocked = user.services &&
user.services['accounts-lockout'] &&
user.services['accounts-lockout'].unlockTime &&
user.services['accounts-lockout'].unlockTime > Number(new Date());
if (isLocked) {
// Unlock the user
Meteor.call('unlockUser', userId, (error) => {
if (error) {
console.error('Error unlocking user:', error);
}
});
} else {
// Lock the user - this is optional, you may want to only allow unlocking
// If you want to implement locking too, you would need a server method for it
// For now, we'll leave this as a no-op
}
},
},
];
},
@@ -1130,23 +1269,30 @@ Template.settingsUserPopup.events({
},
'click #deleteButton'(event) {
event.preventDefault();
Users.remove(this.userId);
/*
// Delete user is enabled, but you should remove user from all boards
// before deleting user, because there is possibility of leaving empty user avatars
// to boards. You can remove non-existing user ids manually from database,
// if that happens.
//. See:
// - wekan/client/components/settings/peopleBody.jade deleteButton
// - wekan/client/components/settings/peopleBody.js deleteButton
// - wekan/client/components/sidebar/sidebar.js Popup.afterConfirm('removeMember'
// that does now remove member from board, card members and assignees correctly,
// but that should be used to remove user from all boards similarly
// - wekan/models/users.js Delete is not enabled
//
//
*/
Popup.back();
// Use secure server method instead of direct client-side removal
Meteor.call('removeUser', this.userId, (error, result) => {
if (error) {
if (process.env.DEBUG === 'true') {
console.error('Error removing user:', error);
}
// Show error message to user
if (error.error === 'not-authorized') {
alert('You are not authorized to delete this user.');
} else if (error.error === 'user-not-found') {
alert('User not found.');
} else if (error.error === 'not-authorized' && error.reason === 'Cannot delete the last administrator') {
alert('Cannot delete the last administrator.');
} else {
alert('Error deleting user: ' + error.reason);
}
} else {
if (process.env.DEBUG === 'true') {
console.log('User deleted successfully:', result);
}
Popup.back();
}
});
},
});
+10 -10
View File
@@ -17,34 +17,34 @@
position: absolute;
}
.setting-content .content-title {
font-size: 20px;
font-size: clamp(16px, 3.5vw, 22px);
}
.setting-content .content-body {
display: flex;
padding-top: 15px;
padding-top: 2vh;
height: 100%;
gap: 10px;
gap: 1.3vw;
}
.setting-content .content-body .side-menu {
background-color: #f7f7f7;
border: 1px solid #f0f0f0;
border-radius: 4px;
width: 250px;
box-shadow: inset -1px -1px 3px rgba(0,0,0,0.05);
border-radius: 0.5vw;
width: min(250px, 32vw);
box-shadow: inset -0.2vh -0.2vh 0.4vh rgba(0,0,0,0.05);
}
.setting-content .content-body .side-menu ul li {
margin: 0.1rem 0.2rem;
margin: 0.2vh 0.3vw;
}
.setting-content .content-body .side-menu ul li.active {
background: #fff;
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.15);
}
.setting-content .content-body .side-menu ul li:hover {
background: #fff;
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
box-shadow: 0 0.2vh 0.3vh rgba(0,0,0,0.15);
}
.setting-content .content-body .side-menu ul li a {
padding: 1rem 0 1rem 1rem;
padding: 1.3vh 0 1.3vh 1.3vw;
width: 95%;
}
.setting-content .content-body .side-menu ul li a span {
+13 -13
View File
@@ -30,10 +30,10 @@ template(name="setting")
a.js-setting-menu(data-id="announcement-setting")
i.fa.fa-bullhorn
| {{_ 'admin-announcement'}}
//li
// a.js-setting-menu(data-id="accessibility-setting")
// i.fa.fa-universal-access
// | {{_ 'accessibility'}}
li
a.js-setting-menu(data-id="accessibility-setting")
i.fa.fa-universal-access
| {{_ 'accessibility'}}
li
a.js-setting-menu(data-id="layout-setting")
i.fa.fa-object-group
@@ -171,6 +171,8 @@ template(name='accountSettings')
label {{_ 'no'}}
button.js-accounts-save.primary {{_ 'save'}}
// Brute force lockout settings moved to People/Locked Users section
template(name='announcementSettings')
ul#announcement-setting.setting-detail
li
@@ -189,24 +191,22 @@ template(name='announcementSettings')
template(name='accessibilitySettings')
ul#accessibility-setting.setting-detail
li
a(href="/accessibility" style="text-decoration: underline; color: blue;") {{_ 'accessibility'}}
li
a.flex.js-toggle-accessibility
.materialCheckBox(class="{{#if currentAccessibility.enabled}}is-checked{{/if}}")
span {{_ 'admin-accessibility-active'}}
li
.title {{_ 'accessibility-title'}}
.form-group
input.wekan-form-control#accessibility-title(type="text", placeholder="" value="{{currentSetting.accessibilityTitle}}")
span {{_ 'accessibility-page-enabled'}}
li
.accessibility-content(class="{{#if currentAccessibility.enabled}}{{else}}hide{{/if}}")
ul
li
.title {{_ 'admin-accessibility-title'}}
textarea#admin-accessibility.wekan-form-control= currentAccessibility.accessibilityTitle
.title {{_ 'accessibility-title'}}
textarea#admin-accessibility-title.wekan-form-control= currentAccessibility.title
li
.title {{_ 'admin-accessibility-content'}}
textarea#admin-accessibility.wekan-form-control= currentAccessibility.accessibilityContent
.title {{_ 'accessibility-content'}}
textarea#admin-accessibility-content.wekan-form-control= currentAccessibility.body
li
button.js-accessibility-save.primary {{_ 'save'}}
+86 -65
View File
@@ -1,6 +1,7 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
import { ALLOWED_WAIT_SPINNERS } from '/config/const';
import LockoutSettings from '/models/lockoutSettings';
BlazeComponent.extendComponent({
onCreated() {
@@ -12,6 +13,7 @@ BlazeComponent.extendComponent({
this.accountSetting = new ReactiveVar(false);
this.tableVisibilityModeSetting = new ReactiveVar(false);
this.announcementSetting = new ReactiveVar(false);
this.accessibilitySetting = new ReactiveVar(false);
this.layoutSetting = new ReactiveVar(false);
this.webhookSetting = new ReactiveVar(false);
@@ -20,7 +22,9 @@ BlazeComponent.extendComponent({
Meteor.subscribe('accountSettings');
Meteor.subscribe('tableVisibilityModeSettings');
Meteor.subscribe('announcements');
Meteor.subscribe('accessibilitySettings');
Meteor.subscribe('globalwebhooks');
Meteor.subscribe('lockoutSettings');
},
setError(error) {
@@ -106,6 +110,7 @@ BlazeComponent.extendComponent({
this.emailSetting.set('email-setting' === targetID);
this.accountSetting.set('account-setting' === targetID);
this.announcementSetting.set('announcement-setting' === targetID);
this.accessibilitySetting.set('accessibility-setting' === targetID);
this.layoutSetting.set('layout-setting' === targetID);
this.webhookSetting.set('webhook-setting' === targetID);
this.tableVisibilityModeSetting.set('tableVisibilityMode-setting' === targetID);
@@ -187,71 +192,29 @@ BlazeComponent.extendComponent({
this.setLoading(true);
$('li').removeClass('has-error');
const productName = $('#product-name')
.val()
.trim();
const customLoginLogoImageUrl = $('#custom-login-logo-image-url')
.val()
.trim();
const customLoginLogoLinkUrl = $('#custom-login-logo-link-url')
.val()
.trim();
const customHelpLinkUrl = $('#custom-help-link-url')
.val()
.trim();
const textBelowCustomLoginLogo = $('#text-below-custom-login-logo')
.val()
.trim();
const automaticLinkedUrlSchemes = $('#automatic-linked-url-schemes')
.val()
.trim();
const customTopLeftCornerLogoImageUrl = $(
'#custom-top-left-corner-logo-image-url',
)
.val()
.trim();
const customTopLeftCornerLogoLinkUrl = $(
'#custom-top-left-corner-logo-link-url',
)
.val()
.trim();
const customTopLeftCornerLogoHeight = $(
'#custom-top-left-corner-logo-height',
)
.val()
.trim();
const productName = ($('#product-name').val() || '').trim();
const customLoginLogoImageUrl = ($('#custom-login-logo-image-url').val() || '').trim();
const customLoginLogoLinkUrl = ($('#custom-login-logo-link-url').val() || '').trim();
const customHelpLinkUrl = ($('#custom-help-link-url').val() || '').trim();
const textBelowCustomLoginLogo = ($('#text-below-custom-login-logo').val() || '').trim();
const automaticLinkedUrlSchemes = ($('#automatic-linked-url-schemes').val() || '').trim();
const customTopLeftCornerLogoImageUrl = ($('#custom-top-left-corner-logo-image-url').val() || '').trim();
const customTopLeftCornerLogoLinkUrl = ($('#custom-top-left-corner-logo-link-url').val() || '').trim();
const customTopLeftCornerLogoHeight = ($('#custom-top-left-corner-logo-height').val() || '').trim();
const oidcBtnText = $(
'#oidcBtnTextvalue',
)
.val()
.trim();
const mailDomainName = $(
'#mailDomainNamevalue',
)
.val()
.trim();
const legalNotice = $(
'#legalNoticevalue',
)
.val()
.trim();
const oidcBtnText = ($('#oidcBtnTextvalue').val() || '').trim();
const mailDomainName = ($('#mailDomainNamevalue').val() || '').trim();
const legalNotice = ($('#legalNoticevalue').val() || '').trim();
const hideLogoChange = $('input[name=hideLogo]:checked').val() === 'true';
const hideCardCounterListChange = $('input[name=hideCardCounterList]:checked').val() === 'true';
const hideBoardMemberListChange = $('input[name=hideBoardMemberList]:checked').val() === 'true';
const displayAuthenticationMethod =
$('input[name=displayAuthenticationMethod]:checked').val() === 'true';
const defaultAuthenticationMethod = $('#defaultAuthenticationMethod').val();
/*
const accessibilityPageEnabled = $('input[name=accessibilityPageEnabled]:checked').val() === 'true';
const accessibilityTitle = $('#accessibility-title')
.val()
.trim();
const accessibilityContent = $('#accessibility-content')
.val()
.trim();
*/
const spinnerName = $('#spinnerName').val();
const accessibilityTitle = ($('#accessibility-title').val() || '').trim();
const accessibilityContent = ($('#accessibility-content').val() || '').trim();
const spinnerName = ($('#spinnerName').val() || '').trim();
try {
Settings.update(ReactiveCache.getCurrentSetting()._id, {
@@ -274,13 +237,11 @@ BlazeComponent.extendComponent({
oidcBtnText,
mailDomainName,
legalNotice,
},
});
/*
accessibilityPageEnabled,
accessibilityTitle,
accessibilityContent,
*/
},
});
} catch (e) {
return;
} finally {
@@ -317,7 +278,6 @@ BlazeComponent.extendComponent({
'click a.js-toggle-hide-logo': this.toggleHideLogo,
'click a.js-toggle-hide-card-counter-list': this.toggleHideCardCounterList,
'click a.js-toggle-hide-board-member-list': this.toggleHideBoardMemberList,
'click a.js-toggle-accessibility-page-enabled': this.toggleAccessibilityPageEnabled,
'click button.js-save-layout': this.saveLayout,
'click a.js-toggle-display-authentication-method': this
.toggleDisplayAuthenticationMethod,
@@ -344,15 +304,23 @@ BlazeComponent.extendComponent({
$set: { booleanValue: allowUserDelete },
});
},
// Brute force lockout settings method moved to lockedUsersBody.js
allowEmailChange() {
return AccountSettings.findOne('accounts-allowEmailChange').booleanValue;
return AccountSettings.findOne('accounts-allowEmailChange')?.booleanValue || false;
},
allowUserNameChange() {
return AccountSettings.findOne('accounts-allowUserNameChange').booleanValue;
return AccountSettings.findOne('accounts-allowUserNameChange')?.booleanValue || false;
},
allowUserDelete() {
return AccountSettings.findOne('accounts-allowUserDelete').booleanValue;
return AccountSettings.findOne('accounts-allowUserDelete')?.booleanValue || false;
},
// Lockout settings helper methods moved to lockedUsersBody.js
allBoardsHideActivities() {
Meteor.call('setAllBoardsHideActivities', (err, ret) => {
if (!err && ret) {
@@ -469,6 +437,59 @@ BlazeComponent.extendComponent({
},
}).register('announcementSettings');
BlazeComponent.extendComponent({
onCreated() {
this.loading = new ReactiveVar(false);
},
setLoading(w) {
this.loading.set(w);
},
currentAccessibility() {
return AccessibilitySettings.findOne();
},
saveAccessibility() {
const title = $('#admin-accessibility-title')
.val()
.trim();
const content = $('#admin-accessibility-content')
.val()
.trim();
AccessibilitySettings.update(AccessibilitySettings.findOne()._id, {
$set: {
title: title,
body: content
},
});
},
toggleAccessibility() {
this.setLoading(true);
const accessibilitySetting = this.currentAccessibility();
const isActive = accessibilitySetting.enabled;
AccessibilitySettings.update(accessibilitySetting._id, {
$set: { enabled: !isActive },
});
this.setLoading(false);
if (isActive) {
$('.accessibility-content').slideUp();
} else {
$('.accessibility-content').slideDown();
}
},
events() {
return [
{
'click a.js-toggle-accessibility': this.toggleAccessibility,
'click button.js-accessibility-save': this.saveAccessibility,
},
];
},
}).register('accessibilitySettings');
Template.selectAuthenticationMethod.onCreated(function() {
this.authenticationMethods = new ReactiveVar([]);
+19 -2
View File
@@ -106,7 +106,7 @@
top: 7px;
font-size: 1em;
line-height: 1.6em;
color: #999;
color: #000;
}
.sidebar .sidebar-shortcuts .sidebar-btn {
margin-left: 3px;
@@ -146,6 +146,23 @@
font-size: 24px;
transition: transform 0.5s;
}
.sidebar-accessibility {
color: #4d4d4d;
padding: 5px 10px;
display: flex;
align-items: center;
text-decoration: none;
border-radius: 3px;
cursor: pointer;
margin-left: auto;
margin-right: 30px;
}
.sidebar-accessibility:hover {
background-color: #d9d9d9;
}
.sidebar-accessibility span {
margin-left: 5px;
}
.board-sidebar.is-open .sidebar-tongue {
left: -28px;
}
@@ -177,7 +194,7 @@
@media screen and (max-width: 800px) {
.board-sidebar {
width: 100%;
right: -100%;
left: 0;
}
.board-sidebar .sidebar-content .hide-btn {
width: 40px;
+10
View File
@@ -12,6 +12,10 @@ template(name="sidebar")
a.sidebar-btn.js-keyboard-shortcuts-toggle(
title="{{#if isKeyboardShortcuts}}{{_ 'keyboard-shortcuts-enabled'}}{{else}}{{_ 'keyboard-shortcuts-disabled'}}{{/if}}")
i.fa(class="fa-solid fa-{{#if isKeyboardShortcuts}}check-square-o{{else}}ban{{/if}}")
if isAccessibilityEnabled
a.sidebar-accessibility
i.fa.fa-universal-access
span {{_ 'accessibility'}}
a.sidebar-xmark.js-close-sidebar &#10005;
.sidebar-content.js-board-sidebar-content
//a.hide-btn.js-hide-sidebar
@@ -39,6 +43,11 @@ template(name='homeSidebar')
span {{_ 'enable-vertical-scrollbars'}}
b &nbsp;
.materialCheckBox(class="{{#if isVerticalScrollbars}}is-checked{{/if}}")
ul#cards.show-week-of-year-toggle
a.flex.js-show-week-of-year-toggle(title="{{_ 'show-week-of-year'}}")
span {{_ 'show-week-of-year'}}
b &nbsp;
.materialCheckBox(class="{{#if isShowWeekOfYear}}is-checked{{/if}}")
hr
unless currentUser.isNoComments
h3.activity-title
@@ -643,6 +652,7 @@ template(name="addMemberPopup")
p.quiet {{_ 'no-results'}}
button.js-email-invite.primary.full {{_ 'email-invite'}}
template(name="changePermissionsPopup")
ul.pop-over-list
li
+20
View File
@@ -26,6 +26,9 @@ BlazeComponent.extendComponent({
this._hideCardCounterList = new ReactiveVar(false);
this._hideBoardMemberList = new ReactiveVar(false);
Sidebar = this;
// Subscribe to accessibility settings
Meteor.subscribe('accessibilitySettings');
},
onDestroyed() {
@@ -115,6 +118,11 @@ BlazeComponent.extendComponent({
return user && user.isVerticalScrollbars();
},
isAccessibilityEnabled() {
const setting = AccessibilitySettings.findOne({});
return setting && setting.enabled;
},
events() {
return [
{
@@ -142,6 +150,13 @@ BlazeComponent.extendComponent({
'click .js-vertical-scrollbars-toggle'() {
ReactiveCache.getCurrentUser().toggleVerticalScrollbars();
},
'click .js-show-week-of-year-toggle'() {
ReactiveCache.getCurrentUser().toggleShowWeekOfYear();
},
'click .sidebar-accessibility'() {
FlowRouter.go('accessibility');
Sidebar.toggle();
},
'click .js-close-sidebar'() {
Sidebar.toggle()
},
@@ -167,6 +182,10 @@ BlazeComponent.extendComponent({
const user = ReactiveCache.getCurrentUser();
return user && user.isVerticalScrollbars();
},
isShowWeekOfYear() {
const user = ReactiveCache.getCurrentUser();
return user && user.isShowWeekOfYear();
},
showActivities() {
let ret = Utils.getCurrentBoard().showActivities ?? false;
return ret;
@@ -1929,3 +1948,4 @@ Template.changePermissionsPopup.helpers({
);
},
});
+17 -9
View File
@@ -13,15 +13,15 @@
font-size: 50%;
color: #a6a6a6;
position: absolute;
top: 5px;
left: 100px;
top: 0.7vh;
left: 13vw;
}
.swimlane-header-menu .swimlane-header-collapse-up {
font-size: 50%;
color: #a6a6a6;
position: absolute;
bottom: 5px;
left: 100px;
bottom: 0.7vh;
left: 13vw;
}
.swimlane-header-menu .swimlane-header-uncollapse-up {
font-size: 50%;
@@ -35,10 +35,10 @@
background-color: rgba(0,0,0,0.2);
border-color: transparent;
box-shadow: none;
height: 100px;
height: 15vh;
}
.swimlane.ui-sortable-helper {
box-shadow: -2px 2px 8px rgba(0,0,0,0.3), 0 0 1px rgba(0,0,0,0.5);
box-shadow: -0.3vw 0.3vh 1vh rgba(0,0,0,0.3), 0 0 0.1vw rgba(0,0,0,0.5);
transform: rotate(2deg);
cursor: grabbing;
}
@@ -50,12 +50,17 @@
flex-direction: row;
flex: 1 0 100%;
background-color: #ccc;
width: 100%;
min-width: 100%;
position: relative;
overflow: hidden;
min-height: 33px;
}
.swimlane .swimlane-header-wrap .swimlane-header {
font-size: 14px;
padding: 5px 5px;
font-weight: bold;
min-height: 9px;
min-height: 33px;
width: 100%;
overflow: hidden;
-o-text-overflow: ellipsis;
@@ -86,9 +91,12 @@
position: absolute;
padding: 7px;
top: 50%;
transform: translateY(-50%);
left: 230px;
font-size: 18px;
font-size: clamp(16px, 3vw, 20px);
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
}
.swimlane .swimlane-header-wrap .swimlane-header-miniscreen-handle {
position: absolute;
+92 -26
View File
@@ -63,7 +63,7 @@ function initSortable(boardComponent, $listsDom) {
};
$listsDom.sortable({
connectWith: '.board-canvas',
connectWith: '.js-swimlane, .js-lists',
tolerance: 'pointer',
helper: 'clone',
items: '.js-list:not(.js-list-composer)',
@@ -82,10 +82,31 @@ function initSortable(boardComponent, $listsDom) {
const nextListDom = ui.item.next('.js-list').get(0);
const sortIndex = calculateIndex(prevListDom, nextListDom, 1);
$listsDom.sortable('cancel');
const listDomElement = ui.item.get(0);
const list = Blaze.getData(listDomElement);
// Detect if the list was dropped in a different swimlane
const targetSwimlaneDom = ui.item.closest('.js-swimlane');
let targetSwimlaneId = null;
if (targetSwimlaneDom.length > 0) {
// List was dropped in a swimlane
targetSwimlaneId = targetSwimlaneDom.attr('id').replace('swimlane-', '');
} else {
// List was dropped in lists view (not swimlanes view)
// In this case, assign to the default swimlane
const currentBoard = ReactiveCache.getBoard(Session.get('currentBoard'));
if (currentBoard) {
const defaultSwimlane = currentBoard.getDefaultSwimline();
if (defaultSwimlane) {
targetSwimlaneId = defaultSwimlane._id;
}
}
}
// Get the original swimlane ID of the list
const originalSwimlaneId = list.swimlaneId;
/*
Reverted incomplete change list width,
removed from below Lists.update:
@@ -95,10 +116,44 @@ function initSortable(boardComponent, $listsDom) {
height: list._id.height(),
*/
// Prepare update object
const updateData = {
sort: sortIndex.base,
};
// Check if the list was dropped in a different swimlane
const isDifferentSwimlane = targetSwimlaneId && targetSwimlaneId !== originalSwimlaneId;
// If the list was dropped in a different swimlane, update the swimlaneId
if (isDifferentSwimlane) {
updateData.swimlaneId = targetSwimlaneId;
if (process.env.DEBUG === 'true') {
console.log(`Moving list "${list.title}" from swimlane ${originalSwimlaneId} to swimlane ${targetSwimlaneId}`);
}
// Move all cards in the list to the new swimlane
const cardsInList = ReactiveCache.getCards({
listId: list._id,
archived: false
});
cardsInList.forEach(card => {
card.move(list.boardId, targetSwimlaneId, list._id);
});
if (process.env.DEBUG === 'true') {
console.log(`Moved ${cardsInList.length} cards to swimlane ${targetSwimlaneId}`);
}
// Don't cancel the sortable when moving to a different swimlane
// The DOM move should be allowed to complete
} else {
// If staying in the same swimlane, cancel the sortable to prevent DOM manipulation issues
$listsDom.sortable('cancel');
}
Lists.update(list._id, {
$set: {
sort: sortIndex.base,
},
$set: updateData,
});
boardComponent.setIsDragging(false);
@@ -109,10 +164,12 @@ function initSortable(boardComponent, $listsDom) {
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
$listsDom.sortable({
handle: '.js-list-handle',
connectWith: '.js-swimlane, .js-lists',
});
} else {
$listsDom.sortable({
handle: '.js-list-header',
connectWith: '.js-swimlane, .js-lists',
});
}
@@ -228,7 +285,7 @@ BlazeComponent.extendComponent({
const user = ReactiveCache.getCurrentUser();
const swimlane = Template.currentData();
const height = user.getSwimlaneHeight(swimlane.boardId, swimlane._id);
return height == -1 ? "auto" : (height + "px");
return height == -1 ? "auto" : (height + 5 + "px");
},
}).register('swimlane');
@@ -250,36 +307,45 @@ BlazeComponent.extendComponent({
return [
{
submit(evt) {
evt.preventDefault();
const lastList = this.currentBoard.getLastList();
const titleInput = this.find('.list-name-input');
const title = titleInput.value.trim();
let sortIndex = 0
if (lastList) {
const positionInput = this.find('.list-position-input');
const position = positionInput.value.trim();
const ret = ReactiveCache.getList({ boardId: Utils.getCurrentBoardId(), _id: position, archived: false })
sortIndex = parseInt(JSON.stringify(ret['sort']))
sortIndex = sortIndex+1
} else {
sortIndex = Utils.calculateIndexData(lastList, null).base;
}
evt.preventDefault();
const titleInput = this.find('.list-name-input');
const title = titleInput?.value.trim();
if (!title) return;
let sortIndex = 0;
const lastList = this.currentBoard.getLastList();
const boardId = Utils.getCurrentBoardId();
const positionInput = this.find('.list-position-input');
if (positionInput) {
const positionId = positionInput.value.trim();
const selectedList = ReactiveCache.getList({ boardId, _id: positionId, archived: false });
if (selectedList) {
sortIndex = selectedList.sort + 1;
} else {
sortIndex = Utils.calculateIndexData(lastList, null).base;
}
} else {
sortIndex = Utils.calculateIndexData(lastList, null).base;
}
if (title) {
Lists.insert({
title,
boardId: Session.get('currentBoard'),
sort: sortIndex,
type: this.isListTemplatesSwimlane ? 'template-list' : 'list',
swimlaneId: this.currentBoard.isTemplatesBoard()
? this.currentSwimlane._id
: '',
swimlaneId: this.currentSwimlane._id, // Always set swimlaneId for per-swimlane list titles
});
titleInput.value = '';
titleInput.focus();
}
},
}
},
{
'click .js-list-template': Popup.open('searchElement'),
},
];
+13 -13
View File
@@ -1,25 +1,25 @@
.auth-layout .at-form-landing-logo {
width: 249px;
width: min(249px, 32vw);
margin: auto;
margin-top: 50px;
margin-bottom: 20px;
margin-top: 6vh;
margin-bottom: 2.5vh;
}
.auth-layout .auth-dialog {
width: 275px;
padding: 25px;
width: min(275px, 36vw);
padding: 3vh 3vw;
margin: auto;
margin-bottom: 20px;
margin-bottom: 2.5vh;
background: #fff;
border-radius: 3px;
border-radius: 0.4vw;
border: 1px solid #dbdbdb;
border-bottom-color: #c2c2c2;
box-shadow: 0 1px 6px rgba(0,0,0,0.3);
box-shadow: 0 0.2vh 0.8vh rgba(0,0,0,0.3);
}
.auth-layout .auth-dialog .at-form .at-link {
color: #17683a;
}
.auth-layout .auth-dialog .at-form label {
margin-bottom: 3px;
margin-bottom: 0.4vh;
}
.auth-layout .auth-dialog .at-form input {
width: 100%;
@@ -31,9 +31,9 @@
}
.auth-layout .auth-dialog .at-form .at-title {
background: #f7f7f7;
margin: -25px;
padding: 15px 25px 5px;
margin-bottom: 20px;
margin: -3vh -3vw;
padding: 2vh 3vw 0.7vh;
margin-bottom: 2.5vh;
border-bottom: 1px solid #dcdcdc;
color: #4d4d4d;
font-weight: bold;
@@ -42,7 +42,7 @@
.auth-layout .auth-dialog .at-form .at-signin-link,
.auth-layout .auth-dialog .at-form .at-forgotPwd {
font-size: 0.9em;
margin-top: 15px;
margin-top: 2vh;
color: #4d4d4d;
}
.auth-layout .auth-dialog .at-form .at-signup-link .at-signUp,
+15 -2
View File
@@ -241,8 +241,21 @@ Template.editProfilePopup.events({
},
'click #deleteButton': Popup.afterConfirm('userDelete', function() {
Popup.back();
Users.remove(Meteor.userId());
AccountsTemplates.logout();
// Use secure server method for self-deletion
Meteor.call('removeUser', Meteor.userId(), (error, result) => {
if (error) {
if (process.env.DEBUG === 'true') {
console.error('Error removing user:', error);
}
alert('Error deleting account: ' + error.reason);
} else {
if (process.env.DEBUG === 'true') {
console.log('User deleted successfully:', result);
}
AccountsTemplates.logout();
}
});
}),
});
+42 -7
View File
@@ -133,7 +133,7 @@ Mousetrap.bind(numbArray, (evt, key) => {
const cardIds = MultiSelection.getSelectedCardIds();
for (const cardId of cardIds)
{
card = ReactiveCache.getCard(cardId);
card = Cards.findOne(cardId);
if(num <= board.labels.length)
{
card.removeLabel(labels[num-1]["_id"]);
@@ -157,7 +157,7 @@ Mousetrap.bind(numArray, (evt, key) => {
const cardIds = MultiSelection.getSelectedCardIds();
for (const cardId of cardIds)
{
card = ReactiveCache.getCard(cardId);
card = Cards.findOne(cardId);
if(num <= board.labels.length)
{
card.addLabel(labels[num-1]["_id"]);
@@ -171,7 +171,7 @@ Mousetrap.bind(numArray, (evt, key) => {
return;
}
if (ReactiveCache.getCurrentUser().isBoardMember()) {
const card = ReactiveCache.getCard(cardId);
const card = Cards.findOne(cardId);
if(num <= board.labels.length)
{
card.toggleLabel(labels[num-1]["_id"]);
@@ -179,6 +179,37 @@ Mousetrap.bind(numArray, (evt, key) => {
}
});
Mousetrap.bind(_.range(1, 10).map(x => `ctrl+alt+${x}`), (evt, key) => {
// Make sure the current user is defined
if (!ReactiveCache.getCurrentUser())
return;
// Make sure the current user is a board member
if (!ReactiveCache.getCurrentUser().isBoardMember())
return;
const memberIndex = parseInt(key.split("+").pop()) - 1;
const currentBoard = Utils.getCurrentBoard();
const validBoardMembers = currentBoard.memberUsers().filter(member => member.isBoardMember());
if (memberIndex >= validBoardMembers.length)
return;
const memberId = validBoardMembers[memberIndex]._id;
if (MultiSelection.isActive()) {
for (const cardId of MultiSelection.getSelectedCardIds())
Cards.findOne(cardId).toggleAssignee(memberId);
} else {
const cardId = getSelectedCardId();
if (!cardId)
return;
Cards.findOne(cardId).toggleAssignee(memberId);
}
});
Mousetrap.bind('m', evt => {
const cardId = getSelectedCardId();
if (!cardId) {
@@ -191,7 +222,7 @@ Mousetrap.bind('m', evt => {
}
if (ReactiveCache.getCurrentUser().isBoardMember()) {
const card = ReactiveCache.getCard(cardId);
const card = Cards.findOne(cardId);
card.toggleAssignee(currentUserId);
// We should prevent scrolling in card when spacebar is clicked
// This should do it according to Mousetrap docs, but it doesn't
@@ -211,7 +242,7 @@ Mousetrap.bind('space', evt => {
}
if (ReactiveCache.getCurrentUser().isBoardMember()) {
const card = ReactiveCache.getCard(cardId);
const card = Cards.findOne(cardId);
card.toggleMember(currentUserId);
// We should prevent scrolling in card when spacebar is clicked
// This should do it according to Mousetrap docs, but it doesn't
@@ -231,7 +262,7 @@ const archiveCard = evt => {
}
if (Utils.canModifyBoard()) {
const card = ReactiveCache.getCard(cardId);
const card = Cards.findOne(cardId);
card.archive();
// We should prevent scrolling in card when spacebar is clicked
// This should do it according to Mousetrap docs, but it doesn't
@@ -260,7 +291,7 @@ Mousetrap.bind('n', evt => {
if (Utils.canModifyBoard()) {
// Find the current hovered card
const card = ReactiveCache.getCard(cardId);
const card = Cards.findOne(cardId);
// Find the button and click it
$(`#js-list-${card.listId} .list-body .minicards .open-minicard-composer`).click();
@@ -333,5 +364,9 @@ Template.keyboardShortcuts.helpers({
keys: ['shift + number keys 1-9'],
action: 'remove-labels-multiselect'
},
{
keys: ['ctrl + alt + number keys 1-9'],
action: 'toggle-assignees'
},
],
});
+121
View File
@@ -0,0 +1,121 @@
import DOMPurify from 'dompurify';
// Centralized secure DOMPurify configuration to prevent XSS and CSS injection attacks
export function getSecureDOMPurifyConfig() {
return {
// Block dangerous elements that can cause XSS and CSS injection
FORBID_TAGS: [
'svg', 'defs', 'use', 'g', 'symbol', 'marker', 'pattern', 'mask', 'clipPath',
'linearGradient', 'radialGradient', 'stop', 'animate', 'animateTransform',
'animateMotion', 'set', 'switch', 'foreignObject', 'script', 'style', 'link',
'meta', 'iframe', 'object', 'embed', 'applet', 'form', 'input', 'textarea',
'select', 'option', 'button', 'label', 'fieldset', 'legend', 'frameset',
'frame', 'noframes', 'base', 'basefont', 'isindex', 'dir', 'menu', 'menuitem'
],
// Block dangerous attributes that can cause XSS and CSS injection
FORBID_ATTR: [
'xlink:href', 'href', 'onload', 'onerror', 'onclick', 'onmouseover',
'onfocus', 'onblur', 'onchange', 'onsubmit', 'onreset', 'onselect',
'onunload', 'onresize', 'onscroll', 'onkeydown', 'onkeyup', 'onkeypress',
'onmousedown', 'onmouseup', 'onmouseover', 'onmouseout', 'onmousemove',
'ondblclick', 'oncontextmenu', 'onwheel', 'ontouchstart', 'ontouchend',
'ontouchmove', 'ontouchcancel', 'onabort', 'oncanplay', 'oncanplaythrough',
'ondurationchange', 'onemptied', 'onended', 'onerror', 'onloadeddata',
'onloadedmetadata', 'onloadstart', 'onpause', 'onplay', 'onplaying',
'onprogress', 'onratechange', 'onseeked', 'onseeking', 'onstalled',
'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting', 'onbeforeunload',
'onhashchange', 'onpagehide', 'onpageshow', 'onpopstate', 'onstorage',
'onunload', 'style', 'class', 'id', 'data-*', 'aria-*'
],
// Allow only safe image formats and protocols
ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,
// Remove dangerous protocols
ALLOW_UNKNOWN_PROTOCOLS: false,
// Sanitize URLs to prevent malicious content loading
SANITIZE_DOM: true,
// Remove dangerous elements completely
KEEP_CONTENT: false,
// Additional security measures
ADD_ATTR: [],
// Block data URIs that could contain malicious content
ALLOW_DATA_ATTR: false,
// Custom hook to further sanitize content
HOOKS: {
uponSanitizeElement: function(node, data) {
// Block any remaining dangerous elements
const dangerousTags = ['svg', 'style', 'script', 'link', 'meta', 'iframe', 'object', 'embed', 'applet'];
if (node.tagName && dangerousTags.includes(node.tagName.toLowerCase())) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked potentially dangerous element:', node.tagName);
}
return false;
}
// Block img tags with SVG data URIs
if (node.tagName && node.tagName.toLowerCase() === 'img') {
const src = node.getAttribute('src');
if (src && (src.startsWith('data:image/svg') || src.endsWith('.svg'))) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked potentially malicious SVG image:', src);
}
return false;
}
}
// Block elements with dangerous attributes
const dangerousAttrs = ['style', 'onload', 'onerror', 'onclick', 'onmouseover', 'onfocus', 'onblur'];
for (const attr of dangerousAttrs) {
if (node.hasAttribute && node.hasAttribute(attr)) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked element with dangerous attribute:', node.tagName, attr);
}
return false;
}
}
return true;
},
uponSanitizeAttribute: function(node, data) {
// Block style attributes completely
if (data.attrName === 'style') {
if (process.env.DEBUG === 'true') {
console.warn('Blocked style attribute');
}
return false;
}
// Block class and id attributes that might be used for CSS injection
if (data.attrName === 'class' || data.attrName === 'id') {
if (process.env.DEBUG === 'true') {
console.warn('Blocked class/id attribute:', data.attrName, data.attrValue);
}
return false;
}
// Block data attributes
if (data.attrName && data.attrName.startsWith('data-')) {
if (process.env.DEBUG === 'true') {
console.warn('Blocked data attribute:', data.attrName);
}
return false;
}
return true;
}
}
};
}
// Convenience function for secure sanitization
export function sanitizeHTML(html) {
return DOMPurify.sanitize(html, getSecureDOMPurifyConfig());
}
// Convenience function for sanitizing text (no HTML)
export function sanitizeText(text) {
return DOMPurify.sanitize(text, {
ALLOWED_TAGS: [],
ALLOWED_ATTR: [],
KEEP_CONTENT: true
});
}
+177
View File
@@ -0,0 +1,177 @@
import { ReactiveVar } from 'meteor/reactive-var';
import { Tracker } from 'meteor/tracker';
/**
* Global upload progress manager for drag-and-drop file uploads
* Tracks upload progress across all cards and provides reactive data
*/
class UploadProgressManager {
constructor() {
// Map of cardId -> array of upload objects
this.cardUploads = new ReactiveVar(new Map());
// Map of uploadId -> upload object for easy lookup
this.uploadMap = new ReactiveVar(new Map());
}
/**
* Add a new upload to track
* @param {string} cardId - The card ID
* @param {Object} uploader - The uploader object from Attachments.insert
* @param {File} file - The file being uploaded
* @returns {string} uploadId - Unique identifier for this upload
*/
addUpload(cardId, uploader, file) {
const uploadId = `upload_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
const upload = {
id: uploadId,
cardId: cardId,
file: file,
uploader: uploader,
progress: new ReactiveVar(0),
status: new ReactiveVar('uploading'), // 'uploading', 'completed', 'error'
error: new ReactiveVar(null),
startTime: Date.now(),
endTime: null
};
// Update card uploads
const currentCardUploads = this.cardUploads.get();
const cardUploads = currentCardUploads.get(cardId) || [];
cardUploads.push(upload);
currentCardUploads.set(cardId, cardUploads);
this.cardUploads.set(currentCardUploads);
// Update upload map
const currentUploadMap = this.uploadMap.get();
currentUploadMap.set(uploadId, upload);
this.uploadMap.set(currentUploadMap);
// Set up uploader event listeners
uploader.on('progress', (progress) => {
upload.progress.set(progress);
});
uploader.on('uploaded', (error, fileRef) => {
upload.status.set(error ? 'error' : 'completed');
upload.endTime = Date.now();
upload.error.set(error);
if (process.env.DEBUG === 'true') {
console.log(`Upload ${uploadId} completed:`, error ? 'error' : 'success');
}
// Remove from tracking after a delay to show completion
setTimeout(() => {
this.removeUpload(uploadId);
}, 2000);
});
uploader.on('error', (error) => {
upload.status.set('error');
upload.endTime = Date.now();
upload.error.set(error);
if (process.env.DEBUG === 'true') {
console.log(`Upload ${uploadId} failed:`, error);
}
// Remove from tracking after a delay to show error
setTimeout(() => {
this.removeUpload(uploadId);
}, 3000);
});
if (process.env.DEBUG === 'true') {
console.log(`Added upload ${uploadId} for card ${cardId}: ${file.name}`);
}
return uploadId;
}
/**
* Remove an upload from tracking
* @param {string} uploadId - The upload ID to remove
*/
removeUpload(uploadId) {
const upload = this.uploadMap.get().get(uploadId);
if (!upload) return;
const cardId = upload.cardId;
// Remove from card uploads
const currentCardUploads = this.cardUploads.get();
const cardUploads = currentCardUploads.get(cardId) || [];
const filteredCardUploads = cardUploads.filter(u => u.id !== uploadId);
if (filteredCardUploads.length === 0) {
currentCardUploads.delete(cardId);
} else {
currentCardUploads.set(cardId, filteredCardUploads);
}
this.cardUploads.set(currentCardUploads);
// Remove from upload map
const currentUploadMap = this.uploadMap.get();
currentUploadMap.delete(uploadId);
this.uploadMap.set(currentUploadMap);
if (process.env.DEBUG === 'true') {
console.log(`Removed upload ${uploadId} from tracking`);
}
}
/**
* Get all uploads for a specific card
* @param {string} cardId - The card ID
* @returns {Array} Array of upload objects
*/
getUploadsForCard(cardId) {
return this.cardUploads.get().get(cardId) || [];
}
/**
* Get upload count for a specific card
* @param {string} cardId - The card ID
* @returns {number} Number of active uploads
*/
getUploadCountForCard(cardId) {
return this.getUploadsForCard(cardId).length;
}
/**
* Check if a card has any active uploads
* @param {string} cardId - The card ID
* @returns {boolean} True if card has active uploads
*/
hasActiveUploads(cardId) {
return this.getUploadCountForCard(cardId) > 0;
}
/**
* Get all uploads across all cards
* @returns {Array} Array of all upload objects
*/
getAllUploads() {
const allUploads = [];
this.cardUploads.get().forEach(cardUploads => {
allUploads.push(...cardUploads);
});
return allUploads;
}
/**
* Clear all uploads (useful for cleanup)
*/
clearAllUploads() {
this.cardUploads.set(new Map());
this.uploadMap.set(new Map());
}
}
// Create global instance
const uploadProgressManager = new UploadProgressManager();
export default uploadProgressManager;
+187 -10
View File
@@ -51,6 +51,146 @@ Utils = {
const ret = ReactiveCache.getCard(cardId);
return ret;
},
// Zoom and mobile mode utilities
getZoomLevel() {
const user = ReactiveCache.getCurrentUser();
if (user && user.profile && user.profile.zoomLevel !== undefined) {
return user.profile.zoomLevel;
}
// For non-logged-in users, check localStorage
const stored = localStorage.getItem('wekan-zoom-level');
return stored ? parseFloat(stored) : 1.0;
},
setZoomLevel(level) {
const user = ReactiveCache.getCurrentUser();
if (user) {
// Update user profile
user.setZoomLevel(level);
} else {
// Store in localStorage for non-logged-in users
localStorage.setItem('wekan-zoom-level', level.toString());
}
Utils.applyZoomLevel(level);
// Trigger reactive updates for UI components
Session.set('wekan-zoom-level', level);
},
getMobileMode() {
const user = ReactiveCache.getCurrentUser();
if (user && user.profile && user.profile.mobileMode !== undefined) {
return user.profile.mobileMode;
}
// For non-logged-in users, check localStorage
const stored = localStorage.getItem('wekan-mobile-mode');
return stored ? stored === 'true' : false;
},
setMobileMode(enabled) {
const user = ReactiveCache.getCurrentUser();
if (user) {
// Update user profile
user.setMobileMode(enabled);
} else {
// Store in localStorage for non-logged-in users
localStorage.setItem('wekan-mobile-mode', enabled.toString());
}
Utils.applyMobileMode(enabled);
// Trigger reactive updates for UI components
Session.set('wekan-mobile-mode', enabled);
},
applyZoomLevel(level) {
const boardWrapper = document.querySelector('.board-wrapper');
const body = document.body;
const isMobileMode = body.classList.contains('mobile-mode');
if (boardWrapper) {
if (isMobileMode) {
// On mobile mode, only apply zoom to text and icons, not the entire layout
// Remove any existing transform from board-wrapper
boardWrapper.style.transform = '';
boardWrapper.style.transformOrigin = '';
// Apply zoom to text and icon elements instead
const textElements = boardWrapper.querySelectorAll('h1, h2, h3, h4, h5, h6, p, span, div, .minicard, .list-header-name, .board-header-btn, .fa, .icon');
textElements.forEach(element => {
element.style.transform = `scale(${level})`;
element.style.transformOrigin = 'center';
});
// Reset board-canvas height
const boardCanvas = document.querySelector('.board-canvas');
if (boardCanvas) {
boardCanvas.style.height = '';
}
} else {
// Desktop mode: apply zoom to entire board-wrapper as before
boardWrapper.style.transform = `scale(${level})`;
boardWrapper.style.transformOrigin = 'top left';
// If zoom is 50% or lower, make board wrapper full width like content
if (level <= 0.5) {
boardWrapper.style.width = '100%';
boardWrapper.style.maxWidth = '100%';
boardWrapper.style.margin = '0';
} else {
// Reset to normal width for higher zoom levels
boardWrapper.style.width = '';
boardWrapper.style.maxWidth = '';
boardWrapper.style.margin = '';
}
// Adjust container height to prevent scroll issues
const boardCanvas = document.querySelector('.board-canvas');
if (boardCanvas) {
boardCanvas.style.height = `${100 / level}%`;
// For high zoom levels (200%+), enable both horizontal and vertical scrolling
if (level >= 2.0) {
boardCanvas.style.overflowX = 'auto';
boardCanvas.style.overflowY = 'auto';
// Ensure the content area can scroll both horizontally and vertically
const content = document.querySelector('#content');
if (content) {
content.style.overflowX = 'auto';
content.style.overflowY = 'auto';
}
} else {
// Reset overflow for normal zoom levels
boardCanvas.style.overflowX = '';
boardCanvas.style.overflowY = '';
const content = document.querySelector('#content');
if (content) {
content.style.overflowX = '';
content.style.overflowY = '';
}
}
}
}
}
},
applyMobileMode(enabled) {
const body = document.body;
if (enabled) {
body.classList.add('mobile-mode');
body.classList.remove('desktop-mode');
} else {
body.classList.add('desktop-mode');
body.classList.remove('mobile-mode');
}
},
initializeUserSettings() {
// Apply saved settings on page load
const zoomLevel = Utils.getZoomLevel();
const mobileMode = Utils.getMobileMode();
Utils.applyZoomLevel(zoomLevel);
Utils.applyMobileMode(mobileMode);
},
getCurrentList() {
const listId = this.getCurrentListId();
let ret = null;
@@ -287,22 +427,50 @@ Utils = {
},
windowResizeDep: new Tracker.Dependency(),
// in fact, what we really care is screen size
// large mobile device like iPad or android Pad has a big screen, it should also behave like a desktop
// in a small window (even on desktop), Wekan run in compact mode.
// we can easily debug with a small window of desktop browser. :-)
isMiniScreen() {
// OLD WINDOW WIDTH DETECTION:
this.windowResizeDep.depend();
return $(window).width() <= 800;
// Show mobile view when:
// 1. Screen width is 800px or less (matches CSS media queries)
// 2. Mobile phones in portrait mode
// 3. iPad in very small screens (≤ 600px)
const isSmallScreen = window.innerWidth <= 800;
const isVerySmallScreen = window.innerWidth <= 600;
const isPortrait = window.innerWidth < window.innerHeight || window.matchMedia("(orientation: portrait)").matches;
const isMobilePhone = /Mobile|Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) && !/iPad/i.test(navigator.userAgent);
const isIPhone = /iPhone|iPod/i.test(navigator.userAgent);
const isIPad = /iPad/i.test(navigator.userAgent);
const isUbuntuTouch = /Ubuntu/i.test(navigator.userAgent);
// For iPhone: always show mobile view regardless of orientation
// For other mobile phones: show mobile view in portrait, desktop view in landscape
// For iPad: show mobile view only in very small screens (≤ 600px)
// For Ubuntu Touch: smartphones behave like mobile phones, tablets like iPad
// For desktop: show mobile view when screen width <= 800px
if (isIPhone) {
return true; // iPhone: always mobile view
} else if (isMobilePhone) {
return isPortrait; // Other mobile phones: portrait = mobile, landscape = desktop
} else if (isIPad) {
return isVerySmallScreen; // iPad: only very small screens get mobile view
} else if (isUbuntuTouch) {
// Ubuntu Touch: smartphones (≤ 600px) behave like mobile phones, tablets (> 600px) like iPad
if (isVerySmallScreen) {
return isPortrait; // Ubuntu Touch smartphone: portrait = mobile, landscape = desktop
} else {
return isVerySmallScreen; // Ubuntu Touch tablet: only very small screens get mobile view
}
} else {
return isSmallScreen; // Desktop: based on 800px screen width
}
},
isTouchScreen() {
// NEW TOUCH DEVICE DETECTION:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent
var hasTouchScreen = false;
if ("maxTouchPoints" in navigator) {
hasTouchScreen = navigator.maxTouchPoints > 0;
@@ -328,12 +496,19 @@ Utils = {
// returns if desktop drag handles are enabled
isShowDesktopDragHandles() {
//const currentUser = ReactiveCache.getCurrentUser();
//if (currentUser) {
// return (currentUser.profile || {}).showDesktopDragHandles;
//} else if (window.localStorage.getItem('showDesktopDragHandles')) {
if (this.isTouchScreen()) {
return true;
/*
const currentUser = ReactiveCache.getCurrentUser();
if (currentUser) {
return (currentUser.profile || {}).showDesktopDragHandles;
} else if (window.localStorage.getItem('showDesktopDragHandles')) {
//
if (window.localStorage.getItem('showDesktopDragHandles')) {
return true;
} else {
return false;
*/
} else {
return false;
}
@@ -341,8 +516,10 @@ Utils = {
// returns if mini screen or desktop drag handles
isTouchScreenOrShowDesktopDragHandles() {
// Always enable drag handles for mobile screens (touch devices)
return this.isTouchScreen() || this.isMiniScreen();
//return this.isTouchScreen() || this.isShowDesktopDragHandles();
return this.isShowDesktopDragHandles();
//return this.isShowDesktopDragHandles();
},
calculateIndexData(prevData, nextData, nItems = 1) {
+1
View File
@@ -57,6 +57,7 @@ AccountsTemplates.addFields([
displayName: 'username',
required: true,
minLength: 2,
autocomplete: 'username',
},
emailField,
passwordField,
+53 -18
View File
@@ -1,14 +1,14 @@
# 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
# https://github.com/wekan/wekan/blob/main/docs/Login/Adding-users.md
#---------------------------------------------------------------------------------------------------------
# ==== FORGOT PASSWORD ====
# https://github.com/wekan/wekan/wiki/Forgot-Password
# https://github.com/wekan/wekan/blob/main/docs/Login/Forgot-Password.md
#---------------------------------------------------------------------------------------------------------
# ==== Upgrading Wekan to new version =====
# NOTE: MongoDB has changed from 3.x to 4.x, in that case you need backup/restore with --noIndexRestore
# see https://github.com/wekan/wekan/wiki/Backup
# see https://github.com/wekan/wekan/tree/main/docs/Backup
# 1) Stop Wekan:
# docker compose stop
# 2) Remove old Wekan app (wekan-app only, not that wekan-db container that has all your data)
@@ -46,7 +46,7 @@
# docker compose stop
# ----------------------------------------------------------------------------------
# ===== INSIDE DOCKER CONTAINERS, AND BACKUP/RESTORE ====
# https://github.com/wekan/wekan/wiki/Backup
# https://github.com/wekan/wekan/tree/main/docs/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
@@ -89,7 +89,7 @@ services:
wekandb:
#-------------------------------------------------------------------------------------
# ==== MONGODB FROM DOCKER HUB ====
image: mongo:6
image: mongo:7
#-------------------------------------------------------------------------------------
container_name: wekan-db
restart: always
@@ -163,9 +163,12 @@ services:
# ap-southeast-1,ap-northeast-1,sa-east-1
#
#- S3='{"s3":{"key": "xxx", "secret": "xxx", "bucket": "xxx", "region": "xxx"}}'
#- S3_SECRET_FILE=/run/secrets/s3_secret
#-----------------------------------------------------------------
# ==== MONGO_URL ====
- MONGO_URL=mongodb://wekandb:27017/wekan
#- MONGO_URL=mongodb://username:password@wekandb:27017/wekan
#- MONGO_PASSWORD_FILE=/run/secrets/mongo_password
#---------------------------------------------------------------
# ==== ROOT_URL SETTING ====
# Change ROOT_URL to your real Wekan URL, for example:
@@ -183,7 +186,7 @@ services:
# ==== EMAIL SETTINGS ====
# Email settings are only at MAIL_URL and MAIL_FROM.
# Admin Panel has test button, but it's not used for settings.
# see https://github.com/wekan/wekan/wiki/Troubleshooting-Mail
# see https://github.com/wekan/wekan/blob/main/docs/Email/Troubleshooting-Mail.md
# 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
@@ -194,6 +197,7 @@ services:
#- MAIL_SERVICE=Outlook365
#- MAIL_SERVICE_USER=firstname.lastname@hotmail.com
#- MAIL_SERVICE_PASSWORD=SecretPassword
#- MAIL_SERVICE_PASSWORD_FILE=/run/secrets/mail_service_password
#---------------------------------------------------------------
# https://github.com/wekan/wekan/issues/3585#issuecomment-1021522132
# Add more Node heap, this is done by default at Dockerfile:
@@ -228,7 +232,7 @@ services:
#- APM_APP_SECRET=
#---------------------------------------------------------------
# ==== OPTIONAL: LOGS AND STATS ====
# https://github.com/wekan/wekan/wiki/Logs
# https://github.com/wekan/wekan/blob/main/docs/Features/Logs.md
#
# Daily export of Wekan changes as JSON to Logstash and ElasticSearch / Kibana (ELK)
# https://github.com/wekan/wekan-logstash
@@ -252,7 +256,7 @@ services:
#---------------------------------------------------------------
# ==== 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/blob/main/docs/API/REST-API.md
# https://github.com/wekan/wekan-gogs
# If you disable Wekan API with false, Export Board does not work.
- WITH_API=true
@@ -361,7 +365,7 @@ services:
#- TRUSTED_URL=https://intra.example.com
#-----------------------------------------------------------------
# ==== METRICS ALLOWED IP ADDRESSES ====
# https://github.com/wekan/wekan/wiki/Metrics
# https://github.com/wekan/wekan/blob/main/docs/Features/Metrics.md
#- METRICS_ALLOWED_IP_ADDRESSES=192.168.0.100,192.168.0.200
#-----------------------------------------------------------------
# ==== OUTGOING WEBHOOKS ====
@@ -372,14 +376,14 @@ services:
#- DEBUG=true
#---------------------------------------------
# ==== AUTOLOGIN WITH OIDC/OAUTH2 ====
# https://github.com/wekan/wekan/wiki/autologin
# https://github.com/wekan/wekan/blob/main/docs/Login/autologin.md
#- OIDC_REDIRECTION_ENABLED=true
#-----------------------------------------------------------------
# ==== OAUTH2 ORACLE on premise identity manager OIM ====
#- ORACLE_OIM_ENABLED=true
#-----------------------------------------------------------------
# ==== OAUTH2 AZURE ====
# https://github.com/wekan/wekan/wiki/Azure
# https://github.com/wekan/wekan/blob/main/docs/Login/Azure/Azure.md
# 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
@@ -397,6 +401,7 @@ services:
#- OAUTH2_CLIENT_ID=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
# Secret key generated during app registration:
#- OAUTH2_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
#- OAUTH2_SERVER_URL=https://login.microsoftonline.com/
#- OAUTH2_AUTH_ENDPOINT=/oauth2/v2.0/authorize
#- OAUTH2_USERINFO_ENDPOINT=https://graph.microsoft.com/oidc/userinfo
@@ -423,6 +428,7 @@ services:
#- OAUTH2_CLIENT_ID=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
# Secret key generated during app registration:
#- OAUTH2_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
#- OAUTH2_SERVER_URL=https://your-nextcloud.tld
#- OAUTH2_AUTH_ENDPOINT=/index.php/apps/oauth2/authorize
#- OAUTH2_USERINFO_ENDPOINT=/ocs/v2.php/cloud/user?format=json
@@ -437,7 +443,7 @@ services:
#- OAUTH2_EMAIL_MAP=email
#-----------------------------------------------------------------
# ==== OAUTH2 KEYCLOAK ====
# https://github.com/wekan/wekan/wiki/Keycloak <== MAPPING INFO, REQUIRED
# https://github.com/wekan/wekan/blob/main/docs/Login/Keycloak/Keycloak.md <== MAPPING INFO, REQUIRED
#- OAUTH2_ENABLED=true
# OAuth2 login style: popup or redirect.
#- OAUTH2_LOGIN_STYLE=redirect
@@ -447,6 +453,7 @@ services:
#- 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_SECRET_FILE=/run/secrets/oauth2_secret
#- OAUTH2_ID_MAP=sub
#- OAUTH2_USERNAME_MAP=preferred_username
#- OAUTH2_EMAIL_MAP=email
@@ -454,16 +461,17 @@ services:
#-----------------------------------------------------------------
# ==== OAUTH2 DOORKEEPER ====
# https://github.com/wekan/wekan/issues/1874
# https://github.com/wekan/wekan/wiki/OAuth2
# https://github.com/wekan/wekan/blob/main/docs/Login/OAuth2.md2
# Enable the OAuth2 connection
#- OAUTH2_ENABLED=true
# OAuth2 docs: https://github.com/wekan/wekan/wiki/OAuth2
# OAuth2 docs: https://github.com/wekan/wekan/blob/main/docs/Login/OAuth2.md
# OAuth2 login style: popup or redirect.
#- OAUTH2_LOGIN_STYLE=redirect
# OAuth2 Client ID.
#- OAUTH2_CLIENT_ID=abcde12345
# OAuth2 Secret.
#- OAUTH2_SECRET=54321abcde
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
# OAuth2 Server URL.
#- OAUTH2_SERVER_URL=https://chat.example.com
# OAuth2 Authorization Endpoint.
@@ -486,8 +494,8 @@ services:
#- 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
# https://github.com/wekan/wekan/blob/main/docs/Login/LDAP.md
# For Snap settings see https://github.com/wekan/wekan/blob/main/docs/Platforms/FOSS/Snap/Supported-settings-keys.md
# 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.
#
@@ -570,6 +578,7 @@ services:
#
# The password for the search user
#- LDAP_AUTHENTIFICATION_PASSWORD=pwd
#- LDAP_AUTHENTIFICATION_PASSWORD_FILE=/run/secrets/ldap_auth_password
#
# Enable logs for the module
#- LDAP_LOG_ENABLED=true
@@ -577,10 +586,14 @@ services:
# If the sync of the users should be done in the background
#- LDAP_BACKGROUND_SYNC=false
#
# At which interval does the background task sync.
# LDAP_BACKGROUND_SYNC_INTERVAL : At which interval does the background task sync in milliseconds
# The format must be as specified in:
# https://bunkat.github.io/later/parsers.html#text
#- LDAP_BACKGROUND_SYNC_INTERVAL=every 1 hour
#- LDAP_BACKGROUND_SYNC_INTERVAL=every 1 hours
# At which interval does the background task sync in milliseconds.
# Leave this unset, so it uses default, and does not crash.
# https://github.com/wekan/wekan/issues/2354#issuecomment-515305722
- LDAP_BACKGROUND_SYNC_INTERVAL=''
#
#- LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false
#
@@ -721,6 +734,12 @@ services:
volumes:
- /etc/localtime:/etc/localtime:ro
- wekan-files:/data:rw
secrets:
- ldap_auth_password
- oauth2_secret
- mail_service_password
- mongo_password
- s3_secret
#---------------------------------------------------------------------------------
# ==== OPTIONAL: SHARE DATABASE TO OFFICE LAN AND REMOTE VPN ====
@@ -782,3 +801,19 @@ volumes:
networks:
wekan-tier:
driver: bridge
# Docker Compose Secrets
# Create secret files on the host system before running docker-compose up
# Example: echo "your_password_here" > ldap_auth_password.txt
# Then use: docker-compose up -d
secrets:
ldap_auth_password:
file: ./secrets/ldap_auth_password.txt
oauth2_secret:
file: ./secrets/oauth2_secret.txt
mail_service_password:
file: ./secrets/mail_service_password.txt
mongo_password:
file: ./secrets/mongo_password.txt
s3_secret:
file: ./secrets/s3_secret.txt
+37 -2
View File
@@ -167,9 +167,12 @@ services:
# ap-southeast-1,ap-northeast-1,sa-east-1
#
#- S3='{"s3":{"key": "xxx", "secret": "xxx", "bucket": "xxx", "region": "xxx"}}'
#- S3_SECRET_FILE=/run/secrets/s3_secret
#-----------------------------------------------------------------
# ==== MONGO_URL ====
- MONGO_URL=mongodb://wekandb:27017/wekan
#- MONGO_URL=mongodb://username:password@wekandb:27017/wekan
#- MONGO_PASSWORD_FILE=/run/secrets/mongo_password
#---------------------------------------------------------------
# ==== ROOT_URL SETTING ====
# Change ROOT_URL to your real Wekan URL, for example:
@@ -198,6 +201,7 @@ services:
#- MAIL_SERVICE=Outlook365
#- MAIL_SERVICE_USER=firstname.lastname@hotmail.com
#- MAIL_SERVICE_PASSWORD=SecretPassword
#- MAIL_SERVICE_PASSWORD_FILE=/run/secrets/mail_service_password
#---------------------------------------------------------------
# https://github.com/wekan/wekan/issues/3585#issuecomment-1021522132
# Add more Node heap, this is done by default at Dockerfile:
@@ -399,6 +403,7 @@ services:
#- OAUTH2_CLIENT_ID=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
# Secret key generated during app registration:
#- OAUTH2_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
#- OAUTH2_SERVER_URL=https://login.microsoftonline.com/
#- OAUTH2_AUTH_ENDPOINT=/oauth2/v2.0/authorize
#- OAUTH2_USERINFO_ENDPOINT=https://graph.microsoft.com/oidc/userinfo
@@ -425,6 +430,7 @@ services:
#- OAUTH2_CLIENT_ID=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
# Secret key generated during app registration:
#- OAUTH2_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
#- OAUTH2_SERVER_URL=https://your-nextcloud.tld
#- OAUTH2_AUTH_ENDPOINT=/index.php/apps/oauth2/authorize
#- OAUTH2_USERINFO_ENDPOINT=/ocs/v2.php/cloud/user?format=json
@@ -449,6 +455,7 @@ services:
#- 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_SECRET_FILE=/run/secrets/oauth2_secret
#-----------------------------------------------------------------
# ==== OAUTH2 DOORKEEPER ====
# https://github.com/wekan/wekan/issues/1874
@@ -462,6 +469,7 @@ services:
#- OAUTH2_CLIENT_ID=abcde12345
# OAuth2 Secret.
#- OAUTH2_SECRET=54321abcde
#- OAUTH2_SECRET_FILE=/run/secrets/oauth2_secret
# OAuth2 Server URL.
#- OAUTH2_SERVER_URL=https://chat.example.com
# OAuth2 Authorization Endpoint.
@@ -568,6 +576,7 @@ services:
#
# The password for the search user
#- LDAP_AUTHENTIFICATION_PASSWORD=pwd
#- LDAP_AUTHENTIFICATION_PASSWORD_FILE=/run/secrets/ldap_auth_password
#
# Enable logs for the module
#- LDAP_LOG_ENABLED=true
@@ -575,10 +584,14 @@ services:
# If the sync of the users should be done in the background
#- LDAP_BACKGROUND_SYNC=false
#
# At which interval does the background task sync.
# LDAP_BACKGROUND_SYNC_INTERVAL : At which interval does the background task sync in milliseconds
# The format must be as specified in:
# https://bunkat.github.io/later/parsers.html#text
#- LDAP_BACKGROUND_SYNC_INTERVAL=every 1 hour
#- LDAP_BACKGROUND_SYNC_INTERVAL=every 1 hours
# At which interval does the background task sync in milliseconds.
# Leave this unset, so it uses default, and does not crash.
# https://github.com/wekan/wekan/issues/2354#issuecomment-515305722
- LDAP_BACKGROUND_SYNC_INTERVAL=''
#
#- LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false
#
@@ -719,6 +732,12 @@ services:
volumes:
- /etc/localtime:/etc/localtime:ro
- wekan-files:/data:rw
secrets:
- ldap_auth_password
- oauth2_secret
- mail_service_password
- mongo_password
- s3_secret
#---------------------------------------------------------------------------------
# ==== OPTIONAL: SHARE DATABASE TO OFFICE LAN AND REMOTE VPN ====
@@ -780,3 +799,19 @@ volumes:
networks:
wekan-tier:
driver: bridge
# Docker Compose Secrets
# Create secret files on the host system before running docker-compose up
# Example: echo "your_password_here" > ldap_auth_password.txt
# Then use: docker-compose up -d
secrets:
ldap_auth_password:
file: ./secrets/ldap_auth_password.txt
oauth2_secret:
file: ./secrets/oauth2_secret.txt
mail_service_password:
file: ./secrets/mail_service_password.txt
mongo_password:
file: ./secrets/mongo_password.txt
s3_secret:
file: ./secrets/s3_secret.txt
@@ -40,7 +40,7 @@ Optional, and defaults:
- "permission":"private" <== Set to "public" if you want public Wekan board
- "color":"belize" <== Board color: belize, nephritis, pomegranate, pumpkin, wisteria, midnight.
<img src="https://wekan.github.io/board-colors.png" width="40%" alt="Wekan logo" />
<img src="https://wekan.fi/board-colors.png" width="40%" alt="Wekan logo" />
Example:
```
File renamed without changes.
File renamed without changes.
@@ -28,6 +28,6 @@ https://github.com/wekan/wekan/blob/main/api.py
### 4) API Docs
https://wekan.github.io/api/
https://wekan.fi/api/
Building API Docs: https://github.com/wekan/wekan/blob/main/releases/rebuild-docs.sh
@@ -2,10 +2,10 @@
https://github.com/wekan/wekan/wiki/REST-API#example-call---as-form-data
2) There needs to be Custom Field added to board
https://wekan.github.io/api/v4.42/#wekan-rest-api-customfields
https://wekan.fi/api/v4.42/#wekan-rest-api-customfields
3) Custom Field at board and card will have same `_id`
https://wekan.github.io/api/v4.42/#put_board_list_card
https://wekan.fi/api/v4.42/#put_board_list_card
4) When writing Custom Field value to card, like text field, content type needs to be "application/json" and the string needs to be an array:
```
File renamed without changes.
File renamed without changes.
@@ -3,7 +3,7 @@ Wekan provides a python script to ease the call of the REST API from command lin
# Context
- [API Login to get Bearer token](REST-API#example-call---as-form-data)
- [API docs and examples for various programming languages](https://wekan.github.io/api/), there is Boards / Export for exporting board with API
- [API docs and examples for various programming languages](https://wekan.fi/api/), there is Boards / Export for exporting board with API
- In the right menu, scroll down REST API Docs etc links =====>
- Wekan-Gogs integration with Node.js https://github.com/wekan/wekan-gogs
@@ -4,7 +4,7 @@ BoardAdmin can change role of user at right sidebar / click avatar / select role
# Change Role with API
- https://wekan.github.io/api/
- https://wekan.fi/api/
- api.py at https://github.com/wekan/wekan
- Login to API https://github.com/wekan/wekan/wiki/REST-API#example-call---as-json
File renamed without changes.
Loaded 100 of 553 files, more files were not shown because too many files have changed in this diff. Show more