Compare commits
638 commits
Author | SHA1 | Date | |
---|---|---|---|
0802dc5777 | |||
e018d26a5b | |||
6b131e0779 | |||
6880744463 | |||
2e86ce673b | |||
acf4065a75 | |||
0bdd146319 | |||
a13ec695f7 | |||
2c868a42c6 | |||
fc98eea515 | |||
713a833b00 | |||
4c6d67dde7 | |||
c727ba8b18 | |||
8a555bce21 | |||
e037713fa3 | |||
b3ee5a18d1 | |||
e84e6ce40d | |||
7a815f233d | |||
c4e16b1e15 | |||
eed89a24ad | |||
adf60bdeb1 | |||
f8ce0dee55 | |||
c8b39ed1ef | |||
9a8b3b0c13 | |||
9baa356f56 | |||
|
4406dce589 | ||
|
a57925fce9 | ||
|
3b7bcea826 | ||
|
bc5dcfbafb | ||
|
8b2acaceb5 | ||
|
b1ce85fd33 | ||
|
4d7a07815a | ||
|
1e5f128a56 | ||
|
a50dc39354 | ||
|
dfc00d9aa4 | ||
|
ab73b3facb | ||
|
e9bd9444b3 | ||
|
d3929fc008 | ||
|
87e1ee4e21 | ||
|
411606dc69 | ||
|
841340caa9 | ||
|
24af70ff6b | ||
|
b068b74a10 | ||
|
3cdb2d012c | ||
|
9fd486dee2 | ||
|
78571918fd | ||
|
e4a82cee72 | ||
|
0f295495ed | ||
|
3377ec883f | ||
|
1a268b5912 | ||
|
c8688007a6 | ||
|
686bc1d162 | ||
|
a3f952b346 | ||
|
14cf2a460c | ||
|
0087e95141 | ||
|
837474f179 | ||
|
259acedd80 | ||
|
6fb956adae | ||
|
e3d891612f | ||
|
73d40d48fb | ||
|
b3cd4a3d1d | ||
|
6abb32e3e6 | ||
|
c6169f36f7 | ||
|
6722a9e34a | ||
|
5ca76701c2 | ||
|
170079e06e | ||
|
56c20277a4 | ||
|
d7ef98e68b | ||
|
4880e55552 | ||
|
8d52a897bb | ||
|
21976f3828 | ||
|
04d2f4bcca | ||
|
05555ae6a3 | ||
|
db268467a9 | ||
|
07bc03f2ef | ||
|
51de129b54 | ||
|
0e5d35fe6c | ||
|
de51323561 | ||
|
5f9789bd24 | ||
|
02f2f0e1f3 | ||
|
8c9b5d5972 | ||
|
2d27962e16 | ||
|
1189095675 | ||
|
f02ff602b5 | ||
|
6921d905dc | ||
|
f96b5e0a0b | ||
|
8b1a60dce2 | ||
|
2bd4b90b22 | ||
|
0dbd32ab42 | ||
|
e6d1489a9a | ||
|
584c456b43 | ||
|
17f4ac6291 | ||
|
ccaeaf9ee1 | ||
8a39058467 | |||
|
18d20efc5f | ||
|
66791289d1 | ||
|
3bb56cea6f | ||
|
3af1869053 | ||
|
3ff2c3ae38 | ||
df0abd99c7 | |||
27db721e39 | |||
891ec85764 | |||
d46869a1c9 | |||
3df5aebadf | |||
30b14142c7 | |||
d4c7989f05 | |||
|
a8cf3a75ba | ||
a549e5291d | |||
61d173549e | |||
4c72ff4625 | |||
|
cc6c8b2b38 | ||
|
2aede0f179 | ||
|
31863b7c49 | ||
|
0e36395a3e | ||
|
1729460a75 | ||
|
bb1658c1aa | ||
|
bcf48997fe | ||
|
c506fa5ee5 | ||
|
05cd0cc712 | ||
|
aa2b9102c3 | ||
|
f50e787fa9 | ||
|
add720534d | ||
|
738e51152e | ||
|
c4c544aed4 | ||
|
f04ded8fa4 | ||
|
ffe03e0d38 | ||
|
b82ee6ff0b | ||
|
c1dfdd3bbe | ||
|
9913909cfa | ||
|
27a4620dba | ||
|
c9e9775eb1 | ||
|
7cac1c7159 | ||
|
c2e80fb063 | ||
|
fd351d63c7 | ||
|
f5b4845aa2 | ||
|
0fda46954e | ||
|
536e77cdaa | ||
|
efa4b975d3 | ||
|
050134bfbf | ||
|
6698a99613 | ||
|
079ef51efd | ||
|
0f9b15148a | ||
|
d0c9ecf233 | ||
|
1ab003bb11 | ||
|
9e3dc60373 | ||
|
c4c547c0e5 | ||
|
fff34e817a | ||
|
ff8a68e720 | ||
|
cceed3045d | ||
|
697138d38b | ||
|
5dc68eed02 | ||
|
80eb0259e2 | ||
|
05b6992dd4 | ||
|
6b58b4f545 | ||
|
4316028e41 | ||
|
58f0c71ee9 | ||
|
28950a8fb8 | ||
|
182543e55f | ||
|
46e590c932 | ||
|
a6202e7460 | ||
|
4851642faf | ||
|
5bd81b1901 | ||
|
4cfab828e7 | ||
|
c615902cee | ||
|
9629862d56 | ||
|
2b4d407ea6 | ||
|
3350a501ad | ||
|
0ef644c6cb | ||
|
f59655995e | ||
|
d843d44d13 | ||
|
0153bb98e2 | ||
|
d65c5a1d29 | ||
|
410ae72b9e | ||
|
c46793cfaa | ||
|
ffb8f3412c | ||
|
855f8640b2 | ||
|
3f31748e08 | ||
|
ecf790257c | ||
|
6cdd2f42fe | ||
|
c64ccc863c | ||
|
fdbd5fdaf8 | ||
|
5ed0a6f7f4 | ||
|
67ebf12a74 | ||
|
b551987afa | ||
|
40e402c780 | ||
|
4a1c7c2841 | ||
|
3711248435 | ||
|
e81c80fa9b | ||
|
408b8db9ad | ||
|
4c58b157f5 | ||
|
f25770ad31 | ||
|
be6a3781d1 | ||
|
fedb634c48 | ||
|
4eed4d0138 | ||
|
1f5e138c9c | ||
|
c15265ebef | ||
|
e7f928a090 | ||
|
35c08fcc3c | ||
|
a90dc10818 | ||
|
dcfee0f5de | ||
|
efbd75834f | ||
|
cd74fa18a2 | ||
|
661b828e5c | ||
|
c5e3aa7f5a | ||
|
7fb00e38ff | ||
|
6d5add9ee3 | ||
|
b154213b45 | ||
|
f3c28930ea | ||
|
462ca3bf4b | ||
|
f0e0047e92 | ||
|
ec739099b6 | ||
|
37b2fb3199 | ||
|
457264b72c | ||
|
da2c1c5dfd | ||
|
6fc6c17d96 | ||
|
665153c903 | ||
|
ee34707047 | ||
|
0b81053f24 | ||
|
d008cbdfc7 | ||
|
36239cd16f | ||
|
f7e9e727ac | ||
|
4a1092d2d6 | ||
|
c08b48dcae | ||
|
f3f7a155d7 | ||
|
d0f73f4222 | ||
|
cad7ad8360 | ||
|
bc812751af | ||
|
3ac082b4ab | ||
|
208431dd00 | ||
|
d414750cd5 | ||
|
b1c22da958 | ||
|
7f59ccb050 | ||
|
8015b3aa3a | ||
|
27f8ac9801 | ||
|
aa8611ba80 | ||
|
3d263f621e | ||
|
39c0773300 | ||
|
b039968517 | ||
|
413e0f5b7f | ||
|
6069a95768 | ||
|
e1b9ccdef1 | ||
|
14a46f7719 | ||
|
b37f91427f | ||
|
b251f1034d | ||
|
ac1864c46f | ||
|
dd88974338 | ||
|
767322c355 | ||
|
72ceba63e6 | ||
|
e3d5d5b625 | ||
|
2d70096f51 | ||
|
8908ecad81 | ||
|
a0d0d25bfd | ||
|
a99fe3833a | ||
|
fc4a48c1d1 | ||
|
2e397f8790 | ||
|
bf5f6beb75 | ||
|
9eb5a1b347 | ||
|
58ba64b87a | ||
|
92079893fa | ||
|
b5a3a29539 | ||
|
9de860eaac | ||
|
8b4fe37a60 | ||
|
d19aef2e94 | ||
|
0fa2d2f267 | ||
c18f167a12 | |||
|
4cc4453a74 | ||
|
27f11164d8 | ||
|
06fb9178b7 | ||
|
08417331ed | ||
|
a028748fb7 | ||
|
c7fdf64d35 | ||
|
ea26e75e77 | ||
|
27be3dd0fc | ||
|
9d318698f4 | ||
|
aecd05fb94 | ||
|
b4ed2dc869 | ||
|
50bd778252 | ||
|
cd92dfa695 | ||
|
2a42c5ed6b | ||
|
d8b3e9e9df | ||
|
a55b76208e | ||
|
a5ab8ceb47 | ||
|
3471f888f8 | ||
|
75531b3fcd | ||
|
d2107a7101 | ||
|
0a146aef7f | ||
|
7e72078f29 | ||
|
04c10cf5e6 | ||
|
2eb1d2b840 | ||
|
9c646f859d | ||
|
7cea3012cd | ||
|
2880cd2ebb | ||
|
04335524c5 | ||
|
eb2b2b2e90 | ||
|
2dc4a93f18 | ||
|
8dc408c511 | ||
|
e4ba720a7d | ||
|
7638fa71bd | ||
|
997a9a6d47 | ||
|
37df2725ac | ||
|
4405537fe7 | ||
|
51da64c138 | ||
|
c9ce3cf231 | ||
|
6bf096b4c8 | ||
|
ab37ebb00b | ||
|
7815274d17 | ||
|
efee8997f8 | ||
|
4fff76a531 | ||
|
1cdf3aa17a | ||
|
e85d5123a5 | ||
|
28eabbea4a | ||
|
ea8374adb7 | ||
|
8ce0e8073f | ||
|
39ef13ff7c | ||
|
996c493f21 | ||
|
5ceda826f2 | ||
|
e0bfc95a00 | ||
|
b9f1c93f65 | ||
|
b36676169a | ||
|
3b4abed18b | ||
|
8e1825ae1a | ||
|
659adbe6d7 | ||
|
3d1087986f | ||
|
54c8c2ddeb | ||
|
c12d3c0451 | ||
|
b60cd76350 | ||
|
198ac3e035 | ||
|
7f7a1813c9 | ||
|
54ccd71b91 | ||
|
dbe0ad7209 | ||
|
11da7c9c7f | ||
|
e8e43c236d | ||
|
a5b74ef396 | ||
|
b3423fcf85 | ||
|
065efcab7f | ||
|
ca3745e237 | ||
|
fdb2b6d257 | ||
|
7a6b9f2e3f | ||
|
92881ead81 | ||
|
bcf958f196 | ||
|
e5f037dc46 | ||
|
4339a3a961 | ||
|
b36e8693b5 | ||
|
3cc934efdc | ||
|
0c80942777 | ||
|
55eb374d36 | ||
|
edd86b1181 | ||
|
81177cc96e | ||
|
94e07f1ead | ||
|
ea46a819d4 | ||
|
753c70114e | ||
|
290ca32fd6 | ||
|
da6df6f018 | ||
|
370faf5678 | ||
|
98e5fa5d36 | ||
|
75b6f027a2 | ||
|
d7eaf61a95 | ||
|
240340ff83 | ||
|
c771ab057c | ||
|
a70a5bb15c | ||
|
d211d4f934 | ||
|
434f8ad2dd | ||
|
f8dbcb80ab | ||
c706d73831 | |||
|
702d989c08 | ||
|
82255a4bcd | ||
|
3df6738bc7 | ||
|
49df2deb31 | ||
|
08bd5dae40 | ||
|
1899450dc1 | ||
|
a710ca9ece | ||
|
090e127f3d | ||
|
710bb8bfa7 | ||
|
b6a66ebe20 | ||
|
0bc5cf9f6b | ||
|
5ae214fbbe | ||
|
6577376642 | ||
|
3f82738d86 | ||
|
13ace35a3c | ||
|
55cf52f4de | ||
|
1e6e006f14 | ||
|
0323053fee | ||
|
f34157b1db | ||
|
cb89fb09be | ||
|
ab0dd31640 | ||
|
4c32a0708f | ||
|
a2649dbb64 | ||
|
0b36c5bbb0 | ||
|
cd689ac75c | ||
|
cea1485ddc | ||
|
991c17f88e | ||
|
764621d6fd | ||
|
9d2a86556c | ||
|
0aff86e638 | ||
|
2881730f33 | ||
91ccbfeda5 | |||
|
866fa29757 | ||
|
71885f017d | ||
|
0a3cbcb70d | ||
|
92aef6b180 | ||
|
f498dcfefe | ||
|
d447ffd314 | ||
|
95615a6bbf | ||
|
0936d0def7 | ||
|
752e8847eb | ||
|
c3960c472a | ||
|
070db1235a | ||
|
05615cddf5 | ||
|
f1a9d1726a | ||
|
1bae1cd3c9 | ||
|
e0f93c45f0 | ||
|
9137362dc7 | ||
|
dca1f2cce8 | ||
|
ed801c5430 | ||
|
92ede0a35f | ||
|
fbcc5ee524 | ||
|
ab77704c97 | ||
|
bac50fe62d | ||
|
acf9012979 | ||
|
84c6319a1f | ||
|
6a73b4f20c | ||
|
a98ee9f4ae | ||
|
6c35973907 | ||
|
ecebe77c40 | ||
|
54e5191d04 | ||
|
a6a92d34ad | ||
|
918bd18b88 | ||
|
8d23e36a54 | ||
|
51020a6699 | ||
|
c2fc99bce0 | ||
|
d8299972b5 | ||
|
17d2a74d5a | ||
|
bb4a2527ae | ||
|
2c6f699a1f | ||
|
f96d495612 | ||
|
d0939463c2 | ||
|
a8fb2a7255 | ||
|
1033eee7e8 | ||
|
2d510fb348 | ||
|
8faf9b18c0 | ||
|
cca3e01979 | ||
|
2d6ff4d610 | ||
|
5554413a7c | ||
|
b48e047a07 | ||
|
12bac96c9d | ||
|
cd126c107f | ||
|
d3b1191fb2 | ||
|
e211e26d16 | ||
|
727f72f058 | ||
|
789fa36e1a | ||
|
a08df92ccc | ||
|
0c1c549631 | ||
|
77646e3de8 | ||
|
7fd8a81301 | ||
|
0a92e71c44 | ||
|
e67fc33600 | ||
|
dcc12137eb | ||
|
8b5bd59267 | ||
|
54f6c90f06 | ||
|
41c26db820 | ||
|
1fa258ff23 | ||
|
f4d7ad9453 | ||
|
019b24245a | ||
|
247fdf61f4 | ||
|
d92d018831 | ||
|
a0cbeefb14 | ||
|
f22485cc21 | ||
|
b8184c47fe | ||
|
372d37e3b3 | ||
|
63ad2f4524 | ||
|
03b5c1d76e | ||
|
fe1024be99 | ||
|
20251b75e5 | ||
|
d23c9f8130 | ||
|
3fc779c6fb | ||
|
3ded23dfe7 | ||
|
2621d7cb51 | ||
|
a936dfb1e1 | ||
|
1c2691478b | ||
|
3e4a3d2609 | ||
|
23ee4813f8 | ||
|
7ca28c7c75 | ||
|
38c3c08533 | ||
|
8d7ffcca89 | ||
|
10c436b24a | ||
|
7aea244706 | ||
|
1d2ecc5255 | ||
|
4b701ced5f | ||
|
1dfc0bacab | ||
|
fd54181805 | ||
|
8fddbb69d2 | ||
|
20a56bb21f | ||
|
1c2782a522 | ||
|
7b7a05170a | ||
|
dd4b5b2f21 | ||
|
da701058a7 | ||
|
52453d63bd | ||
|
af929419fb | ||
|
8e53f52ccf | ||
|
094ec8956b | ||
|
342222d45c | ||
|
88f2859f47 | ||
|
9c28eddec1 | ||
|
861eb1680b | ||
|
008162c508 | ||
|
cb99014af5 | ||
|
bcc1ea16ff | ||
|
8e671ac984 | ||
|
6ec7d89a91 | ||
|
744872d64a | ||
|
8c2cc6cac1 | ||
|
fddc20600d | ||
|
791f576543 | ||
|
8d1d9940c9 | ||
|
8e7eb99f1f | ||
|
2f0f424f91 | ||
|
3bedf77b44 | ||
|
43db9abcd5 | ||
|
7d6fc796de | ||
|
4404e87e3d | ||
|
9c6acae0cf | ||
|
15730cb733 | ||
|
df178b6407 | ||
|
cd5ebccc2f | ||
|
35a9ef2ca9 | ||
|
9ecdddad16 | ||
|
558db9a1c7 | ||
|
7cf2878eb8 | ||
|
5fe5b38c13 | ||
|
cfa85c1e04 | ||
|
c20c2060e9 | ||
|
0a4ddd3e6f | ||
|
005c8ff161 | ||
|
ca8df9e726 | ||
|
9c06776154 | ||
|
5c87ff33a1 | ||
|
96125402cd | ||
|
cd09e09431 | ||
|
99ce098c37 | ||
|
aea87c46c8 | ||
|
56fa5c1460 | ||
|
c94810994f | ||
|
4160a89c66 | ||
|
f822fb4ba6 | ||
|
8937cf87d1 | ||
|
e488e3f852 | ||
|
09f219c201 | ||
|
3dd498c2e5 | ||
|
02c3059a97 | ||
|
4752ce96a3 | ||
|
abb375d2ac | ||
|
73a87b440a | ||
|
a31952b8aa | ||
|
bb36813490 | ||
|
08f96d5881 | ||
|
a806a06107 | ||
|
a54d09c486 | ||
|
1f7d78406c | ||
|
992d07b1c4 | ||
|
f1e1832c7e | ||
|
655584c877 | ||
|
ac6799211d | ||
|
d5e11e279f | ||
|
66c5a85821 | ||
|
d0af7e4907 | ||
|
9010cbbf3f | ||
|
3314a0eace | ||
|
d8cff84bf5 | ||
|
c517f13545 | ||
|
be3372518d | ||
|
8f5d36ee20 | ||
|
e4dcbed6ea | ||
|
9567695186 | ||
|
86777defc7 | ||
|
e2f3860544 | ||
|
79afa08f53 | ||
|
a2072165aa | ||
|
32432e1f6e | ||
|
ee20731a4e | ||
|
7418324210 | ||
|
cea667e0e3 | ||
|
d131b5bd88 | ||
|
0e876da852 | ||
|
1f488a18be | ||
|
5805792211 | ||
|
34f14c93f7 | ||
|
2c8270f24c | ||
|
b5aba2cc81 | ||
|
0ac84426f7 | ||
|
2a38907ebe | ||
|
ca9e84ad4b | ||
|
759dab4729 | ||
|
c7ebd70069 | ||
|
e7167b88f3 | ||
|
2e22228dd2 | ||
|
6d11e30b65 | ||
|
05bc582512 | ||
|
b30d2553c5 | ||
|
05abaf1916 | ||
|
1bcf33abdc | ||
|
747dc65e9b | ||
|
cdb922fa19 | ||
|
c99e47e098 | ||
|
b15f88947d | ||
|
8e3256ad9e | ||
|
81f050f9aa | ||
|
343f9506f2 | ||
|
da67936a63 | ||
|
c65ddfde6c | ||
|
cf9b0c5688 | ||
|
044cfbc246 | ||
|
0e972e44e1 | ||
|
2d7b742bda | ||
|
4b9c5df5f2 | ||
|
f4df449f1a | ||
|
d021c77a3e | ||
|
88b5abc6a3 | ||
|
ce3d3387cf | ||
|
85664ffb54 | ||
|
1d21dc5192 | ||
|
4f61344c50 | ||
|
0cbebe2832 | ||
|
a83d61ed9f | ||
|
619831dbb5 | ||
|
7f01e26a2d | ||
|
148d7b3298 | ||
|
5bea899efd | ||
|
41e94628cb | ||
|
0556b874cf | ||
|
9bca5fbdad | ||
|
584401a3d7 | ||
|
26889c28e3 | ||
|
9395cc782f | ||
|
ab5a7158b5 | ||
|
12b708404b | ||
|
b6d678b423 | ||
|
d0c885c295 | ||
|
55832cb890 |
58
.woodpecker.yml
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
pipeline:
|
||||||
|
lint:
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
image: node:14
|
||||||
|
commands:
|
||||||
|
- git config --global url."https://github.com/".insteadOf git://github.com/
|
||||||
|
- yarn
|
||||||
|
- yarn lint
|
||||||
|
|
||||||
|
test:
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
image: node:14
|
||||||
|
commands:
|
||||||
|
- apt update
|
||||||
|
- apt install firefox-esr -y --no-install-recommends
|
||||||
|
- git config --global url."https://github.com/".insteadOf git://github.com/
|
||||||
|
- yarn
|
||||||
|
- yarn test
|
||||||
|
|
||||||
|
build:
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- stable
|
||||||
|
image: node:14
|
||||||
|
commands:
|
||||||
|
- git config --global url."https://github.com/".insteadOf git://github.com/
|
||||||
|
- yarn
|
||||||
|
- yarn build:prod
|
||||||
|
|
||||||
|
release:
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
- stable
|
||||||
|
image: node:16
|
||||||
|
secrets:
|
||||||
|
- SCW_ACCESS_KEY
|
||||||
|
- SCW_SECRET_KEY
|
||||||
|
- SCW_DEFAULT_ORGANIZATION_ID
|
||||||
|
commands:
|
||||||
|
- apt-get update && apt-get install -y rclone wget zip
|
||||||
|
- wget https://github.com/scaleway/scaleway-cli/releases/download/v2.5.1/scaleway-cli_2.5.1_linux_amd64
|
||||||
|
- mv scaleway-cli_2.5.1_linux_amd64 scaleway-cli
|
||||||
|
- chmod +x scaleway-cli
|
||||||
|
- ./scaleway-cli object config install type=rclone
|
||||||
|
- zip admin-fe.zip -r dist
|
||||||
|
- rclone copyto admin-fe.zip scaleway:akkoma-updates/frontend/$CI_COMMIT_BRANCH/admin-fe.zip
|
129
CHANGELOG.md
|
@ -8,13 +8,142 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
## [2.4.0] - 2021-08-01
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Evicting and banning objects from the MediaProxy cache is disabled if MediaProxy is disabled on the Settings tab. Add ability to enable MediaProxy and Invalidation from MediaProxy tab.
|
||||||
|
- Allow to upload the custom Terms of Service and Instance Panel HTML pages via Admin API
|
||||||
|
- Add Report show page and link Moderation log references to the respective reports
|
||||||
|
- Add Unconfimed filter for Users table
|
||||||
|
- Filter users by actor type: Person, Bot or Application
|
||||||
|
- Add ability to configure Media Preview Proxy, User Backup, Websocket based federation and Pleroma.Web.Endpoint.MetricsExporter settings
|
||||||
|
- Mobile and Tablet UI for Single Report show page
|
||||||
|
- Ability to set rules and conditions for rendering settings (e.g. `:proxy_remote` setting is hidden if `:uploader` setting is set to `Pleroma.Uploaders.Local`)
|
||||||
|
- Ability to install new frontends from the Frontend tab in the Settings section
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
|
||||||
|
- **Breaking**: AdminAPI changed User field `approval_pending` to `is_approved`
|
||||||
|
- **Breaking**: AdminAPI changed User field `deactivated` to `is_active`
|
||||||
|
- Hide Tag actions on Users tab if MRF TagPolicy is disabled. Add ability to enable TagPolicy from Moderation menu
|
||||||
|
- Move `:restrict_unauthenticated` settings from Authentication tab to Instance tab
|
||||||
|
- Replace regular inputs with textareas for setting welcome messages in the Settings section
|
||||||
|
- Remove Websocket based federation settings
|
||||||
|
- Move Settings tab navigation from the tabbed menu to the main sidebar menu. A separate route is created for each tab.
|
||||||
|
- Move Emoji packs configuration to the Emoji tab in the Settings section
|
||||||
|
- 401 and 404 error pages updated
|
||||||
|
- Remove unused components
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix depricatied action names in Reports, move actions that manage users from Reports to reports module
|
||||||
|
- Allow using underscores and hyphens in new account's usernames
|
||||||
|
- Fix wrapping `:icons` setting and parsing tuples in settings with key `:headers`
|
||||||
|
- Update keys for Pleroma.Web.Plugs.RemoteIp and PurgeExpiredActivity settings
|
||||||
|
- Update switching between local and remote emoji packs panels: the panel with the pack's metadata will be closed when another panel is opened
|
||||||
|
- Fix displaying messages for multiple errors
|
||||||
|
## [2.2] - 2020-11-18
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Ability to configure Media Preview Proxy settings on MediaProxy tab
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Update keys for PurgeExpiredActivity and RemoteIp settings
|
||||||
|
- Fix wrapping `:icons` setting and parsing tuples in settings with key `:headers`
|
||||||
|
|
||||||
|
## [2.1] - 2020-08-26
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Create `/statuses/:id` route that shows single status
|
||||||
|
- Add link to the user's account in Pleroma on the user's profile page
|
||||||
|
- On Reports page add links to reported account and the author of the report
|
||||||
|
- In Notes add link to the note author's profile page
|
||||||
|
- In Moderation log add link to the actor's profile page
|
||||||
|
- Support pagination of local emoji packs and files
|
||||||
|
- Add MRF Activity Expiration setting
|
||||||
|
- Add ability to disable multi-factor authentication for a user
|
||||||
|
- Add ability to configure Invalidation settings on MediaProxy tab
|
||||||
|
- Ability to configure `S3` settings on Upload tab, `Pleroma.Web.ApiSpec.CastAndValidate` and `:modules` settings on Other tab, `:pools`, `:connections_pool` and `:hackney_pools` settings on Job Queue tab, `:restrict_unauthenticated` settings on Authentication tab, `:favicons` and `:welcome` settings on Instance tab, `:frontends` and `Pleroma.Web.Preload` settings on Frontend tab
|
||||||
|
- Show number of open reports in Sidebar Menu
|
||||||
|
- Add confirmation message when deleting a user
|
||||||
|
- Add new MediaProxy Cache Tab with ability to manually evict and ban objects from the Pleroma MediaProxy cache
|
||||||
|
- Allow managing user's actor_type field via Admin API
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Statuses count changes when an instance is selected and shows the amount of statuses from an originating instance
|
||||||
|
- Add a confirmation dialog window when Remove button is clicked on the Settings page
|
||||||
|
- Disable tab on the Settings page if there are no settings on this tab that can be changed in Admin FE
|
||||||
|
- Settings that can't be altered in Admin FE are removed: HTTP Signatures settings, Federation publisher modules and Oban Repo
|
||||||
|
- When rendering user's profile, statuses, reports and notes check if required properties exist
|
||||||
|
- Remove ability to moderate users that don't have valid nicknames
|
||||||
|
- Displays both labels and description in the header of group of settiings
|
||||||
|
- Ability to add custom values in Pleroma.Upload.Filter.Mogrify setting in the following format: '{"implode", "1"}'
|
||||||
|
- Change types of the following settings: ':groups', ':replace', ':federated_timeline_removal', ':reject', ':match_actor'. Update functions that parses and wraps settings data according to this change.
|
||||||
|
- Move rendering Crontab setting from a separate component to EditableKeyword component
|
||||||
|
- Show only those MRF settings that have been enabled in MRF Policies setting
|
||||||
|
- Move Auto Linker settings to Link Formatter Tab as its configuration was moved to :pleroma, Pleroma.Formatter
|
||||||
|
- Active and Local filters are applied by default on the Users tab
|
||||||
|
- Update Emoji Packs API to support special chars in pack names
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Send `true` and `false` as booleans if they are values of single selects on the Settings page
|
||||||
|
- Fix sorting users on Users page if there is an acount with missing nickname or ID
|
||||||
|
- Add new type of settings: `['string', 'image']`. Render Image upload Input depending on the type of setting, not its key
|
||||||
|
- Fix displaying `Pending` tag and filtering by Pending Approval status
|
||||||
|
- Fix following and unfollowing relays from Admin-FE, update mobile UI
|
||||||
|
- Support special chars in Emoji packs names
|
||||||
|
|
||||||
|
## [2.0.3] - 2020-04-29
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Link settings that enable registrations and invites
|
||||||
|
- Ability to upload logo, background, default user avatar, instance thumbnail, and NSFW hiding images
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Put Instance Reboot button on all pages of admin-fe
|
||||||
|
- Make Instance Reboot button's positon fixed on Settings page
|
||||||
|
- Update jest and babel-jest
|
||||||
|
- Generate an invite link when an invite token has been generated
|
||||||
|
- Put labels on top of inputs in mobile version
|
||||||
|
- Shorten suggestions for a series of select inputs: Rewrite policy, Pleroma Authenticator, Captcha Method, Mailer adapter, Metadata providers, Rich Media parsers, TTL setters, Scrub policy, Uploader, Filters and Federation publisher modules
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Disable Invites tab when invites are disabled on BE
|
||||||
|
|
||||||
|
## [2.0.2] - 2020-04-01
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
- Ability to see local statuses in Statuses by instance section
|
- Ability to see local statuses in Statuses by instance section
|
||||||
- Ability to configure Oban.Cron settings and settings for notifications streamer
|
- Ability to configure Oban.Cron settings and settings for notifications streamer
|
||||||
|
- Settings search
|
||||||
|
- Ability to set user's password and email on user's page
|
||||||
|
- Display status count by scope on Statuses page
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Link to Pleroma docs when a non-admin user tries to log in
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fix parsing tuples in Pleroma.Upload.Filter.Mogrify and Pleroma.Emails.Mailer settings
|
- Fix parsing tuples in Pleroma.Upload.Filter.Mogrify and Pleroma.Emails.Mailer settings
|
||||||
- Fix settings submit button position on wide screens when sidebar menu is open
|
- Fix settings submit button position on wide screens when sidebar menu is open
|
||||||
|
- Updates links for downloading remote emoji packs
|
||||||
|
- Fix parsing emails that have symbols in it
|
||||||
|
|
||||||
## [2.0] - 2020-02-27
|
## [2.0] - 2020-02-27
|
||||||
|
|
||||||
|
|
24
README.md
|
@ -31,11 +31,31 @@ AdminFE is bundled with Pleroma, i.e. you can just visit `https://your.instance/
|
||||||
|
|
||||||
### Development
|
### Development
|
||||||
|
|
||||||
To run AdminFE locally execute `yarn dev`
|
To run AdminFE locally execute
|
||||||
|
|
||||||
|
```
|
||||||
|
# install dependencies
|
||||||
|
npm install -g yarn
|
||||||
|
yarn
|
||||||
|
|
||||||
|
# run AdminFE locally
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
### Build
|
### Build
|
||||||
|
|
||||||
To compile everything for production run `yarn build:prod`, this will build admin-fe into `dist` folder, which you will need to upload to your server and/or point your webserver of choice to.
|
To compile everything for production run
|
||||||
|
|
||||||
|
```
|
||||||
|
# install dependencies
|
||||||
|
npm install -g yarn
|
||||||
|
yarn
|
||||||
|
|
||||||
|
# compile everything for production
|
||||||
|
yarn build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
This will build admin-fe into `dist` folder, which you will need to upload to your server and/or point your webserver of choice to.
|
||||||
|
|
||||||
#### Disabling features
|
#### Disabling features
|
||||||
|
|
||||||
|
|
9
admin-fe.iml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -2,6 +2,6 @@ module.exports = {
|
||||||
NODE_ENV: '"production"',
|
NODE_ENV: '"production"',
|
||||||
ENV_CONFIG: '"prod"',
|
ENV_CONFIG: '"prod"',
|
||||||
BASE_API: '"https://api-prod"',
|
BASE_API: '"https://api-prod"',
|
||||||
DISABLED_FEATURES: '["emoji-packs"]',
|
DISABLED_FEATURES: '[""]',
|
||||||
ASSETS_PUBLIC_PATH: '/pleroma/admin/'
|
ASSETS_PUBLIC_PATH: '/pleroma/admin/'
|
||||||
}
|
}
|
||||||
|
|
23
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "vue-element-admin",
|
"name": "vue-element-admin",
|
||||||
"version": "3.10.0",
|
"version": "3.11.0",
|
||||||
"description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
"description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
||||||
"author": "Pan <panfree23@gmail.com>",
|
"author": "Pan <panfree23@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -29,10 +29,13 @@
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
|
"url": "git+https://akkoma.dev/AkkomaGang/admin-fe.git"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"prosemirror-model": "1.9.1"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
|
"url": "https://akkoma.dev/AkkomaGang/admin-fe/-/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.3.4",
|
"@babel/runtime": "^7.3.4",
|
||||||
|
@ -60,11 +63,13 @@
|
||||||
"screenfull": "4.0.0",
|
"screenfull": "4.0.0",
|
||||||
"showdown": "1.8.6",
|
"showdown": "1.8.6",
|
||||||
"sortablejs": "1.7.0",
|
"sortablejs": "1.7.0",
|
||||||
|
"tiptap": "^1.29.6",
|
||||||
|
"tiptap-extensions": "^1.32.7",
|
||||||
"tui-editor": "1.2.7",
|
"tui-editor": "1.2.7",
|
||||||
"vue": "^2.6.8",
|
"vue": "^2.6.8",
|
||||||
"vue-count-to": "1.0.13",
|
"vue-count-to": "1.0.13",
|
||||||
"vue-i18n": "^8.9.0",
|
"vue-i18n": "^8.9.0",
|
||||||
"vue-router": "3.0.2",
|
"vue-router": "^3.5.1",
|
||||||
"vue-splitpane": "1.0.2",
|
"vue-splitpane": "1.0.2",
|
||||||
"vuedraggable": "^2.16.0",
|
"vuedraggable": "^2.16.0",
|
||||||
"vuex": "3.0.1",
|
"vuex": "3.0.1",
|
||||||
|
@ -77,11 +82,11 @@
|
||||||
"@babel/preset-env": "^7.3.4",
|
"@babel/preset-env": "^7.3.4",
|
||||||
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.2",
|
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.2",
|
||||||
"@vue/babel-preset-jsx": "^1.0.0-beta.2",
|
"@vue/babel-preset-jsx": "^1.0.0-beta.2",
|
||||||
"@vue/test-utils": "^1.0.0-beta.29",
|
"@vue/test-utils": "^1.1.0",
|
||||||
"autoprefixer": "8.5.0",
|
"autoprefixer": "8.5.0",
|
||||||
"babel-eslint": "8.2.6",
|
"babel-eslint": "8.2.6",
|
||||||
"babel-helper-vue-jsx-merge-props": "2.0.3",
|
"babel-helper-vue-jsx-merge-props": "2.0.3",
|
||||||
"babel-jest": "^24.1.0",
|
"babel-jest": "^25.3.0",
|
||||||
"babel-loader": "^8.0.5",
|
"babel-loader": "^8.0.5",
|
||||||
"babel-plugin-dynamic-import-node-babel-7": "^2.0.7",
|
"babel-plugin-dynamic-import-node-babel-7": "^2.0.7",
|
||||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
|
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
|
||||||
|
@ -101,12 +106,12 @@
|
||||||
"hash-sum": "1.0.2",
|
"hash-sum": "1.0.2",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"husky": "0.14.3",
|
"husky": "0.14.3",
|
||||||
"jest": "^24.1.0",
|
"jest": "^25.3.0",
|
||||||
"jest-transform-stub": "^2.0.0",
|
"jest-transform-stub": "^2.0.0",
|
||||||
"lint-staged": "7.2.2",
|
"lint-staged": "7.2.2",
|
||||||
"mini-css-extract-plugin": "0.4.1",
|
"mini-css-extract-plugin": "0.4.1",
|
||||||
"node-notifier": "5.2.1",
|
"node-notifier": "5.2.1",
|
||||||
"node-sass": "^4.12.0",
|
"node-sass": "^7.0.1",
|
||||||
"optimize-css-assets-webpack-plugin": "5.0.0",
|
"optimize-css-assets-webpack-plugin": "5.0.0",
|
||||||
"ora": "3.0.0",
|
"ora": "3.0.0",
|
||||||
"path-to-regexp": "2.4.0",
|
"path-to-regexp": "2.4.0",
|
||||||
|
@ -131,7 +136,7 @@
|
||||||
"webpack": "^4.29.6",
|
"webpack": "^4.29.6",
|
||||||
"webpack-bundle-analyzer": "2.13.1",
|
"webpack-bundle-analyzer": "2.13.1",
|
||||||
"webpack-cli": "^3.2.3",
|
"webpack-cli": "^3.2.3",
|
||||||
"webpack-dev-server": "3.1.14",
|
"webpack-dev-server": "3.11.0",
|
||||||
"webpack-merge": "4.1.4"
|
"webpack-merge": "4.1.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
7
src/api/__mocks__/app.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export async function needReboot(authHost, token) {
|
||||||
|
return Promise.resolve({ data: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function restartApp(authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
51
src/api/__mocks__/emojiPacks.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
export async function addNewEmojiFile(packName, file, shortcode, filename, host, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addressOfEmojiInPack(host, packName, name) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createPack(host, token, packName) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteEmojiFile(packName, shortcode, host, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deletePack(host, token, packName) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function downloadFrom(instanceAddress, packName, as, host, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchPack(packName, page, pageSize, host, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function importFromFS(host, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listPacks(page, pageSize, host, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listRemotePacks(instance, page, pageSize, host, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function reloadEmoji(host, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function savePackMetadata(host, token, packName, metadata) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateEmojiFile(packName, shortcode, newShortcode, newFilename, force, host, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
|
@ -43,7 +43,7 @@ export function getUserInfo(token, authHost) {
|
||||||
'statuses_count': 0,
|
'statuses_count': 0,
|
||||||
'cover_photo': '',
|
'cover_photo': '',
|
||||||
'hide_follows': false,
|
'hide_follows': false,
|
||||||
'pleroma': { 'confirmation_pending': false, 'deactivated': false, 'tags': ['force_nsfw'], 'is_admin': true },
|
'pleroma': { 'is_confirmed': true, 'is_active': true, 'tags': ['force_nsfw'], 'is_admin': true },
|
||||||
'profile_image_url_original': '',
|
'profile_image_url_original': '',
|
||||||
'created_at': 'Fri Mar 01 15:15:19 +0000 2019',
|
'created_at': 'Fri Mar 01 15:15:19 +0000 2019',
|
||||||
'fields': [],
|
'fields': [],
|
||||||
|
|
20
src/api/__mocks__/mediaProxyCache.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
const urls = [
|
||||||
|
'http://example.com/media/a688346.jpg',
|
||||||
|
'http://example.com/media/fb1f4d.jpg'
|
||||||
|
]
|
||||||
|
|
||||||
|
export async function listBannedUrls(page, pageSize, authHost, token) {
|
||||||
|
return Promise.resolve({ data: { page_size: 1, count: 2, urls }})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function purgeUrls(urls, ban, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function removeBannedUrls(urls, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function searchBannedUrls(query, page, pageSize, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
3
src/api/__mocks__/mediaUpload.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function uploadMedia({ formData, authHost }) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
11
src/api/__mocks__/moderationLog.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export async function fetchLog(authHost, token, params, page = 1) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchAdmins(authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchModerators(authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
4
src/api/__mocks__/peers.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export async function fetchPeers(authHost, token) {
|
||||||
|
const data = ['lain.com', 'heaven.com']
|
||||||
|
return Promise.resolve({ data })
|
||||||
|
}
|
11
src/api/__mocks__/relays.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export async function fetchRelays(authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addRelay(relay_url, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteRelay(relay_url, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
const reports = [
|
const reports = [
|
||||||
{ created_at: '2019-05-21T21:35:33.000Z', account: { acct: 'benj', display_name: 'Benjamin Fame', tags: [] }, actor: { acct: 'admin' }, state: 'open', id: '2', content: 'This is a report', statuses: [] },
|
{ created_at: '2019-05-21T21:35:33.000Z', account: { nickname: 'benjamin', tags: [] }, actor: {}, state: 'open', id: '2', content: 'This is a report', statuses: [] },
|
||||||
{ created_at: '2019-05-20T22:45:33.000Z', account: { acct: 'alice', display_name: 'Alice Pool', tags: [] }, actor: { acct: 'admin2' }, state: 'resolved', id: '1', content: 'Please block this user', statuses: [] },
|
{ created_at: '2019-05-20T22:45:33.000Z', account: { nickname: 'alice', tags: [] }, actor: {}, state: 'resolved', id: '1', content: 'Please block this user', statuses: [] },
|
||||||
{ created_at: '2019-05-18T13:01:33.000Z', account: { acct: 'nick', display_name: 'Nick Keys', tags: [] }, actor: { acct: 'admin' }, state: 'closed', id: '3', content: '', statuses: [] },
|
{ created_at: '2019-05-18T13:01:33.000Z', account: { nickname: 'nick_keys', tags: [] }, actor: {}, state: 'closed', id: '3', content: '', statuses: [] },
|
||||||
{ created_at: '2019-05-21T21:35:33.000Z', account: { acct: 'benj', display_name: 'Benjamin Fame', tags: [] }, actor: { acct: 'admin' }, state: 'open', id: '5', content: 'This is a report', statuses: [] },
|
{ created_at: '2019-05-21T21:35:33.000Z', account: { nickname: 'benjamin', tags: [] }, actor: {}, state: 'open', id: '5', content: 'This is a report', statuses: [] },
|
||||||
{ created_at: '2019-05-20T22:45:33.000Z', account: { acct: 'alice', display_name: 'Alice Pool', tags: [] }, actor: { acct: 'admin2' }, state: 'resolved', id: '7', content: 'Please block this user', statuses: [
|
{ created_at: '2019-05-20T22:45:33.000Z', account: { nickname: 'alice', tags: [] }, actor: {}, state: 'resolved', id: '7', content: 'Please block this user', statuses: [
|
||||||
{ account: { display_name: 'Alice Pool', avatar: '' }, visibility: 'public', sensitive: false, id: '11', content: 'Hey!', url: '', created_at: '2019-05-10T21:35:33.000Z' },
|
{ account: { nickname: 'alice', avatar: '' }, visibility: 'public', sensitive: false, id: '11', content: 'Hey!', url: '', created_at: '2019-05-10T21:35:33.000Z' },
|
||||||
{ account: { display_name: 'Alice Pool', avatar: '' }, visibility: 'unlisted', sensitive: true, id: '10', content: 'Bye!', url: '', created_at: '2019-05-10T21:00:33.000Z' }
|
{ account: { nickname: 'alice', avatar: '' }, visibility: 'unlisted', sensitive: true, id: '10', content: 'Bye!', url: '', created_at: '2019-05-10T21:00:33.000Z' }
|
||||||
] },
|
] },
|
||||||
{ created_at: '2019-05-18T13:01:33.000Z', account: { acct: 'nick', display_name: 'Nick Keys', tags: [] }, actor: { acct: 'admin' }, state: 'closed', id: '6', content: '', statuses: [] },
|
{ created_at: '2019-05-18T13:01:33.000Z', account: { nickname: 'nick_keys', tags: [] }, actor: {}, state: 'closed', id: '6', content: '', statuses: [] },
|
||||||
{ created_at: '2019-05-18T13:01:33.000Z', account: { acct: 'nick', display_name: 'Nick Keys', tags: [] }, actor: { acct: 'admin' }, state: 'closed', id: '4', content: '', statuses: [] }
|
{ created_at: '2019-05-18T13:01:33.000Z', account: { nickname: 'nick_keys', tags: [] }, actor: {}, state: 'closed', id: '4', content: '', statuses: [] }
|
||||||
]
|
]
|
||||||
|
|
||||||
export async function fetchReports(filter, page, pageSize, authHost, token) {
|
export async function fetchReports(filter, page, pageSize, authHost, token) {
|
||||||
|
@ -21,11 +21,19 @@ export async function changeState(reportsData, authHost, token) {
|
||||||
return Promise.resolve({ data: '' })
|
return Promise.resolve({ data: '' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function changeStatusScope(id, sensitive, visibility, authHost, token) {
|
export async function createNote(content, reportID, authHost, token) {
|
||||||
const status = reports[4].statuses[0]
|
|
||||||
return Promise.resolve({ data: { ...status, sensitive, visibility }})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteStatus(statusId, authHost, token) {
|
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function deleteNote(noteID, reportID, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
// export async function changeStatusScope(id, sensitive, visibility, authHost, token) {
|
||||||
|
// const status = reports[4].statuses[0]
|
||||||
|
// return Promise.resolve({ data: { ...status, sensitive, visibility }})
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export async function deleteStatus(statusId, authHost, token) {
|
||||||
|
// return Promise.resolve()
|
||||||
|
// }
|
||||||
|
|
59
src/api/__mocks__/settings.js
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
const configsWithTagPolicy = {
|
||||||
|
configs: [{
|
||||||
|
group: ':pleroma',
|
||||||
|
key: ':mrf',
|
||||||
|
value: [
|
||||||
|
{ tuple: [':policies', ['Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy', 'Pleroma.Web.ActivityPub.MRF.TagPolicy']] },
|
||||||
|
{ tuple: [':transparency', true] },
|
||||||
|
{ tuple: [':transparency_exclusions', []] }
|
||||||
|
] },
|
||||||
|
{
|
||||||
|
group: ':pleroma',
|
||||||
|
key: ':media_proxy',
|
||||||
|
value: [
|
||||||
|
{ tuple: [':enabled', true] },
|
||||||
|
{ tuple: [':invalidation', [
|
||||||
|
{ tuple: [':provider', 'Pleroma.Web.MediaProxy.Invalidation.Script'] },
|
||||||
|
{ tuple: [':enabled', true] }
|
||||||
|
]] }
|
||||||
|
] }],
|
||||||
|
need_reboot: false
|
||||||
|
}
|
||||||
|
|
||||||
|
const configAfterUpdate = {
|
||||||
|
configs: [{
|
||||||
|
db: [':policies'],
|
||||||
|
group: ':pleroma',
|
||||||
|
key: ':mrf',
|
||||||
|
value: [{ tuple: [':policies', ['Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy', 'Pleroma.Web.ActivityPub.MRF.TagPolicy']] }]
|
||||||
|
}],
|
||||||
|
need_reboot: false
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchSettings(authHost, token) {
|
||||||
|
return Promise.resolve({ data: configsWithTagPolicy })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getInstanceDocument(name, authHost, token) {
|
||||||
|
return Promise.resolve({ data: '<h1>Instance panel</h1>' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateSettings(configs, authHost, token) {
|
||||||
|
return Promise.resolve({ data: configAfterUpdate })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteInstanceDocument(name, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchDescription(authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateInstanceDocument(name, formData, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function removeSettings(configs, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
|
@ -5,3 +5,93 @@ export async function changeStatusScope(id, sensitive, visibility, authHost, tok
|
||||||
export async function deleteStatus(id, authHost, token) {
|
export async function deleteStatus(id, authHost, token) {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchStatus(id, authHost, token) {
|
||||||
|
const data = {
|
||||||
|
account: {
|
||||||
|
id: '9n1bySks25olxWrku0',
|
||||||
|
avatar: 'http://localhost:4000/images/avi.png',
|
||||||
|
nickname: 'dolin',
|
||||||
|
tags: ['mrf_tag:media-strip', 'mrf_tag:sandbox', 'mrf_tag:disable-any-subscription', 'mrf_tag:media-force-nsfw'],
|
||||||
|
url: 'http://localhost:4000/users/dolin'
|
||||||
|
},
|
||||||
|
content: 'pizza makes everything better',
|
||||||
|
created_at: '2020-05-22T17:34:34.000Z',
|
||||||
|
id: '9vJOO3iFPyjNaEhJ5s',
|
||||||
|
media_attachments: [],
|
||||||
|
poll: null,
|
||||||
|
sensitive: false,
|
||||||
|
spoiler_text: '',
|
||||||
|
visibility: 'public',
|
||||||
|
url: 'http://localhost:4000/notice/9vJOO3iFPyjNaEhJ5s'
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve({ data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchStatusesByInstance({ instance, authHost, token, pageSize, page }) {
|
||||||
|
let data
|
||||||
|
if (pageSize === 1) {
|
||||||
|
data = page === 1 || page === 2
|
||||||
|
? [{
|
||||||
|
'account': {
|
||||||
|
'avatar': 'http://localhost:4000/images/avi.png',
|
||||||
|
'nickname': 'sky',
|
||||||
|
'url': 'http://localhost:4000/users/sky'
|
||||||
|
},
|
||||||
|
'content': 'A nice young couple contacted us from Brazil to decorate their newly acquired apartment.',
|
||||||
|
'created_at': '2020-01-31T18:20:01.000Z',
|
||||||
|
'id': '9rZIr0Jzao5Gjgfmro',
|
||||||
|
'sensitive': false,
|
||||||
|
'url': 'http://localhost:4000/objects/7af9abbd-fb6c-4318-aeb7-6636c138ac98',
|
||||||
|
'visibility': 'unlisted'
|
||||||
|
}]
|
||||||
|
: []
|
||||||
|
} else {
|
||||||
|
data = [
|
||||||
|
{
|
||||||
|
'account': {
|
||||||
|
'avatar': 'http://localhost:4000/images/avi.png',
|
||||||
|
'nickname': 'sky',
|
||||||
|
'url': 'http://localhost:4000/users/sky'
|
||||||
|
},
|
||||||
|
'content': 'i love parks&rec',
|
||||||
|
'created_at': '2020-04-12T18:20:01.000Z',
|
||||||
|
'id': 'o5Gjgfmro9rZIr0Jza',
|
||||||
|
'sensitive': false,
|
||||||
|
'url': 'http://localhost:4000/objects/7af9abbd-aeb7-6636c138ac98-fb6c-4318',
|
||||||
|
'visibility': 'unlisted'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'account': {
|
||||||
|
'avatar': 'http://localhost:4000/images/avi.png',
|
||||||
|
'nickname': 'sky',
|
||||||
|
'url': 'http://localhost:4000/users/sky'
|
||||||
|
},
|
||||||
|
'content': 'the happiest man ever',
|
||||||
|
'created_at': '2019-11-23T12:56:18.000Z',
|
||||||
|
'id': '9pFoVfWMU3A96Rzq3k',
|
||||||
|
'sensitive': false,
|
||||||
|
'url': 'http://localhost:4000/objects/449c90fe-c457-4c64-baf2-fe6d0a59ca25',
|
||||||
|
'visibility': 'unlisted'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
return Promise.resolve({ data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchStatusesCount(instance, authHost, token) {
|
||||||
|
const data = instance === 'heaven.com'
|
||||||
|
? {
|
||||||
|
'status_visibility':
|
||||||
|
{ 'direct': 1, 'private': 2, 'public': 3, 'unlisted': 0 }
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
'status_visibility':
|
||||||
|
{ 'direct': 4, 'private': 10, 'public': 4, 'unlisted': 10 }
|
||||||
|
}
|
||||||
|
return Promise.resolve({ data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchStatuses({ godmode, localOnly, authHost, token, pageSize, page }) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
|
@ -1,53 +1,46 @@
|
||||||
export let users = [
|
export let users = [
|
||||||
{ active: true, deactivated: false, id: '2', nickname: 'allis', local: true, external: false, roles: { admin: true, moderator: false }, tags: [] },
|
{ is_confirmed: true, is_approved: true, is_active: true, id: '2', nickname: 'allis', local: true, external: false, roles: { admin: true, moderator: false }, tags: [], actor_type: 'Person' },
|
||||||
{ active: true, deactivated: false, id: '10', nickname: 'bob', local: false, external: true, roles: { admin: false, moderator: false }, tags: ['sandbox'] },
|
{ is_confirmed: true, is_approved: true, is_active: true, id: '10', nickname: 'bob', local: true, external: false, roles: { admin: false, moderator: false }, tags: ['mrf_tag:sandbox'], actor_type: 'Person' },
|
||||||
{ active: false, deactivated: true, id: 'abc', nickname: 'john', local: true, external: false, roles: { admin: false, moderator: false }, tags: ['strip_media'] }
|
{ is_confirmed: true, is_approved: false, is_active: true, id: '567', nickname: 'ded', local: false, external: true, roles: { admin: false, moderator: false }, tags: [], actor_type: 'Person' },
|
||||||
|
{ is_confirmed: true, is_approved: true, is_active: false, id: 'abc', nickname: 'john', local: true, external: false, roles: { admin: false, moderator: false }, tags: ['mrf_tag:media-strip'], actor_type: 'Person' },
|
||||||
|
{ is_confirmed: true, is_approved: false, is_active: true, id: '100', nickname: 'sally', local: true, external: false, roles: { admin: false, moderator: false }, tags: [], actor_type: 'Service' },
|
||||||
|
{ is_confirmed: true, is_approved: false, is_active: true, id: '123', nickname: 'bot', local: true, external: false, roles: { admin: false, moderator: false }, tags: [], actor_type: 'Application' }
|
||||||
]
|
]
|
||||||
|
|
||||||
const userProfile = { avatar: 'avatar.jpg', display_name: 'Allis', nickname: 'allis', id: '2', tags: [], roles: { admin: true, moderator: false }, local: true, external: false }
|
const userProfile = { avatar: 'avatar.jpg', nickname: 'allis', id: '2', tags: [], roles: { admin: true, moderator: false }, local: true, external: false }
|
||||||
|
|
||||||
const userStatuses = []
|
const userStatuses = [
|
||||||
|
{ account: { id: '9n1bySks25olxWrku0', nickname: 'dolin' }, content: 'pizza makes everything better', id: '9vJOO3iFPyjNaEhJ5s', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' },
|
||||||
const filterUsers = (str) => {
|
{ account: { id: '9n1bySks25olxWrku0', nickname: 'dolin' }, content: 'pizza time', id: '9vJPD5XKOdzQ0bvGLY', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' },
|
||||||
const filters = str.split(',').filter(item => item.length > 0)
|
{ account: { id: '9n1bySks25olxWrku0', nickname: 'dolin' }, content: 'what is yout favorite pizza?', id: '9jop82OBXeFPYulVjM', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' }
|
||||||
if (filters.length === 0) {
|
]
|
||||||
return users
|
|
||||||
}
|
|
||||||
const applyFilters = (acc, filters, users) => {
|
|
||||||
if (filters.length === 0) {
|
|
||||||
return acc
|
|
||||||
}
|
|
||||||
const filteredUsers = users.filter(user => user[filters[0]])
|
|
||||||
const newAcc = [...filteredUsers]
|
|
||||||
return applyFilters(newAcc, filters.slice(1), filteredUsers)
|
|
||||||
}
|
|
||||||
return applyFilters([], filters, users)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function fetchUser(id, authHost, token) {
|
export async function fetchUser(id, authHost, token) {
|
||||||
return Promise.resolve({ data: userProfile })
|
return Promise.resolve({ data: userProfile })
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchUsers(filters, authHost, token, page = 1) {
|
export async function fetchUserCredentials(nickname, authHost, token) {
|
||||||
const filteredUsers = filterUsers(filters)
|
return Promise.resolve({ data: {}})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchUsers(filters, actorTypeFilters, authHost, token, page = 1) {
|
||||||
return Promise.resolve({ data: {
|
return Promise.resolve({ data: {
|
||||||
users: filteredUsers,
|
users,
|
||||||
count: filteredUsers.length,
|
count: users.length,
|
||||||
page_size: 50
|
page_size: 50
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchUserStatuses(id, authHost, godmode, token) {
|
export async function fetchUserStatuses(id, authHost, godmode, token) {
|
||||||
return Promise.resolve({ data: userStatuses })
|
return Promise.resolve({ data: { activities: userStatuses }})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPasswordResetToken(nickname, authHost, token) {
|
export async function getPasswordResetToken(nickname, authHost, token) {
|
||||||
return Promise.resolve({ data: { token: 'g05lxnBJQnL', link: 'http://url/api/pleroma/password_reset/g05lxnBJQnL' }})
|
return Promise.resolve({ data: { token: 'g05lxnBJQnL', link: 'http://url/api/v1/pleroma/password_reset/g05lxnBJQnL' }})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function searchUsers(query, filters, authHost, token, page = 1) {
|
export async function searchUsers(query, filters, actorTypeFilters, authHost, token, page = 1) {
|
||||||
const filteredUsers = filterUsers(filters)
|
const response = users.filter(user => user.nickname === query)
|
||||||
const response = filteredUsers.filter(user => user.nickname === query)
|
|
||||||
return Promise.resolve({ data: {
|
return Promise.resolve({ data: {
|
||||||
users: response,
|
users: response,
|
||||||
count: response.length,
|
count: response.length,
|
||||||
|
@ -58,7 +51,7 @@ export async function searchUsers(query, filters, authHost, token, page = 1) {
|
||||||
export async function activateUsers(nicknames, authHost, token) {
|
export async function activateUsers(nicknames, authHost, token) {
|
||||||
const response = nicknames.map(nickname => {
|
const response = nicknames.map(nickname => {
|
||||||
const currentUser = users.find(user => user.nickname === nickname)
|
const currentUser = users.find(user => user.nickname === nickname)
|
||||||
return { ...currentUser, deactivated: false }
|
return { ...currentUser, is_active: true }
|
||||||
})
|
})
|
||||||
return Promise.resolve({ data: response })
|
return Promise.resolve({ data: response })
|
||||||
}
|
}
|
||||||
|
@ -72,7 +65,15 @@ export async function addRight(nicknames, right, authHost, token) {
|
||||||
export async function deactivateUsers(nicknames, authHost, token) {
|
export async function deactivateUsers(nicknames, authHost, token) {
|
||||||
const response = nicknames.map(nickname => {
|
const response = nicknames.map(nickname => {
|
||||||
const currentUser = users.find(user => user.nickname === nickname)
|
const currentUser = users.find(user => user.nickname === nickname)
|
||||||
return { ...currentUser, deactivated: true }
|
return { ...currentUser, is_active: false }
|
||||||
|
})
|
||||||
|
return Promise.resolve({ data: response })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function approveUserAccount(nicknames, authHost, token) {
|
||||||
|
const response = nicknames.map(nickname => {
|
||||||
|
const currentUser = users.find(user => user.nickname === nickname)
|
||||||
|
return { ...currentUser, is_approved: true }
|
||||||
})
|
})
|
||||||
return Promise.resolve({ data: response })
|
return Promise.resolve({ data: response })
|
||||||
}
|
}
|
||||||
|
@ -98,7 +99,27 @@ export async function untagUser(nickname, tag, authHost, token) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createNewAccount(nickname, email, password, authHost, token) {
|
export async function createNewAccount(nickname, email, password, authHost, token) {
|
||||||
const newUser = { active: true, deactivated: false, id: '15', nickname, local: true, external: false, roles: { admin: false, moderator: false }, tags: [] }
|
const newUser = { active: true, is_active: true, id: '15', nickname, local: true, external: false, roles: { admin: false, moderator: false }, tags: [] }
|
||||||
users = [...users, newUser]
|
users = [...users, newUser]
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateUserCredentials(nickname, credentials, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function disableMfa(nickname, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function forcePasswordReset(nicknames, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function confirmUserEmail(nicknames, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function resendConfirmationEmail(nicknames, authHost, token) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
23
src/api/app.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { baseName } from './utils'
|
||||||
|
|
||||||
|
export async function needReboot(authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/need_reboot`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function restartApp(authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/restart`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
|
|
@ -2,22 +2,74 @@ import request from '@/utils/request'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import { baseName } from './utils'
|
import { baseName } from './utils'
|
||||||
|
|
||||||
import _ from 'lodash'
|
export async function addNewEmojiFile(packName, file, shortcode, filename, host, token) {
|
||||||
|
const data = new FormData()
|
||||||
|
if (filename.trim() !== '') {
|
||||||
|
data.set('filename', filename)
|
||||||
|
}
|
||||||
|
if (shortcode.trim() !== '') {
|
||||||
|
data.set('shortcode', shortcode)
|
||||||
|
}
|
||||||
|
data.set('file', file)
|
||||||
|
|
||||||
export async function deletePack(host, token, name) {
|
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(host),
|
baseURL: baseName(host),
|
||||||
url: `/api/pleroma/emoji/packs/${name}`,
|
url: `/api/v1/pleroma/emoji/packs/files?name=${packName}`,
|
||||||
|
method: 'post',
|
||||||
|
headers: authHeaders(token),
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addressOfEmojiInPack(host, packName, name) {
|
||||||
|
return `${baseName(host)}/emoji/${encodeUri(packName)}/${name}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createPack(host, token, packName) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(host),
|
||||||
|
url: `/api/v1/pleroma/emoji/pack?name=${packName}`,
|
||||||
|
method: 'post',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteEmojiFile(packName, shortcode, host, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(host),
|
||||||
|
url: `/api/v1/pleroma/emoji/packs/files?name=${packName}&shortcode=${shortcode}`,
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function reloadEmoji(host, token) {
|
export async function deletePack(host, token, packName) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(host),
|
baseURL: baseName(host),
|
||||||
url: '/api/pleroma/admin/reload_emoji',
|
url: `/api/v1/pleroma/emoji/pack?name=${packName}`,
|
||||||
|
method: 'delete',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function downloadFrom(instanceAddress, packName, as, host, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(host),
|
||||||
|
url: '/api/v1/pleroma/emoji/packs/download',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
|
headers: authHeaders(token),
|
||||||
|
data: as.trim() === ''
|
||||||
|
? { url: baseName(instanceAddress), name: packName }
|
||||||
|
: { url: baseName(instanceAddress), name: packName, as },
|
||||||
|
timeout: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchPack(packName, page, pageSize, host, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(host),
|
||||||
|
url: `/api/v1/pleroma/emoji/pack?name=${packName}&page=${page}&page_size=${pageSize}`,
|
||||||
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -25,132 +77,60 @@ export async function reloadEmoji(host, token) {
|
||||||
export async function importFromFS(host, token) {
|
export async function importFromFS(host, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(host),
|
baseURL: baseName(host),
|
||||||
url: '/api/pleroma/emoji/packs/import_from_fs',
|
url: '/api/v1/pleroma/emoji/packs/import',
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listPacks(page, pageSize, host, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(host),
|
||||||
|
url: `/api/v1/pleroma/emoji/packs?page=${page}&page_size=${pageSize}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listRemotePacks(instance, page, pageSize, host, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(host),
|
||||||
|
url: `/api/v1/pleroma/emoji/packs/remote?url=${baseName(instance)}&page=${page}&page_size=${pageSize}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function reloadEmoji(host, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(host),
|
||||||
|
url: '/api/v1/pleroma/admin/reload_emoji',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createPack(host, token, name) {
|
export async function savePackMetadata(host, token, packName, metadata) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(host),
|
baseURL: baseName(host),
|
||||||
url: `/api/pleroma/emoji/packs/${name}`,
|
url: `/api/v1/pleroma/emoji/pack?name=${packName}`,
|
||||||
method: 'put',
|
method: 'patch',
|
||||||
headers: authHeaders(token)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function listPacks(host) {
|
|
||||||
return await request({
|
|
||||||
baseURL: baseName(host),
|
|
||||||
url: `/api/pleroma/emoji/packs/`,
|
|
||||||
method: 'get'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function listRemotePacks(host, token, instance) {
|
|
||||||
return await request({
|
|
||||||
baseURL: baseName(host),
|
|
||||||
url: `/api/pleroma/emoji/packs/list_from`,
|
|
||||||
method: 'post',
|
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { instance_address: baseName(instance) }
|
data: { metadata },
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function downloadFrom(host, instance_address, pack_name, as, token) {
|
|
||||||
if (as.trim() === '') {
|
|
||||||
as = null
|
|
||||||
}
|
|
||||||
|
|
||||||
return await request({
|
|
||||||
baseURL: baseName(host),
|
|
||||||
url: '/api/pleroma/emoji/packs/download_from',
|
|
||||||
method: 'post',
|
|
||||||
headers: authHeaders(token),
|
|
||||||
data: { instance_address: baseName(instance_address), pack_name, as },
|
|
||||||
timeout: 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function savePackMetadata(host, token, name, new_data) {
|
|
||||||
return await request({
|
|
||||||
baseURL: baseName(host),
|
|
||||||
url: `/api/pleroma/emoji/packs/${name}/update_metadata`,
|
|
||||||
method: 'post',
|
|
||||||
headers: authHeaders(token),
|
|
||||||
data: { name, new_data },
|
|
||||||
timeout: 0 // This might take a long time
|
timeout: 0 // This might take a long time
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function fileUpdateFormData(d) {
|
export async function updateEmojiFile(packName, shortcode, newShortcode, newFilename, force, host, token) {
|
||||||
const data = new FormData()
|
|
||||||
|
|
||||||
_.each(d, (v, k) => {
|
|
||||||
data.set(k, v)
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updatePackFile(host, token, args) {
|
|
||||||
let data = null
|
|
||||||
|
|
||||||
switch (args.action) {
|
|
||||||
case 'add': {
|
|
||||||
const { shortcode, file, fileName } = args
|
|
||||||
|
|
||||||
data = fileUpdateFormData({
|
|
||||||
action: 'add',
|
|
||||||
shortcode: shortcode,
|
|
||||||
file: file
|
|
||||||
})
|
|
||||||
if (fileName.trim() !== '') {
|
|
||||||
data.set('filename', fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'update': {
|
|
||||||
const { oldName, newName, newFilename } = args
|
|
||||||
|
|
||||||
data = fileUpdateFormData({
|
|
||||||
action: 'update',
|
|
||||||
shortcode: oldName,
|
|
||||||
new_shortcode: newName,
|
|
||||||
new_filename: newFilename
|
|
||||||
})
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'remove': {
|
|
||||||
const { name } = args
|
|
||||||
data = fileUpdateFormData({
|
|
||||||
action: 'remove',
|
|
||||||
shortcode: name
|
|
||||||
})
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const { packName } = args
|
|
||||||
|
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(host),
|
baseURL: baseName(host),
|
||||||
url: `/api/pleroma/emoji/packs/${packName}/update_file`,
|
url: `/api/v1/pleroma/emoji/packs/files?name=${packName}`,
|
||||||
method: 'post',
|
method: 'patch',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: data,
|
data: { shortcode, new_shortcode: newShortcode, new_filename: newFilename, force }
|
||||||
timeout: 0
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addressOfEmojiInPack(host, packName, name) {
|
|
||||||
return `${baseName(host)}/emoji/${packName}/${name}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
|
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
|
||||||
|
|
||||||
|
const encodeUri = (name) => encodeURIComponent(name)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { baseName } from './utils'
|
||||||
export async function generateInviteToken(max_use, expires_at, authHost, token) {
|
export async function generateInviteToken(max_use, expires_at, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/invite_token`,
|
url: `/api/v1/pleroma/admin/users/invite_token`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: expires_at && expires_at.length > 0 ? { max_use, expires_at } : { max_use }
|
data: expires_at && expires_at.length > 0 ? { max_use, expires_at } : { max_use }
|
||||||
|
@ -16,7 +16,7 @@ export async function inviteViaEmail(email, name, authHost, token) {
|
||||||
const data = name.length > 0 ? { email, name } : { email }
|
const data = name.length > 0 ? { email, name } : { email }
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: '/api/pleroma/admin/users/email_invite',
|
url: '/api/v1/pleroma/admin/users/email_invite',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data
|
data
|
||||||
|
@ -26,7 +26,7 @@ export async function inviteViaEmail(email, name, authHost, token) {
|
||||||
export async function listInviteTokens(authHost, token) {
|
export async function listInviteTokens(authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/invites`,
|
url: `/api/v1/pleroma/admin/users/invites`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -35,7 +35,7 @@ export async function listInviteTokens(authHost, token) {
|
||||||
export async function revokeToken(tokenToRevoke, authHost, token) {
|
export async function revokeToken(tokenToRevoke, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/revoke_invite`,
|
url: `/api/v1/pleroma/admin/users/revoke_invite`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { token: tokenToRevoke }
|
data: { token: tokenToRevoke }
|
||||||
|
|
43
src/api/mediaProxyCache.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { baseName } from './utils'
|
||||||
|
|
||||||
|
export async function listBannedUrls(page, pageSize, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/media_proxy_caches?page=${page}&page_size=${pageSize}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function purgeUrls(urls, ban, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/media_proxy_caches/purge`,
|
||||||
|
method: 'post',
|
||||||
|
headers: authHeaders(token),
|
||||||
|
data: { urls, ban }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function removeBannedUrls(urls, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/media_proxy_caches/delete`,
|
||||||
|
method: 'post',
|
||||||
|
headers: authHeaders(token),
|
||||||
|
data: { urls }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function searchBannedUrls(query, page, pageSize, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/media_proxy_caches?query=${query}&page=${page}&page_size=${pageSize}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
|
19
src/api/mediaUpload.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { baseName } from './utils'
|
||||||
|
|
||||||
|
const UPLOAD_URL = '/api/v1/media'
|
||||||
|
|
||||||
|
export function uploadMedia({ formData, authHost }) {
|
||||||
|
const url = baseName(authHost) + UPLOAD_URL
|
||||||
|
|
||||||
|
return fetch(url, {
|
||||||
|
body: formData,
|
||||||
|
method: 'POST',
|
||||||
|
headers: authHeaders()
|
||||||
|
})
|
||||||
|
.then((data) => data.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
const authHeaders = () => {
|
||||||
|
return { 'Authorization': `Bearer ${getToken()}` }
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ export async function fetchLog(authHost, token, params, page = 1) {
|
||||||
|
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/moderation_log?${normalizedParams}`,
|
url: `/api/v1/pleroma/admin/moderation_log?${normalizedParams}`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -20,7 +20,7 @@ export async function fetchLog(authHost, token, params, page = 1) {
|
||||||
export async function fetchAdmins(authHost, token) {
|
export async function fetchAdmins(authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users?filters=is_admin`,
|
url: `/api/v1/pleroma/admin/users?filters=is_admin`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -29,7 +29,7 @@ export async function fetchAdmins(authHost, token) {
|
||||||
export async function fetchModerators(authHost, token) {
|
export async function fetchModerators(authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users?filters=is_moderator`,
|
url: `/api/v1/pleroma/admin/users?filters=is_moderator`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,29 +5,29 @@ import { baseName } from './utils'
|
||||||
export async function fetchRelays(authHost, token) {
|
export async function fetchRelays(authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: '/api/pleroma/admin/relay',
|
url: '/api/v1/pleroma/admin/relay',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addRelay(relay, authHost, token) {
|
export async function addRelay(relay_url, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: '/api/pleroma/admin/relay',
|
url: '/api/v1/pleroma/admin/relay',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { relay_url: relay }
|
data: { relay_url }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteRelay(relay, authHost, token) {
|
export async function deleteRelay(relay_url, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: '/api/pleroma/admin/relay',
|
url: '/api/v1/pleroma/admin/relay',
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { relay_url: `https://${relay}/actor` }
|
data: { relay_url }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { baseName } from './utils'
|
||||||
export async function changeState(reports, authHost, token) {
|
export async function changeState(reports, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/reports`,
|
url: `/api/v1/pleroma/admin/reports`,
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { reports }
|
data: { reports }
|
||||||
|
@ -14,8 +14,8 @@ export async function changeState(reports, authHost, token) {
|
||||||
|
|
||||||
export async function fetchReports(filter, page, pageSize, authHost, token) {
|
export async function fetchReports(filter, page, pageSize, authHost, token) {
|
||||||
const url = filter.length > 0
|
const url = filter.length > 0
|
||||||
? `/api/pleroma/admin/reports?state=${filter}&page=${page}&page_size=${pageSize}`
|
? `/api/v1/pleroma/admin/reports?state=${filter}&page=${page}&page_size=${pageSize}`
|
||||||
: `/api/pleroma/admin/reports?page=${page}&page_size=${pageSize}`
|
: `/api/v1/pleroma/admin/reports?page=${page}&page_size=${pageSize}`
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url,
|
url,
|
||||||
|
@ -24,10 +24,19 @@ export async function fetchReports(filter, page, pageSize, authHost, token) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchSingleReport(id, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/reports/${id}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export async function createNote(content, reportID, authHost, token) {
|
export async function createNote(content, reportID, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/reports/${reportID}/notes`,
|
url: `/api/v1/pleroma/admin/reports/${reportID}/notes`,
|
||||||
method: `post`,
|
method: `post`,
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { content }
|
data: { content }
|
||||||
|
@ -37,7 +46,7 @@ export async function createNote(content, reportID, authHost, token) {
|
||||||
export async function deleteNote(noteID, reportID, authHost, token) {
|
export async function deleteNote(noteID, reportID, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/reports/${reportID}/notes/${noteID}`,
|
url: `/api/v1/pleroma/admin/reports/${reportID}/notes/${noteID}`,
|
||||||
method: `delete`,
|
method: `delete`,
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,218 +0,0 @@
|
||||||
export const reports = [
|
|
||||||
{
|
|
||||||
id: '1',
|
|
||||||
timestamp: '2019/4/12',
|
|
||||||
local: true,
|
|
||||||
from: 'John', // actor nickname
|
|
||||||
object: 'Bob', // user nickname
|
|
||||||
header: 'Report #1', // content
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Nick', text: 'Lorem ipsum', id: '1', timestamp: '2019/4/13' },
|
|
||||||
{ author: 'Val', text: 'dolor sit amet', id: '2', timestamp: '2019/4/13' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
timestamp: '2019/4/1',
|
|
||||||
local: true,
|
|
||||||
from: 'Max',
|
|
||||||
object: 'Vic',
|
|
||||||
header: 'Report #2',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '3', timestamp: '2019/4/2' },
|
|
||||||
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '4', timestamp: '2019/4/3' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3',
|
|
||||||
timestamp: '2019/2/28',
|
|
||||||
local: true,
|
|
||||||
from: 'Tim',
|
|
||||||
object: 'Jen',
|
|
||||||
header: 'Report #3',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '5', timestamp: '2019/3/1' }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4',
|
|
||||||
timestamp: '2019/4/12',
|
|
||||||
local: true,
|
|
||||||
from: 'John', // actor nickname
|
|
||||||
object: 'Bob', // user nickname
|
|
||||||
header: 'Report #4', // content
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Nick', text: 'Lorem ipsum', id: '6', timestamp: '2019/4/13' },
|
|
||||||
{ author: 'Val', text: 'dolor sit amet', id: '7', timestamp: '2019/4/13' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5',
|
|
||||||
timestamp: '2019/4/1',
|
|
||||||
local: true,
|
|
||||||
from: 'Max',
|
|
||||||
object: 'Vic',
|
|
||||||
header: 'Report #5',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '8', timestamp: '2019/4/2' },
|
|
||||||
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '9', timestamp: '2019/4/3' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '6',
|
|
||||||
timestamp: '2019/2/28',
|
|
||||||
local: true,
|
|
||||||
from: 'Tim',
|
|
||||||
object: 'Jen',
|
|
||||||
header: 'Report #6',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '10', timestamp: '2019/3/1' }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '7',
|
|
||||||
timestamp: '2019/4/12',
|
|
||||||
local: true,
|
|
||||||
from: 'John', // actor nickname
|
|
||||||
object: 'Bob', // user nickname
|
|
||||||
header: 'Report #7', // content
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Nick', text: 'Lorem ipsum', id: '11', timestamp: '2019/4/13' },
|
|
||||||
{ author: 'Val', text: 'dolor sit amet', id: '12', timestamp: '2019/4/13' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '8',
|
|
||||||
timestamp: '2019/4/1',
|
|
||||||
local: true,
|
|
||||||
from: 'Max',
|
|
||||||
object: 'Vic',
|
|
||||||
header: 'Report #8',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '13', timestamp: '2019/4/2' },
|
|
||||||
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '14', timestamp: '2019/4/3' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '9',
|
|
||||||
timestamp: '2019/2/28',
|
|
||||||
local: true,
|
|
||||||
from: 'Tim',
|
|
||||||
object: 'Jen',
|
|
||||||
header: 'Report #9',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '15', timestamp: '2019/3/1' }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '10',
|
|
||||||
timestamp: '2019/4/12',
|
|
||||||
local: true,
|
|
||||||
from: 'John', // actor nickname
|
|
||||||
object: 'Bob', // user nickname
|
|
||||||
header: 'Report #10', // content
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Nick', text: 'Lorem ipsum', id: '16', timestamp: '2019/4/13' },
|
|
||||||
{ author: 'Val', text: 'dolor sit amet', id: '17', timestamp: '2019/4/13' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '11',
|
|
||||||
timestamp: '2019/4/1',
|
|
||||||
local: true,
|
|
||||||
from: 'Max',
|
|
||||||
object: 'Vic',
|
|
||||||
header: 'Report #11',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '18', timestamp: '2019/4/2' },
|
|
||||||
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '19', timestamp: '2019/4/3' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '12',
|
|
||||||
timestamp: '2019/2/28',
|
|
||||||
local: true,
|
|
||||||
from: 'Tim',
|
|
||||||
object: 'Jen',
|
|
||||||
header: 'Report #12',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '20', timestamp: '2019/3/1' }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '13',
|
|
||||||
timestamp: '2019/4/12',
|
|
||||||
local: true,
|
|
||||||
from: 'John', // actor nickname
|
|
||||||
object: 'Bob', // user nickname
|
|
||||||
header: 'Report #13', // content
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Nick', text: 'Lorem ipsum', id: '21', timestamp: '2019/4/13' },
|
|
||||||
{ author: 'Val', text: 'dolor sit amet', id: '22', timestamp: '2019/4/13' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '14',
|
|
||||||
timestamp: '2019/4/1',
|
|
||||||
local: true,
|
|
||||||
from: 'Max',
|
|
||||||
object: 'Vic',
|
|
||||||
header: 'Report #14',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '23', timestamp: '2019/4/2' },
|
|
||||||
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '24', timestamp: '2019/4/3' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '15',
|
|
||||||
timestamp: '2019/2/28',
|
|
||||||
local: true,
|
|
||||||
from: 'Tim',
|
|
||||||
object: 'Jen',
|
|
||||||
header: 'Report #15',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '25', timestamp: '2019/3/1' }]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '16',
|
|
||||||
timestamp: '2019/4/12',
|
|
||||||
local: true,
|
|
||||||
from: 'John', // actor nickname
|
|
||||||
object: 'Bob', // user nickname
|
|
||||||
header: 'Report #16', // content
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Nick', text: 'Lorem ipsum', id: '26', timestamp: '2019/4/13' },
|
|
||||||
{ author: 'Val', text: 'dolor sit amet', id: '27', timestamp: '2019/4/13' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '17',
|
|
||||||
timestamp: '2019/4/1',
|
|
||||||
local: true,
|
|
||||||
from: 'Max',
|
|
||||||
object: 'Vic',
|
|
||||||
header: 'Report #17',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [
|
|
||||||
{ author: 'Tony', text: 'consectetur adipiscing elit', id: '28', timestamp: '2019/4/2' },
|
|
||||||
{ author: 'Zac', text: 'sed do eiusmod tempor incididunt', id: '29', timestamp: '2019/4/3' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '18',
|
|
||||||
timestamp: '2019/2/28',
|
|
||||||
local: true,
|
|
||||||
from: 'Tim',
|
|
||||||
object: 'Jen',
|
|
||||||
header: 'Report #18',
|
|
||||||
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
|
||||||
notes: [{ author: 'Bruce', text: 'ut labore et dolore magna aliqua', id: '30', timestamp: '2019/3/1' }]
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -1,11 +1,30 @@
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import { baseName } from './utils'
|
import { baseName } from './utils'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
export async function deleteInstanceDocument(name, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/instance_document/${name}`,
|
||||||
|
method: 'delete',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export async function fetchDescription(authHost, token) {
|
export async function fetchDescription(authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/config/descriptions`,
|
url: `/api/v1/pleroma/admin/config/descriptions`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchDescription2(authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v2/pleroma/admin/config/descriptions`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -14,16 +33,35 @@ export async function fetchDescription(authHost, token) {
|
||||||
export async function fetchSettings(authHost, token) {
|
export async function fetchSettings(authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/config`,
|
url: `/api/v1/pleroma/admin/config`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getInstanceDocument(name, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/instance_document/${name}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateInstanceDocument(name, formData, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/instance_document/${name}`,
|
||||||
|
method: 'patch',
|
||||||
|
data: formData,
|
||||||
|
headers: { ...authHeaders(token), 'Content-Type': 'multipart/form-data' }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export async function updateSettings(configs, authHost, token) {
|
export async function updateSettings(configs, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/config`,
|
url: `/api/v1/pleroma/admin/config`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { configs }
|
data: { configs }
|
||||||
|
@ -33,20 +71,31 @@ export async function updateSettings(configs, authHost, token) {
|
||||||
export async function removeSettings(configs, authHost, token) {
|
export async function removeSettings(configs, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/config`,
|
url: `/api/v1/pleroma/admin/config`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { configs }
|
data: { configs }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function restartApp(authHost, token) {
|
export async function fetchFrontends(authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/restart`,
|
url: `/api/v1/pleroma/admin/frontends`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function installFrontend(data, authHost, token) {
|
||||||
|
const filteredData = _.pickBy(data)
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/frontends/install`,
|
||||||
|
method: 'post',
|
||||||
|
headers: authHeaders(token),
|
||||||
|
data: filteredData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
|
const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { baseName } from './utils'
|
||||||
export async function changeStatusScope(id, sensitive, visibility, authHost, token) {
|
export async function changeStatusScope(id, sensitive, visibility, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/statuses/${id}`,
|
url: `/api/v1/pleroma/admin/statuses/${id}`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { sensitive, visibility }
|
data: { sensitive, visibility }
|
||||||
|
@ -15,25 +15,34 @@ export async function changeStatusScope(id, sensitive, visibility, authHost, tok
|
||||||
export async function deleteStatus(id, authHost, token) {
|
export async function deleteStatus(id, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/statuses/${id}`,
|
url: `/api/v1/pleroma/admin/statuses/${id}`,
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchStatus(id, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/statuses/${id}`,
|
||||||
|
method: 'get',
|
||||||
|
headers: authHeaders(token)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export async function fetchStatuses({ godmode, localOnly, authHost, token, pageSize, page }) {
|
export async function fetchStatuses({ godmode, localOnly, authHost, token, pageSize, page }) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/statuses?godmode=${godmode}&local_only=${localOnly}&page=${page}&page_size=${pageSize}`,
|
url: `/api/v1/pleroma/admin/statuses?godmode=${godmode}&local_only=${localOnly}&page=${page}&page_size=${pageSize}`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchStatusesCount(authHost, token) {
|
export async function fetchStatusesCount(instance, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/stats`,
|
url: instance ? `/api/v1/pleroma/admin/stats?instance=${instance}` : `/api/v1/pleroma/admin/stats`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -42,7 +51,7 @@ export async function fetchStatusesCount(authHost, token) {
|
||||||
export async function fetchStatusesByInstance({ instance, authHost, token, pageSize, page }) {
|
export async function fetchStatusesByInstance({ instance, authHost, token, pageSize, page }) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/instances/${instance}/statuses?page=${page}&page_size=${pageSize}`,
|
url: `/api/v1/pleroma/admin/instances/${instance}/statuses?page=${page}&page_size=${pageSize}`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { baseName } from './utils'
|
||||||
export async function activateUsers(nicknames, authHost, token) {
|
export async function activateUsers(nicknames, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/activate`,
|
url: `/api/v1/pleroma/admin/users/activate`,
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames }
|
data: { nicknames }
|
||||||
|
@ -15,7 +15,7 @@ export async function activateUsers(nicknames, authHost, token) {
|
||||||
export async function addRight(nicknames, right, authHost, token) {
|
export async function addRight(nicknames, right, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/permission_group/${right}`,
|
url: `/api/v1/pleroma/admin/users/permission_group/${right}`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames }
|
data: { nicknames }
|
||||||
|
@ -25,7 +25,7 @@ export async function addRight(nicknames, right, authHost, token) {
|
||||||
export async function createNewAccount(nickname, email, password, authHost, token) {
|
export async function createNewAccount(nickname, email, password, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: '/api/pleroma/admin/users',
|
url: '/api/v1/pleroma/admin/users',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { users: [{ nickname, email, password }] }
|
data: { users: [{ nickname, email, password }] }
|
||||||
|
@ -35,7 +35,7 @@ export async function createNewAccount(nickname, email, password, authHost, toke
|
||||||
export async function deactivateUsers(nicknames, authHost, token) {
|
export async function deactivateUsers(nicknames, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/deactivate`,
|
url: `/api/v1/pleroma/admin/users/deactivate`,
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames }
|
data: { nicknames }
|
||||||
|
@ -45,7 +45,7 @@ export async function deactivateUsers(nicknames, authHost, token) {
|
||||||
export async function deleteRight(nicknames, right, authHost, token) {
|
export async function deleteRight(nicknames, right, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/permission_group/${right}`,
|
url: `/api/v1/pleroma/admin/users/permission_group/${right}`,
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames }
|
data: { nicknames }
|
||||||
|
@ -55,17 +55,27 @@ export async function deleteRight(nicknames, right, authHost, token) {
|
||||||
export async function deleteUsers(nicknames, authHost, token) {
|
export async function deleteUsers(nicknames, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users`,
|
url: `/api/v1/pleroma/admin/users`,
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames }
|
data: { nicknames }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function disableMfa(nickname, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: `/api/v1/pleroma/admin/users/disable_mfa`,
|
||||||
|
method: 'put',
|
||||||
|
headers: authHeaders(token),
|
||||||
|
data: { nickname }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export async function fetchUser(id, authHost, token) {
|
export async function fetchUser(id, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/${id}`,
|
url: `/api/v1/pleroma/admin/users/${id}`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -74,7 +84,7 @@ export async function fetchUser(id, authHost, token) {
|
||||||
export async function fetchUserCredentials(nickname, authHost, token) {
|
export async function fetchUserCredentials(nickname, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/${nickname}/credentials`,
|
url: `/api/v1/pleroma/admin/users/${nickname}/credentials`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -83,17 +93,24 @@ export async function fetchUserCredentials(nickname, authHost, token) {
|
||||||
export async function updateUserCredentials(nickname, credentials, authHost, token) {
|
export async function updateUserCredentials(nickname, credentials, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/${nickname}/credentials`,
|
url: `/api/v1/pleroma/admin/users/${nickname}/credentials`,
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: credentials
|
data: credentials
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchUsers(filters, authHost, token, page = 1) {
|
export async function fetchUsers(filters, actorTypeFilters, authHost, token, page = 1) {
|
||||||
|
const url = actorTypeFilters.length === 0
|
||||||
|
? `/api/v1/pleroma/admin/users?page=${page}&filters=${filters}`
|
||||||
|
: actorTypeFilters.reduce((acc, filter) => {
|
||||||
|
const newAcc = acc.concat(`&actor_types[]=${filter}`)
|
||||||
|
return newAcc
|
||||||
|
}, `/api/v1/pleroma/admin/users?page=${page}&filters=${filters}`)
|
||||||
|
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users?page=${page}&filters=${filters}`,
|
url,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -102,7 +119,7 @@ export async function fetchUsers(filters, authHost, token, page = 1) {
|
||||||
export async function getPasswordResetToken(nickname, authHost, token) {
|
export async function getPasswordResetToken(nickname, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/${nickname}/password_reset`,
|
url: `/api/v1/pleroma/admin/users/${nickname}/password_reset`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -111,17 +128,24 @@ export async function getPasswordResetToken(nickname, authHost, token) {
|
||||||
export async function forcePasswordReset(nicknames, authHost, token) {
|
export async function forcePasswordReset(nicknames, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/force_password_reset`,
|
url: `/api/v1/pleroma/admin/users/force_password_reset`,
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames }
|
data: { nicknames }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function searchUsers(query, filters, authHost, token, page = 1) {
|
export async function searchUsers(query, filters, actorTypeFilters, authHost, token, page = 1) {
|
||||||
|
const url = actorTypeFilters.length === 0
|
||||||
|
? `/api/v1/pleroma/admin/users?query=${query}&page=${page}&filters=${filters}`
|
||||||
|
: actorTypeFilters.reduce((acc, filter) => {
|
||||||
|
const newAcc = acc.concat(`&actor_types[]=${filter}`)
|
||||||
|
return newAcc
|
||||||
|
}, `/api/v1/pleroma/admin/users?query=${query}&page=${page}&filters=${filters}`)
|
||||||
|
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users?query=${query}&page=${page}&filters=${filters}`,
|
url,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
|
@ -130,7 +154,7 @@ export async function searchUsers(query, filters, authHost, token, page = 1) {
|
||||||
export async function tagUser(nicknames, tags, authHost, token) {
|
export async function tagUser(nicknames, tags, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: '/api/pleroma/admin/users/tag',
|
url: '/api/v1/pleroma/admin/users/tag',
|
||||||
method: 'put',
|
method: 'put',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames, tags }
|
data: { nicknames, tags }
|
||||||
|
@ -140,7 +164,7 @@ export async function tagUser(nicknames, tags, authHost, token) {
|
||||||
export async function untagUser(nicknames, tags, authHost, token) {
|
export async function untagUser(nicknames, tags, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: '/api/pleroma/admin/users/tag',
|
url: '/api/v1/pleroma/admin/users/tag',
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames, tags }
|
data: { nicknames, tags }
|
||||||
|
@ -150,16 +174,26 @@ export async function untagUser(nicknames, tags, authHost, token) {
|
||||||
export async function fetchUserStatuses(id, authHost, godmode, token) {
|
export async function fetchUserStatuses(id, authHost, godmode, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: `/api/pleroma/admin/users/${id}/statuses?godmode=${godmode}`,
|
url: `/api/v1/pleroma/admin/users/${id}/statuses?godmode=${godmode}`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
headers: authHeaders(token)
|
headers: authHeaders(token)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function approveUserAccount(nicknames, authHost, token) {
|
||||||
|
return await request({
|
||||||
|
baseURL: baseName(authHost),
|
||||||
|
url: '/api/v1/pleroma/admin/users/approve',
|
||||||
|
method: 'patch',
|
||||||
|
headers: authHeaders(token),
|
||||||
|
data: { nicknames }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export async function confirmUserEmail(nicknames, authHost, token) {
|
export async function confirmUserEmail(nicknames, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: '/api/pleroma/admin/users/confirm_email',
|
url: '/api/v1/pleroma/admin/users/confirm_email',
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames }
|
data: { nicknames }
|
||||||
|
@ -169,7 +203,7 @@ export async function confirmUserEmail(nicknames, authHost, token) {
|
||||||
export async function resendConfirmationEmail(nicknames, authHost, token) {
|
export async function resendConfirmationEmail(nicknames, authHost, token) {
|
||||||
return await request({
|
return await request({
|
||||||
baseURL: baseName(authHost),
|
baseURL: baseName(authHost),
|
||||||
url: '/api/pleroma/admin/users/resend_confirmation_email',
|
url: '/api/v1/pleroma/admin/users/resend_confirmation_email',
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
headers: authHeaders(token),
|
headers: authHeaders(token),
|
||||||
data: { nicknames }
|
data: { nicknames }
|
||||||
|
|
36
src/components/RebootButton/index.vue
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<template>
|
||||||
|
<el-tooltip v-if="needReboot" :content="$t('settings.restartApp')" placement="bottom-end">
|
||||||
|
<el-button type="warning" class="reboot-button" @click="restartApp">
|
||||||
|
<span>
|
||||||
|
<i class="el-icon-refresh"/>
|
||||||
|
{{ $t('settings.instanceReboot') }}
|
||||||
|
</span>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import i18n from '@/lang'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'RebootButton',
|
||||||
|
computed: {
|
||||||
|
needReboot() {
|
||||||
|
return this.$store.state.app.needReboot
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async restartApp() {
|
||||||
|
try {
|
||||||
|
await this.$store.dispatch('RestartApplication')
|
||||||
|
} catch (e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$message({
|
||||||
|
type: 'success',
|
||||||
|
message: i18n.t('settings.restartSuccess')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,81 +1,78 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<el-card v-if="!status.deleted" class="status-card" @click.native="handleRouteChange()">
|
||||||
<el-card v-if="!status.deleted" class="status-card">
|
<div slot="header">
|
||||||
<div slot="header">
|
<div class="status-header">
|
||||||
<div class="status-header">
|
<div class="status-account-container">
|
||||||
<div class="status-account-container">
|
<div class="status-account">
|
||||||
<div class="status-account">
|
<el-checkbox v-if="showCheckbox" class="status-checkbox" @change="handleStatusSelection(account)"/>
|
||||||
<el-checkbox v-if="showCheckbox" class="status-checkbox" @change="handleStatusSelection(status.account)"/>
|
<router-link
|
||||||
<img :src="status.account.avatar" class="status-avatar-img">
|
v-if="propertyExists(account, 'id')"
|
||||||
<h3 class="status-account-name">{{ status.account.display_name }}</h3>
|
:to="{ name: 'UsersShow', params: { id: account.id }}"
|
||||||
</div>
|
class="router-link"
|
||||||
<a :href="status.account.url" target="_blank" class="account">
|
@click.native.stop>
|
||||||
@{{ status.account.acct }}
|
<div class="status-card-header">
|
||||||
</a>
|
<img v-if="propertyExists(account, 'avatar')" :src="account.avatar" class="status-avatar-img">
|
||||||
|
<span v-if="propertyExists(account, 'nickname')" class="status-account-name">{{ account.nickname }}</span>
|
||||||
|
<span v-else>
|
||||||
|
<span v-if="propertyExists(account, 'nickname')" class="status-account-name">
|
||||||
|
{{ account.nickname }}
|
||||||
|
</span>
|
||||||
|
<span v-else class="status-account-name deactivated">({{ $t('users.invalidNickname') }})</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-actions">
|
</div>
|
||||||
|
<div class="status-actions">
|
||||||
|
<div class="status-tags">
|
||||||
<el-tag v-if="status.sensitive" type="warning" size="large">{{ $t('reports.sensitive') }}</el-tag>
|
<el-tag v-if="status.sensitive" type="warning" size="large">{{ $t('reports.sensitive') }}</el-tag>
|
||||||
<el-tag size="large">{{ capitalizeFirstLetter(status.visibility) }}</el-tag>
|
<el-tag size="large">{{ capitalizeFirstLetter(status.visibility) }}</el-tag>
|
||||||
<el-dropdown trigger="click">
|
|
||||||
<el-button plain size="small" icon="el-icon-edit" class="status-actions-button">
|
|
||||||
{{ $t('reports.changeScope') }}<i class="el-icon-arrow-down el-icon--right"/>
|
|
||||||
</el-button>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="!status.sensitive"
|
|
||||||
@click.native="changeStatus(status.id, true, status.visibility)">
|
|
||||||
{{ $t('reports.addSensitive') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="status.sensitive"
|
|
||||||
@click.native="changeStatus(status.id, false, status.visibility)">
|
|
||||||
{{ $t('reports.removeSensitive') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="status.visibility !== 'public'"
|
|
||||||
@click.native="changeStatus(status.id, status.sensitive, 'public')">
|
|
||||||
{{ $t('reports.public') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="status.visibility !== 'private'"
|
|
||||||
@click.native="changeStatus(status.id, status.sensitive, 'private')">
|
|
||||||
{{ $t('reports.private') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
v-if="status.visibility !== 'unlisted'"
|
|
||||||
@click.native="changeStatus(status.id, status.sensitive, 'unlisted')">
|
|
||||||
{{ $t('reports.unlisted') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
<el-dropdown-item
|
|
||||||
@click.native="deleteStatus(status.id)">
|
|
||||||
{{ $t('reports.deleteStatus') }}
|
|
||||||
</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
</div>
|
||||||
|
<el-dropdown trigger="click" @click.native.stop>
|
||||||
|
<el-button plain size="small" icon="el-icon-edit" class="status-actions-button">
|
||||||
|
{{ $t('reports.changeScope') }}<i class="el-icon-arrow-down el-icon--right"/>
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="!status.sensitive"
|
||||||
|
@click.native="changeStatus(status.id, true, status.visibility)">
|
||||||
|
{{ $t('reports.addSensitive') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="status.sensitive"
|
||||||
|
@click.native="changeStatus(status.id, false, status.visibility)">
|
||||||
|
{{ $t('reports.removeSensitive') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="status.visibility !== 'public'"
|
||||||
|
@click.native="changeStatus(status.id, status.sensitive, 'public')">
|
||||||
|
{{ $t('reports.public') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="status.visibility !== 'private'"
|
||||||
|
@click.native="changeStatus(status.id, status.sensitive, 'private')">
|
||||||
|
{{ $t('reports.private') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="status.visibility !== 'unlisted'"
|
||||||
|
@click.native="changeStatus(status.id, status.sensitive, 'unlisted')">
|
||||||
|
{{ $t('reports.unlisted') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item
|
||||||
|
@click.native="deleteStatus(status.id)">
|
||||||
|
{{ $t('reports.deleteStatus') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-body">
|
</div>
|
||||||
<div v-if="status.spoiler_text">
|
<div class="status-body">
|
||||||
<strong>{{ status.spoiler_text }}</strong>
|
<div v-if="status.spoiler_text">
|
||||||
<el-button v-if="!showHiddenStatus" size="mini" class="show-more-button" @click="showHiddenStatus = true">Show more</el-button>
|
<strong>{{ status.spoiler_text }}</strong>
|
||||||
<el-button v-if="showHiddenStatus" size="mini" class="show-more-button" @click="showHiddenStatus = false">Show less</el-button>
|
<el-button v-if="!showHiddenStatus" size="mini" class="show-more-button" @click="showHiddenStatus = true">Show more</el-button>
|
||||||
<div v-if="showHiddenStatus">
|
<el-button v-if="showHiddenStatus" size="mini" class="show-more-button" @click="showHiddenStatus = false">Show less</el-button>
|
||||||
<span class="status-content" v-html="status.content"/>
|
<div v-if="showHiddenStatus">
|
||||||
<div v-if="status.poll" class="poll">
|
|
||||||
<ul>
|
|
||||||
<li v-for="(option, index) in status.poll.options" :key="index">
|
|
||||||
{{ option.title }}
|
|
||||||
<el-progress :percentage="optionPercent(status.poll, option)" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div v-for="(attachment, index) in status.media_attachments" :key="index" class="image">
|
|
||||||
<img :src="attachment.preview_url">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="!status.spoiler_text">
|
|
||||||
<span class="status-content" v-html="status.content"/>
|
<span class="status-content" v-html="status.content"/>
|
||||||
<div v-if="status.poll" class="poll">
|
<div v-if="status.poll" class="poll">
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -89,30 +86,52 @@
|
||||||
<img :src="attachment.preview_url">
|
<img :src="attachment.preview_url">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a :href="status.url" target="_blank" class="account">
|
</div>
|
||||||
{{ parseTimestamp(status.created_at) }}
|
<div v-if="!status.spoiler_text">
|
||||||
|
<span class="status-content" v-html="status.content"/>
|
||||||
|
<div v-if="status.poll" class="poll">
|
||||||
|
<ul>
|
||||||
|
<li v-for="(option, index) in status.poll.options" :key="index">
|
||||||
|
{{ option.title }}
|
||||||
|
<el-progress :percentage="optionPercent(status.poll, option)" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div v-for="(attachment, index) in status.media_attachments" :key="index" class="image">
|
||||||
|
<img :src="attachment.preview_url">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="status-footer">
|
||||||
|
<span class="status-created-at">{{ parseTimestamp(status.created_at) }}</span>
|
||||||
|
<a v-if="status.url" :href="status.url" target="_blank" class="account" @click.stop>
|
||||||
|
{{ $t('statuses.openStatusInInstance') }}
|
||||||
|
<i class="el-icon-top-right"/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</div>
|
||||||
<el-card v-else class="status-card">
|
</el-card>
|
||||||
<div slot="header">
|
<el-card v-else class="status-card">
|
||||||
<div class="status-header">
|
<div slot="header">
|
||||||
<div class="status-account-container">
|
<div class="status-header">
|
||||||
<div class="status-account">
|
<div class="status-account-container">
|
||||||
<h4 class="status-deleted">{{ $t('reports.statusDeleted') }}</h4>
|
<div class="status-account">
|
||||||
</div>
|
<h4 class="status-deleted">{{ $t('reports.statusDeleted') }}</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-body">
|
</div>
|
||||||
<span v-if="status.content" class="status-content" v-html="status.content"/>
|
<div class="status-body">
|
||||||
<span v-else class="status-without-content">no content</span>
|
<span v-if="status.content" class="status-content" v-html="status.content"/>
|
||||||
</div>
|
<span v-else class="status-without-content">no content</span>
|
||||||
<a v-if="status.created_at" :href="status.url" target="_blank" class="account">
|
</div>
|
||||||
{{ parseTimestamp(status.created_at) }}
|
<div class="status-footer">
|
||||||
|
<span v-if="status.created_at" class="status-created-at">{{ parseTimestamp(status.created_at) }}</span>
|
||||||
|
<a v-if="status.url" :href="status.url" target="_blank" class="account" @click.stop>
|
||||||
|
Open status in instance
|
||||||
|
<i class="el-icon-top-right"/>
|
||||||
</a>
|
</a>
|
||||||
</el-card>
|
</div>
|
||||||
</div>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -121,6 +140,11 @@ import moment from 'moment'
|
||||||
export default {
|
export default {
|
||||||
name: 'Status',
|
name: 'Status',
|
||||||
props: {
|
props: {
|
||||||
|
account: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
default: () => { return {} }
|
||||||
|
},
|
||||||
fetchStatusesByInstance: {
|
fetchStatusesByInstance: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -158,6 +182,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
capitalizeFirstLetter(str) {
|
capitalizeFirstLetter(str) {
|
||||||
|
if (!str) return ''
|
||||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
},
|
},
|
||||||
changeStatus(statusId, isSensitive, visibility) {
|
changeStatus(statusId, isSensitive, visibility) {
|
||||||
|
@ -195,6 +220,12 @@ export default {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleStatusSelection(account) {
|
||||||
|
this.$emit('status-selection', account)
|
||||||
|
},
|
||||||
|
handleRouteChange() {
|
||||||
|
this.$router.push({ name: 'StatusShow', params: { id: this.status.id }})
|
||||||
|
},
|
||||||
optionPercent(poll, pollOption) {
|
optionPercent(poll, pollOption) {
|
||||||
const allVotes = poll.options.reduce((acc, option) => (acc + option.votes_count), 0)
|
const allVotes = poll.options.reduce((acc, option) => (acc + option.votes_count), 0)
|
||||||
if (allVotes === 0) {
|
if (allVotes === 0) {
|
||||||
|
@ -205,8 +236,11 @@ export default {
|
||||||
parseTimestamp(timestamp) {
|
parseTimestamp(timestamp) {
|
||||||
return moment(timestamp).format('YYYY-MM-DD HH:mm')
|
return moment(timestamp).format('YYYY-MM-DD HH:mm')
|
||||||
},
|
},
|
||||||
handleStatusSelection(account) {
|
propertyExists(account, property, _secondProperty) {
|
||||||
this.$emit('status-selection', account)
|
if (_secondProperty) {
|
||||||
|
return account[property] && account[_secondProperty]
|
||||||
|
}
|
||||||
|
return account[property]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,10 +249,19 @@ export default {
|
||||||
<style rel='stylesheet/scss' lang='scss'>
|
<style rel='stylesheet/scss' lang='scss'>
|
||||||
.status-card {
|
.status-card {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
cursor: pointer;
|
||||||
.account {
|
.account {
|
||||||
text-decoration: underline;
|
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
.account:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.deactivated {
|
||||||
|
color: gray;
|
||||||
|
line-height: 28px;
|
||||||
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
.image {
|
.image {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
|
@ -226,6 +269,9 @@ export default {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.router-link {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
.show-more-button {
|
.show-more-button {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
@ -242,12 +288,17 @@ export default {
|
||||||
.status-account-name {
|
.status-account-name {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 22px;
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
.status-body {
|
.status-body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
.status-card-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
.status-checkbox {
|
.status-checkbox {
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
}
|
}
|
||||||
|
@ -255,13 +306,26 @@ export default {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
}
|
}
|
||||||
|
.status-created-at {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
.status-deleted {
|
.status-deleted {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
}
|
}
|
||||||
|
.status-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
.status-header {
|
.status-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.status-tags {
|
||||||
|
display: inline;
|
||||||
}
|
}
|
||||||
.status-without-content {
|
.status-without-content {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
@ -280,7 +344,7 @@ export default {
|
||||||
padding: 10px 17px;
|
padding: 10px 17px;
|
||||||
}
|
}
|
||||||
.el-tag {
|
.el-tag {
|
||||||
margin: 3px 4px 3px 0;
|
margin: 3px 0;
|
||||||
}
|
}
|
||||||
.status-account-container {
|
.status-account-container {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
|
@ -289,12 +353,20 @@ export default {
|
||||||
margin: 3px 0 3px;
|
margin: 3px 0 3px;
|
||||||
}
|
}
|
||||||
.status-actions {
|
.status-actions {
|
||||||
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.status-footer {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
.status-header {
|
.status-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
src/icons/svg/tiptap-add_col_after.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M5,14 C7.76005315,14.0033061 9.99669388,16.2399468 10,19 C10,21.7614237 7.76142375,24 5,24 C2.23857625,24 1.77635684e-15,21.7614237 1.77635684e-15,19 C1.77635684e-15,16.2385763 2.23857625,14 5,14 Z M7.5,19.9375 C8.01776695,19.9375 8.4375,19.517767 8.4375,19 C8.4375,18.482233 8.01776695,18.0625 7.5,18.0625 L6.25,18.0625 C6.07741102,18.0625 5.9375,17.922589 5.9375,17.75 L5.9375,16.5 C5.9375,15.982233 5.51776695,15.5625 5,15.5625 C4.48223305,15.5625 4.0625,15.982233 4.0625,16.5 L4.0625,17.75 C4.0625,17.922589 3.92258898,18.0625 3.75,18.0625 L2.5,18.0625 C1.98223305,18.0625 1.5625,18.482233 1.5625,19 C1.5625,19.517767 1.98223305,19.9375 2.5,19.9375 L3.75,19.9375 C3.92258898,19.9375 4.0625,20.077411 4.0625,20.25 L4.0625,21.5 C4.0625,22.017767 4.48223305,22.4375 5,22.4375 C5.51776695,22.4375 5.9375,22.017767 5.9375,21.5 L5.9375,20.25 C5.9375,20.077411 6.07741102,19.9375 6.25,19.9375 L7.5,19.9375 Z M16,19 C16,20.6568542 17.3431458,22 19,22 C20.6568542,22 22,20.6568542 22,19 L22,5 C22,3.34314575 20.6568542,2 19,2 C17.3431458,2 16,3.34314575 16,5 L16,19 Z M14,19 L14,5 C14,2.23857625 16.2385763,0 19,0 C21.7614237,0 24,2.23857625 24,5 L24,19 C24,21.7614237 21.7614237,24 19,24 C16.2385763,24 14,21.7614237 14,19 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
3
src/icons/svg/tiptap-add_col_before.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M19,14 C21.7600532,14.0033061 23.9966939,16.2399468 24,19 C24,21.7614237 21.7614237,24 19,24 C16.2385763,24 14,21.7614237 14,19 C14,16.2385763 16.2385763,14 19,14 Z M21.5,19.9375 C22.017767,19.9375 22.4375,19.517767 22.4375,19 C22.4375,18.482233 22.017767,18.0625 21.5,18.0625 L20.25,18.0625 C20.077411,18.0625 19.9375,17.922589 19.9375,17.75 L19.9375,16.5 C19.9375,15.982233 19.517767,15.5625 19,15.5625 C18.482233,15.5625 18.0625,15.982233 18.0625,16.5 L18.0625,17.75 C18.0625,17.922589 17.922589,18.0625 17.75,18.0625 L16.5,18.0625 C15.982233,18.0625 15.5625,18.482233 15.5625,19 C15.5625,19.517767 15.982233,19.9375 16.5,19.9375 L17.75,19.9375 C17.922589,19.9375 18.0625,20.077411 18.0625,20.25 L18.0625,21.5 C18.0625,22.017767 18.482233,22.4375 19,22.4375 C19.517767,22.4375 19.9375,22.017767 19.9375,21.5 L19.9375,20.25 C19.9375,20.077411 20.077411,19.9375 20.25,19.9375 L21.5,19.9375 Z M2,19 C2,20.6568542 3.34314575,22 5,22 C6.65685425,22 8,20.6568542 8,19 L8,5 C8,3.34314575 6.65685425,2 5,2 C3.34314575,2 2,3.34314575 2,5 L2,19 Z M-2.7585502e-16,19 L5.81397739e-16,5 C-1.37692243e-16,2.23857625 2.23857625,0 5,0 C7.76142375,0 10,2.23857625 10,5 L10,19 C10,21.7614237 7.76142375,24 5,24 C2.23857625,24 4.43234962e-16,21.7614237 -2.7585502e-16,19 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
3
src/icons/svg/tiptap-add_row_after.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M19,0 C21.7600532,0.00330611633 23.9966939,2.23994685 24,5 C24,7.76142375 21.7614237,10 19,10 C16.2385763,10 14,7.76142375 14,5 C14,2.23857625 16.2385763,0 19,0 Z M21.5,5.9375 C22.017767,5.9375 22.4375,5.51776695 22.4375,5 C22.4375,4.48223305 22.017767,4.0625 21.5,4.0625 L20.25,4.0625 C20.077411,4.0625 19.9375,3.92258898 19.9375,3.75 L19.9375,2.5 C19.9375,1.98223305 19.517767,1.5625 19,1.5625 C18.482233,1.5625 18.0625,1.98223305 18.0625,2.5 L18.0625,3.75 C18.0625,3.92258898 17.922589,4.0625 17.75,4.0625 L16.5,4.0625 C15.982233,4.0625 15.5625,4.48223305 15.5625,5 C15.5625,5.51776695 15.982233,5.9375 16.5,5.9375 L17.75,5.9375 C17.922589,5.9375 18.0625,6.07741102 18.0625,6.25 L18.0625,7.5 C18.0625,8.01776695 18.482233,8.4375 19,8.4375 C19.517767,8.4375 19.9375,8.01776695 19.9375,7.5 L19.9375,6.25 C19.9375,6.07741102 20.077411,5.9375 20.25,5.9375 L21.5,5.9375 Z M5,16 C3.34314575,16 2,17.3431458 2,19 C2,20.6568542 3.34314575,22 5,22 L19,22 C20.6568542,22 22,20.6568542 22,19 C22,17.3431458 20.6568542,16 19,16 L5,16 Z M5,14 L19,14 C21.7614237,14 24,16.2385763 24,19 C24,21.7614237 21.7614237,24 19,24 L5,24 C2.23857625,24 3.38176876e-16,21.7614237 0,19 C-1.2263553e-15,16.2385763 2.23857625,14 5,14 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
3
src/icons/svg/tiptap-add_row_before.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M19,14 C21.7600532,14.0033061 23.9966939,16.2399468 24,19 C24,21.7614237 21.7614237,24 19,24 C16.2385763,24 14,21.7614237 14,19 C14,16.2385763 16.2385763,14 19,14 Z M21.5,19.9375 C22.017767,19.9375 22.4375,19.517767 22.4375,19 C22.4375,18.482233 22.017767,18.0625 21.5,18.0625 L20.25,18.0625 C20.077411,18.0625 19.9375,17.922589 19.9375,17.75 L19.9375,16.5 C19.9375,15.982233 19.517767,15.5625 19,15.5625 C18.482233,15.5625 18.0625,15.982233 18.0625,16.5 L18.0625,17.75 C18.0625,17.922589 17.922589,18.0625 17.75,18.0625 L16.5,18.0625 C15.982233,18.0625 15.5625,18.482233 15.5625,19 C15.5625,19.517767 15.982233,19.9375 16.5,19.9375 L17.75,19.9375 C17.922589,19.9375 18.0625,20.077411 18.0625,20.25 L18.0625,21.5 C18.0625,22.017767 18.482233,22.4375 19,22.4375 C19.517767,22.4375 19.9375,22.017767 19.9375,21.5 L19.9375,20.25 C19.9375,20.077411 20.077411,19.9375 20.25,19.9375 L21.5,19.9375 Z M5,2 C3.34314575,2 2,3.34314575 2,5 C2,6.65685425 3.34314575,8 5,8 L19,8 C20.6568542,8 22,6.65685425 22,5 C22,3.34314575 20.6568542,2 19,2 L5,2 Z M5,0 L19,0 C21.7614237,-5.07265313e-16 24,2.23857625 24,5 C24,7.76142375 21.7614237,10 19,10 L5,10 C2.23857625,10 3.38176876e-16,7.76142375 0,5 C-1.2263553e-15,2.23857625 2.23857625,5.07265313e-16 5,0 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/icons/svg/tiptap-bold.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>text-bold</title><path d="M17.194,10.962A6.271,6.271,0,0,0,12.844.248H4.3a1.25,1.25,0,0,0,0,2.5H5.313a.25.25,0,0,1,.25.25V21a.25.25,0,0,1-.25.25H4.3a1.25,1.25,0,1,0,0,2.5h9.963a6.742,6.742,0,0,0,2.93-12.786Zm-4.35-8.214a3.762,3.762,0,0,1,0,7.523H8.313a.25.25,0,0,1-.25-.25V3a.25.25,0,0,1,.25-.25Zm1.42,18.5H8.313a.25.25,0,0,1-.25-.25V13.021a.25.25,0,0,1,.25-.25h4.531c.017,0,.033,0,.049,0l.013,0h1.358a4.239,4.239,0,0,1,0,8.477Z"/></svg>
|
After Width: | Height: | Size: 505 B |
1
src/icons/svg/tiptap-checklist.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>checklist-alternate</title><path d="M21,0H3A3,3,0,0,0,0,3V21a3,3,0,0,0,3,3H21a3,3,0,0,0,3-3V3A3,3,0,0,0,21,0Zm1,21a1,1,0,0,1-1,1H3a1,1,0,0,1-1-1V3A1,1,0,0,1,3,2H21a1,1,0,0,1,1,1Z"/><path d="M11.249,4.5a1.251,1.251,0,0,0-1.75.25L7.365,7.6l-.482-.481A1.25,1.25,0,0,0,5.116,8.883l1.5,1.5A1.262,1.262,0,0,0,8.5,10.249l3-4A1.25,1.25,0,0,0,11.249,4.5Z"/><path d="M11.249,13.5a1.251,1.251,0,0,0-1.75.25L7.365,16.6l-.482-.481a1.25,1.25,0,1,0-1.767,1.768l1.5,1.5A1.265,1.265,0,0,0,8.5,19.249l3-4A1.25,1.25,0,0,0,11.249,13.5Z"/><path d="M18.5,7.749H14a1.25,1.25,0,0,0,0,2.5h4.5a1.25,1.25,0,0,0,0-2.5Z"/><path d="M18.5,15.749H14a1.25,1.25,0,0,0,0,2.5h4.5a1.25,1.25,0,1,0,0-2.5Z"/></svg>
|
After Width: | Height: | Size: 743 B |
1
src/icons/svg/tiptap-code.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>angle-brackets</title><path d="M9.147,21.552a1.244,1.244,0,0,1-.895-.378L.84,13.561a2.257,2.257,0,0,1,0-3.125L8.252,2.823a1.25,1.25,0,0,1,1.791,1.744l-6.9,7.083a.5.5,0,0,0,0,.7l6.9,7.082a1.25,1.25,0,0,1-.9,2.122Z"/><path d="M14.854,21.552a1.25,1.25,0,0,1-.9-2.122l6.9-7.083a.5.5,0,0,0,0-.7l-6.9-7.082a1.25,1.25,0,0,1,1.791-1.744l7.411,7.612a2.257,2.257,0,0,1,0,3.125l-7.412,7.614A1.244,1.244,0,0,1,14.854,21.552Zm6.514-9.373h0Z"/></svg>
|
After Width: | Height: | Size: 504 B |
3
src/icons/svg/tiptap-combine_cells.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M2,19 C2,20.6568542 3.34314575,22 5,22 L19,22 C20.6568542,22 22,20.6568542 22,19 L22,5 C22,3.34314575 20.6568542,2 19,2 L5,2 C3.34314575,2 2,3.34314575 2,5 L2,19 Z M-1.16403344e-15,19 L-3.0678068e-16,5 C-6.44957556e-16,2.23857625 2.23857625,0 5,0 L19,0 C21.7614237,0 24,2.23857625 24,5 L24,19 C24,21.7614237 21.7614237,24 19,24 L5,24 C2.23857625,24 9.50500275e-16,21.7614237 -1.16403344e-15,19 Z M12,10 C12.5522847,10 13,10.4477153 13,11 L13,13 C13,13.5522847 12.5522847,14 12,14 C11.4477153,14 11,13.5522847 11,13 L11,11 C11,10.4477153 11.4477153,10 12,10 Z M12,16 C12.5522847,16 13,16.4477153 13,17 L13,20 C13,20.5522847 12.5522847,21 12,21 C11.4477153,21 11,20.5522847 11,20 L11,17 C11,16.4477153 11.4477153,16 12,16 Z M12,3 C12.5522847,3 13,3.44771525 13,4 L13,7 C13,7.55228475 12.5522847,8 12,8 C11.4477153,8 11,7.55228475 11,7 L11,4 C11,3.44771525 11.4477153,3 12,3 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 979 B |
3
src/icons/svg/tiptap-delete_col.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M12.6414391,21.9312708 C12.9358807,22.5689168 13.3234155,23.1547532 13.7866134,23.6713497 C13.2317936,23.8836754 12.6294813,24 12,24 C9.23857625,24 7,21.7614237 7,19 L7,5 C7,2.23857625 9.23857625,0 12,0 C14.7614237,0 17,2.23857625 17,5 L17,12.2898787 C16.2775651,12.5048858 15.6040072,12.8333806 15,13.2546893 L15,5 C15,3.34314575 13.6568542,2 12,2 C10.3431458,2 9,3.34314575 9,5 L9,19 C9,20.6568542 10.3431458,22 12,22 C12.220157,22 12.4347751,21.9762852 12.6414391,21.9312708 Z M19,14 C21.7600532,14.0033061 23.9966939,16.2399468 24,19 C24,21.7614237 21.7614237,24 19,24 C16.2385763,24 14,21.7614237 14,19 C14,16.2385763 16.2385763,14 19,14 Z M16.5,19.9375 L21.5,19.9375 C22.017767,19.9375 22.4375,19.517767 22.4375,19 C22.4375,18.482233 22.017767,18.0625 21.5,18.0625 L16.5,18.0625 C15.982233,18.0625 15.5625,18.482233 15.5625,19 C15.5625,19.517767 15.982233,19.9375 16.5,19.9375 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 990 B |
3
src/icons/svg/tiptap-delete_row.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M13.2546893,15 C12.8333806,15.6040072 12.5048858,16.2775651 12.2898787,17 L5,17 C2.23857625,17 3.38176876e-16,14.7614237 0,12 C-1.2263553e-15,9.23857625 2.23857625,7 5,7 L19,7 C21.7614237,7 24,9.23857625 24,12 C24,12.6294813 23.8836754,13.2317936 23.6713497,13.7866134 C23.1547532,13.3234155 22.5689168,12.9358807 21.9312708,12.6414391 C21.9762852,12.4347751 22,12.220157 22,12 C22,10.3431458 20.6568542,9 19,9 L5,9 C3.34314575,9 2,10.3431458 2,12 C2,13.6568542 3.34314575,15 5,15 L13.2546893,15 Z M19,14 C21.7600532,14.0033061 23.9966939,16.2399468 24,19 C24,21.7614237 21.7614237,24 19,24 C16.2385763,24 14,21.7614237 14,19 C14,16.2385763 16.2385763,14 19,14 Z M16.5,19.9375 L21.5,19.9375 C22.017767,19.9375 22.4375,19.517767 22.4375,19 C22.4375,18.482233 22.017767,18.0625 21.5,18.0625 L16.5,18.0625 C15.982233,18.0625 15.5625,18.482233 15.5625,19 C15.5625,19.517767 15.982233,19.9375 16.5,19.9375 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1,008 B |
3
src/icons/svg/tiptap-delete_table.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M19,14 C21.7600532,14.0033061 23.9966939,16.2399468 24,19 C24,21.7614237 21.7614237,24 19,24 C16.2385763,24 14,21.7614237 14,19 C14,16.2385763 16.2385763,14 19,14 Z M16.5,19.9375 L21.5,19.9375 C22.017767,19.9375 22.4375,19.517767 22.4375,19 C22.4375,18.482233 22.017767,18.0625 21.5,18.0625 L16.5,18.0625 C15.982233,18.0625 15.5625,18.482233 15.5625,19 C15.5625,19.517767 15.982233,19.9375 16.5,19.9375 Z M12.2898787,17 L9,17 L9,22 L12.6736312,22 C13.0297295,22.7496048 13.515133,23.4258795 14.1010173,24 L5,24 C2.23857625,24 -1.43817996e-15,21.7614237 -1.77635684e-15,19 L-3.55271368e-15,5 C-3.89089055e-15,2.23857625 2.23857625,5.07265313e-16 5,-1.77635684e-15 L19,-1.77635684e-15 C21.7614237,-2.28362215e-15 24,2.23857625 24,5 L24,7.82313285 C24.0122947,7.88054124 24.0187107,7.93964623 24.0187107,8 C24.0187107,8.06035377 24.0122947,8.11945876 24,8.17686715 L24,14.1010173 C23.4258795,13.515133 22.7496048,13.0297295 22,12.6736312 L22,9 L17,9 L17,12.2898787 C16.2775651,12.5048858 15.6040072,12.8333806 15,13.2546893 L15,9 L9,9 L9,15 L13.2546893,15 C12.8333806,15.6040072 12.5048858,16.2775651 12.2898787,17 Z M17,7 L22,7 L22,5 C22,3.34314575 20.6568542,2 19,2 L17,2 L17,7 Z M15,7 L15,2 L9,2 L9,7 L15,7 Z M7,2 L5,2 C3.34314575,2 2,3.34314575 2,5 L2,7 L7,7 L7,2 Z M2,9 L2,15 L7,15 L7,9 L2,9 Z M2,17 L2,19 C2,20.6568542 3.34314575,22 5,22 L7,22 L7,17 L2,17 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
3
src/icons/svg/tiptap-github.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M11.999,0.5 C5.649,0.5 0.5,5.648 0.5,12 C0.5,17.082 3.794,21.392 8.365,22.914 C8.939,23.017 9.121,22.678 9.121,22.373 C9.121,22.099 9.127,21.336 9.121,20.376 C5.923,21.07 5.26,18.861 5.26,18.861 C4.737,17.532 3.985,17.179 3.985,17.179 C2.94,16.465 4.062,16.48 4.062,16.48 C5.215,16.56 5.824,17.664 5.824,17.664 C6.85,19.422 8.515,18.914 9.17,18.62 C9.276,17.878 9.572,17.369 9.901,17.084 C7.347,16.792 4.663,15.807 4.663,11.398 C4.663,10.143 5.111,9.117 5.847,8.312 C5.729,8.023 5.333,6.852 5.959,5.269 C5.959,5.269 6.926,4.96 9.121,6.449 C10.039,6.193 11.023,6.066 12.001,6.061 C12.977,6.066 13.961,6.193 14.881,6.449 C17.076,4.961 18.04,5.269 18.04,5.269 C18.667,6.852 18.272,8.023 18.154,8.312 C18.89,9.117 19.337,10.143 19.337,11.398 C19.337,15.818 16.648,16.789 14.086,17.072 C14.498,17.429 14.873,18.119 14.873,19.192 C14.873,20.63 14.873,21.998 14.873,22.376 C14.873,22.684 15.059,23.023 15.643,22.912 C20.209,21.389 23.5,17.08 23.5,12 C23.5,5.648 18.352,0.5 11.999,0.5 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
3
src/icons/svg/tiptap-hr.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M5,13 C4.44771525,13 4,12.5522847 4,12 C4,11.4477153 4.44771525,11 5,11 L19,11 C19.5522847,11 20,11.4477153 20,12 C20,12.5522847 19.5522847,13 19,13 L5,13 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 262 B |
1
src/icons/svg/tiptap-image.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>paginate-filter-picture-alternate</title><circle cx="9.75" cy="6.247" r="2.25"/><path d="M16.916,8.71A1.027,1.027,0,0,0,16,8.158a1.007,1.007,0,0,0-.892.586L13.55,12.178a.249.249,0,0,1-.422.053l-.82-1.024a1,1,0,0,0-.813-.376,1.007,1.007,0,0,0-.787.426L7.59,15.71A.5.5,0,0,0,8,16.5H20a.5.5,0,0,0,.425-.237.5.5,0,0,0,.022-.486Z"/><path d="M22,0H5.5a2,2,0,0,0-2,2V18.5a2,2,0,0,0,2,2H22a2,2,0,0,0,2-2V2A2,2,0,0,0,22,0Zm-.145,18.354a.5.5,0,0,1-.354.146H6a.5.5,0,0,1-.5-.5V2.5A.5.5,0,0,1,6,2H21.5a.5.5,0,0,1,.5.5V18A.5.5,0,0,1,21.855,18.351Z"/><path d="M19.5,22H2.5a.5.5,0,0,1-.5-.5V4.5a1,1,0,0,0-2,0V22a2,2,0,0,0,2,2H19.5a1,1,0,0,0,0-2Z"/></svg>
|
After Width: | Height: | Size: 707 B |
1
src/icons/svg/tiptap-italic.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>text-italic</title><path d="M22.5.248H14.863a1.25,1.25,0,0,0,0,2.5h1.086a.25.25,0,0,1,.211.384L4.78,21.017a.5.5,0,0,1-.422.231H1.5a1.25,1.25,0,0,0,0,2.5H9.137a1.25,1.25,0,0,0,0-2.5H8.051a.25.25,0,0,1-.211-.384L19.22,2.98a.5.5,0,0,1,.422-.232H22.5a1.25,1.25,0,0,0,0-2.5Z"/></svg>
|
After Width: | Height: | Size: 346 B |
1
src/icons/svg/tiptap-link.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>hyperlink-2</title><path d="M12.406,14.905a1,1,0,0,0-.543,1.307,1,1,0,0,1-.217,1.09L8.818,20.131a2,2,0,0,1-2.828,0L3.868,18.01a2,2,0,0,1,0-2.829L6.7,12.353a1.013,1.013,0,0,1,1.091-.217,1,1,0,0,0,.763-1.849,3.034,3.034,0,0,0-3.268.652L2.454,13.767a4.006,4.006,0,0,0,0,5.657l2.122,2.121a4,4,0,0,0,5.656,0l2.829-2.828a3.008,3.008,0,0,0,.651-3.27A1,1,0,0,0,12.406,14.905Z"/><path d="M7.757,16.241a1.011,1.011,0,0,0,1.414,0L16.95,8.463a1,1,0,0,0-1.414-1.414L7.757,14.827A1,1,0,0,0,7.757,16.241Z"/><path d="M21.546,4.574,19.425,2.453a4.006,4.006,0,0,0-5.657,0L10.939,5.281a3.006,3.006,0,0,0-.651,3.269,1,1,0,1,0,1.849-.764A1,1,0,0,1,12.354,6.7l2.828-2.828a2,2,0,0,1,2.829,0l2.121,2.121a2,2,0,0,1,0,2.829L17.3,11.645a1.015,1.015,0,0,1-1.091.217,1,1,0,0,0-.765,1.849,3.026,3.026,0,0,0,3.27-.651l2.828-2.828A4.007,4.007,0,0,0,21.546,4.574Z"/></svg>
|
After Width: | Height: | Size: 907 B |
1
src/icons/svg/tiptap-mention.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>read-email-at-alternate</title><path d="M12,.5A11.634,11.634,0,0,0,.262,12,11.634,11.634,0,0,0,12,23.5a11.836,11.836,0,0,0,6.624-2,1.25,1.25,0,1,0-1.393-2.076A9.34,9.34,0,0,1,12,21a9.132,9.132,0,0,1-9.238-9A9.132,9.132,0,0,1,12,3a9.132,9.132,0,0,1,9.238,9v.891a1.943,1.943,0,0,1-3.884,0V12A5.355,5.355,0,1,0,12,17.261a5.376,5.376,0,0,0,3.861-1.634,4.438,4.438,0,0,0,7.877-2.736V12A11.634,11.634,0,0,0,12,.5Zm0,14.261A2.763,2.763,0,1,1,14.854,12,2.812,2.812,0,0,1,12,14.761Z"/></svg>
|
After Width: | Height: | Size: 549 B |
1
src/icons/svg/tiptap-ol.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>list-numbers</title><path d="M7.75,4.5h15a1,1,0,0,0,0-2h-15a1,1,0,0,0,0,2Z"/><path d="M22.75,11h-15a1,1,0,1,0,0,2h15a1,1,0,0,0,0-2Z"/><path d="M22.75,19.5h-15a1,1,0,0,0,0,2h15a1,1,0,0,0,0-2Z"/><path d="M2.212,17.248A2,2,0,0,0,.279,18.732a.75.75,0,1,0,1.45.386.5.5,0,1,1,.483.63.75.75,0,1,0,0,1.5.5.5,0,1,1-.482.635.75.75,0,1,0-1.445.4,2,2,0,1,0,3.589-1.648.251.251,0,0,1,0-.278,2,2,0,0,0-1.662-3.111Z"/><path d="M4.25,10.748a2,2,0,0,0-4,0,.75.75,0,0,0,1.5,0,.5.5,0,0,1,1,0,1.031,1.031,0,0,1-.227.645L.414,14.029A.75.75,0,0,0,1,15.248H3.5a.75.75,0,0,0,0-1.5H3.081a.249.249,0,0,1-.195-.406L3.7,12.33A2.544,2.544,0,0,0,4.25,10.748Z"/><path d="M4,5.248H3.75A.25.25,0,0,1,3.5,5V1.623A1.377,1.377,0,0,0,2.125.248H1.5a.75.75,0,0,0,0,1.5h.25A.25.25,0,0,1,2,2V5a.25.25,0,0,1-.25.25H1.5a.75.75,0,0,0,0,1.5H4a.75.75,0,0,0,0-1.5Z"/></svg>
|
After Width: | Height: | Size: 894 B |
1
src/icons/svg/tiptap-paragraph.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>paragraph</title><path d="M22.5.248H7.228a6.977,6.977,0,1,0,0,13.954H9.546a.25.25,0,0,1,.25.25V22.5a1.25,1.25,0,0,0,2.5,0V3a.25.25,0,0,1,.25-.25h3.682a.25.25,0,0,1,.25.25V22.5a1.25,1.25,0,0,0,2.5,0V3a.249.249,0,0,1,.25-.25H22.5a1.25,1.25,0,0,0,0-2.5ZM9.8,11.452a.25.25,0,0,1-.25.25H7.228a4.477,4.477,0,1,1,0-8.954H9.546A.25.25,0,0,1,9.8,3Z"/></svg>
|
After Width: | Height: | Size: 416 B |
1
src/icons/svg/tiptap-quote.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>close-quote</title><path d="M18.559,3.932a4.942,4.942,0,1,0,0,9.883,4.609,4.609,0,0,0,1.115-.141.25.25,0,0,1,.276.368,6.83,6.83,0,0,1-5.878,3.523,1.25,1.25,0,0,0,0,2.5,9.71,9.71,0,0,0,9.428-9.95V8.873A4.947,4.947,0,0,0,18.559,3.932Z"/><path d="M6.236,3.932a4.942,4.942,0,0,0,0,9.883,4.6,4.6,0,0,0,1.115-.141.25.25,0,0,1,.277.368A6.83,6.83,0,0,1,1.75,17.565a1.25,1.25,0,0,0,0,2.5,9.711,9.711,0,0,0,9.428-9.95V8.873A4.947,4.947,0,0,0,6.236,3.932Z"/></svg>
|
After Width: | Height: | Size: 521 B |
1
src/icons/svg/tiptap-redo.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>redo</title><path d="M22.608.161a.5.5,0,0,0-.545.108L19.472,2.86a.25.25,0,0,1-.292.045A12.537,12.537,0,0,0,6.214,3.77,12.259,12.259,0,0,0,6.1,23.632a1.25,1.25,0,0,0,1.476-2.018A9.759,9.759,0,0,1,7.667,5.805a10,10,0,0,1,9.466-1.1.25.25,0,0,1,.084.409l-1.85,1.85a.5.5,0,0,0,.354.853h6.7a.5.5,0,0,0,.5-.5V.623A.5.5,0,0,0,22.608.161Z"/></svg>
|
After Width: | Height: | Size: 406 B |
1
src/icons/svg/tiptap-remove.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>delete-2-alternate</title><path d="M20.485,3.511A12.01,12.01,0,1,0,24,12,12.009,12.009,0,0,0,20.485,3.511Zm-1.767,15.21A9.51,9.51,0,1,1,21.5,12,9.508,9.508,0,0,1,18.718,18.721Z"/><path d="M16.987,7.01a1.275,1.275,0,0,0-1.8,0l-3.177,3.177L8.829,7.01A1.277,1.277,0,0,0,7.024,8.816L10.2,11.993,7.024,15.171a1.277,1.277,0,0,0,1.805,1.806L12.005,13.8l3.177,3.178a1.277,1.277,0,0,0,1.8-1.806l-3.176-3.178,3.176-3.177A1.278,1.278,0,0,0,16.987,7.01Z"/></svg>
|
After Width: | Height: | Size: 518 B |
1
src/icons/svg/tiptap-strike.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>text-strike-through</title><path d="M23.75,12.952A1.25,1.25,0,0,0,22.5,11.7H13.564a.492.492,0,0,1-.282-.09c-.722-.513-1.482-.981-2.218-1.432-2.8-1.715-4.5-2.9-4.5-4.863,0-2.235,2.207-2.569,3.523-2.569a4.54,4.54,0,0,1,3.081.764A2.662,2.662,0,0,1,13.615,5.5l0,.3a1.25,1.25,0,1,0,2.5,0l0-.268A4.887,4.887,0,0,0,14.95,1.755C13.949.741,12.359.248,10.091.248c-3.658,0-6.023,1.989-6.023,5.069,0,2.773,1.892,4.512,4,5.927a.25.25,0,0,1-.139.458H1.5a1.25,1.25,0,0,0,0,2.5H12.477a.251.251,0,0,1,.159.058,4.339,4.339,0,0,1,1.932,3.466c0,3.268-3.426,3.522-4.477,3.522-1.814,0-3.139-.405-3.834-1.173a3.394,3.394,0,0,1-.65-2.7,1.25,1.25,0,0,0-2.488-.246A5.76,5.76,0,0,0,4.4,21.753c1.2,1.324,3.114,2,5.688,2,4.174,0,6.977-2.42,6.977-6.022a6.059,6.059,0,0,0-.849-3.147.25.25,0,0,1,.216-.377H22.5A1.25,1.25,0,0,0,23.75,12.952Z"/></svg>
|
After Width: | Height: | Size: 885 B |
3
src/icons/svg/tiptap-table.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path fill-rule="evenodd" d="M17,17 L17,22 L19,22 C20.6568542,22 22,20.6568542 22,19 L22,17 L17,17 Z M15,17 L9,17 L9,22 L15,22 L15,17 Z M17,15 L22,15 L22,9 L17,9 L17,15 Z M15,15 L15,9 L9,9 L9,15 L15,15 Z M17,7 L22,7 L22,5 C22,3.34314575 20.6568542,2 19,2 L17,2 L17,7 Z M15,7 L15,2 L9,2 L9,7 L15,7 Z M24,16.1768671 L24,19 C24,21.7614237 21.7614237,24 19,24 L5,24 C2.23857625,24 2.11453371e-15,21.7614237 1.77635684e-15,19 L0,5 C-3.38176876e-16,2.23857625 2.23857625,2.28362215e-15 5,0 L19,0 C21.7614237,-5.07265313e-16 24,2.23857625 24,5 L24,7.82313285 C24.0122947,7.88054124 24.0187107,7.93964623 24.0187107,8 C24.0187107,8.06035377 24.0122947,8.11945876 24,8.17686715 L24,15.8231329 C24.0122947,15.8805412 24.0187107,15.9396462 24.0187107,16 C24.0187107,16.0603538 24.0122947,16.1194588 24,16.1768671 Z M7,2 L5,2 C3.34314575,2 2,3.34314575 2,5 L2,7 L7,7 L7,2 Z M2,9 L2,15 L7,15 L7,9 L2,9 Z M2,17 L2,19 C2,20.6568542 3.34314575,22 5,22 L7,22 L7,17 L2,17 Z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1 KiB |
1
src/icons/svg/tiptap-ul.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>list-bullets</title><circle cx="2.5" cy="3.998" r="2.5"/><path d="M8.5,5H23a1,1,0,0,0,0-2H8.5a1,1,0,0,0,0,2Z"/><circle cx="2.5" cy="11.998" r="2.5"/><path d="M23,11H8.5a1,1,0,0,0,0,2H23a1,1,0,0,0,0-2Z"/><circle cx="2.5" cy="19.998" r="2.5"/><path d="M23,19H8.5a1,1,0,0,0,0,2H23a1,1,0,0,0,0-2Z"/></svg>
|
After Width: | Height: | Size: 369 B |
1
src/icons/svg/tiptap-underline.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>text-underline</title><path d="M22.5,21.248H1.5a1.25,1.25,0,0,0,0,2.5h21a1.25,1.25,0,0,0,0-2.5Z"/><path d="M1.978,2.748H3.341a.25.25,0,0,1,.25.25v8.523a8.409,8.409,0,0,0,16.818,0V3a.25.25,0,0,1,.25-.25h1.363a1.25,1.25,0,0,0,0-2.5H16.3a1.25,1.25,0,0,0,0,2.5h1.363a.25.25,0,0,1,.25.25v8.523a5.909,5.909,0,0,1-11.818,0V3a.25.25,0,0,1,.25-.25H7.7a1.25,1.25,0,1,0,0-2.5H1.978a1.25,1.25,0,0,0,0,2.5Z"/></svg>
|
After Width: | Height: | Size: 470 B |
1
src/icons/svg/tiptap-undo.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>undo</title><path d="M17.786,3.77A12.542,12.542,0,0,0,4.821,2.905a.249.249,0,0,1-.292-.045L1.937.269A.507.507,0,0,0,1.392.16a.5.5,0,0,0-.308.462v6.7a.5.5,0,0,0,.5.5h6.7a.5.5,0,0,0,.354-.854L6.783,5.115a.253.253,0,0,1-.068-.228.249.249,0,0,1,.152-.181,10,10,0,0,1,9.466,1.1,9.759,9.759,0,0,1,.094,15.809A1.25,1.25,0,0,0,17.9,23.631a12.122,12.122,0,0,0,5.013-9.961A12.125,12.125,0,0,0,17.786,3.77Z"/></svg>
|
After Width: | Height: | Size: 472 B |
184
src/lang/en.js
|
@ -65,10 +65,24 @@ export default {
|
||||||
externalLink: 'External Link',
|
externalLink: 'External Link',
|
||||||
users: 'Users',
|
users: 'Users',
|
||||||
reports: 'Reports',
|
reports: 'Reports',
|
||||||
|
invites: 'Invites',
|
||||||
|
statuses: 'Statuses',
|
||||||
settings: 'Settings',
|
settings: 'Settings',
|
||||||
moderationLog: 'Moderation Log',
|
moderationLog: 'Moderation Log',
|
||||||
|
relays: 'Relays',
|
||||||
|
mediaProxyCache: 'MediaProxy Cache',
|
||||||
'emoji-packs': 'Emoji packs'
|
'emoji-packs': 'Emoji packs'
|
||||||
},
|
},
|
||||||
|
errLog: {
|
||||||
|
error401: 'Oops! 401 Error',
|
||||||
|
error404: 'Oops! 404 Error',
|
||||||
|
pageNotFound: 'Page not found',
|
||||||
|
correctUrl: 'Please make sure you URL is correct',
|
||||||
|
unauth: 'Unauthorized',
|
||||||
|
back: 'Back',
|
||||||
|
login: 'Login',
|
||||||
|
homePage: 'Home Page'
|
||||||
|
},
|
||||||
navbar: {
|
navbar: {
|
||||||
logOut: 'Log Out',
|
logOut: 'Log Out',
|
||||||
dashboard: 'Dashboard',
|
dashboard: 'Dashboard',
|
||||||
|
@ -82,13 +96,30 @@ export default {
|
||||||
logInViaPleromaFE: 'Log in via PleromaFE',
|
logInViaPleromaFE: 'Log in via PleromaFE',
|
||||||
username: 'username@host',
|
username: 'username@host',
|
||||||
password: 'password',
|
password: 'password',
|
||||||
omitHostname: 'omit hostname if Pleroma is located on this domain',
|
omitHostname: 'Omit hostname if Pleroma is located on this domain',
|
||||||
errorMessage: 'Username must contain username and host, e.g. john@pleroma.social',
|
errorMessage: 'Username must contain username and host, e.g. john@pleroma.social',
|
||||||
any: 'any',
|
any: 'any',
|
||||||
thirdparty: 'Or connect with',
|
thirdparty: 'Or connect with',
|
||||||
pleromaFELoginFailed: 'Failed to login via PleromaFE, please login with username/password',
|
pleromaFELoginFailed: 'Failed to login via PleromaFE, please login with username/password',
|
||||||
pleromaFELoginSucceed: 'Logged in via PleromaFE'
|
pleromaFELoginSucceed: 'Logged in via PleromaFE'
|
||||||
},
|
},
|
||||||
|
mediaProxyCache: {
|
||||||
|
mediaProxyCache: 'MediaProxy Cache',
|
||||||
|
ban: 'Ban',
|
||||||
|
url: 'URL',
|
||||||
|
evict: 'Evict',
|
||||||
|
evictedMessage: 'This URL was evicted',
|
||||||
|
actions: 'Actions',
|
||||||
|
remove: 'Remove from Cachex',
|
||||||
|
evictObjectsHeader: 'Evict object from the MediaProxy cache',
|
||||||
|
listBannedUrlsHeader: 'List of all banned MediaProxy URLs',
|
||||||
|
multipleInput: 'You can enter a single URL or several comma separated links',
|
||||||
|
removeSelected: 'Remove Selected',
|
||||||
|
enable: 'Enable',
|
||||||
|
invalidationAndMediaProxy: 'MediaProxy and Invalidation to evict and ban MediaProxy objects',
|
||||||
|
confirmEnablingMediaProxy: 'Are you sure you want to enable Media Proxy and Media Cache object Invalidation?',
|
||||||
|
enableMediaProxySuccessMessage: 'Media Proxy and Media Cache object Invalidation were enabled'
|
||||||
|
},
|
||||||
documentation: {
|
documentation: {
|
||||||
documentation: 'Documentation',
|
documentation: 'Documentation',
|
||||||
github: 'Github Repository'
|
github: 'Github Repository'
|
||||||
|
@ -134,12 +165,8 @@ export default {
|
||||||
draft: 'Draft',
|
draft: 'Draft',
|
||||||
delete: 'Delete',
|
delete: 'Delete',
|
||||||
cancel: 'Cancel',
|
cancel: 'Cancel',
|
||||||
confirm: 'Confirm'
|
confirm: 'Confirm',
|
||||||
},
|
unfollow: 'Unfollow'
|
||||||
errorLog: {
|
|
||||||
tips: 'Please click the bug icon in the upper right corner',
|
|
||||||
description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.',
|
|
||||||
documentation: 'Document introduction'
|
|
||||||
},
|
},
|
||||||
excel: {
|
excel: {
|
||||||
export: 'Export',
|
export: 'Export',
|
||||||
|
@ -171,16 +198,17 @@ export default {
|
||||||
id: 'ID',
|
id: 'ID',
|
||||||
name: 'Name',
|
name: 'Name',
|
||||||
status: 'Status',
|
status: 'Status',
|
||||||
local: 'local',
|
local: 'Local',
|
||||||
external: 'external',
|
external: 'External',
|
||||||
deactivated: 'deactivated',
|
deactivated: 'Deactivated',
|
||||||
active: 'active',
|
active: 'Active',
|
||||||
unconfirmed: 'unconfirmed',
|
unapproved: 'Pending',
|
||||||
|
unconfirmed: 'Unconfirmed',
|
||||||
actions: 'Actions',
|
actions: 'Actions',
|
||||||
activate: 'Activate',
|
activate: 'Activate',
|
||||||
deactivate: 'Deactivate',
|
deactivate: 'Deactivate',
|
||||||
admin: 'admin',
|
admin: 'Admin',
|
||||||
moderator: 'moderator',
|
moderator: 'Moderator',
|
||||||
moderation: 'Moderation',
|
moderation: 'Moderation',
|
||||||
revokeAdmin: 'Revoke Admin',
|
revokeAdmin: 'Revoke Admin',
|
||||||
grantAdmin: 'Grant Admin',
|
grantAdmin: 'Grant Admin',
|
||||||
|
@ -201,20 +229,25 @@ export default {
|
||||||
disableAnySubscription: 'Disallow following user at all',
|
disableAnySubscription: 'Disallow following user at all',
|
||||||
disableAnySubscriptionForMultiple: 'Disallow following users at all',
|
disableAnySubscriptionForMultiple: 'Disallow following users at all',
|
||||||
requirePasswordReset: 'Require password reset on next login',
|
requirePasswordReset: 'Require password reset on next login',
|
||||||
|
disableMfa: 'Disable multi-factor authentication',
|
||||||
selectUsers: 'Select users to apply actions to multiple users',
|
selectUsers: 'Select users to apply actions to multiple users',
|
||||||
moderateUser: 'Moderate user',
|
moderateUser: 'Moderate user',
|
||||||
moderateUsers: 'Moderate multiple users',
|
moderateUsers: 'Moderate multiple users',
|
||||||
createAccount: 'Create new account',
|
createAccount: 'Create new account',
|
||||||
apply: 'apply',
|
apply: 'Apply',
|
||||||
remove: 'remove',
|
remove: 'Remove',
|
||||||
grantRightConfirmation: 'Are you sure you want to grant {right} rights to all selected users?',
|
grantRightConfirmation: 'Are you sure you want to grant {right} rights to all selected users?',
|
||||||
revokeRightConfirmation: 'Are you sure you want to revoke {right} rights from all selected users?',
|
revokeRightConfirmation: 'Are you sure you want to revoke {right} rights from all selected users?',
|
||||||
activateMultipleUsersConfirmation: 'Are you sure you want to activate accounts of all selected users?',
|
activateMultipleUsersConfirmation: 'Are you sure you want to activate accounts of all selected users?',
|
||||||
deactivateMultipleUsersConfirmation: 'Are you sure you want to deactivate accounts of all selected users?',
|
deactivateMultipleUsersConfirmation: 'Are you sure you want to deactivate accounts of all selected users?',
|
||||||
deleteMultipleUsersConfirmation: 'Are you sure you want to delete accounts of all selected users?',
|
deleteUserConfirmation: 'Are you sure you want to delete this account? This action cannot be undone.',
|
||||||
|
rejectAccountConfirmation: 'Are you sure you want to reject this account? This account will be deleted and it cannot be undone.',
|
||||||
|
deleteMultipleUsersConfirmation: 'Are you sure you want to delete accounts of all selected users? This action cannot be undone.',
|
||||||
addTagForMultipleUsersConfirmation: 'Are you sure you want to apply tag to all selected users?',
|
addTagForMultipleUsersConfirmation: 'Are you sure you want to apply tag to all selected users?',
|
||||||
removeTagFromMultipleUsersConfirmation: 'Are you sure you want to remove tag from all selected users?',
|
removeTagFromMultipleUsersConfirmation: 'Are you sure you want to remove tag from all selected users?',
|
||||||
requirePasswordResetConfirmation: 'Are you sure you want to require password reset for all selected users?',
|
requirePasswordResetConfirmation: 'Are you sure you want to require password reset for all selected users?',
|
||||||
|
approveAccountsConfirmation: 'Are you sure you want to approve accounts for all selected users?',
|
||||||
|
rejectAccountsConfirmation: 'Are you sure you want to reject accounts for all selected users? These accounts will be deleted and it cannot be undone.',
|
||||||
confirmAccountsConfirmation: 'Are you sure you want to confirm emails for all selected users?',
|
confirmAccountsConfirmation: 'Are you sure you want to confirm emails for all selected users?',
|
||||||
resendEmailConfirmation: 'Are you sure you want to resend confirmation email for all selected users?',
|
resendEmailConfirmation: 'Are you sure you want to resend confirmation email for all selected users?',
|
||||||
mailerMustBeEnabled: 'To require user\'s password reset you must enable mailer.',
|
mailerMustBeEnabled: 'To require user\'s password reset you must enable mailer.',
|
||||||
|
@ -235,10 +268,25 @@ export default {
|
||||||
getPasswordResetToken: 'Get password reset token',
|
getPasswordResetToken: 'Get password reset token',
|
||||||
passwordResetTokenCreated: 'Password reset token was created',
|
passwordResetTokenCreated: 'Password reset token was created',
|
||||||
accountCreated: 'New account was created!',
|
accountCreated: 'New account was created!',
|
||||||
|
approveAccount: 'Approve account',
|
||||||
|
approveAccounts: 'Approve accounts',
|
||||||
|
unapprovedAccount: 'User account is pending approval',
|
||||||
unconfirmedEmail: 'User didn\'t confirm the email',
|
unconfirmedEmail: 'User didn\'t confirm the email',
|
||||||
confirmAccount: 'Confirm account',
|
confirmAccount: 'Confirm account',
|
||||||
confirmAccounts: 'Confirm accounts',
|
confirmAccounts: 'Confirm accounts',
|
||||||
resendConfirmation: 'Resend confirmation email'
|
rejectAccount: 'Reject account',
|
||||||
|
rejectAccounts: 'Reject accounts',
|
||||||
|
resendConfirmation: 'Resend confirmation email',
|
||||||
|
invalidAccount: 'This account has invalid nickname and can\'t be modified',
|
||||||
|
invalidNickname: 'invalid nickname',
|
||||||
|
passwordResetTokenGenerated: 'Password reset token was generated:',
|
||||||
|
linkToResetPassword: 'You can also use this link to reset password:',
|
||||||
|
registrationReason: 'Registration Reason',
|
||||||
|
service: 'Service',
|
||||||
|
person: 'Person',
|
||||||
|
enableTagPolicy: 'Enable MRF TagPolicy to manage user tags',
|
||||||
|
confirmEnablingTagPolicy: 'Are you sure you want to add TagPolicy to the list of enabled MRF policies?',
|
||||||
|
enableTagPolicySuccessMessage: 'MRF TagPolicy was enabled'
|
||||||
},
|
},
|
||||||
statuses: {
|
statuses: {
|
||||||
statuses: 'Statuses',
|
statuses: 'Statuses',
|
||||||
|
@ -250,22 +298,28 @@ export default {
|
||||||
direct: 'Direct',
|
direct: 'Direct',
|
||||||
private: 'Private',
|
private: 'Private',
|
||||||
public: 'Public',
|
public: 'Public',
|
||||||
unlisted: 'Unlisted'
|
unlisted: 'Unlisted',
|
||||||
|
openStatusInInstance: 'Open status in instance'
|
||||||
},
|
},
|
||||||
userProfile: {
|
userProfile: {
|
||||||
tags: 'Tags',
|
tags: 'Tags',
|
||||||
moderator: 'Moderator',
|
moderator: 'Moderator',
|
||||||
admin: 'Admin',
|
admin: 'Admin',
|
||||||
local: 'local',
|
local: 'Local',
|
||||||
external: 'external',
|
external: 'External',
|
||||||
localUppercase: 'Local',
|
accountType: 'Account Type',
|
||||||
|
actorType: 'Actor Type',
|
||||||
nickname: 'Nickname',
|
nickname: 'Nickname',
|
||||||
recentStatuses: 'Recent Statuses',
|
recentStatuses: 'Recent Statuses',
|
||||||
roles: 'Roles',
|
roles: 'Roles',
|
||||||
activeUppercase: 'Active',
|
active: 'Active',
|
||||||
active: 'active',
|
status: 'Status',
|
||||||
deactivated: 'deactivated',
|
reason: 'Registration Reason',
|
||||||
|
deactivated: 'Deactivated',
|
||||||
|
pending: 'Pending',
|
||||||
noStatuses: 'No statuses to show',
|
noStatuses: 'No statuses to show',
|
||||||
|
noMessages: 'No messages to show',
|
||||||
|
openAccountInInstance: 'Open account in instance',
|
||||||
securitySettings: {
|
securitySettings: {
|
||||||
email: 'Email',
|
email: 'Email',
|
||||||
password: 'Password',
|
password: 'Password',
|
||||||
|
@ -284,15 +338,22 @@ export default {
|
||||||
},
|
},
|
||||||
usersFilter: {
|
usersFilter: {
|
||||||
inputPlaceholder: 'Select filter',
|
inputPlaceholder: 'Select filter',
|
||||||
byUserType: 'By user type',
|
byAccountType: 'By account type',
|
||||||
|
byActorType: 'By actor type',
|
||||||
local: 'Local',
|
local: 'Local',
|
||||||
external: 'External',
|
external: 'External',
|
||||||
byStatus: 'By status',
|
byStatus: 'By status',
|
||||||
active: 'Active',
|
active: 'Active',
|
||||||
deactivated: 'Deactivated'
|
pending: 'Pending Approval',
|
||||||
|
deactivated: 'Deactivated',
|
||||||
|
unconfirmed: 'Unconfirmed',
|
||||||
|
person: 'Person',
|
||||||
|
bot: 'Bot',
|
||||||
|
application: 'Application'
|
||||||
},
|
},
|
||||||
reports: {
|
reports: {
|
||||||
reports: 'Reports',
|
reports: 'Reports',
|
||||||
|
report: 'Report',
|
||||||
reply: 'Reply',
|
reply: 'Reply',
|
||||||
from: 'From',
|
from: 'From',
|
||||||
showNotes: 'Show notes',
|
showNotes: 'Show notes',
|
||||||
|
@ -321,6 +382,7 @@ export default {
|
||||||
unlisted: 'Make status unlisted',
|
unlisted: 'Make status unlisted',
|
||||||
sensitive: 'Sensitive',
|
sensitive: 'Sensitive',
|
||||||
deleteStatus: 'Delete status',
|
deleteStatus: 'Delete status',
|
||||||
|
deleteMessage: 'Delete message',
|
||||||
reportOn: 'Report on',
|
reportOn: 'Report on',
|
||||||
reportsOn: 'Reports on',
|
reportsOn: 'Reports on',
|
||||||
id: 'ID',
|
id: 'ID',
|
||||||
|
@ -330,9 +392,12 @@ export default {
|
||||||
content: 'Content',
|
content: 'Content',
|
||||||
reportedStatus: 'Reported status',
|
reportedStatus: 'Reported status',
|
||||||
statusDeleted: 'This status has been deleted',
|
statusDeleted: 'This status has been deleted',
|
||||||
|
messageDeleted: 'This message has been deleted',
|
||||||
|
messageModeration: 'Message options',
|
||||||
leaveNote: 'Leave a note',
|
leaveNote: 'Leave a note',
|
||||||
postNote: 'Send',
|
postNote: 'Send',
|
||||||
deleteNote: 'Delete'
|
deleteNote: 'Delete',
|
||||||
|
notFound: 'account not found'
|
||||||
},
|
},
|
||||||
reportsFilter: {
|
reportsFilter: {
|
||||||
inputPlaceholder: 'Select filter',
|
inputPlaceholder: 'Select filter',
|
||||||
|
@ -344,30 +409,27 @@ export default {
|
||||||
moderationLog: 'Moderation Log'
|
moderationLog: 'Moderation Log'
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
|
submit: 'Submit',
|
||||||
settings: 'Settings',
|
settings: 'Settings',
|
||||||
instance: 'Instance',
|
instance: 'Instance',
|
||||||
|
search: 'Search',
|
||||||
upload: 'Upload',
|
upload: 'Upload',
|
||||||
mailer: 'Mailer',
|
mailer: 'Mailer',
|
||||||
|
linkFormatter: 'Link Formatter',
|
||||||
logger: 'Logger',
|
logger: 'Logger',
|
||||||
activityPub: 'ActivityPub',
|
activityPub: 'ActivityPub',
|
||||||
auth: 'Authentication',
|
auth: 'Authentication',
|
||||||
autoLinker: 'Auto Linker',
|
|
||||||
captcha: 'Captcha',
|
captcha: 'Captcha',
|
||||||
|
emoji: 'Emoji',
|
||||||
frontend: 'Frontend',
|
frontend: 'Frontend',
|
||||||
http: 'HTTP',
|
http: 'HTTP',
|
||||||
mrf: 'MRF',
|
mrf: 'MRF',
|
||||||
mediaProxy: 'Media Proxy',
|
mediaProxy: 'Media Proxy',
|
||||||
metadata: 'Metadata',
|
metadata: 'Metadata',
|
||||||
gopher: 'Gopher',
|
|
||||||
jobQueue: 'Job queue',
|
jobQueue: 'Job queue',
|
||||||
webPush: 'Web push encryption',
|
webPush: 'Web push encryption',
|
||||||
esshd: 'BBS / SSH access',
|
|
||||||
rateLimiters: 'Rate limiters',
|
rateLimiters: 'Rate limiters',
|
||||||
other: 'Other',
|
other: 'Other',
|
||||||
relays: 'Relays',
|
|
||||||
follow: 'Follow',
|
|
||||||
followRelay: 'Follow new relay',
|
|
||||||
instanceUrl: 'Instance URL',
|
|
||||||
success: 'Settings changed successfully!',
|
success: 'Settings changed successfully!',
|
||||||
description: 'Description',
|
description: 'Description',
|
||||||
removeFromDB: 'Remove setting from the DB',
|
removeFromDB: 'Remove setting from the DB',
|
||||||
|
@ -379,13 +441,44 @@ export default {
|
||||||
files: 'files',
|
files: 'files',
|
||||||
successfullyRemoved: 'Setting removed successfully!',
|
successfullyRemoved: 'Setting removed successfully!',
|
||||||
seeDocs: 'See Documentation',
|
seeDocs: 'See Documentation',
|
||||||
assets: 'Assets',
|
instanceReboot: 'Reboot Instance',
|
||||||
emoji: 'Emoji',
|
|
||||||
markup: 'Markup settings',
|
|
||||||
corsPlug: 'CORS plug config',
|
|
||||||
instanceReboot: 'Instance Reboot',
|
|
||||||
restartApp: 'You must restart the instance to apply settings',
|
restartApp: 'You must restart the instance to apply settings',
|
||||||
restartSuccess: 'Instance rebooted successfully!'
|
restartSuccess: 'Instance rebooted successfully!',
|
||||||
|
removeSettingConfirmation: 'Are you sure you want to remove this setting\'s value from the database?',
|
||||||
|
changeImage: 'Change image',
|
||||||
|
uploadImage: 'Upload image',
|
||||||
|
remove: 'Remove',
|
||||||
|
instancePanel: 'Instance Panel Document',
|
||||||
|
termsOfServices: 'Terms of Service',
|
||||||
|
availableFrontends: 'Available Frontends',
|
||||||
|
installFrontends: 'This is the list of available frontends. You can switch to one of the listed frontends or specify all the required options and install another frontend',
|
||||||
|
install: 'Install',
|
||||||
|
installed: 'Installed',
|
||||||
|
name: 'Name',
|
||||||
|
git: 'Git',
|
||||||
|
installAnotherFrontend: 'Install another frontend',
|
||||||
|
addKeyValuePair: 'Add another `key - value` pair to this icon',
|
||||||
|
addIconConfig: 'Add another icon configuration',
|
||||||
|
setLimits: 'Set different limits for unauthenticated and authenticated users',
|
||||||
|
unauthenticatedUsers: 'Unauthenticated users',
|
||||||
|
authenticatedUsers: 'Authenticated users',
|
||||||
|
scale: 'Timespan (ms)',
|
||||||
|
limit: 'Requests',
|
||||||
|
setLimitsForAll: 'Set limit for all users',
|
||||||
|
ref: 'Ref',
|
||||||
|
file: 'File',
|
||||||
|
buildUrl: 'Build URL',
|
||||||
|
buildDir: 'Build Directory',
|
||||||
|
frontendSuccess: 'Frontend installed successfully!',
|
||||||
|
frontendStartedInstallation: 'Installation started',
|
||||||
|
inProcess: 'In process'
|
||||||
|
},
|
||||||
|
relays: {
|
||||||
|
relays: 'Relays',
|
||||||
|
follow: 'Follow',
|
||||||
|
followRelay: 'Follow new relay',
|
||||||
|
followedBack: 'Followed Back',
|
||||||
|
instanceUrl: 'Instance URL'
|
||||||
},
|
},
|
||||||
invites: {
|
invites: {
|
||||||
inviteTokens: 'Invite tokens',
|
inviteTokens: 'Invite tokens',
|
||||||
|
@ -395,6 +488,7 @@ export default {
|
||||||
expiresAt: 'Expires at',
|
expiresAt: 'Expires at',
|
||||||
tokenCreated: 'Invite token was created',
|
tokenCreated: 'Invite token was created',
|
||||||
token: 'Token',
|
token: 'Token',
|
||||||
|
inviteLink: 'Invite link',
|
||||||
uses: 'Uses',
|
uses: 'Uses',
|
||||||
used: 'Used',
|
used: 'Used',
|
||||||
cancel: 'Cancel',
|
cancel: 'Cancel',
|
||||||
|
@ -411,7 +505,8 @@ export default {
|
||||||
invalidEmailError: 'Please input valid e-mail',
|
invalidEmailError: 'Please input valid e-mail',
|
||||||
emailSent: 'Invite was sent',
|
emailSent: 'Invite was sent',
|
||||||
submitFormError: 'There are invalid values in the form. Please fix them before continuing.',
|
submitFormError: 'There are invalid values in the form. Please fix them before continuing.',
|
||||||
inviteViaEmailAlert: 'To send invite via email make sure to enable `invites_enabled` and disable `registrations_open`'
|
inviteViaEmailAlert: 'To send invite via email make sure to enable `invites_enabled` and disable `registrations_open`',
|
||||||
|
copyLink: 'Copy link'
|
||||||
},
|
},
|
||||||
emoji: {
|
emoji: {
|
||||||
emojiPacks: 'Emoji packs',
|
emojiPacks: 'Emoji packs',
|
||||||
|
@ -465,6 +560,9 @@ export default {
|
||||||
specifyShortcode: 'Specify a custom shortcode',
|
specifyShortcode: 'Specify a custom shortcode',
|
||||||
specifyFilename: 'Specify a custom filename',
|
specifyFilename: 'Specify a custom filename',
|
||||||
copy: 'Copy',
|
copy: 'Copy',
|
||||||
copyToLocalPack: 'Copy to local pack'
|
copyToLocalPack: 'Copy to local pack',
|
||||||
|
emptyPack: 'This emoji pack is empty',
|
||||||
|
emojiWarning: 'Pack names cannot include any of the following characters: # / < > & +',
|
||||||
|
image: 'Image'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,11 +127,6 @@ export default {
|
||||||
cancel: 'Cancelar',
|
cancel: 'Cancelar',
|
||||||
confirm: 'Confirmar'
|
confirm: 'Confirmar'
|
||||||
},
|
},
|
||||||
errorLog: {
|
|
||||||
tips: 'Please click the bug icon in the upper right corner',
|
|
||||||
description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.',
|
|
||||||
documentation: 'Documento de introducción'
|
|
||||||
},
|
|
||||||
excel: {
|
excel: {
|
||||||
export: 'Exportar',
|
export: 'Exportar',
|
||||||
selectedExport: 'Exportar seleccionados',
|
selectedExport: 'Exportar seleccionados',
|
||||||
|
|
|
@ -128,11 +128,6 @@ export default {
|
||||||
cancel: 'Anullar',
|
cancel: 'Anullar',
|
||||||
confirm: 'Confirmar'
|
confirm: 'Confirmar'
|
||||||
},
|
},
|
||||||
errorLog: {
|
|
||||||
tips: 'Mercés de clicar l’icòna del babau amont a man drecha',
|
|
||||||
description: 'Ara que lo sistèma de gestion es coma un spa, melhora l’experiéncia dels utilizaire mas aumenta tanben lo risc de problèmas sus la pagina, una pichona negligéncia pòt menar a un blocatge complèt de la pagina. Urosament Vue fornís de manièras per gerir las excepcions, trobar las errors o senhalar las excepcions.',
|
|
||||||
documentation: 'Presentacion del document'
|
|
||||||
},
|
|
||||||
excel: {
|
excel: {
|
||||||
export: 'Exportar',
|
export: 'Exportar',
|
||||||
selectedExport: 'Exportar los elements seleccionats',
|
selectedExport: 'Exportar los elements seleccionats',
|
||||||
|
|
|
@ -127,11 +127,6 @@ export default {
|
||||||
cancel: '取 消',
|
cancel: '取 消',
|
||||||
confirm: '确 定'
|
confirm: '确 定'
|
||||||
},
|
},
|
||||||
errorLog: {
|
|
||||||
tips: '请点击右上角bug小图标',
|
|
||||||
description: '现在的管理后台基本都是spa的形式了,它增强了用户体验,但同时也会增加页面出问题的可能性,可能一个小小的疏忽就导致整个页面的死锁。好在 Vue 官网提供了一个方法来捕获处理异常,你可以在其中进行错误处理或者异常上报。',
|
|
||||||
documentation: '文档介绍'
|
|
||||||
},
|
|
||||||
excel: {
|
excel: {
|
||||||
export: '导出',
|
export: '导出',
|
||||||
selectedExport: '导出已选择项',
|
selectedExport: '导出已选择项',
|
||||||
|
|
|
@ -28,12 +28,17 @@ export const beforeEachRoute = (to, from, next) => {
|
||||||
store.dispatch('GetUserInfo').then(res => {
|
store.dispatch('GetUserInfo').then(res => {
|
||||||
const roles = res.data.pleroma.is_admin ? ['admin'] : []
|
const roles = res.data.pleroma.is_admin ? ['admin'] : []
|
||||||
store.dispatch('GenerateRoutes', { roles }).then(() => {
|
store.dispatch('GenerateRoutes', { roles }).then(() => {
|
||||||
router.addRoutes(store.getters.addRouters)
|
store.getters.addRouters.forEach(route => router.addRoute(route))
|
||||||
next({ ...to, replace: true })
|
next({ ...to, replace: true })
|
||||||
})
|
})
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
store.dispatch('FedLogOut').then(() => {
|
store.dispatch('FedLogOut').then(() => {
|
||||||
Message.error(err)
|
Message({
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: err,
|
||||||
|
type: 'error',
|
||||||
|
duration: 10 * 1000
|
||||||
|
})
|
||||||
next({ path: '/' })
|
next({ path: '/' })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,24 +3,44 @@ import Router from 'vue-router'
|
||||||
|
|
||||||
Vue.use(Router)
|
Vue.use(Router)
|
||||||
|
|
||||||
|
const originalPush = Router.prototype.push
|
||||||
|
Router.prototype.push = function push(location, onResolve, onReject) {
|
||||||
|
if (onResolve || onReject) { return originalPush.call(this, location, onResolve, onReject) }
|
||||||
|
return originalPush.call(this, location).catch((err) => {
|
||||||
|
if (Router.isNavigationFailure(err)) {
|
||||||
|
// resolve err
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// rethrow error
|
||||||
|
return Promise.reject(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
import Layout from '@/views/layout/Layout'
|
import Layout from '@/views/layout/Layout'
|
||||||
|
|
||||||
const disabledFeatures = process.env.DISABLED_FEATURES || []
|
const disabledFeatures = process.env.DISABLED_FEATURES || []
|
||||||
const settingsDisabled = disabledFeatures.includes('settings')
|
const settingsDisabled = disabledFeatures.includes('settings')
|
||||||
|
const settingsChildren = () => {
|
||||||
|
return localStorage.getItem('settingsTabs')
|
||||||
|
? JSON.parse(localStorage.getItem('settingsTabs')).map(({ label, path }) => {
|
||||||
|
return {
|
||||||
|
path,
|
||||||
|
component: () => import(`@/views/settings`),
|
||||||
|
name: label,
|
||||||
|
meta: { title: label }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
: []
|
||||||
|
}
|
||||||
const settings = {
|
const settings = {
|
||||||
path: '/settings',
|
path: '/settings',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
children: [
|
name: 'Settings',
|
||||||
{
|
hasSubmenu: true,
|
||||||
path: 'index',
|
meta: { title: 'settings', icon: 'el-icon-setting', noCache: true },
|
||||||
component: () => import('@/views/settings/index'),
|
children: settingsChildren()
|
||||||
name: 'Settings',
|
|
||||||
meta: { title: 'Settings', icon: 'settings', noCache: true }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusesDisabled = disabledFeatures.includes('statuses')
|
const statusesDisabled = disabledFeatures.includes('statuses')
|
||||||
const statuses = {
|
const statuses = {
|
||||||
path: '/statuses',
|
path: '/statuses',
|
||||||
|
@ -30,7 +50,7 @@ const statuses = {
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/statuses/index'),
|
component: () => import('@/views/statuses/index'),
|
||||||
name: 'Statuses',
|
name: 'Statuses',
|
||||||
meta: { title: 'Statuses', icon: 'form', noCache: true }
|
meta: { title: 'statuses', icon: 'el-icon-chat-line-square', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -44,7 +64,7 @@ const reports = {
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/reports/index'),
|
component: () => import('@/views/reports/index'),
|
||||||
name: 'Reports',
|
name: 'Reports',
|
||||||
meta: { title: 'Reports', icon: 'documentation', noCache: true }
|
meta: { title: 'reports', icon: 'el-icon-receiving', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -58,21 +78,21 @@ const invites = {
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/invites/index'),
|
component: () => import('@/views/invites/index'),
|
||||||
name: 'Invites',
|
name: 'Invites',
|
||||||
meta: { title: 'Invites', icon: 'guide', noCache: true }
|
meta: { title: 'invites', icon: 'el-icon-postcard', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const emojiPacksDisabled = disabledFeatures.includes('emoji-packs')
|
const relaysDisabled = disabledFeatures.includes('relays')
|
||||||
const emojiPacks = {
|
const relays = {
|
||||||
path: '/emoji_packs',
|
path: '/relays',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/emojiPacks/index'),
|
component: () => import('@/views/relays/index'),
|
||||||
name: 'Emoji Packs',
|
name: 'Relays',
|
||||||
meta: { title: 'Emoji Packs', icon: 'eye-open', noCache: true }
|
meta: { title: 'relays', icon: 'el-icon-connection', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -84,9 +104,23 @@ const moderationLog = {
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/moderation_log/index'),
|
component: () => import('@/views/moderationLog/index'),
|
||||||
name: 'Moderation Log',
|
name: 'Moderation Log',
|
||||||
meta: { title: 'moderationLog', icon: 'list', noCache: true }
|
meta: { title: 'moderationLog', icon: 'el-icon-notebook-2', noCache: true }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const mediaProxyCacheDisabled = disabledFeatures.includes('media-proxy-cache')
|
||||||
|
const mediaProxyCache = {
|
||||||
|
path: '/media_proxy_cache',
|
||||||
|
component: Layout,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'index',
|
||||||
|
component: () => import('@/views/mediaProxyCache/index'),
|
||||||
|
name: 'MediaProxy Cache',
|
||||||
|
meta: { title: 'mediaProxyCache', icon: 'el-icon-coin', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -131,7 +165,8 @@ export const constantRouterMap = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/users/index'
|
redirect: '/users/index',
|
||||||
|
hidden: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -150,15 +185,16 @@ export const asyncRouterMap = [
|
||||||
path: 'index',
|
path: 'index',
|
||||||
component: () => import('@/views/users/index'),
|
component: () => import('@/views/users/index'),
|
||||||
name: 'Users',
|
name: 'Users',
|
||||||
meta: { title: 'users', icon: 'peoples', noCache: true }
|
meta: { title: 'users', icon: 'el-icon-user', noCache: true }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
...(statusesDisabled ? [] : [statuses]),
|
...(statusesDisabled ? [] : [statuses]),
|
||||||
...(reportsDisabled ? [] : [reports]),
|
...(reportsDisabled ? [] : [reports]),
|
||||||
...(invitesDisabled ? [] : [invites]),
|
...(invitesDisabled ? [] : [invites]),
|
||||||
...(emojiPacksDisabled ? [] : [emojiPacks]),
|
|
||||||
...(moderationLogDisabled ? [] : [moderationLog]),
|
...(moderationLogDisabled ? [] : [moderationLog]),
|
||||||
|
...(relaysDisabled ? [] : [relays]),
|
||||||
|
...(mediaProxyCacheDisabled ? [] : [mediaProxyCache]),
|
||||||
...(settingsDisabled ? [] : [settings]),
|
...(settingsDisabled ? [] : [settings]),
|
||||||
{
|
{
|
||||||
path: '/users/:id',
|
path: '/users/:id',
|
||||||
|
@ -172,5 +208,29 @@ export const asyncRouterMap = [
|
||||||
],
|
],
|
||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/statuses/:id',
|
||||||
|
component: Layout,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'StatusShow',
|
||||||
|
component: () => import('@/views/statuses/show')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/reports/:id',
|
||||||
|
component: Layout,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'ReportsShow',
|
||||||
|
component: () => import('@/views/reports/show')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
{ path: '*', redirect: '/404', hidden: true }
|
{ path: '*', redirect: '/404', hidden: true }
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
/** When your routing table is too long, you can split it into small modules**/
|
|
||||||
|
|
||||||
import Layout from '@/views/layout/Layout'
|
|
||||||
|
|
||||||
const chartsRouter = {
|
|
||||||
path: '/charts',
|
|
||||||
component: Layout,
|
|
||||||
redirect: 'noredirect',
|
|
||||||
name: 'Charts',
|
|
||||||
meta: {
|
|
||||||
title: 'charts',
|
|
||||||
icon: 'chart'
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'keyboard',
|
|
||||||
component: () => import('@/views/charts/keyboard'),
|
|
||||||
name: 'KeyboardChart',
|
|
||||||
meta: { title: 'keyboardChart', noCache: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'line',
|
|
||||||
component: () => import('@/views/charts/line'),
|
|
||||||
name: 'LineChart',
|
|
||||||
meta: { title: 'lineChart', noCache: true }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'mixchart',
|
|
||||||
component: () => import('@/views/charts/mixChart'),
|
|
||||||
name: 'MixChart',
|
|
||||||
meta: { title: 'mixChart', noCache: true }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export default chartsRouter
|
|
|
@ -1,66 +0,0 @@
|
||||||
/** When your routing table is too long, you can split it into small modules**/
|
|
||||||
|
|
||||||
import Layout from '@/views/layout/Layout'
|
|
||||||
|
|
||||||
const nestedRouter = {
|
|
||||||
path: '/nested',
|
|
||||||
component: Layout,
|
|
||||||
redirect: '/nested/menu1/menu1-1',
|
|
||||||
name: 'Nested',
|
|
||||||
meta: {
|
|
||||||
title: 'nested',
|
|
||||||
icon: 'nested'
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'menu1',
|
|
||||||
component: () => import('@/views/nested/menu1/index'), // Parent router-view
|
|
||||||
name: 'Menu1',
|
|
||||||
meta: { title: 'menu1' },
|
|
||||||
redirect: '/nested/menu1/menu1-1',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'menu1-1',
|
|
||||||
component: () => import('@/views/nested/menu1/menu1-1'),
|
|
||||||
name: 'Menu1-1',
|
|
||||||
meta: { title: 'menu1-1' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'menu1-2',
|
|
||||||
component: () => import('@/views/nested/menu1/menu1-2'),
|
|
||||||
name: 'Menu1-2',
|
|
||||||
redirect: '/nested/menu1/menu1-2/menu1-2-1',
|
|
||||||
meta: { title: 'menu1-2' },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'menu1-2-1',
|
|
||||||
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
|
|
||||||
name: 'Menu1-2-1',
|
|
||||||
meta: { title: 'menu1-2-1' }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'menu1-2-2',
|
|
||||||
component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
|
|
||||||
name: 'Menu1-2-2',
|
|
||||||
meta: { title: 'menu1-2-2' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'menu1-3',
|
|
||||||
component: () => import('@/views/nested/menu1/menu1-3'),
|
|
||||||
name: 'Menu1-3',
|
|
||||||
meta: { title: 'menu1-3' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'menu2',
|
|
||||||
name: 'Menu2',
|
|
||||||
component: () => import('@/views/nested/menu2/index'),
|
|
||||||
meta: { title: 'menu2' }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export default nestedRouter
|
|
|
@ -17,6 +17,7 @@ const getters = {
|
||||||
errorLogs: state => state.errorLog.logs,
|
errorLogs: state => state.errorLog.logs,
|
||||||
users: state => state.users.fetchedUsers,
|
users: state => state.users.fetchedUsers,
|
||||||
authHost: state => state.user.authHost,
|
authHost: state => state.user.authHost,
|
||||||
settings: state => state.settings
|
settings: state => state.settings,
|
||||||
|
tabs: state => state.settings.tabs
|
||||||
}
|
}
|
||||||
export default getters
|
export default getters
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import app from './modules/app'
|
import app from './modules/app'
|
||||||
|
import emojiPacks from './modules/emojiPacks'
|
||||||
import errorLog from './modules/errorLog'
|
import errorLog from './modules/errorLog'
|
||||||
import moderationLog from './modules/moderationLog'
|
import getters from './getters'
|
||||||
import invites from './modules/invites'
|
import invites from './modules/invites'
|
||||||
|
import mediaProxyCache from './modules/mediaProxyCache'
|
||||||
|
import moderationLog from './modules/moderationLog'
|
||||||
import peers from './modules/peers'
|
import peers from './modules/peers'
|
||||||
import permission from './modules/permission'
|
import permission from './modules/permission'
|
||||||
import relays from './modules/relays'
|
import relays from './modules/relays'
|
||||||
|
@ -14,8 +17,6 @@ import tagsView from './modules/tagsView'
|
||||||
import user from './modules/user'
|
import user from './modules/user'
|
||||||
import userProfile from './modules/userProfile'
|
import userProfile from './modules/userProfile'
|
||||||
import users from './modules/users'
|
import users from './modules/users'
|
||||||
import getters from './getters'
|
|
||||||
import emojiPacks from './modules/emojiPacks.js'
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
@ -23,8 +24,10 @@ const store = new Vuex.Store({
|
||||||
modules: {
|
modules: {
|
||||||
app,
|
app,
|
||||||
errorLog,
|
errorLog,
|
||||||
moderationLog,
|
emojiPacks,
|
||||||
invites,
|
invites,
|
||||||
|
mediaProxyCache,
|
||||||
|
moderationLog,
|
||||||
peers,
|
peers,
|
||||||
permission,
|
permission,
|
||||||
relays,
|
relays,
|
||||||
|
@ -34,8 +37,7 @@ const store = new Vuex.Store({
|
||||||
tagsView,
|
tagsView,
|
||||||
user,
|
user,
|
||||||
userProfile,
|
userProfile,
|
||||||
users,
|
users
|
||||||
emojiPacks
|
|
||||||
},
|
},
|
||||||
getters
|
getters
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
|
import { needReboot, restartApp } from '@/api/app'
|
||||||
|
|
||||||
const app = {
|
const app = {
|
||||||
state: {
|
state: {
|
||||||
|
@ -8,7 +9,9 @@ const app = {
|
||||||
},
|
},
|
||||||
device: 'desktop',
|
device: 'desktop',
|
||||||
language: Cookies.get('language') || 'en',
|
language: Cookies.get('language') || 'en',
|
||||||
size: Cookies.get('size') || 'medium'
|
needReboot: false,
|
||||||
|
size: Cookies.get('size') || 'medium',
|
||||||
|
invitesEnabled: false
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
TOGGLE_SIDEBAR: state => {
|
TOGGLE_SIDEBAR: state => {
|
||||||
|
@ -28,30 +31,47 @@ const app = {
|
||||||
TOGGLE_DEVICE: (state, device) => {
|
TOGGLE_DEVICE: (state, device) => {
|
||||||
state.device = device
|
state.device = device
|
||||||
},
|
},
|
||||||
|
SET_INVITES_ENABLED: (state, invitesEnabled) => {
|
||||||
|
state.invitesEnabled = invitesEnabled
|
||||||
|
},
|
||||||
SET_LANGUAGE: (state, language) => {
|
SET_LANGUAGE: (state, language) => {
|
||||||
state.language = language
|
state.language = language
|
||||||
Cookies.set('language', language)
|
Cookies.set('language', language)
|
||||||
},
|
},
|
||||||
|
TOGGLE_REBOOT: (state, needReboot) => {
|
||||||
|
state.needReboot = needReboot
|
||||||
|
},
|
||||||
SET_SIZE: (state, size) => {
|
SET_SIZE: (state, size) => {
|
||||||
state.size = size
|
state.size = size
|
||||||
Cookies.set('size', size)
|
Cookies.set('size', size)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
toggleSideBar({ commit }) {
|
|
||||||
commit('TOGGLE_SIDEBAR')
|
|
||||||
},
|
|
||||||
closeSideBar({ commit }, { withoutAnimation }) {
|
closeSideBar({ commit }, { withoutAnimation }) {
|
||||||
commit('CLOSE_SIDEBAR', withoutAnimation)
|
commit('CLOSE_SIDEBAR', withoutAnimation)
|
||||||
},
|
},
|
||||||
toggleDevice({ commit }, device) {
|
async NeedReboot({ commit, getters }) {
|
||||||
commit('TOGGLE_DEVICE', device)
|
const response = await needReboot(getters.authHost, getters.token)
|
||||||
|
commit('TOGGLE_REBOOT', response.data['need_reboot'])
|
||||||
|
},
|
||||||
|
async RestartApplication({ commit, getters }) {
|
||||||
|
await restartApp(getters.authHost, getters.token)
|
||||||
|
commit('TOGGLE_REBOOT', false)
|
||||||
|
},
|
||||||
|
SetInvitesEnabled({ commit }, invitesEnabled) {
|
||||||
|
commit('SET_INVITES_ENABLED', invitesEnabled)
|
||||||
},
|
},
|
||||||
setLanguage({ commit }, language) {
|
setLanguage({ commit }, language) {
|
||||||
commit('SET_LANGUAGE', language)
|
commit('SET_LANGUAGE', language)
|
||||||
},
|
},
|
||||||
setSize({ commit }, size) {
|
setSize({ commit }, size) {
|
||||||
commit('SET_SIZE', size)
|
commit('SET_SIZE', size)
|
||||||
|
},
|
||||||
|
toggleDevice({ commit }, device) {
|
||||||
|
commit('TOGGLE_DEVICE', device)
|
||||||
|
},
|
||||||
|
toggleSideBar({ commit }) {
|
||||||
|
commit('TOGGLE_SIDEBAR')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,72 @@
|
||||||
import {
|
import {
|
||||||
|
addNewEmojiFile,
|
||||||
|
createPack,
|
||||||
|
deleteEmojiFile,
|
||||||
|
deletePack,
|
||||||
|
downloadFrom,
|
||||||
|
fetchPack,
|
||||||
|
importFromFS,
|
||||||
listPacks,
|
listPacks,
|
||||||
listRemotePacks,
|
listRemotePacks,
|
||||||
downloadFrom,
|
|
||||||
reloadEmoji,
|
reloadEmoji,
|
||||||
createPack,
|
|
||||||
deletePack,
|
|
||||||
savePackMetadata,
|
savePackMetadata,
|
||||||
importFromFS,
|
updateEmojiFile
|
||||||
updatePackFile } from '@/api/emojiPacks'
|
} from '@/api/emojiPacks'
|
||||||
import i18n from '@/lang'
|
import i18n from '@/lang'
|
||||||
import { Message } from 'element-ui'
|
import { Message } from 'element-ui'
|
||||||
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
|
||||||
const packs = {
|
const emojiPacks = {
|
||||||
state: {
|
state: {
|
||||||
|
currentLocalFilesPage: 1,
|
||||||
|
currentLocalPacksPage: 1,
|
||||||
|
currentRemoteFilesPage: 1,
|
||||||
|
currentRemotePacksPage: 1,
|
||||||
|
filesPageSize: 30,
|
||||||
|
localPackFilesCount: 0,
|
||||||
localPacks: {},
|
localPacks: {},
|
||||||
|
localPacksCount: 0,
|
||||||
|
pageSize: 50,
|
||||||
remoteInstance: '',
|
remoteInstance: '',
|
||||||
remotePacks: {}
|
remotePackFilesCount: 0,
|
||||||
|
remotePacks: {},
|
||||||
|
remotePacksCount: 0
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
|
SET_LOCAL_FILES_COUNT: (state, count) => {
|
||||||
|
state.localPackFilesCount = count
|
||||||
|
},
|
||||||
|
SET_LOCAL_FILES_PAGE: (state, page) => {
|
||||||
|
state.currentLocalFilesPage = page
|
||||||
|
},
|
||||||
SET_LOCAL_PACKS: (state, packs) => {
|
SET_LOCAL_PACKS: (state, packs) => {
|
||||||
state.localPacks = packs
|
state.localPacks = packs
|
||||||
},
|
},
|
||||||
|
SET_LOCAL_PACKS_COUNT: (state, count) => {
|
||||||
|
state.localPacksCount = count
|
||||||
|
},
|
||||||
|
SET_LOCAL_PACK_FILES: (state, { name, files }) => {
|
||||||
|
state.localPacks = { ...state.localPacks, [name]: { ...state.localPacks[name], files }}
|
||||||
|
},
|
||||||
|
SET_LOCAL_PAGE: (state, page) => {
|
||||||
|
state.currentLocalPacksPage = page
|
||||||
|
},
|
||||||
|
SET_REMOTE_FILES_COUNT: (state, count) => {
|
||||||
|
state.remotePackFilesCount = count
|
||||||
|
},
|
||||||
|
SET_REMOTE_FILES_PAGE: (state, page) => {
|
||||||
|
state.currentRemoteFilesPage = page
|
||||||
|
},
|
||||||
SET_REMOTE_INSTANCE: (state, name) => {
|
SET_REMOTE_INSTANCE: (state, name) => {
|
||||||
state.remoteInstance = name
|
state.remoteInstance = name
|
||||||
},
|
},
|
||||||
|
SET_REMOTE_PACKS_COUNT: (state, count) => {
|
||||||
|
state.remotePacksCount = count
|
||||||
|
},
|
||||||
|
SET_REMOTE_PACK_FILES: (state, { name, files }) => {
|
||||||
|
state.remotePacks = { ...state.remotePacks, [name]: { ...state.remotePacks[name], files }}
|
||||||
|
},
|
||||||
SET_REMOTE_PACKS: (state, packs) => {
|
SET_REMOTE_PACKS: (state, packs) => {
|
||||||
state.remotePacks = packs
|
state.remotePacks = packs
|
||||||
},
|
},
|
||||||
|
@ -45,6 +86,41 @@ const packs = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
async AddNewEmojiFile({ commit, getters }, { packName, file, shortcode, filename }) {
|
||||||
|
let result
|
||||||
|
try {
|
||||||
|
result = await addNewEmojiFile(packName, file, shortcode, filename, getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Message({
|
||||||
|
message: `${i18n.t('settings.successfullyUpdated')} ${packName} ${i18n.t('settings.metadatLowerCase')}`,
|
||||||
|
type: 'success',
|
||||||
|
duration: 5 * 1000
|
||||||
|
})
|
||||||
|
|
||||||
|
commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: result.data })
|
||||||
|
},
|
||||||
|
async DeleteEmojiFile({ commit, dispatch, getters, state }, { packName, shortcode }) {
|
||||||
|
const { [shortcode]: value, ...updatedPackFiles } = state.localPacks[packName].files
|
||||||
|
commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: updatedPackFiles })
|
||||||
|
|
||||||
|
try {
|
||||||
|
await deleteEmojiFile(packName, shortcode, getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Message({
|
||||||
|
message: `${i18n.t('settings.successfullyUpdated')} ${packName} ${i18n.t('settings.metadatLowerCase')}`,
|
||||||
|
type: 'success',
|
||||||
|
duration: 5 * 1000
|
||||||
|
})
|
||||||
|
if (Object.keys(updatedPackFiles).length === 0 && state.currentLocalFilesPage > 1) {
|
||||||
|
dispatch('FetchLocalSinglePack', { name: packName, page: state.currentLocalFilesPage - 1 })
|
||||||
|
} else {
|
||||||
|
dispatch('FetchLocalSinglePack', { name: packName, page: state.currentLocalFilesPage })
|
||||||
|
}
|
||||||
|
},
|
||||||
async CreatePack({ getters }, { name }) {
|
async CreatePack({ getters }, { name }) {
|
||||||
await createPack(getters.authHost, getters.token, name)
|
await createPack(getters.authHost, getters.token, name)
|
||||||
},
|
},
|
||||||
|
@ -52,7 +128,7 @@ const packs = {
|
||||||
await deletePack(getters.authHost, getters.token, name)
|
await deletePack(getters.authHost, getters.token, name)
|
||||||
},
|
},
|
||||||
async DownloadFrom({ getters }, { instanceAddress, packName, as }) {
|
async DownloadFrom({ getters }, { instanceAddress, packName, as }) {
|
||||||
const result = await downloadFrom(getters.authHost, instanceAddress, packName, as, getters.token)
|
const result = await downloadFrom(instanceAddress, packName, as, getters.authHost, getters.token)
|
||||||
|
|
||||||
if (result.data === 'ok') {
|
if (result.data === 'ok') {
|
||||||
Message({
|
Message({
|
||||||
|
@ -62,6 +138,32 @@ const packs = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async FetchLocalEmojiPacks({ commit, getters, state }, page) {
|
||||||
|
const { data } = await listPacks(page, state.pageSize, getters.authHost, getters.token)
|
||||||
|
const { packs, count } = data
|
||||||
|
const updatedPacks = Object.keys(packs).reduce((acc, packName) => {
|
||||||
|
const { files, ...pack } = packs[packName]
|
||||||
|
acc[packName] = pack
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
commit('SET_LOCAL_PACKS', updatedPacks)
|
||||||
|
commit('SET_LOCAL_PACKS_COUNT', count)
|
||||||
|
commit('SET_LOCAL_PAGE', page)
|
||||||
|
},
|
||||||
|
async FetchLocalSinglePack({ getters, commit, state }, { name, page }) {
|
||||||
|
const { data } = await fetchPack(name, page, state.filesPageSize, getters.authHost, getters.token)
|
||||||
|
const { files, files_count } = data
|
||||||
|
commit('SET_LOCAL_PACK_FILES', { name, files })
|
||||||
|
commit('SET_LOCAL_FILES_COUNT', files_count)
|
||||||
|
commit('SET_LOCAL_FILES_PAGE', page)
|
||||||
|
},
|
||||||
|
async FetchRemoteSinglePack({ getters, commit, state }, { name, page }) {
|
||||||
|
const { data } = await fetchPack(name, page, state.filesPageSize, getters.authHost, getters.token)
|
||||||
|
const { files, files_count } = data
|
||||||
|
commit('SET_REMOTE_PACK_FILES', { name, files })
|
||||||
|
commit('SET_REMOTE_FILES_COUNT', files_count)
|
||||||
|
commit('SET_REMOTE_FILES_PAGE', page)
|
||||||
|
},
|
||||||
async ImportFromFS({ getters }) {
|
async ImportFromFS({ getters }) {
|
||||||
const result = await importFromFS(getters.authHost, getters.token)
|
const result = await importFromFS(getters.authHost, getters.token)
|
||||||
|
|
||||||
|
@ -99,30 +201,45 @@ const packs = {
|
||||||
commit('UPDATE_LOCAL_PACK_PACK', { name: packName, pack: result.data })
|
commit('UPDATE_LOCAL_PACK_PACK', { name: packName, pack: result.data })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async SetLocalEmojiPacks({ commit, getters }) {
|
async SetRemoteEmojiPacks({ commit, getters, state }, { page, remoteInstance }) {
|
||||||
const { data } = await listPacks(getters.authHost)
|
const { data } = await listRemotePacks(remoteInstance, page, state.pageSize, getters.authHost, getters.token)
|
||||||
commit('SET_LOCAL_PACKS', data)
|
const { packs, count } = data
|
||||||
},
|
const updatedPacks = Object.keys(packs).reduce((acc, packName) => {
|
||||||
async SetRemoteEmojiPacks({ commit, getters }, { remoteInstance }) {
|
const { files, ...pack } = packs[packName]
|
||||||
const { data } = await listRemotePacks(getters.authHost, getters.token, remoteInstance)
|
acc[packName] = pack
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
|
||||||
commit('SET_REMOTE_INSTANCE', remoteInstance)
|
commit('SET_REMOTE_INSTANCE', remoteInstance)
|
||||||
commit('SET_REMOTE_PACKS', data)
|
commit('SET_REMOTE_PACKS', updatedPacks)
|
||||||
|
commit('SET_REMOTE_PACKS_COUNT', count)
|
||||||
},
|
},
|
||||||
async UpdateAndSavePackFile({ commit, getters }, args) {
|
SetRemoteInstance({ commit }, instance) {
|
||||||
const result = await updatePackFile(getters.authHost, getters.token, args)
|
commit('SET_REMOTE_INSTANCE', instance)
|
||||||
|
},
|
||||||
|
async UpdateEmojiFile({ commit, dispatch, getters, state }, { packName, shortcode, newShortcode, newFilename, force }) {
|
||||||
|
const updatedPackFiles = Object.keys(state.localPacks[packName].files).reduce((acc, el) => {
|
||||||
|
if (el === shortcode) {
|
||||||
|
acc[newShortcode] = newFilename
|
||||||
|
} else {
|
||||||
|
acc[el] = state.localPacks[packName].files[el]
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: updatedPackFiles })
|
||||||
|
|
||||||
if (result.status === 200) {
|
try {
|
||||||
const { packName } = args
|
await updateEmojiFile(packName, shortcode, newShortcode, newFilename, force, getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
Message({
|
return
|
||||||
message: `${i18n.t('settings.successfullyUpdated')} ${packName} ${i18n.t('settings.metadatLowerCase')}`,
|
|
||||||
type: 'success',
|
|
||||||
duration: 5 * 1000
|
|
||||||
})
|
|
||||||
|
|
||||||
commit('UPDATE_LOCAL_PACK_FILES', { name: packName, files: result.data })
|
|
||||||
}
|
}
|
||||||
|
Message({
|
||||||
|
message: `${i18n.t('settings.successfullyUpdated')} ${packName} ${i18n.t('settings.metadatLowerCase')}`,
|
||||||
|
type: 'success',
|
||||||
|
duration: 5 * 1000
|
||||||
|
})
|
||||||
|
|
||||||
|
dispatch('FetchLocalSinglePack', { name: packName, page: state.currentLocalFilesPage })
|
||||||
},
|
},
|
||||||
async UpdateLocalPackVal({ commit }, args) {
|
async UpdateLocalPackVal({ commit }, args) {
|
||||||
commit('UPDATE_LOCAL_PACK_VAL', args)
|
commit('UPDATE_LOCAL_PACK_VAL', args)
|
||||||
|
@ -130,4 +247,4 @@ const packs = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default packs
|
export default emojiPacks
|
||||||
|
|
108
src/store/modules/mediaProxyCache.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
import { listBannedUrls, purgeUrls, removeBannedUrls, searchBannedUrls } from '@/api/mediaProxyCache'
|
||||||
|
import { fetchSettings, updateSettings } from '@/api/settings'
|
||||||
|
import { Message } from 'element-ui'
|
||||||
|
import i18n from '@/lang'
|
||||||
|
|
||||||
|
const mediaProxyCache = {
|
||||||
|
state: {
|
||||||
|
bannedUrls: [],
|
||||||
|
currentPage: 1,
|
||||||
|
loading: false,
|
||||||
|
mediaProxyEnabled: false,
|
||||||
|
pageSize: 50,
|
||||||
|
searchQuery: '',
|
||||||
|
totalUrlsCount: 0
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
MEDIA_PROXY_ENABLED: (state, enabled) => {
|
||||||
|
state.mediaProxyEnabled = enabled
|
||||||
|
},
|
||||||
|
SET_BANNED_URLS: (state, urls) => {
|
||||||
|
state.bannedUrls = urls.map(el => { return { url: el } })
|
||||||
|
},
|
||||||
|
SET_TOTAL_URLS_COUNT: (state, count) => {
|
||||||
|
state.totalUrlsCount = count
|
||||||
|
},
|
||||||
|
SET_LOADING: (state, status) => {
|
||||||
|
state.loading = status
|
||||||
|
},
|
||||||
|
SET_PAGE: (state, page) => {
|
||||||
|
state.currentPage = page
|
||||||
|
},
|
||||||
|
SET_SEARCH_QUERY: (state, query) => {
|
||||||
|
state.searchQuery = query
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
async EnableMediaProxy({ dispatch, getters, state }) {
|
||||||
|
const configs = [{
|
||||||
|
group: ':pleroma',
|
||||||
|
key: ':media_proxy',
|
||||||
|
value: [
|
||||||
|
{ tuple: [':enabled', true] },
|
||||||
|
{ tuple: [':invalidation', [{ tuple: [':enabled', true] }]] }
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
await updateSettings(configs, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
dispatch('FetchMediaProxySetting')
|
||||||
|
},
|
||||||
|
async FetchMediaProxySetting({ commit, getters }) {
|
||||||
|
const { data } = await fetchSettings(getters.authHost, getters.token)
|
||||||
|
const mediaProxySettings = data.configs.find(el => el.key === ':media_proxy')
|
||||||
|
? data.configs.find(el => el.key === ':media_proxy').value
|
||||||
|
: []
|
||||||
|
const mediaProxyEnabled = mediaProxySettings.find(el => el.tuple[0] === ':enabled')
|
||||||
|
? mediaProxySettings.find(el => el.tuple[0] === ':enabled').tuple[1]
|
||||||
|
: false
|
||||||
|
|
||||||
|
commit('MEDIA_PROXY_ENABLED', mediaProxyEnabled)
|
||||||
|
},
|
||||||
|
async ListBannedUrls({ commit, getters, state }, { page }) {
|
||||||
|
commit('SET_LOADING', true)
|
||||||
|
const response = await listBannedUrls(page, state.pageSize, getters.authHost, getters.token)
|
||||||
|
commit('SET_BANNED_URLS', response.data.urls)
|
||||||
|
commit('SET_TOTAL_URLS_COUNT', response.data.count)
|
||||||
|
commit('SET_PAGE', page)
|
||||||
|
commit('SET_LOADING', false)
|
||||||
|
},
|
||||||
|
async PurgeUrls({ dispatch, getters, state }, { urls, ban }) {
|
||||||
|
await purgeUrls(urls, ban, getters.authHost, getters.token)
|
||||||
|
Message({
|
||||||
|
message: i18n.t('mediaProxyCache.evictedMessage'),
|
||||||
|
type: 'success',
|
||||||
|
duration: 5 * 1000
|
||||||
|
})
|
||||||
|
if (ban && state.searchQuery.length === 0) {
|
||||||
|
dispatch('ListBannedUrls', { page: state.currentPage })
|
||||||
|
} else if (ban) {
|
||||||
|
dispatch('SearchUrls', { query: state.searchQuery, page: state.currentPage })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async RemoveBannedUrls({ dispatch, getters, state }, urls) {
|
||||||
|
await removeBannedUrls(urls, getters.authHost, getters.token)
|
||||||
|
if (state.searchQuery.length === 0) {
|
||||||
|
dispatch('ListBannedUrls', { page: state.currentPage })
|
||||||
|
} else {
|
||||||
|
dispatch('SearchUrls', { query: state.searchQuery, page: state.currentPage })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async SearchUrls({ commit, dispatch, getters, state }, { query, page }) {
|
||||||
|
if (query.length === 0) {
|
||||||
|
commit('SET_SEARCH_QUERY', query)
|
||||||
|
dispatch('ListBannedUrls', { page })
|
||||||
|
} else {
|
||||||
|
commit('SET_LOADING', true)
|
||||||
|
commit('SET_SEARCH_QUERY', query)
|
||||||
|
|
||||||
|
const response = await searchBannedUrls(query, page, state.pageSize, getters.authHost, getters.token)
|
||||||
|
commit('SET_BANNED_URLS', response.data.urls)
|
||||||
|
commit('SET_TOTAL_URLS_COUNT', response.data.count)
|
||||||
|
commit('SET_PAGE', page)
|
||||||
|
commit('SET_LOADING', false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mediaProxyCache
|
|
@ -1,25 +1,12 @@
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
export const checkPartialUpdate = (settings, updatedSettings, description) => {
|
export const getBooleanValue = value => {
|
||||||
return Object.keys(updatedSettings).reduce((acc, group) => {
|
if (value === 'true') {
|
||||||
acc[group] = Object.keys(updatedSettings[group]).reduce((acc, key) => {
|
return true
|
||||||
if (!partialUpdate(group, key)) {
|
} else if (value === 'false') {
|
||||||
const updated = Object.keys(settings[group][key]).reduce((acc, settingName) => {
|
return false
|
||||||
const setting = description
|
}
|
||||||
.find(element => element.group === group && element.key === key).children
|
return value
|
||||||
.find(child => child.key === settingName)
|
|
||||||
const type = setting ? setting.type : ''
|
|
||||||
acc[settingName] = [type, settings[group][key][settingName]]
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
acc[key] = updated
|
|
||||||
return acc
|
|
||||||
}
|
|
||||||
acc[key] = updatedSettings[group][key]
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCurrentValue = (type, value, path) => {
|
const getCurrentValue = (type, value, path) => {
|
||||||
|
@ -41,7 +28,7 @@ const getCurrentValue = (type, value, path) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getValueWithoutKey = (key, [type, value]) => {
|
const getValueWithoutKey = (key, [type, value]) => {
|
||||||
if (type === 'atom' && value.length > 1) {
|
if (prependWithColon(type, value)) {
|
||||||
return `:${value}`
|
return `:${value}`
|
||||||
} else if (key === ':backends') {
|
} else if (key === ':backends') {
|
||||||
const index = value.findIndex(el => el === ':ex_syslogger')
|
const index = value.findIndex(el => el === ':ex_syslogger')
|
||||||
|
@ -63,39 +50,56 @@ export const parseNonTuples = (key, value) => {
|
||||||
return updated
|
return updated
|
||||||
}
|
}
|
||||||
if (key === ':args') {
|
if (key === ':args') {
|
||||||
if (typeof value === 'string') {
|
return typeof value === 'string' ? [value] : value
|
||||||
return [value]
|
|
||||||
}
|
|
||||||
const index = value.findIndex(el => typeof el === 'object' && el.tuple.includes('implode'))
|
|
||||||
const updated = value.map((el, i) => i === index ? 'implode' : el)
|
|
||||||
return updated
|
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
// REFACTOR
|
// REFACTOR
|
||||||
export const parseTuples = (tuples, key) => {
|
export const parseTuples = (tuples, key) => {
|
||||||
return tuples.reduce((accum, item) => {
|
return tuples.reduce((accum, item) => {
|
||||||
if (key === ':rate_limit') {
|
if (key === ':rate_limit' ||
|
||||||
accum[item.tuple[0]] = Array.isArray(item.tuple[1])
|
(key === 'Pleroma.Web.Endpoint.MetricsExporter' && item.tuple[0] === ':auth')) {
|
||||||
? item.tuple[1].map(el => el.tuple)
|
const getValue = () => {
|
||||||
: item.tuple[1].tuple
|
if (typeof item.tuple[1] === 'boolean') {
|
||||||
|
return item.tuple[1]
|
||||||
|
} else if (Array.isArray(item.tuple[1])) {
|
||||||
|
return item.tuple[1].map(el => el.tuple)
|
||||||
|
} else {
|
||||||
|
return item.tuple[1].tuple
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accum[item.tuple[0]] = getValue()
|
||||||
} else if (item.tuple[0] === ':mascots') {
|
} else if (item.tuple[0] === ':mascots') {
|
||||||
accum[item.tuple[0]] = item.tuple[1].reduce((acc, mascot) => {
|
accum[item.tuple[0]] = item.tuple[1].reduce((acc, mascot) => {
|
||||||
return [...acc, { [mascot.tuple[0]]: { ...mascot.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}]
|
return [...acc, { [mascot.tuple[0]]: { ...mascot.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}]
|
||||||
}, [])
|
}, [])
|
||||||
} else if (Array.isArray(item.tuple[1]) &&
|
} else if (Array.isArray(item.tuple[1]) &&
|
||||||
(item.tuple[0] === ':groups' || item.tuple[0] === ':replace' || item.tuple[0] === ':retries')) {
|
(item.tuple[0] === ':groups' ||
|
||||||
accum[item.tuple[0]] = item.tuple[1].reduce((acc, group) => {
|
item.tuple[0] === ':replace' ||
|
||||||
return [...acc, { [group.tuple[0]]: { value: group.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}]
|
item.tuple[0] === ':retries' ||
|
||||||
}, [])
|
item.tuple[0] === ':timeout' ||
|
||||||
} else if (item.tuple[0] === ':crontab') {
|
(item.tuple[0] === ':headers' && key === 'Pleroma.Web.MediaProxy.Invalidation.Http') ||
|
||||||
accum[item.tuple[0]] = item.tuple[1].reduce((acc, group) => {
|
item.tuple[0] === ':crontab' ||
|
||||||
return { ...acc, [group.tuple[1]]: group.tuple[0] }
|
item.tuple[0] === ':transparency_exclusions' ||
|
||||||
}, {})
|
item.tuple[0] === ':quarantined_instances' ||
|
||||||
} else if (item.tuple[0] === ':match_actor') {
|
key === ':mrf_simple')) {
|
||||||
accum[item.tuple[0]] = Object.keys(item.tuple[1]).reduce((acc, regex) => {
|
if (item.tuple[0] === ':crontab') {
|
||||||
return [...acc, { [regex]: { value: item.tuple[1][regex], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}]
|
accum[item.tuple[0]] = item.tuple[1].reduce((acc, group) => {
|
||||||
}, [])
|
return [...acc, { [group.tuple[1]]: { value: group.tuple[0], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}]
|
||||||
|
}, [])
|
||||||
|
} else {
|
||||||
|
accum[item.tuple[0]] = item.tuple[1].reduce((acc, group) => {
|
||||||
|
/**
|
||||||
|
* The ':quarantined_instances' and ':mrf_simple' settings have changed to a list of tuples instead of a list of strings.
|
||||||
|
* This is to have backwards compatibility for instances that still use strings.
|
||||||
|
*/
|
||||||
|
if (typeof group === 'string') {
|
||||||
|
return [...acc, group]
|
||||||
|
} else {
|
||||||
|
return [...acc, { [group.tuple[0]]: { value: group.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}]
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
}
|
||||||
} else if (item.tuple[0] === ':icons') {
|
} else if (item.tuple[0] === ':icons') {
|
||||||
accum[item.tuple[0]] = item.tuple[1].map(icon => {
|
accum[item.tuple[0]] = item.tuple[1].map(icon => {
|
||||||
return Object.keys(icon).map(name => {
|
return Object.keys(icon).map(name => {
|
||||||
|
@ -104,19 +108,27 @@ export const parseTuples = (tuples, key) => {
|
||||||
}, [])
|
}, [])
|
||||||
} else if (item.tuple[0] === ':prune') {
|
} else if (item.tuple[0] === ':prune') {
|
||||||
accum[item.tuple[0]] = item.tuple[1] === ':disabled' ? [item.tuple[1]] : item.tuple[1].tuple
|
accum[item.tuple[0]] = item.tuple[1] === ':disabled' ? [item.tuple[1]] : item.tuple[1].tuple
|
||||||
} else if (item.tuple[0] === ':proxy_url') {
|
} else if (item.tuple[0] === ':sender') {
|
||||||
accum[item.tuple[0]] = parseProxyUrl(item.tuple[1])
|
accum[item.tuple[0]] = parseStringOrTupleValue(item.tuple[0], item.tuple[1])
|
||||||
} else if (item.tuple[0] === ':args') {
|
} else if (item.tuple[0] === ':args') {
|
||||||
accum[item.tuple[0]] = parseNonTuples(item.tuple[0], item.tuple[1])
|
accum[item.tuple[0]] = parseNonTuples(item.tuple[0], item.tuple[1])
|
||||||
} else if (Array.isArray(item.tuple[1]) &&
|
} else if (item.tuple[0] === ':ip_whitelist') {
|
||||||
(typeof item.tuple[1][0] === 'object' && !Array.isArray(item.tuple[1][0])) && item.tuple[1][0]['tuple']) {
|
accum[item.tuple[0]] = item.tuple[1].map(ip => typeof ip === 'string' ? ip : ip.tuple.join('.'))
|
||||||
|
} else if (Array.isArray(item.tuple[1]) && (item.tuple[1][0] !== null &&
|
||||||
|
typeof item.tuple[1][0] === 'object' && !Array.isArray(item.tuple[1][0])) && item.tuple[1][0]['tuple']) {
|
||||||
accum[item.tuple[0]] = parseTuples(item.tuple[1], item.tuple[0])
|
accum[item.tuple[0]] = parseTuples(item.tuple[1], item.tuple[0])
|
||||||
} else if (Array.isArray(item.tuple[1])) {
|
} else if (Array.isArray(item.tuple[1])) {
|
||||||
accum[item.tuple[0]] = item.tuple[1]
|
accum[item.tuple[0]] = item.tuple[1]
|
||||||
} else if (item.tuple[0] === ':ip') {
|
} else if (item.tuple[0] === ':ip') {
|
||||||
accum[item.tuple[0]] = item.tuple[1].tuple.join('.')
|
accum[item.tuple[0]] = item.tuple[1].tuple.join('.')
|
||||||
} else if (item.tuple[1] && typeof item.tuple[1] === 'object') {
|
} else if (item.tuple[1] && typeof item.tuple[1] === 'object') {
|
||||||
accum[item.tuple[0]] = parseObject(item.tuple[1])
|
if (item.tuple[0] === ':params' || item.tuple[0] === ':match_actor') {
|
||||||
|
accum[item.tuple[0]] = Object.keys(item.tuple[1]).reduce((acc, key) => {
|
||||||
|
return [...acc, { [key]: { value: item.tuple[1][key], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}]
|
||||||
|
}, [])
|
||||||
|
} else {
|
||||||
|
accum[item.tuple[0]] = parseObject(item.tuple[1])
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
accum[item.tuple[0]] = item.tuple[1]
|
accum[item.tuple[0]] = item.tuple[1]
|
||||||
}
|
}
|
||||||
|
@ -131,22 +143,34 @@ const parseObject = object => {
|
||||||
}, {})
|
}, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseProxyUrl = value => {
|
const parseStringOrTupleValue = (key, value) => {
|
||||||
if (value && !Array.isArray(value) &&
|
if (key === ':proxy_url') {
|
||||||
typeof value === 'object' &&
|
if (value && !Array.isArray(value) &&
|
||||||
value.tuple.length === 3 &&
|
typeof value === 'object' &&
|
||||||
value.tuple[0] === ':socks5') {
|
value.tuple.length === 3 &&
|
||||||
const [, host, port] = value.tuple
|
value.tuple[0] === ':socks5') {
|
||||||
return { socks5: true, host, port }
|
const [, host, port] = value.tuple
|
||||||
} else if (typeof value === 'string') {
|
return { socks5: true, host, port }
|
||||||
const [host, port] = value.split(':')
|
} else if (typeof value === 'string') {
|
||||||
return { socks5: false, host, port }
|
const [host, port] = value.split(':')
|
||||||
|
return { socks5: false, host, port }
|
||||||
|
}
|
||||||
|
return { socks5: false, host: null, port: null }
|
||||||
|
} else if (key === ':sender') {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
return { email: value }
|
||||||
|
} else if (value &&
|
||||||
|
typeof value === 'object' &&
|
||||||
|
value.tuple.length === 2) {
|
||||||
|
const [nickname, email] = value.tuple
|
||||||
|
return { nickname, email }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return { socks5: false, host: null, port: null }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const partialUpdate = (group, key) => {
|
const prependWithColon = (type, value) => {
|
||||||
return !(group === ':auto_linker' && key === ':opts')
|
return (type === 'atom' && value.length > 0) ||
|
||||||
|
(Array.isArray(type) && type.includes('boolean') && type.includes('atom') && typeof value === 'string')
|
||||||
}
|
}
|
||||||
|
|
||||||
export const processNested = (valueForState, valueForUpdatedSettings, group, parentKey, parents, settings, updatedSettings) => {
|
export const processNested = (valueForState, valueForUpdatedSettings, group, parentKey, parents, settings, updatedSettings) => {
|
||||||
|
@ -226,44 +250,76 @@ export const wrapUpdatedSettings = (group, settings, currentState) => {
|
||||||
const wrapValues = (settings, currentState) => {
|
const wrapValues = (settings, currentState) => {
|
||||||
return Object.keys(settings).map(setting => {
|
return Object.keys(settings).map(setting => {
|
||||||
const [type, value] = settings[setting]
|
const [type, value] = settings[setting]
|
||||||
if (
|
if (type === 'keyword' ||
|
||||||
type === 'keyword' ||
|
(Array.isArray(type) && (
|
||||||
type.includes('keyword') ||
|
type.includes('keyword') ||
|
||||||
type.includes('tuple') && type.includes('list') ||
|
(type.includes('tuple') && type.includes('list'))
|
||||||
setting === ':replace'
|
))
|
||||||
) {
|
) {
|
||||||
return { 'tuple': [setting, wrapValues(value, currentState)] }
|
return { 'tuple': [setting, wrapValues(value, currentState)] }
|
||||||
} else if (type === 'atom' && value.length > 0) {
|
} else if (prependWithColon(type, value)) {
|
||||||
return { 'tuple': [setting, `:${value}`] }
|
return { 'tuple': [setting, `:${value}`] }
|
||||||
} else if (type.includes('tuple') && (type.includes('string') || type.includes('atom'))) {
|
} else if (type.includes('tuple') &&
|
||||||
return typeof value === 'string'
|
(type.includes('string') || type.includes('atom') || type.includes('boolean'))) {
|
||||||
|
return typeof value === 'string' || typeof value === 'boolean'
|
||||||
? { 'tuple': [setting, value] }
|
? { 'tuple': [setting, value] }
|
||||||
: { 'tuple': [setting, { 'tuple': value }] }
|
: { 'tuple': [setting, { 'tuple': value }] }
|
||||||
} else if (type === 'reversed_tuple') {
|
} else if (type === 'reversed_tuple') {
|
||||||
return { 'tuple': [value, setting] }
|
return { 'tuple': [value, setting] }
|
||||||
} else if (type === 'map') {
|
} else if (type === 'map') {
|
||||||
const mapValue = Object.keys(value).reduce((acc, key) => {
|
const mapValue = Object.keys(value).reduce((acc, key) => {
|
||||||
acc[key] = setting === ':match_actor' ? value[key] : value[key][1]
|
acc[key] = value[key][1]
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
const mapCurrentState = setting === ':match_actor'
|
return { 'tuple': [setting, { ...currentState[setting], ...mapValue }] }
|
||||||
? currentState[setting].reduce((acc, element) => {
|
} else if (type.includes('map') && !type.includes('list')) {
|
||||||
return { ...acc, ...{ [Object.keys(element)[0]]: Object.values(element)[0].value }}
|
const mapValue = Object.keys(value).reduce((acc, key) => {
|
||||||
}, {})
|
acc[key] = value[key][1]
|
||||||
: currentState[setting]
|
return acc
|
||||||
return { 'tuple': [setting, { ...mapCurrentState, ...mapValue }] }
|
}, {})
|
||||||
|
return { 'tuple': [setting, mapValue] }
|
||||||
} else if (setting === ':ip') {
|
} else if (setting === ':ip') {
|
||||||
const ip = value.split('.').map(s => parseInt(s, 10))
|
const ip = value.split('.').map(s => parseInt(s, 10))
|
||||||
return { 'tuple': [setting, { 'tuple': ip }] }
|
return { 'tuple': [setting, { 'tuple': ip }] }
|
||||||
} else if (setting === ':args') {
|
|
||||||
const index = value.findIndex(el => el === 'implode')
|
|
||||||
const updatedArray = value.slice()
|
|
||||||
if (index !== -1) {
|
|
||||||
updatedArray[index] = { 'tuple': ['implode', '1'] }
|
|
||||||
}
|
|
||||||
return { 'tuple': [setting, updatedArray] }
|
|
||||||
} else {
|
} else {
|
||||||
return { 'tuple': [setting, value] }
|
return { 'tuple': [setting, value] }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const formSearchObject = description => {
|
||||||
|
const parseNestedSettings = (description, label, key) => description.reduce((acc, setting) => {
|
||||||
|
const searchArray = _.compact([setting.key, setting.label, setting.description]).map(el => el.toLowerCase())
|
||||||
|
const resultObject = { label: setting.label, key: setting.key || setting.group, groupKey: key, groupLabel: label, search: searchArray }
|
||||||
|
if (setting.children) {
|
||||||
|
const updatedAcc = [...acc, resultObject]
|
||||||
|
return [...updatedAcc, ...parseNestedSettings(setting.children, label, key)]
|
||||||
|
}
|
||||||
|
return [...acc, resultObject]
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const processedDescription = description.reduce((acc, setting) => {
|
||||||
|
const searchArray = _.compact([setting.key, setting.label, setting.description]).map(el => el.toLowerCase())
|
||||||
|
const resultObject = { label: setting.label, key: setting.key || setting.group, groupKey: setting.key || setting.group, groupLabel: setting.label, search: searchArray }
|
||||||
|
if (setting.children) {
|
||||||
|
const updatedAcc = !setting.key && setting.group === ':pleroma' ? acc : [...acc, resultObject]
|
||||||
|
return [...updatedAcc, ...parseNestedSettings(setting.children, setting.label, setting.key || setting.group)]
|
||||||
|
}
|
||||||
|
return !setting.key && setting.group === ':pleroma' ? acc : [...acc, resultObject]
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const searchDataForEditableDocs = [{
|
||||||
|
groupKey: ':instance_panel',
|
||||||
|
groupLabel: 'Instance Panel',
|
||||||
|
key: ':instance_panel',
|
||||||
|
label: 'Instance Panel',
|
||||||
|
search: ['Instance Panel', ':instance_panel']
|
||||||
|
}, {
|
||||||
|
groupKey: ':terms_of_services',
|
||||||
|
groupLabel: 'Terms of Services',
|
||||||
|
key: ':terms_of_services',
|
||||||
|
label: 'Terms of Services',
|
||||||
|
search: ['Terms of Services', ':terms_of_services']
|
||||||
|
}]
|
||||||
|
return processedDescription.concat(searchDataForEditableDocs)
|
||||||
|
}
|
||||||
|
|
|
@ -46,15 +46,10 @@ const permission = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
GenerateRoutes({ commit }, data) {
|
GenerateRoutes({ commit }, { roles, _routesWithSettings }) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const { roles } = data
|
const routes = _routesWithSettings || asyncRouterMap
|
||||||
let accessedRouters
|
const accessedRouters = roles.includes('admin') ? routes : filterAsyncRouter(asyncRouterMap, roles)
|
||||||
if (roles.includes('admin')) {
|
|
||||||
accessedRouters = asyncRouterMap
|
|
||||||
} else {
|
|
||||||
accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
|
|
||||||
}
|
|
||||||
commit('SET_ROUTERS', accessedRouters)
|
commit('SET_ROUTERS', accessedRouters)
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
|
|
|
@ -13,19 +13,18 @@ const relays = {
|
||||||
state.fetchedRelays = relays
|
state.fetchedRelays = relays
|
||||||
},
|
},
|
||||||
ADD_RELAY: (state, relay) => {
|
ADD_RELAY: (state, relay) => {
|
||||||
state.fetchedRelays = [...state.fetchedRelays, relay]
|
state.fetchedRelays = [...state.fetchedRelays, { actor: relay }]
|
||||||
},
|
},
|
||||||
DELETE_RELAY: (state, relay) => {
|
DELETE_RELAY: (state, relay) => {
|
||||||
state.fetchedRelays = state.fetchedRelays.filter(fetchedRelay => fetchedRelay !== relay)
|
state.fetchedRelays = state.fetchedRelays.filter(fetchedRelay => fetchedRelay.actor !== relay)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async FetchRelays({ commit, getters }) {
|
async FetchRelays({ commit, getters }) {
|
||||||
commit('SET_LOADING', true)
|
commit('SET_LOADING', true)
|
||||||
|
|
||||||
const response = await fetchRelays(getters.authHost, getters.token)
|
const { data } = await fetchRelays(getters.authHost, getters.token)
|
||||||
|
commit('SET_RELAYS', data.relays)
|
||||||
commit('SET_RELAYS', response.data.relays)
|
|
||||||
commit('SET_LOADING', false)
|
commit('SET_LOADING', false)
|
||||||
},
|
},
|
||||||
async AddRelay({ commit, dispatch, getters }, relay) {
|
async AddRelay({ commit, dispatch, getters }, relay) {
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
import { changeState, fetchReports, createNote, deleteNote } from '@/api/reports'
|
import { changeState, fetchReports, fetchSingleReport, createNote, deleteNote } from '@/api/reports'
|
||||||
|
import {
|
||||||
|
activateUsers,
|
||||||
|
deactivateUsers,
|
||||||
|
deleteUsers,
|
||||||
|
tagUser,
|
||||||
|
untagUser
|
||||||
|
} from '@/api/users'
|
||||||
|
|
||||||
const reports = {
|
const reports = {
|
||||||
state: {
|
state: {
|
||||||
fetchedReports: [],
|
|
||||||
totalReportsCount: 0,
|
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
|
fetchedReports: [],
|
||||||
|
loading: true,
|
||||||
|
loadingSingleReport: true,
|
||||||
|
openReportsCount: 0,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
|
singleReport: {},
|
||||||
stateFilter: '',
|
stateFilter: '',
|
||||||
loading: true
|
totalReportsCount: 0
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
SET_LAST_REPORT_ID: (state, id) => {
|
SET_LAST_REPORT_ID: (state, id) => {
|
||||||
|
@ -16,6 +26,9 @@ const reports = {
|
||||||
SET_LOADING: (state, status) => {
|
SET_LOADING: (state, status) => {
|
||||||
state.loading = status
|
state.loading = status
|
||||||
},
|
},
|
||||||
|
SET_OPEN_REPORTS_COUNT: (state, total) => {
|
||||||
|
state.openReportsCount = total
|
||||||
|
},
|
||||||
SET_PAGE: (state, page) => {
|
SET_PAGE: (state, page) => {
|
||||||
state.currentPage = page
|
state.currentPage = page
|
||||||
},
|
},
|
||||||
|
@ -27,22 +40,122 @@ const reports = {
|
||||||
},
|
},
|
||||||
SET_REPORTS_FILTER: (state, filter) => {
|
SET_REPORTS_FILTER: (state, filter) => {
|
||||||
state.stateFilter = filter
|
state.stateFilter = filter
|
||||||
|
},
|
||||||
|
SET_SINGLE_REPORT: (state, report) => {
|
||||||
|
state.singleReport = report
|
||||||
|
},
|
||||||
|
SET_SINGLE_REPORT_LOADING: (state, status) => {
|
||||||
|
state.loadingSingleReport = status
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async ChangeReportState({ commit, getters, state }, reportsData) {
|
async ActivateUserFromReports({ commit, dispatch, getters, state }, { user, reportId }) {
|
||||||
changeState(reportsData, getters.authHost, getters.token)
|
try {
|
||||||
|
await activateUsers([user.nickname], getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReports = state.fetchedReports.map(report => {
|
||||||
|
const updatedAccount = { ...user, is_active: true }
|
||||||
|
return report.id === reportId ? { ...report, account: updatedAccount } : report
|
||||||
|
})
|
||||||
|
commit('SET_REPORTS', updatedReports)
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
|
async ActivateUserFromReportShow({ commit, dispatch, getters, state }, user) {
|
||||||
|
try {
|
||||||
|
await activateUsers([user.nickname], getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReport = { ...state.singleReport, account: { ...user, is_active: true }}
|
||||||
|
commit('SET_SINGLE_REPORT', updatedReport)
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
|
async AddTagFromReports({ commit, dispatch, getters, state }, { user, tag, reportId }) {
|
||||||
|
try {
|
||||||
|
await tagUser([user.nickname], [tag], getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReports = state.fetchedReports.map(report => {
|
||||||
|
const updatedAccount = { ...user, tags: [...user.tags, tag] }
|
||||||
|
return report.id === reportId ? { ...report, account: updatedAccount } : report
|
||||||
|
})
|
||||||
|
commit('SET_REPORTS', updatedReports)
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
|
async AddTagFromReportsFromReportShow({ commit, dispatch, getters, state }, { user, tag }) {
|
||||||
|
try {
|
||||||
|
await tagUser([user.nickname], [tag], getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReport = { ...state.singleReport, account: { ...user, tags: [...user.tags, tag] }}
|
||||||
|
commit('SET_SINGLE_REPORT', updatedReport)
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
|
async ChangeReportState({ commit, dispatch, getters, state }, reportsData) {
|
||||||
|
try {
|
||||||
|
await changeState(reportsData, getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReports = state.fetchedReports.map(report => {
|
||||||
|
const updatedReportsIds = reportsData.map(({ id }) => id)
|
||||||
|
return updatedReportsIds.includes(report.id) ? { ...report, state: reportsData[0].state } : report
|
||||||
|
})
|
||||||
|
|
||||||
const updatedReports = state.fetchedReports.map(report => {
|
commit('SET_REPORTS', updatedReports)
|
||||||
const updatedReportsIds = reportsData.map(({ id }) => id)
|
dispatch('FetchOpenReportsCount')
|
||||||
return updatedReportsIds.includes(report.id) ? { ...report, state: reportsData[0].state } : report
|
}
|
||||||
})
|
|
||||||
|
|
||||||
commit('SET_REPORTS', updatedReports)
|
|
||||||
},
|
},
|
||||||
ClearFetchedReports({ commit }) {
|
ClearFetchedReports({ commit }) {
|
||||||
commit('SET_REPORTS', [])
|
commit('SET_REPORTS', [])
|
||||||
},
|
},
|
||||||
|
async DeactivateUserFromReports({ commit, dispatch, getters, state }, { user, reportId }) {
|
||||||
|
try {
|
||||||
|
await deactivateUsers([user.nickname], getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReports = state.fetchedReports.map(report => {
|
||||||
|
const updatedAccount = { ...user, is_active: false }
|
||||||
|
return report.id === reportId ? { ...report, account: updatedAccount } : report
|
||||||
|
})
|
||||||
|
commit('SET_REPORTS', updatedReports)
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
|
async DeactivateUserFromReportShow({ commit, dispatch, getters, state }, user) {
|
||||||
|
try {
|
||||||
|
await deactivateUsers([user.nickname], getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReport = { ...state.singleReport, account: { ...user, is_active: false }}
|
||||||
|
commit('SET_SINGLE_REPORT', updatedReport)
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
|
async DeleteUserFromReports({ commit, dispatch, getters, state }, { user, reportId }) {
|
||||||
|
try {
|
||||||
|
await deleteUsers([user.nickname], getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReports = state.fetchedReports.map(report => {
|
||||||
|
const updatedAccount = { ...user, is_active: false }
|
||||||
|
return report.id === reportId ? { ...report, account: updatedAccount } : report
|
||||||
|
})
|
||||||
|
commit('SET_REPORTS', updatedReports)
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
async FetchReports({ commit, getters, state }, page) {
|
async FetchReports({ commit, getters, state }, page) {
|
||||||
commit('SET_LOADING', true)
|
commit('SET_LOADING', true)
|
||||||
const { data } = await fetchReports(state.stateFilter, page, state.pageSize, getters.authHost, getters.token)
|
const { data } = await fetchReports(state.stateFilter, page, state.pageSize, getters.authHost, getters.token)
|
||||||
|
@ -52,7 +165,46 @@ const reports = {
|
||||||
commit('SET_PAGE', page)
|
commit('SET_PAGE', page)
|
||||||
commit('SET_LOADING', false)
|
commit('SET_LOADING', false)
|
||||||
},
|
},
|
||||||
SetFilter({ commit }, filter) {
|
async FetchSingleReport({ commit, getters }, id) {
|
||||||
|
commit('SET_SINGLE_REPORT_LOADING', true)
|
||||||
|
const { data } = await fetchSingleReport(id, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
commit('SET_SINGLE_REPORT', data)
|
||||||
|
commit('SET_SINGLE_REPORT_LOADING', false)
|
||||||
|
},
|
||||||
|
async FetchOpenReportsCount({ commit, getters, state }) {
|
||||||
|
commit('SET_LOADING', true)
|
||||||
|
const { data } = await fetchReports('open', state.currentPage, state.pageSize, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
commit('SET_OPEN_REPORTS_COUNT', data.total)
|
||||||
|
commit('SET_LOADING', false)
|
||||||
|
},
|
||||||
|
async RemoveTagFromReports({ commit, dispatch, getters, state }, { user, tag, reportId }) {
|
||||||
|
try {
|
||||||
|
await untagUser([user.nickname], [tag], getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReports = state.fetchedReports.map(report => {
|
||||||
|
const updatedAccount = { ...user, tags: user.tags.filter(userTag => userTag !== tag) }
|
||||||
|
return report.id === reportId ? { ...report, account: updatedAccount } : report
|
||||||
|
})
|
||||||
|
commit('SET_REPORTS', updatedReports)
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
|
async RemoveTagFromReportsFromReportShow({ commit, dispatch, getters, state }, { user, tag }) {
|
||||||
|
try {
|
||||||
|
await untagUser([user.nickname], [tag], getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
const updatedReport = { ...state.singleReport, account: { ...user, tags: user.tags.filter(userTag => userTag !== tag) }}
|
||||||
|
commit('SET_SINGLE_REPORT', updatedReport)
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
|
SetReportsFilter({ commit }, filter) {
|
||||||
commit('SET_REPORTS_FILTER', filter)
|
commit('SET_REPORTS_FILTER', filter)
|
||||||
},
|
},
|
||||||
CreateReportNote({ commit, getters, state, rootState }, { content, reportID }) {
|
CreateReportNote({ commit, getters, state, rootState }, { content, reportID }) {
|
||||||
|
@ -61,9 +213,8 @@ const reports = {
|
||||||
const optimisticNote = {
|
const optimisticNote = {
|
||||||
user: {
|
user: {
|
||||||
avatar: rootState.user.avatar,
|
avatar: rootState.user.avatar,
|
||||||
display_name: rootState.user.name,
|
nickname: rootState.user.name,
|
||||||
url: `${rootState.user.authHost}/${rootState.user.name}`,
|
id: rootState.user.id
|
||||||
acct: rootState.user.name
|
|
||||||
},
|
},
|
||||||
content: content,
|
content: content,
|
||||||
created_at: new Date().getTime()
|
created_at: new Date().getTime()
|
||||||
|
|
|
@ -1,37 +1,60 @@
|
||||||
import { fetchDescription, fetchSettings, removeSettings, restartApp, updateSettings } from '@/api/settings'
|
import {
|
||||||
import { checkPartialUpdate, parseNonTuples, parseTuples, valueHasTuples, wrapUpdatedSettings } from './normalizers'
|
deleteInstanceDocument,
|
||||||
|
fetchDescription,
|
||||||
|
fetchFrontends,
|
||||||
|
fetchSettings,
|
||||||
|
getInstanceDocument,
|
||||||
|
installFrontend,
|
||||||
|
removeSettings,
|
||||||
|
updateInstanceDocument,
|
||||||
|
updateSettings } from '@/api/settings'
|
||||||
|
import { formSearchObject, parseNonTuples, parseTuples, valueHasTuples, wrapUpdatedSettings } from './normalizers'
|
||||||
|
import { tabs } from '../../utils/tabs'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
const settings = {
|
const settings = {
|
||||||
state: {
|
state: {
|
||||||
activeTab: 'instance',
|
|
||||||
configDisabled: true,
|
configDisabled: true,
|
||||||
|
frontends: [],
|
||||||
db: {},
|
db: {},
|
||||||
description: [],
|
description: [],
|
||||||
|
instancePanel: '',
|
||||||
loading: true,
|
loading: true,
|
||||||
needReboot: false,
|
searchData: {},
|
||||||
|
searchQuery: '',
|
||||||
settings: {},
|
settings: {},
|
||||||
|
tabs: [],
|
||||||
|
termsOfServices: '',
|
||||||
updatedSettings: {}
|
updatedSettings: {}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
CLEAR_UPDATED_SETTINGS: (state) => {
|
CLEAR_UPDATED_SETTINGS: (state) => {
|
||||||
state.updatedSettings = {}
|
state.updatedSettings = {}
|
||||||
},
|
},
|
||||||
|
SET_INSTANCE_PANEL: (state, data) => {
|
||||||
|
state.instancePanel = data
|
||||||
|
},
|
||||||
REMOVE_SETTING_FROM_UPDATED: (state, { group, key, subkeys }) => {
|
REMOVE_SETTING_FROM_UPDATED: (state, { group, key, subkeys }) => {
|
||||||
if (_.get(state.updatedSettings, [group, key, subkeys[0]])) {
|
if (_.get(state.updatedSettings, [group, key, subkeys[0]])) {
|
||||||
const { [subkeys[0]]: value, ...updatedSettings } = state.updatedSettings[group][key]
|
const { [subkeys[0]]: value, ...updatedSettings } = state.updatedSettings[group][key]
|
||||||
state.updatedSettings = updatedSettings
|
state.updatedSettings = updatedSettings
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SET_ACTIVE_TAB: (state, tab) => {
|
|
||||||
state.activeTab = tab
|
|
||||||
},
|
|
||||||
SET_DESCRIPTION: (state, data) => {
|
SET_DESCRIPTION: (state, data) => {
|
||||||
state.description = data
|
state.description = data
|
||||||
},
|
},
|
||||||
|
SET_FRONTENDS: (state, data) => {
|
||||||
|
state.frontends = data
|
||||||
|
},
|
||||||
SET_LOADING: (state, status) => {
|
SET_LOADING: (state, status) => {
|
||||||
state.loading = status
|
state.loading = status
|
||||||
},
|
},
|
||||||
|
SET_SEARCH: (state, searchObject) => {
|
||||||
|
state.searchData = searchObject
|
||||||
|
},
|
||||||
|
SET_SEARCH_QUERY: (state, query) => {
|
||||||
|
state.searchQuery = query
|
||||||
|
},
|
||||||
SET_SETTINGS: (state, data) => {
|
SET_SETTINGS: (state, data) => {
|
||||||
const newSettings = data.reduce((acc, { group, key, value }) => {
|
const newSettings = data.reduce((acc, { group, key, value }) => {
|
||||||
const parsedValue = valueHasTuples(key, value)
|
const parsedValue = valueHasTuples(key, value)
|
||||||
|
@ -51,8 +74,11 @@ const settings = {
|
||||||
state.settings = newSettings
|
state.settings = newSettings
|
||||||
state.db = newDbSettings
|
state.db = newDbSettings
|
||||||
},
|
},
|
||||||
TOGGLE_REBOOT: (state, needReboot) => {
|
SET_TABS: (state, tabs) => {
|
||||||
state.needReboot = needReboot || false
|
state.tabs = tabs
|
||||||
|
},
|
||||||
|
SET_TERMS_OF_SERVICES: (state, data) => {
|
||||||
|
state.termsOfServices = data
|
||||||
},
|
},
|
||||||
TOGGLE_TABS: (state, status) => {
|
TOGGLE_TABS: (state, status) => {
|
||||||
state.configDisabled = status
|
state.configDisabled = status
|
||||||
|
@ -71,23 +97,45 @@ const settings = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
async FetchFrontends({ commit, getters }) {
|
||||||
|
const { data } = await fetchFrontends(getters.authHost, getters.token)
|
||||||
|
commit('SET_FRONTENDS', data)
|
||||||
|
},
|
||||||
|
async FetchInstanceDocument({ commit, getters }, name) {
|
||||||
|
const { data } = await getInstanceDocument(name, getters.authHost, getters.token)
|
||||||
|
if (name === 'instance-panel') {
|
||||||
|
commit('SET_INSTANCE_PANEL', data)
|
||||||
|
} else {
|
||||||
|
commit('SET_TERMS_OF_SERVICES', data)
|
||||||
|
}
|
||||||
|
},
|
||||||
async FetchSettings({ commit, getters }) {
|
async FetchSettings({ commit, getters }) {
|
||||||
commit('SET_LOADING', true)
|
commit('SET_LOADING', true)
|
||||||
try {
|
try {
|
||||||
const response = await fetchSettings(getters.authHost, getters.token)
|
const settings = await fetchSettings(getters.authHost, getters.token)
|
||||||
const description = await fetchDescription(getters.authHost, getters.token)
|
commit('SET_SETTINGS', settings.data.configs)
|
||||||
commit('SET_DESCRIPTION', description.data)
|
|
||||||
commit('SET_SETTINGS', response.data.configs)
|
const { data } = await fetchDescription(getters.authHost, getters.token)
|
||||||
commit('TOGGLE_REBOOT', response.data.need_reboot)
|
commit('SET_DESCRIPTION', data)
|
||||||
|
const searchObject = formSearchObject(data)
|
||||||
|
commit('SET_SEARCH', searchObject)
|
||||||
|
commit('SET_TABS', tabs)
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
commit('TOGGLE_TABS', true)
|
commit('TOGGLE_TABS', true)
|
||||||
commit('SET_ACTIVE_TAB', 'relays')
|
|
||||||
commit('SET_LOADING', false)
|
commit('SET_LOADING', false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
commit('TOGGLE_TABS', false)
|
commit('TOGGLE_TABS', false)
|
||||||
commit('SET_LOADING', false)
|
commit('SET_LOADING', false)
|
||||||
},
|
},
|
||||||
|
async InstallFrontend({ commit, getters }, { name, ref, file, buildUrl, buildDir }) {
|
||||||
|
const { data } = await installFrontend({ name, ref, file, build_url: buildUrl, build_dir: buildDir }, getters.authHost, getters.token)
|
||||||
|
commit('SET_FRONTENDS', data)
|
||||||
|
},
|
||||||
|
async RemoveInstanceDocument({ dispatch, getters }, name) {
|
||||||
|
await deleteInstanceDocument(name, getters.authHost, getters.token)
|
||||||
|
await dispatch('FetchInstanceDocument', name)
|
||||||
|
},
|
||||||
async RemoveSetting({ commit, getters }, configs) {
|
async RemoveSetting({ commit, getters }, configs) {
|
||||||
await removeSettings(configs, getters.authHost, getters.token)
|
await removeSettings(configs, getters.authHost, getters.token)
|
||||||
const response = await fetchSettings(getters.authHost, getters.token)
|
const response = await fetchSettings(getters.authHost, getters.token)
|
||||||
|
@ -96,17 +144,12 @@ const settings = {
|
||||||
commit('TOGGLE_REBOOT', response.data.need_reboot)
|
commit('TOGGLE_REBOOT', response.data.need_reboot)
|
||||||
commit('REMOVE_SETTING_FROM_UPDATED', { group, key, subkeys: subkeys || [] })
|
commit('REMOVE_SETTING_FROM_UPDATED', { group, key, subkeys: subkeys || [] })
|
||||||
},
|
},
|
||||||
async RestartApplication({ commit, getters }) {
|
SetSearchQuery({ commit }, query) {
|
||||||
await restartApp(getters.authHost, getters.token)
|
commit('SET_SEARCH_QUERY', query)
|
||||||
commit('TOGGLE_REBOOT', false)
|
|
||||||
},
|
|
||||||
SetActiveTab({ commit }, tab) {
|
|
||||||
commit('SET_ACTIVE_TAB', tab)
|
|
||||||
},
|
},
|
||||||
async SubmitChanges({ getters, commit, state }) {
|
async SubmitChanges({ getters, commit, state }) {
|
||||||
const updatedData = checkPartialUpdate(state.settings, state.updatedSettings, state.description)
|
const configs = Object.keys(state.updatedSettings).reduce((acc, group) => {
|
||||||
const configs = Object.keys(updatedData).reduce((acc, group) => {
|
return [...acc, ...wrapUpdatedSettings(group, state.updatedSettings[group], state.settings)]
|
||||||
return [...acc, ...wrapUpdatedSettings(group, updatedData[group], state.settings)]
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
await updateSettings(configs, getters.authHost, getters.token)
|
await updateSettings(configs, getters.authHost, getters.token)
|
||||||
|
@ -115,6 +158,13 @@ const settings = {
|
||||||
commit('TOGGLE_REBOOT', response.data.need_reboot)
|
commit('TOGGLE_REBOOT', response.data.need_reboot)
|
||||||
commit('CLEAR_UPDATED_SETTINGS')
|
commit('CLEAR_UPDATED_SETTINGS')
|
||||||
},
|
},
|
||||||
|
async UpdateInstanceDocs({ commit, getters }, { name, content }) {
|
||||||
|
commit('SET_INSTANCE_PANEL', content)
|
||||||
|
const formData = new FormData()
|
||||||
|
const blob = new Blob([content], { type: 'text/html' })
|
||||||
|
formData.append('file', blob)
|
||||||
|
await updateInstanceDocument(name, formData, getters.authHost, getters.token)
|
||||||
|
},
|
||||||
UpdateSettings({ commit }, { group, key, input, value, type }) {
|
UpdateSettings({ commit }, { group, key, input, value, type }) {
|
||||||
key
|
key
|
||||||
? commit('UPDATE_SETTINGS', { group, key, input, value, type })
|
? commit('UPDATE_SETTINGS', { group, key, input, value, type })
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import { changeStatusScope, deleteStatus, fetchStatuses, fetchStatusesCount, fetchStatusesByInstance } from '@/api/status'
|
import { changeStatusScope, deleteStatus, fetchStatus, fetchStatuses, fetchStatusesCount, fetchStatusesByInstance } from '@/api/status'
|
||||||
|
|
||||||
const status = {
|
const status = {
|
||||||
state: {
|
state: {
|
||||||
|
fetchedStatus: {},
|
||||||
fetchedStatuses: [],
|
fetchedStatuses: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
|
statusAuthor: {},
|
||||||
statusesByInstance: {
|
statusesByInstance: {
|
||||||
selectedInstance: '',
|
selectedInstance: '',
|
||||||
showLocal: false,
|
showLocal: false,
|
||||||
|
@ -28,6 +30,9 @@ const status = {
|
||||||
CHANGE_SELECTED_INSTANCE: (state, instance) => {
|
CHANGE_SELECTED_INSTANCE: (state, instance) => {
|
||||||
state.statusesByInstance.selectedInstance = instance
|
state.statusesByInstance.selectedInstance = instance
|
||||||
},
|
},
|
||||||
|
SET_STATUS: (state, status) => {
|
||||||
|
state.fetchedStatus = status
|
||||||
|
},
|
||||||
SET_STATUSES_BY_INSTANCE: (state, statuses) => {
|
SET_STATUSES_BY_INSTANCE: (state, statuses) => {
|
||||||
state.fetchedStatuses = statuses
|
state.fetchedStatuses = statuses
|
||||||
},
|
},
|
||||||
|
@ -45,6 +50,9 @@ const status = {
|
||||||
},
|
},
|
||||||
SET_STATUS_VISIBILITY: (state, visibility) => {
|
SET_STATUS_VISIBILITY: (state, visibility) => {
|
||||||
state.statusVisibility = visibility
|
state.statusVisibility = visibility
|
||||||
|
},
|
||||||
|
SET_STATUS_AUTHOR: (state, user) => {
|
||||||
|
state.statusAuthor = user
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -56,8 +64,18 @@ const status = {
|
||||||
dispatch('FetchUserStatuses', { userId, godmode })
|
dispatch('FetchUserStatuses', { userId, godmode })
|
||||||
} else if (fetchStatusesByInstance) { // called from Statuses by Instance
|
} else if (fetchStatusesByInstance) { // called from Statuses by Instance
|
||||||
dispatch('FetchStatusesByInstance')
|
dispatch('FetchStatusesByInstance')
|
||||||
|
} else { // called from Status show page
|
||||||
|
dispatch('FetchStatusAfterUserModeration', statusId)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ClearState({ commit }) {
|
||||||
|
commit('CHANGE_SELECTED_INSTANCE', '')
|
||||||
|
commit('SET_STATUSES_BY_INSTANCE', [])
|
||||||
|
commit('CHANGE_LOCAL_CHECKBOX_VALUE', false)
|
||||||
|
commit('CHANGE_GODMODE_CHECKBOX_VALUE', false)
|
||||||
|
commit('SET_ALL_LOADED', false)
|
||||||
|
commit('CHANGE_PAGE', 1)
|
||||||
|
},
|
||||||
async DeleteStatus({ dispatch, getters }, { statusId, reportCurrentPage, userId, godmode, fetchStatusesByInstance }) {
|
async DeleteStatus({ dispatch, getters }, { statusId, reportCurrentPage, userId, godmode, fetchStatusesByInstance }) {
|
||||||
await deleteStatus(statusId, getters.authHost, getters.token)
|
await deleteStatus(statusId, getters.authHost, getters.token)
|
||||||
if (reportCurrentPage !== 0) { // called from Reports
|
if (reportCurrentPage !== 0) { // called from Reports
|
||||||
|
@ -68,14 +86,30 @@ const status = {
|
||||||
dispatch('FetchStatusesByInstance')
|
dispatch('FetchStatusesByInstance')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async FetchStatusesCount({ commit, getters }) {
|
async FetchStatus({ commit, dispatch, getters, state }, id) {
|
||||||
commit('SET_LOADING', true)
|
commit('SET_LOADING', true)
|
||||||
const { data } = await fetchStatusesCount(getters.authHost, getters.token)
|
const status = await fetchStatus(id, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
commit('SET_STATUS', status.data)
|
||||||
|
commit('SET_STATUS_AUTHOR', status.data.account)
|
||||||
|
commit('SET_LOADING', false)
|
||||||
|
dispatch('FetchUserStatuses', { userId: state.fetchedStatus.account.id, godmode: false })
|
||||||
|
},
|
||||||
|
FetchStatusAfterUserModeration({ commit, dispatch, getters, state }, id) {
|
||||||
|
commit('SET_LOADING', true)
|
||||||
|
fetchStatus(id, getters.authHost, getters.token)
|
||||||
|
.then(status => dispatch('SetStatus', status.data))
|
||||||
|
commit('SET_LOADING', false)
|
||||||
|
},
|
||||||
|
async FetchStatusesCount({ commit, getters }, instance) {
|
||||||
|
commit('SET_LOADING', true)
|
||||||
|
const { data } = await fetchStatusesCount(instance, getters.authHost, getters.token)
|
||||||
commit('SET_STATUS_VISIBILITY', data.status_visibility)
|
commit('SET_STATUS_VISIBILITY', data.status_visibility)
|
||||||
commit('SET_LOADING', false)
|
commit('SET_LOADING', false)
|
||||||
},
|
},
|
||||||
async FetchStatusesByInstance({ commit, getters, state, rootState }) {
|
async FetchStatusesByInstance({ commit, dispatch, getters, state, rootState }) {
|
||||||
commit('SET_LOADING', true)
|
commit('SET_LOADING', true)
|
||||||
|
dispatch('FetchStatusesCount', state.statusesByInstance.selectedInstance)
|
||||||
if (state.statusesByInstance.selectedInstance === '') {
|
if (state.statusesByInstance.selectedInstance === '') {
|
||||||
commit('SET_STATUSES_BY_INSTANCE', [])
|
commit('SET_STATUSES_BY_INSTANCE', [])
|
||||||
} else {
|
} else {
|
||||||
|
@ -150,6 +184,10 @@ const status = {
|
||||||
},
|
},
|
||||||
HandlePageChange({ commit }, page) {
|
HandlePageChange({ commit }, page) {
|
||||||
commit('CHANGE_PAGE', page)
|
commit('CHANGE_PAGE', page)
|
||||||
|
},
|
||||||
|
SetStatus({ commit }, status) {
|
||||||
|
commit('SET_STATUS', status)
|
||||||
|
commit('SET_STATUS_AUTHOR', status.account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,15 +72,19 @@ const user = {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async GetNodeInfo({ commit, state }) {
|
async GetNodeInfo({ commit, dispatch, state }) {
|
||||||
const nodeInfo = await getNodeInfo(state.authHost)
|
const nodeInfo = await getNodeInfo(state.authHost)
|
||||||
|
|
||||||
commit('SET_NODE_INFO', nodeInfo.data)
|
commit('SET_NODE_INFO', nodeInfo.data)
|
||||||
|
dispatch('SetInvitesEnabled', nodeInfo.data.metadata.invitesEnabled)
|
||||||
},
|
},
|
||||||
GetUserInfo({ commit, state }) {
|
GetUserInfo({ commit, state }) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
getUserInfo(state.token, state.authHost).then(response => {
|
getUserInfo(state.token, state.authHost).then(response => {
|
||||||
const data = response.data
|
const data = response.data
|
||||||
|
const message = '<span>This user doesn\`t have admin rights. Try another credentials or see the </span>' +
|
||||||
|
'<u><a target="_blank" href="https://docs.pleroma.social/backend/administration/CLI_tasks/user/#set-the-value-of-the-given-users-settings">docs</a></u>' +
|
||||||
|
'<span> to find out how to make this user an admin</span>'
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
reject('Verification failed, please login again.')
|
reject('Verification failed, please login again.')
|
||||||
|
@ -89,7 +93,7 @@ const user = {
|
||||||
if (data.pleroma && data.pleroma.is_admin) {
|
if (data.pleroma && data.pleroma.is_admin) {
|
||||||
commit('SET_ROLES', ['admin'])
|
commit('SET_ROLES', ['admin'])
|
||||||
} else {
|
} else {
|
||||||
reject('getInfo: roles must be a non-null array!')
|
reject(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
commit('SET_NAME', data.username)
|
commit('SET_NAME', data.username)
|
||||||
|
|
|
@ -35,18 +35,21 @@ const userProfile = {
|
||||||
|
|
||||||
dispatch('FetchUserStatuses', { userId, godmode })
|
dispatch('FetchUserStatuses', { userId, godmode })
|
||||||
},
|
},
|
||||||
async FetchUserStatuses({ commit, getters }, { userId, godmode }) {
|
FetchUserStatuses({ commit, dispatch, getters }, { userId, godmode }) {
|
||||||
commit('SET_STATUSES_LOADING', true)
|
commit('SET_STATUSES_LOADING', true)
|
||||||
|
|
||||||
const statuses = await fetchUserStatuses(userId, getters.authHost, godmode, getters.token)
|
fetchUserStatuses(userId, getters.authHost, godmode, getters.token)
|
||||||
|
.then(statuses => dispatch('SetStatuses', statuses.data.activities))
|
||||||
|
|
||||||
commit('SET_STATUSES', statuses.data)
|
|
||||||
commit('SET_STATUSES_LOADING', false)
|
commit('SET_STATUSES_LOADING', false)
|
||||||
},
|
},
|
||||||
async FetchUserCredentials({ commit, getters }, { nickname }) {
|
async FetchUserCredentials({ commit, getters }, { nickname }) {
|
||||||
const userResponse = await fetchUserCredentials(nickname, getters.authHost, getters.token)
|
const userResponse = await fetchUserCredentials(nickname, getters.authHost, getters.token)
|
||||||
commit('SET_USER_CREDENTIALS', userResponse.data)
|
commit('SET_USER_CREDENTIALS', userResponse.data)
|
||||||
},
|
},
|
||||||
|
SetStatuses({ commit }, statuses) {
|
||||||
|
commit('SET_STATUSES', statuses)
|
||||||
|
},
|
||||||
async UpdateUserCredentials({ dispatch, getters }, { nickname, credentials }) {
|
async UpdateUserCredentials({ dispatch, getters }, { nickname, credentials }) {
|
||||||
await updateUserCredentials(nickname, credentials, getters.authHost, getters.token)
|
await updateUserCredentials(nickname, credentials, getters.authHost, getters.token)
|
||||||
dispatch('FetchUserCredentials', { nickname })
|
dispatch('FetchUserCredentials', { nickname })
|
||||||
|
|
|
@ -7,35 +7,40 @@ import {
|
||||||
deactivateUsers,
|
deactivateUsers,
|
||||||
deleteRight,
|
deleteRight,
|
||||||
deleteUsers,
|
deleteUsers,
|
||||||
|
disableMfa,
|
||||||
fetchUsers,
|
fetchUsers,
|
||||||
getPasswordResetToken,
|
getPasswordResetToken,
|
||||||
searchUsers,
|
searchUsers,
|
||||||
tagUser,
|
tagUser,
|
||||||
untagUser,
|
untagUser,
|
||||||
forcePasswordReset,
|
forcePasswordReset,
|
||||||
|
approveUserAccount,
|
||||||
confirmUserEmail,
|
confirmUserEmail,
|
||||||
resendConfirmationEmail
|
resendConfirmationEmail,
|
||||||
|
updateUserCredentials
|
||||||
} from '@/api/users'
|
} from '@/api/users'
|
||||||
|
import { fetchSettings, updateSettings } from '@/api/settings'
|
||||||
|
|
||||||
const users = {
|
const users = {
|
||||||
state: {
|
state: {
|
||||||
fetchedUsers: [],
|
fetchedUsers: [],
|
||||||
loading: true,
|
loading: true,
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
|
mrfPolicies: [],
|
||||||
totalUsersCount: 0,
|
totalUsersCount: 0,
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
filters: {
|
pageSize: 50,
|
||||||
local: false,
|
actorTypeFilters: [],
|
||||||
external: false,
|
filters: [],
|
||||||
active: false,
|
|
||||||
deactivated: false
|
|
||||||
},
|
|
||||||
passwordResetToken: {
|
passwordResetToken: {
|
||||||
token: '',
|
token: '',
|
||||||
link: ''
|
link: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
|
SET_ACTOR_TYPE_FILTERS: (state, actorTypeFilters) => {
|
||||||
|
state.actorTypeFilters = actorTypeFilters
|
||||||
|
},
|
||||||
SET_USERS: (state, users) => {
|
SET_USERS: (state, users) => {
|
||||||
state.fetchedUsers = users
|
state.fetchedUsers = users
|
||||||
},
|
},
|
||||||
|
@ -51,9 +56,11 @@ const users = {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
state.fetchedUsers = [...usersWithoutSwapped, ...users].sort((a, b) =>
|
const updatedUsers = [...usersWithoutSwapped, ...users]
|
||||||
a.nickname.localeCompare(b.nickname)
|
state.fetchedUsers = updatedUsers
|
||||||
)
|
.filter(user => user.nickname && user.id)
|
||||||
|
.sort((a, b) => a.nickname.localeCompare(b.nickname))
|
||||||
|
.concat(updatedUsers.filter(user => !user.nickname || !user.id))
|
||||||
},
|
},
|
||||||
SET_COUNT: (state, count) => {
|
SET_COUNT: (state, count) => {
|
||||||
state.totalUsersCount = count
|
state.totalUsersCount = count
|
||||||
|
@ -71,24 +78,24 @@ const users = {
|
||||||
SET_SEARCH_QUERY: (state, query) => {
|
SET_SEARCH_QUERY: (state, query) => {
|
||||||
state.searchQuery = query
|
state.searchQuery = query
|
||||||
},
|
},
|
||||||
|
SET_TAG_POLICY: (state, mrfPolicies) => {
|
||||||
|
state.mrfPolicies = mrfPolicies
|
||||||
|
},
|
||||||
SET_USERS_FILTERS: (state, filters) => {
|
SET_USERS_FILTERS: (state, filters) => {
|
||||||
state.filters = filters
|
state.filters = filters
|
||||||
},
|
|
||||||
SET_USER_PROFILE: (state, user) => {
|
|
||||||
state.userProfile = user
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async ActivateUsers({ dispatch, getters }, { users, _userId }) {
|
async ActivateUsers({ dispatch, getters }, { users, _userId }) {
|
||||||
const updatedUsers = users.map(user => {
|
const updatedUsers = users.map(user => {
|
||||||
return { ...user, deactivated: false }
|
return { ...user, is_active: true }
|
||||||
})
|
})
|
||||||
const nicknames = users.map(user => user.nickname)
|
const nicknames = users.map(user => user.nickname)
|
||||||
const callApiFn = async() => await activateUsers(nicknames, getters.authHost, getters.token)
|
const callApiFn = async() => await activateUsers(nicknames, getters.authHost, getters.token)
|
||||||
|
|
||||||
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId })
|
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId })
|
||||||
},
|
},
|
||||||
async ApplyChanges({ commit, dispatch, state }, { updatedUsers, callApiFn, userId }) {
|
async ApplyChanges({ commit, dispatch, state }, { updatedUsers, callApiFn, userId, statusId }) {
|
||||||
commit('SWAP_USERS', updatedUsers)
|
commit('SWAP_USERS', updatedUsers)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -98,34 +105,57 @@ const users = {
|
||||||
} finally {
|
} finally {
|
||||||
dispatch('SearchUsers', { query: state.searchQuery, page: state.currentPage })
|
dispatch('SearchUsers', { query: state.searchQuery, page: state.currentPage })
|
||||||
}
|
}
|
||||||
|
if (statusId) {
|
||||||
if (userId) {
|
dispatch('FetchStatusAfterUserModeration', statusId)
|
||||||
|
} else if (userId) {
|
||||||
dispatch('FetchUserProfile', { userId, godmode: false })
|
dispatch('FetchUserProfile', { userId, godmode: false })
|
||||||
}
|
}
|
||||||
dispatch('SuccessMessage')
|
dispatch('SuccessMessage')
|
||||||
},
|
},
|
||||||
async AddRight({ dispatch, getters }, { users, right, _userId }) {
|
async AddRight({ dispatch, getters }, { users, right, _userId, _statusId }) {
|
||||||
const updatedUsers = users.map(user => {
|
const updatedUsers = users.map(user => {
|
||||||
return user.local ? { ...user, roles: { ...user.roles, [right]: true }} : user
|
return user.local ? { ...user, roles: { ...user.roles, [right]: true }} : user
|
||||||
})
|
})
|
||||||
const nicknames = users.map(user => user.nickname)
|
const nicknames = users.map(user => user.nickname)
|
||||||
const callApiFn = async() => await addRight(nicknames, right, getters.authHost, getters.token)
|
const callApiFn = async() => await addRight(nicknames, right, getters.authHost, getters.token)
|
||||||
|
|
||||||
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId })
|
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
|
||||||
},
|
},
|
||||||
async AddTag({ dispatch, getters }, { users, tag, _userId }) {
|
async AddTag({ dispatch, getters }, { users, tag, _userId, _statusId }) {
|
||||||
const updatedUsers = users.map(user => {
|
const updatedUsers = users.map(user => {
|
||||||
return { ...user, tags: [...user.tags, tag] }
|
return { ...user, tags: [...user.tags, tag] }
|
||||||
})
|
})
|
||||||
const nicknames = users.map(user => user.nickname)
|
const nicknames = users.map(user => user.nickname)
|
||||||
const callApiFn = async() => await tagUser(nicknames, [tag], getters.authHost, getters.token)
|
const callApiFn = async() => await tagUser(nicknames, [tag], getters.authHost, getters.token)
|
||||||
|
|
||||||
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId })
|
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
|
||||||
|
},
|
||||||
|
async ApproveUsersAccount({ dispatch, getters }, { users, _userId, _statusId }) {
|
||||||
|
const updatedUsers = users.map(user => {
|
||||||
|
return { ...user, is_approved: true }
|
||||||
|
})
|
||||||
|
const nicknames = users.map(user => user.nickname)
|
||||||
|
const callApiFn = async() => await approveUserAccount(nicknames, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
|
||||||
|
},
|
||||||
|
ClearUsersState({ commit }) {
|
||||||
|
commit('SET_SEARCH_QUERY', '')
|
||||||
|
commit('SET_USERS_FILTERS', [])
|
||||||
},
|
},
|
||||||
async ClearFilters({ commit, dispatch, state }) {
|
async ClearFilters({ commit, dispatch, state }) {
|
||||||
commit('CLEAR_USERS_FILTERS')
|
commit('CLEAR_USERS_FILTERS')
|
||||||
dispatch('SearchUsers', { query: state.searchQuery, page: 1 })
|
dispatch('SearchUsers', { query: state.searchQuery, page: 1 })
|
||||||
},
|
},
|
||||||
|
async ConfirmUsersEmail({ dispatch, getters }, { users, _userId, _statusId }) {
|
||||||
|
const updatedUsers = users.map(user => {
|
||||||
|
return { ...user, is_confirmed: true }
|
||||||
|
})
|
||||||
|
const nicknames = users.map(user => user.nickname)
|
||||||
|
const callApiFn = async() => await confirmUserEmail(nicknames, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
|
||||||
|
},
|
||||||
async CreateNewAccount({ dispatch, getters, state }, { nickname, email, password }) {
|
async CreateNewAccount({ dispatch, getters, state }, { nickname, email, password }) {
|
||||||
try {
|
try {
|
||||||
await createNewAccount(nickname, email, password, getters.authHost, getters.token)
|
await createNewAccount(nickname, email, password, getters.authHost, getters.token)
|
||||||
|
@ -138,39 +168,29 @@ const users = {
|
||||||
},
|
},
|
||||||
async DeactivateUsers({ dispatch, getters }, { users, _userId }) {
|
async DeactivateUsers({ dispatch, getters }, { users, _userId }) {
|
||||||
const updatedUsers = users.map(user => {
|
const updatedUsers = users.map(user => {
|
||||||
return { ...user, deactivated: true }
|
return { ...user, is_active: false }
|
||||||
})
|
})
|
||||||
const nicknames = users.map(user => user.nickname)
|
const nicknames = users.map(user => user.nickname)
|
||||||
const callApiFn = async() => await deactivateUsers(nicknames, getters.authHost, getters.token)
|
const callApiFn = async() => await deactivateUsers(nicknames, getters.authHost, getters.token)
|
||||||
|
|
||||||
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId })
|
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId })
|
||||||
},
|
},
|
||||||
async ConfirmUsersEmail({ dispatch, getters }, { users, _userId }) {
|
async DisableMfa({ dispatch, getters }, nickname) {
|
||||||
const updatedUsers = users.map(user => {
|
|
||||||
return { ...user, confirmation_pending: false }
|
|
||||||
})
|
|
||||||
const nicknames = users.map(user => user.nickname)
|
|
||||||
const callApiFn = async() => await confirmUserEmail(nicknames, getters.authHost, getters.token)
|
|
||||||
|
|
||||||
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId })
|
|
||||||
},
|
|
||||||
async ResendConfirmationEmail({ dispatch, getters }, users) {
|
|
||||||
const usersNicknames = users.map(user => user.nickname)
|
|
||||||
try {
|
try {
|
||||||
await resendConfirmationEmail(usersNicknames, getters.authHost, getters.token)
|
await disableMfa(nickname, getters.authHost, getters.token)
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dispatch('SuccessMessage')
|
dispatch('SuccessMessage')
|
||||||
},
|
},
|
||||||
async DeleteRight({ dispatch, getters }, { users, right, _userId }) {
|
async DeleteRight({ dispatch, getters }, { users, right, _userId, _statusId }) {
|
||||||
const updatedUsers = users.map(user => {
|
const updatedUsers = users.map(user => {
|
||||||
return user.local ? { ...user, roles: { ...user.roles, [right]: false }} : user
|
return user.local ? { ...user, roles: { ...user.roles, [right]: false }} : user
|
||||||
})
|
})
|
||||||
const nicknames = users.map(user => user.nickname)
|
const nicknames = users.map(user => user.nickname)
|
||||||
const callApiFn = async() => await deleteRight(nicknames, right, getters.authHost, getters.token)
|
const callApiFn = async() => await deleteRight(nicknames, right, getters.authHost, getters.token)
|
||||||
|
|
||||||
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId })
|
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
|
||||||
},
|
},
|
||||||
async DeleteUsers({ commit, dispatch, getters, state }, { users, _userId }) {
|
async DeleteUsers({ commit, dispatch, getters, state }, { users, _userId }) {
|
||||||
const usersNicknames = users.map(user => user.nickname)
|
const usersNicknames = users.map(user => user.nickname)
|
||||||
|
@ -179,17 +199,41 @@ const users = {
|
||||||
} catch (_e) {
|
} catch (_e) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const deletedUsersIds = users.map(deletedUser => deletedUser.id)
|
const updatedUsers = users.map(user => {
|
||||||
const updatedUsers = state.fetchedUsers.filter(user => !deletedUsersIds.includes(user.id))
|
return { ...user, is_active: false }
|
||||||
commit('SET_USERS', updatedUsers)
|
})
|
||||||
|
commit('SWAP_USERS', updatedUsers)
|
||||||
|
|
||||||
dispatch('FetchUserProfile', { userId: _userId, godmode: false })
|
if (_userId) {
|
||||||
|
dispatch('FetchUserProfile', { userId: _userId, godmode: false })
|
||||||
|
}
|
||||||
dispatch('SuccessMessage')
|
dispatch('SuccessMessage')
|
||||||
},
|
},
|
||||||
|
async EnableTagPolicy({ dispatch, getters, state }) {
|
||||||
|
const configs = [{
|
||||||
|
group: ':pleroma',
|
||||||
|
key: ':mrf',
|
||||||
|
value: [{ tuple: [':policies', [...state.mrfPolicies, 'Pleroma.Web.ActivityPub.MRF.TagPolicy']] }]
|
||||||
|
}]
|
||||||
|
await updateSettings(configs, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
dispatch('FetchTagPolicySetting')
|
||||||
|
},
|
||||||
|
async FetchTagPolicySetting({ commit, getters }) {
|
||||||
|
const { data } = await fetchSettings(getters.authHost, getters.token)
|
||||||
|
const mrfSettings = data.configs.find(el => el.key === ':mrf')
|
||||||
|
? data.configs.find(el => el.key === ':mrf').value
|
||||||
|
: []
|
||||||
|
const mrfPolicies = mrfSettings.find(el => el.tuple[0] === ':policies')
|
||||||
|
? mrfSettings.find(el => el.tuple[0] === ':policies').tuple[1]
|
||||||
|
: []
|
||||||
|
|
||||||
|
commit('SET_TAG_POLICY', Array.isArray(mrfPolicies) ? mrfPolicies : [mrfPolicies])
|
||||||
|
},
|
||||||
async FetchUsers({ commit, dispatch, getters, state }, { page }) {
|
async FetchUsers({ commit, dispatch, getters, state }, { page }) {
|
||||||
commit('SET_LOADING', true)
|
commit('SET_LOADING', true)
|
||||||
const filters = Object.keys(state.filters).filter(filter => state.filters[filter]).join()
|
const filters = state.filters.join()
|
||||||
const response = await fetchUsers(filters, getters.authHost, getters.token, page)
|
const response = await fetchUsers(filters, state.actorTypeFilters, getters.authHost, getters.token, page)
|
||||||
await dispatch('GetNodeInfo')
|
await dispatch('GetNodeInfo')
|
||||||
loadUsers(commit, page, response.data)
|
loadUsers(commit, page, response.data)
|
||||||
},
|
},
|
||||||
|
@ -200,14 +244,14 @@ const users = {
|
||||||
RemovePasswordToken({ commit }) {
|
RemovePasswordToken({ commit }) {
|
||||||
commit('SET_PASSWORD_RESET_TOKEN', { link: '', token: '' })
|
commit('SET_PASSWORD_RESET_TOKEN', { link: '', token: '' })
|
||||||
},
|
},
|
||||||
async RemoveTag({ dispatch, getters }, { users, tag, _userId }) {
|
async RemoveTag({ dispatch, getters }, { users, tag, _userId, _statusId }) {
|
||||||
const updatedUsers = users.map(user => {
|
const updatedUsers = users.map(user => {
|
||||||
return { ...user, tags: user.tags.filter(userTag => userTag !== tag) }
|
return { ...user, tags: user.tags.filter(userTag => userTag !== tag) }
|
||||||
})
|
})
|
||||||
const nicknames = users.map(user => user.nickname)
|
const nicknames = users.map(user => user.nickname)
|
||||||
const callApiFn = async() => await untagUser(nicknames, [tag], getters.authHost, getters.token)
|
const callApiFn = async() => await untagUser(nicknames, [tag], getters.authHost, getters.token)
|
||||||
|
|
||||||
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId })
|
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
|
||||||
},
|
},
|
||||||
async RequirePasswordReset({ dispatch, getters }, users) {
|
async RequirePasswordReset({ dispatch, getters }, users) {
|
||||||
const nicknames = users.map(user => user.nickname)
|
const nicknames = users.map(user => user.nickname)
|
||||||
|
@ -218,6 +262,15 @@ const users = {
|
||||||
}
|
}
|
||||||
dispatch('SuccessMessage')
|
dispatch('SuccessMessage')
|
||||||
},
|
},
|
||||||
|
async ResendConfirmationEmail({ dispatch, getters }, users) {
|
||||||
|
const usersNicknames = users.map(user => user.nickname)
|
||||||
|
try {
|
||||||
|
await resendConfirmationEmail(usersNicknames, getters.authHost, getters.token)
|
||||||
|
} catch (_e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dispatch('SuccessMessage')
|
||||||
|
},
|
||||||
async SearchUsers({ commit, dispatch, state, getters }, { query, page }) {
|
async SearchUsers({ commit, dispatch, state, getters }, { query, page }) {
|
||||||
if (query.length === 0) {
|
if (query.length === 0) {
|
||||||
commit('SET_SEARCH_QUERY', query)
|
commit('SET_SEARCH_QUERY', query)
|
||||||
|
@ -226,8 +279,8 @@ const users = {
|
||||||
commit('SET_LOADING', true)
|
commit('SET_LOADING', true)
|
||||||
commit('SET_SEARCH_QUERY', query)
|
commit('SET_SEARCH_QUERY', query)
|
||||||
|
|
||||||
const filters = Object.keys(state.filters).filter(filter => state.filters[filter]).join()
|
const filters = state.filters.join()
|
||||||
const response = await searchUsers(query, filters, getters.authHost, getters.token, page)
|
const response = await searchUsers(query, filters, state.actorTypeFilters, getters.authHost, getters.token, page)
|
||||||
|
|
||||||
loadUsers(commit, page, response.data)
|
loadUsers(commit, page, response.data)
|
||||||
}
|
}
|
||||||
|
@ -238,16 +291,21 @@ const users = {
|
||||||
duration: 5 * 1000
|
duration: 5 * 1000
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async ToggleUsersFilter({ commit, dispatch, state }, filters) {
|
async ToggleActorTypeFilter({ commit, dispatch, state }, actorTypeFilters) {
|
||||||
const defaultFilters = {
|
commit('SET_ACTOR_TYPE_FILTERS', actorTypeFilters)
|
||||||
local: false,
|
|
||||||
external: false,
|
|
||||||
active: false,
|
|
||||||
deactivated: false
|
|
||||||
}
|
|
||||||
const currentFilters = { ...defaultFilters, ...filters }
|
|
||||||
commit('SET_USERS_FILTERS', currentFilters)
|
|
||||||
dispatch('SearchUsers', { query: state.searchQuery, page: 1 })
|
dispatch('SearchUsers', { query: state.searchQuery, page: 1 })
|
||||||
|
},
|
||||||
|
async ToggleUsersFilter({ commit, dispatch, state }, filters) {
|
||||||
|
commit('SET_USERS_FILTERS', filters)
|
||||||
|
dispatch('SearchUsers', { query: state.searchQuery, page: 1 })
|
||||||
|
},
|
||||||
|
async UpdateActorType({ dispatch, getters }, { user, type, _userId, _statusId }) {
|
||||||
|
const updatedUsers = [{ ...user, actor_type: type }]
|
||||||
|
const credentials = { actor_type: type }
|
||||||
|
|
||||||
|
const callApiFn = async() => await updateUserCredentials(user.nickname, credentials, getters.authHost, getters.token)
|
||||||
|
|
||||||
|
dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,6 @@ div:focus {
|
||||||
code {
|
code {
|
||||||
background: #eef1f6;
|
background: #eef1f6;
|
||||||
padding: 15px 16px;
|
padding: 15px 16px;
|
||||||
margin-bottom: 20px;
|
|
||||||
display: block;
|
display: block;
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
@ -172,32 +171,3 @@ code {
|
||||||
background: #d0d0d0;
|
background: #d0d0d0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.link-type,
|
|
||||||
.link-type:focus {
|
|
||||||
color: #337ab7;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: rgb(32, 160, 255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-container {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
|
|
||||||
.filter-item {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//refine vue-multiselect plugin
|
|
||||||
.multiselect {
|
|
||||||
line-height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.multiselect--active {
|
|
||||||
z-index: 1000 !important;
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1001;
|
z-index: 5000;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
//reset element-ui css
|
//reset element-ui css
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.submenu-title-noDropdown {
|
.submenu-title-noDropdown {
|
||||||
padding-left: 10px !important;
|
padding-left: 8px !important;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.el-tooltip {
|
.el-tooltip {
|
||||||
|
|
|
@ -19,7 +19,7 @@ $menuHover:#263445;
|
||||||
$subMenuBg:#1f2d3d;
|
$subMenuBg:#1f2d3d;
|
||||||
$subMenuHover:#001528;
|
$subMenuHover:#001528;
|
||||||
|
|
||||||
$sideBarWidth: 180px;
|
$sideBarWidth: 205px;
|
||||||
|
|
||||||
// the :export directive is the magic sauce for webpack
|
// the :export directive is the magic sauce for webpack
|
||||||
:export {
|
:export {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Clipboard from 'clipboard'
|
||||||
|
|
||||||
function clipboardSuccess() {
|
function clipboardSuccess() {
|
||||||
Vue.prototype.$message({
|
Vue.prototype.$message({
|
||||||
message: 'Copy successfully',
|
message: 'Copied!',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 1500
|
duration: 1500
|
||||||
})
|
})
|
||||||
|
|
|
@ -6,27 +6,32 @@ const service = axios.create({
|
||||||
timeout: 60000 // request timeout
|
timeout: 60000 // request timeout
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isJson = ({ headers }) => headers['content-type'].includes('application/json')
|
||||||
|
|
||||||
// response interceptor
|
// response interceptor
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
response => response,
|
response => response,
|
||||||
error => {
|
error => {
|
||||||
let errorMessage
|
|
||||||
console.log(`Error ${error}`)
|
console.log(`Error ${error}`)
|
||||||
|
|
||||||
if (error.response) {
|
if (!error.response) {
|
||||||
const edata = error.response.data.error ? error.response.data.error : error.response.data
|
Message({
|
||||||
errorMessage = !error.response.headers['content-type'].includes('application/json')
|
message: error,
|
||||||
? `${error.message}`
|
type: 'error',
|
||||||
: `${error.message} - ${edata}`
|
duration: 5 * 1000
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
errorMessage = error
|
const errors = Array.isArray(error.response.data) ? error.response.data : [error.response.data]
|
||||||
|
errors.forEach(errorData => {
|
||||||
|
const edata = errorData.error || errorData
|
||||||
|
Message({
|
||||||
|
message: isJson(error.response) ? `${error.message} - ${edata}` : `${error.message}`,
|
||||||
|
type: 'error',
|
||||||
|
duration: 5 * 1000
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Message({
|
|
||||||
message: errorMessage,
|
|
||||||
type: 'error',
|
|
||||||
duration: 5 * 1000
|
|
||||||
})
|
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
21
src/utils/tabs.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
export const tabs = [
|
||||||
|
{ label: 'ActivityPub', path: 'activity-pub', tab: ':activity_pub' },
|
||||||
|
{ label: 'Authentication', path: 'authentication', tab: ':authentication' },
|
||||||
|
{ label: 'Captcha', path: 'captcha', tab: ':captcha' },
|
||||||
|
{ label: 'Emoji', path: 'emoji', tab: ':emoji' },
|
||||||
|
{ label: 'Frontend', path: 'frontend', tab: ':frontend' },
|
||||||
|
{ label: 'HTTP', path: 'http', tab: ':http' },
|
||||||
|
{ label: 'Instance', path: 'instance', tab: ':instance' },
|
||||||
|
{ label: 'Job queue', path: 'job-queue', tab: ':job_queue' },
|
||||||
|
{ label: 'Link Formatter', path: 'link-formatter', tab: ':link_formatter' },
|
||||||
|
{ label: 'Logger', path: 'logger', tab: ':logger' },
|
||||||
|
{ label: 'Mailer', path: 'mailer', tab: ':mailer' },
|
||||||
|
{ label: 'Media Proxy', path: 'media-proxy', tab: ':media_proxy' },
|
||||||
|
{ label: 'Metadata', path: 'metadata', tab: ':metadata' },
|
||||||
|
{ label: 'MRF', path: 'mrf', tab: ':mrf' },
|
||||||
|
{ label: 'Rate limiters', path: 'rate-limiters', tab: ':rate_limiters' },
|
||||||
|
{ label: 'Web push encryption', path: 'web-push', tab: ':web_push' },
|
||||||
|
{ label: 'Upload', path: 'upload', tab: ':upload' },
|
||||||
|
{ label: 'Search', path: 'search', tab: ':search' },
|
||||||
|
{ label: 'Other', path: 'other', tab: ':other' }
|
||||||
|
]
|
|
@ -1,23 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="chart-container">
|
|
||||||
<chart height="100%" width="100%"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Chart from '@/components/element-ui/Charts/keyboard'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'KeyboardChart',
|
|
||||||
components: { Chart }
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.chart-container{
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100vh - 84px);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="chart-container">
|
|
||||||
<chart height="100%" width="100%"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Chart from '@/components/element-ui/Charts/lineMarker'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'LineChart',
|
|
||||||
components: { Chart }
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.chart-container{
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100vh - 84px);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="chart-container">
|
|
||||||
<chart height="100%" width="100%"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Chart from '@/components/element-ui/Charts/mixChart'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'MixChart',
|
|
||||||
components: { Chart }
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.chart-container{
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100vh - 84px);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<el-tabs v-model="activeName">
|
|
||||||
<el-tab-pane label="use clipboard directly" name="directly">
|
|
||||||
<el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;"/>
|
|
||||||
<el-button type="primary" icon="document" @click="handleCopy(inputData,$event)">copy</el-button>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="use clipboard by v-directive" name="v-directive">
|
|
||||||
<el-input v-model="inputData" placeholder="Please input" style="width:400px;max-width:100%;"/>
|
|
||||||
<el-button v-clipboard:copy="inputData" v-clipboard:success="clipboardSuccess" type="primary" icon="document">copy</el-button>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import clip from '@/utils/clipboard' // use clipboard directly
|
|
||||||
import clipboard from '@/directive/clipboard/index.js' // use clipboard by v-directive
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'ClipboardDemo',
|
|
||||||
directives: {
|
|
||||||
clipboard
|
|
||||||
},
|
|
||||||
data: function() {
|
|
||||||
return {
|
|
||||||
activeName: 'directly',
|
|
||||||
inputData: 'https://github.com/PanJiaChen/vue-element-admin'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleCopy(text, event) {
|
|
||||||
clip(text, event)
|
|
||||||
},
|
|
||||||
clipboardSuccess() {
|
|
||||||
this.$message({
|
|
||||||
message: 'Copy successfully',
|
|
||||||
type: 'success',
|
|
||||||
duration: 1500
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
<template>
|
|
||||||
<div :class="className" :style="{height:height,width:width}"/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import echarts from 'echarts'
|
|
||||||
require('echarts/theme/macarons') // echarts theme
|
|
||||||
import { debounce } from '@/utils'
|
|
||||||
|
|
||||||
const animationDuration = 6000
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
className: {
|
|
||||||
type: String,
|
|
||||||
default: 'chart'
|
|
||||||
},
|
|
||||||
width: {
|
|
||||||
type: String,
|
|
||||||
default: '100%'
|
|
||||||
},
|
|
||||||
height: {
|
|
||||||
type: String,
|
|
||||||
default: '300px'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: function() {
|
|
||||||
return {
|
|
||||||
chart: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.initChart()
|
|
||||||
this.__resizeHandler = debounce(() => {
|
|
||||||
if (this.chart) {
|
|
||||||
this.chart.resize()
|
|
||||||
}
|
|
||||||
}, 100)
|
|
||||||
window.addEventListener('resize', this.__resizeHandler)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
if (!this.chart) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
window.removeEventListener('resize', this.__resizeHandler)
|
|
||||||
this.chart.dispose()
|
|
||||||
this.chart = null
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initChart() {
|
|
||||||
this.chart = echarts.init(this.$el, 'macarons')
|
|
||||||
|
|
||||||
this.chart.setOption({
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
top: 10,
|
|
||||||
left: '2%',
|
|
||||||
right: '2%',
|
|
||||||
bottom: '3%',
|
|
||||||
containLabel: true
|
|
||||||
},
|
|
||||||
xAxis: [{
|
|
||||||
type: 'category',
|
|
||||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
|
||||||
axisTick: {
|
|
||||||
alignWithLabel: true
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
yAxis: [{
|
|
||||||
type: 'value',
|
|
||||||
axisTick: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
series: [{
|
|
||||||
name: 'pageA',
|
|
||||||
type: 'bar',
|
|
||||||
stack: 'vistors',
|
|
||||||
barWidth: '60%',
|
|
||||||
data: [79, 52, 200, 334, 390, 330, 220],
|
|
||||||
animationDuration
|
|
||||||
}, {
|
|
||||||
name: 'pageB',
|
|
||||||
type: 'bar',
|
|
||||||
stack: 'vistors',
|
|
||||||
barWidth: '60%',
|
|
||||||
data: [80, 52, 200, 334, 390, 330, 220],
|
|
||||||
animationDuration
|
|
||||||
}, {
|
|
||||||
name: 'pageC',
|
|
||||||
type: 'bar',
|
|
||||||
stack: 'vistors',
|
|
||||||
barWidth: '60%',
|
|
||||||
data: [30, 52, 200, 334, 390, 330, 220],
|
|
||||||
animationDuration
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,118 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-card class="box-card-component" style="margin-left:8px;">
|
|
||||||
<div slot="header" class="box-card-header">
|
|
||||||
<img src="https://wpimg.wallstcn.com/e7d23d71-cf19-4b90-a1cc-f56af8c0903d.png">
|
|
||||||
</div>
|
|
||||||
<div style="position:relative;">
|
|
||||||
<pan-thumb :image="avatar" class="panThumb"/>
|
|
||||||
<mallki class-name="mallki-text" text="vue-element-admin"/>
|
|
||||||
<div style="padding-top:35px;" class="progress-item">
|
|
||||||
<span>Vue</span>
|
|
||||||
<el-progress :percentage="70"/>
|
|
||||||
</div>
|
|
||||||
<div class="progress-item">
|
|
||||||
<span>JavaScript</span>
|
|
||||||
<el-progress :percentage="18"/>
|
|
||||||
</div>
|
|
||||||
<div class="progress-item">
|
|
||||||
<span>Css</span>
|
|
||||||
<el-progress :percentage="12"/>
|
|
||||||
</div>
|
|
||||||
<div class="progress-item">
|
|
||||||
<span>ESLint</span>
|
|
||||||
<el-progress :percentage="100" status="success"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
import PanThumb from '@/components/element-ui/PanThumb'
|
|
||||||
import Mallki from '@/components/element-ui/TextHoverEffect/Mallki'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { PanThumb, Mallki },
|
|
||||||
|
|
||||||
filters: {
|
|
||||||
statusFilter(status) {
|
|
||||||
const statusMap = {
|
|
||||||
success: 'success',
|
|
||||||
pending: 'danger'
|
|
||||||
}
|
|
||||||
return statusMap[status]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: function() {
|
|
||||||
return {
|
|
||||||
statisticsData: {
|
|
||||||
article_count: 1024,
|
|
||||||
pageviews_count: 1024
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters([
|
|
||||||
'name',
|
|
||||||
'avatar',
|
|
||||||
'roles'
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style rel="stylesheet/scss" lang="scss" >
|
|
||||||
.box-card-component{
|
|
||||||
.el-card__header {
|
|
||||||
padding: 0px!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
|
||||||
.box-card-component {
|
|
||||||
.box-card-header {
|
|
||||||
position: relative;
|
|
||||||
height: 220px;
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
transition: all 0.2s linear;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.1, 1.1);
|
|
||||||
filter: contrast(130%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.mallki-text {
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
right: 0px;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.panThumb {
|
|
||||||
z-index: 100;
|
|
||||||
height: 70px!important;
|
|
||||||
width: 70px!important;
|
|
||||||
position: absolute!important;
|
|
||||||
top: -45px;
|
|
||||||
left: 0px;
|
|
||||||
border: 5px solid #ffffff;
|
|
||||||
background-color: #fff;
|
|
||||||
margin: auto;
|
|
||||||
box-shadow: none!important;
|
|
||||||
/deep/ .pan-info {
|
|
||||||
box-shadow: none!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.progress-item {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
@media only screen and (max-width: 1510px){
|
|
||||||
.mallki-text{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,156 +0,0 @@
|
||||||
<template>
|
|
||||||
<div :class="className" :style="{height:height,width:width}"/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import echarts from 'echarts'
|
|
||||||
require('echarts/theme/macarons') // echarts theme
|
|
||||||
import { debounce } from '@/utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
className: {
|
|
||||||
type: String,
|
|
||||||
default: 'chart'
|
|
||||||
},
|
|
||||||
width: {
|
|
||||||
type: String,
|
|
||||||
default: '100%'
|
|
||||||
},
|
|
||||||
height: {
|
|
||||||
type: String,
|
|
||||||
default: '350px'
|
|
||||||
},
|
|
||||||
autoResize: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
chartData: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: function() {
|
|
||||||
return {
|
|
||||||
chart: null,
|
|
||||||
sidebarElm: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
chartData: {
|
|
||||||
deep: true,
|
|
||||||
handler(val) {
|
|
||||||
this.setOptions(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.initChart()
|
|
||||||
if (this.autoResize) {
|
|
||||||
this.__resizeHandler = debounce(() => {
|
|
||||||
if (this.chart) {
|
|
||||||
this.chart.resize()
|
|
||||||
}
|
|
||||||
}, 100)
|
|
||||||
window.addEventListener('resize', this.__resizeHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听侧边栏的变化
|
|
||||||
this.sidebarElm = document.getElementsByClassName('sidebar-container')[0]
|
|
||||||
this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
if (!this.chart) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.autoResize) {
|
|
||||||
window.removeEventListener('resize', this.__resizeHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler)
|
|
||||||
|
|
||||||
this.chart.dispose()
|
|
||||||
this.chart = null
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
sidebarResizeHandler(e) {
|
|
||||||
if (e.propertyName === 'width') {
|
|
||||||
this.__resizeHandler()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setOptions({ expectedData, actualData } = {}) {
|
|
||||||
this.chart.setOption({
|
|
||||||
xAxis: {
|
|
||||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
|
||||||
boundaryGap: false,
|
|
||||||
axisTick: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: 10,
|
|
||||||
right: 10,
|
|
||||||
bottom: 20,
|
|
||||||
top: 30,
|
|
||||||
containLabel: true
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'cross'
|
|
||||||
},
|
|
||||||
padding: [5, 10]
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
axisTick: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
data: ['expected', 'actual']
|
|
||||||
},
|
|
||||||
series: [{
|
|
||||||
name: 'expected', itemStyle: {
|
|
||||||
normal: {
|
|
||||||
color: '#FF005A',
|
|
||||||
lineStyle: {
|
|
||||||
color: '#FF005A',
|
|
||||||
width: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
smooth: true,
|
|
||||||
type: 'line',
|
|
||||||
data: expectedData,
|
|
||||||
animationDuration: 2800,
|
|
||||||
animationEasing: 'cubicInOut'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'actual',
|
|
||||||
smooth: true,
|
|
||||||
type: 'line',
|
|
||||||
itemStyle: {
|
|
||||||
normal: {
|
|
||||||
color: '#3888fa',
|
|
||||||
lineStyle: {
|
|
||||||
color: '#3888fa',
|
|
||||||
width: 2
|
|
||||||
},
|
|
||||||
areaStyle: {
|
|
||||||
color: '#f3f8ff'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: actualData,
|
|
||||||
animationDuration: 2800,
|
|
||||||
animationEasing: 'quadraticOut'
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
},
|
|
||||||
initChart() {
|
|
||||||
this.chart = echarts.init(this.$el, 'macarons')
|
|
||||||
this.setOptions(this.chartData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,138 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-row :gutter="40" class="panel-group">
|
|
||||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
|
||||||
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
|
|
||||||
<div class="card-panel-icon-wrapper icon-people">
|
|
||||||
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
|
|
||||||
</div>
|
|
||||||
<div class="card-panel-description">
|
|
||||||
<div class="card-panel-text">New Visits</div>
|
|
||||||
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
|
||||||
<div class="card-panel" @click="handleSetLineChartData('messages')">
|
|
||||||
<div class="card-panel-icon-wrapper icon-message">
|
|
||||||
<svg-icon icon-class="message" class-name="card-panel-icon" />
|
|
||||||
</div>
|
|
||||||
<div class="card-panel-description">
|
|
||||||
<div class="card-panel-text">Messages</div>
|
|
||||||
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
|
||||||
<div class="card-panel" @click="handleSetLineChartData('purchases')">
|
|
||||||
<div class="card-panel-icon-wrapper icon-money">
|
|
||||||
<svg-icon icon-class="money" class-name="card-panel-icon" />
|
|
||||||
</div>
|
|
||||||
<div class="card-panel-description">
|
|
||||||
<div class="card-panel-text">Purchases</div>
|
|
||||||
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
|
||||||
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
|
|
||||||
<div class="card-panel-icon-wrapper icon-shopping">
|
|
||||||
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
|
|
||||||
</div>
|
|
||||||
<div class="card-panel-description">
|
|
||||||
<div class="card-panel-text">Shoppings</div>
|
|
||||||
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import CountTo from 'vue-count-to'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
CountTo
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleSetLineChartData(type) {
|
|
||||||
this.$emit('handleSetLineChartData', type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
|
||||||
.panel-group {
|
|
||||||
margin-top: 18px;
|
|
||||||
.card-panel-col{
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
.card-panel {
|
|
||||||
height: 108px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 12px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
color: #666;
|
|
||||||
background: #fff;
|
|
||||||
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
|
|
||||||
border-color: rgba(0, 0, 0, .05);
|
|
||||||
&:hover {
|
|
||||||
.card-panel-icon-wrapper {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.icon-people {
|
|
||||||
background: #40c9c6;
|
|
||||||
}
|
|
||||||
.icon-message {
|
|
||||||
background: #36a3f7;
|
|
||||||
}
|
|
||||||
.icon-money {
|
|
||||||
background: #f4516c;
|
|
||||||
}
|
|
||||||
.icon-shopping {
|
|
||||||
background: #34bfa3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.icon-people {
|
|
||||||
color: #40c9c6;
|
|
||||||
}
|
|
||||||
.icon-message {
|
|
||||||
color: #36a3f7;
|
|
||||||
}
|
|
||||||
.icon-money {
|
|
||||||
color: #f4516c;
|
|
||||||
}
|
|
||||||
.icon-shopping {
|
|
||||||
color: #34bfa3
|
|
||||||
}
|
|
||||||
.card-panel-icon-wrapper {
|
|
||||||
float: left;
|
|
||||||
margin: 14px 0 0 14px;
|
|
||||||
padding: 16px;
|
|
||||||
transition: all 0.38s ease-out;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
.card-panel-icon {
|
|
||||||
float: left;
|
|
||||||
font-size: 48px;
|
|
||||||
}
|
|
||||||
.card-panel-description {
|
|
||||||
float: right;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 26px;
|
|
||||||
margin-left: 0px;
|
|
||||||
.card-panel-text {
|
|
||||||
line-height: 18px;
|
|
||||||
color: rgba(0, 0, 0, 0.45);
|
|
||||||
font-size: 16px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
.card-panel-num {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,84 +0,0 @@
|
||||||
<template>
|
|
||||||
<div :class="className" :style="{height:height,width:width}"/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import echarts from 'echarts'
|
|
||||||
require('echarts/theme/macarons') // echarts theme
|
|
||||||
import { debounce } from '@/utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
className: {
|
|
||||||
type: String,
|
|
||||||
default: 'chart'
|
|
||||||
},
|
|
||||||
width: {
|
|
||||||
type: String,
|
|
||||||
default: '100%'
|
|
||||||
},
|
|
||||||
height: {
|
|
||||||
type: String,
|
|
||||||
default: '300px'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: function() {
|
|
||||||
return {
|
|
||||||
chart: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.initChart()
|
|
||||||
this.__resizeHandler = debounce(() => {
|
|
||||||
if (this.chart) {
|
|
||||||
this.chart.resize()
|
|
||||||
}
|
|
||||||
}, 100)
|
|
||||||
window.addEventListener('resize', this.__resizeHandler)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
if (!this.chart) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
window.removeEventListener('resize', this.__resizeHandler)
|
|
||||||
this.chart.dispose()
|
|
||||||
this.chart = null
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initChart() {
|
|
||||||
this.chart = echarts.init(this.$el, 'macarons')
|
|
||||||
|
|
||||||
this.chart.setOption({
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item',
|
|
||||||
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
left: 'center',
|
|
||||||
bottom: '10',
|
|
||||||
data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
|
|
||||||
},
|
|
||||||
calculable: true,
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'WEEKLY WRITE ARTICLES',
|
|
||||||
type: 'pie',
|
|
||||||
roseType: 'radius',
|
|
||||||
radius: [15, 95],
|
|
||||||
center: ['50%', '38%'],
|
|
||||||
data: [
|
|
||||||
{ value: 320, name: 'Industries' },
|
|
||||||
{ value: 240, name: 'Technology' },
|
|
||||||
{ value: 149, name: 'Forex' },
|
|
||||||
{ value: 100, name: 'Gold' },
|
|
||||||
{ value: 59, name: 'Forecasts' }
|
|
||||||
],
|
|
||||||
animationEasing: 'cubicInOut',
|
|
||||||
animationDuration: 2600
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,120 +0,0 @@
|
||||||
<template>
|
|
||||||
<div :class="className" :style="{height:height,width:width}"/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import echarts from 'echarts'
|
|
||||||
require('echarts/theme/macarons') // echarts theme
|
|
||||||
import { debounce } from '@/utils'
|
|
||||||
|
|
||||||
const animationDuration = 3000
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
className: {
|
|
||||||
type: String,
|
|
||||||
default: 'chart'
|
|
||||||
},
|
|
||||||
width: {
|
|
||||||
type: String,
|
|
||||||
default: '100%'
|
|
||||||
},
|
|
||||||
height: {
|
|
||||||
type: String,
|
|
||||||
default: '300px'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: function() {
|
|
||||||
return {
|
|
||||||
chart: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.initChart()
|
|
||||||
this.__resizeHandler = debounce(() => {
|
|
||||||
if (this.chart) {
|
|
||||||
this.chart.resize()
|
|
||||||
}
|
|
||||||
}, 100)
|
|
||||||
window.addEventListener('resize', this.__resizeHandler)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
if (!this.chart) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
window.removeEventListener('resize', this.__resizeHandler)
|
|
||||||
this.chart.dispose()
|
|
||||||
this.chart = null
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initChart() {
|
|
||||||
this.chart = echarts.init(this.$el, 'macarons')
|
|
||||||
|
|
||||||
this.chart.setOption({
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
|
||||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
radar: {
|
|
||||||
radius: '66%',
|
|
||||||
center: ['50%', '42%'],
|
|
||||||
splitNumber: 8,
|
|
||||||
splitArea: {
|
|
||||||
areaStyle: {
|
|
||||||
color: 'rgba(127,95,132,.3)',
|
|
||||||
opacity: 1,
|
|
||||||
shadowBlur: 45,
|
|
||||||
shadowColor: 'rgba(0,0,0,.5)',
|
|
||||||
shadowOffsetX: 0,
|
|
||||||
shadowOffsetY: 15
|
|
||||||
}
|
|
||||||
},
|
|
||||||
indicator: [
|
|
||||||
{ name: 'Sales', max: 10000 },
|
|
||||||
{ name: 'Administration', max: 20000 },
|
|
||||||
{ name: 'Information Techology', max: 20000 },
|
|
||||||
{ name: 'Customer Support', max: 20000 },
|
|
||||||
{ name: 'Development', max: 20000 },
|
|
||||||
{ name: 'Marketing', max: 20000 }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
left: 'center',
|
|
||||||
bottom: '10',
|
|
||||||
data: ['Allocated Budget', 'Expected Spending', 'Actual Spending']
|
|
||||||
},
|
|
||||||
series: [{
|
|
||||||
type: 'radar',
|
|
||||||
symbolSize: 0,
|
|
||||||
areaStyle: {
|
|
||||||
normal: {
|
|
||||||
shadowBlur: 13,
|
|
||||||
shadowColor: 'rgba(0,0,0,.2)',
|
|
||||||
shadowOffsetX: 0,
|
|
||||||
shadowOffsetY: 10,
|
|
||||||
opacity: 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: [5000, 7000, 12000, 11000, 15000, 14000],
|
|
||||||
name: 'Allocated Budget'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: [4000, 9000, 15000, 15000, 13000, 11000],
|
|
||||||
name: 'Expected Spending'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: [5500, 11000, 12000, 15000, 12000, 12000],
|
|
||||||
name: 'Actual Spending'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
animationDuration: animationDuration
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,79 +0,0 @@
|
||||||
<template>
|
|
||||||
<li :class="{ completed: todo.done, editing: editing }" class="todo">
|
|
||||||
<div class="view">
|
|
||||||
<input
|
|
||||||
:checked="todo.done"
|
|
||||||
class="toggle"
|
|
||||||
type="checkbox"
|
|
||||||
@change="toggleTodo( todo)">
|
|
||||||
<label @dblclick="editing = true" v-text="todo.text"/>
|
|
||||||
<button class="destroy" @click="deleteTodo( todo )"/>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
v-focus="editing"
|
|
||||||
v-show="editing"
|
|
||||||
:value="todo.text"
|
|
||||||
class="edit"
|
|
||||||
@keyup.enter="doneEdit"
|
|
||||||
@keyup.esc="cancelEdit"
|
|
||||||
@blur="doneEdit">
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'Todo',
|
|
||||||
directives: {
|
|
||||||
focus(el, { value }, { context }) {
|
|
||||||
if (value) {
|
|
||||||
context.$nextTick(() => {
|
|
||||||
el.focus()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
todo: {
|
|
||||||
type: Object,
|
|
||||||
default: function() {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: function() {
|
|
||||||
return {
|
|
||||||
editing: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
deleteTodo(todo) {
|
|
||||||
this.$emit('deleteTodo', todo)
|
|
||||||
},
|
|
||||||
editTodo({ todo, value }) {
|
|
||||||
this.$emit('editTodo', { todo, value })
|
|
||||||
},
|
|
||||||
toggleTodo(todo) {
|
|
||||||
this.$emit('toggleTodo', todo)
|
|
||||||
},
|
|
||||||
doneEdit(e) {
|
|
||||||
const value = e.target.value.trim()
|
|
||||||
const { todo } = this
|
|
||||||
if (!value) {
|
|
||||||
this.deleteTodo({
|
|
||||||
todo
|
|
||||||
})
|
|
||||||
} else if (this.editing) {
|
|
||||||
this.editTodo({
|
|
||||||
todo,
|
|
||||||
value
|
|
||||||
})
|
|
||||||
this.editing = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cancelEdit(e) {
|
|
||||||
e.target.value = this.todo.text
|
|
||||||
this.editing = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,320 +0,0 @@
|
||||||
.todoapp {
|
|
||||||
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
||||||
line-height: 1.4em;
|
|
||||||
color: #4d4d4d;
|
|
||||||
min-width: 230px;
|
|
||||||
max-width: 550px;
|
|
||||||
margin: 0 auto ;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
font-weight: 300;
|
|
||||||
background: #fff;
|
|
||||||
z-index: 1;
|
|
||||||
position: relative;
|
|
||||||
button {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
background: none;
|
|
||||||
font-size: 100%;
|
|
||||||
vertical-align: baseline;
|
|
||||||
font-family: inherit;
|
|
||||||
font-weight: inherit;
|
|
||||||
color: inherit;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
:focus {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.todoapp {
|
|
||||||
background: #fff;
|
|
||||||
margin: 130px 0 40px 0;
|
|
||||||
position: relative;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
.todoapp input::-webkit-input-placeholder {
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #e6e6e6;
|
|
||||||
}
|
|
||||||
.todoapp input::-moz-placeholder {
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #e6e6e6;
|
|
||||||
}
|
|
||||||
.todoapp input::input-placeholder {
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #e6e6e6;
|
|
||||||
}
|
|
||||||
.todoapp h1 {
|
|
||||||
position: absolute;
|
|
||||||
top: -155px;
|
|
||||||
width: 100%;
|
|
||||||
font-size: 100px;
|
|
||||||
font-weight: 100;
|
|
||||||
text-align: center;
|
|
||||||
color: rgba(175, 47, 47, 0.15);
|
|
||||||
-webkit-text-rendering: optimizeLegibility;
|
|
||||||
-moz-text-rendering: optimizeLegibility;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
}
|
|
||||||
.new-todo,
|
|
||||||
.edit {
|
|
||||||
position: relative;
|
|
||||||
margin: 0;
|
|
||||||
width: 100%;
|
|
||||||
font-size: 18px;
|
|
||||||
font-family: inherit;
|
|
||||||
font-weight: inherit;
|
|
||||||
line-height: 1.4em;
|
|
||||||
border: 0;
|
|
||||||
color: inherit;
|
|
||||||
padding: 6px;
|
|
||||||
border: 1px solid #999;
|
|
||||||
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
.new-todo {
|
|
||||||
padding: 10px 16px 16px 60px;
|
|
||||||
border: none;
|
|
||||||
background: rgba(0, 0, 0, 0.003);
|
|
||||||
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
|
|
||||||
}
|
|
||||||
.main {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
border-top: 1px solid #e6e6e6;
|
|
||||||
}
|
|
||||||
.toggle-all {
|
|
||||||
text-align: center;
|
|
||||||
border: none;
|
|
||||||
/* Mobile Safari */
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.toggle-all+label {
|
|
||||||
width: 60px;
|
|
||||||
height: 34px;
|
|
||||||
font-size: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: -52px;
|
|
||||||
left: -13px;
|
|
||||||
-webkit-transform: rotate(90deg);
|
|
||||||
transform: rotate(90deg);
|
|
||||||
}
|
|
||||||
.toggle-all+label:before {
|
|
||||||
content: '❯';
|
|
||||||
font-size: 22px;
|
|
||||||
color: #e6e6e6;
|
|
||||||
padding: 10px 27px 10px 27px;
|
|
||||||
}
|
|
||||||
.toggle-all:checked+label:before {
|
|
||||||
color: #737373;
|
|
||||||
}
|
|
||||||
.todo-list {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
.todo-list li {
|
|
||||||
position: relative;
|
|
||||||
font-size: 24px;
|
|
||||||
border-bottom: 1px solid #ededed;
|
|
||||||
}
|
|
||||||
.todo-list li:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
.todo-list li.editing {
|
|
||||||
border-bottom: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.todo-list li.editing .edit {
|
|
||||||
display: block;
|
|
||||||
width: 506px;
|
|
||||||
padding: 12px 16px;
|
|
||||||
margin: 0 0 0 43px;
|
|
||||||
}
|
|
||||||
.todo-list li.editing .view {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.todo-list li .toggle {
|
|
||||||
text-align: center;
|
|
||||||
width: 40px;
|
|
||||||
/* auto, since non-WebKit browsers doesn't support input styling */
|
|
||||||
height: auto;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
margin: auto 0;
|
|
||||||
border: none;
|
|
||||||
/* Mobile Safari */
|
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
}
|
|
||||||
.todo-list li .toggle {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
.todo-list li .toggle+label {
|
|
||||||
/*
|
|
||||||
Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
|
|
||||||
IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
|
|
||||||
*/
|
|
||||||
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center left;
|
|
||||||
background-size: 36px;
|
|
||||||
}
|
|
||||||
.todo-list li .toggle:checked+label {
|
|
||||||
background-size: 36px;
|
|
||||||
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E');
|
|
||||||
}
|
|
||||||
.todo-list li label {
|
|
||||||
word-break: break-all;
|
|
||||||
padding: 15px 15px 15px 50px;
|
|
||||||
display: block;
|
|
||||||
line-height: 1.0;
|
|
||||||
font-size: 14px;
|
|
||||||
transition: color 0.4s;
|
|
||||||
}
|
|
||||||
.todo-list li.completed label {
|
|
||||||
color: #d9d9d9;
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
.todo-list li .destroy {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 10px;
|
|
||||||
bottom: 0;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
margin: auto 0;
|
|
||||||
font-size: 30px;
|
|
||||||
color: #cc9a9a;
|
|
||||||
transition: color 0.2s ease-out;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.todo-list li .destroy:hover {
|
|
||||||
color: #af5b5e;
|
|
||||||
}
|
|
||||||
.todo-list li .destroy:after {
|
|
||||||
content: '×';
|
|
||||||
}
|
|
||||||
.todo-list li:hover .destroy {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.todo-list li .edit {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.todo-list li.editing:last-child {
|
|
||||||
margin-bottom: -1px;
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
color: #777;
|
|
||||||
position: relative;
|
|
||||||
padding: 10px 15px;
|
|
||||||
height: 40px;
|
|
||||||
text-align: center;
|
|
||||||
border-top: 1px solid #e6e6e6;
|
|
||||||
}
|
|
||||||
.footer:before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 40px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
.todo-count {
|
|
||||||
float: left;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.todo-count strong {
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
.filters {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
.filters li {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.filters li a {
|
|
||||||
color: inherit;
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 3px 7px;
|
|
||||||
text-decoration: none;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
.filters li a:hover {
|
|
||||||
border-color: rgba(175, 47, 47, 0.1);
|
|
||||||
}
|
|
||||||
.filters li a.selected {
|
|
||||||
border-color: rgba(175, 47, 47, 0.2);
|
|
||||||
}
|
|
||||||
.clear-completed,
|
|
||||||
html .clear-completed:active {
|
|
||||||
float: right;
|
|
||||||
position: relative;
|
|
||||||
line-height: 20px;
|
|
||||||
text-decoration: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.clear-completed:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.info {
|
|
||||||
margin: 65px auto 0;
|
|
||||||
color: #bfbfbf;
|
|
||||||
font-size: 10px;
|
|
||||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.info p {
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.info a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
.info a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Hack to remove background from Mobile Safari.
|
|
||||||
Can't use it globally since it destroys checkboxes in Firefox
|
|
||||||
*/
|
|
||||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
|
||||||
.toggle-all,
|
|
||||||
.todo-list li .toggle {
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
.todo-list li .toggle {
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: 430px) {
|
|
||||||
.footer {
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
.filters {
|
|
||||||
bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|