Compare commits
823 Commits
cli
...
open199-cs
Author | SHA1 | Date | |
---|---|---|---|
f373f8cb63 | |||
f3ba1baa73 | |||
a06bb6e114 | |||
ead36b7097 | |||
acb7d4b807 | |||
420399ccbf | |||
6fb6f54cfa | |||
9a42cb4f7e | |||
b573b3a681 | |||
6558461fda | |||
4b23e3fbcb | |||
988323bdbd | |||
9eb8158c4e | |||
75d4be290c | |||
3b9cd5f1ac | |||
64a7647ec3 | |||
9ed10ba9da | |||
c211f413aa | |||
268a2c2427 | |||
c84de00e80 | |||
d6e2895666 | |||
7974ffdda2 | |||
d5858622ba | |||
9656e09066 | |||
845b1dcd6f | |||
2e959e8503 | |||
e6c9cbf0cd | |||
7849803a5d | |||
0263cf5407 | |||
fb0ba0cff9 | |||
573e5608fc | |||
37a7c2b1df | |||
4f0f9e4104 | |||
e6054b8252 | |||
38274728f6 | |||
49b3d67272 | |||
a864c172d5 | |||
400b992ec3 | |||
32815d8427 | |||
10a44c026c | |||
3e25d17702 | |||
9631d95a52 | |||
4ea757faa5 | |||
b5d1118a3f | |||
50d83eaffb | |||
30e6980dc6 | |||
5b9e43f8ff | |||
19d2970e0e | |||
a04b3f8a4b | |||
3ffa6f70aa | |||
0d07c3c289 | |||
29fdb6d641 | |||
b06a38da2f | |||
f45e236281 | |||
2e2b18eaa5 | |||
ee86209166 | |||
9f5729dbbc | |||
de9e41818b | |||
39d007470a | |||
285c8cbd1e | |||
3478f9d861 | |||
558ad94b91 | |||
c2e26b3555 | |||
c5c166c790 | |||
cc7df05a43 | |||
a7f277b0d2 | |||
5ced8e655d | |||
4de7b7dfb5 | |||
a9518e9890 | |||
4ed35cddde | |||
b9cd26aaf6 | |||
5882278f98 | |||
40b21e35fd | |||
2251a0c1e9 | |||
3a36389815 | |||
ba669f1395 | |||
b27b60aedc | |||
606667eb4d | |||
90c06cfc97 | |||
ec4c5864dc | |||
3ff275c853 | |||
cd3bdf4f81 | |||
a8d563975a | |||
ef5a26dfcc | |||
966e993c5d | |||
8363302caf | |||
9b5d894949 | |||
5dd15e3b20 | |||
d961b41253 | |||
564a822423 | |||
2b2ac0b0d9 | |||
f9a7ca85ac | |||
46b110e12f | |||
b7eb9491cb | |||
a92d13c10f | |||
4ad007f882 | |||
9f2303face | |||
51abd1fadf | |||
1ceb6d2d96 | |||
99512f41b9 | |||
93171230e3 | |||
5fdef59f3b | |||
16c3229a84 | |||
49a5ac833b | |||
646df81874 | |||
1058648e76 | |||
5b325a9698 | |||
f0e293a513 | |||
5f8d13672f | |||
4c0a79116a | |||
aa5734d023 | |||
ba8c2b8468 | |||
5a2f073975 | |||
1d0af0b3b6 | |||
6d2fe9d7eb | |||
c5736cafb1 | |||
08ecf00916 | |||
9f3c353ab4 | |||
e3cac49c4b | |||
93d969ad67 | |||
59ea2ea361 | |||
608df8f7b8 | |||
7dc6f553ac | |||
b30e72081c | |||
d60bf94501 | |||
a88fadcb49 | |||
7264a711a3 | |||
ae7a1618e8 | |||
d6d95fed19 | |||
d712a79ba4 | |||
04ce2f985a | |||
a14f30c03c | |||
bd85392b54 | |||
7c427e0b6e | |||
6cf8335f31 | |||
647a1403d0 | |||
1d9b8f34e2 | |||
adf119007b | |||
7114e9b150 | |||
76c1f5bfe9 | |||
33f88d30ed | |||
ffdcbece56 | |||
44eb723efb | |||
689f80bb23 | |||
a2db98d275 | |||
49b983cd3a | |||
ad60b9225e | |||
0c096db8bd | |||
fdf6148811 | |||
62e7adc0b0 | |||
72e0304fc0 | |||
e1110a2bc4 | |||
7172c45404 | |||
d8ced8f635 | |||
e3e44f74d6 | |||
acdd9622d2 | |||
2866574dc0 | |||
cfc9b61e25 | |||
066fd55590 | |||
c0dc30edb7 | |||
2a201df435 | |||
07179f7290 | |||
87684e0945 | |||
55d3a27917 | |||
1d13b245f9 | |||
e31d9decdc | |||
a5fa11749c | |||
2b92c1619e | |||
fd135a16af | |||
aed49d89e3 | |||
05f8739952 | |||
bf39aa1b1d | |||
4e79de6156 | |||
78004ebf37 | |||
51968954a9 | |||
64607b8e56 | |||
cb432051dc | |||
c184a9ce7c | |||
62e2114349 | |||
cca1928b82 | |||
81b136eab1 | |||
d059116782 | |||
bdc99950c6 | |||
76e15f2963 | |||
06436bb876 | |||
d8f3f0f430 | |||
177c1874b9 | |||
96a7c12d69 | |||
148a5eb248 | |||
31d3ec5d20 | |||
7564384b57 | |||
639546bf86 | |||
932e3cb7b0 | |||
cbffc221fb | |||
eef801f1ae | |||
d69cf6c6fe | |||
0a9c162f26 | |||
942fa46022 | |||
74aff1b407 | |||
2f658348a8 | |||
dbff9e2125 | |||
793ed7ebe6 | |||
bed1556a3a | |||
822b4ae96f | |||
99f3b986b6 | |||
fd4c1ea747 | |||
944a5a7424 | |||
dda2c89a58 | |||
c8cfbf5281 | |||
9f383ab101 | |||
063e97fcb5 | |||
7811d50372 | |||
e1c6c76612 | |||
aa2a835cb1 | |||
3741a02d2a | |||
f14cad4a39 | |||
c0ac3a0f96 | |||
09bae63de7 | |||
62b9eb5180 | |||
3f26be885e | |||
7ab318d57b | |||
65a33f8af5 | |||
331b4e9259 | |||
474afdf8ef | |||
3f4ccd93ab | |||
92cf86837b | |||
5274923c49 | |||
a356e01b14 | |||
21a37db15b | |||
a20bbd98f5 | |||
5b3f780204 | |||
43e920d3b6 | |||
8ca22cc510 | |||
3443780ac7 | |||
8e85675732 | |||
2bdc95eb95 | |||
f2efb07d93 | |||
863c3f1720 | |||
b73f9fc19e | |||
10e711f717 | |||
529dde57b9 | |||
7d1a1acc11 | |||
5e1b0f38b7 | |||
4e69ca50fb | |||
05481dcab5 | |||
fa7131ad5c | |||
bd1c3cb7da | |||
cbd21212d1 | |||
5cd458a733 | |||
2f90a89065 | |||
4312857fd4 | |||
6c4c53dde7 | |||
e49b55024f | |||
5f1f54fa91 | |||
f4325e2bb3 | |||
e09cf91def | |||
ff1e1251f6 | |||
5697a39ec3 | |||
32fb84a3cd | |||
2815d97682 | |||
ab01f64cea | |||
e5aa2b4f87 | |||
522ce02302 | |||
e32eb11e60 | |||
bda1bf9f9a | |||
226f0932da | |||
15f9bc083c | |||
1c4a4e475b | |||
f7839b758d | |||
ac529be55c | |||
99376391a9 | |||
2c7c7b90e6 | |||
903778799f | |||
9523c918fb | |||
09be19310b | |||
b8b9b1f79a | |||
4300338b9c | |||
6a42d0c7a1 | |||
c0ed19fd92 | |||
df484c1800 | |||
5940f94644 | |||
0dccaab9cb | |||
c8848b5788 | |||
8d65335786 | |||
2d1faeba8c | |||
cecc52f0a9 | |||
a1d765f271 | |||
fe12cdefc5 | |||
648cdcc86e | |||
946a6d4a04 | |||
f7588d57c2 | |||
91a4138334 | |||
141a54cbd6 | |||
64c6ef6cfd | |||
fe8d9f6717 | |||
c913f173e3 | |||
ae928a138c | |||
d926110b4e | |||
485e6a9de1 | |||
1e6731e6f2 | |||
454a63e1f1 | |||
b487fa4438 | |||
560454e7c2 | |||
04594ea536 | |||
b5b6546710 | |||
a45dfc3822 | |||
f7f6b8d612 | |||
e4a14b7603 | |||
5706fa4567 | |||
796d6b800a | |||
b12bb55495 | |||
f42498ab60 | |||
ec56fe7bfd | |||
4abb48abd8 | |||
7f571415dc | |||
4f9a65a5fe | |||
6db7f056dc | |||
5a1d774b47 | |||
101e3bb346 | |||
a38d4829eb | |||
d5f1d45759 | |||
5ed34c1c30 | |||
bc82a5bf7e | |||
5af3d575a2 | |||
58198636ed | |||
86bf6c6dff | |||
0e07fb860e | |||
b3d4f48e2e | |||
b6d08726fb | |||
675c5be3da | |||
4eaeea1e14 | |||
f44819a7fe | |||
1dbd721b14 | |||
05722d9b11 | |||
92a3fa3e4c | |||
ddebbf119f | |||
8c4fdf5c1c | |||
dd83662e0f | |||
1b0ce7166d | |||
9c90eb52a4 | |||
a0c6ddff5a | |||
f51230b3f7 | |||
660e9f0d4f | |||
59b24d91bb | |||
df3b0bd6fb | |||
5b475c9f64 | |||
a48370abd3 | |||
54d608adb2 | |||
5fba6f5ead | |||
b177c38656 | |||
11ca39b94c | |||
bb0e27ce1f | |||
56e8cd81e6 | |||
e37fa75289 | |||
ee314ab387 | |||
59cd346911 | |||
e7e66bff4b | |||
ca62cc9066 | |||
01b6fda1f2 | |||
ae0cb63a92 | |||
5604bf6d69 | |||
c5fcc5a558 | |||
ea9f607bba | |||
0404303042 | |||
5677548298 | |||
bcc42d705e | |||
ab008ae497 | |||
8fb6ab61ba | |||
3d59f6df0b | |||
929f06e6c1 | |||
e9e6ddd791 | |||
2539e4008f | |||
4708ac0ec1 | |||
bd984abc0f | |||
b4a44dee8f | |||
942f617bd8 | |||
757cb0f015 | |||
90389ea910 | |||
d1bc93cd31 | |||
0541f6edfa | |||
0ad22f6842 | |||
134d853f19 | |||
00c0019122 | |||
e80d094174 | |||
3e7264d6b8 | |||
60ba80d307 | |||
c89aa026b0 | |||
8a3f77d784 | |||
15a5c593fa | |||
fc704b8056 | |||
0a19ab4389 | |||
9e8152719f | |||
55745d281f | |||
8ba112498b | |||
44fc9423df | |||
bd8bbc6e8f | |||
2ee53b17db | |||
60e97eb94a | |||
ce5a650d8c | |||
5ff2e6b652 | |||
f30a2dd791 | |||
920c83771d | |||
a2d06583ca | |||
cc8a7e513f | |||
9dce3a04cc | |||
18cdaf1b53 | |||
e5d4376f06 | |||
6784c6567b | |||
71618ce4b9 | |||
e5ebbdaf7f | |||
6b805183b0 | |||
9723c65016 | |||
5d5425db04 | |||
7bd0e279b0 | |||
caee1f520f | |||
a8856c0612 | |||
b375ede217 | |||
0bd1d53d25 | |||
3fe386fcd6 | |||
74f289cb34 | |||
82b321b3f9 | |||
3bdaae292e | |||
b627de45ba | |||
2056f3aed0 | |||
b928b7d3f2 | |||
df6cd8f403 | |||
c6b7121cf0 | |||
86c61f7543 | |||
741fc57442 | |||
daed6a5b06 | |||
498f854bef | |||
77a1a90905 | |||
19bdf743fc | |||
f655346f46 | |||
20cb2ff239 | |||
7d42292184 | |||
ed9a5b0890 | |||
aa23d358cc | |||
fd582d45d2 | |||
0f34d38451 | |||
f8ee244475 | |||
322d1c8389 | |||
c45bf45475 | |||
8ee4fc9b71 | |||
99c977ce9d | |||
85809ae1e1 | |||
4ec243c6fb | |||
94649b12fd | |||
407d9881ff | |||
aa3cf70b22 | |||
6ee622b3f5 | |||
95ea33b441 | |||
099d70b8d9 | |||
3d996ac466 | |||
896dd8d2c7 | |||
789b640b9b | |||
90828ef63d | |||
8acf01ebdf | |||
ddb567aeb5 | |||
17b3378655 | |||
efd209826d | |||
a43c8f2ce8 | |||
fffe07e7e6 | |||
26db524f0e | |||
4fcef33c58 | |||
dc9369c0f1 | |||
c5b786e5e0 | |||
3e0534c4c3 | |||
19ad4c8174 | |||
8159c365b5 | |||
307047d3ac | |||
83f135e48c | |||
29bdc9d574 | |||
a7ea4c3c6e | |||
bf24ac7c93 | |||
e05858e26b | |||
89046ecad5 | |||
fa7431d68b | |||
78b528b4a5 | |||
1d3870d07f | |||
2452b25fd4 | |||
0c4d422e2d | |||
a283a2a0d3 | |||
827e1af581 | |||
57f11a9767 | |||
3687cc5edd | |||
bf17b77e82 | |||
536d5616d4 | |||
59f094763b | |||
e3ef68bc6f | |||
83276d70d3 | |||
111b3bac09 | |||
67cf8d8cee | |||
b4dd95490c | |||
16e4c32709 | |||
a154c9c870 | |||
1e71df5ce9 | |||
5e9f38dadd | |||
552435b009 | |||
109ae3323d | |||
4f27104663 | |||
0053989de8 | |||
b98c1cdfe8 | |||
0628398b01 | |||
4ff03b081d | |||
e8d7093eb5 | |||
9bc4327c59 | |||
c0fda5b572 | |||
950578f09b | |||
117470068a | |||
0d47b7c47d | |||
c882b2d4c3 | |||
794231143e | |||
6b42d3bf4b | |||
296d9f5acd | |||
1c5101eca6 | |||
7468c0e150 | |||
dc5feb8b1a | |||
0fb9f3731a | |||
3080861764 | |||
dbebf08500 | |||
847c356063 | |||
06bcd28558 | |||
f88e8ebb51 | |||
6d2b2fd81e | |||
608800ae63 | |||
07818b0a6d | |||
fdfb524eef | |||
ef250f58de | |||
15ed91f651 | |||
074254a513 | |||
4c84789d5d | |||
496cf85b7e | |||
833f57e284 | |||
cc97408433 | |||
93f8e61c40 | |||
92573b817f | |||
9a63e99710 | |||
21739fffd9 | |||
5382cca435 | |||
77d81f899b | |||
fe3263fdfe | |||
ce42429fbd | |||
76151d09a0 | |||
ec7e6cc5b4 | |||
1ddce48f7e | |||
98b5ff3c77 | |||
14094a48fc | |||
15c1bf20ab | |||
685dd2114d | |||
6e30a25a6f | |||
be79c104fb | |||
6d08c81b3b | |||
42fa5bfd7e | |||
89e763b515 | |||
2a1388772a | |||
8e2a2eeba5 | |||
fb0ce1eca8 | |||
fa3821b50f | |||
0f63e4dde9 | |||
12efb47be7 | |||
a2fce8e56c | |||
78e5c0143b | |||
099591ad2e | |||
b5505f372f | |||
9ad860babd | |||
87e317a6f5 | |||
d7bd793bf3 | |||
9d17768327 | |||
688718cad0 | |||
efb7611f6e | |||
d3ff0a258e | |||
4f18663c71 | |||
8c2a29e895 | |||
821a1a485c | |||
f08725b6a2 | |||
301b73c6c6 | |||
912e70d219 | |||
1d41939418 | |||
ee382be38d | |||
34ea3ad9bb | |||
2ba6f18c59 | |||
b2a09599a0 | |||
11264759ec | |||
c0ff6de27b | |||
60dda8a7a4 | |||
9cc0c0b06f | |||
5b617295e9 | |||
53a3a2f459 | |||
64fae21d16 | |||
87f48aac35 | |||
e43a788a6d | |||
fa487e026e | |||
3701fd75dd | |||
d787e84fd4 | |||
1922e1e241 | |||
e52f53b7ff | |||
d1be256691 | |||
82ae9e72c1 | |||
c703714cb3 | |||
b48a07cd3e | |||
8c29c8ed0e | |||
85300d3743 | |||
5763511ec8 | |||
2accf21518 | |||
28c42fcd4c | |||
fe3e3325e1 | |||
2b97d61d6c | |||
1efa97e6f5 | |||
756f728865 | |||
d8276c532b | |||
fc0bfa77db | |||
12c6e53939 | |||
4f716ad5c5 | |||
8093fcbda1 | |||
0ea5721f76 | |||
d902943552 | |||
5f7c8ccadb | |||
520d17f9db | |||
7532db5f49 | |||
ebd8fdeee3 | |||
954fdd5906 | |||
f738f84075 | |||
cc19a0acba | |||
8267058487 | |||
4a913376ac | |||
5ff3c71523 | |||
ba614fe2d6 | |||
5e713f279b | |||
df590107cb | |||
fc8630dbc6 | |||
12a94f828a | |||
0e840ae003 | |||
e1e5919f68 | |||
b2cd66bd5d | |||
af1fa6e77a | |||
5ff90f7254 | |||
0ca9e5c952 | |||
dbcad51325 | |||
8ee93d9603 | |||
ac59df9595 | |||
182eff977c | |||
3af23b7bc5 | |||
7f529eec68 | |||
ad4292f1e9 | |||
6840e596a5 | |||
30fd8c451e | |||
bf0014f1b9 | |||
2aeebff652 | |||
471a25a625 | |||
134b749bbf | |||
36d06e8b54 | |||
5520d90984 | |||
77b0086d18 | |||
d606ee421f | |||
926aed72c3 | |||
146e948097 | |||
669b434c36 | |||
431c74ca49 | |||
cd0c0f77cc | |||
8cba321886 | |||
dd83816035 | |||
1ca2b769d9 | |||
7014808c13 | |||
a1d1261179 | |||
99048a4ee3 | |||
553b17fafe | |||
c4aff95341 | |||
13095b4135 | |||
fd927d4c03 | |||
445f22ccb0 | |||
1ad0bf337c | |||
73dc16d398 | |||
bebe53820f | |||
dfe909d6b5 | |||
3cf62ded08 | |||
6cbd3e5fae | |||
3050b265fb | |||
5104a7990a | |||
571beb8df2 | |||
bea5002752 | |||
d04c5e6858 | |||
0d1f3bf87a | |||
b632926d8e | |||
78f3f8367e | |||
85ac4a9a32 | |||
ef527df381 | |||
c2868a4573 | |||
77c66053f3 | |||
0891e15936 | |||
2979ee90a3 | |||
77c399f2a2 | |||
fe8543158e | |||
37dede568c | |||
a4f3e0d776 | |||
866c8882ca | |||
ad7d3d642e | |||
333f7cb848 | |||
f198c281bc | |||
23de3917bb | |||
badaca53d3 | |||
00ac249ee2 | |||
00aa6821d1 | |||
b3fb06ba3f | |||
e33485ec59 | |||
afb1202865 | |||
f5a4a370f9 | |||
2848a8458b | |||
cbaf45afe9 | |||
7a677062e4 | |||
a7153f320f | |||
b7a612127d | |||
b3da6edd0c | |||
ff1fd26efc | |||
4ced6c44a6 | |||
67f627b51f | |||
1d83516982 | |||
9e64dfe3b9 | |||
09f5fa42ab | |||
54a077a4e2 | |||
13525a67c2 | |||
2f4cf44229 | |||
cc6b6538d5 | |||
0c7de98195 | |||
404d1e7801 | |||
1214a32c26 | |||
6bd8e7a47c | |||
825d93cee3 | |||
73e959f95a | |||
9f7dc1da9b | |||
3d8aec2d01 | |||
928e31b548 | |||
f182d1f2c4 | |||
d238b669a5 | |||
5d5a7c26c5 | |||
0b0cee3afb | |||
0260e6fff4 | |||
9811443c71 | |||
7dc13dab66 | |||
e67a2e63cf | |||
f4e53a946d | |||
de71bde62f | |||
8f24e014e0 | |||
190f5fd0ea | |||
ad29fb0f92 | |||
fcd073c010 | |||
071368c3b9 | |||
7a97588aa5 | |||
f776561303 | |||
e34fe1a289 | |||
70d9587c9b | |||
9a78b63065 | |||
6c497f3c36 | |||
d951b794e3 | |||
797046aca4 | |||
cf76583ed7 | |||
6f28ab0145 | |||
9ebf157ec0 | |||
493c63be44 | |||
f29951140f | |||
d0b5bb2d21 | |||
cd98886a43 | |||
4549828cae | |||
8ce8080253 | |||
96f72b3765 | |||
c932e953bc | |||
d0478c3433 | |||
53369ec0dc | |||
de99969f0a | |||
24449d2dcc | |||
f42c5ca1e5 | |||
890aafc203 | |||
2a14cf2dfc | |||
62962e119e | |||
2229e868ce | |||
8d209f4d19 | |||
86bb89a162 | |||
2758250833 | |||
7d20351a6a | |||
78fae345da | |||
4c79c9a1b1 | |||
2ec9956d44 | |||
e3b191b5dc | |||
a4dda695dd | |||
0d710209b1 | |||
fdbc91131b | |||
d2dfec3ce7 | |||
351181d38e | |||
760f4b818f | |||
c026bfa17d | |||
47b97a504e | |||
29c460556a | |||
4d276888e1 | |||
142af3db77 | |||
b66759e519 | |||
c58ffb4a52 | |||
600ff1a3ee | |||
77d11e1bcf | |||
d158aa6028 | |||
c2985d61b7 | |||
3ce40ab870 | |||
bfb19dea74 | |||
01a6d2e6a7 | |||
af462ff3ee | |||
5c1d209eff | |||
8a76c3a425 | |||
9ccd0b9188 | |||
f83588d980 | |||
a481b377cb | |||
35ff4efbca | |||
436e010738 | |||
bf4765fcb6 | |||
dbfb8b9861 | |||
681cd0bb9c | |||
b668fb58fb | |||
f74da6b935 | |||
e4dec21ceb | |||
fc2860810b | |||
9d6b70f433 | |||
57a947eaef | |||
a18cc50a43 | |||
91fe3d798f | |||
e873389655 |
2
.gitignore
vendored
@ -28,3 +28,5 @@ node_modules
|
|||||||
# Protractor logs
|
# Protractor logs
|
||||||
protractor/logs
|
protractor/logs
|
||||||
|
|
||||||
|
# npm-debug log
|
||||||
|
npm-debug.log
|
||||||
|
35
LICENSES.md
@ -345,6 +345,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### moment-duration-format
|
||||||
|
|
||||||
|
#### Info
|
||||||
|
|
||||||
|
* Link: https://github.com/jsmreese/moment-duration-format
|
||||||
|
|
||||||
|
* Version: 1.3.0
|
||||||
|
|
||||||
|
* Authors: John Madhavan-Reese
|
||||||
|
|
||||||
|
* Description: Duration parsing/formatting
|
||||||
|
|
||||||
|
#### License
|
||||||
|
|
||||||
|
Copyright 2014 John Madhavan-Reese
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Json.NET
|
### Json.NET
|
||||||
|
|
||||||
#### Info
|
#### Info
|
||||||
|
2
Procfile
@ -1 +1 @@
|
|||||||
web: node app.js --port $PORT --include example/localstorage
|
web: node app.js --port $PORT
|
||||||
|
15
README.md
@ -103,6 +103,21 @@ This build will:
|
|||||||
|
|
||||||
Run as `mvn clean install`.
|
Run as `mvn clean install`.
|
||||||
|
|
||||||
|
### Building Documentation
|
||||||
|
|
||||||
|
Open MCT Web's documentation is generated by an
|
||||||
|
[npm](https://www.npmjs.com/)-based build:
|
||||||
|
|
||||||
|
* `npm install` _(only needs to run once)_
|
||||||
|
* `npm run docs`
|
||||||
|
|
||||||
|
Documentation will be generated in `target/docs`. Note that diagram
|
||||||
|
generation is dependent on having [Cairo](http://cairographics.org/download/)
|
||||||
|
installed; see
|
||||||
|
[node-canvas](https://github.com/Automattic/node-canvas#installation)'s
|
||||||
|
documentation for help with installation.
|
||||||
|
|
||||||
|
|
||||||
# Glossary
|
# Glossary
|
||||||
|
|
||||||
Certain terms are used throughout Open MCT Web with consistent meanings
|
Certain terms are used throughout Open MCT Web with consistent meanings
|
||||||
|
@ -6,26 +6,32 @@
|
|||||||
"platform/commonUI/browse",
|
"platform/commonUI/browse",
|
||||||
"platform/commonUI/edit",
|
"platform/commonUI/edit",
|
||||||
"platform/commonUI/dialog",
|
"platform/commonUI/dialog",
|
||||||
|
"platform/commonUI/formats",
|
||||||
"platform/commonUI/general",
|
"platform/commonUI/general",
|
||||||
"platform/commonUI/inspect",
|
"platform/commonUI/inspect",
|
||||||
"platform/commonUI/mobile",
|
"platform/commonUI/mobile",
|
||||||
"platform/commonUI/themes/espresso",
|
"platform/commonUI/themes/espresso",
|
||||||
|
"platform/commonUI/notification",
|
||||||
"platform/containment",
|
"platform/containment",
|
||||||
"platform/execution",
|
"platform/execution",
|
||||||
"platform/telemetry",
|
"platform/telemetry",
|
||||||
|
"platform/features/clock",
|
||||||
|
"platform/features/events",
|
||||||
"platform/features/imagery",
|
"platform/features/imagery",
|
||||||
"platform/features/layout",
|
"platform/features/layout",
|
||||||
"platform/features/pages",
|
"platform/features/pages",
|
||||||
"platform/features/plot",
|
"platform/features/plot",
|
||||||
"platform/features/scrolling",
|
"platform/features/scrolling",
|
||||||
"platform/features/events",
|
"platform/features/timeline",
|
||||||
"platform/forms",
|
"platform/forms",
|
||||||
"platform/identity",
|
"platform/identity",
|
||||||
|
"platform/persistence/aggregator",
|
||||||
"platform/persistence/local",
|
"platform/persistence/local",
|
||||||
"platform/persistence/queue",
|
"platform/persistence/queue",
|
||||||
"platform/policy",
|
"platform/policy",
|
||||||
"platform/entanglement",
|
"platform/entanglement",
|
||||||
"platform/search",
|
"platform/search",
|
||||||
|
"platform/status",
|
||||||
|
|
||||||
"example/imagery",
|
"example/imagery",
|
||||||
"example/eventGenerator",
|
"example/eventGenerator",
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
test:
|
||||||
|
override:
|
||||||
|
- exit 0
|
||||||
deployment:
|
deployment:
|
||||||
production:
|
production:
|
||||||
branch: master
|
branch: master
|
||||||
@ -5,7 +8,7 @@ deployment:
|
|||||||
- ./build-docs.sh
|
- ./build-docs.sh
|
||||||
- git push git@heroku.com:openmctweb-demo.git $CIRCLE_SHA1:refs/heads/master
|
- git push git@heroku.com:openmctweb-demo.git $CIRCLE_SHA1:refs/heads/master
|
||||||
openmctweb-staging-un:
|
openmctweb-staging-un:
|
||||||
branch: search
|
branch: open199
|
||||||
heroku:
|
heroku:
|
||||||
appname: openmctweb-staging-un
|
appname: openmctweb-staging-un
|
||||||
openmctweb-staging-deux:
|
openmctweb-staging-deux:
|
||||||
|
9
docs/footer.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<hr>
|
||||||
|
<cite>
|
||||||
|
This document is styled using
|
||||||
|
<a href="https://github.com/jasonm23/markdown-css-themes">
|
||||||
|
https://github.com/jasonm23/markdown-css-themes
|
||||||
|
</a>.
|
||||||
|
</cite>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -20,7 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*global require,process,GLOBAL*/
|
/*global require,process,__dirname,GLOBAL*/
|
||||||
/*jslint nomen: false */
|
/*jslint nomen: false */
|
||||||
|
|
||||||
|
|
||||||
@ -30,7 +30,8 @@
|
|||||||
var CONSTANTS = {
|
var CONSTANTS = {
|
||||||
DIAGRAM_WIDTH: 800,
|
DIAGRAM_WIDTH: 800,
|
||||||
DIAGRAM_HEIGHT: 500
|
DIAGRAM_HEIGHT: 500
|
||||||
};
|
},
|
||||||
|
TOC_HEAD = "# Table of Contents";
|
||||||
|
|
||||||
GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be defined
|
GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be defined
|
||||||
(function () {
|
(function () {
|
||||||
@ -44,7 +45,10 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
|||||||
split = require("split"),
|
split = require("split"),
|
||||||
stream = require("stream"),
|
stream = require("stream"),
|
||||||
nomnoml = require('nomnoml'),
|
nomnoml = require('nomnoml'),
|
||||||
|
toc = require("markdown-toc"),
|
||||||
Canvas = require('canvas'),
|
Canvas = require('canvas'),
|
||||||
|
header = fs.readFileSync(path.resolve(__dirname, 'header.html')),
|
||||||
|
footer = fs.readFileSync(path.resolve(__dirname, 'footer.html')),
|
||||||
options = require("minimist")(process.argv.slice(2));
|
options = require("minimist")(process.argv.slice(2));
|
||||||
|
|
||||||
// Convert from nomnoml source to a target PNG file.
|
// Convert from nomnoml source to a target PNG file.
|
||||||
@ -110,9 +114,12 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
|||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
transform._flush = function (done) {
|
transform._flush = function (done) {
|
||||||
this.push("<html><body>\n");
|
// Prepend table of contents
|
||||||
|
markdown =
|
||||||
|
[ TOC_HEAD, toc(markdown).content, "", markdown ].join("\n");
|
||||||
|
this.push(header);
|
||||||
this.push(marked(markdown));
|
this.push(marked(markdown));
|
||||||
this.push("\n</body></html>\n");
|
this.push(footer);
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
return transform;
|
return transform;
|
||||||
@ -133,8 +140,8 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
|||||||
customRenderer.link = function (href, title, text) {
|
customRenderer.link = function (href, title, text) {
|
||||||
// ...but only if they look like relative paths
|
// ...but only if they look like relative paths
|
||||||
return (href || "").indexOf(":") === -1 && href[0] !== "/" ?
|
return (href || "").indexOf(":") === -1 && href[0] !== "/" ?
|
||||||
renderer.link(href.replace(/\.md/, ".html"), title, text) :
|
renderer.link(href.replace(/\.md/, ".html"), title, text) :
|
||||||
renderer.link.apply(renderer, arguments);
|
renderer.link.apply(renderer, arguments);
|
||||||
};
|
};
|
||||||
return customRenderer;
|
return customRenderer;
|
||||||
}
|
}
|
||||||
@ -179,13 +186,17 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
|||||||
glob(options['in'] + "/**/*.@(html|css|png)", {}, function (err, files) {
|
glob(options['in'] + "/**/*.@(html|css|png)", {}, function (err, files) {
|
||||||
files.forEach(function (file) {
|
files.forEach(function (file) {
|
||||||
var destination = file.replace(options['in'], options.out),
|
var destination = file.replace(options['in'], options.out),
|
||||||
destPath = path.dirname(destination);
|
destPath = path.dirname(destination),
|
||||||
|
streamOptions = {};
|
||||||
|
if (file.match(/png$/)) {
|
||||||
|
streamOptions.encoding = null;
|
||||||
|
} else {
|
||||||
|
streamOptions.encoding = 'utf8';
|
||||||
|
}
|
||||||
|
|
||||||
mkdirp(destPath, function (err) {
|
mkdirp(destPath, function (err) {
|
||||||
fs.createReadStream(file, { encoding: 'utf8' })
|
fs.createReadStream(file, streamOptions)
|
||||||
.pipe(fs.createWriteStream(destination, {
|
.pipe(fs.createWriteStream(destination, streamOptions));
|
||||||
encoding: 'utf8'
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
7
docs/header.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="http://jasonm23.github.io/markdown-css-themes/avenir-white.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
@ -58,13 +58,13 @@ of the software.
|
|||||||
|
|
||||||
These layers are:
|
These layers are:
|
||||||
|
|
||||||
* [_Framework_](Framework.md): The framework layer is responsible for
|
* [_Framework_](framework.md): The framework layer is responsible for
|
||||||
managing the interactions between application components. It has no
|
managing the interactions between application components. It has no
|
||||||
application-specific knowledge; at this layer, we have only
|
application-specific knowledge; at this layer, we have only
|
||||||
established an abstraction by which different software components
|
established an abstraction by which different software components
|
||||||
may communicate and/or interact.
|
may communicate and/or interact.
|
||||||
* [_Platform_](Platform.md): The platform layer defines the general look, feel, and
|
* [_Platform_](platform.md): The platform layer defines the general look,
|
||||||
behavior of Open MCT Web. This includes user-facing components like
|
feel, and behavior of Open MCT Web. This includes user-facing components like
|
||||||
Browse mode and Edit mode, as well as underlying elements of the
|
Browse mode and Edit mode, as well as underlying elements of the
|
||||||
information model and the general service infrastructure.
|
information model and the general service infrastructure.
|
||||||
* _Application_: The application layer defines specific features of
|
* _Application_: The application layer defines specific features of
|
||||||
|
@ -35,16 +35,26 @@ in __any of these tiers__.
|
|||||||
* _DOM_: The rendered HTML document, composed from HTML templates which
|
* _DOM_: The rendered HTML document, composed from HTML templates which
|
||||||
have been processed by AngularJS and will be updated by AngularJS
|
have been processed by AngularJS and will be updated by AngularJS
|
||||||
to reflect changes from the presentation layer. User interactions
|
to reflect changes from the presentation layer. User interactions
|
||||||
are initiated from here and invoke behavior in the presentation layer.
|
are initiated from here and invoke behavior in the presentation layer. HTML
|
||||||
|
templates are written in Angular’s template syntax; see the [Angular documentation on templates](https://docs.angularjs.org/guide/templates).
|
||||||
|
These describe the page as actually seen by the user. Conceptually,
|
||||||
|
stylesheets (controlling the lookandfeel of the rendered templates) belong
|
||||||
|
in this grouping as well.
|
||||||
* [_Presentation layer_](#presentation-layer): The presentation layer
|
* [_Presentation layer_](#presentation-layer): The presentation layer
|
||||||
is responsible for updating (and providing information to update)
|
is responsible for updating (and providing information to update)
|
||||||
the displayed state of the application. The presentation layer consists
|
the displayed state of the application. The presentation layer consists
|
||||||
primarily of _controllers_ and _directives_. The presentation layer is
|
primarily of _controllers_ and _directives_. The presentation layer is
|
||||||
concerned with inspecting the information model and preparing it for
|
concerned with inspecting the information model and preparing it for
|
||||||
display.
|
display.
|
||||||
* [_Information model_](#information-model): The information model
|
* [_Information model_](#information-model): Provides a common (within Open MCT
|
||||||
describes the state and behavior of the objects with which the user
|
Web) set of interfaces for dealing with “things” domain objects within the
|
||||||
interacts.
|
system. Userfacing concerns in a Open MCT Web application are expressed as
|
||||||
|
domain objects; examples include folders (used to organize other domain
|
||||||
|
objects), layouts (used to build displays), or telemetry points (used as
|
||||||
|
handles for streams of remote measurements.) These domain objects expose a
|
||||||
|
common set of interfaces to allow reusable user interfaces to be built in the
|
||||||
|
presentation and template tiers; the specifics of these behaviors are then
|
||||||
|
mapped to interactions with underlying services.
|
||||||
* [_Service infrastructure_](#service-infrastructure): The service
|
* [_Service infrastructure_](#service-infrastructure): The service
|
||||||
infrastructure is responsible for providing the underlying general
|
infrastructure is responsible for providing the underlying general
|
||||||
functionality needed to support the information model. This includes
|
functionality needed to support the information model. This includes
|
||||||
@ -52,7 +62,9 @@ in __any of these tiers__.
|
|||||||
back-end.
|
back-end.
|
||||||
* _Back-end_: The back-end is out of the scope of Open MCT Web, except
|
* _Back-end_: The back-end is out of the scope of Open MCT Web, except
|
||||||
for the interfaces which are utilized by adapters participating in the
|
for the interfaces which are utilized by adapters participating in the
|
||||||
service infrastructure.
|
service infrastructure. Includes the underlying persistence stores, telemetry
|
||||||
|
streams, and so forth which the Open MCT Web client is being used to interact
|
||||||
|
with.
|
||||||
|
|
||||||
## Application Start-up
|
## Application Start-up
|
||||||
|
|
@ -29,8 +29,10 @@
|
|||||||
Sections:
|
Sections:
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="api/">API</a></li>
|
<li><a href="api/">API</a></li>
|
||||||
<li><a href="guide/">Developer Guide</a></li>
|
|
||||||
<li><a href="architecture/">Architecture Overview</a></li>
|
<li><a href="architecture/">Architecture Overview</a></li>
|
||||||
|
<li><a href="guide/">Developer Guide</a></li>
|
||||||
|
<li><a href="tutorials/">Tutorials</a></li>
|
||||||
|
<li><a href="process/">Development Process</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
156
docs/src/process/index.md
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
# Development Cycle
|
||||||
|
|
||||||
|
Development of Open MCT Web occurs on an iterative cycle of
|
||||||
|
sprints and releases.
|
||||||
|
|
||||||
|
* A _sprint_ is three weeks in duration, and represents a
|
||||||
|
set of improvements that can be completed and tested by the
|
||||||
|
development team. Software at the end of the sprint is
|
||||||
|
"semi-stable"; it will have undergone reduced testing and may carry
|
||||||
|
defects or usability issues of lower severity, particularly if
|
||||||
|
there are workarounds.
|
||||||
|
* A _release_ occurs every four sprints. Releases are stable, and
|
||||||
|
will have undergone full acceptance testing to ensure that the
|
||||||
|
software behaves correctly and usably.
|
||||||
|
|
||||||
|
## Roles
|
||||||
|
|
||||||
|
The sprint process assumes the presence of a __project manager.__
|
||||||
|
The project manager is responsible for
|
||||||
|
making tactical decisions about what development work will be
|
||||||
|
performed, and for coordinating with stakeholders to arrive at
|
||||||
|
higher-level strategic decisions about desired functionality
|
||||||
|
and characteristics of the software, major external milestones,
|
||||||
|
and so forth.
|
||||||
|
|
||||||
|
In the absence of a dedicated project manager, this role may be rotated
|
||||||
|
among members of the development team on a per-sprint basis.
|
||||||
|
|
||||||
|
Responsibilities of the project manager including:
|
||||||
|
|
||||||
|
* Maintaining (with agreement of stakeholders) a "road map" of work
|
||||||
|
planned for future releases/sprints; this should be higher-level,
|
||||||
|
usually expressed as "themes",
|
||||||
|
with just enough specificity to gauge feasibility of plans,
|
||||||
|
relate work back to milestones, and identify longer-term
|
||||||
|
dependencies.
|
||||||
|
* Determining (with assistance from the rest of the team) which
|
||||||
|
issues to work on in a given sprint and how they shall be
|
||||||
|
assigned.
|
||||||
|
* Pre-planning subsequent sprints to ensure that all members of the
|
||||||
|
team always have a clear direction.
|
||||||
|
* Scheduling and/or ensuring adherence to
|
||||||
|
[process points](#process-points).
|
||||||
|
* Responding to changes within the sprint (shifting priorities,
|
||||||
|
new issues) and re-allocating work for the sprint as needed.
|
||||||
|
|
||||||
|
## Sprint Calendar
|
||||||
|
|
||||||
|
Certain [process points](#process-points) are regularly scheduled in
|
||||||
|
the sprint cycle.
|
||||||
|
|
||||||
|
### Sprints by Release
|
||||||
|
|
||||||
|
Allocation of work among sprints should be planned relative to release
|
||||||
|
goals and milestones. As a general guideline, higher-risk work (large
|
||||||
|
new features which may carry new defects, major refactoring, design
|
||||||
|
changes with uncertain effects on usability) should be allocated to
|
||||||
|
earlier sprints, allowing for time in later sprints to ensure stability.
|
||||||
|
|
||||||
|
| Sprint | Focus |
|
||||||
|
|:------:|:--------------------------------------------------------|
|
||||||
|
| __1__ | Prototyping, design, experimentation. |
|
||||||
|
| __2__ | New features, refinements, enhancements. |
|
||||||
|
| __3__ | Feature completion, low-risk enhancements, bug fixing. |
|
||||||
|
| __4__ | Stability & quality assurance. |
|
||||||
|
|
||||||
|
### Sprints 1-3
|
||||||
|
|
||||||
|
The first three sprints of a release are primarily centered around
|
||||||
|
development work, with regular acceptance testing in the third
|
||||||
|
week. During this third week, the top priority should be passing
|
||||||
|
acceptance testing (e.g. by resolving any blockers found); any
|
||||||
|
resources not needed for this effort should be used to begin work
|
||||||
|
for the subsequent sprint.
|
||||||
|
|
||||||
|
| Week | Mon | Tue | Wed | Thu | Fri |
|
||||||
|
|:-----:|:-------------------------:|:------:|:---:|:----------------------------:|:-----------:|
|
||||||
|
| __1__ | Sprint plan | Tag-up | | | |
|
||||||
|
| __2__ | | Tag-up | | | Code freeze |
|
||||||
|
| __3__ | Sprint acceptance testing | Triage | | _Sprint acceptance testing*_ | Ship |
|
||||||
|
|
||||||
|
* If necessary.
|
||||||
|
|
||||||
|
### Sprint 4
|
||||||
|
|
||||||
|
The software must be stable at the end of the fourth sprint; because of
|
||||||
|
this, the fourth sprint is scheduled differently, with a heightened
|
||||||
|
emphasis on testing.
|
||||||
|
|
||||||
|
| Week | Mon | Tue | Wed | Thu | Fri |
|
||||||
|
|-------:|:-------------------------:|:------:|:---:|:----------------------------:|:-----------:|
|
||||||
|
| __1__ | Sprint plan | Tag-up | | | Code freeze |
|
||||||
|
| __2__ | Acceptance testing | Triage | | | |
|
||||||
|
| __3__ | _Acceptance testing*_ | Triage | | _Acceptance testing*_ | Ship |
|
||||||
|
|
||||||
|
* If necessary.
|
||||||
|
|
||||||
|
## Process Points
|
||||||
|
|
||||||
|
* __Sprint plan.__ Project manager allocates issues based on
|
||||||
|
theme(s) for sprint, then reviews with team. Each team member
|
||||||
|
should have roughly two weeks of work allocated (to allow time
|
||||||
|
in the third week for testing of work completed.)
|
||||||
|
* Project manager should also sketch out subsequent sprint so
|
||||||
|
that team may begin work for that sprint during the
|
||||||
|
third week, since testing and blocker resolution is unlikely
|
||||||
|
to require all available resources.
|
||||||
|
* __Tag-up.__ Check in and status update among development team.
|
||||||
|
May amend plan for sprint as-needed.
|
||||||
|
* __Code freeze.__ Any new work from this sprint
|
||||||
|
(features, bug fixes, enhancements) must be integrated by the
|
||||||
|
end of the second week of the sprint. After code freeze
|
||||||
|
(and until the end of the sprint) the only changes that should be
|
||||||
|
merged into the master branch should directly address issues
|
||||||
|
needed to pass acceptance testing.
|
||||||
|
* __Acceptance Testing.__ Structured testing with predefined
|
||||||
|
success criteria. No release should ship without passing
|
||||||
|
acceptance tests. Time is allocated in each sprint for subsequent
|
||||||
|
rounds of acceptance testing if issues are identified during a
|
||||||
|
prior round. Specific details of acceptance testing need to be
|
||||||
|
agreed-upon with relevant stakeholders and delivery recipients,
|
||||||
|
and should be flexible enough to allow changes to plans
|
||||||
|
(e.g. deferring delivery of some feature in order to ensure
|
||||||
|
stability of other features.) Baseline testing includes:
|
||||||
|
* __Testathon.__ Multi-user testing, involving as many users as
|
||||||
|
is feasible, plus development team. Open-ended; should verify
|
||||||
|
completed work from this sprint, test exploratorily for
|
||||||
|
regressions, et cetera.
|
||||||
|
* __24-Hour Test.__ A test to verify that the software remains
|
||||||
|
stable after running for longer durations. May include some
|
||||||
|
combination of automated testing and user verification (e.g.
|
||||||
|
checking to verify that software remains subjectively
|
||||||
|
responsive at conclusion of test.)
|
||||||
|
* __Automated Testing.__ Automated testing integrated into the
|
||||||
|
build. (These tests are verified to pass more often than once
|
||||||
|
per sprint, as they run before any merge to master, but still
|
||||||
|
play an important role in acceptance testing.)
|
||||||
|
* __Sprint Acceptance Testing.__ Subset of Acceptance Testing
|
||||||
|
which should be performed before shipping at the end of any
|
||||||
|
sprint. Time is allocated for a second round of
|
||||||
|
Sprint Acceptance Testing if the first round is not passed.
|
||||||
|
* __Triage.__ Team reviews issues from acceptance testing and uses
|
||||||
|
success criteria to determine whether or not they should block
|
||||||
|
release, then formulates a plan to address these issues before
|
||||||
|
the next round of acceptance testing. Focus here should be on
|
||||||
|
ensuring software passes that testing in order to ship on time;
|
||||||
|
may prefer to disable malfunctioning components and fix them
|
||||||
|
in a subsequent sprint, for example.
|
||||||
|
* __Ship.__ Tag a code snapshot that has passed acceptance
|
||||||
|
testing and deploy that version. (Only true if acceptance
|
||||||
|
testing has passed by this point; if acceptance testing has not
|
||||||
|
been passed, will need to make ad hoc decisions with stakeholders,
|
||||||
|
e.g. "extend the sprint" or "defer shipment until end of next
|
||||||
|
sprint.")
|
||||||
|
|
||||||
|
|
BIN
docs/src/tutorials/images/add-task.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
docs/src/tutorials/images/bar-plot-2.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
docs/src/tutorials/images/bar-plot-3.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
docs/src/tutorials/images/bar-plot-4.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
docs/src/tutorials/images/bar-plot.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
docs/src/tutorials/images/chrome.png
Normal file
After Width: | Height: | Size: 140 KiB |
BIN
docs/src/tutorials/images/remove-task.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
docs/src/tutorials/images/telemetry-1.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
docs/src/tutorials/images/telemetry-2.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
docs/src/tutorials/images/telemetry-3.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
docs/src/tutorials/images/todo-edit.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
docs/src/tutorials/images/todo-list.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
docs/src/tutorials/images/todo-restyled.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
docs/src/tutorials/images/todo-selection.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
docs/src/tutorials/images/todo.png
Normal file
After Width: | Height: | Size: 43 KiB |
3122
docs/src/tutorials/index.md
Normal file
@ -16,6 +16,23 @@
|
|||||||
"implementation": "SinewaveLimitCapability.js"
|
"implementation": "SinewaveLimitCapability.js"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"formats": [
|
||||||
|
{
|
||||||
|
"key": "example.delta",
|
||||||
|
"implementation": "SinewaveDeltaFormat.js"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"constants": [
|
||||||
|
{
|
||||||
|
"key": "TIME_CONDUCTOR_DOMAINS",
|
||||||
|
"value": [
|
||||||
|
{ "key": "time", "name": "Time" },
|
||||||
|
{ "key": "yesterday", "name": "Yesterday" },
|
||||||
|
{ "key": "delta", "name": "Delta", "format": "example.delta" }
|
||||||
|
],
|
||||||
|
"priority": -1
|
||||||
|
}
|
||||||
|
],
|
||||||
"types": [
|
"types": [
|
||||||
{
|
{
|
||||||
"key": "generator",
|
"key": "generator",
|
||||||
@ -34,6 +51,15 @@
|
|||||||
{
|
{
|
||||||
"key": "time",
|
"key": "time",
|
||||||
"name": "Time"
|
"name": "Time"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "yesterday",
|
||||||
|
"name": "Yesterday"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "delta",
|
||||||
|
"name": "Delta",
|
||||||
|
"format": "example.delta"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ranges": [
|
"ranges": [
|
||||||
|
@ -19,18 +19,8 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
// Styles to temporarily hide non-functional elements
|
/*global define,Promise*/
|
||||||
|
|
||||||
/******************************** BROWSE */
|
define({
|
||||||
.browse-mode {
|
START_TIME: Date.now() - 24 * 60 * 60 * 1000 // Now minus a day.
|
||||||
.browse {
|
});
|
||||||
&.top-bar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.browse-area.holder {
|
|
||||||
// When .browse.top-bar is hidden, set the top of the browse-area holder
|
|
||||||
top: $bodyMargin;
|
|
||||||
}
|
|
||||||
}
|
|
68
example/generator/src/SinewaveDeltaFormat.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define,Promise*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
['./SinewaveConstants', 'moment'],
|
||||||
|
function (SinewaveConstants, moment) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var START_TIME = SinewaveConstants.START_TIME,
|
||||||
|
FORMAT_REGEX = /^-?\d+:\d+:\d+$/,
|
||||||
|
SECOND = 1000,
|
||||||
|
MINUTE = SECOND * 60,
|
||||||
|
HOUR = MINUTE * 60;
|
||||||
|
|
||||||
|
function SinewaveDeltaFormat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function twoDigit(v) {
|
||||||
|
return v >= 10 ? String(v) : ('0' + v);
|
||||||
|
}
|
||||||
|
|
||||||
|
SinewaveDeltaFormat.prototype.format = function (value) {
|
||||||
|
var delta = Math.abs(value - START_TIME),
|
||||||
|
negative = value < START_TIME,
|
||||||
|
seconds = Math.floor(delta / SECOND) % 60,
|
||||||
|
minutes = Math.floor(delta / MINUTE) % 60,
|
||||||
|
hours = Math.floor(delta / HOUR);
|
||||||
|
return (negative ? "-" : "") +
|
||||||
|
[ hours, minutes, seconds ].map(twoDigit).join(":");
|
||||||
|
};
|
||||||
|
|
||||||
|
SinewaveDeltaFormat.prototype.validate = function (text) {
|
||||||
|
return FORMAT_REGEX.test(text);
|
||||||
|
};
|
||||||
|
|
||||||
|
SinewaveDeltaFormat.prototype.parse = function (text) {
|
||||||
|
var negative = text[0] === "-",
|
||||||
|
parts = text.replace("-", "").split(":");
|
||||||
|
return [ HOUR, MINUTE, SECOND ].map(function (sz, i) {
|
||||||
|
return parseInt(parts[i], 10) * sz;
|
||||||
|
}).reduce(function (a, b) {
|
||||||
|
return a + b;
|
||||||
|
}, 0) * (negative ? -1 : 1) + START_TIME;
|
||||||
|
};
|
||||||
|
|
||||||
|
return SinewaveDeltaFormat;
|
||||||
|
}
|
||||||
|
);
|
@ -30,25 +30,25 @@ define(
|
|||||||
YELLOW = 0.5,
|
YELLOW = 0.5,
|
||||||
LIMITS = {
|
LIMITS = {
|
||||||
rh: {
|
rh: {
|
||||||
cssClass: "s-limit-upr-red",
|
cssClass: "s-limit-upr s-limit-red",
|
||||||
low: RED,
|
low: RED,
|
||||||
high: Number.POSITIVE_INFINITY,
|
high: Number.POSITIVE_INFINITY,
|
||||||
name: "Red High"
|
name: "Red High"
|
||||||
},
|
},
|
||||||
rl: {
|
rl: {
|
||||||
cssClass: "s-limit-lwr-red",
|
cssClass: "s-limit-lwr s-limit-red",
|
||||||
high: -RED,
|
high: -RED,
|
||||||
low: Number.NEGATIVE_INFINITY,
|
low: Number.NEGATIVE_INFINITY,
|
||||||
name: "Red Low"
|
name: "Red Low"
|
||||||
},
|
},
|
||||||
yh: {
|
yh: {
|
||||||
cssClass: "s-limit-upr-yellow",
|
cssClass: "s-limit-upr s-limit-yellow",
|
||||||
low: YELLOW,
|
low: YELLOW,
|
||||||
high: RED,
|
high: RED,
|
||||||
name: "Yellow High"
|
name: "Yellow High"
|
||||||
},
|
},
|
||||||
yl: {
|
yl: {
|
||||||
cssClass: "s-limit-lwr-yellow",
|
cssClass: "s-limit-lwr s-limit-yellow",
|
||||||
low: -RED,
|
low: -RED,
|
||||||
high: -YELLOW,
|
high: -YELLOW,
|
||||||
name: "Yellow Low"
|
name: "Yellow Low"
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
* Module defining SinewaveTelemetryProvider. Created by vwoeltje on 11/12/14.
|
* Module defining SinewaveTelemetryProvider. Created by vwoeltje on 11/12/14.
|
||||||
*/
|
*/
|
||||||
define(
|
define(
|
||||||
["./SinewaveTelemetry"],
|
["./SinewaveTelemetrySeries"],
|
||||||
function (SinewaveTelemetry) {
|
function (SinewaveTelemetrySeries) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,7 +45,7 @@ define(
|
|||||||
function generateData(request) {
|
function generateData(request) {
|
||||||
return {
|
return {
|
||||||
key: request.key,
|
key: request.key,
|
||||||
telemetry: new SinewaveTelemetry(request)
|
telemetry: new SinewaveTelemetrySeries(request)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
78
example/generator/src/SinewaveTelemetrySeries.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define,Promise*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14.
|
||||||
|
*/
|
||||||
|
define(
|
||||||
|
['./SinewaveConstants'],
|
||||||
|
function (SinewaveConstants) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var ONE_DAY = 60 * 60 * 24,
|
||||||
|
firstObservedTime = Math.floor(SinewaveConstants.START_TIME / 1000);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function SinewaveTelemetrySeries(request) {
|
||||||
|
var timeOffset = (request.domain === 'yesterday') ? ONE_DAY : 0,
|
||||||
|
latestTime = Math.floor(Date.now() / 1000) - timeOffset,
|
||||||
|
firstTime = firstObservedTime - timeOffset,
|
||||||
|
endTime = (request.end !== undefined) ?
|
||||||
|
Math.floor(request.end / 1000) : latestTime,
|
||||||
|
count = Math.min(endTime, latestTime) - firstTime,
|
||||||
|
period = +request.period || 30,
|
||||||
|
generatorData = {},
|
||||||
|
requestStart = (request.start === undefined) ? firstTime :
|
||||||
|
Math.max(Math.floor(request.start / 1000), firstTime),
|
||||||
|
offset = requestStart - firstTime;
|
||||||
|
|
||||||
|
if (request.size !== undefined) {
|
||||||
|
offset = Math.max(offset, count - request.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
generatorData.getPointCount = function () {
|
||||||
|
return count - offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
generatorData.getDomainValue = function (i, domain) {
|
||||||
|
// delta uses the same numeric values as the default domain,
|
||||||
|
// so it's not checked for here, just formatted for display
|
||||||
|
// differently.
|
||||||
|
return (i + offset) * 1000 + firstTime * 1000 -
|
||||||
|
(domain === 'yesterday' ? (ONE_DAY * 1000) : 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
generatorData.getRangeValue = function (i, range) {
|
||||||
|
range = range || "sin";
|
||||||
|
return Math[range]((i + offset) * Math.PI * 2 / period);
|
||||||
|
};
|
||||||
|
|
||||||
|
return generatorData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SinewaveTelemetrySeries;
|
||||||
|
}
|
||||||
|
);
|
12
example/mobile/bundle.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "Mobile",
|
||||||
|
"description": "Allows elements with pertinence to mobile usage and development",
|
||||||
|
"extensions": {
|
||||||
|
"stylesheets": [
|
||||||
|
{
|
||||||
|
"stylesheetUrl": "css/mobile-example.css",
|
||||||
|
"priority": "mandatory"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
26
example/mobile/res/config.rb
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
# Require any additional compass plugins here.
|
||||||
|
# require "compass-growl"
|
||||||
|
|
||||||
|
# Set this to the root of your project when deployed:
|
||||||
|
http_path = "/"
|
||||||
|
css_dir = "css"
|
||||||
|
sass_dir = "sass"
|
||||||
|
images_dir = "images"
|
||||||
|
javascripts_dir = "js"
|
||||||
|
|
||||||
|
# You can select your preferred output style here (can be overridden via the command line):
|
||||||
|
# :expanded, :compressed, :nested
|
||||||
|
output_style = :nested
|
||||||
|
|
||||||
|
# To enable relative paths to assets via compass helper functions. Uncomment:
|
||||||
|
relative_assets = true
|
||||||
|
|
||||||
|
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
||||||
|
# line_comments = false
|
||||||
|
|
||||||
|
|
||||||
|
# If you prefer the indented syntax, you might want to regenerate this
|
||||||
|
# project again passing --syntax sass, or you can uncomment this:
|
||||||
|
# preferred_syntax = :sass
|
||||||
|
# and then run:
|
||||||
|
# sass-convert -R --from scss --to sass vfn_platform/static/sass scss && rm -rf sass && mv scss sass
|
103
example/mobile/res/css/mobile-example.css
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/************************** FEATURES */
|
||||||
|
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
|
||||||
|
/************************** RATIOS */
|
||||||
|
/************************** LAYOUT */
|
||||||
|
/************************** CONTROLS */
|
||||||
|
/************************** PATHS */
|
||||||
|
/************************** TIMINGS */
|
||||||
|
/************************** LIMITS */
|
||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/************************** MOBILE REPRESENTATION ITEMS DIMENSIONS */
|
||||||
|
/************************** MOBILE TREE MENU DIMENSIONS */
|
||||||
|
/************************** WINDOW DIMENSIONS FOR RWD */
|
||||||
|
/************************** MEDIA QUERIES: WINDOW CHECKS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
|
||||||
|
/************************** MEDIA QUERIES: WINDOWS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
|
||||||
|
/************************** DEVICE PARAMETERS FOR MENUS/REPRESENTATIONS */
|
||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/* REQUIRES mobile/_constants */
|
||||||
|
@media screen and (orientation: portrait) and (max-width: 514px) and (max-height: 740px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (max-height: 514px) and (max-width: 740px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (max-height: 514px) and (max-width: 740px) and (max-device-width: 1024px) and (max-device-height: 799px), screen and (orientation: portrait) and (min-width: 515px) and (max-width: 799px) and (min-height: 741px) and (max-height: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 1024px) and (max-device-height: 799px) {
|
||||||
|
/* line 28, ../sass/mobile-example.scss */
|
||||||
|
.create-btn-holder {
|
||||||
|
display: block !important; } }
|
31
example/mobile/res/sass/mobile-example.scss
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
@import "../../../../platform/commonUI/general/res/sass/constants";
|
||||||
|
@import "../../../../platform/commonUI/general/res/sass/mobile/constants";
|
||||||
|
@import "../../../../platform/commonUI/general/res/sass/mobile/mixins";
|
||||||
|
|
||||||
|
@include phoneandtablet {
|
||||||
|
// Show the Create button
|
||||||
|
.create-btn-holder {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
}
|
47
example/notifications/bundle.json
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"extensions": {
|
||||||
|
"templates": [
|
||||||
|
{
|
||||||
|
"key": "dialogLaunchTemplate",
|
||||||
|
"templateUrl": "dialog-launch.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "notificationLaunchTemplate",
|
||||||
|
"templateUrl": "notification-launch.html"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"controllers": [
|
||||||
|
{
|
||||||
|
"key": "DialogLaunchController",
|
||||||
|
"implementation": "DialogLaunchController.js",
|
||||||
|
"depends": [
|
||||||
|
"$scope",
|
||||||
|
"$timeout",
|
||||||
|
"$log",
|
||||||
|
"dialogService",
|
||||||
|
"notificationService"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "NotificationLaunchController",
|
||||||
|
"implementation": "NotificationLaunchController.js",
|
||||||
|
"depends": [
|
||||||
|
"$scope",
|
||||||
|
"$timeout",
|
||||||
|
"$log",
|
||||||
|
"notificationService"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indicators": [
|
||||||
|
{
|
||||||
|
"implementation": "DialogLaunchIndicator.js",
|
||||||
|
"priority": "fallback"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"implementation": "NotificationLaunchIndicator.js",
|
||||||
|
"priority": "fallback"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
10
example/notifications/res/dialog-launch.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<span class="status block ok" ng-controller="DialogLaunchController">
|
||||||
|
<span class="ui-symbol status-indicator"></span>
|
||||||
|
<span class="label">
|
||||||
|
<a ng-click="launchProgress(true)">Known</a> |
|
||||||
|
<a ng-click="launchProgress(false)">Unknown</a> |
|
||||||
|
<a ng-click="launchError()">Error</a> |
|
||||||
|
<a ng-click="launchInfo()">Info</a>
|
||||||
|
</span>
|
||||||
|
<span class="count">Dialogs</span>
|
||||||
|
</span>
|
10
example/notifications/res/notification-launch.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<span class="status block ok" ng-controller="NotificationLaunchController">
|
||||||
|
<span class="ui-symbol status-indicator"></span>
|
||||||
|
<span class="label">
|
||||||
|
<a ng-click="newInfo()">Success</a> |
|
||||||
|
<a ng-click="newError()">Error</a> |
|
||||||
|
<a ng-click="newAlert()">Alert</a> |
|
||||||
|
<a ng-click="newProgress()">Progress</a>
|
||||||
|
</span>
|
||||||
|
<span class="count">Notifications</span>
|
||||||
|
</span>
|
150
example/notifications/src/DialogLaunchController.js
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A controller for the dialog launch view. This view allows manual
|
||||||
|
* launching of dialogs for demonstration and testing purposes. It
|
||||||
|
* also demonstrates the use of the DialogService.
|
||||||
|
* @param $scope
|
||||||
|
* @param $timeout
|
||||||
|
* @param $log
|
||||||
|
* @param dialogService
|
||||||
|
* @param notificationService
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function DialogLaunchController($scope, $timeout, $log, dialogService, notificationService) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Demonstrates launching a progress dialog and updating it
|
||||||
|
periodically with the progress of an ongoing process.
|
||||||
|
*/
|
||||||
|
$scope.launchProgress = function (knownProgress) {
|
||||||
|
var model = {
|
||||||
|
title: "Progress Dialog Example",
|
||||||
|
progress: 0,
|
||||||
|
hint: "Do not navigate away from this page or close this browser tab while this operation is in progress.",
|
||||||
|
actionText: "Calculating...",
|
||||||
|
unknownProgress: !knownProgress,
|
||||||
|
unknownDuration: false,
|
||||||
|
severity: "info",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "Cancel Operation",
|
||||||
|
callback: function () {
|
||||||
|
$log.debug("Operation cancelled");
|
||||||
|
dialogService.dismiss();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Do something else...",
|
||||||
|
callback: function () {
|
||||||
|
$log.debug("Something else pressed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
function incrementProgress() {
|
||||||
|
model.progress = Math.min(100, Math.floor(model.progress + Math.random() * 30));
|
||||||
|
model.progressText = ["Estimated time remaining: about ", 60 - Math.floor((model.progress / 100) * 60), " seconds"].join(" ");
|
||||||
|
if (model.progress < 100) {
|
||||||
|
$timeout(incrementProgress, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogService.showBlockingMessage(model)) {
|
||||||
|
//Do processing here
|
||||||
|
model.actionText = "Processing 100 objects...";
|
||||||
|
if (knownProgress) {
|
||||||
|
$timeout(incrementProgress, 1000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$log.error("Could not display modal dialog");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Demonstrates launching an error dialog
|
||||||
|
*/
|
||||||
|
$scope.launchError = function () {
|
||||||
|
var model = {
|
||||||
|
title: "Error Dialog Example",
|
||||||
|
actionText: "Something happened, and it was not good.",
|
||||||
|
severity: "error",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: "Try Again",
|
||||||
|
callback: function () {
|
||||||
|
$log.debug("Try Again Pressed");
|
||||||
|
dialogService.dismiss();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Cancel",
|
||||||
|
callback: function () {
|
||||||
|
$log.debug("Cancel Pressed");
|
||||||
|
dialogService.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!dialogService.showBlockingMessage(model)) {
|
||||||
|
$log.error("Could not display modal dialog");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Demonstrates launching an error dialog
|
||||||
|
*/
|
||||||
|
$scope.launchInfo = function () {
|
||||||
|
var model = {
|
||||||
|
title: "Info Dialog Example",
|
||||||
|
actionText: "This is an example of a blocking info" +
|
||||||
|
" dialog. This dialog can be used to draw the user's" +
|
||||||
|
" attention to an event.",
|
||||||
|
severity: "info",
|
||||||
|
primaryOption: {
|
||||||
|
label: "OK",
|
||||||
|
callback: function () {
|
||||||
|
$log.debug("OK Pressed");
|
||||||
|
dialogService.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!dialogService.showBlockingMessage(model)) {
|
||||||
|
$log.error("Could not display modal dialog");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
return DialogLaunchController;
|
||||||
|
}
|
||||||
|
);
|
56
example/notifications/src/DialogLaunchIndicator.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define,window*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tool for manually invoking dialogs. When included this
|
||||||
|
* indicator will allow for dialogs of different types to be
|
||||||
|
* launched for demonstration and testing purposes.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function DialogLaunchIndicator() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogLaunchIndicator.template = 'dialogLaunchTemplate';
|
||||||
|
|
||||||
|
DialogLaunchIndicator.prototype.getGlyph = function () {
|
||||||
|
return "i";
|
||||||
|
};
|
||||||
|
DialogLaunchIndicator.prototype.getGlyphClass = function () {
|
||||||
|
return 'caution';
|
||||||
|
};
|
||||||
|
DialogLaunchIndicator.prototype.getText = function () {
|
||||||
|
return "Launch test dialog";
|
||||||
|
};
|
||||||
|
DialogLaunchIndicator.prototype.getDescription = function () {
|
||||||
|
return "Launch test dialog";
|
||||||
|
};
|
||||||
|
|
||||||
|
return DialogLaunchIndicator;
|
||||||
|
}
|
||||||
|
);
|
172
example/notifications/src/NotificationLaunchController.js
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows launching of notification messages for the purposes of
|
||||||
|
* demonstration and testing. Also demonstrates use of
|
||||||
|
* the NotificationService. Notifications are non-blocking messages that
|
||||||
|
* appear at the bottom of the screen to inform the user of events
|
||||||
|
* in a non-intrusive way. For more information see the
|
||||||
|
* {@link NotificationService}
|
||||||
|
* @param $scope
|
||||||
|
* @param $timeout
|
||||||
|
* @param $log
|
||||||
|
* @param notificationService
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function NotificationLaunchController($scope, $timeout, $log, notificationService) {
|
||||||
|
var messageCounter = 1;
|
||||||
|
|
||||||
|
function getExampleActionText() {
|
||||||
|
var actionTexts = [
|
||||||
|
"Adipiscing turpis mauris in enim elementu hac, enim aliquam etiam.",
|
||||||
|
"Eros turpis, pulvinar turpis eros eu",
|
||||||
|
"Lundium nascetur a, lectus montes ac, parturient in natoque, duis risus risus pulvinar pid rhoncus, habitasse auctor natoque!"
|
||||||
|
];
|
||||||
|
return actionTexts[Math.floor(Math.random()*3)];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExampleActions() {
|
||||||
|
var actions = [
|
||||||
|
{
|
||||||
|
label: "Try Again",
|
||||||
|
callback: function () {
|
||||||
|
$log.debug("Try Again pressed");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Remove",
|
||||||
|
callback: function () {
|
||||||
|
$log.debug("Remove pressed");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Cancel",
|
||||||
|
callback: function () {
|
||||||
|
$log.debug("Cancel pressed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Randomly remove some actions off the top; leave at least one
|
||||||
|
actions.splice(0,Math.floor(Math.random() * actions.length));
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExampleSeverity() {
|
||||||
|
var severities = [
|
||||||
|
"info",
|
||||||
|
"alert",
|
||||||
|
"error"
|
||||||
|
];
|
||||||
|
return severities[Math.floor(Math.random() * severities.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch a new notification with a severity level of 'Error'.
|
||||||
|
*/
|
||||||
|
$scope.newError = function(){
|
||||||
|
|
||||||
|
notificationService.notify({
|
||||||
|
title: "Example error notification " + messageCounter++,
|
||||||
|
hint: "An error has occurred",
|
||||||
|
severity: "error",
|
||||||
|
primaryOption: {
|
||||||
|
label: 'Retry',
|
||||||
|
callback: function() {
|
||||||
|
$log.info('Retry clicked');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: getExampleActions()});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Launch a new notification with a severity of 'Alert'.
|
||||||
|
*/
|
||||||
|
$scope.newAlert = function(){
|
||||||
|
|
||||||
|
notificationService.notify({
|
||||||
|
title: "Alert notification " + (messageCounter++),
|
||||||
|
hint: "This is an alert message",
|
||||||
|
severity: "alert",
|
||||||
|
primaryOption: {
|
||||||
|
label: 'Retry',
|
||||||
|
callback: function() {
|
||||||
|
$log.info('Retry clicked');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: getExampleActions()});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch a new notification with a progress bar that is updated
|
||||||
|
* periodically, tracking an ongoing process.
|
||||||
|
*/
|
||||||
|
$scope.newProgress = function(){
|
||||||
|
|
||||||
|
var notificationModel = {
|
||||||
|
title: "Progress notification example",
|
||||||
|
severity: "info",
|
||||||
|
progress: 0,
|
||||||
|
actionText: getExampleActionText(),
|
||||||
|
unknownProgress: false
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulate an ongoing process and update the progress bar.
|
||||||
|
* @param notification
|
||||||
|
*/
|
||||||
|
function incrementProgress(notificationModel) {
|
||||||
|
notificationModel.progress = Math.min(100, Math.floor(notificationModel.progress + Math.random() * 30));
|
||||||
|
notificationModel.progressText = ["Estimated time" +
|
||||||
|
" remaining:" +
|
||||||
|
" about ", 60 - Math.floor((notificationModel.progress / 100) * 60), " seconds"].join(" ");
|
||||||
|
if (notificationModel.progress < 100) {
|
||||||
|
$timeout(function(){incrementProgress(notificationModel);}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationService.notify(notificationModel);
|
||||||
|
incrementProgress(notificationModel);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch a new notification with severity level of INFO.
|
||||||
|
*/
|
||||||
|
$scope.newInfo = function(){
|
||||||
|
|
||||||
|
notificationService.info({
|
||||||
|
title: "Example Info notification " + messageCounter++
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
return NotificationLaunchController;
|
||||||
|
}
|
||||||
|
);
|
50
example/notifications/src/NotificationLaunchIndicator.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define,window*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function NotificationLaunchIndicator() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationLaunchIndicator.template = 'notificationLaunchTemplate';
|
||||||
|
|
||||||
|
NotificationLaunchIndicator.prototype.getGlyph = function () {
|
||||||
|
return "i";
|
||||||
|
};
|
||||||
|
NotificationLaunchIndicator.prototype.getGlyphClass = function () {
|
||||||
|
return 'caution';
|
||||||
|
};
|
||||||
|
NotificationLaunchIndicator.prototype.getText = function () {
|
||||||
|
return "Launch notification";
|
||||||
|
};
|
||||||
|
NotificationLaunchIndicator.prototype.getDescription = function () {
|
||||||
|
return "Launch notification";
|
||||||
|
};
|
||||||
|
|
||||||
|
return NotificationLaunchIndicator;
|
||||||
|
}
|
||||||
|
);
|
@ -4,6 +4,10 @@
|
|||||||
{
|
{
|
||||||
"implementation": "WatchIndicator.js",
|
"implementation": "WatchIndicator.js",
|
||||||
"depends": ["$interval", "$rootScope"]
|
"depends": ["$interval", "$rootScope"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"implementation": "DigestIndicator.js",
|
||||||
|
"depends": ["$interval", "$rootScope"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
77
example/profiling/src/DigestIndicator.js
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the number of digests that have occurred since the
|
||||||
|
* indicator was first instantiated.
|
||||||
|
* @constructor
|
||||||
|
* @param $interval Angular's $interval
|
||||||
|
* @implements {Indicator}
|
||||||
|
*/
|
||||||
|
function DigestIndicator($interval, $rootScope) {
|
||||||
|
var digests = 0,
|
||||||
|
displayed = 0,
|
||||||
|
start = Date.now();
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
var secs = (Date.now() - start) / 1000;
|
||||||
|
displayed = Math.round(digests / secs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function increment() {
|
||||||
|
digests += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rootScope.$watch(increment);
|
||||||
|
|
||||||
|
// Update state every second
|
||||||
|
$interval(update, 1000);
|
||||||
|
|
||||||
|
// Provide initial state, too
|
||||||
|
update();
|
||||||
|
|
||||||
|
return {
|
||||||
|
getGlyph: function () {
|
||||||
|
return ".";
|
||||||
|
},
|
||||||
|
getGlyphClass: function () {
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
getText: function () {
|
||||||
|
return displayed + " digests/sec";
|
||||||
|
},
|
||||||
|
getDescription: function () {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return DigestIndicator;
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
2
example/scratchpad/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Example of using multiple persistence stores by exposing a root
|
||||||
|
object with a different space prefix.
|
23
example/scratchpad/bundle.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"extensions": {
|
||||||
|
"roots": [
|
||||||
|
{
|
||||||
|
"id": "scratch:root",
|
||||||
|
"model": {
|
||||||
|
"type": "folder",
|
||||||
|
"composition": [],
|
||||||
|
"name": "Scratchpad"
|
||||||
|
},
|
||||||
|
"priority": "preferred"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"provides": "persistenceService",
|
||||||
|
"type": "provider",
|
||||||
|
"implementation": "ScratchPersistenceProvider.js",
|
||||||
|
"depends": [ "$q" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
79
example/scratchpad/src/ScratchPersistenceProvider.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*global define,window*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ScratchPersistenceProvider keeps JSON documents in memory
|
||||||
|
* and provides a persistence interface, but changes are lost on reload.
|
||||||
|
* @memberof example/scratchpad
|
||||||
|
* @constructor
|
||||||
|
* @implements {PersistenceService}
|
||||||
|
* @param q Angular's $q, for promises
|
||||||
|
*/
|
||||||
|
function ScratchPersistenceProvider($q) {
|
||||||
|
this.$q = $q;
|
||||||
|
this.table = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
ScratchPersistenceProvider.prototype.listSpaces = function () {
|
||||||
|
return this.$q.when(['scratch']);
|
||||||
|
};
|
||||||
|
|
||||||
|
ScratchPersistenceProvider.prototype.listObjects = function (space) {
|
||||||
|
return this.$q.when(
|
||||||
|
space === 'scratch' ? Object.keys(this.table) : []
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ScratchPersistenceProvider.prototype.createObject = function (space, key, value) {
|
||||||
|
if (space === 'scratch') {
|
||||||
|
this.table[key] = JSON.stringify(value);
|
||||||
|
}
|
||||||
|
return this.$q.when(space === 'scratch');
|
||||||
|
};
|
||||||
|
|
||||||
|
ScratchPersistenceProvider.prototype.readObject = function (space, key) {
|
||||||
|
return this.$q.when(
|
||||||
|
(space === 'scratch' && this.table[key]) ?
|
||||||
|
JSON.parse(this.table[key]) : undefined
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ScratchPersistenceProvider.prototype.deleteObject = function (space, key, value) {
|
||||||
|
if (space === 'scratch') {
|
||||||
|
delete this.table[key];
|
||||||
|
}
|
||||||
|
return this.$q.when(space === 'scratch');
|
||||||
|
};
|
||||||
|
|
||||||
|
ScratchPersistenceProvider.prototype.updateObject =
|
||||||
|
ScratchPersistenceProvider.prototype.createObject;
|
||||||
|
|
||||||
|
return ScratchPersistenceProvider;
|
||||||
|
}
|
||||||
|
);
|
@ -34,7 +34,6 @@ module.exports = function(config) {
|
|||||||
// List of files / patterns to load in the browser.
|
// List of files / patterns to load in the browser.
|
||||||
// By default, files are also included in a script tag.
|
// By default, files are also included in a script tag.
|
||||||
files: [
|
files: [
|
||||||
'**/moment*',
|
|
||||||
{pattern: 'example/**/*.js', included: false},
|
{pattern: 'example/**/*.js', included: false},
|
||||||
{pattern: 'platform/**/*.js', included: false},
|
{pattern: 'platform/**/*.js', included: false},
|
||||||
{pattern: 'warp/**/*.js', included: false},
|
{pattern: 'warp/**/*.js', included: false},
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
"split": "^1.0.0",
|
"split": "^1.0.0",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"nomnoml": "^0.0.3",
|
"nomnoml": "^0.0.3",
|
||||||
"canvas": "^1.2.7"
|
"canvas": "^1.2.7",
|
||||||
|
"markdown-toc": "^0.11.7"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node app.js",
|
"start": "node app.js",
|
||||||
|
@ -20,21 +20,23 @@
|
|||||||
"$scope",
|
"$scope",
|
||||||
"$route",
|
"$route",
|
||||||
"$location",
|
"$location",
|
||||||
|
"$q",
|
||||||
"objectService",
|
"objectService",
|
||||||
"navigationService",
|
"navigationService",
|
||||||
"urlService"
|
"urlService"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "BrowseTreeController",
|
"key": "PaneController",
|
||||||
"implementation": "BrowseTreeController.js",
|
"implementation": "PaneController.js",
|
||||||
"priority": "preferred",
|
"priority": "preferred",
|
||||||
"depends": [ "$scope", "agentService" ]
|
"depends": [ "$scope", "agentService","$window" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "BrowseObjectController",
|
"key": "BrowseObjectController",
|
||||||
"implementation": "BrowseObjectController.js",
|
"implementation": "BrowseObjectController.js",
|
||||||
"depends": [ "$scope", "$location", "$route" ]
|
"depends": [ "$scope", "$location", "$route", "$q",
|
||||||
|
"navigationService" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "CreateMenuController",
|
"key": "CreateMenuController",
|
||||||
@ -62,6 +64,7 @@
|
|||||||
{
|
{
|
||||||
"key": "browse-object",
|
"key": "browse-object",
|
||||||
"templateUrl": "templates/browse-object.html",
|
"templateUrl": "templates/browse-object.html",
|
||||||
|
"gestures": ["drop"],
|
||||||
"uses": [ "view" ]
|
"uses": [ "view" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -147,14 +150,15 @@
|
|||||||
"provides": "actionService",
|
"provides": "actionService",
|
||||||
"type": "provider",
|
"type": "provider",
|
||||||
"implementation": "creation/CreateActionProvider.js",
|
"implementation": "creation/CreateActionProvider.js",
|
||||||
"depends": [ "typeService", "dialogService", "creationService", "policyService" ]
|
"depends": ["$q", "typeService",
|
||||||
|
"navigationService"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "CreationService",
|
"key": "CreationService",
|
||||||
"provides": "creationService",
|
"provides": "creationService",
|
||||||
"type": "provider",
|
"type": "provider",
|
||||||
"implementation": "creation/CreationService.js",
|
"implementation": "creation/CreationService.js",
|
||||||
"depends": [ "persistenceService", "now", "$q", "$log" ]
|
"depends": [ "$q", "$log" ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"runs": [
|
"runs": [
|
||||||
@ -173,16 +177,6 @@
|
|||||||
"copyright": "Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
|
"copyright": "Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
|
||||||
"license": "license-mit",
|
"license": "license-mit",
|
||||||
"link": "https://github.com/sindresorhus/screenfull.js/blob/gh-pages/license"
|
"link": "https://github.com/sindresorhus/screenfull.js/blob/gh-pages/license"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Math.uuid.js",
|
|
||||||
"version": "1.4",
|
|
||||||
"description": "Unique identifer generation (code adapted.)",
|
|
||||||
"author": "Robert Kieffer",
|
|
||||||
"website": "https://github.com/broofa/node-uuid",
|
|
||||||
"copyright": "Copyright (c) 2010 Robert Kieffer",
|
|
||||||
"license": "license-mit",
|
|
||||||
"link": "http://opensource.org/licenses/MIT"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -19,16 +19,19 @@
|
|||||||
this source code distribution or the Licensing information page available
|
this source code distribution or the Licensing information page available
|
||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<span ng-controller="BrowseObjectController">
|
<div ng-controller="BrowseObjectController" class="abs l-flex-col"
|
||||||
<div class="object-browse-bar bar l-flex">
|
ng-class="editMode ? 'edit-mode' : 'browse-mode'">
|
||||||
<div class="items-select left">
|
<div class="holder flex-elem l-flex-row object-browse-bar ">
|
||||||
|
<div class="items-select left flex-elem l-flex-row grows">
|
||||||
<mct-representation key="'back-arrow'"
|
<mct-representation key="'back-arrow'"
|
||||||
mct-object="domainObject"
|
mct-object="domainObject"
|
||||||
class="l-back"></mct-representation>
|
class="flex-elem l-back"></mct-representation>
|
||||||
<mct-representation key="'object-header'" mct-object="domainObject">
|
<mct-representation key="'object-header'"
|
||||||
|
mct-object="domainObject"
|
||||||
|
class="l-flex-row flex-elem grows object-header">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-bar right">
|
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
||||||
<mct-representation key="'switcher'"
|
<mct-representation key="'switcher'"
|
||||||
mct-object="domainObject"
|
mct-object="domainObject"
|
||||||
ng-model="representation">
|
ng-model="representation">
|
||||||
@ -41,10 +44,27 @@
|
|||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="holder l-flex-col flex-elem grows l-object-wrapper" ng-class="{ active:editMode, 'edit-main':editMode}">
|
||||||
|
<div class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
|
||||||
|
<!-- Toolbar and Save/Cancel buttons -->
|
||||||
|
<div class="l-edit-controls flex-elem l-flex-row flex-align-end"
|
||||||
|
ng-class="{ active:editMode }">
|
||||||
|
<mct-toolbar name="mctToolbar"
|
||||||
|
structure="toolbar.structure"
|
||||||
|
ng-model="toolbar.state"
|
||||||
|
class="flex-elem grows">
|
||||||
|
</mct-toolbar>
|
||||||
|
<mct-representation key="'edit-action-buttons'"
|
||||||
|
mct-object="domainObject"
|
||||||
|
class='flex-elem conclude-editing'>
|
||||||
|
</mct-representation>
|
||||||
|
|
||||||
<div class='object-holder abs vscroll'>
|
</div>
|
||||||
<mct-representation key="representation.selected.key"
|
<mct-representation key="representation.selected.key"
|
||||||
mct-object="representation.selected.key && domainObject">
|
mct-object="representation.selected.key && domainObject"
|
||||||
</mct-representation>
|
class="abs flex-elem grows object-holder-main scroll"
|
||||||
|
toolbar="toolbar">
|
||||||
|
</mct-representation>
|
||||||
|
</div><!--/ l-object-wrapper-inner -->
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</div>
|
||||||
|
@ -20,45 +20,69 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<div class="abs holder-all browse-mode" ng-controller="BrowseController">
|
<div class="abs holder-all" ng-controller="BrowseController"
|
||||||
|
mct-before-unload="beforeUnloadWarning()">
|
||||||
<mct-include key="'topbar-browse'"></mct-include>
|
<mct-include key="'topbar-browse'"></mct-include>
|
||||||
<div class="holder browse-area s-browse-area abs browse-wrapper"
|
<div class="abs holder holder-main browse-area s-browse-area browse-wrapper"
|
||||||
ng-controller="BrowseTreeController as tree"
|
ng-controller="PaneController as modelPaneTree"
|
||||||
ng-class="tree.visible() ? 'browse-showtree' : 'browse-hidetree'">
|
ng-class="modelPaneTree.visible() ? 'pane-tree-showing' : 'pane-tree-hidden'">
|
||||||
<mct-split-pane class='contents abs' anchor='left'>
|
<mct-split-pane class='abs contents'
|
||||||
|
anchor='left'>
|
||||||
<div class='split-pane-component treeview pane left'>
|
<div class='split-pane-component treeview pane left'>
|
||||||
<div class="holder abs l-mobile">
|
<div class="abs holder l-flex-col holder-treeview-elements">
|
||||||
<mct-representation key="'create-button'" mct-object="navigatedObject">
|
<mct-representation key="'create-button'"
|
||||||
|
mct-object="navigatedObject"
|
||||||
|
class="holder flex-elem create-btn-holder">
|
||||||
|
</mct-representation>
|
||||||
|
<mct-include key="'search'"
|
||||||
|
ng-model="treeModel"
|
||||||
|
class="holder l-flex-col flex-elem search-holder"
|
||||||
|
ng-class="{ active: treeModel.search, grows: treeModel.search }">
|
||||||
|
</mct-include>
|
||||||
|
<mct-representation key="'tree'"
|
||||||
|
mct-object="domainObject"
|
||||||
|
parameters="tree"
|
||||||
|
ng-model="treeModel"
|
||||||
|
class="holder flex-elem grows vscroll tree-holder"
|
||||||
|
ng-hide="treeModel.search">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
<div class='holder search-holder abs'
|
|
||||||
ng-class="{active: treeModel.search}">
|
|
||||||
<mct-representation key="'search'"
|
|
||||||
mct-object="domainObject"
|
|
||||||
ng-model="treeModel">
|
|
||||||
</mct-representation>
|
|
||||||
</div>
|
|
||||||
<div class='tree-holder abs mobile-tree-holder'
|
|
||||||
ng-hide="treeModel.search">
|
|
||||||
<mct-representation key="'tree'"
|
|
||||||
mct-object="domainObject"
|
|
||||||
parameters="tree"
|
|
||||||
ng-model="treeModel">
|
|
||||||
</mct-representation>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mct-splitter class="mobile-hide"></mct-splitter>
|
<mct-splitter class="splitter-treeview mobile-hide"></mct-splitter>
|
||||||
|
|
||||||
<div class='split-pane-component items pane right-repr'>
|
<div class='split-pane-component items pane primary-pane right'>
|
||||||
<div class='holder abs l-mobile' id='content-area'>
|
<a class="mini-tab-icon anchor-left toggle-pane toggle-tree"
|
||||||
<mct-representation mct-object="navigatedObject"
|
title="{{ modelPaneTree.visible()? 'Hide' : 'Show' }} this pane"
|
||||||
key="'browse-object'">
|
ng-click="modelPaneTree.toggle()"
|
||||||
</mct-representation>
|
ng-class="{ collapsed : !modelPaneTree.visible() }"></a>
|
||||||
|
|
||||||
|
<div class='holder holder-object-and-inspector abs' id='content-area'
|
||||||
|
ng-controller="PaneController as modelPaneInspect"
|
||||||
|
ng-class="modelPaneInspect.visible() ? 'pane-inspect-showing' : 'pane-inspect-hidden'">
|
||||||
|
|
||||||
|
<mct-split-pane class='l-object-and-inspector contents abs' anchor='right'>
|
||||||
|
<div class='split-pane-component t-object pane primary-pane left'>
|
||||||
|
<mct-representation mct-object="navigatedObject"
|
||||||
|
key="'browse-object'"
|
||||||
|
class="abs holder holder-object">
|
||||||
|
</mct-representation>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mct-splitter class="splitter-inspect mobile-hide flush-right edge-shdw"></mct-splitter>
|
||||||
|
|
||||||
|
<div class="split-pane-component t-inspect pane right mobile-hide">
|
||||||
|
<mct-representation key="'object-inspector'"
|
||||||
|
mct-object="navigatedObject"
|
||||||
|
ng-model="treeModel">
|
||||||
|
</mct-representation>
|
||||||
|
<a class="mini-tab-icon anchor-right mobile-hide toggle-pane toggle-inspect"
|
||||||
|
title="{{ modelPaneInspect.visible()? 'Hide' : 'Show' }} the Inspection pane"
|
||||||
|
ng-click="modelPaneInspect.toggle()"
|
||||||
|
ng-class="{ collapsed : !modelPaneInspect.visible() }"></a>
|
||||||
|
</div>
|
||||||
|
</mct-split-pane>
|
||||||
</div>
|
</div>
|
||||||
<div class="key-properties ui-symbol icon mobile-menu-icon desktop-hide"
|
|
||||||
mct-device="mobile"
|
|
||||||
ng-click="tree.toggle()">m</div>
|
|
||||||
</div>
|
</div>
|
||||||
</mct-split-pane>
|
</mct-split-pane>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
this source code distribution or the Licensing information page available
|
this source code distribution or the Licensing information page available
|
||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<div class='object-header object-header-mobile'>
|
<span class='type-icon ui-symbol flex-elem'>{{type.getGlyph()}}</span>
|
||||||
<span class='type-icon ui-symbol'>{{type.getGlyph()}}</span>
|
<span class="l-elem-wrapper l-flex-row flex-elem grows">
|
||||||
<!--span class='type-name mobile-important-hide'>{{type.getName()}}</span-->
|
<span ng-if="parameters.mode" class='action flex-elem'>{{parameters.mode}}</span>
|
||||||
<span class="l-elem-wrapper l-flex">
|
<span class='title-label flex-elem flex-can-shrink'>{{model.name}}</span>
|
||||||
<span ng-if="parameters.mode" class='action'>{{parameters.mode}}</span>
|
<mct-representation
|
||||||
<span class='title-label'>{{model.name}}</span>
|
key="'menu-arrow'"
|
||||||
<mct-representation key="'menu-arrow'" mct-object='domainObject'></mct-representation>
|
mct-object='domainObject'
|
||||||
</span>
|
class="flex-elem"></mct-representation>
|
||||||
</div>
|
</span>
|
@ -19,13 +19,12 @@
|
|||||||
this source code distribution or the Licensing information page available
|
this source code distribution or the Licensing information page available
|
||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<div class="menu-element wrapper" ng-controller="ClickAwayController as createController">
|
<span ng-controller="ClickAwayController as createController">
|
||||||
<div class="s-menu major create-btn" ng-click="createController.toggle()">
|
<div class="s-menu-btn major create-btn" ng-click="createController.toggle()">
|
||||||
<span class="ui-symbol icon type-icon">+</span>
|
|
||||||
<span class="title-label">Create</span>
|
<span class="title-label">Create</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu super-menu" ng-show="createController.isActive()">
|
<div class="menu super-menu" ng-show="createController.isActive()">
|
||||||
<mct-representation mct-object="domainObject" key="'create-menu'">
|
<mct-representation mct-object="domainObject" key="'create-menu'">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</span>
|
@ -26,14 +26,8 @@
|
|||||||
<div class='ui-symbol profile' title='Shared'>O</div>
|
<div class='ui-symbol profile' title='Shared'>O</div>
|
||||||
<mct-representation class="desktop-hide" key="'info-button'" mct-object="domainObject"></mct-representation>
|
<mct-representation class="desktop-hide" key="'info-button'" mct-object="domainObject"></mct-representation>
|
||||||
</div>
|
</div>
|
||||||
<div class='item-main abs'>
|
<div class='item-main abs lg'>
|
||||||
<div class='ui-symbol icon lg item-type'>
|
<span class="t-item-icon" ng-class="{ 'l-icon-link':location.isLink() }">{{type.getGlyph()}}</span>
|
||||||
{{type.getGlyph()}}
|
|
||||||
<span
|
|
||||||
class="ui-symbol l-icon-link" title="This object is a link"
|
|
||||||
ng-show="location.isLink()"
|
|
||||||
></span>
|
|
||||||
</div>
|
|
||||||
<div class='ui-symbol abs item-open'>}</div>
|
<div class='ui-symbol abs item-open'>}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='bottom-bar bar abs'>
|
<div class='bottom-bar bar abs'>
|
||||||
|
@ -26,12 +26,16 @@
|
|||||||
* @namespace platform/commonUI/browse
|
* @namespace platform/commonUI/browse
|
||||||
*/
|
*/
|
||||||
define(
|
define(
|
||||||
[],
|
[
|
||||||
function () {
|
'../../../representation/src/gestures/GestureConstants',
|
||||||
|
'../../edit/src/objects/EditableDomainObject'
|
||||||
|
],
|
||||||
|
function (GestureConstants, EditableDomainObject) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var ROOT_ID = "ROOT",
|
var ROOT_ID = "ROOT",
|
||||||
DEFAULT_PATH = "mine";
|
DEFAULT_PATH = "mine",
|
||||||
|
CONFIRM_MSG = "Unsaved changes will be lost if you leave this page.";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The BrowseController is used to populate the initial scope in Browse
|
* The BrowseController is used to populate the initial scope in Browse
|
||||||
@ -43,7 +47,7 @@ define(
|
|||||||
* @memberof platform/commonUI/browse
|
* @memberof platform/commonUI/browse
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function BrowseController($scope, $route, $location, objectService, navigationService, urlService) {
|
function BrowseController($scope, $route, $location, $q, objectService, navigationService, urlService) {
|
||||||
var path = [ROOT_ID].concat(
|
var path = [ROOT_ID].concat(
|
||||||
($route.current.params.ids || DEFAULT_PATH).split("/")
|
($route.current.params.ids || DEFAULT_PATH).split("/")
|
||||||
);
|
);
|
||||||
@ -64,10 +68,21 @@ define(
|
|||||||
// urlService.urlForLocation used to adjust current
|
// urlService.urlForLocation used to adjust current
|
||||||
// path to new, addressed, path based on
|
// path to new, addressed, path based on
|
||||||
// domainObject
|
// domainObject
|
||||||
$location.path(urlService.urlForLocation("browse", domainObject));
|
$location.path(urlService.urlForLocation("browse", domainObject.hasCapability('editor') ? domainObject.getOriginalObject() : domainObject));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSelectedObject(domainObject) {
|
||||||
|
if (domainObject !== $scope.navigatedObject && isDirty() && !confirm(CONFIRM_MSG)) {
|
||||||
|
$scope.treeModel.selectedObject = $scope.navigatedObject;
|
||||||
|
} else {
|
||||||
|
if (domainObject !== $scope.navigatedObject && $scope.navigatedObject.hasCapability('editor')){
|
||||||
|
$scope.navigatedObject.getCapability('action').perform('cancel');
|
||||||
|
}
|
||||||
|
setNavigation(domainObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Callback for updating the in-scope reference to the object
|
// Callback for updating the in-scope reference to the object
|
||||||
// that is currently navigated-to.
|
// that is currently navigated-to.
|
||||||
function setNavigation(domainObject) {
|
function setNavigation(domainObject) {
|
||||||
@ -78,6 +93,7 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function navigateTo(domainObject) {
|
function navigateTo(domainObject) {
|
||||||
|
|
||||||
// Check if an object has been navigated-to already...
|
// Check if an object has been navigated-to already...
|
||||||
// If not, or if an ID path has been explicitly set in the URL,
|
// If not, or if an ID path has been explicitly set in the URL,
|
||||||
// navigate to the URL-specified object.
|
// navigate to the URL-specified object.
|
||||||
@ -143,17 +159,29 @@ define(
|
|||||||
selectedObject: navigationService.getNavigation()
|
selectedObject: navigationService.getNavigation()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isDirty(){
|
||||||
|
var editorCapability = $scope.navigatedObject &&
|
||||||
|
$scope.navigatedObject.getCapability("editor"),
|
||||||
|
hasChanges = editorCapability && editorCapability.dirty();
|
||||||
|
return hasChanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.beforeUnloadWarning = function() {
|
||||||
|
return isDirty() ?
|
||||||
|
"Unsaved changes will be lost if you leave this page." :
|
||||||
|
undefined;
|
||||||
|
}
|
||||||
|
|
||||||
// Listen for changes in navigation state.
|
// Listen for changes in navigation state.
|
||||||
navigationService.addListener(setNavigation);
|
navigationService.addListener(setNavigation);
|
||||||
|
|
||||||
// Also listen for changes which come from the tree
|
// Also listen for changes which come from the tree
|
||||||
$scope.$watch("treeModel.selectedObject", setNavigation);
|
$scope.$watch("treeModel.selectedObject", setSelectedObject);
|
||||||
|
|
||||||
// Clean up when the scope is destroyed
|
// Clean up when the scope is destroyed
|
||||||
$scope.$on("$destroy", function () {
|
$scope.$on("$destroy", function () {
|
||||||
navigationService.removeListener(setNavigation);
|
navigationService.removeListener(setNavigation);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return BrowseController;
|
return BrowseController;
|
||||||
|
@ -22,8 +22,9 @@
|
|||||||
/*global define,Promise*/
|
/*global define,Promise*/
|
||||||
|
|
||||||
define(
|
define(
|
||||||
[],
|
['../../../representation/src/gestures/GestureConstants',
|
||||||
function () {
|
'../../edit/src/objects/EditableDomainObject'],
|
||||||
|
function (GestureConstants, EditableDomainObject) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,8 +33,10 @@ define(
|
|||||||
* @memberof platform/commonUI/browse
|
* @memberof platform/commonUI/browse
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function BrowseObjectController($scope, $location, $route) {
|
function BrowseObjectController($scope, $location, $route, $q, navigationService) {
|
||||||
|
var navigatedObject;
|
||||||
function setViewForDomainObject(domainObject) {
|
function setViewForDomainObject(domainObject) {
|
||||||
|
|
||||||
var locationViewKey = $location.search().view;
|
var locationViewKey = $location.search().view;
|
||||||
|
|
||||||
function selectViewIfMatching(view) {
|
function selectViewIfMatching(view) {
|
||||||
@ -47,12 +50,17 @@ define(
|
|||||||
((domainObject && domainObject.useCapability('view')) || [])
|
((domainObject && domainObject.useCapability('view')) || [])
|
||||||
.forEach(selectViewIfMatching);
|
.forEach(selectViewIfMatching);
|
||||||
}
|
}
|
||||||
|
//$scope.editMode = domainObject.hasCapability('editor') ?
|
||||||
|
// true : false;
|
||||||
|
navigatedObject = domainObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateQueryParam(viewKey) {
|
function updateQueryParam(viewKey) {
|
||||||
var unlisten, priorRoute = $route.current;
|
var unlisten,
|
||||||
|
priorRoute = $route.current,
|
||||||
|
editMode = $scope.domainObject && $scope.domainObject.hasCapability('editor');
|
||||||
|
|
||||||
if (viewKey) {
|
if (viewKey && !editMode) {
|
||||||
$location.search('view', viewKey);
|
$location.search('view', viewKey);
|
||||||
unlisten = $scope.$on('$locationChangeSuccess', function () {
|
unlisten = $scope.$on('$locationChangeSuccess', function () {
|
||||||
// Checks path to make sure /browse/ is at front
|
// Checks path to make sure /browse/ is at front
|
||||||
@ -67,6 +75,15 @@ define(
|
|||||||
|
|
||||||
$scope.$watch('domainObject', setViewForDomainObject);
|
$scope.$watch('domainObject', setViewForDomainObject);
|
||||||
$scope.$watch('representation.selected.key', updateQueryParam);
|
$scope.$watch('representation.selected.key', updateQueryParam);
|
||||||
|
|
||||||
|
$scope.cancelEditing = function() {
|
||||||
|
navigationService.setNavigation($scope.domainObject.getDomainObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.doAction = function (action){
|
||||||
|
$scope[action] && $scope[action]();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return BrowseObjectController;
|
return BrowseObjectController;
|
||||||
|
@ -33,10 +33,12 @@ define(
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @memberof platform/commonUI/browse
|
* @memberof platform/commonUI/browse
|
||||||
*/
|
*/
|
||||||
function BrowseTreeController($scope, agentService) {
|
function PaneController($scope, agentService, $window) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.agentService = agentService;
|
this.agentService = agentService;
|
||||||
this.state = true;
|
|
||||||
|
// Fast and cheap: if this has been opened in a new window, hide panes by default
|
||||||
|
this.state = !$window.opener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to invoke when any selection occurs in the tree.
|
* Callback to invoke when any selection occurs in the tree.
|
||||||
@ -44,7 +46,7 @@ define(
|
|||||||
* to the tree representation.
|
* to the tree representation.
|
||||||
*
|
*
|
||||||
* @property {Function} callback
|
* @property {Function} callback
|
||||||
* @memberof platform/commonUI/browse.BrowseTreeController#
|
* @memberof platform/commonUI/browse.PaneController#
|
||||||
*/
|
*/
|
||||||
this.callback = function () {
|
this.callback = function () {
|
||||||
// Note that, since this is a callback to pass, this is not
|
// Note that, since this is a callback to pass, this is not
|
||||||
@ -59,20 +61,20 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle the visibility of the tree.
|
* Toggle the visibility of the pane.
|
||||||
*/
|
*/
|
||||||
BrowseTreeController.prototype.toggle = function () {
|
PaneController.prototype.toggle = function () {
|
||||||
this.state = !this.state;
|
this.state = !this.state;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the desired visibility state of the tree.
|
* Get the desired visibility state of the pane.
|
||||||
* @returns {boolean} true when visible
|
* @returns {boolean} true when visible
|
||||||
*/
|
*/
|
||||||
BrowseTreeController.prototype.visible = function () {
|
PaneController.prototype.visible = function () {
|
||||||
return this.state;
|
return this.state;
|
||||||
};
|
};
|
||||||
|
|
||||||
return BrowseTreeController;
|
return PaneController;
|
||||||
}
|
}
|
||||||
);
|
);
|
@ -25,8 +25,10 @@
|
|||||||
* Module defining CreateAction. Created by vwoeltje on 11/10/14.
|
* Module defining CreateAction. Created by vwoeltje on 11/10/14.
|
||||||
*/
|
*/
|
||||||
define(
|
define(
|
||||||
['./CreateWizard'],
|
['./CreateWizard',
|
||||||
function (CreateWizard) {
|
'uuid',
|
||||||
|
'../../../edit/src/objects/EditableDomainObject'],
|
||||||
|
function (CreateWizard, uuid, EditableDomainObject) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,13 +47,11 @@ define(
|
|||||||
* override this)
|
* override this)
|
||||||
* @param {ActionContext} context the context in which the
|
* @param {ActionContext} context the context in which the
|
||||||
* action is being performed
|
* action is being performed
|
||||||
* @param {DialogService} dialogService the dialog service
|
* @param {NavigationService} navigationService the navigation service,
|
||||||
* to use when requesting user input
|
* which handles changes in navigation. It allows the object
|
||||||
* @param {CreationService} creationService the creation service,
|
* being browsed/edited to be set.
|
||||||
* which handles the actual instantiation and persistence
|
|
||||||
* of the newly-created domain object
|
|
||||||
*/
|
*/
|
||||||
function CreateAction(type, parent, context, dialogService, creationService, policyService) {
|
function CreateAction(type, parent, context, $q, navigationService) {
|
||||||
this.metadata = {
|
this.metadata = {
|
||||||
key: 'create',
|
key: 'create',
|
||||||
glyph: type.getGlyph(),
|
glyph: type.getGlyph(),
|
||||||
@ -63,9 +63,8 @@ define(
|
|||||||
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.policyService = policyService;
|
this.navigationService = navigationService;
|
||||||
this.dialogService = dialogService;
|
this.$q = $q;
|
||||||
this.creationService = creationService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,45 +72,24 @@ define(
|
|||||||
* This will prompt for user input first.
|
* This will prompt for user input first.
|
||||||
*/
|
*/
|
||||||
CreateAction.prototype.perform = function () {
|
CreateAction.prototype.perform = function () {
|
||||||
/*
|
var newModel = this.type.getInitialModel(),
|
||||||
Overview of steps in object creation:
|
parentObject = this.navigationService.getNavigation(),
|
||||||
|
newObject,
|
||||||
|
editableObject;
|
||||||
|
|
||||||
1. Show dialog
|
newModel.type = this.type.getKey();
|
||||||
a. Prepare dialog contents
|
newObject = parentObject.useCapability('instantiation', newModel);
|
||||||
b. Invoke dialogService
|
editableObject = new EditableDomainObject(newObject, this.$q);
|
||||||
2. Create new object in persistence service
|
editableObject.setOriginalObject(parentObject);
|
||||||
a. Generate UUID
|
editableObject.useCapability('mutation', function(model){
|
||||||
b. Store model
|
model.location = parentObject.getId();
|
||||||
3. Mutate destination container
|
});
|
||||||
a. Get mutation capability
|
|
||||||
b. Add new id to composition
|
|
||||||
4. Persist destination container
|
|
||||||
a. ...use persistence capability.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// The wizard will handle creating the form model based
|
if (newObject.hasCapability('composition') && this.type.getKey()!=='folder') {
|
||||||
// on the type...
|
this.navigationService.setNavigation(editableObject);
|
||||||
var wizard =
|
} else {
|
||||||
new CreateWizard(this.type, this.parent, this.policyService),
|
return editableObject.getCapability('action').perform('save');
|
||||||
self = this;
|
|
||||||
|
|
||||||
// Create and persist the new object, based on user
|
|
||||||
// input.
|
|
||||||
function persistResult(formValue) {
|
|
||||||
var parent = wizard.getLocation(formValue),
|
|
||||||
newModel = wizard.createModel(formValue);
|
|
||||||
return self.creationService.createObject(newModel, parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function doNothing() {
|
|
||||||
// Create cancelled, do nothing
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.dialogService.getUserInput(
|
|
||||||
wizard.getFormStructure(),
|
|
||||||
wizard.getInitialFormValue()
|
|
||||||
).then(persistResult, doNothing);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,11 +46,10 @@ define(
|
|||||||
* introduced in this bundle), responsible for handling actual
|
* introduced in this bundle), responsible for handling actual
|
||||||
* object creation.
|
* object creation.
|
||||||
*/
|
*/
|
||||||
function CreateActionProvider(typeService, dialogService, creationService, policyService) {
|
function CreateActionProvider($q, typeService, navigationService) {
|
||||||
this.typeService = typeService;
|
this.typeService = typeService;
|
||||||
this.dialogService = dialogService;
|
this.navigationService = navigationService;
|
||||||
this.creationService = creationService;
|
this.$q = $q;
|
||||||
this.policyService = policyService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateActionProvider.prototype.getActions = function (actionContext) {
|
CreateActionProvider.prototype.getActions = function (actionContext) {
|
||||||
@ -75,9 +74,8 @@ define(
|
|||||||
type,
|
type,
|
||||||
destination,
|
destination,
|
||||||
context,
|
context,
|
||||||
self.dialogService,
|
self.$q,
|
||||||
self.creationService,
|
self.navigationService
|
||||||
self.policyService
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -34,9 +34,9 @@ define(
|
|||||||
* @memberof platform/commonUI/browse
|
* @memberof platform/commonUI/browse
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function CreateWizard(type, parent, policyService) {
|
function CreateWizard(type, parent, policyService, initialModel) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.model = type.getInitialModel();
|
this.model = initialModel || type.getInitialModel();
|
||||||
this.properties = type.getProperties();
|
this.properties = type.getProperties();
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.policyService = policyService;
|
this.policyService = policyService;
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
* Module defining CreateService. Created by vwoeltje on 11/10/14.
|
* Module defining CreateService. Created by vwoeltje on 11/10/14.
|
||||||
*/
|
*/
|
||||||
define(
|
define(
|
||||||
["../../lib/uuid"],
|
[],
|
||||||
function (uuid) {
|
function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var NON_PERSISTENT_WARNING =
|
var NON_PERSISTENT_WARNING =
|
||||||
@ -42,11 +42,9 @@ define(
|
|||||||
* @memberof platform/commonUI/browse
|
* @memberof platform/commonUI/browse
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function CreationService(persistenceService, now, $q, $log) {
|
function CreationService($q, $log) {
|
||||||
this.persistenceService = persistenceService;
|
|
||||||
this.$q = $q;
|
this.$q = $q;
|
||||||
this.$log = $log;
|
this.$log = $log;
|
||||||
this.now = now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,26 +68,17 @@ define(
|
|||||||
*/
|
*/
|
||||||
CreationService.prototype.createObject = function (model, parent) {
|
CreationService.prototype.createObject = function (model, parent) {
|
||||||
var persistence = parent.getCapability("persistence"),
|
var persistence = parent.getCapability("persistence"),
|
||||||
|
newObject = parent.useCapability("instantiation", model),
|
||||||
|
newObjectPersistence = newObject.getCapability("persistence"),
|
||||||
self = this;
|
self = this;
|
||||||
|
|
||||||
// Persist the new domain object's model; it will be fully
|
|
||||||
// constituted as a domain object when loaded back, as all
|
|
||||||
// domain object models are.
|
|
||||||
function doPersist(space, id, model) {
|
|
||||||
return self.persistenceService.createObject(
|
|
||||||
space,
|
|
||||||
id,
|
|
||||||
model
|
|
||||||
).then(function () { return id; });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the newly-created object's id to the parent's
|
// Add the newly-created object's id to the parent's
|
||||||
// composition, so that it will subsequently appear
|
// composition, so that it will subsequently appear
|
||||||
// as a child contained by that parent.
|
// as a child contained by that parent.
|
||||||
function addToComposition(id, parent, parentPersistence) {
|
function addToComposition() {
|
||||||
var compositionCapability = parent.getCapability('composition'),
|
var compositionCapability = parent.getCapability('composition'),
|
||||||
addResult = compositionCapability &&
|
addResult = compositionCapability &&
|
||||||
compositionCapability.add(id);
|
compositionCapability.add(newObject);
|
||||||
|
|
||||||
return self.$q.when(addResult).then(function (result) {
|
return self.$q.when(addResult).then(function (result) {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@ -97,7 +86,7 @@ define(
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parentPersistence.persist().then(function () {
|
return persistence.persist().then(function () {
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -105,21 +94,13 @@ define(
|
|||||||
|
|
||||||
// We need the parent's persistence capability to determine
|
// We need the parent's persistence capability to determine
|
||||||
// what space to create the new object's model in.
|
// what space to create the new object's model in.
|
||||||
if (!persistence) {
|
if (!persistence || !newObjectPersistence) {
|
||||||
self.$log.warn(NON_PERSISTENT_WARNING);
|
self.$log.warn(NON_PERSISTENT_WARNING);
|
||||||
return self.$q.reject(new Error(NON_PERSISTENT_WARNING));
|
return self.$q.reject(new Error(NON_PERSISTENT_WARNING));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We create a new domain object in three sequential steps:
|
// Persist the new object, then add it to composition.
|
||||||
// 1. Get a new UUID for the object
|
return newObjectPersistence.persist().then(addToComposition);
|
||||||
// 2. Create a model with that ID in the persistence space
|
|
||||||
// 3. Add that ID to
|
|
||||||
return self.$q.when(uuid()).then(function (id) {
|
|
||||||
model.persisted = self.now();
|
|
||||||
return doPersist(persistence.getSpace(), id, model);
|
|
||||||
}).then(function (id) {
|
|
||||||
return addToComposition(id, parent, persistence);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,22 +22,24 @@
|
|||||||
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||||
|
|
||||||
define(
|
define(
|
||||||
["../src/BrowseTreeController"],
|
["../src/PaneController"],
|
||||||
function (BrowseTreeController) {
|
function (PaneController) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
describe("The BrowseTreeController", function () {
|
describe("The PaneController", function () {
|
||||||
var mockScope,
|
var mockScope,
|
||||||
mockAgentService,
|
mockAgentService,
|
||||||
mockDomainObjects,
|
mockDomainObjects,
|
||||||
|
mockWindow,
|
||||||
controller;
|
controller;
|
||||||
|
|
||||||
// We want to reinstantiate for each test case
|
// We want to reinstantiate for each test case
|
||||||
// because device state can influence constructor-time behavior
|
// because device state can influence constructor-time behavior
|
||||||
function instantiateController() {
|
function instantiateController() {
|
||||||
return new BrowseTreeController(
|
return new PaneController(
|
||||||
mockScope,
|
mockScope,
|
||||||
mockAgentService
|
mockAgentService,
|
||||||
|
mockWindow
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +60,7 @@ define(
|
|||||||
"agentService",
|
"agentService",
|
||||||
[ "isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape" ]
|
[ "isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape" ]
|
||||||
);
|
);
|
||||||
|
mockWindow = jasmine.createSpyObj("$window", ["open"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("is initially visible", function () {
|
it("is initially visible", function () {
|
@ -30,9 +30,7 @@ define(
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
describe("The creation service", function () {
|
describe("The creation service", function () {
|
||||||
var mockPersistenceService,
|
var mockQ,
|
||||||
mockNow,
|
|
||||||
mockQ,
|
|
||||||
mockLog,
|
mockLog,
|
||||||
mockParentObject,
|
mockParentObject,
|
||||||
mockNewObject,
|
mockNewObject,
|
||||||
@ -40,7 +38,9 @@ define(
|
|||||||
mockPersistenceCapability,
|
mockPersistenceCapability,
|
||||||
mockCompositionCapability,
|
mockCompositionCapability,
|
||||||
mockContextCapability,
|
mockContextCapability,
|
||||||
|
mockCreationCapability,
|
||||||
mockCapabilities,
|
mockCapabilities,
|
||||||
|
mockNewPersistenceCapability,
|
||||||
creationService;
|
creationService;
|
||||||
|
|
||||||
function mockPromise(value) {
|
function mockPromise(value) {
|
||||||
@ -60,11 +60,6 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
mockPersistenceService = jasmine.createSpyObj(
|
|
||||||
"persistenceService",
|
|
||||||
[ "createObject" ]
|
|
||||||
);
|
|
||||||
mockNow = jasmine.createSpy('now');
|
|
||||||
mockQ = { when: mockPromise, reject: mockReject };
|
mockQ = { when: mockPromise, reject: mockReject };
|
||||||
mockLog = jasmine.createSpyObj(
|
mockLog = jasmine.createSpyObj(
|
||||||
"$log",
|
"$log",
|
||||||
@ -76,7 +71,7 @@ define(
|
|||||||
);
|
);
|
||||||
mockNewObject = jasmine.createSpyObj(
|
mockNewObject = jasmine.createSpyObj(
|
||||||
"newObject",
|
"newObject",
|
||||||
[ "getId" ]
|
[ "getId", "getCapability", "useCapability" ]
|
||||||
);
|
);
|
||||||
mockMutationCapability = jasmine.createSpyObj(
|
mockMutationCapability = jasmine.createSpyObj(
|
||||||
"mutation",
|
"mutation",
|
||||||
@ -94,19 +89,22 @@ define(
|
|||||||
"context",
|
"context",
|
||||||
["getPath"]
|
["getPath"]
|
||||||
);
|
);
|
||||||
|
mockCreationCapability = jasmine.createSpyObj(
|
||||||
|
"creation",
|
||||||
|
["instantiate", "invoke"]
|
||||||
|
);
|
||||||
mockCapabilities = {
|
mockCapabilities = {
|
||||||
mutation: mockMutationCapability,
|
mutation: mockMutationCapability,
|
||||||
persistence: mockPersistenceCapability,
|
persistence: mockPersistenceCapability,
|
||||||
composition: mockCompositionCapability,
|
composition: mockCompositionCapability,
|
||||||
context: mockContextCapability
|
context: mockContextCapability,
|
||||||
|
instantiation: mockCreationCapability
|
||||||
};
|
};
|
||||||
|
mockNewPersistenceCapability = jasmine.createSpyObj(
|
||||||
mockPersistenceService.createObject.andReturn(
|
"new-persistence",
|
||||||
mockPromise(true)
|
[ "persist", "getSpace" ]
|
||||||
);
|
);
|
||||||
|
|
||||||
mockNow.andReturn(12321);
|
|
||||||
|
|
||||||
mockParentObject.getCapability.andCallFake(function (key) {
|
mockParentObject.getCapability.andCallFake(function (key) {
|
||||||
return mockCapabilities[key];
|
return mockCapabilities[key];
|
||||||
});
|
});
|
||||||
@ -115,9 +113,16 @@ define(
|
|||||||
});
|
});
|
||||||
mockParentObject.getId.andReturn('parentId');
|
mockParentObject.getId.andReturn('parentId');
|
||||||
|
|
||||||
mockPersistenceCapability.persist.andReturn(
|
mockNewObject.getId.andReturn('newId');
|
||||||
mockPromise(true)
|
mockNewObject.getCapability.andCallFake(function (c) {
|
||||||
);
|
return c === 'persistence' ?
|
||||||
|
mockNewPersistenceCapability : undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
mockPersistenceCapability.persist
|
||||||
|
.andReturn(mockPromise(true));
|
||||||
|
mockNewPersistenceCapability.persist
|
||||||
|
.andReturn(mockPromise(true));
|
||||||
|
|
||||||
mockMutationCapability.invoke.andReturn(mockPromise(true));
|
mockMutationCapability.invoke.andReturn(mockPromise(true));
|
||||||
mockPersistenceCapability.getSpace.andReturn("testSpace");
|
mockPersistenceCapability.getSpace.andReturn("testSpace");
|
||||||
@ -125,10 +130,12 @@ define(
|
|||||||
mockPromise([mockNewObject])
|
mockPromise([mockNewObject])
|
||||||
);
|
);
|
||||||
mockCompositionCapability.add.andReturn(mockPromise(true));
|
mockCompositionCapability.add.andReturn(mockPromise(true));
|
||||||
|
mockCreationCapability.instantiate.andReturn(mockNewObject);
|
||||||
|
mockCreationCapability.invoke.andCallFake(function (model) {
|
||||||
|
return mockCreationCapability.instantiate(model);
|
||||||
|
});
|
||||||
|
|
||||||
creationService = new CreationService(
|
creationService = new CreationService(
|
||||||
mockPersistenceService,
|
|
||||||
mockNow,
|
|
||||||
mockQ,
|
mockQ,
|
||||||
mockLog
|
mockLog
|
||||||
);
|
);
|
||||||
@ -137,21 +144,18 @@ define(
|
|||||||
it("allows new objects to be created", function () {
|
it("allows new objects to be created", function () {
|
||||||
var model = { someKey: "some value" };
|
var model = { someKey: "some value" };
|
||||||
creationService.createObject(model, mockParentObject);
|
creationService.createObject(model, mockParentObject);
|
||||||
expect(mockPersistenceService.createObject).toHaveBeenCalledWith(
|
expect(mockCreationCapability.instantiate)
|
||||||
"testSpace",
|
.toHaveBeenCalledWith(model);
|
||||||
jasmine.any(String), // the object id; generated UUID
|
|
||||||
model
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("adds new id's to the parent's composition", function () {
|
it("adds new objects to the parent's composition", function () {
|
||||||
var model = { someKey: "some value" },
|
var model = { someKey: "some value" },
|
||||||
parentModel = { composition: ["notAnyUUID"] };
|
parentModel = { composition: ["notAnyUUID"] };
|
||||||
creationService.createObject(model, mockParentObject);
|
creationService.createObject(model, mockParentObject);
|
||||||
|
|
||||||
// Verify that a new ID was added
|
// Verify that a new ID was added
|
||||||
expect(mockCompositionCapability.add)
|
expect(mockCompositionCapability.add)
|
||||||
.toHaveBeenCalledWith(jasmine.any(String));
|
.toHaveBeenCalledWith(mockNewObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("provides the newly-created object", function () {
|
it("provides the newly-created object", function () {
|
||||||
@ -207,11 +211,6 @@ define(
|
|||||||
expect(mockLog.error).toHaveBeenCalled();
|
expect(mockLog.error).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("attaches a 'persisted' timestamp", function () {
|
|
||||||
var model = { someKey: "some value" };
|
|
||||||
creationService.createObject(model, mockParentObject);
|
|
||||||
expect(model.persisted).toEqual(mockNow());
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[
|
[
|
||||||
"BrowseController",
|
"BrowseController",
|
||||||
"BrowseObjectController",
|
"BrowseObjectController",
|
||||||
"BrowseTreeController",
|
"PaneController",
|
||||||
"MenuArrowController",
|
"MenuArrowController",
|
||||||
"creation/CreateAction",
|
"creation/CreateAction",
|
||||||
"creation/CreateActionProvider",
|
"creation/CreateActionProvider",
|
||||||
|
@ -24,6 +24,18 @@
|
|||||||
{
|
{
|
||||||
"key": "form-dialog",
|
"key": "form-dialog",
|
||||||
"templateUrl": "templates/dialog.html"
|
"templateUrl": "templates/dialog.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "overlay-blocking-message",
|
||||||
|
"templateUrl": "templates/overlay-blocking-message.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "message",
|
||||||
|
"templateUrl": "templates/message.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "overlay-message-list",
|
||||||
|
"templateUrl": "templates/overlay-message-list.html"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"containers": [
|
"containers": [
|
||||||
|
@ -21,17 +21,13 @@
|
|||||||
-->
|
-->
|
||||||
<div class="abs top-bar">
|
<div class="abs top-bar">
|
||||||
<div class="title">{{ngModel.title}}</div>
|
<div class="title">{{ngModel.title}}</div>
|
||||||
<div class="hint">
|
<div class="hint">All fields marked <span class="ui-symbol req">*</span> are required.</div>
|
||||||
All fields marked <span class="ui-symbol req">*</span> are required.
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="abs form editor">
|
<div class='abs editor'>
|
||||||
<div class='abs contents l-dialog'>
|
<mct-form ng-model="ngModel.value"
|
||||||
<mct-form ng-model="ngModel.value"
|
structure="ngModel.structure"
|
||||||
structure="ngModel.structure"
|
name="createForm">
|
||||||
name="createForm">
|
</mct-form>
|
||||||
</mct-form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="abs bottom-bar">
|
<div class="abs bottom-bar">
|
||||||
<a class='s-btn major'
|
<a class='s-btn major'
|
||||||
|
32
platform/commonUI/dialog/res/templates/message.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<div class="l-message"
|
||||||
|
ng-class="'message-severity-' + ngModel.severity">
|
||||||
|
<div class="ui-symbol type-icon message-type"></div>
|
||||||
|
<div class="message-contents">
|
||||||
|
<div class="top-bar">
|
||||||
|
<div class="title">{{ngModel.title}}</div>
|
||||||
|
<div class="hint" ng-hide="ngModel.hint === undefined">{{ngModel.hint}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="message-body">
|
||||||
|
<div class="message-action">
|
||||||
|
{{ngModel.actionText}}
|
||||||
|
</div>
|
||||||
|
<mct-include key="'progress-bar'"
|
||||||
|
ng-model="ngModel"
|
||||||
|
ng-show="ngModel.progress !== undefined || ngModel.unknownProgress"></mct-include>
|
||||||
|
</div>
|
||||||
|
<div class="bottom-bar">
|
||||||
|
<a ng-repeat="dialogOption in ngModel.options"
|
||||||
|
class="s-btn major"
|
||||||
|
ng-click="dialogOption.callback()">
|
||||||
|
{{dialogOption.label}}
|
||||||
|
</a>
|
||||||
|
<a class="s-btn major"
|
||||||
|
ng-if="ngModel.primaryOption"
|
||||||
|
ng-click="ngModel.primaryOption.callback()">
|
||||||
|
{{ngModel.primaryOption.label}}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,25 @@
|
|||||||
|
<!--
|
||||||
|
Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
Administration. All rights reserved.
|
||||||
|
|
||||||
|
Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
Open MCT Web includes source code licensed under additional open source
|
||||||
|
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
this source code distribution or the Licensing information page available
|
||||||
|
at runtime from the About dialog for additional information.
|
||||||
|
-->
|
||||||
|
<mct-container key="overlay" class="t-message-single">
|
||||||
|
<mct-include key="'message'" ng-model="ngModel">
|
||||||
|
</mct-include>
|
||||||
|
</mct-container>
|
@ -0,0 +1,19 @@
|
|||||||
|
<mct-container key="overlay" class="t-message-list">
|
||||||
|
<div class="message-contents">
|
||||||
|
<div class="abs top-bar">
|
||||||
|
<div class="title">{{ngModel.dialog.title}}</div>
|
||||||
|
<div class="hint">Displaying {{ngModel.dialog.messages.length}} message<span ng-show="ngModel.dialog.messages.length > 1">s</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="abs message-body">
|
||||||
|
<mct-include ng-repeat="msg in ngModel.dialog.messages | orderBy: '-'" key="'message'" ng-model="msg"></mct-include>
|
||||||
|
</div>
|
||||||
|
<div class="abs bottom-bar">
|
||||||
|
<a ng-repeat="dialogAction in ngModel.dialog.actions"
|
||||||
|
class="s-btn major"
|
||||||
|
ng-click="dialogAction.action()">
|
||||||
|
{{dialogAction.label}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</mct-container>
|
@ -24,13 +24,11 @@
|
|||||||
<div class="title">{{ngModel.dialog.title}}</div>
|
<div class="title">{{ngModel.dialog.title}}</div>
|
||||||
<div class="hint">{{ngModel.dialog.hint}}</div>
|
<div class="hint">{{ngModel.dialog.hint}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="abs form outline editor">
|
<div class='abs editor'>
|
||||||
<div class='abs contents l-dialog'>
|
<mct-include key="ngModel.dialog.template"
|
||||||
<mct-include key="ngModel.dialog.template"
|
parameters="ngModel.dialog.parameters"
|
||||||
parameters="ngModel.dialog.parameters"
|
ng-model="ngModel.dialog.model">
|
||||||
ng-model="ngModel.dialog.model">
|
</mct-include>
|
||||||
</mct-include>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="abs bottom-bar">
|
<div class="abs bottom-bar">
|
||||||
<a ng-repeat="option in ngModel.dialog.options"
|
<a ng-repeat="option in ngModel.dialog.options"
|
||||||
|
@ -22,14 +22,9 @@
|
|||||||
<div class="abs overlay">
|
<div class="abs overlay">
|
||||||
<div class="abs blocker"></div>
|
<div class="abs blocker"></div>
|
||||||
<div class="abs holder">
|
<div class="abs holder">
|
||||||
<a href=""
|
<a ng-click="ngModel.cancel()"
|
||||||
ng-click="ngModel.cancel()"
|
|
||||||
ng-if="ngModel.cancel"
|
ng-if="ngModel.cancel"
|
||||||
class="clk-icon icon ui-symbol close">
|
class="clk-icon icon ui-symbol close">x</a>
|
||||||
x
|
<div class="abs contents" ng-transclude></div>
|
||||||
</a>
|
|
||||||
<div class="abs contents" ng-transclude>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -55,7 +55,7 @@ define(
|
|||||||
this.dialogVisible = false;
|
this.dialogVisible = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
DialogService.prototype.getDialogResponse = function (key, model, resultGetter) {
|
DialogService.prototype.getDialogResponse = function (key, model, resultGetter, typeClass) {
|
||||||
// We will return this result as a promise, because user
|
// We will return this result as a promise, because user
|
||||||
// input is asynchronous.
|
// input is asynchronous.
|
||||||
var deferred = this.$q.defer(),
|
var deferred = this.$q.defer(),
|
||||||
@ -84,27 +84,20 @@ define(
|
|||||||
model.confirm = confirm;
|
model.confirm = confirm;
|
||||||
model.cancel = cancel;
|
model.cancel = cancel;
|
||||||
|
|
||||||
if (this.dialogVisible) {
|
if (this.canShowDialog(model)) {
|
||||||
// Only one dialog should be shown at a time.
|
|
||||||
// The application design should be such that
|
|
||||||
// we never even try to do this.
|
|
||||||
this.$log.warn([
|
|
||||||
"Dialog already showing; ",
|
|
||||||
"unable to show ",
|
|
||||||
model.name
|
|
||||||
].join(""));
|
|
||||||
deferred.reject();
|
|
||||||
} else {
|
|
||||||
// Add the overlay using the OverlayService, which
|
// Add the overlay using the OverlayService, which
|
||||||
// will handle actual insertion into the DOM
|
// will handle actual insertion into the DOM
|
||||||
this.overlay = this.overlayService.createOverlay(
|
this.overlay = this.overlayService.createOverlay(
|
||||||
key,
|
key,
|
||||||
model
|
model,
|
||||||
|
typeClass || "t-dialog"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Track that a dialog is already visible, to
|
// Track that a dialog is already visible, to
|
||||||
// avoid spawning multiple dialogs at once.
|
// avoid spawning multiple dialogs at once.
|
||||||
this.dialogVisible = true;
|
this.dialogVisible = true;
|
||||||
|
} else {
|
||||||
|
deferred.reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
@ -157,6 +150,99 @@ define(
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if a dialog can be displayed. A modal dialog may only be
|
||||||
|
* displayed if one is not already visible.
|
||||||
|
* Will log a warning message if it can't display a dialog.
|
||||||
|
* @returns {boolean} true if dialog is currently visible, false
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
DialogService.prototype.canShowDialog = function(dialogModel){
|
||||||
|
if (this.dialogVisible){
|
||||||
|
// Only one dialog should be shown at a time.
|
||||||
|
// The application design should be such that
|
||||||
|
// we never even try to do this.
|
||||||
|
this.$log.warn([
|
||||||
|
"Dialog already showing; ",
|
||||||
|
"unable to show ",
|
||||||
|
dialogModel.title
|
||||||
|
].join(""));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A user action that can be performed from a blocking dialog. These
|
||||||
|
* actions will be rendered as buttons within a blocking dialog.
|
||||||
|
*
|
||||||
|
* @typedef DialogOption
|
||||||
|
* @property {string} label a label to be displayed as the button
|
||||||
|
* text for this action
|
||||||
|
* @property {function} callback a function to be called when the
|
||||||
|
* button is clicked
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A description of the model options that may be passed to the
|
||||||
|
* showBlockingMessage method. Note that the DialogModel desribed
|
||||||
|
* here is shared with the Notifications framework.
|
||||||
|
* @see NotificationService
|
||||||
|
*
|
||||||
|
* @typedef DialogModel
|
||||||
|
* @property {string} title the title to use for the dialog
|
||||||
|
* @property {string} severity the severity level of this message.
|
||||||
|
* These are defined in a bundle constant with key 'dialogSeverity'
|
||||||
|
* @property {string} hint the 'hint' message to show below the title
|
||||||
|
* @property {string} actionText text that indicates a current action,
|
||||||
|
* shown above a progress bar to indicate what's happening.
|
||||||
|
* @property {number} progress a percentage value (1-100)
|
||||||
|
* indicating the completion of the blocking task
|
||||||
|
* @property {string} progressText the message to show below a
|
||||||
|
* progress bar to indicate progress. For example, this might be
|
||||||
|
* used to indicate time remaining, or items still to process.
|
||||||
|
* @property {boolean} unknownProgress some tasks may be
|
||||||
|
* impossible to provide an estimate for. Providing a true value for
|
||||||
|
* this attribute will indicate to the user that the progress and
|
||||||
|
* duration cannot be estimated.
|
||||||
|
* @property {DialogOption} primaryOption an action that will
|
||||||
|
* be added to the dialog as a button. The primary action can be
|
||||||
|
* used as the suggested course of action for the user. Making it
|
||||||
|
* distinct from other actions allows it to be styled differently,
|
||||||
|
* and treated preferentially in banner mode.
|
||||||
|
* @property {DialogOption[]} options a list of actions that will
|
||||||
|
* be added to the dialog as buttons.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a blocking (modal) dialog. This dialog can be used for
|
||||||
|
* displaying messages that require the user's
|
||||||
|
* immediate attention. The message may include an indication of
|
||||||
|
* progress, as well as a series of actions that
|
||||||
|
* the user can take if necessary
|
||||||
|
* @param {DialogModel} dialogModel defines options for the dialog
|
||||||
|
* @param {typeClass} string tells overlayService that this overlay should use appropriate CSS class
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
DialogService.prototype.showBlockingMessage = function(dialogModel) {
|
||||||
|
if (this.canShowDialog(dialogModel)) {
|
||||||
|
// Add the overlay using the OverlayService, which
|
||||||
|
// will handle actual insertion into the DOM
|
||||||
|
this.overlay = this.overlayService.createOverlay(
|
||||||
|
"overlay-blocking-message",
|
||||||
|
dialogModel,
|
||||||
|
"t-dialog-sm"
|
||||||
|
);
|
||||||
|
// Track that a dialog is already visible, to
|
||||||
|
// avoid spawning multiple dialogs at once.
|
||||||
|
this.dialogVisible = true;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return DialogService;
|
return DialogService;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ define(
|
|||||||
|
|
||||||
// Template to inject into the DOM to show the dialog; really just points to
|
// Template to inject into the DOM to show the dialog; really just points to
|
||||||
// the a specific template that can be included via mct-include
|
// the a specific template that can be included via mct-include
|
||||||
var TEMPLATE = '<mct-include ng-model="overlay" key="key"></mct-include>';
|
var TEMPLATE = '<mct-include ng-model="overlay" key="key" ng-class="typeClass"></mct-include>';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,8 +71,11 @@ define(
|
|||||||
* @param {object} overlayModel the model to pass to the
|
* @param {object} overlayModel the model to pass to the
|
||||||
* included overlay template (this will be passed
|
* included overlay template (this will be passed
|
||||||
* in via ng-model)
|
* in via ng-model)
|
||||||
|
* @param {string} typeClass the element class to use in rendering
|
||||||
|
* the overlay. Can be specified to provide custom styling of
|
||||||
|
* overlays
|
||||||
*/
|
*/
|
||||||
OverlayService.prototype.createOverlay = function (key, overlayModel) {
|
OverlayService.prototype.createOverlay = function (key, overlayModel, typeClass) {
|
||||||
// Create a new scope for this overlay
|
// Create a new scope for this overlay
|
||||||
var scope = this.newScope(),
|
var scope = this.newScope(),
|
||||||
element;
|
element;
|
||||||
@ -90,6 +93,7 @@ define(
|
|||||||
// Populate the scope; will be passed directly to the template
|
// Populate the scope; will be passed directly to the template
|
||||||
scope.overlay = overlayModel;
|
scope.overlay = overlayModel;
|
||||||
scope.key = key;
|
scope.key = key;
|
||||||
|
scope.typeClass = typeClass || 't-dialog';
|
||||||
|
|
||||||
// Create the overlay element and add it to the document's body
|
// Create the overlay element and add it to the document's body
|
||||||
element = this.$compile(TEMPLATE)(scope);
|
element = this.$compile(TEMPLATE)(scope);
|
||||||
|
@ -116,7 +116,19 @@ define(
|
|||||||
dialog: dialogModel,
|
dialog: dialogModel,
|
||||||
confirm: jasmine.any(Function),
|
confirm: jasmine.any(Function),
|
||||||
cancel: jasmine.any(Function)
|
cancel: jasmine.any(Function)
|
||||||
}
|
},
|
||||||
|
't-dialog'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("invokes the overlay service with the correct parameters when" +
|
||||||
|
" a blocking dialog is requested", function() {
|
||||||
|
var dialogModel = {};
|
||||||
|
expect(dialogService.showBlockingMessage(dialogModel)).toBe(true);
|
||||||
|
expect(mockOverlayService.createOverlay).toHaveBeenCalledWith(
|
||||||
|
"overlay-blocking-message",
|
||||||
|
dialogModel,
|
||||||
|
"t-dialog-sm"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,6 +21,11 @@
|
|||||||
"key": "EditPanesController",
|
"key": "EditPanesController",
|
||||||
"implementation": "controllers/EditPanesController.js",
|
"implementation": "controllers/EditPanesController.js",
|
||||||
"depends": [ "$scope" ]
|
"depends": [ "$scope" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "ElementsController",
|
||||||
|
"implementation": "controllers/ElementsController.js",
|
||||||
|
"depends": [ "$scope" ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"directives": [
|
"directives": [
|
||||||
@ -38,7 +43,7 @@
|
|||||||
{
|
{
|
||||||
"key": "edit",
|
"key": "edit",
|
||||||
"implementation": "actions/EditAction.js",
|
"implementation": "actions/EditAction.js",
|
||||||
"depends": [ "$location", "navigationService", "$log" ],
|
"depends": [ "$location", "navigationService", "$log", "$q" ],
|
||||||
"description": "Edit this object.",
|
"description": "Edit this object.",
|
||||||
"category": "view-control",
|
"category": "view-control",
|
||||||
"glyph": "p"
|
"glyph": "p"
|
||||||
@ -67,7 +72,9 @@
|
|||||||
"implementation": "actions/SaveAction.js",
|
"implementation": "actions/SaveAction.js",
|
||||||
"name": "Save",
|
"name": "Save",
|
||||||
"description": "Save changes made to these objects.",
|
"description": "Save changes made to these objects.",
|
||||||
"depends": [ "$location", "urlService" ],
|
"depends": [ "$q", "$location", "$injector", "urlService",
|
||||||
|
"navigationService", "policyService", "dialogService",
|
||||||
|
"creationService" ],
|
||||||
"priority": "mandatory"
|
"priority": "mandatory"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -76,7 +83,7 @@
|
|||||||
"implementation": "actions/CancelAction.js",
|
"implementation": "actions/CancelAction.js",
|
||||||
"name": "Cancel",
|
"name": "Cancel",
|
||||||
"description": "Discard changes made to these objects.",
|
"description": "Discard changes made to these objects.",
|
||||||
"depends": [ "$location", "urlService" ]
|
"depends": ["$injector", "navigationService"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"policies": [
|
"policies": [
|
||||||
|
@ -21,10 +21,11 @@
|
|||||||
-->
|
-->
|
||||||
<span ng-controller="EditActionController">
|
<span ng-controller="EditActionController">
|
||||||
<span ng-repeat="currentAction in editActions">
|
<span ng-repeat="currentAction in editActions">
|
||||||
<a class='s-btn'
|
<a class='s-btn t-{{currentAction.getMetadata().key}}'
|
||||||
|
title='{{currentAction.getMetadata().name}}'
|
||||||
ng-click="currentAction.perform()"
|
ng-click="currentAction.perform()"
|
||||||
ng-class="{ major: $index === 0, subtle: $index !== 0 }">
|
ng-class="{ major: $index === 0 }">
|
||||||
{{currentAction.getMetadata().name}}
|
<span class="title-label">{{currentAction.getMetadata().name}}</span>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
@ -30,12 +30,11 @@
|
|||||||
structure="toolbar.structure"
|
structure="toolbar.structure"
|
||||||
ng-model="toolbar.state">
|
ng-model="toolbar.state">
|
||||||
</mct-toolbar>
|
</mct-toolbar>
|
||||||
<div class='holder abs object-holder work-area'>
|
<mct-representation key="representation.selected.key"
|
||||||
<mct-representation key="representation.selected.key"
|
toolbar="toolbar"
|
||||||
toolbar="toolbar"
|
mct-object="representation.selected.key && domainObject"
|
||||||
mct-object="representation.selected.key && domainObject">
|
class="holder abs object-holder work-area">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<mct-splitter></mct-splitter>
|
<mct-splitter></mct-splitter>
|
||||||
<div
|
<div
|
||||||
|
@ -19,14 +19,21 @@
|
|||||||
this source code distribution or the Licensing information page available
|
this source code distribution or the Licensing information page available
|
||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<div class="current-elements abs" style="height: 100%;">
|
<div ng-controller="ElementsController">
|
||||||
<!--p class="hint">Drop objects here to add them...</p-->
|
<mct-include key="'input-filter'"
|
||||||
<ul class="tree">
|
class="flex-elem holder"
|
||||||
<li ng-repeat="containedObject in composition">
|
ng-model="filterBy">
|
||||||
<span class="tree-item">
|
</mct-include>
|
||||||
<mct-representation key="'label'" mct-object="containedObject">
|
<div>{{searchText}}</div>
|
||||||
</mct-representation>
|
<div class="current-elements abs" style="height: 100%;">
|
||||||
</span>
|
<!--p class="hint">Drop objects here to add them...</p-->
|
||||||
</li>
|
<ul class="tree">
|
||||||
</ul>
|
<li ng-repeat="containedObject in composition | filter:searchText">
|
||||||
|
<span class="tree-item">
|
||||||
|
<mct-representation key="'label'" mct-object="containedObject">
|
||||||
|
</mct-representation>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -22,7 +22,8 @@
|
|||||||
<div class='top-bar edit abs'>
|
<div class='top-bar edit abs'>
|
||||||
<mct-representation key="'object-header'"
|
<mct-representation key="'object-header'"
|
||||||
mct-object="domainObject"
|
mct-object="domainObject"
|
||||||
parameters="{ mode: 'Edit' }">
|
parameters="{ mode: 'Edit' }"
|
||||||
|
class="l-flex-row flex-elem grows object-header">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
<div class='buttons-main btn-bar buttons abs'>
|
<div class='buttons-main btn-bar buttons abs'>
|
||||||
<mct-representation key="'switcher'"
|
<mct-representation key="'switcher'"
|
||||||
|
@ -33,10 +33,10 @@ define(
|
|||||||
* @memberof platform/commonUI/edit
|
* @memberof platform/commonUI/edit
|
||||||
* @implements {Action}
|
* @implements {Action}
|
||||||
*/
|
*/
|
||||||
function CancelAction($location, urlService, context) {
|
function CancelAction($injector, navigationService, context) {
|
||||||
this.domainObject = context.domainObject;
|
this.domainObject = context.domainObject;
|
||||||
this.$location = $location;
|
this.navigationService = navigationService;
|
||||||
this.urlService = urlService;
|
this.objectService = $injector.get('objectService');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,8 +47,7 @@ define(
|
|||||||
*/
|
*/
|
||||||
CancelAction.prototype.perform = function () {
|
CancelAction.prototype.perform = function () {
|
||||||
var domainObject = this.domainObject,
|
var domainObject = this.domainObject,
|
||||||
$location = this.$location,
|
self = this;
|
||||||
urlService = this.urlService;
|
|
||||||
|
|
||||||
// Look up the object's "editor.completion" capability;
|
// Look up the object's "editor.completion" capability;
|
||||||
// this is introduced by EditableDomainObject which is
|
// this is introduced by EditableDomainObject which is
|
||||||
@ -64,13 +63,10 @@ define(
|
|||||||
return editor.cancel();
|
return editor.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discard the current root view (which will be the editing
|
//Discard current 'editable' object, and retrieve original
|
||||||
// UI, which will have been pushed atop the Browise UI.)
|
// un-edited object.
|
||||||
function returnToBrowse() {
|
function returnToBrowse() {
|
||||||
$location.path($location.path(urlService.urlForLocation(
|
return self.navigationService.setNavigation(self.domainObject.getOriginalObject());
|
||||||
"browse",
|
|
||||||
domainObject
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return doCancel(getEditorCapability())
|
return doCancel(getEditorCapability())
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
* Module defining EditAction. Created by vwoeltje on 11/14/14.
|
* Module defining EditAction. Created by vwoeltje on 11/14/14.
|
||||||
*/
|
*/
|
||||||
define(
|
define(
|
||||||
[],
|
['../objects/EditableDomainObject'],
|
||||||
function () {
|
function (EditableDomainObject) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// A no-op action to return in the event that the action cannot
|
// A no-op action to return in the event that the action cannot
|
||||||
@ -46,7 +46,7 @@ define(
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @implements {Action}
|
* @implements {Action}
|
||||||
*/
|
*/
|
||||||
function EditAction($location, navigationService, $log, context) {
|
function EditAction($location, navigationService, $log, $q, context) {
|
||||||
var domainObject = (context || {}).domainObject;
|
var domainObject = (context || {}).domainObject;
|
||||||
|
|
||||||
// We cannot enter Edit mode if we have no domain object to
|
// We cannot enter Edit mode if we have no domain object to
|
||||||
@ -65,14 +65,20 @@ define(
|
|||||||
this.domainObject = domainObject;
|
this.domainObject = domainObject;
|
||||||
this.$location = $location;
|
this.$location = $location;
|
||||||
this.navigationService = navigationService;
|
this.navigationService = navigationService;
|
||||||
|
this.$q = $q;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enter edit mode.
|
* Enter edit mode.
|
||||||
*/
|
*/
|
||||||
EditAction.prototype.perform = function () {
|
EditAction.prototype.perform = function () {
|
||||||
this.navigationService.setNavigation(this.domainObject);
|
var editableObject;
|
||||||
this.$location.path("/edit");
|
if (!this.domainObject.hasCapability("editor")) {
|
||||||
|
editableObject = new EditableDomainObject(this.domainObject, this.$q);
|
||||||
|
editableObject.getCapability('status').set('editing', true);
|
||||||
|
this.navigationService.setNavigation(editableObject);
|
||||||
|
}
|
||||||
|
//this.$location.path("/edit");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,10 +89,11 @@ define(
|
|||||||
*/
|
*/
|
||||||
EditAction.appliesTo = function (context) {
|
EditAction.appliesTo = function (context) {
|
||||||
var domainObject = (context || {}).domainObject,
|
var domainObject = (context || {}).domainObject,
|
||||||
type = domainObject && domainObject.getCapability('type');
|
type = domainObject && domainObject.getCapability('type'),
|
||||||
|
isEditMode = domainObject && domainObject.getDomainObject ? true : false;
|
||||||
|
|
||||||
// Only allow creatable types to be edited
|
// Only allow creatable types to be edited
|
||||||
return type && type.hasFeature('creation');
|
return type && type.hasFeature('creation') && !isEditMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
return EditAction;
|
return EditAction;
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
|
|
||||||
|
|
||||||
define(
|
define(
|
||||||
function () {
|
['../../../browse/src/creation/CreateWizard'],
|
||||||
|
function (CreateWizard) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,10 +35,26 @@ define(
|
|||||||
* @implements {Action}
|
* @implements {Action}
|
||||||
* @memberof platform/commonUI/edit
|
* @memberof platform/commonUI/edit
|
||||||
*/
|
*/
|
||||||
function SaveAction($location, urlService, context) {
|
function SaveAction($q, $location, $injector, urlService, navigationService, policyService, dialogService, creationService, context) {
|
||||||
this.domainObject = (context || {}).domainObject;
|
this.domainObject = (context || {}).domainObject;
|
||||||
this.$location = $location;
|
this.$location = $location;
|
||||||
|
this.injectObjectService = function(){
|
||||||
|
this.objectService = $injector.get("objectService");
|
||||||
|
}
|
||||||
this.urlService = urlService;
|
this.urlService = urlService;
|
||||||
|
this.navigationService = navigationService;
|
||||||
|
this.policyService = policyService;
|
||||||
|
this.dialogService = dialogService;
|
||||||
|
this.creationService = creationService;
|
||||||
|
this.$q = $q;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveAction.prototype.getObjectService = function(){
|
||||||
|
// Lazily acquire object service (avoids cyclical dependency)
|
||||||
|
if (!this.objectService) {
|
||||||
|
this.injectObjectService();
|
||||||
|
}
|
||||||
|
return this.objectService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,25 +67,138 @@ define(
|
|||||||
SaveAction.prototype.perform = function () {
|
SaveAction.prototype.perform = function () {
|
||||||
var domainObject = this.domainObject,
|
var domainObject = this.domainObject,
|
||||||
$location = this.$location,
|
$location = this.$location,
|
||||||
urlService = this.urlService;
|
urlService = this.urlService,
|
||||||
|
self = this;
|
||||||
|
|
||||||
|
function resolveWith(object){
|
||||||
|
return function() {return object};
|
||||||
|
}
|
||||||
|
|
||||||
|
function doWizardSave(parent) {
|
||||||
|
var context = domainObject.getCapability("context");
|
||||||
|
var wizard = new CreateWizard(domainObject.useCapability('type'), parent, self.policyService, domainObject.getModel());
|
||||||
|
|
||||||
|
function mergeObjects(fromObject, toObject){
|
||||||
|
Object.keys(fromObject).forEach(function(key) {
|
||||||
|
toObject[key] = fromObject[key];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and persist the new object, based on user
|
||||||
|
// input.
|
||||||
|
function buildObjectFromInput(formValue) {
|
||||||
|
var parent = wizard.getLocation(formValue),
|
||||||
|
formModel = wizard.createModel(formValue);
|
||||||
|
|
||||||
|
formModel.location = parent.getId();
|
||||||
|
//Replace domain object model with model collected
|
||||||
|
// from user form.
|
||||||
|
domainObject.useCapability("mutation", function(){
|
||||||
|
//Replace object model with the model from the form
|
||||||
|
return formModel;
|
||||||
|
});
|
||||||
|
return domainObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doNothing() {
|
||||||
|
// Create cancelled, do nothing
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAllComposees(domainObject){
|
||||||
|
return domainObject.useCapability('composition');
|
||||||
|
}
|
||||||
|
|
||||||
|
function addComposeesToObject(object){
|
||||||
|
return function(composees){
|
||||||
|
return self.$q.all(composees.map(function (composee) {
|
||||||
|
return object.getCapability('composition').add(composee);
|
||||||
|
})).then(resolveWith(object));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the composees of the 'virtual' object to the
|
||||||
|
* persisted object
|
||||||
|
* @param object
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function composeNewObject(object){
|
||||||
|
if (self.$q.when(object.hasCapability('composition') && domainObject.hasCapability('composition'))) {
|
||||||
|
return getAllComposees(domainObject)
|
||||||
|
.then(addComposeesToObject(object))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.dialogService
|
||||||
|
.getUserInput(wizard.getFormStructure(), wizard.getInitialFormValue())
|
||||||
|
.then(buildObjectFromInput, doNothing)
|
||||||
|
//.then(composeNewObject)
|
||||||
|
//.then(object.getCapability("persistence"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function persistObject(object){
|
||||||
|
|
||||||
|
return (object.hasCapability('editor') && object.getCapability('editor').save(true) || object.getCapability('persistence').persist())
|
||||||
|
.then(resolveWith(object));
|
||||||
|
/*
|
||||||
|
if (object.hasCapability('editor')){
|
||||||
|
return object.getCapability('editor').save(true)
|
||||||
|
.then(resolveWith(object));
|
||||||
|
} else {
|
||||||
|
return object.useCapability(persistence);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchObject(objectId){
|
||||||
|
return self.getObjectService().getObjects([objectId]).then(function(objects){
|
||||||
|
return objects[objectId];
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getParent(object){
|
||||||
|
return fetchObject(object.getModel().location);
|
||||||
|
}
|
||||||
|
|
||||||
|
function locateObjectInParent(parent){
|
||||||
|
parent.getCapability('composition').add(domainObject.getId());
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
// Invoke any save behavior introduced by the editor capability;
|
// Invoke any save behavior introduced by the editor capability;
|
||||||
// this is introduced by EditableDomainObject which is
|
// this is introduced by EditableDomainObject which is
|
||||||
// used to insulate underlying objects from changes made
|
// used to insulate underlying objects from changes made
|
||||||
// during editing.
|
// during editing.
|
||||||
function doSave() {
|
function doSave() {
|
||||||
return domainObject.getCapability("editor").save();
|
//WARNING: HACK
|
||||||
|
//This is a new 'virtual object' that has not been persisted
|
||||||
|
// yet.
|
||||||
|
if (!domainObject.getModel().persisted){
|
||||||
|
return getParent(domainObject)
|
||||||
|
.then(doWizardSave)
|
||||||
|
.then(persistObject)
|
||||||
|
.then(getParent)//Parent may have changed based
|
||||||
|
// on user selection
|
||||||
|
.then(locateObjectInParent)
|
||||||
|
.then(persistObject)
|
||||||
|
.then(function(){return fetchObject(domainObject.getId());})
|
||||||
|
} else {
|
||||||
|
return domainObject.getCapability("editor").save()
|
||||||
|
.then(resolveWith(domainObject.getOriginalObject()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discard the current root view (which will be the editing
|
// Discard the current root view (which will be the editing
|
||||||
// UI, which will have been pushed atop the Browise UI.)
|
// UI, which will have been pushed atop the Browse UI.)
|
||||||
function returnToBrowse() {
|
function returnToBrowse(object) {
|
||||||
return $location.path(urlService.urlForLocation(
|
if (object) {
|
||||||
"browse",
|
self.navigationService.setNavigation(object);
|
||||||
domainObject
|
}
|
||||||
));
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//return doSave().then(returnToBrowse);
|
||||||
return doSave().then(returnToBrowse);
|
return doSave().then(returnToBrowse);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ define(
|
|||||||
EditorCapability.prototype.save = function (nonrecursive) {
|
EditorCapability.prototype.save = function (nonrecursive) {
|
||||||
var domainObject = this.domainObject,
|
var domainObject = this.domainObject,
|
||||||
editableObject = this.editableObject,
|
editableObject = this.editableObject,
|
||||||
|
self = this,
|
||||||
cache = this.cache;
|
cache = this.cache;
|
||||||
|
|
||||||
// Update the underlying, "real" domain object's model
|
// Update the underlying, "real" domain object's model
|
||||||
@ -95,8 +96,10 @@ define(
|
|||||||
return domainObject.getCapability('persistence').persist();
|
return domainObject.getCapability('persistence').persist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editableObject.getCapability("status").set("editing", false);
|
||||||
|
|
||||||
return nonrecursive ?
|
return nonrecursive ?
|
||||||
resolvePromise(doMutate()).then(doPersist) :
|
resolvePromise(doMutate()).then(doPersist).then(function(){self.cancel()}) :
|
||||||
resolvePromise(cache.saveAll());
|
resolvePromise(cache.saveAll());
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -109,6 +112,8 @@ define(
|
|||||||
* @memberof platform/commonUI/edit.EditorCapability#
|
* @memberof platform/commonUI/edit.EditorCapability#
|
||||||
*/
|
*/
|
||||||
EditorCapability.prototype.cancel = function () {
|
EditorCapability.prototype.cancel = function () {
|
||||||
|
this.editableObject.getCapability("status").set("editing", false);
|
||||||
|
//TODO: Reset the cache as well here.
|
||||||
return resolvePromise(undefined);
|
return resolvePromise(undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,43 +21,26 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
/*global define,Promise*/
|
/*global define,Promise*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14.
|
|
||||||
*/
|
|
||||||
define(
|
define(
|
||||||
[],
|
[],
|
||||||
function () {
|
function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var firstObservedTime = Date.now();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The ElementsController prepares the elements view for display
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function SinewaveTelemetry(request) {
|
function ElementsController($scope) {
|
||||||
var latestObservedTime = Date.now(),
|
function filterBy(text){
|
||||||
count = Math.floor((latestObservedTime - firstObservedTime) / 1000),
|
if (typeof text === 'undefined')
|
||||||
period = request.period || 30,
|
return $scope.searchText;
|
||||||
generatorData = {};
|
else
|
||||||
|
$scope.searchText = text;
|
||||||
generatorData.getPointCount = function () {
|
}
|
||||||
return count;
|
$scope.filterBy = filterBy;
|
||||||
};
|
|
||||||
|
|
||||||
generatorData.getDomainValue = function (i, domain) {
|
|
||||||
return i * 1000 +
|
|
||||||
(domain !== 'delta' ? firstObservedTime : 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
generatorData.getRangeValue = function (i, range) {
|
|
||||||
range = range || "sin";
|
|
||||||
return Math[range](i * Math.PI * 2 / period);
|
|
||||||
};
|
|
||||||
|
|
||||||
return generatorData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SinewaveTelemetry;
|
return ElementsController;
|
||||||
}
|
}
|
||||||
);
|
);
|
@ -78,7 +78,9 @@ define(
|
|||||||
// different versions of the same editable domain object
|
// different versions of the same editable domain object
|
||||||
// are not shown in different sections of the same Edit
|
// are not shown in different sections of the same Edit
|
||||||
// UI, which might thereby fall out of sync.
|
// UI, which might thereby fall out of sync.
|
||||||
var cache;
|
var cache,
|
||||||
|
originalObject = domainObject,
|
||||||
|
cachedObject;
|
||||||
|
|
||||||
// Constructor for EditableDomainObject, which adheres
|
// Constructor for EditableDomainObject, which adheres
|
||||||
// to the same shared cache.
|
// to the same shared cache.
|
||||||
@ -102,12 +104,22 @@ define(
|
|||||||
capability;
|
capability;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
editableObject.setOriginalObject = function(object) {
|
||||||
|
originalObject = object;
|
||||||
|
};
|
||||||
|
|
||||||
|
editableObject.getOriginalObject = function() {
|
||||||
|
return originalObject;
|
||||||
|
};
|
||||||
|
|
||||||
return editableObject;
|
return editableObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache = new EditableDomainObjectCache(EditableDomainObjectImpl, $q);
|
cache = new EditableDomainObjectCache(EditableDomainObjectImpl, $q);
|
||||||
|
cachedObject = cache.getEditableObject(domainObject);
|
||||||
|
|
||||||
return cache.getEditableObject(domainObject);
|
return cachedObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EditableDomainObject;
|
return EditableDomainObject;
|
||||||
|
@ -69,7 +69,9 @@ define(
|
|||||||
*/
|
*/
|
||||||
EditableDomainObjectCache.prototype.getEditableObject = function (domainObject) {
|
EditableDomainObjectCache.prototype.getEditableObject = function (domainObject) {
|
||||||
var type = domainObject.getCapability('type'),
|
var type = domainObject.getCapability('type'),
|
||||||
EditableDomainObject = this.EditableDomainObject;
|
EditableDomainObject = this.EditableDomainObject,
|
||||||
|
editableObject,
|
||||||
|
statusListener;
|
||||||
|
|
||||||
// Track the top-level domain object; this will have
|
// Track the top-level domain object; this will have
|
||||||
// some special behavior for its context capability.
|
// some special behavior for its context capability.
|
||||||
@ -86,10 +88,12 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Provide an editable form of the object
|
// Provide an editable form of the object
|
||||||
return new EditableDomainObject(
|
editableObject = new EditableDomainObject(
|
||||||
domainObject,
|
domainObject,
|
||||||
this.cache.getCachedModel(domainObject)
|
this.cache.getCachedModel(domainObject)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return editableObject;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,6 +51,19 @@ define(
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the domain object is currently being edited. If
|
||||||
|
* so, the edit action is not applicable.
|
||||||
|
* @param context
|
||||||
|
* @returns {*|boolean}
|
||||||
|
*/
|
||||||
|
function isEditing(context) {
|
||||||
|
var domainObject = (context || {}).domainObject;
|
||||||
|
return domainObject
|
||||||
|
&& domainObject.hasCapability('status')
|
||||||
|
&& domainObject.getCapability('status').get('editing');
|
||||||
|
}
|
||||||
|
|
||||||
EditActionPolicy.prototype.allow = function (action, context) {
|
EditActionPolicy.prototype.allow = function (action, context) {
|
||||||
var key = action.getMetadata().key,
|
var key = action.getMetadata().key,
|
||||||
category = (context || {}).category;
|
category = (context || {}).category;
|
||||||
@ -59,11 +72,12 @@ define(
|
|||||||
if (category === 'view-control') {
|
if (category === 'view-control') {
|
||||||
// Restrict 'edit' to cases where there are editable
|
// Restrict 'edit' to cases where there are editable
|
||||||
// views (similarly, restrict 'properties' to when
|
// views (similarly, restrict 'properties' to when
|
||||||
// the converse is true)
|
// the converse is true), and where the domain object is not
|
||||||
|
// already being edited.
|
||||||
if (key === 'edit') {
|
if (key === 'edit') {
|
||||||
return countEditableViews(context) > 0;
|
return countEditableViews(context) > 0 && !isEditing(context);
|
||||||
} else if (key === 'properties') {
|
} else if (key === 'properties') {
|
||||||
return countEditableViews(context) < 1;
|
return countEditableViews(context) < 1 && !isEditing(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@ define(
|
|||||||
function EditRepresenter($q, $log, scope) {
|
function EditRepresenter($q, $log, scope) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
this.scope = scope;
|
||||||
|
|
||||||
// Mutate and persist a new version of a domain object's model.
|
// Mutate and persist a new version of a domain object's model.
|
||||||
function doPersist(model) {
|
function doPersist(model) {
|
||||||
var domainObject = self.domainObject;
|
var domainObject = self.domainObject;
|
||||||
@ -100,6 +102,8 @@ define(
|
|||||||
this.key = (representation || {}).key;
|
this.key = (representation || {}).key;
|
||||||
// Track the represented object
|
// Track the represented object
|
||||||
this.domainObject = representedObject;
|
this.domainObject = representedObject;
|
||||||
|
this.scope.editMode = representedObject.hasCapability("editor");
|
||||||
|
|
||||||
// Ensure existing watches are released
|
// Ensure existing watches are released
|
||||||
this.destroy();
|
this.destroy();
|
||||||
};
|
};
|
||||||
|
26
platform/commonUI/formats/bundle.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "Time services bundle",
|
||||||
|
"description": "Defines interfaces and provides default implementations for handling different time systems.",
|
||||||
|
"extensions": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"provides": "formatService",
|
||||||
|
"type": "provider",
|
||||||
|
"implementation": "FormatProvider.js",
|
||||||
|
"depends": [ "formats[]" ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"formats": [
|
||||||
|
{
|
||||||
|
"key": "utc",
|
||||||
|
"implementation": "UTCTimeFormat.js"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"constants": [
|
||||||
|
{
|
||||||
|
"key": "DEFAULT_TIME_FORMAT",
|
||||||
|
"value": "utc"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
114
platform/commonUI/formats/src/FormatProvider.js
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define([
|
||||||
|
|
||||||
|
], function (
|
||||||
|
|
||||||
|
) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object used to convert between numeric values and text values,
|
||||||
|
* typically used to display these values to the user and to convert
|
||||||
|
* user input to a numeric format, particularly for time formats.
|
||||||
|
* @interface {Format}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse text (typically user input) to a numeric value.
|
||||||
|
* Behavior is undefined when the text cannot be parsed;
|
||||||
|
* `validate` should be called first if the text may be invalid.
|
||||||
|
* @method parse
|
||||||
|
* @memberof Format#
|
||||||
|
* @param {string} text the text to parse
|
||||||
|
* @returns {number} the parsed numeric value
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether or not some text (typically user input) can
|
||||||
|
* be parsed to a numeric value by this format.
|
||||||
|
* @method validate
|
||||||
|
* @memberof Format#
|
||||||
|
* @param {string} text the text to parse
|
||||||
|
* @returns {boolean} true if the text can be parsed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a numeric value to a text value for display using
|
||||||
|
* this format.
|
||||||
|
* @method format
|
||||||
|
* @memberof Format#
|
||||||
|
* @param {number} value the numeric value to format
|
||||||
|
* @returns {string} the text representation of the value
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to `Format` objects which can be used to
|
||||||
|
* convert values between human-readable text and numeric
|
||||||
|
* representations.
|
||||||
|
* @interface FormatService
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up a format by its symbolic identifier.
|
||||||
|
* @method getFormat
|
||||||
|
* @memberof FormatService#
|
||||||
|
* @param {string} key the identifier for this format
|
||||||
|
* @returns {Format} the format
|
||||||
|
* @throws {Error} errors when the requested format is unrecognized
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides formats from the `formats` extension category.
|
||||||
|
* @constructor
|
||||||
|
* @implements {FormatService}
|
||||||
|
* @memberof platform/commonUI/formats
|
||||||
|
* @param {Array.<function(new : Format)>} format constructors,
|
||||||
|
* from the `formats` extension category.
|
||||||
|
*/
|
||||||
|
function FormatProvider(formats) {
|
||||||
|
var formatMap = {};
|
||||||
|
|
||||||
|
function addToMap(Format) {
|
||||||
|
var key = Format.key;
|
||||||
|
if (key && !formatMap[key]) {
|
||||||
|
formatMap[key] = new Format();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
formats.forEach(addToMap);
|
||||||
|
this.formatMap = formatMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormatProvider.prototype.getFormat = function (key) {
|
||||||
|
var format = this.formatMap[key];
|
||||||
|
if (!format) {
|
||||||
|
throw new Error("FormatProvider: No format found for " + key);
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
};
|
||||||
|
|
||||||
|
return FormatProvider;
|
||||||
|
|
||||||
|
});
|
63
platform/commonUI/formats/src/UTCTimeFormat.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'moment'
|
||||||
|
], function (
|
||||||
|
moment
|
||||||
|
) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss",
|
||||||
|
DATE_FORMATS = [
|
||||||
|
DATE_FORMAT,
|
||||||
|
"YYYY-MM-DD HH:mm",
|
||||||
|
"YYYY-MM-DD"
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatter for UTC timestamps. Interprets numeric values as
|
||||||
|
* milliseconds since the start of 1970.
|
||||||
|
*
|
||||||
|
* @implements {Format}
|
||||||
|
* @constructor
|
||||||
|
* @memberof platform/commonUI/formats
|
||||||
|
*/
|
||||||
|
function UTCTimeFormat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
UTCTimeFormat.prototype.format = function (value) {
|
||||||
|
return moment.utc(value).format(DATE_FORMAT);
|
||||||
|
};
|
||||||
|
|
||||||
|
UTCTimeFormat.prototype.parse = function (text) {
|
||||||
|
return moment.utc(text, DATE_FORMATS).valueOf();
|
||||||
|
};
|
||||||
|
|
||||||
|
UTCTimeFormat.prototype.validate = function (text) {
|
||||||
|
return moment.utc(text, DATE_FORMATS).isValid();
|
||||||
|
};
|
||||||
|
|
||||||
|
return UTCTimeFormat;
|
||||||
|
});
|
68
platform/commonUI/formats/test/FormatProviderSpec.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
['../src/FormatProvider'],
|
||||||
|
function (FormatProvider) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var KEYS = [ 'a', 'b', 'c' ];
|
||||||
|
|
||||||
|
describe("The FormatProvider", function () {
|
||||||
|
var mockFormats,
|
||||||
|
mockLog,
|
||||||
|
mockFormatInstances,
|
||||||
|
provider;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
mockFormatInstances = KEYS.map(function (k) {
|
||||||
|
return jasmine.createSpyObj(
|
||||||
|
'format-' + k,
|
||||||
|
[ 'parse', 'validate', 'format' ]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
// Return constructors
|
||||||
|
mockFormats = KEYS.map(function (k, i) {
|
||||||
|
function MockFormat() { return mockFormatInstances[i]; }
|
||||||
|
MockFormat.key = k;
|
||||||
|
return MockFormat;
|
||||||
|
});
|
||||||
|
provider = new FormatProvider(mockFormats);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("looks up formats by key", function () {
|
||||||
|
KEYS.forEach(function (k, i) {
|
||||||
|
expect(provider.getFormat(k))
|
||||||
|
.toEqual(mockFormatInstances[i]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("throws an error about unknown formats", function () {
|
||||||
|
expect(function () {
|
||||||
|
provider.getFormat('some-unknown-format');
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
56
platform/commonUI/formats/test/UTCTimeFormatSpec.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
['../src/UTCTimeFormat', 'moment'],
|
||||||
|
function (UTCTimeFormat, moment) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
describe("The UTCTimeFormat", function () {
|
||||||
|
var format;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
format = new UTCTimeFormat();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("formats UTC timestamps", function () {
|
||||||
|
var timestamp = 12345670000,
|
||||||
|
formatted = format.format(timestamp);
|
||||||
|
expect(formatted).toEqual(jasmine.any(String));
|
||||||
|
expect(moment.utc(formatted).valueOf()).toEqual(timestamp);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validates time inputs", function () {
|
||||||
|
expect(format.validate("1977-05-25 11:21:22")).toBe(true);
|
||||||
|
expect(format.validate("garbage text")).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("parses valid input", function () {
|
||||||
|
var text = "1977-05-25 11:21:22",
|
||||||
|
parsed = format.parse(text);
|
||||||
|
expect(parsed).toEqual(jasmine.any(Number));
|
||||||
|
expect(parsed).toEqual(moment.utc(text).valueOf());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|