avo 0.4.10 → 0.5.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of avo might be problematic. Click here for more details.

Files changed (519) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +35 -9
  3. data/Gemfile.lock +108 -85
  4. data/README.md +4 -0
  5. data/app/components/avo/common/badge_viewer_component.html.erb +24 -0
  6. data/app/components/avo/common/badge_viewer_component.rb +8 -0
  7. data/app/components/avo/common/boolean_check_component.html.erb +12 -0
  8. data/app/components/avo/common/boolean_check_component.rb +7 -0
  9. data/app/components/avo/common/boolean_group_component.html.erb +16 -0
  10. data/app/components/avo/common/boolean_group_component.rb +8 -0
  11. data/app/components/avo/common/files_list_viewer_component.html.erb +5 -0
  12. data/app/components/avo/common/files_list_viewer_component.rb +8 -0
  13. data/app/components/avo/common/gravatar_viewer_component.html.erb +12 -0
  14. data/app/components/avo/common/gravatar_viewer_component.rb +12 -0
  15. data/app/components/avo/common/heading_component.html.erb +13 -0
  16. data/app/components/avo/common/heading_component.rb +8 -0
  17. data/app/components/avo/common/multiple_file_viewer_component.html.erb +26 -0
  18. data/app/components/avo/common/multiple_file_viewer_component.rb +13 -0
  19. data/app/components/avo/common/single_file_viewer_component.html.erb +28 -0
  20. data/app/components/avo/common/single_file_viewer_component.rb +13 -0
  21. data/app/components/avo/common/status_viewer_component.html.erb +10 -0
  22. data/app/components/avo/common/status_viewer_component.rb +8 -0
  23. data/app/components/avo/edit/field_wrapper_component.html.erb +20 -0
  24. data/app/components/avo/edit/field_wrapper_component.rb +19 -0
  25. data/app/components/avo/edit/fields/belongs_to_field_component.html.erb +19 -0
  26. data/app/components/avo/edit/fields/belongs_to_field_component.rb +4 -0
  27. data/app/components/avo/edit/fields/boolean_field_component.html.erb +9 -0
  28. data/app/components/avo/edit/fields/boolean_field_component.rb +4 -0
  29. data/app/components/avo/edit/fields/boolean_group_field_component.html.erb +25 -0
  30. data/app/components/avo/edit/fields/boolean_group_field_component.rb +4 -0
  31. data/app/components/avo/edit/fields/code_field_component.html.erb +19 -0
  32. data/app/components/avo/edit/fields/code_field_component.rb +4 -0
  33. data/app/components/avo/edit/fields/country_field_component.html.erb +7 -0
  34. data/app/components/avo/edit/fields/country_field_component.rb +4 -0
  35. data/app/components/avo/edit/fields/date_field_component.html.erb +18 -0
  36. data/app/components/avo/edit/fields/date_field_component.rb +4 -0
  37. data/app/components/avo/edit/fields/date_time_field_component.html.erb +20 -0
  38. data/app/components/avo/edit/fields/date_time_field_component.rb +4 -0
  39. data/app/components/avo/edit/fields/external_image_field_component.html.erb +6 -0
  40. data/app/components/avo/edit/fields/external_image_field_component.rb +4 -0
  41. data/app/components/avo/edit/fields/field_component.rb +13 -0
  42. data/app/components/avo/edit/fields/file_field_component.html.erb +9 -0
  43. data/app/components/avo/edit/fields/file_field_component.rb +4 -0
  44. data/app/components/avo/edit/fields/files_field_component.html.erb +5 -0
  45. data/app/components/avo/edit/fields/files_field_component.rb +4 -0
  46. data/app/components/avo/edit/fields/heading_field_component.html.erb +3 -0
  47. data/app/components/avo/edit/fields/heading_field_component.rb +4 -0
  48. data/app/components/avo/edit/fields/hidden_field_component.html.erb +1 -0
  49. data/app/components/avo/edit/fields/hidden_field_component.rb +4 -0
  50. data/app/components/avo/edit/fields/id_field_component.html.erb +3 -0
  51. data/app/components/avo/edit/fields/id_field_component.rb +4 -0
  52. data/app/components/avo/edit/fields/markdown_field_component.html.erb +11 -0
  53. data/app/components/avo/edit/fields/markdown_field_component.rb +4 -0
  54. data/app/components/avo/edit/fields/number_field_component.html.erb +9 -0
  55. data/app/components/avo/edit/fields/number_field_component.rb +4 -0
  56. data/app/components/avo/edit/fields/password_field_component.html.erb +7 -0
  57. data/app/components/avo/edit/fields/password_field_component.rb +4 -0
  58. data/app/components/avo/edit/fields/select_field_component.html.erb +6 -0
  59. data/app/components/avo/edit/fields/select_field_component.rb +4 -0
  60. data/app/components/avo/edit/fields/status_field_component.html.erb +7 -0
  61. data/app/components/avo/edit/fields/status_field_component.rb +4 -0
  62. data/app/components/avo/edit/fields/text_field_component.html.erb +6 -0
  63. data/app/components/avo/edit/fields/text_field_component.rb +4 -0
  64. data/app/components/avo/edit/fields/textarea_field_component.html.erb +7 -0
  65. data/app/components/avo/edit/fields/textarea_field_component.rb +4 -0
  66. data/app/components/avo/edit/fields/trix_field_component.html.erb +11 -0
  67. data/app/components/avo/edit/fields/trix_field_component.rb +4 -0
  68. data/app/components/avo/index/field_wrapper_component.html.erb +7 -0
  69. data/app/components/avo/index/field_wrapper_component.rb +10 -0
  70. data/app/components/avo/index/fields/badge_field_component.html.erb +3 -0
  71. data/app/components/avo/index/fields/badge_field_component.rb +4 -0
  72. data/app/components/avo/index/fields/belongs_to_field_component.html.erb +7 -0
  73. data/app/components/avo/index/fields/belongs_to_field_component.rb +4 -0
  74. data/app/components/avo/index/fields/boolean_field_component.html.erb +3 -0
  75. data/app/components/avo/index/fields/boolean_field_component.rb +4 -0
  76. data/app/components/avo/index/fields/boolean_group_field_component.html.erb +3 -0
  77. data/app/components/avo/index/fields/boolean_group_field_component.rb +4 -0
  78. data/app/components/avo/index/fields/country_field_component.html.erb +7 -0
  79. data/app/components/avo/index/fields/country_field_component.rb +4 -0
  80. data/app/components/avo/index/fields/date_field_component.html.erb +3 -0
  81. data/app/components/avo/index/fields/date_field_component.rb +4 -0
  82. data/app/components/avo/index/fields/date_time_field_component.html.erb +3 -0
  83. data/app/components/avo/index/fields/date_time_field_component.rb +4 -0
  84. data/app/components/avo/index/fields/external_image_field_component.html.erb +9 -0
  85. data/app/components/avo/index/fields/external_image_field_component.rb +4 -0
  86. data/app/components/avo/index/fields/field_component.html.erb +1 -0
  87. data/app/components/avo/index/fields/field_component.rb +11 -0
  88. data/app/components/avo/index/fields/file_field_component.html.erb +11 -0
  89. data/app/components/avo/index/fields/file_field_component.rb +4 -0
  90. data/app/components/avo/index/fields/files_field_component.html.erb +3 -0
  91. data/app/components/avo/index/fields/files_field_component.rb +4 -0
  92. data/app/components/avo/index/fields/gravatar_field_component.html.erb +11 -0
  93. data/app/components/avo/index/fields/gravatar_field_component.rb +4 -0
  94. data/app/components/avo/index/fields/has_one_field_component.html.erb +7 -0
  95. data/app/components/avo/index/fields/has_one_field_component.rb +4 -0
  96. data/app/components/avo/index/fields/id_field_component.html.erb +10 -0
  97. data/app/components/avo/index/fields/id_field_component.rb +4 -0
  98. data/app/components/avo/index/fields/number_field_component.html.erb +3 -0
  99. data/app/components/avo/index/fields/number_field_component.rb +4 -0
  100. data/app/components/avo/index/fields/select_field_component.html.erb +3 -0
  101. data/app/components/avo/index/fields/select_field_component.rb +4 -0
  102. data/app/components/avo/index/fields/status_field_component.html.erb +3 -0
  103. data/app/components/avo/index/fields/status_field_component.rb +4 -0
  104. data/app/components/avo/index/fields/text_field_component.html.erb +3 -0
  105. data/app/components/avo/index/fields/text_field_component.rb +4 -0
  106. data/app/components/avo/index/grid_item_component.html.erb +41 -0
  107. data/app/components/avo/index/grid_item_component.rb +31 -0
  108. data/app/components/avo/index/resource_controls_component.html.erb +56 -0
  109. data/app/components/avo/index/resource_controls_component.rb +39 -0
  110. data/app/components/avo/index/resource_grid_component.html.erb +13 -0
  111. data/app/components/avo/index/resource_grid_component.rb +10 -0
  112. data/app/components/avo/index/resource_table_component.html.erb +16 -0
  113. data/app/components/avo/index/resource_table_component.rb +10 -0
  114. data/app/components/avo/index/table_row_component.html.erb +18 -0
  115. data/app/components/avo/index/table_row_component.rb +11 -0
  116. data/app/components/avo/loading_component.html.erb +10 -0
  117. data/app/components/avo/loading_component.rb +7 -0
  118. data/app/components/avo/modal_component.html.erb +20 -0
  119. data/app/components/avo/modal_component.rb +5 -0
  120. data/app/components/avo/navigation_heading_component.html.erb +3 -0
  121. data/app/components/avo/navigation_heading_component.rb +7 -0
  122. data/app/components/avo/navigation_link_component.html.erb +3 -0
  123. data/app/components/avo/navigation_link_component.rb +10 -0
  124. data/app/components/avo/panel_component.html.erb +27 -0
  125. data/app/components/avo/panel_component.rb +20 -0
  126. data/app/components/avo/resource_component.rb +14 -0
  127. data/app/components/avo/show/field_wrapper_component.html.erb +16 -0
  128. data/app/components/avo/show/field_wrapper_component.rb +15 -0
  129. data/app/components/avo/show/fields/badge_field_component.html.erb +3 -0
  130. data/app/components/avo/show/fields/badge_field_component.rb +4 -0
  131. data/app/components/avo/show/fields/belongs_to_field_component.html.erb +3 -0
  132. data/app/components/avo/show/fields/belongs_to_field_component.rb +4 -0
  133. data/app/components/avo/show/fields/boolean_field_component.html.erb +3 -0
  134. data/app/components/avo/show/fields/boolean_field_component.rb +4 -0
  135. data/app/components/avo/show/fields/boolean_group_field_component.html.erb +3 -0
  136. data/app/components/avo/show/fields/boolean_group_field_component.rb +4 -0
  137. data/app/components/avo/show/fields/code_field_component.html.erb +19 -0
  138. data/app/components/avo/show/fields/code_field_component.rb +4 -0
  139. data/app/components/avo/show/fields/country_field_component.html.erb +7 -0
  140. data/app/components/avo/show/fields/country_field_component.rb +4 -0
  141. data/app/components/avo/show/fields/date_field_component.html.erb +3 -0
  142. data/app/components/avo/show/fields/date_field_component.rb +4 -0
  143. data/app/components/avo/show/fields/date_time_field_component.html.erb +3 -0
  144. data/app/components/avo/show/fields/date_time_field_component.rb +4 -0
  145. data/app/components/avo/show/fields/external_image_field_component.html.erb +5 -0
  146. data/app/components/avo/show/fields/external_image_field_component.rb +4 -0
  147. data/app/components/avo/show/fields/field_component.rb +11 -0
  148. data/app/components/avo/show/fields/file_field_component.html.erb +3 -0
  149. data/app/components/avo/show/fields/file_field_component.rb +4 -0
  150. data/app/components/avo/show/fields/files_field_component.html.erb +3 -0
  151. data/app/components/avo/show/fields/files_field_component.rb +4 -0
  152. data/app/components/avo/show/fields/gravatar_field_component.html.erb +7 -0
  153. data/app/components/avo/show/fields/gravatar_field_component.rb +4 -0
  154. data/app/components/avo/show/fields/has_many_field_component.html.erb +3 -0
  155. data/app/components/avo/show/fields/has_many_field_component.rb +4 -0
  156. data/app/components/avo/show/fields/has_one_field_component.html.erb +19 -0
  157. data/app/components/avo/show/fields/has_one_field_component.rb +5 -0
  158. data/app/components/avo/show/fields/heading_field_component.html.erb +3 -0
  159. data/app/components/avo/show/fields/heading_field_component.rb +4 -0
  160. data/app/components/avo/show/fields/id_field_component.html.erb +3 -0
  161. data/app/components/avo/show/fields/id_field_component.rb +4 -0
  162. data/app/components/avo/show/fields/markdown_field_component.html.erb +10 -0
  163. data/app/components/avo/show/fields/markdown_field_component.rb +4 -0
  164. data/app/components/avo/show/fields/number_field_component.html.erb +3 -0
  165. data/app/components/avo/show/fields/number_field_component.rb +4 -0
  166. data/app/components/avo/show/fields/select_field_component.html.erb +3 -0
  167. data/app/components/avo/show/fields/select_field_component.rb +4 -0
  168. data/app/components/avo/show/fields/status_field_component.html.erb +3 -0
  169. data/app/components/avo/show/fields/status_field_component.rb +4 -0
  170. data/app/components/avo/show/fields/text_field_component.html.erb +3 -0
  171. data/app/components/avo/show/fields/text_field_component.rb +4 -0
  172. data/app/components/avo/show/fields/textarea_field_component.html.erb +3 -0
  173. data/app/components/avo/show/fields/textarea_field_component.rb +4 -0
  174. data/app/components/avo/show/fields/trix_field_component.html.erb +14 -0
  175. data/app/components/avo/show/fields/trix_field_component.rb +4 -0
  176. data/app/components/avo/views/resource_edit_component.html.erb +29 -0
  177. data/app/components/avo/views/resource_edit_component.rb +23 -0
  178. data/app/components/avo/views/resource_index_component.html.erb +62 -0
  179. data/app/components/avo/views/resource_index_component.rb +93 -0
  180. data/app/components/avo/views/resource_new_component.html.erb +25 -0
  181. data/app/components/avo/views/resource_new_component.rb +27 -0
  182. data/app/components/avo/views/resource_show_component.html.erb +64 -0
  183. data/app/components/avo/views/resource_show_component.rb +66 -0
  184. data/app/controllers/avo/actions_controller.rb +52 -22
  185. data/app/controllers/avo/application_controller.rb +184 -25
  186. data/app/controllers/avo/attachments_controller.rb +25 -0
  187. data/app/controllers/avo/base_controller.rb +218 -0
  188. data/app/controllers/avo/home_controller.rb +3 -0
  189. data/app/controllers/avo/relations_controller.rb +88 -19
  190. data/app/controllers/avo/resource_overview_controller.rb +3 -1
  191. data/app/controllers/avo/resources_controller.rb +2 -259
  192. data/app/controllers/avo/search_controller.rb +7 -6
  193. data/app/frontend/css/alerts.css +35 -0
  194. data/app/frontend/css/application.css +73 -0
  195. data/app/frontend/css/components/code.css +27 -0
  196. data/app/frontend/css/components/status.css +30 -0
  197. data/app/frontend/css/fonts.css +26 -0
  198. data/app/frontend/css/loader.css +134 -0
  199. data/app/frontend/css/pagination.css +67 -0
  200. data/app/frontend/css/tailwindcss/base.css +1 -0
  201. data/app/frontend/css/tailwindcss/components.css +1 -0
  202. data/app/frontend/css/tailwindcss/utilities.css +1 -0
  203. data/app/frontend/css/tooltips.css +105 -0
  204. data/app/frontend/css/typography.css +23 -0
  205. data/app/frontend/fonts/nunito-v16-latin-700.eot +0 -0
  206. data/app/frontend/fonts/nunito-v16-latin-700.svg +388 -0
  207. data/app/frontend/fonts/nunito-v16-latin-700.ttf +0 -0
  208. data/app/frontend/fonts/nunito-v16-latin-700.woff +0 -0
  209. data/app/frontend/fonts/nunito-v16-latin-700.woff2 +0 -0
  210. data/app/frontend/fonts/nunito-v16-latin-regular.eot +0 -0
  211. data/app/frontend/fonts/nunito-v16-latin-regular.svg +380 -0
  212. data/app/frontend/fonts/nunito-v16-latin-regular.ttf +0 -0
  213. data/app/frontend/fonts/nunito-v16-latin-regular.woff +0 -0
  214. data/app/frontend/fonts/nunito-v16-latin-regular.woff2 +0 -0
  215. data/app/frontend/images/logo.png +0 -0
  216. data/app/frontend/importmap.json.erb +5 -0
  217. data/app/frontend/js/controllers/action_controller.js +32 -0
  218. data/app/frontend/js/controllers/actions_picker_controller.js +44 -0
  219. data/app/frontend/js/controllers/alerts_controller.js +26 -0
  220. data/app/frontend/js/controllers/attachments_controller.js +9 -0
  221. data/app/frontend/js/controllers/boolean_filter_controller.js +21 -0
  222. data/app/frontend/js/controllers/fields/code_field_controller.js +35 -0
  223. data/app/frontend/js/controllers/fields/date_field_controller.js +53 -0
  224. data/app/frontend/js/controllers/fields/simple_mde_controller.js +26 -0
  225. data/app/frontend/js/controllers/filter_controller.js +52 -0
  226. data/app/frontend/js/controllers/hidden_input_controller.js +10 -0
  227. data/app/frontend/js/controllers/item_selector_controller.js +68 -0
  228. data/app/frontend/js/controllers/modal_controller.js +11 -0
  229. data/app/frontend/js/controllers/per_page_controller.js +9 -0
  230. data/app/frontend/js/controllers/select_filter_controller.js +15 -0
  231. data/app/frontend/js/controllers/tippy_controller.js +14 -0
  232. data/app/frontend/js/controllers/toggle_panel_controller.js +18 -0
  233. data/app/frontend/js/helpers/cast_boolean.js +2 -0
  234. data/app/frontend/js/toastr.js +9 -0
  235. data/app/frontend/packs/application.js +45 -0
  236. data/{public/avo-packs/media/svgs/arrow-circle-right-1ad1e15ec9a7aa54b67d126566a5aa2d.svg → app/frontend/svgs/arrow-circle-right.svg} +0 -0
  237. data/{public/avo-packs/media/svgs/arrow-left-0e8e808ff771a62a348d0232c8ccf539.svg → app/frontend/svgs/arrow-left.svg} +0 -0
  238. data/{public/avo-packs/media/svgs/avocado-bca389be7cf81162df902dfbd09b8adb.svg → app/frontend/svgs/avocado.svg} +0 -0
  239. data/app/frontend/svgs/badge-check-sm.svg +3 -0
  240. data/{public/avo-packs/media/svgs/check-circle-be9e4dcbd25467ae9a3d3c6c5c7a09fa.svg → app/frontend/svgs/check-circle.svg} +0 -0
  241. data/{public/avo-packs/media/svgs/chevron-down-01208b17a1f70a1bb8d82bba131da4f4.svg → app/frontend/svgs/chevron-down.svg} +0 -0
  242. data/{public/avo-packs/media/svgs/chevron-up-25ecf340dd76966d5ed63c85c025befc.svg → app/frontend/svgs/chevron-up.svg} +0 -0
  243. data/{public/avo-packs/media/svgs/code-69010c6ddb6ad50be8677f16468c51f8.svg → app/frontend/svgs/code.svg} +0 -0
  244. data/{public/avo-packs/media/svgs/color-swatch-60cf90fb6b5386e38f3b003f34e7ecbe.svg → app/frontend/svgs/color-swatch.svg} +0 -0
  245. data/app/frontend/svgs/document-text.svg +3 -0
  246. data/{public/avo-packs/media/svgs/download-c6ae3f12364a467c28cbf41dc90afbdd.svg → app/frontend/svgs/download.svg} +0 -0
  247. data/{public/avo-packs/media/svgs/edit-46c6dbef52ba6ddfc9afbc37186dfa2b.svg → app/frontend/svgs/edit.svg} +0 -0
  248. data/app/frontend/svgs/exclamation-circle-sm.svg +3 -0
  249. data/app/frontend/svgs/exclamation-sm.svg +3 -0
  250. data/{public/avo-packs/media/svgs/exclamation-8d1c0baa390a8df9bb52176011eb5892.svg → app/frontend/svgs/exclamation.svg} +0 -0
  251. data/{public/avo-packs/media/svgs/eye-cc6f85c70ebed6929712a5c7d51f102d.svg → app/frontend/svgs/eye.svg} +0 -0
  252. data/{public/avo-packs/media/svgs/filter-0007cddbc85cfe207f9876d4d184444a.svg → app/frontend/svgs/filter.svg} +0 -0
  253. data/{public/avo-packs/media/svgs/fire-782f08df79993311b6d907e12d9ebe9f.svg → app/frontend/svgs/fire.svg} +0 -0
  254. data/{public/avo-packs/media/svgs/game-board-6c59fe04181ac9954356c9f1f4d28053.svg → app/frontend/svgs/game-board.svg} +0 -0
  255. data/{public/avo-packs/media/svgs/globe-dfd9977c9d65814d2fc576904406dd08.svg → app/frontend/svgs/globe.svg} +0 -0
  256. data/app/frontend/svgs/information-circle-sm.svg +3 -0
  257. data/app/frontend/svgs/information-circle.svg +1 -0
  258. data/{public/avo-packs/media/svgs/library-7d391192a15da64fbb527908c9e035c7.svg → app/frontend/svgs/library.svg} +0 -0
  259. data/{public/avo-packs/media/svgs/photograph-9f37f1f5e6a48e68ce3b7d9cbe7b6fad.svg → app/frontend/svgs/photograph.svg} +0 -0
  260. data/app/frontend/svgs/play.svg +1 -0
  261. data/{public/avo-packs/media/svgs/plus-circle-b379b2a2aa803511ae5945b6fd323204.svg → app/frontend/svgs/plus-circle.svg} +0 -0
  262. data/{public/avo-packs/media/svgs/plus-530f0af27b9f1a4552454233c2f9a641.svg → app/frontend/svgs/plus.svg} +0 -0
  263. data/{public/avo-packs/media/svgs/question-mark-circle-3ece1d61091827910cdd097db711062b.svg → app/frontend/svgs/question-mark-circle.svg} +0 -0
  264. data/{public/avo-packs/media/svgs/save-e54acd7ac9646053e36382776f822756.svg → app/frontend/svgs/save.svg} +0 -0
  265. data/{public/avo-packs/media/svgs/selector-b43b3957d7cc121d06be14312613c218.svg → app/frontend/svgs/selector.svg} +0 -0
  266. data/{public/avo-packs/media/svgs/sort-ascending-f5bc0761702809cab20b0ea3065cb88a.svg → app/frontend/svgs/sort-ascending.svg} +0 -0
  267. data/{public/avo-packs/media/svgs/sort-descending-1c8ddc56c72be6781e59d808f9d06203.svg → app/frontend/svgs/sort-descending.svg} +0 -0
  268. data/{public/avo-packs/media/svgs/switch-horizontal-d23337f0fb533a86d14b746d25ad48ae.svg → app/frontend/svgs/switch-horizontal.svg} +0 -0
  269. data/{public/avo-packs/media/svgs/thumbs-down-44f83eacbf5b8fe0f2f085da75866ce0.svg → app/frontend/svgs/thumbs-down.svg} +0 -0
  270. data/{public/avo-packs/media/svgs/thumbs-up-b866900017db179b50d6b19a1424ed25.svg → app/frontend/svgs/thumbs-up.svg} +0 -0
  271. data/app/frontend/svgs/times.svg +3 -0
  272. data/app/frontend/svgs/trash-sm.svg +3 -0
  273. data/{public/avo-packs/media/svgs/trash-a61412a066e358bcc24494a5080b7255.svg → app/frontend/svgs/trash.svg} +0 -0
  274. data/{public/avo-packs/media/svgs/view-grid-add-d0ee477a044e5d46c0c62af66cb6de77.svg → app/frontend/svgs/view-grid-add.svg} +0 -0
  275. data/{public/avo-packs/media/svgs/view-grid-393669034db69f59497616d5416ae411.svg → app/frontend/svgs/view-grid.svg} +0 -0
  276. data/{public/avo-packs/media/svgs/view-list-8a7a159ca5d892f72cf8c6744a2074e2.svg → app/frontend/svgs/view-list.svg} +0 -0
  277. data/{public/avo-packs/media/svgs/x-circle-c540f9ccfe937ad9b4f662e0b65e47e2.svg → app/frontend/svgs/x-circle.svg} +0 -0
  278. data/app/helpers/avo/actions_helper.rb +4 -0
  279. data/app/helpers/avo/application_helper.rb +156 -3
  280. data/app/helpers/avo/attachments_helper.rb +4 -0
  281. data/app/helpers/avo/resources_helper.rb +101 -0
  282. data/app/views/avo/actions/show.html.erb +71 -0
  283. data/app/views/avo/attachments/show.html.erb +7 -0
  284. data/app/views/avo/base/_actions.html.erb +36 -0
  285. data/app/views/avo/base/_boolean_filter.html.erb +33 -0
  286. data/app/views/avo/base/_filters.html.erb +37 -0
  287. data/app/views/avo/base/_select_filter.html.erb +20 -0
  288. data/app/views/avo/base/edit.html.erb +1 -0
  289. data/app/views/avo/base/index.html.erb +15 -0
  290. data/app/views/avo/base/new.html.erb +1 -0
  291. data/app/views/avo/base/show.html.erb +3 -0
  292. data/app/views/avo/home/_actions.html.erb +16 -0
  293. data/app/views/avo/home/_docs.html.erb +9 -0
  294. data/app/views/avo/home/_filters.html.erb +16 -0
  295. data/app/views/avo/home/_resources.html.erb +29 -0
  296. data/app/views/avo/home/index.html.erb +54 -3
  297. data/app/views/avo/partials/_a_button.html.erb +7 -0
  298. data/app/views/avo/partials/_a_link.html.erb +7 -0
  299. data/app/views/avo/partials/_alert.html.erb +1 -0
  300. data/app/views/avo/partials/_alerts.html.erb +3 -0
  301. data/app/views/avo/partials/_empty_state.html.erb +17 -0
  302. data/app/views/{partials → avo/partials}/_footer.html.erb +0 -0
  303. data/app/views/{partials → avo/partials}/_header.html.erb +0 -0
  304. data/app/views/avo/partials/_javascript.html.erb +3 -0
  305. data/app/views/{partials → avo/partials}/_logo.html.erb +0 -0
  306. data/app/views/avo/partials/_paginator.html.erb +30 -0
  307. data/app/views/avo/partials/_sortable_component.html.erb +14 -0
  308. data/app/views/avo/partials/_table_header.html.erb +50 -0
  309. data/app/views/avo/partials/_view_toggle_button.html.erb +17 -0
  310. data/app/views/avo/relations/new.html.erb +29 -0
  311. data/app/views/avo/sidebar/_license_warning.html.erb +12 -0
  312. data/app/views/avo/sidebar/_license_warnings.html.erb +6 -0
  313. data/app/views/avo/sidebar/_sidebar.html.erb +23 -0
  314. data/app/views/kaminari/_first_page.html.erb +3 -0
  315. data/app/views/kaminari/_last_page.html.erb +3 -0
  316. data/app/views/kaminari/_next_page.html.erb +9 -0
  317. data/app/views/kaminari/_page.html.erb +12 -0
  318. data/app/views/kaminari/_prev_page.html.erb +9 -0
  319. data/app/views/layouts/avo/_filter_wrapper.html.erb +8 -0
  320. data/app/views/layouts/avo/application.html.erb +28 -40
  321. data/app/views/layouts/avo/application_vue.html.erb +61 -0
  322. data/avo.gemspec +5 -3
  323. data/bin/helpers.rb +34 -0
  324. data/bin/init +35 -0
  325. data/bin/rspec +8 -0
  326. data/bin/spring +17 -0
  327. data/bin/test +21 -0
  328. data/bin/webpack +9 -10
  329. data/bin/webpack-dev-server +9 -10
  330. data/config/cable.yml +11 -0
  331. data/config/initializers/inline_svg.rb +33 -0
  332. data/config/initializers/pagy.rb +1 -0
  333. data/config/routes.rb +22 -18
  334. data/config/spring.rb +7 -0
  335. data/config/webpack/environment.js +14 -10
  336. data/config/webpacker.yml +5 -4
  337. data/config/webpacker_packed.yml +86 -0
  338. data/db/factories.rb +10 -3
  339. data/db/migrate/20210305082639_add_url_to_teams.rb +5 -0
  340. data/lib/avo.rb +3 -0
  341. data/lib/avo/app/action.rb +51 -45
  342. data/lib/avo/app/actions_loader.rb +11 -0
  343. data/lib/avo/app/app.rb +57 -45
  344. data/lib/avo/app/fields/badge_field.rb +3 -30
  345. data/lib/avo/app/fields/belongs_to.rb +38 -50
  346. data/lib/avo/app/fields/boolean_field.rb +8 -10
  347. data/lib/avo/app/fields/boolean_group_field.rb +13 -11
  348. data/lib/avo/app/fields/code_field.rb +11 -9
  349. data/lib/avo/app/fields/country_field.rb +12 -21
  350. data/lib/avo/app/fields/currency_field.rb +1 -2
  351. data/lib/avo/app/fields/date_field.rb +16 -11
  352. data/lib/avo/app/fields/date_time_field.rb +38 -0
  353. data/lib/avo/app/fields/external_image_field.rb +23 -0
  354. data/lib/avo/app/fields/field.rb +76 -84
  355. data/lib/avo/app/fields/field_extensions/visible_in_different_views.rb +5 -5
  356. data/lib/avo/app/fields/file_field.rb +8 -14
  357. data/lib/avo/app/fields/files_field.rb +10 -18
  358. data/lib/avo/app/fields/gravatar_field.rb +18 -13
  359. data/lib/avo/app/fields/has_and_belongs_to_many.rb +13 -24
  360. data/lib/avo/app/fields/has_many.rb +13 -26
  361. data/lib/avo/app/fields/has_one.rb +23 -30
  362. data/lib/avo/app/fields/heading_field.rb +2 -8
  363. data/lib/avo/app/fields/hidden_field.rb +2 -2
  364. data/lib/avo/app/fields/id_field.rb +2 -8
  365. data/lib/avo/app/fields/key_value_field.rb +5 -2
  366. data/lib/avo/app/fields/markdown_field.rb +1 -1
  367. data/lib/avo/app/fields/number_field.rb +5 -12
  368. data/lib/avo/app/fields/password_field.rb +1 -1
  369. data/lib/avo/app/fields/select_field.rb +33 -10
  370. data/lib/avo/app/fields/status_field.rb +9 -7
  371. data/lib/avo/app/fields/text_field.rb +1 -8
  372. data/lib/avo/app/fields/textarea_field.rb +2 -9
  373. data/lib/avo/app/fields/trix_field.rb +3 -7
  374. data/lib/avo/app/fields_loader.rb +29 -0
  375. data/lib/avo/app/licensing/hq.rb +3 -3
  376. data/lib/avo/app/licensing/license.rb +1 -1
  377. data/lib/avo/app/resource.rb +184 -126
  378. data/lib/avo/app/services/authorization_service.rb +68 -6
  379. data/lib/avo/app/services/panel_service.rb +25 -0
  380. data/lib/avo/configuration.rb +6 -0
  381. data/lib/avo/engine.rb +4 -1
  382. data/lib/avo/version.rb +1 -1
  383. data/lib/generators/avo/controller_generator.rb +13 -0
  384. data/lib/generators/avo/resource_generator.rb +16 -2
  385. data/lib/generators/avo/templates/initializer/avo.rb +3 -0
  386. data/lib/generators/avo/templates/locales/avo.en.yml +5 -1
  387. data/lib/generators/avo/templates/resource/%plural_name%_controller.tt +2 -0
  388. data/lib/generators/avo/templates/resource/%singular_name%.tt +20 -0
  389. data/public/avo-packs/css/application-3598cfbb.css +6 -0
  390. data/public/avo-packs/css/application-3598cfbb.css.br +0 -0
  391. data/public/avo-packs/css/application-3598cfbb.css.gz +0 -0
  392. data/public/avo-packs/js/1-0565987ca0c3045602ad.chunk.js +2 -0
  393. data/public/avo-packs/js/1-0565987ca0c3045602ad.chunk.js.br +0 -0
  394. data/public/avo-packs/js/1-0565987ca0c3045602ad.chunk.js.gz +0 -0
  395. data/public/avo-packs/js/1-0565987ca0c3045602ad.chunk.js.map +1 -0
  396. data/public/avo-packs/js/1-0565987ca0c3045602ad.chunk.js.map.br +0 -0
  397. data/public/avo-packs/js/1-0565987ca0c3045602ad.chunk.js.map.gz +0 -0
  398. data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js +26 -0
  399. data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.LICENSE.txt +77 -0
  400. data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.br +0 -0
  401. data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.gz +0 -0
  402. data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.map +1 -0
  403. data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.map.br +0 -0
  404. data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.map.gz +0 -0
  405. data/public/avo-packs/manifest.json +17 -46
  406. data/public/avo-packs/manifest.json.br +0 -0
  407. data/public/avo-packs/manifest.json.gz +0 -0
  408. data/public/avo-packs/media/fonts/nunito-v16-latin-700-2cc22f9c0cf217cbfc371f3b74992305.ttf +0 -0
  409. data/public/avo-packs/media/fonts/nunito-v16-latin-700-2cc22f9c0cf217cbfc371f3b74992305.ttf.br +0 -0
  410. data/public/avo-packs/media/fonts/nunito-v16-latin-700-2cc22f9c0cf217cbfc371f3b74992305.ttf.gz +0 -0
  411. data/public/avo-packs/media/fonts/nunito-v16-latin-700-35bd1c96bc2e402cf22ea812ae067995.svg +388 -0
  412. data/public/avo-packs/media/fonts/nunito-v16-latin-700-35bd1c96bc2e402cf22ea812ae067995.svg.br +0 -0
  413. data/public/avo-packs/media/fonts/nunito-v16-latin-700-35bd1c96bc2e402cf22ea812ae067995.svg.gz +0 -0
  414. data/public/avo-packs/media/fonts/nunito-v16-latin-700-412073df419ad5f6f8f2ea76eb4aced9.woff2 +0 -0
  415. data/public/avo-packs/media/fonts/nunito-v16-latin-700-7c472b19cb573f537bad8ef62ca917ac.woff +0 -0
  416. data/public/avo-packs/media/fonts/nunito-v16-latin-700-df7e79af617f98cd3b95d320e8b2a1af.eot +0 -0
  417. data/public/avo-packs/media/fonts/nunito-v16-latin-regular-00fbd8a72a3708b8314cce5f0515640e.svg +380 -0
  418. data/public/avo-packs/media/fonts/nunito-v16-latin-regular-00fbd8a72a3708b8314cce5f0515640e.svg.br +0 -0
  419. data/public/avo-packs/media/fonts/nunito-v16-latin-regular-00fbd8a72a3708b8314cce5f0515640e.svg.gz +0 -0
  420. data/public/avo-packs/media/fonts/nunito-v16-latin-regular-2fae1e2418251b68fe5d0505ab93dd5c.eot +0 -0
  421. data/public/avo-packs/media/fonts/nunito-v16-latin-regular-bcf84d6cb8a0ac214c8c14ba9af834f3.woff2 +0 -0
  422. data/public/avo-packs/media/fonts/nunito-v16-latin-regular-cb632c9fe211ba2c2bf1564c9a9295cc.woff +0 -0
  423. data/public/avo-packs/media/fonts/nunito-v16-latin-regular-df8c4bee41b6ca0ed2b7b71456ed7fbb.ttf +0 -0
  424. data/public/avo-packs/media/fonts/nunito-v16-latin-regular-df8c4bee41b6ca0ed2b7b71456ed7fbb.ttf.br +0 -0
  425. data/public/avo-packs/media/fonts/nunito-v16-latin-regular-df8c4bee41b6ca0ed2b7b71456ed7fbb.ttf.gz +0 -0
  426. metadata +408 -135
  427. data/app/controllers/avo/filters_controller.rb +0 -19
  428. data/app/views/avo/home/router.html.erb +0 -8
  429. data/app/views/layouts/avo/_javascript.html.erb +0 -8
  430. data/app/views/layouts/avo/_translations.html.erb +0 -5
  431. data/config/webpack/loaders/vue-post-css.js +0 -20
  432. data/config/webpack/loaders/vue-svg.js +0 -21
  433. data/config/webpack/loaders/vue.js +0 -6
  434. data/lib/avo/app/fields/datetime_field.rb +0 -34
  435. data/lib/avo/app/resource_actions.rb +0 -18
  436. data/lib/avo/app/resource_fields.rb +0 -26
  437. data/lib/avo/app/resource_filters.rb +0 -18
  438. data/lib/generators/avo/templates/resource.rb +0 -14
  439. data/public/avo-packs/css/application-c9595d99.css +0 -3
  440. data/public/avo-packs/css/application-c9595d99.css.br +0 -0
  441. data/public/avo-packs/css/application-c9595d99.css.gz +0 -0
  442. data/public/avo-packs/js/application-78fe71b4e59ebc7141f4.js +0 -3
  443. data/public/avo-packs/js/application-78fe71b4e59ebc7141f4.js.LICENSE.txt +0 -767
  444. data/public/avo-packs/js/application-78fe71b4e59ebc7141f4.js.br +0 -0
  445. data/public/avo-packs/js/application-78fe71b4e59ebc7141f4.js.gz +0 -0
  446. data/public/avo-packs/js/application-78fe71b4e59ebc7141f4.js.map +0 -1
  447. data/public/avo-packs/js/application-78fe71b4e59ebc7141f4.js.map.br +0 -0
  448. data/public/avo-packs/js/application-78fe71b4e59ebc7141f4.js.map.gz +0 -0
  449. data/public/avo-packs/media/font/fontello-068ca2b3.ttf +0 -0
  450. data/public/avo-packs/media/font/fontello-068ca2b3.ttf.br +0 -0
  451. data/public/avo-packs/media/font/fontello-068ca2b3.ttf.gz +0 -0
  452. data/public/avo-packs/media/font/fontello-8d4a4e6f.woff2 +0 -0
  453. data/public/avo-packs/media/font/fontello-9354499c.svg +0 -72
  454. data/public/avo-packs/media/font/fontello-9354499c.svg.br +0 -0
  455. data/public/avo-packs/media/font/fontello-9354499c.svg.gz +0 -0
  456. data/public/avo-packs/media/font/fontello-a782baa8.woff +0 -0
  457. data/public/avo-packs/media/font/fontello-e73a0647.eot +0 -0
  458. data/public/avo-packs/media/font/fontello-e73a0647.eot.br +0 -0
  459. data/public/avo-packs/media/font/fontello-e73a0647.eot.gz +0 -0
  460. data/public/avo-packs/media/svgs/arrow-circle-right-1ad1e15ec9a7aa54b67d126566a5aa2d.svg.br +0 -0
  461. data/public/avo-packs/media/svgs/arrow-circle-right-1ad1e15ec9a7aa54b67d126566a5aa2d.svg.gz +0 -0
  462. data/public/avo-packs/media/svgs/arrow-left-0e8e808ff771a62a348d0232c8ccf539.svg.br +0 -0
  463. data/public/avo-packs/media/svgs/avocado-bca389be7cf81162df902dfbd09b8adb.svg.br +0 -0
  464. data/public/avo-packs/media/svgs/avocado-bca389be7cf81162df902dfbd09b8adb.svg.gz +0 -0
  465. data/public/avo-packs/media/svgs/check-circle-be9e4dcbd25467ae9a3d3c6c5c7a09fa.svg.br +0 -0
  466. data/public/avo-packs/media/svgs/chevron-down-01208b17a1f70a1bb8d82bba131da4f4.svg.br +0 -0
  467. data/public/avo-packs/media/svgs/chevron-down-01208b17a1f70a1bb8d82bba131da4f4.svg.gz +0 -0
  468. data/public/avo-packs/media/svgs/chevron-up-25ecf340dd76966d5ed63c85c025befc.svg.br +0 -0
  469. data/public/avo-packs/media/svgs/chevron-up-25ecf340dd76966d5ed63c85c025befc.svg.gz +0 -0
  470. data/public/avo-packs/media/svgs/code-69010c6ddb6ad50be8677f16468c51f8.svg.br +0 -0
  471. data/public/avo-packs/media/svgs/color-swatch-60cf90fb6b5386e38f3b003f34e7ecbe.svg.br +0 -0
  472. data/public/avo-packs/media/svgs/color-swatch-60cf90fb6b5386e38f3b003f34e7ecbe.svg.gz +0 -0
  473. data/public/avo-packs/media/svgs/download-c6ae3f12364a467c28cbf41dc90afbdd.svg.br +0 -0
  474. data/public/avo-packs/media/svgs/download-c6ae3f12364a467c28cbf41dc90afbdd.svg.gz +0 -0
  475. data/public/avo-packs/media/svgs/edit-46c6dbef52ba6ddfc9afbc37186dfa2b.svg.br +0 -0
  476. data/public/avo-packs/media/svgs/edit-46c6dbef52ba6ddfc9afbc37186dfa2b.svg.gz +0 -0
  477. data/public/avo-packs/media/svgs/exclamation-8d1c0baa390a8df9bb52176011eb5892.svg.br +0 -0
  478. data/public/avo-packs/media/svgs/exclamation-8d1c0baa390a8df9bb52176011eb5892.svg.gz +0 -0
  479. data/public/avo-packs/media/svgs/eye-cc6f85c70ebed6929712a5c7d51f102d.svg.br +0 -1
  480. data/public/avo-packs/media/svgs/eye-cc6f85c70ebed6929712a5c7d51f102d.svg.gz +0 -0
  481. data/public/avo-packs/media/svgs/filter-0007cddbc85cfe207f9876d4d184444a.svg.br +0 -0
  482. data/public/avo-packs/media/svgs/filter-0007cddbc85cfe207f9876d4d184444a.svg.gz +0 -0
  483. data/public/avo-packs/media/svgs/fire-782f08df79993311b6d907e12d9ebe9f.svg.br +0 -0
  484. data/public/avo-packs/media/svgs/fire-782f08df79993311b6d907e12d9ebe9f.svg.gz +0 -0
  485. data/public/avo-packs/media/svgs/game-board-6c59fe04181ac9954356c9f1f4d28053.svg.br +0 -0
  486. data/public/avo-packs/media/svgs/game-board-6c59fe04181ac9954356c9f1f4d28053.svg.gz +0 -0
  487. data/public/avo-packs/media/svgs/globe-dfd9977c9d65814d2fc576904406dd08.svg.br +0 -0
  488. data/public/avo-packs/media/svgs/globe-dfd9977c9d65814d2fc576904406dd08.svg.gz +0 -0
  489. data/public/avo-packs/media/svgs/library-7d391192a15da64fbb527908c9e035c7.svg.br +0 -0
  490. data/public/avo-packs/media/svgs/photograph-9f37f1f5e6a48e68ce3b7d9cbe7b6fad.svg.br +0 -2
  491. data/public/avo-packs/media/svgs/photograph-9f37f1f5e6a48e68ce3b7d9cbe7b6fad.svg.gz +0 -0
  492. data/public/avo-packs/media/svgs/plus-530f0af27b9f1a4552454233c2f9a641.svg.br +0 -0
  493. data/public/avo-packs/media/svgs/plus-circle-b379b2a2aa803511ae5945b6fd323204.svg.br +0 -0
  494. data/public/avo-packs/media/svgs/question-mark-circle-3ece1d61091827910cdd097db711062b.svg.br +0 -0
  495. data/public/avo-packs/media/svgs/question-mark-circle-3ece1d61091827910cdd097db711062b.svg.gz +0 -0
  496. data/public/avo-packs/media/svgs/save-e54acd7ac9646053e36382776f822756.svg.br +0 -0
  497. data/public/avo-packs/media/svgs/save-e54acd7ac9646053e36382776f822756.svg.gz +0 -0
  498. data/public/avo-packs/media/svgs/selector-b43b3957d7cc121d06be14312613c218.svg.br +0 -0
  499. data/public/avo-packs/media/svgs/sort-ascending-f5bc0761702809cab20b0ea3065cb88a.svg.br +0 -0
  500. data/public/avo-packs/media/svgs/sort-descending-1c8ddc56c72be6781e59d808f9d06203.svg.br +0 -0
  501. data/public/avo-packs/media/svgs/switch-horizontal-d23337f0fb533a86d14b746d25ad48ae.svg.br +0 -2
  502. data/public/avo-packs/media/svgs/switch-horizontal-d23337f0fb533a86d14b746d25ad48ae.svg.gz +0 -0
  503. data/public/avo-packs/media/svgs/thumbs-down-44f83eacbf5b8fe0f2f085da75866ce0.svg.br +0 -0
  504. data/public/avo-packs/media/svgs/thumbs-down-44f83eacbf5b8fe0f2f085da75866ce0.svg.gz +0 -0
  505. data/public/avo-packs/media/svgs/thumbs-up-b866900017db179b50d6b19a1424ed25.svg.br +0 -4
  506. data/public/avo-packs/media/svgs/thumbs-up-b866900017db179b50d6b19a1424ed25.svg.gz +0 -0
  507. data/public/avo-packs/media/svgs/times-539256e95a00360c3bbc6160c6b695cd.svg +0 -1
  508. data/public/avo-packs/media/svgs/times-539256e95a00360c3bbc6160c6b695cd.svg.br +0 -0
  509. data/public/avo-packs/media/svgs/times-539256e95a00360c3bbc6160c6b695cd.svg.gz +0 -0
  510. data/public/avo-packs/media/svgs/trash-a61412a066e358bcc24494a5080b7255.svg.br +0 -0
  511. data/public/avo-packs/media/svgs/trash-a61412a066e358bcc24494a5080b7255.svg.gz +0 -0
  512. data/public/avo-packs/media/svgs/view-grid-393669034db69f59497616d5416ae411.svg.br +0 -1
  513. data/public/avo-packs/media/svgs/view-grid-393669034db69f59497616d5416ae411.svg.gz +0 -0
  514. data/public/avo-packs/media/svgs/view-grid-add-d0ee477a044e5d46c0c62af66cb6de77.svg.br +0 -0
  515. data/public/avo-packs/media/svgs/view-grid-add-d0ee477a044e5d46c0c62af66cb6de77.svg.gz +0 -0
  516. data/public/avo-packs/media/svgs/view-list-8a7a159ca5d892f72cf8c6744a2074e2.svg.br +0 -3
  517. data/public/avo-packs/media/svgs/view-list-8a7a159ca5d892f72cf8c6744a2074e2.svg.gz +0 -0
  518. data/public/avo-packs/media/svgs/x-circle-c540f9ccfe937ad9b4f662e0b65e47e2.svg.br +0 -0
  519. data/public/avo-packs/media/svgs/x-circle-c540f9ccfe937ad9b4f662e0b65e47e2.svg.gz +0 -0
@@ -5,7 +5,7 @@ module Avo
5
5
  class PasswordField < TextField
6
6
  def initialize(name, **args, &block)
7
7
  @defaults = {
8
- component: 'password-field',
8
+ partial_name: 'password-field',
9
9
  }
10
10
 
11
11
  show_on :forms
@@ -1,27 +1,50 @@
1
1
  module Avo
2
2
  module Fields
3
3
  class SelectField < Field
4
+ attr_reader :options
5
+ attr_reader :enum
6
+ attr_reader :display_value
7
+
4
8
  def initialize(name, **args, &block)
5
9
  @defaults = {
6
- sortable: true,
7
- component: 'select-field',
10
+ partial_name: 'select-field',
8
11
  }
9
12
 
10
13
  super(name, **args, &block)
11
14
 
12
- @options = args[:options].present? ? args[:options] : {}
15
+ @options = args[:options].present? ? args[:options] : args[:enum]
16
+ @options = ActiveSupport::HashWithIndifferentAccess.new @options
13
17
  @enum = args[:enum].present? ? args[:enum] : nil
14
18
  @display_value = args[:display_value].present? ? args[:display_value] : false
15
19
  @placeholder = args[:placeholder].present? ? args[:placeholder].to_s : I18n.t('avo.choose_an_option')
16
20
  end
17
21
 
18
- def hydrate_field(fields, model, resource, view)
19
- {
20
- options: @options,
21
- enum: @enum,
22
- display_value: @display_value,
23
- placeholder: @placeholder,
24
- }
22
+ def options_for_select
23
+ if enum.present?
24
+ if display_value
25
+ options.invert
26
+ else
27
+ options.map { |label, value| [label, label] }.to_h
28
+ end
29
+ else
30
+ if display_value
31
+ options.map { |label, value| [value, value] }.to_h
32
+ else
33
+ options
34
+ end
35
+ end
36
+ end
37
+
38
+ def label
39
+ if display_value
40
+ value
41
+ else
42
+ if enum.present?
43
+ options[value]
44
+ else
45
+ options.invert[value]
46
+ end
47
+ end
25
48
  end
26
49
  end
27
50
  end
@@ -3,8 +3,7 @@ module Avo
3
3
  class StatusField < Field
4
4
  def initialize(name, **args, &block)
5
5
  @defaults = {
6
- sortable: true,
7
- component: 'status-field',
6
+ partial_name: 'status-field',
8
7
  }
9
8
 
10
9
  super(name, **args, &block)
@@ -13,11 +12,14 @@ module Avo
13
12
  @failed_when = args[:failed_when].present? ? [args[:failed_when]].flatten : [:failed]
14
13
  end
15
14
 
16
- def hydrate_field(fields, model, resource, view)
17
- {
18
- loading_when: @loading_when,
19
- failed_when: @failed_when,
20
- }
15
+ def status
16
+ status = 'success'
17
+ if value.present?
18
+ status = 'failed' if @failed_when.include? value.to_sym
19
+ status = 'loading' if @loading_when.include? value.to_sym
20
+ end
21
+
22
+ status
21
23
  end
22
24
  end
23
25
  end
@@ -3,8 +3,7 @@ module Avo
3
3
  class TextField < Field
4
4
  def initialize(name, **args, &block)
5
5
  @defaults = {
6
- sortable: true,
7
- component: 'text-field',
6
+ partial_name: 'text-field',
8
7
  computable: true,
9
8
  }.merge(@defaults || {})
10
9
 
@@ -12,12 +11,6 @@ module Avo
12
11
 
13
12
  @link_to_resource = args[:link_to_resource].present? ? args[:link_to_resource] : false
14
13
  end
15
-
16
- def hydrate_field(fields, model, resource, view)
17
- {
18
- link_to_resource: @link_to_resource,
19
- }
20
- end
21
14
  end
22
15
  end
23
16
  end
@@ -5,8 +5,7 @@ module Avo
5
5
  class TextareaField < TextField
6
6
  def initialize(name, **args, &block)
7
7
  @defaults = {
8
- sortable: true,
9
- component: 'textarea-field',
8
+ partial_name: 'textarea-field',
10
9
  computable: true,
11
10
  }
12
11
 
@@ -14,13 +13,7 @@ module Avo
14
13
 
15
14
  hide_on :index
16
15
 
17
- @rows = args[:rows].present? ? args[:rows].to_i : 5
18
- end
19
-
20
- def hydrate_field(fields, model, resource, view)
21
- {
22
- rows: @rows
23
- }
16
+ @meta[:rows] = args[:rows].present? ? args[:rows].to_i : 5
24
17
  end
25
18
  end
26
19
  end
@@ -3,9 +3,11 @@ require_relative 'field'
3
3
  module Avo
4
4
  module Fields
5
5
  class TrixField < Field
6
+ attr_reader :always_show
7
+
6
8
  def initialize(name, **args, &block)
7
9
  @defaults = {
8
- component: 'trix-field',
10
+ partial_name: 'trix-field',
9
11
  }
10
12
 
11
13
  super(name, **args, &block)
@@ -14,12 +16,6 @@ module Avo
14
16
 
15
17
  @always_show = args[:always_show].present? ? args[:always_show] : false
16
18
  end
17
-
18
- def hydrate_field(fields, model, resource, view)
19
- {
20
- always_show: @always_show
21
- }
22
- end
23
19
  end
24
20
  end
25
21
  end
@@ -0,0 +1,29 @@
1
+ class Avo::FieldsLoader
2
+ attr_accessor :bag
3
+
4
+ def initialize
5
+ @bag = []
6
+ end
7
+
8
+ def add_field(field)
9
+ @bag.push field
10
+ end
11
+
12
+ def method_missing(method, *args, &block)
13
+ matched_field = Avo::App.fields.find do |field|
14
+ field[:name].to_s == method.to_s
15
+ end
16
+
17
+ if matched_field.present? and matched_field[:class].present?
18
+ klass = matched_field[:class]
19
+
20
+ if block.present?
21
+ field = klass::new(args[0], **args[1] || {}, &block)
22
+ else
23
+ field = klass::new(args[0], **args[1] || {})
24
+ end
25
+
26
+ add_field field
27
+ end
28
+ end
29
+ end
@@ -2,9 +2,9 @@ module Avo
2
2
  class HQ
3
3
  attr_accessor :current_request
4
4
 
5
- ENDPOINT = 'https://avohq.io/api/v1/licenses/check'
6
- CACHE_KEY = 'avo.hq.response'
7
- REQUEST_TIMEOUT = 5 # seconds
5
+ ENDPOINT = 'https://avohq.io/api/v1/licenses/check' unless const_defined?(:ENDPOINT)
6
+ CACHE_KEY = 'avo.hq.response' unless const_defined?(:CACHE_KEY)
7
+ REQUEST_TIMEOUT = 5 unless const_defined?(:REQUEST_TIMEOUT) # seconds
8
8
 
9
9
  def initialize(current_request)
10
10
  @current_request = current_request
@@ -27,7 +27,7 @@ module Avo
27
27
  end
28
28
 
29
29
  def properties
30
- @response.slice 'valid', 'id', 'error'
30
+ @response.slice('valid', 'id', 'error').symbolize_keys
31
31
  end
32
32
 
33
33
  def abilities
@@ -1,107 +1,151 @@
1
- require_relative 'resource_fields'
2
1
  require_relative 'resource_grid_fields'
3
- require_relative 'resource_filters'
4
- require_relative 'resource_actions'
5
2
  require_relative 'fields/field'
6
3
 
7
4
  module Avo
8
5
  module Resources
9
6
  class Resource
10
- attr_reader :required
11
- attr_reader :includes
12
- attr_reader :default_view_type
13
-
14
- class << self
15
- def hydrate_resource(model:, resource:, view: :index, user:)
16
- case view
17
- when :show
18
- panel_name = I18n.t 'avo.resource_details', name: resource.name.downcase.upcase_first
19
- when :edit
20
- panel_name = I18n.t('avo.edit_item', item: resource.name.downcase).upcase_first
21
- when :create
22
- panel_name = I18n.t('avo.create_new_item', item: resource.name.downcase).upcase_first
23
- end
24
-
25
- resource_with_fields = {
26
- id: model.id,
27
- authorization: get_authorization(user, model),
28
- singular_name: resource.singular_name,
29
- plural_name: resource.plural_name,
30
- title: model[resource.title],
31
- translation_key: resource.translation_key,
32
- path: resource.url,
33
- fields: [],
34
- grid_fields: {},
35
- panels: [{
36
- name: panel_name,
37
- component: 'panel',
38
- }]
39
- }
7
+ attr_writer :name
8
+
9
+ attr_accessor :id
10
+ attr_accessor :title
11
+ attr_accessor :search
12
+ attr_accessor :includes
13
+ attr_accessor :translation_key
14
+ attr_accessor :default_view_type
15
+ attr_accessor :devise_password_optional
16
+ attr_accessor :view
17
+ attr_accessor :model
18
+ attr_accessor :user
19
+ attr_accessor :fields_loader
20
+ attr_accessor :grid_loader
21
+ attr_accessor :actions_loader
22
+ attr_accessor :filters_loader
23
+ attr_accessor :params
24
+
25
+ alias :field :fields_loader
26
+ alias :f :field
27
+ alias :g :grid_loader
28
+ alias :action :actions_loader
29
+ alias :a :action
30
+ alias :filter :filters_loader
31
+
32
+ def initialize(request = nil)
33
+ @id = :id
34
+ @title = 'Resource'
35
+ @search = []
36
+ @includes = []
37
+ @translation_key = nil
38
+ @default_view_type = :table
39
+ @devise_password_optional = false
40
+
41
+ configure
42
+ boot_fields request
43
+ end
40
44
 
41
- grid_fields = resource.get_grid_fields
42
- grid_fields_by_required_field = grid_fields.map { |grid_field_id, field| [field.id, grid_field_id] }.to_h
45
+ def boot_fields(request)
46
+ @fields_loader = Avo::FieldsLoader.new
47
+ fields request
43
48
 
44
- resource.get_fields.each do |field|
45
- field_is_required_in_grid_view = grid_fields.map { |grid_field_id, field| field.id }.include?(field.id)
46
- required_in_current_view = field.send("show_on_#{view.to_s}")
49
+ @grid_loader = Avo::FieldsLoader.new
50
+ grid request if self.respond_to? :grid
47
51
 
48
- next unless required_in_current_view or field_is_required_in_grid_view
52
+ @actions_loader = Avo::ActionsLoader.new
53
+ actions request if self.respond_to? :actions
49
54
 
50
- furnished_field = field.fetch_for_resource(model, resource, view)
55
+ @filters_loader = Avo::ActionsLoader.new
56
+ filters request if self.respond_to? :filters
57
+ end
51
58
 
52
- next unless field_resource_authorized field, furnished_field, user
59
+ def hydrate(model: nil, view: nil, user: nil, params: nil)
60
+ @view = view if view.present?
61
+ @user = user if user.present?
62
+ @params = params if params.present?
53
63
 
54
- next if furnished_field.blank?
64
+ if model.present?
65
+ @model = model
55
66
 
56
- furnished_field[:panel_name] = panel_name
57
- furnished_field[:show_on_show] = field.show_on_show
67
+ hydrate_model_with_default_values if @view == :new
68
+ end
58
69
 
59
- if field.has_own_panel?
60
- furnished_field[:panel_name] = field.name.to_s.pluralize
61
- end
70
+ self
71
+ end
62
72
 
63
- if field_is_required_in_grid_view
64
- required_field = grid_fields_by_required_field[field.id]
65
- resource_with_fields[:grid_fields][required_field] = furnished_field
73
+ def get_fields(panel: nil, view_type: :table, reflection: nil)
74
+ case view_type.to_sym
75
+ when :table
76
+ fields = get_field_definitions.select do |field|
77
+ field.send("show_on_#{@view.to_s}")
78
+ end
79
+ .select do |field|
80
+ field.can_see.present? ? field.can_see.call : true
81
+ end
82
+ .select do |field|
83
+ unless field.respond_to?(:foreign_key) &&
84
+ reflection.present? &&
85
+ reflection.respond_to?(:foreign_key) &&
86
+ reflection.foreign_key == field.foreign_key
87
+ true
66
88
  end
67
89
 
68
- if required_in_current_view
69
- resource_with_fields[:fields] << furnished_field
70
- end
71
90
  end
91
+ when :grid
92
+ fields = @grid_loader.bag
93
+ end
72
94
 
73
- resource_with_fields
95
+ if panel.present?
96
+ fields = fields.select do |field|
97
+ field.panel_name == panel
98
+ end
74
99
  end
75
100
 
76
- def show_path(resource)
77
- "/resources/#{resource.class.model_name.plural}/#{resource.id}"
101
+ fields = fields.map do |field|
102
+ field.hydrate(model: @model, view: @view, resource: self)
78
103
  end
79
104
 
80
- def index_path(resource_or_class)
81
- if resource_or_class.class == String
82
- url = resource_or_class.underscore.pluralize
83
- else
84
- url = resource_or_class.class.name.demodulize.underscore.pluralize
85
- end
105
+ fields
106
+ end
86
107
 
87
- "/resources/#{url}"
108
+ def get_field_definitions
109
+ @fields_loader.bag.map do |field|
110
+ field.hydrate(resource: self, panel_name: default_panel_name, user: user)
88
111
  end
112
+ end
113
+
114
+ def default_panel_name
115
+ return @params[:related_name].capitalize if @params[:related_name].present?
89
116
 
90
- def get_authorization(user, model)
91
- [:create, :edit, :update, :show, :destroy].map do |action|
92
- [action, AuthorizationService::authorize_action(user, model, action)]
93
- end.to_h
117
+ case @view
118
+ when :show
119
+ I18n.t('avo.resource_details', item: self.name.downcase, title: model_title).upcase_first
120
+ when :edit
121
+ I18n.t('avo.update_item', item: self.name.downcase, title: model_title).upcase_first
122
+ when :new
123
+ I18n.t('avo.create_new_item', item: self.name.downcase).upcase_first
94
124
  end
125
+ end
126
+
127
+ def panels
128
+ panels = [
129
+ {
130
+ name: default_panel_name,
131
+ type: :fields,
132
+ in_panel: true,
133
+ }
134
+ ]
95
135
 
96
- def field_resource_authorized(field, furnished_field, user)
97
- if [Avo::Fields::HasManyField, Avo::Fields::HasAndBelongsToManyField].include? field.class
98
- return true if furnished_field[:relationship_model].nil?
136
+ panels
137
+ end
99
138
 
100
- AuthorizationService.authorize user, furnished_field[:relationship_model].safe_constantize, Avo.configuration.authorization_methods.stringify_keys['index']
101
- else
102
- true
103
- end
104
- end
139
+ def model_class
140
+ return @model.class if @model.present?
141
+
142
+ self.class.name.demodulize.safe_constantize
143
+ end
144
+
145
+ def model_title
146
+ return @model.send title if @model.present?
147
+
148
+ name
105
149
  end
106
150
 
107
151
  def name
@@ -113,8 +157,6 @@ module Avo
113
157
  end
114
158
 
115
159
  def singular_name
116
- return I18n.t(@translation_key, count: 1).capitalize if @translation_key
117
-
118
160
  name
119
161
  end
120
162
 
@@ -130,56 +172,26 @@ module Avo
130
172
  self.class.name.demodulize.underscore
131
173
  end
132
174
 
133
- def url
134
- return @url if @url.present?
135
-
136
- self.class.name.demodulize.underscore.pluralize
137
- end
138
-
139
- def title
140
- return @title if @title.present?
141
-
142
- 'id'
143
- end
144
-
145
- def translation_key
146
- @translation_key
147
- end
148
-
149
- def model
150
- return @model if @model.present?
151
-
152
- underscore_name.to_s.camelize.singularize
153
- end
154
-
155
- def get_fields
156
- self.class.get_fields
157
- end
158
-
159
- def get_grid_fields
160
- self.class.get_grid_fields
161
- end
162
-
163
175
  def available_view_types
164
- get_grid_fields.length > 0 ? [:grid, :table] : [:table]
176
+ get_fields(view_type: :grid).length > 0 ? [:grid, :table] : [:table]
165
177
  end
166
178
 
167
179
  def get_filters
168
- self.class.get_filters
180
+ @filters_loader.bag
169
181
  end
170
182
 
171
183
  def get_actions
172
- self.class.get_actions
184
+ @actions_loader.bag
173
185
  end
174
186
 
175
- def search
176
- @search
187
+ def route_key
188
+ model_class.model_name.route_key
177
189
  end
178
190
 
179
191
  def query_search(query: '', via_resource_name: , via_resource_id:, user:)
180
- model_class = self.model
192
+ # model_class = self.model
181
193
 
182
- db_query = AuthorizationService.with_policy(user, model_class)
194
+ db_query = AuthorizationService.apply_policy(user, model_class)
183
195
 
184
196
  if via_resource_name.present?
185
197
  related_model = App.get_resource_by_name(via_resource_name).model
@@ -198,25 +210,15 @@ module Avo
198
210
  db_query.where(new_query.join(' '))
199
211
  end
200
212
 
201
- def model
202
- return @model if @model.present?
203
-
204
- self.class.name.demodulize.safe_constantize
205
- end
206
-
207
213
  def attached_file_fields
208
- get_fields.select do |field|
214
+ get_field_definitions.select do |field|
209
215
  [Avo::Fields::FileField, Avo::Fields::FilesField].include? field.class
210
216
  end
211
217
  end
212
218
 
213
- def has_devise_password
214
- @has_devise_password or false
215
- end
216
-
217
219
  def fill_model(model, params)
218
220
  # Map the received params to their actual fields
219
- fields_by_database_id = self.get_fields.map { |field| [field.database_id(model).to_s, field] }.to_h
221
+ fields_by_database_id = self.get_field_definitions.map { |field| [field.database_id(model).to_s, field] }.to_h
220
222
 
221
223
  params.each do |key, value|
222
224
  field = fields_by_database_id[key]
@@ -228,6 +230,62 @@ module Avo
228
230
 
229
231
  model
230
232
  end
233
+
234
+ def authorization
235
+ AuthorizationService.new(user, model)
236
+ end
237
+
238
+ def file_hash
239
+ content_to_be_hashed = ''
240
+
241
+ # resource file hash
242
+ resource_path = Rails.root.join('app', 'avo', 'resources', "#{name.underscore}.rb").to_s
243
+ if File.file? resource_path
244
+ content_to_be_hashed += File.read(resource_path)
245
+ end
246
+
247
+ # policy file hash
248
+ policy_path = Rails.root.join('app', 'policies', "#{name.underscore}_policy.rb").to_s
249
+ if File.file? policy_path
250
+ content_to_be_hashed += File.read(policy_path)
251
+ end
252
+
253
+ Digest::MD5.hexdigest(content_to_be_hashed)
254
+ end
255
+
256
+ # For :new views we're hydrating the model with the values from the resource's default attribute.
257
+ # We will not overwrite any attributes that come pre-filled in the model.
258
+ def hydrate_model_with_default_values
259
+ default_values = get_fields.select do |field|
260
+ !field.computed
261
+ end
262
+ .map do |field|
263
+ id = field.id
264
+ value = field.value
265
+
266
+ if field.respond_to? :foreign_key
267
+ id = field.foreign_key.to_sym
268
+
269
+ reflection = @model._reflections[@params[:via_relation]]
270
+
271
+ if reflection.present? && reflection.foreign_key.present?
272
+ value = @params[:via_resource_id]
273
+ end
274
+ end
275
+
276
+ [id, value]
277
+ end
278
+ .to_h
279
+ .select do |id, value|
280
+ value.present?
281
+ end
282
+
283
+ default_values.each do |id, value|
284
+ if @model.send(id).nil?
285
+ @model.send("#{id}=", value)
286
+ end
287
+ end
288
+ end
231
289
  end
232
290
  end
233
291
  end