Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60ac208ec2 | ||
|
|
dde98c8870 | ||
|
|
990477e9c6 | ||
|
|
b4d46f3016 | ||
|
|
24bed7bdb2 | ||
|
|
ddca4b55a7 | ||
|
|
cf727a08df | ||
|
|
b6374dac3d | ||
|
|
11f8b17a05 | ||
|
|
26e1c1dc4a | ||
|
|
21c09c67e4 | ||
|
|
985c2cdbfd | ||
|
|
a2968d74d7 | ||
|
|
1dd7388783 | ||
|
|
8964a18e76 | ||
|
|
58da992a0c | ||
|
|
3ed1fc3e6b | ||
|
|
f4fe33fb05 | ||
|
|
55815aac71 | ||
|
|
77d72ae20a | ||
|
|
6af581422c | ||
|
|
27f8356b54 | ||
|
|
072778b9aa | ||
|
|
01a1a2cdce | ||
|
|
7e43a6f4fb | ||
|
|
907013228d | ||
|
|
00768b4392 | ||
|
|
a73a4c1e5b | ||
|
|
963a4711db | ||
|
|
bc8b8cbdbe | ||
|
|
4a78c718d3 | ||
|
|
bfef7844ba | ||
|
|
ca0dfe160f | ||
|
|
303cebef63 | ||
|
|
2856cf9baa | ||
|
|
1fc3ed407a | ||
|
|
28b478d14f | ||
|
|
38d26fa7e3 | ||
|
|
5ddf88bca1 | ||
|
|
255eac9f98 | ||
|
|
f260b7ba88 | ||
|
|
40aae378b6 | ||
|
|
0865f3597a | ||
|
|
b9d6fe8146 | ||
|
|
000e27a4a1 | ||
|
|
fbb0ed5ec1 | ||
|
|
58d760a615 | ||
|
|
567be456be | ||
|
|
454fd6e95a | ||
|
|
8c6dd6a4a9 | ||
|
|
b5a8260086 | ||
|
|
7dd5fa4ac4 | ||
|
|
75525c2215 | ||
|
|
31449167be | ||
|
|
441b3e9c0a | ||
|
|
2e5ec0308f | ||
|
|
d1714abc6a | ||
|
|
3f250a17fd | ||
|
|
3fad014e91 | ||
|
|
86115887af | ||
|
|
7778dcc3fc | ||
|
|
65434876eb | ||
|
|
4c146141f9 | ||
|
|
1705b46f39 | ||
|
|
3aca5bc3e4 | ||
|
|
79a866e238 | ||
|
|
efc19ea88c | ||
|
|
79051e5779 | ||
|
|
456fa270cf | ||
|
|
d271678ef4 | ||
|
|
a9390a9897 | ||
|
|
a196a5ed63 | ||
|
|
3fb709ed70 | ||
|
|
50ce0ce442 | ||
|
|
fbb4f0c933 | ||
|
|
a34cbf95e8 | ||
|
|
68e8155805 | ||
|
|
9f723b5863 | ||
|
|
e726b9be7d | ||
|
|
0e6b31b636 | ||
|
|
7607090bdf | ||
|
|
5a3bc74daf | ||
|
|
d8702b2ca1 | ||
|
|
2dfbb48114 | ||
|
|
5a3778fd5a | ||
|
|
43d6900ecb | ||
|
|
2193c86766 | ||
|
|
8d395e6cb1 | ||
|
|
6b2209c8e1 | ||
|
|
8f43b74bbc | ||
|
|
566527dfad | ||
|
|
c858e0b796 | ||
|
|
f40b0d495d | ||
|
|
28317c7cf3 | ||
|
|
3bea047499 | ||
|
|
958d94e1d3 | ||
|
|
64afe811a7 | ||
|
|
e91e4b5329 | ||
|
|
b7ab79efef | ||
|
|
f1a52c99c5 | ||
|
|
d1efd1f493 | ||
|
|
bd8eda2351 | ||
|
|
5e567365f3 | ||
|
|
a167d8ff3f | ||
|
|
9367ef8c41 | ||
|
|
5c890e4cc3 | ||
|
|
c6212c7d62 | ||
|
|
b8d14abe0c | ||
|
|
a064e03fc7 | ||
|
|
9d587e76ab | ||
|
|
e75f423edd | ||
|
|
dace63d4dc | ||
|
|
cfb88baa7f | ||
|
|
72b8672e62 | ||
|
|
99c37bd521 | ||
|
|
9ef45a75af | ||
|
|
fe018225b4 | ||
|
|
927f155078 | ||
|
|
d63f1b740c | ||
|
|
883beba9ed | ||
|
|
dd0d5dbe9f | ||
|
|
0fcfd8e168 | ||
|
|
44fd652b05 | ||
|
|
536fb00d61 | ||
|
|
8c7ed1855e | ||
|
|
54cf71ce1b | ||
|
|
0e768ff363 | ||
|
|
42a8f04058 | ||
|
|
25f8dd5141 | ||
|
|
2a802ec986 | ||
|
|
41837aac74 | ||
|
|
74fc42a08c | ||
|
|
c79b766b58 | ||
|
|
42b05b263d | ||
|
|
d30e52d336 | ||
|
|
59531f785a | ||
|
|
c0979fffbd | ||
|
|
0c3ca14699 | ||
|
|
6b7cbd9d81 | ||
|
|
44dbca5e05 | ||
|
|
855be80572 | ||
|
|
1b83399236 | ||
|
|
2b579372c3 | ||
|
|
a4732bacce | ||
|
|
1cddd607ec | ||
|
|
80d0ec0898 | ||
|
|
06b812b590 | ||
|
|
2288c8ac15 | ||
|
|
2265d726ae | ||
|
|
09553b7672 | ||
|
|
3d6085157e | ||
|
|
efcca9739a | ||
|
|
1875551a93 | ||
|
|
72abf50b36 | ||
|
|
31d7fbe5fb | ||
|
|
71b82e0049 | ||
|
|
f847439e10 | ||
|
|
94bf192f12 | ||
|
|
bb780976e9 | ||
|
|
0d97b1314d | ||
|
|
e4e8da4718 | ||
|
|
5dcf7f55fd | ||
|
|
0f272b1e66 | ||
|
|
b05fa636ea | ||
|
|
74deeeaaa6 | ||
|
|
dcac00696e | ||
|
|
48cd554229 | ||
|
|
4929653367 | ||
|
|
4158334c2d | ||
|
|
5e131f4c76 | ||
|
|
50990b6e6a | ||
|
|
2cddcd60a1 | ||
|
|
c29393dd7e | ||
|
|
6f995a5bdd | ||
|
|
21a9ab72c2 | ||
|
|
3bfe5c284f | ||
|
|
ef712a700e | ||
|
|
fa9ed55d7d | ||
|
|
075a9016d4 | ||
|
|
2d53cd13b6 | ||
|
|
47397e5be3 | ||
|
|
5af78c6990 | ||
|
|
97356603aa | ||
|
|
6a9433593b | ||
|
|
3813554918 | ||
|
|
76ffdd70d0 | ||
|
|
f8d927c61a | ||
|
|
ccbc53cb9b | ||
|
|
b49aaf8e68 | ||
|
|
3f8a3f26d6 | ||
|
|
c1dba52720 | ||
|
|
1ae5bc482b | ||
|
|
96f8b5c9f4 | ||
|
|
85480a6cae | ||
|
|
6e1bf061f8 | ||
|
|
4277d89514 | ||
|
|
3071152978 | ||
|
|
010aed98a8 | ||
|
|
9294eac642 | ||
|
|
393be58a94 | ||
|
|
c8656afc1e | ||
|
|
6d0f0c3606 | ||
|
|
815e2db0ae | ||
|
|
3eb72c6c48 | ||
|
|
e3daa37c5a | ||
|
|
4e72dadc6f | ||
|
|
3c39953b42 | ||
|
|
c926475eb1 | ||
|
|
4bbe63365c | ||
|
|
c696c8eed0 | ||
|
|
2b9f555f31 | ||
|
|
eb745106d8 | ||
|
|
4ba2a23c72 | ||
|
|
60af7766bf | ||
|
|
ae700d64f7 | ||
|
|
95b39f6d47 | ||
|
|
147a3d99cb | ||
|
|
19c54720c6 | ||
|
|
77085daaa8 | ||
|
|
2b1675847c | ||
|
|
3ae777f2c9 | ||
|
|
89c521c20e | ||
|
|
be8b12457c | ||
|
|
95a4b4fd91 | ||
|
|
8dcdfce0ec | ||
|
|
6d31f493bd | ||
|
|
fb48c746ae | ||
|
|
e018dfe541 | ||
|
|
023deb6c95 | ||
|
|
5654c411fe | ||
|
|
ce55d84fd8 | ||
|
|
cb749ff614 | ||
|
|
3c9a4f6ffa | ||
|
|
45642911a9 | ||
|
|
36305f64c5 | ||
|
|
4677081725 | ||
|
|
359692a564 | ||
|
|
555d42d05e | ||
|
|
e7fa9598e3 | ||
|
|
9ed1105e7e | ||
|
|
ab077e7eb9 | ||
|
|
5f2820d7e0 | ||
|
|
b1ea3fef00 | ||
|
|
1360517af8 | ||
|
|
43d324d138 | ||
|
|
b81dcf1dc8 | ||
|
|
f87cb10d09 | ||
|
|
626a7f83fc | ||
|
|
a825b2fe81 | ||
|
|
12448ab473 | ||
|
|
f824eab198 | ||
|
|
4057bb6372 | ||
|
|
15e3c72430 | ||
|
|
8a39a52d5d | ||
|
|
939976ce88 | ||
|
|
8b2cf30754 | ||
|
|
5bcde1e9a7 | ||
|
|
534559c5a9 | ||
|
|
cb99b66023 | ||
|
|
12c9317e15 | ||
|
|
7d5ed14419 | ||
|
|
dfbad25986 | ||
|
|
00e21ae88e | ||
|
|
dbf034cd87 | ||
|
|
031d6a22df | ||
|
|
37fdde1835 | ||
|
|
f613a5875f | ||
|
|
6dc858d790 | ||
|
|
4ca7b0dad7 | ||
|
|
5b31e2f2fb | ||
|
|
49a996624f | ||
|
|
b7aaff5313 | ||
|
|
0e3d8e8607 | ||
|
|
5eca3de00f | ||
|
|
e7a11c5733 | ||
|
|
5744aac7bf | ||
|
|
0d9c37b006 | ||
|
|
7eb04897ab | ||
|
|
7c637e71f0 | ||
|
|
f8d86923b4 | ||
|
|
6b6fde834c | ||
|
|
bc61d1c205 | ||
|
|
66b733a11e | ||
|
|
536021107e | ||
|
|
a96d18454a | ||
|
|
0c5f9aa167 | ||
|
|
30dbab2577 | ||
|
|
8c68d631d4 | ||
|
|
c6cb6f270e | ||
|
|
4534177f47 | ||
|
|
2576127b10 | ||
|
|
db4421c7b8 | ||
|
|
51094a3c46 | ||
|
|
f2378fcff6 | ||
|
|
c18f531915 | ||
|
|
1a117d1941 | ||
|
|
bf449c5864 | ||
|
|
7b428fa8cb | ||
|
|
325899f7f5 | ||
|
|
3394f54fb4 | ||
|
|
a91e274785 | ||
|
|
4f970eee26 | ||
|
|
08f188c45f | ||
|
|
9df99435a0 | ||
|
|
266af19716 | ||
|
|
470645193e | ||
|
|
128a7ee777 | ||
|
|
ada770c9e6 | ||
|
|
a76eb9da03 | ||
|
|
2a362a2e85 | ||
|
|
35837a6b24 | ||
|
|
c99d069b0d | ||
|
|
10b8612ed9 | ||
|
|
0ecaf58515 | ||
|
|
25dc378c46 | ||
|
|
c8f4fe3da5 | ||
|
|
1e42aebd70 | ||
|
|
266d5dda15 | ||
|
|
74d468ea79 | ||
|
|
14aeef8d96 | ||
|
|
10555e1514 | ||
|
|
437b139490 | ||
|
|
9238b6620c | ||
|
|
d90ef2ebd8 | ||
|
|
5d3d5e4b2d | ||
|
|
c3faa99491 | ||
|
|
9ab2d5fab0 | ||
|
|
c359733270 | ||
|
|
747a3b17d5 | ||
|
|
b9670a50eb | ||
|
|
02e977f512 | ||
|
|
dd89afff4d | ||
|
|
2b655f4b67 | ||
|
|
f8b2237274 | ||
|
|
84d94079cc | ||
|
|
edb4db30bb | ||
|
|
9509269622 | ||
|
|
ffba683c84 | ||
|
|
0426e09cd7 | ||
|
|
5fc5500845 | ||
|
|
971391eae9 | ||
|
|
a19e1b3400 | ||
|
|
9be6312ce1 | ||
|
|
c397b5eda8 | ||
|
|
3251c8f419 | ||
|
|
f2f3b76eda | ||
|
|
402fe5528f | ||
|
|
e2f8989939 | ||
|
|
1da0786211 | ||
|
|
744e90d680 | ||
|
|
ca15e060bb | ||
|
|
1431e4fd48 | ||
|
|
e61e9bb508 | ||
|
|
1cb52a60c1 | ||
|
|
9099e20b80 | ||
|
|
0b6e6491f9 | ||
|
|
0fb00bb18f | ||
|
|
aa3f133f56 | ||
|
|
bf023e8218 | ||
|
|
60466612b6 | ||
|
|
376bcbb373 | ||
|
|
556507705a | ||
|
|
825bc4cf25 | ||
|
|
68c958a890 | ||
|
|
d2414670fa | ||
|
|
2f4e201d55 | ||
|
|
278a8e49b9 | ||
|
|
5514c357ca | ||
|
|
8280ed2d3e | ||
|
|
9fa5b59d7c | ||
|
|
f9b6978303 | ||
|
|
90be8ff936 | ||
|
|
221d90f34b | ||
|
|
850aef41a4 | ||
|
|
d18da20cdf | ||
|
|
62ea3cd4bf | ||
|
|
8a014dbfae | ||
|
|
01a91f3a36 | ||
|
|
9f807c59d7 | ||
|
|
ab0faf9b52 | ||
|
|
272aa34083 | ||
|
|
1f277af722 | ||
|
|
bfef9fc14d | ||
|
|
4603948442 | ||
|
|
27ea306c1c | ||
|
|
6d5651e53f | ||
|
|
ada7b3dd2d | ||
|
|
34c2c87307 | ||
|
|
9179e5ea71 | ||
|
|
f90875d8ef | ||
|
|
c4bf99a9b9 | ||
|
|
87ec6a1076 | ||
|
|
e450337b62 | ||
|
|
a45d1fa855 | ||
|
|
0712309266 | ||
|
|
f8b60de988 | ||
|
|
3887c6f412 | ||
|
|
a2beaa6e83 | ||
|
|
2d30b62b70 | ||
|
|
e1550e9172 | ||
|
|
0565f58165 | ||
|
|
bf6bfc8ed6 | ||
|
|
d52e0bcb6e | ||
|
|
263b405fc8 | ||
|
|
a0dbfa1f7e | ||
|
|
5b60efbe82 | ||
|
|
00f2b77468 | ||
|
|
a7e510412d | ||
|
|
dc6bc9ed54 | ||
|
|
82129139a2 | ||
|
|
e5cfcc84fa | ||
|
|
5d5605754c | ||
|
|
9b4179e163 | ||
|
|
ab33866d1a | ||
|
|
41ba67538b | ||
|
|
e0d8ddf003 | ||
|
|
1a7a41698c | ||
|
|
2b999d2836 | ||
|
|
dc99218e4e | ||
|
|
bec440360a | ||
|
|
cc0658a225 | ||
|
|
00b99cda73 | ||
|
|
b378bb55ac | ||
|
|
7d5eac6876 | ||
|
|
4d539f369a | ||
|
|
5dadb4f0a1 | ||
|
|
1629e6aae6 | ||
|
|
0775e2a3e5 | ||
|
|
454d0b270d | ||
|
|
3076547cee | ||
|
|
4bcddcc98a | ||
|
|
099085b416 | ||
|
|
9bd6879455 | ||
|
|
00efbf00d3 | ||
|
|
5c214c143d | ||
|
|
3418b97faa | ||
|
|
a484101abf | ||
|
|
2f79432e4e | ||
|
|
f71728ae16 | ||
|
|
e7e4296b02 | ||
|
|
b85db43c47 | ||
|
|
db6fc57515 | ||
|
|
6b404da9f8 | ||
|
|
4d31985eb9 | ||
|
|
0e9aa2eeed | ||
|
|
7d73f2bbba | ||
|
|
4929979221 | ||
|
|
90cc96302d | ||
|
|
4a074836fd | ||
|
|
0e0bea0139 | ||
|
|
d00596f88a | ||
|
|
9ca8d78514 | ||
|
|
11d8096b8d | ||
|
|
a49a918547 | ||
|
|
4ebd113bf0 | ||
|
|
14df71de5b | ||
|
|
9f459a37b8 | ||
|
|
5487c015db | ||
|
|
47ca6829eb | ||
|
|
368fe24956 | ||
|
|
086cb9c067 | ||
|
|
25a2ad1144 | ||
|
|
926b617f33 | ||
|
|
f94ae76609 | ||
|
|
f46173077b | ||
|
|
40265144af | ||
|
|
c373013134 | ||
|
|
12c5d2324d | ||
|
|
e6dc20f6c7 | ||
|
|
ea658842a2 | ||
|
|
12f0c85546 | ||
|
|
033a5d8186 | ||
|
|
b769a71af3 | ||
|
|
ad35e7b7bd | ||
|
|
a9e56f2b09 | ||
|
|
5f807b80fe | ||
|
|
4d89eb6083 | ||
|
|
bd2739e78d | ||
|
|
265ee9ab83 | ||
|
|
065485168a | ||
|
|
7d609ef0b1 | ||
|
|
dc7b97c178 | ||
|
|
a5b376e6b5 | ||
|
|
993e99330f | ||
|
|
e563212475 | ||
|
|
cc54867976 | ||
|
|
36250f83b9 | ||
|
|
e715106d65 | ||
|
|
f888b5cb23 | ||
|
|
59823a0661 | ||
|
|
6a9bc12664 | ||
|
|
e99130d3ea | ||
|
|
036fb3e794 | ||
|
|
a15ee068d1 | ||
|
|
1da242ae35 | ||
|
|
addf669d44 | ||
|
|
1c2dbe5149 | ||
|
|
77cb5d88de | ||
|
|
1b591dcda9 | ||
|
|
545fe96c30 | ||
|
|
d8d8a6a64d | ||
|
|
5a74d98795 | ||
|
|
0e8a02ee2c | ||
|
|
2c175f2be6 | ||
|
|
e080aea61d | ||
|
|
59a936ae90 | ||
|
|
c7500661b8 | ||
|
|
0ad7eb4753 | ||
|
|
0254282daf | ||
|
|
d0a27aaec2 | ||
|
|
be712541d5 | ||
|
|
9471eb327e | ||
|
|
c41335a967 | ||
|
|
9de430fdc1 | ||
|
|
13a6067081 | ||
|
|
e2f7b94cde | ||
|
|
ac7d16c40f | ||
|
|
3da88ed858 | ||
|
|
c85f710e74 | ||
|
|
7b64c8b235 | ||
|
|
f244125cd3 | ||
|
|
692d853eca | ||
|
|
eb747ef8e9 | ||
|
|
412b60f794 | ||
|
|
0f91eaa0a0 | ||
|
|
386828fe3e | ||
|
|
9b1ff4dd6d | ||
|
|
2dc6e15024 | ||
|
|
e702f17c7b | ||
|
|
16506e7a6a | ||
|
|
08cc308992 | ||
|
|
ae8d4c1bbd | ||
|
|
e2934b9b09 | ||
|
|
55acce9f0c | ||
|
|
627d7d9456 | ||
|
|
b62dd5782a | ||
|
|
0460a7d9d3 | ||
|
|
45d53dede4 | ||
|
|
ce3c87f767 | ||
|
|
ceed865e30 | ||
|
|
9c3043d40a | ||
|
|
a38a78d9a3 | ||
|
|
966541704c | ||
|
|
52a63c5423 | ||
|
|
18bd797ab9 | ||
|
|
d75fd69406 | ||
|
|
337470cbd0 | ||
|
|
a9bd5c7496 | ||
|
|
e1730c9912 | ||
|
|
8f1754be50 | ||
|
|
4ace1db9b0 | ||
|
|
eff636ddd6 | ||
|
|
9b7bf1ba28 | ||
|
|
7190057d0c | ||
|
|
bb5b723520 | ||
|
|
a2e6f01469 | ||
|
|
12ee7efc5f | ||
|
|
7c7640e63e | ||
|
|
e668fdc500 | ||
|
|
f02478d57c | ||
|
|
8fc117eb53 | ||
|
|
af598b13e8 | ||
|
|
f00f164078 | ||
|
|
70ac18a7e6 | ||
|
|
e461c4a018 | ||
|
|
186364f227 | ||
|
|
72f9d45bbe | ||
|
|
6392e06a36 | ||
|
|
c879e63fc2 | ||
|
|
290a6dfb6e | ||
|
|
94c82d121c | ||
|
|
3e92d6f6a3 | ||
|
|
3a2b50720e | ||
|
|
8f47e65684 | ||
|
|
95ebf3bda8 | ||
|
|
ea95357ae4 | ||
|
|
7501e255dd | ||
|
|
ff13571c71 | ||
|
|
6501173ce4 | ||
|
|
1d13040305 | ||
|
|
af1439b274 | ||
|
|
32af18b33d | ||
|
|
a48e537b2d | ||
|
|
424bc0e7c5 | ||
|
|
e98821fafc | ||
|
|
2d61fcdef4 | ||
|
|
045160c7bb | ||
|
|
f98b03bee5 | ||
|
|
703baf4ce9 | ||
|
|
1bf1ed79e8 | ||
|
|
a7888f0c66 | ||
|
|
7122f59c51 | ||
|
|
839266903a | ||
|
|
a8e3dc06fe | ||
|
|
7e0bc91a44 | ||
|
|
62efb67d06 | ||
|
|
00fd47105d | ||
|
|
1bee24fa68 | ||
|
|
9a539fb414 | ||
|
|
c0828f2d00 | ||
|
|
90c70aef96 | ||
|
|
dfc736b064 | ||
|
|
af53afb9f8 | ||
|
|
df61e471a1 | ||
|
|
3e364c4f35 | ||
|
|
3fb63b518f | ||
|
|
4bf6b457ae | ||
|
|
71c575d4b5 | ||
|
|
8b2c9cc74f | ||
|
|
fc7c70bdc0 | ||
|
|
dd18fd2477 | ||
|
|
2512ea1715 | ||
|
|
d63fa4aa89 | ||
|
|
ec51f7cced | ||
|
|
3eb834c920 | ||
|
|
ba24e4a775 | ||
|
|
bec25720da | ||
|
|
0db7ba5107 | ||
|
|
5e65dfc272 | ||
|
|
9b56f149e1 | ||
|
|
a15ed97ab3 | ||
|
|
d34918b08b | ||
|
|
e16cc34f6d | ||
|
|
87fd4880c9 | ||
|
|
f325fe8436 | ||
|
|
70558d00a7 | ||
|
|
d86eb74eb0 | ||
|
|
6adedfd77f | ||
|
|
e1a7c8abb7 | ||
|
|
8c8fba3c6c | ||
|
|
a176a58a72 | ||
|
|
1db3d9a081 | ||
|
|
8020aa4b81 | ||
|
|
bbef2aff8c | ||
|
|
7e1755c89f | ||
|
|
66a4562c91 | ||
|
|
6ad4e78fa8 | ||
|
|
6a92a95414 | ||
|
|
1fcc0d2ec2 | ||
|
|
e7051c8ecd | ||
|
|
1670ba31e8 | ||
|
|
ac1f540763 | ||
|
|
61dd3180a4 | ||
|
|
930333d546 | ||
|
|
2967d13968 | ||
|
|
56be68fcb7 | ||
|
|
dbb9ddd7d3 | ||
|
|
879ab282e1 | ||
|
|
d9a7950fa4 | ||
|
|
18e34b7f79 | ||
|
|
4abb26f8bc | ||
|
|
cd6b4529be | ||
|
|
6234fdff18 | ||
|
|
d4c3f32383 | ||
|
|
a72d51d901 | ||
|
|
a66257ec21 | ||
|
|
395452b54f | ||
|
|
e40e42103e | ||
|
|
7651c00d57 | ||
|
|
764dbb71f0 | ||
|
|
83ce43ac52 | ||
|
|
e528474fc5 | ||
|
|
73ff4c7966 | ||
|
|
01d8058a3f | ||
|
|
b69f08889a | ||
|
|
edf3573760 | ||
|
|
021def818f | ||
|
|
f519d277a5 | ||
|
|
218ddf03bc | ||
|
|
31c7539eb9 | ||
|
|
eb8d9955d5 | ||
|
|
7bcaf71bf0 | ||
|
|
7afc4638d2 | ||
|
|
c9b7542a9b | ||
|
|
c59c7bd63d | ||
|
|
574116b058 | ||
|
|
dbcc919768 | ||
|
|
bf37737f44 | ||
|
|
187b31caa5 | ||
|
|
f75ab964be | ||
|
|
bff43c3f92 | ||
|
|
fb3099eba9 | ||
|
|
5d1d90c2ff | ||
|
|
4d3c0c60d0 | ||
|
|
99d6f7a765 | ||
|
|
418b9effa7 | ||
|
|
30131ffc20 | ||
|
|
ac85e00e0a | ||
|
|
8b2e2e9b1f | ||
|
|
724f9d43b4 | ||
|
|
2ce136ee0a | ||
|
|
7495c1bf59 | ||
|
|
ef685703cf | ||
|
|
0218f3266b | ||
|
|
6a97dfb4b9 | ||
|
|
75fdc53746 | ||
|
|
ed3c53df35 | ||
|
|
2efa42b853 | ||
|
|
cf151b5632 | ||
|
|
2241c35e55 | ||
|
|
6f7292db5e | ||
|
|
ce587d23fa | ||
|
|
9979193df5 | ||
|
|
bee9dc8b3e | ||
|
|
31bf4072d3 | ||
|
|
fbbd3d5174 | ||
|
|
65b7d3d50d | ||
|
|
4589c3df15 | ||
|
|
a160b662ef | ||
|
|
e176410b54 | ||
|
|
2ac5f0b2d7 | ||
|
|
33f47414bb | ||
|
|
fb27ce027c | ||
|
|
ae180c7b85 | ||
|
|
95ed3a0ab5 | ||
|
|
dbe0b4922f | ||
|
|
e69114319f | ||
|
|
8db78f8dd4 | ||
|
|
f2c31f877c | ||
|
|
a87a591600 | ||
|
|
67687110bb | ||
|
|
db180fa43e | ||
|
|
aff6e361f0 | ||
|
|
a37856c937 | ||
|
|
7f32de3bec | ||
|
|
c46ec4a155 | ||
|
|
0c38700458 | ||
|
|
942065bb29 | ||
|
|
8aa816149f | ||
|
|
27ee16ea1e | ||
|
|
d6b0b0318d | ||
|
|
faf03ae1ce | ||
|
|
dd3c8394e7 | ||
|
|
c10f3e97bf | ||
|
|
ea5b93f97c | ||
|
|
bd08c1a4f1 | ||
|
|
ea17cc8592 | ||
|
|
d535469163 | ||
|
|
349925ad6b | ||
|
|
b876098dc4 | ||
|
|
dc04beb61f | ||
|
|
04d8aee86a | ||
|
|
8064d203f3 | ||
|
|
2fbf411918 | ||
|
|
1e9695a428 | ||
|
|
443b40cff3 | ||
|
|
f144f8c90a | ||
|
|
998d2f5b44 | ||
|
|
c15c10de97 | ||
|
|
142fa1c73d | ||
|
|
23a403644c | ||
|
|
89f4cdb7e5 | ||
|
|
c650dd2088 | ||
|
|
85d51ec403 | ||
|
|
8804ca84ec | ||
|
|
aa0dee1fba | ||
|
|
27d55a49fb | ||
|
|
6ef612d04e | ||
|
|
42610d9642 | ||
|
|
d9c290deda | ||
|
|
49214747cd | ||
|
|
84d0817894 | ||
|
|
94525a4d3d | ||
|
|
4ded5d2f51 | ||
|
|
7f8f3f8f16 | ||
|
|
45d7be19b6 | ||
|
|
8446640060 | ||
|
|
184290ce98 | ||
|
|
39fb0e4911 | ||
|
|
1f65add7b0 | ||
|
|
241c3ed8ae | ||
|
|
ee2fafb6bc | ||
|
|
fee82f7f7a | ||
|
|
c2340c6508 | ||
|
|
5ad9ee1de6 | ||
|
|
ea6551e567 | ||
|
|
6c9a2319ba | ||
|
|
e305bf019f | ||
|
|
505c2da072 | ||
|
|
9085e52446 | ||
|
|
9ac5e44a29 | ||
|
|
3d8e9c8b09 | ||
|
|
5cf352defb | ||
|
|
371dd7db9f | ||
|
|
051de2ea5e | ||
|
|
73408c73af | ||
|
|
7079b65cc1 | ||
|
|
67676c50ad | ||
|
|
e46d10ea4c | ||
|
|
331a64f067 | ||
|
|
7f06218877 | ||
|
|
fc95698953 | ||
|
|
2f69501c14 | ||
|
|
8d2c5a9bbb | ||
|
|
cec05dae47 | ||
|
|
8e6bd81abe | ||
|
|
eb9d44f5f0 | ||
|
|
3a83d48bef | ||
|
|
01cd1c0fdc | ||
|
|
c9ddad5615 | ||
|
|
9eb6a1d6af | ||
|
|
9b22e6da7a | ||
|
|
66488b834b | ||
|
|
8752225409 | ||
|
|
258b31f04a | ||
|
|
6997dbc6a8 | ||
|
|
1c3f42cec1 | ||
|
|
fc6c4f85f0 | ||
|
|
8ad9f2fbea | ||
|
|
ee5ec45c73 | ||
|
|
710c65a8ae | ||
|
|
f094dfb84f | ||
|
|
b84cc037c1 | ||
|
|
7aaa853d1b | ||
|
|
e32225e18f | ||
|
|
d7f903f3cd | ||
|
|
f0ebfb7f58 | ||
|
|
f660dcaa86 | ||
|
|
daa5de7011 | ||
|
|
2827c0e3ed | ||
|
|
00cd8f140c | ||
|
|
8be1d371cd | ||
|
|
2252a855dd | ||
|
|
c1eb175ab8 | ||
|
|
e7174107e9 | ||
|
|
63c838eee9 | ||
|
|
bd336dddec | ||
|
|
673e5b1987 | ||
|
|
d45bbc2269 | ||
|
|
8884d5b7e0 | ||
|
|
a3b99dd02d | ||
|
|
e7138772f0 | ||
|
|
b8a976d4ad | ||
|
|
ba0fb2d985 | ||
|
|
ebc7741fcb | ||
|
|
d1f8c92a99 | ||
|
|
4036abe3c1 | ||
|
|
23a2e90f5f | ||
|
|
5792b21ed1 | ||
|
|
4a4bfef888 | ||
|
|
a2cefc595e | ||
|
|
892828c02e | ||
|
|
9cf8af0416 | ||
|
|
2767c444b2 | ||
|
|
b5ee0649db | ||
|
|
a7b7bfafb5 | ||
|
|
36d8949831 | ||
|
|
5c5c867aca | ||
|
|
383323c4ea | ||
|
|
96465ac664 | ||
|
|
98dedc697c | ||
|
|
f82fbdb8a2 | ||
|
|
5088c12253 | ||
|
|
611af2d523 | ||
|
|
97ef13c222 | ||
|
|
d7adfc779e | ||
|
|
507cfbb377 | ||
|
|
1af75aa579 | ||
|
|
861b98ea37 | ||
|
|
b09be8614b | ||
|
|
8bc047cec3 | ||
|
|
cb7ec54be2 | ||
|
|
6d3b979d67 | ||
|
|
fe01d35fe6 | ||
|
|
f38e3db93c | ||
|
|
b988ef430c | ||
|
|
4a97e70b8d | ||
|
|
f082128d99 | ||
|
|
7577b246da | ||
|
|
9db14a0c3b | ||
|
|
f3d5b887c8 | ||
|
|
7e21589ee1 | ||
|
|
e1e4ea1205 | ||
|
|
54205b7c5d | ||
|
|
e0b5d1c15e | ||
|
|
79b40cd8a9 | ||
|
|
f6830ff4f3 | ||
|
|
765ac045fe | ||
|
|
b9d98f58cf | ||
|
|
e0978000f8 | ||
|
|
bc186958ab | ||
|
|
a190600934 | ||
|
|
65fc2a4fdd | ||
|
|
d41810aca1 | ||
|
|
b75a7a6424 | ||
|
|
bfb3837ee4 | ||
|
|
72fa10761a | ||
|
|
9c1523c916 | ||
|
|
a786262658 | ||
|
|
6245982025 | ||
|
|
c643cdaad3 | ||
|
|
f0cadf858d | ||
|
|
2566286e86 | ||
|
|
8bf3841e6c | ||
|
|
7a959ef1a2 | ||
|
|
5525247f52 | ||
|
|
7444c11c82 | ||
|
|
6d3ecdea55 | ||
|
|
7db1445d09 | ||
|
|
08ee969445 | ||
|
|
4bfa727e9e | ||
|
|
ed53065a09 | ||
|
|
49fdae6e06 | ||
|
|
b78dfc7149 | ||
|
|
0227b38845 | ||
|
|
7d52016d79 | ||
|
|
d9bc5f80a0 | ||
|
|
f1a0e4754f | ||
|
|
496c791629 | ||
|
|
2b7c5cfcb1 | ||
|
|
f647f4580e | ||
|
|
c62c705755 | ||
|
|
57129eff04 | ||
|
|
3c7ca87625 | ||
|
|
126c9ab853 | ||
|
|
c9071a74bc | ||
|
|
292e43466e | ||
|
|
75af42cd8c | ||
|
|
60c831521e | ||
|
|
9e0de569dc | ||
|
|
6dbb8c8c68 | ||
|
|
ac89276ee9 | ||
|
|
7902221a96 | ||
|
|
47540df916 | ||
|
|
dbef7e7cd3 | ||
|
|
4a19790b11 | ||
|
|
533eb41249 | ||
|
|
f09ea42981 | ||
|
|
6290b3b697 | ||
|
|
92b6b0064a | ||
|
|
8662fd59fb | ||
|
|
16bb65f7c7 | ||
|
|
44c3449ab2 | ||
|
|
ed13a3b95f | ||
|
|
32646fb9be | ||
|
|
38eccdb95b | ||
|
|
6944a20ba4 | ||
|
|
2e8323ca6a | ||
|
|
fae4d0be08 | ||
|
|
b58e1c0102 | ||
|
|
f18658c0d2 | ||
|
|
8054f2b002 | ||
|
|
5178aade75 | ||
|
|
6628ae8b5a | ||
|
|
7ca0fa626c | ||
|
|
0ceff124cc | ||
|
|
37faa41d97 | ||
|
|
fc0630715c | ||
|
|
9e75a70212 | ||
|
|
3d61be028a | ||
|
|
f9c179e9df | ||
|
|
2b77a67c03 | ||
|
|
c6fc172055 | ||
|
|
7aafb5e26e | ||
|
|
02b6df320f | ||
|
|
6d719b8a98 | ||
|
|
b1b12b05b5 | ||
|
|
39260bccb3 | ||
|
|
5754a886ab | ||
|
|
624fdea842 | ||
|
|
1975673152 | ||
|
|
1d523c1ede | ||
|
|
407632eed0 | ||
|
|
7518d93feb | ||
|
|
0fb6b6e519 | ||
|
|
fa9641ba7b | ||
|
|
6d855967fe | ||
|
|
17d90684bb | ||
|
|
d6094c3476 | ||
|
|
4eca4eeddc | ||
|
|
b392e515ca | ||
|
|
f25ed7fcfc | ||
|
|
b7928a9538 | ||
|
|
d523a897f6 | ||
|
|
a67e3754ab | ||
|
|
80319b0038 | ||
|
|
becb81f04a | ||
|
|
f50f876cab | ||
|
|
bd7bbd18c5 | ||
|
|
d8218091c6 | ||
|
|
ba3fa2aaea | ||
|
|
0ab86c22af | ||
|
|
0ed029e706 | ||
|
|
c5a7cf56bc | ||
|
|
9f25938b51 | ||
|
|
e0d92c7f64 | ||
|
|
48ecbf5017 | ||
|
|
8fe2e073c5 | ||
|
|
a8c8970192 | ||
|
|
e8e5616832 | ||
|
|
abe5ca752e | ||
|
|
db84c73337 | ||
|
|
a4ac34d8aa | ||
|
|
e47f26a390 | ||
|
|
1eca7c9996 | ||
|
|
25024fbe6b | ||
|
|
1f6d96c873 | ||
|
|
8ec4e1a7d0 | ||
|
|
f4a3363f6f | ||
|
|
4733afe4eb | ||
|
|
72ddd66495 | ||
|
|
a09e961110 | ||
|
|
49c4dd8b14 | ||
|
|
65f0cab730 | ||
|
|
b72fae24ca | ||
|
|
228c78c248 | ||
|
|
73fdc7ff79 | ||
|
|
cbf91c1869 | ||
|
|
70777cfce8 | ||
|
|
f74fab64b6 | ||
|
|
12839fd929 | ||
|
|
b903750f45 | ||
|
|
f2d2982a76 | ||
|
|
efb24c2d25 | ||
|
|
5fd7407207 | ||
|
|
0a77266f6e | ||
|
|
936d9fe306 | ||
|
|
810c3c81db | ||
|
|
67f614ffb0 | ||
|
|
7f7ef0a914 | ||
|
|
4acf3738ca | ||
|
|
f370f749b9 | ||
|
|
f518971520 | ||
|
|
c5eca7f3ec | ||
|
|
9868b3b6af | ||
|
|
f9c9f2a453 | ||
|
|
206828b440 | ||
|
|
343dcb4995 | ||
|
|
546134f6cd | ||
|
|
ac7ef4d4cd | ||
|
|
eb1d3b6101 | ||
|
|
6151382c07 | ||
|
|
1516be030e | ||
|
|
5eb7ce09b2 | ||
|
|
d791914ddd | ||
|
|
fb09efd1a4 | ||
|
|
2d749e13e0 | ||
|
|
712ae37400 | ||
|
|
92ba5f8874 | ||
|
|
8cf392e1ea | ||
|
|
ea01c5c1b9 | ||
|
|
0991e54c22 | ||
|
|
08a01c6d2c | ||
|
|
95cf54836f | ||
|
|
81f5b6a428 | ||
|
|
f1b49e05eb | ||
|
|
fdd23e2f54 | ||
|
|
f906153b47 | ||
|
|
34fa83a461 | ||
|
|
ddc229dabe | ||
|
|
c4d42d86a2 | ||
|
|
c2bd4d1cee | ||
|
|
4fb4deacf9 | ||
|
|
ce5f2a19a5 | ||
|
|
05a1588bac | ||
|
|
e21363d37e | ||
|
|
d8dad479fd | ||
|
|
d04e9bbabd | ||
|
|
790a82c4b1 | ||
|
|
26826b6120 | ||
|
|
f48f67340e | ||
|
|
cf6713a31c | ||
|
|
30ef5c1bf6 | ||
|
|
1859f58ad9 | ||
|
|
3bc2862ae2 | ||
|
|
3ce1e8220b | ||
|
|
2d9c8740b4 | ||
|
|
502bfcb97d | ||
|
|
2bd23d9525 | ||
|
|
a59a242c1e | ||
|
|
9530f38791 | ||
|
|
c136033c1f | ||
|
|
17a5505eda | ||
|
|
8abea470fb | ||
|
|
1d8ff8398c | ||
|
|
0af41dc19c | ||
|
|
21de4a2ca0 | ||
|
|
ed289451f6 | ||
|
|
045502c9e9 | ||
|
|
405411f97f | ||
|
|
00c3092f44 | ||
|
|
e3d52169d7 | ||
|
|
be5b6245e3 | ||
|
|
705e6d7e3a | ||
|
|
6c83cb5b44 | ||
|
|
b51152fca4 | ||
|
|
344094ec18 | ||
|
|
89a7bb8bc8 | ||
|
|
e762465e09 | ||
|
|
7d42b7eaf0 | ||
|
|
4106aab659 | ||
|
|
df2a2aae1d | ||
|
|
fbcafdbd02 | ||
|
|
7cc35970a8 | ||
|
|
123654008f | ||
|
|
711182ef8a | ||
|
|
46a5eec7d2 | ||
|
|
a42c132306 | ||
|
|
be8a3191d1 | ||
|
|
157f16a1d4 | ||
|
|
803c949c8d | ||
|
|
e64bc38932 | ||
|
|
f1d96fcef8 | ||
|
|
5934b7a4a2 | ||
|
|
245d6dc96d | ||
|
|
1941ee6af5 | ||
|
|
e3292dd562 | ||
|
|
ec33d0b34f | ||
|
|
5add2aaea6 | ||
|
|
50a849fccd | ||
|
|
ef53ade32e | ||
|
|
3ee2156399 | ||
|
|
90cd26e78e | ||
|
|
4c9d10f7a7 | ||
|
|
a686a18809 | ||
|
|
c7ab0403a6 | ||
|
|
f90fb28483 | ||
|
|
fecb9cdb66 | ||
|
|
66df3cc2ee | ||
|
|
d9adce7b67 | ||
|
|
6f39a3cf1c | ||
|
|
f840d26faf | ||
|
|
dfd5acea97 | ||
|
|
5411113544 | ||
|
|
d1eb6f2355 | ||
|
|
aed1e71094 | ||
|
|
46f6d1e989 | ||
|
|
e9c1b2b2c4 | ||
|
|
94f8fb2393 | ||
|
|
2055d916e9 | ||
|
|
70dbd1518d | ||
|
|
3db3a5bad9 | ||
|
|
b8a41406f5 | ||
|
|
c8b8fb83dc | ||
|
|
cb9b8d4f2b | ||
|
|
69ce16192d | ||
|
|
46efd27079 | ||
|
|
141e866719 | ||
|
|
4e7f1a9937 | ||
|
|
3e7fee8fae | ||
|
|
b09e5b2680 | ||
|
|
fb00869e49 | ||
|
|
4521d5c10d | ||
|
|
5eb4cff991 | ||
|
|
20415b881c | ||
|
|
90b0a93547 | ||
|
|
f67a174c4a | ||
|
|
8224410e0c | ||
|
|
7f78106211 | ||
|
|
0025212b3e | ||
|
|
d79a35ea82 | ||
|
|
ce829f586b | ||
|
|
a3d41c560b | ||
|
|
5af4386a0f | ||
|
|
c08c9543af | ||
|
|
b25eeb334c | ||
|
|
5c2a44e6fe | ||
|
|
4c0d382fd8 | ||
|
|
8550213146 | ||
|
|
1a09b75974 | ||
|
|
ea73e4ec7d | ||
|
|
7e45e0676a | ||
|
|
6f09987b07 | ||
|
|
a09b7a4002 | ||
|
|
8a51e271a2 | ||
|
|
53c827e134 | ||
|
|
bcc17127a9 | ||
|
|
18ff4bee2d | ||
|
|
71068cf13e | ||
|
|
2666b30ba9 | ||
|
|
7a9ed24127 | ||
|
|
156c0b5d4d | ||
|
|
e5a31e7f99 | ||
|
|
ccc0b3bcf9 | ||
|
|
44f6cc978d | ||
|
|
c07646d13d | ||
|
|
e20ca04fab | ||
|
|
f14e710ac0 | ||
|
|
5546f6aa17 | ||
|
|
9cfbd7b37d | ||
|
|
62bfa75cf7 | ||
|
|
fe2a7e207c | ||
|
|
1c2d4e5b4c | ||
|
|
2b33d7890c | ||
|
|
e8c9222283 | ||
|
|
a62a177fb1 | ||
|
|
e954df4d8e | ||
|
|
d0a0c74fd9 | ||
|
|
552e99d460 | ||
|
|
ce30c7e1b7 | ||
|
|
876d78eec4 | ||
|
|
0313e21ca1 | ||
|
|
e6f94c9d16 | ||
|
|
cdc4be3a13 | ||
|
|
4131dd89d4 | ||
|
|
4936e580fd | ||
|
|
b9250e4be4 | ||
|
|
a59dfa8fc0 | ||
|
|
2fd2ea72fe | ||
|
|
a6d3810e19 | ||
|
|
5e29c68154 | ||
|
|
6b26b5d62b | ||
|
|
81e617a149 | ||
|
|
013620c862 | ||
|
|
086aa51c2e | ||
|
|
95719cbd24 | ||
|
|
a23c8c263c | ||
|
|
dfd1155790 | ||
|
|
3a92cabc3f | ||
|
|
47446315ad | ||
|
|
c586a9bb39 | ||
|
|
4df3416b46 | ||
|
|
a42a3436cd | ||
|
|
367823ea5e | ||
|
|
ccb5acbe70 | ||
|
|
b8e0dfa07d | ||
|
|
a167a1b4f4 | ||
|
|
c95ccaa5c9 | ||
|
|
5b5b8fe427 | ||
|
|
31af30175b | ||
|
|
a22aacf29b | ||
|
|
6a06522777 | ||
|
|
c47b04493a | ||
|
|
6d701cda2e | ||
|
|
8bb27e2762 | ||
|
|
437b62eb97 | ||
|
|
88fbdfbb6b | ||
|
|
92eb3afa6c | ||
|
|
ababeebbf0 | ||
|
|
fdb3f83d1f | ||
|
|
a0e6fc4611 | ||
|
|
2b62b3aa90 | ||
|
|
910c0705f7 | ||
|
|
35469364b4 | ||
|
|
2af5e9c209 | ||
|
|
21a3749086 | ||
|
|
bd2b8625fb | ||
|
|
7ced602be4 | ||
|
|
b59e4d8fc7 | ||
|
|
9809510782 | ||
|
|
ea7136816d | ||
|
|
73872202ec | ||
|
|
a72f1ae8de | ||
|
|
fdf40f4584 | ||
|
|
7a6cfcb498 | ||
|
|
4994f23134 | ||
|
|
8c3ce4bb73 | ||
|
|
48b2e3dd88 | ||
|
|
bcb5cfb235 | ||
|
|
27213245ef | ||
|
|
c07a1412f7 | ||
|
|
dae58d11c2 | ||
|
|
fb66b84b58 | ||
|
|
125c84b6b5 | ||
|
|
5f58ede7e3 | ||
|
|
0f69282eec | ||
|
|
24b0613bac | ||
|
|
4a87d5f0f3 | ||
|
|
09b127b648 | ||
|
|
4ab290928c | ||
|
|
b9178cfcb6 | ||
|
|
cbc6463019 | ||
|
|
a30fee95bf | ||
|
|
b1b2d87045 | ||
|
|
02896e669a | ||
|
|
df5b76aa87 | ||
|
|
ea60d5a205 | ||
|
|
02f056851d | ||
|
|
d4cbcf1a31 | ||
|
|
78190d0d7e | ||
|
|
05ae1ad56d | ||
|
|
5a5a01cf17 | ||
|
|
d9329a9e15 | ||
|
|
3ea285498f | ||
|
|
3921209c9f | ||
|
|
05e0aa0304 | ||
|
|
5c571ca863 | ||
|
|
721e889bee | ||
|
|
bcf3573131 | ||
|
|
153ce880dd | ||
|
|
eac102dbbf | ||
|
|
d9efdb0b88 | ||
|
|
3a583a92f9 | ||
|
|
187e147352 | ||
|
|
2c9439fd7b | ||
|
|
2cefc55865 | ||
|
|
74d1e032f2 | ||
|
|
eb2ec18add | ||
|
|
3c6915e217 | ||
|
|
629fa91fa0 | ||
|
|
516044f3c7 | ||
|
|
a47c0dd512 | ||
|
|
1b06997001 | ||
|
|
458ec4c9a5 | ||
|
|
f76b466fc4 | ||
|
|
d7479c742f | ||
|
|
b12312f998 | ||
|
|
f8e5565b49 | ||
|
|
4a7718820c | ||
|
|
c2d47cfcdb | ||
|
|
64fc2e5d8f | ||
|
|
7c5763439c | ||
|
|
d39e8bc03a | ||
|
|
6cd59f8ce1 | ||
|
|
37a3fbf69c | ||
|
|
684fd8c2c5 | ||
|
|
d481328b20 | ||
|
|
e694c587e5 | ||
|
|
3125cefd41 | ||
|
|
c27a622289 | ||
|
|
51875dc155 | ||
|
|
f9bdfa54e7 | ||
|
|
8fbee23797 | ||
|
|
153e4cc3fa | ||
|
|
5a5d619b89 | ||
|
|
97c56baebb | ||
|
|
9c99c5c3ae | ||
|
|
28d515436e | ||
|
|
f70ec7f53c | ||
|
|
74825c099f | ||
|
|
966670fe70 | ||
|
|
c406607fd2 | ||
|
|
e812a3a087 | ||
|
|
9e6744d1e3 | ||
|
|
835e3ef305 | ||
|
|
ac658af462 | ||
|
|
6c3fcdcc4c | ||
|
|
22cbd5097b | ||
|
|
d06ac09485 | ||
|
|
94b67db78a | ||
|
|
5536525564 | ||
|
|
e6c7463c03 | ||
|
|
11bf4c7c07 | ||
|
|
bc9c7e5aa4 | ||
|
|
9a0f54f4fe | ||
|
|
3b6f3c58e1 | ||
|
|
ff01c2a69f | ||
|
|
1322c1fbbd | ||
|
|
36e2c76456 | ||
|
|
c42a8df65c | ||
|
|
01b38bb2e0 | ||
|
|
9f9a69286c | ||
|
|
e3a0dea85f | ||
|
|
5b5094ced6 | ||
|
|
f5c2557338 | ||
|
|
802f1599a1 | ||
|
|
9781afa17e | ||
|
|
3319602f3f | ||
|
|
8bd2e4f0dd | ||
|
|
8eaa490664 | ||
|
|
db54eb87cd | ||
|
|
d1950efdd4 | ||
|
|
cf51ddb32e | ||
|
|
269551ead5 | ||
|
|
ee06e4f6de | ||
|
|
87e9949f33 | ||
|
|
0b02e88ee3 | ||
|
|
dd58698cef | ||
|
|
f9807bfad8 | ||
|
|
4f6bd86478 | ||
|
|
be6ff3782b | ||
|
|
7ae2360a55 | ||
|
|
1852e66abd | ||
|
|
367b2370a5 | ||
|
|
640df0f4a5 | ||
|
|
37984a6f9a | ||
|
|
c062621dd5 | ||
|
|
437a2ea0e2 | ||
|
|
fc2fb9a081 | ||
|
|
41d9ae92e6 | ||
|
|
4c659da533 | ||
|
|
21a9226c4a | ||
|
|
ee2c167be4 | ||
|
|
09b5359c45 | ||
|
|
e55e8ef000 | ||
|
|
bffd56f5fc | ||
|
|
ac0d7bda1c | ||
|
|
2912e541a0 | ||
|
|
442e6bf983 | ||
|
|
70ba1eca78 | ||
|
|
e925877ae4 | ||
|
|
0e7cc1ef87 | ||
|
|
909b0ef1b7 | ||
|
|
a573083291 | ||
|
|
6a42f738c9 | ||
|
|
9bee6ae666 | ||
|
|
533af4b39e | ||
|
|
99a200d0b2 | ||
|
|
889ec1339a | ||
|
|
0bdc3d04b4 | ||
|
|
bd9fbedbf9 | ||
|
|
6c0a958481 | ||
|
|
45a39ec213 | ||
|
|
800304270e | ||
|
|
9defed2680 | ||
|
|
7be9d7ff49 | ||
|
|
287abe7640 | ||
|
|
262df6c4a0 | ||
|
|
10e3d963ef | ||
|
|
d23920c886 | ||
|
|
be2647556d | ||
|
|
ea57864bcc | ||
|
|
0c121a5894 | ||
|
|
c19723ae27 | ||
|
|
00b43df267 | ||
|
|
edb6355960 | ||
|
|
8626b466b8 | ||
|
|
a80ab6e47a | ||
|
|
2b2978b8e7 | ||
|
|
3bdea42f6d | ||
|
|
b56ea161cd | ||
|
|
cde74a9c0b | ||
|
|
79b00f88b0 | ||
|
|
0da84f8f3e | ||
|
|
4f164a46a6 | ||
|
|
3d9b7eb7ab | ||
|
|
d3eb0ced83 | ||
|
|
08ac1f6b69 | ||
|
|
cc63be8ff0 | ||
|
|
b1d8b0c7d4 | ||
|
|
3f6fde033b | ||
|
|
0a9e10b21e | ||
|
|
25e17fedb9 | ||
|
|
8ec54ffa5b | ||
|
|
b516275c24 | ||
|
|
aea5d62556 | ||
|
|
de2fc69315 | ||
|
|
8629537c3f | ||
|
|
57401e48c1 | ||
|
|
76f4b8316b | ||
|
|
ef0e4e36f4 | ||
|
|
55296b676b | ||
|
|
5b9a2a8bac | ||
|
|
8031b184f3 | ||
|
|
1efd7bb33a | ||
|
|
53d663f77b | ||
|
|
9969523b70 | ||
|
|
2cd0a414d5 | ||
|
|
256a673a7f | ||
|
|
6d8a062e50 | ||
|
|
35a7159be4 | ||
|
|
764d9fa806 | ||
|
|
292ff3c961 | ||
|
|
071929d3a6 | ||
|
|
c7cc9273a6 | ||
|
|
55a11a24f4 | ||
|
|
d1f443bcd8 | ||
|
|
52fafe9976 | ||
|
|
9aa7b792be | ||
|
|
07e9fe3403 | ||
|
|
858967f420 | ||
|
|
e07df35b61 | ||
|
|
2a3aa9331f | ||
|
|
4863689248 | ||
|
|
8a53aa9fa4 | ||
|
|
57a990d91e | ||
|
|
76c0393c53 | ||
|
|
62d472fa54 | ||
|
|
6d9d69e01d | ||
|
|
38666cbda2 | ||
|
|
b3b81546f6 | ||
|
|
9c2151f802 | ||
|
|
1f2c4b5a9e | ||
|
|
c9ef28b2ad | ||
|
|
03a5f46131 | ||
|
|
f1e4297e00 | ||
|
|
9bb1425a81 | ||
|
|
b6277233a1 | ||
|
|
7bed8a7abb | ||
|
|
787df04419 | ||
|
|
8e142dfdcf | ||
|
|
2a216d41f0 | ||
|
|
241eb9df0f | ||
|
|
0bdd7c8973 | ||
|
|
a59932af00 | ||
|
|
c2a073dec0 | ||
|
|
7808fdd22f | ||
|
|
bf2f3ccec1 | ||
|
|
9c7c481f48 | ||
|
|
df26bc9013 | ||
|
|
b36a7621e0 | ||
|
|
f2c242f49e | ||
|
|
5175f13881 | ||
|
|
75a1854cc3 | ||
|
|
48c3263e28 | ||
|
|
f5e26fb2e6 | ||
|
|
1fadf204c2 | ||
|
|
f03b14a46b | ||
|
|
ab8e56e16a | ||
|
|
2f33a1ecff | ||
|
|
abadeb5e14 | ||
|
|
19c68895e9 | ||
|
|
bed6d6c591 | ||
|
|
b2652edf56 | ||
|
|
94bb3bee77 | ||
|
|
e909ece2da | ||
|
|
7bc250ce84 | ||
|
|
7706839fbe | ||
|
|
68ad58431d | ||
|
|
2059752fc6 | ||
|
|
302afae0bb | ||
|
|
3d1d94d628 | ||
|
|
d51fc2f12c | ||
|
|
2dee14b0d5 | ||
|
|
e75849da98 | ||
|
|
508c7b7a90 | ||
|
|
de67e051d7 | ||
|
|
9ce65c601a | ||
|
|
10d7eeb762 | ||
|
|
104a6dd0b3 | ||
|
|
2977120129 | ||
|
|
d8e8512d66 | ||
|
|
7bfbcf7e03 | ||
|
|
91cad7b49e | ||
|
|
26f1defc56 | ||
|
|
9a03654062 | ||
|
|
2576ef75bd | ||
|
|
752b45af42 | ||
|
|
23c70ac252 | ||
|
|
ad4de9e85d | ||
|
|
855d60f28e | ||
|
|
781a94c05f | ||
|
|
b3cc01b041 | ||
|
|
e23ced47ae | ||
|
|
f406b51a5f | ||
|
|
c81cb786ed | ||
|
|
846f1244c7 | ||
|
|
3ea723329a | ||
|
|
698c9ed1ea | ||
|
|
52e45211a2 | ||
|
|
63044ac13a | ||
|
|
68d9de8946 | ||
|
|
92a7717e50 | ||
|
|
d5c0a5d377 | ||
|
|
c0b7fb0b84 | ||
|
|
9b4e556837 | ||
|
|
1aec0b5f0d | ||
|
|
c5d4e06ea3 | ||
|
|
97bf907448 | ||
|
|
7ef2a2a9f4 | ||
|
|
547d82fe57 | ||
|
|
977821d293 | ||
|
|
f4e5306181 | ||
|
|
f01b440fb7 | ||
|
|
2fd741bf54 | ||
|
|
e8522c323f | ||
|
|
def2ec46e0 | ||
|
|
4e17d5a10f | ||
|
|
dcba6909e2 | ||
|
|
fc74324d1a | ||
|
|
8bb33c53f0 | ||
|
|
236b6c3552 | ||
|
|
28e9a6ac33 | ||
|
|
f91cc25b11 | ||
|
|
6fd45ce74b | ||
|
|
b57eae14d4 | ||
|
|
12db3714f9 | ||
|
|
7a1f42fa4e | ||
|
|
74064324cf | ||
|
|
f3baa32d6c | ||
|
|
33eed50290 | ||
|
|
11d9d1c889 | ||
|
|
5a7860ac8e | ||
|
|
b13f691389 | ||
|
|
cca51628ef | ||
|
|
d70e876388 | ||
|
|
36c2cb9573 | ||
|
|
88a47780a8 | ||
|
|
506cb696d3 | ||
|
|
d30ce3c5cf | ||
|
|
0fa8fc8b50 | ||
|
|
6d73618a48 | ||
|
|
db493f1571 | ||
|
|
2b51afaedf | ||
|
|
18b6381d79 | ||
|
|
c65d8ed6a9 | ||
|
|
b3ba156d20 | ||
|
|
e1de787f19 | ||
|
|
e1f08b157b | ||
|
|
508915462d | ||
|
|
7c2ef6fbd5 | ||
|
|
ae73029dda | ||
|
|
542972fc5c | ||
|
|
d7cb143b0a | ||
|
|
d594555227 | ||
|
|
fe25ed5202 | ||
|
|
f6c36d6edd | ||
|
|
fe40f35d6d | ||
|
|
a4e02bb8cd | ||
|
|
789d1d1d1c | ||
|
|
70265deb47 | ||
|
|
c0d1ed714e | ||
|
|
0555b7e34c | ||
|
|
c1c2eb22ba | ||
|
|
697d7613f2 | ||
|
|
33836af1f9 | ||
|
|
4f0c2dafca | ||
|
|
6d588130dd | ||
|
|
0ce2f9ea43 | ||
|
|
84801010d5 | ||
|
|
cb418f5e23 | ||
|
|
f7d6ac9401 | ||
|
|
d939ab0d76 | ||
|
|
d538a01d19 | ||
|
|
8770326ed3 | ||
|
|
b2e96746db | ||
|
|
6ce0be635b | ||
|
|
1001e95a87 | ||
|
|
609adcdf10 | ||
|
|
9de2580e30 | ||
|
|
9eb9081c6d | ||
|
|
f551b03dc7 | ||
|
|
1d5dd5e60f | ||
|
|
35a7036d4a | ||
|
|
7024929881 | ||
|
|
90058f25bf | ||
|
|
24ec9018fb | ||
|
|
ec01e5182d | ||
|
|
06d2880a7e | ||
|
|
2a611a8935 | ||
|
|
b236d95636 | ||
|
|
b1abfc768a | ||
|
|
9b97810109 | ||
|
|
4feffd90e3 | ||
|
|
dd8d2ea276 | ||
|
|
4c29b72242 | ||
|
|
ebe39771a6 | ||
|
|
63605ee42e | ||
|
|
b7f047db88 | ||
|
|
96289210d7 | ||
|
|
3b4a44abb1 | ||
|
|
e0797c83f8 | ||
|
|
30ffcc9246 | ||
|
|
a0945d2a2e | ||
|
|
c4cea9e71b | ||
|
|
35ec61726d | ||
|
|
f18a57b059 | ||
|
|
4ba180fbc4 | ||
|
|
0f34d407a4 | ||
|
|
4b29e9fbcb | ||
|
|
7f648720af | ||
|
|
58081c13cf | ||
|
|
78555f57a7 | ||
|
|
1ad40134dd | ||
|
|
9e16a405d8 | ||
|
|
9122a339cb | ||
|
|
56197274b6 | ||
|
|
6cf65ba82a | ||
|
|
aa59007409 | ||
|
|
66729e4c05 | ||
|
|
6387d32c2f | ||
|
|
48dbeb1e14 | ||
|
|
20452d7296 | ||
|
|
7daa67c792 | ||
|
|
4d9ba8d73b | ||
|
|
3650ef4805 | ||
|
|
be9154a015 | ||
|
|
0e00ca2350 | ||
|
|
2c0549a67a | ||
|
|
59e23e4296 | ||
|
|
3aa7a6e244 | ||
|
|
838c74a83b | ||
|
|
7f17bc9fb0 | ||
|
|
2dca6e8e7c | ||
|
|
a1bb3f9031 | ||
|
|
d1d4453120 | ||
|
|
48dcb02328 | ||
|
|
0a0cec6ef0 | ||
|
|
c3dd9f47fb | ||
|
|
5417f9b190 | ||
|
|
f03c873815 | ||
|
|
80adca5134 | ||
|
|
6efcac2a0e | ||
|
|
5162317298 | ||
|
|
90139b978c | ||
|
|
080fcb9c62 | ||
|
|
c437c2048d | ||
|
|
f80fcfd7c0 | ||
|
|
e9670aa5cb | ||
|
|
164b6e9070 | ||
|
|
5af18809a7 | ||
|
|
a719e8fda1 | ||
|
|
50fa8a0743 | ||
|
|
250f95deb6 | ||
|
|
bc98d82acf | ||
|
|
9e160d2431 | ||
|
|
77cff95c07 | ||
|
|
ecd780962f | ||
|
|
ab06597b7c | ||
|
|
b98a46b78c | ||
|
|
49e31707e5 | ||
|
|
92122e1fdd | ||
|
|
7238a65a6f | ||
|
|
e68ccf8532 | ||
|
|
220c52373a | ||
|
|
362fd86dbf | ||
|
|
8aba58188d | ||
|
|
41848dd99e | ||
|
|
f2fcfd6a47 | ||
|
|
33cdb906e2 | ||
|
|
19e73009b1 | ||
|
|
401e256d84 | ||
|
|
e1cd87433a | ||
|
|
23e5e1e3bd | ||
|
|
8f19f043a1 | ||
|
|
b1f07149c0 | ||
|
|
17acf18848 | ||
|
|
f52f589f7d | ||
|
|
e3e25bc233 | ||
|
|
a2f2ce1135 | ||
|
|
90152ab9f5 | ||
|
|
7a25f542e8 | ||
|
|
8c57250243 | ||
|
|
2e1eb1e224 | ||
|
|
b9a15e68de | ||
|
|
a9d2e03b65 | ||
|
|
d84b04dc35 | ||
|
|
7f3f082557 | ||
|
|
c810c68923 | ||
|
|
865a585c7f | ||
|
|
8703dd4229 | ||
|
|
d0c417b17d | ||
|
|
d09151d8f3 | ||
|
|
01a28860fe | ||
|
|
488b765f95 | ||
|
|
8a21b69fb0 | ||
|
|
eda3ed59df | ||
|
|
611ac0ab57 | ||
|
|
d485154a12 | ||
|
|
0caff7d5d5 | ||
|
|
6df7657c8e | ||
|
|
55d0f0bacd | ||
|
|
a74fac4cbf | ||
|
|
8aa58c0b11 | ||
|
|
4b9f8ab2b1 | ||
|
|
ba41533128 | ||
|
|
38069c6d63 | ||
|
|
1d66058240 | ||
|
|
43ac328e8a | ||
|
|
7519abf3fe | ||
|
|
849deae11e | ||
|
|
06a2b08780 | ||
|
|
4f9d3d8be5 | ||
|
|
ac3d658cb1 | ||
|
|
8f00191617 | ||
|
|
762391965e | ||
|
|
0fa3a2729d | ||
|
|
54640bb125 | ||
|
|
57d35a294d | ||
|
|
39069b322d | ||
|
|
540ce3a6ed | ||
|
|
ab22fb27ce | ||
|
|
0f564365f4 | ||
|
|
cccb7e4a39 | ||
|
|
1e837dec11 | ||
|
|
be3325ce35 | ||
|
|
c042d54714 | ||
|
|
77e2f95c66 | ||
|
|
403b416b2a | ||
|
|
b0901ccd01 | ||
|
|
6d2f8a97af | ||
|
|
bbd3324b79 | ||
|
|
5697b89817 | ||
|
|
6bf6bcb192 | ||
|
|
df74b31541 | ||
|
|
0b34bcdfa8 | ||
|
|
09a060a57b | ||
|
|
2a5147a0c1 | ||
|
|
4caa0e2f2e | ||
|
|
8f5c0af88e | ||
|
|
665d7eb831 | ||
|
|
d08b208bc6 | ||
|
|
c5d8117052 | ||
|
|
b769d18f73 | ||
|
|
b17760d228 | ||
|
|
2983c51db1 | ||
|
|
d6e11940cc | ||
|
|
17f15f546f | ||
|
|
688ef08cd5 | ||
|
|
8607a18a26 | ||
|
|
c5df78fd8b | ||
|
|
62bd96e06e | ||
|
|
399fd098b8 | ||
|
|
f9c21a9b52 | ||
|
|
41893cf06a | ||
|
|
83a8d4c14f | ||
|
|
6ce5ab40a7 | ||
|
|
328fa194a0 | ||
|
|
482b9c9333 | ||
|
|
122757ca9c | ||
|
|
49dd2204f4 | ||
|
|
07a3a0b388 | ||
|
|
56efbf1de7 | ||
|
|
57f31d443f | ||
|
|
65f308434a | ||
|
|
007e0f1c16 | ||
|
|
c249a2d187 | ||
|
|
78324263c1 | ||
|
|
c20229b56a | ||
|
|
1fd10771b0 | ||
|
|
1637920170 | ||
|
|
87ba966db8 | ||
|
|
258391cd8c | ||
|
|
481404e8d7 | ||
|
|
48737dcd01 | ||
|
|
b95585b0f6 | ||
|
|
14b2c1309f | ||
|
|
7e036b9df3 | ||
|
|
72fa32151d | ||
|
|
f5dbe8c6f6 | ||
|
|
93950a3b2e | ||
|
|
eec818f9fd | ||
|
|
a6f15af270 | ||
|
|
646497c3f0 | ||
|
|
2342c27ced | ||
|
|
80f6004404 | ||
|
|
a94946c77c | ||
|
|
659a65b8b9 | ||
|
|
c4b55e862f | ||
|
|
f8a75930b3 | ||
|
|
3a04b1b787 | ||
|
|
ad61a15611 | ||
|
|
d21bc0c277 | ||
|
|
fa3d117372 | ||
|
|
26249f5928 | ||
|
|
b7e6600e88 | ||
|
|
6e46cad56c | ||
|
|
e7340c5021 | ||
|
|
05d6c5f15a | ||
|
|
428442b310 | ||
|
|
753d247cf6 | ||
|
|
802f544cd5 | ||
|
|
bf62a947fb | ||
|
|
80c4908fcc | ||
|
|
30a29e23d3 | ||
|
|
5b08ae12a6 | ||
|
|
46e881bea3 | ||
|
|
5d1714dbd5 | ||
|
|
bd1de94312 | ||
|
|
06937d0aa0 | ||
|
|
9e39731133 | ||
|
|
3908cd5413 | ||
|
|
6be1a33093 | ||
|
|
c656cbf6ae | ||
|
|
83045a6512 | ||
|
|
199485640f | ||
|
|
2e41ff1121 | ||
|
|
487c6fae8d | ||
|
|
ea64b17b82 | ||
|
|
6d0578fd5a | ||
|
|
76a4deda78 | ||
|
|
595abd303c | ||
|
|
5dd6466c0a | ||
|
|
38655ee478 | ||
|
|
23ca25a1ca | ||
|
|
120cb4820e | ||
|
|
3ee0add6f6 | ||
|
|
8911fe5c8d | ||
|
|
1d9346513e | ||
|
|
62150ce6c4 | ||
|
|
b2d4135dca | ||
|
|
49e3e01ece | ||
|
|
23c2ff0e29 | ||
|
|
a550c255e6 | ||
|
|
6b897faaa8 | ||
|
|
48255f6f1e | ||
|
|
45bc3bd3db | ||
|
|
5ab20a9257 | ||
|
|
88e4918208 | ||
|
|
521ef8b6da | ||
|
|
0d86dfa571 | ||
|
|
472350e56f | ||
|
|
68569b9640 | ||
|
|
823f11d5dd | ||
|
|
ae19018831 | ||
|
|
d5b09c7b3e | ||
|
|
d3b4aa4dc7 | ||
|
|
c2da477735 | ||
|
|
843ff8eaaa | ||
|
|
c5143e2c54 | ||
|
|
0596f5e864 | ||
|
|
8ca1b25daf | ||
|
|
1f76159bfe | ||
|
|
39ece35f52 | ||
|
|
63c1bb9e17 | ||
|
|
354622c5ad | ||
|
|
df7fd8c900 | ||
|
|
7957690fca | ||
|
|
63d19447a0 | ||
|
|
018a84ec59 | ||
|
|
e5c0e623a0 | ||
|
|
9a2d3e15e8 | ||
|
|
c07e262e68 | ||
|
|
cacb2b91ee | ||
|
|
6f269d598f | ||
|
|
57ea254bff | ||
|
|
7e183c838f | ||
|
|
3ffdfd9736 | ||
|
|
621c701bef | ||
|
|
3c24c9966c | ||
|
|
995de525d9 | ||
|
|
ae30b1220a | ||
|
|
e380ad26c2 | ||
|
|
9bb31d2380 | ||
|
|
8ec1e4f3fa | ||
|
|
9f0f6841b0 | ||
|
|
5d18f98b44 | ||
|
|
e738177e08 | ||
|
|
bb201935b9 | ||
|
|
bcfe6bd616 | ||
|
|
9c6352a7bc | ||
|
|
9110e41f20 | ||
|
|
7ae871d3a6 | ||
|
|
0ddf027d43 | ||
|
|
45124a39f3 | ||
|
|
4940af0573 | ||
|
|
924b5d1733 | ||
|
|
2119a3a51e | ||
|
|
dcda99ddf3 | ||
|
|
0e35dcd5ad | ||
|
|
991d42ca0b | ||
|
|
ac242c96b7 | ||
|
|
79d45c8e33 | ||
|
|
8e9f7102f9 | ||
|
|
1952dc309b | ||
|
|
5e7767247f | ||
|
|
676bf686c7 | ||
|
|
5cd6985368 | ||
|
|
807e72dcce | ||
|
|
71702b5821 | ||
|
|
40c56248f1 | ||
|
|
74ac7d8d3f | ||
|
|
e7186b47b0 | ||
|
|
661e80084c | ||
|
|
12aa7ea2cb | ||
|
|
ef584e2826 | ||
|
|
f902be10b6 | ||
|
|
29b835de59 | ||
|
|
6ff9c5b58d | ||
|
|
1b86aeb4f5 | ||
|
|
dce99c00be | ||
|
|
e47c700c36 | ||
|
|
09506c78f3 | ||
|
|
9ec1fc0902 | ||
|
|
0b3ec2c19e | ||
|
|
a94bec921c | ||
|
|
3884da3c06 | ||
|
|
d3fa177c7f | ||
|
|
d2176e2c08 | ||
|
|
8d9c59486d | ||
|
|
0e7c2b4b94 | ||
|
|
5c9bc1c745 | ||
|
|
5e7efa0098 | ||
|
|
424862e313 | ||
|
|
9b80ad5a3c | ||
|
|
96c6fa0276 | ||
|
|
69305e1833 | ||
|
|
8aa74ab65e | ||
|
|
aee12c2494 | ||
|
|
83976b3229 | ||
|
|
39f8a138d7 | ||
|
|
120e4af7b2 | ||
|
|
15bddbc86a | ||
|
|
4e8b193801 | ||
|
|
37b65996a0 | ||
|
|
9cd0d3488f | ||
|
|
eaf07cef07 | ||
|
|
02a8775537 | ||
|
|
f2d5698acb | ||
|
|
b0c0e456af | ||
|
|
0857a2ea91 | ||
|
|
1f2e6d33ce | ||
|
|
250e0690d1 | ||
|
|
e709094533 | ||
|
|
4a5b16ee2e | ||
|
|
378d64f99a | ||
|
|
4395760a40 | ||
|
|
8417fae89c | ||
|
|
6c8fae944c | ||
|
|
decab9256b | ||
|
|
183ed35ce8 | ||
|
|
2fcf85fd61 | ||
|
|
3613c1c75e | ||
|
|
e7813046f6 | ||
|
|
9871bf1963 | ||
|
|
b32e7b659b | ||
|
|
2201372744 | ||
|
|
7431a082e2 | ||
|
|
6fe3edebb1 | ||
|
|
4b6406c264 | ||
|
|
86f6bdf9af | ||
|
|
1eeed6645d | ||
|
|
bb8c4325c6 | ||
|
|
07a3301414 | ||
|
|
1590701fc9 | ||
|
|
1d4a65d0b4 | ||
|
|
c845d25ae5 | ||
|
|
ceec27bf90 | ||
|
|
4b90424773 | ||
|
|
31eb9b26b4 | ||
|
|
a8a3c9ad19 | ||
|
|
5cfa03ec07 | ||
|
|
17ab5978ad | ||
|
|
d4c69c3932 | ||
|
|
3778a9ebcf | ||
|
|
880d94e220 | ||
|
|
37607f72b2 | ||
|
|
b1c26e6f64 | ||
|
|
8164af281d | ||
|
|
af676c8f26 | ||
|
|
b8dc7ff18e | ||
|
|
4aee129cdc | ||
|
|
03d29dd674 | ||
|
|
5a6f84ce34 | ||
|
|
0e593c7d81 | ||
|
|
4de830d663 | ||
|
|
769bb7a55d | ||
|
|
ed6c6e5a25 | ||
|
|
302ba75729 | ||
|
|
69dc8f304c | ||
|
|
e43002d5ad | ||
|
|
edd07befe2 | ||
|
|
5cc6a2f7d0 | ||
|
|
926f39c96b | ||
|
|
abd38082de | ||
|
|
5ca90f4d22 | ||
|
|
c9586e579a | ||
|
|
fe7962e10a |
No files matched your search
@@ -1,5 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-stage-3"
|
||||
]
|
||||
],
|
||||
"env": {
|
||||
"COVERAGE": {
|
||||
"plugins": [
|
||||
"istanbul"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+100
-18
@@ -1,16 +1,16 @@
|
||||
FROM quay.io/wekan/ubuntu:groovy-20201125.2
|
||||
FROM ubuntu:21.10
|
||||
LABEL maintainer="sgr"
|
||||
|
||||
# 2020-12-03:
|
||||
# - Above Ubuntu base image copied from Docker Hub ubuntu:groovy-20201125.2
|
||||
# to Quay to avoid Docker Hub rate limits.
|
||||
# 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
|
||||
|
||||
ENV BUILD_DEPS="gnupg gosu bsdtar wget curl bzip2 g++ build-essential python git ca-certificates iproute2"
|
||||
ENV BUILD_DEPS="gnupg gosu libarchive-tools wget curl bzip2 g++ build-essential python3 git ca-certificates iproute2"
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ENV \
|
||||
DEBUG=false \
|
||||
NODE_VERSION=v12.22.0 \
|
||||
NODE_VERSION=v14.19.2 \
|
||||
METEOR_RELEASE=1.10.2 \
|
||||
USE_EDGE=false \
|
||||
METEOR_EDGE=1.5-beta.17 \
|
||||
@@ -26,6 +26,7 @@ ENV \
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 \
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 \
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 \
|
||||
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 \
|
||||
RICHER_CARD_COMMENT_EDITOR=false \
|
||||
CARD_OPENED_WEBHOOK_ENABLED=false \
|
||||
ATTACHMENTS_STORE_PATH="" \
|
||||
@@ -134,23 +135,33 @@ ENV \
|
||||
SAML_PUBLIC_CERTFILE="" \
|
||||
SAML_IDENTIFIER_FORMAT="" \
|
||||
SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE="" \
|
||||
SAML_ATTRIBUTES=""
|
||||
SAML_ATTRIBUTES="" \
|
||||
DEFAULT_WAIT_SPINNER="" \
|
||||
NODE_OPTIONS="--max_old_space_size=4096"
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# 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"
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
# Install OS
|
||||
RUN set -o xtrace \
|
||||
&& useradd --user-group -m --system --home-dir /home/wekan wekan \
|
||||
&& apt-get update \
|
||||
&& apt-get install --assume-yes --no-install-recommends apt-utils apt-transport-https ca-certificates 2>&1 \
|
||||
&& apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS}
|
||||
&& apt-get install --assume-yes --no-install-recommends apt-utils apt-transport-https ca-certificates 2>&1 \
|
||||
&& apt-get install --assume-yes --no-install-recommends ${BUILD_DEPS}
|
||||
|
||||
# Install NodeJS
|
||||
RUN set -o xtrace \
|
||||
&& cd /tmp \
|
||||
&& curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-$ARCHITECTURE.tar.xz" \
|
||||
&& curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
|
||||
&& grep " node-v$NODE_VERSION-$ARCHITECTURE.tar.xz\$" SHASUMS256.txt.asc | sha256sum -c - \
|
||||
&& tar -xJf "node-v$NODE_VERSION-$ARCHITECTURE.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
|
||||
&& rm "node-v$NODE_VERSION-$ARCHITECTURE.tar.xz" SHASUMS256.txt.asc \
|
||||
&& curl -fsSLO --compressed "https://nodejs.org/dist/$NODE_VERSION/node-$NODE_VERSION-$ARCHITECTURE.tar.xz" \
|
||||
&& curl -fsSLO --compressed "https://nodejs.org/dist/$NODE_VERSION/SHASUMS256.txt.asc" \
|
||||
&& grep " node-$NODE_VERSION-$ARCHITECTURE.tar.xz\$" SHASUMS256.txt.asc | sha256sum -c - \
|
||||
&& tar -xJf "node-$NODE_VERSION-$ARCHITECTURE.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
|
||||
&& rm "node-$NODE_VERSION-$ARCHITECTURE.tar.xz" SHASUMS256.txt.asc \
|
||||
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs \
|
||||
&& mkdir -p /usr/local/lib/node_modules/fibers/.node-gyp /root/.node-gyp/${NODE_VERSION} /home/wekan/.config \
|
||||
&& npm install -g npm@${NPM_VERSION} \
|
||||
@@ -172,17 +183,88 @@ RUN set -o xtrace \
|
||||
|
||||
ENV PATH=$PATH:/home/wekan/.meteor/
|
||||
|
||||
# Copy source dir
|
||||
USER root
|
||||
|
||||
RUN echo "export PATH=$PATH" >> /etc/environment
|
||||
|
||||
RUN set -o xtrace \
|
||||
&& mkdir /home/wekan/app
|
||||
USER wekan
|
||||
|
||||
COPY ${SRC_PATH} /home/wekan/app/
|
||||
# Copy source dir
|
||||
RUN set -o xtrace \
|
||||
&& mkdir -p /home/wekan/app/.meteor \
|
||||
&& mkdir -p /home/wekan/app/packages
|
||||
|
||||
COPY \
|
||||
.meteor/.finished-upgraders \
|
||||
.meteor/.id \
|
||||
.meteor/cordova-plugins \
|
||||
.meteor/packages \
|
||||
.meteor/platforms \
|
||||
.meteor/release \
|
||||
.meteor/versions \
|
||||
/home/wekan/app/.meteor/
|
||||
|
||||
COPY \
|
||||
package.json \
|
||||
settings.json \
|
||||
/home/wekan/app/
|
||||
|
||||
COPY \
|
||||
tests \
|
||||
/home/wekan/app/tests/
|
||||
|
||||
COPY \
|
||||
packages \
|
||||
/home/wekan/app/packages/
|
||||
|
||||
USER root
|
||||
|
||||
RUN set -o xtrace \
|
||||
&& chown -R wekan:wekan /home/wekan/app /home/wekan/.meteor
|
||||
|
||||
USER wekan
|
||||
|
||||
RUN \
|
||||
set -o xtrace && \
|
||||
# Build app
|
||||
cd /home/wekan/app && \
|
||||
/home/wekan/.meteor/meteor add standard-minifier-js && \
|
||||
/home/wekan/.meteor/meteor npm install && \
|
||||
/home/wekan/.meteor/meteor build --directory /home/wekan/app_build
|
||||
|
||||
RUN \
|
||||
set -o xtrace && \
|
||||
cd /home/wekan/app_build/bundle/programs/server/ && \
|
||||
chmod u+w package.json npm-shrinkwrap.json && \
|
||||
npm install && \
|
||||
cd node_modules/fibers && \
|
||||
node build.js
|
||||
|
||||
USER root
|
||||
# Cleanup
|
||||
RUN \
|
||||
set -o xtrace && \
|
||||
apt-get clean -y && \
|
||||
apt-get autoremove -y && \
|
||||
rm -Rf /tmp/* && \
|
||||
rm -Rf /home/wekan/app_build && \
|
||||
rm -Rf /var/cache/apt /var/lib/apt/lists && \
|
||||
rm -Rf /var/lib/apt/lists/*
|
||||
|
||||
USER wekan
|
||||
|
||||
ENV PORT=3000
|
||||
EXPOSE $PORT
|
||||
WORKDIR /home/wekan/app
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# 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"
|
||||
#---------------------------------------------------------------------
|
||||
#TODO:
|
||||
#CMD ["bash", "-c", "ulimit -s 65500; exec node --stack-size=65500 /build/main.js"]
|
||||
|
||||
CMD ["/home/wekan/.meteor/meteor", "run", "--verbose", "--settings", "settings.json"]
|
||||
@@ -9,4 +9,6 @@ cp -f fix-download-unicode/cfs_access-point.txt .build/bundle/programs/server/pa
|
||||
cd .build/bundle/programs/server
|
||||
rm -rf node_modules
|
||||
/home/wekan/.meteor/meteor npm install
|
||||
cd node_modules/fibers
|
||||
node build.js
|
||||
cd /home/wekan/app
|
||||
@@ -3,17 +3,18 @@ version: '3.7'
|
||||
services:
|
||||
|
||||
wekandb-dev:
|
||||
image: mongo:4.0.12
|
||||
image: mongo:5.0
|
||||
container_name: wekan-dev-db
|
||||
restart: unless-stopped
|
||||
command: mongod --smallfiles --oplogSize 128
|
||||
command: mongod --oplogSize 128
|
||||
networks:
|
||||
- wekan-dev-tier
|
||||
expose:
|
||||
- 27017
|
||||
volumes:
|
||||
- wekan-dev-db:/data/db
|
||||
- wekan-dev-db-dump:/dump
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ./volumes/wekan-db:/data/db
|
||||
- ./volumes/wekan-db-dump:/dump
|
||||
|
||||
wekan-dev:
|
||||
container_name: wekan-dev-app
|
||||
@@ -32,18 +33,18 @@ services:
|
||||
- WITH_API=true
|
||||
- RICHER_CARD_COMMENT_EDITOR=true
|
||||
- BROWSER_POLICY_ENABLED=true
|
||||
- WRITABLE_PATH=/data
|
||||
depends_on:
|
||||
- wekandb-dev
|
||||
volumes:
|
||||
- ..:/app:delegated
|
||||
command:
|
||||
sleep infinity
|
||||
|
||||
volumes:
|
||||
wekan-dev-db:
|
||||
driver: local
|
||||
wekan-dev-db-dump:
|
||||
driver: local
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ./volumes/data:/data
|
||||
- ../client:/home/wekan/app/client
|
||||
- ../models:/home/wekan/app/models
|
||||
- ../config:/home/wekan/app/config
|
||||
- ../imports:/home/wekan/app/imports
|
||||
- ../server:/home/wekan/app/server
|
||||
- ../public:/home/wekan/app/public
|
||||
|
||||
networks:
|
||||
wekan-dev-tier:
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
*~
|
||||
*.swp
|
||||
.meteor-spk
|
||||
*.sublime-workspace
|
||||
tmp/
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
.gitmodules
|
||||
.vscode/
|
||||
.idea/
|
||||
.build/*
|
||||
**/parts/
|
||||
**/stage
|
||||
**/prime
|
||||
**/*.snap
|
||||
snap/.snapcraft/
|
||||
.idea
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
.build*
|
||||
*.browserify.js.cached
|
||||
*.browserify.js.map
|
||||
.build*
|
||||
versions.json
|
||||
.versions
|
||||
.npm
|
||||
.build*
|
||||
._*
|
||||
.Trashes
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
.eslintcache
|
||||
.meteor/local
|
||||
.devcontainer/docker-compose.extend.yml
|
||||
.devcontainer/volumes*/
|
||||
.git
|
||||
@@ -122,6 +122,7 @@
|
||||
"Activities": true,
|
||||
"Attachments": true,
|
||||
"Boards": true,
|
||||
"CardCommentReactions": true,
|
||||
"CardComments": true,
|
||||
"DatePicker": true,
|
||||
"Cards": true,
|
||||
@@ -156,6 +157,7 @@
|
||||
"Integrations": true,
|
||||
"HTTP": true,
|
||||
"AccountSettings": true,
|
||||
"TableVisibilityModeSettings": true,
|
||||
"Announcements": true,
|
||||
"Swimlanes": true,
|
||||
"ChecklistItems": true,
|
||||
|
||||
@@ -81,7 +81,7 @@ parts:
|
||||
wekan:
|
||||
source: .
|
||||
plugin: nodejs
|
||||
node-engine: 12.22.0
|
||||
node-engine: 14.19.2
|
||||
node-packages:
|
||||
- node-gyp
|
||||
- node-pre-gyp
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
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
|
||||
+93
-65
@@ -1,8 +1,9 @@
|
||||
name: wekan
|
||||
version: git
|
||||
summary: The open-source kanban
|
||||
version: '6.21'
|
||||
base: core20
|
||||
summary: Open Source kanban
|
||||
description: |
|
||||
Wekan is an open-source and collaborative kanban board application.
|
||||
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.
|
||||
@@ -11,10 +12,19 @@ description: |
|
||||
|
||||
confinement: strict
|
||||
grade: stable
|
||||
base: core18
|
||||
|
||||
architectures:
|
||||
- amd64
|
||||
- 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:
|
||||
@@ -37,12 +47,14 @@ apps:
|
||||
wekan:
|
||||
command: wekan-control
|
||||
daemon: simple
|
||||
plugs: [network, network-bind]
|
||||
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
|
||||
restart-condition: on-failure
|
||||
|
||||
mongodb:
|
||||
command: mongodb-control
|
||||
daemon: simple
|
||||
plugs: [network, network-bind]
|
||||
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
|
||||
restart-condition: on-failure
|
||||
|
||||
caddy:
|
||||
command: caddy-control
|
||||
@@ -54,22 +66,27 @@ apps:
|
||||
|
||||
database-backup:
|
||||
command: mongodb-backup
|
||||
plugs: [network, network-bind]
|
||||
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]
|
||||
plugs: [network, network-bind, mount-observe, system-observe, bluetooth-control]
|
||||
|
||||
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]
|
||||
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
|
||||
@@ -81,61 +98,46 @@ parts:
|
||||
- $mongo
|
||||
|
||||
wekan:
|
||||
source: .
|
||||
plugin: nodejs
|
||||
node-engine: 12.22.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
|
||||
#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: |
|
||||
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
|
||||
|
||||
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
|
||||
@@ -143,8 +145,34 @@ parts:
|
||||
|
||||
caddy:
|
||||
plugin: dump
|
||||
source: https://caddyserver.com/download/linux/amd64?license=personal&telemetry=off
|
||||
source-type: tar
|
||||
## 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
|
||||
|
||||
+24
-21
@@ -1,32 +1,35 @@
|
||||
## Issue
|
||||
<!--
|
||||
**[PLEASE UPGRADE](https://github.com/wekan/wekan/wiki/Backup)** to the newest WeKan ® before reporting an issue.
|
||||
Please search existing Open and Closed issues, most questions have already been answered.
|
||||
|
||||
Email settings:
|
||||
- https://github.com/wekan/wekan/wiki/Troubleshooting-Mail
|
||||
If you can not login for any reason: https://github.com/wekan/wekan/wiki/Forgot-Password
|
||||
Email settings, only SMTP MAIL_URL and MAIL_FROM are in use: https://github.com/wekan/wekan/wiki/Troubleshooting-Mail
|
||||
|
||||
Add these issues to elsewhere:
|
||||
The following types of issues should be reported separately:
|
||||
- SECURITY ISSUES: https://github.com/wekan/wekan/blob/master/SECURITY.md
|
||||
- UCS: https://github.com/wekan/univention/issues
|
||||
-->
|
||||
|
||||
Other Wekan issues can be added here.
|
||||
|
||||
**Server Setup Information**:
|
||||
|
||||
* Note: Please anonymize info, and do not add to this public issue any of your Wekan board URLs, passwords, API tokens etc, do you understand?:
|
||||
### Server Setup Information
|
||||
<!-- Please anonymize info, and do not any of your Wekan board URLs, passwords, API tokens etc to this public issue. -->
|
||||
* Did you test in newest Wekan?:
|
||||
* For new Wekan install, did you configure root-url correctly so Wekan cards open correctly https://github.com/wekan/wekan/wiki/Settings ?
|
||||
* Wekan version:
|
||||
* If this is about old version of Wekan, what upgrade problem you have?:
|
||||
* Did you configure root-url correctly so Wekan cards open correctly (see https://github.com/wekan/wekan/wiki/Settings)?
|
||||
* Operating System:
|
||||
* Deployment Method(snap/docker/sandstorm/mongodb bundle/source):
|
||||
* Deployment Method (Snap/Docker/Sandstorm/bundle/source):
|
||||
* Http frontend if any (Caddy, Nginx, Apache, see config examples from Wekan GitHub wiki first):
|
||||
* Node Version:
|
||||
* Node.js Version:
|
||||
* MongoDB Version:
|
||||
* Wekan only works on newest desktop Firefox/Chromium/Chrome/Edge/Chromium Edge and mobile Chrome. What webbrowser version are you using?
|
||||
* What webbrowser version are you using (Wekan should work on all modern browsers that support Javascript)?
|
||||
|
||||
**Problem description**:
|
||||
- *REQUIRED: Add recorded animated gif about how it works currently, and screenshot mockups how it should work. Use peek to record animgif in Linux https://github.com/phw/peek*
|
||||
- *Explain steps how to reproduce*
|
||||
- *In webbrowser, what does show Right Click / Inspect / Console ? Chrome shows more detailed info than Firefox.*
|
||||
- *If using Snap, what does show command `sudo snap logs wekan.wekan` ? Please anonymize logs.*
|
||||
- *If using Docker, what does show command `sudo docker logs wekan-app` ? Please anonymize logs.*
|
||||
- *If logs are very long, attach them in .zip file*
|
||||
### Problem description
|
||||
<!-- Add a recorded animated gif (e.g. with https://github.com/phw/peek) about how it works currently, and screenshot mockups how it should work. -->
|
||||
#### Reproduction Steps
|
||||
|
||||
#### Logs
|
||||
<!-- Check Right Click>Inspect>Console in you browser - generally Chrome shows more detailed info than Firefox. -->
|
||||
|
||||
<!-- Please anonymize logs.
|
||||
Snap: sudo snap logs wekan.wekan
|
||||
Docker: sudo docker logs wekan-app
|
||||
If logs are very long, attach them in .zip file -->
|
||||
@@ -0,0 +1,63 @@
|
||||
name: Docker
|
||||
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '28 23 * * *'
|
||||
push:
|
||||
branches: [ master ]
|
||||
# Publish semver tags as releases.
|
||||
tags: [ 'v*.*.*' ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# 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@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Extract metadata (tags, labels) for Docker
|
||||
# https://github.com/docker/metadata-action
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
|
||||
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@ad44023a93711e3deb337508980b4b5e9bcdc5dc
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
@@ -1,12 +0,0 @@
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
zap_scan:
|
||||
runs-on: ubuntu-latest
|
||||
name: Scan the webapplication
|
||||
steps:
|
||||
- name: OWASP ZAP Scan
|
||||
runs-on: ubuntu-latest
|
||||
uses: zaproxy/action-baseline@v0.4.0
|
||||
with:
|
||||
target: 'https://boards.wekan.team/sign-in'
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Release Charts
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config user.name "$GITHUB_ACTOR"
|
||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
|
||||
- name: Run chart-releaser
|
||||
uses: helm/chart-releaser-action@v1.1.0
|
||||
env:
|
||||
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
@@ -0,0 +1,160 @@
|
||||
name: Test suite
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
# the following are optional jobs and need to be configured according
|
||||
# to this project's settings:
|
||||
#
|
||||
# lintcode:
|
||||
# name: Javascript lint
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: checkout
|
||||
# uses: actions/checkout@v2
|
||||
#
|
||||
# - name: setup node
|
||||
# uses: actions/setup-node@v1
|
||||
# with:
|
||||
# node-version: '12.x'
|
||||
#
|
||||
# - name: cache dependencies
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ~/.npm
|
||||
# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-node-
|
||||
#
|
||||
# - run: npm install
|
||||
# - run: npm run lint:code
|
||||
#
|
||||
# lintstyle:
|
||||
# name: SCSS lint
|
||||
# runs-on: ubuntu-latest
|
||||
# needs: [lintcode]
|
||||
# steps:
|
||||
# - name: checkout
|
||||
# uses: actions/checkout@v2
|
||||
#
|
||||
# - name: setup node
|
||||
# uses: actions/setup-node@v1
|
||||
# with:
|
||||
# node-version: '12.x'
|
||||
#
|
||||
# - name: cache dependencies
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ~/.npm
|
||||
# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-node-
|
||||
# - run: npm install
|
||||
# - run: npm run lint:style
|
||||
#
|
||||
# lintdocs:
|
||||
# name: documentation lint
|
||||
# runs-on: ubuntu-latest
|
||||
# needs: [lintcode,lintstyle]
|
||||
# steps:
|
||||
# - name: checkout
|
||||
# uses: actions/checkout@v2
|
||||
#
|
||||
# - name: setup node
|
||||
# uses: actions/setup-node@v1
|
||||
# with:
|
||||
# node-version: '12.x'
|
||||
#
|
||||
# - name: cache dependencies
|
||||
# uses: actions/cache@v1
|
||||
# with:
|
||||
# path: ~/.npm
|
||||
# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-node-
|
||||
#
|
||||
# - run: npm install
|
||||
# - run: npm run lint:markdown
|
||||
|
||||
tests:
|
||||
name: Meteor ${{ matrix.meteor }} tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
# CHECKOUTS
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# CACHING
|
||||
- name: Install Meteor
|
||||
id: cache-meteor-install
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.meteor
|
||||
key: v1-meteor-${{ hashFiles('.meteor/versions') }}
|
||||
restore-keys: |
|
||||
v1-meteor-
|
||||
|
||||
- name: Cache NPM dependencies
|
||||
id: cache-meteor-npm
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: v1-npm-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: |
|
||||
v1-npm-
|
||||
|
||||
- name: Cache Meteor build
|
||||
id: cache-meteor-build
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
.meteor/local/resolver-result-cache.json
|
||||
.meteor/local/plugin-cache
|
||||
.meteor/local/isopacks
|
||||
.meteor/local/bundler-cache/scanner
|
||||
key: v1-meteor_build_cache-${{ github.ref }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
v1-meteor_build_cache-
|
||||
|
||||
- name: Setup meteor
|
||||
uses: meteorengineer/setup-meteor@v1
|
||||
with:
|
||||
meteor-release: '2.2'
|
||||
|
||||
- name: Install NPM Dependencies
|
||||
run: meteor npm ci
|
||||
|
||||
- name: Run Tests
|
||||
run: sh ./test-wekan.sh -cv
|
||||
|
||||
- name: Upload coverage
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: coverage-folder
|
||||
path: .coverage/
|
||||
|
||||
coverage:
|
||||
name: Coverage report
|
||||
runs-on: ubuntu-latest
|
||||
needs: [tests]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Download coverage
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: coverage-folder
|
||||
path: .coverage/
|
||||
|
||||
|
||||
- name: Coverage Report
|
||||
uses: VeryGoodOpenSource/very_good_coverage@v1.1.1
|
||||
with:
|
||||
path: ".coverage/lcov.info"
|
||||
min_coverage: 1 # TODO add tests and increase to 95!
|
||||
+8
-1
@@ -1,5 +1,5 @@
|
||||
*~
|
||||
*.swp
|
||||
*.sw*
|
||||
.meteor-spk
|
||||
*.sublime-workspace
|
||||
tmp/
|
||||
@@ -32,3 +32,10 @@ ehthumbs.db
|
||||
.eslintcache
|
||||
.meteor/local
|
||||
.devcontainer/docker-compose.extend.yml
|
||||
.devcontainer/volumes*/
|
||||
.coverage
|
||||
|
||||
# Helm chart
|
||||
# Chart dependencies
|
||||
/helm/wekan/**/*.tgz
|
||||
/helm/wekan/charts
|
||||
+38
-37
@@ -3,12 +3,12 @@
|
||||
# 'meteor add' and 'meteor remove' will edit this file for you,
|
||||
# but you can also edit it by hand.
|
||||
|
||||
meteor-base@1.4.0
|
||||
meteor-base@1.5.1
|
||||
|
||||
# Build system
|
||||
ecmascript@0.15.0
|
||||
standard-minifier-css@1.7.2
|
||||
standard-minifier-js@2.6.0
|
||||
ecmascript@0.16.2
|
||||
standard-minifier-css@1.8.1
|
||||
standard-minifier-js@2.8.0
|
||||
mquandalle:jade
|
||||
coffeescript@2.4.1!
|
||||
|
||||
@@ -21,19 +21,14 @@ cfs:standard-packages
|
||||
cottz:publish-relations
|
||||
dburles:collection-helpers
|
||||
idmontie:migrations
|
||||
matb33:collection-hooks
|
||||
matteodem:easy-search
|
||||
mongo@1.10.1
|
||||
mongo@1.15.0
|
||||
mquandalle:collection-mutations
|
||||
|
||||
# Account system
|
||||
kenton:accounts-sandstorm
|
||||
service-configuration@1.0.11
|
||||
useraccounts:unstyled
|
||||
useraccounts:flow-routing
|
||||
wekan-ldap
|
||||
wekan-accounts-cas
|
||||
wekan-accounts-oidc
|
||||
#wekan-ldap
|
||||
#wekan-accounts-cas
|
||||
#wekan-accounts-oidc
|
||||
|
||||
# Utilities
|
||||
check@1.3.1
|
||||
@@ -43,7 +38,6 @@ reactive-dict@1.3.0
|
||||
session@1.2.0
|
||||
tracker@1.2.0
|
||||
underscore@1.0.10
|
||||
3stack:presence
|
||||
arillo:flow-router-helpers
|
||||
audit-argument-checks@1.0.7
|
||||
kadira:blaze-layout
|
||||
@@ -51,49 +45,36 @@ kadira:dochead
|
||||
mquandalle:autofocus
|
||||
ongoworks:speakingurl
|
||||
raix:handlebar-helpers
|
||||
tap:i18n
|
||||
http@1.4.2
|
||||
http@2.0.0! # force new http package
|
||||
|
||||
# UI components
|
||||
blaze
|
||||
ostrio:i18n
|
||||
reactive-var@1.0.11
|
||||
fortawesome:fontawesome
|
||||
mousetrap:mousetrap
|
||||
mquandalle:jquery-textcomplete
|
||||
mquandalle:jquery-ui-drag-drop-sort
|
||||
mquandalle:mousetrap-bindglobal
|
||||
peerlibrary:blaze-components@=0.15.1
|
||||
peerlibrary:blaze-components
|
||||
templates:tabs
|
||||
verron:autosize
|
||||
simple:json-routes
|
||||
meteor-autosize
|
||||
rajit:bootstrap3-datepicker
|
||||
shell-server@0.5.0
|
||||
simple:rest-accounts-password
|
||||
useraccounts:core
|
||||
email@2.0.0
|
||||
horka:swipebox
|
||||
dynamic-import@0.6.0
|
||||
email@2.2.1
|
||||
dynamic-import@0.7.2
|
||||
|
||||
accounts-password@1.7.0
|
||||
cfs:gridfs
|
||||
rzymek:fullcalendar
|
||||
momentjs:moment@2.22.2
|
||||
browser-policy-framing@1.1.0
|
||||
mquandalle:moment
|
||||
msavin:usercache
|
||||
# Keep stylus in 1.1.0, because building v2 takes extra 52 minutes.
|
||||
coagmano:stylus@1.1.0!
|
||||
lucasantoniassi:accounts-lockout
|
||||
meteorhacks:subs-manager
|
||||
meteorhacks:picker
|
||||
lamhieu:unblock
|
||||
meteorhacks:aggregate@1.3.0
|
||||
wekan-markdown
|
||||
konecty:mongo-counter
|
||||
percolate:synced-cron
|
||||
cfs:filesystem
|
||||
tmeasday:check-npm-versions
|
||||
steffo:meteor-accounts-saml
|
||||
ostrio:cookies
|
||||
ostrio:files@2.0.1
|
||||
rajit:bootstrap3-datepicker-fi
|
||||
rajit:bootstrap3-datepicker-ar
|
||||
rajit:bootstrap3-datepicker-bg
|
||||
@@ -142,6 +123,26 @@ rajit:bootstrap3-datepicker-uk
|
||||
rajit:bootstrap3-datepicker-vi
|
||||
rajit:bootstrap3-datepicker-zh-cn
|
||||
rajit:bootstrap3-datepicker-zh-tw
|
||||
staringatlights:fast-render
|
||||
spacebars
|
||||
easylogic:summernote
|
||||
pascoual:pdfkit
|
||||
lmieulet:meteor-coverage
|
||||
meteortesting:mocha@2.0.3
|
||||
aldeed:simple-schema
|
||||
accounts-password@2.3.1
|
||||
matb33:collection-hooks
|
||||
simple:json-routes
|
||||
kadira:flow-router
|
||||
spacebars
|
||||
useraccounts:core
|
||||
useraccounts:flow-routing
|
||||
useraccounts:unstyled
|
||||
service-configuration@1.3.0
|
||||
communitypackages:picker
|
||||
simple:rest-accounts-password
|
||||
wekan-accounts-sandstorm
|
||||
wekan-accounts-lockout
|
||||
wekan-oidc
|
||||
wekan-accounts-oidc
|
||||
wekan-ldap
|
||||
wekan-accounts-cas
|
||||
czbaker:lightbox2
|
||||
+1
-1
@@ -1 +1 @@
|
||||
METEOR@2.1
|
||||
METEOR@2.7.2
|
||||
+82
-90
@@ -1,28 +1,25 @@
|
||||
3stack:presence@1.1.2
|
||||
accounts-base@1.8.0
|
||||
accounts-oauth@1.2.0
|
||||
accounts-password@1.7.0
|
||||
accounts-base@2.2.3
|
||||
accounts-oauth@1.4.1
|
||||
accounts-password@2.3.1
|
||||
aldeed:collection2@2.10.0
|
||||
aldeed:collection2-core@1.2.0
|
||||
aldeed:schema-deny@1.1.0
|
||||
aldeed:schema-index@1.1.1
|
||||
aldeed:simple-schema@1.5.4
|
||||
allow-deny@1.1.0
|
||||
allow-deny@1.1.1
|
||||
arillo:flow-router-helpers@0.5.2
|
||||
audit-argument-checks@1.0.7
|
||||
autoupdate@1.7.0
|
||||
babel-compiler@7.6.0
|
||||
autoupdate@1.8.0
|
||||
babel-compiler@7.9.0
|
||||
babel-runtime@1.5.0
|
||||
base64@1.0.12
|
||||
binary-heap@1.0.11
|
||||
blaze@2.3.4
|
||||
blaze-tools@1.0.10
|
||||
blaze@2.6.0
|
||||
blaze-tools@1.1.3
|
||||
boilerplate-generator@1.7.1
|
||||
browser-policy-common@1.0.11
|
||||
browser-policy-framing@1.1.0
|
||||
caching-compiler@1.2.2
|
||||
caching-html-compiler@1.1.3
|
||||
callback-hook@1.3.0
|
||||
caching-html-compiler@1.2.1
|
||||
callback-hook@1.4.0
|
||||
cfs:access-point@0.1.49
|
||||
cfs:base-package@0.0.30
|
||||
cfs:collection@0.5.5
|
||||
@@ -42,77 +39,76 @@ cfs:tempstore@0.1.6
|
||||
cfs:upload-http@0.0.20
|
||||
cfs:worker@0.1.5
|
||||
check@1.3.1
|
||||
chuangbo:cookie@1.1.0
|
||||
coagmano:stylus@1.1.0
|
||||
coffeescript@2.4.1
|
||||
coffeescript-compiler@2.4.1
|
||||
communitypackages:picker@1.1.0
|
||||
cottz:publish-relations@2.0.8
|
||||
czbaker:lightbox2@2.7.1_1
|
||||
dburles:collection-helpers@1.1.0
|
||||
ddp@1.4.0
|
||||
ddp-client@2.4.0
|
||||
ddp-client@2.5.0
|
||||
ddp-common@1.4.0
|
||||
ddp-rate-limiter@1.0.9
|
||||
ddp-server@2.3.2
|
||||
ddp-rate-limiter@1.1.0
|
||||
ddp-server@2.5.0
|
||||
deps@1.0.12
|
||||
diff-sequence@1.1.1
|
||||
dynamic-import@0.6.0
|
||||
dynamic-import@0.7.2
|
||||
easylogic:summernote@0.8.8
|
||||
ecmascript@0.15.0
|
||||
ecmascript-runtime@0.7.0
|
||||
ecmascript-runtime-client@0.11.0
|
||||
ecmascript-runtime-server@0.10.0
|
||||
ejson@1.1.1
|
||||
email@2.0.0
|
||||
ecmascript@0.16.2
|
||||
ecmascript-runtime@0.8.0
|
||||
ecmascript-runtime-client@0.12.1
|
||||
ecmascript-runtime-server@0.11.0
|
||||
ejson@1.1.2
|
||||
email@2.2.1
|
||||
es5-shim@4.8.0
|
||||
fastclick@1.0.13
|
||||
fetch@0.1.1
|
||||
fortawesome:fontawesome@4.7.0
|
||||
geojson-utils@1.0.10
|
||||
horka:swipebox@1.0.2
|
||||
hot-code-push@1.0.4
|
||||
html-tools@1.0.11
|
||||
htmljs@1.0.11
|
||||
http@1.4.3
|
||||
id-map@1.1.0
|
||||
html-tools@1.1.3
|
||||
htmljs@1.1.1
|
||||
http@2.0.0
|
||||
id-map@1.1.1
|
||||
idmontie:migrations@1.0.3
|
||||
inter-process-messaging@0.1.1
|
||||
jquery@1.11.11
|
||||
kadira:blaze-layout@2.3.0
|
||||
kadira:dochead@1.5.0
|
||||
kadira:flow-router@2.12.1
|
||||
kenton:accounts-sandstorm@0.7.0
|
||||
konecty:mongo-counter@0.0.5_3
|
||||
lamhieu:meteorx@2.1.1
|
||||
lamhieu:unblock@1.0.0
|
||||
launch-screen@1.2.0
|
||||
launch-screen@1.3.0
|
||||
livedata@1.0.18
|
||||
lmieulet:meteor-coverage@1.1.4
|
||||
localstorage@1.2.0
|
||||
logging@1.2.0
|
||||
lucasantoniassi:accounts-lockout@1.0.0
|
||||
matb33:collection-hooks@0.9.1
|
||||
logging@1.3.1
|
||||
matb33:collection-hooks@1.1.2
|
||||
matteodem:easy-search@1.6.4
|
||||
mdg:validation-error@0.5.1
|
||||
meteor@1.9.3
|
||||
meteor-base@1.4.0
|
||||
meteor@1.10.0
|
||||
meteor-autosize@5.0.1
|
||||
meteor-base@1.5.1
|
||||
meteor-platform@1.2.6
|
||||
meteorhacks:aggregate@1.3.0
|
||||
meteorhacks:collection-utils@1.2.0
|
||||
meteorhacks:picker@1.0.3
|
||||
meteorhacks:subs-manager@1.6.4
|
||||
meteorspark:util@0.2.0
|
||||
minifier-css@1.5.3
|
||||
minifier-js@2.6.0
|
||||
meteortesting:browser-tests@1.3.5
|
||||
meteortesting:mocha@2.0.3
|
||||
meteortesting:mocha-core@8.0.1
|
||||
minifier-css@1.6.0
|
||||
minifier-js@2.7.4
|
||||
minifiers@1.1.8-faster-rebuild.0
|
||||
minimongo@1.6.1
|
||||
minimongo@1.8.0
|
||||
mobile-status-bar@1.1.0
|
||||
modern-browsers@0.1.5
|
||||
modules@0.16.0
|
||||
modules-runtime@0.12.0
|
||||
momentjs:moment@2.29.1
|
||||
mongo@1.10.1
|
||||
mongo-decimal@0.1.2
|
||||
modern-browsers@0.1.8
|
||||
modules@0.18.0
|
||||
modules-runtime@0.13.0
|
||||
momentjs:moment@2.29.3
|
||||
mongo@1.15.0
|
||||
mongo-decimal@0.1.3
|
||||
mongo-dev-server@1.1.0
|
||||
mongo-id@1.0.7
|
||||
mongo-id@1.0.8
|
||||
mongo-livedata@1.0.12
|
||||
mousetrap:mousetrap@1.4.6_1
|
||||
mquandalle:autofocus@1.0.0
|
||||
@@ -120,24 +116,27 @@ mquandalle:collection-mutations@0.1.0
|
||||
mquandalle:jade@0.4.9
|
||||
mquandalle:jade-compiler@0.4.5
|
||||
mquandalle:jquery-textcomplete@0.8.0_1
|
||||
mquandalle:jquery-ui-drag-drop-sort@0.2.0
|
||||
mquandalle:moment@1.0.1
|
||||
mquandalle:mousetrap-bindglobal@0.0.1
|
||||
msavin:usercache@1.8.0
|
||||
npm-bcrypt@0.9.3
|
||||
npm-mongo@3.8.1
|
||||
oauth@1.3.2
|
||||
oauth2@1.3.0
|
||||
observe-sequence@1.0.16
|
||||
npm-mongo@4.3.1
|
||||
oauth@2.1.2
|
||||
oauth2@1.3.1
|
||||
observe-sequence@1.0.20
|
||||
ongoworks:speakingurl@1.1.0
|
||||
ordered-dict@1.1.0
|
||||
ostrio:cookies@2.7.0
|
||||
ostrio:cstorage@2.2.2
|
||||
ostrio:files@2.0.1
|
||||
ostrio:i18n@3.1.0
|
||||
pascoual:pdfkit@1.0.7
|
||||
peerlibrary:assert@0.3.0
|
||||
peerlibrary:base-component@0.16.0
|
||||
peerlibrary:blaze-components@0.15.1
|
||||
peerlibrary:base-component@0.17.1
|
||||
peerlibrary:blaze-components@0.23.0
|
||||
peerlibrary:computed-field@0.10.0
|
||||
peerlibrary:data-lookup@0.3.0
|
||||
peerlibrary:reactive-field@0.6.0
|
||||
percolate:synced-cron@1.3.2
|
||||
promise@0.11.2
|
||||
promise@0.12.0
|
||||
raix:eventemitter@0.1.3
|
||||
raix:handlebar-helpers@0.2.5
|
||||
rajit:bootstrap3-datepicker@1.7.1_1
|
||||
@@ -191,53 +190,46 @@ rajit:bootstrap3-datepicker-zh-cn@1.7.1
|
||||
rajit:bootstrap3-datepicker-zh-tw@1.7.1
|
||||
random@1.2.0
|
||||
rate-limit@1.0.9
|
||||
react-fast-refresh@0.1.0
|
||||
react-fast-refresh@0.2.3
|
||||
reactive-dict@1.3.0
|
||||
reactive-var@1.0.11
|
||||
reload@1.3.1
|
||||
retry@1.1.0
|
||||
routepolicy@1.1.0
|
||||
routepolicy@1.1.1
|
||||
rzymek:fullcalendar@3.8.0
|
||||
server-render@0.3.1
|
||||
service-configuration@1.0.11
|
||||
service-configuration@1.3.0
|
||||
session@1.2.0
|
||||
sha@1.0.9
|
||||
shell-server@0.5.0
|
||||
simple:authenticate-user-by-token@1.0.1
|
||||
simple:json-routes@2.1.0
|
||||
simple:rest-accounts-password@1.1.2
|
||||
simple:rest-bearer-token-parser@1.0.1
|
||||
simple:rest-json-error-handler@1.0.1
|
||||
socket-stream-client@0.3.1
|
||||
softwarerero:accounts-t9n@1.3.11
|
||||
spacebars@1.0.15
|
||||
spacebars-compiler@1.1.3
|
||||
srp@1.1.0
|
||||
standard-minifier-css@1.7.2
|
||||
standard-minifier-js@2.6.0
|
||||
staringatlights:fast-render@3.3.0
|
||||
staringatlights:inject-data@2.3.0
|
||||
steffo:meteor-accounts-saml@0.0.18
|
||||
tap:i18n@1.8.2
|
||||
simple:authenticate-user-by-token@1.2.1
|
||||
simple:json-routes@2.3.1
|
||||
simple:rest-accounts-password@1.2.1
|
||||
simple:rest-bearer-token-parser@1.1.1
|
||||
simple:rest-json-error-handler@1.1.1
|
||||
socket-stream-client@0.5.0
|
||||
spacebars@1.3.0
|
||||
spacebars-compiler@1.3.1
|
||||
standard-minifier-css@1.8.1
|
||||
standard-minifier-js@2.8.0
|
||||
templates:tabs@2.3.0
|
||||
templating@1.3.2
|
||||
templating-compiler@1.3.3
|
||||
templating-runtime@1.3.2
|
||||
templating-tools@1.1.2
|
||||
tmeasday:check-npm-versions@0.3.2
|
||||
templating@1.4.1
|
||||
templating-compiler@1.4.1
|
||||
templating-runtime@1.5.0
|
||||
templating-tools@1.2.2
|
||||
tracker@1.2.0
|
||||
twbs:bootstrap@3.3.6
|
||||
ui@1.0.13
|
||||
underscore@1.0.10
|
||||
url@1.3.1
|
||||
useraccounts:core@1.14.2
|
||||
useraccounts:flow-routing@1.14.2
|
||||
url@1.3.2
|
||||
useraccounts:core@1.16.2
|
||||
useraccounts:flow-routing@1.15.0
|
||||
useraccounts:unstyled@1.14.2
|
||||
verron:autosize@3.0.8
|
||||
webapp@1.10.0
|
||||
webapp@1.13.1
|
||||
webapp-hashing@1.1.0
|
||||
wekan-accounts-cas@0.1.0
|
||||
wekan-accounts-lockout@1.0.0
|
||||
wekan-accounts-oidc@1.0.10
|
||||
wekan-accounts-sandstorm@0.8.0
|
||||
wekan-ldap@0.0.2
|
||||
wekan-markdown@1.0.9
|
||||
wekan-oidc@1.0.12
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ sudo: required
|
||||
|
||||
env:
|
||||
TRAVIS_DOCKER_COMPOSE_VERSION: 1.24.0
|
||||
TRAVIS_NODE_VERSION: 12.22.0
|
||||
TRAVIS_NODE_VERSION: 14.19.2
|
||||
TRAVIS_NPM_VERSION: latest
|
||||
|
||||
before_install:
|
||||
|
||||
+2
-2
@@ -39,10 +39,10 @@ host = https://www.transifex.com
|
||||
# tap:i18n requires us to use `-` separator in the language identifiers whereas
|
||||
# Transifex uses a `_` separator, without an option to customize it on one side
|
||||
# or the other, so we need to do a Manual mapping.
|
||||
lang_map = ar_EG:ar-EG, bg_BG:bg, en_GB:en-GB, es_AR:es-AR, es_CL:es-CL, es_419:es-LA, es_PE:es-PE, es_MX:es-MX, es_TX:es-TX, es_PY:es-PY, el_GR:el, fa_IR:fa-IR, fi_FI:fi, hu_HU:hu, id_ID:id, mn_MN:mn, no:nb, lv_LV:lv, pt_BR:pt-BR, ro_RO:ro, sl_SI:sl, zh_CN:zh-CN, zh_TW:zh-TW, zh_HK:zh-HK
|
||||
lang_map = ar_EG:ar-EG, bg_BG:bg, cs_CZ:cs-CZ, cy_GB:cy-GB, de_AT:de-AT, de_CH:de-CH, en_BR:en-BR, en_DE:en-DE, en_IT:en-IT, en_GB:en-GB, et_EE:et-EE, es_AR:es-AR, en@ysv:en-YS, es_CL:es-CL, es_419:es-LA, es_PE:es-PE, es_MX:es-MX, es_TX:es-TX, es_PY:es-PY, el_GR:el-GR, fa_IR:fa-IR, fi_FI:fi, fr_FR:fr-FR, fr_CH:fr-CH, fy_NL:fy-NL, gl_ES:gl-ES, gu_IN:gu-IN, he_IL:he-IL, hi_IN:hi-IN, hu_HU:hu, id_ID:id, mn_MN:mn, ms_MY:ms-MY, nl_NL:nl-NL, ko_KR:ko-KR, lv_LV:lv, pl_PL:pl-PL, pt_BR:pt-BR, ro_RO:ro, ru_UA:ru-UA, sl_SI:sl, uk_UA:uk-UA, uz@Arab:uz-AR, uz@Latn:uz-LA, uz_UZ:uz-UZ, vec:ve-CC, vep:ve-PP, vls:vl-SS, war:wa-RR, vi_VN:vi-VN, zh_CN:zh-CN, zh_TW:zh-TW, zh_Hans:zh-Hans, zh_HK:zh-HK, zu_ZA:zu-ZA
|
||||
|
||||
[wekan.application]
|
||||
file_filter = i18n/<lang>.i18n.json
|
||||
file_filter = imports/i18n/data/<lang>.i18n.json
|
||||
source_lang = en
|
||||
type = KEYVALUEJSON
|
||||
|
||||
|
||||
Vendored
+17
@@ -17,6 +17,23 @@
|
||||
"outputCapture": "std",
|
||||
"port": 9229,
|
||||
"timeout": 60000
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Test: Node",
|
||||
"runtimeExecutable": "meteor",
|
||||
"runtimeArgs": [
|
||||
"test",
|
||||
"--inspect-brk=9229",
|
||||
"--port=4040",
|
||||
"--exclude-archs=web.browser.legacy,web.cordova",
|
||||
"--driver-package=meteortesting:mocha",
|
||||
"--settings=settings.json"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"port": 9229,
|
||||
"timeout": 60000
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
|
||||
+2092
-3
File diff suppressed because it is too large.
Load diff
+43
-13
@@ -1,8 +1,12 @@
|
||||
FROM quay.io/wekan/ubuntu:groovy-20210115
|
||||
FROM ubuntu:21.10
|
||||
LABEL maintainer="wekan"
|
||||
|
||||
# 2020-12-03:
|
||||
# - Above Ubuntu base image copied from Docker Hub ubuntu:groovy-20201125.2
|
||||
# 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.
|
||||
|
||||
# Set the environment variables (defaults where required)
|
||||
@@ -12,7 +16,7 @@ ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-essential git ca-certificates python3" \
|
||||
DEBUG=false \
|
||||
NODE_VERSION=v12.22.0 \
|
||||
NODE_VERSION=v14.19.2 \
|
||||
METEOR_RELEASE=1.10.2 \
|
||||
USE_EDGE=false \
|
||||
METEOR_EDGE=1.5-beta.17 \
|
||||
@@ -28,9 +32,9 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURES_BERORE=3 \
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_LOCKOUT_PERIOD=60 \
|
||||
ACCOUNTS_LOCKOUT_UNKNOWN_USERS_FAILURE_WINDOW=15 \
|
||||
ACCOUNTS_COMMON_LOGIN_EXPIRATION_IN_DAYS=90 \
|
||||
RICHER_CARD_COMMENT_EDITOR=false \
|
||||
CARD_OPENED_WEBHOOK_ENABLED=false \
|
||||
ATTACHMENTS_STORE_PATH="" \
|
||||
MAX_IMAGE_PIXEL="" \
|
||||
IMAGE_COMPRESS_RATIO="" \
|
||||
NOTIFICATION_TRAY_AFTER_READ_DAYS_BEFORE_REMOVE="" \
|
||||
@@ -64,6 +68,9 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
|
||||
LDAP_ENABLE=false \
|
||||
LDAP_PORT=389 \
|
||||
LDAP_HOST="" \
|
||||
LDAP_AD_SIMPLE_AUTH="" \
|
||||
LDAP_USER_AUTHENTICATION=false \
|
||||
LDAP_USER_AUTHENTICATION_FIELD=uid \
|
||||
LDAP_BASEDN="" \
|
||||
LDAP_LOGIN_FALLBACK=false \
|
||||
LDAP_RECONNECT=true \
|
||||
@@ -81,8 +88,6 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
|
||||
LDAP_ENCRYPTION=false \
|
||||
LDAP_CA_CERT="" \
|
||||
LDAP_REJECT_UNAUTHORIZED=false \
|
||||
LDAP_USER_AUTHENTICATION=false \
|
||||
LDAP_USER_AUTHENTICATION_FIELD=uid \
|
||||
LDAP_USER_SEARCH_FILTER="" \
|
||||
LDAP_USER_SEARCH_SCOPE="" \
|
||||
LDAP_USER_SEARCH_FIELD="" \
|
||||
@@ -137,7 +142,18 @@ ENV BUILD_DEPS="apt-utils libarchive-tools gnupg gosu wget curl bzip2 g++ build-
|
||||
SAML_IDENTIFIER_FORMAT="" \
|
||||
SAML_LOCAL_PROFILE_MATCH_ATTRIBUTE="" \
|
||||
SAML_ATTRIBUTES="" \
|
||||
ORACLE_OIM_ENABLED=false
|
||||
ORACLE_OIM_ENABLED=false \
|
||||
WAIT_SPINNER="" \
|
||||
NODE_OPTIONS="--max_old_space_size=4096" \
|
||||
WRITABLE_PATH=/data
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# 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"
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
# Copy the app to the image
|
||||
COPY ${SRC_PATH} /home/wekan/app
|
||||
@@ -205,7 +221,7 @@ RUN \
|
||||
mv node-${NODE_VERSION}-${ARCHITECTURE} /opt/nodejs && \
|
||||
ln -s /opt/nodejs/bin/node /usr/bin/node && \
|
||||
ln -s /opt/nodejs/bin/npm /usr/bin/npm && \
|
||||
mkdir -p /opt/nodejs/lib/node_modules/fibers/.node-gyp /root/.node-gyp/8.16.1 /home/wekan/.config && \
|
||||
mkdir -p /opt/nodejs/lib/node_modules/fibers/.node-gyp /root/.node-gyp/${NODE_VERSION} /home/wekan/.config && \
|
||||
chown wekan --recursive /home/wekan/.config && \
|
||||
\
|
||||
#DOES NOT WORK: paxctl fix for alpine linux: https://github.com/wekan/wekan/issues/1303
|
||||
@@ -278,9 +294,7 @@ RUN \
|
||||
chmod u+w *.json && \
|
||||
gosu wekan:wekan npm install && \
|
||||
gosu wekan:wekan /home/wekan/.meteor/meteor build --directory /home/wekan/app_build && \
|
||||
#cp /home/wekan/app/fix-download-unicode/cfs_access-point.txt /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
|
||||
#rm /home/wekan/app_build/bundle/programs/server/npm/node_modules/meteor/rajit_bootstrap3-datepicker/lib/bootstrap-datepicker/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs && \
|
||||
#chown wekan /home/wekan/app_build/bundle/programs/server/packages/cfs_access-point.js && \
|
||||
#Removed binary version of bcrypt because of security vulnerability that is not fixed yet.
|
||||
#https://github.com/wekan/wekan/commit/4b2010213907c61b0e0482ab55abb06f6a668eac
|
||||
#https://github.com/wekan/wekan/commit/7eeabf14be3c63fae2226e561ef8a0c1390c8d3c
|
||||
@@ -295,6 +309,9 @@ RUN \
|
||||
cd /home/wekan/app_build/bundle/programs/server/ && \
|
||||
chmod u+w *.json && \
|
||||
gosu wekan:wekan npm install && \
|
||||
cd node_modules/fibers && \
|
||||
node build.js && \
|
||||
cd ../.. && \
|
||||
#gosu wekan:wekan npm install bcrypt && \
|
||||
# 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 && \
|
||||
@@ -307,10 +324,13 @@ RUN \
|
||||
apt-get remove --purge -y ${BUILD_DEPS} && \
|
||||
apt-get autoremove -y && \
|
||||
npm uninstall -g api2html &&\
|
||||
rm -R /tmp/* && \
|
||||
rm -R /var/lib/apt/lists/* && \
|
||||
rm -R /home/wekan/.meteor && \
|
||||
rm -R /home/wekan/app && \
|
||||
rm -R /home/wekan/app_build
|
||||
rm -R /home/wekan/app_build && \
|
||||
mkdir /data && \
|
||||
chown wekan --recursive /data
|
||||
#cat /home/wekan/python/esprima-python/files.txt | xargs rm -R && \
|
||||
#rm -R /home/wekan/python
|
||||
#rm /home/wekan/install_meteor.sh
|
||||
@@ -319,4 +339,14 @@ ENV PORT=8080
|
||||
EXPOSE $PORT
|
||||
USER wekan
|
||||
|
||||
CMD ["node", "/build/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"]
|
||||
+31
-11
@@ -4,16 +4,25 @@ FROM amd64/alpine:3.7 AS builder
|
||||
ENV QEMU_VERSION=v4.2.0-6 \
|
||||
QEMU_ARCHITECTURE=aarch64 \
|
||||
NODE_ARCHITECTURE=linux-arm64 \
|
||||
NODE_VERSION=v12.22.0 \
|
||||
WEKAN_VERSION=3.96 \
|
||||
WEKAN_ARCHITECTURE=arm64
|
||||
NODE_VERSION=v14.19.2 \
|
||||
WEKAN_VERSION=latest \
|
||||
WEKAN_ARCHITECTURE=arm64 \
|
||||
NODE_OPTIONS="--max_old_space_size=4096"
|
||||
|
||||
# Install dependencies
|
||||
RUN apk update && apk add ca-certificates outils-sha1 && \
|
||||
\
|
||||
# Download qemu static for our architecture
|
||||
wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_VERSION}/qemu-${QEMU_ARCHITECTURE}-static.tar.gz -O - | tar -xz && \
|
||||
\
|
||||
#---------------------------------------------------------------------
|
||||
# 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"
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
# Install dependencies
|
||||
RUN apk update && apk add ca-certificates outils-sha1 && \
|
||||
\
|
||||
# Download qemu static for our architecture
|
||||
wget https://github.com/multiarch/qemu-user-static/releases/download/${QEMU_VERSION}/qemu-${QEMU_ARCHITECTURE}-static.tar.gz -O - | tar -xz && \
|
||||
\
|
||||
# Download wekan and shasum
|
||||
wget https://releases.wekan.team/raspi3/wekan-${WEKAN_VERSION}-${WEKAN_ARCHITECTURE}.zip && \
|
||||
wget https://releases.wekan.team/raspi3/SHA256SUMS.txt && \
|
||||
@@ -40,7 +49,7 @@ LABEL maintainer="wekan"
|
||||
# Set the environment variables (defaults where required)
|
||||
ENV QEMU_ARCHITECTURE=aarch64 \
|
||||
NODE_ARCHITECTURE=linux-arm64 \
|
||||
NODE_VERSION=v12.22.0 \
|
||||
NODE_VERSION=v14.19.2 \
|
||||
NODE_ENV=production \
|
||||
NPM_VERSION=latest \
|
||||
WITH_API=true \
|
||||
@@ -74,4 +83,15 @@ RUN \
|
||||
EXPOSE $PORT
|
||||
USER wekan
|
||||
|
||||
CMD ["node", "/home/wekan/bundle/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", "/home/wekan/bundle/main.js"]
|
||||
|
||||
CMD ["bash", "-c", "ulimit -s 65500; exec node --stack-size=65500 /home/wekan/bundle/main.js"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[](https://gitpod.io/#https://github.com/wekan/wekan)
|
||||
|
||||
# Wekan - Open Source kanban
|
||||
# WeKan ® - Open Source kanban
|
||||
|
||||
[](https://github.com/wekan/wekan/graphs/contributors)
|
||||
[](https://quay.io/repository/wekan/wekan)
|
||||
@@ -14,31 +14,36 @@
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fwekan%2Fwekan?ref=badge_shield)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/4619)
|
||||
|
||||
## [Translate Wekan at Transifex](https://transifex.com/wekan/wekan)
|
||||
## [Translate WeKan ® at Transifex](https://transifex.com/wekan/wekan)
|
||||
|
||||
Translations to non-English languages are accepted only at [Transifex](https://transifex.com/wekan/wekan) using webbrowser.
|
||||
New English strings of new features can be added as PRs to edge branch file wekan/i18n/en.i18n.json .
|
||||
|
||||
## [Wekan feature requests and bugs](https://github.com/wekan/wekan/issues)
|
||||
|
||||
Please add most of your questions as GitHub issue: [Wekan Feature Requests and Bugs](https://github.com/wekan/wekan/issues).
|
||||
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] - Wekan Community GitHub Discussions, that are not [Feature Requests and Bugs](https://github.com/wekan/wekan/issues).
|
||||
[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)
|
||||
|
||||
## Docker: Please only use Docker release tags
|
||||
|
||||
Note: With Docker, please don't use latest tag. Only use release tags.
|
||||
See 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 :)
|
||||
|
||||
## About Wekan
|
||||
## About WeKan ®
|
||||
|
||||
Wekan is an completely [Open Source][open_source] and [Free software][free_software]
|
||||
WeKan ® is an completely [Open Source][open_source] and [Free software][free_software]
|
||||
collaborative kanban board application with MIT license.
|
||||
|
||||
Whether you’re maintaining a personal todo list, planning your holidays with some friends,
|
||||
@@ -46,58 +51,58 @@ or working in a team on your next revolutionary idea, Kanban boards are an unbea
|
||||
to keep your things organized. They give you a visual overview of the current state of your project,
|
||||
and make you productive by allowing you to focus on the few items that matter the most.
|
||||
|
||||
Since Wekan is a free software, you don’t have to trust us with your data and can
|
||||
Since WeKan ® is a free software, you don’t have to trust us with your data and can
|
||||
install Wekan on your own computer or server. In fact we encourage you to do
|
||||
that by providing one-click installation on various platforms.
|
||||
|
||||
- Wekan is used in [most countries of the world](https://snapcraft.io/wekan).
|
||||
- Wekan largest user has 13k users using Wekan in their company.
|
||||
- Wekan has been [translated](https://transifex.com/wekan/wekan) to about 62 languages.
|
||||
- [Features][features]: Wekan has real-time user interface.
|
||||
- [Platforms][platforms]: Wekan supports many platforms.
|
||||
Wekan is critical part of new platforms Wekan is currently being integrated to.
|
||||
- WeKan ® is used in [most countries of the world](https://snapcraft.io/wekan).
|
||||
- Wekan largest user has 22k users using Wekan in their company.
|
||||
- Wekan has been [translated](https://transifex.com/wekan/wekan) to about 105 languages.
|
||||
- [Features][features]: WeKan ® has real-time user interface.
|
||||
- [Platforms][platforms]: WeKan ® supports many platforms.
|
||||
WeKan ® is critical part of new platforms Wekan is currently being integrated to.
|
||||
|
||||
## 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.
|
||||
- 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/master/docker-compose.yml): 3 frontend servers,
|
||||
each having 2 CPU and 2 wekan-app containers. One backend wekan-db server with many CPUs.
|
||||
- Enough disk space and alerts about low disk space. If you run out disk space, MongoDB database gets corrupted.
|
||||
- SECURITY: Updating to newest Wekan version very often. Please check you do not have automatic updates of Sandstorm or Snap turned off.
|
||||
Old versions have security issues because of old versions Node.js etc. Only newest Wekan is supported.
|
||||
Wekan on Sandstorm is not usually affected by any Standalone Wekan (Snap/Docker/Source) security issues.
|
||||
- SECURITY: Updating to newest WeKan ® version very often. Please check you do not have automatic updates of Sandstorm or Snap turned off.
|
||||
Old versions have security issues because of old versions Node.js etc. Only newest WeKan ® is supported.
|
||||
WeKan ® on Sandstorm is not usually affected by any Standalone WeKan ® (Snap/Docker/Source) security issues.
|
||||
- [Reporting all new bugs immediately](https://github.com/wekan/wekan/issues).
|
||||
New features and fixes are added to Wekan [many times a day](https://github.com/wekan/wekan/blob/devel/CHANGELOG.md).
|
||||
- [Backups](https://github.com/wekan/wekan/wiki/Backup) of Wekan database once a day miminum.
|
||||
New features and fixes are added to WeKan ® [many times a day](https://github.com/wekan/wekan/blob/master/CHANGELOG.md).
|
||||
- [Backups](https://github.com/wekan/wekan/wiki/Backup) of WeKan ® database once a day miminum.
|
||||
Bugs, updates, users deleting list or card, harddrive full, harddrive crash etc can eat your data. There is no undo yet.
|
||||
Some bug can cause Wekan board to not load at all, requiring manual fixing of database content.
|
||||
Some bug can cause WeKan ® board to not load at all, requiring manual fixing of database content.
|
||||
|
||||
## Roadmap and Demo
|
||||
|
||||
[Roadmap][roadmap_wekan] - Public read-only board at Wekan demo.
|
||||
[Roadmap][roadmap_wekan] - Public read-only board at WeKan ® demo.
|
||||
|
||||
[Developer Documentation][dev_docs]
|
||||
|
||||
- There is many companies and individuals contributing code to Wekan, to add features and bugfixes
|
||||
[many times a day](https://github.com/wekan/wekan/blob/devel/CHANGELOG.md).
|
||||
- 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/master/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/).
|
||||
|
||||
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.
|
||||
By working directly with WeKan ® you get the benefit of active maintenance and new features added by growing WeKan ® developer community.
|
||||
|
||||
## Screenshot
|
||||
|
||||
[More screenshots at Features page](https://github.com/wekan/wekan/wiki/Features)
|
||||
|
||||
[![Screenshot of Wekan][screenshot_wekan]][roadmap_wekan]
|
||||
[![Screenshot of WeKan ®][screenshot_wekan]][roadmap_wekan]
|
||||
|
||||
## License
|
||||
|
||||
Wekan is released under the very permissive [MIT license](LICENSE), and made
|
||||
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
|
||||
|
||||
+4
-4
@@ -51,8 +51,8 @@ This also means all Standalone Wekan functionality works in offline local networ
|
||||
Wekan is used by companies that have [thousands of users](https://github.com/wekan/wekan/wiki/AWS) and at healthcare.
|
||||
|
||||
Wekan uses xss package for input fields like cards, as you can see from
|
||||
[package.json](https://github.com/wekan/wekan/blob/devel/package.json). Other used versions can be seen from
|
||||
[Meteor versions file](https://github.com/wekan/wekan/blob/devel/.meteor/versions).
|
||||
[package.json](https://github.com/wekan/wekan/blob/master/package.json). Other used versions can be seen from
|
||||
[Meteor versions file](https://github.com/wekan/wekan/blob/master/.meteor/versions).
|
||||
Forms can include markdown links, html, image tags etc like you see at https://wekan.github.io .
|
||||
It's possible to add attachments to cards, and markdown/html links to files.
|
||||
|
||||
@@ -69,7 +69,7 @@ access to outside of Wekan grain.
|
||||
Standalone Wekan only has password auth currently, there is work in progress to add
|
||||
[oauth2](https://github.com/wekan/wekan/pull/1578), [Openid](https://github.com/wekan/wekan/issues/538),
|
||||
[LDAP](https://github.com/wekan/wekan/issues/119) etc. If you need more login security for Standalone Wekan now,
|
||||
it's possible add additional [Google Auth proxybouncer](https://github.com/wekan/wekan/wiki/Let's-Encrypt-and-Google-Auth) in front of password auth, and then use Google Authenticator for Google Auth. Standalone Wekan does have [brute force protection with eluck:accounts-lockout and browser-policy clickjacking protection](https://github.com/wekan/wekan/blob/devel/CHANGELOG.md#v080-2018-04-04-wekan-release). You can also optionally use some [WAF](https://en.wikipedia.org/wiki/Web_application_firewall)
|
||||
it's possible add additional [Google Auth proxybouncer](https://github.com/wekan/wekan/wiki/Let's-Encrypt-and-Google-Auth) in front of password auth, and then use Google Authenticator for Google Auth. Standalone Wekan does have [brute force protection with eluck:accounts-lockout and browser-policy clickjacking protection](https://github.com/wekan/wekan/blob/master/CHANGELOG.md#v080-2018-04-04-wekan-release). You can also optionally use some [WAF](https://en.wikipedia.org/wiki/Web_application_firewall)
|
||||
like for example [AWS WAF](https://aws.amazon.com/waf/).
|
||||
|
||||
[All Wekan Platforms](https://github.com/wekan/wekan/wiki/Platforms)
|
||||
@@ -106,7 +106,7 @@ a security issue, we'd like to know about it, and also how to fix it:
|
||||
Typical already known or "no impact" bugs such as:
|
||||
|
||||
- Brute force password guessign. Currently there is
|
||||
[brute force protection with eluck:accounts-lockout](https://github.com/wekan/wekan/blob/devel/CHANGELOG.md#v080-2018-04-04-wekan-release).
|
||||
[brute force protection with eluck:accounts-lockout](https://github.com/wekan/wekan/blob/master/CHANGELOG.md#v080-2018-04-04-wekan-release).
|
||||
- Security issues related to that Wekan uses Meteor 1.6.0.1 related packages, and upgrading to newer
|
||||
Meteor 1.6.1 is complicated process that requires lots of changes to many dependency packages.
|
||||
Upgrading [has been tried many times, spending a lot of time](https://github.com/meteor/meteor/issues/9609)
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v5.17.0"
|
||||
appVersion: "v6.25.0"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
# Wekan API Python CLI, originally from here, where is more details:
|
||||
# https://github.com/wekan/wekan/wiki/New-card-with-Python3-and-REST-API
|
||||
|
||||
# TODO:
|
||||
# addcustomfieldtoboard: There is error: Settings must be object. So adding does not work yet.
|
||||
|
||||
try:
|
||||
# python 3
|
||||
from urllib.parse import urlencode
|
||||
@@ -23,17 +26,25 @@ if arguments == 0:
|
||||
print("AUTHORID is USERID that writes card.")
|
||||
print("If *nix: chmod +x api.py => ./api.py users")
|
||||
print("Syntax:")
|
||||
print(" python3 api.py users # All users")
|
||||
print(" python3 api.py boards USERID # Boards of USERID")
|
||||
print(" python3 api.py board BOARDID # Info of BOARDID")
|
||||
print(" python3 api.py swimlanes BOARDID # Swimlanes of BOARDID")
|
||||
print(" python3 api.py lists BOARDID # Lists of BOARDID")
|
||||
print(" python3 api.py users # All users")
|
||||
print(" python3 api.py boards # All Public Boards")
|
||||
print(" python3 api.py boards USERID # Boards of USERID")
|
||||
print(" python3 api.py board BOARDID # Info of BOARDID")
|
||||
print(" python3 api.py customfields BOARDID # Custom Fields of BOARDID")
|
||||
print(" python3 api.py customfield BOARDID CUSTOMFIELDID # Info of CUSTOMFIELDID")
|
||||
print(" python3 api.py addcustomfieldtoboard AUTHORID BOARDID NAME TYPE SETTINGS SHOWONCARD AUTOMATICALLYONCARD SHOWLABELONMINICARD SHOWSUMATTOPOFLIST # Add Custom Field to Board")
|
||||
print(" python3 api.py swimlanes BOARDID # Swimlanes of BOARDID")
|
||||
print(" python3 api.py lists BOARDID # Lists of BOARDID")
|
||||
print(" python3 api.py list BOARDID LISTID # Info of LISTID")
|
||||
print(" python3 api.py createlist BOARDID LISTTITLE # Create list")
|
||||
print(" python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION")
|
||||
print(" python3 api.py editcard BOARDID LISTID CARDID NEWCARDTITLE NEWCARDDESCRIPTION")
|
||||
print(" python3 api.py listattachments BOARDID # List attachments")
|
||||
# TODO:
|
||||
# print(" python3 api.py attachmentdownload BOARDID ATTACHMENTID # One attachment as file")
|
||||
# print(" python3 api.py attachmentsdownload BOARDID # All attachments as files")
|
||||
# print(" python3 api.py attachmentjson BOARDID ATTACHMENTID # One attachment as JSON base64")
|
||||
# print(" python3 api.py attachmentbinary BOARDID ATTACHMENTID # One attachment as binary file")
|
||||
# print(" python3 api.py attachmentdownload BOARDID ATTACHMENTID # One attachment as file")
|
||||
# print(" python3 api.py attachmentsdownload BOARDID # All attachments as files")
|
||||
exit
|
||||
|
||||
# ------- SETTINGS START -------------
|
||||
@@ -61,17 +72,29 @@ chmod +x api.py
|
||||
=== Wekan API Python CLI: Shows IDs for addcard ===
|
||||
AUTHORID is USERID that writes card.
|
||||
Syntax:
|
||||
python3 api.py users # All users
|
||||
python3 api.py boards USERID # Boards of USERID
|
||||
python3 api.py board BOARDID # Info of BOARDID
|
||||
python3 api.py swimlanes BOARDID # Swimlanes of BOARDID
|
||||
python3 api.py lists BOARDID # Lists of BOARDID
|
||||
python3 api.py users # All users
|
||||
python3 api.py boards USERID # Boards of USERID
|
||||
python3 api.py board BOARDID # Info of BOARDID
|
||||
python3 api.py customfields BOARDID # Custom Fields of BOARDID
|
||||
python3 api.py customfield BOARDID CUSTOMFIELDID # Info of CUSTOMFIELDID
|
||||
python3 api.py addcustomfieldtoboard AUTHORID BOARDID NAME TYPE SETTINGS SHOWONCARD AUTOMATICALLYONCARD SHOWLABELONMINICARD SHOWSUMATTOPOFLIST # Add Custom Field to Board
|
||||
python3 api.py swimlanes BOARDID # Swimlanes of BOARDID
|
||||
python3 api.py lists BOARDID # Lists of BOARDID
|
||||
python3 api.py list BOARDID LISTID # Info of LISTID
|
||||
python3 api.py createlist BOARDID LISTTITLE # Create list
|
||||
python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION
|
||||
python3 api.py editcard BOARDID LISTID CARDID NEWCARDTITLE NEWCARDDESCRIPTION
|
||||
python3 api.py listattachments BOARDID # List attachments
|
||||
python3 api.py attachmentjson BOARDID ATTACHMENTID # One attachment as JSON base64
|
||||
python3 api.py attachmentbinary BOARDID ATTACHMENTID # One attachment as binary file
|
||||
|
||||
=== ADD CUSTOM FIELD TO BOARD ===
|
||||
|
||||
Type: text, number, date, dropdown, checkbox, currency, stringtemplate.
|
||||
|
||||
python3 api.py addcustomfieldtoboard cmx3gmHLKwAXLqjxz LcDW4QdooAx8hsZh8 "SomeField" "date" "" true true true true
|
||||
|
||||
|
||||
=== USERS ===
|
||||
|
||||
python3 api.py users
|
||||
@@ -127,6 +150,7 @@ l = 'lists'
|
||||
sw = 'swimlane'
|
||||
sws = 'swimlanes'
|
||||
cs = 'cards'
|
||||
cf = 'custom-fields'
|
||||
bs = 'boards'
|
||||
atl = 'attachmentslist'
|
||||
at = 'attachment'
|
||||
@@ -144,10 +168,34 @@ apikey = d['token']
|
||||
|
||||
# ------- LOGIN TOKEN END -----------
|
||||
|
||||
if arguments == 10:
|
||||
|
||||
if sys.argv[1] == 'addcustomfieldtoboard':
|
||||
# ------- ADD CUSTOM FIELD TO BOARD START -----------
|
||||
authorid = sys.argv[2]
|
||||
boardid = sys.argv[3]
|
||||
name = sys.argv[4]
|
||||
type1 = sys.argv[5]
|
||||
settings = str(json.loads(sys.argv[6]))
|
||||
# There is error: Settings must be object. So this does not work yet.
|
||||
#settings = {'currencyCode': 'EUR'}
|
||||
print(type(settings))
|
||||
showoncard = sys.argv[7]
|
||||
automaticallyoncard = sys.argv[8]
|
||||
showlabelonminicard = sys.argv[9]
|
||||
showsumattopoflist = sys.argv[10]
|
||||
customfieldtoboard = wekanurl + apiboards + boardid + s + cf
|
||||
# Add Custom Field to Board
|
||||
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
|
||||
post_data = {'authorId': '{}'.format(authorid), 'name': '{}'.format(name), 'type': '{}'.format(type1), 'settings': '{}'.format(settings), 'showoncard': '{}'.format(showoncard), 'automaticallyoncard': '{}'.format(automaticallyoncard), 'showlabelonminicard': '{}'.format(showlabelonminicard), 'showsumattopoflist': '{}'.format(showsumattopoflist)}
|
||||
body = requests.post(customfieldtoboard, data=post_data, headers=headers)
|
||||
print(body.text)
|
||||
# ------- ADD CUSTOM FIELD TO BOARD END -----------
|
||||
|
||||
if arguments == 7:
|
||||
|
||||
if sys.argv[1] == 'addcard':
|
||||
# ------- WRITE TO CARD START -----------
|
||||
# ------- ADD CARD START -----------
|
||||
authorid = sys.argv[2]
|
||||
boardid = sys.argv[3]
|
||||
swimlaneid = sys.argv[4]
|
||||
@@ -155,12 +203,33 @@ if arguments == 7:
|
||||
cardtitle = sys.argv[6]
|
||||
carddescription = sys.argv[7]
|
||||
cardtolist = wekanurl + apiboards + boardid + s + l + s + listid + s + cs
|
||||
# Write to card
|
||||
# Add card
|
||||
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
|
||||
post_data = {'authorId': '{}'.format(authorid), 'title': '{}'.format(cardtitle), 'description': '{}'.format(carddescription), 'swimlaneId': '{}'.format(swimlaneid)}
|
||||
body = requests.post(cardtolist, data=post_data, headers=headers)
|
||||
print(body.text)
|
||||
# ------- WRITE TO CARD END -----------
|
||||
# ------- ADD CARD END -----------
|
||||
|
||||
if arguments == 6:
|
||||
|
||||
if sys.argv[1] == 'editcard':
|
||||
|
||||
# ------- EDIT CARD START -----------
|
||||
boardid = sys.argv[2]
|
||||
listid = sys.argv[3]
|
||||
cardid = sys.argv[4]
|
||||
newcardtitle = sys.argv[5]
|
||||
newcarddescription = sys.argv[6]
|
||||
edcard = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid
|
||||
print(edcard)
|
||||
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
|
||||
put_data = {'title': '{}'.format(newcardtitle), 'description': '{}'.format(newcarddescription)}
|
||||
body = requests.put(edcard, data=put_data, headers=headers)
|
||||
print("=== EDIT CARD ===\n")
|
||||
body = requests.get(edcard, headers=headers)
|
||||
data2 = body.text.replace('}',"}\n")
|
||||
print(data2)
|
||||
# ------- EDIT CARD END -----------
|
||||
|
||||
if arguments == 3:
|
||||
|
||||
@@ -177,6 +246,32 @@ if arguments == 3:
|
||||
print(body.text)
|
||||
# ------- CREATE LIST END -----------
|
||||
|
||||
if sys.argv[1] == 'list':
|
||||
|
||||
# ------- LIST OF BOARD START -----------
|
||||
boardid = sys.argv[2]
|
||||
listid = sys.argv[3]
|
||||
listone = wekanurl + apiboards + boardid + s + l + s + listid
|
||||
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
|
||||
print("=== INFO OF ONE LIST ===\n")
|
||||
body = requests.get(listone, headers=headers)
|
||||
data2 = body.text.replace('}',"}\n")
|
||||
print(data2)
|
||||
# ------- LISTS OF BOARD END -----------
|
||||
|
||||
if sys.argv[1] == 'customfield':
|
||||
|
||||
# ------- INFO OF CUSTOM FIELD START -----------
|
||||
boardid = sys.argv[2]
|
||||
customfieldid = sys.argv[3]
|
||||
customfieldone = wekanurl + apiboards + boardid + s + cf + s + customfieldid
|
||||
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
|
||||
print("=== INFO OF ONE CUSTOM FIELD ===\n")
|
||||
body = requests.get(customfieldone, headers=headers)
|
||||
data2 = body.text.replace('}',"}\n")
|
||||
print(data2)
|
||||
# ------- INFO OF CUSTOM FIELD END -----------
|
||||
|
||||
if arguments == 2:
|
||||
|
||||
# ------- BOARDS LIST START -----------
|
||||
@@ -190,8 +285,8 @@ if arguments == 2:
|
||||
data2 = body.text.replace('}',"}\n")
|
||||
print(data2)
|
||||
# ------- BOARDS LIST END -----------
|
||||
if sys.argv[1] == 'board':
|
||||
|
||||
if sys.argv[1] == 'board':
|
||||
# ------- BOARD INFO START -----------
|
||||
boardid = sys.argv[2]
|
||||
board = wekanurl + apiboards + boardid
|
||||
@@ -202,6 +297,17 @@ if arguments == 2:
|
||||
print(data2)
|
||||
# ------- BOARD INFO END -----------
|
||||
|
||||
if sys.argv[1] == 'customfields':
|
||||
# ------- CUSTOM FIELDS OF BOARD START -----------
|
||||
boardid = sys.argv[2]
|
||||
boardcustomfields = wekanurl + apiboards + boardid + s + cf
|
||||
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
|
||||
body = requests.get(boardcustomfields, headers=headers)
|
||||
print("=== CUSTOM FIELDS OF BOARD ===\n")
|
||||
data2 = body.text.replace('}',"}\n")
|
||||
print(data2)
|
||||
# ------- CUSTOM FIELDS OF BOARD END -----------
|
||||
|
||||
if sys.argv[1] == 'swimlanes':
|
||||
boardid = sys.argv[2]
|
||||
swimlanes = wekanurl + apiboards + boardid + s + sws
|
||||
@@ -217,7 +323,7 @@ if arguments == 2:
|
||||
|
||||
# ------- LISTS OF BOARD START -----------
|
||||
boardid = sys.argv[2]
|
||||
attachments = wekanurl + apiboards + boardid
|
||||
lists = wekanurl + apiboards + boardid + s + l
|
||||
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
|
||||
print("=== LISTS ===\n")
|
||||
body = requests.get(lists, headers=headers)
|
||||
@@ -249,3 +355,14 @@ if arguments == 1:
|
||||
data2 = body.text.replace('}',"}\n")
|
||||
print(data2)
|
||||
# ------- LIST OF USERS END -----------
|
||||
|
||||
if sys.argv[1] == 'boards':
|
||||
|
||||
# ------- LIST OF PUBLIC BOARDS START -----------
|
||||
headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
|
||||
print("=== PUBLIC BOARDS ===\n")
|
||||
listpublicboards = wekanurl + apiboards
|
||||
body = requests.get(listpublicboards, headers=headers)
|
||||
data2 = body.text.replace('}',"}\n")
|
||||
print(data2)
|
||||
# ------- LIST OF PUBLIC BOARDS END -----------
|
||||
@@ -0,0 +1,8 @@
|
||||
# v1.0 2022-03-22 Perl Asana export to WeKan ® release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- [Added Perl scripts for Asana export to WeKan ®](https://github.com/wekan/wekan/commit/376bcbb373d16317060adc2b1154cc20496775cc).
|
||||
Thanks to GeekRuthie.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 WeKan ® Team and GeekRuthie
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,178 @@
|
||||
#!/usr/local/perl-cbt/bin/perl
|
||||
use Modern::Perl;
|
||||
use Carp;
|
||||
use Data::Dumper;
|
||||
use HTTP::Request;
|
||||
use JSON;
|
||||
use LWP::UserAgent;
|
||||
use MIME::Base64 qw/encode_base64/;
|
||||
|
||||
my $BASE_URL = 'https://app.asana.com/api/1.0';
|
||||
my $ASANA_API_KEY = 'ASANA_PERSONAL_TOKEN';
|
||||
my $ua = LWP::UserAgent->new();
|
||||
|
||||
open my $input_wekan, '<', 'template.json';
|
||||
my $wekan_json = readline($input_wekan);
|
||||
close $input_wekan;
|
||||
my $wekan_board = decode_json($wekan_json);
|
||||
my %users;
|
||||
my %users_by_gid;
|
||||
# get user IDs from template board
|
||||
foreach my $user ( @{ $wekan_board->{users} } ) {
|
||||
$users{ $user->{profile}->{fullname} } = $user->{_id};
|
||||
}
|
||||
# get list IDs from template (we ended up not using these)
|
||||
my %lists;
|
||||
foreach my $list ( @{ $wekan_board->{lists} } ) {
|
||||
$lists{ $list->{title} } = $list->{_id};
|
||||
}
|
||||
|
||||
my @headers;
|
||||
push @headers, ( 'Accept', 'application/json' );
|
||||
push @headers, ( 'Authorization', "Bearer $ASANA_API_KEY" );
|
||||
my $projects_req = HTTP::Request->new( "GET", "$BASE_URL/projects", \@headers, );
|
||||
my $projects_res = $ua->request($projects_req);
|
||||
my $projects = decode_json( $projects_res->content )->{data};
|
||||
foreach my $project (@$projects) {
|
||||
say "Project: ".$project->{name};
|
||||
my $tasks_url =
|
||||
'/tasks?project='
|
||||
. $project->{gid}
|
||||
. '&opt_fields=completed,name,notes,assignee,created_by,memberships.project.name, memberships.section.name,due_on,created_at,custom_fields';
|
||||
my $tasks_req = HTTP::Request->new( 'GET', "$BASE_URL$tasks_url", \@headers );
|
||||
my $tasks_res = $ua->request($tasks_req);
|
||||
my @output_tasks;
|
||||
my $tasks = decode_json( $tasks_res->content )->{data};
|
||||
foreach my $task (@$tasks) {
|
||||
next if $task->{completed};
|
||||
say ' - '.$task->{name};
|
||||
my $git_branch;
|
||||
my $prio;
|
||||
foreach my $custom ( @{ $task->{custom_fields} } ) {
|
||||
if ( $custom->{name} eq 'git branch' ) {
|
||||
$git_branch = $custom->{text_value};
|
||||
next;
|
||||
}
|
||||
# We ended up not importing these.
|
||||
if ( $custom->{name} eq 'Priority' && defined $custom->{display_value} ) {
|
||||
$prio =
|
||||
$custom->{display_value} eq 'High' ? 'fwccC9'
|
||||
: $custom->{display_value} eq 'Med' ? 'yPnaFa'
|
||||
: $custom->{display_value} eq 'Low' ? 'W4vMvm'
|
||||
: 'ML5drH';
|
||||
next;
|
||||
}
|
||||
}
|
||||
if ( !defined $users_by_gid{ $task->{created_by}->{gid} } ) {
|
||||
my $user_req =
|
||||
HTTP::Request->new( 'GET', "$BASE_URL/users/" . $task->{created_by}->{gid},
|
||||
\@headers );
|
||||
my $user_res = $ua->request($user_req);
|
||||
my $user = decode_json( $user_res->content )->{data};
|
||||
if ( defined $users{ $user->{name} } ) {
|
||||
$users_by_gid{ $task->{created_by}->{gid} } = $users{ $user->{name} };
|
||||
}
|
||||
}
|
||||
my $creator = $users_by_gid{ $task->{created_by}->{gid} } // undef;
|
||||
if ( defined $task->{assignee} && !defined $users_by_gid{ $task->{assignee}->{gid} } ) {
|
||||
my $user_req =
|
||||
HTTP::Request->new( 'GET', "$BASE_URL/users/" . $task->{assignee}->{gid},
|
||||
\@headers );
|
||||
my $user_res = $ua->request($user_req);
|
||||
my $user = decode_json( $user_res->content )->{data};
|
||||
if ( defined $users{ $user->{name} } ) {
|
||||
$users_by_gid{ $task->{assignee}->{gid} } = $users{ $user->{name} };
|
||||
}
|
||||
}
|
||||
my $assignee = defined $task->{assignee} ? $users_by_gid{ $task->{assignee}->{gid} } : undef;
|
||||
my $list;
|
||||
foreach my $membership ( @{ $task->{memberships} } ) {
|
||||
next if $membership->{project}->{name} ne $project->{name};
|
||||
$list = $membership->{section}->{name};
|
||||
}
|
||||
|
||||
# I was trying to create JSON that I could use on the import screen in Wekan,
|
||||
# but for bigger boards, it was just *too* hefty, so I took that JSON and used
|
||||
# APIs to import.
|
||||
my %output_task = (
|
||||
swimlaneId => 'As4SNerx4Y4mMnJ8n', # 'Bugs'
|
||||
sort => 0,
|
||||
type => 'cardType-card',
|
||||
archived => JSON::false,
|
||||
title => $task->{name},
|
||||
description => $task->{notes},
|
||||
createdAt => $task->{created_at},
|
||||
dueAt => defined $task->{due_on} ? $task->{due_on} . 'T22:00:00.000Z' : undef,
|
||||
customFields => [
|
||||
{
|
||||
_id => 'rL8BpFHp5xxSFbDdr',
|
||||
value => $git_branch,
|
||||
},
|
||||
],
|
||||
labelIds => [$prio],
|
||||
listId => $list,
|
||||
userId => $creator,
|
||||
assignees => [$assignee],
|
||||
);
|
||||
my @final_comments;
|
||||
my $comments_req =
|
||||
HTTP::Request->new( 'GET', "$BASE_URL/tasks/" . $task->{gid} . '/stories',
|
||||
\@headers );
|
||||
my $comments_res = $ua->request($comments_req);
|
||||
my $comments = decode_json( $comments_res->content )->{data};
|
||||
foreach my $comment (@$comments) {
|
||||
next if $comment->{type} ne 'comment';
|
||||
if ( !defined $users_by_gid{ $comment->{created_by}->{gid} } ) {
|
||||
my $user_req =
|
||||
HTTP::Request->new( 'GET', "$BASE_URL/users/" . $comment->{created_by}->{gid},
|
||||
\@headers );
|
||||
my $user_res = $ua->request($user_req);
|
||||
my $user = decode_json( $user_res->content )->{data};
|
||||
if ( defined $users{ $user->{name} } ) {
|
||||
$users_by_gid{ $comment->{created_bye}->{gid} } = $users{ $user->{name} };
|
||||
}
|
||||
}
|
||||
my $commentor = $users_by_gid{ $comment->{created_by}->{gid} };
|
||||
my %this_comment = (
|
||||
text => $comment->{text},
|
||||
createdAt => $comment->{created_at},
|
||||
userId => $commentor,
|
||||
);
|
||||
push @final_comments, \%this_comment;
|
||||
}
|
||||
$output_task{comments} = \@final_comments;
|
||||
|
||||
|
||||
my @final_attachments;
|
||||
my $attachments_req =
|
||||
HTTP::Request->new( 'GET', "$BASE_URL/tasks/" . $task->{gid} . '/attachments',
|
||||
\@headers );
|
||||
my $attachments_res = $ua->request($attachments_req);
|
||||
my $attachments = decode_json( $attachments_res->content )->{data};
|
||||
foreach my $attachment (@$attachments) {
|
||||
my $att_req =
|
||||
HTTP::Request->new( 'GET', "$BASE_URL/attachments/" . $attachment->{gid},
|
||||
\@headers );
|
||||
my $att_res = $ua->request($att_req);
|
||||
my $att = decode_json( $att_res->content )->{data};
|
||||
my $file_req=HTTP::Request->new('GET',$att->{download_url});
|
||||
my $file_res=$ua->request($file_req);
|
||||
my $file=encode_base64($file_res->content);
|
||||
|
||||
my %this_attachment = (
|
||||
file => $file,
|
||||
name => $att->{name},
|
||||
createdAt => $att->{created_at},
|
||||
);
|
||||
push @final_attachments, \%this_attachment;
|
||||
|
||||
}
|
||||
$output_task{attachments} = \@final_attachments;
|
||||
push @output_tasks, \%output_task;
|
||||
}
|
||||
my $file_name = $project->{name};
|
||||
$file_name =~ s/\//_/g;
|
||||
open my $output_file, '>',$file_name.'_exported.json';
|
||||
print $output_file encode_json(\@output_tasks);
|
||||
close $output_file;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
#!/usr/local/perl-cbt/bin/perl
|
||||
use Modern::Perl;
|
||||
use Carp;
|
||||
use Data::Dumper;
|
||||
use HTTP::Request;
|
||||
use JSON;
|
||||
use LWP::UserAgent;
|
||||
use MIME::Base64 qw/decode_base64/;
|
||||
use Try::Tiny;
|
||||
|
||||
my $BASE_URL = 'https://taskboard.example.com/api';
|
||||
my $TOKEN = 'MY_TOKEN';
|
||||
my $me = 'MY_USER_ID';
|
||||
my $ua = LWP::UserAgent->new();
|
||||
|
||||
my @headers;
|
||||
push @headers, ( 'Accept', 'application/json' );
|
||||
push @headers, ( 'Authorization', "Bearer $TOKEN" );
|
||||
|
||||
my @form_headers;
|
||||
push @form_headers, ( 'Content-Type', 'application/json' );
|
||||
push @form_headers, ( 'Accept', 'application/json' );
|
||||
push @form_headers, ( 'Authorization', "Bearer $TOKEN" );
|
||||
|
||||
# Prior to running this, I built all the boards, with labels and lists and swimlanes.
|
||||
# Grabbed the IDs for the boards for each project, and put them here to match up with
|
||||
# filenames from the Asana export script.
|
||||
|
||||
my %board_to_use = (
|
||||
Project_1 => 'F5ZiCXnf4d7qNBRjp',
|
||||
Project_2 => 'Shw3tyfC2JWCutBLj',
|
||||
);
|
||||
|
||||
opendir my $files_dir, '.'
|
||||
or croak "Cannot open input directory: $!";
|
||||
my @files = readdir $files_dir;
|
||||
closedir $files_dir;
|
||||
|
||||
foreach my $tasks_file (@files) {
|
||||
next if $tasks_file !~ /_exported.json/;
|
||||
my $project = $tasks_file;
|
||||
$project =~ s/_exported.json//;
|
||||
say "Project - $project";
|
||||
my $board;
|
||||
if ( $board_to_use{$project} ) {
|
||||
$board = $board_to_use{$project};
|
||||
}
|
||||
say ' No board!' if !$board;
|
||||
next if !$board;
|
||||
my $labels_req = HTTP::Request->new( 'GET', "$BASE_URL/boards/$board", \@headers );
|
||||
my $labels_res = $ua->request($labels_req);
|
||||
my $board_data = decode_json( $labels_res->content);
|
||||
my $labels = $board_data->{labels};
|
||||
my $label_to_use;
|
||||
# We're merging several Asana boards onto one Wekan board, with labels per project.
|
||||
foreach my $label (@$labels) {
|
||||
$label_to_use = $label->{_id} if $label->{name} eq $project;
|
||||
}
|
||||
|
||||
my $lanes_req = HTTP::Request->new( 'GET', "$BASE_URL/boards/$board/swimlanes", \@headers );
|
||||
my $lanes_res = $ua->request($lanes_req);
|
||||
my $lanes = decode_json( $lanes_res->content );
|
||||
my $lane_to_use;
|
||||
foreach my $lane (@$lanes) {
|
||||
# Our Asana didn't use swimlanes; all of our Wekan boards have a "Bugs" lane, so use that.
|
||||
$lane_to_use = $lane->{_id} if $lane->{title} eq 'Bugs';
|
||||
}
|
||||
|
||||
my $lists_req = HTTP::Request->new( 'GET', "$BASE_URL/boards/$board/lists", \@headers );
|
||||
my $lists_res = $ua->request($lists_req);
|
||||
my $lists = decode_json( $lists_res->content );
|
||||
my %list_to_use;
|
||||
foreach my $list (@$lists) {
|
||||
$list_to_use{ $list->{title} } = $list->{_id};
|
||||
}
|
||||
|
||||
open my $task_export_file, '<', $tasks_file;
|
||||
my $tasks_json = readline($task_export_file);
|
||||
close $task_export_file;
|
||||
my $tasks = decode_json($tasks_json);
|
||||
foreach my $task (@$tasks) {
|
||||
say ' - ' . $task->{title};
|
||||
my %body_info = (
|
||||
swimlaneId => $lane_to_use,
|
||||
authorId => $task->{userId},
|
||||
assignees => $task->{assignees},
|
||||
title => $task->{title},
|
||||
description => $task->{description},
|
||||
);
|
||||
my $body = encode_json( \%body_info );
|
||||
my $list = $list_to_use{ $task->{listId} } // $list_to_use{'Backlog'};
|
||||
my $task_req = HTTP::Request->new( 'POST', "$BASE_URL/boards/$board/lists/$list/cards",
|
||||
\@form_headers, $body );
|
||||
my $task_res = $ua->request($task_req);
|
||||
my $res;
|
||||
try {
|
||||
$res = decode_json( $task_res->content );
|
||||
} catch {
|
||||
# Did these manually afterward.
|
||||
say "--->UNABLE TO LOAD TASK";
|
||||
next;
|
||||
};
|
||||
my $card = $res->{_id};
|
||||
|
||||
if ($label_to_use) {
|
||||
my $card_edit_body = encode_json( { labelIds => [ $label_to_use ]});
|
||||
my $card_edit_req = HTTP::Request->new( 'PUT', "$BASE_URL/boards/$board/lists/$list/cards/$card",
|
||||
\@form_headers, $card_edit_body );
|
||||
my $card_edit_res = $ua->request($card_edit_req);
|
||||
}
|
||||
|
||||
foreach my $comment ( @{ $task->{comments} } ) {
|
||||
my $comment_body =
|
||||
encode_json( { authorId => $comment->{userId}, comment => $comment->{text} } );
|
||||
my $comment_req =
|
||||
HTTP::Request->new( 'POST', "$BASE_URL/boards/$board/cards/$card/comments",
|
||||
\@form_headers, $comment_body );
|
||||
my $comment_res = $ua->request($comment_req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
.activity-title {
|
||||
margin: 0 0.5em 0.8em;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.reactions-popup .add-comment-reaction {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
font-size: 22px;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
width: 40px;
|
||||
}
|
||||
.reactions-popup .add-comment-reaction:hover {
|
||||
background-color: #b0c4de;
|
||||
}
|
||||
.activities {
|
||||
clear: both;
|
||||
}
|
||||
.activities .activity {
|
||||
margin: 0.5px 0;
|
||||
padding: 6px 0;
|
||||
display: flex;
|
||||
}
|
||||
.activities .activity .member {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
.activities .activity .activity-member {
|
||||
font-weight: 700;
|
||||
}
|
||||
.activities .activity .activity-desc {
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
align-self: center;
|
||||
margin: 0;
|
||||
margin-left: 3px;
|
||||
overflow: hidden;
|
||||
word-break: break-word;
|
||||
}
|
||||
.activities .activity .activity-desc .activity-comment {
|
||||
display: block;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
margin-top: 5px;
|
||||
padding: 5px;
|
||||
}
|
||||
.activities .activity .activity-desc .reactions {
|
||||
display: flex;
|
||||
margin-top: 5px;
|
||||
gap: 5px;
|
||||
}
|
||||
.activities .activity .activity-desc .reactions .open-comment-reaction-popup {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
height: 24px;
|
||||
}
|
||||
.activities .activity .activity-desc .reactions .open-comment-reaction-popup i.fa.fa-smile-o {
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
margin-left: 2px;
|
||||
}
|
||||
.activities .activity .activity-desc .reactions .open-comment-reaction-popup i.fa.fa-plus {
|
||||
font-size: 8px;
|
||||
margin-top: -7px;
|
||||
margin-left: 1px;
|
||||
}
|
||||
.activities .activity .activity-desc .reactions .reaction {
|
||||
cursor: pointer;
|
||||
border: 1px solid #808080;
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
.activities .activity .activity-desc .reactions .reaction.selected {
|
||||
background-color: #b0c4de;
|
||||
}
|
||||
.activities .activity .activity-desc .reactions .reaction:hover {
|
||||
background-color: #b0c4de;
|
||||
}
|
||||
.activities .activity .activity-desc .reactions .reaction .reaction-count {
|
||||
font-size: 12px;
|
||||
}
|
||||
.activities .activity .activity-desc .activity-checklist {
|
||||
display: block;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
margin-top: 5px;
|
||||
padding: 5px;
|
||||
}
|
||||
.activities .activity .activity-desc .activity-meta {
|
||||
font-size: 0.8em;
|
||||
color: #999;
|
||||
}
|
||||
@@ -12,7 +12,7 @@ template(name="boardActivities")
|
||||
+activity(activity=activityData card=card mode=mode)
|
||||
|
||||
template(name="cardActivities")
|
||||
each activityData in currentCard.activities
|
||||
each activityData in activities
|
||||
+activity(activity=activityData card=card mode=mode)
|
||||
|
||||
template(name="editOrDeleteComment")
|
||||
@@ -21,8 +21,28 @@ template(name="editOrDeleteComment")
|
||||
= ' - '
|
||||
a.js-delete-comment {{_ "delete"}}
|
||||
|
||||
template(name="deleteCommentPopup")
|
||||
p {{_ "comment-delete"}}
|
||||
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
|
||||
|
||||
template(name="commentReactions")
|
||||
.reactions
|
||||
each reaction in reactions
|
||||
span.reaction(class="{{#if isSelected reaction.userIds}}selected{{/if}}" data-codepoint="#{reaction.reactionCodepoint}" title="{{userNames reaction.userIds}}")
|
||||
span.reaction-codepoint !{reaction.reactionCodepoint}
|
||||
span.reaction-count #{reaction.userIds.length}
|
||||
if (currentUser.isBoardMember)
|
||||
a.open-comment-reaction-popup(title="{{_ 'addReactionPopup-title'}}")
|
||||
i.fa.fa-smile-o
|
||||
i.fa.fa-plus
|
||||
|
||||
template(name="addReactionPopup")
|
||||
.reactions-popup
|
||||
each codepoint in codepoints
|
||||
span.add-comment-reaction(data-codepoint="#{codepoint}") !{codepoint}
|
||||
|
||||
template(name="activity")
|
||||
.activity
|
||||
.activity(data-id=activity._id)
|
||||
+userAvatar(userId=activity.user._id)
|
||||
p.activity-desc
|
||||
span.activity-member
|
||||
@@ -39,18 +59,17 @@ template(name="activity")
|
||||
img.attachment-image-preview(src=activity.attachment.url)
|
||||
|
||||
//- board activity ------------------------------------------------------
|
||||
if($eq mode 'board')
|
||||
if($eq activity.activityType 'createBoard')
|
||||
| {{{_ 'activity-created' boardLabelLink}}}.
|
||||
if($eq activity.activityType 'createBoard')
|
||||
| {{{_ 'activity-created' boardLabelLink}}}.
|
||||
|
||||
if($eq activity.activityType 'importBoard')
|
||||
| {{{_ 'activity-imported-board' boardLabelLink sourceLink}}}.
|
||||
if($eq activity.activityType 'importBoard')
|
||||
| {{{_ 'activity-imported-board' boardLabelLink sourceLink}}}.
|
||||
|
||||
if($eq activity.activityType 'addBoardMember')
|
||||
| {{{_ 'activity-added' memberLink boardLabelLink}}}.
|
||||
if($eq activity.activityType 'addBoardMember')
|
||||
| {{{_ 'activity-added' memberLink boardLabelLink}}}.
|
||||
|
||||
if($eq activity.activityType 'removeBoardMember')
|
||||
| {{{_ 'activity-excluded' memberLink boardLabelLink}}}.
|
||||
if($eq activity.activityType 'removeBoardMember')
|
||||
| {{{_ 'activity-excluded' memberLink boardLabelLink}}}.
|
||||
|
||||
//- card activity -------------------------------------------------------
|
||||
if($eq activity.activityType 'createCard')
|
||||
@@ -120,10 +139,12 @@ template(name="activity")
|
||||
= activity.comment.text
|
||||
.edit-controls
|
||||
button.primary(type="submit") {{_ 'edit'}}
|
||||
.fa.fa-times-thin.js-close-inlined-form
|
||||
else
|
||||
.activity-comment
|
||||
+viewer
|
||||
= activity.comment.text
|
||||
+commentReactions(reactions=activity.comment.reactions commentId=activity.comment._id)
|
||||
span(title=activity.createdAt).activity-meta {{ moment activity.createdAt }}
|
||||
if($eq currentUser._id activity.comment.userId)
|
||||
+editOrDeleteComment
|
||||
@@ -131,10 +152,10 @@ template(name="activity")
|
||||
+editOrDeleteComment
|
||||
|
||||
if($eq activity.activityType 'deleteComment')
|
||||
| {{{_ 'activity-deleteComment' currentData.commentId}}}.
|
||||
| {{{_ 'activity-deleteComment' activity.commentId}}}.
|
||||
|
||||
if($eq activity.activityType 'editComment')
|
||||
| {{{_ 'activity-editComment' currentData.commentId}}}.
|
||||
| {{{_ 'activity-editComment' activity.commentId}}}.
|
||||
else
|
||||
//- if we are not in card mode we only display a summary of the comment
|
||||
if($eq activity.activityType 'addComment')
|
||||
@@ -144,42 +165,27 @@ template(name="activity")
|
||||
= activity.comment.text
|
||||
|
||||
//- date activity ------------------------------------------------
|
||||
if($eq mode 'card')
|
||||
if($eq activity.activityType 'a-receivedAt')
|
||||
| {{{_ 'activity-receivedDate' (sanitize receivedDate) cardLink}}}.
|
||||
if($eq activity.activityType 'a-receivedAt')
|
||||
| {{{_ 'activity-receivedDate' (sanitize receivedDate) cardLink}}}.
|
||||
|
||||
if($eq activity.activityType 'a-startAt')
|
||||
| {{{_ 'activity-startDate' (sanitize startDate) cardLink}}}.
|
||||
|
||||
if($eq activity.activityType 'a-dueAt')
|
||||
| {{{_ 'activity-dueDate' (sanitize dueDate) cardLink}}}.
|
||||
if($eq activity.activityType 'a-startAt')
|
||||
| {{{_ 'activity-startDate' (sanitize startDate) cardLink}}}.
|
||||
|
||||
if($eq activity.activityType 'a-endAt')
|
||||
| {{{_ 'activity-endDate' (sanitize endDate) cardLink}}}.
|
||||
|
||||
if($eq mode 'board')
|
||||
if($eq activity.activityType 'a-receivedAt')
|
||||
| {{{_ 'activity-receivedDate' (sanitize receivedDate) cardLink}}}.
|
||||
if($eq activity.activityType 'a-dueAt')
|
||||
| {{{_ 'activity-dueDate' (sanitize dueDate) cardLink}}}.
|
||||
|
||||
if($eq activity.activityType 'a-startAt')
|
||||
| {{{_ 'activity-startDate' (sanitize startDate) cardLink}}}.
|
||||
|
||||
if($eq activity.activityType 'a-dueAt')
|
||||
| {{{_ 'activity-dueDate' (sanitize dueDate) cardLink}}}.
|
||||
|
||||
if($eq activity.activityType 'a-endAt')
|
||||
| {{{_ 'activity-endDate' (sanitize endDate) cardLink}}}.
|
||||
if($eq activity.activityType 'a-endAt')
|
||||
| {{{_ 'activity-endDate' (sanitize endDate) cardLink}}}.
|
||||
|
||||
//- customField activity ------------------------------------------------
|
||||
if($eq mode 'board')
|
||||
if($eq activity.activityType 'createCustomField')
|
||||
| {{_ 'activity-customfield-created' customField}}.
|
||||
if($eq activity.activityType 'createCustomField')
|
||||
| {{_ 'activity-customfield-created' customField}}.
|
||||
|
||||
if($eq activity.activityType 'setCustomField')
|
||||
| {{{_ 'activity-set-customfield' (sanitize lastCustomField) (sanitize lastCustomFieldValue) cardLink}}}.
|
||||
if($eq activity.activityType 'setCustomField')
|
||||
| {{{_ 'activity-set-customfield' (sanitize lastCustomField) (sanitize lastCustomFieldValue) cardLink}}}.
|
||||
|
||||
if($eq activity.activityType 'unsetCustomField')
|
||||
| {{{_ 'activity-unset-customfield' (sanitize lastCustomField) cardLink}}}.
|
||||
if($eq activity.activityType 'unsetCustomField')
|
||||
| {{{_ 'activity-unset-customfield' (sanitize lastCustomField) cardLink}}}.
|
||||
|
||||
//- label activity ------------------------------------------------------
|
||||
if($eq activity.activityType 'addedLabel')
|
||||
@@ -216,12 +222,11 @@ template(name="activity")
|
||||
| {{{_ 'activity-removed' memberLink cardLink}}}.
|
||||
|
||||
//- swimlane activity --------------------------------------------------
|
||||
if($neq mode 'card')
|
||||
if($eq activity.activityType 'createSwimlane')
|
||||
| {{_ 'activity-added' (sanitize activity.swimlane.title) boardLabelLink}}.
|
||||
if($eq activity.activityType 'createSwimlane')
|
||||
| {{{_ 'activity-added' (sanitize activity.swimlane.title) boardLabelLink}}}.
|
||||
|
||||
if($eq activity.activityType 'archivedSwimlane')
|
||||
| {{_ 'activity-archived' (sanitize activity.swimlane.title)}}.
|
||||
if($eq activity.activityType 'archivedSwimlane')
|
||||
| {{{_ 'activity-archived' (sanitize activity.swimlane.title)}}}.
|
||||
|
||||
|
||||
//- I don't understand this part ----------------------------------------
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import sanitizeXss from 'xss';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
|
||||
const activitiesPerPage = 500;
|
||||
|
||||
@@ -13,14 +14,14 @@ BlazeComponent.extendComponent({
|
||||
this.autorun(() => {
|
||||
let mode = this.data().mode;
|
||||
const capitalizedMode = Utils.capitalize(mode);
|
||||
let thisId, searchId;
|
||||
let searchId;
|
||||
if (mode === 'linkedcard' || mode === 'linkedboard') {
|
||||
thisId = Session.get('currentCard');
|
||||
searchId = Cards.findOne({ _id: thisId }).linkedId;
|
||||
searchId = Utils.getCurrentCard().linkedId;
|
||||
mode = mode.replace('linked', '');
|
||||
} else if (mode === 'card') {
|
||||
searchId = Utils.getCurrentCardId();
|
||||
} else {
|
||||
thisId = Session.get(`current${capitalizedMode}`);
|
||||
searchId = thisId;
|
||||
searchId = Session.get(`current${capitalizedMode}`);
|
||||
}
|
||||
const limit = this.page.get() * activitiesPerPage;
|
||||
const user = Meteor.user();
|
||||
@@ -54,6 +55,13 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
}).register('activities');
|
||||
|
||||
Template.activities.helpers({
|
||||
activities() {
|
||||
const ret = this.card.activities();
|
||||
return ret;
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
checkItem() {
|
||||
const checkItemId = this.currentData().activity.checklistItemId;
|
||||
@@ -63,22 +71,51 @@ BlazeComponent.extendComponent({
|
||||
|
||||
boardLabelLink() {
|
||||
const data = this.currentData();
|
||||
const currentBoardId = Session.get('currentBoard');
|
||||
if (data.mode !== 'board') {
|
||||
return createBoardLink(data.activity.board(), data.activity.listName);
|
||||
// data.mode: card, linkedcard, linkedboard
|
||||
return createBoardLink(data.activity.board(), data.activity.listName ? data.activity.listName : null);
|
||||
}
|
||||
else if (currentBoardId != data.activity.boardId) {
|
||||
// data.mode: board
|
||||
// current activitie is linked
|
||||
return createBoardLink(data.activity.board(), data.activity.listName ? data.activity.listName : null);
|
||||
}
|
||||
return TAPi18n.__('this-board');
|
||||
},
|
||||
|
||||
cardLabelLink() {
|
||||
const data = this.currentData();
|
||||
if (data.mode !== 'card') {
|
||||
return createCardLink(data.activity.card());
|
||||
const currentBoardId = Session.get('currentBoard');
|
||||
if (data.mode == 'card') {
|
||||
// data.mode: card
|
||||
return TAPi18n.__('this-card');
|
||||
}
|
||||
return TAPi18n.__('this-card');
|
||||
else if (data.mode !== 'board') {
|
||||
// data.mode: linkedcard, linkedboard
|
||||
return createCardLink(data.activity.card(), null);
|
||||
}
|
||||
else if (currentBoardId != data.activity.boardId) {
|
||||
// data.mode: board
|
||||
// current activitie is linked
|
||||
return createCardLink(data.activity.card(), data.activity.board().title);
|
||||
}
|
||||
return createCardLink(this.currentData().activity.card(), null);
|
||||
},
|
||||
|
||||
cardLink() {
|
||||
return createCardLink(this.currentData().activity.card());
|
||||
const data = this.currentData();
|
||||
const currentBoardId = Session.get('currentBoard');
|
||||
if (data.mode !== 'board') {
|
||||
// data.mode: card, linkedcard, linkedboard
|
||||
return createCardLink(data.activity.card(), null);
|
||||
}
|
||||
else if (currentBoardId != data.activity.boardId) {
|
||||
// data.mode: board
|
||||
// current activitie is linked
|
||||
return createCardLink(data.activity.card(), data.activity.board().title);
|
||||
}
|
||||
return createCardLink(this.currentData().activity.card(), null);
|
||||
},
|
||||
|
||||
receivedDate() {
|
||||
@@ -113,8 +150,10 @@ BlazeComponent.extendComponent({
|
||||
).getLabelById(lastLabelId);
|
||||
if (lastLabel && (lastLabel.name === undefined || lastLabel.name === '')) {
|
||||
return lastLabel.color;
|
||||
} else {
|
||||
} else if (lastLabel.name !== undefined && lastLabel.name !== '') {
|
||||
return lastLabel.name;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -162,11 +201,15 @@ BlazeComponent.extendComponent({
|
||||
{
|
||||
href: source.url,
|
||||
},
|
||||
sanitizeXss(source.system),
|
||||
DOMPurify.sanitize(source.system, {
|
||||
ALLOW_UNKNOWN_PROTOCOLS: true,
|
||||
}),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return sanitizeXss(source.system);
|
||||
return DOMPurify.sanitize(source.system, {
|
||||
ALLOW_UNKNOWN_PROTOCOLS: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -183,17 +226,17 @@ BlazeComponent.extendComponent({
|
||||
// trying to display url before file is stored generates js errors
|
||||
return (
|
||||
(attachment &&
|
||||
attachment.url({ download: true }) &&
|
||||
attachment.path &&
|
||||
Blaze.toHTML(
|
||||
HTML.A(
|
||||
{
|
||||
href: attachment.url({ download: true }),
|
||||
href: `${attachment.link()}?download=true`,
|
||||
target: '_blank',
|
||||
},
|
||||
sanitizeXss(attachment.name()),
|
||||
DOMPurify.sanitize(attachment.name),
|
||||
),
|
||||
)) ||
|
||||
sanitizeXss(this.currentData().activity.attachmentName)
|
||||
DOMPurify.sanitize(this.currentData().activity.attachmentName)
|
||||
);
|
||||
},
|
||||
|
||||
@@ -207,10 +250,11 @@ BlazeComponent.extendComponent({
|
||||
return [
|
||||
{
|
||||
// XXX We should use Popup.afterConfirmation here
|
||||
'click .js-delete-comment'() {
|
||||
const commentId = this.currentData().activity.commentId;
|
||||
'click .js-delete-comment': Popup.afterConfirm('deleteComment', () => {
|
||||
const commentId = this.data().activity.commentId;
|
||||
CardComments.remove(commentId);
|
||||
},
|
||||
Popup.back();
|
||||
}),
|
||||
'submit .js-edit-comment'(evt) {
|
||||
evt.preventDefault();
|
||||
const commentText = this.currentComponent()
|
||||
@@ -232,12 +276,68 @@ BlazeComponent.extendComponent({
|
||||
|
||||
Template.activity.helpers({
|
||||
sanitize(value) {
|
||||
return sanitizeXss(value);
|
||||
return DOMPurify.sanitize(value, { ALLOW_UNKNOWN_PROTOCOLS: true });
|
||||
},
|
||||
});
|
||||
|
||||
function createCardLink(card) {
|
||||
Template.commentReactions.events({
|
||||
'click .reaction'(event) {
|
||||
if (Meteor.user().isBoardMember()) {
|
||||
const codepoint = event.currentTarget.dataset['codepoint'];
|
||||
const commentId = Template.instance().data.commentId;
|
||||
const cardComment = CardComments.findOne({_id: commentId});
|
||||
cardComment.toggleReaction(codepoint);
|
||||
}
|
||||
},
|
||||
'click .open-comment-reaction-popup': Popup.open('addReaction'),
|
||||
})
|
||||
|
||||
Template.addReactionPopup.events({
|
||||
'click .add-comment-reaction'(event) {
|
||||
if (Meteor.user().isBoardMember()) {
|
||||
const codepoint = event.currentTarget.dataset['codepoint'];
|
||||
const commentId = Template.instance().data.commentId;
|
||||
const cardComment = CardComments.findOne({_id: commentId});
|
||||
cardComment.toggleReaction(codepoint);
|
||||
}
|
||||
Popup.back();
|
||||
},
|
||||
})
|
||||
|
||||
Template.addReactionPopup.helpers({
|
||||
codepoints() {
|
||||
// Starting set of unicode codepoints as comment reactions
|
||||
return [
|
||||
'👍',
|
||||
'👎',
|
||||
'👀',
|
||||
'✅',
|
||||
'❌',
|
||||
'🙏',
|
||||
'👏',
|
||||
'🎉',
|
||||
'🚀',
|
||||
'😊',
|
||||
'🤔',
|
||||
'😔'];
|
||||
}
|
||||
})
|
||||
|
||||
Template.commentReactions.helpers({
|
||||
isSelected(userIds) {
|
||||
return userIds.includes(Meteor.user()._id);
|
||||
},
|
||||
userNames(userIds) {
|
||||
return Users.find({_id: {$in: userIds}})
|
||||
.map(user => user.profile.fullname)
|
||||
.join(', ');
|
||||
}
|
||||
})
|
||||
|
||||
function createCardLink(card, board) {
|
||||
if (!card) return '';
|
||||
let text = card.title;
|
||||
if (board) text = `${board} > ` + text;
|
||||
return (
|
||||
card &&
|
||||
Blaze.toHTML(
|
||||
@@ -246,7 +346,7 @@ function createCardLink(card) {
|
||||
href: card.originRelativeUrl(),
|
||||
class: 'action-card',
|
||||
},
|
||||
sanitizeXss(card.title),
|
||||
DOMPurify.sanitize(text, { ALLOW_UNKNOWN_PROTOCOLS: true }),
|
||||
),
|
||||
)
|
||||
);
|
||||
@@ -263,7 +363,7 @@ function createBoardLink(board, list) {
|
||||
href: board.originRelativeUrl(),
|
||||
class: 'action-board',
|
||||
},
|
||||
sanitizeXss(text),
|
||||
DOMPurify.sanitize(text, { ALLOW_UNKNOWN_PROTOCOLS: true }),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
.activity-title
|
||||
margin: 0 0.5em 0.8em
|
||||
display: flex
|
||||
justify-content:space-between
|
||||
|
||||
.activities
|
||||
clear: both
|
||||
|
||||
.activity
|
||||
margin: 0.5px 0
|
||||
padding: 6px 0;
|
||||
display: flex
|
||||
|
||||
.member
|
||||
width: 32px
|
||||
height: @width
|
||||
|
||||
.activity-member
|
||||
font-weight: 700
|
||||
|
||||
.activity-desc
|
||||
word-wrap: break-word
|
||||
overflow: hidden
|
||||
flex: 1
|
||||
align-self: center
|
||||
margin: 0
|
||||
margin-left: 3px
|
||||
overflow: hidden;
|
||||
word-break: break-word;
|
||||
|
||||
.activity-comment
|
||||
display: block
|
||||
border-radius: 3px
|
||||
background: white
|
||||
text-decoration: none
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.2)
|
||||
margin-top: 5px
|
||||
padding: 5px
|
||||
|
||||
.activity-checklist
|
||||
display: block
|
||||
border-radius: 3px
|
||||
background: white
|
||||
text-decoration: none
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.2)
|
||||
margin-top: 5px
|
||||
padding: 5px
|
||||
.activity-meta
|
||||
font-size: 0.8em
|
||||
color: darken(white, 40%)
|
||||
@@ -0,0 +1,65 @@
|
||||
.new-comment {
|
||||
position: relative;
|
||||
margin: 0 0 20px 38px;
|
||||
}
|
||||
.new-comment .member {
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: -38px;
|
||||
}
|
||||
.new-comment.is-open .member {
|
||||
opacity: 1;
|
||||
}
|
||||
.new-comment.is-open .helper {
|
||||
display: inline-block;
|
||||
}
|
||||
.new-comment.is-open textarea {
|
||||
min-height: 100px;
|
||||
color: #4d4d4d;
|
||||
cursor: auto;
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.new-comment .too-long {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.new-comment textarea {
|
||||
background-color: #fff;
|
||||
border: 0;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.23);
|
||||
height: 36px;
|
||||
margin: 4px 4px 6px 0;
|
||||
padding: 9px 11px;
|
||||
width: 100%;
|
||||
}
|
||||
.new-comment textarea:hover,
|
||||
.new-comment textarea:is-open {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.33);
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.new-comment textarea:is-open {
|
||||
cursor: auto;
|
||||
}
|
||||
.comment-item {
|
||||
background-color: #fff;
|
||||
border: 0;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.23);
|
||||
color: #8c8c8c;
|
||||
height: 36px;
|
||||
margin: 4px 4px 6px 0;
|
||||
width: 92%;
|
||||
}
|
||||
.comment-item:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
.comment-item.add-comment {
|
||||
display: flex;
|
||||
margin: 5px;
|
||||
}
|
||||
.comment-item.add-comment a {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
template(name="commentForm")
|
||||
.new-comment.js-new-comment(
|
||||
class="{{#if commentFormIsOpen}}is-open{{/if}}")
|
||||
+userAvatar(userId=currentUser._id)
|
||||
+userAvatar(userId=currentUser._id noRemove=true)
|
||||
form.js-new-comment-form
|
||||
+editor(class="js-new-comment-input")
|
||||
| {{getUnsavedValue 'cardComment' currentCard._id}}
|
||||
|
||||
@@ -3,6 +3,7 @@ const commentFormIsOpen = new ReactiveVar(false);
|
||||
BlazeComponent.extendComponent({
|
||||
onDestroyed() {
|
||||
commentFormIsOpen.set(false);
|
||||
$('.note-popover').hide();
|
||||
},
|
||||
|
||||
commentFormIsOpen() {
|
||||
@@ -25,6 +26,8 @@ BlazeComponent.extendComponent({
|
||||
if (card.isLinkedCard()) {
|
||||
boardId = Cards.findOne(card.linkedId).boardId;
|
||||
cardId = card.linkedId;
|
||||
} else if (card.isLinkedBoard()) {
|
||||
boardId = card.linkedId;
|
||||
}
|
||||
if (text) {
|
||||
CardComments.insert({
|
||||
@@ -63,7 +66,7 @@ function resetCommentInput(input) {
|
||||
// Tracker.autorun to register the component dependencies, and re-run when these
|
||||
// dependencies are invalidated. A better component API would remove this hack.
|
||||
Tracker.autorun(() => {
|
||||
Session.get('currentCard');
|
||||
Utils.getCurrentCardId();
|
||||
Tracker.afterFlush(() => {
|
||||
autosize.update($('.js-new-comment-input'));
|
||||
});
|
||||
@@ -74,7 +77,7 @@ EscapeActions.register(
|
||||
() => {
|
||||
const draftKey = {
|
||||
fieldName: 'cardComment',
|
||||
docId: Session.get('currentCard'),
|
||||
docId: Utils.getCurrentCardId(),
|
||||
};
|
||||
const commentInput = $('.js-new-comment-input');
|
||||
const draft = commentInput.val().trim();
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
.new-comment
|
||||
position: relative
|
||||
margin: 0 0 20px 38px
|
||||
|
||||
.member
|
||||
opacity: .7
|
||||
position: absolute
|
||||
top: 1px
|
||||
left: -38px
|
||||
|
||||
&.is-open
|
||||
.member
|
||||
opacity: 1
|
||||
|
||||
.helper
|
||||
display: inline-block
|
||||
|
||||
textarea
|
||||
min-height: 100px
|
||||
color: #4d4d4d
|
||||
cursor: auto
|
||||
overflow: hidden
|
||||
word-wrap: break-word
|
||||
|
||||
.too-long
|
||||
margin-top: 8px
|
||||
|
||||
textarea
|
||||
background-color: #fff
|
||||
border: 0
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .23)
|
||||
color: #8c8c8c
|
||||
height: 36px
|
||||
margin: 4px 4px 6px 0
|
||||
padding: 9px 11px
|
||||
width: 100%
|
||||
|
||||
&:hover,
|
||||
&:is-open
|
||||
background-color: #fff
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, .33)
|
||||
border: 0
|
||||
cursor: pointer
|
||||
|
||||
&:is-open
|
||||
cursor: auto
|
||||
|
||||
.comment-item
|
||||
background-color: #fff
|
||||
border: 0
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .23)
|
||||
color: #8c8c8c
|
||||
height: 36px
|
||||
margin: 4px 4px 6px 0
|
||||
width: 92%
|
||||
|
||||
&:hover
|
||||
background: darken(white, 12%)
|
||||
|
||||
&.add-comment
|
||||
display: flex
|
||||
margin: 5px
|
||||
|
||||
a
|
||||
display: block
|
||||
margin: auto
|
||||
@@ -34,7 +34,7 @@ BlazeComponent.extendComponent({
|
||||
Utils.goBoardId(board._id);
|
||||
},
|
||||
'click .js-delete-board': Popup.afterConfirm('boardDelete', function() {
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
const isSandstorm =
|
||||
Meteor.settings &&
|
||||
Meteor.settings.public &&
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
.board-wrapper {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.board-wrapper .board-canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
transition: margin 0.1s;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.board-wrapper .board-canvas.is-sibling-sidebar-open {
|
||||
margin-right: 248px;
|
||||
}
|
||||
.board-wrapper .board-canvas .board-overlay {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
top: -100px;
|
||||
right: -400px;
|
||||
background: #000;
|
||||
opacity: 0.33;
|
||||
animation: fadeIn 0.2s;
|
||||
z-index: 16;
|
||||
}
|
||||
.board-wrapper .board-canvas.is-dragging-active .open-minicard-composer,
|
||||
.board-wrapper .board-canvas.is-dragging-active .minicard-wrapper.is-checked {
|
||||
display: none;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.board-wrapper .board-canvas .swimlane {
|
||||
border-bottom: 1px solid #ccc;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
padding: 0 0px 0px 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
.calendar-event-green {
|
||||
background: #3cb500 !important;
|
||||
border-color: #2a8000;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-yellow {
|
||||
background: #fad900 !important;
|
||||
border-color: #c7ac00;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-orange {
|
||||
background: #ff9f19 !important;
|
||||
border-color: #cc7c14;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-red {
|
||||
background: #eb4646 !important;
|
||||
border-color: #b83737;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-purple {
|
||||
background: #a632db !important;
|
||||
border-color: #7d26a6;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-blue {
|
||||
background: #0079bf !important;
|
||||
border-color: #005a8a;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-pink {
|
||||
background: #ff78cb !important;
|
||||
border-color: #cc62a3;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-sky {
|
||||
background: #00c2e0 !important;
|
||||
border-color: #0094ab;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-black {
|
||||
background: #4d4d4d !important;
|
||||
border-color: #1a1a1a;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-lime {
|
||||
background: #51e898 !important;
|
||||
border-color: #3eb375;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-silver {
|
||||
background: #c0c0c0 !important;
|
||||
border-color: #8c8c8c;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-peachpuff {
|
||||
background: #ffdab9 !important;
|
||||
border-color: #ccaf95;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-crimson {
|
||||
background: #dc143c !important;
|
||||
border-color: #a8112f;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-plum {
|
||||
background: #dda0dd !important;
|
||||
border-color: #a87ba8;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-darkgreen {
|
||||
background: #006400 !important;
|
||||
border-color: #003000;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-slateblue {
|
||||
background: #6a5acd !important;
|
||||
border-color: #4f4399;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-magenta {
|
||||
background: #f0f !important;
|
||||
border-color: #c0c;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-gold {
|
||||
background: #ffd700 !important;
|
||||
border-color: #ca0;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-navy {
|
||||
background: #000080 !important;
|
||||
border-color: #003;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-gray {
|
||||
background: #808080 !important;
|
||||
border-color: #333;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-saddlebrown {
|
||||
background: #8b4513 !important;
|
||||
border-color: #572b0c;
|
||||
color: #fff !important;
|
||||
}
|
||||
.calendar-event-paleturquoise {
|
||||
background: #afeeee !important;
|
||||
border-color: #8ababa;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-mistyrose {
|
||||
background: #ffe4e1 !important;
|
||||
border-color: #ccb8b6;
|
||||
color: #000 !important;
|
||||
}
|
||||
.calendar-event-indigo {
|
||||
background: #4b0082 !important;
|
||||
border-color: #2b004d;
|
||||
color: #fff !important;
|
||||
}
|
||||
@@ -13,26 +13,29 @@ template(name="board")
|
||||
+spinner
|
||||
|
||||
template(name="boardBody")
|
||||
.board-wrapper(class=currentBoard.colorClass)
|
||||
+sidebar
|
||||
.board-canvas.js-swimlanes(
|
||||
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}}")
|
||||
if showOverlay.get
|
||||
.board-overlay
|
||||
if currentBoard.isTemplatesBoard
|
||||
each currentBoard.swimlanes
|
||||
+swimlane(this)
|
||||
else if isViewSwimlanes
|
||||
each currentBoard.swimlanes
|
||||
+swimlane(this)
|
||||
else if isViewLists
|
||||
+listsGroup(currentBoard)
|
||||
else if isViewCalendar
|
||||
+calendarView
|
||||
else
|
||||
+listsGroup(currentBoard)
|
||||
if notDisplayThisBoard
|
||||
| {{_ 'tableVisibilityMode-allowPrivateOnly'}}
|
||||
else
|
||||
.board-wrapper(class=currentBoard.colorClass)
|
||||
+sidebar
|
||||
.board-canvas.js-swimlanes(
|
||||
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}}")
|
||||
if showOverlay.get
|
||||
.board-overlay
|
||||
if currentBoard.isTemplatesBoard
|
||||
each currentBoard.swimlanes
|
||||
+swimlane(this)
|
||||
else if isViewSwimlanes
|
||||
each currentBoard.swimlanes
|
||||
+swimlane(this)
|
||||
else if isViewLists
|
||||
+listsGroup(currentBoard)
|
||||
else if isViewCalendar
|
||||
+calendarView
|
||||
else
|
||||
+listsGroup(currentBoard)
|
||||
|
||||
template(name="calendarView")
|
||||
if isViewCalendar
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
|
||||
const subManager = new SubsManager();
|
||||
const { calculateIndex } = Utils;
|
||||
const swimlaneWhileSortingHeight = 150;
|
||||
@@ -23,7 +25,7 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
|
||||
onlyShowCurrentCard() {
|
||||
return Utils.isMiniScreen() && Session.get('currentCard');
|
||||
return Utils.isMiniScreen() && Utils.getCurrentCardId(true);
|
||||
},
|
||||
|
||||
goHome() {
|
||||
@@ -33,6 +35,7 @@ BlazeComponent.extendComponent({
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
Meteor.subscribe('tableVisibilityModeSettings');
|
||||
this.showOverlay = new ReactiveVar(false);
|
||||
this.draggingActive = new ReactiveVar(false);
|
||||
this._isDragging = false;
|
||||
@@ -190,21 +193,11 @@ BlazeComponent.extendComponent({
|
||||
});
|
||||
|
||||
this.autorun(() => {
|
||||
let showDesktopDragHandles = false;
|
||||
currentUser = Meteor.user();
|
||||
if (currentUser) {
|
||||
showDesktopDragHandles = (currentUser.profile || {})
|
||||
.showDesktopDragHandles;
|
||||
} else if (window.localStorage.getItem('showDesktopDragHandles')) {
|
||||
showDesktopDragHandles = true;
|
||||
} else {
|
||||
showDesktopDragHandles = false;
|
||||
}
|
||||
if (Utils.isMiniScreen() || showDesktopDragHandles) {
|
||||
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
|
||||
$swimlanesDom.sortable({
|
||||
handle: '.js-swimlane-header-handle',
|
||||
});
|
||||
} else if (!Utils.isMiniScreen() && !showDesktopDragHandles) {
|
||||
} else {
|
||||
$swimlanesDom.sortable({
|
||||
handle: '.swimlane-header',
|
||||
});
|
||||
@@ -215,7 +208,7 @@ BlazeComponent.extendComponent({
|
||||
$swimlanesDom.sortable(
|
||||
'option',
|
||||
'disabled',
|
||||
!Meteor.user().isBoardAdmin(),
|
||||
!Meteor.user() || !Meteor.user().isBoardAdmin(),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -235,6 +228,16 @@ BlazeComponent.extendComponent({
|
||||
}
|
||||
},
|
||||
|
||||
notDisplayThisBoard(){
|
||||
let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly');
|
||||
let currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
if(allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue && currentBoard.permission == 'public'){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
isViewSwimlanes() {
|
||||
currentUser = Meteor.user();
|
||||
if (currentUser) {
|
||||
@@ -266,9 +269,10 @@ BlazeComponent.extendComponent({
|
||||
|
||||
openNewListForm() {
|
||||
if (this.isViewSwimlanes()) {
|
||||
this.childComponents('swimlane')[0]
|
||||
.childComponents('addListAndSwimlaneForm')[0]
|
||||
.open();
|
||||
// The form had been removed in 416b17062e57f215206e93a85b02ef9eb1ab4902
|
||||
// this.childComponents('swimlane')[0]
|
||||
// .childComponents('addListAndSwimlaneForm')[0]
|
||||
// .open();
|
||||
} else if (this.isViewLists()) {
|
||||
this.childComponents('listsGroup')[0]
|
||||
.childComponents('addListForm')[0]
|
||||
@@ -325,6 +329,7 @@ BlazeComponent.extendComponent({
|
||||
defaultView: 'agendaDay',
|
||||
editable: true,
|
||||
timezone: 'local',
|
||||
weekNumbers: true,
|
||||
header: {
|
||||
left: 'title today prev,next',
|
||||
center:
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
position()
|
||||
if arguments[0] == cover || arguments[0] == fixed-cover
|
||||
if arguments[0] == cover
|
||||
position: absolute
|
||||
else
|
||||
position: fixed
|
||||
left: 0
|
||||
right: 0
|
||||
top: 0
|
||||
bottom: 0
|
||||
else
|
||||
position: arguments
|
||||
|
||||
.board-wrapper
|
||||
position: cover
|
||||
overflow-x: hidden
|
||||
overflow-y: hidden
|
||||
|
||||
.board-canvas
|
||||
position: cover
|
||||
transition: margin .1s
|
||||
overflow-y: auto
|
||||
|
||||
&.is-sibling-sidebar-open
|
||||
margin-right: 248px
|
||||
|
||||
.board-overlay
|
||||
position: fixed-cover
|
||||
top: -100px
|
||||
right: -400px
|
||||
background: black
|
||||
opacity: 0.33
|
||||
animation: fadeIn 0.2s
|
||||
z-index: 16
|
||||
|
||||
&.is-dragging-active
|
||||
.open-minicard-composer,
|
||||
.minicard-wrapper.is-checked
|
||||
display: none
|
||||
|
||||
@media screen and (max-width: 800px)
|
||||
.board-wrapper
|
||||
|
||||
.board-canvas
|
||||
|
||||
.swimlane
|
||||
border-bottom: 1px solid #CCC
|
||||
display: flex
|
||||
flex-direction: column
|
||||
margin: 0
|
||||
padding: 0 0px 0px 0
|
||||
overflow-x: hidden
|
||||
overflow-y: auto
|
||||
|
||||
calendar-event-color(background, borderColor, color...)
|
||||
background: background !important
|
||||
border-color: borderColor
|
||||
if color
|
||||
color: color !important //overwrite text for better visibility
|
||||
|
||||
.calendar-event-green
|
||||
calendar-event-color(#3cb500, #2a8000, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-yellow
|
||||
calendar-event-color(#fad900, #c7ac00, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-orange
|
||||
calendar-event-color(#ff9f19, #cc7c14, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-red
|
||||
calendar-event-color(#eb4646, #b83737, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-purple
|
||||
calendar-event-color(#a632db, #7d26a6, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-blue
|
||||
calendar-event-color(#0079bf, #005a8a, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-pink
|
||||
calendar-event-color(#ff78cb, #cc62a3, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-sky
|
||||
calendar-event-color(#00c2e0, #0094ab, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-black
|
||||
calendar-event-color(#4d4d4d, #1a1a1a, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-lime
|
||||
calendar-event-color(#51e898, #3eb375, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-silver
|
||||
calendar-event-color(#c0c0c0, #8c8c8c, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-peachpuff
|
||||
calendar-event-color(#ffdab9, #ccaf95, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-crimson
|
||||
calendar-event-color(#dc143c, #a8112f, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-plum
|
||||
calendar-event-color(#dda0dd, #a87ba8, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-darkgreen
|
||||
calendar-event-color(#006400, #003000, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-slateblue
|
||||
calendar-event-color(#6a5acd, #4f4399, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-magenta
|
||||
calendar-event-color(#ff00ff, #cc00cc, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-gold
|
||||
calendar-event-color(#ffd700, #ccaa00, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-navy
|
||||
calendar-event-color(#000080, #000033, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-gray
|
||||
calendar-event-color(#808080, #333333, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-saddlebrown
|
||||
calendar-event-color(#8b4513, #572b0c, #ffffff) //White text for better visibility
|
||||
|
||||
.calendar-event-paleturquoise
|
||||
calendar-event-color(#afeeee, #8ababa, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-mistyrose
|
||||
calendar-event-color(#ffe4e1, #ccb8b6, #000) //Black text for better visibility
|
||||
|
||||
.calendar-event-indigo
|
||||
calendar-event-color(#4b0082, #2b004d, #ffffff) //White text for better visibility
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,23 @@
|
||||
.integration-form {
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.flex,
|
||||
.option {
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -webkit-flex;
|
||||
display: -moz-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
.option {
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
text-decoration: none;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
margin-top: 5px;
|
||||
padding: 5px;
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
template(name="boardHeaderBar")
|
||||
h1.header-board-menu
|
||||
with currentBoard
|
||||
+viewer
|
||||
= title
|
||||
if $eq title 'Templates'
|
||||
| {{_ 'templates'}}
|
||||
else
|
||||
+viewer
|
||||
= title
|
||||
|
||||
.board-header-btns.left
|
||||
unless isMiniScreen
|
||||
@@ -77,6 +80,12 @@ template(name="boardHeaderBar")
|
||||
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
|
||||
|
||||
else
|
||||
a.board-header-btn.js-log-in(
|
||||
@@ -131,7 +140,7 @@ template(name="boardHeaderBar")
|
||||
i.fa.fa-times-thin
|
||||
|
||||
.separator
|
||||
a.board-header-btn.js-toggle-sidebar
|
||||
a.board-header-btn.js-toggle-sidebar(title="{{_ 'sidebar-open'}} {{_ 'or'}} {{_ 'sidebar-close'}}")
|
||||
i.fa.fa-navicon
|
||||
|
||||
template(name="boardVisibilityList")
|
||||
@@ -144,14 +153,15 @@ template(name="boardVisibilityList")
|
||||
if visibilityCheck
|
||||
i.fa.fa-check
|
||||
span.sub-name {{_ 'private-desc'}}
|
||||
li
|
||||
with "public"
|
||||
a.js-select-visibility
|
||||
i.fa.fa-globe.colorful
|
||||
| {{_ 'public'}}
|
||||
if visibilityCheck
|
||||
i.fa.fa-check
|
||||
span.sub-name {{_ 'public-desc'}}
|
||||
if notAllowPrivateVisibilityOnly
|
||||
li
|
||||
with "public"
|
||||
a.js-select-visibility
|
||||
i.fa.fa-globe.colorful
|
||||
| {{_ 'public'}}
|
||||
if visibilityCheck
|
||||
i.fa.fa-check
|
||||
span.sub-name {{_ 'public-desc'}}
|
||||
|
||||
template(name="boardChangeVisibilityPopup")
|
||||
+boardVisibilityList
|
||||
@@ -225,6 +235,9 @@ template(name="createBoard")
|
||||
= " "
|
||||
| {{{_ 'board-private-info'}}}
|
||||
a.js-change-visibility {{_ 'change'}}.
|
||||
a.flex.js-toggle-add-template-container
|
||||
.materialCheckBox#add-template-container
|
||||
span {{_ 'add-template-container'}}
|
||||
input.primary.wide(type="submit" value="{{_ 'create'}}")
|
||||
span.quiet
|
||||
| {{_ 'or'}}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
|
||||
/*
|
||||
const DOWNCLS = 'fa-sort-down';
|
||||
const UPCLS = 'fa-sort-up';
|
||||
@@ -7,11 +9,11 @@ Template.boardMenuPopup.events({
|
||||
'click .js-rename-board': Popup.open('boardChangeTitle'),
|
||||
'click .js-custom-fields'() {
|
||||
Sidebar.setView('customFields');
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-open-archives'() {
|
||||
Sidebar.setView('archives');
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-change-board-color': Popup.open('boardChangeColor'),
|
||||
'click .js-change-language': Popup.open('changeLanguage'),
|
||||
@@ -24,7 +26,7 @@ Template.boardMenuPopup.events({
|
||||
}),
|
||||
'click .js-delete-board': Popup.afterConfirm('deleteBoard', function() {
|
||||
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
Boards.remove(currentBoard._id);
|
||||
FlowRouter.go('home');
|
||||
}),
|
||||
@@ -32,6 +34,7 @@ Template.boardMenuPopup.events({
|
||||
'click .js-import-board': Popup.open('chooseBoardSource'),
|
||||
'click .js-subtask-settings': Popup.open('boardSubtaskSettings'),
|
||||
'click .js-card-settings': Popup.open('boardCardSettings'),
|
||||
'click .js-minicard-settings': Popup.open('boardMinicardSettings'),
|
||||
});
|
||||
|
||||
Template.boardChangeTitlePopup.events({
|
||||
@@ -47,7 +50,7 @@ Template.boardChangeTitlePopup.events({
|
||||
if (newTitle) {
|
||||
this.rename(newTitle);
|
||||
this.setDescription(newDesc);
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
}
|
||||
event.preventDefault();
|
||||
},
|
||||
@@ -136,7 +139,7 @@ BlazeComponent.extendComponent({
|
||||
Sidebar.setView('search');
|
||||
},
|
||||
'click .js-multiselection-activate'() {
|
||||
const currentCard = Session.get('currentCard');
|
||||
const currentCard = Utils.getCurrentCardId();
|
||||
MultiSelection.activate();
|
||||
if (currentCard) {
|
||||
MultiSelection.add(currentCard);
|
||||
@@ -173,15 +176,15 @@ Template.boardHeaderBar.helpers({
|
||||
Template.boardChangeViewPopup.events({
|
||||
'click .js-open-lists-view'() {
|
||||
Utils.setBoardView('board-view-lists');
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-open-swimlanes-view'() {
|
||||
Utils.setBoardView('board-view-swimlanes');
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-open-cal-view'() {
|
||||
Utils.setBoardView('board-view-cal');
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -194,6 +197,11 @@ const CreateBoard = BlazeComponent.extendComponent({
|
||||
this.visibilityMenuIsOpen = new ReactiveVar(false);
|
||||
this.visibility = new ReactiveVar('private');
|
||||
this.boardId = new ReactiveVar('');
|
||||
Meteor.subscribe('tableVisibilityModeSettings');
|
||||
},
|
||||
|
||||
notAllowPrivateVisibilityOnly(){
|
||||
return !TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly').booleanValue;
|
||||
},
|
||||
|
||||
visibilityCheck() {
|
||||
@@ -209,24 +217,79 @@ const CreateBoard = BlazeComponent.extendComponent({
|
||||
this.visibilityMenuIsOpen.set(!this.visibilityMenuIsOpen.get());
|
||||
},
|
||||
|
||||
toggleAddTemplateContainer() {
|
||||
$('#add-template-container').toggleClass('is-checked');
|
||||
},
|
||||
|
||||
onSubmit(event) {
|
||||
event.preventDefault();
|
||||
const title = this.find('.js-new-board-title').value;
|
||||
const visibility = this.visibility.get();
|
||||
|
||||
this.boardId.set(
|
||||
Boards.insert({
|
||||
title,
|
||||
permission: visibility,
|
||||
}),
|
||||
);
|
||||
const addTemplateContainer = $('#add-template-container.is-checked').length > 0;
|
||||
if (addTemplateContainer) {
|
||||
//const templateContainerId = Meteor.call('setCreateTemplateContainer');
|
||||
//Utils.goBoardId(templateContainerId);
|
||||
//alert('niinku template ' + Meteor.call('setCreateTemplateContainer'));
|
||||
|
||||
Swimlanes.insert({
|
||||
title: 'Default',
|
||||
boardId: this.boardId.get(),
|
||||
});
|
||||
this.boardId.set(
|
||||
Boards.insert({
|
||||
// title: TAPi18n.__('templates'),
|
||||
title: title,
|
||||
permission: 'private',
|
||||
type: 'template-container',
|
||||
}),
|
||||
);
|
||||
|
||||
Utils.goBoardId(this.boardId.get());
|
||||
// Insert the card templates swimlane
|
||||
Swimlanes.insert({
|
||||
// title: TAPi18n.__('card-templates-swimlane'),
|
||||
title: 'Card Templates',
|
||||
boardId: this.boardId.get(),
|
||||
sort: 1,
|
||||
type: 'template-container',
|
||||
}),
|
||||
|
||||
// Insert the list templates swimlane
|
||||
Swimlanes.insert(
|
||||
{
|
||||
// title: TAPi18n.__('list-templates-swimlane'),
|
||||
title: 'List Templates',
|
||||
boardId: this.boardId.get(),
|
||||
sort: 2,
|
||||
type: 'template-container',
|
||||
},
|
||||
);
|
||||
|
||||
// Insert the board templates swimlane
|
||||
Swimlanes.insert(
|
||||
{
|
||||
//title: TAPi18n.__('board-templates-swimlane'),
|
||||
title: 'Board Templates',
|
||||
boardId: this.boardId.get(),
|
||||
sort: 3,
|
||||
type: 'template-container',
|
||||
},
|
||||
);
|
||||
|
||||
Utils.goBoardId(this.boardId.get());
|
||||
|
||||
} else {
|
||||
const visibility = this.visibility.get();
|
||||
|
||||
this.boardId.set(
|
||||
Boards.insert({
|
||||
title,
|
||||
permission: visibility,
|
||||
}),
|
||||
);
|
||||
|
||||
Swimlanes.insert({
|
||||
title: 'Default',
|
||||
boardId: this.boardId.get(),
|
||||
});
|
||||
|
||||
Utils.goBoardId(this.boardId.get());
|
||||
}
|
||||
},
|
||||
|
||||
events() {
|
||||
@@ -240,6 +303,7 @@ const CreateBoard = BlazeComponent.extendComponent({
|
||||
submit: this.onSubmit,
|
||||
'click .js-import-board': Popup.open('chooseBoardSource'),
|
||||
'click .js-board-template': Popup.open('searchElement'),
|
||||
'click .js-toggle-add-template-container': this.toggleAddTemplateContainer,
|
||||
},
|
||||
];
|
||||
},
|
||||
@@ -254,6 +318,9 @@ const CreateBoard = BlazeComponent.extendComponent({
|
||||
}.register('headerBarCreateBoardPopup'));
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
notAllowPrivateVisibilityOnly(){
|
||||
return !TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly').booleanValue;
|
||||
},
|
||||
visibilityCheck() {
|
||||
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
return this.currentData() === currentBoard.permission;
|
||||
@@ -263,7 +330,7 @@ BlazeComponent.extendComponent({
|
||||
const currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
const visibility = this.currentData();
|
||||
currentBoard.setVisibility(visibility);
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
|
||||
events() {
|
||||
@@ -296,7 +363,7 @@ BlazeComponent.extendComponent({
|
||||
Session.get('currentBoard'),
|
||||
level,
|
||||
(err, ret) => {
|
||||
if (!err && ret) Popup.close();
|
||||
if (!err && ret) Popup.back();
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -368,7 +435,7 @@ BlazeComponent.extendComponent({
|
||||
const direction = down ? -1 : 1;
|
||||
this.setSortBy([sortby, direction]);
|
||||
if (Utils.isMiniScreen) {
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -387,7 +454,7 @@ BlazeComponent.extendComponent({
|
||||
};
|
||||
Session.set('sortBy', sortBy);
|
||||
sortCardsBy.set(TAPi18n.__('due-date'));
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-sort-title'() {
|
||||
const sortBy = {
|
||||
@@ -395,7 +462,7 @@ BlazeComponent.extendComponent({
|
||||
};
|
||||
Session.set('sortBy', sortBy);
|
||||
sortCardsBy.set(TAPi18n.__('title'));
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-sort-created-asc'() {
|
||||
const sortBy = {
|
||||
@@ -403,7 +470,7 @@ BlazeComponent.extendComponent({
|
||||
};
|
||||
Session.set('sortBy', sortBy);
|
||||
sortCardsBy.set(TAPi18n.__('date-created-newest-first'));
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-sort-created-desc'() {
|
||||
const sortBy = {
|
||||
@@ -411,7 +478,7 @@ BlazeComponent.extendComponent({
|
||||
};
|
||||
Session.set('sortBy', sortBy);
|
||||
sortCardsBy.set(TAPi18n.__('date-created-oldest-first'));
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
.integration-form
|
||||
padding: 5px
|
||||
border-bottom: 1px solid #ccc
|
||||
|
||||
.flex
|
||||
display: -webkit-box
|
||||
display: -moz-box
|
||||
display: -webkit-flex
|
||||
display: -moz-flex
|
||||
display: -ms-flexbox
|
||||
display: flex
|
||||
|
||||
.option
|
||||
@extends .flex
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
text-decoration: none;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
margin-top: 5px;
|
||||
padding: 5px;
|
||||
@@ -0,0 +1,281 @@
|
||||
@import url("css/reset.css") print, screen;
|
||||
|
||||
.board-list {
|
||||
margin: 0 8px;
|
||||
}
|
||||
.board-list li {
|
||||
float: left;
|
||||
width: 20%;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
.board-list li.placeholder:after {
|
||||
content: '';
|
||||
display: block;
|
||||
background: #ccc;
|
||||
border-radius: 3px;
|
||||
height: 106px;
|
||||
margin: 8px;
|
||||
}
|
||||
.board-list li.ui-sortable-helper {
|
||||
cursor: grabbing;
|
||||
transform: rotate(4deg);
|
||||
display: block !important;
|
||||
}
|
||||
.board-list li.starred .fa-star,
|
||||
.board-list li.starred .fa-star-o {
|
||||
opacity: 1;
|
||||
}
|
||||
.board-list .board-list-item {
|
||||
overflow: hidden;
|
||||
background-color: #999;
|
||||
color: #f6f6f6;
|
||||
min-height: 100px;
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.board-list .board-list-item.template-container {
|
||||
border: 4px solid #fff;
|
||||
}
|
||||
.board-list .board-list-item.tile {
|
||||
background-size: auto;
|
||||
background-repeat: repeat;
|
||||
}
|
||||
.board-list .board-list-item-sub-name {
|
||||
color: rgba(255,255,255,0.5);
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
}
|
||||
.board-list .board-list-item-desc {
|
||||
color: #fff;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 18px;
|
||||
}
|
||||
.board-list .js-add-board {
|
||||
text-align: center;
|
||||
}
|
||||
.board-list .js-add-board .label {
|
||||
font-weight: normal;
|
||||
line-height: 56px;
|
||||
}
|
||||
.board-list .js-add-board :hover {
|
||||
background-color: #939393;
|
||||
}
|
||||
.board-list .fa-star,
|
||||
.board-list .fa-star-o {
|
||||
bottom: 0;
|
||||
font-size: 14px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
opacity: 0;
|
||||
padding: 9px 9px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transition-duration: 0.15s;
|
||||
transition-property: color, font-size, background;
|
||||
}
|
||||
.board-list .fa-circle {
|
||||
bottom: 0;
|
||||
font-size: 10px;
|
||||
height: 10px;
|
||||
line-height: 10px;
|
||||
padding: 9px 9px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
transition-duration: 0.15s;
|
||||
transition-property: color, font-size, background;
|
||||
}
|
||||
.board-list .has-overtime-card-active {
|
||||
color: #eb4646 !important;
|
||||
}
|
||||
.board-list .no-overtime-card-active {
|
||||
color: #3cb500 !important;
|
||||
}
|
||||
.board-list .is-star-active {
|
||||
color: #fff;
|
||||
}
|
||||
.board-list .fa-clone {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
font-size: 14px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
opacity: 0;
|
||||
right: 0;
|
||||
padding: 9px 9px;
|
||||
transition-duration: 0.15s;
|
||||
transition-property: color, font-size, background;
|
||||
}
|
||||
.board-list .fa-archive {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
font-size: 14px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
opacity: 0;
|
||||
left: 0;
|
||||
padding: 9px 9px;
|
||||
transition-duration: 0.15s;
|
||||
transition-property: color, font-size, background;
|
||||
}
|
||||
.board-list li:hover a:hover .fa-star,
|
||||
.board-list li:hover a:hover .fa-clone,
|
||||
.board-list li:hover a:hover .fa-archive,
|
||||
.board-list li:hover a:hover .fa-star-o {
|
||||
color: #fff;
|
||||
}
|
||||
.board-list li:hover a .fa-star,
|
||||
.board-list li:hover a .fa-clone,
|
||||
.board-list li:hover a .fa-archive,
|
||||
.board-list li:hover a .fa-star-o {
|
||||
color: #fff;
|
||||
opacity: 0.75;
|
||||
}
|
||||
.board-list li:hover a .fa-star:hover,
|
||||
.board-list li:hover a .fa-clone:hover,
|
||||
.board-list li:hover a .fa-archive:hover,
|
||||
.board-list li:hover a .fa-star-o:hover {
|
||||
font-size: 18px;
|
||||
opacity: 1;
|
||||
}
|
||||
.board-list li:hover a .fa-star.is-star-active,
|
||||
.board-list li:hover a .fa-clone.is-star-active,
|
||||
.board-list li:hover a .fa-archive.is-star-active,
|
||||
.board-list li:hover a .fa-star-o.is-star-active {
|
||||
opacity: 1;
|
||||
}
|
||||
.board-backgrounds-list .board-background-select {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
float: left;
|
||||
width: 50%;
|
||||
padding-top: 12px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.board-backgrounds-list .board-background-select:nth-child(-n + 2) {
|
||||
padding-top: 0;
|
||||
}
|
||||
.board-backgrounds-list .board-background-select:nth-child(2n) {
|
||||
padding-left: 6px;
|
||||
}
|
||||
.board-backgrounds-list .board-background-select:nth-child(2n+1) {
|
||||
padding-right: 6px;
|
||||
}
|
||||
.board-backgrounds-list .board-background-select .background-box {
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
background-size: cover;
|
||||
display: block;
|
||||
height: 74px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.board-backgrounds-list .board-background-select .background-box i.fa-check {
|
||||
font-size: 25px;
|
||||
color: #fff;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.board-list {
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
.board-list li {
|
||||
width: 50%;
|
||||
}
|
||||
.board-list .board-list-item {
|
||||
overflow: hidden;
|
||||
height: 8rem;
|
||||
}
|
||||
.board-list .board-list-item-sub-name {
|
||||
position: relative;
|
||||
top: -100px;
|
||||
left: -100px;
|
||||
}
|
||||
.board-list .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%;
|
||||
}
|
||||
.board-handle {
|
||||
position: absolute;
|
||||
padding: 7px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: 10px;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
.AllBoardTeamsOrgs {
|
||||
list-style-type: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
.AllBoardTeams,
|
||||
.AllBoardOrgs,
|
||||
.AllBoardBtns {
|
||||
float: left;
|
||||
}
|
||||
.js-AllBoardOrgs {
|
||||
margin-left: 16px;
|
||||
}
|
||||
.AllBoardTeams {
|
||||
margin-left: 16px;
|
||||
}
|
||||
.AllBoardButtonsContainer {
|
||||
margin: 16px;
|
||||
}
|
||||
#filterBtn,
|
||||
#resetBtn {
|
||||
display: inline;
|
||||
}
|
||||
.js-board {
|
||||
display: block;
|
||||
}
|
||||
.minicard-members {
|
||||
padding: 6px 0 6px 8px;
|
||||
width: 100%;
|
||||
margin-bottom: 2px;
|
||||
margin-left: -4px;
|
||||
display: inline-block;
|
||||
}
|
||||
.minicard-lists {
|
||||
margin: 0 auto;
|
||||
max-width: 95%;
|
||||
height: 100%;
|
||||
}
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.flex-wrap .item {
|
||||
margin: 2px;
|
||||
padding-right: 6px;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -1,10 +1,40 @@
|
||||
template(name="boardList")
|
||||
.wrapper
|
||||
ul.AllBoardTeamsOrgs
|
||||
li.AllBoardTeams
|
||||
if userHasTeams
|
||||
select.js-AllBoardTeams#jsAllBoardTeams("multiple")
|
||||
option(value="-1") {{_ 'teams'}} :
|
||||
each teamsDatas
|
||||
option(value="{{teamId}}") {{_ teamDisplayName}}
|
||||
|
||||
li.AllBoardOrgs
|
||||
if userHasOrgs
|
||||
select.js-AllBoardOrgs#jsAllBoardOrgs("multiple")
|
||||
option(value="-1") {{_ 'organizations'}} :
|
||||
each orgsDatas
|
||||
option(value="{{orgId}}") {{orgDisplayName}}
|
||||
|
||||
//li.AllBoardTemplates
|
||||
// if userHasTemplates
|
||||
// select.js-AllBoardTemplates#jsAllBoardTemplates("multiple")
|
||||
// option(value="-1") {{_ 'templates'}} :
|
||||
// each templatesDatas
|
||||
// option(value="{{templateId}}") {{_ templateDisplayName}}
|
||||
|
||||
li.AllBoardBtns
|
||||
div.AllBoardButtonsContainer
|
||||
if userHasOrgsOrTeams
|
||||
i.fa.fa-filter
|
||||
input#filterBtn(type="button" value="{{_ 'filter'}}")
|
||||
input#resetBtn(type="button" value="{{_ 'filter-clear'}}")
|
||||
|
||||
ul.board-list.clearfix.js-boards
|
||||
li.js-add-board
|
||||
a.board-list-item.label {{_ 'add-board'}}
|
||||
a.board-list-item.label(title="{{_ 'add-board'}}")
|
||||
| {{_ 'add-board'}}
|
||||
each boards
|
||||
li(class="{{#if isStarred}}starred{{/if}}" class=colorClass).js-board
|
||||
li(class="{{_id}}" class="{{#if isStarred}}starred{{/if}}" class=colorClass).js-board
|
||||
if isInvited
|
||||
.board-list-item
|
||||
span.details
|
||||
@@ -16,47 +46,100 @@ template(name="boardList")
|
||||
button.js-accept-invite.primary {{_ 'accept'}}
|
||||
button.js-decline-invite {{_ 'decline'}}
|
||||
else
|
||||
a.js-open-board.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}")
|
||||
span.details
|
||||
span.board-list-item-name
|
||||
+viewer
|
||||
= title
|
||||
i.fa.js-star-board(
|
||||
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
|
||||
title="{{_ 'star-board-title'}}")
|
||||
p.board-list-item-desc
|
||||
+viewer
|
||||
= description
|
||||
if hasSpentTimeCards
|
||||
i.fa.js-has-spenttime-cards(
|
||||
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
|
||||
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
|
||||
if isMiniScreen
|
||||
i.fa.board-handle(
|
||||
class="fa-arrows"
|
||||
title="{{_ 'Drag board'}}")
|
||||
unless isMiniScreen
|
||||
if isSandstorm
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if isAdministrable
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if currentUser.isAdmin
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
if $eq type "template-container"
|
||||
a.js-open-board.template-container.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}")
|
||||
span.details
|
||||
span.board-list-item-name(title="{{_ 'template-container'}}")
|
||||
+viewer
|
||||
= title
|
||||
i.fa.js-star-board(
|
||||
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
|
||||
title="{{_ 'star-board-title'}}")
|
||||
p.board-list-item-desc
|
||||
+viewer
|
||||
= description
|
||||
if hasSpentTimeCards
|
||||
i.fa.js-has-spenttime-cards(
|
||||
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
|
||||
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
|
||||
if isMiniScreenOrShowDesktopDragHandles
|
||||
i.fa.board-handle(
|
||||
class="fa-arrows"
|
||||
title="{{_ 'Drag board'}}")
|
||||
else
|
||||
if isSandstorm
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if isAdministrable
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if currentUser.isAdmin
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else
|
||||
a.js-open-board.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}")
|
||||
span.details
|
||||
span.board-list-item-name(title="{{_ 'board-drag-drop-reorder-or-click-open'}}")
|
||||
+viewer
|
||||
= title
|
||||
if allowsBoardMemberList
|
||||
.minicard-members
|
||||
each member in boardMembers _id
|
||||
a.name
|
||||
+userAvatar(userId=member noRemove=true)
|
||||
if allowsCardCounterList
|
||||
.minicard-lists.flex.flex-wrap
|
||||
each list in boardLists _id
|
||||
.item
|
||||
| {{ list }}
|
||||
i.fa.js-star-board(
|
||||
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
|
||||
title="{{_ 'star-board-title'}}")
|
||||
p.board-list-item-desc
|
||||
+viewer
|
||||
= description
|
||||
if hasSpentTimeCards
|
||||
i.fa.js-has-spenttime-cards(
|
||||
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
|
||||
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
|
||||
if isMiniScreenOrShowDesktopDragHandles
|
||||
i.fa.board-handle(
|
||||
class="fa-arrows"
|
||||
title="{{_ 'Drag board'}}")
|
||||
else
|
||||
if isSandstorm
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if isAdministrable
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if currentUser.isAdmin
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
|
||||
template(name="boardListHeaderBar")
|
||||
h1 {{_ title }}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
|
||||
const subManager = new SubsManager();
|
||||
const { calculateIndex, enableClickOnTouch } = Utils;
|
||||
|
||||
Template.boardListHeaderBar.events({
|
||||
'click .js-open-archived-board'() {
|
||||
@@ -9,7 +10,11 @@ Template.boardListHeaderBar.events({
|
||||
|
||||
Template.boardListHeaderBar.helpers({
|
||||
title() {
|
||||
//if (FlowRouter.getRouteName() === 'template-container') {
|
||||
// return 'template-container';
|
||||
//} else {
|
||||
return FlowRouter.getRouteName() === 'home' ? 'my-boards' : 'public';
|
||||
//}
|
||||
},
|
||||
templatesBoardId() {
|
||||
return Meteor.user() && Meteor.user().getTemplatesBoardId();
|
||||
@@ -22,6 +27,15 @@ Template.boardListHeaderBar.helpers({
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
Meteor.subscribe('setting');
|
||||
Meteor.subscribe('tableVisibilityModeSettings');
|
||||
let currUser = Meteor.user();
|
||||
let userLanguage;
|
||||
if(currUser && currUser.profile){
|
||||
userLanguage = currUser.profile.language
|
||||
}
|
||||
if (userLanguage) {
|
||||
TAPi18n.setLanguage(userLanguage);
|
||||
}
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
@@ -46,7 +60,7 @@ BlazeComponent.extendComponent({
|
||||
// of the previous and the following card -- if any.
|
||||
const prevBoardDom = ui.item.prev('.js-board').get(0);
|
||||
const nextBoardBom = ui.item.next('.js-board').get(0);
|
||||
const sortIndex = calculateIndex(prevBoardDom, nextBoardBom, 1);
|
||||
const sortIndex = Utils.calculateIndex(prevBoardDom, nextBoardBom, 1);
|
||||
|
||||
const boardDomElement = ui.item.get(0);
|
||||
const board = Blaze.getData(boardDomElement);
|
||||
@@ -63,32 +77,144 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
});
|
||||
|
||||
// ugly touch event hotfix
|
||||
enableClickOnTouch(itemsSelector);
|
||||
|
||||
// Disable drag-dropping if the current user is not a board member or is comment only
|
||||
this.autorun(() => {
|
||||
if (Utils.isMiniScreen()) {
|
||||
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
|
||||
$boards.sortable({
|
||||
handle: '.board-handle',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
userHasTeams(){
|
||||
if(Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
teamsDatas() {
|
||||
if(Meteor.user().teams)
|
||||
return Meteor.user().teams.sort((a, b) => a.teamDisplayName.localeCompare(b.teamDisplayName));
|
||||
else
|
||||
return [];
|
||||
},
|
||||
userHasOrgs(){
|
||||
if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
/*
|
||||
userHasTemplates(){
|
||||
if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
*/
|
||||
orgsDatas() {
|
||||
if(Meteor.user().orgs)
|
||||
return Meteor.user().orgs.sort((a, b) => a.orgDisplayName.localeCompare(b.orgDisplayName));
|
||||
else
|
||||
return [];
|
||||
},
|
||||
userHasOrgsOrTeams(){
|
||||
let boolUserHasOrgs;
|
||||
if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
|
||||
boolUserHasOrgs = true;
|
||||
else
|
||||
boolUserHasOrgs = false;
|
||||
|
||||
let boolUserHasTeams;
|
||||
if(Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
|
||||
boolUserHasTeams = true;
|
||||
else
|
||||
boolUserHasTeams = false;
|
||||
|
||||
return (boolUserHasOrgs || boolUserHasTeams);
|
||||
},
|
||||
boards() {
|
||||
const query = {
|
||||
archived: false,
|
||||
type: 'board',
|
||||
let query = {
|
||||
// { type: 'board' },
|
||||
// { type: { $in: ['board','template-container'] } },
|
||||
$and: [
|
||||
{ archived: false },
|
||||
{ type: { $in: ['board','template-container'] } },
|
||||
{ $or:[] }
|
||||
]
|
||||
};
|
||||
if (FlowRouter.getRouteName() === 'home')
|
||||
query['members.userId'] = Meteor.userId();
|
||||
else query.permission = 'public';
|
||||
|
||||
let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly');
|
||||
|
||||
if (FlowRouter.getRouteName() === 'home'){
|
||||
query.$and[2].$or.push({'members.userId': Meteor.userId()});
|
||||
|
||||
if(allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue){
|
||||
query.$and.push({'permission': 'private'});
|
||||
}
|
||||
const currUser = Users.findOne(Meteor.userId());
|
||||
|
||||
// const currUser = Users.findOne(Meteor.userId(), {
|
||||
// fields: {
|
||||
// orgs: 1,
|
||||
// teams: 1,
|
||||
// },
|
||||
// });
|
||||
|
||||
let orgIdsUserBelongs = currUser !== undefined && currUser.teams !== 'undefined' ? currUser.orgIdsUserBelongs() : '';
|
||||
if(orgIdsUserBelongs && orgIdsUserBelongs != ''){
|
||||
let orgsIds = orgIdsUserBelongs.split(',');
|
||||
// for(let i = 0; i < orgsIds.length; i++){
|
||||
// query.$and[2].$or.push({'orgs.orgId': orgsIds[i]});
|
||||
// }
|
||||
|
||||
//query.$and[2].$or.push({'orgs': {$elemMatch : {orgId: orgsIds[0]}}});
|
||||
query.$and[2].$or.push({'orgs.orgId': {$in : orgsIds}});
|
||||
}
|
||||
|
||||
let teamIdsUserBelongs = currUser !== undefined && currUser.teams !== 'undefined' ? currUser.teamIdsUserBelongs() : '';
|
||||
if(teamIdsUserBelongs && teamIdsUserBelongs != ''){
|
||||
let teamsIds = teamIdsUserBelongs.split(',');
|
||||
// for(let i = 0; i < teamsIds.length; i++){
|
||||
// query.$or[2].$or.push({'teams.teamId': teamsIds[i]});
|
||||
// }
|
||||
//query.$and[2].$or.push({'teams': { $elemMatch : {teamId: teamsIds[0]}}});
|
||||
query.$and[2].$or.push({'teams.teamId': {$in : teamsIds}});
|
||||
}
|
||||
}
|
||||
else if(allowPrivateVisibilityOnly !== undefined && !allowPrivateVisibilityOnly.booleanValue){
|
||||
query = {
|
||||
archived: false,
|
||||
//type: { $in: ['board','template-container'] },
|
||||
type: 'board',
|
||||
permission: 'public',
|
||||
};
|
||||
}
|
||||
|
||||
return Boards.find(query, {
|
||||
sort: { sort: 1 /* boards default sorting */ },
|
||||
});
|
||||
},
|
||||
boardLists(boardId) {
|
||||
let boardLists = [];
|
||||
const lists = Lists.find({'boardId' : boardId})
|
||||
lists.forEach(list => {
|
||||
let cardCount = Cards.find({'boardId':boardId, 'listId':list._id}).count()
|
||||
boardLists.push(`${list.title}: ${cardCount}`);
|
||||
});
|
||||
return boardLists
|
||||
},
|
||||
|
||||
boardMembers(boardId) {
|
||||
let boardMembers = [];
|
||||
const lists = Boards.findOne({'_id' : boardId})
|
||||
let members = lists.members
|
||||
members.forEach(member => {
|
||||
boardMembers.push(member.userId);
|
||||
});
|
||||
return boardMembers
|
||||
},
|
||||
|
||||
isStarred() {
|
||||
const user = Meteor.user();
|
||||
return user && user.hasStarred(this.currentData()._id);
|
||||
@@ -123,6 +249,7 @@ BlazeComponent.extendComponent({
|
||||
evt.preventDefault();
|
||||
},
|
||||
'click .js-clone-board'(evt) {
|
||||
let title = getSlug(Boards.findOne(this.currentData()._id).title) || 'cloned-board';
|
||||
Meteor.call(
|
||||
'copyBoard',
|
||||
this.currentData()._id,
|
||||
@@ -133,10 +260,14 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
(err, res) => {
|
||||
if (err) {
|
||||
this.setError(err.error);
|
||||
console.error(err);
|
||||
} else {
|
||||
Session.set('fromBoard', null);
|
||||
Utils.goBoardId(res);
|
||||
subManager.subscribe('board', res, false);
|
||||
FlowRouter.go('board', {
|
||||
id: res,
|
||||
slug: title,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -160,6 +291,74 @@ BlazeComponent.extendComponent({
|
||||
}
|
||||
});
|
||||
},
|
||||
'click #resetBtn'(event){
|
||||
let allBoards = document.getElementsByClassName("js-board");
|
||||
let currBoard;
|
||||
for(let i=0; i < allBoards.length; i++){
|
||||
currBoard = allBoards[i];
|
||||
currBoard.style.display = "block";
|
||||
}
|
||||
},
|
||||
'click #filterBtn'(event) {
|
||||
event.preventDefault();
|
||||
let selectedTeams = document.querySelectorAll('#jsAllBoardTeams option:checked');
|
||||
let selectedTeamsValues = Array.from(selectedTeams).map(function(elt){return elt.value});
|
||||
let index = selectedTeamsValues.indexOf("-1");
|
||||
if (index > -1) {
|
||||
selectedTeamsValues.splice(index, 1);
|
||||
}
|
||||
|
||||
let selectedOrgs = document.querySelectorAll('#jsAllBoardOrgs option:checked');
|
||||
let selectedOrgsValues = Array.from(selectedOrgs).map(function(elt){return elt.value});
|
||||
index = selectedOrgsValues.indexOf("-1");
|
||||
if (index > -1) {
|
||||
selectedOrgsValues.splice(index, 1);
|
||||
}
|
||||
|
||||
if(selectedTeamsValues.length > 0 || selectedOrgsValues.length > 0){
|
||||
const query = {
|
||||
$and: [
|
||||
{ archived: false },
|
||||
{ type: 'board' },
|
||||
{ $or:[] }
|
||||
]
|
||||
};
|
||||
if(selectedTeamsValues.length > 0)
|
||||
{
|
||||
query.$and[2].$or.push({'teams.teamId': {$in : selectedTeamsValues}});
|
||||
}
|
||||
if(selectedOrgsValues.length > 0)
|
||||
{
|
||||
query.$and[2].$or.push({'orgs.orgId': {$in : selectedOrgsValues}});
|
||||
}
|
||||
|
||||
let filteredBoards = Boards.find(query, {}).fetch();
|
||||
let allBoards = document.getElementsByClassName("js-board");
|
||||
let currBoard;
|
||||
if(filteredBoards.length > 0){
|
||||
let currBoardId;
|
||||
let found;
|
||||
for(let i=0; i < allBoards.length; i++){
|
||||
currBoard = allBoards[i];
|
||||
currBoardId = currBoard.classList[0];
|
||||
found = filteredBoards.find(function(board){
|
||||
return board._id == currBoardId;
|
||||
});
|
||||
|
||||
if(found !== undefined)
|
||||
currBoard.style.display = "block";
|
||||
else
|
||||
currBoard.style.display = "none";
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(let i=0; i < allBoards.length; i++){
|
||||
currBoard = allBoards[i];
|
||||
currBoard.style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
$spaceBetweenTiles = 16px
|
||||
|
||||
.board-list
|
||||
margin: 0 ($spaceBetweenTiles/2)
|
||||
|
||||
li
|
||||
float: left
|
||||
width: 20%
|
||||
box-sizing: border-box
|
||||
position: relative
|
||||
|
||||
&.placeholder:after
|
||||
content: '';
|
||||
display: block;
|
||||
background: darken(white, 20%)
|
||||
border-radius: 3px;
|
||||
height: 106px;
|
||||
margin: 8px;
|
||||
|
||||
&.ui-sortable-helper
|
||||
cursor: grabbing
|
||||
transform: rotate(4deg)
|
||||
display: block !important
|
||||
|
||||
&.starred
|
||||
.fa-star,
|
||||
.fa-star-o
|
||||
opacity: 1
|
||||
|
||||
.board-list-item
|
||||
overflow: hidden;
|
||||
background-color: #999
|
||||
color: #f6f6f6
|
||||
min-height: 100px
|
||||
font-size: 16px
|
||||
line-height: 22px
|
||||
border-radius: 3px
|
||||
display: block
|
||||
font-weight: 700
|
||||
padding: 8px
|
||||
margin: ($spaceBetweenTiles/2)
|
||||
position: relative
|
||||
text-decoration: none
|
||||
word-wrap: break-word
|
||||
|
||||
&.tile
|
||||
background-size: auto
|
||||
background-repeat: repeat
|
||||
|
||||
.board-list-item-sub-name
|
||||
color: rgba(255, 255, 255, .5)
|
||||
display: block
|
||||
font-size: 14px
|
||||
font-weight: 400
|
||||
line-height: 22px
|
||||
|
||||
.board-list-item-desc
|
||||
color: #fff
|
||||
display: block
|
||||
font-size: 14px
|
||||
font-weight: 400
|
||||
line-height: 18px
|
||||
|
||||
.js-add-board
|
||||
text-align:center
|
||||
|
||||
.label
|
||||
font-weight: normal
|
||||
line-height: 56px
|
||||
|
||||
:hover
|
||||
background-color:#939393
|
||||
|
||||
.fa-star,
|
||||
.fa-star-o
|
||||
bottom: 0
|
||||
font-size: 14px
|
||||
height: 18px
|
||||
line-height: 18px
|
||||
opacity: 0
|
||||
padding: 9px 9px
|
||||
position: absolute
|
||||
right: 0
|
||||
top: 0
|
||||
transition-duration: .15s
|
||||
transition-property: color, font-size, background
|
||||
|
||||
.fa-circle
|
||||
bottom: 0;
|
||||
font-size: 10px;
|
||||
height: 10px;
|
||||
line-height: 10px;
|
||||
padding: 9px 9px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
transition-duration: .15s
|
||||
transition-property: color, font-size, background
|
||||
|
||||
.has-overtime-card-active
|
||||
color: #eb4646 !important
|
||||
|
||||
.no-overtime-card-active
|
||||
color: #3cb500 !important
|
||||
|
||||
.is-star-active
|
||||
color: white
|
||||
|
||||
.fa-clone
|
||||
position: absolute;
|
||||
bottom: 0
|
||||
font-size: 14px
|
||||
height: 18px
|
||||
line-height: 18px
|
||||
opacity: 0
|
||||
right: 0
|
||||
padding: 9px 9px
|
||||
transition-duration: .15s
|
||||
transition-property: color, font-size, background
|
||||
|
||||
.fa-archive
|
||||
position: absolute;
|
||||
bottom: 0
|
||||
font-size: 14px
|
||||
height: 18px
|
||||
line-height: 18px
|
||||
opacity: 0
|
||||
left: 0
|
||||
padding: 9px 9px
|
||||
transition-duration: .15s
|
||||
transition-property: color, font-size, background
|
||||
|
||||
li:hover a
|
||||
&:hover
|
||||
.fa-star,
|
||||
.fa-clone,
|
||||
.fa-archive,
|
||||
.fa-star-o
|
||||
color: white
|
||||
|
||||
.fa-star,
|
||||
.fa-clone,
|
||||
.fa-archive,
|
||||
.fa-star-o
|
||||
color: white
|
||||
opacity: .75
|
||||
|
||||
&:hover
|
||||
font-size: 18px
|
||||
opacity: 1
|
||||
|
||||
&.is-star-active
|
||||
opacity: 1
|
||||
|
||||
.board-backgrounds-list
|
||||
|
||||
.board-background-select
|
||||
box-sizing: border-box
|
||||
display: block
|
||||
float: left
|
||||
width: 50%
|
||||
padding-top: 12px
|
||||
position: relative
|
||||
z-index: 1
|
||||
|
||||
&:nth-child(-n + 2)
|
||||
padding-top: 0
|
||||
|
||||
&:nth-child(2n)
|
||||
padding-left: 6px
|
||||
|
||||
&:nth-child(2n+1)
|
||||
padding-right: 6px
|
||||
|
||||
.background-box
|
||||
color: white
|
||||
border-radius: 3px
|
||||
background-size: cover
|
||||
display: block
|
||||
height: 74px
|
||||
position: relative
|
||||
width: 100%
|
||||
cursor: pointer
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
i.fa-check
|
||||
font-size: 25px
|
||||
color: white
|
||||
|
||||
@media screen and (max-width: 800px)
|
||||
.board-list
|
||||
height: 100%
|
||||
overflow: scroll
|
||||
|
||||
li
|
||||
width: 50%
|
||||
|
||||
.board-list-item
|
||||
overflow: hidden
|
||||
height: 8rem
|
||||
|
||||
.board-list-item-sub-name
|
||||
position: relative
|
||||
top: -100px
|
||||
left: -100px
|
||||
|
||||
.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%
|
||||
|
||||
.board-handle
|
||||
position: absolute
|
||||
padding: 7px
|
||||
top: 50%
|
||||
transform: translateY(-50%)
|
||||
right: 10px
|
||||
font-size: 24px
|
||||
@@ -0,0 +1,81 @@
|
||||
.attachments-galery {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.attachments-galery .attachment-item {
|
||||
width: 31.33%;
|
||||
margin: 10px 1% 0;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
overflow: auto;
|
||||
background: #ededed;
|
||||
min-height: 120px;
|
||||
}
|
||||
.attachments-galery .attachment-item:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
.attachments-galery .attachment-item.add-attachment {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.attachments-galery .attachment-item.add-attachment a {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
.attachments-galery .attachment-item .attachment-thumbnail {
|
||||
height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
.attachments-galery .attachment-item .attachment-thumbnail .attachment-thumbnail-img {
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
.attachments-galery .attachment-item .attachment-thumbnail .attachment-thumbnail-ext {
|
||||
text-transform: uppercase;
|
||||
font-size: 1.6em;
|
||||
}
|
||||
.attachments-galery .attachment-item .attachment-details {
|
||||
font-size: 0.75em;
|
||||
margin: 3px;
|
||||
}
|
||||
.attachments-galery .attachment-item .attachment-details .attachment-details-actions a {
|
||||
display: block;
|
||||
}
|
||||
.attachments-galery .attachment-item .attachment-details .attachment-details-actions a.attachment-details-menu {
|
||||
padding-top: 10px;
|
||||
}
|
||||
.attachment-image-preview {
|
||||
max-width: 100px;
|
||||
display: block;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
}
|
||||
.preview-clipboard-image {
|
||||
width: 280px;
|
||||
max-width: 100%;
|
||||
height: 200px;
|
||||
display: block;
|
||||
border: 1px solid #000;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.attachments-galery .attachment-item {
|
||||
width: 48%;
|
||||
}
|
||||
.attachments-galery .attachment-item .attachment-thumbnail {
|
||||
height: 130px;
|
||||
}
|
||||
.attachments-galery .attachment-item .attachment-details {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 360px) {
|
||||
.attachments-galery .attachment-item {
|
||||
width: 100%;
|
||||
}
|
||||
.attachments-galery .attachment-item .attachment-thumbnail {
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,6 @@ template(name="previewClipboardImagePopup")
|
||||
img.preview-clipboard-image()
|
||||
button.primary.js-upload-pasted-image {{_ 'upload'}}
|
||||
|
||||
template(name="previewAttachedImagePopup")
|
||||
img.preview-large-image.js-large-image-clicked(src="{{url}}")
|
||||
|
||||
template(name="attachmentDeletePopup")
|
||||
p {{_ "attachment-delete-pop"}}
|
||||
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
|
||||
@@ -22,39 +19,77 @@ template(name="attachmentsGalery")
|
||||
.attachments-galery
|
||||
each attachments
|
||||
.attachment-item
|
||||
a.attachment-thumbnail.swipebox(href="{{url}}" title="{{name}}")
|
||||
if isUploaded
|
||||
a.attachment-thumbnail(href="{{link}}" title="{{name}}" data-lightbox="{{name}}")
|
||||
if link
|
||||
if isImage
|
||||
img.attachment-thumbnail-img(src="{{url}}")
|
||||
img.attachment-thumbnail-img(src="{{link}}")
|
||||
else if($eq extension 'mp3')
|
||||
video(width="100%" height="100%" controls="true")
|
||||
source(src="{{link}}" type="audio/mpeg")
|
||||
else if($eq extension 'ogg')
|
||||
video(width="100%" height="100%" controls="true")
|
||||
source(src="{{link}}" type="video/ogg")
|
||||
else if($eq extension 'webm')
|
||||
video(width="100%" height="100%" controls="true")
|
||||
source(src="{{link}}" type="video/webm")
|
||||
else if($eq extension 'mp4')
|
||||
video(width="100%" height="100%" controls="true")
|
||||
source(src="{{link}}" type="video/mp4")
|
||||
else
|
||||
span.attachment-thumbnail-ext= extension
|
||||
else
|
||||
+spinner
|
||||
p.attachment-details
|
||||
= name
|
||||
span.file-size ({{fileSize size}} KB)
|
||||
span.attachment-details-actions
|
||||
a.js-download(href="{{url download=true}}")
|
||||
a.js-download(href="{{link}}?download=true", download="{{name}}")
|
||||
i.fa.fa-download
|
||||
| {{_ 'download'}}
|
||||
if currentUser.isBoardMember
|
||||
unless currentUser.isCommentOnly
|
||||
unless currentUser.isWorker
|
||||
if isImage
|
||||
a(class="{{#if $eq ../coverId _id}}js-remove-cover{{else}}js-add-cover{{/if}}")
|
||||
i.fa.fa-thumb-tack
|
||||
if($eq ../coverId _id)
|
||||
| {{_ 'remove-cover'}}
|
||||
else
|
||||
| {{_ 'add-cover'}}
|
||||
if currentUser.isBoardAdmin
|
||||
a.js-confirm-delete
|
||||
i.fa.fa-close
|
||||
| {{_ 'delete'}}
|
||||
a.fa.fa-navicon.attachment-details-menu.js-open-attachment-menu(title="{{_ 'attachmentActionsPopup-title'}}")
|
||||
|
||||
if currentUser.isBoardMember
|
||||
unless currentUser.isCommentOnly
|
||||
unless currentUser.isWorker
|
||||
//li.attachment-item.add-attachment
|
||||
a.js-add-attachment
|
||||
a.js-add-attachment(title="{{_ 'add-attachment' }}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-attachment' }}
|
||||
|
||||
template(name="attachmentActionsPopup")
|
||||
ul.pop-over-list
|
||||
li
|
||||
if isImage
|
||||
a(class="{{#if isCover}}js-remove-cover{{else}}js-add-cover{{/if}}")
|
||||
i.fa.fa-thumb-tack
|
||||
if isCover
|
||||
| {{_ 'remove-cover'}}
|
||||
else
|
||||
| {{_ 'add-cover'}}
|
||||
if currentUser.isBoardAdmin
|
||||
a.js-rename
|
||||
i.fa.fa-pencil-square-o
|
||||
| {{_ 'rename'}}
|
||||
a.js-confirm-delete
|
||||
i.fa.fa-close
|
||||
| {{_ 'delete'}}
|
||||
p.attachment-storage
|
||||
| {{versions.original.storage}}
|
||||
|
||||
if $neq versions.original.storage "fs"
|
||||
a.js-move-storage-fs
|
||||
i.fa.fa-arrow-right
|
||||
| {{_ 'attachment-move-storage-fs'}}
|
||||
|
||||
if $neq versions.original.storage "gridfs"
|
||||
if versions.original.storage
|
||||
a.js-move-storage-gridfs
|
||||
i.fa.fa-arrow-right
|
||||
| {{_ 'attachment-move-storage-gridfs'}}
|
||||
|
||||
template(name="attachmentRenamePopup")
|
||||
input.js-edit-attachment-name(type='text' autofocus value="{{getNameWithoutExtension}}" dir="auto")
|
||||
.edit-controls.clearfix
|
||||
button.primary.confirm.js-submit-edit-attachment-name(type="submit") {{_ 'save'}}
|
||||
@@ -1,109 +1,50 @@
|
||||
Template.attachmentsGalery.events({
|
||||
'click .js-add-attachment': Popup.open('cardAttachments'),
|
||||
'click .js-confirm-delete': Popup.afterConfirm(
|
||||
'attachmentDelete',
|
||||
function() {
|
||||
Attachments.remove(this._id);
|
||||
Popup.close();
|
||||
},
|
||||
),
|
||||
// If we let this event bubble, FlowRouter will handle it and empty the page
|
||||
// content, see #101.
|
||||
'click .js-download'(event) {
|
||||
event.stopPropagation();
|
||||
},
|
||||
'click .js-add-cover'() {
|
||||
Cards.findOne(this.cardId).setCover(this._id);
|
||||
},
|
||||
'click .js-remove-cover'() {
|
||||
Cards.findOne(this.cardId).unsetCover();
|
||||
},
|
||||
'click .js-preview-image'(event) {
|
||||
Popup.open('previewAttachedImage').call(this, event);
|
||||
// when multiple thumbnails, if click one then another very fast,
|
||||
// we might get a wrong width from previous img.
|
||||
// when popup reused, onRendered() won't be called, so we cannot get there.
|
||||
// here make sure to get correct size when this img fully loaded.
|
||||
const img = $('img.preview-large-image')[0];
|
||||
if (!img) return;
|
||||
const rePosPopup = () => {
|
||||
const w = img.width;
|
||||
const h = img.height;
|
||||
// if the image is too large, we resize & center the popup.
|
||||
if (w > 300) {
|
||||
$('div.pop-over').css({
|
||||
width: w + 20,
|
||||
position: 'absolute',
|
||||
left: (window.innerWidth - w) / 2,
|
||||
top: (window.innerHeight - h) / 2,
|
||||
});
|
||||
}
|
||||
};
|
||||
const url = $(event.currentTarget).attr('src');
|
||||
if (img.src === url && img.complete) rePosPopup();
|
||||
else img.onload = rePosPopup;
|
||||
},
|
||||
'click .js-open-attachment-menu': Popup.open('attachmentActions'),
|
||||
});
|
||||
|
||||
Template.attachmentsGalery.helpers({
|
||||
isBoardAdmin() {
|
||||
return Meteor.user().isBoardAdmin();
|
||||
},
|
||||
});
|
||||
|
||||
Template.previewAttachedImagePopup.events({
|
||||
'click .js-large-image-clicked'() {
|
||||
Popup.close();
|
||||
fileSize(size) {
|
||||
return Math.round(size / 1024);
|
||||
},
|
||||
});
|
||||
|
||||
Template.cardAttachmentsPopup.events({
|
||||
'change .js-attach-file'(event) {
|
||||
const card = this;
|
||||
const processFile = f => {
|
||||
Utils.processUploadedAttachment(card, f, attachment => {
|
||||
if (attachment && attachment._id && attachment.isImage()) {
|
||||
card.setCover(attachment._id);
|
||||
}
|
||||
Popup.close();
|
||||
});
|
||||
};
|
||||
|
||||
FS.Utility.eachFile(event, f => {
|
||||
if (
|
||||
MAX_IMAGE_PIXEL > 0 &&
|
||||
typeof f.type === 'string' &&
|
||||
f.type.match(/^image/)
|
||||
) {
|
||||
// is image
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
const dataurl = e && e.target && e.target.result;
|
||||
if (dataurl !== undefined) {
|
||||
Utils.shrinkImage({
|
||||
dataurl,
|
||||
maxSize: MAX_IMAGE_PIXEL,
|
||||
ratio: COMPRESS_RATIO,
|
||||
toBlob: true,
|
||||
callback(blob) {
|
||||
if (blob === false) {
|
||||
processFile(f);
|
||||
} else {
|
||||
blob.name = f.name;
|
||||
processFile(blob);
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// couldn't process it let other function handle it?
|
||||
processFile(f);
|
||||
if (event.currentTarget.files && event.currentTarget.files[0]) {
|
||||
const fileId = Random.id();
|
||||
const config = {
|
||||
file: event.currentTarget.files[0],
|
||||
fileId: fileId,
|
||||
meta: Utils.getCommonAttachmentMetaFrom(card),
|
||||
chunkSize: 'dynamic',
|
||||
};
|
||||
config.meta.fileId = fileId;
|
||||
const uploader = Attachments.insert(
|
||||
config,
|
||||
false,
|
||||
);
|
||||
uploader.on('uploaded', (error, fileRef) => {
|
||||
if (!error) {
|
||||
if (fileRef.isImage) {
|
||||
card.setCover(fileRef._id);
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(f);
|
||||
} else {
|
||||
processFile(f);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
uploader.on('end', (error, fileRef) => {
|
||||
Popup.back();
|
||||
});
|
||||
uploader.start();
|
||||
}
|
||||
},
|
||||
'click .js-computer-upload'(event, templateInstance) {
|
||||
templateInstance.find('.js-attach-file').click();
|
||||
@@ -151,30 +92,98 @@ Template.previewClipboardImagePopup.onRendered(() => {
|
||||
|
||||
Template.previewClipboardImagePopup.events({
|
||||
'click .js-upload-pasted-image'() {
|
||||
const results = pastedResults;
|
||||
if (results && results.file) {
|
||||
const card = this;
|
||||
if (pastedResults && pastedResults.file) {
|
||||
const file = pastedResults.file;
|
||||
window.oPasted = pastedResults;
|
||||
const card = this;
|
||||
const file = new FS.File(results.file);
|
||||
if (!results.name) {
|
||||
// if no filename, it's from clipboard. then we give it a name, with ext name from MIME type
|
||||
if (typeof results.file.type === 'string') {
|
||||
file.name(results.file.type.replace('image/', 'clipboard.'));
|
||||
const fileId = Random.id();
|
||||
const config = {
|
||||
file,
|
||||
fileId: fileId,
|
||||
meta: Utils.getCommonAttachmentMetaFrom(card),
|
||||
fileName: file.name || file.type.replace('image/', 'clipboard.'),
|
||||
chunkSize: 'dynamic',
|
||||
};
|
||||
config.meta.fileId = fileId;
|
||||
const uploader = Attachments.insert(
|
||||
config,
|
||||
false,
|
||||
);
|
||||
uploader.on('uploaded', (error, fileRef) => {
|
||||
if (!error) {
|
||||
if (fileRef.isImage) {
|
||||
card.setCover(fileRef._id);
|
||||
}
|
||||
}
|
||||
}
|
||||
file.updatedAt(new Date());
|
||||
file.boardId = card.boardId;
|
||||
file.cardId = card._id;
|
||||
file.userId = Meteor.userId();
|
||||
const attachment = Attachments.insert(file);
|
||||
|
||||
if (attachment && attachment._id && attachment.isImage()) {
|
||||
card.setCover(attachment._id);
|
||||
}
|
||||
|
||||
pastedResults = null;
|
||||
$(document.body).pasteImageReader(() => {});
|
||||
Popup.close();
|
||||
});
|
||||
uploader.on('end', (error, fileRef) => {
|
||||
pastedResults = null;
|
||||
$(document.body).pasteImageReader(() => {});
|
||||
Popup.back();
|
||||
});
|
||||
uploader.start();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
isCover() {
|
||||
const ret = Cards.findOne(this.data().meta.cardId).coverId == this.data()._id;
|
||||
return ret;
|
||||
},
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-rename': Popup.open('attachmentRename'),
|
||||
'click .js-confirm-delete': Popup.afterConfirm('attachmentDelete', function() {
|
||||
Attachments.remove(this._id);
|
||||
Popup.back(2);
|
||||
}),
|
||||
'click .js-add-cover'() {
|
||||
Cards.findOne(this.data().meta.cardId).setCover(this.data()._id);
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-remove-cover'() {
|
||||
Cards.findOne(this.data().meta.cardId).unsetCover();
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-move-storage-fs'() {
|
||||
Meteor.call('moveAttachmentToStorage', this.data()._id, "fs");
|
||||
Popup.back();
|
||||
},
|
||||
'click .js-move-storage-gridfs'() {
|
||||
Meteor.call('moveAttachmentToStorage', this.data()._id, "gridfs");
|
||||
Popup.back();
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}).register('attachmentActionsPopup');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
getNameWithoutExtension() {
|
||||
const ret = this.data().name.replace(new RegExp("\." + this.data().extension + "$"), "");
|
||||
return ret;
|
||||
},
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'keydown input.js-edit-attachment-name'(evt) {
|
||||
// enter = save
|
||||
if (evt.keyCode === 13) {
|
||||
this.find('button[type=submit]').click();
|
||||
}
|
||||
},
|
||||
'click button.js-submit-edit-attachment-name'(event) {
|
||||
// save button pressed
|
||||
event.preventDefault();
|
||||
const name = this.$('.js-edit-attachment-name')[0]
|
||||
.value
|
||||
.trim() + this.data().extensionWithDot;
|
||||
Meteor.call('renameAttachment', this.data()._id, name);
|
||||
Popup.back(2);
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}).register('attachmentRenamePopup');
|
||||
@@ -1,85 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
.attachments-galery
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
|
||||
.attachment-item
|
||||
width: 33.33% - 2%
|
||||
margin: 10px 1% 0
|
||||
text-align: center
|
||||
border-radius: 3px
|
||||
overflow: hidden
|
||||
background: darken(white, 7%)
|
||||
min-height: 120px
|
||||
|
||||
&:hover
|
||||
background: darken(white, 12%)
|
||||
|
||||
&.add-attachment
|
||||
display: flex
|
||||
align-items: center
|
||||
|
||||
a
|
||||
display: block
|
||||
margin: auto
|
||||
|
||||
.attachment-thumbnail
|
||||
height: 80px
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
position: relative
|
||||
|
||||
.attachment-thumbnail-img
|
||||
max-height: 100%
|
||||
max-width: 100%
|
||||
|
||||
.attachment-thumbnail-ext
|
||||
text-transform: uppercase
|
||||
font-size: 1.6em
|
||||
|
||||
.attachment-details
|
||||
font-size: 0.75em
|
||||
margin: 3px
|
||||
|
||||
.attachment-details-actions a
|
||||
display: block
|
||||
|
||||
.attachment-image-preview
|
||||
max-width: 100px
|
||||
display: block
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.2)
|
||||
|
||||
.preview-large-image
|
||||
max-width: 1000px
|
||||
display: block
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.2)
|
||||
|
||||
.preview-clipboard-image
|
||||
width: 280px
|
||||
max-width: 100%;
|
||||
height: 200px
|
||||
display: block
|
||||
border: 1px solid black
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.2)
|
||||
|
||||
@media screen and (max-width: 800px)
|
||||
.attachments-galery
|
||||
flex-direction
|
||||
row
|
||||
.attachment-item
|
||||
width: 50% - 2%
|
||||
|
||||
.attachment-thumbnail
|
||||
height: 130px
|
||||
.attachment-details
|
||||
font-size: 1.1em
|
||||
|
||||
@media screen and (max-width: 360px)
|
||||
.attachments-galery
|
||||
.attachment-item
|
||||
width: 100%
|
||||
|
||||
.attachment-thumbnail
|
||||
height: 200px
|
||||
@@ -63,7 +63,7 @@ template(name="cardCustomField-checkbox")
|
||||
template(name="cardCustomField-currency")
|
||||
if canModifyCard
|
||||
+inlinedForm(classNames="js-card-customfield-currency")
|
||||
input(type="text" value=data.value)
|
||||
input(type="text" value=data.value autofocus)
|
||||
.edit-controls.clearfix
|
||||
button.primary(type="submit") {{_ 'save'}}
|
||||
a.fa.fa-times-thin.js-close-inlined-form
|
||||
@@ -79,18 +79,22 @@ template(name="cardCustomField-currency")
|
||||
|
||||
template(name="cardCustomField-date")
|
||||
if canModifyCard
|
||||
a.js-edit-date(title="{{showTitle}}" class="{{classes}}")
|
||||
if value
|
||||
div.card-date
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
else
|
||||
| {{_ 'edit'}}
|
||||
else
|
||||
a.js-edit-date(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
|
||||
if value
|
||||
div.card-date
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
div.card-date
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
b
|
||||
| {{showWeek}}
|
||||
else
|
||||
| {{_ 'edit'}}
|
||||
else
|
||||
if value
|
||||
div.card-date
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
b
|
||||
| {{showWeek}}
|
||||
|
||||
template(name="cardCustomField-dropdown")
|
||||
if canModifyCard
|
||||
@@ -119,3 +123,24 @@ template(name="cardCustomField-dropdown")
|
||||
if value
|
||||
+viewer
|
||||
= selectedItem
|
||||
|
||||
template(name="cardCustomField-stringtemplate")
|
||||
if canModifyCard
|
||||
+inlinedForm(classNames="js-card-customfield-stringtemplate")
|
||||
each item in stringtemplateItems.get
|
||||
input.js-card-customfield-stringtemplate-item(type="text" value=item placeholder="")
|
||||
input.js-card-customfield-stringtemplate-item.last(type="text" value="" placeholder="{{_ 'custom-field-stringtemplate-item-placeholder'}}" autofocus)
|
||||
.edit-controls.clearfix
|
||||
button.primary(type="submit") {{_ 'save'}}
|
||||
a.fa.fa-times-thin.js-close-inlined-form
|
||||
else
|
||||
a.js-open-inlined-form
|
||||
if value
|
||||
+viewer
|
||||
= formattedValue
|
||||
else
|
||||
| {{_ 'edit'}}
|
||||
else
|
||||
if value
|
||||
+viewer
|
||||
= formattedValue
|
||||
@@ -1,6 +1,11 @@
|
||||
import moment from 'moment/min/moment-with-locales';
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
import { DatePicker } from '/client/lib/datepicker';
|
||||
import Cards from '/models/cards';
|
||||
|
||||
Template.cardCustomFieldsPopup.helpers({
|
||||
hasCustomField() {
|
||||
const card = Cards.findOne(Session.get('currentCard'));
|
||||
const card = Utils.getCurrentCard();
|
||||
const customFieldId = this._id;
|
||||
return card.customFieldIndex(customFieldId) > -1;
|
||||
},
|
||||
@@ -8,7 +13,7 @@ Template.cardCustomFieldsPopup.helpers({
|
||||
|
||||
Template.cardCustomFieldsPopup.events({
|
||||
'click .js-select-field'(event) {
|
||||
const card = Cards.findOne(Session.get('currentCard'));
|
||||
const card = Utils.getCurrentCard();
|
||||
const customFieldId = this._id;
|
||||
card.toggleCustomField(customFieldId);
|
||||
event.preventDefault();
|
||||
@@ -28,7 +33,7 @@ const CardCustomField = BlazeComponent.extendComponent({
|
||||
|
||||
onCreated() {
|
||||
const self = this;
|
||||
self.card = Cards.findOne(Session.get('currentCard'));
|
||||
self.card = Utils.getCurrentCard();
|
||||
self.customFieldId = this.data()._id;
|
||||
},
|
||||
|
||||
@@ -146,6 +151,10 @@ CardCustomField.register('cardCustomField');
|
||||
});
|
||||
}
|
||||
|
||||
showWeek() {
|
||||
return this.date.get().week().toString();
|
||||
}
|
||||
|
||||
showDate() {
|
||||
// this will start working once mquandalle:moment
|
||||
// is updated to at least moment.js 2.10.5
|
||||
@@ -187,7 +196,7 @@ CardCustomField.register('cardCustomField');
|
||||
onCreated() {
|
||||
super.onCreated();
|
||||
const self = this;
|
||||
self.card = Cards.findOne(Session.get('currentCard'));
|
||||
self.card = Utils.getCurrentCard();
|
||||
self.customFieldId = this.data()._id;
|
||||
this.data().value && this.date.set(moment(this.data().value));
|
||||
}
|
||||
@@ -234,3 +243,91 @@ CardCustomField.register('cardCustomField');
|
||||
];
|
||||
}
|
||||
}.register('cardCustomField-dropdown'));
|
||||
|
||||
// cardCustomField-stringtemplate
|
||||
(class extends CardCustomField {
|
||||
onCreated() {
|
||||
super.onCreated();
|
||||
|
||||
this.stringtemplateFormat = this.data().definition.settings.stringtemplateFormat;
|
||||
this.stringtemplateSeparator = this.data().definition.settings.stringtemplateSeparator;
|
||||
|
||||
this.stringtemplateItems = new ReactiveVar(this.data().value ?? []);
|
||||
}
|
||||
|
||||
formattedValue() {
|
||||
return (this.data().value ?? [])
|
||||
.filter(value => !!value.trim())
|
||||
.map(value => this.stringtemplateFormat.replace(/%\{value\}/gi, value))
|
||||
.join(this.stringtemplateSeparator ?? '');
|
||||
}
|
||||
|
||||
getItems() {
|
||||
return Array.from(this.findAll('input'))
|
||||
.map(input => input.value)
|
||||
.filter(value => !!value.trim());
|
||||
}
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'submit .js-card-customfield-stringtemplate'(event) {
|
||||
event.preventDefault();
|
||||
const items = this.stringtemplateItems.get();
|
||||
this.card.setCustomField(this.customFieldId, items);
|
||||
},
|
||||
|
||||
'keydown .js-card-customfield-stringtemplate-item'(event) {
|
||||
if (event.keyCode === 13) {
|
||||
event.preventDefault();
|
||||
|
||||
if (event.target.value.trim() || event.metaKey || event.ctrlKey) {
|
||||
const inputLast = this.find('input.last');
|
||||
|
||||
let items = this.getItems();
|
||||
|
||||
if (event.target === inputLast) {
|
||||
inputLast.value = '';
|
||||
} else if (event.target.nextSibling === inputLast) {
|
||||
inputLast.focus();
|
||||
} else {
|
||||
event.target.blur();
|
||||
|
||||
const idx = Array.from(this.findAll('input')).indexOf(
|
||||
event.target,
|
||||
);
|
||||
items.splice(idx + 1, 0, '');
|
||||
|
||||
Tracker.afterFlush(() => {
|
||||
const element = this.findAll('input')[idx + 1];
|
||||
element.focus();
|
||||
element.value = '';
|
||||
});
|
||||
}
|
||||
|
||||
this.stringtemplateItems.set(items);
|
||||
}
|
||||
if (event.metaKey || event.ctrlKey) {
|
||||
this.find('button[type=submit]').click();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
'blur .js-card-customfield-stringtemplate-item'(event) {
|
||||
if (
|
||||
!event.target.value.trim() ||
|
||||
event.target === this.find('input.last')
|
||||
) {
|
||||
const items = this.getItems();
|
||||
this.stringtemplateItems.set(items);
|
||||
this.find('input.last').value = '';
|
||||
}
|
||||
},
|
||||
|
||||
'click .js-close-inlined-form'(event) {
|
||||
this.stringtemplateItems.set(this.data().value ?? []);
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
}.register('cardCustomField-stringtemplate'));
|
||||
@@ -0,0 +1,67 @@
|
||||
.card-date {
|
||||
display: block;
|
||||
border-radius: 4px;
|
||||
padding: 1px 3px;
|
||||
background-color: #dbdbdb;
|
||||
}
|
||||
.card-date:hover,
|
||||
.card-date.is-active {
|
||||
background-color: #b3b3b3;
|
||||
}
|
||||
.card-date.current,
|
||||
.card-date.almost-due,
|
||||
.card-date.due,
|
||||
.card-date.long-overdue {
|
||||
color: #fff;
|
||||
}
|
||||
.card-date.current {
|
||||
background-color: #5ba639;
|
||||
}
|
||||
.card-date.current:hover,
|
||||
.card-date.current.is-active {
|
||||
background-color: #46802c;
|
||||
}
|
||||
.card-date.almost-due {
|
||||
background-color: #edc909;
|
||||
}
|
||||
.card-date.almost-due:hover,
|
||||
.card-date.almost-due.is-active {
|
||||
background-color: #bc9f07;
|
||||
}
|
||||
.card-date.due {
|
||||
background-color: #fa3f00;
|
||||
}
|
||||
.card-date.due:hover,
|
||||
.card-date.due.is-active {
|
||||
background-color: #c73200;
|
||||
}
|
||||
.card-date.long-overdue {
|
||||
background-color: #fd5d47;
|
||||
}
|
||||
.card-date.long-overdue:hover,
|
||||
.card-date.long-overdue.is-active {
|
||||
background-color: #fd3e24;
|
||||
}
|
||||
.card-date.end-date time::before {
|
||||
content: "\f253";
|
||||
}
|
||||
.card-date.due-date time::before {
|
||||
content: "\f090";
|
||||
}
|
||||
.card-date.start-date time::before {
|
||||
content: "\f251";
|
||||
}
|
||||
.card-date.received-date time::before {
|
||||
content: "\f08b";
|
||||
}
|
||||
.card-date time::before {
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: inherit;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
.customfield-date {
|
||||
display: block;
|
||||
border-radius: 4px;
|
||||
padding: 1px 3px;
|
||||
}
|
||||
@@ -1,14 +1,20 @@
|
||||
template(name="dateBadge")
|
||||
if canModifyCard
|
||||
a.js-edit-date.card-date(title="{{showTitle}}" class="{{classes}}")
|
||||
a.js-edit-date.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
b
|
||||
| {{showWeek}}
|
||||
else
|
||||
a.card-date(title="{{showTitle}}" class="{{classes}}")
|
||||
a.card-date(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
b
|
||||
| {{showWeek}}
|
||||
|
||||
template(name="dateCustomField")
|
||||
a(title="{{showTitle}}" class="{{classes}}")
|
||||
a(title="{{showTitle}} {{_ 'predicate-week'}} {{showWeek}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
b
|
||||
| {{showWeek}}
|
||||
@@ -1,122 +1,6 @@
|
||||
// Helper function to replace HH with H for 24 hours format, because H allows also single-digit hours
|
||||
function adjustedTimeFormat() {
|
||||
return moment
|
||||
.localeData()
|
||||
.longDateFormat('LT')
|
||||
.replace(/HH/i, 'H');
|
||||
}
|
||||
|
||||
// Edit received, start, due & end dates
|
||||
BlazeComponent.extendComponent({
|
||||
template() {
|
||||
return 'editCardDate';
|
||||
},
|
||||
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
this.card = this.data();
|
||||
this.date = new ReactiveVar(moment.invalid());
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
const $picker = this.$('.js-datepicker')
|
||||
.datepicker({
|
||||
todayHighlight: true,
|
||||
todayBtn: 'linked',
|
||||
language: TAPi18n.getLanguage(),
|
||||
})
|
||||
.on(
|
||||
'changeDate',
|
||||
function(evt) {
|
||||
this.find('#date').value = moment(evt.date).format('L');
|
||||
this.error.set('');
|
||||
this.find('#time').focus();
|
||||
}.bind(this),
|
||||
);
|
||||
|
||||
if (this.date.get().isValid()) {
|
||||
$picker.datepicker('update', this.date.get().toDate());
|
||||
}
|
||||
},
|
||||
|
||||
showDate() {
|
||||
if (this.date.get().isValid()) return this.date.get().format('L');
|
||||
return '';
|
||||
},
|
||||
showTime() {
|
||||
if (this.date.get().isValid()) return this.date.get().format('LT');
|
||||
return '';
|
||||
},
|
||||
dateFormat() {
|
||||
return moment.localeData().longDateFormat('L');
|
||||
},
|
||||
timeFormat() {
|
||||
return moment.localeData().longDateFormat('LT');
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'keyup .js-date-field'() {
|
||||
// parse for localized date format in strict mode
|
||||
const dateMoment = moment(this.find('#date').value, 'L', true);
|
||||
if (dateMoment.isValid()) {
|
||||
this.error.set('');
|
||||
this.$('.js-datepicker').datepicker('update', dateMoment.toDate());
|
||||
}
|
||||
},
|
||||
'keyup .js-time-field'() {
|
||||
// parse for localized time format in strict mode
|
||||
const dateMoment = moment(
|
||||
this.find('#time').value,
|
||||
adjustedTimeFormat(),
|
||||
true,
|
||||
);
|
||||
if (dateMoment.isValid()) {
|
||||
this.error.set('');
|
||||
}
|
||||
},
|
||||
'submit .edit-date'(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
// if no time was given, init with 12:00
|
||||
const time =
|
||||
evt.target.time.value ||
|
||||
moment(new Date().setHours(12, 0, 0)).format('LT');
|
||||
const newTime = moment(time, adjustedTimeFormat(), true);
|
||||
const newDate = moment(evt.target.date.value, 'L', true);
|
||||
const dateString = `${evt.target.date.value} ${time}`;
|
||||
const newCompleteDate = moment(
|
||||
dateString,
|
||||
'L ' + adjustedTimeFormat(),
|
||||
true,
|
||||
);
|
||||
if (!newTime.isValid()) {
|
||||
this.error.set('invalid-time');
|
||||
evt.target.time.focus();
|
||||
}
|
||||
if (!newDate.isValid()) {
|
||||
this.error.set('invalid-date');
|
||||
evt.target.date.focus();
|
||||
}
|
||||
if (newCompleteDate.isValid()) {
|
||||
this._storeDate(newCompleteDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
if (!this.error) {
|
||||
this.error.set('invalid');
|
||||
}
|
||||
}
|
||||
},
|
||||
'click .js-delete-date'(evt) {
|
||||
evt.preventDefault();
|
||||
this._deleteDate();
|
||||
Popup.close();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
});
|
||||
import moment from 'moment/min/moment-with-locales';
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
import { DatePicker } from '/client/lib/datepicker';
|
||||
|
||||
Template.dateBadge.helpers({
|
||||
canModifyCard() {
|
||||
@@ -142,7 +26,7 @@ Template.dateBadge.helpers({
|
||||
}
|
||||
|
||||
_deleteDate() {
|
||||
this.card.setReceived(null);
|
||||
this.card.unsetReceived();
|
||||
}
|
||||
}.register('editCardReceivedDatePopup'));
|
||||
|
||||
@@ -168,7 +52,7 @@ Template.dateBadge.helpers({
|
||||
}
|
||||
|
||||
_deleteDate() {
|
||||
this.card.setStart(null);
|
||||
this.card.unsetStart();
|
||||
}
|
||||
}.register('editCardStartDatePopup'));
|
||||
|
||||
@@ -191,7 +75,7 @@ Template.dateBadge.helpers({
|
||||
}
|
||||
|
||||
_deleteDate() {
|
||||
this.card.setDue(null);
|
||||
this.card.unsetDue();
|
||||
}
|
||||
}.register('editCardDueDatePopup'));
|
||||
|
||||
@@ -214,7 +98,7 @@ Template.dateBadge.helpers({
|
||||
}
|
||||
|
||||
_deleteDate() {
|
||||
this.card.setEnd(null);
|
||||
this.card.unsetEnd();
|
||||
}
|
||||
}.register('editCardEndDatePopup'));
|
||||
|
||||
@@ -233,6 +117,10 @@ const CardDate = BlazeComponent.extendComponent({
|
||||
}, 60000);
|
||||
},
|
||||
|
||||
showWeek() {
|
||||
return this.date.get().week().toString();
|
||||
},
|
||||
|
||||
showDate() {
|
||||
// this will start working once mquandalle:moment
|
||||
// is updated to at least moment.js 2.10.5
|
||||
@@ -305,7 +193,7 @@ class CardStartDate extends CardDate {
|
||||
// if dueAt or endAt exist & are > startAt, startAt doesn't need to be flagged
|
||||
if ((endAt && theDate.isAfter(endAt)) || (dueAt && theDate.isAfter(dueAt)))
|
||||
classes += 'long-overdue';
|
||||
else if (theDate.isBefore(now, 'minute')) classes += 'almost-due';
|
||||
else if (theDate.isAfter(now)) classes += '';
|
||||
else classes += 'current';
|
||||
return classes;
|
||||
}
|
||||
@@ -402,12 +290,25 @@ class CardCustomFieldDate extends CardDate {
|
||||
});
|
||||
}
|
||||
|
||||
classes() {
|
||||
return 'customfield-date';
|
||||
showWeek() {
|
||||
return this.date.get().week().toString();
|
||||
}
|
||||
|
||||
showDate() {
|
||||
// this will start working once mquandalle:moment
|
||||
// is updated to at least moment.js 2.10.5
|
||||
// until then, the date is displayed in the "L" format
|
||||
return this.date.get().calendar(null, {
|
||||
sameElse: 'llll',
|
||||
});
|
||||
}
|
||||
|
||||
showTitle() {
|
||||
return '';
|
||||
return `${this.date.get().format('LLLL')}`;
|
||||
}
|
||||
|
||||
classes() {
|
||||
return 'customfield-date';
|
||||
}
|
||||
|
||||
events() {
|
||||
@@ -418,31 +319,31 @@ CardCustomFieldDate.register('cardCustomFieldDate');
|
||||
|
||||
(class extends CardReceivedDate {
|
||||
showDate() {
|
||||
return this.date.get().format('l');
|
||||
return this.date.get().format('L');
|
||||
}
|
||||
}.register('minicardReceivedDate'));
|
||||
|
||||
(class extends CardStartDate {
|
||||
showDate() {
|
||||
return this.date.get().format('l');
|
||||
return this.date.get().format('L');
|
||||
}
|
||||
}.register('minicardStartDate'));
|
||||
|
||||
(class extends CardDueDate {
|
||||
showDate() {
|
||||
return this.date.get().format('l');
|
||||
return this.date.get().format('L');
|
||||
}
|
||||
}.register('minicardDueDate'));
|
||||
|
||||
(class extends CardEndDate {
|
||||
showDate() {
|
||||
return this.date.get().format('l');
|
||||
return this.date.get().format('L');
|
||||
}
|
||||
}.register('minicardEndDate'));
|
||||
|
||||
(class extends CardCustomFieldDate {
|
||||
showDate() {
|
||||
return this.date.get().format('l');
|
||||
return this.date.get().format('L');
|
||||
}
|
||||
}.register('minicardCustomFieldDate'));
|
||||
|
||||
@@ -459,7 +360,7 @@ class VoteEndDate extends CardDate {
|
||||
return classes;
|
||||
}
|
||||
showDate() {
|
||||
return this.date.get().format('l LT');
|
||||
return this.date.get().format('L LT');
|
||||
}
|
||||
showTitle() {
|
||||
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
|
||||
@@ -472,3 +373,30 @@ class VoteEndDate extends CardDate {
|
||||
}
|
||||
}
|
||||
VoteEndDate.register('voteEndDate');
|
||||
|
||||
class PokerEndDate extends CardDate {
|
||||
onCreated() {
|
||||
super.onCreated();
|
||||
const self = this;
|
||||
self.autorun(() => {
|
||||
self.date.set(moment(self.data().getPokerEnd()));
|
||||
});
|
||||
}
|
||||
classes() {
|
||||
const classes = 'end-date' + ' ';
|
||||
return classes;
|
||||
}
|
||||
showDate() {
|
||||
return this.date.get().format('l LT');
|
||||
}
|
||||
showTitle() {
|
||||
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
|
||||
}
|
||||
|
||||
events() {
|
||||
return super.events().concat({
|
||||
'click .js-edit-date': Popup.open('editPokerEndDate'),
|
||||
});
|
||||
}
|
||||
}
|
||||
PokerEndDate.register('pokerEndDate');
|
||||
@@ -1,63 +0,0 @@
|
||||
.card-date
|
||||
display: block
|
||||
border-radius: 4px
|
||||
padding: 1px 3px
|
||||
|
||||
background-color: #dbdbdb
|
||||
&:hover, &.is-active
|
||||
background-color: #b3b3b3
|
||||
|
||||
&.current, &.almost-due, &.due, &.long-overdue
|
||||
color: #fff
|
||||
|
||||
&.current
|
||||
background-color: #5ba639
|
||||
&:hover, &.is-active
|
||||
background-color: darken(#5ba639, 10)
|
||||
|
||||
&.almost-due
|
||||
background-color: #edc909
|
||||
&:hover, &.is-active
|
||||
background-color: darken(#edc909, 10)
|
||||
|
||||
&.due
|
||||
background-color: #fa3f00
|
||||
&:hover, &.is-active
|
||||
background-color: darken(#fa3f00, 10)
|
||||
|
||||
&.long-overdue
|
||||
background-color: #fd5d47
|
||||
&:hover, &.is-active
|
||||
background-color: darken(#fd5d47, 7)
|
||||
|
||||
&.end-date
|
||||
time
|
||||
&::before
|
||||
content: "\f253" // symbol: fa-hourglass-end
|
||||
|
||||
&.due-date
|
||||
time
|
||||
&::before
|
||||
content: "\f090" // symbol: fa-sign-in
|
||||
|
||||
&.start-date
|
||||
time
|
||||
&::before
|
||||
content: "\f251" // symbol: fa-hourglass-start
|
||||
|
||||
&.received-date
|
||||
time
|
||||
&::before
|
||||
content: "\f08b" // symbol: fa-sign-out
|
||||
|
||||
time
|
||||
&::before
|
||||
font: normal normal normal 14px/1 FontAwesome
|
||||
font-size: inherit
|
||||
-webkit-font-smoothing: antialiased
|
||||
margin-right: 0.3em
|
||||
|
||||
.customfield-date
|
||||
display: block
|
||||
border-radius: 4px
|
||||
padding: 1px 3px
|
||||
@@ -0,0 +1,56 @@
|
||||
.new-description {
|
||||
position: relative;
|
||||
margin: 0 0 20px 0;
|
||||
}
|
||||
.new-description.is-open .helper {
|
||||
display: inline-block;
|
||||
}
|
||||
.new-description.is-open textarea {
|
||||
min-height: 100px;
|
||||
color: #4d4d4d;
|
||||
cursor: auto;
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.new-description .too-long {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.new-description textarea {
|
||||
background-color: #fff;
|
||||
border: 0;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.23);
|
||||
height: 36px;
|
||||
margin: 4px 4px 6px 0;
|
||||
padding: 9px 11px;
|
||||
width: 100%;
|
||||
}
|
||||
.new-description textarea:hover,
|
||||
.new-description textarea:is-open {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.33);
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.new-description textarea:is-open {
|
||||
cursor: auto;
|
||||
}
|
||||
.description-item {
|
||||
background-color: #fff;
|
||||
border: 0;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.23);
|
||||
color: #8c8c8c;
|
||||
height: 36px;
|
||||
margin: 4px 4px 6px 0;
|
||||
width: 92%;
|
||||
}
|
||||
.description-item:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
.description-item.add-description {
|
||||
display: flex;
|
||||
margin: 5px;
|
||||
}
|
||||
.description-item.add-description a {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
@@ -3,6 +3,7 @@ const descriptionFormIsOpen = new ReactiveVar(false);
|
||||
BlazeComponent.extendComponent({
|
||||
onDestroyed() {
|
||||
descriptionFormIsOpen.set(false);
|
||||
$('.note-popover').hide();
|
||||
},
|
||||
|
||||
descriptionFormIsOpen() {
|
||||
@@ -24,7 +25,10 @@ BlazeComponent.extendComponent({
|
||||
// Pressing Ctrl+Enter should submit the form
|
||||
'keydown form textarea'(evt) {
|
||||
if (evt.keyCode === 13 && (evt.metaKey || evt.ctrlKey)) {
|
||||
this.find('button[type=submit]').click();
|
||||
const submitButton = this.find('button[type=submit]');
|
||||
if (submitButton) {
|
||||
submitButton.click();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
.new-description
|
||||
position: relative
|
||||
margin: 0 0 20px 0
|
||||
|
||||
|
||||
&.is-open
|
||||
.helper
|
||||
display: inline-block
|
||||
|
||||
textarea
|
||||
min-height: 100px
|
||||
color: #4d4d4d
|
||||
cursor: auto
|
||||
overflow: hidden
|
||||
word-wrap: break-word
|
||||
|
||||
.too-long
|
||||
margin-top: 8px
|
||||
|
||||
textarea
|
||||
background-color: #fff
|
||||
border: 0
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .23)
|
||||
color: #8c8c8c
|
||||
height: 36px
|
||||
margin: 4px 4px 6px 0
|
||||
padding: 9px 11px
|
||||
width: 100%
|
||||
|
||||
&:hover,
|
||||
&:is-open
|
||||
background-color: #fff
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, .33)
|
||||
border: 0
|
||||
cursor: pointer
|
||||
|
||||
&:is-open
|
||||
cursor: auto
|
||||
|
||||
.description-item
|
||||
background-color: #fff
|
||||
border: 0
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .23)
|
||||
color: #8c8c8c
|
||||
height: 36px
|
||||
margin: 4px 4px 6px 0
|
||||
width: 92%
|
||||
|
||||
&:hover
|
||||
background: darken(white, 12%)
|
||||
|
||||
&.add-description
|
||||
display: flex
|
||||
margin: 5px
|
||||
|
||||
a
|
||||
display: block
|
||||
margin: auto
|
||||
@@ -0,0 +1,588 @@
|
||||
.assignee {
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
position: relative;
|
||||
float: left;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
margin: 0 4px 4px 0;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
z-index: 1;
|
||||
text-decoration: none;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.assignee .avatar {
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.assignee .avatar.avatar-assignee-initials {
|
||||
height: 70%;
|
||||
width: 70%;
|
||||
padding: 15%;
|
||||
background-color: #dbdbdb;
|
||||
color: #444;
|
||||
position: absolute;
|
||||
}
|
||||
.assignee .avatar.avatar-image {
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.assignee .assignee-presence-status {
|
||||
background-color: #b3b3b3;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 50%;
|
||||
height: 7px;
|
||||
width: 7px;
|
||||
position: absolute;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
border: 1px solid #fff;
|
||||
z-index: 15;
|
||||
}
|
||||
.assignee .assignee-presence-status.active {
|
||||
background: #64c464;
|
||||
border-color: #daf1da;
|
||||
}
|
||||
.assignee .assignee-presence-status.idle {
|
||||
background: #e4e467;
|
||||
border-color: #f7f7d4;
|
||||
}
|
||||
.assignee .assignee-presence-status.disconnected {
|
||||
background: #bdbdbd;
|
||||
border-color: #ededed;
|
||||
}
|
||||
.assignee .assignee-presence-status.pending {
|
||||
background: #e44242;
|
||||
border-color: #f1dada;
|
||||
}
|
||||
.assignee.add-assignee {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 0 0 2px #bfbfbf inset;
|
||||
}
|
||||
.assignee.add-assignee:hover,
|
||||
.assignee.add-assignee.is-active {
|
||||
box-shadow: 0 0 0 2px #666 inset;
|
||||
}
|
||||
.copied-tooltip {
|
||||
display: none;
|
||||
padding: 0px 10px;
|
||||
background-color: rgba(0,0,0,0.875);
|
||||
color: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.card-details {
|
||||
padding: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 600px;
|
||||
will-change: flex-basis;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
background: #f7f7f7;
|
||||
border-radius: bottom 3px;
|
||||
z-index: 20;
|
||||
animation: flexGrowIn 0.1s;
|
||||
box-shadow: 0 0 7px 0 #b3b3b3;
|
||||
transition: flex-basis 0.1s;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.card-details .mCustomScrollBox {
|
||||
padding-left: 0;
|
||||
}
|
||||
.card-details .card-details-canvas {
|
||||
width: auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
.card-details .card-details-header {
|
||||
margin: 0 -20px 5px;
|
||||
padding: 7px 20px;
|
||||
background: #ededed;
|
||||
border-bottom: 1px solid #dbdbdb;
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
z-index: 500;
|
||||
}
|
||||
.card-details .card-details-header .card-number {
|
||||
color: #b3b3b3;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.card-details .card-details-header .close-card-details,
|
||||
.card-details .card-details-header .maximize-card-details,
|
||||
.card-details .card-details-header .minimize-card-details,
|
||||
.card-details .card-details-header .card-details-menu,
|
||||
.card-details .card-details-header .card-copy-button,
|
||||
.card-details .card-details-header .card-copy-mobile-button,
|
||||
.card-details .card-details-header .close-card-details-mobile-web,
|
||||
.card-details .card-details-header .card-details-menu-mobile-web,
|
||||
.card-details .card-details-header .copied-tooltip {
|
||||
float: right;
|
||||
}
|
||||
.card-details .card-details-header .close-card-details,
|
||||
.card-details .card-details-header .maximize-card-details,
|
||||
.card-details .card-details-header .minimize-card-details {
|
||||
font-size: 24px;
|
||||
padding: 5px 10px 5px 10px;
|
||||
margin-right: -8px;
|
||||
}
|
||||
.card-details .card-details-header .close-card-details-mobile-web {
|
||||
font-size: 24px;
|
||||
padding: 5px;
|
||||
margin-right: 40px;
|
||||
}
|
||||
.card-details .card-details-header .card-copy-button {
|
||||
font-size: 17px;
|
||||
padding: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.card-details .card-details-header .card-copy-mobile-button {
|
||||
font-size: 17px;
|
||||
padding: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.card-details .card-details-header .card-details-menu {
|
||||
font-size: 17px;
|
||||
padding: 10px;
|
||||
}
|
||||
.card-details .card-details-header .card-details-menu-mobile-web {
|
||||
font-size: 17px;
|
||||
padding: 10px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
.card-details .card-details-header .card-details-watch {
|
||||
font-size: 17px;
|
||||
padding-left: 7px;
|
||||
color: #a6a6a6;
|
||||
}
|
||||
.card-details .card-details-header .card-details-title {
|
||||
font-weight: bold;
|
||||
font-size: 1.33em;
|
||||
margin: 7px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
.card-details .card-details-header .linked-card-location {
|
||||
font-style: italic;
|
||||
font-size: 1em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.card-details .card-details-header .linked-card-location p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.card-details .card-details-header form.inlined-form {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.card-details .card-details-header form.inlined-form .copied-tooltip {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
.card-details .card-details-header .card-details-list {
|
||||
font-size: 0.85em;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.card-details .card-details-header .card-details-list a.card-details-list-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
.card-details .card-details-header .card-details-list a.card-details-list-title.is-editable {
|
||||
display: inline-block;
|
||||
background: #e6e6e6;
|
||||
border-radius: 3px;
|
||||
padding: 0px 5px;
|
||||
}
|
||||
.card-details .card-details-header .copied-tooltip {
|
||||
margin-right: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
.card-details .card-description textarea {
|
||||
min-height: 100px;
|
||||
}
|
||||
.card-details .card-details-items {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.card-details .card-details-items .card-details-item {
|
||||
margin-right: 0.5em;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.card-details .card-details-items .card-details-item:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
.card-details .card-details-items .card-details-item.card-details-item-labels {
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
max-width: 95%;
|
||||
}
|
||||
.card-details .card-details-items .card-details-item.card-details-item-members,
|
||||
.card-details .card-details-items .card-details-item.card-details-item-assignees,
|
||||
.card-details .card-details-items .card-details-item.card-details-item-customfield,
|
||||
.card-details .card-details-items .card-details-item.card-details-item-name {
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
max-width: 36%;
|
||||
}
|
||||
.card-details .card-details-items .card-details-item.card-details-item-creator,
|
||||
.card-details .card-details-items .card-details-item.card-details-item-received,
|
||||
.card-details .card-details-items .card-details-item.card-details-item-start,
|
||||
.card-details .card-details-items .card-details-item.card-details-item-due,
|
||||
.card-details .card-details-items .card-details-item.card-details-item-end {
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
max-width: 28%;
|
||||
}
|
||||
.card-details .card-details-items .card-details-item.custom-fields {
|
||||
padding-left: 10px;
|
||||
}
|
||||
.card-details .card-details-item-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #4d4d4d;
|
||||
}
|
||||
.card-details .activities {
|
||||
padding-top: 10px;
|
||||
}
|
||||
@media screen and (min-width: 801px) {
|
||||
.card-details-maximized {
|
||||
padding: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: calc(100% - 20px);
|
||||
will-change: flex-basis;
|
||||
overflow-y: scroll;
|
||||
overflow-x: scroll;
|
||||
background: #f7f7f7;
|
||||
border-radius: bottom 3px;
|
||||
z-index: 100;
|
||||
animation: flexGrowIn 0.1s;
|
||||
box-shadow: 0 0 7px 0 #b3b3b3;
|
||||
transition: flex-basis 0.1s;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: calc(100% - 20px);
|
||||
width: calc(100% - 20px);
|
||||
float: left;
|
||||
}
|
||||
.card-details-maximized .card-details-left {
|
||||
float: left;
|
||||
top: 60px;
|
||||
left: 20px;
|
||||
width: 47%;
|
||||
border-right: solid 2px #dbdbdb;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.card-details-maximized .card-details-right {
|
||||
position: absolute;
|
||||
float: right;
|
||||
left: 50%;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.card-details-maximized .card-details-header {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
input[type="text"].attachment-add-link-input {
|
||||
float: left;
|
||||
margin: 0 0 8px;
|
||||
width: 80%;
|
||||
}
|
||||
input[type="submit"].attachment-add-link-submit {
|
||||
float: left;
|
||||
margin: 0 0 8px 4px;
|
||||
padding: 6px 12px;
|
||||
width: 18%;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.card-details {
|
||||
width: calc(100% - 1px);
|
||||
padding: 0px 20px 0px 20px;
|
||||
margin: 0px;
|
||||
transition: none;
|
||||
overflow-y: revert;
|
||||
overflow-x: revert;
|
||||
}
|
||||
.card-details .card-details-canvas {
|
||||
width: 100%;
|
||||
padding-left: 0px;
|
||||
}
|
||||
.card-details .card-details-header .close-card-details {
|
||||
margin-right: 0px;
|
||||
}
|
||||
.card-details .card-details-header .card-details-menu {
|
||||
margin-right: 40px;
|
||||
}
|
||||
.card-details .card-details-header .maximize-card-details {
|
||||
margin-right: 40px;
|
||||
}
|
||||
.card-details .card-details-header .minimize-card-details {
|
||||
margin-right: 40px;
|
||||
}
|
||||
.card-details-popup {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
.pop-over > .content-wrapper > .popup-container-depth-0 {
|
||||
width: 100%;
|
||||
}
|
||||
.pop-over > .content-wrapper > .popup-container-depth-0 > .content {
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
.pop-over > .content-wrapper > .popup-container-depth-0 > .content > .card-details-popup hr {
|
||||
margin: 15px 0px;
|
||||
}
|
||||
.pop-over > .content-wrapper > .popup-container-depth-0 .card-details-header {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.card-details-white {
|
||||
background: unset !important;
|
||||
color: #000 !important;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
.card-details-green {
|
||||
background: #3cb500 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-yellow {
|
||||
background: #fad900 !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-orange {
|
||||
background: #ff9f19 !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-red {
|
||||
background: #eb4646 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-purple {
|
||||
background: #a632db !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-blue {
|
||||
background: #0079bf !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-pink {
|
||||
background: #ff78cb !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-sky {
|
||||
background: #00c2e0 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-black {
|
||||
background: #4d4d4d !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-lime {
|
||||
background: #51e898 !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-silver {
|
||||
background: #c0c0c0 !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-peachpuff {
|
||||
background: #ffdab9 !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-crimson {
|
||||
background: #dc143c !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-plum {
|
||||
background: #dda0dd !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-darkgreen {
|
||||
background: #006400 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-slateblue {
|
||||
background: #6a5acd !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-magenta {
|
||||
background: #f0f !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-gold {
|
||||
background: #ffd700 !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-navy {
|
||||
background: #000080 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-gray {
|
||||
background: #808080 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-saddlebrown {
|
||||
background: #8b4513 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.card-details-paleturquoise {
|
||||
background: #afeeee !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-mistyrose {
|
||||
background: #ffe4e1 !important;
|
||||
color: #000 !important;
|
||||
}
|
||||
.card-details-indigo {
|
||||
background: #4b0082 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.voted {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.vote-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.vote-title .js-edit-date {
|
||||
align-self: baseline;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.vote-result {
|
||||
display: flex;
|
||||
}
|
||||
.js-show-positive-votes {
|
||||
cursor: pointer;
|
||||
}
|
||||
.poker-voted {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.poker-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.poker-title .js-edit-date {
|
||||
align-self: baseline;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.poker-result {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
}
|
||||
.js-show-positive-poker-votes {
|
||||
cursor: pointer;
|
||||
}
|
||||
.poker-deck {
|
||||
display: grid;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
.poker-card-result {
|
||||
width: 32px;
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
padding: 4px 2px 4px 2px;
|
||||
cursor: default;
|
||||
}
|
||||
.winner {
|
||||
font-weight: bold;
|
||||
outline: #2d2d2d solid 2px;
|
||||
}
|
||||
.loser {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.responsive-table {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.poker-table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.poker-table-row {
|
||||
display: table-row;
|
||||
}
|
||||
.poker-table-heading {
|
||||
background-color: #eee;
|
||||
display: table-header-group;
|
||||
}
|
||||
.poker-table-cell {
|
||||
display: table-cell;
|
||||
padding: 0 0 5px 2px;
|
||||
border-bottom: 1px solid #d2d0d0;
|
||||
text-align: center;
|
||||
min-width: 45px;
|
||||
}
|
||||
.poker-table-cell-who {
|
||||
width: 150px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.poker-table-heading-left,
|
||||
.poker-table-heading-right {
|
||||
display: table-header-group;
|
||||
font-weight: bold;
|
||||
border-top: 1px solid #808080;
|
||||
}
|
||||
@media (max-width: 400px) {
|
||||
.poker-table-heading-right {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.poker-table-body {
|
||||
display: table-row-group;
|
||||
}
|
||||
.poker-table-side-left,
|
||||
.poker-table-side-right {
|
||||
display: inline-block;
|
||||
}
|
||||
.poker-table-side-right {
|
||||
padding-left: 10px;
|
||||
}
|
||||
@media (max-width: 400px) {
|
||||
.poker-table-side-right {
|
||||
padding-left: 0px;
|
||||
}
|
||||
}
|
||||
.estimation-add {
|
||||
display: block;
|
||||
overflow: auto;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.estimation-add input {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin: auto;
|
||||
margin-right: 10px;
|
||||
width: 100px;
|
||||
}
|
||||
.estimation-add button {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
margin: auto;
|
||||
}
|
||||
.poker-card {
|
||||
width: 48px;
|
||||
height: 72px;
|
||||
float: left;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
display: table;
|
||||
box-sizing: border-box;
|
||||
padding: 5px;
|
||||
margin: 3px;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
text-shadow: #2d2d2d 1px 1px 0;
|
||||
box-shadow: 0 0 5px #aaa;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
.poker-card .inner {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
background-color: #cecece;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,358 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
// Assignee, code copied from wekan/client/users/userAvatar.styl
|
||||
|
||||
avatar-radius = 50%
|
||||
|
||||
#cardURL_copy
|
||||
// Have clipboard text not visible by moving it to far left
|
||||
position: absolute
|
||||
left: -2000px
|
||||
top: 0px
|
||||
|
||||
#clipboard
|
||||
white-space: normal
|
||||
|
||||
.assignee
|
||||
border-radius: 3px
|
||||
display: block
|
||||
position: relative
|
||||
float: left
|
||||
height: 30px
|
||||
width: @height
|
||||
margin: 0 4px 4px 0
|
||||
cursor: pointer
|
||||
user-select: none
|
||||
z-index: 1
|
||||
text-decoration: none
|
||||
border-radius: avatar-radius
|
||||
|
||||
.avatar
|
||||
overflow: hidden
|
||||
border-radius: avatar-radius
|
||||
|
||||
&.avatar-assignee-initials
|
||||
height: 70%
|
||||
width: @height
|
||||
padding: 15%
|
||||
background-color: #dbdbdb
|
||||
color: #444444
|
||||
position: absolute
|
||||
|
||||
&.avatar-image
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
height: 100%
|
||||
width: @height
|
||||
|
||||
.assignee-presence-status
|
||||
background-color: #b3b3b3
|
||||
border: 1px solid #fff
|
||||
border-radius: 50%
|
||||
height: 7px
|
||||
width: @height
|
||||
position: absolute
|
||||
right: -1px
|
||||
bottom: -1px
|
||||
border: 1px solid white
|
||||
z-index: 15
|
||||
|
||||
&.active
|
||||
background: #64c464
|
||||
border-color: #daf1da
|
||||
|
||||
&.idle
|
||||
background: #e4e467
|
||||
border-color: #f7f7d4
|
||||
|
||||
&.disconnected
|
||||
background: #bdbdbd
|
||||
border-color: #ededed
|
||||
|
||||
&.pending
|
||||
background: #e44242
|
||||
border-color: #f1dada
|
||||
|
||||
|
||||
|
||||
&.add-assignee
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
box-shadow: 0 0 0 2px darken(white, 25%) inset
|
||||
|
||||
&:hover, &.is-active
|
||||
box-shadow: 0 0 0 2px darken(white, 60%) inset
|
||||
|
||||
// Other card details
|
||||
|
||||
.card-details
|
||||
padding: 0
|
||||
flex-shrink: 0
|
||||
flex-basis: 600px
|
||||
will-change: flex-basis
|
||||
overflow-y: scroll
|
||||
overflow-x: hidden
|
||||
background: darken(white, 3%)
|
||||
border-radius: bottom 3px
|
||||
z-index: 20 !important
|
||||
animation: flexGrowIn 0.1s
|
||||
box-shadow: 0 0 7px 0 darken(white, 30%)
|
||||
transition: flex-basis 0.1s
|
||||
box-sizing: border-box
|
||||
|
||||
.mCustomScrollBox
|
||||
padding-left: 0
|
||||
|
||||
.card-details-canvas
|
||||
width: auto
|
||||
padding: 0 20px
|
||||
|
||||
.card-details-header
|
||||
margin: 0 -20px 5px
|
||||
padding 7px 20px
|
||||
background: darken(white, 7%)
|
||||
border-bottom: 1px solid darken(white, 14%)
|
||||
|
||||
.close-card-details,
|
||||
.card-details-menu,
|
||||
.card-copy-button,
|
||||
.card-copy-mobile-button,
|
||||
.close-card-details-mobile-web,
|
||||
.card-details-menu-mobile-web
|
||||
float: right
|
||||
|
||||
.close-card-details
|
||||
font-size: 24px
|
||||
padding: 5px
|
||||
margin-right: -8px
|
||||
|
||||
.close-card-details-mobile-web
|
||||
font-size: 24px
|
||||
padding: 5px
|
||||
margin-right: 40px
|
||||
|
||||
.card-copy-button
|
||||
font-size: 17px
|
||||
padding: 10px
|
||||
margin-right: 10px
|
||||
|
||||
.card-copy-mobile-button
|
||||
font-size: 17px
|
||||
padding: 10px
|
||||
margin-right: 10px
|
||||
|
||||
.card-details-menu
|
||||
font-size: 17px
|
||||
padding: 10px
|
||||
|
||||
.card-details-menu-mobile-web
|
||||
font-size: 17px
|
||||
padding: 10px
|
||||
margin-right: 30px
|
||||
|
||||
.card-details-watch
|
||||
font-size: 17px
|
||||
padding-left: 7px
|
||||
color: #a6a6a6
|
||||
|
||||
.card-details-title
|
||||
font-weight: bold
|
||||
font-size: 1.33em
|
||||
margin: 7px 0 0
|
||||
padding: 0
|
||||
|
||||
.linked-card-location
|
||||
font-style: italic
|
||||
font-size: 1em
|
||||
margin-bottom: 0
|
||||
& p
|
||||
margin-bottom: 0
|
||||
|
||||
form.inlined-form
|
||||
margin-top: 5px
|
||||
margin-bottom: 10px
|
||||
|
||||
.card-details-list
|
||||
font-size: 0.85em
|
||||
margin-bottom: 3px
|
||||
|
||||
a.card-details-list-title
|
||||
font-weight: bold
|
||||
|
||||
&.is-editable
|
||||
display: inline-block
|
||||
background: darken(white, 10%)
|
||||
border-radius: 3px
|
||||
padding: 0px 5px
|
||||
|
||||
.card-description textarea
|
||||
min-height: 100px
|
||||
|
||||
.card-details-items
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
margin: 15px 0
|
||||
|
||||
.card-details-item
|
||||
margin-right: 0.5em
|
||||
&:last-child
|
||||
margin-right: 0
|
||||
&.card-details-item-labels
|
||||
display: block
|
||||
word-wrap: break-word
|
||||
max-width: 95%
|
||||
flex-grow: 1
|
||||
&.card-details-item-members,
|
||||
&.card-details-item-assignees,
|
||||
&.card-details-item-customfield,
|
||||
&.card-details-item-name
|
||||
display: block
|
||||
word-wrap: break-word
|
||||
max-width: 36%
|
||||
flex-grow: 1
|
||||
&.card-details-item-received,
|
||||
&.card-details-item-start,
|
||||
&.card-details-item-due,
|
||||
&.card-details-item-end
|
||||
display: block
|
||||
word-wrap: break-word
|
||||
max-width: 28%
|
||||
flex-grow: 1
|
||||
|
||||
.card-details-item-title
|
||||
font-size: 16px
|
||||
font-weight: bold
|
||||
color: #4d4d4d
|
||||
|
||||
.card-label
|
||||
padding-top: 5px
|
||||
padding-bottom: 5px
|
||||
|
||||
.activities
|
||||
padding-top: 10px
|
||||
|
||||
input[type="text"].attachment-add-link-input
|
||||
float: left
|
||||
margin: 0 0 8px
|
||||
width: 80%
|
||||
|
||||
input[type="submit"].attachment-add-link-submit
|
||||
float: left
|
||||
margin: 0 0 8px 4px
|
||||
padding: 6px 12px
|
||||
width: 18%
|
||||
|
||||
@media screen and (max-width: 800px)
|
||||
.card-details
|
||||
width: calc(100% - 1px)
|
||||
padding: 0px 20px 0px 20px
|
||||
margin: 0px
|
||||
transition: none
|
||||
|
||||
.card-details-canvas
|
||||
width: 100%
|
||||
padding-left: 0px
|
||||
|
||||
.card-details-header
|
||||
.close-card-details
|
||||
margin-right: 0px
|
||||
|
||||
.card-details-menu
|
||||
margin-right: 10px
|
||||
|
||||
card-details-color(background, color...)
|
||||
background: background !important
|
||||
if color
|
||||
color: color !important //overwrite text for better visibility
|
||||
|
||||
.card-details-white
|
||||
card-details-color(unset, #000) //Black text for better visibility
|
||||
border: 1px solid #eee
|
||||
|
||||
.card-details-green
|
||||
card-details-color(#3cb500, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-yellow
|
||||
card-details-color(#fad900, #000) //Black text for better visibility
|
||||
|
||||
.card-details-orange
|
||||
card-details-color(#ff9f19, #000) //Black text for better visibility
|
||||
|
||||
.card-details-red
|
||||
card-details-color(#eb4646, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-purple
|
||||
card-details-color(#a632db, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-blue
|
||||
card-details-color(#0079bf, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-pink
|
||||
card-details-color(#ff78cb, #000) //Black text for better visibility
|
||||
|
||||
.card-details-sky
|
||||
card-details-color(#00c2e0, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-black
|
||||
card-details-color(#4d4d4d, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-lime
|
||||
card-details-color(#51e898, #000) //Black text for better visibility
|
||||
|
||||
.card-details-silver
|
||||
card-details-color(#c0c0c0, #000) //Black text for better visibility
|
||||
|
||||
.card-details-peachpuff
|
||||
card-details-color(#ffdab9, #000) //Black text for better visibility
|
||||
|
||||
.card-details-crimson
|
||||
card-details-color(#dc143c, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-plum
|
||||
card-details-color(#dda0dd, #000) //Black text for better visibility
|
||||
|
||||
.card-details-darkgreen
|
||||
card-details-color(#006400, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-slateblue
|
||||
card-details-color(#6a5acd, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-magenta
|
||||
card-details-color(#ff00ff, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-gold
|
||||
card-details-color(#ffd700, #000) //Black text for better visibility
|
||||
|
||||
.card-details-navy
|
||||
card-details-color(#000080, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-gray
|
||||
card-details-color(#808080, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-saddlebrown
|
||||
card-details-color(#8b4513, #ffffff) //White text for better visibility
|
||||
|
||||
.card-details-paleturquoise
|
||||
card-details-color(#afeeee, #000) //Black text for better visibility
|
||||
|
||||
.card-details-mistyrose
|
||||
card-details-color(#ffe4e1, #000) //Black text for better visibility
|
||||
|
||||
.card-details-indigo
|
||||
card-details-color(#4b0082, #ffffff) //White text for better visibility
|
||||
|
||||
.voted
|
||||
opacity: .7
|
||||
.vote-title
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
|
||||
.js-edit-date
|
||||
align-self: baseline
|
||||
margin-left: 5px
|
||||
|
||||
.vote-result
|
||||
display: flex
|
||||
.js-show-positive-votes
|
||||
cursor: pointer
|
||||
@@ -0,0 +1,18 @@
|
||||
.card-time {
|
||||
display: block;
|
||||
border-radius: 4px;
|
||||
padding: 1px 3px;
|
||||
color: #fff;
|
||||
background-color: #dbdbdb;
|
||||
}
|
||||
.card-time:hover,
|
||||
.card-time.is-active {
|
||||
background-color: #b3b3b3;
|
||||
}
|
||||
.card-time time::before {
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: inherit;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
content: "\f017";
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
template() {
|
||||
return 'editCardSpentTime';
|
||||
@@ -9,7 +11,6 @@ BlazeComponent.extendComponent({
|
||||
toggleOvertime() {
|
||||
this.card.setIsOvertime(!this.card.getIsOvertime());
|
||||
$('#overtime .materialCheckBox').toggleClass('is-checked');
|
||||
|
||||
$('#overtime').toggleClass('is-checked');
|
||||
},
|
||||
storeTime(spentTime, isOvertime) {
|
||||
@@ -18,6 +19,7 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
deleteTime() {
|
||||
this.card.setSpentTime(null);
|
||||
this.card.setIsOvertime(false);
|
||||
},
|
||||
events() {
|
||||
return [
|
||||
@@ -27,11 +29,14 @@ BlazeComponent.extendComponent({
|
||||
evt.preventDefault();
|
||||
|
||||
const spentTime = parseFloat(evt.target.time.value);
|
||||
const isOvertime = this.card.getIsOvertime();
|
||||
|
||||
//const isOvertime = this.card.getIsOvertime();
|
||||
let isOvertime = false;
|
||||
if ($('#overtime').attr('class').indexOf('is-checked') >= 0) {
|
||||
isOvertime = true;
|
||||
}
|
||||
if (spentTime >= 0) {
|
||||
this.storeTime(spentTime, isOvertime);
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
} else {
|
||||
this.error.set('invalid-time');
|
||||
evt.target.time.focus();
|
||||
@@ -40,7 +45,7 @@ BlazeComponent.extendComponent({
|
||||
'click .js-delete-time'(evt) {
|
||||
evt.preventDefault();
|
||||
this.deleteTime();
|
||||
Popup.close();
|
||||
Popup.back();
|
||||
},
|
||||
'click a.js-toggle-overtime': this.toggleOvertime,
|
||||
},
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
.card-time
|
||||
display: block
|
||||
border-radius: 4px
|
||||
padding: 1px 3px
|
||||
color: #fff
|
||||
|
||||
background-color: #dbdbdb
|
||||
&:hover, &.is-active
|
||||
background-color: #b3b3b3
|
||||
|
||||
time
|
||||
&::before
|
||||
font: normal normal normal 14px/1 FontAwesome
|
||||
font-size: inherit
|
||||
-webkit-font-smoothing: antialiased
|
||||
content: "\f017" // clock symbol
|
||||
margin-right: 0.3em
|
||||
@@ -0,0 +1,173 @@
|
||||
.js-add-checklist {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
textarea.js-add-checklist-item,
|
||||
textarea.js-edit-checklist-item {
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
resize: none;
|
||||
height: 34px;
|
||||
}
|
||||
.delete-text,
|
||||
.js-delete-checklist-item,
|
||||
.js-convert-checklist-item-to-card {
|
||||
color: #8c8c8c;
|
||||
text-decoration: underline;
|
||||
word-wrap: break-word;
|
||||
float: right;
|
||||
padding-top: 6px;
|
||||
}
|
||||
.delete-text:hover,
|
||||
.js-delete-checklist-item:hover,
|
||||
.js-convert-checklist-item-to-card:hover {
|
||||
color: inherit;
|
||||
}
|
||||
.checklists-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.checklist-progress-bar-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.checklist-progress-bar-container .checklist-progress-text {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.checklist-progress-bar-container .checklist-progress-bar {
|
||||
width: 80%;
|
||||
height: 10px;
|
||||
}
|
||||
.checklist-progress-bar-container .checklist-progress-bar .checklist-progress {
|
||||
color: #fff !important;
|
||||
background-color: #2196f3 !important;
|
||||
padding: 0.01em 16px;
|
||||
border-radius: 16px;
|
||||
height: 100%;
|
||||
}
|
||||
.checklist-title .checkbox {
|
||||
float: left;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: 18px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.checklist-title .title {
|
||||
font-size: 18px;
|
||||
line-height: 25px;
|
||||
}
|
||||
.checklist-title .checklist-stat {
|
||||
margin: 0 0.5em;
|
||||
float: right;
|
||||
padding-top: 6px;
|
||||
}
|
||||
.checklist-title .checklist-stat.is-finished {
|
||||
color: #3cb500;
|
||||
}
|
||||
.checklist-title span.fa.checklist-handle {
|
||||
padding-right: 20px;
|
||||
padding-top: 3px;
|
||||
float: left;
|
||||
}
|
||||
#card-details-overlay {
|
||||
top: 0;
|
||||
bottom: -600px;
|
||||
right: 0;
|
||||
}
|
||||
.checklist {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
.checklist.placeholder {
|
||||
background: #ccc;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.checklist.ui-sortable-helper {
|
||||
box-shadow: -2px 2px 8px rgba(0,0,0,0.3), 0 0 1px rgba(0,0,0,0.5);
|
||||
transform: rotate(4deg);
|
||||
cursor: grabbing;
|
||||
}
|
||||
.checklist-item {
|
||||
margin: 0 0 0 0.1em;
|
||||
line-height: 18px;
|
||||
font-size: 1.1em;
|
||||
margin-top: 3px;
|
||||
display: flex;
|
||||
background: #f7f7f7;
|
||||
opacity: 1;
|
||||
transition: height 0ms 400ms, opacity 400ms 0ms;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
.checklist-item.is-checked.invisible {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
transition: height 0ms 0ms, opacity 600ms 0ms;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.checklist-item.placeholder {
|
||||
background: #ccc;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.checklist-item.ui-sortable-helper {
|
||||
box-shadow: -2px 2px 8px rgba(0,0,0,0.3), 0 0 1px rgba(0,0,0,0.5);
|
||||
transform: rotate(4deg);
|
||||
cursor: grabbing;
|
||||
}
|
||||
.checklist-item:hover {
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
.checklist-item .check-box-container {
|
||||
padding-right: 10px;
|
||||
}
|
||||
.checklist-item .check-box {
|
||||
margin: 0.1em 0 0 0;
|
||||
}
|
||||
.checklist-item .check-box.is-checked {
|
||||
border-bottom: 2px solid #3cb500;
|
||||
border-right: 2px solid #3cb500;
|
||||
}
|
||||
.checklist-item .item-title {
|
||||
flex: 1;
|
||||
}
|
||||
.checklist-item .item-title.is-checked {
|
||||
color: #8c8c8c;
|
||||
font-style: italic;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.checklist-item .item-title .viewer p {
|
||||
margin-bottom: 2px;
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
max-width: 420px;
|
||||
}
|
||||
.checklist-item span.fa.checklistitem-handle {
|
||||
padding-top: 2px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.js-delete-checklist-item,
|
||||
.js-convert-checklist-item-to-card {
|
||||
margin: 0 0 0.5em 1.33em;
|
||||
padding: 12px 0 0 0;
|
||||
}
|
||||
.add-checklist-item {
|
||||
margin: 0.2em 0 0.5em 1.33em;
|
||||
}
|
||||
.add-checklist-item.js-open-inlined-form,
|
||||
.add-checklist.js-open-inlined-form {
|
||||
display: block;
|
||||
width: 50%;
|
||||
}
|
||||
.add-checklist-item.js-open-inlined-form:hover,
|
||||
.add-checklist.js-open-inlined-form:hover {
|
||||
background: #dbdbdb;
|
||||
color: #222;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
}
|
||||
.checklist-details-menu {
|
||||
float: right;
|
||||
padding: 6px 10px 6px 10px;
|
||||
}
|
||||
.edit-controls label.toggle-label {
|
||||
margin-left: 2px;
|
||||
}
|
||||
@@ -4,30 +4,24 @@ template(name="checklists")
|
||||
i.fa.fa-check
|
||||
| {{_ 'checklists'}}
|
||||
if currentUser.isBoardMember
|
||||
.material-toggle-switch
|
||||
span.toggle-switch-title {{_ 'hide-checked-items'}}
|
||||
.material-toggle-switch(title="{{_ 'hide-checked-items'}}")
|
||||
//span.toggle-switch-title
|
||||
if hideCheckedItems
|
||||
input.toggle-switch(type="checkbox" id="toggleHideCheckedItemsButton" checked="checked")
|
||||
else
|
||||
input.toggle-switch(type="checkbox" id="toggleHideCheckedItemsButton")
|
||||
label.toggle-label(for="toggleHideCheckedItemsButton")
|
||||
|
||||
if toggleDeleteDialog.get
|
||||
.board-overlay#card-details-overlay
|
||||
+checklistDeleteDialog(checklist = checklistToDelete)
|
||||
|
||||
|
||||
.card-checklist-items
|
||||
each checklist in currentCard.checklists
|
||||
each checklist in checklists
|
||||
+checklistDetail(checklist = checklist)
|
||||
|
||||
if canModifyCard
|
||||
+inlinedForm(autoclose=false classNames="js-add-checklist" cardId = cardId)
|
||||
+addChecklistItemForm
|
||||
+addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=false)
|
||||
else
|
||||
a.js-open-inlined-form
|
||||
a.add-checklist.js-open-inlined-form(title="{{_ 'add-checklist'}}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-checklist'}}...
|
||||
|
||||
template(name="checklistDetail")
|
||||
.js-checklist.checklist
|
||||
@@ -37,7 +31,7 @@ template(name="checklistDetail")
|
||||
.checklist-title
|
||||
span
|
||||
if canModifyCard
|
||||
a.js-delete-checklist.toggle-delete-checklist-dialog {{_ "delete"}}...
|
||||
a.fa.fa-navicon.checklist-details-menu.js-open-checklist-details-menu(title="{{_ 'checklistActionsPopup-title'}}")
|
||||
|
||||
if canModifyCard
|
||||
h2.title.js-open-inlined-form.is-editable
|
||||
@@ -49,27 +43,33 @@ template(name="checklistDetail")
|
||||
h2.title
|
||||
+viewer
|
||||
= checklist.title
|
||||
|
||||
if $gt finishedPercent 0
|
||||
.checklist-progress-bar-container
|
||||
.checklist-progress-text {{finishedPercent}}%
|
||||
.checklist-progress-bar
|
||||
.checklist-progress(style="width:{{finishedPercent}}%")
|
||||
+checklistItems(checklist = checklist)
|
||||
|
||||
template(name="checklistDeleteDialog")
|
||||
.js-confirm-checklist-delete
|
||||
p
|
||||
i(class="fa fa-exclamation-triangle" aria-hidden="true")
|
||||
p
|
||||
| {{_ 'confirm-checklist-delete-dialog'}}
|
||||
span {{checklist.title}}
|
||||
| ?
|
||||
.js-checklist-delete-buttons
|
||||
button.confirm-checklist-delete(type="button") {{_ 'delete'}}
|
||||
button.toggle-delete-checklist-dialog(type="button") {{_ 'cancel'}}
|
||||
template(name="checklistDeletePopup")
|
||||
p {{_ 'confirm-checklist-delete-popup'}}
|
||||
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
|
||||
|
||||
template(name="addChecklistItemForm")
|
||||
a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}")
|
||||
span.copied-tooltip {{_ 'copied'}}
|
||||
textarea.js-add-checklist-item(rows='1' autofocus)
|
||||
.edit-controls.clearfix
|
||||
button.primary.confirm.js-submit-add-checklist-item-form(type="submit") {{_ 'save'}}
|
||||
a.fa.fa-times-thin.js-close-inlined-form
|
||||
if showNewlineBecomesNewChecklistItem
|
||||
.material-toggle-switch(title="{{_ 'newlineBecomesNewChecklistItem'}}")
|
||||
input.toggle-switch(type="checkbox" id="toggleNewlineBecomesNewChecklistItem")
|
||||
label.toggle-label(for="toggleNewlineBecomesNewChecklistItem")
|
||||
|
||||
template(name="editChecklistItemForm")
|
||||
a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}")
|
||||
span.copied-tooltip {{_ 'copied'}}
|
||||
textarea.js-edit-checklist-item(rows='1' autofocus dir="auto")
|
||||
if $eq type 'item'
|
||||
= item.title
|
||||
@@ -81,6 +81,9 @@ template(name="editChecklistItemForm")
|
||||
span(title=createdAt) {{ moment createdAt }}
|
||||
if canModifyCard
|
||||
a.js-delete-checklist-item {{_ "delete"}}...
|
||||
a.js-convert-checklist-item-to-card
|
||||
i.fa.fa-copy
|
||||
| {{_ 'convertChecklistItemToCardPopup-title'}}
|
||||
|
||||
template(name="checklistItems")
|
||||
.checklist-items.js-checklist-items
|
||||
@@ -91,11 +94,10 @@ template(name="checklistItems")
|
||||
+checklistItemDetail(item = item checklist = checklist)
|
||||
if canModifyCard
|
||||
+inlinedForm(autoclose=false classNames="js-add-checklist-item" checklist = checklist)
|
||||
+addChecklistItemForm
|
||||
+addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=true)
|
||||
else
|
||||
a.add-checklist-item.js-open-inlined-form
|
||||
a.add-checklist-item.js-open-inlined-form(title="{{_ 'add-checklist-item'}}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-checklist-item'}}...
|
||||
|
||||
template(name='checklistItemDetail')
|
||||
.js-checklist-item.checklist-item(class="{{#if item.isFinished }}is-checked{{#if hideCheckedItems}} invisible{{/if}}{{/if}}")
|
||||
@@ -112,3 +114,79 @@ template(name='checklistItemDetail')
|
||||
.item-title(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
+viewer
|
||||
= item.title
|
||||
|
||||
template(name="convertChecklistItemToCardPopup")
|
||||
label(for='convert-checklist-item-to-card-title') {{_ 'title'}}:
|
||||
textarea#copy-card-title.minicard-composer-textarea.js-card-title(autofocus)
|
||||
= item.title
|
||||
+boardsSwimlanesAndLists
|
||||
|
||||
template(name="boardsSwimlanesAndLists")
|
||||
unless currentUser.isWorker
|
||||
label {{_ 'boards'}}:
|
||||
select.js-select-boards(autofocus)
|
||||
each boards
|
||||
if $eq _id currentBoard._id
|
||||
option(value="{{_id}}" selected) {{_ 'current'}}
|
||||
else
|
||||
option(value="{{_id}}") {{title}}
|
||||
|
||||
label {{_ 'swimlanes'}}:
|
||||
select.js-select-swimlanes
|
||||
each swimlanes
|
||||
option(value="{{_id}}") {{title}}
|
||||
|
||||
label {{_ 'lists'}}:
|
||||
select.js-select-lists
|
||||
each aBoardLists
|
||||
option(value="{{_id}}") {{title}}
|
||||
|
||||
.edit-controls.clearfix
|
||||
button.primary.confirm.js-done {{_ 'done'}}
|
||||
|
||||
template(name="checklistActionsPopup")
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.js-delete-checklist.delete-checklist
|
||||
i.fa.fa-trash
|
||||
| {{_ "delete"}} ...
|
||||
a.js-move-checklist.move-checklist
|
||||
i.fa.fa-arrow-right
|
||||
| {{_ "moveChecklist"}} ...
|
||||
a.js-copy-checklist.copy-checklist
|
||||
i.fa.fa-copy
|
||||
| {{_ "copyChecklist"}} ...
|
||||
|
||||
template(name="copyChecklistPopup")
|
||||
+copyAndMoveChecklist
|
||||
|
||||
template(name="moveChecklistPopup")
|
||||
+copyAndMoveChecklist
|
||||
|
||||
template(name="copyAndMoveChecklist")
|
||||
unless currentUser.isWorker
|
||||
label {{_ 'boards'}}:
|
||||
select.js-select-boards(autofocus)
|
||||
each boards
|
||||
if $eq _id currentBoard._id
|
||||
option(value="{{_id}}" selected) {{_ 'current'}}
|
||||
else
|
||||
option(value="{{_id}}" selected="{{#if isChecklistDialogOptionBoardId _id}}selected{{/if}}") {{title}}
|
||||
|
||||
label {{_ 'swimlanes'}}:
|
||||
select.js-select-swimlanes
|
||||
each swimlanes
|
||||
option(value="{{_id}}" selected="{{#if isChecklistDialogOptionSwimlaneId _id}}selected{{/if}}") {{title}}
|
||||
|
||||
label {{_ 'lists'}}:
|
||||
select.js-select-lists
|
||||
each lists
|
||||
option(value="{{_id}}" selected="{{#if isChecklistDialogOptionListId _id}}selected{{/if}}") {{title}}
|
||||
|
||||
label {{_ 'cards'}}:
|
||||
select.js-select-cards
|
||||
each cards
|
||||
option(value="{{_id}}" selected="{{#if isChecklistDialogOptionCardId _id}}selected{{/if}}") {{title}}
|
||||
|
||||
.edit-controls.clearfix
|
||||
button.primary.confirm.js-done {{_ 'done'}}
|
||||
@@ -1,3 +1,8 @@
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
import Cards from '/models/cards';
|
||||
import Boards from '/models/boards';
|
||||
|
||||
const subManager = new SubsManager();
|
||||
const { calculateIndexData, capitalize } = Utils;
|
||||
|
||||
function initSorting(items) {
|
||||
@@ -9,10 +14,10 @@ function initSorting(items) {
|
||||
appendTo: 'parent',
|
||||
distance: 7,
|
||||
placeholder: 'checklist-item placeholder',
|
||||
scroll: false,
|
||||
scroll: true,
|
||||
start(evt, ui) {
|
||||
ui.placeholder.height(ui.helper.height());
|
||||
EscapeActions.executeUpTo('popup-close');
|
||||
EscapeActions.clickExecute(evt.target, 'inlinedForm');
|
||||
},
|
||||
stop(evt, ui) {
|
||||
const parent = ui.item.parents('.js-checklist-items');
|
||||
@@ -51,7 +56,7 @@ BlazeComponent.extendComponent({
|
||||
return Meteor.user() && Meteor.user().isBoardMember();
|
||||
}
|
||||
|
||||
// Disable sorting if the current user is not a board member or is a miniscreen
|
||||
// Disable sorting if the current user is not a board member
|
||||
self.autorun(() => {
|
||||
const $itemsDom = $(self.itemsDom);
|
||||
if ($itemsDom.data('uiSortable') || $itemsDom.data('sortable')) {
|
||||
@@ -73,6 +78,12 @@ BlazeComponent.extendComponent({
|
||||
!Meteor.user().isWorker()
|
||||
);
|
||||
},
|
||||
|
||||
/** returns the finished percent of the checklist */
|
||||
finishedPercent() {
|
||||
const ret = this.data().checklist.finishedPercent();
|
||||
return ret;
|
||||
},
|
||||
}).register('checklistDetail');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
@@ -82,7 +93,8 @@ BlazeComponent.extendComponent({
|
||||
const title = textarea.value.trim();
|
||||
let cardId = this.currentData().cardId;
|
||||
const card = Cards.findOne(cardId);
|
||||
if (card.isLinked()) cardId = card.linkedId;
|
||||
//if (card.isLinked()) cardId = card.linkedId;
|
||||
if (card.isLinkedCard()) cardId = card.linkedId;
|
||||
|
||||
if (title) {
|
||||
Checklists.insert({
|
||||
@@ -90,29 +102,34 @@ BlazeComponent.extendComponent({
|
||||
title,
|
||||
sort: card.checklists().count(),
|
||||
});
|
||||
this.closeAllInlinedForms();
|
||||
setTimeout(() => {
|
||||
this.$('.add-checklist-item')
|
||||
.last()
|
||||
.click();
|
||||
}, 100);
|
||||
}
|
||||
textarea.value = '';
|
||||
textarea.focus();
|
||||
},
|
||||
|
||||
addChecklistItem(event) {
|
||||
event.preventDefault();
|
||||
const textarea = this.find('textarea.js-add-checklist-item');
|
||||
const newlineBecomesNewChecklistItem = this.find('input#toggleNewlineBecomesNewChecklistItem');
|
||||
const title = textarea.value.trim();
|
||||
const checklist = this.currentData().checklist;
|
||||
|
||||
if (title) {
|
||||
ChecklistItems.insert({
|
||||
title,
|
||||
checklistId: checklist._id,
|
||||
cardId: checklist.cardId,
|
||||
sort: Utils.calculateIndexData(checklist.lastItem()).base,
|
||||
});
|
||||
let checklistItems = [title];
|
||||
if (newlineBecomesNewChecklistItem.checked) {
|
||||
checklistItems = title.split('\n').map(_value => _value.trim());
|
||||
}
|
||||
for (let checklistItem of checklistItems) {
|
||||
ChecklistItems.insert({
|
||||
title: checklistItem,
|
||||
checklistId: checklist._id,
|
||||
cardId: checklist.cardId,
|
||||
sort: Utils.calculateIndexData(checklist.lastItem()).base,
|
||||
});
|
||||
}
|
||||
}
|
||||
// We keep the form opened, empty it.
|
||||
textarea.value = '';
|
||||
@@ -128,14 +145,6 @@ BlazeComponent.extendComponent({
|
||||
);
|
||||
},
|
||||
|
||||
deleteChecklist() {
|
||||
const checklist = this.currentData().checklist;
|
||||
if (checklist && checklist._id) {
|
||||
Checklists.remove(checklist._id);
|
||||
this.toggleDeleteDialog.set(false);
|
||||
}
|
||||
},
|
||||
|
||||
deleteItem() {
|
||||
const checklist = this.currentData().checklist;
|
||||
const item = this.currentData().item;
|
||||
@@ -161,11 +170,6 @@ BlazeComponent.extendComponent({
|
||||
item.setTitle(title);
|
||||
},
|
||||
|
||||
onCreated() {
|
||||
this.toggleDeleteDialog = new ReactiveVar(false);
|
||||
this.checklistToDelete = null; //Store data context to pass to checklistDeleteDialog template
|
||||
},
|
||||
|
||||
pressKey(event) {
|
||||
//If user press enter key inside a form, submit it
|
||||
//Unless the user is also holding down the 'shift' key
|
||||
@@ -186,14 +190,13 @@ BlazeComponent.extendComponent({
|
||||
}
|
||||
},
|
||||
|
||||
/** closes all inlined forms (checklist and checklist-item input fields) */
|
||||
closeAllInlinedForms() {
|
||||
this.$('.js-close-inlined-form').click();
|
||||
},
|
||||
|
||||
events() {
|
||||
const events = {
|
||||
'click .toggle-delete-checklist-dialog'(event) {
|
||||
if ($(event.target).hasClass('js-delete-checklist')) {
|
||||
this.checklistToDelete = this.currentData().checklist; //Store data context
|
||||
}
|
||||
this.toggleDeleteDialog.set(!this.toggleDeleteDialog.get());
|
||||
},
|
||||
'click #toggleHideCheckedItemsButton'() {
|
||||
Meteor.call('toggleHideCheckedItems');
|
||||
},
|
||||
@@ -202,20 +205,69 @@ BlazeComponent.extendComponent({
|
||||
return [
|
||||
{
|
||||
...events,
|
||||
'click .js-open-checklist-details-menu': Popup.open('checklistActions'),
|
||||
'submit .js-add-checklist': this.addChecklist,
|
||||
'submit .js-edit-checklist-title': this.editChecklist,
|
||||
'submit .js-add-checklist-item': this.addChecklistItem,
|
||||
'submit .js-edit-checklist-item': this.editChecklistItem,
|
||||
'click .js-convert-checklist-item-to-card': Popup.open('convertChecklistItemToCard'),
|
||||
'click .js-delete-checklist-item': this.deleteItem,
|
||||
'click .confirm-checklist-delete': this.deleteChecklist,
|
||||
'focus .js-add-checklist-item': this.focusChecklistItem,
|
||||
// add and delete checklist / checklist-item
|
||||
'click .js-open-inlined-form': this.closeAllInlinedForms,
|
||||
keydown: this.pressKey,
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('checklists');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
subManager.subscribe('board', Session.get('currentBoard'), false);
|
||||
this.selectedBoardId = new ReactiveVar(Session.get('currentBoard'));
|
||||
},
|
||||
|
||||
boards() {
|
||||
return Boards.find(
|
||||
{
|
||||
archived: false,
|
||||
'members.userId': Meteor.userId(),
|
||||
_id: { $ne: Meteor.user().getTemplatesBoardId() },
|
||||
},
|
||||
{
|
||||
sort: { sort: 1 /* boards default sorting */ },
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
swimlanes() {
|
||||
const board = Boards.findOne(this.selectedBoardId.get());
|
||||
return board.swimlanes();
|
||||
},
|
||||
|
||||
aBoardLists() {
|
||||
const board = Boards.findOne(this.selectedBoardId.get());
|
||||
return board.lists();
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'change .js-select-boards'(event) {
|
||||
this.selectedBoardId.set($(event.currentTarget).val());
|
||||
subManager.subscribe('board', this.selectedBoardId.get(), false);
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('boardsSwimlanesAndLists');
|
||||
|
||||
Template.checklists.helpers({
|
||||
checklists() {
|
||||
const card = Cards.findOne(this.cardId);
|
||||
const ret = card.checklists();
|
||||
return ret;
|
||||
},
|
||||
hideCheckedItems() {
|
||||
const currentUser = Meteor.user();
|
||||
if (currentUser) return currentUser.hasHideCheckedItems();
|
||||
@@ -223,39 +275,77 @@ Template.checklists.helpers({
|
||||
},
|
||||
});
|
||||
|
||||
Template.addChecklistItemForm.onRendered(() => {
|
||||
autosize($('textarea.js-add-checklist-item'));
|
||||
});
|
||||
BlazeComponent.extendComponent({
|
||||
onRendered() {
|
||||
autosize(this.$('textarea.js-add-checklist-item'));
|
||||
},
|
||||
canModifyCard() {
|
||||
return (
|
||||
Meteor.user() &&
|
||||
Meteor.user().isBoardMember() &&
|
||||
!Meteor.user().isCommentOnly() &&
|
||||
!Meteor.user().isWorker()
|
||||
);
|
||||
},
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click a.fa.fa-copy'(event) {
|
||||
const $editor = this.$('textarea');
|
||||
const promise = Utils.copyTextToClipboard($editor[0].value);
|
||||
|
||||
Template.editChecklistItemForm.onRendered(() => {
|
||||
autosize($('textarea.js-edit-checklist-item'));
|
||||
});
|
||||
const $tooltip = this.$('.copied-tooltip');
|
||||
Utils.showCopied(promise, $tooltip);
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
}).register('addChecklistItemForm');
|
||||
|
||||
Template.checklistDeleteDialog.onCreated(() => {
|
||||
const $cardDetails = this.$('.card-details');
|
||||
this.scrollState = {
|
||||
position: $cardDetails.scrollTop(), //save current scroll position
|
||||
top: false, //required for smooth scroll animation
|
||||
};
|
||||
//Callback's purpose is to only prevent scrolling after animation is complete
|
||||
$cardDetails.animate({ scrollTop: 0 }, 500, () => {
|
||||
this.scrollState.top = true;
|
||||
});
|
||||
BlazeComponent.extendComponent({
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-delete-checklist' : Popup.afterConfirm('checklistDelete', function () {
|
||||
Popup.back(2);
|
||||
const checklist = this.checklist;
|
||||
if (checklist && checklist._id) {
|
||||
Checklists.remove(checklist._id);
|
||||
}
|
||||
}),
|
||||
'click .js-move-checklist' : Popup.open('moveChecklist'),
|
||||
'click .js-copy-checklist' : Popup.open('copyChecklist'),
|
||||
}
|
||||
]
|
||||
}
|
||||
}).register('checklistActionsPopup');
|
||||
|
||||
//Prevent scrolling while dialog is open
|
||||
$cardDetails.on('scroll', () => {
|
||||
if (this.scrollState.top) {
|
||||
//If it's already in position, keep it there. Otherwise let animation scroll
|
||||
$cardDetails.scrollTop(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
BlazeComponent.extendComponent({
|
||||
onRendered() {
|
||||
autosize(this.$('textarea.js-edit-checklist-item'));
|
||||
},
|
||||
canModifyCard() {
|
||||
return (
|
||||
Meteor.user() &&
|
||||
Meteor.user().isBoardMember() &&
|
||||
!Meteor.user().isCommentOnly() &&
|
||||
!Meteor.user().isWorker()
|
||||
);
|
||||
},
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click a.fa.fa-copy'(event) {
|
||||
const $editor = this.$('textarea');
|
||||
const promise = Utils.copyTextToClipboard($editor[0].value);
|
||||
|
||||
Template.checklistDeleteDialog.onDestroyed(() => {
|
||||
const $cardDetails = this.$('.card-details');
|
||||
$cardDetails.off('scroll'); //Reactivate scrolling
|
||||
$cardDetails.animate({ scrollTop: this.scrollState.position });
|
||||
});
|
||||
const $tooltip = this.$('.copied-tooltip');
|
||||
Utils.showCopied(promise, $tooltip);
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
}).register('editChecklistItemForm');
|
||||
|
||||
Template.checklistItemDetail.helpers({
|
||||
canModifyCard() {
|
||||
@@ -289,3 +379,231 @@ BlazeComponent.extendComponent({
|
||||
];
|
||||
},
|
||||
}).register('checklistItemDetail');
|
||||
|
||||
class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
|
||||
/** returns the checklist dialog options
|
||||
* @return Object with properties { boardId, swimlaneId, listId, cardId }
|
||||
*/
|
||||
getChecklistDialogOptions() {
|
||||
}
|
||||
|
||||
/** checklist is done
|
||||
* @param cardId the selected card id
|
||||
* @param options the selected options (Object with properties { boardId, swimlaneId, listId, cardId })
|
||||
*/
|
||||
setDone(cardId, options) {
|
||||
}
|
||||
|
||||
onCreated() {
|
||||
this.currentBoardId = Utils.getCurrentBoardId();
|
||||
this.selectedBoardId = new ReactiveVar(this.currentBoardId);
|
||||
this.selectedSwimlaneId = new ReactiveVar('');
|
||||
this.selectedListId = new ReactiveVar('');
|
||||
this.setChecklistDialogOption(this.currentBoardId);
|
||||
}
|
||||
|
||||
/** set the last confirmed dialog field values
|
||||
* @param boardId the current board id
|
||||
*/
|
||||
setChecklistDialogOption(boardId) {
|
||||
this.checklistDialogOption = {
|
||||
'boardId' : "",
|
||||
'swimlaneId' : "",
|
||||
'listId' : "",
|
||||
'cardId': "",
|
||||
}
|
||||
|
||||
let currentOptions = this.getChecklistDialogOptions();
|
||||
if (currentOptions && boardId && currentOptions[boardId]) {
|
||||
this.checklistDialogOption = currentOptions[boardId];
|
||||
if (this.checklistDialogOption.boardId &&
|
||||
this.checklistDialogOption.swimlaneId &&
|
||||
this.checklistDialogOption.listId
|
||||
)
|
||||
{
|
||||
this.selectedBoardId.set(this.checklistDialogOption.boardId)
|
||||
this.selectedSwimlaneId.set(this.checklistDialogOption.swimlaneId);
|
||||
this.selectedListId.set(this.checklistDialogOption.listId);
|
||||
}
|
||||
}
|
||||
this.getBoardData(this.selectedBoardId.get());
|
||||
if (!this.selectedSwimlaneId.get() || !Swimlanes.findOne({_id: this.selectedSwimlaneId.get(), boardId: this.selectedBoardId.get()})) {
|
||||
this.setFirstSwimlaneId();
|
||||
}
|
||||
if (!this.selectedListId.get() || !Lists.findOne({_id: this.selectedListId.get(), boardId: this.selectedBoardId.get()})) {
|
||||
this.setFirstListId();
|
||||
}
|
||||
}
|
||||
/** sets the first swimlane id */
|
||||
setFirstSwimlaneId() {
|
||||
try {
|
||||
const board = Boards.findOne(this.selectedBoardId.get());
|
||||
const swimlaneId = board.swimlanes().fetch()[0]._id;
|
||||
this.selectedSwimlaneId.set(swimlaneId);
|
||||
} catch (e) {}
|
||||
}
|
||||
/** sets the first list id */
|
||||
setFirstListId() {
|
||||
try {
|
||||
const board = Boards.findOne(this.selectedBoardId.get());
|
||||
const listId = board.lists().fetch()[0]._id;
|
||||
this.selectedListId.set(listId);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
/** returns if the board id was the last confirmed one
|
||||
* @param boardId check this board id
|
||||
* @return if the board id was the last confirmed one
|
||||
*/
|
||||
isChecklistDialogOptionBoardId(boardId) {
|
||||
let ret = this.checklistDialogOption.boardId == boardId;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** returns if the swimlane id was the last confirmed one
|
||||
* @param swimlaneId check this swimlane id
|
||||
* @return if the swimlane id was the last confirmed one
|
||||
*/
|
||||
isChecklistDialogOptionSwimlaneId(swimlaneId) {
|
||||
let ret = this.checklistDialogOption.swimlaneId == swimlaneId;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** returns if the list id was the last confirmed one
|
||||
* @param listId check this list id
|
||||
* @return if the list id was the last confirmed one
|
||||
*/
|
||||
isChecklistDialogOptionListId(listId) {
|
||||
let ret = this.checklistDialogOption.listId == listId;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** returns if the card id was the last confirmed one
|
||||
* @param cardId check this card id
|
||||
* @return if the card id was the last confirmed one
|
||||
*/
|
||||
isChecklistDialogOptionCardId(cardId) {
|
||||
let ret = this.checklistDialogOption.cardId == cardId;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** returns all available board */
|
||||
boards() {
|
||||
const ret = Boards.find(
|
||||
{
|
||||
archived: false,
|
||||
'members.userId': Meteor.userId(),
|
||||
_id: { $ne: Meteor.user().getTemplatesBoardId() },
|
||||
},
|
||||
{
|
||||
sort: { sort: 1 },
|
||||
},
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** returns all available swimlanes of the current board */
|
||||
swimlanes() {
|
||||
const board = Boards.findOne(this.selectedBoardId.get());
|
||||
const ret = board.swimlanes();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** returns all available lists of the current board */
|
||||
lists() {
|
||||
const board = Boards.findOne(this.selectedBoardId.get());
|
||||
const ret = board.lists();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** returns all available cards of the current list */
|
||||
cards() {
|
||||
const list = Lists.findOne(this.selectedListId.get());
|
||||
const ret = list.cards(this.selectedSwimlaneId.get());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** get the board data from the server
|
||||
* @param boardId get the board data of this board id
|
||||
*/
|
||||
getBoardData(boardId) {
|
||||
const self = this;
|
||||
Meteor.subscribe('board', boardId, false, {
|
||||
onReady() {
|
||||
const sameBoardId = self.selectedBoardId.get() == boardId;
|
||||
self.selectedBoardId.set(boardId);
|
||||
|
||||
if (!sameBoardId) {
|
||||
// reset swimlane id (for selection in cards())
|
||||
self.setFirstSwimlaneId();
|
||||
|
||||
// reset list id (for selection in cards())
|
||||
self.setFirstListId();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-done'() {
|
||||
const boardSelect = this.$('.js-select-boards')[0];
|
||||
const boardId = boardSelect.options[boardSelect.selectedIndex].value;
|
||||
|
||||
const listSelect = this.$('.js-select-lists')[0];
|
||||
const listId = listSelect.options[listSelect.selectedIndex].value;
|
||||
|
||||
const swimlaneSelect = this.$('.js-select-swimlanes')[0];
|
||||
const swimlaneId = swimlaneSelect.options[swimlaneSelect.selectedIndex].value;
|
||||
|
||||
const cardSelect = this.$('.js-select-cards')[0];
|
||||
const cardId = cardSelect.options[cardSelect.selectedIndex].value;
|
||||
|
||||
const options = {
|
||||
'boardId' : boardId,
|
||||
'swimlaneId' : swimlaneId,
|
||||
'listId' : listId,
|
||||
'cardId': cardId,
|
||||
}
|
||||
this.setDone(cardId, options);
|
||||
Popup.back(2);
|
||||
},
|
||||
'change .js-select-boards'(event) {
|
||||
const boardId = $(event.currentTarget).val();
|
||||
this.getBoardData(boardId);
|
||||
},
|
||||
'change .js-select-swimlanes'(event) {
|
||||
this.selectedSwimlaneId.set($(event.currentTarget).val());
|
||||
},
|
||||
'change .js-select-lists'(event) {
|
||||
this.selectedListId.set($(event.currentTarget).val());
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/** Move Checklist Dialog */
|
||||
(class extends DialogWithBoardSwimlaneListAndCard {
|
||||
getChecklistDialogOptions() {
|
||||
const ret = Meteor.user().getMoveChecklistDialogOptions();
|
||||
return ret;
|
||||
}
|
||||
setDone(cardId, options) {
|
||||
Meteor.user().setMoveChecklistDialogOption(this.currentBoardId, options);
|
||||
this.data().checklist.move(cardId);
|
||||
}
|
||||
}).register('moveChecklistPopup');
|
||||
|
||||
/** Copy Checklist Dialog */
|
||||
(class extends DialogWithBoardSwimlaneListAndCard {
|
||||
getChecklistDialogOptions() {
|
||||
const ret = Meteor.user().getCopyChecklistDialogOptions();
|
||||
return ret;
|
||||
}
|
||||
setDone(cardId, options) {
|
||||
Meteor.user().setCopyChecklistDialogOption(this.currentBoardId, options);
|
||||
this.data().checklist.copy(cardId);
|
||||
}
|
||||
}).register('copyChecklistPopup');
|
||||
@@ -1,169 +0,0 @@
|
||||
.js-add-checklist
|
||||
color: #8c8c8c
|
||||
|
||||
textarea.js-add-checklist-item, textarea.js-edit-checklist-item
|
||||
overflow: hidden
|
||||
word-wrap: break-word
|
||||
resize: none
|
||||
height: 34px
|
||||
|
||||
.delete-text
|
||||
color: #8c8c8c
|
||||
text-decoration: underline
|
||||
word-wrap: break-word
|
||||
float: right
|
||||
padding-top: 6px
|
||||
&:hover
|
||||
color: inherit
|
||||
|
||||
.checklists-title
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
|
||||
.checklist-title
|
||||
.checkbox
|
||||
float: left
|
||||
width: 30px
|
||||
height 30px
|
||||
font-size: 18px
|
||||
line-height: 30px
|
||||
|
||||
.title
|
||||
font-size: 18px
|
||||
line-height: 25px
|
||||
|
||||
.checklist-stat
|
||||
margin: 0 0.5em
|
||||
float: right
|
||||
padding-top: 6px
|
||||
&.is-finished
|
||||
color: #3cb500
|
||||
|
||||
.js-delete-checklist
|
||||
@extends .delete-text
|
||||
|
||||
span.fa.checklist-handle
|
||||
padding-right: 20px
|
||||
padding-top: 3px
|
||||
float: left
|
||||
|
||||
|
||||
.js-confirm-checklist-delete
|
||||
background-color: darken(white, 3%)
|
||||
position: absolute
|
||||
float: left;
|
||||
width: 60%
|
||||
margin-top: 0
|
||||
margin-left: 13%
|
||||
padding-bottom: 2%
|
||||
padding-left: 3%
|
||||
padding-right: 3%
|
||||
z-index: 17
|
||||
border-radius: 3px
|
||||
|
||||
p
|
||||
position: relative
|
||||
margin-top: 3%
|
||||
width: 100%
|
||||
text-align: center
|
||||
span
|
||||
font-weight: bold
|
||||
|
||||
i
|
||||
font-size: 2em
|
||||
|
||||
.js-checklist-delete-buttons
|
||||
position: relative
|
||||
padding: left 2% right 2%
|
||||
.confirm-checklist-delete
|
||||
margin-left: 12%
|
||||
float: left
|
||||
.toggle-delete-checklist-dialog
|
||||
margin-right: 12%
|
||||
float: right
|
||||
|
||||
#card-details-overlay
|
||||
top: 0
|
||||
bottom: -600px
|
||||
right: 0
|
||||
|
||||
.checklist
|
||||
background: darken(white, 3%)
|
||||
|
||||
&.placeholder
|
||||
background: darken(white, 20%)
|
||||
border-radius: 2px
|
||||
|
||||
&.ui-sortable-helper
|
||||
box-shadow: -2px 2px 8px rgba(0, 0, 0, .3),
|
||||
0 0 1px rgba(0, 0, 0, .5)
|
||||
transform: rotate(4deg)
|
||||
cursor: grabbing
|
||||
|
||||
|
||||
.checklist-item
|
||||
margin: 0 0 0 0.1em
|
||||
line-height: 18px
|
||||
font-size: 1.1em
|
||||
margin-top: 3px
|
||||
display: flex
|
||||
background: darken(white, 3%)
|
||||
opacity: 1
|
||||
transition: height 0ms 400ms, opacity 400ms 0ms
|
||||
height: auto
|
||||
overflow: hidden
|
||||
|
||||
&.is-checked.invisible
|
||||
opacity: 0
|
||||
height: 0
|
||||
transition: height 0ms 0ms, opacity 600ms 0ms
|
||||
margin-top: 0
|
||||
margin-bottom: 0
|
||||
|
||||
&.placeholder
|
||||
background: darken(white, 20%)
|
||||
border-radius: 2px
|
||||
|
||||
&.ui-sortable-helper
|
||||
box-shadow: -2px 2px 8px rgba(0, 0, 0, .3),
|
||||
0 0 1px rgba(0, 0, 0, .5)
|
||||
transform: rotate(4deg)
|
||||
cursor: grabbing
|
||||
|
||||
&:hover
|
||||
background-color: darken(white, 8%)
|
||||
|
||||
.check-box-container
|
||||
padding-right: 10px;
|
||||
|
||||
.check-box
|
||||
margin: 0.1em 0 0 0;
|
||||
&.is-checked
|
||||
border-bottom: 2px solid #3cb500
|
||||
border-right: 2px solid #3cb500
|
||||
|
||||
.item-title
|
||||
flex: 1
|
||||
&.is-checked
|
||||
color: #8c8c8c
|
||||
font-style: italic
|
||||
text-decoration: line-through
|
||||
& .viewer
|
||||
p
|
||||
margin-bottom: 2px
|
||||
display: block
|
||||
word-wrap: break-word
|
||||
max-width: 420px
|
||||
|
||||
span.fa.checklistitem-handle
|
||||
padding-top: 2px
|
||||
padding-right: 10px;
|
||||
|
||||
.js-delete-checklist-item
|
||||
margin: 0 0 0.5em 1.33em
|
||||
@extends .delete-text
|
||||
padding: 12px 0 0 0
|
||||
|
||||
.add-checklist-item
|
||||
margin: 0.2em 0 0.5em 1.33em
|
||||
display: inline-block
|
||||
@@ -0,0 +1,230 @@
|
||||
.card-label {
|
||||
border: 1px solid #000;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
margin-right: 4px;
|
||||
margin-bottom: 5px;
|
||||
padding: 3px 8px;
|
||||
max-width: 210px;
|
||||
min-width: 8px;
|
||||
word-wrap: break-word;
|
||||
min-height: 18px;
|
||||
vertical-align: middle;
|
||||
white-space: initial;
|
||||
overflow: initial;
|
||||
}
|
||||
.card-label:hover {
|
||||
color: #fff;
|
||||
}
|
||||
.card-label.square {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
padding: 0;
|
||||
}
|
||||
.card-label.add-label {
|
||||
box-shadow: 0 0 0 2px #bfbfbf inset;
|
||||
border: initial;
|
||||
}
|
||||
.card-label.add-label:hover,
|
||||
.card-label.add-label.is-active {
|
||||
box-shadow: 0 0 0 2px #666 inset;
|
||||
}
|
||||
.card-label p {
|
||||
margin: 0px;
|
||||
}
|
||||
.palette-colors {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.palette-colors .palette-color {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.card-label-white {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-white:hover {
|
||||
color: #aaa;
|
||||
}
|
||||
.card-label-green {
|
||||
background-color: #3cb500;
|
||||
}
|
||||
.card-label-green:hover {
|
||||
color: #000;
|
||||
}
|
||||
.card-label-yellow {
|
||||
background-color: #fad900;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-orange {
|
||||
background-color: #ff9f19;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-red {
|
||||
background-color: #eb4646;
|
||||
}
|
||||
.card-label-purple {
|
||||
background-color: #a632db;
|
||||
}
|
||||
.card-label-blue {
|
||||
background-color: #0079bf;
|
||||
}
|
||||
.card-label-pink {
|
||||
background-color: #ff78cb;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-sky {
|
||||
background-color: #00c2e0;
|
||||
}
|
||||
.card-label-black {
|
||||
background-color: #4d4d4d;
|
||||
}
|
||||
.card-label-lime {
|
||||
background-color: #51e898;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-silver {
|
||||
background-color: #c0c0c0;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-peachpuff {
|
||||
background-color: #ffdab9;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-crimson {
|
||||
background-color: #dc143c;
|
||||
}
|
||||
.card-label-plum {
|
||||
background-color: #dda0dd;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-darkgreen {
|
||||
background-color: #006400;
|
||||
}
|
||||
.card-label-slateblue {
|
||||
background-color: #6a5acd;
|
||||
}
|
||||
.card-label-magenta {
|
||||
background-color: #f0f;
|
||||
}
|
||||
.card-label-gold {
|
||||
background-color: #ffd700;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-navy {
|
||||
background-color: #000080;
|
||||
}
|
||||
.card-label-gray {
|
||||
background-color: #808080;
|
||||
}
|
||||
.card-label-saddlebrown {
|
||||
background-color: #8b4513;
|
||||
}
|
||||
.card-label-paleturquoise {
|
||||
background-color: #afeeee;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-mistyrose {
|
||||
background-color: #ffe4e1;
|
||||
color: #000;
|
||||
}
|
||||
.card-label-indigo {
|
||||
background-color: #4b0082;
|
||||
}
|
||||
.edit-label .card-label,
|
||||
.create-label .card-label {
|
||||
float: left;
|
||||
height: 25px;
|
||||
margin: 0px 3% 7px 0px;
|
||||
width: 10.5%;
|
||||
max-width: 10.5%;
|
||||
cursor: pointer;
|
||||
}
|
||||
.edit-labels input[type="text"] {
|
||||
margin: 4px 0 6px 38px;
|
||||
width: 243px;
|
||||
}
|
||||
.edit-labels .card-label {
|
||||
height: 30px;
|
||||
left: 0;
|
||||
padding: 1px 5px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 24px;
|
||||
}
|
||||
.edit-labels .labels-static .card-label {
|
||||
line-height: 30px;
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
top: auto;
|
||||
left: 0;
|
||||
width: 260px;
|
||||
}
|
||||
.edit-labels-pop-over {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.edit-labels-pop-over .card-label .viewer p {
|
||||
margin: 0;
|
||||
}
|
||||
.edit-labels-pop-over .shortcut {
|
||||
display: inline-block;
|
||||
}
|
||||
.card-label-selectable {
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
margin-bottom: 3px;
|
||||
width: 190px;
|
||||
min-height: 18px;
|
||||
padding: 8px;
|
||||
position: relative;
|
||||
transition: margin-right 0.1s;
|
||||
}
|
||||
.card-label-selectable .card-label-selectable-icon {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: -20px;
|
||||
}
|
||||
.card-label-selectable.active:hover,
|
||||
.card-label-selectable.active,
|
||||
.card-label-selectable.active.selected:hover,
|
||||
.card-label-selectable.active.selected {
|
||||
padding-right: 32px;
|
||||
}
|
||||
.card-label-selectable.active:hover .card-label-selectable-icon,
|
||||
.card-label-selectable.active .card-label-selectable-icon,
|
||||
.card-label-selectable.active.selected:hover .card-label-selectable-icon,
|
||||
.card-label-selectable.active.selected .card-label-selectable-icon {
|
||||
right: 6px;
|
||||
}
|
||||
.card-label-selectable.selected,
|
||||
.card-label-selectable:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.active .card-label-selectable,
|
||||
.active .card-label-selectable:hover {
|
||||
margin-right: 0;
|
||||
}
|
||||
.active .card-label-selectable .card-label-selectable-icon {
|
||||
right: 8px;
|
||||
}
|
||||
.card-label-edit-button {
|
||||
border-radius: 3px;
|
||||
float: right;
|
||||
padding: 8px;
|
||||
}
|
||||
.card-label-edit-button:hover {
|
||||
background: #dbdbdb;
|
||||
}
|
||||
ul.edit-labels-pop-over span.fa.label-handle {
|
||||
padding-right: 10px;
|
||||
}
|
||||
ul.edit-labels-pop-over span.fa.label-handle + .card-label {
|
||||
max-width: 180px;
|
||||
}
|
||||
@@ -27,9 +27,11 @@ template(name="deleteLabelPopup")
|
||||
template(name="cardLabelsPopup")
|
||||
ul.edit-labels-pop-over
|
||||
each board.labels
|
||||
li
|
||||
li.js-card-label-item
|
||||
a.card-label-edit-button.fa.fa-pencil.js-edit-label
|
||||
span.card-label.card-label-selectable.js-select-label(class="card-label-{{color}}"
|
||||
if isMiniScreenOrShowDesktopDragHandles
|
||||
span.fa.label-handle(class="fa-arrows" title="{{_ 'dragLabel'}}")
|
||||
span.card-label.card-label-selectable.js-select-label.card-label-wrapper(class="card-label-{{color}}"
|
||||
class="{{# if isLabelSelected ../_id }}active{{/if}}")
|
||||
+viewer
|
||||
= name
|
||||
|
||||
@@ -39,15 +39,67 @@ Template.createLabelPopup.helpers({
|
||||
},
|
||||
});
|
||||
|
||||
Template.cardLabelsPopup.events({
|
||||
'click .js-select-label'(event) {
|
||||
const card = Cards.findOne(Session.get('currentCard'));
|
||||
const labelId = this._id;
|
||||
card.toggleLabel(labelId);
|
||||
event.preventDefault();
|
||||
BlazeComponent.extendComponent({
|
||||
onRendered() {
|
||||
const itemsSelector = 'li.js-card-label-item:not(.placeholder)';
|
||||
const $labels = this.$('.edit-labels-pop-over');
|
||||
|
||||
$labels.sortable({
|
||||
connectWith: '.edit-labels-pop-over',
|
||||
tolerance: 'pointer',
|
||||
appendTo: '.edit-labels-pop-over',
|
||||
helper(element, currentItem) {
|
||||
let ret = currentItem.clone();
|
||||
if (currentItem.closest('.popup-container-depth-0').size() == 0)
|
||||
{ // only set css transform at every sub-popup, not at the main popup
|
||||
const content = currentItem.closest('.content')[0]
|
||||
const offsetLeft = content.offsetLeft;
|
||||
const offsetTop = $('.pop-over > .header').height() * -1;
|
||||
ret.css("transform", `translate(${offsetLeft}px, ${offsetTop}px)`);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
distance: 7,
|
||||
items: itemsSelector,
|
||||
placeholder: 'card-label-wrapper placeholder',
|
||||
start(evt, ui) {
|
||||
ui.helper.css('z-index', 1000);
|
||||
ui.placeholder.height(ui.helper.height());
|
||||
EscapeActions.clickExecute(evt.target, 'inlinedForm');
|
||||
},
|
||||
stop(evt, ui) {
|
||||
const newLabelOrderOnlyIds = ui.item.parent().children().toArray().map(_element => Blaze.getData(_element)._id)
|
||||
const card = Blaze.getData(this);
|
||||
card.board().setNewLabelOrder(newLabelOrderOnlyIds);
|
||||
},
|
||||
});
|
||||
|
||||
// Disable drag-dropping if the current user is not a board member or is comment only
|
||||
this.autorun(() => {
|
||||
if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
|
||||
$labels.sortable({
|
||||
handle: '.label-handle',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
'click .js-edit-label': Popup.open('editLabel'),
|
||||
'click .js-add-label': Popup.open('createLabel'),
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-select-label'(event) {
|
||||
const card = this.data();
|
||||
const labelId = this.currentData()._id;
|
||||
card.toggleLabel(labelId);
|
||||
event.preventDefault();
|
||||
},
|
||||
'click .js-edit-label': Popup.open('editLabel'),
|
||||
'click .js-add-label': Popup.open('createLabel'),
|
||||
}
|
||||
];
|
||||
}
|
||||
}).register('cardLabelsPopup');
|
||||
|
||||
Template.cardLabelsPopup.events({
|
||||
});
|
||||
|
||||
Template.formLabel.events({
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
// XXX Use .board-widget-labels as a flexbox container
|
||||
.card-label
|
||||
border-radius: 4px
|
||||
color: white //Default white text, in select cases, changed to black to improve contrast between label colour and text
|
||||
display: inline-block
|
||||
font-weight: 700
|
||||
font-size: 13px
|
||||
margin-right: 4px
|
||||
margin-bottom: 5px
|
||||
padding: 3px 8px
|
||||
max-width: 210px
|
||||
min-width: 8px
|
||||
overflow: ellipsis
|
||||
word-wrap: break-word
|
||||
height: 18px
|
||||
vertical-align: bottom
|
||||
|
||||
&:hover
|
||||
color: white
|
||||
|
||||
&.square
|
||||
height: 30px
|
||||
width: @height
|
||||
padding: 0
|
||||
|
||||
&.add-label
|
||||
box-shadow: 0 0 0 2px darken(white, 25%) inset
|
||||
|
||||
&:hover, &.is-active
|
||||
box-shadow: 0 0 0 2px darken(white, 60%) inset
|
||||
|
||||
i.fa-plus
|
||||
margin-top: 3px
|
||||
|
||||
.palette-colors
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
|
||||
.palette-color
|
||||
flex-grow: 1
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
.card-label-green
|
||||
background-color: #3cb500
|
||||
|
||||
.card-label-yellow
|
||||
background-color: #fad900
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-orange
|
||||
background-color: #ff9f19
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-red
|
||||
background-color: #eb4646
|
||||
|
||||
.card-label-purple
|
||||
background-color: #a632db
|
||||
|
||||
.card-label-blue
|
||||
background-color: #0079bf
|
||||
|
||||
.card-label-pink
|
||||
background-color: #ff78cb
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-sky
|
||||
background-color: #00c2e0
|
||||
|
||||
.card-label-black
|
||||
background-color: #4d4d4d
|
||||
|
||||
.card-label-lime
|
||||
background-color: #51e898
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-silver
|
||||
background-color: #c0c0c0
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-peachpuff
|
||||
background-color: #ffdab9
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-crimson
|
||||
background-color: #dc143c
|
||||
|
||||
.card-label-plum
|
||||
background-color: #dda0dd
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-darkgreen
|
||||
background-color: #006400
|
||||
|
||||
.card-label-slateblue
|
||||
background-color: #6a5acd
|
||||
|
||||
.card-label-magenta
|
||||
background-color: #ff00ff
|
||||
|
||||
.card-label-gold
|
||||
background-color: #ffd700
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-navy
|
||||
background-color: #000080
|
||||
|
||||
.card-label-gray
|
||||
background-color: #808080
|
||||
|
||||
.card-label-saddlebrown
|
||||
background-color: #8b4513
|
||||
|
||||
.card-label-paleturquoise
|
||||
background-color: #afeeee
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-mistyrose
|
||||
background-color: #ffe4e1
|
||||
color: #000000 //Black text for better visibility
|
||||
|
||||
.card-label-indigo
|
||||
background-color: #4b0082
|
||||
|
||||
.edit-label,
|
||||
.create-label
|
||||
.card-label
|
||||
float: left
|
||||
height: 25px
|
||||
margin: 0px 3% 7px 0px
|
||||
width: 10.5%
|
||||
cursor: pointer
|
||||
|
||||
.edit-labels
|
||||
input[type="text"]
|
||||
margin: 4px 0 6px 38px
|
||||
width: 243px
|
||||
|
||||
.card-label
|
||||
height: 30px
|
||||
left: 0
|
||||
padding: 1px 5px
|
||||
position: absolute
|
||||
top: 0
|
||||
width: 24px
|
||||
|
||||
.labels-static .card-label
|
||||
line-height: 30px
|
||||
margin-bottom: 4px
|
||||
position: relative
|
||||
top: auto
|
||||
left: 0
|
||||
width: 260px
|
||||
|
||||
.edit-labels-pop-over
|
||||
margin-bottom: 8px
|
||||
.card-label .viewer p
|
||||
margin: 0
|
||||
|
||||
.edit-labels-pop-over .shortcut
|
||||
display: inline-block
|
||||
|
||||
.card-label-selectable
|
||||
border-radius: 3px
|
||||
cursor: pointer
|
||||
margin: 0
|
||||
margin-bottom: 3px
|
||||
width: 190px
|
||||
min-height: 18px
|
||||
padding: 8px
|
||||
position: relative
|
||||
transition: margin-right .1s
|
||||
|
||||
.card-label-selectable-icon
|
||||
position: absolute
|
||||
top: 8px
|
||||
right: -20px
|
||||
|
||||
&.active:hover,
|
||||
&.active,
|
||||
&.active.selected:hover,
|
||||
&.active.selected
|
||||
padding-right: 32px
|
||||
|
||||
.card-label-selectable-icon
|
||||
right: 6px
|
||||
|
||||
&.selected,
|
||||
&:hover
|
||||
opacity: .8
|
||||
|
||||
.active .card-label-selectable
|
||||
&,
|
||||
&:hover
|
||||
margin-right: 0
|
||||
|
||||
.card-label-selectable-icon
|
||||
right: 8px
|
||||
|
||||
.card-label-edit-button
|
||||
border-radius: 3px
|
||||
float: right
|
||||
padding: 8px
|
||||
|
||||
&:hover
|
||||
background: #dbdbdb
|
||||
|
||||
@@ -0,0 +1,550 @@
|
||||
.minicard-wrapper {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
.minicard-wrapper.placeholder {
|
||||
background: #ccc;
|
||||
border-radius: 9px;
|
||||
}
|
||||
.minicard-wrapper.ui-sortable-helper {
|
||||
cursor: grabbing;
|
||||
transform: rotate(4deg);
|
||||
display: block !important;
|
||||
}
|
||||
.minicard-wrapper.ui-sortable-helper .and-n-other {
|
||||
width: 100%;
|
||||
height: 16px;
|
||||
padding: 4px;
|
||||
background-color: #f2f2f2;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.minicard-wrapper.ui-sortable-helper .multi-selection-checkbox {
|
||||
display: none;
|
||||
}
|
||||
.minicard-wrapper .multi-selection-checkbox + .minicard {
|
||||
margin-left: 8px;
|
||||
}
|
||||
.minicard {
|
||||
padding: 6px 8px 2px;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
flex-wrap: wrap;
|
||||
background-color: #fff;
|
||||
min-height: 20px;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
|
||||
border-radius: 2px;
|
||||
color: #4d4d4d;
|
||||
overflow: hidden;
|
||||
transition: transform 0.2s, border-radius 0.2s;
|
||||
}
|
||||
.minicard.linked-board .linked-icon,
|
||||
.minicard.linked-card .linked-icon {
|
||||
display: inline-block;
|
||||
margin-right: 11px;
|
||||
vertical-align: baseline;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.minicard.linked-board .linked-archived,
|
||||
.minicard.linked-card .linked-archived {
|
||||
color: #937760;
|
||||
}
|
||||
.is-selected .minicard {
|
||||
transform: translateX(11px);
|
||||
border-bottom-right-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
z-index: 25;
|
||||
box-shadow: -2px 1px 2px rgba(0,0,0,0.2);
|
||||
}
|
||||
.minicard:hover:not(.minicard-composer),
|
||||
.is-selected .minicard,
|
||||
.draggable-hover-card .minicard {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
.draggable-hover-card .minicard {
|
||||
background: #ededed;
|
||||
}
|
||||
.minicard .minicard-cover {
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
height: 145px;
|
||||
user-select: none;
|
||||
margin: -6px -8px 6px -8px;
|
||||
border-radius: top 2px;
|
||||
}
|
||||
.minicard .minicard-labels {
|
||||
float: none;
|
||||
}
|
||||
.minicard .minicard-labels .minicard-label {
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
border-radius: 2px;
|
||||
margin-right: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
.minicard .minicard-labels-no-text {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.minicard .minicard-custom-fields {
|
||||
display: block;
|
||||
}
|
||||
.minicard .minicard-custom-field {
|
||||
display: flex;
|
||||
}
|
||||
.minicard .minicard-custom-field-item {
|
||||
flex-grow: 1;
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
max-width: 100px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
.minicard .handle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
display: none;
|
||||
}
|
||||
@media only screen {
|
||||
.minicard .handle {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.minicard .handle .fa-arrows {
|
||||
font-size: 20px;
|
||||
color: #ccc;
|
||||
}
|
||||
.minicard .minicard-title .card-number {
|
||||
color: #b3b3b3;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.minicard .minicard-title p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.minicard .minicard-title .viewer {
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
max-width: 230px;
|
||||
}
|
||||
.minicard .dates {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.minicard .date {
|
||||
margin-right: 3px;
|
||||
}
|
||||
.minicard .badges {
|
||||
float: left;
|
||||
margin-top: 7px;
|
||||
color: #808080;
|
||||
}
|
||||
.minicard .badges:empty {
|
||||
display: none;
|
||||
}
|
||||
.minicard .badges .badge {
|
||||
float: left;
|
||||
margin-right: 11px;
|
||||
margin-bottom: 3px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.minicard .badges .badge.is-finished {
|
||||
background: #3cb500;
|
||||
padding: 0px 3px;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
}
|
||||
.minicard .badges .badge:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
.minicard .badges .badge .badge-icon,
|
||||
.minicard .badges .badge .badge-text {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.minicard .badges .badge .badge-icon.badge-comment,
|
||||
.minicard .badges .badge .badge-text.badge-comment {
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
.minicard .badges .badge .badge-text {
|
||||
font-size: 0.9em;
|
||||
padding-left: 2px;
|
||||
line-height: 14px;
|
||||
}
|
||||
.minicard .badges .badge .check-list-text {
|
||||
padding-left: 0px;
|
||||
line-height: 12px;
|
||||
}
|
||||
.minicard .minicard-members,
|
||||
.minicard .minicard-assignees,
|
||||
.minicard .minicard-creator {
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.minicard .minicard-members .member,
|
||||
.minicard .minicard-assignees .member,
|
||||
.minicard .minicard-creator .member {
|
||||
float: right;
|
||||
border-radius: 50%;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.minicard .minicard-members .assignee,
|
||||
.minicard .minicard-assignees .assignee,
|
||||
.minicard .minicard-creator .assignee {
|
||||
float: right;
|
||||
border-radius: 50%;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
}
|
||||
.minicard .minicard-members + .badges,
|
||||
.minicard .minicard-assignees + .badges,
|
||||
.minicard .minicard-creator + .badges {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.minicard .minicard-assignees {
|
||||
border-bottom: 1px solid #f00;
|
||||
}
|
||||
.minicard .minicard-creator {
|
||||
border-bottom: 1px solid #008000;
|
||||
}
|
||||
.minicard .minicard-members:empty,
|
||||
.minicard .minicard-assignees:empty {
|
||||
display: none;
|
||||
}
|
||||
.minicard .minicard-description {
|
||||
padding: 6px 0 6px 8px;
|
||||
background-color: #eee;
|
||||
width: 100%;
|
||||
margin-bottom: 2px;
|
||||
margin-left: -4px;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
}
|
||||
.minicard.minicard-composer {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.minicard.minicard-composer textarea.minicard-composer-textarea,
|
||||
.minicard.minicard-composer textarea.minicard-composer-textarea:focus {
|
||||
resize: none;
|
||||
background: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
height: auto;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
max-height: 162px;
|
||||
min-height: 36px;
|
||||
margin-bottom: 20px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.parent-prefix {
|
||||
color: #b3b3b3;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.parent-subtext {
|
||||
color: #b3b3b3;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.is-selected .minicard {
|
||||
transform: translateX(0px);
|
||||
border-bottom-right-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
z-index: 15;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
|
||||
}
|
||||
}
|
||||
/* https://github.com/wekan/wekan/issues/4254#issuecomment-1037192960 */
|
||||
.minicard-green {
|
||||
background-color: #3cb500 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-green:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-green,
|
||||
.draggable-hover-card .minicard-green {
|
||||
background: #3ab000;
|
||||
}
|
||||
.draggable-hover-card .minicard-green {
|
||||
background: #38a800;
|
||||
}
|
||||
.minicard-yellow {
|
||||
background-color: #fad900 !important;
|
||||
}
|
||||
.minicard-yellow:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-yellow,
|
||||
.draggable-hover-card .minicard-yellow {
|
||||
background: #f3d200;
|
||||
}
|
||||
.draggable-hover-card .minicard-yellow {
|
||||
background: #e9ca00;
|
||||
}
|
||||
.minicard-orange {
|
||||
background-color: #ff9f19 !important;
|
||||
}
|
||||
.minicard-orange:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-orange,
|
||||
.draggable-hover-card .minicard-orange {
|
||||
background: #ff9b11;
|
||||
}
|
||||
.draggable-hover-card .minicard-orange {
|
||||
background: #ff9705;
|
||||
}
|
||||
.minicard-red {
|
||||
background-color: #eb4646 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-red:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-red,
|
||||
.draggable-hover-card .minicard-red {
|
||||
background: #ea3e3e;
|
||||
}
|
||||
.draggable-hover-card .minicard-red {
|
||||
background: #e93333;
|
||||
}
|
||||
.minicard-purple {
|
||||
background-color: #a632db !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-purple:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-purple,
|
||||
.draggable-hover-card .minicard-purple {
|
||||
background: #a32bda;
|
||||
}
|
||||
.draggable-hover-card .minicard-purple {
|
||||
background: #9e25d5;
|
||||
}
|
||||
.minicard-blue {
|
||||
background-color: #0079bf !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-blue:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-blue,
|
||||
.draggable-hover-card .minicard-blue {
|
||||
background: #0075b9;
|
||||
}
|
||||
.draggable-hover-card .minicard-blue {
|
||||
background: #0071b2;
|
||||
}
|
||||
.minicard-pink {
|
||||
background-color: #ff78cb !important;
|
||||
}
|
||||
.minicard-pink:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-pink,
|
||||
.draggable-hover-card .minicard-pink {
|
||||
background: #ff6dc7;
|
||||
}
|
||||
.draggable-hover-card .minicard-pink {
|
||||
background: #ff5ec1;
|
||||
}
|
||||
.minicard-sky {
|
||||
background-color: #00c2e0 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-sky:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-sky,
|
||||
.draggable-hover-card .minicard-sky {
|
||||
background: #00bcd9;
|
||||
}
|
||||
.draggable-hover-card .minicard-sky {
|
||||
background: #00b4d0;
|
||||
}
|
||||
.minicard-black {
|
||||
background-color: #4d4d4d !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-black:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-black,
|
||||
.draggable-hover-card .minicard-black {
|
||||
background: #4b4b4b;
|
||||
}
|
||||
.draggable-hover-card .minicard-black {
|
||||
background: #484848;
|
||||
}
|
||||
.minicard-lime {
|
||||
background-color: #51e898 !important;
|
||||
}
|
||||
.minicard-lime:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-lime,
|
||||
.draggable-hover-card .minicard-lime {
|
||||
background: #49e793;
|
||||
}
|
||||
.draggable-hover-card .minicard-lime {
|
||||
background: #3ee58d;
|
||||
}
|
||||
.minicard-silver {
|
||||
background-color: #c0c0c0 !important;
|
||||
}
|
||||
.minicard-silver:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-silver,
|
||||
.draggable-hover-card .minicard-silver {
|
||||
background: #bababa;
|
||||
}
|
||||
.draggable-hover-card .minicard-silver {
|
||||
background: #b3b3b3;
|
||||
}
|
||||
.minicard-peachpuff {
|
||||
background-color: #ffdab9 !important;
|
||||
}
|
||||
.minicard-peachpuff:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-peachpuff,
|
||||
.draggable-hover-card .minicard-peachpuff {
|
||||
background: #ffd3ac;
|
||||
}
|
||||
.draggable-hover-card .minicard-peachpuff {
|
||||
background: #ffca9a;
|
||||
}
|
||||
.minicard-crimson {
|
||||
background-color: #dc143c !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-crimson:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-crimson,
|
||||
.draggable-hover-card .minicard-crimson {
|
||||
background: #d5133a;
|
||||
}
|
||||
.draggable-hover-card .minicard-crimson {
|
||||
background: #cd1338;
|
||||
}
|
||||
.minicard-plum {
|
||||
background-color: #dda0dd !important;
|
||||
}
|
||||
.minicard-plum:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-plum,
|
||||
.draggable-hover-card .minicard-plum {
|
||||
background: #da98da;
|
||||
}
|
||||
.draggable-hover-card .minicard-plum {
|
||||
background: #d68cd6;
|
||||
}
|
||||
.minicard-darkgreen {
|
||||
background-color: #006400 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-darkgreen:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-darkgreen,
|
||||
.draggable-hover-card .minicard-darkgreen {
|
||||
background: #006100;
|
||||
}
|
||||
.draggable-hover-card .minicard-darkgreen {
|
||||
background: #005d00;
|
||||
}
|
||||
.minicard-slateblue {
|
||||
background-color: #6a5acd !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-slateblue:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-slateblue,
|
||||
.draggable-hover-card .minicard-slateblue {
|
||||
background: #6453cb;
|
||||
}
|
||||
.draggable-hover-card .minicard-slateblue {
|
||||
background: #5c4ac8;
|
||||
}
|
||||
.minicard-magenta {
|
||||
background-color: #f0f !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-magenta:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-magenta,
|
||||
.draggable-hover-card .minicard-magenta {
|
||||
background: #f700f7;
|
||||
}
|
||||
.draggable-hover-card .minicard-magenta {
|
||||
background: #ed00ed;
|
||||
}
|
||||
.minicard-gold {
|
||||
background-color: #ffd700 !important;
|
||||
}
|
||||
.minicard-gold:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-gold,
|
||||
.draggable-hover-card .minicard-gold {
|
||||
background: #f7d100;
|
||||
}
|
||||
.draggable-hover-card .minicard-gold {
|
||||
background: #edc800;
|
||||
}
|
||||
.minicard-navy {
|
||||
background-color: #000080 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-navy:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-navy,
|
||||
.draggable-hover-card .minicard-navy {
|
||||
background: #00007c;
|
||||
}
|
||||
.draggable-hover-card .minicard-navy {
|
||||
background: #007;
|
||||
}
|
||||
.minicard-gray {
|
||||
background-color: #808080 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-gray:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-gray,
|
||||
.draggable-hover-card .minicard-gray {
|
||||
background: #7c7c7c;
|
||||
}
|
||||
.draggable-hover-card .minicard-gray {
|
||||
background: #777;
|
||||
}
|
||||
.minicard-saddlebrown {
|
||||
background-color: #8b4513 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-saddlebrown:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-saddlebrown,
|
||||
.draggable-hover-card .minicard-saddlebrown {
|
||||
background: #874312;
|
||||
}
|
||||
.draggable-hover-card .minicard-saddlebrown {
|
||||
background: #814012;
|
||||
}
|
||||
.minicard-paleturquoise {
|
||||
background-color: #afeeee !important;
|
||||
}
|
||||
.minicard-paleturquoise:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-paleturquoise,
|
||||
.draggable-hover-card .minicard-paleturquoise {
|
||||
background: #a5ecec;
|
||||
}
|
||||
.draggable-hover-card .minicard-paleturquoise {
|
||||
background: #97e9e9;
|
||||
}
|
||||
.minicard-mistyrose {
|
||||
background-color: #ffe4e1 !important;
|
||||
}
|
||||
.minicard-mistyrose:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-mistyrose,
|
||||
.draggable-hover-card .minicard-mistyrose {
|
||||
background: #ffd7d3;
|
||||
}
|
||||
.draggable-hover-card .minicard-mistyrose {
|
||||
background: #ffc6bf;
|
||||
}
|
||||
.minicard-indigo {
|
||||
background-color: #4b0082 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.minicard-indigo:hover:not(.minicard-composer),
|
||||
.is-selected .minicard-indigo,
|
||||
.draggable-hover-card .minicard-indigo {
|
||||
background: #49007e;
|
||||
}
|
||||
.draggable-hover-card .minicard-indigo {
|
||||
background: #460079;
|
||||
}
|
||||
.text-red {
|
||||
color: #f00;
|
||||
}
|
||||
.text-green {
|
||||
color: #008000;
|
||||
}
|
||||
@@ -2,21 +2,17 @@ template(name="minicard")
|
||||
.minicard(
|
||||
class="{{#if isLinkedCard}}linked-card{{/if}}"
|
||||
class="{{#if isLinkedBoard}}linked-board{{/if}}"
|
||||
class="minicard-{{colorClass}}")
|
||||
if isMiniScreen
|
||||
class="{{#if colorClass}}minicard-{{colorClass}}{{/if}}")
|
||||
if isMiniScreenOrShowDesktopDragHandles
|
||||
.handle
|
||||
.fa.fa-arrows
|
||||
unless isMiniScreen
|
||||
if showDesktopDragHandles
|
||||
.handle
|
||||
.fa.fa-arrows
|
||||
if cover
|
||||
.minicard-cover(style="background-image: url('{{cover.url}}');")
|
||||
.minicard-cover(style="background-image: url('{{cover.link 'original' '/'}}?dummyReloadAfterSessionEstablished={{sess}}');")
|
||||
if labels
|
||||
.minicard-labels
|
||||
.minicard-labels(class="{{#if hiddenMinicardLabelText}}minicard-labels-no-text{{/if}}")
|
||||
each labels
|
||||
unless hiddenMinicardLabelText
|
||||
span.card-label(class="card-label-{{color}}" title=name)
|
||||
span.js-card-label.card-label(class="card-label-{{color}}" title=name)
|
||||
+viewer
|
||||
= name
|
||||
if hiddenMinicardLabelText
|
||||
@@ -37,6 +33,9 @@ template(name="minicard")
|
||||
if getArchived
|
||||
span.linked-icon.linked-archived.fa.fa-archive
|
||||
+viewer
|
||||
if currentBoard.allowsCardNumber
|
||||
span.card-number
|
||||
| ##{getCardNumber}
|
||||
= getTitle
|
||||
if $eq 'subtext-with-full-path' currentBoard.presentParentTask
|
||||
.parent-subtext
|
||||
@@ -82,19 +81,28 @@ template(name="minicard")
|
||||
+minicardCustomFieldDate
|
||||
else if $eq definition.type "checkbox"
|
||||
.materialCheckBox(class="{{#if value }}is-checked{{/if}}")
|
||||
else if $eq definition.type "stringtemplate"
|
||||
+viewer
|
||||
= formattedStringtemplateCustomFieldValue(definition)
|
||||
else
|
||||
+viewer
|
||||
= trueValue
|
||||
|
||||
if getAssignees
|
||||
.minicard-assignees.js-minicard-assignees
|
||||
each getAssignees
|
||||
+userAvatar(userId=this)
|
||||
if showAssignee
|
||||
if getAssignees
|
||||
.minicard-assignees.js-minicard-assignees
|
||||
each getAssignees
|
||||
+userAvatar(userId=this)
|
||||
|
||||
if getMembers
|
||||
.minicard-members.js-minicard-members
|
||||
each getMembers
|
||||
+userAvatar(userId=this)
|
||||
if showMembers
|
||||
if getMembers
|
||||
.minicard-members.js-minicard-members
|
||||
each getMembers
|
||||
+userAvatar(userId=this)
|
||||
|
||||
if showCreator
|
||||
.minicard-creator
|
||||
+userAvatar(userId=this.userId noRemove=true)
|
||||
|
||||
.badges
|
||||
unless currentUser.isNoComments
|
||||
@@ -106,19 +114,44 @@ template(name="minicard")
|
||||
//span.badge-comment.badge-text
|
||||
//| {{_ 'comment'}}
|
||||
if getDescription
|
||||
.badge.badge-state-image-only(title=getDescription)
|
||||
span.badge-icon.fa.fa-align-left
|
||||
unless currentBoard.allowsDescriptionTextOnMinicard
|
||||
.badge.badge-state-image-only(title=getDescription)
|
||||
span.badge-icon.fa.fa-align-left
|
||||
if getVoteQuestion
|
||||
.badge.badge-state-image-only(title=getVoteQuestion)
|
||||
span.badge-icon.fa.fa-thumbs-up(class="{{#if voteState}}text-green{{/if}}")
|
||||
span.badge-text {{ voteCountPositive }}
|
||||
span.badge-icon.fa.fa-thumbs-down(class="{{#if $eq voteState false}}text-red{{/if}}")
|
||||
span.badge-text {{ voteCountNegative }}
|
||||
if attachments.count
|
||||
if getPokerQuestion
|
||||
.badge.badge-state-image-only(title=getPokerQuestion)
|
||||
span.badge-icon.fa.fa-check(class="{{#if pokerState}}text-green{{/if}}")
|
||||
if expiredPoker
|
||||
span.badge-text {{ getPokerEstimation }}
|
||||
if attachments.length
|
||||
.badge
|
||||
span.badge-icon.fa.fa-paperclip
|
||||
span.badge-text= attachments.count
|
||||
span.badge-text= attachments.length
|
||||
if checklists.count
|
||||
.badge(class="{{#if checklistFinished}}is-finished{{/if}}")
|
||||
span.badge-icon.fa.fa-check-square-o
|
||||
span.badge-text.check-list-text {{checklistFinishedCount}}/{{checklistItemCount}}
|
||||
if allSubtasks.count
|
||||
.badge
|
||||
span.badge-icon.fa.fa-sitemap
|
||||
span.badge-text.check-list-text {{subtasksFinishedCount}}/{{allSubtasksCount}}
|
||||
//{{subtasksFinishedCount}}/{{subtasksCount}} does not work because when a subtaks is archived, the count goes down
|
||||
if currentBoard.allowsCardSortingByNumber
|
||||
.badge
|
||||
span.badge-icon.fa.fa-sort
|
||||
span.badge-text.check-list-sort {{ sort }}
|
||||
if currentBoard.allowsDescriptionTextOnMinicard
|
||||
if getDescription
|
||||
.minicard-description
|
||||
+viewer
|
||||
| {{ getDescription }}
|
||||
|
||||
template(name="editCardSortOrderPopup")
|
||||
input.js-edit-card-sort-popup(type='text' autofocus value=sort dir="auto")
|
||||
.edit-controls.clearfix
|
||||
button.primary.confirm.js-submit-edit-card-sort-popup(type="submit") {{_ 'save'}}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
|
||||
// Template.cards.events({
|
||||
// 'click .member': Popup.open('cardMember')
|
||||
// });
|
||||
@@ -21,6 +23,66 @@ BlazeComponent.extendComponent({
|
||||
}).format(customFieldTrueValue);
|
||||
},
|
||||
|
||||
formattedStringtemplateCustomFieldValue(definition) {
|
||||
const customField = this.data()
|
||||
.customFieldsWD()
|
||||
.find(f => f._id === definition._id);
|
||||
|
||||
const customFieldTrueValue =
|
||||
customField && customField.trueValue ? customField.trueValue : [];
|
||||
|
||||
return customFieldTrueValue
|
||||
.filter(value => !!value.trim())
|
||||
.map(value =>
|
||||
definition.settings.stringtemplateFormat.replace(/%\{value\}/gi, value),
|
||||
)
|
||||
.join(definition.settings.stringtemplateSeparator ?? '');
|
||||
},
|
||||
|
||||
showCreator() {
|
||||
if (this.data().board()) {
|
||||
return (
|
||||
this.data().board.allowsCreator === null ||
|
||||
this.data().board().allowsCreator === undefined ||
|
||||
this.data().board().allowsCreator
|
||||
);
|
||||
// return this.data().board().allowsCreator;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
showMembers() {
|
||||
if (this.data().board()) {
|
||||
return (
|
||||
this.data().board.allowsMembers === null ||
|
||||
this.data().board().allowsMembers === undefined ||
|
||||
this.data().board().allowsMembers
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
showAssignee() {
|
||||
if (this.data().board()) {
|
||||
return (
|
||||
this.data().board.allowsAssignee === null ||
|
||||
this.data().board().allowsAssignee === undefined ||
|
||||
this.data().board().allowsAssignee
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/** opens the card label popup only if clicked onto a label
|
||||
* <li> this is necessary to have the data context of the minicard.
|
||||
* if .js-card-label is used at click event, then only the data context of the label itself is available at this.currentData()
|
||||
*/
|
||||
cardLabelsPopup(event) {
|
||||
if (this.find('.js-card-label:hover')) {
|
||||
Popup.open("cardLabels")(event, {dataContextIfCurrentDataIsUndefined: this.currentData()});
|
||||
}
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
@@ -29,8 +91,6 @@ BlazeComponent.extendComponent({
|
||||
else if (this.data().isLinkedBoard())
|
||||
Utils.goBoardId(this.data().linkedId);
|
||||
},
|
||||
},
|
||||
{
|
||||
'click .js-toggle-minicard-label-text'() {
|
||||
if (window.localStorage.getItem('hiddenMinicardLabelText')) {
|
||||
window.localStorage.removeItem('hiddenMinicardLabelText'); //true
|
||||
@@ -38,22 +98,14 @@ BlazeComponent.extendComponent({
|
||||
window.localStorage.setItem('hiddenMinicardLabelText', 'true'); //true
|
||||
}
|
||||
},
|
||||
},
|
||||
'click span.badge-icon.fa.fa-sort, click span.badge-text.check-list-sort' : Popup.open("editCardSortOrder"),
|
||||
'click .minicard-labels' : this.cardLabelsPopup,
|
||||
}
|
||||
];
|
||||
},
|
||||
}).register('minicard');
|
||||
|
||||
Template.minicard.helpers({
|
||||
showDesktopDragHandles() {
|
||||
currentUser = Meteor.user();
|
||||
if (currentUser) {
|
||||
return (currentUser.profile || {}).showDesktopDragHandles;
|
||||
} else if (window.localStorage.getItem('showDesktopDragHandles')) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
hiddenMinicardLabelText() {
|
||||
currentUser = Meteor.user();
|
||||
if (currentUser) {
|
||||
@@ -64,4 +116,37 @@ Template.minicard.helpers({
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// XXX resolve this nasty hack for https://github.com/veliovgroup/Meteor-Files/issues/763
|
||||
sess() {
|
||||
return Meteor.connection && Meteor.connection._lastSessionId
|
||||
? Meteor.connection._lastSessionId
|
||||
: null;
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'keydown input.js-edit-card-sort-popup'(evt) {
|
||||
// enter = save
|
||||
if (evt.keyCode === 13) {
|
||||
this.find('button[type=submit]').click();
|
||||
}
|
||||
},
|
||||
'click button.js-submit-edit-card-sort-popup'(event) {
|
||||
// save button pressed
|
||||
event.preventDefault();
|
||||
const sort = this.$('.js-edit-card-sort-popup')[0]
|
||||
.value
|
||||
.trim();
|
||||
if (!Number.isNaN(sort)) {
|
||||
let card = this.data();
|
||||
card.move(card.boardId, card.swimlaneId, card.listId, sort);
|
||||
Popup.back();
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}).register('editCardSortOrderPopup');
|
||||
@@ -1,313 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
.minicard-wrapper
|
||||
cursor: pointer
|
||||
position: relative
|
||||
display: flex
|
||||
align-items: center
|
||||
margin-bottom: 9px
|
||||
|
||||
&.placeholder
|
||||
background: darken(white, 20%)
|
||||
border-radius: 9px
|
||||
|
||||
&.ui-sortable-helper
|
||||
cursor: grabbing
|
||||
transform: rotate(4deg)
|
||||
display: block !important
|
||||
|
||||
.and-n-other
|
||||
width: 100%
|
||||
height: 16px
|
||||
padding: 4px
|
||||
background-color: darken(white, 5%)
|
||||
text-align: center
|
||||
border-radius: 3px
|
||||
|
||||
.multi-selection-checkbox
|
||||
display: none
|
||||
|
||||
.multi-selection-checkbox + .minicard
|
||||
margin-left: 8px
|
||||
|
||||
.minicard
|
||||
padding: 6px 8px 2px
|
||||
position: relative
|
||||
flex: 1
|
||||
flex-wrap: wrap
|
||||
background-color: #fff
|
||||
min-height: 20px
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.15)
|
||||
border-radius: 2px
|
||||
color: #4d4d4d
|
||||
overflow: hidden
|
||||
transition: transform 0.2s,
|
||||
border-radius 0.2s
|
||||
|
||||
&.linked-board
|
||||
&.linked-card
|
||||
.linked-icon
|
||||
display: inline-block
|
||||
margin-right: 11px
|
||||
vertical-align: baseline
|
||||
font-size: 0.9em
|
||||
.linked-archived
|
||||
color: #937760
|
||||
|
||||
.is-selected &
|
||||
transform: translateX(11px)
|
||||
border-bottom-right-radius: 0
|
||||
border-top-right-radius: 0
|
||||
z-index: 25
|
||||
box-shadow: -2px 1px 2px rgba(0,0,0,.2)
|
||||
|
||||
&:hover:not(.minicard-composer),
|
||||
.is-selected &,
|
||||
.draggable-hover-card &
|
||||
background: darken(white, 3%)
|
||||
|
||||
.draggable-hover-card &
|
||||
background: darken(white, 7%)
|
||||
|
||||
.minicard-cover
|
||||
background-position: center
|
||||
background-repeat: no-repeat
|
||||
background-size: contain
|
||||
height: 145px
|
||||
user-select: none
|
||||
margin: -6px -8px 6px -8px
|
||||
border-radius: top 2px
|
||||
|
||||
.minicard-labels
|
||||
float: none
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
|
||||
.minicard-label
|
||||
width: 11px
|
||||
height: @width
|
||||
border-radius: 2px
|
||||
margin-right: 3px
|
||||
margin-bottom: 3px
|
||||
|
||||
.minicard-custom-fields
|
||||
display:block;
|
||||
.minicard-custom-field
|
||||
display:flex;
|
||||
.minicard-custom-field-item
|
||||
flex-grow: 1
|
||||
display: block
|
||||
word-wrap: break-word
|
||||
max-width: 100px
|
||||
margin-right: 4px
|
||||
.handle
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
display:none;
|
||||
@media only screen {
|
||||
display:block;
|
||||
}
|
||||
.fa-arrows
|
||||
font-size:20px;
|
||||
color: #ccc;
|
||||
.minicard-title
|
||||
p:last-child
|
||||
margin-bottom: 0
|
||||
.viewer
|
||||
display: block
|
||||
word-wrap: break-word
|
||||
max-width: 230px
|
||||
.dates
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
.date
|
||||
margin-right: 3px
|
||||
.badges
|
||||
float: left
|
||||
margin-top: 7px
|
||||
color: darken(white, 50%)
|
||||
|
||||
&:empty
|
||||
display: none
|
||||
|
||||
.badge
|
||||
float: left
|
||||
margin-right: 11px
|
||||
margin-bottom: 3px
|
||||
font-size: 0.9em
|
||||
&.is-finished
|
||||
background: #3cb500
|
||||
padding: 0px 3px
|
||||
border-radius: 3px
|
||||
color: white
|
||||
|
||||
&:last-of-type
|
||||
margin-right: 0
|
||||
|
||||
.badge-icon,
|
||||
.badge-text
|
||||
vertical-align: middle
|
||||
&.badge-comment
|
||||
margin-bottom: 0.1rem
|
||||
|
||||
.badge-text
|
||||
font-size: 0.9em
|
||||
padding-left: 2px
|
||||
line-height: 14px
|
||||
.check-list-text
|
||||
padding-left: 0px
|
||||
line-height: 12px
|
||||
|
||||
.minicard-members,
|
||||
.minicard-assignees
|
||||
float: right
|
||||
margin-left: 5px
|
||||
margin-bottom: 4px
|
||||
|
||||
.member
|
||||
float: right
|
||||
border-radius: 50%
|
||||
height: 28px
|
||||
width: @height
|
||||
margin-bottom: 4px
|
||||
|
||||
.assignee
|
||||
float: right
|
||||
border-radius: 50%
|
||||
height: 28px
|
||||
width: @height
|
||||
|
||||
+ .badges
|
||||
margin-top: 5px
|
||||
|
||||
.minicard-assignees
|
||||
border-bottom: 1px solid red
|
||||
|
||||
.minicard-members:empty,
|
||||
.minicard-assignees:empty
|
||||
display: none
|
||||
|
||||
&.minicard-composer
|
||||
margin-bottom: 10px
|
||||
|
||||
textarea.minicard-composer-textarea,
|
||||
textarea.minicard-composer-textarea:focus
|
||||
resize: none
|
||||
background: none
|
||||
border: none
|
||||
box-shadow: none
|
||||
height: auto
|
||||
margin: 0
|
||||
padding: 0
|
||||
max-height: 162px
|
||||
min-height: 36px
|
||||
margin-bottom: 20px
|
||||
overflow-y: auto
|
||||
|
||||
.parent-prefix
|
||||
color: darken(white, 30%)
|
||||
font-size: 0.9em
|
||||
.parent-subtext
|
||||
color: darken(white, 30%)
|
||||
font-size: 0.9em
|
||||
|
||||
@media screen and (max-width: 800px)
|
||||
.minicard
|
||||
.is-selected &
|
||||
transform: translateX(0px)
|
||||
border-bottom-right-radius: 0
|
||||
border-top-right-radius: 0
|
||||
z-index: 15
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.15)
|
||||
|
||||
minicard-color(background, color...)
|
||||
background-color: background
|
||||
if color
|
||||
color: color //overwrite text for better visibility
|
||||
&:hover:not(.minicard-composer),
|
||||
.is-selected &,
|
||||
.draggable-hover-card &
|
||||
background: darken(background, 3%)
|
||||
.draggable-hover-card &
|
||||
background: darken(background, 7%)
|
||||
|
||||
.minicard-green
|
||||
minicard-color(#3cb500, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-yellow
|
||||
minicard-color(#fad900)
|
||||
|
||||
.minicard-orange
|
||||
minicard-color(#ff9f19)
|
||||
|
||||
.minicard-red
|
||||
minicard-color(#eb4646, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-purple
|
||||
minicard-color(#a632db, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-blue
|
||||
minicard-color(#0079bf, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-pink
|
||||
minicard-color(#ff78cb)
|
||||
|
||||
.minicard-sky
|
||||
minicard-color(#00c2e0, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-black
|
||||
minicard-color(#4d4d4d, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-lime
|
||||
minicard-color(#51e898)
|
||||
|
||||
.minicard-silver
|
||||
minicard-color(#c0c0c0)
|
||||
|
||||
.minicard-peachpuff
|
||||
minicard-color(#ffdab9)
|
||||
|
||||
.minicard-crimson
|
||||
minicard-color(#dc143c, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-plum
|
||||
minicard-color(#dda0dd)
|
||||
|
||||
.minicard-darkgreen
|
||||
minicard-color(#006400, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-slateblue
|
||||
minicard-color(#6a5acd, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-magenta
|
||||
minicard-color(#ff00ff, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-gold
|
||||
minicard-color(#ffd700)
|
||||
|
||||
.minicard-navy
|
||||
minicard-color(#000080, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-gray
|
||||
minicard-color(#808080, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-saddlebrown
|
||||
minicard-color(#8b4513, #ffffff) //White text for better visibility
|
||||
|
||||
.minicard-paleturquoise
|
||||
minicard-color(#afeeee)
|
||||
|
||||
.minicard-mistyrose
|
||||
minicard-color(#ffe4e1)
|
||||
|
||||
.minicard-indigo
|
||||
minicard-color(#4b0082, #ffffff) //White text for better visibility
|
||||
|
||||
.text-red
|
||||
color:red
|
||||
.text-green
|
||||
color:green
|
||||
@@ -0,0 +1,25 @@
|
||||
.result-card-list-wrapper {
|
||||
margin: 1rem;
|
||||
border-radius: 5px;
|
||||
padding: 1.5rem;
|
||||
padding-top: 0.75rem;
|
||||
display: inline-block;
|
||||
min-width: 250px;
|
||||
max-width: 350px;
|
||||
}
|
||||
.result-card-wrapper {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.result-card-context {
|
||||
display: inline-block;
|
||||
}
|
||||
.result-card-context-separator {
|
||||
font-weight: bold;
|
||||
}
|
||||
.result-card-context-list {
|
||||
margin-bottom: 0.7rem;
|
||||
}
|
||||
.result-card-block-wrapper {
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
template(name="resultCard")
|
||||
.result-card-wrapper
|
||||
a.minicard-wrapper.card-title(href=originRelativeUrl)
|
||||
a.minicard-wrapper.js-minicard.card-title(href=originRelativeUrl)
|
||||
+minicard(this)
|
||||
//= card.title
|
||||
ul.result-card-context-list
|
||||
|
||||
@@ -5,7 +5,31 @@ Template.resultCard.helpers({
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
clickOnMiniCard(evt) {
|
||||
evt.preventDefault();
|
||||
const this_ = this;
|
||||
const cardId = this.currentData()._id;
|
||||
const boardId = this.currentData().boardId;
|
||||
Meteor.subscribe('popupCardData', cardId, {
|
||||
onReady() {
|
||||
Session.set('popupCardId', cardId);
|
||||
Session.set('popupCardBoardId', boardId);
|
||||
this_.cardDetailsPopup(evt);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
cardDetailsPopup(event) {
|
||||
if (!Popup.isOpen()) {
|
||||
Popup.open("cardDetails")(event);
|
||||
}
|
||||
},
|
||||
|
||||
events() {
|
||||
return [{}];
|
||||
return [
|
||||
{
|
||||
'click .js-minicard': this.clickOnMiniCard,
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('resultCard');
|
||||
@@ -1,24 +0,0 @@
|
||||
.result-card-list-wrapper
|
||||
margin: 1rem
|
||||
border-radius: 5px
|
||||
padding: 1.5rem
|
||||
padding-top: 0.75rem
|
||||
display: inline-block
|
||||
min-width: 250px
|
||||
max-width: 350px
|
||||
|
||||
.result-card-wrapper
|
||||
margin-top: 0
|
||||
margin-bottom: 10px
|
||||
|
||||
.result-card-context
|
||||
display: inline-block
|
||||
|
||||
.result-card-context-separator
|
||||
font-weight: bold
|
||||
|
||||
.result-card-context-list
|
||||
margin-bottom: 0.7rem
|
||||
|
||||
.result-card-block-wrapper
|
||||
display: inline-block
|
||||
@@ -0,0 +1,152 @@
|
||||
.js-add-subtask {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
textarea.js-add-subtask-item,
|
||||
textarea.js-edit-subtask-item {
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
resize: none;
|
||||
height: 34px;
|
||||
}
|
||||
.delete-text,
|
||||
.subtask-title .js-delete-subtask,
|
||||
.subtask-title .js-view-subtask,
|
||||
.js-delete-subtask-item {
|
||||
color: #8c8c8c;
|
||||
text-decoration: underline;
|
||||
word-wrap: break-word;
|
||||
float: right;
|
||||
padding-top: 6px;
|
||||
}
|
||||
.delete-text:hover,
|
||||
.subtask-title .js-delete-subtask:hover,
|
||||
.subtask-title .js-view-subtask:hover,
|
||||
.js-delete-subtask-item:hover {
|
||||
color: inherit;
|
||||
}
|
||||
.subtask-title .checkbox {
|
||||
float: left;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: 18px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.subtask-title .title {
|
||||
font-size: 18px;
|
||||
line-height: 25px;
|
||||
}
|
||||
.subtask-title .subtasks-stat {
|
||||
margin: 0 0.5em;
|
||||
float: right;
|
||||
padding-top: 6px;
|
||||
}
|
||||
.subtask-title .subtasks-stat.is-finished {
|
||||
color: #3cb500;
|
||||
}
|
||||
.subtask-title .js-delete-subtask {
|
||||
margin: 0 0.5em;
|
||||
}
|
||||
.js-confirm-subtask-delete {
|
||||
background-color: #f7f7f7;
|
||||
position: absolute;
|
||||
float: left;
|
||||
width: 60%;
|
||||
margin-top: 0;
|
||||
margin-left: 13%;
|
||||
padding-bottom: 2%;
|
||||
padding-left: 3%;
|
||||
padding-right: 3%;
|
||||
z-index: 17;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.js-confirm-subtask-delete p {
|
||||
position: relative;
|
||||
margin-top: 3%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.js-confirm-subtask-delete p span {
|
||||
font-weight: bold;
|
||||
}
|
||||
.js-confirm-subtask-delete p i {
|
||||
font-size: 2em;
|
||||
}
|
||||
.js-confirm-subtask-delete .js-subtask-delete-buttons {
|
||||
position: relative;
|
||||
padding: left 2% right 2%;
|
||||
}
|
||||
.js-confirm-subtask-delete .js-subtask-delete-buttons .confirm-subtask-delete {
|
||||
margin-left: 12%;
|
||||
float: left;
|
||||
}
|
||||
.js-confirm-subtask-delete .js-subtask-delete-buttons .toggle-delete-subtask-dialog {
|
||||
margin-right: 12%;
|
||||
float: right;
|
||||
}
|
||||
#card-details-overlay {
|
||||
top: 0;
|
||||
bottom: -600px;
|
||||
right: 0;
|
||||
}
|
||||
.subtasks {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
.subtasks.placeholder {
|
||||
background: #ccc;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.subtasks.ui-sortable-helper {
|
||||
box-shadow: -2px 2px 8px rgba(0,0,0,0.3), 0 0 1px rgba(0,0,0,0.5);
|
||||
transform: rotate(4deg);
|
||||
cursor: grabbing;
|
||||
}
|
||||
.subtasks-item {
|
||||
margin: 0 0 0 0.1em;
|
||||
line-height: 18px;
|
||||
font-size: 1.1em;
|
||||
margin-top: 3px;
|
||||
display: flex;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
.subtasks-item.placeholder {
|
||||
background: #ccc;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.subtasks-item.ui-sortable-helper {
|
||||
box-shadow: -2px 2px 8px rgba(0,0,0,0.3), 0 0 1px rgba(0,0,0,0.5);
|
||||
transform: rotate(4deg);
|
||||
cursor: grabbing;
|
||||
}
|
||||
.subtasks-item:hover {
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
.subtasks-item .check-box {
|
||||
margin: 0.1em 0 0 0;
|
||||
}
|
||||
.subtasks-item .check-box.is-checked {
|
||||
border-bottom: 2px solid #3cb500;
|
||||
border-right: 2px solid #3cb500;
|
||||
}
|
||||
.subtasks-item .item-title {
|
||||
flex: 1;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.subtasks-item .item-title.is-checked {
|
||||
color: #8c8c8c;
|
||||
font-style: italic;
|
||||
}
|
||||
.subtasks-item .item-title .viewer p {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.js-delete-subtask-item {
|
||||
margin: 0 0 0.5em 1.33em;
|
||||
padding: 12px 0 0 0;
|
||||
}
|
||||
.add-subtask-item {
|
||||
margin: 0.2em 0 0.5em 1.33em;
|
||||
display: inline-block;
|
||||
}
|
||||
.subtask-details-menu {
|
||||
float: right;
|
||||
padding: 6px 10px 6px 10px;
|
||||
}
|
||||
@@ -15,9 +15,8 @@ template(name="subtasks")
|
||||
+inlinedForm(autoclose=false classNames="js-add-subtask" cardId = cardId)
|
||||
+addSubtaskItemForm
|
||||
else
|
||||
a.js-open-inlined-form
|
||||
a.js-open-inlined-form(title="{{_ 'add-subtask'}}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-subtask'}}...
|
||||
|
||||
template(name="subtaskDetail")
|
||||
.js-subtasks.subtask
|
||||
@@ -26,11 +25,9 @@ template(name="subtaskDetail")
|
||||
else
|
||||
.subtask-title
|
||||
span
|
||||
a.js-view-subtask(title="{{ subtask.title }}") {{_ "view-it"}}
|
||||
if canModifyCard
|
||||
if currentUser.isBoardAdmin
|
||||
a.js-delete-subtask.toggle-delete-subtask-dialog {{_ "delete"}}...
|
||||
|
||||
a.fa.fa-navicon.subtask-details-menu.js-open-subtask-details-menu(title="{{_ 'subtaskActionsPopup-title'}}")
|
||||
if canModifyCard
|
||||
h2.title.js-open-inlined-form.is-editable
|
||||
+viewer
|
||||
@@ -40,18 +37,6 @@ template(name="subtaskDetail")
|
||||
+viewer
|
||||
= subtask.title
|
||||
|
||||
template(name="subtaskDeleteDialog")
|
||||
.js-confirm-subtask-delete
|
||||
p
|
||||
i(class="fa fa-exclamation-triangle" aria-hidden="true")
|
||||
p
|
||||
| {{_ 'confirm-subtask-delete-dialog'}}
|
||||
span {{subtask.title}}
|
||||
| ?
|
||||
.js-subtask-delete-buttons
|
||||
button.confirm-subtask-delete(type="button") {{_ 'delete'}}
|
||||
button.toggle-delete-subtask-dialog(type="button") {{_ 'cancel'}}
|
||||
|
||||
template(name="addSubtaskItemForm")
|
||||
textarea.js-add-subtask-item(rows='1' autofocus dir="auto")
|
||||
.edit-controls.clearfix
|
||||
@@ -99,3 +84,18 @@ template(name='subtaskItemDetail')
|
||||
.item-title(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
+viewer
|
||||
= item.title
|
||||
|
||||
template(name="subtaskDeletePopup")
|
||||
p {{_ 'confirm-subtask-delete-popup'}}
|
||||
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
|
||||
|
||||
template(name="subtaskActionsPopup")
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.js-view-subtask(title="{{ subtask.title }}")
|
||||
i.fa.fa-eye
|
||||
| {{_ "view-it"}}
|
||||
a.js-delete-subtask.delete-subtask
|
||||
i.fa.fa-trash
|
||||
| {{_ "delete"}} ...
|
||||
|
||||
@@ -37,6 +37,8 @@ BlazeComponent.extendComponent({
|
||||
? targetBoard.getDefaultSwimline()._id
|
||||
: targetSwimlane._id;
|
||||
|
||||
const nextCardNumber = targetBoard.getNextCardNumber();
|
||||
|
||||
if (title) {
|
||||
const _id = Cards.insert({
|
||||
title,
|
||||
@@ -49,6 +51,7 @@ BlazeComponent.extendComponent({
|
||||
sort: sortIndex,
|
||||
swimlaneId,
|
||||
type: 'cardType-card',
|
||||
cardNumber: nextCardNumber
|
||||
});
|
||||
|
||||
// In case the filter is active we need to add the newly inserted card in
|
||||
@@ -80,7 +83,6 @@ BlazeComponent.extendComponent({
|
||||
const subtask = this.currentData().subtask;
|
||||
if (subtask && subtask._id) {
|
||||
subtask.archive();
|
||||
this.toggleDeleteDialog.set(false);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -92,11 +94,6 @@ BlazeComponent.extendComponent({
|
||||
subtask.setTitle(title);
|
||||
},
|
||||
|
||||
onCreated() {
|
||||
this.toggleDeleteDialog = new ReactiveVar(false);
|
||||
this.subtaskToDelete = null; //Store data context to pass to subtaskDeleteDialog template
|
||||
},
|
||||
|
||||
pressKey(event) {
|
||||
//If user press enter key inside a form, submit it
|
||||
//Unless the user is also holding down the 'shift' key
|
||||
@@ -108,64 +105,18 @@ BlazeComponent.extendComponent({
|
||||
},
|
||||
|
||||
events() {
|
||||
const events = {
|
||||
'click .toggle-delete-subtask-dialog'(event) {
|
||||
if ($(event.target).hasClass('js-delete-subtask')) {
|
||||
this.subtaskToDelete = this.currentData().subtask; //Store data context
|
||||
}
|
||||
this.toggleDeleteDialog.set(!this.toggleDeleteDialog.get());
|
||||
},
|
||||
'click .js-view-subtask'(event) {
|
||||
if ($(event.target).hasClass('js-view-subtask')) {
|
||||
const subtask = this.currentData().subtask;
|
||||
const board = subtask.board();
|
||||
FlowRouter.go('card', {
|
||||
boardId: board._id,
|
||||
slug: board.slug,
|
||||
cardId: subtask._id,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
...events,
|
||||
'click .js-open-subtask-details-menu': Popup.open('subtaskActions'),
|
||||
'submit .js-add-subtask': this.addSubtask,
|
||||
'submit .js-edit-subtask-title': this.editSubtask,
|
||||
'click .confirm-subtask-delete': this.deleteSubtask,
|
||||
'click .js-delete-subtask-item': this.deleteSubtask,
|
||||
keydown: this.pressKey,
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('subtasks');
|
||||
|
||||
Template.subtaskDeleteDialog.onCreated(() => {
|
||||
const $cardDetails = this.$('.card-details');
|
||||
this.scrollState = {
|
||||
position: $cardDetails.scrollTop(), //save current scroll position
|
||||
top: false, //required for smooth scroll animation
|
||||
};
|
||||
//Callback's purpose is to only prevent scrolling after animation is complete
|
||||
$cardDetails.animate({ scrollTop: 0 }, 500, () => {
|
||||
this.scrollState.top = true;
|
||||
});
|
||||
|
||||
//Prevent scrolling while dialog is open
|
||||
$cardDetails.on('scroll', () => {
|
||||
if (this.scrollState.top) {
|
||||
//If it's already in position, keep it there. Otherwise let animation scroll
|
||||
$cardDetails.scrollTop(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Template.subtaskDeleteDialog.onDestroyed(() => {
|
||||
const $cardDetails = this.$('.card-details');
|
||||
$cardDetails.off('scroll'); //Reactivate scrolling
|
||||
$cardDetails.animate({ scrollTop: this.scrollState.position });
|
||||
});
|
||||
|
||||
Template.subtaskItemDetail.helpers({
|
||||
canModifyCard() {
|
||||
return (
|
||||
@@ -180,3 +131,30 @@ Template.subtaskItemDetail.helpers({
|
||||
BlazeComponent.extendComponent({
|
||||
// ...
|
||||
}).register('subtaskItemDetail');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-view-subtask'(event) {
|
||||
if ($(event.target).hasClass('js-view-subtask')) {
|
||||
const subtask = this.currentData().subtask;
|
||||
const board = subtask.board();
|
||||
FlowRouter.go('card', {
|
||||
boardId: board._id,
|
||||
slug: board.slug,
|
||||
cardId: subtask._id,
|
||||
});
|
||||
}
|
||||
},
|
||||
'click .js-delete-subtask' : Popup.afterConfirm('subtaskDelete', function () {
|
||||
Popup.back(2);
|
||||
const subtask = this.subtask;
|
||||
if (subtask && subtask._id) {
|
||||
subtask.archive();
|
||||
}
|
||||
}),
|
||||
}
|
||||
]
|
||||
}
|
||||
}).register('subtaskActionsPopup');
|
||||
@@ -1,142 +0,0 @@
|
||||
.js-add-subtask
|
||||
color: #8c8c8c
|
||||
|
||||
textarea.js-add-subtask-item, textarea.js-edit-subtask-item
|
||||
overflow: hidden
|
||||
word-wrap: break-word
|
||||
resize: none
|
||||
height: 34px
|
||||
|
||||
.delete-text
|
||||
color: #8c8c8c
|
||||
text-decoration: underline
|
||||
word-wrap: break-word
|
||||
float: right
|
||||
padding-top: 6px
|
||||
&:hover
|
||||
color: inherit
|
||||
|
||||
.subtask-title
|
||||
.checkbox
|
||||
float: left
|
||||
width: 30px
|
||||
height 30px
|
||||
font-size: 18px
|
||||
line-height: 30px
|
||||
|
||||
.title
|
||||
font-size: 18px
|
||||
line-height: 25px
|
||||
|
||||
.subtasks-stat
|
||||
margin: 0 0.5em
|
||||
float: right
|
||||
padding-top: 6px
|
||||
&.is-finished
|
||||
color: #3cb500
|
||||
|
||||
.js-delete-subtask
|
||||
@extends .delete-text
|
||||
margin: 0 0.5em
|
||||
|
||||
.js-view-subtask
|
||||
@extends .delete-text
|
||||
|
||||
.js-confirm-subtask-delete
|
||||
background-color: darken(white, 3%)
|
||||
position: absolute
|
||||
float: left;
|
||||
width: 60%
|
||||
margin-top: 0
|
||||
margin-left: 13%
|
||||
padding-bottom: 2%
|
||||
padding-left: 3%
|
||||
padding-right: 3%
|
||||
z-index: 17
|
||||
border-radius: 3px
|
||||
|
||||
p
|
||||
position: relative
|
||||
margin-top: 3%
|
||||
width: 100%
|
||||
text-align: center
|
||||
span
|
||||
font-weight: bold
|
||||
|
||||
i
|
||||
font-size: 2em
|
||||
|
||||
.js-subtask-delete-buttons
|
||||
position: relative
|
||||
padding: left 2% right 2%
|
||||
.confirm-subtask-delete
|
||||
margin-left: 12%
|
||||
float: left
|
||||
.toggle-delete-subtask-dialog
|
||||
margin-right: 12%
|
||||
float: right
|
||||
|
||||
#card-details-overlay
|
||||
top: 0
|
||||
bottom: -600px
|
||||
right: 0
|
||||
|
||||
.subtasks
|
||||
background: darken(white, 3%)
|
||||
|
||||
&.placeholder
|
||||
background: darken(white, 20%)
|
||||
border-radius: 2px
|
||||
|
||||
&.ui-sortable-helper
|
||||
box-shadow: -2px 2px 8px rgba(0, 0, 0, .3),
|
||||
0 0 1px rgba(0, 0, 0, .5)
|
||||
transform: rotate(4deg)
|
||||
cursor: grabbing
|
||||
|
||||
|
||||
.subtasks-item
|
||||
margin: 0 0 0 0.1em
|
||||
line-height: 18px
|
||||
font-size: 1.1em
|
||||
margin-top: 3px
|
||||
display: flex
|
||||
background: darken(white, 3%)
|
||||
|
||||
&.placeholder
|
||||
background: darken(white, 20%)
|
||||
border-radius: 2px
|
||||
|
||||
&.ui-sortable-helper
|
||||
box-shadow: -2px 2px 8px rgba(0, 0, 0, .3),
|
||||
0 0 1px rgba(0, 0, 0, .5)
|
||||
transform: rotate(4deg)
|
||||
cursor: grabbing
|
||||
|
||||
&:hover
|
||||
background-color: darken(white, 8%)
|
||||
|
||||
.check-box
|
||||
margin: 0.1em 0 0 0;
|
||||
&.is-checked
|
||||
border-bottom: 2px solid #3cb500
|
||||
border-right: 2px solid #3cb500
|
||||
|
||||
.item-title
|
||||
flex: 1
|
||||
padding-left: 10px;
|
||||
&.is-checked
|
||||
color: #8c8c8c
|
||||
font-style: italic
|
||||
& .viewer
|
||||
p
|
||||
margin-bottom: 2px
|
||||
|
||||
.js-delete-subtask-item
|
||||
margin: 0 0 0.5em 1.33em
|
||||
@extends .delete-text
|
||||
padding: 12px 0 0 0
|
||||
|
||||
.add-subtask-item
|
||||
margin: 0.2em 0 0.5em 1.33em
|
||||
display: inline-block
|
||||
@@ -0,0 +1,22 @@
|
||||
.datepicker-container .fields .left {
|
||||
width: 56%;
|
||||
}
|
||||
.datepicker-container .fields .right {
|
||||
width: 38%;
|
||||
}
|
||||
.datepicker-container .datepicker {
|
||||
width: 100%;
|
||||
}
|
||||
.datepicker-container .datepicker table {
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.datepicker-container .datepicker table thead {
|
||||
background: none;
|
||||
}
|
||||
.datepicker-container .datepicker table td,
|
||||
.datepicker-container .datepicker table th {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
.datepicker-container
|
||||
.fields
|
||||
.left
|
||||
width: 56%
|
||||
.right
|
||||
width: 38%
|
||||
.datepicker
|
||||
width: 100%
|
||||
table
|
||||
width: 100%
|
||||
border: none
|
||||
border-spacing: 0
|
||||
border-collapse: collapse
|
||||
thead
|
||||
background: none
|
||||
td, th
|
||||
box-sizing: border-box
|
||||
@@ -0,0 +1,736 @@
|
||||
select,
|
||||
textarea,
|
||||
input:not([type=file]),
|
||||
button {
|
||||
box-sizing: border-box;
|
||||
background-color: #ebebeb;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
min-height: 34px;
|
||||
padding: 7px;
|
||||
}
|
||||
select.full,
|
||||
textarea.full,
|
||||
input:not([type=file]).full,
|
||||
button.full {
|
||||
width: 100%;
|
||||
}
|
||||
select.input-error,
|
||||
textarea.input-error,
|
||||
input:not([type=file]).input-error,
|
||||
button.input-error {
|
||||
background-color: #ece9e9;
|
||||
border-color: #ba1212;
|
||||
}
|
||||
select:focus,
|
||||
textarea:focus,
|
||||
input:not([type=file]):focus,
|
||||
button:focus {
|
||||
outline: 0;
|
||||
}
|
||||
input[type="file"] {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
input[type="radio"] {
|
||||
-webkit-appearance: radio;
|
||||
min-height: inherit;
|
||||
}
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"] {
|
||||
transition: background 85ms ease-in, border-color 85ms ease-in;
|
||||
width: 250px;
|
||||
}
|
||||
input[type="text"].inline-input,
|
||||
input[type="password"].inline-input,
|
||||
input[type="email"].inline-input {
|
||||
background: none;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
min-height: 0;
|
||||
height: 18px;
|
||||
width: 200px;
|
||||
}
|
||||
input[type="text"].full-line,
|
||||
input[type="password"].full-line,
|
||||
input[type="email"].full-line {
|
||||
width: 100%;
|
||||
}
|
||||
input[type="email"]:invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
input[type="text"]:hover,
|
||||
input[type="password"]:hover,
|
||||
input[type="email"]:hover,
|
||||
textarea:hover {
|
||||
border-color: #999;
|
||||
}
|
||||
input[type="text"]:hover.input-error,
|
||||
input[type="password"]:hover.input-error,
|
||||
input[type="email"]:hover.input-error,
|
||||
textarea:hover.input-error {
|
||||
border-color: #ba1212;
|
||||
}
|
||||
input[type="text"]:focus,
|
||||
input[type="password"]:focus,
|
||||
input[type="email"]:focus,
|
||||
textarea:focus {
|
||||
background: #fff;
|
||||
border-color: #318ec4;
|
||||
box-shadow: 0 0 2px #318ec4;
|
||||
}
|
||||
input[type="text"]:focus.input-error,
|
||||
input[type="password"]:focus.input-error,
|
||||
input[type="email"]:focus.input-error,
|
||||
textarea:focus.input-error {
|
||||
background-color: #f8f7f7;
|
||||
border-color: #ba1212;
|
||||
box-shadow: 0 0 2px #d11515;
|
||||
}
|
||||
input[type="text"]:disabled,
|
||||
input[type="password"]:disabled,
|
||||
input[type="email"]:disabled,
|
||||
textarea:disabled {
|
||||
background-color: #dcdcdc;
|
||||
border-color: #bfbfbf;
|
||||
color: #8c8c8c;
|
||||
-webkit-touch-callout: none;
|
||||
user-select: none;
|
||||
}
|
||||
select {
|
||||
max-height: 300px;
|
||||
width: 256px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
select.inline {
|
||||
width: 100%;
|
||||
}
|
||||
option[disabled] {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
textarea {
|
||||
height: 150px;
|
||||
transition: background 85ms ease-in, border-color 85ms ease-in;
|
||||
resize: vertical;
|
||||
width: 100%;
|
||||
}
|
||||
textarea.editor {
|
||||
resize: none;
|
||||
padding-bottom: 22px;
|
||||
}
|
||||
.button {
|
||||
border-radius: 3px;
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
}
|
||||
input[type="submit"],
|
||||
button {
|
||||
background: #cfcfcf;
|
||||
background: linear-gradient(#cfcfcf, #c2c2c2);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-weight: 700;
|
||||
line-height: 22px;
|
||||
padding: 7px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
input[type="submit"] .wide,
|
||||
button .wide {
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
input[type="submit"]:hover,
|
||||
button:hover,
|
||||
input[type="submit"]:focus,
|
||||
button:focus {
|
||||
background: #c2c2c2;
|
||||
background: linear-gradient(#c2c2c2, #b5b5b5);
|
||||
}
|
||||
input[type="submit"]:active,
|
||||
button:active {
|
||||
background: #b5b5b5;
|
||||
background: linear-gradient(#b5b5b5, #a8a8a8);
|
||||
box-shadow: inset 0 3px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
input[type="submit"]:active:hover,
|
||||
button:active:hover,
|
||||
input[type="submit"]:active:focus,
|
||||
button:active:focus,
|
||||
input[type="submit"]:active:active,
|
||||
button:active:active {
|
||||
background: #e6e6e6;
|
||||
background: linear-gradient(#e6e6e6, #e6e6e6);
|
||||
}
|
||||
input[type="submit"].primary,
|
||||
button.primary {
|
||||
background: #005377;
|
||||
box-shadow: 0 1px 0 #4d4d4d;
|
||||
color: #fff;
|
||||
}
|
||||
input[type="submit"].primary:hover,
|
||||
button.primary:hover,
|
||||
input[type="submit"].primary:focus,
|
||||
button.primary:focus {
|
||||
background: #004766;
|
||||
}
|
||||
input[type="submit"].primary:active,
|
||||
button.primary:active {
|
||||
background: #01628c;
|
||||
}
|
||||
input[type="submit"].negate:hover,
|
||||
button.negate:hover,
|
||||
input[type="submit"].negate:focus,
|
||||
button.negate:focus {
|
||||
background: #990f0f;
|
||||
background: linear-gradient(#990f0f, #7d0c0c);
|
||||
box-shadow: 0 1px 0 #4d4d4d;
|
||||
color: #fff;
|
||||
}
|
||||
input[type="submit"].negate:active,
|
||||
button.negate:active {
|
||||
background: #7d0c0c;
|
||||
box-shadow: 0 1px 0 #4d4d4d;
|
||||
color: #fff;
|
||||
}
|
||||
input[type="submit"] i.fa,
|
||||
button i.fa {
|
||||
margin-right: 10px;
|
||||
}
|
||||
input[type="submit"].disabled,
|
||||
input[type="submit"]:disabled,
|
||||
input[type="button"].disabled,
|
||||
button.disabled,
|
||||
.button.disabled,
|
||||
input[type="submit"].disabled:hover,
|
||||
input[type="submit"]:disabled:hover,
|
||||
input[type="button"].disabled:hover,
|
||||
button.disabled:hover,
|
||||
.button.disabled:hover,
|
||||
input[type="submit"].disabled:active,
|
||||
input[type="submit"]:disabled:active,
|
||||
input[type="button"].disabled:active,
|
||||
button.disabled:active,
|
||||
.button.disabled:active {
|
||||
background: #cfcfcf;
|
||||
cursor: default;
|
||||
box-shadow: none;
|
||||
color: #a8a8a8;
|
||||
}
|
||||
fieldset {
|
||||
border: 1px solid #bfbfbf;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
input[type="hidden"] {
|
||||
display: none;
|
||||
}
|
||||
.radio-div,
|
||||
.check-div {
|
||||
display: block;
|
||||
margin: 0 0 4px 20px;
|
||||
min-height: 20px;
|
||||
position: relative;
|
||||
}
|
||||
.radio-div input,
|
||||
.check-div input {
|
||||
left: -18px;
|
||||
min-height: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
}
|
||||
.radio-div label,
|
||||
.check-div label {
|
||||
font-weight: 400;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
label.form-error {
|
||||
color: #ba1212;
|
||||
}
|
||||
input::-webkit-input-placeholder,
|
||||
textarea::-webkit-input-placeholder,
|
||||
input::-moz-placeholder,
|
||||
textarea::-moz-placeholder {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
.edit-controls,
|
||||
.add-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.edit-controls button[type=submit],
|
||||
.add-controls button[type=submit],
|
||||
.edit-controls input[type=button],
|
||||
.add-controls input[type=button] {
|
||||
float: left;
|
||||
height: 32px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.edit-controls .fa-times-thin,
|
||||
.add-controls .fa-times-thin {
|
||||
font-size: 26px;
|
||||
margin: 3px 10px;
|
||||
}
|
||||
[type="checkbox"]:not(:checked),
|
||||
[type="checkbox"]:checked {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
visibility: hidden;
|
||||
display: none;
|
||||
}
|
||||
.materialCheckBox {
|
||||
position: relative;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
z-index: 0;
|
||||
border: 2px solid #5a5a5a;
|
||||
border-radius: 1px;
|
||||
transition: 0.2s;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.materialCheckBox.is-checked {
|
||||
top: -4px;
|
||||
left: -3px;
|
||||
width: 7px;
|
||||
height: 15px;
|
||||
margin-right: 6px;
|
||||
border-top: 2px solid transparent;
|
||||
border-left: 2px solid transparent;
|
||||
transform: rotate(40deg);
|
||||
-webkit-backface-visibility: hidden;
|
||||
transform-origin: 100% 100%;
|
||||
}
|
||||
.button-link {
|
||||
background: #fff;
|
||||
background: linear-gradient(#fff, #f5f5f5);
|
||||
border-radius: 3px;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
border: 1px solid #e3e3e3;
|
||||
border-bottom-color: #c2c2c2;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
height: 34px;
|
||||
margin-top: 6px;
|
||||
max-width: 300px;
|
||||
padding: 7px;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
overflow: ellipsis;
|
||||
}
|
||||
.button-link .on {
|
||||
background: #48b512;
|
||||
background: linear-gradient(#48b512, #3d990f);
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
display: none;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
height: 17px;
|
||||
line-height: 17px;
|
||||
margin: 0;
|
||||
padding: 2px 4px;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
.button-link.is-on {
|
||||
padding-right: 30px;
|
||||
max-width: 196px;
|
||||
}
|
||||
.button-link.is-on .on {
|
||||
display: block;
|
||||
}
|
||||
.button-link.inline {
|
||||
color: #666;
|
||||
padding: 2px 14px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.button-link.setting {
|
||||
height: 52px;
|
||||
float: left;
|
||||
position: relative;
|
||||
margin-top: 0;
|
||||
}
|
||||
.button-link.setting.disabled {
|
||||
background: #fff;
|
||||
border-color: #e9e9e9;
|
||||
color: #8c8c8c;
|
||||
cursor: default;
|
||||
}
|
||||
.button-link.setting.disabled select {
|
||||
display: none;
|
||||
}
|
||||
.button-link.setting.disabled:hover .label {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
.button-link.setting.disabled,
|
||||
.button-link.setting.disabled:hover,
|
||||
.button-link.setting.disabled:active,
|
||||
.button-link.setting.disabled.primary,
|
||||
.button-link.setting.disabled.primary:hover,
|
||||
.button-link.setting.disabled.primary:active {
|
||||
background: #cfcfcf;
|
||||
border-color: #c2c2c2;
|
||||
border-bottom-color: #b5b5b5;
|
||||
cursor: default;
|
||||
box-shadow: none;
|
||||
color: #a8a8a8;
|
||||
}
|
||||
.button-link.setting .label {
|
||||
color: #8c8c8c;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.button-link.setting:hover .label {
|
||||
color: #eee;
|
||||
}
|
||||
.button-link.setting .value {
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.button-link.setting label {
|
||||
display: none;
|
||||
}
|
||||
.button-link.setting select {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
height: 50px;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
}
|
||||
.button-link:hover {
|
||||
background: #318ec4;
|
||||
background: linear-gradient(#318ec4, #2b7cab);
|
||||
border-color: #2e85b8;
|
||||
color: #fff;
|
||||
}
|
||||
.button-link:hover .on {
|
||||
background-image: none;
|
||||
background-color: rgba(255,255,255,0.3);
|
||||
border-color: transparent;
|
||||
}
|
||||
.button-link:active {
|
||||
background: #2e85b8;
|
||||
background: linear-gradient(#2e85b8, #28739f);
|
||||
border-color: #2b7cab;
|
||||
color: #fff;
|
||||
}
|
||||
.button-link .button-link.negate:hover {
|
||||
background: #990f0f;
|
||||
background: linear-gradient(#990f0f, #7d0c0c);
|
||||
border-color: linear-gradient(#990f0f, #7d0c0c);
|
||||
}
|
||||
.button-link .button-link.negate:active {
|
||||
background: #7d0c0c;
|
||||
border-color: #990f0f;
|
||||
}
|
||||
.button-link.primary {
|
||||
background: #48b512;
|
||||
background: linear-gradient(#48b512, #3d990f);
|
||||
border: 1px solid;
|
||||
border-color: #3d990f;
|
||||
color: #fff;
|
||||
}
|
||||
.button-link.primary:hover {
|
||||
background: #3d990f;
|
||||
background: linear-gradient(#3d990f, #327d0c);
|
||||
border-color: #3d990f;
|
||||
}
|
||||
.button-link.danger {
|
||||
background: #ba1212;
|
||||
background: linear-gradient(#ba1212, #8b0e0e);
|
||||
border: 1px solid;
|
||||
border-color: #a21010;
|
||||
color: #fff;
|
||||
}
|
||||
.button-link.danger:hover {
|
||||
background: #a21010;
|
||||
background: linear-gradient(#a21010, #740b0b);
|
||||
border-color: #8b0e0e;
|
||||
}
|
||||
button.quiet-button,
|
||||
button.loud-text-button {
|
||||
background: none;
|
||||
text-align: left;
|
||||
line-height: normal;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
button.quiet-button:active,
|
||||
button.loud-text-button:active {
|
||||
color: #4d4d4d;
|
||||
background: #d3d3d3;
|
||||
box-shadow: none;
|
||||
}
|
||||
button.quiet-button {
|
||||
font-weight: 400;
|
||||
text-decoration: underline;
|
||||
}
|
||||
button.loud-text-button {
|
||||
width: 100%;
|
||||
}
|
||||
button.loud-text-button:hover {
|
||||
color: #111;
|
||||
}
|
||||
.emphasis-button,
|
||||
.quiet-button {
|
||||
border-radius: 3px;
|
||||
user-select: none;
|
||||
color: #8c8c8c;
|
||||
display: block;
|
||||
margin: 2px 0;
|
||||
padding: 6px 8px;
|
||||
position: relative;
|
||||
}
|
||||
.emphasis-button.w-img,
|
||||
.quiet-button.w-img {
|
||||
padding-left: 28px;
|
||||
}
|
||||
.emphasis-button:hover,
|
||||
.quiet-button:hover {
|
||||
color: #4d4d4d;
|
||||
background: #dcdcdc;
|
||||
}
|
||||
.emphasis-button:active,
|
||||
.quiet-button:active {
|
||||
color: #4d4d4d;
|
||||
background: #d3d3d3;
|
||||
}
|
||||
.quiet-button-large {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
.emphasis-button {
|
||||
color: #74663e;
|
||||
background: #ecdfbb;
|
||||
}
|
||||
.emphasis-button:hover {
|
||||
color: #53492d;
|
||||
background: #e7d6a7;
|
||||
}
|
||||
.emphasis-button:active {
|
||||
color: #53492d;
|
||||
background: #e1cc93;
|
||||
}
|
||||
.is-editable {
|
||||
cursor: pointer;
|
||||
}
|
||||
.big-link {
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
margin: 6px 0 6px 40px;
|
||||
padding: 11px;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.big-link .text {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.big-link:hover {
|
||||
background: #dcdcdc;
|
||||
}
|
||||
.big-link.options {
|
||||
padding-right: 41px;
|
||||
}
|
||||
.big-link .option {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 6px;
|
||||
}
|
||||
.big-link.none {
|
||||
color: #8c8c8c;
|
||||
text-decoration: none;
|
||||
}
|
||||
.big-link.none:hover {
|
||||
background: transparent;
|
||||
}
|
||||
.big-link.avatar-changer {
|
||||
padding-right: 51px;
|
||||
}
|
||||
.big-link.avatar-changer .member {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.big-link.avatar-changer .member .member-avatar {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
.big-link.avatar-changer .member .member-initials {
|
||||
font-size: 16px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
max-height: 40px;
|
||||
}
|
||||
.show-more {
|
||||
border-radius: 3px;
|
||||
color: #8c8c8c;
|
||||
display: block;
|
||||
padding: 16px 8px 16px 40px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
.show-more:hover {
|
||||
background: #dcdcdc;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.show-more.compact {
|
||||
padding: 12px 8px;
|
||||
margin: 8px 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
.board-widget .show-more {
|
||||
padding: 12px 8px 12px 40px;
|
||||
}
|
||||
.uploader {
|
||||
clear: both;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
}
|
||||
.uploader .realfile {
|
||||
cursor: pointer;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
font-size: 23px;
|
||||
}
|
||||
.uploader .realfile input[type="file"] {
|
||||
cursor: pointer;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
z-index: 2;
|
||||
font-size: 23px;
|
||||
}
|
||||
.uploader:hover .fakefile {
|
||||
background: #318ec4;
|
||||
background: linear-gradient(#318ec4, #2b7cab);
|
||||
border-color: #2e85b8;
|
||||
color: #fff;
|
||||
}
|
||||
.dropdown-menu {
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.dropdown-menu li {
|
||||
border-top: none;
|
||||
}
|
||||
.dropdown-menu li a {
|
||||
padding: 4px 12px 4px 8px;
|
||||
}
|
||||
.dropdown-menu li a img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.dropdown-menu li a .minicard-label {
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
border-radius: 2px;
|
||||
margin: 2px 7px -2px -2px;
|
||||
display: inline-block;
|
||||
}
|
||||
.dropdown-menu li.active {
|
||||
background: #005377;
|
||||
}
|
||||
.dropdown-menu li.active a,
|
||||
.dropdown-menu li.active .quiet {
|
||||
color: #fff;
|
||||
}
|
||||
.material-toggle-switch {
|
||||
display: flex;
|
||||
}
|
||||
.toggle-label {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 20px;
|
||||
width: 44px;
|
||||
background-color: #a6a6a6;
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.toggle-label:after {
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
top: -3px;
|
||||
display: block;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border-radius: 100px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.05);
|
||||
content: '';
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.toggle-label:active:after {
|
||||
transform: scale(1.15, 0.85);
|
||||
}
|
||||
.toggle-switch:checked ~ .toggle-label {
|
||||
background-color: #6fbeb5;
|
||||
}
|
||||
.toggle-switch:checked ~ .toggle-label:after {
|
||||
left: 20px;
|
||||
background-color: #179588;
|
||||
}
|
||||
.toggle-switch:checked:disabled ~ .toggle-label {
|
||||
background-color: #d5d5d5;
|
||||
pointer-events: none;
|
||||
}
|
||||
.toggle-switch:checked:disabled ~ .toggle-label:after {
|
||||
background-color: #bcbdbc;
|
||||
}
|
||||
.toggle-switch {
|
||||
display: none;
|
||||
}
|
||||
.toggle-switch-title {
|
||||
margin: 0 0.5em;
|
||||
display: flex;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.edit-controls .fa-times-thin,
|
||||
.add-controls .fa-times-thin {
|
||||
margin: 3px 20px;
|
||||
}
|
||||
}
|
||||
@@ -1,696 +0,0 @@
|
||||
@import 'nib'
|
||||
|
||||
select,
|
||||
textarea,
|
||||
input:not([type=file]),
|
||||
button
|
||||
box-sizing: border-box
|
||||
background-color: #ebebeb
|
||||
border: 1px solid #ccc
|
||||
border-radius: 3px
|
||||
display: block
|
||||
margin-bottom: 12px
|
||||
min-height: 34px
|
||||
padding: 7px
|
||||
|
||||
&.full
|
||||
width: 100%
|
||||
|
||||
&.input-error
|
||||
background-color: #ece9e9
|
||||
border-color: #ba1212
|
||||
|
||||
&:focus
|
||||
outline: 0
|
||||
|
||||
input[type="file"]
|
||||
margin-bottom: 16px
|
||||
|
||||
input[type="radio"]
|
||||
-webkit-appearance: radio
|
||||
min-height: inherit
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"]
|
||||
transition: background 85ms ease-in,
|
||||
border-color 85ms ease-in
|
||||
width: 250px
|
||||
|
||||
&.inline-input
|
||||
background: none
|
||||
border: 0
|
||||
margin: 0
|
||||
padding: 2px
|
||||
min-height: 0
|
||||
height: 18px
|
||||
width: 200px
|
||||
|
||||
&.full-line
|
||||
width: 100%
|
||||
|
||||
input[type="email"]:invalid
|
||||
box-shadow: none
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"],
|
||||
textarea
|
||||
|
||||
&:hover
|
||||
border-color: #999
|
||||
|
||||
&.input-error
|
||||
border-color: #ba1212
|
||||
|
||||
&:focus
|
||||
background: #fff
|
||||
border-color: #318ec4
|
||||
box-shadow: 0 0 2px #318ec4
|
||||
|
||||
&.input-error
|
||||
background-color: #f8f7f7
|
||||
border-color: #ba1212
|
||||
box-shadow: 0 0 2px #d11515
|
||||
|
||||
&:disabled
|
||||
background-color: #dcdcdc
|
||||
border-color: #bfbfbf
|
||||
color: #8c8c8c
|
||||
-webkit-touch-callout: none
|
||||
user-select: none
|
||||
|
||||
select
|
||||
max-height: 300px
|
||||
width: 256px
|
||||
margin-bottom: 8px
|
||||
|
||||
&.inline
|
||||
width: 100%
|
||||
|
||||
option[disabled]
|
||||
color: #8c8c8c
|
||||
|
||||
textarea
|
||||
height: 150px
|
||||
transition: background 85ms ease-in,
|
||||
border-color 85ms ease-in
|
||||
resize: vertical
|
||||
width: 100%
|
||||
|
||||
&.editor
|
||||
resize: none
|
||||
padding-bottom: 22px
|
||||
|
||||
|
||||
.button
|
||||
border-radius: 3px
|
||||
text-decoration: none
|
||||
position: relative
|
||||
|
||||
input[type="submit"],
|
||||
button
|
||||
background: #cfcfcf
|
||||
background: linear-gradient(#cfcfcf, #c2c2c2)
|
||||
border: none
|
||||
cursor: pointer
|
||||
display: inline-block
|
||||
font-weight: 700
|
||||
line-height: 22px
|
||||
margin: 8px 4px 0 0
|
||||
padding: 7px 20px
|
||||
text-align: center
|
||||
|
||||
.wide
|
||||
padding-left: 30px
|
||||
padding-right: 30px
|
||||
|
||||
&:hover,
|
||||
&:focus
|
||||
background: #c2c2c2
|
||||
background: linear-gradient(#c2c2c2, #b5b5b5)
|
||||
|
||||
&:active
|
||||
background: #b5b5b5
|
||||
background: linear-gradient(#b5b5b5, #a8a8a8)
|
||||
box-shadow: inset 0 3px 6px rgba(0, 0, 0, .1)
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active
|
||||
background: #e6e6e6
|
||||
background: linear-gradient(#e6e6e6, #e6e6e6)
|
||||
|
||||
&.primary
|
||||
background: #005377
|
||||
box-shadow: 0 1px 0 #4d4d4d
|
||||
color: white
|
||||
|
||||
&:hover,
|
||||
&:focus
|
||||
background: #004766
|
||||
|
||||
&:active
|
||||
background: #01628C
|
||||
|
||||
&.negate
|
||||
&:hover,
|
||||
&:focus
|
||||
background: #990f0f
|
||||
background: linear-gradient(#990f0f, #7d0c0c)
|
||||
box-shadow: 0 1px 0 #4d4d4d
|
||||
color: #fff
|
||||
|
||||
&:active
|
||||
background: #7d0c0c
|
||||
box-shadow: 0 1px 0 #4d4d4d
|
||||
color: #fff
|
||||
|
||||
i.fa
|
||||
margin-right: 10px
|
||||
|
||||
input[type="submit"].disabled,
|
||||
input[type="submit"]:disabled,
|
||||
input[type="button"].disabled,
|
||||
button.disabled,
|
||||
.button.disabled
|
||||
|
||||
&,
|
||||
&:hover,
|
||||
&:active
|
||||
background: #cfcfcf
|
||||
cursor: default
|
||||
box-shadow: none
|
||||
color: #a8a8a8
|
||||
|
||||
fieldset
|
||||
border: 1px solid #bfbfbf
|
||||
padding: 15px
|
||||
margin-bottom: 15px
|
||||
|
||||
input[type="hidden"]
|
||||
display: none
|
||||
|
||||
.radio-div,
|
||||
.check-div
|
||||
display: block
|
||||
margin: 0 0 4px 20px
|
||||
min-height: 20px
|
||||
position: relative
|
||||
|
||||
input
|
||||
left: -18px
|
||||
min-height: 0
|
||||
margin: 0
|
||||
padding: 0
|
||||
position: absolute
|
||||
top: 2px
|
||||
|
||||
label
|
||||
font-weight: 400
|
||||
|
||||
label
|
||||
display: block
|
||||
font-weight: 700
|
||||
margin-bottom: 4px
|
||||
|
||||
&.form-error
|
||||
color: #ba1212
|
||||
|
||||
input,
|
||||
textarea
|
||||
&::-webkit-input-placeholder,
|
||||
&::-moz-placeholder
|
||||
color: #8c8c8c
|
||||
|
||||
.edit-controls,
|
||||
.add-controls
|
||||
display: flex
|
||||
align-items: baseline
|
||||
margin-top: 0
|
||||
|
||||
button[type=submit]
|
||||
input[type=button]
|
||||
float: left
|
||||
height: 32px
|
||||
margin-top: -2px
|
||||
padding-top: 5px
|
||||
padding-bottom: 5px
|
||||
|
||||
.fa-times-thin
|
||||
font-size: 26px
|
||||
margin: 3px 4px
|
||||
|
||||
// Material Design checkboxes
|
||||
[type="checkbox"]:not(:checked),
|
||||
[type="checkbox"]:checked
|
||||
position: absolute
|
||||
left: -9999px
|
||||
visibility: hidden
|
||||
|
||||
.materialCheckBox
|
||||
position: relative
|
||||
width: 13px
|
||||
height: @width
|
||||
z-index: 0
|
||||
border: 2px solid #5a5a5a
|
||||
border-radius: 1px
|
||||
transition: .2s
|
||||
margin: 0
|
||||
cursor: pointer
|
||||
|
||||
&.is-checked
|
||||
top: -4px
|
||||
left: -3px
|
||||
width: 7px
|
||||
height: 15px
|
||||
margin-right: 6px
|
||||
border-top: 2px solid transparent
|
||||
border-left: 2px solid transparent
|
||||
transform: rotate(40deg)
|
||||
-webkit-backface-visibility: hidden
|
||||
transform-origin: 100% 100%
|
||||
|
||||
.button-link
|
||||
background: #fff
|
||||
background: linear-gradient(#fff, #f5f5f5)
|
||||
border-radius: 3px
|
||||
box-sizing: border-box
|
||||
user-select: none
|
||||
border: 1px solid #e3e3e3
|
||||
border-bottom-color: #c2c2c2
|
||||
cursor: pointer
|
||||
display: block
|
||||
font-weight: 700
|
||||
height: 34px
|
||||
margin-top: 6px
|
||||
max-width: 300px
|
||||
padding: 7px
|
||||
position: relative
|
||||
text-decoration: none
|
||||
overflow: ellipsis
|
||||
|
||||
.on
|
||||
background: #48b512
|
||||
background: linear-gradient(#48b512, #3d990f)
|
||||
border-radius: 3px
|
||||
color: #fff
|
||||
display: none
|
||||
font-size: 12px
|
||||
font-weight: 700
|
||||
height: 17px
|
||||
line-height: @height
|
||||
margin: 0
|
||||
padding: 2px 4px
|
||||
position: absolute
|
||||
right: 5px
|
||||
top: 5px
|
||||
text-align: center
|
||||
|
||||
&.is-on
|
||||
padding-right: 30px
|
||||
max-width: 196px
|
||||
|
||||
.on
|
||||
display: block
|
||||
|
||||
&.inline
|
||||
color: #666
|
||||
padding: 2px 14px
|
||||
margin-left: 4px
|
||||
|
||||
&.setting
|
||||
height: 52px
|
||||
float: left
|
||||
position: relative
|
||||
margin-top: 0
|
||||
|
||||
&.disabled
|
||||
background: #fff
|
||||
border-color: #e9e9e9
|
||||
color: #8c8c8c
|
||||
cursor: default
|
||||
|
||||
select
|
||||
display: none
|
||||
|
||||
&:hover .label
|
||||
color: #8c8c8c
|
||||
|
||||
&,
|
||||
&:hover,
|
||||
&:active,
|
||||
&.primary,
|
||||
&.primary:hover,
|
||||
&.primary:active
|
||||
background: #cfcfcf
|
||||
border-color: #c2c2c2
|
||||
border-bottom-color: #b5b5b5
|
||||
cursor: default
|
||||
box-shadow: none
|
||||
color: #a8a8a8
|
||||
|
||||
.label
|
||||
color: #8c8c8c
|
||||
display: block
|
||||
font-size: 12px
|
||||
line-height: 14px
|
||||
margin-bottom: 0
|
||||
|
||||
&:hover .label
|
||||
color: #eee
|
||||
|
||||
.value
|
||||
display: block
|
||||
font-size: 18px
|
||||
line-height: 24px
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
|
||||
label
|
||||
display: none
|
||||
|
||||
select
|
||||
border: none
|
||||
cursor: pointer
|
||||
height: 50px
|
||||
left: 0
|
||||
margin: 0
|
||||
opacity: 0
|
||||
position: absolute
|
||||
top: 0
|
||||
z-index: 2
|
||||
width: 100%
|
||||
|
||||
&:hover
|
||||
background: #318ec4
|
||||
background: linear-gradient(#318ec4, #2b7cab)
|
||||
border-color: #2e85b8
|
||||
color: #fff
|
||||
|
||||
.on
|
||||
background-image: none
|
||||
background-color: rgba(255, 255, 255, .3)
|
||||
border-color: transparent
|
||||
|
||||
&:active
|
||||
background: #2e85b8
|
||||
background: linear-gradient(#2e85b8, #28739f)
|
||||
border-color: #2b7cab
|
||||
color: #fff
|
||||
|
||||
.button-link.negate
|
||||
|
||||
&:hover
|
||||
background: #990f0f
|
||||
background: linear-gradient(#990f0f, #7d0c0c)
|
||||
border-color: @background
|
||||
|
||||
&:active
|
||||
background: #7d0c0c
|
||||
border-color: #990f0f
|
||||
|
||||
|
||||
&.primary
|
||||
background: #48b512
|
||||
background: linear-gradient(#48b512, #3d990f)
|
||||
border: 1px solid
|
||||
border-color: #3d990f
|
||||
color: #fff
|
||||
|
||||
&:hover
|
||||
background: #3d990f
|
||||
background: linear-gradient(#3d990f, #327d0c)
|
||||
border-color: #3d990f
|
||||
|
||||
&.danger
|
||||
background: #ba1212
|
||||
background: linear-gradient(#ba1212, #8b0e0e)
|
||||
border: 1px solid
|
||||
border-color: #a21010
|
||||
color: #fff
|
||||
|
||||
&:hover
|
||||
background: #a21010
|
||||
background: linear-gradient(#a21010, #740b0b)
|
||||
border-color: #8b0e0e
|
||||
|
||||
button
|
||||
&.quiet-button,
|
||||
&.loud-text-button
|
||||
background: none
|
||||
text-align: left
|
||||
line-height: normal
|
||||
border: none
|
||||
box-shadow: none
|
||||
|
||||
&:active
|
||||
color: #4d4d4d
|
||||
background: #d3d3d3
|
||||
box-shadow: none
|
||||
|
||||
&.quiet-button
|
||||
font-weight: 400
|
||||
text-decoration: underline
|
||||
|
||||
&.loud-text-button
|
||||
width: 100%
|
||||
|
||||
&:hover
|
||||
color: #111
|
||||
|
||||
.emphasis-button,
|
||||
.quiet-button
|
||||
border-radius: 3px
|
||||
user-select: none
|
||||
color: #8c8c8c
|
||||
display: block
|
||||
margin: 2px 0
|
||||
padding: 6px 8px
|
||||
position: relative
|
||||
|
||||
&.w-img
|
||||
padding-left: 28px
|
||||
|
||||
&:hover
|
||||
color: #4d4d4d
|
||||
background: #dcdcdc
|
||||
|
||||
&:active
|
||||
color: #4d4d4d
|
||||
background: #d3d3d3
|
||||
|
||||
.quiet-button-large
|
||||
padding: 16px 24px
|
||||
|
||||
.emphasis-button
|
||||
color: #74663e
|
||||
background: #ecdfbb
|
||||
|
||||
&:hover
|
||||
color: #53492d
|
||||
background: #e7d6a7
|
||||
|
||||
&:active
|
||||
color: #53492d
|
||||
background: #e1cc93
|
||||
|
||||
.is-editable
|
||||
cursor: pointer
|
||||
|
||||
.big-link
|
||||
border-radius: 3px
|
||||
display: block
|
||||
margin: 6px 0 6px 40px
|
||||
padding: 11px
|
||||
position: relative
|
||||
text-decoration: none
|
||||
font-size: 16px
|
||||
line-height: 20px
|
||||
|
||||
.text
|
||||
text-decoration: underline
|
||||
|
||||
&:hover
|
||||
background: #dcdcdc
|
||||
|
||||
&.options
|
||||
padding-right: 41px
|
||||
|
||||
.option
|
||||
height: 30px
|
||||
width: @height
|
||||
position: absolute
|
||||
right: 6px
|
||||
top: 6px
|
||||
|
||||
&.none
|
||||
color: #8c8c8c
|
||||
text-decoration: none
|
||||
|
||||
&:hover
|
||||
background: transparent
|
||||
|
||||
&.avatar-changer
|
||||
padding-right: 51px
|
||||
|
||||
.member
|
||||
border: 1px solid #ccc
|
||||
border-radius: 3px
|
||||
height: 40px
|
||||
width: @height
|
||||
position: absolute
|
||||
right: 0
|
||||
top: 0
|
||||
|
||||
.member-avatar
|
||||
height: 40px
|
||||
width: @height
|
||||
|
||||
.member-initials
|
||||
font-size: 16px
|
||||
height: 40px
|
||||
line-height: @height
|
||||
max-height: @height
|
||||
|
||||
.show-more
|
||||
border-radius: 3px
|
||||
color: #8c8c8c
|
||||
display: block
|
||||
padding: 16px 8px 16px 40px
|
||||
margin: 8px 0
|
||||
|
||||
&:hover
|
||||
background: #dcdcdc
|
||||
text-decoration: underline
|
||||
|
||||
&.compact
|
||||
padding: 12px 8px
|
||||
margin: 8px 0 0
|
||||
text-align: center
|
||||
|
||||
.board-widget .show-more
|
||||
padding: 12px 8px 12px 40px
|
||||
|
||||
.uploader
|
||||
clear: both
|
||||
cursor: pointer
|
||||
position: relative
|
||||
height: 34px
|
||||
width: 100%
|
||||
|
||||
.realfile
|
||||
cursor: pointer
|
||||
height: 34px
|
||||
line-height: @height
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
width: 100%
|
||||
z-index: 2
|
||||
font-size: 23px
|
||||
|
||||
input[type="file"]
|
||||
cursor: pointer
|
||||
height: 34px
|
||||
line-height: @height
|
||||
margin: 0
|
||||
opacity: 0
|
||||
padding: 0
|
||||
width: 100%
|
||||
z-index: 2
|
||||
font-size: 23px
|
||||
|
||||
&:hover .fakefile
|
||||
background: #318ec4
|
||||
background: linear-gradient(#318ec4, #2b7cab)
|
||||
border-color: #2e85b8
|
||||
color: #fff
|
||||
|
||||
.dropdown-menu
|
||||
border-radius: 2px
|
||||
overflow: hidden
|
||||
|
||||
li
|
||||
border-top: none
|
||||
|
||||
a
|
||||
padding: 4px 12px 4px 8px
|
||||
|
||||
img
|
||||
width: 18px
|
||||
height: @width
|
||||
margin-right: 5px
|
||||
vertical-align: middle
|
||||
|
||||
.minicard-label
|
||||
width: 11px
|
||||
height: @width
|
||||
border-radius: 2px
|
||||
margin: 2px 7px -2px -2px
|
||||
display: inline-block
|
||||
|
||||
&.active
|
||||
background: #005377
|
||||
|
||||
a, .quiet
|
||||
color: white
|
||||
|
||||
// Material Design Toggle Switch
|
||||
.material-toggle-switch
|
||||
display: flex
|
||||
|
||||
.toggle-label
|
||||
position: relative
|
||||
display: block
|
||||
height: 20px
|
||||
width: 44px
|
||||
background-color: #a6a6a6
|
||||
border-radius: 100px
|
||||
cursor: pointer
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:after
|
||||
position: absolute
|
||||
left: -2px
|
||||
top: -3px
|
||||
display: block
|
||||
width: 26px
|
||||
height: 26px
|
||||
border-radius: 100px
|
||||
background-color: #fff
|
||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.05)
|
||||
content: ''
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:active
|
||||
&:after
|
||||
transform: scale(1.15, 0.85)
|
||||
|
||||
.toggle-switch:checked ~ .toggle-label
|
||||
background-color: #6fbeb5
|
||||
|
||||
&:after
|
||||
left: 20px
|
||||
background-color: #179588
|
||||
|
||||
.toggle-switch:checked:disabled ~ .toggle-label
|
||||
background-color: #d5d5d5
|
||||
pointer-events: none
|
||||
|
||||
&:after
|
||||
background-color: #bcbdbc
|
||||
|
||||
.toggle-switch
|
||||
display: none
|
||||
|
||||
.toggle-switch-title
|
||||
margin: 0 0.5em
|
||||
display: flex
|
||||
|
||||
|
||||
@media screen and (max-width: 800px)
|
||||
.edit-controls,
|
||||
.add-controls
|
||||
.fa-times-thin
|
||||
margin: 3px 20px
|
||||
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
.map-members:after {
|
||||
content: "";
|
||||
flex: auto;
|
||||
}
|
||||
.map-members .mapping-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -4px;
|
||||
}
|
||||
.map-members .mapping-list .mapping-item {
|
||||
max-width: 300px;
|
||||
min-width: 200px;
|
||||
padding: 6px;
|
||||
margin: 5px;
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
|
||||
}
|
||||
.map-members .mapping-list .mapping-item:hover {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
.map-members .mapping-list .mapping-item.filled {
|
||||
background: #e0ffe5;
|
||||
}
|
||||
.map-members .mapping-list .mapping-item.filled:hover {
|
||||
background: #ffe0e0;
|
||||
}
|
||||
.map-members .mapping-list .mapping-item.ghost-item {
|
||||
height: 0;
|
||||
visibility: hidden;
|
||||
border: none;
|
||||
}
|
||||
.map-members .mapping-list .profile-source {
|
||||
display: inline-block;
|
||||
width: 80%;
|
||||
}
|
||||
.map-members .mapping-list .wekan {
|
||||
display: inline-block;
|
||||
width: 35px;
|
||||
}
|
||||
.map-members .mapping-list .wekan .member {
|
||||
float: none;
|
||||
}
|
||||
a.show-mapping {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.import-members-map-note {
|
||||
font-size: 90%;
|
||||
font-weight: bold;
|
||||
}
|
||||
Loaded 100 of 657 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user