voom-presenters 0.1.13 → 2.0.3

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 (514) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. data/.github/ISSUE_TEMPLATE/questions-support.md +10 -0
  6. data/.github/workflows/semantic-release.yml +42 -0
  7. data/.gitignore +3 -2
  8. data/.releaserc +15 -0
  9. data/.ruby-version +2 -1
  10. data/CHANGELOG.md +143 -0
  11. data/CONTRIBUTING.md +60 -0
  12. data/Gemfile +14 -4
  13. data/Gemfile.lock +111 -65
  14. data/HISTORY.md +61 -0
  15. data/Procfile +1 -0
  16. data/README.md +55 -24
  17. data/app/demo/components/avatars.pom +40 -0
  18. data/app/demo/components/cards.pom +11 -4
  19. data/app/demo/components/chips.pom +65 -52
  20. data/app/demo/components/content.pom +111 -0
  21. data/app/demo/components/date_fields.pom +1 -1
  22. data/app/demo/components/datetime_fields.pom +6 -0
  23. data/app/demo/components/dialogs.pom +175 -6
  24. data/app/demo/components/drawers.pom +1 -1
  25. data/app/demo/components/file_inputs.pom +52 -0
  26. data/app/demo/components/footers.pom +1 -1
  27. data/app/demo/components/google_maps.pom +22 -0
  28. data/app/demo/components/headers.pom +80 -20
  29. data/app/demo/components/icons.pom +86 -55
  30. data/app/demo/components/image_lists.pom +100 -0
  31. data/app/demo/components/images.pom +45 -0
  32. data/app/demo/components/layouts.pom +15 -5
  33. data/app/demo/components/lists.pom +48 -3
  34. data/app/demo/components/menus.pom +14 -4
  35. data/app/demo/components/nav/menu.pom +40 -2
  36. data/app/demo/components/nav/pattern_drawer.pom +5 -0
  37. data/app/demo/components/nav/pattern_menu.pom +12 -0
  38. data/app/demo/components/number_fields.pom +53 -0
  39. data/app/demo/components/padding.pom +96 -0
  40. data/app/demo/components/progress.pom +71 -0
  41. data/app/demo/components/selects.pom +44 -5
  42. data/app/demo/components/sliders.pom +54 -0
  43. data/app/demo/components/snackbar.pom +10 -0
  44. data/app/demo/components/steppers.pom +178 -0
  45. data/app/demo/components/tab_bars.pom +66 -0
  46. data/app/demo/components/tables.pom +96 -13
  47. data/app/demo/components/text_areas.pom +23 -3
  48. data/app/demo/components/text_fields.pom +75 -17
  49. data/app/demo/components/toggles.pom +83 -16
  50. data/app/demo/components/tooltips.pom +10 -10
  51. data/app/demo/components/unordered_list.pom +81 -0
  52. data/app/demo/custom_css.pom +37 -0
  53. data/app/demo/events/actions/autocomplete.pom +3 -3
  54. data/app/demo/events/actions/clear.pom +25 -0
  55. data/app/demo/events/actions/dialogs/discard.pom +9 -0
  56. data/app/demo/events/actions/dialogs/show_dialog.pom +4 -2
  57. data/app/demo/events/actions/last_response.pom +40 -0
  58. data/app/demo/events/actions/loads.pom +16 -6
  59. data/app/demo/events/actions/posts.pom +1 -1
  60. data/app/demo/events/actions/prompt_if_dirty.pom +54 -0
  61. data/app/demo/events/actions/toggle_visiblity.pom +4 -3
  62. data/app/demo/events/content_as_form.pom +313 -0
  63. data/app/demo/events/nav/drawer.pom +7 -3
  64. data/app/demo/events/parallel.pom +44 -0
  65. data/app/demo/events/tagged_input.pom +37 -0
  66. data/app/demo/hello_world.pom +3 -0
  67. data/app/demo/index.pom +5 -5
  68. data/app/demo/markdown.pom +1 -0
  69. data/app/demo/namespaces.pom +89 -0
  70. data/app/demo/nav/top_nav.pom +22 -4
  71. data/app/demo/patterns.pom +19 -0
  72. data/app/demo/patterns/drag_drop.pom +89 -0
  73. data/app/demo/patterns/floating_card.pom +29 -0
  74. data/app/demo/patterns/search_select.pom +106 -0
  75. data/app/demo/plugins/chart.pom +254 -0
  76. data/app/demo/plugins/image_crop.pom +44 -0
  77. data/app/demo/plugins/index.pom +29 -0
  78. data/app/demo/plugins/nav/drawer.pom +19 -0
  79. data/app/demo/shared/context_list.pom +2 -2
  80. data/app/demo/styles.pom +24 -12
  81. data/bin/console +4 -4
  82. data/component-status.yml +26 -26
  83. data/config.ru +21 -10
  84. data/docs/settings.md +81 -0
  85. data/exe/presenters +3 -0
  86. data/lib/hash_ext/traverse.rb +14 -0
  87. data/lib/voom.rb +25 -0
  88. data/lib/voom/container_methods.rb +2 -2
  89. data/lib/voom/engine.rb +5 -0
  90. data/lib/voom/presenters/api/app.rb +46 -13
  91. data/lib/voom/presenters/api/router.rb +3 -87
  92. data/lib/voom/presenters/app.rb +3 -3
  93. data/lib/voom/presenters/cli.rb +28 -0
  94. data/lib/voom/presenters/demo/dragon_drop.rb +48 -0
  95. data/lib/voom/presenters/demo/echo.rb +7 -0
  96. data/lib/voom/presenters/demo/slow.rb +18 -0
  97. data/lib/voom/presenters/dsl/components/actions/autocomplete.rb +15 -0
  98. data/lib/voom/presenters/dsl/components/actions/base.rb +65 -0
  99. data/lib/voom/presenters/dsl/components/actions/clear.rb +15 -0
  100. data/lib/voom/presenters/dsl/components/actions/close_dialog.rb +17 -0
  101. data/lib/voom/presenters/dsl/components/actions/deletes.rb +15 -0
  102. data/lib/voom/presenters/dsl/components/actions/dialog.rb +15 -0
  103. data/lib/voom/presenters/dsl/components/actions/loads.rb +31 -0
  104. data/lib/voom/presenters/dsl/components/actions/navigates.rb +15 -0
  105. data/lib/voom/presenters/dsl/components/actions/post_message.rb +17 -0
  106. data/lib/voom/presenters/dsl/components/actions/posts.rb +20 -0
  107. data/lib/voom/presenters/dsl/components/actions/prompt_if_dirty.rb +15 -0
  108. data/lib/voom/presenters/dsl/components/actions/remove.rb +15 -0
  109. data/lib/voom/presenters/dsl/components/actions/replaces.rb +25 -0
  110. data/lib/voom/presenters/dsl/components/actions/snackbar.rb +15 -0
  111. data/lib/voom/presenters/dsl/components/actions/stepper.rb +15 -0
  112. data/lib/voom/presenters/dsl/components/actions/toggle_disabled.rb +15 -0
  113. data/lib/voom/presenters/dsl/components/actions/toggle_visibility.rb +15 -0
  114. data/lib/voom/presenters/dsl/components/actions/updates.rb +20 -0
  115. data/lib/voom/presenters/dsl/components/avatar.rb +5 -10
  116. data/lib/voom/presenters/dsl/components/badge.rb +0 -2
  117. data/lib/voom/presenters/dsl/components/base.rb +37 -21
  118. data/lib/voom/presenters/dsl/components/button.rb +23 -17
  119. data/lib/voom/presenters/dsl/components/card.rb +54 -42
  120. data/lib/voom/presenters/dsl/components/checkbox.rb +2 -2
  121. data/lib/voom/presenters/dsl/components/chip.rb +10 -13
  122. data/lib/voom/presenters/dsl/components/chipset.rb +33 -0
  123. data/lib/voom/presenters/dsl/components/content.rb +33 -13
  124. data/lib/voom/presenters/dsl/components/date_field.rb +1 -1
  125. data/lib/voom/presenters/dsl/components/datetime_base.rb +0 -3
  126. data/lib/voom/presenters/dsl/components/datetime_field.rb +0 -2
  127. data/lib/voom/presenters/dsl/components/dialog.rb +41 -13
  128. data/lib/voom/presenters/dsl/components/drawer.rb +13 -8
  129. data/lib/voom/presenters/dsl/components/event.rb +117 -60
  130. data/lib/voom/presenters/dsl/components/event_base.rb +1 -3
  131. data/lib/voom/presenters/dsl/components/expansion_panel.rb +3 -6
  132. data/lib/voom/presenters/dsl/components/file_input.rb +34 -0
  133. data/lib/voom/presenters/dsl/components/footer.rb +2 -2
  134. data/lib/voom/presenters/dsl/components/form.rb +3 -16
  135. data/lib/voom/presenters/dsl/components/grid.rb +64 -22
  136. data/lib/voom/presenters/dsl/components/header.rb +19 -6
  137. data/lib/voom/presenters/dsl/components/hidden_field.rb +1 -3
  138. data/lib/voom/presenters/dsl/components/icon.rb +3 -6
  139. data/lib/voom/presenters/dsl/components/icon_base.rb +6 -8
  140. data/lib/voom/presenters/dsl/components/icon_toggle.rb +3 -5
  141. data/lib/voom/presenters/dsl/components/image.rb +61 -13
  142. data/lib/voom/presenters/dsl/components/image_list.rb +43 -0
  143. data/lib/voom/presenters/dsl/components/input.rb +14 -5
  144. data/lib/voom/presenters/dsl/components/link.rb +33 -0
  145. data/lib/voom/presenters/dsl/components/list.rb +11 -16
  146. data/lib/voom/presenters/dsl/components/lists/action.rb +11 -14
  147. data/lib/voom/presenters/dsl/components/lists/actions.rb +7 -10
  148. data/lib/voom/presenters/dsl/components/lists/header.rb +2 -2
  149. data/lib/voom/presenters/dsl/components/lists/line.rb +34 -25
  150. data/lib/voom/presenters/dsl/components/lists/separator.rb +2 -2
  151. data/lib/voom/presenters/dsl/components/menu.rb +56 -16
  152. data/lib/voom/presenters/dsl/components/mixins/append.rb +2 -2
  153. data/lib/voom/presenters/dsl/components/mixins/attaches.rb +7 -3
  154. data/lib/voom/presenters/dsl/components/mixins/avatar.rb +1 -4
  155. data/lib/voom/presenters/dsl/components/mixins/buttons.rb +1 -1
  156. data/lib/voom/presenters/dsl/components/mixins/chips.rb +0 -3
  157. data/lib/voom/presenters/dsl/components/mixins/chipset.rb +19 -0
  158. data/lib/voom/presenters/dsl/components/mixins/common.rb +21 -16
  159. data/lib/voom/presenters/dsl/components/mixins/content.rb +1 -1
  160. data/lib/voom/presenters/dsl/components/mixins/date_time_fields.rb +0 -3
  161. data/lib/voom/presenters/dsl/components/mixins/dialogs.rb +0 -3
  162. data/lib/voom/presenters/dsl/components/mixins/event.rb +2 -4
  163. data/lib/voom/presenters/dsl/components/mixins/expansion_panels.rb +1 -1
  164. data/lib/voom/presenters/dsl/components/mixins/file_inputs.rb +16 -0
  165. data/lib/voom/presenters/dsl/components/mixins/google_maps.rb +15 -0
  166. data/lib/voom/presenters/dsl/components/mixins/grids.rb +1 -1
  167. data/lib/voom/presenters/dsl/components/mixins/icons.rb +0 -1
  168. data/lib/voom/presenters/dsl/components/mixins/image_lists.rb +15 -0
  169. data/lib/voom/presenters/dsl/components/mixins/last_response.rb +48 -0
  170. data/lib/voom/presenters/dsl/components/mixins/menus.rb +1 -1
  171. data/lib/voom/presenters/dsl/components/mixins/padding.rb +42 -0
  172. data/lib/voom/presenters/dsl/components/mixins/progress.rb +16 -0
  173. data/lib/voom/presenters/dsl/components/mixins/selects.rb +0 -1
  174. data/lib/voom/presenters/dsl/components/mixins/sliders.rb +15 -0
  175. data/lib/voom/presenters/dsl/components/mixins/snackbars.rb +0 -1
  176. data/lib/voom/presenters/dsl/components/mixins/steppers.rb +15 -0
  177. data/lib/voom/presenters/dsl/components/mixins/tab_bars.rb +17 -0
  178. data/lib/voom/presenters/dsl/components/mixins/tables.rb +15 -0
  179. data/lib/voom/presenters/dsl/components/mixins/text_fields.rb +10 -3
  180. data/lib/voom/presenters/dsl/components/mixins/toggles.rb +0 -5
  181. data/lib/voom/presenters/dsl/components/mixins/tooltips.rb +0 -1
  182. data/lib/voom/presenters/dsl/components/mixins/typography.rb +91 -14
  183. data/lib/voom/presenters/dsl/components/mixins/yield_to.rb +2 -2
  184. data/lib/voom/presenters/dsl/components/number_field.rb +20 -0
  185. data/lib/voom/presenters/dsl/components/page.rb +0 -1
  186. data/lib/voom/presenters/dsl/components/page_title.rb +31 -0
  187. data/lib/voom/presenters/dsl/components/progress.rb +27 -0
  188. data/lib/voom/presenters/dsl/components/radio_button.rb +0 -1
  189. data/lib/voom/presenters/dsl/components/rich_text_area.rb +20 -0
  190. data/lib/voom/presenters/dsl/components/select.rb +23 -12
  191. data/lib/voom/presenters/dsl/components/separator.rb +21 -0
  192. data/lib/voom/presenters/dsl/components/slider.rb +38 -0
  193. data/lib/voom/presenters/dsl/components/snackbar.rb +2 -2
  194. data/lib/voom/presenters/dsl/components/stepper.rb +96 -0
  195. data/lib/voom/presenters/dsl/components/switch.rb +0 -2
  196. data/lib/voom/presenters/dsl/components/tab_bar.rb +50 -0
  197. data/lib/voom/presenters/dsl/components/table.rb +126 -35
  198. data/lib/voom/presenters/dsl/components/text_area.rb +4 -5
  199. data/lib/voom/presenters/dsl/components/text_field.rb +55 -16
  200. data/lib/voom/presenters/dsl/components/time_field.rb +0 -2
  201. data/lib/voom/presenters/dsl/components/toggle_base.rb +8 -6
  202. data/lib/voom/presenters/dsl/components/tooltip.rb +1 -2
  203. data/lib/voom/presenters/dsl/components/typography.rb +6 -7
  204. data/lib/voom/presenters/dsl/components/unordered_list.rb +50 -0
  205. data/lib/voom/presenters/dsl/definer.rb +0 -4
  206. data/lib/voom/presenters/dsl/definition.rb +9 -6
  207. data/lib/voom/presenters/dsl/protect_from_forgery.rb +43 -0
  208. data/lib/voom/presenters/dsl/user_interface.rb +43 -32
  209. data/lib/voom/presenters/errors.rb +1 -0
  210. data/lib/voom/presenters/errors/invalid_dsl.rb +8 -0
  211. data/lib/voom/presenters/errors/parameter_validation.rb +1 -3
  212. data/lib/voom/presenters/generators/inflectors.rb +59 -0
  213. data/lib/voom/presenters/generators/plugin.rb +115 -0
  214. data/lib/voom/presenters/generators/templates/plugin/.gitignore +12 -0
  215. data/lib/voom/presenters/generators/templates/plugin/Gemfile +6 -0
  216. data/lib/voom/presenters/generators/templates/plugin/LICENSE.txt.tt +21 -0
  217. data/lib/voom/presenters/generators/templates/plugin/README.md +253 -0
  218. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/actions/action.rb.tt +16 -0
  219. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/actions/dsl.rb.tt +22 -0
  220. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/component.rb.tt +18 -0
  221. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/dsl.rb.tt +19 -0
  222. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/helpers/helper.rb.tt +15 -0
  223. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/plugin.rb.tt +9 -0
  224. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/web_client/components/actions/data.rb.tt +17 -0
  225. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/web_client/components/render.rb.tt +23 -0
  226. data/lib/voom/presenters/generators/templates/plugin/presenter_plugin.gemspec.tt +21 -0
  227. data/lib/voom/presenters/generators/templates/plugin/views/assets/css/components/component.css.tt +21 -0
  228. data/lib/voom/presenters/generators/templates/plugin/views/assets/js/components/actions/action.js.tt +15 -0
  229. data/lib/voom/presenters/generators/templates/plugin/views/assets/js/components/component.js.tt +39 -0
  230. data/lib/voom/presenters/generators/templates/plugin/views/components/component.erb.tt +14 -0
  231. data/lib/voom/presenters/generators/templates/plugin/views/components/component_header.erb.tt +20 -0
  232. data/lib/voom/presenters/helpers.rb +2 -8
  233. data/lib/voom/presenters/helpers/date.rb +3 -3
  234. data/lib/voom/presenters/helpers/inflector.rb +1 -1
  235. data/lib/voom/presenters/helpers/rails.rb +18 -6
  236. data/lib/voom/presenters/helpers/rails/model_table.rb +14 -6
  237. data/lib/voom/presenters/helpers/redact.rb +13 -0
  238. data/lib/voom/presenters/helpers/route.rb +15 -2
  239. data/lib/voom/presenters/helpers/time.rb +1 -1
  240. data/lib/voom/presenters/namespace.rb +12 -0
  241. data/lib/voom/presenters/pluggable.rb +37 -0
  242. data/lib/voom/presenters/plugins.rb +7 -0
  243. data/lib/voom/presenters/plugins/google_maps.rb +24 -0
  244. data/lib/voom/presenters/plugins/google_maps/google_map.erb +10 -0
  245. data/lib/voom/presenters/plugins/google_maps/google_map.rb +41 -0
  246. data/lib/voom/presenters/{dsl.rb → registry.rb} +14 -10
  247. data/lib/voom/presenters/router.rb +59 -0
  248. data/lib/voom/presenters/settings.rb +70 -39
  249. data/lib/voom/presenters/version.rb +3 -1
  250. data/lib/voom/presenters/web_client/app.rb +121 -34
  251. data/lib/voom/presenters/web_client/component_decorator_factory.rb +27 -0
  252. data/lib/voom/presenters/web_client/component_html_decorator.rb +50 -0
  253. data/lib/voom/presenters/web_client/component_renderer.rb +49 -0
  254. data/lib/voom/presenters/web_client/custom_css.rb +65 -0
  255. data/lib/voom/presenters/web_client/custom_render.rb +31 -0
  256. data/lib/voom/presenters/web_client/helpers/expand_hash.rb +19 -0
  257. data/lib/voom/presenters/web_client/helpers/form_helpers.rb +14 -0
  258. data/lib/voom/presenters/web_client/helpers/padding_helpers.rb +21 -0
  259. data/lib/voom/presenters/web_client/plugin_headers.rb +37 -0
  260. data/lib/voom/presenters/web_client/router.rb +3 -89
  261. data/lib/voom/railtie.rb +37 -0
  262. data/lib/voom/serializer.rb +2 -2
  263. data/lib/voom/symbol/to_str.rb +3 -3
  264. data/lib/voom/trace.rb +0 -2
  265. data/presenters.gemspec +12 -7
  266. data/public/bundle.css +18221 -0
  267. data/public/bundle.js +59949 -0
  268. data/public/img/demo/avatar.jpg +0 -0
  269. data/public/presenters/custom_css.css +26 -0
  270. data/public/style-bundle.js +2 -2
  271. data/public/wc.js +52704 -0
  272. data/scripts/build.sh +10 -0
  273. data/views/mdc/.babelrc +8 -0
  274. data/views/mdc/.eslintrc.yml +24 -0
  275. data/views/mdc/.nvmrc +1 -0
  276. data/views/mdc/assets/js/app.js +30 -6
  277. data/views/mdc/assets/js/components/base-component.js +160 -2
  278. data/views/mdc/assets/js/components/base-container.js +87 -0
  279. data/views/mdc/assets/js/components/base-toggle.js +56 -0
  280. data/views/mdc/assets/js/components/button.js +71 -9
  281. data/views/mdc/assets/js/components/cards.js +13 -2
  282. data/views/mdc/assets/js/components/checkboxes.js +11 -11
  283. data/views/mdc/assets/js/components/chips.js +104 -7
  284. data/views/mdc/assets/js/components/content.js +14 -0
  285. data/views/mdc/assets/js/components/data-tables.js +15 -0
  286. data/views/mdc/assets/js/components/datetime.js +83 -20
  287. data/views/mdc/assets/js/components/dialogs.js +130 -27
  288. data/views/mdc/assets/js/components/drag_n_drop.js +182 -0
  289. data/views/mdc/assets/js/components/drawer.js +43 -0
  290. data/views/mdc/assets/js/components/events.js +195 -68
  291. data/views/mdc/assets/js/components/events/action_parameter.js +62 -0
  292. data/views/mdc/assets/js/components/events/action_parameter.test.js +62 -0
  293. data/views/mdc/assets/js/components/events/autocomplete.js +15 -17
  294. data/views/mdc/assets/js/components/events/base.js +142 -16
  295. data/views/mdc/assets/js/components/events/clears.js +15 -12
  296. data/views/mdc/assets/js/components/events/close_dialog.js +50 -0
  297. data/views/mdc/assets/js/components/events/dialog.js +32 -14
  298. data/views/mdc/assets/js/components/events/encode.js +8 -0
  299. data/views/mdc/assets/js/components/events/errors.js +175 -92
  300. data/views/mdc/assets/js/components/events/loads.js +50 -11
  301. data/views/mdc/assets/js/components/events/navigates.js +17 -15
  302. data/views/mdc/assets/js/components/events/plugin.js +18 -0
  303. data/views/mdc/assets/js/components/events/post_message.js +21 -0
  304. data/views/mdc/assets/js/components/events/posts.js +169 -47
  305. data/views/mdc/assets/js/components/events/prompt_if_dirty.js +67 -0
  306. data/views/mdc/assets/js/components/events/removes.js +21 -0
  307. data/views/mdc/assets/js/components/events/replaces.js +110 -57
  308. data/views/mdc/assets/js/components/events/snackbar.js +10 -10
  309. data/views/mdc/assets/js/components/events/stepper.js +21 -0
  310. data/views/mdc/assets/js/components/events/toggle_disabled.js +41 -0
  311. data/views/mdc/assets/js/components/events/toggle_visibility.js +62 -16
  312. data/views/mdc/assets/js/components/file-inputs.js +76 -0
  313. data/views/mdc/assets/js/components/form-fields.js +16 -0
  314. data/views/mdc/assets/js/components/forms.js +9 -60
  315. data/views/mdc/assets/js/components/get_event_target.js +15 -0
  316. data/views/mdc/assets/js/components/grid.js +21 -0
  317. data/views/mdc/assets/js/components/header.js +20 -0
  318. data/views/mdc/assets/js/components/hidden-fields.js +44 -0
  319. data/views/mdc/assets/js/components/icon-toggles.js +10 -17
  320. data/views/mdc/assets/js/components/images.js +19 -0
  321. data/views/mdc/assets/js/components/initialize.js +62 -18
  322. data/views/mdc/assets/js/components/lists.js +10 -5
  323. data/views/mdc/assets/js/components/menus.js +66 -20
  324. data/views/mdc/assets/js/components/mixins/dirtyable.js +22 -0
  325. data/views/mdc/assets/js/components/mixins/event-handler.js +7 -7
  326. data/views/mdc/assets/js/components/mixins/visibility-observer.js +35 -0
  327. data/views/mdc/assets/js/components/plugins.js +86 -0
  328. data/views/mdc/assets/js/components/progress.js +31 -0
  329. data/views/mdc/assets/js/components/radios.js +14 -0
  330. data/views/mdc/assets/js/components/rich-text-area.js +227 -0
  331. data/views/mdc/assets/js/components/rich-text-area/horizontal-rule-blot.js +23 -0
  332. data/views/mdc/assets/js/components/root_document.js +5 -0
  333. data/views/mdc/assets/js/components/selects.js +41 -30
  334. data/views/mdc/assets/js/components/sliders.js +67 -0
  335. data/views/mdc/assets/js/components/snackbar.js +17 -23
  336. data/views/mdc/assets/js/components/steppers.js +48 -0
  337. data/views/mdc/assets/js/components/switches.js +10 -32
  338. data/views/mdc/assets/js/components/tab-bars.js +28 -0
  339. data/views/mdc/assets/js/components/text-fields.js +117 -43
  340. data/views/mdc/assets/js/components/tooltip.js +17 -0
  341. data/views/mdc/assets/js/components/typography.js +28 -0
  342. data/views/mdc/assets/js/components/uninitialize.js +7 -0
  343. data/views/mdc/assets/js/config.js +27 -0
  344. data/views/mdc/assets/js/mdl-stepper.js +1108 -0
  345. data/views/mdc/assets/js/utils/compatibility.js +9 -0
  346. data/views/mdc/assets/js/utils/config.js +73 -0
  347. data/views/mdc/assets/js/utils/config.test.js +59 -0
  348. data/views/mdc/assets/js/utils/urls.js +5 -2
  349. data/views/mdc/assets/js/wc.js +111 -0
  350. data/views/mdc/assets/scss/app.scss +20 -5
  351. data/views/mdc/assets/scss/components/avatar.scss +51 -7
  352. data/views/mdc/assets/scss/components/button.scss +20 -7
  353. data/views/mdc/assets/scss/components/card.scss +13 -7
  354. data/views/mdc/assets/scss/components/checkbox.scss +0 -4
  355. data/views/mdc/assets/scss/components/chip.scss +4 -0
  356. data/views/mdc/assets/scss/components/content.scss +36 -0
  357. data/views/mdc/assets/scss/components/data-table.scss +91 -0
  358. data/views/mdc/assets/scss/components/datetime.scss +7 -2
  359. data/views/mdc/assets/scss/components/dialog.scss +7 -2
  360. data/views/mdc/assets/scss/components/drag_n_drop.scss +17 -0
  361. data/views/mdc/assets/scss/components/drawer.scss +82 -0
  362. data/views/mdc/assets/scss/components/expansion-panel.scss +2 -2
  363. data/views/mdc/assets/scss/components/fab.scss +23 -4
  364. data/views/mdc/assets/scss/components/file-input.scss +18 -0
  365. data/views/mdc/assets/scss/components/grid.scss +74 -3
  366. data/views/mdc/assets/scss/components/header.scss +21 -0
  367. data/views/mdc/assets/scss/components/icon-button-toggles.scss +2 -0
  368. data/views/mdc/assets/scss/components/icon.scss +23 -0
  369. data/views/mdc/assets/scss/components/image-list.scss +18 -0
  370. data/views/mdc/assets/scss/components/image.scss +14 -16
  371. data/views/mdc/assets/scss/components/list.scss +19 -0
  372. data/views/mdc/assets/scss/components/menu.scss +14 -3
  373. data/views/mdc/assets/scss/components/progress.scss +1 -0
  374. data/views/mdc/assets/scss/components/radio.scss +4 -0
  375. data/views/mdc/assets/scss/components/rich-text-area.scss +73 -0
  376. data/views/mdc/assets/scss/components/select.scss +6 -3
  377. data/views/mdc/assets/scss/components/separator.scss +3 -0
  378. data/views/mdc/assets/scss/components/slider.scss +1 -0
  379. data/views/mdc/assets/scss/components/snackbar.scss +1 -5
  380. data/views/mdc/assets/scss/components/stepper.scss +235 -0
  381. data/views/mdc/assets/scss/components/switch.scss +13 -4
  382. data/views/mdc/assets/scss/components/tab-bars.scss +4 -0
  383. data/views/mdc/assets/scss/components/textfield.scss +14 -3
  384. data/views/mdc/assets/scss/components/tooltip.scss +3 -0
  385. data/views/mdc/assets/scss/components/typography.scss +10 -0
  386. data/views/mdc/assets/scss/components/unordered-lists.scss +17 -0
  387. data/views/mdc/assets/scss/components/vendor/quill.snow.css +945 -0
  388. data/views/mdc/assets/scss/material.blue_grey-orange.min.css +1 -1
  389. data/views/mdc/assets/scss/media.scss +39 -0
  390. data/views/mdc/assets/scss/palette.scss +16 -0
  391. data/views/mdc/assets/scss/styles.scss +40 -1
  392. data/views/mdc/assets/scss/theme.scss +25 -2
  393. data/views/mdc/body/dismissable-drawer.erb +34 -0
  394. data/views/mdc/body/drawer/divider.erb +1 -0
  395. data/views/mdc/body/drawer/item.erb +13 -0
  396. data/views/mdc/body/drawer/label.erb +1 -0
  397. data/views/mdc/body/drawers/menu.erb +1 -1
  398. data/views/mdc/body/footers/menu_item.erb +2 -2
  399. data/views/mdc/body/header.erb +38 -30
  400. data/views/mdc/body/modal-drawer.erb +35 -0
  401. data/views/mdc/body/snackbar.erb +12 -6
  402. data/views/mdc/components/actions/autocomplete.rb +8 -0
  403. data/views/mdc/components/actions/clear.rb +11 -0
  404. data/views/mdc/components/actions/close_dialog.rb +10 -0
  405. data/views/mdc/components/actions/delete.rb +11 -0
  406. data/views/mdc/components/actions/dialog.rb +11 -0
  407. data/views/mdc/components/actions/loads.rb +17 -0
  408. data/views/mdc/components/actions/navigates.rb +11 -0
  409. data/views/mdc/components/actions/post.rb +14 -0
  410. data/views/mdc/components/actions/post_message.rb +10 -0
  411. data/views/mdc/components/actions/prompt_if_dirty.rb +17 -0
  412. data/views/mdc/components/actions/remove.rb +10 -0
  413. data/views/mdc/components/actions/replaces.rb +16 -0
  414. data/views/mdc/components/actions/resolver.rb +39 -0
  415. data/views/mdc/components/actions/snackbar.rb +12 -0
  416. data/views/mdc/components/actions/stepper.rb +10 -0
  417. data/views/mdc/components/actions/toggle_disabled.rb +10 -0
  418. data/views/mdc/components/actions/toggle_visibility.rb +10 -0
  419. data/views/mdc/components/actions/update.rb +10 -0
  420. data/views/mdc/components/avatar.erb +12 -7
  421. data/views/mdc/components/badge.erb +1 -1
  422. data/views/mdc/components/button.erb +10 -8
  423. data/views/mdc/components/buttons/button.erb +19 -14
  424. data/views/mdc/components/buttons/fab.erb +9 -2
  425. data/views/mdc/components/buttons/icon.erb +12 -5
  426. data/views/mdc/components/buttons/image.erb +11 -5
  427. data/views/mdc/components/{display.erb → caption.erb} +0 -0
  428. data/views/mdc/components/card.erb +67 -41
  429. data/views/mdc/components/checkbox.erb +32 -23
  430. data/views/mdc/components/chip.erb +39 -22
  431. data/views/mdc/components/chipset.erb +18 -0
  432. data/views/mdc/components/content.erb +37 -11
  433. data/views/mdc/components/datetime.erb +12 -17
  434. data/views/mdc/components/dialog.erb +45 -22
  435. data/views/mdc/components/drag_and_drop/drag_and_drop.rb +16 -0
  436. data/views/mdc/components/event.erb +3 -9
  437. data/views/mdc/components/expansion_panel.erb +8 -6
  438. data/views/mdc/components/file_input.erb +17 -0
  439. data/views/mdc/components/form.erb +7 -8
  440. data/views/mdc/components/grid.erb +27 -10
  441. data/views/mdc/components/headline.erb +2 -0
  442. data/views/mdc/components/hidden_field.erb +5 -1
  443. data/views/mdc/components/icon.erb +7 -5
  444. data/views/mdc/components/icon_toggle.erb +9 -8
  445. data/views/mdc/components/image.erb +23 -5
  446. data/views/mdc/components/image_list.erb +38 -0
  447. data/views/mdc/components/link.erb +3 -13
  448. data/views/mdc/components/list.erb +9 -4
  449. data/views/mdc/components/list/actions/switch.erb +1 -1
  450. data/views/mdc/components/list/avatar.erb +2 -1
  451. data/views/mdc/components/list/header.erb +5 -3
  452. data/views/mdc/components/list/hidden_field.erb +3 -0
  453. data/views/mdc/components/list/icon.erb +2 -1
  454. data/views/mdc/components/list/line.erb +24 -13
  455. data/views/mdc/components/list/menu.erb +7 -2
  456. data/views/mdc/components/list/separator.erb +1 -1
  457. data/views/mdc/components/menu.erb +20 -16
  458. data/views/mdc/components/number_field.erb +38 -0
  459. data/views/mdc/components/{subheading.erb → overline.erb} +0 -0
  460. data/views/mdc/components/page_title.erb +2 -2
  461. data/views/mdc/components/progress.erb +11 -0
  462. data/views/mdc/components/radio_button.erb +19 -10
  463. data/views/mdc/components/render.erb +2 -3
  464. data/views/mdc/components/rich_text_area.erb +22 -0
  465. data/views/mdc/components/select.erb +28 -8
  466. data/views/mdc/components/separator.erb +3 -0
  467. data/views/mdc/components/shared/hint_error_display.erb +9 -0
  468. data/views/mdc/components/shared/input_label.erb +7 -0
  469. data/views/mdc/components/slider.erb +43 -0
  470. data/views/mdc/components/snackbar.erb +2 -6
  471. data/views/mdc/components/stepper.erb +47 -0
  472. data/views/mdc/components/stepper/step.erb +33 -0
  473. data/views/mdc/components/{title.erb → subtitle.erb} +0 -0
  474. data/views/mdc/components/switch.erb +28 -12
  475. data/views/mdc/components/tab_bar.erb +35 -0
  476. data/views/mdc/components/table.erb +28 -13
  477. data/views/mdc/components/table/checkbox.erb +20 -0
  478. data/views/mdc/components/table/column.erb +18 -0
  479. data/views/mdc/components/table/footer.erb +8 -0
  480. data/views/mdc/components/table/header.erb +14 -4
  481. data/views/mdc/components/table/pagination.erb +11 -24
  482. data/views/mdc/components/table/row.erb +7 -5
  483. data/views/mdc/components/text_area.erb +15 -7
  484. data/views/mdc/components/text_field.erb +38 -28
  485. data/views/mdc/components/tooltip.erb +2 -2
  486. data/views/mdc/components/typography.erb +7 -5
  487. data/views/mdc/components/unordered_list.erb +10 -0
  488. data/views/mdc/components/unordered_list/icon.erb +3 -0
  489. data/views/mdc/components/unordered_list/list_item.erb +7 -0
  490. data/views/mdc/layout.erb +45 -31
  491. data/views/mdc/package-lock.json +11801 -6869
  492. data/views/mdc/package.json +66 -29
  493. data/views/mdc/web.erb +4 -0
  494. data/views/mdc/webpack.config.js +14 -1
  495. metadata +327 -37
  496. data/app/demo/component_status.pom +0 -76
  497. data/app/demo/components/forms.pom +0 -31
  498. data/lib/voom-presenters.rb +0 -9
  499. data/lib/voom/presenters-engine.rb +0 -41
  500. data/lib/voom/presenters.rb +0 -13
  501. data/lib/voom/presenters/dsl/components/action.rb +0 -35
  502. data/lib/voom/presenters/web_client/markdown_render.rb +0 -16
  503. data/public/.gitignore +0 -2
  504. data/scripts/bump.sh +0 -4
  505. data/scripts/deploy-demo.sh +0 -2
  506. data/scripts/release.sh +0 -5
  507. data/views/mdc/assets/js/dialog-polyfill.js +0 -738
  508. data/views/mdc/assets/js/material.js +0 -3996
  509. data/views/mdc/assets/scss/components/icon-toggles.scss +0 -9
  510. data/views/mdc/assets/scss/components/table-pagination.scss +0 -65
  511. data/views/mdc/assets/scss/components/vendor/flatpickr.min.css +0 -13
  512. data/views/mdc/body/drawer.erb +0 -18
  513. data/views/mdc/components/modal.erb +0 -15
  514. data/views/mdc/components/static.erb +0 -7
@@ -2,9 +2,22 @@ module Voom
2
2
  module Presenters
3
3
  module Helpers
4
4
  module Route
5
- def presenters_path(presenter, **params)
6
- router.url(render: presenter, context: params)
5
+ include Namespace
6
+
7
+ def presenters_path(presenter, host: false, **params)
8
+ presenter = _expand_namespace_(presenter, namespace)
9
+ presenter = presenter.gsub(':', '/')
10
+ router.url(render: presenter, host: host, context: params)
7
11
  end
12
+
13
+ alias presenter_path presenters_path
14
+
15
+ # Full qualified URL
16
+ def presenters_url(presenter, **params)
17
+ presenters_path(presenter, host: true, **params)
18
+ end
19
+
20
+ alias presenter_url presenters_url
8
21
  end
9
22
  end
10
23
  end
@@ -7,7 +7,7 @@ module Voom
7
7
  LONG_FORMAT='%m/%d/%Y %I:%M:%S %p %Z'
8
8
  SHORT_FORMAT='%d %b %H:%M %Z'
9
9
 
10
- def format_time(time, format: '%m/%d/%Y %I:%M:%S %p %Z', timezone: nil)
10
+ def format_time(time, format: LONG_FORMAT, timezone: nil)
11
11
  return '' unless time
12
12
  time = time.in_time_zone(timezone) if timezone
13
13
  time.strftime(format)
@@ -0,0 +1,12 @@
1
+ module Voom
2
+ module Presenters
3
+ module Namespace
4
+ def _expand_namespace_(presenter, namespace)
5
+ presenter = presenter.to_s
6
+ return presenter if presenter.split(':').size > 1
7
+ return presenter if presenter.split('/').size > 1
8
+ namespace.any? ? namespace.join(':')+':'+presenter : presenter
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,37 @@
1
+ include Voom::Trace
2
+
3
+ module Voom
4
+ module Presenters
5
+ module Pluggable
6
+ def include_plugins(*layers, plugins: [],
7
+ plugin_method: method(:include))
8
+ plugins = Array(plugins) + Array(Voom::Presenters::Settings.config.presenters.plugins)
9
+ plugins.uniq.each do |plugin|
10
+ plugin(plugin, *layers, plugin_method: plugin_method)
11
+ end
12
+ end
13
+
14
+
15
+ # Returns the module for the specified plugin. If the module is not
16
+ # defined, the corresponding plugin required.
17
+ def plugin_module(plugin)
18
+ module_name = plugin.to_s.gsub(/(^|_)(.)/) {|x| x[-1..-1].upcase}
19
+ unless Voom::Presenters::Plugins.const_defined?(module_name, false)
20
+ trace {"Method plugin loading plugin: #{plugin}"}
21
+ load "voom/presenters/plugins/#{plugin}.rb"
22
+ end
23
+ Voom::Presenters::Plugins.const_get(module_name)
24
+ end
25
+
26
+ def plugin(plugin, *layers, plugin_method: method(:include))
27
+ m = plugin.is_a?(Module) ? plugin : plugin_module(plugin)
28
+ layers.each do |layer|
29
+ if m.const_defined?(layer, false) && !self.const_defined?(layer, false)
30
+ trace {"Injecting plugin(#{m.const_get(layer).inspect}) into #{self.inspect}!"}
31
+ plugin_method.call(m.const_get(layer))
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ module Voom
2
+ module Presenters
3
+ module Plugins
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ module Voom
2
+ module Presenters
3
+ module Plugins
4
+ module GoogleMaps
5
+ module DSLComponents
6
+ def google_map(**attributes, &block)
7
+ self << GoogleMap.new(parent: self, **attributes, &block)
8
+ end
9
+ end
10
+ module WebClientComponents
11
+ def render_google_map(comp,
12
+ render:,
13
+ components:,
14
+ index:)
15
+ view_dir = File.join(__dir__, 'google_maps')
16
+ render.call :erb, :google_map, views: view_dir,
17
+ locals: {comp: comp,
18
+ components: components, index: index}
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ <% if comp %>
2
+ <img id="<%= comp.id %>"
3
+ class="v-image v-google-map-image <%= comp.events ? 'v-actionable' : nil%>"
4
+ src="<%= comp.url %>"
5
+ border="0"
6
+ height="<%= comp.height %>"
7
+ width="<%= comp.width %>"
8
+ alt=""
9
+ <%= erb :"components/event", :locals => {comp: comp, events: comp.events, parent_id: comp.id} %>>
10
+ <% end %>
@@ -0,0 +1,41 @@
1
+ require 'uri'
2
+
3
+ module Voom
4
+ module Presenters
5
+ module Plugins
6
+ module GoogleMaps
7
+ class GoogleMap < DSL::Components::EventBase
8
+
9
+ attr_reader :url, :google_api_key, :height, :width
10
+
11
+ def initialize(**attribs_, &block)
12
+ super(type: :google_map, **attribs_, &block)
13
+ @address = attribs.delete(:address)
14
+ @latitude = attribs.delete(:latitude)
15
+ @longitude = attribs.delete(:longitude)
16
+ @width = attribs.delete(:width) { 640 }
17
+ @height = attribs.delete(:height) { 640 }
18
+ @zoom = attribs.delete(:zoom) { 14 }
19
+ @scale = attribs.delete(:scale) { 1 }
20
+ @google_api_key = attribs.delete(:google_api_key) { ENV['GOOGLE_API_KEY'] }
21
+ @url = build_static_map_image_url
22
+ expand!
23
+ end
24
+
25
+ private
26
+
27
+ def build_static_map_image_url
28
+ return @img_url if locked?
29
+ @img_url = "https://maps.googleapis.com/maps/api/staticmap?center=#{query_string}&zoom=#{@zoom}&scale=#{@scale}&size=#{@width}x#{@height}&markers=|#{query_string}&key=#{@google_api_key}"
30
+ end
31
+
32
+ def query_string
33
+ return "#{@latitude},#{@longitude}" if @latitude && @longitude
34
+ URI.escape(@address)
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,12 +1,6 @@
1
- require 'voom/trace'
2
-
3
1
  module Voom
4
2
  module Presenters
5
- def self.define(name, &block)
6
- DSL.define(name, &block)
7
- end
8
-
9
- module DSL
3
+ class Registry
10
4
  class << self
11
5
  include Voom::Trace
12
6
  end
@@ -17,8 +11,10 @@ module Voom
17
11
  @registry
18
12
  end
19
13
 
20
- def self.define(name, &block)
21
- registry[name] = Voom::Presenters::DSL::Definition.new(&block)
14
+ def self.define(name, namespace, options, &block)
15
+ namespace = Array(namespace).map(&:to_s)
16
+ fq_name = namespace.any? ? namespace.join(':') + ':' + name.to_s : name.to_s
17
+ registry[fq_name] = Voom::Presenters::DSL::Definition.new(name, namespace, options, &block)
22
18
  end
23
19
 
24
20
  def self.load(directory)
@@ -49,12 +45,20 @@ module Voom
49
45
 
50
46
  def self.register(name, definition)
51
47
  return Voom::Presenters::App.register(name: name, presenter: definition) unless Voom::Presenters::App.registered?(name)
52
- logger.warn {"Warning attempted to redefine the presenter: #{name}!"}
53
48
  end
54
49
 
55
50
  def self.build(definition)
56
51
  definition.build
57
52
  end
58
53
  end
54
+
55
+ def self.define(name, namespace: nil, options: {}, &block)
56
+ unless namespace
57
+ namespace = name.to_s.split(':')
58
+ name = namespace.pop
59
+ end
60
+ Registry.define(name, namespace, options, &block)
61
+ end
62
+
59
63
  end
60
64
  end
@@ -0,0 +1,59 @@
1
+ require 'rack'
2
+
3
+ module Voom
4
+ module Presenters
5
+ class Router
6
+
7
+ attr_reader :base_url
8
+
9
+ def initialize(base_url: nil)
10
+ @base_url = base_url
11
+ end
12
+
13
+ def url(command: nil, render: nil, host: false, context:)
14
+ _params_ = context.dup
15
+ return build_render_url(render, _params_, host: host) unless command
16
+ _params_[:redirect]=build_render_url(render, _params_) if render
17
+ build_command_url(command, _params_)
18
+ end
19
+
20
+ def scrub_params(_params_)
21
+ _params_.delete('captures')
22
+ _params_.delete('presenter')
23
+ _params_.delete('action')
24
+ _params_.delete('errors')
25
+ _params_
26
+ end
27
+
28
+ private
29
+
30
+ def build_command_url(command, params)
31
+ return '' unless command
32
+ add_query_params(command, params)
33
+ end
34
+
35
+ def build_render_url(render_, params, host:)
36
+ return '#' unless render_
37
+ render = render_.to_s
38
+ return render if render.start_with?('http')
39
+ render = render.gsub(':', '/')
40
+ seperator = render.start_with?('/') ? '' : '/'
41
+ url = "#{host ? base_url : nil}#{seperator}#{render}"
42
+ add_query_params(url, params)
43
+ end
44
+
45
+ def add_query_params(url, params)
46
+ query_params = build_params(params)
47
+ if (!query_params.nil? && !query_params.empty?)
48
+ query_seperator = url.include?('?') ? '&' : '?'
49
+ url = "#{url}#{query_seperator}#{query_params}"
50
+ end
51
+ url
52
+ end
53
+
54
+ def build_params(params)
55
+ Rack::Utils.build_nested_query(scrub_params(params))
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,48 +1,79 @@
1
- include Voom::Trace
2
- trace {"Loading Presenters Settings"}
3
- require_relative 'helpers/route'
1
+ #include Voom::Trace
2
+ #trace {"Loading Presenters Settings"}
3
+ require 'dry-configurable'
4
4
 
5
- module Voom
6
- module Presenters
7
- class Settings
8
- extend Dry::Configurable
9
- setting :presenters do
10
- setting :root, []
11
- # You can add helpers that will automatically be included
12
- # For example:
13
- # For example:
14
- # Voom::Presenters::Settings.configure do |config|
15
- # config.presenters.helpers << YourHelperModule # Passing a module
16
- # config.presenters.helpers << &->{ def foo; :foo; end } # Passing a block
17
- # end
18
- setting :helpers, [Voom::Presenters::Helpers::Route]
19
- setting :deep_freeze, true
20
- setting :id_generator, ->(node) {"id-#{SecureRandom.hex}"}
21
- setting :web_client do
22
- # Add lambda's to modify the context for the presenters
5
+ unless defined?(Voom::Presenters::Settings)
6
+ module Voom
7
+ module Presenters
8
+ class Settings
9
+ extend ::Dry::Configurable
10
+ setting :presenters do
11
+ setting :root, []
12
+ # You can add helpers that will automatically be included
23
13
  # For example:
24
14
  # Voom::Presenters::Settings.configure do |config|
25
- # config.presenters.web_client.prepare_context << ->(context, session, _env){
26
- # identity_id = session[:aaa_identity]
27
- # context.merge(aaa_identity: identity_id)
28
- # }
15
+ # config.presenters.helpers << YourHelperModule # Passing a module
16
+ # config.presenters.helpers << &->{ def foo; :foo; end } # Passing a block
29
17
  # end
30
- setting :prepare_context, []
31
- end
32
- setting :components do
33
- setting :defaults do
34
- setting :datetime do
35
- setting :format, 'F j, Y h:i K'
36
- setting :time_24hr, false
37
- end
38
- setting :date do
39
- setting :format, 'F j, Y'
40
- end
41
- setting :time do
42
- setting :format, 'h:i K'
43
- setting :time_24hr, false
18
+ setting :helpers, [Voom::Presenters::Helpers::Route]
19
+ setting :deep_freeze, false
20
+ setting :id_generator, ->(node) {"id-#{SecureRandom.hex}"}
21
+ setting :web_client do
22
+ # Add lambda's to modify the context for the presenters
23
+ # For example:
24
+ # Voom::Presenters::Settings.configure do |config|
25
+ # config.presenters.web_client.prepare_context << ->(context, session, _env){
26
+ # identity_id = session[:aaa_identity]
27
+ # context.merge(aaa_identity: identity_id)
28
+ # }
29
+ # end
30
+ setting :prepare_context, []
31
+ # Relative to the root
32
+ setting :custom_css, '../public/presenters'
33
+ setting :protect_from_forgery, false
34
+ end
35
+ setting :plugins, [:google_maps]
36
+ setting :components do
37
+ setting :defaults do
38
+ setting :datetime do
39
+ setting :format, 'M j, y h:i K'
40
+ setting :time_24hr, false
41
+ end
42
+ setting :date do
43
+ setting :format, 'F j, Y'
44
+ end
45
+ setting :time do
46
+ setting :format, 'h:i K'
47
+ setting :time_24hr, false
48
+ end
49
+ setting :text_area do
50
+ setting :rows, 3
51
+ setting :cols, 80
52
+ end
53
+ # Typography
54
+ setting :headline do
55
+ setting :level, 5
56
+ end
57
+ setting :title do
58
+ setting :level, 6
59
+ end
60
+ setting :rich_text_area do
61
+ setting :rows, 6
62
+ end
44
63
  end
45
64
  end
65
+ setting :error_logger, ->(file, e, _params, _presenter_name) {
66
+ msg = [
67
+ "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{e.class} - #{e.message}:",
68
+ *e.backtrace
69
+ ].join("\n\t")
70
+ file.puts(msg)
71
+ }
72
+ setting :before_render, [] # an array of `#call`ables
73
+ end
74
+
75
+ def self.default(type, key)
76
+ config.presenters.components.defaults&.public_send(type)&.public_send(key)
46
77
  end
47
78
  end
48
79
  end
@@ -1,5 +1,7 @@
1
1
  module Voom
2
2
  module Presenters
3
- VERSION = '0.1.13'.freeze
3
+ module Version
4
+ VERSION = '2.0.3'
5
+ end
4
6
  end
5
7
  end
@@ -1,13 +1,8 @@
1
1
  require 'sinatra'
2
+ require 'honeybadger' if ENV['HONEYBADGER_API_KEY']
2
3
  require 'uri'
3
4
  require 'redcarpet'
4
- require 'voom/trace'
5
- require 'voom/presenters/app'
6
- require "dry/inflector"
7
-
8
- require_relative 'router'
9
- require_relative 'markdown_render'
10
- require_relative '../errors/unprocessable'
5
+ require 'dry/inflector'
11
6
 
12
7
  module Voom
13
8
  module Presenters
@@ -17,9 +12,20 @@ module Voom
17
12
  set :root, File.expand_path('../../../../..', __FILE__)
18
13
  set :router_, WebClient::Router
19
14
  set :bind, '0.0.0.0'
20
- set :views, Proc.new {File.join(root, "views", ENV['VIEW_ENGINE']||'mdc')}
21
-
15
+ set :views, Proc.new {File.join(root, "views", ENV['VIEW_ENGINE'] || 'mdc')}
16
+ set :dump_errors, false
17
+ set :protection, :except => :frame_options
18
+ configure do
19
+ enable :logging
20
+ end
21
+ helpers Helpers::FormHelpers
22
+ helpers Helpers::PaddingHelpers
23
+ helpers Helpers::ExpandHash
22
24
  helpers do
25
+ def render_component(scope, comp, components, index)
26
+ ComponentRenderer.new(comp, render: method(:render), scope: scope, components: components, index: index).render
27
+ end
28
+
23
29
  def markdown(text)
24
30
  unless @markdown
25
31
  renderer = CustomRender.new(hard_wrap: false, filter_html: true)
@@ -46,21 +52,43 @@ module Voom
46
52
  attrib.to_s == value.to_s
47
53
  end
48
54
 
55
+ def h(text)
56
+ Rack::Utils.escape_html(text)
57
+ end
58
+
59
+ def include?(array, value)
60
+ array.map(&:to_s).include?(value.to_s)
61
+ end
62
+
63
+ def includes_one?(array1, array2)
64
+ (array2.map(&:to_sym)-array1.map(&:to_sym)).size != array2.size
65
+ end
66
+
49
67
  def unique_id(comp)
50
68
  "#{comp.id}-#{SecureRandom.hex(4)}"
51
69
  end
52
70
 
53
- def expand_text(text)
54
- self.markdown(Array(text).join("\n\n")) #.gsub("\n\n", "<br/>")
71
+ def expand_text(text, markdown: true)
72
+ if markdown
73
+ self.markdown(Array(text).join("\n\n")) #.gsub("\n\n", "<br/>")
74
+ else
75
+ Array(text).join('<br/>')
76
+ end
55
77
  end
56
78
 
57
- def color_classname(comp)
58
- return "v-#{comp.type}__primary" if eq(comp.color, :primary)
59
- "v-#{comp.type}__secondary" if eq(comp.color, :secondary)
79
+ def color_classname(comp, affects = nil, color_attr = :color)
80
+ color = comp&.public_send(color_attr)
81
+ return unless color
82
+
83
+ return "v-#{comp.type}__primary" if eq(color, :primary)
84
+ return "v-#{comp.type}__secondary" if eq(color, :secondary)
85
+
86
+ "v-#{affects}color__#{color}"
60
87
  end
61
88
 
62
- def color_style(comp, affects=nil)
63
- "#{affects}color: #{comp.color};" unless %w(primary secondary).include?(comp.color.to_s) || comp.color.nil?
89
+ def color_style(comp, affects = nil, color_attr = :color)
90
+ color = comp.public_send(color_attr)
91
+ "#{affects}color: #{color};" unless %w(primary secondary).include?(color.to_s) || color.nil?
64
92
  end
65
93
 
66
94
  def snake_to_camel(hash, except: [])
@@ -80,17 +108,38 @@ module Voom
80
108
 
81
109
  def transform(thing)
82
110
  case thing
83
- when OpenStruct
84
- to_hash(thing)
85
- when Array
86
- thing.map {|v| transform(v)}
87
- else
88
- thing
111
+ when OpenStruct
112
+ to_hash(thing)
113
+ when Array
114
+ thing.map {|v| transform(v)}
115
+ else
116
+ thing
89
117
  end
90
118
  end
91
119
 
120
+ def plugin_headers(pom)
121
+ PluginHeaders.new(pom: pom, render: method(:render)).render
122
+ end
123
+
124
+ def custom_css(path, host=nil)
125
+ CustomCss.new(path, root: Presenters::Settings.config.presenters.root, host: host).render
126
+ end
127
+
128
+ def custom_js
129
+ custom_js_path = Presenters::Settings.config.presenters.web_client.custom_js
130
+ Dir.glob(custom_js_path).map do |file|
131
+ _build_script_tag_(file)
132
+ end.join("\n") if custom_js_path
133
+ end
134
+
135
+ def _build_script_tag_(path)
136
+ (<<~JS)
137
+ <script defer src="#{env['SCRIPT_NAME']}#{path.sub('public/','')}"></script>
138
+ JS
139
+ end
92
140
  end
93
141
 
142
+
94
143
  get '/' do
95
144
  pass unless Presenters::App.registered?('index')
96
145
  presenter = Presenters::App['index'].call
@@ -98,8 +147,24 @@ module Voom
98
147
  end
99
148
 
100
149
  get '/:_presenter_' do
101
- pass unless Presenters::App.registered?(params[:_presenter_])
102
- presenter = Presenters::App[params[:_presenter_]].call
150
+ fq_presenter = [params[:_presenter_], 'index'].join(':')
151
+ pass unless Presenters::App.registered?(params[:_presenter_]) || Presenters::App.registered?(fq_presenter)
152
+ presenter = (Presenters::App.registered?(fq_presenter) ? Presenters::App[fq_presenter] :
153
+ Presenters::App[params[:_presenter_]]).call
154
+ render_presenter(presenter)
155
+ end
156
+
157
+ get '/:_namespace1_/:_presenter_' do
158
+ fq_presenter = [params[:_namespace1_], params[:_presenter_]].join(':')
159
+ pass unless Presenters::App.registered?(fq_presenter)
160
+ presenter = Presenters::App[fq_presenter].call
161
+ render_presenter(presenter)
162
+ end
163
+
164
+ get '/:_namespace1_/:_namespace2_/:_presenter_' do
165
+ fq_presenter = [params[:_namespace1_], params[:_namespace2_], params[:_presenter_]].join(':')
166
+ pass unless Presenters::App.registered?(fq_presenter)
167
+ presenter = Presenters::App[fq_presenter].call
103
168
  render_presenter(presenter)
104
169
  end
105
170
 
@@ -107,21 +172,43 @@ module Voom
107
172
  post '/__post__/:presenter' do
108
173
  @pom = JSON.parse(request.body.read, object_class: OpenStruct)
109
174
  @grid_nesting = Integer(params[:grid_nesting] || 0)
175
+ @base_url = request.base_url
110
176
  layout = !(request.env['HTTP_X_NO_LAYOUT'] == 'true')
111
177
  erb :web, layout: layout
112
178
  end
113
179
 
114
180
  private
115
181
 
182
+ # analogous to Voom::Presenters::Api::App#render_presenter
116
183
  def render_presenter(presenter)
117
184
  @grid_nesting = Integer(params[:grid_nesting] || 0)
118
185
 
119
186
  begin
120
- @pom = presenter.expand(router: router, context: prepare_context)
187
+ before_render = Presenters::Settings.config.presenters.before_render
188
+ render_instead, ctx = before_render
189
+ .lazy
190
+ .map { |p| p.call(request) }
191
+ .detect(&:itself)
192
+
193
+ if Presenters::App.registered?(render_instead)
194
+ presenter = Presenters::App[render_instead].call
195
+ end
196
+
197
+ p = params.merge(ctx || {})
198
+ @pom = presenter.expand(router: router, context: prepare_context(p))
199
+ @base_url = request.base_url
121
200
  layout = !(request.env['HTTP_X_NO_LAYOUT'] == 'true')
122
- response.headers['X-Frame-Options'] = 'ALLOWALL' if ENV['ALLOWALL_FRAME_OPTIONS']
201
+ response.headers['X-Frame-Options'] = ENV['ALLOWALL_FRAME_OPTIONS'] || presenter.options.fetch(:allow_all_frame_options, false) ? 'ALLOWALL' : 'SAMEORIGIN'
123
202
  erb :web, layout: layout
124
- rescue Errors::Unprocessable => e
203
+ rescue StandardError => e
204
+ Presenters::Settings.config.presenters.error_logger.call(
205
+ @env['rack.errors'],
206
+ e,
207
+ params,
208
+ presenter.name
209
+ )
210
+ raise e
211
+ rescue Presenters::Errors::Unprocessable => e
125
212
  content_type :json
126
213
  status 422
127
214
  JSON.dump({error: e.message})
@@ -129,26 +216,26 @@ module Voom
129
216
  end
130
217
 
131
218
  def router
132
- settings.router_.new(base_url: "#{request.script_name}")
219
+ settings.router_.new(base_url: "#{request.base_url}")
133
220
  end
134
221
 
135
- def prepare_context
222
+ def prepare_context(base_params = params)
136
223
  prepare_context = Presenters::Settings.config.presenters.web_client.prepare_context.dup
137
224
  prepare_context.push(method(:scrub_context))
138
- context = params.dup
225
+ context = base_params.dup
139
226
  prepare_context.reduce(context) do |params, context_proc|
140
- context_proc.call(params, session, env)
227
+ context = context_proc.call(params, session, env)
141
228
  end
142
229
  context
143
230
  end
144
231
 
145
232
  def scrub_context(params, _session, _env)
146
- %i(splat captures _presenter_ grid_nesting).each do |key|
147
- params.delete(key)
233
+ %i(splat captures grid_nesting input_tag).each do |key|
234
+ params.delete(key) {params.delete(key.to_s)}
148
235
  end
149
236
  params
150
237
  end
151
238
  end
152
239
  end
153
240
  end
154
- end
241
+ end