Compare commits
645 Commits
backport/6
...
v1.11.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fa6123e53 | ||
|
|
06f209ed04 | ||
|
|
b04dbeadff | ||
|
|
2d4eaee796 | ||
|
|
91b2487eed | ||
|
|
4b3c3c6242 | ||
|
|
e2b43309af | ||
|
|
4928297dd6 | ||
|
|
c04e123d22 | ||
|
|
51dfc9f158 | ||
|
|
60a4c16cc9 | ||
|
|
3d65c2f1ea | ||
|
|
3d3c6df7ab | ||
|
|
f98226b4ab | ||
|
|
c9f83ead42 | ||
|
|
9aa888cef7 | ||
|
|
00e650a230 | ||
|
|
324cdf72db | ||
|
|
1cbdfd263f | ||
|
|
e322a2e000 | ||
|
|
81abfff44a | ||
|
|
2123ae6169 | ||
|
|
c8bf47376a | ||
|
|
32d38b6cb8 | ||
|
|
b60f6e3fa0 | ||
|
|
2dfe686994 | ||
|
|
bc322a0da5 | ||
|
|
8ad3705e72 | ||
|
|
9a172cdb5a | ||
|
|
b5e047c5d1 | ||
|
|
e7feac81b9 | ||
|
|
017fa30a4b | ||
|
|
ddf9d554f5 | ||
|
|
9eb51b0fa8 | ||
|
|
620b61bd79 | ||
|
|
7387beee39 | ||
|
|
aeaf5d201b | ||
|
|
1021b7197a | ||
|
|
ecd063bc89 | ||
|
|
9614dc3b17 | ||
|
|
f8251e9423 | ||
|
|
d4c1f855cd | ||
|
|
8032fe6964 | ||
|
|
36533a3952 | ||
|
|
48df7928bf | ||
|
|
ae51a8bb02 | ||
|
|
3f1f834849 | ||
|
|
4390969143 | ||
|
|
f942d803d2 | ||
|
|
9e5584de89 | ||
|
|
e4b38fdc96 | ||
|
|
e0c30deb12 | ||
|
|
be224c64e9 | ||
|
|
6a3655ddfd | ||
|
|
78b55d5f5d | ||
|
|
c397d3e6ab | ||
|
|
41eed1e637 | ||
|
|
f3b9b99152 | ||
|
|
4821017b7c | ||
|
|
e24fddc61b | ||
|
|
7ec74261b4 | ||
|
|
c796f05241 | ||
|
|
92b91f6108 | ||
|
|
66cb1933e3 | ||
|
|
2ee2191430 | ||
|
|
9aa84c7e07 | ||
|
|
2ad25b034b | ||
|
|
a7e8bd9055 | ||
|
|
a0fb2f7297 | ||
|
|
30fb9ea528 | ||
|
|
b9543981a5 | ||
|
|
9b95895965 | ||
|
|
902e806a6a | ||
|
|
da7d7deb65 | ||
|
|
f94c7f01e0 | ||
|
|
1afbf3436a | ||
|
|
b81c49bd38 | ||
|
|
b67a5cb7d7 | ||
|
|
f47802b053 | ||
|
|
dbfead42cc | ||
|
|
61d236cfb4 | ||
|
|
17799a490b | ||
|
|
f7b691a8a3 | ||
|
|
d558a65383 | ||
|
|
7abbe6c0b5 | ||
|
|
3830ee6d80 | ||
|
|
4c432fea5a | ||
|
|
66d0883f0d | ||
|
|
c82eff05b5 | ||
|
|
e3c0f7da21 | ||
|
|
e38d93edf1 | ||
|
|
dbd4058a0e | ||
|
|
2ae4cef580 | ||
|
|
322676d06f | ||
|
|
fbc2e4830d | ||
|
|
d1f588c668 | ||
|
|
a78e566c8e | ||
|
|
c18d7c8486 | ||
|
|
7eceacdca8 | ||
|
|
2c94b89447 | ||
|
|
efb5f8e28d | ||
|
|
c2d014ef93 | ||
|
|
2fe2f824e0 | ||
|
|
69f7c2e623 | ||
|
|
d5eeb5cd43 | ||
|
|
507e8b027f | ||
|
|
0ba3ae663a | ||
|
|
0e991947a6 | ||
|
|
0c5e28664a | ||
|
|
69f6764d80 | ||
|
|
363b9d0a44 | ||
|
|
0429d0471c | ||
|
|
24bef69476 | ||
|
|
556e721471 | ||
|
|
86551e9c8e | ||
|
|
76f20011c1 | ||
|
|
6d50829f43 | ||
|
|
46bc0f3b94 | ||
|
|
4c558f1ae4 | ||
|
|
1c03b1529c | ||
|
|
ac6ad995cd | ||
|
|
fc96836c93 | ||
|
|
fc063a446c | ||
|
|
b0ee7ffa26 | ||
|
|
994d351ac1 | ||
|
|
c1ce0aaabe | ||
|
|
bed7f63461 | ||
|
|
1ab361d280 | ||
|
|
3323100808 | ||
|
|
6cd47a9854 | ||
|
|
0bf4905030 | ||
|
|
f955bad413 | ||
|
|
2731a044ce | ||
|
|
1189dc083f | ||
|
|
c72c6b7f29 | ||
|
|
6e5d88d2b7 | ||
|
|
e4db2c9ace | ||
|
|
6fca0cc5ff | ||
|
|
8641cfb9ea | ||
|
|
b19dddfa84 | ||
|
|
6da100f39f | ||
|
|
eb9288d2bb | ||
|
|
a54eea62de | ||
|
|
80dd40d595 | ||
|
|
6ac40933ce | ||
|
|
8f3c22f718 | ||
|
|
bf043b455a | ||
|
|
16d930df22 | ||
|
|
5074b47f7d | ||
|
|
e24eb88cc4 | ||
|
|
b70204c5b1 | ||
|
|
99d47d0ea2 | ||
|
|
1620e35f74 | ||
|
|
4600a8c122 | ||
|
|
329272d65a | ||
|
|
c4b0e08d44 | ||
|
|
75242c09d2 | ||
|
|
e2c78434e4 | ||
|
|
3749f4d9b0 | ||
|
|
7fe13533b9 | ||
|
|
0a9b64c758 | ||
|
|
460a08effa | ||
|
|
3aea97bdae | ||
|
|
a33bb9dfb2 | ||
|
|
72375fcfab | ||
|
|
e52c520550 | ||
|
|
454d87c1d0 | ||
|
|
7620ec382e | ||
|
|
1184d5c6bf | ||
|
|
8fdd2d134b | ||
|
|
395c93366b | ||
|
|
284bc6e9c5 | ||
|
|
04b769d6d6 | ||
|
|
5a1a498af9 | ||
|
|
e821ba1341 | ||
|
|
f435f66cf5 | ||
|
|
f9f45d0aec | ||
|
|
a9227ee883 | ||
|
|
fdbc6fdc0f | ||
|
|
e4e39faa58 | ||
|
|
d63ebaf351 | ||
|
|
0ae87e788d | ||
|
|
3ebed58179 | ||
|
|
8e84aa0c8e | ||
|
|
747ca07129 | ||
|
|
9d0a5783d9 | ||
|
|
6519f14761 | ||
|
|
fec79db898 | ||
|
|
ba282cd698 | ||
|
|
175db14042 | ||
|
|
89bbe502ff | ||
|
|
86279fd06a | ||
|
|
69ff3454b4 | ||
|
|
10a3060454 | ||
|
|
0542900bb3 | ||
|
|
bd2e74770e | ||
|
|
8a576880a8 | ||
|
|
e19ffd163c | ||
|
|
a3e870d54d | ||
|
|
8c2c387525 | ||
|
|
62dee21821 | ||
|
|
d16249726c | ||
|
|
ae0beda636 | ||
|
|
c4593568c8 | ||
|
|
54c8202d1f | ||
|
|
4746754c25 | ||
|
|
fe7c4430f5 | ||
|
|
db2d80a2b9 | ||
|
|
5495f35d46 | ||
|
|
b9f8c598b3 | ||
|
|
f8b5b08871 | ||
|
|
224b1033ab | ||
|
|
359d4da5e3 | ||
|
|
ad846b9d1a | ||
|
|
bc85a944b1 | ||
|
|
16286010ef | ||
|
|
517d79156a | ||
|
|
eaa639e9ba | ||
|
|
fdd86f68f0 | ||
|
|
1417051b48 | ||
|
|
0985179e58 | ||
|
|
05cd47141f | ||
|
|
e389ac4ad6 | ||
|
|
1257b7d77b | ||
|
|
f12c56ae0d | ||
|
|
6e6fc25b35 | ||
|
|
1b670aafa3 | ||
|
|
1f5071ad5f | ||
|
|
f0921676a4 | ||
|
|
e7c7219b76 | ||
|
|
c01af6b5bc | ||
|
|
6d27c56ef3 | ||
|
|
ab49524214 | ||
|
|
a50884a6b7 | ||
|
|
defb10bee0 | ||
|
|
4fc4b5b0c2 | ||
|
|
af142340f6 | ||
|
|
449b576c33 | ||
|
|
332143eff5 | ||
|
|
9cbd3f9e87 | ||
|
|
5c50bcab88 | ||
|
|
6daebf941a | ||
|
|
9ecf52952b | ||
|
|
cfff7855fc | ||
|
|
b692630900 | ||
|
|
f719264979 | ||
|
|
1bf4e4c623 | ||
|
|
3520d831e9 | ||
|
|
07b805621d | ||
|
|
4b0ceee2ac | ||
|
|
b8edc70db2 | ||
|
|
ef72c924e7 | ||
|
|
1577582def | ||
|
|
b24d512fda | ||
|
|
e1bd8b2d72 | ||
|
|
48dfe02fe4 | ||
|
|
aa5fb57cb4 | ||
|
|
818a08b6a1 | ||
|
|
0ef2041a29 | ||
|
|
b7d624c671 | ||
|
|
6b5667dd8f | ||
|
|
26a03c3b86 | ||
|
|
5569028a72 | ||
|
|
9aeec692d0 | ||
|
|
0d754c713c | ||
|
|
6c8b28f68c | ||
|
|
41743bfe65 | ||
|
|
64427acb6b | ||
|
|
58219901ad | ||
|
|
869c460e40 | ||
|
|
487941532a | ||
|
|
857a82ecff | ||
|
|
09a2f0ea5e | ||
|
|
66e33773e5 | ||
|
|
230bffc85a | ||
|
|
9f5936fe16 | ||
|
|
ce6793b486 | ||
|
|
7f553afe8c | ||
|
|
52d860f447 | ||
|
|
d07c7dd916 | ||
|
|
13ba28bc75 | ||
|
|
9867a8331e | ||
|
|
51146ea811 | ||
|
|
6b81352764 | ||
|
|
30c82eacda | ||
|
|
8c96524e1c | ||
|
|
1277fe2e35 | ||
|
|
d02d397563 | ||
|
|
2675353070 | ||
|
|
f6645753c4 | ||
|
|
eaa9bef731 | ||
|
|
be31a7017b | ||
|
|
f73497d053 | ||
|
|
e098e13cfe | ||
|
|
fbf993ee00 | ||
|
|
d4930eedd7 | ||
|
|
72c328bb9a | ||
|
|
9b8e6282b6 | ||
|
|
16459f96e2 | ||
|
|
b86e0bb0e3 | ||
|
|
c71376cb3f | ||
|
|
796ff48769 | ||
|
|
d33c12b026 | ||
|
|
55b89f66f7 | ||
|
|
3be4068c82 | ||
|
|
6a44b7c765 | ||
|
|
b2b7f2951f | ||
|
|
188eae833e | ||
|
|
a07d8bd687 | ||
|
|
cac3df45da | ||
|
|
a42e6ace9a | ||
|
|
d6a728627c | ||
|
|
b7a4dd928a | ||
|
|
746ae60fc7 | ||
|
|
ce6c480330 | ||
|
|
f6fafb6d6b | ||
|
|
8266fd3ed4 | ||
|
|
7e5dbb608d | ||
|
|
3d1e28442f | ||
|
|
e9574f3fc4 | ||
|
|
f7ba07713e | ||
|
|
c2fd39779f | ||
|
|
cc5e6c349a | ||
|
|
8855ae4d8c | ||
|
|
bcefc2a36c | ||
|
|
d0049b5257 | ||
|
|
ee673e358e | ||
|
|
6038140492 | ||
|
|
047400e05e | ||
|
|
30842fa969 | ||
|
|
f8f81af3f8 | ||
|
|
ffe8aa55d0 | ||
|
|
00d33a582f | ||
|
|
0d61202ecc | ||
|
|
d10e5582d7 | ||
|
|
b3b7d3907d | ||
|
|
4fbb75b073 | ||
|
|
9b00792827 | ||
|
|
06c1835eda | ||
|
|
cadfd3c58a | ||
|
|
755fae987f | ||
|
|
3514416aa6 | ||
|
|
2cfb85b3db | ||
|
|
ab9b24e664 | ||
|
|
d8e0d70031 | ||
|
|
a9a6a87e8a | ||
|
|
3e72c1975d | ||
|
|
48bde61347 | ||
|
|
c17b11192d | ||
|
|
69caca2871 | ||
|
|
036b67c48a | ||
|
|
da15b2f50c | ||
|
|
75688cbb5c | ||
|
|
0fa9544691 | ||
|
|
1e5c3b4fdd | ||
|
|
1843c9e712 | ||
|
|
a7bafab341 | ||
|
|
f94d62d96b | ||
|
|
baf0bba6c3 | ||
|
|
3cac7877f5 | ||
|
|
c4a06a6529 | ||
|
|
f18fc1a9df | ||
|
|
f87d53052a | ||
|
|
6ae5a8d640 | ||
|
|
5f5561f202 | ||
|
|
9e7a547764 | ||
|
|
49b5b0dafe | ||
|
|
d7c62045ba | ||
|
|
e97e4dc62f | ||
|
|
9ded432281 | ||
|
|
31fbe0346e | ||
|
|
bbba55e415 | ||
|
|
48e0b2d913 | ||
|
|
d2f9743249 | ||
|
|
978a8f3e8d | ||
|
|
e5597fb7c1 | ||
|
|
fdcbba4f53 | ||
|
|
076ff122fc | ||
|
|
4a721cf7bd | ||
|
|
618f030cef | ||
|
|
0ff409a5f4 | ||
|
|
48cc66767a | ||
|
|
d67c5a2052 | ||
|
|
be80476de7 | ||
|
|
eb2fae6d77 | ||
|
|
6e88dd4c1b | ||
|
|
09819dc3ef | ||
|
|
bf356216f6 | ||
|
|
437d0cca21 | ||
|
|
61b2117008 | ||
|
|
4f17681227 | ||
|
|
55df8704b7 | ||
|
|
f1e0a6d87d | ||
|
|
837f9e9cdc | ||
|
|
82e9471857 | ||
|
|
e2f7fafe6a | ||
|
|
a70d9df08f | ||
|
|
97493f3a9f | ||
|
|
0d91aad137 | ||
|
|
2f3889aff8 | ||
|
|
9178f6fb08 | ||
|
|
a68d505c06 | ||
|
|
1822c153ed | ||
|
|
5930f135a6 | ||
|
|
2159ce8a9c | ||
|
|
9cbcc76cd7 | ||
|
|
0643f3ae5b | ||
|
|
8c276b9c07 | ||
|
|
c62b6ab955 | ||
|
|
780169a4a8 | ||
|
|
6b2eba5e29 | ||
|
|
a6aba64d27 | ||
|
|
f7f1dfaa9e | ||
|
|
18f34b8de9 | ||
|
|
af48d11758 | ||
|
|
dbe9ba133d | ||
|
|
183113a4f1 | ||
|
|
51750a1cdf | ||
|
|
c5b11b344e | ||
|
|
55296059a9 | ||
|
|
f6805b87e1 | ||
|
|
21f32b8e62 | ||
|
|
e1413b1c1e | ||
|
|
f37258a85d | ||
|
|
9dad72f8d4 | ||
|
|
52bfeb8062 | ||
|
|
0685fc7322 | ||
|
|
9c5c46510a | ||
|
|
582d5045f9 | ||
|
|
66e3ca55a6 | ||
|
|
3f1418749b | ||
|
|
5617f0f290 | ||
|
|
87318087a6 | ||
|
|
67e839017d | ||
|
|
3de219d48c | ||
|
|
68232ec293 | ||
|
|
e402284366 | ||
|
|
1dffc29338 | ||
|
|
d8623b0aa5 | ||
|
|
9686ee8ed9 | ||
|
|
ea6182c289 | ||
|
|
69254008c6 | ||
|
|
eb17f3b466 | ||
|
|
5f4cf248ef | ||
|
|
7744fc62e6 | ||
|
|
42e7818d87 | ||
|
|
1329466173 | ||
|
|
203befc219 | ||
|
|
dd24eab75d | ||
|
|
1195acc523 | ||
|
|
ef5dcc5c52 | ||
|
|
8fe2cab239 | ||
|
|
aefeb93ee0 | ||
|
|
7dbde8e3d3 | ||
|
|
35440c41c7 | ||
|
|
c893ee6586 | ||
|
|
ba88ee898d | ||
|
|
a6526b1072 | ||
|
|
b1b3c6b779 | ||
|
|
293ad83476 | ||
|
|
ceea3ab007 | ||
|
|
5592f2557d | ||
|
|
5b22c3b841 | ||
|
|
d1b77cb541 | ||
|
|
680595e5ca | ||
|
|
ad6d3bf29c | ||
|
|
b738161b1f | ||
|
|
2ac6df3846 | ||
|
|
d195f2a12c | ||
|
|
e926a0a6d0 | ||
|
|
2336e63459 | ||
|
|
4719cea172 | ||
|
|
dc9b2b5c7f | ||
|
|
4881de7bfe | ||
|
|
84c8d70eef | ||
|
|
3da4e2498f | ||
|
|
bbb69789f2 | ||
|
|
8e21035ba2 | ||
|
|
a5a3d0aa45 | ||
|
|
e8e1630ed6 | ||
|
|
07c9c276ee | ||
|
|
2a083caa37 | ||
|
|
3a2ac7abc2 | ||
|
|
beafcfa743 | ||
|
|
1881010b7a | ||
|
|
07ba4b2e4a | ||
|
|
a8466d1426 | ||
|
|
b0af2fef2d | ||
|
|
8feeb7005d | ||
|
|
0af05d62b7 | ||
|
|
4b9bae2753 | ||
|
|
cc9750ace7 | ||
|
|
8cabd6001e | ||
|
|
73c6487798 | ||
|
|
5f4c4cdce7 | ||
|
|
e48a1c6a94 | ||
|
|
e2ac4df537 | ||
|
|
ab8d4b8432 | ||
|
|
6318a314c1 | ||
|
|
fb7f316b26 | ||
|
|
7a4ae5fa2c | ||
|
|
4c05c4039b | ||
|
|
c683044d2c | ||
|
|
b381588199 | ||
|
|
4e4da92ad6 | ||
|
|
22fb404774 | ||
|
|
2984c71d32 | ||
|
|
9824c578ad | ||
|
|
ca3c93fed8 | ||
|
|
3912b3c3ae | ||
|
|
0f8a6c0d25 | ||
|
|
2f349e0138 | ||
|
|
9aded3ccb8 | ||
|
|
a32b3cd3cf | ||
|
|
731a491bd1 | ||
|
|
9542dde184 | ||
|
|
1cd5f2f496 | ||
|
|
4d10663406 | ||
|
|
ff75b39aca | ||
|
|
62e06a0d24 | ||
|
|
54be05e448 | ||
|
|
ab6ae1df0d | ||
|
|
d3d1e0af36 | ||
|
|
59e0ffaf05 | ||
|
|
4287bde8ce | ||
|
|
70917f3f65 | ||
|
|
ade0554c70 | ||
|
|
32d4179bdc | ||
|
|
81e567b680 | ||
|
|
5819a19a88 | ||
|
|
188d722bf2 | ||
|
|
a6e09adf77 | ||
|
|
4fe38c62dd | ||
|
|
eec4e614bd | ||
|
|
6714e18889 | ||
|
|
275e8eedaf | ||
|
|
f921f5d5a6 | ||
|
|
856aeb146d | ||
|
|
0c1ef382aa | ||
|
|
36fac54f0f | ||
|
|
498ab8bd0d | ||
|
|
9947aa4288 | ||
|
|
754903ccca | ||
|
|
13d5289e73 | ||
|
|
06ccb7b7b9 | ||
|
|
91c0704186 | ||
|
|
228a2bdca9 | ||
|
|
9e23a89659 | ||
|
|
5619c683c2 | ||
|
|
ca347cbc80 | ||
|
|
19a4832caf | ||
|
|
9f0783c4c6 | ||
|
|
6e5111b266 | ||
|
|
bed3096f11 | ||
|
|
9538cccf50 | ||
|
|
6a3c242176 | ||
|
|
93959b0efc | ||
|
|
99a42e7639 | ||
|
|
ed02d93a92 | ||
|
|
1dce8b797d | ||
|
|
5d17c3167b | ||
|
|
e0d59c0653 | ||
|
|
0308599096 | ||
|
|
00e1a1da74 | ||
|
|
5783d9ec15 | ||
|
|
01b4a4d264 | ||
|
|
fbc703b033 | ||
|
|
ee7313beac | ||
|
|
3dc99f129c | ||
|
|
11a5362108 | ||
|
|
18343eea89 | ||
|
|
6ceb1b3e09 | ||
|
|
e5873c566b | ||
|
|
93f9db2549 | ||
|
|
de78de243f | ||
|
|
e82ba2aebc | ||
|
|
50298b14ff | ||
|
|
697d2ce8d5 | ||
|
|
90e986dfc1 | ||
|
|
6e844b22fd | ||
|
|
9ecafadc43 | ||
|
|
08a9714842 | ||
|
|
ed50c9413c | ||
|
|
b0c026bc83 | ||
|
|
2adec18b1d | ||
|
|
30371b0e06 | ||
|
|
afc0c662d2 | ||
|
|
146a5eb602 | ||
|
|
317ee4901b | ||
|
|
3d254f7d62 | ||
|
|
948b8f5f84 | ||
|
|
d555bf1cab | ||
|
|
0456e43378 | ||
|
|
5cf3f48de9 | ||
|
|
32b4b18868 | ||
|
|
ec937a8edf | ||
|
|
33dae40326 | ||
|
|
d032f8a820 | ||
|
|
4b20bfca74 | ||
|
|
e29eb22a49 | ||
|
|
b125e18c52 | ||
|
|
736222f975 | ||
|
|
2b33583bd7 | ||
|
|
b77cb9b270 | ||
|
|
1c116012ce | ||
|
|
d7fa2ae265 | ||
|
|
3c407c06ff | ||
|
|
3fdb70e547 | ||
|
|
febd4b1a0b | ||
|
|
12c3e476f9 | ||
|
|
ec8c782b5a | ||
|
|
0575926692 | ||
|
|
617671c004 | ||
|
|
2f9cf4df37 | ||
|
|
7e5e0e2814 | ||
|
|
dd09c2ad69 | ||
|
|
87dfdd62d4 | ||
|
|
bd77b12f9b | ||
|
|
b861f2b1cd | ||
|
|
8cf3853387 | ||
|
|
313b5b0e15 | ||
|
|
7c81c7237b | ||
|
|
82eb262433 | ||
|
|
5ba5eb89b2 | ||
|
|
b714be7829 | ||
|
|
36e66e4345 | ||
|
|
542c70eac1 | ||
|
|
f54722cd5a | ||
|
|
5c29392428 | ||
|
|
b8071def95 | ||
|
|
fba6dc0a45 | ||
|
|
536029e6c6 | ||
|
|
77b81f4686 | ||
|
|
7ba4b2617a | ||
|
|
56e9d5ceb4 | ||
|
|
bb569f7df7 | ||
|
|
4060c7a14a | ||
|
|
4cebac2306 | ||
|
|
2fd8cab627 | ||
|
|
4921f3dd62 | ||
|
|
a268d428bf | ||
|
|
ab11f47afa | ||
|
|
0751f604ec | ||
|
|
c2aec9f312 | ||
|
|
04e9373c58 |
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -11,10 +11,9 @@ updates:
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- juliushaertl
|
||||
- luka-nextcloud
|
||||
|
||||
- package-ecosystem: npm
|
||||
target-branch: stable28
|
||||
target-branch: stable25
|
||||
versioning-strategy: lockfile-only
|
||||
directory: "/"
|
||||
schedule:
|
||||
@@ -31,7 +30,7 @@ updates:
|
||||
- dependencies
|
||||
|
||||
- package-ecosystem: npm
|
||||
target-branch: stable27
|
||||
target-branch: stable24
|
||||
versioning-strategy: lockfile-only
|
||||
directory: "/"
|
||||
schedule:
|
||||
@@ -57,8 +56,6 @@ updates:
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- juliushaertl
|
||||
- luka-nextcloud
|
||||
|
||||
- package-ecosystem: composer
|
||||
directory: "/tests/integration"
|
||||
schedule:
|
||||
@@ -69,8 +66,6 @@ updates:
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- juliushaertl
|
||||
- luka-nextcloud
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
@@ -81,4 +76,3 @@ updates:
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- juliushaertl
|
||||
- luka-nextcloud
|
||||
|
||||
8
.github/workflows/appbuild.yml
vendored
8
.github/workflows/appbuild.yml
vendored
@@ -16,15 +16,15 @@ jobs:
|
||||
node-version: [16.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.1
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.0.2
|
||||
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.30.0
|
||||
uses: shivammathur/setup-php@2.25.1
|
||||
with:
|
||||
php-version: '7.4'
|
||||
tools: composer
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
uname -a
|
||||
RUST_BACKTRACE=1 krankerl --version
|
||||
RUST_BACKTRACE=1 krankerl package
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Deck app tarball
|
||||
path: build/artifacts/deck.tar.gz
|
||||
|
||||
27
.github/workflows/appstore-build-publish.yml
vendored
27
.github/workflows/appstore-build-publish.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
types: [published]
|
||||
|
||||
env:
|
||||
PHP_VERSION: 8.2
|
||||
PHP_VERSION: 8.1
|
||||
|
||||
jobs:
|
||||
build_and_publish:
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check actor permission
|
||||
uses: skjnldsv/check-actor-permission@69e92a3c4711150929bca9fcf34448c5bf5526e7 # v3.0
|
||||
uses: skjnldsv/check-actor-permission@e591dbfe838300c007028e1219ca82cc26e8d7c5 # v2.1
|
||||
with:
|
||||
require: write
|
||||
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
echo "APP_VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
with:
|
||||
path: ${{ env.APP_NAME }}
|
||||
|
||||
@@ -44,19 +44,19 @@ jobs:
|
||||
expression: "//info//dependencies//nextcloud/@min-version"
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
||||
uses: skjnldsv/read-package-engines-version-actions@0ce2ed60f6df073a62a77c0a4958dd0fc68e32e7 # v2.1
|
||||
id: versions
|
||||
# Continue if no package.json
|
||||
continue-on-error: true
|
||||
with:
|
||||
path: ${{ env.APP_NAME }}
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^9'
|
||||
fallbackNode: "^16"
|
||||
fallbackNpm: "^7"
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
# Skip if no package.json
|
||||
if: ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
||||
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3
|
||||
with:
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
||||
|
||||
- name: Set up php ${{ env.PHP_VERSION }}
|
||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
||||
uses: shivammathur/setup-php@2.25.1 # v2
|
||||
with:
|
||||
php-version: ${{ env.PHP_VERSION }}
|
||||
coverage: none
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
|
||||
- name: Check composer.json
|
||||
id: check_composer
|
||||
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v2
|
||||
uses: andstor/file-existence-action@20b4d2e596410855db8f9ca21e96fbe18e12930b # v2
|
||||
with:
|
||||
files: "${{ env.APP_NAME }}/composer.json"
|
||||
|
||||
@@ -88,8 +88,6 @@ jobs:
|
||||
- name: Build ${{ env.APP_NAME }}
|
||||
# Skip if no package.json
|
||||
if: ${{ steps.versions.outputs.nodeVersion }}
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
run: |
|
||||
cd ${{ env.APP_NAME }}
|
||||
npm ci
|
||||
@@ -97,7 +95,7 @@ jobs:
|
||||
|
||||
- name: Check Krankerl config
|
||||
id: krankerl
|
||||
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v2
|
||||
uses: andstor/file-existence-action@20b4d2e596410855db8f9ca21e96fbe18e12930b # v2
|
||||
with:
|
||||
files: ${{ env.APP_NAME }}/krankerl.toml
|
||||
|
||||
@@ -128,10 +126,9 @@ jobs:
|
||||
unzip latest-$NCVERSION.zip
|
||||
|
||||
- name: Checkout server master fallback
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
if: ${{ steps.server-checkout.outcome != 'success' }}
|
||||
with:
|
||||
submodules: true
|
||||
repository: nextcloud/server
|
||||
path: nextcloud
|
||||
|
||||
@@ -151,7 +148,7 @@ jobs:
|
||||
tar -zcvf ${{ env.APP_NAME }}.tar.gz ${{ env.APP_NAME }}
|
||||
|
||||
- name: Attach tarball to github release
|
||||
uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # v2
|
||||
uses: svenstaro/upload-release-action@7319e4733ec7a184d739a6f412c40ffc339b69c7 # v2
|
||||
id: attach_to_release
|
||||
with:
|
||||
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:
|
||||
- name: Add reaction on start
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
|
||||
uses: peter-evans/create-or-update-comment@ca08ebd5dc95aa0cd97021e9708fcd6b87138c9b # v3.0.1
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
repository: ${{ github.event.repository.full_name }}
|
||||
@@ -31,18 +31,18 @@ jobs:
|
||||
reaction-type: "+1"
|
||||
|
||||
- name: Checkout the latest code
|
||||
uses: actions/checkout@v4.1.1 # v3.5.2
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
|
||||
- name: Automatic Rebase
|
||||
uses: cirrus-actions/rebase@b87d48154a87a85666003575337e27b8cd65f691 # 1.8
|
||||
uses: cirrus-actions/rebase@6e572f08c244e2f04f9beb85a943eb618218714d # 1.7
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
|
||||
- name: Add reaction on failure
|
||||
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
|
||||
uses: peter-evans/create-or-update-comment@ca08ebd5dc95aa0cd97021e9708fcd6b87138c9b # v3.0.1
|
||||
if: failure()
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
|
||||
24
.github/workflows/cypress.yml
vendored
24
.github/workflows/cypress.yml
vendored
@@ -19,17 +19,19 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [20.x]
|
||||
node-version: [14.x]
|
||||
# containers: [1, 2, 3]
|
||||
php-versions: [ '8.0' ]
|
||||
databases: [ 'sqlite' ]
|
||||
server-versions: [ 'stable29' ]
|
||||
server-versions: [ 'stable27' ]
|
||||
|
||||
steps:
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.0.2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Set up npm7
|
||||
run: npm i -g npm@7
|
||||
|
||||
- name: Register text Git reference
|
||||
run: |
|
||||
@@ -37,7 +39,7 @@ jobs:
|
||||
echo "text_app_ref=$text_app_ref" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@v4.1.1
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: nextcloud/server
|
||||
ref: ${{ matrix.server-versions }}
|
||||
@@ -50,19 +52,19 @@ jobs:
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
|
||||
- name: Checkout ${{ env.APP_NAME }}
|
||||
uses: actions/checkout@v4.1.1
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: Checkout text
|
||||
uses: actions/checkout@v4.1.1
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: nextcloud/text
|
||||
ref: ${{ env.text_app_ref }}
|
||||
path: apps/text
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2.30.0
|
||||
uses: shivammathur/setup-php@2.25.1
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, zip, gd, apcu
|
||||
@@ -94,9 +96,9 @@ jobs:
|
||||
curl -v http://localhost:8081/index.php/login
|
||||
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v6
|
||||
uses: cypress-io/github-action@v5
|
||||
with:
|
||||
record: false
|
||||
record: true
|
||||
parallel: false
|
||||
wait-on: '${{ env.CYPRESS_baseUrl }}'
|
||||
working-directory: 'apps/${{ env.APP_NAME }}'
|
||||
@@ -106,7 +108,7 @@ jobs:
|
||||
npm_package_name: ${{ env.APP_NAME }}
|
||||
|
||||
- name: Upload test failure screenshots
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: Upload screenshots
|
||||
@@ -114,7 +116,7 @@ jobs:
|
||||
retention-days: 5
|
||||
|
||||
- name: Upload nextcloud logs
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: Upload nextcloud log
|
||||
|
||||
34
.github/workflows/fixup.yml
vendored
34
.github/workflows/fixup.yml
vendored
@@ -3,31 +3,31 @@
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Block fixup and squash commits
|
||||
name: Pull request checks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, ready_for_review, reopened, synchronize]
|
||||
pull_request:
|
||||
types: [opened, ready_for_review, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: fixup-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
group: fixup-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
commit-message-check:
|
||||
if: github.event.pull_request.draft == false
|
||||
commit-message-check:
|
||||
if: github.event.pull_request.draft == false
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
name: Block fixup and squash commits
|
||||
permissions:
|
||||
pull-requests: write
|
||||
name: Block fixup and squash commits
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Run check
|
||||
uses: skjnldsv/block-fixup-merge-action@42d26e1b536ce61e5cf467d65fb76caf4aa85acf # v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- name: Run check
|
||||
uses: xt0rted/block-autosquash-commits-action@79880c36b4811fe549cfffe20233df88876024e7 # v2
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
12
.github/workflows/integration.yml
vendored
12
.github/workflows/integration.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
matrix:
|
||||
php-versions: ['8.1']
|
||||
databases: ['sqlite', 'mysql', 'pgsql']
|
||||
server-versions: ['stable29']
|
||||
server-versions: ['stable27']
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
||||
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@v4.1.1
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: nextcloud/server
|
||||
ref: ${{ matrix.server-versions }}
|
||||
@@ -66,19 +66,19 @@ jobs:
|
||||
cd build/integration && composer require --dev phpunit/phpunit:~9
|
||||
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@v4.1.1
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: Checkout activity
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
repository: nextcloud/activity
|
||||
ref: ${{ matrix.server-versions }}
|
||||
path: apps/activity
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2.30.0
|
||||
uses: shivammathur/setup-php@2.25.1
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql, apcu
|
||||
@@ -114,7 +114,7 @@ jobs:
|
||||
|
||||
- name: Query count
|
||||
if: ${{ matrix.databases == 'mysql' }}
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
|
||||
75
.github/workflows/lint-eslint.yml
vendored
75
.github/workflows/lint-eslint.yml
vendored
@@ -6,9 +6,22 @@
|
||||
# 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
|
||||
|
||||
name: Lint eslint
|
||||
name: Lint
|
||||
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- 'src/**'
|
||||
- 'appinfo/info.xml'
|
||||
- 'package.json'
|
||||
- 'package-lock.json'
|
||||
- 'tsconfig.json'
|
||||
- '.eslintrc.*'
|
||||
- '.eslintignore'
|
||||
- '**.js'
|
||||
- '**.ts'
|
||||
- '**.vue'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -18,52 +31,24 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
src: ${{ steps.changes.outputs.src}}
|
||||
|
||||
steps:
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
name: NPM lint
|
||||
name: eslint
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
||||
uses: skjnldsv/read-package-engines-version-actions@0ce2ed60f6df073a62a77c0a4958dd0fc68e32e7 # v2.1
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^9'
|
||||
fallbackNode: '^16'
|
||||
fallbackNpm: '^7'
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
||||
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3
|
||||
with:
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
@@ -71,25 +56,7 @@ jobs:
|
||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
||||
|
||||
- name: Install dependencies
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
PUPPETEER_SKIP_DOWNLOAD: true
|
||||
run: npm ci
|
||||
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest
|
||||
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
|
||||
|
||||
11
.github/workflows/lint-php-cs.yml
vendored
11
.github/workflows/lint-php-cs.yml
vendored
@@ -3,7 +3,7 @@
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Lint php-cs
|
||||
name: Lint
|
||||
|
||||
on: pull_request
|
||||
|
||||
@@ -22,14 +22,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
|
||||
- name: Set up php8.2
|
||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@2.25.1 # v2
|
||||
with:
|
||||
php-version: 8.2
|
||||
php-version: 8.1
|
||||
coverage: none
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
17
.github/workflows/lint-php.yml
vendored
17
.github/workflows/lint-php.yml
vendored
@@ -3,9 +3,15 @@
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Lint php
|
||||
name: Lint
|
||||
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- stable*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -19,20 +25,19 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: [ '8.0', '8.1', '8.2', '8.3' ]
|
||||
php-versions: [ "8.0", "8.1", "8.2" ]
|
||||
|
||||
name: php-lint
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
||||
uses: shivammathur/setup-php@2.25.1 # v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
coverage: none
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
14
.github/workflows/lint-stylelint.yml
vendored
14
.github/workflows/lint-stylelint.yml
vendored
@@ -3,7 +3,7 @@
|
||||
# https://github.com/nextcloud/.github
|
||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
||||
|
||||
name: Lint stylelint
|
||||
name: Lint
|
||||
|
||||
on: pull_request
|
||||
|
||||
@@ -22,17 +22,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
||||
uses: skjnldsv/read-package-engines-version-actions@0ce2ed60f6df073a62a77c0a4958dd0fc68e32e7 # v2.1
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^9'
|
||||
fallbackNode: '^16'
|
||||
fallbackNpm: '^7'
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
||||
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3
|
||||
with:
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
@@ -40,8 +40,6 @@ jobs:
|
||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
||||
|
||||
- name: Install dependencies
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
run: npm ci
|
||||
|
||||
- name: Lint
|
||||
|
||||
64
.github/workflows/nightly.yml
vendored
Normal file
64
.github/workflows/nightly.yml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
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]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.1
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4.0.2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- 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://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:
|
||||
workflow_dispatch:
|
||||
@@ -18,25 +18,25 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['main', 'master', 'stable28', 'stable27', 'stable26']
|
||||
|
||||
branches: ["main", "master", "stable26", "stable25", "stable24"]
|
||||
|
||||
name: npm-audit-fix-${{ matrix.branches }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
with:
|
||||
ref: ${{ matrix.branches }}
|
||||
|
||||
- name: Read package.json node and npm engines version
|
||||
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
||||
uses: skjnldsv/read-package-engines-version-actions@0ce2ed60f6df073a62a77c0a4958dd0fc68e32e7 # v2.1
|
||||
id: versions
|
||||
with:
|
||||
fallbackNode: '^20'
|
||||
fallbackNpm: '^9'
|
||||
fallbackNode: '^16'
|
||||
fallbackNpm: '^7'
|
||||
|
||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
||||
uses: actions/setup-node@8c91899e586c5b171469028077307d293428b516 # v3
|
||||
with:
|
||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
||||
|
||||
@@ -49,15 +49,13 @@ jobs:
|
||||
|
||||
- name: Run npm ci and npm run build
|
||||
if: always()
|
||||
env:
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
run: |
|
||||
npm ci
|
||||
npm run build --if-present
|
||||
|
||||
- name: Create Pull Request
|
||||
if: always()
|
||||
uses: peter-evans/create-pull-request@70a41aba780001da0a30141984ae2a0c95d8704e # v5
|
||||
uses: peter-evans/create-pull-request@284f54f989303d2699d373481a0cfa13ad5a6666 # v3
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
commit-message: "chore(deps): fix npm audit"
|
||||
|
||||
185
.github/workflows/phpunit-mysql.yml
vendored
185
.github/workflows/phpunit-mysql.yml
vendored
@@ -1,185 +0,0 @@
|
||||
# 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: PHPUnit MySQL
|
||||
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-mysql-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
runs-on: ubuntu-latest-low
|
||||
outputs:
|
||||
matrix: ${{ steps.versions.outputs.sparse-matrix }}
|
||||
steps:
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Get version matrix
|
||||
id: versions
|
||||
uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
|
||||
with:
|
||||
matrix: '{"mysql-versions": ["8.1"]}'
|
||||
|
||||
changes:
|
||||
runs-on: ubuntu-latest-low
|
||||
|
||||
outputs:
|
||||
src: ${{ steps.changes.outputs.src}}
|
||||
|
||||
steps:
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
id: changes
|
||||
continue-on-error: true
|
||||
with:
|
||||
filters: |
|
||||
src:
|
||||
- '.github/workflows/**'
|
||||
- 'appinfo/**'
|
||||
- 'lib/**'
|
||||
- 'templates/**'
|
||||
- 'tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
|
||||
phpunit-mysql:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: [changes, matrix]
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix: ${{ fromJson(needs.matrix.outputs.matrix) }}
|
||||
|
||||
name: MySQL ${{ matrix.mysql-versions }} PHP ${{ matrix.php-versions }} Nextcloud ${{ matrix.server-versions }}
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest
|
||||
ports:
|
||||
- 4444:3306/tcp
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: rootpassword
|
||||
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
|
||||
|
||||
steps:
|
||||
- name: Set app env
|
||||
run: |
|
||||
# Split and keep last
|
||||
echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
submodules: true
|
||||
repository: nextcloud/server
|
||||
ref: ${{ matrix.server-versions }}
|
||||
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
# 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, mysql, pdo_mysql
|
||||
coverage: none
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable ONLY_FULL_GROUP_BY MySQL option
|
||||
run: |
|
||||
echo "SET GLOBAL sql_mode=(SELECT CONCAT(@@sql_mode,',ONLY_FULL_GROUP_BY'));" | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
|
||||
echo "SELECT @@sql_mode;" | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
|
||||
|
||||
- name: Check composer file existence
|
||||
id: check_composer
|
||||
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0
|
||||
with:
|
||||
files: apps/${{ env.APP_NAME }}/composer.json
|
||||
|
||||
- name: Set up dependencies
|
||||
# Only run if phpunit config file exists
|
||||
if: steps.check_composer.outputs.files_exists == 'true'
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer i
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
DB_PORT: 4444
|
||||
run: |
|
||||
mkdir data
|
||||
./occ maintenance:install --verbose --database=mysql --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
./occ app:enable --force ${{ env.APP_NAME }}
|
||||
|
||||
- name: Check PHPUnit script is defined
|
||||
id: check_phpunit
|
||||
continue-on-error: true
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: |
|
||||
composer run --list | grep "^ test:unit " | wc -l | grep 1
|
||||
|
||||
- name: PHPUnit
|
||||
# Only run if phpunit config file exists
|
||||
if: steps.check_phpunit.outcome == 'success'
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer run test:unit
|
||||
|
||||
- name: Check PHPUnit integration script is defined
|
||||
id: check_integration
|
||||
continue-on-error: true
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: |
|
||||
composer run --list | grep "^ test:integration " | wc -l | grep 1
|
||||
|
||||
- name: Run Nextcloud
|
||||
# Only run if phpunit integration config file exists
|
||||
if: steps.check_integration.outcome == 'success'
|
||||
run: php -S localhost:8080 &
|
||||
|
||||
- name: PHPUnit integration
|
||||
# Only run if phpunit integration config file exists
|
||||
if: steps.check_integration.outcome == 'success'
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer run test:integration
|
||||
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
|
||||
- name: Skipped
|
||||
# Fail the action when neither unit nor integration tests ran
|
||||
if: steps.check_phpunit.outcome == 'failure' && steps.check_integration.outcome == 'failure'
|
||||
run: |
|
||||
echo 'Neither PHPUnit nor PHPUnit integration tests are specified in composer.json scripts'
|
||||
exit 1
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest-low
|
||||
needs: [changes, phpunit-mysql]
|
||||
|
||||
if: always()
|
||||
|
||||
name: phpunit-mysql-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-mysql.result != 'success' }}; then exit 1; fi
|
||||
168
.github/workflows/phpunit-pgsql.yml
vendored
168
.github/workflows/phpunit-pgsql.yml
vendored
@@ -1,168 +0,0 @@
|
||||
# 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: PHPUnit pgsql
|
||||
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-pgsql-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
src: ${{ steps.changes.outputs.src}}
|
||||
|
||||
steps:
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
id: changes
|
||||
continue-on-error: true
|
||||
with:
|
||||
filters: |
|
||||
src:
|
||||
- '.github/workflows/**'
|
||||
- 'appinfo/**'
|
||||
- 'lib/**'
|
||||
- 'templates/**'
|
||||
- 'tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
|
||||
phpunit-pgsql:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.2']
|
||||
server-versions: ['stable29']
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: ghcr.io/nextcloud/continuous-integration-postgres-14:latest
|
||||
ports:
|
||||
- 4444:5432/tcp
|
||||
env:
|
||||
POSTGRES_USER: root
|
||||
POSTGRES_PASSWORD: rootpassword
|
||||
POSTGRES_DB: nextcloud
|
||||
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Set app env
|
||||
run: |
|
||||
# Split and keep last
|
||||
echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
submodules: true
|
||||
repository: nextcloud/server
|
||||
ref: ${{ matrix.server-versions }}
|
||||
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
# 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, pgsql, pdo_pgsql
|
||||
coverage: none
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Check composer file existence
|
||||
id: check_composer
|
||||
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v2
|
||||
with:
|
||||
files: apps/${{ env.APP_NAME }}/composer.json
|
||||
|
||||
- name: Set up dependencies
|
||||
# Only run if phpunit config file exists
|
||||
if: steps.check_composer.outputs.files_exists == 'true'
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer i
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
DB_PORT: 4444
|
||||
run: |
|
||||
mkdir data
|
||||
./occ maintenance:install --verbose --database=pgsql --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
./occ app:enable --force ${{ env.APP_NAME }}
|
||||
|
||||
- name: Check PHPUnit script is defined
|
||||
id: check_phpunit
|
||||
continue-on-error: true
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: |
|
||||
composer run --list | grep "^ test:unit " | wc -l | grep 1
|
||||
|
||||
- name: PHPUnit
|
||||
# Only run if phpunit config file exists
|
||||
if: steps.check_phpunit.outcome == 'success'
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer run test:unit
|
||||
|
||||
- name: Check PHPUnit integration script is defined
|
||||
id: check_integration
|
||||
continue-on-error: true
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: |
|
||||
composer run --list | grep "^ test:integration " | wc -l | grep 1
|
||||
|
||||
- name: Run Nextcloud
|
||||
# Only run if phpunit integration config file exists
|
||||
if: steps.check_integration.outcome == 'success'
|
||||
run: php -S localhost:8080 &
|
||||
|
||||
- name: PHPUnit integration
|
||||
# Only run if phpunit integration config file exists
|
||||
if: steps.check_integration.outcome == 'success'
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer run test:integration
|
||||
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
|
||||
- name: Skipped
|
||||
# Fail the action when neither unit nor integration tests ran
|
||||
if: steps.check_phpunit.outcome == 'failure' && steps.check_integration.outcome == 'failure'
|
||||
run: |
|
||||
echo 'Neither PHPUnit nor PHPUnit integration tests are specified in composer.json scripts'
|
||||
exit 1
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest
|
||||
needs: [changes, phpunit-pgsql]
|
||||
|
||||
if: always()
|
||||
|
||||
name: phpunit-pgsql-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-pgsql.result != 'success' }}; then exit 1; fi
|
||||
157
.github/workflows/phpunit-sqlite.yml
vendored
157
.github/workflows/phpunit-sqlite.yml
vendored
@@ -1,157 +0,0 @@
|
||||
# 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: PHPUnit sqlite
|
||||
|
||||
on: pull_request
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: phpunit-sqlite-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
src: ${{ steps.changes.outputs.src}}
|
||||
|
||||
steps:
|
||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
||||
id: changes
|
||||
continue-on-error: true
|
||||
with:
|
||||
filters: |
|
||||
src:
|
||||
- '.github/workflows/**'
|
||||
- 'appinfo/**'
|
||||
- 'lib/**'
|
||||
- 'templates/**'
|
||||
- 'tests/**'
|
||||
- 'vendor/**'
|
||||
- 'vendor-bin/**'
|
||||
- '.php-cs-fixer.dist.php'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
|
||||
phpunit-sqlite:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: changes
|
||||
if: needs.changes.outputs.src != 'false'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['8.2']
|
||||
server-versions: ['stable29']
|
||||
|
||||
steps:
|
||||
- name: Set app env
|
||||
run: |
|
||||
# Split and keep last
|
||||
echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
submodules: true
|
||||
repository: nextcloud/server
|
||||
ref: ${{ matrix.server-versions }}
|
||||
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
# 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
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Check composer file existence
|
||||
id: check_composer
|
||||
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v2
|
||||
with:
|
||||
files: apps/${{ env.APP_NAME }}/composer.json
|
||||
|
||||
- name: Set up dependencies
|
||||
# Only run if phpunit config file exists
|
||||
if: steps.check_composer.outputs.files_exists == 'true'
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer i
|
||||
|
||||
- name: Set up Nextcloud
|
||||
env:
|
||||
DB_PORT: 4444
|
||||
run: |
|
||||
mkdir data
|
||||
./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
./occ app:enable --force ${{ env.APP_NAME }}
|
||||
|
||||
- name: Check PHPUnit script is defined
|
||||
id: check_phpunit
|
||||
continue-on-error: true
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: |
|
||||
composer run --list | grep "^ test:unit " | wc -l | grep 1
|
||||
|
||||
- name: PHPUnit
|
||||
# Only run if phpunit config file exists
|
||||
if: steps.check_phpunit.outcome == 'success'
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer run test:unit
|
||||
|
||||
- name: Check PHPUnit integration script is defined
|
||||
id: check_integration
|
||||
continue-on-error: true
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: |
|
||||
composer run --list | grep "^ test:integration " | wc -l | grep 1
|
||||
|
||||
- name: Run Nextcloud
|
||||
# Only run if phpunit integration config file exists
|
||||
if: steps.check_integration.outcome == 'success'
|
||||
run: php -S localhost:8080 &
|
||||
|
||||
- name: PHPUnit integration
|
||||
# Only run if phpunit integration config file exists
|
||||
if: steps.check_integration.outcome == 'success'
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer run test:integration
|
||||
|
||||
- name: Print logs
|
||||
if: always()
|
||||
run: |
|
||||
cat data/nextcloud.log
|
||||
|
||||
- name: Skipped
|
||||
# Fail the action when neither unit nor integration tests ran
|
||||
if: steps.check_phpunit.outcome == 'failure' && steps.check_integration.outcome == 'failure'
|
||||
run: |
|
||||
echo 'Neither PHPUnit nor PHPUnit integration tests are specified in composer.json scripts'
|
||||
exit 1
|
||||
|
||||
summary:
|
||||
permissions:
|
||||
contents: none
|
||||
runs-on: ubuntu-latest
|
||||
needs: [changes, phpunit-sqlite]
|
||||
|
||||
if: always()
|
||||
|
||||
name: phpunit-sqlite-summary
|
||||
|
||||
steps:
|
||||
- name: Summary status
|
||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-sqlite.result != 'success' }}; then exit 1; fi
|
||||
102
.github/workflows/phpunit.yml
vendored
Normal file
102
.github/workflows/phpunit.yml
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
name: PHPUnit
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/phpunit.yml'
|
||||
- 'appinfo/**'
|
||||
- 'lib/**'
|
||||
- 'templates/**'
|
||||
- 'tests/**'
|
||||
- 'composer.json'
|
||||
- 'composer.lock'
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable*
|
||||
|
||||
env:
|
||||
APP_NAME: deck
|
||||
|
||||
|
||||
jobs:
|
||||
integration:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['8.0', '8.1']
|
||||
databases: ['sqlite', 'mysql', 'pgsql']
|
||||
server-versions: ['stable27']
|
||||
|
||||
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14
|
||||
ports:
|
||||
- 4445:5432/tcp
|
||||
env:
|
||||
POSTGRES_USER: root
|
||||
POSTGRES_PASSWORD: rootpassword
|
||||
POSTGRES_DB: nextcloud
|
||||
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
|
||||
mysql:
|
||||
image: mariadb:10.5
|
||||
ports:
|
||||
- 4444:3306/tcp
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: rootpassword
|
||||
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 5
|
||||
|
||||
steps:
|
||||
- name: Checkout server
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: nextcloud/server
|
||||
ref: ${{ matrix.server-versions }}
|
||||
|
||||
- name: Checkout submodules
|
||||
shell: bash
|
||||
run: |
|
||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
||||
git submodule sync --recursive
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
|
||||
- name: Checkout app
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: apps/${{ env.APP_NAME }}
|
||||
|
||||
- name: Set up php ${{ matrix.php-versions }}
|
||||
uses: shivammathur/setup-php@2.25.1
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpunit
|
||||
extensions: zip, gd, mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql
|
||||
coverage: none
|
||||
|
||||
- name: Set up PHPUnit
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: composer i
|
||||
|
||||
- name: Set up Nextcloud
|
||||
run: |
|
||||
if [ "${{ matrix.databases }}" = "mysql" ]; then
|
||||
export DB_PORT=4444
|
||||
elif [ "${{ matrix.databases }}" = "pgsql" ]; then
|
||||
export DB_PORT=4445
|
||||
fi
|
||||
mkdir data
|
||||
./occ maintenance:install --verbose --database=${{ matrix.databases }} --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
|
||||
./occ app:enable --force ${{ env.APP_NAME }}
|
||||
php -S localhost:8080 &
|
||||
|
||||
- name: PHPUnit
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: ./vendor/phpunit/phpunit/phpunit -c tests/phpunit.xml
|
||||
|
||||
- name: PHPUnit integration
|
||||
working-directory: apps/${{ env.APP_NAME }}
|
||||
run: ./vendor/phpunit/phpunit/phpunit -c tests/phpunit.integration.xml
|
||||
34
.github/workflows/pr-feedback.yml
vendored
34
.github/workflows/pr-feedback.yml
vendored
@@ -1,34 +0,0 @@
|
||||
# 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
|
||||
19
.github/workflows/psalm.yml
vendored
19
.github/workflows/psalm.yml
vendored
@@ -5,7 +5,13 @@
|
||||
|
||||
name: Static analysis
|
||||
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
- stable*
|
||||
|
||||
concurrency:
|
||||
group: psalm-${{ github.head_ref || github.run_id }}
|
||||
@@ -15,17 +21,16 @@ jobs:
|
||||
static-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
name: static-psalm-analysis
|
||||
name: Nextcloud
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
|
||||
- name: Set up php8.2
|
||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
||||
- name: Set up php
|
||||
uses: shivammathur/setup-php@2.25.1 # v2
|
||||
with:
|
||||
php-version: 8.2
|
||||
php-version: 8.1
|
||||
coverage: none
|
||||
ini-file: development
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# 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: Auto approve nextcloud/ocp
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- stable*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: update-nextcloud-ocp-approve-merge-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
auto-approve-merge:
|
||||
if: github.actor == 'nextcloud-command'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# for hmarr/auto-approve-action to approve PRs
|
||||
pull-requests: write
|
||||
# for alexwilson/enable-github-automerge-action to approve PRs
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- uses: mdecoleman/pr-branch-name@bab4c71506bcd299fb350af63bb8e53f2940a599 # v2.0.0
|
||||
id: branchname
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# GitHub actions bot approve
|
||||
- uses: hmarr/auto-approve-action@b40d6c9ed2fa10c9a2749eca7eb004418a705501 # v2
|
||||
if: startsWith(steps.branchname.outputs.branch, 'automated/noid/') && endsWith(steps.branchname.outputs.branch, 'update-nextcloud-ocp')
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Enable GitHub auto merge
|
||||
- name: Auto merge
|
||||
uses: alexwilson/enable-github-automerge-action@d8d24b8699d9749aca9279609909abca856457c8 # main
|
||||
if: startsWith(steps.branchname.outputs.branch, 'automated/noid/') && endsWith(steps.branchname.outputs.branch, 'update-nextcloud-ocp')
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
68
.github/workflows/update-nextcloud-ocp.yml
vendored
68
.github/workflows/update-nextcloud-ocp.yml
vendored
@@ -17,90 +17,42 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
branches: ['main', 'master', 'stable28', 'stable27', 'stable26']
|
||||
branches: ["master", "stable26", "stable25", "stable24"]
|
||||
|
||||
name: update-nextcloud-ocp-${{ matrix.branches }}
|
||||
|
||||
steps:
|
||||
- id: checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3
|
||||
with:
|
||||
ref: ${{ matrix.branches }}
|
||||
submodules: true
|
||||
continue-on-error: true
|
||||
|
||||
- name: Set up php8.2
|
||||
if: steps.checkout.outcome == 'success'
|
||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
||||
- name: Set up php8.1
|
||||
uses: shivammathur/setup-php@2.25.1 # v2
|
||||
with:
|
||||
php-version: 8.2
|
||||
# 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
|
||||
php-version: 8.1
|
||||
extensions: ctype,curl,dom,fileinfo,gd,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
|
||||
coverage: none
|
||||
env:
|
||||
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
|
||||
if: steps.checkout.outcome == 'success'
|
||||
run: composer install
|
||||
|
||||
- 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 }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Raise on issue on failure
|
||||
uses: dacbd/create-issue-action@cdb57ab6ff8862aa09fee2be6ba77a59581921c2 # v2.0.0
|
||||
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@cdb57ab6ff8862aa09fee2be6ba77a59581921c2 # v2.0.0
|
||||
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'
|
||||
- name: Reset checkout dirs
|
||||
run: |
|
||||
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 checkout vendor
|
||||
continue-on-error: true
|
||||
|
||||
- name: Reset checkout vendor-bin
|
||||
if: steps.checkout.outcome == 'success'
|
||||
run: |
|
||||
git clean -f vendor-bin
|
||||
git checkout vendor-bin
|
||||
git checkout 3rdparty vendor vendor-bin
|
||||
continue-on-error: true
|
||||
|
||||
- name: Create Pull Request
|
||||
if: steps.checkout.outcome == 'success'
|
||||
uses: peter-evans/create-pull-request@70a41aba780001da0a30141984ae2a0c95d8704e # v3
|
||||
uses: peter-evans/create-pull-request@284f54f989303d2699d373481a0cfa13ad5a6666 # v3
|
||||
with:
|
||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
||||
commit-message: "chore(dev-deps): Bump nextcloud/ocp package"
|
||||
|
||||
190
CHANGELOG.md
190
CHANGELOG.md
@@ -1,139 +1,112 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## 1.13.1
|
||||
### Fixed
|
||||
- fix: Adjust dependencies to fix filepicker #6038
|
||||
- Fix npm audit #6028
|
||||
- Fix npm audit #6001
|
||||
- fix: Avoid optional before required parameter #5820
|
||||
- fix: permission check for cloning board #5853
|
||||
|
||||
## 1.13.0
|
||||
|
||||
### Added
|
||||
|
||||
- feat: Rename to teams @juliushaertl [#5611](https://github.com/nextcloud/deck/pull/5611)
|
||||
- feat: Implement a team resource provider @juliushaertl [#5625](https://github.com/nextcloud/deck/pull/5625)
|
||||
- Interactive board widget @juliushaertl [#5630](https://github.com/nextcloud/deck/pull/5630)
|
||||
- introduce done and open filters @grnd-alt [#5488](https://github.com/nextcloud/deck/pull/5488)
|
||||
## 1.11.6
|
||||
|
||||
### Fixed
|
||||
|
||||
- fixed sorting for upcoming cards @elzody [#5493](https://github.com/nextcloud/deck/pull/5493)
|
||||
- fix(PermissionService#getPermissions): Catch exceptions from getBoard method @marcelklehr [#5542](https://github.com/nextcloud/deck/pull/5542)
|
||||
- fix(activity): Fix permission checks when rendering activities in bac… @nickvergessen [#5533](https://github.com/nextcloud/deck/pull/5533)
|
||||
- fix: Safeguard sync requests to hopefully not spam then server @juliushaertl [#5590](https://github.com/nextcloud/deck/pull/5590)
|
||||
- fix: card move dialog auto close @luka-nextcloud [#5537](https://github.com/nextcloud/deck/pull/5537)
|
||||
- fix: Avoid conflicts on deck attachments folder name @juliushaertl [#5703](https://github.com/nextcloud/deck/pull/5703)
|
||||
- fix: Adapt NcAppSidebar props to new version @backportbot[bot] [#5768](https://github.com/nextcloud/deck/pull/5768)
|
||||
- Fix tags' display when they are numerous @backportbot[bot] [#5727](https://github.com/nextcloud/deck/pull/5727)
|
||||
- Clarify config file not found exception message @backportbot[bot] [#5724](https://github.com/nextcloud/deck/pull/5724)
|
||||
- fix: Avoid optional before required parameter [#6094](https://github.com/nextcloud/deck/pull/6094)
|
||||
- use deleted_users for users that do not exist [#6202](https://github.com/nextcloud/deck/pull/6202)
|
||||
|
||||
## 1.11.5
|
||||
|
||||
### Fixed
|
||||
- don't reset update time when no update was written to db #6036
|
||||
- fix: Avoid conflicts on deck attachments folder name #5709
|
||||
- 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
|
||||
|
||||
- chore(CI): Adjust testing matrix for Nextcloud 29 on stable29 @nickvergessen [#5711](https://github.com/nextcloud/deck/pull/5711)
|
||||
- Fix small issues around delete/undo @juliushaertl [#5420](https://github.com/nextcloud/deck/pull/5420)
|
||||
|
||||
## 1.13.0-beta.1
|
||||
|
||||
### Added
|
||||
|
||||
- feat: Rename to teams @juliushaertl [#5611](https://github.com/nextcloud/deck/pull/5611)
|
||||
- feat: Implement a team resource provider @juliushaertl [#5625](https://github.com/nextcloud/deck/pull/5625)
|
||||
- Interactive board widget @juliushaertl [#5630](https://github.com/nextcloud/deck/pull/5630)
|
||||
## 1.11.2
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix deleted card/board issues @juliushaertl [#5423](https://github.com/nextcloud/deck/pull/5423)
|
||||
- Fixing #5451 @mintsoft [#5455](https://github.com/nextcloud/deck/pull/5455)
|
||||
- fix: Add debounce to update due date @juliushaertl [#5458](https://github.com/nextcloud/deck/pull/5458)
|
||||
- fix(done): Mark card as undone when updating card @stefan-niedermann [#5491](https://github.com/nextcloud/deck/pull/5491)
|
||||
- fixed sorting for upcoming cards @elzody [#5493](https://github.com/nextcloud/deck/pull/5493)
|
||||
- fix(PermissionService#getPermissions): Catch exceptions from getBoard method @marcelklehr [#5542](https://github.com/nextcloud/deck/pull/5542)
|
||||
- fix(activity): Fix permission checks when rendering activities in bac… @nickvergessen [#5533](https://github.com/nextcloud/deck/pull/5533)
|
||||
- fix: Safeguard sync requests to hopefully not spam then server @juliushaertl [#5590](https://github.com/nextcloud/deck/pull/5590)
|
||||
- fix: card move dialog auto close @luka-nextcloud [#5537](https://github.com/nextcloud/deck/pull/5537)
|
||||
- also filter by storage when getting shares in folder @icewind1991 [#5452](https://github.com/nextcloud/deck/pull/5452)
|
||||
- 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(i18n): Improved wording @rakekniven [#5496](https://github.com/nextcloud/deck/pull/5496)
|
||||
- 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
|
||||
|
||||
## 1.12.0-beta.3
|
||||
## 1.11.0
|
||||
|
||||
### Added
|
||||
|
||||
- feat: Move to contenteditable for inline title editing @juliushaertl [#5282](https://github.com/nextcloud/deck/pull/5282)
|
||||
- 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
|
||||
|
||||
- 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(occ): set user id for permission sevice from board service [#4813](https://github.com/nextcloud/deck/pull/4813)
|
||||
- fix: Allow dynamic autoloading for classes added during upgrade [#4804](https://github.com/nextcloud/deck/pull/4804)
|
||||
- fix(notification): Prevent null in parameters [#4909](https://github.com/nextcloud/deck/pull/4909)
|
||||
- fix: Split query to fetch board ids to avoid slow query join @juliushaertl [#4949](https://github.com/nextcloud/deck/pull/4949)
|
||||
- fix: export doesn't handle lists with no cards [#5118](https://github.com/nextcloud/deck/pull/5118)
|
||||
- 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)
|
||||
|
||||
## 1.12.0-beta.2
|
||||
### Other
|
||||
|
||||
- Dependency updates
|
||||
|
||||
## 1.11.0-beta.1
|
||||
|
||||
### Added
|
||||
|
||||
- Card layout polishing @juliushaertl [#5264](https://github.com/nextcloud/deck/pull/5264)
|
||||
- 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
|
||||
|
||||
- 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)
|
||||
- Fix(occ): set user id for permission sevice from board service [#4813](https://github.com/nextcloud/deck/pull/4813)
|
||||
- fix: Allow dynamic autoloading for classes added during upgrade [#4804](https://github.com/nextcloud/deck/pull/4804)
|
||||
- fix(notification): Prevent null in parameters [#4909](https://github.com/nextcloud/deck/pull/4909)
|
||||
- fix: Split query to fetch board ids to avoid slow query join @juliushaertl [#4949](https://github.com/nextcloud/deck/pull/4949)
|
||||
- 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)
|
||||
|
||||
### 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
|
||||
## 1.10.0
|
||||
|
||||
### Added
|
||||
|
||||
@@ -141,6 +114,8 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
### 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(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)
|
||||
@@ -160,7 +135,12 @@ 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)
|
||||
- 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)
|
||||
- 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
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ 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
|
||||
- [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
|
||||
- [QOwnNotes](https://github.com/pbek/QOwnNotes) - Quickly creates cards and links to them in Markdown notes
|
||||
|
||||
## Installation/Update
|
||||
|
||||
@@ -77,7 +76,7 @@ You can enable HMR (Hot module replacement) to avoid page reloads when working o
|
||||
|
||||
### Docker: Simple app development container
|
||||
|
||||
- Fork the app
|
||||
- Fork the app
|
||||
- Clone the repository: `git clone https://github.com/nextcloud/deck.git`
|
||||
- Go into deck directory: `cd deck`
|
||||
- Build the app as described in the general build instructions
|
||||
@@ -93,7 +92,7 @@ docker run --rm \
|
||||
### 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).
|
||||
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
|
||||
You can use the provided Makefile to run all tests by using:
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
- 🚀 Get your project organized
|
||||
|
||||
</description>
|
||||
<version>1.13.1</version>
|
||||
<version>1.11.6</version>
|
||||
<licence>agpl</licence>
|
||||
<author>Julius Härtl</author>
|
||||
<documentation>
|
||||
@@ -38,7 +38,7 @@
|
||||
<database min-version="9.4">pgsql</database>
|
||||
<database>sqlite</database>
|
||||
<database min-version="8.0">mysql</database>
|
||||
<nextcloud min-version="29" max-version="29"/>
|
||||
<nextcloud min-version="27" max-version="27"/>
|
||||
</dependencies>
|
||||
<background-jobs>
|
||||
<job>OCA\Deck\Cron\DeleteCron</job>
|
||||
@@ -58,9 +58,9 @@
|
||||
</commands>
|
||||
<activity>
|
||||
<settings>
|
||||
<setting>OCA\Deck\Activity\SettingChanges</setting>
|
||||
<setting>OCA\Deck\Activity\SettingDescription</setting>
|
||||
<setting>OCA\Deck\Activity\Setting</setting>
|
||||
<setting>OCA\Deck\Activity\SettingComment</setting>
|
||||
<setting>OCA\Deck\Activity\DescriptionSetting</setting>
|
||||
</settings>
|
||||
<filters>
|
||||
<filter>OCA\Deck\Activity\Filter</filter>
|
||||
|
||||
@@ -25,11 +25,6 @@
|
||||
return [
|
||||
'routes' => [
|
||||
['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'],
|
||||
|
||||
// boards
|
||||
@@ -66,8 +61,6 @@ return [
|
||||
['name' => 'card#reorder', 'url' => '/cards/{cardId}/reorder', 'verb' => 'PUT'],
|
||||
['name' => 'card#archive', 'url' => '/cards/{cardId}/archive', '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#removeLabel', 'url' => '/cards/{cardId}/label/{labelId}', 'verb' => 'DELETE'],
|
||||
['name' => 'card#assignUser', 'url' => '/cards/{cardId}/assign', 'verb' => 'POST'],
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
"roave/security-advisories": "dev-master",
|
||||
"phpunit/phpunit": "^9",
|
||||
"nextcloud/coding-standard": "^1.1",
|
||||
"nextcloud/ocp": "dev-stable29",
|
||||
"psalm/phar": "^5.13"
|
||||
"psalm/phar": "^5.13",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"nextcloud/ocp": "dev-stable27"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
|
||||
316
composer.lock
generated
316
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "100910e14ce26e45293a1b29bc723416",
|
||||
"content-hash": "25b1df7f8fcc7b43083c1d7b3178cd0f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "justinrainbow/json-schema",
|
||||
@@ -209,16 +209,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nextcloud/coding-standard",
|
||||
"version": "v1.2.1",
|
||||
"version": "v1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nextcloud/coding-standard.git",
|
||||
"reference": "cf5f18d989ec62fb4cdc7fc92a36baf34b3d829e"
|
||||
"reference": "55def702fb9a37a219511e1d8c6fe8e37164c1fb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nextcloud/coding-standard/zipball/cf5f18d989ec62fb4cdc7fc92a36baf34b3d829e",
|
||||
"reference": "cf5f18d989ec62fb4cdc7fc92a36baf34b3d829e",
|
||||
"url": "https://api.github.com/repos/nextcloud/coding-standard/zipball/55def702fb9a37a219511e1d8c6fe8e37164c1fb",
|
||||
"reference": "55def702fb9a37a219511e1d8c6fe8e37164c1fb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -244,26 +244,26 @@
|
||||
"description": "Nextcloud coding standards for the php cs fixer",
|
||||
"support": {
|
||||
"issues": "https://github.com/nextcloud/coding-standard/issues",
|
||||
"source": "https://github.com/nextcloud/coding-standard/tree/v1.2.1"
|
||||
"source": "https://github.com/nextcloud/coding-standard/tree/v1.1.1"
|
||||
},
|
||||
"time": "2024-02-01T14:54:37+00:00"
|
||||
"time": "2023-06-01T12:05:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nextcloud/ocp",
|
||||
"version": "dev-stable29",
|
||||
"version": "dev-stable27",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nextcloud-deps/ocp.git",
|
||||
"reference": "32f6e6f4cdc1d8a1913a052c644f0e140e5d9ade"
|
||||
"reference": "ba957cf4c69c55488d58229032bba7d71ad19e72"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/32f6e6f4cdc1d8a1913a052c644f0e140e5d9ade",
|
||||
"reference": "32f6e6f4cdc1d8a1913a052c644f0e140e5d9ade",
|
||||
"url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/ba957cf4c69c55488d58229032bba7d71ad19e72",
|
||||
"reference": "ba957cf4c69c55488d58229032bba7d71ad19e72",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~8.0 || ~8.1 || ~8.2 || ~8.3",
|
||||
"php": "^7.4 || ~8.0 || ~8.1",
|
||||
"psr/clock": "^1.0",
|
||||
"psr/container": "^2.0.2",
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
@@ -272,7 +272,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-stable29": "29.0.0-dev"
|
||||
"dev-stable27": "27.0.0-dev"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -288,33 +288,31 @@
|
||||
"description": "Composer package containing Nextcloud's public API (classes, interfaces)",
|
||||
"support": {
|
||||
"issues": "https://github.com/nextcloud-deps/ocp/issues",
|
||||
"source": "https://github.com/nextcloud-deps/ocp/tree/stable29"
|
||||
"source": "https://github.com/nextcloud-deps/ocp/tree/stable27"
|
||||
},
|
||||
"time": "2024-07-26T00:37:14+00:00"
|
||||
"time": "2024-07-28T00:41:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v5.0.2",
|
||||
"version": "v4.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13"
|
||||
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13",
|
||||
"reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
||||
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-json": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"php": ">=7.4"
|
||||
"php": ">=7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ircmaxell/php-yacc": "^0.0.7",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
|
||||
"phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"bin": [
|
||||
"bin/php-parse"
|
||||
@@ -322,7 +320,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0-dev"
|
||||
"dev-master": "4.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -346,27 +344,26 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0"
|
||||
},
|
||||
"time": "2024-03-05T20:51:40+00:00"
|
||||
"time": "2023-12-10T21:03:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
"version": "2.0.4",
|
||||
"version": "2.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phar-io/manifest.git",
|
||||
"reference": "54750ef60c58e43759730615a392c31c80e23176"
|
||||
"reference": "97803eca37d319dfa7826cc2437fc020857acb53"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
|
||||
"reference": "54750ef60c58e43759730615a392c31c80e23176",
|
||||
"url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
|
||||
"reference": "97803eca37d319dfa7826cc2437fc020857acb53",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"phar-io/version": "^3.0.1",
|
||||
@@ -407,15 +404,9 @@
|
||||
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
|
||||
"support": {
|
||||
"issues": "https://github.com/phar-io/manifest/issues",
|
||||
"source": "https://github.com/phar-io/manifest/tree/2.0.4"
|
||||
"source": "https://github.com/phar-io/manifest/tree/2.0.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/theseer",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-03T12:33:53+00:00"
|
||||
"time": "2021-07-20T11:28:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/version",
|
||||
@@ -470,16 +461,16 @@
|
||||
},
|
||||
{
|
||||
"name": "php-cs-fixer/shim",
|
||||
"version": "v3.49.0",
|
||||
"version": "v3.41.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/shim.git",
|
||||
"reference": "f7d3219cac46632f12362c9aa7c2ac0d2fe92c52"
|
||||
"reference": "01cea2dca727100537bd63e28e06e49a475b54e9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/f7d3219cac46632f12362c9aa7c2ac0d2fe92c52",
|
||||
"reference": "f7d3219cac46632f12362c9aa7c2ac0d2fe92c52",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/01cea2dca727100537bd63e28e06e49a475b54e9",
|
||||
"reference": "01cea2dca727100537bd63e28e06e49a475b54e9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -516,29 +507,86 @@
|
||||
"description": "A tool to automatically fix PHP code style",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/shim/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.49.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.41.1"
|
||||
},
|
||||
"time": "2024-02-02T00:42:09+00:00"
|
||||
"time": "2023-12-10T19:59:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.31",
|
||||
"name": "php-parallel-lint/php-parallel-lint",
|
||||
"version": "v1.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "48c34b5d8d983006bd2adc2d0de92963b9155965"
|
||||
"url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git",
|
||||
"reference": "6483c9832e71973ed29cf71bd6b3f4fde438a9de"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965",
|
||||
"reference": "48c34b5d8d983006bd2adc2d0de92963b9155965",
|
||||
"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",
|
||||
"version": "9.2.29",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76",
|
||||
"reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"nikic/php-parser": "^4.18 || ^5.0",
|
||||
"nikic/php-parser": "^4.15",
|
||||
"php": ">=7.3",
|
||||
"phpunit/php-file-iterator": "^3.0.3",
|
||||
"phpunit/php-text-template": "^2.0.2",
|
||||
@@ -588,7 +636,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -596,7 +644,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-02T06:37:42+00:00"
|
||||
"time": "2023-09-19T04:57:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
@@ -841,16 +889,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.6.18",
|
||||
"version": "9.6.15",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "32c2c2d6580b1d8ab3c10b1e9e4dc263cc69bb04"
|
||||
"reference": "05017b80304e0eb3f31d90194a563fd53a6021f1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/32c2c2d6580b1d8ab3c10b1e9e4dc263cc69bb04",
|
||||
"reference": "32c2c2d6580b1d8ab3c10b1e9e4dc263cc69bb04",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1",
|
||||
"reference": "05017b80304e0eb3f31d90194a563fd53a6021f1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -924,7 +972,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.18"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -940,20 +988,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-21T12:07:32+00:00"
|
||||
"time": "2023-12-01T16:55:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psalm/phar",
|
||||
"version": "5.23.1",
|
||||
"version": "5.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/psalm/phar.git",
|
||||
"reference": "07bb50acefdaf7b663087186f86d47542a9b1622"
|
||||
"reference": "a78b5c2e8860c3b4242c63bc0864621278705f9a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/psalm/phar/zipball/07bb50acefdaf7b663087186f86d47542a9b1622",
|
||||
"reference": "07bb50acefdaf7b663087186f86d47542a9b1622",
|
||||
"url": "https://api.github.com/repos/psalm/phar/zipball/a78b5c2e8860c3b4242c63bc0864621278705f9a",
|
||||
"reference": "a78b5c2e8860c3b4242c63bc0864621278705f9a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -973,9 +1021,9 @@
|
||||
"description": "Composer-based Psalm Phar",
|
||||
"support": {
|
||||
"issues": "https://github.com/psalm/phar/issues",
|
||||
"source": "https://github.com/psalm/phar/tree/5.23.1"
|
||||
"source": "https://github.com/psalm/phar/tree/5.18.0"
|
||||
},
|
||||
"time": "2024-03-11T20:43:33+00:00"
|
||||
"time": "2023-12-16T09:41:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/clock",
|
||||
@@ -1184,12 +1232,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Roave/SecurityAdvisories.git",
|
||||
"reference": "c7332a39b09af9d355cf0048e985c54055bd1fe5"
|
||||
"reference": "3c2385497f806decca1e5abeba3cb8fd7caba4e0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/c7332a39b09af9d355cf0048e985c54055bd1fe5",
|
||||
"reference": "c7332a39b09af9d355cf0048e985c54055bd1fe5",
|
||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3c2385497f806decca1e5abeba3cb8fd7caba4e0",
|
||||
"reference": "3c2385497f806decca1e5abeba3cb8fd7caba4e0",
|
||||
"shasum": ""
|
||||
},
|
||||
"conflict": {
|
||||
@@ -1292,7 +1340,7 @@
|
||||
"derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3",
|
||||
"derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1",
|
||||
"desperado/xml-bundle": "<=0.1.7",
|
||||
"directmailteam/direct-mail": "<5.2.4",
|
||||
"directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2",
|
||||
"doctrine/annotations": "<1.2.7",
|
||||
"doctrine/cache": "<1.3.2|>=1.4,<1.4.2",
|
||||
"doctrine/common": "<2.4.3|>=2.5,<2.5.1",
|
||||
@@ -1303,7 +1351,7 @@
|
||||
"doctrine/mongodb-odm-bundle": "<3.0.1",
|
||||
"doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4",
|
||||
"dolibarr/dolibarr": "<18.0.2",
|
||||
"dompdf/dompdf": "<2.0.2|==2.0.2",
|
||||
"dompdf/dompdf": "<2.0.4",
|
||||
"doublethreedigital/guest-entries": "<3.1.2",
|
||||
"drupal/core": "<9.4.14|>=9.5,<9.5.8|>=10,<10.0.8",
|
||||
"drupal/drupal": ">=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4",
|
||||
@@ -1313,6 +1361,7 @@
|
||||
"ectouch/ectouch": "<=2.7.2",
|
||||
"elefant/cms": "<2.0.7",
|
||||
"elgg/elgg": "<3.3.24|>=4,<4.0.5",
|
||||
"elijaa/phpmemcacheadmin": "<=1.3",
|
||||
"encore/laravel-admin": "<=1.8.19",
|
||||
"endroid/qr-code-bundle": "<3.4.2",
|
||||
"enshrined/svg-sanitize": "<0.15",
|
||||
@@ -1335,7 +1384,7 @@
|
||||
"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/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31",
|
||||
"ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.03.5.1",
|
||||
"ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.06,<=2019.03.5.1",
|
||||
"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",
|
||||
"ezyang/htmlpurifier": "<4.1.1",
|
||||
@@ -1415,7 +1464,7 @@
|
||||
"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",
|
||||
"impresscms/impresscms": "<=1.4.5",
|
||||
"in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.2",
|
||||
"in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3",
|
||||
"in2code/ipandlanguageredirect": "<5.1.2",
|
||||
"in2code/lux": "<17.6.1|>=18,<24.0.2",
|
||||
"innologi/typo3-appointments": "<2.0.6",
|
||||
@@ -1482,11 +1531,15 @@
|
||||
"mautic/core": "<4.3",
|
||||
"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/semantic-media-wiki": "<4.0.2",
|
||||
"melisplatform/melis-asset-manager": "<5.0.1",
|
||||
"melisplatform/melis-cms": "<5.0.1",
|
||||
"melisplatform/melis-front": "<5.0.1",
|
||||
"mezzio/mezzio-swoole": "<3.7|>=4,<4.3",
|
||||
"mgallegos/laravel-jqgrid": "<=1.3",
|
||||
"microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2.0.0.0-RC1-dev,<2.0.1",
|
||||
"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",
|
||||
"mittwald/typo3_forum": "<1.2.1",
|
||||
@@ -1533,7 +1586,7 @@
|
||||
"open-web-analytics/open-web-analytics": "<1.7.4",
|
||||
"opencart/opencart": "<=3.0.3.7|>=4,<4.0.2.3-dev",
|
||||
"openid/php-openid": "<2.3",
|
||||
"openmage/magento-lts": "<=19.5|>=20,<=20.1",
|
||||
"openmage/magento-lts": "<20.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",
|
||||
"oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1",
|
||||
@@ -1556,6 +1609,7 @@
|
||||
"pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1",
|
||||
"personnummer/personnummer": "<3.0.2",
|
||||
"phanan/koel": "<5.1.4",
|
||||
"phenx/php-svg-lib": "<0.5.1",
|
||||
"php-mod/curl": "<2.3.2",
|
||||
"phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1",
|
||||
"phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7",
|
||||
@@ -1601,6 +1655,7 @@
|
||||
"pterodactyl/panel": "<1.7",
|
||||
"ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2",
|
||||
"ptrofimov/beanstalk_console": "<1.7.14",
|
||||
"pubnub/pubnub": "<6.1",
|
||||
"pusher/pusher-php-server": "<2.2.1",
|
||||
"pwweb/laravel-core": "<=0.3.6.0-beta",
|
||||
"pyrocms/pyrocms": "<=3.9.1",
|
||||
@@ -1726,8 +1781,10 @@
|
||||
"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",
|
||||
"symphonycms/symphony-2": "<2.6.4",
|
||||
"t3/dce": "<0.11.5|>=2.2,<2.6.2",
|
||||
"t3g/svg-sanitizer": "<1.0.3",
|
||||
"t3s/content-consent": "<1.0.3|>=2,<2.0.2",
|
||||
"tastyigniter/tastyigniter": "<3.3",
|
||||
"tcg/voyager": "<=1.4",
|
||||
"tecnickcom/tcpdf": "<6.2.22",
|
||||
@@ -1752,7 +1809,7 @@
|
||||
"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-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.54|>=9,<=9.5.43|>=10,<=10.4.40|>=11,<=11.5.32|>=12,<=12.4.7",
|
||||
"typo3/cms-core": "<8.7.55|>=9,<9.5.44|>=10,<10.4.41|>=11,<11.5.33|>=12,<12.4.8",
|
||||
"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-install": ">=12.2,<12.4.8",
|
||||
@@ -1765,7 +1822,7 @@
|
||||
"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",
|
||||
"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",
|
||||
"usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2",
|
||||
"uvdesk/community-skeleton": "<=1.1.1",
|
||||
@@ -1846,7 +1903,7 @@
|
||||
"zf-commons/zfc-user": "<1.2.2",
|
||||
"zfcampus/zf-apigility-doctrine": "<1.0.3",
|
||||
"zfr/zfr-oauth2-server-module": "<0.1.2",
|
||||
"zoujingli/thinkadmin": "<6.0.22"
|
||||
"zoujingli/thinkadmin": "<=6.1.53"
|
||||
},
|
||||
"type": "metapackage",
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -1883,20 +1940,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-05T01:28:42+00:00"
|
||||
"time": "2023-12-15T16:04:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/cli-parser.git",
|
||||
"reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b"
|
||||
"reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
|
||||
"reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
|
||||
"reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1931,7 +1988,7 @@
|
||||
"homepage": "https://github.com/sebastianbergmann/cli-parser",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/cli-parser/issues",
|
||||
"source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2"
|
||||
"source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1939,7 +1996,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-02T06:27:43+00:00"
|
||||
"time": "2020-09-28T06:08:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/code-unit",
|
||||
@@ -2128,20 +2185,20 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/complexity",
|
||||
"version": "2.0.3",
|
||||
"version": "2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/complexity.git",
|
||||
"reference": "25f207c40d62b8b7aa32f5ab026c53561964053a"
|
||||
"reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a",
|
||||
"reference": "25f207c40d62b8b7aa32f5ab026c53561964053a",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
|
||||
"reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"nikic/php-parser": "^4.18 || ^5.0",
|
||||
"nikic/php-parser": "^4.7",
|
||||
"php": ">=7.3"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -2173,7 +2230,7 @@
|
||||
"homepage": "https://github.com/sebastianbergmann/complexity",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/complexity/issues",
|
||||
"source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3"
|
||||
"source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2181,20 +2238,20 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-22T06:19:30+00:00"
|
||||
"time": "2020-10-26T15:52:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/diff",
|
||||
"version": "4.0.6",
|
||||
"version": "4.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/diff.git",
|
||||
"reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc"
|
||||
"reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc",
|
||||
"reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
|
||||
"reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2239,7 +2296,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/diff/issues",
|
||||
"source": "https://github.com/sebastianbergmann/diff/tree/4.0.6"
|
||||
"source": "https://github.com/sebastianbergmann/diff/tree/4.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2247,7 +2304,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-02T06:30:58+00:00"
|
||||
"time": "2023-05-07T05:35:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
@@ -2314,16 +2371,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
"version": "4.0.6",
|
||||
"version": "4.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/exporter.git",
|
||||
"reference": "78c00df8f170e02473b682df15bfcdacc3d32d72"
|
||||
"reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72",
|
||||
"reference": "78c00df8f170e02473b682df15bfcdacc3d32d72",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
|
||||
"reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2379,7 +2436,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/exporter/issues",
|
||||
"source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6"
|
||||
"source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2387,20 +2444,20 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-02T06:33:00+00:00"
|
||||
"time": "2022-09-14T06:03:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
"version": "5.0.7",
|
||||
"version": "5.0.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/global-state.git",
|
||||
"reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9"
|
||||
"reference": "bde739e7565280bda77be70044ac1047bc007e34"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
|
||||
"reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34",
|
||||
"reference": "bde739e7565280bda77be70044ac1047bc007e34",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2443,7 +2500,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/global-state/issues",
|
||||
"source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7"
|
||||
"source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2451,24 +2508,24 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-02T06:35:11+00:00"
|
||||
"time": "2023-08-02T09:26:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/lines-of-code",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/lines-of-code.git",
|
||||
"reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5"
|
||||
"reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5",
|
||||
"reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
|
||||
"reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"nikic/php-parser": "^4.18 || ^5.0",
|
||||
"nikic/php-parser": "^4.6",
|
||||
"php": ">=7.3"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -2500,7 +2557,7 @@
|
||||
"homepage": "https://github.com/sebastianbergmann/lines-of-code",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
|
||||
"source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4"
|
||||
"source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2508,7 +2565,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-22T06:20:34+00:00"
|
||||
"time": "2020-11-28T06:42:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/object-enumerator",
|
||||
@@ -2687,16 +2744,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/resource-operations",
|
||||
"version": "3.0.4",
|
||||
"version": "3.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/resource-operations.git",
|
||||
"reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e"
|
||||
"reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
|
||||
"reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
|
||||
"reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2708,7 +2765,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.0-dev"
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2729,7 +2786,8 @@
|
||||
"description": "Provides a list of PHP built-in functions that operate on resources",
|
||||
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
|
||||
"support": {
|
||||
"source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4"
|
||||
"issues": "https://github.com/sebastianbergmann/resource-operations/issues",
|
||||
"source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2737,7 +2795,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-14T16:00:52+00:00"
|
||||
"time": "2020-09-28T06:45:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/type",
|
||||
@@ -2850,16 +2908,16 @@
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/theseer/tokenizer.git",
|
||||
"reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
|
||||
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
|
||||
"reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
|
||||
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
|
||||
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2888,7 +2946,7 @@
|
||||
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
|
||||
"support": {
|
||||
"issues": "https://github.com/theseer/tokenizer/issues",
|
||||
"source": "https://github.com/theseer/tokenizer/tree/1.2.3"
|
||||
"source": "https://github.com/theseer/tokenizer/tree/1.2.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2896,7 +2954,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-03T12:36:25+00:00"
|
||||
"time": "2023-11-20T00:12:19+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { randUser } from '../utils/index.js'
|
||||
import { sampleBoard } from '../utils/sampleBoard'
|
||||
import moment from '@nextcloud/moment'
|
||||
|
||||
const user = randUser()
|
||||
const boardData = sampleBoard()
|
||||
@@ -69,13 +68,11 @@ describe('Card', function() {
|
||||
.first().click()
|
||||
cy.get('.modal-mask.card-selector .card-title').should('be.visible').click().type(newCardTitle)
|
||||
cy.get('.modal-mask.card-selector .multiselect-board').should('be.visible').click()
|
||||
cy.get('.vs__dropdown-menu [data-cy="board-select-title"]:contains("' + boardData.title + '")').should('be.visible').click()
|
||||
|
||||
cy.get('.modal-mask.card-selector .multiselect-board li:contains("' + boardData.title + '")').should('be.visible').click()
|
||||
cy.wait('@getBoard', { timeout: 7000 })
|
||||
|
||||
cy.get('.modal-mask.card-selector .multiselect-list').should('be.visible').click()
|
||||
cy.get('.vs__dropdown-menu span[title="TestList"]').should('be.visible').click()
|
||||
|
||||
cy.get('.modal-mask.card-selector .multiselect-list li').eq(0).should('be.visible').click()
|
||||
cy.get('.modal-mask.card-selector button.button-vue--vue-primary').should('be.visible').click()
|
||||
cy.wait('@save', { timeout: 7000 })
|
||||
|
||||
@@ -103,28 +100,28 @@ describe('Card', function() {
|
||||
})
|
||||
|
||||
cy.get('.modal__card').should('be.visible')
|
||||
cy.get('.app-sidebar-header__mainname').contains('Hello world')
|
||||
cy.get('.app-sidebar-header__maintitle').contains('Hello world')
|
||||
})
|
||||
|
||||
it('Attachment from files app', () => {
|
||||
cy.get('.card:contains("Hello world")').should('be.visible').click()
|
||||
cy.get('.modal__card').should('be.visible')
|
||||
cy.get('#tab-button-attachments').click()
|
||||
cy.get('.app-sidebar-tabs__tab [data-id="attachments"]').click()
|
||||
cy.get('button.icon-upload').should('be.visible')
|
||||
cy.get('button.icon-folder').should('be.visible')
|
||||
.click()
|
||||
cy.get('.file-picker__main').should('be.visible')
|
||||
cy.get('.file-picker__main [data-filename="welcome.txt"]', { timeout: 30000 }).should('be.visible')
|
||||
cy.get('.file-picker__main [data-filename="welcome.txt"]').should('be.visible')
|
||||
.click()
|
||||
cy.get('.dialog__actions button.button-vue--vue-primary').click()
|
||||
cy.get('.attachment-list .basename').contains('welcome.txt')
|
||||
})
|
||||
|
||||
it.only('Shows the modal with the editor', () => {
|
||||
it('Shows the modal with the editor', () => {
|
||||
cy.get('.card:contains("Hello world")').should('be.visible').click()
|
||||
cy.intercept({ method: 'PUT', url: '**/apps/deck/cards/*' }).as('save')
|
||||
cy.get('.modal__card').should('be.visible')
|
||||
cy.get('.app-sidebar-header__mainname').contains('Hello world')
|
||||
cy.get('.app-sidebar-header__maintitle').contains('Hello world')
|
||||
cy.get('.modal__card .ProseMirror h1').contains('Hello world').should('be.visible')
|
||||
cy.get('.modal__card .ProseMirror h1')
|
||||
.click()
|
||||
@@ -180,119 +177,6 @@ describe('Card', function() {
|
||||
cy.get('#app-sidebar-vue')
|
||||
.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('.vs__dropdown-menu .tag:contains("Action needed")').should('be.visible').click()
|
||||
cy.get('.vs__selected .tag:contains("Action needed")').should('be.visible')
|
||||
cy.get('.vs__dropdown-menu .tag:contains("Later")').should('be.visible').click()
|
||||
|
||||
cy.get('.vs__selected .tag:contains("Action needed")').should('be.visible')
|
||||
cy.get('.vs__selected .tag:contains("Action needed")')
|
||||
.parent().find('button').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,5 +1,4 @@
|
||||
import { randUser } from '../utils/index.js'
|
||||
import { sampleBoard } from '../utils/sampleBoard'
|
||||
const user = randUser()
|
||||
|
||||
describe('Deck dashboard', function() {
|
||||
@@ -9,18 +8,16 @@ describe('Deck dashboard', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
cy.login(user)
|
||||
cy.visit('/apps/deck')
|
||||
})
|
||||
|
||||
it('Can show the right title on the dashboard', function() {
|
||||
cy.visit('/apps/deck')
|
||||
cy.get('.board-title h2')
|
||||
.should('have.length', 1).first()
|
||||
.should($el => expect($el.text().trim()).to.equal('Upcoming cards'))
|
||||
.should('have.text', 'Upcoming cards')
|
||||
})
|
||||
|
||||
it('Can see the default "Personal Board" created for user by default', function() {
|
||||
cy.visit('/apps/deck')
|
||||
|
||||
const defaultBoard = 'Personal'
|
||||
|
||||
cy.get('.app-navigation-entry-wrapper[icon=icon-deck]')
|
||||
@@ -29,29 +26,4 @@ describe('Deck dashboard', function() {
|
||||
.contains(defaultBoard)
|
||||
.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')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -38,10 +38,7 @@ describe('Board', function() {
|
||||
cy.get('.board-title').contains(board.title)
|
||||
|
||||
cy.shareBoardWithUi(recipient.userId)
|
||||
|
||||
cy.intercept({ method: 'PUT', url: '**/apps/deck/boards/*/acl/*' }).as('setAcl')
|
||||
cy.get(`[data-cy="acl-participant:${recipient.userId}"]`).find('[data-cy="action:permission-edit"]').click()
|
||||
cy.wait('@setAcl')
|
||||
|
||||
cy.login(recipient)
|
||||
cy.visit(`/apps/deck/#/board/${boardId}`)
|
||||
|
||||
@@ -107,14 +107,11 @@ Cypress.Commands.add('getNavigationEntry', (boardTitle) => {
|
||||
})
|
||||
|
||||
Cypress.Commands.add('shareBoardWithUi', (userId) => {
|
||||
cy.intercept({ method: 'GET', url: `**/ocs/v2.php/apps/files_sharing/api/v1/sharees?search=${userId}*` }).as('fetchRecipients')
|
||||
cy.get('[aria-label="Open details"]').click()
|
||||
cy.get('.app-sidebar').should('be.visible')
|
||||
cy.get('.select input').type(`${userId}`)
|
||||
cy.wait('@fetchRecipients', { timeout: 7000 })
|
||||
|
||||
cy.get('.vs__dropdown-menu .option').first().contains(userId)
|
||||
cy.get('.select input').type('{enter}')
|
||||
cy.get('.multiselect__input').type(`${userId}`)
|
||||
cy.get('.multiselect__content .multiselect__element').first().contains(userId)
|
||||
cy.get('.multiselect__input').type('{enter}')
|
||||
|
||||
cy.get('.shareWithList').contains(userId)
|
||||
})
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import './commands.js'
|
||||
|
||||
Cypress.on('uncaught:exception', (err) => {
|
||||
return !err.message.includes('ResizeObserver loop limit exceeded') && !err.message.includes('ResizeObserver loop completed with undelivered notifications')
|
||||
return !err.message.includes('ResizeObserver loop limit exceeded')
|
||||
})
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
|
||||
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 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.
|
||||
|
||||
@@ -117,7 +117,6 @@ 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/config/system/{schema} - Import a board](#get-boardsimportconfigsystemschema-import-a-board)
|
||||
- [POST /boards/import - Import a board](#post-boardsimport-import-a-board)
|
||||
- The `done` property was added to cards
|
||||
|
||||
# Endpoints
|
||||
|
||||
@@ -588,7 +587,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
{
|
||||
"title":"Test",
|
||||
"description":null,
|
||||
"stackId":6,
|
||||
@@ -602,7 +601,6 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
"owner":"admin",
|
||||
"order":999,
|
||||
"archived":false,
|
||||
"done":null,
|
||||
"duedate": "2019-12-24T19:29:30+00:00",
|
||||
"deletedAt":0,
|
||||
"commentsUnread":0,
|
||||
@@ -625,28 +623,22 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
#### Request data
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-------------|-----------------|-----------------------------------------------------------------------------------------------------|
|
||||
| title | String | The title of the card, maximum length is limited to 255 characters |
|
||||
| description | String | The markdown description of the card |
|
||||
| type | String | Type of the card (for later use) use 'plain' for now |
|
||||
| owner | String | The user that owns the card |
|
||||
| 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) |
|
||||
| Parameter | Type | Description |
|
||||
|-------------|-----------|------------------------------------------------------|
|
||||
| title | String | The title of the card, maximum length is limited to 255 characters |
|
||||
| description | String | The markdown description of the card |
|
||||
| type | String | Type of the card (for later use) use 'plain' for now |
|
||||
| order | Integer | Order for sorting the stacks |
|
||||
| duedate | timestamp | The ISO-8601 formatted duedate of the card or null |
|
||||
|
||||
|
||||
```
|
||||
{
|
||||
{
|
||||
"title": "Test card",
|
||||
"description": "A card description",
|
||||
"type": "plain",
|
||||
"owner": "admin",
|
||||
"order": 999,
|
||||
"duedate": "2019-12-24T19:29:30+00:00",
|
||||
"archived": false,
|
||||
"done": null,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -985,7 +977,7 @@ For now only `deck_file` is supported as an attachment type.
|
||||
|
||||
### DELETE /boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId} - Delete an attachment
|
||||
|
||||
|
||||
|
||||
#### Request parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
@@ -1059,12 +1051,12 @@ Make a request to see the json schema of system
|
||||
|
||||
# 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.
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1072,10 +1064,10 @@ Deck stores user and app configuration values globally and per board. The GET en
|
||||
|
||||
| Config key | Description |
|
||||
| --- | --- |
|
||||
| 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) |
|
||||
| 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)|
|
||||
| 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) |
|
||||
| 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)|
|
||||
|
||||
```
|
||||
{
|
||||
@@ -1120,7 +1112,7 @@ Deck stores user and app configuration values globally and per board. The GET en
|
||||
| calendar | Boolean |
|
||||
| cardDetailsInModal | Boolean |
|
||||
| cardIdBadge | Boolean |
|
||||
|
||||
|
||||
#### Example request
|
||||
|
||||
```
|
||||
@@ -1194,7 +1186,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
|
||||
[
|
||||
|
||||
@@ -12,12 +12,11 @@ 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)
|
||||
2. [Create stacks and cards](#2-create-stacks-and-cards)
|
||||
3. [Handle cards options](#3-handle-cards-options)
|
||||
4. [Mark task as done](#4-mark-as-done)
|
||||
5. [Archive old tasks](#5-archive-old-tasks)
|
||||
6. [Manage your board](#6-manage-your-board)
|
||||
7. [Import boards](#7-import-boards)
|
||||
8. [Search](#8-search)
|
||||
9. [New owner for the deck entities](#9-new-owner-for-the-deck-entities)
|
||||
4. [Archive old tasks](#4-archive-old-tasks)
|
||||
5. [Manage your board](#5-manage-your-board)
|
||||
6. [Import boards](#6-import-boards)
|
||||
7. [Search](#7-search)
|
||||
8. [New owner for the deck entities](#8-new-owner-for-the-deck-entities)
|
||||
|
||||
### 1. Create my first board
|
||||
In this example, we're going to create a board and share it with an other nextcloud user.
|
||||
@@ -26,7 +25,7 @@ In this example, we're going to create a board and share it with an other nextcl
|
||||
|
||||
|
||||
### 2. Create stacks and cards
|
||||
Stacks are simply columns with list of cards. It can represent a category of tasks or any step in your projects for example.
|
||||
Stacks are simply columns with list of cards. It can represent a category of tasks or an y step in your projects for example.
|
||||
**Check this out :**
|
||||
|
||||

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

|
||||
|
||||
### 4. Mark as done
|
||||
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.
|
||||
### 4. Archive old tasks
|
||||
Once finished or obsolete, a task could be archived. The tasks is not deleted, it's just archived, and you can retrieve it later
|
||||
|
||||

|
||||

|
||||
|
||||
### 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
|
||||
### 5. 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.
|
||||
Once in this menu, you have access to several things:
|
||||
|
||||
@@ -79,7 +72,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.
|
||||
The **Timeline** allows you to see everything that happened in your boards. Everything!
|
||||
|
||||
### 7. Import boards
|
||||
### 6. Import boards
|
||||
|
||||
Importing can be done using the API or the `occ` `deck:import` command.
|
||||
|
||||
@@ -145,7 +138,7 @@ Example configuration file:
|
||||
}
|
||||
```
|
||||
|
||||
### 8. Search
|
||||
### 7. 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.
|
||||
This search allows advanced filtering of cards across all board of the logged in user.
|
||||
@@ -168,7 +161,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"`.
|
||||
|
||||
### 9. New owner for the deck entities
|
||||
### 8. New owner for the deck entities
|
||||
You can transfer ownership of boards, cards, etc to a new user, using `occ` command `deck:transfer-ownership`
|
||||
|
||||
```bash
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 88 KiB |
@@ -1,8 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16">
|
||||
<g fill="currentColor">
|
||||
<rect ry="1" height="8" width="14" y="7" x="1"/>
|
||||
<rect ry=".5" height="1" width="12" y="5" x="2"/>
|
||||
<rect ry=".5" height="1" width="10" y="3" x="3"/>
|
||||
<rect ry=".5" height="1" width="8" y="1" x="4"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 372 B |
@@ -92,8 +92,6 @@ class ActivityManager {
|
||||
public const SUBJECT_CARD_UPDATE_DUEDATE = 'card_update_duedate';
|
||||
public const SUBJECT_CARD_UPDATE_ARCHIVE = 'card_update_archive';
|
||||
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_USER_ASSIGN = 'card_user_assign';
|
||||
public const SUBJECT_CARD_USER_UNASSIGN = 'card_user_unassign';
|
||||
@@ -201,12 +199,6 @@ class ActivityManager {
|
||||
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}');
|
||||
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:
|
||||
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}');
|
||||
@@ -366,8 +358,6 @@ class ActivityManager {
|
||||
case self::SUBJECT_CARD_DELETE:
|
||||
case self::SUBJECT_CARD_UPDATE_ARCHIVE:
|
||||
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_DESCRIPTION:
|
||||
case self::SUBJECT_CARD_UPDATE_DUEDATE:
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
namespace OCA\Deck\Activity;
|
||||
|
||||
use \OCP\Comments\ICommentsEventHandler;
|
||||
use OCA\Deck\Db\CardMapper;
|
||||
use OCA\Deck\Db\ChangeHelper;
|
||||
use OCA\Deck\Notification\NotificationHelper;
|
||||
use OCP\Comments\CommentsEvent;
|
||||
use OCP\Comments\IComment;
|
||||
use OCP\Comments\ICommentsEventHandler;
|
||||
|
||||
class CommentEventHandler implements ICommentsEventHandler {
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ class DeckProvider implements IProvider {
|
||||
* @throws \InvalidArgumentException Should be thrown if your provider does not know this event
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function parse($language, IEvent $event, ?IEvent $previousEvent = null): IEvent {
|
||||
public function parse($language, IEvent $event, IEvent $previousEvent = null): IEvent {
|
||||
if ($event->getApp() !== 'deck') {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
namespace OCA\Deck\Activity;
|
||||
|
||||
class SettingDescription extends SettingBase {
|
||||
class DescriptionSetting extends Setting {
|
||||
|
||||
/**
|
||||
* @return string Lowercase a-z and underscore only identifier
|
||||
@@ -38,6 +38,6 @@ class SettingDescription extends SettingBase {
|
||||
* @since 11.0.0
|
||||
*/
|
||||
public function getName(): string {
|
||||
return $this->l->t('A <strong>card description</strong> has been changed');
|
||||
return $this->l->t('A <strong>card description</strong> inside the Deck app has been changed');
|
||||
}
|
||||
}
|
||||
@@ -23,10 +23,9 @@
|
||||
|
||||
namespace OCA\Deck\Activity;
|
||||
|
||||
use OCP\Activity\ActivitySettings;
|
||||
use OCP\IL10N;
|
||||
|
||||
abstract class SettingBase extends ActivitySettings {
|
||||
class Setting implements \OCP\Activity\ISetting {
|
||||
|
||||
/** @var IL10N */
|
||||
protected $l;
|
||||
@@ -38,14 +37,6 @@ abstract class SettingBase extends ActivitySettings {
|
||||
$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
|
||||
* @since 11.0.0
|
||||
@@ -1,84 +0,0 @@
|
||||
<?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;
|
||||
|
||||
class SettingComment extends SettingBase {
|
||||
class SettingComment extends Setting {
|
||||
|
||||
/**
|
||||
* @return string Lowercase a-z and underscore only identifier
|
||||
|
||||
@@ -30,9 +30,7 @@ use OCA\Deck\Activity\CommentEventHandler;
|
||||
use OCA\Deck\Capabilities;
|
||||
use OCA\Deck\Collaboration\Resources\ResourceProvider;
|
||||
use OCA\Deck\Collaboration\Resources\ResourceProviderCard;
|
||||
use OCA\Deck\Dashboard\DeckWidgetToday;
|
||||
use OCA\Deck\Dashboard\DeckWidgetTomorrow;
|
||||
use OCA\Deck\Dashboard\DeckWidgetUpcoming;
|
||||
use OCA\Deck\Dashboard\DeckWidget;
|
||||
use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\CardMapper;
|
||||
use OCA\Deck\Event\AclCreatedEvent;
|
||||
@@ -62,7 +60,6 @@ use OCA\Deck\Search\DeckProvider;
|
||||
use OCA\Deck\Service\PermissionService;
|
||||
use OCA\Deck\Sharing\DeckShareProvider;
|
||||
use OCA\Deck\Sharing\Listener;
|
||||
use OCA\Deck\Teams\DeckTeamResourceProvider;
|
||||
use OCA\Text\Event\LoadEditor;
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\Bootstrap\IBootContext;
|
||||
@@ -138,9 +135,7 @@ class Application extends App implements IBootstrap {
|
||||
|
||||
$context->registerSearchProvider(DeckProvider::class);
|
||||
$context->registerSearchProvider(CardCommentProvider::class);
|
||||
$context->registerDashboardWidget(DeckWidgetUpcoming::class);
|
||||
$context->registerDashboardWidget(DeckWidgetToday::class);
|
||||
$context->registerDashboardWidget(DeckWidgetTomorrow::class);
|
||||
$context->registerDashboardWidget(DeckWidget::class);
|
||||
|
||||
$context->registerReferenceProvider(CreateCardReferenceProvider::class);
|
||||
|
||||
@@ -180,8 +175,6 @@ class Application extends App implements IBootstrap {
|
||||
|
||||
$context->registerNotifierService(Notifier::class);
|
||||
$context->registerEventListener(LoadAdditionalScriptsEvent::class, ResourceAdditionalScriptsListener::class);
|
||||
|
||||
$context->registerTeamResourceProvider(DeckTeamResourceProvider::class);
|
||||
}
|
||||
|
||||
public function registerCommentsEntity(IEventDispatcher $eventDispatcher): void {
|
||||
|
||||
@@ -43,7 +43,7 @@ class Capabilities implements ICapability {
|
||||
/**
|
||||
* Function an app uses to return the capabilities
|
||||
*
|
||||
* @return array{deck: array{version: string, canCreateBoards: bool, apiVersions: array<string>}}
|
||||
* @return array Array containing the apps capabilities
|
||||
* @since 8.2.0
|
||||
*/
|
||||
public function getCapabilities() {
|
||||
|
||||
@@ -29,12 +29,11 @@ use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\IRequest;
|
||||
|
||||
class AttachmentApiController extends ApiController {
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
private AttachmentService $attachmentService,
|
||||
) {
|
||||
private $attachmentService;
|
||||
|
||||
public function __construct($appName, IRequest $request, AttachmentService $attachmentService) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->attachmentService = $attachmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,12 +28,13 @@ use OCP\AppFramework\Controller;
|
||||
use OCP\IRequest;
|
||||
|
||||
class AttachmentController extends Controller {
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
private AttachmentService $attachmentService,
|
||||
) {
|
||||
|
||||
/** @var AttachmentService */
|
||||
private $attachmentService;
|
||||
|
||||
public function __construct($appName, IRequest $request, AttachmentService $attachmentService) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->attachmentService = $attachmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,16 +40,18 @@ use Sabre\HTTP\Util;
|
||||
* @package OCA\Deck\Controller
|
||||
*/
|
||||
class BoardApiController extends ApiController {
|
||||
private $boardService;
|
||||
|
||||
/**
|
||||
* @param string $appName
|
||||
* @param IRequest $request
|
||||
* @param BoardService $service
|
||||
* @param $userId
|
||||
*/
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
private BoardService $boardService,
|
||||
private $userId,
|
||||
) {
|
||||
public function __construct($appName, IRequest $request, BoardService $service, $userId) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->boardService = $service;
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,14 +33,15 @@ use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\IRequest;
|
||||
|
||||
class BoardController extends ApiController {
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
private BoardService $boardService,
|
||||
private PermissionService $permissionService,
|
||||
private $userId,
|
||||
) {
|
||||
private $userId;
|
||||
private $boardService;
|
||||
private $permissionService;
|
||||
|
||||
public function __construct($appName, IRequest $request, BoardService $boardService, PermissionService $permissionService, $userId) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->userId = $userId;
|
||||
$this->boardService = $boardService;
|
||||
$this->permissionService = $permissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +56,7 @@ class BoardController extends ApiController {
|
||||
* @param $boardId
|
||||
* @return \OCP\AppFramework\Db\Entity
|
||||
*/
|
||||
public function read(int $boardId) {
|
||||
public function read($boardId) {
|
||||
return $this->boardService->find($boardId);
|
||||
}
|
||||
|
||||
@@ -143,7 +144,7 @@ class BoardController extends ApiController {
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @param $aclId
|
||||
* @return \OCP\AppFramework\Db\Entity|null
|
||||
* @return \OCP\AppFramework\Db\Entity
|
||||
*/
|
||||
public function deleteAcl($aclId) {
|
||||
return $this->boardService->deleteAcl($aclId);
|
||||
|
||||
@@ -30,13 +30,20 @@ use OCP\AppFramework\OCSController;
|
||||
use OCP\IRequest;
|
||||
|
||||
class BoardImportApiController extends OCSController {
|
||||
/** @var BoardImportService */
|
||||
private $boardImportService;
|
||||
/** @var string */
|
||||
private $userId;
|
||||
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
private BoardImportService $boardImportService,
|
||||
private string $userId,
|
||||
BoardImportService $boardImportService,
|
||||
string $userId
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->boardImportService = $boardImportService;
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
namespace OCA\Deck\Controller;
|
||||
|
||||
use OCA\Deck\Model\OptionalNullableValue;
|
||||
use OCA\Deck\Service\AssignmentService;
|
||||
use OCA\Deck\Service\CardService;
|
||||
use OCP\AppFramework\ApiController;
|
||||
@@ -39,22 +38,21 @@ use OCP\IRequest;
|
||||
* @package OCA\Deck\Controller
|
||||
*/
|
||||
class CardApiController extends ApiController {
|
||||
private $cardService;
|
||||
private $userId;
|
||||
private $assignmentService;
|
||||
|
||||
/**
|
||||
* @param string $appName
|
||||
* @param IRequest $request
|
||||
* @param CardService $cardService
|
||||
* @param AssignmentService $assignmentService
|
||||
* @param $userId
|
||||
*/
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
private CardService $cardService,
|
||||
private AssignmentService $assignmentService,
|
||||
private $userId,
|
||||
) {
|
||||
public function __construct($appName, IRequest $request, CardService $cardService, AssignmentService $assignmentService, $userId) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->cardService = $cardService;
|
||||
$this->userId = $userId;
|
||||
$this->assignmentService = $assignmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,8 +104,7 @@ class CardApiController extends ApiController {
|
||||
* Update a card
|
||||
*/
|
||||
public function update($title, $type, $owner, $description = '', $order = 0, $duedate = null, $archived = null) {
|
||||
$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);
|
||||
$card = $this->cardService->update($this->request->getParam('cardId'), $title, $this->request->getParam('stackId'), $type, $owner, $description, $order, $duedate, 0, $archived);
|
||||
return new DataResponse($card, HTTP::STATUS_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +29,15 @@ use OCP\AppFramework\Controller;
|
||||
use OCP\IRequest;
|
||||
|
||||
class CardController extends Controller {
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
private CardService $cardService,
|
||||
private AssignmentService $assignmentService,
|
||||
private $userId,
|
||||
) {
|
||||
private $userId;
|
||||
private $cardService;
|
||||
private $assignmentService;
|
||||
|
||||
public function __construct($appName, IRequest $request, CardService $cardService, AssignmentService $assignmentService, $userId) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->userId = $userId;
|
||||
$this->cardService = $cardService;
|
||||
$this->assignmentService = $assignmentService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,24 +144,6 @@ class CardController extends Controller {
|
||||
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
|
||||
* @param $cardId
|
||||
|
||||
@@ -31,15 +31,18 @@ use OCP\AppFramework\OCSController;
|
||||
use OCP\IRequest;
|
||||
|
||||
class CommentsApiController extends OCSController {
|
||||
|
||||
/** @var CommentService */
|
||||
private $commentService;
|
||||
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
private CommentService $commentService,
|
||||
string $corsMethods = 'PUT, POST, GET, DELETE, PATCH',
|
||||
string $corsAllowedHeaders = 'Authorization, Content-Type, Accept',
|
||||
int $corsMaxAge = 1728000,
|
||||
CommentService $commentService,
|
||||
string $corsMethods = 'PUT, POST, GET, DELETE, PATCH', string $corsAllowedHeaders = 'Authorization, Content-Type, Accept', int $corsMaxAge = 1728000
|
||||
) {
|
||||
parent::__construct($appName, $request, $corsMethods, $corsAllowedHeaders, $corsMaxAge);
|
||||
$this->commentService = $commentService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,12 +30,16 @@ use OCP\AppFramework\OCSController;
|
||||
use OCP\IRequest;
|
||||
|
||||
class ConfigController extends OCSController {
|
||||
private $configService;
|
||||
|
||||
public function __construct(
|
||||
$AppName,
|
||||
IRequest $request,
|
||||
private ConfigService $configService,
|
||||
ConfigService $configService
|
||||
) {
|
||||
parent::__construct($AppName, $request);
|
||||
|
||||
$this->configService = $configService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,18 +35,21 @@ use OCP\IRequest;
|
||||
* @package OCA\Deck\Controller
|
||||
*/
|
||||
class LabelApiController extends ApiController {
|
||||
private $labelService;
|
||||
private $userId;
|
||||
|
||||
/**
|
||||
* @param string $appName
|
||||
* @param IRequest $request
|
||||
* @param LabelService $labelService
|
||||
* @param $userId
|
||||
*/
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
private LabelService $labelService,
|
||||
private $userId,
|
||||
) {
|
||||
public function __construct($appName, IRequest $request, LabelService $labelService, $userId) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->labelService = $labelService;
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @CORS
|
||||
|
||||
@@ -28,12 +28,11 @@ use OCP\AppFramework\Controller;
|
||||
use OCP\IRequest;
|
||||
|
||||
class LabelController extends Controller {
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
private LabelService $labelService,
|
||||
) {
|
||||
private $labelService;
|
||||
|
||||
public function __construct($appName, IRequest $request, LabelService $labelService) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->labelService = $labelService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,13 +32,17 @@ use OCP\AppFramework\OCSController;
|
||||
use OCP\IRequest;
|
||||
|
||||
class OverviewApiController extends OCSController {
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
private OverviewService $dashboardService,
|
||||
private $userId,
|
||||
) {
|
||||
|
||||
/** @var OverviewService */
|
||||
private $dashboardService;
|
||||
|
||||
/** @var string */
|
||||
private $userId;
|
||||
|
||||
public function __construct($appName, IRequest $request, OverviewService $dashboardService, $userId) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->dashboardService = $dashboardService;
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
|
||||
namespace OCA\Deck\Controller;
|
||||
|
||||
use \OCP\AppFramework\Http\RedirectResponse;
|
||||
use OCA\Deck\AppInfo\Application;
|
||||
use OCA\Deck\Db\Acl;
|
||||
use OCA\Deck\Db\CardMapper;
|
||||
use OCA\Deck\Service\BoardService;
|
||||
use OCA\Deck\Service\CardService;
|
||||
use OCA\Deck\Service\ConfigService;
|
||||
use OCA\Deck\Service\PermissionService;
|
||||
@@ -33,43 +34,60 @@ use OCA\Files\Event\LoadSidebar;
|
||||
use OCA\Text\Event\LoadEditor;
|
||||
use OCA\Viewer\Event\LoadViewer;
|
||||
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\RedirectResponse;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\AppFramework\Services\IInitialState;
|
||||
use OCP\Collaboration\Resources\LoadAdditionalScriptsEvent as CollaborationResourcesEvent;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IConfig;
|
||||
use OCP\IInitialStateService;
|
||||
use OCP\IRequest;
|
||||
use OCP\IURLGenerator;
|
||||
|
||||
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(
|
||||
string $AppName,
|
||||
IRequest $request,
|
||||
private PermissionService $permissionService,
|
||||
private IInitialState $initialState,
|
||||
private BoardService $boardService,
|
||||
private ConfigService $configService,
|
||||
private IEventDispatcher $eventDispatcher,
|
||||
private CardMapper $cardMapper,
|
||||
private IURLGenerator $urlGenerator,
|
||||
private CardService $cardService,
|
||||
private IConfig $config,
|
||||
PermissionService $permissionService,
|
||||
IInitialStateService $initialStateService,
|
||||
ConfigService $configService,
|
||||
IEventDispatcher $eventDispatcher,
|
||||
CardMapper $cardMapper,
|
||||
IURLGenerator $urlGenerator,
|
||||
CardService $cardService,
|
||||
IConfig $config
|
||||
) {
|
||||
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]
|
||||
#[NoCSRFRequired]
|
||||
public function index(): TemplateResponse {
|
||||
$this->initialState->provideInitialState('maxUploadSize', (int)\OCP\Util::uploadLimit());
|
||||
$this->initialState->provideInitialState('canCreate', $this->permissionService->canCreate());
|
||||
$this->initialState->provideInitialState('config', $this->configService->getAll());
|
||||
|
||||
$this->initialState->provideInitialState('initialBoards', $this->boardService->findAll());
|
||||
/**
|
||||
* Handle main html view from templates/main.php
|
||||
* This will return the main angular application
|
||||
*
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function index() {
|
||||
$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 CollaborationResourcesEvent());
|
||||
@@ -95,32 +113,10 @@ class PageController extends Controller {
|
||||
return $response;
|
||||
}
|
||||
|
||||
#[NoAdminRequired]
|
||||
#[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]
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function redirectToCard($cardId): RedirectResponse {
|
||||
try {
|
||||
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_READ);
|
||||
|
||||
@@ -34,12 +34,15 @@ use OCP\AppFramework\OCSController;
|
||||
use OCP\IRequest;
|
||||
|
||||
class SearchController extends OCSController {
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
private SearchService $searchService,
|
||||
) {
|
||||
|
||||
/**
|
||||
* @var SearchService
|
||||
*/
|
||||
private $searchService;
|
||||
|
||||
public function __construct(string $appName, IRequest $request, SearchService $searchService) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->searchService = $searchService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,23 +29,30 @@ use OCA\Deck\Db\BoardMapper;
|
||||
use OCA\Deck\Service\PermissionService;
|
||||
use OCA\Deck\Service\SessionService;
|
||||
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\OCSController;
|
||||
use OCP\IRequest;
|
||||
|
||||
class SessionController extends OCSController {
|
||||
private SessionService $sessionService;
|
||||
private PermissionService $permissionService;
|
||||
private BoardMapper $boardMapper;
|
||||
|
||||
public function __construct($appName,
|
||||
IRequest $request,
|
||||
private SessionService $sessionService,
|
||||
private PermissionService $permissionService,
|
||||
private BoardMapper $boardMapper,
|
||||
SessionService $sessionService,
|
||||
PermissionService $permissionService,
|
||||
BoardMapper $boardMapper
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->sessionService = $sessionService;
|
||||
$this->permissionService = $permissionService;
|
||||
$this->boardMapper = $boardMapper;
|
||||
}
|
||||
|
||||
#[NoAdminRequired]
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function create(int $boardId): DataResponse {
|
||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
||||
|
||||
@@ -55,7 +62,11 @@ 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 {
|
||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
||||
try {
|
||||
@@ -66,12 +77,13 @@ class SessionController extends OCSController {
|
||||
}
|
||||
}
|
||||
|
||||
#[NoAdminRequired]
|
||||
#[NoCSRFRequired]
|
||||
public function close(int $boardId, ?string $token = null): DataResponse {
|
||||
if ($token === null) {
|
||||
return new DataResponse();
|
||||
}
|
||||
/**
|
||||
* delete a session if existing
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @param $boardId
|
||||
*/
|
||||
public function close(int $boardId, string $token) {
|
||||
$this->permissionService->checkPermission($this->boardMapper, $boardId, Acl::PERMISSION_READ);
|
||||
$this->sessionService->closeSession($boardId, $token);
|
||||
return new DataResponse();
|
||||
|
||||
@@ -39,16 +39,18 @@ use Sabre\HTTP\Util;
|
||||
* @package OCA\Deck\Controller
|
||||
*/
|
||||
class StackApiController extends ApiController {
|
||||
private $boardService;
|
||||
private $stackService;
|
||||
|
||||
/**
|
||||
* @param string $appName
|
||||
* @param IRequest $request
|
||||
* @param StackService $stackService
|
||||
*/
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
private StackService $stackService,
|
||||
private BoardService $boardService,
|
||||
) {
|
||||
public function __construct($appName, IRequest $request, StackService $stackService, BoardService $boardService) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->stackService = $stackService;
|
||||
$this->boardService = $boardService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,13 +30,12 @@ use OCP\AppFramework\Controller;
|
||||
use OCP\IRequest;
|
||||
|
||||
class StackController extends Controller {
|
||||
public function __construct(
|
||||
string $appName,
|
||||
IRequest $request,
|
||||
private StackService $stackService,
|
||||
private $userId,
|
||||
) {
|
||||
private $userId;
|
||||
private $stackService;
|
||||
public function __construct($appName, IRequest $request, StackService $stackService, $userId) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->userId = $userId;
|
||||
$this->stackService = $stackService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,7 @@ use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\Util;
|
||||
|
||||
class DeckWidgetUpcoming implements IAPIWidget, IButtonWidget, IIconWidget {
|
||||
class DeckWidget implements IAPIWidget, IButtonWidget, IIconWidget {
|
||||
private IL10N $l10n;
|
||||
private OverviewService $dashboardService;
|
||||
private IURLGenerator $urlGenerator;
|
||||
@@ -1,85 +0,0 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
@@ -23,10 +23,10 @@
|
||||
|
||||
namespace OCA\Deck\Db;
|
||||
|
||||
use OC\Cache\CappedMemoryCache;
|
||||
use OCA\Deck\Service\CirclesService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\QBMapper;
|
||||
use OCP\Cache\CappedMemoryCache;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IGroupManager;
|
||||
@@ -35,22 +35,37 @@ use Psr\Log\LoggerInterface;
|
||||
|
||||
/** @template-extends QBMapper<Board> */
|
||||
class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
private $labelMapper;
|
||||
private $aclMapper;
|
||||
private $stackMapper;
|
||||
private $userManager;
|
||||
private $groupManager;
|
||||
private $circlesService;
|
||||
private $logger;
|
||||
|
||||
/** @var CappedMemoryCache<Board[]> */
|
||||
private CappedMemoryCache $userBoardCache;
|
||||
private $userBoardCache;
|
||||
/** @var CappedMemoryCache<Board> */
|
||||
private CappedMemoryCache $boardCache;
|
||||
private $boardCache;
|
||||
|
||||
public function __construct(
|
||||
IDBConnection $db,
|
||||
private LabelMapper $labelMapper,
|
||||
private AclMapper $aclMapper,
|
||||
private StackMapper $stackMapper,
|
||||
private IUserManager $userManager,
|
||||
private IGroupManager $groupManager,
|
||||
private CirclesService $circlesService,
|
||||
private LoggerInterface $logger
|
||||
LabelMapper $labelMapper,
|
||||
AclMapper $aclMapper,
|
||||
StackMapper $stackMapper,
|
||||
IUserManager $userManager,
|
||||
IGroupManager $groupManager,
|
||||
CirclesService $circlesService,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
parent::__construct($db, 'deck_boards', Board::class);
|
||||
$this->labelMapper = $labelMapper;
|
||||
$this->aclMapper = $aclMapper;
|
||||
$this->stackMapper = $stackMapper;
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->circlesService = $circlesService;
|
||||
$this->logger = $logger;
|
||||
|
||||
$this->userBoardCache = new CappedMemoryCache();
|
||||
$this->boardCache = new CappedMemoryCache();
|
||||
@@ -66,8 +81,7 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
* @throws DoesNotExistException
|
||||
*/
|
||||
public function find(int $id, bool $withLabels = false, bool $withAcl = false, bool $allowDeleted = false): Board {
|
||||
$cacheKey = (string)$id;
|
||||
if (!isset($this->boardCache[$cacheKey])) {
|
||||
if (!isset($this->boardCache[$id])) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$deletedWhere = $allowDeleted ? $qb->expr()->gte('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)) : $qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT));
|
||||
$qb->select('*')
|
||||
@@ -75,22 +89,22 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($deletedWhere)
|
||||
->orderBy('id');
|
||||
$this->boardCache[(string)$id] = $this->findEntity($qb);
|
||||
$this->boardCache[$id] = $this->findEntity($qb);
|
||||
}
|
||||
|
||||
// Add labels
|
||||
if ($withLabels && $this->boardCache[$cacheKey]->getLabels() === null) {
|
||||
if ($withLabels && $this->boardCache[$id]->getLabels() === null) {
|
||||
$labels = $this->labelMapper->findAll($id);
|
||||
$this->boardCache[$cacheKey]->setLabels($labels);
|
||||
$this->boardCache[$id]->setLabels($labels);
|
||||
}
|
||||
|
||||
// Add acl
|
||||
if ($withAcl && $this->boardCache[$cacheKey]->getAcl() === null) {
|
||||
if ($withAcl && $this->boardCache[$id]->getAcl() === null) {
|
||||
$acl = $this->aclMapper->findAll($id);
|
||||
$this->boardCache[$cacheKey]->setAcl($acl);
|
||||
$this->boardCache[$id]->setAcl($acl);
|
||||
}
|
||||
|
||||
return $this->boardCache[$cacheKey];
|
||||
return $this->boardCache[$id];
|
||||
}
|
||||
|
||||
public function findBoardIds(string $userId): array {
|
||||
@@ -400,51 +414,6 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function findAllByTeam(string $teamId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('b.id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified')
|
||||
->from('deck_boards', 'b')
|
||||
->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id'))
|
||||
->where($qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_CIRCLE, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->eq('acl.participant', $qb->createNamedParameter($teamId, IQueryBuilder::PARAM_STR)));
|
||||
$entries = $this->findEntities($qb);
|
||||
foreach ($entries as $entry) {
|
||||
$entry->setShared(2);
|
||||
}
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function findTeamsForBoard(int $boardId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('acl.participant')
|
||||
->from('deck_boards', 'b')
|
||||
->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id'))
|
||||
->where($qb->expr()->eq('b.id', $qb->createNamedParameter($boardId, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_CIRCLE, IQueryBuilder::PARAM_INT)));
|
||||
|
||||
$result = $qb->executeQuery();
|
||||
return array_map(function ($entry) {
|
||||
return $entry['participant'];
|
||||
}, $result->fetchAll());
|
||||
}
|
||||
|
||||
public function isSharedWithTeam(int $boardId, string $teamId): bool {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('b.id', 'title', 'owner', 'color', 'archived', 'deleted_at', 'last_modified')
|
||||
->from('deck_boards', 'b')
|
||||
->innerJoin('b', 'deck_board_acl', 'acl', $qb->expr()->eq('b.id', 'acl.board_id'))
|
||||
->where($qb->expr()->eq('b.id', $qb->createNamedParameter($boardId, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->eq('acl.type', $qb->createNamedParameter(Acl::PERMISSION_TYPE_CIRCLE, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->eq('acl.participant', $qb->createNamedParameter($teamId, IQueryBuilder::PARAM_STR)));
|
||||
try {
|
||||
$this->findEntity($qb);
|
||||
return true;
|
||||
} catch (DoesNotExistException $e) {
|
||||
// Expected return falue
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function findAll(): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('id')
|
||||
@@ -495,7 +464,8 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
}
|
||||
|
||||
public function mapAcl(Acl &$acl) {
|
||||
$acl->resolveRelation('participant', function ($participant) use (&$acl) {
|
||||
$groupManager = $this->groupManager;
|
||||
$acl->resolveRelation('participant', function ($participant) use (&$acl, &$userManager, &$groupManager) {
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_USER) {
|
||||
if ($this->userManager->userExists($acl->getParticipant())) {
|
||||
return new User($acl->getParticipant(), $this->userManager);
|
||||
@@ -504,7 +474,7 @@ class BoardMapper extends QBMapper implements IPermissionMapper {
|
||||
return null;
|
||||
}
|
||||
if ($acl->getType() === Acl::PERMISSION_TYPE_GROUP) {
|
||||
$group = $this->groupManager->get($participant);
|
||||
$group = $groupManager->get($participant);
|
||||
if ($group !== null) {
|
||||
return new Group($group);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
@@ -42,8 +39,6 @@ use Sabre\VObject\Component\VCalendar;
|
||||
* @method int getDeletedAt()
|
||||
* @method void setDeletedAt(int $deletedAt)
|
||||
* @method bool getNotified()
|
||||
* @method ?DateTime getDone()
|
||||
* @method void setDone(?DateTime $done)
|
||||
*
|
||||
* @method void setLabels(Label[] $labels)
|
||||
* @method null|Label[] getLabels()
|
||||
@@ -90,7 +85,6 @@ class Card extends RelationalEntity {
|
||||
protected $owner;
|
||||
protected $order;
|
||||
protected $archived = false;
|
||||
protected $done = null;
|
||||
protected $duedate;
|
||||
protected $notified = false;
|
||||
protected $deletedAt = 0;
|
||||
@@ -114,7 +108,6 @@ class Card extends RelationalEntity {
|
||||
$this->addType('lastModified', 'integer');
|
||||
$this->addType('createdAt', 'integer');
|
||||
$this->addType('archived', 'boolean');
|
||||
$this->addType('done', 'datetime');
|
||||
$this->addType('notified', 'boolean');
|
||||
$this->addType('deletedAt', 'integer');
|
||||
$this->addType('duedate', 'datetime');
|
||||
@@ -148,21 +141,18 @@ class Card extends RelationalEntity {
|
||||
$event->add('RELATED-TO', 'deck-stack-' . $this->getStackId());
|
||||
|
||||
// FIXME: For write support: CANCELLED / IN-PROCESS handling
|
||||
if ($this->getDone() || $this->getArchived()) {
|
||||
$event->STATUS = $this->getArchived() ? "COMPLETED" : "NEEDS-ACTION";
|
||||
if ($this->getArchived()) {
|
||||
$date = new DateTime();
|
||||
$date->setTimestamp($this->getLastModified());
|
||||
$event->STATUS = 'COMPLETED';
|
||||
$event->COMPLETED = $this->getDone() ? $this->getDone() : $this->getArchived();
|
||||
} else {
|
||||
$event->STATUS = 'NEEDS-ACTION';
|
||||
$event->COMPLETED = $date;
|
||||
//$event->add('PERCENT-COMPLETE', 100);
|
||||
}
|
||||
if (count($this->getLabels()) > 0) {
|
||||
$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->DESCRIPTION = $this->getDescription();
|
||||
@@ -189,7 +179,7 @@ class Card extends RelationalEntity {
|
||||
return 'card';
|
||||
}
|
||||
|
||||
public function getETag(): string {
|
||||
public function getETag() {
|
||||
return md5((string)$this->getLastModified());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
|
||||
public function queryCardsByBoards(array $boardIds): IQueryBuilder {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->selectDistinct('c.*')
|
||||
$qb->select('c.*')
|
||||
->from('deck_cards', 'c')
|
||||
->innerJoin('c', 'deck_stacks', 's', $qb->expr()->eq('s.id', 'c.stack_id'))
|
||||
->andWhere($qb->expr()->in('s.board_id', $qb->createNamedParameter($boardIds, IQueryBuilder::PARAM_INT_ARRAY)));
|
||||
@@ -263,7 +263,6 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
->where($qb->expr()->in('s.board_id', $qb->createNamedParameter($boardIds, IQueryBuilder::PARAM_INT_ARRAY)))
|
||||
->andWhere($qb->expr()->isNotNull('c.duedate'))
|
||||
->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('s.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->eq('b.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||
@@ -285,7 +284,6 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
)
|
||||
// Filter out archived/deleted cards and board
|
||||
->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('s.deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)))
|
||||
->andWhere($qb->expr()->eq('b.archived', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)))
|
||||
@@ -300,7 +298,6 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
->where($qb->expr()->lt('duedate', $qb->createFunction('NOW()')))
|
||||
->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()->isNull('done'))
|
||||
->andWhere($qb->expr()->eq('deleted_at', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT)));
|
||||
return $this->findEntities($qb);
|
||||
}
|
||||
@@ -313,7 +310,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
return $this->findEntities($qb);
|
||||
}
|
||||
|
||||
public function search(array $boardIds, SearchQuery $query, ?int $limit = null, ?int $offset = null): array {
|
||||
public function search(array $boardIds, SearchQuery $query, int $limit = null, int $offset = null): array {
|
||||
$qb = $this->queryCardsByBoards($boardIds);
|
||||
$this->extendQueryByFilter($qb, $query);
|
||||
|
||||
@@ -339,6 +336,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
);
|
||||
}
|
||||
|
||||
$qb->groupBy('c.id');
|
||||
$qb->orderBy('c.last_modified', 'DESC');
|
||||
if ($limit !== null) {
|
||||
$qb->setMaxResults($limit);
|
||||
@@ -356,7 +354,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
return $entities;
|
||||
}
|
||||
|
||||
public function searchComments(array $boardIds, SearchQuery $query, ?int $limit = null, ?int $offset = null): array {
|
||||
public function searchComments(array $boardIds, SearchQuery $query, int $limit = null, int $offset = null): array {
|
||||
if (count($query->getTextTokens()) === 0) {
|
||||
return [];
|
||||
}
|
||||
@@ -382,6 +380,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
$tokenMatching
|
||||
);
|
||||
|
||||
$qb->groupBy('comments.id', 'c.id');
|
||||
$qb->orderBy('comments.id', 'DESC');
|
||||
if ($limit !== null) {
|
||||
$qb->setMaxResults($limit);
|
||||
@@ -614,7 +613,7 @@ class CardMapper extends QBMapper implements IPermissionMapper {
|
||||
});
|
||||
}
|
||||
|
||||
public function transferOwnership(string $ownerId, string $newOwnerId, ?int $boardId = null): void {
|
||||
public function transferOwnership(string $ownerId, string $newOwnerId, int $boardId = null): void {
|
||||
$params = [
|
||||
'owner' => $ownerId,
|
||||
'newOwner' => $newOwnerId
|
||||
|
||||
@@ -37,7 +37,7 @@ class User extends RelationalObject {
|
||||
public function getObjectSerialization() {
|
||||
return [
|
||||
'uid' => $this->getObject()->getUID(),
|
||||
'displayname' => $this->getDisplayName(),
|
||||
'displayname' => $this->getObject()->getDisplayName(),
|
||||
'type' => Acl::PERMISSION_TYPE_USER
|
||||
];
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ use OCA\Deck\Db\Card;
|
||||
class CardUpdatedEvent extends ACardEvent {
|
||||
private $cardBefore;
|
||||
|
||||
public function __construct(Card $card, ?Card $before = null) {
|
||||
public function __construct(Card $card, Card $before = null) {
|
||||
parent::__construct($card);
|
||||
$this->cardBefore = $before;
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
<?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,7 +32,6 @@ use OCP\Migration\IOutput;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
|
||||
class Version1011Date20231106160059 extends SimpleMigrationStep {
|
||||
|
||||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
|
||||
$schema = $schemaClosure();
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
<?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);
|
||||
|
||||
// link example: https://nextcloud.local/index.php/apps/deck/#/board/2
|
||||
$noIndexMatch = preg_match('/^' . preg_quote($start, '/') . '(?:\/#!?)?\/board\/[0-9]+$/', $referenceText) === 1;
|
||||
$indexMatch = preg_match('/^' . preg_quote($startIndex, '/') . '(?:\/#!?)?\/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;
|
||||
|
||||
return $noIndexMatch || $indexMatch;
|
||||
}
|
||||
@@ -108,9 +108,9 @@ class BoardReferenceProvider implements IReferenceProvider {
|
||||
$start = $this->urlGenerator->getAbsoluteURL('/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) {
|
||||
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) {
|
||||
return (int) $matches[1];
|
||||
|
||||
@@ -108,8 +108,8 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
||||
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
|
||||
|
||||
// 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;
|
||||
$indexMatchFull = preg_match('/^' . preg_quote($startIndex, '/') . '(?:\/#!?)?\/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;
|
||||
|
||||
// link example: https://nextcloud.local/index.php/apps/deck/card/11
|
||||
$noIndexMatch = preg_match('/^' . preg_quote($start, '/') . '\/card\/[0-9]+$/', $referenceText) === 1;
|
||||
@@ -125,17 +125,16 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
||||
if ($this->matchReference($referenceText)) {
|
||||
$ids = $this->getBoardCardId($referenceText);
|
||||
if ($ids !== null) {
|
||||
[, $cardId] = $ids;
|
||||
[$boardId, $cardId] = $ids;
|
||||
try {
|
||||
$card = $this->cardService->find((int) $cardId)->jsonSerialize();
|
||||
$stack = $this->stackService->find((int) $card['stackId'])->jsonSerialize();
|
||||
$board = $this->boardService->find((int) $stack['boardId'])->jsonSerialize();
|
||||
$board = $this->boardService->find((int)($boardId ?? $stack['boardId']))->jsonSerialize();
|
||||
} catch (NoPermissionException $e) {
|
||||
// Skip throwing if user has no permissions
|
||||
return null;
|
||||
}
|
||||
|
||||
$boardId = $board['id'];
|
||||
|
||||
$card = $this->sanitizeSerializedCard($card);
|
||||
$board = $this->sanitizeSerializedBoard($board);
|
||||
@@ -160,14 +159,14 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
||||
$result = $cardDetails->jsonSerialize();
|
||||
unset($result['assignedUsers']);
|
||||
return $result;
|
||||
}, $stack['cards'] ?? []);
|
||||
}, $stack['cards']);
|
||||
|
||||
return $stack;
|
||||
}
|
||||
|
||||
private function sanitizeSerializedBoard(array $board): array {
|
||||
unset($board['labels']);
|
||||
$board['owner'] = $board['owner']?->jsonSerialize();
|
||||
$board['owner'] = $board['owner']->jsonSerialize();
|
||||
unset($board['acl']);
|
||||
unset($board['users']);
|
||||
|
||||
@@ -177,18 +176,18 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
||||
private function sanitizeSerializedCard(array $card): array {
|
||||
$card['labels'] = array_map(function (Label $label) {
|
||||
return $label->jsonSerialize();
|
||||
}, $card['labels'] ?? []);
|
||||
}, $card['labels']);
|
||||
$card['assignedUsers'] = array_map(function (Assignment $assignment) {
|
||||
$result = $assignment->jsonSerialize();
|
||||
$result['participant'] = $result['participant']->jsonSerialize();
|
||||
return $result;
|
||||
}, $card['assignedUsers'] ?? []);
|
||||
$card['owner'] = $card['owner']?->jsonSerialize() ?? $card['owner'];
|
||||
}, $card['assignedUsers']);
|
||||
$card['owner'] = $card['owner']->jsonSerialize();
|
||||
unset($card['relatedStack']);
|
||||
unset($card['relatedBoard']);
|
||||
$card['attachments'] = array_map(function (Attachment $attachment) {
|
||||
return $attachment->jsonSerialize();
|
||||
}, $card['attachments'] ?? []);
|
||||
}, $card['attachments']);
|
||||
|
||||
return $card;
|
||||
}
|
||||
@@ -197,12 +196,12 @@ class CardReferenceProvider extends ADiscoverableReferenceProvider implements IS
|
||||
$start = $this->urlGenerator->getAbsoluteURL('/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) {
|
||||
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) {
|
||||
return [$matches2[1], $matches2[2]];
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
|
||||
class CreateCardReferenceProvider extends ADiscoverableReferenceProvider {
|
||||
|
||||
public function __construct(
|
||||
private IL10N $l10n,
|
||||
private IURLGenerator $urlGenerator,
|
||||
|
||||
@@ -43,7 +43,6 @@ use OCA\Deck\Event\CardCreatedEvent;
|
||||
use OCA\Deck\Event\CardDeletedEvent;
|
||||
use OCA\Deck\Event\CardUpdatedEvent;
|
||||
use OCA\Deck\Model\CardDetails;
|
||||
use OCA\Deck\Model\OptionalNullableValue;
|
||||
use OCA\Deck\NoPermissionException;
|
||||
use OCA\Deck\Notification\NotificationHelper;
|
||||
use OCA\Deck\StatusException;
|
||||
@@ -285,9 +284,6 @@ class CardService {
|
||||
* @param $description
|
||||
* @param $order
|
||||
* @param $duedate
|
||||
* @param $deletedAt
|
||||
* @param $archived
|
||||
* @param $done
|
||||
* @return \OCP\AppFramework\Db\Entity
|
||||
* @throws StatusException
|
||||
* @throws \OCA\Deck\NoPermissionException
|
||||
@@ -295,7 +291,7 @@ class CardService {
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
* @throws BadRequestException
|
||||
*/
|
||||
public function update($id, $title, $stackId, $type, $owner, $description = '', $order = 0, $duedate = null, $deletedAt = null, $archived = null, ?OptionalNullableValue $done = null) {
|
||||
public function update($id, $title, $stackId, $type, $owner, $description = '', $order = 0, $duedate = null, $deletedAt = null, $archived = null) {
|
||||
$this->cardServiceValidator->check(compact('id', 'title', 'stackId', 'type', 'owner', 'order'));
|
||||
|
||||
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT, allowDeletedCard: true);
|
||||
@@ -353,11 +349,6 @@ class CardService {
|
||||
if ($archived !== null) {
|
||||
$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
|
||||
@@ -528,57 +519,6 @@ class CardService {
|
||||
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 $labelId
|
||||
|
||||
@@ -190,7 +190,8 @@ class CommentService {
|
||||
}
|
||||
|
||||
private function formatComment(IComment $comment, $addReplyTo = false): array {
|
||||
$actorDisplayName = $this->userManager->getDisplayName($comment->getActorId()) ?? $comment->getActorId();
|
||||
$user = $this->userManager->get($comment->getActorId());
|
||||
$actorDisplayName = $user !== null ? $user->getDisplayName() : $comment->getActorId();
|
||||
|
||||
$formattedComment = [
|
||||
'id' => (int)$comment->getId(),
|
||||
|
||||
@@ -110,7 +110,7 @@ class ConfigService {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isCalendarEnabled(?int $boardId = null): bool {
|
||||
public function isCalendarEnabled(int $boardId = null): bool {
|
||||
if ($this->getUserId() === null) {
|
||||
return false;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ class ConfigService {
|
||||
return (bool)$this->config->getUserValue($this->getUserId(), Application::APP_ID, 'board:' . $boardId . ':calendar', $defaultState);
|
||||
}
|
||||
|
||||
public function isCardDetailsInModal(?int $boardId = null): bool {
|
||||
public function isCardDetailsInModal(int $boardId = null): bool {
|
||||
if ($this->getUserId() === null) {
|
||||
return false;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ class ConfigService {
|
||||
return array_filter($groups);
|
||||
}
|
||||
|
||||
public function getAttachmentFolder(?string $userId = null): string {
|
||||
public function getAttachmentFolder(string $userId = null): string {
|
||||
if ($userId === null && $this->getUserId() === null) {
|
||||
throw new NoPermissionException('Must be logged in get the attachment folder');
|
||||
}
|
||||
|
||||
@@ -250,7 +250,6 @@ class BoardImportService {
|
||||
$this->getImportSystem()->updateAcl($code, $acl);
|
||||
} catch (\Exception $e) {
|
||||
$this->addError('Failed to import acl rule for ' . $acl->getParticipant(), $e);
|
||||
|
||||
}
|
||||
}
|
||||
$this->getBoard()->setAcl($aclList);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
},
|
||||
"token": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9a-fA-FT]{64,76}$"
|
||||
"pattern": "^[0-9a-fA-F]{64}$"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -75,7 +75,7 @@ class SearchService {
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
}
|
||||
|
||||
public function searchCards(string $term, ?int $limit = null, ?int $cursor = null): array {
|
||||
public function searchCards(string $term, int $limit = null, ?int $cursor = null): array {
|
||||
$boards = $this->boardService->getUserBoards();
|
||||
$boardIds = array_map(static function (Board $board) {
|
||||
return $board->getId();
|
||||
@@ -115,7 +115,8 @@ class SearchService {
|
||||
$card = Card::fromRow($cardRow);
|
||||
// TODO: Only perform one enrich call here
|
||||
$self->cardService->enrichCards([$card]);
|
||||
$displayName = $this->userManager->getDisplayName($comment->getActorId()) ?? '';
|
||||
$user = $this->userManager->get($comment->getActorId());
|
||||
$displayName = $user ? $user->getDisplayName() : '';
|
||||
return new CommentSearchResultEntry($comment->getId(), $comment->getMessage(), $displayName, $card, $this->urlGenerator, $this->l10n);
|
||||
}, $matchedComments);
|
||||
}
|
||||
|
||||
@@ -516,7 +516,6 @@ class DeckShareProvider implements \OCP\Share\IShareProvider {
|
||||
}
|
||||
|
||||
$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
|
||||
$qb->andWhere($qb->expr()->eq('f.storage', $qb->createNamedParameter($node->getMountPoint()->getNumericStorageId(), IQueryBuilder::PARAM_INT)));
|
||||
if ($shallow) {
|
||||
$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
|
||||
} else {
|
||||
@@ -848,7 +847,7 @@ class DeckShareProvider implements \OCP\Share\IShareProvider {
|
||||
$pathSections = explode('/', $data['path'], 2);
|
||||
// FIXME: would not detect rare md5'd home storage case properly
|
||||
if ($pathSections[0] !== 'files'
|
||||
&& (strpos($data['storage_string_id'], 'home::') === 0 || strpos($data['storage_string_id'], 'object::user') === 0)) {
|
||||
&& in_array(explode(':', $data['storage_string_id'], 2)[0], ['home', 'object'])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -30,9 +30,9 @@ use OC\Files\Filesystem;
|
||||
use OCA\Deck\Service\ConfigService;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Server;
|
||||
use OCP\Share\Events\BeforeShareCreatedEvent;
|
||||
use OCP\Share\Events\VerifyMountPointEvent;
|
||||
use OCP\Share\IShare;
|
||||
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||
|
||||
class Listener {
|
||||
private ConfigService $configService;
|
||||
@@ -45,11 +45,11 @@ class Listener {
|
||||
/**
|
||||
* @psalm-suppress UndefinedClass
|
||||
*/
|
||||
$dispatcher->addListener(BeforeShareCreatedEvent::class, [self::class, 'listenPreShare'], 1000);
|
||||
$dispatcher->addListener('OCP\Share::preShare', [self::class, 'listenPreShare'], 1000);
|
||||
$dispatcher->addListener(VerifyMountPointEvent::class, [self::class, 'listenVerifyMountPointEvent'], 1000);
|
||||
}
|
||||
|
||||
public static function listenPreShare(BeforeShareCreatedEvent $event): void {
|
||||
public static function listenPreShare(GenericEvent $event): void {
|
||||
/** @var self $listener */
|
||||
$listener = Server::get(self::class);
|
||||
$listener->overwriteShareTarget($event);
|
||||
@@ -61,8 +61,9 @@ class Listener {
|
||||
$listener->overwriteMountPoint($event);
|
||||
}
|
||||
|
||||
public function overwriteShareTarget(BeforeShareCreatedEvent $event): void {
|
||||
$share = $event->getShare();
|
||||
public function overwriteShareTarget(GenericEvent $event): void {
|
||||
/** @var IShare $share */
|
||||
$share = $event->getSubject();
|
||||
|
||||
if ($share->getShareType() !== IShare::TYPE_DECK
|
||||
&& $share->getShareType() !== DeckShareProvider::SHARE_TYPE_DECK_USER) {
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\Deck\Teams;
|
||||
|
||||
use OCA\Deck\AppInfo\Application;
|
||||
use OCA\Deck\Db\Board;
|
||||
use OCA\Deck\Db\BoardMapper;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\Teams\TeamResource;
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2024 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/>.
|
||||
*/
|
||||
|
||||
class DeckTeamResourceProvider implements \OCP\Teams\ITeamResourceProvider {
|
||||
|
||||
public function __construct(
|
||||
private BoardMapper $boardMapper,
|
||||
private IURLGenerator $urlGenerator,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function getId(): string {
|
||||
return Application::APP_ID;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return 'Deck';
|
||||
}
|
||||
|
||||
public function getIconSvg(): string {
|
||||
return file_get_contents(__DIR__ . '/../../img/deck-current.svg');
|
||||
}
|
||||
|
||||
public function getSharedWith($teamId): array {
|
||||
$boards = $this->boardMapper->findAllByTeam($teamId);
|
||||
return array_map(function (Board $board) {
|
||||
return new TeamResource(
|
||||
$this,
|
||||
(string)$board->getId(),
|
||||
$board->getTitle(),
|
||||
$this->urlGenerator->linkToRouteAbsolute('deck.page.index') . '#/board/' . $board->getId(),
|
||||
$this->getBoardBulletIcon($board),
|
||||
$this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('deck', 'deck-current.svg')),
|
||||
);
|
||||
}, $boards);
|
||||
}
|
||||
|
||||
public function isSharedWithTeam(string $teamId, string $resourceId): bool {
|
||||
return $this->boardMapper->isSharedWithTeam((int)$resourceId, $teamId);
|
||||
}
|
||||
|
||||
public function getTeamsForResource(string $resourceId): array {
|
||||
return $this->boardMapper->findTeamsForBoard((int)$resourceId);
|
||||
}
|
||||
|
||||
public function getBoardBulletIcon(Board $board): string {
|
||||
return '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16"><g fill="#' . $board->getColor(). '"><rect ry="15" height="14" width="14" y="1" x="1"/></g></svg>';
|
||||
}
|
||||
}
|
||||
9434
package-lock.json
generated
9434
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
76
package.json
76
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "deck",
|
||||
"description": "",
|
||||
"version": "1.13.1",
|
||||
"version": "1.11.6",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Julius Härtl",
|
||||
@@ -31,36 +31,34 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/runtime": "^7.24.1",
|
||||
"@nextcloud/auth": "^2.3.0",
|
||||
"@nextcloud/axios": "^2.4.0",
|
||||
"@nextcloud/capabilities": "^1.1.0",
|
||||
"@nextcloud/dialogs": "^5.3.2",
|
||||
"@nextcloud/event-bus": "^3.1.0",
|
||||
"@nextcloud/files": "^3.4.0",
|
||||
"@nextcloud/initial-state": "^2.1.0",
|
||||
"@nextcloud/l10n": "^2.2.0",
|
||||
"@nextcloud/moment": "^1.3.1",
|
||||
"@nextcloud/notify_push": "^1.1.4",
|
||||
"@nextcloud/router": "^3.0.0",
|
||||
"@nextcloud/vue": "^8.12.0",
|
||||
"@babel/runtime": "^7.21.5",
|
||||
"@nextcloud/auth": "^2.0.0",
|
||||
"@nextcloud/axios": "^2.3.0",
|
||||
"@nextcloud/dialogs": "^4.0.1",
|
||||
"@nextcloud/event-bus": "^3.0.2",
|
||||
"@nextcloud/files": "^2.1.0",
|
||||
"@nextcloud/initial-state": "^2.0.0",
|
||||
"@nextcloud/l10n": "^2.1.0",
|
||||
"@nextcloud/moment": "^1.2.1",
|
||||
"@nextcloud/notify_push": "^1.1.3",
|
||||
"@nextcloud/router": "^2.1.1",
|
||||
"@nextcloud/vue": "^7.11.4",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"chroma-js": "^2.4.2",
|
||||
"dompurify": "^3.0.11",
|
||||
"dompurify": "^3.0.3",
|
||||
"lodash": "^4.17.21",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it": "^13.0.1",
|
||||
"markdown-it-link-attributes": "^4.0.1",
|
||||
"markdown-it-task-checkbox": "^1.0.6",
|
||||
"moment": "^2.30.1",
|
||||
"nextcloud-vue-collections": "^0.12.0",
|
||||
"p-queue": "^8.0.1",
|
||||
"url-search-params-polyfill": "^8.2.5",
|
||||
"vue": "^2.7.15",
|
||||
"moment": "^2.29.4",
|
||||
"nextcloud-vue-collections": "^0.11.1",
|
||||
"p-queue": "^7.3.4",
|
||||
"url-search-params-polyfill": "^8.1.1",
|
||||
"vue": "^2.7.14",
|
||||
"vue-at": "^2.5.1",
|
||||
"vue-click-outside": "^1.1.0",
|
||||
"vue-easymde": "^2.0.0",
|
||||
"vue-infinite-loading": "^2.4.5",
|
||||
"vue-material-design-icons": "^5.3.0",
|
||||
"vue-material-design-icons": "^5.2.0",
|
||||
"vue-router": "^3.6.5",
|
||||
"vue-smooth-dnd": "^0.8.1",
|
||||
"vuex": "^3.6.2",
|
||||
@@ -70,26 +68,26 @@
|
||||
"extends @nextcloud/browserslist-config"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.0.0",
|
||||
"npm": "^9.0.0"
|
||||
"node": "^16.0.0",
|
||||
"npm": "^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nextcloud/babel-config": "^1.0.0",
|
||||
"@nextcloud/browserslist-config": "^3.0.0",
|
||||
"@nextcloud/cypress": "^1.0.0-beta.7",
|
||||
"@nextcloud/eslint-config": "^8.3.0",
|
||||
"@nextcloud/stylelint-config": "^2.4.0",
|
||||
"@nextcloud/webpack-vue-config": "^6.0.0",
|
||||
"@relative-ci/agent": "^4.2.5",
|
||||
"@vue/test-utils": "^2.4.5",
|
||||
"@vue/vue2-jest": "^29.2.6",
|
||||
"cypress": "^13.7.1",
|
||||
"eslint-plugin-cypress": "^2.15.1",
|
||||
"eslint-webpack-plugin": "^4.1.0",
|
||||
"jest": "^29.7.0",
|
||||
"@nextcloud/browserslist-config": "^2.3.0",
|
||||
"@nextcloud/cypress": "^1.0.0-beta.2",
|
||||
"@nextcloud/eslint-config": "^8.2.1",
|
||||
"@nextcloud/stylelint-config": "^2.3.0",
|
||||
"@nextcloud/webpack-vue-config": "^5.5.1",
|
||||
"@relative-ci/agent": "^4.1.4",
|
||||
"@vue/test-utils": "^1.3.5",
|
||||
"@vue/vue2-jest": "^29.2.4",
|
||||
"cypress": "^12.12.0",
|
||||
"eslint-plugin-cypress": "^2.13.3",
|
||||
"eslint-webpack-plugin": "^4.0.1",
|
||||
"jest": "^29.5.0",
|
||||
"jest-serializer-vue": "^3.1.0",
|
||||
"stylelint-webpack-plugin": "^5.0.0",
|
||||
"vue-template-compiler": "^2.7.16"
|
||||
"stylelint-webpack-plugin": "^4.1.1",
|
||||
"vue-template-compiler": "^2.7.14"
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
|
||||
10
psalm.xml
10
psalm.xml
@@ -4,7 +4,7 @@
|
||||
resolveFromConfigFile="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
errorBaseline="tests/psalm-baseline.xml"
|
||||
>
|
||||
<stubs>
|
||||
@@ -18,6 +18,9 @@
|
||||
</projectFiles>
|
||||
<extraFiles>
|
||||
<directory name="vendor" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor/phpunit/php-code-coverage" />
|
||||
</ignoreFiles>
|
||||
</extraFiles>
|
||||
<issueHandlers>
|
||||
<UndefinedMagicMethod>
|
||||
@@ -37,10 +40,6 @@
|
||||
<referencedClass name="OC\*" />
|
||||
<referencedClass name="OC" />
|
||||
<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>
|
||||
</UndefinedClass>
|
||||
<UndefinedDocblockClass>
|
||||
@@ -51,7 +50,6 @@
|
||||
<referencedClass name="Doctrine\DBAL\Driver\Statement" />
|
||||
<referencedClass name="Doctrine\DBAL\Schema\Table" />
|
||||
<referencedClass name="OC\Security\CSP\ContentSecurityPolicyNonceManager" />
|
||||
<referencedClass name="Symfony\Component\Console\Command\Command" />
|
||||
</errorLevel>
|
||||
</UndefinedDocblockClass>
|
||||
</issueHandlers>
|
||||
|
||||
16
src/App.vue
16
src/App.vue
@@ -40,32 +40,25 @@
|
||||
|
||||
<router-view name="sidebar" :visible="!cardDetailsInModal || !$route.params.cardId" />
|
||||
</div>
|
||||
<KeyboardShortcuts />
|
||||
<CardMoveDialog />
|
||||
</NcContent>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import AppNavigation from './components/navigation/AppNavigation.vue'
|
||||
import KeyboardShortcuts from './components/KeyboardShortcuts.vue'
|
||||
import { NcModal, NcContent, NcAppContent } from '@nextcloud/vue'
|
||||
import { BoardApi } from './services/BoardApi.js'
|
||||
import { emit, subscribe } from '@nextcloud/event-bus'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import CardMoveDialog from './CardMoveDialog.vue'
|
||||
|
||||
const boardApi = new BoardApi()
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
CardMoveDialog,
|
||||
AppNavigation,
|
||||
NcModal,
|
||||
NcContent,
|
||||
NcAppContent,
|
||||
KeyboardShortcuts,
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
@@ -115,10 +108,7 @@ export default {
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const initialState = loadState('deck', 'initialBoards', null)
|
||||
if (initialState !== null) {
|
||||
this.$store.dispatch('loadBoards')
|
||||
}
|
||||
this.$store.dispatch('loadBoards')
|
||||
this.$store.dispatch('loadSharees')
|
||||
},
|
||||
mounted() {
|
||||
@@ -200,13 +190,11 @@ export default {
|
||||
background-image: url('../img/color_picker.svg');
|
||||
}
|
||||
|
||||
.v-select {
|
||||
.multiselect {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.modal__card {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
height: 100vh;
|
||||
max-height: calc(100vh - 120px);
|
||||
overflow: auto;
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
<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>
|
||||
<NcSelect v-model="selectedBoard"
|
||||
:input-label="t('deck', 'Select a board')"
|
||||
:placeholder="t('deck', 'Select a board')"
|
||||
:options="activeBoards"
|
||||
:max-height="100"
|
||||
label="title"
|
||||
@option:selected="loadStacksFromBoard" />
|
||||
<NcSelect v-model="selectedStack"
|
||||
:disabled="stacksFromBoard.length === 0"
|
||||
:placeholder="stacksFromBoard.length === 0 ? t('deck', 'No lists available') : t('deck', 'Select a list')"
|
||||
:input-label="t('deck', 'Select a list')"
|
||||
:options="stacksFromBoard"
|
||||
:max-height="100"
|
||||
label="title" />
|
||||
|
||||
<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, NcSelect } 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, NcSelect },
|
||||
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;
|
||||
margin: 20px 20px 100px 20px;
|
||||
|
||||
h3 {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.select {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.modal__content button {
|
||||
float: right;
|
||||
margin-top: 50px;
|
||||
}
|
||||
</style>
|
||||
@@ -24,12 +24,12 @@
|
||||
<NcModal class="card-selector" @close="close">
|
||||
<div id="modal-inner" :class="{ 'icon-loading': loading }">
|
||||
<h3>{{ title }}</h3>
|
||||
<NcSelect v-model="selectedBoard"
|
||||
<NcMultiselect v-model="selectedBoard"
|
||||
:placeholder="t('deck', 'Select a board')"
|
||||
:options="boards"
|
||||
:disabled="loading"
|
||||
label="title"
|
||||
@option:selected="fetchCardsFromBoard">
|
||||
@select="fetchCardsFromBoard">
|
||||
<template slot="singleLabel" slot-scope="props">
|
||||
<span>
|
||||
<span :style="{ 'backgroundColor': '#' + props.option.color }" class="board-bullet" />
|
||||
@@ -42,9 +42,9 @@
|
||||
<span>{{ props.option.title }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</NcSelect>
|
||||
</NcMultiselect>
|
||||
|
||||
<NcSelect v-model="selectedCard"
|
||||
<NcMultiselect v-model="selectedCard"
|
||||
:placeholder="t('deck', 'Select a card')"
|
||||
:options="cardsFromBoard"
|
||||
:disabled="loading || selectedBoard === ''"
|
||||
@@ -62,14 +62,14 @@
|
||||
|
||||
<script>
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { NcModal, NcSelect } from '@nextcloud/vue'
|
||||
import { NcModal, NcMultiselect } from '@nextcloud/vue'
|
||||
import axios from '@nextcloud/axios'
|
||||
|
||||
export default {
|
||||
name: 'CardSelector',
|
||||
components: {
|
||||
NcModal,
|
||||
NcSelect,
|
||||
NcMultiselect,
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<div class="activity--header">
|
||||
<img :src="activity.icon" class="activity--icon">
|
||||
<NcRichText class="activity--subject" :text="message.subject" :arguments="message.parameters" />
|
||||
<div class="activity--timestamp" :name="formatReadableDate(activity.datetime)">
|
||||
<div class="activity--timestamp" :title="formatReadableDate(activity.datetime)">
|
||||
{{ relativeDate(activity.datetime) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<NcModal v-if="modalShow" :name="t('deck', 'File already exists')" @close="modalShow=false">
|
||||
<NcModal v-if="modalShow" :title="t('deck', 'File already exists')" @close="modalShow=false">
|
||||
<div class="modal__content">
|
||||
<h2>{{ t('deck', 'File already exists') }}</h2>
|
||||
<p>
|
||||
|
||||
@@ -22,25 +22,21 @@
|
||||
|
||||
<template>
|
||||
<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 class="board-bullet icon-calendar-dark" />
|
||||
<h2 dir="auto">
|
||||
{{ overviewName }}
|
||||
</h2>
|
||||
<h2>{{ overviewName }}</h2>
|
||||
<NcActions>
|
||||
<NcActionButton icon="icon-add" @click="clickShowAddCardModel">
|
||||
{{ t('deck', 'Add card') }}
|
||||
</NcActionButton>
|
||||
</NcActions>
|
||||
<NcModal v-if="showAddCardModal" class="card-selector" @close="clickHideAddCardModel">
|
||||
<CreateNewCardCustomPicker show-created-notice @cancel="clickHideAddCardModel" />
|
||||
</NcModal>
|
||||
</div>
|
||||
<div v-else-if="board" class="board-title">
|
||||
<div :style="{backgroundColor: '#' + board.color}" class="board-bullet" />
|
||||
<h2 dir="auto">
|
||||
{{ board.title }}
|
||||
</h2>
|
||||
<h2>{{ board.title }}</h2>
|
||||
<p v-if="showArchived">
|
||||
({{ t('deck', 'Archived cards') }})
|
||||
</p>
|
||||
@@ -49,14 +45,9 @@
|
||||
<SessionList v-if="isNotifyPushEnabled && presentUsers.length"
|
||||
:sessions="presentUsers" />
|
||||
<div v-if="searchQuery || true" class="deck-search">
|
||||
<input id="deck-search-input"
|
||||
ref="search"
|
||||
:tabindex="0"
|
||||
type="search"
|
||||
<input type="search"
|
||||
class="icon-search"
|
||||
:value="searchQuery"
|
||||
@focus="$store.dispatch('toggleShortcutLock', true)"
|
||||
@blur="$store.dispatch('toggleShortcutLock', false)"
|
||||
@input="$store.commit('setSearchQuery', $event.target.value)">
|
||||
</div>
|
||||
<div v-if="board && canManage && !showArchived && !board.archived"
|
||||
@@ -75,10 +66,8 @@
|
||||
type="text"
|
||||
class="no-close"
|
||||
:placeholder="t('deck', 'List name')"
|
||||
required
|
||||
@focus="$store.dispatch('toggleShortcutLock', true)"
|
||||
@blur="$store.dispatch('toggleShortcutLock', false)">
|
||||
<input :title="t('deck', 'Add list')"
|
||||
required>
|
||||
<input v-tooltip="t('deck', 'Add list')"
|
||||
class="icon-confirm"
|
||||
type="submit"
|
||||
value="">
|
||||
@@ -86,24 +75,21 @@
|
||||
</div>
|
||||
<div v-if="board" class="board-action-buttons">
|
||||
<div class="board-action-buttons__filter">
|
||||
<NcPopover :placement="'bottom-end'"
|
||||
<NcPopover container=".board-action-buttons__filter"
|
||||
:placement="'bottom-end'"
|
||||
:aria-label="t('deck', 'Active filters')"
|
||||
:name="t('deck', 'Active filters')"
|
||||
@show="filterVisible=true"
|
||||
@hide="filterVisible=false">
|
||||
<!-- We cannot use NcActions here are the popover trigger does not update on reactive icons -->
|
||||
<template #trigger>
|
||||
<NcButton ref="filterPopover"
|
||||
:title="t('deck', 'Apply filter')"
|
||||
:aria-label="t('deck', 'Apply filter')"
|
||||
class="filter-button"
|
||||
:type="isFilterActive ? 'primary' : 'tertiary'">
|
||||
<template #icon>
|
||||
<FilterIcon v-if="isFilterActive" :size="20" decorative />
|
||||
<FilterOffIcon v-else :size="20" decorative />
|
||||
</template>
|
||||
</NcButton>
|
||||
</template>
|
||||
<NcButton slot="trigger"
|
||||
:title="t('deck', 'Apply filter')"
|
||||
class="filter-button"
|
||||
type="tertiary-no-background">
|
||||
<template #icon>
|
||||
<FilterIcon v-if="isFilterActive" :size="20" decorative />
|
||||
<FilterOffIcon v-else :size="20" decorative />
|
||||
</template>
|
||||
</NcButton>
|
||||
|
||||
<div v-if="filterVisible" class="filter">
|
||||
<h3>{{ t('deck', 'Filter by tag') }}</h3>
|
||||
@@ -138,40 +124,8 @@
|
||||
<label :for="user.uid"><NcAvatar :user="user.uid" :size="24" :disable-menu="true" /> {{ user.displayname }}</label>
|
||||
</div>
|
||||
|
||||
<h3>{{ t('deck', 'Filter by completed') }}</h3>
|
||||
<div class="filter--item">
|
||||
<input id="filter-option-both"
|
||||
v-model="filter.completed"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="both"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="filter-option-both">{{ t('deck', 'Open and completed') }}</label>
|
||||
</div>
|
||||
<div class="filter--item">
|
||||
<input id="filter-option-open"
|
||||
v-model="filter.completed"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="open"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="filter-option-open">{{ t('deck', 'Open') }}</label>
|
||||
</div>
|
||||
|
||||
<div class="filter--item">
|
||||
<input id="filter-option-completed"
|
||||
v-model="filter.completed"
|
||||
type="radio"
|
||||
class="radio"
|
||||
value="completed"
|
||||
@change="setFilter"
|
||||
@click="beforeSetFilter">
|
||||
<label for="filter-option-completed">{{ t('deck', 'Completed') }}</label>
|
||||
</div>
|
||||
|
||||
<h3>{{ t('deck', 'Filter by due date') }}</h3>
|
||||
|
||||
<div class="filter--item">
|
||||
<input id="overdue"
|
||||
v-model="filter.due"
|
||||
@@ -234,8 +188,7 @@
|
||||
</NcPopover>
|
||||
</div>
|
||||
|
||||
<NcActions :aria-label="t('deck', 'View Modes')"
|
||||
:name="t('deck', 'Toggle View Modes')">
|
||||
<NcActions>
|
||||
<NcActionButton @click="toggleShowArchived">
|
||||
<template #icon>
|
||||
<ArchiveIcon :size="20" decorative />
|
||||
@@ -252,18 +205,12 @@
|
||||
<ArrowCollapseVerticalIcon slot="icon" :size="20" decorative />
|
||||
{{ t('deck', 'Toggle compact mode') }}
|
||||
</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>
|
||||
<!-- FIXME: NcActionRouter currently doesn't work as an inline action -->
|
||||
<NcActions v-if="isFullApp">
|
||||
<NcActions>
|
||||
<NcActionButton icon="icon-menu-sidebar"
|
||||
:aria-label="t('deck', 'Open details')"
|
||||
:name="t('deck', 'Details')"
|
||||
:title="t('deck', 'Details')"
|
||||
@click="toggleDetailsView" />
|
||||
</NcActions>
|
||||
</div>
|
||||
@@ -273,11 +220,9 @@
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
||||
import { NcActions, NcActionButton, NcAvatar, NcButton, NcPopover, NcModal } from '@nextcloud/vue'
|
||||
import labelStyle from '../mixins/labelStyle.js'
|
||||
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 FilterOffIcon from 'vue-material-design-icons/FilterOff.vue'
|
||||
import ArrowCollapseVerticalIcon from 'vue-material-design-icons/ArrowCollapseVertical.vue'
|
||||
@@ -285,7 +230,6 @@ import ArrowExpandVerticalIcon from 'vue-material-design-icons/ArrowExpandVertic
|
||||
import SessionList from './SessionList.vue'
|
||||
import { isNotifyPushEnabled } from '../sessions.js'
|
||||
import CreateNewCardCustomPicker from '../views/CreateNewCardCustomPicker.vue'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
|
||||
export default {
|
||||
name: 'Controls',
|
||||
@@ -298,7 +242,6 @@ export default {
|
||||
NcPopover,
|
||||
NcAvatar,
|
||||
ArchiveIcon,
|
||||
ImageIcon,
|
||||
FilterIcon,
|
||||
FilterOffIcon,
|
||||
ArrowCollapseVerticalIcon,
|
||||
@@ -325,7 +268,7 @@ export default {
|
||||
filterVisible: false,
|
||||
showArchived: false,
|
||||
isAddStackVisible: false,
|
||||
filter: { tags: [], users: [], due: '', unassigned: false, completed: 'both' },
|
||||
filter: { tags: [], users: [], due: '', unassigned: false },
|
||||
showAddCardModal: false,
|
||||
defaultPageTitle: false,
|
||||
isNotifyPushEnabled: isNotifyPushEnabled(),
|
||||
@@ -338,9 +281,7 @@ export default {
|
||||
'canManage',
|
||||
]),
|
||||
...mapState({
|
||||
isFullApp: state => state.isFullApp,
|
||||
compactMode: state => state.compactMode,
|
||||
showCardCover: state => state.showCardCover,
|
||||
searchQuery: state => state.searchQuery,
|
||||
}),
|
||||
detailsRoute() {
|
||||
@@ -349,7 +290,7 @@ export default {
|
||||
}
|
||||
},
|
||||
isFilterActive() {
|
||||
return this.filter.tags.length !== 0 || this.filter.users.length !== 0 || this.filter.due !== '' || this.filter.completed !== 'both'
|
||||
return this.filter.tags.length !== 0 || this.filter.users.length !== 0 || this.filter.due !== ''
|
||||
},
|
||||
labelsSorted() {
|
||||
return [...this.board.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
|
||||
@@ -370,18 +311,7 @@ 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() {
|
||||
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('')
|
||||
},
|
||||
methods: {
|
||||
@@ -392,12 +322,7 @@ export default {
|
||||
}
|
||||
if (e.target.value === 'unassigned') {
|
||||
this.filter.users = []
|
||||
this.$store.dispatch('setFilter', { ...this.filter })
|
||||
} else {
|
||||
this.filter.completed = 'both'
|
||||
this.$store.dispatch('setFilter', { ...this.filter })
|
||||
}
|
||||
this.$store.dispatch('setFilter', { ...this.filter })
|
||||
},
|
||||
setFilter() {
|
||||
if (this.filter.users.length > 0) {
|
||||
@@ -411,9 +336,6 @@ export default {
|
||||
toggleCompactMode() {
|
||||
this.$store.dispatch('toggleCompactMode')
|
||||
},
|
||||
toggleShowCardCover() {
|
||||
this.$store.dispatch('toggleShowCardCover')
|
||||
},
|
||||
toggleShowArchived() {
|
||||
this.$store.dispatch('toggleShowArchived')
|
||||
this.showArchived = !this.showArchived
|
||||
@@ -439,7 +361,7 @@ export default {
|
||||
}
|
||||
},
|
||||
clearFilter() {
|
||||
const filterReset = { tags: [], users: [], due: '', completed: 'both' }
|
||||
const filterReset = { tags: [], users: [], due: '' }
|
||||
this.$store.dispatch('setFilter', { ...filterReset })
|
||||
this.filter = filterReset
|
||||
},
|
||||
@@ -450,9 +372,6 @@ export default {
|
||||
this.showAddCardModal = false
|
||||
},
|
||||
setPageTitle(title) {
|
||||
if (!this.isFullApp) {
|
||||
return
|
||||
}
|
||||
if (this.defaultPageTitle === false) {
|
||||
this.defaultPageTitle = window.document.title
|
||||
if (this.defaultPageTitle.indexOf(' - Deck - ') !== -1) {
|
||||
@@ -468,23 +387,6 @@ export default {
|
||||
}
|
||||
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>
|
||||
@@ -556,6 +458,7 @@ export default {
|
||||
input + label {
|
||||
display: block;
|
||||
padding: 6px 0;
|
||||
vertical-align: middle;
|
||||
.avatardiv {
|
||||
vertical-align: middle;
|
||||
margin-bottom: 2px;
|
||||
@@ -587,11 +490,8 @@ export default {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
|
||||
&[data-popper-shown] {
|
||||
background-color: var(--color-background-hover);
|
||||
&.button-vue--vue-primary {
|
||||
background-color: var(--color-primary-element);
|
||||
}
|
||||
&:hover, &:focus {
|
||||
background-color: rgba(127,127,127,0.25) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -599,4 +499,8 @@ export default {
|
||||
.popover:focus {
|
||||
outline: 2px solid var(--color-main-text);
|
||||
}
|
||||
|
||||
.tooltip-inner.popover-inner {
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,279 +0,0 @@
|
||||
<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>
|
||||
@@ -20,7 +20,7 @@
|
||||
* -->
|
||||
|
||||
<template>
|
||||
<div :title="t('text', 'Currently present people')"
|
||||
<div v-tooltip.bottom="t('text', 'Currently present people')"
|
||||
class="avatar-list">
|
||||
<div v-for="session in sessionsVisible"
|
||||
:key="session.uid"
|
||||
@@ -37,13 +37,16 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { NcAvatar } from '@nextcloud/vue'
|
||||
import { NcAvatar, Tooltip } from '@nextcloud/vue'
|
||||
|
||||
export default {
|
||||
name: 'SessionList',
|
||||
components: {
|
||||
NcAvatar,
|
||||
},
|
||||
directives: {
|
||||
tooltip: Tooltip,
|
||||
},
|
||||
props: {
|
||||
sessions: {
|
||||
type: Array,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="board-wrapper" :tabindex="-1">
|
||||
<div class="board-wrapper">
|
||||
<Controls :board="board" />
|
||||
|
||||
<transition name="fade" mode="out-in">
|
||||
@@ -52,18 +52,14 @@
|
||||
class="no-close"
|
||||
:placeholder="t('deck', 'List name')"
|
||||
required>
|
||||
<input title="t('deck', 'Add list')"
|
||||
<input v-tooltip="t('deck', 'Add list')"
|
||||
class="icon-confirm"
|
||||
type="submit"
|
||||
value="">
|
||||
</form>
|
||||
</template>
|
||||
</NcEmptyContent>
|
||||
<div v-else-if="!isEmpty && !loading"
|
||||
key="board"
|
||||
ref="board"
|
||||
class="board"
|
||||
@mousedown="onMouseDown">
|
||||
<div v-else-if="!isEmpty && !loading" key="board" class="board">
|
||||
<Container lock-axix="y"
|
||||
orientation="horizontal"
|
||||
:drag-handle-selector="dragHandleSelector"
|
||||
@@ -74,37 +70,28 @@
|
||||
<Draggable v-for="stack in stacksByBoard"
|
||||
:key="stack.id"
|
||||
data-click-closes-sidebar="true"
|
||||
data-dragscroll-enabled
|
||||
class="stack-draggable-wrapper">
|
||||
<Stack :stack="stack" :dragging="draggingStack" data-click-closes-sidebar="true" />
|
||||
</Draggable>
|
||||
</Container>
|
||||
</div>
|
||||
</transition>
|
||||
<GlobalSearchResults v-if="isFullApp" />
|
||||
<NcModal v-if="localModal"
|
||||
:clear-view-delay="0"
|
||||
:close-button-contained="true"
|
||||
size="large"
|
||||
@close="localModal = null">
|
||||
<div class="modal__content modal__card">
|
||||
<CardSidebar :id="localModal" @close="localModal = null" />
|
||||
</div>
|
||||
</NcModal>
|
||||
<GlobalSearchResults />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { Container, Draggable } from 'vue-smooth-dnd'
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import Controls from '../Controls.vue'
|
||||
import DeckIcon from '../icons/DeckIcon.vue'
|
||||
import Stack from './Stack.vue'
|
||||
import { NcEmptyContent, NcModal } from '@nextcloud/vue'
|
||||
import { NcEmptyContent } from '@nextcloud/vue'
|
||||
import GlobalSearchResults from '../search/GlobalSearchResults.vue'
|
||||
import { showError } from '../../helpers/errors.js'
|
||||
import { createSession } from '../../sessions.js'
|
||||
import CardSidebar from '../card/CardSidebar.vue'
|
||||
|
||||
export default {
|
||||
name: 'Board',
|
||||
components: {
|
||||
@@ -115,8 +102,6 @@ export default {
|
||||
Draggable,
|
||||
Stack,
|
||||
NcEmptyContent,
|
||||
NcModal,
|
||||
CardSidebar,
|
||||
},
|
||||
inject: [
|
||||
'boardApi',
|
||||
@@ -132,14 +117,10 @@ export default {
|
||||
draggingStack: false,
|
||||
loading: true,
|
||||
newStackTitle: '',
|
||||
currentScrollPosX: null,
|
||||
currentMousePosX: null,
|
||||
localModal: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
isFullApp: state => state.isFullApp,
|
||||
board: state => state.currentBoard,
|
||||
showArchived: state => state.showArchived,
|
||||
}),
|
||||
@@ -168,9 +149,6 @@ export default {
|
||||
created() {
|
||||
this.session = createSession(this.id)
|
||||
this.fetchData()
|
||||
this.$root.$on('open-card', (cardId) => {
|
||||
this.localModal = cardId
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.session.close()
|
||||
@@ -205,40 +183,12 @@ export default {
|
||||
this.$store.dispatch('createStack', newStack)
|
||||
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>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@import '../../css/animations';
|
||||
@import '../../css/variables';
|
||||
|
||||
@@ -298,9 +248,9 @@ export default {
|
||||
padding: $stack-spacing;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
scrollbar-gutter: stable;
|
||||
padding-top: 15px;
|
||||
margin-top: -10px;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.smooth-dnd-container.vertical > .smooth-dnd-draggable-wrapper {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<template>
|
||||
<NcAppSidebar v-if="board != null"
|
||||
:actions="[]"
|
||||
:name="board.title"
|
||||
:title="board.title"
|
||||
@close="closeSidebar">
|
||||
<NcAppSidebarTab id="sharing"
|
||||
:order="0"
|
||||
@@ -56,7 +56,7 @@
|
||||
<NcAppSidebarTab v-if="hasActivity"
|
||||
id="activity"
|
||||
:order="3"
|
||||
:name="t('deck', 'Activity')">
|
||||
:name="t('deck', 'Timeline')">
|
||||
<template #icon>
|
||||
<ActivityIcon :size="20" />
|
||||
</template>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<ul>
|
||||
<li v-for="deletedStack in deletedStacks" :key="deletedStack.id">
|
||||
<span class="icon icon-deck" />
|
||||
<div class="title" dir="auto">
|
||||
<div class="title">
|
||||
<span>{{ deletedStack.title }}</span>
|
||||
<span class="timestamp">{{ relativeDate(deletedStack.deletedAt*1000) }}</span>
|
||||
</div>
|
||||
@@ -18,7 +18,7 @@
|
||||
<ul>
|
||||
<li v-for="deletedCard in deletedCards" :key="deletedCard.id">
|
||||
<div class="icon icon-deck" />
|
||||
<div class="title" dir="auto">
|
||||
<div class="title">
|
||||
<span>{{ deletedCard.title }}</span>
|
||||
<span class="timestamp">{{ relativeDate(deletedCard.deletedAt*1000) }}</span>
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user