wallaby 5.0.1 → 5.1.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 (350) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -3
  3. data/app/assets/images/wallaby/404.png +0 -0
  4. data/app/assets/images/wallaby/422.png +0 -0
  5. data/app/assets/images/wallaby/500.png +0 -0
  6. data/app/assets/javascripts/wallaby/application.js +1 -15
  7. data/app/assets/javascripts/wallaby/auto_select.js +77 -0
  8. data/app/assets/javascripts/wallaby/base.js +17 -0
  9. data/app/assets/javascripts/wallaby/setup.js.erb +60 -0
  10. data/app/assets/stylesheets/wallaby/application.scss +1 -51
  11. data/app/assets/stylesheets/wallaby/base/_layout.scss +257 -9
  12. data/app/assets/stylesheets/wallaby/base/_layout_desktop.scss +53 -0
  13. data/app/assets/stylesheets/wallaby/base/_mixins.scss +119 -0
  14. data/app/assets/stylesheets/wallaby/base/_override.scss +10 -0
  15. data/app/assets/stylesheets/wallaby/base/_vars.scss +72 -2
  16. data/app/assets/stylesheets/wallaby/base.scss +27 -0
  17. data/app/assets/stylesheets/wallaby/components/_auto_select.scss +119 -0
  18. data/app/assets/stylesheets/wallaby/components/_auto_select_desktop.scss +7 -0
  19. data/app/assets/stylesheets/wallaby/components/_color_square.scss +8 -0
  20. data/app/assets/stylesheets/wallaby/components/_filters.scss +14 -0
  21. data/app/assets/stylesheets/wallaby/components/_links.scss +25 -0
  22. data/app/assets/stylesheets/wallaby/components/_pagination.scss +35 -91
  23. data/app/assets/stylesheets/wallaby/components/_query.scss +101 -0
  24. data/app/assets/stylesheets/wallaby/components/_text.scss +6 -6
  25. data/app/assets/stylesheets/wallaby/pages/_error.scss +108 -0
  26. data/app/assets/stylesheets/wallaby/pages/_form.scss +40 -0
  27. data/app/assets/stylesheets/wallaby/pages/_index.scss +193 -0
  28. data/app/assets/stylesheets/wallaby/pages/_index_desktop.scss +22 -0
  29. data/app/assets/stylesheets/wallaby/pages/_show.scss +21 -0
  30. data/app/controllers/wallaby/abstract_resources_controller.rb +334 -0
  31. data/app/controllers/wallaby/application_controller.rb +45 -15
  32. data/app/controllers/wallaby/base_controller.rb +30 -0
  33. data/app/controllers/wallaby/resources_controller.rb +2 -131
  34. data/app/controllers/wallaby/secure_controller.rb +38 -24
  35. data/app/routes/wallaby/resources_router.rb +40 -43
  36. data/app/security/ability.rb +4 -28
  37. data/app/views/layouts/wallaby/application.html.erb +11 -6
  38. data/app/views/layouts/wallaby/error.html.erb +26 -4
  39. data/app/views/wallaby/error.html.erb +11 -0
  40. data/app/views/wallaby/error.json.jbuilder +8 -0
  41. data/app/views/wallaby/{shared → resources}/_flash_messages.html.erb +0 -0
  42. data/app/views/wallaby/resources/_footer.html.erb +1 -0
  43. data/app/views/wallaby/resources/_form.html.erb +2 -2
  44. data/app/views/wallaby/resources/_header.html.erb +38 -0
  45. data/app/views/wallaby/resources/_imodal.html.erb +13 -0
  46. data/app/views/wallaby/resources/_index_actions.html.erb +4 -1
  47. data/app/views/wallaby/resources/_index_filters.html.erb +23 -0
  48. data/app/views/wallaby/resources/_index_pagination.html.erb +63 -0
  49. data/app/views/wallaby/resources/_index_query.html.erb +23 -0
  50. data/app/views/wallaby/resources/_logo.html.erb +1 -0
  51. data/app/views/wallaby/resources/_navs.html.erb +9 -0
  52. data/app/views/wallaby/resources/_resource_actions.html.erb +3 -3
  53. data/app/views/wallaby/resources/{shared/_resource_nav.html.erb → _resource_navs.html.erb} +6 -6
  54. data/app/views/wallaby/resources/_title.html.erb +1 -0
  55. data/app/views/wallaby/resources/_user_menu.html.erb +5 -0
  56. data/app/views/wallaby/resources/bad_request.json.jbuilder +7 -0
  57. data/app/views/wallaby/resources/edit.html.erb +16 -12
  58. data/app/views/wallaby/resources/form/_belongs_to.html.erb +63 -12
  59. data/app/views/wallaby/resources/form/_bigint.html.erb +10 -1
  60. data/app/views/wallaby/resources/form/_bigserial.html.erb +18 -0
  61. data/app/views/wallaby/resources/form/_binary.html.erb +11 -2
  62. data/app/views/wallaby/resources/form/_bit.html.erb +10 -1
  63. data/app/views/wallaby/resources/form/_bit_varying.html.erb +10 -1
  64. data/app/views/wallaby/resources/form/_blob.html.erb +21 -0
  65. data/app/views/wallaby/resources/form/_boolean.html.erb +9 -0
  66. data/app/views/wallaby/resources/form/_box.html.erb +21 -0
  67. data/app/views/wallaby/resources/form/_cidr.html.erb +13 -1
  68. data/app/views/wallaby/resources/form/_circle.html.erb +21 -0
  69. data/app/views/wallaby/resources/form/_citext.html.erb +11 -2
  70. data/app/views/wallaby/resources/form/_color.html.erb +11 -2
  71. data/app/views/wallaby/resources/form/_date.html.erb +12 -3
  72. data/app/views/wallaby/resources/form/_daterange.html.erb +14 -5
  73. data/app/views/wallaby/resources/form/_datetime.html.erb +12 -3
  74. data/app/views/wallaby/resources/form/_decimal.html.erb +10 -1
  75. data/app/views/wallaby/resources/form/_dropdown.html.erb +18 -0
  76. data/app/views/wallaby/resources/form/_email.html.erb +9 -0
  77. data/app/views/wallaby/resources/form/_file.html.erb +21 -0
  78. data/app/views/wallaby/resources/form/_float.html.erb +10 -1
  79. data/app/views/wallaby/resources/form/_has_and_belongs_to_many.html.erb +53 -7
  80. data/app/views/wallaby/resources/form/_has_many.html.erb +52 -7
  81. data/app/views/wallaby/resources/form/_has_one.html.erb +10 -2
  82. data/app/views/wallaby/resources/form/_hstore.html.erb +12 -5
  83. data/app/views/wallaby/resources/form/_inet.html.erb +13 -1
  84. data/app/views/wallaby/resources/form/_int4range.html.erb +11 -2
  85. data/app/views/wallaby/resources/form/_int8range.html.erb +11 -2
  86. data/app/views/wallaby/resources/form/_integer.html.erb +10 -1
  87. data/app/views/wallaby/resources/form/_json.html.erb +13 -6
  88. data/app/views/wallaby/resources/form/_jsonb.html.erb +13 -6
  89. data/app/views/wallaby/resources/form/_line.html.erb +21 -0
  90. data/app/views/wallaby/resources/form/_longblob.html.erb +21 -0
  91. data/app/views/wallaby/resources/form/_longtext.html.erb +30 -0
  92. data/app/views/wallaby/resources/form/_lseg.html.erb +21 -0
  93. data/app/views/wallaby/resources/form/_ltree.html.erb +17 -1
  94. data/app/views/wallaby/resources/form/_macaddr.html.erb +13 -1
  95. data/app/views/wallaby/resources/form/_markdown.html.erb +29 -0
  96. data/app/views/wallaby/resources/form/_mediumblob.html.erb +21 -0
  97. data/app/views/wallaby/resources/form/_mediumtext.html.erb +30 -0
  98. data/app/views/wallaby/resources/form/_money.html.erb +10 -1
  99. data/app/views/wallaby/resources/form/_numrange.html.erb +11 -2
  100. data/app/views/wallaby/resources/form/_password.html.erb +14 -1
  101. data/app/views/wallaby/resources/form/_path.html.erb +17 -0
  102. data/app/views/wallaby/resources/form/_point.html.erb +11 -2
  103. data/app/views/wallaby/resources/form/_polygon.html.erb +17 -0
  104. data/app/views/wallaby/resources/form/_serial.html.erb +18 -0
  105. data/app/views/wallaby/resources/form/_sti.html.erb +18 -0
  106. data/app/views/wallaby/resources/form/_string.html.erb +14 -1
  107. data/app/views/wallaby/resources/form/_text.html.erb +11 -2
  108. data/app/views/wallaby/resources/form/_time.html.erb +12 -3
  109. data/app/views/wallaby/resources/form/_tinyblob.html.erb +21 -0
  110. data/app/views/wallaby/resources/form/_tinytext.html.erb +30 -0
  111. data/app/views/wallaby/resources/form/_tsrange.html.erb +14 -5
  112. data/app/views/wallaby/resources/form/_tstzrange.html.erb +14 -5
  113. data/app/views/wallaby/resources/form/_tsvector.html.erb +9 -0
  114. data/app/views/wallaby/resources/form/_unsigned_bigint.html.erb +18 -0
  115. data/app/views/wallaby/resources/form/_unsigned_decimal.html.erb +18 -0
  116. data/app/views/wallaby/resources/form/_unsigned_float.html.erb +18 -0
  117. data/app/views/wallaby/resources/form/_unsigned_integer.html.erb +18 -0
  118. data/app/views/wallaby/resources/form/_uuid.html.erb +10 -1
  119. data/app/views/wallaby/resources/form/_xml.html.erb +11 -5
  120. data/app/views/wallaby/resources/form.json.jbuilder +5 -0
  121. data/app/views/wallaby/{core → resources}/home.html.erb +1 -1
  122. data/app/views/wallaby/resources/index/_belongs_to.html.erb +5 -1
  123. data/app/views/wallaby/resources/index/_bigint.html.erb +4 -0
  124. data/app/views/wallaby/resources/index/_bigserial.html.erb +5 -0
  125. data/app/views/wallaby/resources/index/_binary.html.erb +5 -1
  126. data/app/views/wallaby/resources/index/_bit.html.erb +4 -0
  127. data/app/views/wallaby/resources/index/_bit_varying.html.erb +4 -0
  128. data/app/views/wallaby/resources/index/_blob.html.erb +5 -0
  129. data/app/views/wallaby/resources/index/_boolean.html.erb +5 -1
  130. data/app/views/wallaby/resources/index/_box.html.erb +16 -0
  131. data/app/views/wallaby/resources/index/_cidr.html.erb +5 -1
  132. data/app/views/wallaby/resources/index/_circle.html.erb +16 -0
  133. data/app/views/wallaby/resources/index/_citext.html.erb +5 -1
  134. data/app/views/wallaby/resources/index/_color.html.erb +6 -1
  135. data/app/views/wallaby/resources/index/_date.html.erb +4 -0
  136. data/app/views/wallaby/resources/index/_daterange.html.erb +5 -1
  137. data/app/views/wallaby/resources/index/_datetime.html.erb +5 -1
  138. data/app/views/wallaby/resources/index/_decimal.html.erb +4 -0
  139. data/app/views/wallaby/resources/index/_email.html.erb +4 -0
  140. data/app/views/wallaby/resources/index/_float.html.erb +4 -0
  141. data/app/views/wallaby/resources/index/_has_and_belongs_to_many.html.erb +6 -2
  142. data/app/views/wallaby/resources/index/_has_many.html.erb +6 -2
  143. data/app/views/wallaby/resources/index/_has_one.html.erb +5 -1
  144. data/app/views/wallaby/resources/index/_hstore.html.erb +6 -2
  145. data/app/views/wallaby/resources/index/_inet.html.erb +5 -1
  146. data/app/views/wallaby/resources/index/_int4range.html.erb +4 -0
  147. data/app/views/wallaby/resources/index/_int8range.html.erb +4 -0
  148. data/app/views/wallaby/resources/index/_integer.html.erb +4 -0
  149. data/app/views/wallaby/resources/index/_json.html.erb +5 -2
  150. data/app/views/wallaby/resources/index/_jsonb.html.erb +5 -2
  151. data/app/views/wallaby/resources/index/_line.html.erb +16 -0
  152. data/app/views/wallaby/resources/index/_longblob.html.erb +5 -0
  153. data/app/views/wallaby/resources/index/_longtext.html.erb +16 -0
  154. data/app/views/wallaby/resources/index/_lseg.html.erb +16 -0
  155. data/app/views/wallaby/resources/index/_ltree.html.erb +5 -1
  156. data/app/views/wallaby/resources/index/_macaddr.html.erb +4 -0
  157. data/app/views/wallaby/resources/index/_mediumblob.html.erb +5 -0
  158. data/app/views/wallaby/resources/index/_mediumtext.html.erb +16 -0
  159. data/app/views/wallaby/resources/index/_money.html.erb +4 -0
  160. data/app/views/wallaby/resources/index/_numrange.html.erb +4 -0
  161. data/app/views/wallaby/resources/index/_password.html.erb +9 -0
  162. data/app/views/wallaby/resources/index/_path.html.erb +16 -0
  163. data/app/views/wallaby/resources/index/_point.html.erb +4 -0
  164. data/app/views/wallaby/resources/index/_polygon.html.erb +16 -0
  165. data/app/views/wallaby/resources/index/_raw.html.erb +9 -0
  166. data/app/views/wallaby/resources/index/_serial.html.erb +5 -0
  167. data/app/views/wallaby/resources/index/_sti.html.erb +16 -0
  168. data/app/views/wallaby/resources/index/_string.html.erb +5 -1
  169. data/app/views/wallaby/resources/index/_text.html.erb +5 -1
  170. data/app/views/wallaby/resources/index/_time.html.erb +4 -0
  171. data/app/views/wallaby/resources/index/_tinyblob.html.erb +5 -0
  172. data/app/views/wallaby/resources/index/_tinytext.html.erb +16 -0
  173. data/app/views/wallaby/resources/index/_tsrange.html.erb +5 -1
  174. data/app/views/wallaby/resources/index/_tstzrange.html.erb +5 -1
  175. data/app/views/wallaby/resources/index/_tsvector.html.erb +5 -1
  176. data/app/views/wallaby/resources/index/_unsigned_bigint.html.erb +5 -0
  177. data/app/views/wallaby/resources/index/_unsigned_decimal.html.erb +5 -0
  178. data/app/views/wallaby/resources/index/_unsigned_float.html.erb +5 -0
  179. data/app/views/wallaby/resources/index/_unsigned_integer.html.erb +5 -0
  180. data/app/views/wallaby/resources/index/_uuid.html.erb +5 -1
  181. data/app/views/wallaby/resources/index/_xml.html.erb +5 -1
  182. data/app/views/wallaby/resources/index.csv.erb +26 -0
  183. data/app/views/wallaby/resources/index.html.erb +47 -59
  184. data/app/views/wallaby/resources/index.json.jbuilder +5 -0
  185. data/app/views/wallaby/resources/new.html.erb +12 -11
  186. data/app/views/wallaby/resources/show/_belongs_to.html.erb +5 -1
  187. data/app/views/wallaby/resources/show/_bigint.html.erb +4 -0
  188. data/app/views/wallaby/resources/show/_bigserial.html.erb +5 -0
  189. data/app/views/wallaby/resources/show/_binary.html.erb +5 -1
  190. data/app/views/wallaby/resources/show/_bit.html.erb +4 -0
  191. data/app/views/wallaby/resources/show/_bit_varying.html.erb +4 -0
  192. data/app/views/wallaby/resources/show/_blob.html.erb +5 -0
  193. data/app/views/wallaby/resources/show/_boolean.html.erb +5 -1
  194. data/app/views/wallaby/resources/show/_box.html.erb +9 -0
  195. data/app/views/wallaby/resources/show/_cidr.html.erb +5 -1
  196. data/app/views/wallaby/resources/show/_circle.html.erb +9 -0
  197. data/app/views/wallaby/resources/show/_citext.html.erb +4 -0
  198. data/app/views/wallaby/resources/show/_color.html.erb +6 -1
  199. data/app/views/wallaby/resources/show/_date.html.erb +4 -0
  200. data/app/views/wallaby/resources/show/_daterange.html.erb +4 -0
  201. data/app/views/wallaby/resources/show/_datetime.html.erb +4 -0
  202. data/app/views/wallaby/resources/show/_decimal.html.erb +4 -0
  203. data/app/views/wallaby/resources/show/_email.html.erb +4 -0
  204. data/app/views/wallaby/resources/show/_float.html.erb +4 -0
  205. data/app/views/wallaby/resources/show/_has_and_belongs_to_many.html.erb +6 -2
  206. data/app/views/wallaby/resources/show/_has_many.html.erb +6 -2
  207. data/app/views/wallaby/resources/show/_has_one.html.erb +5 -1
  208. data/app/views/wallaby/resources/show/_hstore.html.erb +4 -0
  209. data/app/views/wallaby/resources/show/_image.html.erb +9 -0
  210. data/app/views/wallaby/resources/show/_inet.html.erb +5 -1
  211. data/app/views/wallaby/resources/show/_int4range.html.erb +4 -0
  212. data/app/views/wallaby/resources/show/_int8range.html.erb +4 -0
  213. data/app/views/wallaby/resources/show/_integer.html.erb +4 -0
  214. data/app/views/wallaby/resources/show/_json.html.erb +4 -0
  215. data/app/views/wallaby/resources/show/_jsonb.html.erb +4 -0
  216. data/app/views/wallaby/resources/show/_line.html.erb +9 -0
  217. data/app/views/wallaby/resources/show/_longblob.html.erb +5 -0
  218. data/app/views/wallaby/resources/show/_longtext.html.erb +5 -0
  219. data/app/views/wallaby/resources/show/_lseg.html.erb +9 -0
  220. data/app/views/wallaby/resources/show/_ltree.html.erb +4 -0
  221. data/app/views/wallaby/resources/show/_macaddr.html.erb +4 -0
  222. data/app/views/wallaby/resources/show/_mediumblob.html.erb +5 -0
  223. data/app/views/wallaby/resources/show/_mediumtext.html.erb +5 -0
  224. data/app/views/wallaby/resources/show/_money.html.erb +4 -0
  225. data/app/views/wallaby/resources/show/_numrange.html.erb +4 -0
  226. data/app/views/wallaby/resources/show/_password.html.erb +9 -0
  227. data/app/views/wallaby/resources/show/_path.html.erb +9 -0
  228. data/app/views/wallaby/resources/show/_point.html.erb +4 -0
  229. data/app/views/wallaby/resources/show/_polygon.html.erb +9 -0
  230. data/app/views/wallaby/resources/show/_raw.html.erb +9 -0
  231. data/app/views/wallaby/resources/show/_serial.html.erb +5 -0
  232. data/app/views/wallaby/resources/show/_sti.html.erb +5 -0
  233. data/app/views/wallaby/resources/show/_string.html.erb +4 -0
  234. data/app/views/wallaby/resources/show/_text.html.erb +4 -0
  235. data/app/views/wallaby/resources/show/_time.html.erb +4 -0
  236. data/app/views/wallaby/resources/show/_tinyblob.html.erb +5 -0
  237. data/app/views/wallaby/resources/show/_tinytext.html.erb +5 -0
  238. data/app/views/wallaby/resources/show/_tsrange.html.erb +4 -0
  239. data/app/views/wallaby/resources/show/_tstzrange.html.erb +4 -0
  240. data/app/views/wallaby/resources/show/_tsvector.html.erb +4 -0
  241. data/app/views/wallaby/resources/show/_unsigned_bigint.html.erb +5 -0
  242. data/app/views/wallaby/resources/show/_unsigned_decimal.html.erb +5 -0
  243. data/app/views/wallaby/resources/show/_unsigned_float.html.erb +5 -0
  244. data/app/views/wallaby/resources/show/_unsigned_integer.html.erb +5 -0
  245. data/app/views/wallaby/resources/show/_uuid.html.erb +4 -0
  246. data/app/views/wallaby/resources/show/_xml.html.erb +4 -0
  247. data/app/views/wallaby/resources/show.html.erb +14 -24
  248. data/app/views/wallaby/resources/show.json.jbuilder +5 -0
  249. data/config/brakeman.ignore +26 -0
  250. data/config/locales/wallaby.en.yml +91 -0
  251. data/config/massa.yml +45 -0
  252. data/config/rails_best_practices.yml +42 -0
  253. data/config/routes.rb +29 -23
  254. data/lib/adaptors/wallaby/active_record/model_decorator/fields_builder/association_builder.rb +39 -0
  255. data/lib/adaptors/wallaby/active_record/model_decorator/fields_builder/polymorphic_builder.rb +44 -0
  256. data/lib/adaptors/wallaby/active_record/model_decorator/fields_builder/sti_builder.rb +42 -0
  257. data/lib/adaptors/wallaby/active_record/model_decorator/fields_builder.rb +41 -94
  258. data/lib/adaptors/wallaby/active_record/model_decorator/title_field_finder.rb +24 -14
  259. data/lib/adaptors/wallaby/active_record/model_decorator.rb +118 -64
  260. data/lib/adaptors/wallaby/active_record/model_finder.rb +44 -15
  261. data/lib/adaptors/wallaby/active_record/model_pagination_provider.rb +30 -0
  262. data/lib/adaptors/wallaby/active_record/model_service_provider/normalizer.rb +42 -0
  263. data/lib/adaptors/wallaby/active_record/model_service_provider/permitter.rb +64 -0
  264. data/lib/adaptors/wallaby/active_record/model_service_provider/querier/transformer.rb +70 -0
  265. data/lib/adaptors/wallaby/active_record/model_service_provider/querier.rb +102 -0
  266. data/lib/adaptors/wallaby/active_record/model_service_provider/validator.rb +29 -0
  267. data/lib/adaptors/wallaby/active_record/model_service_provider.rb +137 -0
  268. data/lib/adaptors/wallaby/active_record.rb +4 -1
  269. data/lib/decorators/wallaby/abstract_resource_decorator.rb +74 -0
  270. data/lib/decorators/wallaby/resource_decorator.rb +5 -76
  271. data/lib/errors/wallaby/model_not_found.rb +5 -1
  272. data/lib/errors/wallaby/not_found.rb +4 -0
  273. data/lib/errors/wallaby/resource_not_found.rb +5 -1
  274. data/lib/forms/wallaby/form_builder.rb +42 -19
  275. data/lib/helpers/wallaby/application_helper.rb +34 -24
  276. data/lib/helpers/wallaby/base_helper.rb +52 -0
  277. data/lib/helpers/wallaby/form_helper.rb +40 -16
  278. data/lib/helpers/wallaby/index_helper.rb +59 -0
  279. data/lib/helpers/wallaby/links_helper.rb +150 -81
  280. data/lib/helpers/wallaby/resources_helper.rb +41 -46
  281. data/lib/helpers/wallaby/secure_helper.rb +36 -19
  282. data/lib/helpers/wallaby/styling_helper.rb +53 -44
  283. data/lib/interfaces/wallaby/mode.rb +19 -12
  284. data/lib/interfaces/wallaby/model_decorator.rb +176 -50
  285. data/lib/interfaces/wallaby/model_finder.rb +7 -3
  286. data/lib/interfaces/wallaby/model_pagination_provider.rb +104 -0
  287. data/lib/interfaces/wallaby/model_service_provider.rb +71 -0
  288. data/lib/paginators/wallaby/abstract_resource_paginator.rb +23 -0
  289. data/lib/paginators/wallaby/resource_paginator.rb +6 -0
  290. data/lib/parsers/wallaby/parser.rb +32 -0
  291. data/lib/responders/wallaby/abstract_responder.rb +68 -0
  292. data/lib/responders/wallaby/resources_responder.rb +6 -0
  293. data/lib/servicers/wallaby/abstract_model_servicer.rb +48 -0
  294. data/lib/servicers/wallaby/model_servicer.rb +5 -0
  295. data/lib/services/wallaby/link_options_normalizer.rb +16 -0
  296. data/lib/services/wallaby/lookup_context_wrapper.rb +23 -30
  297. data/lib/services/wallaby/map/mode_mapper.rb +19 -0
  298. data/lib/services/wallaby/map/model_class_collector.rb +41 -0
  299. data/lib/services/wallaby/map/model_class_mapper.rb +24 -0
  300. data/lib/services/wallaby/map.rb +76 -39
  301. data/lib/services/wallaby/partial_renderer.rb +60 -0
  302. data/lib/services/wallaby/prefixes_builder.rb +54 -0
  303. data/lib/services/wallaby/sorting/hash_builder.rb +16 -0
  304. data/lib/services/wallaby/sorting/link_builder.rb +45 -0
  305. data/lib/services/wallaby/sorting/next_builder.rb +54 -0
  306. data/lib/services/wallaby/url_for.rb +36 -0
  307. data/lib/tree/wallaby/node.rb +17 -0
  308. data/lib/utils/wallaby/utils.rb +67 -22
  309. data/lib/wallaby/configuration/features.rb +12 -0
  310. data/lib/wallaby/configuration/metadata.rb +12 -0
  311. data/lib/wallaby/configuration/models.rb +27 -12
  312. data/lib/wallaby/configuration/pagination.rb +12 -0
  313. data/lib/wallaby/configuration/security.rb +55 -24
  314. data/lib/wallaby/configuration.rb +38 -19
  315. data/lib/wallaby/engine.rb +84 -39
  316. data/lib/wallaby/version.rb +1 -1
  317. data/lib/wallaby.rb +22 -3
  318. metadata +200 -55
  319. data/app/assets/javascripts/wallaby/form.js +0 -8
  320. data/app/assets/stylesheets/wallaby/base/_functions.scss +0 -0
  321. data/app/assets/stylesheets/wallaby/base/_normalize.scss +0 -0
  322. data/app/assets/stylesheets/wallaby/base/_reset.scss +0 -0
  323. data/app/assets/stylesheets/wallaby/components/_forms.scss +0 -53
  324. data/app/assets/stylesheets/wallaby/components/_nav.scss +0 -19
  325. data/app/assets/stylesheets/wallaby/components/_tables.scss +0 -78
  326. data/app/assets/stylesheets/wallaby/form.scss +0 -11
  327. data/app/controllers/wallaby/core_controller.rb +0 -28
  328. data/app/views/layouts/wallaby/_footer.html.erb +0 -2
  329. data/app/views/layouts/wallaby/_header.html.erb +0 -57
  330. data/app/views/layouts/wallaby/_navs.html.erb +0 -1
  331. data/app/views/wallaby/errors/access_denied.html.erb +0 -1
  332. data/app/views/wallaby/errors/not_authenticated.html.erb +0 -1
  333. data/app/views/wallaby/errors/not_found.html.erb +0 -6
  334. data/app/views/wallaby/errors/unprocessable_entity.erb +0 -1
  335. data/config/locales/en.yml +0 -29
  336. data/lib/adaptors/wallaby/active_record/model_operator/normalizer.rb +0 -44
  337. data/lib/adaptors/wallaby/active_record/model_operator/permitter.rb +0 -50
  338. data/lib/adaptors/wallaby/active_record/model_operator/querier.rb +0 -47
  339. data/lib/adaptors/wallaby/active_record/model_operator/validator.rb +0 -16
  340. data/lib/adaptors/wallaby/active_record/model_operator.rb +0 -82
  341. data/lib/errors/wallaby/deprecated.rb +0 -4
  342. data/lib/errors/wallaby/operation_not_found.rb +0 -4
  343. data/lib/handlers/wallaby/cached_compiled_erb.rb +0 -14
  344. data/lib/helpers/wallaby/core_helper.rb +0 -50
  345. data/lib/helpers/wallaby/paginatable_helper.rb +0 -9
  346. data/lib/helpers/wallaby/sorting_helper.rb +0 -43
  347. data/lib/interfaces/wallaby/model_operator.rb +0 -31
  348. data/lib/services/wallaby/decorator_finder.rb +0 -16
  349. data/lib/services/wallaby/model_servicer.rb +0 -38
  350. data/lib/services/wallaby/servicer_finder.rb +0 -5
@@ -1,58 +1,184 @@
1
- class Wallaby::ModelDecorator
2
- attr_reader :model_class
1
+ module Wallaby
2
+ # Model Decorator interface, designed to maintain metadata information for all
3
+ # the fields coming from data source (database/api)
4
+ # @see Wallaby::ResourceDecorator for more information on how to customise
5
+ # metadata information
6
+ class ModelDecorator
7
+ attr_reader :model_class
8
+ attr_writer \
9
+ :field_names, :index_field_names, :show_field_names, :form_field_names
3
10
 
4
- def initialize(model_class)
5
- @model_class = model_class
6
- end
11
+ def initialize(model_class)
12
+ @model_class = model_class
13
+ end
7
14
 
8
- [ '', 'index_', 'show_', 'form_' ].each do |prefix|
9
- class_eval <<-RUBY
10
- def #{ prefix }fields
11
- fail Wallaby::NotImplemented
12
- end
13
-
14
- def #{ prefix }fields=(#{ prefix }fields)
15
- @#{ prefix }fields = #{ prefix }fields.with_indifferent_access
16
- end
17
-
18
- def #{ prefix }field_names
19
- @#{ prefix }field_names ||= #{ prefix }fields.keys.tap do |names|
20
- names.delete primary_key
21
- names.unshift primary_key
22
- end
23
- end
24
-
25
- def #{ prefix }field_names=(#{ prefix }field_names)
26
- @#{ prefix }field_names = #{ prefix }field_names
27
- end
28
-
29
- def #{ prefix }metadata_of(field_name)
30
- #{ prefix }fields[field_name] || {}
31
- end
32
-
33
- def #{ prefix }label_of(field_name)
34
- #{ prefix }metadata_of(field_name)[:label]
35
- end
36
-
37
- def #{ prefix }type_of(field_name)
38
- #{ prefix }metadata_of(field_name)[:type]
39
- end
40
- RUBY
41
- end
15
+ # @return [Hash] metadata information for all fields that index/show/form
16
+ # will copy
17
+ def fields
18
+ raise NotImplemented
19
+ end
42
20
 
43
- def form_active_errors(resource)
44
- fail Wallaby::NotImplemented
45
- end
21
+ # @param fields [Hash] metadata information for all fields
22
+ def fields=(fields)
23
+ @fields = ::ActiveSupport::HashWithIndifferentAccess.new fields
24
+ end
46
25
 
47
- def primary_key
48
- fail Wallaby::NotImplemented
49
- end
26
+ # @return [Array] field names
27
+ def field_names
28
+ @field_names ||= reposition fields.keys, primary_key
29
+ end
50
30
 
51
- def guess_title(resource)
52
- fail Wallaby::NotImplemented
53
- end
31
+ # @return [Hash] metadata information for a given field
32
+ def metadata_of(field_name)
33
+ fields[field_name] || {}
34
+ end
35
+
36
+ # @return [String] label for a given field
37
+ def label_of(field_name)
38
+ metadata_of(field_name)[:label]
39
+ end
40
+
41
+ # @return [String, Symbol] type for a given field
42
+ def type_of(field_name)
43
+ validate_presence_of metadata_of(field_name)[:type]
44
+ end
45
+
46
+ # @return [Hash] metadata information for all fields that would be used on
47
+ # index page
48
+ def index_fields
49
+ raise NotImplemented
50
+ end
51
+
52
+ # @param fields [Hash] metadata information for all fields that would be
53
+ # used on index page
54
+ def index_fields=(fields)
55
+ @index_fields = ::ActiveSupport::HashWithIndifferentAccess.new fields
56
+ end
57
+
58
+ # @return [Array] field names of index page
59
+ def index_field_names
60
+ @index_field_names ||= reposition index_fields.keys, primary_key
61
+ end
62
+
63
+ # @return [Hash] index metadata information for a given field
64
+ def index_metadata_of(field_name)
65
+ index_fields[field_name] || {}
66
+ end
67
+
68
+ # @return [String] index label for a given field
69
+ def index_label_of(field_name)
70
+ index_metadata_of(field_name)[:label]
71
+ end
72
+
73
+ # @return [String, Symbol] index type for a given field
74
+ def index_type_of(field_name)
75
+ validate_presence_of index_metadata_of(field_name)[:type]
76
+ end
77
+
78
+ # @return [Hash] metadata information for all fields that would be used on
79
+ # show page
80
+ def show_fields
81
+ raise NotImplemented
82
+ end
83
+
84
+ # @param fields [Hash] metadata information for all fields that would be
85
+ # used on show page
86
+ def show_fields=(fields)
87
+ @show_fields = ::ActiveSupport::HashWithIndifferentAccess.new fields
88
+ end
89
+
90
+ # @return [Array] field names of show page
91
+ def show_field_names
92
+ @show_field_names ||= reposition show_fields.keys, primary_key
93
+ end
94
+
95
+ # @return [Hash] show metadata information for a given field
96
+ def show_metadata_of(field_name)
97
+ show_fields[field_name] || {}
98
+ end
99
+
100
+ # @return [String] show label for a given field
101
+ def show_label_of(field_name)
102
+ show_metadata_of(field_name)[:label]
103
+ end
104
+
105
+ # @return [String, Symbol] show type for a given field
106
+ def show_type_of(field_name)
107
+ validate_presence_of show_metadata_of(field_name)[:type]
108
+ end
109
+
110
+ # @return [Hash] metadata information for all fields that would be used on
111
+ # form page
112
+ def form_fields
113
+ raise NotImplemented
114
+ end
115
+
116
+ # @param fields [Hash] metadata information for all fields that would be
117
+ # used on form page
118
+ def form_fields=(fields)
119
+ @form_fields = ::ActiveSupport::HashWithIndifferentAccess.new fields
120
+ end
121
+
122
+ # @return [Array] field names of form page
123
+ def form_field_names
124
+ @form_field_names ||= reposition form_fields.keys, primary_key
125
+ end
126
+
127
+ # @return [Hash] form metadata information for a given field
128
+ def form_metadata_of(field_name)
129
+ form_fields[field_name] || {}
130
+ end
131
+
132
+ # @return [String] form label for a given field
133
+ def form_label_of(field_name)
134
+ form_metadata_of(field_name)[:label]
135
+ end
136
+
137
+ # @return [String, Symbol] form type for a given field
138
+ def form_type_of(field_name)
139
+ validate_presence_of form_metadata_of(field_name)[:type]
140
+ end
141
+
142
+ # @return [Hash] custom filters
143
+ def filters
144
+ @filters ||= ::ActiveSupport::HashWithIndifferentAccess.new
145
+ end
146
+
147
+ # @return [Hash] errors
148
+ def form_active_errors(_resource)
149
+ raise NotImplemented
150
+ end
151
+
152
+ # @return [String] primary key
153
+ def primary_key
154
+ raise NotImplemented
155
+ end
156
+
157
+ # @param _resource [Object] resource
158
+ # @return [String] title of given resource
159
+ def guess_title(_resource)
160
+ raise NotImplemented
161
+ end
162
+
163
+ # @return [String] resources name mapped from model class
164
+ def resources_name
165
+ Map.resources_name_map @model_class
166
+ end
167
+
168
+ protected
169
+
170
+ # @param field_names [Array] field names
171
+ # @param primary_key [String] primary key name
172
+ # @return [Array] a list of field names that primary key goes first
173
+ def reposition(field_names, primary_key)
174
+ field_names.unshift(primary_key).uniq
175
+ end
54
176
 
55
- def resources_name
56
- Wallaby::Utils.to_resources_name @model_class
177
+ # Ensure type is present
178
+ # @param type [String, Symbol, nil] type of a field
179
+ # @return [String, Symbol] type name
180
+ def validate_presence_of(type)
181
+ type || raise(::ArgumentError, 'Type is required.')
182
+ end
57
183
  end
58
184
  end
@@ -1,5 +1,9 @@
1
- class Wallaby::ModelFinder
2
- def all
3
- fail Wallaby::NotImplemented
1
+ module Wallaby
2
+ # Model finder interface
3
+ class ModelFinder
4
+ # Need to implement this method to get all the available model for a mode
5
+ def all
6
+ raise NotImplemented
7
+ end
4
8
  end
5
9
  end
@@ -0,0 +1,104 @@
1
+ module Wallaby
2
+ # Model pagination provider interface
3
+ class ModelPaginationProvider
4
+ # @param collection
5
+ # @param params [ActionController::Parameters]
6
+ # @param options [Hash] options
7
+ # @param model_decorator [Wallaby::ModelDecorator, nil]
8
+ def initialize(collection, params, options: {}, model_decorator: nil)
9
+ @collection = collection
10
+ @params = params
11
+ @options = options
12
+ @model_decorator = model_decorator
13
+ end
14
+
15
+ # If a collection has pagination feature
16
+ def paginatable?
17
+ raise NotImplemented
18
+ end
19
+
20
+ # Check and see if it's the first page
21
+ # @return boolean
22
+ def first_page?
23
+ page_number > first_page_number
24
+ end
25
+
26
+ # Check and see if it's the previous page
27
+ # @return boolean
28
+ def prev_page?
29
+ page_number > first_page_number
30
+ end
31
+
32
+ # Check and see if it's the last page
33
+ # @return boolean
34
+ def last_page?
35
+ page_number < last_page_number
36
+ end
37
+
38
+ # Check and see if it's the next page
39
+ # @return boolean
40
+ def next_page?
41
+ page_number < last_page_number
42
+ end
43
+
44
+ # Find out the offset `from`
45
+ # @return [Integer]
46
+ def from
47
+ (page_number - 1) * page_size + 1
48
+ end
49
+
50
+ # Find out the offset `to`
51
+ # @return [Integer]
52
+ def to
53
+ [page_number * page_size, total].min
54
+ end
55
+
56
+ # Find out the total count of current query
57
+ # @return [Integer]
58
+ def total
59
+ raise NotImplemented
60
+ end
61
+
62
+ # Find out the current page size
63
+ # @return [Integer]
64
+ def page_size
65
+ raise NotImplemented
66
+ end
67
+
68
+ # Find out the current page number
69
+ # @return [Integer]
70
+ def page_number
71
+ raise NotImplemented
72
+ end
73
+
74
+ # Page number of first page
75
+ # @return [Integer]
76
+ def first_page_number
77
+ 1
78
+ end
79
+
80
+ # Page number of last page
81
+ # @return [Integer]
82
+ def last_page_number
83
+ number_of_pages
84
+ end
85
+
86
+ # Page number of previous page
87
+ # @return [Integer]
88
+ def prev_page_number
89
+ [page_number - 1, first_page_number].max
90
+ end
91
+
92
+ # Page number of next page
93
+ # @return [Integer]
94
+ def next_page_number
95
+ [page_number + 1, last_page_number].min
96
+ end
97
+
98
+ # Total number of pages
99
+ # @return [Integer]
100
+ def number_of_pages
101
+ (total / page_size.to_f).ceil
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,71 @@
1
+ module Wallaby
2
+ # Model service provider interface
3
+ class ModelServiceProvider
4
+ # @param model_class [Class] model class
5
+ # @param model_decorator [Wallaby::ModelDecorator, nil] model decorator
6
+ def initialize(model_class, model_decorator = nil)
7
+ raise ::ArgumentError, 'model class required' unless model_class
8
+ @model_class = model_class
9
+ @model_decorator = model_decorator || Map.model_decorator_map(model_class)
10
+ end
11
+
12
+ # To whitelist params for a model class
13
+ # @param _params [ActionController::Parameters]
14
+ def permit(_params)
15
+ raise NotImplemented
16
+ end
17
+
18
+ # Fetch collection by params
19
+ # @param _params [ActionController::Parameters]
20
+ # @param _authorizer
21
+ def collection(_params, _authorizer)
22
+ raise NotImplemented
23
+ end
24
+
25
+ # Paginate the records
26
+ # @param _query
27
+ # @param _params [ActionController::Parameters]
28
+ def paginate(_query, _params)
29
+ raise NotImplemented
30
+ end
31
+
32
+ # Initialize the model class using params
33
+ # @param _params [ActionController::Parameters]
34
+ # @param _authorizer
35
+ def new(_params, _authorizer)
36
+ raise NotImplemented
37
+ end
38
+
39
+ # Find a record using id
40
+ # @param _id [Object]
41
+ # @param _params [ActionController::Parameters]
42
+ # @param _authorizer
43
+ def find(_id, _params, _authorizer)
44
+ raise NotImplemented
45
+ end
46
+
47
+ # Save the newly initialized resource
48
+ # @param _resource [Object]
49
+ # @param _params [ActionController::Parameters]
50
+ # @param _authorizer
51
+ def create(_resource, _params, _authorizer)
52
+ raise NotImplemented
53
+ end
54
+
55
+ # Update the persisted resource
56
+ # @param _resource [Object]
57
+ # @param _params [ActionController::Parameters]
58
+ # @param _authorizer
59
+ def update(_resource, _params, _authorizer)
60
+ raise NotImplemented
61
+ end
62
+
63
+ # Destroy the given resource
64
+ # @param _resource [Object]
65
+ # @param _params [ActionController::Parameters]
66
+ # @param _authorizer
67
+ def destroy(_resource, _params, _authorizer)
68
+ raise NotImplemented
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,23 @@
1
+ module Wallaby
2
+ # Model paginator
3
+ class AbstractResourcePaginator
4
+ def self.model_class
5
+ return unless self < ::Wallaby::ResourcePaginator
6
+ Map.model_class_map name.gsub('Paginator', EMPTY_STRING)
7
+ end
8
+
9
+ # Delegate methods to pagination provider
10
+ instance_methods =
11
+ ModelPaginationProvider.instance_methods - ::Object.instance_methods
12
+ delegate(*instance_methods, to: :@provider)
13
+
14
+ def initialize(model_class, collection, params)
15
+ @model_class = model_class || self.class.model_class
16
+ raise ArgumentError, 'model class required' unless @model_class
17
+ @collection = collection
18
+ @params = params
19
+ @provider =
20
+ Map.pagination_provider_map(@model_class).new(@collection, @params)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ module Wallaby
2
+ # Resource paginator
3
+ # @see Wallaby::AbstractResourcePaginator
4
+ class ResourcePaginator < AbstractResourcePaginator
5
+ end
6
+ end
@@ -0,0 +1,32 @@
1
+ module Wallaby
2
+ # a parser to handle colon query
3
+ class Parser < Parslet::Parser
4
+ root(:statement)
5
+ rule(:statement) { expression >> (space >> expression).repeat }
6
+ rule(:expression) { colon_query | general_keyword }
7
+ rule(:colon_query) do
8
+ name.as(:left) >> operator.as(:op) >> keywords.as(:right)
9
+ end
10
+ rule(:name) { (space.absent? >> colon.absent? >> any).repeat(1) }
11
+ rule(:operator) { colon >> match('[^\s\'\"\:\,0-9a-zA-Z]').repeat(0, 3) }
12
+ rule(:keywords) { general_keyword >> (comma >> general_keyword).repeat }
13
+ rule(:general_keyword) { quoted_keyword | keyword }
14
+
15
+ # basic elements
16
+ rule(:quoted_keyword) do
17
+ open_quote >>
18
+ (close_quote.absent? >> any).repeat.as(:keyword) >>
19
+ close_quote
20
+ end
21
+ rule(:keyword) { ((space | comma).absent? >> any).repeat.as(:keyword) }
22
+
23
+ # atomic entities
24
+ rule(:comma) { str(',') }
25
+ rule(:space) { match('\s').repeat(1) }
26
+ rule(:colon) { str(':') }
27
+
28
+ # open-close elements
29
+ rule(:open_quote) { match('[\'\"]').capture(:quote) }
30
+ rule(:close_quote) { dynamic { |_src, ctx| str(ctx.captures[:quote]) } }
31
+ end
32
+ end
@@ -0,0 +1,68 @@
1
+ module Wallaby
2
+ # abstract responder for later usage
3
+ class AbstractResponder < ActionController::Responder
4
+ include ::Responders::FlashResponder
5
+
6
+ delegate :params, :headers, to: :request
7
+
8
+ def to_html
9
+ set_flash_message
10
+ if post? then create_action
11
+ elsif patch? || put? then update_action
12
+ elsif delete? then destroy_action
13
+ else default_render
14
+ end
15
+ end
16
+
17
+ def to_csv
18
+ set_layout_to_none
19
+ headers['Content-Disposition'] = "attachment; filename=\"#{file_name}\""
20
+ default_render
21
+ end
22
+
23
+ def to_json
24
+ set_layout_to_none
25
+ return default_render unless post? || patch? || put? || delete?
26
+ if has_errors? then \
27
+ render :bad_request, options.merge(status: :bad_request)
28
+ else render :form, options
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def create_action
35
+ if has_errors?
36
+ render :new, options
37
+ else
38
+ redirect_to resource_location
39
+ end
40
+ end
41
+
42
+ def update_action
43
+ if has_errors?
44
+ render :edit, options
45
+ else
46
+ redirect_to resource_location
47
+ end
48
+ end
49
+
50
+ def destroy_action
51
+ redirect_to resource_location
52
+ end
53
+
54
+ def file_name
55
+ timestamp = Time.zone.now.to_s(:number)
56
+ "#{params[:resources]}-exported-#{timestamp}.#{format}"
57
+ end
58
+
59
+ def set_layout_to_none
60
+ options[:layout] = false
61
+ end
62
+
63
+ def set_flash_message
64
+ # @see FlashResponder
65
+ set_flash_message! if set_flash_message?
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,6 @@
1
+ module Wallaby
2
+ # Resources responder for later usage
3
+ # @overwritable
4
+ class ResourcesResponder < AbstractResponder
5
+ end
6
+ end
@@ -0,0 +1,48 @@
1
+ module Wallaby
2
+ # Model servicer
3
+ class AbstractModelServicer
4
+ def self.model_class
5
+ return unless self < ::Wallaby::ModelServicer
6
+ Map.model_class_map name.gsub('Servicer', EMPTY_STRING)
7
+ end
8
+
9
+ def initialize(model_class = nil, authorizer = nil)
10
+ @model_class = model_class || self.class.model_class
11
+ raise ArgumentError, 'model class required' unless @model_class
12
+ @authorizer = authorizer
13
+ @provider = Map.service_provider_map @model_class
14
+ end
15
+
16
+ def permit(params)
17
+ @provider.permit params
18
+ end
19
+
20
+ def collection(params)
21
+ @provider.collection params, @authorizer
22
+ end
23
+
24
+ def paginate(query, params)
25
+ @provider.paginate query, params
26
+ end
27
+
28
+ def new(params)
29
+ @provider.new params, @authorizer
30
+ end
31
+
32
+ def find(id, params)
33
+ @provider.find id, params, @authorizer
34
+ end
35
+
36
+ def create(resource, params)
37
+ @provider.create resource, params, @authorizer
38
+ end
39
+
40
+ def update(resource, params)
41
+ @provider.update resource, params, @authorizer
42
+ end
43
+
44
+ def destroy(resource, params)
45
+ @provider.destroy resource, params, @authorizer
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ module Wallaby
2
+ # Model servicer
3
+ class ModelServicer < AbstractModelServicer
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ module Wallaby
2
+ # Link renderer
3
+ class LinkOptionsNormalizer
4
+ class << self
5
+ def normalize(html_options, block, defaults)
6
+ block ||= defaults[:block]
7
+ html_options[:title] ||= defaults[:block].call
8
+ # allow empty class to be set
9
+ if !html_options.key?(:class) && defaults[:class]
10
+ html_options[:class] = defaults[:class]
11
+ end
12
+ [html_options, block]
13
+ end
14
+ end
15
+ end
16
+ end