Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f5670e830 | ||
|
|
108b18cebf | ||
|
|
814ac22a0d | ||
|
|
3814a218c2 | ||
|
|
3fda90612d | ||
|
|
05762aa50c | ||
|
|
9a31371de0 | ||
|
|
b9b7143185 | ||
|
|
972721bdb5 | ||
|
|
3a48982916 | ||
|
|
6b3a6f9f7d | ||
|
|
48fddecb62 | ||
|
|
7f0d1cc5b3 | ||
|
|
70e82be0b4 | ||
|
|
5fc0809844 | ||
|
|
c79990bcd9 | ||
|
|
cd9e7412ea | ||
|
|
3e472606b5 | ||
|
|
2966bc3204 | ||
|
|
5dc6093eec | ||
|
|
86fc60f5ba | ||
|
|
8189a3f9ab | ||
|
|
76a65e2533 | ||
|
|
ad2914934e | ||
|
|
2769ba2874 | ||
|
|
294f1e178e | ||
|
|
c994d34bb8 | ||
|
|
42b5dd0751 | ||
|
|
f884d6d471 | ||
|
|
abe915a8d6 | ||
|
|
a2e8de2fd8 | ||
|
|
e34ca6a8a5 | ||
|
|
596c9de603 | ||
|
|
4170361a1c | ||
|
|
978a36ea77 | ||
|
|
8745ef7de8 | ||
|
|
2ce929b7b3 | ||
|
|
2dcdfa2862 | ||
|
|
b18daac9c9 | ||
|
|
606041a00d | ||
|
|
4ed5952a81 | ||
|
|
37bfce2eb7 | ||
|
|
59541699ce | ||
|
|
af73c16e37 | ||
|
|
673b09b84b | ||
|
|
09f8edfead | ||
|
|
e1ebdeca4f | ||
|
|
31769aa4af | ||
|
|
b32ad86ce7 | ||
|
|
7350473a65 | ||
|
|
1c87e337d6 | ||
|
|
dec038e7ed | ||
|
|
ebe6f7813e | ||
|
|
706dbfacac | ||
|
|
62ad588aa9 | ||
|
|
3c776e2ab6 | ||
|
|
ab4e2d1ed6 | ||
|
|
5e90c4a142 | ||
|
|
9a7fa25ca3 | ||
|
|
65cb0641f3 | ||
|
|
6f2b891214 | ||
|
|
44d7ab83ec | ||
|
|
b328cc3f6a | ||
|
|
836226a8d3 | ||
|
|
2083f6630a | ||
|
|
25e1e9028f | ||
|
|
a5651c686f | ||
|
|
93f0e0b125 | ||
|
|
730bb6d166 | ||
|
|
855bac59bf | ||
|
|
870900b92a | ||
|
|
a1d5802d36 | ||
|
|
6e16fa3992 | ||
|
|
ee3b49ce59 | ||
|
|
3253dd5010 | ||
|
|
a10d8e0438 | ||
|
|
5151814e98 | ||
|
|
2e2a0f01f4 | ||
|
|
dec9b82da0 | ||
|
|
33f4db5871 | ||
|
|
9a086c0397 | ||
|
|
013ddb8978 | ||
|
|
c4161c5ce6 | ||
|
|
392b8dd5b2 | ||
|
|
d19eb801f3 | ||
|
|
ed416ca555 | ||
|
|
106009316f | ||
|
|
cb10ad3a20 | ||
|
|
2fad0099e4 | ||
|
|
454416b0bd | ||
|
|
dd80b7308b | ||
|
|
fe5c5f1bdc | ||
|
|
79074deb34 | ||
|
|
db0294c95e | ||
|
|
8f0fa88eac | ||
|
|
946f7045e9 | ||
|
|
dda8c90d44 | ||
|
|
701485d76a | ||
|
|
b25198b87e | ||
|
|
ad7e3774c2 | ||
|
|
ee67dea96c | ||
|
|
b3d3bf1593 | ||
|
|
53726fed24 | ||
|
|
7d2ca2c811 | ||
|
|
c0d10a0ec3 | ||
|
|
8e01e3c762 | ||
|
|
04be599893 | ||
|
|
f6cb7fddf1 | ||
|
|
a662283b7d | ||
|
|
f34490fe28 | ||
|
|
1a98c86a37 | ||
|
|
97b5931a4f | ||
|
|
2a4dd9b693 | ||
|
|
ecf31c3675 | ||
|
|
9b0d0a2b7c | ||
|
|
e2ffca2e39 | ||
|
|
a8435879cf | ||
|
|
e16695585a | ||
|
|
a7bcfc6db7 | ||
|
|
21bed98d69 | ||
|
|
044793cc44 | ||
|
|
083a7050b9 | ||
|
|
cc78e19740 | ||
|
|
ee01a07b0a | ||
|
|
ce528b1826 | ||
|
|
92c0543614 | ||
|
|
b6638f4a29 | ||
|
|
96be56a620 | ||
|
|
2e555e420a | ||
|
|
a849951c53 | ||
|
|
435cb04717 | ||
|
|
25a375261e | ||
|
|
1a1a44616f | ||
|
|
e6347a305c | ||
|
|
b137108ae1 | ||
|
|
4ce7ff7cef | ||
|
|
184415a026 | ||
|
|
3977adcb8f | ||
|
|
1c47f98f59 | ||
|
|
9f0c37352e | ||
|
|
7a20fa4805 | ||
|
|
6a713d9e8d | ||
|
|
51b0544752 | ||
|
|
1022a7aa3a | ||
|
|
c048678844 | ||
|
|
f9fb02457c | ||
|
|
ce419ce64e | ||
|
|
ecb6ff57fc | ||
|
|
663866562f | ||
|
|
dfdd0b6cbb | ||
|
|
c81ca82822 | ||
|
|
66b067eb49 | ||
|
|
4e9f2dc46a | ||
|
|
f02d8b61b5 | ||
|
|
088de1877c | ||
|
|
4611abffed | ||
|
|
f206f2f45c | ||
|
|
9c5f5757be | ||
|
|
ec2e0f6fed | ||
|
|
ae0d059b6f | ||
|
|
0132b801b2 | ||
|
|
06ca564ec2 | ||
|
|
d83ce5e633 | ||
|
|
5287319fde | ||
|
|
c75a23e693 | ||
|
|
180bf930c1 | ||
|
|
c16e99ba1e | ||
|
|
b9887fc917 | ||
|
|
96b36bd8ef | ||
|
|
0e32f666eb | ||
|
|
1341fc6a98 | ||
|
|
81c9e96bf3 | ||
|
|
20f91ef893 | ||
|
|
1187254573 | ||
|
|
f22fb4f4a9 | ||
|
|
a14762e005 | ||
|
|
9a91214043 | ||
|
|
30795a46cf | ||
|
|
b0865c8d06 | ||
|
|
c2aabbc6db | ||
|
|
4aad3dafd4 | ||
|
|
62269a9902 | ||
|
|
4bc2fd4a7f | ||
|
|
0e43a08689 | ||
|
|
77b1416413 | ||
|
|
200545822c | ||
|
|
ac33f2164f | ||
|
|
e82ca8a1f4 | ||
|
|
f894f9ef6d | ||
|
|
ccfd8ef566 | ||
|
|
6c6b66c802 | ||
|
|
2cb2e7cb10 | ||
|
|
8744f47a0e | ||
|
|
b742b25f96 | ||
|
|
6d7c20f397 | ||
|
|
f3d384c1dd | ||
|
|
69ce79a7b9 | ||
|
|
1cd191f76b | ||
|
|
afc3c29341 | ||
|
|
fedb3040d1 | ||
|
|
0a969c59d3 | ||
|
|
d9fb9f49fd | ||
|
|
fc77d0d201 | ||
|
|
56700d1d06 | ||
|
|
84259c5116 | ||
|
|
6cc746df8b | ||
|
|
b3ad06692f | ||
|
|
bb0814bb11 | ||
|
|
722faf8aaa | ||
|
|
159324858b | ||
|
|
f73a370719 | ||
|
|
dfc658b910 | ||
|
|
0a52f470b7 | ||
|
|
e4822d8bc4 | ||
|
|
9d1cab3ac2 | ||
|
|
6d16ec238a | ||
|
|
e0284f225b | ||
|
|
a5acd0801a | ||
|
|
d59337ae47 | ||
|
|
2f27a3f839 | ||
|
|
450b33f98a | ||
|
|
9adf5027fa | ||
|
|
1610b84845 | ||
|
|
40b2cf88fc | ||
|
|
55ef6c0c56 | ||
|
|
a9c67ac200 | ||
|
|
3892be47ac | ||
|
|
a2654b2e29 | ||
|
|
a052cc8fa5 | ||
|
|
5d09100cb6 | ||
|
|
76769d1b85 | ||
|
|
2cf57250e8 | ||
|
|
5d0a0c931f | ||
|
|
fa1adfec76 | ||
|
|
9271b07383 | ||
|
|
4fe955650a | ||
|
|
6b401000b9 | ||
|
|
aa681cde88 | ||
|
|
0921c6ea53 | ||
|
|
2df73bedee | ||
|
|
938fe49b2c | ||
|
|
7e2e649a8e | ||
|
|
6e11aa27f8 | ||
|
|
57ee624398 | ||
|
|
3cba95b60a | ||
|
|
bd796ce642 | ||
|
|
3a8473e632 | ||
|
|
89480b61ce | ||
|
|
c5e5bb613e | ||
|
|
b52d1ca6c4 | ||
|
|
790bafbb09 | ||
|
|
c256ce6968 | ||
|
|
85465e0dfb | ||
|
|
b7409c1d0b | ||
|
|
4060d33bbc | ||
|
|
6526d99123 | ||
|
|
1b44c848ad | ||
|
|
e6980be061 | ||
|
|
81c77650b4 | ||
|
|
791e37dd9c | ||
|
|
f926448bbb | ||
|
|
7128f067d0 | ||
|
|
59ab6c1cd8 | ||
|
|
89105b6e72 | ||
|
|
51e43f1c25 | ||
|
|
9b24d644a4 | ||
|
|
2549e0e4c8 | ||
|
|
d974fa638c | ||
|
|
f399b5119f | ||
|
|
12d3fabdb7 | ||
|
|
d5727f5b15 | ||
|
|
1908d04fd4 | ||
|
|
c7f8c828cb | ||
|
|
054d0913fd | ||
|
|
ca7dc69c85 | ||
|
|
b2ff51d99c | ||
|
|
abd4b6bd87 | ||
|
|
b92d07c9a6 | ||
|
|
c6204417a3 | ||
|
|
3a23401443 | ||
|
|
12e6e46924 | ||
|
|
be1b959519 | ||
|
|
7841c9e801 | ||
|
|
bc486e2a7d | ||
|
|
d01885e2ad | ||
|
|
358ffe0601 | ||
|
|
8d0bf1b758 | ||
|
|
c7961cf2f4 | ||
|
|
2ac374e578 | ||
|
|
ad3306e19e | ||
|
|
f54cbac370 | ||
|
|
4bfc0140be | ||
|
|
cc7459b983 | ||
|
|
11415cd517 | ||
|
|
9aa028f32d | ||
|
|
2a415cbd26 | ||
|
|
40a52da2d3 | ||
|
|
31e043c1d7 | ||
|
|
985afafed0 | ||
|
|
3a4d20ecb2 | ||
|
|
35b524f179 | ||
|
|
d2f17ef140 | ||
|
|
d99864ca95 | ||
|
|
e6e1191f8a | ||
|
|
1f10c20874 | ||
|
|
c699f7a940 | ||
|
|
7115c292c7 | ||
|
|
7744b14b48 | ||
|
|
6fed9e73d8 | ||
|
|
e14a3f9c2d | ||
|
|
7bf75b1ff7 | ||
|
|
6905e24199 | ||
|
|
9eb25c09da | ||
|
|
c97f5ffca3 | ||
|
|
eb19168b5f | ||
|
|
e421b68766 | ||
|
|
6b86625c56 | ||
|
|
254b6dd5c7 | ||
|
|
7b545d12c7 | ||
|
|
01ed20b400 | ||
|
|
fad930833a | ||
|
|
9192fbee44 | ||
|
|
aaa5f9885d | ||
|
|
1979b1692d | ||
|
|
fc31eeca88 | ||
|
|
6d4de76a9a | ||
|
|
9245ba4a5b | ||
|
|
973a788c21 | ||
|
|
0d5df8d3cf | ||
|
|
b67a236657 | ||
|
|
170617d457 | ||
|
|
cc2f359b6c | ||
|
|
c0d44a8686 | ||
|
|
a1700f38b1 | ||
|
|
b82ba63532 | ||
|
|
dbd1324a90 | ||
|
|
e52158b729 | ||
|
|
68a717cf47 | ||
|
|
c0a9780f80 | ||
|
|
0520129a40 | ||
|
|
6b36e126ab | ||
|
|
3cb4662363 | ||
|
|
cef14f301f | ||
|
|
eca4a0c440 | ||
|
|
cea04b2ada | ||
|
|
b7d9af9ae7 | ||
|
|
0046b3c802 | ||
|
|
25384c8ac3 | ||
|
|
2eee72da8a | ||
|
|
d65c422e3f | ||
|
|
2ab9bd3172 | ||
|
|
a0b5c2e88c | ||
|
|
0bd4108661 | ||
|
|
7d1a1475ba | ||
|
|
6418263165 | ||
|
|
b32c835cf9 | ||
|
|
a927685bc6 | ||
|
|
6827d40e84 | ||
|
|
9aa12b0eb6 | ||
|
|
8ca1a36d78 | ||
|
|
394f2eae69 | ||
|
|
7588459c3e | ||
|
|
2c33f45a6a | ||
|
|
43cf0b66ac | ||
|
|
c05f6fcff2 | ||
|
|
a4eb32158b | ||
|
|
072ced9d0e | ||
|
|
c5fefc1414 | ||
|
|
c825895ceb | ||
|
|
9488972ed8 | ||
|
|
1f4bed38f7 | ||
|
|
747112957a | ||
|
|
18228096f9 | ||
|
|
d0ea5bf500 | ||
|
|
74fe91fa3a | ||
|
|
d4e3075fcc | ||
|
|
413ae5f20e | ||
|
|
e23f86f542 | ||
|
|
b3c47dbe84 | ||
|
|
b10c2b9a15 | ||
|
|
bb6910acd1 | ||
|
|
76b000820e | ||
|
|
50b874629c | ||
|
|
4d145ab4ad | ||
|
|
4d67a4641f | ||
|
|
bc2eab6f9d | ||
|
|
3ccce75863 | ||
|
|
b390b266e2 | ||
|
|
561af8926c | ||
|
|
5717dc2cf4 | ||
|
|
d0e64ad6d2 | ||
|
|
8e1a735ec7 | ||
|
|
1301d67295 | ||
|
|
7c239f5218 | ||
|
|
61235c953c | ||
|
|
ea65a0308d | ||
|
|
f840b07c02 | ||
|
|
8af719d39e | ||
|
|
c1a4250bd2 | ||
|
|
b4b442f8a8 | ||
|
|
b7e76fcfa1 | ||
|
|
01950cc796 | ||
|
|
14f2022e21 | ||
|
|
23bac73559 | ||
|
|
2de9b94b01 | ||
|
|
05d1736f5f | ||
|
|
db5346fc5c | ||
|
|
f09f5bd737 | ||
|
|
d96a1a5c9e | ||
|
|
ad3cc9c087 | ||
|
|
d0c7bf65a4 | ||
|
|
bb6ac70f63 | ||
|
|
c38b9da7d6 | ||
|
|
19153ca489 | ||
|
|
8e7a5e8cb5 | ||
|
|
1407059937 | ||
|
|
a2911bc9c3 | ||
|
|
f99b735746 | ||
|
|
4510ddda15 | ||
|
|
028ec46f46 | ||
|
|
c0e4e01deb | ||
|
|
cfcf682134 | ||
|
|
27bd9817d7 | ||
|
|
dc389a68ab | ||
|
|
6d982cdfd9 | ||
|
|
827ee615c1 | ||
|
|
f5f0ba721e | ||
|
|
1344f85986 | ||
|
|
e7462ada12 | ||
|
|
11199b6225 | ||
|
|
345aece0f2 | ||
|
|
912c84422b | ||
|
|
b402676079 | ||
|
|
908a5fc60d | ||
|
|
38e57d3635 | ||
|
|
14167b19b9 | ||
|
|
fc548b426d | ||
|
|
094f13934c | ||
|
|
71acd9603e | ||
|
|
341f655ab7 | ||
|
|
0c5323c106 | ||
|
|
7f871fdf30 | ||
|
|
6347b40a02 | ||
|
|
bce84a432a | ||
|
|
b6fc4deb63 | ||
|
|
6b48f9e259 | ||
|
|
44b7666426 | ||
|
|
ef70ed76a2 | ||
|
|
a1a1b3d1ee | ||
|
|
0326757399 | ||
|
|
edbc8ed92b | ||
|
|
07e9ec0617 | ||
|
|
18d0fa4327 | ||
|
|
666ee84033 | ||
|
|
120642f47d | ||
|
|
148b81262d | ||
|
|
c41467f76e | ||
|
|
c83e83b8b1 | ||
|
|
563a508e26 | ||
|
|
1d8347cc23 | ||
|
|
874abf2c41 | ||
|
|
3e18f820ea | ||
|
|
b571f1c953 | ||
|
|
fd69c7ceb8 | ||
|
|
d15faa1890 | ||
|
|
0c7e12c5e7 | ||
|
|
36a3077853 | ||
|
|
51bc23dbd9 | ||
|
|
0b1e0bd395 | ||
|
|
151aafd114 | ||
|
|
16c8a65a1c | ||
|
|
f3133e9cd8 | ||
|
|
de84aa7674 | ||
|
|
1bdbfe86bb | ||
|
|
397b9f439e | ||
|
|
261e0aee0f | ||
|
|
a6d9bde658 | ||
|
|
8d0a07e1a8 | ||
|
|
659615e6f2 | ||
|
|
9f0b82c0d5 | ||
|
|
9a23dcc991 | ||
|
|
980d345305 | ||
|
|
41f76ee974 | ||
|
|
83a60e6303 | ||
|
|
7b23c85117 | ||
|
|
ff3900d100 | ||
|
|
e5e4b8ebfb | ||
|
|
9516b75d65 | ||
|
|
6b1a92001a | ||
|
|
e4e1fdb187 | ||
|
|
58ad80218a | ||
|
|
3322d3b33d | ||
|
|
bd9d0c2d1b | ||
|
|
02b99e0555 | ||
|
|
f803190dd2 | ||
|
|
deb3a8389a | ||
|
|
e7d02c12eb | ||
|
|
169eaa180b | ||
|
|
08cde06ce5 | ||
|
|
4607bfe454 | ||
|
|
de0eece27c | ||
|
|
25ad901fb3 | ||
|
|
99e579f47d |
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,3 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
custom: ['https://wekan.team/commercial-support/']
|
||||
custom: ['https://wekan.fi/commercial-support/']
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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' }}
|
||||
|
||||
@@ -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)
|
||||
@@ -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 }}"
|
||||
@@ -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/
|
||||
|
||||
@@ -1,19 +1,562 @@
|
||||
[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.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 +2461,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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
@@ -203,36 +158,134 @@ ENV WITH_API=true \
|
||||
WRITABLE_PATH=/data \
|
||||
S3=""
|
||||
|
||||
# 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.97/wekan-7.97-amd64.zip"
|
||||
unzip wekan-7.97-amd64.zip
|
||||
rm wekan-7.97-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"]
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
---
|
||||
@@ -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,5 +1,5 @@
|
||||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v7.78.0"
|
||||
appVersion: "v7.97.0"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
||||
@@ -33,6 +33,17 @@
|
||||
.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 .board-canvas.mobile-view .swimlane {
|
||||
border-bottom: 1px solid #ccc;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
padding: 0 0px 0px 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.board-wrapper .board-canvas .swimlane {
|
||||
border-bottom: 1px solid #ccc;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -76,6 +76,179 @@ BlazeComponent.extendComponent({
|
||||
}
|
||||
},
|
||||
onRendered() {
|
||||
// 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 +499,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 +615,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 +758,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';
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -62,15 +62,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 +76,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 +86,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 +101,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 +118,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
|
||||
|
||||
@@ -192,6 +192,32 @@
|
||||
font-size: 25px;
|
||||
color: #fff;
|
||||
}
|
||||
/* Mobile view styles - applied when isMiniScreen is true (iPhone, etc.) */
|
||||
.board-list.mobile-view {
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
.board-list.mobile-view li {
|
||||
width: 50%;
|
||||
}
|
||||
.board-list.mobile-view .board-list-item {
|
||||
overflow: hidden;
|
||||
height: 8rem;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.board-list {
|
||||
height: 100%;
|
||||
@@ -218,6 +244,19 @@
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
/* Mobile view styles for very small screens - applied when isMiniScreen is true */
|
||||
.board-list.mobile-view li {
|
||||
width: 50%;
|
||||
}
|
||||
.board-list.mobile-view .board-handle {
|
||||
position: absolute;
|
||||
padding: 7px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 10px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 360px) {
|
||||
li {
|
||||
width: 100%;
|
||||
|
||||
@@ -29,7 +29,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'}}
|
||||
|
||||
@@ -239,34 +239,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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}}
|
||||
@@ -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'));
|
||||
|
||||
|
||||
@@ -225,3 +225,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'}}
|
||||
|
||||
@@ -46,6 +46,10 @@ BlazeComponent.extendComponent({
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
isWatching() {
|
||||
const card = this.currentData();
|
||||
return card.findWatcher(Meteor.userId());
|
||||
},
|
||||
|
||||
showMembers() {
|
||||
// cache "board" to reduce the mini-mongodb access
|
||||
@@ -125,6 +129,9 @@ Template.minicard.helpers({
|
||||
? Meteor.connection._lastSessionId
|
||||
: null;
|
||||
},
|
||||
isWatching() {
|
||||
return this.findWatcher(Meteor.userId());
|
||||
}
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
@@ -178,4 +185,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();
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -35,6 +35,7 @@ input[type="file"] {
|
||||
}
|
||||
input[type="radio"] {
|
||||
-webkit-appearance: radio;
|
||||
appearance: radio;
|
||||
min-height: inherit;
|
||||
}
|
||||
input[type="text"],
|
||||
@@ -96,8 +97,9 @@ 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 {
|
||||
@@ -109,7 +111,7 @@ select.inline {
|
||||
width: 100%;
|
||||
}
|
||||
option[disabled] {
|
||||
color: #8c8c8c;
|
||||
color: #222;
|
||||
}
|
||||
textarea {
|
||||
height: 150px;
|
||||
@@ -254,13 +256,13 @@ label {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
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 {
|
||||
@@ -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;
|
||||
|
||||
@@ -214,6 +214,125 @@
|
||||
#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%;
|
||||
border-left: 0px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.list.mobile-view {
|
||||
display: contents;
|
||||
flex-basis: auto;
|
||||
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;
|
||||
}
|
||||
.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;
|
||||
/* 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;
|
||||
@@ -267,24 +386,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 +419,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;
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
},
|
||||
*/
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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'}}
|
||||
@@ -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');
|
||||
@@ -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() {
|
||||
|
||||
@@ -23,12 +23,12 @@ 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
|
||||
//-
|
||||
@@ -61,12 +61,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
|
||||
|
||||
@@ -59,8 +59,12 @@ button {
|
||||
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;
|
||||
@@ -188,7 +192,10 @@ strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
p {
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
|
||||
|
||||
}
|
||||
p a {
|
||||
text-decoration: underline;
|
||||
@@ -207,7 +214,7 @@ pre,
|
||||
code,
|
||||
tt {
|
||||
font-family: lucida console, monospace;
|
||||
line-height: 1.25em;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
blockquote {
|
||||
margin: 8px 0 8px 8px;
|
||||
@@ -431,7 +438,8 @@ a:not(.disabled).is-active i.fa {
|
||||
.viewer em {
|
||||
font-style: italic;
|
||||
}
|
||||
.viewer pre {
|
||||
.viewer pre,
|
||||
.viewer code {
|
||||
padding: 10px 12px 7px;
|
||||
background: #dedede;
|
||||
overflow-y: auto;
|
||||
|
||||
@@ -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,16 @@ 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;")
|
||||
// Add autocomplete attribute to login input for WCAG compliance
|
||||
script.
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var 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');
|
||||
}
|
||||
});
|
||||
+Template.dynamic(template=content)
|
||||
if currentSetting.displayAuthenticationMethod
|
||||
+connectionMethod(authenticationMethod=currentSetting.defaultAuthenticationMethod)
|
||||
@@ -59,7 +71,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}}
|
||||
|
||||
@@ -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');
|
||||
@@ -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'}}
|
||||
@@ -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
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
@@ -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'}}
|
||||
|
||||
|
||||
@@ -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([]);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ✕
|
||||
.sidebar-content.js-board-sidebar-content
|
||||
//a.hide-btn.js-hide-sidebar
|
||||
@@ -39,6 +43,11 @@ template(name='homeSidebar')
|
||||
span {{_ 'enable-vertical-scrollbars'}}
|
||||
b
|
||||
.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
|
||||
.materialCheckBox(class="{{#if isShowWeekOfYear}}is-checked{{/if}}")
|
||||
hr
|
||||
unless currentUser.isNoComments
|
||||
h3.activity-title
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -250,36 +250,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.currentBoard.isTemplatesBoard() ? this.currentSwimlane._id : '',
|
||||
});
|
||||
|
||||
titleInput.value = '';
|
||||
titleInput.focus();
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
'click .js-list-template': Popup.open('searchElement'),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -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'
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -287,22 +287,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 +356,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 +376,9 @@ Utils = {
|
||||
|
||||
// returns if mini screen or desktop drag handles
|
||||
isTouchScreenOrShowDesktopDragHandles() {
|
||||
return this.isTouchScreen();
|
||||
//return this.isTouchScreen() || this.isShowDesktopDragHandles();
|
||||
return this.isShowDesktopDragHandles();
|
||||
//return this.isShowDesktopDragHandles();
|
||||
},
|
||||
|
||||
calculateIndexData(prevData, nextData, nItems = 1) {
|
||||
|
||||
@@ -57,6 +57,7 @@ AccountsTemplates.addFields([
|
||||
displayName: 'username',
|
||||
required: true,
|
||||
minLength: 2,
|
||||
autocomplete: 'username',
|
||||
},
|
||||
emailField,
|
||||
passwordField,
|
||||
|
||||
@@ -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
|
||||
@@ -183,7 +183,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
|
||||
@@ -228,7 +228,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 +252,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 +361,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 +372,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
|
||||
@@ -437,7 +437,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
|
||||
@@ -454,10 +454,10 @@ 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.
|
||||
@@ -486,8 +486,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.
|
||||
#
|
||||
@@ -577,10 +577,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
|
||||
#
|
||||
|
||||
@@ -575,10 +575,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
|
||||
#
|
||||
|
||||
@@ -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:
|
||||
```
|
||||
@@ -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:
|
||||
```
|
||||
@@ -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
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
Admin Panel / People / Click at right side of usename `...` button that is User Settings / Impersonate user.
|
||||
|
||||
You will be switched to logged in as that user.
|
||||
|
||||
To switch back to your original user, at your webbrowser click `Reload open webpage` round arrow button.
|
||||
|
||||
This feature was added to Wekan v4.39 at https://github.com/wekan/wekan/pull/3280
|
||||
|
||||
@@ -137,11 +137,11 @@ https://nosqlbooster.com/downloads
|
||||
|
||||
### At server where Wekan Snap is installed, MongoDB is running at localhost port 27019
|
||||
|
||||
<img src="https://wekan.github.io/nosqlbooster-basic-connection.png" width="60%" alt="Wekan logo" />
|
||||
<img src="nosqlbooster-basic-connection.png" width="60%" alt="NoSQLBooster basic connection" />
|
||||
|
||||
### You can tunnel via SSH to server, using password auth or private key auth dropdown selection
|
||||
|
||||
<img src="https://wekan.github.io/nosqlbooster-ssh-tunnel.png" width="60%" alt="Wekan logo" />
|
||||
<img src="nosqlbooster-ssh-tunnel.png" width="60%" alt="NoSQLBooster SSH tunnel" />
|
||||
|
||||
# Scheduled backups to local or remote server
|
||||
|
||||
|
||||
@@ -32,15 +32,15 @@ Instead of filesystem, Rclone mounted cloud filesystem directory can be used, li
|
||||
|
||||
Note: In some cases, only buttons `Move all attachments` at top are visible. In some other cases, there is more visible, like moving all attachments of board, etc, maybe when some have been already moved.
|
||||
|
||||
<img src="https://wekan.github.io/rclone/wekan-admin-panel.png" width="100%" alt="Wekan Admin Panel file move" />
|
||||
<img src="https://wekan.fi/rclone/wekan-admin-panel.png" width="100%" alt="Wekan Admin Panel file move" />
|
||||
|
||||
## Screenshot 2: Files at MinIO after moving all to filesystem
|
||||
|
||||
<img src="https://wekan.github.io/rclone/minio1.png" width="100%" alt="MinIO 1" />
|
||||
<img src="https://wekan.fi/rclone/minio1.png" width="100%" alt="MinIO 1" />
|
||||
|
||||
## Screenshot 3: Files at MinIO after moving all to filesystem
|
||||
|
||||
<img src="https://wekan.github.io/rclone/minio2.png" width="100%" alt="MinIO 2" />
|
||||
<img src="https://wekan.fi/rclone/minio2.png" width="100%" alt="MinIO 2" />
|
||||
|
||||
## Rclone config
|
||||
|
||||
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 58 KiB |
@@ -24,7 +24,7 @@ https://github.com/wekan/wekan/issues/5073
|
||||
|
||||
At step 12 below is actual repair MongoDB command.
|
||||
|
||||
Some customer of [WeKan Commercial Support](https://wekan.team/commercial-support/) ordered restore and repair of WeKan MongoDB database at UCS appliance. This was needed when changing back to previous UCS 4.x major version, when in new major UCS 5.x version Docker containers were all the time crashing and restarting, or something else got broken. Here are commands that were used while repairing.
|
||||
Some customer of [WeKan Commercial Support](https://wekan.fi/commercial-support/) ordered restore and repair of WeKan MongoDB database at UCS appliance. This was needed when changing back to previous UCS 4.x major version, when in new major UCS 5.x version Docker containers were all the time crashing and restarting, or something else got broken. Here are commands that were used while repairing.
|
||||
|
||||
Similarly, MongoDB may require repair, if:
|
||||
- MongoDB does not recover from sudden power failure cleanly
|
||||
|
||||
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 276 KiB |
@@ -10,6 +10,7 @@ There edit Browser-compatibility-matrix.md and attach it with .txt extension or
|
||||
Browser | [PWA](PWA) | Mobile | Desktop | OS
|
||||
------- | ----| ------ | ------- | -------
|
||||
Safari | iOS Yes | iOS Newest | Newest | iOS, macOS
|
||||
Iris | No | No | Newest | [Iris browser news](https://www.riscosopen.org/forum/forums/1/topics/19545), Download [RISC OS Direct](https://www.riscosdev.com/direct/) for Raspberry Pi etc. [Other versions of RISC OS for many ARM CPU devices](https://www.riscosopen.org/content/downloads) do not have Iris browser yet, but there could be some way to transfer Iris browser files from RISC OS Direct.
|
||||
|
||||
## Firefox based
|
||||
|
||||
@@ -17,15 +18,14 @@ Any telemetry at any Firefox based browser can be additionally most locked down
|
||||
|
||||
Browser | [PWA](PWA) | Mobile | Desktop | OS
|
||||
------- | ----| ------ | ------- | -------
|
||||
[Mypal](https://releases.wekan.team/mypal/) | No | No | Newest | For 32bit ReactOS/WinXP/Win7/etc [issue](https://github.com/wekan/wekan/issues/3132), Other 32bit browsers probably not
|
||||
Firefox | Android Yes | Android Newest | Newest | Win/Mac/Linux/BSD/RasPi. [Haiku](https://discuss.haiku-os.org/t/progress-on-porting-firefox/13493/143) not tested yet - [HN](https://news.ycombinator.com/item?id=41214762).
|
||||
Morph Browser | No | Yes | Yes | [Ubuntu Touch](https://ubports.com) (based on Ubuntu 16.04) on PinePhone, OnePlus 3, [RasPi3](https://ci.ubports.com/job/rootfs/job/rootfs-rpi/) (not RasPi4 yet). Works best with bluetooth or USB mouse and keyboard. [Repo](https://gitlab.com/ubports/development/core/morph-browser)
|
||||
[OpenStore App](https://open-store.io/app/wekan.wekanteam) | Yes | Yes | Yes | Based on [Wekan PWA](https://boards.wekan.team/b/D2SzJKZDS4Z48yeQH/wekan-open-source-kanban-board-with-mit-license/s7SkzYviC2e963FkT), [Ubuntu Touch](https://ubports.com) app at [OpenStore](https://open-store.io/app/wekan.wekanteam) using Morph browser with Wekan demo & development server https://boards.wekan.team . Tested on [RasPi3](https://ci.ubports.com/job/rootfs/job/rootfs-rpi/). PWA URL is configured here https://github.com/wekan/wekan-openstore/blob/master/wekan.desktop#L3
|
||||
[uWolf](https://open-store.io/app/uwolf.chromiumos-guy) | No | Yes | No | Ubuntu Touch webbrowser based of LibreWolf
|
||||
[LibreWolf](https://librewolf.net) | No | No | Yes | [Win/Mac/Linux](https://librewolf.net/installation/), [Repos](https://codeberg.org/librewolf)
|
||||
[Mypal](https://github.com/reactosapps/apps/releases/download/0.01/mypal-27.9.4.win32.installer.exe) | No | No | Newest | For 32bit ReactOS/WinXP/Win7/etc [issue](https://github.com/wekan/wekan/issues/3132)
|
||||
Firefox | No | Newest | Newest | iOS/Android/Win/Mac/Linux/BSD/RasPi. At iOS uses Safari engine, elsewhere Firefox engine. [Haiku](https://discuss.haiku-os.org/t/progress-on-porting-firefox/13493/143) not tested yet - [HN](https://news.ycombinator.com/item?id=41214762).
|
||||
[Waterfox](https://www.waterfox.net) | No | No | Yes | Win/Mac/Linux, more private than Firefox, no tracking. [Repo](https://github.com/BrowserWorks/Waterfox)
|
||||
[Floorp](https://floorp.app) | No | No | Yes | [Win/Mac/Linux](https://github.com/Floorp-Projects/Floorp/releases), more private than Firefox, [Repo](https://github.com/Floorp-Projects/Floorp)
|
||||
[Mercury](https://thorium.rocks/mercury) | No | No | Yes | [Win/Linux](https://github.com/Alex313031/Mercury/releases), more private than Firefox, [Repo](https://github.com/Alex313031/Mercury)
|
||||
[SeaLion](https://github.com/wicknix/SeaLion) | No | No | Yes | [MacOS 10.7-14.1 x32,x64,ppc,ppc64/Linux x64](https://github.com/wicknix/SeaLion/releases), [Repo](https://github.com/wicknix/SeaLion)
|
||||
[LibreWolf](https://librewolf.net) | No | No | Yes | [Win/Mac/Linux](https://librewolf.net/installation/), [Repos](https://codeberg.org/librewolf)
|
||||
[Zen Browser](https://www.zen-browser.app/) | No | No | Yes | [Win/Mac/Linux](https://www.zen-browser.app/download), [Repos](https://github.com/zen-browser), [Review at YouTube](https://www.youtube.com/watch?v=tKM2N4TQHQY)
|
||||
|
||||
## Chromium based
|
||||
@@ -38,6 +38,8 @@ Brave | Android Yes | Android Newest | Newest | Win/Mac/Linux/RasPi
|
||||
Vivaldi | Android Yes | Android Newest | Newest | Win/Mac/Linux
|
||||
Opera | Android Yes | Android Newest | Newest | Win/Mac/Linux
|
||||
Credge, Chromium Edge | Android Yes | Android | Newest | Win/Mac/Linux/Mobile
|
||||
Morph Browser | No | Yes | Yes | [Ubuntu Touch](https://ubports.com) based on Ubuntu 16.04 and 20.04 at all Ubuntu Touch devices, [RasPi3](https://ci.ubports.com/job/rootfs/job/rootfs-rpi/) (not RasPi4 yet). [Repo](https://gitlab.com/ubports/development/core/morph-browser)
|
||||
[OpenStore App](https://open-store.io/app/wekan.wekanteam) | Yes | Yes | Yes | [Ubuntu Touch](https://ubports.com) app at [OpenStore](https://open-store.io/app/wekan.wekanteam) using Morph browser with Wekan demo & development server https://boards.wekan.team . App source code for Ubuntu 16.04 at https://github.com/wekan/wekan-openstore and Ubuntu 20.04 at https://github.com/wekan/wekan-openstore2
|
||||
[Microsoft Store App](https://www.microsoft.com/fi-fi/p/wekan/9p2mrxvd087r#activetab=pivot:overviewtab) | Yes | Yes | Yes | At Microsoft Store of Windows 10/11 desktop, made with [PWABuilder](https://www.pwabuilder.com/). Based on [Wekan PWA](https://boards.wekan.team/b/D2SzJKZDS4Z48yeQH/wekan-open-source-kanban-board-with-mit-license/s7SkzYviC2e963FkT), changed app from EdgeHTML to Credge based with Wekan demo & development server https://boards.wekan.team
|
||||
[Android Play Store App](https://play.google.com/store/apps/details?id=team.wekan.boards.twa) | Yes | Yes | Yes | Based on [Wekan PWA](https://boards.wekan.team/b/D2SzJKZDS4Z48yeQH/wekan-open-source-kanban-board-with-mit-license/s7SkzYviC2e963FkT), made with [PWABuilder](https://www.pwabuilder.com/), uses Android Chrome browser with Wekan demo & development server https://boards.wekan.team
|
||||
[Thorium](https://thorium.rocks) | No | Yes | Yes | [Win/Win7/Mac/Linux/Android/RasPi](https://thorium.rocks), speed optimized
|
||||
@@ -57,10 +59,26 @@ Internet Explorer | No | No | No | No | No
|
||||
|
||||
## Servo based, not tested yet
|
||||
|
||||
- Apache 2.0 or MIT license
|
||||
- Repo: https://github.com/versotile-org/verso
|
||||
- Verso
|
||||
- Apache 2.0 or MIT license
|
||||
- Repo: https://github.com/versotile-org/verso
|
||||
- Servo
|
||||
- MPL-2.0 license
|
||||
- https://servo.org
|
||||
- Repo: https://github.com/servo/servo
|
||||
- At https://www.youtube.com/watch?v=g9hzWXxUgiU was said, that Gmail works, so maybe WeKan could also work
|
||||
- This month in Servo: color inputs, SVG, embedder JavaScript, and more
|
||||
- https://servo.org/blog/2025/06/18/this-month-in-servo/
|
||||
- https://news.ycombinator.com/item?id=44382451
|
||||
|
||||
## Ladybird based, not tested yet:
|
||||
## TUI webbrowsers, not yet supported
|
||||
|
||||
Browser | [PWA](PWA) | Mobile | Desktop | OS
|
||||
------- | ----| ------ | ------- | -------
|
||||
[Chawan](https://chawan.net) | No | No | Yes | Linux/BSD. [Release 0.2.0](https://chawan.net/news/chawan-0-2-0.html), [HN](https://news.ycombinator.com/item?id=44293260)
|
||||
Elinks | No | No | Yes | Win/Mac/Linux/BSD/DOS TUI.
|
||||
|
||||
## Ladybird based, not yet compatible with WeKan
|
||||
|
||||
- BSD-2-Clause license
|
||||
- Website: https://ladybird.org
|
||||
@@ -76,7 +94,7 @@ Benefits:
|
||||
|
||||
## Desktop app with Meteor
|
||||
|
||||
https://forums.meteor.com/t/desktop-electron-meteor-app-with-todesktop/60904
|
||||
- https://forums.meteor.com/t/desktop-electron-meteor-app-with-todesktop/60904
|
||||
|
||||
## Optional Payments
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[Browser compatibility matrix](Browser-compatibility-matrix)
|
||||
[Browser compatibility matrix](../Browser/Browser-compatibility-matrix)
|
||||
|
||||
## Install your Wekan server as an app
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
3. From Edge menu, install site as app, by clicking top right `⋮` and this menu, that can be used to install and manage/remove apps:
|
||||
|
||||
<img src="https://wekan.github.io/chromium-edge-install-pwa.png" width="60%" alt="Wekan logo" />
|
||||
<img src="chromium-edge-install-pwa.png" width="60%" alt="Install PWA at Chromium Edge" />
|
||||
|
||||
4. In next popup, give name to app, like `YourCompany Wekan`, and click `Add`
|
||||
4. In next popup, give name to app, like `YourCompany WeKan`, and click `Add`
|
||||
|
||||
5. Now new app is in your Windows Start menu.
|
||||
|
||||
@@ -99,7 +99,7 @@ Related, for creating apps to other appstores: https://github.com/wekan/wekan/wi
|
||||
|
||||
6. At Play Console https://play.google.com/console/ there is `App Integrity` button in the sidemenu (highlighted blue in the screenshot) where you find required 2 SHA256 keys for Caddyfile:
|
||||
|
||||

|
||||

|
||||
|
||||
7. Caddy uses tabs for indenting. At `/etc/caddy` you can also `caddy format > ca` to format output and forward to new file, and if it works then `mv ca Caddyfile` and validate it `caddy validate` and reload `caddy reload`. Sometimes update caddy with `caddy upgrade` and after that `caddy stop` and `caddy start`.
|
||||
|
||||
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
@@ -1,15 +1,39 @@
|
||||
# Try FerretDB instead
|
||||
|
||||
https://github.com/wekan/wekan/wiki/PostgreSQL
|
||||
# What was ToroDB
|
||||
|
||||
ToroDB was made with Java. It was about replacing MongoDB with ToroDB/PostgreSQL or ToroDB/MySQL.
|
||||
ToroDB is not developed anymore.
|
||||
|
||||
ToroDB is compatible with MongoDB 3.0. WeKan 7.x is compatible with MongoDB 6.x.
|
||||
# Try FerretDB instead
|
||||
|
||||
https://blog.ferretdb.io/building-project-management-stack-wekan-ferretdb/
|
||||
|
||||
FerretDB https://www.ferretdb.com , https://github.com/FerretDB/FerretDB is made with Go.
|
||||
Why FerretDB is explained at https://docs.ferretdb.io/#why-do-we-need-ferretdb .
|
||||
It is about replacing MongoDB with FerretDB/PostgreSQL,
|
||||
using Microsoft DocumentDB https://github.com/microsoft/documentdb for additional compatibility.
|
||||
|
||||
There is old FerretDB/SQLite, community can maintain it, it's not developed currently by FerretDB:
|
||||
https://github.com/FerretDB/FerretDB/tree/main-v1 .
|
||||
|
||||
C89 SQLite has problems with concurrency, corruption etc.
|
||||
|
||||
It will help when updated SQLite made with Rust
|
||||
will have these issues fixed at https://github.com/tursodatabase/turso .
|
||||
Turso originally had fork of C89 SQLite C89 Open Contribution based fork of SQLite
|
||||
https://github.com/tursodatabase/libsql , where they added fixes, but they run into some limits,
|
||||
so they then moved the Turso Rust SQLite experiment to main tursodatabase GitHub org
|
||||
https://github.com/tursodatabase/turso like they say at https://www.youtube.com/watch?v=010OKqc3ObM .
|
||||
Turso is using simulator like https://tigerbeetle.com https://github.com/tigerbeetle/tigerbeetle
|
||||
to fix concurrency, corruption etc bugs.
|
||||
So when they get rewrite done, Rust based SQLite is drop-in replacement for C89 SQLite.
|
||||
It has same database syntax, etc. But it also works with high concurrent usage,
|
||||
does not corrupt data like C89 SQLite, that is verified with simulator.
|
||||
|
||||
|
||||
# Docker: Wekan to PostgreSQL read-only mirroring
|
||||
|
||||
* [Wekan kanban board, made with Meteor.js framework, running on
|
||||
Node.js](https://wekan.github.io) -- [GitHub](https://github.com/wekan/wekan)
|
||||
Node.js](https://wekan.fi) -- [GitHub](https://github.com/wekan/wekan)
|
||||
* [MongoDB NoSQL database](https://www.mongodb.com)
|
||||
* [ToroDB: MongoDB to PostgreSQL read-only mirroring, programmed with Java](https://www.8kdata.com/products) --
|
||||
[GitHub](https://github.com/torodb/stampede) --
|
||||
@@ -61,4 +85,4 @@ docker-compose up -d
|
||||
|
||||
[GitHub issue 787](https://github.com/wekan/wekan/issues/787)
|
||||
|
||||
[screenshot]: https://wekan.github.io/ToroDB.png
|
||||
[screenshot]: https://wekan.fi/ToroDB.png
|
||||
|
After Width: | Height: | Size: 283 KiB |
@@ -520,6 +520,15 @@ services:
|
||||
# https://bunkat.github.io/later/parsers.html#text
|
||||
#- LDAP_BACKGROUND_SYNC_INTERVAL='every 1 hour'
|
||||
#
|
||||
# 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 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 :
|
||||
# example : LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=true
|
||||
#- LDAP_BACKGROUND_SYNC_KEEP_EXISTANT_USERS_UPDATED=false
|
||||
@@ -0,0 +1,63 @@
|
||||
## Meteor podcast about using MongoDB at unsupported CPUs
|
||||
|
||||
- https://www.youtube.com/watch?v=bnU9bUVeN04
|
||||
- Making MongoDB working with Qemu: https://github.com/wekan/wekan/issues/4321#issuecomment-3006557279
|
||||
|
||||
## MongoDB Operating System Support precompiled binaries
|
||||
|
||||
- arm64: Only Ubuntu. No Raspberry Pi OS, Alpine Linux.
|
||||
- But installing .deb packages to Raspberry Pi 5 running Raspberry OS 64bit can have hardware running cooler, than on Ubuntu.
|
||||
- For anything else, see MongoDB download page.
|
||||
|
||||
## MongoDB CPU support
|
||||
|
||||
New MongoDB supports newer CPUs only, like:
|
||||
- x86_64 that have AVX instructions, from MongoDB 5 and later
|
||||
- ARMv8.2-A microarchitecture, from MongoDB 4.4.19, 5.0, 6.0 and later, like:
|
||||
- Raspberry Pi 5
|
||||
- OrangePi 5
|
||||
- Apple Silicon arm64
|
||||
|
||||
Old MongoDB 4.4.18 supports old CPUs, like:
|
||||
- Intel Core 2 Duo, CPU does not support AVX instructions
|
||||
- ARMv8.0 microarchitecture, like Cortex A53/A55/A72:
|
||||
- Raspberry Pi 3, Cortex-A53, https://en.wikipedia.org/wiki/Raspberry_Pi
|
||||
- Raspberry Pi 4, Cortex-A72
|
||||
- Orange Pi 3, https://en.wikipedia.org/wiki/Orange_Pi
|
||||
|
||||
Info about requiring newer arm64:
|
||||
- https://www.mongodb.com/community/forums/t/mongodb-community-6-0-5-illegal-instruction-core-dumped-ubuntu-18-04-on-cortex-a72-aarch64/223970/3
|
||||
|
||||
Detecting does x86_64 CPU support AVX:
|
||||
- https://github.com/wekan/wekan/issues/4321#issuecomment-2469332492
|
||||
|
||||
Error running MongoDB 8 at RasPi4, when not using Qemu:
|
||||
|
||||
```
|
||||
December 06 11:48:49 rpi4b systemd[1]: Started mongod.service - MongoDB Database Server.
|
||||
December 06 11:48:53 rpi4b mongod[3749]: /usr/bin/mongod: line 4: 3750 Illegal instruction (core dumped) /usr/bin/mongodreal --co>
|
||||
December 06 11:48:53 rpi4b systemd[1]: mongod.service: Main process exited, code=exited, status=132/n/a
|
||||
December 06 11:48:53 rpi4b systemd[1]: mongod.service: Failed with result 'exit-code'.
|
||||
```
|
||||
## a) Prebuilt binary
|
||||
|
||||
MongoDB 7.3.4 for RasPi4 and older:
|
||||
- https://github.com/123swk123/mongodb-armv8-a/releases/tag/v7.3.4-alpha
|
||||
|
||||
## b) Compile MongoDB, takes a lot of time
|
||||
|
||||
CrossCompiling MongoDB from x86_64 to ARMv8.0 Cortex A53/A55/A72 like RasPi4 and older:
|
||||
- https://github.com/123swk123/mongodb-armv8-a
|
||||
|
||||
Compiling MongoDB from x86_64 to x86_64 CPUs that does not have AVX instructions:
|
||||
- https://github.com/GermanAizek/mongodb-without-avx/blob/main/Dockerfile
|
||||
|
||||
## c) Run MongoDB with Qemu, that supports newest CPU features
|
||||
|
||||
qemu-user can run single Linux executeable for many architectures. It does not emulate full OS like qemu-system.
|
||||
|
||||
Running MongoDB with Qemu on x86_64 CPU that does not support AVX, like Intel Core 2 Duo:
|
||||
- https://github.com/stevekerrison/mongo-qemu-avx
|
||||
|
||||
Running MongoDB with Qemu on older arm64, like RasPi4 and older RasPi:
|
||||
- https://github.com/xet7/simpletasks/blob/main/install-mongodb.md
|
||||
@@ -0,0 +1,59 @@
|
||||
## Meteor podcast about using MongoDB at unsupported CPUs
|
||||
|
||||
- https://www.youtube.com/watch?v=bnU9bUVeN04
|
||||
- Making MongoDB working with Qemu: https://github.com/wekan/wekan/issues/4321#issuecomment-3006557279
|
||||
|
||||
## Installing MongoDB
|
||||
|
||||
MongoDB 8 arm64 works at M1 Air arm64 macOS and Linux.
|
||||
|
||||
But because MongoDB 8 core dumps at RasPi4, running it here with Qemu.
|
||||
|
||||
1. Install Ubuntu 24.04 arm64 for Raspberry Pi
|
||||
|
||||
2. Install MongoDB 8 repo for Ubuntu 24.04 arm64
|
||||
|
||||
3. Install deps:
|
||||
|
||||
```
|
||||
sudo apt -y install qemu-user
|
||||
```
|
||||
|
||||
4. Rename MongoDB to different filename:
|
||||
|
||||
```
|
||||
sudo mv /usr/bin/mongod /usr/bin/mongodreal
|
||||
```
|
||||
|
||||
5. Edit start scipt for Qemu MongoDB
|
||||
|
||||
```
|
||||
sudo nano /usr/bin/mongod
|
||||
```
|
||||
|
||||
6. Copy paste start script for Qemu MongoDB
|
||||
|
||||
It uses qemu-user to run MongoDB,
|
||||
and passes all command line arguments to MongoDB.
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
/usr/bin/qemu-arm64 /usr/bin/mongodreal --config /etc/mongod.conf
|
||||
```
|
||||
|
||||
7. Save and exit nano: Ctrl-o Enter Ctrl-x Enter
|
||||
|
||||
8. Make script executeable
|
||||
|
||||
```
|
||||
sudo chmod a+x /usr/bin/mongod
|
||||
```
|
||||
|
||||
9. Start and run MongoDB
|
||||
|
||||
```
|
||||
sudo systemctl enable mongod
|
||||
|
||||
sudo systemctl start mongod
|
||||
```
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## 1) Click right top your username
|
||||
|
||||
<img src="https://wekan.github.io/day/day_of_week_start_1.png" width="40%" alt="Day of Week Start 1" />
|
||||
<img src="https://wekan.fi/day/day_of_week_start_1.png" width="40%" alt="Day of Week Start 1" />
|
||||
|
||||
## 2) Click Change Settings => Set day of the week start => Select first day of the week from dropdown menu
|
||||
|
||||
<img src="https://wekan.github.io/day/day_of_week_start_2.png" width="40%" alt="Day of Week Start 1" />
|
||||
<img src="https://wekan.fi/day/day_of_week_start_2.png" width="40%" alt="Day of Week Start 1" />
|
||||
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -4,7 +4,7 @@ https://www.youtube.com/watch?v=ke-mbnZM3zE
|
||||
|
||||
## Screenshot of Meteor WeKan
|
||||
|
||||
<img src="https://wekan.github.io/wekan-dark-mode.png" width="100%" alt="Meteor WeKan screenshot" />
|
||||
<img src="https://wekan.fi/wekan-dark-mode.png" width="100%" alt="Meteor WeKan screenshot" />
|
||||
|
||||
## Description of Meteor WeKan
|
||||
|
||||
@@ -13,7 +13,7 @@ https://www.youtube.com/watch?v=ke-mbnZM3zE
|
||||
- Used in most countries of the world https://snapcraft.io/wekan
|
||||
- Biggest user have about 30k users, using many pods at Kubernetes
|
||||
- Changelog https://github.com/wekan/wekan/blob/main/CHANGELOG.md
|
||||
- Commercial Support at https://wekan.team/commercial-support/ . Currently looking who could sponsor more of maintenance and development.
|
||||
- Commercial Support at https://wekan.fi/commercial-support/ . Currently looking who could sponsor more of maintenance and development.
|
||||
|
||||
## How much effort to create Meteor WeKan, in COCOMO model
|
||||
|
||||
@@ -36,8 +36,8 @@ https://www.youtube.com/watch?v=ke-mbnZM3zE
|
||||
- CPU: amd64, arm64, s390x, Source Bundle at https://github.com/wekan/wekan/wiki/Raspberry-Pi
|
||||
- Windows On-Premise: https://github.com/wekan/wekan/wiki/Offline
|
||||
- Mac: Docker, or at https://github.com/wekan/wekan/wiki/Mac
|
||||
- Newest at platforms: Source Bundle, Snap Candidate, Docker, Kubernetes https://wekan.github.io
|
||||
- Platforms that will be updated to be up-to-date: Snap Stable, Sandstorm, UCS https://wekan.github.io
|
||||
- Newest at platforms: Source Bundle, Snap Candidate, Docker, Kubernetes https://wekan.fi
|
||||
- Platforms that will be updated to be up-to-date: Snap Stable, Sandstorm, UCS https://wekan.fi
|
||||
|
||||
## Meteor WeKan Features
|
||||
|
||||
@@ -102,7 +102,7 @@ https://www.youtube.com/watch?v=ke-mbnZM3zE
|
||||
- Default board for users https://github.com/wekan/wekan/pull/5098
|
||||
- Brute Force Accounts Lockout https://github.com/wekan/wekan/wiki/Accounts-Lockout
|
||||
- Markdown, Emoji, MathML, sanitizing https://github.com/wekan/wekan/blob/main/packages/markdown/src/template-integration.js
|
||||
- Many security fixes from Responsible Disclosure https://wekan.github.io/hall-of-fame/
|
||||
- Many security fixes from Responsible Disclosure https://wekan.fi/hall-of-fame/
|
||||
|
||||
## Upcoming Features
|
||||
|
||||
@@ -126,7 +126,7 @@ https://www.youtube.com/watch?v=ke-mbnZM3zE
|
||||
- So here is The Deep Dive!
|
||||
- Questions for upcoming "This Week in MeteorJS", some already mentioned to be upcoming:
|
||||
- How to upgrade dependencies to Meteor 3.0 ? Some answer was to mention Meteor version at package dependency:
|
||||
<img src="https://wekan.github.io/upgrade-meteor3-new.png" width="100%" alt="Meteor 3.0 upgrading dependencies" />
|
||||
<img src="https://wekan.fi/upgrade-meteor3-new.png" width="100%" alt="Meteor 3.0 upgrading dependencies" />
|
||||
- But what if adding dependency adds some more error messages? Probably that depends on error message, like here when
|
||||
trying to upgrade to Meteor 3.0 alpha 15: https://github.com/wekan/wekan/issues/5142
|
||||
- https://forums.meteor.com/t/my-journey-towards-meteor-3-0/60001/23
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
- 2024-08 Design discussion here: https://github.com/wekan/wekan/discussions/5507
|
||||
- Original WeKan Design:
|
||||
- Uses WeKan style confirm popups `Popup.afterConfirm(` , translations etc. Please look at existing code to keep same style.
|
||||
- Kanban, the good parts. Like was done when figuring out best design for Swimlanes https://github.com/wekan/wekan/issues/955
|
||||
- Intuitive, easy to figure out, prevent messing up something https://github.com/wekan/wekan/wiki/Monkey-Proof-Software
|
||||
- Polished UI/UX
|
||||
@@ -17,7 +18,7 @@
|
||||
- PWA https://github.com/wekan/wekan/wiki/PWA
|
||||
- On-Premise:
|
||||
- Linux amd64/arm64/s390x
|
||||
- https://wekan.github.io/install/
|
||||
- https://wekan.fi/install/
|
||||
- https://github.com/wekan/wekan/wiki/Raspberry-Pi
|
||||
- Windows https://github.com/wekan/wekan/wiki/Offline
|
||||
- Mac https://github.com/wekan/wekan/wiki/Mac
|
||||
@@ -0,0 +1,48 @@
|
||||
# Design: WeKan vs Trello vs Jira
|
||||
|
||||
### Kanban originally from Toyota paper cards
|
||||
|
||||
- https://en.wikipedia.org/wiki/Kanban
|
||||
- Every kanban software usually implements similar features, original or inspired by some other kanban software
|
||||
|
||||
### WeKan copied design from Trello, then WeKan did redesign, then Trello copied design from WeKan
|
||||
|
||||
- WeKan has all original developed Open Source MIT licensed code, that is different than Trello propietary code.
|
||||
- WeKan UI redesign was done at 2015-01-20 [after DMCA from Trello](../FAQ/FAQ.md#werent-you-called-libreboard-before)
|
||||
- by original WeKan creator [mquandalle](https://github.com/mquandalle)
|
||||
- [Original redesign](../FAQ/FAQ.md#werent-you-called-libreboard-before)
|
||||
- by [xet7](https://github.com/xet7) current maintainer of WeKan
|
||||
- [Improvements to original design](Design-Principles.md)
|
||||
- [Monkey Proof Software](Monkey-Proof-Software.md)
|
||||
- Then Trello started copying from original WeKan design
|
||||
|
||||
### Trello copied design from WeKan
|
||||
|
||||
Existing WeKan features
|
||||
|
||||
- 2025-04 Opened card has comments at right, copied from [original WeKan feature Maximize Card 2021-06-14](https://github.com/wekan/wekan/blob/main/CHANGELOG.md#v535-2021-06-14-wekan-release). Trello does not have WeKan feature Minimize Card.
|
||||
- https://community.atlassian.com/forums/Trello-questions/comments-in-the-ticket-on-the-right/qaq-p/3029030
|
||||
- https://community.atlassian.com/forums/Trello-questions/Trello-card-comments-now-appear-in-a-side-tab-how-to-go-back-to/qaq-p/3003380
|
||||
- 2025-02 Mirror Card, copied from [original WeKan feature Linked Cards from 2018-04-18](https://github.com/wekan/wekan/pull/1592), discussed at [WeKan issue 5683](https://github.com/wekan/wekan/issues/5683)
|
||||
- 2021-02 New board button position at top, copied from [original WeKan feature from 2018-09-28](../../CHANGELOG.md#v1511-2018-09-28-wekan-edge-release)
|
||||
|
||||
Existing WeKan ideas, that are not yet implemented in WeKan
|
||||
|
||||
- 2025-01-28 Sync Jira Lists to Trello, copied from [original WeKan Multiverse from 2022-07-14](https://boards.wekan.team/b/JctQEtkayWXTTJyzt/wekan-multiverse)
|
||||
- 2021-02 Map Card, copied from [original WeKan feature request from 2017-01-06](https://github.com/wekan/wekan/issues/755).
|
||||
|
||||
News
|
||||
|
||||
- https://news.ycombinator.com/item?id=44821127
|
||||
|
||||
### Trello features, that are not yet implemented in WeKan
|
||||
|
||||
- 2025-05-21 Email Inbox
|
||||
- 2025-02 Complete Card Checkbox: https://github.com/wekan/wekan/issues/5818
|
||||
- 2021-05 Workspaces
|
||||
- 2018 Butler Scheduled and Repeating Tasks: https://github.com/wekan/wekan/issues/5825 . [WeKan added IFTTT Rules at 2018-09-16](../../CHANGELOG.md#v147-2018-09-16-wekan-release), but not yet scheduled or repeating IFTTT Rules.
|
||||
- 2016-12 Card Repeater PowerUp: Copy cards daily/weekly/monthly/yearly
|
||||
|
||||
### Jira copied design from ClickUp
|
||||
|
||||
- 2025-06-29 Jira has UI design copied from ClickUp, where is left sidebar menu.
|
||||