releaf-core 0.2.1

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 (288) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +24 -0
  3. data/app/assets/fonts/releaf/RobotoRegular_normal_400.ttf +0 -0
  4. data/app/assets/fonts/releaf/RobotoRegular_normal_400.woff +0 -0
  5. data/app/assets/fonts/releaf/RobotoRegular_normal_400.woff2 +0 -0
  6. data/app/assets/images/releaf/icons/apple-touch-icon-114x114-precomposed.png +0 -0
  7. data/app/assets/images/releaf/icons/apple-touch-icon-152x152-precomposed.png +0 -0
  8. data/app/assets/images/releaf/icons/apple-touch-icon-72x72-precomposed.png +0 -0
  9. data/app/assets/images/releaf/icons/favicon.ico +0 -0
  10. data/app/assets/images/releaf/icons/favicon.png +0 -0
  11. data/app/assets/images/releaf/icons/msapplication-tile-144x144.png +0 -0
  12. data/app/assets/images/releaf/logo-login.png +0 -0
  13. data/app/assets/images/releaf/logo.png +0 -0
  14. data/app/assets/javascripts/ckeditor/plugins/mediaembed/icons/hidpi/mediaembed.png +0 -0
  15. data/app/assets/javascripts/ckeditor/plugins/mediaembed/icons/mediaembed.png +0 -0
  16. data/app/assets/javascripts/ckeditor/plugins/mediaembed/lang/en.js +12 -0
  17. data/app/assets/javascripts/ckeditor/plugins/mediaembed/lang/es.js +12 -0
  18. data/app/assets/javascripts/ckeditor/plugins/mediaembed/plugin.js +63 -0
  19. data/app/assets/javascripts/releaf/3rd_party/jquery-ui-timepicker-addon.js +1882 -0
  20. data/app/assets/javascripts/releaf/3rd_party/jquery.magnific-popup.min.js +4 -0
  21. data/app/assets/javascripts/releaf/application.js +13 -0
  22. data/app/assets/javascripts/releaf/include/ajax.js +66 -0
  23. data/app/assets/javascripts/releaf/include/ajaxbox.js +179 -0
  24. data/app/assets/javascripts/releaf/include/dialogs.js +13 -0
  25. data/app/assets/javascripts/releaf/include/field.type_associated_set.js +32 -0
  26. data/app/assets/javascripts/releaf/include/field.type_date_or_datetime_or_time.js +73 -0
  27. data/app/assets/javascripts/releaf/include/field.type_richtext.js +188 -0
  28. data/app/assets/javascripts/releaf/include/loader.js +45 -0
  29. data/app/assets/javascripts/releaf/include/localization.js +213 -0
  30. data/app/assets/javascripts/releaf/include/nested_fields.js +295 -0
  31. data/app/assets/javascripts/releaf/include/notifications.js +267 -0
  32. data/app/assets/javascripts/releaf/include/pagination.js +19 -0
  33. data/app/assets/javascripts/releaf/include/profile_settings.js +28 -0
  34. data/app/assets/javascripts/releaf/include/remote_validator.js +437 -0
  35. data/app/assets/javascripts/releaf/include/search.js +140 -0
  36. data/app/assets/javascripts/releaf/include/sidebar.js +149 -0
  37. data/app/assets/javascripts/releaf/include/sortable.js +69 -0
  38. data/app/assets/javascripts/releaf/include/toolbox.js +221 -0
  39. data/app/assets/javascripts/releaf/include/url_builder.js +193 -0
  40. data/app/assets/stylesheets/releaf/application.scss +9 -0
  41. data/app/assets/stylesheets/releaf/environment/extras.scss +11 -0
  42. data/app/assets/stylesheets/releaf/environment/functions/units.scss +12 -0
  43. data/app/assets/stylesheets/releaf/environment/functions.scss +1 -0
  44. data/app/assets/stylesheets/releaf/environment/mixins/blocks.scss +133 -0
  45. data/app/assets/stylesheets/releaf/environment/mixins/elements.scss +64 -0
  46. data/app/assets/stylesheets/releaf/environment/mixins/text.scss +61 -0
  47. data/app/assets/stylesheets/releaf/environment/mixins.scss +3 -0
  48. data/app/assets/stylesheets/releaf/environment/variables/colors.scss +93 -0
  49. data/app/assets/stylesheets/releaf/environment/variables/dimensions.scss +0 -0
  50. data/app/assets/stylesheets/releaf/environment/variables/magnific-popup.scss +6 -0
  51. data/app/assets/stylesheets/releaf/environment/variables.scss +5 -0
  52. data/app/assets/stylesheets/releaf/environment.scss +4 -0
  53. data/app/assets/stylesheets/releaf/layout/base.scss +32 -0
  54. data/app/assets/stylesheets/releaf/layout/breadcrumbs.scss +47 -0
  55. data/app/assets/stylesheets/releaf/layout/buttons.scss +107 -0
  56. data/app/assets/stylesheets/releaf/layout/deprecated.scss +29 -0
  57. data/app/assets/stylesheets/releaf/layout/dialogs.scss +138 -0
  58. data/app/assets/stylesheets/releaf/layout/errors.scss +28 -0
  59. data/app/assets/stylesheets/releaf/layout/extras.scss +10 -0
  60. data/app/assets/stylesheets/releaf/layout/fields.scss +305 -0
  61. data/app/assets/stylesheets/releaf/layout/fonts.scss +16 -0
  62. data/app/assets/stylesheets/releaf/layout/footer.scss +80 -0
  63. data/app/assets/stylesheets/releaf/layout/forms.scss +23 -0
  64. data/app/assets/stylesheets/releaf/layout/header.scss +55 -0
  65. data/app/assets/stylesheets/releaf/layout/icons.scss +4 -0
  66. data/app/assets/stylesheets/releaf/layout/images.scss +4 -0
  67. data/app/assets/stylesheets/releaf/layout/links.scss +7 -0
  68. data/app/assets/stylesheets/releaf/layout/localization.scss +79 -0
  69. data/app/assets/stylesheets/releaf/layout/main.scss +43 -0
  70. data/app/assets/stylesheets/releaf/layout/notifications.scss +67 -0
  71. data/app/assets/stylesheets/releaf/layout/pagination.scss +18 -0
  72. data/app/assets/stylesheets/releaf/layout/search.scss +70 -0
  73. data/app/assets/stylesheets/releaf/layout/sections.scss +138 -0
  74. data/app/assets/stylesheets/releaf/layout/sidebar.scss +306 -0
  75. data/app/assets/stylesheets/releaf/layout/tables.scss +99 -0
  76. data/app/assets/stylesheets/releaf/layout/text.scss +31 -0
  77. data/app/assets/stylesheets/releaf/layout/toolboxes.scss +69 -0
  78. data/app/assets/stylesheets/releaf/layout.scss +35 -0
  79. data/app/assets/stylesheets/releaf/vendor/magnific-popup/main.scss +596 -0
  80. data/app/assets/stylesheets/releaf/vendor/magnific-popup/settings.scss +45 -0
  81. data/app/builders/releaf/builders/association_reflector.rb +58 -0
  82. data/app/builders/releaf/builders/base.rb +80 -0
  83. data/app/builders/releaf/builders/collection.rb +8 -0
  84. data/app/builders/releaf/builders/confirm_destroy_dialog_builder.rb +25 -0
  85. data/app/builders/releaf/builders/confirm_dialog_builder.rb +54 -0
  86. data/app/builders/releaf/builders/edit_builder.rb +66 -0
  87. data/app/builders/releaf/builders/form_builder.rb +594 -0
  88. data/app/builders/releaf/builders/index_builder.rb +118 -0
  89. data/app/builders/releaf/builders/orderer.rb +5 -0
  90. data/app/builders/releaf/builders/page/header_builder.rb +70 -0
  91. data/app/builders/releaf/builders/page/layout_builder.rb +155 -0
  92. data/app/builders/releaf/builders/page/menu_builder.rb +140 -0
  93. data/app/builders/releaf/builders/pagination_builder.rb +107 -0
  94. data/app/builders/releaf/builders/refused_destroy_dialog_builder.rb +68 -0
  95. data/app/builders/releaf/builders/resource.rb +9 -0
  96. data/app/builders/releaf/builders/resource_dialog.rb +8 -0
  97. data/app/builders/releaf/builders/resource_view.rb +54 -0
  98. data/app/builders/releaf/builders/show_builder.rb +3 -0
  99. data/app/builders/releaf/builders/table_builder.rb +280 -0
  100. data/app/builders/releaf/builders/tags/releaf_associated_set_field.rb +40 -0
  101. data/app/builders/releaf/builders/template.rb +8 -0
  102. data/app/builders/releaf/builders/toolbox.rb +23 -0
  103. data/app/builders/releaf/builders/toolbox_builder.rb +27 -0
  104. data/app/builders/releaf/builders/view.rb +132 -0
  105. data/app/builders/releaf/builders.rb +38 -0
  106. data/app/builders/releaf/core/settings/form_builder.rb +21 -0
  107. data/app/builders/releaf/core/settings/table_builder.rb +11 -0
  108. data/app/controllers/concerns/releaf/breadcrumbs.rb +42 -0
  109. data/app/controllers/concerns/releaf/richtext_attachments.rb +20 -0
  110. data/app/controllers/releaf/base_controller.rb +458 -0
  111. data/app/controllers/releaf/core/errors_controller.rb +5 -0
  112. data/app/controllers/releaf/core/settings_controller.rb +50 -0
  113. data/app/helpers/releaf/application_helper.rb +53 -0
  114. data/app/helpers/releaf/button_helper.rb +50 -0
  115. data/app/helpers/releaf/javascript_helper.rb +75 -0
  116. data/app/lib/releaf/core/assets_resolver.rb +58 -0
  117. data/app/lib/releaf/core/default_searchable_fields.rb +43 -0
  118. data/app/lib/releaf/core/error_formatter.rb +103 -0
  119. data/app/lib/releaf/core/item_orderer.rb +102 -0
  120. data/app/lib/releaf/core/resource_base.rb +66 -0
  121. data/app/lib/releaf/core/resource_fields.rb +6 -0
  122. data/app/lib/releaf/core/resource_params.rb +47 -0
  123. data/app/lib/releaf/core/resource_table_fields.rb +10 -0
  124. data/app/lib/releaf/core/resource_utilities.rb +36 -0
  125. data/app/lib/releaf/core/responders/access_denied_responder.rb +9 -0
  126. data/app/lib/releaf/core/responders/after_save_responder.rb +28 -0
  127. data/app/lib/releaf/core/responders/confirm_destroy_responder.rb +13 -0
  128. data/app/lib/releaf/core/responders/destroy_responder.rb +10 -0
  129. data/app/lib/releaf/core/responders/error_responder.rb +9 -0
  130. data/app/lib/releaf/core/responders/feature_disabled_responder.rb +9 -0
  131. data/app/lib/releaf/core/responders/page_not_found_responder.rb +9 -0
  132. data/app/lib/releaf/core/responders.rb +31 -0
  133. data/app/lib/releaf/core/search.rb +147 -0
  134. data/app/lib/releaf/core/template_field_type_mapper.rb +127 -0
  135. data/app/models/releaf/richtext_attachment.rb +6 -0
  136. data/app/models/releaf/settings.rb +27 -0
  137. data/app/views/layouts/releaf/admin.html.erb +1 -0
  138. data/app/views/releaf/base/confirm_destroy.ruby +1 -0
  139. data/app/views/releaf/base/create_releaf_richtext_attachment.haml +1 -0
  140. data/app/views/releaf/base/edit.ruby +1 -0
  141. data/app/views/releaf/base/index.ruby +1 -0
  142. data/app/views/releaf/base/new.ruby +1 -0
  143. data/app/views/releaf/base/refused_destroy.ruby +1 -0
  144. data/app/views/releaf/base/show.ruby +1 -0
  145. data/app/views/releaf/base/toolbox.ruby +1 -0
  146. data/app/views/releaf/error_pages/_error.html.haml +10 -0
  147. data/app/views/releaf/error_pages/access_denied.html.haml +1 -0
  148. data/app/views/releaf/error_pages/feature_disabled.html.haml +1 -0
  149. data/app/views/releaf/error_pages/page_not_found.html.haml +2 -0
  150. data/lib/generators/dummy/install_generator.rb +18 -0
  151. data/lib/generators/dummy/templates/builders/admin/books/form_builder.rb +13 -0
  152. data/lib/generators/dummy/templates/builders/admin/books/index_builder.rb +30 -0
  153. data/lib/generators/dummy/templates/builders/admin/books/table_builder.rb +7 -0
  154. data/lib/generators/dummy/templates/builders/admin/nodes/form_builder.rb +7 -0
  155. data/lib/generators/dummy/templates/config/routes.rb +19 -0
  156. data/lib/generators/dummy/templates/controllers/admin/authors_controller.rb +12 -0
  157. data/lib/generators/dummy/templates/controllers/admin/books_controller.rb +17 -0
  158. data/lib/generators/dummy/templates/controllers/admin/chapters_controller.rb +3 -0
  159. data/lib/generators/dummy/templates/controllers/admin/publishers_controller.rb +3 -0
  160. data/lib/generators/dummy/templates/controllers/application_controller.rb +39 -0
  161. data/lib/generators/dummy/templates/controllers/concerns/.keep +0 -0
  162. data/lib/generators/dummy/templates/controllers/concerns/node_controller.rb +37 -0
  163. data/lib/generators/dummy/templates/controllers/contacts_controller.rb +3 -0
  164. data/lib/generators/dummy/templates/controllers/home_pages_controller.rb +3 -0
  165. data/lib/generators/dummy/templates/controllers/text_pages_controller.rb +3 -0
  166. data/lib/generators/dummy/templates/initializers/releaf.rb +35 -0
  167. data/lib/generators/dummy/templates/migrations/create_authors.rb +14 -0
  168. data/lib/generators/dummy/templates/migrations/create_banners.rb +11 -0
  169. data/lib/generators/dummy/templates/migrations/create_book_sequels.rb +14 -0
  170. data/lib/generators/dummy/templates/migrations/create_books.rb +27 -0
  171. data/lib/generators/dummy/templates/migrations/create_bundles.rb +7 -0
  172. data/lib/generators/dummy/templates/migrations/create_chapters.rb +13 -0
  173. data/lib/generators/dummy/templates/migrations/create_home_pages.rb +9 -0
  174. data/lib/generators/dummy/templates/migrations/create_node_extra_fields.rb +5 -0
  175. data/lib/generators/dummy/templates/migrations/create_publishers.rb +8 -0
  176. data/lib/generators/dummy/templates/migrations/create_text_pages.rb +9 -0
  177. data/lib/generators/dummy/templates/models/author.rb +10 -0
  178. data/lib/generators/dummy/templates/models/banner.rb +5 -0
  179. data/lib/generators/dummy/templates/models/book.rb +19 -0
  180. data/lib/generators/dummy/templates/models/book_sequel.rb +4 -0
  181. data/lib/generators/dummy/templates/models/bundle.rb +17 -0
  182. data/lib/generators/dummy/templates/models/chapter.rb +7 -0
  183. data/lib/generators/dummy/templates/models/home_page.rb +5 -0
  184. data/lib/generators/dummy/templates/models/node.rb +10 -0
  185. data/lib/generators/dummy/templates/models/publisher.rb +9 -0
  186. data/lib/generators/dummy/templates/models/text_page.rb +5 -0
  187. data/lib/generators/dummy/templates/views/contacts/show.html.haml +1 -0
  188. data/lib/generators/dummy/templates/views/home_pages/show.haml +1 -0
  189. data/lib/generators/dummy/templates/views/layouts/application.html.haml +22 -0
  190. data/lib/generators/dummy/templates/views/text_pages/show.haml +1 -0
  191. data/lib/generators/releaf/install_generator.rb +93 -0
  192. data/lib/generators/releaf/templates/initializers/haml.rb +1 -0
  193. data/lib/generators/releaf/templates/initializers/releaf.rb +30 -0
  194. data/lib/generators/releaf/templates/migrations/create_releaf_nodes.rb +28 -0
  195. data/lib/generators/releaf/templates/migrations/create_releaf_permissions.rb +12 -0
  196. data/lib/generators/releaf/templates/migrations/create_releaf_richtext_attachments.rb +12 -0
  197. data/lib/generators/releaf/templates/migrations/create_releaf_roles.rb +9 -0
  198. data/lib/generators/releaf/templates/migrations/create_releaf_settings.rb +17 -0
  199. data/lib/generators/releaf/templates/migrations/create_releaf_translations.rb +21 -0
  200. data/lib/generators/releaf/templates/migrations/create_releaf_users.rb +52 -0
  201. data/lib/generators/releaf/templates/models/node.rb +3 -0
  202. data/lib/generators/releaf/templates/seeds/seeds.rb +54 -0
  203. data/lib/releaf/core/application.rb +17 -0
  204. data/lib/releaf/core/builders_autoload.rb +27 -0
  205. data/lib/releaf/core/component.rb +9 -0
  206. data/lib/releaf/core/configuration.rb +101 -0
  207. data/lib/releaf/core/engine.rb +35 -0
  208. data/lib/releaf/core/exceptions.rb +38 -0
  209. data/lib/releaf/core/route_mapper.rb +59 -0
  210. data/lib/releaf/core/settings_ui_component.rb +7 -0
  211. data/lib/releaf/core/validation_error_codes.rb +36 -0
  212. data/lib/releaf/version.rb +3 -0
  213. data/lib/releaf-core.rb +14 -0
  214. data/lib/tasks/releaf_tasks.rake +4 -0
  215. data/releaf-core.gemspec +35 -0
  216. data/spec/builders/builders/association_reflector_spec.rb +138 -0
  217. data/spec/builders/builders/base_spec.rb +276 -0
  218. data/spec/builders/builders/collection_spec.rb +18 -0
  219. data/spec/builders/builders/confirm_destroy_dialog_builder_spec.rb +71 -0
  220. data/spec/builders/builders/confirm_dialog_builder_spec.rb +105 -0
  221. data/spec/builders/builders/edit_builder_spec.rb +215 -0
  222. data/spec/builders/builders/form_builder_spec.rb +562 -0
  223. data/spec/builders/builders/index_builder_spec.rb +345 -0
  224. data/spec/builders/builders/orderer_spec.rb +22 -0
  225. data/spec/builders/builders/page/header_builder_spec.rb +143 -0
  226. data/spec/builders/builders/page/layout_builder_spec.rb +73 -0
  227. data/spec/builders/builders/page/menu_builder_spec.rb +160 -0
  228. data/spec/builders/builders/pagination_builder_spec.rb +330 -0
  229. data/spec/builders/builders/resource_dialog_spec.rb +21 -0
  230. data/spec/builders/builders/resource_view_spec.rb +158 -0
  231. data/spec/builders/builders/show_builder_spec.rb +7 -0
  232. data/spec/builders/builders/table_builder_spec.rb +638 -0
  233. data/spec/builders/builders/template_spec.rb +12 -0
  234. data/spec/builders/builders/toolbox_builder_spec.rb +67 -0
  235. data/spec/builders/builders/toolbox_spec.rb +48 -0
  236. data/spec/builders/builders/view_spec.rb +281 -0
  237. data/spec/builders/builders_spec.rb +134 -0
  238. data/spec/builders/core/settings/form_builder_spec.rb +69 -0
  239. data/spec/builders/core/settings/table_builder_spec.rb +21 -0
  240. data/spec/controllers/concerns/releaf/richtext_attachments_spec.rb +51 -0
  241. data/spec/controllers/releaf/base_controller_spec.rb +447 -0
  242. data/spec/controllers/releaf/core/settings_controller_spec.rb +31 -0
  243. data/spec/features/ajaxbox_spec.rb +111 -0
  244. data/spec/features/authorization_spec.rb +50 -0
  245. data/spec/features/dragonfly_integration_spec.rb +24 -0
  246. data/spec/features/edit_actions_spec.rb +142 -0
  247. data/spec/features/errors_spec.rb +29 -0
  248. data/spec/features/index_actions_spec.rb +85 -0
  249. data/spec/features/index_table_spec.rb +32 -0
  250. data/spec/features/menu_spec.rb +71 -0
  251. data/spec/features/richtext_attachments_spec.rb +64 -0
  252. data/spec/features/richtext_embed_spec.rb +29 -0
  253. data/spec/features/richtext_spec.rb +19 -0
  254. data/spec/features/search_spec.rb +825 -0
  255. data/spec/features/settings_spec.rb +38 -0
  256. data/spec/features/title_spec.rb +13 -0
  257. data/spec/fixtures/common_fields.yml +17 -0
  258. data/spec/fixtures/cs.png +0 -0
  259. data/spec/fixtures/time.formats.xlsx +0 -0
  260. data/spec/fixtures/unicorn.jpg +0 -0
  261. data/spec/helpers/application_helper_spec.rb +75 -0
  262. data/spec/helpers/button_helper_spec.rb +146 -0
  263. data/spec/lib/releaf/core/application_spec.rb +42 -0
  264. data/spec/lib/releaf/core/assets_resolver_spec.rb +113 -0
  265. data/spec/lib/releaf/core/configuration_spec.rb +230 -0
  266. data/spec/lib/releaf/core/default_searchable_fields_spec.rb +161 -0
  267. data/spec/lib/releaf/core/error_formatter_spec.rb +242 -0
  268. data/spec/lib/releaf/core/item_orderer_spec.rb +142 -0
  269. data/spec/lib/releaf/core/resource_base_spec.rb +174 -0
  270. data/spec/lib/releaf/core/resource_fields_spec.rb +12 -0
  271. data/spec/lib/releaf/core/resource_params_spec.rb +117 -0
  272. data/spec/lib/releaf/core/resource_table_fields_spec.rb +18 -0
  273. data/spec/lib/releaf/core/resource_utilities_spec.rb +87 -0
  274. data/spec/lib/releaf/core/responders/access_denied_responder_spec.rb +12 -0
  275. data/spec/lib/releaf/core/responders/after_save_responder_spec.rb +102 -0
  276. data/spec/lib/releaf/core/responders/confirm_destroy_responder_spec.rb +26 -0
  277. data/spec/lib/releaf/core/responders/destroy_responder_spec.rb +30 -0
  278. data/spec/lib/releaf/core/responders/error_responder_spec.rb +26 -0
  279. data/spec/lib/releaf/core/responders/feature_disabled_responder_spec.rb +12 -0
  280. data/spec/lib/releaf/core/responders/page_not_found_responder_spec.rb +12 -0
  281. data/spec/lib/releaf/core/responders_spec.rb +60 -0
  282. data/spec/lib/releaf/core/template_field_type_mapper_spec.rb +311 -0
  283. data/spec/lib/validation_error_codes_spec.rb +56 -0
  284. data/spec/misc/factories_spec.rb +43 -0
  285. data/spec/models/settings_spec.rb +58 -0
  286. data/spec/routing/route_mapper_spec.rb +185 -0
  287. data/spec/rspec_helpers/test_helpers_spec.rb +20 -0
  288. metadata +657 -0
@@ -0,0 +1,5 @@
1
+ class Releaf::Core::ErrorsController < Releaf::BaseController
2
+ def page_not_found
3
+ respond_with(nil, responder: action_responder(:page_not_found))
4
+ end
5
+ end
@@ -0,0 +1,50 @@
1
+ class Releaf::Core::SettingsController < ::Releaf::BaseController
2
+
3
+ def self.resource_class
4
+ ::Releaf::Settings
5
+ end
6
+
7
+ def resources
8
+ super.where(thing_type: nil, var: resource_class.registered_keys)
9
+ end
10
+
11
+ def normalize_value(value)
12
+ case resource_class.registry[@resource.var][:type]
13
+ when :boolean
14
+ value == '1'
15
+ when :date
16
+ Date.parse(value)
17
+ when :time
18
+ Time.parse(value)
19
+ when :datetime
20
+ DateTime.parse(value)
21
+ when :integer
22
+ value.to_i
23
+ when :float
24
+ value.to_s.sub(",", ".").to_f
25
+ when :decimal
26
+ value.to_s.sub(",", ".").to_d
27
+ else
28
+ value
29
+ end
30
+ end
31
+
32
+ def searchable_fields
33
+ [:var]
34
+ end
35
+
36
+ protected
37
+
38
+ def prepare_update
39
+ @resource = resource_class.find(params[:id]) unless resource_given?
40
+ params[:resource][:value] = normalize_value(params[:resource][:value])
41
+ end
42
+
43
+ def setup
44
+ super
45
+ @features = {
46
+ edit: true,
47
+ index: true,
48
+ }
49
+ end
50
+ end
@@ -0,0 +1,53 @@
1
+ module Releaf
2
+ module ApplicationHelper
3
+ def merge_attributes(a, b)
4
+ if a.key?(:class) || b.key?(:class)
5
+ classes = {class: [a[:class], b[:class]].flatten.reject(&:blank?)}
6
+ else
7
+ classes = {}
8
+ end
9
+
10
+ a.deep_merge(b).merge(classes)
11
+ end
12
+
13
+ def releaf_table(collection, resource_class, options = {})
14
+ builder_class = options[:builder]
15
+ options.delete(:builder)
16
+ builder_class.new(collection, resource_class, self, options).output
17
+ end
18
+
19
+ def translate(key, options = {})
20
+ # prevent I18n from raising errors when translation is missing
21
+ options.merge!(raise: false) unless options.key?(:raise)
22
+ super(key, options)
23
+ end
24
+ alias :t :translate
25
+
26
+ def i18n_options_for_select container, selected, prefix, i18n_options={}
27
+ i18n_options = { scope: controller_scope_name }.merge(i18n_options)
28
+
29
+ translated_container = []
30
+
31
+ container.each do|element|
32
+ text, value = i18n_option_text_and_value(element).map { |item| item.to_s }
33
+ text = I18n.t("#{prefix.to_s}-#{text}", i18n_options.merge(default: text))
34
+ translated_container << [text, value]
35
+ end
36
+
37
+ return options_for_select(translated_container, selected)
38
+ end
39
+
40
+ private
41
+
42
+ def i18n_option_text_and_value(option)
43
+ # Options are [text, value] pairs or strings used for both.
44
+ if !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last)
45
+ option = option.reject { |e| Hash === e } if Array === option
46
+ [option.first, option.last]
47
+ else
48
+ [option, option]
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,50 @@
1
+ module Releaf
2
+ module ButtonHelper
3
+
4
+ def releaf_button(text, icon, attributes = {})
5
+ attributes = releaf_button_attributes( text, icon, attributes )
6
+ tag = attributes.key?(:href) ? :a : :button
7
+ content_tag(tag, attributes) do
8
+ releaf_button_content( text, icon, attributes )
9
+ end
10
+ end
11
+
12
+
13
+ def releaf_button_attributes( text, icon, attributes = {} )
14
+ default_attributes = {
15
+ class: ["button"],
16
+ title: text
17
+ }
18
+
19
+ unless attributes.key? :href
20
+ default_attributes[:type] = :button
21
+ default_attributes[:autocomplete] = "off"
22
+ end
23
+
24
+ if icon.present?
25
+ icon_class = (text.present?) ? "with-icon" : "only-icon"
26
+ default_attributes[:class] << icon_class
27
+ end
28
+
29
+ merge_attributes(default_attributes, attributes)
30
+ end
31
+
32
+
33
+ def releaf_button_content( text, icon, attributes = {} )
34
+ if text.blank? && icon.present?
35
+ raise ArgumentError, "Title is required for icon-only buttons" if attributes[:title].blank?
36
+ end
37
+
38
+ html = "".html_safe
39
+ html << fa_icon(icon) if icon.present?
40
+ html << text if text.present?
41
+
42
+ if html.length < 1
43
+ raise ArgumentError, "Either text or icon is required for buttons"
44
+ end
45
+
46
+ html
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,75 @@
1
+ module Releaf
2
+ module JavascriptHelper
3
+
4
+ # converts date format used by ruby to dateformat used by jquery (when possible)
5
+ #
6
+ # references:
7
+ # http://www.ruby-doc.org/core-2.0/Time.html#strftime-method
8
+ # http://api.jqueryui.com/datepicker/#utility-formatDate
9
+ # http://trentrichardson.com/examples/timepicker/#tp-formatting
10
+ def jquery_date_format date_format
11
+
12
+ raise ArgumentError, "date_format is not a string" unless date_format.is_a? String
13
+
14
+ ruby2jquery = {
15
+ '%' => '%',
16
+ '-d' => 'd',
17
+ '-j' => 'o',
18
+ '-m' => 'm',
19
+ '3N' => 'l',
20
+ ':z' => 'Z',
21
+ 'A' => nil,
22
+ 'B' => 'MM',
23
+ 'C' => nil,
24
+ 'D' => 'mm/dd/y',
25
+ 'F' => 'yy-mm-dd',
26
+ 'G' => nil,
27
+ 'H' => 'HH',
28
+ 'I' => 'h',
29
+ 'L' => 'l',
30
+ 'M' => 'mm',
31
+ 'P' => 'tt',
32
+ 'R' => 'HH:mm',
33
+ 'S' => 'ss',
34
+ 'T' => 'HH:mm:ss',
35
+ 'U' => nil,
36
+ 'V' => nil,
37
+ 'W' => nil,
38
+ 'X' => 'HH:mm:ss',
39
+ 'Y' => 'yy',
40
+ 'Z' => nil,
41
+ '_m' => 'm',
42
+ 'a' => nil,
43
+ 'b' => 'M',
44
+ 'c' => 'M d HH:mm:ss yy', # not exact translation
45
+ 'd' => 'dd',
46
+ 'e' => 'd',
47
+ 'g' => nil,
48
+ 'h' => 'M',
49
+ 'j' => 'oo',
50
+ 'k' => 'H',
51
+ 'l' => 'hh',
52
+ 'm' => 'mm',
53
+ 'n' => nil,
54
+ 'p' => 'TT',
55
+ 'r' => 'h:mm:ss TT',
56
+ 's' => '@',
57
+ 't' => nil,
58
+ 'u' => nil,
59
+ 'v' => nil,
60
+ 'w' => nil,
61
+ 'x' => 'mm/dd/y',
62
+ 'y' => 'y',
63
+ 'z' => nil
64
+ }
65
+
66
+ match_regexp = Regexp.new "%( #{ruby2jquery.reject { |k,v| v.nil? }.keys.join('|') })"
67
+ jquery_date_format = date_format.gsub(match_regexp) do |match|
68
+ ruby2jquery[match[1..-1]]
69
+ end
70
+
71
+ return jquery_date_format
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,58 @@
1
+ module Releaf::Core
2
+ class AssetsResolver
3
+ NONCOMPILED_PATTERN = /app\/assets\/(javascripts|stylesheets)\/((releaf\/)?controllers\/(.*?))\..*/
4
+ COMPILED_PATTERN = /(releaf\/)?controllers\/(.*?)\.(js|css)$/
5
+
6
+ def self.base_assets
7
+ ["releaf/application"]
8
+ end
9
+
10
+ def self.controller_assets(controller, type)
11
+ base_assets + assets.fetch(controller, {}).fetch(type, [])
12
+ end
13
+
14
+ def self.noncompiled_assets
15
+ list = {}
16
+
17
+ Rails.application.assets.each_file do|file|
18
+ match = file.to_s.match(NONCOMPILED_PATTERN)
19
+ if match
20
+ controller = match[4]
21
+ asset_type = match[1].to_sym
22
+ list[controller] ||= {stylesheets: [], javascripts: []}
23
+ list[controller][asset_type] << match[2]
24
+ end
25
+ end
26
+
27
+ list
28
+ end
29
+
30
+ def self.compiled_assets
31
+ list = {}
32
+
33
+ Rails.application.assets_manifest.files.each_pair do|asset_path, asset|
34
+ match = asset["logical_path"].match(COMPILED_PATTERN)
35
+ if match
36
+ controller = match[2]
37
+ asset_type = match[3] == "css" ? :stylesheets : :javascripts
38
+ list[controller] ||= {stylesheets: [], javascripts: []}
39
+ list[controller][asset_type] << asset["logical_path"]
40
+ end
41
+ end
42
+
43
+ list
44
+ end
45
+
46
+ def self.compiled_assets?
47
+ Rails.application.assets.nil?
48
+ end
49
+
50
+ def self.assets
51
+ if compiled_assets?
52
+ @@compiled_assets ||= compiled_assets
53
+ else
54
+ noncompiled_assets
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,43 @@
1
+ module Releaf::Core
2
+ class DefaultSearchableFields
3
+ attr_accessor :klass
4
+
5
+ def initialize(klass)
6
+ self.klass = klass
7
+ end
8
+
9
+ def find
10
+ search_columns = possible_field_names & string_columns
11
+ search_columns << { translations: searchable_translated_string_columns } if has_searchable_translated_string_columns?
12
+ search_columns
13
+ end
14
+
15
+ def string_columns
16
+ klass.columns.select { |column| column.type == :string }.map(&:name)
17
+ end
18
+
19
+ def searchable_translated_string_columns
20
+ @searchable_translated_string_columns ||= self.class.new(klass::Translation).find
21
+ end
22
+
23
+ def has_searchable_translated_string_columns?
24
+ return false unless klass.translates?
25
+ searchable_translated_string_columns.present?
26
+ end
27
+
28
+ def possible_field_names
29
+ %w[
30
+ email
31
+ first_name
32
+ forename
33
+ last_name
34
+ login
35
+ middle_name
36
+ name
37
+ surname
38
+ title
39
+ username
40
+ ]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,103 @@
1
+ module Releaf::Core
2
+ class ErrorFormatter
3
+ attr_reader :errors
4
+
5
+ def self.format_errors(resource, field_name_prefix = "resource")
6
+ validator = new(resource, field_name_prefix)
7
+ validator.errors
8
+ end
9
+
10
+ def initialize(resource, field_name_prefix)
11
+ @resource = resource
12
+ @klass = @resource.class
13
+ @field_name_prefix = field_name_prefix
14
+ @errors = {}
15
+ @error_message_i18n_scope = "activerecord.errors.messages.#{@klass.name.underscore}"
16
+ format_errors
17
+ end
18
+
19
+ private
20
+
21
+ def format_errors
22
+ @resource.errors.each do |attribute, message|
23
+ if models_attribute? attribute
24
+ add_error attribute, message
25
+ else
26
+ process_nested_resource_errors attribute
27
+ end
28
+ end
29
+ end
30
+
31
+ def process_nested_resource_errors(attribute)
32
+ association_name = attribute.to_s.split('.', 2).first
33
+ if single_association? association_name
34
+ prefix_template = "#{@field_name_prefix}[#{association_name}_attributes]"
35
+ nested_resources = [@resource.send(association_name)]
36
+ else
37
+ prefix_template = "#{@field_name_prefix}[#{association_name}_attributes][%d]"
38
+ nested_resources = @resource.send(association_name)
39
+ end
40
+
41
+ nested_resources.each_with_index do |resource, i|
42
+ prefix = prefix_template % i
43
+ resource_errors = ErrorFormatter.format_errors(resource, prefix)
44
+ @errors.merge!(resource_errors)
45
+ end
46
+ end
47
+
48
+ def models_attribute?(attribute)
49
+ attribute !~ /\./
50
+ end
51
+
52
+ def add_error(attribute, message)
53
+ @errors[field_id(attribute)] ||= []
54
+ @errors[field_id(attribute)] << error_hash(attribute, message)
55
+ end
56
+
57
+ def error_hash(attribute, message)
58
+ h = {
59
+ error_code: message.error_code,
60
+ message: I18n.t(message, scope: @error_message_i18n_scope),
61
+ full_message: full_error_message(attribute, message)
62
+ }
63
+ h[:data] = message.data unless message.data.nil?
64
+ h
65
+ end
66
+
67
+ def full_error_message(attribute, message)
68
+ template = "%{class} with id %{id} has error \"#{message}\""
69
+ template += ' on attribute "%{attribute}"' unless attribute.to_sym == :base
70
+ options = {
71
+ default: template,
72
+ attribute: attribute,
73
+ class: @resource.class.name,
74
+ id: @resource.id ? @resource.id.to_s : 'null',
75
+ scope: @error_message_i18n_scope
76
+ }
77
+ I18n.t(template, options)
78
+ end
79
+
80
+ def field_id(attribute)
81
+ return @field_name_prefix if attribute.to_sym == :base
82
+ field = attribute
83
+ if association(attribute).present?
84
+ field = association(attribute).foreign_key.to_s
85
+ end
86
+
87
+ "#{@field_name_prefix}[#{field}]"
88
+ end
89
+
90
+ def single_association?(association_name)
91
+ [:belongs_to, :has_one].include? association_type(association_name)
92
+ end
93
+
94
+ def association_type(association_name)
95
+ association(association_name).macro
96
+ end
97
+
98
+ def association(association_name)
99
+ @klass.reflect_on_association(association_name.to_sym)
100
+ end
101
+
102
+ end
103
+ end