Compare commits
876 Commits
v2020.1.0-
...
v3.0.0a2
Author | SHA1 | Date | |
---|---|---|---|
a5030baf62 | |||
e6e7122e33 | |||
20bd0733f2 | |||
3fa923a9d1 | |||
02bd105b86 | |||
573d36057b | |||
0eaa5c714c | |||
1c8e56274a | |||
43c689b30a | |||
5bee5deb22 | |||
22ef305e81 | |||
b66af49137 | |||
fcfcb7566d | |||
6fe15bac9c | |||
2f9e735928 | |||
c5837b237a | |||
1d13862880 | |||
651d4c9d32 | |||
d03bd2a667 | |||
f338a2e33d | |||
15f8fff179 | |||
b3aeb148e7 | |||
85f60fbc1c | |||
228ea78c41 | |||
c0f5b022e8 | |||
1888174ebf | |||
3cf1984b39 | |||
eda1099b41 | |||
b309cf92e6 | |||
5da993e2f5 | |||
8e197a8831 | |||
c80ff95757 | |||
6f3b0d2004 | |||
75cb4f0280 | |||
d4ea702a6a | |||
a143f0d037 | |||
7b1bd4a170 | |||
4ad56ed856 | |||
c264268ab8 | |||
835f35d996 | |||
9e61e2cb0b | |||
cb48ea2715 | |||
206d25d032 | |||
0bb4db78a4 | |||
e8e5ce8bb9 | |||
8424df0e2b | |||
24deb65a0b | |||
4d5a5b8934 | |||
408130596a | |||
8846415959 | |||
939e4dfd5b | |||
a1163f0274 | |||
1e0afa2460 | |||
a2338d905b | |||
5bb61bd1bc | |||
2a44abadd5 | |||
37684efe79 | |||
c8188ebf9c | |||
060a1f32cc | |||
387e5366be | |||
83a6da8cdb | |||
fc5b7b6e34 | |||
f75e7e0e10 | |||
73bc8cd4b7 | |||
7601a75831 | |||
44c0f75628 | |||
3c23e983ec | |||
9b6e927c7b | |||
17901e9ed2 | |||
3024f62d4b | |||
bd118fc4bd | |||
97a04a2fba | |||
cffd8d79a9 | |||
dc94d22822 | |||
c3bfad647f | |||
e2f4d67a30 | |||
698ecfa255 | |||
ff1b991d2a | |||
714db5e399 | |||
c59dd035eb | |||
a79d6c916f | |||
e72c6f6609 | |||
f6961777f0 | |||
f340586956 | |||
8929d1d659 | |||
cb7c445a0b | |||
7c343c51be | |||
20fe475791 | |||
974e17395b | |||
4b0499e373 | |||
a6661a24c6 | |||
7a79835a8d | |||
c682db4595 | |||
ca601e410b | |||
845f1f1ad8 | |||
3bbd755d0a | |||
56a22ec5c8 | |||
8c444059ad | |||
2755f7226b | |||
37cc3f3731 | |||
99e022bed8 | |||
f106ca51da | |||
9f80df4360 | |||
46c7c66362 | |||
1cd479751f | |||
fe7f65c723 | |||
eff4ed11d6 | |||
caa444121e | |||
6dcacbaa85 | |||
5cc45a39ca | |||
a61c0bfe07 | |||
e24aa1387b | |||
9381578657 | |||
379a39a98f | |||
cb11e8b1a2 | |||
5bddf9c5fc | |||
9c3667277c | |||
576c108da8 | |||
7398c07c6b | |||
5fbb4108dd | |||
b032c88467 | |||
50de71dc5a | |||
335ea23b6b | |||
40ffe84b77 | |||
a6b65fc8fe | |||
1d75fefb68 | |||
59667e3a90 | |||
06852d94d7 | |||
be831aaf15 | |||
3d0e94257f | |||
50f6cd2191 | |||
06ed79ec78 | |||
5c1ce1a5ab | |||
ea76493ab8 | |||
7d706a39f1 | |||
f7696e5453 | |||
726562d615 | |||
78f77dc881 | |||
1787db7c6d | |||
088b128b57 | |||
b7e314deeb | |||
fd95c2d43c | |||
52f10b0c53 | |||
ecf729fc56 | |||
b430ab9a1c | |||
18a014d739 | |||
07c505187d | |||
eb07abe786 | |||
78da4f0efa | |||
0185dbd8af | |||
83fa40907e | |||
0ae25095a8 | |||
ea1e280e66 | |||
667c8fc7f0 | |||
36482c7a96 | |||
7aae84b2be | |||
7049e05c91 | |||
e7e55e7eaf | |||
65c48769b7 | |||
2816202ee5 | |||
434bf57cd1 | |||
0120a1281c | |||
824833e621 | |||
23fe8ae9b8 | |||
4f90a6d1fd | |||
f055836f44 | |||
88e1cb66eb | |||
2f0cdfc33c | |||
6152f68acf | |||
8ec2b806a9 | |||
dc382348b8 | |||
05d980e6e3 | |||
fbfb6b7152 | |||
834173201b | |||
49693efc04 | |||
29f1eb92d8 | |||
d5287bfb8e | |||
a7e637a466 | |||
f71a8edc3c | |||
0df6294cc7 | |||
7ff43eb582 | |||
236a9d11b3 | |||
dc2c4cbbbe | |||
a074bbc617 | |||
4c11b6c012 | |||
a26a08cb20 | |||
7ac6b1ef76 | |||
c929f49aa2 | |||
d00e56627f | |||
a172b7d41f | |||
f7ba01211e | |||
002569ed75 | |||
f23315fd75 | |||
2121d29a9e | |||
834cdecd80 | |||
78f2b76a14 | |||
978b473e8e | |||
d652ae0bbb | |||
50a5307d03 | |||
408184874c | |||
a8043f9423 | |||
66cd41018e | |||
d43e6649c7 | |||
5cb3c43e88 | |||
97974339b9 | |||
a1228d009b | |||
67c564caa7 | |||
258e9f02c2 | |||
fcc03f5ad0 | |||
5e65aff228 | |||
c86769dd4f | |||
147cae1313 | |||
97d1bc7596 | |||
fa0531644d | |||
ab89aa8ec8 | |||
8adad9c13f | |||
316fe735fc | |||
f91a5f657f | |||
6a09772459 | |||
48bb035b34 | |||
9558b2137f | |||
c2410f0933 | |||
2f9999b41c | |||
96a11384a0 | |||
c938c3a8ca | |||
93188f2aec | |||
f9cc7f3883 | |||
160b0eccc0 | |||
0b2128f00b | |||
02c323463c | |||
067c8a00ec | |||
7d1ed62f30 | |||
349666dcc1 | |||
3ad28e6d09 | |||
5aa7afe15c | |||
c5434a4e99 | |||
87a0b951a7 | |||
0154d123a9 | |||
fc0fdd2e51 | |||
b6b9d735f5 | |||
8df255ebc3 | |||
02285265e3 | |||
c400ad551e | |||
5102039dbd | |||
7bff9b40de | |||
707f5b6c7f | |||
6a573110e8 | |||
0d5f11dfc1 | |||
65f1d45dc5 | |||
2664911455 | |||
65172c18b5 | |||
920154e7b9 | |||
36e39f908b | |||
39627c28c8 | |||
b8b7e4d151 | |||
fb7845bbce | |||
a7f6743860 | |||
a4e8dee2e1 | |||
4911b0da66 | |||
6122801f90 | |||
c3f3fafbef | |||
cbeca9d0ca | |||
eb5437d005 | |||
2e2a59f6f2 | |||
596a11210f | |||
11029db956 | |||
0c0d77e220 | |||
4e207d270e | |||
9546ed94fe | |||
7219f02783 | |||
2ea79aaa27 | |||
e37f1e97fa | |||
4e2d043561 | |||
d46502b804 | |||
108f95de59 | |||
60a9e45e4a | |||
fa22ce5d0f | |||
8b177013d1 | |||
6353207d40 | |||
f721bd0d26 | |||
44c530d1b5 | |||
f2b70d562d | |||
6dd81b2406 | |||
a153e97f55 | |||
7953a86fd9 | |||
5c426ad822 | |||
a9b7e09da4 | |||
a2085e846a | |||
aa5a328f44 | |||
02c5c85148 | |||
a7528fe990 | |||
758f680a28 | |||
ac265a90bf | |||
44e1b3d656 | |||
a93125cdd7 | |||
34b974461b | |||
a2a3f542e6 | |||
f7e07851f7 | |||
60bae5db3c | |||
d6e5dee1aa | |||
cb101e8202 | |||
0124018b02 | |||
04fdcc6893 | |||
62c94275a9 | |||
5270134626 | |||
21dfa56b17 | |||
8eda2ddcea | |||
4c7d0b317e | |||
8e93fa9d36 | |||
2b81d72232 | |||
e54638a248 | |||
239d1305fa | |||
aac7b57d22 | |||
9421b4bf57 | |||
717336fbd1 | |||
48f093360d | |||
bac6047247 | |||
e36d56ff5d | |||
354b313eaa | |||
b91a113cf5 | |||
7d95200eb3 | |||
b048a846e0 | |||
092fe5991b | |||
1a03bb0456 | |||
a04804eaa0 | |||
8a56032291 | |||
c80dbe6baf | |||
2b17b3d627 | |||
6e9ebfb69d | |||
6faba7c4ec | |||
3f7fe0a7f3 | |||
666e39ede3 | |||
60f8685c68 | |||
ca5a8ea891 | |||
3b07b4a2db | |||
d01fcbcfe1 | |||
9bf2980b6b | |||
57e6200972 | |||
b692bd0f43 | |||
e37bdc6162 | |||
e3db70a7d9 | |||
bb2a963237 | |||
c0cff3a6db | |||
2a96a6b601 | |||
1d5bbb58f9 | |||
0e3dd69767 | |||
823e9a4b59 | |||
6b2760c06a | |||
eb7da2f565 | |||
521b593212 | |||
ca7b43a5c2 | |||
c8f1a4d428 | |||
350ed9a4aa | |||
96919f8c05 | |||
d290daed11 | |||
faf2dbf276 | |||
5ba7799d8a | |||
17da822a47 | |||
748997c635 | |||
cf2f0e3110 | |||
8bfb375e02 | |||
9fd34e8253 | |||
abdd739f06 | |||
84d0f803dc | |||
1f972d3261 | |||
42ae0b671a | |||
a5b4a12849 | |||
06ad9c2f07 | |||
b51159513f | |||
12ba174dfa | |||
62c1f8b003 | |||
f7a3df27b8 | |||
4261086495 | |||
1e21f672fb | |||
c8caf20234 | |||
17acd161d8 | |||
a27f854bde | |||
4a8be81534 | |||
e863c1f6e7 | |||
9835c106d8 | |||
71077413b7 | |||
5cfda3500a | |||
ab6c43c167 | |||
84f7fabdc8 | |||
4eefe89eb1 | |||
a9aa64c7f5 | |||
64b814acd7 | |||
d73f65dc70 | |||
e669e4cc47 | |||
469fa6cd23 | |||
f664165190 | |||
16d86a2322 | |||
b92c6384de | |||
ccc328f279 | |||
5f5cd8aa9e | |||
668093ffb3 | |||
644dc588b2 | |||
7c48791ae5 | |||
aac9476e26 | |||
e57350e0e5 | |||
1a853f5c36 | |||
89db5d2602 | |||
641a542714 | |||
909986af96 | |||
c6ccaf3c4d | |||
56a00bc877 | |||
0015c09ba5 | |||
25829b89e6 | |||
611ba2b410 | |||
700eff76eb | |||
f5296dd1fb | |||
085659bbcc | |||
20afbbcb5b | |||
2350f88c59 | |||
bec15d4d37 | |||
5697274dd4 | |||
2e750a0465 | |||
708009d374 | |||
bba7d8b221 | |||
1dc4887071 | |||
7362f2625b | |||
9b79cb9873 | |||
ee943eacad | |||
02e614de42 | |||
b8812a9e41 | |||
98ac55c96e | |||
7d9928609d | |||
c4df0e49f9 | |||
0a67137cc6 | |||
d86eca7061 | |||
0e71897317 | |||
330d004e3b | |||
12d1f7fd41 | |||
ca251bd984 | |||
c90f37b030 | |||
0d7e76eb6c | |||
4f34076440 | |||
249a98b340 | |||
9da4079d2f | |||
e2c4b2a372 | |||
da5eb7a4b6 | |||
ae9efcf7b4 | |||
b8c45688f6 | |||
3026a70e61 | |||
5832f9f724 | |||
6b676fa91e | |||
785855d3bd | |||
e609965e91 | |||
d042ad8ce4 | |||
ddb2e3f34a | |||
7cd1d5ed87 | |||
bc45a1bea9 | |||
b0e197dbbd | |||
e213279cdc | |||
d072324ef7 | |||
a101620954 | |||
e5813a255e | |||
a6eb1cc09f | |||
1b0c62c0d1 | |||
d45947999d | |||
06926c53af | |||
96f4600706 | |||
fe8550678d | |||
a0d88a937e | |||
e1b0e73916 | |||
767dc0c963 | |||
6c4cdb06b2 | |||
91844ee770 | |||
46c4bc1d78 | |||
baa344fbe5 | |||
73d3ab2534 | |||
7294e926a8 | |||
c4eecd3e8b | |||
015a1a9350 | |||
0bbaca6439 | |||
e4ad03e1c6 | |||
0bc000f096 | |||
703ceb177b | |||
ab533a9be4 | |||
d72cf3595f | |||
9e7d11bf8a | |||
8b7fb1f0d2 | |||
7bc95954ec | |||
6af1b97174 | |||
37f94d5002 | |||
317304c08a | |||
80bf232f06 | |||
5c1ed5de06 | |||
3cc84364ff | |||
b6fdc260c6 | |||
c8ec9c1213 | |||
33e0fbb0b4 | |||
d4d9093505 | |||
32945dbd55 | |||
daf7da2189 | |||
ad553a6aa2 | |||
df6d760444 | |||
e319aa4c4e | |||
4983af48d1 | |||
b114c7db81 | |||
140e56643d | |||
ec704d63dd | |||
1fc111a6e2 | |||
7f44ad4e7c | |||
ad593d8408 | |||
2c5683917b | |||
85ab218bc2 | |||
735a618e0c | |||
f508242858 | |||
991f014ba3 | |||
60aa98e721 | |||
c956bc84c8 | |||
5668016ef5 | |||
a66b66f270 | |||
ced2cba28b | |||
73ef1f0f80 | |||
383c628f2f | |||
80e19f5538 | |||
d7012416ec | |||
0df3420cd5 | |||
75dd47afac | |||
1b96d94384 | |||
99b90db6ed | |||
165ab06fde | |||
72371cb8d6 | |||
c431d163c2 | |||
98df9cd2b7 | |||
40a580dcb0 | |||
149b68e037 | |||
288879ccb2 | |||
5cb3aa051b | |||
c420dd8512 | |||
05e1519ceb | |||
daff351b22 | |||
82aa9c1d2c | |||
b68b871dd6 | |||
de6529ddd7 | |||
1fc48b28b3 | |||
0386d97a56 | |||
a28b22eafb | |||
fc34cbf524 | |||
9861f4a2f5 | |||
57294f49a7 | |||
15b9748120 | |||
6c92941794 | |||
b6137b8ef1 | |||
692db7b605 | |||
43042fcde0 | |||
0ca1c02d10 | |||
b2cb7804de | |||
05971ef1ae | |||
3db88acff4 | |||
ccfd4d468e | |||
d2d37135a6 | |||
0abc9756b7 | |||
22c72f411b | |||
e16152edaf | |||
c11d32e253 | |||
d80b0142fd | |||
dce29bb45d | |||
e4d1ef7cf7 | |||
3130eda5d5 | |||
4bab23fa60 | |||
8ffbf1be30 | |||
3667a4d755 | |||
55fe1e561a | |||
74803d193e | |||
7c27ceaab7 | |||
b661ba7ddf | |||
fe2ab05f57 | |||
a522b12842 | |||
9455c9970c | |||
ac10eae134 | |||
19b1e4b230 | |||
5d6bda7e31 | |||
d782bcafbe | |||
e335a552c5 | |||
753e08a6ba | |||
305182b01f | |||
dd7dcf4dab | |||
8205c65799 | |||
169a06fd3a | |||
820fa9f690 | |||
cf725931f9 | |||
c7db04ce3b | |||
93532d3274 | |||
81bc3cb3bd | |||
87aa6c4b59 | |||
b32fdf4fc2 | |||
6f991e4885 | |||
fe02a4cb79 | |||
61d4e2461f | |||
c80284d7d2 | |||
00d4a5ff92 | |||
61bb6e45bf | |||
bbb344557b | |||
94ce514cfe | |||
0ccae1dde7 | |||
4c08a11452 | |||
8687c0b1f0 | |||
36b610eafa | |||
58497c1f5a | |||
bd6693cb11 | |||
c732ed5a72 | |||
696a708930 | |||
ad783722d0 | |||
d266d5ece2 | |||
8948bd7205 | |||
9c1c15df8a | |||
97a6d5298e | |||
8978c0cc33 | |||
9e37f47ef1 | |||
0682595f6f | |||
f79e320d55 | |||
e33fe70a38 | |||
535a48211a | |||
659db6a73e | |||
340004d9d5 | |||
cb133d9525 | |||
910ddb9955 | |||
c3c25efb71 | |||
29a8b9f527 | |||
9dfd58b14b | |||
dd4ab0013b | |||
a7e05cff7c | |||
128d02b85d | |||
a0073e1d23 | |||
0742574221 | |||
20f0b06a77 | |||
8d795ebf10 | |||
cb6cacc557 | |||
bf4f2dcdb7 | |||
72418a1a9f | |||
4d6678fa4d | |||
5aeecb08a1 | |||
8bd289c3d2 | |||
9b77b40bd0 | |||
69177e86fc | |||
75de6d2c38 | |||
76dbcc0782 | |||
a1f6be337a | |||
d1fb7e6624 | |||
29e8949872 | |||
1e36a721b6 | |||
b2e96172e6 | |||
05cda2b3a6 | |||
d0e6318198 | |||
b78f3824fc | |||
ffb3646d08 | |||
af564d6cd7 | |||
01ea42e930 | |||
7ee47d2e86 | |||
841f5c6283 | |||
dea33c9992 | |||
2c9ea028d7 | |||
1f6f81a02e | |||
e228ac2654 | |||
dede19d686 | |||
26153aa0e7 | |||
6d023828ec | |||
acf5a9fadb | |||
e9aeb169c5 | |||
141fc9cae5 | |||
4125c98e82 | |||
801c10feff | |||
0d4cc53ebb | |||
da16f39355 | |||
565051c259 | |||
da43d843c0 | |||
1356aa1962 | |||
8362e3463b | |||
695ca81cc0 | |||
97d259c7f4 | |||
62587fbdcd | |||
a3142c6fb1 | |||
46c6cd1d7e | |||
4c528bea07 | |||
9adcd6090d | |||
9a974ae72d | |||
b5c2c3b4f2 | |||
f185f97ad5 | |||
1b05924070 | |||
2ebe412cc8 | |||
a3e4483478 | |||
76f71b7c8b | |||
1924fcbce0 | |||
20441a3e38 | |||
aa78dc682f | |||
ed2ec8f004 | |||
290ed5ee89 | |||
491eb86451 | |||
b8ed394937 | |||
0195b3dfc9 | |||
33786ccd14 | |||
c7d7a97279 | |||
4ddc8a198d | |||
fc7c52efb7 | |||
9b626b6805 | |||
5365e228a6 | |||
9215ab8e87 | |||
38941c209b | |||
c8104a577f | |||
7c4e745075 | |||
b91ca628a0 | |||
f0ec495ff4 | |||
b35c4ace6a | |||
31fa79472a | |||
9938055638 | |||
f4dde0ecae | |||
62e866273b | |||
3e2c537a6d | |||
1658845022 | |||
e76527840b | |||
09fe6dbcbb | |||
92cfb2d94a | |||
206242dba9 | |||
c78517c22e | |||
91cfd1d257 | |||
7b1c5deff5 | |||
fc6a5671fb | |||
b0c331d054 | |||
d07fad3c79 | |||
c0b9311b38 | |||
41e7f1c53e | |||
e7dfa6242b | |||
3c47cbcb1b | |||
671b2d9d37 | |||
df8f39e951 | |||
7a62a7589a | |||
b8e2bb00ac | |||
300e710341 | |||
67754192ea | |||
c415011f34 | |||
561226f31b | |||
c7dc56babd | |||
1a8701d845 | |||
2fd1bb2358 | |||
976d92a866 | |||
220bda22f5 | |||
57490b7272 | |||
6d0f41714a | |||
e853849cc9 | |||
0f4890fd10 | |||
edb7aefba2 | |||
71415dac8f | |||
15505b9b8c | |||
66bbe2cd11 | |||
b3109a8cc5 | |||
41f5af2b90 | |||
a7f5a5fa09 | |||
7248a0f183 | |||
53b4e064ee | |||
5f52f25da4 | |||
84212c0c33 | |||
d6808ba1d7 | |||
d190765a99 | |||
68a13e293b | |||
0463b8c3b8 | |||
da5dcd5fe9 | |||
f06ba2bf77 | |||
06e3befe0e | |||
932c482855 | |||
bf292b4286 | |||
7fa49824c6 | |||
2b380a2699 | |||
eb9102769c | |||
672d25132f | |||
b8ded15ef7 | |||
3a57e73192 | |||
38dc9ccced | |||
f3b6b8393a | |||
de0454f420 | |||
6bf268b47f | |||
7625ff5cfa | |||
455a13b96f | |||
25b1edd178 | |||
d15b4db9fe | |||
d5e0c8271b | |||
b37b5c7134 | |||
4992eae284 | |||
0cee6188fb | |||
1ed8123082 | |||
424799a54d | |||
5a314f2631 | |||
3adc53eda9 | |||
6fc059bd10 | |||
0e8f9326a3 | |||
9a2744bc64 | |||
d127986b03 | |||
9e5985c8c8 | |||
5e2d3c6a87 | |||
482834594f | |||
3eda507229 | |||
2f3014fcf6 | |||
494055a5b5 | |||
9f58be90ea | |||
6f118413af | |||
7a5437c29e | |||
c684577c57 | |||
afa9facb3a | |||
82891b248f | |||
81b388a7fe | |||
cace01ce9a | |||
02095ca359 | |||
5e95cfdea1 | |||
449c8a97db | |||
f185762969 | |||
3f0772c352 | |||
79dee73590 | |||
11e116f508 | |||
5600364583 | |||
e01c06a54e | |||
81b6eb32cf | |||
53c57b069e | |||
626769aa61 | |||
467cf2b1d8 | |||
1fd926593a | |||
9595787e59 | |||
9b482837d8 | |||
fe51a1797d | |||
6b6ac2f312 | |||
8da4407109 | |||
c3ebdd6498 | |||
c23892f836 | |||
9e2bc25c01 | |||
9594e397e5 | |||
a75de3b179 | |||
e78ca38f30 | |||
57c9caa40f | |||
b6d02ca5d4 | |||
18f7f350f7 | |||
72b6be6862 | |||
1d0baa8857 | |||
d3d897c936 | |||
01d49a7321 | |||
6860efa2a6 | |||
505c6152fb | |||
9a33b28576 | |||
b3aee79f40 | |||
ee784783a9 | |||
09a03ea013 | |||
0bcc662d91 | |||
0e4ea77d3f | |||
71c1798152 | |||
1199dedc23 | |||
e85fb93923 | |||
ffefd65625 | |||
10f7376030 | |||
3f4bb0b172 | |||
33c35308f9 | |||
e7766ec708 | |||
1afbb39d85 | |||
5c57135a80 | |||
252bcf89d5 | |||
7279ca71ed | |||
2b2511537b | |||
e21602069e | |||
24fffafbf1 | |||
f71af8c57c | |||
f722872a94 | |||
b424abb600 | |||
48dbd7f6aa | |||
2d8c5966cd | |||
d16913a678 | |||
65f86ee4e4 | |||
7393fd52e1 | |||
bb75727aaf | |||
ee9fc3cb29 | |||
2cd3b7a4d6 | |||
7f16a6db1e | |||
6e21cfeb4f | |||
2c3387c960 | |||
a341d7c2ec | |||
43787e94e8 | |||
4402a53ae0 | |||
4fc87c4cda |
@ -20,6 +20,7 @@ install:
|
|||||||
build_script:
|
build_script:
|
||||||
- cmd: set NODE_OPTIONS=--max-old-space-size=8092
|
- cmd: set NODE_OPTIONS=--max-old-space-size=8092
|
||||||
- yarn buildforelectron
|
- yarn buildforelectron
|
||||||
|
- "%PYTHON%\\python.exe -m pip install -U pip"
|
||||||
- "%PYTHON%\\python.exe -m pip install -r scripts\\requirements.txt"
|
- "%PYTHON%\\python.exe -m pip install -r scripts\\requirements.txt"
|
||||||
- "%PYTHON%\\python.exe scripts\\build.py download -a"
|
- "%PYTHON%\\python.exe scripts\\build.py download -a"
|
||||||
- "%PYTHON%\\python.exe scripts\\build.py build_exe -b dist/exe.gns3server -s"
|
- "%PYTHON%\\python.exe scripts\\build.py build_exe -b dist/exe.gns3server -s"
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
# iOS CircleCI 2.1 configuration file
|
# iOS CircleCI 2.1 configuration file
|
||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
|
orbs:
|
||||||
|
node: circleci/node@4.2.0
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
macos:
|
macos:
|
||||||
@ -7,13 +11,16 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
- node/install:
|
||||||
|
install-yarn: true
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Install nodejs
|
name: Update BREW and print configs
|
||||||
command: |
|
command: |
|
||||||
brew update
|
brew update
|
||||||
brew upgrade yarn
|
brew analytics off
|
||||||
brew upgrade node
|
brew --env
|
||||||
|
brew --config
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Set timezone and check current datetime
|
name: Set timezone and check current datetime
|
||||||
@ -34,6 +41,8 @@ jobs:
|
|||||||
curl -o /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/readline.rb https://raw.githubusercontent.com/Homebrew/homebrew-core/b1bd1c4a62e1336422de3614d1fc49ffbce589a8/Formula/readline.rb
|
curl -o /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/readline.rb https://raw.githubusercontent.com/Homebrew/homebrew-core/b1bd1c4a62e1336422de3614d1fc49ffbce589a8/Formula/readline.rb
|
||||||
# remove check for old compilers which creates the error described in https://github.com/sashkab/homebrew-python/issues/36
|
# remove check for old compilers which creates the error described in https://github.com/sashkab/homebrew-python/issues/36
|
||||||
sed -i.bak -e '58,61d' /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python.rb
|
sed -i.bak -e '58,61d' /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python.rb
|
||||||
|
# remove 'do devel' block to avoid error: Calling 'devel' blocks in formulae is disabled!
|
||||||
|
sed -i.bak -e '14,17d' /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python.rb
|
||||||
brew unlink python
|
brew unlink python
|
||||||
brew uninstall --ignore-dependencies readline
|
brew uninstall --ignore-dependencies readline
|
||||||
brew install readline
|
brew install readline
|
||||||
@ -41,7 +50,7 @@ jobs:
|
|||||||
brew pin readline
|
brew pin readline
|
||||||
# --ignore-dependencies is used to prevent this issue: https://github.com/tensorflow/tensorflow/issues/25093
|
# --ignore-dependencies is used to prevent this issue: https://github.com/tensorflow/tensorflow/issues/25093
|
||||||
brew install --ignore-dependencies python
|
brew install --ignore-dependencies python
|
||||||
brew switch python 3.6.5_1
|
#brew link python 3.6.5_1
|
||||||
brew info python
|
brew info python
|
||||||
brew pin python
|
brew pin python
|
||||||
|
|
||||||
@ -77,8 +86,11 @@ jobs:
|
|||||||
name: Building gns3server
|
name: Building gns3server
|
||||||
command: |
|
command: |
|
||||||
python3 -V
|
python3 -V
|
||||||
pip3 install -r scripts/requirements.txt
|
python3 -m pip install -U pip
|
||||||
|
python3 -m pip install -r scripts/requirements.txt
|
||||||
python3 scripts/build.py download -a
|
python3 scripts/build.py download -a
|
||||||
|
# necessary because of https://github.com/GNS3/gns3-gui/issues/2849
|
||||||
|
python3 -m pip install jsonschema==2.6.0
|
||||||
python3 scripts/build.py build_exe -b dist/exe.gns3server -s
|
python3 scripts/build.py build_exe -b dist/exe.gns3server -s
|
||||||
python3 scripts/build.py validate -b dist
|
python3 scripts/build.py validate -b dist
|
||||||
|
|
||||||
@ -105,4 +117,3 @@ workflows:
|
|||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
only: /v.*/
|
only: /v.*/
|
||||||
|
|
||||||
|
28
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
name: Build
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- master-3.0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node: [ 14, 16, 18 ]
|
||||||
|
name: Node ${{ matrix.node }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Setup Node ${{ matrix.node }}
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
|
cache: 'yarn'
|
||||||
|
- name: Install JS dependencies
|
||||||
|
run: yarn install --frozen-lockfile --immutable
|
||||||
|
- name: Test
|
||||||
|
run: yarn test
|
2
.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
# compiled output
|
# compiled output
|
||||||
|
/.angular
|
||||||
/dist
|
/dist
|
||||||
/tmp
|
/tmp
|
||||||
/out-tsc
|
/out-tsc
|
||||||
@ -11,6 +12,7 @@
|
|||||||
/scripts/build
|
/scripts/build
|
||||||
/scripts/dist
|
/scripts/dist
|
||||||
/env
|
/env
|
||||||
|
/.angular
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
/node_modules
|
||||||
|
8
.snyk
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
|
||||||
|
version: v1.16.0
|
||||||
|
ignore: {}
|
||||||
|
# patches apply the minimum changes required to fix a vulnerability
|
||||||
|
patch:
|
||||||
|
SNYK-JS-LODASH-567746:
|
||||||
|
- ngx-childprocess > @types/electron > electron > @electron/get > global-tunnel-ng > lodash:
|
||||||
|
patched: '2020-07-10T04:10:11.863Z'
|
@ -37,12 +37,12 @@ before_install:
|
|||||||
before_script:
|
before_script:
|
||||||
# greenkeeper-lockfile support
|
# greenkeeper-lockfile support
|
||||||
- greenkeeper-lockfile-update
|
- greenkeeper-lockfile-update
|
||||||
- npm install -g codecov
|
# - npm install -g codecov
|
||||||
|
|
||||||
script: yarn coverage
|
script: yarn coverage
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- codecov
|
# - codecov
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
# greenkeeper-lockfile support
|
# greenkeeper-lockfile support
|
||||||
|
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"angular.enable-strict-mode-prompt": false
|
||||||
|
}
|
13
.whitesource
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"scanSettings": {
|
||||||
|
"configMode": "AUTO",
|
||||||
|
"configExternalURL": "",
|
||||||
|
"projectToken" : ""
|
||||||
|
},
|
||||||
|
"checkRunSettings": {
|
||||||
|
"vulnerableCheckRunConclusionLevel": "failure"
|
||||||
|
},
|
||||||
|
"issueSettings": {
|
||||||
|
"minSeverityLevel": "LOW"
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
# Dockerfile for GNS3 Web-ui development
|
# Dockerfile for GNS3 Web-ui development
|
||||||
FROM node:carbon
|
FROM node:stretch
|
||||||
|
|
||||||
# Create user
|
# Create user
|
||||||
RUN useradd --user-group --create-home --shell /bin/false gns3-web-ui
|
RUN useradd --user-group --create-home --shell /bin/false gns3-web-ui
|
||||||
|
23
README.md
@ -1,16 +1,9 @@
|
|||||||
# gns3-web-ui
|
# gns3-web-ui
|
||||||
|
|
||||||
[](https://greenkeeper.io/)
|
[](https://github.com/GNS3/gns3-web-ui/actions/workflows/main.yml)
|
||||||
[](https://travis-ci.org)
|
[](https://libraries.io/github/GNS3/gns3-web-ui)
|
||||||
[](https://www.appveyor.com/)
|
[](https://repology.org/metapackage/gns3/versions)
|
||||||
[](https://circleci.com/gh/GNS3/gns3-web-ui/tree/master.png)
|
[](https://repology.org/metapackage/gns3/versions)
|
||||||
[](https://codecov.io/gh/GNS3/gns3-web-ui)
|
|
||||||
|
|
||||||
|
|
||||||
Test WebUI implementation for GNS3.
|
|
||||||
|
|
||||||
This is not production ready version. It has been made to evaluate possibility of creation Web User Interface for GNS3 application.
|
|
||||||
|
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
|
||||||
@ -30,6 +23,14 @@ We're using [yarn](https://yarnpkg.com/lang/en/) for packages installation:
|
|||||||
yarn install
|
yarn install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## JavaScript heap out of memory
|
||||||
|
|
||||||
|
Increase the memory allocated to Node if you get JavaScript heap out of memory errors.
|
||||||
|
|
||||||
|
```
|
||||||
|
export NODE_OPTIONS=--max-old-space-size=8192
|
||||||
|
```
|
||||||
|
|
||||||
#### Run GNS3 server
|
#### Run GNS3 server
|
||||||
|
|
||||||
Visit [gns3-server](https://github.com/GNS3/gns3-server) for guide how to run GNS3 server.
|
Visit [gns3-server](https://github.com/GNS3/gns3-server) for guide how to run GNS3 server.
|
||||||
|
412
angular.json
@ -1,207 +1,231 @@
|
|||||||
{
|
{
|
||||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"newProjectRoot": "projects",
|
"newProjectRoot": "projects",
|
||||||
"projects": {
|
"projects": {
|
||||||
"gns3-web-ui": {
|
"gns3-web-ui": {
|
||||||
"root": "",
|
"root": "",
|
||||||
"sourceRoot": "src",
|
"sourceRoot": "src",
|
||||||
"projectType": "application",
|
"projectType": "application",
|
||||||
"architect": {
|
"architect": {
|
||||||
"build": {
|
"build": {
|
||||||
"builder": "@angular-devkit/build-angular:browser",
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
"options": {
|
"options": {
|
||||||
"outputPath": "dist",
|
"allowedCommonJsDependencies": [
|
||||||
"index": "src/index.html",
|
"rxjs",
|
||||||
"main": "src/main.ts",
|
"rxjs-compat",
|
||||||
"tsConfig": "src/tsconfig.app.json",
|
"uuid",
|
||||||
"polyfills": "src/polyfills.ts",
|
"css-tree",
|
||||||
"extractCss": true,
|
"save-svg-as-png",
|
||||||
"assets": [
|
"angular-draggable-droppable",
|
||||||
"src/assets",
|
"dom-set",
|
||||||
"src/favicon.ico",
|
"dom-plane",
|
||||||
"src/ReleaseNotes.txt"
|
"mousetrap",
|
||||||
],
|
"@mattlewis92/dom-autoscroller",
|
||||||
"styles": [
|
"rxjs/Rx",
|
||||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
"rxjs/add/operator/map",
|
||||||
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
"rxjs-compat/add/operator/map",
|
||||||
"src/styles.css",
|
"classnames",
|
||||||
{
|
"stylenames",
|
||||||
"input": "src/theme.scss",
|
"source-map-js"
|
||||||
"lazy": true,
|
],
|
||||||
"bundleName": "theme-default-dark"
|
"outputPath": "dist",
|
||||||
},
|
"index": "src/index.html",
|
||||||
{
|
"main": "src/main.ts",
|
||||||
"input": "src/theme-light.scss",
|
"tsConfig": "src/tsconfig.app.json",
|
||||||
"lazy": true,
|
"polyfills": "src/polyfills.ts",
|
||||||
"bundleName": "theme-default"
|
"assets": [
|
||||||
}
|
"src/assets",
|
||||||
],
|
"src/favicon.ico",
|
||||||
"scripts": []
|
"src/ReleaseNotes.txt"
|
||||||
},
|
],
|
||||||
"configurations": {
|
"styles": [
|
||||||
"production": {
|
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||||
"optimization": true,
|
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
||||||
"outputHashing": "all",
|
"src/styles.scss",
|
||||||
"sourceMap": {
|
"src/theme.scss"
|
||||||
"hidden": true,
|
],
|
||||||
"scripts": true,
|
"scripts": [],
|
||||||
"styles": false
|
"vendorChunk": true,
|
||||||
},
|
"extractLicenses": false,
|
||||||
"extractCss": true,
|
"buildOptimizer": true,
|
||||||
"namedChunks": false,
|
"sourceMap": true,
|
||||||
"aot": true,
|
"optimization": false,
|
||||||
"extractLicenses": true,
|
"namedChunks": true,
|
||||||
"vendorChunk": false,
|
"aot": true
|
||||||
"buildOptimizer": true,
|
},
|
||||||
"fileReplacements": [
|
"configurations": {
|
||||||
{
|
"production": {
|
||||||
"replace": "src/environments/environment.ts",
|
"budgets": [{
|
||||||
"with": "src/environments/environment.prod.ts"
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "6kb"
|
||||||
|
}],
|
||||||
|
"optimization": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": {
|
||||||
|
"hidden": true,
|
||||||
|
"scripts": true,
|
||||||
|
"styles": false
|
||||||
|
},
|
||||||
|
"namedChunks": false,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"vendorChunk": false,
|
||||||
|
"buildOptimizer": true,
|
||||||
|
"fileReplacements": [{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.prod.ts"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"electronProd": {
|
||||||
|
"budgets": [{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "6kb"
|
||||||
|
}],
|
||||||
|
"optimization": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": false,
|
||||||
|
"namedChunks": false,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"vendorChunk": false,
|
||||||
|
"buildOptimizer": true,
|
||||||
|
"fileReplacements": [{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.electron.prod.ts"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"electronDev": {
|
||||||
|
"budgets": [{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "6kb"
|
||||||
|
}],
|
||||||
|
"fileReplacements": [{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.electron.ts"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"githubProd": {
|
||||||
|
"budgets": [{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "6kb"
|
||||||
|
}],
|
||||||
|
"optimization": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": false,
|
||||||
|
"namedChunks": false,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"vendorChunk": false,
|
||||||
|
"buildOptimizer": true,
|
||||||
|
"fileReplacements": [{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.github.prod.ts"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "gns3-web-ui:build"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"browserTarget": "gns3-web-ui:build:production"
|
||||||
|
},
|
||||||
|
"electronProd": {
|
||||||
|
"browserTarget": "gns3-web-ui:build:electronProd"
|
||||||
|
},
|
||||||
|
"electronDev": {
|
||||||
|
"browserTarget": "gns3-web-ui:build:electronDev"
|
||||||
|
},
|
||||||
|
"githubProd": {
|
||||||
|
"browserTarget": "gns3-web-ui:build:githubProd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "gns3-web-ui:build"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"main": "src/test.ts",
|
||||||
|
"karmaConfig": "./karma.conf.js",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
|
"scripts": [],
|
||||||
|
"styles": [
|
||||||
|
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||||
|
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
||||||
|
"src/styles.scss",
|
||||||
|
"src/theme.scss"
|
||||||
|
],
|
||||||
|
"sourceMap": false,
|
||||||
|
"assets": [
|
||||||
|
"src/assets",
|
||||||
|
"src/favicon.ico"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": [
|
||||||
|
"src/tsconfig.app.json",
|
||||||
|
"src/tsconfig.spec.json"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/node_modules/**",
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"electronProd": {
|
"schematics": {
|
||||||
"optimization": true,
|
"@schematics/angular:component": {
|
||||||
"outputHashing": "all",
|
"style": "scss"
|
||||||
"sourceMap": false,
|
|
||||||
"extractCss": true,
|
|
||||||
"namedChunks": false,
|
|
||||||
"aot": true,
|
|
||||||
"extractLicenses": true,
|
|
||||||
"vendorChunk": false,
|
|
||||||
"buildOptimizer": true,
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.electron.prod.ts"
|
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
|
||||||
"electronDev": {
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.electron.ts"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"githubProd": {
|
|
||||||
"optimization": true,
|
|
||||||
"outputHashing": "all",
|
|
||||||
"sourceMap": false,
|
|
||||||
"extractCss": true,
|
|
||||||
"namedChunks": false,
|
|
||||||
"aot": true,
|
|
||||||
"extractLicenses": true,
|
|
||||||
"vendorChunk": false,
|
|
||||||
"buildOptimizer": true,
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.github.prod.ts"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"serve": {
|
"gns3-web-ui-e2e": {
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
"root": "e2e",
|
||||||
"options": {
|
"sourceRoot": "e2e",
|
||||||
"browserTarget": "gns3-web-ui:build"
|
"projectType": "application",
|
||||||
},
|
"architect": {
|
||||||
"configurations": {
|
"e2e": {
|
||||||
"production": {
|
"builder": "@angular-devkit/build-angular:protractor",
|
||||||
"browserTarget": "gns3-web-ui:build:production"
|
"options": {
|
||||||
},
|
"protractorConfig": "./protractor.conf.js",
|
||||||
"electronProd": {
|
"devServerTarget": "gns3-web-ui:serve"
|
||||||
"browserTarget": "gns3-web-ui:build:electronProd"
|
}
|
||||||
},
|
},
|
||||||
"electronDev": {
|
"lint": {
|
||||||
"browserTarget": "gns3-web-ui:build:electronDev"
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
},
|
"options": {
|
||||||
"githubProd": {
|
"tsConfig": [
|
||||||
"browserTarget": "gns3-web-ui:build:githubProd"
|
"e2e/tsconfig.e2e.json"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/node_modules/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
"extract-i18n": {
|
|
||||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
|
||||||
"options": {
|
|
||||||
"browserTarget": "gns3-web-ui:build"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"builder": "@angular-devkit/build-angular:karma",
|
|
||||||
"options": {
|
|
||||||
"main": "src/test.ts",
|
|
||||||
"karmaConfig": "./karma.conf.js",
|
|
||||||
"polyfills": "src/polyfills.ts",
|
|
||||||
"tsConfig": "src/tsconfig.spec.json",
|
|
||||||
"scripts": [],
|
|
||||||
"styles": [
|
|
||||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
|
||||||
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
|
||||||
"src/styles.css",
|
|
||||||
"src/theme.scss"
|
|
||||||
],
|
|
||||||
"assets": [
|
|
||||||
"src/assets",
|
|
||||||
"src/favicon.ico"
|
|
||||||
],
|
|
||||||
"codeCoverageExclude": [
|
|
||||||
"src/app/cartography/components/experimental-map/**/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": [
|
|
||||||
"src/tsconfig.app.json",
|
|
||||||
"src/tsconfig.spec.json"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"gns3-web-ui-e2e": {
|
"defaultProject": "gns3-web-ui",
|
||||||
"root": "e2e",
|
"schematics": {
|
||||||
"sourceRoot": "e2e",
|
"@schematics/angular:component": {
|
||||||
"projectType": "application",
|
"prefix": "app",
|
||||||
"architect": {
|
"style": "scss"
|
||||||
"e2e": {
|
|
||||||
"builder": "@angular-devkit/build-angular:protractor",
|
|
||||||
"options": {
|
|
||||||
"protractorConfig": "./protractor.conf.js",
|
|
||||||
"devServerTarget": "gns3-web-ui:serve"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"lint": {
|
"@schematics/angular:directive": {
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
"prefix": "app"
|
||||||
"options": {
|
|
||||||
"tsConfig": [
|
|
||||||
"e2e/tsconfig.e2e.json"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultProject": "gns3-web-ui",
|
|
||||||
"schematics": {
|
|
||||||
"@schematics/angular:component": {
|
|
||||||
"prefix": "app",
|
|
||||||
"styleext": "scss"
|
|
||||||
},
|
},
|
||||||
"@schematics/angular:directive": {
|
"cli": {
|
||||||
"prefix": "app"
|
"analytics": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
1
debug.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
[1109/003452.026:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3)
|
@ -10,7 +10,7 @@ describe('GNS3 Web UI Application', () => {
|
|||||||
it('should have correct page title', async () => {
|
it('should have correct page title', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
await page.navigateTo();
|
await page.navigateTo();
|
||||||
|
|
||||||
// act
|
// act
|
||||||
let text = await page.getTitleText();
|
let text = await page.getTitleText();
|
||||||
|
|
||||||
|
43
e2e/controllers.e2e-spec.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { TestHelper } from './helpers/common.po';
|
||||||
|
import { ControllersPage } from './helpers/controller.po';
|
||||||
|
|
||||||
|
describe('Controllers page', () => {
|
||||||
|
let page: ControllersPage;
|
||||||
|
let helper: TestHelper;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
page = new ControllersPage();
|
||||||
|
helper = new TestHelper();
|
||||||
|
});
|
||||||
|
|
||||||
|
xit('user should have possibility to add controller', async () => {
|
||||||
|
// arrange
|
||||||
|
page.maximizeWindow();
|
||||||
|
await page.navigateToControllersPage();
|
||||||
|
|
||||||
|
// act
|
||||||
|
let text = await page.getAddControllerNotificationText();
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(text).toBe("We've discovered GNS3 controller on 127.0.0.1:3080, would you like to add to the list?");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('user should see added controller in the list', async () => {
|
||||||
|
// arrange
|
||||||
|
page.maximizeWindow();
|
||||||
|
await page.navigateToControllersPage();
|
||||||
|
await page.clickAddController();
|
||||||
|
helper.sleep(1000);
|
||||||
|
|
||||||
|
// act
|
||||||
|
let firstRowOfControllersTable = await page.checkControllersTable();
|
||||||
|
let controllerData = [];
|
||||||
|
await helper.asyncForEach(firstRowOfControllersTable, async (element) => {
|
||||||
|
controllerData.push(await element.getText());
|
||||||
|
});
|
||||||
|
|
||||||
|
// assert
|
||||||
|
expect(controllerData).toContain('127.0.0.1');
|
||||||
|
expect(controllerData).toContain('3080');
|
||||||
|
});
|
||||||
|
});
|
@ -1,22 +1,21 @@
|
|||||||
import { browser, by, element } from 'protractor';
|
import { browser } from 'protractor';
|
||||||
import { ServersPage } from './server.po';
|
|
||||||
|
|
||||||
export class TestHelper {
|
export class TestHelper {
|
||||||
sleep(value: number) {
|
sleep(value: number) {
|
||||||
browser.sleep(value);
|
browser.sleep(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
waitForLoading() {
|
waitForLoading() {
|
||||||
browser.waitForAngular();
|
browser.waitForAngular();
|
||||||
}
|
}
|
||||||
|
|
||||||
async asyncForEach(array, callback) {
|
async asyncForEach(array, callback) {
|
||||||
for (let index = 0; index < array.length; index++) {
|
for (let index = 0; index < array.length; index++) {
|
||||||
await callback(array[index], index, array);
|
await callback(array[index], index, array);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getCurrentUrl() {
|
getCurrentUrl() {
|
||||||
return browser.getCurrentUrl();
|
return browser.getCurrentUrl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
41
e2e/helpers/controller.po.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { browser, by } from 'protractor';
|
||||||
|
import { TestHelper } from './common.po';
|
||||||
|
|
||||||
|
export class ControllersPage {
|
||||||
|
helper = new TestHelper();
|
||||||
|
|
||||||
|
maximizeWindow() {
|
||||||
|
browser.driver.manage().window().maximize();
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateToControllersPage() {
|
||||||
|
return browser.get('/controllers');
|
||||||
|
}
|
||||||
|
|
||||||
|
getAddControllerNotificationText() {
|
||||||
|
return browser.driver.findElement(by.className('mat-card-content')).getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
async clickAddController() {
|
||||||
|
let controllerTable = await this.checkControllersTable();
|
||||||
|
if (controllerTable.length === 0) {
|
||||||
|
let buttons = await browser.driver.findElements(by.className('mat-button mat-button-base'));
|
||||||
|
await buttons[3].click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkControllersTable() {
|
||||||
|
return browser.driver.findElements(by.css('mat-cell'));
|
||||||
|
}
|
||||||
|
|
||||||
|
async navigateToControllerProjects() {
|
||||||
|
this.helper.sleep(2000);
|
||||||
|
let hyperlinks = await browser.driver.findElements(by.css('a.table-link'));
|
||||||
|
let controllerLink;
|
||||||
|
await this.helper.asyncForEach(hyperlinks, async (element) => {
|
||||||
|
let text = await element.getText();
|
||||||
|
if (text === '127.0.0.1') controllerLink = element;
|
||||||
|
});
|
||||||
|
await controllerLink.click();
|
||||||
|
}
|
||||||
|
}
|
@ -1,50 +1,50 @@
|
|||||||
import { TestHelper } from "./common.po"
|
import { browser, by } from 'protractor';
|
||||||
import { browser, by } from "protractor";
|
import { TestHelper } from './common.po';
|
||||||
|
|
||||||
export class ProjectMapPage {
|
export class ProjectMapPage {
|
||||||
helper = new TestHelper();
|
helper = new TestHelper();
|
||||||
|
|
||||||
async openAddProjectDialog() {
|
async openAddProjectDialog() {
|
||||||
let addButton = await browser.driver.findElement(by.css('button.addNode'));
|
let addButton = await browser.driver.findElement(by.css('button.addNode'));
|
||||||
await addButton.click();
|
await addButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async addNode() {
|
||||||
|
let inputs = await browser.driver.findElements(by.css('input.mat-input-element'));
|
||||||
|
await inputs[0].sendKeys('VPCS');
|
||||||
|
this.helper.sleep(1000);
|
||||||
|
|
||||||
|
let selects = await browser.driver.findElements(by.css('mat-select.mat-select'));
|
||||||
|
await selects[1].click();
|
||||||
|
this.helper.sleep(1000);
|
||||||
|
|
||||||
|
let options = await browser.driver.findElements(by.css('mat-option.mat-option'));
|
||||||
|
await options[1].click(); //first option should be chosen
|
||||||
|
this.helper.sleep(1000);
|
||||||
|
|
||||||
|
// new select appears after refreshing data
|
||||||
|
selects = await browser.driver.findElements(by.css('mat-select.mat-select'));
|
||||||
|
if (selects[2]) {
|
||||||
|
await selects[2].click();
|
||||||
|
this.helper.sleep(1000);
|
||||||
|
|
||||||
|
options = await browser.driver.findElements(by.css('mat-option.mat-option'));
|
||||||
|
await options[0].click();
|
||||||
|
this.helper.sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
async addNode() {
|
let addButton = await browser.driver.findElement(by.css('button.addButton'));
|
||||||
let inputs = await browser.driver.findElements(by.css('input.mat-input-element'));
|
await addButton.click();
|
||||||
await inputs[0].sendKeys('VPCS');
|
this.helper.sleep(1000);
|
||||||
this.helper.sleep(1000);
|
}
|
||||||
|
|
||||||
let selects = await browser.driver.findElements(by.css('mat-select.mat-select'));
|
async verifyIfNodeWithLabelExists(labelToFind: string) {
|
||||||
await selects[1].click();
|
this.helper.sleep(5000);
|
||||||
this.helper.sleep(1000);
|
let nodeLabel = await browser.driver.findElement(by.css('#map > g > g.layer > g.nodes > g > g > g > g > text'));
|
||||||
|
let selectedNode;
|
||||||
|
let textFromNodeLabel = await nodeLabel.getText();
|
||||||
|
if (textFromNodeLabel == labelToFind) selectedNode = nodeLabel;
|
||||||
|
|
||||||
let options = await browser.driver.findElements(by.css('mat-option.mat-option'));
|
return selectedNode ? true : false;
|
||||||
await options[1].click(); //first option should be chosen
|
}
|
||||||
this.helper.sleep(1000);
|
|
||||||
|
|
||||||
// new select appears after refreshing data
|
|
||||||
selects = await browser.driver.findElements(by.css('mat-select.mat-select'));
|
|
||||||
if (selects[2]) {
|
|
||||||
await selects[2].click();
|
|
||||||
this.helper.sleep(1000);
|
|
||||||
|
|
||||||
options = await browser.driver.findElements(by.css('mat-option.mat-option'));
|
|
||||||
await options[0].click();
|
|
||||||
this.helper.sleep(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
let addButton = await browser.driver.findElement(by.css('button.addButton'));
|
|
||||||
await addButton.click();
|
|
||||||
this.helper.sleep(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
async verifyIfNodeWithLabelExists(labelToFind: string) {
|
|
||||||
this.helper.sleep(5000);
|
|
||||||
let nodeLabel = await browser.driver.findElement(by.css('#map > g > g.layer > g.nodes > g > g > g > g > text'));
|
|
||||||
let selectedNode;
|
|
||||||
let textFromNodeLabel = await nodeLabel.getText();
|
|
||||||
if (textFromNodeLabel == labelToFind) selectedNode = nodeLabel;
|
|
||||||
|
|
||||||
return selectedNode ? true : false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import { TestHelper } from "./common.po"
|
import { browser, by } from 'protractor';
|
||||||
import { browser, by } from "protractor";
|
import { TestHelper } from './common.po';
|
||||||
|
|
||||||
export class ProjectsPage {
|
export class ProjectsPage {
|
||||||
helper = new TestHelper();
|
helper = new TestHelper();
|
||||||
|
|
||||||
async openAddProjectDialog() {
|
async openAddProjectDialog() {
|
||||||
let addButton = await browser.driver.findElement(by.css('button.add-button'));
|
let addButton = await browser.driver.findElement(by.css('button.add-button'));
|
||||||
await addButton.click();
|
await addButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async createProject() {
|
async createProject() {
|
||||||
let today = new Date();
|
let today = new Date();
|
||||||
let inputs = await browser.driver.findElements(by.css('input.mat-input-element'));
|
let inputs = await browser.driver.findElements(by.css('input.mat-input-element'));
|
||||||
await inputs[1].sendKeys('test project ' + today.getUTCMilliseconds());
|
await inputs[1].sendKeys('test project ' + today.getUTCMilliseconds());
|
||||||
this.helper.sleep(2000);
|
this.helper.sleep(2000);
|
||||||
let dialogButton = await browser.driver.findElement(by.css('button.add-project-button'));
|
let dialogButton = await browser.driver.findElement(by.css('button.add-project-button'));
|
||||||
await dialogButton.click();
|
await dialogButton.click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
import { browser, by, element } from 'protractor';
|
|
||||||
import { TestHelper } from './common.po';
|
|
||||||
|
|
||||||
export class ServersPage {
|
|
||||||
helper = new TestHelper;
|
|
||||||
|
|
||||||
maximizeWindow() {
|
|
||||||
browser.driver.manage().window().maximize();
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToServersPage() {
|
|
||||||
return browser.get('/servers');
|
|
||||||
}
|
|
||||||
|
|
||||||
getAddServerNotificationText() {
|
|
||||||
return browser.driver.findElement(by.className('mat-card-content')).getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
async clickAddServer() {
|
|
||||||
let serversTable = await this.checkServersTable();
|
|
||||||
if (serversTable.length === 0) {
|
|
||||||
let buttons = await browser.driver.findElements(by.className('mat-button mat-button-base'));
|
|
||||||
await buttons[3].click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkServersTable() {
|
|
||||||
return browser.driver.findElements(by.css('mat-cell'));
|
|
||||||
}
|
|
||||||
|
|
||||||
async navigateToServerProjects() {
|
|
||||||
this.helper.sleep(2000);
|
|
||||||
let hyperlinks = await browser.driver.findElements(by.css('a.table-link'));
|
|
||||||
let serverLink;
|
|
||||||
await this.helper.asyncForEach(hyperlinks, async element => {
|
|
||||||
let text = await element.getText();
|
|
||||||
if (text === '127.0.0.1') serverLink = element;
|
|
||||||
});
|
|
||||||
await serverLink.click();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +1,40 @@
|
|||||||
import { ServersPage } from './helpers/server.po';
|
|
||||||
import { TestHelper } from './helpers/common.po';
|
import { TestHelper } from './helpers/common.po';
|
||||||
import { element } from 'protractor';
|
|
||||||
import { ProjectsPage } from './helpers/project.po';
|
|
||||||
import { ProjectMapPage } from './helpers/project-map.po';
|
import { ProjectMapPage } from './helpers/project-map.po';
|
||||||
|
import { ProjectsPage } from './helpers/project.po';
|
||||||
|
import { ControllersPage } from './helpers/controller.po';
|
||||||
|
|
||||||
describe('Project map page', () => {
|
describe('Project map page', () => {
|
||||||
let serversPage: ServersPage;
|
let controllersPage: ControllersPage;
|
||||||
let projectsPage: ProjectsPage;
|
let projectsPage: ProjectsPage;
|
||||||
let projectMapPage: ProjectMapPage;
|
let projectMapPage: ProjectMapPage;
|
||||||
let helper: TestHelper;
|
let helper: TestHelper;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
serversPage = new ServersPage();
|
controllersPage = new ControllersPage();
|
||||||
projectsPage = new ProjectsPage();
|
projectsPage = new ProjectsPage();
|
||||||
projectMapPage = new ProjectMapPage();
|
projectMapPage = new ProjectMapPage();
|
||||||
helper = new TestHelper();
|
helper = new TestHelper();
|
||||||
|
|
||||||
serversPage.maximizeWindow();
|
controllersPage.maximizeWindow();
|
||||||
await serversPage.navigateToServersPage();
|
await controllersPage.navigateToControllersPage();
|
||||||
await serversPage.clickAddServer();
|
await controllersPage.clickAddController();
|
||||||
await serversPage.navigateToServerProjects();
|
await controllersPage.navigateToControllerProjects();
|
||||||
await projectsPage.openAddProjectDialog();
|
await projectsPage.openAddProjectDialog();
|
||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
await projectsPage.createProject();
|
await projectsPage.createProject();
|
||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('user should have possibility to add nodes to map', async () => {
|
it('user should have possibility to add nodes to map', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
projectMapPage.openAddProjectDialog();
|
projectMapPage.openAddProjectDialog();
|
||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
|
|
||||||
//act
|
//act
|
||||||
projectMapPage.addNode();
|
projectMapPage.addNode();
|
||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
expect(await projectMapPage.verifyIfNodeWithLabelExists('PC1')).toBe(true);
|
expect(await projectMapPage.verifyIfNodeWithLabelExists('PC1')).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,34 +1,33 @@
|
|||||||
import { ServersPage } from './helpers/server.po';
|
|
||||||
import { TestHelper } from './helpers/common.po';
|
import { TestHelper } from './helpers/common.po';
|
||||||
import { element } from 'protractor';
|
|
||||||
import { ProjectsPage } from './helpers/project.po';
|
import { ProjectsPage } from './helpers/project.po';
|
||||||
|
import { ControllersPage } from './helpers/controller.po';
|
||||||
|
|
||||||
describe('Projects page', () => {
|
describe('Projects page', () => {
|
||||||
let serversPage: ServersPage;
|
let controllersPage: ControllersPage;
|
||||||
let projectsPage: ProjectsPage;
|
let projectsPage: ProjectsPage;
|
||||||
let helper: TestHelper;
|
let helper: TestHelper;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
serversPage = new ServersPage();
|
controllersPage = new ControllersPage();
|
||||||
projectsPage = new ProjectsPage();
|
projectsPage = new ProjectsPage();
|
||||||
helper = new TestHelper();
|
helper = new TestHelper();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('user should have possibility to create new project', async () => {
|
it('user should have possibility to create new project', async () => {
|
||||||
// arrange
|
// arrange
|
||||||
serversPage.maximizeWindow();
|
controllersPage.maximizeWindow();
|
||||||
await serversPage.navigateToServersPage();
|
await controllersPage.navigateToControllersPage();
|
||||||
await serversPage.clickAddServer();
|
await controllersPage.clickAddController();
|
||||||
await serversPage.navigateToServerProjects();
|
await controllersPage.navigateToControllerProjects();
|
||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
|
|
||||||
//act
|
//act
|
||||||
await projectsPage.openAddProjectDialog();
|
await projectsPage.openAddProjectDialog();
|
||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
await projectsPage.createProject();
|
await projectsPage.createProject();
|
||||||
helper.sleep(2000);
|
helper.sleep(2000);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
expect(helper.getCurrentUrl()).toMatch('server/1/project/');
|
expect(helper.getCurrentUrl()).toMatch('controller/1/project/');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
import { ServersPage } from './helpers/server.po';
|
|
||||||
import { TestHelper } from './helpers/common.po';
|
|
||||||
import { element } from 'protractor';
|
|
||||||
|
|
||||||
describe('Servers page', () => {
|
|
||||||
let page: ServersPage;
|
|
||||||
let helper: TestHelper;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
page = new ServersPage();
|
|
||||||
helper = new TestHelper();
|
|
||||||
});
|
|
||||||
|
|
||||||
xit('user should have possibility to add server', async () => {
|
|
||||||
// arrange
|
|
||||||
page.maximizeWindow();
|
|
||||||
await page.navigateToServersPage();
|
|
||||||
|
|
||||||
// act
|
|
||||||
let text = await page.getAddServerNotificationText();
|
|
||||||
|
|
||||||
// assert
|
|
||||||
expect(text).toBe("We've discovered GNS3 server on 127.0.0.1:3080, would you like to add to the list?");
|
|
||||||
});
|
|
||||||
|
|
||||||
it('user should see added server in the list', async () => {
|
|
||||||
// arrange
|
|
||||||
page.maximizeWindow();
|
|
||||||
await page.navigateToServersPage();
|
|
||||||
await page.clickAddServer();
|
|
||||||
helper.sleep(1000);
|
|
||||||
|
|
||||||
// act
|
|
||||||
let firstRowOfServersTable = await page.checkServersTable();
|
|
||||||
let serverData = [];
|
|
||||||
await helper.asyncForEach(firstRowOfServersTable, async element => {
|
|
||||||
serverData.push(await element.getText());
|
|
||||||
});
|
|
||||||
|
|
||||||
// assert
|
|
||||||
expect(serverData).toContain('127.0.0.1');
|
|
||||||
expect(serverData).toContain('3080');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"extends": "../tsconfig.json",
|
"extends": "../tsconfig.base.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../out-tsc/e2e",
|
"outDir": "../out-tsc/e2e",
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
|
@ -15,7 +15,7 @@ files:
|
|||||||
- renderer.js
|
- renderer.js
|
||||||
- sentry.js
|
- sentry.js
|
||||||
- installed-software.js
|
- installed-software.js
|
||||||
- local-server.js
|
- local-controller.js
|
||||||
- console-executor.js
|
- console-executor.js
|
||||||
- package.json
|
- package.json
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ module.exports = function (config) {
|
|||||||
colors: true,
|
colors: true,
|
||||||
logLevel: config.LOG_INFO,
|
logLevel: config.LOG_INFO,
|
||||||
autoWatch: true,
|
autoWatch: true,
|
||||||
browsers: ['Chrome'],
|
browsers: ['ChromeHeadless'],
|
||||||
singleRun: false
|
singleRun: true
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -8,9 +8,9 @@ const { app } = require('electron')
|
|||||||
|
|
||||||
const isWin = /^win/.test(process.platform);
|
const isWin = /^win/.test(process.platform);
|
||||||
|
|
||||||
let runningServers = {};
|
let runningControllers = {};
|
||||||
|
|
||||||
exports.getLocalServerPath = async () => {
|
exports.getLocalControllerPath = async () => {
|
||||||
let binary = isWin ? 'gns3server.exe': 'gns3server';
|
let binary = isWin ? 'gns3server.exe': 'gns3server';
|
||||||
return findBinary('exe.', binary);
|
return findBinary('exe.', binary);
|
||||||
}
|
}
|
||||||
@ -20,27 +20,27 @@ exports.getUbridgePath = async () => {
|
|||||||
return findBinary('ubridge', binary);
|
return findBinary('ubridge', binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.startLocalServer = async (server) => {
|
exports.startLocalController = async (controller) => {
|
||||||
return await run(server, {
|
return await run(controller, {
|
||||||
logStdout: true
|
logStdout: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.stopLocalServer = async (server) => {
|
exports.stopLocalController = async (controller) => {
|
||||||
return await stop(server.name);
|
return await stop(controller.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getRunningServers = () => {
|
exports.getRunningControllers = () => {
|
||||||
return Object.keys(runningServers);
|
return Object.keys(runningControllers);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.stopAllLocalServers = async () => {
|
exports.stopAllLocalControllers = async () => {
|
||||||
return await stopAll();
|
return await stopAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findBinary(binaryDirectory, filename) {
|
async function findBinary(binaryDirectory, filename) {
|
||||||
const lookupDirectories = [
|
const lookupDirectories = [
|
||||||
__dirname,
|
__dirname,
|
||||||
path.dirname(app.getPath('exe'))
|
path.dirname(app.getPath('exe'))
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ async function findBinaryInDirectory(baseDirectory, binaryDirectory, filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const files = fs.readdirSync(distDirectory);
|
const files = fs.readdirSync(distDirectory);
|
||||||
|
|
||||||
let binaryPath = null;
|
let binaryPath = null;
|
||||||
|
|
||||||
files.forEach((directory) => {
|
files.forEach((directory) => {
|
||||||
@ -77,33 +77,33 @@ async function findBinaryInDirectory(baseDirectory, binaryDirectory, filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getServerArguments(server, overrides, configPath) {
|
function getControllerArguments(controller, overrides, configPath) {
|
||||||
let serverArguments = [];
|
let controllerArguments = [];
|
||||||
if(server.host) {
|
if(controller.host) {
|
||||||
serverArguments.push('--host');
|
controllerArguments.push('--host');
|
||||||
serverArguments.push(server.host);
|
controllerArguments.push(controller.host);
|
||||||
}
|
}
|
||||||
if(server.port) {
|
if(controller.port) {
|
||||||
serverArguments.push('--port');
|
controllerArguments.push('--port');
|
||||||
serverArguments.push(server.port);
|
controllerArguments.push(controller.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
serverArguments.push('--local');
|
controllerArguments.push('--local');
|
||||||
|
|
||||||
if(configPath) {
|
if(configPath) {
|
||||||
serverArguments.push('--config');
|
controllerArguments.push('--config');
|
||||||
serverArguments.push(configPath);
|
controllerArguments.push(configPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return serverArguments;
|
return controllerArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannelForServer(server) {
|
function getChannelForController(controller) {
|
||||||
return `local-server-run-${server.name}`;
|
return `local-controller-run-${controller.name}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function notifyStatus(status) {
|
function notifyStatus(status) {
|
||||||
ipcMain.emit('local-server-status-events', status);
|
ipcMain.emit('local-controller-status-events', status);
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterOutput(line) {
|
function filterOutput(line) {
|
||||||
@ -120,44 +120,44 @@ function filterOutput(line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function stopAll() {
|
async function stopAll() {
|
||||||
for(var serverName in runningServers) {
|
for(var controllerName in runningControllers) {
|
||||||
let result, error = await stop(serverName);
|
let result, error = await stop(controllerName);
|
||||||
}
|
}
|
||||||
console.log(`Stopped all servers`);
|
console.log(`Stopped all controllers`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stop(serverName) {
|
async function stop(controllerName) {
|
||||||
let pid = undefined;
|
let pid = undefined;
|
||||||
|
|
||||||
const runningServer = runningServers[serverName];
|
const runningController = runningControllers[controllerName];
|
||||||
|
|
||||||
if(runningServer !== undefined && runningServer.process) {
|
if(runningController !== undefined && runningController.process) {
|
||||||
pid = runningServer.process.pid;
|
pid = runningController.process.pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Stopping '${serverName}' with PID='${pid}'`);
|
console.log(`Stopping '${controllerName}' with PID='${pid}'`);
|
||||||
|
|
||||||
const stopped = new Promise((resolve, reject) => {
|
const stopped = new Promise((resolve, reject) => {
|
||||||
if(pid === undefined) {
|
if(pid === undefined) {
|
||||||
resolve(`Server '${serverName} is already stopped`);
|
resolve(`Controller '${controllerName} is already stopped`);
|
||||||
delete runningServers[serverName];
|
delete runningControllers[controllerName];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
kill(pid, (error) => {
|
kill(pid, (error) => {
|
||||||
if(error) {
|
if(error) {
|
||||||
console.error(`Error occured during stopping '${serverName}' with PID='${pid}'`);
|
console.error(`Error occured during stopping '${controllerName}' with PID='${pid}'`);
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
delete runningServers[serverName];
|
delete runningControllers[controllerName];
|
||||||
console.log(`Stopped '${serverName}' with PID='${pid}'`);
|
console.log(`Stopped '${controllerName}' with PID='${pid}'`);
|
||||||
resolve(`Stopped '${serverName}' with PID='${pid}'`);
|
resolve(`Stopped '${controllerName}' with PID='${pid}'`);
|
||||||
|
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
serverName: serverName,
|
controllerName: controllerName,
|
||||||
status: 'stopped',
|
status: 'stopped',
|
||||||
message: `Server '${serverName}' stopped'`
|
message: `Controller '${controllerName}' stopped'`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -166,11 +166,11 @@ async function stop(serverName) {
|
|||||||
return stopped;
|
return stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getIniFile(server) {
|
async function getIniFile(controller) {
|
||||||
return path.join(app.getPath('userData'), `gns3_server_${server.id}.ini`);
|
return path.join(app.getPath('userData'), `gns3_controller_${controller.id}.ini`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function configure(configPath, server) {
|
async function configure(configPath, controller) {
|
||||||
if(!fs.existsSync(configPath)) {
|
if(!fs.existsSync(configPath)) {
|
||||||
fs.closeSync(fs.openSync(configPath, 'w'));
|
fs.closeSync(fs.openSync(configPath, 'w'));
|
||||||
console.log(`Configuration file '${configPath}' has been created.`);
|
console.log(`Configuration file '${configPath}' has been created.`);
|
||||||
@ -178,20 +178,20 @@ async function configure(configPath, server) {
|
|||||||
|
|
||||||
var config = ini.parse(fs.readFileSync(configPath, 'utf-8'));
|
var config = ini.parse(fs.readFileSync(configPath, 'utf-8'));
|
||||||
|
|
||||||
if(server.path) {
|
if(controller.path) {
|
||||||
config.path = server.path;
|
config.path = controller.path;
|
||||||
}
|
}
|
||||||
if(server.host) {
|
if(controller.host) {
|
||||||
config.host = server.host;
|
config.host = controller.host;
|
||||||
}
|
}
|
||||||
if(server.port) {
|
if(controller.port) {
|
||||||
config.port = server.port;
|
config.port = controller.port;
|
||||||
}
|
}
|
||||||
if(server.ubridge_path) {
|
if(controller.ubridge_path) {
|
||||||
config.ubridge_path = server.ubridge_path;
|
config.ubridge_path = controller.ubridge_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(configPath, ini.stringify(config, { section: 'Server' }));
|
fs.writeFileSync(configPath, ini.stringify(config, { section: 'Controller' }));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setPATHEnv() {
|
async function setPATHEnv() {
|
||||||
@ -216,7 +216,7 @@ async function setPATHEnv() {
|
|||||||
process.env.PATH = extra.join(";");
|
process.env.PATH = extra.join(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function run(server, options) {
|
async function run(controller, options) {
|
||||||
if(!options) {
|
if(!options) {
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
@ -226,34 +226,34 @@ async function run(server, options) {
|
|||||||
|
|
||||||
console.log(`Configuring`);
|
console.log(`Configuring`);
|
||||||
|
|
||||||
const configPath = await getIniFile(server);
|
const configPath = await getIniFile(controller);
|
||||||
await configure(configPath, server);
|
await configure(configPath, controller);
|
||||||
|
|
||||||
console.log(`Setting up PATH`);
|
console.log(`Setting up PATH`);
|
||||||
await setPATHEnv();
|
await setPATHEnv();
|
||||||
|
|
||||||
console.log(`Running '${server.path}'`);
|
console.log(`Running '${controller.path}'`);
|
||||||
|
|
||||||
let serverProcess = spawn(server.path, getServerArguments(server, {}, configPath));
|
let controllerProcess = spawn(controller.path, getControllerArguments(controller, {}, configPath));
|
||||||
|
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
serverName: server.name,
|
controllerName: controller.name,
|
||||||
status: 'started',
|
status: 'started',
|
||||||
message: `Server '${server.name}' started'`
|
message: `Controller '${controller.name}' started'`
|
||||||
});
|
});
|
||||||
|
|
||||||
runningServers[server.name] = {
|
runningControllers[controller.name] = {
|
||||||
process: serverProcess
|
process: controllerProcess
|
||||||
};
|
};
|
||||||
|
|
||||||
serverProcess.stdout.on('data', function(data) {
|
controllerProcess.stdout.on('data', function(data) {
|
||||||
const line = data.toString();
|
const line = data.toString();
|
||||||
const { isCritical, errorMessage } = filterOutput(line);
|
const { isCritical, errorMessage } = filterOutput(line);
|
||||||
if(isCritical) {
|
if(isCritical) {
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
serverName: server.name,
|
controllerName: controller.name,
|
||||||
status: 'stderr',
|
status: 'stderr',
|
||||||
message: `Server reported error: '${errorMessage}`
|
message: `Controller reported error: '${errorMessage}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,25 +262,25 @@ async function run(server, options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
serverProcess.stderr.on('data', function(data) {
|
controllerProcess.stderr.on('data', function(data) {
|
||||||
if(logSterr) {
|
if(logSterr) {
|
||||||
console.log(data.toString());
|
console.log(data.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
serverProcess.on('exit', (code, signal) => {
|
controllerProcess.on('exit', (code, signal) => {
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
serverName: server.name,
|
controllerName: controller.name,
|
||||||
status: 'errored',
|
status: 'errored',
|
||||||
message: `Server '${server.name}' has exited with status='${code}'`
|
message: `controller '${controller.name}' has exited with status='${code}'`
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
serverProcess.on('error', (err) => {
|
controllerProcess.on('error', (err) => {
|
||||||
notifyStatus({
|
notifyStatus({
|
||||||
serverName: server.name,
|
controllerName: controller.name,
|
||||||
status: 'errored',
|
status: 'errored',
|
||||||
message: `Server errored: '${err}`
|
message: `Controller errored: '${err}`
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -297,9 +297,9 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ipcMain) {
|
if(ipcMain) {
|
||||||
ipcMain.on('local-server-run', async function (event, server) {
|
ipcMain.on('local-controller-run', async function (event, controller) {
|
||||||
const responseChannel = getChannelForServer();
|
const responseChannel = getChannelForController();
|
||||||
await run(server);
|
await run(controller);
|
||||||
event.sender.send(responseChannel, {
|
event.sender.send(responseChannel, {
|
||||||
success: true
|
success: true
|
||||||
});
|
});
|
||||||
@ -318,4 +318,4 @@ if (require.main === module) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
main();
|
main();
|
||||||
}
|
}
|
165
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gns3-web-ui",
|
"name": "gns3-web-ui",
|
||||||
"version": "2020.1.0-alpha.1",
|
"version": "3.0.0a2",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "GNS3 Technology Inc.",
|
"name": "GNS3 Technology Inc.",
|
||||||
"email": "developers@gns3.com"
|
"email": "developers@gns3.com"
|
||||||
@ -17,6 +17,7 @@
|
|||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"startforelectron": "ng serve --configuration=electronDev",
|
"startforelectron": "ng serve --configuration=electronDev",
|
||||||
"build": "ng build",
|
"build": "ng build",
|
||||||
|
"buildforproduction": "ng build --source-map=false --configuration=production --base-href /static/web-ui/",
|
||||||
"buildforelectron": "ng build --configuration=electronProd",
|
"buildforelectron": "ng build --configuration=electronProd",
|
||||||
"buildforgithub": "ng build --configuration=githubProd",
|
"buildforgithub": "ng build --configuration=githubProd",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
@ -34,92 +35,106 @@
|
|||||||
"prettier:write": "yarn prettier:base -- --write \"src/**/*.{ts,js,html,scss}\"",
|
"prettier:write": "yarn prettier:base -- --write \"src/**/*.{ts,js,html,scss}\"",
|
||||||
"generate-licenses-file": "yarn license-checker --production --csv --out licenses.csv",
|
"generate-licenses-file": "yarn license-checker --production --csv --out licenses.csv",
|
||||||
"prebuildforelectron": "node set-variables-in-env.js --set src/environments/environment.electron.prod.ts",
|
"prebuildforelectron": "node set-variables-in-env.js --set src/environments/environment.electron.prod.ts",
|
||||||
"postbuildforelectron": "node set-variables-in-env.js --unset src/environments/environment.electron.prod.ts"
|
"postbuildforelectron": "node set-variables-in-env.js --unset src/environments/environment.electron.prod.ts",
|
||||||
|
"postinstall": "ngcc --properties es5 browser module main --first-only --create-ivy-entry-points --tsconfig \"./src/tsconfig.app.json\" && ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points --tsconfig \"./src/tsconfig.app.json\"",
|
||||||
|
"snyk-protect": "snyk-protect",
|
||||||
|
"prepare": "yarn run snyk-protect"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^8.2.11",
|
"@angular/animations": "^13.3.5",
|
||||||
"@angular/cdk": "^8.2.3",
|
"@angular/cdk": "^13.3.5",
|
||||||
"@angular/common": "^8.2.11",
|
"@angular/common": "^13.3.5",
|
||||||
"@angular/compiler": "^8.2.11",
|
"@angular/compiler": "^13.3.5",
|
||||||
"@angular/core": "^8.2.11",
|
"@angular/core": "^13.3.5",
|
||||||
"@angular/forms": "^8.2.11",
|
"@angular/forms": "^13.3.5",
|
||||||
"@angular/http": "^7.2.15",
|
"@angular/material": "^13.3.5",
|
||||||
"@angular/material": "^8.2.3",
|
"@angular/platform-browser": "^13.3.5",
|
||||||
"@angular/platform-browser": "^8.2.11",
|
"@angular/platform-browser-dynamic": "^13.3.5",
|
||||||
"@angular/platform-browser-dynamic": "^8.2.11",
|
"@angular/router": "^13.3.5",
|
||||||
"@angular/router": "^8.2.11",
|
"@sentry/browser": "^6.14.1",
|
||||||
"angular-draggable-droppable": "^4.3.8",
|
"@snyk/protect": "^1.972.0",
|
||||||
"angular-persistence": "^1.0.1",
|
"@types/jest": "^27.0.2",
|
||||||
"angular-resizable-element": "^3.2.6",
|
"@types/mocha": "^9.1.1",
|
||||||
"angular2-draggable": "^2.3.2",
|
"@types/react": "^17.0.34",
|
||||||
"angular2-hotkeys": "^2.1.5",
|
"@types/react-dom": "^17.0.11",
|
||||||
"angular2-indexeddb": "^1.2.3",
|
"angular-draggable-droppable": "^6.1.0",
|
||||||
"bootstrap": "4.3.1",
|
"angular-resizable-element": "^3.4.0",
|
||||||
"command-exists": "^1.2.8",
|
"autoprefixer": "10.4.5",
|
||||||
"core-js": "^3.3.2",
|
"bootstrap": "^5.1.3",
|
||||||
"css-tree": "^1.0.0-alpha.36",
|
"command-exists": "^1.2.9",
|
||||||
"d3-ng2-service": "^2.1.0",
|
"core-js": "^3.22.3",
|
||||||
"file-saver": "^2.0.2",
|
"css-tree": "^2.1.0",
|
||||||
"hammerjs": "^2.0.8",
|
"d3-ng2-service": "^2.2.0",
|
||||||
"ini": "^1.3.5",
|
"eev": "^0.1.5",
|
||||||
|
"ini": "^3.0.0",
|
||||||
|
"marked": "^4.0.14",
|
||||||
"material-design-icons": "^3.0.1",
|
"material-design-icons": "^3.0.1",
|
||||||
"ng-circle-progress": "^1.5.1",
|
"mousetrap": "^1.6.5",
|
||||||
"ng2-file-upload": "^1.3.0",
|
"ng-circle-progress": "^1.6.0",
|
||||||
|
"ng2-file-upload": "^1.4.0",
|
||||||
"ngx-childprocess": "^0.0.6",
|
"ngx-childprocess": "^0.0.6",
|
||||||
"ngx-device-detector": "^1.3.18",
|
"ngx-device-detector": "^3.0.0",
|
||||||
"ngx-electron": "^2.1.1",
|
"ngx-electron": "^2.2.0",
|
||||||
"node-fetch": "^2.6.0",
|
"node-fetch": "^3.2.10",
|
||||||
"notosans-fontface": "^1.1.0",
|
"notosans-fontface": "^1.3.0",
|
||||||
"raven-js": "^3.27.2",
|
"postcss-loader": "^6.2.1",
|
||||||
"rxjs": "^6.5.3",
|
"prettier-plugin-organize-imports": "^2.3.4",
|
||||||
"rxjs-compat": "^6.5.3",
|
"rxjs": "^6.6.7",
|
||||||
"save-html-as-image": "^1.2.0",
|
"rxjs-compat": "^6.6.7",
|
||||||
"save-svg-as-png": "^1.4.14",
|
"save-svg-as-png": "^1.4.17",
|
||||||
"svg-crowbar": "^0.2.4",
|
"spark-md5": "^3.0.2",
|
||||||
"tree-kill": "^1.2.1",
|
"svg-crowbar": "^0.7.0",
|
||||||
"typeface-roboto": "^0.0.75",
|
"tree-kill": "^1.2.2",
|
||||||
"xterm": "^4.1.0",
|
"tslib": "^2.4.0",
|
||||||
"yargs": "^15.0.2",
|
"typeface-roboto": "^1.1.13",
|
||||||
"zone.js": "^0.10.2"
|
"xterm": "^4.18.0",
|
||||||
|
"xterm-addon-attach": "^0.6.0",
|
||||||
|
"xterm-addon-fit": "^0.5.0",
|
||||||
|
"yargs": "^17.4.1",
|
||||||
|
"zone.js": "^0.11.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^0.803.10",
|
"@angular-devkit/build-angular": "^13.3.4",
|
||||||
"@angular/cli": "^8.3.10",
|
"@angular/cli": "^13.3.4",
|
||||||
"@angular/compiler-cli": "^8.2.11",
|
"@angular/compiler-cli": "^13.3.5",
|
||||||
"@angular/language-service": "^8.2.11",
|
"@angular/language-service": "^13.3.5",
|
||||||
"@sentry/cli": "^1.48.0",
|
"@sentry/cli": "^2.0.4",
|
||||||
"@sentry/electron": "^0.17.4",
|
"@sentry/electron": "^3.0.7",
|
||||||
"@types/jasmine": "^3.4.4",
|
"@types/jasmine": "^4.0.3",
|
||||||
"@types/jasminewd2": "^2.0.8",
|
"@types/jasminewd2": "^2.0.10",
|
||||||
"@types/node": "^12.12.10",
|
"@types/node": "^17.0.31",
|
||||||
"codelyzer": "^5.1.2",
|
"codelyzer": "^0.0.28",
|
||||||
"electron": "7.1.2",
|
"electron": "13.6.6",
|
||||||
"electron-builder": "21.2.0",
|
"electron-builder": "^23.0.3",
|
||||||
"jasmine-core": "~3.5.0",
|
"file-loader": "^6.2.0",
|
||||||
"jasmine-spec-reporter": "~4.2.1",
|
"jasmine-core": "^4.1.0",
|
||||||
"jquery": "^3.4.1",
|
"jasmine-spec-reporter": "^7.0.0",
|
||||||
"karma": "~4.4.0",
|
"jquery": "^3.6.0",
|
||||||
"karma-chrome-launcher": "~3.1.0",
|
"karma": "^6.3.19",
|
||||||
"karma-cli": "~2.0.0",
|
"karma-chrome-launcher": "^3.1.1",
|
||||||
"karma-coverage-istanbul-reporter": "^2.1.0",
|
"karma-cli": "^2.0.0",
|
||||||
"karma-jasmine": "~2.0.1",
|
"karma-coverage-istanbul-reporter": "^3.0.3",
|
||||||
"karma-jasmine-html-reporter": "^1.4.2",
|
"karma-jasmine": "^5.0.0",
|
||||||
|
"karma-jasmine-html-reporter": "^1.7.0",
|
||||||
"license-checker": "^25.0.1",
|
"license-checker": "^25.0.1",
|
||||||
"node-sass": "^4.12.0",
|
"popper.js": "^1.16.1",
|
||||||
"popper.js": "^1.16.0",
|
"prettier": "^2.6.2",
|
||||||
"prettier": "^1.18.2",
|
"protractor": "^7.0.0",
|
||||||
"protractor": "~5.4.2",
|
"replace": "^1.2.1",
|
||||||
"replace": "^1.1.1",
|
"rxjs-tslint": "^0.1.8",
|
||||||
"ts-mockito": "^2.5.0",
|
"ts-mockito": "^2.6.1",
|
||||||
"ts-node": "~8.4.1",
|
"ts-node": "^10.7.0",
|
||||||
"tslint": "~5.20.0",
|
"tslint": "^6.1.3",
|
||||||
"tslint-config-prettier": "^1.18.0",
|
"tslint-config-prettier": "^1.18.0",
|
||||||
"typescript": ">=3.4.0 <3.6.0"
|
"typescript": "4.6.4",
|
||||||
|
"webpack": "^5.72.0",
|
||||||
|
"yarn-upgrade-all": "^0.7.1"
|
||||||
},
|
},
|
||||||
"greenkeeper": {
|
"greenkeeper": {
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"typescript"
|
"typescript"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"snyk": true
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ def download_from_github(name, definition, output_directory):
|
|||||||
files = []
|
files = []
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
files = definition['files']['windows']
|
files = definition['files']['windows']
|
||||||
|
|
||||||
for filename in files:
|
for filename in files:
|
||||||
dependency_file = os.path.join(dependency_dir, filename)
|
dependency_file = os.path.join(dependency_dir, filename)
|
||||||
dependency_url = list(filter(lambda x: x['name'] == filename, release['assets']))[0]['browser_download_url']
|
dependency_url = list(filter(lambda x: x['name'] == filename, release['assets']))[0]['browser_download_url']
|
||||||
@ -161,7 +161,7 @@ def download_from_http(name, definition, output_directory):
|
|||||||
files = []
|
files = []
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
files = definition['files']['windows']
|
files = definition['files']['windows']
|
||||||
|
|
||||||
for filename in files:
|
for filename in files:
|
||||||
dependency_file = os.path.join(dependency_dir, filename)
|
dependency_file = os.path.join(dependency_dir, filename)
|
||||||
download(url, dependency_file)
|
download(url, dependency_file)
|
||||||
@ -193,7 +193,7 @@ def is_tagged():
|
|||||||
return True
|
return True
|
||||||
if os.environ.get('APPVEYOR_REPO_TAG', False) in (1, "True", "true"):
|
if os.environ.get('APPVEYOR_REPO_TAG', False) in (1, "True", "true"):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def is_web_ui_non_dev():
|
def is_web_ui_non_dev():
|
||||||
package_file = os.path.join(FILE_DIR, '..', 'package.json')
|
package_file = os.path.join(FILE_DIR, '..', 'package.json')
|
||||||
@ -237,6 +237,8 @@ def download_command(arguments):
|
|||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
requirements = 'win-requirements.txt'
|
requirements = 'win-requirements.txt'
|
||||||
|
elif platform.system() == "Darwin":
|
||||||
|
requirements = 'mac-requirements.txt'
|
||||||
else:
|
else:
|
||||||
requirements = 'requirements.txt'
|
requirements = 'requirements.txt'
|
||||||
|
|
||||||
@ -277,13 +279,11 @@ def build_command(arguments):
|
|||||||
]
|
]
|
||||||
|
|
||||||
excludes = [
|
excludes = [
|
||||||
"raven.deprecation", # reported problem in raven package (6.4.0)
|
|
||||||
"distutils", # issue on macOS
|
"distutils", # issue on macOS
|
||||||
"tkinter", # issue on Windows
|
"tkinter", # issue on Windows
|
||||||
]
|
]
|
||||||
|
|
||||||
packages = [
|
packages = [
|
||||||
"raven",
|
|
||||||
"psutil",
|
"psutil",
|
||||||
"asyncio",
|
"asyncio",
|
||||||
"packaging", # needed for linux
|
"packaging", # needed for linux
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
setuptools==40.8.0
|
setuptools==54.2.0
|
||||||
cx_Freeze==5.1.1
|
cx_Freeze==5.1.1
|
||||||
requests==2.21.0
|
requests==2.25.1
|
||||||
packaging==19.0
|
packaging==20.9
|
||||||
appdirs==1.4.3
|
appdirs==1.4.4
|
||||||
psutil==5.6.3
|
psutil==5.8.0
|
||||||
jsonschema==2.6.0 # lock down jsonschema, 3.0 makes problems
|
|
||||||
|
@ -1,6 +1,111 @@
|
|||||||
GNS3 WebUI is web implementation of user interface for GNS3 software.
|
GNS3 WebUI is web implementation of user interface for GNS3 software.
|
||||||
|
|
||||||
Current version: GNS3 Web UI 2019.2.0 v11
|
Current version: 2.2.24
|
||||||
|
|
||||||
|
Bug Fixes & enhancements
|
||||||
|
- security fixes
|
||||||
|
|
||||||
|
Current version: 2020.4.0-beta.1
|
||||||
|
|
||||||
|
Bug Fixes & enhancements
|
||||||
|
- symbol is not properly selected in change symbol dialog
|
||||||
|
- issue when using the scroll wheel on the web console
|
||||||
|
- missing settings for Docker nodes
|
||||||
|
- error on servers page
|
||||||
|
|
||||||
|
What's new
|
||||||
|
- double click nodes to open the console
|
||||||
|
|
||||||
|
Current version: 2020.3.0-beta.3
|
||||||
|
|
||||||
|
Bug Fixes & enhancements
|
||||||
|
- direct download URL in template dialog
|
||||||
|
- fix for issues with suspnded nodes
|
||||||
|
- fix for bug with deleting templates
|
||||||
|
- fix for importing images
|
||||||
|
|
||||||
|
What's new
|
||||||
|
- Option to resize console
|
||||||
|
- Improvements in creating templates
|
||||||
|
|
||||||
|
GNS3 Web UI 2020.3.0-beta.1
|
||||||
|
|
||||||
|
Bug Fixes & enhancements
|
||||||
|
- refreshing list of templates after adding new template from project map
|
||||||
|
- link to preferences from project page
|
||||||
|
- disallow user to create Qemu template when binary is not selected
|
||||||
|
- extending the time for notification to appear
|
||||||
|
- open first settings menu at start
|
||||||
|
- the menu for the map rearranged
|
||||||
|
- restyling SystemStatus page
|
||||||
|
- marking files which already exist in appliance wizard
|
||||||
|
|
||||||
|
What's new
|
||||||
|
- Option to import appliances
|
||||||
|
|
||||||
|
GNS3 Web UI 2020.2.0-beta.5
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
|
||||||
|
- Bug in symbol selection
|
||||||
|
- Same question is asked after going back to project
|
||||||
|
- Cannot read property 'forEach' of undefined
|
||||||
|
- Error when selecting existing Docker image
|
||||||
|
- Invalid property when adding VMware VM template
|
||||||
|
- Invalid type for adapters field when adding Docker template
|
||||||
|
- Prevent user to move to another step when adding template
|
||||||
|
- Web UI cannot set flag "Leave this project running in the background after closing"
|
||||||
|
|
||||||
|
What's new
|
||||||
|
- Default values in templates
|
||||||
|
- New option for Qemu VMs
|
||||||
|
- Ability to quickly change Hostname from right click
|
||||||
|
- Progress bar for node creation
|
||||||
|
|
||||||
|
GNS3 Web UI 2020.2.0-beta.4
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
- New port setting for GNS3 VM preferences
|
||||||
|
- Option to auto-hide menu toolbar on the left side
|
||||||
|
-Controller type in template preferences
|
||||||
|
- Error when selecting existing Docker image
|
||||||
|
- Default values in templates
|
||||||
|
- TypeError: Cannot read property 'message' of undefined
|
||||||
|
- TypeError: e.error is undefined
|
||||||
|
- TypeError: Cannot read property 'placements' of null
|
||||||
|
- Creating IOS templates -> fix for platforms and network adapters
|
||||||
|
|
||||||
|
GNS3 Web UI 2020.2.0-beta.2
|
||||||
|
|
||||||
|
What's New
|
||||||
|
- Drag & drop to add new nodes on topology
|
||||||
|
- Option to minimize/maximize and hide console widget
|
||||||
|
- Ability to add IOS templates
|
||||||
|
- Node names in HTTP console tabs
|
||||||
|
- Default settings for templates
|
||||||
|
- Support for adding IOS images
|
||||||
|
- Node dialog updated
|
||||||
|
- Messages with description in toasts
|
||||||
|
- Adding interfaces to cloud nodes
|
||||||
|
- Changes in notification box mechanism (once per day option)
|
||||||
|
- Additional tooltips added
|
||||||
|
- Copy/paste options in console (only Chrome full support)
|
||||||
|
- More details for server failed connections
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
- Fix for console icons
|
||||||
|
- Fix for creating ethernet switches and hubs
|
||||||
|
- Fix for opening console from context menu
|
||||||
|
- Qemu configurator now works properly
|
||||||
|
- Fixes in snap to grid option
|
||||||
|
- Symbols preview now works correctly
|
||||||
|
- Error messages in preferences should be displayed
|
||||||
|
- Default values for New Ethernet devices in configurator
|
||||||
|
- Fix for wrong adapter types in Qemu
|
||||||
|
- Fix for fit in view option on Firefox
|
||||||
|
- Fix for navigation errors
|
||||||
|
|
||||||
|
GNS3 Web UI 2020.2.0-beta.1
|
||||||
|
|
||||||
What's New
|
What's New
|
||||||
- Support for suspended status added
|
- Support for suspended status added
|
||||||
|
@ -1,167 +1,320 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { BundledControllerFinderComponent } from './components/bundled-controller-finder/bundled-controller-finder.component';
|
||||||
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
import { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
||||||
import { ServersComponent } from './components/servers/servers.component';
|
import { HelpComponent } from './components/help/help.component';
|
||||||
import { ProjectsComponent } from './components/projects/projects.component';
|
import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component';
|
||||||
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
import { LoginComponent } from './components/login/login.component';
|
||||||
import { SettingsComponent } from './components/settings/settings.component';
|
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
|
||||||
import { BundledServerFinderComponent } from './components/bundled-server-finder/bundled-server-finder.component';
|
|
||||||
import { PreferencesComponent } from './components/preferences/preferences.component';
|
|
||||||
import { QemuPreferencesComponent } from './components/preferences/qemu/qemu-preferences/qemu-preferences.component';
|
|
||||||
import { QemuVmTemplatesComponent } from './components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component';
|
|
||||||
import { QemuVmTemplateDetailsComponent } from './components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component';
|
|
||||||
import { AddQemuVmTemplateComponent } from './components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component';
|
|
||||||
import { GeneralPreferencesComponent } from './components/preferences/general/general-preferences.component';
|
|
||||||
import { VpcsPreferencesComponent } from './components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component';
|
|
||||||
import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component';
|
|
||||||
import { AddVpcsTemplateComponent } from './components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component';
|
|
||||||
import { VpcsTemplateDetailsComponent } from './components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component';
|
|
||||||
import { VirtualBoxPreferencesComponent } from './components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component';
|
|
||||||
import { VirtualBoxTemplatesComponent } from './components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component';
|
|
||||||
import { VirtualBoxTemplateDetailsComponent } from './components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component';
|
|
||||||
import { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component';
|
|
||||||
import { BuiltInPreferencesComponent } from './components/preferences/built-in/built-in-preferences.component';
|
import { BuiltInPreferencesComponent } from './components/preferences/built-in/built-in-preferences.component';
|
||||||
import { EthernetHubsTemplatesComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component';
|
|
||||||
import { EthernetHubsAddTemplateComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component';
|
|
||||||
import { EthernetHubsTemplateDetailsComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component';
|
|
||||||
import { CloudNodesTemplatesComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component';
|
|
||||||
import { CloudNodesAddTemplateComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component';
|
import { CloudNodesAddTemplateComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component';
|
||||||
import { CloudNodesTemplateDetailsComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component';
|
import { CloudNodesTemplateDetailsComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component';
|
||||||
import { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component';
|
import { CloudNodesTemplatesComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component';
|
||||||
|
import { EthernetHubsAddTemplateComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component';
|
||||||
|
import { EthernetHubsTemplateDetailsComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component';
|
||||||
|
import { EthernetHubsTemplatesComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component';
|
||||||
import { EthernetSwitchesAddTemplateComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component';
|
import { EthernetSwitchesAddTemplateComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component';
|
||||||
import { EthernetSwitchesTemplateDetailsComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component';
|
import { EthernetSwitchesTemplateDetailsComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component';
|
||||||
import { DynamipsPreferencesComponent } from './components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component';
|
import { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component';
|
||||||
import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component';
|
|
||||||
import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component';
|
|
||||||
import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component';
|
|
||||||
import { AddIosTemplateComponent } from './components/preferences/dynamips/add-ios-template/add-ios-template.component';
|
|
||||||
import { VmwarePreferencesComponent } from './components/preferences/vmware/vmware-preferences/vmware-preferences.component';
|
|
||||||
import { VmwareTemplatesComponent } from './components/preferences/vmware/vmware-templates/vmware-templates.component';
|
|
||||||
import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/vmware-template-details/vmware-template-details.component';
|
|
||||||
import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component';
|
|
||||||
import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component';
|
|
||||||
import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-docker-template.component';
|
import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-docker-template.component';
|
||||||
import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component';
|
|
||||||
import { IouTemplatesComponent } from './components/preferences/ios-on-unix/iou-templates/iou-templates.component';
|
|
||||||
import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component';
|
|
||||||
import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component';
|
|
||||||
import { CopyQemuVmTemplateComponent } from './components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component';
|
|
||||||
import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy-ios-template/copy-ios-template.component';
|
|
||||||
import { CopyDockerTemplateComponent } from './components/preferences/docker/copy-docker-template/copy-docker-template.component';
|
import { CopyDockerTemplateComponent } from './components/preferences/docker/copy-docker-template/copy-docker-template.component';
|
||||||
|
import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component';
|
||||||
|
import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component';
|
||||||
|
import { AddIosTemplateComponent } from './components/preferences/dynamips/add-ios-template/add-ios-template.component';
|
||||||
|
import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy-ios-template/copy-ios-template.component';
|
||||||
|
import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component';
|
||||||
|
import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component';
|
||||||
|
import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component';
|
||||||
import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component';
|
import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component';
|
||||||
import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component';
|
import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component';
|
||||||
|
import { IouTemplatesComponent } from './components/preferences/ios-on-unix/iou-templates/iou-templates.component';
|
||||||
|
import { PreferencesComponent } from './components/preferences/preferences.component';
|
||||||
|
import { AddQemuVmTemplateComponent } from './components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component';
|
||||||
|
import { CopyQemuVmTemplateComponent } from './components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component';
|
||||||
|
import { QemuVmTemplateDetailsComponent } from './components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component';
|
||||||
|
import { QemuVmTemplatesComponent } from './components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component';
|
||||||
|
import { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component';
|
||||||
|
import { VirtualBoxTemplateDetailsComponent } from './components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component';
|
||||||
|
import { VirtualBoxTemplatesComponent } from './components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component';
|
||||||
|
import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component';
|
||||||
|
import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/vmware-template-details/vmware-template-details.component';
|
||||||
|
import { VmwareTemplatesComponent } from './components/preferences/vmware/vmware-templates/vmware-templates.component';
|
||||||
|
import { AddVpcsTemplateComponent } from './components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component';
|
||||||
|
import { VpcsTemplateDetailsComponent } from './components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component';
|
||||||
|
import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component';
|
||||||
|
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
||||||
|
import { ProjectsComponent } from './components/projects/projects.component';
|
||||||
|
import { ControllersComponent } from './components/controllers/controllers.component';
|
||||||
import { ConsoleComponent } from './components/settings/console/console.component';
|
import { ConsoleComponent } from './components/settings/console/console.component';
|
||||||
import { HelpComponent } from './components/help/help.component';
|
import { SettingsComponent } from './components/settings/settings.component';
|
||||||
import { TracengPreferencesComponent } from './components/preferences/traceng/traceng-preferences/traceng-preferences.component';
|
import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component';
|
||||||
import { TracengTemplatesComponent } from './components/preferences/traceng/traceng-templates/traceng-templates.component';
|
|
||||||
import { AddTracengTemplateComponent } from './components/preferences/traceng/add-traceng/add-traceng-template.component';
|
|
||||||
import { TracengTemplateDetailsComponent } from './components/preferences/traceng/traceng-template-details/traceng-template-details.component';
|
|
||||||
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
|
|
||||||
import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.component';
|
|
||||||
import { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
|
||||||
import { SystemStatusComponent } from './components/system-status/system-status.component';
|
import { SystemStatusComponent } from './components/system-status/system-status.component';
|
||||||
import { ServerResolve } from './resolvers/server-resolve';
|
import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component';
|
||||||
import { ProjectMapGuard } from './guards/project-map-guard';
|
import { ConsoleGuard } from './guards/console-guard';
|
||||||
|
import { LoginGuard } from './guards/login-guard';
|
||||||
|
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
||||||
|
import { ControllerResolve } from './resolvers/controller-resolve';
|
||||||
|
import { UserManagementComponent } from './components/user-management/user-management.component';
|
||||||
|
import { LoggedUserComponent } from './components/users/logged-user/logged-user.component';
|
||||||
|
import { ImageManagerComponent } from './components/image-manager/image-manager.component';
|
||||||
|
import { UserDetailComponent } from "./components/user-management/user-detail/user-detail.component";
|
||||||
|
import { UserDetailResolver } from "./resolvers/user-detail.resolver";
|
||||||
|
import { ManagementComponent } from "./components/management/management.component";
|
||||||
|
import { PermissionResolver } from "./resolvers/permission.resolver";
|
||||||
|
import { UserGroupsResolver } from "./resolvers/user-groups.resolver";
|
||||||
|
import { UserPermissionsResolver } from "./resolvers/user-permissions.resolver";
|
||||||
|
import { GroupManagementComponent } from "./components/group-management/group-management.component";
|
||||||
|
import { RoleManagementComponent } from "./components/role-management/role-management.component";
|
||||||
|
import { PermissionsManagementComponent } from "./components/permissions-management/permissions-management.component";
|
||||||
|
import { GroupDetailsComponent } from "./components/group-details/group-details.component";
|
||||||
|
import { GroupMembersResolver } from "./resolvers/group-members.resolver";
|
||||||
|
import { GroupResolver } from "./resolvers/group.resolver";
|
||||||
|
import { GroupRoleResolver } from "./resolvers/group-role.resolver";
|
||||||
|
import { RoleDetailComponent } from "./components/role-management/role-detail/role-detail.component";
|
||||||
|
import { RoleDetailResolver } from "./resolvers/role-detail.resolver";
|
||||||
|
import { RolePermissionsComponent } from "./components/role-management/role-detail/role-permissions/role-permissions.component";
|
||||||
|
import { UserPermissionsComponent } from "./components/user-management/user-detail/user-permissions/user-permissions.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: DefaultLayoutComponent,
|
component: DefaultLayoutComponent,
|
||||||
children: [
|
children: [
|
||||||
{ path: '', redirectTo: 'servers', pathMatch: 'full' },
|
{ path: '', redirectTo: 'controllers', pathMatch: 'full' },
|
||||||
{ path: 'servers', component: ServersComponent },
|
{ path: 'controllers', component: ControllersComponent },
|
||||||
{ path: 'bundled', component: BundledServerFinderComponent },
|
{ path: 'bundled', component: BundledControllerFinderComponent },
|
||||||
{
|
{ path: 'controller/:controller_id/login', component: LoginComponent },
|
||||||
path: 'server/:server_id/projects',
|
{ path: 'controller/:controller_id/loggeduser', component: LoggedUserComponent },
|
||||||
|
{path : 'controller/:controller_id/image-manager', component: ImageManagerComponent},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/projects',
|
||||||
component: ProjectsComponent,
|
component: ProjectsComponent,
|
||||||
resolve: { server : ServerResolve }
|
canActivate: [LoginGuard],
|
||||||
|
resolve: { controller: ControllerResolve },
|
||||||
|
},
|
||||||
|
{ path: 'controller/:controller_id/help', component: HelpComponent },
|
||||||
|
{ path: 'controller/:controller_id/settings', component: SettingsComponent },
|
||||||
|
{ path: 'controller/:controller_id/settings/console', component: ConsoleComponent },
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/management/users/:user_id',
|
||||||
|
component: UserDetailComponent,
|
||||||
|
canActivate: [LoginGuard],
|
||||||
|
resolve: {
|
||||||
|
user: UserDetailResolver,
|
||||||
|
groups: UserGroupsResolver,
|
||||||
|
permissions: UserPermissionsResolver,
|
||||||
|
controller: ControllerResolve},
|
||||||
},
|
},
|
||||||
{ path: 'help', component: HelpComponent },
|
|
||||||
{ path: 'settings', component: SettingsComponent },
|
|
||||||
{ path: 'settings/console', component: ConsoleComponent },
|
|
||||||
{ path: 'installed-software', component: InstalledSoftwareComponent },
|
{ path: 'installed-software', component: InstalledSoftwareComponent },
|
||||||
{ path: 'server/:server_id/systemstatus', component: SystemStatusComponent },
|
{ path: 'controller/:controller_id/systemstatus', component: SystemStatusComponent, canActivate: [LoginGuard] },
|
||||||
|
|
||||||
{ path: 'server/:server_ip/:server_port/project/:project_id', component: DirectLinkComponent},
|
{ path: 'controller/:controller_ip/:controller_port/project/:project_id', component: DirectLinkComponent, canActivate: [LoginGuard] },
|
||||||
{
|
{
|
||||||
path: 'server/:server_id/project/:project_id/snapshots',
|
path: 'controller/:controller_id/project/:project_id/snapshots',
|
||||||
component: ListOfSnapshotsComponent,
|
component: ListOfSnapshotsComponent,
|
||||||
resolve: { server : ServerResolve }
|
canActivate: [LoginGuard],
|
||||||
|
resolve: { controller: ControllerResolve },
|
||||||
},
|
},
|
||||||
{ path: 'server/:server_id/preferences', component: PreferencesComponent },
|
{ path: 'controller/:controller_id/preferences', component: PreferencesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/gns3vm', component: Gns3vmComponent },
|
// { path: 'controller/:controller_id/preferences/general', component: GeneralPreferencesComponent },
|
||||||
// { path: 'server/:server_id/preferences/general', component: GeneralPreferencesComponent },
|
{ path: 'controller/:controller_id/preferences/builtin', component: BuiltInPreferencesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/builtin', component: BuiltInPreferencesComponent},
|
|
||||||
|
|
||||||
{ path: 'server/:server_id/preferences/builtin/ethernet-hubs', component: EthernetHubsTemplatesComponent },
|
{ path: 'controller/:controller_id/preferences/builtin/ethernet-hubs', component: EthernetHubsTemplatesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/builtin/ethernet-hubs/addtemplate', component: EthernetHubsAddTemplateComponent },
|
{
|
||||||
{ path: 'server/:server_id/preferences/builtin/ethernet-hubs/:template_id', component: EthernetHubsTemplateDetailsComponent },
|
path: 'controller/:controller_id/preferences/builtin/ethernet-hubs/addtemplate',
|
||||||
|
component: EthernetHubsAddTemplateComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/preferences/builtin/ethernet-hubs/:template_id',
|
||||||
|
component: EthernetHubsTemplateDetailsComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
|
||||||
{ path: 'server/:server_id/preferences/builtin/ethernet-switches', component: EthernetSwitchesTemplatesComponent },
|
{
|
||||||
{ path: 'server/:server_id/preferences/builtin/ethernet-switches/addtemplate', component: EthernetSwitchesAddTemplateComponent },
|
path: 'controller/:controller_id/preferences/builtin/ethernet-switches',
|
||||||
{ path: 'server/:server_id/preferences/builtin/ethernet-switches/:template_id', component: EthernetSwitchesTemplateDetailsComponent },
|
component: EthernetSwitchesTemplatesComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/preferences/builtin/ethernet-switches/addtemplate',
|
||||||
|
component: EthernetSwitchesAddTemplateComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/preferences/builtin/ethernet-switches/:template_id',
|
||||||
|
component: EthernetSwitchesTemplateDetailsComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
|
||||||
{ path: 'server/:server_id/preferences/builtin/cloud-nodes', component: CloudNodesTemplatesComponent },
|
{ path: 'controller/:controller_id/preferences/builtin/cloud-nodes', component: CloudNodesTemplatesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/builtin/cloud-nodes/addtemplate', component: CloudNodesAddTemplateComponent },
|
{
|
||||||
{ path: 'server/:server_id/preferences/builtin/cloud-nodes/:template_id', component: CloudNodesTemplateDetailsComponent },
|
path: 'controller/:controller_id/preferences/builtin/cloud-nodes/addtemplate',
|
||||||
|
component: CloudNodesAddTemplateComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/preferences/builtin/cloud-nodes/:template_id',
|
||||||
|
component: CloudNodesTemplateDetailsComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
|
||||||
//{ path: 'server/:server_id/preferences/dynamips', component: DynamipsPreferencesComponent },
|
//{ path: 'controller/:controller_id/preferences/dynamips', component: DynamipsPreferencesComponent },
|
||||||
{ path: 'server/:server_id/preferences/dynamips/templates', component: IosTemplatesComponent },
|
{ path: 'controller/:controller_id/preferences/dynamips/templates', component: IosTemplatesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/dynamips/templates/addtemplate', component: AddIosTemplateComponent },
|
{ path: 'controller/:controller_id/preferences/dynamips/templates/addtemplate', component: AddIosTemplateComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/dynamips/templates/:template_id', component: IosTemplateDetailsComponent },
|
{ path: 'controller/:controller_id/preferences/dynamips/templates/:template_id', component: IosTemplateDetailsComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/dynamips/templates/:template_id/copy', component: CopyIosTemplateComponent },
|
{
|
||||||
|
path: 'controller/:controller_id/preferences/dynamips/templates/:template_id/copy',
|
||||||
|
component: CopyIosTemplateComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
|
||||||
// { path: 'server/:server_id/preferences/qemu', component: QemuPreferencesComponent },
|
// { path: 'controller/:controller_id/preferences/qemu', component: QemuPreferencesComponent },
|
||||||
{ path: 'server/:server_id/preferences/qemu/templates', component: QemuVmTemplatesComponent },
|
{ path: 'controller/:controller_id/preferences/qemu/templates', component: QemuVmTemplatesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/qemu/templates/:template_id/copy', component: CopyQemuVmTemplateComponent },
|
{
|
||||||
{ path: 'server/:server_id/preferences/qemu/templates/:template_id', component: QemuVmTemplateDetailsComponent },
|
path: 'controller/:controller_id/preferences/qemu/templates/:template_id/copy',
|
||||||
{ path: 'server/:server_id/preferences/qemu/addtemplate', component: AddQemuVmTemplateComponent },
|
component: CopyQemuVmTemplateComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
{ path: 'controller/:controller_id/preferences/qemu/templates/:template_id', component: QemuVmTemplateDetailsComponent, canActivate: [LoginGuard] },
|
||||||
|
{ path: 'controller/:controller_id/preferences/qemu/addtemplate', component: AddQemuVmTemplateComponent, canActivate: [LoginGuard] },
|
||||||
|
|
||||||
// { path: 'server/:server_id/preferences/vpcs', component: VpcsPreferencesComponent },
|
// { path: 'controller/:controller_id/preferences/vpcs', component: VpcsPreferencesComponent },
|
||||||
{ path: 'server/:server_id/preferences/vpcs/templates', component: VpcsTemplatesComponent },
|
{ path: 'controller/:controller_id/preferences/vpcs/templates', component: VpcsTemplatesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/vpcs/templates/:template_id', component: VpcsTemplateDetailsComponent},
|
{ path: 'controller/:controller_id/preferences/vpcs/templates/:template_id', component: VpcsTemplateDetailsComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/vpcs/addtemplate', component: AddVpcsTemplateComponent },
|
{ path: 'controller/:controller_id/preferences/vpcs/addtemplate', component: AddVpcsTemplateComponent, canActivate: [LoginGuard] },
|
||||||
|
|
||||||
// { path: 'server/:server_id/preferences/virtualbox', component: VirtualBoxPreferencesComponent },
|
// { path: 'controller/:controller_id/preferences/virtualbox', component: VirtualBoxPreferencesComponent },
|
||||||
{ path: 'server/:server_id/preferences/virtualbox/templates', component: VirtualBoxTemplatesComponent },
|
{ path: 'controller/:controller_id/preferences/virtualbox/templates', component: VirtualBoxTemplatesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/virtualbox/templates/:template_id', component: VirtualBoxTemplateDetailsComponent },
|
{
|
||||||
{ path: 'server/:server_id/preferences/virtualbox/addtemplate', component: AddVirtualBoxTemplateComponent },
|
path: 'controller/:controller_id/preferences/virtualbox/templates/:template_id',
|
||||||
|
component: VirtualBoxTemplateDetailsComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
{ path: 'controller/:controller_id/preferences/virtualbox/addtemplate', component: AddVirtualBoxTemplateComponent, canActivate: [LoginGuard] },
|
||||||
|
|
||||||
// { path: 'server/:server_id/preferences/vmware', component: VmwarePreferencesComponent },
|
// { path: 'controller/:controller_id/preferences/vmware', component: VmwarePreferencesComponent },
|
||||||
{ path: 'server/:server_id/preferences/vmware/templates', component: VmwareTemplatesComponent },
|
{ path: 'controller/:controller_id/preferences/vmware/templates', component: VmwareTemplatesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/vmware/templates/:template_id', component: VmwareTemplateDetailsComponent },
|
{
|
||||||
{ path: 'server/:server_id/preferences/vmware/addtemplate', component: AddVmwareTemplateComponent },
|
path: 'controller/:controller_id/preferences/vmware/templates/:template_id',
|
||||||
|
component: VmwareTemplateDetailsComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
{ path: 'controller/:controller_id/preferences/vmware/addtemplate', component: AddVmwareTemplateComponent, canActivate: [LoginGuard] },
|
||||||
|
|
||||||
// { path: 'server/:server_id/preferences/traceng', component: TracengPreferencesComponent },
|
{ path: 'controller/:controller_id/preferences/docker/templates', component: DockerTemplatesComponent, canActivate: [LoginGuard] },
|
||||||
// { path: 'server/:server_id/preferences/traceng/templates', component: TracengTemplatesComponent },
|
{
|
||||||
// { path: 'server/:server_id/preferences/traceng/templates/:template_id', component: TracengTemplateDetailsComponent },
|
path: 'controller/:controller_id/preferences/docker/templates/:template_id',
|
||||||
// { path: 'server/:server_id/preferences/traceng/addtemplate', component: AddTracengTemplateComponent },
|
component: DockerTemplateDetailsComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
{ path: 'server/:server_id/preferences/docker/templates', component: DockerTemplatesComponent },
|
},
|
||||||
{ path: 'server/:server_id/preferences/docker/templates/:template_id', component: DockerTemplateDetailsComponent },
|
{
|
||||||
{ path: 'server/:server_id/preferences/docker/templates/:template_id/copy', component: CopyDockerTemplateComponent },
|
path: 'controller/:controller_id/preferences/docker/templates/:template_id/copy',
|
||||||
{ path: 'server/:server_id/preferences/docker/addtemplate', component: AddDockerTemplateComponent },
|
component: CopyDockerTemplateComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
{ path: 'server/:server_id/preferences/iou/templates', component: IouTemplatesComponent },
|
},
|
||||||
{ path: 'server/:server_id/preferences/iou/templates/:template_id', component: IouTemplateDetailsComponent },
|
{ path: 'controller/:controller_id/preferences/docker/addtemplate', component: AddDockerTemplateComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/iou/templates/:template_id/copy', component: CopyIouTemplateComponent },
|
{ path: 'controller/:controller_id/preferences/iou/templates', component: IouTemplatesComponent, canActivate: [LoginGuard] },
|
||||||
{ path: 'server/:server_id/preferences/iou/addtemplate', component: AddIouTemplateComponent }
|
{ path: 'controller/:controller_id/preferences/iou/templates/:template_id', component: IouTemplateDetailsComponent, canActivate: [LoginGuard] },
|
||||||
]
|
{
|
||||||
|
path: 'controller/:controller_id/preferences/iou/templates/:template_id/copy',
|
||||||
|
component: CopyIouTemplateComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
{ path: 'controller/:controller_id/preferences/iou/addtemplate', component: AddIouTemplateComponent, canActivate: [LoginGuard] },
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/management',
|
||||||
|
component: ManagementComponent,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'users',
|
||||||
|
component: UserManagementComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'groups',
|
||||||
|
component: GroupManagementComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'roles',
|
||||||
|
component: RoleManagementComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'permissions',
|
||||||
|
component: PermissionsManagementComponent
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/management/groups/:user_group_id',
|
||||||
|
component: GroupDetailsComponent,
|
||||||
|
resolve: {
|
||||||
|
members: GroupMembersResolver,
|
||||||
|
controller: ControllerResolve,
|
||||||
|
group: GroupResolver,
|
||||||
|
roles: GroupRoleResolver
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/management/roles/:role_id',
|
||||||
|
component: RoleDetailComponent,
|
||||||
|
resolve: {
|
||||||
|
role: RoleDetailResolver,
|
||||||
|
controller: ControllerResolve
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/management/roles/:role_id/permissions',
|
||||||
|
component: RolePermissionsComponent,
|
||||||
|
resolve: {
|
||||||
|
role: RoleDetailResolver,
|
||||||
|
controller: ControllerResolve,
|
||||||
|
permissions: PermissionResolver
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/management/users/:user_id/permissions',
|
||||||
|
component: UserPermissionsComponent,
|
||||||
|
resolve: {
|
||||||
|
user: UserDetailResolver,
|
||||||
|
userPermissions: UserPermissionsResolver,
|
||||||
|
controller: ControllerResolve,
|
||||||
|
permissions: PermissionResolver
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'server/:server_id/project/:project_id',
|
path: 'controller/:controller_id/project/:project_id',
|
||||||
component: ProjectMapComponent,
|
component: ProjectMapComponent,
|
||||||
canActivate: [ProjectMapGuard]
|
canActivate: [LoginGuard],
|
||||||
|
canDeactivate: [ConsoleGuard],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'controller/:controller_id/project/:project_id/nodes/:node_id',
|
||||||
|
component: WebConsoleFullWindowComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'static/web-ui/controller/:controller_id/project/:project_id/nodes/:node_id',
|
||||||
|
component: WebConsoleFullWindowComponent,
|
||||||
|
canActivate: [LoginGuard]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
component: PageNotFoundComponent
|
component: PageNotFoundComponent,
|
||||||
}
|
}
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [RouterModule.forRoot(routes, { anchorScrolling: 'enabled', enableTracing: true, scrollPositionRestoration: 'enabled'})],
|
imports: [
|
||||||
exports: [RouterModule]
|
RouterModule.forRoot(routes, {
|
||||||
|
anchorScrolling: 'enabled',
|
||||||
|
enableTracing: false,
|
||||||
|
scrollPositionRestoration: 'enabled',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
exports: [RouterModule],
|
||||||
})
|
})
|
||||||
export class AppRoutingModule {}
|
export class AppRoutingModule {
|
||||||
|
}
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
mat-menu-panel {
|
|
||||||
min-height: 0px;
|
|
||||||
}
|
|
@ -1,2 +1,4 @@
|
|||||||
<router-outlet></router-outlet>
|
<div [ngClass]="{ dark: darkThemeEnabled, light: !darkThemeEnabled }">
|
||||||
<app-notification-box></app-notification-box>
|
<router-outlet></router-outlet>
|
||||||
|
<app-adbutler></app-adbutler>
|
||||||
|
</div>
|
||||||
|
11
src/app/app.component.scss
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
mat-menu-panel {
|
||||||
|
min-height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
background: #263238 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light {
|
||||||
|
background: white !important;
|
||||||
|
}
|
@ -1,14 +1,14 @@
|
|||||||
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
|
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
import { MatIconModule } from '@angular/material';
|
|
||||||
import { SettingsService } from './services/settings.service';
|
|
||||||
import { PersistenceService } from 'angular-persistence';
|
|
||||||
import { ElectronService, NgxElectronModule } from 'ngx-electron';
|
|
||||||
import createSpyObj = jasmine.createSpyObj;
|
|
||||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
import { ElectronService, NgxElectronModule } from 'ngx-electron';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
import { ProgressService } from './common/progress/progress.service';
|
import { ProgressService } from './common/progress/progress.service';
|
||||||
|
import { SettingsService } from './services/settings.service';
|
||||||
|
|
||||||
|
import createSpyObj = jasmine.createSpyObj;
|
||||||
|
// import 'jasmine';
|
||||||
|
|
||||||
describe('AppComponent', () => {
|
describe('AppComponent', () => {
|
||||||
let component: AppComponent;
|
let component: AppComponent;
|
||||||
@ -16,17 +16,17 @@ describe('AppComponent', () => {
|
|||||||
let electronService: ElectronService;
|
let electronService: ElectronService;
|
||||||
let settingsService: SettingsService;
|
let settingsService: SettingsService;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [AppComponent],
|
declarations: [AppComponent],
|
||||||
imports: [RouterTestingModule, MatIconModule, NgxElectronModule],
|
imports: [RouterTestingModule, MatIconModule, NgxElectronModule],
|
||||||
providers: [SettingsService, PersistenceService, ProgressService],
|
providers: [SettingsService, ProgressService],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
electronService = TestBed.get(ElectronService);
|
electronService = TestBed.inject(ElectronService);
|
||||||
settingsService = TestBed.get(SettingsService);
|
settingsService = TestBed.inject(SettingsService);
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(AppComponent);
|
fixture = TestBed.createComponent(AppComponent);
|
||||||
@ -34,34 +34,29 @@ describe('AppComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create the app', async(() => {
|
it('should create the app', async() => {
|
||||||
const app = fixture.debugElement.componentInstance;
|
const app = fixture.debugElement.componentInstance;
|
||||||
expect(app).toBeTruthy();
|
await expect(app).toBeTruthy();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should have footer', async(() => {
|
it('should have footer', async() => {
|
||||||
const compiled = fixture.debugElement.nativeElement;
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
expect(compiled.querySelector('router-outlet').textContent).toEqual('');
|
await expect(compiled.querySelector('router-outlet').textContent).toEqual('');
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should receive changed settings and forward to electron', async(() => {
|
it('should receive changed settings and forward to electron', async() => {
|
||||||
const spy = createSpyObj('Electron.IpcRenderer', ['send']);
|
await spyOnProperty(electronService, 'isElectronApp').and.returnValue(true);
|
||||||
spyOnProperty(electronService, 'isElectronApp').and.returnValue(true);
|
settingsService.setReportsSettings(true);
|
||||||
spyOnProperty(electronService, 'ipcRenderer').and.returnValue(spy);
|
|
||||||
settingsService.set('crash_reports', true);
|
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
settingsService.set('crash_reports', false);
|
settingsService.setReportsSettings(false);
|
||||||
expect(spy.send).toHaveBeenCalled();
|
});
|
||||||
expect(spy.send.calls.mostRecent().args[0]).toEqual('settings.changed');
|
|
||||||
expect(spy.send.calls.mostRecent().args[1].crash_reports).toEqual(false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should receive changed settings and do not forward to electron', async(() => {
|
it('should receive changed settings and do not forward to electron', async() => {
|
||||||
const spy = createSpyObj('Electron.IpcRenderer', ['send']);
|
const spy = createSpyObj('Electron.IpcRenderer', ['send']);
|
||||||
spyOnProperty(electronService, 'isElectronApp').and.returnValue(false);
|
spyOnProperty(electronService, 'isElectronApp').and.returnValue(false);
|
||||||
settingsService.set('crash_reports', true);
|
settingsService.setReportsSettings(true);
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
settingsService.set('crash_reports', false);
|
settingsService.setReportsSettings(false);
|
||||||
expect(spy.send).not.toHaveBeenCalled();
|
await expect(spy.send).not.toHaveBeenCalled();
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||||
import { MatIconRegistry } from '@angular/material';
|
import { Component, HostBinding, OnInit } from '@angular/core';
|
||||||
|
import { MatIconRegistry } from '@angular/material/icon';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
|
import { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';
|
||||||
import { ElectronService } from 'ngx-electron';
|
import { ElectronService } from 'ngx-electron';
|
||||||
|
import { ProgressService } from './common/progress/progress.service';
|
||||||
import { SettingsService } from './services/settings.service';
|
import { SettingsService } from './services/settings.service';
|
||||||
import { ThemeService } from './services/theme.service';
|
import { ThemeService } from './services/theme.service';
|
||||||
import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
|
|
||||||
import { ProgressService } from './common/progress/progress.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrls: ['./app.component.css']
|
styleUrls: ['./app.component.scss'],
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
|
public darkThemeEnabled: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private overlayContainer: OverlayContainer,
|
||||||
iconReg: MatIconRegistry,
|
iconReg: MatIconRegistry,
|
||||||
sanitizer: DomSanitizer,
|
sanitizer: DomSanitizer,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
@ -30,28 +34,33 @@ export class AppComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@HostBinding('class') componentCssClass;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (this.electronService.isElectronApp) {
|
this.applyTheme(this.themeService.savedTheme + '-theme');
|
||||||
this.settingsService.subscribe(settings => {
|
this.themeService.themeChanged.subscribe((event: string) => {
|
||||||
this.electronService.ipcRenderer.send('settings.changed', settings);
|
this.applyTheme(event);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
let theme = localStorage.getItem('theme');
|
|
||||||
if (theme === 'light') {
|
|
||||||
this.themeService.setDarkMode(false);
|
|
||||||
} else {
|
|
||||||
this.themeService.setDarkMode(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkEvent(routerEvent) : void {
|
applyTheme(theme: string) {
|
||||||
|
if (theme === 'dark-theme') {
|
||||||
|
this.darkThemeEnabled = true;
|
||||||
|
} else {
|
||||||
|
this.darkThemeEnabled = false;
|
||||||
|
}
|
||||||
|
this.overlayContainer.getContainerElement().classList.add(theme);
|
||||||
|
this.componentCssClass = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEvent(routerEvent): void {
|
||||||
if (routerEvent instanceof NavigationStart) {
|
if (routerEvent instanceof NavigationStart) {
|
||||||
this.progressService.activate();
|
this.progressService.activate();
|
||||||
}
|
} else if (
|
||||||
|
routerEvent instanceof NavigationEnd ||
|
||||||
else if (routerEvent instanceof NavigationEnd ||
|
routerEvent instanceof NavigationCancel ||
|
||||||
routerEvent instanceof NavigationCancel ||
|
routerEvent instanceof NavigationError
|
||||||
routerEvent instanceof NavigationError) {
|
) {
|
||||||
this.progressService.deactivate();
|
this.progressService.deactivate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,289 +1,337 @@
|
|||||||
import * as Raven from 'raven-js';
|
/* tslint:disable */
|
||||||
import { BrowserModule, Title } from '@angular/platform-browser';
|
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||||
import { NgModule, ErrorHandler } from '@angular/core';
|
import { OverlayModule } from '@angular/cdk/overlay';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { CdkTableModule } from '@angular/cdk/table';
|
import { CdkTableModule } from '@angular/cdk/table';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||||
|
import { ErrorHandler, NgModule } from '@angular/core';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||||
|
import { BrowserModule, Title } from '@angular/platform-browser';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { DragAndDropModule } from 'angular-draggable-droppable';
|
||||||
|
import { ResizableModule } from 'angular-resizable-element';
|
||||||
import { D3Service } from 'd3-ng2-service';
|
import { D3Service } from 'd3-ng2-service';
|
||||||
import { HotkeyModule } from 'angular2-hotkeys';
|
import { NgCircleProgressModule } from 'ng-circle-progress';
|
||||||
import { PersistenceModule } from 'angular-persistence';
|
|
||||||
import { NgxElectronModule } from 'ngx-electron';
|
|
||||||
import { FileUploadModule } from 'ng2-file-upload';
|
import { FileUploadModule } from 'ng2-file-upload';
|
||||||
|
import { NgxChildProcessModule } from 'ngx-childprocess';
|
||||||
|
import { NgxElectronModule } from 'ngx-electron';
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
|
||||||
import { VersionService } from './services/version.service';
|
|
||||||
import { ProjectService } from './services/project.service';
|
|
||||||
import { SymbolService } from './services/symbol.service';
|
|
||||||
import { ServerService } from './services/server.service';
|
|
||||||
import { IndexedDbService } from './services/indexed-db.service';
|
|
||||||
import { HttpServer, ServerErrorHandler } from './services/http-server.service';
|
|
||||||
import { SnapshotService } from './services/snapshot.service';
|
|
||||||
import { ProgressDialogService } from './common/progress-dialog/progress-dialog.service';
|
|
||||||
import { NodeService } from './services/node.service';
|
|
||||||
import { TemplateService } from './services/template.service';
|
|
||||||
import { LinkService } from './services/link.service';
|
|
||||||
|
|
||||||
import { ProjectsComponent } from './components/projects/projects.component';
|
|
||||||
import { AddBlankProjectDialogComponent } from './components/projects/add-blank-project-dialog/add-blank-project-dialog.component';
|
|
||||||
import { ImportProjectDialogComponent } from './components/projects/import-project-dialog/import-project-dialog.component';
|
|
||||||
import { ConfirmationDialogComponent } from './components/projects/confirmation-dialog/confirmation-dialog.component';
|
|
||||||
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
|
||||||
import { ProgressDialogComponent } from './common/progress-dialog/progress-dialog.component';
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
|
||||||
import { ServersComponent } from './components/servers/servers.component';
|
|
||||||
import { AddServerDialogComponent } from './components/servers/add-server-dialog/add-server-dialog.component';
|
|
||||||
import { ContextMenuComponent } from './components/project-map/context-menu/context-menu.component';
|
|
||||||
import { StartNodeActionComponent } from './components/project-map/context-menu/actions/start-node-action/start-node-action.component';
|
|
||||||
import { StopNodeActionComponent } from './components/project-map/context-menu/actions/stop-node-action/stop-node-action.component';
|
|
||||||
import { TemplateComponent } from './components/template/template.component';
|
|
||||||
import { TemplateListDialogComponent } from './components/template/template-list-dialog/template-list-dialog.component';
|
|
||||||
import { CartographyModule } from './cartography/cartography.module';
|
import { CartographyModule } from './cartography/cartography.module';
|
||||||
import { ToasterService } from './services/toaster.service';
|
import { DrawingsDataSource } from './cartography/datasources/drawings-datasource';
|
||||||
import { ProjectWebServiceHandler } from './handlers/project-web-service-handler';
|
|
||||||
import { LinksDataSource } from './cartography/datasources/links-datasource';
|
import { LinksDataSource } from './cartography/datasources/links-datasource';
|
||||||
import { NodesDataSource } from './cartography/datasources/nodes-datasource';
|
import { NodesDataSource } from './cartography/datasources/nodes-datasource';
|
||||||
import { SymbolsDataSource } from './cartography/datasources/symbols-datasource';
|
import { SymbolsDataSource } from './cartography/datasources/symbols-datasource';
|
||||||
import { SelectionManager } from './cartography/managers/selection-manager';
|
|
||||||
import { InRectangleHelper } from './cartography/helpers/in-rectangle-helper';
|
import { InRectangleHelper } from './cartography/helpers/in-rectangle-helper';
|
||||||
import { DrawingsDataSource } from './cartography/datasources/drawings-datasource';
|
import { SelectionManager } from './cartography/managers/selection-manager';
|
||||||
import { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-action.component';
|
import { ToasterErrorHandler } from './common/error-handlers/toaster-error-handler';
|
||||||
import { MoveLayerDownActionComponent } from './components/project-map/context-menu/actions/move-layer-down-action/move-layer-down-action.component';
|
import { ProgressDialogComponent } from './common/progress-dialog/progress-dialog.component';
|
||||||
import { MoveLayerUpActionComponent } from './components/project-map/context-menu/actions/move-layer-up-action/move-layer-up-action.component';
|
import { ProgressDialogService } from './common/progress-dialog/progress-dialog.service';
|
||||||
import { ProjectMapShortcutsComponent } from './components/project-map/project-map-shortcuts/project-map-shortcuts.component';
|
|
||||||
import { SettingsComponent } from './components/settings/settings.component';
|
|
||||||
import { SettingsService } from './services/settings.service';
|
|
||||||
|
|
||||||
import { BundledServerFinderComponent } from './components/bundled-server-finder/bundled-server-finder.component';
|
|
||||||
import { ProgressComponent } from './common/progress/progress.component';
|
import { ProgressComponent } from './common/progress/progress.component';
|
||||||
import { ProgressService } from './common/progress/progress.service';
|
import { ProgressService } from './common/progress/progress.service';
|
||||||
import { version } from './version';
|
import { AdbutlerComponent } from './components/adbutler/adbutler.component';
|
||||||
import { ToasterErrorHandler } from './common/error-handlers/toaster-error-handler';
|
import { BundledControllerFinderComponent } from './components/bundled-controller-finder/bundled-controller-finder.component';
|
||||||
import { environment } from '../environments/environment';
|
import { InformationDialogComponent } from './components/dialogs/information-dialog.component';
|
||||||
import { RavenState } from './common/error-handlers/raven-state-communicator';
|
import { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
||||||
import { ServerDiscoveryComponent } from './components/servers/server-discovery/server-discovery.component';
|
import { DrawingAddedComponent } from './components/drawings-listeners/drawing-added/drawing-added.component';
|
||||||
import { ServerDatabase } from './services/server.database';
|
import { DrawingDraggedComponent } from './components/drawings-listeners/drawing-dragged/drawing-dragged.component';
|
||||||
import { CreateSnapshotDialogComponent } from './components/snapshots/create-snapshot-dialog/create-snapshot-dialog.component';
|
|
||||||
import { SnapshotMenuItemComponent } from './components/snapshots/snapshot-menu-item/snapshot-menu-item.component';
|
|
||||||
import { MATERIAL_IMPORTS } from './material.imports';
|
|
||||||
import { DrawingService } from './services/drawing.service';
|
|
||||||
import { ProjectNameValidator } from './components/projects/models/projectNameValidator';
|
|
||||||
import { MatSidenavModule } from '@angular/material';
|
|
||||||
import { NodeSelectInterfaceComponent } from './components/project-map/node-select-interface/node-select-interface.component';
|
|
||||||
import { DrawLinkToolComponent } from './components/project-map/draw-link-tool/draw-link-tool.component';
|
|
||||||
|
|
||||||
import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component';
|
|
||||||
import { DrawingResizedComponent } from './components/drawings-listeners/drawing-resized/drawing-resized.component';
|
import { DrawingResizedComponent } from './components/drawings-listeners/drawing-resized/drawing-resized.component';
|
||||||
import { TextEditedComponent } from './components/drawings-listeners/text-edited/text-edited.component';
|
import { InterfaceLabelDraggedComponent } from './components/drawings-listeners/interface-label-dragged/interface-label-dragged.component';
|
||||||
|
import { LinkCreatedComponent } from './components/drawings-listeners/link-created/link-created.component';
|
||||||
import { NodeDraggedComponent } from './components/drawings-listeners/node-dragged/node-dragged.component';
|
import { NodeDraggedComponent } from './components/drawings-listeners/node-dragged/node-dragged.component';
|
||||||
import { NodeLabelDraggedComponent } from './components/drawings-listeners/node-label-dragged/node-label-dragged.component';
|
import { NodeLabelDraggedComponent } from './components/drawings-listeners/node-label-dragged/node-label-dragged.component';
|
||||||
import { DrawingDraggedComponent } from './components/drawings-listeners/drawing-dragged/drawing-dragged.component';
|
|
||||||
import { LinkCreatedComponent } from './components/drawings-listeners/link-created/link-created.component';
|
|
||||||
import { InterfaceLabelDraggedComponent } from './components/drawings-listeners/interface-label-dragged/interface-label-dragged.component';
|
|
||||||
import { ToolsService } from './services/tools.service';
|
|
||||||
import { TextAddedComponent } from './components/drawings-listeners/text-added/text-added.component';
|
import { TextAddedComponent } from './components/drawings-listeners/text-added/text-added.component';
|
||||||
import { DrawingAddedComponent } from './components/drawings-listeners/drawing-added/drawing-added.component';
|
import { TextEditedComponent } from './components/drawings-listeners/text-edited/text-edited.component';
|
||||||
|
import { HelpComponent } from './components/help/help.component';
|
||||||
import { InstallSoftwareComponent } from './components/installed-software/install-software/install-software.component';
|
import { InstallSoftwareComponent } from './components/installed-software/install-software/install-software.component';
|
||||||
|
import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component';
|
||||||
import { StyleEditorDialogComponent } from './components/project-map/drawings-editors/style-editor/style-editor.component';
|
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
|
||||||
import { EditTextActionComponent } from './components/project-map/context-menu/actions/edit-text-action/edit-text-action.component';
|
|
||||||
import { TextEditorDialogComponent } from './components/project-map/drawings-editors/text-editor/text-editor.component';
|
|
||||||
import { PreferencesComponent } from './components/preferences/preferences.component';
|
|
||||||
import { QemuPreferencesComponent } from './components/preferences/qemu/qemu-preferences/qemu-preferences.component';
|
|
||||||
import { ServerSettingsService } from './services/server-settings.service';
|
|
||||||
import { QemuVmTemplatesComponent } from './components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component';
|
|
||||||
import { AddQemuVmTemplateComponent } from './components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component';
|
|
||||||
import { QemuVmTemplateDetailsComponent } from './components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component';
|
|
||||||
import { QemuService } from './services/qemu.service';
|
|
||||||
import { GeneralPreferencesComponent } from './components/preferences/general/general-preferences.component';
|
|
||||||
import { VpcsPreferencesComponent } from './components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component';
|
|
||||||
import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component';
|
|
||||||
import { VpcsService } from './services/vpcs.service';
|
|
||||||
import { AddVpcsTemplateComponent } from './components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component';
|
|
||||||
import { VpcsTemplateDetailsComponent } from './components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component';
|
|
||||||
import { TemplateMocksService } from './services/template-mocks.service';
|
|
||||||
import { VirtualBoxPreferencesComponent } from './components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component';
|
|
||||||
import { VirtualBoxTemplatesComponent } from './components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component';
|
|
||||||
import { VirtualBoxService } from './services/virtual-box.service';
|
|
||||||
import { VirtualBoxTemplateDetailsComponent } from './components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component';
|
|
||||||
import { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component';
|
|
||||||
import { BuiltInPreferencesComponent } from './components/preferences/built-in/built-in-preferences.component';
|
import { BuiltInPreferencesComponent } from './components/preferences/built-in/built-in-preferences.component';
|
||||||
import { EthernetHubsTemplatesComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component';
|
|
||||||
import { BuiltInTemplatesService } from './services/built-in-templates.service';
|
|
||||||
import { EthernetHubsAddTemplateComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component';
|
|
||||||
import { EthernetHubsTemplateDetailsComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component';
|
|
||||||
import { CloudNodesTemplatesComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component';
|
|
||||||
import { CloudNodesAddTemplateComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component';
|
import { CloudNodesAddTemplateComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-add-template/cloud-nodes-add-template.component';
|
||||||
import { CloudNodesTemplateDetailsComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component';
|
import { CloudNodesTemplateDetailsComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-template-details/cloud-nodes-template-details.component';
|
||||||
import { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component';
|
import { CloudNodesTemplatesComponent } from './components/preferences/built-in/cloud-nodes/cloud-nodes-templates/cloud-nodes-templates.component';
|
||||||
|
import { EthernetHubsAddTemplateComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-add-template/ethernet-hubs-add-template.component';
|
||||||
|
import { EthernetHubsTemplateDetailsComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-template-details/ethernet-hubs-template-details.component';
|
||||||
|
import { EthernetHubsTemplatesComponent } from './components/preferences/built-in/ethernet-hubs/ethernet-hubs-templates/ethernet-hubs-templates.component';
|
||||||
import { EthernetSwitchesAddTemplateComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component';
|
import { EthernetSwitchesAddTemplateComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-add-template/ethernet-switches-add-template.component';
|
||||||
import { EthernetSwitchesTemplateDetailsComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component';
|
import { EthernetSwitchesTemplateDetailsComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-template-details/ethernet-switches-template-details.component';
|
||||||
import { DynamipsPreferencesComponent } from './components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component';
|
import { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component';
|
||||||
import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component';
|
import { CustomAdaptersTableComponent } from './components/preferences/common/custom-adapters-table/custom-adapters-table.component';
|
||||||
import { IosService } from './services/ios.service';
|
import { CustomAdaptersComponent } from './components/preferences/common/custom-adapters/custom-adapters.component';
|
||||||
import { SymbolsComponent } from './components/preferences/common/symbols/symbols.component';
|
|
||||||
import { InstalledSoftwareService } from './services/installed-software.service';
|
|
||||||
import { ExternalSoftwareDefinitionService } from './services/external-software-definition.service';
|
|
||||||
import { PlatformService } from './services/platform.service';
|
|
||||||
import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component';
|
|
||||||
import { AddIosTemplateComponent } from './components/preferences/dynamips/add-ios-template/add-ios-template.component';
|
|
||||||
import { IosConfigurationService } from './services/ios-configuration.service';
|
|
||||||
import { QemuConfigurationService } from './services/qemu-configuration.service';
|
|
||||||
import { VirtualBoxConfigurationService } from './services/virtual-box-configuration.service';
|
|
||||||
import { VpcsConfigurationService } from './services/vpcs-configuration.service';
|
|
||||||
import { BuiltInTemplatesConfigurationService } from './services/built-in-templates-configuration.service';
|
|
||||||
import { VmwarePreferencesComponent } from './components/preferences/vmware/vmware-preferences/vmware-preferences.component';
|
|
||||||
import { VmwareTemplatesComponent } from './components/preferences/vmware/vmware-templates/vmware-templates.component';
|
|
||||||
import { VmwareService } from './services/vmware.service';
|
|
||||||
import { VmwareConfigurationService } from './services/vmware-configuration.service';
|
|
||||||
import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/vmware-template-details/vmware-template-details.component';
|
|
||||||
import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component';
|
|
||||||
import { DeleteConfirmationDialogComponent } from './components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component';
|
import { DeleteConfirmationDialogComponent } from './components/preferences/common/delete-confirmation-dialog/delete-confirmation-dialog.component';
|
||||||
import { DeleteTemplateComponent } from './components/preferences/common/delete-template-component/delete-template.component';
|
import { DeleteTemplateComponent } from './components/preferences/common/delete-template-component/delete-template.component';
|
||||||
import { DockerService } from './services/docker.service';
|
|
||||||
import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component';
|
|
||||||
import { DockerConfigurationService } from './services/docker-configuration.service';
|
|
||||||
import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-docker-template.component';
|
|
||||||
import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component';
|
|
||||||
import { IouTemplatesComponent } from './components/preferences/ios-on-unix/iou-templates/iou-templates.component';
|
|
||||||
import { IouService } from './services/iou.service';
|
|
||||||
import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component';
|
|
||||||
import { IouConfigurationService } from './services/iou-configuration.service';
|
|
||||||
import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component';
|
|
||||||
import { CopyQemuVmTemplateComponent } from './components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component';
|
|
||||||
import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy-ios-template/copy-ios-template.component';
|
|
||||||
import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component';
|
|
||||||
import { CopyDockerTemplateComponent } from './components/preferences/docker/copy-docker-template/copy-docker-template.component';
|
|
||||||
import { EmptyTemplatesListComponent } from './components/preferences/common/empty-templates-list/empty-templates-list.component';
|
import { EmptyTemplatesListComponent } from './components/preferences/common/empty-templates-list/empty-templates-list.component';
|
||||||
import { SymbolsMenuComponent } from './components/preferences/common/symbols-menu/symbols-menu.component';
|
|
||||||
import { SearchFilter } from './filters/searchFilter.pipe';
|
|
||||||
import { RecentlyOpenedProjectService } from './services/recentlyOpenedProject.service';
|
|
||||||
import { ServerManagementService } from './services/server-management.service';
|
|
||||||
import { DeleteActionComponent } from './components/project-map/context-menu/actions/delete-action/delete-action.component';
|
|
||||||
import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component';
|
|
||||||
import { DateFilter } from './filters/dateFilter.pipe';
|
|
||||||
import { NameFilter } from './filters/nameFilter.pipe';
|
|
||||||
import { CustomAdaptersComponent } from './components/preferences/common/custom-adapters/custom-adapters.component';
|
|
||||||
|
|
||||||
import { ConsoleDeviceActionComponent } from './components/project-map/context-menu/actions/console-device-action/console-device-action.component';
|
|
||||||
import { ConsoleComponent } from './components/settings/console/console.component';
|
|
||||||
import { NodesMenuComponent } from './components/project-map/nodes-menu/nodes-menu.component';
|
|
||||||
import { PacketFiltersActionComponent } from './components/project-map/context-menu/actions/packet-filters-action/packet-filters-action.component';
|
|
||||||
import { PacketFiltersDialogComponent } from './components/project-map/packet-capturing/packet-filters/packet-filters.component';
|
|
||||||
import { HelpDialogComponent } from './components/project-map/help-dialog/help-dialog.component';
|
|
||||||
import { StartCaptureActionComponent } from './components/project-map/context-menu/actions/start-capture/start-capture-action.component';
|
|
||||||
import { StartCaptureDialogComponent } from './components/project-map/packet-capturing/start-capture/start-capture.component';
|
|
||||||
import { SuspendLinkActionComponent } from './components/project-map/context-menu/actions/suspend-link/suspend-link-action.component';
|
|
||||||
import { ResumeLinkActionComponent } from './components/project-map/context-menu/actions/resume-link-action/resume-link-action.component';
|
|
||||||
import { StopCaptureActionComponent } from './components/project-map/context-menu/actions/stop-capture/stop-capture-action.component';
|
|
||||||
import { MapScaleService } from './services/mapScale.service';
|
|
||||||
import { AdbutlerComponent } from './components/adbutler/adbutler.component';
|
|
||||||
import { ConsoleService } from './services/settings/console.service';
|
|
||||||
import { DefaultConsoleService } from './services/settings/default-console.service';
|
|
||||||
import { NodeCreatedLabelStylesFixer } from './components/project-map/helpers/node-created-label-styles-fixer';
|
|
||||||
import { NotificationBoxComponent } from './components/notification-box/notification-box.component';
|
|
||||||
import { NonNegativeValidator } from './validators/non-negative-validator';
|
|
||||||
import { RotationValidator } from './validators/rotation-validator';
|
|
||||||
import { DuplicateActionComponent } from './components/project-map/context-menu/actions/duplicate-action/duplicate-action.component';
|
|
||||||
import { MapSettingsService } from './services/mapsettings.service';
|
|
||||||
import { ProjectMapMenuComponent } from './components/project-map/project-map-menu/project-map-menu.component';
|
|
||||||
import { HelpComponent } from './components/help/help.component';
|
|
||||||
import { ConfigEditorDialogComponent } from './components/project-map/node-editors/config-editor/config-editor.component';
|
|
||||||
import { EditConfigActionComponent } from './components/project-map/context-menu/actions/edit-config/edit-config-action.component';
|
|
||||||
import { LogConsoleComponent } from './components/project-map/log-console/log-console.component';
|
|
||||||
import { LogEventsDataSource } from './components/project-map/log-console/log-events-datasource';
|
|
||||||
import { SaveProjectDialogComponent } from './components/projects/save-project-dialog/save-project-dialog.component';
|
|
||||||
import { TopologySummaryComponent } from './components/topology-summary/topology-summary.component';
|
|
||||||
import { ShowNodeActionComponent } from './components/project-map/context-menu/actions/show-node-action/show-node-action.component';
|
|
||||||
import { InfoDialogComponent } from './components/project-map/info-dialog/info-dialog.component';
|
|
||||||
import { InfoService } from './services/info.service';
|
|
||||||
import { BringToFrontActionComponent } from './components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component';
|
|
||||||
import { ExportConfigActionComponent } from './components/project-map/context-menu/actions/export-config/export-config-action.component';
|
|
||||||
import { ImportConfigActionComponent } from './components/project-map/context-menu/actions/import-config/import-config-action.component';
|
|
||||||
import { ConsoleDeviceActionBrowserComponent } from './components/project-map/context-menu/actions/console-device-action-browser/console-device-action-browser.component';
|
|
||||||
import { ChangeSymbolDialogComponent } from './components/project-map/change-symbol-dialog/change-symbol-dialog.component';
|
|
||||||
import { ChangeSymbolActionComponent } from './components/project-map/context-menu/actions/change-symbol/change-symbol-action.component';
|
|
||||||
import { EditProjectDialogComponent } from './components/projects/edit-project-dialog/edit-project-dialog.component';
|
|
||||||
import { ProjectsFilter } from './filters/projectsFilter.pipe';
|
|
||||||
import { ComputeService } from './services/compute.service';
|
|
||||||
import { ReloadNodeActionComponent } from './components/project-map/context-menu/actions/reload-node-action/reload-node-action.component';
|
|
||||||
import { SuspendNodeActionComponent } from './components/project-map/context-menu/actions/suspend-node-action/suspend-node-action.component';
|
|
||||||
import { ConfigActionComponent } from './components/project-map/context-menu/actions/config-action/config-action.component';
|
|
||||||
import { ConfiguratorDialogVpcsComponent } from './components/project-map/node-editors/configurator/vpcs/configurator-vpcs.component';
|
|
||||||
import { ConfiguratorDialogEthernetHubComponent } from './components/project-map/node-editors/configurator/ethernet_hub/configurator-ethernet-hub.component';
|
|
||||||
import { ConfiguratorDialogEthernetSwitchComponent } from './components/project-map/node-editors/configurator/ethernet-switch/configurator-ethernet-switch.component';
|
|
||||||
import { PortsComponent } from './components/preferences/common/ports/ports.component';
|
import { PortsComponent } from './components/preferences/common/ports/ports.component';
|
||||||
import { ConfiguratorDialogSwitchComponent } from './components/project-map/node-editors/configurator/switch/configurator-switch.component';
|
import { SymbolsMenuComponent } from './components/preferences/common/symbols-menu/symbols-menu.component';
|
||||||
import { ConfiguratorDialogVirtualBoxComponent } from './components/project-map/node-editors/configurator/virtualbox/configurator-virtualbox.component';
|
import { SymbolsComponent } from './components/preferences/common/symbols/symbols.component';
|
||||||
import { CustomAdaptersTableComponent } from './components/preferences/common/custom-adapters-table/custom-adapters-table.component';
|
|
||||||
import { ConfiguratorDialogQemuComponent } from './components/project-map/node-editors/configurator/qemu/configurator-qemu.component';
|
|
||||||
import { ConfiguratorDialogCloudComponent } from './components/project-map/node-editors/configurator/cloud/configurator-cloud.component';
|
|
||||||
import { UdpTunnelsComponent } from './components/preferences/common/udp-tunnels/udp-tunnels.component';
|
import { UdpTunnelsComponent } from './components/preferences/common/udp-tunnels/udp-tunnels.component';
|
||||||
import { ConfiguratorDialogAtmSwitchComponent } from './components/project-map/node-editors/configurator/atm_switch/configurator-atm-switch.component';
|
import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-docker-template.component';
|
||||||
import { ConfiguratorDialogVmwareComponent } from './components/project-map/node-editors/configurator/vmware/configurator-vmware.component';
|
import { CopyDockerTemplateComponent } from './components/preferences/docker/copy-docker-template/copy-docker-template.component';
|
||||||
import { ConfiguratorDialogIouComponent } from './components/project-map/node-editors/configurator/iou/configurator-iou.component';
|
import { DockerTemplateDetailsComponent } from './components/preferences/docker/docker-template-details/docker-template-details.component';
|
||||||
import { ConfiguratorDialogIosComponent } from './components/project-map/node-editors/configurator/ios/configurator-ios.component';
|
import { DockerTemplatesComponent } from './components/preferences/docker/docker-templates/docker-templates.component';
|
||||||
import { ConfiguratorDialogDockerComponent } from './components/project-map/node-editors/configurator/docker/configurator-docker.component';
|
import { AddIosTemplateComponent } from './components/preferences/dynamips/add-ios-template/add-ios-template.component';
|
||||||
import { ConfiguratorDialogNatComponent } from './components/project-map/node-editors/configurator/nat/configurator-nat.component';
|
import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy-ios-template/copy-ios-template.component';
|
||||||
import { ConfiguratorDialogTracengComponent } from './components/project-map/node-editors/configurator/traceng/configurator-traceng.component';
|
import { DynamipsPreferencesComponent } from './components/preferences/dynamips/dynamips-preferences/dynamips-preferences.component';
|
||||||
import { AddTracengTemplateComponent } from './components/preferences/traceng/add-traceng/add-traceng-template.component';
|
import { IosTemplateDetailsComponent } from './components/preferences/dynamips/ios-template-details/ios-template-details.component';
|
||||||
import { TracengPreferencesComponent } from './components/preferences/traceng/traceng-preferences/traceng-preferences.component';
|
import { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component';
|
||||||
import { TracengTemplatesComponent } from './components/preferences/traceng/traceng-templates/traceng-templates.component';
|
import { GeneralPreferencesComponent } from './components/preferences/general/general-preferences.component';
|
||||||
import { TracengService } from './services/traceng.service';
|
import { AddIouTemplateComponent } from './components/preferences/ios-on-unix/add-iou-template/add-iou-template.component';
|
||||||
import { TracengTemplateDetailsComponent } from './components/preferences/traceng/traceng-template-details/traceng-template-details.component';
|
import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component';
|
||||||
import { QemuImageCreatorComponent } from './components/project-map/node-editors/configurator/qemu/qemu-image-creator/qemu-image-creator.component';
|
import { IouTemplateDetailsComponent } from './components/preferences/ios-on-unix/iou-template-details/iou-template-details.component';
|
||||||
import { ChooseNameDialogComponent } from './components/projects/choose-name-dialog/choose-name-dialog.component';
|
import { IouTemplatesComponent } from './components/preferences/ios-on-unix/iou-templates/iou-templates.component';
|
||||||
import { PacketCaptureService } from './services/packet-capture.service';
|
import { PreferencesComponent } from './components/preferences/preferences.component';
|
||||||
import { StartCaptureOnStartedLinkActionComponent } from './components/project-map/context-menu/actions/start-capture-on-started-link/start-capture-on-started-link.component';
|
import { AddQemuVmTemplateComponent } from './components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component';
|
||||||
import { LockActionComponent } from './components/project-map/context-menu/actions/lock-action/lock-action.component';
|
import { CopyQemuVmTemplateComponent } from './components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component';
|
||||||
import { NavigationDialogComponent } from './components/projects/navigation-dialog/navigation-dialog.component';
|
import { QemuPreferencesComponent } from './components/preferences/qemu/qemu-preferences/qemu-preferences.component';
|
||||||
import { ScreenshotDialogComponent } from './components/project-map/screenshot-dialog/screenshot-dialog.component';
|
import { QemuVmTemplateDetailsComponent } from './components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component';
|
||||||
import { ResizableModule } from 'angular-resizable-element';
|
import { QemuVmTemplatesComponent } from './components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component';
|
||||||
import { DragAndDropModule } from 'angular-draggable-droppable';
|
import { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component';
|
||||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
import { VirtualBoxPreferencesComponent } from './components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.component';
|
||||||
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
|
import { VirtualBoxTemplateDetailsComponent } from './components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component';
|
||||||
|
import { VirtualBoxTemplatesComponent } from './components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component';
|
||||||
|
import { AddVmwareTemplateComponent } from './components/preferences/vmware/add-vmware-template/add-vmware-template.component';
|
||||||
|
import { VmwarePreferencesComponent } from './components/preferences/vmware/vmware-preferences/vmware-preferences.component';
|
||||||
|
import { VmwareTemplateDetailsComponent } from './components/preferences/vmware/vmware-template-details/vmware-template-details.component';
|
||||||
|
import { VmwareTemplatesComponent } from './components/preferences/vmware/vmware-templates/vmware-templates.component';
|
||||||
|
import { AddVpcsTemplateComponent } from './components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component';
|
||||||
|
import { VpcsPreferencesComponent } from './components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component';
|
||||||
|
import { VpcsTemplateDetailsComponent } from './components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component';
|
||||||
|
import { VpcsTemplatesComponent } from './components/preferences/vpcs/vpcs-templates/vpcs-templates.component';
|
||||||
|
import { ChangeHostnameDialogComponent } from './components/project-map/change-hostname-dialog/change-hostname-dialog.component';
|
||||||
|
import { ChangeSymbolDialogComponent } from './components/project-map/change-symbol-dialog/change-symbol-dialog.component';
|
||||||
|
import { ConsoleWrapperComponent } from './components/project-map/console-wrapper/console-wrapper.component';
|
||||||
|
import { ContextConsoleMenuComponent } from './components/project-map/context-console-menu/context-console-menu.component';
|
||||||
import { AlignHorizontallyActionComponent } from './components/project-map/context-menu/actions/align-horizontally/align-horizontally.component';
|
import { AlignHorizontallyActionComponent } from './components/project-map/context-menu/actions/align-horizontally/align-horizontally.component';
|
||||||
import { AlignVerticallyActionComponent } from './components/project-map/context-menu/actions/align_vertically/align-vertically.component';
|
import { AlignVerticallyActionComponent } from './components/project-map/context-menu/actions/align_vertically/align-vertically.component';
|
||||||
import { ConfirmationBottomSheetComponent } from './components/projects/confirmation-bottomsheet/confirmation-bottomsheet.component';
|
import { BringToFrontActionComponent } from './components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component';
|
||||||
import { TemplateFilter } from './filters/templateFilter.pipe';
|
import { ChangeHostnameActionComponent } from './components/project-map/context-menu/actions/change-hostname/change-hostname-action.component';
|
||||||
import { NotificationService } from './services/notification.service';
|
import { ChangeSymbolActionComponent } from './components/project-map/context-menu/actions/change-symbol/change-symbol-action.component';
|
||||||
import { DeviceDetectorModule } from 'ngx-device-detector';
|
import { ConfigActionComponent } from './components/project-map/context-menu/actions/config-action/config-action.component';
|
||||||
import { ConfigDialogComponent } from './components/project-map/context-menu/dialogs/config-dialog/config-dialog.component';
|
import { ConsoleDeviceActionBrowserComponent } from './components/project-map/context-menu/actions/console-device-action-browser/console-device-action-browser.component';
|
||||||
import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.component';
|
import { ConsoleDeviceActionComponent } from './components/project-map/context-menu/actions/console-device-action/console-device-action.component';
|
||||||
import { Gns3vmService } from './services/gns3vm.service';
|
import { DeleteActionComponent } from './components/project-map/context-menu/actions/delete-action/delete-action.component';
|
||||||
import { ThemeService } from './services/theme.service';
|
import { DuplicateActionComponent } from './components/project-map/context-menu/actions/duplicate-action/duplicate-action.component';
|
||||||
import { ConfigureGns3VMDialogComponent } from './components/servers/configure-gns3vm-dialog/configure-gns3vm-dialog.component';
|
import { EditConfigActionComponent } from './components/project-map/context-menu/actions/edit-config/edit-config-action.component';
|
||||||
import { ImportApplianceComponent } from './components/project-map/import-appliance/import-appliance.component';
|
import { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-action.component';
|
||||||
import { GoogleAnalyticsService } from './services/google-analytics.service';
|
import { EditLinkStyleActionComponent } from './components/project-map/context-menu/actions/edit-link-style-action/edit-link-style-action.component';
|
||||||
import { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
import { EditTextActionComponent } from './components/project-map/context-menu/actions/edit-text-action/edit-text-action.component';
|
||||||
import { SystemStatusComponent } from './components/system-status/system-status.component';
|
import { ExportConfigActionComponent } from './components/project-map/context-menu/actions/export-config/export-config-action.component';
|
||||||
import { StatusInfoComponent } from './components/system-status/status-info/status-info.component';
|
import { HttpConsoleNewTabActionComponent } from './components/project-map/context-menu/actions/http-console-new-tab/http-console-new-tab-action.component';
|
||||||
import { StatusChartComponent } from './components/system-status/status-chart/status-chart.component';
|
import { HttpConsoleActionComponent } from './components/project-map/context-menu/actions/http-console/http-console-action.component';
|
||||||
import { NgCircleProgressModule } from 'ng-circle-progress';
|
import { ImportConfigActionComponent } from './components/project-map/context-menu/actions/import-config/import-config-action.component';
|
||||||
|
import { LockActionComponent } from './components/project-map/context-menu/actions/lock-action/lock-action.component';
|
||||||
|
import { MoveLayerDownActionComponent } from './components/project-map/context-menu/actions/move-layer-down-action/move-layer-down-action.component';
|
||||||
|
import { MoveLayerUpActionComponent } from './components/project-map/context-menu/actions/move-layer-up-action/move-layer-up-action.component';
|
||||||
import { OpenFileExplorerActionComponent } from './components/project-map/context-menu/actions/open-file-explorer/open-file-explorer-action.component';
|
import { OpenFileExplorerActionComponent } from './components/project-map/context-menu/actions/open-file-explorer/open-file-explorer-action.component';
|
||||||
import { NgxChildProcessModule } from 'ngx-childprocess';
|
import { PacketFiltersActionComponent } from './components/project-map/context-menu/actions/packet-filters-action/packet-filters-action.component';
|
||||||
import { ServerResolve } from './resolvers/server-resolve';
|
import { ReloadNodeActionComponent } from './components/project-map/context-menu/actions/reload-node-action/reload-node-action.component';
|
||||||
import { ProjectMapGuard } from './guards/project-map-guard';
|
import { ResumeLinkActionComponent } from './components/project-map/context-menu/actions/resume-link-action/resume-link-action.component';
|
||||||
|
import { ShowNodeActionComponent } from './components/project-map/context-menu/actions/show-node-action/show-node-action.component';
|
||||||
if (environment.production) {
|
import { StartCaptureOnStartedLinkActionComponent } from './components/project-map/context-menu/actions/start-capture-on-started-link/start-capture-on-started-link.component';
|
||||||
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
|
import { StartCaptureActionComponent } from './components/project-map/context-menu/actions/start-capture/start-capture-action.component';
|
||||||
shouldSendCallback: () => {
|
import { StartNodeActionComponent } from './components/project-map/context-menu/actions/start-node-action/start-node-action.component';
|
||||||
return RavenState.shouldSend;
|
import { StopCaptureActionComponent } from './components/project-map/context-menu/actions/stop-capture/stop-capture-action.component';
|
||||||
},
|
import { IsolateNodeActionComponent } from './components/project-map/context-menu/actions/isolate-node-action/isolate-node-action.component';
|
||||||
release: version
|
import { UnisolateNodeActionComponent } from './components/project-map/context-menu/actions/unisolate-node-action/unisolate-node-action.component';
|
||||||
}).install();
|
import {StopNodeActionComponent } from './components/project-map/context-menu/actions/stop-node-action/stop-node-action.component';
|
||||||
}
|
import { SuspendLinkActionComponent } from './components/project-map/context-menu/actions/suspend-link/suspend-link-action.component';
|
||||||
|
import { SuspendNodeActionComponent } from './components/project-map/context-menu/actions/suspend-node-action/suspend-node-action.component';
|
||||||
|
import { ContextMenuComponent } from './components/project-map/context-menu/context-menu.component';
|
||||||
|
import { ConfigDialogComponent } from './components/project-map/context-menu/dialogs/config-dialog/config-dialog.component';
|
||||||
|
import { DrawLinkToolComponent } from './components/project-map/draw-link-tool/draw-link-tool.component';
|
||||||
|
import { StyleEditorDialogComponent } from './components/project-map/drawings-editors/style-editor/style-editor.component';
|
||||||
|
import { LinkStyleEditorDialogComponent } from './components/project-map/drawings-editors/link-style-editor/link-style-editor.component';
|
||||||
|
import { TextEditorDialogComponent } from './components/project-map/drawings-editors/text-editor/text-editor.component';
|
||||||
|
import { HelpDialogComponent } from './components/project-map/help-dialog/help-dialog.component';
|
||||||
|
import { NodeCreatedLabelStylesFixer } from './components/project-map/helpers/node-created-label-styles-fixer';
|
||||||
|
import { ImportApplianceComponent } from './components/project-map/import-appliance/import-appliance.component';
|
||||||
|
import { InfoDialogComponent } from './components/project-map/info-dialog/info-dialog.component';
|
||||||
|
import { LogConsoleComponent } from './components/project-map/log-console/log-console.component';
|
||||||
|
import { LogEventsDataSource } from './components/project-map/log-console/log-events-datasource';
|
||||||
|
import { ApplianceInfoDialogComponent } from './components/project-map/new-template-dialog/appliance-info-dialog/appliance-info-dialog.component';
|
||||||
|
import { NewTemplateDialogComponent } from './components/project-map/new-template-dialog/new-template-dialog.component';
|
||||||
|
import { TemplateNameDialogComponent } from './components/project-map/new-template-dialog/template-name-dialog/template-name-dialog.component';
|
||||||
|
import { ConfigEditorDialogComponent } from './components/project-map/node-editors/config-editor/config-editor.component';
|
||||||
|
import { ConfiguratorDialogAtmSwitchComponent } from './components/project-map/node-editors/configurator/atm_switch/configurator-atm-switch.component';
|
||||||
|
import { ConfiguratorDialogCloudComponent } from './components/project-map/node-editors/configurator/cloud/configurator-cloud.component';
|
||||||
|
import { ConfiguratorDialogDockerComponent } from './components/project-map/node-editors/configurator/docker/configurator-docker.component';
|
||||||
|
import { ConfigureCustomAdaptersDialogComponent } from './components/project-map/node-editors/configurator/docker/configure-custom-adapters/configure-custom-adapters.component';
|
||||||
|
import { EditNetworkConfigurationDialogComponent } from './components/project-map/node-editors/configurator/docker/edit-network-configuration/edit-network-configuration.component';
|
||||||
|
import { ConfiguratorDialogEthernetSwitchComponent } from './components/project-map/node-editors/configurator/ethernet-switch/configurator-ethernet-switch.component';
|
||||||
|
import { ConfiguratorDialogEthernetHubComponent } from './components/project-map/node-editors/configurator/ethernet_hub/configurator-ethernet-hub.component';
|
||||||
|
import { ConfiguratorDialogIosComponent } from './components/project-map/node-editors/configurator/ios/configurator-ios.component';
|
||||||
|
import { ConfiguratorDialogIouComponent } from './components/project-map/node-editors/configurator/iou/configurator-iou.component';
|
||||||
|
import { ConfiguratorDialogNatComponent } from './components/project-map/node-editors/configurator/nat/configurator-nat.component';
|
||||||
|
import { ConfiguratorDialogQemuComponent } from './components/project-map/node-editors/configurator/qemu/configurator-qemu.component';
|
||||||
|
import { QemuImageCreatorComponent } from './components/project-map/node-editors/configurator/qemu/qemu-image-creator/qemu-image-creator.component';
|
||||||
|
import { ConfiguratorDialogSwitchComponent } from './components/project-map/node-editors/configurator/switch/configurator-switch.component';
|
||||||
|
import { ConfiguratorDialogVirtualBoxComponent } from './components/project-map/node-editors/configurator/virtualbox/configurator-virtualbox.component';
|
||||||
|
import { ConfiguratorDialogVmwareComponent } from './components/project-map/node-editors/configurator/vmware/configurator-vmware.component';
|
||||||
|
import { ConfiguratorDialogVpcsComponent } from './components/project-map/node-editors/configurator/vpcs/configurator-vpcs.component';
|
||||||
|
import { NodeSelectInterfaceComponent } from './components/project-map/node-select-interface/node-select-interface.component';
|
||||||
|
import { NodesMenuComponent } from './components/project-map/nodes-menu/nodes-menu.component';
|
||||||
|
import { PacketFiltersDialogComponent } from './components/project-map/packet-capturing/packet-filters/packet-filters.component';
|
||||||
|
import { StartCaptureDialogComponent } from './components/project-map/packet-capturing/start-capture/start-capture.component';
|
||||||
|
import { ProjectMapMenuComponent } from './components/project-map/project-map-menu/project-map-menu.component';
|
||||||
|
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
||||||
|
import { ProjectReadmeComponent } from './components/project-map/project-readme/project-readme.component';
|
||||||
|
import { ScreenshotDialogComponent } from './components/project-map/screenshot-dialog/screenshot-dialog.component';
|
||||||
|
import { WebConsoleComponent } from './components/project-map/web-console/web-console.component';
|
||||||
|
import { AddBlankProjectDialogComponent } from './components/projects/add-blank-project-dialog/add-blank-project-dialog.component';
|
||||||
|
import { ChooseNameDialogComponent } from './components/projects/choose-name-dialog/choose-name-dialog.component';
|
||||||
|
import { ConfirmationBottomSheetComponent } from './components/projects/confirmation-bottomsheet/confirmation-bottomsheet.component';
|
||||||
|
import { ConfirmationDialogComponent } from './components/projects/confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { EditProjectDialogComponent } from './components/projects/edit-project-dialog/edit-project-dialog.component';
|
||||||
|
import { ReadmeEditorComponent } from './components/projects/edit-project-dialog/readme-editor/readme-editor.component';
|
||||||
|
import { ImportProjectDialogComponent } from './components/projects/import-project-dialog/import-project-dialog.component';
|
||||||
|
import { ProjectNameValidator } from './components/projects/models/projectNameValidator';
|
||||||
|
import { NavigationDialogComponent } from './components/projects/navigation-dialog/navigation-dialog.component';
|
||||||
|
import { ProjectsComponent } from './components/projects/projects.component';
|
||||||
|
import { SaveProjectDialogComponent } from './components/projects/save-project-dialog/save-project-dialog.component';
|
||||||
|
import { AddControllerDialogComponent } from './components/controllers/add-controller-dialog/add-controller-dialog.component';
|
||||||
|
import { ControllerDiscoveryComponent } from './components/controllers/controller-discovery/controller-discovery.component';
|
||||||
|
import { ControllersComponent } from './components/controllers/controllers.component';
|
||||||
|
import { ConsoleComponent } from './components/settings/console/console.component';
|
||||||
|
import { SettingsComponent } from './components/settings/settings.component';
|
||||||
|
import { CreateSnapshotDialogComponent } from './components/snapshots/create-snapshot-dialog/create-snapshot-dialog.component';
|
||||||
|
import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component';
|
||||||
|
import { SnapshotMenuItemComponent } from './components/snapshots/snapshot-menu-item/snapshot-menu-item.component';
|
||||||
|
import { StatusChartComponent } from './components/system-status/status-chart/status-chart.component';
|
||||||
|
import { StatusInfoComponent } from './components/system-status/status-info/status-info.component';
|
||||||
|
import { SystemStatusComponent } from './components/system-status/system-status.component';
|
||||||
|
import { TemplateListDialogComponent } from './components/template/template-list-dialog/template-list-dialog.component';
|
||||||
|
import { TemplateComponent } from './components/template/template.component';
|
||||||
|
import { TopologySummaryComponent } from './components/topology-summary/topology-summary.component';
|
||||||
|
import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component';
|
||||||
|
import { DataSourceFilter } from './filters/dataSourceFilter';
|
||||||
|
import { AuthImageFilter } from './filters/authImageFilter';
|
||||||
|
import { DateFilter } from './filters/dateFilter.pipe';
|
||||||
|
import { NameFilter } from './filters/nameFilter.pipe';
|
||||||
|
import { ProjectsFilter } from './filters/projectsFilter.pipe';
|
||||||
|
import { SearchFilter } from './filters/searchFilter.pipe';
|
||||||
|
import { TemplateFilter } from './filters/templateFilter.pipe';
|
||||||
|
import { ConsoleGuard } from './guards/console-guard';
|
||||||
|
import { LoginGuard } from './guards/login-guard';
|
||||||
|
import { ProjectWebServiceHandler } from './handlers/project-web-service-handler';
|
||||||
|
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
||||||
|
import { MATERIAL_IMPORTS } from './material.imports';
|
||||||
|
import { ControllerResolve } from './resolvers/controller-resolve';
|
||||||
|
import { ApplianceService } from './services/appliances.service';
|
||||||
|
import { BuiltInTemplatesConfigurationService } from './services/built-in-templates-configuration.service';
|
||||||
|
import { BuiltInTemplatesService } from './services/built-in-templates.service';
|
||||||
|
import { ComputeService } from './services/compute.service';
|
||||||
|
import { DockerConfigurationService } from './services/docker-configuration.service';
|
||||||
|
import { DockerService } from './services/docker.service';
|
||||||
|
import { DrawingService } from './services/drawing.service';
|
||||||
|
import { ExternalSoftwareDefinitionService } from './services/external-software-definition.service';
|
||||||
|
import { GoogleAnalyticsService } from './services/google-analytics.service';
|
||||||
|
import { HttpController, ControllerErrorHandler } from './services/http-controller.service';
|
||||||
|
import { InfoService } from './services/info.service';
|
||||||
|
import { InstalledSoftwareService } from './services/installed-software.service';
|
||||||
|
import { IosConfigurationService } from './services/ios-configuration.service';
|
||||||
|
import { IosService } from './services/ios.service';
|
||||||
|
import { IouConfigurationService } from './services/iou-configuration.service';
|
||||||
|
import { IouService } from './services/iou.service';
|
||||||
|
import { LinkService } from './services/link.service';
|
||||||
|
import { MapScaleService } from './services/mapScale.service';
|
||||||
|
import { MapSettingsService } from './services/mapsettings.service';
|
||||||
|
import { NodeService } from './services/node.service';
|
||||||
|
import { NodeConsoleService } from './services/nodeConsole.service';
|
||||||
|
import { NotificationService } from './services/notification.service';
|
||||||
|
import { PacketCaptureService } from './services/packet-capture.service';
|
||||||
|
import { PlatformService } from './services/platform.service';
|
||||||
|
import { ProjectService } from './services/project.service';
|
||||||
|
import { QemuConfigurationService } from './services/qemu-configuration.service';
|
||||||
|
import { QemuService } from './services/qemu.service';
|
||||||
|
import { RecentlyOpenedProjectService } from './services/recentlyOpenedProject.service';
|
||||||
|
import { ControllerManagementService } from './services/controller-management.service';
|
||||||
|
import { ControllerSettingsService } from './services/controller-settings.service';
|
||||||
|
import { ControllerDatabase } from './services/controller.database';
|
||||||
|
import { ControllerService } from './services/controller.service';
|
||||||
|
import { SettingsService } from './services/settings.service';
|
||||||
|
import { ConsoleService } from './services/settings/console.service';
|
||||||
|
import { DefaultConsoleService } from './services/settings/default-console.service';
|
||||||
|
import { SnapshotService } from './services/snapshot.service';
|
||||||
|
import { SymbolService } from './services/symbol.service';
|
||||||
|
import { TemplateMocksService } from './services/template-mocks.service';
|
||||||
|
import { TemplateService } from './services/template.service';
|
||||||
|
import { ThemeService } from './services/theme.service';
|
||||||
|
import { ToasterService } from './services/toaster.service';
|
||||||
|
import { ToolsService } from './services/tools.service';
|
||||||
|
import { UpdatesService } from './services/updates.service';
|
||||||
|
import { VersionService } from './services/version.service';
|
||||||
|
import { VirtualBoxConfigurationService } from './services/virtual-box-configuration.service';
|
||||||
|
import { VirtualBoxService } from './services/virtual-box.service';
|
||||||
|
import { VmwareConfigurationService } from './services/vmware-configuration.service';
|
||||||
|
import { VmwareService } from './services/vmware.service';
|
||||||
|
import { VpcsConfigurationService } from './services/vpcs-configuration.service';
|
||||||
|
import { VpcsService } from './services/vpcs.service';
|
||||||
|
import { NonNegativeValidator } from './validators/non-negative-validator';
|
||||||
|
import { RotationValidator } from './validators/rotation-validator';
|
||||||
|
import { MarkedDirective } from './directives/marked.directive';
|
||||||
|
import { LoginComponent } from './components/login/login.component';
|
||||||
|
import { LoginService } from './services/login.service';
|
||||||
|
import { HttpRequestsInterceptor } from './interceptors/http.interceptor';
|
||||||
|
import { UserManagementComponent } from './components/user-management/user-management.component';
|
||||||
|
import { UserService } from './services/user.service';
|
||||||
|
import { LoggedUserComponent } from './components/users/logged-user/logged-user.component';
|
||||||
|
import { AddUserDialogComponent } from './components/user-management/add-user-dialog/add-user-dialog.component';
|
||||||
|
import { UserFilterPipe } from './filters/user-filter.pipe';
|
||||||
|
import { GroupManagementComponent } from './components/group-management/group-management.component';
|
||||||
|
import { GroupFilterPipe } from './filters/group-filter.pipe';
|
||||||
|
import { AddGroupDialogComponent } from './components/group-management/add-group-dialog/add-group-dialog.component';
|
||||||
|
import { DeleteGroupDialogComponent } from './components/group-management/delete-group-dialog/delete-group-dialog.component';
|
||||||
|
import { DeleteUserDialogComponent } from './components/user-management/delete-user-dialog/delete-user-dialog.component';
|
||||||
|
import { GroupDetailsComponent } from './components/group-details/group-details.component';
|
||||||
|
import { UserDetailComponent } from './components/user-management/user-detail/user-detail.component';
|
||||||
|
import { AddUserToGroupDialogComponent } from './components/group-details/add-user-to-group-dialog/add-user-to-group-dialog.component';
|
||||||
|
import { RemoveToGroupDialogComponent } from '@components/group-details/remove-to-group-dialog/remove-to-group-dialog.component';
|
||||||
|
import { PaginatorPipe } from './components/group-details/paginator.pipe';
|
||||||
|
import { MembersFilterPipe } from './components/group-details/members-filter.pipe';
|
||||||
|
import { ManagementComponent } from './components/management/management.component';
|
||||||
|
import {MatCheckboxModule} from "@angular/material/checkbox";
|
||||||
|
import { RoleManagementComponent } from './components/role-management/role-management.component';
|
||||||
|
import { RoleFilterPipe } from './components/role-management/role-filter.pipe';
|
||||||
|
import { AddRoleDialogComponent } from './components/role-management/add-role-dialog/add-role-dialog.component';
|
||||||
|
import { DeleteRoleDialogComponent } from './components/role-management/delete-role-dialog/delete-role-dialog.component';
|
||||||
|
import { RoleDetailComponent } from './components/role-management/role-detail/role-detail.component';
|
||||||
|
import { PermissionEditorComponent } from './components/role-management/role-detail/permission-editor/permission-editor.component';
|
||||||
|
import { EditablePermissionComponent } from './components/role-management/role-detail/permission-editor/editable-permission/editable-permission.component';
|
||||||
|
import { PermissionEditorValidateDialogComponent } from './components/role-management/role-detail/permission-editor/permission-editor-validate-dialog/permission-editor-validate-dialog.component';
|
||||||
|
import { PermissionsManagementComponent } from './components/permissions-management/permissions-management.component';
|
||||||
|
import { PermissionEditLineComponent } from '@components/permissions-management/permission-edit-line/permission-edit-line.component';
|
||||||
|
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
|
||||||
|
import { UserPermissionsComponent } from './components/user-management/user-detail/user-permissions/user-permissions.component';
|
||||||
|
import {MatAutocompleteModule} from "@angular/material/autocomplete";
|
||||||
|
import {PathAutoCompleteComponent} from './components/permissions-management/add-permission-line/path-auto-complete/path-auto-complete.component';
|
||||||
|
import {FilterCompletePipe} from './components/permissions-management/add-permission-line/path-auto-complete/filter-complete.pipe';
|
||||||
|
import { AddPermissionLineComponent } from './components/permissions-management/add-permission-line/add-permission-line.component';
|
||||||
|
import { MethodButtonComponent } from './components/permissions-management/method-button/method-button.component';
|
||||||
|
import { ActionButtonComponent } from './components/permissions-management/action-button/action-button.component';
|
||||||
|
import { DeletePermissionDialogComponent } from './components/permissions-management/delete-permission-dialog/delete-permission-dialog.component';
|
||||||
|
import { AddRoleToGroupComponent } from './components/group-details/add-role-to-group/add-role-to-group.component';
|
||||||
|
import {MatFormFieldModule} from "@angular/material/form-field";
|
||||||
|
import { PermissionsFilterPipe } from './components/permissions-management/permissions-filter.pipe';
|
||||||
|
import { DisplayPathPipe } from './components/permissions-management/display-path.pipe';
|
||||||
|
import {RolePermissionsComponent} from "@components/role-management/role-detail/role-permissions/role-permissions.component";
|
||||||
|
import { ChangeUserPasswordComponent } from './components/user-management/user-detail/change-user-password/change-user-password.component';
|
||||||
|
import {MatMenuModule} from "@angular/material/menu";
|
||||||
|
import { ImageManagerComponent } from './components/image-manager/image-manager.component';
|
||||||
|
import { AddImageDialogComponent } from './components/image-manager/add-image-dialog/add-image-dialog.component';
|
||||||
|
import { DeleteAllImageFilesDialogComponent } from './components/image-manager/deleteallfiles-dialog/deleteallfiles-dialog.component';
|
||||||
|
import { UploadingProcessbarComponent } from './common/uploading-processbar/uploading-processbar.component';
|
||||||
|
import { ExportPortableProjectComponent } from './components/export-portable-project/export-portable-project.component';
|
||||||
|
import { NodesMenuConfirmationDialogComponent } from './components/project-map/nodes-menu/nodes-menu-confirmation-dialog/nodes-menu-confirmation-dialog.component';
|
||||||
|
import { ConfirmationDeleteAllProjectsComponent } from './components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
LoggedUserComponent,
|
||||||
ProjectMapComponent,
|
ProjectMapComponent,
|
||||||
ServersComponent,
|
LoginComponent,
|
||||||
AddServerDialogComponent,
|
ControllersComponent,
|
||||||
|
AddControllerDialogComponent,
|
||||||
CreateSnapshotDialogComponent,
|
CreateSnapshotDialogComponent,
|
||||||
SnapshotMenuItemComponent,
|
SnapshotMenuItemComponent,
|
||||||
ProjectsComponent,
|
ProjectsComponent,
|
||||||
@ -293,13 +341,17 @@ if (environment.production) {
|
|||||||
DefaultLayoutComponent,
|
DefaultLayoutComponent,
|
||||||
ProgressDialogComponent,
|
ProgressDialogComponent,
|
||||||
ContextMenuComponent,
|
ContextMenuComponent,
|
||||||
|
ContextConsoleMenuComponent,
|
||||||
StartNodeActionComponent,
|
StartNodeActionComponent,
|
||||||
|
IsolateNodeActionComponent,
|
||||||
|
UnisolateNodeActionComponent,
|
||||||
StopNodeActionComponent,
|
StopNodeActionComponent,
|
||||||
TemplateComponent,
|
TemplateComponent,
|
||||||
TemplateListDialogComponent,
|
TemplateListDialogComponent,
|
||||||
MoveLayerDownActionComponent,
|
MoveLayerDownActionComponent,
|
||||||
MoveLayerUpActionComponent,
|
MoveLayerUpActionComponent,
|
||||||
EditStyleActionComponent,
|
EditStyleActionComponent,
|
||||||
|
EditLinkStyleActionComponent,
|
||||||
EditTextActionComponent,
|
EditTextActionComponent,
|
||||||
DeleteActionComponent,
|
DeleteActionComponent,
|
||||||
DuplicateActionComponent,
|
DuplicateActionComponent,
|
||||||
@ -308,12 +360,11 @@ if (environment.production) {
|
|||||||
StopCaptureActionComponent,
|
StopCaptureActionComponent,
|
||||||
ResumeLinkActionComponent,
|
ResumeLinkActionComponent,
|
||||||
SuspendLinkActionComponent,
|
SuspendLinkActionComponent,
|
||||||
ProjectMapShortcutsComponent,
|
|
||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
PreferencesComponent,
|
PreferencesComponent,
|
||||||
BundledServerFinderComponent,
|
BundledControllerFinderComponent,
|
||||||
ProgressComponent,
|
ProgressComponent,
|
||||||
ServerDiscoveryComponent,
|
ControllerDiscoveryComponent,
|
||||||
NodeSelectInterfaceComponent,
|
NodeSelectInterfaceComponent,
|
||||||
DrawLinkToolComponent,
|
DrawLinkToolComponent,
|
||||||
InstalledSoftwareComponent,
|
InstalledSoftwareComponent,
|
||||||
@ -328,6 +379,7 @@ if (environment.production) {
|
|||||||
InterfaceLabelDraggedComponent,
|
InterfaceLabelDraggedComponent,
|
||||||
InstallSoftwareComponent,
|
InstallSoftwareComponent,
|
||||||
StyleEditorDialogComponent,
|
StyleEditorDialogComponent,
|
||||||
|
LinkStyleEditorDialogComponent,
|
||||||
TextEditorDialogComponent,
|
TextEditorDialogComponent,
|
||||||
PacketFiltersDialogComponent,
|
PacketFiltersDialogComponent,
|
||||||
QemuPreferencesComponent,
|
QemuPreferencesComponent,
|
||||||
@ -381,8 +433,10 @@ if (environment.production) {
|
|||||||
SearchFilter,
|
SearchFilter,
|
||||||
DateFilter,
|
DateFilter,
|
||||||
NameFilter,
|
NameFilter,
|
||||||
|
DataSourceFilter,
|
||||||
TemplateFilter,
|
TemplateFilter,
|
||||||
ProjectsFilter,
|
ProjectsFilter,
|
||||||
|
AuthImageFilter,
|
||||||
ListOfSnapshotsComponent,
|
ListOfSnapshotsComponent,
|
||||||
CustomAdaptersComponent,
|
CustomAdaptersComponent,
|
||||||
NodesMenuComponent,
|
NodesMenuComponent,
|
||||||
@ -391,7 +445,6 @@ if (environment.production) {
|
|||||||
ShowNodeActionComponent,
|
ShowNodeActionComponent,
|
||||||
ConsoleComponent,
|
ConsoleComponent,
|
||||||
NodesMenuComponent,
|
NodesMenuComponent,
|
||||||
NotificationBoxComponent,
|
|
||||||
ProjectMapMenuComponent,
|
ProjectMapMenuComponent,
|
||||||
HelpComponent,
|
HelpComponent,
|
||||||
ConfigEditorDialogComponent,
|
ConfigEditorDialogComponent,
|
||||||
@ -426,11 +479,6 @@ if (environment.production) {
|
|||||||
ConfiguratorDialogIosComponent,
|
ConfiguratorDialogIosComponent,
|
||||||
ConfiguratorDialogDockerComponent,
|
ConfiguratorDialogDockerComponent,
|
||||||
ConfiguratorDialogNatComponent,
|
ConfiguratorDialogNatComponent,
|
||||||
ConfiguratorDialogTracengComponent,
|
|
||||||
AddTracengTemplateComponent,
|
|
||||||
TracengPreferencesComponent,
|
|
||||||
TracengTemplatesComponent,
|
|
||||||
TracengTemplateDetailsComponent,
|
|
||||||
QemuImageCreatorComponent,
|
QemuImageCreatorComponent,
|
||||||
ChooseNameDialogComponent,
|
ChooseNameDialogComponent,
|
||||||
StartCaptureOnStartedLinkActionComponent,
|
StartCaptureOnStartedLinkActionComponent,
|
||||||
@ -442,14 +490,77 @@ if (environment.production) {
|
|||||||
AlignVerticallyActionComponent,
|
AlignVerticallyActionComponent,
|
||||||
ConfirmationBottomSheetComponent,
|
ConfirmationBottomSheetComponent,
|
||||||
ConfigDialogComponent,
|
ConfigDialogComponent,
|
||||||
Gns3vmComponent,
|
|
||||||
ConfigureGns3VMDialogComponent,
|
|
||||||
ImportApplianceComponent,
|
ImportApplianceComponent,
|
||||||
DirectLinkComponent,
|
DirectLinkComponent,
|
||||||
SystemStatusComponent,
|
SystemStatusComponent,
|
||||||
StatusInfoComponent,
|
StatusInfoComponent,
|
||||||
StatusChartComponent,
|
StatusChartComponent,
|
||||||
OpenFileExplorerActionComponent
|
OpenFileExplorerActionComponent,
|
||||||
|
HttpConsoleActionComponent,
|
||||||
|
WebConsoleComponent,
|
||||||
|
ConsoleWrapperComponent,
|
||||||
|
HttpConsoleNewTabActionComponent,
|
||||||
|
WebConsoleFullWindowComponent,
|
||||||
|
NewTemplateDialogComponent,
|
||||||
|
ChangeHostnameActionComponent,
|
||||||
|
ChangeHostnameDialogComponent,
|
||||||
|
ApplianceInfoDialogComponent,
|
||||||
|
ReadmeEditorComponent,
|
||||||
|
MarkedDirective,
|
||||||
|
InformationDialogComponent,
|
||||||
|
TemplateNameDialogComponent,
|
||||||
|
ConfigureCustomAdaptersDialogComponent,
|
||||||
|
EditNetworkConfigurationDialogComponent,
|
||||||
|
UserManagementComponent,
|
||||||
|
ProjectReadmeComponent,
|
||||||
|
AddGroupDialogComponent,
|
||||||
|
GroupFilterPipe,
|
||||||
|
GroupManagementComponent,
|
||||||
|
AddUserDialogComponent,
|
||||||
|
UserFilterPipe,
|
||||||
|
DeleteGroupDialogComponent,
|
||||||
|
DeleteUserDialogComponent,
|
||||||
|
GroupDetailsComponent,
|
||||||
|
UserDetailComponent,
|
||||||
|
AddUserToGroupDialogComponent,
|
||||||
|
RemoveToGroupDialogComponent,
|
||||||
|
PaginatorPipe,
|
||||||
|
MembersFilterPipe,
|
||||||
|
ManagementComponent,
|
||||||
|
RoleManagementComponent,
|
||||||
|
RoleFilterPipe,
|
||||||
|
AddRoleDialogComponent,
|
||||||
|
DeleteRoleDialogComponent,
|
||||||
|
RoleDetailComponent,
|
||||||
|
PermissionEditorComponent,
|
||||||
|
EditablePermissionComponent,
|
||||||
|
PermissionEditorValidateDialogComponent,
|
||||||
|
RemoveToGroupDialogComponent,
|
||||||
|
PermissionsManagementComponent,
|
||||||
|
AddRoleToGroupComponent,
|
||||||
|
PermissionEditLineComponent,
|
||||||
|
AddPermissionLineComponent,
|
||||||
|
MethodButtonComponent,
|
||||||
|
ActionButtonComponent,
|
||||||
|
DeletePermissionDialogComponent,
|
||||||
|
PathAutoCompleteComponent,
|
||||||
|
FilterCompletePipe,
|
||||||
|
UserPermissionsComponent,
|
||||||
|
PermissionsFilterPipe,
|
||||||
|
RolePermissionsComponent,
|
||||||
|
DisplayPathPipe,
|
||||||
|
ChangeUserPasswordComponent,
|
||||||
|
FilterCompletePipe,
|
||||||
|
DisplayPathPipe,
|
||||||
|
ChangeUserPasswordComponent,
|
||||||
|
ProjectReadmeComponent,
|
||||||
|
ImageManagerComponent,
|
||||||
|
AddImageDialogComponent,
|
||||||
|
DeleteAllImageFilesDialogComponent,
|
||||||
|
UploadingProcessbarComponent,
|
||||||
|
ExportPortableProjectComponent,
|
||||||
|
NodesMenuConfirmationDialogComponent,
|
||||||
|
ConfirmationDeleteAllProjectsComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
@ -460,33 +571,36 @@ if (environment.production) {
|
|||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
CdkTableModule,
|
CdkTableModule,
|
||||||
CartographyModule,
|
CartographyModule,
|
||||||
HotkeyModule.forRoot(),
|
|
||||||
PersistenceModule,
|
|
||||||
NgxElectronModule,
|
NgxElectronModule,
|
||||||
FileUploadModule,
|
FileUploadModule,
|
||||||
MatSidenavModule,
|
MatSidenavModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatMenuModule,
|
||||||
ResizableModule,
|
ResizableModule,
|
||||||
DragAndDropModule,
|
DragAndDropModule,
|
||||||
DragDropModule,
|
DragDropModule,
|
||||||
NgxChildProcessModule,
|
NgxChildProcessModule,
|
||||||
MATERIAL_IMPORTS,
|
MATERIAL_IMPORTS,
|
||||||
DeviceDetectorModule.forRoot(),
|
NgCircleProgressModule.forRoot(),
|
||||||
NgCircleProgressModule.forRoot()
|
OverlayModule,
|
||||||
|
MatSlideToggleModule,
|
||||||
|
MatCheckboxModule,
|
||||||
|
MatAutocompleteModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
SettingsService,
|
SettingsService,
|
||||||
{ provide: ErrorHandler, useClass: ToasterErrorHandler },
|
{provide: ErrorHandler, useClass: ToasterErrorHandler},
|
||||||
|
{provide: HTTP_INTERCEPTORS, useClass: HttpRequestsInterceptor, multi: true},
|
||||||
D3Service,
|
D3Service,
|
||||||
VersionService,
|
VersionService,
|
||||||
ProjectService,
|
ProjectService,
|
||||||
SymbolService,
|
SymbolService,
|
||||||
ServerService,
|
ControllerService,
|
||||||
TemplateService,
|
TemplateService,
|
||||||
NodeService,
|
NodeService,
|
||||||
LinkService,
|
LinkService,
|
||||||
DrawingService,
|
DrawingService,
|
||||||
IndexedDbService,
|
HttpController,
|
||||||
HttpServer,
|
|
||||||
SnapshotService,
|
SnapshotService,
|
||||||
ProgressDialogService,
|
ProgressDialogService,
|
||||||
ToasterService,
|
ToasterService,
|
||||||
@ -499,11 +613,11 @@ if (environment.production) {
|
|||||||
SelectionManager,
|
SelectionManager,
|
||||||
InRectangleHelper,
|
InRectangleHelper,
|
||||||
DrawingsDataSource,
|
DrawingsDataSource,
|
||||||
ServerErrorHandler,
|
ControllerErrorHandler,
|
||||||
ServerDatabase,
|
ControllerDatabase,
|
||||||
ProjectNameValidator,
|
ProjectNameValidator,
|
||||||
ToolsService,
|
ToolsService,
|
||||||
ServerSettingsService,
|
ControllerSettingsService,
|
||||||
QemuService,
|
QemuService,
|
||||||
VpcsService,
|
VpcsService,
|
||||||
TemplateMocksService,
|
TemplateMocksService,
|
||||||
@ -525,7 +639,7 @@ if (environment.production) {
|
|||||||
IouService,
|
IouService,
|
||||||
IouConfigurationService,
|
IouConfigurationService,
|
||||||
RecentlyOpenedProjectService,
|
RecentlyOpenedProjectService,
|
||||||
ServerManagementService,
|
ControllerManagementService,
|
||||||
MapScaleService,
|
MapScaleService,
|
||||||
ConsoleService,
|
ConsoleService,
|
||||||
DefaultConsoleService,
|
DefaultConsoleService,
|
||||||
@ -535,18 +649,22 @@ if (environment.production) {
|
|||||||
MapSettingsService,
|
MapSettingsService,
|
||||||
InfoService,
|
InfoService,
|
||||||
ComputeService,
|
ComputeService,
|
||||||
TracengService,
|
|
||||||
PacketCaptureService,
|
PacketCaptureService,
|
||||||
NotificationService,
|
NotificationService,
|
||||||
Gns3vmService,
|
|
||||||
ThemeService,
|
ThemeService,
|
||||||
GoogleAnalyticsService,
|
GoogleAnalyticsService,
|
||||||
ServerResolve,
|
NodeConsoleService,
|
||||||
ProjectMapGuard,
|
ControllerResolve,
|
||||||
Title
|
LoginGuard,
|
||||||
|
ConsoleGuard,
|
||||||
|
Title,
|
||||||
|
ApplianceService,
|
||||||
|
UpdatesService,
|
||||||
|
LoginService,
|
||||||
|
UserService
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
AddServerDialogComponent,
|
AddControllerDialogComponent,
|
||||||
CreateSnapshotDialogComponent,
|
CreateSnapshotDialogComponent,
|
||||||
ProgressDialogComponent,
|
ProgressDialogComponent,
|
||||||
TemplateListDialogComponent,
|
TemplateListDialogComponent,
|
||||||
@ -565,7 +683,6 @@ if (environment.production) {
|
|||||||
InfoDialogComponent,
|
InfoDialogComponent,
|
||||||
ChangeSymbolDialogComponent,
|
ChangeSymbolDialogComponent,
|
||||||
EditProjectDialogComponent,
|
EditProjectDialogComponent,
|
||||||
ConfigureGns3VMDialogComponent,
|
|
||||||
ConfiguratorDialogVpcsComponent,
|
ConfiguratorDialogVpcsComponent,
|
||||||
ConfiguratorDialogEthernetHubComponent,
|
ConfiguratorDialogEthernetHubComponent,
|
||||||
ConfiguratorDialogEthernetSwitchComponent,
|
ConfiguratorDialogEthernetSwitchComponent,
|
||||||
@ -579,15 +696,22 @@ if (environment.production) {
|
|||||||
ConfiguratorDialogIosComponent,
|
ConfiguratorDialogIosComponent,
|
||||||
ConfiguratorDialogDockerComponent,
|
ConfiguratorDialogDockerComponent,
|
||||||
ConfiguratorDialogNatComponent,
|
ConfiguratorDialogNatComponent,
|
||||||
ConfiguratorDialogTracengComponent,
|
|
||||||
QemuImageCreatorComponent,
|
QemuImageCreatorComponent,
|
||||||
ChooseNameDialogComponent,
|
ChooseNameDialogComponent,
|
||||||
NavigationDialogComponent,
|
NavigationDialogComponent,
|
||||||
ScreenshotDialogComponent,
|
ScreenshotDialogComponent,
|
||||||
ConfirmationBottomSheetComponent,
|
ConfirmationBottomSheetComponent,
|
||||||
ConfigDialogComponent,
|
ConfigDialogComponent,
|
||||||
AdbutlerComponent
|
AdbutlerComponent,
|
||||||
|
NewTemplateDialogComponent,
|
||||||
|
ChangeHostnameDialogComponent,
|
||||||
|
ApplianceInfoDialogComponent,
|
||||||
|
ConfigureCustomAdaptersDialogComponent,
|
||||||
|
EditNetworkConfigurationDialogComponent,
|
||||||
|
ProjectReadmeComponent
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {
|
||||||
|
constructor(protected _googleAnalyticsService: GoogleAnalyticsService) {}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { NodeComponent } from './components/experimental-map/node/node.component';
|
import { DraggableComponent } from './components/experimental-map/draggable/draggable.component';
|
||||||
import { LinkComponent } from './components/experimental-map/link/link.component';
|
|
||||||
import { StatusComponent } from './components/experimental-map/status/status.component';
|
|
||||||
import { DrawingComponent } from './components/experimental-map/drawing/drawing.component';
|
import { DrawingComponent } from './components/experimental-map/drawing/drawing.component';
|
||||||
import { EllipseComponent } from './components/experimental-map/drawing/drawings/ellipse/ellipse.component';
|
import { EllipseComponent } from './components/experimental-map/drawing/drawings/ellipse/ellipse.component';
|
||||||
import { ImageComponent } from './components/experimental-map/drawing/drawings/image/image.component';
|
import { ImageComponent } from './components/experimental-map/drawing/drawings/image/image.component';
|
||||||
@ -8,8 +6,10 @@ import { LineComponent } from './components/experimental-map/drawing/drawings/li
|
|||||||
import { RectComponent } from './components/experimental-map/drawing/drawings/rect/rect.component';
|
import { RectComponent } from './components/experimental-map/drawing/drawings/rect/rect.component';
|
||||||
import { TextComponent } from './components/experimental-map/drawing/drawings/text/text.component';
|
import { TextComponent } from './components/experimental-map/drawing/drawings/text/text.component';
|
||||||
import { InterfaceLabelComponent } from './components/experimental-map/interface-label/interface-label.component';
|
import { InterfaceLabelComponent } from './components/experimental-map/interface-label/interface-label.component';
|
||||||
import { DraggableComponent } from './components/experimental-map/draggable/draggable.component';
|
import { LinkComponent } from './components/experimental-map/link/link.component';
|
||||||
|
import { NodeComponent } from './components/experimental-map/node/node.component';
|
||||||
import { SelectionComponent } from './components/experimental-map/selection/selection.component';
|
import { SelectionComponent } from './components/experimental-map/selection/selection.component';
|
||||||
|
import { StatusComponent } from './components/experimental-map/status/status.component';
|
||||||
|
|
||||||
export const ANGULAR_MAP_DECLARATIONS = [
|
export const ANGULAR_MAP_DECLARATIONS = [
|
||||||
NodeComponent,
|
NodeComponent,
|
||||||
@ -23,5 +23,5 @@ export const ANGULAR_MAP_DECLARATIONS = [
|
|||||||
TextComponent,
|
TextComponent,
|
||||||
DraggableComponent,
|
DraggableComponent,
|
||||||
SelectionComponent,
|
SelectionComponent,
|
||||||
InterfaceLabelComponent
|
InterfaceLabelComponent,
|
||||||
];
|
];
|
||||||
|
@ -1,26 +1,23 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { MatMenuModule, MatIconModule } from '@angular/material';
|
import { NgModule } from '@angular/core';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { CssFixer } from './helpers/css-fixer';
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
import { FontFixer } from './helpers/font-fixer';
|
|
||||||
import { DefaultDrawingsFactory } from './helpers/default-drawings-factory';
|
|
||||||
import { MultiLinkCalculatorHelper } from './helpers/multi-link-calculator-helper';
|
|
||||||
import { SvgToDrawingConverter } from './helpers/svg-to-drawing-converter';
|
|
||||||
import { QtDasharrayFixer } from './helpers/qt-dasharray-fixer';
|
|
||||||
import { LayersManager } from './managers/layers-manager';
|
|
||||||
import { MapChangeDetectorRef } from './services/map-change-detector-ref';
|
|
||||||
import { Context } from './models/context';
|
|
||||||
import { ANGULAR_MAP_DECLARATIONS } from './angular-map.imports';
|
import { ANGULAR_MAP_DECLARATIONS } from './angular-map.imports';
|
||||||
import { D3_MAP_IMPORTS } from './d3-map.imports';
|
import { D3MapComponent } from './components/d3-map/d3-map.component';
|
||||||
import { CanvasSizeDetector } from './helpers/canvas-size-detector';
|
import { DraggableSelectionComponent } from './components/draggable-selection/draggable-selection.component';
|
||||||
import { DrawingsEventSource } from './events/drawings-event-source';
|
import { LinkEditingComponent } from './components/link-editing/link-editing.component';
|
||||||
import { NodesEventSource } from './events/nodes-event-source';
|
import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component';
|
||||||
import { MapDrawingToSvgConverter } from './converters/map/map-drawing-to-svg-converter';
|
import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.component';
|
||||||
|
import { ExperimentalMapComponent } from './components/experimental-map/experimental-map.component';
|
||||||
|
import { SelectionControlComponent } from './components/selection-control/selection-control.component';
|
||||||
|
import { SelectionSelectComponent } from './components/selection-select/selection-select.component';
|
||||||
|
import { TextEditorComponent } from './components/text-editor/text-editor.component';
|
||||||
import { DrawingToMapDrawingConverter } from './converters/map/drawing-to-map-drawing-converter';
|
import { DrawingToMapDrawingConverter } from './converters/map/drawing-to-map-drawing-converter';
|
||||||
import { LabelToMapLabelConverter } from './converters/map/label-to-map-label-converter';
|
import { LabelToMapLabelConverter } from './converters/map/label-to-map-label-converter';
|
||||||
|
import { LinkNodeToMapLinkNodeConverter } from './converters/map/link-node-to-map-link-node-converter';
|
||||||
import { LinkToMapLinkConverter } from './converters/map/link-to-map-link-converter';
|
import { LinkToMapLinkConverter } from './converters/map/link-to-map-link-converter';
|
||||||
import { MapDrawingToDrawingConverter } from './converters/map/map-drawing-to-drawing-converter';
|
import { MapDrawingToDrawingConverter } from './converters/map/map-drawing-to-drawing-converter';
|
||||||
|
import { MapDrawingToSvgConverter } from './converters/map/map-drawing-to-svg-converter';
|
||||||
import { MapLabelToLabelConverter } from './converters/map/map-label-to-label-converter';
|
import { MapLabelToLabelConverter } from './converters/map/map-label-to-label-converter';
|
||||||
import { MapLinkNodeToLinkNodeConverter } from './converters/map/map-link-node-to-link-node-converter';
|
import { MapLinkNodeToLinkNodeConverter } from './converters/map/map-link-node-to-link-node-converter';
|
||||||
import { MapLinkToLinkConverter } from './converters/map/map-link-to-link-converter';
|
import { MapLinkToLinkConverter } from './converters/map/map-link-to-link-converter';
|
||||||
@ -30,34 +27,38 @@ import { MapSymbolToSymbolConverter } from './converters/map/map-symbol-to-symbo
|
|||||||
import { NodeToMapNodeConverter } from './converters/map/node-to-map-node-converter';
|
import { NodeToMapNodeConverter } from './converters/map/node-to-map-node-converter';
|
||||||
import { PortToMapPortConverter } from './converters/map/port-to-map-port-converter';
|
import { PortToMapPortConverter } from './converters/map/port-to-map-port-converter';
|
||||||
import { SymbolToMapSymbolConverter } from './converters/map/symbol-to-map-symbol-converter';
|
import { SymbolToMapSymbolConverter } from './converters/map/symbol-to-map-symbol-converter';
|
||||||
import { LinkNodeToMapLinkNodeConverter } from './converters/map/link-node-to-map-link-node-converter';
|
|
||||||
import { GraphDataManager } from './managers/graph-data-manager';
|
|
||||||
import {
|
|
||||||
MapNodesDataSource,
|
|
||||||
MapLinksDataSource,
|
|
||||||
MapDrawingsDataSource,
|
|
||||||
MapSymbolsDataSource
|
|
||||||
} from './datasources/map-datasource';
|
|
||||||
import { LinksEventSource } from './events/links-event-source';
|
|
||||||
import { D3MapComponent } from './components/d3-map/d3-map.component';
|
|
||||||
import { ExperimentalMapComponent } from './components/experimental-map/experimental-map.component';
|
|
||||||
import { SelectionEventSource } from './events/selection-event-source';
|
|
||||||
import { SelectionControlComponent } from './components/selection-control/selection-control.component';
|
|
||||||
import { SelectionSelectComponent } from './components/selection-select/selection-select.component';
|
|
||||||
import { DraggableSelectionComponent } from './components/draggable-selection/draggable-selection.component';
|
|
||||||
import { MapSettingsManager } from './managers/map-settings-manager';
|
|
||||||
import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.component';
|
|
||||||
import { FontBBoxCalculator } from './helpers/font-bbox-calculator';
|
|
||||||
import { StylesToFontConverter } from './converters/styles-to-font-converter';
|
import { StylesToFontConverter } from './converters/styles-to-font-converter';
|
||||||
import { TextElementFactory } from './helpers/drawings-factory/text-element-factory';
|
import { D3_MAP_IMPORTS } from './d3-map.imports';
|
||||||
import { EllipseElementFactory } from './helpers/drawings-factory/ellipse-element-factory';
|
import {
|
||||||
import { RectangleElementFactory } from './helpers/drawings-factory/rectangle-element-factory';
|
MapDrawingsDataSource,
|
||||||
import { LineElementFactory } from './helpers/drawings-factory/line-element-factory';
|
MapLinksDataSource,
|
||||||
import { TextEditorComponent } from './components/text-editor/text-editor.component';
|
MapNodesDataSource,
|
||||||
import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component';
|
MapSymbolsDataSource,
|
||||||
import { MovingEventSource } from './events/moving-event-source';
|
} from './datasources/map-datasource';
|
||||||
import { MovingCanvasDirective } from './directives/moving-canvas.directive';
|
import { MovingCanvasDirective } from './directives/moving-canvas.directive';
|
||||||
import { ZoomingCanvasDirective } from './directives/zooming-canvas.directive';
|
import { ZoomingCanvasDirective } from './directives/zooming-canvas.directive';
|
||||||
|
import { DrawingsEventSource } from './events/drawings-event-source';
|
||||||
|
import { LinksEventSource } from './events/links-event-source';
|
||||||
|
import { MovingEventSource } from './events/moving-event-source';
|
||||||
|
import { NodesEventSource } from './events/nodes-event-source';
|
||||||
|
import { SelectionEventSource } from './events/selection-event-source';
|
||||||
|
import { CanvasSizeDetector } from './helpers/canvas-size-detector';
|
||||||
|
import { CssFixer } from './helpers/css-fixer';
|
||||||
|
import { DefaultDrawingsFactory } from './helpers/default-drawings-factory';
|
||||||
|
import { EllipseElementFactory } from './helpers/drawings-factory/ellipse-element-factory';
|
||||||
|
import { LineElementFactory } from './helpers/drawings-factory/line-element-factory';
|
||||||
|
import { RectangleElementFactory } from './helpers/drawings-factory/rectangle-element-factory';
|
||||||
|
import { TextElementFactory } from './helpers/drawings-factory/text-element-factory';
|
||||||
|
import { FontBBoxCalculator } from './helpers/font-bbox-calculator';
|
||||||
|
import { FontFixer } from './helpers/font-fixer';
|
||||||
|
import { MultiLinkCalculatorHelper } from './helpers/multi-link-calculator-helper';
|
||||||
|
import { QtDasharrayFixer } from './helpers/qt-dasharray-fixer';
|
||||||
|
import { SvgToDrawingConverter } from './helpers/svg-to-drawing-converter';
|
||||||
|
import { GraphDataManager } from './managers/graph-data-manager';
|
||||||
|
import { LayersManager } from './managers/layers-manager';
|
||||||
|
import { MapSettingsManager } from './managers/map-settings-manager';
|
||||||
|
import { Context } from './models/context';
|
||||||
|
import { MapChangeDetectorRef } from './services/map-change-detector-ref';
|
||||||
import { EthernetLinkWidget } from './widgets/links/ethernet-link';
|
import { EthernetLinkWidget } from './widgets/links/ethernet-link';
|
||||||
import { SerialLinkWidget } from './widgets/links/serial-link';
|
import { SerialLinkWidget } from './widgets/links/serial-link';
|
||||||
|
|
||||||
@ -73,8 +74,9 @@ import { SerialLinkWidget } from './widgets/links/serial-link';
|
|||||||
SelectionControlComponent,
|
SelectionControlComponent,
|
||||||
SelectionSelectComponent,
|
SelectionSelectComponent,
|
||||||
DraggableSelectionComponent,
|
DraggableSelectionComponent,
|
||||||
|
LinkEditingComponent,
|
||||||
MovingCanvasDirective,
|
MovingCanvasDirective,
|
||||||
ZoomingCanvasDirective
|
ZoomingCanvasDirective,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
CssFixer,
|
CssFixer,
|
||||||
@ -121,8 +123,8 @@ import { SerialLinkWidget } from './widgets/links/serial-link';
|
|||||||
StylesToFontConverter,
|
StylesToFontConverter,
|
||||||
EthernetLinkWidget,
|
EthernetLinkWidget,
|
||||||
SerialLinkWidget,
|
SerialLinkWidget,
|
||||||
...D3_MAP_IMPORTS
|
...D3_MAP_IMPORTS,
|
||||||
],
|
],
|
||||||
exports: [D3MapComponent, ExperimentalMapComponent]
|
exports: [D3MapComponent, ExperimentalMapComponent],
|
||||||
})
|
})
|
||||||
export class CartographyModule {}
|
export class CartographyModule {}
|
||||||
|
@ -1,14 +1,38 @@
|
|||||||
<svg id="map" #svg class="map" preserveAspectRatio="none" movingCanvas zoomingCanvas>
|
<svg id="map" #svg class="map" preserveAspectRatio="none" movingCanvas zoomingCanvas>
|
||||||
<filter id="grayscale"><feColorMatrix id="feGrayscale" type="saturate" values="0" /></filter>
|
<filter id="grayscale"><feColorMatrix id="feGrayscale" type="saturate" values="0" /></filter>
|
||||||
<defs>
|
<defs>
|
||||||
<pattern id="gridDrawing" attr.width="{{project.drawing_grid_size}}" attr.height="{{project.drawing_grid_size}}" patternUnits="userSpaceOnUse">
|
<pattern
|
||||||
<path attr.d="M {{project.drawing_grid_size}} 0 L 0 0 0 {{project.drawing_grid_size}}" fill="none" stroke="silver" attr.stroke-width="{{gridVisibility}}"/>
|
attr.x="{{ drawingGridX }}"
|
||||||
|
attr.y="{{ drawingGridY }}"
|
||||||
|
id="gridDrawing"
|
||||||
|
attr.width="{{ project.drawing_grid_size }}"
|
||||||
|
attr.height="{{ project.drawing_grid_size }}"
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
attr.d="M {{ project.drawing_grid_size }} 0 L 0 0 0 {{ project.drawing_grid_size }}"
|
||||||
|
fill="none"
|
||||||
|
stroke="silver"
|
||||||
|
attr.stroke-width="{{ gridVisibility }}"
|
||||||
|
/>
|
||||||
</pattern>
|
</pattern>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<defs>
|
<defs>
|
||||||
<pattern id="gridNode" attr.width="{{project.grid_size}}" attr.height="{{project.grid_size}}" patternUnits="userSpaceOnUse">
|
<pattern
|
||||||
<path attr.d="M {{project.grid_size}} 0 L 0 0 0 {{project.grid_size}}" fill="none" stroke="DarkSlateGray" attr.stroke-width="{{gridVisibility}}"/>
|
attr.x="{{ nodeGridX }}"
|
||||||
|
attr.y="{{ nodeGridY }}"
|
||||||
|
id="gridNode"
|
||||||
|
attr.width="{{ project.grid_size }}"
|
||||||
|
attr.height="{{ project.grid_size }}"
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
attr.d="M {{ project.grid_size }} 0 L 0 0 0 {{ project.grid_size }}"
|
||||||
|
fill="none"
|
||||||
|
stroke="DarkSlateGray"
|
||||||
|
attr.stroke-width="{{ gridVisibility }}"
|
||||||
|
/>
|
||||||
</pattern>
|
</pattern>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
@ -20,5 +44,6 @@
|
|||||||
<app-drawing-resizing></app-drawing-resizing>
|
<app-drawing-resizing></app-drawing-resizing>
|
||||||
<app-selection-control></app-selection-control>
|
<app-selection-control></app-selection-control>
|
||||||
<app-selection-select></app-selection-select>
|
<app-selection-select></app-selection-select>
|
||||||
<app-text-editor #textEditor [server]="server" [svg]="svg"></app-text-editor>
|
<app-text-editor #textEditor [controller]="controller" [svg]="svg"></app-text-editor>
|
||||||
<app-draggable-selection [svg]="svg"></app-draggable-selection>
|
<app-draggable-selection [svg]="svg"></app-draggable-selection>
|
||||||
|
<app-link-editing [svg]="svg"></app-link-editing>
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.6 KiB |
@ -1,24 +1,17 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { D3MapComponent } from './d3-map.component';
|
import { D3MapComponent } from './d3-map.component';
|
||||||
|
|
||||||
describe('D3MapComponent', () => {
|
describe('D3MapComponent', () => {
|
||||||
let component: D3MapComponent;
|
let component: D3MapComponent;
|
||||||
let fixture: ComponentFixture<D3MapComponent>;
|
let fixture: ComponentFixture<D3MapComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [D3MapComponent]
|
declarations: [D3MapComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
// beforeEach(() => {
|
it('should create', () => {
|
||||||
// fixture = TestBed.createComponent(MapComponent);
|
expect(component)
|
||||||
// component = fixture.componentInstance;
|
});
|
||||||
// fixture.detectChanges();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should create', () => {
|
|
||||||
// expect(component).toBeTruthy();
|
|
||||||
// });
|
|
||||||
});
|
});
|
||||||
|
@ -7,38 +7,35 @@ import {
|
|||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
SimpleChange,
|
SimpleChange,
|
||||||
EventEmitter,
|
ViewChild,
|
||||||
Output,
|
|
||||||
ViewChild
|
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { Selection, select } from 'd3-selection';
|
import { select, Selection } from 'd3-selection';
|
||||||
|
|
||||||
import { GraphLayout } from '../../widgets/graph-layout';
|
|
||||||
import { Context } from '../../models/context';
|
|
||||||
import { Size } from '../../models/size';
|
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
|
||||||
import { SelectionTool } from '../../tools/selection-tool';
|
|
||||||
import { MovingTool } from '../../tools/moving-tool';
|
|
||||||
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
|
||||||
import { CanvasSizeDetector } from '../../helpers/canvas-size-detector';
|
|
||||||
import { Node } from '../../models/node';
|
|
||||||
import { Link } from '../../../models/link';
|
import { Link } from '../../../models/link';
|
||||||
import { Drawing } from '../../models/drawing';
|
import { Project } from '../../../models/project';
|
||||||
|
import { Controller } from '../../../models/controller';
|
||||||
import { Symbol } from '../../../models/symbol';
|
import { Symbol } from '../../../models/symbol';
|
||||||
|
import { MapScaleService } from '../../../services/mapScale.service';
|
||||||
|
import { MapSettingsService } from '../../../services/mapsettings.service';
|
||||||
|
import { ToolsService } from '../../../services/tools.service';
|
||||||
|
import { CanvasSizeDetector } from '../../helpers/canvas-size-detector';
|
||||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||||
import { MapSettingsManager } from '../../managers/map-settings-manager';
|
import { MapSettingsManager } from '../../managers/map-settings-manager';
|
||||||
import { Server } from '../../../models/server';
|
import { Context } from '../../models/context';
|
||||||
import { ToolsService } from '../../../services/tools.service';
|
import { Drawing } from '../../models/drawing';
|
||||||
|
import { Node } from '../../models/node';
|
||||||
|
import { Size } from '../../models/size';
|
||||||
|
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
||||||
|
import { MovingTool } from '../../tools/moving-tool';
|
||||||
|
import { SelectionTool } from '../../tools/selection-tool';
|
||||||
|
import { GraphLayout } from '../../widgets/graph-layout';
|
||||||
|
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
||||||
import { TextEditorComponent } from '../text-editor/text-editor.component';
|
import { TextEditorComponent } from '../text-editor/text-editor.component';
|
||||||
import { MapScaleService } from '../../../services/mapScale.service';
|
|
||||||
import { Project } from '../../../models/project';
|
|
||||||
import { MapSettingsService } from '../../../services/mapsettings.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-d3-map',
|
selector: 'app-d3-map',
|
||||||
templateUrl: './d3-map.component.html',
|
templateUrl: './d3-map.component.html',
|
||||||
styleUrls: ['./d3-map.component.scss']
|
styleUrls: ['./d3-map.component.scss'],
|
||||||
})
|
})
|
||||||
export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
@Input() nodes: Node[] = [];
|
@Input() nodes: Node[] = [];
|
||||||
@ -46,13 +43,13 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
@Input() drawings: Drawing[] = [];
|
@Input() drawings: Drawing[] = [];
|
||||||
@Input() symbols: Symbol[] = [];
|
@Input() symbols: Symbol[] = [];
|
||||||
@Input() project: Project;
|
@Input() project: Project;
|
||||||
@Input() server: Server;
|
@Input() controller: Controller;
|
||||||
|
|
||||||
@Input() width = 1500;
|
@Input() width = 1500;
|
||||||
@Input() height = 600;
|
@Input() height = 600;
|
||||||
|
|
||||||
@ViewChild('svg', {static: false}) svgRef: ElementRef;
|
@ViewChild('svg') svgRef: ElementRef;
|
||||||
@ViewChild('textEditor', {static: false}) textEditor: TextEditorComponent;
|
@ViewChild('textEditor') textEditor: TextEditorComponent;
|
||||||
|
|
||||||
private parentNativeElement: any;
|
private parentNativeElement: any;
|
||||||
private svg: Selection<SVGSVGElement, any, null, undefined>;
|
private svg: Selection<SVGSVGElement, any, null, undefined>;
|
||||||
@ -60,10 +57,15 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
private subscriptions: Subscription[] = [];
|
private subscriptions: Subscription[] = [];
|
||||||
private drawLinkTool: boolean;
|
private drawLinkTool: boolean;
|
||||||
protected settings = {
|
protected settings = {
|
||||||
show_interface_labels: true
|
show_interface_labels: true,
|
||||||
};
|
};
|
||||||
public gridVisibility: number = 0;
|
public gridVisibility: number = 0;
|
||||||
|
|
||||||
|
public nodeGridX: number = 0;
|
||||||
|
public nodeGridY: number = 0;
|
||||||
|
public drawingGridX: number = 0;
|
||||||
|
public drawingGridY: number = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private graphDataManager: GraphDataManager,
|
private graphDataManager: GraphDataManager,
|
||||||
public context: Context,
|
public context: Context,
|
||||||
@ -84,8 +86,14 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
|
|
||||||
@Input('show-interface-labels')
|
@Input('show-interface-labels')
|
||||||
set showInterfaceLabels(value) {
|
set showInterfaceLabels(value) {
|
||||||
this.settings.show_interface_labels = value;
|
if (value && !this.mapSettingsService.integrateLinkLabelsToLinks) {
|
||||||
this.interfaceLabelWidget.setEnabled(value);
|
this.settings.show_interface_labels = true;
|
||||||
|
this.interfaceLabelWidget.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
this.settings.show_interface_labels = false;
|
||||||
|
this.interfaceLabelWidget.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
this.mapChangeDetectorRef.detectChanges();
|
this.mapChangeDetectorRef.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +101,20 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
this.mapSettings.isReadOnly = value;
|
this.mapSettings.isReadOnly = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resize(val: boolean) {
|
||||||
|
if (val) {
|
||||||
|
this.svg.attr('height', window.innerHeight + window.scrollY - 16);
|
||||||
|
} else {
|
||||||
|
let heightOfProjectWindow = window.innerHeight - 16;
|
||||||
|
|
||||||
|
if (this.height > heightOfProjectWindow) {
|
||||||
|
this.svg.attr('height', this.height);
|
||||||
|
} else {
|
||||||
|
this.svg.attr('height', heightOfProjectWindow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
|
ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
|
||||||
if (
|
if (
|
||||||
(changes['width'] && !changes['width'].isFirstChange()) ||
|
(changes['width'] && !changes['width'].isFirstChange()) ||
|
||||||
@ -123,9 +145,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.subscriptions.push(
|
this.subscriptions.push(this.mapScaleService.scaleChangeEmitter.subscribe((value: number) => this.redraw()));
|
||||||
this.mapScaleService.scaleChangeEmitter.subscribe((value: number) => this.redraw())
|
|
||||||
);
|
|
||||||
|
|
||||||
this.subscriptions.push(
|
this.subscriptions.push(
|
||||||
this.toolsService.isMovingToolActivated.subscribe((value: boolean) => {
|
this.toolsService.isMovingToolActivated.subscribe((value: boolean) => {
|
||||||
@ -147,6 +167,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.gridVisibility = localStorage.getItem('gridVisibility') === 'true' ? 1 : 0;
|
this.gridVisibility = localStorage.getItem('gridVisibility') === 'true' ? 1 : 0;
|
||||||
|
this.mapSettingsService.isScrollDisabled.subscribe((val) => this.resize(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
@ -164,10 +185,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
public createGraph(domElement: HTMLElement) {
|
public createGraph(domElement: HTMLElement) {
|
||||||
const rootElement = select(domElement);
|
const rootElement = select(domElement);
|
||||||
this.svg = rootElement.select<SVGSVGElement>('svg');
|
this.svg = rootElement.select<SVGSVGElement>('svg');
|
||||||
this.graphLayout.connect(
|
this.graphLayout.connect(this.svg, this.context);
|
||||||
this.svg,
|
|
||||||
this.context
|
|
||||||
);
|
|
||||||
this.graphLayout.draw(this.svg, this.context);
|
this.graphLayout.draw(this.svg, this.context);
|
||||||
this.mapChangeDetectorRef.hasBeenDrawn = true;
|
this.mapChangeDetectorRef.hasBeenDrawn = true;
|
||||||
}
|
}
|
||||||
@ -189,6 +207,8 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private redraw() {
|
private redraw() {
|
||||||
|
this.updateGrid();
|
||||||
|
|
||||||
this.graphDataManager.setNodes(this.nodes);
|
this.graphDataManager.setNodes(this.nodes);
|
||||||
this.graphDataManager.setLinks(this.links);
|
this.graphDataManager.setLinks(this.links);
|
||||||
this.graphDataManager.setDrawings(this.drawings);
|
this.graphDataManager.setDrawings(this.drawings);
|
||||||
@ -198,6 +218,26 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
this.mapSettingsService.mapRenderedEmitter.emit(true);
|
this.mapSettingsService.mapRenderedEmitter.emit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateGrid() {
|
||||||
|
if (this.project.grid_size && this.project.grid_size > 0)
|
||||||
|
this.nodeGridX =
|
||||||
|
this.project.scene_width / 2 -
|
||||||
|
Math.floor(this.project.scene_width / 2 / this.project.grid_size) * this.project.grid_size;
|
||||||
|
if (this.project.grid_size && this.project.grid_size > 0)
|
||||||
|
this.nodeGridY =
|
||||||
|
this.project.scene_height / 2 -
|
||||||
|
Math.floor(this.project.scene_height / 2 / this.project.grid_size) * this.project.grid_size;
|
||||||
|
|
||||||
|
if (this.project.drawing_grid_size && this.project.drawing_grid_size > 0)
|
||||||
|
this.drawingGridX =
|
||||||
|
this.project.scene_width / 2 -
|
||||||
|
Math.floor(this.project.scene_width / 2 / this.project.drawing_grid_size) * this.project.drawing_grid_size;
|
||||||
|
if (this.project.drawing_grid_size && this.project.drawing_grid_size > 0)
|
||||||
|
this.drawingGridY =
|
||||||
|
this.project.scene_height / 2 -
|
||||||
|
Math.floor(this.project.scene_height / 2 / this.project.drawing_grid_size) * this.project.drawing_grid_size;
|
||||||
|
}
|
||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
@HostListener('window:resize', ['$event'])
|
||||||
onResize(event) {
|
onResize(event) {
|
||||||
this.changeLayout();
|
this.changeLayout();
|
||||||
|
@ -1,27 +1,26 @@
|
|||||||
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
|
import { EventEmitter } from '@angular/core';
|
||||||
|
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||||
import { DraggableSelectionComponent } from './draggable-selection.component';
|
import { select } from 'd3-selection';
|
||||||
import { NodesWidget } from '../../widgets/nodes';
|
import { MapSettingsService } from '../../../services/mapsettings.service';
|
||||||
import { DrawingsWidget } from '../../widgets/drawings';
|
import { DraggableDrag, DraggableEnd, DraggableStart } from '../../events/draggable';
|
||||||
import { LinksWidget } from '../../widgets/links';
|
|
||||||
import { LabelWidget } from '../../widgets/label';
|
|
||||||
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
|
||||||
import { SelectionManager } from '../../managers/selection-manager';
|
|
||||||
import { SelectionManagerMock } from '../../managers/selection-manager.spec';
|
|
||||||
import { NodesEventSource } from '../../events/nodes-event-source';
|
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
|
import { LinksEventSource } from '../../events/links-event-source';
|
||||||
|
import { NodesEventSource } from '../../events/nodes-event-source';
|
||||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||||
import { MockedGraphDataManager } from '../../managers/graph-data-manager.spec';
|
import { MockedGraphDataManager } from '../../managers/graph-data-manager.spec';
|
||||||
import { LinksEventSource } from '../../events/links-event-source';
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
import { DraggableStart, DraggableDrag, DraggableEnd } from '../../events/draggable';
|
import { SelectionManagerMock } from '../../managers/selection-manager.spec';
|
||||||
import { MapNode } from '../../models/map/map-node';
|
|
||||||
import { EventEmitter } from '@angular/core';
|
|
||||||
import { MapDrawing } from '../../models/map/map-drawing';
|
import { MapDrawing } from '../../models/map/map-drawing';
|
||||||
import { MapLabel } from '../../models/map/map-label';
|
import { MapLabel } from '../../models/map/map-label';
|
||||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
|
||||||
import { select } from 'd3-selection';
|
|
||||||
import { MapLink } from '../../models/map/map-link';
|
import { MapLink } from '../../models/map/map-link';
|
||||||
import { MapSettingsService } from '../../../services/mapsettings.service';
|
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||||
|
import { MapNode } from '../../models/map/map-node';
|
||||||
|
import { DrawingsWidget } from '../../widgets/drawings';
|
||||||
|
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
||||||
|
import { LabelWidget } from '../../widgets/label';
|
||||||
|
import { LinksWidget } from '../../widgets/links';
|
||||||
|
import { NodesWidget } from '../../widgets/nodes';
|
||||||
|
import { DraggableSelectionComponent } from './draggable-selection.component';
|
||||||
|
|
||||||
describe('DraggableSelectionComponent', () => {
|
describe('DraggableSelectionComponent', () => {
|
||||||
let component: DraggableSelectionComponent;
|
let component: DraggableSelectionComponent;
|
||||||
@ -43,7 +42,7 @@ describe('DraggableSelectionComponent', () => {
|
|||||||
let interfaceLabelDragEventEmitter: EventEmitter<DraggableDrag<MapLinkNode>>;
|
let interfaceLabelDragEventEmitter: EventEmitter<DraggableDrag<MapLinkNode>>;
|
||||||
let interfaceLabelEndEventEmitter: EventEmitter<DraggableEnd<MapLinkNode>>;
|
let interfaceLabelEndEventEmitter: EventEmitter<DraggableEnd<MapLinkNode>>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async () => {
|
||||||
mockedGraphDataManager = new MockedGraphDataManager();
|
mockedGraphDataManager = new MockedGraphDataManager();
|
||||||
|
|
||||||
nodesStartEventEmitter = new EventEmitter<DraggableStart<MapNode>>();
|
nodesStartEventEmitter = new EventEmitter<DraggableStart<MapNode>>();
|
||||||
@ -67,8 +66,8 @@ describe('DraggableSelectionComponent', () => {
|
|||||||
draggable: {
|
draggable: {
|
||||||
start: nodesStartEventEmitter,
|
start: nodesStartEventEmitter,
|
||||||
drag: nodesDragEventEmitter,
|
drag: nodesDragEventEmitter,
|
||||||
end: nodesEndEventEmitter
|
end: nodesEndEventEmitter,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawingsWidgetStub = {
|
const drawingsWidgetStub = {
|
||||||
@ -76,11 +75,11 @@ describe('DraggableSelectionComponent', () => {
|
|||||||
draggable: {
|
draggable: {
|
||||||
start: drawingsStartEventEmitter,
|
start: drawingsStartEventEmitter,
|
||||||
drag: drawingsDragEventEmitter,
|
drag: drawingsDragEventEmitter,
|
||||||
end: drawingsEndEventEmitter
|
end: drawingsEndEventEmitter,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
const linksWidgetStub = {
|
const linksWidgetStub = {
|
||||||
redrawLink: () => {}
|
redrawLink: () => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const labelWidgetStub = {
|
const labelWidgetStub = {
|
||||||
@ -88,30 +87,30 @@ describe('DraggableSelectionComponent', () => {
|
|||||||
draggable: {
|
draggable: {
|
||||||
start: labelStartEventEmitter,
|
start: labelStartEventEmitter,
|
||||||
drag: labelDragEventEmitter,
|
drag: labelDragEventEmitter,
|
||||||
end: labelEndEventEmitter
|
end: labelEndEventEmitter,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const interfaceLabelWidgetStub = {
|
const interfaceLabelWidgetStub = {
|
||||||
draggable: {
|
draggable: {
|
||||||
start: interfaceLabelStartEventEmitter,
|
start: interfaceLabelStartEventEmitter,
|
||||||
drag: interfaceLabelDragEventEmitter,
|
drag: interfaceLabelDragEventEmitter,
|
||||||
end: interfaceLabelEndEventEmitter
|
end: interfaceLabelEndEventEmitter,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const nodesEventSourceStub = {
|
const nodesEventSourceStub = {
|
||||||
dragged: { emit: () => {} },
|
dragged: { emit: () => {} },
|
||||||
labelDragged: { emit: () => {} }
|
labelDragged: { emit: () => {} },
|
||||||
};
|
};
|
||||||
const drawingsEventSourceStub = {
|
const drawingsEventSourceStub = {
|
||||||
dragged: { emit: () => {} }
|
dragged: { emit: () => {} },
|
||||||
};
|
};
|
||||||
const linksEventSourceStub = {
|
const linksEventSourceStub = {
|
||||||
interfaceDragged: { emit: () => {} }
|
interfaceDragged: { emit: () => {} },
|
||||||
};
|
};
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: NodesWidget, useValue: nodesWidgetStub },
|
{ provide: NodesWidget, useValue: nodesWidgetStub },
|
||||||
{ provide: DrawingsWidget, useValue: drawingsWidgetStub },
|
{ provide: DrawingsWidget, useValue: drawingsWidgetStub },
|
||||||
@ -123,11 +122,11 @@ describe('DraggableSelectionComponent', () => {
|
|||||||
{ provide: DrawingsEventSource, useValue: drawingsEventSourceStub },
|
{ provide: DrawingsEventSource, useValue: drawingsEventSourceStub },
|
||||||
{ provide: GraphDataManager, useValue: mockedGraphDataManager },
|
{ provide: GraphDataManager, useValue: mockedGraphDataManager },
|
||||||
{ provide: LinksEventSource, useValue: linksEventSourceStub },
|
{ provide: LinksEventSource, useValue: linksEventSourceStub },
|
||||||
{ provide: MapSettingsService, useClass: MapSettingsService }
|
{ provide: MapSettingsService, useClass: MapSettingsService },
|
||||||
],
|
],
|
||||||
declarations: [DraggableSelectionComponent]
|
declarations: [DraggableSelectionComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DraggableSelectionComponent);
|
fixture = TestBed.createComponent(DraggableSelectionComponent);
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
|
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Subscription, merge } from 'rxjs';
|
|
||||||
import { NodesWidget } from '../../widgets/nodes';
|
|
||||||
import { DrawingsWidget } from '../../widgets/drawings';
|
|
||||||
import { LinksWidget } from '../../widgets/links';
|
|
||||||
import { SelectionManager } from '../../managers/selection-manager';
|
|
||||||
import { NodesEventSource } from '../../events/nodes-event-source';
|
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
|
||||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
|
||||||
import { DraggableStart, DraggableDrag, DraggableEnd } from '../../events/draggable';
|
|
||||||
import { MapNode } from '../../models/map/map-node';
|
|
||||||
import { MapDrawing } from '../../models/map/map-drawing';
|
|
||||||
import { DraggedDataEvent } from '../../events/event-source';
|
|
||||||
import { select } from 'd3-selection';
|
import { select } from 'd3-selection';
|
||||||
import { MapLabel } from '../../models/map/map-label';
|
import { merge, Subscription } from 'rxjs';
|
||||||
import { LabelWidget } from '../../widgets/label';
|
|
||||||
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
|
||||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
|
||||||
import { LinksEventSource } from '../../events/links-event-source';
|
|
||||||
import { MapSettingsService } from '../../../services/mapsettings.service';
|
import { MapSettingsService } from '../../../services/mapsettings.service';
|
||||||
|
import { DraggableDrag, DraggableEnd, DraggableStart } from '../../events/draggable';
|
||||||
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
|
import { DraggedDataEvent } from '../../events/event-source';
|
||||||
|
import { LinksEventSource } from '../../events/links-event-source';
|
||||||
|
import { NodesEventSource } from '../../events/nodes-event-source';
|
||||||
|
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||||
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
|
import { MapDrawing } from '../../models/map/map-drawing';
|
||||||
|
import { MapLabel } from '../../models/map/map-label';
|
||||||
|
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||||
|
import { MapNode } from '../../models/map/map-node';
|
||||||
|
import { DrawingsWidget } from '../../widgets/drawings';
|
||||||
|
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
||||||
|
import { LabelWidget } from '../../widgets/label';
|
||||||
|
import { LinksWidget } from '../../widgets/links';
|
||||||
|
import { NodesWidget } from '../../widgets/nodes';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-draggable-selection',
|
selector: 'app-draggable-selection',
|
||||||
templateUrl: './draggable-selection.component.html',
|
templateUrl: './draggable-selection.component.html',
|
||||||
styleUrls: ['./draggable-selection.component.scss']
|
styleUrls: ['./draggable-selection.component.scss'],
|
||||||
})
|
})
|
||||||
export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||||
private start: Subscription;
|
private start: Subscription;
|
||||||
@ -62,25 +62,25 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
|||||||
).subscribe((evt: DraggableStart<any>) => {
|
).subscribe((evt: DraggableStart<any>) => {
|
||||||
const selected = this.selectionManager.getSelected();
|
const selected = this.selectionManager.getSelected();
|
||||||
if (evt.datum instanceof MapNode) {
|
if (evt.datum instanceof MapNode) {
|
||||||
if (selected.filter(item => item instanceof MapNode && item.id === evt.datum.id).length === 0) {
|
if (selected.filter((item) => item instanceof MapNode && item.id === evt.datum.id).length === 0) {
|
||||||
this.selectionManager.setSelected([evt.datum]);
|
this.selectionManager.setSelected([evt.datum]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt.datum instanceof MapDrawing) {
|
if (evt.datum instanceof MapDrawing) {
|
||||||
if (selected.filter(item => item instanceof MapDrawing && item.id === evt.datum.id).length === 0) {
|
if (selected.filter((item) => item instanceof MapDrawing && item.id === evt.datum.id).length === 0) {
|
||||||
this.selectionManager.setSelected([evt.datum]);
|
this.selectionManager.setSelected([evt.datum]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt.datum instanceof MapLabel) {
|
if (evt.datum instanceof MapLabel) {
|
||||||
if (selected.filter(item => item instanceof MapLabel && item.id === evt.datum.id).length === 0) {
|
if (selected.filter((item) => item instanceof MapLabel && item.id === evt.datum.id).length === 0) {
|
||||||
this.selectionManager.setSelected([evt.datum]);
|
this.selectionManager.setSelected([evt.datum]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt.datum instanceof MapLinkNode) {
|
if (evt.datum instanceof MapLinkNode) {
|
||||||
if (selected.filter(item => item instanceof MapLinkNode && item.id === evt.datum.id).length === 0) {
|
if (selected.filter((item) => item instanceof MapLinkNode && item.id === evt.datum.id).length === 0) {
|
||||||
this.selectionManager.setSelected([evt.datum]);
|
this.selectionManager.setSelected([evt.datum]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
|||||||
if (!this.isMapLocked) {
|
if (!this.isMapLocked) {
|
||||||
const selected = this.selectionManager.getSelected();
|
const selected = this.selectionManager.getSelected();
|
||||||
// update nodes
|
// update nodes
|
||||||
let mapNodes = selected.filter(item => item instanceof MapNode);
|
let mapNodes = selected.filter((item) => item instanceof MapNode);
|
||||||
const lockedNodes = mapNodes.filter((item: MapNode) => item.locked);
|
const lockedNodes = mapNodes.filter((item: MapNode) => item.locked);
|
||||||
const selectedNodes = mapNodes.filter((item: MapNode) => !item.locked);
|
const selectedNodes = mapNodes.filter((item: MapNode) => !item.locked);
|
||||||
selectedNodes.forEach((node: MapNode) => {
|
selectedNodes.forEach((node: MapNode) => {
|
||||||
@ -107,18 +107,18 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
|||||||
const links = this.graphDataManager
|
const links = this.graphDataManager
|
||||||
.getLinks()
|
.getLinks()
|
||||||
.filter(
|
.filter(
|
||||||
link =>
|
(link) =>
|
||||||
(link.target !== undefined && link.target.id === node.id) ||
|
(link.target !== undefined && link.target.id === node.id) ||
|
||||||
(link.source !== undefined && link.source.id === node.id)
|
(link.source !== undefined && link.source.id === node.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
links.forEach(link => {
|
links.forEach((link) => {
|
||||||
this.linksWidget.redrawLink(svg, link);
|
this.linksWidget.redrawLink(svg, link);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// update drawings
|
// update drawings
|
||||||
let mapDrawings = selected.filter(item => item instanceof MapDrawing);
|
let mapDrawings = selected.filter((item) => item instanceof MapDrawing);
|
||||||
const selectedDrawings = mapDrawings.filter((item: MapDrawing) => !item.locked);
|
const selectedDrawings = mapDrawings.filter((item: MapDrawing) => !item.locked);
|
||||||
selectedDrawings.forEach((drawing: MapDrawing) => {
|
selectedDrawings.forEach((drawing: MapDrawing) => {
|
||||||
drawing.x += evt.dx;
|
drawing.x += evt.dx;
|
||||||
@ -127,32 +127,36 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// update labels
|
// update labels
|
||||||
let mapLabels = selected.filter(item => item instanceof MapLabel);
|
let mapLabels = selected.filter((item) => item instanceof MapLabel);
|
||||||
const selectedLabels = mapLabels.filter((item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0);
|
const selectedLabels = mapLabels.filter(
|
||||||
|
(item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0
|
||||||
|
);
|
||||||
selectedLabels.forEach((label: MapLabel) => {
|
selectedLabels.forEach((label: MapLabel) => {
|
||||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0;
|
const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0;
|
||||||
if (isParentNodeSelected) {
|
if (isParentNodeSelected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const node = this.graphDataManager.getNodes().filter(node => node.id === label.nodeId)[0];
|
const node = this.graphDataManager.getNodes().filter((node) => node.id === label.nodeId)[0];
|
||||||
node.label.x += evt.dx;
|
node.label.x += evt.dx;
|
||||||
node.label.y += evt.dy;
|
node.label.y += evt.dy;
|
||||||
this.labelWidget.redrawLabel(svg, label);
|
this.labelWidget.redrawLabel(svg, label);
|
||||||
});
|
});
|
||||||
|
|
||||||
// update interface labels
|
// update interface labels
|
||||||
let mapLinkNodes = selected.filter(item => item instanceof MapLinkNode);
|
let mapLinkNodes = selected.filter((item) => item instanceof MapLinkNode);
|
||||||
const selectedLinkNodes = mapLinkNodes.filter((item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0);
|
const selectedLinkNodes = mapLinkNodes.filter(
|
||||||
|
(item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0
|
||||||
|
);
|
||||||
selectedLinkNodes.forEach((interfaceLabel: MapLinkNode) => {
|
selectedLinkNodes.forEach((interfaceLabel: MapLinkNode) => {
|
||||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === interfaceLabel.nodeId).length > 0;
|
const isParentNodeSelected = selectedNodes.filter((node) => node.id === interfaceLabel.nodeId).length > 0;
|
||||||
if (isParentNodeSelected) {
|
if (isParentNodeSelected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const link = this.graphDataManager
|
const link = this.graphDataManager
|
||||||
.getLinks()
|
.getLinks()
|
||||||
.filter(link => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0];
|
.filter((link) => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0];
|
||||||
if (link.nodes[0].id === interfaceLabel.id) {
|
if (link.nodes[0].id === interfaceLabel.id) {
|
||||||
link.nodes[0].label.x += evt.dx;
|
link.nodes[0].label.x += evt.dx;
|
||||||
link.nodes[0].label.y += evt.dy;
|
link.nodes[0].label.y += evt.dy;
|
||||||
@ -176,23 +180,25 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
|||||||
if (!this.isMapLocked) {
|
if (!this.isMapLocked) {
|
||||||
const selected = this.selectionManager.getSelected();
|
const selected = this.selectionManager.getSelected();
|
||||||
|
|
||||||
let mapNodes = selected.filter(item => item instanceof MapNode);
|
let mapNodes = selected.filter((item) => item instanceof MapNode);
|
||||||
const lockedNodes = mapNodes.filter((item: MapNode) => item.locked);
|
const lockedNodes = mapNodes.filter((item: MapNode) => item.locked);
|
||||||
const selectedNodes = mapNodes.filter((item: MapNode) => !item.locked);
|
const selectedNodes = mapNodes.filter((item: MapNode) => !item.locked);
|
||||||
selectedNodes.forEach((item: MapNode) => {
|
selectedNodes.forEach((item: MapNode) => {
|
||||||
this.nodesEventSource.dragged.emit(new DraggedDataEvent<MapNode>(item, evt.dx, evt.dy));
|
this.nodesEventSource.dragged.emit(new DraggedDataEvent<MapNode>(item, evt.dx, evt.dy));
|
||||||
});
|
});
|
||||||
|
|
||||||
let mapDrawings = selected.filter(item => item instanceof MapDrawing);
|
let mapDrawings = selected.filter((item) => item instanceof MapDrawing);
|
||||||
const selectedDrawings = mapDrawings.filter((item: MapDrawing) => !item.locked);
|
const selectedDrawings = mapDrawings.filter((item: MapDrawing) => !item.locked);
|
||||||
selectedDrawings.forEach((item: MapDrawing) => {
|
selectedDrawings.forEach((item: MapDrawing) => {
|
||||||
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(item, evt.dx, evt.dy));
|
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(item, evt.dx, evt.dy));
|
||||||
});
|
});
|
||||||
|
|
||||||
let mapLabels = selected.filter(item => item instanceof MapLabel);
|
let mapLabels = selected.filter((item) => item instanceof MapLabel);
|
||||||
const selectedLabels = mapLabels.filter((item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0);
|
const selectedLabels = mapLabels.filter(
|
||||||
|
(item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0
|
||||||
|
);
|
||||||
selectedLabels.forEach((label: MapLabel) => {
|
selectedLabels.forEach((label: MapLabel) => {
|
||||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0;
|
const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0;
|
||||||
if (isParentNodeSelected) {
|
if (isParentNodeSelected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -200,10 +206,12 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
|||||||
this.nodesEventSource.labelDragged.emit(new DraggedDataEvent<MapLabel>(label, evt.dx, evt.dy));
|
this.nodesEventSource.labelDragged.emit(new DraggedDataEvent<MapLabel>(label, evt.dx, evt.dy));
|
||||||
});
|
});
|
||||||
|
|
||||||
let mapLinkNodes = selected.filter(item => item instanceof MapLinkNode);
|
let mapLinkNodes = selected.filter((item) => item instanceof MapLinkNode);
|
||||||
const selectedLinkNodes = mapLinkNodes.filter((item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0)
|
const selectedLinkNodes = mapLinkNodes.filter(
|
||||||
|
(item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0
|
||||||
|
);
|
||||||
selectedLinkNodes.forEach((label: MapLinkNode) => {
|
selectedLinkNodes.forEach((label: MapLinkNode) => {
|
||||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0;
|
const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0;
|
||||||
if (isParentNodeSelected) {
|
if (isParentNodeSelected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import { DrawingAddingComponent } from './drawing-adding.component';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
import { Context } from '../../models/context';
|
import { Context } from '../../models/context';
|
||||||
|
import { DrawingAddingComponent } from './drawing-adding.component';
|
||||||
|
|
||||||
describe('DrawingAddingComponent', () => {
|
describe('DrawingAddingComponent', () => {
|
||||||
let component: DrawingAddingComponent;
|
let component: DrawingAddingComponent;
|
||||||
let fixture: ComponentFixture<DrawingAddingComponent>;
|
let fixture: ComponentFixture<DrawingAddingComponent>;
|
||||||
let drawingsEventSource = new DrawingsEventSource();
|
let drawingsEventSource = new DrawingsEventSource();
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource },
|
{ provide: DrawingsEventSource, useValue: drawingsEventSource },
|
||||||
{ provide: Context, useClass: Context }
|
{ provide: Context, useClass: Context },
|
||||||
],
|
],
|
||||||
declarations: [DrawingAddingComponent]
|
declarations: [DrawingAddingComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DrawingAddingComponent);
|
fixture = TestBed.createComponent(DrawingAddingComponent);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Context } from '../../models/context';
|
import { Subscription } from 'rxjs';
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
import { AddedDataEvent } from '../../events/event-source';
|
import { AddedDataEvent } from '../../events/event-source';
|
||||||
import { Subscription } from 'rxjs';
|
import { Context } from '../../models/context';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-drawing-adding',
|
selector: 'app-drawing-adding',
|
||||||
templateUrl: './drawing-adding.component.html',
|
templateUrl: './drawing-adding.component.html',
|
||||||
styleUrls: ['./drawing-adding.component.scss']
|
styleUrls: ['./drawing-adding.component.scss'],
|
||||||
})
|
})
|
||||||
export class DrawingAddingComponent implements OnInit, OnDestroy {
|
export class DrawingAddingComponent implements OnInit, OnDestroy {
|
||||||
@Input('svg') svg: SVGSVGElement;
|
@Input('svg') svg: SVGSVGElement;
|
||||||
@ -18,15 +18,19 @@ export class DrawingAddingComponent implements OnInit, OnDestroy {
|
|||||||
constructor(private drawingsEventSource: DrawingsEventSource, private context: Context) {}
|
constructor(private drawingsEventSource: DrawingsEventSource, private context: Context) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.drawingSelected = this.drawingsEventSource.selected.subscribe(evt => {
|
this.drawingSelected = this.drawingsEventSource.selected.subscribe((evt) => {
|
||||||
evt === '' ? this.deactivate() : this.activate();
|
evt === '' ? this.deactivate() : this.activate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
let listener = (event: MouseEvent) => {
|
let listener = (event: MouseEvent) => {
|
||||||
let x = (event.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x))/this.context.transformation.k;
|
let x =
|
||||||
let y = (event.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y))/this.context.transformation.k;
|
(event.pageX - (this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x)) /
|
||||||
|
this.context.transformation.k;
|
||||||
|
let y =
|
||||||
|
(event.pageY - (this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y)) /
|
||||||
|
this.context.transformation.k;
|
||||||
|
|
||||||
this.drawingsEventSource.pointToAddSelected.emit(new AddedDataEvent(x, y));
|
this.drawingsEventSource.pointToAddSelected.emit(new AddedDataEvent(x, y));
|
||||||
this.deactivate();
|
this.deactivate();
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { DrawingResizingComponent } from './drawing-resizing.component';
|
|
||||||
import { DrawingsWidget } from '../../widgets/drawings';
|
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
|
||||||
import { EventEmitter } from '@angular/core';
|
import { EventEmitter } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
import { ResizingEnd } from '../../events/resizing';
|
import { ResizingEnd } from '../../events/resizing';
|
||||||
import { MapDrawing } from '../../models/map/map-drawing';
|
import { MapDrawing } from '../../models/map/map-drawing';
|
||||||
|
import { DrawingsWidget } from '../../widgets/drawings';
|
||||||
|
import { DrawingResizingComponent } from './drawing-resizing.component';
|
||||||
|
|
||||||
export class DrawingWidgetMock {
|
export class DrawingWidgetMock {
|
||||||
resizingFinished = new EventEmitter<ResizingEnd<MapDrawing>>();
|
resizingFinished = new EventEmitter<ResizingEnd<MapDrawing>>();
|
||||||
@ -31,16 +30,16 @@ describe('DrawingResizingComponent', () => {
|
|||||||
let drawingsWidgetMock = new DrawingWidgetMock();
|
let drawingsWidgetMock = new DrawingWidgetMock();
|
||||||
let drawingsEventSource = new DrawingsEventSource();
|
let drawingsEventSource = new DrawingsEventSource();
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: DrawingsWidget, useValue: drawingsWidgetMock },
|
{ provide: DrawingsWidget, useValue: drawingsWidgetMock },
|
||||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource }
|
{ provide: DrawingsEventSource, useValue: drawingsEventSource },
|
||||||
],
|
],
|
||||||
declarations: [DrawingResizingComponent]
|
declarations: [DrawingResizingComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DrawingResizingComponent);
|
fixture = TestBed.createComponent(DrawingResizingComponent);
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
import { Component, OnInit, ElementRef, OnDestroy, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
import { DrawingsWidget } from '../../widgets/drawings';
|
|
||||||
import { MapDrawing } from '../../models/map/map-drawing';
|
|
||||||
import { ResizedDataEvent } from '../../events/event-source';
|
import { ResizedDataEvent } from '../../events/event-source';
|
||||||
import { ResizingEnd } from '../../events/resizing';
|
import { ResizingEnd } from '../../events/resizing';
|
||||||
|
import { MapDrawing } from '../../models/map/map-drawing';
|
||||||
|
import { DrawingsWidget } from '../../widgets/drawings';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-drawing-resizing',
|
selector: 'app-drawing-resizing',
|
||||||
template: `
|
template: ` <ng-content></ng-content> `,
|
||||||
<ng-content></ng-content>
|
styleUrls: ['./drawing-resizing.component.scss'],
|
||||||
`,
|
|
||||||
styleUrls: ['./drawing-resizing.component.scss']
|
|
||||||
})
|
})
|
||||||
export class DrawingResizingComponent implements OnInit, OnDestroy {
|
export class DrawingResizingComponent implements OnInit, OnDestroy {
|
||||||
resizingFinished: Subscription;
|
resizingFinished: Subscription;
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { DraggableComponent } from './draggable.component';
|
import { DraggableComponent } from './draggable.component';
|
||||||
|
|
||||||
describe('DraggableComponent', () => {
|
describe('DraggableComponent', () => {
|
||||||
let component: DraggableComponent;
|
let component: DraggableComponent;
|
||||||
let fixture: ComponentFixture<DraggableComponent>;
|
let fixture: ComponentFixture<DraggableComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [DraggableComponent]
|
declarations: [DraggableComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DraggableComponent);
|
fixture = TestBed.createComponent(DraggableComponent);
|
||||||
@ -18,7 +17,7 @@ describe('DraggableComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, ElementRef, AfterViewInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core';
|
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
import { Point } from '../../../models/point';
|
import { Point } from '../../../models/point';
|
||||||
|
|
||||||
@ -8,10 +8,8 @@ export class DraggableDraggedEvent {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-draggable]',
|
selector: '[app-draggable]',
|
||||||
template: `
|
template: ` <ng-content></ng-content> `,
|
||||||
<ng-content></ng-content>
|
styleUrls: ['./draggable.component.scss'],
|
||||||
`,
|
|
||||||
styleUrls: ['./draggable.component.scss']
|
|
||||||
})
|
})
|
||||||
export class DraggableComponent implements OnInit, AfterViewInit, OnDestroy {
|
export class DraggableComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||||
@Input('app-draggable') item: Point;
|
@Input('app-draggable') item: Point;
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
(dragging)="OnDragging($event)"
|
(dragging)="OnDragging($event)"
|
||||||
(dragged)="OnDragged($event)"
|
(dragged)="OnDragged($event)"
|
||||||
>
|
>
|
||||||
<svg:g *ngIf="is(drawing.element, 'ellipse')" [app-ellipse]="drawing.element" />
|
<svg:g *ngIf="is(drawing?.element, 'ellipse')" [app-ellipse]="drawing?.element" />
|
||||||
|
|
||||||
<svg:g *ngIf="is(drawing.element, 'image')" [app-image]="drawing.element" />
|
<svg:g *ngIf="is(drawing?.element, 'image')" [app-image]="drawing?.element" />
|
||||||
|
|
||||||
<svg:g *ngIf="is(drawing.element, 'line')" [app-line]="drawing.element" />
|
<svg:g *ngIf="is(drawing?.element, 'line')" [app-line]="drawing?.element" />
|
||||||
|
|
||||||
<svg:g *ngIf="is(drawing.element, 'rect')" [app-rect]="drawing.element" />
|
<svg:g *ngIf="is(drawing?.element, 'rect')" [app-rect]="drawing?.element" />
|
||||||
|
|
||||||
<svg:g *ngIf="is(drawing.element, 'text')" [app-text]="drawing.element" />
|
<svg:g *ngIf="is(drawing?.element, 'text')" [app-text]="drawing?.element" />
|
||||||
</svg:g>
|
</svg:g>
|
||||||
|
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 573 B |
@ -1,16 +1,18 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import {ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { DrawingsEventSource } from 'app/cartography/events/drawings-event-source';
|
||||||
|
import { SvgToDrawingConverter } from 'app/cartography/helpers/svg-to-drawing-converter';
|
||||||
import { DrawingComponent } from './drawing.component';
|
import { DrawingComponent } from './drawing.component';
|
||||||
|
|
||||||
describe('DrawingComponent', () => {
|
describe('DrawingComponent', () => {
|
||||||
let component: DrawingComponent;
|
let component: DrawingComponent;
|
||||||
let fixture: ComponentFixture<DrawingComponent>;
|
let fixture: ComponentFixture<DrawingComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [DrawingComponent]
|
declarations: [DrawingComponent],
|
||||||
|
providers:[SvgToDrawingConverter,DrawingsEventSource]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DrawingComponent);
|
fixture = TestBed.createComponent(DrawingComponent);
|
||||||
@ -18,7 +20,7 @@ describe('DrawingComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { Component, OnInit, Input, ChangeDetectorRef } from '@angular/core';
|
import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
|
||||||
|
import { DrawingsEventSource } from '../../../events/drawings-event-source';
|
||||||
|
import { DraggedDataEvent } from '../../../events/event-source';
|
||||||
|
import { SvgToDrawingConverter } from '../../../helpers/svg-to-drawing-converter';
|
||||||
import { EllipseElement } from '../../../models/drawings/ellipse-element';
|
import { EllipseElement } from '../../../models/drawings/ellipse-element';
|
||||||
import { ImageElement } from '../../../models/drawings/image-element';
|
import { ImageElement } from '../../../models/drawings/image-element';
|
||||||
import { LineElement } from '../../../models/drawings/line-element';
|
import { LineElement } from '../../../models/drawings/line-element';
|
||||||
import { RectElement } from '../../../models/drawings/rect-element';
|
import { RectElement } from '../../../models/drawings/rect-element';
|
||||||
import { TextElement } from '../../../models/drawings/text-element';
|
import { TextElement } from '../../../models/drawings/text-element';
|
||||||
import { SvgToDrawingConverter } from '../../../helpers/svg-to-drawing-converter';
|
|
||||||
import { DraggedDataEvent } from '../../../events/event-source';
|
|
||||||
import { MapDrawing } from '../../../models/map/map-drawing';
|
import { MapDrawing } from '../../../models/map/map-drawing';
|
||||||
import { DrawingsEventSource } from '../../../events/drawings-event-source';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-drawing]',
|
selector: '[app-drawing]',
|
||||||
templateUrl: './drawing.component.html',
|
templateUrl: './drawing.component.html',
|
||||||
styleUrls: ['./drawing.component.scss']
|
styleUrls: ['./drawing.component.scss'],
|
||||||
})
|
})
|
||||||
export class DrawingComponent implements OnInit {
|
export class DrawingComponent implements OnInit {
|
||||||
@Input('app-drawing') drawing: MapDrawing;
|
@Input('app-drawing') drawing: MapDrawing;
|
||||||
@ -21,19 +21,17 @@ export class DrawingComponent implements OnInit {
|
|||||||
private svgToDrawingConverter: SvgToDrawingConverter,
|
private svgToDrawingConverter: SvgToDrawingConverter,
|
||||||
private drawingsEventSource: DrawingsEventSource,
|
private drawingsEventSource: DrawingsEventSource,
|
||||||
private cd: ChangeDetectorRef
|
private cd: ChangeDetectorRef
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
try {
|
try {
|
||||||
this.drawing.element = this.svgToDrawingConverter.convert(this.drawing.svg);
|
this.drawing.element = this.svgToDrawingConverter.convert(this.drawing.svg);
|
||||||
} catch (error) {
|
} catch (error) { }
|
||||||
console.log(`Cannot convert due to Error: '${error}'`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OnDragging(evt) {
|
OnDragging(evt) {
|
||||||
this.drawing.x = evt.x;
|
this.drawing.x = evt ? evt.x : '';
|
||||||
this.drawing.y = evt.y;
|
this.drawing.y = evt ? evt.y : '';
|
||||||
this.cd.detectChanges();
|
this.cd.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +64,8 @@ export class DrawingComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get transformation() {
|
get transformation() {
|
||||||
return `translate(${this.drawing.x},${this.drawing.y}) rotate(${this.drawing.rotation})`;
|
if (this.drawing) {
|
||||||
|
return `translate(${this.drawing.x},${this.drawing.y}) rotate(${this.drawing.rotation})`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<svg:ellipse
|
<svg:ellipse
|
||||||
class="ellipse_element noselect"
|
class="ellipse_element noselect"
|
||||||
[attr.fill]="ellipse.fill"
|
[attr.fill]="ellipse?.fill"
|
||||||
[attr.fill-opacity]="fill_opacity"
|
[attr.fill-opacity]="fill_opacity"
|
||||||
[attr.stroke]="ellipse.stroke"
|
[attr.stroke]="ellipse?.stroke"
|
||||||
[attr.stroke-width]="stroke_width"
|
[attr.stroke-width]="stroke_width"
|
||||||
[attr.stroke-dasharray]="stroke_dasharray"
|
[attr.stroke-dasharray]="stroke_dasharray"
|
||||||
[attr.cx]="ellipse.cx"
|
[attr.cx]="ellipse?.cx"
|
||||||
[attr.cy]="ellipse.cy"
|
[attr.cy]="ellipse?.cy"
|
||||||
[attr.rx]="ellipse.rx"
|
[attr.rx]="ellipse?.rx"
|
||||||
[attr.ry]="ellipse.ry"
|
[attr.ry]="ellipse?.ry"
|
||||||
/>
|
/>
|
||||||
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 338 B |
@ -1,16 +1,17 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { QtDasharrayFixer } from 'app/cartography/helpers/qt-dasharray-fixer';
|
||||||
import { EllipseComponent } from './ellipse.component';
|
import { EllipseComponent } from './ellipse.component';
|
||||||
|
|
||||||
describe('EllipseComponent', () => {
|
describe('EllipseComponent', () => {
|
||||||
let component: EllipseComponent;
|
let component: EllipseComponent;
|
||||||
let fixture: ComponentFixture<EllipseComponent>;
|
let fixture: ComponentFixture<EllipseComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [EllipseComponent]
|
declarations: [EllipseComponent],
|
||||||
|
providers:[QtDasharrayFixer]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(EllipseComponent);
|
fixture = TestBed.createComponent(EllipseComponent);
|
||||||
@ -18,7 +19,7 @@ describe('EllipseComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { EllipseElement } from '../../../../../models/drawings/ellipse-element';
|
|
||||||
import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
||||||
|
import { EllipseElement } from '../../../../../models/drawings/ellipse-element';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-ellipse]',
|
selector: '[app-ellipse]',
|
||||||
templateUrl: './ellipse.component.html',
|
templateUrl: './ellipse.component.html',
|
||||||
styleUrls: ['./ellipse.component.scss']
|
styleUrls: ['./ellipse.component.scss'],
|
||||||
})
|
})
|
||||||
export class EllipseComponent implements OnInit {
|
export class EllipseComponent implements OnInit {
|
||||||
@Input('app-ellipse') ellipse: EllipseElement;
|
@Input('app-ellipse') ellipse: EllipseElement;
|
||||||
@ -15,21 +15,21 @@ export class EllipseComponent implements OnInit {
|
|||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
get fill_opacity() {
|
get fill_opacity() {
|
||||||
if (isFinite(this.ellipse.fill_opacity)) {
|
if (this.ellipse && isFinite(this.ellipse.fill_opacity)) {
|
||||||
return this.ellipse.fill_opacity;
|
return this.ellipse.fill_opacity;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_width() {
|
get stroke_width() {
|
||||||
if (isFinite(this.ellipse.stroke_width)) {
|
if (this.ellipse && isFinite(this.ellipse.stroke_width)) {
|
||||||
return this.ellipse.stroke_width;
|
return this.ellipse.stroke_width;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_dasharray() {
|
get stroke_dasharray() {
|
||||||
if (this.ellipse.stroke_dasharray) {
|
if (this.ellipse && this.ellipse.stroke_dasharray) {
|
||||||
return this.qtDasharrayFixer.fix(this.ellipse.stroke_dasharray);
|
return this.qtDasharrayFixer.fix(this.ellipse.stroke_dasharray);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<svg:image
|
<svg:image
|
||||||
class="image_element noselect"
|
class="image_element noselect"
|
||||||
[attr.xlink:href]="image.data"
|
[attr.xlink:href]="image?.data"
|
||||||
[attr.width]="image.width"
|
[attr.width]="image?.width"
|
||||||
[attr.height]="image.height"
|
[attr.height]="image?.height"
|
||||||
/>
|
/>
|
||||||
|
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 143 B |
@ -1,16 +1,15 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { ImageComponent } from './image.component';
|
import { ImageComponent } from './image.component';
|
||||||
|
|
||||||
describe('ImageComponent', () => {
|
describe('ImageComponent', () => {
|
||||||
let component: ImageComponent;
|
let component: ImageComponent;
|
||||||
let fixture: ComponentFixture<ImageComponent>;
|
let fixture: ComponentFixture<ImageComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [ImageComponent]
|
declarations: [ImageComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(ImageComponent);
|
fixture = TestBed.createComponent(ImageComponent);
|
||||||
@ -18,7 +17,7 @@ describe('ImageComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { ImageElement } from '../../../../../models/drawings/image-element';
|
import { ImageElement } from '../../../../../models/drawings/image-element';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-image]',
|
selector: '[app-image]',
|
||||||
templateUrl: './image.component.html',
|
templateUrl: './image.component.html',
|
||||||
styleUrls: ['./image.component.scss']
|
styleUrls: ['./image.component.scss'],
|
||||||
})
|
})
|
||||||
export class ImageComponent implements OnInit {
|
export class ImageComponent implements OnInit {
|
||||||
@Input('app-image') image: ImageElement;
|
@Input('app-image') image: ImageElement;
|
||||||
|
data:any
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<svg:line
|
<svg:line
|
||||||
class="line_element noselect"
|
class="line_element noselect"
|
||||||
[attr.stroke]="line.stroke"
|
[attr.stroke]="line?.stroke"
|
||||||
[attr.stroke-width]="stroke_width"
|
[attr.stroke-width]="stroke_width ?? ''"
|
||||||
[attr.stroke-dasharray]="stroke_dasharray"
|
[attr.stroke-dasharray]="stroke_dasharray"
|
||||||
[attr.x1]="line.x1"
|
[attr.x1]="line?.x1"
|
||||||
[attr.x2]="line.x2"
|
[attr.x2]="line?.x2"
|
||||||
[attr.y1]="line.y1"
|
[attr.y1]="line?.y1"
|
||||||
[attr.y2]="line.y2"
|
[attr.y2]="line?.y2"
|
||||||
/>
|
/>
|
||||||
|
Before Width: | Height: | Size: 245 B After Width: | Height: | Size: 256 B |
@ -1,16 +1,17 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import {ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { QtDasharrayFixer } from 'app/cartography/helpers/qt-dasharray-fixer';
|
||||||
import { LineComponent } from './line.component';
|
import { LineComponent } from './line.component';
|
||||||
|
|
||||||
describe('LineComponent', () => {
|
describe('LineComponent', () => {
|
||||||
let component: LineComponent;
|
let component: LineComponent;
|
||||||
let fixture: ComponentFixture<LineComponent>;
|
let fixture: ComponentFixture<LineComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [LineComponent]
|
declarations: [LineComponent],
|
||||||
|
providers:[QtDasharrayFixer]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(LineComponent);
|
fixture = TestBed.createComponent(LineComponent);
|
||||||
@ -18,7 +19,7 @@ describe('LineComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
||||||
import { LineElement } from '../../../../../models/drawings/line-element';
|
import { LineElement } from '../../../../../models/drawings/line-element';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-line]',
|
selector: '[app-line]',
|
||||||
templateUrl: './line.component.html',
|
templateUrl: './line.component.html',
|
||||||
styleUrls: ['./line.component.scss']
|
styleUrls: ['./line.component.scss'],
|
||||||
})
|
})
|
||||||
export class LineComponent implements OnInit {
|
export class LineComponent implements OnInit {
|
||||||
@Input('app-line') line: LineElement;
|
@Input('app-line') line: LineElement;
|
||||||
@ -15,14 +15,14 @@ export class LineComponent implements OnInit {
|
|||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
get stroke_width() {
|
get stroke_width() {
|
||||||
if (isFinite(this.line.stroke_width)) {
|
if (this.line && isFinite(this.line.stroke_width)) {
|
||||||
return this.line.stroke_width;
|
return this.line.stroke_width;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_dasharray() {
|
get stroke_dasharray() {
|
||||||
if (this.line.stroke_dasharray) {
|
if ( this.line && this.line.stroke_dasharray) {
|
||||||
return this.qtDasharrayFixer.fix(this.line.stroke_dasharray);
|
return this.qtDasharrayFixer.fix(this.line.stroke_dasharray);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<svg:rect
|
<svg:rect
|
||||||
class="rect_element noselect"
|
class="rect_element noselect"
|
||||||
[attr.fill]="rect.fill"
|
[attr.fill]="rect?.fill"
|
||||||
[attr.fill-opacity]="fill_opacity"
|
[attr.fill-opacity]="fill_opacity ? fill_opacity : '' "
|
||||||
[attr.stroke]="rect.stroke"
|
[attr.stroke]="rect?.stroke"
|
||||||
[attr.stroke-width]="stroke_width"
|
[attr.stroke-width]="stroke_width"
|
||||||
[attr.stroke-dasharray]="stroke_dasharray"
|
[attr.stroke-dasharray]="stroke_dasharray"
|
||||||
[attr.width]="rect.width"
|
[attr.width]="rect?.width"
|
||||||
[attr.height]="rect.height"
|
[attr.height]="rect?.height"
|
||||||
/>
|
/>
|
||||||
|
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 303 B |
@ -1,16 +1,17 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import {ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { QtDasharrayFixer } from 'app/cartography/helpers/qt-dasharray-fixer';
|
||||||
import { RectComponent } from './rect.component';
|
import { RectComponent } from './rect.component';
|
||||||
|
|
||||||
describe('RectComponent', () => {
|
describe('RectComponent', () => {
|
||||||
let component: RectComponent;
|
let component: RectComponent;
|
||||||
let fixture: ComponentFixture<RectComponent>;
|
let fixture: ComponentFixture<RectComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [RectComponent]
|
declarations: [RectComponent],
|
||||||
|
providers:[QtDasharrayFixer]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(RectComponent);
|
fixture = TestBed.createComponent(RectComponent);
|
||||||
@ -18,7 +19,7 @@ describe('RectComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { RectElement } from '../../../../../models/drawings/rect-element';
|
|
||||||
import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
||||||
|
import { RectElement } from '../../../../../models/drawings/rect-element';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-rect]',
|
selector: '[app-rect]',
|
||||||
templateUrl: './rect.component.html',
|
templateUrl: './rect.component.html',
|
||||||
styleUrls: ['./rect.component.scss']
|
styleUrls: ['./rect.component.scss'],
|
||||||
})
|
})
|
||||||
export class RectComponent implements OnInit {
|
export class RectComponent implements OnInit {
|
||||||
@Input('app-rect') rect: RectElement;
|
@Input('app-rect') rect: RectElement;
|
||||||
@ -15,21 +15,21 @@ export class RectComponent implements OnInit {
|
|||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
get fill_opacity() {
|
get fill_opacity() {
|
||||||
if (isFinite(this.rect.fill_opacity)) {
|
if (this.rect && isFinite(this.rect.fill_opacity)) {
|
||||||
return this.rect.fill_opacity;
|
return this.rect.fill_opacity ? this.rect.fill_opacity : null;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_width() {
|
get stroke_width() {
|
||||||
if (isFinite(this.rect.stroke_width)) {
|
if (this.rect && isFinite(this.rect.stroke_width)) {
|
||||||
return this.rect.stroke_width;
|
return this.rect.stroke_width ? this.rect.stroke_width : null;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stroke_dasharray() {
|
get stroke_dasharray() {
|
||||||
if (this.rect.stroke_dasharray) {
|
if (this.rect && this.rect.stroke_dasharray) {
|
||||||
return this.qtDasharrayFixer.fix(this.rect.stroke_dasharray);
|
return this.qtDasharrayFixer.fix(this.rect.stroke_dasharray);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class="text_element noselect"
|
class="text_element noselect"
|
||||||
[attr.style]="style"
|
[attr.style]="style"
|
||||||
[attr.text-decoration]="textDecoration"
|
[attr.text-decoration]="textDecoration"
|
||||||
[attr.fill]="text.fill"
|
[attr.fill]="text?.fill"
|
||||||
[attr.transform]="transformation"
|
[attr.transform]="transformation"
|
||||||
>
|
>
|
||||||
<svg:tspan *ngFor="let line of lines; index as i" xml:space="preserve" x="0" [attr.dy]="i == 0 ? '0em' : '1.4em'">
|
<svg:tspan *ngFor="let line of lines; index as i" xml:space="preserve" x="0" [attr.dy]="i == 0 ? '0em' : '1.4em'">
|
||||||
|
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 339 B |
@ -1,16 +1,17 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { FontFixer } from 'app/cartography/helpers/font-fixer';
|
||||||
import { TextComponent } from './text.component';
|
import { TextComponent } from './text.component';
|
||||||
|
|
||||||
describe('TextComponent', () => {
|
describe('TextComponent', () => {
|
||||||
let component: TextComponent;
|
let component: TextComponent;
|
||||||
let fixture: ComponentFixture<TextComponent>;
|
let fixture: ComponentFixture<TextComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [TextComponent]
|
declarations: [TextComponent],
|
||||||
|
providers:[FontFixer]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(TextComponent);
|
fixture = TestBed.createComponent(TextComponent);
|
||||||
@ -18,7 +19,7 @@ describe('TextComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,28 +1,30 @@
|
|||||||
import { Component, OnInit, Input, ViewChild, ElementRef, DoCheck } from '@angular/core';
|
import { Component, DoCheck, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
import { TextElement } from '../../../../../models/drawings/text-element';
|
|
||||||
import { FontFixer } from '../../../../../helpers/font-fixer';
|
import { FontFixer } from '../../../../../helpers/font-fixer';
|
||||||
|
import { TextElement } from '../../../../../models/drawings/text-element';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-text]',
|
selector: '[app-text]',
|
||||||
templateUrl: './text.component.html',
|
templateUrl: './text.component.html',
|
||||||
styleUrls: ['./text.component.scss']
|
styleUrls: ['./text.component.scss'],
|
||||||
})
|
})
|
||||||
export class TextComponent implements OnInit, DoCheck {
|
export class TextComponent implements OnInit, DoCheck {
|
||||||
static MARGIN = 4;
|
static MARGIN = 4;
|
||||||
|
|
||||||
@Input('app-text') text: TextElement;
|
@Input('app-text') text: TextElement;
|
||||||
|
|
||||||
@ViewChild('text', {static: false}) textRef: ElementRef;
|
@ViewChild('text') textRef: ElementRef;
|
||||||
|
|
||||||
lines: string[] = [];
|
lines: string[] = [];
|
||||||
|
|
||||||
transformation = '';
|
transformation = '';
|
||||||
|
|
||||||
constructor(private fontFixer: FontFixer, private sanitizer: DomSanitizer) {}
|
constructor(private fontFixer: FontFixer, private sanitizer: DomSanitizer) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.lines = this.getLines(this.text.text);
|
if (this.text) {
|
||||||
|
this.lines = this.getLines(this.text.text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngDoCheck() {
|
ngDoCheck() {
|
||||||
@ -30,32 +32,38 @@ export class TextComponent implements OnInit, DoCheck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get style() {
|
get style() {
|
||||||
const font = this.fontFixer.fix(this.text);
|
if (this.text) {
|
||||||
|
const font = this.fontFixer.fix(this.text);
|
||||||
|
|
||||||
const styles: string[] = [];
|
const styles: string[] = [];
|
||||||
if (font.font_family) {
|
if (font.font_family) {
|
||||||
styles.push(`font-family: "${this.text.font_family}"`);
|
styles.push(`font-family: "${this.text.font_family}"`);
|
||||||
|
}
|
||||||
|
if (font.font_size) {
|
||||||
|
styles.push(`font-size: ${this.text.font_size}pt`);
|
||||||
|
}
|
||||||
|
if (font.font_weight) {
|
||||||
|
styles.push(`font-weight: ${this.text.font_weight}`);
|
||||||
|
}
|
||||||
|
return this.sanitizer.bypassSecurityTrustStyle(styles.join('; '));
|
||||||
}
|
}
|
||||||
if (font.font_size) {
|
|
||||||
styles.push(`font-size: ${this.text.font_size}pt`);
|
|
||||||
}
|
|
||||||
if (font.font_weight) {
|
|
||||||
styles.push(`font-weight: ${this.text.font_weight}`);
|
|
||||||
}
|
|
||||||
return this.sanitizer.bypassSecurityTrustStyle(styles.join('; '));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get textDecoration() {
|
get textDecoration() {
|
||||||
return this.text.text_decoration;
|
if (this.text) {
|
||||||
|
return this.text.text_decoration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateTransformation() {
|
calculateTransformation() {
|
||||||
const tspans = this.textRef.nativeElement.getElementsByTagName('tspan');
|
if (this.textRef != undefined) {
|
||||||
if (tspans.length > 0) {
|
const tspans = this.textRef.nativeElement.getElementsByTagName('tspan');
|
||||||
const height = this.textRef.nativeElement.getBBox().height / tspans.length;
|
if (tspans.length > 0) {
|
||||||
return `translate(${TextComponent.MARGIN}, ${height - TextComponent.MARGIN})`;
|
const height = this.textRef.nativeElement.getBBox().height / tspans.length;
|
||||||
|
return `translate(${TextComponent.MARGIN}, ${height - TextComponent.MARGIN})`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getLines(text: string) {
|
getLines(text: string) {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
HostListener,
|
HostListener,
|
||||||
@ -7,29 +9,26 @@ import {
|
|||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
SimpleChange,
|
SimpleChange,
|
||||||
ChangeDetectionStrategy,
|
ViewChild,
|
||||||
ChangeDetectorRef,
|
|
||||||
ViewChild
|
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
import { GraphLayout } from '../../widgets/graph-layout';
|
|
||||||
import { Context } from '../../models/context';
|
|
||||||
import { Size } from '../../models/size';
|
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
|
||||||
import { CanvasSizeDetector } from '../../helpers/canvas-size-detector';
|
|
||||||
import { Node } from '../../models/node';
|
|
||||||
import { Link } from '../../../models/link';
|
import { Link } from '../../../models/link';
|
||||||
import { Drawing } from '../../models/drawing';
|
|
||||||
import { Symbol } from '../../../models/symbol';
|
import { Symbol } from '../../../models/symbol';
|
||||||
|
import { CanvasSizeDetector } from '../../helpers/canvas-size-detector';
|
||||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||||
import { LayersManager } from '../../managers/layers-manager';
|
import { LayersManager } from '../../managers/layers-manager';
|
||||||
|
import { Context } from '../../models/context';
|
||||||
|
import { Drawing } from '../../models/drawing';
|
||||||
|
import { Node } from '../../models/node';
|
||||||
|
import { Size } from '../../models/size';
|
||||||
|
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
||||||
|
import { GraphLayout } from '../../widgets/graph-layout';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-experimental-map',
|
selector: 'app-experimental-map',
|
||||||
templateUrl: './experimental-map.component.html',
|
templateUrl: './experimental-map.component.html',
|
||||||
styleUrls: ['./experimental-map.component.scss'],
|
styleUrls: ['./experimental-map.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
@Input() nodes: Node[] = [];
|
@Input() nodes: Node[] = [];
|
||||||
@ -43,12 +42,12 @@ export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
@Input() width = 1500;
|
@Input() width = 1500;
|
||||||
@Input() height = 600;
|
@Input() height = 600;
|
||||||
|
|
||||||
@ViewChild('svg', {static: false}) svg: ElementRef;
|
@ViewChild('svg') svg: ElementRef;
|
||||||
|
|
||||||
private changesDetected: Subscription;
|
private changesDetected: Subscription;
|
||||||
|
|
||||||
protected settings = {
|
protected settings = {
|
||||||
show_interface_labels: true
|
show_interface_labels: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -1,16 +1,28 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ChangeDetectorRef, ElementRef, Injectable } from '@angular/core';
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { CssFixer } from 'app/cartography/helpers/css-fixer';
|
||||||
import { InterfaceLabelComponent } from './interface-label.component';
|
import { InterfaceLabelComponent } from './interface-label.component';
|
||||||
|
|
||||||
describe('InterfaceLabelComponent', () => {
|
export class MockElementRef extends ElementRef {
|
||||||
|
constructor() { super(null || undefined); }
|
||||||
|
nativeElement={}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xdescribe('InterfaceLabelComponent', () => {
|
||||||
let component: InterfaceLabelComponent;
|
let component: InterfaceLabelComponent;
|
||||||
let fixture: ComponentFixture<InterfaceLabelComponent>;
|
let fixture: ComponentFixture<InterfaceLabelComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [InterfaceLabelComponent]
|
declarations: [InterfaceLabelComponent],
|
||||||
|
providers: [
|
||||||
|
CssFixer,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
{ provide: ElementRef, useValue: new MockElementRef() },
|
||||||
|
]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(InterfaceLabelComponent);
|
fixture = TestBed.createComponent(InterfaceLabelComponent);
|
||||||
@ -18,7 +30,7 @@ describe('InterfaceLabelComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy()
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import { Component, OnInit, Input, ChangeDetectorRef, ElementRef, ViewChild } from '@angular/core';
|
import { ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
import { CssFixer } from '../../../helpers/css-fixer';
|
import { CssFixer } from '../../../helpers/css-fixer';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-interface-label]',
|
selector: '[app-interface-label]',
|
||||||
templateUrl: './interface-label.component.html',
|
templateUrl: './interface-label.component.html',
|
||||||
styleUrls: ['./interface-label.component.scss']
|
styleUrls: ['./interface-label.component.scss'],
|
||||||
})
|
})
|
||||||
export class InterfaceLabelComponent implements OnInit {
|
export class InterfaceLabelComponent implements OnInit {
|
||||||
@Input('app-interface-label') ignore: any;
|
@Input('app-interface-label') ignore: any;
|
||||||
|
|
||||||
@ViewChild('textSvg', {static: false}) textRef: ElementRef;
|
@ViewChild('textSvg') textRef: ElementRef;
|
||||||
|
|
||||||
private label = {
|
private label = {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
text: '',
|
text: '',
|
||||||
style: '',
|
style: '',
|
||||||
rotation: 0
|
rotation: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
borderSize = 5;
|
borderSize = 5;
|
||||||
@ -30,9 +30,9 @@ export class InterfaceLabelComponent implements OnInit {
|
|||||||
private ref: ChangeDetectorRef,
|
private ref: ChangeDetectorRef,
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
private cssFixer: CssFixer
|
private cssFixer: CssFixer
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() { }
|
||||||
|
|
||||||
@Input('x')
|
@Input('x')
|
||||||
set x(value) {
|
set x(value) {
|
||||||
@ -89,9 +89,11 @@ export class InterfaceLabelComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get transform() {
|
get transform() {
|
||||||
const bbox = this.elementRef.nativeElement.getBBox();
|
if (this.elementRef.nativeElement.getBBox) {
|
||||||
const x = this.label.x;
|
const bbox = this.elementRef.nativeElement.getBBox()
|
||||||
const y = this.label.y + bbox.height;
|
const x = this.label.x;
|
||||||
return `translate(${x}, ${y}) rotate(${this.label.rotation}, ${x}, ${y})`;
|
const y = this.label.y + bbox.height;
|
||||||
|
return `translate(${x}, ${y}) rotate(${this.label.rotation}, ${x}, ${y})`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<svg:g
|
<svg:g
|
||||||
class="link"
|
class="link"
|
||||||
[attr.link_id]="link.id"
|
[attr.link_id]="link?.id"
|
||||||
[attr.map-source]="link.source.id"
|
[attr.map-source]="link?.source?.id"
|
||||||
[attr.map-target]="link.target.id"
|
[attr.map-target]="link?.target?.id"
|
||||||
[attr.transform]="transform"
|
[attr.transform]="transform"
|
||||||
>
|
>
|
||||||
<svg:path
|
<svg:path
|
||||||
#path
|
#path
|
||||||
*ngIf="link.linkType == 'ethernet'"
|
*ngIf="link?.linkType == 'ethernet'"
|
||||||
class="ethernet_link"
|
class="ethernet_link"
|
||||||
stroke="#000"
|
stroke="#000"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<svg:path
|
<svg:path
|
||||||
#path
|
#path
|
||||||
*ngIf="link.linkType == 'serial'"
|
*ngIf="link?.linkType == 'serial'"
|
||||||
class="serial_link"
|
class="serial_link"
|
||||||
stroke="#B22222"
|
stroke="#B22222"
|
||||||
fill="none"
|
fill="none"
|
||||||
@ -24,27 +24,27 @@
|
|||||||
[attr.d]="d"
|
[attr.d]="d"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<svg:g [app-status]="link.source.status" [direction]="'source'" [path]="path" [d]="d" />
|
<svg:g [app-status]="link?.source?.status" [direction]="'source'" [path]="path" [d]="d" />
|
||||||
|
|
||||||
<svg:g [app-status]="link.target.status" [direction]="'target'" [path]="path" [d]="d" />
|
<svg:g [app-status]="link?.target?.status" [direction]="'target'" [path]="path" [d]="d" />
|
||||||
|
|
||||||
<svg:g
|
<svg:g
|
||||||
*ngIf="showInterfaceLabels"
|
*ngIf="showInterfaceLabels"
|
||||||
[app-interface-label]
|
[app-interface-label]
|
||||||
[x]="link.source.x + link.nodes[0].label.x"
|
[x]="link?.source?.x + link?.nodes[0]?.label?.x"
|
||||||
[y]="link.source.y + link.nodes[0].label.y"
|
[y]="link?.source?.y + link?.nodes[0]?.label?.y"
|
||||||
[text]="link.nodes[0].label.text"
|
[text]="link?.nodes[0]?.label?.text"
|
||||||
[style]="link.nodes[0].label.style"
|
[style]="link?.nodes[0]?.label?.style"
|
||||||
[rotation]="link.nodes[0].label.rotation"
|
[rotation]="link?.nodes[0]?.label?.rotation"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<svg:g
|
<svg:g
|
||||||
*ngIf="showInterfaceLabels"
|
*ngIf="showInterfaceLabels"
|
||||||
[app-interface-label]
|
[app-interface-label]
|
||||||
[x]="link.target.x + link.nodes[1].label.x"
|
[x]="link?.target?.x + link?.nodes[1]?.label?.x"
|
||||||
[y]="link.target.y + link.nodes[1].label.y"
|
[y]="link?.target?.y + link?.nodes[1]?.label?.y"
|
||||||
[text]="link.nodes[1].label.text"
|
[text]="link?.nodes[1]?.label?.text"
|
||||||
[style]="link.nodes[1].label.style"
|
[style]="link?.nodes[1]?.label?.style"
|
||||||
[rotation]="link.nodes[1].label.rotation"
|
[rotation]="link?.nodes[1]?.label?.rotation"
|
||||||
/>
|
/>
|
||||||
</svg:g>
|
</svg:g>
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
@ -1,16 +1,18 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { MultiLinkCalculatorHelper } from 'app/cartography/helpers/multi-link-calculator-helper';
|
||||||
import { LinkComponent } from './link.component';
|
import { LinkComponent } from './link.component';
|
||||||
|
|
||||||
describe('LinkComponent', () => {
|
describe('LinkComponent', () => {
|
||||||
let component: LinkComponent;
|
let component: LinkComponent;
|
||||||
let fixture: ComponentFixture<LinkComponent>;
|
let fixture: ComponentFixture<LinkComponent>;
|
||||||
|
beforeEach(async () => {
|
||||||
beforeEach(async(() => {
|
await TestBed.configureTestingModule({
|
||||||
TestBed.configureTestingModule({
|
declarations: [LinkComponent],
|
||||||
declarations: [LinkComponent]
|
providers: [
|
||||||
|
{ provide: MultiLinkCalculatorHelper, useValue: {} }
|
||||||
|
]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(LinkComponent);
|
fixture = TestBed.createComponent(LinkComponent);
|
||||||
@ -18,7 +20,7 @@ describe('LinkComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,39 +1,39 @@
|
|||||||
import {
|
import {
|
||||||
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
OnInit,
|
|
||||||
Input,
|
|
||||||
ViewChild,
|
|
||||||
ElementRef,
|
ElementRef,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
ChangeDetectorRef,
|
Input,
|
||||||
OnDestroy
|
OnDestroy,
|
||||||
|
OnInit,
|
||||||
|
ViewChild,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { LinkStrategy } from './strategies/link-strategy';
|
|
||||||
import { EthernetLinkStrategy } from './strategies/ethernet-link-strategy';
|
|
||||||
import { SerialLinkStrategy } from './strategies/serial-link-strategy';
|
|
||||||
import { MultiLinkCalculatorHelper } from '../../../helpers/multi-link-calculator-helper';
|
import { MultiLinkCalculatorHelper } from '../../../helpers/multi-link-calculator-helper';
|
||||||
import { Node } from '../../../models/node';
|
|
||||||
import { MapLink } from '../../../models/map/map-link';
|
import { MapLink } from '../../../models/map/map-link';
|
||||||
|
import { Node } from '../../../models/node';
|
||||||
|
import { EthernetLinkStrategy } from './strategies/ethernet-link-strategy';
|
||||||
|
import { LinkStrategy } from './strategies/link-strategy';
|
||||||
|
import { SerialLinkStrategy } from './strategies/serial-link-strategy';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-link]',
|
selector: '[app-link]',
|
||||||
templateUrl: './link.component.html',
|
templateUrl: './link.component.html',
|
||||||
styleUrls: ['./link.component.scss']
|
styleUrls: ['./link.component.scss'],
|
||||||
})
|
})
|
||||||
export class LinkComponent implements OnInit, OnDestroy {
|
export class LinkComponent implements OnInit, OnDestroy {
|
||||||
@Input('app-link') link: MapLink;
|
@Input('app-link') link: MapLink;
|
||||||
@Input('node-changed') nodeChanged: EventEmitter<Node>;
|
@Input('node-changed') nodeChanged: EventEmitter<Node>;
|
||||||
@Input('show-interface-labels') showInterfaceLabels: boolean;
|
@Input('show-interface-labels') showInterfaceLabels: boolean;
|
||||||
|
|
||||||
@ViewChild('path', {static: false}) path: ElementRef;
|
@ViewChild('path') path: ElementRef;
|
||||||
|
|
||||||
private ethernetLinkStrategy = new EthernetLinkStrategy();
|
private ethernetLinkStrategy = new EthernetLinkStrategy();
|
||||||
private serialLinkStrategy = new SerialLinkStrategy();
|
private serialLinkStrategy = new SerialLinkStrategy();
|
||||||
|
|
||||||
private nodeChangedSubscription: Subscription;
|
private nodeChangedSubscription: Subscription;
|
||||||
|
|
||||||
constructor(private multiLinkCalculatorHelper: MultiLinkCalculatorHelper, private ref: ChangeDetectorRef) {}
|
constructor(private multiLinkCalculatorHelper: MultiLinkCalculatorHelper, private ref: ChangeDetectorRef) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.ref.detectChanges();
|
this.ref.detectChanges();
|
||||||
@ -49,19 +49,21 @@ export class LinkComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get strategy(): LinkStrategy {
|
get strategy(): LinkStrategy {
|
||||||
if (this.link.linkType === 'serial') {
|
if (this.link && this.link != undefined && this.link.linkType === 'serial') {
|
||||||
return this.serialLinkStrategy;
|
return this.serialLinkStrategy;
|
||||||
}
|
}
|
||||||
return this.ethernetLinkStrategy;
|
return this.ethernetLinkStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
get transform() {
|
get transform() {
|
||||||
const translation = this.multiLinkCalculatorHelper.linkTranslation(
|
if (this.link) {
|
||||||
this.link.distance,
|
const translation = this.multiLinkCalculatorHelper.linkTranslation(
|
||||||
this.link.source,
|
this.link.distance,
|
||||||
this.link.target
|
this.link.source,
|
||||||
);
|
this.link.target
|
||||||
return `translate (${translation.dx}, ${translation.dy})`;
|
);
|
||||||
|
return `translate (${translation.dx}, ${translation.dy})`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get d() {
|
get d() {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { LinkStrategy } from './link-strategy';
|
|
||||||
import { path } from 'd3-path';
|
import { path } from 'd3-path';
|
||||||
import { MapLink } from '../../../../models/map/map-link';
|
import { MapLink } from '../../../../models/map/map-link';
|
||||||
|
import { LinkStrategy } from './link-strategy';
|
||||||
|
|
||||||
export class EthernetLinkStrategy implements LinkStrategy {
|
export class EthernetLinkStrategy implements LinkStrategy {
|
||||||
public d(link: MapLink): string {
|
public d(link: MapLink): string {
|
||||||
const points = [
|
const points = [
|
||||||
[link.source.x + link.source.width / 2, link.source.y + link.source.height / 2],
|
|
||||||
[link.target.x + link.target.width / 2, link.target.y + link.target.height / 2]
|
[link?.source?.x + link?.source?.width / 2, link?.source.y + link?.source?.height / 2],
|
||||||
|
[link?.target?.x + link?.target?.width / 2, link?.target?.y + link?.target?.height / 2],
|
||||||
];
|
];
|
||||||
|
|
||||||
const line_generator = path();
|
const line_generator = path();
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { path } from 'd3-path';
|
import { path } from 'd3-path';
|
||||||
import { LinkStrategy } from './link-strategy';
|
|
||||||
import { MapLink } from '../../../../models/map/map-link';
|
import { MapLink } from '../../../../models/map/map-link';
|
||||||
|
import { LinkStrategy } from './link-strategy';
|
||||||
|
|
||||||
export class SerialLinkStrategy implements LinkStrategy {
|
export class SerialLinkStrategy implements LinkStrategy {
|
||||||
private linkToPoints(link: MapLink) {
|
private linkToPoints(link: MapLink) {
|
||||||
const source = {
|
const source = {
|
||||||
x: link.source.x + link.source.width / 2,
|
x: link.source.x + link.source.width / 2,
|
||||||
y: link.source.y + link.source.height / 2
|
y: link.source.y + link.source.height / 2,
|
||||||
};
|
};
|
||||||
const target = {
|
const target = {
|
||||||
x: link.target.x + link.target.width / 2,
|
x: link.target.x + link.target.width / 2,
|
||||||
y: link.target.y + link.target.height / 2
|
y: link.target.y + link.target.height / 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
const dx = target.x - source.x;
|
const dx = target.x - source.x;
|
||||||
@ -22,12 +22,12 @@ export class SerialLinkStrategy implements LinkStrategy {
|
|||||||
|
|
||||||
const angle_source: [number, number] = [
|
const angle_source: [number, number] = [
|
||||||
source.x + dx / 2.0 + 15 * vect_rot[0],
|
source.x + dx / 2.0 + 15 * vect_rot[0],
|
||||||
source.y + dy / 2.0 + 15 * vect_rot[1]
|
source.y + dy / 2.0 + 15 * vect_rot[1],
|
||||||
];
|
];
|
||||||
|
|
||||||
const angle_target: [number, number] = [
|
const angle_target: [number, number] = [
|
||||||
target.x - dx / 2.0 - 15 * vect_rot[0],
|
target.x - dx / 2.0 - 15 * vect_rot[0],
|
||||||
target.y - dy / 2.0 - 15 * vect_rot[1]
|
target.y - dy / 2.0 - 15 * vect_rot[1],
|
||||||
];
|
];
|
||||||
|
|
||||||
return [[source.x, source.y], angle_source, angle_target, [target.x, target.y]];
|
return [[source.x, source.y], angle_source, angle_target, [target.x, target.y]];
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<svg:g class="node" [attr.transform]="'translate(' + node.x + ',' + node.y + ')'">
|
<svg:g class="node" [attr.transform]="'translate(' + node?.x + ',' + node?.y + ')'">
|
||||||
<svg:image
|
<svg:image
|
||||||
#image
|
#image
|
||||||
[attr.width]="node.width"
|
[attr.width]="node?.width"
|
||||||
[attr.height]="node.height"
|
[attr.height]="node?.height"
|
||||||
[attr.x]="0"
|
[attr.x]="0"
|
||||||
[attr.y]="0"
|
[attr.y]="0"
|
||||||
[attr.xlink:href]="symbol"
|
[attr.xlink:href]="symbol"
|
||||||
@ -11,6 +11,6 @@
|
|||||||
(dragged)="OnDragged($event)"
|
(dragged)="OnDragged($event)"
|
||||||
/>
|
/>
|
||||||
<svg:text #label class="label" [attr.style]="label_style" [attr.x]="label_x" [attr.y]="label_y">
|
<svg:text #label class="label" [attr.style]="label_style" [attr.x]="label_x" [attr.y]="label_y">
|
||||||
{{ node.label.text }}
|
{{ node?.label?.text }}
|
||||||
</svg:text>
|
</svg:text>
|
||||||
</svg:g>
|
</svg:g>
|
||||||
|
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 490 B |
@ -1,16 +1,23 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { NodesEventSource } from 'app/cartography/events/nodes-event-source';
|
||||||
|
import { CssFixer } from 'app/cartography/helpers/css-fixer';
|
||||||
|
import { FontFixer } from 'app/cartography/helpers/font-fixer';
|
||||||
import { NodeComponent } from './node.component';
|
import { NodeComponent } from './node.component';
|
||||||
|
|
||||||
describe('NodeComponent', () => {
|
describe('NodeComponent', () => {
|
||||||
let component: NodeComponent;
|
let component: NodeComponent;
|
||||||
let fixture: ComponentFixture<NodeComponent>;
|
let fixture: ComponentFixture<NodeComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [NodeComponent]
|
declarations: [NodeComponent],
|
||||||
|
providers:[
|
||||||
|
CssFixer,
|
||||||
|
FontFixer,
|
||||||
|
NodesEventSource,
|
||||||
|
]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(NodeComponent);
|
fixture = TestBed.createComponent(NodeComponent);
|
||||||
@ -18,7 +25,7 @@ describe('NodeComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,37 +1,36 @@
|
|||||||
import {
|
import {
|
||||||
Component,
|
AfterViewInit,
|
||||||
OnInit,
|
|
||||||
Input,
|
|
||||||
ElementRef,
|
|
||||||
ViewChild,
|
|
||||||
ChangeDetectorRef,
|
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Output,
|
ChangeDetectorRef,
|
||||||
|
Component,
|
||||||
|
ElementRef,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
OnDestroy,
|
Input,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
AfterViewInit
|
OnDestroy,
|
||||||
|
OnInit,
|
||||||
|
ViewChild,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
|
import { Symbol } from '../../../../models/symbol';
|
||||||
|
import { DraggedDataEvent } from '../../../events/event-source';
|
||||||
|
import { NodesEventSource } from '../../../events/nodes-event-source';
|
||||||
import { CssFixer } from '../../../helpers/css-fixer';
|
import { CssFixer } from '../../../helpers/css-fixer';
|
||||||
import { FontFixer } from '../../../helpers/font-fixer';
|
import { FontFixer } from '../../../helpers/font-fixer';
|
||||||
import { Symbol } from '../../../../models/symbol';
|
|
||||||
import { MapNode } from '../../../models/map/map-node';
|
import { MapNode } from '../../../models/map/map-node';
|
||||||
import { NodesEventSource } from '../../../events/nodes-event-source';
|
|
||||||
import { DraggedDataEvent } from '../../../events/event-source';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-node]',
|
selector: '[app-node]',
|
||||||
templateUrl: './node.component.html',
|
templateUrl: './node.component.html',
|
||||||
styleUrls: ['./node.component.scss'],
|
styleUrls: ['./node.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
|
export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
|
||||||
static NODE_LABEL_MARGIN = 3;
|
static NODE_LABEL_MARGIN = 3;
|
||||||
|
|
||||||
@ViewChild('label', {static: false}) label: ElementRef;
|
@ViewChild('label') label: ElementRef;
|
||||||
@ViewChild('image', {static: false}) imageRef: ElementRef;
|
@ViewChild('image') imageRef: ElementRef;
|
||||||
|
|
||||||
@Input('app-node') node: MapNode;
|
@Input('app-node') node: MapNode;
|
||||||
@Input('symbols') symbols: Symbol[];
|
@Input('symbols') symbols: Symbol[];
|
||||||
@ -50,7 +49,7 @@ export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewIni
|
|||||||
protected element: ElementRef,
|
protected element: ElementRef,
|
||||||
private cd: ChangeDetectorRef,
|
private cd: ChangeDetectorRef,
|
||||||
private nodesEventSource: NodesEventSource
|
private nodesEventSource: NodesEventSource
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
// this.nodeChangedSubscription = this.nodeChanged.subscribe((node: Node) => {
|
// this.nodeChangedSubscription = this.nodeChanged.subscribe((node: Node) => {
|
||||||
@ -86,42 +85,52 @@ export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
get symbol(): string {
|
get symbol(): string {
|
||||||
const symbol = this.symbols.find((s: Symbol) => s.symbol_id === this.node.symbol);
|
if (this.symbols) {
|
||||||
if (symbol) {
|
const symbol = this.symbols.find((s: Symbol) => s.symbol_id === this.node.symbol);
|
||||||
return 'data:image/svg+xml;base64,' + btoa(symbol.raw);
|
if (symbol) {
|
||||||
|
return 'data:image/svg+xml;base64,' + btoa(symbol.raw);
|
||||||
|
}
|
||||||
|
// @todo; we need to have default image
|
||||||
|
return 'data:image/svg+xml;base64,none';
|
||||||
}
|
}
|
||||||
// @todo; we need to have default image
|
|
||||||
return 'data:image/svg+xml;base64,none';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get label_style() {
|
get label_style() {
|
||||||
let styles = this.cssFixer.fix(this.node.label.style);
|
if (this.node != undefined) {
|
||||||
styles = this.fontFixer.fixStyles(styles);
|
let styles = this.cssFixer.fix(this.node.label.style);
|
||||||
return this.sanitizer.bypassSecurityTrustStyle(styles);
|
styles = this.fontFixer.fixStyles(styles);
|
||||||
|
return this.sanitizer.bypassSecurityTrustStyle(styles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get label_x(): number {
|
get label_x(): number {
|
||||||
if (this.node.label.x === null) {
|
if (this.node != undefined) {
|
||||||
// center
|
if (this.node.label.x === null) {
|
||||||
const bbox = this.label.nativeElement.getBBox();
|
// center
|
||||||
|
const bbox = this.label.nativeElement.getBBox();
|
||||||
|
|
||||||
return -bbox.width / 2;
|
return -bbox.width / 2;
|
||||||
|
}
|
||||||
|
return this.node.label.x + NodeComponent.NODE_LABEL_MARGIN;
|
||||||
}
|
}
|
||||||
return this.node.label.x + NodeComponent.NODE_LABEL_MARGIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get label_y(): number {
|
get label_y(): number {
|
||||||
this.labelHeight = this.getLabelHeight();
|
this.labelHeight = this.getLabelHeight();
|
||||||
|
|
||||||
if (this.node.label.x === null) {
|
if (this.node != undefined) {
|
||||||
// center
|
if (this.node.label.x === null) {
|
||||||
return -this.node.height / 2 - this.labelHeight;
|
// center
|
||||||
|
return -this.node.height / 2 - this.labelHeight;
|
||||||
|
}
|
||||||
|
return this.node.label.y + this.labelHeight - NodeComponent.NODE_LABEL_MARGIN;
|
||||||
}
|
}
|
||||||
return this.node.label.y + this.labelHeight - NodeComponent.NODE_LABEL_MARGIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getLabelHeight() {
|
private getLabelHeight() {
|
||||||
const bbox = this.label.nativeElement.getBBox();
|
if (this.label != undefined) {
|
||||||
return bbox.height;
|
const bbox = this.label.nativeElement.getBBox();
|
||||||
|
return bbox.height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { SelectionComponent } from './selection.component';
|
import { SelectionComponent } from './selection.component';
|
||||||
|
|
||||||
describe('SelectionComponent', () => {
|
describe('SelectionComponent', () => {
|
||||||
let component: SelectionComponent;
|
let component: SelectionComponent;
|
||||||
let fixture: ComponentFixture<SelectionComponent>;
|
let fixture: ComponentFixture<SelectionComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [SelectionComponent]
|
|
||||||
}).compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [SelectionComponent],
|
||||||
|
}).compileComponents();
|
||||||
fixture = TestBed.createComponent(SelectionComponent);
|
fixture = TestBed.createComponent(SelectionComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
fixture.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
// it('should create', () => {
|
|
||||||
// expect(component).toBeTruthy();
|
it('should create', () => {
|
||||||
// });
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Component, OnInit, Input, AfterViewInit, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';
|
import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { Observable, Subscription, Subject } from 'rxjs';
|
import { Observable, Subscription} from 'rxjs';
|
||||||
import { Rectangle } from '../../../models/rectangle';
|
import { Rectangle } from '../../../models/rectangle';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-selection]',
|
selector: '[app-selection]',
|
||||||
templateUrl: './selection.component.html',
|
templateUrl: './selection.component.html',
|
||||||
styleUrls: ['./selection.component.scss']
|
styleUrls: ['./selection.component.scss'],
|
||||||
})
|
})
|
||||||
export class SelectionComponent implements OnInit, AfterViewInit {
|
export class SelectionComponent implements OnInit, AfterViewInit {
|
||||||
@Input('app-selection') svg: SVGSVGElement;
|
@Input('app-selection') svg: SVGSVGElement;
|
||||||
@ -28,15 +28,14 @@ export class SelectionComponent implements OnInit, AfterViewInit {
|
|||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
const down = Observable.fromEvent(this.svg, 'mousedown').do((e: MouseEvent) => e.preventDefault());
|
const down = Observable.fromEvent(this.svg, 'mousedown').do((e: MouseEvent) => e.preventDefault());
|
||||||
|
|
||||||
down.subscribe((e: MouseEvent) => {
|
down.subscribe((e: MouseEvent) => {
|
||||||
if (e.target !== this.svg) {
|
if (e.target !== this.svg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.started = true;
|
this.started = true;
|
||||||
this.startX = e.clientX + window.scrollX;
|
this.startX = e?.clientX + window?.scrollX;
|
||||||
this.startY = e.clientY + window.scrollY;
|
this.startY = e?.clientY + window?.scrollY;
|
||||||
this.width = 0;
|
this.width = 0;
|
||||||
this.height = 0;
|
this.height = 0;
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
@ -51,7 +50,7 @@ export class SelectionComponent implements OnInit, AfterViewInit {
|
|||||||
|
|
||||||
const scrollWindow = Observable.fromEvent(document, 'scroll').startWith({});
|
const scrollWindow = Observable.fromEvent(document, 'scroll').startWith({});
|
||||||
|
|
||||||
const move = Observable.combineLatest(mouseMove, scrollWindow);
|
const move = Observable.combineLatest([mouseMove, scrollWindow]);
|
||||||
|
|
||||||
const drag = down.mergeMap((md: MouseEvent) => {
|
const drag = down.mergeMap((md: MouseEvent) => {
|
||||||
return move
|
return move
|
||||||
@ -76,11 +75,11 @@ export class SelectionComponent implements OnInit, AfterViewInit {
|
|||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.started = false;
|
this.started = false;
|
||||||
|
|
||||||
|
|
||||||
this.width = e.clientX - this.startX + window.scrollX;
|
this.width = e.clientX - this.startX + window.scrollX;
|
||||||
this.height = e.clientY - this.startY + window.scrollY;
|
this.height = e.clientY - this.startY + window.scrollY;
|
||||||
|
|
||||||
this.ref.detectChanges();
|
this.ref.detectChanges();
|
||||||
|
|
||||||
this.selectedEvent([this.startX, this.startY], [this.width, this.height]);
|
this.selectedEvent([this.startX, this.startY], [this.width, this.height]);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { StatusComponent } from './status.component';
|
import { StatusComponent } from './status.component';
|
||||||
|
|
||||||
describe('StatusComponent', () => {
|
describe('StatusComponent', () => {
|
||||||
let component: StatusComponent;
|
let component: StatusComponent;
|
||||||
let fixture: ComponentFixture<StatusComponent>;
|
let fixture: ComponentFixture<StatusComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [StatusComponent]
|
declarations: [StatusComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(StatusComponent);
|
fixture = TestBed.createComponent(StatusComponent);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Component, ElementRef, Input, ChangeDetectorRef } from '@angular/core';
|
import { ChangeDetectorRef, Component, ElementRef, Input } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: '[app-status]',
|
selector: '[app-status]',
|
||||||
templateUrl: './status.component.html',
|
templateUrl: './status.component.html',
|
||||||
styleUrls: ['./status.component.scss']
|
styleUrls: ['./status.component.scss'],
|
||||||
})
|
})
|
||||||
export class StatusComponent {
|
export class StatusComponent {
|
||||||
static STOPPED_STATUS_RECT_WIDTH = 10;
|
static STOPPED_STATUS_RECT_WIDTH = 10;
|
||||||
@ -12,7 +12,7 @@ export class StatusComponent {
|
|||||||
status: '',
|
status: '',
|
||||||
path: null,
|
path: null,
|
||||||
direction: null,
|
direction: null,
|
||||||
d: null
|
d: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(protected element: ElementRef, private ref: ChangeDetectorRef) {}
|
constructor(protected element: ElementRef, private ref: ChangeDetectorRef) {}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
import { select } from 'd3-selection';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { LinksEventSource } from '../../events/links-event-source';
|
||||||
|
import { MapLink } from '../../models/map/map-link';
|
||||||
|
import { LinksWidget } from '../../widgets/links';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-link-editing',
|
||||||
|
templateUrl: './link-editing.component.html',
|
||||||
|
styleUrls: ['./link-editing.component.scss'],
|
||||||
|
})
|
||||||
|
export class LinkEditingComponent implements OnInit, OnDestroy {
|
||||||
|
private linkEditedSubscription: Subscription;
|
||||||
|
@Input('svg') svg: SVGSVGElement;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private linksWidget: LinksWidget,
|
||||||
|
private linksEventSource: LinksEventSource ) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
const svg = select(this.svg);
|
||||||
|
this.linkEditedSubscription = this.linksEventSource.edited.subscribe((link: MapLink) => {
|
||||||
|
this.linksWidget.redrawLink(svg, link);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.linkEditedSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,13 @@
|
|||||||
import { fakeAsync, tick } from '@angular/core/testing';
|
import { fakeAsync, tick } from '@angular/core/testing';
|
||||||
|
import { instance, mock, when } from 'ts-mockito';
|
||||||
import { SelectionControlComponent } from './selection-control.component';
|
|
||||||
import { SelectionManager } from '../../managers/selection-manager';
|
|
||||||
import { SelectionEventSource } from '../../events/selection-event-source';
|
import { SelectionEventSource } from '../../events/selection-event-source';
|
||||||
import { mock, when, instance } from 'ts-mockito';
|
|
||||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
|
||||||
import { MapNode } from '../../models/map/map-node';
|
|
||||||
import { MapLink } from '../../models/map/map-link';
|
|
||||||
import { InRectangleHelper } from '../../helpers/in-rectangle-helper';
|
import { InRectangleHelper } from '../../helpers/in-rectangle-helper';
|
||||||
|
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||||
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
|
import { MapLink } from '../../models/map/map-link';
|
||||||
|
import { MapNode } from '../../models/map/map-node';
|
||||||
import { Rectangle } from '../../models/rectangle';
|
import { Rectangle } from '../../models/rectangle';
|
||||||
|
import { SelectionControlComponent } from './selection-control.component';
|
||||||
|
|
||||||
describe('SelectionControlComponent', () => {
|
describe('SelectionControlComponent', () => {
|
||||||
let component: SelectionControlComponent;
|
let component: SelectionControlComponent;
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { SelectionEventSource } from '../../events/selection-event-source';
|
import { SelectionEventSource } from '../../events/selection-event-source';
|
||||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
|
||||||
import { InRectangleHelper } from '../../helpers/in-rectangle-helper';
|
import { InRectangleHelper } from '../../helpers/in-rectangle-helper';
|
||||||
|
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||||
import { SelectionManager } from '../../managers/selection-manager';
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
import { Rectangle } from '../../models/rectangle';
|
import { Rectangle } from '../../models/rectangle';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-selection-control',
|
selector: 'app-selection-control',
|
||||||
templateUrl: './selection-control.component.html',
|
templateUrl: './selection-control.component.html',
|
||||||
styleUrls: ['./selection-control.component.scss']
|
styleUrls: ['./selection-control.component.scss'],
|
||||||
})
|
})
|
||||||
export class SelectionControlComponent implements OnInit, OnDestroy {
|
export class SelectionControlComponent implements OnInit, OnDestroy {
|
||||||
private onSelection: Subscription;
|
private onSelection: Subscription;
|
||||||
@ -23,21 +23,21 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.onSelection = this.selectionEventSource.selected.subscribe((rectangle: Rectangle) => {
|
this.onSelection = this.selectionEventSource.selected.subscribe((rectangle: Rectangle) => {
|
||||||
const selectedNodes = this.graphDataManager.getNodes().filter(node => {
|
const selectedNodes = this.graphDataManager.getNodes().filter((node) => {
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y);
|
return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y);
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedLinks = this.graphDataManager.getLinks().filter(link => {
|
const selectedLinks = this.graphDataManager.getLinks().filter((link) => {
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y);
|
return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y);
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedDrawings = this.graphDataManager.getDrawings().filter(drawing => {
|
const selectedDrawings = this.graphDataManager.getDrawings().filter((drawing) => {
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y);
|
return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y);
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedLabels = this.graphDataManager
|
const selectedLabels = this.graphDataManager
|
||||||
.getNodes()
|
.getNodes()
|
||||||
.filter(node => {
|
.filter((node) => {
|
||||||
if (node.label === undefined) {
|
if (node.label === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -45,11 +45,11 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
|||||||
const labelY = node.y + node.label.y;
|
const labelY = node.y + node.label.y;
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, labelX, labelY);
|
return this.inRectangleHelper.inRectangle(rectangle, labelX, labelY);
|
||||||
})
|
})
|
||||||
.map(node => node.label);
|
.map((node) => node.label);
|
||||||
|
|
||||||
const selectedInterfacesLabelsSources = this.graphDataManager
|
const selectedInterfacesLabelsSources = this.graphDataManager
|
||||||
.getLinks()
|
.getLinks()
|
||||||
.filter(link => {
|
.filter((link) => {
|
||||||
if (link.source === undefined || link.nodes.length != 2 || link.nodes[0].label === undefined) {
|
if (link.source === undefined || link.nodes.length != 2 || link.nodes[0].label === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -57,11 +57,11 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
|||||||
const interfaceLabelY = link.source.y + link.nodes[0].label.y;
|
const interfaceLabelY = link.source.y + link.nodes[0].label.y;
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
||||||
})
|
})
|
||||||
.map(link => link.nodes[0]);
|
.map((link) => link.nodes[0]);
|
||||||
|
|
||||||
const selectedInterfacesLabelsTargets = this.graphDataManager
|
const selectedInterfacesLabelsTargets = this.graphDataManager
|
||||||
.getLinks()
|
.getLinks()
|
||||||
.filter(link => {
|
.filter((link) => {
|
||||||
if (link.target === undefined || link.nodes.length != 2 || link.nodes[1].label === undefined) {
|
if (link.target === undefined || link.nodes.length != 2 || link.nodes[1].label === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
|||||||
const interfaceLabelY = link.target.y + link.nodes[1].label.y;
|
const interfaceLabelY = link.target.y + link.nodes[1].label.y;
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
||||||
})
|
})
|
||||||
.map(link => link.nodes[1]);
|
.map((link) => link.nodes[1]);
|
||||||
|
|
||||||
const selectedInterfaces = [...selectedInterfacesLabelsSources, ...selectedInterfacesLabelsTargets];
|
const selectedInterfaces = [...selectedInterfacesLabelsSources, ...selectedInterfacesLabelsTargets];
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
|||||||
...selectedLinks,
|
...selectedLinks,
|
||||||
...selectedDrawings,
|
...selectedDrawings,
|
||||||
...selectedLabels,
|
...selectedLabels,
|
||||||
...selectedInterfaces
|
...selectedInterfaces,
|
||||||
];
|
];
|
||||||
|
|
||||||
this.selectionManager.setSelected(selected);
|
this.selectionManager.setSelected(selected);
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { SelectionManager } from 'app/cartography/managers/selection-manager';
|
||||||
|
import { MapChangeDetectorRef } from 'app/cartography/services/map-change-detector-ref';
|
||||||
import { SelectionSelectComponent } from './selection-select.component';
|
import { SelectionSelectComponent } from './selection-select.component';
|
||||||
|
|
||||||
describe('SelectionSelectComponent', () => {
|
describe('SelectionSelectComponent', () => {
|
||||||
let component: SelectionSelectComponent;
|
let component: SelectionSelectComponent;
|
||||||
let fixture: ComponentFixture<SelectionSelectComponent>;
|
let fixture: ComponentFixture<SelectionSelectComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [SelectionSelectComponent]
|
declarations: [SelectionSelectComponent],
|
||||||
|
providers: [MapChangeDetectorRef,SelectionManager]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(SelectionSelectComponent);
|
fixture = TestBed.createComponent(SelectionSelectComponent);
|
||||||
@ -18,7 +20,7 @@ describe('SelectionSelectComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should create', () => {
|
it('should create', () => {
|
||||||
// expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { SelectionManager } from '../../managers/selection-manager';
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
||||||
@ -6,16 +6,13 @@ import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-selection-select',
|
selector: 'app-selection-select',
|
||||||
templateUrl: './selection-select.component.html',
|
templateUrl: './selection-select.component.html',
|
||||||
styleUrls: ['./selection-select.component.scss']
|
styleUrls: ['./selection-select.component.scss'],
|
||||||
})
|
})
|
||||||
export class SelectionSelectComponent implements OnInit, OnDestroy {
|
export class SelectionSelectComponent implements OnInit, OnDestroy {
|
||||||
private onSelected: Subscription;
|
private onSelected: Subscription;
|
||||||
private onUnselected: Subscription;
|
private onUnselected: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(private selectionManager: SelectionManager, private mapChangeDetectorRef: MapChangeDetectorRef) {}
|
||||||
private selectionManager: SelectionManager,
|
|
||||||
private mapChangeDetectorRef: MapChangeDetectorRef
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.onSelected = this.selectionManager.selected.subscribe(() => {
|
this.onSelected = this.selectionManager.selected.subscribe(() => {
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import { TextEditorComponent } from './text-editor.component';
|
|
||||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
|
||||||
import { ToolsService } from '../../../services/tools.service';
|
|
||||||
import { Context } from '../../models/context';
|
|
||||||
import { Renderer2 } from '@angular/core';
|
import { Renderer2 } from '@angular/core';
|
||||||
import { MapScaleService } from '../../../services/mapScale.service';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { LinkService } from '../../../services/link.service';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { NodesDataSource } from '../../datasources/nodes-datasource';
|
|
||||||
import { LinksDataSource } from '../../datasources/links-datasource';
|
|
||||||
import { SelectionManager } from '../../managers/selection-manager';
|
|
||||||
import { FontFixer } from '../../helpers/font-fixer';
|
|
||||||
import { MockedLinkService } from '../../../components/project-map/project-map.component.spec';
|
import { MockedLinkService } from '../../../components/project-map/project-map.component.spec';
|
||||||
|
import { LinkService } from '../../../services/link.service';
|
||||||
|
import { MapScaleService } from '../../../services/mapScale.service';
|
||||||
|
import { ToolsService } from '../../../services/tools.service';
|
||||||
|
import { LinksDataSource } from '../../datasources/links-datasource';
|
||||||
|
import { NodesDataSource } from '../../datasources/nodes-datasource';
|
||||||
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
|
import { FontFixer } from '../../helpers/font-fixer';
|
||||||
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
|
import { Context } from '../../models/context';
|
||||||
|
import { TextEditorComponent } from './text-editor.component';
|
||||||
|
|
||||||
describe('TextEditorComponent', () => {
|
describe('TextEditorComponent', () => {
|
||||||
let component: TextEditorComponent;
|
let component: TextEditorComponent;
|
||||||
let fixture: ComponentFixture<TextEditorComponent>;
|
let fixture: ComponentFixture<TextEditorComponent>;
|
||||||
let mockedLinkService: MockedLinkService = new MockedLinkService();
|
let mockedLinkService: MockedLinkService = new MockedLinkService();
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
providers: [
|
providers: [
|
||||||
@ -31,11 +31,11 @@ describe('TextEditorComponent', () => {
|
|||||||
{ provide: NodesDataSource, useClass: NodesDataSource },
|
{ provide: NodesDataSource, useClass: NodesDataSource },
|
||||||
{ provide: LinksDataSource, useClass: LinksDataSource },
|
{ provide: LinksDataSource, useClass: LinksDataSource },
|
||||||
{ provide: SelectionManager, useClass: SelectionManager },
|
{ provide: SelectionManager, useClass: SelectionManager },
|
||||||
{ provide: FontFixer, useClass: FontFixer }
|
{ provide: FontFixer, useClass: FontFixer },
|
||||||
],
|
],
|
||||||
declarations: [TextEditorComponent]
|
declarations: [TextEditorComponent],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(TextEditorComponent);
|
fixture = TestBed.createComponent(TextEditorComponent);
|
||||||
|
@ -1,35 +1,43 @@
|
|||||||
import { Component, ViewChild, ElementRef, OnInit, Input, EventEmitter, OnDestroy, Renderer2, NgZone } from '@angular/core';
|
import {
|
||||||
|
Component,
|
||||||
|
ElementRef,
|
||||||
|
EventEmitter,
|
||||||
|
Input,
|
||||||
|
NgZone,
|
||||||
|
OnDestroy,
|
||||||
|
OnInit,
|
||||||
|
Renderer2,
|
||||||
|
ViewChild,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { select } from 'd3-selection';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { StyleProperty } from '../../../components/project-map/drawings-editors/text-editor/text-editor.component';
|
||||||
|
import { Link } from '../../../models/link';
|
||||||
|
import { Controller } from '../../../models/controller';
|
||||||
|
import { LinkService } from '../../../services/link.service';
|
||||||
|
import { MapScaleService } from '../../../services/mapScale.service';
|
||||||
|
import { ToolsService } from '../../../services/tools.service';
|
||||||
|
import { LinksDataSource } from '../../datasources/links-datasource';
|
||||||
|
import { NodesDataSource } from '../../datasources/nodes-datasource';
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
import { TextAddedDataEvent, TextEditedDataEvent } from '../../events/event-source';
|
import { TextAddedDataEvent, TextEditedDataEvent } from '../../events/event-source';
|
||||||
import { ToolsService } from '../../../services/tools.service';
|
|
||||||
import { select } from 'd3-selection';
|
|
||||||
import { TextElement } from '../../models/drawings/text-element';
|
|
||||||
import { Context } from '../../models/context';
|
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
import { MapScaleService } from '../../../services/mapScale.service';
|
|
||||||
import { MapLabel } from '../../models/map/map-label';
|
|
||||||
import { MapNode } from '../../models/map/map-node';
|
|
||||||
import { NodesDataSource } from '../../datasources/nodes-datasource';
|
|
||||||
import { Node } from '../../models/node';
|
|
||||||
import { SelectionManager } from '../../managers/selection-manager';
|
|
||||||
import { Server } from '../../../models/server';
|
|
||||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
|
||||||
import { LinkService } from '../../../services/link.service';
|
|
||||||
import { LinksDataSource } from '../../datasources/links-datasource';
|
|
||||||
import { Link } from '../../../models/link';
|
|
||||||
import { StyleProperty } from '../../../components/project-map/drawings-editors/text-editor/text-editor.component';
|
|
||||||
import { FontFixer } from '../../helpers/font-fixer';
|
import { FontFixer } from '../../helpers/font-fixer';
|
||||||
|
import { SelectionManager } from '../../managers/selection-manager';
|
||||||
|
import { Context } from '../../models/context';
|
||||||
|
import { TextElement } from '../../models/drawings/text-element';
|
||||||
import { Font } from '../../models/font';
|
import { Font } from '../../models/font';
|
||||||
|
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||||
|
import { Node } from '../../models/node';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-text-editor',
|
selector: 'app-text-editor',
|
||||||
templateUrl: './text-editor.component.html',
|
templateUrl: './text-editor.component.html',
|
||||||
styleUrls: ['./text-editor.component.scss']
|
styleUrls: ['./text-editor.component.scss'],
|
||||||
})
|
})
|
||||||
export class TextEditorComponent implements OnInit, OnDestroy {
|
export class TextEditorComponent implements OnInit, OnDestroy {
|
||||||
@ViewChild('temporaryTextElement', {static: false}) temporaryTextElement: ElementRef;
|
@ViewChild('temporaryTextElement') temporaryTextElement: ElementRef;
|
||||||
@Input('svg') svg: SVGSVGElement;
|
@Input('svg') svg: SVGSVGElement;
|
||||||
@Input('server') server: Server;
|
@Input('controller') controller: Controller;
|
||||||
|
|
||||||
leftPosition: string = '0px';
|
leftPosition: string = '0px';
|
||||||
topPosition: string = '0px';
|
topPosition: string = '0px';
|
||||||
@ -73,8 +81,13 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
|||||||
this.leftPosition = event.pageX.toString() + 'px';
|
this.leftPosition = event.pageX.toString() + 'px';
|
||||||
this.topPosition = event.pageY.toString() + 'px';
|
this.topPosition = event.pageY.toString() + 'px';
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'transform', `scale(${this.mapScaleService.getScale()})`);
|
this.renderer.setStyle(
|
||||||
|
this.temporaryTextElement.nativeElement,
|
||||||
|
'transform',
|
||||||
|
`scale(${this.mapScaleService.getScale()})`
|
||||||
|
);
|
||||||
this.temporaryTextElement.nativeElement.focus();
|
this.temporaryTextElement.nativeElement.focus();
|
||||||
|
document.documentElement.style.cursor = "default";
|
||||||
|
|
||||||
let textListener = () => {
|
let textListener = () => {
|
||||||
this.drawingsEventSource.textAdded.emit(
|
this.drawingsEventSource.textAdded.emit(
|
||||||
@ -113,7 +126,11 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
|||||||
this.selectionManager.setSelected([]);
|
this.selectionManager.setSelected([]);
|
||||||
|
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'transform', `scale(${this.mapScaleService.getScale()})`);
|
this.renderer.setStyle(
|
||||||
|
this.temporaryTextElement.nativeElement,
|
||||||
|
'transform',
|
||||||
|
`scale(${this.mapScaleService.getScale()})`
|
||||||
|
);
|
||||||
this.editedLink = elem;
|
this.editedLink = elem;
|
||||||
|
|
||||||
select(textElements[index]).attr('visibility', 'hidden');
|
select(textElements[index]).attr('visibility', 'hidden');
|
||||||
@ -121,36 +138,54 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this.editedNode = this.nodesDataSource.get(elem.nodeId);
|
this.editedNode = this.nodesDataSource.get(elem.nodeId);
|
||||||
this.editedLink = elem;
|
this.editedLink = elem;
|
||||||
let x = ((elem.label.originalX + this.editedNode.x - 1) * this.context.transformation.k) + this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x;
|
let x =
|
||||||
let y = ((elem.label.originalY + this.editedNode.y + 4) * this.context.transformation.k) + this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y;
|
(elem.label.originalX + this.editedNode.x - 1) * this.context.transformation.k +
|
||||||
|
this.context.getZeroZeroTransformationPoint().x +
|
||||||
|
this.context.transformation.x;
|
||||||
|
let y =
|
||||||
|
(elem.label.originalY + this.editedNode.y + 4) * this.context.transformation.k +
|
||||||
|
this.context.getZeroZeroTransformationPoint().y +
|
||||||
|
this.context.transformation.y;
|
||||||
this.leftPosition = x.toString() + 'px';
|
this.leftPosition = x.toString() + 'px';
|
||||||
this.topPosition = y.toString() + 'px';
|
this.topPosition = y.toString() + 'px';
|
||||||
this.temporaryTextElement.nativeElement.innerText = elem.label.text;
|
this.temporaryTextElement.nativeElement.innerText = elem.label.text;
|
||||||
|
|
||||||
let styleProperties: StyleProperty[] = [];
|
let styleProperties: StyleProperty[] = [];
|
||||||
for (let property of elem.label.style.split(";")){
|
for (let property of elem.label.style.split(';')) {
|
||||||
styleProperties.push({
|
styleProperties.push({
|
||||||
property: property.split(": ")[0],
|
property: property.split(': ')[0],
|
||||||
value: property.split(": ")[1]
|
value: property.split(': ')[1],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let font: Font = {
|
let font: Font = {
|
||||||
font_family: styleProperties.find(p => p.property === 'font-family') ? styleProperties.find(p => p.property === 'font-family').value : 'TypeWriter',
|
font_family: styleProperties.find((p) => p.property === 'font-family')
|
||||||
font_size: styleProperties.find(p => p.property === 'font-size') ? Number(styleProperties.find(p => p.property === 'font-size').value) : 10.0,
|
? styleProperties.find((p) => p.property === 'font-family').value
|
||||||
font_weight: styleProperties.find(p => p.property === 'font-weight') ? styleProperties.find(p => p.property === 'font-weight').value : 'normal'
|
: 'TypeWriter',
|
||||||
|
font_size: styleProperties.find((p) => p.property === 'font-size')
|
||||||
|
? Number(styleProperties.find((p) => p.property === 'font-size').value)
|
||||||
|
: 10.0,
|
||||||
|
font_weight: styleProperties.find((p) => p.property === 'font-weight')
|
||||||
|
? styleProperties.find((p) => p.property === 'font-weight').value
|
||||||
|
: 'normal',
|
||||||
};
|
};
|
||||||
font = this.fontFixer.fix(font);
|
font = this.fontFixer.fix(font);
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'color', styleProperties.find(p => p.property === 'fill') ? styleProperties.find(p => p.property === 'fill').value : '#000000');
|
this.renderer.setStyle(
|
||||||
|
this.temporaryTextElement.nativeElement,
|
||||||
|
'color',
|
||||||
|
styleProperties.find((p) => p.property === 'fill')
|
||||||
|
? styleProperties.find((p) => p.property === 'fill').value
|
||||||
|
: '#000000'
|
||||||
|
);
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-family', font.font_family);
|
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-family', font.font_family);
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-size', `${font.font_size}pt`);
|
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-size', `${font.font_size}pt`);
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-weight', font.font_weight);
|
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-weight', font.font_weight);
|
||||||
|
|
||||||
let listener = () => {
|
let listener = () => {
|
||||||
let innerText = this.temporaryTextElement.nativeElement.innerText;
|
let innerText = this.temporaryTextElement.nativeElement.innerText;
|
||||||
let link: Link = this.linksDataSource.get(this.editedLink.linkId);
|
let link: Link = this.linksDataSource.get(this.editedLink.linkId);
|
||||||
link.nodes.find(n => n.node_id === this.editedNode.node_id).label.text = innerText;
|
link.nodes.find((n) => n.node_id === this.editedNode.node_id).label.text = innerText;
|
||||||
|
|
||||||
this.linkService.updateLink(this.server, link).subscribe((link: Link) => {
|
this.linkService.updateLink(this.controller, link).subscribe((link: Link) => {
|
||||||
rootElement
|
rootElement
|
||||||
.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
||||||
.attr('visibility', 'visible')
|
.attr('visibility', 'visible')
|
||||||
@ -177,7 +212,11 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
|||||||
.selectAll<SVGTextElement, TextElement>('text.text_element')
|
.selectAll<SVGTextElement, TextElement>('text.text_element')
|
||||||
.on('dblclick', (elem, index, textElements) => {
|
.on('dblclick', (elem, index, textElements) => {
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
||||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'transform', `scale(${this.mapScaleService.getScale()})`);
|
this.renderer.setStyle(
|
||||||
|
this.temporaryTextElement.nativeElement,
|
||||||
|
'transform',
|
||||||
|
`scale(${this.mapScaleService.getScale()})`
|
||||||
|
);
|
||||||
this.editedElement = elem;
|
this.editedElement = elem;
|
||||||
|
|
||||||
select(textElements[index]).attr('visibility', 'hidden');
|
select(textElements[index]).attr('visibility', 'hidden');
|
||||||
@ -185,8 +224,14 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
this.editingDrawingId = textElements[index].parentElement.parentElement.getAttribute('drawing_id');
|
this.editingDrawingId = textElements[index].parentElement.parentElement.getAttribute('drawing_id');
|
||||||
var transformData = textElements[index].parentElement.getAttribute('transform').split(/\(|\)/);
|
var transformData = textElements[index].parentElement.getAttribute('transform').split(/\(|\)/);
|
||||||
var x = (Number(transformData[1].split(/,/)[0]) * this.context.transformation.k) + this.context.getZeroZeroTransformationPoint().x + this.context.transformation.x;
|
var x =
|
||||||
var y = (Number(transformData[1].split(/,/)[1]) * this.context.transformation.k) + this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y;
|
Number(transformData[1].split(/,/)[0]) * this.context.transformation.k +
|
||||||
|
this.context.getZeroZeroTransformationPoint().x +
|
||||||
|
this.context.transformation.x;
|
||||||
|
var y =
|
||||||
|
Number(transformData[1].split(/,/)[1]) * this.context.transformation.k +
|
||||||
|
this.context.getZeroZeroTransformationPoint().y +
|
||||||
|
this.context.transformation.y;
|
||||||
this.leftPosition = x.toString() + 'px';
|
this.leftPosition = x.toString() + 'px';
|
||||||
this.topPosition = y.toString() + 'px';
|
this.topPosition = y.toString() + 'px';
|
||||||
this.temporaryTextElement.nativeElement.innerText = elem.text;
|
this.temporaryTextElement.nativeElement.innerText = elem.text;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { Converter } from '../converter';
|
|
||||||
import { Drawing } from '../../models/drawing';
|
import { Drawing } from '../../models/drawing';
|
||||||
import { MapDrawing } from '../../models/map/map-drawing';
|
import { MapDrawing } from '../../models/map/map-drawing';
|
||||||
|
import { Converter } from '../converter';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DrawingToMapDrawingConverter implements Converter<Drawing, MapDrawing> {
|
export class DrawingToMapDrawingConverter implements Converter<Drawing, MapDrawing> {
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CssFixer } from '../../helpers/css-fixer';
|
||||||
import { Converter } from '../converter';
|
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||||
|
import { FontFixer } from '../../helpers/font-fixer';
|
||||||
import { Label } from '../../models/label';
|
import { Label } from '../../models/label';
|
||||||
import { MapLabel } from '../../models/map/map-label';
|
import { MapLabel } from '../../models/map/map-label';
|
||||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
import { Converter } from '../converter';
|
||||||
import { CssFixer } from '../../helpers/css-fixer';
|
|
||||||
import { FontFixer } from '../../helpers/font-fixer';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { Converter } from '../converter';
|
|
||||||
import { LabelToMapLabelConverter } from './label-to-map-label-converter';
|
|
||||||
import { LinkNode } from '../../../models/link-node';
|
import { LinkNode } from '../../../models/link-node';
|
||||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||||
|
import { Converter } from '../converter';
|
||||||
|
import { LabelToMapLabelConverter } from './label-to-map-label-converter';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LinkNodeToMapLinkNodeConverter implements Converter<LinkNode, MapLinkNode> {
|
export class LinkNodeToMapLinkNodeConverter implements Converter<LinkNode, MapLinkNode> {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { Converter } from '../converter';
|
|
||||||
import { LinkNodeToMapLinkNodeConverter } from './link-node-to-map-link-node-converter';
|
|
||||||
import { Link } from '../../../models/link';
|
import { Link } from '../../../models/link';
|
||||||
import { MapLink } from '../../models/map/map-link';
|
import { MapLink } from '../../models/map/map-link';
|
||||||
|
import { Converter } from '../converter';
|
||||||
|
import { LinkNodeToMapLinkNodeConverter } from './link-node-to-map-link-node-converter';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LinkToMapLinkConverter implements Converter<Link, MapLink> {
|
export class LinkToMapLinkConverter implements Converter<Link, MapLink> {
|
||||||
@ -16,8 +15,11 @@ export class LinkToMapLinkConverter implements Converter<Link, MapLink> {
|
|||||||
mapLink.captureFilePath = link.capture_file_path;
|
mapLink.captureFilePath = link.capture_file_path;
|
||||||
mapLink.capturing = link.capturing;
|
mapLink.capturing = link.capturing;
|
||||||
mapLink.filters = link.filters;
|
mapLink.filters = link.filters;
|
||||||
|
mapLink.link_style = link.link_style;
|
||||||
mapLink.linkType = link.link_type;
|
mapLink.linkType = link.link_type;
|
||||||
mapLink.nodes = link.nodes.map(linkNode => this.linkNodeToMapLinkNode.convert(linkNode, { link_id: link.link_id }));
|
mapLink.nodes = link.nodes.map((linkNode) =>
|
||||||
|
this.linkNodeToMapLinkNode.convert(linkNode, { link_id: link.link_id })
|
||||||
|
);
|
||||||
mapLink.projectId = link.project_id;
|
mapLink.projectId = link.project_id;
|
||||||
mapLink.suspend = link.suspend;
|
mapLink.suspend = link.suspend;
|
||||||
return mapLink;
|
return mapLink;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { Converter } from '../converter';
|
|
||||||
import { Drawing } from '../../models/drawing';
|
import { Drawing } from '../../models/drawing';
|
||||||
import { MapDrawing } from '../../models/map/map-drawing';
|
import { MapDrawing } from '../../models/map/map-drawing';
|
||||||
|
import { Converter } from '../converter';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MapDrawingToDrawingConverter implements Converter<MapDrawing, Drawing> {
|
export class MapDrawingToDrawingConverter implements Converter<MapDrawing, Drawing> {
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { Converter } from '../converter';
|
|
||||||
import { MapDrawing } from '../../models/map/map-drawing';
|
|
||||||
import { RectElement } from '../../models/drawings/rect-element';
|
|
||||||
import { EllipseElement } from '../../models/drawings/ellipse-element';
|
import { EllipseElement } from '../../models/drawings/ellipse-element';
|
||||||
import { LineElement } from '../../models/drawings/line-element';
|
import { LineElement } from '../../models/drawings/line-element';
|
||||||
|
import { RectElement } from '../../models/drawings/rect-element';
|
||||||
import { TextElement } from '../../models/drawings/text-element';
|
import { TextElement } from '../../models/drawings/text-element';
|
||||||
|
import { MapDrawing } from '../../models/map/map-drawing';
|
||||||
|
import { Converter } from '../converter';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MapDrawingToSvgConverter implements Converter<MapDrawing, string> {
|
export class MapDrawingToSvgConverter implements Converter<MapDrawing, string> {
|
||||||
@ -15,27 +14,13 @@ export class MapDrawingToSvgConverter implements Converter<MapDrawing, string> {
|
|||||||
let elem = ``;
|
let elem = ``;
|
||||||
|
|
||||||
if (mapDrawing.element instanceof RectElement) {
|
if (mapDrawing.element instanceof RectElement) {
|
||||||
elem = `<rect fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" height=\"${
|
elem = `${mapDrawing.element.stroke_dasharray == '' ? `<rect fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\"/>` :`<rect fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" stroke-dasharray=\"${mapDrawing.element.stroke_dasharray}\" />`}`;
|
||||||
mapDrawing.element.height
|
|
||||||
}\" width=\"${mapDrawing.element.width}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${
|
|
||||||
mapDrawing.element.stroke_width
|
|
||||||
}\" />`;
|
|
||||||
} else if (mapDrawing.element instanceof EllipseElement) {
|
} else if (mapDrawing.element instanceof EllipseElement) {
|
||||||
elem = `<ellipse fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" cx=\"${
|
elem = `${mapDrawing.element.stroke_dasharray == '' ? `<ellipse fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" cx=\"${mapDrawing.element.cx}\" cy=\"${mapDrawing.element.cy}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\"/>` :`<ellipse fill=\"${mapDrawing.element.fill}\" fill-opacity=\"${mapDrawing.element.fill_opacity}\" cx=\"${mapDrawing.element.cx}\" cy=\"${mapDrawing.element.cy}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" stroke-dasharray=\"${mapDrawing.element.stroke_dasharray}\" />`}`;
|
||||||
mapDrawing.element.cx
|
|
||||||
}\" cy=\"${mapDrawing.element.cy}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" stroke=\"${
|
|
||||||
mapDrawing.element.stroke
|
|
||||||
}\" stroke-width=\"${mapDrawing.element.stroke_width}\" />`;
|
|
||||||
} else if (mapDrawing.element instanceof LineElement) {
|
} else if (mapDrawing.element instanceof LineElement) {
|
||||||
elem = `<line stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" x1=\"${
|
elem = `<line stroke=\"${mapDrawing.element.stroke}\" stroke-width=\"${mapDrawing.element.stroke_width}\" x1=\"${mapDrawing.element.x1}\" x2=\"${mapDrawing.element.x2}\" y1=\"${mapDrawing.element.y1}\" y2=\"${mapDrawing.element.y2}\" stroke-dasharray=\"${mapDrawing.element.stroke_dasharray ?? 'none'}\" />`;
|
||||||
mapDrawing.element.x1
|
|
||||||
}\" x2=\"${mapDrawing.element.x2}\" y1=\"${mapDrawing.element.y1}\" y2=\"${mapDrawing.element.y2}\" />`;
|
|
||||||
} else if (mapDrawing.element instanceof TextElement) {
|
} else if (mapDrawing.element instanceof TextElement) {
|
||||||
elem = `<text fill=\"${mapDrawing.element.fill}\" fill-opacity=\"1.0\" font-family=\"${
|
elem = `<text fill=\"${mapDrawing.element.fill}\" fill-opacity=\"1.0\" font-family=\"${mapDrawing.element.font_family}\" font-size=\"${mapDrawing.element.font_size}\" font-weight=\"${mapDrawing.element.font_weight}\">${mapDrawing.element.text}</text>`;
|
||||||
mapDrawing.element.font_family
|
|
||||||
}\" font-size=\"${mapDrawing.element.font_size}\" font-weight=\"${mapDrawing.element.font_weight}\">${
|
|
||||||
mapDrawing.element.text
|
|
||||||
}</text>`;
|
|
||||||
} else return '';
|
} else return '';
|
||||||
|
|
||||||
return `<svg height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\">${elem}</svg>`;
|
return `<svg height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\">${elem}</svg>`;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CssFixer } from '../../helpers/css-fixer';
|
||||||
import { Converter } from '../converter';
|
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||||
|
import { FontFixer } from '../../helpers/font-fixer';
|
||||||
import { Label } from '../../models/label';
|
import { Label } from '../../models/label';
|
||||||
import { MapLabel } from '../../models/map/map-label';
|
import { MapLabel } from '../../models/map/map-label';
|
||||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
import { Converter } from '../converter';
|
||||||
import { CssFixer } from '../../helpers/css-fixer';
|
|
||||||
import { FontFixer } from '../../helpers/font-fixer';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MapLabelToLabelConverter implements Converter<MapLabel, Label> {
|
export class MapLabelToLabelConverter implements Converter<MapLabel, Label> {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { Converter } from '../converter';
|
|
||||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
|
||||||
import { MapLabelToLabelConverter } from './map-label-to-label-converter';
|
|
||||||
import { LinkNode } from '../../../models/link-node';
|
import { LinkNode } from '../../../models/link-node';
|
||||||
|
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||||
|
import { Converter } from '../converter';
|
||||||
|
import { MapLabelToLabelConverter } from './map-label-to-label-converter';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MapLinkNodeToLinkNodeConverter implements Converter<MapLinkNode, LinkNode> {
|
export class MapLinkNodeToLinkNodeConverter implements Converter<MapLinkNode, LinkNode> {
|
||||||
|