Compare commits
928 Commits
backport/5
...
release/1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34741c3efd | ||
|
|
36646f8be8 | ||
|
|
231b6e5be3 | ||
|
|
8398dcdb6f | ||
|
|
63846cb72a | ||
|
|
040f48657a | ||
|
|
16c44c36dc | ||
|
|
d5a443ebbd | ||
|
|
bba0d951d5 | ||
|
|
2dd0c09a38 | ||
|
|
01a527b748 | ||
|
|
dd2641d250 | ||
|
|
2c6a38d2ba | ||
|
|
af27b4ff05 | ||
|
|
91347360aa | ||
|
|
49ce3ea9b3 | ||
|
|
2dde00690c | ||
|
|
7eac5db40a | ||
|
|
e93526fde0 | ||
|
|
405a48ba57 | ||
|
|
6dd9edb2af | ||
|
|
4e3493c047 | ||
|
|
566c521139 | ||
|
|
83d80d65d7 | ||
|
|
810ff87893 | ||
|
|
c458a201be | ||
|
|
3810b1ed03 | ||
|
|
7e0c336eef | ||
|
|
547dcbc35b | ||
|
|
52032dd3d1 | ||
|
|
7d7edfb3b0 | ||
|
|
2f124c2f14 | ||
|
|
e0f88e6a27 | ||
|
|
3896c1c9ee | ||
|
|
8670380001 | ||
|
|
9cd58cae17 | ||
|
|
304a4e290e | ||
|
|
e43ad40335 | ||
|
|
5c9df98aee | ||
|
|
548637155c | ||
|
|
4ac0ba920b | ||
|
|
16f7f5453a | ||
|
|
35ee8dc5d1 | ||
|
|
55849d0efb | ||
|
|
1ebae75d25 | ||
|
|
224921e033 | ||
|
|
b942ac9cc1 | ||
|
|
ca063c0f6c | ||
|
|
29d7abd76a | ||
|
|
a9b8fce30e | ||
|
|
6a41c6403e | ||
|
|
e9bf197b29 | ||
|
|
55a28b0853 | ||
|
|
d35f15d65d | ||
|
|
a448546f43 | ||
|
|
a83bcbc00c | ||
|
|
d1b9db0c51 | ||
|
|
2b3c43d658 | ||
|
|
7d6e9feab0 | ||
|
|
53c79253ff | ||
|
|
00dbcd962e | ||
|
|
4eeb67bb56 | ||
|
|
59fe26b1ba | ||
|
|
567ecd782e | ||
|
|
3b5b471c87 | ||
|
|
7211d73159 | ||
|
|
6da7aa5480 | ||
|
|
8832a345b8 | ||
|
|
4e7d50bf2c | ||
|
|
6a6bd5b72b | ||
|
|
5767b70613 | ||
|
|
dc4b77edc8 | ||
|
|
2c1835a287 | ||
|
|
1fd3592ebe | ||
|
|
e5417f0eed | ||
|
|
ee6be8404c | ||
|
|
f5b0077de4 | ||
|
|
97f05e6374 | ||
|
|
4e2b33127c | ||
|
|
20def97ddf | ||
|
|
a1c486cefa | ||
|
|
224a8a059d | ||
|
|
50587f2202 | ||
|
|
b1793e12f8 | ||
|
|
305315c031 | ||
|
|
0803b9bdc2 | ||
|
|
ff3a2ae3c0 | ||
|
|
13e89ae68f | ||
|
|
1b83dfc372 | ||
|
|
cf5ff3cd55 | ||
|
|
0be801dee3 | ||
|
|
f975dc6863 | ||
|
|
c8e94b5b2f | ||
|
|
ea8a982f78 | ||
|
|
e4db0f9286 | ||
|
|
9bb6d1b04f | ||
|
|
6ad1c94060 | ||
|
|
ec281c2068 | ||
|
|
56bb9affea | ||
|
|
c8672ee464 | ||
|
|
3613c2cd68 | ||
|
|
e5dcd211de | ||
|
|
f0e64228fc | ||
|
|
cd72557078 | ||
|
|
e9d0c0131d | ||
|
|
417b7b13e7 | ||
|
|
a1347d6db7 | ||
|
|
c7ecbc99a7 | ||
|
|
e7d5e52c00 | ||
|
|
bb6cc695b6 | ||
|
|
4613c0ccd5 | ||
|
|
566cae9682 | ||
|
|
1375d33091 | ||
|
|
e51aba4e79 | ||
|
|
3e964e3277 | ||
|
|
91a61283e6 | ||
|
|
752fb198f1 | ||
|
|
8fc87997f6 | ||
|
|
cf3fad4f18 | ||
|
|
1bb26481ba | ||
|
|
63325ef0da | ||
|
|
0b1006ff57 | ||
|
|
c52afdb059 | ||
|
|
b13a8014d7 | ||
|
|
869e8a8b88 | ||
|
|
59dedc9d9a | ||
|
|
28b6fbf7b4 | ||
|
|
243a3ba349 | ||
|
|
4fea944207 | ||
|
|
303a4ee737 | ||
|
|
808f28125e | ||
|
|
d4fa66050b | ||
|
|
129d972a37 | ||
|
|
0ee347ab9f | ||
|
|
e7a0c7bee5 | ||
|
|
735579fd1d | ||
|
|
c3168429d8 | ||
|
|
672b301a14 | ||
|
|
7aafcbf80d | ||
|
|
11466c32ea | ||
|
|
3775f53ff8 | ||
|
|
2e7cdcbeec | ||
|
|
1bb2a849b4 | ||
|
|
78e876f9e4 | ||
|
|
d1496a6b95 | ||
|
|
66d4841359 | ||
|
|
8521de277a | ||
|
|
189125aca3 | ||
|
|
eacd219938 | ||
|
|
c48d3b7cb7 | ||
|
|
161fad4df3 | ||
|
|
ae02338f5e | ||
|
|
2cfeeed597 | ||
|
|
2b7804f296 | ||
|
|
eb18d27bc5 | ||
|
|
e85ad0c402 | ||
|
|
7542c44d57 | ||
|
|
fdb157eff7 | ||
|
|
6f0dcbba03 | ||
|
|
061dd35449 | ||
|
|
66a27691e4 | ||
|
|
88ccbdcf5b | ||
|
|
a8d581cbc2 | ||
|
|
f4736861f9 | ||
|
|
1e1fe22154 | ||
|
|
c8931128e7 | ||
|
|
c9b1adbbb6 | ||
|
|
0cc580d46c | ||
|
|
697db29456 | ||
|
|
87eb65ce0b | ||
|
|
1cfaa5ee3c | ||
|
|
888fd674a2 | ||
|
|
5334fc8673 | ||
|
|
a7f486d6b1 | ||
|
|
f1aabb35fd | ||
|
|
8bf087fa87 | ||
|
|
b5440e99a0 | ||
|
|
694a3e8525 | ||
|
|
30a43423f7 | ||
|
|
444e3a967b | ||
|
|
d9689533ed | ||
|
|
a2690e2a6f | ||
|
|
dc6748c6a9 | ||
|
|
d7d6c9ba5e | ||
|
|
a00e42d97f | ||
|
|
142a7e7e44 | ||
|
|
11cf8214ef | ||
|
|
98391cf3de | ||
|
|
52ae8b0261 | ||
|
|
46b2be0532 | ||
|
|
c538a5dce0 | ||
|
|
d28d6f7ca1 | ||
|
|
f0e2459f86 | ||
|
|
d87e8a5f9d | ||
|
|
39ecb4c9ed | ||
|
|
afcd3b7dd2 | ||
|
|
21c34d8000 | ||
|
|
089c55c989 | ||
|
|
d8090331a0 | ||
|
|
de0163f377 | ||
|
|
41c88bd529 | ||
|
|
b740814786 | ||
|
|
52e30a7ca8 | ||
|
|
4faa460afc | ||
|
|
3a461f5e12 | ||
|
|
7520da3455 | ||
|
|
5f790264f4 | ||
|
|
bb38a505a8 | ||
|
|
215925740e | ||
|
|
2cad880bd2 | ||
|
|
8cf754d5e1 | ||
|
|
86f9325542 | ||
|
|
b173684e66 | ||
|
|
01d242077e | ||
|
|
8d1fc3e08d | ||
|
|
1b000264a0 | ||
|
|
357397a2dd | ||
|
|
8d092053bf | ||
|
|
a302b554c8 | ||
|
|
04351d8778 | ||
|
|
4128af5a8d | ||
|
|
4ae731339f | ||
|
|
419b6a223c | ||
|
|
17f31a39a1 | ||
|
|
b34a301936 | ||
|
|
99dcce4d2e | ||
|
|
cdd0796814 | ||
|
|
bf0efbfe51 | ||
|
|
a3ce3c9939 | ||
|
|
d187637bc2 | ||
|
|
501084dc89 | ||
|
|
eaa2cccf55 | ||
|
|
dbac248ff2 | ||
|
|
bf39c2b2b0 | ||
|
|
69d446aaa7 | ||
|
|
2ddf10ef33 | ||
|
|
7702a577a9 | ||
|
|
6834a8cb39 | ||
|
|
485f11a38e | ||
|
|
46ace17a65 | ||
|
|
8f3382191e | ||
|
|
c4bd2995c3 | ||
|
|
61c6d7f005 | ||
|
|
59ecf6936b | ||
|
|
5ede270690 | ||
|
|
fc41410812 | ||
|
|
ec11bf0468 | ||
|
|
ee0b6bfea9 | ||
|
|
7459424216 | ||
|
|
3995b326e4 | ||
|
|
c42a5241fb | ||
|
|
2494770bab | ||
|
|
32a72c8335 | ||
|
|
9ee235d24e | ||
|
|
14236e7934 | ||
|
|
7dd6c19e0d | ||
|
|
cfc1f38378 | ||
|
|
4751517e9a | ||
|
|
9e7224a561 | ||
|
|
f41070c777 | ||
|
|
8965bc2d15 | ||
|
|
2c499601ca | ||
|
|
c80ac4ab9d | ||
|
|
473b481183 | ||
|
|
aeda808d67 | ||
|
|
9b5552663f | ||
|
|
e7a20c18b0 | ||
|
|
899ee5d459 | ||
|
|
778e6980a1 | ||
|
|
9710013a9d | ||
|
|
2e41be3b83 | ||
|
|
334788f4ba | ||
|
|
5f9fcdf3dd | ||
|
|
ec04eadd3b | ||
|
|
68b598f047 | ||
|
|
41d224d7ab | ||
|
|
295d80ec28 | ||
|
|
7aeec0199d | ||
|
|
f6eb4929ca | ||
|
|
01f3514a44 | ||
|
|
443d3f7585 | ||
|
|
22f07394ef | ||
|
|
f760d1b159 | ||
|
|
a950d76e4d | ||
|
|
968cbc39eb | ||
|
|
3fe2e37e64 | ||
|
|
8623e9f3af | ||
|
|
91344b296d | ||
|
|
174756e486 | ||
|
|
47dd5cfdf6 | ||
|
|
170dc6f9b3 | ||
|
|
75e065bcb9 | ||
|
|
07b3d91e4f | ||
|
|
aecd332d5b | ||
|
|
22f4742a73 | ||
|
|
ba645054ea | ||
|
|
ac437b99de | ||
|
|
e537e41254 | ||
|
|
64308791fd | ||
|
|
23a29c62cd | ||
|
|
6d31ba2b04 | ||
|
|
8920bddfd5 | ||
|
|
7b2f32e6a5 | ||
|
|
a464c5c785 | ||
|
|
dc9a0cb31b | ||
|
|
e03b7aa385 | ||
|
|
ab1d89f5b4 | ||
|
|
4e6a7bcd30 | ||
|
|
f3c408abb6 | ||
|
|
3cd514e722 | ||
|
|
471b724ae8 | ||
|
|
e58981577c | ||
|
|
3768013c17 | ||
|
|
d72aa4b047 | ||
|
|
4dcf91e691 | ||
|
|
1cd787fb31 | ||
|
|
6434c7afc4 | ||
|
|
44e61bdc49 | ||
|
|
23c4730ef0 | ||
|
|
744812f01f | ||
|
|
008732aba1 | ||
|
|
7446acebff | ||
|
|
ecc9cbab33 | ||
|
|
3898d17b83 | ||
|
|
365639e9dc | ||
|
|
b5ff812e84 | ||
|
|
8800053905 | ||
|
|
0a77443c5c | ||
|
|
49d9f975f8 | ||
|
|
363812fa4b | ||
|
|
e8ab1adb50 | ||
|
|
0bfa2ac16b | ||
|
|
6b6ce1a3a9 | ||
|
|
0589d4dd61 | ||
|
|
581755e520 | ||
|
|
2d30564a69 | ||
|
|
1474e84640 | ||
|
|
33572a6af9 | ||
|
|
4e2ea13c2c | ||
|
|
216967e976 | ||
|
|
2d9febf8a4 | ||
|
|
2cdca8250c | ||
|
|
81a41ffd6f | ||
|
|
bd02944bf3 | ||
|
|
c34c1bbbf1 | ||
|
|
44fc8a3931 | ||
|
|
44d072647e | ||
|
|
3cb8821dca | ||
|
|
0a649768fa | ||
|
|
c624d51586 | ||
|
|
12514b8c55 | ||
|
|
4d3953ec13 | ||
|
|
1a45c2dba3 | ||
|
|
4b886c6097 | ||
|
|
1a4f96e5dc | ||
|
|
4875fe6f0b | ||
|
|
6c4bf09958 | ||
|
|
f223a39d64 | ||
|
|
80e09355f0 | ||
|
|
ebdbe651d0 | ||
|
|
3c047d3e21 | ||
|
|
911ed7a2f4 | ||
|
|
a05d64250f | ||
|
|
1e5b4fe8ea | ||
|
|
cabe1ff53f | ||
|
|
5deb88e946 | ||
|
|
e3e3894a9d | ||
|
|
20da8d004b | ||
|
|
af653a0f93 | ||
|
|
ea23daed7d | ||
|
|
bd06fd6b33 | ||
|
|
66958e5dcc | ||
|
|
b9b1fb9f03 | ||
|
|
907d472749 | ||
|
|
e16baa527a | ||
|
|
a1def14db3 | ||
|
|
91f1557362 | ||
|
|
b2364bd076 | ||
|
|
b637c00ac5 | ||
|
|
d17498b79e | ||
|
|
2242a7d646 | ||
|
|
72da4c88d8 | ||
|
|
23a4e24d38 | ||
|
|
4b7dbb5714 | ||
|
|
93ea309a79 | ||
|
|
5f3620da83 | ||
|
|
eca1b8760c | ||
|
|
446360437d | ||
|
|
9e41cb162d | ||
|
|
91ce24b7a6 | ||
|
|
bf7e7e33b2 | ||
|
|
304dd0101b | ||
|
|
110ee28447 | ||
|
|
cdba29d6fa | ||
|
|
2a750f666a | ||
|
|
a6b561acb7 | ||
|
|
2703f7111a | ||
|
|
54ff02bcdb | ||
|
|
488cdbcd93 | ||
|
|
bb51988ddb | ||
|
|
3ef2bcee3b | ||
|
|
05020b08b8 | ||
|
|
030ad0f20d | ||
|
|
4e10f80eb1 | ||
|
|
1a57c10741 | ||
|
|
8ccc12433e | ||
|
|
7127f88318 | ||
|
|
9f98f0bd5f | ||
|
|
29d5913e8b | ||
|
|
587b44f7b9 | ||
|
|
8eb2f48d85 | ||
|
|
bd122b0d74 | ||
|
|
f24123c686 | ||
|
|
6f6d6282bc | ||
|
|
c876e87990 | ||
|
|
bd515c125e | ||
|
|
342d9beaf6 | ||
|
|
ee1a3e0515 | ||
|
|
265c4c4039 | ||
|
|
58180272ec | ||
|
|
ce0cb78aa3 | ||
|
|
7cdd2087dd | ||
|
|
8711b3f9c3 | ||
|
|
769c320ce6 | ||
|
|
6950affc84 | ||
|
|
b360ba66c0 | ||
|
|
5a54ea12cf | ||
|
|
66ae730276 | ||
|
|
2d72aa1330 | ||
|
|
21a7131728 | ||
|
|
72191c39f0 | ||
|
|
1a3f1bdeb9 | ||
|
|
da8b12a7fa | ||
|
|
f16240388d | ||
|
|
a52de61b57 | ||
|
|
41d17494d4 | ||
|
|
8f8597def7 | ||
|
|
9810faf877 | ||
|
|
ef958d1566 | ||
|
|
6ea878e39a | ||
|
|
51ac5db960 | ||
|
|
71cb08b00f | ||
|
|
6d671338b6 | ||
|
|
1462d6b7e2 | ||
|
|
27d5861456 | ||
|
|
c405a5729a | ||
|
|
c2fd5163b0 | ||
|
|
c3b4ed6e1f | ||
|
|
de4ad24cd6 | ||
|
|
08d30bbc23 | ||
|
|
93e5ee7301 | ||
|
|
cc57e67eb5 | ||
|
|
029082bf7f | ||
|
|
2140188dbf | ||
|
|
078495fcf7 | ||
|
|
20b31f4718 | ||
|
|
9872a4bec4 | ||
|
|
2a4b3e709c | ||
|
|
9d3b90b098 | ||
|
|
30c5f276b6 | ||
|
|
8093abad96 | ||
|
|
e9c6eb3be2 | ||
|
|
a7aff64fec | ||
|
|
7df322e81c | ||
|
|
c0644faecf | ||
|
|
9b08e5cdfc | ||
|
|
68191d84cd | ||
|
|
db1484dffa | ||
|
|
2f16239831 | ||
|
|
7a7d40ff24 | ||
|
|
19eec1ec1a | ||
|
|
fc10c99f0f | ||
|
|
9fac135d96 | ||
|
|
27e212163c | ||
|
|
9e188cb48a | ||
|
|
47823f9417 | ||
|
|
dc40bc189b | ||
|
|
781b68f255 | ||
|
|
d1e781872b | ||
|
|
d9e9c4be8b | ||
|
|
594c661394 | ||
|
|
1a05a88c31 | ||
|
|
b636493396 | ||
|
|
ca48120568 | ||
|
|
cdc9b7eb15 | ||
|
|
ca06249e68 | ||
|
|
d1c7567e4e | ||
|
|
1792e626f2 | ||
|
|
3a63030787 | ||
|
|
aa793fab6d | ||
|
|
81258ff62f | ||
|
|
28d7f6618b | ||
|
|
3850a1747c | ||
|
|
9f4421153e | ||
|
|
de22cf0280 | ||
|
|
856f3c94d9 | ||
|
|
8f077979f1 | ||
|
|
1e7bae293c | ||
|
|
deea18b5d3 | ||
|
|
a12d9f2f36 | ||
|
|
2f5b5ec713 | ||
|
|
0799b7e394 | ||
|
|
6c6c3de61a | ||
|
|
8ebb6cb543 | ||
|
|
13b2796d91 | ||
|
|
89a93b0f96 | ||
|
|
7df062d97a | ||
|
|
7f36dd2b9d | ||
|
|
7e0765adb0 | ||
|
|
42461a74ea | ||
|
|
ea6795694b | ||
|
|
7c774bd988 | ||
|
|
0b68948a0f | ||
|
|
6aaa9bea9c | ||
|
|
a37e7192aa | ||
|
|
515d9cbd65 | ||
|
|
7b57c92f12 | ||
|
|
8aa4fdcec5 | ||
|
|
320ac3f1d4 | ||
|
|
30eb743b64 | ||
|
|
7ce6ce3958 | ||
|
|
9f66712dc2 | ||
|
|
bab1395f93 | ||
|
|
93c6af4d5b | ||
|
|
38ae668218 | ||
|
|
09fd1e0fee | ||
|
|
0b471b89b3 | ||
|
|
24b7c232f2 | ||
|
|
6e1e6a8957 | ||
|
|
bf28940608 | ||
|
|
6743368f1f | ||
|
|
1564da544e | ||
|
|
4ab35e0c89 | ||
|
|
f2f6f80a1d | ||
|
|
b0dc54117b | ||
|
|
f87b4ae837 | ||
|
|
36bc5d1f8f | ||
|
|
16f99901ee | ||
|
|
34a4db4d42 | ||
|
|
56161aa4a2 | ||
|
|
ef058908ae | ||
|
|
1207d6c28f | ||
|
|
0f75f2f3fb | ||
|
|
ca4f58d509 | ||
|
|
4fa737f30d | ||
|
|
096bef4101 | ||
|
|
2ab186a688 | ||
|
|
028b4c0bb7 | ||
|
|
b789d45cb5 | ||
|
|
47fc41eb93 | ||
|
|
c96399bbad | ||
|
|
1238910a11 | ||
|
|
6603c46a9c | ||
|
|
91abf77a34 | ||
|
|
1d27822e5d | ||
|
|
4f92eda181 | ||
|
|
1915e08048 | ||
|
|
a2ca625012 | ||
|
|
5909098257 | ||
|
|
77a662f47a | ||
|
|
d2a58213e5 | ||
|
|
e7e21ca2da | ||
|
|
c169a9f651 | ||
|
|
ca959ec1fd | ||
|
|
218146a7f3 | ||
|
|
b672fa333f | ||
|
|
5501641cb8 | ||
|
|
9c842ff511 | ||
|
|
a2af03606c | ||
|
|
e19eb9d908 | ||
|
|
c5f830fe39 | ||
|
|
bcb505b78b | ||
|
|
8bbc45c6c8 | ||
|
|
c63da670ec | ||
|
|
307db42dc4 | ||
|
|
97b0eb64ad | ||
|
|
691d267186 | ||
|
|
e8dd287528 | ||
|
|
5f9c0f0939 | ||
|
|
1a473f4e44 | ||
|
|
a86d8abffd | ||
|
|
34960d04b9 | ||
|
|
f9e4d24b62 | ||
|
|
b2b724fb89 | ||
|
|
cea940f96d | ||
|
|
d3f7d150b4 | ||
|
|
e3999de287 | ||
|
|
a5340d7419 | ||
|
|
0eb5374c6d | ||
|
|
a85ccf39cf | ||
|
|
cfbed5e612 | ||
|
|
ae81baf2d4 | ||
|
|
4b7e8921b1 | ||
|
|
5f3017d08b | ||
|
|
14e03b390c | ||
|
|
a034b05c00 | ||
|
|
74e8c66e09 | ||
|
|
6ca33cd75a | ||
|
|
058720536e | ||
|
|
283aca847c | ||
|
|
3077ee4136 | ||
|
|
57d6436b34 | ||
|
|
1d70055dd3 | ||
|
|
80eddeed61 | ||
|
|
2496d4d0a1 | ||
|
|
4ad992da42 | ||
|
|
b5d90de7bd | ||
|
|
87d987b158 | ||
|
|
4175e0b62c | ||
|
|
ff45f243c9 | ||
|
|
77bc2e38d0 | ||
|
|
c1a5d818e0 | ||
|
|
9ae297b8a9 | ||
|
|
63c9eb162d | ||
|
|
8d64921213 | ||
|
|
4b53a94a30 | ||
|
|
083e4ec42e | ||
|
|
8e1055bc49 | ||
|
|
3a8579faca | ||
|
|
85daaf3127 | ||
|
|
54cc67da93 | ||
|
|
05b2648e0b | ||
|
|
2f6e46ee15 | ||
|
|
906a2b3799 | ||
|
|
bd12608ff7 | ||
|
|
26d9626f2a | ||
|
|
d61395717c | ||
|
|
d21c6e1b3b | ||
|
|
d3515de265 | ||
|
|
a8839ccb64 | ||
|
|
f53785ef54 | ||
|
|
08bc7b163b | ||
|
|
27a1e7eb83 | ||
|
|
9313c98055 | ||
|
|
54670ffdbf | ||
|
|
ce05997174 | ||
|
|
8a8bc33bb0 | ||
|
|
72e17ce70e | ||
|
|
3c2eb738ff | ||
|
|
15f9c94c64 | ||
|
|
7e92c0dabd | ||
|
|
a4f5ac1504 | ||
|
|
c08b829d1a | ||
|
|
e68865ed84 | ||
|
|
35b0e2fbe9 | ||
|
|
8ebb881028 | ||
|
|
ea6d2b0135 | ||
|
|
95ff8e19d2 | ||
|
|
b88931cc10 | ||
|
|
dac4679cea | ||
|
|
a222a826e7 | ||
|
|
90fad55424 | ||
|
|
77a9c8ba8d | ||
|
|
a5e8b26cea | ||
|
|
889b98fbe3 | ||
|
|
d589559c7d | ||
|
|
2bf339fb03 | ||
|
|
e03e57e5ac | ||
|
|
56a00258d4 | ||
|
|
788b785b3c | ||
|
|
89cc8e2024 | ||
|
|
0d658e0959 | ||
|
|
f9cf7223e4 | ||
|
|
8e4c783c97 | ||
|
|
af1e413513 | ||
|
|
b9316cdd2b | ||
|
|
b4e6d69695 | ||
|
|
bc2873da84 | ||
|
|
3a0aa3c599 | ||
|
|
2466b00738 | ||
|
|
8ed14499c4 | ||
|
|
5b93bfa24d | ||
|
|
20f1219c27 | ||
|
|
ccbad7198c | ||
|
|
e10c578d96 | ||
|
|
72c3d8a3c9 | ||
|
|
f333cb3865 | ||
|
|
3428b1793b | ||
|
|
3337d007af | ||
|
|
87cc013c2a | ||
|
|
369de2d8be | ||
|
|
cfeda558f6 | ||
|
|
3f74854f49 | ||
|
|
6b7abfc3d9 | ||
|
|
d232979d7b | ||
|
|
f1e7a4b184 | ||
|
|
be86a2e96c | ||
|
|
a5f7160b52 | ||
|
|
6191d62ade | ||
|
|
f2ccbf3fae | ||
|
|
d8894e1ab4 | ||
|
|
9ec077884b | ||
|
|
b20be99732 | ||
|
|
82f427bc4f | ||
|
|
b6de652dd0 | ||
|
|
10c5783170 | ||
|
|
86111b3939 | ||
|
|
d01df8c1a3 | ||
|
|
390adc92af | ||
|
|
20f0e8efa1 | ||
|
|
66728431b8 | ||
|
|
caebc01a9f | ||
|
|
8e720f1147 | ||
|
|
86302937a9 | ||
|
|
15118f4154 | ||
|
|
d3ade90129 | ||
|
|
54176e2723 | ||
|
|
282c1e7d41 | ||
|
|
39320a9bac | ||
|
|
9d6c83030b | ||
|
|
e7d5fbff63 | ||
|
|
cccc4f2f67 | ||
|
|
648200e8d7 | ||
|
|
1147d3ab53 | ||
|
|
894c415bfd | ||
|
|
56e16b2d3f | ||
|
|
507510f60b | ||
|
|
724a12c71f | ||
|
|
b57827023b | ||
|
|
863e729e60 | ||
|
|
e6c1279327 | ||
|
|
bcdc621238 | ||
|
|
96081a5d7a | ||
|
|
3b09608328 | ||
|
|
5db743cef0 | ||
|
|
16063af045 | ||
|
|
5910d8a964 | ||
|
|
12217afe65 | ||
|
|
ba56687982 | ||
|
|
63b0c8271b | ||
|
|
1f53ce1d74 | ||
|
|
c9181d16f0 | ||
|
|
0d1decf746 | ||
|
|
2ccfb9beee | ||
|
|
1d781323f6 | ||
|
|
a4d024b7bf | ||
|
|
03f0acba0c | ||
|
|
e96c3df0db | ||
|
|
62c1b88a24 | ||
|
|
1e729f8fa0 | ||
|
|
cf0f096e77 | ||
|
|
d059d7bb4a | ||
|
|
d86855a2f7 | ||
|
|
12e8966d47 | ||
|
|
0569f2b520 | ||
|
|
3d75cbc58a | ||
|
|
dcf57c0b51 | ||
|
|
a44612d970 | ||
|
|
c0b69a2291 | ||
|
|
45eba0b047 | ||
|
|
34cd8b664f | ||
|
|
a66943d9a5 | ||
|
|
aa3a2fdce2 | ||
|
|
a555b78c78 | ||
|
|
bfbf7c94a6 | ||
|
|
dc49e0f21d | ||
|
|
69a13a7b23 | ||
|
|
77e818e6f1 | ||
|
|
6785968df9 | ||
|
|
00dfd3b55b | ||
|
|
e316a4784e | ||
|
|
a0fef6bc56 | ||
|
|
a84715808e | ||
|
|
fe319c86ab | ||
|
|
554efab34b | ||
|
|
631b32d43d | ||
|
|
2a4076c5ba | ||
|
|
d19a335c6a | ||
|
|
46d5be10c1 | ||
|
|
84e1bd5fbe | ||
|
|
f55d851bff | ||
|
|
40c13a7fa5 | ||
|
|
573d884acf | ||
|
|
7b29f11e1d | ||
|
|
a37c1e173b | ||
|
|
80c45b4dd8 | ||
|
|
72a48d956d | ||
|
|
e272ddaf96 | ||
|
|
b80c3bf30f | ||
|
|
1b5cc98249 | ||
|
|
c4a826b073 | ||
|
|
559579fbd9 | ||
|
|
90d051f8e4 | ||
|
|
4b1e670b4e | ||
|
|
85e09acfc3 | ||
|
|
1a89685d53 | ||
|
|
698ee422ff | ||
|
|
2b19c3353a | ||
|
|
6e99ec8fc5 | ||
|
|
281eb6d2ff | ||
|
|
f4daedd84f | ||
|
|
4a9e399cc9 | ||
|
|
683ae36b8b | ||
|
|
74b0d2f690 | ||
|
|
dfd8656339 | ||
|
|
7ae66082c4 | ||
|
|
f2ba642207 | ||
|
|
dd23dd6bf3 | ||
|
|
8d324c0669 | ||
|
|
e6363439b6 | ||
|
|
bf66da8313 | ||
|
|
4a4fcca61f | ||
|
|
85a99dd15b | ||
|
|
e21c3da80b | ||
|
|
7379fbad1b | ||
|
|
fc721646c1 | ||
|
|
05823b9119 | ||
|
|
ad770a370a | ||
|
|
bdb97c56df | ||
|
|
ff3592134c | ||
|
|
fdb8f710ca | ||
|
|
425f76de55 | ||
|
|
ec312abd7a | ||
|
|
580ed4c843 | ||
|
|
801076e2ae | ||
|
|
c0c8e4b5fa | ||
|
|
843c31097b | ||
|
|
d85a2e3844 | ||
|
|
bb045e0cee | ||
|
|
ab016b4561 | ||
|
|
df2ab676cd | ||
|
|
deaed6324d | ||
|
|
7e59907485 | ||
|
|
bfaa63363d | ||
|
|
a99993f54c | ||
|
|
117e2a4ca6 | ||
|
|
aeb2716831 | ||
|
|
064041f4fb | ||
|
|
f9ba318f9e | ||
|
|
a3326c9e10 | ||
|
|
d0ab17ab67 | ||
|
|
dc2153d813 | ||
|
|
26fd2c5945 | ||
|
|
ce199d66a8 | ||
|
|
54258aca68 | ||
|
|
3cb4cd6f21 | ||
|
|
58cc4b5ccb | ||
|
|
e3c275a7cb | ||
|
|
36350fa292 | ||
|
|
82e356ad01 | ||
|
|
f23deebd25 | ||
|
|
6a103b5a76 | ||
|
|
110e1e42e7 | ||
|
|
fa08842aa4 | ||
|
|
66e679bd11 | ||
|
|
bc379bade8 | ||
|
|
db8d83c1c4 | ||
|
|
6a8f3b626b | ||
|
|
54f7cf78e9 | ||
|
|
2581584b6b | ||
|
|
72ac69b075 | ||
|
|
d1a3720f50 | ||
|
|
710d648af7 | ||
|
|
e2d463e7d8 | ||
|
|
91b1f6e9aa | ||
|
|
cfa9c4d1c4 | ||
|
|
4ddbf472c3 | ||
|
|
5298a8d26a | ||
|
|
53f1247939 | ||
|
|
ff16f95b57 | ||
|
|
0419ebc856 | ||
|
|
6fa8480722 | ||
|
|
1da513cecd | ||
|
|
309ec45a98 | ||
|
|
ddfd695376 | ||
|
|
260e87c983 | ||
|
|
460b0d8968 | ||
|
|
b61daa36a0 | ||
|
|
fcbb4ee45e | ||
|
|
536e9350b3 | ||
|
|
9efabe8638 | ||
|
|
4f9c8b3640 | ||
|
|
e9a03d79b6 | ||
|
|
e920676f92 | ||
|
|
63544eb8f4 | ||
|
|
6b5c2a8821 | ||
|
|
41ca96880f | ||
|
|
39bcdfe5d9 | ||
|
|
186082caf6 | ||
|
|
b53d6a3fe5 | ||
|
|
afcccabd22 | ||
|
|
1de3a25157 | ||
|
|
8038e568a3 | ||
|
|
f2e15a3dce | ||
|
|
0985f24f57 | ||
|
|
a7e7daf177 | ||
|
|
adc488b334 | ||
|
|
fead689299 | ||
|
|
1b4391cbd1 | ||
|
|
c0136ca0d0 | ||
|
|
45f9db3641 | ||
|
|
a281e92f34 | ||
|
|
c8458d10ba | ||
|
|
78d4d7ef99 | ||
|
|
1c576245ce | ||
|
|
3eede07064 | ||
|
|
0eb7ecc90e | ||
|
|
050df0577e | ||
|
|
8d395186fd | ||
|
|
2c23a8e154 | ||
|
|
c60d16ab1c | ||
|
|
6dcbf3c56d | ||
|
|
bde86ea0c0 | ||
|
|
dafcd563c2 | ||
|
|
15f303be12 | ||
|
|
2ffc9aa1bb | ||
|
|
dc8112e574 | ||
|
|
31d80cf0a5 | ||
|
|
c8290725bd | ||
|
|
8482a26c60 | ||
|
|
b5026fc4c7 | ||
|
|
acb1cd9576 | ||
|
|
42f38543fd | ||
|
|
7ecca9727e | ||
|
|
0e8416ccbd | ||
|
|
5bfa61ab70 | ||
|
|
bc8d5b2c39 | ||
|
|
bff7663b55 | ||
|
|
c34990bdae | ||
|
|
63bf418060 | ||
|
|
26c031c0ee | ||
|
|
c72d85ffd3 | ||
|
|
01ba03eb0e | ||
|
|
79fd89b3c4 | ||
|
|
0824921b2d | ||
|
|
a9a4aceaac | ||
|
|
d096208f58 | ||
|
|
9f753e4395 |
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@@ -13,7 +13,7 @@ updates:
|
|||||||
- juliushaertl
|
- juliushaertl
|
||||||
|
|
||||||
- package-ecosystem: npm
|
- package-ecosystem: npm
|
||||||
target-branch: stable25
|
target-branch: stable27
|
||||||
versioning-strategy: lockfile-only
|
versioning-strategy: lockfile-only
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
@@ -30,7 +30,7 @@ updates:
|
|||||||
- dependencies
|
- dependencies
|
||||||
|
|
||||||
- package-ecosystem: npm
|
- package-ecosystem: npm
|
||||||
target-branch: stable24
|
target-branch: stable26
|
||||||
versioning-strategy: lockfile-only
|
versioning-strategy: lockfile-only
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
|
|||||||
6
.github/workflows/appbuild.yml
vendored
6
.github/workflows/appbuild.yml
vendored
@@ -16,15 +16,15 @@ jobs:
|
|||||||
node-version: [16.x]
|
node-version: [16.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
- name: Set up npm7
|
- name: Set up npm7
|
||||||
run: npm i -g npm@7
|
run: npm i -g npm@7
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@2.25.1
|
uses: shivammathur/setup-php@2.27.1
|
||||||
with:
|
with:
|
||||||
php-version: '7.4'
|
php-version: '7.4'
|
||||||
tools: composer
|
tools: composer
|
||||||
|
|||||||
27
.github/workflows/appstore-build-publish.yml
vendored
27
.github/workflows/appstore-build-publish.yml
vendored
@@ -10,7 +10,7 @@ on:
|
|||||||
types: [published]
|
types: [published]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PHP_VERSION: 8.1
|
PHP_VERSION: 8.2
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_and_publish:
|
build_and_publish:
|
||||||
@@ -21,7 +21,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check actor permission
|
- name: Check actor permission
|
||||||
uses: skjnldsv/check-actor-permission@e591dbfe838300c007028e1219ca82cc26e8d7c5 # v2.1
|
uses: skjnldsv/check-actor-permission@69e92a3c4711150929bca9fcf34448c5bf5526e7 # v3.0
|
||||||
with:
|
with:
|
||||||
require: write
|
require: write
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ jobs:
|
|||||||
echo "APP_VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV
|
echo "APP_VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
with:
|
with:
|
||||||
path: ${{ env.APP_NAME }}
|
path: ${{ env.APP_NAME }}
|
||||||
|
|
||||||
@@ -44,19 +44,19 @@ jobs:
|
|||||||
expression: "//info//dependencies//nextcloud/@min-version"
|
expression: "//info//dependencies//nextcloud/@min-version"
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
- name: Read package.json node and npm engines version
|
||||||
uses: skjnldsv/read-package-engines-version-actions@0ce2ed60f6df073a62a77c0a4958dd0fc68e32e7 # v2.1
|
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
||||||
id: versions
|
id: versions
|
||||||
# Continue if no package.json
|
# Continue if no package.json
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
path: ${{ env.APP_NAME }}
|
path: ${{ env.APP_NAME }}
|
||||||
fallbackNode: "^16"
|
fallbackNode: '^20'
|
||||||
fallbackNpm: "^7"
|
fallbackNpm: '^10'
|
||||||
|
|
||||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||||
# Skip if no package.json
|
# Skip if no package.json
|
||||||
if: ${{ steps.versions.outputs.nodeVersion }}
|
if: ${{ steps.versions.outputs.nodeVersion }}
|
||||||
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3
|
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ jobs:
|
|||||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
||||||
|
|
||||||
- name: Set up php ${{ env.PHP_VERSION }}
|
- name: Set up php ${{ env.PHP_VERSION }}
|
||||||
uses: shivammathur/setup-php@2.25.1 # v2
|
uses: shivammathur/setup-php@6d7209f44a25a59e904b1ee9f3b0c33ab2cd888d # v2
|
||||||
with:
|
with:
|
||||||
php-version: ${{ env.PHP_VERSION }}
|
php-version: ${{ env.PHP_VERSION }}
|
||||||
coverage: none
|
coverage: none
|
||||||
@@ -75,7 +75,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check composer.json
|
- name: Check composer.json
|
||||||
id: check_composer
|
id: check_composer
|
||||||
uses: andstor/file-existence-action@20b4d2e596410855db8f9ca21e96fbe18e12930b # v2
|
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v2
|
||||||
with:
|
with:
|
||||||
files: "${{ env.APP_NAME }}/composer.json"
|
files: "${{ env.APP_NAME }}/composer.json"
|
||||||
|
|
||||||
@@ -88,6 +88,8 @@ jobs:
|
|||||||
- name: Build ${{ env.APP_NAME }}
|
- name: Build ${{ env.APP_NAME }}
|
||||||
# Skip if no package.json
|
# Skip if no package.json
|
||||||
if: ${{ steps.versions.outputs.nodeVersion }}
|
if: ${{ steps.versions.outputs.nodeVersion }}
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
run: |
|
run: |
|
||||||
cd ${{ env.APP_NAME }}
|
cd ${{ env.APP_NAME }}
|
||||||
npm ci
|
npm ci
|
||||||
@@ -95,7 +97,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check Krankerl config
|
- name: Check Krankerl config
|
||||||
id: krankerl
|
id: krankerl
|
||||||
uses: andstor/file-existence-action@20b4d2e596410855db8f9ca21e96fbe18e12930b # v2
|
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v2
|
||||||
with:
|
with:
|
||||||
files: ${{ env.APP_NAME }}/krankerl.toml
|
files: ${{ env.APP_NAME }}/krankerl.toml
|
||||||
|
|
||||||
@@ -126,9 +128,10 @@ jobs:
|
|||||||
unzip latest-$NCVERSION.zip
|
unzip latest-$NCVERSION.zip
|
||||||
|
|
||||||
- name: Checkout server master fallback
|
- name: Checkout server master fallback
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
if: ${{ steps.server-checkout.outcome != 'success' }}
|
if: ${{ steps.server-checkout.outcome != 'success' }}
|
||||||
with:
|
with:
|
||||||
|
submodules: true
|
||||||
repository: nextcloud/server
|
repository: nextcloud/server
|
||||||
path: nextcloud
|
path: nextcloud
|
||||||
|
|
||||||
@@ -148,7 +151,7 @@ jobs:
|
|||||||
tar -zcvf ${{ env.APP_NAME }}.tar.gz ${{ env.APP_NAME }}
|
tar -zcvf ${{ env.APP_NAME }}.tar.gz ${{ env.APP_NAME }}
|
||||||
|
|
||||||
- name: Attach tarball to github release
|
- name: Attach tarball to github release
|
||||||
uses: svenstaro/upload-release-action@7319e4733ec7a184d739a6f412c40ffc339b69c7 # v2
|
uses: svenstaro/upload-release-action@1beeb572c19a9242f4361f4cee78f8e0d9aec5df # v2
|
||||||
id: attach_to_release
|
id: attach_to_release
|
||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
8
.github/workflows/command-rebase.yml
vendored
8
.github/workflows/command-rebase.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Add reaction on start
|
- name: Add reaction on start
|
||||||
uses: peter-evans/create-or-update-comment@ca08ebd5dc95aa0cd97021e9708fcd6b87138c9b # v3.0.1
|
uses: peter-evans/create-or-update-comment@23ff15729ef2fc348714a3bb66d2f655ca9066f2 # v3.1.0
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||||
repository: ${{ github.event.repository.full_name }}
|
repository: ${{ github.event.repository.full_name }}
|
||||||
@@ -31,18 +31,18 @@ jobs:
|
|||||||
reaction-type: "+1"
|
reaction-type: "+1"
|
||||||
|
|
||||||
- name: Checkout the latest code
|
- name: Checkout the latest code
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
uses: actions/checkout@v4 # v3.5.2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||||
|
|
||||||
- name: Automatic Rebase
|
- name: Automatic Rebase
|
||||||
uses: cirrus-actions/rebase@6e572f08c244e2f04f9beb85a943eb618218714d # 1.7
|
uses: cirrus-actions/rebase@b87d48154a87a85666003575337e27b8cd65f691 # 1.8
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }}
|
GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }}
|
||||||
|
|
||||||
- name: Add reaction on failure
|
- name: Add reaction on failure
|
||||||
uses: peter-evans/create-or-update-comment@ca08ebd5dc95aa0cd97021e9708fcd6b87138c9b # v3.0.1
|
uses: peter-evans/create-or-update-comment@23ff15729ef2fc348714a3bb66d2f655ca9066f2 # v3.1.0
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||||
|
|||||||
20
.github/workflows/cypress.yml
vendored
20
.github/workflows/cypress.yml
vendored
@@ -19,19 +19,17 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [14.x]
|
node-version: [20.x]
|
||||||
# containers: [1, 2, 3]
|
# containers: [1, 2, 3]
|
||||||
php-versions: [ '8.0' ]
|
php-versions: [ '8.0' ]
|
||||||
databases: [ 'sqlite' ]
|
databases: [ 'sqlite' ]
|
||||||
server-versions: [ 'stable27' ]
|
server-versions: [ 'stable28' ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
- name: Set up npm7
|
|
||||||
run: npm i -g npm@7
|
|
||||||
|
|
||||||
- name: Register text Git reference
|
- name: Register text Git reference
|
||||||
run: |
|
run: |
|
||||||
@@ -39,7 +37,7 @@ jobs:
|
|||||||
echo "text_app_ref=$text_app_ref" >> $GITHUB_ENV
|
echo "text_app_ref=$text_app_ref" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Checkout server
|
- name: Checkout server
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: nextcloud/server
|
repository: nextcloud/server
|
||||||
ref: ${{ matrix.server-versions }}
|
ref: ${{ matrix.server-versions }}
|
||||||
@@ -52,19 +50,19 @@ jobs:
|
|||||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||||
|
|
||||||
- name: Checkout ${{ env.APP_NAME }}
|
- name: Checkout ${{ env.APP_NAME }}
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
path: apps/${{ env.APP_NAME }}
|
path: apps/${{ env.APP_NAME }}
|
||||||
|
|
||||||
- name: Checkout text
|
- name: Checkout text
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: nextcloud/text
|
repository: nextcloud/text
|
||||||
ref: ${{ env.text_app_ref }}
|
ref: ${{ env.text_app_ref }}
|
||||||
path: apps/text
|
path: apps/text
|
||||||
|
|
||||||
- name: Set up php ${{ matrix.php-versions }}
|
- name: Set up php ${{ matrix.php-versions }}
|
||||||
uses: shivammathur/setup-php@2.25.1
|
uses: shivammathur/setup-php@2.27.1
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php-versions }}
|
php-version: ${{ matrix.php-versions }}
|
||||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, zip, gd, apcu
|
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, zip, gd, apcu
|
||||||
@@ -96,9 +94,9 @@ jobs:
|
|||||||
curl -v http://localhost:8081/index.php/login
|
curl -v http://localhost:8081/index.php/login
|
||||||
|
|
||||||
- name: Cypress run
|
- name: Cypress run
|
||||||
uses: cypress-io/github-action@v5
|
uses: cypress-io/github-action@v6
|
||||||
with:
|
with:
|
||||||
record: true
|
record: false
|
||||||
parallel: false
|
parallel: false
|
||||||
wait-on: '${{ env.CYPRESS_baseUrl }}'
|
wait-on: '${{ env.CYPRESS_baseUrl }}'
|
||||||
working-directory: 'apps/${{ env.APP_NAME }}'
|
working-directory: 'apps/${{ env.APP_NAME }}'
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ concurrency:
|
|||||||
jobs:
|
jobs:
|
||||||
auto-approve-merge:
|
auto-approve-merge:
|
||||||
if: github.actor == 'dependabot[bot]'
|
if: github.actor == 'dependabot[bot]'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-low
|
||||||
permissions:
|
permissions:
|
||||||
# for hmarr/auto-approve-action to approve PRs
|
# for hmarr/auto-approve-action to approve PRs
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|||||||
34
.github/workflows/fixup.yml
vendored
34
.github/workflows/fixup.yml
vendored
@@ -3,31 +3,31 @@
|
|||||||
# https://github.com/nextcloud/.github
|
# https://github.com/nextcloud/.github
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||||
|
|
||||||
name: Pull request checks
|
name: Block fixup and squash commits
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [opened, ready_for_review, reopened, synchronize]
|
types: [opened, ready_for_review, reopened, synchronize]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: fixup-${{ github.head_ref || github.run_id }}
|
group: fixup-${{ github.head_ref || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
commit-message-check:
|
commit-message-check:
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
name: Block fixup and squash commits
|
name: Block fixup and squash commits
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-low
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Run check
|
- name: Run check
|
||||||
uses: xt0rted/block-autosquash-commits-action@79880c36b4811fe549cfffe20233df88876024e7 # v2
|
uses: skjnldsv/block-fixup-merge-action@42d26e1b536ce61e5cf467d65fb76caf4aa85acf # v1
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
10
.github/workflows/integration.yml
vendored
10
.github/workflows/integration.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
php-versions: ['8.1']
|
php-versions: ['8.1']
|
||||||
databases: ['sqlite', 'mysql', 'pgsql']
|
databases: ['sqlite', 'mysql', 'pgsql']
|
||||||
server-versions: ['stable27']
|
server-versions: ['stable28']
|
||||||
|
|
||||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout server
|
- name: Checkout server
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: nextcloud/server
|
repository: nextcloud/server
|
||||||
ref: ${{ matrix.server-versions }}
|
ref: ${{ matrix.server-versions }}
|
||||||
@@ -66,7 +66,7 @@ jobs:
|
|||||||
cd build/integration && composer require --dev phpunit/phpunit:~9
|
cd build/integration && composer require --dev phpunit/phpunit:~9
|
||||||
|
|
||||||
- name: Checkout app
|
- name: Checkout app
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
path: apps/${{ env.APP_NAME }}
|
path: apps/${{ env.APP_NAME }}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ jobs:
|
|||||||
path: apps/activity
|
path: apps/activity
|
||||||
|
|
||||||
- name: Set up php ${{ matrix.php-versions }}
|
- name: Set up php ${{ matrix.php-versions }}
|
||||||
uses: shivammathur/setup-php@2.25.1
|
uses: shivammathur/setup-php@2.27.1
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php-versions }}
|
php-version: ${{ matrix.php-versions }}
|
||||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql, apcu
|
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql, apcu
|
||||||
@@ -114,7 +114,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Query count
|
- name: Query count
|
||||||
if: ${{ matrix.databases == 'mysql' }}
|
if: ${{ matrix.databases == 'mysql' }}
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||||
script: |
|
script: |
|
||||||
|
|||||||
75
.github/workflows/lint-eslint.yml
vendored
75
.github/workflows/lint-eslint.yml
vendored
@@ -6,22 +6,9 @@
|
|||||||
# Use lint-eslint together with lint-eslint-when-unrelated to make eslint a required check for GitHub actions
|
# Use lint-eslint together with lint-eslint-when-unrelated to make eslint a required check for GitHub actions
|
||||||
# https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
|
# https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
|
||||||
|
|
||||||
name: Lint
|
name: Lint eslint
|
||||||
|
|
||||||
on:
|
on: pull_request
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- '.github/workflows/**'
|
|
||||||
- 'src/**'
|
|
||||||
- 'appinfo/info.xml'
|
|
||||||
- 'package.json'
|
|
||||||
- 'package-lock.json'
|
|
||||||
- 'tsconfig.json'
|
|
||||||
- '.eslintrc.*'
|
|
||||||
- '.eslintignore'
|
|
||||||
- '**.js'
|
|
||||||
- '**.ts'
|
|
||||||
- '**.vue'
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -31,24 +18,52 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
changes:
|
||||||
|
runs-on: ubuntu-latest-low
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
src: ${{ steps.changes.outputs.src}}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0
|
||||||
|
id: changes
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
src:
|
||||||
|
- '.github/workflows/**'
|
||||||
|
- 'src/**'
|
||||||
|
- 'appinfo/info.xml'
|
||||||
|
- 'package.json'
|
||||||
|
- 'package-lock.json'
|
||||||
|
- 'tsconfig.json'
|
||||||
|
- '.eslintrc.*'
|
||||||
|
- '.eslintignore'
|
||||||
|
- '**.js'
|
||||||
|
- '**.ts'
|
||||||
|
- '**.vue'
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
name: eslint
|
needs: changes
|
||||||
|
if: needs.changes.outputs.src != 'false'
|
||||||
|
|
||||||
|
name: NPM lint
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
- name: Read package.json node and npm engines version
|
||||||
uses: skjnldsv/read-package-engines-version-actions@0ce2ed60f6df073a62a77c0a4958dd0fc68e32e7 # v2.1
|
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
||||||
id: versions
|
id: versions
|
||||||
with:
|
with:
|
||||||
fallbackNode: '^16'
|
fallbackNode: '^20'
|
||||||
fallbackNpm: '^7'
|
fallbackNpm: '^10'
|
||||||
|
|
||||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||||
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3
|
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||||
|
|
||||||
@@ -56,7 +71,25 @@ jobs:
|
|||||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
|
PUPPETEER_SKIP_DOWNLOAD: true
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: npm run lint
|
run: npm run lint
|
||||||
|
|
||||||
|
summary:
|
||||||
|
permissions:
|
||||||
|
contents: none
|
||||||
|
runs-on: ubuntu-latest-low
|
||||||
|
needs: [changes, lint]
|
||||||
|
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
# This is the summary, we just avoid to rename it so that branch protection rules still match
|
||||||
|
name: eslint
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Summary status
|
||||||
|
run: if ${{ needs.changes.outputs.src != 'false' && needs.lint.result != 'success' }}; then exit 1; fi
|
||||||
|
|||||||
12
.github/workflows/lint-php-cs.yml
vendored
12
.github/workflows/lint-php-cs.yml
vendored
@@ -3,7 +3,7 @@
|
|||||||
# https://github.com/nextcloud/.github
|
# https://github.com/nextcloud/.github
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||||
|
|
||||||
name: Lint
|
name: Lint php-cs
|
||||||
|
|
||||||
on: pull_request
|
on: pull_request
|
||||||
|
|
||||||
@@ -22,13 +22,15 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Set up php
|
- name: Set up php8.2
|
||||||
uses: shivammathur/setup-php@2.25.1 # v2
|
uses: shivammathur/setup-php@6d7209f44a25a59e904b1ee9f3b0c33ab2cd888d # v2
|
||||||
with:
|
with:
|
||||||
php-version: 8.1
|
php-version: 8.2
|
||||||
|
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
||||||
coverage: none
|
coverage: none
|
||||||
|
ini-file: development
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
|||||||
20
.github/workflows/lint-php.yml
vendored
20
.github/workflows/lint-php.yml
vendored
@@ -3,15 +3,9 @@
|
|||||||
# https://github.com/nextcloud/.github
|
# https://github.com/nextcloud/.github
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||||
|
|
||||||
name: Lint
|
name: Lint php
|
||||||
|
|
||||||
on:
|
on: pull_request
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
- stable*
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -25,19 +19,21 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
php-versions: [ "8.0", "8.1", "8.2" ]
|
php-versions: [ '8.0', '8.1', '8.2', '8.3' ]
|
||||||
|
|
||||||
name: php-lint
|
name: php-lint
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Set up php ${{ matrix.php-versions }}
|
- name: Set up php ${{ matrix.php-versions }}
|
||||||
uses: shivammathur/setup-php@2.25.1 # v2
|
uses: shivammathur/setup-php@6d7209f44a25a59e904b1ee9f3b0c33ab2cd888d # v2
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php-versions }}
|
php-version: ${{ matrix.php-versions }}
|
||||||
|
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
||||||
coverage: none
|
coverage: none
|
||||||
|
ini-file: development
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
@@ -47,7 +43,7 @@ jobs:
|
|||||||
summary:
|
summary:
|
||||||
permissions:
|
permissions:
|
||||||
contents: none
|
contents: none
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest-low
|
||||||
needs: php-lint
|
needs: php-lint
|
||||||
|
|
||||||
if: always()
|
if: always()
|
||||||
|
|||||||
14
.github/workflows/lint-stylelint.yml
vendored
14
.github/workflows/lint-stylelint.yml
vendored
@@ -3,7 +3,7 @@
|
|||||||
# https://github.com/nextcloud/.github
|
# https://github.com/nextcloud/.github
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||||
|
|
||||||
name: Lint
|
name: Lint stylelint
|
||||||
|
|
||||||
on: pull_request
|
on: pull_request
|
||||||
|
|
||||||
@@ -22,17 +22,17 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
- name: Read package.json node and npm engines version
|
||||||
uses: skjnldsv/read-package-engines-version-actions@0ce2ed60f6df073a62a77c0a4958dd0fc68e32e7 # v2.1
|
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
||||||
id: versions
|
id: versions
|
||||||
with:
|
with:
|
||||||
fallbackNode: '^16'
|
fallbackNode: '^20'
|
||||||
fallbackNpm: '^7'
|
fallbackNpm: '^10'
|
||||||
|
|
||||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||||
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3
|
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||||
|
|
||||||
@@ -40,6 +40,8 @@ jobs:
|
|||||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
||||||
- name: Lint
|
- name: Lint
|
||||||
|
|||||||
64
.github/workflows/nightly.yml
vendored
64
.github/workflows/nightly.yml
vendored
@@ -1,64 +0,0 @@
|
|||||||
name: Package nightly
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- nightly
|
|
||||||
schedule:
|
|
||||||
- cron: '0 1 * * *' # run at 2 AM UTC
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
node-version: [14.x]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
- name: Set up npm7
|
|
||||||
run: npm i -g npm@7
|
|
||||||
- name: Setup PHP
|
|
||||||
uses: shivammathur/setup-php@2.25.1
|
|
||||||
with:
|
|
||||||
php-version: '7.4'
|
|
||||||
tools: composer
|
|
||||||
- name: install dependencies
|
|
||||||
run: |
|
|
||||||
wget https://github.com/ChristophWurst/krankerl/releases/download/v0.12.2/krankerl_0.12.2_amd64.deb
|
|
||||||
sudo dpkg -i krankerl_0.12.2_amd64.deb
|
|
||||||
- name: package
|
|
||||||
run: |
|
|
||||||
uname -a
|
|
||||||
RUST_BACKTRACE=1 krankerl --version
|
|
||||||
RUST_BACKTRACE=1 krankerl package
|
|
||||||
- name: Set git config
|
|
||||||
run: |
|
|
||||||
git config --local user.email "action@github.com"
|
|
||||||
git config --local user.name "GitHub Action"
|
|
||||||
git tag -f nightly
|
|
||||||
- name: Push tag
|
|
||||||
uses: juliushaertl/github-push-action@main
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
tags: true
|
|
||||||
force: true
|
|
||||||
- name: Create Release
|
|
||||||
id: create_release
|
|
||||||
uses: juliushaertl/action-release@main
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
tag: nightly
|
|
||||||
files: ./build/artifacts/deck.tar.gz
|
|
||||||
name: Nightly build
|
|
||||||
body: |
|
|
||||||
Nightly release of deck
|
|
||||||
draft: false
|
|
||||||
prerelease: true
|
|
||||||
overwrite: true
|
|
||||||
4
.github/workflows/nodejs.yml
vendored
4
.github/workflows/nodejs.yml
vendored
@@ -12,9 +12,9 @@ jobs:
|
|||||||
node-version: [14.x]
|
node-version: [14.x]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
- name: Set up npm7
|
- name: Set up npm7
|
||||||
|
|||||||
20
.github/workflows/npm-audit-fix.yml
vendored
20
.github/workflows/npm-audit-fix.yml
vendored
@@ -3,7 +3,7 @@
|
|||||||
# https://github.com/nextcloud/.github
|
# https://github.com/nextcloud/.github
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||||
|
|
||||||
name: npm audit fix and compile
|
name: Npm audit fix and compile
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -18,25 +18,25 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
branches: ["main", "master", "stable26", "stable25", "stable24"]
|
branches: ['main', 'master', 'stable28', 'stable27', 'stable26']
|
||||||
|
|
||||||
name: npm-audit-fix-${{ matrix.branches }}
|
name: npm-audit-fix-${{ matrix.branches }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ matrix.branches }}
|
ref: ${{ matrix.branches }}
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
- name: Read package.json node and npm engines version
|
||||||
uses: skjnldsv/read-package-engines-version-actions@0ce2ed60f6df073a62a77c0a4958dd0fc68e32e7 # v2.1
|
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
||||||
id: versions
|
id: versions
|
||||||
with:
|
with:
|
||||||
fallbackNode: '^16'
|
fallbackNode: '^20'
|
||||||
fallbackNpm: '^7'
|
fallbackNpm: '^10'
|
||||||
|
|
||||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||||
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3
|
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||||
|
|
||||||
@@ -49,13 +49,15 @@ jobs:
|
|||||||
|
|
||||||
- name: Run npm ci and npm run build
|
- name: Run npm ci and npm run build
|
||||||
if: always()
|
if: always()
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
run: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
npm run build --if-present
|
npm run build --if-present
|
||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
if: always()
|
if: always()
|
||||||
uses: peter-evans/create-pull-request@284f54f989303d2699d373481a0cfa13ad5a6666 # v3
|
uses: peter-evans/create-pull-request@b1ddad2c994a25fbc81a28b3ec0e368bb2021c50 # v5
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||||
commit-message: "chore(deps): fix npm audit"
|
commit-message: "chore(deps): fix npm audit"
|
||||||
|
|||||||
10
.github/workflows/phpunit.yml
vendored
10
.github/workflows/phpunit.yml
vendored
@@ -26,9 +26,9 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
php-versions: ['8.0', '8.1']
|
php-versions: ['8.0', '8.1', '8.2', '8.3']
|
||||||
databases: ['sqlite', 'mysql', 'pgsql']
|
databases: ['sqlite', 'mysql', 'pgsql']
|
||||||
server-versions: ['stable27']
|
server-versions: ['stable28']
|
||||||
|
|
||||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout server
|
- name: Checkout server
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: nextcloud/server
|
repository: nextcloud/server
|
||||||
ref: ${{ matrix.server-versions }}
|
ref: ${{ matrix.server-versions }}
|
||||||
@@ -65,12 +65,12 @@ jobs:
|
|||||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||||
|
|
||||||
- name: Checkout app
|
- name: Checkout app
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
path: apps/${{ env.APP_NAME }}
|
path: apps/${{ env.APP_NAME }}
|
||||||
|
|
||||||
- name: Set up php ${{ matrix.php-versions }}
|
- name: Set up php ${{ matrix.php-versions }}
|
||||||
uses: shivammathur/setup-php@2.25.1
|
uses: shivammathur/setup-php@2.27.1
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php-versions }}
|
php-version: ${{ matrix.php-versions }}
|
||||||
tools: phpunit
|
tools: phpunit
|
||||||
|
|||||||
34
.github/workflows/pr-feedback.yml
vendored
Normal file
34
.github/workflows/pr-feedback.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# This workflow is provided via the organization template repository
|
||||||
|
#
|
||||||
|
# https://github.com/nextcloud/.github
|
||||||
|
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||||
|
|
||||||
|
name: 'Ask for feedback on PRs'
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '30 1 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pr-feedback:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: The get-github-handles-from-website action
|
||||||
|
uses: marcelklehr/get-github-handles-from-website-action@a739600f6b91da4957f51db0792697afbb2f143c # v1.0.0
|
||||||
|
id: scrape
|
||||||
|
with:
|
||||||
|
website: 'https://nextcloud.com/team/'
|
||||||
|
- uses: marcelklehr/pr-feedback-action@601109aa729eb4c8d6d0ece7567b9d4901db4aef
|
||||||
|
with:
|
||||||
|
feedback-message: |
|
||||||
|
Hello there,
|
||||||
|
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.
|
||||||
|
|
||||||
|
We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.
|
||||||
|
|
||||||
|
Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6
|
||||||
|
|
||||||
|
Thank you for contributing to Nextcloud and we hope to hear from you soon!
|
||||||
|
days-before-feedback: 14
|
||||||
|
start-date: "2023-07-10"
|
||||||
|
exempt-authors: "${{ steps.scrape.outputs.users }},nextcloud-command,nextcloud-android-bot,skjnldsv,datenangebot"
|
||||||
|
exempt-bots: true
|
||||||
20
.github/workflows/psalm.yml
vendored
20
.github/workflows/psalm.yml
vendored
@@ -5,13 +5,7 @@
|
|||||||
|
|
||||||
name: Static analysis
|
name: Static analysis
|
||||||
|
|
||||||
on:
|
on: pull_request
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- main
|
|
||||||
- stable*
|
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: psalm-${{ github.head_ref || github.run_id }}
|
group: psalm-${{ github.head_ref || github.run_id }}
|
||||||
@@ -21,16 +15,18 @@ jobs:
|
|||||||
static-analysis:
|
static-analysis:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
name: Nextcloud
|
name: static-psalm-analysis
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Set up php
|
- name: Set up php8.2
|
||||||
uses: shivammathur/setup-php@2.25.1 # v2
|
uses: shivammathur/setup-php@6d7209f44a25a59e904b1ee9f3b0c33ab2cd888d # v2
|
||||||
with:
|
with:
|
||||||
php-version: 8.1
|
php-version: 8.2
|
||||||
|
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
||||||
coverage: none
|
coverage: none
|
||||||
|
ini-file: development
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
|||||||
68
.github/workflows/update-nextcloud-ocp.yml
vendored
68
.github/workflows/update-nextcloud-ocp.yml
vendored
@@ -17,42 +17,90 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
branches: ["master", "stable26", "stable25", "stable24"]
|
branches: ['main', 'master', 'stable28', 'stable27', 'stable26']
|
||||||
|
|
||||||
name: update-nextcloud-ocp-${{ matrix.branches }}
|
name: update-nextcloud-ocp-${{ matrix.branches }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
- id: checkout
|
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ matrix.branches }}
|
ref: ${{ matrix.branches }}
|
||||||
submodules: true
|
submodules: true
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Set up php8.1
|
- name: Set up php8.2
|
||||||
uses: shivammathur/setup-php@2.25.1 # v2
|
if: steps.checkout.outcome == 'success'
|
||||||
|
uses: shivammathur/setup-php@6d7209f44a25a59e904b1ee9f3b0c33ab2cd888d # v2
|
||||||
with:
|
with:
|
||||||
php-version: 8.1
|
php-version: 8.2
|
||||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
# https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
|
||||||
|
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
||||||
coverage: none
|
coverage: none
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Read codeowners
|
||||||
|
if: steps.checkout.outcome == 'success'
|
||||||
|
id: codeowners
|
||||||
|
run: |
|
||||||
|
grep '/appinfo/info.xml' .github/CODEOWNERS | cut -f 2- -d ' ' | xargs | awk '{ print "codeowners="$0 }' >> $GITHUB_OUTPUT
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Composer install
|
- name: Composer install
|
||||||
|
if: steps.checkout.outcome == 'success'
|
||||||
run: composer install
|
run: composer install
|
||||||
|
|
||||||
- name: Composer update nextcloud/ocp
|
- name: Composer update nextcloud/ocp
|
||||||
|
id: update_branch
|
||||||
|
if: ${{ steps.checkout.outcome == 'success' && matrix.branches != 'main' }}
|
||||||
run: composer require --dev nextcloud/ocp:dev-${{ matrix.branches }}
|
run: composer require --dev nextcloud/ocp:dev-${{ matrix.branches }}
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Reset checkout dirs
|
- name: Raise on issue on failure
|
||||||
|
uses: dacbd/create-issue-action@ba4d1c45cccf9c483f2720cefb40e437f0ee6f7d # v1.2.1
|
||||||
|
if: ${{ steps.checkout.outcome == 'success' && failure() && steps.update_branch.conclusion == 'failure' }}
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
title: Failed to update nextcloud/ocp package on branch ${{ matrix.branches }}
|
||||||
|
body: Please check the output of the GitHub action and manually resolve the issues<br>${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}<br>${{ steps.codeowners.outputs.codeowners }}
|
||||||
|
|
||||||
|
- name: Composer update nextcloud/ocp
|
||||||
|
id: update_main
|
||||||
|
if: ${{ steps.checkout.outcome == 'success' && matrix.branches == 'main' }}
|
||||||
|
run: composer require --dev nextcloud/ocp:dev-master
|
||||||
|
|
||||||
|
- name: Raise on issue on failure
|
||||||
|
uses: dacbd/create-issue-action@ba4d1c45cccf9c483f2720cefb40e437f0ee6f7d # v1.2.1
|
||||||
|
if: ${{ steps.checkout.outcome == 'success' && failure() && steps.update_main.conclusion == 'failure' }}
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
title: Failed to update nextcloud/ocp package on branch ${{ matrix.branches }}
|
||||||
|
body: Please check the output of the GitHub action and manually resolve the issues<br>${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}<br>${{ steps.codeowners.outputs.codeowners }}
|
||||||
|
|
||||||
|
- name: Reset checkout 3rdparty
|
||||||
|
if: steps.checkout.outcome == 'success'
|
||||||
run: |
|
run: |
|
||||||
git clean -f 3rdparty
|
git clean -f 3rdparty
|
||||||
|
git checkout 3rdparty
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Reset checkout vendor
|
||||||
|
if: steps.checkout.outcome == 'success'
|
||||||
|
run: |
|
||||||
git clean -f vendor
|
git clean -f vendor
|
||||||
|
git checkout vendor
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Reset checkout vendor-bin
|
||||||
|
if: steps.checkout.outcome == 'success'
|
||||||
|
run: |
|
||||||
git clean -f vendor-bin
|
git clean -f vendor-bin
|
||||||
git checkout 3rdparty vendor vendor-bin
|
git checkout vendor-bin
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
uses: peter-evans/create-pull-request@284f54f989303d2699d373481a0cfa13ad5a6666 # v3
|
if: steps.checkout.outcome == 'success'
|
||||||
|
uses: peter-evans/create-pull-request@b1ddad2c994a25fbc81a28b3ec0e368bb2021c50 # v3
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||||
commit-message: "chore(dev-deps): Bump nextcloud/ocp package"
|
commit-message: "chore(dev-deps): Bump nextcloud/ocp package"
|
||||||
|
|||||||
272
CHANGELOG.md
272
CHANGELOG.md
@@ -1,105 +1,198 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## 1.11.5
|
## 1.12.3
|
||||||
|
- don't reset update time when no update was written to db #6035
|
||||||
### Fixed
|
- Clarify config file not found exception message #5725
|
||||||
- don't reset update time when no update was written to db #6036
|
- fix: permission check for cloning board #5854
|
||||||
- fix: Avoid conflicts on deck attachments folder name #5709
|
- fix: Avoid conflicts on deck attachments folder name #5704
|
||||||
- fix: permission check for cloning board #5856
|
|
||||||
- fix(CardMenu): introduce cardRichObject in CardMenu #5610
|
|
||||||
- Clarify config file not found exception message #5726
|
|
||||||
|
|
||||||
## 1.11.4
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- fix(PermissionService#getPermissions): Catch exceptions from getBoard method @backportbot[bot] [#5547](https://github.com/nextcloud/deck/pull/5547)
|
|
||||||
- fix(activity): Fix permission checks when rendering activities in bac… @backportbot[bot] [#5544](https://github.com/nextcloud/deck/pull/5544)
|
|
||||||
|
|
||||||
## 1.11.3
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- fix: allow null label colors in trello json importer @juliushaertl [#5438](https://github.com/nextcloud/deck/pull/5438)
|
|
||||||
- Fix deleted card/board issues @juliushaertl [#5442](https://github.com/nextcloud/deck/pull/5442)
|
|
||||||
|
|
||||||
### Other
|
|
||||||
|
|
||||||
- Fix small issues around delete/undo @juliushaertl [#5420](https://github.com/nextcloud/deck/pull/5420)
|
|
||||||
|
|
||||||
## 1.11.2
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- fix: Use text content as result for comments [#5297](https://github.com/nextcloud/deck/pull/5297)
|
|
||||||
|
|
||||||
## 1.11.1
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- feat: remember last board, list for new card dialog [#5049](https://github.com/nextcloud/deck/pull/5049)
|
|
||||||
- feat: update smart picker links [#5072](https://github.com/nextcloud/deck/pull/5072)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- fix: export doesn't handle lists with no cards [#5118](https://github.com/nextcloud/deck/pull/5118)
|
|
||||||
- fix: Check both card reference url patterns [#5263](https://github.com/nextcloud/deck/pull/5263)
|
|
||||||
- Issue triage fix collection @juliushaertl [#5286](https://github.com/nextcloud/deck/pull/5286)
|
|
||||||
- fix: open card in modal on main route [#5288](https://github.com/nextcloud/deck/pull/5288)
|
|
||||||
- fix: Avoid too large index on postgres as indexing just the last_editor column is enough [#5291](https://github.com/nextcloud/deck/pull/5291)
|
|
||||||
- fix: error msg on CreateNewCardCustomPicker & only show available bo… [#5030](https://github.com/nextcloud/deck/pull/5030)
|
|
||||||
- Remove duplicate button [#5043](https://github.com/nextcloud/deck/pull/5043)
|
|
||||||
|
|
||||||
### Other
|
|
||||||
|
|
||||||
- fix cypress for new file picker @juliushaertl [#5027](https://github.com/nextcloud/deck/pull/5027)
|
|
||||||
- test: add cypress tests for create new deck card [#5026](https://github.com/nextcloud/deck/pull/5026)
|
|
||||||
- Update dependencies
|
- Update dependencies
|
||||||
|
|
||||||
## 1.11.0
|
## 1.12.2
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- feat: Import of deck JSON data through occ [#5003](https://github.com/nextcloud/deck/pull/5003)
|
|
||||||
- feat: create new card from smart picker [#5000](https://github.com/nextcloud/deck/pull/5000)
|
|
||||||
- feat: update smart picker links [#5072](https://github.com/nextcloud/deck/pull/5072)
|
|
||||||
- feat: remember last board, list for new card dialog [#5049](https://github.com/nextcloud/deck/pull/5049)
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix(occ): set user id for permission sevice from board service [#4813](https://github.com/nextcloud/deck/pull/4813)
|
- fix(done): Mark card as undone when updating card [#5492](https://github.com/nextcloud/deck/pull/5492)
|
||||||
- fix: Allow dynamic autoloading for classes added during upgrade [#4804](https://github.com/nextcloud/deck/pull/4804)
|
- fix(activity): Fix permission checks when rendering activities in bac… @backportbot[bot] [#5543](https://github.com/nextcloud/deck/pull/5543)
|
||||||
- fix(notification): Prevent null in parameters [#4909](https://github.com/nextcloud/deck/pull/4909)
|
- fix(PermissionService#getPermissions): Catch exceptions from getBoard method @backportbot[bot] [#5546](https://github.com/nextcloud/deck/pull/5546)
|
||||||
- fix: Split query to fetch board ids to avoid slow query join @juliushaertl [#4949](https://github.com/nextcloud/deck/pull/4949)
|
- fix: Safeguard sync requests to hopefully not spam then server @backportbot[bot] [#5593](https://github.com/nextcloud/deck/pull/5593)
|
||||||
- fix: export doesn't handle lists with no cards [#5118](https://github.com/nextcloud/deck/pull/5118)
|
- fix: card move dialog auto close @backportbot[bot] [#5596](https://github.com/nextcloud/deck/pull/5596)
|
||||||
- fix: execute return int for export command [#4811](https://github.com/nextcloud/deck/pull/4811)
|
|
||||||
- fix: crash when leaving out system parameter [#4831](https://github.com/nextcloud/deck/pull/4831)
|
|
||||||
- test: add cypress tests for create new deck card [#5026](https://github.com/nextcloud/deck/pull/5026)
|
|
||||||
- feat: error msg on CreateNewCardCustomPicker & only show available bo… [#5030](https://github.com/nextcloud/deck/pull/5030)
|
|
||||||
- Remove duplicate button [#5043](https://github.com/nextcloud/deck/pull/5043)
|
|
||||||
|
|
||||||
### Other
|
### Other
|
||||||
|
|
||||||
- Dependency updates
|
- fix(i18n): Improved wording [#5497](https://github.com/nextcloud/deck/pull/5497)
|
||||||
|
|
||||||
## 1.11.0-beta.1
|
## 1.12.1
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Import deck json files through occ @juliushaertl [#5003](https://github.com/nextcloud/deck/pull/5003)
|
|
||||||
- Create new card via smart picker [#5000](https://github.com/nextcloud/deck/pull/5000)
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix(occ): set user id for permission sevice from board service [#4813](https://github.com/nextcloud/deck/pull/4813)
|
- Fix deleted card/board issues @juliushaertl [#5441](https://github.com/nextcloud/deck/pull/5441)
|
||||||
- fix: Allow dynamic autoloading for classes added during upgrade [#4804](https://github.com/nextcloud/deck/pull/4804)
|
- Fixing #5451 [#5457](https://github.com/nextcloud/deck/pull/5457)
|
||||||
- fix(notification): Prevent null in parameters [#4909](https://github.com/nextcloud/deck/pull/4909)
|
- fix: Add debounce to update due date [#5483](https://github.com/nextcloud/deck/pull/5483)
|
||||||
- fix: Split query to fetch board ids to avoid slow query join @juliushaertl [#4949](https://github.com/nextcloud/deck/pull/4949)
|
- fix(i18n): Fixed typo [#5424](https://github.com/nextcloud/deck/pull/5424)
|
||||||
- fix: execute return int for export command [#4811](https://github.com/nextcloud/deck/pull/4811)
|
|
||||||
- fix: crash when leaving out system parameter [#4831](https://github.com/nextcloud/deck/pull/4831)
|
|
||||||
|
|
||||||
## 1.10.0
|
## 1.12.0
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added ability to mark a card as done @TehThanos [#4137](https://github.com/nextcloud/deck/pull/4137)
|
||||||
|
- Card Cover Images @jszeibert [#5035](https://github.com/nextcloud/deck/pull/5035)
|
||||||
|
- Upcoming/Today/Tomorrow dashboard widgets @BKapelari [#2658](https://github.com/nextcloud/deck/pull/2658)
|
||||||
|
- Enabled advanced fields option on tag color picker @faab007nl [#4362](https://github.com/nextcloud/deck/pull/4362)
|
||||||
|
- Remember last board, list for new card dialog @luka-nextcloud [#5046](https://github.com/nextcloud/deck/pull/5046)
|
||||||
|
- Add support for bidirectional text @jamazi [#5258](https://github.com/nextcloud/deck/pull/5258)
|
||||||
|
- Card layout polishing @juliushaertl [#5264](https://github.com/nextcloud/deck/pull/5264)
|
||||||
|
- feat: Move to contenteditable for inline title editing @juliushaertl [#5282](https://github.com/nextcloud/deck/pull/5282)
|
||||||
|
- scroll board by dragging @shoetten [#5293](https://github.com/nextcloud/deck/pull/5293)
|
||||||
|
- Keyboard shortcuts [#5358](https://github.com/nextcloud/deck/pull/5358)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- fix: allow null label colors in trello json importer [#5355](https://github.com/nextcloud/deck/pull/5355)
|
||||||
|
- fix: Get proper rich object for card actions [#5352](https://github.com/nextcloud/deck/pull/5352)
|
||||||
|
- fix: Use text content as result for comments @juliushaertl [#5294](https://github.com/nextcloud/deck/pull/5294)
|
||||||
|
- fix: Bring back due date indicator to compact mode @juliushaertl [#5292](https://github.com/nextcloud/deck/pull/5292)
|
||||||
|
- Fix small issues around delete/undo @juliushaertl [#5296](https://github.com/nextcloud/deck/pull/5296)
|
||||||
|
- fix(controls): use primary when filter is active @fitrahfm [#5299](https://github.com/nextcloud/deck/pull/5299)
|
||||||
|
- fix: Properly get done state for dav @juliushaertl [#5287](https://github.com/nextcloud/deck/pull/5287)
|
||||||
|
- Fix upcoming cards and label input @juliushaertl [#5290](https://github.com/nextcloud/deck/pull/5290)
|
||||||
|
- fix: Properly handle adding new tags through multiselect @juliushaertl [#5285](https://github.com/nextcloud/deck/pull/5285)
|
||||||
|
- fix: Avoid throwing errors if no token provided on close @juliushaertl [#5284](https://github.com/nextcloud/deck/pull/5284)
|
||||||
|
- fix: Expose card actions in the card menu (fix #3180) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Use full card menu everywhere (fix #3993) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Detect end of the activity responses (fix #3395) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Add title with absolute date time to activity (fix #4508, fix #2122) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Disable dragging archived cards (fix #3271) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Hide unavailable card menu entries for archived card view [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Use localCompare to sort labels (fix #2736) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: More fitting click target for title editing [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Always load proper dashboard js (fixes a log error) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Set fixed height for card modal (fix #4296) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Make sure to always update card description when navigating away (fix #5254 #2705) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- perf: Already pass board list as initial state @juliushaertl [#5281](https://github.com/nextcloud/deck/pull/5281)
|
||||||
|
- Deck card comment notification label improvement @Jerome-Herbinet [#4748](https://github.com/nextcloud/deck/pull/4748)
|
||||||
|
- update smart picker links @luka-nextcloud [#5047](https://github.com/nextcloud/deck/pull/5047)
|
||||||
|
- feat: Enhance dark mode @juliushaertl [#5045](https://github.com/nextcloud/deck/pull/5045)
|
||||||
|
- fix: export doesn't handle lists with no cards @magikmw [#5096](https://github.com/nextcloud/deck/pull/5096)
|
||||||
|
- add attributes aria-label= and title= to Filters & View Modes buttons @privatemaker [#5133](https://github.com/nextcloud/deck/pull/5133)
|
||||||
|
- fix: Check both card reference url patterns @juliushaertl [#5262](https://github.com/nextcloud/deck/pull/5262)
|
||||||
|
- fix: Avoid too large index on postgres as indexing just the last_editor column is enough @juliushaertl [#5260](https://github.com/nextcloud/deck/pull/5260)
|
||||||
|
- feat: error msg on CreateNewCardCustomPicker & only show available bo… @luka-nextcloud [#5029](https://github.com/nextcloud/deck/pull/5029)
|
||||||
|
- test: add cypress tests for create new deck card @luka-nextcloud [#5025](https://github.com/nextcloud/deck/pull/5025)
|
||||||
|
- Remove duplicate button @solracsf [#4850](https://github.com/nextcloud/deck/pull/4850)
|
||||||
|
- [stable27] fix cypress for new file picker [#5088](https://github.com/nextcloud/deck/pull/5088)
|
||||||
|
- Replace "Timeline" wording with "Activity" in order to be consistent with equivalent contexts throughout Nextcloud @Jerome-Herbinet [#5164](https://github.com/nextcloud/deck/pull/5164)
|
||||||
|
- Board creation limitation : More understandable wordings @Jerome-Herbinet [#5168](https://github.com/nextcloud/deck/pull/5168)
|
||||||
|
- ci(cypress): Fix file picker selector @juliushaertl [#5212](https://github.com/nextcloud/deck/pull/5212)
|
||||||
|
- Switch to native date picker @juliushaertl [#4668](https://github.com/nextcloud/deck/pull/4668)
|
||||||
|
- fixes minor spelling error @FundreasFrohsinn [#5216](https://github.com/nextcloud/deck/pull/5216)
|
||||||
|
- feat(card): tooltip for comment timestamp @fitrahfm [#5253](https://github.com/nextcloud/deck/pull/5253)
|
||||||
|
|
||||||
|
## 1.12.0-beta.5
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Keyboard shortcuts [#5358](https://github.com/nextcloud/deck/pull/5358)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- fix: allow null label colors in trello json importer [#5355](https://github.com/nextcloud/deck/pull/5355)
|
||||||
|
- fix: Get proper rich object for card actions [#5352](https://github.com/nextcloud/deck/pull/5352)
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Update nextcloud/ocp dependency @nextcloud-command [#5343](https://github.com/nextcloud/deck/pull/5343)
|
||||||
|
- Chore(deps): Bump @babel/runtime from 7.23.4 to 7.23.5 @dependabot[bot] [#5338](https://github.com/nextcloud/deck/pull/5338)
|
||||||
|
|
||||||
|
|
||||||
|
## 1.12.0-beta.4
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- scroll board by dragging @shoetten [#5293](https://github.com/nextcloud/deck/pull/5293)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- fix: Use text content as result for comments @juliushaertl [#5294](https://github.com/nextcloud/deck/pull/5294)
|
||||||
|
- fix: Bring back due date indicator to compact mode @juliushaertl [#5292](https://github.com/nextcloud/deck/pull/5292)
|
||||||
|
- Fix small issues around delete/undo @juliushaertl [#5296](https://github.com/nextcloud/deck/pull/5296)
|
||||||
|
- fix(controls): use primary when filter is active @fitrahfm [#5299](https://github.com/nextcloud/deck/pull/5299)
|
||||||
|
|
||||||
|
## 1.12.0-beta.3
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- feat: Move to contenteditable for inline title editing @juliushaertl [#5282](https://github.com/nextcloud/deck/pull/5282)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- fix: Properly get done state for dav @juliushaertl [#5287](https://github.com/nextcloud/deck/pull/5287)
|
||||||
|
- Fix upcoming cards and label input @juliushaertl [#5290](https://github.com/nextcloud/deck/pull/5290)
|
||||||
|
|
||||||
|
## 1.12.0-beta.2
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Card layout polishing @juliushaertl [#5264](https://github.com/nextcloud/deck/pull/5264)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- fix: Properly handle adding new tags through multiselect @juliushaertl [#5285](https://github.com/nextcloud/deck/pull/5285)
|
||||||
|
- fix: Avoid throwing errors if no token provided on close @juliushaertl [#5284](https://github.com/nextcloud/deck/pull/5284)
|
||||||
|
- fix: Expose card actions in the card menu (fix #3180) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Use full card menu everywhere (fix #3993) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Detect end of the activity responses (fix #3395) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Add title with absolute date time to activity (fix #4508, fix #2122) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Disable dragging archived cards (fix #3271) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Hide unavailable card menu entries for archived card view [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Use localCompare to sort labels (fix #2736) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: More fitting click target for title editing [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Always load proper dashboard js (fixes a log error) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Set fixed height for card modal (fix #4296) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- fix: Make sure to always update card description when navigating away (fix #5254 #2705) [#5280](https://github.com/nextcloud/deck/pull/5280)
|
||||||
|
- perf: Already pass board list as initial state @juliushaertl [#5281](https://github.com/nextcloud/deck/pull/5281)
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
- Fix npm audit @nextcloud-command [#5277](https://github.com/nextcloud/deck/pull/5277)
|
||||||
|
- Update nextcloud/ocp dependency @nextcloud-command [#5275](https://github.com/nextcloud/deck/pull/5275)
|
||||||
|
- Chore(deps): Bump @nextcloud/dialogs from 4.2.1 to 4.2.2 @dependabot[bot] [#5266](https://github.com/nextcloud/deck/pull/5266)
|
||||||
|
- Chore(deps-dev): Bump cypress from 13.4.0 to 13.5.0 @dependabot[bot] [#5267](https://github.com/nextcloud/deck/pull/5267)
|
||||||
|
- Chore(deps): Bump shivammathur/setup-php from 2.27.0 to 2.27.1 @dependabot[bot] [#5268](https://github.com/nextcloud/deck/pull/5268)
|
||||||
|
|
||||||
|
|
||||||
|
## 1.12.0-beta.1
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added ability to mark a card as done @TehThanos [#4137](https://github.com/nextcloud/deck/pull/4137)
|
||||||
|
- Card Cover Images @jszeibert [#5035](https://github.com/nextcloud/deck/pull/5035)
|
||||||
|
- Upcoming/Today/Tomorrow dashboard widgets @BKapelari [#2658](https://github.com/nextcloud/deck/pull/2658)
|
||||||
|
- Enabled advanced fields option on tag color picker @faab007nl [#4362](https://github.com/nextcloud/deck/pull/4362)
|
||||||
|
- Remember last board, list for new card dialog @luka-nextcloud [#5046](https://github.com/nextcloud/deck/pull/5046)
|
||||||
|
- Add support for bidirectional text @jamazi [#5258](https://github.com/nextcloud/deck/pull/5258)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Deck card comment notification label improvement @Jerome-Herbinet [#4748](https://github.com/nextcloud/deck/pull/4748)
|
||||||
|
- update smart picker links @luka-nextcloud [#5047](https://github.com/nextcloud/deck/pull/5047)
|
||||||
|
- feat: Enhance dark mode @juliushaertl [#5045](https://github.com/nextcloud/deck/pull/5045)
|
||||||
|
- fix: export doesn't handle lists with no cards @magikmw [#5096](https://github.com/nextcloud/deck/pull/5096)
|
||||||
|
- add attributes aria-label= and title= to Filters & View Modes buttons @privatemaker [#5133](https://github.com/nextcloud/deck/pull/5133)
|
||||||
|
- fix: Check both card reference url patterns @juliushaertl [#5262](https://github.com/nextcloud/deck/pull/5262)
|
||||||
|
- fix: Avoid too large index on postgres as indexing just the last_editor column is enough @juliushaertl [#5260](https://github.com/nextcloud/deck/pull/5260)
|
||||||
|
- feat: error msg on CreateNewCardCustomPicker & only show available bo… @luka-nextcloud [#5029](https://github.com/nextcloud/deck/pull/5029)
|
||||||
|
- test: add cypress tests for create new deck card @luka-nextcloud [#5025](https://github.com/nextcloud/deck/pull/5025)
|
||||||
|
- Remove duplicate button @solracsf [#4850](https://github.com/nextcloud/deck/pull/4850)
|
||||||
|
- [stable27] fix cypress for new file picker [#5088](https://github.com/nextcloud/deck/pull/5088)
|
||||||
|
- Replace "Timeline" wording with "Activity" in order to be consistent with equivalent contexts throughout Nextcloud @Jerome-Herbinet [#5164](https://github.com/nextcloud/deck/pull/5164)
|
||||||
|
- Board creation limitation : More understandable wordings @Jerome-Herbinet [#5168](https://github.com/nextcloud/deck/pull/5168)
|
||||||
|
- ci(cypress): Fix file picker selector @juliushaertl [#5212](https://github.com/nextcloud/deck/pull/5212)
|
||||||
|
- Switch to native date picker @juliushaertl [#4668](https://github.com/nextcloud/deck/pull/4668)
|
||||||
|
- fixes minor spelling error @FundreasFrohsinn [#5216](https://github.com/nextcloud/deck/pull/5216)
|
||||||
|
- feat(card): tooltip for comment timestamp @fitrahfm [#5253](https://github.com/nextcloud/deck/pull/5253)
|
||||||
|
|
||||||
|
## 1.10.0-beta.1
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
@@ -107,8 +200,6 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- fix: Properly overwrite z-index of datepicker above modal @juliushaertl [#4664](https://github.com/nextcloud/deck/pull/4664)
|
|
||||||
- Use the color-primary-element* variables @szaimen [#4673](https://github.com/nextcloud/deck/pull/4673)
|
|
||||||
- fix(references): Mute NoPermissionException as it is expected to happen for references @juliushaertl [#4514](https://github.com/nextcloud/deck/pull/4514)
|
- fix(references): Mute NoPermissionException as it is expected to happen for references @juliushaertl [#4514](https://github.com/nextcloud/deck/pull/4514)
|
||||||
- fix(cards): Fix card sizing by limiting too wide style rules @juliushaertl [#4512](https://github.com/nextcloud/deck/pull/4512)
|
- fix(cards): Fix card sizing by limiting too wide style rules @juliushaertl [#4512](https://github.com/nextcloud/deck/pull/4512)
|
||||||
- fix: Adapt NcEmptyContent usages to new slots @juliushaertl [#4561](https://github.com/nextcloud/deck/pull/4561)
|
- fix: Adapt NcEmptyContent usages to new slots @juliushaertl [#4561](https://github.com/nextcloud/deck/pull/4561)
|
||||||
@@ -128,12 +219,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- Better display of card dates (creation and change dates) @Jerome-Herbinet [#4604](https://github.com/nextcloud/deck/pull/4604)
|
- Better display of card dates (creation and change dates) @Jerome-Herbinet [#4604](https://github.com/nextcloud/deck/pull/4604)
|
||||||
- Refactors lib\Activity\DeckProvider.php to improve code readability. @fsamapoor [#4648](https://github.com/nextcloud/deck/pull/4648)
|
- Refactors lib\Activity\DeckProvider.php to improve code readability. @fsamapoor [#4648](https://github.com/nextcloud/deck/pull/4648)
|
||||||
- Converts 'strpos()' calls to improve code readability. @fsamapoor [#4657](https://github.com/nextcloud/deck/pull/4657)
|
- Converts 'strpos()' calls to improve code readability. @fsamapoor [#4657](https://github.com/nextcloud/deck/pull/4657)
|
||||||
- Dependency updates
|
|
||||||
|
|
||||||
### Other
|
|
||||||
|
|
||||||
- feat: Add devcontainer and update dev docs @juliushaertl [#4683](https://github.com/nextcloud/deck/pull/4683)
|
|
||||||
- chore(CI): Adjust testing matrix for Nextcloud 27 on stable27 @nickvergessen [#4691](https://github.com/nextcloud/deck/pull/4691)
|
|
||||||
|
|
||||||
## 1.9.0-beta.1
|
## 1.9.0-beta.1
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ Deck is a kanban style organization tool aimed at personal planning and project
|
|||||||
- [trello-to-deck](https://github.com/maxammann/trello-to-deck) - Migrates cards from Trello
|
- [trello-to-deck](https://github.com/maxammann/trello-to-deck) - Migrates cards from Trello
|
||||||
- [mail2deck](https://github.com/newroco/mail2deck) - Provides an "email in" solution
|
- [mail2deck](https://github.com/newroco/mail2deck) - Provides an "email in" solution
|
||||||
- [A-deck](https://github.com/leoossa/A-deck) - Chrome Extension that allows to create new card in selected stack based on current tab
|
- [A-deck](https://github.com/leoossa/A-deck) - Chrome Extension that allows to create new card in selected stack based on current tab
|
||||||
|
- [QOwnNotes](https://github.com/pbek/QOwnNotes) - Quickly creates cards and links to them in Markdown notes
|
||||||
|
|
||||||
## Installation/Update
|
## Installation/Update
|
||||||
|
|
||||||
@@ -76,7 +77,7 @@ You can enable HMR (Hot module replacement) to avoid page reloads when working o
|
|||||||
|
|
||||||
### Docker: Simple app development container
|
### Docker: Simple app development container
|
||||||
|
|
||||||
- Fork the app
|
- Fork the app
|
||||||
- Clone the repository: `git clone https://github.com/nextcloud/deck.git`
|
- Clone the repository: `git clone https://github.com/nextcloud/deck.git`
|
||||||
- Go into deck directory: `cd deck`
|
- Go into deck directory: `cd deck`
|
||||||
- Build the app as described in the general build instructions
|
- Build the app as described in the general build instructions
|
||||||
@@ -92,7 +93,7 @@ docker run --rm \
|
|||||||
### Full Nextcloud development environment
|
### Full Nextcloud development environment
|
||||||
|
|
||||||
You need to setup a [development environment](https://docs.nextcloud.com/server/latest/developer_manual//getting_started/devenv.html) of the current Nextcloud version. You can also alternatively install & run the [nextcloud docker container](https://github.com/juliushaertl/nextcloud-docker-dev).
|
You need to setup a [development environment](https://docs.nextcloud.com/server/latest/developer_manual//getting_started/devenv.html) of the current Nextcloud version. You can also alternatively install & run the [nextcloud docker container](https://github.com/juliushaertl/nextcloud-docker-dev).
|
||||||
After the finished installation, you can clone the deck project directly in the `/[nextcloud-docker-dev-dir]/workspace/server/apps/` folder.
|
After the finished installation, you can clone the deck project directly in the `/[nextcloud-docker-dev-dir]/workspace/server/apps/` folder.
|
||||||
|
|
||||||
### Running tests
|
### Running tests
|
||||||
You can use the provided Makefile to run all tests by using:
|
You can use the provided Makefile to run all tests by using:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
- 🚀 Get your project organized
|
- 🚀 Get your project organized
|
||||||
|
|
||||||
</description>
|
</description>
|
||||||
<version>1.11.5</version>
|
<version>1.12.3</version>
|
||||||
<licence>agpl</licence>
|
<licence>agpl</licence>
|
||||||
<author>Julius Härtl</author>
|
<author>Julius Härtl</author>
|
||||||
<documentation>
|
<documentation>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
<database min-version="9.4">pgsql</database>
|
<database min-version="9.4">pgsql</database>
|
||||||
<database>sqlite</database>
|
<database>sqlite</database>
|
||||||
<database min-version="8.0">mysql</database>
|
<database min-version="8.0">mysql</database>
|
||||||
<nextcloud min-version="27" max-version="27"/>
|
<nextcloud min-version="28" max-version="28"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<background-jobs>
|
<background-jobs>
|
||||||
<job>OCA\Deck\Cron\DeleteCron</job>
|
<job>OCA\Deck\Cron\DeleteCron</job>
|
||||||
@@ -58,9 +58,9 @@
|
|||||||
</commands>
|
</commands>
|
||||||
<activity>
|
<activity>
|
||||||
<settings>
|
<settings>
|
||||||
<setting>OCA\Deck\Activity\Setting</setting>
|
<setting>OCA\Deck\Activity\SettingChanges</setting>
|
||||||
|
<setting>OCA\Deck\Activity\SettingDescription</setting>
|
||||||
<setting>OCA\Deck\Activity\SettingComment</setting>
|
<setting>OCA\Deck\Activity\SettingComment</setting>
|
||||||
<setting>OCA\Deck\Activity\DescriptionSetting</setting>
|
|
||||||
</settings>
|
</settings>
|
||||||
<filters>
|
<filters>
|
||||||
<filter>OCA\Deck\Activity\Filter</filter>
|
<filter>OCA\Deck\Activity\Filter</filter>
|
||||||
|
|||||||
@@ -25,6 +25,11 @@
|
|||||||
return [
|
return [
|
||||||
'routes' => [
|
'routes' => [
|
||||||
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
|
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
|
||||||
|
['name' => 'page#indexList', 'url' => '/board', 'verb' => 'GET'],
|
||||||
|
['name' => 'page#indexBoard', 'url' => '/board/{boardId}', 'verb' => 'GET'],
|
||||||
|
['name' => 'page#indexBoardDetails', 'url' => '/board/{boardId}/details', 'verb' => 'GET'],
|
||||||
|
['name' => 'page#indexCard', 'url' => '/board/{boardId}/card/{cardId}', 'verb' => 'GET'],
|
||||||
|
|
||||||
['name' => 'page#redirectToCard', 'url' => '/card/{cardId}', 'verb' => 'GET'],
|
['name' => 'page#redirectToCard', 'url' => '/card/{cardId}', 'verb' => 'GET'],
|
||||||
|
|
||||||
// boards
|
// boards
|
||||||
@@ -61,6 +66,8 @@ return [
|
|||||||
['name' => 'card#reorder', 'url' => '/cards/{cardId}/reorder', 'verb' => 'PUT'],
|
['name' => 'card#reorder', 'url' => '/cards/{cardId}/reorder', 'verb' => 'PUT'],
|
||||||
['name' => 'card#archive', 'url' => '/cards/{cardId}/archive', 'verb' => 'PUT'],
|
['name' => 'card#archive', 'url' => '/cards/{cardId}/archive', 'verb' => 'PUT'],
|
||||||
['name' => 'card#unarchive', 'url' => '/cards/{cardId}/unarchive', 'verb' => 'PUT'],
|
['name' => 'card#unarchive', 'url' => '/cards/{cardId}/unarchive', 'verb' => 'PUT'],
|
||||||
|
['name' => 'card#done', 'url' => '/cards/{cardId}/done', 'verb' => 'PUT'],
|
||||||
|
['name' => 'card#undone', 'url' => '/cards/{cardId}/undone', 'verb' => 'PUT'],
|
||||||
['name' => 'card#assignLabel', 'url' => '/cards/{cardId}/label/{labelId}', 'verb' => 'POST'],
|
['name' => 'card#assignLabel', 'url' => '/cards/{cardId}/label/{labelId}', 'verb' => 'POST'],
|
||||||
['name' => 'card#removeLabel', 'url' => '/cards/{cardId}/label/{labelId}', 'verb' => 'DELETE'],
|
['name' => 'card#removeLabel', 'url' => '/cards/{cardId}/label/{labelId}', 'verb' => 'DELETE'],
|
||||||
['name' => 'card#assignUser', 'url' => '/cards/{cardId}/assign', 'verb' => 'POST'],
|
['name' => 'card#assignUser', 'url' => '/cards/{cardId}/assign', 'verb' => 'POST'],
|
||||||
|
|||||||
@@ -15,9 +15,8 @@
|
|||||||
"roave/security-advisories": "dev-master",
|
"roave/security-advisories": "dev-master",
|
||||||
"phpunit/phpunit": "^9",
|
"phpunit/phpunit": "^9",
|
||||||
"nextcloud/coding-standard": "^1.1",
|
"nextcloud/coding-standard": "^1.1",
|
||||||
"psalm/phar": "^5.13",
|
"nextcloud/ocp": "dev-stable28",
|
||||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
"psalm/phar": "^5.13"
|
||||||
"nextcloud/ocp": "dev-stable27"
|
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"optimize-autoloader": true,
|
"optimize-autoloader": true,
|
||||||
|
|||||||
460
composer.lock
generated
460
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "25b1df7f8fcc7b43083c1d7b3178cd0f",
|
"content-hash": "2ab83bbc55ad8f0f50c5de28c10764ba",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "justinrainbow/json-schema",
|
"name": "justinrainbow/json-schema",
|
||||||
@@ -250,20 +250,20 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nextcloud/ocp",
|
"name": "nextcloud/ocp",
|
||||||
"version": "dev-stable27",
|
"version": "dev-stable28",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/nextcloud-deps/ocp.git",
|
"url": "https://github.com/nextcloud-deps/ocp.git",
|
||||||
"reference": "a25af68d428145141ac85ae0746f70d9f04911e4"
|
"reference": "1c0336e8d268afa7accafe096b52cc6fe2c694d1"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/a25af68d428145141ac85ae0746f70d9f04911e4",
|
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/1c0336e8d268afa7accafe096b52cc6fe2c694d1",
|
||||||
"reference": "a25af68d428145141ac85ae0746f70d9f04911e4",
|
"reference": "1c0336e8d268afa7accafe096b52cc6fe2c694d1",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.4 || ~8.0 || ~8.1",
|
"php": "~8.0 || ~8.1 || ~8.2 || ~8.3",
|
||||||
"psr/clock": "^1.0",
|
"psr/clock": "^1.0",
|
||||||
"psr/container": "^2.0.2",
|
"psr/container": "^2.0.2",
|
||||||
"psr/event-dispatcher": "^1.0",
|
"psr/event-dispatcher": "^1.0",
|
||||||
@@ -272,7 +272,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-stable27": "27.0.0-dev"
|
"dev-stable28": "28.0.0-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
@@ -288,22 +288,22 @@
|
|||||||
"description": "Composer package containing Nextcloud's public API (classes, interfaces)",
|
"description": "Composer package containing Nextcloud's public API (classes, interfaces)",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/nextcloud-deps/ocp/issues",
|
"issues": "https://github.com/nextcloud-deps/ocp/issues",
|
||||||
"source": "https://github.com/nextcloud-deps/ocp/tree/stable27"
|
"source": "https://github.com/nextcloud-deps/ocp/tree/stable28"
|
||||||
},
|
},
|
||||||
"time": "2024-06-05T00:35:15+00:00"
|
"time": "2024-06-14T00:35:47+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
"version": "v4.18.0",
|
"version": "v4.17.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||||
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
|
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
|
||||||
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -344,9 +344,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0"
|
"source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
|
||||||
},
|
},
|
||||||
"time": "2023-12-10T21:03:43+00:00"
|
"time": "2023-08-13T19:53:39+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phar-io/manifest",
|
"name": "phar-io/manifest",
|
||||||
@@ -461,16 +461,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "php-cs-fixer/shim",
|
"name": "php-cs-fixer/shim",
|
||||||
"version": "v3.41.1",
|
"version": "v3.22.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/PHP-CS-Fixer/shim.git",
|
"url": "https://github.com/PHP-CS-Fixer/shim.git",
|
||||||
"reference": "01cea2dca727100537bd63e28e06e49a475b54e9"
|
"reference": "f6692934a6d1fe40fd8bc3339487490baa4a6700"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/01cea2dca727100537bd63e28e06e49a475b54e9",
|
"url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/f6692934a6d1fe40fd8bc3339487490baa4a6700",
|
||||||
"reference": "01cea2dca727100537bd63e28e06e49a475b54e9",
|
"reference": "f6692934a6d1fe40fd8bc3339487490baa4a6700",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -507,66 +507,9 @@
|
|||||||
"description": "A tool to automatically fix PHP code style",
|
"description": "A tool to automatically fix PHP code style",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/PHP-CS-Fixer/shim/issues",
|
"issues": "https://github.com/PHP-CS-Fixer/shim/issues",
|
||||||
"source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.41.1"
|
"source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.22.0"
|
||||||
},
|
},
|
||||||
"time": "2023-12-10T19:59:57+00:00"
|
"time": "2023-07-16T23:08:49+00:00"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "php-parallel-lint/php-parallel-lint",
|
|
||||||
"version": "v1.3.2",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git",
|
|
||||||
"reference": "6483c9832e71973ed29cf71bd6b3f4fde438a9de"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/6483c9832e71973ed29cf71bd6b3f4fde438a9de",
|
|
||||||
"reference": "6483c9832e71973ed29cf71bd6b3f4fde438a9de",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-json": "*",
|
|
||||||
"php": ">=5.3.0"
|
|
||||||
},
|
|
||||||
"replace": {
|
|
||||||
"grogy/php-parallel-lint": "*",
|
|
||||||
"jakub-onderka/php-parallel-lint": "*"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"nette/tester": "^1.3 || ^2.0",
|
|
||||||
"php-parallel-lint/php-console-highlighter": "0.* || ^1.0",
|
|
||||||
"squizlabs/php_codesniffer": "^3.6"
|
|
||||||
},
|
|
||||||
"suggest": {
|
|
||||||
"php-parallel-lint/php-console-highlighter": "Highlight syntax in code snippet"
|
|
||||||
},
|
|
||||||
"bin": [
|
|
||||||
"parallel-lint"
|
|
||||||
],
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"classmap": [
|
|
||||||
"./src/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"BSD-2-Clause"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Jakub Onderka",
|
|
||||||
"email": "ahoj@jakubonderka.cz"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "This tool check syntax of PHP files about 20x faster than serial check.",
|
|
||||||
"homepage": "https://github.com/php-parallel-lint/PHP-Parallel-Lint",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/issues",
|
|
||||||
"source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v1.3.2"
|
|
||||||
},
|
|
||||||
"time": "2022-02-21T12:50:22+00:00"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
@@ -889,16 +832,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "9.6.15",
|
"version": "9.6.13",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "05017b80304e0eb3f31d90194a563fd53a6021f1"
|
"reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be",
|
||||||
"reference": "05017b80304e0eb3f31d90194a563fd53a6021f1",
|
"reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -972,7 +915,7 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15"
|
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -988,20 +931,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-12-01T16:55:19+00:00"
|
"time": "2023-09-19T05:39:22+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psalm/phar",
|
"name": "psalm/phar",
|
||||||
"version": "5.18.0",
|
"version": "5.15.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/psalm/phar.git",
|
"url": "https://github.com/psalm/phar.git",
|
||||||
"reference": "a78b5c2e8860c3b4242c63bc0864621278705f9a"
|
"reference": "19dde3eba5901ff50ca43a5e4c43540f097e0511"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/psalm/phar/zipball/a78b5c2e8860c3b4242c63bc0864621278705f9a",
|
"url": "https://api.github.com/repos/psalm/phar/zipball/19dde3eba5901ff50ca43a5e4c43540f097e0511",
|
||||||
"reference": "a78b5c2e8860c3b4242c63bc0864621278705f9a",
|
"reference": "19dde3eba5901ff50ca43a5e4c43540f097e0511",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1021,9 +964,9 @@
|
|||||||
"description": "Composer-based Psalm Phar",
|
"description": "Composer-based Psalm Phar",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/psalm/phar/issues",
|
"issues": "https://github.com/psalm/phar/issues",
|
||||||
"source": "https://github.com/psalm/phar/tree/5.18.0"
|
"source": "https://github.com/psalm/phar/tree/5.15.0"
|
||||||
},
|
},
|
||||||
"time": "2023-12-16T09:41:14+00:00"
|
"time": "2023-08-21T03:20:52+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/clock",
|
"name": "psr/clock",
|
||||||
@@ -1232,21 +1175,20 @@
|
|||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Roave/SecurityAdvisories.git",
|
"url": "https://github.com/Roave/SecurityAdvisories.git",
|
||||||
"reference": "3c2385497f806decca1e5abeba3cb8fd7caba4e0"
|
"reference": "6488b89b30eb204b9f78b3db4c2916914afa7445"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3c2385497f806decca1e5abeba3cb8fd7caba4e0",
|
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/6488b89b30eb204b9f78b3db4c2916914afa7445",
|
||||||
"reference": "3c2385497f806decca1e5abeba3cb8fd7caba4e0",
|
"reference": "6488b89b30eb204b9f78b3db4c2916914afa7445",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"3f/pygmentize": "<1.2",
|
"3f/pygmentize": "<1.2",
|
||||||
"admidio/admidio": "<4.2.13",
|
"admidio/admidio": "<4.2.10",
|
||||||
"adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3",
|
"adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3",
|
||||||
"aheinze/cockpit": "<2.2",
|
"aheinze/cockpit": "<=2.2.1",
|
||||||
"aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5",
|
"aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5",
|
||||||
"airesvsg/acf-to-rest-api": "<=3.1",
|
|
||||||
"akaunting/akaunting": "<2.1.13",
|
"akaunting/akaunting": "<2.1.13",
|
||||||
"akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53",
|
"akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53",
|
||||||
"alextselegidis/easyappointments": "<1.5",
|
"alextselegidis/easyappointments": "<1.5",
|
||||||
@@ -1258,34 +1200,30 @@
|
|||||||
"anchorcms/anchor-cms": "<=0.12.7",
|
"anchorcms/anchor-cms": "<=0.12.7",
|
||||||
"andreapollastri/cipi": "<=3.1.15",
|
"andreapollastri/cipi": "<=3.1.15",
|
||||||
"andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5",
|
"andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5",
|
||||||
"apache-solr-for-typo3/solr": "<2.8.3",
|
|
||||||
"apereo/phpcas": "<1.6",
|
"apereo/phpcas": "<1.6",
|
||||||
"api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6|>=2.6,<2.7.10|>=3,<3.0.12|>=3.1,<3.1.3",
|
"api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6|>=2.6,<2.7.10|>=3,<3.0.12|>=3.1,<3.1.3",
|
||||||
"appwrite/server-ce": "<=1.2.1",
|
"appwrite/server-ce": "<=1.2.1",
|
||||||
"arc/web": "<3",
|
"arc/web": "<3",
|
||||||
"area17/twill": "<1.2.5|>=2,<2.5.3",
|
"area17/twill": "<1.2.5|>=2,<2.5.3",
|
||||||
"artesaos/seotools": "<0.17.2",
|
"artesaos/seotools": "<0.17.2",
|
||||||
"asymmetricrypt/asymmetricrypt": "<9.9.99",
|
"asymmetricrypt/asymmetricrypt": ">=0,<9.9.99",
|
||||||
"athlon1600/php-proxy": "<=5.1",
|
"athlon1600/php-proxy": "<=5.1",
|
||||||
"athlon1600/php-proxy-app": "<=3",
|
"athlon1600/php-proxy-app": "<=3",
|
||||||
"austintoddj/canvas": "<=3.4.2",
|
|
||||||
"automad/automad": "<1.8",
|
"automad/automad": "<1.8",
|
||||||
"awesome-support/awesome-support": "<=6.0.7",
|
"awesome-support/awesome-support": "<=6.0.7",
|
||||||
"aws/aws-sdk-php": ">=3,<3.2.1",
|
"aws/aws-sdk-php": ">=3,<3.2.1",
|
||||||
"azuracast/azuracast": "<0.18.3",
|
"azuracast/azuracast": "<0.18.3",
|
||||||
"backdrop/backdrop": "<1.24.2",
|
"backdrop/backdrop": "<1.24.2",
|
||||||
"backpack/crud": "<3.4.9",
|
|
||||||
"bacula-web/bacula-web": "<8.0.0.0-RC2-dev",
|
|
||||||
"badaso/core": "<2.7",
|
"badaso/core": "<2.7",
|
||||||
"bagisto/bagisto": "<0.1.5",
|
"bagisto/bagisto": "<0.1.5",
|
||||||
"barrelstrength/sprout-base-email": "<1.2.7",
|
"barrelstrength/sprout-base-email": "<1.2.7",
|
||||||
"barrelstrength/sprout-forms": "<3.9",
|
"barrelstrength/sprout-forms": "<3.9",
|
||||||
"barryvdh/laravel-translation-manager": "<0.6.2",
|
"barryvdh/laravel-translation-manager": "<0.6.2",
|
||||||
"barzahlen/barzahlen-php": "<2.0.1",
|
"barzahlen/barzahlen-php": "<2.0.1",
|
||||||
"baserproject/basercms": "<4.8",
|
"baserproject/basercms": "<4.7.5",
|
||||||
"bassjobsen/bootstrap-3-typeahead": ">4.0.2",
|
"bassjobsen/bootstrap-3-typeahead": ">4.0.2",
|
||||||
"bigfork/silverstripe-form-capture": ">=3,<3.1.1",
|
"bigfork/silverstripe-form-capture": ">=3,<3.1.1",
|
||||||
"billz/raspap-webgui": "<2.9.5",
|
"billz/raspap-webgui": "<2.8.9",
|
||||||
"bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3",
|
"bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3",
|
||||||
"bmarshall511/wordpress_zero_spam": "<5.2.13",
|
"bmarshall511/wordpress_zero_spam": "<5.2.13",
|
||||||
"bolt/bolt": "<3.7.2",
|
"bolt/bolt": "<3.7.2",
|
||||||
@@ -1296,100 +1234,91 @@
|
|||||||
"brotkrueml/schema": "<1.13.1|>=2,<2.5.1",
|
"brotkrueml/schema": "<1.13.1|>=2,<2.5.1",
|
||||||
"brotkrueml/typo3-matomo-integration": "<1.3.2",
|
"brotkrueml/typo3-matomo-integration": "<1.3.2",
|
||||||
"buddypress/buddypress": "<7.2.1",
|
"buddypress/buddypress": "<7.2.1",
|
||||||
"bugsnag/bugsnag-laravel": "<2.0.2",
|
"bugsnag/bugsnag-laravel": ">=2,<2.0.2",
|
||||||
"bytefury/crater": "<6.0.2",
|
"bytefury/crater": "<6.0.2",
|
||||||
"cachethq/cachet": "<2.5.1",
|
"cachethq/cachet": "<2.5.1",
|
||||||
"cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10",
|
"cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10|= 1.3.7|>=4.1,<4.1.4",
|
||||||
"cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10",
|
"cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10",
|
||||||
"cardgate/magento2": "<2.0.33",
|
"cardgate/magento2": "<2.0.33",
|
||||||
"cardgate/woocommerce": "<=3.1.15",
|
"cardgate/woocommerce": "<=3.1.15",
|
||||||
"cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4",
|
"cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4",
|
||||||
"cartalyst/sentry": "<=2.1.6",
|
"cartalyst/sentry": "<=2.1.6",
|
||||||
"catfan/medoo": "<1.7.5",
|
"catfan/medoo": "<1.7.5",
|
||||||
"cecil/cecil": "<7.47.1",
|
"centreon/centreon": "<22.10-beta.1",
|
||||||
"centreon/centreon": "<22.10.0.0-beta1",
|
|
||||||
"cesnet/simplesamlphp-module-proxystatistics": "<3.1",
|
"cesnet/simplesamlphp-module-proxystatistics": "<3.1",
|
||||||
"chriskacerguis/codeigniter-restserver": "<=2.7.1",
|
"cockpit-hq/cockpit": "<2.4.1",
|
||||||
"civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3",
|
|
||||||
"cockpit-hq/cockpit": "<=2.6.3",
|
|
||||||
"codeception/codeception": "<3.1.3|>=4,<4.1.22",
|
"codeception/codeception": "<3.1.3|>=4,<4.1.22",
|
||||||
"codeigniter/framework": "<3.1.9",
|
"codeigniter/framework": "<=3.0.6",
|
||||||
"codeigniter4/framework": "<=4.4.2",
|
"codeigniter4/framework": "<4.3.5",
|
||||||
"codeigniter4/shield": "<1.0.0.0-beta8",
|
"codeigniter4/shield": "<1-beta.4|= 1.0.0-beta",
|
||||||
"codiad/codiad": "<=2.8.4",
|
"codiad/codiad": "<=2.8.4",
|
||||||
"composer/composer": "<1.10.27|>=2,<2.2.22|>=2.3,<2.6.4",
|
"composer/composer": "<1.10.26|>=2-alpha.1,<2.2.12|>=2.3,<2.3.5",
|
||||||
"concrete5/concrete5": "<9.2.2",
|
"concrete5/concrete5": "<9.2|>= 9.0.0RC1, < 9.1.3",
|
||||||
"concrete5/core": "<8.5.8|>=9,<9.1",
|
"concrete5/core": "<8.5.8|>=9,<9.1",
|
||||||
"contao-components/mediaelement": ">=2.14.2,<2.21.1",
|
"contao-components/mediaelement": ">=2.14.2,<2.21.1",
|
||||||
"contao/contao": ">=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4",
|
"contao/contao": ">=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4",
|
||||||
"contao/core": ">=2,<3.5.39",
|
"contao/core": ">=2,<3.5.39",
|
||||||
"contao/core-bundle": "<4.9.42|>=4.10,<4.13.28|>=5,<5.1.10",
|
"contao/core-bundle": "<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4|= 4.10.0",
|
||||||
"contao/listing-bundle": ">=4,<4.4.8",
|
"contao/listing-bundle": ">=4,<4.4.8",
|
||||||
"contao/managed-edition": "<=1.5",
|
"contao/managed-edition": "<=1.5",
|
||||||
"cosenary/instagram": "<=2.3",
|
"cosenary/instagram": "<=2.3",
|
||||||
"craftcms/cms": "<=4.4.14",
|
"craftcms/cms": "<=4.4.9|>= 4.0.0-RC1, < 4.4.12|>= 4.0.0-RC1, <= 4.4.5|>= 4.0.0-RC1, <= 4.4.6|>= 4.0.0-RC1, < 4.4.6|>= 4.0.0-RC1, < 4.3.7|>= 4.0.0-RC1, < 4.2.1",
|
||||||
"croogo/croogo": "<4",
|
"croogo/croogo": "<3.0.7",
|
||||||
"cuyz/valinor": "<0.12",
|
"cuyz/valinor": "<0.12",
|
||||||
"czproject/git-php": "<4.0.3",
|
"czproject/git-php": "<4.0.3",
|
||||||
"darylldoyle/safe-svg": "<1.9.10",
|
"darylldoyle/safe-svg": "<1.9.10",
|
||||||
"datadog/dd-trace": ">=0.30,<0.30.2",
|
"datadog/dd-trace": ">=0.30,<0.30.2",
|
||||||
"datatables/datatables": "<1.10.10",
|
|
||||||
"david-garcia/phpwhois": "<=4.3.1",
|
"david-garcia/phpwhois": "<=4.3.1",
|
||||||
"dbrisinajumi/d2files": "<1",
|
"dbrisinajumi/d2files": "<1",
|
||||||
"dcat/laravel-admin": "<=2.1.3.0-beta",
|
"dcat/laravel-admin": "<=2.1.3-beta",
|
||||||
"derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3",
|
"derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3",
|
||||||
"derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1",
|
"derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1",
|
||||||
"desperado/xml-bundle": "<=0.1.7",
|
"desperado/xml-bundle": "<=0.1.7",
|
||||||
"directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2",
|
"directmailteam/direct-mail": "<5.2.4",
|
||||||
"doctrine/annotations": "<1.2.7",
|
"doctrine/annotations": ">=1,<1.2.7",
|
||||||
"doctrine/cache": "<1.3.2|>=1.4,<1.4.2",
|
"doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2",
|
||||||
"doctrine/common": "<2.4.3|>=2.5,<2.5.1",
|
"doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1",
|
||||||
"doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4",
|
"doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4",
|
||||||
"doctrine/doctrine-bundle": "<1.5.2",
|
"doctrine/doctrine-bundle": "<1.5.2",
|
||||||
"doctrine/doctrine-module": "<=0.7.1",
|
"doctrine/doctrine-module": "<=0.7.1",
|
||||||
"doctrine/mongodb-odm": "<1.0.2",
|
"doctrine/mongodb-odm": ">=1,<1.0.2",
|
||||||
"doctrine/mongodb-odm-bundle": "<3.0.1",
|
"doctrine/mongodb-odm-bundle": ">=2,<3.0.1",
|
||||||
"doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4",
|
"doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4",
|
||||||
"dolibarr/dolibarr": "<18.0.2",
|
"dolibarr/dolibarr": "<17.0.1|= 12.0.5|>= 3.3.beta1, < 13.0.2",
|
||||||
"dompdf/dompdf": "<2.0.4",
|
"dompdf/dompdf": "<2.0.2|= 2.0.2",
|
||||||
"doublethreedigital/guest-entries": "<3.1.2",
|
"drupal/core": ">=7,<7.96|>=8,<9.4.14|>=9.5,<9.5.8|>=10,<10.0.8",
|
||||||
"drupal/core": "<9.4.14|>=9.5,<9.5.8|>=10,<10.0.8",
|
"drupal/drupal": ">=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4",
|
||||||
"drupal/drupal": ">=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4",
|
|
||||||
"duncanmcclean/guest-entries": "<3.1.2",
|
|
||||||
"dweeves/magmi": "<=0.7.24",
|
"dweeves/magmi": "<=0.7.24",
|
||||||
"ecodev/newsletter": "<=4",
|
"ecodev/newsletter": "<=4",
|
||||||
"ectouch/ectouch": "<=2.7.2",
|
"ectouch/ectouch": "<=2.7.2",
|
||||||
"elefant/cms": "<2.0.7",
|
"elefant/cms": "<1.3.13",
|
||||||
"elgg/elgg": "<3.3.24|>=4,<4.0.5",
|
"elgg/elgg": "<3.3.24|>=4,<4.0.5",
|
||||||
"elijaa/phpmemcacheadmin": "<=1.3",
|
|
||||||
"encore/laravel-admin": "<=1.8.19",
|
"encore/laravel-admin": "<=1.8.19",
|
||||||
"endroid/qr-code-bundle": "<3.4.2",
|
"endroid/qr-code-bundle": "<3.4.2",
|
||||||
"enshrined/svg-sanitize": "<0.15",
|
"enshrined/svg-sanitize": "<0.15",
|
||||||
"erusev/parsedown": "<1.7.2",
|
"erusev/parsedown": "<1.7.2",
|
||||||
"ether/logs": "<3.0.4",
|
"ether/logs": "<3.0.4",
|
||||||
"evolutioncms/evolution": "<=3.2.3",
|
|
||||||
"exceedone/exment": "<4.4.3|>=5,<5.0.3",
|
"exceedone/exment": "<4.4.3|>=5,<5.0.3",
|
||||||
"exceedone/laravel-admin": "<2.2.3|==3",
|
"exceedone/laravel-admin": "= 3.0.0|<2.2.3",
|
||||||
"ezsystems/demobundle": ">=5.4,<5.4.6.1-dev",
|
"ezsystems/demobundle": ">=5.4,<5.4.6.1",
|
||||||
"ezsystems/ez-support-tools": ">=2.2,<2.2.3",
|
"ezsystems/ez-support-tools": ">=2.2,<2.2.3",
|
||||||
"ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1-dev",
|
"ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1",
|
||||||
"ezsystems/ezfind-ls": ">=5.3,<5.3.6.1-dev|>=5.4,<5.4.11.1-dev|>=2017.12,<2017.12.0.1-dev",
|
"ezsystems/ezfind-ls": ">=5.3,<5.3.6.1|>=5.4,<5.4.11.1|>=2017.12,<2017.12.0.1",
|
||||||
"ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24",
|
"ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24",
|
||||||
"ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26",
|
"ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26",
|
||||||
"ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1",
|
"ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1",
|
||||||
"ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12",
|
"ezsystems/ezplatform-graphql": ">=1-rc.1,<1.0.13|>=2-beta.1,<2.3.12",
|
||||||
"ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.34",
|
"ezsystems/ezplatform-kernel": "<1.2.5.1|>=1.3,<1.3.26",
|
||||||
"ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8",
|
"ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8",
|
||||||
"ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev",
|
"ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1",
|
||||||
"ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15",
|
|
||||||
"ezsystems/ezplatform-user": ">=1,<1.0.1",
|
"ezsystems/ezplatform-user": ">=1,<1.0.1",
|
||||||
"ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31",
|
"ezsystems/ezpublish-kernel": "<6.13.8.2|>=7,<7.5.30",
|
||||||
"ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.06,<=2019.03.5.1",
|
"ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.3.5.1",
|
||||||
"ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3",
|
"ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3",
|
||||||
"ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15",
|
"ezsystems/repository-forms": ">=2.3,<2.3.2.1|>=2.5,<2.5.15",
|
||||||
"ezyang/htmlpurifier": "<4.1.1",
|
"ezyang/htmlpurifier": "<4.1.1",
|
||||||
"facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2",
|
"facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2",
|
||||||
"facturascripts/facturascripts": "<=2022.08",
|
"facturascripts/facturascripts": "<=2022.8",
|
||||||
"feehi/cms": "<=2.1.1",
|
"feehi/cms": "<=2.1.1",
|
||||||
"feehi/feehicms": "<=2.1.1",
|
"feehi/feehicms": "<=2.1.1",
|
||||||
"fenom/fenom": "<=2.12.1",
|
"fenom/fenom": "<=2.12.1",
|
||||||
@@ -1397,16 +1326,13 @@
|
|||||||
"firebase/php-jwt": "<6",
|
"firebase/php-jwt": "<6",
|
||||||
"fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2",
|
"fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2",
|
||||||
"fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6",
|
"fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6",
|
||||||
"flarum/core": "<1.8",
|
"flarum/core": "<1.7",
|
||||||
"flarum/framework": "<1.8",
|
|
||||||
"flarum/mentions": "<1.6.3",
|
"flarum/mentions": "<1.6.3",
|
||||||
"flarum/sticky": ">=0.1.0.0-beta14,<=0.1.0.0-beta15",
|
"flarum/sticky": ">=0.1-beta.14,<=0.1-beta.15",
|
||||||
"flarum/tags": "<=0.1.0.0-beta13",
|
"flarum/tags": "<=0.1-beta.13",
|
||||||
"floriangaerber/magnesium": "<0.3.1",
|
|
||||||
"fluidtypo3/vhs": "<5.1.1",
|
"fluidtypo3/vhs": "<5.1.1",
|
||||||
"fof/byobu": ">=0.3.0.0-beta2,<1.1.7",
|
"fof/byobu": ">=0.3-beta.2,<1.1.7",
|
||||||
"fof/upload": "<1.2.3",
|
"fof/upload": "<1.2.3",
|
||||||
"foodcoopshop/foodcoopshop": ">=3.2,<3.6.1",
|
|
||||||
"fooman/tcpdf": "<6.2.22",
|
"fooman/tcpdf": "<6.2.22",
|
||||||
"forkcms/forkcms": "<5.11.1",
|
"forkcms/forkcms": "<5.11.1",
|
||||||
"fossar/tcpdf-parser": "<6.2.22",
|
"fossar/tcpdf-parser": "<6.2.22",
|
||||||
@@ -1416,20 +1342,17 @@
|
|||||||
"friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
|
"friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
|
||||||
"friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
|
"friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
|
||||||
"friendsoftypo3/mediace": ">=7.6.2,<7.6.5",
|
"friendsoftypo3/mediace": ">=7.6.2,<7.6.5",
|
||||||
"friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6",
|
"froala/wysiwyg-editor": "<3.2.7",
|
||||||
"froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.1",
|
"froxlor/froxlor": "<2.1",
|
||||||
"froxlor/froxlor": "<2.1.0.0-beta1",
|
|
||||||
"fuel/core": "<1.8.1",
|
"fuel/core": "<1.8.1",
|
||||||
"funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3",
|
"funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3",
|
||||||
"gaoming13/wechat-php-sdk": "<=1.10.2",
|
"gaoming13/wechat-php-sdk": "<=1.10.2",
|
||||||
"genix/cms": "<=1.1.11",
|
"genix/cms": "<=1.1.11",
|
||||||
"getgrav/grav": "<=1.7.42.1",
|
"getgrav/grav": "<1.7.42",
|
||||||
"getkirby/cms": "<3.5.8.3-dev|>=3.6,<3.6.6.3-dev|>=3.7,<3.7.5.2-dev|>=3.8,<3.8.4.1-dev|>=3.9,<3.9.6",
|
"getkirby/cms": "= 3.8.0|<3.5.8.2|>=3.6,<3.6.6.2|>=3.7,<3.7.5.1",
|
||||||
"getkirby/kirby": "<=2.5.12",
|
|
||||||
"getkirby/panel": "<2.5.14",
|
"getkirby/panel": "<2.5.14",
|
||||||
"getkirby/starterkit": "<=3.7.0.2",
|
"getkirby/starterkit": "<=3.7.0.2",
|
||||||
"gilacms/gila": "<=1.11.4",
|
"gilacms/gila": "<=1.11.4",
|
||||||
"gleez/cms": "<=1.2|==2",
|
|
||||||
"globalpayments/php-sdk": "<2",
|
"globalpayments/php-sdk": "<2",
|
||||||
"gogentooss/samlbase": "<1.2.7",
|
"gogentooss/samlbase": "<1.2.7",
|
||||||
"google/protobuf": "<3.15",
|
"google/protobuf": "<3.15",
|
||||||
@@ -1437,12 +1360,11 @@
|
|||||||
"gree/jose": "<2.2.1",
|
"gree/jose": "<2.2.1",
|
||||||
"gregwar/rst": "<1.0.3",
|
"gregwar/rst": "<1.0.3",
|
||||||
"grumpydictator/firefly-iii": "<6",
|
"grumpydictator/firefly-iii": "<6",
|
||||||
"gugoan/economizzer": "<=0.9.0.0-beta1",
|
|
||||||
"guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5",
|
"guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5",
|
||||||
"guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5",
|
"guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5",
|
||||||
"haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2",
|
"haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2",
|
||||||
"harvesthq/chosen": "<1.8.7",
|
"harvesthq/chosen": "<1.8.7",
|
||||||
"helloxz/imgurl": "<=2.31",
|
"helloxz/imgurl": "= 2.31|<=2.31",
|
||||||
"hhxsv5/laravel-s": "<3.7.36",
|
"hhxsv5/laravel-s": "<3.7.36",
|
||||||
"hillelcoren/invoice-ninja": "<5.3.35",
|
"hillelcoren/invoice-ninja": "<5.3.35",
|
||||||
"himiklab/yii2-jqgrid-widget": "<1.0.8",
|
"himiklab/yii2-jqgrid-widget": "<1.0.8",
|
||||||
@@ -1451,10 +1373,9 @@
|
|||||||
"httpsoft/http-message": "<1.0.12",
|
"httpsoft/http-message": "<1.0.12",
|
||||||
"hyn/multi-tenant": ">=5.6,<5.7.2",
|
"hyn/multi-tenant": ">=5.6,<5.7.2",
|
||||||
"ibexa/admin-ui": ">=4.2,<4.2.3",
|
"ibexa/admin-ui": ">=4.2,<4.2.3",
|
||||||
"ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.4",
|
"ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3",
|
||||||
"ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3",
|
"ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3",
|
||||||
"ibexa/post-install": "<=1.0.4",
|
"ibexa/post-install": "<=1.0.4",
|
||||||
"ibexa/solr": ">=4.5,<4.5.4",
|
|
||||||
"ibexa/user": ">=4,<4.4.3",
|
"ibexa/user": ">=4,<4.4.3",
|
||||||
"icecoder/icecoder": "<=8.1",
|
"icecoder/icecoder": "<=8.1",
|
||||||
"idno/known": "<=1.3.1",
|
"idno/known": "<=1.3.1",
|
||||||
@@ -1464,25 +1385,21 @@
|
|||||||
"illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15",
|
"illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15",
|
||||||
"illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75",
|
"illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75",
|
||||||
"impresscms/impresscms": "<=1.4.5",
|
"impresscms/impresscms": "<=1.4.5",
|
||||||
"in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3",
|
"in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.1",
|
||||||
"in2code/ipandlanguageredirect": "<5.1.2",
|
"in2code/ipandlanguageredirect": "<5.1.2",
|
||||||
"in2code/lux": "<17.6.1|>=18,<24.0.2",
|
"in2code/lux": "<17.6.1|>=18,<24.0.2",
|
||||||
"innologi/typo3-appointments": "<2.0.6",
|
"innologi/typo3-appointments": "<2.0.6",
|
||||||
"intelliants/subrion": "<4.2.2",
|
"intelliants/subrion": "<=4.2.1",
|
||||||
"islandora/islandora": ">=2,<2.4.1",
|
"islandora/islandora": ">=2,<2.4.1",
|
||||||
"ivankristianto/phpwhois": "<=4.3",
|
"ivankristianto/phpwhois": "<=4.3",
|
||||||
"jackalope/jackalope-doctrine-dbal": "<1.7.4",
|
"jackalope/jackalope-doctrine-dbal": "<1.7.4",
|
||||||
"james-heinrich/getid3": "<1.9.21",
|
"james-heinrich/getid3": "<1.9.21",
|
||||||
"james-heinrich/phpthumb": "<1.7.12",
|
|
||||||
"jasig/phpcas": "<1.3.3",
|
"jasig/phpcas": "<1.3.3",
|
||||||
"jcbrand/converse.js": "<3.3.3",
|
|
||||||
"joomla/application": "<1.0.13",
|
|
||||||
"joomla/archive": "<1.1.12|>=2,<2.0.1",
|
"joomla/archive": "<1.1.12|>=2,<2.0.1",
|
||||||
"joomla/filesystem": "<1.6.2|>=2,<2.0.1",
|
"joomla/filesystem": "<1.6.2|>=2,<2.0.1",
|
||||||
"joomla/filter": "<1.4.4|>=2,<2.0.1",
|
"joomla/filter": "<1.4.4|>=2,<2.0.1",
|
||||||
"joomla/framework": ">=2.5.4,<=3.8.12",
|
|
||||||
"joomla/input": ">=2,<2.0.2",
|
"joomla/input": ">=2,<2.0.2",
|
||||||
"joomla/joomla-cms": ">=2.5,<3.9.12",
|
"joomla/joomla-cms": ">=3,<3.9.12",
|
||||||
"joomla/session": "<1.3.1",
|
"joomla/session": "<1.3.1",
|
||||||
"joyqi/hyper-down": "<=2.4.27",
|
"joyqi/hyper-down": "<=2.4.27",
|
||||||
"jsdecena/laracom": "<2.0.9",
|
"jsdecena/laracom": "<2.0.9",
|
||||||
@@ -1491,28 +1408,27 @@
|
|||||||
"kelvinmo/simplexrd": "<3.1.1",
|
"kelvinmo/simplexrd": "<3.1.1",
|
||||||
"kevinpapst/kimai2": "<1.16.7",
|
"kevinpapst/kimai2": "<1.16.7",
|
||||||
"khodakhah/nodcms": "<=3",
|
"khodakhah/nodcms": "<=3",
|
||||||
"kimai/kimai": "<=2.1",
|
"kimai/kimai": "<1.1",
|
||||||
"kitodo/presentation": "<3.2.3|>=3.3,<3.3.4",
|
"kitodo/presentation": "<3.2.3|>=3.3,<3.3.4",
|
||||||
"klaviyo/magento2-extension": ">=1,<3",
|
"klaviyo/magento2-extension": ">=1,<3",
|
||||||
"knplabs/knp-snappy": "<=1.4.2",
|
"knplabs/knp-snappy": "<1.4.2",
|
||||||
"kohana/core": "<3.3.3",
|
|
||||||
"krayin/laravel-crm": "<1.2.2",
|
"krayin/laravel-crm": "<1.2.2",
|
||||||
"kreait/firebase-php": ">=3.2,<3.8.1",
|
"kreait/firebase-php": ">=3.2,<3.8.1",
|
||||||
"la-haute-societe/tcpdf": "<6.2.22",
|
"la-haute-societe/tcpdf": "<6.2.22",
|
||||||
"laminas/laminas-diactoros": "<2.18.1|==2.19|==2.20|==2.21|==2.22|==2.23|>=2.24,<2.24.2|>=2.25,<2.25.2",
|
"laminas/laminas-diactoros": "<2.18.1|>=2.24,<2.24.2|>=2.25,<2.25.2|= 2.23.0|= 2.22.0|= 2.21.0|= 2.20.0|= 2.19.0",
|
||||||
"laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1",
|
"laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1",
|
||||||
"laminas/laminas-http": "<2.14.2",
|
"laminas/laminas-http": "<2.14.2",
|
||||||
"laravel/fortify": "<1.11.1",
|
"laravel/fortify": "<1.11.1",
|
||||||
"laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75",
|
"laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75",
|
||||||
"laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
|
"laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
|
||||||
"latte/latte": "<2.10.8",
|
"latte/latte": "<2.10.8",
|
||||||
"lavalite/cms": "<=9",
|
"lavalite/cms": "= 9.0.0|<=9",
|
||||||
"lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5",
|
"lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5",
|
||||||
"league/commonmark": "<0.18.3",
|
"league/commonmark": "<0.18.3",
|
||||||
"league/flysystem": "<1.1.4|>=2,<2.1.1",
|
"league/flysystem": "<1.1.4|>=2,<2.1.1",
|
||||||
"league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3",
|
"league/oauth2-server": ">=8.3.2,<8.5.3",
|
||||||
"lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3",
|
"lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3",
|
||||||
"librenms/librenms": "<2017.08.18",
|
"librenms/librenms": "<22.10",
|
||||||
"liftkit/database": "<2.13.2",
|
"liftkit/database": "<2.13.2",
|
||||||
"limesurvey/limesurvey": "<3.27.19",
|
"limesurvey/limesurvey": "<3.27.19",
|
||||||
"livehelperchat/livehelperchat": "<=3.91",
|
"livehelperchat/livehelperchat": "<=3.91",
|
||||||
@@ -1521,84 +1437,68 @@
|
|||||||
"localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2",
|
"localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2",
|
||||||
"luyadev/yii-helpers": "<1.2.1",
|
"luyadev/yii-helpers": "<1.2.1",
|
||||||
"magento/community-edition": "<=2.4",
|
"magento/community-edition": "<=2.4",
|
||||||
"magento/magento1ce": "<1.9.4.3-dev",
|
"magento/magento1ce": "<1.9.4.3",
|
||||||
"magento/magento1ee": ">=1,<1.14.4.3-dev",
|
"magento/magento1ee": ">=1,<1.14.4.3",
|
||||||
"magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2.0-patch2",
|
"magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2-p.2",
|
||||||
"maikuolan/phpmussel": ">=1,<1.6",
|
"maikuolan/phpmussel": ">=1,<1.6",
|
||||||
"mantisbt/mantisbt": "<=2.25.7",
|
"mantisbt/mantisbt": "<=2.25.5",
|
||||||
"marcwillmann/turn": "<0.3.3",
|
"marcwillmann/turn": "<0.3.3",
|
||||||
"matyhtf/framework": "<3.0.6",
|
"matyhtf/framework": "<3.0.6",
|
||||||
"mautic/core": "<4.3",
|
"mautic/core": "<4.3|= 2.13.1",
|
||||||
"mediawiki/core": ">=1.27,<1.27.6|>=1.29,<1.29.3|>=1.30,<1.30.2|>=1.31,<1.31.9|>=1.32,<1.32.6|>=1.32.99,<1.33.3|>=1.33.99,<1.34.3|>=1.34.99,<1.35",
|
"mediawiki/core": ">=1.27,<1.27.6|>=1.29,<1.29.3|>=1.30,<1.30.2|>=1.31,<1.31.9|>=1.32,<1.32.6|>=1.32.99,<1.33.3|>=1.33.99,<1.34.3|>=1.34.99,<1.35",
|
||||||
"mediawiki/matomo": "<2.4.3",
|
"mediawiki/matomo": "<2.4.3",
|
||||||
"mediawiki/semantic-media-wiki": "<4.0.2",
|
|
||||||
"melisplatform/melis-asset-manager": "<5.0.1",
|
"melisplatform/melis-asset-manager": "<5.0.1",
|
||||||
"melisplatform/melis-cms": "<5.0.1",
|
"melisplatform/melis-cms": "<5.0.1",
|
||||||
"melisplatform/melis-front": "<5.0.1",
|
"melisplatform/melis-front": "<5.0.1",
|
||||||
"mezzio/mezzio-swoole": "<3.7|>=4,<4.3",
|
"mezzio/mezzio-swoole": "<3.7|>=4,<4.3",
|
||||||
"mgallegos/laravel-jqgrid": "<=1.3",
|
"mgallegos/laravel-jqgrid": "<=1.3",
|
||||||
"microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2.0.0.0-RC1-dev,<2.0.1",
|
"microweber/microweber": "= 1.1.18|<=1.3.4",
|
||||||
"microsoft/microsoft-graph-beta": "<2.0.1",
|
|
||||||
"microsoft/microsoft-graph-core": "<2.0.2",
|
|
||||||
"microweber/microweber": "<=2.0.4",
|
|
||||||
"miniorange/miniorange-saml": "<1.4.3",
|
"miniorange/miniorange-saml": "<1.4.3",
|
||||||
"mittwald/typo3_forum": "<1.2.1",
|
"mittwald/typo3_forum": "<1.2.1",
|
||||||
"mobiledetect/mobiledetectlib": "<2.8.32",
|
"mobiledetect/mobiledetectlib": "<2.8.32",
|
||||||
"modx/revolution": "<=2.8.3.0-patch",
|
"modx/revolution": "<= 2.8.3-pl|<2.8",
|
||||||
"mojo42/jirafeau": "<4.4",
|
"mojo42/jirafeau": "<4.4",
|
||||||
"mongodb/mongodb": ">=1,<1.9.2",
|
|
||||||
"monolog/monolog": ">=1.8,<1.12",
|
"monolog/monolog": ">=1.8,<1.12",
|
||||||
"moodle/moodle": "<4.3.0.0-RC2-dev",
|
"moodle/moodle": "<4.2-rc.2|= 3.7|= 3.9|= 3.8|= 4.2.0|= 3.11",
|
||||||
"mos/cimage": "<0.7.19",
|
|
||||||
"movim/moxl": ">=0.8,<=0.10",
|
"movim/moxl": ">=0.8,<=0.10",
|
||||||
"mpdf/mpdf": "<=7.1.7",
|
"mpdf/mpdf": "<=7.1.7",
|
||||||
"munkireport/comment": "<4.1",
|
|
||||||
"munkireport/managedinstalls": "<2.6",
|
|
||||||
"munkireport/munkireport": ">=2.5.3,<5.6.3",
|
|
||||||
"mustache/mustache": ">=2,<2.14.1",
|
"mustache/mustache": ">=2,<2.14.1",
|
||||||
"namshi/jose": "<2.2",
|
"namshi/jose": "<2.2",
|
||||||
"neoan3-apps/template": "<1.1.1",
|
"neoan3-apps/template": "<1.1.1",
|
||||||
"neorazorx/facturascripts": "<2022.04",
|
"neorazorx/facturascripts": "<2022.4",
|
||||||
"neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
|
"neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
|
||||||
"neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3",
|
"neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3",
|
||||||
"neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2",
|
"neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2",
|
||||||
"neos/neos-ui": "<=8.3.3",
|
|
||||||
"neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5",
|
"neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5",
|
||||||
"netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15",
|
"netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15",
|
||||||
"nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6",
|
"nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6",
|
||||||
"nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13",
|
"nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13",
|
||||||
"nilsteampassnet/teampass": "<3.0.10",
|
"nilsteampassnet/teampass": "<3.0.10",
|
||||||
"nonfiction/nterchange": "<4.1.1",
|
|
||||||
"notrinos/notrinos-erp": "<=0.7",
|
"notrinos/notrinos-erp": "<=0.7",
|
||||||
"noumo/easyii": "<=0.9",
|
"noumo/easyii": "<=0.9",
|
||||||
"nukeviet/nukeviet": "<4.5.02",
|
"nukeviet/nukeviet": "<4.5.2",
|
||||||
"nyholm/psr7": "<1.6.1",
|
"nyholm/psr7": "<1.6.1",
|
||||||
"nystudio107/craft-seomatic": "<3.4.12",
|
"nystudio107/craft-seomatic": "<3.4.12",
|
||||||
"nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1",
|
"nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1",
|
||||||
"october/backend": "<1.1.2",
|
"october/backend": "<1.1.2",
|
||||||
"october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1",
|
"october/cms": "= 1.1.1|= 1.0.471|= 1.0.469|>=1.0.319,<1.0.469",
|
||||||
"october/october": "<=3.4.4",
|
"october/october": ">=1.0.319,<1.0.466|>=2.1,<2.1.12",
|
||||||
"october/rain": "<1.0.472|>=1.1,<1.1.2",
|
"october/rain": "<1.0.472|>=1.1,<1.1.2",
|
||||||
"october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.2",
|
"october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.0.66",
|
||||||
"omeka/omeka-s": "<4.0.3",
|
|
||||||
"onelogin/php-saml": "<2.10.4",
|
"onelogin/php-saml": "<2.10.4",
|
||||||
"oneup/uploader-bundle": "<1.9.3|>=2,<2.1.5",
|
"oneup/uploader-bundle": "<1.9.3|>=2,<2.1.5",
|
||||||
"open-web-analytics/open-web-analytics": "<1.7.4",
|
"open-web-analytics/open-web-analytics": "<1.7.4",
|
||||||
"opencart/opencart": "<=3.0.3.7|>=4,<4.0.2.3-dev",
|
"opencart/opencart": "<=3.0.3.7",
|
||||||
"openid/php-openid": "<2.3",
|
"openid/php-openid": "<2.3",
|
||||||
"openmage/magento-lts": "<20.2",
|
"openmage/magento-lts": "<19.4.22|>=20,<20.0.19",
|
||||||
"opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2",
|
"opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2",
|
||||||
"orchid/platform": ">=9,<9.4.4|>=14.0.0.0-alpha4,<14.5",
|
"orchid/platform": ">=9,<9.4.4|>=14-alpha.4,<14.5",
|
||||||
"oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1",
|
"oro/commerce": ">=4.1,<5.0.6",
|
||||||
"oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1",
|
|
||||||
"oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7",
|
"oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7",
|
||||||
"oro/crm-call-bundle": ">=4.2,<=4.2.5|>=5,<5.0.4|>=5.1,<5.1.1",
|
"oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<4.2.8",
|
||||||
"oro/customer-portal": ">=4.2,<=4.2.8|>=5,<5.0.11|>=5.1,<5.1.1",
|
|
||||||
"oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<5.0.8",
|
|
||||||
"oxid-esales/oxideshop-ce": "<4.5",
|
|
||||||
"packbackbooks/lti-1-3-php-library": "<5",
|
"packbackbooks/lti-1-3-php-library": "<5",
|
||||||
"padraic/humbug_get_contents": "<1.1.2",
|
"padraic/humbug_get_contents": "<1.1.2",
|
||||||
"pagarme/pagarme-php": "<3",
|
"pagarme/pagarme-php": ">=0,<3",
|
||||||
"pagekit/pagekit": "<=1.0.18",
|
"pagekit/pagekit": "<=1.0.18",
|
||||||
"paragonie/random_compat": "<2",
|
"paragonie/random_compat": "<2",
|
||||||
"passbolt/passbolt_api": "<2.11",
|
"passbolt/passbolt_api": "<2.11",
|
||||||
@@ -1609,7 +1509,6 @@
|
|||||||
"pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1",
|
"pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1",
|
||||||
"personnummer/personnummer": "<3.0.2",
|
"personnummer/personnummer": "<3.0.2",
|
||||||
"phanan/koel": "<5.1.4",
|
"phanan/koel": "<5.1.4",
|
||||||
"phenx/php-svg-lib": "<0.5.1",
|
|
||||||
"php-mod/curl": "<2.3.2",
|
"php-mod/curl": "<2.3.2",
|
||||||
"phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1",
|
"phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1",
|
||||||
"phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7",
|
"phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7",
|
||||||
@@ -1619,7 +1518,7 @@
|
|||||||
"phpmyfaq/phpmyfaq": "<=3.1.7",
|
"phpmyfaq/phpmyfaq": "<=3.1.7",
|
||||||
"phpoffice/phpexcel": "<1.8",
|
"phpoffice/phpexcel": "<1.8",
|
||||||
"phpoffice/phpspreadsheet": "<1.16",
|
"phpoffice/phpspreadsheet": "<1.16",
|
||||||
"phpseclib/phpseclib": "<2.0.31|>=3,<3.0.34",
|
"phpseclib/phpseclib": "<2.0.31|>=3,<3.0.19",
|
||||||
"phpservermon/phpservermon": "<3.6",
|
"phpservermon/phpservermon": "<3.6",
|
||||||
"phpsysinfo/phpsysinfo": "<3.2.5",
|
"phpsysinfo/phpsysinfo": "<3.2.5",
|
||||||
"phpunit/phpunit": ">=4.8.19,<4.8.28|>=5,<5.6.3",
|
"phpunit/phpunit": ">=4.8.19,<4.8.28|>=5,<5.6.3",
|
||||||
@@ -1627,48 +1526,39 @@
|
|||||||
"phpxmlrpc/extras": "<0.6.1",
|
"phpxmlrpc/extras": "<0.6.1",
|
||||||
"phpxmlrpc/phpxmlrpc": "<4.9.2",
|
"phpxmlrpc/phpxmlrpc": "<4.9.2",
|
||||||
"pi/pi": "<=2.5",
|
"pi/pi": "<=2.5",
|
||||||
"pimcore/admin-ui-classic-bundle": "<1.2.2",
|
"pimcore/admin-ui-classic-bundle": "<1.0.3",
|
||||||
"pimcore/customer-management-framework-bundle": "<3.4.2",
|
"pimcore/customer-management-framework-bundle": "<3.4.1",
|
||||||
"pimcore/data-hub": "<1.2.4",
|
"pimcore/data-hub": "<1.2.4",
|
||||||
"pimcore/demo": "<10.3",
|
|
||||||
"pimcore/perspective-editor": "<1.5.1",
|
"pimcore/perspective-editor": "<1.5.1",
|
||||||
"pimcore/pimcore": "<11.1.1",
|
"pimcore/pimcore": "<10.5.24",
|
||||||
"pixelfed/pixelfed": "<=0.11.4",
|
"pixelfed/pixelfed": "<=0.11.4",
|
||||||
"pocketmine/bedrock-protocol": "<8.0.2",
|
"pocketmine/bedrock-protocol": "<8.0.2",
|
||||||
"pocketmine/pocketmine-mp": "<=4.23|>=5,<5.3.1",
|
"pocketmine/pocketmine-mp": "<4.22.3|>=5,<5.2.1|< 4.18.0-ALPHA2|>= 4.0.0-BETA5, < 4.4.2",
|
||||||
"pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1",
|
|
||||||
"pressbooks/pressbooks": "<5.18",
|
"pressbooks/pressbooks": "<5.18",
|
||||||
"prestashop/autoupgrade": ">=4,<4.10.1",
|
"prestashop/autoupgrade": ">=4,<4.10.1",
|
||||||
"prestashop/blockreassurance": "<=5.1.3",
|
|
||||||
"prestashop/blockwishlist": ">=2,<2.1.1",
|
"prestashop/blockwishlist": ">=2,<2.1.1",
|
||||||
"prestashop/contactform": ">=1.0.1,<4.3",
|
"prestashop/contactform": ">=1.0.1,<4.3",
|
||||||
"prestashop/gamification": "<2.3.2",
|
"prestashop/gamification": "<2.3.2",
|
||||||
"prestashop/prestashop": "<8.1.2",
|
"prestashop/prestashop": "<8.0.4",
|
||||||
"prestashop/productcomments": "<5.0.2",
|
"prestashop/productcomments": "<5.0.2",
|
||||||
"prestashop/ps_emailsubscription": "<2.6.1",
|
"prestashop/ps_emailsubscription": "<2.6.1",
|
||||||
"prestashop/ps_facetedsearch": "<3.4.1",
|
"prestashop/ps_facetedsearch": "<3.4.1",
|
||||||
"prestashop/ps_linklist": "<3.1",
|
"prestashop/ps_linklist": "<3.1",
|
||||||
"privatebin/privatebin": "<1.4",
|
"privatebin/privatebin": "<1.4",
|
||||||
"processwire/processwire": "<=3.0.200",
|
"processwire/processwire": "<=3.0.200",
|
||||||
"propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7",
|
"propel/propel": ">=2-alpha.1,<=2-alpha.7",
|
||||||
"propel/propel1": ">=1,<=1.7.1",
|
"propel/propel1": ">=1,<=1.7.1",
|
||||||
"pterodactyl/panel": "<1.7",
|
"pterodactyl/panel": "<1.7",
|
||||||
"ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2",
|
|
||||||
"ptrofimov/beanstalk_console": "<1.7.14",
|
"ptrofimov/beanstalk_console": "<1.7.14",
|
||||||
"pubnub/pubnub": "<6.1",
|
|
||||||
"pusher/pusher-php-server": "<2.2.1",
|
"pusher/pusher-php-server": "<2.2.1",
|
||||||
"pwweb/laravel-core": "<=0.3.6.0-beta",
|
"pwweb/laravel-core": "<=0.3.6-beta",
|
||||||
"pyrocms/pyrocms": "<=3.9.1",
|
"pyrocms/pyrocms": "<=3.9.1",
|
||||||
"rainlab/blog-plugin": "<1.4.1",
|
|
||||||
"rainlab/debugbar-plugin": "<3.1",
|
"rainlab/debugbar-plugin": "<3.1",
|
||||||
"rainlab/user-plugin": "<=1.4.5",
|
|
||||||
"rankmath/seo-by-rank-math": "<=1.0.95",
|
"rankmath/seo-by-rank-math": "<=1.0.95",
|
||||||
"rap2hpoutre/laravel-log-viewer": "<0.13",
|
"rap2hpoutre/laravel-log-viewer": "<0.13",
|
||||||
"react/http": ">=0.7,<1.9",
|
"react/http": ">=0.7,<1.9",
|
||||||
"really-simple-plugins/complianz-gdpr": "<6.4.2",
|
"really-simple-plugins/complianz-gdpr": "<6.4.2",
|
||||||
"remdex/livehelperchat": "<3.99",
|
"remdex/livehelperchat": "<3.99",
|
||||||
"reportico-web/reportico": "<=7.1.21",
|
|
||||||
"rhukster/dom-sanitizer": "<1.0.7",
|
|
||||||
"rmccue/requests": ">=1.6,<1.8",
|
"rmccue/requests": ">=1.6,<1.8",
|
||||||
"robrichards/xmlseclibs": "<3.0.4",
|
"robrichards/xmlseclibs": "<3.0.4",
|
||||||
"roots/soil": "<4.1",
|
"roots/soil": "<4.1",
|
||||||
@@ -1677,7 +1567,7 @@
|
|||||||
"s-cart/s-cart": "<6.9",
|
"s-cart/s-cart": "<6.9",
|
||||||
"sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1",
|
"sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1",
|
||||||
"sabre/dav": "<1.7.11|>=1.8,<1.8.9",
|
"sabre/dav": "<1.7.11|>=1.8,<1.8.9",
|
||||||
"scheb/two-factor-bundle": "<3.26|>=4,<4.11",
|
"scheb/two-factor-bundle": ">=0,<3.26|>=4,<4.11",
|
||||||
"sensiolabs/connect": "<4.2.3",
|
"sensiolabs/connect": "<4.2.3",
|
||||||
"serluck/phpwhois": "<=4.2.6",
|
"serluck/phpwhois": "<=4.2.6",
|
||||||
"sfroemken/url_redirect": "<=1.2.1",
|
"sfroemken/url_redirect": "<=1.2.1",
|
||||||
@@ -1690,15 +1580,14 @@
|
|||||||
"shopxo/shopxo": "<2.2.6",
|
"shopxo/shopxo": "<2.2.6",
|
||||||
"showdoc/showdoc": "<2.10.4",
|
"showdoc/showdoc": "<2.10.4",
|
||||||
"silverstripe-australia/advancedreports": ">=1,<=2",
|
"silverstripe-australia/advancedreports": ">=1,<=2",
|
||||||
"silverstripe/admin": "<1.13.6",
|
"silverstripe/admin": "<1.12.7",
|
||||||
"silverstripe/assets": ">=1,<1.11.1",
|
"silverstripe/assets": ">=1,<1.11.1",
|
||||||
"silverstripe/cms": "<4.11.3",
|
"silverstripe/cms": "<4.11.3",
|
||||||
"silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1",
|
"silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1",
|
||||||
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
|
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
|
||||||
"silverstripe/framework": "<4.13.14|>=5,<5.0.13",
|
"silverstripe/framework": "<4.12.5",
|
||||||
"silverstripe/graphql": "<3.8.2|>=4,<4.1.3|>=4.2,<4.2.5|>=4.3,<4.3.4|>=5,<5.0.3",
|
"silverstripe/graphql": "<3.5.2|>=4-alpha.1,<4-alpha.2|>=4.1.1,<4.1.2|>=4.2.2,<4.2.3|= 4.0.0-alpha1",
|
||||||
"silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1",
|
"silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1",
|
||||||
"silverstripe/recipe-cms": ">=4.5,<4.5.3",
|
|
||||||
"silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1",
|
"silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1",
|
||||||
"silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4",
|
"silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4",
|
||||||
"silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1",
|
"silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1",
|
||||||
@@ -1707,38 +1596,36 @@
|
|||||||
"silverstripe/userforms": "<3",
|
"silverstripe/userforms": "<3",
|
||||||
"silverstripe/versioned-admin": ">=1,<1.11.1",
|
"silverstripe/versioned-admin": ">=1,<1.11.1",
|
||||||
"simple-updates/phpwhois": "<=1",
|
"simple-updates/phpwhois": "<=1",
|
||||||
"simplesamlphp/saml2": "<1.15.4|>=2,<2.3.8|>=3,<3.1.4|==5.0.0.0-alpha12",
|
"simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4",
|
||||||
"simplesamlphp/simplesamlphp": "<1.18.6",
|
"simplesamlphp/simplesamlphp": "<1.18.6",
|
||||||
"simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
|
"simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
|
||||||
"simplesamlphp/simplesamlphp-module-openid": "<1",
|
"simplesamlphp/simplesamlphp-module-openid": "<1",
|
||||||
"simplesamlphp/simplesamlphp-module-openidprovider": "<0.9",
|
"simplesamlphp/simplesamlphp-module-openidprovider": "<0.9",
|
||||||
"simplesamlphp/xml-security": "==1.6.11",
|
|
||||||
"simplito/elliptic-php": "<1.0.6",
|
"simplito/elliptic-php": "<1.0.6",
|
||||||
"sitegeist/fluid-components": "<3.5",
|
"sitegeist/fluid-components": "<3.5",
|
||||||
"sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3",
|
"sjbr/sr-freecap": "<=2.5.2",
|
||||||
"slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1",
|
"slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1",
|
||||||
"slim/slim": "<2.6",
|
"slim/slim": "<2.6",
|
||||||
"slub/slub-events": "<3.0.3",
|
|
||||||
"smarty/smarty": "<3.1.48|>=4,<4.3.1",
|
"smarty/smarty": "<3.1.48|>=4,<4.3.1",
|
||||||
"snipe/snipe-it": "<=6.2.2",
|
"snipe/snipe-it": "<=6.0.14|>= 6.0.0-RC-1, <= 6.0.0-RC-5",
|
||||||
"socalnick/scn-social-auth": "<1.15.2",
|
"socalnick/scn-social-auth": "<1.15.2",
|
||||||
"socialiteproviders/steam": "<1.1",
|
"socialiteproviders/steam": "<1.1",
|
||||||
"spatie/browsershot": "<3.57.4",
|
"spatie/browsershot": "<3.57.4",
|
||||||
"spipu/html2pdf": "<5.2.8",
|
"spipu/html2pdf": "<5.2.4",
|
||||||
"spoon/library": "<1.4.1",
|
"spoon/library": "<1.4.1",
|
||||||
"spoonity/tcpdf": "<6.2.22",
|
"spoonity/tcpdf": "<6.2.22",
|
||||||
"squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
|
"squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
|
||||||
"ssddanbrown/bookstack": "<22.02.3",
|
"ssddanbrown/bookstack": "<22.2.3",
|
||||||
"statamic/cms": "<4.36",
|
"statamic/cms": "<4.10",
|
||||||
"stormpath/sdk": "<9.9.99",
|
"stormpath/sdk": ">=0,<9.9.99",
|
||||||
"studio-42/elfinder": "<2.1.62",
|
"studio-42/elfinder": "<2.1.62",
|
||||||
"subhh/libconnect": "<7.0.8|>=8,<8.1",
|
"subhh/libconnect": "<7.0.8|>=8,<8.1",
|
||||||
|
"subrion/cms": "<=4.2.1",
|
||||||
"sukohi/surpass": "<1",
|
"sukohi/surpass": "<1",
|
||||||
"sulu/sulu": "<1.6.44|>=2,<2.2.18|>=2.3,<2.3.8|==2.4.0.0-RC1|>=2.5,<2.5.10",
|
"sulu/sulu": "= 2.4.0-RC1|<1.6.44|>=2,<2.2.18|>=2.3,<2.3.8",
|
||||||
"sumocoders/framework-user-bundle": "<1.4",
|
"sumocoders/framework-user-bundle": "<1.4",
|
||||||
"swag/paypal": "<5.4.4",
|
"swag/paypal": "<5.4.4",
|
||||||
"swiftmailer/swiftmailer": ">=4,<5.4.5",
|
"swiftmailer/swiftmailer": ">=4,<5.4.5",
|
||||||
"swiftyedit/swiftyedit": "<1.2",
|
|
||||||
"sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2",
|
"sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2",
|
||||||
"sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1",
|
"sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1",
|
||||||
"sylius/grid-bundle": "<1.10.1",
|
"sylius/grid-bundle": "<1.10.1",
|
||||||
@@ -1754,7 +1641,7 @@
|
|||||||
"symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
|
"symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
|
||||||
"symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4",
|
"symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4",
|
||||||
"symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
|
"symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
|
||||||
"symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<=5.3.14|>=5.4.3,<=5.4.3|>=6.0.3,<=6.0.3",
|
"symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<=5.3.14|>=5.4.3,<=5.4.3|>=6.0.3,<=6.0.3|= 6.0.3|= 5.4.3|= 5.3.14",
|
||||||
"symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7",
|
"symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7",
|
||||||
"symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6",
|
"symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6",
|
||||||
"symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13",
|
"symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13",
|
||||||
@@ -1770,59 +1657,49 @@
|
|||||||
"symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9",
|
"symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9",
|
||||||
"symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11",
|
"symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11",
|
||||||
"symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8",
|
"symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8",
|
||||||
"symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2|>=5.4,<5.4.31|>=6,<6.3.8",
|
"symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2",
|
||||||
"symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12",
|
"symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12",
|
||||||
"symfony/symfony": "<4.4.51|>=5,<5.4.31|>=6,<6.3.8",
|
"symfony/symfony": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6",
|
||||||
"symfony/translation": ">=2,<2.0.17",
|
"symfony/translation": ">=2,<2.0.17",
|
||||||
"symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8",
|
|
||||||
"symfony/ux-autocomplete": "<2.11.2",
|
|
||||||
"symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3",
|
"symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3",
|
||||||
"symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8",
|
"symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8",
|
||||||
"symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
|
"symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
|
||||||
"symfony/webhook": ">=6.3,<6.3.8",
|
|
||||||
"symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
|
"symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
|
||||||
"symphonycms/symphony-2": "<2.6.4",
|
"t3/dce": ">=2.2,<2.6.2",
|
||||||
"t3/dce": "<0.11.5|>=2.2,<2.6.2",
|
|
||||||
"t3g/svg-sanitizer": "<1.0.3",
|
"t3g/svg-sanitizer": "<1.0.3",
|
||||||
"t3s/content-consent": "<1.0.3|>=2,<2.0.2",
|
|
||||||
"tastyigniter/tastyigniter": "<3.3",
|
"tastyigniter/tastyigniter": "<3.3",
|
||||||
"tcg/voyager": "<=1.4",
|
"tcg/voyager": "<=1.4",
|
||||||
"tecnickcom/tcpdf": "<6.2.22",
|
"tecnickcom/tcpdf": "<6.2.22",
|
||||||
"terminal42/contao-tablelookupwizard": "<3.3.5",
|
"terminal42/contao-tablelookupwizard": "<3.3.5",
|
||||||
"thelia/backoffice-default-template": ">=2.1,<2.1.2",
|
"thelia/backoffice-default-template": ">=2.1,<2.1.2",
|
||||||
"thelia/thelia": ">=2.1,<2.1.3",
|
"thelia/thelia": ">=2.1-beta.1,<2.1.3",
|
||||||
"theonedemon/phpwhois": "<=4.2.5",
|
"theonedemon/phpwhois": "<=4.2.5",
|
||||||
"thinkcmf/thinkcmf": "<=5.1.7",
|
"thinkcmf/thinkcmf": "<=5.1.7",
|
||||||
"thorsten/phpmyfaq": "<3.2.2",
|
"thorsten/phpmyfaq": "<3.2-beta.2",
|
||||||
"tikiwiki/tiki-manager": "<=17.1",
|
"tinymce/tinymce": "<5.10.7|>=6,<6.3.1",
|
||||||
"tinymce/tinymce": "<5.10.9|>=6,<6.7.3",
|
|
||||||
"tinymighty/wiki-seo": "<1.2.2",
|
"tinymighty/wiki-seo": "<1.2.2",
|
||||||
"titon/framework": "<9.9.99",
|
"titon/framework": ">=0,<9.9.99",
|
||||||
"tobiasbg/tablepress": "<=2.0.0.0-RC1",
|
"tobiasbg/tablepress": "<= 2.0-RC1",
|
||||||
"topthink/framework": "<6.0.14",
|
"topthink/framework": "<6.0.14",
|
||||||
"topthink/think": "<=6.1.1",
|
"topthink/think": "<=6.1.1",
|
||||||
"topthink/thinkphp": "<=3.2.3",
|
"topthink/thinkphp": "<=3.2.3",
|
||||||
"tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2",
|
"tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2",
|
||||||
"tribalsystems/zenario": "<=9.4.59197",
|
"tribalsystems/zenario": "<=9.3.57595",
|
||||||
"truckersmp/phpwhois": "<=4.3.1",
|
"truckersmp/phpwhois": "<=4.3.1",
|
||||||
"ttskch/pagination-service-provider": "<1",
|
"ttskch/pagination-service-provider": "<1",
|
||||||
"twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3",
|
"twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3",
|
||||||
"typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2",
|
"typo3/cms": "<2.0.5|>=3,<3.0.3|>=6.2,<=6.2.38|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2",
|
||||||
"typo3/cms-backend": ">=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
|
"typo3/cms-backend": ">=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
|
||||||
"typo3/cms-core": "<8.7.55|>=9,<9.5.44|>=10,<10.4.41|>=11,<11.5.33|>=12,<12.4.8",
|
"typo3/cms-core": "<8.7.51|>=9,<9.5.40|>=10,<10.4.36|>=11,<11.5.23|>=12,<12.2",
|
||||||
"typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1",
|
|
||||||
"typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
|
"typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
|
||||||
"typo3/cms-install": ">=12.2,<12.4.8",
|
|
||||||
"typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30",
|
|
||||||
"typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
|
"typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
|
||||||
"typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3",
|
"typo3/html-sanitizer": ">=1,<1.5|>=2,<2.1.1",
|
||||||
"typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3",
|
"typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3",
|
||||||
"typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1",
|
"typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1",
|
||||||
"typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5",
|
"typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5",
|
||||||
"typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10",
|
"typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10",
|
||||||
"ua-parser/uap-php": "<3.8",
|
"ua-parser/uap-php": "<3.8",
|
||||||
"uasoft-indonesia/badaso": "<=2.9.7",
|
"unisharp/laravel-filemanager": "<=2.5.1",
|
||||||
"unisharp/laravel-filemanager": "<2.6.4",
|
|
||||||
"userfrosting/userfrosting": ">=0.3.1,<4.6.3",
|
"userfrosting/userfrosting": ">=0.3.1,<4.6.3",
|
||||||
"usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2",
|
"usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2",
|
||||||
"uvdesk/community-skeleton": "<=1.1.1",
|
"uvdesk/community-skeleton": "<=1.1.1",
|
||||||
@@ -1830,9 +1707,8 @@
|
|||||||
"verot/class.upload.php": "<=1.0.3|>=2,<=2.0.4",
|
"verot/class.upload.php": "<=1.0.3|>=2,<=2.0.4",
|
||||||
"vova07/yii2-fileapi-widget": "<0.1.9",
|
"vova07/yii2-fileapi-widget": "<0.1.9",
|
||||||
"vrana/adminer": "<4.8.1",
|
"vrana/adminer": "<4.8.1",
|
||||||
"waldhacker/hcaptcha": "<2.1.2",
|
|
||||||
"wallabag/tcpdf": "<6.2.22",
|
"wallabag/tcpdf": "<6.2.22",
|
||||||
"wallabag/wallabag": "<2.6.7",
|
"wallabag/wallabag": "<=2.5.4",
|
||||||
"wanglelecc/laracms": "<=1.0.3",
|
"wanglelecc/laracms": "<=1.0.3",
|
||||||
"web-auth/webauthn-framework": ">=3.3,<3.3.4",
|
"web-auth/webauthn-framework": ">=3.3,<3.3.4",
|
||||||
"webbuilders-group/silverstripe-kapost-bridge": "<0.4",
|
"webbuilders-group/silverstripe-kapost-bridge": "<0.4",
|
||||||
@@ -1856,7 +1732,7 @@
|
|||||||
"yetiforce/yetiforce-crm": "<=6.4",
|
"yetiforce/yetiforce-crm": "<=6.4",
|
||||||
"yidashi/yii2cmf": "<=2",
|
"yidashi/yii2cmf": "<=2",
|
||||||
"yii2mod/yii2-cms": "<1.9.2",
|
"yii2mod/yii2-cms": "<1.9.2",
|
||||||
"yiisoft/yii": "<1.1.29",
|
"yiisoft/yii": "<1.1.27",
|
||||||
"yiisoft/yii2": "<2.0.38",
|
"yiisoft/yii2": "<2.0.38",
|
||||||
"yiisoft/yii2-bootstrap": "<2.0.4",
|
"yiisoft/yii2-bootstrap": "<2.0.4",
|
||||||
"yiisoft/yii2-dev": "<2.0.43",
|
"yiisoft/yii2-dev": "<2.0.43",
|
||||||
@@ -1867,9 +1743,9 @@
|
|||||||
"yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6",
|
"yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6",
|
||||||
"yoast-seo-for-typo3/yoast_seo": "<7.2.3",
|
"yoast-seo-for-typo3/yoast_seo": "<7.2.3",
|
||||||
"yourls/yourls": "<=1.8.2",
|
"yourls/yourls": "<=1.8.2",
|
||||||
"zencart/zencart": "<=1.5.7.0-beta",
|
"zencart/zencart": "<1.5.8",
|
||||||
"zendesk/zendesk_api_client_php": "<2.2.11",
|
"zendesk/zendesk_api_client_php": "<2.2.11",
|
||||||
"zendframework/zend-cache": "<2.4.8|>=2.5,<2.5.3",
|
"zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3",
|
||||||
"zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2",
|
"zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2",
|
||||||
"zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2",
|
"zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2",
|
||||||
"zendframework/zend-db": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.10|>=2.3,<2.3.5",
|
"zendframework/zend-db": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.10|>=2.3,<2.3.5",
|
||||||
@@ -1888,22 +1764,14 @@
|
|||||||
"zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6",
|
"zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6",
|
||||||
"zendframework/zendframework": "<=3",
|
"zendframework/zendframework": "<=3",
|
||||||
"zendframework/zendframework1": "<1.12.20",
|
"zendframework/zendframework1": "<1.12.20",
|
||||||
"zendframework/zendopenid": "<2.0.2",
|
"zendframework/zendopenid": ">=2,<2.0.2",
|
||||||
"zendframework/zendrest": "<2.0.2",
|
"zendframework/zendxml": ">=1,<1.0.1",
|
||||||
"zendframework/zendservice-amazon": "<2.0.3",
|
|
||||||
"zendframework/zendservice-api": "<1",
|
|
||||||
"zendframework/zendservice-audioscrobbler": "<2.0.2",
|
|
||||||
"zendframework/zendservice-nirvanix": "<2.0.2",
|
|
||||||
"zendframework/zendservice-slideshare": "<2.0.2",
|
|
||||||
"zendframework/zendservice-technorati": "<2.0.2",
|
|
||||||
"zendframework/zendservice-windowsazure": "<2.0.2",
|
|
||||||
"zendframework/zendxml": "<1.0.1",
|
|
||||||
"zenstruck/collection": "<0.2.1",
|
"zenstruck/collection": "<0.2.1",
|
||||||
"zetacomponents/mail": "<1.8.2",
|
"zetacomponents/mail": "<1.8.2",
|
||||||
"zf-commons/zfc-user": "<1.2.2",
|
"zf-commons/zfc-user": "<1.2.2",
|
||||||
"zfcampus/zf-apigility-doctrine": "<1.0.3",
|
"zfcampus/zf-apigility-doctrine": ">=1,<1.0.3",
|
||||||
"zfr/zfr-oauth2-server-module": "<0.1.2",
|
"zfr/zfr-oauth2-server-module": "<0.1.2",
|
||||||
"zoujingli/thinkadmin": "<=6.1.53"
|
"zoujingli/thinkadmin": "<6.0.22"
|
||||||
},
|
},
|
||||||
"type": "metapackage",
|
"type": "metapackage",
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
@@ -1940,7 +1808,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-12-15T16:04:17+00:00"
|
"time": "2023-07-19T22:04:22+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/cli-parser",
|
"name": "sebastian/cli-parser",
|
||||||
@@ -2908,16 +2776,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "theseer/tokenizer",
|
"name": "theseer/tokenizer",
|
||||||
"version": "1.2.2",
|
"version": "1.2.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/theseer/tokenizer.git",
|
"url": "https://github.com/theseer/tokenizer.git",
|
||||||
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
|
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
|
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
|
||||||
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
|
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2946,7 +2814,7 @@
|
|||||||
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
|
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/theseer/tokenizer/issues",
|
"issues": "https://github.com/theseer/tokenizer/issues",
|
||||||
"source": "https://github.com/theseer/tokenizer/tree/1.2.2"
|
"source": "https://github.com/theseer/tokenizer/tree/1.2.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2954,7 +2822,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-11-20T00:12:19+00:00"
|
"time": "2021-07-28T10:34:58+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { randUser } from '../utils/index.js'
|
import { randUser } from '../utils/index.js'
|
||||||
import { sampleBoard } from '../utils/sampleBoard'
|
import { sampleBoard } from '../utils/sampleBoard'
|
||||||
|
import moment from '@nextcloud/moment'
|
||||||
|
|
||||||
const user = randUser()
|
const user = randUser()
|
||||||
const boardData = sampleBoard()
|
const boardData = sampleBoard()
|
||||||
@@ -111,7 +112,7 @@ describe('Card', function() {
|
|||||||
cy.get('button.icon-folder').should('be.visible')
|
cy.get('button.icon-folder').should('be.visible')
|
||||||
.click()
|
.click()
|
||||||
cy.get('.file-picker__main').should('be.visible')
|
cy.get('.file-picker__main').should('be.visible')
|
||||||
cy.get('.file-picker__main [data-filename="welcome.txt"]').should('be.visible')
|
cy.get('.file-picker__main [data-filename="welcome.txt"]', { timeout: 30000 }).should('be.visible')
|
||||||
.click()
|
.click()
|
||||||
cy.get('.dialog__actions button.button-vue--vue-primary').click()
|
cy.get('.dialog__actions button.button-vue--vue-primary').click()
|
||||||
cy.get('.attachment-list .basename').contains('welcome.txt')
|
cy.get('.attachment-list .basename').contains('welcome.txt')
|
||||||
@@ -177,6 +178,126 @@ describe('Card', function() {
|
|||||||
cy.get('#app-sidebar-vue')
|
cy.get('#app-sidebar-vue')
|
||||||
.find('.ProseMirror h1').contains('Hello world writing more text').should('be.visible')
|
.find('.ProseMirror h1').contains('Hello world writing more text').should('be.visible')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Set a due date', function() {
|
||||||
|
const newCardTitle = 'Card with a due date'
|
||||||
|
|
||||||
|
cy.get('.button-vue[aria-label*="Add card"]')
|
||||||
|
.first().click()
|
||||||
|
cy.get('.stack__card-add form input#new-stack-input-main')
|
||||||
|
.type(newCardTitle)
|
||||||
|
cy.get('.stack__card-add form input[type=submit]')
|
||||||
|
.first().click()
|
||||||
|
cy.get(`.card:contains("${newCardTitle}")`).should('be.visible')
|
||||||
|
|
||||||
|
cy.get('.card:contains("Card with a due date")').should('be.visible').click()
|
||||||
|
|
||||||
|
cy.get('#app-sidebar-vue [data-cy-due-date-actions]').should('be.visible').click()
|
||||||
|
|
||||||
|
// Set a due date through shortcut
|
||||||
|
cy.get('[data-cy-due-date-shortcut="tomorrow"] button').should('be.visible').click()
|
||||||
|
|
||||||
|
const tomorrow = moment().add(1, 'days').hour(8).minutes(0).seconds(0)
|
||||||
|
cy.get('#card-duedate-picker').should('have.value', tomorrow.format('YYYY-MM-DDTHH:mm'))
|
||||||
|
|
||||||
|
const now = moment().hour(11).minutes(0).seconds(0).toDate()
|
||||||
|
cy.clock(now)
|
||||||
|
cy.log(now)
|
||||||
|
cy.tick(60_000)
|
||||||
|
|
||||||
|
cy.get(`.card:contains("${newCardTitle}")`).find('[data-due-state="Now"]').should('be.visible').should('contain', '21 hours')
|
||||||
|
|
||||||
|
|
||||||
|
// Remove the due date again
|
||||||
|
cy.get('#app-sidebar-vue [data-cy-due-date-actions]').should('be.visible').click()
|
||||||
|
// tick needed to show the popover menu
|
||||||
|
cy.tick(1_000)
|
||||||
|
cy.get('[data-cy-due-date-remove] button').should('be.visible').click()
|
||||||
|
|
||||||
|
cy.get(`.card:contains("${newCardTitle}")`).find('[data-due-state]').should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Add a label', function() {
|
||||||
|
const newCardTitle = 'Card with labels'
|
||||||
|
|
||||||
|
cy.get('.button-vue[aria-label*="Add card"]')
|
||||||
|
.first().click()
|
||||||
|
cy.get('.stack__card-add form input#new-stack-input-main')
|
||||||
|
.type(newCardTitle)
|
||||||
|
cy.get('.stack__card-add form input[type=submit]')
|
||||||
|
.first().click()
|
||||||
|
cy.get(`.card:contains("${newCardTitle}")`).should('be.visible').click()
|
||||||
|
|
||||||
|
cy.get('#app-sidebar-vue [data-test="tag-selector"]').should('be.visible').click()
|
||||||
|
cy.get('.multiselect__option:contains("Action needed")').should('be.visible').click()
|
||||||
|
|
||||||
|
cy.get('[data-test="tag-selector"] .selector-wrapper--icon').click()
|
||||||
|
cy.get('.multiselect__option:contains("Action needed")').should('not.be.visible')
|
||||||
|
|
||||||
|
cy.get('[data-test="tag-selector"] .multiselect__tags .tag:contains("Action needed")')
|
||||||
|
.should('be.visible')
|
||||||
|
|
||||||
|
cy.get(`.card:contains("${newCardTitle}")`).find('.labels li:contains("Action needed")')
|
||||||
|
.should('be.visible')
|
||||||
|
|
||||||
|
cy.get('#app-sidebar-vue [data-test="tag-selector"]').should('be.visible').click()
|
||||||
|
cy.get('.multiselect__option:contains("Later")').should('be.visible').click()
|
||||||
|
cy.get('.multiselect__option:contains("Action needed")').should('be.visible').click()
|
||||||
|
|
||||||
|
cy.get(`.card:contains("${newCardTitle}")`).find('.labels li:contains("Later")')
|
||||||
|
.should('be.visible')
|
||||||
|
cy.get(`.card:contains("${newCardTitle}")`).find('.labels li:contains("Action needed")')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('Card actions', () => {
|
||||||
|
beforeEach(function() {
|
||||||
|
cy.login(user)
|
||||||
|
useModal(false).then(() => {
|
||||||
|
cy.visit(`/apps/deck/#/board/${boardId}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Custom card actions', () => {
|
||||||
|
const myAction = {
|
||||||
|
label: 'Test action',
|
||||||
|
icon: 'icon-user',
|
||||||
|
callback(card) {
|
||||||
|
console.log('Called callback', card)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cy.spy(myAction, 'callback').as('myAction.callback')
|
||||||
|
|
||||||
|
cy.window().then(win => {
|
||||||
|
win.OCA.Deck.registerCardAction(myAction)
|
||||||
|
})
|
||||||
|
|
||||||
|
cy.get('.card:contains("Hello world")').should('be.visible').click()
|
||||||
|
cy.get('#app-sidebar-vue')
|
||||||
|
.find('.ProseMirror h1').contains('Hello world').should('be.visible')
|
||||||
|
|
||||||
|
cy.get('.app-sidebar-header .action-item__menutoggle').click()
|
||||||
|
cy.get('.v-popper__popper button:contains("Test action")').click()
|
||||||
|
|
||||||
|
cy.get('@myAction.callback')
|
||||||
|
.should('be.called')
|
||||||
|
.its('firstCall.args.0')
|
||||||
|
.as('args')
|
||||||
|
|
||||||
|
cy.url().then(url => {
|
||||||
|
const cardId = url.split('/').pop()
|
||||||
|
cy.get('@args').should('have.property', 'name', 'Hello world')
|
||||||
|
cy.get('@args').should('have.property', 'stackname', 'TestList')
|
||||||
|
cy.get('@args').should('have.property', 'boardname', 'MyTestBoard')
|
||||||
|
cy.get('@args').its('link').then((url) => {
|
||||||
|
expect(url.split('/').pop() === cardId).to.be.true
|
||||||
|
cy.visit(url)
|
||||||
|
cy.get('#app-sidebar-vue')
|
||||||
|
.find('.ProseMirror h1').contains('Hello world').should('be.visible')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { randUser } from '../utils/index.js'
|
import { randUser } from '../utils/index.js'
|
||||||
|
import { sampleBoard } from '../utils/sampleBoard'
|
||||||
const user = randUser()
|
const user = randUser()
|
||||||
|
|
||||||
describe('Deck dashboard', function() {
|
describe('Deck dashboard', function() {
|
||||||
@@ -8,16 +9,18 @@ describe('Deck dashboard', function() {
|
|||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
cy.login(user)
|
cy.login(user)
|
||||||
cy.visit('/apps/deck')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Can show the right title on the dashboard', function() {
|
it('Can show the right title on the dashboard', function() {
|
||||||
|
cy.visit('/apps/deck')
|
||||||
cy.get('.board-title h2')
|
cy.get('.board-title h2')
|
||||||
.should('have.length', 1).first()
|
.should('have.length', 1).first()
|
||||||
.should('have.text', 'Upcoming cards')
|
.should($el => expect($el.text().trim()).to.equal('Upcoming cards'))
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Can see the default "Personal Board" created for user by default', function() {
|
it('Can see the default "Personal Board" created for user by default', function() {
|
||||||
|
cy.visit('/apps/deck')
|
||||||
|
|
||||||
const defaultBoard = 'Personal'
|
const defaultBoard = 'Personal'
|
||||||
|
|
||||||
cy.get('.app-navigation-entry-wrapper[icon=icon-deck]')
|
cy.get('.app-navigation-entry-wrapper[icon=icon-deck]')
|
||||||
@@ -26,4 +29,29 @@ describe('Deck dashboard', function() {
|
|||||||
.contains(defaultBoard)
|
.contains(defaultBoard)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Shows a card with due date on the overview', function() {
|
||||||
|
cy.createExampleBoard({
|
||||||
|
user,
|
||||||
|
board: sampleBoard(),
|
||||||
|
}).then((board) => {
|
||||||
|
cy.visit(`/apps/deck/#/board/${board.id}`)
|
||||||
|
|
||||||
|
cy.intercept({ method: 'PUT', url: '**/apps/deck/cards/**' }).as('updateCard')
|
||||||
|
|
||||||
|
const newCardTitle = 'Hello world'
|
||||||
|
cy.get(`.card:contains("${newCardTitle}")`).should('be.visible').click()
|
||||||
|
cy.get('#app-sidebar-vue [data-cy-due-date-actions]').should('be.visible').click()
|
||||||
|
cy.get('[data-cy-due-date-shortcut="tomorrow"] button').should('be.visible').click()
|
||||||
|
|
||||||
|
cy.wait('@updateCard')
|
||||||
|
|
||||||
|
cy.get('button[title="Close sidebar"]').click()
|
||||||
|
cy.get('.app-navigation-entry:contains("Upcoming cards") a').click()
|
||||||
|
|
||||||
|
cy.get(`.card:contains("${newCardTitle}")`).should('be.visible')
|
||||||
|
cy.get('.dashboard-column:contains("Tomorrow")').should('be.visible')
|
||||||
|
cy.get('.dashboard-column:contains("Tomorrow") .card:contains("Hello world")').should('be.visible')
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
46
docs/API.md
46
docs/API.md
@@ -80,7 +80,7 @@ An ETag header is returned in order to determine if further child elements have
|
|||||||
- Fetch a single card of a board `GET /api/v1.0/boards/{boardId}/stacks/{stackId}/cards/{cardId}`
|
- Fetch a single card of a board `GET /api/v1.0/boards/{boardId}/stacks/{stackId}/cards/{cardId}`
|
||||||
- Fetch attachments of a card `GET /api/v1.0/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments`
|
- Fetch attachments of a card `GET /api/v1.0/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments`
|
||||||
|
|
||||||
If a `If-None-Match` header is provided and the requested element has not changed a `304` Not Modified response will be returned.
|
If a `If-None-Match` header is provided and the requested element has not changed a `304` Not Modified response will be returned.
|
||||||
|
|
||||||
Changes of child elements will propagate to their parents and also cause an update of the ETag which will be useful for determining if a sync is necessary on any client integration side. As an example, if a label is added to a card, the ETag of all related entities (the card, stack and board) will change.
|
Changes of child elements will propagate to their parents and also cause an update of the ETag which will be useful for determining if a sync is necessary on any client integration side. As an example, if a label is added to a card, the ETag of all related entities (the card, stack and board) will change.
|
||||||
|
|
||||||
@@ -117,6 +117,7 @@ This API version has become available with **Deck 1.3.0**.
|
|||||||
- [GET /boards/import/getSystems - Import a board](#get-boardsimportgetsystems-import-a-board)
|
- [GET /boards/import/getSystems - Import a board](#get-boardsimportgetsystems-import-a-board)
|
||||||
- [GET /boards/import/config/system/{schema} - Import a board](#get-boardsimportconfigsystemschema-import-a-board)
|
- [GET /boards/import/config/system/{schema} - Import a board](#get-boardsimportconfigsystemschema-import-a-board)
|
||||||
- [POST /boards/import - Import a board](#post-boardsimport-import-a-board)
|
- [POST /boards/import - Import a board](#post-boardsimport-import-a-board)
|
||||||
|
- The `done` property was added to cards
|
||||||
|
|
||||||
# Endpoints
|
# Endpoints
|
||||||
|
|
||||||
@@ -587,7 +588,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
|||||||
#### Response
|
#### Response
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"title":"Test",
|
"title":"Test",
|
||||||
"description":null,
|
"description":null,
|
||||||
"stackId":6,
|
"stackId":6,
|
||||||
@@ -601,6 +602,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
|||||||
"owner":"admin",
|
"owner":"admin",
|
||||||
"order":999,
|
"order":999,
|
||||||
"archived":false,
|
"archived":false,
|
||||||
|
"done":null,
|
||||||
"duedate": "2019-12-24T19:29:30+00:00",
|
"duedate": "2019-12-24T19:29:30+00:00",
|
||||||
"deletedAt":0,
|
"deletedAt":0,
|
||||||
"commentsUnread":0,
|
"commentsUnread":0,
|
||||||
@@ -623,22 +625,28 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
|||||||
|
|
||||||
#### Request data
|
#### Request data
|
||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
|-------------|-----------|------------------------------------------------------|
|
|-------------|-----------------|-----------------------------------------------------------------------------------------------------|
|
||||||
| title | String | The title of the card, maximum length is limited to 255 characters |
|
| title | String | The title of the card, maximum length is limited to 255 characters |
|
||||||
| description | String | The markdown description of the card |
|
| description | String | The markdown description of the card |
|
||||||
| type | String | Type of the card (for later use) use 'plain' for now |
|
| type | String | Type of the card (for later use) use 'plain' for now |
|
||||||
| order | Integer | Order for sorting the stacks |
|
| owner | String | The user that owns the card |
|
||||||
| duedate | timestamp | The ISO-8601 formatted duedate of the card or null |
|
| order | Integer | Order for sorting the stacks |
|
||||||
|
| duedate | timestamp | The ISO-8601 formatted duedate of the card or null |
|
||||||
|
| archived | bool | Whether the card is archived or not |
|
||||||
|
| done | timestamp\|null | The ISO-8601 formatted date when the card is marked as done (optional, null indicates undone state) |
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"title": "Test card",
|
"title": "Test card",
|
||||||
"description": "A card description",
|
"description": "A card description",
|
||||||
"type": "plain",
|
"type": "plain",
|
||||||
|
"owner": "admin",
|
||||||
"order": 999,
|
"order": 999,
|
||||||
"duedate": "2019-12-24T19:29:30+00:00",
|
"duedate": "2019-12-24T19:29:30+00:00",
|
||||||
|
"archived": false,
|
||||||
|
"done": null,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -977,7 +985,7 @@ For now only `deck_file` is supported as an attachment type.
|
|||||||
|
|
||||||
### DELETE /boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId} - Delete an attachment
|
### DELETE /boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId} - Delete an attachment
|
||||||
|
|
||||||
|
|
||||||
#### Request parameters
|
#### Request parameters
|
||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
@@ -1051,12 +1059,12 @@ Make a request to see the json schema of system
|
|||||||
|
|
||||||
# OCS API
|
# OCS API
|
||||||
|
|
||||||
The following endpoints are available through the Nextcloud OCS endpoint, which is available at `/ocs/v2.php/apps/deck/api/v1.0/`.
|
The following endpoints are available through the Nextcloud OCS endpoint, which is available at `/ocs/v2.php/apps/deck/api/v1.0/`.
|
||||||
This has the benefit that both the web UI as well as external integrations can use the same API.
|
This has the benefit that both the web UI as well as external integrations can use the same API.
|
||||||
|
|
||||||
## Config
|
## Config
|
||||||
|
|
||||||
Deck stores user and app configuration values globally and per board. The GET endpoint allows to fetch the current global configuration while board settings will be exposed through the board element on the regular API endpoints.
|
Deck stores user and app configuration values globally and per board. The GET endpoint allows to fetch the current global configuration while board settings will be exposed through the board element on the regular API endpoints.
|
||||||
|
|
||||||
### GET /api/v1.0/config - Fetch app configuration values
|
### GET /api/v1.0/config - Fetch app configuration values
|
||||||
|
|
||||||
@@ -1064,10 +1072,10 @@ Deck stores user and app configuration values globally and per board. The GET en
|
|||||||
|
|
||||||
| Config key | Description |
|
| Config key | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| calendar | Determines if the calendar/tasks integration through the CalDAV backend is enabled for the user (boolean) |
|
| calendar | Determines if the calendar/tasks integration through the CalDAV backend is enabled for the user (boolean) |
|
||||||
| cardDetailsInModal | Determines if the bigger view is used (boolean) |
|
| cardDetailsInModal | Determines if the bigger view is used (boolean) |
|
||||||
| cardIdBadge | Determines if the ID badges are displayed on cards (boolean) |
|
| cardIdBadge | Determines if the ID badges are displayed on cards (boolean) |
|
||||||
| groupLimit | Determines if creating new boards is limited to certain groups of the instance. The resulting output is an array of group objects with the id and the displayname (Admin only)|
|
| groupLimit | Determines if creating new boards is limited to certain groups of the instance. The resulting output is an array of group objects with the id and the displayname (Admin only)|
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
@@ -1112,7 +1120,7 @@ Deck stores user and app configuration values globally and per board. The GET en
|
|||||||
| calendar | Boolean |
|
| calendar | Boolean |
|
||||||
| cardDetailsInModal | Boolean |
|
| cardDetailsInModal | Boolean |
|
||||||
| cardIdBadge | Boolean |
|
| cardIdBadge | Boolean |
|
||||||
|
|
||||||
#### Example request
|
#### Example request
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -1186,7 +1194,7 @@ A list of comments will be provided under the `ocs.data` key. If no or no more c
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
In case a comment is marked as a reply to another comment object, the parent comment will be added as `replyTo` entry to the response. Only the next parent node is added, nested replies are not exposed directly.
|
In case a comment is marked as a reply to another comment object, the parent comment will be added as `replyTo` entry to the response. Only the next parent node is added, nested replies are not exposed directly.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -12,11 +12,12 @@ Overall, Deck is easy to use. You can create boards, add users, share the Deck,
|
|||||||
1. [Create my first board](#1-create-my-first-board)
|
1. [Create my first board](#1-create-my-first-board)
|
||||||
2. [Create stacks and cards](#2-create-stacks-and-cards)
|
2. [Create stacks and cards](#2-create-stacks-and-cards)
|
||||||
3. [Handle cards options](#3-handle-cards-options)
|
3. [Handle cards options](#3-handle-cards-options)
|
||||||
4. [Archive old tasks](#4-archive-old-tasks)
|
4. [Mark task as done](#4-mark-as-done)
|
||||||
5. [Manage your board](#5-manage-your-board)
|
5. [Archive old tasks](#5-archive-old-tasks)
|
||||||
6. [Import boards](#6-import-boards)
|
6. [Manage your board](#6-manage-your-board)
|
||||||
7. [Search](#7-search)
|
7. [Import boards](#7-import-boards)
|
||||||
8. [New owner for the deck entities](#8-new-owner-for-the-deck-entities)
|
8. [Search](#8-search)
|
||||||
|
9. [New owner for the deck entities](#9-new-owner-for-the-deck-entities)
|
||||||
|
|
||||||
### 1. Create my first board
|
### 1. Create my first board
|
||||||
In this example, we're going to create a board and share it with an other nextcloud user.
|
In this example, we're going to create a board and share it with an other nextcloud user.
|
||||||
@@ -25,7 +26,7 @@ In this example, we're going to create a board and share it with an other nextcl
|
|||||||
|
|
||||||
|
|
||||||
### 2. Create stacks and cards
|
### 2. Create stacks and cards
|
||||||
Stacks are simply columns with list of cards. It can represent a category of tasks or an y step in your projects for example.
|
Stacks are simply columns with list of cards. It can represent a category of tasks or any step in your projects for example.
|
||||||
**Check this out :**
|
**Check this out :**
|
||||||
|
|
||||||

|

|
||||||
@@ -53,12 +54,18 @@ And even :
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 4. Archive old tasks
|
### 4. Mark as done
|
||||||
Once finished or obsolete, a task could be archived. The tasks is not deleted, it's just archived, and you can retrieve it later
|
Once a task has been completed, you can mark it as done. This will prevent it from becoming overdue and hide it from the upcoming cards.
|
||||||
|
You can mark it as not done at any time.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 5. Manage your board
|
### 5. Archive old tasks
|
||||||
|
Once obsolete, a task could be archived. The task is not deleted, it's just archived, and you can retrieve it later
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 6. Manage your board
|
||||||
You can manage the settings of your Deck once you are inside it, by clicking on the small wheel at the top right.
|
You can manage the settings of your Deck once you are inside it, by clicking on the small wheel at the top right.
|
||||||
Once in this menu, you have access to several things:
|
Once in this menu, you have access to several things:
|
||||||
|
|
||||||
@@ -72,7 +79,7 @@ The **sharing tab** allows you to add users or even groups to your boards.
|
|||||||
**Deleted objects** allows you to return previously deleted stacks or cards.
|
**Deleted objects** allows you to return previously deleted stacks or cards.
|
||||||
The **Timeline** allows you to see everything that happened in your boards. Everything!
|
The **Timeline** allows you to see everything that happened in your boards. Everything!
|
||||||
|
|
||||||
### 6. Import boards
|
### 7. Import boards
|
||||||
|
|
||||||
Importing can be done using the API or the `occ` `deck:import` command.
|
Importing can be done using the API or the `occ` `deck:import` command.
|
||||||
|
|
||||||
@@ -138,7 +145,7 @@ Example configuration file:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 7. Search
|
### 8. Search
|
||||||
|
|
||||||
Deck provides a global search either through the unified search in the Nextcloud header or with the inline search next to the board controls.
|
Deck provides a global search either through the unified search in the Nextcloud header or with the inline search next to the board controls.
|
||||||
This search allows advanced filtering of cards across all board of the logged in user.
|
This search allows advanced filtering of cards across all board of the logged in user.
|
||||||
@@ -161,7 +168,7 @@ Other text tokens will be used to perform a case-insensitive search on the card
|
|||||||
|
|
||||||
In addition, quotes can be used to pass a query with spaces, e.g. `"Exact match with spaces"` or `title:"My card"`.
|
In addition, quotes can be used to pass a query with spaces, e.g. `"Exact match with spaces"` or `title:"My card"`.
|
||||||
|
|
||||||
### 8. New owner for the deck entities
|
### 9. New owner for the deck entities
|
||||||
You can transfer ownership of boards, cards, etc to a new user, using `occ` command `deck:transfer-ownership`
|
You can transfer ownership of boards, cards, etc to a new user, using `occ` command `deck:transfer-ownership`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
BIN
docs/resources/gifs/EN_done.gif
Normal file
BIN
docs/resources/gifs/EN_done.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
@@ -92,6 +92,8 @@ class ActivityManager {
|
|||||||
public const SUBJECT_CARD_UPDATE_DUEDATE = 'card_update_duedate';
|
public const SUBJECT_CARD_UPDATE_DUEDATE = 'card_update_duedate';
|
||||||
public const SUBJECT_CARD_UPDATE_ARCHIVE = 'card_update_archive';
|
public const SUBJECT_CARD_UPDATE_ARCHIVE = 'card_update_archive';
|
||||||
public const SUBJECT_CARD_UPDATE_UNARCHIVE = 'card_update_unarchive';
|
public const SUBJECT_CARD_UPDATE_UNARCHIVE = 'card_update_unarchive';
|
||||||
|
public const SUBJECT_CARD_UPDATE_DONE = 'card_update_done';
|
||||||
|
public const SUBJECT_CARD_UPDATE_UNDONE = 'card_update_undone';
|
||||||
public const SUBJECT_CARD_UPDATE_STACKID = 'card_update_stackId';
|
public const SUBJECT_CARD_UPDATE_STACKID = 'card_update_stackId';
|
||||||
public const SUBJECT_CARD_USER_ASSIGN = 'card_user_assign';
|
public const SUBJECT_CARD_USER_ASSIGN = 'card_user_assign';
|
||||||
public const SUBJECT_CARD_USER_UNASSIGN = 'card_user_unassign';
|
public const SUBJECT_CARD_USER_UNASSIGN = 'card_user_unassign';
|
||||||
@@ -199,6 +201,12 @@ class ActivityManager {
|
|||||||
case self::SUBJECT_CARD_UPDATE_UNARCHIVE:
|
case self::SUBJECT_CARD_UPDATE_UNARCHIVE:
|
||||||
$subject = $ownActivity ? $l->t('You have unarchived card {card} in list {stack} on board {board}') : $l->t('{user} has unarchived card {card} in list {stack} on board {board}');
|
$subject = $ownActivity ? $l->t('You have unarchived card {card} in list {stack} on board {board}') : $l->t('{user} has unarchived card {card} in list {stack} on board {board}');
|
||||||
break;
|
break;
|
||||||
|
case self::SUBJECT_CARD_UPDATE_DONE:
|
||||||
|
$subject = $ownActivity ? $l->t('You have marked the card {card} as done in list {stack} on board {board}') : $l->t('{user} has marked card {card} as done in list {stack} on board {board}');
|
||||||
|
break;
|
||||||
|
case self::SUBJECT_CARD_UPDATE_UNDONE:
|
||||||
|
$subject = $ownActivity ? $l->t('You have marked the card {card} as undone in list {stack} on board {board}') : $l->t('{user} has marked the card {card} as undone in list {stack} on board {board}');
|
||||||
|
break;
|
||||||
case self::SUBJECT_CARD_UPDATE_DUEDATE:
|
case self::SUBJECT_CARD_UPDATE_DUEDATE:
|
||||||
if (!isset($subjectParams['after'])) {
|
if (!isset($subjectParams['after'])) {
|
||||||
$subject = $ownActivity ? $l->t('You have removed the due date of card {card}') : $l->t('{user} has removed the due date of card {card}');
|
$subject = $ownActivity ? $l->t('You have removed the due date of card {card}') : $l->t('{user} has removed the due date of card {card}');
|
||||||
@@ -358,6 +366,8 @@ class ActivityManager {
|
|||||||
case self::SUBJECT_CARD_DELETE:
|
case self::SUBJECT_CARD_DELETE:
|
||||||
case self::SUBJECT_CARD_UPDATE_ARCHIVE:
|
case self::SUBJECT_CARD_UPDATE_ARCHIVE:
|
||||||
case self::SUBJECT_CARD_UPDATE_UNARCHIVE:
|
case self::SUBJECT_CARD_UPDATE_UNARCHIVE:
|
||||||
|
case self::SUBJECT_CARD_UPDATE_DONE:
|
||||||
|
case self::SUBJECT_CARD_UPDATE_UNDONE:
|
||||||
case self::SUBJECT_CARD_UPDATE_TITLE:
|
case self::SUBJECT_CARD_UPDATE_TITLE:
|
||||||
case self::SUBJECT_CARD_UPDATE_DESCRIPTION:
|
case self::SUBJECT_CARD_UPDATE_DESCRIPTION:
|
||||||
case self::SUBJECT_CARD_UPDATE_DUEDATE:
|
case self::SUBJECT_CARD_UPDATE_DUEDATE:
|
||||||
|
|||||||
@@ -23,9 +23,10 @@
|
|||||||
|
|
||||||
namespace OCA\Deck\Activity;
|
namespace OCA\Deck\Activity;
|
||||||
|
|
||||||
|
use OCP\Activity\ActivitySettings;
|
||||||
use OCP\IL10N;
|
use OCP\IL10N;
|
||||||
|
|
||||||
class Setting implements \OCP\Activity\ISetting {
|
abstract class SettingBase extends ActivitySettings {
|
||||||
|
|
||||||
/** @var IL10N */
|
/** @var IL10N */
|
||||||
protected $l;
|
protected $l;
|
||||||
@@ -37,6 +38,14 @@ class Setting implements \OCP\Activity\ISetting {
|
|||||||
$this->l = $l;
|
$this->l = $l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getGroupIdentifier() {
|
||||||
|
return 'deck';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGroupName() {
|
||||||
|
return $this->l->t('Deck');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string Lowercase a-z and underscore only identifier
|
* @return string Lowercase a-z and underscore only identifier
|
||||||
* @since 11.0.0
|
* @since 11.0.0
|
||||||
84
lib/Activity/SettingChanges.php
Normal file
84
lib/Activity/SettingChanges.php
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @author Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Deck\Activity;
|
||||||
|
|
||||||
|
class SettingChanges extends SettingBase {
|
||||||
|
/**
|
||||||
|
* @return string Lowercase a-z and underscore only identifier
|
||||||
|
* @since 11.0.0
|
||||||
|
*/
|
||||||
|
public function getIdentifier(): string {
|
||||||
|
return 'deck';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string A translated string
|
||||||
|
* @since 11.0.0
|
||||||
|
*/
|
||||||
|
public function getName(): string {
|
||||||
|
return $this->l->t('A <strong>board, list or card</strong> was changed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int whether the filter should be rather on the top or bottom of
|
||||||
|
* the admin section. The filters are arranged in ascending order of the
|
||||||
|
* priority values. It is required to return a value between 0 and 100.
|
||||||
|
* @since 11.0.0
|
||||||
|
*/
|
||||||
|
public function getPriority(): int {
|
||||||
|
return 90;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool True when the option can be changed for the stream
|
||||||
|
* @since 11.0.0
|
||||||
|
*/
|
||||||
|
public function canChangeStream(): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool True when the option can be changed for the stream
|
||||||
|
* @since 11.0.0
|
||||||
|
*/
|
||||||
|
public function isDefaultEnabledStream(): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool True when the option can be changed for the mail
|
||||||
|
* @since 11.0.0
|
||||||
|
*/
|
||||||
|
public function canChangeMail(): bool {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool True when the option can be changed for the stream
|
||||||
|
* @since 11.0.0
|
||||||
|
*/
|
||||||
|
public function isDefaultEnabledMail(): bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
namespace OCA\Deck\Activity;
|
namespace OCA\Deck\Activity;
|
||||||
|
|
||||||
class SettingComment extends Setting {
|
class SettingComment extends SettingBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string Lowercase a-z and underscore only identifier
|
* @return string Lowercase a-z and underscore only identifier
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
namespace OCA\Deck\Activity;
|
namespace OCA\Deck\Activity;
|
||||||
|
|
||||||
class DescriptionSetting extends Setting {
|
class SettingDescription extends SettingBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string Lowercase a-z and underscore only identifier
|
* @return string Lowercase a-z and underscore only identifier
|
||||||
@@ -38,6 +38,6 @@ class DescriptionSetting extends Setting {
|
|||||||
* @since 11.0.0
|
* @since 11.0.0
|
||||||
*/
|
*/
|
||||||
public function getName(): string {
|
public function getName(): string {
|
||||||
return $this->l->t('A <strong>card description</strong> inside the Deck app has been changed');
|
return $this->l->t('A <strong>card description</strong> has been changed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,9 @@ use OCA\Deck\Activity\CommentEventHandler;
|
|||||||
use OCA\Deck\Capabilities;
|
use OCA\Deck\Capabilities;
|
||||||
use OCA\Deck\Collaboration\Resources\ResourceProvider;
|
use OCA\Deck\Collaboration\Resources\ResourceProvider;
|
||||||
use OCA\Deck\Collaboration\Resources\ResourceProviderCard;
|
use OCA\Deck\Collaboration\Resources\ResourceProviderCard;
|
||||||
use OCA\Deck\Dashboard\DeckWidget;
|
use OCA\Deck\Dashboard\DeckWidgetToday;
|
||||||
|
use OCA\Deck\Dashboard\DeckWidgetTomorrow;
|
||||||
|
use OCA\Deck\Dashboard\DeckWidgetUpcoming;
|
||||||
use OCA\Deck\Db\Acl;
|
use OCA\Deck\Db\Acl;
|
||||||
use OCA\Deck\Db\CardMapper;
|
use OCA\Deck\Db\CardMapper;
|
||||||
use OCA\Deck\Event\AclCreatedEvent;
|
use OCA\Deck\Event\AclCreatedEvent;
|
||||||
@@ -135,7 +137,9 @@ class Application extends App implements IBootstrap {
|
|||||||
|
|
||||||
$context->registerSearchProvider(DeckProvider::class);
|
$context->registerSearchProvider(DeckProvider::class);
|
||||||
$context->registerSearchProvider(CardCommentProvider::class);
|
$context->registerSearchProvider(CardCommentProvider::class);
|
||||||
$context->registerDashboardWidget(DeckWidget::class);
|
$context->registerDashboardWidget(DeckWidgetUpcoming::class);
|
||||||
|
$context->registerDashboardWidget(DeckWidgetToday::class);
|
||||||
|
$context->registerDashboardWidget(DeckWidgetTomorrow::class);
|
||||||
|
|
||||||
$context->registerReferenceProvider(CreateCardReferenceProvider::class);
|
$context->registerReferenceProvider(CreateCardReferenceProvider::class);
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class Capabilities implements ICapability {
|
|||||||
/**
|
/**
|
||||||
* Function an app uses to return the capabilities
|
* Function an app uses to return the capabilities
|
||||||
*
|
*
|
||||||
* @return array Array containing the apps capabilities
|
* @return array{deck: array{version: string, canCreateBoards: bool, apiVersions: array<string>}}
|
||||||
* @since 8.2.0
|
* @since 8.2.0
|
||||||
*/
|
*/
|
||||||
public function getCapabilities() {
|
public function getCapabilities() {
|
||||||
|
|||||||
@@ -29,11 +29,12 @@ use OCP\AppFramework\Http\DataResponse;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class AttachmentApiController extends ApiController {
|
class AttachmentApiController extends ApiController {
|
||||||
private $attachmentService;
|
public function __construct(
|
||||||
|
$appName,
|
||||||
public function __construct($appName, IRequest $request, AttachmentService $attachmentService) {
|
IRequest $request,
|
||||||
|
private AttachmentService $attachmentService,
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->attachmentService = $attachmentService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,13 +28,12 @@ use OCP\AppFramework\Controller;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class AttachmentController extends Controller {
|
class AttachmentController extends Controller {
|
||||||
|
public function __construct(
|
||||||
/** @var AttachmentService */
|
$appName,
|
||||||
private $attachmentService;
|
IRequest $request,
|
||||||
|
private AttachmentService $attachmentService,
|
||||||
public function __construct($appName, IRequest $request, AttachmentService $attachmentService) {
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->attachmentService = $attachmentService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -40,18 +40,16 @@ use Sabre\HTTP\Util;
|
|||||||
* @package OCA\Deck\Controller
|
* @package OCA\Deck\Controller
|
||||||
*/
|
*/
|
||||||
class BoardApiController extends ApiController {
|
class BoardApiController extends ApiController {
|
||||||
private $boardService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $appName
|
* @param string $appName
|
||||||
* @param IRequest $request
|
|
||||||
* @param BoardService $service
|
|
||||||
* @param $userId
|
|
||||||
*/
|
*/
|
||||||
public function __construct($appName, IRequest $request, BoardService $service, $userId) {
|
public function __construct(
|
||||||
|
$appName,
|
||||||
|
IRequest $request,
|
||||||
|
private BoardService $boardService,
|
||||||
|
private $userId,
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->boardService = $service;
|
|
||||||
$this->userId = $userId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -33,15 +33,14 @@ use OCP\AppFramework\Http\DataResponse;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class BoardController extends ApiController {
|
class BoardController extends ApiController {
|
||||||
private $userId;
|
public function __construct(
|
||||||
private $boardService;
|
$appName,
|
||||||
private $permissionService;
|
IRequest $request,
|
||||||
|
private BoardService $boardService,
|
||||||
public function __construct($appName, IRequest $request, BoardService $boardService, PermissionService $permissionService, $userId) {
|
private PermissionService $permissionService,
|
||||||
|
private $userId,
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->userId = $userId;
|
|
||||||
$this->boardService = $boardService;
|
|
||||||
$this->permissionService = $permissionService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,7 +143,7 @@ class BoardController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @param $aclId
|
* @param $aclId
|
||||||
* @return \OCP\AppFramework\Db\Entity
|
* @return \OCP\AppFramework\Db\Entity|null
|
||||||
*/
|
*/
|
||||||
public function deleteAcl($aclId) {
|
public function deleteAcl($aclId) {
|
||||||
return $this->boardService->deleteAcl($aclId);
|
return $this->boardService->deleteAcl($aclId);
|
||||||
|
|||||||
@@ -30,20 +30,13 @@ use OCP\AppFramework\OCSController;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class BoardImportApiController extends OCSController {
|
class BoardImportApiController extends OCSController {
|
||||||
/** @var BoardImportService */
|
|
||||||
private $boardImportService;
|
|
||||||
/** @var string */
|
|
||||||
private $userId;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $appName,
|
string $appName,
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
BoardImportService $boardImportService,
|
private BoardImportService $boardImportService,
|
||||||
string $userId
|
private string $userId,
|
||||||
) {
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->boardImportService = $boardImportService;
|
|
||||||
$this->userId = $userId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
namespace OCA\Deck\Controller;
|
namespace OCA\Deck\Controller;
|
||||||
|
|
||||||
|
use OCA\Deck\Model\OptionalNullableValue;
|
||||||
use OCA\Deck\Service\AssignmentService;
|
use OCA\Deck\Service\AssignmentService;
|
||||||
use OCA\Deck\Service\CardService;
|
use OCA\Deck\Service\CardService;
|
||||||
use OCP\AppFramework\ApiController;
|
use OCP\AppFramework\ApiController;
|
||||||
@@ -38,21 +39,22 @@ use OCP\IRequest;
|
|||||||
* @package OCA\Deck\Controller
|
* @package OCA\Deck\Controller
|
||||||
*/
|
*/
|
||||||
class CardApiController extends ApiController {
|
class CardApiController extends ApiController {
|
||||||
private $cardService;
|
|
||||||
private $userId;
|
|
||||||
private $assignmentService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $appName
|
* @param string $appName
|
||||||
* @param IRequest $request
|
* @param IRequest $request
|
||||||
* @param CardService $cardService
|
* @param CardService $cardService
|
||||||
|
* @param AssignmentService $assignmentService
|
||||||
* @param $userId
|
* @param $userId
|
||||||
*/
|
*/
|
||||||
public function __construct($appName, IRequest $request, CardService $cardService, AssignmentService $assignmentService, $userId) {
|
public function __construct(
|
||||||
|
string $appName,
|
||||||
|
IRequest $request,
|
||||||
|
private CardService $cardService,
|
||||||
|
private AssignmentService $assignmentService,
|
||||||
|
private $userId,
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->cardService = $cardService;
|
|
||||||
$this->userId = $userId;
|
|
||||||
$this->assignmentService = $assignmentService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,7 +106,8 @@ class CardApiController extends ApiController {
|
|||||||
* Update a card
|
* Update a card
|
||||||
*/
|
*/
|
||||||
public function update($title, $type, $owner, $description = '', $order = 0, $duedate = null, $archived = null) {
|
public function update($title, $type, $owner, $description = '', $order = 0, $duedate = null, $archived = null) {
|
||||||
$card = $this->cardService->update($this->request->getParam('cardId'), $title, $this->request->getParam('stackId'), $type, $owner, $description, $order, $duedate, 0, $archived);
|
$done = array_key_exists('done', $this->request->getParams()) ? new OptionalNullableValue($this->request->getParam('done', null)) : null;
|
||||||
|
$card = $this->cardService->update($this->request->getParam('cardId'), $title, $this->request->getParam('stackId'), $type, $owner, $description, $order, $duedate, 0, $archived, $done);
|
||||||
return new DataResponse($card, HTTP::STATUS_OK);
|
return new DataResponse($card, HTTP::STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,15 +29,14 @@ use OCP\AppFramework\Controller;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class CardController extends Controller {
|
class CardController extends Controller {
|
||||||
private $userId;
|
public function __construct(
|
||||||
private $cardService;
|
$appName,
|
||||||
private $assignmentService;
|
IRequest $request,
|
||||||
|
private CardService $cardService,
|
||||||
public function __construct($appName, IRequest $request, CardService $cardService, AssignmentService $assignmentService, $userId) {
|
private AssignmentService $assignmentService,
|
||||||
|
private $userId,
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->userId = $userId;
|
|
||||||
$this->cardService = $cardService;
|
|
||||||
$this->assignmentService = $assignmentService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,6 +143,24 @@ class CardController extends Controller {
|
|||||||
return $this->cardService->unarchive($cardId);
|
return $this->cardService->unarchive($cardId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @param $cardId
|
||||||
|
* @return \OCP\AppFramework\Db\Entity
|
||||||
|
*/
|
||||||
|
public function done(int $cardId) {
|
||||||
|
return $this->cardService->done($cardId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @param $cardId
|
||||||
|
* @return \OCP\AppFramework\Db\Entity
|
||||||
|
*/
|
||||||
|
public function undone(int $cardId) {
|
||||||
|
return $this->cardService->undone($cardId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @param $cardId
|
* @param $cardId
|
||||||
|
|||||||
@@ -31,18 +31,15 @@ use OCP\AppFramework\OCSController;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class CommentsApiController extends OCSController {
|
class CommentsApiController extends OCSController {
|
||||||
|
|
||||||
/** @var CommentService */
|
|
||||||
private $commentService;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $appName,
|
string $appName,
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
CommentService $commentService,
|
private CommentService $commentService,
|
||||||
string $corsMethods = 'PUT, POST, GET, DELETE, PATCH', string $corsAllowedHeaders = 'Authorization, Content-Type, Accept', int $corsMaxAge = 1728000
|
string $corsMethods = 'PUT, POST, GET, DELETE, PATCH',
|
||||||
|
string $corsAllowedHeaders = 'Authorization, Content-Type, Accept',
|
||||||
|
int $corsMaxAge = 1728000,
|
||||||
) {
|
) {
|
||||||
parent::__construct($appName, $request, $corsMethods, $corsAllowedHeaders, $corsMaxAge);
|
parent::__construct($appName, $request, $corsMethods, $corsAllowedHeaders, $corsMaxAge);
|
||||||
$this->commentService = $commentService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -30,16 +30,12 @@ use OCP\AppFramework\OCSController;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class ConfigController extends OCSController {
|
class ConfigController extends OCSController {
|
||||||
private $configService;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$AppName,
|
$AppName,
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
ConfigService $configService
|
private ConfigService $configService,
|
||||||
) {
|
) {
|
||||||
parent::__construct($AppName, $request);
|
parent::__construct($AppName, $request);
|
||||||
|
|
||||||
$this->configService = $configService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -35,21 +35,18 @@ use OCP\IRequest;
|
|||||||
* @package OCA\Deck\Controller
|
* @package OCA\Deck\Controller
|
||||||
*/
|
*/
|
||||||
class LabelApiController extends ApiController {
|
class LabelApiController extends ApiController {
|
||||||
private $labelService;
|
|
||||||
private $userId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $appName
|
* @param string $appName
|
||||||
* @param IRequest $request
|
|
||||||
* @param LabelService $labelService
|
|
||||||
* @param $userId
|
|
||||||
*/
|
*/
|
||||||
public function __construct($appName, IRequest $request, LabelService $labelService, $userId) {
|
public function __construct(
|
||||||
|
$appName,
|
||||||
|
IRequest $request,
|
||||||
|
private LabelService $labelService,
|
||||||
|
private $userId,
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->labelService = $labelService;
|
|
||||||
$this->userId = $userId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @NoAdminRequired
|
* @NoAdminRequired
|
||||||
* @CORS
|
* @CORS
|
||||||
|
|||||||
@@ -28,11 +28,12 @@ use OCP\AppFramework\Controller;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class LabelController extends Controller {
|
class LabelController extends Controller {
|
||||||
private $labelService;
|
public function __construct(
|
||||||
|
$appName,
|
||||||
public function __construct($appName, IRequest $request, LabelService $labelService) {
|
IRequest $request,
|
||||||
|
private LabelService $labelService,
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->labelService = $labelService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,17 +32,13 @@ use OCP\AppFramework\OCSController;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class OverviewApiController extends OCSController {
|
class OverviewApiController extends OCSController {
|
||||||
|
public function __construct(
|
||||||
/** @var OverviewService */
|
$appName,
|
||||||
private $dashboardService;
|
IRequest $request,
|
||||||
|
private OverviewService $dashboardService,
|
||||||
/** @var string */
|
private $userId,
|
||||||
private $userId;
|
) {
|
||||||
|
|
||||||
public function __construct($appName, IRequest $request, OverviewService $dashboardService, $userId) {
|
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->dashboardService = $dashboardService;
|
|
||||||
$this->userId = $userId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,9 +24,9 @@
|
|||||||
namespace OCA\Deck\Controller;
|
namespace OCA\Deck\Controller;
|
||||||
|
|
||||||
use \OCP\AppFramework\Http\RedirectResponse;
|
use \OCP\AppFramework\Http\RedirectResponse;
|
||||||
use OCA\Deck\AppInfo\Application;
|
|
||||||
use OCA\Deck\Db\Acl;
|
use OCA\Deck\Db\Acl;
|
||||||
use OCA\Deck\Db\CardMapper;
|
use OCA\Deck\Db\CardMapper;
|
||||||
|
use OCA\Deck\Service\BoardService;
|
||||||
use OCA\Deck\Service\CardService;
|
use OCA\Deck\Service\CardService;
|
||||||
use OCA\Deck\Service\ConfigService;
|
use OCA\Deck\Service\ConfigService;
|
||||||
use OCA\Deck\Service\PermissionService;
|
use OCA\Deck\Service\PermissionService;
|
||||||
@@ -34,60 +34,42 @@ use OCA\Files\Event\LoadSidebar;
|
|||||||
use OCA\Text\Event\LoadEditor;
|
use OCA\Text\Event\LoadEditor;
|
||||||
use OCA\Viewer\Event\LoadViewer;
|
use OCA\Viewer\Event\LoadViewer;
|
||||||
use OCP\AppFramework\Controller;
|
use OCP\AppFramework\Controller;
|
||||||
|
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||||
|
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||||
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
|
use OCP\AppFramework\Services\IInitialState;
|
||||||
use OCP\Collaboration\Resources\LoadAdditionalScriptsEvent as CollaborationResourcesEvent;
|
use OCP\Collaboration\Resources\LoadAdditionalScriptsEvent as CollaborationResourcesEvent;
|
||||||
use OCP\EventDispatcher\IEventDispatcher;
|
use OCP\EventDispatcher\IEventDispatcher;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\IInitialStateService;
|
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use OCP\IURLGenerator;
|
use OCP\IURLGenerator;
|
||||||
|
|
||||||
class PageController extends Controller {
|
class PageController extends Controller {
|
||||||
private PermissionService $permissionService;
|
|
||||||
private IInitialStateService $initialState;
|
|
||||||
private ConfigService $configService;
|
|
||||||
private IEventDispatcher $eventDispatcher;
|
|
||||||
private CardMapper $cardMapper;
|
|
||||||
private IURLGenerator $urlGenerator;
|
|
||||||
private CardService $cardService;
|
|
||||||
private IConfig $config;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $AppName,
|
string $AppName,
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
PermissionService $permissionService,
|
private PermissionService $permissionService,
|
||||||
IInitialStateService $initialStateService,
|
private IInitialState $initialState,
|
||||||
ConfigService $configService,
|
private BoardService $boardService,
|
||||||
IEventDispatcher $eventDispatcher,
|
private ConfigService $configService,
|
||||||
CardMapper $cardMapper,
|
private IEventDispatcher $eventDispatcher,
|
||||||
IURLGenerator $urlGenerator,
|
private CardMapper $cardMapper,
|
||||||
CardService $cardService,
|
private IURLGenerator $urlGenerator,
|
||||||
IConfig $config
|
private CardService $cardService,
|
||||||
|
private IConfig $config,
|
||||||
) {
|
) {
|
||||||
parent::__construct($AppName, $request);
|
parent::__construct($AppName, $request);
|
||||||
|
|
||||||
$this->permissionService = $permissionService;
|
|
||||||
$this->initialState = $initialStateService;
|
|
||||||
$this->configService = $configService;
|
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
|
||||||
$this->cardMapper = $cardMapper;
|
|
||||||
$this->urlGenerator = $urlGenerator;
|
|
||||||
$this->cardService = $cardService;
|
|
||||||
$this->config = $config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#[NoAdminRequired]
|
||||||
* Handle main html view from templates/main.php
|
#[NoCSRFRequired]
|
||||||
* This will return the main angular application
|
public function index(): TemplateResponse {
|
||||||
*
|
$this->initialState->provideInitialState('maxUploadSize', (int)\OCP\Util::uploadLimit());
|
||||||
* @NoAdminRequired
|
$this->initialState->provideInitialState('canCreate', $this->permissionService->canCreate());
|
||||||
* @NoCSRFRequired
|
$this->initialState->provideInitialState('config', $this->configService->getAll());
|
||||||
*/
|
|
||||||
public function index() {
|
$this->initialState->provideInitialState('initialBoards', $this->boardService->findAll());
|
||||||
$this->initialState->provideInitialState(Application::APP_ID, 'maxUploadSize', (int)\OCP\Util::uploadLimit());
|
|
||||||
$this->initialState->provideInitialState(Application::APP_ID, 'canCreate', $this->permissionService->canCreate());
|
|
||||||
$this->initialState->provideInitialState(Application::APP_ID, 'config', $this->configService->getAll());
|
|
||||||
|
|
||||||
$this->eventDispatcher->dispatchTyped(new LoadSidebar());
|
$this->eventDispatcher->dispatchTyped(new LoadSidebar());
|
||||||
$this->eventDispatcher->dispatchTyped(new CollaborationResourcesEvent());
|
$this->eventDispatcher->dispatchTyped(new CollaborationResourcesEvent());
|
||||||
@@ -113,10 +95,32 @@ class PageController extends Controller {
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#[NoAdminRequired]
|
||||||
* @NoAdminRequired
|
#[NoCSRFRequired]
|
||||||
* @NoCSRFRequired
|
public function indexList(): TemplateResponse {
|
||||||
*/
|
return $this->index();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[NoAdminRequired]
|
||||||
|
#[NoCSRFRequired]
|
||||||
|
public function indexBoard(int $boardId): TemplateResponse {
|
||||||
|
return $this->index();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[NoAdminRequired]
|
||||||
|
#[NoCSRFRequired]
|
||||||
|
public function indexBoardDetails(int $boardId): TemplateResponse {
|
||||||
|
return $this->index();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[NoAdminRequired]
|
||||||
|
#[NoCSRFRequired]
|
||||||
|
public function indexCard(int $cardId): TemplateResponse {
|
||||||
|
return $this->index();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[NoAdminRequired]
|
||||||
|
#[NoCSRFRequired]
|
||||||
public function redirectToCard($cardId): RedirectResponse {
|
public function redirectToCard($cardId): RedirectResponse {
|
||||||
try {
|
try {
|
||||||
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_READ);
|
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_READ);
|
||||||
|
|||||||
@@ -34,15 +34,12 @@ use OCP\AppFramework\OCSController;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class SearchController extends OCSController {
|
class SearchController extends OCSController {
|
||||||
|
public function __construct(
|
||||||
/**
|
string $appName,
|
||||||
* @var SearchService
|
IRequest $request,
|
||||||
*/
|
private SearchService $searchService,
|
||||||
private $searchService;
|
) {
|
||||||
|
|
||||||
public function __construct(string $appName, IRequest $request, SearchService $searchService) {
|
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->searchService = $searchService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -29,30 +29,23 @@ use OCA\Deck\Db\BoardMapper;
|
|||||||
use OCA\Deck\Service\PermissionService;
|
use OCA\Deck\Service\PermissionService;
|
||||||
use OCA\Deck\Service\SessionService;
|
use OCA\Deck\Service\SessionService;
|
||||||
use OCP\AppFramework\Db\DoesNotExistException;
|
use OCP\AppFramework\Db\DoesNotExistException;
|
||||||
|
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||||
|
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||||
use OCP\AppFramework\Http\DataResponse;
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
use OCP\AppFramework\OCSController;
|
use OCP\AppFramework\OCSController;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class SessionController extends OCSController {
|
class SessionController extends OCSController {
|
||||||
private SessionService $sessionService;
|
|
||||||
private PermissionService $permissionService;
|
|
||||||
private BoardMapper $boardMapper;
|
|
||||||
|
|
||||||
public function __construct($appName,
|
public function __construct($appName,
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
SessionService $sessionService,
|
private SessionService $sessionService,
|
||||||
PermissionService $permissionService,
|
private PermissionService $permissionService,
|
||||||
BoardMapper $boardMapper
|
private BoardMapper $boardMapper,
|
||||||
) {
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->sessionService = $sessionService;
|
|
||||||
$this->permissionService = $permissionService;
|
|
||||||
$this->boardMapper = $boardMapper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#[NoAdminRequired]
|
||||||
* @NoAdminRequired
|
|
||||||
*/
|
|
||||||
public function create(int $boardId): DataResponse {
|
public function create(int $boardId): DataResponse {
|
||||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
||||||
|
|
||||||
@@ -62,11 +55,7 @@ class SessionController extends OCSController {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#[NoAdminRequired]
|
||||||
* notifies the server that the session is still active
|
|
||||||
* @NoAdminRequired
|
|
||||||
* @param $boardId
|
|
||||||
*/
|
|
||||||
public function sync(int $boardId, string $token): DataResponse {
|
public function sync(int $boardId, string $token): DataResponse {
|
||||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
||||||
try {
|
try {
|
||||||
@@ -77,13 +66,12 @@ class SessionController extends OCSController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#[NoAdminRequired]
|
||||||
* delete a session if existing
|
#[NoCSRFRequired]
|
||||||
* @NoAdminRequired
|
public function close(int $boardId, string $token = null): DataResponse {
|
||||||
* @NoCSRFRequired
|
if ($token === null) {
|
||||||
* @param $boardId
|
return new DataResponse();
|
||||||
*/
|
}
|
||||||
public function close(int $boardId, string $token) {
|
|
||||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
||||||
$this->sessionService->closeSession($boardId, $token);
|
$this->sessionService->closeSession($boardId, $token);
|
||||||
return new DataResponse();
|
return new DataResponse();
|
||||||
|
|||||||
@@ -39,18 +39,16 @@ use Sabre\HTTP\Util;
|
|||||||
* @package OCA\Deck\Controller
|
* @package OCA\Deck\Controller
|
||||||
*/
|
*/
|
||||||
class StackApiController extends ApiController {
|
class StackApiController extends ApiController {
|
||||||
private $boardService;
|
|
||||||
private $stackService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $appName
|
* @param string $appName
|
||||||
* @param IRequest $request
|
|
||||||
* @param StackService $stackService
|
|
||||||
*/
|
*/
|
||||||
public function __construct($appName, IRequest $request, StackService $stackService, BoardService $boardService) {
|
public function __construct(
|
||||||
|
$appName,
|
||||||
|
IRequest $request,
|
||||||
|
private StackService $stackService,
|
||||||
|
private BoardService $boardService,
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->stackService = $stackService;
|
|
||||||
$this->boardService = $boardService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -30,12 +30,13 @@ use OCP\AppFramework\Controller;
|
|||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
|
|
||||||
class StackController extends Controller {
|
class StackController extends Controller {
|
||||||
private $userId;
|
public function __construct(
|
||||||
private $stackService;
|
string $appName,
|
||||||
public function __construct($appName, IRequest $request, StackService $stackService, $userId) {
|
IRequest $request,
|
||||||
|
private StackService $stackService,
|
||||||
|
private $userId,
|
||||||
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->userId = $userId;
|
|
||||||
$this->stackService = $stackService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
85
lib/Dashboard/DeckWidgetToday.php
Normal file
85
lib/Dashboard/DeckWidgetToday.php
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @author Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Deck\Dashboard;
|
||||||
|
|
||||||
|
use OCP\Dashboard\IWidget;
|
||||||
|
use OCP\IL10N;
|
||||||
|
|
||||||
|
class DeckWidgetToday implements IWidget {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var IL10N
|
||||||
|
*/
|
||||||
|
private $l10n;
|
||||||
|
|
||||||
|
public function __construct(IL10N $l10n) {
|
||||||
|
$this->l10n = $l10n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getId(): string {
|
||||||
|
return 'deckToday';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getTitle(): string {
|
||||||
|
return $this->l10n->t('Cards due today');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getOrder(): int {
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getIconClass(): string {
|
||||||
|
return 'icon-deck';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getUrl(): ?string {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function load(): void {
|
||||||
|
\OCP\Util::addScript('deck', 'deck-dashboard');
|
||||||
|
}
|
||||||
|
}
|
||||||
85
lib/Dashboard/DeckWidgetTomorrow.php
Normal file
85
lib/Dashboard/DeckWidgetTomorrow.php
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @author Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Deck\Dashboard;
|
||||||
|
|
||||||
|
use OCP\Dashboard\IWidget;
|
||||||
|
use OCP\IL10N;
|
||||||
|
|
||||||
|
class DeckWidgetTomorrow implements IWidget {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var IL10N
|
||||||
|
*/
|
||||||
|
private $l10n;
|
||||||
|
|
||||||
|
public function __construct(IL10N $l10n) {
|
||||||
|
$this->l10n = $l10n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getId(): string {
|
||||||
|
return 'deckTomorrow';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getTitle(): string {
|
||||||
|
return $this->l10n->t('Cards due tomorrow');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getOrder(): int {
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getIconClass(): string {
|
||||||
|
return 'icon-deck';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getUrl(): ?string {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function load(): void {
|
||||||
|
\OCP\Util::addScript('deck', 'deck-dashboard');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,7 +40,7 @@ use OCP\IL10N;
|
|||||||
use OCP\IURLGenerator;
|
use OCP\IURLGenerator;
|
||||||
use OCP\Util;
|
use OCP\Util;
|
||||||
|
|
||||||
class DeckWidget implements IAPIWidget, IButtonWidget, IIconWidget {
|
class DeckWidgetUpcoming implements IAPIWidget, IButtonWidget, IIconWidget {
|
||||||
private IL10N $l10n;
|
private IL10N $l10n;
|
||||||
private OverviewService $dashboardService;
|
private OverviewService $dashboardService;
|
||||||
private IURLGenerator $urlGenerator;
|
private IURLGenerator $urlGenerator;
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||||
*
|
*
|
||||||
@@ -39,6 +42,8 @@ use Sabre\VObject\Component\VCalendar;
|
|||||||
* @method int getDeletedAt()
|
* @method int getDeletedAt()
|
||||||
* @method void setDeletedAt(int $deletedAt)
|
* @method void setDeletedAt(int $deletedAt)
|
||||||
* @method bool getNotified()
|
* @method bool getNotified()
|
||||||
|
* @method ?DateTime getDone()
|
||||||
|
* @method void setDone(?DateTime $done)
|
||||||
*
|
*
|
||||||
* @method void setLabels(Label[] $labels)
|
* @method void setLabels(Label[] $labels)
|
||||||
* @method null|Label[] getLabels()
|
* @method null|Label[] getLabels()
|
||||||
@@ -85,6 +90,7 @@ class Card extends RelationalEntity {
|
|||||||
protected $owner;
|
protected $owner;
|
||||||
protected $order;
|
protected $order;
|
||||||
protected $archived = false;
|
protected $archived = false;
|
||||||
|
protected $done = null;
|
||||||
protected $duedate;
|
protected $duedate;
|
||||||
protected $notified = false;
|
protected $notified = false;
|
||||||
protected $deletedAt = 0;
|
protected $deletedAt = 0;
|
||||||
@@ -108,6 +114,7 @@ class Card extends RelationalEntity {
|
|||||||
$this->addType('lastModified', 'integer');
|
$this->addType('lastModified', 'integer');
|
||||||
$this->addType('createdAt', 'integer');
|
$this->addType('createdAt', 'integer');
|
||||||
$this->addType('archived', 'boolean');
|
$this->addType('archived', 'boolean');
|
||||||
|
$this->addType('done', 'datetime');
|
||||||
$this->addType('notified', 'boolean');
|
$this->addType('notified', 'boolean');
|
||||||
$this->addType('deletedAt', 'integer');
|
$this->addType('deletedAt', 'integer');
|
||||||
$this->addType('duedate', 'datetime');
|
$this->addType('duedate', 'datetime');
|
||||||
@@ -141,19 +148,22 @@ class Card extends RelationalEntity {
|
|||||||
$event->add('RELATED-TO', 'deck-stack-' . $this->getStackId());
|
$event->add('RELATED-TO', 'deck-stack-' . $this->getStackId());
|
||||||
|
|
||||||
// FIXME: For write support: CANCELLED / IN-PROCESS handling
|
// FIXME: For write support: CANCELLED / IN-PROCESS handling
|
||||||
$event->STATUS = $this->getArchived() ? "COMPLETED" : "NEEDS-ACTION";
|
if ($this->getDone() || $this->getArchived()) {
|
||||||
if ($this->getArchived()) {
|
|
||||||
$date = new DateTime();
|
$date = new DateTime();
|
||||||
$date->setTimestamp($this->getLastModified());
|
$date->setTimestamp($this->getLastModified());
|
||||||
$event->COMPLETED = $date;
|
$event->STATUS = 'COMPLETED';
|
||||||
//$event->add('PERCENT-COMPLETE', 100);
|
$event->COMPLETED = $this->getDone() ? $this->getDone() : $this->getArchived();
|
||||||
}
|
} else {
|
||||||
if (count($this->getLabels()) > 0) {
|
$event->STATUS = 'NEEDS-ACTION';
|
||||||
$event->CATEGORIES = array_map(function ($label) {
|
|
||||||
return $label->getTitle();
|
|
||||||
}, $this->getLabels());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $event->add('PERCENT-COMPLETE', 100);
|
||||||
|
|
||||||
|
$labels = $this->getLabels() ?? [];
|
||||||
|
$event->CATEGORIES = array_map(function ($label): string {
|
||||||
|
return $label->getTitle();
|
||||||
|
}, $labels);
|
||||||
|
|
||||||
$event->SUMMARY = $this->getTitle();
|
$event->SUMMARY = $this->getTitle();
|
||||||
$event->DESCRIPTION = $this->getDescription();
|
$event->DESCRIPTION = $this->getDescription();
|
||||||
$calendar->add($event);
|
$calendar->add($event);
|
||||||
@@ -179,7 +189,7 @@ class Card extends RelationalEntity {
|
|||||||
return 'card';
|
return 'card';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getETag() {
|
public function getETag(): string {
|
||||||
return md5((string)$this->getLastModified());
|
return md5((string)$this->getLastModified());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
|||||||
->where($qb->expr()->in('s.board_id', $qb->createNamedParameter($boardIds, IQueryBuilder::PARAM_INT_ARRAY)))
|
->where($qb->expr()->in('s.board_id', $qb->createNamedParameter($boardIds, IQueryBuilder::PARAM_INT_ARRAY)))
|
||||||
->andWhere($qb->expr()->isNotNull('c.duedate'))
|
->andWhere($qb->expr()->isNotNull('c.duedate'))
|
||||||
->andWhere($qb->expr()->eq('c.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
->andWhere($qb->expr()->eq('c.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||||
|
->andWhere($qb->expr()->isNull('done'))
|
||||||
->andWhere($qb->expr()->eq('c.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
->andWhere($qb->expr()->eq('c.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
||||||
->andWhere($qb->expr()->eq('s.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
->andWhere($qb->expr()->eq('s.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
||||||
->andWhere($qb->expr()->eq('b.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
->andWhere($qb->expr()->eq('b.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||||
@@ -284,6 +285,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
|||||||
)
|
)
|
||||||
// Filter out archived/deleted cards and board
|
// Filter out archived/deleted cards and board
|
||||||
->andWhere($qb->expr()->eq('c.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
->andWhere($qb->expr()->eq('c.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||||
|
->andWhere($qb->expr()->isNull('done'))
|
||||||
->andWhere($qb->expr()->eq('c.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
->andWhere($qb->expr()->eq('c.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
||||||
->andWhere($qb->expr()->eq('s.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
->andWhere($qb->expr()->eq('s.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
||||||
->andWhere($qb->expr()->eq('b.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
->andWhere($qb->expr()->eq('b.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||||
@@ -298,6 +300,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
|||||||
->where($qb->expr()->lt('duedate', $qb->createFunction('NOW()')))
|
->where($qb->expr()->lt('duedate', $qb->createFunction('NOW()')))
|
||||||
->andWhere($qb->expr()->eq('notified', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
->andWhere($qb->expr()->eq('notified', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||||
->andWhere($qb->expr()->eq('archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
->andWhere($qb->expr()->eq('archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||||
|
->andWhere($qb->expr()->isNull('done'))
|
||||||
->andWhere($qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
|
->andWhere($qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
|
||||||
return $this->findEntities($qb);
|
return $this->findEntities($qb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class User extends RelationalObject {
|
|||||||
public function getObjectSerialization() {
|
public function getObjectSerialization() {
|
||||||
return [
|
return [
|
||||||
'uid' => $this->getObject()->getUID(),
|
'uid' => $this->getObject()->getUID(),
|
||||||
'displayname' => $this->getObject()->getDisplayName(),
|
'displayname' => $this->getDisplayName(),
|
||||||
'type' => Acl::PERMISSION_TYPE_USER
|
'type' => Acl::PERMISSION_TYPE_USER
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
61
lib/Migration/Version1011Date20230901010840.php
Normal file
61
lib/Migration/Version1011Date20230901010840.php
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2023 Thanos kamber <thanos.kamber@gmail.com>
|
||||||
|
*
|
||||||
|
* @author Thanos kamber <thanos.kamber@gmail.com>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Deck\Migration;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use OCP\DB\ISchemaWrapper;
|
||||||
|
use OCP\DB\Types;
|
||||||
|
use OCP\Migration\IOutput;
|
||||||
|
use OCP\Migration\SimpleMigrationStep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated migration step: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
class Version1011Date20230901010840 extends SimpleMigrationStep {
|
||||||
|
/**
|
||||||
|
* @param IOutput $output
|
||||||
|
* @param Closure $schemaClosure
|
||||||
|
* @param array $options
|
||||||
|
* @return null|ISchemaWrapper
|
||||||
|
*/
|
||||||
|
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
|
||||||
|
/** @var ISchemaWrapper $schema */
|
||||||
|
$schema = $schemaClosure();
|
||||||
|
|
||||||
|
$table = $schema->getTable('deck_cards');
|
||||||
|
if (!$table->hasColumn('done')) {
|
||||||
|
$table->addColumn('done', Types::DATETIME, [
|
||||||
|
'default' => null,
|
||||||
|
'notnull' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ use OCP\Migration\IOutput;
|
|||||||
use OCP\Migration\SimpleMigrationStep;
|
use OCP\Migration\SimpleMigrationStep;
|
||||||
|
|
||||||
class Version1011Date20231106160059 extends SimpleMigrationStep {
|
class Version1011Date20231106160059 extends SimpleMigrationStep {
|
||||||
|
|
||||||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
|
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
|
||||||
$schema = $schemaClosure();
|
$schema = $schemaClosure();
|
||||||
|
|
||||||
|
|||||||
51
lib/Model/OptionalNullableValue.php
Normal file
51
lib/Model/OptionalNullableValue.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2023 Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @author Julius Härtl <jus@bitgrid.net>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Deck\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a helper abstraction to allow usage of optional parameters
|
||||||
|
* which hold a nullable value. The actual null value of the parameter
|
||||||
|
* is used to indicate if it has been set or not. The containing value
|
||||||
|
* will then still allow having null as a value
|
||||||
|
*
|
||||||
|
* Example use case: Have a nullable database column,
|
||||||
|
* but only update it if it is passed
|
||||||
|
*
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
class OptionalNullableValue {
|
||||||
|
|
||||||
|
/** @var ?T */
|
||||||
|
private mixed $value;
|
||||||
|
|
||||||
|
/** @param ?T $value */
|
||||||
|
public function __construct(mixed $value) {
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return ?T */
|
||||||
|
public function getValue(): mixed {
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -55,8 +55,8 @@ class BoardReferenceProvider implements IReferenceProvider {
|
|||||||
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
|
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
|
||||||
|
|
||||||
// link example: https://nextcloud.local/index.php/apps/deck/#/board/2
|
// link example: https://nextcloud.local/index.php/apps/deck/#/board/2
|
||||||
$noIndexMatch = preg_match('/^' . preg_quote($start, '/') . '\/#\/board\/[0-9]+$/', $referenceText) === 1;
|
$noIndexMatch = preg_match('/^' . preg_quote($start, '/') . '(?:\/#!?)?\/board\/[0-9]+$/', $referenceText) === 1;
|
||||||
$indexMatch = preg_match('/^' . preg_quote($startIndex, '/') . '\/#\/board\/[0-9]+$/', $referenceText) === 1;
|
$indexMatch = preg_match('/^' . preg_quote($startIndex, '/') . '(?:\/#!?)?\/board\/[0-9]+$/', $referenceText) === 1;
|
||||||
|
|
||||||
return $noIndexMatch || $indexMatch;
|
return $noIndexMatch || $indexMatch;
|
||||||
}
|
}
|
||||||
@@ -108,9 +108,9 @@ class BoardReferenceProvider implements IReferenceProvider {
|
|||||||
$start = $this->urlGenerator->getAbsoluteURL('/apps/' . Application::APP_ID);
|
$start = $this->urlGenerator->getAbsoluteURL('/apps/' . Application::APP_ID);
|
||||||
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
|
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
|
||||||
|
|
||||||
preg_match('/^' . preg_quote($start, '/') . '\/#\/board\/([0-9]+)$/', $url, $matches);
|
preg_match('/^' . preg_quote($start, '/') . '(?:\/#!?)?\/board\/([0-9]+)$/', $url, $matches);
|
||||||
if (!$matches) {
|
if (!$matches) {
|
||||||
preg_match('/^' . preg_quote($startIndex, '/') . '\/#\/board\/([0-9]+)$/', $url, $matches);
|
preg_match('/^' . preg_quote($startIndex, '/') . '(?:\/#!?)?\/board\/([0-9]+)$/', $url, $matches);
|
||||||
}
|
}
|
||||||
if ($matches && count($matches) > 1) {
|
if ($matches && count($matches) > 1) {
|
||||||
return (int) $matches[1];
|
return (int) $matches[1];
|
||||||
|
|||||||
@@ -108,8 +108,8 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
|||||||
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
|
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
|
||||||
|
|
||||||
// link example: https://nextcloud.local/index.php/apps/deck/#/board/2/card/11
|
// link example: https://nextcloud.local/index.php/apps/deck/#/board/2/card/11
|
||||||
$noIndexMatchFull = preg_match('/^' . preg_quote($start, '/') . '\/#\/board\/[0-9]+\/card\/[0-9]+$/', $referenceText) === 1;
|
$noIndexMatchFull = preg_match('/^' . preg_quote($start, '/') . '(?:\/#!?)?\/board\/[0-9]+\/card\/[0-9]+$/', $referenceText) === 1;
|
||||||
$indexMatchFull = preg_match('/^' . preg_quote($startIndex, '/') . '\/#\/board\/[0-9]+\/card\/[0-9]+$/', $referenceText) === 1;
|
$indexMatchFull = preg_match('/^' . preg_quote($startIndex, '/') . '(?:\/#!?)?\/board\/[0-9]+\/card\/[0-9]+$/', $referenceText) === 1;
|
||||||
|
|
||||||
// link example: https://nextcloud.local/index.php/apps/deck/card/11
|
// link example: https://nextcloud.local/index.php/apps/deck/card/11
|
||||||
$noIndexMatch = preg_match('/^' . preg_quote($start, '/') . '\/card\/[0-9]+$/', $referenceText) === 1;
|
$noIndexMatch = preg_match('/^' . preg_quote($start, '/') . '\/card\/[0-9]+$/', $referenceText) === 1;
|
||||||
@@ -125,16 +125,17 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
|||||||
if ($this->matchReference($referenceText)) {
|
if ($this->matchReference($referenceText)) {
|
||||||
$ids = $this->getBoardCardId($referenceText);
|
$ids = $this->getBoardCardId($referenceText);
|
||||||
if ($ids !== null) {
|
if ($ids !== null) {
|
||||||
[$boardId, $cardId] = $ids;
|
[, $cardId] = $ids;
|
||||||
try {
|
try {
|
||||||
$card = $this->cardService->find((int) $cardId)->jsonSerialize();
|
$card = $this->cardService->find((int) $cardId)->jsonSerialize();
|
||||||
$stack = $this->stackService->find((int) $card['stackId'])->jsonSerialize();
|
$stack = $this->stackService->find((int) $card['stackId'])->jsonSerialize();
|
||||||
$board = $this->boardService->find((int)($boardId ?? $stack['boardId']))->jsonSerialize();
|
$board = $this->boardService->find((int) $stack['boardId'])->jsonSerialize();
|
||||||
} catch (NoPermissionException $e) {
|
} catch (NoPermissionException $e) {
|
||||||
// Skip throwing if user has no permissions
|
// Skip throwing if user has no permissions
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$boardId = $board['id'];
|
||||||
|
|
||||||
$card = $this->sanitizeSerializedCard($card);
|
$card = $this->sanitizeSerializedCard($card);
|
||||||
$board = $this->sanitizeSerializedBoard($board);
|
$board = $this->sanitizeSerializedBoard($board);
|
||||||
@@ -159,14 +160,14 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
|||||||
$result = $cardDetails->jsonSerialize();
|
$result = $cardDetails->jsonSerialize();
|
||||||
unset($result['assignedUsers']);
|
unset($result['assignedUsers']);
|
||||||
return $result;
|
return $result;
|
||||||
}, $stack['cards']);
|
}, $stack['cards'] ?? []);
|
||||||
|
|
||||||
return $stack;
|
return $stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sanitizeSerializedBoard(array $board): array {
|
private function sanitizeSerializedBoard(array $board): array {
|
||||||
unset($board['labels']);
|
unset($board['labels']);
|
||||||
$board['owner'] = $board['owner']->jsonSerialize();
|
$board['owner'] = $board['owner']?->jsonSerialize();
|
||||||
unset($board['acl']);
|
unset($board['acl']);
|
||||||
unset($board['users']);
|
unset($board['users']);
|
||||||
|
|
||||||
@@ -176,18 +177,18 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
|||||||
private function sanitizeSerializedCard(array $card): array {
|
private function sanitizeSerializedCard(array $card): array {
|
||||||
$card['labels'] = array_map(function (Label $label) {
|
$card['labels'] = array_map(function (Label $label) {
|
||||||
return $label->jsonSerialize();
|
return $label->jsonSerialize();
|
||||||
}, $card['labels']);
|
}, $card['labels'] ?? []);
|
||||||
$card['assignedUsers'] = array_map(function (Assignment $assignment) {
|
$card['assignedUsers'] = array_map(function (Assignment $assignment) {
|
||||||
$result = $assignment->jsonSerialize();
|
$result = $assignment->jsonSerialize();
|
||||||
$result['participant'] = $result['participant']->jsonSerialize();
|
$result['participant'] = $result['participant']->jsonSerialize();
|
||||||
return $result;
|
return $result;
|
||||||
}, $card['assignedUsers']);
|
}, $card['assignedUsers'] ?? []);
|
||||||
$card['owner'] = $card['owner']->jsonSerialize();
|
$card['owner'] = $card['owner']?->jsonSerialize() ?? $card['owner'];
|
||||||
unset($card['relatedStack']);
|
unset($card['relatedStack']);
|
||||||
unset($card['relatedBoard']);
|
unset($card['relatedBoard']);
|
||||||
$card['attachments'] = array_map(function (Attachment $attachment) {
|
$card['attachments'] = array_map(function (Attachment $attachment) {
|
||||||
return $attachment->jsonSerialize();
|
return $attachment->jsonSerialize();
|
||||||
}, $card['attachments']);
|
}, $card['attachments'] ?? []);
|
||||||
|
|
||||||
return $card;
|
return $card;
|
||||||
}
|
}
|
||||||
@@ -196,12 +197,12 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
|||||||
$start = $this->urlGenerator->getAbsoluteURL('/apps/' . Application::APP_ID);
|
$start = $this->urlGenerator->getAbsoluteURL('/apps/' . Application::APP_ID);
|
||||||
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
|
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
|
||||||
|
|
||||||
preg_match('/^' . preg_quote($start, '/') . '\/#\/board\/([0-9]+)\/card\/([0-9]+)$/', $url, $matches);
|
preg_match('/^' . preg_quote($start, '/') . '(?:\/#!?)?\/board\/([0-9]+)\/card\/([0-9]+)$/', $url, $matches);
|
||||||
if ($matches && count($matches) > 2) {
|
if ($matches && count($matches) > 2) {
|
||||||
return [$matches[1], $matches[2]];
|
return [$matches[1], $matches[2]];
|
||||||
}
|
}
|
||||||
|
|
||||||
preg_match('/^' . preg_quote($startIndex, '/') . '\/#\/board\/([0-9]+)\/card\/([0-9]+)$/', $url, $matches2);
|
preg_match('/^' . preg_quote($startIndex, '/') . '(?:\/#!?)?\/board\/([0-9]+)\/card\/([0-9]+)$/', $url, $matches2);
|
||||||
if ($matches2 && count($matches2) > 2) {
|
if ($matches2 && count($matches2) > 2) {
|
||||||
return [$matches2[1], $matches2[2]];
|
return [$matches2[1], $matches2[2]];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use OCP\IL10N;
|
|||||||
use OCP\IURLGenerator;
|
use OCP\IURLGenerator;
|
||||||
|
|
||||||
class CreateCardReferenceProvider extends ADiscoverableReferenceProvider {
|
class CreateCardReferenceProvider extends ADiscoverableReferenceProvider {
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private IL10N $l10n,
|
private IL10N $l10n,
|
||||||
private IURLGenerator $urlGenerator,
|
private IURLGenerator $urlGenerator,
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ use OCA\Deck\Event\CardCreatedEvent;
|
|||||||
use OCA\Deck\Event\CardDeletedEvent;
|
use OCA\Deck\Event\CardDeletedEvent;
|
||||||
use OCA\Deck\Event\CardUpdatedEvent;
|
use OCA\Deck\Event\CardUpdatedEvent;
|
||||||
use OCA\Deck\Model\CardDetails;
|
use OCA\Deck\Model\CardDetails;
|
||||||
|
use OCA\Deck\Model\OptionalNullableValue;
|
||||||
use OCA\Deck\NoPermissionException;
|
use OCA\Deck\NoPermissionException;
|
||||||
use OCA\Deck\Notification\NotificationHelper;
|
use OCA\Deck\Notification\NotificationHelper;
|
||||||
use OCA\Deck\StatusException;
|
use OCA\Deck\StatusException;
|
||||||
@@ -284,6 +285,9 @@ class CardService {
|
|||||||
* @param $description
|
* @param $description
|
||||||
* @param $order
|
* @param $order
|
||||||
* @param $duedate
|
* @param $duedate
|
||||||
|
* @param $deletedAt
|
||||||
|
* @param $archived
|
||||||
|
* @param $done
|
||||||
* @return \OCP\AppFramework\Db\Entity
|
* @return \OCP\AppFramework\Db\Entity
|
||||||
* @throws StatusException
|
* @throws StatusException
|
||||||
* @throws \OCA\Deck\NoPermissionException
|
* @throws \OCA\Deck\NoPermissionException
|
||||||
@@ -291,7 +295,7 @@ class CardService {
|
|||||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||||
* @throws BadRequestException
|
* @throws BadRequestException
|
||||||
*/
|
*/
|
||||||
public function update($id, $title, $stackId, $type, $owner, $description = '', $order = 0, $duedate = null, $deletedAt = null, $archived = null) {
|
public function update($id, $title, $stackId, $type, $owner, $description = '', $order = 0, $duedate = null, $deletedAt = null, $archived = null, ?OptionalNullableValue $done = null) {
|
||||||
$this->cardServiceValidator->check(compact('id', 'title', 'stackId', 'type', 'owner', 'order'));
|
$this->cardServiceValidator->check(compact('id', 'title', 'stackId', 'type', 'owner', 'order'));
|
||||||
|
|
||||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT, allowDeletedCard: true);
|
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT, allowDeletedCard: true);
|
||||||
@@ -349,6 +353,11 @@ class CardService {
|
|||||||
if ($archived !== null) {
|
if ($archived !== null) {
|
||||||
$card->setArchived($archived);
|
$card->setArchived($archived);
|
||||||
}
|
}
|
||||||
|
if ($done !== null) {
|
||||||
|
$card->setDone($done->getValue());
|
||||||
|
} else {
|
||||||
|
$card->setDone(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Trigger update events before setting description as it is handled separately
|
// Trigger update events before setting description as it is handled separately
|
||||||
@@ -519,6 +528,57 @@ class CardService {
|
|||||||
return $newCard;
|
return $newCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $id
|
||||||
|
* @return \OCA\Deck\Db\Card
|
||||||
|
* @throws StatusException
|
||||||
|
* @throws \OCA\Deck\NoPermissionException
|
||||||
|
* @throws \OCP\AppFramework\Db\DoesNotExistException
|
||||||
|
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||||
|
* @throws BadRequestException
|
||||||
|
*/
|
||||||
|
public function done(int $id): Card {
|
||||||
|
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
|
||||||
|
if ($this->boardService->isArchived($this->cardMapper, $id)) {
|
||||||
|
throw new StatusException('Operation not allowed. This board is archived.');
|
||||||
|
}
|
||||||
|
$card = $this->cardMapper->find($id);
|
||||||
|
$card->setDone(new \DateTime());
|
||||||
|
$newCard = $this->cardMapper->update($card);
|
||||||
|
$this->notificationHelper->markDuedateAsRead($card);
|
||||||
|
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_DONE);
|
||||||
|
$this->changeHelper->cardChanged($id, false);
|
||||||
|
|
||||||
|
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
|
||||||
|
|
||||||
|
return $newCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $id
|
||||||
|
* @return \OCA\Deck\Db\Card
|
||||||
|
* @throws StatusException
|
||||||
|
* @throws \OCA\Deck\NoPermissionException
|
||||||
|
* @throws \OCP\AppFramework\Db\DoesNotExistException
|
||||||
|
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||||
|
* @throws BadRequestException
|
||||||
|
*/
|
||||||
|
public function undone(int $id): Card {
|
||||||
|
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
|
||||||
|
if ($this->boardService->isArchived($this->cardMapper, $id)) {
|
||||||
|
throw new StatusException('Operation not allowed. This board is archived.');
|
||||||
|
}
|
||||||
|
$card = $this->cardMapper->find($id);
|
||||||
|
$card->setDone(null);
|
||||||
|
$newCard = $this->cardMapper->update($card);
|
||||||
|
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_UNDONE);
|
||||||
|
$this->changeHelper->cardChanged($id, false);
|
||||||
|
|
||||||
|
$this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card));
|
||||||
|
|
||||||
|
return $newCard;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $cardId
|
* @param $cardId
|
||||||
* @param $labelId
|
* @param $labelId
|
||||||
|
|||||||
@@ -190,8 +190,7 @@ class CommentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function formatComment(IComment $comment, $addReplyTo = false): array {
|
private function formatComment(IComment $comment, $addReplyTo = false): array {
|
||||||
$user = $this->userManager->get($comment->getActorId());
|
$actorDisplayName = $this->userManager->getDisplayName($comment->getActorId()) ?? $comment->getActorId();
|
||||||
$actorDisplayName = $user !== null ? $user->getDisplayName() : $comment->getActorId();
|
|
||||||
|
|
||||||
$formattedComment = [
|
$formattedComment = [
|
||||||
'id' => (int)$comment->getId(),
|
'id' => (int)$comment->getId(),
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ class ConfigService {
|
|||||||
return $this->config->getUserValue($userId ?? $this->getUserId(), 'deck', 'attachment_folder', '/Deck');
|
return $this->config->getUserValue($userId ?? $this->getUserId(), 'deck', 'attachment_folder', '/Deck');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAttachmentFolder(?string $userId, string $path): void {
|
public function setAttachmentFolder(?string $userId = null, string $path): void {
|
||||||
if ($userId === null && $this->getUserId() === null) {
|
if ($userId === null && $this->getUserId() === null) {
|
||||||
throw new NoPermissionException('Must be logged in get the attachment folder');
|
throw new NoPermissionException('Must be logged in get the attachment folder');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ class BoardImportService {
|
|||||||
$this->getImportSystem()->updateAcl($code, $acl);
|
$this->getImportSystem()->updateAcl($code, $acl);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->addError('Failed to import acl rule for ' . $acl->getParticipant(), $e);
|
$this->addError('Failed to import acl rule for ' . $acl->getParticipant(), $e);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->getBoard()->setAcl($aclList);
|
$this->getBoard()->setAcl($aclList);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
},
|
},
|
||||||
"token": {
|
"token": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^[0-9a-fA-F]{64}$"
|
"pattern": "^[0-9a-fA-FT]{64,76}$"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -115,8 +115,7 @@ class SearchService {
|
|||||||
$card = Card::fromRow($cardRow);
|
$card = Card::fromRow($cardRow);
|
||||||
// TODO: Only perform one enrich call here
|
// TODO: Only perform one enrich call here
|
||||||
$self->cardService->enrichCards([$card]);
|
$self->cardService->enrichCards([$card]);
|
||||||
$user = $this->userManager->get($comment->getActorId());
|
$displayName = $this->userManager->getDisplayName($comment->getActorId()) ?? '';
|
||||||
$displayName = $user ? $user->getDisplayName() : '';
|
|
||||||
return new CommentSearchResultEntry($comment->getId(), $comment->getMessage(), $displayName, $card, $this->urlGenerator, $this->l10n);
|
return new CommentSearchResultEntry($comment->getId(), $comment->getMessage(), $displayName, $card, $this->urlGenerator, $this->l10n);
|
||||||
}, $matchedComments);
|
}, $matchedComments);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ use OC\Files\Filesystem;
|
|||||||
use OCA\Deck\Service\ConfigService;
|
use OCA\Deck\Service\ConfigService;
|
||||||
use OCP\EventDispatcher\IEventDispatcher;
|
use OCP\EventDispatcher\IEventDispatcher;
|
||||||
use OCP\Server;
|
use OCP\Server;
|
||||||
|
use OCP\Share\Events\BeforeShareCreatedEvent;
|
||||||
use OCP\Share\Events\VerifyMountPointEvent;
|
use OCP\Share\Events\VerifyMountPointEvent;
|
||||||
use OCP\Share\IShare;
|
use OCP\Share\IShare;
|
||||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
|
||||||
|
|
||||||
class Listener {
|
class Listener {
|
||||||
private ConfigService $configService;
|
private ConfigService $configService;
|
||||||
@@ -45,11 +45,11 @@ class Listener {
|
|||||||
/**
|
/**
|
||||||
* @psalm-suppress UndefinedClass
|
* @psalm-suppress UndefinedClass
|
||||||
*/
|
*/
|
||||||
$dispatcher->addListener('OCP\Share::preShare', [self::class, 'listenPreShare'], 1000);
|
$dispatcher->addListener(BeforeShareCreatedEvent::class, [self::class, 'listenPreShare'], 1000);
|
||||||
$dispatcher->addListener(VerifyMountPointEvent::class, [self::class, 'listenVerifyMountPointEvent'], 1000);
|
$dispatcher->addListener(VerifyMountPointEvent::class, [self::class, 'listenVerifyMountPointEvent'], 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function listenPreShare(GenericEvent $event): void {
|
public static function listenPreShare(BeforeShareCreatedEvent $event): void {
|
||||||
/** @var self $listener */
|
/** @var self $listener */
|
||||||
$listener = Server::get(self::class);
|
$listener = Server::get(self::class);
|
||||||
$listener->overwriteShareTarget($event);
|
$listener->overwriteShareTarget($event);
|
||||||
@@ -61,9 +61,8 @@ class Listener {
|
|||||||
$listener->overwriteMountPoint($event);
|
$listener->overwriteMountPoint($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function overwriteShareTarget(GenericEvent $event): void {
|
public function overwriteShareTarget(BeforeShareCreatedEvent $event): void {
|
||||||
/** @var IShare $share */
|
$share = $event->getShare();
|
||||||
$share = $event->getSubject();
|
|
||||||
|
|
||||||
if ($share->getShareType() !== IShare::TYPE_DECK
|
if ($share->getShareType() !== IShare::TYPE_DECK
|
||||||
&& $share->getShareType() !== DeckShareProvider::SHARE_TYPE_DECK_USER) {
|
&& $share->getShareType() !== DeckShareProvider::SHARE_TYPE_DECK_USER) {
|
||||||
|
|||||||
3594
package-lock.json
generated
3594
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
63
package.json
63
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "deck",
|
"name": "deck",
|
||||||
"description": "",
|
"description": "",
|
||||||
"version": "1.11.5",
|
"version": "1.12.3",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Julius Härtl",
|
"name": "Julius Härtl",
|
||||||
@@ -31,29 +31,30 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/polyfill": "^7.12.1",
|
"@babel/polyfill": "^7.12.1",
|
||||||
"@babel/runtime": "^7.21.5",
|
"@babel/runtime": "^7.23.2",
|
||||||
"@nextcloud/auth": "^2.0.0",
|
"@nextcloud/auth": "^2.2.1",
|
||||||
"@nextcloud/axios": "^2.3.0",
|
"@nextcloud/axios": "^2.4.0",
|
||||||
"@nextcloud/dialogs": "^4.0.1",
|
"@nextcloud/dialogs": "^4.2.2",
|
||||||
"@nextcloud/event-bus": "^3.0.2",
|
"@nextcloud/event-bus": "^3.1.0",
|
||||||
"@nextcloud/files": "^2.1.0",
|
"@nextcloud/files": "^3.0.0",
|
||||||
"@nextcloud/initial-state": "^2.0.0",
|
"@nextcloud/initial-state": "^2.1.0",
|
||||||
"@nextcloud/l10n": "^2.1.0",
|
"@nextcloud/l10n": "^2.2.0",
|
||||||
"@nextcloud/moment": "^1.2.1",
|
"@nextcloud/moment": "^1.2.2",
|
||||||
"@nextcloud/notify_push": "^1.1.3",
|
"@nextcloud/notify_push": "^1.1.3",
|
||||||
"@nextcloud/router": "^2.1.1",
|
"@nextcloud/router": "^2.2.0",
|
||||||
"@nextcloud/vue": "^7.11.4",
|
"@nextcloud/vue": "^7.12.6",
|
||||||
"blueimp-md5": "^2.19.0",
|
"blueimp-md5": "^2.19.0",
|
||||||
"dompurify": "^3.0.3",
|
"chroma-js": "^2.4.2",
|
||||||
|
"dompurify": "^3.0.6",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"markdown-it": "^13.0.1",
|
"markdown-it": "^13.0.2",
|
||||||
"markdown-it-link-attributes": "^4.0.1",
|
"markdown-it-link-attributes": "^4.0.1",
|
||||||
"markdown-it-task-checkbox": "^1.0.6",
|
"markdown-it-task-checkbox": "^1.0.6",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"nextcloud-vue-collections": "^0.11.1",
|
"nextcloud-vue-collections": "^0.11.1",
|
||||||
"p-queue": "^7.3.4",
|
"p-queue": "^7.4.1",
|
||||||
"url-search-params-polyfill": "^8.1.1",
|
"url-search-params-polyfill": "^8.2.5",
|
||||||
"vue": "^2.7.14",
|
"vue": "^2.7.15",
|
||||||
"vue-at": "^2.5.1",
|
"vue-at": "^2.5.1",
|
||||||
"vue-click-outside": "^1.1.0",
|
"vue-click-outside": "^1.1.0",
|
||||||
"vue-easymde": "^2.0.0",
|
"vue-easymde": "^2.0.0",
|
||||||
@@ -68,26 +69,26 @@
|
|||||||
"extends @nextcloud/browserslist-config"
|
"extends @nextcloud/browserslist-config"
|
||||||
],
|
],
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^16.0.0",
|
"node": "^20.0.0",
|
||||||
"npm": "^7.0.0 || ^8.0.0"
|
"npm": "^9.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nextcloud/babel-config": "^1.0.0",
|
"@nextcloud/babel-config": "^1.0.0",
|
||||||
"@nextcloud/browserslist-config": "^2.3.0",
|
"@nextcloud/browserslist-config": "^3.0.0",
|
||||||
"@nextcloud/cypress": "^1.0.0-beta.2",
|
"@nextcloud/cypress": "^1.0.0-beta.6",
|
||||||
"@nextcloud/eslint-config": "^8.2.1",
|
"@nextcloud/eslint-config": "^8.3.0",
|
||||||
"@nextcloud/stylelint-config": "^2.3.0",
|
"@nextcloud/stylelint-config": "^2.3.1",
|
||||||
"@nextcloud/webpack-vue-config": "^5.5.1",
|
"@nextcloud/webpack-vue-config": "^6.0.0",
|
||||||
"@relative-ci/agent": "^4.1.4",
|
"@relative-ci/agent": "^4.2.1",
|
||||||
"@vue/test-utils": "^1.3.5",
|
"@vue/test-utils": "^1.3.6",
|
||||||
"@vue/vue2-jest": "^29.2.4",
|
"@vue/vue2-jest": "^29.2.6",
|
||||||
"cypress": "^12.12.0",
|
"cypress": "^13.5.1",
|
||||||
"eslint-plugin-cypress": "^2.13.3",
|
"eslint-plugin-cypress": "^2.15.1",
|
||||||
"eslint-webpack-plugin": "^4.0.1",
|
"eslint-webpack-plugin": "^4.0.1",
|
||||||
"jest": "^29.5.0",
|
"jest": "^29.7.0",
|
||||||
"jest-serializer-vue": "^3.1.0",
|
"jest-serializer-vue": "^3.1.0",
|
||||||
"stylelint-webpack-plugin": "^4.1.1",
|
"stylelint-webpack-plugin": "^4.1.1",
|
||||||
"vue-template-compiler": "^2.7.14"
|
"vue-template-compiler": "^2.7.15"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"moduleFileExtensions": [
|
"moduleFileExtensions": [
|
||||||
|
|||||||
10
psalm.xml
10
psalm.xml
@@ -4,7 +4,7 @@
|
|||||||
resolveFromConfigFile="true"
|
resolveFromConfigFile="true"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns="https://getpsalm.org/schema/config"
|
xmlns="https://getpsalm.org/schema/config"
|
||||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
xsi:schemaLocation="https://getpsalm.org/schema/config"
|
||||||
errorBaseline="tests/psalm-baseline.xml"
|
errorBaseline="tests/psalm-baseline.xml"
|
||||||
>
|
>
|
||||||
<stubs>
|
<stubs>
|
||||||
@@ -18,9 +18,6 @@
|
|||||||
</projectFiles>
|
</projectFiles>
|
||||||
<extraFiles>
|
<extraFiles>
|
||||||
<directory name="vendor" />
|
<directory name="vendor" />
|
||||||
<ignoreFiles>
|
|
||||||
<directory name="vendor/phpunit/php-code-coverage" />
|
|
||||||
</ignoreFiles>
|
|
||||||
</extraFiles>
|
</extraFiles>
|
||||||
<issueHandlers>
|
<issueHandlers>
|
||||||
<UndefinedMagicMethod>
|
<UndefinedMagicMethod>
|
||||||
@@ -40,6 +37,10 @@
|
|||||||
<referencedClass name="OC\*" />
|
<referencedClass name="OC\*" />
|
||||||
<referencedClass name="OC" />
|
<referencedClass name="OC" />
|
||||||
<referencedClass name="OC\Security\CSP\ContentSecurityPolicyNonceManager" />
|
<referencedClass name="OC\Security\CSP\ContentSecurityPolicyNonceManager" />
|
||||||
|
<referencedClass name="Symfony\Component\Console\Command\Command" />
|
||||||
|
<referencedClass name="Symfony\Component\Console\Question\ChoiceQuestion" />
|
||||||
|
<referencedClass name="Symfony\Component\Console\Question\Question" />
|
||||||
|
<referencedClass name="Symfony\Component\EventDispatcher\GenericEvent" />
|
||||||
</errorLevel>
|
</errorLevel>
|
||||||
</UndefinedClass>
|
</UndefinedClass>
|
||||||
<UndefinedDocblockClass>
|
<UndefinedDocblockClass>
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
<referencedClass name="Doctrine\DBAL\Driver\Statement" />
|
<referencedClass name="Doctrine\DBAL\Driver\Statement" />
|
||||||
<referencedClass name="Doctrine\DBAL\Schema\Table" />
|
<referencedClass name="Doctrine\DBAL\Schema\Table" />
|
||||||
<referencedClass name="OC\Security\CSP\ContentSecurityPolicyNonceManager" />
|
<referencedClass name="OC\Security\CSP\ContentSecurityPolicyNonceManager" />
|
||||||
|
<referencedClass name="Symfony\Component\Console\Command\Command" />
|
||||||
</errorLevel>
|
</errorLevel>
|
||||||
</UndefinedDocblockClass>
|
</UndefinedDocblockClass>
|
||||||
</issueHandlers>
|
</issueHandlers>
|
||||||
|
|||||||
12
src/App.vue
12
src/App.vue
@@ -40,25 +40,32 @@
|
|||||||
|
|
||||||
<router-view name="sidebar" :visible="!cardDetailsInModal || !$route.params.cardId" />
|
<router-view name="sidebar" :visible="!cardDetailsInModal || !$route.params.cardId" />
|
||||||
</div>
|
</div>
|
||||||
|
<KeyboardShortcuts />
|
||||||
|
<CardMoveDialog />
|
||||||
</NcContent>
|
</NcContent>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import AppNavigation from './components/navigation/AppNavigation.vue'
|
import AppNavigation from './components/navigation/AppNavigation.vue'
|
||||||
|
import KeyboardShortcuts from './components/KeyboardShortcuts.vue'
|
||||||
import { NcModal, NcContent, NcAppContent } from '@nextcloud/vue'
|
import { NcModal, NcContent, NcAppContent } from '@nextcloud/vue'
|
||||||
import { BoardApi } from './services/BoardApi.js'
|
import { BoardApi } from './services/BoardApi.js'
|
||||||
import { emit, subscribe } from '@nextcloud/event-bus'
|
import { emit, subscribe } from '@nextcloud/event-bus'
|
||||||
|
import { loadState } from '@nextcloud/initial-state'
|
||||||
|
import CardMoveDialog from './CardMoveDialog.vue'
|
||||||
|
|
||||||
const boardApi = new BoardApi()
|
const boardApi = new BoardApi()
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
|
CardMoveDialog,
|
||||||
AppNavigation,
|
AppNavigation,
|
||||||
NcModal,
|
NcModal,
|
||||||
NcContent,
|
NcContent,
|
||||||
NcAppContent,
|
NcAppContent,
|
||||||
|
KeyboardShortcuts,
|
||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
@@ -108,7 +115,10 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.$store.dispatch('loadBoards')
|
const initialState = loadState('deck', 'initialBoards', null)
|
||||||
|
if (initialState !== null) {
|
||||||
|
this.$store.dispatch('loadBoards')
|
||||||
|
}
|
||||||
this.$store.dispatch('loadSharees')
|
this.$store.dispatch('loadSharees')
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
107
src/CardMoveDialog.vue
Normal file
107
src/CardMoveDialog.vue
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<template>
|
||||||
|
<NcModal v-if="modalShow" :title="t('deck', 'Move card to another board')" @close="modalShow=false">
|
||||||
|
<div class="modal__content">
|
||||||
|
<h3>{{ t('deck', 'Move card to another board') }}</h3>
|
||||||
|
<NcMultiselect v-model="selectedBoard"
|
||||||
|
:placeholder="t('deck', 'Select a board')"
|
||||||
|
:options="activeBoards"
|
||||||
|
:max-height="100"
|
||||||
|
label="title"
|
||||||
|
@select="loadStacksFromBoard" />
|
||||||
|
<NcMultiselect v-model="selectedStack"
|
||||||
|
:placeholder="t('deck', 'Select a list')"
|
||||||
|
:options="stacksFromBoard"
|
||||||
|
:max-height="100"
|
||||||
|
label="title">
|
||||||
|
<span slot="noOptions">
|
||||||
|
{{ t('deck', 'List is empty') }}
|
||||||
|
</span>
|
||||||
|
</NcMultiselect>
|
||||||
|
|
||||||
|
<button :disabled="!isBoardAndStackChoosen" class="primary" @click="moveCard">
|
||||||
|
{{ t('deck', 'Move card') }}
|
||||||
|
</button>
|
||||||
|
<button @click="modalShow=false">
|
||||||
|
{{ t('deck', 'Cancel') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</NcModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { NcModal, NcMultiselect } from '@nextcloud/vue'
|
||||||
|
import { generateUrl } from '@nextcloud/router'
|
||||||
|
import axios from '@nextcloud/axios'
|
||||||
|
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CardMoveDialog',
|
||||||
|
components: { NcModal, NcMultiselect },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
card: null,
|
||||||
|
modalShow: false,
|
||||||
|
selectedBoard: '',
|
||||||
|
selectedStack: '',
|
||||||
|
stacksFromBoard: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
activeBoards() {
|
||||||
|
return this.$store.getters.boards.filter((item) => item.deletedAt === 0 && item.archived === false)
|
||||||
|
},
|
||||||
|
isBoardAndStackChoosen() {
|
||||||
|
return !(this.selectedBoard === '' || this.selectedStack === '')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
subscribe('deck:card:show-move-dialog', this.openModal)
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
unsubscribe('deck:card:show-move-dialog', this.openModal)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openModal(card) {
|
||||||
|
this.card = card
|
||||||
|
this.modalShow = true
|
||||||
|
},
|
||||||
|
async loadStacksFromBoard(board) {
|
||||||
|
try {
|
||||||
|
const url = generateUrl('/apps/deck/stacks/' + board.id)
|
||||||
|
const response = await axios.get(url)
|
||||||
|
this.stacksFromBoard = response.data
|
||||||
|
} catch (err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async moveCard() {
|
||||||
|
this.copiedCard = Object.assign({}, this.card)
|
||||||
|
this.copiedCard.stackId = this.selectedStack.id
|
||||||
|
this.$store.dispatch('moveCard', this.copiedCard)
|
||||||
|
if (parseInt(this.boardId) === parseInt(this.selectedStack.boardId)) {
|
||||||
|
await this.$store.commit('addNewCard', { ...this.copiedCard })
|
||||||
|
}
|
||||||
|
this.modalShow = false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.modal__content {
|
||||||
|
width: 25vw;
|
||||||
|
min-width: 250px;
|
||||||
|
min-height: 120px;
|
||||||
|
text-align: center;
|
||||||
|
margin: 20px 20px 100px 20px;
|
||||||
|
|
||||||
|
.multiselect {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal__content button {
|
||||||
|
float: right;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -22,21 +22,25 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
|
<NcModal v-if="showAddCardModal" class="card-selector" @close="clickHideAddCardModel">
|
||||||
|
<CreateNewCardCustomPicker show-created-notice @cancel="clickHideAddCardModel" />
|
||||||
|
</NcModal>
|
||||||
<div v-if="overviewName" class="board-title">
|
<div v-if="overviewName" class="board-title">
|
||||||
<div class="board-bullet icon-calendar-dark" />
|
<div class="board-bullet icon-calendar-dark" />
|
||||||
<h2>{{ overviewName }}</h2>
|
<h2 dir="auto">
|
||||||
|
{{ overviewName }}
|
||||||
|
</h2>
|
||||||
<NcActions>
|
<NcActions>
|
||||||
<NcActionButton icon="icon-add" @click="clickShowAddCardModel">
|
<NcActionButton icon="icon-add" @click="clickShowAddCardModel">
|
||||||
{{ t('deck', 'Add card') }}
|
{{ t('deck', 'Add card') }}
|
||||||
</NcActionButton>
|
</NcActionButton>
|
||||||
</NcActions>
|
</NcActions>
|
||||||
<NcModal v-if="showAddCardModal" class="card-selector" @close="clickHideAddCardModel">
|
|
||||||
<CreateNewCardCustomPicker show-created-notice @cancel="clickHideAddCardModel" />
|
|
||||||
</NcModal>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="board" class="board-title">
|
<div v-else-if="board" class="board-title">
|
||||||
<div :style="{backgroundColor: '#' + board.color}" class="board-bullet" />
|
<div :style="{backgroundColor: '#' + board.color}" class="board-bullet" />
|
||||||
<h2>{{ board.title }}</h2>
|
<h2 dir="auto">
|
||||||
|
{{ board.title }}
|
||||||
|
</h2>
|
||||||
<p v-if="showArchived">
|
<p v-if="showArchived">
|
||||||
({{ t('deck', 'Archived cards') }})
|
({{ t('deck', 'Archived cards') }})
|
||||||
</p>
|
</p>
|
||||||
@@ -45,9 +49,14 @@
|
|||||||
<SessionList v-if="isNotifyPushEnabled && presentUsers.length"
|
<SessionList v-if="isNotifyPushEnabled && presentUsers.length"
|
||||||
:sessions="presentUsers" />
|
:sessions="presentUsers" />
|
||||||
<div v-if="searchQuery || true" class="deck-search">
|
<div v-if="searchQuery || true" class="deck-search">
|
||||||
<input type="search"
|
<input id="deck-search-input"
|
||||||
|
ref="search"
|
||||||
|
:tabindex="0"
|
||||||
|
type="search"
|
||||||
class="icon-search"
|
class="icon-search"
|
||||||
:value="searchQuery"
|
:value="searchQuery"
|
||||||
|
@focus="$store.dispatch('toggleShortcutLock', true)"
|
||||||
|
@blur="$store.dispatch('toggleShortcutLock', false)"
|
||||||
@input="$store.commit('setSearchQuery', $event.target.value)">
|
@input="$store.commit('setSearchQuery', $event.target.value)">
|
||||||
</div>
|
</div>
|
||||||
<div v-if="board && canManage && !showArchived && !board.archived"
|
<div v-if="board && canManage && !showArchived && !board.archived"
|
||||||
@@ -66,7 +75,9 @@
|
|||||||
type="text"
|
type="text"
|
||||||
class="no-close"
|
class="no-close"
|
||||||
:placeholder="t('deck', 'List name')"
|
:placeholder="t('deck', 'List name')"
|
||||||
required>
|
required
|
||||||
|
@focus="$store.dispatch('toggleShortcutLock', true)"
|
||||||
|
@blur="$store.dispatch('toggleShortcutLock', false)">
|
||||||
<input v-tooltip="t('deck', 'Add list')"
|
<input v-tooltip="t('deck', 'Add list')"
|
||||||
class="icon-confirm"
|
class="icon-confirm"
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -78,13 +89,16 @@
|
|||||||
<NcPopover container=".board-action-buttons__filter"
|
<NcPopover container=".board-action-buttons__filter"
|
||||||
:placement="'bottom-end'"
|
:placement="'bottom-end'"
|
||||||
:aria-label="t('deck', 'Active filters')"
|
:aria-label="t('deck', 'Active filters')"
|
||||||
|
:title="t('deck', 'Active filters')"
|
||||||
|
:tooltip="t('deck', 'Active filters')"
|
||||||
@show="filterVisible=true"
|
@show="filterVisible=true"
|
||||||
@hide="filterVisible=false">
|
@hide="filterVisible=false">
|
||||||
<!-- We cannot use NcActions here are the popover trigger does not update on reactive icons -->
|
<!-- We cannot use NcActions here are the popover trigger does not update on reactive icons -->
|
||||||
<NcButton slot="trigger"
|
<NcButton slot="trigger"
|
||||||
|
ref="filterPopover"
|
||||||
:title="t('deck', 'Apply filter')"
|
:title="t('deck', 'Apply filter')"
|
||||||
class="filter-button"
|
class="filter-button"
|
||||||
type="tertiary-no-background">
|
:type="isFilterActive ? 'primary' : 'tertiary'">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<FilterIcon v-if="isFilterActive" :size="20" decorative />
|
<FilterIcon v-if="isFilterActive" :size="20" decorative />
|
||||||
<FilterOffIcon v-else :size="20" decorative />
|
<FilterOffIcon v-else :size="20" decorative />
|
||||||
@@ -188,7 +202,8 @@
|
|||||||
</NcPopover>
|
</NcPopover>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<NcActions>
|
<NcActions :aria-label="t('deck', 'View Modes')"
|
||||||
|
:title="t('deck', 'Toggle View Modes')">
|
||||||
<NcActionButton @click="toggleShowArchived">
|
<NcActionButton @click="toggleShowArchived">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<ArchiveIcon :size="20" decorative />
|
<ArchiveIcon :size="20" decorative />
|
||||||
@@ -205,6 +220,12 @@
|
|||||||
<ArrowCollapseVerticalIcon slot="icon" :size="20" decorative />
|
<ArrowCollapseVerticalIcon slot="icon" :size="20" decorative />
|
||||||
{{ t('deck', 'Toggle compact mode') }}
|
{{ t('deck', 'Toggle compact mode') }}
|
||||||
</NcActionButton>
|
</NcActionButton>
|
||||||
|
<NcActionButton @click="toggleShowCardCover">
|
||||||
|
<template #icon>
|
||||||
|
<ImageIcon :size="20" decorative />
|
||||||
|
</template>
|
||||||
|
{{ showCardCover ? t('deck', 'Hide card cover images') : t('deck', 'Show card cover images') }}
|
||||||
|
</NcActionButton>
|
||||||
</NcActions>
|
</NcActions>
|
||||||
<!-- FIXME: NcActionRouter currently doesn't work as an inline action -->
|
<!-- FIXME: NcActionRouter currently doesn't work as an inline action -->
|
||||||
<NcActions>
|
<NcActions>
|
||||||
@@ -220,9 +241,11 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapGetters } from 'vuex'
|
import { mapState, mapGetters } from 'vuex'
|
||||||
|
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||||
import { NcActions, NcActionButton, NcAvatar, NcButton, NcPopover, NcModal } from '@nextcloud/vue'
|
import { NcActions, NcActionButton, NcAvatar, NcButton, NcPopover, NcModal } from '@nextcloud/vue'
|
||||||
import labelStyle from '../mixins/labelStyle.js'
|
import labelStyle from '../mixins/labelStyle.js'
|
||||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||||
|
import ImageIcon from 'vue-material-design-icons/ImageMultiple.vue'
|
||||||
import FilterIcon from 'vue-material-design-icons/Filter.vue'
|
import FilterIcon from 'vue-material-design-icons/Filter.vue'
|
||||||
import FilterOffIcon from 'vue-material-design-icons/FilterOff.vue'
|
import FilterOffIcon from 'vue-material-design-icons/FilterOff.vue'
|
||||||
import ArrowCollapseVerticalIcon from 'vue-material-design-icons/ArrowCollapseVertical.vue'
|
import ArrowCollapseVerticalIcon from 'vue-material-design-icons/ArrowCollapseVertical.vue'
|
||||||
@@ -230,6 +253,7 @@ import ArrowExpandVerticalIcon from 'vue-material-design-icons/ArrowExpandVertic
|
|||||||
import SessionList from './SessionList.vue'
|
import SessionList from './SessionList.vue'
|
||||||
import { isNotifyPushEnabled } from '../sessions.js'
|
import { isNotifyPushEnabled } from '../sessions.js'
|
||||||
import CreateNewCardCustomPicker from '../views/CreateNewCardCustomPicker.vue'
|
import CreateNewCardCustomPicker from '../views/CreateNewCardCustomPicker.vue'
|
||||||
|
import { getCurrentUser } from '@nextcloud/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Controls',
|
name: 'Controls',
|
||||||
@@ -242,6 +266,7 @@ export default {
|
|||||||
NcPopover,
|
NcPopover,
|
||||||
NcAvatar,
|
NcAvatar,
|
||||||
ArchiveIcon,
|
ArchiveIcon,
|
||||||
|
ImageIcon,
|
||||||
FilterIcon,
|
FilterIcon,
|
||||||
FilterOffIcon,
|
FilterOffIcon,
|
||||||
ArrowCollapseVerticalIcon,
|
ArrowCollapseVerticalIcon,
|
||||||
@@ -282,6 +307,7 @@ export default {
|
|||||||
]),
|
]),
|
||||||
...mapState({
|
...mapState({
|
||||||
compactMode: state => state.compactMode,
|
compactMode: state => state.compactMode,
|
||||||
|
showCardCover: state => state.showCardCover,
|
||||||
searchQuery: state => state.searchQuery,
|
searchQuery: state => state.searchQuery,
|
||||||
}),
|
}),
|
||||||
detailsRoute() {
|
detailsRoute() {
|
||||||
@@ -311,7 +337,18 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
beforeMount() {
|
||||||
|
subscribe('deck:board:show-new-card', this.clickShowAddCardModel)
|
||||||
|
subscribe('deck:board:toggle-filter-popover', this.triggerOpenFilters)
|
||||||
|
subscribe('deck:board:clear-filter', this.triggerClearFilter)
|
||||||
|
subscribe('deck:board:toggle-filter-by-me', this.triggerFilterByMe)
|
||||||
|
|
||||||
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
unsubscribe('deck:board:show-new-card', this.clickShowAddCardModel)
|
||||||
|
unsubscribe('deck:board:toggle-filter-popover', this.triggerOpenFilters)
|
||||||
|
unsubscribe('deck:board:clear-filter', this.triggerClearFilter)
|
||||||
|
unsubscribe('deck:board:toggle-filter-by-me', this.triggerFilterByMe)
|
||||||
this.setPageTitle('')
|
this.setPageTitle('')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -336,6 +373,9 @@ export default {
|
|||||||
toggleCompactMode() {
|
toggleCompactMode() {
|
||||||
this.$store.dispatch('toggleCompactMode')
|
this.$store.dispatch('toggleCompactMode')
|
||||||
},
|
},
|
||||||
|
toggleShowCardCover() {
|
||||||
|
this.$store.dispatch('toggleShowCardCover')
|
||||||
|
},
|
||||||
toggleShowArchived() {
|
toggleShowArchived() {
|
||||||
this.$store.dispatch('toggleShowArchived')
|
this.$store.dispatch('toggleShowArchived')
|
||||||
this.showArchived = !this.showArchived
|
this.showArchived = !this.showArchived
|
||||||
@@ -387,6 +427,23 @@ export default {
|
|||||||
}
|
}
|
||||||
window.document.title = newTitle
|
window.document.title = newTitle
|
||||||
},
|
},
|
||||||
|
triggerOpenFilters() {
|
||||||
|
this.$refs.filterPopover.$el.click()
|
||||||
|
},
|
||||||
|
triggerOpenSearch() {
|
||||||
|
this.$refs.search.focus()
|
||||||
|
},
|
||||||
|
triggerClearFilter() {
|
||||||
|
this.clearFilter()
|
||||||
|
},
|
||||||
|
triggerFilterByMe() {
|
||||||
|
if (this.isFilterActive) {
|
||||||
|
this.clearFilter()
|
||||||
|
} else {
|
||||||
|
this.filter.users = [getCurrentUser().uid]
|
||||||
|
this.setFilter()
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -490,8 +547,11 @@ export default {
|
|||||||
width: 44px;
|
width: 44px;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
|
|
||||||
&:hover, &:focus {
|
&[data-popper-shown] {
|
||||||
background-color: rgba(127,127,127,0.25) !important;
|
background-color: var(--color-background-hover);
|
||||||
|
&.button-vue--vue-primary {
|
||||||
|
background-color: var(--color-primary-element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
279
src/components/KeyboardShortcuts.vue
Normal file
279
src/components/KeyboardShortcuts.vue
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
<template>
|
||||||
|
<!-- :style="{top:cardTop, left:cardLeft}" -->
|
||||||
|
<div v-if="card && selector"
|
||||||
|
ref="shortcutModal"
|
||||||
|
v-click-outside="close"
|
||||||
|
class="keyboard-shortcuts__modal"
|
||||||
|
tabindex="0"
|
||||||
|
@keydown.esc="close">
|
||||||
|
<CardItem :card="card" />
|
||||||
|
<DueDateSelector v-if="selector === 'due-date'" :card="card" :can-edit="true" />
|
||||||
|
<TagSelector v-if="selector === 'tag'" :card="card" :can-edit="true" />
|
||||||
|
<AssignmentSelector v-if="selector === 'assignment'" :card="card" :can-edit="true" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import DueDateSelector from './card/DueDateSelector.vue'
|
||||||
|
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
import TagSelector from './card/TagSelector.vue'
|
||||||
|
import AssignmentSelector from './card/AssignmentSelector.vue'
|
||||||
|
import CardItem from './cards/CardItem.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'KeyboardShortcuts',
|
||||||
|
components: {
|
||||||
|
DueDateSelector,
|
||||||
|
TagSelector,
|
||||||
|
AssignmentSelector,
|
||||||
|
CardItem,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
card: null,
|
||||||
|
cardTop: null,
|
||||||
|
cardLeft: null,
|
||||||
|
selector: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
board: state => state.currentBoard,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
document.addEventListener('keydown', this.onKeydown)
|
||||||
|
subscribe('deck:card:show-assignment-selector', this.handleShowAssignemnt)
|
||||||
|
subscribe('deck:card:show-due-date-selector', this.handleShowDueDate)
|
||||||
|
subscribe('deck:card:show-label-selector', this.handleShowLabel)
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
document.removeEventListener('keydown', this.onKeydown)
|
||||||
|
unsubscribe('deck:card:show-assignment-selector', this.handleShowAssignemnt)
|
||||||
|
unsubscribe('deck:card:show-due-date-selector', this.handleShowDueDate)
|
||||||
|
unsubscribe('deck:card:show-label-selector', this.handleShowLabel)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onKeydown(key) {
|
||||||
|
if (OCP.Accessibility.disableKeyboardShortcuts()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'].includes(key.target.tagName) || key.target.isContentEditable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Global shortcuts (not board specific)
|
||||||
|
if ((key.metaKey || key.ctrlKey) && key.code === 'KeyF') {
|
||||||
|
const searchInput = document.getElementById('deck-search-input')
|
||||||
|
if (searchInput === document.activeElement) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('deck-search-input').focus()
|
||||||
|
key.preventDefault()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (key.code === 'Minus') {
|
||||||
|
emit('deck:global:toggle-help-dialog')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.$store.state.shortcutLock || key.shiftKey || key.ctrlKey || key.altKey || key.metaKey) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.$route.name === 'card' && key.code === 'Escape') {
|
||||||
|
this.$router.push({ name: 'board' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Board specific shortcuts
|
||||||
|
if (!this.board) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (key.code) {
|
||||||
|
case 'KeyN':
|
||||||
|
emit('deck:board:show-new-card', this.board.id)
|
||||||
|
break
|
||||||
|
case 'KeyF':
|
||||||
|
emit('deck:board:toggle-filter-popover', this.board.id)
|
||||||
|
break
|
||||||
|
case 'KeyX':
|
||||||
|
emit('deck:board:clear-filter', this.board.id)
|
||||||
|
break
|
||||||
|
case 'KeyQ':
|
||||||
|
emit('deck:board:toggle-filter-by-me', this.board.id)
|
||||||
|
break
|
||||||
|
case 'ArrowDown':
|
||||||
|
this.keyboardFocusDown()
|
||||||
|
break
|
||||||
|
case 'ArrowUp':
|
||||||
|
this.keyboardFocusUp()
|
||||||
|
break
|
||||||
|
case 'ArrowLeft':
|
||||||
|
this.keyboardFocusLeft()
|
||||||
|
break
|
||||||
|
case 'ArrowRight':
|
||||||
|
this.keyboardFocusRight()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
key.preventDefault()
|
||||||
|
},
|
||||||
|
keyboardFocusDown() {
|
||||||
|
const activeCard = document.activeElement.closest('.card')
|
||||||
|
const cards = document.querySelectorAll('.card')
|
||||||
|
const stacks = document.querySelectorAll('.stack')
|
||||||
|
const index = Array.from(cards).findIndex(card => card === activeCard)
|
||||||
|
if (index === -1) {
|
||||||
|
cards[0]?.focus()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentStack = Array.from(stacks).find(stack => stack.contains(document.activeElement))
|
||||||
|
const currentStackCards = currentStack.querySelectorAll('.card')
|
||||||
|
const currentStackIndex = Array.from(currentStackCards).findIndex(card => card === document.activeElement)
|
||||||
|
|
||||||
|
if (currentStackIndex === currentStackCards.length - 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cards[index + 1]?.focus()
|
||||||
|
cards[index + 1]?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
|
||||||
|
},
|
||||||
|
|
||||||
|
keyboardFocusUp() {
|
||||||
|
const activeCard = document.activeElement.closest('.card')
|
||||||
|
const cards = document.querySelectorAll('.card')
|
||||||
|
const stacks = document.querySelectorAll('.stack')
|
||||||
|
const index = Array.from(cards).findIndex(card => card === activeCard)
|
||||||
|
if (index === -1) {
|
||||||
|
cards[0]?.focus()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentStack = Array.from(stacks).find(stack => stack.contains(document.activeElement))
|
||||||
|
const currentStackCards = currentStack.querySelectorAll('.card')
|
||||||
|
const currentStackIndex = Array.from(currentStackCards).findIndex(card => card === document.activeElement)
|
||||||
|
|
||||||
|
if (currentStackIndex === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cards[index - 1]?.focus()
|
||||||
|
cards[index - 1]?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
|
||||||
|
},
|
||||||
|
keyboardFocusLeft() {
|
||||||
|
const activeCard = document.activeElement.closest('.card')
|
||||||
|
const stacks = document.querySelectorAll('.stack')
|
||||||
|
const currentStackIndex = Array.from(stacks).findIndex(stack => stack.contains(activeCard))
|
||||||
|
|
||||||
|
if (!currentStackIndex === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextStack = stacks[currentStackIndex - 1] ?? stacks[0]
|
||||||
|
|
||||||
|
const currentCardTopOffset = document.activeElement.getBoundingClientRect().top
|
||||||
|
|
||||||
|
// iterate over all next stack cards and remember the one with the smallest offset
|
||||||
|
const nextStackCards = nextStack.querySelectorAll('.card')
|
||||||
|
let nextCard = null
|
||||||
|
for (const card of nextStackCards) {
|
||||||
|
const cardTopOffset = card.getBoundingClientRect().bottom
|
||||||
|
if (cardTopOffset < currentCardTopOffset) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
nextCard = card
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nextCard) {
|
||||||
|
nextCard = nextStackCards[nextStackCards.length - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
nextCard?.focus()
|
||||||
|
nextCard?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
|
||||||
|
},
|
||||||
|
keyboardFocusRight() {
|
||||||
|
const activeCard = document.activeElement.closest('.card')
|
||||||
|
const stacks = document.querySelectorAll('.stack')
|
||||||
|
const currentStackIndex = Array.from(stacks).findIndex(stack => stack.contains(activeCard))
|
||||||
|
|
||||||
|
if (currentStackIndex === stacks.length - 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextStack = stacks[currentStackIndex + 1]
|
||||||
|
|
||||||
|
const currentCardTopOffset = document.activeElement.getBoundingClientRect().top
|
||||||
|
|
||||||
|
// iterate over all next stack cards and remember the one with the smallest offset
|
||||||
|
const nextStackCards = nextStack.querySelectorAll('.card')
|
||||||
|
let nextCard = null
|
||||||
|
for (const card of nextStackCards) {
|
||||||
|
const cardTopOffset = card.getBoundingClientRect().bottom
|
||||||
|
if (cardTopOffset < currentCardTopOffset) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
nextCard = card
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nextCard) {
|
||||||
|
nextCard = nextStackCards[nextStackCards.length - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
nextCard?.focus()
|
||||||
|
nextCard?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
|
||||||
|
},
|
||||||
|
handleShowDueDate({ card, element }) {
|
||||||
|
// this.cardTop = element.getBoundingClientRect().top + 'px'
|
||||||
|
// this.cardLeft = element.getBoundingClientRect().left + 'px'
|
||||||
|
this.card = card
|
||||||
|
this.selector = 'due-date'
|
||||||
|
this.$refs.shortcutModal?.focus()
|
||||||
|
},
|
||||||
|
handleShowAssignemnt({ card, element }) {
|
||||||
|
// this.cardTop = element.getBoundingClientRect().top + 'px'
|
||||||
|
// this.cardLeft = element.getBoundingClientRect().left + 'px'
|
||||||
|
this.card = card
|
||||||
|
this.selector = 'assignment'
|
||||||
|
this.$refs.shortcutModal?.focus()
|
||||||
|
},
|
||||||
|
handleShowLabel({ card, element }) {
|
||||||
|
// this.cardTop = element.getBoundingClientRect().top + 'px'
|
||||||
|
// this.cardLeft = element.getBoundingClientRect().left + 'px'
|
||||||
|
this.card = card
|
||||||
|
this.selector = 'tag'
|
||||||
|
this.$refs.shortcutModal?.focus()
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.card = null
|
||||||
|
this.selector = null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.keyboard-shortcuts__modal {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 9999;
|
||||||
|
box-shadow: 0 0 100px 30px rgba(0, 0, 0, 0.5);
|
||||||
|
max-width: 500px;
|
||||||
|
bottom: 32px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background-color: var(--color-background-dark);
|
||||||
|
border-radius: var(--border-radius-rounded);
|
||||||
|
padding: 24px 32px;
|
||||||
|
width: 100%;
|
||||||
|
border: 2px solid var(--color-border-maxcontrast);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="board-wrapper">
|
<div class="board-wrapper" :tabindex="-1">
|
||||||
<Controls :board="board" />
|
<Controls :board="board" />
|
||||||
|
|
||||||
<transition name="fade" mode="out-in">
|
<transition name="fade" mode="out-in">
|
||||||
@@ -59,7 +59,11 @@
|
|||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
</NcEmptyContent>
|
</NcEmptyContent>
|
||||||
<div v-else-if="!isEmpty && !loading" key="board" class="board">
|
<div v-else-if="!isEmpty && !loading"
|
||||||
|
key="board"
|
||||||
|
ref="board"
|
||||||
|
class="board"
|
||||||
|
@mousedown="onMouseDown">
|
||||||
<Container lock-axix="y"
|
<Container lock-axix="y"
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
:drag-handle-selector="dragHandleSelector"
|
:drag-handle-selector="dragHandleSelector"
|
||||||
@@ -70,6 +74,7 @@
|
|||||||
<Draggable v-for="stack in stacksByBoard"
|
<Draggable v-for="stack in stacksByBoard"
|
||||||
:key="stack.id"
|
:key="stack.id"
|
||||||
data-click-closes-sidebar="true"
|
data-click-closes-sidebar="true"
|
||||||
|
data-dragscroll-enabled
|
||||||
class="stack-draggable-wrapper">
|
class="stack-draggable-wrapper">
|
||||||
<Stack :stack="stack" :dragging="draggingStack" data-click-closes-sidebar="true" />
|
<Stack :stack="stack" :dragging="draggingStack" data-click-closes-sidebar="true" />
|
||||||
</Draggable>
|
</Draggable>
|
||||||
@@ -81,7 +86,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import { Container, Draggable } from 'vue-smooth-dnd'
|
import { Container, Draggable } from 'vue-smooth-dnd'
|
||||||
import { mapState, mapGetters } from 'vuex'
|
import { mapState, mapGetters } from 'vuex'
|
||||||
import Controls from '../Controls.vue'
|
import Controls from '../Controls.vue'
|
||||||
@@ -117,6 +121,8 @@ export default {
|
|||||||
draggingStack: false,
|
draggingStack: false,
|
||||||
loading: true,
|
loading: true,
|
||||||
newStackTitle: '',
|
newStackTitle: '',
|
||||||
|
currentScrollPosX: null,
|
||||||
|
currentMousePosX: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -183,12 +189,40 @@ export default {
|
|||||||
this.$store.dispatch('createStack', newStack)
|
this.$store.dispatch('createStack', newStack)
|
||||||
this.newStackTitle = ''
|
this.newStackTitle = ''
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onMouseDown(event) {
|
||||||
|
this.startMouseDrag(event)
|
||||||
|
},
|
||||||
|
|
||||||
|
startMouseDrag(event) {
|
||||||
|
if (!('dragscrollEnabled' in event.target.dataset)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault()
|
||||||
|
this.currentMousePosX = event.clientX
|
||||||
|
this.currentScrollPosX = this.$refs.board.scrollLeft
|
||||||
|
window.addEventListener('mousemove', this.handleMouseDrag)
|
||||||
|
window.addEventListener('mouseup', this.stopMouseDrag)
|
||||||
|
window.addEventListener('mouseleave', this.stopMouseDrag)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMouseDrag(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
const deltaX = event.clientX - this.currentMousePosX
|
||||||
|
this.$refs.board.scrollLeft = this.currentScrollPosX - deltaX
|
||||||
|
},
|
||||||
|
|
||||||
|
stopMouseDrag(event) {
|
||||||
|
window.removeEventListener('mousemove', this.handleMouseDrag)
|
||||||
|
window.removeEventListener('mouseup', this.stopMouseDrag)
|
||||||
|
window.removeEventListener('mouseleave', this.stopMouseDrag)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
@import '../../css/animations';
|
@import '../../css/animations';
|
||||||
@import '../../css/variables';
|
@import '../../css/variables';
|
||||||
|
|
||||||
@@ -248,9 +282,9 @@ export default {
|
|||||||
padding: $stack-spacing;
|
padding: $stack-spacing;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
scrollbar-gutter: stable;
|
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
margin-top: -10px;
|
margin-top: -10px;
|
||||||
|
scrollbar-gutter: stable;
|
||||||
}
|
}
|
||||||
|
|
||||||
.smooth-dnd-container.vertical > .smooth-dnd-draggable-wrapper {
|
.smooth-dnd-container.vertical > .smooth-dnd-draggable-wrapper {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
<NcAppSidebarTab v-if="hasActivity"
|
<NcAppSidebarTab v-if="hasActivity"
|
||||||
id="activity"
|
id="activity"
|
||||||
:order="3"
|
:order="3"
|
||||||
:name="t('deck', 'Timeline')">
|
:name="t('deck', 'Activity')">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<ActivityIcon :size="20" />
|
<ActivityIcon :size="20" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li v-for="deletedStack in deletedStacks" :key="deletedStack.id">
|
<li v-for="deletedStack in deletedStacks" :key="deletedStack.id">
|
||||||
<span class="icon icon-deck" />
|
<span class="icon icon-deck" />
|
||||||
<div class="title">
|
<div class="title" dir="auto">
|
||||||
<span>{{ deletedStack.title }}</span>
|
<span>{{ deletedStack.title }}</span>
|
||||||
<span class="timestamp">{{ relativeDate(deletedStack.deletedAt*1000) }}</span>
|
<span class="timestamp">{{ relativeDate(deletedStack.deletedAt*1000) }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li v-for="deletedCard in deletedCards" :key="deletedCard.id">
|
<li v-for="deletedCard in deletedCards" :key="deletedCard.id">
|
||||||
<div class="icon icon-deck" />
|
<div class="icon icon-deck" />
|
||||||
<div class="title">
|
<div class="title" dir="auto">
|
||||||
<span>{{ deletedCard.title }}</span>
|
<span>{{ deletedCard.title }}</span>
|
||||||
<span class="timestamp">{{ relativeDate(deletedCard.deletedAt*1000) }}</span>
|
<span class="timestamp">{{ relativeDate(deletedCard.deletedAt*1000) }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -26,14 +26,14 @@
|
|||||||
<div v-click-outside="stopCardCreation"
|
<div v-click-outside="stopCardCreation"
|
||||||
class="stack__header"
|
class="stack__header"
|
||||||
:class="{'stack__header--add': showAddCard}"
|
:class="{'stack__header--add': showAddCard}"
|
||||||
tabindex="0"
|
|
||||||
:aria-label="stack.title">
|
:aria-label="stack.title">
|
||||||
<transition name="fade" mode="out-in">
|
<transition name="fade" mode="out-in">
|
||||||
<h3 v-if="!canManage || isArchived">
|
<h3 v-if="!canManage || isArchived" tabindex="0">
|
||||||
{{ stack.title }}
|
{{ stack.title }}
|
||||||
</h3>
|
</h3>
|
||||||
<h3 v-else-if="!editing"
|
<h3 v-else-if="!editing"
|
||||||
v-tooltip="stack.title"
|
v-tooltip="stack.title"
|
||||||
|
dir="auto"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
:aria-label="stack.title"
|
:aria-label="stack.title"
|
||||||
class="stack__title"
|
class="stack__title"
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
@keyup.esc="cancelEdit">
|
@keyup.esc="cancelEdit">
|
||||||
<input v-model="copiedStack.title"
|
<input v-model="copiedStack.title"
|
||||||
v-focus
|
v-focus
|
||||||
|
dir="auto"
|
||||||
type="text"
|
type="text"
|
||||||
required="required">
|
required="required">
|
||||||
<input v-tooltip="t('deck', 'Edit list title')"
|
<input v-tooltip="t('deck', 'Edit list title')"
|
||||||
@@ -131,6 +132,7 @@
|
|||||||
data-click-closes-sidebar="true"
|
data-click-closes-sidebar="true"
|
||||||
non-drag-area-selector=".dragDisabled"
|
non-drag-area-selector=".dragDisabled"
|
||||||
:drag-handle-selector="dragHandleSelector"
|
:drag-handle-selector="dragHandleSelector"
|
||||||
|
data-dragscroll-enabled
|
||||||
@should-accept-drop="canEdit"
|
@should-accept-drop="canEdit"
|
||||||
@drag-start="draggingCard = true"
|
@drag-start="draggingCard = true"
|
||||||
@drag-end="draggingCard = false"
|
@drag-end="draggingCard = false"
|
||||||
@@ -328,8 +330,6 @@ export default {
|
|||||||
|
|
||||||
.stack {
|
.stack {
|
||||||
width: $stack-width + $stack-spacing * 3;
|
width: $stack-width + $stack-spacing * 3;
|
||||||
margin-left: math.div($stack-spacing, 2);
|
|
||||||
margin-right: math.div($stack-spacing, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.stack__header {
|
.stack__header {
|
||||||
@@ -338,6 +338,7 @@ export default {
|
|||||||
top: 0;
|
top: 0;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
padding-left: $card-spacing;
|
padding-left: $card-spacing;
|
||||||
|
padding-right: $card-spacing;
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
|
|
||||||
@@ -346,10 +347,10 @@ export default {
|
|||||||
content: ' ';
|
content: ' ';
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: calc(100% - 16px);
|
||||||
height: 20px;
|
height: 20px;
|
||||||
top: 30px;
|
top: 30px;
|
||||||
right: 10px;
|
left: 0px;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
transition: top var(--animation-slow);
|
transition: top var(--animation-slow);
|
||||||
|
|
||||||
@@ -409,7 +410,7 @@ export default {
|
|||||||
z-index: 100;
|
z-index: 100;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 8px;
|
||||||
background-color: var(--color-main-background);
|
background-color: var(--color-main-background);
|
||||||
|
|
||||||
form {
|
form {
|
||||||
@@ -417,7 +418,7 @@ export default {
|
|||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: 0 0 3px var(--color-box-shadow);
|
border: 2px solid var(--color-border);
|
||||||
border-radius: var(--border-radius-large);
|
border-radius: var(--border-radius-large);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
|||||||
@@ -5,7 +5,10 @@
|
|||||||
<!-- Edit Tag -->
|
<!-- Edit Tag -->
|
||||||
<template v-if="editingLabelId === label.id">
|
<template v-if="editingLabelId === label.id">
|
||||||
<form class="label-form" @submit.prevent="updateLabel(label)">
|
<form class="label-form" @submit.prevent="updateLabel(label)">
|
||||||
<NcColorPicker class="color-picker-wrapper" :value="'#' + editingLabel.color" @input="updateColor">
|
<NcColorPicker class="color-picker-wrapper"
|
||||||
|
:value="'#' + editingLabel.color"
|
||||||
|
:advanced-fields="true"
|
||||||
|
@input="updateColor">
|
||||||
<div :style="{ backgroundColor: '#' + editingLabel.color }" class="color0 icon-colorpicker" />
|
<div :style="{ backgroundColor: '#' + editingLabel.color }" class="color0 icon-colorpicker" />
|
||||||
</NcColorPicker>
|
</NcColorPicker>
|
||||||
<input v-model="editingLabel.title" type="text">
|
<input v-model="editingLabel.title" type="text">
|
||||||
@@ -48,7 +51,10 @@
|
|||||||
<li v-if="addLabel" class="editing">
|
<li v-if="addLabel" class="editing">
|
||||||
<!-- New Tag -->
|
<!-- New Tag -->
|
||||||
<form class="label-form" @submit.prevent="clickAddLabel">
|
<form class="label-form" @submit.prevent="clickAddLabel">
|
||||||
<NcColorPicker class="color-picker-wrapper" :value="'#' + addLabelObj.color" @input="updateColor">
|
<NcColorPicker class="color-picker-wrapper"
|
||||||
|
:value="'#' + addLabelObj.color"
|
||||||
|
:advanced-fields="true"
|
||||||
|
@input="updateColor">
|
||||||
<div :style="{ backgroundColor: '#' + addLabelObj.color }" class="color0 icon-colorpicker" />
|
<div :style="{ backgroundColor: '#' + addLabelObj.color }" class="color0 icon-colorpicker" />
|
||||||
</NcColorPicker>
|
</NcColorPicker>
|
||||||
<input v-model="addLabelObj.title" type="text">
|
<input v-model="addLabelObj.title" type="text">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="selector-wrapper" :aria-label="t('deck', 'Assign to users/groups/circles')">
|
<div class="selector-wrapper" :aria-label="t('deck', 'Assign to users/groups/circles')" data-test="assignment-selector">
|
||||||
<div class="selector-wrapper--icon">
|
<div class="selector-wrapper--icon">
|
||||||
<AccountMultiple :size="20" />
|
<AccountMultiple :size="20" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,12 +23,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<AttachmentDragAndDrop :card-id="cardId" class="drop-upload--sidebar">
|
<AttachmentDragAndDrop :card-id="cardId" class="drop-upload--sidebar">
|
||||||
<div v-if="!isReadOnly" class="button-group">
|
<div v-if="!isReadOnly" class="button-group">
|
||||||
<button class="icon-upload" @click="uploadNewFile()">
|
<NcButton class="icon-upload" @click="uploadNewFile()">
|
||||||
{{ t('deck', 'Upload new files') }}
|
{{ t('deck', 'Upload new files') }}
|
||||||
</button>
|
</NcButton>
|
||||||
<button class="icon-folder" @click="shareFromFiles()">
|
<NcButton class="icon-folder" @click="shareFromFiles()">
|
||||||
{{ t('deck', 'Share from Files') }}
|
{{ t('deck', 'Share from Files') }}
|
||||||
</button>
|
</NcButton>
|
||||||
</div>
|
</div>
|
||||||
<input ref="filesAttachment"
|
<input ref="filesAttachment"
|
||||||
type="file"
|
type="file"
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { NcActions, NcActionButton, NcActionLink } from '@nextcloud/vue'
|
import { NcActions, NcActionButton, NcActionLink, NcButton } from '@nextcloud/vue'
|
||||||
import AttachmentDragAndDrop from '../AttachmentDragAndDrop.vue'
|
import AttachmentDragAndDrop from '../AttachmentDragAndDrop.vue'
|
||||||
import relativeDate from '../../mixins/relativeDate.js'
|
import relativeDate from '../../mixins/relativeDate.js'
|
||||||
import { formatFileSize } from '@nextcloud/files'
|
import { formatFileSize } from '@nextcloud/files'
|
||||||
@@ -128,6 +128,7 @@ export default {
|
|||||||
NcActions,
|
NcActions,
|
||||||
NcActionButton,
|
NcActionButton,
|
||||||
NcActionLink,
|
NcActionLink,
|
||||||
|
NcButton,
|
||||||
AttachmentDragAndDrop,
|
AttachmentDragAndDrop,
|
||||||
},
|
},
|
||||||
mixins: [relativeDate, attachmentUpload],
|
mixins: [relativeDate, attachmentUpload],
|
||||||
@@ -267,6 +268,7 @@ export default {
|
|||||||
|
|
||||||
.button-group {
|
.button-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: calc(var(--default-grid-baseline) * 3);
|
||||||
|
|
||||||
.icon-upload, .icon-folder {
|
.icon-upload, .icon-folder {
|
||||||
padding-left: 44px;
|
padding-left: 44px;
|
||||||
|
|||||||
27
src/components/card/CardDetailEntry.vue
Normal file
27
src/components/card/CardDetailEntry.vue
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<div class="selector-wrapper" :aria-label="label">
|
||||||
|
<div class="selector-wrapper--icon">
|
||||||
|
<slot name="icon" />
|
||||||
|
</div>
|
||||||
|
<div class="selector-wrapper--content">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'CardDetailEntry',
|
||||||
|
props: {
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
@import '../../css/selector';
|
||||||
|
</style>
|
||||||
@@ -39,13 +39,7 @@
|
|||||||
{{ t('deck', 'Open in bigger view') }}
|
{{ t('deck', 'Open in bigger view') }}
|
||||||
</NcActionButton>
|
</NcActionButton>
|
||||||
|
|
||||||
<NcActionButton v-for="action in cardActions"
|
<CardMenuEntries :card="currentCard" :hide-details-entry="true" />
|
||||||
:key="action.label"
|
|
||||||
:close-after-click="true"
|
|
||||||
:icon="action.icon"
|
|
||||||
@click="action.callback(cardRichObject)">
|
|
||||||
{{ action.label }}
|
|
||||||
</NcActionButton>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<NcAppSidebarTab id="details"
|
<NcAppSidebarTab id="details"
|
||||||
@@ -78,7 +72,7 @@
|
|||||||
<NcAppSidebarTab v-if="hasActivity"
|
<NcAppSidebarTab v-if="hasActivity"
|
||||||
id="timeline"
|
id="timeline"
|
||||||
:order="3"
|
:order="3"
|
||||||
:name="t('deck', 'Timeline')">
|
:name="t('deck', 'Activity')">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<ActivityIcon :size="20" />
|
<ActivityIcon :size="20" />
|
||||||
</template>
|
</template>
|
||||||
@@ -89,7 +83,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { NcActionButton, NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
|
import { NcActionButton, NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
|
||||||
import { mapState, mapGetters } from 'vuex'
|
import { mapState, mapGetters } from 'vuex'
|
||||||
import CardSidebarTabDetails from './CardSidebarTabDetails.vue'
|
import CardSidebarTabDetails from './CardSidebarTabDetails.vue'
|
||||||
import CardSidebarTabAttachments from './CardSidebarTabAttachments.vue'
|
import CardSidebarTabAttachments from './CardSidebarTabAttachments.vue'
|
||||||
@@ -104,6 +97,7 @@ import ActivityIcon from 'vue-material-design-icons/LightningBolt.vue'
|
|||||||
|
|
||||||
import { showError } from '@nextcloud/dialogs'
|
import { showError } from '@nextcloud/dialogs'
|
||||||
import { getLocale } from '@nextcloud/l10n'
|
import { getLocale } from '@nextcloud/l10n'
|
||||||
|
import CardMenuEntries from '../cards/CardMenuEntries.vue'
|
||||||
|
|
||||||
const capabilities = window.OC.getCapabilities()
|
const capabilities = window.OC.getCapabilities()
|
||||||
|
|
||||||
@@ -121,6 +115,7 @@ export default {
|
|||||||
AttachmentIcon,
|
AttachmentIcon,
|
||||||
CommentIcon,
|
CommentIcon,
|
||||||
HomeIcon,
|
HomeIcon,
|
||||||
|
CardMenuEntries,
|
||||||
},
|
},
|
||||||
mixins: [relativeDate],
|
mixins: [relativeDate],
|
||||||
props: {
|
props: {
|
||||||
@@ -164,15 +159,6 @@ export default {
|
|||||||
subtitleTooltip() {
|
subtitleTooltip() {
|
||||||
return t('deck', 'Modified') + ': ' + this.formatDate(this.currentCard.lastModified) + '\n' + t('deck', 'Created') + ': ' + this.formatDate(this.currentCard.createdAt)
|
return t('deck', 'Modified') + ': ' + this.formatDate(this.currentCard.lastModified) + '\n' + t('deck', 'Created') + ': ' + this.formatDate(this.currentCard.createdAt)
|
||||||
},
|
},
|
||||||
cardRichObject() {
|
|
||||||
return {
|
|
||||||
id: '' + this.currentCard.id,
|
|
||||||
name: this.currentCard.title,
|
|
||||||
boardname: this.currentBoard.title,
|
|
||||||
stackname: this.stackById(this.currentCard.stackId)?.title,
|
|
||||||
link: window.location.protocol + '//' + window.location.host + generateUrl('/apps/deck/') + `#/board/${this.currentBoard.id}/card/${this.currentCard.id}`,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cardDetailsInModal: {
|
cardDetailsInModal: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.getters.config('cardDetailsInModal')
|
return this.$store.getters.config('cardDetailsInModal')
|
||||||
|
|||||||
@@ -35,7 +35,10 @@
|
|||||||
@select="assignUserToCard"
|
@select="assignUserToCard"
|
||||||
@remove="removeUserFromCard" />
|
@remove="removeUserFromCard" />
|
||||||
|
|
||||||
<DueDateSelector :card="card" :can-edit="canEdit && !saving" @change="updateCardDue" />
|
<DueDateSelector :card="card"
|
||||||
|
:can-edit="canEdit"
|
||||||
|
@change="updateCardDue"
|
||||||
|
@input="debouncedUpdateCardDue" />
|
||||||
|
|
||||||
<div v-if="projectsEnabled" class="section-wrapper">
|
<div v-if="projectsEnabled" class="section-wrapper">
|
||||||
<CollectionList v-if="card.id"
|
<CollectionList v-if="card.id"
|
||||||
@@ -66,6 +69,7 @@ import Description from './Description.vue'
|
|||||||
import TagSelector from './TagSelector.vue'
|
import TagSelector from './TagSelector.vue'
|
||||||
import AssignmentSelector from './AssignmentSelector.vue'
|
import AssignmentSelector from './AssignmentSelector.vue'
|
||||||
import DueDateSelector from './DueDateSelector.vue'
|
import DueDateSelector from './DueDateSelector.vue'
|
||||||
|
import { debounce } from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CardSidebarTabDetails',
|
name: 'CardSidebarTabDetails',
|
||||||
@@ -85,7 +89,6 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
saving: false,
|
|
||||||
addedLabelToCard: null,
|
addedLabelToCard: null,
|
||||||
copiedCard: null,
|
copiedCard: null,
|
||||||
locale: getLocale(),
|
locale: getLocale(),
|
||||||
@@ -105,7 +108,6 @@ export default {
|
|||||||
this.$store.dispatch('setConfig', { cardDetailsInModal: newValue })
|
this.$store.dispatch('setConfig', { cardDetailsInModal: newValue })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
labelsSorted() {
|
labelsSorted() {
|
||||||
return [...this.currentBoard.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
|
return [...this.currentBoard.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
|
||||||
},
|
},
|
||||||
@@ -135,15 +137,6 @@ export default {
|
|||||||
localStorage.setItem('deck.selectedStackId', this.card.stackId)
|
localStorage.setItem('deck.selectedStackId', this.card.stackId)
|
||||||
},
|
},
|
||||||
|
|
||||||
async updateCardDue(val) {
|
|
||||||
this.saving = true
|
|
||||||
await this.$store.dispatch('updateCardDue', {
|
|
||||||
...this.copiedCard,
|
|
||||||
duedate: val ? (new Date(val)).toISOString() : null,
|
|
||||||
})
|
|
||||||
this.saving = false
|
|
||||||
},
|
|
||||||
|
|
||||||
assignUserToCard(user) {
|
assignUserToCard(user) {
|
||||||
this.$store.dispatch('assignCardToUser', {
|
this.$store.dispatch('assignCardToUser', {
|
||||||
card: this.copiedCard,
|
card: this.copiedCard,
|
||||||
@@ -164,6 +157,17 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateCardDue(val) {
|
||||||
|
this.$store.dispatch('updateCardDue', {
|
||||||
|
...this.copiedCard,
|
||||||
|
duedate: val ? (new Date(val)).toISOString() : null,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
debouncedUpdateCardDue: debounce(function(val) {
|
||||||
|
this.updateCardDue(val)
|
||||||
|
}, 500),
|
||||||
|
|
||||||
addLabelToCard(newLabel) {
|
addLabelToCard(newLabel) {
|
||||||
this.copiedCard.labels.push(newLabel)
|
this.copiedCard.labels.push(newLabel)
|
||||||
const data = {
|
const data = {
|
||||||
@@ -174,13 +178,14 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async addLabelToBoardAndCard(name) {
|
async addLabelToBoardAndCard(name) {
|
||||||
await this.$store.dispatch('addLabelToCurrentBoardAndCard', {
|
const newLabel = await this.$store.dispatch('addLabelToCurrentBoardAndCard', {
|
||||||
card: this.copiedCard,
|
card: this.copiedCard,
|
||||||
newLabel: {
|
newLabel: {
|
||||||
title: name,
|
title: name,
|
||||||
color: this.randomColor(),
|
color: this.randomColor(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
this.copiedCard.labels.push(newLabel)
|
||||||
},
|
},
|
||||||
|
|
||||||
removeLabelFromCard(removedLabel) {
|
removeLabelFromCard(removedLabel) {
|
||||||
@@ -207,15 +212,6 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
.section-wrapper:deep(.mx-datepicker-main.mx-datepicker-popup) {
|
|
||||||
left: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-wrapper:deep(.mx-datepicker-main.mx-datepicker-popup.mx-datepicker-sidebar) {
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-wrapper {
|
.section-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
@@ -233,12 +229,36 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
button.action-item--single {
|
.remove-due-button{
|
||||||
margin-top: -3px;
|
margin-top: -2px;
|
||||||
|
margin-left: 6px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.done {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0px 5px;
|
||||||
|
border-radius: 15px;
|
||||||
|
font-size: 85%;
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
.avatarLabel {
|
.avatarLabel {
|
||||||
padding: 6px
|
padding: 6px
|
||||||
}
|
}
|
||||||
@@ -268,9 +288,3 @@ export default {
|
|||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style>
|
|
||||||
.mx-datepicker-main.mx-datepicker-popup {
|
|
||||||
/* above the modal */
|
|
||||||
z-index: 9999 !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<div ref="contentEditable"
|
<div ref="contentEditable"
|
||||||
|
dir="auto"
|
||||||
class="comment-form__contenteditable"
|
class="comment-form__contenteditable"
|
||||||
contenteditable
|
contenteditable
|
||||||
@keydown.enter="handleKeydown"
|
@keydown.enter="handleKeydown"
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
</NcActions>
|
</NcActions>
|
||||||
</div>
|
</div>
|
||||||
<NcRichText class="comment--content"
|
<NcRichText class="comment--content"
|
||||||
|
dir="auto"
|
||||||
:text="richText(comment)"
|
:text="richText(comment)"
|
||||||
:arguments="richArgs(comment)"
|
:arguments="richArgs(comment)"
|
||||||
:autolink="true" />
|
:autolink="true" />
|
||||||
@@ -48,18 +49,24 @@
|
|||||||
<NcActionButton icon="icon-close" @click="hideUpdateForm" />
|
<NcActionButton icon="icon-close" @click="hideUpdateForm" />
|
||||||
</NcActions>
|
</NcActions>
|
||||||
<div class="spacer" />
|
<div class="spacer" />
|
||||||
<div class="timestamp">
|
<div class="timestamp"
|
||||||
|
:aria-label="formattedTimestamp"
|
||||||
|
:title="formattedTimestamp">
|
||||||
{{ relativeDate(comment.creationDateTime) }}
|
{{ relativeDate(comment.creationDateTime) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CommentItem v-if="comment.replyTo" :reply="true" :comment="comment.replyTo" />
|
<CommentItem v-if="comment.replyTo" :reply="true" :comment="comment.replyTo" />
|
||||||
<div v-show="!edit" ref="richTextElement">
|
<div v-show="!edit" ref="richTextElement">
|
||||||
<NcRichText class="comment--content"
|
<NcRichText class="comment--content"
|
||||||
|
dir="auto"
|
||||||
:text="richText(comment)"
|
:text="richText(comment)"
|
||||||
:arguments="richArgs(comment)"
|
:arguments="richArgs(comment)"
|
||||||
:autolink="true" />
|
:autolink="true" />
|
||||||
</div>
|
</div>
|
||||||
<CommentForm v-if="edit" v-model="commentMsg" @submit="updateComment" />
|
<CommentForm v-if="edit"
|
||||||
|
v-model="commentMsg"
|
||||||
|
dir="auto"
|
||||||
|
@submit="updateComment" />
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -70,6 +77,7 @@ import { getCurrentUser } from '@nextcloud/auth'
|
|||||||
import md5 from 'blueimp-md5'
|
import md5 from 'blueimp-md5'
|
||||||
import relativeDate from '../../mixins/relativeDate.js'
|
import relativeDate from '../../mixins/relativeDate.js'
|
||||||
import ReplyIcon from 'vue-material-design-icons/Reply.vue'
|
import ReplyIcon from 'vue-material-design-icons/Reply.vue'
|
||||||
|
import moment from 'moment'
|
||||||
|
|
||||||
const AtMention = {
|
const AtMention = {
|
||||||
name: 'AtMention',
|
name: 'AtMention',
|
||||||
@@ -158,6 +166,9 @@ export default {
|
|||||||
return (div.textContent || div.innerText || '')
|
return (div.textContent || div.innerText || '')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
formattedTimestamp() {
|
||||||
|
return t('deck', 'Created:') + ' ' + moment(this.comment.creationDateTime).format('LLLL')
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div data-test="description">
|
||||||
<h5>
|
<h5>
|
||||||
{{ t('deck', 'Description') }}
|
{{ t('deck', 'Description') }}
|
||||||
<span v-if="descriptionLastEdit && !descriptionSaving">{{ t('deck', '(Unsaved)') }}</span>
|
<span v-if="descriptionLastEdit && !descriptionSaving">{{ t('deck', '(Unsaved)') }}</span>
|
||||||
@@ -55,6 +55,7 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<div v-if="!descriptionEditing && hasDescription"
|
<div v-if="!descriptionEditing && hasDescription"
|
||||||
id="description-preview"
|
id="description-preview"
|
||||||
|
dir="auto"
|
||||||
@click="clickedPreview"
|
@click="clickedPreview"
|
||||||
v-html="renderedDescription" />
|
v-html="renderedDescription" />
|
||||||
<p v-else-if="!descriptionEditing" class="placeholder" @click="showEditor()">
|
<p v-else-if="!descriptionEditing" class="placeholder" @click="showEditor()">
|
||||||
|
|||||||
@@ -1,43 +1,123 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="selector-wrapper" :aria-label="t('deck', 'Assign a due date to this card…')">
|
<CardDetailEntry :label="t('deck', 'Assign a due date to this card…')" data-test="due-date-selector">
|
||||||
<div class="selector-wrapper--icon">
|
<Calendar v-if="!card.done" slot="icon" :size="20" />
|
||||||
<Calendar :size="20" />
|
<CalendarCheck v-else slot="icon" :size="20" />
|
||||||
</div>
|
<template v-if="!card.done && !card.archived">
|
||||||
<div class="duedate-selector">
|
<NcDateTimePickerNative v-if="duedate"
|
||||||
<NcDatetimePicker v-model="duedate"
|
id="card-duedate-picker"
|
||||||
|
v-model="duedate"
|
||||||
:placeholder="t('deck', 'Set a due date')"
|
:placeholder="t('deck', 'Set a due date')"
|
||||||
type="datetime"
|
:hide-label="true"
|
||||||
:minute-step="5"
|
type="datetime-local" />
|
||||||
:show-second="false"
|
<NcActions v-if="canEdit"
|
||||||
:lang="lang"
|
:menu-title="!duedate ? t('deck', 'Add due date') : null"
|
||||||
:formatter="format"
|
type="tertiary"
|
||||||
:disabled="!canEdit"
|
data-cy-due-date-actions>
|
||||||
:shortcuts="shortcuts"
|
<template v-if="!duedate" #icon>
|
||||||
:append-to-body="true"
|
<Plus :size="20" />
|
||||||
confirm />
|
</template>
|
||||||
<NcActions v-if="canEdit">
|
<NcActionButton v-for="shortcut in reminderOptions"
|
||||||
<NcActionButton v-if="duedate" icon="icon-delete" @click="removeDue()">
|
:key="shortcut.key"
|
||||||
|
close-after-click
|
||||||
|
:data-cy-due-date-shortcut="shortcut.key"
|
||||||
|
@click="() => selectShortcut(shortcut)">
|
||||||
|
{{ shortcut.label }}
|
||||||
|
</NcActionButton>
|
||||||
|
<NcActionSeparator />
|
||||||
|
|
||||||
|
<NcActionButton v-if="!duedate"
|
||||||
|
close-after-click
|
||||||
|
data-cy-due-date-pick
|
||||||
|
@click="initDate">
|
||||||
|
<template #icon>
|
||||||
|
<Plus :size="20" />
|
||||||
|
</template>
|
||||||
|
{{ t('deck', 'Choose a date') }}
|
||||||
|
</NcActionButton>
|
||||||
|
<NcActionButton v-else
|
||||||
|
icon="icon-delete"
|
||||||
|
close-after-click
|
||||||
|
data-cy-due-date-remove
|
||||||
|
@click="removeDue">
|
||||||
{{ t('deck', 'Remove due date') }}
|
{{ t('deck', 'Remove due date') }}
|
||||||
</NcActionButton>
|
</NcActionButton>
|
||||||
</NcActions>
|
</NcActions>
|
||||||
</div>
|
|
||||||
</div>
|
<NcButton v-if="!card.done"
|
||||||
|
type="secondary"
|
||||||
|
class="completed-button"
|
||||||
|
@click="changeCardDoneStatus()">
|
||||||
|
<template #icon>
|
||||||
|
<CheckIcon :size="20" />
|
||||||
|
</template>
|
||||||
|
{{ t('deck', 'Completed') }}
|
||||||
|
</NcButton>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="done-info">
|
||||||
|
<span v-if="card.done" class="done-info--done">
|
||||||
|
{{ formatReadableDate(card.done) }}
|
||||||
|
</span>
|
||||||
|
<span v-if="duedate" class="done-info--duedate" :class="{ 'dimmed': card.done }">
|
||||||
|
{{ t('deck', 'Due at:') }}
|
||||||
|
{{ formatReadableDate(duedate) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="due-actions">
|
||||||
|
<NcButton v-if="!card.archived"
|
||||||
|
type="tertiary"
|
||||||
|
:title="t('deck', 'Not completed')"
|
||||||
|
@click="changeCardDoneStatus()">
|
||||||
|
<template #icon>
|
||||||
|
<ClearIcon :size="20" />
|
||||||
|
</template>
|
||||||
|
</NcButton>
|
||||||
|
<NcButton type="secondary" @click="archiveUnarchiveCard()">
|
||||||
|
<template #icon>
|
||||||
|
<ArchiveIcon :size="20" />
|
||||||
|
</template>
|
||||||
|
{{ card.archived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
|
||||||
|
</NcButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</CardDetailEntry>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import { NcActionButton, NcActions, NcDatetimePicker } from '@nextcloud/vue'
|
import {
|
||||||
import { getDayNamesMin, getFirstDay, getMonthNamesShort } from '@nextcloud/l10n'
|
NcActionButton,
|
||||||
import Calendar from 'vue-material-design-icons/Calendar.vue'
|
NcActions,
|
||||||
|
NcActionSeparator,
|
||||||
|
NcButton,
|
||||||
|
NcDateTimePickerNative,
|
||||||
|
} from '@nextcloud/vue'
|
||||||
import readableDate from '../../mixins/readableDate.js'
|
import readableDate from '../../mixins/readableDate.js'
|
||||||
|
import { getDayNamesMin, getFirstDay, getMonthNamesShort } from '@nextcloud/l10n'
|
||||||
|
import moment from '@nextcloud/moment'
|
||||||
|
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
||||||
|
import Plus from 'vue-material-design-icons/Plus.vue'
|
||||||
|
import Calendar from 'vue-material-design-icons/Calendar.vue'
|
||||||
|
import CalendarCheck from 'vue-material-design-icons/CalendarCheck.vue'
|
||||||
|
import CheckIcon from 'vue-material-design-icons/Check.vue'
|
||||||
|
import ClearIcon from 'vue-material-design-icons/Close.vue'
|
||||||
|
import CardDetailEntry from './CardDetailEntry.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'DueDateSelector',
|
name: 'DueDateSelector',
|
||||||
components: {
|
components: {
|
||||||
|
NcButton,
|
||||||
|
ArchiveIcon,
|
||||||
|
ClearIcon,
|
||||||
|
CardDetailEntry,
|
||||||
|
Plus,
|
||||||
Calendar,
|
Calendar,
|
||||||
|
CalendarCheck,
|
||||||
|
CheckIcon,
|
||||||
NcActions,
|
NcActions,
|
||||||
NcActionButton,
|
NcActionButton,
|
||||||
NcDatetimePicker,
|
NcActionSeparator,
|
||||||
|
NcDateTimePickerNative,
|
||||||
},
|
},
|
||||||
mixins: [
|
mixins: [
|
||||||
readableDate,
|
readableDate,
|
||||||
@@ -68,71 +148,113 @@ export default defineComponent({
|
|||||||
stringify: this.stringify,
|
stringify: this.stringify,
|
||||||
parse: this.parse,
|
parse: this.parse,
|
||||||
},
|
},
|
||||||
shortcuts: [
|
|
||||||
{
|
|
||||||
text: t('deck', 'Today'),
|
|
||||||
onClick() {
|
|
||||||
const date = new Date()
|
|
||||||
date.setDate(date.getDate())
|
|
||||||
date.setHours(23)
|
|
||||||
date.setMinutes(59)
|
|
||||||
return date
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: t('deck', 'Tomorrow'),
|
|
||||||
onClick() {
|
|
||||||
const date = new Date()
|
|
||||||
date.setDate(date.getDate() + 1)
|
|
||||||
date.setHours(23)
|
|
||||||
date.setMinutes(59)
|
|
||||||
return date
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: t('deck', 'Next week'),
|
|
||||||
onClick() {
|
|
||||||
const date = new Date()
|
|
||||||
date.setDate(date.getDate() + 7)
|
|
||||||
date.setHours(23)
|
|
||||||
date.setMinutes(59)
|
|
||||||
return date
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: t('deck', 'Next month'),
|
|
||||||
onClick() {
|
|
||||||
const date = new Date()
|
|
||||||
date.setDate(date.getDate() + 30)
|
|
||||||
date.setHours(23)
|
|
||||||
date.setMinutes(59)
|
|
||||||
return date
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
duedate: {
|
duedate: {
|
||||||
get() {
|
get() {
|
||||||
return this.card.duedate ? new Date(this.card.duedate) : null
|
return this.card?.duedate ? new Date(this.card.duedate) : null
|
||||||
},
|
},
|
||||||
set(val) {
|
set(val) {
|
||||||
this.$emit('change', val)
|
this.$emit('input', val ? new Date(val) : null)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
reminderOptions() {
|
||||||
|
const currentDateTime = moment()
|
||||||
|
// Same day 18:00 PM (or hidden)
|
||||||
|
const laterTodayTime = (currentDateTime.hour() < 18)
|
||||||
|
? moment().hour(18)
|
||||||
|
: null
|
||||||
|
// Tomorrow 08:00 AM
|
||||||
|
const tomorrowTime = moment().add(1, 'days').hour(8)
|
||||||
|
// Saturday 08:00 AM (or hidden)
|
||||||
|
const thisWeekendTime = (currentDateTime.day() !== 6 && currentDateTime.day() !== 0)
|
||||||
|
? moment().day(6).hour(8)
|
||||||
|
: null
|
||||||
|
// Next Monday 08:00 AM
|
||||||
|
const nextWeekTime = moment().add(1, 'weeks').day(1).hour(8)
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'laterToday',
|
||||||
|
timestamp: this.getTimestamp(laterTodayTime),
|
||||||
|
label: t('deck', 'Later today – {timeLocale}', { timeLocale: laterTodayTime?.format('LT') }),
|
||||||
|
ariaLabel: t('deck', 'Set due date for later today'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'tomorrow',
|
||||||
|
timestamp: this.getTimestamp(tomorrowTime),
|
||||||
|
label: t('deck', 'Tomorrow – {timeLocale}', { timeLocale: tomorrowTime?.format('ddd LT') }),
|
||||||
|
ariaLabel: t('deck', 'Set due date for tomorrow'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'thisWeekend',
|
||||||
|
timestamp: this.getTimestamp(thisWeekendTime),
|
||||||
|
label: t('deck', 'This weekend – {timeLocale}', { timeLocale: thisWeekendTime?.format('ddd LT') }),
|
||||||
|
ariaLabel: t('deck', 'Set due date for this weekend'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'nextWeek',
|
||||||
|
timestamp: this.getTimestamp(nextWeekTime),
|
||||||
|
label: t('deck', 'Next week – {timeLocale}', { timeLocale: nextWeekTime?.format('ddd LT') }),
|
||||||
|
ariaLabel: t('deck', 'Set due date for next week'),
|
||||||
|
},
|
||||||
|
].filter(option => option.timestamp !== null)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
initDate() {
|
||||||
|
if (this.duedate === null) {
|
||||||
|
// We initialize empty dates with a time once clicked to make picking a day easier
|
||||||
|
const now = new Date()
|
||||||
|
now.setDate(now.getDate() + 1)
|
||||||
|
now.setHours(8)
|
||||||
|
now.setMinutes(0)
|
||||||
|
now.setMilliseconds(0)
|
||||||
|
this.duedate = now
|
||||||
|
}
|
||||||
|
},
|
||||||
removeDue() {
|
removeDue() {
|
||||||
this.duedate = null
|
this.duedate = null
|
||||||
|
this.$emit('change', null)
|
||||||
|
|
||||||
|
},
|
||||||
|
selectShortcut(shortcut) {
|
||||||
|
this.duedate = shortcut.timestamp
|
||||||
|
this.$emit('change', shortcut.timestamp)
|
||||||
|
},
|
||||||
|
getTimestamp(momentObject) {
|
||||||
|
return momentObject?.minute(0).second(0).millisecond(0).toDate() || null
|
||||||
|
},
|
||||||
|
changeCardDoneStatus() {
|
||||||
|
this.$store.dispatch('changeCardDoneStatus', { ...this.card, done: !this.card.done })
|
||||||
|
},
|
||||||
|
archiveUnarchiveCard() {
|
||||||
|
this.$store.dispatch('archiveUnarchiveCard', { ...this.card, archived: !this.card.archived })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style scoped lang="scss">
|
||||||
@import '../../css/selector';
|
.done-info {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.duedate-selector {
|
.done-info--duedate,
|
||||||
|
.done-info--done {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
padding-top: 10px;
|
||||||
|
&.dimmed {
|
||||||
|
color: var(--color-text-maxcontrast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.completed-button {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.due-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="selector-wrapper" :aria-label="t('deck', 'Assign a tag to this card…')">
|
<div class="selector-wrapper" :aria-label="t('deck', 'Assign a tag to this card…')" data-test="tag-selector">
|
||||||
<div class="selector-wrapper--icon">
|
<div class="selector-wrapper--icon">
|
||||||
<TagMultiple :size="20" />
|
<TagMultiple :size="20" />
|
||||||
</div>
|
</div>
|
||||||
<NcMultiselect v-model="assignedLabels"
|
<NcMultiselect :value="assignedLabels"
|
||||||
class="selector-wrapper--selector"
|
class="selector-wrapper--selector"
|
||||||
:multiple="true"
|
:multiple="true"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
@@ -12,13 +12,19 @@
|
|||||||
:taggable="true"
|
:taggable="true"
|
||||||
label="title"
|
label="title"
|
||||||
track-by="id"
|
track-by="id"
|
||||||
|
tag-position="bottom"
|
||||||
@select="onSelect"
|
@select="onSelect"
|
||||||
@remove="onRemove"
|
@remove="onRemove"
|
||||||
@tag="onNewTag">
|
@tag="onNewTag">
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<div :style="{ backgroundColor: '#' + scope.option.color, color: textColor(scope.option.color)}" class="tag">
|
<div v-if="!scope.option?.isTag" :style="{ backgroundColor: '#' + scope.option.color, color: textColor(scope.option.color)}" class="tag">
|
||||||
{{ scope.option.title }}
|
{{ scope.option.title }}
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ t('deck', 'Create a new tag:') }} <div class="tag">
|
||||||
|
{{ scope.option.label }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #tag="scope">
|
<template #tag="scope">
|
||||||
<div :style="{ backgroundColor: '#' + scope.option.color, color: textColor(scope.option.color)}" class="tag">
|
<div :style="{ backgroundColor: '#' + scope.option.color, color: textColor(scope.option.color)}" class="tag">
|
||||||
@@ -52,32 +58,15 @@ export default {
|
|||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
assignedLabels: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
labelsSorted() {
|
labelsSorted() {
|
||||||
return [...this.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
|
return [...this.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
|
||||||
},
|
},
|
||||||
},
|
assignedLabels() {
|
||||||
watch: {
|
return [...this.card.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
|
||||||
card() {
|
|
||||||
this.initialize()
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
this.initialize()
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
async initialize() {
|
|
||||||
if (!this.card) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.assignedLabels = [...this.card.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
|
|
||||||
},
|
|
||||||
onSelect(newLabel) {
|
onSelect(newLabel) {
|
||||||
this.$emit('select', newLabel)
|
this.$emit('select', newLabel)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<div class="avatars">
|
<div class="avatars">
|
||||||
<div class="avatar-list" @click.stop="togglePopover">
|
<div class="avatar-list" @click.stop="togglePopover">
|
||||||
<div v-if="popover.length > 0">
|
<div v-if="popover.length > 0">
|
||||||
<div class="avatardiv icon-more" />
|
<AccountMultiple class="avatardiv more-avatars" :size="24" />
|
||||||
</div>
|
</div>
|
||||||
<div v-for="user in firstUsers" :key="user.id">
|
<div v-for="user in firstUsers" :key="user.id">
|
||||||
<NcAvatar v-if="user.type === 0"
|
<NcAvatar v-if="user.type === 0"
|
||||||
@@ -72,12 +72,14 @@
|
|||||||
<script>
|
<script>
|
||||||
import { NcAvatar, NcPopoverMenu, Tooltip } from '@nextcloud/vue'
|
import { NcAvatar, NcPopoverMenu, Tooltip } from '@nextcloud/vue'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
|
import AccountMultiple from 'vue-material-design-icons/AccountMultiple.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AvatarList',
|
name: 'AvatarList',
|
||||||
components: {
|
components: {
|
||||||
NcAvatar,
|
NcAvatar,
|
||||||
NcPopoverMenu,
|
NcPopoverMenu,
|
||||||
|
AccountMultiple,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
tooltip: Tooltip,
|
tooltip: Tooltip,
|
||||||
@@ -151,7 +153,6 @@ export default {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.avatars {
|
.avatars {
|
||||||
margin-top: 5px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
:deep(.popovermenu) {
|
:deep(.popovermenu) {
|
||||||
@@ -173,25 +174,29 @@ export default {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
padding-right: $avatar-offset;
|
padding-right: $avatar-offset;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
.avatardiv,
|
.avatardiv,
|
||||||
:deep(.avatardiv) {
|
:deep(.avatardiv) {
|
||||||
width: 36px;
|
width: 32px;
|
||||||
height: 36px;
|
height: 32px;
|
||||||
box-sizing: content-box !important;
|
box-sizing: content-box !important;
|
||||||
margin-right: -$avatar-offset;
|
margin-right: -$avatar-offset;
|
||||||
transition: margin-right 0.2s ease-in-out;
|
transition: margin-right 0.2s ease-in-out;
|
||||||
|
border: 2px solid var(--color-main-background);
|
||||||
|
}
|
||||||
|
|
||||||
&.icon-more {
|
.more-avatars {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
opacity: .5;
|
background-color: var(--color-background-dark) !important;
|
||||||
background-color: var(--color-background-dark) !important;
|
cursor: pointer;
|
||||||
cursor: pointer;
|
color: var(--color-text-maxcontrast);
|
||||||
}
|
|
||||||
}
|
|
||||||
&:hover div:nth-child(n+2) :deep(.avatardiv) {
|
|
||||||
margin-right: 1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.popovermenu {
|
.popovermenu {
|
||||||
|
|||||||
@@ -22,46 +22,66 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="card" class="badges">
|
<div v-if="card" class="badges">
|
||||||
<CardId v-if="idBadge" class="icon-badge" :card="card" />
|
<div class="badge-left">
|
||||||
<div v-if="card.commentsCount > 0"
|
<DueDate v-if="card.duedate || card.done" :card="card" />
|
||||||
v-tooltip="commentsHint"
|
|
||||||
class="icon-badge"
|
<div class="inline-badges">
|
||||||
@click.stop="openComments">
|
<CardId v-if="idBadge" class="icon-badge" :card="card" />
|
||||||
<CommentUnreadIcon v-if="card.commentsUnread > 0" :size="16" />
|
|
||||||
<CommentIcon v-else :size="16" />
|
<div v-if="card.commentsCount > 0"
|
||||||
<span>{{ card.commentsCount }}</span>
|
v-tooltip="commentsHint"
|
||||||
|
class="icon-badge"
|
||||||
|
@click.stop="openComments">
|
||||||
|
<CommentUnreadIcon v-if="card.commentsUnread > 0" :size="16" />
|
||||||
|
<CommentIcon v-else :size="16" />
|
||||||
|
<span>{{ card.commentsCount }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="card.description && checkListCount > 0" class="icon-badge">
|
||||||
|
<CheckmarkIcon :size="16" :title="t('deck', 'Todo items')" />
|
||||||
|
<span>{{ checkListCheckedCount }}/{{ checkListCount }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else-if="card.description && card.description.trim() && checkListCount == 0" class="icon-badge">
|
||||||
|
<TextIcon :size="16" decorative />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="card.attachmentCount > 0" class="icon-badge">
|
||||||
|
<AttachmentIcon :size="16" />
|
||||||
|
<span>{{ card.attachmentCount }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="card.description && checkListCount > 0" class="icon-badge">
|
<div class="badge-right">
|
||||||
<CheckmarkIcon :size="16" :title="t('deck', 'Todo items')" />
|
<NcAvatarList :users="card.assignedUsers" :size="32" />
|
||||||
<span>{{ checkListCheckedCount }}/{{ checkListCount }}</span>
|
|
||||||
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TextIcon v-else-if="card.description && card.description.trim() && checkListCount == 0" :size="16" decorative />
|
|
||||||
|
|
||||||
<div v-if="card.attachmentCount > 0" class="icon-badge">
|
|
||||||
<AttachmentIcon :size="16" />
|
|
||||||
<span>{{ card.attachmentCount }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<NcAvatarList :users="card.assignedUsers" />
|
|
||||||
|
|
||||||
<CardMenu class="card-menu" :card="card" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import NcAvatarList from './AvatarList.vue'
|
import NcAvatarList from './AvatarList.vue'
|
||||||
import CardId from './badges/CardId.vue'
|
import CardId from './badges/CardId.vue'
|
||||||
import CardMenu from './CardMenu.vue'
|
|
||||||
import TextIcon from 'vue-material-design-icons/Text.vue'
|
import TextIcon from 'vue-material-design-icons/Text.vue'
|
||||||
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'
|
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'
|
||||||
import CheckmarkIcon from 'vue-material-design-icons/CheckboxMarked.vue'
|
import CheckmarkIcon from 'vue-material-design-icons/CheckboxMarked.vue'
|
||||||
import CommentIcon from 'vue-material-design-icons/Comment.vue'
|
import CommentIcon from 'vue-material-design-icons/Comment.vue'
|
||||||
import CommentUnreadIcon from 'vue-material-design-icons/CommentAccount.vue'
|
import CommentUnreadIcon from 'vue-material-design-icons/CommentAccount.vue'
|
||||||
|
import DueDate from './badges/DueDate.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CardBadges',
|
name: 'CardBadges',
|
||||||
components: { NcAvatarList, CardMenu, TextIcon, AttachmentIcon, CheckmarkIcon, CommentIcon, CommentUnreadIcon, CardId },
|
components: {
|
||||||
|
DueDate,
|
||||||
|
NcAvatarList,
|
||||||
|
TextIcon,
|
||||||
|
AttachmentIcon,
|
||||||
|
CheckmarkIcon,
|
||||||
|
CommentIcon,
|
||||||
|
CommentUnreadIcon,
|
||||||
|
CardId,
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
card: {
|
card: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -102,26 +122,33 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 3px;
|
||||||
|
|
||||||
.icon-badge {
|
.icon-badge {
|
||||||
opacity: .7;
|
color: var(--color-text-maxcontrast);
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
|
|
||||||
span,
|
span,
|
||||||
&:deep(span) {
|
&:deep(span) {
|
||||||
padding: 10px 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline-badges {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
.badges .icon.due {
|
.badges .icon.due {
|
||||||
background-position: 4px center;
|
background-position: 4px center;
|
||||||
border-radius: 3px;
|
border-radius: var(--border-radius);
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
font-size: 90%;
|
font-size: 13px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
opacity: .5;
|
opacity: .5;
|
||||||
@@ -153,6 +180,31 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.badge-left, .badge-right {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-left {
|
||||||
|
align-self: end;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
flex-basis: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-content: flex-end;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-right {
|
||||||
|
align-items: center;
|
||||||
|
align-self: flex-end;
|
||||||
|
display: flex;
|
||||||
|
justify-items: center;
|
||||||
|
max-width: 165px;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.fade-enter-active, .fade-leave-active {
|
.fade-enter-active, .fade-leave-active {
|
||||||
transition: opacity .125s;
|
transition: opacity .125s;
|
||||||
}
|
}
|
||||||
@@ -166,9 +218,5 @@ export default {
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
max-height: none !important;
|
max-height: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-menu {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
106
src/components/cards/CardCover.vue
Normal file
106
src/components/cards/CardCover.vue
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
<!--
|
||||||
|
- @copyright Copyright (c) 2023 Johannes Szeibert <johannes@szeibert.de>
|
||||||
|
-
|
||||||
|
- @author Johannes Szeibert <johannes@szeibert.de>
|
||||||
|
-
|
||||||
|
- @license GNU AGPL version 3 or any later version
|
||||||
|
-
|
||||||
|
- This program is free software: you can redistribute it and/or modify
|
||||||
|
- it under the terms of the GNU Affero General Public License as
|
||||||
|
- published by the Free Software Foundation, either version 3 of the
|
||||||
|
- License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- This program is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
- GNU Affero General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Affero General Public License
|
||||||
|
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="cardId && ( attachments.length > 0 )" class="card-cover">
|
||||||
|
<div v-for="(attachment, index) in attachments"
|
||||||
|
:key="attachment.id"
|
||||||
|
:class="['image-wrapper', { 'rounded-left': index === 0 }, { 'rounded-right': index === attachments.length - 1 }]"
|
||||||
|
:style="{ backgroundImage: `url(${attachmentPreview(attachment)})` }" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapActions } from 'vuex'
|
||||||
|
import { generateUrl } from '@nextcloud/router'
|
||||||
|
export default {
|
||||||
|
name: 'CardCover',
|
||||||
|
props: {
|
||||||
|
cardId: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
attachments() {
|
||||||
|
return [...this.$store.getters.attachmentsByCard(this.cardId)]
|
||||||
|
// Filter deleted and hasPreview
|
||||||
|
.filter(attachment => attachment.deletedAt >= 0 && attachment.extendedData.hasPreview)
|
||||||
|
// sort by id (same as in AttachmentList) to get Newest
|
||||||
|
.sort((a, b) => b.id - a.id)
|
||||||
|
// limit to 3 like with android Deck app
|
||||||
|
.slice(0, 3)
|
||||||
|
},
|
||||||
|
attachmentPreview() {
|
||||||
|
// FIXME find a better way to get the stack-width
|
||||||
|
const stackWidth = getComputedStyle(document.documentElement).getPropertyValue('--stack-width').trim()
|
||||||
|
const x = Math.ceil(parseInt(stackWidth) / this.attachments.length) | 260
|
||||||
|
const y = 100
|
||||||
|
return attachment => (
|
||||||
|
// The core preview provider is a bit strange at times, providing much larger than needed images
|
||||||
|
// when cropping is enabled. Therefore use a=1 to not crop the image and let css handle the overflow
|
||||||
|
attachment.extendedData.fileid ? generateUrl(`/core/preview?fileId=${attachment.extendedData.fileid}&x=${x}&y=${y}&a=1`) : null
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
cardId: {
|
||||||
|
immediate: true,
|
||||||
|
handler() {
|
||||||
|
if (this.$store.getters.cardById(this.cardId)?.attachmentCount > 0) {
|
||||||
|
this.fetchAttachments(this.cardId)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions([
|
||||||
|
'fetchAttachments',
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../../css/variables';
|
||||||
|
|
||||||
|
.card-cover {
|
||||||
|
height: 100px;
|
||||||
|
display: flex;
|
||||||
|
margin-top: -8px;
|
||||||
|
margin-left: -8px;
|
||||||
|
margin-right: -8px;
|
||||||
|
|
||||||
|
.image-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
&.rounded-left {
|
||||||
|
border-top-left-radius: 10px;
|
||||||
|
}
|
||||||
|
&.rounded-right {
|
||||||
|
border-top-right-radius: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -26,56 +26,62 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<AttachmentDragAndDrop v-if="card" :card-id="card.id" class="drop-upload--card">
|
<AttachmentDragAndDrop v-if="card" :card-id="card.id" class="drop-upload--card">
|
||||||
<div :class="{'compact': compactMode, 'current-card': currentCard, 'has-labels': card.labels && card.labels.length > 0, 'is-editing': editing, 'card__editable': canEdit, 'card__archived': card.archived }"
|
<div :ref="`card${card.id}`"
|
||||||
|
:class="{'compact': compactMode, 'current-card': currentCard, 'has-labels': card.labels && card.labels.length > 0, 'card__editable': canEdit, 'card__archived': card.archived }"
|
||||||
tag="div"
|
tag="div"
|
||||||
|
:tabindex="0"
|
||||||
class="card"
|
class="card"
|
||||||
@click="openCard">
|
@click="openCard"
|
||||||
|
@keyup.self="handleCardKeyboardShortcut"
|
||||||
|
@mouseenter="focus(card.id)">
|
||||||
<div v-if="standalone" class="card-related">
|
<div v-if="standalone" class="card-related">
|
||||||
<div :style="{backgroundColor: '#' + board.color}" class="board-bullet" />
|
<div :style="{backgroundColor: '#' + board.color}" class="board-bullet" dir="auto" />
|
||||||
{{ board.title }} » {{ stack.title }}
|
{{ board.title }} » {{ stack.title }}
|
||||||
</div>
|
</div>
|
||||||
|
<CardCover v-if="showCardCover" :card-id="card.id" />
|
||||||
<div class="card-upper">
|
<div class="card-upper">
|
||||||
<h3 v-if="inlineEditingBlocked">
|
<h3 v-if="inlineEditingBlocked" dir="auto">
|
||||||
{{ card.title }}
|
{{ card.title }}
|
||||||
</h3>
|
</h3>
|
||||||
<h3 v-else-if="!editing"
|
<h3 v-else
|
||||||
tabindex="0"
|
dir="auto"
|
||||||
class="editable"
|
class="editable"
|
||||||
:aria-label="t('deck', 'Edit card title')"
|
:aria-label="t('deck', 'Edit card title')">
|
||||||
@keydown.enter.stop.prevent="startEditing(card)">
|
<span ref="titleContentEditable"
|
||||||
<span @click.stop="startEditing(card)">{{ card.title }}</span>
|
tabindex="0"
|
||||||
|
contenteditable="true"
|
||||||
|
role="textbox"
|
||||||
|
@focus="onTitleFocus"
|
||||||
|
@blur="onTitleBlur"
|
||||||
|
@click.stop
|
||||||
|
@keyup.esc="cancelEdit"
|
||||||
|
@keyup.stop>{{ card.title }}</span>
|
||||||
</h3>
|
</h3>
|
||||||
<form v-else-if="editing"
|
|
||||||
v-click-outside="cancelEdit"
|
|
||||||
class="dragDisabled"
|
|
||||||
@click.stop
|
|
||||||
@keyup.esc="cancelEdit"
|
|
||||||
@submit.prevent="finishedEdit(card)">
|
|
||||||
<input v-model="copiedCard.title"
|
|
||||||
v-focus
|
|
||||||
type="text"
|
|
||||||
autocomplete="off"
|
|
||||||
required
|
|
||||||
pattern=".*\S+.*">
|
|
||||||
<input type="submit" value="" class="icon-confirm">
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<DueDate v-if="!editing" :card="card" />
|
<DueDate v-if="compactMode" :card="card" />
|
||||||
|
<CardMenu v-if="showMenuAtTitle" :card="card" class="right card-menu" />
|
||||||
<CardMenu v-if="!editing && compactMode" :card="card" class="right" />
|
|
||||||
</div>
|
</div>
|
||||||
<transition-group v-if="card.labels && card.labels.length"
|
|
||||||
name="zoom"
|
|
||||||
tag="ul"
|
|
||||||
class="labels"
|
|
||||||
@click.stop="openCard">
|
|
||||||
<li v-for="label in labelsSorted" :key="label.id" :style="labelStyle(label)">
|
|
||||||
<span @click.stop="applyLabelFilter(label)">{{ label.title }}</span>
|
|
||||||
</li>
|
|
||||||
</transition-group>
|
|
||||||
|
|
||||||
<div v-show="!compactMode" class="card-controls compact-item" @click="openCard">
|
<div v-if="hasLabels" class="card-labels">
|
||||||
<CardBadges :card="card" />
|
<transition-group v-if="card.labels && card.labels.length"
|
||||||
|
name="zoom"
|
||||||
|
tag="ul"
|
||||||
|
class="labels"
|
||||||
|
@click.stop="openCard">
|
||||||
|
<li v-for="label in labelsSorted" :key="label.id" :style="labelStyle(label)">
|
||||||
|
<span @click.stop="applyLabelFilter(label)">{{ label.title }}</span>
|
||||||
|
</li>
|
||||||
|
</transition-group>
|
||||||
|
<CardMenu v-if="showMenuAtLabels" :card="card" class="right" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="hasBadges"
|
||||||
|
v-show="!compactMode"
|
||||||
|
class="card-controls compact-item"
|
||||||
|
@click="openCard">
|
||||||
|
<CardBadges :card="card">
|
||||||
|
<CardMenu v-if="showMenuAtBadges" :card="card" class="right" />
|
||||||
|
</CardBadges>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AttachmentDragAndDrop>
|
</AttachmentDragAndDrop>
|
||||||
@@ -89,11 +95,13 @@ import Color from '../../mixins/color.js'
|
|||||||
import labelStyle from '../../mixins/labelStyle.js'
|
import labelStyle from '../../mixins/labelStyle.js'
|
||||||
import AttachmentDragAndDrop from '../AttachmentDragAndDrop.vue'
|
import AttachmentDragAndDrop from '../AttachmentDragAndDrop.vue'
|
||||||
import CardMenu from './CardMenu.vue'
|
import CardMenu from './CardMenu.vue'
|
||||||
|
import CardCover from './CardCover.vue'
|
||||||
import DueDate from './badges/DueDate.vue'
|
import DueDate from './badges/DueDate.vue'
|
||||||
|
import { getCurrentUser } from '@nextcloud/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CardItem',
|
name: 'CardItem',
|
||||||
components: { CardBadges, AttachmentDragAndDrop, CardMenu, DueDate },
|
components: { CardBadges, AttachmentDragAndDrop, CardMenu, CardCover, DueDate },
|
||||||
directives: {
|
directives: {
|
||||||
ClickOutside,
|
ClickOutside,
|
||||||
},
|
},
|
||||||
@@ -116,17 +124,12 @@ export default {
|
|||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
editing: false,
|
|
||||||
copiedCard: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
compactMode: state => state.compactMode,
|
compactMode: state => state.compactMode,
|
||||||
showArchived: state => state.showArchived,
|
showArchived: state => state.showArchived,
|
||||||
currentBoard: state => state.currentBoard,
|
currentBoard: state => state.currentBoard,
|
||||||
|
showCardCover: state => state.showCardCover,
|
||||||
}),
|
}),
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
'isArchived',
|
'isArchived',
|
||||||
@@ -145,7 +148,7 @@ export default {
|
|||||||
return board ? !board.archived && board.permissions.PERMISSION_EDIT : false
|
return board ? !board.archived && board.permissions.PERMISSION_EDIT : false
|
||||||
},
|
},
|
||||||
inlineEditingBlocked() {
|
inlineEditingBlocked() {
|
||||||
return this.compactMode || this.isArchived || this.showArchived || !this.canEdit || this.standalone
|
return this.isArchived || this.showArchived || !this.canEdit || this.standalone
|
||||||
},
|
},
|
||||||
card() {
|
card() {
|
||||||
return this.item ? this.item : this.$store.getters.cardById(this.id)
|
return this.item ? this.item : this.$store.getters.cardById(this.id)
|
||||||
@@ -156,6 +159,36 @@ export default {
|
|||||||
labelsSorted() {
|
labelsSorted() {
|
||||||
return [...this.card.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
|
return [...this.card.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
|
||||||
},
|
},
|
||||||
|
hasLabels() {
|
||||||
|
return this.card.labels.length > 0
|
||||||
|
},
|
||||||
|
hasBadges() {
|
||||||
|
return this.card.done
|
||||||
|
|| this.card.duedate
|
||||||
|
|| this.idBadge
|
||||||
|
|| this.card.commentsCount > 0
|
||||||
|
|| this.card.description
|
||||||
|
|| this.card.attachmentCount > 0
|
||||||
|
|| this.card.assignedUsers.length > 0
|
||||||
|
},
|
||||||
|
idBadge() {
|
||||||
|
return this.$store.getters.config('cardIdBadge')
|
||||||
|
},
|
||||||
|
showMenuAtTitle() {
|
||||||
|
return this.compactMode || (!this.compactMode && !this.hasBadges && !this.hasLabels)
|
||||||
|
},
|
||||||
|
showMenuAtLabels() {
|
||||||
|
if (this.compactMode) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !this.hasBadges && this.hasLabels
|
||||||
|
},
|
||||||
|
showMenuAtBadges() {
|
||||||
|
if (this.compactMode) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.hasBadges
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
currentCard(newValue) {
|
currentCard(newValue) {
|
||||||
@@ -163,8 +196,18 @@ export default {
|
|||||||
this.$nextTick(() => this.$el.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' }))
|
this.$nextTick(() => this.$el.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' }))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'card.title'(value) {
|
||||||
|
if (document.activeElement === this.$refs.titleContentEditable || this.$refs.titleContentEditable.textContent === value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$refs.titleContentEditable.textContent = value
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
focus(card) {
|
||||||
|
card = this.$refs[`card${card}`]
|
||||||
|
card.focus()
|
||||||
|
},
|
||||||
openCard() {
|
openCard() {
|
||||||
if (this.dragging) {
|
if (this.dragging) {
|
||||||
return
|
return
|
||||||
@@ -172,18 +215,53 @@ export default {
|
|||||||
const boardId = this.card && this.card.boardId ? this.card.boardId : this.$route.params.id
|
const boardId = this.card && this.card.boardId ? this.card.boardId : this.$route.params.id
|
||||||
this.$router.push({ name: 'card', params: { id: boardId, cardId: this.card.id } }).catch(() => {})
|
this.$router.push({ name: 'card', params: { id: boardId, cardId: this.card.id } }).catch(() => {})
|
||||||
},
|
},
|
||||||
startEditing(card) {
|
onTitleBlur(e) {
|
||||||
this.copiedCard = Object.assign({}, card)
|
// TODO Handle empty title
|
||||||
this.editing = true
|
if (e.target.innerText !== this.card.title) {
|
||||||
},
|
this.$store.dispatch('updateCardTitle', {
|
||||||
finishedEdit(card) {
|
...this.card,
|
||||||
if (this.copiedCard.title !== card.title) {
|
title: e.target.innerText,
|
||||||
this.$store.dispatch('updateCardTitle', this.copiedCard)
|
})
|
||||||
}
|
}
|
||||||
this.editing = false
|
this.$store.dispatch('toggleShortcutLock', false)
|
||||||
|
},
|
||||||
|
onTitleFocus() {
|
||||||
|
this.$store.dispatch('toggleShortcutLock', true)
|
||||||
},
|
},
|
||||||
cancelEdit() {
|
cancelEdit() {
|
||||||
this.editing = false
|
this.$refs.titleContentEditable.textContent = this.card.title
|
||||||
|
this.$store.dispatch('toggleShortcutLock', false)
|
||||||
|
},
|
||||||
|
handleCardKeyboardShortcut(key) {
|
||||||
|
if (OCP.Accessibility.disableKeyboardShortcuts()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.canEdit || this.$store.state.shortcutLock || key.shiftKey || key.ctrlKey || key.altKey || key.metaKey) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (key.code) {
|
||||||
|
case 'KeyE':
|
||||||
|
this.$refs.titleContentEditable?.focus()
|
||||||
|
break
|
||||||
|
case 'KeyA':
|
||||||
|
this.$store.dispatch('archiveUnarchiveCard', { ...this.card, archived: !this.card.archived })
|
||||||
|
break
|
||||||
|
case 'KeyO':
|
||||||
|
this.$store.dispatch('changeCardDoneStatus', { ...this.card, done: !this.card.done })
|
||||||
|
break
|
||||||
|
case 'KeyM':
|
||||||
|
this.$el.querySelector('button.action-item__menutoggle')?.click()
|
||||||
|
break
|
||||||
|
case 'Enter':
|
||||||
|
case 'Space':
|
||||||
|
this.openCard().then(() => document.getElementById('app-sidebar-vue')?.focus())
|
||||||
|
break
|
||||||
|
case 'KeyS':
|
||||||
|
this.toggleSelfAsignment()
|
||||||
|
break
|
||||||
|
}
|
||||||
},
|
},
|
||||||
applyLabelFilter(label) {
|
applyLabelFilter(label) {
|
||||||
if (this.dragging) {
|
if (this.dragging) {
|
||||||
@@ -191,6 +269,18 @@ export default {
|
|||||||
}
|
}
|
||||||
this.$nextTick(() => this.$store.dispatch('toggleFilter', { tags: [label.id] }))
|
this.$nextTick(() => this.$store.dispatch('toggleFilter', { tags: [label.id] }))
|
||||||
},
|
},
|
||||||
|
toggleSelfAsignment() {
|
||||||
|
const isAssigned = this.card.assignedUsers.find(
|
||||||
|
(item) => item.type === 0 && item.participant.uid === getCurrentUser()?.uid,
|
||||||
|
)
|
||||||
|
this.$store.dispatch(isAssigned ? 'removeUserFromCard' : 'assignCardToUser', {
|
||||||
|
card: this.card,
|
||||||
|
assignee: {
|
||||||
|
userId: getCurrentUser()?.uid,
|
||||||
|
type: 0,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -199,62 +289,72 @@ export default {
|
|||||||
@import './../../css/animations';
|
@import './../../css/animations';
|
||||||
@import './../../css/variables';
|
@import './../../css/variables';
|
||||||
|
|
||||||
|
@mixin dark-card {
|
||||||
|
border: 2px solid var(--color-border-dark);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
transition: box-shadow 0.1s ease-in-out;
|
transition: border 0.1s ease-in-out;
|
||||||
box-shadow: 0 0 2px 0 var(--color-box-shadow);
|
|
||||||
border-radius: var(--border-radius-large);
|
border-radius: var(--border-radius-large);
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
background-color: var(--color-main-background);
|
background-color: var(--color-main-background);
|
||||||
margin-bottom: $card-spacing;
|
margin-bottom: $card-spacing;
|
||||||
|
padding: var(--default-grid-baseline) $card-padding;
|
||||||
|
border: 2px solid var(--color-border);
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
&:deep(*) {
|
&:deep(*) {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.dark &, body.theme--dark & {
|
&.current-card {
|
||||||
border: 2px solid var(--color-border);
|
border: 2px solid var(--color-primary-element);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:focus, &:focus-visible, &:focus-within {
|
||||||
box-shadow: 0 0 5px 0 var(--color-box-shadow);
|
outline: none;
|
||||||
}
|
border: 2px solid var(--color-border-maxcontrast);
|
||||||
&.current-card {
|
&.current-card {
|
||||||
box-shadow: 0 0 5px 1px var(--color-box-shadow);
|
border: 2px solid var(--color-primary-element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-upper {
|
.card-upper {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-height: 44px;
|
|
||||||
form {
|
|
||||||
display: flex;
|
|
||||||
padding: 3px 5px;
|
|
||||||
width: 100%;
|
|
||||||
input[type=text] {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 5px $card-padding;
|
margin: 0;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
|
align-self: center;
|
||||||
&.editable {
|
&.editable {
|
||||||
span {
|
span {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
|
padding-right: 8px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
|
||||||
|
&:focus, &:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus-within {
|
||||||
outline: 2px solid var(--color-border-dark);
|
outline: 2px solid var(--color-border-dark);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input[type=text] {
|
.card-menu {
|
||||||
font-size: 100%;
|
height: 44px;
|
||||||
|
align-self: end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,13 +363,6 @@ export default {
|
|||||||
|
|
||||||
.card-controls {
|
.card-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-left: $card-padding;
|
|
||||||
margin-right: $card-padding;
|
|
||||||
|
|
||||||
& > div {
|
|
||||||
display: flex;
|
|
||||||
max-height: 44px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
&.card__editable .card-controls {
|
&.card__editable .card-controls {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
@@ -277,10 +370,16 @@ export default {
|
|||||||
&.card__archived {
|
&.card__archived {
|
||||||
background-color: var(--color-background-dark);
|
background-color: var(--color-background-dark);
|
||||||
}
|
}
|
||||||
}
|
.card-labels {
|
||||||
|
display: flex;
|
||||||
|
align-items: end;
|
||||||
|
margin-bottom: var(--default-grid-baseline);
|
||||||
|
|
||||||
.duedate {
|
.labels {
|
||||||
margin-right: 9px;
|
flex-wrap: wrap;
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
@@ -311,6 +410,10 @@ export default {
|
|||||||
|
|
||||||
.duedate {
|
.duedate {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
display: flex;
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
margin-top: 6px;
|
||||||
}
|
}
|
||||||
&.has-labels {
|
&.has-labels {
|
||||||
padding-bottom: $card-padding;
|
padding-bottom: $card-padding;
|
||||||
@@ -326,5 +429,20 @@ export default {
|
|||||||
font-size: 0;
|
font-size: 0;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
.card-menu {
|
||||||
|
align-self: start !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.card {
|
||||||
|
@include dark-card;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.card-menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -21,222 +21,24 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="card">
|
<div v-if="card" class="card-menu" @click.stop.prevent>
|
||||||
<div @click.stop.prevent>
|
<NcActions>
|
||||||
<NcActions>
|
<CardMenuEntries :card="card" />
|
||||||
<NcActionButton v-if="showArchived === false && !isCurrentUserAssigned"
|
</NcActions>
|
||||||
icon="icon-user"
|
|
||||||
:close-after-click="true"
|
|
||||||
@click="assignCardToMe()">
|
|
||||||
{{ t('deck', 'Assign to me') }}
|
|
||||||
</NcActionButton>
|
|
||||||
<NcActionButton v-if="showArchived === false && isCurrentUserAssigned"
|
|
||||||
icon="icon-user"
|
|
||||||
:close-after-click="true"
|
|
||||||
@click="unassignCardFromMe()">
|
|
||||||
{{ t('deck', 'Unassign myself') }}
|
|
||||||
</NcActionButton>
|
|
||||||
<NcActionButton icon="icon-external" :close-after-click="true" @click="modalShow=true">
|
|
||||||
{{ t('deck', 'Move card') }}
|
|
||||||
</NcActionButton>
|
|
||||||
<NcActionButton v-for="action in cardActions"
|
|
||||||
:key="action.label"
|
|
||||||
:close-after-click="true"
|
|
||||||
:icon="action.icon"
|
|
||||||
@click="action.callback(cardRichObject)">
|
|
||||||
{{ action.label }}
|
|
||||||
</NcActionButton>
|
|
||||||
<NcActionButton icon="icon-settings-dark" :close-after-click="true" @click="openCard">
|
|
||||||
<CardBulletedIcon slot="icon" :size="20" decorative />
|
|
||||||
{{ t('deck', 'Card details') }}
|
|
||||||
</NcActionButton>
|
|
||||||
<NcActionButton :close-after-click="true" @click="archiveUnarchiveCard()">
|
|
||||||
<template #icon>
|
|
||||||
<ArchiveIcon :size="20" decorative />
|
|
||||||
</template>
|
|
||||||
{{ card.archived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
|
|
||||||
</NcActionButton>
|
|
||||||
<NcActionButton v-if="showArchived === false"
|
|
||||||
icon="icon-delete"
|
|
||||||
:close-after-click="true"
|
|
||||||
@click="deleteCard()">
|
|
||||||
{{ t('deck', 'Delete card') }}
|
|
||||||
</NcActionButton>
|
|
||||||
</NcActions>
|
|
||||||
</div>
|
|
||||||
<NcModal v-if="modalShow" :title="t('deck', 'Move card to another board')" @close="modalShow=false">
|
|
||||||
<div class="modal__content">
|
|
||||||
<h3>{{ t('deck', 'Move card to another board') }}</h3>
|
|
||||||
<NcMultiselect v-model="selectedBoard"
|
|
||||||
:placeholder="t('deck', 'Select a board')"
|
|
||||||
:options="activeBoards"
|
|
||||||
:max-height="100"
|
|
||||||
label="title"
|
|
||||||
@select="loadStacksFromBoard" />
|
|
||||||
<NcMultiselect v-model="selectedStack"
|
|
||||||
:placeholder="t('deck', 'Select a list')"
|
|
||||||
:options="stacksFromBoard"
|
|
||||||
:max-height="100"
|
|
||||||
label="title">
|
|
||||||
<span slot="noOptions">
|
|
||||||
{{ t('deck', 'List is empty') }}
|
|
||||||
</span>
|
|
||||||
</NcMultiselect>
|
|
||||||
|
|
||||||
<button :disabled="!isBoardAndStackChoosen" class="primary" @click="moveCard">
|
|
||||||
{{ t('deck', 'Move card') }}
|
|
||||||
</button>
|
|
||||||
<button @click="modalShow=false">
|
|
||||||
{{ t('deck', 'Cancel') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</NcModal>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { NcModal, NcActions, NcActionButton, NcMultiselect } from '@nextcloud/vue'
|
import { NcActions } from '@nextcloud/vue'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import CardMenuEntries from './CardMenuEntries.vue'
|
||||||
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
|
|
||||||
import CardBulletedIcon from 'vue-material-design-icons/CardBulleted.vue'
|
|
||||||
import axios from '@nextcloud/axios'
|
|
||||||
import { generateUrl } from '@nextcloud/router'
|
|
||||||
import { getCurrentUser } from '@nextcloud/auth'
|
|
||||||
import { showUndo } from '@nextcloud/dialogs'
|
|
||||||
|
|
||||||
import '@nextcloud/dialogs/dist/index.css'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CardMenu',
|
name: 'CardMenu',
|
||||||
components: { NcActions, NcActionButton, NcModal, NcMultiselect, ArchiveIcon, CardBulletedIcon },
|
components: { NcActions, CardMenuEntries },
|
||||||
props: {
|
props: {
|
||||||
card: {
|
card: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
modalShow: false,
|
|
||||||
selectedBoard: '',
|
|
||||||
selectedStack: '',
|
|
||||||
stacksFromBoard: [],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'isArchived',
|
|
||||||
'boards',
|
|
||||||
'cardActions',
|
|
||||||
'stackById',
|
|
||||||
]),
|
|
||||||
...mapState({
|
|
||||||
showArchived: state => state.showArchived,
|
|
||||||
currentBoard: state => state.currentBoard,
|
|
||||||
}),
|
|
||||||
canEdit() {
|
|
||||||
if (this.currentBoard) {
|
|
||||||
return this.$store.getters.canEdit
|
|
||||||
}
|
|
||||||
const board = this.$store.getters.boards.find((item) => item.id === this.card.boardId)
|
|
||||||
return !!board?.permissions?.PERMISSION_EDIT
|
|
||||||
},
|
|
||||||
isBoardAndStackChoosen() {
|
|
||||||
if (this.selectedBoard === '' || this.selectedStack === '') {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
isCurrentUserAssigned() {
|
|
||||||
return this.card.assignedUsers.find((item) => item.type === 0 && item.participant.uid === getCurrentUser()?.uid)
|
|
||||||
},
|
|
||||||
activeBoards() {
|
|
||||||
return this.$store.getters.boards.filter((item) => item.deletedAt === 0 && item.archived === false)
|
|
||||||
},
|
|
||||||
|
|
||||||
boardId() {
|
|
||||||
return this.card?.boardId ? this.card.boardId : this.$route.params.id
|
|
||||||
},
|
|
||||||
currentCard() {
|
|
||||||
return this.$store.getters.cardById(this.card.id)
|
|
||||||
},
|
|
||||||
cardRichObject() {
|
|
||||||
return {
|
|
||||||
id: '' + this.currentCard.id,
|
|
||||||
name: this.currentCard.title,
|
|
||||||
boardname: this.currentBoard.title,
|
|
||||||
stackname: this.stackById(this.currentCard.stackId)?.title,
|
|
||||||
link: window.location.protocol + '//' + window.location.host + generateUrl('/apps/deck/') + `#/board/${this.currentBoard.id}/card/${this.currentCard.id}`,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
openCard() {
|
|
||||||
const boardId = this.card?.boardId ? this.card.boardId : this.$route.params.id
|
|
||||||
this.$router.push({ name: 'card', params: { id: boardId, cardId: this.card.id } }).catch(() => {})
|
|
||||||
},
|
|
||||||
deleteCard() {
|
|
||||||
this.$store.dispatch('deleteCard', this.card)
|
|
||||||
const undoCard = { ...this.card, deletedAt: 0 }
|
|
||||||
showUndo(t('deck', 'Card deleted'), () => this.$store.dispatch('cardUndoDelete', undoCard))
|
|
||||||
},
|
|
||||||
archiveUnarchiveCard() {
|
|
||||||
this.$store.dispatch('archiveUnarchiveCard', { ...this.card, archived: !this.card.archived })
|
|
||||||
},
|
|
||||||
assignCardToMe() {
|
|
||||||
this.$store.dispatch('assignCardToUser', {
|
|
||||||
card: this.card,
|
|
||||||
assignee: {
|
|
||||||
userId: getCurrentUser()?.uid,
|
|
||||||
type: 0,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
unassignCardFromMe() {
|
|
||||||
this.$store.dispatch('removeUserFromCard', {
|
|
||||||
card: this.card,
|
|
||||||
assignee: {
|
|
||||||
userId: getCurrentUser()?.uid,
|
|
||||||
type: 0,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
async moveCard() {
|
|
||||||
this.copiedCard = Object.assign({}, this.card)
|
|
||||||
this.copiedCard.stackId = this.selectedStack.id
|
|
||||||
this.$store.dispatch('moveCard', this.copiedCard)
|
|
||||||
if (parseInt(this.boardId) === parseInt(this.selectedStack.boardId)) {
|
|
||||||
await this.$store.commit('addNewCard', { ...this.copiedCard })
|
|
||||||
}
|
|
||||||
this.modalShow = false
|
|
||||||
},
|
|
||||||
async loadStacksFromBoard(board) {
|
|
||||||
try {
|
|
||||||
const url = generateUrl('/apps/deck/stacks/' + board.id)
|
|
||||||
const response = await axios.get(url)
|
|
||||||
this.stacksFromBoard = response.data
|
|
||||||
} catch (err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.modal__content {
|
|
||||||
width: 25vw;
|
|
||||||
min-width: 250px;
|
|
||||||
min-height: 120px;
|
|
||||||
text-align: center;
|
|
||||||
margin: 20px 20px 100px 20px;
|
|
||||||
|
|
||||||
.multiselect {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal__content button {
|
|
||||||
float: right;
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user