mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-24 09:11:20 +00:00
Compare commits
1316 Commits
v2019.2.0-
...
v2.2.53
Author | SHA1 | Date | |
---|---|---|---|
1a49bec3d4 | |||
64f9631946 | |||
84169a2c1e | |||
2a9ced5cbd | |||
ee5b88e19a | |||
608fcfd04e | |||
99c6502a65 | |||
28d27194be | |||
52f772676b | |||
8068751032 | |||
28f8de0da1 | |||
8cc4fb6f75 | |||
1196742e3b | |||
d398efe229 | |||
33e8fa7f5f | |||
b9833aa00b | |||
fc66124ea9 | |||
3f74a916d4 | |||
ff78754fd5 | |||
323255286b | |||
a9314b65f8 | |||
e5b3a101b8 | |||
8b2d20e8e9 | |||
26023fe884 | |||
9a2e06471c | |||
98f4ec1ce0 | |||
4d695274bb | |||
e5af89821d | |||
78b910504d | |||
93aabe0cbc | |||
27446f8d14 | |||
a026374e75 | |||
4f303921c6 | |||
dea6a5021d | |||
46c7c58402 | |||
0df3525bbf | |||
9667e2363c | |||
24ec96a2dd | |||
9844a2f88f | |||
0cdbeb98a2 | |||
dc40d3be6e | |||
2015917767 | |||
360d77d2ef | |||
75c3d8ed97 | |||
f94d59206e | |||
5b41f9789a | |||
ac84106dbc | |||
21f2267960 | |||
a9781943d5 | |||
6fc2f6f964 | |||
cd5773e58a | |||
f4bcb844dc | |||
24cf0f5623 | |||
5e02a3d757 | |||
42599dafb5 | |||
9c754f3444 | |||
6772f0cb16 | |||
2730ee6f6e | |||
de058e175b | |||
e9487c5ada | |||
035c846f85 | |||
80239229aa | |||
c12a7acb2c | |||
23bf5ad2f3 | |||
bed98624cc | |||
383c26dcef | |||
f505c101f7 | |||
ca071f79c2 | |||
20be9027fd | |||
63389812b5 | |||
6873432833 | |||
a7e3c24a27 | |||
358f50596c | |||
b61f5803fd | |||
c27f4aee57 | |||
5aa00a9f77 | |||
91075a60b1 | |||
57e590a704 | |||
8d3e571aa4 | |||
af5917b6e4 | |||
21ed977a55 | |||
f861364727 | |||
0ff4d534f4 | |||
ca408663a5 | |||
c96d66b34a | |||
896ca927f3 | |||
8253f8da38 | |||
cbb1c9ecfc | |||
1e8b6261dc | |||
f3b8a42d89 | |||
7812ff38cc | |||
d725363fe5 | |||
58d42558f7 | |||
aecbe32c6c | |||
35193043a2 | |||
7a229d8e3e | |||
ba1180786f | |||
535649f0a9 | |||
a4f7db62ba | |||
662aba4ec8 | |||
bfc72c219c | |||
997b8df598 | |||
89bff8ac30 | |||
df6248d641 | |||
cefbc3c9be | |||
de07558349 | |||
b59c528ece | |||
61334d197d | |||
d855e5cb33 | |||
b8253d365d | |||
05685af5c4 | |||
8dbaa11808 | |||
0d7020af97 | |||
58b9083c49 | |||
43213d0669 | |||
924cbe2542 | |||
d06a3efd2c | |||
e2466ca4ab | |||
1da94efe63 | |||
838480509e | |||
04c28bd40a | |||
328dd37ffe | |||
c5a692babf | |||
119afd14d2 | |||
37e6921ffb | |||
5d48ea046d | |||
4342d27d07 | |||
3394035e2e | |||
49403a5568 | |||
70e4745657 | |||
543b81c81b | |||
02562cd046 | |||
252452051a | |||
a64ff3503e | |||
318143f5a8 | |||
e029bccf18 | |||
721adacde4 | |||
4374573c60 | |||
1e7c04f93c | |||
7e172e30ba | |||
4d243f895c | |||
aeef3e74ed | |||
83d72787f4 | |||
829bfe12d7 | |||
f5b5c717b4 | |||
5b7da298d6 | |||
d7742a7c59 | |||
e0ce8c0770 | |||
061dec9d75 | |||
684a160d99 | |||
21a12c151b | |||
17be201862 | |||
57385b84f7 | |||
8e4f860b43 | |||
2c015e695d | |||
9fe2b3646b | |||
313966548f | |||
69a7cf44c5 | |||
faec4b07be | |||
908c721094 | |||
e3c4188171 | |||
f48471cdd4 | |||
50fb05aa8e | |||
63728091c1 | |||
03a417d78c | |||
c7a7a357c6 | |||
7d95267283 | |||
8a7309bde1 | |||
afccf4955b | |||
ad57a5f3f7 | |||
7407ddafd3 | |||
168de3aecb | |||
13f80cdaad | |||
28f32de0b2 | |||
a6a4fb401d | |||
f62366440c | |||
135ecbdc33 | |||
9ebbbb197b | |||
f90c074191 | |||
2d49ca30fa | |||
83f7d36e2d | |||
174053f297 | |||
0e4e124c14 | |||
c928ab0342 | |||
9efd99dccb | |||
7e43dc77cb | |||
d7752a4d7b | |||
40df0fe1ee | |||
d5bd84234d | |||
a9a7ecf3e7 | |||
5dc5a953e6 | |||
32c78450a2 | |||
82feb9aa92 | |||
a08a7e1476 | |||
b5e4972bdb | |||
dc5c0d3d94 | |||
04936cfc8d | |||
8728056b8d | |||
138d1f8552 | |||
dc31d51844 | |||
def33a353d | |||
ed3db2ea4d | |||
7ad6de2256 | |||
6dcc5cdc2e | |||
089e66a02b | |||
da848d42af | |||
6b08fb8d9a | |||
8874e7efbc | |||
2b834768c6 | |||
eabdda0e74 | |||
9e3f667767 | |||
8898141bc1 | |||
c8753ed45c | |||
d496d8dc64 | |||
a8f9b6948d | |||
ccd3ff61f1 | |||
abf9d8b387 | |||
f8cc654539 | |||
56554f6d0c | |||
7be137dc1c | |||
1b45a2284d | |||
6b4f5186d0 | |||
c3f2ebad0c | |||
249f63a97a | |||
cc6b8cd28c | |||
96928d86f8 | |||
a213a7aca1 | |||
fc1d17b921 | |||
0ddf4f6e95 | |||
8d466d655e | |||
2c7dd5f179 | |||
64999f2b72 | |||
253c65b8c1 | |||
74c1a82524 | |||
4e42bd7a54 | |||
891e65b094 | |||
c808477914 | |||
8503a17187 | |||
8afea664ff | |||
538ae8b7fb | |||
370694f3b0 | |||
5175b3beac | |||
2df1956dbc | |||
56384fbcc0 | |||
15faca6d89 | |||
4142144d4d | |||
e2e87db039 | |||
c868f08a25 | |||
9aedd410bb | |||
5fb76d7d11 | |||
a7c343aa7c | |||
cfe8c4760b | |||
7cbcc84cc1 | |||
357e478fb8 | |||
063d8c9dc7 | |||
63ecacb6b6 | |||
6cecacf611 | |||
c389404e58 | |||
b1aba60410 | |||
4cd9f77732 | |||
1619c3ec05 | |||
b33a01e225 | |||
353740376e | |||
9fe899e4df | |||
dd1f16c53d | |||
3fa52d3c9c | |||
bc5dd0271f | |||
81ca3e2af2 | |||
d7a0d2f69a | |||
8f0bbafa72 | |||
08f7456bb1 | |||
752246c629 | |||
2709d8d102 | |||
d949f536ab | |||
42d8bcebbb | |||
a153e97f55 | |||
7953a86fd9 | |||
5c426ad822 | |||
a9b7e09da4 | |||
60bae5db3c | |||
d6e5dee1aa | |||
cb101e8202 | |||
0124018b02 | |||
04fdcc6893 | |||
e54638a248 | |||
aac7b57d22 | |||
9421b4bf57 | |||
354b313eaa | |||
b048a846e0 | |||
092fe5991b | |||
1a03bb0456 | |||
a04804eaa0 | |||
8a56032291 | |||
c80dbe6baf | |||
2b17b3d627 | |||
6e9ebfb69d | |||
6faba7c4ec | |||
3f7fe0a7f3 | |||
666e39ede3 | |||
60f8685c68 | |||
ca5a8ea891 | |||
3b07b4a2db | |||
9bf2980b6b | |||
57e6200972 | |||
b692bd0f43 | |||
e37bdc6162 | |||
bb2a963237 | |||
c0cff3a6db | |||
2a96a6b601 | |||
1d5bbb58f9 | |||
d290daed11 | |||
5ba7799d8a | |||
17da822a47 | |||
748997c635 | |||
cf2f0e3110 | |||
8bfb375e02 | |||
9fd34e8253 | |||
abdd739f06 | |||
1f972d3261 | |||
42ae0b671a | |||
b51159513f | |||
12ba174dfa | |||
62c1f8b003 | |||
4261086495 | |||
1e21f672fb | |||
c8caf20234 | |||
e669e4cc47 | |||
469fa6cd23 | |||
f664165190 | |||
16d86a2322 | |||
b92c6384de | |||
ccc328f279 | |||
5f5cd8aa9e | |||
668093ffb3 | |||
644dc588b2 | |||
7c48791ae5 | |||
aac9476e26 | |||
e57350e0e5 | |||
1a853f5c36 | |||
89db5d2602 | |||
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 | |||
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 | |||
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 | |||
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 | |||
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 | |||
c33c6b8f36 | |||
4fc87c4cda | |||
34059da0f6 | |||
6a21b88a4a | |||
7ca696643f | |||
a0aa918016 | |||
0cad0ee459 | |||
2b45f7a643 | |||
ae540777a4 | |||
117e67ed33 | |||
8b332a51f5 | |||
1622d7d60a | |||
ac3335a33d | |||
b33eb4ce24 | |||
271807cd9a | |||
a83d2141f6 | |||
00ed82183c | |||
6b5051d58b | |||
51805832c3 | |||
f0aeb8df07 | |||
f6f7ceb627 | |||
c2c74f34ea | |||
ea2f5e8801 | |||
e5f0bbb07c | |||
a0043660e8 | |||
541fc18811 | |||
487eda0dee | |||
7598cfffcd | |||
04a2cd543a | |||
5c37f4dfa6 | |||
0148480d5b | |||
0d1739e63e | |||
cfdfebc2d4 | |||
1950a675cc | |||
52880ddc3e | |||
c996c1fe51 | |||
54c2af8896 | |||
851d006ef2 | |||
53b3128c66 | |||
8b2535c03d | |||
7ddc75b2ff | |||
b195bad841 | |||
1df117ba60 | |||
5f448da7d3 | |||
5abbbcdb65 | |||
f9938db312 | |||
e69b4684e7 | |||
94f690bb2f | |||
e6c9df863c | |||
ca3045d236 | |||
cf60f1a046 | |||
2e82ed8ebf | |||
36a5596d33 | |||
6ac9c94922 | |||
556f0f8ed5 | |||
8fc1505a96 | |||
82d31b8f19 | |||
b54fe1d9d1 | |||
882bc94bb6 | |||
adadf886ab | |||
135f37fa92 | |||
3c722f3baa | |||
cd111fde13 | |||
7f1d91ff1e | |||
62e0d64bf7 | |||
c73a8ddf16 | |||
f40b2c64c2 | |||
0f542c3e3b | |||
2396bef0cc | |||
156096a948 | |||
76d0f0d209 | |||
0beff5f418 | |||
6413c2fdec | |||
f7143b4d93 | |||
2e851cd6d2 | |||
d8a8af306e | |||
a1476384e6 | |||
20a86eb6bf | |||
b28f224fdd | |||
4de4471d73 | |||
875c4f3152 | |||
4d369eef30 | |||
f5ee039510 | |||
fce7241bb2 | |||
f744c02c44 | |||
e11281ddf6 | |||
b134a7fecf | |||
f49cc1960c | |||
235483dba5 | |||
4955245b9c | |||
8175c47b6f | |||
61cca78609 | |||
acc41aebe1 | |||
9835c5b4cc | |||
eab9bca34a | |||
31cffedd93 | |||
46f3b9f1f0 | |||
fd2599f4a1 | |||
0adaa88e6d | |||
7b94cb779a | |||
50c5701192 | |||
2d2738024e | |||
11baa33169 | |||
939d6d4e0a | |||
50e2c02f93 | |||
85f3172111 | |||
67aaaa8b2a | |||
5c2b773d33 | |||
3b452d746c | |||
492539460d | |||
5cf1326d1e | |||
46dbd31ec1 | |||
0820b835d7 | |||
a88fd0df76 | |||
9b239ebc85 | |||
9a4bb93add | |||
58069d4962 | |||
e965bc11e2 | |||
60f3bd6f1e | |||
a704d0dcd0 | |||
b048c308d6 | |||
d60d906043 | |||
14fcf9466d | |||
fe29be8237 | |||
bbe19e0513 | |||
8f4b2c502f | |||
f9af6e32be | |||
6870f707bf | |||
80207eda36 | |||
999921bfe4 | |||
0c8c09ef56 | |||
919e5fb44b | |||
49b669819d | |||
aefcc16b3a | |||
578038e792 | |||
5b340507e5 | |||
8b25b2fa08 | |||
4c7bf86ff0 | |||
e02311af57 | |||
7062f4b874 | |||
fbcebb9c2a | |||
5048f84e9c | |||
de3938d5e0 | |||
95d0645506 | |||
abad187ea6 | |||
2d364c3636 | |||
0782994340 | |||
8aa4a52d34 | |||
1f624e3957 | |||
b1b84efa61 | |||
84efd2d2a9 | |||
12616a6519 | |||
d37d4ebac1 | |||
91fa54cf9b | |||
58a02c7066 | |||
f8c798340e | |||
f16be0b97b | |||
9ade466b80 | |||
4b1ee170df | |||
e982c6d4c7 | |||
7eaabf0cc8 | |||
ff5d79f38f | |||
8ca4eabe22 | |||
01d2fc2d43 | |||
5db7fbc461 | |||
6986dccf6e | |||
ed9ca9ed03 | |||
fa59471dd8 | |||
1ff8f00397 | |||
f225de7467 | |||
b6d74c58cb | |||
ce97ba085d | |||
a0cace9b62 | |||
ffc3e02855 | |||
47cc51a68d | |||
fabfff2e8f | |||
bc89f796a6 | |||
ed7d67f570 | |||
1798aaf7dd | |||
00cf8a29c7 | |||
0e04e9b021 | |||
e6e518b40f | |||
6f65063477 | |||
1a531e5f6e | |||
c9c11d1031 | |||
3132136020 | |||
67e6003f47 | |||
ae414c1f60 | |||
c5515ca832 | |||
97c5c4599f | |||
a8731da525 | |||
349078a61c | |||
20b87dd330 | |||
44ce03d354 | |||
fb381370f5 | |||
146543bc87 | |||
43131547e5 | |||
50b28596ae | |||
3e8c21082b | |||
cb71af1ea3 | |||
6b327316b7 | |||
a6ed6660ca | |||
d51f024a16 | |||
3447ac4b42 | |||
830e9edc60 | |||
e80aec68fe | |||
2d588c411d | |||
0c788b9898 | |||
1762c118b6 | |||
3a10302a9b | |||
92b9163bf3 | |||
8e97a71696 | |||
3e54df0b79 | |||
0dbede58f2 | |||
0bffe1b0b0 | |||
98f93901ec | |||
ceda238507 | |||
6274c90a33 | |||
b372493e51 | |||
6b804fa525 | |||
2f1d6d80d5 | |||
128953b0fe | |||
97aa9d7413 | |||
cb7ec182d3 | |||
adb65dc50c | |||
6d81bd4a0b | |||
9a6bcad71c | |||
9c49236f1c | |||
6880c993ab | |||
9674f20941 | |||
d32e3f6b7f | |||
1db8157f1a | |||
e7973839c7 | |||
df125f87b2 | |||
b3f9a61d60 | |||
949dcb0fc1 | |||
f7a9b78833 | |||
1703075b63 | |||
fc21c0717f | |||
01f90433b0 | |||
3051368ee7 | |||
052eab0367 | |||
761e1a62ce | |||
b17fcd251b | |||
3d3983926b | |||
0659bf01fe | |||
3f1257cfe9 | |||
31d7719fee | |||
bea4d4f296 | |||
87454fd7ed | |||
3ac5bf879a | |||
8e8d5a46a5 | |||
85b60f390d | |||
c01ad75457 | |||
a60595c299 | |||
eac1662294 | |||
7576b1c81c | |||
18b037ef04 | |||
623ff89f1a | |||
b8d607b7c6 | |||
2981d6eafe | |||
ebd2614b84 | |||
3cb517743c | |||
59778da856 | |||
8def343892 | |||
8233985136 | |||
d756ce9b87 | |||
63987f5df8 | |||
efdf98b869 | |||
37c491acc6 | |||
4a180adda9 | |||
b0b2c0718e | |||
e4d977fe15 | |||
3afcac3963 | |||
864bb84270 | |||
70f7c54de0 | |||
0d89b7df11 | |||
70c9b98c3f | |||
ff5f8eddc3 | |||
14581d0d5f | |||
5e76902934 | |||
725c387bdd | |||
e7ac895b85 | |||
fb148ff534 | |||
077c94f567 | |||
20413c6d8a | |||
1a7be375a9 | |||
41c67ae6ec | |||
0ab0e7712e | |||
ce8574d64b | |||
02be6b2449 | |||
42f1f8b49a | |||
6cf670d5cf | |||
c2263336a9 | |||
26fed4cabb | |||
45653036f9 | |||
4d5ac71f0b | |||
dfa25d7b94 | |||
a242c1c66f | |||
8764a417d3 | |||
35ade675df | |||
5a82f982a9 | |||
f92894d4c2 | |||
4bb9b98154 | |||
c94c12c27a | |||
ac53a8d936 | |||
088a6c4399 | |||
c1c679593e | |||
bb11e88f13 | |||
5d8d2a3c2b | |||
68453092b2 | |||
98c079175f | |||
d594fc0a36 | |||
eba1e07a0f | |||
1b4d4d2837 | |||
258623f62e | |||
5aedd2758d | |||
170560e5f7 | |||
2d227bc05b | |||
c80a052e55 | |||
e513d7145e | |||
a75acc3747 | |||
b55d5ff59f | |||
5832d3f36e | |||
03b88da9f6 | |||
abad45814a | |||
53b85fa57f | |||
679a0d02bb | |||
a989a88dbb | |||
cdbf2e4eb2 | |||
544e77d82e | |||
716ca9d47f | |||
f678a6cdd7 | |||
d893c54362 | |||
46b5a136d9 | |||
1dddc2462c | |||
d0445daa75 | |||
f6c1454cfc | |||
8c375da67c | |||
6ac5a40009 | |||
380a45883e | |||
78767399fc | |||
041b9bc271 | |||
074b1d840e | |||
5ec9e0134a | |||
02fc46567b | |||
c8a2067847 | |||
125706dd7b | |||
6f92207847 | |||
c1099b22bb | |||
94f179c74f | |||
fb06398517 | |||
75bf2ef3de | |||
83558d0d4e | |||
a50209455c | |||
9800e3ea4c | |||
aea8010e0a | |||
36a8387ea2 | |||
4b90568b7b | |||
8fe6a3d517 | |||
41707d6724 | |||
35c96d1c90 | |||
e904454623 | |||
838359b4ac | |||
eaf74aa878 | |||
b1480670e1 | |||
24ab40bfa9 | |||
9ab7616d89 | |||
32dc9e3c07 | |||
bdf8e89dfa | |||
0fe44b2235 | |||
96e297ff6a | |||
ecce86aaf7 | |||
5e76feca5c | |||
cd5edebd98 | |||
00597accac | |||
03dbac5aba | |||
92d0908327 | |||
9344174e89 | |||
f07353943c | |||
903448f102 | |||
7450dd6731 | |||
df8e5825cc | |||
5b2eaefc01 | |||
6bca43563d | |||
2fe8cc72aa | |||
675bb04b6c | |||
a879aab519 | |||
e89a8c79f2 | |||
2fca17376a | |||
506394336b | |||
a1dcf6b8b3 | |||
998889b721 | |||
4d2d7f6180 | |||
a146dfcb40 | |||
9d9481e983 | |||
b4eff2361f | |||
583be8032a | |||
f7b113f813 | |||
b25cfa229c | |||
63bcd6f4b2 | |||
c4959b97da | |||
f257992ffc | |||
aef6d044b3 | |||
94240ee783 | |||
eca520073b | |||
26bc2df064 | |||
c2d40943ee | |||
69934fb870 | |||
40ef11edbe | |||
801b3ebfac | |||
fee26eff87 | |||
fc746f04cb | |||
e181be93c2 | |||
a25f71c523 | |||
44c924b654 | |||
8ad744213b | |||
c2d5e6fd08 | |||
554944fb51 | |||
9eca05016c | |||
92ae767a6f | |||
37aa6191ab | |||
b515f53b24 | |||
22820f6320 | |||
d8e1486692 | |||
f3bfcebcf6 | |||
b9a2879f60 | |||
cfef46e25c | |||
43e87307ba | |||
6f62f4171d | |||
032a700040 | |||
25588f5953 | |||
8163b4d709 | |||
af4ef62132 | |||
73bbc12d84 | |||
6be70591c9 | |||
0524099dce | |||
72998d87e2 | |||
672c6577e2 | |||
12f31987d4 | |||
ef0803a94a | |||
3cc062f457 | |||
3e96766daa | |||
ded882a7bc | |||
479a9e1df9 | |||
3da59f20e0 | |||
51ef91f8d3 | |||
909e197b9a | |||
8581753520 | |||
cd365798bb | |||
528842b713 | |||
1abcad72d2 | |||
cd5890ca2b | |||
85b7d0943d | |||
c0ef682e9c | |||
2f1f6b5a35 | |||
46ef26931d | |||
c70d9852f6 | |||
162806b268 | |||
c9bdfeba8f | |||
99df35282e | |||
7f30d6ddf6 | |||
668b640a9e | |||
91545e5049 | |||
6d965e5773 | |||
34a31449f3 | |||
4487ab5167 | |||
031291612f | |||
3f696a9200 | |||
9b876dd1a9 | |||
ee1b18dee1 | |||
1e346c9e72 | |||
ebbeac6e0b | |||
d94f6d3d7d | |||
e610fcd6ec | |||
8da7311fa4 | |||
649bd0f245 | |||
ee2d755eb0 | |||
07aefc6933 | |||
4ed1f3da30 | |||
6a5aca2dcd | |||
753649a321 | |||
d2271f0421 | |||
13ddddb944 | |||
dfaea6297b | |||
430107c065 | |||
d11413d10e | |||
8b5aed9597 | |||
e5817cc3fb | |||
37c43c8e1b | |||
28d05a70cf | |||
485e41c329 | |||
1b63b2082d | |||
c17bc3731c | |||
15c5203678 | |||
4d05a4269e | |||
478a09fc34 | |||
a1909c19d0 | |||
f81f3b5887 | |||
4351e93d70 | |||
1b3f2b5623 | |||
5c99ec64eb | |||
6e23aed7b9 | |||
7893858b6d | |||
0904d94019 | |||
b6404a6bdf | |||
c2bff662ec | |||
da7ecf3446 | |||
ebd24bf235 | |||
2be02a8bd0 | |||
4f33fb49f9 | |||
230aaf31fd | |||
8eafbf66c9 | |||
d37b043711 | |||
a3110e87aa | |||
fc43f98f86 | |||
6da54a290c | |||
d7b73b4653 | |||
fd6393acf7 | |||
0809759765 |
@ -14,11 +14,13 @@ init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
install:
|
||||
- ps: Install-Product node 8 x64
|
||||
- ps: Install-Product node 12 x64
|
||||
- yarn install
|
||||
|
||||
build_script:
|
||||
- cmd: set NODE_OPTIONS=--max-old-space-size=8092
|
||||
- yarn buildforelectron
|
||||
- "%PYTHON%\\python.exe -m pip install -U pip"
|
||||
- "%PYTHON%\\python.exe -m pip install -r scripts\\requirements.txt"
|
||||
- "%PYTHON%\\python.exe scripts\\build.py download -a"
|
||||
- "%PYTHON%\\python.exe scripts\\build.py build_exe -b dist/exe.gns3server -s"
|
||||
|
@ -1,12 +1,26 @@
|
||||
# iOS CircleCI 2.0 configuration file
|
||||
version: 2
|
||||
# iOS CircleCI 2.1 configuration file
|
||||
version: 2.1
|
||||
|
||||
orbs:
|
||||
node: circleci/node@4.2.0
|
||||
|
||||
jobs:
|
||||
build:
|
||||
macos:
|
||||
xcode: "9.4.0"
|
||||
xcode: "10.1.0"
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- node/install:
|
||||
install-yarn: true
|
||||
|
||||
- run:
|
||||
name: Update BREW and print configs
|
||||
command: |
|
||||
brew update
|
||||
brew analytics off
|
||||
brew --env
|
||||
brew --config
|
||||
|
||||
- run:
|
||||
name: Set timezone and check current datetime
|
||||
@ -14,6 +28,32 @@ jobs:
|
||||
sudo systemsetup -settimezone Europe/Warsaw
|
||||
echo "Today is $(date +"%Y-%m-%d %T")"
|
||||
|
||||
- run:
|
||||
name: Set ENV variables
|
||||
command: |
|
||||
echo 'export HOMEBREW_NO_AUTO_UPDATE=1' >> ~/.envs
|
||||
|
||||
- run:
|
||||
name: Install Python version 3.6.5 & readline 7.0.5
|
||||
command: |
|
||||
source ~/.envs
|
||||
curl -o /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python.rb https://raw.githubusercontent.com/Homebrew/homebrew-core/f2a764ef944b1080be64bd88dca9a1d80130c558/Formula/python.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
|
||||
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 uninstall --ignore-dependencies readline
|
||||
brew install readline
|
||||
brew info readline
|
||||
brew pin readline
|
||||
# --ignore-dependencies is used to prevent this issue: https://github.com/tensorflow/tensorflow/issues/25093
|
||||
brew install --ignore-dependencies python
|
||||
#brew link python 3.6.5_1
|
||||
brew info python
|
||||
brew pin python
|
||||
|
||||
- run:
|
||||
name: Installed python and pip version
|
||||
command: |
|
||||
@ -46,8 +86,11 @@ jobs:
|
||||
name: Building gns3server
|
||||
command: |
|
||||
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
|
||||
# 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 validate -b dist
|
||||
|
||||
@ -74,4 +117,3 @@ workflows:
|
||||
filters:
|
||||
tags:
|
||||
only: /v.*/
|
||||
|
||||
|
16
.github/workflows/add-new-issues-to-project.yml
vendored
Normal file
16
.github/workflows/add-new-issues-to-project.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
name: Add new issues to GNS3 project
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
|
||||
jobs:
|
||||
add-to-project:
|
||||
name: Add issue to project
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/add-to-project@v0.4.0
|
||||
with:
|
||||
project-url: https://github.com/orgs/GNS3/projects/3
|
||||
github-token: ${{ secrets.ADD_NEW_ISSUES_TO_PROJECT }}
|
76
.github/workflows/codeql.yml
vendored
Normal file
76
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master", "master-3.0" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "master", "master-3.0" ]
|
||||
schedule:
|
||||
- cron: '38 18 * * 6'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript', 'python' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
25
.github/workflows/main.yml
vendored
Normal file
25
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
name: Build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- master-3.0
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup node 14
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14.x
|
||||
- uses: c-hive/gha-yarn-cache@v1
|
||||
- name: Install JS dependencies
|
||||
run: yarn install
|
||||
- name: Test
|
||||
run: yarn test
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/.angular
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
|
8
.snyk
Normal file
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'
|
@ -1,7 +1,7 @@
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- '10' # use node for latest
|
||||
- '11' # use node for latest
|
||||
|
||||
# Issue with Travis: https://github.com/travis-ci/travis-ci/issues/8836#issuecomment-356362524
|
||||
sudo: required
|
||||
@ -37,12 +37,12 @@ before_install:
|
||||
before_script:
|
||||
# greenkeeper-lockfile support
|
||||
- greenkeeper-lockfile-update
|
||||
- npm install -g codecov
|
||||
# - npm install -g codecov
|
||||
|
||||
script: yarn coverage
|
||||
|
||||
after_success:
|
||||
- codecov
|
||||
# - codecov
|
||||
|
||||
after_script:
|
||||
# greenkeeper-lockfile support
|
||||
|
14
.whitesource
Normal file
14
.whitesource
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"scanSettings": {
|
||||
"configMode": "AUTO",
|
||||
"configExternalURL": "",
|
||||
"projectToken" : "",
|
||||
"baseBranches": ["master", "master-3.0"]
|
||||
},
|
||||
"checkRunSettings": {
|
||||
"vulnerableCheckRunConclusionLevel": "failure"
|
||||
},
|
||||
"issueSettings": {
|
||||
"minSeverityLevel": "LOW"
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
# Dockerfile for GNS3 Web-ui development
|
||||
FROM node:carbon
|
||||
FROM node:stretch
|
||||
|
||||
# Create user
|
||||
RUN useradd --user-group --create-home --shell /bin/false gns3-web-ui
|
||||
|
27
README.md
27
README.md
@ -1,16 +1,9 @@
|
||||
# gns3-web-ui
|
||||
|
||||
[](https://greenkeeper.io/)
|
||||
[](https://travis-ci.org)
|
||||
[](https://www.appveyor.com/)
|
||||
[](https://circleci.com/gh/GNS3/gns3-web-ui/tree/master.png)
|
||||
[](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.
|
||||
|
||||
[](https://github.com/GNS3/gns3-web-ui/actions/workflows/main.yml)
|
||||
[](https://libraries.io/github/GNS3/gns3-web-ui)
|
||||
[](https://repology.org/metapackage/gns3/versions)
|
||||
[](https://repology.org/metapackage/gns3/versions)
|
||||
|
||||
## Demo
|
||||
|
||||
@ -30,6 +23,14 @@ We're using [yarn](https://yarnpkg.com/lang/en/) for packages installation:
|
||||
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
|
||||
|
||||
Visit [gns3-server](https://github.com/GNS3/gns3-server) for guide how to run GNS3 server.
|
||||
@ -79,6 +80,10 @@ Run `yarn ng test` to execute the unit tests via [Karma](https://karma-runner.gi
|
||||
|
||||
## Releasing
|
||||
|
||||
### Release naming convention
|
||||
|
||||
Releases are named by the year and quarter when release is happening, e.g. January 2020 release is named 2020.1.X.
|
||||
|
||||
### Bumping releases
|
||||
|
||||
We're using [version-bump-prompt](https://www.npmjs.com/package/version-bump-prompt) for increasing version.
|
||||
|
5
SECURITY.md
Normal file
5
SECURITY.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please use GitHub's report a vulnerability feature. More information can be found in https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability
|
438
angular.json
438
angular.json
@ -1,197 +1,247 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"gns3-web-ui": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico",
|
||||
"src/ReleaseNotes.txt"
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"gns3-web-ui": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"allowedCommonJsDependencies": [
|
||||
"rxjs",
|
||||
"rxjs-compat",
|
||||
"uuid",
|
||||
"css-tree",
|
||||
"save-svg-as-png",
|
||||
"angular-draggable-droppable",
|
||||
"dom-set",
|
||||
"dom-plane",
|
||||
"mousetrap",
|
||||
"@mattlewis92/dom-autoscroller",
|
||||
"rxjs/Rx",
|
||||
"rxjs/add/operator/map",
|
||||
"rxjs-compat/add/operator/map",
|
||||
"classnames",
|
||||
"stylenames",
|
||||
"ipaddr.js"
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
||||
"src/styles.css",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": {
|
||||
"hidden": true,
|
||||
"scripts": true,
|
||||
"styles": false
|
||||
},
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
},
|
||||
"electronProd": {
|
||||
"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.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": {
|
||||
"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.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": {
|
||||
"root": "e2e",
|
||||
"sourceRoot": "e2e",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "./protractor.conf.js",
|
||||
"devServerTarget": "gns3-web-ui:serve"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"e2e/tsconfig.e2e.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "gns3-web-ui",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"prefix": "app",
|
||||
"styleext": "scss"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"prefix": "app"
|
||||
}
|
||||
}
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico",
|
||||
"src/ReleaseNotes.txt"
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||
"node_modules/notosans-fontface/css/notosans-fontface.min.css",
|
||||
"src/styles.scss",
|
||||
"src/theme.scss"
|
||||
],
|
||||
"scripts": [],
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"buildOptimizer": true,
|
||||
"sourceMap": true,
|
||||
"optimization": false,
|
||||
"namedChunks": true,
|
||||
"aot": true
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gns3-web-ui-e2e": {
|
||||
"root": "e2e",
|
||||
"sourceRoot": "e2e",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "./protractor.conf.js",
|
||||
"devServerTarget": "gns3-web-ui:serve"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"e2e/tsconfig.e2e.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "gns3-web-ui",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"prefix": "app",
|
||||
"style": "scss"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"prefix": "app"
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
const { spawn } = require('child_process');
|
||||
const { app } = require('electron');
|
||||
const shell = require('node-powershell');
|
||||
const path = require('path');
|
||||
|
||||
async function setPATHEnv() {
|
||||
@ -30,50 +29,21 @@ exports.openConsole = async (consoleRequest) => {
|
||||
|
||||
console.log(`Starting console with command: '${command}'`);
|
||||
|
||||
//with node-powershell
|
||||
let consoleProcess = spawn(command, [], {
|
||||
shell :true
|
||||
});
|
||||
|
||||
var ps = new shell();
|
||||
ps.addCommand(command);
|
||||
ps.invoke()
|
||||
.then((output) => {
|
||||
console.log(output)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
ps.dispose()
|
||||
});
|
||||
consoleProcess.stdout.on('data', (data) => {
|
||||
console.log(`Console stdout is producing: ${data.toString()}`);
|
||||
});
|
||||
|
||||
//with exec
|
||||
consoleProcess.stderr.on('data', (data) => {
|
||||
console.log(`Console stderr is producing: ${data.toString()}`);
|
||||
});
|
||||
|
||||
// var exec = require('child_process').exec;
|
||||
// function Callback(err, stdout, stderr) {
|
||||
// if (err) {
|
||||
// console.log(`exec error: ${err}`);
|
||||
// return;
|
||||
// }else{
|
||||
// console.log(`${stdout}`);
|
||||
// }
|
||||
// }
|
||||
|
||||
// res = exec(command, Callback);
|
||||
|
||||
//with spawn
|
||||
|
||||
// let consoleProcess = spawn('cmd.exe dir', [], {
|
||||
// shell :true
|
||||
// });
|
||||
|
||||
// consoleProcess.stdout.on('data', (data) => {
|
||||
// console.log(`Console stdout is producing: ${data.toString()}`);
|
||||
// });
|
||||
|
||||
// consoleProcess.stderr.on('data', (data) => {
|
||||
// console.log(`Console stderr is producing: ${data.toString()}`);
|
||||
// });
|
||||
|
||||
// consoleProcess.on('close', (code) => {
|
||||
// console.log(`child process exited with code ${code}`);
|
||||
// });
|
||||
consoleProcess.on('close', (code) => {
|
||||
console.log(`child process exited with code ${code}`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
1
debug.log
Normal file
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)
|
@ -1,14 +1,20 @@
|
||||
import { Gns3WebUiPage } from './app.po';
|
||||
|
||||
describe('gns3-web-ui App', () => {
|
||||
describe('GNS3 Web UI Application', () => {
|
||||
let page: Gns3WebUiPage;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new Gns3WebUiPage();
|
||||
});
|
||||
|
||||
it('should display title', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getTitleText()).toEqual('GNS3 Web UI');
|
||||
it('should have correct page title', async () => {
|
||||
// arrange
|
||||
await page.navigateTo();
|
||||
|
||||
// act
|
||||
let text = await page.getTitleText();
|
||||
|
||||
// assert
|
||||
expect(text).toEqual('GNS3 Web UI');
|
||||
});
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ export class Gns3WebUiPage {
|
||||
}
|
||||
|
||||
getTitleText() {
|
||||
return browser.getTitle();
|
||||
return browser.driver.getTitle();
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
|
21
e2e/helpers/common.po.ts
Normal file
21
e2e/helpers/common.po.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { browser } from 'protractor';
|
||||
|
||||
export class TestHelper {
|
||||
sleep(value: number) {
|
||||
browser.sleep(value);
|
||||
}
|
||||
|
||||
waitForLoading() {
|
||||
browser.waitForAngular();
|
||||
}
|
||||
|
||||
async asyncForEach(array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array);
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentUrl() {
|
||||
return browser.getCurrentUrl();
|
||||
}
|
||||
}
|
50
e2e/helpers/project-map.po.ts
Normal file
50
e2e/helpers/project-map.po.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { browser, by } from 'protractor';
|
||||
import { TestHelper } from './common.po';
|
||||
|
||||
export class ProjectMapPage {
|
||||
helper = new TestHelper();
|
||||
|
||||
async openAddProjectDialog() {
|
||||
let addButton = await browser.driver.findElement(by.css('button.addNode'));
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
20
e2e/helpers/project.po.ts
Normal file
20
e2e/helpers/project.po.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { browser, by } from 'protractor';
|
||||
import { TestHelper } from './common.po';
|
||||
|
||||
export class ProjectsPage {
|
||||
helper = new TestHelper();
|
||||
|
||||
async openAddProjectDialog() {
|
||||
let addButton = await browser.driver.findElement(by.css('button.add-button'));
|
||||
await addButton.click();
|
||||
}
|
||||
|
||||
async createProject() {
|
||||
let today = new Date();
|
||||
let inputs = await browser.driver.findElements(by.css('input.mat-input-element'));
|
||||
await inputs[1].sendKeys('test project ' + today.getUTCMilliseconds());
|
||||
this.helper.sleep(2000);
|
||||
let dialogButton = await browser.driver.findElement(by.css('button.add-project-button'));
|
||||
await dialogButton.click();
|
||||
}
|
||||
}
|
41
e2e/helpers/server.po.ts
Normal file
41
e2e/helpers/server.po.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { browser, by } 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();
|
||||
}
|
||||
}
|
40
e2e/project-map.e2e-spec.ts
Normal file
40
e2e/project-map.e2e-spec.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { TestHelper } from './helpers/common.po';
|
||||
import { ProjectMapPage } from './helpers/project-map.po';
|
||||
import { ProjectsPage } from './helpers/project.po';
|
||||
import { ServersPage } from './helpers/server.po';
|
||||
|
||||
describe('Project map page', () => {
|
||||
let serversPage: ServersPage;
|
||||
let projectsPage: ProjectsPage;
|
||||
let projectMapPage: ProjectMapPage;
|
||||
let helper: TestHelper;
|
||||
|
||||
beforeEach(async () => {
|
||||
serversPage = new ServersPage();
|
||||
projectsPage = new ProjectsPage();
|
||||
projectMapPage = new ProjectMapPage();
|
||||
helper = new TestHelper();
|
||||
|
||||
serversPage.maximizeWindow();
|
||||
await serversPage.navigateToServersPage();
|
||||
await serversPage.clickAddServer();
|
||||
await serversPage.navigateToServerProjects();
|
||||
await projectsPage.openAddProjectDialog();
|
||||
helper.sleep(2000);
|
||||
await projectsPage.createProject();
|
||||
helper.sleep(2000);
|
||||
});
|
||||
|
||||
it('user should have possibility to add nodes to map', async () => {
|
||||
// arrange
|
||||
projectMapPage.openAddProjectDialog();
|
||||
helper.sleep(2000);
|
||||
|
||||
//act
|
||||
projectMapPage.addNode();
|
||||
helper.sleep(2000);
|
||||
|
||||
//assert
|
||||
expect(await projectMapPage.verifyIfNodeWithLabelExists('PC1')).toBe(true);
|
||||
});
|
||||
});
|
33
e2e/projects.e2e-spec.ts
Normal file
33
e2e/projects.e2e-spec.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { TestHelper } from './helpers/common.po';
|
||||
import { ProjectsPage } from './helpers/project.po';
|
||||
import { ServersPage } from './helpers/server.po';
|
||||
|
||||
describe('Projects page', () => {
|
||||
let serversPage: ServersPage;
|
||||
let projectsPage: ProjectsPage;
|
||||
let helper: TestHelper;
|
||||
|
||||
beforeEach(() => {
|
||||
serversPage = new ServersPage();
|
||||
projectsPage = new ProjectsPage();
|
||||
helper = new TestHelper();
|
||||
});
|
||||
|
||||
it('user should have possibility to create new project', async () => {
|
||||
// arrange
|
||||
serversPage.maximizeWindow();
|
||||
await serversPage.navigateToServersPage();
|
||||
await serversPage.clickAddServer();
|
||||
await serversPage.navigateToServerProjects();
|
||||
helper.sleep(2000);
|
||||
|
||||
//act
|
||||
await projectsPage.openAddProjectDialog();
|
||||
helper.sleep(2000);
|
||||
await projectsPage.createProject();
|
||||
helper.sleep(2000);
|
||||
|
||||
//assert
|
||||
expect(helper.getCurrentUrl()).toMatch('server/1/project/');
|
||||
});
|
||||
});
|
43
e2e/servers.e2e-spec.ts
Normal file
43
e2e/servers.e2e-spec.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { TestHelper } from './helpers/common.po';
|
||||
import { ServersPage } from './helpers/server.po';
|
||||
|
||||
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": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"baseUrl": "./",
|
||||
|
@ -26,6 +26,6 @@ module.exports = function (config) {
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false
|
||||
singleRun: true
|
||||
});
|
||||
};
|
||||
|
156
package.json
156
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gns3-web-ui",
|
||||
"version": "2019.2.0-alpha.6dev",
|
||||
"version": "2.2.53",
|
||||
"author": {
|
||||
"name": "GNS3 Technology Inc.",
|
||||
"email": "developers@gns3.com"
|
||||
@ -17,6 +17,7 @@
|
||||
"start": "ng serve",
|
||||
"startforelectron": "ng serve --configuration=electronDev",
|
||||
"build": "ng build",
|
||||
"buildforproduction": "ng build --source-map=false --build-optimizer --configuration=production --base-href /static/web-ui/",
|
||||
"buildforelectron": "ng build --configuration=electronProd",
|
||||
"buildforgithub": "ng build --configuration=githubProd",
|
||||
"test": "ng test",
|
||||
@ -34,83 +35,104 @@
|
||||
"prettier:write": "yarn prettier:base -- --write \"src/**/*.{ts,js,html,scss}\"",
|
||||
"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",
|
||||
"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 && ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points",
|
||||
"snyk-protect": "snyk protect",
|
||||
"prepare": "yarn run snyk-protect"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^7.2.14",
|
||||
"@angular/cdk": "^7.3.7",
|
||||
"@angular/common": "^7.2.14",
|
||||
"@angular/compiler": "^7.2.14",
|
||||
"@angular/core": "^7.2.14",
|
||||
"@angular/forms": "^7.2.14",
|
||||
"@angular/http": "^7.2.14",
|
||||
"@angular/material": "^7.3.7",
|
||||
"@angular/platform-browser": "^7.2.14",
|
||||
"@angular/platform-browser-dynamic": "^7.2.14",
|
||||
"@angular/router": "^7.2.14",
|
||||
"angular-persistence": "^1.0.1",
|
||||
"angular2-hotkeys": "^2.1.4",
|
||||
"angular2-indexeddb": "^1.2.3",
|
||||
"bootstrap": "4.3.1",
|
||||
"command-exists": "^1.2.8",
|
||||
"core-js": "^3.0.1",
|
||||
"css-tree": "^1.0.0-alpha.29",
|
||||
"d3-ng2-service": "^2.1.0",
|
||||
"hammerjs": "^2.0.8",
|
||||
"ini": "^1.3.5",
|
||||
"@angular/animations": "^12.2.12",
|
||||
"@angular/cdk": "^12.2.12",
|
||||
"@angular/common": "^12.2.12",
|
||||
"@angular/compiler": "^12.2.12",
|
||||
"@angular/core": "^12.2.12",
|
||||
"@angular/forms": "^12.2.12",
|
||||
"@angular/material": "^12.2.12",
|
||||
"@angular/platform-browser": "^12.2.12",
|
||||
"@angular/platform-browser-dynamic": "^12.2.12",
|
||||
"@angular/router": "^12.2.12",
|
||||
"@sentry/browser": "^6.14.1",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/react": "^17.0.34",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"angular-draggable-droppable": "^5.0.0",
|
||||
"angular-resizable-element": "^3.4.0",
|
||||
"bootstrap": "^5.1.3",
|
||||
"command-exists": "^1.2.9",
|
||||
"core-js": "^3.19.1",
|
||||
"css-tree": "^1.1.3",
|
||||
"d3-ng2-service": "^2.2.0",
|
||||
"eev": "^0.1.5",
|
||||
"ini": "^2.0.0",
|
||||
"ipaddr.js": "^2.1.0",
|
||||
"material-design-icons": "^3.0.1",
|
||||
"ng2-file-upload": "^1.3.0",
|
||||
"ngx-electron": "^2.1.1",
|
||||
"node-fetch": "^2.4.1",
|
||||
"node-powershell": "^4.0.0",
|
||||
"notosans-fontface": "^1.1.0",
|
||||
"raven-js": "^3.27.0",
|
||||
"rxjs": "^6.5.1",
|
||||
"rxjs-compat": "^6.5.1",
|
||||
"tree-kill": "^1.2.1",
|
||||
"typeface-roboto": "^0.0.54",
|
||||
"xterm": "^3.14.5",
|
||||
"yargs": "^13.2.2",
|
||||
"zone.js": "^0.9.0"
|
||||
"mousetrap": "^1.6.5",
|
||||
"ng-circle-progress": "^1.6.0",
|
||||
"ng2-file-upload": "^1.4.0",
|
||||
"ngx-childprocess": "^0.0.6",
|
||||
"ngx-device-detector": "^2.1.1",
|
||||
"ngx-electron": "^2.2.0",
|
||||
"node-fetch": "^3.2.10",
|
||||
"notosans-fontface": "1.2.2",
|
||||
"prettier-plugin-organize-imports": "^2.3.4",
|
||||
"rxjs": "^6.6.7",
|
||||
"rxjs-compat": "^6.6.7",
|
||||
"save-svg-as-png": "^1.4.17",
|
||||
"snyk": "^1.1064.0",
|
||||
"spark-md5": "^3.0.2",
|
||||
"svg-crowbar": "^0.7.0",
|
||||
"tree-kill": "^1.2.2",
|
||||
"tslib": "^2.3.1",
|
||||
"typeface-roboto": "^1.1.13",
|
||||
"xterm": "^4.15.0",
|
||||
"xterm-addon-attach": "^0.6.0",
|
||||
"xterm-addon-fit": "^0.5.0",
|
||||
"yargs": "^17.2.1",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.13.8",
|
||||
"@angular/cli": "^7.3.8",
|
||||
"@angular/compiler-cli": "^7.2.14",
|
||||
"@angular/language-service": "^7.2.14",
|
||||
"@sentry/cli": "^1.41.2",
|
||||
"@sentry/electron": "^0.17.1",
|
||||
"@types/jasmine": "~3.3.12",
|
||||
"@types/jasminewd2": "~2.0.6",
|
||||
"@types/node": "~12.0.0",
|
||||
"codelyzer": "~5.0.1",
|
||||
"electron": "5.0.2",
|
||||
"electron-builder": "20.39.0",
|
||||
"jasmine-core": "~3.4.0",
|
||||
"jasmine-spec-reporter": "~4.2.1",
|
||||
"jquery": "^3.4.0",
|
||||
"karma": "~4.1.0",
|
||||
"karma-chrome-launcher": "~2.2.0",
|
||||
"karma-cli": "~2.0.0",
|
||||
"karma-coverage-istanbul-reporter": "^2.0.5",
|
||||
"karma-jasmine": "~2.0.1",
|
||||
"karma-jasmine-html-reporter": "^1.4.2",
|
||||
"@angular-devkit/build-angular": "^12.2.12",
|
||||
"@angular/cli": "^12.2.12",
|
||||
"@angular/compiler-cli": "^12.2.12",
|
||||
"@angular/language-service": "^12.2.12",
|
||||
"@sentry/cli": "^1.71.0",
|
||||
"@sentry/electron": "^2.5.4",
|
||||
"@types/jasmine": "^3.10.2",
|
||||
"@types/jasminewd2": "^2.0.10",
|
||||
"@types/node": "16.11.6",
|
||||
"codelyzer": "^6.0.2",
|
||||
"electron": "^13.6.6",
|
||||
"electron-builder": "^22.9.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"jasmine-core": "~3.10.1",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"jquery": "^3.6.0",
|
||||
"karma": "^6.3.16",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-cli": "^2.0.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.3",
|
||||
"karma-jasmine": "~4.0.1",
|
||||
"karma-jasmine-html-reporter": "^1.7.0",
|
||||
"license-checker": "^25.0.1",
|
||||
"node-sass": "^4.12.0",
|
||||
"popper.js": "^1.15.0",
|
||||
"prettier": "^1.17.0",
|
||||
"protractor": "~5.4.2",
|
||||
"replace": "^1.1.0",
|
||||
"ts-mockito": "^2.3.1",
|
||||
"ts-node": "~8.1.0",
|
||||
"tslint": "~5.16.0",
|
||||
"popper.js": "^1.16.1",
|
||||
"prettier": "^2.4.1",
|
||||
"protractor": "^7.0.0",
|
||||
"replace": "^1.2.1",
|
||||
"rxjs-tslint": "^0.1.8",
|
||||
"ts-mockito": "^2.6.1",
|
||||
"ts-node": "~10.4.0",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"typescript": "<3.3.0"
|
||||
"typescript": "4.2.3",
|
||||
"webpack": "5.76.0",
|
||||
"yarn-upgrade-all": "^0.5.4"
|
||||
},
|
||||
"greenkeeper": {
|
||||
"ignore": [
|
||||
"typescript"
|
||||
]
|
||||
}
|
||||
},
|
||||
"snyk": true
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ def download_from_github(name, definition, output_directory):
|
||||
files = []
|
||||
if platform.system() == "Windows":
|
||||
files = definition['files']['windows']
|
||||
|
||||
|
||||
for filename in files:
|
||||
dependency_file = os.path.join(dependency_dir, filename)
|
||||
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 = []
|
||||
if platform.system() == "Windows":
|
||||
files = definition['files']['windows']
|
||||
|
||||
|
||||
for filename in files:
|
||||
dependency_file = os.path.join(dependency_dir, filename)
|
||||
download(url, dependency_file)
|
||||
@ -193,7 +193,7 @@ def is_tagged():
|
||||
return True
|
||||
if os.environ.get('APPVEYOR_REPO_TAG', False) in (1, "True", "true"):
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def is_web_ui_non_dev():
|
||||
package_file = os.path.join(FILE_DIR, '..', 'package.json')
|
||||
@ -237,6 +237,8 @@ def download_command(arguments):
|
||||
|
||||
if platform.system() == "Windows":
|
||||
requirements = 'win-requirements.txt'
|
||||
elif platform.system() == "Darwin":
|
||||
requirements = 'mac-requirements.txt'
|
||||
else:
|
||||
requirements = 'requirements.txt'
|
||||
|
||||
@ -277,13 +279,11 @@ def build_command(arguments):
|
||||
]
|
||||
|
||||
excludes = [
|
||||
"raven.deprecation", # reported problem in raven package (6.4.0)
|
||||
"distutils", # issue on macOS
|
||||
"tkinter", # issue on Windows
|
||||
]
|
||||
|
||||
packages = [
|
||||
"raven",
|
||||
"psutil",
|
||||
"asyncio",
|
||||
"packaging", # needed for linux
|
||||
|
@ -1,7 +1,6 @@
|
||||
setuptools==40.8.0
|
||||
setuptools==71.1.0
|
||||
cx_Freeze==5.1.1
|
||||
requests==2.21.0
|
||||
packaging==19.0
|
||||
appdirs==1.4.3
|
||||
psutil==5.5.1
|
||||
jsonschema==2.6.0 # lock down jsonschema, 3.0 makes problems
|
||||
requests==2.32.3
|
||||
packaging==20.9
|
||||
appdirs==1.4.4
|
||||
psutil==5.8.0
|
||||
|
@ -1,16 +1,180 @@
|
||||
GNS3 WebUI is web implementation of user interface for GNS3 software.
|
||||
|
||||
Current version: 2019.2.0
|
||||
Current version: 2.2.32
|
||||
|
||||
What's New
|
||||
- Help section added with information about third party components
|
||||
- Showing progress when server starting
|
||||
- Possibility to edit interface & node labels by using context menu
|
||||
- Enhancements in moving elements on map
|
||||
- Context menu extended with option to duplicate
|
||||
- Main menu extended with option to lock all items on map
|
||||
Bug Fixes & enhancements
|
||||
- Fixed generated capture file is not valid
|
||||
- Fixed Docker additional directories
|
||||
|
||||
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
|
||||
- Removing issues with positioning interface labels while adding link between nodes on map
|
||||
|
||||
- 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
|
||||
- Server 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
|
||||
- Support for suspended status added
|
||||
- Suport for 404 page
|
||||
- Actions for group of nodes added
|
||||
- Updating packages
|
||||
- Button to close project added
|
||||
- Opening ads in new window
|
||||
- New dialog for adding nodes
|
||||
- Option to import config
|
||||
- Support for light theme added
|
||||
|
||||
Bug Fixes
|
||||
- Fix for navigating to project that doesn't exist
|
||||
- Fix for AdButler errors
|
||||
- Fix for screenshot issue
|
||||
- Proper centering of icons
|
||||
- Fix for adding custom symbols
|
||||
- Fix for return command in console
|
||||
- Fix for deleting links
|
||||
- Fix for duplicating any node type
|
||||
- Fix for console errors on servers page
|
||||
- Fix for console errors on projects page
|
||||
|
||||
GNS3 Web UI 2019.2.0 v10
|
||||
|
||||
What's New
|
||||
- Qemu image configurator
|
||||
- Custom console for particular node
|
||||
- Option to connect console to all nodes
|
||||
- Option to start Winpcap
|
||||
- Filtering devices with packet filters on topology summary
|
||||
- Filtering devices with captures on topology summary
|
||||
- View options taken from map configuration
|
||||
- Servers summary widget
|
||||
- Ability to lock single item on the map
|
||||
- Editing & import & export config files
|
||||
- Context menu for inserted drawings
|
||||
- Ability to drag topology summary & servers summary & console widgets
|
||||
- Ability to resize topology summary & servers summary & console widgets
|
||||
- Option to show the grid
|
||||
- Option to snap to grid
|
||||
- Usage instructions available from context menu
|
||||
- Errors & warnings visible as notifications
|
||||
- Fit in view options
|
||||
- Support for global variables
|
||||
- Support for layers
|
||||
- Extending template preferences
|
||||
|
||||
Bug Fixes
|
||||
- Input validation in styles editor
|
||||
- Fix for saving map as image
|
||||
- Removing errors with uncorrect subscriptions
|
||||
|
||||
GNS3 Web UI 2019.2.0 v9
|
||||
|
||||
What's New
|
||||
- Editing interface labels on double click
|
||||
- Support for keyboard shortcuts
|
||||
- Menu extended with option to delete currently opened project, export & import project
|
||||
- Possibility to save current state of project
|
||||
- Ability to duplicate project from projects page
|
||||
- Node information dialog available from context menu
|
||||
- Topology summary widget on map view
|
||||
- Improvements in dialog styles
|
||||
|
||||
Bug Fixes
|
||||
- Removing issues with opening console
|
||||
- Context menu now is correctly placed
|
||||
- Entered text in text & style editor is now validated
|
||||
- Text validation in dialogs
|
||||
- Removing errors with creating WebSockets
|
||||
|
@ -1,58 +1,58 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { ProjectMapComponent } from './components/project-map/project-map.component';
|
||||
import { ServersComponent } from './components/servers/servers.component';
|
||||
import { ProjectsComponent } from './components/projects/projects.component';
|
||||
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
||||
import { SettingsComponent } from './components/settings/settings.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 { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
||||
import { HelpComponent } from './components/help/help.component';
|
||||
import { InstalledSoftwareComponent } from './components/installed-software/installed-software.component';
|
||||
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.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 { 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 { 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 { 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 { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.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 { 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 { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.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 { 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 { ServersComponent } from './components/servers/servers.component';
|
||||
import { ConsoleComponent } from './components/settings/console/console.component';
|
||||
import { HelpComponent } from './components/help/help.component';
|
||||
import { SettingsComponent } from './components/settings/settings.component';
|
||||
import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component';
|
||||
import { SystemStatusComponent } from './components/system-status/system-status.component';
|
||||
import { WebConsoleFullWindowComponent } from './components/web-console-full-window/web-console-full-window.component';
|
||||
import { ConsoleGuard } from './guards/console-guard';
|
||||
import { DefaultLayoutComponent } from './layouts/default-layout/default-layout.component';
|
||||
import { ServerResolve } from './resolvers/server-resolve';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@ -62,77 +62,149 @@ const routes: Routes = [
|
||||
{ path: '', redirectTo: 'servers', pathMatch: 'full' },
|
||||
{ path: 'servers', component: ServersComponent },
|
||||
{ path: 'bundled', component: BundledServerFinderComponent },
|
||||
{ path: 'server/:server_id/projects', component: ProjectsComponent },
|
||||
{
|
||||
path: 'server/:server_id/projects',
|
||||
component: ProjectsComponent,
|
||||
resolve: { server: ServerResolve },
|
||||
},
|
||||
{ path: 'help', component: HelpComponent },
|
||||
{ path: 'settings', component: SettingsComponent },
|
||||
{ path: 'settings/console', component: ConsoleComponent },
|
||||
{ path: 'installed-software', component: InstalledSoftwareComponent },
|
||||
{ path: 'server/:server_id/project/:project_id/snapshots', component: ListOfSnapshotsComponent },
|
||||
{ path: 'server/:server_id/systemstatus', component: SystemStatusComponent },
|
||||
|
||||
{ path: 'server/:server_ip/:server_port/project/:project_id', component: DirectLinkComponent },
|
||||
{
|
||||
path: 'server/:server_id/project/:project_id/snapshots',
|
||||
component: ListOfSnapshotsComponent,
|
||||
resolve: { server: ServerResolve },
|
||||
},
|
||||
{ path: 'server/:server_id/preferences', component: PreferencesComponent },
|
||||
{ path: 'server/:server_id/preferences/gns3vm', component: Gns3vmComponent },
|
||||
// { path: 'server/:server_id/preferences/general', component: GeneralPreferencesComponent },
|
||||
{ path: 'server/:server_id/preferences/builtin', component: BuiltInPreferencesComponent},
|
||||
{ path: 'server/:server_id/preferences/builtin', component: BuiltInPreferencesComponent },
|
||||
|
||||
{ path: 'server/:server_id/preferences/builtin/ethernet-hubs', component: EthernetHubsTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/builtin/ethernet-hubs/addtemplate', component: EthernetHubsAddTemplateComponent },
|
||||
{ path: 'server/:server_id/preferences/builtin/ethernet-hubs/:template_id', component: EthernetHubsTemplateDetailsComponent },
|
||||
{
|
||||
path: 'server/:server_id/preferences/builtin/ethernet-hubs/addtemplate',
|
||||
component: EthernetHubsAddTemplateComponent,
|
||||
},
|
||||
{
|
||||
path: 'server/:server_id/preferences/builtin/ethernet-hubs/:template_id',
|
||||
component: EthernetHubsTemplateDetailsComponent,
|
||||
},
|
||||
|
||||
{ path: 'server/:server_id/preferences/builtin/ethernet-switches', component: EthernetSwitchesTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/builtin/ethernet-switches/addtemplate', component: EthernetSwitchesAddTemplateComponent },
|
||||
{ path: 'server/:server_id/preferences/builtin/ethernet-switches/:template_id', component: EthernetSwitchesTemplateDetailsComponent },
|
||||
{
|
||||
path: 'server/:server_id/preferences/builtin/ethernet-switches',
|
||||
component: EthernetSwitchesTemplatesComponent,
|
||||
},
|
||||
{
|
||||
path: 'server/:server_id/preferences/builtin/ethernet-switches/addtemplate',
|
||||
component: EthernetSwitchesAddTemplateComponent,
|
||||
},
|
||||
{
|
||||
path: 'server/:server_id/preferences/builtin/ethernet-switches/:template_id',
|
||||
component: EthernetSwitchesTemplateDetailsComponent,
|
||||
},
|
||||
|
||||
{ path: 'server/:server_id/preferences/builtin/cloud-nodes', component: CloudNodesTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/builtin/cloud-nodes/addtemplate', component: CloudNodesAddTemplateComponent },
|
||||
{ path: 'server/:server_id/preferences/builtin/cloud-nodes/:template_id', component: CloudNodesTemplateDetailsComponent },
|
||||
{
|
||||
path: 'server/:server_id/preferences/builtin/cloud-nodes/addtemplate',
|
||||
component: CloudNodesAddTemplateComponent,
|
||||
},
|
||||
{
|
||||
path: 'server/:server_id/preferences/builtin/cloud-nodes/:template_id',
|
||||
component: CloudNodesTemplateDetailsComponent,
|
||||
},
|
||||
|
||||
//{ path: 'server/:server_id/preferences/dynamips', component: DynamipsPreferencesComponent },
|
||||
{ path: 'server/:server_id/preferences/dynamips/templates', component: IosTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/dynamips/templates/addtemplate', component: AddIosTemplateComponent },
|
||||
{ path: 'server/:server_id/preferences/dynamips/templates/:template_id', component: IosTemplateDetailsComponent },
|
||||
{ path: 'server/:server_id/preferences/dynamips/templates/:template_id/copy', component: CopyIosTemplateComponent },
|
||||
{
|
||||
path: 'server/:server_id/preferences/dynamips/templates/:template_id/copy',
|
||||
component: CopyIosTemplateComponent,
|
||||
},
|
||||
|
||||
// { path: 'server/:server_id/preferences/qemu', component: QemuPreferencesComponent },
|
||||
{ path: 'server/:server_id/preferences/qemu/templates', component: QemuVmTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/qemu/templates/:template_id/copy', component: CopyQemuVmTemplateComponent },
|
||||
{
|
||||
path: 'server/:server_id/preferences/qemu/templates/:template_id/copy',
|
||||
component: CopyQemuVmTemplateComponent,
|
||||
},
|
||||
{ path: 'server/:server_id/preferences/qemu/templates/:template_id', component: QemuVmTemplateDetailsComponent },
|
||||
{ path: 'server/:server_id/preferences/qemu/addtemplate', component: AddQemuVmTemplateComponent },
|
||||
|
||||
// { path: 'server/:server_id/preferences/vpcs', component: VpcsPreferencesComponent },
|
||||
{ path: 'server/:server_id/preferences/vpcs/templates', component: VpcsTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/vpcs/templates/:template_id', component: VpcsTemplateDetailsComponent},
|
||||
{ path: 'server/:server_id/preferences/vpcs/templates/:template_id', component: VpcsTemplateDetailsComponent },
|
||||
{ path: 'server/:server_id/preferences/vpcs/addtemplate', component: AddVpcsTemplateComponent },
|
||||
|
||||
// { path: 'server/:server_id/preferences/virtualbox', component: VirtualBoxPreferencesComponent },
|
||||
{ path: 'server/:server_id/preferences/virtualbox/templates', component: VirtualBoxTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/virtualbox/templates/:template_id', component: VirtualBoxTemplateDetailsComponent },
|
||||
{
|
||||
path: 'server/:server_id/preferences/virtualbox/templates/:template_id',
|
||||
component: VirtualBoxTemplateDetailsComponent,
|
||||
},
|
||||
{ path: 'server/:server_id/preferences/virtualbox/addtemplate', component: AddVirtualBoxTemplateComponent },
|
||||
|
||||
// { path: 'server/:server_id/preferences/vmware', component: VmwarePreferencesComponent },
|
||||
{ path: 'server/:server_id/preferences/vmware/templates', component: VmwareTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/vmware/templates/:template_id', component: VmwareTemplateDetailsComponent },
|
||||
{
|
||||
path: 'server/:server_id/preferences/vmware/templates/:template_id',
|
||||
component: VmwareTemplateDetailsComponent,
|
||||
},
|
||||
{ path: 'server/:server_id/preferences/vmware/addtemplate', component: AddVmwareTemplateComponent },
|
||||
|
||||
// { path: 'server/:server_id/preferences/traceng', component: TracengPreferencesComponent },
|
||||
// { path: 'server/:server_id/preferences/traceng/templates', component: TracengTemplatesComponent },
|
||||
// { path: 'server/:server_id/preferences/traceng/templates/:template_id', component: TracengTemplateDetailsComponent },
|
||||
// { path: 'server/:server_id/preferences/traceng/addtemplate', component: AddTracengTemplateComponent },
|
||||
|
||||
{ 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: 'server/:server_id/preferences/docker/templates/:template_id',
|
||||
component: DockerTemplateDetailsComponent,
|
||||
},
|
||||
{
|
||||
path: 'server/:server_id/preferences/docker/templates/:template_id/copy',
|
||||
component: CopyDockerTemplateComponent,
|
||||
},
|
||||
{ path: 'server/:server_id/preferences/docker/addtemplate', component: AddDockerTemplateComponent },
|
||||
|
||||
{ path: 'server/:server_id/preferences/iou/templates', component: IouTemplatesComponent },
|
||||
{ path: 'server/:server_id/preferences/iou/templates/:template_id', component: IouTemplateDetailsComponent },
|
||||
{ path: 'server/:server_id/preferences/iou/templates/:template_id/copy', component: CopyIouTemplateComponent },
|
||||
{ path: 'server/:server_id/preferences/iou/addtemplate', component: AddIouTemplateComponent }
|
||||
]
|
||||
{ path: 'server/:server_id/preferences/iou/addtemplate', component: AddIouTemplateComponent },
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'server/:server_id/project/:project_id', component: ProjectMapComponent,
|
||||
{
|
||||
path: 'server/:server_id/project/:project_id',
|
||||
component: ProjectMapComponent,
|
||||
canDeactivate: [ConsoleGuard],
|
||||
},
|
||||
{
|
||||
path: 'server/:server_id/project/:project_id/nodes/:node_id',
|
||||
component: WebConsoleFullWindowComponent,
|
||||
},
|
||||
{
|
||||
path: 'static/web-ui/server/:server_id/project/:project_id/nodes/:node_id',
|
||||
component: WebConsoleFullWindowComponent,
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
redirectTo: 'servers'
|
||||
}
|
||||
component: PageNotFoundComponent,
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule]
|
||||
imports: [
|
||||
RouterModule.forRoot(routes, {
|
||||
anchorScrolling: 'enabled',
|
||||
enableTracing: false,
|
||||
scrollPositionRestoration: 'enabled',
|
||||
}),
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class AppRoutingModule {}
|
||||
|
@ -1 +1,4 @@
|
||||
<router-outlet></router-outlet>
|
||||
<div [ngClass]="{ dark: darkThemeEnabled, light: !darkThemeEnabled }">
|
||||
<router-outlet></router-outlet>
|
||||
<!-- <app-adbutler></app-adbutler> -->
|
||||
</div>
|
||||
|
11
src/app/app.component.scss
Normal file
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,12 +1,14 @@
|
||||
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
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 { AppComponent } from './app.component';
|
||||
import { ProgressService } from './common/progress/progress.service';
|
||||
import { SettingsService } from './services/settings.service';
|
||||
|
||||
import createSpyObj = jasmine.createSpyObj;
|
||||
// import 'jasmine';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
let component: AppComponent;
|
||||
@ -18,11 +20,12 @@ describe('AppComponent', () => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [RouterTestingModule, MatIconModule, NgxElectronModule],
|
||||
providers: [SettingsService, PersistenceService]
|
||||
providers: [SettingsService, ProgressService],
|
||||
schemas: [NO_ERRORS_SCHEMA],
|
||||
}).compileComponents();
|
||||
|
||||
electronService = TestBed.get(ElectronService);
|
||||
settingsService = TestBed.get(SettingsService);
|
||||
electronService = TestBed.inject(ElectronService);
|
||||
settingsService = TestBed.inject(SettingsService);
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
@ -42,23 +45,18 @@ describe('AppComponent', () => {
|
||||
}));
|
||||
|
||||
it('should receive changed settings and forward to electron', async(() => {
|
||||
const spy = createSpyObj('Electron.IpcRenderer', ['send']);
|
||||
spyOnProperty(electronService, 'isElectronApp').and.returnValue(true);
|
||||
spyOnProperty(electronService, 'ipcRenderer').and.returnValue(spy);
|
||||
settingsService.set('crash_reports', true);
|
||||
settingsService.setReportsSettings(true);
|
||||
component.ngOnInit();
|
||||
settingsService.set('crash_reports', 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);
|
||||
settingsService.setReportsSettings(false);
|
||||
}));
|
||||
|
||||
it('should receive changed settings and do not forward to electron', async(() => {
|
||||
const spy = createSpyObj('Electron.IpcRenderer', ['send']);
|
||||
spyOnProperty(electronService, 'isElectronApp').and.returnValue(false);
|
||||
settingsService.set('crash_reports', true);
|
||||
settingsService.setReportsSettings(true);
|
||||
component.ngOnInit();
|
||||
settingsService.set('crash_reports', false);
|
||||
settingsService.setReportsSettings(false);
|
||||
expect(spy.send).not.toHaveBeenCalled();
|
||||
}));
|
||||
});
|
||||
|
@ -1,29 +1,67 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatIconRegistry } from '@angular/material';
|
||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||
import { Component, HostBinding, OnInit } from '@angular/core';
|
||||
import { MatIconRegistry } from '@angular/material/icon';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';
|
||||
import { ElectronService } from 'ngx-electron';
|
||||
import { ProgressService } from './common/progress/progress.service';
|
||||
import { SettingsService } from './services/settings.service';
|
||||
import { ThemeService } from './services/theme.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
styleUrls: ['./app.component.scss'],
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
public darkThemeEnabled: boolean = false;
|
||||
|
||||
constructor(
|
||||
private overlayContainer: OverlayContainer,
|
||||
iconReg: MatIconRegistry,
|
||||
sanitizer: DomSanitizer,
|
||||
private settingsService: SettingsService,
|
||||
private electronService: ElectronService
|
||||
private electronService: ElectronService,
|
||||
private themeService: ThemeService,
|
||||
private router: Router,
|
||||
private progressService: ProgressService
|
||||
) {
|
||||
iconReg.addSvgIcon('gns3', sanitizer.bypassSecurityTrustResourceUrl('./assets/gns3_icon.svg'));
|
||||
iconReg.addSvgIcon('gns3black', sanitizer.bypassSecurityTrustResourceUrl('./assets/gns3_icon_black.svg'));
|
||||
|
||||
router.events.subscribe((value) => {
|
||||
this.checkEvent(value);
|
||||
});
|
||||
}
|
||||
|
||||
@HostBinding('class') componentCssClass;
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.electronService.isElectronApp) {
|
||||
this.settingsService.subscribe(settings => {
|
||||
this.electronService.ipcRenderer.send('settings.changed', settings);
|
||||
});
|
||||
this.applyTheme(this.themeService.savedTheme + '-theme');
|
||||
this.themeService.themeChanged.subscribe((event: string) => {
|
||||
this.applyTheme(event);
|
||||
});
|
||||
}
|
||||
|
||||
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) {
|
||||
this.progressService.activate();
|
||||
} else if (
|
||||
routerEvent instanceof NavigationEnd ||
|
||||
routerEvent instanceof NavigationCancel ||
|
||||
routerEvent instanceof NavigationError
|
||||
) {
|
||||
this.progressService.deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,205 +1,274 @@
|
||||
import * as Raven from 'raven-js';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule, ErrorHandler } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { HttpClientModule } 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 { DragAndDropModule } from 'angular-draggable-droppable';
|
||||
import { ResizableModule } from 'angular-resizable-element';
|
||||
import { D3Service } from 'd3-ng2-service';
|
||||
import { HotkeyModule } from 'angular2-hotkeys';
|
||||
import { PersistenceModule } from 'angular-persistence';
|
||||
import { NgxElectronModule } from 'ngx-electron';
|
||||
import { NgCircleProgressModule } from 'ng-circle-progress';
|
||||
import { FileUploadModule } from 'ng2-file-upload';
|
||||
import { NgxChildProcessModule } from 'ngx-childprocess';
|
||||
import { NgxElectronModule } from 'ngx-electron';
|
||||
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 { 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 { ToasterService } from './services/toaster.service';
|
||||
import { ProjectWebServiceHandler } from './handlers/project-web-service-handler';
|
||||
import { DrawingsDataSource } from './cartography/datasources/drawings-datasource';
|
||||
import { LinksDataSource } from './cartography/datasources/links-datasource';
|
||||
import { NodesDataSource } from './cartography/datasources/nodes-datasource';
|
||||
import { SymbolsDataSource } from './cartography/datasources/symbols-datasource';
|
||||
import { SelectionManager } from './cartography/managers/selection-manager';
|
||||
import { InRectangleHelper } from './cartography/helpers/in-rectangle-helper';
|
||||
import { DrawingsDataSource } from './cartography/datasources/drawings-datasource';
|
||||
import { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-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 { 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 { SelectionManager } from './cartography/managers/selection-manager';
|
||||
import { ToasterErrorHandler } from './common/error-handlers/toaster-error-handler';
|
||||
import { ProgressDialogComponent } from './common/progress-dialog/progress-dialog.component';
|
||||
import { ProgressDialogService } from './common/progress-dialog/progress-dialog.service';
|
||||
import { ProgressComponent } from './common/progress/progress.component';
|
||||
import { ProgressService } from './common/progress/progress.service';
|
||||
import { version } from './version';
|
||||
import { ToasterErrorHandler } from './common/error-handlers/toaster-error-handler';
|
||||
import { environment } from '../environments/environment';
|
||||
import { RavenState } from './common/error-handlers/raven-state-communicator';
|
||||
import { ServerDiscoveryComponent } from './components/servers/server-discovery/server-discovery.component';
|
||||
import { ServerDatabase } from './services/server.database';
|
||||
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 { AdbutlerComponent } from './components/adbutler/adbutler.component';
|
||||
import { BundledServerFinderComponent } from './components/bundled-server-finder/bundled-server-finder.component';
|
||||
import { InformationDialogComponent } from './components/dialogs/information-dialog.component';
|
||||
import { DirectLinkComponent } from './components/direct-link/direct-link.component';
|
||||
import { DrawingAddedComponent } from './components/drawings-listeners/drawing-added/drawing-added.component';
|
||||
import { DrawingDraggedComponent } from './components/drawings-listeners/drawing-dragged/drawing-dragged.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 { 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 { 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 { StyleEditorDialogComponent } from './components/project-map/drawings-editors/style-editor/style-editor.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 { InstalledSoftwareComponent } from './components/installed-software/installed-software.component';
|
||||
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.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 { 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 { 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 { IosTemplatesComponent } from './components/preferences/dynamips/ios-templates/ios-templates.component';
|
||||
import { IosService } from './services/ios.service';
|
||||
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 { EthernetSwitchesTemplatesComponent } from './components/preferences/built-in/ethernet-switches/ethernet-switches-templates/ethernet-switches-templates.component';
|
||||
import { CustomAdaptersTableComponent } from './components/preferences/common/custom-adapters-table/custom-adapters-table.component';
|
||||
import { CustomAdaptersComponent } from './components/preferences/common/custom-adapters/custom-adapters.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 { 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 { PortsComponent } from './components/preferences/common/ports/ports.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 { SymbolsComponent } from './components/preferences/common/symbols/symbols.component';
|
||||
import { UdpTunnelsComponent } from './components/preferences/common/udp-tunnels/udp-tunnels.component';
|
||||
import { AddDockerTemplateComponent } from './components/preferences/docker/add-docker-template/add-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 { DynamipsPreferencesComponent } from './components/preferences/dynamips/dynamips-preferences/dynamips-preferences.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 { GeneralPreferencesComponent } from './components/preferences/general/general-preferences.component';
|
||||
import { Gns3vmComponent } from './components/preferences/gns3vm/gns3vm.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 { 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 { QemuPreferencesComponent } from './components/preferences/qemu/qemu-preferences/qemu-preferences.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 { AddTracengTemplateComponent } from './components/preferences/traceng/add-traceng/add-traceng-template.component';
|
||||
import { TracengPreferencesComponent } from './components/preferences/traceng/traceng-preferences/traceng-preferences.component';
|
||||
import { TracengTemplateDetailsComponent } from './components/preferences/traceng/traceng-template-details/traceng-template-details.component';
|
||||
import { TracengTemplatesComponent } from './components/preferences/traceng/traceng-templates/traceng-templates.component';
|
||||
import { AddVirtualBoxTemplateComponent } from './components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component';
|
||||
import { VirtualBoxPreferencesComponent } from './components/preferences/virtual-box/virtual-box-preferences/virtual-box-preferences.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 { AlignVerticallyActionComponent } from './components/project-map/context-menu/actions/align_vertically/align-vertically.component';
|
||||
import { BringToFrontActionComponent } from './components/project-map/context-menu/actions/bring-to-front-action/bring-to-front-action.component';
|
||||
import { ChangeHostnameActionComponent } from './components/project-map/context-menu/actions/change-hostname/change-hostname-action.component';
|
||||
import { ChangeSymbolActionComponent } from './components/project-map/context-menu/actions/change-symbol/change-symbol-action.component';
|
||||
import { ConfigActionComponent } from './components/project-map/context-menu/actions/config-action/config-action.component';
|
||||
import { ConsoleDeviceActionBrowserComponent } from './components/project-map/context-menu/actions/console-device-action-browser/console-device-action-browser.component';
|
||||
import { ConsoleDeviceActionComponent } from './components/project-map/context-menu/actions/console-device-action/console-device-action.component';
|
||||
import { DeleteActionComponent } from './components/project-map/context-menu/actions/delete-action/delete-action.component';
|
||||
import { DuplicateActionComponent } from './components/project-map/context-menu/actions/duplicate-action/duplicate-action.component';
|
||||
import { EditConfigActionComponent } from './components/project-map/context-menu/actions/edit-config/edit-config-action.component';
|
||||
import { EditStyleActionComponent } from './components/project-map/context-menu/actions/edit-style-action/edit-style-action.component';
|
||||
import { EditTextActionComponent } from './components/project-map/context-menu/actions/edit-text-action/edit-text-action.component';
|
||||
import { ExportConfigActionComponent } from './components/project-map/context-menu/actions/export-config/export-config-action.component';
|
||||
import { HttpConsoleNewTabActionComponent } from './components/project-map/context-menu/actions/http-console-new-tab/http-console-new-tab-action.component';
|
||||
import { HttpConsoleActionComponent } from './components/project-map/context-menu/actions/http-console/http-console-action.component';
|
||||
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 { PacketFiltersActionComponent } from './components/project-map/context-menu/actions/packet-filters-action/packet-filters-action.component';
|
||||
import { ReloadNodeActionComponent } from './components/project-map/context-menu/actions/reload-node-action/reload-node-action.component';
|
||||
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';
|
||||
import { StartCaptureOnStartedLinkActionComponent } from './components/project-map/context-menu/actions/start-capture-on-started-link/start-capture-on-started-link.component';
|
||||
import { StartCaptureActionComponent } from './components/project-map/context-menu/actions/start-capture/start-capture-action.component';
|
||||
import { StartNodeActionComponent } from './components/project-map/context-menu/actions/start-node-action/start-node-action.component';
|
||||
import { StopCaptureActionComponent } from './components/project-map/context-menu/actions/stop-capture/stop-capture-action.component';
|
||||
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 { 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 { ConfiguratorDialogTracengComponent } from './components/project-map/node-editors/configurator/traceng/configurator-traceng.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 { 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 { 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 { AddServerDialogComponent } from './components/servers/add-server-dialog/add-server-dialog.component';
|
||||
import { ConfigureGns3VMDialogComponent } from './components/servers/configure-gns3vm-dialog/configure-gns3vm-dialog.component';
|
||||
import { ServerDiscoveryComponent } from './components/servers/server-discovery/server-discovery.component';
|
||||
import { ServersComponent } from './components/servers/servers.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 { 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 { ProjectsFilter } from './filters/projectsFilter.pipe';
|
||||
import { SearchFilter } from './filters/searchFilter.pipe';
|
||||
import { TemplateFilter } from './filters/templateFilter.pipe';
|
||||
import { ConsoleGuard } from './guards/console-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 { ServerResolve } from './resolvers/server-resolve';
|
||||
import { ApplianceService } from './services/appliances.service';
|
||||
import { ProtocolHandlerService } from './services/protocol-handler.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 { Gns3vmService } from './services/gns3vm.service';
|
||||
import { GoogleAnalyticsService } from './services/google-analytics.service';
|
||||
import { HttpServer, ServerErrorHandler } from './services/http-server.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 { AdbutlerComponent } from './components/adbutler/adbutler.component';
|
||||
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 { ServerManagementService } from './services/server-management.service';
|
||||
import { ServerSettingsService } from './services/server-settings.service';
|
||||
import { ServerDatabase } from './services/server.database';
|
||||
import { ServerService } from './services/server.service';
|
||||
import { SettingsService } from './services/settings.service';
|
||||
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 { 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 { TracengService } from './services/traceng.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 { DuplicateActionComponent } from './components/project-map/context-menu/actions/duplicate-action/duplicate-action.component';
|
||||
import { MapSettingService } from './services/mapsettings.service';
|
||||
import { ProjectMapMenuComponent } from './components/project-map/project-map-menu/project-map-menu.component';
|
||||
import { HelpComponent } from './components/help/help.component';
|
||||
|
||||
if (environment.production) {
|
||||
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
|
||||
shouldSendCallback: () => {
|
||||
return RavenState.shouldSend;
|
||||
},
|
||||
release: version
|
||||
}).install();
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -216,6 +285,7 @@ if (environment.production) {
|
||||
DefaultLayoutComponent,
|
||||
ProgressDialogComponent,
|
||||
ContextMenuComponent,
|
||||
ContextConsoleMenuComponent,
|
||||
StartNodeActionComponent,
|
||||
StopNodeActionComponent,
|
||||
TemplateComponent,
|
||||
@ -231,7 +301,6 @@ if (environment.production) {
|
||||
StopCaptureActionComponent,
|
||||
ResumeLinkActionComponent,
|
||||
SuspendLinkActionComponent,
|
||||
ProjectMapShortcutsComponent,
|
||||
SettingsComponent,
|
||||
PreferencesComponent,
|
||||
BundledServerFinderComponent,
|
||||
@ -304,15 +373,88 @@ if (environment.production) {
|
||||
SearchFilter,
|
||||
DateFilter,
|
||||
NameFilter,
|
||||
DataSourceFilter,
|
||||
TemplateFilter,
|
||||
ProjectsFilter,
|
||||
ListOfSnapshotsComponent,
|
||||
CustomAdaptersComponent,
|
||||
NodesMenuComponent,
|
||||
AdbutlerComponent,
|
||||
ConsoleDeviceActionComponent,
|
||||
ShowNodeActionComponent,
|
||||
ConsoleComponent,
|
||||
NodesMenuComponent,
|
||||
ProjectMapMenuComponent,
|
||||
HelpComponent
|
||||
HelpComponent,
|
||||
ConfigEditorDialogComponent,
|
||||
EditConfigActionComponent,
|
||||
LogConsoleComponent,
|
||||
SaveProjectDialogComponent,
|
||||
TopologySummaryComponent,
|
||||
InfoDialogComponent,
|
||||
BringToFrontActionComponent,
|
||||
ExportConfigActionComponent,
|
||||
ImportConfigActionComponent,
|
||||
ConsoleDeviceActionBrowserComponent,
|
||||
ChangeSymbolDialogComponent,
|
||||
ChangeSymbolActionComponent,
|
||||
EditProjectDialogComponent,
|
||||
ReloadNodeActionComponent,
|
||||
SuspendNodeActionComponent,
|
||||
ConfigActionComponent,
|
||||
ConfiguratorDialogVpcsComponent,
|
||||
ConfiguratorDialogEthernetHubComponent,
|
||||
ConfiguratorDialogEthernetSwitchComponent,
|
||||
PortsComponent,
|
||||
ConfiguratorDialogSwitchComponent,
|
||||
ConfiguratorDialogVirtualBoxComponent,
|
||||
CustomAdaptersTableComponent,
|
||||
ConfiguratorDialogQemuComponent,
|
||||
ConfiguratorDialogCloudComponent,
|
||||
UdpTunnelsComponent,
|
||||
ConfiguratorDialogAtmSwitchComponent,
|
||||
ConfiguratorDialogVmwareComponent,
|
||||
ConfiguratorDialogIouComponent,
|
||||
ConfiguratorDialogIosComponent,
|
||||
ConfiguratorDialogDockerComponent,
|
||||
ConfiguratorDialogNatComponent,
|
||||
ConfiguratorDialogTracengComponent,
|
||||
AddTracengTemplateComponent,
|
||||
TracengPreferencesComponent,
|
||||
TracengTemplatesComponent,
|
||||
TracengTemplateDetailsComponent,
|
||||
QemuImageCreatorComponent,
|
||||
ChooseNameDialogComponent,
|
||||
StartCaptureOnStartedLinkActionComponent,
|
||||
LockActionComponent,
|
||||
NavigationDialogComponent,
|
||||
ScreenshotDialogComponent,
|
||||
PageNotFoundComponent,
|
||||
AlignHorizontallyActionComponent,
|
||||
AlignVerticallyActionComponent,
|
||||
ConfirmationBottomSheetComponent,
|
||||
ConfigDialogComponent,
|
||||
Gns3vmComponent,
|
||||
ConfigureGns3VMDialogComponent,
|
||||
ImportApplianceComponent,
|
||||
DirectLinkComponent,
|
||||
SystemStatusComponent,
|
||||
StatusInfoComponent,
|
||||
StatusChartComponent,
|
||||
OpenFileExplorerActionComponent,
|
||||
HttpConsoleActionComponent,
|
||||
WebConsoleComponent,
|
||||
ConsoleWrapperComponent,
|
||||
HttpConsoleNewTabActionComponent,
|
||||
WebConsoleFullWindowComponent,
|
||||
NewTemplateDialogComponent,
|
||||
ChangeHostnameActionComponent,
|
||||
ChangeHostnameDialogComponent,
|
||||
ApplianceInfoDialogComponent,
|
||||
InformationDialogComponent,
|
||||
TemplateNameDialogComponent,
|
||||
ConfigureCustomAdaptersDialogComponent,
|
||||
EditNetworkConfigurationDialogComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@ -323,12 +465,16 @@ if (environment.production) {
|
||||
BrowserAnimationsModule,
|
||||
CdkTableModule,
|
||||
CartographyModule,
|
||||
HotkeyModule.forRoot(),
|
||||
PersistenceModule,
|
||||
NgxElectronModule,
|
||||
FileUploadModule,
|
||||
MatSidenavModule,
|
||||
MATERIAL_IMPORTS
|
||||
ResizableModule,
|
||||
DragAndDropModule,
|
||||
DragDropModule,
|
||||
NgxChildProcessModule,
|
||||
MATERIAL_IMPORTS,
|
||||
NgCircleProgressModule.forRoot(),
|
||||
OverlayModule,
|
||||
],
|
||||
providers: [
|
||||
SettingsService,
|
||||
@ -342,7 +488,6 @@ if (environment.production) {
|
||||
NodeService,
|
||||
LinkService,
|
||||
DrawingService,
|
||||
IndexedDbService,
|
||||
HttpServer,
|
||||
SnapshotService,
|
||||
ProgressDialogService,
|
||||
@ -352,6 +497,7 @@ if (environment.production) {
|
||||
LinksDataSource,
|
||||
NodesDataSource,
|
||||
SymbolsDataSource,
|
||||
LogEventsDataSource,
|
||||
SelectionManager,
|
||||
InRectangleHelper,
|
||||
DrawingsDataSource,
|
||||
@ -388,7 +534,22 @@ if (environment.production) {
|
||||
NodeCreatedLabelStylesFixer,
|
||||
NonNegativeValidator,
|
||||
RotationValidator,
|
||||
MapSettingService
|
||||
MapSettingsService,
|
||||
InfoService,
|
||||
ComputeService,
|
||||
TracengService,
|
||||
PacketCaptureService,
|
||||
ProtocolHandlerService,
|
||||
NotificationService,
|
||||
Gns3vmService,
|
||||
ThemeService,
|
||||
GoogleAnalyticsService,
|
||||
NodeConsoleService,
|
||||
ServerResolve,
|
||||
ConsoleGuard,
|
||||
Title,
|
||||
ApplianceService,
|
||||
UpdatesService,
|
||||
],
|
||||
entryComponents: [
|
||||
AddServerDialogComponent,
|
||||
@ -404,8 +565,42 @@ if (environment.production) {
|
||||
SymbolsComponent,
|
||||
DeleteConfirmationDialogComponent,
|
||||
HelpDialogComponent,
|
||||
StartCaptureDialogComponent
|
||||
StartCaptureDialogComponent,
|
||||
ConfigEditorDialogComponent,
|
||||
SaveProjectDialogComponent,
|
||||
InfoDialogComponent,
|
||||
ChangeSymbolDialogComponent,
|
||||
EditProjectDialogComponent,
|
||||
ConfigureGns3VMDialogComponent,
|
||||
ConfiguratorDialogVpcsComponent,
|
||||
ConfiguratorDialogEthernetHubComponent,
|
||||
ConfiguratorDialogEthernetSwitchComponent,
|
||||
ConfiguratorDialogSwitchComponent,
|
||||
ConfiguratorDialogVirtualBoxComponent,
|
||||
ConfiguratorDialogQemuComponent,
|
||||
ConfiguratorDialogCloudComponent,
|
||||
ConfiguratorDialogAtmSwitchComponent,
|
||||
ConfiguratorDialogVmwareComponent,
|
||||
ConfiguratorDialogIouComponent,
|
||||
ConfiguratorDialogIosComponent,
|
||||
ConfiguratorDialogDockerComponent,
|
||||
ConfiguratorDialogNatComponent,
|
||||
ConfiguratorDialogTracengComponent,
|
||||
QemuImageCreatorComponent,
|
||||
ChooseNameDialogComponent,
|
||||
NavigationDialogComponent,
|
||||
ScreenshotDialogComponent,
|
||||
ConfirmationBottomSheetComponent,
|
||||
ConfigDialogComponent,
|
||||
AdbutlerComponent,
|
||||
NewTemplateDialogComponent,
|
||||
ChangeHostnameDialogComponent,
|
||||
ApplianceInfoDialogComponent,
|
||||
ConfigureCustomAdaptersDialogComponent,
|
||||
EditNetworkConfigurationDialogComponent,
|
||||
],
|
||||
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 { LinkComponent } from './components/experimental-map/link/link.component';
|
||||
import { StatusComponent } from './components/experimental-map/status/status.component';
|
||||
import { DraggableComponent } from './components/experimental-map/draggable/draggable.component';
|
||||
import { DrawingComponent } from './components/experimental-map/drawing/drawing.component';
|
||||
import { EllipseComponent } from './components/experimental-map/drawing/drawings/ellipse/ellipse.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 { TextComponent } from './components/experimental-map/drawing/drawings/text/text.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 { StatusComponent } from './components/experimental-map/status/status.component';
|
||||
|
||||
export const ANGULAR_MAP_DECLARATIONS = [
|
||||
NodeComponent,
|
||||
@ -23,5 +23,5 @@ export const ANGULAR_MAP_DECLARATIONS = [
|
||||
TextComponent,
|
||||
DraggableComponent,
|
||||
SelectionComponent,
|
||||
InterfaceLabelComponent
|
||||
InterfaceLabelComponent,
|
||||
];
|
||||
|
@ -1,26 +1,22 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatMenuModule, MatIconModule } from '@angular/material';
|
||||
|
||||
import { CssFixer } from './helpers/css-fixer';
|
||||
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 { NgModule } from '@angular/core';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { ANGULAR_MAP_DECLARATIONS } from './angular-map.imports';
|
||||
import { D3_MAP_IMPORTS } from './d3-map.imports';
|
||||
import { CanvasSizeDetector } from './helpers/canvas-size-detector';
|
||||
import { DrawingsEventSource } from './events/drawings-event-source';
|
||||
import { NodesEventSource } from './events/nodes-event-source';
|
||||
import { MapDrawingToSvgConverter } from './converters/map/map-drawing-to-svg-converter';
|
||||
import { D3MapComponent } from './components/d3-map/d3-map.component';
|
||||
import { DraggableSelectionComponent } from './components/draggable-selection/draggable-selection.component';
|
||||
import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component';
|
||||
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 { 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 { 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 { MapLinkNodeToLinkNodeConverter } from './converters/map/map-link-node-to-link-node-converter';
|
||||
import { MapLinkToLinkConverter } from './converters/map/map-link-to-link-converter';
|
||||
@ -30,34 +26,40 @@ import { MapSymbolToSymbolConverter } from './converters/map/map-symbol-to-symbo
|
||||
import { NodeToMapNodeConverter } from './converters/map/node-to-map-node-converter';
|
||||
import { PortToMapPortConverter } from './converters/map/port-to-map-port-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 { TextElementFactory } from './helpers/drawings-factory/text-element-factory';
|
||||
import { EllipseElementFactory } from './helpers/drawings-factory/ellipse-element-factory';
|
||||
import { RectangleElementFactory } from './helpers/drawings-factory/rectangle-element-factory';
|
||||
import { LineElementFactory } from './helpers/drawings-factory/line-element-factory';
|
||||
import { TextEditorComponent } from './components/text-editor/text-editor.component';
|
||||
import { DrawingAddingComponent } from './components/drawing-adding/drawing-adding.component';
|
||||
import { MovingEventSource } from './events/moving-event-source';
|
||||
import { D3_MAP_IMPORTS } from './d3-map.imports';
|
||||
import {
|
||||
MapDrawingsDataSource,
|
||||
MapLinksDataSource,
|
||||
MapNodesDataSource,
|
||||
MapSymbolsDataSource,
|
||||
} from './datasources/map-datasource';
|
||||
import { MovingCanvasDirective } from './directives/moving-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 { SerialLinkWidget } from './widgets/links/serial-link';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, MatMenuModule, MatIconModule],
|
||||
@ -72,7 +74,7 @@ import { ZoomingCanvasDirective } from './directives/zooming-canvas.directive';
|
||||
SelectionSelectComponent,
|
||||
DraggableSelectionComponent,
|
||||
MovingCanvasDirective,
|
||||
ZoomingCanvasDirective
|
||||
ZoomingCanvasDirective,
|
||||
],
|
||||
providers: [
|
||||
CssFixer,
|
||||
@ -117,8 +119,10 @@ import { ZoomingCanvasDirective } from './directives/zooming-canvas.directive';
|
||||
MapSettingsManager,
|
||||
FontBBoxCalculator,
|
||||
StylesToFontConverter,
|
||||
...D3_MAP_IMPORTS
|
||||
EthernetLinkWidget,
|
||||
SerialLinkWidget,
|
||||
...D3_MAP_IMPORTS,
|
||||
],
|
||||
exports: [D3MapComponent, ExperimentalMapComponent]
|
||||
exports: [D3MapComponent, ExperimentalMapComponent],
|
||||
})
|
||||
export class CartographyModule {}
|
||||
|
@ -1,10 +1,48 @@
|
||||
<svg #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>
|
||||
<defs>
|
||||
<pattern
|
||||
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>
|
||||
</defs>
|
||||
|
||||
<defs>
|
||||
<pattern
|
||||
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>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="url(#gridDrawing)" />
|
||||
<rect width="100%" height="100%" fill="url(#gridNode)" />
|
||||
</svg>
|
||||
|
||||
<app-drawing-adding [svg]="svg"></app-drawing-adding>
|
||||
<app-drawing-resizing></app-drawing-resizing>
|
||||
<app-selection-control></app-selection-control>
|
||||
<app-selection-select></app-selection-select>
|
||||
<app-text-editor #textEditor [svg]="svg"></app-text-editor>
|
||||
<app-text-editor #textEditor [server]="server" [svg]="svg"></app-text-editor>
|
||||
<app-draggable-selection [svg]="svg"></app-draggable-selection>
|
||||
|
Before Width: | Height: | Size: 499 B After Width: | Height: | Size: 1.6 KiB |
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { D3MapComponent } from './d3-map.component';
|
||||
|
||||
describe('D3MapComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('D3MapComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [D3MapComponent]
|
||||
declarations: [D3MapComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -7,42 +7,42 @@ import {
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
SimpleChange,
|
||||
EventEmitter,
|
||||
Output,
|
||||
ViewChild
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { Selection, select } from 'd3-selection';
|
||||
|
||||
import { GraphLayout } from '../../widgets/graph-layout';
|
||||
import { Context } from '../../models/context';
|
||||
import { Size } from '../../models/size';
|
||||
import { select, Selection } from 'd3-selection';
|
||||
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 { Drawing } from '../../models/drawing';
|
||||
import { Project } from '../../../models/project';
|
||||
import { Server } from '../../../models/server';
|
||||
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 { MapSettingsManager } from '../../managers/map-settings-manager';
|
||||
import { Server } from '../../../models/server';
|
||||
import { ToolsService } from '../../../services/tools.service';
|
||||
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 { 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 { MapScaleService } from '../../../services/mapScale.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-d3-map',
|
||||
templateUrl: './d3-map.component.html',
|
||||
styleUrls: ['./d3-map.component.scss']
|
||||
styleUrls: ['./d3-map.component.scss'],
|
||||
})
|
||||
export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() nodes: Node[] = [];
|
||||
@Input() links: Link[] = [];
|
||||
@Input() drawings: Drawing[] = [];
|
||||
@Input() symbols: Symbol[] = [];
|
||||
@Input() project: Project;
|
||||
@Input() server: Server;
|
||||
|
||||
@Input() width = 1500;
|
||||
@ -53,15 +53,18 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
private parentNativeElement: any;
|
||||
private svg: Selection<SVGSVGElement, any, null, undefined>;
|
||||
|
||||
private onChangesDetected: Subscription;
|
||||
private subscriptions: Subscription[] = [];
|
||||
|
||||
private drawLinkTool: boolean;
|
||||
|
||||
protected settings = {
|
||||
show_interface_labels: true
|
||||
show_interface_labels: true,
|
||||
};
|
||||
public gridVisibility: number = 0;
|
||||
|
||||
public nodeGridX: number = 0;
|
||||
public nodeGridY: number = 0;
|
||||
public drawingGridX: number = 0;
|
||||
public drawingGridY: number = 0;
|
||||
|
||||
constructor(
|
||||
private graphDataManager: GraphDataManager,
|
||||
@ -75,15 +78,22 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
protected movingToolWidget: MovingTool,
|
||||
public graphLayout: GraphLayout,
|
||||
private toolsService: ToolsService,
|
||||
private mapScaleService: MapScaleService
|
||||
private mapScaleService: MapScaleService,
|
||||
private mapSettingsService: MapSettingsService
|
||||
) {
|
||||
this.parentNativeElement = element.nativeElement;
|
||||
}
|
||||
|
||||
@Input('show-interface-labels')
|
||||
set showInterfaceLabels(value) {
|
||||
this.settings.show_interface_labels = value;
|
||||
this.interfaceLabelWidget.setEnabled(value);
|
||||
if (value && !this.mapSettingsService.integrateLinkLabelsToLinks) {
|
||||
this.settings.show_interface_labels = true;
|
||||
this.interfaceLabelWidget.setEnabled(true);
|
||||
} else {
|
||||
this.settings.show_interface_labels = false;
|
||||
this.interfaceLabelWidget.setEnabled(false);
|
||||
}
|
||||
|
||||
this.mapChangeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
@ -91,6 +101,20 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
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 }) {
|
||||
if (
|
||||
(changes['width'] && !changes['width'].isFirstChange()) ||
|
||||
@ -121,9 +145,7 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
});
|
||||
|
||||
this.subscriptions.push(
|
||||
this.mapScaleService.scaleChangeEmitter.subscribe((value: number) => this.redraw())
|
||||
);
|
||||
this.subscriptions.push(this.mapScaleService.scaleChangeEmitter.subscribe((value: number) => this.redraw()));
|
||||
|
||||
this.subscriptions.push(
|
||||
this.toolsService.isMovingToolActivated.subscribe((value: boolean) => {
|
||||
@ -143,6 +165,9 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.drawLinkTool = value;
|
||||
})
|
||||
);
|
||||
|
||||
this.gridVisibility = localStorage.getItem('gridVisibility') === 'true' ? 1 : 0;
|
||||
this.mapSettingsService.isScrollDisabled.subscribe((val) => this.resize(val));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@ -153,13 +178,14 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
public applyMapSettingsChanges() {
|
||||
this.redraw();
|
||||
}
|
||||
|
||||
public createGraph(domElement: HTMLElement) {
|
||||
const rootElement = select(domElement);
|
||||
this.svg = rootElement.select<SVGSVGElement>('svg');
|
||||
this.graphLayout.connect(
|
||||
this.svg,
|
||||
this.context
|
||||
);
|
||||
this.graphLayout.connect(this.svg, this.context);
|
||||
this.graphLayout.draw(this.svg, this.context);
|
||||
this.mapChangeDetectorRef.hasBeenDrawn = true;
|
||||
}
|
||||
@ -181,11 +207,35 @@ export class D3MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
private redraw() {
|
||||
this.updateGrid();
|
||||
|
||||
this.graphDataManager.setNodes(this.nodes);
|
||||
this.graphDataManager.setLinks(this.links);
|
||||
this.graphDataManager.setDrawings(this.drawings);
|
||||
this.graphLayout.draw(this.svg, this.context);
|
||||
this.textEditor.activateTextEditing();
|
||||
this.textEditor.activateTextEditingForDrawings();
|
||||
this.textEditor.activateTextEditingForNodeLabels();
|
||||
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'])
|
||||
|
@ -1,27 +1,26 @@
|
||||
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
|
||||
|
||||
import { DraggableSelectionComponent } from './draggable-selection.component';
|
||||
import { NodesWidget } from '../../widgets/nodes';
|
||||
import { DrawingsWidget } from '../../widgets/drawings';
|
||||
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 { EventEmitter } from '@angular/core';
|
||||
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { select } from 'd3-selection';
|
||||
import { MapSettingsService } from '../../../services/mapsettings.service';
|
||||
import { DraggableDrag, DraggableEnd, DraggableStart } from '../../events/draggable';
|
||||
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 { MockedGraphDataManager } from '../../managers/graph-data-manager.spec';
|
||||
import { LinksEventSource } from '../../events/links-event-source';
|
||||
import { DraggableStart, DraggableDrag, DraggableEnd } from '../../events/draggable';
|
||||
import { MapNode } from '../../models/map/map-node';
|
||||
import { EventEmitter } from '@angular/core';
|
||||
import { SelectionManager } from '../../managers/selection-manager';
|
||||
import { SelectionManagerMock } from '../../managers/selection-manager.spec';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
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 { MapSettingService } 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', () => {
|
||||
let component: DraggableSelectionComponent;
|
||||
@ -67,8 +66,8 @@ describe('DraggableSelectionComponent', () => {
|
||||
draggable: {
|
||||
start: nodesStartEventEmitter,
|
||||
drag: nodesDragEventEmitter,
|
||||
end: nodesEndEventEmitter
|
||||
}
|
||||
end: nodesEndEventEmitter,
|
||||
},
|
||||
};
|
||||
|
||||
const drawingsWidgetStub = {
|
||||
@ -76,11 +75,11 @@ describe('DraggableSelectionComponent', () => {
|
||||
draggable: {
|
||||
start: drawingsStartEventEmitter,
|
||||
drag: drawingsDragEventEmitter,
|
||||
end: drawingsEndEventEmitter
|
||||
}
|
||||
end: drawingsEndEventEmitter,
|
||||
},
|
||||
};
|
||||
const linksWidgetStub = {
|
||||
redrawLink: () => {}
|
||||
redrawLink: () => {},
|
||||
};
|
||||
|
||||
const labelWidgetStub = {
|
||||
@ -88,27 +87,27 @@ describe('DraggableSelectionComponent', () => {
|
||||
draggable: {
|
||||
start: labelStartEventEmitter,
|
||||
drag: labelDragEventEmitter,
|
||||
end: labelEndEventEmitter
|
||||
}
|
||||
end: labelEndEventEmitter,
|
||||
},
|
||||
};
|
||||
|
||||
const interfaceLabelWidgetStub = {
|
||||
draggable: {
|
||||
start: interfaceLabelStartEventEmitter,
|
||||
drag: interfaceLabelDragEventEmitter,
|
||||
end: interfaceLabelEndEventEmitter
|
||||
}
|
||||
end: interfaceLabelEndEventEmitter,
|
||||
},
|
||||
};
|
||||
|
||||
const nodesEventSourceStub = {
|
||||
dragged: { emit: () => {} },
|
||||
labelDragged: { emit: () => {} }
|
||||
labelDragged: { emit: () => {} },
|
||||
};
|
||||
const drawingsEventSourceStub = {
|
||||
dragged: { emit: () => {} }
|
||||
dragged: { emit: () => {} },
|
||||
};
|
||||
const linksEventSourceStub = {
|
||||
interfaceDragged: { emit: () => {} }
|
||||
interfaceDragged: { emit: () => {} },
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
@ -123,9 +122,9 @@ describe('DraggableSelectionComponent', () => {
|
||||
{ provide: DrawingsEventSource, useValue: drawingsEventSourceStub },
|
||||
{ provide: GraphDataManager, useValue: mockedGraphDataManager },
|
||||
{ provide: LinksEventSource, useValue: linksEventSourceStub },
|
||||
{ provide: MapSettingService, useClass: MapSettingService }
|
||||
{ provide: MapSettingsService, useClass: MapSettingsService },
|
||||
],
|
||||
declarations: [DraggableSelectionComponent]
|
||||
declarations: [DraggableSelectionComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,28 +1,28 @@
|
||||
import { Component, OnInit, OnDestroy, Input } 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 { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { select } from 'd3-selection';
|
||||
import { MapLabel } from '../../models/map/map-label';
|
||||
import { LabelWidget } from '../../widgets/label';
|
||||
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||
import { merge, Subscription } from 'rxjs';
|
||||
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 { MapSettingService } from '../../../services/mapsettings.service';
|
||||
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({
|
||||
selector: 'app-draggable-selection',
|
||||
templateUrl: './draggable-selection.component.html',
|
||||
styleUrls: ['./draggable-selection.component.scss']
|
||||
styleUrls: ['./draggable-selection.component.scss'],
|
||||
})
|
||||
export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
private start: Subscription;
|
||||
@ -44,7 +44,7 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
private drawingsEventSource: DrawingsEventSource,
|
||||
private graphDataManager: GraphDataManager,
|
||||
private linksEventSource: LinksEventSource,
|
||||
private mapSettingsService: MapSettingService
|
||||
private mapSettingsService: MapSettingsService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@ -62,25 +62,25 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
).subscribe((evt: DraggableStart<any>) => {
|
||||
const selected = this.selectionManager.getSelected();
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
@ -94,8 +94,10 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
).subscribe((evt: DraggableDrag<any>) => {
|
||||
if (!this.isMapLocked) {
|
||||
const selected = this.selectionManager.getSelected();
|
||||
const selectedNodes = selected.filter(item => item instanceof MapNode);
|
||||
// update nodes
|
||||
let mapNodes = selected.filter((item) => item instanceof MapNode);
|
||||
const lockedNodes = mapNodes.filter((item: MapNode) => item.locked);
|
||||
const selectedNodes = mapNodes.filter((item: MapNode) => !item.locked);
|
||||
selectedNodes.forEach((node: MapNode) => {
|
||||
node.x += evt.dx;
|
||||
node.y += evt.dy;
|
||||
@ -105,63 +107,67 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
const links = this.graphDataManager
|
||||
.getLinks()
|
||||
.filter(
|
||||
link =>
|
||||
(link) =>
|
||||
(link.target !== undefined && link.target.id === node.id) ||
|
||||
(link.source !== undefined && link.source.id === node.id)
|
||||
);
|
||||
|
||||
links.forEach(link => {
|
||||
links.forEach((link) => {
|
||||
this.linksWidget.redrawLink(svg, link);
|
||||
});
|
||||
});
|
||||
|
||||
// update drawings
|
||||
selected
|
||||
.filter(item => item instanceof MapDrawing)
|
||||
.forEach((drawing: MapDrawing) => {
|
||||
drawing.x += evt.dx;
|
||||
drawing.y += evt.dy;
|
||||
this.drawingsWidget.redrawDrawing(svg, drawing);
|
||||
});
|
||||
let mapDrawings = selected.filter((item) => item instanceof MapDrawing);
|
||||
const selectedDrawings = mapDrawings.filter((item: MapDrawing) => !item.locked);
|
||||
selectedDrawings.forEach((drawing: MapDrawing) => {
|
||||
drawing.x += evt.dx;
|
||||
drawing.y += evt.dy;
|
||||
this.drawingsWidget.redrawDrawing(svg, drawing);
|
||||
});
|
||||
|
||||
// update labels
|
||||
selected
|
||||
.filter(item => item instanceof MapLabel)
|
||||
.forEach((label: MapLabel) => {
|
||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
let mapLabels = selected.filter((item) => item instanceof MapLabel);
|
||||
const selectedLabels = mapLabels.filter(
|
||||
(item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0
|
||||
);
|
||||
selectedLabels.forEach((label: MapLabel) => {
|
||||
const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const node = this.graphDataManager.getNodes().filter(node => node.id === label.nodeId)[0];
|
||||
node.label.x += evt.dx;
|
||||
node.label.y += evt.dy;
|
||||
this.labelWidget.redrawLabel(svg, label);
|
||||
});
|
||||
const node = this.graphDataManager.getNodes().filter((node) => node.id === label.nodeId)[0];
|
||||
node.label.x += evt.dx;
|
||||
node.label.y += evt.dy;
|
||||
this.labelWidget.redrawLabel(svg, label);
|
||||
});
|
||||
|
||||
// update interface labels
|
||||
selected
|
||||
.filter(item => item instanceof MapLinkNode)
|
||||
.forEach((interfaceLabel: MapLinkNode) => {
|
||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === interfaceLabel.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
let mapLinkNodes = selected.filter((item) => item instanceof MapLinkNode);
|
||||
const selectedLinkNodes = mapLinkNodes.filter(
|
||||
(item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0
|
||||
);
|
||||
selectedLinkNodes.forEach((interfaceLabel: MapLinkNode) => {
|
||||
const isParentNodeSelected = selectedNodes.filter((node) => node.id === interfaceLabel.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const link = this.graphDataManager
|
||||
.getLinks()
|
||||
.filter(link => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0];
|
||||
if (link.nodes[0].id === interfaceLabel.id) {
|
||||
link.nodes[0].label.x += evt.dx;
|
||||
link.nodes[0].label.y += evt.dy;
|
||||
}
|
||||
if (link.nodes[1].id === interfaceLabel.id) {
|
||||
link.nodes[1].label.x += evt.dx;
|
||||
link.nodes[1].label.y += evt.dy;
|
||||
}
|
||||
const link = this.graphDataManager
|
||||
.getLinks()
|
||||
.filter((link) => link.nodes[0].id === interfaceLabel.id || link.nodes[1].id === interfaceLabel.id)[0];
|
||||
if (link.nodes[0].id === interfaceLabel.id) {
|
||||
link.nodes[0].label.x += evt.dx;
|
||||
link.nodes[0].label.y += evt.dy;
|
||||
}
|
||||
if (link.nodes[1].id === interfaceLabel.id) {
|
||||
link.nodes[1].label.x += evt.dx;
|
||||
link.nodes[1].label.y += evt.dy;
|
||||
}
|
||||
|
||||
this.linksWidget.redrawLink(svg, link);
|
||||
});
|
||||
this.linksWidget.redrawLink(svg, link);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -173,39 +179,45 @@ export class DraggableSelectionComponent implements OnInit, OnDestroy {
|
||||
).subscribe((evt: DraggableEnd<any>) => {
|
||||
if (!this.isMapLocked) {
|
||||
const selected = this.selectionManager.getSelected();
|
||||
const selectedNodes = selected.filter(item => item instanceof MapNode);
|
||||
|
||||
let mapNodes = selected.filter((item) => item instanceof MapNode);
|
||||
const lockedNodes = mapNodes.filter((item: MapNode) => item.locked);
|
||||
const selectedNodes = mapNodes.filter((item: MapNode) => !item.locked);
|
||||
selectedNodes.forEach((item: MapNode) => {
|
||||
this.nodesEventSource.dragged.emit(new DraggedDataEvent<MapNode>(item, evt.dx, evt.dy));
|
||||
});
|
||||
|
||||
selected
|
||||
.filter(item => item instanceof MapDrawing)
|
||||
.forEach((item: MapDrawing) => {
|
||||
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(item, evt.dx, evt.dy));
|
||||
});
|
||||
let mapDrawings = selected.filter((item) => item instanceof MapDrawing);
|
||||
const selectedDrawings = mapDrawings.filter((item: MapDrawing) => !item.locked);
|
||||
selectedDrawings.forEach((item: MapDrawing) => {
|
||||
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(item, evt.dx, evt.dy));
|
||||
});
|
||||
|
||||
selected
|
||||
.filter(item => item instanceof MapLabel)
|
||||
.forEach((label: MapLabel) => {
|
||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
let mapLabels = selected.filter((item) => item instanceof MapLabel);
|
||||
const selectedLabels = mapLabels.filter(
|
||||
(item: MapLabel) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0
|
||||
);
|
||||
selectedLabels.forEach((label: MapLabel) => {
|
||||
const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.nodesEventSource.labelDragged.emit(new DraggedDataEvent<MapLabel>(label, evt.dx, evt.dy));
|
||||
});
|
||||
this.nodesEventSource.labelDragged.emit(new DraggedDataEvent<MapLabel>(label, evt.dx, evt.dy));
|
||||
});
|
||||
|
||||
selected
|
||||
.filter(item => item instanceof MapLinkNode)
|
||||
.forEach((label: MapLinkNode) => {
|
||||
const isParentNodeSelected = selectedNodes.filter(node => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
this.linksEventSource.interfaceDragged.emit(new DraggedDataEvent<MapLinkNode>(label, evt.dx, evt.dy));
|
||||
});
|
||||
}
|
||||
let mapLinkNodes = selected.filter((item) => item instanceof MapLinkNode);
|
||||
const selectedLinkNodes = mapLinkNodes.filter(
|
||||
(item: MapLinkNode) => lockedNodes.filter((node) => node.id === item.nodeId).length === 0
|
||||
);
|
||||
selectedLinkNodes.forEach((label: MapLinkNode) => {
|
||||
const isParentNodeSelected = selectedNodes.filter((node) => node.id === label.nodeId).length > 0;
|
||||
if (isParentNodeSelected) {
|
||||
return;
|
||||
}
|
||||
this.linksEventSource.interfaceDragged.emit(new DraggedDataEvent<MapLinkNode>(label, evt.dx, evt.dy));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { DrawingAddingComponent } from './drawing-adding.component';
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||
import { Context } from '../../models/context';
|
||||
import { DrawingAddingComponent } from './drawing-adding.component';
|
||||
|
||||
describe('DrawingAddingComponent', () => {
|
||||
let component: DrawingAddingComponent;
|
||||
@ -14,9 +14,9 @@ describe('DrawingAddingComponent', () => {
|
||||
imports: [NoopAnimationsModule],
|
||||
providers: [
|
||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource },
|
||||
{ provide: Context, useClass: Context }
|
||||
{ provide: Context, useClass: Context },
|
||||
],
|
||||
declarations: [DrawingAddingComponent]
|
||||
declarations: [DrawingAddingComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
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 { AddedDataEvent } from '../../events/event-source';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Context } from '../../models/context';
|
||||
|
||||
@Component({
|
||||
selector: 'app-drawing-adding',
|
||||
templateUrl: './drawing-adding.component.html',
|
||||
styleUrls: ['./drawing-adding.component.scss']
|
||||
styleUrls: ['./drawing-adding.component.scss'],
|
||||
})
|
||||
export class DrawingAddingComponent implements OnInit, OnDestroy {
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
@ -18,15 +18,19 @@ export class DrawingAddingComponent implements OnInit, OnDestroy {
|
||||
constructor(private drawingsEventSource: DrawingsEventSource, private context: Context) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.drawingSelected = this.drawingsEventSource.selected.subscribe(evt => {
|
||||
this.drawingSelected = this.drawingsEventSource.selected.subscribe((evt) => {
|
||||
evt === '' ? this.deactivate() : this.activate();
|
||||
});
|
||||
}
|
||||
|
||||
activate() {
|
||||
let listener = (event: MouseEvent) => {
|
||||
let x = (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;
|
||||
let x =
|
||||
(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.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 { async, 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 { MapDrawing } from '../../models/map/map-drawing';
|
||||
import { DrawingsWidget } from '../../widgets/drawings';
|
||||
import { DrawingResizingComponent } from './drawing-resizing.component';
|
||||
|
||||
export class DrawingWidgetMock {
|
||||
resizingFinished = new EventEmitter<ResizingEnd<MapDrawing>>();
|
||||
@ -36,9 +35,9 @@ describe('DrawingResizingComponent', () => {
|
||||
imports: [NoopAnimationsModule],
|
||||
providers: [
|
||||
{ provide: DrawingsWidget, useValue: drawingsWidgetMock },
|
||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource }
|
||||
{ provide: DrawingsEventSource, useValue: drawingsEventSource },
|
||||
],
|
||||
declarations: [DrawingResizingComponent]
|
||||
declarations: [DrawingResizingComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -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 { 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 { ResizingEnd } from '../../events/resizing';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
import { DrawingsWidget } from '../../widgets/drawings';
|
||||
|
||||
@Component({
|
||||
selector: 'app-drawing-resizing',
|
||||
template: `
|
||||
<ng-content></ng-content>
|
||||
`,
|
||||
styleUrls: ['./drawing-resizing.component.scss']
|
||||
template: ` <ng-content></ng-content> `,
|
||||
styleUrls: ['./drawing-resizing.component.scss'],
|
||||
})
|
||||
export class DrawingResizingComponent implements OnInit, OnDestroy {
|
||||
resizingFinished: Subscription;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DraggableComponent } from './draggable.component';
|
||||
|
||||
describe('DraggableComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('DraggableComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DraggableComponent]
|
||||
declarations: [DraggableComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -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 { Point } from '../../../models/point';
|
||||
|
||||
@ -8,10 +8,8 @@ export class DraggableDraggedEvent {
|
||||
|
||||
@Component({
|
||||
selector: '[app-draggable]',
|
||||
template: `
|
||||
<ng-content></ng-content>
|
||||
`,
|
||||
styleUrls: ['./draggable.component.scss']
|
||||
template: ` <ng-content></ng-content> `,
|
||||
styleUrls: ['./draggable.component.scss'],
|
||||
})
|
||||
export class DraggableComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
@Input('app-draggable') item: Point;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DrawingComponent } from './drawing.component';
|
||||
|
||||
describe('DrawingComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('DrawingComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [DrawingComponent]
|
||||
declarations: [DrawingComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -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 { ImageElement } from '../../../models/drawings/image-element';
|
||||
import { LineElement } from '../../../models/drawings/line-element';
|
||||
import { RectElement } from '../../../models/drawings/rect-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 { DrawingsEventSource } from '../../../events/drawings-event-source';
|
||||
|
||||
@Component({
|
||||
selector: '[app-drawing]',
|
||||
templateUrl: './drawing.component.html',
|
||||
styleUrls: ['./drawing.component.scss']
|
||||
styleUrls: ['./drawing.component.scss'],
|
||||
})
|
||||
export class DrawingComponent implements OnInit {
|
||||
@Input('app-drawing') drawing: MapDrawing;
|
||||
@ -26,9 +26,7 @@ export class DrawingComponent implements OnInit {
|
||||
ngOnInit() {
|
||||
try {
|
||||
this.drawing.element = this.svgToDrawingConverter.convert(this.drawing.svg);
|
||||
} catch (error) {
|
||||
console.log(`Cannot convert due to Error: '${error}'`);
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
OnDragging(evt) {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EllipseComponent } from './ellipse.component';
|
||||
|
||||
describe('EllipseComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('EllipseComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [EllipseComponent]
|
||||
declarations: [EllipseComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { EllipseElement } from '../../../../../models/drawings/ellipse-element';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
||||
import { EllipseElement } from '../../../../../models/drawings/ellipse-element';
|
||||
|
||||
@Component({
|
||||
selector: '[app-ellipse]',
|
||||
templateUrl: './ellipse.component.html',
|
||||
styleUrls: ['./ellipse.component.scss']
|
||||
styleUrls: ['./ellipse.component.scss'],
|
||||
})
|
||||
export class EllipseComponent implements OnInit {
|
||||
@Input('app-ellipse') ellipse: EllipseElement;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ImageComponent } from './image.component';
|
||||
|
||||
describe('ImageComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('ImageComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ImageComponent]
|
||||
declarations: [ImageComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { ImageElement } from '../../../../../models/drawings/image-element';
|
||||
|
||||
@Component({
|
||||
selector: '[app-image]',
|
||||
templateUrl: './image.component.html',
|
||||
styleUrls: ['./image.component.scss']
|
||||
styleUrls: ['./image.component.scss'],
|
||||
})
|
||||
export class ImageComponent implements OnInit {
|
||||
@Input('app-image') image: ImageElement;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LineComponent } from './line.component';
|
||||
|
||||
describe('LineComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('LineComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [LineComponent]
|
||||
declarations: [LineComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -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 { LineElement } from '../../../../../models/drawings/line-element';
|
||||
|
||||
@Component({
|
||||
selector: '[app-line]',
|
||||
templateUrl: './line.component.html',
|
||||
styleUrls: ['./line.component.scss']
|
||||
styleUrls: ['./line.component.scss'],
|
||||
})
|
||||
export class LineComponent implements OnInit {
|
||||
@Input('app-line') line: LineElement;
|
||||
|
@ -7,4 +7,6 @@
|
||||
[attr.stroke-dasharray]="stroke_dasharray"
|
||||
[attr.width]="rect.width"
|
||||
[attr.height]="rect.height"
|
||||
[attr.rx]="rect.rx"
|
||||
[attr.ry]="rect.ry"
|
||||
/>
|
||||
|
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 322 B |
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { RectComponent } from './rect.component';
|
||||
|
||||
describe('RectComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('RectComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [RectComponent]
|
||||
declarations: [RectComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { RectElement } from '../../../../../models/drawings/rect-element';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { QtDasharrayFixer } from '../../../../../helpers/qt-dasharray-fixer';
|
||||
import { RectElement } from '../../../../../models/drawings/rect-element';
|
||||
|
||||
@Component({
|
||||
selector: '[app-rect]',
|
||||
templateUrl: './rect.component.html',
|
||||
styleUrls: ['./rect.component.scss']
|
||||
styleUrls: ['./rect.component.scss'],
|
||||
})
|
||||
export class RectComponent implements OnInit {
|
||||
@Input('app-rect') rect: RectElement;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TextComponent } from './text.component';
|
||||
|
||||
describe('TextComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('TextComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [TextComponent]
|
||||
declarations: [TextComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
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 { TextElement } from '../../../../../models/drawings/text-element';
|
||||
import { FontFixer } from '../../../../../helpers/font-fixer';
|
||||
import { TextElement } from '../../../../../models/drawings/text-element';
|
||||
|
||||
@Component({
|
||||
selector: '[app-text]',
|
||||
templateUrl: './text.component.html',
|
||||
styleUrls: ['./text.component.scss']
|
||||
styleUrls: ['./text.component.scss'],
|
||||
})
|
||||
export class TextComponent implements OnInit, DoCheck {
|
||||
static MARGIN = 4;
|
||||
|
@ -1,4 +1,6 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
@ -7,29 +9,26 @@ import {
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
SimpleChange,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
ViewChild
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
|
||||
import { GraphLayout } from '../../widgets/graph-layout';
|
||||
import { Context } from '../../models/context';
|
||||
import { Size } from '../../models/size';
|
||||
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 { Drawing } from '../../models/drawing';
|
||||
import { Symbol } from '../../../models/symbol';
|
||||
import { CanvasSizeDetector } from '../../helpers/canvas-size-detector';
|
||||
import { GraphDataManager } from '../../managers/graph-data-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({
|
||||
selector: 'app-experimental-map',
|
||||
templateUrl: './experimental-map.component.html',
|
||||
styleUrls: ['./experimental-map.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() nodes: Node[] = [];
|
||||
@ -48,7 +47,7 @@ export class ExperimentalMapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private changesDetected: Subscription;
|
||||
|
||||
protected settings = {
|
||||
show_interface_labels: true
|
||||
show_interface_labels: true,
|
||||
};
|
||||
|
||||
constructor(
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { InterfaceLabelComponent } from './interface-label.component';
|
||||
|
||||
describe('InterfaceLabelComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('InterfaceLabelComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [InterfaceLabelComponent]
|
||||
declarations: [InterfaceLabelComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
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 { CssFixer } from '../../../helpers/css-fixer';
|
||||
|
||||
@Component({
|
||||
selector: '[app-interface-label]',
|
||||
templateUrl: './interface-label.component.html',
|
||||
styleUrls: ['./interface-label.component.scss']
|
||||
styleUrls: ['./interface-label.component.scss'],
|
||||
})
|
||||
export class InterfaceLabelComponent implements OnInit {
|
||||
@Input('app-interface-label') ignore: any;
|
||||
@ -17,7 +17,7 @@ export class InterfaceLabelComponent implements OnInit {
|
||||
y: 0,
|
||||
text: '',
|
||||
style: '',
|
||||
rotation: 0
|
||||
rotation: 0,
|
||||
};
|
||||
|
||||
borderSize = 5;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LinkComponent } from './link.component';
|
||||
|
||||
describe('LinkComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('LinkComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [LinkComponent]
|
||||
declarations: [LinkComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
OnInit,
|
||||
Input,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
ChangeDetectorRef,
|
||||
OnDestroy
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
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 { Node } from '../../../models/node';
|
||||
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({
|
||||
selector: '[app-link]',
|
||||
templateUrl: './link.component.html',
|
||||
styleUrls: ['./link.component.scss']
|
||||
styleUrls: ['./link.component.scss'],
|
||||
})
|
||||
export class LinkComponent implements OnInit, OnDestroy {
|
||||
@Input('app-link') link: MapLink;
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { LinkStrategy } from './link-strategy';
|
||||
import { path } from 'd3-path';
|
||||
import { MapLink } from '../../../../models/map/map-link';
|
||||
import { LinkStrategy } from './link-strategy';
|
||||
|
||||
export class EthernetLinkStrategy implements LinkStrategy {
|
||||
public d(link: MapLink): string {
|
||||
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.target.x + link.target.width / 2, link.target.y + link.target.height / 2],
|
||||
];
|
||||
|
||||
const line_generator = path();
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { path } from 'd3-path';
|
||||
import { LinkStrategy } from './link-strategy';
|
||||
import { MapLink } from '../../../../models/map/map-link';
|
||||
import { LinkStrategy } from './link-strategy';
|
||||
|
||||
export class SerialLinkStrategy implements LinkStrategy {
|
||||
private linkToPoints(link: MapLink) {
|
||||
const source = {
|
||||
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 = {
|
||||
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;
|
||||
@ -22,12 +22,12 @@ export class SerialLinkStrategy implements LinkStrategy {
|
||||
|
||||
const angle_source: [number, number] = [
|
||||
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] = [
|
||||
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]];
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NodeComponent } from './node.component';
|
||||
|
||||
describe('NodeComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('NodeComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [NodeComponent]
|
||||
declarations: [NodeComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,31 +1,30 @@
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
Input,
|
||||
ElementRef,
|
||||
ViewChild,
|
||||
ChangeDetectorRef,
|
||||
AfterViewInit,
|
||||
ChangeDetectionStrategy,
|
||||
Output,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
OnDestroy,
|
||||
Input,
|
||||
OnChanges,
|
||||
AfterViewInit
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
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 { FontFixer } from '../../../helpers/font-fixer';
|
||||
import { Symbol } from '../../../../models/symbol';
|
||||
import { MapNode } from '../../../models/map/map-node';
|
||||
import { NodesEventSource } from '../../../events/nodes-event-source';
|
||||
import { DraggedDataEvent } from '../../../events/event-source';
|
||||
|
||||
@Component({
|
||||
selector: '[app-node]',
|
||||
templateUrl: './node.component.html',
|
||||
styleUrls: ['./node.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class NodeComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
|
||||
static NODE_LABEL_MARGIN = 3;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SelectionComponent } from './selection.component';
|
||||
|
||||
describe('SelectionComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('SelectionComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SelectionComponent]
|
||||
declarations: [SelectionComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Component, OnInit, Input, AfterViewInit, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';
|
||||
import { Observable, Subscription, Subject } from 'rxjs';
|
||||
import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { Rectangle } from '../../../models/rectangle';
|
||||
|
||||
@Component({
|
||||
selector: '[app-selection]',
|
||||
templateUrl: './selection.component.html',
|
||||
styleUrls: ['./selection.component.scss']
|
||||
styleUrls: ['./selection.component.scss'],
|
||||
})
|
||||
export class SelectionComponent implements OnInit, AfterViewInit {
|
||||
@Input('app-selection') svg: SVGSVGElement;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { StatusComponent } from './status.component';
|
||||
|
||||
describe('StatusComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('StatusComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [StatusComponent]
|
||||
declarations: [StatusComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Component, ElementRef, Input, ChangeDetectorRef } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, ElementRef, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: '[app-status]',
|
||||
templateUrl: './status.component.html',
|
||||
styleUrls: ['./status.component.scss']
|
||||
styleUrls: ['./status.component.scss'],
|
||||
})
|
||||
export class StatusComponent {
|
||||
static STOPPED_STATUS_RECT_WIDTH = 10;
|
||||
@ -12,7 +12,7 @@ export class StatusComponent {
|
||||
status: '',
|
||||
path: null,
|
||||
direction: null,
|
||||
d: null
|
||||
d: null,
|
||||
};
|
||||
|
||||
constructor(protected element: ElementRef, private ref: ChangeDetectorRef) {}
|
||||
|
@ -1,14 +1,13 @@
|
||||
import { fakeAsync, tick } from '@angular/core/testing';
|
||||
|
||||
import { SelectionControlComponent } from './selection-control.component';
|
||||
import { SelectionManager } from '../../managers/selection-manager';
|
||||
import { instance, mock, when } from 'ts-mockito';
|
||||
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 { 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 { SelectionControlComponent } from './selection-control.component';
|
||||
|
||||
describe('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 { SelectionEventSource } from '../../events/selection-event-source';
|
||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||
import { InRectangleHelper } from '../../helpers/in-rectangle-helper';
|
||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||
import { SelectionManager } from '../../managers/selection-manager';
|
||||
import { Rectangle } from '../../models/rectangle';
|
||||
|
||||
@Component({
|
||||
selector: 'app-selection-control',
|
||||
templateUrl: './selection-control.component.html',
|
||||
styleUrls: ['./selection-control.component.scss']
|
||||
styleUrls: ['./selection-control.component.scss'],
|
||||
})
|
||||
export class SelectionControlComponent implements OnInit, OnDestroy {
|
||||
private onSelection: Subscription;
|
||||
@ -23,21 +23,21 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
||||
|
||||
ngOnInit() {
|
||||
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);
|
||||
});
|
||||
|
||||
const selectedLinks = this.graphDataManager.getLinks().filter(link => {
|
||||
const selectedLinks = this.graphDataManager.getLinks().filter((link) => {
|
||||
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);
|
||||
});
|
||||
|
||||
const selectedLabels = this.graphDataManager
|
||||
.getNodes()
|
||||
.filter(node => {
|
||||
.filter((node) => {
|
||||
if (node.label === undefined) {
|
||||
return false;
|
||||
}
|
||||
@ -45,11 +45,11 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
||||
const labelY = node.y + node.label.y;
|
||||
return this.inRectangleHelper.inRectangle(rectangle, labelX, labelY);
|
||||
})
|
||||
.map(node => node.label);
|
||||
.map((node) => node.label);
|
||||
|
||||
const selectedInterfacesLabelsSources = this.graphDataManager
|
||||
.getLinks()
|
||||
.filter(link => {
|
||||
.filter((link) => {
|
||||
if (link.source === undefined || link.nodes.length != 2 || link.nodes[0].label === undefined) {
|
||||
return false;
|
||||
}
|
||||
@ -57,11 +57,11 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
||||
const interfaceLabelY = link.source.y + link.nodes[0].label.y;
|
||||
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
||||
})
|
||||
.map(link => link.nodes[0]);
|
||||
.map((link) => link.nodes[0]);
|
||||
|
||||
const selectedInterfacesLabelsTargets = this.graphDataManager
|
||||
.getLinks()
|
||||
.filter(link => {
|
||||
.filter((link) => {
|
||||
if (link.target === undefined || link.nodes.length != 2 || link.nodes[1].label === undefined) {
|
||||
return false;
|
||||
}
|
||||
@ -69,7 +69,7 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
||||
const interfaceLabelY = link.target.y + link.nodes[1].label.y;
|
||||
return this.inRectangleHelper.inRectangle(rectangle, interfaceLabelX, interfaceLabelY);
|
||||
})
|
||||
.map(link => link.nodes[1]);
|
||||
.map((link) => link.nodes[1]);
|
||||
|
||||
const selectedInterfaces = [...selectedInterfacesLabelsSources, ...selectedInterfacesLabelsTargets];
|
||||
|
||||
@ -78,7 +78,7 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
||||
...selectedLinks,
|
||||
...selectedDrawings,
|
||||
...selectedLabels,
|
||||
...selectedInterfaces
|
||||
...selectedInterfaces,
|
||||
];
|
||||
|
||||
this.selectionManager.setSelected(selected);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SelectionSelectComponent } from './selection-select.component';
|
||||
|
||||
describe('SelectionSelectComponent', () => {
|
||||
@ -8,7 +7,7 @@ describe('SelectionSelectComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SelectionSelectComponent]
|
||||
declarations: [SelectionSelectComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { SelectionManager } from '../../managers/selection-manager';
|
||||
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
||||
@ -6,16 +6,13 @@ import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
||||
@Component({
|
||||
selector: 'app-selection-select',
|
||||
templateUrl: './selection-select.component.html',
|
||||
styleUrls: ['./selection-select.component.scss']
|
||||
styleUrls: ['./selection-select.component.scss'],
|
||||
})
|
||||
export class SelectionSelectComponent implements OnInit, OnDestroy {
|
||||
private onSelected: Subscription;
|
||||
private onUnselected: Subscription;
|
||||
|
||||
constructor(
|
||||
private selectionManager: SelectionManager,
|
||||
private mapChangeDetectorRef: MapChangeDetectorRef
|
||||
) {}
|
||||
constructor(private selectionManager: SelectionManager, private mapChangeDetectorRef: MapChangeDetectorRef) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.onSelected = this.selectionManager.selected.subscribe(() => {
|
||||
|
@ -1,15 +1,22 @@
|
||||
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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
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('TemporaryTextElementComponent', () => {
|
||||
describe('TextEditorComponent', () => {
|
||||
let component: TextEditorComponent;
|
||||
let fixture: ComponentFixture<TextEditorComponent>;
|
||||
let mockedLinkService: MockedLinkService = new MockedLinkService();
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@ -19,9 +26,14 @@ describe('TemporaryTextElementComponent', () => {
|
||||
{ provide: ToolsService, useClass: ToolsService },
|
||||
{ provide: Context, useClass: Context },
|
||||
{ provide: Renderer2, useClass: Renderer2 },
|
||||
{ provide: MapScaleService, useClass: MapScaleService }
|
||||
{ provide: MapScaleService, useClass: MapScaleService },
|
||||
{ provide: LinkService, useValue: mockedLinkService },
|
||||
{ provide: NodesDataSource, useClass: NodesDataSource },
|
||||
{ provide: LinksDataSource, useClass: LinksDataSource },
|
||||
{ provide: SelectionManager, useClass: SelectionManager },
|
||||
{ provide: FontFixer, useClass: FontFixer },
|
||||
],
|
||||
declarations: [TextEditorComponent]
|
||||
declarations: [TextEditorComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@ -1,21 +1,43 @@
|
||||
import { Component, ViewChild, ElementRef, OnInit, Input, EventEmitter, OnDestroy, Renderer2 } 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 { Server } from '../../../models/server';
|
||||
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 { 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 { FontFixer } from '../../helpers/font-fixer';
|
||||
import { SelectionManager } from '../../managers/selection-manager';
|
||||
import { Context } from '../../models/context';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { MapScaleService } from '../../../services/mapScale.service';
|
||||
import { TextElement } from '../../models/drawings/text-element';
|
||||
import { Font } from '../../models/font';
|
||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||
import { Node } from '../../models/node';
|
||||
|
||||
@Component({
|
||||
selector: 'app-text-editor',
|
||||
templateUrl: './text-editor.component.html',
|
||||
styleUrls: ['./text-editor.component.scss']
|
||||
styleUrls: ['./text-editor.component.scss'],
|
||||
})
|
||||
export class TextEditorComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('temporaryTextElement') temporaryTextElement: ElementRef;
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
@Input('server') server: Server;
|
||||
|
||||
leftPosition: string = '0px';
|
||||
topPosition: string = '0px';
|
||||
@ -23,6 +45,8 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
||||
|
||||
private editingDrawingId: string;
|
||||
private editedElement: any;
|
||||
private editedLink: MapLinkNode;
|
||||
private editedNode: Node;
|
||||
|
||||
private mapListener: Function;
|
||||
private textListener: Function;
|
||||
@ -34,7 +58,13 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
||||
private toolsService: ToolsService,
|
||||
private context: Context,
|
||||
private renderer: Renderer2,
|
||||
private mapScaleService: MapScaleService
|
||||
private mapScaleService: MapScaleService,
|
||||
private linkService: LinkService,
|
||||
private linksDataSource: LinksDataSource,
|
||||
private nodesDataSource: NodesDataSource,
|
||||
private selectionManager: SelectionManager,
|
||||
private fontFixer: FontFixer,
|
||||
private ngZone: NgZone
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@ -42,7 +72,8 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
||||
isActive ? this.activateTextAdding() : this.deactivateTextAdding();
|
||||
});
|
||||
|
||||
this.activateTextEditing();
|
||||
this.ngZone.runOutsideAngular(this.activateTextEditingForDrawings.bind(this));
|
||||
this.ngZone.runOutsideAngular(this.activateTextEditingForNodeLabels.bind(this));
|
||||
}
|
||||
|
||||
activateTextAdding() {
|
||||
@ -50,8 +81,13 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
||||
this.leftPosition = event.pageX.toString() + 'px';
|
||||
this.topPosition = event.pageY.toString() + 'px';
|
||||
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();
|
||||
document.documentElement.style.cursor = "default";
|
||||
|
||||
let textListener = () => {
|
||||
this.drawingsEventSource.textAdded.emit(
|
||||
@ -80,14 +116,107 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
||||
this.svg.removeEventListener('click', this.mapListener as EventListenerOrEventListenerObject);
|
||||
}
|
||||
|
||||
activateTextEditing() {
|
||||
activateTextEditingForNodeLabels() {
|
||||
const rootElement = select(this.svg);
|
||||
|
||||
rootElement
|
||||
.selectAll<SVGGElement, MapLinkNode>('g.interface_label_container')
|
||||
.select<SVGTextElement>('text.interface_label')
|
||||
.on('dblclick', (elem, index, textElements) => {
|
||||
this.selectionManager.setSelected([]);
|
||||
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'initial');
|
||||
this.renderer.setStyle(
|
||||
this.temporaryTextElement.nativeElement,
|
||||
'transform',
|
||||
`scale(${this.mapScaleService.getScale()})`
|
||||
);
|
||||
this.editedLink = elem;
|
||||
|
||||
select(textElements[index]).attr('visibility', 'hidden');
|
||||
select(textElements[index]).classed('editingMode', true);
|
||||
|
||||
this.editedNode = this.nodesDataSource.get(elem.nodeId);
|
||||
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 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.topPosition = y.toString() + 'px';
|
||||
this.temporaryTextElement.nativeElement.innerText = elem.label.text;
|
||||
|
||||
let styleProperties: StyleProperty[] = [];
|
||||
for (let property of elem.label.style.split(';')) {
|
||||
styleProperties.push({
|
||||
property: property.split(': ')[0],
|
||||
value: property.split(': ')[1],
|
||||
});
|
||||
}
|
||||
let font: Font = {
|
||||
font_family: styleProperties.find((p) => p.property === 'font-family')
|
||||
? styleProperties.find((p) => p.property === 'font-family').value
|
||||
: '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);
|
||||
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-size', `${font.font_size}pt`);
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'font-weight', font.font_weight);
|
||||
|
||||
let listener = () => {
|
||||
let innerText = this.temporaryTextElement.nativeElement.innerText;
|
||||
let link: Link = this.linksDataSource.get(this.editedLink.linkId);
|
||||
link.nodes.find((n) => n.node_id === this.editedNode.node_id).label.text = innerText;
|
||||
|
||||
this.linkService.updateLink(this.server, link).subscribe((link: Link) => {
|
||||
rootElement
|
||||
.selectAll<SVGTextElement, TextElement>('text.editingMode')
|
||||
.attr('visibility', 'visible')
|
||||
.classed('editingMode', false);
|
||||
|
||||
this.innerText = '';
|
||||
this.temporaryTextElement.nativeElement.innerText = '';
|
||||
this.temporaryTextElement.nativeElement.removeEventListener('focusout', this.textListener);
|
||||
|
||||
this.clearStyle();
|
||||
this.renderer.setStyle(this.temporaryTextElement.nativeElement, 'display', 'none');
|
||||
});
|
||||
};
|
||||
this.textListener = listener;
|
||||
this.temporaryTextElement.nativeElement.addEventListener('focusout', this.textListener);
|
||||
this.temporaryTextElement.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
|
||||
activateTextEditingForDrawings() {
|
||||
const rootElement = select(this.svg);
|
||||
|
||||
rootElement
|
||||
.selectAll<SVGTextElement, TextElement>('text.text_element')
|
||||
.on('dblclick', (elem, index, textElements) => {
|
||||
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;
|
||||
|
||||
select(textElements[index]).attr('visibility', 'hidden');
|
||||
@ -95,8 +224,14 @@ export class TextEditorComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.editingDrawingId = textElements[index].parentElement.parentElement.getAttribute('drawing_id');
|
||||
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 y = (Number(transformData[1].split(/,/)[1]) * this.context.transformation.k) + this.context.getZeroZeroTransformationPoint().y + this.context.transformation.y;
|
||||
var x =
|
||||
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.topPosition = y.toString() + 'px';
|
||||
this.temporaryTextElement.nativeElement.innerText = elem.text;
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Drawing } from '../../models/drawing';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
import { Converter } from '../converter';
|
||||
|
||||
@Injectable()
|
||||
export class DrawingToMapDrawingConverter implements Converter<Drawing, MapDrawing> {
|
||||
@ -14,6 +13,7 @@ export class DrawingToMapDrawingConverter implements Converter<Drawing, MapDrawi
|
||||
mapDrawing.projectId = drawing.project_id;
|
||||
mapDrawing.rotation = drawing.rotation;
|
||||
mapDrawing.svg = drawing.svg;
|
||||
mapDrawing.locked = drawing.locked;
|
||||
mapDrawing.x = drawing.x;
|
||||
mapDrawing.y = drawing.y;
|
||||
mapDrawing.z = drawing.z;
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { CssFixer } from '../../helpers/css-fixer';
|
||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||
import { FontFixer } from '../../helpers/font-fixer';
|
||||
import { Label } from '../../models/label';
|
||||
import { MapLabel } from '../../models/map/map-label';
|
||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||
import { CssFixer } from '../../helpers/css-fixer';
|
||||
import { FontFixer } from '../../helpers/font-fixer';
|
||||
import { Converter } from '../converter';
|
||||
|
||||
@Injectable()
|
||||
export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { LabelToMapLabelConverter } from './label-to-map-label-converter';
|
||||
import { LinkNode } from '../../../models/link-node';
|
||||
import { MapLinkNode } from '../../models/map/map-link-node';
|
||||
import { Converter } from '../converter';
|
||||
import { LabelToMapLabelConverter } from './label-to-map-label-converter';
|
||||
|
||||
@Injectable()
|
||||
export class LinkNodeToMapLinkNodeConverter implements Converter<LinkNode, MapLinkNode> {
|
||||
|
@ -1,9 +1,8 @@
|
||||
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 { MapLink } from '../../models/map/map-link';
|
||||
import { Converter } from '../converter';
|
||||
import { LinkNodeToMapLinkNodeConverter } from './link-node-to-map-link-node-converter';
|
||||
|
||||
@Injectable()
|
||||
export class LinkToMapLinkConverter implements Converter<Link, MapLink> {
|
||||
@ -17,7 +16,9 @@ export class LinkToMapLinkConverter implements Converter<Link, MapLink> {
|
||||
mapLink.capturing = link.capturing;
|
||||
mapLink.filters = link.filters;
|
||||
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.suspend = link.suspend;
|
||||
return mapLink;
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Drawing } from '../../models/drawing';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
import { Converter } from '../converter';
|
||||
|
||||
@Injectable()
|
||||
export class MapDrawingToDrawingConverter implements Converter<MapDrawing, Drawing> {
|
||||
@ -14,6 +13,7 @@ export class MapDrawingToDrawingConverter implements Converter<MapDrawing, Drawi
|
||||
drawing.project_id = mapDrawing.projectId;
|
||||
drawing.rotation = mapDrawing.rotation;
|
||||
drawing.svg = mapDrawing.svg;
|
||||
drawing.locked = mapDrawing.locked;
|
||||
drawing.x = mapDrawing.x;
|
||||
drawing.y = mapDrawing.y;
|
||||
drawing.z = mapDrawing.z;
|
||||
|
@ -1,11 +1,10 @@
|
||||
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 { LineElement } from '../../models/drawings/line-element';
|
||||
import { RectElement } from '../../models/drawings/rect-element';
|
||||
import { TextElement } from '../../models/drawings/text-element';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
import { Converter } from '../converter';
|
||||
|
||||
@Injectable()
|
||||
export class MapDrawingToSvgConverter implements Converter<MapDrawing, string> {
|
||||
@ -15,27 +14,13 @@ export class MapDrawingToSvgConverter implements Converter<MapDrawing, string> {
|
||||
let elem = ``;
|
||||
|
||||
if (mapDrawing.element instanceof RectElement) {
|
||||
elem = `<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
|
||||
}\" />`;
|
||||
elem = `<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}\" rx=\"${mapDrawing.element.rx}\" ry=\"${mapDrawing.element.ry}\" />`;
|
||||
} else if (mapDrawing.element instanceof EllipseElement) {
|
||||
elem = `<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}\" />`;
|
||||
elem = `<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}\" />`;
|
||||
} else if (mapDrawing.element instanceof LineElement) {
|
||||
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}\" />`;
|
||||
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}\" />`;
|
||||
} else if (mapDrawing.element instanceof TextElement) {
|
||||
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>`;
|
||||
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>`;
|
||||
} else return '';
|
||||
|
||||
return `<svg height=\"${mapDrawing.element.height}\" width=\"${mapDrawing.element.width}\">${elem}</svg>`;
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { CssFixer } from '../../helpers/css-fixer';
|
||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||
import { FontFixer } from '../../helpers/font-fixer';
|
||||
import { Label } from '../../models/label';
|
||||
import { MapLabel } from '../../models/map/map-label';
|
||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||
import { CssFixer } from '../../helpers/css-fixer';
|
||||
import { FontFixer } from '../../helpers/font-fixer';
|
||||
import { Converter } from '../converter';
|
||||
|
||||
@Injectable()
|
||||
export class MapLabelToLabelConverter implements Converter<MapLabel, Label> {
|
||||
|
@ -1,9 +1,8 @@
|
||||
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 { MapLinkNode } from '../../models/map/map-link-node';
|
||||
import { Converter } from '../converter';
|
||||
import { MapLabelToLabelConverter } from './map-label-to-label-converter';
|
||||
|
||||
@Injectable()
|
||||
export class MapLinkNodeToLinkNodeConverter implements Converter<MapLinkNode, LinkNode> {
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { MapLinkNodeToLinkNodeConverter } from './map-link-node-to-link-node-converter';
|
||||
import { Link } from '../../../models/link';
|
||||
import { MapLink } from '../../models/map/map-link';
|
||||
import { Converter } from '../converter';
|
||||
import { MapLinkNodeToLinkNodeConverter } from './map-link-node-to-link-node-converter';
|
||||
|
||||
@Injectable()
|
||||
export class MapLinkToLinkConverter implements Converter<MapLink, Link> {
|
||||
@ -17,7 +16,7 @@ export class MapLinkToLinkConverter implements Converter<MapLink, Link> {
|
||||
link.capturing = mapLink.capturing;
|
||||
link.filters = mapLink.filters;
|
||||
link.link_type = mapLink.linkType;
|
||||
link.nodes = mapLink.nodes.map(mapLinkNode => this.mapLinkNodeToMapLinkNode.convert(mapLinkNode));
|
||||
link.nodes = mapLink.nodes.map((mapLinkNode) => this.mapLinkNodeToMapLinkNode.convert(mapLinkNode));
|
||||
link.project_id = mapLink.projectId;
|
||||
link.suspend = mapLink.suspend;
|
||||
return link;
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { MapNode } from '../../models/map/map-node';
|
||||
import { Node } from '../../models/node';
|
||||
import { Converter } from '../converter';
|
||||
import { MapLabelToLabelConverter } from './map-label-to-label-converter';
|
||||
import { MapPortToPortConverter } from './map-port-to-port-converter';
|
||||
import { Node } from '../../models/node';
|
||||
|
||||
@Injectable()
|
||||
export class MapNodeToNodeConverter implements Converter<MapNode, Node> {
|
||||
@ -17,19 +16,22 @@ export class MapNodeToNodeConverter implements Converter<MapNode, Node> {
|
||||
node.compute_id = mapNode.computeId;
|
||||
node.console = mapNode.console;
|
||||
node.console_host = mapNode.consoleHost;
|
||||
node.console_type = mapNode.consoleType;
|
||||
node.first_port_name = mapNode.firstPortName;
|
||||
node.height = mapNode.height;
|
||||
node.label = mapNode.label ? this.mapLabelToLabel.convert(mapNode.label) : undefined;
|
||||
node.locked = mapNode.locked;
|
||||
node.name = mapNode.name;
|
||||
node.node_directory = mapNode.nodeDirectory;
|
||||
node.node_type = mapNode.nodeType;
|
||||
node.port_name_format = mapNode.portNameFormat;
|
||||
node.port_segment_size = mapNode.portSegmentSize;
|
||||
node.ports = mapNode.ports ? mapNode.ports.map(mapPort => this.mapPortToPort.convert(mapPort)) : [];
|
||||
node.ports = mapNode.ports ? mapNode.ports.map((mapPort) => this.mapPortToPort.convert(mapPort)) : [];
|
||||
node.project_id = mapNode.projectId;
|
||||
node.status = mapNode.status;
|
||||
node.symbol = mapNode.symbol;
|
||||
node.symbol_url = mapNode.symbolUrl;
|
||||
node.usage = mapNode.usage;
|
||||
node.width = mapNode.width;
|
||||
node.x = mapNode.x;
|
||||
node.y = mapNode.y;
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Port } from '../../../models/port';
|
||||
import { MapPort } from '../../models/map/map-port';
|
||||
import { Converter } from '../converter';
|
||||
|
||||
@Injectable()
|
||||
export class MapPortToPortConverter implements Converter<MapPort, Port> {
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { MapSymbol } from '../../models/map/map-symbol';
|
||||
import { Symbol } from '../../../models/symbol';
|
||||
import { MapSymbol } from '../../models/map/map-symbol';
|
||||
import { Converter } from '../converter';
|
||||
|
||||
@Injectable()
|
||||
export class MapSymbolToSymbolConverter implements Converter<MapSymbol, Symbol> {
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { CssFixer } from '../../helpers/css-fixer';
|
||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||
import { FontFixer } from '../../helpers/font-fixer';
|
||||
import { MapNode } from '../../models/map/map-node';
|
||||
import { Node } from '../../models/node';
|
||||
import { Converter } from '../converter';
|
||||
import { LabelToMapLabelConverter } from './label-to-map-label-converter';
|
||||
import { PortToMapPortConverter } from './port-to-map-port-converter';
|
||||
import { FontBBoxCalculator } from '../../helpers/font-bbox-calculator';
|
||||
import { CssFixer } from '../../helpers/css-fixer';
|
||||
import { FontFixer } from '../../helpers/font-fixer';
|
||||
|
||||
@Injectable()
|
||||
export class NodeToMapNodeConverter implements Converter<Node, MapNode> {
|
||||
@ -26,19 +25,24 @@ export class NodeToMapNodeConverter implements Converter<Node, MapNode> {
|
||||
mapNode.computeId = node.compute_id;
|
||||
mapNode.console = node.console;
|
||||
mapNode.consoleHost = node.console_host;
|
||||
mapNode.consoleType = node.console_type;
|
||||
mapNode.firstPortName = node.first_port_name;
|
||||
mapNode.height = node.height;
|
||||
mapNode.label = this.labelToMapLabel.convert(node.label, { node_id: node.node_id });
|
||||
mapNode.label = this.labelToMapLabel
|
||||
? this.labelToMapLabel.convert(node.label, { node_id: node.node_id })
|
||||
: undefined;
|
||||
mapNode.locked = node.locked;
|
||||
mapNode.name = node.name;
|
||||
mapNode.nodeDirectory = node.node_directory;
|
||||
mapNode.nodeType = node.node_type;
|
||||
mapNode.portNameFormat = node.port_name_format;
|
||||
mapNode.portSegmentSize = node.port_segment_size;
|
||||
mapNode.ports = node.ports.map(port => this.portToMapPort.convert(port));
|
||||
mapNode.ports = node.ports ? node.ports.map((port) => this.portToMapPort.convert(port)) : [];
|
||||
mapNode.projectId = node.project_id;
|
||||
mapNode.status = node.status;
|
||||
mapNode.symbol = node.symbol;
|
||||
mapNode.symbolUrl = node.symbol_url;
|
||||
mapNode.usage = node.usage;
|
||||
mapNode.width = node.width;
|
||||
mapNode.x = node.x;
|
||||
mapNode.y = node.y;
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Port } from '../../../models/port';
|
||||
import { MapPort } from '../../models/map/map-port';
|
||||
import { Converter } from '../converter';
|
||||
|
||||
@Injectable()
|
||||
export class PortToMapPortConverter implements Converter<Port, MapPort> {
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { Symbol } from '../../../models/symbol';
|
||||
import { MapSymbol } from '../../models/map/map-symbol';
|
||||
import { Converter } from '../converter';
|
||||
|
||||
@Injectable()
|
||||
export class SymbolToMapSymbolConverter implements Converter<Symbol, MapSymbol> {
|
||||
|
@ -14,7 +14,7 @@ describe('StylesToFontConverter', () => {
|
||||
const expectedFont: Font = {
|
||||
font_family: 'TypeWriter',
|
||||
font_size: 10,
|
||||
font_weight: 'bold'
|
||||
font_weight: 'bold',
|
||||
};
|
||||
|
||||
expect(converter.convert(styles)).toEqual(expectedFont);
|
||||
|
@ -1,8 +1,7 @@
|
||||
import * as csstree from 'css-tree';
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Converter } from './converter';
|
||||
import * as csstree from 'css-tree';
|
||||
import { Font } from '../models/font';
|
||||
import { Converter } from './converter';
|
||||
|
||||
@Injectable()
|
||||
export class StylesToFontConverter implements Converter<string, Font> {
|
||||
@ -10,30 +9,30 @@ export class StylesToFontConverter implements Converter<string, Font> {
|
||||
const font: Font = {
|
||||
font_family: undefined,
|
||||
font_size: undefined,
|
||||
font_weight: undefined
|
||||
font_weight: undefined,
|
||||
};
|
||||
|
||||
const ast = csstree.parse(styles, {
|
||||
context: 'declarationList'
|
||||
context: 'declarationList',
|
||||
});
|
||||
|
||||
ast.children.forEach(child => {
|
||||
if (child.property === 'font-size') {
|
||||
child.value.children.forEach(value => {
|
||||
ast.children.forEach((child) => {
|
||||
if (child.property === 'font-size' && child.value && child.value.children) {
|
||||
child.value.children.forEach((value) => {
|
||||
if (value.type === 'Dimension') {
|
||||
font.font_size = parseInt(value.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (child.property === 'font-family') {
|
||||
child.value.children.forEach(value => {
|
||||
if (child.property === 'font-family' && child.value && child.value.children) {
|
||||
child.value.children.forEach((value) => {
|
||||
if (value.type === 'Identifier') {
|
||||
font.font_family = value.name;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (child.property === 'font-weight') {
|
||||
child.value.children.forEach(value => {
|
||||
if (child.property === 'font-weight' && child.value && child.value.children) {
|
||||
child.value.children.forEach((value) => {
|
||||
if (value.type === 'Identifier') {
|
||||
font.font_weight = value.name;
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
import { GraphLayout } from './widgets/graph-layout';
|
||||
import { LinksWidget } from './widgets/links';
|
||||
import { NodesWidget } from './widgets/nodes';
|
||||
import { DrawingsWidget } from './widgets/drawings';
|
||||
import { DrawingLineWidget } from './widgets/drawing-line';
|
||||
import { SelectionTool } from './tools/selection-tool';
|
||||
import { MovingTool } from './tools/moving-tool';
|
||||
import { LayersWidget } from './widgets/layers';
|
||||
import { LinkWidget } from './widgets/link';
|
||||
import { InterfaceStatusWidget } from './widgets/interface-status';
|
||||
import { InterfaceLabelWidget } from './widgets/interface-label';
|
||||
import { SelectionTool } from './tools/selection-tool';
|
||||
import { DrawingWidget } from './widgets/drawing';
|
||||
import { DrawingLineWidget } from './widgets/drawing-line';
|
||||
import { DrawingsWidget } from './widgets/drawings';
|
||||
import { EllipseDrawingWidget } from './widgets/drawings/ellipse-drawing';
|
||||
import { ImageDrawingWidget } from './widgets/drawings/image-drawing';
|
||||
import { LineDrawingWidget } from './widgets/drawings/line-drawing';
|
||||
import { RectDrawingWidget } from './widgets/drawings/rect-drawing';
|
||||
import { TextDrawingWidget } from './widgets/drawings/text-drawing';
|
||||
import { LineDrawingWidget } from './widgets/drawings/line-drawing';
|
||||
import { NodeWidget } from './widgets/node';
|
||||
import { DrawingWidget } from './widgets/drawing';
|
||||
import { GraphLayout } from './widgets/graph-layout';
|
||||
import { InterfaceLabelWidget } from './widgets/interface-label';
|
||||
import { InterfaceStatusWidget } from './widgets/interface-status';
|
||||
import { LabelWidget } from './widgets/label';
|
||||
import { LayersWidget } from './widgets/layers';
|
||||
import { LinkWidget } from './widgets/link';
|
||||
import { LinksWidget } from './widgets/links';
|
||||
import { NodeWidget } from './widgets/node';
|
||||
import { NodesWidget } from './widgets/nodes';
|
||||
|
||||
export const D3_MAP_IMPORTS = [
|
||||
GraphLayout,
|
||||
@ -37,5 +37,5 @@ export const D3_MAP_IMPORTS = [
|
||||
LineDrawingWidget,
|
||||
RectDrawingWidget,
|
||||
TextDrawingWidget,
|
||||
DrawingWidget
|
||||
DrawingWidget,
|
||||
];
|
||||
|
@ -20,7 +20,7 @@ export abstract class DataSource<T> {
|
||||
}
|
||||
|
||||
public set(data: T[]) {
|
||||
data.forEach(item => {
|
||||
data.forEach((item) => {
|
||||
const index = this.findIndex(item);
|
||||
if (index >= 0) {
|
||||
const updated = Object.assign(this.data[index], item);
|
||||
@ -31,9 +31,9 @@ export abstract class DataSource<T> {
|
||||
});
|
||||
|
||||
const toRemove = this.data.filter(
|
||||
item => data.filter(i => this.getItemKey(i) === this.getItemKey(item)).length === 0
|
||||
(item) => data.filter((i) => this.getItemKey(i) === this.getItemKey(item)).length === 0
|
||||
);
|
||||
toRemove.forEach(item => this.remove(item));
|
||||
toRemove.forEach((item) => this.remove(item));
|
||||
|
||||
this.dataChange.next(this.data);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user