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,83 +1,152 @@
1
- module Wallaby::LinksHelper
2
- def index_path(model_class = nil, extra_params = nil)
3
- model_class ||= current_model_class
4
- extra_params ||= {}
5
- wallaby_engine.resources_path to_resources_name(model_class), extra_params
6
- end
7
-
8
- def new_path(model_class = nil)
9
- model_class ||= current_model_class
10
- wallaby_engine.new_resource_path to_resources_name model_class
11
- end
12
-
13
- def show_path(resource)
14
- decorated = decorate resource
15
- wallaby_engine.resource_path decorated.resources_name, decorated.primary_key_value
16
- end
17
-
18
- def edit_path(resource)
19
- decorated = decorate resource
20
- wallaby_engine.edit_resource_path decorated.resources_name, decorated.primary_key_value
21
- end
22
-
23
- def index_link(model_class = nil, html_options = {}, &block)
24
- model_class ||= current_model_class
25
- return if cannot? :index, model_class
26
- block ||= -> { to_model_label model_class }
27
-
28
- link_to index_path(model_class, html_options.delete(:extra_params)), html_options, &block
29
- end
30
-
31
- def new_link(model_class = nil, html_options = {}, &block)
32
- model_class ||= current_model_class
33
- return if cannot? :new, model_class
34
-
35
- block ||= -> { "#{ ct 'link.new' } #{ to_model_label model_class }" }
36
- html_options[:class] = 'text-success' unless html_options.has_key? :class
37
-
38
- prepend_if html_options
39
- link_to new_path(model_class), html_options, &block
40
- end
41
-
42
- def show_link(resource, html_options = {}, &block)
43
- return if cannot? :show, extract(resource)
44
-
45
- # NOTE: to_s is a must
46
- # if a block is returning integer (e.g. `{ 1 }`)
47
- # `link_to` will render blank text note inside hyper link
48
- block ||= -> { decorate(resource).to_label.to_s }
49
-
50
- link_to show_path(resource), html_options, &block
51
- end
52
-
53
- def edit_link(resource, html_options = {}, &block)
54
- return if cannot? :edit, extract(resource)
55
-
56
- block ||= -> { "#{ ct 'link.edit' } #{ decorate(resource).to_label }" }
57
- html_options[:class] = 'text-warning' unless html_options.has_key? :class
58
-
59
- link_to edit_path(resource), html_options, &block
60
- end
61
-
62
- def delete_link(resource, html_options = {}, &block)
63
- return if cannot? :destroy, extract(resource)
64
-
65
- block ||= -> { ct 'link.delete' }
66
- html_options[:class] = 'text-danger' unless html_options.has_key? :class
67
- html_options[:method] ||= :delete
68
- html_options[:data] ||= {}
69
- html_options[:data][:confirm] ||= ct('link.confirm.delete')
70
-
71
- link_to show_path(resource), html_options, &block
72
- end
73
-
74
- def cancel_link(html_options = {}, &block)
75
- block ||= -> { ct 'link.cancel' }
76
- link_to :back, html_options, &block
77
- end
78
-
79
- def prepend_if(html_options = {})
80
- prepend = html_options.delete :prepend
81
- concat "#{ prepend } " if prepend.present?
1
+ module Wallaby
2
+ # Links helper
3
+ module LinksHelper
4
+ # Permit the params used by Wallaby
5
+ def index_params
6
+ params.except(:resources, :utf8).permit(:filter, :page, :per, :q, :sort)
7
+ end
8
+
9
+ # Return link to index page by a given model class
10
+ # If user's not authorized, nil will be returned
11
+ # @param model_class [Class] model class
12
+ # @param url_params [ActionController::Parameters, Hash]
13
+ # @param html_options [Hash] (see ActionView::Helpers::UrlHelper#link_to)
14
+ # @return [String, nil] anchor element
15
+ def index_link(model_class, url_params: {}, html_options: {}, &block)
16
+ return if cannot? :index, model_class
17
+ html_options, block = LinkOptionsNormalizer.normalize(
18
+ html_options, block,
19
+ block: -> { to_model_label model_class }
20
+ )
21
+
22
+ path = index_path model_class, url_params: url_params
23
+ link_to path, html_options, &block
24
+ end
25
+
26
+ # Return link to create page by a given model class
27
+ # If user's not authorized, nil will be returned
28
+ # @param model_class [Class] model class
29
+ # @param options [Hash]
30
+ # @param html_options [Hash] (see ActionView::Helpers::UrlHelper#link_to)
31
+ # @return [String, nil] anchor element
32
+ def new_link(model_class, html_options: {}, &block)
33
+ return if cannot? :new, model_class
34
+ html_options, block = LinkOptionsNormalizer.normalize(
35
+ html_options, block,
36
+ class: 'resource__create',
37
+ block: -> { t 'links.new', model: to_model_label(model_class) }
38
+ )
39
+
40
+ link_to new_path(model_class), html_options, &block
41
+ end
42
+
43
+ # Return link to show page by a given model class
44
+ # If user's not authorized, resource label will be returned
45
+ # @param resource [Object, Wallaby::ResourceDecorator] model class
46
+ # @param options [Hash]
47
+ # @param html_options [Hash] (see ActionView::Helpers::UrlHelper#link_to)
48
+ # @return [String] anchor element / text
49
+ def show_link(resource, options: {}, html_options: {}, &block)
50
+ # NOTE: to_s is a must
51
+ # if a block is returning integer (e.g. `{ 1 }`)
52
+ # `link_to` will render blank text note inside hyper link
53
+ html_options, block = LinkOptionsNormalizer.normalize(
54
+ html_options, block,
55
+ block: -> { decorate(resource).to_label.to_s }
56
+ )
57
+
58
+ default = options[:readonly] && block.call || nil
59
+ return default if cannot? :show, extract(resource)
60
+ link_to show_path(resource), html_options, &block
61
+ end
62
+
63
+ # Return link to edit page by a given model class
64
+ # If user's not authorized, resource label will be returned
65
+ # @param resource [Object, Wallaby::ResourceDecorator] model class
66
+ # @param options [Hash]
67
+ # @param html_options [Hash] (see ActionView::Helpers::UrlHelper#link_to)
68
+ # @return [String] anchor element / text
69
+ def edit_link(resource, options: {}, html_options: {}, &block)
70
+ default = options[:readonly] && decorate(resource).to_label || nil
71
+ return default if cannot? :edit, extract(resource)
72
+
73
+ html_options, block = LinkOptionsNormalizer.normalize(
74
+ html_options, block,
75
+ class: 'resource__update',
76
+ block: -> { "#{t 'links.edit'} #{decorate(resource).to_label}" }
77
+ )
78
+
79
+ link_to edit_path(resource), html_options, &block
80
+ end
81
+
82
+ # Return link to delete action by a given model class
83
+ # If user's not authorized, nil will be returned
84
+ # @param resource [Object, Wallaby::ResourceDecorator] model class
85
+ # @param options [Hash]
86
+ # @param html_options [Hash] (see ActionView::Helpers::UrlHelper#link_to)
87
+ # @return [String, nil] anchor element
88
+ def delete_link(resource, html_options: {}, &block)
89
+ return if cannot? :destroy, extract(resource)
90
+
91
+ html_options, block = LinkOptionsNormalizer.normalize(
92
+ html_options, block,
93
+ class: 'resource__destroy',
94
+ block: -> { t 'links.delete' }
95
+ )
96
+
97
+ html_options[:method] ||= :delete
98
+ html_options[:data] ||= {}
99
+ html_options[:data][:confirm] ||= t 'links.confirm.delete'
100
+
101
+ link_to show_path(resource), html_options, &block
102
+ end
103
+
104
+ # Return link to cancel an action
105
+ # @param html_options [Hash] (see ActionView::Helpers::UrlHelper#link_to)
106
+ # @return [String] HTML anchor element
107
+ def cancel_link(html_options = {}, &block)
108
+ block ||= -> { t 'links.cancel' }
109
+ link_to :back, html_options, &block
110
+ end
111
+
112
+ # Url for index page
113
+ # @param model_class [Class]
114
+ # @param url_params [ActionController::Parameters, Hash]
115
+ # @return [String]
116
+ def index_path(model_class, url_params: {})
117
+ if url_params.is_a?(::ActionController::Parameters) \
118
+ && !url_params.permitted?
119
+ url_params = {}
120
+ end
121
+ wallaby_engine.resources_path \
122
+ to_resources_name(model_class), url_params.to_h
123
+ end
124
+
125
+ # Url for new resource form page
126
+ # @param model_class [Class]
127
+ # @return [String]
128
+ def new_path(model_class)
129
+ wallaby_engine.new_resource_path to_resources_name(model_class)
130
+ end
131
+
132
+ # Url for show page of given resource
133
+ # @param resource [Object]
134
+ # @return [String]
135
+ def show_path(resource)
136
+ decorated = decorate resource
137
+ return unless decorated.primary_key_value
138
+ wallaby_engine.resource_path \
139
+ decorated.resources_name, decorated.primary_key_value
140
+ end
141
+
142
+ # Url for edit form page of given resource
143
+ # @param resource [Object]
144
+ # @return [String]
145
+ def edit_path(resource)
146
+ decorated = decorate resource
147
+ return unless decorated.primary_key_value
148
+ wallaby_engine.edit_resource_path \
149
+ decorated.resources_name, decorated.primary_key_value
150
+ end
82
151
  end
83
152
  end
@@ -1,55 +1,50 @@
1
- module Wallaby::ResourcesHelper
2
- include Wallaby::FormHelper
3
- include Wallaby::SortingHelper
4
- include Wallaby::PaginatableHelper
5
-
6
- def decorate(resource)
7
- if resource.respond_to? :map # collection
8
- decorator = Wallaby::DecoratorFinder.find_resource resource.first.class
9
- resource.map do |item|
10
- decorator.decorate item
11
- end
12
- else
13
- decorator = Wallaby::DecoratorFinder.find_resource resource.class
14
- decorator.decorate resource
1
+ module Wallaby
2
+ # Resources helper
3
+ module ResourcesHelper
4
+ include FormHelper
5
+ include IndexHelper
6
+
7
+ def model_decorator(model_class)
8
+ Map.model_decorator_map model_class
15
9
  end
16
- end
17
10
 
18
- def extract(resource)
19
- if resource.is_a? Wallaby::ResourceDecorator
20
- resource.resource
21
- else
22
- resource
11
+ # Shortcut for `Wallaby.configuration.metadata
12
+ def default_metadata
13
+ Wallaby.configuration.metadata
23
14
  end
24
- end
25
-
26
- def model_decorator(model_class)
27
- Wallaby::DecoratorFinder.find_model model_class
28
- end
29
-
30
- def model_servicer(model_decorator)
31
- model_class = model_decorator.model_class
32
- Wallaby::ServicerFinder.find(model_class).new model_class, model_decorator
33
- end
34
-
35
- def type_partial_render(options = {}, locals = {}, metadata_method = :show_metadata_of, &block)
36
- decorated = locals[:object]
37
- field_name = locals[:field_name].to_s
38
15
 
39
- fail ArgumentError unless field_name.present? && decorated.is_a?(Wallaby::ResourceDecorator)
40
-
41
- locals[:metadata] = decorated.send metadata_method, field_name
42
- locals[:value] = decorated.public_send field_name
16
+ # Wrap resource into a decorator
17
+ # @param resource [Object, Enumerable]
18
+ # @return
19
+ # [Wallaby::ResourceDecorator, Enumerable<Wallaby::ResourceDecorator]
20
+ def decorate(resource)
21
+ return resource if resource.is_a? ResourceDecorator
22
+ return resource.map { |item| decorate item } if resource.respond_to? :map
23
+ decorator = Map.resource_decorator_map resource.class
24
+ decorator ? decorator.new(resource) : resource
25
+ end
43
26
 
44
- render(options, locals, &block) or render('string', locals, &block)
45
- end
27
+ # Get the origin resource object
28
+ # @param resource [Object, Wallaby::ResourceDecorator]
29
+ # @return [Object]
30
+ def extract(resource)
31
+ return resource.resource if resource.is_a? ResourceDecorator
32
+ resource
33
+ end
46
34
 
47
- def index_type_partial_render(options = {}, locals = {}, &block)
48
- type_partial_render options, locals, :index_metadata_of
49
- end
35
+ # Render partial for index/show
36
+ def type_partial_render(options = {}, locals = {}, &block)
37
+ PartialRenderer.render self, options, locals, params[:action], &block
38
+ end
50
39
 
51
- def show_title(decorated)
52
- fail ArgumentError unless decorated.is_a? Wallaby::ResourceDecorator
53
- [ to_model_label(decorated.model_class), decorated.to_label ].compact.join ': '
40
+ # Title for show page of given resource
41
+ # @param decorated [Wallaby::ResourceDecorator]
42
+ # @return [String]
43
+ def show_title(decorated)
44
+ raise ::ArgumentError unless decorated.is_a? ResourceDecorator
45
+ [
46
+ to_model_label(decorated.model_class), decorated.to_label
47
+ ].compact.join ': '
48
+ end
54
49
  end
55
50
  end
@@ -1,25 +1,42 @@
1
- module Wallaby::SecureHelper
2
- def user_portrait(user = current_user)
3
- if user.respond_to? :email
4
- image_source = "http#{ request.ssl? ? 's' : '' }://www.gravatar.com/avatar/#{ Digest::MD5.hexdigest user.email.downcase }"
5
- image_tag image_source, class: 'hidden-xs user-portrait'
6
- else
7
- content_tag :i, nil, class: 'glyphicon glyphicon-user user-portrait'
1
+ module Wallaby
2
+ # Secure helper
3
+ module SecureHelper
4
+ # Image portrait for given user
5
+ # @param user [Object]
6
+ # @return [String] IMG or I element
7
+ def user_portrait(user = current_user)
8
+ if user.respond_to? :email
9
+ https = "http#{request.ssl? ? 's' : EMPTY_STRING}"
10
+ email_md5 = Digest::MD5.hexdigest user.email.downcase
11
+ image_source = "#{https}://www.gravatar.com/avatar/#{email_md5}"
12
+ image_tag image_source, class: 'hidden-xs user-portrait'
13
+ else
14
+ content_tag :i, nil, class: 'fa fa-user user-portrait'
15
+ end
8
16
  end
9
- end
10
17
 
11
- def logout_path(user = current_user, app = main_app)
12
- path = if defined? Devise
13
- scope = Devise::Mapping.find_scope! user
14
- "destroy_#{ scope }_session_path"
15
- else
16
- 'logout_path'
18
+ # Logout path for given user
19
+ # @param user [Object]
20
+ # @param app [Object]
21
+ # @return [String] HTML anchor element
22
+ def logout_path(user = current_user, app = main_app)
23
+ # TODO: use authenticater
24
+ path =
25
+ if defined? ::Devise
26
+ scope = ::Devise::Mapping.find_scope! user
27
+ "destroy_#{scope}_session_path"
28
+ else
29
+ 'logout_path'
30
+ end
31
+ app.public_send path if app.respond_to? path
17
32
  end
18
- app.public_send path if app.respond_to? path
19
- end
20
33
 
21
- def logout_method
22
- method = Array(Devise.sign_out_via).first if defined? Devise
23
- method || :delete
34
+ # Logout method
35
+ # @return [String, Symbol]
36
+ def logout_method
37
+ # TODO: use authenticater
38
+ method = Array(Devise.sign_out_via).first if defined? Devise
39
+ method || :delete
40
+ end
24
41
  end
25
42
  end
@@ -1,57 +1,66 @@
1
- module Wallaby::StylingHelper
2
- def icon(icon_suffix, html_options = {}, &block)
3
- html_options[:class] = Array html_options[:class]
4
- html_options[:class] << "glyphicon glyphicon-#{ icon_suffix }"
1
+ module Wallaby
2
+ # Styling helper
3
+ module StylingHelper
4
+ # Shortcut to build up the html options as keyword arguments
5
+ # @param string_or_array [String, Array]
6
+ # @return [Hash]
7
+ def html_classes(string_or_array)
8
+ { html_options: { class: string_or_array } }
9
+ end
5
10
 
6
- content_tag :i, nil, html_options, &block
7
- end
11
+ # Shortcut for fontawesome icons
12
+ # @param icon_suffix [String]
13
+ # @param html_options [Hash]
14
+ # @return [String] HTML I element
15
+ def fa_icon(icon_suffix, html_options = {}, &block)
16
+ html_options[:class] = Array html_options[:class]
17
+ html_options[:class] << "fa fa-#{icon_suffix}"
8
18
 
9
- def itooltip(title, icon_suffix = 'info-sign', html_options = {})
10
- html_options[:title] = title
11
- (html_options[:data] ||= {}).merge! toggle: "tooltip", placement: "top"
19
+ content_tag :i, nil, html_options, &block
20
+ end
12
21
 
13
- icon icon_suffix, html_options
14
- end
22
+ # Build up tooltip
23
+ # @param title [String]
24
+ # @param icon_suffix [String]
25
+ # @param html_options [Hash]
26
+ # @return [String] tooltip HTML
27
+ def itooltip(title, icon_suffix = 'info-circle', html_options = {})
28
+ html_options[:title] = title
29
+ (html_options[:data] ||= {}).merge! toggle: 'tooltip', placement: 'top'
15
30
 
16
- def ilink_to(options = nil, html_options = {})
17
- icon_suffix = html_options.delete(:icon) || 'info-sign'
18
- link_to options, html_options do
19
- icon icon_suffix
31
+ fa_icon icon_suffix, html_options
20
32
  end
21
- end
22
33
 
23
- def imodal(title, body, html_options = {})
24
- uuid = random_uuid
25
- label ||= html_options.delete(:label) ||
26
- html_options.delete(:icon) ||
27
- icon('circle-arrow-up')
28
- link_to(label, 'javascript:;', data: { toggle: 'modal', target: "##{ uuid }" }) +
29
- content_tag(:div, id: uuid, class: 'modal fade', tabindex: -1, role: 'dialog') do
30
- content_tag :div, class: 'modal-dialog modal-lg' do
31
- content_tag :div, class: 'modal-content' do
32
- content_tag(:div, class: 'modal-header') do
33
- button_tag(type: 'button', class: 'close', data: { dismiss: 'modal' }, aria: { label: 'Close' }) do
34
- content_tag :span, raw('&times;'), aria: { hidden: true }
35
- end +
36
- content_tag(:h4, title, class: 'modal-title')
37
- end +
38
- content_tag(:div, class: 'modal-body') do
39
- body
40
- end
41
- end
34
+ # Build up modal
35
+ # @param title [String]
36
+ # @param body [String]
37
+ # @param html_options [Hash]
38
+ # @return [String] modal HTML
39
+ def imodal(title, body, html_options = {})
40
+ label ||= html_options.delete(:label) \
41
+ || html_options.delete(:icon) || fa_icon('clone')
42
+ content_tag :span, class: 'modaler' do
43
+ concat link_to(label, '#', data: { target: '#imodal', toggle: 'modal' })
44
+ concat content_tag(:span, title, class: 'modaler__title')
45
+ concat content_tag(:span, body, class: 'modaler__body')
42
46
  end
43
47
  end
44
- end
45
48
 
46
- def null
47
- muted 'null'
48
- end
49
+ # @return [String] grey null
50
+ def null
51
+ muted 'null'
52
+ end
49
53
 
50
- def na
51
- muted 'n/a'
52
- end
54
+ # @return [String] grey N/A
55
+ def na
56
+ muted 'n/a'
57
+ end
53
58
 
54
- def muted(content)
55
- content_tag :i, "<#{ content }>", class: 'text-muted'
59
+ # Grey text
60
+ # @param text_content [String]
61
+ # @return [String] HTML I element
62
+ def muted(text_content)
63
+ content_tag :i, "<#{text_content}>", class: 'text-muted'
64
+ end
56
65
  end
57
66
  end
@@ -1,17 +1,24 @@
1
- class Wallaby::Mode
2
- INTERFACE_METHODS = %w( model_decorator model_finder model_operator )
1
+ module Wallaby
2
+ # This is the abstract class that all ORM modes to have implemented.
3
+ class Mode
4
+ INTERFACE_METHODS = %w(
5
+ model_decorator model_finder
6
+ model_service_provider model_pagination_provider
7
+ ).freeze
3
8
 
4
- INTERFACE_METHODS.each do |method_id|
5
- define_singleton_method method_id do
6
- begin
7
- method_class = __callee__.to_s.classify
8
- class_name = "#{ name }::#{ method_class }"
9
- parent_class = "Wallaby::#{ method_class }".constantize
10
- class_name.constantize.tap do |klass|
11
- fail Wallaby::InvalidError, "#{ klass } must inherit #{ parent_class }" unless klass < parent_class
9
+ INTERFACE_METHODS.each do |method_id|
10
+ define_singleton_method method_id do
11
+ begin
12
+ method_class = __callee__.to_s.classify
13
+ class_name = "#{name}::#{method_class}"
14
+ parent_class = "Wallaby::#{method_class}".constantize
15
+ class_name.constantize.tap do |klass|
16
+ next if klass < parent_class
17
+ raise InvalidError, "#{klass} must inherit #{parent_class}"
18
+ end
19
+ rescue NameError
20
+ raise NotImplemented, class_name
12
21
  end
13
- rescue NameError
14
- fail Wallaby::NotImplemented, class_name
15
22
  end
16
23
  end
17
24
  end