Compare commits
530 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d0741e691 | ||
|
|
090e788c0c | ||
|
|
0e6b79fe9b | ||
|
|
ab3a42fc11 | ||
|
|
56bee425b9 | ||
|
|
6e192db79b | ||
|
|
c29aed239c | ||
|
|
9c8f5d5f63 | ||
|
|
1fcb667a3c | ||
|
|
7390acae26 | ||
|
|
677123a8f7 | ||
|
|
067ec5e057 | ||
|
|
fd406a0adb | ||
|
|
1d4fe31155 | ||
|
|
c2b8408cd2 | ||
|
|
b50e295e27 | ||
|
|
97864ac1ff | ||
|
|
f940d23968 | ||
|
|
ce31e02d6a | ||
|
|
c2189683c7 | ||
|
|
9b2903b4d5 | ||
|
|
2875e23b96 | ||
|
|
1d54fc3ae8 | ||
|
|
23e88a7e15 | ||
|
|
08ef55c950 | ||
|
|
4d10b5fd59 | ||
|
|
4a3ba6540c | ||
|
|
9c6d80d5d3 | ||
|
|
2d3ef29041 | ||
|
|
4d9e26a6ce | ||
|
|
1a2c950b61 | ||
|
|
029accfe49 | ||
|
|
7716fb6738 | ||
|
|
da87973b85 | ||
|
|
91aa14c7c2 | ||
|
|
f3da8f80a7 | ||
|
|
5021e475c7 | ||
|
|
7628eb425c | ||
|
|
d33725303a | ||
|
|
e0808273ec | ||
|
|
84dc4ce1dd | ||
|
|
e7fcef3e3a | ||
|
|
99591eae0e | ||
|
|
a88ea8f4b3 | ||
|
|
5772a7025d | ||
|
|
abd82db9af | ||
|
|
6efcf374d3 | ||
|
|
335d9a3a42 | ||
|
|
040e248962 | ||
|
|
87c0bc819a | ||
|
|
d902f88258 | ||
|
|
a6bdf077ff | ||
|
|
0f2e735a20 | ||
|
|
bb2eb7221a | ||
|
|
e69b5465bd | ||
|
|
7d393292f3 | ||
|
|
1c2c700593 | ||
|
|
71e7c98fd6 | ||
|
|
da650bb356 | ||
|
|
ddc903cc03 | ||
|
|
e70340e267 | ||
|
|
c140e2f946 | ||
|
|
7cffc7cdff | ||
|
|
c5ffde0469 | ||
|
|
f561dc77e6 | ||
|
|
b9f37c6c36 | ||
|
|
60e6ac0f10 | ||
|
|
9fbd85a67a | ||
|
|
27b8c79bca | ||
|
|
31ae00708d | ||
|
|
3b8ee46bdd | ||
|
|
999010aec2 | ||
|
|
b577a79915 | ||
|
|
d6373226db | ||
|
|
436ca348e4 | ||
|
|
1f56372aa0 | ||
|
|
5028b48777 | ||
|
|
e968b6f680 | ||
|
|
452f49c17c | ||
|
|
df0a8515a3 | ||
|
|
7b1dea3e56 | ||
|
|
6862b1c07e | ||
|
|
d05694c2ce | ||
|
|
d156a6ae80 | ||
|
|
511f17f13f | ||
|
|
8073ae9c0e | ||
|
|
6eb8c117a3 | ||
|
|
f74a3d6724 | ||
|
|
d3efff0ce7 | ||
|
|
44fd63ef7e | ||
|
|
19f5063068 | ||
|
|
8bc497b4b2 | ||
|
|
fba60673c5 | ||
|
|
36afac9eff | ||
|
|
014f708752 | ||
|
|
2139a82e9d | ||
|
|
4e320ff1e9 | ||
|
|
d4c744b084 | ||
|
|
695042cdd0 | ||
|
|
6c8ac1ed47 | ||
|
|
b75d1ef3fd | ||
|
|
cba7525951 | ||
|
|
1db20878a9 | ||
|
|
12037679e5 | ||
|
|
80b025fafe | ||
|
|
91f9b8ee72 | ||
|
|
ab1c765ff6 | ||
|
|
8661d51317 | ||
|
|
625ebdc4c0 | ||
|
|
283aa01fd4 | ||
|
|
2ad66ca76e | ||
|
|
1d8b4cd33d | ||
|
|
469e687686 | ||
|
|
ee2ebbecf8 | ||
|
|
90d6923fb6 | ||
|
|
d08bd23578 | ||
|
|
f36a1614c2 | ||
|
|
011470cfde | ||
|
|
fecd59b511 | ||
|
|
59827e0f69 | ||
|
|
619f70b33b | ||
|
|
bc904c44d4 | ||
|
|
6a43db39a3 | ||
|
|
57921c9e96 | ||
|
|
eb4b82060a | ||
|
|
60bf07d88b | ||
|
|
71617d9d6b | ||
|
|
1c040d35be | ||
|
|
329df8e856 | ||
|
|
493eee601b | ||
|
|
e3405c915b | ||
|
|
001aaa4dcd | ||
|
|
9f62a24450 | ||
|
|
6b8d42f176 | ||
|
|
bc7c5ea4b7 | ||
|
|
c3d925a172 | ||
|
|
1b2fed9e86 | ||
|
|
f4f7c05f9f | ||
|
|
610507f790 | ||
|
|
edbeda81f6 | ||
|
|
9accaa4987 | ||
|
|
0dbe106907 | ||
|
|
64e3af25f9 | ||
|
|
77a3563b89 | ||
|
|
ba3b5b59ff | ||
|
|
60d77e4d33 | ||
|
|
6f595aebdc | ||
|
|
0b5c7fb56a | ||
|
|
f14e9758a0 | ||
|
|
bd5f2c13b7 | ||
|
|
bdb9442671 | ||
|
|
8874b3df69 | ||
|
|
74550b9953 | ||
|
|
a0af85abe4 | ||
|
|
34316d84f0 | ||
|
|
84a9e72463 | ||
|
|
da8b7774b4 | ||
|
|
0de1c581e8 | ||
|
|
1eeaff7f29 | ||
|
|
c88b25c627 | ||
|
|
14244f257e | ||
|
|
bcc9f03942 | ||
|
|
002587523f | ||
|
|
313ceb9a95 | ||
|
|
36977564a2 | ||
|
|
27ec348533 | ||
|
|
a5ee26a592 | ||
|
|
3496c09472 | ||
|
|
17999595a5 | ||
|
|
96dac29870 | ||
|
|
be752061ff | ||
|
|
1652bb921a | ||
|
|
1ab2ee1daa | ||
|
|
7aa7574e26 | ||
|
|
138faf2de1 | ||
|
|
2887df270d | ||
|
|
7e58486877 | ||
|
|
3454127aee | ||
|
|
c0a9597877 | ||
|
|
f63eef36b7 | ||
|
|
35e7c7dbe7 | ||
|
|
75189217b0 | ||
|
|
519336787c | ||
|
|
9e792db7c0 | ||
|
|
23a218d9af | ||
|
|
ec7eb72f05 | ||
|
|
4324fe9e2e | ||
|
|
0e3b54a5d4 | ||
|
|
8dffaaa8c5 | ||
|
|
6d88ea7ef6 | ||
|
|
4ca406472d | ||
|
|
f8cd20a01a | ||
|
|
aa2b9adeec | ||
|
|
37de63434e | ||
|
|
bb665fa56c | ||
|
|
a13e4b664d | ||
|
|
e020c2631f | ||
|
|
781e2b0bb2 | ||
|
|
2d35d90999 | ||
|
|
65952acfdb | ||
|
|
7ec4870999 | ||
|
|
015e2d9461 | ||
|
|
623b55d348 | ||
|
|
0e37354a6e | ||
|
|
e16852ad17 | ||
|
|
8fc38a41d0 | ||
|
|
097bb21b45 | ||
|
|
39ae9332e2 | ||
|
|
cc92937c6b | ||
|
|
ac9fef5f05 | ||
|
|
4e67c3172b | ||
|
|
4a45687a28 | ||
|
|
38dc7945dd | ||
|
|
70d3fba187 | ||
|
|
10b7d8b335 | ||
|
|
fcabdbdc24 | ||
|
|
408ea69272 | ||
|
|
c6d16f4c16 | ||
|
|
770142232c | ||
|
|
501545f2e5 | ||
|
|
f71f24c450 | ||
|
|
b8cb364f00 | ||
|
|
7a673efc4a | ||
|
|
36a5888faf | ||
|
|
6bfd9127ed | ||
|
|
a5e155b6c7 | ||
|
|
a0a0f9443d | ||
|
|
3cb811bb79 | ||
|
|
910325a712 | ||
|
|
2a6385c68a | ||
|
|
33cb61fe07 | ||
|
|
f3fc9904d2 | ||
|
|
3b7382f2d0 | ||
|
|
7d52891eb8 | ||
|
|
a36bfda277 | ||
|
|
427e954764 | ||
|
|
5f6eb7848f | ||
|
|
dfdd3222ea | ||
|
|
8845ba1033 | ||
|
|
1b82ca5d17 | ||
|
|
cefec146a2 | ||
|
|
6db4cf44bc | ||
|
|
eff48652c9 | ||
|
|
28bdb2ea43 | ||
|
|
7b2de87b05 | ||
|
|
1fcf3f95ac | ||
|
|
2f893eb6ad | ||
|
|
65272d76e1 | ||
|
|
96bd7194af | ||
|
|
f064fe55e2 | ||
|
|
799497e62f | ||
|
|
a87277735d | ||
|
|
9d5c67cbef | ||
|
|
c031e1b9c2 | ||
|
|
54b4b7c430 | ||
|
|
a953822671 | ||
|
|
ea4f4e8335 | ||
|
|
0bf11c1976 | ||
|
|
98bd957dd6 | ||
|
|
6089d190f4 | ||
|
|
c51509faeb | ||
|
|
c817ff2245 | ||
|
|
a9dd5b8ebe | ||
|
|
3105ec62ec | ||
|
|
012454abbc | ||
|
|
179f75052c | ||
|
|
e49c905d6e | ||
|
|
a25f4ac6c1 | ||
|
|
37a9655f90 | ||
|
|
717955a233 | ||
|
|
2f14fa60e9 | ||
|
|
36940d3c4b | ||
|
|
804e662ec4 | ||
|
|
6ef071cee9 | ||
|
|
2bf98e57b1 | ||
|
|
5f9d039056 | ||
|
|
76943246c8 | ||
|
|
ecdae3a558 | ||
|
|
836d15486b | ||
|
|
1281bde407 | ||
|
|
a250b0ec7a | ||
|
|
b09c622b7b | ||
|
|
99153659ae | ||
|
|
c3661e6b25 | ||
|
|
b17b2bec39 | ||
|
|
8e524e3ccb | ||
|
|
5b7cd146d0 | ||
|
|
e18e8fb032 | ||
|
|
5af9b3937a | ||
|
|
0f9972cff4 | ||
|
|
ac852cd4e7 | ||
|
|
8ff832a9f9 | ||
|
|
45d8e224e4 | ||
|
|
5238e475a7 | ||
|
|
5d8e52b106 | ||
|
|
436626684b | ||
|
|
d6e218064f | ||
|
|
c5cfef3ddb | ||
|
|
78233b2d62 | ||
|
|
f3b5fd4030 | ||
|
|
5d0180956a | ||
|
|
75c7502186 | ||
|
|
3733b13651 | ||
|
|
0543c1d775 | ||
|
|
abb8ae5cff | ||
|
|
40fd0c1401 | ||
|
|
fa0a3f099f | ||
|
|
22087fddc3 | ||
|
|
db59150d74 | ||
|
|
8b8db54309 | ||
|
|
5b019b1c04 | ||
|
|
1811dc73b7 | ||
|
|
cc96da86c2 | ||
|
|
7523792b9a | ||
|
|
29a555f475 | ||
|
|
2d757e9a95 | ||
|
|
691988c885 | ||
|
|
2713434084 | ||
|
|
f18accd9c4 | ||
|
|
2d95d29c63 | ||
|
|
58a5a73124 | ||
|
|
cc4439517d | ||
|
|
f357d9ebd0 | ||
|
|
c7b7f767e0 | ||
|
|
b4984d6e73 | ||
|
|
db4b9a3d97 | ||
|
|
d9478518fe | ||
|
|
dfd2e09136 | ||
|
|
a5e23ead24 | ||
|
|
ead3608082 | ||
|
|
f3efc9d95a | ||
|
|
53cf93cb8e | ||
|
|
587483df19 | ||
|
|
21920b2380 | ||
|
|
7e7dfa3b0b | ||
|
|
cdb41f4376 | ||
|
|
ec2f9ad431 | ||
|
|
319b13fbf9 | ||
|
|
4f1f9fd78d | ||
|
|
1155b85554 | ||
|
|
e577fbca20 | ||
|
|
5eadc789fe | ||
|
|
86431ec3dc | ||
|
|
2eb39d43fc | ||
|
|
f645f73993 | ||
|
|
e3201ee21a | ||
|
|
37ee10121b | ||
|
|
aecd402628 | ||
|
|
bf28b32684 | ||
|
|
1accc9f11e | ||
|
|
0297c6384c | ||
|
|
f86d060028 | ||
|
|
fe59f0f976 | ||
|
|
86515a7219 | ||
|
|
159535a1f5 | ||
|
|
7f22f82b63 | ||
|
|
78955c54ae | ||
|
|
e8c8d4c08d | ||
|
|
5aabac0554 | ||
|
|
492afaa11e | ||
|
|
17fb44f248 | ||
|
|
3e5bea372d | ||
|
|
56708643d5 | ||
|
|
39ca8e5255 | ||
|
|
8402b80690 | ||
|
|
49c21f7dc4 | ||
|
|
0262902164 | ||
|
|
31e2edabb8 | ||
|
|
ba55adde4f | ||
|
|
1c62be7b31 | ||
|
|
8adad1457a | ||
|
|
5423894175 | ||
|
|
dfc8b15ab2 | ||
|
|
3950beaaad | ||
|
|
b16cfbf662 | ||
|
|
dd841b5e1a | ||
|
|
ec9b1b992a | ||
|
|
8fd36933ce | ||
|
|
caab88ed19 | ||
|
|
e2ad6739f1 | ||
|
|
fcd831a010 | ||
|
|
85ba0c524f | ||
|
|
6de2614f05 | ||
|
|
6782641c28 | ||
|
|
ffa9716722 | ||
|
|
690db724b3 | ||
|
|
ca66afd841 | ||
|
|
4739681929 | ||
|
|
002f956861 | ||
|
|
e567c91c25 | ||
|
|
fd586db444 | ||
|
|
9c157a7112 | ||
|
|
68efe83fdf | ||
|
|
78780ff44b | ||
|
|
e33faa594d | ||
|
|
8688b05474 | ||
|
|
362de5d411 | ||
|
|
57dd1a7b40 | ||
|
|
47e3aad1b7 | ||
|
|
c118de2165 | ||
|
|
99fd3c9945 | ||
|
|
4d4c2257a0 | ||
|
|
a181ffdd41 | ||
|
|
a57a5350bc | ||
|
|
057c0875ba | ||
|
|
230756112b | ||
|
|
13295c7f8c | ||
|
|
f9fff3a165 | ||
|
|
a410aca159 | ||
|
|
81510ce1e0 | ||
|
|
5d2d114c78 | ||
|
|
865d961436 | ||
|
|
930845abfa | ||
|
|
0190a51546 | ||
|
|
9a21f5ee66 | ||
|
|
1c1b1f1f6d | ||
|
|
fbcc2a4934 | ||
|
|
83b8488b05 | ||
|
|
65fdb98302 | ||
|
|
d32da1017c | ||
|
|
643797daca | ||
|
|
b854015e16 | ||
|
|
e7400fe1e5 | ||
|
|
3f272b91c6 | ||
|
|
907bf57460 | ||
|
|
49e1d8e8ec | ||
|
|
1cd1684936 | ||
|
|
b3cb618707 | ||
|
|
96ec6b812c | ||
|
|
ec01ab4f42 | ||
|
|
f51d0b6716 | ||
|
|
e654fa0b4c | ||
|
|
ea01804567 | ||
|
|
93589d3eed | ||
|
|
a7497aa590 | ||
|
|
74eb579474 | ||
|
|
b2d844c013 | ||
|
|
dfb91a0e39 | ||
|
|
07cfa1abb8 | ||
|
|
29c63288bf | ||
|
|
47f9b6cfc3 | ||
|
|
f04225a33a | ||
|
|
a3b89f7da6 | ||
|
|
8f1dbd3576 | ||
|
|
d92f4d9739 | ||
|
|
4c9b4ed24f | ||
|
|
79c653152c | ||
|
|
1a7d3ce00f | ||
|
|
77fb6d54ea | ||
|
|
f14e086c66 | ||
|
|
0506c2454f | ||
|
|
adf443902c | ||
|
|
6c3239ea1f | ||
|
|
c2b5ada462 | ||
|
|
1f14b76caa | ||
|
|
026abd72f6 | ||
|
|
18544f90c2 | ||
|
|
0d7379366e | ||
|
|
2c7ce4590a | ||
|
|
64f6a64f77 | ||
|
|
8cec3f4b58 | ||
|
|
4c14cb74c1 | ||
|
|
4729e1f85b | ||
|
|
297eb6b2c8 | ||
|
|
65c83837a3 | ||
|
|
bd0aa664b8 | ||
|
|
b46e4c918a | ||
|
|
1b4519f578 | ||
|
|
f00f03253b | ||
|
|
65bfebb218 | ||
|
|
96f328475d | ||
|
|
71cbf8894d | ||
|
|
1bcb07bcad | ||
|
|
6b5adbed02 | ||
|
|
47b08f0e52 | ||
|
|
c8b5b1efa5 | ||
|
|
8521cf4e0c | ||
|
|
a63de8066e | ||
|
|
35d9b48117 | ||
|
|
0f46b283b7 | ||
|
|
c1580c765b | ||
|
|
1fc0d64925 | ||
|
|
45be999245 | ||
|
|
03a3d29f1a | ||
|
|
b1e434ef6b | ||
|
|
1edb403c9a | ||
|
|
d2f78714a6 | ||
|
|
fb2ee56346 | ||
|
|
950c6b9046 | ||
|
|
acd85eb097 | ||
|
|
ef06f21d2a | ||
|
|
24af938058 | ||
|
|
2354a96624 | ||
|
|
4a2c360de1 | ||
|
|
89fc66df64 | ||
|
|
d60ff00eec | ||
|
|
756b4ddcc2 | ||
|
|
41b917abfb | ||
|
|
5ab601274c | ||
|
|
1b0ea73318 | ||
|
|
32269d0483 | ||
|
|
021e3aa346 | ||
|
|
465a09f129 | ||
|
|
adc44622eb | ||
|
|
0711149e41 | ||
|
|
69ad41bb58 | ||
|
|
22744ee39c | ||
|
|
6a3643384c | ||
|
|
2649309e57 | ||
|
|
6b2873ab28 | ||
|
|
643d70e6f0 | ||
|
|
17fcf0cd61 | ||
|
|
922aaf31d8 | ||
|
|
8c94da81f1 | ||
|
|
a4dbb31b8c | ||
|
|
5ea20e1268 | ||
|
|
bd349a677d | ||
|
|
411cab1d45 | ||
|
|
18b03550cc | ||
|
|
6ae42b1007 | ||
|
|
37ce80b085 | ||
|
|
c121a936ef | ||
|
|
a1edb667b9 | ||
|
|
4ef6045ee5 | ||
|
|
6783962cd8 | ||
|
|
921cfdfc4a | ||
|
|
c5179ac62f | ||
|
|
0a50467db0 | ||
|
|
7f6cde15d4 | ||
|
|
1e4d663c11 |
18
.babelrc
Normal file
18
.babelrc
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"plugins": [
|
||||
"@babel/plugin-syntax-dynamic-import"
|
||||
],
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"browsers": [
|
||||
"last 2 versions",
|
||||
"ie >= 11"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
95
.drone.yml
95
.drone.yml
@@ -16,20 +16,11 @@ steps:
|
||||
- ./occ app:check-code $APP_NAME -c strong-comparison
|
||||
- ./occ app:check-code $APP_NAME -c deprecation
|
||||
- cd apps/$APP_NAME/
|
||||
- name: syntax-php7.0
|
||||
image: nextcloudci/php7.0:php7.0-17
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable15
|
||||
DB: sqlite
|
||||
commands:
|
||||
- composer install
|
||||
- ./vendor/bin/parallel-lint --exclude ./vendor/ --exclude ./lib/Collaboration/ .
|
||||
- name: syntax-php7.1
|
||||
image: nextcloudci/php7.1:php7.1-15
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable15
|
||||
CORE_BRANCH: master
|
||||
DB: sqlite
|
||||
commands:
|
||||
- composer install
|
||||
@@ -38,7 +29,7 @@ steps:
|
||||
image: nextcloudci/php7.2:php7.2-9
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable15
|
||||
CORE_BRANCH: master
|
||||
DB: sqlite
|
||||
commands:
|
||||
- composer install
|
||||
@@ -47,7 +38,7 @@ steps:
|
||||
image: nextcloudci/php7.3:php7.3-2
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable15
|
||||
CORE_BRANCH: master
|
||||
DB: sqlite
|
||||
commands:
|
||||
- composer install
|
||||
@@ -61,41 +52,13 @@ trigger:
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: unit-php7.0
|
||||
steps:
|
||||
- name: php7.0
|
||||
image: nextcloudci/php7.0:php7.0-17
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable15
|
||||
DB: sqlite
|
||||
commands:
|
||||
# Pre-setup steps
|
||||
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
|
||||
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
|
||||
- cd ../server/
|
||||
- php occ app:enable deck
|
||||
- cd apps/$APP_NAME
|
||||
# Run phpunit tests
|
||||
- composer install
|
||||
- phpunit -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
|
||||
- phpunit -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- stable*
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: unit-php7.1
|
||||
steps:
|
||||
- name: php7.1
|
||||
image: nextcloudci/php7.1:php7.1-15
|
||||
image: nextcloudci/php7.1:php7.1-16
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable15
|
||||
CORE_BRANCH: master
|
||||
DB: sqlite
|
||||
commands:
|
||||
# Pre-setup steps
|
||||
@@ -122,7 +85,7 @@ steps:
|
||||
image: nextcloudci/php7.2:php7.2-9
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable15
|
||||
CORE_BRANCH: master
|
||||
DB: sqlite
|
||||
commands:
|
||||
# Pre-setup steps
|
||||
@@ -149,7 +112,7 @@ steps:
|
||||
image: nextcloudci/php7.3:php7.3-2
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable15
|
||||
CORE_BRANCH: master
|
||||
DB: sqlite
|
||||
commands:
|
||||
# Pre-setup steps
|
||||
@@ -170,39 +133,13 @@ trigger:
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: integration-stable16
|
||||
name: integration
|
||||
steps:
|
||||
- name: integration
|
||||
image: nextcloudci/php7.1:php7.1-16
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable16
|
||||
DB: sqlite
|
||||
commands:
|
||||
# Pre-setup steps
|
||||
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
|
||||
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
|
||||
- cd ../server/
|
||||
- php occ app:enable deck
|
||||
- cd apps/$APP_NAME
|
||||
- cd tests/integration
|
||||
- ./run.sh || true
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- stable*
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
---
|
||||
kind: pipeline
|
||||
name: integration-stable15
|
||||
steps:
|
||||
- name: integration
|
||||
image: nextcloudci/php7.1:php7.1-16
|
||||
environment:
|
||||
APP_NAME: deck
|
||||
CORE_BRANCH: stable15
|
||||
CORE_BRANCH: master
|
||||
DB: sqlite
|
||||
commands:
|
||||
# Pre-setup steps
|
||||
@@ -225,19 +162,23 @@ trigger:
|
||||
kind: pipeline
|
||||
name: frontend
|
||||
steps:
|
||||
- name: install
|
||||
image: node:11-alpine
|
||||
commands:
|
||||
- npm install
|
||||
- name: eslint
|
||||
image: nextcloudci/eslint:eslint-1
|
||||
image: node:11-alpine
|
||||
commands:
|
||||
- ./run-eslint.sh
|
||||
- npm run lint
|
||||
- name: jsbuild
|
||||
image: mhart/alpine-node:6.8.0
|
||||
image: node:11-alpine
|
||||
commands:
|
||||
- apk add --no-cache make
|
||||
- make build-js
|
||||
- npm run build
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- stable*
|
||||
- vue
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{js,vue}]
|
||||
indent_style = tab
|
||||
67
.eslintrc.js
Normal file
67
.eslintrc.js
Normal file
@@ -0,0 +1,67 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
node: true,
|
||||
jest: true
|
||||
},
|
||||
globals: {
|
||||
t: true,
|
||||
n: true,
|
||||
OC: true,
|
||||
OCA: true,
|
||||
Vue: true,
|
||||
VueRouter: true
|
||||
},
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
ecmaVersion: 6
|
||||
},
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:node/recommended',
|
||||
'plugin:vue/essential',
|
||||
'plugin:vue/recommended',
|
||||
'standard'
|
||||
],
|
||||
plugins: ['vue', 'node'],
|
||||
rules: {
|
||||
// space before function ()
|
||||
'space-before-function-paren': ['error', 'never'],
|
||||
// curly braces always space
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
// stay consistent with array brackets
|
||||
'array-bracket-newline': ['error', 'consistent'],
|
||||
// 1tbs brace style
|
||||
'brace-style': 'error',
|
||||
// tabs only
|
||||
indent: ['error', 'tab'],
|
||||
'no-tabs': 0,
|
||||
'vue/html-indent': ['error', 'tab'],
|
||||
// only debug console
|
||||
'no-console': ['warn', { allow: ['error', 'warn', 'debug'] }],
|
||||
// classes blocks
|
||||
'padded-blocks': ['error', { classes: 'always' }],
|
||||
// always have the operator in front
|
||||
'operator-linebreak': ['error', 'before'],
|
||||
// ternary on multiline
|
||||
'multiline-ternary': ['error', 'always-multiline'],
|
||||
// es6 import/export and require
|
||||
'node/no-unpublished-require': ['off'],
|
||||
'node/no-unsupported-features/es-syntax': ['off'],
|
||||
// space before self-closing elements
|
||||
'vue/html-closing-bracket-spacing': 'error',
|
||||
// code spacing with attributes
|
||||
'vue/max-attributes-per-line': [
|
||||
'error',
|
||||
{
|
||||
singleline: 3,
|
||||
multiline: {
|
||||
max: 3,
|
||||
allowFirstLine: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
root: true
|
||||
|
||||
extends:
|
||||
- eslint:recommended
|
||||
|
||||
env:
|
||||
browser: true
|
||||
amd: true
|
||||
es6: true
|
||||
|
||||
globals:
|
||||
global: false
|
||||
app: false
|
||||
angular: false
|
||||
$: false
|
||||
escapeHTML: false
|
||||
OC: false
|
||||
OCA: false
|
||||
t: false
|
||||
oc_current_user: false
|
||||
oc_requesttoken: false
|
||||
Clipboard: false
|
||||
oc_defaults: false
|
||||
|
||||
parserOptions:
|
||||
ecmaVersion: 6
|
||||
sourceType: "module"
|
||||
|
||||
rules:
|
||||
curly: error
|
||||
eqeqeq: ["error", "smart"]
|
||||
guard-for-in: error
|
||||
no-console: off
|
||||
no-fallthrough: error
|
||||
no-mixed-spaces-and-tabs: error
|
||||
no-unused-vars: warn
|
||||
no-useless-escape: warn
|
||||
no-use-before-define: error
|
||||
semi: ["error", "always"]
|
||||
indent:
|
||||
- error
|
||||
- tab
|
||||
- SwitchCase: 1
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,7 +1,5 @@
|
||||
js/node_modules/*
|
||||
js/vendor/
|
||||
js/public/
|
||||
js/build/
|
||||
node_modules/*
|
||||
js/
|
||||
build/
|
||||
css/style.css
|
||||
css/vendor.css
|
||||
|
||||
@@ -2,18 +2,17 @@ language: php
|
||||
services:
|
||||
- mysql
|
||||
php:
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
env:
|
||||
- CORE_BRANCH=stable15 DB=mysql
|
||||
- CORE_BRANCH=master DB=mysql
|
||||
|
||||
before_install:
|
||||
- wget https://phar.phpunit.de/phpunit-5.7.phar
|
||||
- chmod +x phpunit-5.7.phar
|
||||
- wget https://phar.phpunit.de/phpunit-6.5.phar
|
||||
- chmod +x phpunit-6.5.phar
|
||||
- mkdir bin
|
||||
- mv phpunit-5.7.phar bin/phpunit
|
||||
- mv phpunit-6.5.phar bin/phpunit
|
||||
- export PATH="$PWD/bin:$PATH"
|
||||
- phpunit --version
|
||||
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
|
||||
|
||||
38
CHANGELOG.md
38
CHANGELOG.md
@@ -1,6 +1,44 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## 0.7.0 - 2019-08-20
|
||||
|
||||
## Added
|
||||
- Make deck compatible to Nextcloud 17
|
||||
- Allow to set the description when creating cards though the REST API
|
||||
|
||||
## 0.6.6 - 2019-08-01
|
||||
|
||||
### Fixed
|
||||
- Bump security related dependencies
|
||||
|
||||
## 0.6.5 - 2019-07-28
|
||||
|
||||
### Fixed
|
||||
- Fix attachment upload/delete failures
|
||||
- Bump dependencies
|
||||
|
||||
## 0.6.4 - 2019-06-30
|
||||
|
||||
### Fixed
|
||||
- Restore stable15 compatibility
|
||||
|
||||
## 0.6.3 - 2019-06-30
|
||||
|
||||
### Fixed
|
||||
- Fix issues with comments and activity stream
|
||||
- Fix setting archived state through API
|
||||
- Fix type of acl in API responses
|
||||
- Fix type mismatch with fulltext search
|
||||
|
||||
## 0.6.2 - 2019-05-15
|
||||
|
||||
### Fixed
|
||||
- Fix group limit for nonexisting groups
|
||||
- Only map circle ACLs if the app is enabled
|
||||
- Fix updating sharing permissions
|
||||
- Add app version to capabilities
|
||||
|
||||
## 0.6.1 - 2019-04-27
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
- 🚀 Get your project organized
|
||||
|
||||
</description>
|
||||
<version>0.6.1</version>
|
||||
<version>0.7.0</version>
|
||||
<licence>agpl</licence>
|
||||
<author>Julius Härtl</author>
|
||||
<namespace>Deck</namespace>
|
||||
@@ -36,7 +36,7 @@
|
||||
<database min-version="9.4">pgsql</database>
|
||||
<database>sqlite</database>
|
||||
<database min-version="5.5">mysql</database>
|
||||
<nextcloud min-version="15" max-version="16" />
|
||||
<nextcloud min-version="17" max-version="18" />
|
||||
</dependencies>
|
||||
<background-jobs>
|
||||
<job>OCA\Deck\Cron\DeleteCron</job>
|
||||
@@ -54,6 +54,7 @@
|
||||
<activity>
|
||||
<settings>
|
||||
<setting>OCA\Deck\Activity\Setting</setting>
|
||||
<setting>OCA\Deck\Activity\SettingComment</setting>
|
||||
<setting>OCA\Deck\Activity\DescriptionSetting</setting>
|
||||
</settings>
|
||||
<filters>
|
||||
|
||||
@@ -38,8 +38,9 @@ return [
|
||||
['name' => 'board#deleteUndo', 'url' => '/boards/{boardId}/deleteUndo', 'verb' => 'POST'],
|
||||
['name' => 'board#getUserPermissions', 'url' => '/boards/{boardId}/permissions', 'verb' => 'GET'],
|
||||
['name' => 'board#addAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'POST'],
|
||||
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'PUT'],
|
||||
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'PUT'],
|
||||
['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
|
||||
['name' => 'board#clone', 'url' => '/boards/{boardId}/clone', 'verb' => 'POST'],
|
||||
|
||||
// stacks
|
||||
['name' => 'stack#index', 'url' => '/stacks/{boardId}', 'verb' => 'GET'],
|
||||
@@ -88,8 +89,8 @@ return [
|
||||
['name' => 'board_api#update', 'url' => '/api/v1.0/boards/{boardId}', 'verb' => 'PUT'],
|
||||
['name' => 'board_api#undo_delete', 'url' => '/api/v1.0/boards/{boardId}/undo_delete', 'verb' => 'POST'],
|
||||
['name' => 'board_api#addAcl', 'url' => '/api/v1.0/boards/{boardId}/acl', 'verb' => 'POST'],
|
||||
['name' => 'board_api#deleteAcl', 'url' => '/api/v1.0/boards/{boardId}/acl', 'verb' => 'DELETE'],
|
||||
['name' => 'board_api#updateAcl', 'url' => '/api/v1.0/boards/{boardId}/acl', 'verb' => 'PUT'],
|
||||
['name' => 'board_api#deleteAcl', 'url' => '/api/v1.0/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
|
||||
['name' => 'board_api#updateAcl', 'url' => '/api/v1.0/boards/{boardId}/acl/{aclId}', 'verb' => 'PUT'],
|
||||
|
||||
|
||||
['name' => 'stack_api#index', 'url' => '/api/v1.0/boards/{boardId}/stacks', 'verb' => 'GET'],
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"roave/security-advisories": "dev-master",
|
||||
"christophwurst/nextcloud": "^14.0",
|
||||
"christophwurst/nextcloud": "^16.0",
|
||||
"jakub-onderka/php-parallel-lint": "^1.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
|
||||
*
|
||||
* @author Julius Härtl <jus@bitgrid.net>
|
||||
* @author Artem Anufrij <artem.anufrij@live.de>
|
||||
* @author Marin Treselj <marin@pixelipo.com>
|
||||
* @author Oskar Kurz <oskar.kurz@gmail.com>
|
||||
* @author Ryan Fletcher <ryan.fletcher@codepassion.ca>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
@@ -20,28 +24,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
// OwnCloud Click Handling
|
||||
// https://doc.owncloud.org/server/8.0/developer_manual/app/css.html
|
||||
app.directive('appNavigationEntryUtils', function () {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'C',
|
||||
link: function (scope, elm) {
|
||||
// colors
|
||||
$color-warning-light: nc-lighten($color-warning, 15%);
|
||||
$color-lightgrey: nc-darken($color-main-background, 4%);
|
||||
$color-grey: nc-darken($color-main-background, 7%);
|
||||
$color-darkgrey: nc-darken($color-main-background, 32%);
|
||||
|
||||
var menu = elm.siblings('.app-navigation-entry-menu');
|
||||
var button = $(elm)
|
||||
.find('.app-navigation-entry-utils-menu-button button');
|
||||
// margins/paddings
|
||||
$board-item-margin: 10px 10px 20px 10px;
|
||||
$board-last-item-margin: 10px;
|
||||
|
||||
button.click(function () {
|
||||
menu.toggleClass('open');
|
||||
});
|
||||
scope.$on('documentClicked', function (scope, event) {
|
||||
if (event.target !== button[0]) {
|
||||
menu.removeClass('open');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
$compact-board-item-margin: 5px 10px 10px 10px;
|
||||
$compact-board-last-item-margin: 5px 10px 10px;
|
||||
|
||||
@import 'icons';
|
||||
@@ -5,10 +5,6 @@
|
||||
background-image: url('../img/deck-dark.svg');
|
||||
}
|
||||
|
||||
.icon-group {
|
||||
background-image: url('../../../settings/img/users.svg');
|
||||
}
|
||||
|
||||
.icon-help {
|
||||
background-image: url('../../../settings/img/help.svg');
|
||||
}
|
||||
@@ -17,6 +13,10 @@
|
||||
background-image: url('../img/add-white.svg');
|
||||
}
|
||||
|
||||
.icon-attach {
|
||||
background-image: url('../img/attach.svg');
|
||||
}
|
||||
|
||||
.icon-archive {
|
||||
background-image: url('../img/archive.svg');
|
||||
}
|
||||
@@ -53,11 +53,14 @@
|
||||
background-image: url('../img/toggle-view-collapse.svg');
|
||||
}
|
||||
|
||||
|
||||
@if mixin-exists('icon-black-white') {
|
||||
@include icon-black-white('deck', 'deck', 1);
|
||||
@include icon-black-white('archive', 'deck', 1);
|
||||
@include icon-black-white('circles', 'deck', 1);
|
||||
|
||||
@include icon-black-white('deck', 'deck', 1);
|
||||
@include icon-black-white('archive', 'deck', 1);
|
||||
@include icon-black-white('circles', 'deck', 1);
|
||||
@include icon-black-white('clone', 'deck', 1);
|
||||
@include icon-black-white('attach', 'deck', 1);
|
||||
|
||||
.icon-toggle-compact-collapsed {
|
||||
@include icon-color('toggle-view-expand', 'deck', $color-black);
|
||||
}
|
||||
@@ -77,4 +80,7 @@
|
||||
opacity: 1;
|
||||
background-size: 20px;
|
||||
background-position: center center;
|
||||
}
|
||||
}
|
||||
.icon-colorpicker {
|
||||
background-image: url('../img/color_picker.svg');
|
||||
}
|
||||
|
||||
@@ -72,10 +72,6 @@ input.input-inline {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#app img {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
#searchbox {
|
||||
display: flex !important;
|
||||
}
|
||||
@@ -543,11 +539,6 @@ input.input-inline {
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 22px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
|
||||
50
docs/API.md
50
docs/API.md
@@ -354,7 +354,7 @@ Returns an array of board items
|
||||
|
||||
## Stacks
|
||||
|
||||
### GET /board/{boardId}/stacks - Get stacks
|
||||
### GET /boards/{boardId}/stacks - Get stacks
|
||||
|
||||
#### Headers
|
||||
|
||||
@@ -385,7 +385,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### GET /board/{boardId}/stacks/archived - Get list of archived stacks
|
||||
### GET /boards/{boardId}/stacks/archived - Get list of archived stacks
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -411,7 +411,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### GET /board/{boardId}/stacks/{stackId} - Get stack details
|
||||
### GET /boards/{boardId}/stacks/{stackId} - Get stack details
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -424,7 +424,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### POST /board/{boardId}/stacks - Create a new stack
|
||||
### POST /boards/{boardId}/stacks - Create a new stack
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -436,7 +436,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/stacks/{stackId} - Update stack details
|
||||
### PUT /boards/{boardId}/stacks/{stackId} - Update stack details
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -456,7 +456,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### DELETE /board/{boardId}/stacks/{stackId} - Delete a stack
|
||||
### DELETE /boards/{boardId}/stacks/{stackId} - Delete a stack
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -471,7 +471,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
## Cards
|
||||
|
||||
### GET /board/{boardId}/stacks/{stackId}/cards/{cardId} - Get card details
|
||||
### GET /boards/{boardId}/stacks/{stackId}/cards/{cardId} - Get card details
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -485,7 +485,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### POST /board/{boardId}/stacks/{stackId}/cards - Create a new card
|
||||
### POST /boards/{boardId}/stacks/{stackId}/cards - Create a new card
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -529,7 +529,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/stacks/{stackId}/cards/{cardId} - Update card details
|
||||
### PUT /boards/{boardId}/stacks/{stackId}/cards/{cardId} - Update card details
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -564,7 +564,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### DELETE /board/{boardId}/stacks/{stackId}/cards/{cardId} - Delete a card
|
||||
### DELETE /boards/{boardId}/stacks/{stackId}/cards/{cardId} - Delete a card
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -578,7 +578,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/stacks/{stackId}/cards/{cardId}/assignLabel - Assign a label to a card
|
||||
### PUT /boards/{boardId}/stacks/{stackId}/cards/{cardId}/assignLabel - Assign a label to a card
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -597,7 +597,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/stacks/{stackId}/cards/{cardId}/removeLabel - Remove a label to a card
|
||||
### PUT /boards/{boardId}/stacks/{stackId}/cards/{cardId}/removeLabel - Remove a label to a card
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -617,7 +617,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/stacks/{stackId}/cards/{cardId}/assignUser - Assign a user to a card
|
||||
### PUT /boards/{boardId}/stacks/{stackId}/cards/{cardId}/assignUser - Assign a user to a card
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -637,7 +637,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/stacks/{stackId}/cards/{cardId}/unassignUser - Assign a user to a card
|
||||
### PUT /boards/{boardId}/stacks/{stackId}/cards/{cardId}/unassignUser - Assign a user to a card
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -657,7 +657,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/stacks/{stackId}/cards/{cardId}/reorder - Change the sorting order of a card
|
||||
### PUT /boards/{boardId}/stacks/{stackId}/cards/{cardId}/reorder - Change the sorting order of a card
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -681,7 +681,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
## Labels
|
||||
|
||||
### GET /board/{boardId}/labels/{labelId} - Get label details
|
||||
### GET /boards/{boardId}/labels/{labelId} - Get label details
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -704,7 +704,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
}
|
||||
```
|
||||
|
||||
### POST /board/{boardId}/labels - Create a new label
|
||||
### POST /boards/{boardId}/labels - Create a new label
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -725,7 +725,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/labels/{labelId} - Update label details
|
||||
### PUT /boards/{boardId}/labels/{labelId} - Update label details
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -748,7 +748,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### DELETE /board/{boardId}/labels/{labelId} - Delete a label
|
||||
### DELETE /boards/{boardId}/labels/{labelId} - Delete a label
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -763,7 +763,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
## Attachments
|
||||
|
||||
### GET /board/{boardId}/stacks/{stackId}/cards/{cardId}/attachments - Get a list of attachments
|
||||
### GET /boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments - Get a list of attachments
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -803,7 +803,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
```
|
||||
|
||||
### GET /board/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId} - Get the attachment file
|
||||
### GET /boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId} - Get the attachment file
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -818,7 +818,7 @@ The board list endpoint supports setting an `If-Modified-Since` header to limit
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### POST /board/{boardId}/stacks/{stackId}/cards/{cardId}/attachments - Upload an attachment
|
||||
### POST /boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments - Upload an attachment
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -841,7 +841,7 @@ For now only `deck_file` is supported as an attachment type.
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId} - Update an attachment
|
||||
### PUT /boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId} - Update an attachment
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -865,7 +865,7 @@ For now only `deck_file` is supported as an attachment type.
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### DELETE /board/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId} - Delete an attachment
|
||||
### DELETE /boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId} - Delete an attachment
|
||||
|
||||
#### Request parameters
|
||||
|
||||
@@ -880,7 +880,7 @@ For now only `deck_file` is supported as an attachment type.
|
||||
|
||||
##### 200 Success
|
||||
|
||||
### PUT /board/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId}/restore - Resore a deleted attachment
|
||||
### PUT /boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId}/restore - Resore a deleted attachment
|
||||
|
||||
#### Request parameters
|
||||
|
||||
|
||||
1
img/attach.svg
Normal file
1
img/attach.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
|
||||
|
After Width: | Height: | Size: 390 B |
1
img/clone.svg
Normal file
1
img/clone.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M11.8 13.8H2.2V4.2h9.6m1.2 0c0-.67-.53-1.2-1.2-1.2H2.2C1.53 3 1 3.53 1 4.2v9.6c0 .67.53 1.2 1.2 1.2h9.6c.67 0 1.2-.53 1.2-1.2"/><path d="m4.2 1c-0.67 0-1.2 0.54-1.2 1.2h10.8v10.8c0.67 0 1.2-0.53 1.2-1.2v-9.6c0-0.67-0.53-1.2-1.2-1.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 327 B |
@@ -1,12 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
browsers: ['last 2 versions', 'ie >= 11']
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
49
js/.jshintrc
49
js/.jshintrc
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"esversion": 6,
|
||||
|
||||
"globals": {
|
||||
"jasmine" : false,
|
||||
"spyOn" : false,
|
||||
"it" : false,
|
||||
"describe" : false,
|
||||
"expect" : false,
|
||||
"beforeEach" : false,
|
||||
"waits" : false,
|
||||
"waitsFor" : false,
|
||||
"runs" : false,
|
||||
"require" : false,
|
||||
"module": true
|
||||
},
|
||||
|
||||
"asi" : true,
|
||||
"boss" : true,
|
||||
"browser" : true,
|
||||
"curly" : true,
|
||||
"debug" : true,
|
||||
"devel" : true,
|
||||
"eqeqeq" : true,
|
||||
"eqnull" : false,
|
||||
"evil" : false,
|
||||
"forin" : true,
|
||||
"immed" : true,
|
||||
"indent" : 4,
|
||||
"jquery" : true,
|
||||
"latedef" : true,
|
||||
"laxbreak" : false,
|
||||
"newcap" : true,
|
||||
"noarg" : true,
|
||||
"node" : false,
|
||||
"noempty" : false,
|
||||
"nomen" : false,
|
||||
"nonew" : true,
|
||||
"onevar" : true,
|
||||
"plusplus" : false,
|
||||
"quotmark" : "single",
|
||||
"regexp" : false,
|
||||
"sub" : true,
|
||||
"trailing" : true,
|
||||
"undef" : true,
|
||||
"unused" : true,
|
||||
"white" : false,
|
||||
"scripturl" : true
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global angular */
|
||||
|
||||
|
||||
angular.module('markdown', [])
|
||||
.provider('markdown', [function () {
|
||||
var opts = {};
|
||||
return {
|
||||
config: function (newOpts) {
|
||||
opts = newOpts;
|
||||
},
|
||||
$get: function () {
|
||||
return new window.showdown.Converter(opts);
|
||||
}
|
||||
};
|
||||
}])
|
||||
.filter('markdown', ['markdown', function (markdown) {
|
||||
return function (text) {
|
||||
return markdown.makeHtml(text || '');
|
||||
};
|
||||
}]);
|
||||
|
||||
import uirouter from '@uirouter/angularjs';
|
||||
import ngsanitize from 'angular-sanitize';
|
||||
import angularuiselect from 'ui-select';
|
||||
import ngsortable from 'ng-sortable';
|
||||
import md from 'angular-markdown-it';
|
||||
import nganimate from 'angular-animate';
|
||||
import 'angular-file-upload';
|
||||
import ngInfiniteScroll from 'ng-infinite-scroll';
|
||||
import '../legacy/jquery.atwho.min';
|
||||
import '../legacy/jquery.caret.min';
|
||||
|
||||
var app = angular.module('Deck', [
|
||||
ngsanitize,
|
||||
uirouter,
|
||||
angularuiselect,
|
||||
ngsortable, md, nganimate,
|
||||
'angularFileUpload',
|
||||
ngInfiniteScroll
|
||||
]);
|
||||
|
||||
export default app;
|
||||
117
js/app/Config.js
117
js/app/Config.js
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global app oc_requesttoken markdownitLinkTarget */
|
||||
|
||||
import app from './App.js';
|
||||
import md from 'angular-markdown-it';
|
||||
import markdownitLinkTarget from 'markdown-it-link-target';
|
||||
import markdownitCheckbox from 'legacy/markdown-it-checkbox.js';
|
||||
|
||||
app.config(function ($provide, $interpolateProvider, $httpProvider, $urlRouterProvider, $stateProvider, $compileProvider, markdownItConverterProvider) {
|
||||
'use strict';
|
||||
$httpProvider.defaults.headers.common.requesttoken = oc_requesttoken;
|
||||
|
||||
|
||||
$compileProvider.debugInfoEnabled(true);
|
||||
// This should fix adding "unsafe:" prefix to ui-select href links containing javascript
|
||||
// inline JS is blocked by CSP anyway and filtered out by our markdown renderer as well
|
||||
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|javascript):/);
|
||||
|
||||
markdownItConverterProvider.config({
|
||||
breaks: true,
|
||||
linkify: true,
|
||||
xhtmlOut: true
|
||||
});
|
||||
markdownItConverterProvider.use(markdownitLinkTarget).use(markdownitCheckbox);
|
||||
|
||||
$urlRouterProvider.otherwise('/');
|
||||
|
||||
$stateProvider
|
||||
.state('list', {
|
||||
url: '/:filter',
|
||||
templateUrl: '/boardlist.mainView.html',
|
||||
controller: 'ListController',
|
||||
reloadOnSearch: false,
|
||||
params: {
|
||||
filter: {value: '', dynamic: true}
|
||||
}
|
||||
})
|
||||
.state('board', {
|
||||
url: '/board/:boardId/:filter',
|
||||
templateUrl: '/board.html',
|
||||
controller: 'BoardController',
|
||||
params: {
|
||||
filter: {value: '', dynamic: true}
|
||||
}
|
||||
})
|
||||
.state('board.detail', {
|
||||
url: '/detail/',
|
||||
reloadOnSearch: false,
|
||||
params: {
|
||||
tab: {value: 0, dynamic: true},
|
||||
},
|
||||
views: {
|
||||
'sidebarView@': {
|
||||
templateUrl: '/board.sidebarView.html',
|
||||
controller: 'BoardController'
|
||||
}
|
||||
}
|
||||
})
|
||||
.state('board.card', {
|
||||
url: '/card/:cardId',
|
||||
params: {
|
||||
tab: {value: 0, dynamic: true},
|
||||
},
|
||||
views: {
|
||||
'sidebarView@': {
|
||||
templateUrl: '/card.sidebarView.html',
|
||||
controller: 'CardController'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$provide.decorator('nvFileOverDirective', function ($delegate) {
|
||||
var directive = $delegate[0],
|
||||
link = directive.link;
|
||||
|
||||
directive.compile = function () {
|
||||
return function (scope, element, attrs) {
|
||||
var overClass = attrs.overClass || 'nv-file-over';
|
||||
link.apply(this, arguments);
|
||||
let counter = 0;
|
||||
element.on('dragenter', function (event) {
|
||||
counter++;
|
||||
});
|
||||
element.on('dragleave', function (event) {
|
||||
counter--;
|
||||
if (counter <= 0) {
|
||||
$('.' + overClass).removeClass(overClass);
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
return $delegate;
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from './App.js';
|
||||
|
||||
/* global Snap */
|
||||
app.run(function ($document, $rootScope, $transitions, BoardService) {
|
||||
'use strict';
|
||||
|
||||
$document.click(function (event) {
|
||||
$rootScope.$broadcast('documentClicked', event);
|
||||
});
|
||||
$transitions.onEnter({from: 'list'}, function ($state, $transition$) {
|
||||
BoardService.unsetCurrrent();
|
||||
});
|
||||
$transitions.onEnter({to: 'list'}, function ($state, $transition$) {
|
||||
BoardService.unsetCurrrent();
|
||||
document.title = "Deck - " + oc_defaults.name;
|
||||
});
|
||||
$transitions.onEnter({to: 'board.card'}, function ($state, $transition$) {
|
||||
$rootScope.sidebar.show = true;
|
||||
});
|
||||
$transitions.onEnter({to: 'board.detail'}, function ($state, $transition$) {
|
||||
$rootScope.sidebar.show = true;
|
||||
});
|
||||
$transitions.onEnter({to: 'board'}, function ($state) {
|
||||
$rootScope.sidebar.show = false;
|
||||
});
|
||||
$transitions.onExit({from: 'board.card'}, function ($state) {
|
||||
$rootScope.sidebar.show = false;
|
||||
});
|
||||
$transitions.onExit({from: 'board.detail'}, function ($state) {
|
||||
$rootScope.sidebar.show = false;
|
||||
});
|
||||
|
||||
$('link[rel="shortcut icon"]').attr(
|
||||
'href',
|
||||
OC.filePath('deck', 'img', 'app-512.png')
|
||||
);
|
||||
|
||||
// Select all elements with data-toggle="tooltips" in the document
|
||||
$('body').tooltip({
|
||||
selector: '[data-toggle="tooltip"]'
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global OC OCA OCP t escapeHTML Handlebars moment */
|
||||
|
||||
import CommentCollection from '../legacy/commentcollection';
|
||||
import CommentModel from '../legacy/commentmodel';
|
||||
|
||||
class ActivityController {
|
||||
constructor ($scope, CardService, ActivityService, BoardService) {
|
||||
'ngInject';
|
||||
this.cardservice = CardService;
|
||||
this.boardservice = BoardService;
|
||||
this.activityservice = ActivityService;
|
||||
this.$scope = $scope;
|
||||
this.type = '';
|
||||
this.loading = false;
|
||||
this.status = {
|
||||
commentCreateLoading: false
|
||||
};
|
||||
this.$scope.newComment = '';
|
||||
this.$scope.newCommentString = 'New comment…';
|
||||
|
||||
this.currentUser = OC.getCurrentUser();
|
||||
|
||||
const self = this;
|
||||
this.$scope.$watch(function () {
|
||||
return self.element.id;
|
||||
}, function (params) {
|
||||
if (self.type === 'deck_card') {
|
||||
self.activityservice.loadComments(self.element.id);
|
||||
}
|
||||
|
||||
if (self.getData(self.element.id).length === 0) {
|
||||
self.loading = true;
|
||||
self.fetchUntilResults();
|
||||
}
|
||||
self.activityservice.fetchNewerActivities(self.type, self.element.id).then(function () {});
|
||||
if (self.type === 'deck_card') {
|
||||
self.cardservice.getCurrent().commentsUnread = 0;
|
||||
}
|
||||
}, true);
|
||||
|
||||
let $target = $('.newCommentForm .message');
|
||||
this.applyAtWho($target);
|
||||
|
||||
this.activityservice.subscribe(this.$scope, function() {
|
||||
self.$scope.$apply();
|
||||
});
|
||||
|
||||
if (typeof OCA.Activity.Templates !== 'undefined') {
|
||||
OCA.Activity.Templates.userLocal = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
|
||||
var helper;
|
||||
// Compiled handlesbars template
|
||||
// '<span class="avatar-name-wrapper"><avatar ng-attr-contactsmenu ng-attr-tooltip ng-attr-user="{{ id }}" ng-attr-displayname="{{name}}" ng-attr-size="16"></avatar> {{ name }}</span>';
|
||||
return "<span class=\"avatar-name-wrapper\"><avatar ng-attr-contactsmenu ng-attr-tooltip ng-attr-user=\""
|
||||
+ container.escapeExpression(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : {},{"name":"id","hash":{},"data":data}) : helper)))
|
||||
+ "\" ng-attr-displayname=\""
|
||||
+ container.escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : {},{"name":"name","hash":{},"data":data}) : helper)))
|
||||
+ "\" ng-attr-size=\"16\"></avatar> "
|
||||
+ container.escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : {},{"name":"name","hash":{},"data":data}) : helper)))
|
||||
+ "</span>";
|
||||
},"useData":true});
|
||||
} else {
|
||||
OCA.Activity.RichObjectStringParser._userLocalTemplate = '<span class="avatar-name-wrapper"><avatar ng-attr-contactsmenu ng-attr-tooltip ng-attr-user="{{ id }}" ng-attr-displayname="{{name}}" ng-attr-size="16"></avatar> {{ name }}</span>';
|
||||
}
|
||||
}
|
||||
|
||||
applyAtWho($target) {
|
||||
const self = this;
|
||||
if (!$target) {
|
||||
return;
|
||||
}
|
||||
$target.atwho({
|
||||
at: '@',
|
||||
callbacks: {
|
||||
remoteFilter: function(query, callback) {
|
||||
let uids = self.boardservice.getUsers();
|
||||
uids = uids.filter((x) => x.uid.toLowerCase().includes(query.toLowerCase()) || x.displayname.toLowerCase().includes(query.toLowerCase()));
|
||||
callback(uids);
|
||||
},
|
||||
highlighter: function (li) {
|
||||
// misuse the highlighter callback to instead of
|
||||
// highlighting loads the avatars.
|
||||
var $li = $(li);
|
||||
$li.find('.avatar').avatar(undefined, 32);
|
||||
return $li;
|
||||
},
|
||||
sorter: function (q, items) { return items; }
|
||||
},
|
||||
displayTpl: function (item) {
|
||||
return '<li>' +
|
||||
'<span class="avatar-name-wrapper">' +
|
||||
'<span class="avatar" ' +
|
||||
'data-username="' + escapeHTML(item.uid) + '" ' + // for avatars
|
||||
'data-user="' + escapeHTML(item.uid) + '" ' + // for contactsmenu
|
||||
'data-user-display-name="' + escapeHTML(item.displayname) + '">' +
|
||||
'</span>' +
|
||||
'<strong>' + escapeHTML(item.displayname) + '</strong>' +
|
||||
'</span></li>';
|
||||
},
|
||||
insertTpl: function (item) {
|
||||
return '' +
|
||||
'<span class="avatar-name-wrapper">' +
|
||||
'<span class="avatar" ' +
|
||||
'data-username="' + escapeHTML(item.uid) + '" ' + // for avatars
|
||||
'data-user="' + escapeHTML(item.uid) + '" ' + // for contactsmenu
|
||||
'data-user-display-name="' + escapeHTML(item.displayname) + '">' +
|
||||
'</span>' +
|
||||
'<strong>' + escapeHTML(item.displayname) + '</strong>' +
|
||||
'</span>';
|
||||
},
|
||||
searchKey: 'displayname'
|
||||
});
|
||||
$target.on('inserted.atwho', function (je, $el) {
|
||||
$(je.target).find(
|
||||
'span[data-username="' + $el.find('[data-username]').data('username') + '"]'
|
||||
).avatar(undefined, 16);
|
||||
});
|
||||
$target.on('shown.atwho', function (je) {
|
||||
$target.find('.avatar').avatar(undefined, 16);
|
||||
});
|
||||
}
|
||||
|
||||
commentBodyToPlain(content) {
|
||||
let $comment = $('<div/>').html(content);
|
||||
$comment.find('.avatar-name-wrapper').each(function () {
|
||||
var $this = $(this);
|
||||
var $inserted = $this.parent();
|
||||
$inserted.html('@' + $this.find('.avatar').data('username'));
|
||||
});
|
||||
$comment.html(OCP.Comments.richToPlain($comment.html()));
|
||||
$comment.html($comment.html().replace(/<br\s*[\/]?>/gi, '\n'));
|
||||
return $comment.text();
|
||||
}
|
||||
|
||||
static _composeHTMLMention(uid, displayName) {
|
||||
var avatar = '' +
|
||||
'<span class="avatar" data-username="' + escapeHTML(uid) + '" data-user="' + escapeHTML(uid) + '" ng-attr-size="16" ' +
|
||||
'ng-attr-user="' + escapeHTML(uid) + '" ' +
|
||||
'ng-attr-displayname="' + escapeHTML(displayName) + '" ng-attr-contactsmenu="true">' +
|
||||
'</span>';
|
||||
|
||||
var isCurrentUser = (uid === OC.getCurrentUser().uid);
|
||||
|
||||
return '' +
|
||||
'<span class="atwho-inserted" contenteditable="false">' +
|
||||
'<span class="avatar-name-wrapper' + (isCurrentUser ? ' currentUser' : '') + '">' +
|
||||
avatar +
|
||||
'<strong>' + escapeHTML(displayName) + '</strong>' +
|
||||
'</span>' +
|
||||
'</span>';
|
||||
}
|
||||
|
||||
formatMessage(activity) {
|
||||
let message = activity.message;
|
||||
let mentions = activity.commentModel.get('mentions');
|
||||
const editMode = false;
|
||||
message = escapeHTML(message).replace(/\n/g, '<br/>');
|
||||
|
||||
for(var i in mentions) {
|
||||
if(!mentions.hasOwnProperty(i)) {
|
||||
return;
|
||||
}
|
||||
var mention = '@' + mentions[i].mentionId;
|
||||
// escape possible regex characters in the name
|
||||
mention = mention.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
|
||||
const displayName = ActivityController._composeHTMLMention(mentions[i].mentionId, mentions[i].mentionDisplayName);
|
||||
// replace every mention either at the start of the input or after a whitespace
|
||||
// followed by a non-word character.
|
||||
message = message.replace(new RegExp('(^|\\s)(' + mention + ')\\b', 'g'),
|
||||
function(match, p1) {
|
||||
// to get number of whitespaces (0 vs 1) right
|
||||
return p1+displayName;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
if(editMode !== true) {
|
||||
message = OCP.Comments.plainToRich(message);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
postComment() {
|
||||
const self = this;
|
||||
this.status.commentCreateLoading = true;
|
||||
|
||||
let content = this.commentBodyToPlain(self.$scope.newComment);
|
||||
if (content.length < 1) {
|
||||
self.status.commentCreateLoading = false;
|
||||
OC.Notification.showTemporary(t('deck', 'Please provide a content for your comment.'));
|
||||
return;
|
||||
}
|
||||
var model = this.activityservice.commentCollection.create({
|
||||
actorId: OC.getCurrentUser().uid,
|
||||
actorDisplayName: OC.getCurrentUser().displayName,
|
||||
actorType: 'users',
|
||||
verb: 'comment',
|
||||
message: content,
|
||||
creationDateTime: (new Date()).toUTCString()
|
||||
}, {
|
||||
at: 0,
|
||||
// wait for real creation before adding
|
||||
wait: true,
|
||||
success: function() {
|
||||
self.$scope.newComment = '';
|
||||
self.activityservice.fetchNewerActivities(self.type, self.element.id).then(function () {});
|
||||
self.status.commentCreateLoading = false;
|
||||
},
|
||||
error: function() {
|
||||
self.status.commentCreateLoading = false;
|
||||
OC.Notification.showTemporary(t('deck', 'Posting the comment failed.'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateComment(item) {
|
||||
item.commentEdit = this.formatMessage(item);
|
||||
let $target = $('.newCommentForm .message');
|
||||
this.applyAtWho($target);
|
||||
/** Workaround to trigger avatar rendering after the view has been updated */
|
||||
window.setTimeout(function () {
|
||||
$target.find('.avatar').avatar(undefined, 16);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
editComment(item) {
|
||||
const self = this;
|
||||
let content = this.commentBodyToPlain(item.commentEdit);
|
||||
if (content.length < 1) {
|
||||
OC.Notification.showTemporary(t('deck', 'Please provide a content for your comment.'));
|
||||
return;
|
||||
}
|
||||
/** We need to save the model and afterwards run a fetch to update the mentions
|
||||
* and call apply to propagate the changes to angular
|
||||
*/
|
||||
item.commentModel.on('sync', function() {
|
||||
item.commentModel.off('sync');
|
||||
item.commentModel.fetch({
|
||||
success: function() {
|
||||
self.$scope.$apply();
|
||||
}
|
||||
});
|
||||
});
|
||||
item.commentModel.save({
|
||||
message: content,
|
||||
});
|
||||
item.message = content;
|
||||
item.commentEdit = undefined;
|
||||
}
|
||||
|
||||
deleteComment(item) {
|
||||
item.commentModel.destroy();
|
||||
item.deleted = true;
|
||||
item.commentModel = undefined;
|
||||
item.message = t('deck', 'The comment has been deleted');
|
||||
}
|
||||
|
||||
getData(id) {
|
||||
return this.activityservice.getData(this.type, id);
|
||||
}
|
||||
|
||||
parseMessage(activity) {
|
||||
let subject = activity.subject_rich[0];
|
||||
let parameters = activity.subject_rich[1];
|
||||
if (parameters.after && parameters.after.id && parameters.after.id.startsWith('dt:')) {
|
||||
let dateTime = parameters.after.id.substr(3);
|
||||
parameters.after.name = moment(dateTime).format('L LTS');
|
||||
}
|
||||
return OCA.Activity.RichObjectStringParser.parseMessage(subject, parameters);
|
||||
}
|
||||
|
||||
fetchUntilResults () {
|
||||
const self = this;
|
||||
let dataLengthBefore = self.getData(self.element.id).length;
|
||||
let _executeFetch = function() {
|
||||
let promise = self.activityservice.fetchMoreActivities(self.type, self.element.id);
|
||||
promise.then(function (data) {
|
||||
let dataLengthAfter = self.getData(self.element.id).length;
|
||||
if (data !== null && (dataLengthAfter <= dataLengthBefore || dataLengthAfter < self.activityservice.RESULT_PER_PAGE)) {
|
||||
_executeFetch();
|
||||
} else {
|
||||
self.loading = false;
|
||||
}
|
||||
}, function () {
|
||||
self.loading = false;
|
||||
self.$scope.$apply();
|
||||
});
|
||||
|
||||
};
|
||||
_executeFetch();
|
||||
}
|
||||
|
||||
getComments() {
|
||||
return this.activityservice.comments;
|
||||
}
|
||||
|
||||
getActivityStream() {
|
||||
let activities = this.activityservice.getData(this.type, this.element.id);
|
||||
return activities;
|
||||
}
|
||||
|
||||
page() {
|
||||
if (!this.activityservice.since[this.type][this.element.id].finished) {
|
||||
this.loading = true;
|
||||
this.fetchUntilResults();
|
||||
} else {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
loadingNewer() {
|
||||
return this.activityservice.runningNewer;
|
||||
}
|
||||
|
||||
t(text) {
|
||||
return t('deck', text);
|
||||
}
|
||||
}
|
||||
|
||||
let activityComponent = {
|
||||
templateUrl: OC.linkTo('deck', 'templates/part.card.activity.html'),
|
||||
controller: ActivityController,
|
||||
bindings: {
|
||||
type: '@',
|
||||
element: '='
|
||||
}
|
||||
};
|
||||
export default activityComponent;
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* globals oc_current_user: false */
|
||||
app.controller('AppController', function ($scope, $location, $http, $log, $rootScope, $attrs) {
|
||||
$rootScope.sidebar = {
|
||||
show: false
|
||||
};
|
||||
$scope.sidebar = $rootScope.sidebar;
|
||||
$scope.user = oc_current_user;
|
||||
$rootScope.config = JSON.parse($attrs.config);
|
||||
|
||||
$rootScope.compactMode = localStorage.getItem('deck.compactMode') === 'true';
|
||||
$scope.appNavigationHide = localStorage.getItem('deck.appNavigationHide') === 'true';
|
||||
|
||||
$scope.toggleSidebar = function() {
|
||||
if ($(window).width() > 768) {
|
||||
$log.debug($scope.appNavigationHide);
|
||||
$scope.appNavigationHide = !$scope.appNavigationHide;
|
||||
localStorage.setItem('deck.appNavigationHide', JSON.stringify($scope.appNavigationHide));
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global OC */
|
||||
|
||||
class AttachmentListController {
|
||||
constructor ($scope, CardService, FileService) {
|
||||
'ngInject';
|
||||
this.cardservice = CardService;
|
||||
this.fileservice = FileService;
|
||||
this.attachments = CardService.getCurrent().attachments;
|
||||
}
|
||||
|
||||
mimetypeForAttachment(attachment) {
|
||||
let url = OC.MimeType.getIconUrl(attachment.extendedData.mimetype);
|
||||
let styles = {
|
||||
'background-image': `url("${url}")`,
|
||||
};
|
||||
return styles;
|
||||
}
|
||||
|
||||
attachmentUrl(attachment) {
|
||||
let cardId = this.cardservice.getCurrent().id;
|
||||
let attachmentId = attachment.id;
|
||||
return OC.generateUrl(`/apps/deck/cards/${cardId}/attachment/${attachmentId}`);
|
||||
}
|
||||
|
||||
getAttachmentMarkdown(attachment) {
|
||||
const inlineMimetypes = ['image/png', 'image/jpg', 'image/jpeg'];
|
||||
let url = this.attachmentUrl(attachment);
|
||||
let filename = attachment.data;
|
||||
let insertText = `[📎 ${filename}](${url})`;
|
||||
if (inlineMimetypes.indexOf(attachment.extendedData.mimetype) > -1) {
|
||||
insertText = ``;
|
||||
}
|
||||
return insertText;
|
||||
}
|
||||
|
||||
select(attachment) {
|
||||
this.onSelect({attachment: this.getAttachmentMarkdown(attachment)});
|
||||
}
|
||||
|
||||
abort() {
|
||||
this.onAbort();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let attachmentListComponent = {
|
||||
templateUrl: '/card.attachments.html',
|
||||
controller: AttachmentListController,
|
||||
bindings: {
|
||||
isFileSelector: '<',
|
||||
attachments: '=',
|
||||
onSelect: '&',
|
||||
onAbort: '&'
|
||||
}
|
||||
};
|
||||
export default attachmentListComponent;
|
||||
@@ -1,568 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
/* global oc_defaults oc_config OC OCP OCA t n */
|
||||
|
||||
import app from '../app/App.js';
|
||||
import Vue from 'vue';
|
||||
|
||||
Vue.prototype.t = t;
|
||||
Vue.prototype.n = n;
|
||||
Vue.prototype.OC = OC;
|
||||
|
||||
import CollaborationView from '../views/CollaborationView';
|
||||
|
||||
app.controller('BoardController', function ($rootScope, $scope, $element, $stateParams, StatusService, BoardService, StackService, CardService, LabelService, $state, $transitions, $filter, FileService) {
|
||||
|
||||
$scope.sidebar = $rootScope.sidebar;
|
||||
|
||||
$scope.id = $stateParams.boardId;
|
||||
$scope.status = {
|
||||
addCard: [],
|
||||
};
|
||||
$scope.newLabel = {};
|
||||
|
||||
$scope.OC = OC;
|
||||
$scope.stackservice = StackService;
|
||||
$scope.boardservice = BoardService;
|
||||
$scope.cardservice = CardService;
|
||||
$scope.statusservice = StatusService.getInstance();
|
||||
$scope.labelservice = LabelService;
|
||||
$scope.defaultColors = ['31CC7C', '317CCC', 'FF7A66', 'F1DB50', '7C31CC', 'CC317C', '3A3B3D', 'CACBCD'];
|
||||
$scope.board = BoardService.getCurrent();
|
||||
$scope.uploader = FileService.uploader;
|
||||
$scope.searchText = '';
|
||||
|
||||
$scope.startTitleEdit = function(card) {
|
||||
card.renameTitle = card.title;
|
||||
card.status = card.status || {};
|
||||
card.status.editCard = true;
|
||||
};
|
||||
|
||||
$scope.finishTitleEdit = function(card) {
|
||||
var newTitle;
|
||||
if (!card.renameTitle || !card.renameTitle.trim()) {
|
||||
newTitle = '';
|
||||
} else {
|
||||
newTitle = card.renameTitle.trim();
|
||||
}
|
||||
|
||||
if (newTitle === card.title) {
|
||||
// title unchanged
|
||||
card.status.editCard = false;
|
||||
delete card.renameTitle;
|
||||
} else if (newTitle !== '') {
|
||||
// title changed
|
||||
card.title = newTitle;
|
||||
CardService.update(card).then(function (data) {
|
||||
card.status.editCard = false;
|
||||
delete card.renameTitle;
|
||||
});
|
||||
} else {
|
||||
// empty title
|
||||
card.status.editCard = false;
|
||||
delete card.renameTitle;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$watch(function() {
|
||||
return $scope.params.tab;
|
||||
}, function (newTab, oldTab) {
|
||||
if (newTab === 2 && oldTab !== 2) {
|
||||
CardService.fetchDeleted($scope.id);
|
||||
StackService.fetchDeleted($scope.id);
|
||||
}
|
||||
});
|
||||
|
||||
// workaround for $stateParams changes not being propagated
|
||||
$scope.$watch(function() {
|
||||
return $state.params;
|
||||
}, function (params) {
|
||||
$scope.params = params;
|
||||
}, true);
|
||||
$scope.params = $state.params;
|
||||
|
||||
/**
|
||||
* Check for markdown checkboxes in description to render the counter
|
||||
*
|
||||
* This should probably be moved to the backend at some point
|
||||
*
|
||||
* @param text
|
||||
* @returns array of [finished, total] checkboxes
|
||||
*/
|
||||
$scope.getCheckboxes = function(text) {
|
||||
const regTotal = /\[(X|\s|\_|\-)\]/igm;
|
||||
const regFinished = /\[(X|\_|\-)\]/igm;
|
||||
return [
|
||||
((text || '').match(regFinished) || []).length,
|
||||
((text || '').match(regTotal) || []).length
|
||||
];
|
||||
};
|
||||
|
||||
$scope.search = function (searchText) {
|
||||
$scope.searchText = searchText;
|
||||
$scope.refreshData();
|
||||
};
|
||||
|
||||
$scope.$watch(function () {
|
||||
if (typeof BoardService.getCurrent() !== 'undefined') {
|
||||
return BoardService.getCurrent().title;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, function () {
|
||||
$scope.setPageTitle();
|
||||
});
|
||||
$scope.setPageTitle = function () {
|
||||
if (BoardService.getCurrent()) {
|
||||
document.title = BoardService.getCurrent().title + ' | Deck - ' + oc_defaults.name;
|
||||
} else {
|
||||
document.title = 'Deck - ' + oc_defaults.name;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.statusservice.retainWaiting();
|
||||
$scope.statusservice.retainWaiting();
|
||||
|
||||
// handle filter parameter for switching between archived/unarchived cards
|
||||
$scope.switchFilter = function (filter) {
|
||||
$state.go('.', {filter: filter});
|
||||
};
|
||||
$scope.$watch(function() {
|
||||
return $scope.params.filter;
|
||||
}, function (filter) {
|
||||
if (filter === 'archive') {
|
||||
$scope.loadArchived();
|
||||
} else {
|
||||
$scope.loadDefault();
|
||||
}
|
||||
});
|
||||
|
||||
if (parseInt(oc_config.version.split('.')[0]) >= 16) {
|
||||
const ComponentVM = new Vue({
|
||||
render: h => h(CollaborationView),
|
||||
data: {
|
||||
model: BoardService.getCurrent()
|
||||
},
|
||||
});
|
||||
$scope.mountCollections = function () {
|
||||
const MountingPoint = document.getElementById('collaborationResources');
|
||||
if (MountingPoint) {
|
||||
ComponentVM.model = BoardService.getCurrent();
|
||||
ComponentVM.$mount(MountingPoint);
|
||||
}
|
||||
};
|
||||
$scope.$$postDigest($scope.mountCollections);
|
||||
$scope.$watch(function () {
|
||||
return BoardService.getCurrent();
|
||||
}, function () {
|
||||
ComponentVM.model = BoardService.getCurrent();
|
||||
if ($scope.sidebar.show) {
|
||||
$scope.$$postDigest($scope.mountCollections);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.toggleCompactMode = function() {
|
||||
$rootScope.compactMode = !$rootScope.compactMode;
|
||||
localStorage.setItem('deck.compactMode', JSON.stringify($rootScope.compactMode));
|
||||
};
|
||||
|
||||
$scope.stacksData = StackService;
|
||||
$scope.stacks = [];
|
||||
$scope.$watch('stacksData', function () {
|
||||
$scope.refreshData();
|
||||
}, true);
|
||||
$scope.refreshData = function () {
|
||||
if ($scope.params.filter === 'archive') {
|
||||
$scope.filterData('-lastModified', $scope.searchText);
|
||||
} else {
|
||||
$scope.filterData('order', $scope.searchText);
|
||||
}
|
||||
};
|
||||
$scope.checkCanEdit = function () {
|
||||
return !BoardService.getCurrent().archived;
|
||||
};
|
||||
|
||||
// filter cards here, as ng-sortable will not work nicely with html-inline filters
|
||||
$scope.filterData = function (order, text) {
|
||||
if ($scope.stacks === undefined) {
|
||||
return;
|
||||
}
|
||||
angular.copy(StackService.getData(), $scope.stacks);
|
||||
$scope.stacks = $filter('orderBy')($scope.stacks, 'order');
|
||||
angular.forEach($scope.stacks, function (value, key) {
|
||||
var cards = $filter('cardSearchFilter')(value.cards, text);
|
||||
cards = $filter('orderBy')(cards, order);
|
||||
$scope.stacks[key].cards = cards;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.loadDefault = function () {
|
||||
StackService.fetchAll($scope.id).then(function (data) {
|
||||
$scope.statusservice.releaseWaiting();
|
||||
}, function (error) {
|
||||
$scope.statusservice.setError('Error occured', error);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.loadArchived = function () {
|
||||
StackService.fetchArchived($scope.id).then(function (data) {
|
||||
$scope.statusservice.releaseWaiting();
|
||||
}, function (error) {
|
||||
$scope.statusservice.setError('Error occured', error);
|
||||
});
|
||||
};
|
||||
|
||||
// Handle initial Loading
|
||||
BoardService.fetchOne($scope.id).then(function (data) {
|
||||
$scope.statusservice.releaseWaiting();
|
||||
$scope.setPageTitle();
|
||||
}, function (error) {
|
||||
$scope.statusservice.setError('Error occured', error);
|
||||
});
|
||||
|
||||
$scope.searchForUser = function (search) {
|
||||
BoardService.searchUsers(search);
|
||||
};
|
||||
|
||||
$scope.newStack = {'boardId': $scope.id};
|
||||
$scope.newCard = {};
|
||||
|
||||
// Create a new Stack
|
||||
$scope.createStack = function () {
|
||||
StackService.create($scope.newStack).then(function (data) {
|
||||
$scope.newStack.title = '';
|
||||
});
|
||||
};
|
||||
|
||||
$scope.createCard = function (stack, title) {
|
||||
if (this['addCardForm' + stack].$valid) {
|
||||
var newCard = {
|
||||
'title': title,
|
||||
'stackId': stack,
|
||||
'type': 'plain'
|
||||
};
|
||||
CardService.create(newCard).then(function (data) {
|
||||
$scope.stackservice.addCard(data);
|
||||
$scope.newCard.title = '';
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.stackDelete = function (stack) {
|
||||
$scope.stackservice.delete(stack.id);
|
||||
};
|
||||
|
||||
$scope.stackUndoDelete = function (deletedStack) {
|
||||
return StackService.undoDelete(deletedStack);
|
||||
};
|
||||
|
||||
$scope.cardDelete = function (card) {
|
||||
CardService.delete(card.id).then(function () {
|
||||
StackService.removeCard(card);
|
||||
$scope.sidebar.show = false;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cardOrCardAndStackUndoDelete = function (deletedCard) {
|
||||
var associatedDeletedStack = $scope.stackservice.deleted[deletedCard.stackId];
|
||||
if(associatedDeletedStack !== undefined) {
|
||||
$scope.cardAndStackUndoDeleteAskForConfirmation(deletedCard, associatedDeletedStack);
|
||||
} else {
|
||||
$scope.cardUndoDelete(deletedCard);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.cardAndStackUndoDeleteAskForConfirmation = function(deletedCard, associatedDeletedStack) {
|
||||
OC.dialogs.confirm(
|
||||
t('deck', 'The associated stack is deleted as well, it will be restored as well.'),
|
||||
t('deck', 'Restore associated stack'),
|
||||
function(state) {
|
||||
if (state) {
|
||||
$scope.cardAndStackUndoDelete(deletedCard, associatedDeletedStack);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.cardAndStackUndoDelete = function(deletedCard, associatedDeletedStack) {
|
||||
$scope.stackUndoDelete(associatedDeletedStack).then(function() {
|
||||
$scope.cardUndoDelete(deletedCard);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cardUndoDelete = function(deletedCard) {
|
||||
CardService.undoDelete(deletedCard).then(function() {
|
||||
StackService.addCard(deletedCard);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cardArchive = function (card) {
|
||||
CardService.archive(card);
|
||||
StackService.removeCard(card);
|
||||
};
|
||||
|
||||
$scope.isCurrentUserAssigned = function (card) {
|
||||
if (! CardService.get(card.id).assignedUsers) {
|
||||
return false;
|
||||
}
|
||||
var userList = CardService.get(card.id).assignedUsers.filter(function (obj) {
|
||||
return obj.participant.uid === OC.getCurrentUser().uid;
|
||||
});
|
||||
return userList.length === 1;
|
||||
};
|
||||
|
||||
$scope.cardAssignToMe = function (card) {
|
||||
CardService.assignUser(card, OC.getCurrentUser().uid)
|
||||
.then(
|
||||
function() {StackService.updateCard(card);}
|
||||
);
|
||||
// TODO: remove this jquery call. Fix and use appPopoverMenuUtils instead
|
||||
$('.popovermenu').addClass('hidden');
|
||||
};
|
||||
|
||||
$scope.cardUnassignFromMe = function (card) {
|
||||
CardService.unassignUser(card, OC.getCurrentUser().uid);
|
||||
StackService.updateCard(card);
|
||||
// TODO: remove this jquery call.Fix and use appPopoverMenuUtils instead
|
||||
$('.popovermenu').addClass('hidden');
|
||||
};
|
||||
$scope.cardUnarchive = function (card) {
|
||||
CardService.unarchive(card);
|
||||
StackService.removeCard(card);
|
||||
};
|
||||
|
||||
$scope.labelDelete = function (label) {
|
||||
LabelService.delete(label.id);
|
||||
// remove from board data
|
||||
var i = BoardService.getCurrent().labels.indexOf(label);
|
||||
BoardService.getCurrent().labels.splice(i, 1);
|
||||
|
||||
// remove from cards
|
||||
var cards = CardService.data;
|
||||
for (var card in cards) {
|
||||
if (Object.prototype.hasOwnProperty.call(cards, card)) {
|
||||
var labelsFromCard = cards[card].labels;
|
||||
|
||||
labelsFromCard.forEach(function (labelFromCard, index) {
|
||||
if (labelFromCard.id === label.id) {
|
||||
cards[card].labels.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.labelCreate = function (label) {
|
||||
label.boardId = $scope.id;
|
||||
LabelService.create(label).then(function (data) {
|
||||
$scope.newStack.title = '';
|
||||
BoardService.getCurrent().labels.push(data);
|
||||
$scope.status.createLabel = false;
|
||||
$scope.newLabel = {};
|
||||
}).catch((err) => {
|
||||
OC.Notification.showTemporary(err);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.labelUpdateBefore = function (label) {
|
||||
label.renameTitle = label.title;
|
||||
};
|
||||
|
||||
$scope.labelUpdate = function (label) {
|
||||
label.edit = false;
|
||||
LabelService.update(label).catch((err) => {
|
||||
label.title = label.renameTitle;
|
||||
OC.Notification.showTemporary(err);
|
||||
});
|
||||
|
||||
// update labels in UI
|
||||
var cards = CardService.data;
|
||||
for (var card in cards) {
|
||||
if (Object.prototype.hasOwnProperty.call(cards, card)) {
|
||||
var labelsFromCard = cards[card].labels;
|
||||
|
||||
labelsFromCard.forEach(function (labelFromCard, index) {
|
||||
if (labelFromCard.id === label.id) {
|
||||
cards[card].labels[index] = label;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.aclAdd = function (sharee) {
|
||||
sharee.boardId = $scope.id;
|
||||
BoardService.addAcl(sharee);
|
||||
$scope.status.addSharee = null;
|
||||
};
|
||||
|
||||
$scope.aclDelete = function (acl) {
|
||||
BoardService.deleteAcl(acl).then(function(data) {
|
||||
$scope.loadDefault();
|
||||
$scope.refreshData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.aclUpdate = function (acl) {
|
||||
BoardService.updateAcl(acl);
|
||||
};
|
||||
|
||||
$scope.aclTypeString = function (acl) {
|
||||
if (typeof acl === 'undefined') {
|
||||
return '';
|
||||
}
|
||||
switch (acl.type) {
|
||||
case OC.Share.SHARE_TYPE_USER:
|
||||
return 'user';
|
||||
case OC.Share.SHARE_TYPE_GROUP:
|
||||
return 'group';
|
||||
case OC.Share.SHARE_TYPE_CIRCLE:
|
||||
return 'circles';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
// settings for card sorting
|
||||
$scope.sortOptions = {
|
||||
id: 'card',
|
||||
itemMoved: function (event) {
|
||||
event.source.itemScope.modelValue.status = event.dest.sortableScope.$parent.column;
|
||||
var order = event.dest.index;
|
||||
var card = $scope.cardservice.get(event.source.itemScope.c.id);
|
||||
var newStack = event.dest.sortableScope.$parent.s.id;
|
||||
var oldStack = card.stackId;
|
||||
card.stackId = newStack;
|
||||
CardService.update(card);
|
||||
CardService.reorder(card, order).then(function (data) {
|
||||
StackService.addCard(card);
|
||||
StackService.reorderCard(card, order);
|
||||
StackService.removeCard({
|
||||
id: card.id,
|
||||
stackId: oldStack
|
||||
});
|
||||
});
|
||||
},
|
||||
orderChanged: function (event) {
|
||||
var order = event.dest.index;
|
||||
var card = $scope.cardservice.get(event.source.itemScope.c.id);
|
||||
var stack = event.dest.sortableScope.$parent.s.id;
|
||||
CardService.reorder(card, order).then(function (data) {
|
||||
StackService.reorderCard(card, order);
|
||||
$scope.refreshData();
|
||||
});
|
||||
},
|
||||
scrollableContainer: '#innerBoard',
|
||||
containerPositioning: 'relative',
|
||||
containment: '#innerBoard',
|
||||
longTouch: true,
|
||||
// auto scroll on drag
|
||||
dragMove: function (itemPosition, containment, eventObj) {
|
||||
if (eventObj) {
|
||||
var container = $('#board');
|
||||
var offset = container.offset();
|
||||
var targetX = eventObj.pageX - (offset.left || container.scrollLeft());
|
||||
var targetY = eventObj.pageY - (offset.top || container.scrollTop());
|
||||
if (targetX < offset.left) {
|
||||
container.scrollLeft(container.scrollLeft() - 25);
|
||||
} else if (targetX > container.width()) {
|
||||
container.scrollLeft(container.scrollLeft() + 25);
|
||||
}
|
||||
if (targetY < offset.top) {
|
||||
container.scrollTop(container.scrollTop() - 25);
|
||||
} else if (targetY > container.height()) {
|
||||
container.scrollTop(container.scrollTop() + 25);
|
||||
}
|
||||
}
|
||||
},
|
||||
accept: function (sourceItemHandleScope, destSortableScope, destItemScope) {
|
||||
return sourceItemHandleScope.sortableScope.options.id === 'card';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.sortOptionsStack = {
|
||||
id: 'stack',
|
||||
orderChanged: function (event) {
|
||||
var order = event.dest.index;
|
||||
var stack = event.source.itemScope.s;
|
||||
StackService.reorder(stack, order).then(function (data) {
|
||||
$scope.refreshData();
|
||||
});
|
||||
},
|
||||
scrollableContainer: '#board',
|
||||
containerPositioning: 'relative',
|
||||
containment: '#innerBoard',
|
||||
dragMove: function (itemPosition, containment, eventObj) {
|
||||
if (eventObj) {
|
||||
var container = $('#board');
|
||||
var offset = container.offset();
|
||||
var targetX = eventObj.pageX - (offset.left || container.scrollLeft());
|
||||
var targetY = eventObj.pageY - (offset.top || container.scrollTop());
|
||||
if (targetX < offset.left) {
|
||||
container.scrollLeft(container.scrollLeft() - 50);
|
||||
} else if (targetX > container.width()) {
|
||||
container.scrollLeft(container.scrollLeft() + 50);
|
||||
}
|
||||
if (targetY < offset.top) {
|
||||
container.scrollTop(container.scrollTop() - 50);
|
||||
} else if (targetY > container.height()) {
|
||||
container.scrollTop(container.scrollTop() + 50);
|
||||
}
|
||||
}
|
||||
},
|
||||
accept: function (sourceItemHandleScope, destSortableScope, destItemScope) {
|
||||
return sourceItemHandleScope.sortableScope.options.id === 'stack';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.labelStyle = function (color) {
|
||||
return {
|
||||
'background-color': '#' + color,
|
||||
'color': $filter('textColorFilter')(color)
|
||||
};
|
||||
};
|
||||
|
||||
$scope.colorValue = function(color) {
|
||||
const re = /^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/;
|
||||
if (re.test(color)) {
|
||||
return color;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
$scope.attachmentCount = function(card) {
|
||||
if (Array.isArray(card.attachments)) {
|
||||
return card.attachments.filter((obj) => obj.deletedAt === 0).length;
|
||||
}
|
||||
return card.attachmentCount;
|
||||
};
|
||||
|
||||
$scope.unreadCommentCount = function(card) {
|
||||
return card.commentsUnread;
|
||||
};
|
||||
|
||||
$scope.isTimelineEnabled = function() {
|
||||
return OCP.Comments && OCA.Activity;
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global app moment angular OC OCP OCA */
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.controller('CardController', function ($scope, $rootScope, $sce, $location, $stateParams, $state, $interval, $timeout, $filter, BoardService, CardService, StackService, StatusService, markdownItConverter, FileService) {
|
||||
$scope.sidebar = $rootScope.sidebar;
|
||||
$scope.status = {
|
||||
renameTitle: '',
|
||||
lastEdit: 0,
|
||||
lastSave: Date.now()
|
||||
};
|
||||
|
||||
$scope.cardservice = CardService;
|
||||
$scope.fileservice = FileService;
|
||||
$scope.cardId = $stateParams.cardId;
|
||||
|
||||
$scope.statusservice = StatusService.getInstance();
|
||||
$scope.boardservice = BoardService;
|
||||
|
||||
$scope.isArray = angular.isArray;
|
||||
// workaround for $stateParams changes not being propagated
|
||||
$scope.$watch(function() {
|
||||
return $state.params;
|
||||
}, function (params) {
|
||||
$scope.params = params;
|
||||
$scope.fileservice.reset();
|
||||
}, true);
|
||||
$scope.params = $state.params;
|
||||
|
||||
$scope.addAttachmentToDescription = function(insertText) {
|
||||
let el = document.querySelectorAll('textarea')[0];
|
||||
let start = el.selectionStart;
|
||||
let end = el.selectionEnd;
|
||||
let text = $scope.status.edit.description || '';
|
||||
let before = text.substring(0, start);
|
||||
let after = text.substring(end, text.length);
|
||||
let newText = before + '\n' + insertText + '\n' + after;
|
||||
$scope.status.edit.description = newText;
|
||||
el.selectionStart = el.selectionEnd = start + newText.length;
|
||||
el.focus();
|
||||
$scope.status.continueEdit = false;
|
||||
$scope.cardEditDescriptionChanged();
|
||||
$scope.status.selectAttachment = false;
|
||||
};
|
||||
|
||||
$scope.abortAttachmentSelection = function() {
|
||||
$scope.status.continueEdit = false;
|
||||
$scope.status.selectAttachment = false;
|
||||
let el = document.querySelectorAll('textarea')[0];
|
||||
el.focus();
|
||||
};
|
||||
|
||||
$scope.statusservice.retainWaiting();
|
||||
|
||||
$scope.description = function() {
|
||||
return $scope.rendered;
|
||||
};
|
||||
|
||||
$scope.updateMarkdown = function(content) {
|
||||
// only trust the html from markdown-it-checkbox
|
||||
$scope.rendered = $sce.trustAsHtml(markdownItConverter.render(content || ''));
|
||||
};
|
||||
|
||||
CardService.fetchOne($scope.cardId).then(function (data) {
|
||||
$scope.statusservice.releaseWaiting();
|
||||
$scope.archived = CardService.getCurrent().archived;
|
||||
$scope.updateMarkdown(CardService.getCurrent().description);
|
||||
}, function (error) {
|
||||
});
|
||||
|
||||
$scope.cardRenameShow = function () {
|
||||
if ($scope.archived || !BoardService.canEdit()) {
|
||||
return false;
|
||||
} else {
|
||||
$scope.status.renameTitle = CardService.getCurrent().title;
|
||||
$scope.status.cardRename = true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleCheckbox = function (id) {
|
||||
$('#markdown input[type=checkbox]').attr('disabled', true);
|
||||
$scope.status.edit = angular.copy(CardService.getCurrent());
|
||||
var reg = /\[(X|\s|\_|\-)\]/ig;
|
||||
var nth = 0;
|
||||
$scope.status.edit.description = $scope.status.edit.description.replace(reg, function (match, i, original) {
|
||||
var result = match;
|
||||
if ('' + nth++ === '' + id) {
|
||||
if (match.match(/^\[\s\]/i)) {
|
||||
result = match.replace(/\[\s\]/i, '[x]');
|
||||
}
|
||||
if (match.match(/^\[x\]/i)) {
|
||||
result = match.replace(/\[x\]/i, '[ ]');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
CardService.update($scope.status.edit).then(function (data) {
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').hide();
|
||||
header.find('.save-indicator.saved').fadeIn(250).fadeOut(1000);
|
||||
});
|
||||
$('#markdown input[type=checkbox]').removeAttr('disabled');
|
||||
|
||||
};
|
||||
$scope.clickCardDescription = function ($event) {
|
||||
var checkboxId = $($event.target).data('id');
|
||||
if ($event.target.tagName === 'LABEL') {
|
||||
$scope.toggleCheckbox(checkboxId);
|
||||
$event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
if ($event.target.tagName === 'INPUT') {
|
||||
$event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
if (BoardService.isArchived() || CardService.getCurrent().archived) {
|
||||
return false;
|
||||
}
|
||||
if ($scope.card.archived || !$scope.boardservice.canEdit()) {
|
||||
return false;
|
||||
}
|
||||
$scope.status.cardEditDescription = true;
|
||||
$scope.status.edit = angular.copy(CardService.getCurrent());
|
||||
return true;
|
||||
};
|
||||
$scope.cardEditDescriptionChanged = function ($event) {
|
||||
$scope.status.lastEdit = Date.now();
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').show();
|
||||
header.find('.save-indicator.saved').hide();
|
||||
};
|
||||
$interval(function() {
|
||||
var currentTime = Date.now();
|
||||
var timeSinceEdit = currentTime-$scope.status.lastEdit;
|
||||
if (timeSinceEdit > 1000 && $scope.status.lastEdit > $scope.status.lastSave && !$scope.status.saving) {
|
||||
$scope.status.lastSave = currentTime;
|
||||
$scope.status.saving = true;
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').fadeIn(500);
|
||||
CardService.update($scope.status.edit).then(function (data) {
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').hide();
|
||||
header.find('.save-indicator.saved').fadeIn(250).fadeOut(1000);
|
||||
$scope.status.saving = false;
|
||||
});
|
||||
}
|
||||
}, 500, 0, false);
|
||||
|
||||
// handle rename to update information on the board as well
|
||||
$scope.cardRename = function (card) {
|
||||
var newTitle;
|
||||
if (!$scope.status.renameTitle || !$scope.status.renameTitle.trim()) {
|
||||
newTitle = '';
|
||||
} else {
|
||||
newTitle = $scope.status.renameTitle.trim();
|
||||
}
|
||||
|
||||
if (newTitle === card.title) {
|
||||
// title unchanged
|
||||
$scope.status.renameCard = false;
|
||||
} else if (newTitle !== '') {
|
||||
// title changed
|
||||
card.title = newTitle;
|
||||
CardService.rename(card).then(function (data) {
|
||||
$scope.status.renameCard = false;
|
||||
});
|
||||
} else {
|
||||
// empty title
|
||||
$scope.status.renameTitle = card.title;
|
||||
$scope.status.renameCard = false;
|
||||
}
|
||||
};
|
||||
$scope.cardUpdate = function (card) {
|
||||
CardService.update(card).then(function (data) {
|
||||
$scope.status.cardEditDescription = false;
|
||||
$scope.updateMarkdown($scope.status.edit.description);
|
||||
var header = $('.tabDetails');
|
||||
header.find('.save-indicator.unsaved').hide();
|
||||
header.find('.save-indicator.saved').fadeIn(500).fadeOut(1000);
|
||||
});
|
||||
};
|
||||
|
||||
$scope.labelAssign = function (element, model) {
|
||||
CardService.assignLabel($scope.cardId, element.id).then(function (data) {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.labelRemove = function (element, model) {
|
||||
CardService.removeLabel($scope.cardId, element.id).then(function (data) {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.setDuedate = function (duedate) {
|
||||
var element = CardService.getCurrent();
|
||||
var newDate = moment(element.duedate);
|
||||
if(!newDate.isValid()) {
|
||||
newDate = moment();
|
||||
}
|
||||
newDate.date(duedate.date());
|
||||
newDate.month(duedate.month());
|
||||
newDate.year(duedate.year());
|
||||
element.duedate = newDate.toISOString();
|
||||
CardService.update(element);
|
||||
};
|
||||
$scope.setDuedateTime = function (time) {
|
||||
var element = CardService.getCurrent();
|
||||
var newDate = moment(element.duedate);
|
||||
if(!newDate.isValid()) {
|
||||
newDate = moment();
|
||||
}
|
||||
newDate.hour(time.hour());
|
||||
newDate.minute(time.minute());
|
||||
element.duedate = newDate.toISOString();
|
||||
CardService.update(element);
|
||||
};
|
||||
|
||||
$scope.resetDuedate = function () {
|
||||
var element = CardService.getCurrent();
|
||||
element.duedate = null;
|
||||
CardService.update(element);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show ui-select field when clicking the add button
|
||||
*/
|
||||
$scope.toggleAssignUser = function() {
|
||||
$scope.status.showAssignUser = !$scope.status.showAssignUser;
|
||||
if ($scope.status.showAssignUser === true) {
|
||||
$timeout(function () {
|
||||
$('#assignUserSelect').find('a').click();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide ui-select when select list is closed
|
||||
*/
|
||||
$scope.assingUserOpenClose = function(isOpen) {
|
||||
$scope.status.showAssignUser = isOpen;
|
||||
};
|
||||
|
||||
$scope.addAssignedUser = function(item) {
|
||||
CardService.assignUser(CardService.getCurrent(), item.uid).then(function (data) {
|
||||
});
|
||||
$scope.status.showAssignUser = false;
|
||||
};
|
||||
|
||||
$scope.removeAssignedUser = function(uid) {
|
||||
CardService.unassignUser(CardService.getCurrent(), uid).then(function (data) {
|
||||
});
|
||||
};
|
||||
|
||||
$scope.labelStyle = function (color) {
|
||||
return {
|
||||
'background-color': '#' + color,
|
||||
'color': $filter('textColorFilter')(color)
|
||||
};
|
||||
};
|
||||
|
||||
$scope.isTimelineEnabled = function() {
|
||||
return OCP.Comments && OCA.Activity;
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2018 Oskar Kurz <oskar.kurz@gmail.com>
|
||||
*
|
||||
* @author Oskar Kurz <oskar.kurz@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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global oc_defaults OC */
|
||||
app.controller('ColorPickerController', ['$scope', function ($scope) {
|
||||
$scope.hashedColor = '';
|
||||
|
||||
$scope.setColor = function (object, color) {
|
||||
object.color = color;
|
||||
object.hashedColor = '#' + color;
|
||||
|
||||
return object;
|
||||
};
|
||||
|
||||
$scope.setHashedColor = function (object) {
|
||||
object.color = object.hashedColor.substr(1);
|
||||
return object;
|
||||
};
|
||||
|
||||
$scope.getCustomBackground = function (color) {
|
||||
return {'background-color': color};
|
||||
};
|
||||
}]);
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global app angular oc_isadmin */
|
||||
|
||||
var ListController = function ($scope, $location, $filter, BoardService, $element, $timeout, $stateParams, $state, StatusService, $http, $q, $rootScope) {
|
||||
|
||||
function calculateNewColor() {
|
||||
var boards = BoardService.getAll();
|
||||
var boardKeys = Object.keys(boards);
|
||||
var colorOccurrences = [];
|
||||
|
||||
for (var i = 0; i < $scope.colors.length; i++) {
|
||||
colorOccurrences.push(0);
|
||||
}
|
||||
|
||||
for (var j = 0; j < boardKeys.length; j++) {
|
||||
var key = boardKeys[j];
|
||||
var board = boards[key];
|
||||
|
||||
if (board && $scope.colors.indexOf(board.color) !== -1) {
|
||||
colorOccurrences[$scope.colors.indexOf(board.color)]++;
|
||||
}
|
||||
}
|
||||
|
||||
return $scope.colors[colorOccurrences.indexOf(Math.min.apply(Math, colorOccurrences))];
|
||||
}
|
||||
|
||||
$scope.boards = [];
|
||||
$scope.newBoard = {};
|
||||
$scope.status = {
|
||||
deleteUndo: [],
|
||||
filter: $stateParams.filter ? $stateParams.filter : '',
|
||||
sidebar: false
|
||||
};
|
||||
$scope.colors = ['0082c9', '00c9c6','00c906', 'c92b00', 'F1DB50', '7C31CC', '3A3B3D', 'CACBCD'];
|
||||
$scope.boardservice = BoardService;
|
||||
$scope.updatingBoard = null;
|
||||
$scope.isAdmin = oc_isadmin;
|
||||
$scope.canCreate = $rootScope.config.canCreate;
|
||||
|
||||
if ($scope.isAdmin) {
|
||||
OC.Apps.enableDynamicSlideToggle();
|
||||
$scope.groups = [];
|
||||
$scope.groupLimit = [];
|
||||
$scope.groupLimitDisabled = true;
|
||||
let fetchGroups = function () {
|
||||
var deferred = $q.defer();
|
||||
// TODO: move to groups/details once 15 is min version
|
||||
$http.get(OC.linkToOCS('cloud', 2) + 'groups').then(function (response) {
|
||||
$scope.groups = response.data.ocs.data.groups.reduce((obj, item) => {
|
||||
obj.push({
|
||||
id: item,
|
||||
displayname: item,
|
||||
});
|
||||
return obj;
|
||||
}, []);
|
||||
deferred.resolve($scope.groups);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while loading groups');
|
||||
});
|
||||
$http.get(OC.generateUrl('apps/deck/config')).then(function (response) {
|
||||
$scope.groupLimit = response.data.groupLimit;
|
||||
$scope.groupLimitDisabled = false;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while loading groupLimit');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
let updateConfig = function() {
|
||||
$scope.groupLimitDisabled = true;
|
||||
var deferred = $q.defer();
|
||||
$http.post(OC.generateUrl('apps/deck/config/groupLimit'), {value: $scope.groupLimit}).then(function (response) {
|
||||
$scope.groupLimitDisabled = false;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while saving groupLimit');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
$scope.groupLimitAdd = function (element, model) {
|
||||
$scope.groupLimit.push(element);
|
||||
updateConfig();
|
||||
};
|
||||
$scope.groupLimitRemove = function (element, model) {
|
||||
$scope.groupLimit = $scope.groupLimit.filter((el) => {
|
||||
return el.id !== element.id;
|
||||
});
|
||||
updateConfig();
|
||||
};
|
||||
fetchGroups();
|
||||
}
|
||||
|
||||
var filterData = function () {
|
||||
if($element.attr('id') === 'app-navigation') {
|
||||
$scope.boardservice.sidebar = $scope.boardservice.getData();
|
||||
$scope.boardservice.sidebar = $filter('orderBy')($scope.boardservice.sidebar, 'title');
|
||||
$scope.boardservice.sidebar = $filter('cardFilter')($scope.boardservice.sidebar, {archived: false});
|
||||
} else {
|
||||
$scope.boardservice.sorted = $scope.boardservice.getData();
|
||||
if ($scope.status.filter === 'archived') {
|
||||
var filter = {};
|
||||
filter[$scope.status.filter] = true;
|
||||
$scope.boardservice.sorted = $filter('cardFilter')($scope.boardservice.sorted, filter);
|
||||
} else if ($scope.status.filter === 'shared') {
|
||||
$scope.boardservice.sorted = $filter('cardFilter')($scope.boardservice.sorted, {archived: false});
|
||||
$scope.boardservice.sorted = $filter('boardFilterAcl')($scope.boardservice.sorted);
|
||||
} else {
|
||||
$scope.boardservice.sorted = $filter('cardFilter')($scope.boardservice.sorted, {archived: false});
|
||||
}
|
||||
$scope.boardservice.sorted = $filter('orderBy')($scope.boardservice.sorted, ['deletedAt', 'title']);
|
||||
}
|
||||
};
|
||||
|
||||
var finishedLoading = function() {
|
||||
filterData();
|
||||
$scope.newBoard.color = calculateNewColor();
|
||||
};
|
||||
|
||||
var initialize = function () {
|
||||
$scope.statusservice = StatusService.listStatus;
|
||||
|
||||
if($element.attr('id') === 'app-navigation') {
|
||||
$scope.statusservice.retainWaiting();
|
||||
BoardService.fetchAll().then(function(data) {
|
||||
finishedLoading();
|
||||
$scope.statusservice.releaseWaiting();
|
||||
BoardService.loaded = true;
|
||||
}, function (error) {
|
||||
$scope.statusservice.setError('Error occured', error);
|
||||
});
|
||||
} else {
|
||||
/* initialize main list controller when board list is loaded */
|
||||
var boardDataWatch = $scope.$watch(function () {
|
||||
return $scope.boardservice.loaded;
|
||||
}, function () {
|
||||
if (BoardService.loaded === true) {
|
||||
boardDataWatch();
|
||||
finishedLoading();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch(function () {
|
||||
return $scope.boardservice.data;
|
||||
}, function () {
|
||||
filterData();
|
||||
}, true);
|
||||
|
||||
/* Watch for board filter change */
|
||||
$scope.$watchCollection(function(){
|
||||
return $state.params;
|
||||
}, function(){
|
||||
$scope.status.filter = $state.params.filter;
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
initialize();
|
||||
|
||||
$scope.selectColor = function(color) {
|
||||
$scope.newBoard.color = color;
|
||||
};
|
||||
|
||||
$scope.gotoBoard = function(board) {
|
||||
if(board.deletedAt > 0) {
|
||||
return false;
|
||||
}
|
||||
return $state.go('board', {boardId: board.id});
|
||||
};
|
||||
|
||||
$scope.boardCreate = function() {
|
||||
if(!$scope.newBoard.title || !$scope.newBoard.color) {
|
||||
$scope.status.addBoard=false;
|
||||
return;
|
||||
}
|
||||
BoardService.create($scope.newBoard)
|
||||
.then(function (response) {
|
||||
$scope.newBoard = {};
|
||||
$scope.newBoard.color = calculateNewColor();
|
||||
$scope.status.addBoard=false;
|
||||
filterData();
|
||||
}, function(error) {
|
||||
$scope.status.createBoard = 'Unable to insert board: ' + error.message;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardUpdate = function(board) {
|
||||
BoardService.update(board).then(function(data) {
|
||||
board.status.edit = false;
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardUpdateBegin = function(board) {
|
||||
$scope.updatingBoard = angular.copy(board);
|
||||
};
|
||||
|
||||
$scope.boardUpdateReset = function(board) {
|
||||
board.title = $scope.updatingBoard.title;
|
||||
board.color = $scope.updatingBoard.color;
|
||||
filterData();
|
||||
board.status.edit = false;
|
||||
};
|
||||
|
||||
$scope.boardArchive = function (board) {
|
||||
board.archived = true;
|
||||
BoardService.update(board).then(function(data) {
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardUnarchive = function (board) {
|
||||
board.archived = false;
|
||||
BoardService.update(board).then(function(data) {
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardDelete = function(board) {
|
||||
BoardService.delete(board.id).then(function (data) {
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.boardDeleteUndo = function (board) {
|
||||
BoardService.deleteUndo(board.id).then(function (data) {
|
||||
filterData();
|
||||
});
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
export default ListController;
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('appPopoverMenuUtils', function () {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'C',
|
||||
link: function (scope, elm) {
|
||||
var menu = elm.find('.popovermenu');
|
||||
var button = elm.find('button');
|
||||
button.click(function (e) {
|
||||
var popovermenus = $('.popovermenu');
|
||||
var shouldShow = menu.hasClass('hidden');
|
||||
popovermenus.addClass('hidden');
|
||||
if (shouldShow) {
|
||||
menu.toggleClass('hidden');
|
||||
}
|
||||
e.stopPropagation();
|
||||
});
|
||||
scope.$on('documentClicked', function (scope, event) {
|
||||
/* prevent closing popover if target has no-close class */
|
||||
if (event.target !== button && !$(event.target).hasClass('no-close')) {
|
||||
menu.addClass('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('autofocusOnInsert', function () {
|
||||
'use strict';
|
||||
return function (scope, elm) {
|
||||
elm.focus();
|
||||
};
|
||||
});
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('avatar', function() {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'AEC',
|
||||
transclude: true,
|
||||
replace: true,
|
||||
template: '<div class="avatardiv-container"><div class="avatardiv" data-toggle="tooltip" ng-transclude></div></div>',
|
||||
scope: { attr: '=' },
|
||||
link: function(scope, element, attr){
|
||||
scope.uid = attr.displayname;
|
||||
scope.displayname = attr.displayname;
|
||||
scope.size = attr.size;
|
||||
if (typeof scope.size === 'undefined') {
|
||||
scope.size = 32;
|
||||
}
|
||||
var value = attr.user;
|
||||
var avatardiv = $(element).find('.avatardiv');
|
||||
if(typeof attr.contactsmenu !== 'undefined' && attr.contactsmenu !== 'false') {
|
||||
avatardiv.contactsMenu(value, 0, $(element));
|
||||
avatardiv.addClass('has-contactsmenu');
|
||||
}
|
||||
if(typeof attr.tooltip !== 'undefined' && attr.tooltip !== 'false') {
|
||||
$(element).tooltip({
|
||||
title: scope.displayname,
|
||||
placement: 'top'
|
||||
});
|
||||
}
|
||||
avatardiv.avatar(value, scope.size, false, false, false, attr.displayname);
|
||||
},
|
||||
controller: function () {}
|
||||
};
|
||||
});
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('contactsmenudelete', function() {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'A',
|
||||
priority: 1,
|
||||
link: function(scope, element, attr){
|
||||
var user = attr.user;
|
||||
var menu = $(element).parent().find('.contactsmenu-popover');
|
||||
if (oc_current_user === user) {
|
||||
menu.children(':first').remove();
|
||||
}
|
||||
var menuEntry = $('<li><a><span class="icon icon-delete"></span><span>' + t('deck', 'Remove user from card') + '</span></a></li>');
|
||||
menuEntry.on('click', function () {
|
||||
scope.removeAssignedUser(user);
|
||||
});
|
||||
$(menu).append(menuEntry);
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App';
|
||||
|
||||
app.directive('ngContenteditable', function($compile) {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
submit: '&ngSubmit'
|
||||
},
|
||||
link: function(scope, element, attrs, ngModel) {
|
||||
|
||||
//read the text typed in the div (syncing model with the view)
|
||||
function read() {
|
||||
ngModel.$setViewValue(element.html());
|
||||
}
|
||||
|
||||
//render the data now in your model into your view
|
||||
//$render is invoked when the modelvalue differs from the viewvalue
|
||||
//see documentation: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#
|
||||
ngModel.$render = function() {
|
||||
element.html(ngModel.$viewValue || '');
|
||||
};
|
||||
|
||||
//do this whenever someone starts typing
|
||||
element.bind('blur keyup change', function(event) {
|
||||
scope.$apply(read);
|
||||
});
|
||||
|
||||
element.bind('keydown', function(event) {
|
||||
if(event.which === 13 && event.shiftKey) {
|
||||
scope.submit();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2017 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global app */
|
||||
/* gloabl t */
|
||||
/* global moment */
|
||||
|
||||
app.directive('datepicker', function () {
|
||||
'use strict';
|
||||
return {
|
||||
link: function (scope, elm, attr) {
|
||||
return elm.datepicker({
|
||||
dateFormat: moment.localeData().longDateFormat('L').replace('YYYY', 'YY').toLowerCase(),
|
||||
onSelect: function(date, inst) {
|
||||
var selectedDate = $(this).datepicker('getDate');
|
||||
scope.setDuedate(moment(selectedDate));
|
||||
scope.$apply();
|
||||
},
|
||||
beforeShow: function(input, inst) {
|
||||
var dp, marginLeft;
|
||||
dp = $(inst).datepicker('widget');
|
||||
marginLeft = -Math.abs($(input).outerWidth() - dp.outerWidth()) / 2 + 'px';
|
||||
dp.css({
|
||||
'margin-left': marginLeft
|
||||
});
|
||||
$('div.ui-datepicker:before').css({
|
||||
'left': 100 + 'px'
|
||||
});
|
||||
return $('.hasDatepicker').datepicker();
|
||||
},
|
||||
minDate: null
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
// original idea from blockloop: http://stackoverflow.com/a/24090733
|
||||
app.directive('elastic', [
|
||||
'$timeout',
|
||||
function($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, element) {
|
||||
$scope.initialHeight = $scope.initialHeight || element[0].style.height;
|
||||
var resize = function() {
|
||||
element[0].style.height = $scope.initialHeight;
|
||||
element[0].style.height = "" + element[0].scrollHeight + "px";
|
||||
};
|
||||
element.on("input change", resize);
|
||||
$timeout(resize, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.directive('search', function ($document, $location) {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
'onSearch': '='
|
||||
},
|
||||
link: function (scope) {
|
||||
if (OCA.Search && OCA.Search.Core) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const search = new OCA.Search((term) => {
|
||||
scope.$apply(function () {
|
||||
scope.onSearch(term);
|
||||
});
|
||||
}, () => {
|
||||
scope.$apply(function () {
|
||||
scope.onSearch('');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const box = $('#searchbox');
|
||||
box.val($location.search().search);
|
||||
|
||||
var doSearch = function () {
|
||||
var value = box.val();
|
||||
scope.$apply(function () {
|
||||
scope.onSearch(value);
|
||||
});
|
||||
};
|
||||
|
||||
box.on('search keyup', function (event) {
|
||||
doSearch();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2017 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
import '../legacy/jquery.ui.timepicker.js';
|
||||
import 'legacy/jquery.ui.timepicker.css';
|
||||
|
||||
/* global app */
|
||||
/* global t */
|
||||
/* global moment */
|
||||
|
||||
app.directive('timepicker', function() {
|
||||
'use strict';
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, elm, attr) {
|
||||
return $(elm).timepicker({
|
||||
onSelect: function(date, inst) {
|
||||
scope.setDuedateTime(moment('2000-01-01 ' + date));
|
||||
scope.$apply();
|
||||
},
|
||||
myPosition: 'center top',
|
||||
atPosition: 'center bottom',
|
||||
hourText: t('deck', 'Hours'),
|
||||
minuteText: t('deck', 'Minutes'),
|
||||
showPeriodLabels: false
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2017 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('boardFilterAcl', function() {
|
||||
return function(boards) {
|
||||
var _result = [];
|
||||
angular.forEach(boards, function(board){
|
||||
if(board.acl !== null && Object.keys(board.acl).length > 0) {
|
||||
_result.push(board);
|
||||
}
|
||||
});
|
||||
return _result;
|
||||
};
|
||||
});
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
// usage | cardFilter({ member: 'admin'})
|
||||
|
||||
app.filter('cardFilter', function() {
|
||||
return function(cards, rules) {
|
||||
var _result = [];
|
||||
angular.forEach(cards, function(card){
|
||||
var _card = card;
|
||||
var keys = Object.keys(rules);
|
||||
keys.some(function(key, condition) {
|
||||
if(_card[key]===rules[key]) {
|
||||
_result.push(_card);
|
||||
}
|
||||
});
|
||||
});
|
||||
return _result;
|
||||
};
|
||||
});
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('cardSearchFilter', function() {
|
||||
return function(cards, searchString) {
|
||||
var _result = {};
|
||||
var rules = {
|
||||
title: searchString,
|
||||
//owner: searchString,
|
||||
};
|
||||
angular.forEach(cards, function(card){
|
||||
var _card = card;
|
||||
Object.keys(rules).some(function(rule) {
|
||||
if(_card[rule].search(rules[rule])>=0) {
|
||||
_result[_card.id] = _card;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return $.map(_result, function(value, index) {
|
||||
return [value];
|
||||
});
|
||||
};
|
||||
});
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global app */
|
||||
/* global OC */
|
||||
/* global moment */
|
||||
|
||||
app.filter('relativeDateFilter', function() {
|
||||
return function (timestamp) {
|
||||
return OC.Util.relativeModifiedDate(timestamp*1000);
|
||||
};
|
||||
});
|
||||
|
||||
app.filter('relativeDateFilterString', function() {
|
||||
return function (date) {
|
||||
return OC.Util.relativeModifiedDate(Date.parse(date));
|
||||
};
|
||||
});
|
||||
|
||||
app.filter('dateToTimestamp', function() {
|
||||
return function (date) {
|
||||
return Date.parse(date);
|
||||
};
|
||||
});
|
||||
|
||||
app.filter('parseDate', function() {
|
||||
return function (date) {
|
||||
if(moment(date).isValid()) {
|
||||
var dateFormat = moment.localeData().longDateFormat('L');
|
||||
return moment(date).format(dateFormat);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
});
|
||||
|
||||
app.filter('parseTime', function() {
|
||||
return function (date) {
|
||||
if(moment(date).isValid()) {
|
||||
return moment(date).format('HH:mm');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
});
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('iconWhiteFilter', function () {
|
||||
return function (hex) {
|
||||
// RGB2HLS by Garry Tan
|
||||
// http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
||||
var result = /^([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex);
|
||||
var color = result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
if (result === null) {
|
||||
return '';
|
||||
}
|
||||
var r = color.r / 255;
|
||||
var g = color.g / 255;
|
||||
var b = color.b / 255;
|
||||
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
var h, s, l = (max + min) / 2;
|
||||
|
||||
if (max === min) {
|
||||
h = s = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch (max) {
|
||||
case r:
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
break;
|
||||
case g:
|
||||
h = (b - r) / d + 2;
|
||||
break;
|
||||
case b:
|
||||
h = (r - g) / d + 4;
|
||||
break;
|
||||
}
|
||||
h /= 6;
|
||||
}
|
||||
if (l < 0.5) {
|
||||
return '-white';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('lightenColorFilter', function() {
|
||||
return function (hex) {
|
||||
var result = /^([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex);
|
||||
var color = result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
if (result !== null) {
|
||||
return 'rgba(' + color.r + ',' + color.g + ',' + color.b + ',0.7)';
|
||||
} else {
|
||||
return '#' + hex;
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('orderObjectBy', function(){
|
||||
return function(input, attribute) {
|
||||
if (!angular.isObject(input)) {
|
||||
return input;
|
||||
}
|
||||
var array = [];
|
||||
for(var objectKey in input) {
|
||||
if ({}.hasOwnProperty.call(input, objectKey)) {
|
||||
array.push(input[objectKey]);
|
||||
}
|
||||
}
|
||||
|
||||
array.sort(function(a, b){
|
||||
a = parseInt(a[attribute]);
|
||||
b = parseInt(b[attribute]);
|
||||
return a < b;
|
||||
});
|
||||
return array;
|
||||
};
|
||||
});
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.filter('textColorFilter', function () {
|
||||
return function (hex) {
|
||||
// RGB2HLS by Garry Tan
|
||||
// http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
|
||||
var result = /^#?([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex);
|
||||
var color = result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
if (result !== null) {
|
||||
var r = color.r / 255;
|
||||
var g = color.g / 255;
|
||||
var b = color.b / 255;
|
||||
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
var h, s, l = (max + min) / 2;
|
||||
|
||||
if (max === min) {
|
||||
h = s = 0; // achromatic
|
||||
} else {
|
||||
var d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch (max) {
|
||||
case r:
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
break;
|
||||
case g:
|
||||
h = (b - r) / d + 2;
|
||||
break;
|
||||
case b:
|
||||
h = (r - g) / d + 4;
|
||||
break;
|
||||
}
|
||||
h /= 6;
|
||||
}
|
||||
if (l < 0.5) {
|
||||
return '#ffffff';
|
||||
} else {
|
||||
return '#000000';
|
||||
}
|
||||
} else {
|
||||
return '#000000';
|
||||
}
|
||||
|
||||
};
|
||||
});
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2017 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global app */
|
||||
/* global angular */
|
||||
|
||||
/*
|
||||
* Remove all assignedUsers from users list
|
||||
*/
|
||||
app.filter('withoutAssignedUsers', function () {
|
||||
return function (users, assignedUsers) {
|
||||
var _result = [];
|
||||
angular.forEach(users, function (user) {
|
||||
var _found = false;
|
||||
angular.forEach(assignedUsers, function (assignedUser) {
|
||||
if (assignedUser.participant.uid === user.uid) {
|
||||
_found = true;
|
||||
}
|
||||
});
|
||||
if (_found === false) {
|
||||
_result.push(user);
|
||||
}
|
||||
});
|
||||
return _result;
|
||||
};
|
||||
});
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2019 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/* global __webpack_nonce__ __webpack_public_path__ OC t n */
|
||||
// eslint-disable-next-line
|
||||
__webpack_nonce__ = btoa(OC.requestToken);
|
||||
// eslint-disable-next-line
|
||||
__webpack_public_path__ = OC.linkTo('deck', 'js/build/');
|
||||
|
||||
import Vue from 'vue';
|
||||
|
||||
Vue.prototype.t = t;
|
||||
Vue.prototype.n = n;
|
||||
Vue.prototype.OC = OC;
|
||||
|
||||
import BoardSelector from './views/BoardSelector';
|
||||
|
||||
import './../css/collections.css';
|
||||
|
||||
((function(OCP) {
|
||||
|
||||
OCP.Collaboration.registerType('deck', {
|
||||
action: () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const container = document.createElement('div');
|
||||
container.id = 'deck-board-select';
|
||||
const body = document.getElementById('body-user');
|
||||
body.append(container);
|
||||
const ComponentVM = new Vue({
|
||||
render: h => h(BoardSelector),
|
||||
});
|
||||
ComponentVM.$mount(container);
|
||||
ComponentVM.$root.$on('close', () => {
|
||||
ComponentVM.$el.remove();
|
||||
ComponentVM.$destroy();
|
||||
reject();
|
||||
});
|
||||
ComponentVM.$root.$on('select', (id) => {
|
||||
resolve(id);
|
||||
ComponentVM.$el.remove();
|
||||
ComponentVM.$destroy();
|
||||
});
|
||||
});
|
||||
},
|
||||
typeString: t('deck', 'Link to a board'),
|
||||
typeIconClass: 'icon-deck'
|
||||
});
|
||||
})(window.OCP));
|
||||
36
js/init.js
36
js/init.js
@@ -1,36 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/* global __webpack_nonce__ __webpack_public_path__ OC t n */
|
||||
// eslint-disable-next-line
|
||||
__webpack_nonce__ = btoa(OC.requestToken);
|
||||
// eslint-disable-next-line
|
||||
__webpack_public_path__ = OC.linkTo('deck', 'js/build/');
|
||||
|
||||
// used for building a vendor stylesheet
|
||||
import 'ng-sortable/dist/ng-sortable.css';
|
||||
|
||||
import angular from 'angular';
|
||||
import markdownit from 'markdown-it';
|
||||
global.markdownit = markdownit;
|
||||
|
||||
import app from './app/App.js';
|
||||
import './app/Config.js';
|
||||
import './app/Run.js';
|
||||
|
||||
|
||||
import ListController from 'controller/ListController.js';
|
||||
import attachmentListComponent from './controller/AttachmentController.js';
|
||||
import activityComponent from './controller/ActivityController.js';
|
||||
|
||||
app.controller('ListController', ListController);
|
||||
app.component('attachmentListComponent', attachmentListComponent);
|
||||
app.component('activityComponent', activityComponent);
|
||||
|
||||
|
||||
// require all the js files from subdirectories
|
||||
var context = require.context('.', true, /(controller|service|filters|directive)\/(.*)\.js$/);
|
||||
|
||||
context.keys().forEach(function (key) {
|
||||
context(key);
|
||||
});
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
/**
|
||||
* @licence
|
||||
*/
|
||||
|
||||
import CommentModel from './commentmodel.js';
|
||||
import CommentSummaryModel from './commentsummarymodel.js';
|
||||
|
||||
/**
|
||||
* @class CommentCollection
|
||||
* @classdesc
|
||||
*
|
||||
* Collection of comments assigned to a file
|
||||
*
|
||||
*/
|
||||
var CommentCollection = OC.Backbone.Collection.extend(
|
||||
/** @lends OCA.AnnouncementCenter.Comments.CommentCollection.prototype */ {
|
||||
|
||||
sync: OC.Backbone.davSync,
|
||||
|
||||
model: CommentModel,
|
||||
|
||||
/**
|
||||
* Object type
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectType: 'deckCard',
|
||||
|
||||
/**
|
||||
* Object id
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectId: null,
|
||||
|
||||
/**
|
||||
* True if there are no more page results left to fetch
|
||||
*
|
||||
* @type bool
|
||||
*/
|
||||
_endReached: false,
|
||||
|
||||
/**
|
||||
* Number of comments to fetch per page
|
||||
*
|
||||
* @type int
|
||||
*/
|
||||
_limit : 5,
|
||||
|
||||
/**
|
||||
* Initializes the collection
|
||||
*
|
||||
* @param {string} [options.objectType] object type
|
||||
* @param {string} [options.objectId] object id
|
||||
*/
|
||||
initialize: function(models, options) {
|
||||
options = options || {};
|
||||
if (options.objectType) {
|
||||
this._objectType = options.objectType;
|
||||
}
|
||||
if (options.objectId) {
|
||||
this._objectId = options.objectId;
|
||||
}
|
||||
},
|
||||
|
||||
url: function() {
|
||||
return OC.linkToRemote('dav') + '/comments/' +
|
||||
encodeURIComponent(this._objectType) + '/' +
|
||||
encodeURIComponent(this._objectId) + '/';
|
||||
},
|
||||
|
||||
setObjectId: function(objectId) {
|
||||
this._objectId = objectId;
|
||||
},
|
||||
|
||||
hasMoreResults: function() {
|
||||
return !this._endReached;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this._endReached = false;
|
||||
this._summaryModel = null;
|
||||
return OC.Backbone.Collection.prototype.reset.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch the next set of results
|
||||
*/
|
||||
fetchNext: function(options) {
|
||||
var self = this;
|
||||
if (!this.hasMoreResults()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var body = '<?xml version="1.0" encoding="utf-8" ?>\n' +
|
||||
'<oc:filter-comments xmlns:D="DAV:" xmlns:oc="http://owncloud.org/ns">\n' +
|
||||
// load one more so we know there is more
|
||||
' <oc:limit>' + (this._limit + 1) + '</oc:limit>\n' +
|
||||
' <oc:offset>' + this.length + '</oc:offset>\n' +
|
||||
'</oc:filter-comments>\n';
|
||||
|
||||
options = options || {};
|
||||
var success = options.success;
|
||||
options = _.extend({
|
||||
remove: false,
|
||||
parse: true,
|
||||
data: body,
|
||||
davProperties: CommentCollection.prototype.model.prototype.davProperties,
|
||||
success: function(resp) {
|
||||
if (resp.length <= self._limit) {
|
||||
// no new entries, end reached
|
||||
self._endReached = true;
|
||||
} else {
|
||||
// remove last entry, for next page load
|
||||
resp = _.initial(resp);
|
||||
}
|
||||
if (!self.set(resp, options)) {
|
||||
return false;
|
||||
}
|
||||
if (success) {
|
||||
success.apply(null, arguments);
|
||||
}
|
||||
self.trigger('sync', 'REPORT', self, options);
|
||||
}
|
||||
}, options);
|
||||
|
||||
return this.sync('REPORT', this, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the matching summary model
|
||||
*
|
||||
* @return {OCA.AnnouncementCenter.Comments.CommentSummaryModel} summary model
|
||||
*/
|
||||
getSummaryModel: function() {
|
||||
if (!this._summaryModel) {
|
||||
this._summaryModel = new CommentSummaryModel({
|
||||
id: this._objectId,
|
||||
objectType: this._objectType
|
||||
});
|
||||
}
|
||||
return this._summaryModel;
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the read marker for this comment thread
|
||||
*
|
||||
* @param {Date} [date] optional date, defaults to now
|
||||
* @param {Object} [options] backbone options
|
||||
*/
|
||||
updateReadMarker: function(date, options) {
|
||||
options = options || {};
|
||||
|
||||
return this.getSummaryModel().save({
|
||||
readMarker: (date || new Date()).toUTCString()
|
||||
}, options);
|
||||
}
|
||||
});
|
||||
|
||||
export default CommentCollection;
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3
|
||||
* or later.
|
||||
*
|
||||
* See the COPYING-README file.
|
||||
*
|
||||
*/
|
||||
|
||||
var NS_OWNCLOUD = 'http://owncloud.org/ns';
|
||||
/**
|
||||
* @class CommentModel
|
||||
* @classdesc
|
||||
*
|
||||
* Comment
|
||||
*
|
||||
*/
|
||||
var CommentModel = OC.Backbone.Model.extend(
|
||||
/** @lends OCA.Comments.CommentModel.prototype */ {
|
||||
sync: OC.Backbone.davSync,
|
||||
|
||||
/**
|
||||
* Object type
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectType: 'deckCard',
|
||||
|
||||
/**
|
||||
* Object id
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectId: null,
|
||||
|
||||
initialize: function(model, options) {
|
||||
options = options || {};
|
||||
if (options.objectType) {
|
||||
this._objectType = options.objectType;
|
||||
}
|
||||
if (options.objectId) {
|
||||
this._objectId = options.objectId;
|
||||
}
|
||||
},
|
||||
|
||||
defaults: {
|
||||
actorType: 'users',
|
||||
objectType: 'deckCard'
|
||||
},
|
||||
|
||||
davProperties: {
|
||||
'id': '{' + NS_OWNCLOUD + '}id',
|
||||
'message': '{' + NS_OWNCLOUD + '}message',
|
||||
'actorType': '{' + NS_OWNCLOUD + '}actorType',
|
||||
'actorId': '{' + NS_OWNCLOUD + '}actorId',
|
||||
'actorDisplayName': '{' + NS_OWNCLOUD + '}actorDisplayName',
|
||||
'creationDateTime': '{' + NS_OWNCLOUD + '}creationDateTime',
|
||||
'objectType': '{' + NS_OWNCLOUD + '}objectType',
|
||||
'objectId': '{' + NS_OWNCLOUD + '}objectId',
|
||||
'isUnread': '{' + NS_OWNCLOUD + '}isUnread',
|
||||
'mentions': '{' + NS_OWNCLOUD + '}mentions'
|
||||
},
|
||||
|
||||
parse: function(data) {
|
||||
return {
|
||||
id: data.id,
|
||||
message: data.message,
|
||||
actorType: data.actorType,
|
||||
actorId: data.actorId,
|
||||
actorDisplayName: data.actorDisplayName,
|
||||
creationDateTime: data.creationDateTime,
|
||||
objectType: data.objectType,
|
||||
objectId: data.objectId,
|
||||
isUnread: (data.isUnread === 'true'),
|
||||
mentions: this._parseMentions(data.mentions)
|
||||
};
|
||||
},
|
||||
|
||||
_parseMentions: function(mentions) {
|
||||
if(_.isUndefined(mentions)) {
|
||||
return {};
|
||||
}
|
||||
var result = {};
|
||||
for(var i in mentions) {
|
||||
var mention = mentions[i];
|
||||
if(_.isUndefined(mention.localName) || mention.localName !== 'mention') {
|
||||
continue;
|
||||
}
|
||||
result[i] = {};
|
||||
for (var child = mention.firstChild; child; child = child.nextSibling) {
|
||||
if(_.isUndefined(child.localName) || !child.localName.startsWith('mention')) {
|
||||
continue;
|
||||
}
|
||||
result[i][child.localName] = child.textContent;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
url: function() {
|
||||
let baseUrl;
|
||||
if (typeof this.collection === 'undefined') {
|
||||
baseUrl = OC.linkToRemote('dav') + '/comments/' +
|
||||
encodeURIComponent(this.get('objectType')) + '/' +
|
||||
encodeURIComponent(this.get('objectId')) + '/';
|
||||
} else {
|
||||
baseUrl = this.collection.url();
|
||||
}
|
||||
if (typeof this.get('id') !== 'undefined') {
|
||||
return baseUrl + this.get('id');
|
||||
} else {
|
||||
return baseUrl;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default CommentModel;
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
|
||||
var NS_OWNCLOUD = 'http://owncloud.org/ns';
|
||||
/**
|
||||
* @class OCA.AnnouncementCenter.Comments.CommentSummaryModel
|
||||
* @classdesc
|
||||
*
|
||||
* Model containing summary information related to comments
|
||||
* like the read marker.
|
||||
*
|
||||
*/
|
||||
var CommentSummaryModel = OC.Backbone.Model.extend(
|
||||
/** @lends OCA.AnnouncementCenter.Comments.CommentSummaryModel.prototype */ {
|
||||
sync: OC.Backbone.davSync,
|
||||
|
||||
/**
|
||||
* Object type
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectType: 'deckCard',
|
||||
|
||||
/**
|
||||
* Object id
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
_objectId: null,
|
||||
|
||||
davProperties: {
|
||||
'readMarker': '{' + NS_OWNCLOUD + '}readMarker'
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the summary model
|
||||
*
|
||||
* @param {string} [options.objectType] object type
|
||||
* @param {string} [options.objectId] object id
|
||||
*/
|
||||
initialize: function(attrs, options) {
|
||||
options = options || {};
|
||||
if (options.objectType) {
|
||||
this._objectType = options.objectType;
|
||||
}
|
||||
},
|
||||
|
||||
url: function() {
|
||||
return OC.linkToRemote('dav') + '/comments/' +
|
||||
encodeURIComponent(this._objectType) + '/' +
|
||||
encodeURIComponent(this.id) + '/';
|
||||
}
|
||||
});
|
||||
|
||||
export default CommentSummaryModel;
|
||||
|
||||
1
js/legacy/jquery.atwho.min.js
vendored
1
js/legacy/jquery.atwho.min.js
vendored
File diff suppressed because one or more lines are too long
561
js/legacy/jquery.caret.min.js
vendored
561
js/legacy/jquery.caret.min.js
vendored
@@ -1,561 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
(function($, undefined) {
|
||||
|
||||
var _input = document.createElement('input');
|
||||
|
||||
var _support = {
|
||||
setSelectionRange: ('setSelectionRange' in _input) || ('selectionStart' in _input),
|
||||
createTextRange: ('createTextRange' in _input) || ('selection' in document)
|
||||
};
|
||||
|
||||
var _rNewlineIE = /\r\n/g,
|
||||
_rCarriageReturn = /\r/g;
|
||||
|
||||
var _getValue = function(input) {
|
||||
if (typeof(input.value) !== 'undefined') {
|
||||
return input.value;
|
||||
}
|
||||
return $(input).text();
|
||||
};
|
||||
|
||||
var _setValue = function(input, value) {
|
||||
if (typeof(input.value) !== 'undefined') {
|
||||
input.value = value;
|
||||
} else {
|
||||
$(input).text(value);
|
||||
}
|
||||
};
|
||||
|
||||
var _getIndex = function(input, pos) {
|
||||
var norm = _getValue(input).replace(_rCarriageReturn, '');
|
||||
var len = norm.length;
|
||||
|
||||
if (typeof(pos) === 'undefined') {
|
||||
pos = len;
|
||||
}
|
||||
|
||||
pos = Math.floor(pos);
|
||||
|
||||
// Negative index counts backward from the end of the input/textarea's value
|
||||
if (pos < 0) {
|
||||
pos = len + pos;
|
||||
}
|
||||
|
||||
// Enforce boundaries
|
||||
if (pos < 0) { pos = 0; }
|
||||
if (pos > len) { pos = len; }
|
||||
|
||||
return pos;
|
||||
};
|
||||
|
||||
var _hasAttr = function(input, attrName) {
|
||||
return input.hasAttribute ? input.hasAttribute(attrName) : (typeof(input[attrName]) !== 'undefined');
|
||||
};
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @constructor
|
||||
*/
|
||||
var Range = function(start, end, length, text) {
|
||||
this.start = start || 0;
|
||||
this.end = end || 0;
|
||||
this.length = length || 0;
|
||||
this.text = text || '';
|
||||
};
|
||||
|
||||
Range.prototype.toString = function() {
|
||||
return JSON.stringify(this, null, ' ');
|
||||
};
|
||||
|
||||
var _getCaretW3 = function(input) {
|
||||
return input.selectionStart;
|
||||
};
|
||||
|
||||
/**
|
||||
* @see http://stackoverflow.com/q/6943000/467582
|
||||
*/
|
||||
var _getCaretIE = function(input) {
|
||||
var caret, range, textInputRange, rawValue, len, endRange;
|
||||
|
||||
// Yeah, you have to focus twice for IE 7 and 8. *cries*
|
||||
input.focus();
|
||||
input.focus();
|
||||
|
||||
range = document.selection.createRange();
|
||||
|
||||
if (range && range.parentElement() === input) {
|
||||
rawValue = _getValue(input);
|
||||
|
||||
len = rawValue.length;
|
||||
|
||||
// Create a working TextRange that lives only in the input
|
||||
textInputRange = input.createTextRange();
|
||||
textInputRange.moveToBookmark(range.getBookmark());
|
||||
|
||||
// Check if the start and end of the selection are at the very end
|
||||
// of the input, since moveStart/moveEnd doesn't return what we want
|
||||
// in those cases
|
||||
endRange = input.createTextRange();
|
||||
endRange.collapse(false);
|
||||
|
||||
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
|
||||
caret = rawValue.replace(_rNewlineIE, '\n').length;
|
||||
} else {
|
||||
caret = -textInputRange.moveStart("character", -len);
|
||||
}
|
||||
|
||||
return caret;
|
||||
}
|
||||
|
||||
// NOTE: This occurs when you highlight part of a textarea and then click in the middle of the highlighted portion in IE 6-10.
|
||||
// There doesn't appear to be anything we can do about it.
|
||||
// alert("Your browser is incredibly stupid. I don't know what else to say.");
|
||||
// alert(range + '\n\n' + range.parentElement().tagName + '#' + range.parentElement().id);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the position of the caret in the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @returns {Number}
|
||||
* @see http://stackoverflow.com/questions/263743/how-to-get-cursor-position-in-textarea/263796#263796
|
||||
*/
|
||||
var _getCaret = function(input) {
|
||||
if (!input) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
return _getCaretW3(input);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
return _getCaretIE(input);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
var _setCaretW3 = function(input, pos) {
|
||||
input.setSelectionRange(pos, pos);
|
||||
};
|
||||
|
||||
var _setCaretIE = function(input, pos) {
|
||||
var range = input.createTextRange();
|
||||
range.move('character', pos);
|
||||
range.select();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the position of the caret in the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @param {Number} pos
|
||||
* @see http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
*/
|
||||
var _setCaret = function(input, pos) {
|
||||
input.focus();
|
||||
|
||||
pos = _getIndex(input, pos);
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
_setCaretW3(input, pos);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
_setCaretIE(input, pos);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Inserts the specified text at the current caret position in the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @param {String} text
|
||||
* @see http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
*/
|
||||
var _insertAtCaret = function(input, text) {
|
||||
var curPos = _getCaret(input);
|
||||
|
||||
var oldValueNorm = _getValue(input).replace(_rCarriageReturn, '');
|
||||
|
||||
var newLength = +(curPos + text.length + (oldValueNorm.length - curPos));
|
||||
var maxLength = +input.getAttribute('maxlength');
|
||||
|
||||
if(_hasAttr(input, 'maxlength') && newLength > maxLength) {
|
||||
var delta = text.length - (newLength - maxLength);
|
||||
text = text.substr(0, delta);
|
||||
}
|
||||
|
||||
_setValue(input, oldValueNorm.substr(0, curPos) + text + oldValueNorm.substr(curPos));
|
||||
|
||||
_setCaret(input, curPos + text.length);
|
||||
};
|
||||
|
||||
var _getInputRangeW3 = function(input) {
|
||||
var range = new Range();
|
||||
|
||||
range.start = input.selectionStart;
|
||||
range.end = input.selectionEnd;
|
||||
|
||||
var min = Math.min(range.start, range.end);
|
||||
var max = Math.max(range.start, range.end);
|
||||
|
||||
range.length = max - min;
|
||||
range.text = _getValue(input).substring(min, max);
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
/** @see http://stackoverflow.com/a/3648244/467582 */
|
||||
var _getInputRangeIE = function(input) {
|
||||
var range = new Range();
|
||||
|
||||
input.focus();
|
||||
|
||||
var selection = document.selection.createRange();
|
||||
|
||||
if (selection && selection.parentElement() === input) {
|
||||
var len, normalizedValue, textInputRange, endRange, start = 0, end = 0;
|
||||
var rawValue = _getValue(input);
|
||||
|
||||
len = rawValue.length;
|
||||
normalizedValue = rawValue.replace(/\r\n/g, "\n");
|
||||
|
||||
// Create a working TextRange that lives only in the input
|
||||
textInputRange = input.createTextRange();
|
||||
textInputRange.moveToBookmark(selection.getBookmark());
|
||||
|
||||
// Check if the start and end of the selection are at the very end
|
||||
// of the input, since moveStart/moveEnd doesn't return what we want
|
||||
// in those cases
|
||||
endRange = input.createTextRange();
|
||||
endRange.collapse(false);
|
||||
|
||||
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
|
||||
start = end = len;
|
||||
} else {
|
||||
start = -textInputRange.moveStart("character", -len);
|
||||
start += normalizedValue.slice(0, start).split("\n").length - 1;
|
||||
|
||||
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
|
||||
end = len;
|
||||
} else {
|
||||
end = -textInputRange.moveEnd("character", -len);
|
||||
end += normalizedValue.slice(0, end).split("\n").length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// normalize newlines
|
||||
start -= (rawValue.substring(0, start).split('\r\n').length - 1);
|
||||
end -= (rawValue.substring(0, end).split('\r\n').length - 1);
|
||||
/// normalize newlines
|
||||
|
||||
range.start = start;
|
||||
range.end = end;
|
||||
range.length = range.end - range.start;
|
||||
range.text = normalizedValue.substr(range.start, range.length);
|
||||
}
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the selected text range of the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @returns {Range}
|
||||
* @see http://stackoverflow.com/a/263796/467582
|
||||
* @see http://stackoverflow.com/a/2966703/467582
|
||||
*/
|
||||
var _getInputRange = function(input) {
|
||||
if (!input) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
return _getInputRangeW3(input);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
return _getInputRangeIE(input);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
var _setInputRangeW3 = function(input, startPos, endPos) {
|
||||
input.setSelectionRange(startPos, endPos);
|
||||
};
|
||||
|
||||
var _setInputRangeIE = function(input, startPos, endPos) {
|
||||
var tr = input.createTextRange();
|
||||
tr.moveEnd('textedit', -1);
|
||||
tr.moveStart('character', startPos);
|
||||
tr.moveEnd('character', endPos - startPos);
|
||||
tr.select();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the selected text range of (i.e., highlights text in) the given input.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @param {Number} startPos Zero-based index
|
||||
* @param {Number} endPos Zero-based index
|
||||
* @see http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
* @see http://stackoverflow.com/a/2966703/467582
|
||||
*/
|
||||
var _setInputRange = function(input, startPos, endPos) {
|
||||
startPos = _getIndex(input, startPos);
|
||||
endPos = _getIndex(input, endPos);
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
_setInputRangeW3(input, startPos, endPos);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
_setInputRangeIE(input, startPos, endPos);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Replaces the currently selected text with the given string.
|
||||
* @param {HTMLInputElement|HTMLTextAreaElement} input input or textarea element
|
||||
* @param {String} text New text that will replace the currently selected text.
|
||||
* @see http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
*/
|
||||
var _replaceInputRange = function(input, text) {
|
||||
var $input = $(input);
|
||||
|
||||
var oldValue = $input.val();
|
||||
var selection = _getInputRange(input);
|
||||
|
||||
var newLength = +(selection.start + text.length + (oldValue.length - selection.end));
|
||||
var maxLength = +$input.attr('maxlength');
|
||||
|
||||
if($input.is('[maxlength]') && newLength > maxLength) {
|
||||
var delta = text.length - (newLength - maxLength);
|
||||
text = text.substr(0, delta);
|
||||
}
|
||||
|
||||
// Now that we know what the user selected, we can replace it
|
||||
var startText = oldValue.substr(0, selection.start);
|
||||
var endText = oldValue.substr(selection.end);
|
||||
|
||||
$input.val(startText + text + endText);
|
||||
|
||||
// Reset the selection
|
||||
var startPos = selection.start;
|
||||
var endPos = startPos + text.length;
|
||||
|
||||
_setInputRange(input, selection.length ? startPos : endPos, endPos);
|
||||
};
|
||||
|
||||
var _selectAllW3 = function(elem) {
|
||||
var selection = window.getSelection();
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(elem);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
};
|
||||
|
||||
var _selectAllIE = function(elem) {
|
||||
var range = document.body.createTextRange();
|
||||
range.moveToElementText(elem);
|
||||
range.select();
|
||||
};
|
||||
|
||||
/**
|
||||
* Select all text in the given element.
|
||||
* @param {HTMLElement} elem Any block or inline element other than a form element.
|
||||
*/
|
||||
var _selectAll = function(elem) {
|
||||
var $elem = $(elem);
|
||||
if ($elem.is('input, textarea') || elem.select) {
|
||||
$elem.select();
|
||||
return;
|
||||
}
|
||||
|
||||
// Mozilla, et al.
|
||||
if (_support.setSelectionRange) {
|
||||
_selectAllW3(elem);
|
||||
}
|
||||
// IE
|
||||
else if (_support.createTextRange) {
|
||||
_selectAllIE(elem);
|
||||
}
|
||||
};
|
||||
|
||||
var _deselectAll = function() {
|
||||
if (document.selection) {
|
||||
document.selection.empty();
|
||||
}
|
||||
else if (window.getSelection) {
|
||||
window.getSelection().removeAllRanges();
|
||||
}
|
||||
};
|
||||
|
||||
$.extend($.fn, {
|
||||
|
||||
/**
|
||||
* Gets or sets the position of the caret or inserts text at the current caret position in an input or textarea element.
|
||||
* @returns {Number|jQuery} The current caret position if invoked as a getter (with no arguments)
|
||||
* or this jQuery object if invoked as a setter or inserter.
|
||||
* @see http://web.archive.org/web/20080704185920/http://parentnode.org/javascript/working-with-the-cursor-position/
|
||||
* @since 1.0.0
|
||||
* @example
|
||||
* <pre>
|
||||
* // Get position
|
||||
* var pos = $('input:first').caret();
|
||||
* </pre>
|
||||
* @example
|
||||
* <pre>
|
||||
* // Set position
|
||||
* $('input:first').caret(15);
|
||||
* $('input:first').caret(-3);
|
||||
* </pre>
|
||||
* @example
|
||||
* <pre>
|
||||
* // Insert text at current position
|
||||
* $('input:first').caret('Some text');
|
||||
* </pre>
|
||||
*/
|
||||
caret: function() {
|
||||
var $inputs = this.filter('input, textarea');
|
||||
|
||||
// getCaret()
|
||||
if (arguments.length === 0) {
|
||||
var input = $inputs.get(0);
|
||||
return _getCaret(input);
|
||||
}
|
||||
// setCaret(position)
|
||||
else if (typeof arguments[0] === 'number') {
|
||||
var pos = arguments[0];
|
||||
$inputs.each(function(_i, input) {
|
||||
_setCaret(input, pos);
|
||||
});
|
||||
}
|
||||
// insertAtCaret(text)
|
||||
else {
|
||||
var text = arguments[0];
|
||||
$inputs.each(function(_i, input) {
|
||||
_insertAtCaret(input, text);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets or sets the selection range or replaces the currently selected text in an input or textarea element.
|
||||
* @returns {Range|jQuery} The current selection range if invoked as a getter (with no arguments)
|
||||
* or this jQuery object if invoked as a setter or replacer.
|
||||
* @see http://stackoverflow.com/a/2966703/467582
|
||||
* @since 1.0.0
|
||||
* @example
|
||||
* <pre>
|
||||
* // Get selection range
|
||||
* var range = $('input:first').range();
|
||||
* </pre>
|
||||
* @example
|
||||
* <pre>
|
||||
* // Set selection range
|
||||
* $('input:first').range(15);
|
||||
* $('input:first').range(15, 20);
|
||||
* $('input:first').range(-3);
|
||||
* $('input:first').range(-8, -3);
|
||||
* </pre>
|
||||
* @example
|
||||
* <pre>
|
||||
* // Replace the currently selected text
|
||||
* $('input:first').range('Replacement text');
|
||||
* </pre>
|
||||
*/
|
||||
range: function() {
|
||||
var $inputs = this.filter('input, textarea');
|
||||
|
||||
// getRange() = { start: pos, end: pos }
|
||||
if (arguments.length === 0) {
|
||||
var input = $inputs.get(0);
|
||||
return _getInputRange(input);
|
||||
}
|
||||
// setRange(startPos, endPos)
|
||||
else if (typeof arguments[0] === 'number') {
|
||||
var startPos = arguments[0];
|
||||
var endPos = arguments[1];
|
||||
$inputs.each(function(_i, input) {
|
||||
_setInputRange(input, startPos, endPos);
|
||||
});
|
||||
}
|
||||
// replaceRange(text)
|
||||
else {
|
||||
var text = arguments[0];
|
||||
$inputs.each(function(_i, input) {
|
||||
_replaceInputRange(input, text);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects all text in each element of this jQuery object.
|
||||
* @returns {jQuery} This jQuery object
|
||||
* @see http://stackoverflow.com/a/11128179/467582
|
||||
* @since 1.5.0
|
||||
* @example
|
||||
* <pre>
|
||||
* // Select the contents of span elements when clicked
|
||||
* $('span').on('click', function() { $(this).highlight(); });
|
||||
* </pre>
|
||||
*/
|
||||
selectAll: function() {
|
||||
return this.each(function(_i, elem) {
|
||||
_selectAll(elem);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$.extend($, {
|
||||
/**
|
||||
* Deselects all text on the page.
|
||||
* @returns {jQuery} The jQuery function
|
||||
* @since 1.5.0
|
||||
* @example
|
||||
* <pre>
|
||||
* // Select some text
|
||||
* $('span').selectAll();
|
||||
*
|
||||
* // Deselect the text
|
||||
* $.deselectAll();
|
||||
* </pre>
|
||||
*/
|
||||
deselectAll: function() {
|
||||
_deselectAll();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
}(window.jQuery || window.Zepto || window.$));
|
||||
57
js/legacy/jquery.ui.timepicker.css
vendored
57
js/legacy/jquery.ui.timepicker.css
vendored
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Timepicker stylesheet
|
||||
* Highly inspired from datepicker
|
||||
* FG - Nov 2010 - Web3R
|
||||
*
|
||||
* version 0.0.3 : Fixed some settings, more dynamic
|
||||
* version 0.0.4 : Removed width:100% on tables
|
||||
* version 0.1.1 : set width 0 on tables to fix an ie6 bug
|
||||
*/
|
||||
|
||||
.ui-timepicker-inline { display: inline; }
|
||||
|
||||
#ui-timepicker-div { padding: 0.2em; }
|
||||
.ui-timepicker-table { display: inline-table; width: 0; }
|
||||
.ui-timepicker-table table { margin:0.15em 0 0 0; border-collapse: collapse; }
|
||||
|
||||
.ui-timepicker-hours, .ui-timepicker-minutes { padding: 0.2em; }
|
||||
|
||||
.ui-timepicker-table .ui-timepicker-title { line-height: 1.8em; text-align: center; }
|
||||
.ui-timepicker-table td { padding: 0.1em; width: 2.2em; }
|
||||
.ui-timepicker-table th.periods { padding: 0.1em; width: 2.2em; }
|
||||
|
||||
/* span for disabled cells */
|
||||
.ui-timepicker-table td span {
|
||||
display:block;
|
||||
padding:0.2em 0.3em 0.2em 0.5em;
|
||||
width: 1.2em;
|
||||
|
||||
text-align:right;
|
||||
text-decoration:none;
|
||||
}
|
||||
/* anchors for clickable cells */
|
||||
.ui-timepicker-table td a {
|
||||
display:block;
|
||||
padding:0.2em 0.3em 0.2em 0.5em;
|
||||
width: 1.2em;
|
||||
cursor: pointer;
|
||||
text-align:right;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
|
||||
/* buttons and button pane styling */
|
||||
.ui-timepicker .ui-timepicker-buttonpane {
|
||||
background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0;
|
||||
}
|
||||
.ui-timepicker .ui-timepicker-buttonpane button { margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
|
||||
/* The close button */
|
||||
.ui-timepicker .ui-timepicker-close { float: right }
|
||||
|
||||
/* the now button */
|
||||
.ui-timepicker .ui-timepicker-now { float: left; }
|
||||
|
||||
/* the deselect button */
|
||||
.ui-timepicker .ui-timepicker-deselect { float: left; }
|
||||
|
||||
|
||||
1496
js/legacy/jquery.ui.timepicker.js
vendored
1496
js/legacy/jquery.ui.timepicker.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,120 +0,0 @@
|
||||
/**
|
||||
* Original source code from https://github.com/mcecot/markdown-it-checkbox
|
||||
* © 2015 Markus Cecot
|
||||
* licenced under MIT
|
||||
* https://github.com/mcecot/markdown-it-checkbox/blob/master/LICENSE
|
||||
*/
|
||||
var checkboxReplace;
|
||||
|
||||
checkboxReplace = function(md, options, Token) {
|
||||
"use strict";
|
||||
var arrayReplaceAt, createTokens, defaults, lastId, pattern, splitTextToken;
|
||||
arrayReplaceAt = md.utils.arrayReplaceAt;
|
||||
lastId = 0;
|
||||
defaults = {
|
||||
divWrap: false,
|
||||
divClass: 'checkbox',
|
||||
idPrefix: 'checkbox'
|
||||
};
|
||||
options = Object.assign(defaults, options);
|
||||
pattern = /(.*?)(\[(X|\s|\_|\-)\])(.*)/igm;
|
||||
createTokens = function(checked, label, Token, before) {
|
||||
var id, idNumeric, nodes, token;
|
||||
nodes = [];
|
||||
|
||||
token = new Token("text", "", 0);
|
||||
token.content = before;
|
||||
nodes.push(token);
|
||||
|
||||
/**
|
||||
* <div class="checkbox">
|
||||
*/
|
||||
if (options.divWrap) {
|
||||
token = new Token("checkbox_open", "div", 1);
|
||||
token.attrs = [["class", options.divClass]];
|
||||
nodes.push(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* <input type="checkbox" id="checkbox{n}" checked="true">
|
||||
*/
|
||||
id = options.idPrefix + lastId;
|
||||
idNumeric = lastId;
|
||||
lastId += 1;
|
||||
token = new Token("checkbox_input", "input", 0);
|
||||
token.attrs = [["type", "checkbox"], ["id", id], ["data-id", idNumeric]];
|
||||
if (checked === true) {
|
||||
token.attrs.push(["checked", "true"]);
|
||||
}
|
||||
token.attrs.push(["class", "checkbox"]);
|
||||
nodes.push(token);
|
||||
|
||||
/**
|
||||
* <label for="checkbox{n}">
|
||||
*/
|
||||
token = new Token("label_open", "label", 1);
|
||||
token.attrs = [["for", id], ["data-id", idNumeric]];
|
||||
nodes.push(token);
|
||||
|
||||
/**
|
||||
* content of label tag
|
||||
*/
|
||||
token = new Token("text", "", 0);
|
||||
token.content = label;
|
||||
nodes.push(token);
|
||||
|
||||
/**
|
||||
* closing tags
|
||||
*/
|
||||
nodes.push(new Token("label_close", "label", -1));
|
||||
if (options.divWrap) {
|
||||
nodes.push(new Token("checkbox_close", "div", -1));
|
||||
}
|
||||
return nodes;
|
||||
};
|
||||
splitTextToken = function(original, Token) {
|
||||
var checked, label, matches, text, value, before;
|
||||
text = original.content;
|
||||
matches = pattern.exec(text);
|
||||
if (matches === null) {
|
||||
return original;
|
||||
}
|
||||
checked = false;
|
||||
before = matches[1];
|
||||
value = matches[3];
|
||||
label = matches[4];
|
||||
if (value === "X" || value === "x") {
|
||||
checked = true;
|
||||
}
|
||||
return createTokens(checked, label, Token, before);
|
||||
};
|
||||
return function(state) {
|
||||
lastId = 0;
|
||||
var blockTokens, i, j, l, token, tokens;
|
||||
blockTokens = state.tokens;
|
||||
j = 0;
|
||||
l = blockTokens.length;
|
||||
while (j < l) {
|
||||
if (blockTokens[j].type !== "inline") {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
tokens = blockTokens[j].children;
|
||||
i = 0;
|
||||
while (i < tokens.length) {
|
||||
token = tokens[i];
|
||||
blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, splitTextToken(token, state.Token));
|
||||
i++;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*global module */
|
||||
|
||||
module.exports = function(md, options) {
|
||||
"use strict";
|
||||
md.core.ruler.push("checkbox", checkboxReplace(md, options));
|
||||
};
|
||||
7477
js/package-lock.json
generated
7477
js/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"name": "deck",
|
||||
"description": "Frontend for the Nextcloud Deck app",
|
||||
"repository": "https://github.com/nextcloud/deck",
|
||||
"version": "1.0.0",
|
||||
"directories": {
|
||||
"test": "tests"
|
||||
},
|
||||
"dependencies": {
|
||||
"@uirouter/angularjs": "^1.0.22",
|
||||
"angular": "^1.7.8",
|
||||
"angular-animate": "^1.7.8",
|
||||
"angular-file-upload": "^2.5.0",
|
||||
"angular-markdown-it": "^0.6.1",
|
||||
"angular-sanitize": "^1.7.8",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"markdown-it": "^8.4.2",
|
||||
"markdown-it-link-target": "^1.0.2",
|
||||
"nextcloud-axios": "^0.1.3",
|
||||
"nextcloud-vue": "^0.10.0",
|
||||
"nextcloud-vue-collections": "^0.4.0",
|
||||
"ng-infinite-scroll": "^1.3.0",
|
||||
"ng-sortable": "^1.3.8",
|
||||
"ui-select": "^0.19.8",
|
||||
"vue": "^2.6.10",
|
||||
"vuex": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.4.3",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/polyfill": "^7.4.3",
|
||||
"@babel/preset-env": "^7.4.3",
|
||||
"babel-loader": "^8.0.5",
|
||||
"css-loader": "^2.1.1",
|
||||
"karma": "^4.1.0",
|
||||
"mini-css-extract-plugin": "^0.6.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"uglifyjs-webpack-plugin": "^2.1.2",
|
||||
"url-loader": "^1.1.2",
|
||||
"vue-loader": "^15.7.0",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"webpack": "^4.30.0",
|
||||
"webpack-cli": "^3.3.0",
|
||||
"webpack-merge": "^4.2.1"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=production ./node_modules/webpack-cli/bin/cli.js --mode production --config webpack.prod.config.js",
|
||||
"dev": "./node_modules/webpack-cli/bin/cli.js --mode development --config webpack.dev.config.js",
|
||||
"watch": "./node_modules/webpack-cli/bin/cli.js --mode development --config webpack.dev.config.js --watch",
|
||||
"test": "echo \"Warning: no test specified\" && exit 0"
|
||||
},
|
||||
"author": "",
|
||||
"license": "AGPL-3.0",
|
||||
"keywords": []
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
import CommentCollection from '../legacy/commentcollection';
|
||||
import CommentModel from '../legacy/commentmodel';
|
||||
|
||||
const DECK_ACTIVITY_TYPE_BOARD = 'deck_board';
|
||||
const DECK_ACTIVITY_TYPE_CARD = 'deck_card';
|
||||
|
||||
/* global OC oc_requesttoken */
|
||||
class ActivityService {
|
||||
|
||||
static get RESULT_PER_PAGE() { return 50; }
|
||||
|
||||
constructor ($rootScope, $filter, $http, $q) {
|
||||
this.running = false;
|
||||
this.runningNewer = false;
|
||||
this.$filter = $filter;
|
||||
this.$http = $http;
|
||||
this.$q = $q;
|
||||
this.$rootScope = $rootScope;
|
||||
this.data = {};
|
||||
this.data[DECK_ACTIVITY_TYPE_BOARD] = {};
|
||||
this.data[DECK_ACTIVITY_TYPE_CARD] = {};
|
||||
this.toEnhanceWithComments = [];
|
||||
this.commentCollection = new CommentCollection();
|
||||
this.commentCollection._limit = ActivityService.RESULT_PER_PAGE;
|
||||
this.commentCollection.on('request', function() {
|
||||
}, this);
|
||||
this.commentCollection.on('sync', function(a) {
|
||||
for (let index in this.toEnhanceWithComments) {
|
||||
if (this.toEnhanceWithComments.hasOwnProperty(index)) {
|
||||
let item = this.toEnhanceWithComments[index];
|
||||
let commentId = Array.isArray(item.subject_rich[1].comment) ? item.subject_rich[1].comment.id : item.subject_rich[1].comment;
|
||||
item.commentModel = this.commentCollection.get(commentId);
|
||||
if (typeof item.commentModel !== 'undefined') {
|
||||
this.toEnhanceWithComments = this.toEnhanceWithComments.filter((entry) => entry.activity_id !== item.activity_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
var firstUnread = this.commentCollection.findWhere({isUnread: true});
|
||||
if (typeof firstUnread !== 'undefined') {
|
||||
this.commentCollection.updateReadMarker();
|
||||
}
|
||||
this.notify();
|
||||
}, this);
|
||||
this.commentCollection.on('add', function(model, collection, options) {
|
||||
// we need to update the model, because it consists of client data
|
||||
// only, but the server might add meta data, e.g. about mentions
|
||||
model.fetch();
|
||||
}, this);
|
||||
this.since = {
|
||||
deck_card: {
|
||||
|
||||
},
|
||||
deck_board: {
|
||||
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* We need a event here to properly update scope once the external data from
|
||||
* the comments backbone js code has changed
|
||||
*/
|
||||
subscribe(scope, callback) {
|
||||
let handler = this.$rootScope.$on('notify-comment-update', callback);
|
||||
scope.$on('$destroy', handler);
|
||||
}
|
||||
|
||||
notify() {
|
||||
this.$rootScope.$emit('notify-comment-update');
|
||||
}
|
||||
|
||||
static getUrl(type, id, since) {
|
||||
if (type === DECK_ACTIVITY_TYPE_CARD) {
|
||||
return OC.linkToOCS('apps/activity/api/v2/activity', 2) + 'filter?format=json&object_type=deck_card&object_id=' + id + '&limit=' + this.RESULT_PER_PAGE + '&since=' + since;
|
||||
}
|
||||
if (type === DECK_ACTIVITY_TYPE_BOARD) {
|
||||
return OC.linkToOCS('apps/activity/api/v2/activity', 2) + 'deck?format=json&limit=' + this.RESULT_PER_PAGE + '&since=' + since;
|
||||
}
|
||||
}
|
||||
|
||||
fetchCardActivities(type, id, since) {
|
||||
this.running = true;
|
||||
|
||||
this.checkData(type, id);
|
||||
const self = this;
|
||||
return this.$http.get(ActivityService.getUrl(type, id, since)).then(function (response) {
|
||||
const objects = response.data.ocs.data;
|
||||
|
||||
for (let index in objects) {
|
||||
if (objects.hasOwnProperty(index)) {
|
||||
let item = objects[index];
|
||||
self.addItem(type, id, item);
|
||||
if (item.activity_id > self.since[type][id].latest) {
|
||||
self.since[type][id].latest = item.activity_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.data[type][id].sort(function(a, b) {
|
||||
return b.activity_id - a.activity_id;
|
||||
});
|
||||
self.since[type][id].oldest = response.headers('X-Activity-Last-Given');
|
||||
self.running = false;
|
||||
return response;
|
||||
}, function (error) {
|
||||
if (error.status === 304 || error.status === 404) {
|
||||
self.since[type][id].finished = true;
|
||||
}
|
||||
self.running = false;
|
||||
});
|
||||
}
|
||||
|
||||
fetchMoreActivities(type, id, success) {
|
||||
const self = this;
|
||||
this.checkData(type, id);
|
||||
if (this.running === true) {
|
||||
return this.runningPromise;
|
||||
}
|
||||
if (!this.since[type][id].finished) {
|
||||
this.runningPromise = this.fetchCardActivities(type, id, this.since[type][id].oldest);
|
||||
this.runningPromise.then(function() {
|
||||
if (type === 'deck_card') {
|
||||
self.commentCollection.fetchNext();
|
||||
}
|
||||
});
|
||||
return this.runningPromise;
|
||||
}
|
||||
return Promise.reject();
|
||||
}
|
||||
checkData(type, id) {
|
||||
if (!Array.isArray(this.data[type][id])) {
|
||||
this.data[type][id] = [];
|
||||
}
|
||||
if (typeof this.since[type][id] === 'undefined') {
|
||||
this.since[type][id] = {
|
||||
latest: -1,
|
||||
oldestCatchedUp: false,
|
||||
oldest: '0',
|
||||
finished: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
addItem(type, id, item) {
|
||||
const self = this;
|
||||
const existingEntry = this.data[type][id].findIndex((entry) => { return entry.activity_id === item.activity_id; });
|
||||
if (existingEntry !== -1) {
|
||||
return;
|
||||
}
|
||||
/** check if the fetched item from all deck activities is actually related */
|
||||
const isUnrelatedBoard = (item.object_type === DECK_ACTIVITY_TYPE_BOARD && item.object_id !== id);
|
||||
const isUnrelatedCard = (item.object_type === DECK_ACTIVITY_TYPE_CARD && (
|
||||
(item.subject_rich[1].board && item.subject_rich[1].board.id !== id) || (typeof item.subject_rich[1].board === 'undefined'))
|
||||
);
|
||||
if (type === DECK_ACTIVITY_TYPE_BOARD && (isUnrelatedBoard || isUnrelatedCard)) {
|
||||
return;
|
||||
}
|
||||
item.timestamp = new Date(item.datetime).getTime();
|
||||
item.type = 'activity';
|
||||
if (item.subject_rich[1].comment) {
|
||||
item.type = 'comment';
|
||||
item.commentModel = this.commentCollection.get(item.subject_rich[1].comment);
|
||||
if (typeof item.commentModel === 'undefined') {
|
||||
this.toEnhanceWithComments.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
this.data[type][id].push(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch newer activities starting from the latest ones that are in cache
|
||||
*
|
||||
* @param type
|
||||
* @param id
|
||||
*/
|
||||
fetchNewerActivities(type, id) {
|
||||
if (this.since[type][id].latest === 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
let self = this;
|
||||
return this.fetchNewer(type, id).then(function() {
|
||||
return self.fetchNewerActivities(type, id);
|
||||
});
|
||||
}
|
||||
|
||||
fetchNewer(type, id) {
|
||||
const deferred = this.$q.defer();
|
||||
this.running = true;
|
||||
this.runningNewer = true;
|
||||
const self = this;
|
||||
this.$http.get(ActivityService.getUrl(type, id, this.since[type][id].latest) + '&sort=asc').then(function (response) {
|
||||
let objects = response.data.ocs.data;
|
||||
|
||||
let data = [];
|
||||
for (let index in objects) {
|
||||
if (objects.hasOwnProperty(index)) {
|
||||
let item = objects[index];
|
||||
self.addItem(type, id, item);
|
||||
}
|
||||
}
|
||||
self.data[type][id].sort(function(a, b) {
|
||||
return b.activity_id - a.activity_id;
|
||||
});
|
||||
self.since[type][id].latest = response.headers('X-Activity-Last-Given');
|
||||
self.data[type][id] = data.concat(self.data[type][id]);
|
||||
self.running = false;
|
||||
self.runningNewer = false;
|
||||
deferred.resolve(objects);
|
||||
}, function (error) {
|
||||
self.runningNewer = false;
|
||||
self.running = false;
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
getData(type, id) {
|
||||
if (!Array.isArray(this.data[type][id])) {
|
||||
return [];
|
||||
}
|
||||
return this.data[type][id];
|
||||
}
|
||||
|
||||
loadComments(id) {
|
||||
this.commentCollection.reset();
|
||||
this.commentCollection.setObjectId(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.service('ActivityService', ActivityService);
|
||||
|
||||
export default ActivityService;
|
||||
export {DECK_ACTIVITY_TYPE_BOARD, DECK_ACTIVITY_TYPE_CARD};
|
||||
@@ -1,232 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
/** global: oc_defaults */
|
||||
app.factory('ApiService', function ($http, $q) {
|
||||
var ApiService = function (http, endpoint) {
|
||||
// Consider renaming endpoint to resource
|
||||
this.endpoint = endpoint;
|
||||
this.baseUrl = this.generateUrl(this.endpoint);
|
||||
this.http = http;
|
||||
this.q = $q;
|
||||
this.data = {};
|
||||
this.deleted = {};
|
||||
this.id = null;
|
||||
this.sorted = [];
|
||||
};
|
||||
|
||||
ApiService.prototype.generateUrl = function(path) {
|
||||
return OC.generateUrl('/apps/deck/' + path);
|
||||
};
|
||||
|
||||
ApiService.prototype.tryAllThenDeleted = function(id) {
|
||||
let object = this.data[id];
|
||||
if (object === undefined) {
|
||||
object = this.deleted[id];
|
||||
}
|
||||
return object;
|
||||
};
|
||||
|
||||
ApiService.prototype.fetchAll = function () {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.get(this.baseUrl).then(function (response) {
|
||||
var objects = response.data;
|
||||
objects.forEach(function (obj) {
|
||||
self.data[obj.id] = obj;
|
||||
});
|
||||
deferred.resolve(self.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Fetching ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ApiService.prototype.fetchDeleted = function (scopeId) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
self.deleted = {};
|
||||
$http.get(this.generateUrl(scopeId + '/' + this.endpoint + '/deleted')).then(function (response) {
|
||||
var objects = response.data;
|
||||
objects.forEach(function (obj) {
|
||||
if(self.deleted[obj.id] !== undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.deleted[obj.id] = obj;
|
||||
|
||||
if(self.afterFetch !== undefined) {
|
||||
self.afterFetch(obj);
|
||||
}
|
||||
});
|
||||
deferred.resolve(objects);
|
||||
}, function (error) {
|
||||
deferred.reject('Fetching ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
|
||||
ApiService.prototype.fetchOne = function (id) {
|
||||
|
||||
this.id = id;
|
||||
var deferred = $q.defer();
|
||||
|
||||
if (id === undefined) {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
$http.get(this.baseUrl + '/' + id).then(function (response) {
|
||||
var data = response.data;
|
||||
if (self.data[data.id] === undefined) {
|
||||
self.data[data.id] = response.data;
|
||||
}
|
||||
$.each(response.data, function (key, value) {
|
||||
self.data[data.id][key] = value;
|
||||
});
|
||||
deferred.resolve(response.data);
|
||||
|
||||
}, function (error) {
|
||||
deferred.reject('Fetching ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ApiService.prototype.create = function (entity) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.post(this.baseUrl, entity).then(function (response) {
|
||||
self.add(response.data);
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject(error.data.message);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ApiService.prototype.update = function (entity) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + entity.id, entity).then(function (response) {
|
||||
self.add(response.data);
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject(error.data.message);
|
||||
});
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
ApiService.prototype.delete = function (id) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
|
||||
$http.delete(this.baseUrl + '/' + id).then(function (response) {
|
||||
self.deleted[id] = self.data[id];
|
||||
delete self.data[id];
|
||||
|
||||
let deletedAt = response.data.deletedAt;
|
||||
if (deletedAt !== undefined) {
|
||||
self.deleted[id].deletedAt = deletedAt;
|
||||
}
|
||||
|
||||
deferred.resolve(response.data);
|
||||
|
||||
}, function (error) {
|
||||
deferred.reject('Deleting ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
ApiService.prototype.undoDelete = function(entity) {
|
||||
var self = this;
|
||||
entity.deletedAt = 0;
|
||||
|
||||
var promise = this.update(entity);
|
||||
|
||||
promise.then(() => {
|
||||
self.data[entity.id] = entity;
|
||||
delete this.deleted[entity.id];
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
// methods for managing data
|
||||
ApiService.prototype.clear = function () {
|
||||
this.data = {};
|
||||
};
|
||||
|
||||
ApiService.prototype.add = function (entity) {
|
||||
var element = this.data[entity.id];
|
||||
if (element === undefined) {
|
||||
this.data[entity.id] = entity;
|
||||
} else {
|
||||
Object.keys(entity).forEach(function (key) {
|
||||
if (entity[key] !== null && element[key] !== entity[key]) {
|
||||
element[key] = entity[key];
|
||||
}
|
||||
});
|
||||
element.status = {};
|
||||
}
|
||||
};
|
||||
|
||||
ApiService.prototype.addAll = function (entities) {
|
||||
var self = this;
|
||||
angular.forEach(entities, function (entity) {
|
||||
self.add(entity);
|
||||
});
|
||||
};
|
||||
|
||||
ApiService.prototype.getCurrent = function () {
|
||||
return this.data[this.id];
|
||||
};
|
||||
|
||||
ApiService.prototype.unsetCurrrent = function () {
|
||||
this.id = null;
|
||||
};
|
||||
|
||||
|
||||
ApiService.prototype.getData = function () {
|
||||
return $.map(this.data, function (value, index) {
|
||||
return [value];
|
||||
});
|
||||
};
|
||||
|
||||
ApiService.prototype.getAll = function () {
|
||||
return this.data;
|
||||
};
|
||||
|
||||
ApiService.prototype.get = function (id) {
|
||||
return this.data[id];
|
||||
};
|
||||
|
||||
ApiService.prototype.getName = function () {
|
||||
var funcNameRegex = /function (.{1,})\(/;
|
||||
var results = (funcNameRegex).exec((this).constructor.toString());
|
||||
return (results && results.length > 1) ? results[1] : '';
|
||||
};
|
||||
|
||||
return ApiService;
|
||||
|
||||
});
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
/* global app OC angular */
|
||||
app.factory('BoardService', function (ApiService, $http, $q) {
|
||||
var BoardService = function ($http, ep, $q) {
|
||||
ApiService.call(this, $http, ep, $q);
|
||||
};
|
||||
BoardService.prototype = angular.copy(ApiService.prototype);
|
||||
|
||||
BoardService.prototype.delete = function (id) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
|
||||
$http.delete(this.baseUrl + '/' + id).then(function (response) {
|
||||
self.data[id].deletedAt = response.data.deletedAt;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Deleting ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype.deleteUndo = function (id) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
var _id = id;
|
||||
$http.post(this.baseUrl + '/' + id + '/deleteUndo').then(function (response) {
|
||||
self.data[_id].deletedAt = 0;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Deleting ' + self.endpoint + ' failed');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype.searchUsers = function (search) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
var searchData = {
|
||||
format: 'json',
|
||||
perPage: 4,
|
||||
itemType: [0, 1, 7]
|
||||
};
|
||||
if (search !== "") {
|
||||
searchData.search = search;
|
||||
}
|
||||
$http({
|
||||
method: 'GET',
|
||||
url: OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees',
|
||||
params: searchData
|
||||
})
|
||||
.then(function (result) {
|
||||
var response = result.data;
|
||||
if (response.ocs.meta.statuscode !== 100) {
|
||||
deferred.reject('Error while searching for sharees');
|
||||
return;
|
||||
}
|
||||
self.sharees = [];
|
||||
|
||||
var users = response.ocs.data.exact.users.concat(response.ocs.data.users.slice(0, 4));
|
||||
var groups = response.ocs.data.exact.groups.concat(response.ocs.data.groups.slice(0, 4));
|
||||
var circles = response.ocs.data.exact.groups.concat(response.ocs.data.circles.slice(0, 4));
|
||||
|
||||
// filter out everyone who is already in the share list
|
||||
angular.forEach(users, function (item) {
|
||||
var acl = self.generateAcl(OC.Share.SHARE_TYPE_USER, item);
|
||||
var exists = false;
|
||||
angular.forEach(self.getCurrent().acl, function (acl) {
|
||||
if (acl.participant.primaryKey === item.value.shareWith) {
|
||||
exists = true;
|
||||
}
|
||||
});
|
||||
if (!exists && OC.getCurrentUser().uid !== item.value.shareWith) {
|
||||
self.sharees.push(acl);
|
||||
}
|
||||
});
|
||||
angular.forEach(groups, function (item) {
|
||||
var acl = self.generateAcl(OC.Share.SHARE_TYPE_GROUP, item);
|
||||
var exists = false;
|
||||
angular.forEach(self.getCurrent().acl, function (acl) {
|
||||
if (acl.participant.primaryKey === item.value.shareWith) {
|
||||
exists = true;
|
||||
}
|
||||
});
|
||||
if (!exists) {
|
||||
self.sharees.push(acl);
|
||||
}
|
||||
});
|
||||
angular.forEach(circles, function (item) {
|
||||
var acl = self.generateAcl(OC.Share.SHARE_TYPE_CIRCLE, item);
|
||||
var exists = false;
|
||||
angular.forEach(self.getCurrent().acl, function (acl) {
|
||||
if (acl.participant.primaryKey === item.value.shareWith) {
|
||||
exists = true;
|
||||
}
|
||||
});
|
||||
if (!exists) {
|
||||
self.sharees.push(acl);
|
||||
}
|
||||
});
|
||||
|
||||
deferred.resolve(self.sharees);
|
||||
}, function () {
|
||||
deferred.reject('Error while searching for sharees');
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype.generateAcl = function (type, ocsItem) {
|
||||
return {
|
||||
boardId: null,
|
||||
id: null,
|
||||
owner: false,
|
||||
participant: {
|
||||
primaryKey: ocsItem.value.shareWith,
|
||||
uid: ocsItem.value.shareWith,
|
||||
displayname: ocsItem.label
|
||||
},
|
||||
permissionEdit: true,
|
||||
permissionManage: false,
|
||||
permissionShare: false,
|
||||
type: type
|
||||
};
|
||||
};
|
||||
|
||||
BoardService.prototype.addAcl = function (acl) {
|
||||
var board = this.getCurrent();
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
var _acl = acl;
|
||||
$http.post(this.baseUrl + '/' + acl.boardId + '/acl', _acl).then(function (response) {
|
||||
if (!board.acl || board.acl.length === 0) {
|
||||
board.acl = {};
|
||||
}
|
||||
board.acl[response.data.id] = response.data;
|
||||
if (response.data.type === OC.Share.SHARE_TYPE_USER) {
|
||||
self._updateUsers();
|
||||
} else {
|
||||
self.fetchOne(response.data.boardId);
|
||||
}
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error creating ACL ' + _acl);
|
||||
});
|
||||
acl = null;
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype.deleteAcl = function (acl) {
|
||||
var board = this.getCurrent();
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.delete(this.baseUrl + '/' + acl.boardId + '/acl/' + acl.id).then(function (response) {
|
||||
delete board.acl[response.data.id];
|
||||
if (response.data.type === OC.Share.SHARE_TYPE_USER) {
|
||||
self._updateUsers();
|
||||
} else {
|
||||
self.fetchOne(response.data.boardId);
|
||||
}
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error deleting ACL ' + acl.id);
|
||||
});
|
||||
acl = null;
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype.updateAcl = function (acl) {
|
||||
var board = this.getCurrent();
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
var _acl = acl;
|
||||
$http.put(this.baseUrl + '/' + acl.boardId + '/acl', _acl).then(function (response) {
|
||||
board.acl[_acl.id] = response.data;
|
||||
if (response.data.type === OC.Share.SHARE_TYPE_USER) {
|
||||
self._updateUsers();
|
||||
} else {
|
||||
self.fetchOne(response.data.boardId);
|
||||
}
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error updating ACL ' + _acl);
|
||||
});
|
||||
acl = null;
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
BoardService.prototype._updateUsers = function () {
|
||||
if (!this.getCurrent() || !this.getCurrent().acl) {
|
||||
return [];
|
||||
}
|
||||
|
||||
this.getCurrent().users = [this.getCurrent().owner];
|
||||
let self = this;
|
||||
angular.forEach(this.getCurrent().acl, function(value, key) {
|
||||
if (value.type === OC.Share.SHARE_TYPE_USER) {
|
||||
self.getCurrent().users.push(value.participant);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
BoardService.prototype.getUsers = function () {
|
||||
if (this.getCurrent() && !this.getCurrent().users) {
|
||||
this._updateUsers();
|
||||
}
|
||||
return this.getCurrent().users;
|
||||
};
|
||||
|
||||
BoardService.prototype.canRead = function () {
|
||||
if (!this.getCurrent() || !this.getCurrent().permissions) {
|
||||
return false;
|
||||
}
|
||||
return this.getCurrent().permissions['PERMISSION_READ'];
|
||||
};
|
||||
|
||||
BoardService.prototype.canEdit = function () {
|
||||
if (!this.getCurrent() || !this.getCurrent().permissions) {
|
||||
return false;
|
||||
}
|
||||
return this.getCurrent().permissions['PERMISSION_EDIT'];
|
||||
};
|
||||
|
||||
BoardService.prototype.canManage = function (board) {
|
||||
if (board !== null && board !== undefined) {
|
||||
return board.permissions['PERMISSION_MANAGE'];
|
||||
}
|
||||
if (!this.getCurrent() || !this.getCurrent().permissions) {
|
||||
return false;
|
||||
}
|
||||
return this.getCurrent().permissions['PERMISSION_MANAGE'];
|
||||
};
|
||||
|
||||
BoardService.prototype.canShare = function () {
|
||||
if (!this.getCurrent() || !this.getCurrent().permissions) {
|
||||
return false;
|
||||
}
|
||||
return this.getCurrent().permissions['PERMISSION_SHARE'];
|
||||
};
|
||||
|
||||
BoardService.prototype.isArchived = function () {
|
||||
if (!this.getCurrent() || this.getCurrent().archived) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
return new BoardService($http, 'boards', $q);
|
||||
|
||||
});
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.factory('CardService', function (ApiService, $http, $q) {
|
||||
var CardService = function ($http, ep, $q) {
|
||||
ApiService.call(this, $http, ep, $q);
|
||||
};
|
||||
CardService.prototype = angular.copy(ApiService.prototype);
|
||||
|
||||
CardService.prototype.reorder = function (card, order) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + card.id + '/reorder', {
|
||||
cardId: card.id,
|
||||
order: order,
|
||||
stackId: card.stackId
|
||||
}).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.rename = function (card) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + card.id + '/rename', {
|
||||
cardId: card.id,
|
||||
title: card.title
|
||||
}).then(function (response) {
|
||||
self.data[card.id].title = card.title;
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while renaming ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.assignLabel = function (card, label) {
|
||||
var url = this.baseUrl + '/' + card + '/label/' + label;
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.post(url).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
CardService.prototype.removeLabel = function (card, label) {
|
||||
var url = this.baseUrl + '/' + card + '/label/' + label;
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.delete(url).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.archive = function (card) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + card.id + '/archive', {}).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
CardService.prototype.unarchive = function (card) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + card.id + '/unarchive', {}).then(function (response) {
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.assignUser = function (card, user) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
if (self.get(card.id).assignedUsers === null) {
|
||||
self.get(card.id).assignedUsers = [];
|
||||
}
|
||||
$http.post(this.baseUrl + '/' + card.id + '/assign', {'userId': user}).then(function (response) {
|
||||
self.get(card.id).assignedUsers.push(response.data);
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
|
||||
};
|
||||
|
||||
CardService.prototype.unassignUser = function (card, user) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.delete(this.baseUrl + '/' + card.id + '/assign/' + user, {}).then(function (response) {
|
||||
self.get(card.id).assignedUsers = self.get(card.id).assignedUsers.filter(function (obj) {
|
||||
return obj.participant.uid !== user;
|
||||
});
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.attachmentRemove = function (attachment) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.delete(this.baseUrl + '/' + this.getCurrent().id + '/attachment/' + attachment.id, {}).then(function (response) {
|
||||
if (response.data.deletedAt > 0) {
|
||||
let currentAttachment = self.getCurrent().attachments.find(function (obj) {
|
||||
if (obj.id === attachment.id) {
|
||||
obj.deletedAt = response.data.deletedAt;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
self.getCurrent().attachments = self.getCurrent().attachments.filter(function (obj) {
|
||||
return obj.id !== attachment.id;
|
||||
});
|
||||
}
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error when removing the attachment');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
CardService.prototype.attachmentRemoveUndo = function (attachment) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.get(this.baseUrl + '/' + this.getCurrent().id + '/attachment/' + attachment.id + '/restore', {}).then(function (response) {
|
||||
let currentAttachment = self.getCurrent().attachments.find(function (obj) {
|
||||
if (obj.id === attachment.id) {
|
||||
obj.deletedAt = response.data.deletedAt;
|
||||
}
|
||||
});
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error when restoring the attachment');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
var service = new CardService($http, 'cards', $q);
|
||||
return service;
|
||||
});
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* @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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global OC oc_requesttoken */
|
||||
export default class FileService {
|
||||
|
||||
constructor (FileUploader, CardService, $rootScope, $filter) {
|
||||
this.$filter = $filter;
|
||||
this.uploader = new FileUploader();
|
||||
this.cardservice = CardService;
|
||||
this.uploader.onAfterAddingFile = this.onAfterAddingFile.bind(this);
|
||||
this.uploader.onSuccessItem = this.onSuccessItem.bind(this);
|
||||
this.uploader.onErrorItem = this.onErrorItem.bind(this);
|
||||
this.uploader.onCancelItem = this.onCancelItem.bind(this);
|
||||
|
||||
this.maxUploadSize = $rootScope.config.maxUploadSize;
|
||||
this.progress = [];
|
||||
this.status = null;
|
||||
}
|
||||
|
||||
reset () {
|
||||
this.status = null;
|
||||
}
|
||||
|
||||
runUpload (fileItem, attachmentId) {
|
||||
this.status = null;
|
||||
fileItem.url = OC.generateUrl('/apps/deck/cards/' + fileItem.cardId + '/attachment?type=deck_file');
|
||||
if (typeof attachmentId !== 'undefined') {
|
||||
fileItem.url = OC.generateUrl('/apps/deck/cards/' + fileItem.cardId + '/attachment/' + attachmentId + '?type=deck_file');
|
||||
} else {
|
||||
fileItem.formData = [
|
||||
{
|
||||
requesttoken: oc_requesttoken,
|
||||
type: 'deck_file',
|
||||
}
|
||||
];
|
||||
}
|
||||
fileItem.headers = {requesttoken: oc_requesttoken};
|
||||
|
||||
this.uploader.uploadItem(fileItem);
|
||||
}
|
||||
|
||||
onAfterAddingFile (fileItem) {
|
||||
if (this.maxUploadSize > 0 && fileItem.file.size > this.maxUploadSize) {
|
||||
this.status = {
|
||||
error: t('deck', `Failed to upload {name}`, {name: fileItem.file.name}),
|
||||
message: t('deck', 'Maximum file size of {size} exceeded', {size: this.$filter('bytes')(this.maxUploadSize)})
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch card details before trying to upload so we can detect filename collisions properly
|
||||
let self = this;
|
||||
this.progress.push(fileItem);
|
||||
this.cardservice.fetchOne(fileItem.cardId).then(function (data) {
|
||||
let attachments = self.cardservice.get(fileItem.cardId).attachments;
|
||||
let existingFile = attachments.find((attachment) => {
|
||||
return attachment.data === fileItem.file.name;
|
||||
});
|
||||
if (typeof existingFile !== 'undefined') {
|
||||
OC.dialogs.confirm(
|
||||
`A file with the name ${fileItem.file.name} already exists. Do you want to overwrite it?`,
|
||||
'File already exists',
|
||||
function (result) {
|
||||
if (result) {
|
||||
self.runUpload(fileItem, existingFile.id);
|
||||
} else {
|
||||
let fileName = existingFile.extendedData.info.filename;
|
||||
let foundFilesMatching = attachments.filter((attachment) => {
|
||||
return attachment.extendedData.info.extension === existingFile.extendedData.info.extension
|
||||
&& attachment.extendedData.info.filename.startsWith(fileName);
|
||||
});
|
||||
let nextIndex = foundFilesMatching.length + 1;
|
||||
fileItem.file.name = fileName + ' (' + nextIndex + ').' + existingFile.extendedData.info.extension;
|
||||
self.runUpload(fileItem);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
self.runUpload(fileItem);
|
||||
}
|
||||
}, function (error) {
|
||||
this.progress = this.progress.filter((item) => (fileItem.file.name !== item.file.name));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
onSuccessItem (item, response) {
|
||||
let attachments = this.cardservice.get(item.cardId).attachments;
|
||||
let index = attachments.indexOf(attachments.find((attachment) => attachment.id === response.id));
|
||||
if (~index) {
|
||||
attachments = attachments.splice(index, 1);
|
||||
}
|
||||
this.cardservice.get(item.cardId).attachments.push(response);
|
||||
this.progress = this.progress.filter((fileItem) => (fileItem.file.name !== item.file.name));
|
||||
}
|
||||
|
||||
onErrorItem (item, response) {
|
||||
this.progress = this.progress.filter((fileItem) => (fileItem.file.name !== item.file.name));
|
||||
this.status = {
|
||||
error: t('deck', `Failed to upload:`) + ' ' + item.file.name,
|
||||
message: response.message
|
||||
};
|
||||
}
|
||||
|
||||
onCancelItem (item) {
|
||||
this.progress = this.progress.filter((fileItem) => (fileItem.file.name !== item.file.name));
|
||||
}
|
||||
|
||||
getProgressItemsForCard (cardId) {
|
||||
return this.progress.filter((fileItem) => (fileItem.cardId === cardId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.service('FileService', FileService);
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.factory('LabelService', function (ApiService, $http, $q) {
|
||||
var LabelService = function ($http, ep, $q) {
|
||||
ApiService.call(this, $http, ep, $q);
|
||||
};
|
||||
LabelService.prototype = angular.copy(ApiService.prototype);
|
||||
return new LabelService($http, 'labels', $q);
|
||||
});
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
/* global app angular */
|
||||
app.factory('StackService', function (ApiService, CardService, $http, $q) {
|
||||
var StackService = function ($http, ep, $q) {
|
||||
ApiService.call(this, $http, ep, $q);
|
||||
};
|
||||
StackService.prototype = angular.copy(ApiService.prototype);
|
||||
|
||||
StackService.prototype.afterFetch = function(stack) {
|
||||
CardService.addAll(stack.cards);
|
||||
};
|
||||
|
||||
StackService.prototype.fetchAll = function (boardId) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.get(this.baseUrl + '/' + boardId).then(function (response) {
|
||||
self.clear();
|
||||
self.addAll(response.data);
|
||||
// When loading a stack add cards to the CardService so we can fetch
|
||||
// information from there. That way we don't need to refresh the whole
|
||||
// stack data during digest if some value changes
|
||||
angular.forEach(response.data, function (entity) {
|
||||
CardService.addAll(entity.cards);
|
||||
});
|
||||
deferred.resolve(self.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while loading stacks');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
StackService.prototype.fetchArchived = function (boardId) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.get(this.baseUrl + '/' + boardId + '/archived').then(function (response) {
|
||||
self.clear();
|
||||
self.addAll(response.data);
|
||||
angular.forEach(response.data, function (entity) {
|
||||
CardService.addAll(entity.cards);
|
||||
});
|
||||
deferred.resolve(self.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while loading stacks');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
StackService.prototype.addCard = function (entity) {
|
||||
if (!this.data[entity.stackId].cards) {
|
||||
this.data[entity.stackId].cards = [];
|
||||
}
|
||||
this.data[entity.stackId].cards.push(entity);
|
||||
};
|
||||
|
||||
StackService.prototype.reorder = function (stack, order) {
|
||||
var deferred = $q.defer();
|
||||
var self = this;
|
||||
$http.put(this.baseUrl + '/' + stack.id + '/reorder', {
|
||||
stackId: stack.id,
|
||||
order: order
|
||||
}).then(function (response) {
|
||||
angular.forEach(response.data, function (value, key) {
|
||||
var id = value.id;
|
||||
self.data[id].order = value.order;
|
||||
});
|
||||
deferred.resolve(response.data);
|
||||
}, function (error) {
|
||||
deferred.reject('Error while update ' + self.endpoint);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
StackService.prototype.reorderCard = function (entity, order) {
|
||||
// assign new order
|
||||
for (var i = 0, j = 0; i < this.data[entity.stackId].cards.length; i++) {
|
||||
if (this.data[entity.stackId].cards[i].id === entity.id) {
|
||||
this.data[entity.stackId].cards[i].order = order;
|
||||
}
|
||||
if (j === order) {
|
||||
j++;
|
||||
}
|
||||
if (this.data[entity.stackId].cards[i].id !== entity.id) {
|
||||
this.data[entity.stackId].cards[i].order = j++;
|
||||
}
|
||||
}
|
||||
// sort array by order
|
||||
this.data[entity.stackId].cards.sort(function (a, b) {
|
||||
if (a.order < b.order)
|
||||
{return -1;}
|
||||
if (a.order > b.order)
|
||||
{return 1;}
|
||||
return 0;
|
||||
});
|
||||
};
|
||||
|
||||
StackService.prototype.updateCard = function (entity) {
|
||||
var self = this;
|
||||
var cards = this.data[entity.stackId].cards;
|
||||
for (var i = 0; i < cards.length; i++) {
|
||||
if (cards[i].id === entity.id) {
|
||||
cards[i] = entity;
|
||||
}
|
||||
}
|
||||
};
|
||||
StackService.prototype.removeCard = function (entity) {
|
||||
var self = this;
|
||||
var cards = this.data[entity.stackId].cards;
|
||||
for (var i = 0; i < cards.length; i++) {
|
||||
if (cards[i].id === entity.id) {
|
||||
cards.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var service = new StackService($http, 'stacks', $q);
|
||||
return service;
|
||||
});
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
import app from '../app/App.js';
|
||||
|
||||
app.factory('StatusService', function () {
|
||||
// Status Helper
|
||||
var StatusService = function () {
|
||||
this.active = true;
|
||||
this.icon = 'loading';
|
||||
this.title = '';
|
||||
this.text = '';
|
||||
this.counter = 0;
|
||||
};
|
||||
|
||||
|
||||
StatusService.prototype.setStatus = function ($icon, $title, $text) {
|
||||
this.active = true;
|
||||
this.icon = $icon;
|
||||
this.title = $title;
|
||||
this.text = $text;
|
||||
};
|
||||
|
||||
StatusService.prototype.setError = function ($title, $text) {
|
||||
this.active = true;
|
||||
this.icon = 'error';
|
||||
this.title = $title;
|
||||
this.text = $text;
|
||||
this.counter = 0;
|
||||
};
|
||||
|
||||
StatusService.prototype.releaseWaiting = function () {
|
||||
if (this.counter > 0) {
|
||||
this.counter--;
|
||||
}
|
||||
if (this.counter <= 0) {
|
||||
this.active = false;
|
||||
this.counter = 0;
|
||||
}
|
||||
};
|
||||
|
||||
StatusService.prototype.retainWaiting = function () {
|
||||
this.active = true;
|
||||
this.icon = 'loading';
|
||||
this.title = '';
|
||||
this.text = '';
|
||||
this.counter++;
|
||||
};
|
||||
|
||||
StatusService.prototype.unsetStatus = function () {
|
||||
this.active = false;
|
||||
};
|
||||
|
||||
return {
|
||||
getInstance: function () {
|
||||
return new StatusService();
|
||||
},
|
||||
/* Shared StatusService instance between both ListController instances */
|
||||
listStatus: new StatusService()
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* @copyright Copyright (c) 2016 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
describe('BoardController', function() {
|
||||
'use strict';
|
||||
|
||||
var $controller;
|
||||
|
||||
beforeEach(inject(function(_$controller_){
|
||||
// The injector unwraps the underscores (_) from around the parameter names when matching
|
||||
$controller = _$controller_;
|
||||
}));
|
||||
|
||||
describe('$scope.rgblight', function() {
|
||||
it('converts rbg color to a lighter color', function() {
|
||||
var $scope = {};
|
||||
var controller = $controller('BoardController', { $scope: $scope });
|
||||
var hex = $scope.rgblight('red');
|
||||
expect(hex).toEqual('#red');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,76 +0,0 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const { VueLoaderPlugin } = require('vue-loader');
|
||||
|
||||
module.exports = {
|
||||
node: {
|
||||
fs: 'empty',
|
||||
},
|
||||
entry: {
|
||||
deck: ['./init.js'],
|
||||
collections: ['./init-collections.js']
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
path: __dirname + '/build'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['vue-style-loader', 'style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader'
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'babel-loader',
|
||||
query: {
|
||||
presets: ['@babel/preset-env'],
|
||||
plugins: ['@babel/plugin-syntax-dynamic-import']
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
'vue-style-loader',
|
||||
'css-loader',
|
||||
'sass-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|gif|svg)$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
name: '[name].[ext]?[hash]'
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
/* use external jQuery from server */
|
||||
externals: {
|
||||
'jquery': 'jQuery'
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
vue$: 'vue/dist/vue.esm.js'
|
||||
},
|
||||
extensions: ['*', '.js', '.vue', '.json'],
|
||||
modules: [
|
||||
path.resolve(__dirname),
|
||||
path.join(__dirname, 'node_modules'),
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin(),
|
||||
new webpack.ProvidePlugin({
|
||||
$: 'jquery',
|
||||
jQuery: 'jquery'
|
||||
})
|
||||
]
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
const merge = require('webpack-merge');
|
||||
const baseConfig = require('./webpack.config.js');
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'development',
|
||||
devtool: 'source-map',
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
const webpack = require('webpack');
|
||||
const merge = require('webpack-merge');
|
||||
const baseConfig = require('./webpack.config.js');
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'production',
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new UglifyJsPlugin({
|
||||
test: /(vendor\.js)+/i
|
||||
})
|
||||
]
|
||||
}});
|
||||
18
l10n/ar.js
Normal file
18
l10n/ar.js
Normal file
@@ -0,0 +1,18 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Hours" : "ساعات",
|
||||
"Minutes" : "دقائق",
|
||||
"File already exists" : "الملف موجود مسبقاً",
|
||||
"Done" : "تم",
|
||||
"Actions" : "الإجراءات",
|
||||
"Delete card" : "حذف البطاقة",
|
||||
"Timeline" : "الخيط الزمني",
|
||||
"Share" : "شارك",
|
||||
"Update tag" : "تحديث الوسم",
|
||||
"Edit tag" : "تعديل الوسم",
|
||||
"Delete tag" : "حذف الوسم",
|
||||
"Delete attachment" : "حذف المرفق",
|
||||
"Settings" : "الإعدادات"
|
||||
},
|
||||
"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;");
|
||||
16
l10n/ar.json
Normal file
16
l10n/ar.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{ "translations": {
|
||||
"Hours" : "ساعات",
|
||||
"Minutes" : "دقائق",
|
||||
"File already exists" : "الملف موجود مسبقاً",
|
||||
"Done" : "تم",
|
||||
"Actions" : "الإجراءات",
|
||||
"Delete card" : "حذف البطاقة",
|
||||
"Timeline" : "الخيط الزمني",
|
||||
"Share" : "شارك",
|
||||
"Update tag" : "تحديث الوسم",
|
||||
"Edit tag" : "تعديل الوسم",
|
||||
"Delete tag" : "حذف الوسم",
|
||||
"Delete attachment" : "حذف المرفق",
|
||||
"Settings" : "الإعدادات"
|
||||
},"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"
|
||||
}
|
||||
29
l10n/ast.js
Normal file
29
l10n/ast.js
Normal file
@@ -0,0 +1,29 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Hours" : "Hores",
|
||||
"Minutes" : "Minutos",
|
||||
"Deck" : "Deck",
|
||||
"Finished" : "Finó",
|
||||
"Action needed" : "Precísase aición",
|
||||
"Later" : "Más sero",
|
||||
"Submit" : "Unviar",
|
||||
"Show archived cards" : "Amosar tarxetes archivaes",
|
||||
"Close" : "Zarrar",
|
||||
"Tags" : "Etiquetes",
|
||||
"Select users or groups to share with" : "Esbilla usuarios o grupos colos que compartir",
|
||||
"No matching user or group found." : "Nun s'alcontró dengún usuariu o grupu que concasara.",
|
||||
"Loading" : "Cargando",
|
||||
"Edit" : "Editar",
|
||||
"Share" : "Compartir",
|
||||
"Manage" : "Xestionar",
|
||||
"Discard share" : "Escartar compartición",
|
||||
"Title" : "Títulu",
|
||||
"Members" : "Miembros",
|
||||
"More actions" : "Más aiciones",
|
||||
"by" : "por",
|
||||
"Click to set" : "Primi p'afitar",
|
||||
"Description" : "Descripción",
|
||||
"Saved" : "Guardóse"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
27
l10n/ast.json
Normal file
27
l10n/ast.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{ "translations": {
|
||||
"Hours" : "Hores",
|
||||
"Minutes" : "Minutos",
|
||||
"Deck" : "Deck",
|
||||
"Finished" : "Finó",
|
||||
"Action needed" : "Precísase aición",
|
||||
"Later" : "Más sero",
|
||||
"Submit" : "Unviar",
|
||||
"Show archived cards" : "Amosar tarxetes archivaes",
|
||||
"Close" : "Zarrar",
|
||||
"Tags" : "Etiquetes",
|
||||
"Select users or groups to share with" : "Esbilla usuarios o grupos colos que compartir",
|
||||
"No matching user or group found." : "Nun s'alcontró dengún usuariu o grupu que concasara.",
|
||||
"Loading" : "Cargando",
|
||||
"Edit" : "Editar",
|
||||
"Share" : "Compartir",
|
||||
"Manage" : "Xestionar",
|
||||
"Discard share" : "Escartar compartición",
|
||||
"Title" : "Títulu",
|
||||
"Members" : "Miembros",
|
||||
"More actions" : "Más aiciones",
|
||||
"by" : "por",
|
||||
"Click to set" : "Primi p'afitar",
|
||||
"Description" : "Descripción",
|
||||
"Saved" : "Guardóse"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
42
l10n/bg.js
Normal file
42
l10n/bg.js
Normal file
@@ -0,0 +1,42 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Hours" : "Часове",
|
||||
"Minutes" : "Минути",
|
||||
"Finished" : "Готово",
|
||||
"To review" : "За преглед",
|
||||
"Action needed" : "Необходимо е действие",
|
||||
"Later" : "По-късно",
|
||||
"The file was uploaded" : "Файлът е качен",
|
||||
"The file was only partially uploaded" : "Файлът е качен частично",
|
||||
"No file was uploaded" : "Нито един файл не е качен",
|
||||
"Sharing" : "Споделяне",
|
||||
"Tags" : "Етикети",
|
||||
"Select users or groups to share with" : "Споделяне с потребители или групи",
|
||||
"No matching user or group found." : "Не са намерени съвпадащи потребители или групи",
|
||||
"Loading" : "Зареждане",
|
||||
"Edit" : "Редакция",
|
||||
"Share" : "Сподели",
|
||||
"Manage" : "Управление",
|
||||
"Discard share" : "Отхвърляне на споделяне",
|
||||
"Create" : "Създай",
|
||||
"Title" : "Име",
|
||||
"Members" : "Членове",
|
||||
"Cancel upload" : "Откажи качването",
|
||||
"by" : "от",
|
||||
"Modified:" : "Променена:",
|
||||
"Created:" : "Създадена:",
|
||||
"Choose a tag" : "Изберете етикет",
|
||||
"Add a tag" : "Етикети",
|
||||
"Select tags" : "Изберете етикети",
|
||||
"Assign users" : "Зачисляване на потребител",
|
||||
"Choose a user to assign" : "Изберете потребител на който да бъде зачислена",
|
||||
"Due date" : "Крайна дата",
|
||||
"Remove due date" : "Премахни крайната дата",
|
||||
"Description" : "Описание",
|
||||
"Attachments" : "Прикачени файлове",
|
||||
"Saved" : "Запазено",
|
||||
"Upload attachment" : "Качване",
|
||||
"Settings" : "Настройки"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
40
l10n/bg.json
Normal file
40
l10n/bg.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{ "translations": {
|
||||
"Hours" : "Часове",
|
||||
"Minutes" : "Минути",
|
||||
"Finished" : "Готово",
|
||||
"To review" : "За преглед",
|
||||
"Action needed" : "Необходимо е действие",
|
||||
"Later" : "По-късно",
|
||||
"The file was uploaded" : "Файлът е качен",
|
||||
"The file was only partially uploaded" : "Файлът е качен частично",
|
||||
"No file was uploaded" : "Нито един файл не е качен",
|
||||
"Sharing" : "Споделяне",
|
||||
"Tags" : "Етикети",
|
||||
"Select users or groups to share with" : "Споделяне с потребители или групи",
|
||||
"No matching user or group found." : "Не са намерени съвпадащи потребители или групи",
|
||||
"Loading" : "Зареждане",
|
||||
"Edit" : "Редакция",
|
||||
"Share" : "Сподели",
|
||||
"Manage" : "Управление",
|
||||
"Discard share" : "Отхвърляне на споделяне",
|
||||
"Create" : "Създай",
|
||||
"Title" : "Име",
|
||||
"Members" : "Членове",
|
||||
"Cancel upload" : "Откажи качването",
|
||||
"by" : "от",
|
||||
"Modified:" : "Променена:",
|
||||
"Created:" : "Създадена:",
|
||||
"Choose a tag" : "Изберете етикет",
|
||||
"Add a tag" : "Етикети",
|
||||
"Select tags" : "Изберете етикети",
|
||||
"Assign users" : "Зачисляване на потребител",
|
||||
"Choose a user to assign" : "Изберете потребител на който да бъде зачислена",
|
||||
"Due date" : "Крайна дата",
|
||||
"Remove due date" : "Премахни крайната дата",
|
||||
"Description" : "Описание",
|
||||
"Attachments" : "Прикачени файлове",
|
||||
"Saved" : "Запазено",
|
||||
"Upload attachment" : "Качване",
|
||||
"Settings" : "Настройки"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
15
l10n/bs.js
Normal file
15
l10n/bs.js
Normal file
@@ -0,0 +1,15 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Hours" : "Sati",
|
||||
"Minutes" : "Minute",
|
||||
"Maximum file size of {size} exceeded" : "Maksimalna veličina datoteke prekoračena",
|
||||
"Edit" : "Izmjeni",
|
||||
"Share" : "Podjeli",
|
||||
"Create" : "Ustvari",
|
||||
"Status" : "Status",
|
||||
"Title" : "Naslov",
|
||||
"Members" : "Članovi",
|
||||
"Settings" : "Podešavanje"
|
||||
},
|
||||
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
|
||||
13
l10n/bs.json
Normal file
13
l10n/bs.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{ "translations": {
|
||||
"Hours" : "Sati",
|
||||
"Minutes" : "Minute",
|
||||
"Maximum file size of {size} exceeded" : "Maksimalna veličina datoteke prekoračena",
|
||||
"Edit" : "Izmjeni",
|
||||
"Share" : "Podjeli",
|
||||
"Create" : "Ustvari",
|
||||
"Status" : "Status",
|
||||
"Title" : "Naslov",
|
||||
"Members" : "Članovi",
|
||||
"Settings" : "Podešavanje"
|
||||
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
|
||||
}
|
||||
22
l10n/ca.js
22
l10n/ca.js
@@ -1,7 +1,7 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Please provide a content for your comment." : "Si us plau, proporcioneu un contingut per al vostre comentari.",
|
||||
"Please provide a content for your comment." : "Proporcioneu un contingut per al vostre comentari.",
|
||||
"Posting the comment failed." : "No s'ha pogut publicar el comentari.",
|
||||
"The comment has been deleted" : "S'ha suprimit el comentari",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "La pila associada també se suprimeix, també es restaurarà.",
|
||||
@@ -11,6 +11,7 @@ OC.L10N.register(
|
||||
"Minutes" : "Minuts",
|
||||
"Link to a board" : "Enllaça a un tauler",
|
||||
"Maximum file size of {size} exceeded" : "S'ha superat la mida màxima per fitxer de {size}",
|
||||
"File already exists" : "El fitxer ja existeix",
|
||||
"You have created a new board {board}" : "Heu creat el nou tauler {board}",
|
||||
"{user} has created a new board {board}" : "{user} ha creat el nou tauler {board}",
|
||||
"You have deleted the board {board}" : "Heu suprimit el tauler {board}",
|
||||
@@ -18,7 +19,7 @@ OC.L10N.register(
|
||||
"You have restored the board {board}" : "Heu restaurat el tauler {board}",
|
||||
"{user} has restored the board {board}" : "{user} ha restaurat el tauler {board}",
|
||||
"You have shared the board {board} with {acl}" : "Heu compartit el tauler {board} amb {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} ha compartit el tauler {board} amb {sharee}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} ha compartit el tauler {board} amb {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Heu suprimit {acl} del tauler {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} ha suprimit {acl} del tauler {board}",
|
||||
"You have renamed the board {before} to {board}" : "Heu reanomenat el tauler {before} a {board}",
|
||||
@@ -76,6 +77,7 @@ OC.L10N.register(
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "S'ha canviat una <strong>descripció de targeta</strong> a l'aplicació Tauler",
|
||||
"Deck" : "Tauler",
|
||||
"Changes in the <strong>Deck app</strong>" : "Hi ha canvis a l'<strong>aplicació Tauler</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "S'ha afegit un <strong>comentari</strong> a una targeta",
|
||||
"Personal" : "Personal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La targeta \"%s\" sobre \"%s\" se us ha assignat per %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} us ha assignat la targeta \"%s\" sobre \"%s\".",
|
||||
@@ -89,13 +91,13 @@ OC.L10N.register(
|
||||
"To review" : "Per revisar",
|
||||
"Action needed" : "Acció necessària",
|
||||
"Later" : "Més tard",
|
||||
"To do" : "Pendent de fer",
|
||||
"Doing" : "S'està fent",
|
||||
"Done" : "Fet",
|
||||
"Example Task 3" : "Exemple Tasca 3",
|
||||
"Example Task 2" : "Exemple Tasca 2",
|
||||
"Example Task 1" : "Exemple Tasca 1",
|
||||
"The file was uploaded" : "El fitxer ha estat carregat",
|
||||
"To do" : "Pendents",
|
||||
"Doing" : "En procés",
|
||||
"Done" : "Finalitzades",
|
||||
"Example Task 3" : "Tasca d'exemple 3",
|
||||
"Example Task 2" : "Tasca d'exemple 2",
|
||||
"Example Task 1" : "Tasca d'exemple 1",
|
||||
"The file was uploaded" : "S'ha carregat el fitxer",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "El fitxer carregat excedeix la directiva upload_max_filesize dins de php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "El fitxer carregat excedeix la directiva MAX_FILE_SIZE que hi ha especificada al formulari d'HTML",
|
||||
"The file was only partially uploaded" : "El fitxer s'ha carregat només parcialment",
|
||||
@@ -122,7 +124,7 @@ OC.L10N.register(
|
||||
"Drop your files here to upload it to the card" : "Deixeu anar els fitxers aquí per carregar-los a la targeta",
|
||||
"Assign card to me" : "Assigna'm la targeta",
|
||||
"Unassign card from me" : "Desassigna'm la targeta",
|
||||
"Archive card" : "Arxiva targeta",
|
||||
"Archive card" : "Arxiva la targeta",
|
||||
"Unarchive card" : "Desarxiva targeta",
|
||||
"Delete card" : "Suprimeix targeta",
|
||||
"Enter a card title" : "Introduïu un títol a la targeta",
|
||||
|
||||
22
l10n/ca.json
22
l10n/ca.json
@@ -1,5 +1,5 @@
|
||||
{ "translations": {
|
||||
"Please provide a content for your comment." : "Si us plau, proporcioneu un contingut per al vostre comentari.",
|
||||
"Please provide a content for your comment." : "Proporcioneu un contingut per al vostre comentari.",
|
||||
"Posting the comment failed." : "No s'ha pogut publicar el comentari.",
|
||||
"The comment has been deleted" : "S'ha suprimit el comentari",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "La pila associada també se suprimeix, també es restaurarà.",
|
||||
@@ -9,6 +9,7 @@
|
||||
"Minutes" : "Minuts",
|
||||
"Link to a board" : "Enllaça a un tauler",
|
||||
"Maximum file size of {size} exceeded" : "S'ha superat la mida màxima per fitxer de {size}",
|
||||
"File already exists" : "El fitxer ja existeix",
|
||||
"You have created a new board {board}" : "Heu creat el nou tauler {board}",
|
||||
"{user} has created a new board {board}" : "{user} ha creat el nou tauler {board}",
|
||||
"You have deleted the board {board}" : "Heu suprimit el tauler {board}",
|
||||
@@ -16,7 +17,7 @@
|
||||
"You have restored the board {board}" : "Heu restaurat el tauler {board}",
|
||||
"{user} has restored the board {board}" : "{user} ha restaurat el tauler {board}",
|
||||
"You have shared the board {board} with {acl}" : "Heu compartit el tauler {board} amb {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} ha compartit el tauler {board} amb {sharee}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} ha compartit el tauler {board} amb {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Heu suprimit {acl} del tauler {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} ha suprimit {acl} del tauler {board}",
|
||||
"You have renamed the board {before} to {board}" : "Heu reanomenat el tauler {before} a {board}",
|
||||
@@ -74,6 +75,7 @@
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "S'ha canviat una <strong>descripció de targeta</strong> a l'aplicació Tauler",
|
||||
"Deck" : "Tauler",
|
||||
"Changes in the <strong>Deck app</strong>" : "Hi ha canvis a l'<strong>aplicació Tauler</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "S'ha afegit un <strong>comentari</strong> a una targeta",
|
||||
"Personal" : "Personal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La targeta \"%s\" sobre \"%s\" se us ha assignat per %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} us ha assignat la targeta \"%s\" sobre \"%s\".",
|
||||
@@ -87,13 +89,13 @@
|
||||
"To review" : "Per revisar",
|
||||
"Action needed" : "Acció necessària",
|
||||
"Later" : "Més tard",
|
||||
"To do" : "Pendent de fer",
|
||||
"Doing" : "S'està fent",
|
||||
"Done" : "Fet",
|
||||
"Example Task 3" : "Exemple Tasca 3",
|
||||
"Example Task 2" : "Exemple Tasca 2",
|
||||
"Example Task 1" : "Exemple Tasca 1",
|
||||
"The file was uploaded" : "El fitxer ha estat carregat",
|
||||
"To do" : "Pendents",
|
||||
"Doing" : "En procés",
|
||||
"Done" : "Finalitzades",
|
||||
"Example Task 3" : "Tasca d'exemple 3",
|
||||
"Example Task 2" : "Tasca d'exemple 2",
|
||||
"Example Task 1" : "Tasca d'exemple 1",
|
||||
"The file was uploaded" : "S'ha carregat el fitxer",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "El fitxer carregat excedeix la directiva upload_max_filesize dins de php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "El fitxer carregat excedeix la directiva MAX_FILE_SIZE que hi ha especificada al formulari d'HTML",
|
||||
"The file was only partially uploaded" : "El fitxer s'ha carregat només parcialment",
|
||||
@@ -120,7 +122,7 @@
|
||||
"Drop your files here to upload it to the card" : "Deixeu anar els fitxers aquí per carregar-los a la targeta",
|
||||
"Assign card to me" : "Assigna'm la targeta",
|
||||
"Unassign card from me" : "Desassigna'm la targeta",
|
||||
"Archive card" : "Arxiva targeta",
|
||||
"Archive card" : "Arxiva la targeta",
|
||||
"Unarchive card" : "Desarxiva targeta",
|
||||
"Delete card" : "Suprimeix targeta",
|
||||
"Enter a card title" : "Introduïu un títol a la targeta",
|
||||
|
||||
@@ -10,6 +10,7 @@ OC.L10N.register(
|
||||
"Hours" : "Hodiny",
|
||||
"Minutes" : "Minuty",
|
||||
"Maximum file size of {size} exceeded" : "U souboru {size} překročena nejvyšší umožněná velikost",
|
||||
"File already exists" : "Soubor už existuje",
|
||||
"You have created a new board {board}" : "Vytvořili jste nástěnku {board}",
|
||||
"{user} has created a new board {board}" : "{user} vytvořil(a) novou nástěnku {board}",
|
||||
"You have deleted the board {board}" : "Smazali jste nástěnku {board}",
|
||||
@@ -17,7 +18,6 @@ OC.L10N.register(
|
||||
"You have restored the board {board}" : "Obnovili jste nástěnku {board}",
|
||||
"{user} has restored the board {board}" : "{user} obnovil(a) nástěnku {board}",
|
||||
"You have shared the board {board} with {acl}" : "Nasdíleli jste nástěnku {board} s {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} nasdílel(a) nástěnku {board} pro {sharee}",
|
||||
"You have removed {acl} from the board {board}" : "Odebrali jste {acl} z nástěnky {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} odebral(a) {acl} z nástěnky {board}",
|
||||
"You have renamed the board {before} to {board}" : "Přejmenovali jste nástěnku {before} na {board}",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"Hours" : "Hodiny",
|
||||
"Minutes" : "Minuty",
|
||||
"Maximum file size of {size} exceeded" : "U souboru {size} překročena nejvyšší umožněná velikost",
|
||||
"File already exists" : "Soubor už existuje",
|
||||
"You have created a new board {board}" : "Vytvořili jste nástěnku {board}",
|
||||
"{user} has created a new board {board}" : "{user} vytvořil(a) novou nástěnku {board}",
|
||||
"You have deleted the board {board}" : "Smazali jste nástěnku {board}",
|
||||
@@ -15,7 +16,6 @@
|
||||
"You have restored the board {board}" : "Obnovili jste nástěnku {board}",
|
||||
"{user} has restored the board {board}" : "{user} obnovil(a) nástěnku {board}",
|
||||
"You have shared the board {board} with {acl}" : "Nasdíleli jste nástěnku {board} s {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} nasdílel(a) nástěnku {board} pro {sharee}",
|
||||
"You have removed {acl} from the board {board}" : "Odebrali jste {acl} z nástěnky {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} odebral(a) {acl} z nástěnky {board}",
|
||||
"You have renamed the board {before} to {board}" : "Přejmenovali jste nástěnku {before} na {board}",
|
||||
|
||||
@@ -11,6 +11,7 @@ OC.L10N.register(
|
||||
"Minutes" : "Minuten",
|
||||
"Link to a board" : "Mit einem Board verknüpfen",
|
||||
"Maximum file size of {size} exceeded" : "Maximale Dateigröße von {size} überschritten",
|
||||
"File already exists" : "Datei bereits vorhanden",
|
||||
"You have created a new board {board}" : "Du hast das neue Board {board} erstellt",
|
||||
"{user} has created a new board {board}" : "{user} hat das neue Board {board} erstellt",
|
||||
"You have deleted the board {board}" : "Du hast das Board {board} gelöscht",
|
||||
@@ -18,7 +19,7 @@ OC.L10N.register(
|
||||
"You have restored the board {board}" : "Du hast das Board {board} wiederhergestellt",
|
||||
"{user} has restored the board {board}" : "{user} hat das Board {board} wiederhergestellt",
|
||||
"You have shared the board {board} with {acl}" : "Du hast das Board {board} mit {acl} geteilt",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} hat das Board {board} mit {sharee} geteilt",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} hat das Board {board} mit {acl} geteilt",
|
||||
"You have removed {acl} from the board {board}" : "Du hast {acl} vom Board {board} entfernt",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} hat {acl} vom Board {board} entfernt",
|
||||
"You have renamed the board {before} to {board}" : "Du hast das Board {before} in {board} umbenannt",
|
||||
@@ -76,6 +77,7 @@ OC.L10N.register(
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "Eine <strong>Kartenbeschreibung</strong> wurde innerhalb der Deck-App geändert",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Änderungen in der <strong>Deck-App</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Ein <strong>Kommentar</strong> zu einer Karte wurde erstellt",
|
||||
"Personal" : "Persönlich",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Die Karte \"%s\" auf \"%s\" wurde Dir von %s zugewiesen.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} hat Dir die Karte \"%s\" auf \"%s\" zugewiesen.",
|
||||
@@ -106,7 +108,7 @@ OC.L10N.register(
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Keine Datei hochgeladen oder die Dateigröße überschreitet %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban Werkzeug für Nextcloud",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Füge Deine Aufgaben zu den Karten hinzu und ordne diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Vergabe von Labels für noch bessere Organisation\n- 👥 Teile mit Deinem Team, Freunden oder der Familie\n- 📎 Füge Dateien hinzu und verwende diese in Deinen Markdown-Beschreibungen\n- 💬 Diskutiere mit Deinem Team mit Kommentaren\n- ⚡ Behalte Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisiere Dein Projekt",
|
||||
"Select the board to link to a project" : "Wähle ein Board aus um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select the board to link to a project" : "Wähle ein Board aus, um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select board" : "Board auswählen",
|
||||
"Add a new stack" : "Neuer Stapel",
|
||||
"Submit" : "Übermitteln",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"Minutes" : "Minuten",
|
||||
"Link to a board" : "Mit einem Board verknüpfen",
|
||||
"Maximum file size of {size} exceeded" : "Maximale Dateigröße von {size} überschritten",
|
||||
"File already exists" : "Datei bereits vorhanden",
|
||||
"You have created a new board {board}" : "Du hast das neue Board {board} erstellt",
|
||||
"{user} has created a new board {board}" : "{user} hat das neue Board {board} erstellt",
|
||||
"You have deleted the board {board}" : "Du hast das Board {board} gelöscht",
|
||||
@@ -16,7 +17,7 @@
|
||||
"You have restored the board {board}" : "Du hast das Board {board} wiederhergestellt",
|
||||
"{user} has restored the board {board}" : "{user} hat das Board {board} wiederhergestellt",
|
||||
"You have shared the board {board} with {acl}" : "Du hast das Board {board} mit {acl} geteilt",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} hat das Board {board} mit {sharee} geteilt",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} hat das Board {board} mit {acl} geteilt",
|
||||
"You have removed {acl} from the board {board}" : "Du hast {acl} vom Board {board} entfernt",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} hat {acl} vom Board {board} entfernt",
|
||||
"You have renamed the board {before} to {board}" : "Du hast das Board {before} in {board} umbenannt",
|
||||
@@ -74,6 +75,7 @@
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "Eine <strong>Kartenbeschreibung</strong> wurde innerhalb der Deck-App geändert",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Änderungen in der <strong>Deck-App</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Ein <strong>Kommentar</strong> zu einer Karte wurde erstellt",
|
||||
"Personal" : "Persönlich",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Die Karte \"%s\" auf \"%s\" wurde Dir von %s zugewiesen.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} hat Dir die Karte \"%s\" auf \"%s\" zugewiesen.",
|
||||
@@ -104,7 +106,7 @@
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Keine Datei hochgeladen oder die Dateigröße überschreitet %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban Werkzeug für Nextcloud",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Füge Deine Aufgaben zu den Karten hinzu und ordne diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Vergabe von Labels für noch bessere Organisation\n- 👥 Teile mit Deinem Team, Freunden oder der Familie\n- 📎 Füge Dateien hinzu und verwende diese in Deinen Markdown-Beschreibungen\n- 💬 Diskutiere mit Deinem Team mit Kommentaren\n- ⚡ Behalte Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisiere Dein Projekt",
|
||||
"Select the board to link to a project" : "Wähle ein Board aus um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select the board to link to a project" : "Wähle ein Board aus, um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select board" : "Board auswählen",
|
||||
"Add a new stack" : "Neuer Stapel",
|
||||
"Submit" : "Übermitteln",
|
||||
|
||||
@@ -11,6 +11,7 @@ OC.L10N.register(
|
||||
"Minutes" : "Minuten",
|
||||
"Link to a board" : "Mit einem Board verknüpfen",
|
||||
"Maximum file size of {size} exceeded" : "Maximale Dateigröße von {size} überschritten",
|
||||
"File already exists" : "Datei bereits vorhanden",
|
||||
"You have created a new board {board}" : "Sie haben das neue Board {board} erstellt",
|
||||
"{user} has created a new board {board}" : "{user} hat das neue Board {board} erstellt",
|
||||
"You have deleted the board {board}" : "Sie haben das Board {board} gelöscht",
|
||||
@@ -18,7 +19,7 @@ OC.L10N.register(
|
||||
"You have restored the board {board}" : "Sie haben das Board {board} wiederhergestellt",
|
||||
"{user} has restored the board {board}" : "{user} hat das Board {board} wiederhergestellt",
|
||||
"You have shared the board {board} with {acl}" : "Sie haben das Board {board} mit {acl} geteilt",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} hat das Board {board} mit {sharee} geteilt",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} hat das Board {board} mit {acl} geteilt",
|
||||
"You have removed {acl} from the board {board}" : "Sie haben {acl} vom Board {board} entfernt",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} hat {acl} vom Board {board} entfernt",
|
||||
"You have renamed the board {before} to {board}" : "Sie haben das Board {before} in {board} umbenannt",
|
||||
@@ -76,6 +77,7 @@ OC.L10N.register(
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "Eine <strong>Kartenbeschreibung</strong> wurde innerhalb der Deck-App geändert",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Änderungen in der <strong>Deck-App</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Ein <strong>Kommentar</strong> zu einer Karte wurde erstellt",
|
||||
"Personal" : "Persönlich",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Die Karte \"%s\" auf \"%s\" wurde Ihnen von %s zugewiesen.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} hat Ihnen die Karte \"%s\" auf \"%s\" zugewiesen.",
|
||||
@@ -106,7 +108,7 @@ OC.L10N.register(
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Keine Datei hochgeladen oder die Dateigröße überschreitet %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban Werkzeug für Nextcloud",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Fügen Sie Ihre Aufgaben zu den Karten hinzu und ordnen Sie diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Zuweisung von Labels für noch bessere Organisation\n- 👥 Teilen Sie mit Ihrem Team, Ihren Freunden oder Ihrer Familie\n- 📎 Fügen Sie Dateien hinzu und verwende diese in Ihren Markdown-Beschreibungen\n- 💬 Diskutieren Sie mit Ihrem Team mit Kommentaren\n- ⚡ Behalten Sie Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisieren Sie Ihr Projekt",
|
||||
"Select the board to link to a project" : "Wählen Sie ein Board aus um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select the board to link to a project" : "Wählen Sie ein Board aus, um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select board" : "Board auswählen",
|
||||
"Add a new stack" : "Neuer Stapel",
|
||||
"Submit" : "Übermitteln",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"Minutes" : "Minuten",
|
||||
"Link to a board" : "Mit einem Board verknüpfen",
|
||||
"Maximum file size of {size} exceeded" : "Maximale Dateigröße von {size} überschritten",
|
||||
"File already exists" : "Datei bereits vorhanden",
|
||||
"You have created a new board {board}" : "Sie haben das neue Board {board} erstellt",
|
||||
"{user} has created a new board {board}" : "{user} hat das neue Board {board} erstellt",
|
||||
"You have deleted the board {board}" : "Sie haben das Board {board} gelöscht",
|
||||
@@ -16,7 +17,7 @@
|
||||
"You have restored the board {board}" : "Sie haben das Board {board} wiederhergestellt",
|
||||
"{user} has restored the board {board}" : "{user} hat das Board {board} wiederhergestellt",
|
||||
"You have shared the board {board} with {acl}" : "Sie haben das Board {board} mit {acl} geteilt",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} hat das Board {board} mit {sharee} geteilt",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} hat das Board {board} mit {acl} geteilt",
|
||||
"You have removed {acl} from the board {board}" : "Sie haben {acl} vom Board {board} entfernt",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} hat {acl} vom Board {board} entfernt",
|
||||
"You have renamed the board {before} to {board}" : "Sie haben das Board {before} in {board} umbenannt",
|
||||
@@ -74,6 +75,7 @@
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "Eine <strong>Kartenbeschreibung</strong> wurde innerhalb der Deck-App geändert",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Änderungen in der <strong>Deck-App</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Ein <strong>Kommentar</strong> zu einer Karte wurde erstellt",
|
||||
"Personal" : "Persönlich",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "Die Karte \"%s\" auf \"%s\" wurde Ihnen von %s zugewiesen.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} hat Ihnen die Karte \"%s\" auf \"%s\" zugewiesen.",
|
||||
@@ -104,7 +106,7 @@
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Keine Datei hochgeladen oder die Dateigröße überschreitet %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Ein Kanban Werkzeug für Nextcloud",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck ist ein Organisationstool im Kanban-Stil für die persönliche Planung und Projektorganisation von Teams, die in Nextcloud integriert sind.\n\n\n- 📥 Fügen Sie Ihre Aufgaben zu den Karten hinzu und ordnen Sie diese\n- 📄 Zusätzliche Hinweise in der Abschrift notieren\n- 🔖 Zuweisung von Labels für noch bessere Organisation\n- 👥 Teilen Sie mit Ihrem Team, Ihren Freunden oder Ihrer Familie\n- 📎 Fügen Sie Dateien hinzu und verwende diese in Ihren Markdown-Beschreibungen\n- 💬 Diskutieren Sie mit Ihrem Team mit Kommentaren\n- ⚡ Behalten Sie Überblick über Änderungen mit dem Aktivitäten-Stream\n- 🚀 Organisieren Sie Ihr Projekt",
|
||||
"Select the board to link to a project" : "Wählen Sie ein Board aus um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select the board to link to a project" : "Wählen Sie ein Board aus, um dieses mit einem Projekt zu verknüpfen",
|
||||
"Select board" : "Board auswählen",
|
||||
"Add a new stack" : "Neuer Stapel",
|
||||
"Submit" : "Übermitteln",
|
||||
|
||||
@@ -26,6 +26,7 @@ OC.L10N.register(
|
||||
"Deleted items" : "Διαγραμμένα αντικείμενα",
|
||||
"Timeline" : "Χρονοδιάγραμμα",
|
||||
"Select users or groups to share with" : "Επιλέξτε χρήστες ή ομάδες με τις οποίες θα μοιραστείτε",
|
||||
"Group" : "Ομάδα",
|
||||
"No matching user or group found." : "Δεν βρέθηκε χρήστης ή ομάδα να ταιριάζει.",
|
||||
"Loading" : "Γίνεται φόρτωση",
|
||||
"Edit" : "Επεξεργασία",
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"Deleted items" : "Διαγραμμένα αντικείμενα",
|
||||
"Timeline" : "Χρονοδιάγραμμα",
|
||||
"Select users or groups to share with" : "Επιλέξτε χρήστες ή ομάδες με τις οποίες θα μοιραστείτε",
|
||||
"Group" : "Ομάδα",
|
||||
"No matching user or group found." : "Δεν βρέθηκε χρήστης ή ομάδα να ταιριάζει.",
|
||||
"Loading" : "Γίνεται φόρτωση",
|
||||
"Edit" : "Επεξεργασία",
|
||||
|
||||
@@ -11,6 +11,7 @@ OC.L10N.register(
|
||||
"Minutes" : "Minutoj",
|
||||
"Link to a board" : "Ligilo al tabulo",
|
||||
"Maximum file size of {size} exceeded" : "Maksimuma dosiergrando {size} transpasita",
|
||||
"File already exists" : "La dosiero jam ekzistas",
|
||||
"You have created a new board {board}" : "Vi kreis novan tabulon {board}",
|
||||
"{user} has created a new board {board}" : "{user} kreis novan tabulon {board}",
|
||||
"You have deleted the board {board}" : "Vi forigis tabulon {board}",
|
||||
@@ -18,7 +19,7 @@ OC.L10N.register(
|
||||
"You have restored the board {board}" : "Vi restaŭris tabulon {board}",
|
||||
"{user} has restored the board {board}" : "{user} restaŭris tabulon {board}",
|
||||
"You have shared the board {board} with {acl}" : "Vi kunhavigis tabulon {board} kun {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} kunhavigis tabulon {board} kun {sharee}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} kunhavigis tabulon {board} kun {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Vi forigis {acl} el la tabulo {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} forigis {acl} el la tabulo {board}",
|
||||
"You have renamed the board {before} to {board}" : "Vi alinomis la tabulon {before} al {board}",
|
||||
@@ -76,6 +77,7 @@ OC.L10N.register(
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "<strong>Karta priskribo</strong> ene de la aplikaĵo Kartaro ŝanĝiĝis",
|
||||
"Deck" : "Kartaro",
|
||||
"Changes in the <strong>Deck app</strong>" : "Ŝanĝoj en la <strong>aplikaĵo Kartaro</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "<strong>Komento</strong> kreiĝis sur karton",
|
||||
"Personal" : "Persona",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La karto „%s“ sur „%s“ estis atribuita al vi de %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} atribuis la karton „%s“ sur „%s“ al vi.",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"Minutes" : "Minutoj",
|
||||
"Link to a board" : "Ligilo al tabulo",
|
||||
"Maximum file size of {size} exceeded" : "Maksimuma dosiergrando {size} transpasita",
|
||||
"File already exists" : "La dosiero jam ekzistas",
|
||||
"You have created a new board {board}" : "Vi kreis novan tabulon {board}",
|
||||
"{user} has created a new board {board}" : "{user} kreis novan tabulon {board}",
|
||||
"You have deleted the board {board}" : "Vi forigis tabulon {board}",
|
||||
@@ -16,7 +17,7 @@
|
||||
"You have restored the board {board}" : "Vi restaŭris tabulon {board}",
|
||||
"{user} has restored the board {board}" : "{user} restaŭris tabulon {board}",
|
||||
"You have shared the board {board} with {acl}" : "Vi kunhavigis tabulon {board} kun {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} kunhavigis tabulon {board} kun {sharee}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} kunhavigis tabulon {board} kun {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Vi forigis {acl} el la tabulo {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} forigis {acl} el la tabulo {board}",
|
||||
"You have renamed the board {before} to {board}" : "Vi alinomis la tabulon {before} al {board}",
|
||||
@@ -74,6 +75,7 @@
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "<strong>Karta priskribo</strong> ene de la aplikaĵo Kartaro ŝanĝiĝis",
|
||||
"Deck" : "Kartaro",
|
||||
"Changes in the <strong>Deck app</strong>" : "Ŝanĝoj en la <strong>aplikaĵo Kartaro</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "<strong>Komento</strong> kreiĝis sur karton",
|
||||
"Personal" : "Persona",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La karto „%s“ sur „%s“ estis atribuita al vi de %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} atribuis la karton „%s“ sur „%s“ al vi.",
|
||||
|
||||
@@ -9,7 +9,9 @@ OC.L10N.register(
|
||||
"Remove user from card" : "Eliminar usuario de la tarjeta",
|
||||
"Hours" : "Horas",
|
||||
"Minutes" : "Minutos",
|
||||
"Link to a board" : "Enlace a un tablero",
|
||||
"Maximum file size of {size} exceeded" : "Tamaño máximo de archivo de {size} excedido",
|
||||
"File already exists" : "El archivo ya existe",
|
||||
"You have created a new board {board}" : "Has creado el tablero nuevo {board}",
|
||||
"{user} has created a new board {board}" : "{user} ha creado el tablero nuevo {board}",
|
||||
"You have deleted the board {board}" : "Has eliminado el tablero {board}",
|
||||
@@ -17,7 +19,7 @@ OC.L10N.register(
|
||||
"You have restored the board {board}" : "Has restaurado el tablero {board}",
|
||||
"{user} has restored the board {board}" : "{user} ha restaurado el tablero {board}",
|
||||
"You have shared the board {board} with {acl}" : "Has compartido el tablero {board} con {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} ha compartido el tablero {board} con {sharee}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} ha compartido el tablero {board} con {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Has eliminado a {acl} del tablero {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} ha elimiando a {acl} del tablero {board}",
|
||||
"You have renamed the board {before} to {board}" : "Has renombrado el tablero {before} como {board}",
|
||||
@@ -75,6 +77,7 @@ OC.L10N.register(
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "Una <strong>descripción de tarjeta</strong> dentro de la app Deck ha cambiado",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Cambios en la <strong>app Deck</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Un <strong>comment</strong> ha sido creado en una tarjeta",
|
||||
"Personal" : "Personal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La tarjeta \"%s\" en \"%s\" te ha sido asignada por %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} te ha asignado la tarjeta \"%s\" en \"%s\".",
|
||||
@@ -105,6 +108,8 @@ OC.L10N.register(
|
||||
"No file uploaded or file size exceeds maximum of %s" : "No se ha subido ningún archivo, o el tamaño del archivo excede el máximo de %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Una herramienta de manejo de proyectos y personal al estilo kanban para Nextcloud.",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos integrados con Nextcloud.\n\n\n- 📥 Agrega tus tareas a las tarjetas y ordénalas.\n- 📄 Escriba notas adicionales\n- 🔖 Asignar etiquetas para una organización mejor\n- 👥 Comparte con tu equipo, amigos o familia.\n- 📎 Adjuntar archivos e incrustarlos en su descripción\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organiza tu proyecto",
|
||||
"Select the board to link to a project" : "Selecciona el tablero que enlazar a un proyecto",
|
||||
"Select board" : "Selecciona tablero",
|
||||
"Add a new stack" : "Añadir nuevo montón",
|
||||
"Submit" : "Enviar",
|
||||
"Show archived cards" : "Mostrar tarjetas archivadas",
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
"Remove user from card" : "Eliminar usuario de la tarjeta",
|
||||
"Hours" : "Horas",
|
||||
"Minutes" : "Minutos",
|
||||
"Link to a board" : "Enlace a un tablero",
|
||||
"Maximum file size of {size} exceeded" : "Tamaño máximo de archivo de {size} excedido",
|
||||
"File already exists" : "El archivo ya existe",
|
||||
"You have created a new board {board}" : "Has creado el tablero nuevo {board}",
|
||||
"{user} has created a new board {board}" : "{user} ha creado el tablero nuevo {board}",
|
||||
"You have deleted the board {board}" : "Has eliminado el tablero {board}",
|
||||
@@ -15,7 +17,7 @@
|
||||
"You have restored the board {board}" : "Has restaurado el tablero {board}",
|
||||
"{user} has restored the board {board}" : "{user} ha restaurado el tablero {board}",
|
||||
"You have shared the board {board} with {acl}" : "Has compartido el tablero {board} con {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} ha compartido el tablero {board} con {sharee}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} ha compartido el tablero {board} con {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Has eliminado a {acl} del tablero {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} ha elimiando a {acl} del tablero {board}",
|
||||
"You have renamed the board {before} to {board}" : "Has renombrado el tablero {before} como {board}",
|
||||
@@ -73,6 +75,7 @@
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "Una <strong>descripción de tarjeta</strong> dentro de la app Deck ha cambiado",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Cambios en la <strong>app Deck</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Un <strong>comment</strong> ha sido creado en una tarjeta",
|
||||
"Personal" : "Personal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La tarjeta \"%s\" en \"%s\" te ha sido asignada por %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} te ha asignado la tarjeta \"%s\" en \"%s\".",
|
||||
@@ -103,6 +106,8 @@
|
||||
"No file uploaded or file size exceeds maximum of %s" : "No se ha subido ningún archivo, o el tamaño del archivo excede el máximo de %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Una herramienta de manejo de proyectos y personal al estilo kanban para Nextcloud.",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck es una herramienta de organización de estilo kanban dirigida a la planificación personal y la organización de proyectos para equipos integrados con Nextcloud.\n\n\n- 📥 Agrega tus tareas a las tarjetas y ordénalas.\n- 📄 Escriba notas adicionales\n- 🔖 Asignar etiquetas para una organización mejor\n- 👥 Comparte con tu equipo, amigos o familia.\n- 📎 Adjuntar archivos e incrustarlos en su descripción\n- 💬 Discuta con su equipo usando comentarios.\n- ⚡ Mantenga un registro de los cambios en el flujo de actividad\n- 🚀 Organiza tu proyecto",
|
||||
"Select the board to link to a project" : "Selecciona el tablero que enlazar a un proyecto",
|
||||
"Select board" : "Selecciona tablero",
|
||||
"Add a new stack" : "Añadir nuevo montón",
|
||||
"Submit" : "Enviar",
|
||||
"Show archived cards" : "Mostrar tarjetas archivadas",
|
||||
|
||||
32
l10n/es_AR.js
Normal file
32
l10n/es_AR.js
Normal file
@@ -0,0 +1,32 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Deck" : "Deck",
|
||||
"Finished" : "Terminado",
|
||||
"To review" : "Para revisar",
|
||||
"Action needed" : "Acción requerida",
|
||||
"Later" : "Después",
|
||||
"Show archived cards" : "Mostrar tarjetas archivadas",
|
||||
"Hide archived cards" : "Ocultar tarjetas archivadas",
|
||||
"All Boards" : "Todos los Tablero",
|
||||
"Enter a card title" : "Ingrese el títilo de la tarjeta",
|
||||
"Sharing" : "Compartiendo",
|
||||
"Select users or groups to share with" : "Seleccione los usuarios o grupos con los cuales compartir",
|
||||
"No matching user or group found." : "No se encontraron coincidencias de usuarios o grupos.",
|
||||
"Edit" : "Editar",
|
||||
"Share" : "Compartir",
|
||||
"Manage" : "Administrar",
|
||||
"Discard share" : "Descartar elemento compartido",
|
||||
"Members" : "Miembros",
|
||||
"Create new board" : "Crear un nuevo tablero",
|
||||
"New board title" : "Nuevo título de tablero",
|
||||
"by" : "por",
|
||||
"Modified:" : "Modificado:",
|
||||
"Created:" : "Creado:",
|
||||
"Description" : "Descripción",
|
||||
"Saved" : "Guardado",
|
||||
"Formatting help" : "Ayuda de formato",
|
||||
"Add a card description…" : "Agregar una descripción de tarjeta...",
|
||||
"Create a new board" : "Crear nuevo tablero"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
30
l10n/es_AR.json
Normal file
30
l10n/es_AR.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{ "translations": {
|
||||
"Deck" : "Deck",
|
||||
"Finished" : "Terminado",
|
||||
"To review" : "Para revisar",
|
||||
"Action needed" : "Acción requerida",
|
||||
"Later" : "Después",
|
||||
"Show archived cards" : "Mostrar tarjetas archivadas",
|
||||
"Hide archived cards" : "Ocultar tarjetas archivadas",
|
||||
"All Boards" : "Todos los Tablero",
|
||||
"Enter a card title" : "Ingrese el títilo de la tarjeta",
|
||||
"Sharing" : "Compartiendo",
|
||||
"Select users or groups to share with" : "Seleccione los usuarios o grupos con los cuales compartir",
|
||||
"No matching user or group found." : "No se encontraron coincidencias de usuarios o grupos.",
|
||||
"Edit" : "Editar",
|
||||
"Share" : "Compartir",
|
||||
"Manage" : "Administrar",
|
||||
"Discard share" : "Descartar elemento compartido",
|
||||
"Members" : "Miembros",
|
||||
"Create new board" : "Crear un nuevo tablero",
|
||||
"New board title" : "Nuevo título de tablero",
|
||||
"by" : "por",
|
||||
"Modified:" : "Modificado:",
|
||||
"Created:" : "Creado:",
|
||||
"Description" : "Descripción",
|
||||
"Saved" : "Guardado",
|
||||
"Formatting help" : "Ayuda de formato",
|
||||
"Add a card description…" : "Agregar una descripción de tarjeta...",
|
||||
"Create a new board" : "Crear nuevo tablero"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
65
l10n/fi.js
65
l10n/fi.js
@@ -1,11 +1,37 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Please provide a content for your comment." : "Kirjoita sisältö kommenttiisi.",
|
||||
"Posting the comment failed." : "Kommentin lähettäminen epäonnistui.",
|
||||
"The comment has been deleted" : "Kommentti on poistettu",
|
||||
"Remove user from card" : "Poista käyttäjä kortilta",
|
||||
"Hours" : "Tunnit",
|
||||
"Minutes" : "Minuutit",
|
||||
"Link to a board" : "Linkki taululle",
|
||||
"Maximum file size of {size} exceeded" : "Tiedoston enimmäiskoko {size} ylitetty",
|
||||
"File already exists" : "Tiedosto on jo olemassa",
|
||||
"You have created a new board {board}" : "Loit uuden taulun {board}",
|
||||
"{user} has created a new board {board}" : "{user} loi uuden taulun {board}",
|
||||
"You have deleted the board {board}" : "Poistit taulun {board}",
|
||||
"{user} has deleted the board {board}" : "{user} poisti taulun {board}",
|
||||
"You have restored the board {board}" : "Palautit taulun {board}",
|
||||
"{user} has restored the board {board}" : "{user} palautti taulun {board}",
|
||||
"You have renamed the board {before} to {board}" : "Asetit taulun {before} uudeksi nimeksi {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} asetti taulun {before} uudeksi nimeksi {board}",
|
||||
"You have archived the board {board}" : "Arkistoit taulun {board}",
|
||||
"{user} has archived the board {before}" : "{user} arkistoi taulun {before}",
|
||||
"You have renamed the card {before} to {card}" : "Muutit kortin {before} uudeksi nimeksi {card}",
|
||||
"{user} has renamed the card {before} to {card}" : "{user} muutti kortin {before} uudeksi nimeksi {card}",
|
||||
"You have added the attachment {attachment} to card {card}" : "Lisäsit liitteen {attachment} kortille {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} lisäsi liitteen {attachment} kortille {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Poistit liitteen {attachment} kortilta {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Palautit liitteen {attachment} kortille {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} palautti liitteen {attachment} kortille {card}",
|
||||
"You have commented on card {card}" : "Kommentoit korttia {card}",
|
||||
"{user} has commented on card {card}" : "{user} kommentoi korttia {card}",
|
||||
"Deck" : "Kansi",
|
||||
"A <strong>comment</strong> was created on a card" : "<strong>Kommentti</strong> luotiin kortille",
|
||||
"Personal" : "Henkilökohtainen",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Kortin \"%s\" on \"%s\" eräpäivä on tullut vastaan.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Taulu \"%s\" on jaettu kanssasi käyttäjän %s toimesta.",
|
||||
"{user} has shared the board %s with you." : "{user} on jakanut taulun %s kanssasi.",
|
||||
@@ -13,32 +39,61 @@ OC.L10N.register(
|
||||
"To review" : "Arvostella",
|
||||
"Action needed" : "Toimia vaaditaan",
|
||||
"Later" : "Myöhemmin",
|
||||
"To do" : "Odottaa",
|
||||
"Doing" : "Tekeillä",
|
||||
"Done" : "Valmis",
|
||||
"Example Task 3" : "Esimerkkitehtävä 3",
|
||||
"Example Task 2" : "Esimerkkitehtävä 2",
|
||||
"Example Task 1" : "Esimerkkitehtävä 1",
|
||||
"The file was uploaded" : "Tiedosto lähetettiin",
|
||||
"The file was only partially uploaded" : "Tiedosto lähetettiin vain osittain",
|
||||
"No file was uploaded" : "Tiedostoa ei lähetetty",
|
||||
"Could not write file to disk" : "Tiedostoa ei voitu kirjoittaa levylle",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Kanban-tyylinen projektien ja henkilökohtaisten asioiden hallintatyökalu Nextcloudille",
|
||||
"Select the board to link to a project" : "Valitse projektiin linkitettävä taulu",
|
||||
"Select board" : "Valitse taulu",
|
||||
"Add a new stack" : "Lisää uusi pino",
|
||||
"Submit" : "Lähetä",
|
||||
"Show archived cards" : "Näytä arkistoidut kortit",
|
||||
"Hide archived cards" : "Piilota arkistoidut kortit",
|
||||
"Show board details" : "Näytä taulun tiedot",
|
||||
"All Boards" : "Kaikki taulut",
|
||||
"Archived boards" : "Arkistoidut taulut",
|
||||
"Share board" : "Jaa taulu",
|
||||
"Archived cards" : "Arkistoidut kortit",
|
||||
"Actions" : "Toiminnot",
|
||||
"Drop your files here to upload it to the card" : "Pudota tiedostot tähän lähettääksesi ne kortille",
|
||||
"Assign card to me" : "Määritä kortti minulle",
|
||||
"Unassign card from me" : "Poista kortin määritys minulta",
|
||||
"Archive card" : "Arkistoi kortti",
|
||||
"Unarchive card" : "Poista kortti arkistosta",
|
||||
"Delete card" : "Poista kortti",
|
||||
"Enter a card title" : "Anna otsikko",
|
||||
"Add card" : "Lisää kortti",
|
||||
"Close" : "Sulje",
|
||||
"Sharing" : "Jakaminen",
|
||||
"Tags" : "Tunnisteet",
|
||||
"Deleted items" : "Poistetut tietueet",
|
||||
"Timeline" : "Aikajana",
|
||||
"Select users or groups to share with" : "Valitse käyttäjiä tai ryhmiä joille haluat jakaa",
|
||||
"Group" : "Ryhmä",
|
||||
"Circle" : "Piiri",
|
||||
"No matching user or group found." : "Käyttäjää tai ryhmää ei löytynyt.",
|
||||
"Loading" : "Ladataan",
|
||||
"Edit" : "Muokkaa",
|
||||
"Share" : "Jaa",
|
||||
"Manage" : "Hallitse",
|
||||
"Discard share" : "Peru jakaminen",
|
||||
"Sharing has been disabled for your account." : "Jakaminen on poistettu käytöstä tililtäsi.",
|
||||
"Update tag" : "Päivitä tunniste",
|
||||
"Edit tag" : "Muokkaa tunnistetta",
|
||||
"Delete tag" : "Poista tunniste",
|
||||
"Create" : "Luo",
|
||||
"Create a new tag" : "Luo uusi tunniste",
|
||||
"Deleted cards" : "Poistetut kortit",
|
||||
"Status" : "Tila",
|
||||
"No archived boards to display" : "Ei arkistoituja tauluja näytettäväksi",
|
||||
"No shared boards to display" : "Ei jaettuja tauluja näytettäväksi",
|
||||
"Title" : "Otsikko",
|
||||
"Members" : "Jäsenet",
|
||||
"More actions" : "Lisää toimintoja",
|
||||
@@ -46,11 +101,17 @@ OC.L10N.register(
|
||||
"Archive board" : "Arkistoi taulu",
|
||||
"Unarchive board" : "Kumoa taulun arkistointi",
|
||||
"Delete board" : "Poista taulu",
|
||||
"Update board" : "Päivitä taulu",
|
||||
"Reset board" : "Nollaa taulu",
|
||||
"Create new board" : "Luo uusi taulu",
|
||||
"New board title" : "Uusi taulun otsikko",
|
||||
"Create board" : "Luo taulu",
|
||||
"Select an attachment" : "Valitse liite",
|
||||
"Cancel upload" : "Peruuta lähetys",
|
||||
"by" : " Kirjoittaja:",
|
||||
"Undo file deletion" : "Kumoa tiedoston luonti",
|
||||
"Insert the file into the description" : "Lisää tiedosto kuvaukseen",
|
||||
"Delete attachment" : "Poista liite",
|
||||
"Modified:" : "Muokattu:",
|
||||
"Created:" : "Luotu:",
|
||||
"Choose a tag" : "Valitse tunniste",
|
||||
@@ -66,11 +127,13 @@ OC.L10N.register(
|
||||
"Attachments" : "Liitteet",
|
||||
"Saved" : "Tallennettu",
|
||||
"Unsaved changes" : "Tallentamattomia muutoksia",
|
||||
"Insert attachment" : "Lisää liite",
|
||||
"Formatting help" : "Muotoiluapu",
|
||||
"Upload attachment" : "Lähetä liite",
|
||||
"Add a card description…" : "Lisää kortin kuvaus…",
|
||||
"Shared boards" : "Jaetut taulut",
|
||||
"Move board to archive" : "Siirrä taulu arkistoon",
|
||||
"Create a new board" : "Luo uusi taulu"
|
||||
"Create a new board" : "Luo uusi taulu",
|
||||
"Settings" : "Asetukset"
|
||||
},
|
||||
"nplurals=2; plural=(n != 1);");
|
||||
|
||||
65
l10n/fi.json
65
l10n/fi.json
@@ -1,9 +1,35 @@
|
||||
{ "translations": {
|
||||
"Please provide a content for your comment." : "Kirjoita sisältö kommenttiisi.",
|
||||
"Posting the comment failed." : "Kommentin lähettäminen epäonnistui.",
|
||||
"The comment has been deleted" : "Kommentti on poistettu",
|
||||
"Remove user from card" : "Poista käyttäjä kortilta",
|
||||
"Hours" : "Tunnit",
|
||||
"Minutes" : "Minuutit",
|
||||
"Link to a board" : "Linkki taululle",
|
||||
"Maximum file size of {size} exceeded" : "Tiedoston enimmäiskoko {size} ylitetty",
|
||||
"File already exists" : "Tiedosto on jo olemassa",
|
||||
"You have created a new board {board}" : "Loit uuden taulun {board}",
|
||||
"{user} has created a new board {board}" : "{user} loi uuden taulun {board}",
|
||||
"You have deleted the board {board}" : "Poistit taulun {board}",
|
||||
"{user} has deleted the board {board}" : "{user} poisti taulun {board}",
|
||||
"You have restored the board {board}" : "Palautit taulun {board}",
|
||||
"{user} has restored the board {board}" : "{user} palautti taulun {board}",
|
||||
"You have renamed the board {before} to {board}" : "Asetit taulun {before} uudeksi nimeksi {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} asetti taulun {before} uudeksi nimeksi {board}",
|
||||
"You have archived the board {board}" : "Arkistoit taulun {board}",
|
||||
"{user} has archived the board {before}" : "{user} arkistoi taulun {before}",
|
||||
"You have renamed the card {before} to {card}" : "Muutit kortin {before} uudeksi nimeksi {card}",
|
||||
"{user} has renamed the card {before} to {card}" : "{user} muutti kortin {before} uudeksi nimeksi {card}",
|
||||
"You have added the attachment {attachment} to card {card}" : "Lisäsit liitteen {attachment} kortille {card}",
|
||||
"{user} has added the attachment {attachment} to card {card}" : "{user} lisäsi liitteen {attachment} kortille {card}",
|
||||
"You have deleted the attachment {attachment} from card {card}" : "Poistit liitteen {attachment} kortilta {card}",
|
||||
"You have restored the attachment {attachment} to card {card}" : "Palautit liitteen {attachment} kortille {card}",
|
||||
"{user} has restored the attachment {attachment} to card {card}" : "{user} palautti liitteen {attachment} kortille {card}",
|
||||
"You have commented on card {card}" : "Kommentoit korttia {card}",
|
||||
"{user} has commented on card {card}" : "{user} kommentoi korttia {card}",
|
||||
"Deck" : "Kansi",
|
||||
"A <strong>comment</strong> was created on a card" : "<strong>Kommentti</strong> luotiin kortille",
|
||||
"Personal" : "Henkilökohtainen",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Kortin \"%s\" on \"%s\" eräpäivä on tullut vastaan.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Taulu \"%s\" on jaettu kanssasi käyttäjän %s toimesta.",
|
||||
"{user} has shared the board %s with you." : "{user} on jakanut taulun %s kanssasi.",
|
||||
@@ -11,32 +37,61 @@
|
||||
"To review" : "Arvostella",
|
||||
"Action needed" : "Toimia vaaditaan",
|
||||
"Later" : "Myöhemmin",
|
||||
"To do" : "Odottaa",
|
||||
"Doing" : "Tekeillä",
|
||||
"Done" : "Valmis",
|
||||
"Example Task 3" : "Esimerkkitehtävä 3",
|
||||
"Example Task 2" : "Esimerkkitehtävä 2",
|
||||
"Example Task 1" : "Esimerkkitehtävä 1",
|
||||
"The file was uploaded" : "Tiedosto lähetettiin",
|
||||
"The file was only partially uploaded" : "Tiedosto lähetettiin vain osittain",
|
||||
"No file was uploaded" : "Tiedostoa ei lähetetty",
|
||||
"Could not write file to disk" : "Tiedostoa ei voitu kirjoittaa levylle",
|
||||
"A kanban style project and personal management tool for Nextcloud" : "Kanban-tyylinen projektien ja henkilökohtaisten asioiden hallintatyökalu Nextcloudille",
|
||||
"Select the board to link to a project" : "Valitse projektiin linkitettävä taulu",
|
||||
"Select board" : "Valitse taulu",
|
||||
"Add a new stack" : "Lisää uusi pino",
|
||||
"Submit" : "Lähetä",
|
||||
"Show archived cards" : "Näytä arkistoidut kortit",
|
||||
"Hide archived cards" : "Piilota arkistoidut kortit",
|
||||
"Show board details" : "Näytä taulun tiedot",
|
||||
"All Boards" : "Kaikki taulut",
|
||||
"Archived boards" : "Arkistoidut taulut",
|
||||
"Share board" : "Jaa taulu",
|
||||
"Archived cards" : "Arkistoidut kortit",
|
||||
"Actions" : "Toiminnot",
|
||||
"Drop your files here to upload it to the card" : "Pudota tiedostot tähän lähettääksesi ne kortille",
|
||||
"Assign card to me" : "Määritä kortti minulle",
|
||||
"Unassign card from me" : "Poista kortin määritys minulta",
|
||||
"Archive card" : "Arkistoi kortti",
|
||||
"Unarchive card" : "Poista kortti arkistosta",
|
||||
"Delete card" : "Poista kortti",
|
||||
"Enter a card title" : "Anna otsikko",
|
||||
"Add card" : "Lisää kortti",
|
||||
"Close" : "Sulje",
|
||||
"Sharing" : "Jakaminen",
|
||||
"Tags" : "Tunnisteet",
|
||||
"Deleted items" : "Poistetut tietueet",
|
||||
"Timeline" : "Aikajana",
|
||||
"Select users or groups to share with" : "Valitse käyttäjiä tai ryhmiä joille haluat jakaa",
|
||||
"Group" : "Ryhmä",
|
||||
"Circle" : "Piiri",
|
||||
"No matching user or group found." : "Käyttäjää tai ryhmää ei löytynyt.",
|
||||
"Loading" : "Ladataan",
|
||||
"Edit" : "Muokkaa",
|
||||
"Share" : "Jaa",
|
||||
"Manage" : "Hallitse",
|
||||
"Discard share" : "Peru jakaminen",
|
||||
"Sharing has been disabled for your account." : "Jakaminen on poistettu käytöstä tililtäsi.",
|
||||
"Update tag" : "Päivitä tunniste",
|
||||
"Edit tag" : "Muokkaa tunnistetta",
|
||||
"Delete tag" : "Poista tunniste",
|
||||
"Create" : "Luo",
|
||||
"Create a new tag" : "Luo uusi tunniste",
|
||||
"Deleted cards" : "Poistetut kortit",
|
||||
"Status" : "Tila",
|
||||
"No archived boards to display" : "Ei arkistoituja tauluja näytettäväksi",
|
||||
"No shared boards to display" : "Ei jaettuja tauluja näytettäväksi",
|
||||
"Title" : "Otsikko",
|
||||
"Members" : "Jäsenet",
|
||||
"More actions" : "Lisää toimintoja",
|
||||
@@ -44,11 +99,17 @@
|
||||
"Archive board" : "Arkistoi taulu",
|
||||
"Unarchive board" : "Kumoa taulun arkistointi",
|
||||
"Delete board" : "Poista taulu",
|
||||
"Update board" : "Päivitä taulu",
|
||||
"Reset board" : "Nollaa taulu",
|
||||
"Create new board" : "Luo uusi taulu",
|
||||
"New board title" : "Uusi taulun otsikko",
|
||||
"Create board" : "Luo taulu",
|
||||
"Select an attachment" : "Valitse liite",
|
||||
"Cancel upload" : "Peruuta lähetys",
|
||||
"by" : " Kirjoittaja:",
|
||||
"Undo file deletion" : "Kumoa tiedoston luonti",
|
||||
"Insert the file into the description" : "Lisää tiedosto kuvaukseen",
|
||||
"Delete attachment" : "Poista liite",
|
||||
"Modified:" : "Muokattu:",
|
||||
"Created:" : "Luotu:",
|
||||
"Choose a tag" : "Valitse tunniste",
|
||||
@@ -64,11 +125,13 @@
|
||||
"Attachments" : "Liitteet",
|
||||
"Saved" : "Tallennettu",
|
||||
"Unsaved changes" : "Tallentamattomia muutoksia",
|
||||
"Insert attachment" : "Lisää liite",
|
||||
"Formatting help" : "Muotoiluapu",
|
||||
"Upload attachment" : "Lähetä liite",
|
||||
"Add a card description…" : "Lisää kortin kuvaus…",
|
||||
"Shared boards" : "Jaetut taulut",
|
||||
"Move board to archive" : "Siirrä taulu arkistoon",
|
||||
"Create a new board" : "Luo uusi taulu"
|
||||
"Create a new board" : "Luo uusi taulu",
|
||||
"Settings" : "Asetukset"
|
||||
},"pluralForm" :"nplurals=2; plural=(n != 1);"
|
||||
}
|
||||
88
l10n/fr.js
88
l10n/fr.js
@@ -1,7 +1,7 @@
|
||||
OC.L10N.register(
|
||||
"deck",
|
||||
{
|
||||
"Please provide a content for your comment." : "Merci de renseigner votre commentaire.",
|
||||
"Please provide a content for your comment." : "Merci de renseigner un contenu pour votre commentaire.",
|
||||
"Posting the comment failed." : "L'envoi du commentaire a échoué.",
|
||||
"The comment has been deleted" : "Le commentaire a été supprimé",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "La pile associée est également supprimée, elle sera également restaurée.",
|
||||
@@ -9,8 +9,9 @@ OC.L10N.register(
|
||||
"Remove user from card" : "Supprimer l'utilisateur de la carte",
|
||||
"Hours" : "Heures",
|
||||
"Minutes" : "Minutes",
|
||||
"Link to a board" : "Lien à un tableau",
|
||||
"Link to a board" : "Lier à un tableau",
|
||||
"Maximum file size of {size} exceeded" : "Taille de fichier maximale de {size} dépassée",
|
||||
"File already exists" : "Le fichier existe déjà",
|
||||
"You have created a new board {board}" : "Vous avez créé un nouveau tableau {tableau}",
|
||||
"{user} has created a new board {board}" : "{user} a créé un nouveau tableau {board}",
|
||||
"You have deleted the board {board}" : "Vous avez supprimé le tableau {board}",
|
||||
@@ -18,15 +19,15 @@ OC.L10N.register(
|
||||
"You have restored the board {board}" : "Vous avez restauré le tableau {board}",
|
||||
"{user} has restored the board {board}" : "{user} a restauré le tableau {board}",
|
||||
"You have shared the board {board} with {acl}" : "Vous avez partagé le tableau {board} avec {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} a partagé le tableau {board} avec {sharee}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} a partagé le tableau {board} en {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Vous avez supprimé {acl} du tableau {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} a supprimé {acl} du tableau {board}",
|
||||
"You have renamed the board {before} to {board}" : "Vous avez renommé le tableau {before} en {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} a renommé le tableau {before} à {board}",
|
||||
"You have archived the board {board}" : "Vous avez archivé le tableau {board}",
|
||||
"{user} has archived the board {before}" : "{user} a archivé le tableau {before}",
|
||||
"You have unarchived the board {board}" : "Vous avez sorti de l’archive le tableau {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} a sorti de l’archive le tableau {board}",
|
||||
"You have unarchived the board {board}" : "Vous avez sorti des archives le tableau {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} a sorti des archives le tableau {board}",
|
||||
"You have created a new stack {stack} on board {board}" : "Vous avez créé une nouvelle pile {stack} sur le tableau {board}",
|
||||
"{user} has created a new stack {stack} on board {board}" : "{user} a créé une nouvelle pile {stack} sur le tableau {board}",
|
||||
"You have renamed stack {before} to {stack} on board {board}" : "Vous avez renommé la pile {before} en {stack} sur le tableau {board}",
|
||||
@@ -45,22 +46,22 @@ OC.L10N.register(
|
||||
"{user} has updated the description of the card {card} in stack {stack} on board {board}" : "{user} a mis à jour la description de la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have archived card {card} in stack {stack} on board {board}" : "Vous avez archivé la carte {card} de la pile {stack} du tableau {board}",
|
||||
"{user} has archived card {card} in stack {stack} on board {board}" : "{user} a archivé la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have unarchived card {card} in stack {stack} on board {board}" : "Vous avez une carte {card} non-archivée dans la pile {stack} du tableau {board}",
|
||||
"{user} has unarchived card {card} in stack {stack} on board {board}" : "{user} a une carte {card} non-archivée dans la pile {stack} du tableau {board}",
|
||||
"You have removed the due date of card {card}" : "Vous avez supprimé la date limite de la carte {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} a supprimé la date limite de la carte {card}",
|
||||
"You have set the due date of card {card} to {after}" : "Vous avez établie la date limite de la carte {card} à {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} a établie la date limite de la carte {card} à {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Vous avez mis à jour la date limite de la carte {card} à {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} a mis à jour la date limite de la carte {card} à {after}",
|
||||
"You have unarchived card {card} in stack {stack} on board {board}" : "Vous avez retiré des archives la carte {card} de la pile {stack} du tableau {board}",
|
||||
"{user} has unarchived card {card} in stack {stack} on board {board}" : "{user} a retiré des archives la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have removed the due date of card {card}" : "Vous avez supprimé la date d'échéance de la carte {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} a supprimé la date d'échéance de la carte {card}",
|
||||
"You have set the due date of card {card} to {after}" : "Vous avez établi la date d'échéance de la carte {card} à {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} a établi la date d'échéance de la carte {card} à {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Vous avez mis à jour la date d'échéance de la carte {card} à {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} a mis à jour la date d'échéance de la carte {card} à {after}",
|
||||
"You have added the tag {label} to card {card} in stack {stack} on board {board}" : "Vous avez ajouté l'étiquette {label} à la carte {card} de la pile {stack} du tableau {board}",
|
||||
"{user} has added the tag {label} to card {card} in stack {stack} on board {board}" : "{user} a ajouté l'étiquette {label} à la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have removed the tag {label} from card {card} in stack {stack} on board {board}" : "Vous avez supprimé l'étiquette {label} de la carte {card} de la pile {stack} du tableau {board}",
|
||||
"{user} has removed the tag {label} from card {card} in stack {stack} on board {board}" : "{user} a supprimé l'étiquette {label} de la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "Vous avez assigné {assigneduser} à la carte {card} du tableau {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} a assigné {assigneduser} à la carte {card} du tableau {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Vous avez désassigner {assigneduser} de la carte {card} du tableau {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} a désassigner {assigneduser} de la carte {card} du tableau {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Vous avez retiré {assigneduser} de la carte {card} du tableau {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} a retiré {assigneduser} de la carte {card} du tableau {board}",
|
||||
"You have moved the card {card} from stack {stackBefore} to {stack}" : "Vous avez déplacé la carte {card} de la pile {stackBefore} vers {stack}",
|
||||
"{user} has moved the card {card} from stack {stackBefore} to {stack}" : "{user} a déplacé la carte {card} de la pile {stackBefore} vers {stack}",
|
||||
"You have added the attachment {attachment} to card {card}" : "Vous avez ajouté la pièce jointe {attachment} à la carte {card}",
|
||||
@@ -76,13 +77,14 @@ OC.L10N.register(
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "La <strong>description de la carte</strong> présente dans l’application Deck a été modifiée",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Modifications dans <strong>Deck app</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Un <strong>commentaire</strong> a été créé sur une carte",
|
||||
"Personal" : "Personnel",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La carte \"%s\" de \"%s\" vous a été assignée par %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} vous a assigné la carte \"%s\" de \"%s\".",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Le délai de la carte %s de %s est expiré.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "La date d'échéance de la carte \"%s\" de \"%s\" a été atteinte.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s vous a mentionné dans un commentaire sur \"%s\".",
|
||||
"{user} has mentioned you in a comment on \"%s\"." : " {user} vous a mentionné dans un commentaire sur \"%s\".",
|
||||
"The board \"%s\" has been shared with you by %s." : "Le tableau %s a été partagé avec vous par %s.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Le tableau \"%s\" a été partagé avec vous par %s.",
|
||||
"{user} has shared the board %s with you." : "{user} a partagé le tableau %s avec vous.",
|
||||
"No data was provided to create an attachment." : "Aucune donnée n'a été fournie pour créer une pièce jointe.",
|
||||
"Finished" : "Terminé",
|
||||
@@ -95,17 +97,17 @@ OC.L10N.register(
|
||||
"Example Task 3" : "Exemple de tâche 3",
|
||||
"Example Task 2" : "Exemple de tâche 2",
|
||||
"Example Task 1" : "Exemple de tâche 1",
|
||||
"The file was uploaded" : "Le fichier a été téléchargé",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Le fichier téléversé dépasse la valeur upload_max_filesize située dans le fichier php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Le fichier envoyé dépasse la valeur MAX_FILE_SIZE qui était spécifiée dans le formulaire HTML",
|
||||
"The file was uploaded" : "Le fichier a été envoyé",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Le fichier envoyé dépasse la valeur upload_max_filesize spécifiée dans php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Le fichier envoyé dépasse la valeur MAX_FILE_SIZE spécifiée dans le formulaire HTML",
|
||||
"The file was only partially uploaded" : "Le fichier n'a été que partiellement envoyé",
|
||||
"No file was uploaded" : "Aucun fichier n'a été téléchargé",
|
||||
"No file was uploaded" : "Aucun fichier n'a été envoyé",
|
||||
"Missing a temporary folder" : "Absence de dossier temporaire",
|
||||
"Could not write file to disk" : "Impossible d'écrire le fichier sur le disque.",
|
||||
"A PHP extension stopped the file upload" : "Une extension PHP a arrêté le téléversement du fichier",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Aucun fichier téléversé ou la taille du fichier dépasse la maximum de %s",
|
||||
"Could not write file to disk" : "Impossible d'écrire le fichier sur le disque",
|
||||
"A PHP extension stopped the file upload" : "Une extension PHP a arrêté l'envoi du fichier",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Aucun fichier envoyé ou la taille du fichier dépasse le maximum de %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : " Un outil de style kanban pour Nextcloud, pour la gestion de votre vie personnelle et de vos projets.",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck est un outil d'organisation de style kanban destiné à la planification personnelle et à l'organisation de projets pour les équipes intégrées à Nextcloud.\n\n\n- 📥 Ajoutez vos tâches à des cartes et organisez-les\n- 📄 Écrivez des notes supplémentaires en Markdown\n- 🔖 Affectez des étiquettes pour une organisation encore meilleure\n- 👥 Partagez avec votre équipe, vos amis ou votre famille\n- 📎 Attachez des fichiers et utilisez les dans vos descriptions en Markdown\n- 💬 Echanger avec votre équipe grâce aux commentaires\n- ⚡ Garder l'oeil sur les modifications dans le flux d'activité\n- 🚀 Organisez vos projets",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck est un outil d'organisation de style kanban destiné à la planification personnelle et à l'organisation de projets pour les équipes intégrées à Nextcloud.\n\n\n- 📥 Ajoutez vos tâches à des cartes et organisez-les\n- 📄 Écrivez des notes supplémentaires en Markdown\n- 🔖 Affectez des étiquettes pour une organisation encore meilleure\n- 👥 Partagez avec votre équipe, vos amis ou votre famille\n- 📎 Attachez des fichiers et utilisez les dans vos descriptions en Markdown\n- 💬 Échangez avec votre équipe grâce aux commentaires\n- ⚡ Gardez un œil sur les modifications dans le flux d'activité\n- 🚀 Organisez vos projets",
|
||||
"Select the board to link to a project" : "Sélection le tableau pour faire le lien avec un projet.",
|
||||
"Select board" : "Sélectionner le tableau",
|
||||
"Add a new stack" : "Ajouter une nouvelle pile",
|
||||
@@ -119,13 +121,13 @@ OC.L10N.register(
|
||||
"Share board" : "Partager le tableau",
|
||||
"Archived cards" : "Cartes archivées",
|
||||
"Actions" : "Actions",
|
||||
"Drop your files here to upload it to the card" : "Déposez vos fichiers ici pour les téléverser sur la carte",
|
||||
"Assign card to me" : "Assignez-moi la carte",
|
||||
"Unassign card from me" : "Retirez-moi la carte",
|
||||
"Drop your files here to upload it to the card" : "Déposez vos fichiers ici pour les envoyer sur la carte",
|
||||
"Assign card to me" : "M'assigner la carte",
|
||||
"Unassign card from me" : "Me retirer de la carte",
|
||||
"Archive card" : "Archiver la carte",
|
||||
"Unarchive card" : "Ne plus archiver la carte",
|
||||
"Unarchive card" : "Sortir la carte des archives",
|
||||
"Delete card" : "Supprimer la carte",
|
||||
"Enter a card title" : "Saisissez un titre de carte",
|
||||
"Enter a card title" : "Saisir un titre de carte",
|
||||
"Add card" : "Ajouter une carte",
|
||||
"Close" : "Fermer",
|
||||
"Sharing" : "Partage",
|
||||
@@ -135,7 +137,7 @@ OC.L10N.register(
|
||||
"Select users or groups to share with" : "Sélectionnez des utilisateurs ou des groupes avec qui partager",
|
||||
"Group" : "Groupe",
|
||||
"Circle" : "Cercle",
|
||||
"No matching user or group found." : "Aucun utilisateur ou groupe correspondant trouvé",
|
||||
"No matching user or group found." : "Aucun utilisateur ou groupe correspondant trouvé.",
|
||||
"Loading" : "Chargement",
|
||||
"Edit" : "Modifier",
|
||||
"Share" : "Partager",
|
||||
@@ -157,23 +159,23 @@ OC.L10N.register(
|
||||
"More actions" : "Plus d'actions",
|
||||
"Edit board" : "Modifier le tableau",
|
||||
"Archive board" : "Archiver le tableau",
|
||||
"Unarchive board" : "Ne plus archiver le tableau",
|
||||
"Unarchive board" : "Sortir le tableau des archives",
|
||||
"Delete board" : "Supprimer le tableau",
|
||||
"Update board" : "Mettre à jour le tableau",
|
||||
"Reset board" : "Réinitialiser le tableau",
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Annuler la suppression du tableau — Autrement le tableau sera supprimé lors du prochain lancement de la tâche cron.",
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Annuler la suppression du tableau — Autrement le tableau sera supprimé lors de la prochaine tâche cron.",
|
||||
"Create new board" : "Créer un nouveau tableau",
|
||||
"New board title" : "Nouveau titre pour le tableau",
|
||||
"Create board" : "Créer le tableau",
|
||||
"Select an attachment" : "Sélectionner une pièce jointe",
|
||||
"Cancel upload" : "Annuler le téléversement",
|
||||
"Cancel upload" : "Annuler l'envoi",
|
||||
"by" : "par",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Annuler la suppression du fichier — Autrement le fichier sera supprimé lors du prochain lancement de la tâche cron.",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Annuler la suppression du fichier — Autrement le fichier sera supprimé lors de la prochaine tâche cron.",
|
||||
"Undo file deletion" : "Annuler la suppression du fichier",
|
||||
"Insert the file into the description" : "Insérer le fichier dans la description",
|
||||
"Delete attachment" : "Supprimer la pièce jointe",
|
||||
"Modified:" : "Modifié le :",
|
||||
"Created:" : "Créé le :",
|
||||
"Modified:" : "Modifiée le :",
|
||||
"Created:" : "Créée le :",
|
||||
"Choose a tag" : "Choisir une étiquette",
|
||||
"Add a tag" : "Ajouter une étiquette",
|
||||
"Select tags" : "Sélectionner les étiquettes",
|
||||
@@ -181,21 +183,21 @@ OC.L10N.register(
|
||||
"Choose a user to assign" : "Choisir un utilisateur à assigner",
|
||||
"Assign this card to a user" : "Assigner cette carte à un utilisateur",
|
||||
"Due date" : "Date d'échéance",
|
||||
"Click to set" : "Cliquez pour définir",
|
||||
"Click to set" : "Cliquer pour définir",
|
||||
"Remove due date" : "Supprimer la date d'échéance",
|
||||
"Description" : "Description",
|
||||
"Attachments" : "Pièces jointes",
|
||||
"Saved" : "Enregistré",
|
||||
"Unsaved changes" : "Modifications non sauvegardées",
|
||||
"Unsaved changes" : "Modifications non enregistrées",
|
||||
"Insert attachment" : "Insérer une pièce jointe",
|
||||
"Formatting help" : "Aide sur la mise en forme",
|
||||
"Upload attachment" : "Téléverser la pièce jointe",
|
||||
"Add a card description…" : "Ajouter une description pour la carte",
|
||||
"Upload attachment" : "Envoyer une pièce jointe",
|
||||
"Add a card description…" : "Ajouter une description pour la carte...",
|
||||
"Shared boards" : "Tableaux partagés",
|
||||
"Move board to archive" : "Déplacer le tableau vers l'archive",
|
||||
"Move board to archive" : "Déplacer le tableau vers les archives",
|
||||
"Create a new board" : "Créer un nouveau tableau",
|
||||
"Settings" : "Paramètres",
|
||||
"Limit deck to groups" : "Limiter deck aux groupes",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limiter le Deck empêchera les utilisateurs ne faisant pas partie de ces groupes de créer leurs propres tableaux. Les utilisateurs pourront toujours travailler sur des tableaux qui ont été partagés avec eux."
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limiter Deck empêchera les utilisateurs ne faisant pas partie de ces groupes de créer leurs propres tableaux. Ces utilisateurs pourront toujours travailler sur les tableaux qui ont été partagés avec eux."
|
||||
},
|
||||
"nplurals=2; plural=(n > 1);");
|
||||
|
||||
88
l10n/fr.json
88
l10n/fr.json
@@ -1,5 +1,5 @@
|
||||
{ "translations": {
|
||||
"Please provide a content for your comment." : "Merci de renseigner votre commentaire.",
|
||||
"Please provide a content for your comment." : "Merci de renseigner un contenu pour votre commentaire.",
|
||||
"Posting the comment failed." : "L'envoi du commentaire a échoué.",
|
||||
"The comment has been deleted" : "Le commentaire a été supprimé",
|
||||
"The associated stack is deleted as well, it will be restored as well." : "La pile associée est également supprimée, elle sera également restaurée.",
|
||||
@@ -7,8 +7,9 @@
|
||||
"Remove user from card" : "Supprimer l'utilisateur de la carte",
|
||||
"Hours" : "Heures",
|
||||
"Minutes" : "Minutes",
|
||||
"Link to a board" : "Lien à un tableau",
|
||||
"Link to a board" : "Lier à un tableau",
|
||||
"Maximum file size of {size} exceeded" : "Taille de fichier maximale de {size} dépassée",
|
||||
"File already exists" : "Le fichier existe déjà",
|
||||
"You have created a new board {board}" : "Vous avez créé un nouveau tableau {tableau}",
|
||||
"{user} has created a new board {board}" : "{user} a créé un nouveau tableau {board}",
|
||||
"You have deleted the board {board}" : "Vous avez supprimé le tableau {board}",
|
||||
@@ -16,15 +17,15 @@
|
||||
"You have restored the board {board}" : "Vous avez restauré le tableau {board}",
|
||||
"{user} has restored the board {board}" : "{user} a restauré le tableau {board}",
|
||||
"You have shared the board {board} with {acl}" : "Vous avez partagé le tableau {board} avec {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} a partagé le tableau {board} avec {sharee}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} a partagé le tableau {board} en {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Vous avez supprimé {acl} du tableau {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} a supprimé {acl} du tableau {board}",
|
||||
"You have renamed the board {before} to {board}" : "Vous avez renommé le tableau {before} en {board}",
|
||||
"{user} has renamed the board {before} to {board}" : "{user} a renommé le tableau {before} à {board}",
|
||||
"You have archived the board {board}" : "Vous avez archivé le tableau {board}",
|
||||
"{user} has archived the board {before}" : "{user} a archivé le tableau {before}",
|
||||
"You have unarchived the board {board}" : "Vous avez sorti de l’archive le tableau {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} a sorti de l’archive le tableau {board}",
|
||||
"You have unarchived the board {board}" : "Vous avez sorti des archives le tableau {board}",
|
||||
"{user} has unarchived the board {before}" : "{user} a sorti des archives le tableau {board}",
|
||||
"You have created a new stack {stack} on board {board}" : "Vous avez créé une nouvelle pile {stack} sur le tableau {board}",
|
||||
"{user} has created a new stack {stack} on board {board}" : "{user} a créé une nouvelle pile {stack} sur le tableau {board}",
|
||||
"You have renamed stack {before} to {stack} on board {board}" : "Vous avez renommé la pile {before} en {stack} sur le tableau {board}",
|
||||
@@ -43,22 +44,22 @@
|
||||
"{user} has updated the description of the card {card} in stack {stack} on board {board}" : "{user} a mis à jour la description de la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have archived card {card} in stack {stack} on board {board}" : "Vous avez archivé la carte {card} de la pile {stack} du tableau {board}",
|
||||
"{user} has archived card {card} in stack {stack} on board {board}" : "{user} a archivé la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have unarchived card {card} in stack {stack} on board {board}" : "Vous avez une carte {card} non-archivée dans la pile {stack} du tableau {board}",
|
||||
"{user} has unarchived card {card} in stack {stack} on board {board}" : "{user} a une carte {card} non-archivée dans la pile {stack} du tableau {board}",
|
||||
"You have removed the due date of card {card}" : "Vous avez supprimé la date limite de la carte {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} a supprimé la date limite de la carte {card}",
|
||||
"You have set the due date of card {card} to {after}" : "Vous avez établie la date limite de la carte {card} à {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} a établie la date limite de la carte {card} à {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Vous avez mis à jour la date limite de la carte {card} à {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} a mis à jour la date limite de la carte {card} à {after}",
|
||||
"You have unarchived card {card} in stack {stack} on board {board}" : "Vous avez retiré des archives la carte {card} de la pile {stack} du tableau {board}",
|
||||
"{user} has unarchived card {card} in stack {stack} on board {board}" : "{user} a retiré des archives la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have removed the due date of card {card}" : "Vous avez supprimé la date d'échéance de la carte {card}",
|
||||
"{user} has removed the due date of card {card}" : "{user} a supprimé la date d'échéance de la carte {card}",
|
||||
"You have set the due date of card {card} to {after}" : "Vous avez établi la date d'échéance de la carte {card} à {after}",
|
||||
"{user} has set the due date of card {card} to {after}" : "{user} a établi la date d'échéance de la carte {card} à {after}",
|
||||
"You have updated the due date of card {card} to {after}" : "Vous avez mis à jour la date d'échéance de la carte {card} à {after}",
|
||||
"{user} has updated the due date of card {card} to {after}" : "{user} a mis à jour la date d'échéance de la carte {card} à {after}",
|
||||
"You have added the tag {label} to card {card} in stack {stack} on board {board}" : "Vous avez ajouté l'étiquette {label} à la carte {card} de la pile {stack} du tableau {board}",
|
||||
"{user} has added the tag {label} to card {card} in stack {stack} on board {board}" : "{user} a ajouté l'étiquette {label} à la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have removed the tag {label} from card {card} in stack {stack} on board {board}" : "Vous avez supprimé l'étiquette {label} de la carte {card} de la pile {stack} du tableau {board}",
|
||||
"{user} has removed the tag {label} from card {card} in stack {stack} on board {board}" : "{user} a supprimé l'étiquette {label} de la carte {card} de la pile {stack} du tableau {board}",
|
||||
"You have assigned {assigneduser} to card {card} on board {board}" : "Vous avez assigné {assigneduser} à la carte {card} du tableau {board}",
|
||||
"{user} has assigned {assigneduser} to card {card} on board {board}" : "{user} a assigné {assigneduser} à la carte {card} du tableau {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Vous avez désassigner {assigneduser} de la carte {card} du tableau {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} a désassigner {assigneduser} de la carte {card} du tableau {board}",
|
||||
"You have unassigned {assigneduser} from card {card} on board {board}" : "Vous avez retiré {assigneduser} de la carte {card} du tableau {board}",
|
||||
"{user} has unassigned {assigneduser} from card {card} on board {board}" : "{user} a retiré {assigneduser} de la carte {card} du tableau {board}",
|
||||
"You have moved the card {card} from stack {stackBefore} to {stack}" : "Vous avez déplacé la carte {card} de la pile {stackBefore} vers {stack}",
|
||||
"{user} has moved the card {card} from stack {stackBefore} to {stack}" : "{user} a déplacé la carte {card} de la pile {stackBefore} vers {stack}",
|
||||
"You have added the attachment {attachment} to card {card}" : "Vous avez ajouté la pièce jointe {attachment} à la carte {card}",
|
||||
@@ -74,13 +75,14 @@
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "La <strong>description de la carte</strong> présente dans l’application Deck a été modifiée",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Modifications dans <strong>Deck app</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Un <strong>commentaire</strong> a été créé sur une carte",
|
||||
"Personal" : "Personnel",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "La carte \"%s\" de \"%s\" vous a été assignée par %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} vous a assigné la carte \"%s\" de \"%s\".",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "Le délai de la carte %s de %s est expiré.",
|
||||
"The card \"%s\" on \"%s\" has reached its due date." : "La date d'échéance de la carte \"%s\" de \"%s\" a été atteinte.",
|
||||
"%s has mentioned you in a comment on \"%s\"." : "%s vous a mentionné dans un commentaire sur \"%s\".",
|
||||
"{user} has mentioned you in a comment on \"%s\"." : " {user} vous a mentionné dans un commentaire sur \"%s\".",
|
||||
"The board \"%s\" has been shared with you by %s." : "Le tableau %s a été partagé avec vous par %s.",
|
||||
"The board \"%s\" has been shared with you by %s." : "Le tableau \"%s\" a été partagé avec vous par %s.",
|
||||
"{user} has shared the board %s with you." : "{user} a partagé le tableau %s avec vous.",
|
||||
"No data was provided to create an attachment." : "Aucune donnée n'a été fournie pour créer une pièce jointe.",
|
||||
"Finished" : "Terminé",
|
||||
@@ -93,17 +95,17 @@
|
||||
"Example Task 3" : "Exemple de tâche 3",
|
||||
"Example Task 2" : "Exemple de tâche 2",
|
||||
"Example Task 1" : "Exemple de tâche 1",
|
||||
"The file was uploaded" : "Le fichier a été téléchargé",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Le fichier téléversé dépasse la valeur upload_max_filesize située dans le fichier php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Le fichier envoyé dépasse la valeur MAX_FILE_SIZE qui était spécifiée dans le formulaire HTML",
|
||||
"The file was uploaded" : "Le fichier a été envoyé",
|
||||
"The uploaded file exceeds the upload_max_filesize directive in php.ini" : "Le fichier envoyé dépasse la valeur upload_max_filesize spécifiée dans php.ini",
|
||||
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form" : "Le fichier envoyé dépasse la valeur MAX_FILE_SIZE spécifiée dans le formulaire HTML",
|
||||
"The file was only partially uploaded" : "Le fichier n'a été que partiellement envoyé",
|
||||
"No file was uploaded" : "Aucun fichier n'a été téléchargé",
|
||||
"No file was uploaded" : "Aucun fichier n'a été envoyé",
|
||||
"Missing a temporary folder" : "Absence de dossier temporaire",
|
||||
"Could not write file to disk" : "Impossible d'écrire le fichier sur le disque.",
|
||||
"A PHP extension stopped the file upload" : "Une extension PHP a arrêté le téléversement du fichier",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Aucun fichier téléversé ou la taille du fichier dépasse la maximum de %s",
|
||||
"Could not write file to disk" : "Impossible d'écrire le fichier sur le disque",
|
||||
"A PHP extension stopped the file upload" : "Une extension PHP a arrêté l'envoi du fichier",
|
||||
"No file uploaded or file size exceeds maximum of %s" : "Aucun fichier envoyé ou la taille du fichier dépasse le maximum de %s",
|
||||
"A kanban style project and personal management tool for Nextcloud" : " Un outil de style kanban pour Nextcloud, pour la gestion de votre vie personnelle et de vos projets.",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck est un outil d'organisation de style kanban destiné à la planification personnelle et à l'organisation de projets pour les équipes intégrées à Nextcloud.\n\n\n- 📥 Ajoutez vos tâches à des cartes et organisez-les\n- 📄 Écrivez des notes supplémentaires en Markdown\n- 🔖 Affectez des étiquettes pour une organisation encore meilleure\n- 👥 Partagez avec votre équipe, vos amis ou votre famille\n- 📎 Attachez des fichiers et utilisez les dans vos descriptions en Markdown\n- 💬 Echanger avec votre équipe grâce aux commentaires\n- ⚡ Garder l'oeil sur les modifications dans le flux d'activité\n- 🚀 Organisez vos projets",
|
||||
"Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.\n\n\n- 📥 Add your tasks to cards and put them in order\n- 📄 Write down additional notes in markdown\n- 🔖 Assign labels for even better organization\n- 👥 Share with your team, friends or family\n- 📎 Attach files and embed them in your markdown description\n- 💬 Discuss with your team using comments\n- ⚡ Keep track of changes in the activity stream\n- 🚀 Get your project organized" : "Deck est un outil d'organisation de style kanban destiné à la planification personnelle et à l'organisation de projets pour les équipes intégrées à Nextcloud.\n\n\n- 📥 Ajoutez vos tâches à des cartes et organisez-les\n- 📄 Écrivez des notes supplémentaires en Markdown\n- 🔖 Affectez des étiquettes pour une organisation encore meilleure\n- 👥 Partagez avec votre équipe, vos amis ou votre famille\n- 📎 Attachez des fichiers et utilisez les dans vos descriptions en Markdown\n- 💬 Échangez avec votre équipe grâce aux commentaires\n- ⚡ Gardez un œil sur les modifications dans le flux d'activité\n- 🚀 Organisez vos projets",
|
||||
"Select the board to link to a project" : "Sélection le tableau pour faire le lien avec un projet.",
|
||||
"Select board" : "Sélectionner le tableau",
|
||||
"Add a new stack" : "Ajouter une nouvelle pile",
|
||||
@@ -117,13 +119,13 @@
|
||||
"Share board" : "Partager le tableau",
|
||||
"Archived cards" : "Cartes archivées",
|
||||
"Actions" : "Actions",
|
||||
"Drop your files here to upload it to the card" : "Déposez vos fichiers ici pour les téléverser sur la carte",
|
||||
"Assign card to me" : "Assignez-moi la carte",
|
||||
"Unassign card from me" : "Retirez-moi la carte",
|
||||
"Drop your files here to upload it to the card" : "Déposez vos fichiers ici pour les envoyer sur la carte",
|
||||
"Assign card to me" : "M'assigner la carte",
|
||||
"Unassign card from me" : "Me retirer de la carte",
|
||||
"Archive card" : "Archiver la carte",
|
||||
"Unarchive card" : "Ne plus archiver la carte",
|
||||
"Unarchive card" : "Sortir la carte des archives",
|
||||
"Delete card" : "Supprimer la carte",
|
||||
"Enter a card title" : "Saisissez un titre de carte",
|
||||
"Enter a card title" : "Saisir un titre de carte",
|
||||
"Add card" : "Ajouter une carte",
|
||||
"Close" : "Fermer",
|
||||
"Sharing" : "Partage",
|
||||
@@ -133,7 +135,7 @@
|
||||
"Select users or groups to share with" : "Sélectionnez des utilisateurs ou des groupes avec qui partager",
|
||||
"Group" : "Groupe",
|
||||
"Circle" : "Cercle",
|
||||
"No matching user or group found." : "Aucun utilisateur ou groupe correspondant trouvé",
|
||||
"No matching user or group found." : "Aucun utilisateur ou groupe correspondant trouvé.",
|
||||
"Loading" : "Chargement",
|
||||
"Edit" : "Modifier",
|
||||
"Share" : "Partager",
|
||||
@@ -155,23 +157,23 @@
|
||||
"More actions" : "Plus d'actions",
|
||||
"Edit board" : "Modifier le tableau",
|
||||
"Archive board" : "Archiver le tableau",
|
||||
"Unarchive board" : "Ne plus archiver le tableau",
|
||||
"Unarchive board" : "Sortir le tableau des archives",
|
||||
"Delete board" : "Supprimer le tableau",
|
||||
"Update board" : "Mettre à jour le tableau",
|
||||
"Reset board" : "Réinitialiser le tableau",
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Annuler la suppression du tableau — Autrement le tableau sera supprimé lors du prochain lancement de la tâche cron.",
|
||||
"Undo board deletion - Otherwise the board will be deleted during the next cronjob run." : "Annuler la suppression du tableau — Autrement le tableau sera supprimé lors de la prochaine tâche cron.",
|
||||
"Create new board" : "Créer un nouveau tableau",
|
||||
"New board title" : "Nouveau titre pour le tableau",
|
||||
"Create board" : "Créer le tableau",
|
||||
"Select an attachment" : "Sélectionner une pièce jointe",
|
||||
"Cancel upload" : "Annuler le téléversement",
|
||||
"Cancel upload" : "Annuler l'envoi",
|
||||
"by" : "par",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Annuler la suppression du fichier — Autrement le fichier sera supprimé lors du prochain lancement de la tâche cron.",
|
||||
"Undo file deletion - Otherwise the file will be deleted during the next cronjob run." : "Annuler la suppression du fichier — Autrement le fichier sera supprimé lors de la prochaine tâche cron.",
|
||||
"Undo file deletion" : "Annuler la suppression du fichier",
|
||||
"Insert the file into the description" : "Insérer le fichier dans la description",
|
||||
"Delete attachment" : "Supprimer la pièce jointe",
|
||||
"Modified:" : "Modifié le :",
|
||||
"Created:" : "Créé le :",
|
||||
"Modified:" : "Modifiée le :",
|
||||
"Created:" : "Créée le :",
|
||||
"Choose a tag" : "Choisir une étiquette",
|
||||
"Add a tag" : "Ajouter une étiquette",
|
||||
"Select tags" : "Sélectionner les étiquettes",
|
||||
@@ -179,21 +181,21 @@
|
||||
"Choose a user to assign" : "Choisir un utilisateur à assigner",
|
||||
"Assign this card to a user" : "Assigner cette carte à un utilisateur",
|
||||
"Due date" : "Date d'échéance",
|
||||
"Click to set" : "Cliquez pour définir",
|
||||
"Click to set" : "Cliquer pour définir",
|
||||
"Remove due date" : "Supprimer la date d'échéance",
|
||||
"Description" : "Description",
|
||||
"Attachments" : "Pièces jointes",
|
||||
"Saved" : "Enregistré",
|
||||
"Unsaved changes" : "Modifications non sauvegardées",
|
||||
"Unsaved changes" : "Modifications non enregistrées",
|
||||
"Insert attachment" : "Insérer une pièce jointe",
|
||||
"Formatting help" : "Aide sur la mise en forme",
|
||||
"Upload attachment" : "Téléverser la pièce jointe",
|
||||
"Add a card description…" : "Ajouter une description pour la carte",
|
||||
"Upload attachment" : "Envoyer une pièce jointe",
|
||||
"Add a card description…" : "Ajouter une description pour la carte...",
|
||||
"Shared boards" : "Tableaux partagés",
|
||||
"Move board to archive" : "Déplacer le tableau vers l'archive",
|
||||
"Move board to archive" : "Déplacer le tableau vers les archives",
|
||||
"Create a new board" : "Créer un nouveau tableau",
|
||||
"Settings" : "Paramètres",
|
||||
"Limit deck to groups" : "Limiter deck aux groupes",
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limiter le Deck empêchera les utilisateurs ne faisant pas partie de ces groupes de créer leurs propres tableaux. Les utilisateurs pourront toujours travailler sur des tableaux qui ont été partagés avec eux."
|
||||
"Limiting Deck will block users not part of those groups from creating their own boards. Users will still be able to work on boards that have been shared with them." : "Limiter Deck empêchera les utilisateurs ne faisant pas partie de ces groupes de créer leurs propres tableaux. Ces utilisateurs pourront toujours travailler sur les tableaux qui ont été partagés avec eux."
|
||||
},"pluralForm" :"nplurals=2; plural=(n > 1);"
|
||||
}
|
||||
@@ -11,6 +11,7 @@ OC.L10N.register(
|
||||
"Minutes" : "Minutos",
|
||||
"Link to a board" : "Ligar a un taboleiro",
|
||||
"Maximum file size of {size} exceeded" : "Excedeuse o tamaño máximo de ficheiro de {size}",
|
||||
"File already exists" : "O ficheiro xa existe",
|
||||
"You have created a new board {board}" : "Vostede creou o novo taboleiro {board}",
|
||||
"{user} has created a new board {board}" : "{user} creou o novo taboleiro {board}",
|
||||
"You have deleted the board {board}" : "Vostede eliminou o taboleiro {board}",
|
||||
@@ -18,7 +19,7 @@ OC.L10N.register(
|
||||
"You have restored the board {board}" : "Vostede restaurou o taboleiro {board}",
|
||||
"{user} has restored the board {board}" : "{user} restaurou o taboleiro {board}",
|
||||
"You have shared the board {board} with {acl}" : "Vostede compartiu o taboleiro {board} con {acl}",
|
||||
"{user} has shared the board {board} with {sharee}" : "{user} compartiu o taboleiro {board} con {acl}",
|
||||
"{user} has shared the board {board} with {acl}" : "{user} compartiu o taboleiro {board} con {acl}",
|
||||
"You have removed {acl} from the board {board}" : "Vostede retirou a {acl} do taboleiro {board}",
|
||||
"{user} has removed {acl} from the board {board}" : "{user} retirou a {acl} do taboleiro {board}",
|
||||
"You have renamed the board {before} to {board}" : "Vostede renomeou o taboleiro {before} como {board}",
|
||||
@@ -76,6 +77,7 @@ OC.L10N.register(
|
||||
"A <strong>card description</strong> inside the Deck app has been changed" : "Cambiouse a <strong>descripción da tarxeta</strong> dentro do aplicativo Deck",
|
||||
"Deck" : "Deck",
|
||||
"Changes in the <strong>Deck app</strong>" : "Cambios no <strong>aplicativo Deck</strong>",
|
||||
"A <strong>comment</strong> was created on a card" : "Creouse un <strong>comentario</strong> nunha tarxeta",
|
||||
"Personal" : "Persoal",
|
||||
"The card \"%s\" on \"%s\" has been assigned to you by %s." : "A tarxeta «%s» en «%s» foi asignada a vostede por %s.",
|
||||
"{user} has assigned the card \"%s\" on \"%s\" to you." : "{user} asignoulle a vostede a tarxeta «%s» en «%s».",
|
||||
@@ -111,7 +113,7 @@ OC.L10N.register(
|
||||
"Add a new stack" : "Engadir unha nova rima",
|
||||
"Submit" : "Enviar",
|
||||
"Show archived cards" : "Amosar as tarxetas arquivadas",
|
||||
"Hide archived cards" : "Agachar as tarxetas arquivadas",
|
||||
"Hide archived cards" : "Agochar as tarxetas arquivadas",
|
||||
"Toggle compact mode" : "Alternar o modo compacto",
|
||||
"Show board details" : "Amosar os detalles do taboleiro",
|
||||
"All Boards" : "Todos os taboleiros",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user