neo.mjs 6.9.9 → 6.9.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/apps/learnneo/neo-config.json +5 -1
  3. package/apps/learnneo/store/Content.mjs +1 -1
  4. package/apps/learnneo/view/Viewport.mjs +12 -1
  5. package/apps/learnneo/view/home/ContentTreeList.mjs +53 -34
  6. package/apps/learnneo/view/home/ContentView.mjs +60 -0
  7. package/apps/learnneo/view/home/MainContainer.mjs +36 -9
  8. package/apps/learnneo/view/home/MainContainerController.mjs +57 -18
  9. package/apps/newwebsite/app.mjs +6 -0
  10. package/apps/newwebsite/index.html +10 -0
  11. package/apps/newwebsite/neo-config.json +7 -0
  12. package/apps/newwebsite/view/MainContainer.mjs +59 -0
  13. package/buildScripts/webpack/json/myApps.template.json +1 -0
  14. package/examples/ConfigurationViewport.mjs +12 -9
  15. package/examples/ServiceWorker.mjs +2 -2
  16. package/examples/button/base/neo-config.json +1 -2
  17. package/examples/form/field/textarea/MainContainer.mjs +1 -1
  18. package/package.json +2 -2
  19. package/resources/data/{learnneo → deck/learnneo}/p/2023-10-01T18-29-19-158Z.md +3 -6
  20. package/resources/data/deck/learnneo/p/stylesheet.md +40 -0
  21. package/resources/data/{learnneo → deck/learnneo}/t.json +19 -2
  22. package/resources/data/deck/training/p/2022-12-27T21-54-52-300Z.md +11 -0
  23. package/resources/data/deck/training/p/2022-12-27T21-55-23-144Z.md +43 -0
  24. package/resources/data/deck/training/p/2022-12-27T21-55-30-948Z.md +1 -0
  25. package/resources/data/deck/training/p/2022-12-27T21-55-43-542Z.md +84 -0
  26. package/resources/data/deck/training/p/2022-12-27T22-23-55-083Z.md +1 -0
  27. package/resources/data/deck/training/p/2022-12-27T22-24-07-886Z.md +8 -0
  28. package/resources/data/deck/training/p/2022-12-27T22-24-52-295Z.md +8 -0
  29. package/resources/data/deck/training/p/2022-12-27T22-25-03-853Z.md +5 -0
  30. package/resources/data/deck/training/p/2022-12-27T22-43-58-924Z.md +10 -0
  31. package/resources/data/deck/training/p/2022-12-27T22-44-28-881Z.md +3 -0
  32. package/resources/data/deck/training/p/2022-12-27T22-44-41-791Z.md +4 -0
  33. package/resources/data/deck/training/p/2022-12-27T22-45-21-032Z.md +7 -0
  34. package/resources/data/deck/training/p/2022-12-27T22-49-22-078Z.md +4 -0
  35. package/resources/data/deck/training/p/2022-12-27T22-50-20-626Z.md +4 -0
  36. package/resources/data/deck/training/p/2022-12-28T16-58-47-786Z.md +0 -0
  37. package/resources/data/deck/training/p/2022-12-28T16-58-55-192Z.md +9 -0
  38. package/resources/data/deck/training/p/2022-12-28T17-10-18-058Z.md +15 -0
  39. package/resources/data/deck/training/p/2022-12-28T17-10-42-296Z.md +40 -0
  40. package/resources/data/deck/training/p/2022-12-28T17-11-34-653Z.md +41 -0
  41. package/resources/data/deck/training/p/2022-12-28T17-13-09-994Z.md +0 -0
  42. package/resources/data/deck/training/p/2022-12-28T21-32-14-420Z.md +0 -0
  43. package/resources/data/deck/training/p/2022-12-29T01-43-32-431Z.md +7 -0
  44. package/resources/data/deck/training/p/2022-12-29T15-56-54-485Z.md +7 -0
  45. package/resources/data/deck/training/p/2022-12-29T15-57-11-499Z.md +7 -0
  46. package/resources/data/deck/training/p/2022-12-29T16-00-13-223Z.md +7 -0
  47. package/resources/data/deck/training/p/2022-12-29T18-34-25-826Z.md +4 -0
  48. package/resources/data/deck/training/p/2022-12-29T18-36-08-226Z.md +106 -0
  49. package/resources/data/deck/training/p/2022-12-29T18-36-56-893Z.md +112 -0
  50. package/resources/data/deck/training/p/2022-12-29T19-31-30-507Z.md +31 -0
  51. package/resources/data/deck/training/p/2022-12-29T19-31-55-091Z.md +14 -0
  52. package/resources/data/deck/training/p/2022-12-29T20-03-42-628Z.md +9 -0
  53. package/resources/data/deck/training/p/2022-12-29T20-21-20-669Z.md +7 -0
  54. package/resources/data/deck/training/p/2022-12-29T20-37-08-919Z.md +46 -0
  55. package/resources/data/deck/training/p/2022-12-29T20-37-20-344Z.md +43 -0
  56. package/resources/data/deck/training/p/2022-12-30T19-04-30-990Z.md +8 -0
  57. package/resources/data/deck/training/p/2022-12-31T18-43-56-338Z.md +7 -0
  58. package/resources/data/deck/training/p/2022-12-31T18-51-50-682Z.md +1 -0
  59. package/resources/data/deck/training/p/2022-12-31T18-54-04-176Z.md +4 -0
  60. package/resources/data/deck/training/p/2022-12-31T22-11-55-555Z.md +112 -0
  61. package/resources/data/deck/training/p/2022-12-31T23-00-41-222Z.md +6 -0
  62. package/resources/data/deck/training/p/2022-12-31T23-18-55-655Z.md +69 -0
  63. package/resources/data/deck/training/p/2022-12-31T23-25-40-735Z.md +21 -0
  64. package/resources/data/deck/training/p/2022-12-31T23-25-51-014Z.md +7 -0
  65. package/resources/data/deck/training/p/2023-01-01T17-49-18-429Z.md +3 -0
  66. package/resources/data/deck/training/p/2023-01-01T18-44-07-034Z.md +34 -0
  67. package/resources/data/deck/training/p/2023-01-01T18-47-39-766Z.md +15 -0
  68. package/resources/data/deck/training/p/2023-01-01T19-04-22-830Z.md +4 -0
  69. package/resources/data/deck/training/p/2023-01-01T21-11-58-025Z.md +25 -0
  70. package/resources/data/deck/training/p/2023-01-01T21-12-37-340Z.md +23 -0
  71. package/resources/data/deck/training/p/2023-01-01T21-13-13-880Z.md +8 -0
  72. package/resources/data/deck/training/p/2023-01-01T21-14-45-740Z.md +98 -0
  73. package/resources/data/deck/training/p/2023-01-01T21-18-23-886Z.md +26 -0
  74. package/resources/data/deck/training/p/2023-01-01T21-18-31-316Z.md +19 -0
  75. package/resources/data/deck/training/p/2023-01-01T21-18-42-290Z.md +23 -0
  76. package/resources/data/deck/training/p/2023-01-01T21-19-57-020Z.md +24 -0
  77. package/resources/data/deck/training/p/2023-01-01T21-22-31-184Z.md +13 -0
  78. package/resources/data/deck/training/p/2023-01-01T21-22-38-317Z.md +17 -0
  79. package/resources/data/deck/training/p/2023-01-01T21-22-47-693Z.md +20 -0
  80. package/resources/data/deck/training/p/2023-01-01T21-23-17-716Z.md +39 -0
  81. package/resources/data/deck/training/p/2023-01-01T21-23-28-532Z.md +22 -0
  82. package/resources/data/deck/training/p/2023-01-01T21-25-23-899Z.md +3 -0
  83. package/resources/data/deck/training/p/2023-01-01T21-25-59-742Z.md +1 -0
  84. package/resources/data/deck/training/p/2023-01-01T21-26-53-748Z.md +12 -0
  85. package/resources/data/deck/training/p/2023-01-01T23-38-42-863Z.md +2 -0
  86. package/resources/data/deck/training/p/2023-01-03T02-07-19-014Z.md +143 -0
  87. package/resources/data/deck/training/p/2023-01-04T01-52-23-454Z.md +76 -0
  88. package/resources/data/deck/training/p/2023-01-06T23-21-12-009Z.md +127 -0
  89. package/resources/data/deck/training/p/2023-01-06T23-21-31-685Z.md +81 -0
  90. package/resources/data/deck/training/p/2023-01-06T23-21-59-596Z.md +36 -0
  91. package/resources/data/deck/training/p/2023-01-06T23-34-13-897Z.md +87 -0
  92. package/resources/data/deck/training/p/2023-01-06T23-44-02-340Z.md +0 -0
  93. package/resources/data/deck/training/p/2023-01-06T23-46-36-687Z.md +1 -0
  94. package/resources/data/deck/training/p/2023-01-06T23-46-45-783Z.md +33 -0
  95. package/resources/data/deck/training/p/2023-01-08T00-45-11-144Z.md +50 -0
  96. package/resources/data/deck/training/p/2023-01-08T01-06-31-267Z.md +41 -0
  97. package/resources/data/deck/training/p/2023-01-08T01-24-21-088Z.md +95 -0
  98. package/resources/data/deck/training/p/2023-01-08T01-25-12-557Z.md +11 -0
  99. package/resources/data/deck/training/p/2023-01-08T01-46-50-723Z.md +25 -0
  100. package/resources/data/deck/training/p/2023-01-08T02-09-07-802Z.md +18 -0
  101. package/resources/data/deck/training/p/2023-01-08T02-09-19-678Z.md +66 -0
  102. package/resources/data/deck/training/p/2023-01-08T02-11-26-333Z.md +29 -0
  103. package/resources/data/deck/training/p/2023-01-08T17-22-48-841Z.md +14 -0
  104. package/resources/data/deck/training/p/2023-01-08T20-46-11-806Z.md +5 -0
  105. package/resources/data/deck/training/p/2023-01-08T20-47-23-682Z.md +5 -0
  106. package/resources/data/deck/training/p/2023-01-08T20-47-32-064Z.md +13 -0
  107. package/resources/data/deck/training/p/2023-01-08T20-47-57-045Z.md +0 -0
  108. package/resources/data/deck/training/p/2023-01-08T20-48-03-791Z.md +18 -0
  109. package/resources/data/deck/training/p/2023-01-08T20-48-32-466Z.md +9 -0
  110. package/resources/data/deck/training/p/2023-01-08T20-48-51-322Z.md +20 -0
  111. package/resources/data/deck/training/p/2023-01-08T20-49-52-741Z.md +0 -0
  112. package/resources/data/deck/training/p/2023-01-08T20-52-03-556Z.md +0 -0
  113. package/resources/data/deck/training/p/2023-01-08T20-57-36-333Z.md +2 -0
  114. package/resources/data/deck/training/p/2023-01-08T20-57-51-136Z.md +5 -0
  115. package/resources/data/deck/training/p/2023-01-09T00-07-37-951Z.md +0 -0
  116. package/resources/data/deck/training/p/2023-01-09T00-35-40-671Z.md +3 -0
  117. package/resources/data/deck/training/p/2023-01-10T01-29-38-148Z.md +10 -0
  118. package/resources/data/deck/training/p/2023-01-10T01-43-12-166Z.md +31 -0
  119. package/resources/data/deck/training/p/2023-01-10T02-21-54-303Z.md +10 -0
  120. package/resources/data/deck/training/p/2023-01-12T01-50-54-617Z.md +74 -0
  121. package/resources/data/deck/training/p/2023-01-13T19-55-24-735Z.md +14 -0
  122. package/resources/data/deck/training/p/2023-01-13T20-08-27-068Z.md +28 -0
  123. package/resources/data/deck/training/p/2023-01-13T20-23-38-411Z.md +25 -0
  124. package/resources/data/deck/training/p/2023-01-13T20-37-06-267Z.md +13 -0
  125. package/resources/data/deck/training/p/2023-01-13T21-05-57-708Z.md +8 -0
  126. package/resources/data/deck/training/p/2023-01-13T21-48-17-258Z.md +20 -0
  127. package/resources/data/deck/training/p/2023-01-13T22-05-05-799Z.md +14 -0
  128. package/resources/data/deck/training/p/2023-01-13T22-08-30-863Z.md +17 -0
  129. package/resources/data/deck/training/p/2023-01-13T23-01-50-449Z.md +4 -0
  130. package/resources/data/deck/training/p/2023-01-14T00-33-05-958Z.md +62 -0
  131. package/resources/data/deck/training/p/2023-01-14T00-40-27-784Z.md +229 -0
  132. package/resources/data/deck/training/p/2023-01-14T00-41-59-081Z.md +153 -0
  133. package/resources/data/deck/training/p/2023-01-14T13-50-28-199Z.md +19 -0
  134. package/resources/data/deck/training/p/2023-01-14T13-59-20-275Z.md +6 -0
  135. package/resources/data/deck/training/p/2023-01-14T14-03-29-456Z.md +3 -0
  136. package/resources/data/deck/training/p/2023-01-14T14-27-57-678Z.md +7 -0
  137. package/resources/data/deck/training/p/2023-01-14T17-30-18-228Z.md +33 -0
  138. package/resources/data/deck/training/p/2023-01-14T18-28-39-316Z.md +1 -0
  139. package/resources/data/deck/training/p/2023-01-14T18-28-44-115Z.md +4 -0
  140. package/resources/data/deck/training/p/2023-01-14T18-28-49-548Z.md +18 -0
  141. package/resources/data/deck/training/p/2023-01-14T18-40-13-758Z.md +10 -0
  142. package/resources/data/deck/training/p/2023-01-14T19-29-15-291Z.md +12 -0
  143. package/resources/data/deck/training/p/2023-01-15T18-51-52-134Z.md +83 -0
  144. package/resources/data/deck/training/p/2023-01-15T20-03-30-073Z.md +11 -0
  145. package/resources/data/deck/training/p/2023-01-15T22-07-52-073Z.md +16 -0
  146. package/resources/data/deck/training/p/2023-01-15T22-22-13-517Z.md +12 -0
  147. package/resources/data/deck/training/p/2023-01-15T22-28-57-508Z.md +131 -0
  148. package/resources/data/deck/training/p/2023-01-15T22-36-30-913Z.md +115 -0
  149. package/resources/data/deck/training/p/2023-01-16T16-03-40-770Z.md +12 -0
  150. package/resources/data/deck/training/p/2023-01-16T20-21-56-859Z.md +5 -0
  151. package/resources/data/deck/training/p/2023-01-16T20-24-09-690Z.md +24 -0
  152. package/resources/data/deck/training/p/2023-01-20T12-51-22-646Z.md +21 -0
  153. package/resources/data/deck/training/p/2023-01-20T13-06-46-614Z.md +9 -0
  154. package/resources/data/deck/training/p/2023-01-20T13-08-51-600Z.md +7 -0
  155. package/resources/data/deck/training/p/2023-01-20T15-20-13-363Z.md +26 -0
  156. package/resources/data/deck/training/p/2023-01-20T15-34-58-813Z.md +75 -0
  157. package/resources/data/deck/training/p/2023-01-21T16-33-20-458Z.md +33 -0
  158. package/resources/data/deck/training/p/2023-01-21T16-45-28-263Z.md +28 -0
  159. package/resources/data/deck/training/p/2023-01-21T16-56-25-452Z.md +3 -0
  160. package/resources/data/deck/training/p/2023-01-21T17-28-31-493Z.md +6 -0
  161. package/resources/data/deck/training/p/2023-01-21T19-49-51-918Z.md +13 -0
  162. package/resources/data/deck/training/p/2023-01-21T20-08-24-452Z.md +15 -0
  163. package/resources/data/deck/training/p/2023-01-21T20-35-54-947Z.md +20 -0
  164. package/resources/data/deck/training/p/2023-01-21T20-54-47-603Z.md +39 -0
  165. package/resources/data/deck/training/p/2023-01-21T20-56-28-184Z.md +25 -0
  166. package/resources/data/deck/training/p/2023-01-21T20-57-32-927Z.md +4 -0
  167. package/resources/data/deck/training/p/2023-01-21T23-13-33-394Z.md +6 -0
  168. package/resources/data/deck/training/p/2023-01-28T19-11-37-464Z.md +24 -0
  169. package/resources/data/deck/training/p/2023-01-28T20-43-41-188Z.md +9 -0
  170. package/resources/data/deck/training/p/2023-01-28T20-53-56-476Z.md +8 -0
  171. package/resources/data/deck/training/p/2023-01-28T20-58-43-776Z.md +10 -0
  172. package/resources/data/deck/training/p/2023-01-28T22-18-41-259Z.md +33 -0
  173. package/resources/data/deck/training/p/2023-01-28T22-24-34-808Z.md +24 -0
  174. package/resources/data/deck/training/p/2023-01-29T16-25-24-528Z.md +44 -0
  175. package/resources/data/deck/training/p/2023-01-29T21-14-32-588Z.md +12 -0
  176. package/resources/data/deck/training/p/2023-01-31T19-24-53-504Z.md +8 -0
  177. package/resources/data/deck/training/p/2023-01-31T20-33-55-855Z.md +11 -0
  178. package/resources/data/deck/training/p/2023-01-31T20-34-30-261Z.md +7 -0
  179. package/resources/data/deck/training/p/2023-01-31T20-52-53-367Z.md +43 -0
  180. package/resources/data/deck/training/p/2023-02-04T15-18-35-682Z.md +20 -0
  181. package/resources/data/deck/training/p/2023-02-04T15-49-47-597Z.md +14 -0
  182. package/resources/data/deck/training/p/2023-02-04T18-58-57-808Z.md +1 -0
  183. package/resources/data/deck/training/p/2023-02-04T20-07-11-288Z.md +1 -0
  184. package/resources/data/deck/training/p/2023-02-04T20-09-50-169Z.md +1 -0
  185. package/resources/data/deck/training/p/2023-02-04T20-19-42-740Z.md +8 -0
  186. package/resources/data/deck/training/p/2023-02-04T20-23-56-013Z.md +12 -0
  187. package/resources/data/deck/training/p/2023-02-04T20-28-12-391Z.md +20 -0
  188. package/resources/data/deck/training/p/2023-02-05T00-20-32-554Z.md +16 -0
  189. package/resources/data/deck/training/p/2023-02-05T00-35-56-282Z.md +13 -0
  190. package/resources/data/deck/training/p/2023-02-05T15-36-57-182Z.md +24 -0
  191. package/resources/data/deck/training/p/2023-02-05T17-39-51-712Z.md +70 -0
  192. package/resources/data/deck/training/p/2023-02-05T17-44-53-815Z.md +195 -0
  193. package/resources/data/deck/training/p/2023-02-05T17-45-40-114Z.md +92 -0
  194. package/resources/data/deck/training/p/2023-02-05T18-12-14-489Z.md +60 -0
  195. package/resources/data/deck/training/p/2023-02-06T00-14-54-457Z.md +9 -0
  196. package/resources/data/deck/training/p/2023-06-28T18-03-14-313Z.md +8 -0
  197. package/resources/data/deck/training/p/2023-06-28T18-26-17-290Z.md +7 -0
  198. package/resources/data/deck/training/p/2023-06-28T21-16-24-034Z.md +40 -0
  199. package/resources/data/deck/training/p/2023-06-28T21-16-34-972Z.md +16 -0
  200. package/resources/data/deck/training/p/2023-06-28T21-28-28-379Z.md +4 -0
  201. package/resources/data/deck/training/p/2023-06-29T23-15-10-411Z.md +5 -0
  202. package/resources/data/deck/training/p/2023-07-01T15-42-45-193Z.md +433 -0
  203. package/resources/data/deck/training/p/2023-07-01T21-54-31-329Z.md +6 -0
  204. package/resources/data/deck/training/p/2023-07-02T16-14-06-970Z.md +14 -0
  205. package/resources/data/deck/training/p/2023-07-31T00-26-03-842Z.md +4 -0
  206. package/resources/data/deck/training/p/2023-07-31T00-31-51-933Z.md +10 -0
  207. package/resources/data/deck/training/p/2023-07-31T00-37-21-927Z.md +205 -0
  208. package/resources/data/deck/training/p/2023-10-01T18-29-19-158Z.md +76 -0
  209. package/resources/data/deck/training/p/2023-10-07T19-18-28-517Z.md +102 -0
  210. package/resources/data/deck/training/p/2023-10-08T20-20-07-934Z.md +75 -0
  211. package/resources/data/deck/training/p/2023-10-08T20-20-37-336Z.md +29 -0
  212. package/resources/data/deck/training/p/2023-10-08T20-37-30-658Z.md +0 -0
  213. package/resources/data/deck/training/p/2023-10-08T21-58-25-809Z.md +68 -0
  214. package/resources/data/deck/training/p/2023-10-08T22-22-11-013Z.md +0 -0
  215. package/resources/data/deck/training/p/2023-10-14T19-25-08-153Z.md +119 -0
  216. package/resources/data/deck/training/t.json +1 -0
  217. package/resources/scss/src/apps/learnneo/Viewport.scss +0 -106
  218. package/resources/scss/src/apps/learnneo/home/ContentTreeList.scss +37 -0
  219. package/resources/scss/src/apps/learnneo/home/ContentView.scss +55 -0
  220. package/resources/scss/src/form/field/FileUpload.scss +4 -4
  221. package/resources/scss/src/form/field/TextArea.scss +1 -1
  222. package/resources/scss/theme-neo-light/Global.scss +46 -0
  223. package/resources/scss/theme-neo-light/design-tokens/Core.scss +7 -0
  224. package/resources/scss/theme-neo-light/design-tokens/Semantic.scss +0 -0
  225. package/resources/scss/theme-neo-light/design-tokens/_all.scss +4 -0
  226. package/src/DefaultConfig.mjs +4 -4
  227. package/src/form/field/FileUpload.mjs +9 -2
  228. package/src/form/field/TextArea.mjs +19 -34
  229. package/src/main/DomAccess.mjs +34 -0
  230. package/test/components/files/form/field/Select.mjs +1 -1
  231. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-07T19-18-28-517Z.md +0 -0
  232. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T20-20-07-934Z.md +0 -0
  233. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T20-20-37-336Z.md +0 -0
  234. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T20-37-30-658Z.md +0 -0
  235. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T21-58-25-809Z.md +0 -0
  236. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-08T22-22-11-013Z.md +0 -0
  237. /package/resources/data/{learnneo → deck/learnneo}/p/2023-10-14T19-25-08-153Z.md +0 -0
  238. /package/resources/data/{learnneo → deck/learnneo}/pages/whyneo.md +0 -0
  239. /package/resources/data/{learnneo → deck/learnneo}/tree.json +0 -0
  240. /package/resources/{deck → data/deck}/whyneo.md +0 -0
  241. /package/resources/scss/src/apps/newwebsite/{MainContainer.css → MainContainer.scss} +0 -0
  242. /package/resources/scss/theme-neo-light/design-tokens/{Components.scss → Component.scss} +0 -0
@@ -0,0 +1,10 @@
1
+ <a href="" target="_blank">Here are some examples.</a>
2
+
3
+
4
+ (They don't demo as well while screen charing because the
5
+ meeting app will have its own frame rate.)
6
+
7
+ Run the the prod version of one of the demos, like
8
+ the <a href="https://neomjs.github.io/pages/node_modules/neo.mjs/dist/production/examples/component/coronaHelix/index.html" target="">COVID-19 Helix</a> example. Note the delta-updates per second information
9
+ at the upper right. You're seeing 10,000 or 20,000 delta updates per
10
+ second as you zoom in and out and pan.
@@ -0,0 +1,74 @@
1
+ #Introduction
2
+
3
+ In this lab you'll add the Google map.
4
+
5
+ #Steps
6
+
7
+ ??Add the import
8
+
9
+ import GoogleMapsComponent from '../../../node_modules/neo.mjs/src/component/wrapper/GoogleMaps.mjs';
10
+
11
+ Save and refresh to make sure the import is working.
12
+
13
+ ??Add the map to the main view
14
+
15
+ Add a second item to the main container's `items[]`
16
+
17
+ {
18
+ module: GoogleMapsComponent,
19
+ flex: 1,
20
+ center: {
21
+ lat: 64.8014187,
22
+ lng: -18.3096357
23
+ },
24
+ zoom: 6,
25
+ }
26
+
27
+ ??Bind the store
28
+
29
+ The map component has a `markerStore` config. Add the code to bind that to
30
+ the store. This will be very similar to what you did for the table.
31
+
32
+ ??Solution &mdash; don't peek
33
+
34
+ Here's the code, in case you need it.
35
+
36
+ <pre style="border: thin solid gray; padding: 8px; ">
37
+ import Viewport from '../../../node_modules/neo.mjs/src/container/Viewport.mjs';
38
+ import EarthquakesTable from './earthquakes/Table.mjs';
39
+ import ViewModel from './MainContainerViewModel.mjs';
40
+ import GoogleMapsComponent from '../../../../node_modules/neo.mjs/src/component/wrapper/GoogleMaps.mjs';
41
+
42
+ class MainContainer extends Viewport {
43
+ static getConfig() {
44
+ return {
45
+ className: 'Earthquakes.view.MainContainer',
46
+ layout: { ntype: 'vbox', align: 'stretch' },
47
+ autoMount: true,
48
+ model: {
49
+ module: ViewModel,
50
+ },
51
+ items: [{
52
+ module: EarthquakesTable,
53
+ flex: 1,
54
+ bind: {
55
+ store: 'stores.earthquakes'
56
+ }
57
+ }, {
58
+ module: GoogleMapsComponent,
59
+ flex: 1,
60
+ center: {
61
+ lat: 64.8014187,
62
+ lng: -18.3096357
63
+ },
64
+ zoom: 6,
65
+ }],
66
+ }
67
+ }
68
+ }
69
+
70
+ Neo.applyClassConfig(MainContainer);
71
+
72
+ export default MainContainer;
73
+ </pre>
74
+
@@ -0,0 +1,14 @@
1
+
2
+ <pre class="runnable readonly text 300">
3
+ /**
4
+ * The person's name. Null names are ignored.
5
+ * @member {String} name_=''
6
+ */
7
+ name_: '',
8
+
9
+ ...
10
+
11
+ beforeSetName(name, oldName){
12
+ return (name == null)?oldName:name; // null or undefined are ignored.
13
+ }
14
+ </pre>
@@ -0,0 +1,28 @@
1
+ <pre class="runnable readonly text 240">
2
+ /**
3
+ * The number of ducks
4
+ * @member {Integer} duckCount_=0
5
+ */
6
+ duckCount_: 0,
7
+
8
+ ...
9
+
10
+ beforeSetDuckCount(count){
11
+ return Math.round(count);
12
+ }
13
+ </pre>
14
+
15
+ <pre class="runnable readonly text 260">
16
+ /**
17
+ * Store holding
18
+ * @member {Store|Object}
19
+ */
20
+ store_: null,
21
+
22
+ ...
23
+
24
+ beforeSetStore(store){
25
+ // Utility method that returns store if it's a Store instance, or a Store if store is a config
26
+ return ClassSystem.beforeSetInstance(store, Store); store]
27
+ }
28
+ </pre>
@@ -0,0 +1,25 @@
1
+ A side effect is a state change outside of setting the value.
2
+
3
+ Another common use the afterSet method is to fire some kind of change event.
4
+
5
+ <pre class="runnable readonly text 340">
6
+ /**
7
+ * Account balance
8
+ * @member {Number} balance_=0
9
+ */
10
+ balance_: 0,
11
+
12
+ ...
13
+
14
+ afterSetBalance(balance){
15
+
16
+ if (balance < 0) this.status = this.OVERDRAWN; // Side-effect
17
+
18
+ this.fire('balanceChange', {
19
+ component: this,
20
+ balance
21
+ });
22
+
23
+ }
24
+ </pre>
25
+
@@ -0,0 +1,13 @@
1
+ <pre class="runnable readonly text 240">
2
+ /**
3
+ * Account balance
4
+ * @member {Number} balance_=0
5
+ */
6
+ balance_: 0,
7
+
8
+ ...
9
+
10
+ beforeGetBalance(balance){
11
+ return this.governmentAudit?(balance * .8):balance; // Claim lower balances when audits are underway
12
+ }
13
+ </pre>
@@ -0,0 +1,8 @@
1
+ You rarely need `Neo.component.Base` instances &mdash; they're just too primitive.
2
+
3
+ A `Neo.component.Base` might be used as a placeholder, to be replaced
4
+ later on with some other component type.
5
+
6
+ However, if you need to code a custom component &mdash; where you specify
7
+ your own DOM structure &mdash; then you'll extend `Ext.component.Base`.
8
+ We'll see an example of that later.
@@ -0,0 +1,20 @@
1
+ Compont content is defined via a `_vdom` config, and by procedurally changing the `vdom` property.
2
+
3
+ We'll go further in-depth with low-level components and vdom later in the course.
4
+
5
+ <pre style="font-size: 14pt; padding: 8pt; border: solid thin lightgray">
6
+ name_: '',
7
+
8
+ _vdom: {
9
+ tag: 'div',
10
+ style: 'fontWeight:bold',
11
+ innerHTML: ''
12
+ }
13
+
14
+ ...
15
+
16
+ afterSetName(name, oldName) {
17
+ this.vdom.innerHTML = name;
18
+ this.update();
19
+ }
20
+ </pre>
@@ -0,0 +1,14 @@
1
+ <pre class="runnable readonly text 240">
2
+ /**
3
+ * An array of ducks
4
+ * @member {[Duck]} ducks=[]
5
+ */
6
+ ducks_: [],
7
+
8
+ ...
9
+
10
+ beforeSetDucks(ducks){
11
+ return Neo.clone(ducks); // Use a defensive copy so we don't mess up the original array
12
+ }
13
+ </pre>
14
+
@@ -0,0 +1,17 @@
1
+ <pre class="runnable readonly text 300">
2
+ /**
3
+ * An array of ducks
4
+ * @member {[Duck]} ducks=[]
5
+ */
6
+ ducks_: [],
7
+
8
+ ...
9
+
10
+ beforeSetDucks(ducks){
11
+ return Neo.clone(ducks); // Use a defensive copy so we don't mess up the original array
12
+ }
13
+ beforeGetDucks(ducks){
14
+ return Neo.clone(ducks); // Use a defensive copy so the other code doesn't mess up our copy
15
+ }
16
+ </pre>
17
+
@@ -0,0 +1,4 @@
1
+ The way Neo handles configs, and especially the creation of get/set methods, is _very important_.
2
+ It's not hard to learn, but it play a huge role in how Neo works.
3
+
4
+ Some of these examples are in `apps/componentBasics/`.
@@ -0,0 +1,62 @@
1
+ #Introduction
2
+
3
+ In this lab you'll bind the map's center to the city.
4
+
5
+ #Steps
6
+
7
+
8
+ ??Configure an in-line view model in the main view
9
+
10
+ You'll need to import
11
+ `src/model/Component.mjs', named something like `ViewModel`, then
12
+ configure the model:
13
+
14
+ model: {
15
+ module: ViewModel,
16
+ data: {},
17
+ stores: {}
18
+ }
19
+
20
+
21
+ ??Create a `center` property in the view model
22
+
23
+ <pre style="color:lightgray">
24
+ model: {
25
+ module: ViewModel,
26
+ data: {
27
+ <span style="color:firebrick">center: {
28
+ lat: lat: -27.1259626,
29
+ lng: -109.4088545
30
+ }</span>
31
+ },
32
+ },
33
+ </pre>
34
+
35
+ ??Watch the values change
36
+
37
+ Just for the fun of it, and to gain insights into how view model changes occur, add
38
+ a listener to the view model config.
39
+
40
+ <pre style="color:lightgray">
41
+ model: {
42
+ module: ViewModel,
43
+ <span style="color:firebrick">listeners: {
44
+ dataPropertyChange: data => console.log(data.key, data.value)
45
+ },</span>
46
+ data: {
47
+ center: {
48
+ lat: lat: -27.1259626,
49
+ lng: -109.4088545
50
+ }
51
+ },
52
+ },
53
+ </pre>
54
+
55
+ ??Bind the map center to that property
56
+
57
+ Edit `Yelp.view.businessses.Tabs` and modify the map
58
+ config to bind the center to the view model property.
59
+
60
+ bind: { center: data => data.center }
61
+
62
+ Save and refresh, and you should see the map centered at the specified location.
@@ -0,0 +1,229 @@
1
+ #Introduction
2
+
3
+ In this lab you'll fetch Yelp data based on the latitude and longitude corresponding
4
+ to the city.
5
+
6
+ #Steps
7
+
8
+ ??Define the store
9
+
10
+ Edit the main view model.
11
+
12
+ Import `data/Store.mjs`.
13
+
14
+ import Store from '../../../node_modules/neo.mjs/src/data/Store.mjs';
15
+
16
+ Add a config _businesses_ in the `stores` config block
17
+
18
+ stores: {
19
+ businesses: {
20
+ module: Store,
21
+ url:"https://nameless-tundra-27404.herokuapp.com/go/?fn=yelp&latitude=43.084&longitude=-89.546&term=pizza&limit=1",
22
+ responseRoot: 'businesses',
23
+ autoLoad: true
24
+ }
25
+ }
26
+
27
+ Save and refresh then look in the debugger's Network tab. You should see the data being fetched.
28
+
29
+ <img style="border: thin solid gray" src="resources/images/yelp/initialNetworkTraffic.png"></img>
30
+
31
+ ??Load the store procedurally
32
+
33
+ Remove the `autoLoad:true,`.
34
+
35
+ Edit the main view controller and add a statement to load the store.
36
+
37
+ <pre style='color:lightgray; padding: 8px;'>
38
+ doFetchYelpData() {
39
+ const model = this.getModel();
40
+ <span style="color:firebrick">model.stores.businesses.load();</span>
41
+ }
42
+ </pre>
43
+
44
+ If you were to save and refresh, and look in network traffic, you'd see
45
+ the url being run twice: once when the _center_ changed and once when
46
+ the _category_ changed. (In theory we could buffer the method that calls
47
+ the Yelp service, but for the lab we're not going to bother.)
48
+
49
+ ??Update search parameters dynamically
50
+
51
+ Edit the main view model and replace the `url` with this value.
52
+
53
+ url:"https://nameless-tundra-27404.herokuapp.com/go/",
54
+
55
+ That URL omits the query fields &mdash; we'll be adding those dynamically.
56
+
57
+ Edit the main view controller and update the `load()` params to include
58
+ the _method_, _latitude_, and _longitude_, and _category.
59
+
60
+ <pre style='color:lightgray; padding: 8px;'>
61
+ doFetchYelpData() {
62
+ const model = this.getModel();
63
+ <span style="color:firebrick">const params = {
64
+ fn: 'yelp',
65
+ latitude: model.data.center.lat,
66
+ longitude: model.data.center.lng,
67
+ term: model.data.category
68
+ };
69
+ model.stores.businesses.load({ method: 'GET', params });</span>
70
+ }
71
+ </pre>
72
+
73
+ Test this by saving, refreshing, then changing the city a few times.
74
+ With each city changes you should see a new call to the Yelp web service.
75
+
76
+ <img style="border:thin solid gray" src="resources/images/yelp/CityChangesReflectedInTheFeed.png"></img>
77
+
78
+ ??Add two fields to the store's model config
79
+
80
+ As you probably recall, the Google Maps component expects a store whose records specify
81
+ a _title_, and a _position_. The Yelp feed has values that looks like this:
82
+
83
+ ...
84
+ "name": "Joe's Diner",
85
+ "coordinates": {
86
+ "latitude": 43.0753733442932,
87
+ "longitude": -89.5296266588608
88
+ },
89
+ ...
90
+
91
+ Therefore, we need to add a two fields in the store's `fields:[]`.
92
+
93
+ model: {
94
+ fields: [{
95
+ name: 'title',
96
+ mapping: 'name'
97
+ }, {
98
+ name: 'position',
99
+ calculate: (data, field, item) => ({ lat: item.coordinates.latitude, lng: item.coordinates.longitude })
100
+ }]
101
+ },
102
+
103
+ Save, refresh, then use the debugger console to verity that the records reflect those values.
104
+
105
+ This should show the title of the first record.
106
+
107
+ Neo.findFirst({ntype:'yelp-main'}).model.stores.businesses.items[0].title;
108
+
109
+ This should show the position (lat, lng) of the first record.
110
+
111
+ Neo.findFirst({ntype:'yelp-main'}).model.stores.businesses.items[0].position
112
+
113
+
114
+ ??Don't peek...
115
+
116
+ You can peek. If you get stuck, or just to compare to another implementation, here's the
117
+ full store and controller logic in invisible writing. Highlight the code to read it.
118
+
119
+ Your code may differ slightly to reflect your preferences for default city, etc.,
120
+ but this code will show how the store is configured and how the controller dynamically
121
+ fetches the data.
122
+
123
+ Here's the view model.
124
+
125
+ <pre style="border:thin solid #dddddd; padding: 4px; color: white">
126
+
127
+ import Base from '../../../node_modules/neo.mjs/src/model/Component.mjs';
128
+ import Store from '../../../node_modules/neo.mjs/src/data/Store.mjs';
129
+
130
+ class MainViewModel extends Base {
131
+ static config = {
132
+ className: 'Y.view.MainViewModel',
133
+
134
+ data: {
135
+ city: 'Oconomowoc, Wisconsin',
136
+ category: 'pizza',
137
+ center: {
138
+ lat: -27.1259626,
139
+ lng: -109.4088545
140
+ },
141
+ },
142
+ stores: {
143
+ businesses: {
144
+ module: Store,
145
+ url: "https://nameless-tundra-27404.herokuapp.com/go/",
146
+ responseRoot: 'businesses',
147
+ model: {
148
+ fields: [{
149
+ name: 'title',
150
+ mapping: 'name'
151
+ }, {
152
+ name: 'position',
153
+ calculate: (data, field, item) => ({lat: item.coordinates.latitude, lng: item.coordinates.longitude})
154
+ }]
155
+ }
156
+ }
157
+ }
158
+
159
+ }
160
+ }
161
+
162
+ Neo.applyClassConfig(MainViewModel);
163
+
164
+ export default MainViewModel;
165
+ </pre>
166
+
167
+ Here's the main view controller.
168
+
169
+ <pre style="border:thin solid #dddddd; padding: 4px; color: white">
170
+ import Base from '../../../node_modules/neo.mjs/src/controller/Component.mjs';
171
+
172
+ class MainViewController extends Base {
173
+ static config = {
174
+ className: 'Y.view.MainViewController',
175
+ }
176
+
177
+ onComponentConstructed() {
178
+ const model = this.getModel();
179
+ this.onCityChange(model.data.city);
180
+ model.on('dataPropertyChange', data => {
181
+ if (data.key === 'city') this.onCityChange(data.value);
182
+ if (data.key === 'center') this.doFetchYData();
183
+ if (data.key === 'category') this.doFetchYData();
184
+ });
185
+ }
186
+ onCityChange(city) {
187
+ if (!city) return;
188
+ Neo.main.addon.GoogleMaps.geocode({address: city})
189
+ .then(data => this.getModel().data.center = data.results[0].geometry.location);
190
+ }
191
+
192
+ doFetchYData() {
193
+ const model = this.getModel();
194
+ console.log('Fetch Yelp data', model.data.center, model.data.category);
195
+ const params = {
196
+ fn: 'yelp',
197
+ latitude: model.data.center.lat,
198
+ longitude: model.data.center.lng,
199
+ term: model.data.category,
200
+ limit: 20,
201
+ };
202
+ model.stores.businesses.load({method: 'GET', params});
203
+ }
204
+
205
+
206
+ }
207
+
208
+ Neo.applyClassConfig(MainViewController);
209
+
210
+ export default MainViewController;
211
+ </pre>
212
+
213
+ ??Bind the store to the map
214
+
215
+ You have the map center, and a store that holds the information the map expects.
216
+
217
+ Edit `view/businesses/Tabs.mjs` and add an additional binding to the map:
218
+
219
+ <pre style='color:lightgray'>
220
+ bind: {
221
+ center: data => data.center,
222
+ <span style="color:firebrick">markerStore: 'stores.businesses'</span>
223
+ },
224
+ </pre>
225
+
226
+ Save, refresh, then change the category a few times &mdash; the markers should
227
+ update at the specification city. Change city and see the markers for that
228
+ location and category.
229
+
@@ -0,0 +1,153 @@
1
+ #Introduction
2
+
3
+ In this lab you'll show Yelp information in a `Neo.table.Container`.
4
+
5
+ #Steps
6
+
7
+ ??Import Table
8
+
9
+ Edit `yelp/view/businesses/Tabs.mjs` and import _src/table/Container.mjs_ &mdash;
10
+ make sure you use the correct relative path.
11
+
12
+ ??Make the second tab the table
13
+
14
+ Configure the second tab to use imported `Neo.table.Container`. Configure the
15
+ button text to be _Table_, and use `iconCls:'fas fa-table-list'` (or any other icon
16
+ you think looks good).
17
+
18
+ If you save and refresh you should see the warning _Attempting to create a table.Container without defined columns..._. We'll fix that in the next step.
19
+
20
+ ??Start to configure the columns
21
+
22
+ We want to show the business name, street address, telephone, star rating, and review count.
23
+
24
+ Configure a `columns:[]` with five columns whose `text` is: _Name_, _Address_, _Telephone_, _Rating_, and _Reviews_.
25
+
26
+ ??Plan how to show the data
27
+
28
+ Here's what a business looks like in the data feed:
29
+
30
+ {
31
+ "name": "Pizza Brutta",
32
+ "review_count": 422,
33
+ "rating": 4.5,
34
+ "coordinates": {
35
+ "latitude": 43.06512,
36
+ "longitude": -89.41629
37
+ },
38
+ "location": {
39
+ "display_address": [
40
+ "1805 Monroe St",
41
+ "Madison, WI 53711"
42
+ ]
43
+ },
44
+ "display_phone": "(608) 257-2120"
45
+ }
46
+
47
+ There are already two fields in each record. The fields match what the Google Maps component expects
48
+ for its store:
49
+
50
+ - _title_, which is mapped to _name_
51
+ - _position_, which uses a `calculate` to create a object with _lat_ and _lng_
52
+
53
+ We need four more values: _address_, _telephone_, _rating_, and _reviews_.
54
+
55
+ Some of those map directly to their value in the feed, some need a `mapping` config.
56
+
57
+ Showing `address` is a little trickier. We have two choices: we can configure a `calculate`
58
+ in the store model's `fields[]`, or code a table column renderer to get the value.
59
+
60
+ We'll try both techniques.
61
+
62
+ ??Add field definitions
63
+
64
+ Edit the main view model `businesses` store config and add four fields:
65
+
66
+ - _reviews_, which is mapped to _review_count_
67
+ - _rating_
68
+ - _phone_, which is mapped to _display_phone_
69
+ - _address_, which is mapped to _location.display_address_
70
+
71
+ We aren't using these in the table yet, but you can still verify that the store
72
+ is getting the right data by getting a reference to the map and looking at its
73
+ store items.
74
+
75
+ Neo.findFirst({ntype:'googlemaps'}).markerStore.items
76
+
77
+ Each item should six properties that look like this:
78
+
79
+ {
80
+ "title": "Pizza Brutta",
81
+ "position": {
82
+ "lat": 43.06512,
83
+ "lng": -89.41629
84
+ },
85
+ "reviews": 422,
86
+ "rating": 4.5,
87
+ "telephone": "(608) 257-2120",
88
+ "address": [
89
+ "1805 Monroe St",
90
+ "Madison, WI 53711"
91
+ ],
92
+ "id": -1
93
+ }
94
+
95
+ ??Continue to configure the table
96
+
97
+ Edit `yelp/view/businesses/Tabs.mjs` and add a `dataField` config for each column using
98
+ the corresponding value specified in store's `fields:[]`.
99
+
100
+ Also specify `align:'right'` for ratings and review count.
101
+
102
+ Of course, we won't see anything until you bind the table to the store. Configure the
103
+ binding. This is the same as the map binding, except table has a _store_ rather than
104
+ a _markerStore_.
105
+
106
+ Save and refresh, and you should see data in the store. If you change the city or category
107
+ the table should update accordingly.
108
+
109
+ ??Use renderers
110
+
111
+ We need some renderers.
112
+
113
+ Configure a renderer for the address.
114
+
115
+ renderer: data => data.value.join(', ')
116
+
117
+ Configure a renderer for the review count.
118
+
119
+ renderer: data => new Intl.NumberFormat().format(data.value)
120
+
121
+ Configure a renderer for the rating.
122
+
123
+ renderer: data => new Intl.NumberFormat('en-US', {minimumFractionDigits: 1})
124
+ .format(data.value)
125
+
126
+ Save, refresh and try it out. You should see the renderers being used.
127
+
128
+ ??Use a calculated value in the store
129
+
130
+ Go back to the main view model and modify the _address_ field config to use a `calculate`.
131
+
132
+ calculate: (record, field, data) => data.location.display_address.join(', ')
133
+
134
+ Then remove the `renderer` from the table.
135
+
136
+ ??Calculating store values versus table renderers
137
+
138
+ Is it better to calculate values as you populate a store, or is it better
139
+ to user renderer functions to do the calculation?
140
+
141
+ Ideally, you want good data-view separation. In other words, you create your data stuctures
142
+ to use sensible primitive values, then have the UI display those in ways that makes sense
143
+ for a given part of the UI. That may mean formatting values.
144
+
145
+ Dates are a good example: stores will hold dates, but you don't want to store date strings,
146
+ because the view will decide how to format a date for that particular part of the UI. The
147
+ same holds for numbers, which may or may not be displayed with thousands separators, etc.
148
+
149
+ In the case of the address &mdash; which Yelp provides as an array of address parts &mdash; it's a
150
+ toss-up. An array of address parts seems more primitive and flexible, so maybe it's
151
+ preferable to have the view provide the renderer. But maybe not!
152
+
153
+