Compare commits
1295 Commits
v3.10.11-l
...
pr@pam@fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbce3bd010 | ||
|
|
cd974b80ce | ||
|
|
880c44fdaa | ||
|
|
2a0f6dc1df | ||
|
|
dadfc9a240 | ||
|
|
598d3803dc | ||
|
|
f5bd0f0533 | ||
|
|
63db09a22f | ||
|
|
6c6399abc0 | ||
|
|
0968a4d7ef | ||
|
|
c5bc1ab833 | ||
|
|
819bbae3e5 | ||
|
|
0dd11735fc | ||
|
|
972e420354 | ||
|
|
2da3b2ac75 | ||
|
|
1fdfd8e2d8 | ||
|
|
48662ed9f4 | ||
|
|
485f45a2ea | ||
|
|
fa93f52f87 | ||
|
|
f0b332a269 | ||
|
|
f61a535454 | ||
|
|
ebebfcd03e | ||
|
|
3ac0ce7429 | ||
|
|
a34b2c7074 | ||
|
|
88a66039ce | ||
|
|
c637f0e93a | ||
|
|
f3792720b7 | ||
|
|
4a1f4c88cf | ||
|
|
8546f9f735 | ||
|
|
cc4b5183ea | ||
|
|
e361bcbf42 | ||
|
|
8e461e8aed | ||
|
|
b6ae2aa2f8 | ||
|
|
f985c75fc5 | ||
|
|
c2b176376f | ||
|
|
3d0e6fc3d1 | ||
|
|
3752d23b42 | ||
|
|
ace605884e | ||
|
|
e8e3ca123b | ||
|
|
137c59a1e1 | ||
|
|
b0d989e1da | ||
|
|
bd4b5ec0c3 | ||
|
|
f13e7fd1d0 | ||
|
|
8be5c22ae4 | ||
|
|
4722384741 | ||
|
|
0952a571b3 | ||
|
|
1dd00bbfa7 | ||
|
|
79a1a1faef | ||
|
|
8ef4b466d7 | ||
|
|
4ccc7ac56b | ||
|
|
7fb24cadea | ||
|
|
e89be5f278 | ||
|
|
b746e1d553 | ||
|
|
b8b764c04c | ||
|
|
45532a3eb6 | ||
|
|
ffee484d6c | ||
|
|
9e4afd5271 | ||
|
|
d5099c3a04 | ||
|
|
2558cfa4c2 | ||
|
|
6357056600 | ||
|
|
c1b60e6298 | ||
|
|
f2b45c5084 | ||
|
|
a451f38701 | ||
|
|
e6efd91414 | ||
|
|
19469508f7 | ||
|
|
5166287b0e | ||
|
|
494c4c5753 | ||
|
|
27e2d34171 | ||
|
|
eddff3d75b | ||
|
|
910bef6695 | ||
|
|
fa2faecb7c | ||
|
|
e6cd2306c9 | ||
|
|
59945ad798 | ||
|
|
ded7920a8a | ||
|
|
60b8748b95 | ||
|
|
f1956b4982 | ||
|
|
5708aa25c4 | ||
|
|
f2e6f89c08 | ||
|
|
1c222c3ce0 | ||
|
|
d6c28b8286 | ||
|
|
0cd9f6dcd6 | ||
|
|
b2abee724d | ||
|
|
3e3cb309ce | ||
|
|
55c8dfa549 | ||
|
|
9740c58291 | ||
|
|
77558186a4 | ||
|
|
d94752a021 | ||
|
|
b524848742 | ||
|
|
339c1ab227 | ||
|
|
1bdc27ea98 | ||
|
|
19dc42cd2c | ||
|
|
7375dc58a3 | ||
|
|
ee678289d4 | ||
|
|
c932fbb5f3 | ||
|
|
768cae7abc | ||
|
|
5abb8a867f | ||
|
|
c4bba7e74d | ||
|
|
e365f874bc | ||
|
|
f54e2c8ddc | ||
|
|
e93979ab5f | ||
|
|
5d5e87595b | ||
|
|
ff769179a8 | ||
|
|
8546388439 | ||
|
|
7dcecd4421 | ||
|
|
4bc039185c | ||
|
|
efef672157 | ||
|
|
ec8c8e7d4b | ||
|
|
c14970e232 | ||
|
|
bee45ee7a0 | ||
|
|
7bfc0ee507 | ||
|
|
9e768f4ef4 | ||
|
|
0e53d7e657 | ||
|
|
906a1accd1 | ||
|
|
1e381b06ee | ||
|
|
731ae82bc5 | ||
|
|
8019ee550e | ||
|
|
d7affe1034 | ||
|
|
5f35e0bb94 | ||
|
|
75b70d33ee | ||
|
|
e3c17ef96d | ||
|
|
0f6ae3f626 | ||
|
|
175b819e8e | ||
|
|
9933f68ba9 | ||
|
|
44e05e7f80 | ||
|
|
f518e4cb10 | ||
|
|
b127849388 | ||
|
|
7524b6f895 | ||
|
|
0a96331218 | ||
|
|
caf34a96e6 | ||
|
|
5645d253e5 | ||
|
|
e2ad3f3749 | ||
|
|
b1137249f1 | ||
|
|
369247d987 | ||
|
|
fe8f594cb4 | ||
|
|
64db1176a6 | ||
|
|
27d175a06e | ||
|
|
3b96b3c90b | ||
|
|
32183336a2 | ||
|
|
fb9d9d6480 | ||
|
|
7394ff27a5 | ||
|
|
6093d8915c | ||
|
|
83bb13b806 | ||
|
|
c9062a9e26 | ||
|
|
6dc7cc0b37 | ||
|
|
aa631678f8 | ||
|
|
1c36d1b3c6 | ||
|
|
90050bf87d | ||
|
|
58bb69c252 | ||
|
|
14c3b249a7 | ||
|
|
4589c4abaf | ||
|
|
94f1959d40 | ||
|
|
e7c63b2d41 | ||
|
|
e2904acff6 | ||
|
|
3d1a2d6833 | ||
|
|
d1e340f104 | ||
|
|
d1a48a2e56 | ||
|
|
6d8f159975 | ||
|
|
5925ac448e | ||
|
|
fdb1dd886b | ||
|
|
7075b5c90a | ||
|
|
66b3018ace | ||
|
|
87ae6242a1 | ||
|
|
de5f1a8bd1 | ||
|
|
9cefe70061 | ||
|
|
73cbd4d8d2 | ||
|
|
02d9f6b116 | ||
|
|
1f5cc25b86 | ||
|
|
63200bca26 | ||
|
|
305029649e | ||
|
|
cfb7292f36 | ||
|
|
582b83d4f5 | ||
|
|
42eaa4996d | ||
|
|
df465eef29 | ||
|
|
b3f8c61df0 | ||
|
|
6f57ef5bcf | ||
|
|
7ca47d9015 | ||
|
|
b9a0bbf12d | ||
|
|
4a8c84ee9d | ||
|
|
2f9ad17b1f | ||
|
|
e8e1b35cd3 | ||
|
|
edd85e700e | ||
|
|
a7378d297f | ||
|
|
dd75e160c3 | ||
|
|
84c78f993b | ||
|
|
25ba669f67 | ||
|
|
3bb3361e2f | ||
|
|
d82e557fd1 | ||
|
|
3c9de27e66 | ||
|
|
276b1a7255 | ||
|
|
25c7d0a372 | ||
|
|
31c630ca25 | ||
|
|
e5eaa05bdb | ||
|
|
2431755f2b | ||
|
|
29f35d590e | ||
|
|
ac9451dd1c | ||
|
|
b4ee023b93 | ||
|
|
28e7321754 | ||
|
|
daab079e3c | ||
|
|
a32f818abd | ||
|
|
d8980e66e3 | ||
|
|
46898d2419 | ||
|
|
153c29fbcc | ||
|
|
feb3dbabc2 | ||
|
|
0ac1e0d75a | ||
|
|
572e61046f | ||
|
|
9f47b50dac | ||
|
|
5022ca9075 | ||
|
|
fee2123b49 | ||
|
|
78e6d4e367 | ||
|
|
a5b8d51747 | ||
|
|
e9245dfd19 | ||
|
|
f605192fe1 | ||
|
|
504adad9fe | ||
|
|
cd82d8ee92 | ||
|
|
d97dbc612c | ||
|
|
368bad6771 | ||
|
|
41cc618a49 | ||
|
|
4f0f1b372e | ||
|
|
acfac6d45f | ||
|
|
1a3f483654 | ||
|
|
559177ea32 | ||
|
|
c9f9264c87 | ||
|
|
8fabd32426 | ||
|
|
6a34bb426c | ||
|
|
a1edc55ca0 | ||
|
|
d1366f161d | ||
|
|
b58754b6c5 | ||
|
|
ee3e68f3ac | ||
|
|
3a0af18f74 | ||
|
|
24f30ab198 | ||
|
|
72b9447b12 | ||
|
|
7e24454743 | ||
|
|
48d81dbd19 | ||
|
|
cdf0a9eed1 | ||
|
|
59cf22a421 | ||
|
|
41a34fb2d7 | ||
|
|
4164ea4086 | ||
|
|
a2db27163e | ||
|
|
5a0b4ec6aa | ||
|
|
4cfb1a6f37 | ||
|
|
e2f7fd0d77 | ||
|
|
80d530a2ed | ||
|
|
a1a06e1cbf | ||
|
|
6bec731396 | ||
|
|
ac40823319 | ||
|
|
ef063898ca | ||
|
|
b27a801b04 | ||
|
|
4bcee2fc2d | ||
|
|
b0672bb543 | ||
|
|
7b0ea02ad4 | ||
|
|
eaf7ba5f43 | ||
|
|
28b4aa0d55 | ||
|
|
d9ec7917f3 | ||
|
|
ac6040177a | ||
|
|
f2ac6a61ab | ||
|
|
5f904f99b6 | ||
|
|
6fbef03b33 | ||
|
|
98aa11bb64 | ||
|
|
fba83f39bd | ||
|
|
c3a2c3c23d | ||
|
|
5125038e9c | ||
|
|
42ca29bdaf | ||
|
|
48e4027525 | ||
|
|
1c4893bc22 | ||
|
|
2955b4800f | ||
|
|
5a26589052 | ||
|
|
4c2cdc1232 | ||
|
|
cb6e40bea7 | ||
|
|
4c61a84652 | ||
|
|
ffaca80b21 | ||
|
|
395b204da3 | ||
|
|
0f5f6b860b | ||
|
|
a9ba931bba | ||
|
|
23fae59411 | ||
|
|
320613d15d | ||
|
|
57ea32e785 | ||
|
|
3e3f80c59b | ||
|
|
c15ba5b078 | ||
|
|
651888faab | ||
|
|
71ebd6bf56 | ||
|
|
0494ce7f5b | ||
|
|
fdf869cd46 | ||
|
|
7dfca604c2 | ||
|
|
d220047fe2 | ||
|
|
bbe80f0292 | ||
|
|
41e73a2c9b | ||
|
|
7d89cf9f45 | ||
|
|
b4abcd4c90 | ||
|
|
8a048f692f | ||
|
|
70777f8335 | ||
|
|
800317346c | ||
|
|
d62c87b858 | ||
|
|
4a1e2db7ca | ||
|
|
743187b4b3 | ||
|
|
5c1f24af6a | ||
|
|
6702d94ba1 | ||
|
|
9477bfa2c1 | ||
|
|
1ba58f476f | ||
|
|
02600d7a1b | ||
|
|
a87d04fb9d | ||
|
|
2126c92e07 | ||
|
|
367db0daf1 | ||
|
|
af774a8835 | ||
|
|
b93fad1f91 | ||
|
|
ef43be0cb7 | ||
|
|
583b28a6c4 | ||
|
|
8b6eea0267 | ||
|
|
d0da22738f | ||
|
|
ec5f2e69eb | ||
|
|
d058f0e777 | ||
|
|
89befaad43 | ||
|
|
18eda16851 | ||
|
|
610e9b9efa | ||
|
|
a0c7d60719 | ||
|
|
60ba0d8f02 | ||
|
|
b9afb05f1b | ||
|
|
fcf9ea2b79 | ||
|
|
430b1117c9 | ||
|
|
a65023c8f7 | ||
|
|
d6de85ffdd | ||
|
|
5f11d8b54f | ||
|
|
c7ce602d4c | ||
|
|
d0988da277 | ||
|
|
7f13ef35a7 | ||
|
|
548d0e0670 | ||
|
|
44348de4ab | ||
|
|
be82fe1bde | ||
|
|
2e472dad93 | ||
|
|
7b862ee0e1 | ||
|
|
bbfb237f23 | ||
|
|
d4e37e9418 | ||
|
|
b53b1d1e58 | ||
|
|
390224613a | ||
|
|
7e0c677ad3 | ||
|
|
9936f2b806 | ||
|
|
bfde8bd28b | ||
|
|
4b309d950c | ||
|
|
688f06ebac | ||
|
|
6fb3b552eb | ||
|
|
f27e7bdad4 | ||
|
|
2ee139c92b | ||
|
|
7a6c156aaa | ||
|
|
0342c73f07 | ||
|
|
727d9037d1 | ||
|
|
11d40b4be1 | ||
|
|
b772580f99 | ||
|
|
fafdb6be5b | ||
|
|
2f984530e3 | ||
|
|
b24c244186 | ||
|
|
d365aea6a0 | ||
|
|
115f1171ad | ||
|
|
b2b477d4e0 | ||
|
|
1e37ecff11 | ||
|
|
68b39bbc3d | ||
|
|
d21dc57305 | ||
|
|
9cf87404be | ||
|
|
2e51b0dea1 | ||
|
|
a1f20c6f92 | ||
|
|
6b6a60b84f | ||
|
|
c58d826898 | ||
|
|
7e80361635 | ||
|
|
4e999176ed | ||
|
|
76ff273ec7 | ||
|
|
475a77497f | ||
|
|
5d1301c871 | ||
|
|
772f40e13d | ||
|
|
1b2f7ad28c | ||
|
|
84778881f6 | ||
|
|
d6d0338666 | ||
|
|
de6f477d05 | ||
|
|
03e07ee280 | ||
|
|
35e2273603 | ||
|
|
7a138388b2 | ||
|
|
b1f42dd6bf | ||
|
|
2eeba4ee4f | ||
|
|
d91579e848 | ||
|
|
13751f14f3 | ||
|
|
b25d2016a6 | ||
|
|
7ea00e17bd | ||
|
|
ec78370ecc | ||
|
|
636630fe57 | ||
|
|
e18726efc2 | ||
|
|
c9f62ae5d3 | ||
|
|
b80b69dd26 | ||
|
|
ac49415061 | ||
|
|
823c26aa5e | ||
|
|
c0c9d56408 | ||
|
|
9edb64837d | ||
|
|
671fa65930 | ||
|
|
0da81ea60d | ||
|
|
c610d396d6 | ||
|
|
ff4adde897 | ||
|
|
0ed02ca7f7 | ||
|
|
c22981e2c1 | ||
|
|
b0af35a4b9 | ||
|
|
45ae7cab21 | ||
|
|
1d16a165a5 | ||
|
|
f1f4242ad6 | ||
|
|
bff8f10cd5 | ||
|
|
429f5aed90 | ||
|
|
d8999ffc06 | ||
|
|
fd745f0a26 | ||
|
|
322d12f27f | ||
|
|
305e44ea1c | ||
|
|
a1bc8ac5bc | ||
|
|
9271cb2e1a | ||
|
|
0e7c682f72 | ||
|
|
c0b4029917 | ||
|
|
b1acb62889 | ||
|
|
26fd9b1813 | ||
|
|
4fabdfdc5f | ||
|
|
6e894c31a1 | ||
|
|
d8a6fd96ce | ||
|
|
7c5c5f966d | ||
|
|
a636bb2037 | ||
|
|
9b6f54c1ed | ||
|
|
611341307b | ||
|
|
f8479c53ff | ||
|
|
8b25fd198e | ||
|
|
e25bf46659 | ||
|
|
6d07307e56 | ||
|
|
6fb7fe8fa1 | ||
|
|
762fa4c17e | ||
|
|
19cd497095 | ||
|
|
73cc319e7b | ||
|
|
d858489367 | ||
|
|
d90aba37cf | ||
|
|
341a30ba06 | ||
|
|
d775ffa501 | ||
|
|
e8cf8347e9 | ||
|
|
8390fb7429 | ||
|
|
5389f1d011 | ||
|
|
bde642570f | ||
|
|
3e7b970fe7 | ||
|
|
7ff1da71d4 | ||
|
|
2421e822b4 | ||
|
|
b2e474e3f6 | ||
|
|
a23a0d0197 | ||
|
|
541836390a | ||
|
|
bb92e3f22b | ||
|
|
c9ad797b40 | ||
|
|
2a08310efc | ||
|
|
3b2803b9a1 | ||
|
|
1b8ac9112e | ||
|
|
9cc3dd4de9 | ||
|
|
120ef70eb1 | ||
|
|
541f4ebc62 | ||
|
|
a47636abc7 | ||
|
|
78f6f4b36a | ||
|
|
5abc0b77cf | ||
|
|
464638e782 | ||
|
|
37cfeb2077 | ||
|
|
44e297f01a | ||
|
|
febc283e36 | ||
|
|
dae33f55e8 | ||
|
|
c62cd27690 | ||
|
|
83443f8187 | ||
|
|
cb46f393e0 | ||
|
|
ddf5ac2151 | ||
|
|
88173f852a | ||
|
|
d5f16e90e2 | ||
|
|
d1c0aca4ff | ||
|
|
a42edf17ec | ||
|
|
dac5dfcd1c | ||
|
|
8e6ca146e1 | ||
|
|
9c06d36eab | ||
|
|
ab7bd574f8 | ||
|
|
6007dc8621 | ||
|
|
a0e7c48dc9 | ||
|
|
71dea791bf | ||
|
|
e1b9184f41 | ||
|
|
730d47f02a | ||
|
|
e82ec68935 | ||
|
|
e8e5975d7f | ||
|
|
3cb9dec978 | ||
|
|
c025441075 | ||
|
|
050b50fa74 | ||
|
|
e26befabc3 | ||
|
|
8545fc6136 | ||
|
|
1477712c78 | ||
|
|
e343e0df9d | ||
|
|
74519e6f3c | ||
|
|
1305f90372 | ||
|
|
bbc3f53c0a | ||
|
|
aa605adbc7 | ||
|
|
49ea7d0969 | ||
|
|
4221bdb2ab | ||
|
|
77a0100add | ||
|
|
833e44024f | ||
|
|
af4010e299 | ||
|
|
9b7c4ed353 | ||
|
|
879df90503 | ||
|
|
41f841532f | ||
|
|
0b9f47dd84 | ||
|
|
d32a376e8c | ||
|
|
0f8a8845df | ||
|
|
8bb2c66b99 | ||
|
|
b3d0be2f60 | ||
|
|
5a94ddd976 | ||
|
|
7b9627a80b | ||
|
|
5fcfecc060 | ||
|
|
f4d7a2283c | ||
|
|
40bb8410d3 | ||
|
|
45344ac620 | ||
|
|
5b894c9667 | ||
|
|
d89bd15b6d | ||
|
|
5e640dd45c | ||
|
|
09aa750794 | ||
|
|
744b215800 | ||
|
|
f4e11da053 | ||
|
|
2e6b5706d5 | ||
|
|
440a5b27ef | ||
|
|
932e16844e | ||
|
|
aff2e439dd | ||
|
|
a618794c14 | ||
|
|
8dd66c400a | ||
|
|
ac3ce464b7 | ||
|
|
4d01c6dabe | ||
|
|
47eeac23eb | ||
|
|
592f783245 | ||
|
|
c34ac6a56f | ||
|
|
9a7162cc9e | ||
|
|
5edf2f34dd | ||
|
|
859d824195 | ||
|
|
c382cc633e | ||
|
|
653e24773f | ||
|
|
ae489610ee | ||
|
|
b5e85c66e4 | ||
|
|
4060fa4c4a | ||
|
|
9630b79daa | ||
|
|
ad93917387 | ||
|
|
691590da7b | ||
|
|
71828fd78b | ||
|
|
5a45f31ac4 | ||
|
|
44901eee23 | ||
|
|
2d91fa107d | ||
|
|
7a6ade4bd9 | ||
|
|
951778668f | ||
|
|
0aca23bf38 | ||
|
|
9b97dc9a74 | ||
|
|
32cd030479 | ||
|
|
607bb476db | ||
|
|
1d676ec9b7 | ||
|
|
614ebb4121 | ||
|
|
8c2719a95d | ||
|
|
c6b0a958a6 | ||
|
|
3edebf3f4f | ||
|
|
f63405978e | ||
|
|
c582c8de98 | ||
|
|
c44e79ed3b | ||
|
|
fc7d5b9c29 | ||
|
|
335febd4a5 | ||
|
|
5ea2918fe7 | ||
|
|
7668d10ba5 | ||
|
|
df15d141da | ||
|
|
e2f4bbde79 | ||
|
|
3ca7de42af | ||
|
|
e6a577ba9b | ||
|
|
6290179460 | ||
|
|
4f3c9e9353 | ||
|
|
aa28a8f765 | ||
|
|
98d0a52fa2 | ||
|
|
8d9e1ffadb | ||
|
|
b3be312a4d | ||
|
|
7c41d148aa | ||
|
|
6dee911642 | ||
|
|
6dd35e5173 | ||
|
|
fdaa33f68d | ||
|
|
0b813bb719 | ||
|
|
7ba6b8d4e4 | ||
|
|
ef99e25fde | ||
|
|
d1e7b907e3 | ||
|
|
83f7dda5e7 | ||
|
|
80f929fdea | ||
|
|
1ec3d02933 | ||
|
|
fdf148cc2b | ||
|
|
c9e6ef89dc | ||
|
|
59f9f88f8b | ||
|
|
16417ae843 | ||
|
|
58bd0a17c8 | ||
|
|
c4a1eb6938 | ||
|
|
b7d9031889 | ||
|
|
96b29a9dc2 | ||
|
|
336e176639 | ||
|
|
2df4a9d66d | ||
|
|
45a102cff1 | ||
|
|
57ebfa0812 | ||
|
|
4e9dd57efe | ||
|
|
3fcc4ca160 | ||
|
|
958760811c | ||
|
|
b60e0251c2 | ||
|
|
3db0ed756e | ||
|
|
453c4b1e4e | ||
|
|
bf4d8ce7a6 | ||
|
|
34effdbe15 | ||
|
|
274db466f2 | ||
|
|
cbe697f9dc | ||
|
|
fb7acb100e | ||
|
|
ebb36847df | ||
|
|
beba4f1994 | ||
|
|
452796e3f5 | ||
|
|
02a7969d90 | ||
|
|
798dbec151 | ||
|
|
0e11a56e37 | ||
|
|
be5344344c | ||
|
|
e75d711e0a | ||
|
|
46ee116f3e | ||
|
|
f4b304338f | ||
|
|
e93e78307c | ||
|
|
d22079446f | ||
|
|
d57b99b00c | ||
|
|
e7321356af | ||
|
|
a0edc2c527 | ||
|
|
10ebcfd64d | ||
|
|
a3fedb9697 | ||
|
|
1eb8a18c66 | ||
|
|
f491c57c34 | ||
|
|
50b7f54652 | ||
|
|
5bf298a5bf | ||
|
|
124ff9a8c2 | ||
|
|
387ab4f1b3 | ||
|
|
d6fbdfa7ea | ||
|
|
cd4260fd8d | ||
|
|
baeece62d3 | ||
|
|
576c8f5891 | ||
|
|
5e97600807 | ||
|
|
4e2eb3a37d | ||
|
|
e92173f8e8 | ||
|
|
412d9c804e | ||
|
|
b84a725d4a | ||
|
|
58b39743e0 | ||
|
|
7651443c25 | ||
|
|
8d64e331d1 | ||
|
|
f873254248 | ||
|
|
c569d0c21c | ||
|
|
95d1e23cf8 | ||
|
|
a976948388 | ||
|
|
38aadbd8e4 | ||
|
|
257ddd9517 | ||
|
|
2630eddb41 | ||
|
|
5d84b7c874 | ||
|
|
017884e7cc | ||
|
|
682528367d | ||
|
|
d1b343dfd4 | ||
|
|
1e120f6b77 | ||
|
|
e59c129e50 | ||
|
|
4ad17c33a5 | ||
|
|
31179d665e | ||
|
|
8476cd3dd9 | ||
|
|
d442f9bc7d | ||
|
|
f7c48072c4 | ||
|
|
2690f1904b | ||
|
|
6d72a5af4a | ||
|
|
c4ddfb7d64 | ||
|
|
d388cb3059 | ||
|
|
07223c0e31 | ||
|
|
6a492a83bf | ||
|
|
1f6346dbe1 | ||
|
|
4ab788364e | ||
|
|
9849c0e47b | ||
|
|
3d86e75bc8 | ||
|
|
265466c549 | ||
|
|
7e3808c4b9 | ||
|
|
7c141b5183 | ||
|
|
cccec1aa1b | ||
|
|
7c3effe1d9 | ||
|
|
4717b21abb | ||
|
|
44bd9cb8c7 | ||
|
|
117bccc520 | ||
|
|
fb86ac4060 | ||
|
|
dae1fef629 | ||
|
|
455496adcf | ||
|
|
3b50431e57 | ||
|
|
27765ca866 | ||
|
|
9dad31c75a | ||
|
|
04067f5729 | ||
|
|
edcff7d640 | ||
|
|
1b5f20f9e4 | ||
|
|
add8bd0f01 | ||
|
|
83c5cf4231 | ||
|
|
fc4ffe53a5 | ||
|
|
92e66981a8 | ||
|
|
98153ff98c | ||
|
|
89246186d0 | ||
|
|
31faca5d3f | ||
|
|
ed371dba4f | ||
|
|
0ac4337f98 | ||
|
|
526a2eb1d8 | ||
|
|
9ce7ebd600 | ||
|
|
3e00c06766 | ||
|
|
2c9e1f6d3a | ||
|
|
0a57f3afc7 | ||
|
|
ee31b501af | ||
|
|
4e79074cef | ||
|
|
ada6479177 | ||
|
|
32585e4abc | ||
|
|
861bce244e | ||
|
|
5412647971 | ||
|
|
887496fe51 | ||
|
|
1f3d29560d | ||
|
|
d3c018dc4a | ||
|
|
8a7f358b06 | ||
|
|
42ea79858f | ||
|
|
e60dd28212 | ||
|
|
4eefb448ed | ||
|
|
918b6dbe8e | ||
|
|
34154178e2 | ||
|
|
060fc4719c | ||
|
|
ea44fe7c13 | ||
|
|
6264caf8a8 | ||
|
|
2b3537ac7e | ||
|
|
86efbbcd82 | ||
|
|
40b8b3f739 | ||
|
|
40a18d7efb | ||
|
|
517917947a | ||
|
|
b6b97cb3a5 | ||
|
|
46a8e53c51 | ||
|
|
0a6a628be5 | ||
|
|
1238a62a3c | ||
|
|
aaff23d261 | ||
|
|
9df71344ed | ||
|
|
7acf008adc | ||
|
|
7f2bab1a30 | ||
|
|
6eaa8b9a85 | ||
|
|
ea9f067f35 | ||
|
|
564b04850a | ||
|
|
3f42ad7d18 | ||
|
|
1b7ffaeda3 | ||
|
|
8fad0019f8 | ||
|
|
f06d28dab1 | ||
|
|
5b3d20972a | ||
|
|
20f97f96b8 | ||
|
|
a952c0b216 | ||
|
|
1edb374a90 | ||
|
|
39b43d6eff | ||
|
|
0b3eb69749 | ||
|
|
440a3fa7fe | ||
|
|
16e9bf37ea | ||
|
|
448e4fac32 | ||
|
|
e819bc5aee | ||
|
|
662e29c4c7 | ||
|
|
195f0cd69a | ||
|
|
d4fff004c9 | ||
|
|
de89e7e80a | ||
|
|
cd94116465 | ||
|
|
78706a0fb6 | ||
|
|
bee96b9e09 | ||
|
|
47b5e4ba90 | ||
|
|
6583c27600 | ||
|
|
ebba329a0d | ||
|
|
0aadfe5d24 | ||
|
|
5e7e4151a3 | ||
|
|
4d418221d6 | ||
|
|
2d81cc857b | ||
|
|
b0ab3bf434 | ||
|
|
8eb381b81c | ||
|
|
2e7611ad92 | ||
|
|
7955afcf35 | ||
|
|
8e8ee7c495 | ||
|
|
f3f1da452e | ||
|
|
3efe6efa0b | ||
|
|
37453aaa11 | ||
|
|
47c26e93df | ||
|
|
e3f5f948c3 | ||
|
|
17d0dab859 | ||
|
|
02f5f4261e | ||
|
|
5ccaa3b77d | ||
|
|
fc4f10a7ea | ||
|
|
6d127bdee7 | ||
|
|
00c5968380 | ||
|
|
0f8e02c738 | ||
|
|
77c1af3dcf | ||
|
|
ad52d17bda | ||
|
|
d45e18fac6 | ||
|
|
5432306b1a | ||
|
|
b1000227c0 | ||
|
|
9d86a63b52 | ||
|
|
32d6fc95be | ||
|
|
d7ff7c8038 | ||
|
|
b042bf4b55 | ||
|
|
b315f65bcd | ||
|
|
ead06c5eae | ||
|
|
b8b488274f | ||
|
|
e54ac05df2 | ||
|
|
6146ffc9c3 | ||
|
|
0fcd8c134d | ||
|
|
ccac4745ea | ||
|
|
70dba5a317 | ||
|
|
f6adb3b1c3 | ||
|
|
27d3637330 | ||
|
|
0b4b551d56 | ||
|
|
cd1e371acb | ||
|
|
8e0117a100 | ||
|
|
1b0bb1a711 | ||
|
|
392d150396 | ||
|
|
c3114609f5 | ||
|
|
1e82ca3f66 | ||
|
|
e4c7b1d8cf | ||
|
|
942b74be8e | ||
|
|
7841669db7 | ||
|
|
a0382dc984 | ||
|
|
fdb52fb4f4 | ||
|
|
38aa42ff9b | ||
|
|
802bf6f1e3 | ||
|
|
ae9312983a | ||
|
|
c156250c90 | ||
|
|
5dcdbb702f | ||
|
|
4750f8388a | ||
|
|
3fb47fb6ea | ||
|
|
eba323fb64 | ||
|
|
53b00421d2 | ||
|
|
cc77c1ebaf | ||
|
|
5ea3ae3a0c | ||
|
|
76b6aebac4 | ||
|
|
1e1f2f3bd9 | ||
|
|
085b11e262 | ||
|
|
4eb556e1bb | ||
|
|
e4a0ef311b | ||
|
|
9073e9fa68 | ||
|
|
29ceb66837 | ||
|
|
5184252e5f | ||
|
|
cad65469a4 | ||
|
|
03051c6a8f | ||
|
|
a25392f934 | ||
|
|
ba4fc027e6 | ||
|
|
3b21e8f858 | ||
|
|
31a2a97bee | ||
|
|
bf1ae6570c | ||
|
|
29ddc06c4b | ||
|
|
8a6d56e09f | ||
|
|
b739d3f435 | ||
|
|
82d2c06eff | ||
|
|
adf8617abf | ||
|
|
286275142a | ||
|
|
1b0d46bdfb | ||
|
|
d9864afa8c | ||
|
|
c0beb480d4 | ||
|
|
20b7b87cff | ||
|
|
e374906dee | ||
|
|
3459529d08 | ||
|
|
4d67c7e2ff | ||
|
|
6cbec0c39e | ||
|
|
8c074a9f9a | ||
|
|
e37ca4c34f | ||
|
|
a8c85826de | ||
|
|
91ed7636ff | ||
|
|
8db03bf315 | ||
|
|
793ced1758 | ||
|
|
9ef07fb494 | ||
|
|
349c5116ea | ||
|
|
93949d9fd7 | ||
|
|
eedcad947e | ||
|
|
5e17b74684 | ||
|
|
99f027e0ee | ||
|
|
04de130e02 | ||
|
|
30444565a8 | ||
|
|
c9b72491b6 | ||
|
|
86b687d27b | ||
|
|
03b0219a1e | ||
|
|
8ddc2cda92 | ||
|
|
c3d9da1186 | ||
|
|
b1b28f93c5 | ||
|
|
a465a093c9 | ||
|
|
3d362db71a | ||
|
|
3ea506adca | ||
|
|
bb37dde0e0 | ||
|
|
c1e21905df | ||
|
|
9445ac1efe | ||
|
|
0f6e12f80b | ||
|
|
94181dbb46 | ||
|
|
988eec7224 | ||
|
|
4a604f4f6a | ||
|
|
cc244c6af6 | ||
|
|
b97ef23bf8 | ||
|
|
0952e9e9ae | ||
|
|
7391c9e675 | ||
|
|
757184c459 | ||
|
|
85a4247d9b | ||
|
|
9b36f51015 | ||
|
|
60d8f00723 | ||
|
|
d9d0f922bb | ||
|
|
040d049742 | ||
|
|
53044e0551 | ||
|
|
59f0a16544 | ||
|
|
60f44c6759 | ||
|
|
2cb1ae1ab7 | ||
|
|
bf8e6118c2 | ||
|
|
a561a62ef5 | ||
|
|
982f9e5635 | ||
|
|
ca57e8106b | ||
|
|
d0ae764ab6 | ||
|
|
104e711aec | ||
|
|
1dde0cba15 | ||
|
|
3981570360 | ||
|
|
bba9951b9b | ||
|
|
f3e55a58ce | ||
|
|
f706d38e2d | ||
|
|
e88f84e438 | ||
|
|
9ca80bda50 | ||
|
|
19c71d4ddd | ||
|
|
601acb63bb | ||
|
|
4f3a1cac43 | ||
|
|
c1085cce70 | ||
|
|
8331e8b58c | ||
|
|
8e81a9fca4 | ||
|
|
df11f56a40 | ||
|
|
71b21f78e1 | ||
|
|
174117161e | ||
|
|
affdcc3225 | ||
|
|
165d5dfef3 | ||
|
|
94ae70a2c2 | ||
|
|
acef2eff3a | ||
|
|
7d7208a1bf | ||
|
|
56f66a169c | ||
|
|
4caf3b2f86 | ||
|
|
e58911d9cf | ||
|
|
c03c9dac30 | ||
|
|
19858a4467 | ||
|
|
1b5b4188b5 | ||
|
|
689b25b743 | ||
|
|
5ee2ed14af | ||
|
|
eecfebe66f | ||
|
|
e1d48a62e2 | ||
|
|
00bd0e52ef | ||
|
|
aa3c9762c9 | ||
|
|
6fac279db7 | ||
|
|
0f013cd7a0 | ||
|
|
dac84749fd | ||
|
|
b2f650cab0 | ||
|
|
a3a58040a0 | ||
|
|
659a3864f7 | ||
|
|
a1a5dfdbfd | ||
|
|
a89c32e668 | ||
|
|
903a1ecda4 | ||
|
|
3802520958 | ||
|
|
54acd85586 | ||
|
|
3c41aa44eb | ||
|
|
b830674abc | ||
|
|
1949d76654 | ||
|
|
82689b48ba | ||
|
|
455f732250 | ||
|
|
5494bec24a | ||
|
|
1eedf42be0 | ||
|
|
5d0c8535f2 | ||
|
|
a0c9a72c1d | ||
|
|
7fbbb75fed | ||
|
|
897198b785 | ||
|
|
04e7d66667 | ||
|
|
b6c81dacf7 | ||
|
|
f4c9637949 | ||
|
|
141d4208e1 | ||
|
|
46d1969254 | ||
|
|
0cf0e04705 | ||
|
|
e6a3b1e9e1 | ||
|
|
35fa8ed374 | ||
|
|
38856deaa7 | ||
|
|
f573a3a7ab | ||
|
|
500d3e15c3 | ||
|
|
bbee6cafdf | ||
|
|
5053b0a89a | ||
|
|
024e4a1d96 | ||
|
|
f791a2cfcf | ||
|
|
962bad10aa | ||
|
|
288c6af300 | ||
|
|
7eb5be9081 | ||
|
|
fcd049721d | ||
|
|
efaec831e8 | ||
|
|
d2f9256fb0 | ||
|
|
4811b4af5b | ||
|
|
bf2e9d4471 | ||
|
|
15978c968e | ||
|
|
b46fc915f3 | ||
|
|
a12e17b39c | ||
|
|
1cc8b626a6 | ||
|
|
f13f5e455b | ||
|
|
7de34ac9a2 | ||
|
|
fb38ba1c9d | ||
|
|
5d6a58421f | ||
|
|
3cc89b8469 | ||
|
|
c9826a7520 | ||
|
|
2b7a874c1e | ||
|
|
a8a79df6b4 | ||
|
|
f07e14e62f | ||
|
|
ee1b38a88d | ||
|
|
32af035674 | ||
|
|
6cbc7d0220 | ||
|
|
bfa3836cc2 | ||
|
|
c8f6d0b595 | ||
|
|
f6ddd44ccb | ||
|
|
e813ce3fef | ||
|
|
8234ea338b | ||
|
|
7ba78302b0 | ||
|
|
4143c2c32d | ||
|
|
68fa8f30c0 | ||
|
|
e0f9b819d2 | ||
|
|
9b9b096749 | ||
|
|
c03c8b2299 | ||
|
|
2e78e5e5c6 | ||
|
|
d2fc125642 | ||
|
|
51fb493462 | ||
|
|
838f6e06b5 | ||
|
|
ebe131d4a4 | ||
|
|
ccd739d570 | ||
|
|
503a2ed934 | ||
|
|
d1f59f2bde | ||
|
|
48daa0f04a | ||
|
|
28a2248491 | ||
|
|
c4433592f4 | ||
|
|
576c51fcac | ||
|
|
aaf8b3ea51 | ||
|
|
d8ba39ebf2 | ||
|
|
e9e63cd11b | ||
|
|
5fc23c15f0 | ||
|
|
8015ceeed5 | ||
|
|
5068a126be | ||
|
|
5996d89e4c | ||
|
|
23f6502d99 | ||
|
|
c4a13e06e5 | ||
|
|
080565bea6 | ||
|
|
f7ab833cb8 | ||
|
|
b8025ae5bb | ||
|
|
9247c6c4f3 | ||
|
|
061981688d | ||
|
|
d2e07bcf69 | ||
|
|
d44d209c21 | ||
|
|
3672716ee6 | ||
|
|
1ef850a09f | ||
|
|
ce4b3f2a35 | ||
|
|
8f229001aa | ||
|
|
035597d330 | ||
|
|
4f0ec2e6e3 | ||
|
|
ebe4cce3ac | ||
|
|
4a0af806f5 | ||
|
|
51b26395ad | ||
|
|
73f75e6515 | ||
|
|
771c3f5516 | ||
|
|
fd9d08eb0c | ||
|
|
44bfaad9cb | ||
|
|
8931331466 | ||
|
|
a450c8d3dc | ||
|
|
1151d501f5 | ||
|
|
b6b042407d | ||
|
|
4f215cbc49 | ||
|
|
dd7329930c | ||
|
|
acfc1fc942 | ||
|
|
aed40c518e | ||
|
|
2d7fae677b | ||
|
|
50077dd0ac | ||
|
|
5dafd7217e | ||
|
|
2ffcf7bd26 | ||
|
|
334fb0c6e9 | ||
|
|
51ffebb04f | ||
|
|
9754395e62 | ||
|
|
bb5766c85d | ||
|
|
fc27497535 | ||
|
|
31221c1d6e | ||
|
|
1cf2ef60e8 | ||
|
|
13cad16712 | ||
|
|
7c2f13f883 | ||
|
|
cbaef4cc6c | ||
|
|
37182779f9 | ||
|
|
cc97affc16 | ||
|
|
af5d3778c3 | ||
|
|
ef25720797 | ||
|
|
20a08e650d | ||
|
|
fe8c610f3d | ||
|
|
a33f907ba5 | ||
|
|
e78569b325 | ||
|
|
f6cb3fb118 | ||
|
|
7798ae79d7 | ||
|
|
c8d1bb0276 | ||
|
|
ce2a62d198 | ||
|
|
fd0e1a7b5e | ||
|
|
c93fed32ef | ||
|
|
4023537b8a | ||
|
|
e2712005e4 | ||
|
|
aea72bcc6e | ||
|
|
40ef074522 | ||
|
|
6aa021e4a6 | ||
|
|
ac97dbf8ba | ||
|
|
87d7a291f0 | ||
|
|
e8f3950072 | ||
|
|
2fd2fc5f62 | ||
|
|
145e6db3ec | ||
|
|
63d1983914 | ||
|
|
333c68e33f | ||
|
|
739ce9da27 | ||
|
|
aadc032b31 | ||
|
|
2b90faa98e | ||
|
|
e68e4b2a24 | ||
|
|
2c541d465c | ||
|
|
329a02bf07 | ||
|
|
2c7d662c22 | ||
|
|
920eeded4d | ||
|
|
740b51d405 | ||
|
|
cee00b0382 | ||
|
|
4bbd59787a | ||
|
|
acdc7c6e49 | ||
|
|
a5f190685b | ||
|
|
fd53727f12 | ||
|
|
cea843bcbc | ||
|
|
dda5e79a77 | ||
|
|
f9dd7bd74b | ||
|
|
2ef68977bd | ||
|
|
673d2e3ef2 | ||
|
|
17b172e3f1 | ||
|
|
acde080e48 | ||
|
|
b139d8d049 | ||
|
|
1c39041de2 | ||
|
|
cd6d9e1687 | ||
|
|
57746a9daf | ||
|
|
2e961e7875 | ||
|
|
5fc368c86b | ||
|
|
37abeb5735 | ||
|
|
e34d34526f | ||
|
|
3eb249dcfd | ||
|
|
3f96888e1a | ||
|
|
59df06676d | ||
|
|
26a0f39ee8 | ||
|
|
b63df1eee3 | ||
|
|
fdd906c982 | ||
|
|
0f9d5b94ff | ||
|
|
98b222a9bf | ||
|
|
6c0c1aa9d4 | ||
|
|
6f41ed1c27 | ||
|
|
8b773e9899 | ||
|
|
b51acbd268 | ||
|
|
6e66a17fe3 | ||
|
|
88855305e1 | ||
|
|
53f61ad31b | ||
|
|
650b1c0102 | ||
|
|
77be9ddf8d | ||
|
|
ad7527c4ae | ||
|
|
68563a198d | ||
|
|
8a6459e828 | ||
|
|
846f3c6c5b | ||
|
|
f843dde3d6 | ||
|
|
ef7db30658 | ||
|
|
b6f430c0db | ||
|
|
8b07b6ca5d | ||
|
|
f1171d06a8 | ||
|
|
e01201be81 | ||
|
|
1e21a5fb05 | ||
|
|
df0e7ee6ae | ||
|
|
d30066bcf9 | ||
|
|
0ca7d3a2ad | ||
|
|
2b9af5070b | ||
|
|
94065bb38c | ||
|
|
63c02eb14a | ||
|
|
a3c387d445 | ||
|
|
9abca0ea0d | ||
|
|
b1c43d0b04 | ||
|
|
a1fcdb39b9 | ||
|
|
077ea93bc3 | ||
|
|
82b14b6542 | ||
|
|
6ef985207c | ||
|
|
13d0c99e8c | ||
|
|
0c7051eac0 | ||
|
|
b14c636f94 | ||
|
|
049cd35a1c | ||
|
|
e7986b57b2 | ||
|
|
3dbac1fe2e | ||
|
|
42425dc61b | ||
|
|
5261dce34f | ||
|
|
1ef34efed6 | ||
|
|
593c97c165 | ||
|
|
6540c0a165 | ||
|
|
411051f921 | ||
|
|
907e3ba729 | ||
|
|
afa1a9fd9f | ||
|
|
07afdbe0f8 | ||
|
|
dcd59ca69f | ||
|
|
98ae943db0 | ||
|
|
8e06dde724 | ||
|
|
71ca5a87f1 | ||
|
|
c9b1d2fb5b | ||
|
|
981fe00c5f | ||
|
|
373661d35a | ||
|
|
1be5f23204 | ||
|
|
723123fa50 | ||
|
|
7bf1c2056c | ||
|
|
74c0a562e9 | ||
|
|
65856db131 | ||
|
|
5d67012121 | ||
|
|
573cf454ce | ||
|
|
0d81b7839b | ||
|
|
5b00ab795d | ||
|
|
86709e3604 | ||
|
|
38a9468fd2 | ||
|
|
cf3ba419f4 | ||
|
|
c94fad4145 | ||
|
|
f371a968b7 | ||
|
|
e163318c5a | ||
|
|
bb6be97bee | ||
|
|
cb454d83a1 | ||
|
|
6b5d13e8b8 | ||
|
|
5f9b124a7b | ||
|
|
f7a48c04b8 | ||
|
|
9315dab053 | ||
|
|
274d14d905 | ||
|
|
9625dbf3ed | ||
|
|
eef16080d4 | ||
|
|
66cf423598 | ||
|
|
53187cb8aa | ||
|
|
a8cdbc0b22 | ||
|
|
7845a1901b | ||
|
|
e3d8476396 | ||
|
|
88d9238c17 | ||
|
|
fdb35eafc1 | ||
|
|
2bbd785ada | ||
|
|
f30294c2ae | ||
|
|
95267a5581 | ||
|
|
a860cf1a13 | ||
|
|
f2cf4fb4a0 | ||
|
|
3323a39767 | ||
|
|
9ed323321a | ||
|
|
968089201a | ||
|
|
d232d61350 | ||
|
|
3cc2be8874 | ||
|
|
cd1d0c3746 | ||
|
|
780c55e99e | ||
|
|
2b9e508a5c | ||
|
|
a68328ae83 | ||
|
|
f9cd35ac74 | ||
|
|
06cfed009a | ||
|
|
dc94ff58c3 | ||
|
|
6b87a2ad31 | ||
|
|
9c7606e59b | ||
|
|
5f0fdf326b | ||
|
|
cd550054d8 | ||
|
|
cb634bea1e | ||
|
|
3d93f708be | ||
|
|
6c315e1669 | ||
|
|
0fee313f18 | ||
|
|
bcb817b30d | ||
|
|
33c75915ca | ||
|
|
89ed35815c | ||
|
|
69d244b227 | ||
|
|
047ed5a6f8 | ||
|
|
61acec17ee | ||
|
|
2438c2fd04 | ||
|
|
5f06b7bde9 | ||
|
|
59bb23232f | ||
|
|
64eacb5237 | ||
|
|
7804d741a0 | ||
|
|
31b9158e3d | ||
|
|
a5bd2965d0 | ||
|
|
191143fb17 | ||
|
|
8be48c87a8 | ||
|
|
5aeb57fb61 | ||
|
|
b0ae5d4299 | ||
|
|
fb6ac84fb3 | ||
|
|
e32c44aaa3 | ||
|
|
4baf71d8dc | ||
|
|
8b0d7bb422 | ||
|
|
80e44e302f | ||
|
|
009770bb04 | ||
|
|
e2d7d8edd8 | ||
|
|
2d9b4ddd0b | ||
|
|
a58ed5e1a9 | ||
|
|
2595b8bc8e | ||
|
|
ee270f419c | ||
|
|
4b6c9d7705 | ||
|
|
445eb31db1 | ||
|
|
c8151d94ba | ||
|
|
8dd5ca8bc8 | ||
|
|
8a6f0b57d4 | ||
|
|
7b91c26689 | ||
|
|
6083a2a9aa | ||
|
|
31608ce4ee | ||
|
|
5e36cddca3 | ||
|
|
56bae6ee84 | ||
|
|
0d870b62de | ||
|
|
c453134fa3 | ||
|
|
8012a5783e | ||
|
|
c9d231f8f4 | ||
|
|
97b182f06e | ||
|
|
82b33b5ab4 | ||
|
|
2f7d5336e2 | ||
|
|
f425da1555 | ||
|
|
2d5278aa80 | ||
|
|
ed91112531 | ||
|
|
e224f30de6 | ||
|
|
bb66fe6e98 | ||
|
|
9d096dd994 | ||
|
|
c0d4ec7dba | ||
|
|
b91287a974 | ||
|
|
94bf737584 | ||
|
|
6960ff471c | ||
|
|
5bad1f397d | ||
|
|
327ebeaa53 | ||
|
|
ea87c9d148 | ||
|
|
2853b48144 | ||
|
|
3eb113a5cb | ||
|
|
1b60735808 |
@@ -22,5 +22,6 @@ VUE_APP_LOGOUT_PATH = '/core/auth/logout/'
|
||||
# Dev server for core proxy
|
||||
VUE_APP_CORE_HOST = 'http://localhost:8080'
|
||||
VUE_APP_CORE_WS = 'ws://localhost:8080'
|
||||
VUE_APP_KAEL_HOST = 'http://localhost:8083'
|
||||
VUE_APP_KOKO_HOST = 'http://localhost:5000'
|
||||
VUE_APP_KOKO_WS = 'ws://localhost:5000'
|
||||
VUE_APP_ENV = 'development'
|
||||
|
||||
28
.github/workflows/.github/workflows/llm-code-review.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: LLM Code Review
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
jobs:
|
||||
llm-code-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: fit2cloud/LLM-CodeReview-Action@main
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FIT2CLOUDRD_LLM_CODE_REVIEW_TOKEN }}
|
||||
OPENAI_API_KEY: ${{ secrets.ALIYUN_LLM_API_KEY }}
|
||||
LANGUAGE: English
|
||||
OPENAI_API_ENDPOINT: https://dashscope.aliyuncs.com/compatible-mode/v1
|
||||
MODEL: qwen2-1.5b-instruct
|
||||
PROMPT: "Please check the following code differences for any irregularities, potential issues, or optimization suggestions, and provide your answers in English."
|
||||
top_p: 1
|
||||
temperature: 1
|
||||
# max_tokens: 10000
|
||||
MAX_PATCH_LENGTH: 10000
|
||||
IGNORE_PATTERNS: "/node_modules,*.md,/dist,/.github"
|
||||
FILE_PATTERNS: "*.java,*.go,*.py,*.vue,*.ts,*.js,*.css,*.scss,*.html"
|
||||
72
.github/workflows/build-base-image.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: Build and Push Base Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'pr*'
|
||||
paths:
|
||||
- 'package.json'
|
||||
- 'package-lock.json'
|
||||
- 'yarn.lock'
|
||||
- 'Dockerfile-base'
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Lock Pull Request
|
||||
run: |
|
||||
curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
||||
-d '{"state":"pending", "description":"Action running, merge disabled", "context":"Lock PR"}' \
|
||||
"https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }}"
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract date
|
||||
id: vars
|
||||
run: echo "IMAGE_TAG=$(date +'%Y%m%d_%H%M%S')" >> $GITHUB_ENV
|
||||
|
||||
- name: Extract repository name
|
||||
id: repo
|
||||
run: echo "REPO=$(basename ${{ github.repository }})" >> $GITHUB_ENV
|
||||
|
||||
- name: Build and push multi-arch image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
file: Dockerfile-base
|
||||
tags: jumpserver/${{ env.REPO }}-base:${{ env.IMAGE_TAG }}
|
||||
|
||||
- name: Update Dockerfile
|
||||
run: |
|
||||
sed -i 's|-base:.* AS stage-build|-base:${{ env.IMAGE_TAG }} AS stage-build|' Dockerfile
|
||||
|
||||
- name: Commit changes
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
git add Dockerfile
|
||||
git commit -m "perf: Update Dockerfile with new base image tag"
|
||||
git push
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Unlock Pull Request
|
||||
run: |
|
||||
curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
||||
-d '{"state":"success", "description":"Action running, merge disabled", "context":"Lock PR"}' \
|
||||
"https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }}"
|
||||
32
.github/workflows/jms-build-test.yml
vendored
@@ -1,32 +0,0 @@
|
||||
name: "Run Build Test"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- pr@*
|
||||
- repr@*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: docker/setup-qemu-action@v2
|
||||
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
|
||||
- uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
push: false
|
||||
tags: jumpserver/lina:test
|
||||
file: Dockerfile
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- uses: LouisBrunner/checks-action@v1.5.0
|
||||
if: always()
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: Check Build
|
||||
conclusion: ${{ job.status }}
|
||||
46
.github/workflows/jms-build-test.yml.disabled
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: "Run Build Test"
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile*'
|
||||
- 'package.json'
|
||||
- 'yarn.lock'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
component: [ lina ]
|
||||
version: [ v4 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Prepare Build
|
||||
run: |
|
||||
sed -i 's@registry.npmmirror.com@registry.yarnpkg.com@g' yarn.lock
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build Image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
file: Dockerfile
|
||||
tags: ghcr.io/jumpserver/${{ matrix.component }}:${{ matrix.version }}
|
||||
platforms: linux/amd64
|
||||
build-args: |
|
||||
VERSION=${{ matrix.version }}
|
||||
APT_MIRROR=http://deb.debian.org
|
||||
NPM_REGISTRY=https://registry.yarnpkg.com
|
||||
outputs: type=image,oci-mediatypes=true,compression=zstd,compression-level=3,force-compression=true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
28
.github/workflows/llm-code-review.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: LLM Code Review
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
|
||||
jobs:
|
||||
llm-code-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: fit2cloud/LLM-CodeReview-Action@main
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FIT2CLOUDRD_LLM_CODE_REVIEW_TOKEN }}
|
||||
OPENAI_API_KEY: ${{ secrets.ALIYUN_LLM_API_KEY }}
|
||||
LANGUAGE: English
|
||||
OPENAI_API_ENDPOINT: https://dashscope.aliyuncs.com/compatible-mode/v1
|
||||
MODEL: qwen2-1.5b-instruct
|
||||
PROMPT: "Please check the following code differences for any irregularities, potential issues, or optimization suggestions, and provide your answers in English."
|
||||
top_p: 1
|
||||
temperature: 1
|
||||
# max_tokens: 10000
|
||||
MAX_PATCH_LENGTH: 10000
|
||||
IGNORE_PATTERNS: "/node_modules,*.md,/dist,/.github"
|
||||
FILE_PATTERNS: "*.java,*.go,*.py,*.vue,*.ts,*.js,*.css,*.scss,*.html"
|
||||
2
.github/workflows/release-drafter.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
tag: ${{ steps.get_version.outputs.TAG }}
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16.20'
|
||||
node-version: '20.15'
|
||||
- name: Install dependencies
|
||||
run: yarn install
|
||||
- name: Build web
|
||||
|
||||
2
.gitignore
vendored
@@ -17,3 +17,5 @@ tests/**/coverage/
|
||||
*.sln
|
||||
.env.development
|
||||
.python-version
|
||||
|
||||
helper.json
|
||||
33
Dockerfile
@@ -1,36 +1,11 @@
|
||||
FROM node:16.20-bullseye-slim as stage-build
|
||||
ARG TARGETARCH
|
||||
|
||||
ARG DEPENDENCIES=" \
|
||||
g++ \
|
||||
make \
|
||||
python3"
|
||||
|
||||
ARG APT_MIRROR=http://mirrors.ustc.edu.cn
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=lina \
|
||||
sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \
|
||||
&& rm -f /etc/apt/apt.conf.d/docker-clean \
|
||||
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends ${DEPENDENCIES} \
|
||||
&& echo "no" | dpkg-reconfigure dash \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG NPM_REGISTRY="https://registry.npmmirror.com"
|
||||
RUN set -ex \
|
||||
&& npm config set registry ${NPM_REGISTRY} \
|
||||
&& yarn config set registry ${NPM_REGISTRY}
|
||||
|
||||
WORKDIR /data
|
||||
|
||||
ADD package.json yarn.lock /data
|
||||
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=lina \
|
||||
yarn install
|
||||
FROM jumpserver/lina-base:20240723_084702 AS stage-build
|
||||
|
||||
ARG VERSION
|
||||
ENV VERSION=$VERSION
|
||||
|
||||
ADD . /data
|
||||
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=lina \
|
||||
|
||||
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked \
|
||||
sed -i "s@version-dev@${VERSION}@g" src/layout/components/NavHeader/About.vue \
|
||||
&& yarn build
|
||||
|
||||
|
||||
22
Dockerfile-base
Normal file
@@ -0,0 +1,22 @@
|
||||
FROM node:20.15-bullseye-slim
|
||||
|
||||
ARG DEPENDENCIES=" \
|
||||
g++ \
|
||||
make \
|
||||
python3"
|
||||
|
||||
RUN set -ex \
|
||||
&& rm -f /etc/apt/apt.conf.d/docker-clean \
|
||||
&& echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache \
|
||||
&& apt-get update \
|
||||
&& apt-get -y install --no-install-recommends ${DEPENDENCIES} \
|
||||
&& echo "no" | dpkg-reconfigure dash
|
||||
|
||||
WORKDIR /data
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
|
||||
ARG NPM_MIRROR="https://registry.npmjs.org"
|
||||
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn,sharing=locked,id=yarn-cache \
|
||||
sed -i "s|https://registry.npmmirror.com|${NPM_MIRROR}|g" yarn.lock \
|
||||
&& yarn install
|
||||
@@ -5,5 +5,6 @@
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
||||
29
package.json
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "vue-admin-template",
|
||||
"version": "4.2.1",
|
||||
"description": "A vue admin template with Element UI & axios & iconfont & permission control & lint",
|
||||
"author": "Pan <panfree23@gmail.com>",
|
||||
"license": "MIT",
|
||||
"name": "lina",
|
||||
"version": "v4.0.0",
|
||||
"description": "JumpServer Web UI",
|
||||
"author": "JumpServer Team <support@fit2cloud.com>",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve",
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"dev": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve",
|
||||
"serve": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service serve",
|
||||
"build": "NODE_OPTIONS=--openssl-legacy-provider vue-cli-service build",
|
||||
"build:prod": "vue-cli-service build",
|
||||
"build:stage": "vue-cli-service build --mode staging",
|
||||
"preview": "node build/index.js --preview",
|
||||
@@ -25,17 +25,20 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.13.12",
|
||||
"@fontsource/open-sans": "^5.0.24",
|
||||
"@traptitech/markdown-it-katex": "^3.6.0",
|
||||
"@ztree/ztree_v3": "3.5.44",
|
||||
"axios": "0.28.0",
|
||||
"axios-retry": "^3.1.9",
|
||||
"caniuse-lite": "^1.0.30001642",
|
||||
"cron-parser": "^4.0.0",
|
||||
"crypto-js": "^4.1.1",
|
||||
"css-color-function": "^1.3.3",
|
||||
"decimal.js": "^10.4.3",
|
||||
"deepmerge": "^4.2.2",
|
||||
"dompurify": "^3.1.6",
|
||||
"echarts": "4.7.0",
|
||||
"element-ui": "2.13.2",
|
||||
"element-ui": "2.15.14",
|
||||
"eslint-plugin-html": "^6.0.0",
|
||||
"highlight.js": "^11.9.0",
|
||||
"install": "^0.13.0",
|
||||
@@ -63,7 +66,8 @@
|
||||
"normalize.css": "7.0.0",
|
||||
"npm": "^7.8.0",
|
||||
"nprogress": "0.2.0",
|
||||
"path-to-regexp": "2.4.0",
|
||||
"path-to-regexp": "3.3.0",
|
||||
"v-sanitize": "^0.0.13",
|
||||
"vue": "2.6.10",
|
||||
"vue-codemirror": "4.0.6",
|
||||
"vue-cookie": "^1.1.4",
|
||||
@@ -90,6 +94,7 @@
|
||||
"@vue/cli-plugin-unit-jest": "3.6.3",
|
||||
"@vue/cli-service": "3.6.0",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"@vue/runtime-dom": "3.5.13",
|
||||
"autoprefixer": "^9.5.1",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "10.0.1",
|
||||
@@ -113,10 +118,10 @@
|
||||
"sass-loader": "^7.1.0",
|
||||
"script-ext-html-webpack-plugin": "2.1.3",
|
||||
"script-loader": "0.7.2",
|
||||
"serve-static": "^1.13.2",
|
||||
"serve-static": "^1.16.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"svg-sprite-loader": "4.1.3",
|
||||
"svgo": "1.2.2",
|
||||
"svgo": "1.2.4",
|
||||
"vue-i18n-extract": "^1.1.1",
|
||||
"vue-template-compiler": "2.6.10"
|
||||
},
|
||||
|
||||
@@ -2,37 +2,70 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Cache-control" content="no-cache">
|
||||
<meta http-equiv="Cache" content="no-cache">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
|
||||
<meta content="0" http-equiv="Expires">
|
||||
<meta content="no-cache" http-equiv="Pragma">
|
||||
<meta content="no-cache" http-equiv="Cache-control">
|
||||
<meta content="no-cache" http-equiv="Cache">
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<title><%= webpackConfig.name %></title>
|
||||
<link rel="stylesheet" href="<%= BASE_URL %>theme/element-ui.css">
|
||||
<link href="<%= BASE_URL %>theme/element-ui.css" rel="stylesheet">
|
||||
<style>
|
||||
#loading {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 5px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 50%;
|
||||
border-top-color: #3498db;
|
||||
animation: spin 1s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
if (location.pathname === '/') {
|
||||
location.pathname = '/ui/'
|
||||
}
|
||||
const pathname = window.location.pathname
|
||||
if (pathname.startsWith('/core')) {
|
||||
return
|
||||
}
|
||||
if(pathname.indexOf('/ui') === -1) {
|
||||
window.location.href = window.location.origin + '/ui/#' + pathname
|
||||
}
|
||||
if (pathname.startsWith('/ui/#/chat')) {
|
||||
window.location.href = window.location.origin + pathname
|
||||
}
|
||||
window.onload = function () {
|
||||
if (location.pathname === '/') {
|
||||
location.pathname = '/ui/'
|
||||
}
|
||||
const pathname = window.location.pathname
|
||||
if (pathname.startsWith('/core')) {
|
||||
return
|
||||
}
|
||||
if (pathname.indexOf('/ui') === -1) {
|
||||
window.location.href = window.location.origin + '/ui/#' + pathname
|
||||
}
|
||||
if (pathname.startsWith('/ui/#/chat')) {
|
||||
window.location.href = window.location.origin + pathname
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<div id="app"></div>
|
||||
<div id="app">
|
||||
</div>
|
||||
<div id="loading">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -21,32 +21,39 @@
|
||||
}
|
||||
|
||||
.el-alert--info.is-light {
|
||||
background-color: light-9;
|
||||
color: light-2;
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
color: info;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.el-alert--info .el-alert__description {
|
||||
color: light-2;
|
||||
color: info;
|
||||
}
|
||||
|
||||
.el-pagination.is-background {
|
||||
.el-pagination__total,
|
||||
.el-pagination__sizes,
|
||||
.el-pager {
|
||||
color: var(--color-icon-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.el-pagination.is-background .el-pager li:not(.disabled):hover {
|
||||
color: white;
|
||||
color: #fff;
|
||||
background-color: primary;
|
||||
}
|
||||
|
||||
.el-pagination.is-background .btn-next,
|
||||
.el-pagination.is-background .btn-prev,
|
||||
.el-pagination.is-background .el-pager li {
|
||||
margin: 0 5px;
|
||||
background-color: white;
|
||||
color: #606266;
|
||||
min-width: 28px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #DCDFE6;
|
||||
font-size: 12px;
|
||||
line-height: 26px;
|
||||
font-weight: 400;
|
||||
margin: 0 5px;
|
||||
background-color: #fff;
|
||||
color: var(--color-icon-primary);
|
||||
min-width: 28px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #DCDFE6;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.el-breadcrumb__inner,
|
||||
@@ -85,8 +92,12 @@
|
||||
|
||||
|
||||
td .el-button.el-button--mini {
|
||||
padding: 1px 5px;
|
||||
padding: 1px 6px;
|
||||
line-height: 1.5;
|
||||
|
||||
.el-icon--right {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-tabs__item.is-active, .el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active {
|
||||
@@ -191,7 +202,7 @@ td .el-button.el-button--mini {
|
||||
}
|
||||
|
||||
.el-input--small .el-input__icon {
|
||||
line-height: 34px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.option-group .el-select-dropdown__item.hover, .option-group .el-select-dropdown__item.selected {
|
||||
@@ -224,8 +235,10 @@ td .el-button.el-button--mini {
|
||||
}
|
||||
|
||||
.el-tag.el-tag--info .el-tag__close {
|
||||
color: #333333!important;
|
||||
background-color: inherit;
|
||||
display: inline-block;
|
||||
margin-top: 3px;
|
||||
color: var(--color-text-primary);
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.el-tag.el-tag--info.is-hit {
|
||||
@@ -280,7 +293,7 @@ td .el-button.el-button--mini {
|
||||
}
|
||||
|
||||
.el-textarea__inner {
|
||||
border-radius: 0;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.el-pagination.is-background .number {
|
||||
@@ -313,11 +326,11 @@ td .el-button.el-button--mini {
|
||||
|
||||
.el-tooltip__popper.is-light {
|
||||
background: #FFF;
|
||||
max-width: 500px;
|
||||
border: 1px solid #e7eaec;
|
||||
}
|
||||
|
||||
.el-tooltip__popper.is-light .popper__arrow {
|
||||
border-bottom-color: #e7eaec !important;
|
||||
box-shadow: 0 1.6px 3.6px 0 rgba(0, 0, 0, .132), 0 .3px .9px 0 rgba(0, 0, 0, .108);
|
||||
line-height: 1.5;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.el-dialog__headerbtn .el-dialog__close {
|
||||
@@ -326,7 +339,7 @@ td .el-button.el-button--mini {
|
||||
}
|
||||
|
||||
.el-table__header thead tr th {
|
||||
border-bottom: 1px solid #e7e7e7 !important;
|
||||
/*border-bottom: 1px solid #e7e7e7 !important;*/
|
||||
}
|
||||
|
||||
.el-table .cell,
|
||||
@@ -423,14 +436,34 @@ td .el-button.el-button--mini {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.el-dialog .el-dialog__header .el-dialog__title {
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.el-dialog .el-dialog__body {
|
||||
max-height: 80vh;
|
||||
overflow: auto;
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.el-dialog .el-dialog__body .el-transfer-panel .el-transfer-panel__body .el-input__inner,
|
||||
.el-dialog .el-dialog__body .el-transfer-panel .el-transfer-panel__header .el-checkbox__label,
|
||||
.el-dialog .el-dialog__body .el-transfer-panel .el-transfer-panel__body .el-checkbox-group .el-checkbox.el-transfer-panel__item {
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.el-dialog .el-dialog__body .opera .el-button.is-disabled,
|
||||
.el-dialog .el-dialog__body .el-transfer-panel .vip-footer .el-button.is-disabled {
|
||||
color: var(--color-input-border);
|
||||
}
|
||||
|
||||
.el-dialog .el-dialog__body .opera .el-button.is-disabled.el-button--primary {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.el-dialog .el-dialog__body form {
|
||||
padding-right: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.el-dialog .el-dialog__footer {
|
||||
|
||||
@@ -16,6 +16,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
9
src/api/component.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getLokiLog(data) {
|
||||
return request({
|
||||
url: `/api/v1/terminal/loki/logs/`,
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
@@ -53,7 +53,7 @@ export function createJob(form) {
|
||||
})
|
||||
}
|
||||
|
||||
export function StopJob(form) {
|
||||
export function stopJob(form) {
|
||||
return request({
|
||||
url: '/api/v1/ops/job-executions/stop/',
|
||||
method: 'post',
|
||||
@@ -71,3 +71,10 @@ export function JobUploadFile(form) {
|
||||
})
|
||||
}
|
||||
|
||||
export function auditUpdateJob(id, form) {
|
||||
return request({
|
||||
url: `/api/v1/audits/jobs/${id}/`,
|
||||
method: 'patch',
|
||||
data: form
|
||||
})
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ export function testEmailSetting(data) {
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function importLicense(formData) {
|
||||
return request({
|
||||
url: '/api/v1/xpack/license/import',
|
||||
@@ -25,6 +26,7 @@ export function importLicense(formData) {
|
||||
data: formData
|
||||
})
|
||||
}
|
||||
|
||||
export function testLdapSetting(data, refresh = true) {
|
||||
let url = '/api/v1/settings/ldap/testing/config/'
|
||||
if (refresh) {
|
||||
@@ -96,9 +98,17 @@ export function getPublicSettings(isOpen) {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getLogo() {
|
||||
return request({
|
||||
url: '/api/v1/xpack/interface/setting/',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getPreference() {
|
||||
return request({
|
||||
url: '/api/v1/users/preference/?category=luna',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -65,10 +65,6 @@ export function logout() {
|
||||
})
|
||||
}
|
||||
|
||||
export function refreshSessionIdAge() {
|
||||
return getProfile()
|
||||
}
|
||||
|
||||
export default {
|
||||
getProfile,
|
||||
getUserList
|
||||
|
||||
1
src/assets/img/cloud/ali.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717741737122" class="icon" viewBox="0 0 1653 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5514" width="200" height="200"><path d="M344.8620198 721.82988526a57.857089 57.857089 0 0 1-46.13274501-56.07295017v-308.4012244a59.89610558 59.89610558 0 0 1 46.13274501-56.07295017l286.35436058-62.06256065 30.07549089-122.72329718H328.80476645A210.78331632 210.78331632 0 0 0 116.61962599 327.28021902v364.47417458a213.71440233 213.71440233 0 0 0 212.18514046 212.31257895h332.48710482l-30.07549089-122.21354321zM1178.05508073 116.49690269H843.01920461l30.58524561 122.72329718 286.35436059 62.06256065a57.98452749 57.98452749 0 0 1 46.132745 56.07295017v308.4012244a60.15098257 60.15098257 0 0 1-46.13274502 56.07295017l-286.35436057 62.06256066-30.58524561 122.72329716H1178.05508073a212.44001744 212.44001744 0 0 0 212.94977139-212.82233291V327.28021902A213.33208686 213.33208686 0 0 0 1178.05508073 116.49690269z" fill="#F76E05" p-id="5515"></path><path d="M631.21638038 495.49906876h244.29964793v30.07549166H631.21638038z" fill="#F76E05" p-id="5516"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
src/assets/img/cloud/aws_china.svg
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
1
src/assets/img/cloud/aws_international.svg
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
1
src/assets/img/cloud/azure_china.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743450082" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="39383" width="200" height="200"><path d="M18.753 17.145h468.424l-0.02 468.426H18.774V17.145h-0.02z m0 0" fill="#F25022" p-id="39384"></path><path d="M534.999 17.145h468.422c0 156.141 0.022 312.283-0.02 468.426H535.038c-0.06-156.162-0.039-312.285-0.039-468.426z m0 0" fill="#80BA01" p-id="39385"></path><path d="M18.753 533.352c156.141 0.058 312.282-0.019 468.424 0.058v468.386H18.753V533.352z m0 0" fill="#02A4EF" p-id="39386"></path><path d="M535.018 533.41c156.124-0.058 312.243-0.019 468.383-0.019v468.422H534.999c0.019-156.163-0.02-312.28 0.019-468.403z m0 0" fill="#FFB902" p-id="39387"></path></svg>
|
||||
|
After Width: | Height: | Size: 721 B |
1
src/assets/img/cloud/azure_international.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743450082" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="39383" width="200" height="200"><path d="M18.753 17.145h468.424l-0.02 468.426H18.774V17.145h-0.02z m0 0" fill="#F25022" p-id="39384"></path><path d="M534.999 17.145h468.422c0 156.141 0.022 312.283-0.02 468.426H535.038c-0.06-156.162-0.039-312.285-0.039-468.426z m0 0" fill="#80BA01" p-id="39385"></path><path d="M18.753 533.352c156.141 0.058 312.282-0.019 468.424 0.058v468.386H18.753V533.352z m0 0" fill="#02A4EF" p-id="39386"></path><path d="M535.018 533.41c156.124-0.058 312.243-0.019 468.383-0.019v468.422H534.999c0.019-156.163-0.02-312.28 0.019-468.403z m0 0" fill="#FFB902" p-id="39387"></path></svg>
|
||||
|
After Width: | Height: | Size: 721 B |
1
src/assets/img/cloud/baidu.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743183519" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="34140" width="200" height="200"><path d="M521.30666655 248.79999969c4.93333313 0 9.14666625 0.73333312 12.66666657 2.17333406l181.97333343 106.71999938a34.00000031 34.00000031 0 0 0 26.83999969-0.61333313l168.72-94.69333312L520.06666624 36.26666656 128.02666624 262.38666687l171.20000063 95.93333344c3.69333375 1.63999969 7.8 2.46666656 12.33333281 2.46666656 4.93333313 0 9.04000031-0.82666687 12.33333375-2.46666656l184.45333312-107.04c4.32-1.63999969 8.64-2.46666656 12.96-2.46666656" fill="#5BCA87" p-id="34141"></path><path d="M763.02666687 421.28a34.39999969 34.39999969 0 0 0-9.52000032 23.28l3 200.17333312a28.74666656 28.74666656 0 0 1-9.86666625 22.04000063l-4.54666687 4.38666656-167.49333375 103.39999969a34.89333375 34.89333375 0 0 0-10.39999969 7.56c-5.86666687 5.83999969-8.93333344 13.39999969-9.19999969 22.65333375l2.79999938 186.6 384-230.04-6.61333313-441.36-161.47999968 93.43999969a40.89333375 40.89333375 0 0 0-10.68 7.86666656" fill="#EC5D3E" p-id="34142"></path><path d="M292.4400003 667.69333344a30.40000031 30.40000031 0 0 1-9.86666718-21.58666688V444.68c0-8.44000031-3.29333344-16.13333344-9.87999938-23.13333375a55.63999969 55.63999969 0 0 0-10.8-7.71999938l-162.85333406-90.66666656V765.46666625l387.42666656 222.40000031V801.25333344c-0.21333375-9.25333312-3.40000031-16.75999969-9.57333281-22.51999969a31.81333312 31.81333312 0 0 0-10.8-7.40000063l-168.72-99.31999968-4.93333313-4.32z" fill="#2464F5" p-id="34143"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
src/assets/img/cloud/gcp.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743357432" class="icon" viewBox="0 0 1228 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="37305" width="200" height="200"><path d="M779.7248 289.8944h37.4784l106.8032-106.8032 5.2736-45.3632A480.1024 480.1024 0 0 0 148.224 371.968c11.8784-4.864 25.088-5.632 37.4784-2.2528l213.6064-35.2256s10.9056-17.9712 16.4864-16.896a266.496 266.496 0 0 1 364.6976-27.6992h-0.768z" fill="#EA4335" p-id="37306"></path><path d="M1076.224 371.9168a481.28 481.28 0 0 0-145.1008-233.8304l-149.9136 149.9136a266.496 266.496 0 0 1 97.792 211.3536v26.624a133.4272 133.4272 0 1 1 0 266.8544h-266.752l-26.624 26.9824v160l26.624 26.624h266.752A347.0336 347.0336 0 0 0 1076.224 371.9168" fill="#4285F4" p-id="37307"></path><path d="M344.9856 1004.9536h266.8544v-213.6064H344.9856a132.608 132.608 0 0 1-55.0912-12.032l-37.4784 11.6224-107.5712 106.8032-9.3696 37.4784a345.1904 345.1904 0 0 0 209.5104 69.7344" fill="#34A853" p-id="37308"></path><path d="M344.9856 311.9616a347.0336 347.0336 0 0 0-209.5104 622.1312l154.7776-154.7776a133.4272 133.4272 0 1 1 176.5376-176.4864L621.568 448a346.6752 346.6752 0 0 0-276.5824-136.0384" fill="#FBBC05" p-id="37309"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
src/assets/img/cloud/huawei.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743147068" class="icon" viewBox="0 0 1027 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="32927" width="200" height="200"><path d="M402.3125 208.25c16.875-5.62500027 33.75-8.4375 50.625-11.24999973 19.68749973 25.3125 25.3125 59.0625 33.75 89.99999946 5.62500027 33.75 11.24999973 67.5 11.24999973 101.25 5.62500027 22.50000027 2.81249973 47.81250027 2.81250054 70.31250054s-2.81249973 42.1875 0 64.68749946c0 30.93750027-2.81249973 59.0625-2.81250054 90.00000027-5.62500027 19.68749973 0 39.37500027-5.62499946 59.0625-8.4375-2.81249973-11.24999973-11.24999973-14.06250027-16.875-33.75-50.625-64.68750027-101.25-92.8125-154.68749973-28.12499973-56.25000027-56.25000027-112.49999973-59.0625-177.1875-5.62500027-50.625 28.12499973-98.43750027 75.9375-115.31250027z m174.37500027-8.4375c5.62500027-2.81249973 8.4375 0 14.06249946 0 22.50000027 5.62500027 47.81250027 8.4375 67.5 22.50000027s36.56249973 33.75 42.1875 56.24999946c8.4375 28.12499973 5.62500027 59.0625 0 87.18750054-8.4375 36.56249973-25.3125 70.31249973-42.1875 104.06249973-5.62500027 11.24999973-11.24999973 19.68749973-16.875 30.93750027-8.4375 19.68749973-22.50000027 39.37500027-33.75 59.0625-19.68749973 33.75-39.37500027 61.87499973-59.0625 95.62499973-2.81249973 2.81249973-5.62500027 11.24999973-11.24999973 5.62500027-2.81249973-33.75-5.62500027-67.5-8.4375-104.06250054-5.62500027-44.99999973-2.81249973-87.18749973-2.81249973-132.18749946 2.81249973-28.12499973 2.81249973-59.0625 5.62499946-87.18750054 5.62500027-33.75 11.24999973-70.31249973 22.50000027-104.06249973 11.24999973-8.4375 11.24999973-25.3125 22.50000027-33.75zM222.31250027 309.5c2.81249973 0 5.62500027 5.62500027 8.4375 8.4375 81.56250027 106.87500027 154.68749973 219.375 213.74999973 340.31249973 5.62500027 8.4375 11.24999973 19.68749973 11.24999973 30.93750027-11.24999973-2.81249973-19.68749973-8.4375-28.12499973-14.06250027-53.43749973-28.12499973-106.87500027-59.0625-160.3125-89.99999946-19.68749973-14.06250027-39.37500027-28.12499973-56.25000027-42.1875-33.75-22.50000027-56.25000027-64.68750027-53.43749973-106.87500027 2.81249973-50.625 30.93750027-92.8125 64.68750027-126.5625z m582.1875 0h5.62499946c14.06250027 19.68749973 33.75 39.37500027 45.00000054 61.87499973 11.24999973 19.68749973 16.875 44.99999973 19.68749973 67.5 0 25.3125-8.4375 53.43749973-28.12499973 73.12500027-11.24999973 11.24999973-19.68749973 22.50000027-33.75 30.93750027-64.68750027 50.625-135 90.00000027-208.12500027 126.5625-11.24999973 5.62500027-19.68749973 14.06250027-33.75 14.06249946 2.81249973-14.06250027 11.24999973-28.12499973 16.875-39.37499946 47.81250027-98.43750027 106.87500027-191.25000027 171.56249973-281.25000054 14.06250027-14.06250027 30.93750027-33.75 45.00000054-53.43749973z m-705.93750027 225.00000027c2.81249973-2.81249973 0-8.4375 5.62500027-11.25000054 8.4375 2.81249973 16.875 8.4375 22.49999946 11.25000054 101.25 56.25000027 202.5 112.49999973 300.93750027 174.37499946 2.81249973 2.81249973 5.62500027 5.62500027 5.62500027 8.4375H239.18750027c-39.37500027 0-75.9375-16.875-104.06250054-44.99999973-22.50000027-25.3125-42.1875-59.0625-44.99999973-92.8125 5.62500027-14.06250027 2.81249973-28.12499973 8.4375-44.99999973z m810-2.81250054c5.62500027-2.81249973 14.06250027-8.4375 19.68749973-5.62499946 0 14.06250027 5.62500027 30.93750027 5.62500027 44.99999973-2.81249973 19.68749973-2.81249973 36.56249973-11.24999973 53.43749973-5.62500027 14.06250027-14.06250027 30.93750027-25.3125 42.1875-14.06250027 11.24999973-22.50000027 25.3125-39.37500027 33.75-16.875 14.06250027-42.1875 16.875-61.87499973 19.68750054h-202.5c2.81249973-2.81249973 2.81249973-5.62500027 5.62499946-8.4375 101.25-64.68750027 205.31249973-123.75000027 309.37500027-180.00000054zM242 748.25c36.56249973-2.81249973 73.12500027 0 109.6875-5.62500027 25.3125 0 53.43749973-2.81249973 78.74999973 0-5.62500027 11.24999973-19.68749973 16.875-28.12499973 22.50000027-28.12499973 19.68749973-56.25000027 36.56249973-87.18749973 50.625s-67.5 8.4375-92.8125-11.24999973c-19.68749973-14.06250027-36.56249973-36.56249973-47.81250027-56.25000027h67.5z m357.18749973-5.62500027c25.3125-2.81249973 50.625 0 78.75000054 0 33.75 2.81249973 70.31249973 0 106.87499946 5.62500027 25.3125 2.81249973 50.625 0 73.12500027 2.81249973-8.4375 16.875-22.50000027 33.75-36.56249973 47.81250027-22.50000027 22.50000027-56.25000027 33.75-87.18750054 28.12499973-28.12499973-8.4375-50.625-25.3125-75.9375-39.37499946-14.06250027-8.4375-25.3125-16.875-39.37499946-25.3125-8.4375-8.4375-14.06250027-11.24999973-19.68750054-19.68750054z" fill="#C71F1E" p-id="32928"></path></svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
1
src/assets/img/cloud/jd.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743099498" class="icon" viewBox="0 0 2030 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="30911" width="200" height="200"><path d="M1669.09384945 432.48813594c15.51186469 21.69491531 27.11864437 51.1457625 25.81694906 112.86779625-17.46440719 193.78983094-181.96610156 316.14915281-345.76271156 316.14915281-177.24745781 0-302.04745781-127.56610125-377.111865-270.10169531C954.30062883 557.72203344 941.44639195 520.13559312 929.35147664 487.59322063c-23.701695 32.21694937-73.6542375 84.77288156-99.09152531 109.23389812A629.15254219 629.15254219 0 0 0 890.24639133 720.81355906c20.01355969 31.18644094 70.508475 101.74915219 142.69830562 157.61355938 65.62711875 50.60338969 128.59661062 81.68135625 199.81016906 99.41694937a487.81016906 487.81016906 0 0 0 354.65762719-50.00677968c128.81355937-73.81694906 219.60678-209.78983031 236.04067781-350.96949188-31.72881375-52.61016937-100.501695-114.76610156-154.35932156-144.37966031zM585.37859508 381.12542375a238.96949156 238.96949156 0 0 1 126.96949125 36.39322031c30.53559281-32.5423725 57.54576281-66.16949156 85.58644125-100.06779656A370.54915219 370.54915219 0 0 0 214.66673039 621.01694937a373.09830469 373.09830469 0 0 0 4.39322062 57.00339c10.3593225 12.79999969 114.71186438 4.12203375 130.98305063-10.52203406a242.49491531 242.49491531 0 0 1-4.55593219-46.48135594 239.89152563 239.89152563 0 0 1 239.89152563-239.89152562zM585.37859508 992a370.6576275 370.6576275 0 0 1-320.97627094-185.38305094c4.98983062-6.61694906 121.60000031-19.57966125 149.42372812-18.00678a239.07796594 239.07796594 0 0 0 171.55254282 72.29830594s147.52542375 11.33559281 285.39661031-97.62711937c0 0 51.85084781 73.87118625 91.66101656 101.64067781 0 0-130.00677938 127.07796656-377.05762687 127.07796656z" fill="#E1251B" p-id="30912"></path><path d="M1545.05317101 74.305085C1369.9209682 0.70508469 1199.0735107 22.18305125 1030.23283195 146.27796594 881.35147664 255.67457656 822.1243582 365.88474594 726.88367976 460.47457625c-113.89830469 113.13898313-199.32203344 151.21355906-267.06440718 176.81355938-69.96610125 26.46779625-167.59322062 44.52881344-240.75932157 40.51525406a371.41694906 371.41694906 0 0 0 45.34237313 128.59661062c186.79322063-3.19999969 318.48135562-74.68474594 403.41694875-126.48135656 74.2508475-45.28813594 185.97966094-159.34915219 244.61016937-233.22033844 94.21016906-118.56271219 216.94915219-231.97288125 329.16610219-267.55254281 156.7457625-49.62711844 309.1525425 19.79661 383.02372875 117.85762688 6.61694906 8.62372875 145.13898281 58.3593225 188.691525 95.78305125C1797.31079883 324.88135625 1721.8124932 148.61016969 1545.05317101 74.305085z" fill="#E1251B" p-id="30913" class="custom-cursor-on-hover"></path><path d="M1809.24300164 377.81694875A497.35593188 497.35593188 0 0 0 1526.39554383 286.91525469c-122.63050875 0-245.42372906 47.78305125-331.82372813 132.88135594-62.86101656 61.83050812-93.4508475 112.00000031-163.14576281 195.57966093a570.35932219 570.35932219 0 0 0 92.63728781 108.47457563c9.00339-13.12542375 59.66101688-84.82711875 97.62711844-135.21355875 48.81355969-64.10847469 98.38644094-115.36271156 173.5593225-145.03050844a350.04745781 350.04745781 0 0 1 427.498305 139.3355925A486.02033906 486.02033906 0 0 0 1809.24300164 377.81694875z" fill="#E1251B" p-id="30914" class="custom-cursor-on-hover"></path></svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
1
src/assets/img/cloud/kingsoft.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743116713" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="31939" width="200" height="200"><path d="M718.5408 453.8368c-4.1984 0-8.3968-0.7168-12.5952-0.7168a103.8336 103.8336 0 0 0-67.8912 25.088 139.6736 139.6736 0 0 0 13.6192-60.3136 133.12 133.12 0 0 0-2.4576-25.7024 139.5712 139.5712 0 0 0-274.432 0 133.12 133.12 0 0 0-2.4576 25.7024 139.6736 139.6736 0 0 0 13.6192 60.3136 103.8336 103.8336 0 0 0-67.8912-25.088c-4.1984 0-8.3968 0-12.5952 0.7168a104.5504 104.5504 0 1 0 101.0688 159.4368 116.736 116.736 0 0 0 6.144-11.0592 105.1648 105.1648 0 0 0 4.9152-76.6976 62.6688 62.6688 0 0 1 27.3408 20.48l2.6624 3.8912a83.2512 83.2512 0 0 1 133.9392-3.3792l4.7104 6.8608 51.2 73.9328a84.0704 84.0704 0 0 0 62.464 34.6112h5.5296a104.5504 104.5504 0 0 0 12.5952-208.384z" fill="#E6002D" p-id="31940"></path><path d="M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m200.8064 732.3648h-6.8608a152.4736 152.4736 0 0 1-120.5248-58.9824S509.2352 564.6336 508.0064 563.2a42.1888 42.1888 0 0 0-32.4608-15.2576 40.96 40.96 0 0 0-24.064 7.5776l122.88 175.4112a62.5664 62.5664 0 0 0 77.0048 20.48A97.5872 97.5872 0 0 1 593.92 783.5648a97.0752 97.0752 0 0 1-95.5392-39.1168l-49.4592-70.656a174.8992 174.8992 0 1 1-143.36-290.5088 209.7152 209.7152 0 0 1 413.9008 0 174.7968 174.7968 0 0 1-6.144 349.0816z" fill="#E6002D" p-id="31941"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
1
src/assets/img/cloud/lan.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717746661932" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="60936" width="200" height="200"><path d="M29.696 541.696A30.72 30.72 0 0 0 59.52 512 452.16 452.16 0 0 1 512 59.456a439.68 439.68 0 0 1 225.664 61.44l16.704 10.432 7.04 4.608-3.84 7.488c-1.216 2.496-1.536 6.592-1.536 16.64 0 44.352 37.504 81.856 81.856 81.856s81.856-37.504 81.856-81.856a83.008 83.008 0 0 0-108.544-77.824l-8.96 3.136-4.48 1.792-4.096-2.624A520.768 520.768 0 0 0 512 0C230.4 0 0 230.4 0 512c0 15.68 14.08 29.696 29.696 29.696z m588.16-186.24c-13.056-93.568-37.12-164.224-62.336-203.584a383.808 383.808 0 0 0-43.776-2.752c-14.784 0-29.568 1.088-43.776 2.752-25.216 39.36-49.28 109.44-62.4 203.584z m221.696 0a365.504 365.504 0 0 0-203.52-184.96c21.312 51.392 36.608 115.456 45.888 184.96z m-497.472 0c9.28-69.504 24.576-133.568 45.952-184.96a365.504 365.504 0 0 0-203.584 184.96z m520.512 250.688a358.4 358.4 0 0 0 0-188.288H688c2.688 31.232 3.84 62.4 3.84 94.144 0 31.744-1.664 62.912-3.84 94.144z m-237.568 0c2.176-29.568 3.84-61.312 3.84-94.144 0-33.408-1.664-64.64-3.84-94.144H398.976c-2.752 29.568-3.84 61.312-3.84 94.144 0 33.408 1.664 64.64 3.84 94.144z m-289.024 0A1073.92 1073.92 0 0 1 332.16 512c0-31.744 1.152-62.912 3.84-94.144H161.408a358.4 358.4 0 0 0 0 188.288zM512 1024c281.6 0 512-230.4 512-512a30.72 30.72 0 0 0-29.696-29.696 30.72 30.72 0 0 0-29.76 29.696A452.16 452.16 0 0 1 512 964.544a439.68 439.68 0 0 1-225.664-61.44l-16.704-10.432-7.04-4.608 3.84-7.488c1.216-2.496 1.536-6.592 1.536-16.64 0-44.352-37.504-81.856-81.856-81.856s-81.856 37.504-81.856 81.856a83.008 83.008 0 0 0 108.544 77.824l8.96-3.136 4.48-1.792 4.096 2.624A520.768 520.768 0 0 0 512 1024z m-0.256-149.12c14.72 0 29.568-1.088 43.776-2.752 25.152-39.36 49.28-109.44 62.4-203.584H405.568c13.12 93.568 37.184 164.224 62.4 203.584 14.208 1.664 28.992 2.752 43.776 2.752z m124.224-21.312a365.504 365.504 0 0 0 203.584-185.024h-157.632c-9.28 69.504-24.576 133.568-45.952 184.96z m-247.936 0c-21.376-51.456-36.672-115.52-45.952-185.024H184.448a365.504 365.504 0 0 0 203.52 184.96z" fill="#448CF7" p-id="60937"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
1
src/assets/img/cloud/nutanix.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717747391666" class="icon" viewBox="0 0 1333 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4694" width="200" height="200"><path d="M1018.488284 0.541672L1314.82427 0a18.458499 18.458499 0 0 1 13.083451 31.500282L894.070504 465.337499a18.458499 18.458499 0 0 1-26.104401 0L720.079363 317.450758a18.458499 18.458499 0 0 1 0-26.093983L1005.477751 5.937553a18.458499 18.458499 0 0 1 13.02095-5.406298zM1018.488284 1023.446662l296.335986 0.552088a18.458499 18.458499 0 0 0 13.083451-31.500282L894.070504 558.650834a18.458499 18.458499 0 0 0-26.104401 0L720.079363 706.547992a18.458499 18.458499 0 0 0 0 26.1044l285.398388 285.398388a18.458499 18.458499 0 0 0 13.02095 5.406298z" fill="#054496" p-id="4695"></path><path d="M821.319852 500.275312L327.34668 5.416715A18.437665 18.437665 0 0 0 314.29448 0H18.510582A18.479332 18.479332 0 0 0 5.437549 31.531532l466.566676 467.400018a18.500166 18.500166 0 0 1 0 26.146067L5.458382 992.425551a18.489749 18.489749 0 0 0 13.083451 31.562782h295.74223a18.437665 18.437665 0 0 0 13.052201-5.416715l493.973172-494.858596a16.593899 16.593899 0 0 0 0-23.448127z" fill="#87BB4C" p-id="4696"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
src/assets/img/cloud/openstack.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717746166860" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="51952" width="200" height="200"><path d="M928.856 10.912H95.142C42.814 10.912 0 53.726 0 106.054v224.202h231.25v-36.64c0-28.418 23.046-51.454 51.464-51.454h458.58c28.42 0 51.456 23.036 51.456 51.456v36.64H1024V106.052c0-52.328-42.816-95.142-95.144-95.142zM792.75 730.38c0 28.42-23.036 51.466-51.456 51.466h-458.58c-28.418 0-51.464-23.046-51.464-51.466v-36.63H0v224.194c0 52.336 42.816 95.142 95.144 95.142h833.714c52.328 0 95.142-42.806 95.142-95.142V693.752H792.75v36.63zM0.006 627.628h231.25V396.38H0.006v231.25z m792.74 0h231.25V396.38H792.748v231.25z" fill="#E72F52" p-id="51953"></path></svg>
|
||||
|
After Width: | Height: | Size: 713 B |
1
src/assets/img/cloud/qcloud.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743207396" class="icon" viewBox="0 0 1402 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="35171" width="200" height="200"><path d="M1216.84017881 832.26669714c-22.01770438 22.42169837-66.05311315 55.95324845-143.01407896 55.95324845H600.84945441c143.01407897-139.88312044 264.01045355-257.44554135 275.01930505-268.65639054a860.50843905 860.50843905 0 0 1 65.9521143-61.60917245c55.04426026-50.29732444 98.9786702-55.8522496 137.45915242-55.85224962 55.04426026 0 98.9786702 22.32069952 137.56015263 55.95324846 76.96096581 72.71902281 76.96096581 201.4922929 0 274.2113157z m93.42374503-363.79711171a304.81390494 304.81390494 0 0 0-225.42897111-100.79664655c-77.06196465 0-143.01407897 27.97662354-203.51226695 72.71902278-22.01770438 22.52269721-54.94326142 44.84339811-82.51589098 78.47594568-21.91670555 22.32069952-494.89335097 492.5703818-494.89335097 492.57038317 27.47163072 5.55492517 60.59918544 5.55492517 87.96981869 5.55492517h599.42694635c44.03540877 0 76.96096581 0 110.08852053-5.55492517a335.11349765 335.11349765 0 0 0 203.41126672-89.58579738c126.45030092-123.21834493 126.45030092-330.265563 5.45392772-453.3829077z" fill="#00A3FF" p-id="35172"></path><path d="M528.73642327 435.44302817c-60.80118311-45.14639325-121.70336508-67.66909045-193.51339969-67.66909045a306.02588827 306.02588827 0 0 0-226.74195328 101.60463453 333.80051551 333.80051551 0 0 0 5.55492517 462.97777956c55.24625795 50.80231726 110.59351474 78.98093847 176.94962165 84.63686387l127.1572928-124.22833194h-71.91103484c-71.91103347-5.65592402-116.14843991-28.27962006-143.72106809-56.45824128a206.03723244 206.03723244 0 0 1-5.55492656-282.29120635c38.68247989-39.49046924 82.91988635-56.45824127 138.26714315-56.45824267 33.12755473 0 82.91988635 5.65592402 132.71221657 56.55924012 22.11870323 22.52269721 82.91988635 67.66909045 105.03858956 90.29278788h5.55492518l82.91988496-84.73786132v-5.65592401c-38.68247989-39.49046924-99.58466186-90.29278651-132.71221658-118.57240794" fill="#00C8DC" p-id="35173"></path><path d="M1114.32655611 290.00498256A436.81913102 436.81913102 0 0 0 705.58504746 7.00678432c-218.3590661 0-391.87473546 160.8908378-425.507283 360.66615456 16.76577435 0 33.63254755-5.45392634 55.95324845-5.45392634 22.42169837 0 50.49932212 5.45392634 72.82002164 5.45392634 27.97662354-138.67113711 151.19496845-238.55879549 296.73401291-238.55879412a310.06583359 310.06583359 0 0 1 279.96823856 177.55561331s5.55492517 5.55492517 5.55492517 0c39.18747409-5.55492517 84.03087084-16.66477551 123.21834492-16.66477551 0 5.55492517 0 5.55492517 0 0" fill="#006EFF" p-id="35174"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
1
src/assets/img/cloud/qcloud_lighthouse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743207396" class="icon" viewBox="0 0 1402 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="35171" width="200" height="200"><path d="M1216.84017881 832.26669714c-22.01770438 22.42169837-66.05311315 55.95324845-143.01407896 55.95324845H600.84945441c143.01407897-139.88312044 264.01045355-257.44554135 275.01930505-268.65639054a860.50843905 860.50843905 0 0 1 65.9521143-61.60917245c55.04426026-50.29732444 98.9786702-55.8522496 137.45915242-55.85224962 55.04426026 0 98.9786702 22.32069952 137.56015263 55.95324846 76.96096581 72.71902281 76.96096581 201.4922929 0 274.2113157z m93.42374503-363.79711171a304.81390494 304.81390494 0 0 0-225.42897111-100.79664655c-77.06196465 0-143.01407897 27.97662354-203.51226695 72.71902278-22.01770438 22.52269721-54.94326142 44.84339811-82.51589098 78.47594568-21.91670555 22.32069952-494.89335097 492.5703818-494.89335097 492.57038317 27.47163072 5.55492517 60.59918544 5.55492517 87.96981869 5.55492517h599.42694635c44.03540877 0 76.96096581 0 110.08852053-5.55492517a335.11349765 335.11349765 0 0 0 203.41126672-89.58579738c126.45030092-123.21834493 126.45030092-330.265563 5.45392772-453.3829077z" fill="#00A3FF" p-id="35172"></path><path d="M528.73642327 435.44302817c-60.80118311-45.14639325-121.70336508-67.66909045-193.51339969-67.66909045a306.02588827 306.02588827 0 0 0-226.74195328 101.60463453 333.80051551 333.80051551 0 0 0 5.55492517 462.97777956c55.24625795 50.80231726 110.59351474 78.98093847 176.94962165 84.63686387l127.1572928-124.22833194h-71.91103484c-71.91103347-5.65592402-116.14843991-28.27962006-143.72106809-56.45824128a206.03723244 206.03723244 0 0 1-5.55492656-282.29120635c38.68247989-39.49046924 82.91988635-56.45824127 138.26714315-56.45824267 33.12755473 0 82.91988635 5.65592402 132.71221657 56.55924012 22.11870323 22.52269721 82.91988635 67.66909045 105.03858956 90.29278788h5.55492518l82.91988496-84.73786132v-5.65592401c-38.68247989-39.49046924-99.58466186-90.29278651-132.71221658-118.57240794" fill="#00C8DC" p-id="35173"></path><path d="M1114.32655611 290.00498256A436.81913102 436.81913102 0 0 0 705.58504746 7.00678432c-218.3590661 0-391.87473546 160.8908378-425.507283 360.66615456 16.76577435 0 33.63254755-5.45392634 55.95324845-5.45392634 22.42169837 0 50.49932212 5.45392634 72.82002164 5.45392634 27.97662354-138.67113711 151.19496845-238.55879549 296.73401291-238.55879412a310.06583359 310.06583359 0 0 1 279.96823856 177.55561331s5.55492517 5.55492517 5.55492517 0c39.18747409-5.55492517 84.03087084-16.66477551 123.21834492-16.66477551 0 5.55492517 0 5.55492517 0 0" fill="#006EFF" p-id="35174"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
1
src/assets/img/cloud/qing.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717745876738" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="50950" width="200" height="200"><path d="M494.272 0L347.968 89.088l146.304 86.4V0z m43.904 175.552l146.304-87.488L538.176 0v175.552z m0 731.392l146.304-87.872-146.304-87.68v175.552z m-43.904 0V731.52l-146.304 88.128 146.304 87.36m409.6-205.696L757.568 614.4v175.552l146.304-88.704M289.472 614.4l-146.304 87.68 146.304 87.872V614.4z m468.096-73.152l146.304-88.128-146.304-87.424v175.552z m-468.096 0V365.696L143.168 453.632l146.304 87.68m614.4-336.768L757.568 117.12V292.48l146.304-88m-614.4-87.488l-146.304 88.32 146.304 87.168V117.12z m629.056 307.2V248.704l-146.304 88.256 146.304 87.296m-789.952 0l146.304-88.064-146.304-87.488v175.552z m146.304 146.432L128.576 482.752v175.552l146.304-87.616m497.344 0.192l146.304 87.424V482.752L772.224 570.88m-438.848 43.52v175.552l146.304-88L333.376 614.4m380.352 175.552V614.4l-146.304 87.68 146.304 87.872M333.376 307.2l146.304-88.128-146.304-87.424V307.2z m380.352 541.248l-146.304 88.768L713.728 1024v-175.552z m0-555.904V131.648L567.424 212.672l146.304 79.872" fill="#57B382" p-id="50951"></path><path d="M494.272 0v175.552L347.968 89.088 494.272 0m43.904 175.552V0l146.304 88.064-146.304 87.488m0 731.392V731.52l146.304 87.68-146.304 87.808m-43.904 0l-146.304-87.36 146.304-88.128v175.488z m409.6-205.696l-146.304 88.704V614.4l146.304 86.848M289.472 614.4v175.552L143.168 702.08 289.472 614.4m468.096-73.152V365.696l146.304 87.424-146.304 88.128m-468.096 0L143.168 453.632l146.304-87.936v175.552z m614.4-336.64L757.568 292.48V117.12l146.304 87.488m-614.4-87.488V292.48L143.168 205.44l146.304-88.384m629.056 307.2l-146.304-87.296 146.304-88.32V424.32z m-789.952 0V248.704l146.304 87.488-146.304 88.064m146.304 146.432l-146.304 87.616V482.752l146.304 87.936m497.344 0.192l146.304-88.128v175.552L772.224 570.88m-438.848 43.52l146.304 87.552-146.304 88V614.4z m380.352 175.552l-146.304-87.936L713.728 614.4v175.552zM333.376 307.2V131.648l146.304 87.424L333.376 307.2m380.352 541.248V1024l-146.304-86.784 146.304-88.768m0-555.904L567.424 212.672l146.304-81.024v160.896z" fill="#57B382" p-id="50952" class="custom-cursor-on-hover"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
1
src/assets/img/cloud/scp.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717746510567" class="icon" viewBox="0 0 1351 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="55261" width="200" height="200"><path d="M416.92885 824.173591c-56.901379 30.927289-130.232881 35.397249-203.685192-3.745101a159.190971 159.190971 0 0 1-65.35806-64.754011c-79.130368-147.025432 15.826074-294.775723 150.770533-309.635319 7.369393-0.845668 14.738786-1.328907 22.228989-1.328907 59.317574 0 112.353042 25.732471 149.320817 66.324538a249.50832 249.50832 0 0 1-26.457329-111.628184c0-16.188503 1.691336-31.893767 4.590769-47.236601a320.508194 320.508194 0 0 0-127.575067-26.45733c-6.161296 0-12.201782 0.604049-18.242268 0.966478C83.252396 339.122556-77.424535 571.198033 39.036038 806.897801c25.370042 51.344132 66.686967 93.748345 117.668669 119.601625 115.614904 58.713525 230.50495 50.377654 319.420907 0.966478 31.531338-17.51741 38.659111-59.921622 15.946883-88.070288-0.241619-0.362429-0.483239-0.604049-0.724858-0.966477-18.000649-22.349799-49.290367-27.907046-74.418789-14.255548z" fill="#62B0DB" p-id="55262"></path><path d="M443.869418 399.527417c0-16.188503 1.691336-31.893767 4.590769-47.236602 23.557896-123.709156 137.602274-215.403735 270.855398-203.081143 24.041135 2.174575 46.994982 8.094251 68.740732 16.792551 50.377654-17.879839 104.3796-28.148665 160.91855-28.148665 16.550932 0 32.981054 0.845668 49.169557 2.537004C928.558024 59.448048 827.561096 5.929341 715.328864 0.492904c-204.65167-10.027207-377.167953 134.098792-412.565202 326.18625-4.34915 23.678706-6.886154 47.96146-6.886154 72.848263 0 15.826074 1.208097 31.289718 2.899433 46.511743 7.369393-0.845668 14.738786-1.328907 22.228989-1.328907 59.317574 0 112.473852 25.732471 149.320817 66.324538-16.792551-33.464293-26.457329-71.277736-26.457329-111.507374z" fill="#8FC361" p-id="55263"></path><path d="M1114.725806 778.386706S880.717374 806.172943 749.034777 723.176663c-66.928586-42.162593-43.73312-127.937496 50.015225-152.461869 63.666724-16.671742 302.024306-14.376357 457.989657 13.04745 156.086161 27.423807 124.675634 166.717417-142.313853 194.624462zM1316.961282 782.615047s-67.170206 87.22462-241.981874 113.561139c-72.727453 10.993685-135.06527 13.289069-224.102035 0 0 0-70.311258-18.967126-82.392231 35.638868-14.376357 65.23725 157.656688 128.420735 327.998396 62.458627 172.274664-66.566157 220.477743-211.658634 220.477744-211.658634z" fill="#ADD079" p-id="55264"></path><path d="M1341.244036 531.089205s-44.457978-76.955793-241.136206-131.924217c-195.228511-54.605995-295.86301 15.463644-346.240665-30.202431-24.886803-22.470608-5.194818-77.318222 23.557896-101.480167 46.994982-39.504779 176.744624-83.600328 323.407627-20.416843 214.558067 92.540247 240.411348 284.023657 240.411348 284.023658z" fill="#A2CB70" p-id="55265"></path><path d="M783.948786 456.791225s234.008432-27.786236 365.69103 55.210044c66.928586 42.162593 43.73312 127.937496-50.015225 152.461869-63.666724 16.671742-302.024306 14.376357-457.989658-13.04745-156.086161-27.302997-124.675634-166.717417 142.313853-194.624463z m11.839353 535.42869c146.663003 63.183485 276.412645 19.208746 323.407627-20.416843 28.631904-24.161944 48.444699-78.888749 23.557896-101.480167-50.377654-45.666075-151.012153 24.403564-346.240665-30.20243-196.678228-54.968424-241.136206-131.924217-241.136206-131.924217s25.97409 191.60422 240.411348 284.023657zM579.780355 456.791225s67.170206-87.22462 241.981874-113.561139c72.727453-10.993685 135.06527-13.289069 224.102036 0 0 0 70.311258 18.967126 82.39223-35.638868 14.376357-65.23725-157.656688-128.420735-327.998396-62.458626-172.274664 66.566157-220.477743 211.658634-220.477744 211.658633z" fill="#4885BE" p-id="55266"></path></svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
1
src/assets/img/cloud/state.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717747284124" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2464" width="200" height="200"><path d="M838.4 416c-6.4-70.4-64-115.2-134.4-115.2-19.2 0-38.4 6.4-51.2 6.4-44.8-51.2-115.2-83.2-185.6-83.2-89.6 0-172.8 51.2-211.2 128h-12.8C115.2 352 19.2 448 12.8 576s96 224 224 230.4h294.4c25.6 0 44.8-19.2 44.8-44.8s-19.2-44.8-44.8-44.8H249.6c-70.4 0-134.4-57.6-134.4-128s51.2-128 121.6-134.4c12.8 0 25.6 0 38.4 6.4h6.4l25.6 6.4C320 390.4 390.4 320 473.6 320c57.6 0 108.8 32 140.8 83.2 6.4 6.4 6.4 12.8 6.4 19.2l6.4-6.4c19.2-19.2 51.2-19.2 70.4-19.2 44.8 0 70.4 38.4 70.4 76.8 0 12.8-6.4 25.6-6.4 38.4 12.8 6.4 19.2 19.2 38.4 19.2 6.4-6.4 19.2-12.8 19.2-19.2 64 6.4 115.2 57.6 108.8 128-6.4 57.6-57.6 108.8-121.6 108.8-51.2 0-96-32-115.2-83.2h51.2c6.4 0 12.8-6.4 12.8-12.8s0-6.4-6.4-6.4l-96-128c-6.4-6.4-12.8-12.8-19.2-6.4h-6.4l-96 128c-6.4 6.4-6.4 19.2 6.4 19.2 6.4 0 6.4 6.4 6.4 6.4h57.6c19.2 115.2 128 192 243.2 172.8 115.2-19.2 192-128 172.8-243.2-25.6-96-89.6-160-179.2-179.2z" fill="#F3A22F" p-id="2465"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
1
src/assets/img/cloud/ucloud.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743387740" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="38378" width="200" height="200"><path d="M912.192 0C973.952 0 1024 50.048 1024 111.808v800.384c0 61.76-50.048 111.808-111.808 111.808H111.808A111.808 111.808 0 0 1 0 912.192V111.808C0 50.048 50.048 0 111.808 0h800.384zM672 185.152c-23.936-1.088-30.912 6.144-30.656 30.4 1.28 116.864 0.832 233.728 0.384 350.592-0.128 37.76 2.368 75.52-3.392 113.216-6.912 45.184-33.92 71.68-76.16 82.88-52.672 13.952-107.136-1.728-131.2-36.736-17.6-25.728-19.84-55.552-19.904-85.632-0.192-120.32-0.448-240.64 0.192-360.96 0.128-18.432-4.032-26.24-24.448-26.24-20.416 0.128-27.136 8-24.128 26.432 4.608 28.16-8.256 37.12-34.24 33.152-23.168-3.456-35.2 5.248-30.912 29.952 5.312 30.4-6.912 42.304-37.248 37.248-20.416-3.392-30.72 2.304-30.144 26.88 1.6 79.04-0.512 158.08 1.024 237.184 2.24 113.088 79.104 204.8 189.632 230.912a462.08 462.08 0 0 0 187.136 5.632c133.12-23.04 214.08-117.824 214.4-252.416V435.2c0-74.496-0.896-148.992 0.448-223.424 0.448-21.76-6.4-27.264-27.2-26.56-41.152 1.536-82.432 1.92-123.52 0z m-422.784 133.76c-16.832-3.84-18.752 7.04-19.2 21.568-0.384 15.296 3.968 22.208 20.736 22.464 18.496 0.32 22.528-7.36 22.528-24.128 0-16.96-7.296-22.144-24.064-19.84z m73.6-65.92l-4.992 0.448c-17.792-2.816-20.928 7.04-20.8 22.272 0 15.104 6.592 19.456 20.864 19.648 15.68 0.256 22.72-4.224 22.656-21.248 0-17.024-6.72-23.04-22.72-20.672z m-134.464 3.904c-10.88 0.384-12.288 7.36-12.608 16-0.448 11.008 2.88 17.664 15.168 16 12.672 1.216 15.168-6.144 14.912-16.768-0.32-11.84-6.656-15.552-17.472-15.232z m68.032-3.648c-11.776 0.32-19.904 1.664-19.52 16.512 0.32 11.776 1.472 19.968 16.448 19.328 11.52-0.448 21.12-0.896 18.944-16.192 1.28-11.904-0.96-20.096-15.872-19.648z m126.592-68.032c-17.088-0.32-20.8 6.848-20.928 22.336-0.128 16.96 6.848 22.656 22.592 20.352 17.664 2.88 20.288-7.04 20.736-21.952 0.512-17.28-7.232-20.48-22.4-20.736z m-58.816 7.104l-4.736 0.32c-12.48-0.96-22.272-0.064-22.336 16.96 0 15.872 7.552 19.072 21.056 18.752 12.352-0.256 22.08-0.64 22.208-17.6 0.128-16.128-7.616-19.648-20.928-18.112z m-137.6 6.016c-9.088-0.128-10.816 5.632-10.432 13.056 0.384 9.088 6.464 10.304 13.632 9.792 7.872-0.64 11.776-4.928 11.008-12.992-0.832-8.832-7.232-9.792-14.208-9.856z m65.728-5.632h-3.584c-11.328 0.32-11.392 7.936-11.456 16.128 0 10.88 6.976 12.544 15.616 12.096 10.368 0.512 12.928-5.248 13.184-14.528 0.32-13.056-7.552-13.952-17.28-13.696z m66.816-55.68c-7.808 0.256-16.832-0.96-17.472 10.56-0.704 11.712 6.592 15.616 17.024 15.744 9.152 0.128 15.424-2.944 15.36-13.312 0.832-11.008-5.952-13.312-14.912-12.992z m-63.68 0.448c-7.936-0.128-12.352 3.072-12.288 11.456 0.128 7.424 2.752 12.8 11.008 13.376 8.32 0.512 11.712-4.288 12.032-12.032 0.64-7.808-2.176-12.608-10.752-12.8z" fill="#3860F4" p-id="38379" class="custom-cursor-on-hover"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
1
src/assets/img/cloud/vmware.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717747341803" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3484" width="200" height="200"><path d="M813.6 65H451.9c-81.8 0-144.7 62.7-144.7 144.1v100.4h-97.5C127.9 309.5 65 372.3 65 453.7v360.5c0 81.4 62.8 144.2 144.7 144.2h358.6c81.8 0 144.7-62.7 144.7-144.2V710.7h100.6c81.8 0 144.7-62.7 144.7-144.2V206c3.2-75.3-62.9-141-144.7-141z m37.8 504.6c-0.4 20.6-17.1 37.3-37.7 37.5H609.2V814c-0.3 20.7-17 37.3-37.7 37.6H209.8c-20.7-0.2-37.4-16.9-37.8-37.6V453.6c0.3-20.7 17.1-37.4 37.8-37.6h204.4V209.1c0-21.9 18.9-37.5 37.8-37.5h361.7c20.6 0.3 37.3 16.9 37.7 37.5v360.5z m0 0" fill="#8FBE48" p-id="3485"></path><path d="M514.8 268.7v235H272.7V745h242.2V510H757V268.7H514.8z m0 0" fill="#F2B624" p-id="3486"></path></svg>
|
||||
|
After Width: | Height: | Size: 773 B |
1
src/assets/img/cloud/volcengine.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717743222537" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="36225" width="200" height="200"><path d="M830.537143 476.525714L706.413714 961.828571a8.484571 8.484571 0 0 0 0 4.022858 9.069714 9.069714 0 0 0 8.996572 6.948571h248.100571a9.069714 9.069714 0 0 0 9.069714-10.971429l-124.708571-485.302857a9.142857 9.142857 0 0 0-17.334857 0M147.602286 586.386286L51.492571 961.828571a8.996571 8.996571 0 0 0 9.069715 10.971429h191.488a9.142857 9.142857 0 0 0 7.241143-3.291429 8.777143 8.777143 0 0 0 1.755428-3.657142 8.484571 8.484571 0 0 0 0-4.022858L164.864 586.459429a8.777143 8.777143 0 0 0-3.291429-4.534858 9.216 9.216 0 0 0-10.752 0 8.777143 8.777143 0 0 0-3.218285 4.534858" fill="#00E5E5" p-id="36226"></path><path d="M317.074286 275.748571l-175.104 686.08a8.777143 8.777143 0 0 0 1.682285 7.460572c1.682286 2.194286 4.242286 3.437714 6.948572 3.437714h350.354286a9.069714 9.069714 0 0 0 9.069714-10.898286L334.409143 275.748571a8.777143 8.777143 0 0 0-3.291429-4.608 9.216 9.216 0 0 0-10.752 0 8.777143 8.777143 0 0 0-3.291428 4.608" fill="#006EFF" p-id="36227"></path><path d="M619.227429 57.490286A8.777143 8.777143 0 0 0 615.862857 52.955429a9.216 9.216 0 0 0-10.752 0 8.777143 8.777143 0 0 0-3.291428 4.534857L362.569143 961.828571a8.996571 8.996571 0 0 0 8.996571 10.898286h478.354286a9.216 9.216 0 0 0 9.142857-6.875428 8.996571 8.996571 0 0 0 0-4.022858L619.154286 57.490286z" fill="#006EFF" p-id="36228"></path><path d="M443.318857 375.442286L291.474286 961.828571a9.069714 9.069714 0 0 0 9.069714 10.971429l302.957714 0.073143a9.216 9.216 0 0 0 7.314286-3.364572 9.142857 9.142857 0 0 0 1.828571-7.68L460.653714 375.442286a9.216 9.216 0 0 0-8.704-6.290286 9.216 9.216 0 0 0-8.630857 6.290286" fill="#00E5E5" p-id="36229"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
1
src/assets/img/cloud/zstack.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1717746226986" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="52962" width="200" height="200"><path d="M527.36 102.4H450.048L350.0032 266.8544h68.9152L25.6 921.6h263.68l96.256-164.7616H317.1328l299.7248-489.984L527.36 102.4z m124.4672 211.7632l-233.1136 387.584h257.6896l32.512 55.0912H455.168L364.4928 921.6H998.4l-183.7056-327.168H681.472l27.3408-58.0608h69.12l-126.1568-222.208z" fill="#2558E6" p-id="52963"></path></svg>
|
||||
|
After Width: | Height: | Size: 478 B |
BIN
src/assets/img/deepSeek.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/assets/img/icons/bsd.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
src/assets/img/icons/cisco.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
BIN
src/assets/img/icons/clickhouse.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/assets/img/icons/db2.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/img/icons/gateway.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/assets/img/icons/general.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/img/icons/gpt.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
src/assets/img/icons/h3c.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
src/assets/img/icons/huawei.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
src/assets/img/icons/k8s.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/assets/img/icons/linux.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
src/assets/img/icons/macos.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src/assets/img/icons/mariadb.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
src/assets/img/icons/mongodb.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
src/assets/img/icons/mysql.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/img/icons/oracle.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
src/assets/img/icons/other.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src/assets/img/icons/postgresql.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/assets/img/icons/private.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/img/icons/redis.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/assets/img/icons/sqlserver.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
src/assets/img/icons/unix.png
Normal file
|
After Width: | Height: | Size: 940 B |
BIN
src/assets/img/icons/vmware.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/assets/img/icons/website.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/img/icons/windows.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
@@ -4,6 +4,7 @@
|
||||
|
||||
<script>
|
||||
import DataActions from '@/components/DataActions'
|
||||
|
||||
export default {
|
||||
name: 'ActionsGroup',
|
||||
components: {
|
||||
@@ -24,9 +25,7 @@ export default {
|
||||
},
|
||||
moreActionsTitle: {
|
||||
type: String,
|
||||
default() {
|
||||
return this.$t('common.MoreActions')
|
||||
}
|
||||
default: ''
|
||||
},
|
||||
moreActionsPlacement: {
|
||||
type: String,
|
||||
@@ -45,8 +44,9 @@ export default {
|
||||
iMoreAction() {
|
||||
const defaultBtn = {
|
||||
name: 'moreActions',
|
||||
title: this.$t('common.MoreActions'),
|
||||
title: '',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-more',
|
||||
plain: true
|
||||
}
|
||||
const btn = {
|
||||
@@ -62,7 +62,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
import { UpdateToken, UploadSecret } from '@/components/Form/FormFields'
|
||||
import Select2 from '@/components/Form/FormFields/Select2.vue'
|
||||
import AssetSelect from '@/components/Apps/AssetSelect/index.vue'
|
||||
import { Required, RequiredChange } from '@/components/Form/DataForm/rules'
|
||||
import AutomationParamsForm from '@/views/assets/Platform/AutomationParamsSetting.vue'
|
||||
|
||||
export const accountFieldsMeta = (vm) => {
|
||||
const defaultPrivilegedAccounts = ['root', 'administrator']
|
||||
|
||||
return {
|
||||
assets: {
|
||||
component: Select2,
|
||||
label: vm.$t('Assets'),
|
||||
rules: [Required],
|
||||
component: AssetSelect,
|
||||
label: vm.$t('assets.Asset'),
|
||||
el: {
|
||||
multiple: false
|
||||
multiple: true,
|
||||
ajax: {
|
||||
url: '/api/v1/assets/assets/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.address + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
hidden: () => {
|
||||
return vm.platform || vm.asset
|
||||
@@ -22,6 +28,9 @@ export const accountFieldsMeta = (vm) => {
|
||||
component: Select2,
|
||||
rules: [Required],
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
},
|
||||
multiple: false,
|
||||
ajax: {
|
||||
url: '/api/v1/accounts/account-templates/',
|
||||
@@ -36,15 +45,25 @@ export const accountFieldsMeta = (vm) => {
|
||||
},
|
||||
on_invalid: {
|
||||
rules: [Required],
|
||||
label: vm.$t('accounts.AccountPolicy'),
|
||||
helpText: vm.$t('accounts.BulkCreateStrategy'),
|
||||
label: vm.$t('AccountPolicy'),
|
||||
helpTip: vm.$t('AccountPolicyHelpText'),
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: () => {
|
||||
return vm.platform || vm.asset
|
||||
}
|
||||
},
|
||||
name: {
|
||||
label: vm.$t('common.Name'),
|
||||
label: vm.$t('Name'),
|
||||
rules: [RequiredChange],
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
if (!vm.usernameChanged) {
|
||||
@@ -64,7 +83,9 @@ export const accountFieldsMeta = (vm) => {
|
||||
},
|
||||
username: {
|
||||
el: {
|
||||
disabled: !!vm.account?.name
|
||||
get disabled() {
|
||||
return !!vm.account?.name || vm.isDisabled
|
||||
}
|
||||
},
|
||||
on: {
|
||||
input: ([value], updateForm) => {
|
||||
@@ -82,7 +103,12 @@ export const accountFieldsMeta = (vm) => {
|
||||
}
|
||||
},
|
||||
privileged: {
|
||||
label: vm.$t('assets.Privileged'),
|
||||
label: vm.$t('Privileged'),
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: () => {
|
||||
return vm.addTemplate
|
||||
}
|
||||
@@ -95,6 +121,11 @@ export const accountFieldsMeta = (vm) => {
|
||||
el: {
|
||||
multiple: false,
|
||||
clearable: true,
|
||||
disabled: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
ajax: {
|
||||
url: `/api/v1/accounts/accounts/su-from-accounts/?account=${vm.account?.id || ''}&asset=${vm.asset?.id || ''}`,
|
||||
transformOption: (item) => {
|
||||
@@ -104,65 +135,106 @@ export const accountFieldsMeta = (vm) => {
|
||||
}
|
||||
},
|
||||
su_from_username: {
|
||||
label: vm.$t('assets.UserSwitchFrom'),
|
||||
label: vm.$t('UserSwitchFrom'),
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: (formValue) => {
|
||||
return vm.platform || vm.asset || vm.addTemplate
|
||||
}
|
||||
},
|
||||
password: {
|
||||
label: vm.$t('assets.Password'),
|
||||
label: vm.$t('Password'),
|
||||
component: UpdateToken,
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: (formValue) => {
|
||||
return formValue.secret_type !== 'password' || vm.addTemplate
|
||||
}
|
||||
},
|
||||
ssh_key: {
|
||||
label: vm.$t('assets.PrivateKey'),
|
||||
label: vm.$t('PrivateKey'),
|
||||
component: UploadSecret,
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: (formValue) => formValue.secret_type !== 'ssh_key' || vm.addTemplate
|
||||
},
|
||||
passphrase: {
|
||||
label: vm.$t('assets.Passphrase'),
|
||||
label: vm.$t('Passphrase'),
|
||||
component: UpdateToken,
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: (formValue) => formValue.secret_type !== 'ssh_key' || vm.addTemplate
|
||||
},
|
||||
token: {
|
||||
label: vm.$t('assets.Token'),
|
||||
label: vm.$t('Token'),
|
||||
component: UploadSecret,
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: (formValue) => formValue.secret_type !== 'token' || vm.addTemplate
|
||||
},
|
||||
access_key: {
|
||||
id: 'access_key',
|
||||
label: vm.$t('assets.AccessKey'),
|
||||
label: vm.$t('AccessKey'),
|
||||
component: UploadSecret,
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: (formValue) => formValue.secret_type !== 'access_key' || vm.addTemplate
|
||||
},
|
||||
api_key: {
|
||||
id: 'api_key',
|
||||
label: vm.$t('assets.ApiKey'),
|
||||
label: vm.$t('ApiKey'),
|
||||
component: UploadSecret,
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: (formValue) => formValue.secret_type !== 'api_key' || vm.addTemplate
|
||||
},
|
||||
secret_type: {
|
||||
type: 'radio-group',
|
||||
options: [],
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
},
|
||||
hidden: () => {
|
||||
return vm.addTemplate
|
||||
}
|
||||
},
|
||||
push_now: {
|
||||
helpText: vm.$t('accounts.AccountPush.WindowsPushHelpText'),
|
||||
helpTip: vm.$t('WindowsPushHelpText'),
|
||||
hidden: (formValue) => {
|
||||
const automation = vm.iPlatform.automation || {}
|
||||
return !automation.push_account_enabled ||
|
||||
!automation.ansible_enabled ||
|
||||
!vm.$hasPerm('accounts.push_account') ||
|
||||
(formValue.secret_type === 'ssh_key' && vm.iPlatform.type.value === 'windows') ||
|
||||
vm.addTemplate
|
||||
vm.addTemplate ||
|
||||
!formValue.secret_reset
|
||||
}
|
||||
},
|
||||
params: {
|
||||
label: vm.$t('assets.PushParams'),
|
||||
label: vm.$t('PushParams'),
|
||||
component: AutomationParamsForm,
|
||||
el: {},
|
||||
hidden: (formValue) => {
|
||||
@@ -179,12 +251,27 @@ export const accountFieldsMeta = (vm) => {
|
||||
}
|
||||
},
|
||||
is_active: {
|
||||
label: vm.$t('common.IsActive')
|
||||
label: vm.$t('IsActive'),
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
}
|
||||
},
|
||||
comment: {
|
||||
label: vm.$t('common.Comment'),
|
||||
hidden: () => {
|
||||
return vm.addTemplate
|
||||
label: vm.$t('Comment'),
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
}
|
||||
},
|
||||
secret_reset: {
|
||||
label: vm.$t('SecretReset'),
|
||||
el: {
|
||||
get disabled() {
|
||||
return vm.isDisabled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<AutoDataForm
|
||||
v-if="!loading"
|
||||
ref="AutoDataForm"
|
||||
:class="addTemplate? '': 'account-add'"
|
||||
:submit-btn-text="submitBtnText"
|
||||
v-bind="$data"
|
||||
@submit="confirm"
|
||||
/>
|
||||
@@ -43,7 +45,9 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
isDisabled: false,
|
||||
usernameChanged: false,
|
||||
submitBtnText: this.$t('Confirm'),
|
||||
iPlatform: {
|
||||
automation: {},
|
||||
su_enabled: false,
|
||||
@@ -58,19 +62,29 @@ export default {
|
||||
form: Object.assign({ 'on_invalid': 'error' }, this.account || {}),
|
||||
encryptedFields: ['secret'],
|
||||
fields: [
|
||||
[this.$t('assets.Asset'), ['assets']],
|
||||
[this.$t('accounts.AccountTemplate'), ['template']],
|
||||
[this.$t('common.Basic'), ['name', 'username', 'privileged', 'su_from', 'su_from_username']],
|
||||
[this.$t('assets.Secret'), [
|
||||
[this.$t('Basic'), ['name', 'username', 'privileged', 'su_from', 'su_from_username', 'template']],
|
||||
[this.$t('Assets'), ['assets']],
|
||||
[this.$t('Secret'), [
|
||||
'secret_type', 'password', 'ssh_key', 'token',
|
||||
'access_key', 'passphrase', 'api_key'
|
||||
'access_key', 'passphrase', 'api_key',
|
||||
'secret_reset'
|
||||
]],
|
||||
[this.$t('common.Other'), ['push_now', 'params', 'on_invalid', 'is_active', 'comment']]
|
||||
[this.$t('Other'), ['push_now', 'params', 'on_invalid', 'is_active', 'comment']]
|
||||
],
|
||||
fieldsMeta: accountFieldsMeta(this),
|
||||
hasSaveContinue: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$route.query': {
|
||||
handler(nv, ov) {
|
||||
if (nv && (nv.flag === 'move' || nv.flag === 'copy')) {
|
||||
this.isDisabled = true
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
try {
|
||||
await this.getPlatform()
|
||||
@@ -100,23 +114,23 @@ export default {
|
||||
setSecretTypeOptions() {
|
||||
const choices = [
|
||||
{
|
||||
label: this.$t('assets.Password'),
|
||||
label: this.$t('Password'),
|
||||
value: 'password'
|
||||
},
|
||||
{
|
||||
label: this.$t('assets.SSHKey'),
|
||||
label: this.$t('SSHKey'),
|
||||
value: 'ssh_key'
|
||||
},
|
||||
{
|
||||
label: this.$t('assets.Token'),
|
||||
label: this.$t('Token'),
|
||||
value: 'token'
|
||||
},
|
||||
{
|
||||
label: this.$t('assets.AccessKey'),
|
||||
label: this.$t('AccessKey'),
|
||||
value: 'access_key'
|
||||
},
|
||||
{
|
||||
label: this.$t('assets.ApiKey'),
|
||||
label: this.$t('ApiKey'),
|
||||
value: 'api_key'
|
||||
}
|
||||
]
|
||||
@@ -143,7 +157,11 @@ export default {
|
||||
delete form['secret']
|
||||
}
|
||||
if (this.account?.name) {
|
||||
this.$emit('edit', form)
|
||||
if (this.account.payload && this.account.payload === 'pam_account_clone') {
|
||||
this.$emit('add', form)
|
||||
} else {
|
||||
this.$emit('edit', form)
|
||||
}
|
||||
} else {
|
||||
this.$emit('add', form)
|
||||
}
|
||||
@@ -152,5 +170,24 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang='scss' scoped>
|
||||
.account-add {
|
||||
::v-deep .el-form-item {
|
||||
//margin-bottom: 5px;
|
||||
|
||||
.help-block {
|
||||
//margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .form-group-header {
|
||||
.hr-line-dashed {
|
||||
//margin: 5px 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,35 +1,38 @@
|
||||
<template>
|
||||
<Dialog
|
||||
v-if="iVisible"
|
||||
:close-on-click-modal="false"
|
||||
:destroy-on-close="true"
|
||||
:show-cancel="false"
|
||||
:show-confirm="false"
|
||||
<template v-if="iVisible">
|
||||
<Drawer
|
||||
:title="title"
|
||||
:visible.sync="iVisible"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
:visible="iVisible"
|
||||
class="drawer"
|
||||
@close-drawer="handleCloseDrawer"
|
||||
>
|
||||
<AccountCreateUpdateForm
|
||||
v-if="!loading"
|
||||
ref="form"
|
||||
:account="account"
|
||||
:add-template="addTemplate"
|
||||
:asset="asset"
|
||||
@add="addAccount"
|
||||
@edit="editAccount"
|
||||
/>
|
||||
</Dialog>
|
||||
<Page :title="'null'">
|
||||
<IBox class="content">
|
||||
<AccountCreateUpdateForm
|
||||
v-if="!loading"
|
||||
ref="form"
|
||||
:account="account"
|
||||
:add-template="addTemplate"
|
||||
:asset="asset"
|
||||
@add="addAccount"
|
||||
@edit="editAccount"
|
||||
/>
|
||||
</IBox>
|
||||
</Page>
|
||||
</Drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dialog from '@/components/Dialog/index.vue'
|
||||
import Drawer from '@/components/Drawer/index.vue'
|
||||
import AccountCreateUpdateForm from '@/components/Apps/AccountCreateUpdateForm/index.vue'
|
||||
import IBox from '@/components/IBox/index.vue'
|
||||
import Page from '@/layout/components/Page/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'CreateAccountDialog',
|
||||
components: {
|
||||
Dialog,
|
||||
IBox,
|
||||
Drawer,
|
||||
Page,
|
||||
AccountCreateUpdateForm
|
||||
},
|
||||
props: {
|
||||
@@ -52,7 +55,7 @@ export default {
|
||||
title: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return this.$t('assets.AddAccount')
|
||||
return this.$t('AddAccount')
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -91,7 +94,7 @@ export default {
|
||||
data = formValue
|
||||
url = `/api/v1/accounts/accounts/bulk/`
|
||||
if (data.assets.length === 0) {
|
||||
this.$message.error(this.$tc('assets.PleaseSelectAsset'))
|
||||
this.$message.error(this.$tc('PleaseSelectAsset'))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -110,11 +113,22 @@ export default {
|
||||
},
|
||||
editAccount(form) {
|
||||
const data = { ...form }
|
||||
this.$axios.patch(`/api/v1/accounts/accounts/${this.account.id}/`, data).then(() => {
|
||||
this.iVisible = false
|
||||
this.$emit('add', true)
|
||||
this.$message.success(this.$tc('common.updateSuccessMsg'))
|
||||
}).catch(error => this.setFieldError(error))
|
||||
const flag = this.$route.query.flag
|
||||
|
||||
switch (flag) {
|
||||
case 'copy':
|
||||
this.handleAccountOperation(this.account.id, 'copy-to-assets', data)
|
||||
break
|
||||
case 'move':
|
||||
this.handleAccountOperation(this.account.id, 'move-to-assets', data)
|
||||
break
|
||||
default:
|
||||
this.$axios.patch(`/api/v1/accounts/accounts/${this.account.id}/`, data).then(() => {
|
||||
this.iVisible = false
|
||||
this.$emit('add', true)
|
||||
this.$message.success(this.$tc('UpdateSuccessMsg'))
|
||||
}).catch(error => this.setFieldError(error))
|
||||
}
|
||||
},
|
||||
handleResult(resp, error) {
|
||||
let bulkCreate = !this.asset
|
||||
@@ -126,7 +140,7 @@ export default {
|
||||
}
|
||||
if (!bulkCreate) {
|
||||
if (!error) {
|
||||
this.$message.success(this.$tc('common.createSuccessMsg'))
|
||||
this.$message.success(this.$tc('CreateSuccessMsg'))
|
||||
} else {
|
||||
this.setFieldError(error)
|
||||
}
|
||||
@@ -167,11 +181,29 @@ export default {
|
||||
refsAutoDataForm.setFieldError(current, err)
|
||||
}
|
||||
}
|
||||
},
|
||||
handleCloseDrawer() {
|
||||
this.iVisible = false
|
||||
Reflect.deleteProperty(this.$route.query, 'flag')
|
||||
},
|
||||
handleAccountOperation(id, path, data) {
|
||||
this.$axios.post(`/api/v1/accounts/accounts/${id}/${path}/`, data).then((res) => {
|
||||
this.iVisible = false
|
||||
this.$emit('add', true)
|
||||
this.handleResult(res, null)
|
||||
}).catch(error => this.handleResult(null, error))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.drawer {
|
||||
::v-deep .el-drawer__body {
|
||||
|
||||
.el-form {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
<ListTable ref="ListTable" :header-actions="headerActions" :table-config="tableConfig" />
|
||||
<DrawerListTable
|
||||
ref="ListTable"
|
||||
:detail-drawer="detailDrawer"
|
||||
:header-actions="headerActions"
|
||||
:quick-filters="quickFilters"
|
||||
:table-config="tableConfig"
|
||||
/>
|
||||
<ViewSecret
|
||||
v-if="showViewSecretDialog"
|
||||
:account="account"
|
||||
@@ -16,26 +22,18 @@
|
||||
<AccountCreateUpdate
|
||||
v-if="showAddDialog"
|
||||
:account="account"
|
||||
:add-template="addTemplate"
|
||||
:asset="iAsset"
|
||||
:title="accountCreateUpdateTitle"
|
||||
:visible.sync="showAddDialog"
|
||||
@add="addAccountSuccess"
|
||||
@bulk-create-done="showBulkCreateResult($event)"
|
||||
/>
|
||||
<AccountCreateUpdate
|
||||
v-if="showAddTemplateDialog"
|
||||
:account="account"
|
||||
:add-template="true"
|
||||
:asset="iAsset"
|
||||
:title="accountCreateUpdateTitle"
|
||||
:visible.sync="showAddTemplateDialog"
|
||||
@add="addAccountSuccess"
|
||||
@bulk-create-done="showBulkCreateResult($event)"
|
||||
/>
|
||||
<ResultDialog
|
||||
v-if="showResultDialog"
|
||||
:result="createAccountResults"
|
||||
:visible.sync="showResultDialog"
|
||||
@close-all="closeAll"
|
||||
/>
|
||||
<AccountBulkUpdateDialog
|
||||
v-if="updateSelectedDialogSetting.visible"
|
||||
@@ -43,29 +41,36 @@
|
||||
v-bind="updateSelectedDialogSetting"
|
||||
@update="handleAccountBulkUpdate"
|
||||
/>
|
||||
<PasswordHistoryDialog
|
||||
v-if="showPasswordHistoryDialog"
|
||||
:account="currentAccountColumn"
|
||||
:visible.sync="showPasswordHistoryDialog"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ListTable from '@/components/Table/ListTable/index.vue'
|
||||
import { ActionsFormatter } from '@/components/Table/TableFormatters'
|
||||
import { accountOtherActions, accountQuickFilters, connectivityMeta } from './const'
|
||||
import { openTaskPage } from '@/utils/jms'
|
||||
import { ActionsFormatter, PlatformFormatter, SecretViewerFormatter, AccountConnectFormatter } from '@/components/Table/TableFormatters'
|
||||
import ViewSecret from './ViewSecret.vue'
|
||||
import UpdateSecretInfo from './UpdateSecretInfo.vue'
|
||||
import AccountCreateUpdate from './AccountCreateUpdate.vue'
|
||||
import { connectivityMeta } from './const'
|
||||
import { openTaskPage } from '@/utils/jms'
|
||||
import ResultDialog from './BulkCreateResultDialog.vue'
|
||||
import AccountCreateUpdate from './AccountCreateUpdate.vue'
|
||||
import PasswordHistoryDialog from './PasswordHistoryDialog.vue'
|
||||
import DrawerListTable from '@/components/Table/DrawerListTable/index.vue'
|
||||
import AccountBulkUpdateDialog from '@/components/Apps/AccountListTable/AccountBulkUpdateDialog.vue'
|
||||
|
||||
export default {
|
||||
name: 'AccountListTable',
|
||||
components: {
|
||||
AccountBulkUpdateDialog,
|
||||
ResultDialog,
|
||||
ListTable,
|
||||
UpdateSecretInfo,
|
||||
ViewSecret,
|
||||
AccountCreateUpdate
|
||||
ResultDialog,
|
||||
DrawerListTable,
|
||||
UpdateSecretInfo,
|
||||
AccountCreateUpdate,
|
||||
PasswordHistoryDialog,
|
||||
AccountBulkUpdateDialog
|
||||
},
|
||||
props: {
|
||||
url: {
|
||||
@@ -88,7 +93,7 @@ export default {
|
||||
},
|
||||
hasClone: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: true
|
||||
},
|
||||
asset: {
|
||||
type: Object,
|
||||
@@ -118,8 +123,7 @@ export default {
|
||||
columnsDefault: {
|
||||
type: Array,
|
||||
default: () => ([
|
||||
'name', 'username', 'asset', 'privileged',
|
||||
'secret_type', 'is_active', 'date_updated'
|
||||
'name', 'username', 'secret', 'asset', 'platform', 'connect'
|
||||
])
|
||||
},
|
||||
headerExtraActions: {
|
||||
@@ -129,21 +133,29 @@ export default {
|
||||
extraQuery: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
showQuickFilters: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
addTemplate: false,
|
||||
currentAccountColumn: {},
|
||||
showPasswordHistoryDialog: false,
|
||||
showViewSecretDialog: false,
|
||||
showUpdateSecretDialog: false,
|
||||
showResultDialog: false,
|
||||
showAddDialog: false,
|
||||
showAddTemplateDialog: false,
|
||||
detailDrawer: () => import('@/views/accounts/Account/AccountDetail/index.vue'),
|
||||
createAccountResults: [],
|
||||
accountCreateUpdateTitle: this.$t('assets.AddAccount'),
|
||||
iAsset: this.asset,
|
||||
account: {},
|
||||
secretUrl: '',
|
||||
quickFilters: this.showQuickFilters ? accountQuickFilters(this) : [],
|
||||
tableConfig: {
|
||||
url: this.url,
|
||||
permissions: {
|
||||
@@ -152,40 +164,64 @@ export default {
|
||||
},
|
||||
extraQuery: this.extraQuery,
|
||||
columnsExclude: ['spec_info'],
|
||||
columnsAdd: ['secret', 'platform', 'connect'],
|
||||
columnsShow: {
|
||||
min: ['name', 'username', 'actions'],
|
||||
default: this.columnsDefault
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatter: function(row) {
|
||||
const to = {
|
||||
name: 'AssetAccountDetail',
|
||||
params: { id: row.id }
|
||||
width: '120px',
|
||||
formatterArgs: {
|
||||
can: () => vm.$hasPerm('accounts.view_account'),
|
||||
getDrawerTitle({ row }) {
|
||||
return `${row.username}@${row.asset.name}`
|
||||
}
|
||||
if (vm.$hasPerm('accounts.view_account')) {
|
||||
return <router-link to={to}>{row.name}</router-link>
|
||||
} else {
|
||||
return <span>{row.name}</span>
|
||||
}
|
||||
},
|
||||
secret: {
|
||||
formatter: SecretViewerFormatter,
|
||||
width: '130px',
|
||||
formatterArgs: {
|
||||
secretFrom: 'api',
|
||||
hasDownload: false,
|
||||
actionLeft: true
|
||||
}
|
||||
},
|
||||
connect: {
|
||||
label: this.$t('Connect'),
|
||||
width: '80px',
|
||||
formatter: AccountConnectFormatter,
|
||||
formatterArgs: {
|
||||
buttonIcon: 'fa fa-desktop',
|
||||
titleText: '可选协议',
|
||||
url: '/api/v1/assets/assets/{id}',
|
||||
connectUrlTemplate: (row) => `/luna/pam_connect/${row.id}/${row.username}/${row.asset.id}/${row.asset.name}/`,
|
||||
setMapItem: (id, protocol) => {
|
||||
this.$store.commit('table/SET_PROTOCOL_MAP_ITEM', {
|
||||
key: id,
|
||||
value: protocol
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
platform: {
|
||||
label: this.$t('Platform'),
|
||||
width: '120px',
|
||||
formatter: PlatformFormatter,
|
||||
formatterArgs: {
|
||||
platformAttr: 'asset.platform'
|
||||
}
|
||||
},
|
||||
asset: {
|
||||
label: this.$t('assets.Asset'),
|
||||
formatter: function(row) {
|
||||
const to = {
|
||||
name: 'AssetDetail',
|
||||
params: { id: row.asset.id }
|
||||
}
|
||||
if (vm.$hasPerm('assets.view_asset')) {
|
||||
return <router-link to={to}>{row.asset.name}</router-link>
|
||||
} else {
|
||||
return <span>{row.asset.name}</span>
|
||||
}
|
||||
return row.asset.name
|
||||
}
|
||||
},
|
||||
username: {
|
||||
width: '120px'
|
||||
},
|
||||
secret_type: {
|
||||
width: '100px',
|
||||
formatter: function(row) {
|
||||
return row.secret_type.label
|
||||
}
|
||||
@@ -196,17 +232,16 @@ export default {
|
||||
}
|
||||
},
|
||||
has_secret: {
|
||||
width: '100px',
|
||||
width: '120px',
|
||||
formatterArgs: {
|
||||
showFalse: false
|
||||
}
|
||||
},
|
||||
privileged: {
|
||||
label: this.$t('assets.Privileged'),
|
||||
width: '120px',
|
||||
formatterArgs: {
|
||||
showText: false,
|
||||
showFalse: false
|
||||
showFalse: true
|
||||
}
|
||||
},
|
||||
connectivity: connectivityMeta,
|
||||
@@ -214,75 +249,11 @@ export default {
|
||||
formatter: ActionsFormatter,
|
||||
formatterArgs: {
|
||||
hasUpdate: false, // can set function(row, value)
|
||||
hasDelete: false, // can set function(row, value)
|
||||
hasClone: this.hasClone,
|
||||
moreActionsTitle: this.$t('common.More'),
|
||||
extraActions: [
|
||||
{
|
||||
name: 'View',
|
||||
title: this.$t('common.View'),
|
||||
can: this.$hasPerm('accounts.view_accountsecret'),
|
||||
type: 'primary',
|
||||
callback: ({ row }) => {
|
||||
// debugger
|
||||
vm.secretUrl = `/api/v1/accounts/account-secrets/${row.id}/`
|
||||
vm.account = row
|
||||
vm.showViewSecretDialog = false
|
||||
setTimeout(() => {
|
||||
vm.showViewSecretDialog = true
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ClearSecret',
|
||||
title: this.$t('common.ClearSecret'),
|
||||
can: this.$hasPerm('accounts.change_account'),
|
||||
type: 'primary',
|
||||
callback: ({ row }) => {
|
||||
this.$axios.patch(
|
||||
`/api/v1/accounts/accounts/clear-secret/`,
|
||||
{ account_ids: [row.id] }
|
||||
).then(() => {
|
||||
this.$message.success(this.$tc('common.ClearSuccessMsg'))
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Test',
|
||||
title: this.$t('accounts.Test'),
|
||||
can: ({ row }) =>
|
||||
!this.$store.getters.currentOrgIsRoot &&
|
||||
this.$hasPerm('accounts.change_account') &&
|
||||
row.asset['auto_config'].ansible_enabled &&
|
||||
row.asset['auto_config'].ping_enabled,
|
||||
callback: ({ row }) => {
|
||||
this.$axios.post(
|
||||
`/api/v1/accounts/accounts/tasks/`,
|
||||
{ action: 'verify', accounts: [row.id] }
|
||||
).then(res => {
|
||||
openTaskPage(res['task'])
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
title: this.$t('common.Update'),
|
||||
can: this.$hasPerm('accounts.change_account') && !this.$store.getters.currentOrgIsRoot,
|
||||
callback: ({ row }) => {
|
||||
const data = {
|
||||
...this.asset,
|
||||
...row.asset
|
||||
}
|
||||
vm.account = row
|
||||
vm.iAsset = data
|
||||
vm.showAddDialog = false
|
||||
vm.accountCreateUpdateTitle = this.$t('assets.UpdateAccount')
|
||||
setTimeout(() => {
|
||||
vm.showAddDialog = true
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
hasDelete: true, // can set function(row, value)
|
||||
hasClone: false,
|
||||
canDelete: () => vm.$hasPerm('accounts.delete_account'),
|
||||
moreActionsTitle: this.$t('More'),
|
||||
extraActions: accountOtherActions(this)
|
||||
}
|
||||
},
|
||||
...this.columnsMeta
|
||||
@@ -295,17 +266,10 @@ export default {
|
||||
hasCreate: false,
|
||||
hasImport: this.hasImport,
|
||||
hasExport: this.hasExport && this.$hasPerm('accounts.view_accountsecret'),
|
||||
handleImportClick: ({ selectedRows }) => {
|
||||
this.$eventBus.$emit('showImportDialog', {
|
||||
selectedRows,
|
||||
url: '/api/v1/accounts/accounts/',
|
||||
name: this?.name
|
||||
})
|
||||
},
|
||||
exportOptions: {
|
||||
url: this.exportUrl,
|
||||
mfaVerifyRequired: true,
|
||||
tips: this.$t('accounts.AccountExportTips')
|
||||
tips: this.$t('AccountExportTips')
|
||||
},
|
||||
importOptions: {
|
||||
canImportCreate: this.$hasPerm('accounts.add_account'),
|
||||
@@ -314,8 +278,9 @@ export default {
|
||||
extraActions: [
|
||||
{
|
||||
name: 'add',
|
||||
title: this.$t('common.Add'),
|
||||
title: this.$t('Create'),
|
||||
type: 'primary',
|
||||
icon: 'plus',
|
||||
can: () => {
|
||||
return vm.$hasPerm('accounts.add_account') && !this.$store.getters.currentOrgIsRoot
|
||||
},
|
||||
@@ -324,14 +289,14 @@ export default {
|
||||
setTimeout(() => {
|
||||
vm.iAsset = this.asset
|
||||
vm.account = {}
|
||||
vm.accountCreateUpdateTitle = this.$t('assets.AddAccount')
|
||||
vm.addTemplate = false
|
||||
vm.showAddDialog = true
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'add-template',
|
||||
title: this.$t('common.TemplateAdd'),
|
||||
title: this.$t('TemplateAdd'),
|
||||
has: !(this.platform || this.asset),
|
||||
can: () => {
|
||||
return vm.$hasPerm('accounts.add_account') && !this.$store.getters.currentOrgIsRoot
|
||||
@@ -341,8 +306,8 @@ export default {
|
||||
setTimeout(() => {
|
||||
vm.iAsset = this.asset
|
||||
vm.account = {}
|
||||
vm.accountCreateUpdateTitle = this.$t('assets.AddAccount')
|
||||
vm.showAddTemplateDialog = true
|
||||
vm.showAddDialog = true
|
||||
vm.addTemplate = true
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -350,14 +315,14 @@ export default {
|
||||
],
|
||||
extraMoreActions: [
|
||||
{
|
||||
name: 'BulkVerify',
|
||||
title: this.$t('accounts.BulkVerify'),
|
||||
name: 'TestSelected',
|
||||
title: this.$t('TestSelected'),
|
||||
type: 'primary',
|
||||
fa: 'fa-link',
|
||||
icon: 'verify',
|
||||
can: ({ selectedRows }) => {
|
||||
return selectedRows.length > 0 &&
|
||||
['clickhouse', 'redis', 'website', 'chatgpt'].indexOf(selectedRows[0].asset.type.value) === -1 &&
|
||||
!this.$store.getters.currentOrgIsRoot
|
||||
['clickhouse', 'redis', 'website', 'chatgpt'].indexOf(selectedRows[0].asset.type.value) === -1 &&
|
||||
!this.$store.getters.currentOrgIsRoot
|
||||
},
|
||||
callback: function({ selectedRows }) {
|
||||
const ids = selectedRows.map(v => {
|
||||
@@ -368,15 +333,15 @@ export default {
|
||||
{ action: 'verify', accounts: ids }).then(res => {
|
||||
openTaskPage(res['task'])
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$tc('common.bulkVerifyErrorMsg' + ' ' + err))
|
||||
this.$message.error(this.$tc('BulkVerifyErrorMsg' + ' ' + err))
|
||||
})
|
||||
}.bind(this)
|
||||
},
|
||||
{
|
||||
name: 'ClearSecrets',
|
||||
title: this.$t('common.ClearSecret'),
|
||||
name: 'BatchClearSecret',
|
||||
title: this.$t('ClearSecret'),
|
||||
type: 'primary',
|
||||
fa: 'clean',
|
||||
icon: 'clean',
|
||||
can: ({ selectedRows }) => {
|
||||
return selectedRows.length > 0 && vm.$hasPerm('accounts.change_account')
|
||||
},
|
||||
@@ -387,16 +352,16 @@ export default {
|
||||
this.$axios.patch(
|
||||
'/api/v1/accounts/accounts/clear-secret/',
|
||||
{ account_ids: ids }).then(() => {
|
||||
this.$message.success(this.$tc('common.ClearSuccessMsg'))
|
||||
this.$message.success(this.$tc('ClearSuccessMsg'))
|
||||
}).catch(err => {
|
||||
this.$message.error(this.$tc('common.bulkClearErrorMsg' + ' ' + err))
|
||||
this.$message.error(this.$tc('ClearErrorMsg' + ' ' + err))
|
||||
})
|
||||
}.bind(this)
|
||||
},
|
||||
{
|
||||
name: 'actionUpdateSelected',
|
||||
title: this.$t('accounts.AccountBatchUpdate'),
|
||||
fa: 'batch-update',
|
||||
name: 'UpdateSelected',
|
||||
title: this.$t('UpdateSelected'),
|
||||
icon: 'batch-update',
|
||||
can: ({ selectedRows }) => {
|
||||
return selectedRows.length > 0 &&
|
||||
!this.$store.getters.currentOrgIsRoot &&
|
||||
@@ -422,6 +387,15 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
accountCreateUpdateTitle() {
|
||||
if (this.addTemplate) {
|
||||
return this.$t('AddAccountByTemplate')
|
||||
} else {
|
||||
return this.$t('AddAccount')
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
url(iNew) {
|
||||
this.$set(this.tableConfig, 'url', iNew)
|
||||
@@ -429,46 +403,34 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.columns.length > 0) {
|
||||
this.tableConfig.columns = this.columns
|
||||
}
|
||||
if (this.otherActions) {
|
||||
const actionColumn = this.tableConfig.columns[this.tableConfig.columns.length - 1]
|
||||
for (const item of this.otherActions) {
|
||||
actionColumn.formatterArgs.extraActions.push(item)
|
||||
}
|
||||
}
|
||||
if (this.hasDeleteAction) {
|
||||
this.tableConfig.columnsMeta.actions.formatterArgs.extraActions.push(
|
||||
{
|
||||
name: 'Delete',
|
||||
title: this.$t('common.Delete'),
|
||||
can: this.$hasPerm('accounts.delete_account'),
|
||||
type: 'primary',
|
||||
callback: ({ row }) => {
|
||||
const msg = this.$t('accounts.AccountDeleteConfirmMsg')
|
||||
this.$confirm(msg, this.$tc('common.Info'), {
|
||||
type: 'warning',
|
||||
confirmButtonClass: 'el-button--danger',
|
||||
beforeClose: async(action, instance, done) => {
|
||||
if (action !== 'confirm') return done()
|
||||
this.$axios.delete(`/api/v1/accounts/accounts/${row.id}/`).then(() => {
|
||||
done()
|
||||
this.$refs.ListTable.reloadTable()
|
||||
this.$message.success(this.$tc('common.deleteSuccessMsg'))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
this.setActions()
|
||||
},
|
||||
activated() {
|
||||
// 由于组件嵌套较深,有可能导致 Error in activated hook: "TypeError: Cannot read properties of undefined (reading 'getList')" 的问题
|
||||
if (this.tabDeactivated) {
|
||||
setTimeout(() => this.refresh(), 300)
|
||||
}
|
||||
},
|
||||
deactivated() {
|
||||
this.tabDeactivated = true
|
||||
},
|
||||
methods: {
|
||||
setActions() {
|
||||
if (this.columns.length > 0) {
|
||||
this.tableConfig.columns = this.columns
|
||||
}
|
||||
if (this.otherActions) {
|
||||
const actionColumn = this.tableConfig.columns[this.tableConfig.columns.length - 1]
|
||||
for (const item of this.otherActions) {
|
||||
actionColumn.formatterArgs.extraActions.push(item)
|
||||
}
|
||||
}
|
||||
},
|
||||
onUpdateAuthDone(account) {
|
||||
Object.assign(this.account, account)
|
||||
},
|
||||
addAccountSuccess() {
|
||||
Reflect.deleteProperty(this.$route.query, 'flag')
|
||||
this.$refs.ListTable.reloadTable()
|
||||
},
|
||||
async getAssetDetail() {
|
||||
@@ -481,21 +443,33 @@ export default {
|
||||
this.$refs.ListTable.reloadTable()
|
||||
},
|
||||
showBulkCreateResult(results) {
|
||||
this.showResultDialog = false
|
||||
this.createAccountResults = results
|
||||
setTimeout(() => {
|
||||
this.showResultDialog = true
|
||||
}, 100)
|
||||
this.createAccountResults = results
|
||||
}, 350)
|
||||
},
|
||||
handleAccountBulkUpdate() {
|
||||
this.updateSelectedDialogSetting.visible = false
|
||||
this.$refs.ListTable.reloadTable()
|
||||
},
|
||||
closeAll() {
|
||||
setTimeout(() => {
|
||||
this.showResultDialog = false
|
||||
}, 350)
|
||||
|
||||
setTimeout(() => {
|
||||
this.showAddDialog = false
|
||||
}, 800)
|
||||
|
||||
setTimeout(() => {
|
||||
this.refresh()
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
<style lang="scss" scoped>
|
||||
.cell a {
|
||||
color: var(--color-info);
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const errorProp = this.$t('common.Error')
|
||||
const errorProp = this.$t('Error')
|
||||
const stateMap = {
|
||||
'created': this.$tc('common.Created'),
|
||||
'updated': this.$tc('common.Updated'),
|
||||
'skipped': this.$tc('common.Skipped')
|
||||
'created': this.$tc('Created'),
|
||||
'updated': this.$tc('Updated'),
|
||||
'skipped': this.$tc('Skipped')
|
||||
}
|
||||
const stateClsMap = {
|
||||
'created': 'color-primary',
|
||||
@@ -42,16 +42,16 @@ export default {
|
||||
'skipped': 'color-default'
|
||||
}
|
||||
return {
|
||||
title: this.$t('accounts.AddAccountResult'),
|
||||
title: this.$t('AddAccountResult'),
|
||||
config: {
|
||||
columns: [
|
||||
{
|
||||
prop: 'asset',
|
||||
label: this.$t('assets.Asset')
|
||||
label: this.$t('Asset')
|
||||
},
|
||||
{
|
||||
prop: 'state',
|
||||
label: this.$t('common.Status'),
|
||||
label: this.$t('Status'),
|
||||
width: '200px',
|
||||
formatter: (row) => {
|
||||
if (row.error) {
|
||||
@@ -71,11 +71,11 @@ export default {
|
||||
computed: {
|
||||
summary() {
|
||||
const labels = {
|
||||
total: this.$tc('common.Total'),
|
||||
created: this.$tc('common.Created'),
|
||||
updated: this.$tc('common.Updated'),
|
||||
skipped: this.$tc('common.Skipped'),
|
||||
error: this.$tc('common.Error')
|
||||
total: this.$tc('Total'),
|
||||
created: this.$tc('Created'),
|
||||
updated: this.$tc('Updated'),
|
||||
skipped: this.$tc('Skipped'),
|
||||
error: this.$tc('Error')
|
||||
}
|
||||
const grouped = _.groupBy(this.result, 'state')
|
||||
const groupedLength = _.mapValues(grouped, 'length')
|
||||
@@ -91,7 +91,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
closeDialog() {
|
||||
this.$emit('update:visible', false)
|
||||
this.$emit('close-all')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<script>
|
||||
import { GenericListTableDialog } from '@/layout/components'
|
||||
import { ShowKeyCopyFormatter } from '@/components/Table/TableFormatters'
|
||||
import { SecretViewerFormatter } from '@/components/Table/TableFormatters'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -23,7 +23,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
config: {
|
||||
title: this.$t('accounts.HistoryPassword'),
|
||||
title: this.$t('HistoryPassword'),
|
||||
visible: false,
|
||||
width: '60%',
|
||||
tableConfig: {
|
||||
@@ -32,15 +32,15 @@ export default {
|
||||
columns: ['secret', 'version', 'history_date'],
|
||||
columnsMeta: {
|
||||
secret: {
|
||||
label: this.$t('assets.Password'),
|
||||
formatter: ShowKeyCopyFormatter,
|
||||
label: this.$t('Password'),
|
||||
formatter: SecretViewerFormatter,
|
||||
formatterArgs: {
|
||||
hasDownload: false,
|
||||
name: this.account.name
|
||||
}
|
||||
},
|
||||
history_date: {
|
||||
label: this.$t('accounts.HistoryDate')
|
||||
label: this.$t('HistoryDate')
|
||||
},
|
||||
secret_type: {
|
||||
width: '200px'
|
||||
|
||||
@@ -65,7 +65,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item-textarea > > > .el-textarea__inner {
|
||||
.item-textarea ::v-deep .el-textarea__inner {
|
||||
height: 110px;
|
||||
}
|
||||
|
||||
@@ -78,12 +78,12 @@ export default {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
> > > .el-form-item__label {
|
||||
::v-deep .el-form-item__label {
|
||||
padding-right: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
> > > .el-form-item__content {
|
||||
::v-deep .el-form-item__content {
|
||||
line-height: 30px;
|
||||
|
||||
pre {
|
||||
|
||||
@@ -1,44 +1,36 @@
|
||||
<template>
|
||||
<Dialog
|
||||
:destroy-on-close="true"
|
||||
:title="$tc('assets.UpdateAssetUserToken')"
|
||||
:visible.sync="visible"
|
||||
width="50"
|
||||
@cancel="handleCancel()"
|
||||
@confirm="handleConfirm()"
|
||||
:show-buttons="false"
|
||||
:title="$tc('UpdateAssetUserToken')"
|
||||
:visible.sync="iVisible"
|
||||
width="800px"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<el-form label-position="right" label-width="90px">
|
||||
<el-form-item :label="$tc('assets.Name')">
|
||||
<el-input v-model="account['asset_name']" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$tc('assets.Username')">
|
||||
<el-input v-model="account['username']" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$tc('assets.Password')">
|
||||
<UpdateToken v-model="authInfo.password" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$tc('assets.SSHSecretKey')">
|
||||
<UploadKey @input="getFile" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$tc('assets.Passphrase')">
|
||||
<UpdateToken v-model="authInfo.passphrase" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<AutoDataForm
|
||||
:fields="fields"
|
||||
:fields-meta="fieldsMeta"
|
||||
:form="init"
|
||||
:has-reset="false"
|
||||
:has-save-continue="false"
|
||||
:url="''"
|
||||
method="patch"
|
||||
@submit="handleConfirm"
|
||||
/>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Dialog from '@/components/Dialog/index.vue'
|
||||
import { UpdateToken, UploadKey } from '@/components/Form/FormFields'
|
||||
import { accountFieldsMeta } from '@/components/Apps/AccountCreateUpdateForm/const'
|
||||
import { encryptPassword } from '@/utils/crypto'
|
||||
import AutoDataForm from '@/components/Form/AutoDataForm/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'UpdateSecretInfo',
|
||||
components: {
|
||||
Dialog,
|
||||
UploadKey,
|
||||
UpdateToken
|
||||
AutoDataForm,
|
||||
Dialog
|
||||
},
|
||||
props: {
|
||||
account: {
|
||||
@@ -51,49 +43,59 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const accountMeta = accountFieldsMeta(this)
|
||||
return {
|
||||
secretInfo: {
|
||||
password: '',
|
||||
private_key: '',
|
||||
passphrase: ''
|
||||
fields: [
|
||||
'name', 'secret_type', 'password', 'ssh_key', 'token',
|
||||
'access_key', 'passphrase', 'api_key'
|
||||
],
|
||||
fieldsMeta: {
|
||||
...accountMeta,
|
||||
name: {
|
||||
...accountMeta.name,
|
||||
readonly: true
|
||||
},
|
||||
secret_type: {
|
||||
hidden: () => true
|
||||
}
|
||||
},
|
||||
init: {
|
||||
...this.account
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iVisible: {
|
||||
get() {
|
||||
return this.visible
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:visible', val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleConfirm() {
|
||||
const data = {}
|
||||
if (this.secretInfo.password !== '') {
|
||||
data.password = encryptPassword(this.secretInfo.password)
|
||||
}
|
||||
if (this.secretInfo.private_key !== '') {
|
||||
data.private_key = encryptPassword(this.secretInfo.private_key)
|
||||
if (this.secretInfo.passphrase) data.passphrase = this.secretInfo.passphrase
|
||||
handleConfirm(form) {
|
||||
const secretType = this.account.secret_type.value
|
||||
const data = {
|
||||
secret: encryptPassword(form[secretType])
|
||||
}
|
||||
this.$axios.patch(
|
||||
`/api/v1/accounts/accounts/${this.account.id}/`,
|
||||
data,
|
||||
{ disableFlashErrorMsg: true }
|
||||
).then(res => {
|
||||
this.authInfo = { password: '', private_key: '' }
|
||||
this.$message.success(this.$tc('common.updateSuccessMsg'))
|
||||
this.$emit('updateAuthDone', res)
|
||||
this.$emit('update:visible', false)
|
||||
this.$message.success(this.$tc('UpdateSuccessMsg'))
|
||||
this.iVisible = false
|
||||
}).catch(err => {
|
||||
const errMsg = Object.values(err.response.data).join(', ')
|
||||
this.$message.error(this.$tc('common.updateErrorMsg') + ' ' + errMsg)
|
||||
this.$emit('update:visible', true)
|
||||
this.$message.error(this.$tc('UpdateErrorMsg') + ' ' + errMsg)
|
||||
this.iVisible = false
|
||||
})
|
||||
},
|
||||
handleCancel() {
|
||||
this.$emit('update:visible', false)
|
||||
},
|
||||
getFile(file) {
|
||||
this.secretInfo.private_key = file
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
@confirm="accountConfirmHandle"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<el-form :model="secretInfo" class="password-form" label-position="right" label-width="100px">
|
||||
<el-form-item :label="$tc('assets.Name')">
|
||||
<el-form :model="secretInfo" class="password-form" label-position="right" label-width="130px">
|
||||
<el-form-item :label="$tc('Name')">
|
||||
<span>{{ account['name'] }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$tc('assets.Username')">
|
||||
<el-form-item :label="$tc('Username')">
|
||||
<span>{{ account['username'] }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="secretTypeLabel">
|
||||
<ShowKeyCopyFormatter
|
||||
<SecretViewerFormatter
|
||||
:cell-value="secretInfo.secret"
|
||||
:col="{ formatterArgs: {
|
||||
name: account['name'],
|
||||
@@ -27,16 +27,16 @@
|
||||
@input="onShowKeyCopyFormatterChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="secretType === 'ssh_key'" :label="$tc('assets.sshKeyFingerprint')">
|
||||
<el-form-item v-if="secretType === 'ssh_key'" :label="$tc('SshKeyFingerprint')">
|
||||
<span>{{ sshKeyFingerprint }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$tc('common.DateCreated')">
|
||||
<el-form-item :label="$tc('DateCreated')">
|
||||
<span>{{ account['date_created'] | date }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$tc('common.DateUpdated')">
|
||||
<el-form-item :label="$tc('DateUpdated')">
|
||||
<span>{{ account['date_updated'] | date }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="showPasswordRecord" v-perms="'accounts.view_accountsecret'" :label="$tc('accounts.PasswordRecord')">
|
||||
<el-form-item v-if="showPasswordRecord" v-perms="'accounts.view_accountsecret'" :label="$tc('PasswordRecord')">
|
||||
<el-link
|
||||
:underline="false"
|
||||
type="success"
|
||||
@@ -60,7 +60,7 @@
|
||||
<script>
|
||||
import Dialog from '@/components/Dialog/index.vue'
|
||||
import PasswordHistoryDialog from './PasswordHistoryDialog.vue'
|
||||
import { ShowKeyCopyFormatter } from '@/components/Table/TableFormatters'
|
||||
import { SecretViewerFormatter } from '@/components/Table/TableFormatters'
|
||||
import { encryptPassword } from '@/utils/crypto'
|
||||
|
||||
export default {
|
||||
@@ -68,7 +68,7 @@ export default {
|
||||
components: {
|
||||
Dialog,
|
||||
PasswordHistoryDialog,
|
||||
ShowKeyCopyFormatter
|
||||
SecretViewerFormatter
|
||||
},
|
||||
props: {
|
||||
account: {
|
||||
@@ -90,7 +90,7 @@ export default {
|
||||
title: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return this.$tc('assets.AccountDetail')
|
||||
return this.$tc('Detail')
|
||||
}
|
||||
},
|
||||
showPasswordRecord: {
|
||||
@@ -142,7 +142,7 @@ export default {
|
||||
}
|
||||
const url = this.type === 'account' ? `/api/v1/accounts/accounts` : `/api/v1/accounts/account-templates`
|
||||
this.$axios.patch(`${url}/${this.account.id}/`, params).then(() => {
|
||||
this.$message.success(this.$tc('common.updateSuccessMsg'))
|
||||
this.$message.success(this.$tc('UpdateSuccessMsg'))
|
||||
})
|
||||
},
|
||||
showSecretDialog() {
|
||||
@@ -167,7 +167,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item-textarea >>> .el-textarea__inner {
|
||||
.item-textarea ::v-deep .el-textarea__inner {
|
||||
height: 110px;
|
||||
}
|
||||
|
||||
@@ -180,12 +180,18 @@ export default {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
>>> .el-form-item__label {
|
||||
::v-deep .el-form-item__label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding-right: 20px;
|
||||
line-height: 30px;
|
||||
word-break: keep-all;
|
||||
overflow-wrap: break-word;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
>>> .el-form-item__content {
|
||||
::v-deep .el-form-item__content {
|
||||
line-height: 30px;
|
||||
|
||||
pre {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import i18n from '@/i18n/i18n'
|
||||
import { ChoicesFormatter } from '@/components/Table/TableFormatters'
|
||||
import { openTaskPage } from '@/utils/jms'
|
||||
|
||||
export const connectivityMeta = {
|
||||
label: i18n.t('assets.Connectivity'),
|
||||
formatter: ChoicesFormatter,
|
||||
formatterArgs: {
|
||||
faChoices: {
|
||||
@@ -22,5 +21,276 @@ export const connectivityMeta = {
|
||||
}
|
||||
}
|
||||
},
|
||||
width: '100px'
|
||||
width: '130px'
|
||||
}
|
||||
|
||||
export const accountOtherActions = (vm) => [
|
||||
{
|
||||
name: 'View',
|
||||
title: vm.$t('View'),
|
||||
can: vm.$hasPerm('accounts.view_accountsecret'),
|
||||
type: 'primary',
|
||||
order: 1,
|
||||
callback: ({ row }) => {
|
||||
// debugger
|
||||
vm.secretUrl = `/api/v1/accounts/account-secrets/${row.id}/`
|
||||
vm.account = row
|
||||
vm.showViewSecretDialog = false
|
||||
setTimeout(() => {
|
||||
vm.showViewSecretDialog = true
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Update',
|
||||
title: vm.$t('Edit'),
|
||||
can: vm.$hasPerm('accounts.change_account') && !vm.$store.getters.currentOrgIsRoot,
|
||||
callback: ({ row }) => {
|
||||
const data = {
|
||||
...vm.asset,
|
||||
...row.asset
|
||||
}
|
||||
vm.account = row
|
||||
vm.iAsset = data
|
||||
vm.showAddDialog = false
|
||||
vm.accountCreateUpdateTitle = vm.$t('UpdateAccount')
|
||||
setTimeout(() => {
|
||||
vm.showAddDialog = true
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'UpdateSecret',
|
||||
title: vm.$t('EditSecret'),
|
||||
can: vm.$hasPerm('accounts.change_account') && !vm.$store.getters.currentOrgIsRoot,
|
||||
callback: ({ row }) => {
|
||||
const data = {
|
||||
...vm.asset,
|
||||
...row.asset
|
||||
}
|
||||
vm.account = row
|
||||
vm.iAsset = data
|
||||
vm.showUpdateSecretDialog = false
|
||||
vm.accountCreateUpdateTitle = vm.$t('UpdateAccount')
|
||||
setTimeout(() => {
|
||||
vm.showUpdateSecretDialog = true
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Clone',
|
||||
title: vm.$t('Duplicate'),
|
||||
can: vm.$hasPerm('accounts.add_account') && !vm.$store.getters.currentOrgIsRoot,
|
||||
callback: ({ row }) => {
|
||||
vm.account = {
|
||||
name: `${row.name} - ${vm.$t('Duplicate').toLowerCase()}`,
|
||||
username: `${row.username} - ${vm.$t('Duplicate').toLowerCase()}`,
|
||||
payload: 'pam_account_clone'
|
||||
}
|
||||
vm.iAsset = vm.asset
|
||||
|
||||
vm.showAddDialog = false
|
||||
setTimeout(() => {
|
||||
vm.showAddDialog = true
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Test',
|
||||
title: vm.$t('VerifySecret'),
|
||||
divided: true,
|
||||
can: ({ row }) =>
|
||||
!vm.$store.getters.currentOrgIsRoot &&
|
||||
vm.$hasPerm('accounts.verify_account') &&
|
||||
row.asset['auto_config'].ansible_enabled &&
|
||||
row.asset['auto_config'].ping_enabled,
|
||||
callback: ({ row }) => {
|
||||
vm.$axios.post(
|
||||
`/api/v1/accounts/accounts/tasks/`,
|
||||
{ action: 'verify', accounts: [row.id] }
|
||||
).then(res => {
|
||||
openTaskPage(res['task'])
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'ClearSecret',
|
||||
title: vm.$t('ClearSecret'),
|
||||
can: vm.$hasPerm('accounts.change_account'),
|
||||
type: 'primary',
|
||||
callback: ({ row }) => {
|
||||
vm.$axios.patch(
|
||||
`/api/v1/accounts/accounts/clear-secret/`,
|
||||
{ account_ids: [row.id] }
|
||||
).then(() => {
|
||||
vm.$message.success(vm.$tc('ClearSuccessMsg'))
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'SecretHistory',
|
||||
title: vm.$t('HistoryPassword'),
|
||||
can: () => vm.$hasPerm('accounts.view_accountsecret'),
|
||||
type: 'primary',
|
||||
callback: ({ row }) => {
|
||||
vm.account = row
|
||||
vm.currentAccountColumn = row
|
||||
vm.showViewSecretDialog = false
|
||||
vm.secretUrl = `/api/v1/accounts/account-secrets/${row.id}/`
|
||||
setTimeout(() => {
|
||||
vm.showViewSecretDialog = true
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'CopyToOther',
|
||||
title: vm.$t('CopyToAsset'),
|
||||
type: 'primary',
|
||||
divided: true,
|
||||
callback: ({ row }) => {
|
||||
vm.accountCreateUpdateTitle = vm.$t('CopyToOther')
|
||||
vm.$route.query.flag = 'copy'
|
||||
vm.iAsset = vm.asset
|
||||
vm.account = row
|
||||
vm.showAddDialog = true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'MoveToOther',
|
||||
title: vm.$t('MoveToAsset'),
|
||||
type: 'primary',
|
||||
callback: ({ row }) => {
|
||||
vm.accountCreateUpdateTitle = vm.$t('MoveToOther')
|
||||
vm.$route.query.flag = 'move'
|
||||
vm.iAsset = vm.asset
|
||||
vm.account = row
|
||||
vm.showAddDialog = true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export const accountQuickFilters = (vm) => [
|
||||
{
|
||||
label: vm.$t('Recent (7 days)'),
|
||||
options: [
|
||||
{
|
||||
label: vm.$t('RecentlyDiscovered'),
|
||||
filter: {
|
||||
latest_discovery: '1'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('RecentlyLoggedIn'),
|
||||
filter: {
|
||||
latest_accessed: '1'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('RecentlyModified'),
|
||||
filter: {
|
||||
latest_updated: '1'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('RecentlyChangedPassword'),
|
||||
filter: {
|
||||
latest_secret_changed: '1'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('RecentPasswordChangeFailed'),
|
||||
filter: {
|
||||
latest_secret_change_failed: '1'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: vm.$t('RiskyAccount'),
|
||||
options: [
|
||||
{
|
||||
label: vm.$t('NoLoginLongTime'),
|
||||
filter: {
|
||||
risk: 'long_time_no_login'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('UnmanagedAccount'),
|
||||
filter: {
|
||||
risk: 'new_found'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('WeakPassword'),
|
||||
filter: {
|
||||
risk: 'weak_password'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('EmptyPassword'),
|
||||
filter: {
|
||||
has_secret: 'false'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('LongTimePassword'),
|
||||
filter: {
|
||||
long_time_no_change_secret: 'true'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('LongTimeNoVerify'),
|
||||
filter: {
|
||||
long_time_no_verify: 'true'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: vm.$t('AccountType'),
|
||||
options: [
|
||||
{
|
||||
label: vm.$t('All'),
|
||||
filter: {
|
||||
category: ''
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('Host'),
|
||||
filter: {
|
||||
category: 'host'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('Database'),
|
||||
filter: {
|
||||
category: 'database'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('Cloud'),
|
||||
filter: {
|
||||
category: 'cloud'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('Device'),
|
||||
filter: {
|
||||
category: 'device'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Web',
|
||||
filter: {
|
||||
category: 'web'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: vm.$t('Other'),
|
||||
filter: {
|
||||
category: 'custom'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<el-button :disabled="disabled" :type="type" size="small" @click="addObjects">{{ $t('common.Add') }}</el-button>
|
||||
<el-button :disabled="disabled" :type="type" size="small" @click="addObjects">{{ $t('Add') }}</el-button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<Dialog
|
||||
:close-on-click-modal="false"
|
||||
:title="$tc('assets.Assets')"
|
||||
:title="$tc('Assets')"
|
||||
custom-class="asset-select-dialog"
|
||||
top="2vh"
|
||||
v-bind="$attrs"
|
||||
@@ -15,12 +15,15 @@
|
||||
ref="ListPage"
|
||||
:header-actions="headerActions"
|
||||
:node-url="baseNodeUrl"
|
||||
:sync-select-to-url="false"
|
||||
:table-config="tableConfig"
|
||||
:tree-setting="iTreeSetting"
|
||||
:tree-url="`${baseNodeUrl}children/tree/`"
|
||||
:url="baseUrl"
|
||||
:tree-setting="treeSetting"
|
||||
class="tree-table"
|
||||
v-bind="$attrs"
|
||||
@loaded="handleTableLoaded"
|
||||
v-on="$listeners"
|
||||
/>
|
||||
</Dialog>
|
||||
</template>
|
||||
@@ -63,6 +66,7 @@ export default {
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
isLoaded: false,
|
||||
dialogVisible: false,
|
||||
rowSelected: _.cloneDeep(this.value) || [],
|
||||
rowsAdd: [],
|
||||
@@ -73,17 +77,17 @@ export default {
|
||||
columns: [
|
||||
{
|
||||
prop: 'name',
|
||||
label: this.$t('assets.Name'),
|
||||
label: this.$t('Name'),
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
prop: 'address',
|
||||
label: this.$t('assets.ipDomain'),
|
||||
label: this.$t('IpDomain'),
|
||||
sortable: 'custom'
|
||||
},
|
||||
{
|
||||
prop: 'platform',
|
||||
label: this.$t('assets.Platform'),
|
||||
label: this.$t('Platform'),
|
||||
sortable: true,
|
||||
formatter: function(row) {
|
||||
return row.platform.name
|
||||
@@ -117,9 +121,17 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iTreeSetting() {
|
||||
return { ...this.treeSetting, selectSyncToRoute: false }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTableLoaded() {
|
||||
this.isLoaded = true
|
||||
},
|
||||
handleClose() {
|
||||
this.$eventBus.$emit('treeComponentKey')
|
||||
this.$refs.ListPage.$refs.TreeList.componentKey += 1
|
||||
},
|
||||
handleConfirm() {
|
||||
this.$emit('confirm', this.rowSelected, this.rowsAdd)
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
<script>
|
||||
import Select2 from '@/components/Form/FormFields/Select2.vue'
|
||||
import AssetSelectDialog from './dialog.vue'
|
||||
import { b } from 'css-color-function/lib/adjusters'
|
||||
|
||||
export default {
|
||||
componentName: 'AssetSelect',
|
||||
@@ -38,6 +37,10 @@ export default {
|
||||
type: String,
|
||||
default: '/api/v1/assets/assets/'
|
||||
},
|
||||
defaultPageSize: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
baseNodeUrl: {
|
||||
type: String,
|
||||
default: '/api/v1/assets/nodes/'
|
||||
@@ -71,6 +74,7 @@ export default {
|
||||
value: iValue,
|
||||
multiple: true,
|
||||
clearable: true,
|
||||
defaultPageSize: this.defaultPageSize,
|
||||
ajax: {
|
||||
url: this.baseUrl,
|
||||
transformOption: (item) => {
|
||||
@@ -81,7 +85,6 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
b,
|
||||
handleFocus() {
|
||||
this.$refs.select2.selectRef.blur()
|
||||
this.dialogVisible = true
|
||||
@@ -136,16 +139,22 @@ export default {
|
||||
|
||||
.tree-table {
|
||||
.left {
|
||||
padding: 5px;
|
||||
padding: 5px 0;
|
||||
|
||||
.ztree {
|
||||
min-height: 500px;
|
||||
height: inherit !important;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
.transition-box {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mini {
|
||||
padding-top: 8px;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.transition-box {
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
<TreeTable
|
||||
ref="TreeList"
|
||||
:active-menu.sync="treeTableConfig.activeMenu"
|
||||
:component="treeComponent"
|
||||
:table-config="tableConfig"
|
||||
:tree-tab-config="treeTableConfig"
|
||||
component="TabTree"
|
||||
:tree-width="treeWidth"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
@@ -31,6 +32,10 @@ export default {
|
||||
type: String,
|
||||
default: '/api/v1/assets/assets/'
|
||||
},
|
||||
typeUrl: {
|
||||
type: String,
|
||||
default: '/api/v1/assets/nodes/category/tree/'
|
||||
},
|
||||
nodeUrl: {
|
||||
type: String,
|
||||
default: '/api/v1/assets/nodes/'
|
||||
@@ -63,12 +68,14 @@ export default {
|
||||
const vm = this
|
||||
|
||||
return {
|
||||
treeComponent: 'TabTree',
|
||||
treeTabConfig: {
|
||||
activeMenu: 'CustomTree',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('assets.AssetTree'),
|
||||
title: this.$t('AssetTree'),
|
||||
name: 'CustomTree',
|
||||
icon: 'fa-tree',
|
||||
treeSetting: {
|
||||
showAssets,
|
||||
showMenu: false,
|
||||
@@ -94,16 +101,17 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.BuiltinTree'),
|
||||
title: this.$t('TypeTree'),
|
||||
icon: 'fa-list-ul',
|
||||
name: 'BuiltinTree',
|
||||
treeSetting: {
|
||||
showRefresh: true,
|
||||
showAssets: false,
|
||||
showSearch: false,
|
||||
customTreeHeaderName: this.$t('assets.BuiltinTree'),
|
||||
url: '/api/v1/assets/nodes/category/tree/',
|
||||
customTreeHeaderName: this.$t('TypeTree'),
|
||||
url: this.typeUrl,
|
||||
nodeUrl: this.treeSetting?.nodeUrl || this.nodeUrl,
|
||||
treeUrl: `/api/v1/assets/nodes/category/tree/?assets=${showAssets ? '1' : '0'}&count_resource=${this.treeSetting.countResource || 'asset'}`,
|
||||
treeUrl: `${this.typeUrl}?assets=${showAssets ? '1' : '0'}&count_resource=${this.treeSetting.countResource || 'asset'}`,
|
||||
callback: {
|
||||
onSelected: (event, treeNode) => this.getAssetsUrl(treeNode)
|
||||
}
|
||||
@@ -114,6 +122,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
treeWidth() {
|
||||
return '23.6%'
|
||||
},
|
||||
treeTableConfig() {
|
||||
if (this.treeSetting.notShowBuiltinTree) {
|
||||
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
||||
@@ -131,6 +142,9 @@ export default {
|
||||
treeSetting.showDelete = this.$hasPerm('assets.delete_node')
|
||||
},
|
||||
methods: {
|
||||
reloadTable() {
|
||||
this.$refs.TreeList.reloadTable()
|
||||
},
|
||||
setTreeUrlQuery() {
|
||||
let str = ''
|
||||
for (const key in this.treeUrlQuery) {
|
||||
@@ -150,33 +164,42 @@ export default {
|
||||
$('#m_show_asset_only_current_node').css('color', '#606266')
|
||||
}
|
||||
},
|
||||
|
||||
getAssetsUrl(treeNode) {
|
||||
let url = this.treeSetting?.url || this.url
|
||||
|
||||
const setParam = (param, value, delay) => {
|
||||
setTimeout(() => {
|
||||
url = setUrlParam(url, param, value)
|
||||
})
|
||||
}
|
||||
|
||||
if (treeNode.meta.type === 'node') {
|
||||
const nodeId = treeNode.meta.data.id
|
||||
url = setUrlParam(url, 'node_id', nodeId)
|
||||
url = setUrlParam(url, 'asset_id', '')
|
||||
setParam('node_id', nodeId)
|
||||
setParam('asset_id', '')
|
||||
} else if (treeNode.meta.type === 'asset') {
|
||||
const assetId = treeNode.meta.data?.id || treeNode.id
|
||||
url = setUrlParam(url, 'node_id', '')
|
||||
url = setUrlParam(url, 'asset_id', assetId)
|
||||
setParam('node_id', '')
|
||||
setParam('asset_id', assetId)
|
||||
} else if (treeNode.meta.type === 'category') {
|
||||
url = setUrlParam(url, 'category', treeNode.meta.category)
|
||||
setParam('category', treeNode.meta.category)
|
||||
} else if (treeNode.meta.type === 'type') {
|
||||
url = setUrlParam(url, 'category', treeNode.meta.category)
|
||||
url = setUrlParam(url, 'type', treeNode.meta._type)
|
||||
setParam('category', treeNode.meta.category)
|
||||
setParam('type', treeNode.meta._type)
|
||||
} else if (treeNode.meta.type === 'platform') {
|
||||
url = setUrlParam(url, 'platform', treeNode.id)
|
||||
setParam('platform', treeNode.id)
|
||||
}
|
||||
setTimeout(() => {
|
||||
const query = this.setTreeUrlQuery()
|
||||
url = query ? `${url}&${query}` : url
|
||||
this.$set(this.tableConfig, 'url', url)
|
||||
})
|
||||
|
||||
if (this.treeSetting.selectSyncToRoute !== false) {
|
||||
setRouterQuery(this, url)
|
||||
}
|
||||
const query = this.setTreeUrlQuery()
|
||||
url = query ? `${url}&${query}` : url
|
||||
this.$set(this.tableConfig, 'url', url)
|
||||
setRouterQuery(this, url)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
type="primary"
|
||||
@click="onOpenDialog"
|
||||
>
|
||||
{{ $tc('common.Setting') }}
|
||||
{{ $tc('Setting') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<Dialog
|
||||
@@ -50,7 +50,7 @@ export default {
|
||||
title: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return this.$t('assets.PushParams')
|
||||
return this.$t('PushParams')
|
||||
}
|
||||
},
|
||||
assets: {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
<ListTable ref="ListTable" :header-actions="headerActions" :table-config="tableConfig" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ListTable from '@/components/Table/ListTable/index.vue'
|
||||
import { DrawerListTable as ListTable } from '@/components'
|
||||
|
||||
export default {
|
||||
name: 'BlockedIPList',
|
||||
@@ -27,7 +27,7 @@ export default {
|
||||
],
|
||||
columnsMeta: {
|
||||
ip: {
|
||||
label: this.$t('assets.ip')
|
||||
label: this.$t('IP')
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
@@ -37,7 +37,7 @@ export default {
|
||||
extraActions: [
|
||||
{
|
||||
name: 'UnlockIP',
|
||||
title: this.$t('setting.Unblock'),
|
||||
title: this.$t('Unblock'),
|
||||
can: this.$hasPerm('settings.change_security'),
|
||||
type: 'primary',
|
||||
callback: ({ row }) => {
|
||||
@@ -45,7 +45,7 @@ export default {
|
||||
'/api/v1/settings/security/unlock-ip/',
|
||||
{ ips: [row.ip] }
|
||||
).then(() => {
|
||||
vm.$message.success(this.$tc('common.UnlockSuccessMsg'))
|
||||
vm.$message.success(this.$tc('UnlockSuccessMsg'))
|
||||
vm.$refs.ListTable.reloadTable()
|
||||
})
|
||||
}
|
||||
@@ -68,7 +68,7 @@ export default {
|
||||
extraMoreActions: [
|
||||
{
|
||||
name: 'UnlockSelected',
|
||||
title: this.$t('setting.BulkUnblock'),
|
||||
title: this.$t('UnblockSelected'),
|
||||
type: 'primary',
|
||||
can: ({ selectedRows }) => {
|
||||
return selectedRows.length > 0
|
||||
@@ -77,10 +77,12 @@ export default {
|
||||
vm.$axios.post(
|
||||
'/api/v1/settings/security/unlock-ip/',
|
||||
{
|
||||
ips: selectedRows.map(v => { return v.ip })
|
||||
ips: selectedRows.map(v => {
|
||||
return v.ip
|
||||
})
|
||||
}
|
||||
).then(res => {
|
||||
vm.$message.success(vm.$tc('common.UnlockSuccessMsg'))
|
||||
vm.$message.success(vm.$tc('UnlockSuccessMsg'))
|
||||
vm.$refs.ListTable.reloadTable()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
type="primary"
|
||||
@click="onOpenDialog"
|
||||
>
|
||||
{{ $tc('common.View') }}
|
||||
<span>({{ $tc('setting.LockedIP', ipCounts ) }})</span>
|
||||
{{ $tc('View') }}
|
||||
<span>({{ $tc('LockedIP', ipCounts ) }})</span>
|
||||
</el-button>
|
||||
</div>
|
||||
<Dialog
|
||||
:visible.sync="visible"
|
||||
:title="title"
|
||||
width="40%"
|
||||
:destroy-on-close="true"
|
||||
:show-cancel="false"
|
||||
:show-confirm="false"
|
||||
:destroy-on-close="true"
|
||||
:title="title"
|
||||
:visible.sync="visible"
|
||||
v-bind="$attrs"
|
||||
width="40%"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<BlockedIPList />
|
||||
@@ -43,7 +43,7 @@ export default {
|
||||
title: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return this.$t('setting.BlockedIPS')
|
||||
return this.$t('BlockedIPS')
|
||||
}
|
||||
},
|
||||
url: {
|
||||
|
||||
@@ -11,16 +11,16 @@
|
||||
v-on="$listeners"
|
||||
>
|
||||
<el-form :model="secretInfo" class="password-form" label-position="right" label-width="100px">
|
||||
<el-form-item :label="$tc('accounts.AccountChangeSecret.OldSecret')">
|
||||
<ShowKeyCopyFormatter
|
||||
<el-form-item :label="$tc('OldSecret')">
|
||||
<SecretViewerFormatter
|
||||
:cell-value="secretInfo.old_secret"
|
||||
:col="{ formatterArgs: {
|
||||
name: 'old_secret'
|
||||
}}"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$tc('accounts.AccountChangeSecret.NewSecret')">
|
||||
<ShowKeyCopyFormatter
|
||||
<el-form-item :label="$tc('NewSecret')">
|
||||
<SecretViewerFormatter
|
||||
:cell-value="secretInfo.new_secret"
|
||||
:col="{ formatterArgs: {
|
||||
name: 'new_secret'
|
||||
@@ -34,13 +34,13 @@
|
||||
|
||||
<script>
|
||||
import Dialog from '@/components/Dialog/index.vue'
|
||||
import { ShowKeyCopyFormatter } from '@/components/Table/TableFormatters'
|
||||
import { SecretViewerFormatter } from '@/components/Table/TableFormatters'
|
||||
|
||||
export default {
|
||||
name: 'RecordViewSecret',
|
||||
components: {
|
||||
Dialog,
|
||||
ShowKeyCopyFormatter
|
||||
SecretViewerFormatter
|
||||
},
|
||||
props: {
|
||||
visible: {
|
||||
@@ -54,7 +54,7 @@ export default {
|
||||
title: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return this.$tc('common.ViewSecret')
|
||||
return this.$tc('ViewSecret')
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -65,8 +65,7 @@ export default {
|
||||
mfaDialogVisible: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
this.showSecretDialog()
|
||||
},
|
||||
@@ -89,7 +88,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item-textarea >>> .el-textarea__inner {
|
||||
.item-textarea ::v-deep .el-textarea__inner {
|
||||
height: 110px;
|
||||
}
|
||||
|
||||
@@ -102,12 +101,12 @@ export default {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
>>> .el-form-item__label {
|
||||
::v-deep .el-form-item__label {
|
||||
padding-right: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
>>> .el-form-item__content {
|
||||
::v-deep .el-form-item__content {
|
||||
line-height: 30px;
|
||||
|
||||
pre {
|
||||
|
||||
@@ -12,31 +12,31 @@
|
||||
<el-input
|
||||
v-model="inputValue"
|
||||
:disabled="isLoading"
|
||||
:placeholder="$tc('common.InputMessage')"
|
||||
:placeholder="$tc('InputMessage')"
|
||||
:rows="expanded ? 3 :2"
|
||||
type="textarea"
|
||||
@compositionend="isIM = false"
|
||||
@compositionstart="isIM = true"
|
||||
@keypress.native="onKeyEnter"
|
||||
/>
|
||||
<div class="input-action">
|
||||
<span class="right">
|
||||
<i :class="{'active': inputValue }" class="fa fa-send" @click="onSendHandle" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import Select2 from '../../../../Form/FormFields/Select2.vue'
|
||||
import { useChat } from '../../useChat.js'
|
||||
import Select2 from '../../../../Form/FormFields/Select2.vue'
|
||||
|
||||
const { setLoading } = useChat()
|
||||
|
||||
export default {
|
||||
components: { Select2 },
|
||||
props: {
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -46,7 +46,7 @@ export default {
|
||||
url: '/api/v1/settings/chatai-prompts/',
|
||||
value: '',
|
||||
multiple: false,
|
||||
placeholder: this.$t('common.Prompt'),
|
||||
placeholder: this.$t('Prompt'),
|
||||
ajax: {
|
||||
transformOption: (item) => {
|
||||
return { label: item.name, value: item.content }
|
||||
@@ -91,11 +91,14 @@ export default {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
.chat-action {
|
||||
width: 100%;
|
||||
margin: 6px 0;
|
||||
&>>> .el-select {
|
||||
|
||||
&::v-deep .el-select {
|
||||
width: 50%;
|
||||
|
||||
.el-input__inner {
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
@@ -104,60 +107,47 @@ export default {
|
||||
background-color: #f7f7f8;
|
||||
font-size: 13px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
|
||||
&:hover {
|
||||
background-color: #ededed;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__icon {
|
||||
line-height: 0px;
|
||||
line-height: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-input {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid #DCDFE6;
|
||||
border-radius: 12px;
|
||||
&:has(.el-textarea__inner:focus) {
|
||||
border: 1px solid var(--color-primary);
|
||||
}
|
||||
&>>> .el-textarea {
|
||||
|
||||
&::v-deep .el-textarea {
|
||||
height: 100%;
|
||||
|
||||
.el-textarea__inner {
|
||||
height: 100%;
|
||||
padding: 8px 10px;
|
||||
border: none;
|
||||
border-top-left-radius: 12px;
|
||||
border-top-right-radius: 12px;
|
||||
resize: none;
|
||||
border-radius: 5px;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-textarea.is-disabled + .input-action {
|
||||
background-color: #F5F7FA;
|
||||
cursor: no-drop;
|
||||
|
||||
i {
|
||||
cursor: no-drop;
|
||||
}
|
||||
}
|
||||
.input-action {
|
||||
overflow: hidden;
|
||||
padding: 0 16px 15px;
|
||||
border-bottom-left-radius: 12px;
|
||||
border-bottom-right-radius: 12px;
|
||||
.right {
|
||||
float: right;
|
||||
.active {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
i {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,42 +1,74 @@
|
||||
<template>
|
||||
<div :class="{'user-role': isUserRole}" class="chat-item">
|
||||
<div class="avatar">
|
||||
<el-avatar :src="isUserRole ? userUrl : chatUrl" class="header-avatar" />
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="operational">
|
||||
<span class="date">
|
||||
{{ $moment(item.message.create_time).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</span>
|
||||
<div :class="{ 'user-role': isUserRole }" class="chat-item">
|
||||
<div class="chart-item-container">
|
||||
<div class="avatar">
|
||||
<el-avatar
|
||||
:src="isUserRole ? userUrl : chatUrl"
|
||||
class="header-avatar"
|
||||
/>
|
||||
</div>
|
||||
<div class="message">
|
||||
<div class="message-content">
|
||||
<span v-if="isSystemError" class="error">
|
||||
{{ item.message.content }}
|
||||
</span>
|
||||
<span v-else class="chat-text">
|
||||
<MessageText :message="item.message" />
|
||||
</span>
|
||||
<div class="content">
|
||||
<div class="operational">
|
||||
<div v-if="!item.message.is_reasoning" class="date">
|
||||
{{
|
||||
$moment(item.message.create_time).format("YYYY-MM-DD HH:mm:ss")
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div v-else class="thinking-time">{{ $i18n.t('DeeplyThoughtAbout') }}</div>
|
||||
</div>
|
||||
<div class="action">
|
||||
<el-tooltip
|
||||
v-if="isSystemError && isLoading"
|
||||
:content="$tc('common.Reconnect')"
|
||||
effect="dark"
|
||||
placement="top"
|
||||
>
|
||||
<svg-icon icon-class="refresh" @click="onRefresh" />
|
||||
</el-tooltip>
|
||||
<el-dropdown v-else size="small" @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="fa fa-ellipsis-v" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-for="i in dropdownOptions" :key="i.action" :command="i.action">
|
||||
{{ i.label }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<div :class="item.reasoning ? 'reasoning' : 'message'">
|
||||
<div class="message-content">
|
||||
<div v-if="!item.reasoning">
|
||||
<span v-if="isSystemError" class="error">
|
||||
{{ item.message.content }}
|
||||
</span>
|
||||
<span v-else class="chat-text">
|
||||
<MessageText :message="item.message" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-else class="thinking-wrapper">
|
||||
<div class="thinking-content">
|
||||
<!-- eslint-disable-next-line -->
|
||||
<div class="divider"></div>
|
||||
<p>
|
||||
<MessageText :message="item.reasoning" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="thinking-result">
|
||||
<span v-if="isServerError" class="error">
|
||||
{{ isServerError }}
|
||||
</span>
|
||||
<MessageText :message="item.result" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action">
|
||||
<el-tooltip
|
||||
v-if="isSystemError && isLoading"
|
||||
:content="$tc('Reconnect')"
|
||||
:open-delay="500"
|
||||
placement="top"
|
||||
>
|
||||
<svg-icon icon-class="refresh" @click="onRefresh" />
|
||||
</el-tooltip>
|
||||
<el-dropdown v-else size="small" @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="fa fa-ellipsis-v" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
v-for="i in dropdownOptions"
|
||||
:key="i.action"
|
||||
:command="i.action"
|
||||
>
|
||||
{{ i.label }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -45,7 +77,7 @@
|
||||
|
||||
<script>
|
||||
import MessageText from './MessageText.vue'
|
||||
import { mapState } from 'vuex'
|
||||
import { mapGetters, mapState } from 'vuex'
|
||||
import { copy } from '@/utils/common'
|
||||
import { useChat } from '../../useChat.js'
|
||||
import { reconnect } from '@/utils/socket'
|
||||
@@ -59,17 +91,17 @@ export default {
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
default: () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chatUrl: require('@/assets/img/chat.png'),
|
||||
userUrl: '/api/v1/settings/logo/',
|
||||
dropdownOptions: [
|
||||
{
|
||||
action: 'copy',
|
||||
label: this.$t('common.Copy')
|
||||
label: this.$t('Copy')
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -78,11 +110,26 @@ export default {
|
||||
...mapState({
|
||||
isLoading: state => state.chat.loading
|
||||
}),
|
||||
...mapGetters([
|
||||
'publicSettings'
|
||||
]),
|
||||
isUserRole() {
|
||||
return this.item.message?.role === 'user'
|
||||
},
|
||||
isSystemError() {
|
||||
return this.item.type === 'error' && this.item.message?.role === 'assistant'
|
||||
return (
|
||||
this.item.type === 'error' && this.item?.role === 'assistant'
|
||||
)
|
||||
},
|
||||
isServerError() {
|
||||
return (this.item.type === 'finish' && this.item.result.content === '')
|
||||
? this.$i18n.t('ServerBusyRetry')
|
||||
: ''
|
||||
},
|
||||
chatUrl() {
|
||||
return this.publicSettings.CHAT_AI_TYPE === 'gpt'
|
||||
? require('@/assets/img/chat.png')
|
||||
: require('@/assets/img/deepSeek.png')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -93,7 +140,7 @@ export default {
|
||||
},
|
||||
handleCommand(value) {
|
||||
if (value === 'copy') {
|
||||
copy(this.item.message.content)
|
||||
copy(this.item.result.content)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,82 +150,160 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.chat-item {
|
||||
display: flex;
|
||||
padding: 16px 14px 0;
|
||||
&:last-child {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.avatar {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-top: 2px;
|
||||
.header-avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
&>>> img {
|
||||
background-color: #e5e5e7;
|
||||
padding: 0.5rem;
|
||||
|
||||
.chart-item-container {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
|
||||
.avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-top: 2px;
|
||||
|
||||
.header-avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
|
||||
&::v-deep img {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.content {
|
||||
margin-left: 6px;
|
||||
overflow: hidden;
|
||||
.operational {
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
// gap: 0.5rem;
|
||||
overflow: hidden;
|
||||
.copy {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.message {
|
||||
display: -webkit-box;
|
||||
.message-content {
|
||||
flex: 1;
|
||||
padding: 6px 10px;
|
||||
border-radius: 2px 12px 12px;
|
||||
background-color: #f0f1f5;
|
||||
}
|
||||
.action {
|
||||
.svg-icon {
|
||||
transform: translateY(50%);
|
||||
margin-left: 3px;
|
||||
|
||||
.operational {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
|
||||
.date {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.thinking-time {
|
||||
width: 6rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 5px 10px;
|
||||
border-radius: 0.5rem;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.copy {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
.el-dropdown {
|
||||
height: 32px;
|
||||
line-height: 37px;
|
||||
font-size: 13px;
|
||||
.el-dropdown-link {
|
||||
i {
|
||||
padding: 4px 5px;
|
||||
font-size: 15px;
|
||||
color: #8d9091;
|
||||
&:hover {
|
||||
color: #7b8085
|
||||
}
|
||||
|
||||
.reasoning {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
align-items: flex-end;
|
||||
|
||||
.message-content .thinking-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
|
||||
.thinking-content {
|
||||
position: relative;
|
||||
color: #8b8b8b;
|
||||
|
||||
.divider {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
border-left: 2px solid #e5e5e5;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: unset;
|
||||
padding-left: 0.5rem;
|
||||
|
||||
::v-deep p {
|
||||
color: #8b8b8b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
|
||||
.message {
|
||||
display: -webkit-box;
|
||||
|
||||
.message-content {
|
||||
flex: 1;
|
||||
padding: 6px 10px;
|
||||
border-radius: 2px 12px 12px;
|
||||
background-color: #f0f1f5;
|
||||
}
|
||||
|
||||
.action {
|
||||
.svg-icon {
|
||||
transform: translateY(50%);
|
||||
margin-left: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.el-dropdown {
|
||||
height: 32px;
|
||||
line-height: 37px;
|
||||
font-size: 13px;
|
||||
|
||||
.el-dropdown-link {
|
||||
i {
|
||||
padding: 4px 5px;
|
||||
font-size: 15px;
|
||||
color: #8d9091;
|
||||
|
||||
&:hover {
|
||||
color: #7b8085;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-role {
|
||||
flex-direction: row-reverse;
|
||||
.content {
|
||||
margin-right: 10px;
|
||||
.operational {
|
||||
|
||||
&:last-child {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
&.user-role {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.chart-item-container {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.message {
|
||||
flex-direction: row-reverse;
|
||||
.message-content {
|
||||
background-color: var(--menu-hover);
|
||||
border-radius: 12px 2px 12px 12px;
|
||||
|
||||
.content {
|
||||
margin-right: 10px;
|
||||
|
||||
.operational {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.message {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.message-content {
|
||||
background-color: var(--menu-hover);
|
||||
border-radius: 12px 2px 12px 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<span />
|
||||
<span />
|
||||
</span>
|
||||
<div v-else class="inline-block markdown-body" v-html="text" />
|
||||
<div v-else v-sanitize="text" class="inline-block markdown-body" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -19,12 +19,12 @@ import hljs from 'highlight.js'
|
||||
import 'highlight.js/styles/atom-one-dark.css'
|
||||
import { copy } from '@/utils/common'
|
||||
|
||||
/* eslint-disable vue/no-v-html */
|
||||
export default {
|
||||
props: {
|
||||
message: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
default: () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -86,7 +86,8 @@ export default {
|
||||
if (this.$refs.textRef) {
|
||||
const copyBtn = this.$refs.textRef.querySelectorAll('.code-block-header__copy')
|
||||
copyBtn.forEach((btn) => {
|
||||
btn.removeEventListener('click', () => {})
|
||||
btn.removeEventListener('click', () => {
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -97,24 +98,31 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.markdown-body {
|
||||
font-size: 13px;
|
||||
&>>> p {
|
||||
|
||||
&::v-deep p {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
background: inherit;
|
||||
&>>> pre {
|
||||
|
||||
&::v-deep pre {
|
||||
padding: 0 0 6px 0;
|
||||
|
||||
.hljs.code-block-body {
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
&>>> .code-block-wrapper {
|
||||
|
||||
&::v-deep .code-block-wrapper {
|
||||
background: #1F2329;
|
||||
padding: 2px 6px;
|
||||
margin: 5px 0;
|
||||
|
||||
.code-block-body {
|
||||
padding: 5px 10px 0;
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
.code-block-header {
|
||||
margin-bottom: 4px;
|
||||
overflow: hidden;
|
||||
@@ -124,11 +132,13 @@ export default {
|
||||
.code-block-header__copy {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #6e747b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hljs.code-block-body.javascript {
|
||||
.hljs-comment {
|
||||
display: block;
|
||||
@@ -136,16 +146,20 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
>>> .link-style {
|
||||
|
||||
::v-deep .link-style {
|
||||
color: #487bf4;
|
||||
|
||||
&:hover {
|
||||
color: #275ee3;
|
||||
}
|
||||
}
|
||||
.loading-box{
|
||||
|
||||
.loading-box {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.loading-box span{
|
||||
|
||||
.loading-box span {
|
||||
display: inline-block;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
@@ -155,24 +169,29 @@ export default {
|
||||
background: #676A6c;
|
||||
animation: load 1.2s ease infinite;
|
||||
}
|
||||
.loading-box span:last-child{
|
||||
|
||||
.loading-box span:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
@keyframes load{
|
||||
0%{
|
||||
|
||||
@keyframes load {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100%{
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.loading-box span:nth-child(1){
|
||||
|
||||
.loading-box span:nth-child(1) {
|
||||
animation-delay: 0.23s;
|
||||
}
|
||||
.loading-box span:nth-child(2){
|
||||
|
||||
.loading-box span:nth-child(2) {
|
||||
animation-delay: 0.36s;
|
||||
}
|
||||
.loading-box span:nth-child(3){
|
||||
|
||||
.loading-box span:nth-child(3) {
|
||||
animation-delay: 0.49s;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
<div class="chat-content">
|
||||
<div id="scrollRef" class="chat-list">
|
||||
<div v-if="showIntroduction" class="introduction">
|
||||
<div v-for="(item, index) in introduction" :key="index" class="introduction-item" @click="sendIntroduction(item)">
|
||||
<div
|
||||
v-for="(item, index) in introduction"
|
||||
:key="index"
|
||||
class="introduction-item"
|
||||
@click="sendIntroduction(item)"
|
||||
>
|
||||
<div class="head">
|
||||
<i v-if="item.icon" :class="item.icon" />
|
||||
<span class="title">{{ item.title }}</span>
|
||||
@@ -22,8 +27,8 @@
|
||||
round
|
||||
size="small"
|
||||
@click="onStopHandle"
|
||||
>{{ $tc('common.Stop') }}</el-button>
|
||||
<ChatInput ref="chatInput" @send="onSendHandle" @select-prompt="onSelectPromptHandle" />
|
||||
>{{ $tc('Stop') }}</el-button>
|
||||
<ChatInput ref="chatInput" :expanded="expanded" @send="onSendHandle" @select-prompt="onSelectPromptHandle" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -52,23 +57,18 @@ export default {
|
||||
ChatMessage
|
||||
},
|
||||
props: {
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
socket: {},
|
||||
prompt: '',
|
||||
currentConversationId: '',
|
||||
conversationId: '',
|
||||
showIntroduction: false,
|
||||
introduction: [
|
||||
{
|
||||
title: this.$t('common.introduction.ConceptTitle'),
|
||||
content: this.$t('common.introduction.ConceptContent')
|
||||
},
|
||||
{
|
||||
title: this.$t('common.introduction.IdeaTitle'),
|
||||
content: this.$t('common.introduction.IdeaContent')
|
||||
}
|
||||
]
|
||||
introduction: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -86,23 +86,23 @@ export default {
|
||||
this.initChatMessage()
|
||||
},
|
||||
initWebSocket() {
|
||||
const { NODE_ENV, VUE_APP_KAEL_HOST } = process.env || {}
|
||||
const api = '/kael/chat/system/'
|
||||
const { NODE_ENV, VUE_APP_KOKO_HOST } = process.env || {}
|
||||
const api = '/koko/ws/chat/system/'
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'
|
||||
const path = `${protocol}://${window.location.host}${api}`
|
||||
const index = VUE_APP_KAEL_HOST?.indexOf('://')
|
||||
const localPath = protocol + VUE_APP_KAEL_HOST?.substring(index, VUE_APP_KAEL_HOST?.length) + api
|
||||
const index = VUE_APP_KOKO_HOST?.indexOf('://')
|
||||
const localPath = protocol + VUE_APP_KOKO_HOST?.substring(index, VUE_APP_KOKO_HOST?.length) + api
|
||||
const url = NODE_ENV === 'development' ? localPath : path
|
||||
createWebSocket(url, this.onWebSocketMessage)
|
||||
},
|
||||
initChatMessage() {
|
||||
this.prompt = ''
|
||||
this.showIntroduction = true
|
||||
this.currentConversationId = ''
|
||||
this.conversationId = ''
|
||||
this.$refs.chatInput.select.value = ''
|
||||
const chat = {
|
||||
message: {
|
||||
content: this.$t('common.ChatHello'),
|
||||
content: this.$t('ChatHello'),
|
||||
role: 'assistant',
|
||||
create_time: new Date()
|
||||
}
|
||||
@@ -119,11 +119,21 @@ export default {
|
||||
}
|
||||
},
|
||||
onChatMessage(data) {
|
||||
if (data.conversation_id) {
|
||||
if (data.id) {
|
||||
setLoading(true)
|
||||
removeLoadingMessageInChat()
|
||||
this.currentConversationId = data.conversation_id
|
||||
updateChaMessageContentById(data.message.id, data)
|
||||
this.conversationId = data.id
|
||||
|
||||
const newFragment = {
|
||||
message: { id: data.message.id, is_reasoning: data.message.is_reasoning },
|
||||
reasoning: { content: data.message.is_reasoning ? data.message.content : '' },
|
||||
result: { content: data.message.is_reasoning ? '' : data.message.content },
|
||||
role: data.message.role,
|
||||
type: data.message.type,
|
||||
create_time: data.message.create_time
|
||||
}
|
||||
|
||||
updateChaMessageContentById(data.message.id, newFragment)
|
||||
}
|
||||
if (data.message?.type === 'finish') {
|
||||
setLoading(false)
|
||||
@@ -132,20 +142,18 @@ export default {
|
||||
},
|
||||
onSystemMessage(data) {
|
||||
data.message = {
|
||||
content: data.system_message,
|
||||
content: data.data,
|
||||
role: 'assistant',
|
||||
create_time: new Date()
|
||||
}
|
||||
removeLoadingMessageInChat()
|
||||
addMessageToActiveChat(data)
|
||||
this.socketReadyStateSuccess = false
|
||||
setLoading(true)
|
||||
},
|
||||
onSendHandle(value) {
|
||||
this.showIntroduction = false
|
||||
this.socket = ws || {}
|
||||
if (ws?.readyState === 1) {
|
||||
this.socketReadyStateSuccess = true
|
||||
const chat = {
|
||||
message: {
|
||||
content: value,
|
||||
@@ -154,9 +162,9 @@ export default {
|
||||
}
|
||||
}
|
||||
const message = {
|
||||
content: value,
|
||||
data: value,
|
||||
prompt: this.prompt,
|
||||
conversation_id: this.currentConversationId || ''
|
||||
id: this.conversationId || ''
|
||||
}
|
||||
addChatMessageById(chat)
|
||||
onSend(message)
|
||||
@@ -164,20 +172,19 @@ export default {
|
||||
} else {
|
||||
const chat = {
|
||||
message: {
|
||||
content: this.$t('common.ConnectionDropped'),
|
||||
content: this.$t('ConnectionDropped'),
|
||||
role: 'assistant',
|
||||
create_time: new Date()
|
||||
},
|
||||
type: 'error'
|
||||
}
|
||||
addChatMessageById(chat)
|
||||
this.socketReadyStateSuccess = false
|
||||
setLoading(true)
|
||||
}
|
||||
},
|
||||
onSelectPromptHandle(value) {
|
||||
this.prompt = value
|
||||
this.currentConversationId = ''
|
||||
this.conversationId = ''
|
||||
this.showIntroduction = false
|
||||
this.onSendHandle(value)
|
||||
},
|
||||
@@ -186,13 +193,13 @@ export default {
|
||||
this.initChatMessage()
|
||||
},
|
||||
onStopHandle() {
|
||||
this.$axios.post(
|
||||
'/kael/interrupt_current_ask/',
|
||||
{ id: this.currentConversationId || '' }
|
||||
).finally(() => {
|
||||
removeLoadingMessageInChat()
|
||||
setLoading(false)
|
||||
})
|
||||
const message = {
|
||||
id: this.conversationId || '',
|
||||
interrupt: true
|
||||
}
|
||||
onSend(message)
|
||||
removeLoadingMessageInChat()
|
||||
setLoading(false)
|
||||
},
|
||||
sendIntroduction(item) {
|
||||
this.showIntroduction = false
|
||||
@@ -226,13 +233,16 @@ export default {
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.head {
|
||||
margin-bottom: 2px;
|
||||
|
||||
.title {
|
||||
font-weight: 500;
|
||||
color: #373739;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
display: inline-block;
|
||||
color: #a7a7ab;
|
||||
@@ -240,30 +250,35 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-list {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
padding: 0 15px 25px;
|
||||
overflow-y: auto;
|
||||
user-select: text;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-box {
|
||||
position: relative;
|
||||
height: 160px;
|
||||
//height: 60px;
|
||||
padding: 0 15px;
|
||||
margin-bottom: 15px;
|
||||
border-top: 1px solid #ececec;
|
||||
//border-top: 1px solid #ececec;
|
||||
}
|
||||
|
||||
.stop {
|
||||
position: absolute;
|
||||
top: -37px;
|
||||
left: 50%;
|
||||
z-index: 11;
|
||||
transform: translateX(-50%);
|
||||
>>> i {
|
||||
|
||||
::v-deep i {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="close-sidebar">
|
||||
<i v-if="hasClose" class="el-icon-close" @click="onClose" />
|
||||
<i v-if="hasClose" class="el-icon-download" @click="onClose" />
|
||||
</div>
|
||||
<div v-if="!expanded" class="close-sidebar">
|
||||
<i class="fa fa-expand" style="font-weight: 200" @click="$emit('expand')" />
|
||||
</div>
|
||||
<div v-if="expanded" class="close-sidebar">
|
||||
<i class="fa fa-compress" style="font-weight: 200" @click="$emit('compress')" />
|
||||
</div>
|
||||
<el-tabs v-model="active" :tab-position="'right'" @tab-click="handleClick">
|
||||
<el-tab-pane v-for="(item) in submenu" :key="item.name" :name="item.name">
|
||||
<span slot="label">
|
||||
<el-tooltip effect="dark" placement="left" :content="item.label">
|
||||
<svg-icon :icon-class="item.icon" />
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -29,18 +26,21 @@ export default {
|
||||
submenu: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
handleClick(tab, event) {
|
||||
this.$emit('tab-click', tab)
|
||||
},
|
||||
onClose() {
|
||||
this.$parent.onClose()
|
||||
this.$emit('close')
|
||||
},
|
||||
handleExpand() {
|
||||
this.$emit('expand-full')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,17 +51,23 @@ export default {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f0f1f5;
|
||||
|
||||
.close-sidebar {
|
||||
height: 48px;
|
||||
padding: 12px 0;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
|
||||
i {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
i, .svg {
|
||||
border-radius: 2px;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
background: var(--menu-hover);
|
||||
@@ -69,10 +75,16 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
>>> .el-tabs {
|
||||
|
||||
.el-icon-download {
|
||||
transform: rotate(-90deg)
|
||||
}
|
||||
|
||||
::v-deep .el-tabs {
|
||||
.el-tabs__item {
|
||||
padding: 0 13px;
|
||||
font-size: 15px;
|
||||
padding: 0 10px;
|
||||
font-size: 14px;
|
||||
|
||||
:hover {
|
||||
color: #7b8085;
|
||||
}
|
||||
|
||||
@@ -1,26 +1,44 @@
|
||||
<template>
|
||||
<div class="chat">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<div class="left">
|
||||
<img :src="robotUrl" alt="">
|
||||
<span class="title">{{ title }}</span>
|
||||
<DrawerPanel
|
||||
ref="drawer"
|
||||
:default-show-panel="!!defaultShowPanel"
|
||||
:expanded="expanded"
|
||||
:height="height"
|
||||
:icon="robotUrl"
|
||||
:modal="false"
|
||||
@toggle="onToggle"
|
||||
>
|
||||
<div class="chat">
|
||||
<div class="container">
|
||||
<div ref="header" class="header" @mousedown="handleMoveMouseDown" @mouseup="handleMouseMoveUp">
|
||||
<div class="left">
|
||||
<img :src="robotUrl" alt="">
|
||||
<span class="title">{{ title }}</span>
|
||||
</div>
|
||||
<span class="new" @click="onNewChat">
|
||||
<i class="el-icon-plus" />
|
||||
<span>{{ $tc('NewChat') }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<keep-alive>
|
||||
<component :is="active" ref="component" :expanded="expanded" />
|
||||
</keep-alive>
|
||||
</div>
|
||||
<span class="new" @click="onNewChat">
|
||||
<i class="el-icon-plus" />
|
||||
<span>{{ $tc('common.NewChat') }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<keep-alive>
|
||||
<component :is="active" ref="component" />
|
||||
</keep-alive>
|
||||
<div class="sidebar">
|
||||
<Sidebar
|
||||
:active.sync="active"
|
||||
:expanded="expanded"
|
||||
v-bind="$attrs"
|
||||
@close="onClose"
|
||||
@compress="compress"
|
||||
@expand="expandFull"
|
||||
v-on="$listeners"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar">
|
||||
<Sidebar v-bind="$attrs" :active.sync="active" :submenu="submenu" />
|
||||
</div>
|
||||
</div>
|
||||
</DrawerPanel>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -28,9 +46,11 @@ import Sidebar from './components/Sidebar/index.vue'
|
||||
import Chat from './components/ChitChat/index.vue'
|
||||
import { getInputFocus } from './useChat.js'
|
||||
import { ws } from '@/utils/socket'
|
||||
import DrawerPanel from '@/components/Apps/DrawerPanel/index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DrawerPanel,
|
||||
Chat,
|
||||
Sidebar
|
||||
},
|
||||
@@ -38,9 +58,13 @@ export default {
|
||||
title: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return this.$t('setting.ChatAI')
|
||||
return this.$t('ChatAI')
|
||||
}
|
||||
},
|
||||
defaultShowPanel: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
drawerPanelVisible: {
|
||||
type: Boolean,
|
||||
default: () => false
|
||||
@@ -49,29 +73,46 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
active: 'chat',
|
||||
robotUrl: require('../../../assets/img/robot-assistant.png'),
|
||||
submenu: [
|
||||
{
|
||||
name: 'chat',
|
||||
label: this.$t('common.Chat'),
|
||||
icon: 'chat'
|
||||
}
|
||||
]
|
||||
robotUrl: require('@/assets/img/robot-assistant.png'),
|
||||
height: '400px',
|
||||
expanded: false,
|
||||
clientOffset: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
drawerPanelVisible(value) {
|
||||
if (value && !ws) {
|
||||
this.initWebSocket()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.handlePostMessage()
|
||||
},
|
||||
methods: {
|
||||
handlePostMessage() {
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data === 'show-chat-panel') {
|
||||
this.$refs.drawer.show = true
|
||||
}
|
||||
})
|
||||
},
|
||||
handleMoveMouseDown(event) {
|
||||
this.$refs.drawer.handleHeaderMoveDown(event)
|
||||
},
|
||||
handleMouseMoveUp(event) {
|
||||
this.$refs.drawer.handleHeaderMoveUp(event)
|
||||
},
|
||||
initWebSocket() {
|
||||
this.$refs.component?.init()
|
||||
if (!ws) {
|
||||
this.$refs.component?.init()
|
||||
}
|
||||
},
|
||||
onClose() {
|
||||
this.$parent.show = false
|
||||
this.$refs.drawer.show = false
|
||||
},
|
||||
expandFull() {
|
||||
this.height = '100%'
|
||||
this.expanded = true
|
||||
},
|
||||
compress() {
|
||||
this.height = '400px'
|
||||
this.expanded = false
|
||||
},
|
||||
onNewChat() {
|
||||
this.active = 'chat'
|
||||
@@ -79,6 +120,12 @@ export default {
|
||||
this.$refs.component?.onNewChat()
|
||||
getInputFocus()
|
||||
})
|
||||
},
|
||||
onToggle(status) {
|
||||
this.initWebSocket()
|
||||
if (status) {
|
||||
getInputFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,12 +136,16 @@ export default {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: auto;
|
||||
|
||||
.container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.header {
|
||||
background: linear-gradient(90deg, #ebf1ff 24.34%, #e5fbf8 56.18%, #f2ebfe 90.18%);;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 48px;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div ref="drawer" :class="{show: show}" class="drawer">
|
||||
<div :style="{'background-color': modal ? 'rgba(0, 0, 0, .3)' : 'transparent'}" class="modal" />
|
||||
<div :style="{'width': width}" class="drawer-panel">
|
||||
<div v-show="!show" ref="dragBox" class="handle-button">
|
||||
<div v-if="modal" :style="{'background-color': modal ? 'rgba(0, 0, 0, .3)' : 'transparent'}" class="modal" />
|
||||
<div ref="panel" :style="{width: width, height: height }" class="drawer-panel">
|
||||
<div v-show="!show && !defaultShowPanel" ref="dragBox" class="handle-button">
|
||||
<i v-if="icon.startsWith('fa') || icon.startsWith('el')" :class="show ? 'el-icon-close': icon" />
|
||||
<img v-else :src="icon" alt="">
|
||||
</div>
|
||||
@@ -12,7 +12,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
@@ -26,6 +25,10 @@ export default {
|
||||
type: String,
|
||||
default: '440px'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '400px'
|
||||
},
|
||||
modal: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
@@ -33,11 +36,20 @@ export default {
|
||||
clickNotClose: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
defaultShowPanel: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false
|
||||
show: this.defaultShowPanel,
|
||||
clientOffset: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -45,7 +57,17 @@ export default {
|
||||
if (value && !this.clickNotClose) {
|
||||
this.addEventClick()
|
||||
}
|
||||
const event = value ? 'show-chat-panel' : 'close-chat-panel'
|
||||
window.parent.postMessage(event, '*')
|
||||
this.$emit('toggle', this.show)
|
||||
},
|
||||
expanded(value) {
|
||||
if (value) {
|
||||
this.$refs.panel.style.top = '0px'
|
||||
} else {
|
||||
this.$refs.panel.style.top = 'auto'
|
||||
this.$refs.panel.style.bottom = '2px'
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -55,49 +77,65 @@ export default {
|
||||
beforeDestroy() {
|
||||
const element = this.$refs.drawer
|
||||
element.remove()
|
||||
window.removeEventListener('click', this.closeSidebar)
|
||||
// window.removeEventListener('click', this.closeSidebar)
|
||||
},
|
||||
methods: {
|
||||
handleHeaderMoveUp(event) {
|
||||
this.handleMouseMoveUp(event)
|
||||
},
|
||||
handleHeaderMoveDown(event) {
|
||||
this.handleMoveMouseDown(event, true)
|
||||
},
|
||||
handleMoveMouseDown(event, isHeader = false) {
|
||||
const dragBox = this.$refs.dragBox
|
||||
const vm = this
|
||||
const rect = dragBox.getBoundingClientRect()
|
||||
const parentRect = dragBox.parentElement.getBoundingClientRect()
|
||||
const clientOffset = this.clientOffset
|
||||
clientOffset.clientX = event.clientX
|
||||
clientOffset.clientY = event.clientY
|
||||
|
||||
const handleOnMouseMove = _.debounce(function(event) {
|
||||
const diffY = rect.top - parentRect.top
|
||||
const maxY = window.innerHeight - parentRect.height
|
||||
let parentY = event.clientY - diffY
|
||||
// 这个是拖动的 header, 不是 bar
|
||||
if (isHeader) {
|
||||
parentY = event.clientY - rect.height / 2
|
||||
}
|
||||
if (parentY < 0) {
|
||||
parentY = 0
|
||||
} else if (parentY > maxY) {
|
||||
parentY = maxY
|
||||
}
|
||||
if (vm.$refs.panel) {
|
||||
vm.$refs.panel.style.top = parentY + 'px'
|
||||
}
|
||||
})
|
||||
|
||||
document.onmousemove = handleOnMouseMove
|
||||
document.onmouseup = function() {
|
||||
document.removeEventListener('mousemove', handleOnMouseMove)
|
||||
setTimeout(() => {
|
||||
document.onmousemove = null
|
||||
document.onmouseup = null
|
||||
}, 0)
|
||||
}
|
||||
},
|
||||
handleMouseMoveUp(event) {
|
||||
const clientOffset = this.clientOffset
|
||||
const clientX = event.clientX
|
||||
const clientY = event.clientY
|
||||
if (this.isDifferenceWithinThreshold(clientX, clientOffset.clientX) &&
|
||||
this.isDifferenceWithinThreshold(clientY, clientOffset.clientY)) {
|
||||
this.show = !this.show
|
||||
}
|
||||
},
|
||||
init() {
|
||||
this.$nextTick(() => {
|
||||
const dragBox = this.$refs.dragBox
|
||||
const clientOffset = {}
|
||||
dragBox.addEventListener('mousedown', (event) => {
|
||||
const offsetX = dragBox.getBoundingClientRect().left
|
||||
const offsetY = dragBox.getBoundingClientRect().top
|
||||
const innerX = event.clientX - offsetX
|
||||
const innerY = event.clientY - offsetY
|
||||
|
||||
clientOffset.clientX = event.clientX
|
||||
clientOffset.clientY = event.clientY
|
||||
document.onmousemove = function(event) {
|
||||
dragBox.style.left = event.clientX - innerX + 'px'
|
||||
dragBox.style.top = event.clientY - innerY + 'px'
|
||||
const dragDivTop = window.innerHeight - dragBox.getBoundingClientRect().height
|
||||
const dragDivLeft = window.innerWidth - dragBox.getBoundingClientRect().width
|
||||
dragBox.style.left = dragDivLeft + 'px'
|
||||
dragBox.style.left = '-48px'
|
||||
if (dragBox.getBoundingClientRect().top <= 0) {
|
||||
dragBox.style.top = '0px'
|
||||
}
|
||||
if (dragBox.getBoundingClientRect().top >= dragDivTop) {
|
||||
dragBox.style.top = dragDivTop + 'px'
|
||||
}
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
}
|
||||
document.onmouseup = function() {
|
||||
document.onmousemove = null
|
||||
document.onmouseup = null
|
||||
}
|
||||
}, false)
|
||||
dragBox.addEventListener('mouseup', (event) => {
|
||||
const clientX = event.clientX
|
||||
const clientY = event.clientY
|
||||
if (this.isDifferenceWithinThreshold(clientX, clientOffset.clientX) && this.isDifferenceWithinThreshold(clientY, clientOffset.clientY)) {
|
||||
this.show = !this.show
|
||||
}
|
||||
})
|
||||
dragBox.addEventListener('mousedown', this.handleMoveMouseDown, false)
|
||||
dragBox.addEventListener('mouseup', this.handleMouseMoveUp, false)
|
||||
})
|
||||
},
|
||||
isDifferenceWithinThreshold(num1, num2, threshold = 5) {
|
||||
@@ -105,13 +143,6 @@ export default {
|
||||
return difference <= threshold
|
||||
},
|
||||
addEventClick() {
|
||||
window.addEventListener('click', this.closeSidebar)
|
||||
},
|
||||
closeSidebar(evt) {
|
||||
const parent = evt.target.closest('.drawer-panel')
|
||||
if (!parent && evt.target.className === 'modal') {
|
||||
this.show = false
|
||||
}
|
||||
},
|
||||
insertToBody() {
|
||||
const element = this.$refs.drawer
|
||||
@@ -135,11 +166,10 @@ export default {
|
||||
|
||||
.drawer-panel {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 1px;
|
||||
right: -1px;
|
||||
width: 100%;
|
||||
min-width: 260px;
|
||||
height: 100vh;
|
||||
user-select: none;
|
||||
transition: transform .25s cubic-bezier(.7, .3, .1, 1);
|
||||
box-shadow: 0 0 8px 4px #00000014;
|
||||
@@ -187,23 +217,26 @@ export default {
|
||||
pointer-events: auto;
|
||||
color: #fff;
|
||||
background-color: #FFFFFF;
|
||||
opacity: 0.9;
|
||||
box-shadow: 0 0 8px 4px #00000014;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
left: -50px !important;
|
||||
left: -51px !important;
|
||||
width: 50px !important;
|
||||
transform: scale(1.06);
|
||||
transform: scale(1.01);
|
||||
}
|
||||
i {
|
||||
font-size: 20px;
|
||||
line-height: 45px;
|
||||
pointer-events: none;
|
||||
}
|
||||
img {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
transform: translateY(10%);
|
||||
margin-left: 3px;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
:destroy-on-close="true"
|
||||
:show-cancel="false"
|
||||
:show-confirm="false"
|
||||
:title="$tc('assets.TestGatewayTestConnection')"
|
||||
:title="$tc('TestGatewayTestConnection')"
|
||||
:visible.sync="iVisible"
|
||||
top="35vh"
|
||||
width="40%"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :md="4" :sm="24">
|
||||
<div style="line-height: 34px">{{ $t('assets.SSHPort') }}</div>
|
||||
<div style="line-height: 34px">{{ $t('SSHPort') }}</div>
|
||||
</el-col>
|
||||
<el-col :md="14" :sm="24">
|
||||
<el-input v-model="port" />
|
||||
<span class="help-tips help-block">{{ $t('assets.TestGatewayHelpMessage') }}</span>
|
||||
<span class="help-tips help-block">{{ $t('TestGatewayHelpMessage') }}</span>
|
||||
</el-col>
|
||||
<el-col :md="4" :sm="24">
|
||||
<el-button
|
||||
@@ -25,7 +25,7 @@
|
||||
type="primary"
|
||||
@click="dialogConfirm"
|
||||
>
|
||||
{{ this.$t('common.Confirm') }}
|
||||
{{ this.$t('Confirm') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -75,7 +75,7 @@ export default {
|
||||
methods: {
|
||||
dialogConfirm() {
|
||||
if (isNaN(this.port)) {
|
||||
return this.$message.error(this.$tc('common.TestPortErrorMsg'))
|
||||
return this.$message.error(this.$tc('TestPortErrorMsg'))
|
||||
}
|
||||
this.$axios.post(
|
||||
`/api/v1/assets/gateways/${this.cell}/test-connective/`,
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
<template>
|
||||
<TreeTable :header-actions="headerActions" :table-config="tableConfig" :tree-setting="treeSetting" />
|
||||
<AssetTreeTable
|
||||
ref="AssetTreeTable"
|
||||
:header-actions="headerActions"
|
||||
:table-config="tableConfig"
|
||||
:tree-setting="treeSetting"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script type="text/jsx">
|
||||
import TreeTable from '../../Table/TreeTable/index.vue'
|
||||
import { DetailFormatter } from '@/components/Table/TableFormatters'
|
||||
import { AccountInfoFormatter } from '@/components/Table/TableFormatters'
|
||||
import AssetTreeTable from '@/components/Apps/AssetTreeTable'
|
||||
import { AccountInfoFormatter, DetailFormatter } from '@/components/Table/TableFormatters'
|
||||
import { connectivityMeta } from '@/components/Apps/AccountListTable/const'
|
||||
|
||||
export default {
|
||||
name: 'GrantedAssets',
|
||||
components: {
|
||||
TreeTable
|
||||
AssetTreeTable
|
||||
},
|
||||
props: {
|
||||
treeUrl: {
|
||||
@@ -34,11 +38,29 @@ export default {
|
||||
vm.tableConfig.url = url
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
getShowUrl: {
|
||||
type: Function,
|
||||
default({ row, col }) {
|
||||
return this.tableUrl.replace('/assets/', `/assets/${row.id}/accounts/`)
|
||||
}
|
||||
},
|
||||
name: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
route: 'AssetDetail',
|
||||
can: true
|
||||
}
|
||||
})
|
||||
},
|
||||
comment: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -48,9 +70,11 @@ export default {
|
||||
showMenu: false,
|
||||
showRefresh: true,
|
||||
showAssets: false,
|
||||
showSearch: false,
|
||||
url: this.tableUrl,
|
||||
// ?assets=0不显示资产. =1显示资产
|
||||
treeUrl: this.treeUrl,
|
||||
notShowBuiltinTree: true,
|
||||
callback: {
|
||||
onSelected: (event, node) => vm.onSelected(node, vm),
|
||||
refresh: vm.refreshObjectAssetPermission
|
||||
@@ -63,24 +87,32 @@ export default {
|
||||
columnsExclude: ['spec_info'],
|
||||
columnsShow: {
|
||||
min: ['name', 'address', 'accounts'],
|
||||
default: ['name', 'address', 'platform', 'view_account', 'connectivity']
|
||||
default: ['name', 'address', 'platform', 'view_account', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatter: DetailFormatter,
|
||||
...this.name
|
||||
},
|
||||
labels: {
|
||||
formatterArgs: {
|
||||
route: 'AssetDetail'
|
||||
showEditBtn: false
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
has: false
|
||||
...this.actions
|
||||
},
|
||||
view_account: {
|
||||
label: this.$t('assets.Account'),
|
||||
label: this.$t('Accounts'),
|
||||
formatter: AccountInfoFormatter,
|
||||
width: '100px'
|
||||
},
|
||||
connectivity: connectivityMeta
|
||||
connectivity: connectivityMeta,
|
||||
comment: { ...this.comment }
|
||||
},
|
||||
tableAttrs: {
|
||||
rowClassName({ row }) {
|
||||
return !row.is_active ? 'row_disabled' : ''
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
@@ -103,4 +135,8 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.row_disabled, .row_disabled:hover, .row_disabled:hover > td {
|
||||
cursor: not-allowed;
|
||||
background-color: rgba(192, 196, 204, 0.28) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
<template>
|
||||
<el-row :gutter="24">
|
||||
<el-col :md="20" :sm="22">
|
||||
<ListTable v-bind="config" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<TwoCol>
|
||||
<ListTable v-bind="config" />
|
||||
</TwoCol>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ListTable from '@/components/Table/ListTable/index.vue'
|
||||
import { DrawerListTable as ListTable } from '@/components'
|
||||
import { toM2MJsonParams } from '@/utils/jms'
|
||||
import TwoCol from '@/layout/components/Page/TwoColPage.vue'
|
||||
|
||||
export default {
|
||||
name: 'AssetJsonTab',
|
||||
components: {
|
||||
TwoCol,
|
||||
ListTable
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
default: () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -32,12 +33,14 @@ export default {
|
||||
},
|
||||
tableConfig: {
|
||||
url: `/api/v1/assets/assets/?${key}=${value}`,
|
||||
columns: ['name', 'address', 'platform',
|
||||
'type', 'is_active'
|
||||
],
|
||||
columns: ['name', 'address', 'platform', 'type', 'is_active'],
|
||||
columnsShow: {
|
||||
min: ['name', 'address'],
|
||||
default: ['name', 'address', 'platform']
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
label: this.$t('assets.Asset'),
|
||||
label: this.$t('Asset'),
|
||||
formatter: (row) => {
|
||||
const to = {
|
||||
name: 'AssetDetail',
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
<template>
|
||||
<el-row :gutter="24">
|
||||
<el-col :md="20" :sm="22">
|
||||
<ListTable v-bind="config" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<TwoCol>
|
||||
<ListTable v-bind="config" />
|
||||
</TwoCol>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ListTable from '@/components/Table/ListTable/index.vue'
|
||||
import { DrawerListTable as ListTable } from '@/components'
|
||||
import { toM2MJsonParams } from '@/utils/jms'
|
||||
import TwoCol from '@/layout/components/Page/TwoColPage.vue'
|
||||
|
||||
export default {
|
||||
name: 'User',
|
||||
components: {
|
||||
TwoCol,
|
||||
ListTable
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
default: () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -33,12 +34,16 @@ export default {
|
||||
tableConfig: {
|
||||
url: `/api/v1/users/users/?${key}=${value}`,
|
||||
columns: [
|
||||
'name', 'username', 'groups', 'system_roles',
|
||||
'name', 'username', 'email', 'groups', 'system_roles',
|
||||
'org_roles', 'source', 'is_valid'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'username'],
|
||||
default: ['name', 'username', 'email']
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
label: this.$t('common.Name'),
|
||||
label: this.$t('Name'),
|
||||
formatter: (row) => {
|
||||
const to = {
|
||||
name: 'UserDetail',
|
||||
@@ -52,7 +57,7 @@ export default {
|
||||
}
|
||||
},
|
||||
system_roles: {
|
||||
label: this.$t('users.SystemRoles'),
|
||||
label: this.$t('SystemRoles'),
|
||||
formatter: (row) => {
|
||||
return row['system_roles'].map(item => item['display_name']).join(', ') || '-'
|
||||
},
|
||||
@@ -60,7 +65,7 @@ export default {
|
||||
columnKey: 'system_roles'
|
||||
},
|
||||
org_roles: {
|
||||
label: this.$t('users.OrgRoles'),
|
||||
label: this.$t('OrgRoles'),
|
||||
formatter: (row) => {
|
||||
return row['org_roles'].map(item => item['display_name']).join(', ') || '-'
|
||||
},
|
||||
|
||||
@@ -1,31 +1,29 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :md="12" :sm="24">
|
||||
<IBox :title="title" class="block" v-bind="$attrs">
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
v-for="(activity, index) in activities"
|
||||
:key="index"
|
||||
:size="activity.size"
|
||||
:timestamp="activity.timestamp"
|
||||
:type="activity.type"
|
||||
placement="bottom"
|
||||
<TwoCol>
|
||||
<IBox :title="title" class="block" v-bind="$attrs">
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
v-for="(activity, index) in activities"
|
||||
:key="index"
|
||||
:size="activity.size"
|
||||
:timestamp="activity.timestamp"
|
||||
:type="activity.type"
|
||||
placement="bottom"
|
||||
>
|
||||
{{ activity.content }}
|
||||
<el-link
|
||||
v-if="activity['detail_url']"
|
||||
type="primary"
|
||||
@click.native="onClick(activity)"
|
||||
>
|
||||
{{ activity.content }}
|
||||
<el-link
|
||||
v-if="activity['detail_url']"
|
||||
type="primary"
|
||||
@click.native="onClick(activity)"
|
||||
>
|
||||
{{ $tc('common.Detail') }}
|
||||
</el-link>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</IBox>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<DiffDetail ref="DetailDialog" :title="$tc('route.OperateLog')" />
|
||||
{{ $tc('Detail') }}
|
||||
</el-link>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</IBox>
|
||||
</TwoCol>
|
||||
<DiffDetail ref="DetailDialog" :title="$tc('OperateLog')" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -33,10 +31,13 @@
|
||||
import IBox from '@/components/IBox/index.vue'
|
||||
import DiffDetail from '@/components/Dialog/DiffDetail.vue'
|
||||
import { openTaskPage } from '@/utils/jms'
|
||||
import { toSafeLocalDateStr } from '@/utils/time'
|
||||
import TwoCol from '@/layout/components/Page/TwoColPage.vue'
|
||||
|
||||
export default {
|
||||
name: 'ResourceActivity',
|
||||
components: {
|
||||
TwoCol,
|
||||
IBox,
|
||||
DiffDetail
|
||||
},
|
||||
@@ -49,11 +50,11 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
activityUrl: `/api/v1/audits/activities/?resource_id=${this.object.id}`,
|
||||
title: `${this.$t('common.Activity')} - ${this.$t('common.Last30')}`,
|
||||
title: `${this.$t('Last30')}`,
|
||||
activities: [
|
||||
{
|
||||
content: this.$t('common.Now'),
|
||||
timestamp: this.$moment().format('YYYY-MM-DD HH:mm:ss'),
|
||||
content: this.$t('Now'),
|
||||
timestamp: toSafeLocalDateStr(this.$moment()),
|
||||
type: 'primary'
|
||||
}
|
||||
]
|
||||
@@ -65,9 +66,11 @@ export default {
|
||||
methods: {
|
||||
getActivities() {
|
||||
this.$axios.get(this.activityUrl).then(res => {
|
||||
for (const i in res) {
|
||||
this.activities.push(res[i])
|
||||
}
|
||||
const activities = res || []
|
||||
activities.forEach(activity => {
|
||||
activity.timestamp = toSafeLocalDateStr(activity.timestamp)
|
||||
this.activities.push(activity)
|
||||
})
|
||||
})
|
||||
},
|
||||
onClick(activity) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:visible.sync="visible"
|
||||
class="dialog-content"
|
||||
v-bind="$attrs"
|
||||
width="600px"
|
||||
width="740px"
|
||||
@confirm="visible = false"
|
||||
v-on="$listeners"
|
||||
>
|
||||
@@ -16,7 +16,7 @@
|
||||
<el-row :gutter="24" style="margin: 0 auto;">
|
||||
<el-col :md="24" :sm="24">
|
||||
<el-alert
|
||||
:title="$tc('auth.ReLoginTitle')"
|
||||
:title="$tc('ReLoginTitle')"
|
||||
center
|
||||
style="margin-bottom: 20px;"
|
||||
type="error"
|
||||
@@ -26,7 +26,7 @@
|
||||
<el-row :gutter="24" style="margin: 0 auto;">
|
||||
<el-col :md="24" :sm="24">
|
||||
<el-button class="confirm-btn" size="mini" type="primary" @click="logout">
|
||||
{{ this.$t('auth.ReLogin') }}
|
||||
{{ this.$t('ReLogin') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -50,18 +50,28 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24" style="margin: 0 auto;">
|
||||
<el-col :md="24" :sm="24" style="display: flex; margin-bottom: 20px;">
|
||||
<el-col :md="24" :sm="24" style="display: flex; align-items: center; margin-bottom: 20px;">
|
||||
<el-input
|
||||
v-if="subTypeSelected !== 'face'"
|
||||
v-model="secretValue"
|
||||
:placeholder="inputPlaceholder"
|
||||
:show-password="showPassword"
|
||||
@keyup.enter.native="handleConfirm"
|
||||
/>
|
||||
|
||||
<iframe
|
||||
v-if="isFaceCaptureVisible && subTypeSelected ==='face' && faceCaptureUrl"
|
||||
:src="faceCaptureUrl"
|
||||
allow="camera"
|
||||
sandbox="allow-scripts allow-same-origin"
|
||||
style="width: 100%; height: 800px;border: none;"
|
||||
/>
|
||||
|
||||
<span v-if="subTypeSelected === 'sms'" style="margin: -1px 0 0 20px;">
|
||||
<el-button
|
||||
:disabled="smsBtnDisabled"
|
||||
size="mini"
|
||||
style="line-height:20px; float: right;"
|
||||
style="line-height: 14px; float: right;"
|
||||
type="primary"
|
||||
@click="sendSMSCode"
|
||||
>
|
||||
@@ -72,8 +82,23 @@
|
||||
</el-row>
|
||||
<el-row :gutter="24" style="margin: 10px auto;">
|
||||
<el-col :md="24" :sm="24">
|
||||
<el-button class="confirm-btn" size="mini" type="primary" @click="handleConfirm">
|
||||
{{ this.$t('common.Confirm') }}
|
||||
<el-button
|
||||
v-if="subTypeSelected!=='face'"
|
||||
class="confirm-btn"
|
||||
size="mini"
|
||||
type="primary"
|
||||
@click="handleConfirm"
|
||||
>
|
||||
{{ this.$t('Confirm') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="subTypeSelected==='face'&&!isFaceCaptureVisible"
|
||||
class="confirm-btn"
|
||||
size="mini"
|
||||
type="primary"
|
||||
@click="handleFaceCapture"
|
||||
>
|
||||
{{ this.$tc('VerifyFace') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -82,6 +107,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import Dialog from '@/components/Dialog/index.vue'
|
||||
import { encryptPassword } from '@/utils/crypto'
|
||||
|
||||
export default {
|
||||
name: 'UserConfirmDialog',
|
||||
@@ -100,11 +126,11 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: this.$t('common.CurrentUserVerify'),
|
||||
title: this.$t('CurrentUserVerify'),
|
||||
smsWidth: 0,
|
||||
subTypeSelected: '',
|
||||
inputPlaceholder: '',
|
||||
smsBtnText: this.$t('common.SendVerificationCode'),
|
||||
smsBtnText: this.$t('SendVerificationCode'),
|
||||
smsBtnDisabled: false,
|
||||
confirmTypeRequired: '',
|
||||
subTypeChoices: [],
|
||||
@@ -112,7 +138,10 @@ export default {
|
||||
visible: false,
|
||||
callback: null,
|
||||
cancel: null,
|
||||
processing: false
|
||||
processing: false,
|
||||
isFaceCaptureVisible: false,
|
||||
faceToken: null,
|
||||
faceCaptureUrl: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -128,10 +157,14 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handleSubTypeChange(val) {
|
||||
if (val !== 'face') {
|
||||
this.isFaceCaptureVisible = false
|
||||
}
|
||||
|
||||
this.inputPlaceholder = this.subTypeChoices.filter(item => item.name === val)[0]?.placeholder
|
||||
this.smsWidth = val === 'sms' ? 6 : 0
|
||||
},
|
||||
performConfirm: _.throttle(function({ response, callback, cancel }) {
|
||||
performConfirm: _.debounce(function({ response, callback, cancel }) {
|
||||
if (this.processing || this.visible) {
|
||||
return
|
||||
}
|
||||
@@ -149,7 +182,7 @@ export default {
|
||||
this.callback()
|
||||
this.visible = false
|
||||
}).catch(() => {
|
||||
this.title = this.$t('auth.NeedReLogin')
|
||||
this.title = this.$t('NeedReLogin')
|
||||
this.visible = true
|
||||
})
|
||||
return
|
||||
@@ -161,50 +194,83 @@ export default {
|
||||
this.visible = true
|
||||
}).catch((err) => {
|
||||
const data = err.response?.data
|
||||
const msg = data?.error || data?.detail || data?.msg || this.$t('common.GetConfirmTypeFailed')
|
||||
const msg = data?.error || data?.detail || data?.msg || this.$t('GetConfirmTypeFailed')
|
||||
this.$message.error(msg)
|
||||
this.cancel(err)
|
||||
}).finally(() => {
|
||||
this.processing = false
|
||||
})
|
||||
}, 300),
|
||||
}, 500),
|
||||
logout() {
|
||||
window.location.href = `${process.env.VUE_APP_LOGOUT_PATH}?next=${this.$route.fullPath}`
|
||||
},
|
||||
sendSMSCode() {
|
||||
this.$axios.post(`/api/v1/authentication/mfa/select/`, { type: 'sms' }).then(res => {
|
||||
this.$message.success(this.$tc('common.VerificationCodeSent'))
|
||||
this.$message.success(this.$tc('VerificationCodeSent'))
|
||||
let time = 60
|
||||
const interval = setInterval(() => {
|
||||
const originText = this.smsBtnText
|
||||
this.smsBtnText = this.$t('common.Pending') + `: ${time}`
|
||||
this.smsBtnDisabled = true
|
||||
time -= 1
|
||||
this.smsBtnDisabled = true
|
||||
|
||||
if (time === 0) {
|
||||
this.smsBtnText = originText
|
||||
this.smsBtnDisabled = false
|
||||
const interval = setInterval(() => {
|
||||
time -= 1
|
||||
this.smsBtnText = `${this.$t('Pending')}: ${time}`
|
||||
|
||||
if (time <= 0) {
|
||||
clearInterval(interval)
|
||||
this.smsBtnText = this.$t('SendVerificationCode')
|
||||
this.smsBtnDisabled = false
|
||||
}
|
||||
}, 1000)
|
||||
}).catch(() => {
|
||||
this.$message.error(this.$tc('FailedToSendVerificationCode'))
|
||||
})
|
||||
},
|
||||
startFaceCapture() {
|
||||
const url = '/api/v1/authentication/face/context/'
|
||||
this.$axios.post(url).then(data => {
|
||||
const token = data['token']
|
||||
this.faceCaptureUrl = '/facelive/capture?token=' + token
|
||||
this.isFaceCaptureVisible = true
|
||||
|
||||
const timer = setInterval(() => {
|
||||
this.$axios.get(url + `?token=${token}`).then(data => {
|
||||
if (data['is_finished']) {
|
||||
clearInterval(timer)
|
||||
this.isFaceCaptureVisible = false
|
||||
this.handleConfirm()
|
||||
}
|
||||
})
|
||||
}, 1000)
|
||||
}).catch(() => {
|
||||
this.$message.error(this.$tc('FailedToStartFaceCapture'))
|
||||
})
|
||||
},
|
||||
handleFaceCapture() {
|
||||
this.startFaceCapture()
|
||||
},
|
||||
handleConfirm() {
|
||||
if (this.confirmTypeRequired === 'relogin') {
|
||||
return this.logout()
|
||||
}
|
||||
if (this.subTypeSelected === 'otp' && this.secretValue.length !== 6) {
|
||||
return this.$message.error(this.$tc('common.MFAErrorMsg'))
|
||||
return this.$message.error(this.$tc('MFAErrorMsg'))
|
||||
}
|
||||
|
||||
const data = {
|
||||
confirm_type: this.confirmTypeRequired,
|
||||
mfa_type: this.confirmTypeRequired === 'mfa' ? this.subTypeSelected : '',
|
||||
secret_key: this.secretValue
|
||||
secret_key: this.confirmTypeRequired === 'password' ? encryptPassword(this.secretValue) : this.secretValue
|
||||
}
|
||||
this.$axios.post(`/api/v1/authentication/confirm/`, data).then(res => {
|
||||
this.callback()
|
||||
|
||||
this.$axios.post(`/api/v1/authentication/confirm/`, data).then(() => {
|
||||
this.secretValue = ''
|
||||
this.visible = false
|
||||
this.$nextTick(() => {
|
||||
this.callback()
|
||||
})
|
||||
}).catch((err) => {
|
||||
this.$message.error(err.message || this.$tc('ConfirmFailed'))
|
||||
this.faceCaptureUrl = null
|
||||
this.isFaceCaptureVisible = false
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -212,22 +278,21 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dialog-content >>> .el-dialog__footer {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dialog-content >>> .el-dialog {
|
||||
padding: 8px;
|
||||
|
||||
.el-dialog__body {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
width: 100%;
|
||||
line-height: 20px;
|
||||
.dialog-content ::v-deep .el-dialog__footer {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dialog-content ::v-deep .el-dialog {
|
||||
padding: 8px;
|
||||
|
||||
.el-dialog__body {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
width: 100%;
|
||||
line-height: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
133
src/components/Apps/VariableCreateUpdateForm/index.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<AutoDataForm
|
||||
ref="AutoDataForm"
|
||||
class="variable-add"
|
||||
:submit-btn-text="submitBtnText"
|
||||
v-bind="$data"
|
||||
@submit="confirm"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AutoDataForm from '@/components/Form/AutoDataForm/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'VariableCreateForm',
|
||||
components: {
|
||||
AutoDataForm
|
||||
},
|
||||
props: {
|
||||
variable: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const defaultValidator = (rule, value, callback) => {
|
||||
if (this.defaultValueRequired && !value) {
|
||||
callback(new Error(this.$t('FieldRequiredError')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
defaultValueRequired: false,
|
||||
submitBtnText: this.$t('Confirm'),
|
||||
url: '/api/v1/ops/variables/',
|
||||
form: Object.assign({ 'on_invalid': 'error' }, this.variable || {}),
|
||||
fields: [
|
||||
['', ['name', 'var_name', 'type', 'text_default_value', 'select_default_value', 'extra_args', 'tips', 'required']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
text_default_value: {
|
||||
label: this.$t('DefaultValue'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.type !== 'text'
|
||||
},
|
||||
rules: [{ validator: defaultValidator }],
|
||||
helpTip: this.$t('DefaultValueTip'),
|
||||
el: {
|
||||
type: 'input'
|
||||
}
|
||||
},
|
||||
select_default_value: {
|
||||
label: this.$t('DefaultValue'),
|
||||
helpTip: this.$t('DefaultValueTip'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.type !== 'select'
|
||||
},
|
||||
rules: [{ validator: defaultValidator }],
|
||||
el: { type: 'input' }
|
||||
},
|
||||
extra_args: {
|
||||
hidden: (formValue) => {
|
||||
return formValue.type !== 'select'
|
||||
},
|
||||
el: { type: 'textarea', rows: 4, placeholder: this.$t('ExtraArgsPlaceholder') },
|
||||
rules: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
try {
|
||||
const lines = value.split('\n')
|
||||
const regex = /^[^:]+:[^:]+$/
|
||||
for (const line of lines) {
|
||||
if (!regex.test(line.trim())) {
|
||||
callback(new Error(this.$t('ExtraArgsFormatError')))
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
callback(new Error(this.$t('ExtraArgsFormatError')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
required: {
|
||||
on: {
|
||||
change: ([event], updateForm) => {
|
||||
this.defaultValueRequired = event
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
hasSaveContinue: false,
|
||||
method: 'get'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.defaultValueRequired = this.variable?.required || false
|
||||
},
|
||||
methods: {
|
||||
confirm(form) {
|
||||
if (this.variable?.name) {
|
||||
this.$emit('edit', form)
|
||||
} else {
|
||||
this.$emit('add', form)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.variable-add {
|
||||
::v-deep .el-form-item {
|
||||
margin-bottom: 5px;
|
||||
|
||||
.help-block {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .form-group-header {
|
||||
.hr-line-dashed {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||