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,45 @@
1
+ ////////////////////////
2
+ // Settings //
3
+ ////////////////////////
4
+
5
+ // overlay
6
+ $mfp-overlay-color: #0b0b0b !default; // Color of overlay screen
7
+ $mfp-overlay-opacity: 0.8 !default; // Opacity of overlay screen
8
+ $mfp-shadow: 0 0 8px rgba(0, 0, 0, 0.6) !default; // Shadow on image or iframe
9
+
10
+ // spacing
11
+ $mfp-popup-padding-left: 8px!default ; // Padding from left and from right side
12
+ $mfp-popup-padding-left-mobile: 6px !default; // Same as above, but is applied when width of window is less than 800px
13
+
14
+ $mfp-z-index-base: 1040 !default; // Base z-index of popup
15
+
16
+ // controls
17
+ $mfp-include-arrows: true !default; // Include styles for nav arrows
18
+ $mfp-controls-opacity: 0.65 !default; // Opacity of controls
19
+ $mfp-controls-color: #FFF !default; // Color of controls
20
+ $mfp-controls-border-color: #3F3F3F !default; // Border color of controls
21
+ $mfp-inner-close-icon-color: #333 !default; // Color of close button when inside
22
+ $mfp-controls-text-color: #CCC !default; // Color of preloader and "1 of X" indicator
23
+ $mfp-controls-text-color-hover: #FFF !default; // Hover color of preloader and "1 of X" indicator
24
+ $mfp-IE7support: true !default; // Very basic IE7 support
25
+
26
+ // Iframe-type options
27
+ $mfp-include-iframe-type: true !default; // Enable Iframe-type popups
28
+ $mfp-iframe-padding-top: 40px !default; // Iframe padding top
29
+ $mfp-iframe-background: #000 !default; // Background color of iframes
30
+ $mfp-iframe-max-width: 900px !default; // Maximum width of iframes
31
+ $mfp-iframe-ratio: 9/16 !default; // Ratio of iframe (9/16 = widescreen, 3/4 = standard, etc.)
32
+
33
+ // Image-type options
34
+ $mfp-include-image-type: true !default; // Enable Image-type popups
35
+ $mfp-image-background: #444 !default;
36
+ $mfp-image-padding-top: 40px !default; // Image padding top
37
+ $mfp-image-padding-bottom: 40px !default; // Image padding bottom
38
+ $mfp-include-mobile-layout-for-image: true !default; // Removes paddings from top and bottom
39
+
40
+ // Image caption options
41
+ $mfp-caption-title-color: #F3F3F3 !default; // Caption title color
42
+ $mfp-caption-subtitle-color: #BDBDBD !default; // Caption subtitle color
43
+
44
+ // A11y
45
+ $mfp-use-visuallyhidden: false !default; // Hide content from browsers, but make it available for screen readers
@@ -0,0 +1,58 @@
1
+ class Releaf::Builders::AssociationReflector
2
+ delegate :macro, :name, :klass, to: :reflection
3
+
4
+ attr_accessor :reflection, :fields, :sortable_column_name, :sortable_cache
5
+
6
+ def initialize(reflection, fields, sortable_column_name)
7
+ self.reflection = reflection
8
+ self.fields = fields
9
+ self.sortable_column_name = sortable_column_name.to_sym
10
+ end
11
+
12
+ def sortable?
13
+ if @sortable.nil?
14
+ @sortable = (expected_order_clause == actual_order_clause)
15
+ end
16
+
17
+ @sortable
18
+ end
19
+
20
+ def destroyable?
21
+ if @destroyable.nil?
22
+ @destroyable = reflection
23
+ .active_record
24
+ .nested_attributes_options
25
+ .fetch(reflection.name, {})
26
+ .fetch(:allow_destroy, false)
27
+ end
28
+
29
+ @destroyable
30
+ end
31
+
32
+ def actual_order_clause
33
+ relation = reflection.klass.all
34
+
35
+ if reflection.scope
36
+ relation = relation.instance_exec(reflection.active_record, &reflection.scope)
37
+ end
38
+
39
+ extract_order_clause(relation)
40
+ end
41
+
42
+ def expected_order_clause
43
+ relation = reflection.klass.all.order(sortable_column_name)
44
+ extract_order_clause(relation)
45
+ end
46
+
47
+ def extract_order_clause(relation)
48
+ relation.order_values.map{|value| value_as_sql(value) }.join(", ")
49
+ end
50
+
51
+ def value_as_sql(value)
52
+ if value.respond_to?(:to_sql)
53
+ value.to_sql
54
+ else
55
+ value
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,80 @@
1
+ module Releaf::Builders::Base
2
+ extend ActiveSupport::Concern
3
+
4
+ delegate :controller, :controller_name, :url_for, :form_for,
5
+ :releaf_button, :params, :form_tag, :file_field_tag,
6
+ :request, :check_box_tag, :label_tag, :content_tag, :hidden_field_tag,
7
+ :render, :link_to, :flash, :truncate, :radio_button_tag,
8
+ :options_for_select, :action_name, :options_from_collection_for_select,
9
+ :select_tag, :text_field_tag,
10
+ :image_tag, :jquery_date_format, :cookies, :button_tag, :merge_attributes, to: :template
11
+
12
+ delegate :layout_settings, :access_control, :controller_scope_name,
13
+ :feature_available?, :index_url, to: :controller
14
+
15
+ alias_method :button, :releaf_button
16
+
17
+ def wrapper(content_or_attributes_with_block, attributes = {}, &block)
18
+ if block_given?
19
+ tag(:div, content_or_attributes_with_block, nil, nil, &block)
20
+ else
21
+ tag(:div, content_or_attributes_with_block, attributes)
22
+ end
23
+ end
24
+
25
+ def html_escape(value)
26
+ ERB::Util.html_escape(value)
27
+ end
28
+
29
+ def tag(*args, &block)
30
+ return content_tag(*args) unless block_given?
31
+
32
+ content_tag(*args) do
33
+ block_result = yield
34
+ if block_result.is_a? Array
35
+ safe_join do
36
+ block_result
37
+ end
38
+ else
39
+ block_result.to_s
40
+ end
41
+ end
42
+ end
43
+
44
+ def template_variable(variable)
45
+ template.instance_variable_get("@#{variable}")
46
+ end
47
+
48
+ def icon(name)
49
+ template.fa_icon(name)
50
+ end
51
+
52
+ def safe_join(&block)
53
+ template.safe_join(yield)
54
+ end
55
+
56
+ def t(key, options = {})
57
+ options[:scope] = default_translation_scope unless options.key? :scope
58
+ I18n.t(key, options)
59
+ end
60
+
61
+ def translate_locale(locale)
62
+ t(locale, scope: "locales")
63
+ end
64
+
65
+ def locale_options(locales)
66
+ locales.collect do|locale|
67
+ [translate_locale(locale), locale]
68
+ end
69
+ end
70
+
71
+ def default_translation_scope
72
+ controller_scope_name
73
+ end
74
+
75
+ # calls `#to_text` on resource if resource supports it. Otherwise calls
76
+ # `#to_s` method
77
+ def resource_to_text(resource)
78
+ resource.send(resource.respond_to?(:to_text) ? :to_text : :to_s)
79
+ end
80
+ end
@@ -0,0 +1,8 @@
1
+ module Releaf::Builders::Collection
2
+ attr_accessor :collection
3
+
4
+ def initialize(template)
5
+ super
6
+ self.collection = template_variable("collection")
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+ class Releaf::Builders::ConfirmDestroyDialogBuilder < Releaf::Builders::ConfirmDialogBuilder
2
+ def question_content
3
+ t("Do you want to delete the following object?")
4
+ end
5
+
6
+ def description_content
7
+ resource_to_text(resource)
8
+ end
9
+
10
+ def section_header_text
11
+ t("Confirm deletion")
12
+ end
13
+
14
+ def confirm_method
15
+ :delete
16
+ end
17
+
18
+ def icon_name
19
+ "trash-o"
20
+ end
21
+
22
+ def confirm_url
23
+ url_for( action: 'destroy', id: resource.id, index_url: index_url)
24
+ end
25
+ end
@@ -0,0 +1,54 @@
1
+ class Releaf::Builders::ConfirmDialogBuilder
2
+ include Releaf::Builders::ResourceDialog
3
+
4
+ attr_accessor :form
5
+
6
+ def output
7
+ tag(:section, section_attributes) do
8
+ form_for(resource, confirm_form_options) do |form|
9
+ self.form = form
10
+ safe_join do
11
+ section_blocks
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ def section_body
18
+ tag(:div, class: "body") do
19
+ section_body_blocks
20
+ end
21
+ end
22
+
23
+ def section_body_blocks
24
+ [
25
+ icon(icon_name),
26
+ tag(:div, question_content, class: "question"),
27
+ tag(:div, description_content, class: "description")
28
+ ]
29
+ end
30
+
31
+ def section_attributes
32
+ merge_attributes(super, class: ["confirm"])
33
+ end
34
+
35
+ def footer_primary_tools
36
+ [cancel_button, confirm_button]
37
+ end
38
+
39
+ def confirm_form_options
40
+ {builder: Releaf::Builders::FormBuilder, url: confirm_url, as: :resource, method: confirm_method}
41
+ end
42
+
43
+ def confirm_button
44
+ button(t("Yes"), "check", class: "danger", type: 'submit')
45
+ end
46
+
47
+ def cancel_url
48
+ index_url
49
+ end
50
+
51
+ def cancel_button
52
+ button(t("No"), "ban", class: "secondary", data: {type: 'cancel'}, href: index_url)
53
+ end
54
+ end
@@ -0,0 +1,66 @@
1
+ class Releaf::Builders::EditBuilder
2
+ include Releaf::Builders::ResourceView
3
+
4
+ attr_accessor :form
5
+
6
+ def section_content
7
+ form_for(resource, form_options) do |form|
8
+ self.form = form
9
+ safe_join do
10
+ [index_url_preserver] + section_blocks
11
+ end
12
+ end
13
+ end
14
+
15
+ def index_url_preserver
16
+ hidden_field_tag 'index_url', params[:index_url] if params[:index_url].present?
17
+ end
18
+
19
+ def section_body_blocks
20
+ [error_notices, form_fields]
21
+ end
22
+
23
+ def form_fields
24
+ form.releaf_fields(form.field_names.to_a)
25
+ end
26
+
27
+ def form_options
28
+ controller.form_options(action_name, resource, :resource)
29
+ end
30
+
31
+ def error_notices
32
+ return unless resource.errors.any?
33
+ tag(:div, class: "form-error-box") do
34
+ error_notices_header <<
35
+ tag(:ul) do
36
+ resource.errors.full_messages.collect do|message|
37
+ tag(:li, message, class: "error")
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ def error_notices_header
44
+ tag(:strong, "#{resource.errors.count} validation #{"error".pluralize(resource.errors.count)} occured:")
45
+ end
46
+
47
+ def footer_primary_tools
48
+ tools = []
49
+ tools << save_and_create_another_button if create_another_available?
50
+ tools << save_button
51
+ tools
52
+ end
53
+
54
+ def create_another_available?
55
+ resource.present? && resource.new_record? && controller.feature_available?(:create_another)
56
+ end
57
+
58
+ def save_and_create_another_button
59
+ button(t("Save and create another"), "plus", name: "after_save", value: "create_another", class: "secondary", data: { type: 'ok', disable: true }, type: "submit")
60
+ end
61
+
62
+ def save_button
63
+ button(t("Save"), "check", class: "primary", data: { type: 'ok', disable: true }, type: "submit")
64
+ end
65
+
66
+ end
@@ -0,0 +1,594 @@
1
+ class Releaf::Builders::FormBuilder < ActionView::Helpers::FormBuilder
2
+ include Releaf::Builders::Base
3
+ include Releaf::Tags::AssociatedSetField
4
+ include Releaf::Builders::Orderer
5
+ attr_accessor :template
6
+
7
+ def field_names
8
+ resource_fields.values
9
+ end
10
+
11
+ def resource_fields
12
+ Releaf::Core::ResourceFields.new(object.class)
13
+ end
14
+
15
+ def field_render_method_name(name)
16
+ parts = [name]
17
+
18
+ builder = self
19
+ until builder.options[:parent_builder].nil? do
20
+ parts << builder.options[:relation_name] if builder.options[:relation_name]
21
+ builder = builder.options[:parent_builder]
22
+ end
23
+
24
+ parts << "render"
25
+ parts.reverse.join("_")
26
+ end
27
+
28
+ def normalize_fields(fields)
29
+ fields.flatten.map do |item|
30
+ if item.is_a? Hash
31
+ item.each_pair.map do |(association, subfields)|
32
+ normalize_field(association, subfields)
33
+ end
34
+ else
35
+ normalize_field(item, nil)
36
+ end
37
+ end.flatten
38
+ end
39
+
40
+ def normalize_field(field, subfields)
41
+ {
42
+ render_method: field_render_method_name(field),
43
+ field: field,
44
+ subfields: subfields
45
+ }
46
+ end
47
+
48
+ def releaf_fields(*fields)
49
+ safe_join do
50
+ normalize_fields(fields).collect{|field_option| render_field_by_options(field_option) }
51
+ end
52
+ end
53
+
54
+ def render_field_by_options(options)
55
+ if respond_to? options[:render_method]
56
+ send(options[:render_method])
57
+ else
58
+ reflection = reflect_on_association(options[:field])
59
+
60
+ if reflection
61
+ releaf_association_fields(reflection, options[:subfields])
62
+ else
63
+ releaf_field(options[:field])
64
+ end
65
+ end
66
+ end
67
+
68
+ def reflect_on_association(association_name)
69
+ object.class.reflect_on_association(association_name)
70
+ end
71
+
72
+ def association_reflector(reflection, fields)
73
+ fields ||= resource_fields.association_attributes(reflection)
74
+ Releaf::Builders::AssociationReflector.new(reflection, fields, sortable_column_name)
75
+ end
76
+
77
+ def releaf_association_fields(reflection, fields)
78
+ reflector = association_reflector(reflection, fields)
79
+
80
+ case reflector.macro
81
+ when :has_many
82
+ releaf_has_many_association(reflector)
83
+ when :belongs_to
84
+ releaf_belongs_to_association(reflector)
85
+ when :has_one
86
+ releaf_has_one_association(reflector)
87
+ else
88
+ raise 'not implemented'
89
+ end
90
+ end
91
+
92
+ def releaf_belongs_to_association(reflector)
93
+ releaf_has_one_or_belongs_to_association(reflector)
94
+ end
95
+
96
+ def releaf_has_one_association(reflector)
97
+ object.send("build_#{reflector.name}") unless object.send(reflector.name).present?
98
+ releaf_has_one_or_belongs_to_association(reflector)
99
+ end
100
+
101
+ def releaf_has_one_or_belongs_to_association(reflector)
102
+ tag(:fieldset, class: "type-association", data: {name: reflector.name}) do
103
+ tag(:legend, translate_attribute(reflector.name)) <<
104
+ fields_for(reflector.name, object.send(reflector.name), relation_name: reflector.name, builder: self.class) do |builder|
105
+ builder.releaf_fields(reflector.fields)
106
+ end
107
+ end
108
+ end
109
+
110
+ def releaf_has_many_association(reflector)
111
+ item_template = releaf_has_many_association_fields(reflector, reflector.klass.new, '_template_', true)
112
+
113
+ tag(:section, class: "nested", data: {name: reflector.name, "releaf-template" => html_escape(item_template.to_str)}) do
114
+ [
115
+ releaf_has_many_association_header(reflector),
116
+ releaf_has_many_association_body(reflector),
117
+ releaf_has_many_association_footer(reflector)
118
+ ]
119
+ end
120
+ end
121
+
122
+ def releaf_has_many_association_header(reflector)
123
+ tag(:header) do
124
+ tag(:h1, translate_attribute(reflector.name))
125
+ end
126
+ end
127
+
128
+ def releaf_has_many_association_body(reflector)
129
+ attributes = {
130
+ class: ["body", "list"]
131
+ }
132
+ attributes["data"] = {sortable: nil} if reflector.sortable?
133
+
134
+ tag(:div, attributes) do
135
+ association_collection(reflector).each_with_index.map do |association_object, index|
136
+ releaf_has_many_association_fields(reflector, association_object, index, reflector.destroyable?)
137
+ end
138
+ end
139
+ end
140
+
141
+ def releaf_has_many_association_footer(reflector)
142
+ tag(:footer){ field_type_add_nested }
143
+ end
144
+
145
+ def releaf_has_many_association_fields(reflector, association_object, association_index, destroyable)
146
+ tag(:fieldset, class: ["item", "type-association"], data: {name: reflector.name, index: association_index}) do
147
+ fields_for(reflector.name, association_object, relation_name: reflector.name,
148
+ child_index: association_index, builder: self.class) do |builder|
149
+ builder.releaf_has_many_association_field(reflector, destroyable)
150
+ end
151
+ end
152
+ end
153
+
154
+ def releaf_has_many_association_field(reflector, destroyable)
155
+ content = ActiveSupport::SafeBuffer.new
156
+ skippable_fields = []
157
+
158
+ if reflector.sortable?
159
+ skippable_fields << sortable_column_name
160
+ content << hidden_field(sortable_column_name.to_sym, class: "item-position")
161
+ content << tag(:div, "&nbsp;".html_safe, class: "handle")
162
+ end
163
+
164
+ content << releaf_fields(reflector.fields - skippable_fields)
165
+ content << field_type_remove_nested if destroyable
166
+
167
+ content
168
+ end
169
+
170
+ def field_type_remove_nested
171
+ button_attributes = {title: t('Remove item'), class: "danger remove-nested-item"}
172
+ wrapper(class: "remove-item-box") do
173
+ button(nil, "trash-o", button_attributes) << hidden_field("_destroy", class: "destroy")
174
+ end
175
+ end
176
+
177
+ def field_type_add_nested
178
+ button(t('Add item'), "plus", class: "primary add-nested-item")
179
+ end
180
+
181
+ def field_type_method(name)
182
+ type = Releaf::Core::TemplateFieldTypeMapper.field_type_name(object, name)
183
+ localization = Releaf::Core::TemplateFieldTypeMapper.use_i18n?(object, name)
184
+
185
+ "releaf_#{type}_#{'i18n_' if localization}field"
186
+ end
187
+
188
+ def releaf_field(name, input: {}, label: {}, field: {}, options: {}, &block)
189
+ method_name = field_type_method(name)
190
+ send(method_name, name, input: input, label: label, field: field, options: options, &block)
191
+ end
192
+
193
+ def releaf_item_field_collection(name, options = {})
194
+ options[:collection] || object.class.reflect_on_association(relation_name(name)).try(:klass).try(:all)
195
+ end
196
+
197
+ def releaf_item_field_choices(name, options = {})
198
+ unless options.key? :select_options
199
+ options[:select_options] = releaf_item_field_collection(name, options)
200
+ .collect{|item| [resource_to_text(item), item.id]}
201
+ end
202
+
203
+ if options[:select_options].is_a? Array
204
+ choices = options_for_select(options[:select_options], object.send(name))
205
+ else
206
+ choices = options[:select_options]
207
+ end
208
+
209
+ choices
210
+ end
211
+
212
+ def relation_name(name)
213
+ name.to_s.sub(/_id$/, '').to_sym
214
+ end
215
+
216
+ def releaf_item_field(name, input: {}, label: {}, field: {}, options: {}, &block)
217
+ label = {translation_key: name.to_s.sub(/_id$/, '').to_s}.deep_merge(label)
218
+ attributes = input_attributes(name, {value: object.send(name)}.merge(input), options)
219
+ options = {field: {type: "item"}}.deep_merge(options)
220
+
221
+
222
+ # add empty value when validation exists, so user is forced to choose something
223
+ unless options.key? :include_blank
224
+ options[:include_blank] = true
225
+ object.class.validators_on(name).each do |validator|
226
+ next unless validator.is_a? ActiveModel::Validations::PresenceValidator
227
+ # if new record, or object is missing (was deleted)
228
+ options[:include_blank] = object.new_record? || object.send(relation_name(name)).blank?
229
+ break
230
+ end
231
+ end
232
+
233
+
234
+ choices = releaf_item_field_choices(name, options)
235
+ content = select(name, choices, options, attributes)
236
+ input_wrapper_with_label(name, content, label: label, field: field, options: options, &block)
237
+ end
238
+
239
+ def releaf_image_field(name, input: {}, label: {}, field: {}, options: {}, &block)
240
+ name = name.to_s.sub(/_uid$/, '')
241
+
242
+ attributes = {
243
+ accept: 'image/png,image/jpeg,image/bmp,image/gif'
244
+ }.merge(input)
245
+
246
+ attributes = input_attributes(name, attributes, options)
247
+
248
+ options = {field: {type: "image"}}.deep_merge(options)
249
+ content = file_field(name, attributes)
250
+ if object.send(name).present?
251
+ content += tag(:div, class: "value-preview") do
252
+ inner_content = tag(:div, class: "image-wrap") do
253
+ thumbnail = image_tag(object.send(name).thumb('410x128>').url, alt: '')
254
+ hidden_field("retained_#{name}") +
255
+ link_to(thumbnail, object.send(name).url, target: :_blank, class: :ajaxbox, rel: :image)
256
+ end
257
+ inner_content << releaf_file_remove_button(name)
258
+ end
259
+ end
260
+
261
+ input_wrapper_with_label(name, content, label: label, field: field, options: options, &block)
262
+ end
263
+
264
+ def releaf_file_remove_button(name)
265
+ tag(:div, class: "remove") do
266
+ check_box("remove_#{name}") << label("remove_#{name}", t("Remove"))
267
+ end
268
+ end
269
+
270
+ def releaf_file_field(name, input: {}, label: {}, field: {}, options: {}, &block)
271
+ name = name.to_s.sub(/_uid$/, '')
272
+ attributes = input_attributes(name, input, options)
273
+ options = {field: {type: "file"}}.deep_merge(options)
274
+
275
+ content = file_field(name, attributes)
276
+ if object.send(name).present?
277
+ content << hidden_field("retained_#{name}")
278
+ content << link_to(t("Download"), object.send(name).url, target: "_blank")
279
+ content << releaf_file_remove_button(name)
280
+ end
281
+
282
+ input_wrapper_with_label(name, content, label: label, field: field, options: options, &block)
283
+ end
284
+
285
+ def releaf_boolean_field(name, input: {}, label: {}, field: {}, options: {})
286
+ attributes = input_attributes(name, input, options)
287
+ options = {field: {type: "boolean"}}.deep_merge(options)
288
+
289
+ wrapper(field_attributes(name, field, options)) do
290
+ wrapper(class: "value") do
291
+ check_box(name, attributes) << releaf_label(name, label, options.deep_merge(label: {minimal: true}))
292
+ end
293
+ end
294
+ end
295
+
296
+ def date_or_time_fields(name, type, input: {}, label: {}, field: {}, options: {})
297
+ input = date_or_time_fields_input_attributes(name, type, input)
298
+ options = {field: {type: type.to_s}}.deep_merge(options)
299
+ releaf_text_field(name, input: input, label: label, field: field, options: options)
300
+ end
301
+
302
+ def date_or_time_fields_input_attributes(name, type, attributes)
303
+ value = object.send(name)
304
+ {
305
+ class: "text #{type}-picker",
306
+ data: {
307
+ "date-format" => date_format_for_jquery,
308
+ "time-format" => time_format_for_jquery
309
+ },
310
+ value: (format_date_or_time_value(value, type) if value)
311
+ }.merge(attributes)
312
+ end
313
+
314
+ def normalize_date_or_time_value(value, type)
315
+ case type
316
+ when :date
317
+ value.to_date
318
+ when :datetime
319
+ value.to_datetime
320
+ when :time
321
+ value.to_time
322
+ end
323
+ end
324
+
325
+ def format_date_or_time_value(value, type)
326
+ default_format = date_or_time_default_format(type)
327
+ value = normalize_date_or_time_value(value, type)
328
+
329
+ if type == :time
330
+ value.strftime(default_format)
331
+ else
332
+ I18n.l(value, default: default_format)
333
+ end
334
+ end
335
+
336
+ def time_format_for_jquery
337
+ format = date_or_time_default_format(:time)
338
+ jquery_date_format(format)
339
+ end
340
+
341
+ def date_format_for_jquery
342
+ format = date_or_time_default_format(:date)
343
+ jquery_date_format(t("default", scope: "date.formats", default: format))
344
+ end
345
+
346
+ def date_or_time_default_format(type)
347
+ case type
348
+ when :date
349
+ "%Y-%m-%d"
350
+ when :datetime
351
+ "%Y-%m-%d %H:%M"
352
+ when :time
353
+ "%H:%M"
354
+ end
355
+ end
356
+
357
+ def releaf_datetime_field(name, input: {}, label: {}, field: {}, options: {})
358
+ date_or_time_fields(name, :datetime, input: input, label: label, field: field, options: options)
359
+ end
360
+
361
+ def releaf_time_field(name, input: {}, label: {}, field: {}, options: {})
362
+ date_or_time_fields(name, :time, input: input, label: label, field: field, options: options)
363
+ end
364
+
365
+ def releaf_date_field(name, input: {}, label: {}, field: {}, options: {})
366
+ date_or_time_fields(name, :date, input: input, label: label, field: field, options: options)
367
+ end
368
+
369
+ def releaf_richtext_field(name, input: {}, label: {}, field: {}, options: {}, &block)
370
+ attributes = richtext_input_attributes(name)
371
+ .merge(value: object.send(name))
372
+ .merge(input)
373
+ attributes = input_attributes(name, attributes, options)
374
+
375
+ options = richtext_options(name, options)
376
+ content = text_area(name, attributes)
377
+
378
+ input_wrapper_with_label(name, content, label: label, field: field, options: options, &block)
379
+ end
380
+
381
+ def releaf_textarea_field(name, input: {}, label: {}, field: {}, options: {}, &block)
382
+ attributes = {
383
+ rows: 5,
384
+ cols: 75,
385
+ value: object.send(name)
386
+ }.merge(input)
387
+
388
+ attributes = input_attributes(name, attributes, options)
389
+
390
+ options = {field: {type: "textarea"}}.deep_merge(options)
391
+ content = text_area(name, attributes)
392
+
393
+ input_wrapper_with_label(name, content, label: label, field: field, options: options, &block)
394
+ end
395
+
396
+ def releaf_email_field(name, input: {}, label: {}, field: {}, options: {}, &block)
397
+ options = {field: {type: "email"}}.deep_merge(options)
398
+ input = {type: "email"}.deep_merge(input)
399
+ releaf_text_field(name, input: input, label: label, field: field, options: options, &block)
400
+ end
401
+
402
+ def releaf_link_field(name, input: {}, label: {}, field: {}, options: {}, &block)
403
+ options = {field: {type: "link"}}.deep_merge(options)
404
+ releaf_text_field(name, input: input, label: label, field: field, options: options, &block)
405
+ end
406
+
407
+ def releaf_password_field(name, input: {}, label: {}, field: {}, options: {}, &block)
408
+ attributes = input_attributes(name, {autocomplete: "off", class: "text"}.merge(input), options)
409
+ options = {field: {type: "password"}}.deep_merge(options)
410
+ content = password_field(name, attributes)
411
+
412
+ input_wrapper_with_label(name, content, label: label, field: field, options: options, &block)
413
+ end
414
+
415
+ def releaf_number_field(name, input: {}, label: {}, field: {}, options: {}, &block)
416
+ attributes = input_attributes(name, {value: object.send(name), step: "any", class: "text" }.merge(input), options)
417
+ options = {field: {type: "number"}}.deep_merge(options)
418
+ content = number_field(name, attributes)
419
+
420
+ input_wrapper_with_label(name, content, label: label, field: field, options: options, &block)
421
+ end
422
+
423
+ alias_method :releaf_integer_field, :releaf_number_field
424
+ alias_method :releaf_float_field, :releaf_number_field
425
+ alias_method :releaf_decimal_field, :releaf_number_field
426
+
427
+ def releaf_text_field(name, input: {}, label: {}, field: {}, options: {}, &block)
428
+ attributes = input_attributes(name, {value: object.send(name), class: "text"}.merge(input), options)
429
+ options = {field: {type: "text"}}.deep_merge(options)
430
+ content = text_field(name, attributes)
431
+
432
+ input_wrapper_with_label(name, content, label: label, field: field, options: options, &block)
433
+ end
434
+
435
+ def releaf_text_i18n_field(name, input: {}, label: {}, field: {}, options: {})
436
+ options = {field: {type: "text"}}.deep_merge(options)
437
+ input = {class: "text"}.deep_merge(input)
438
+ localized_field(name, :text_field, input: input, label: label, field: field, options: options)
439
+ end
440
+
441
+ def releaf_link_i18n_field(name, input: {}, label: {}, field: {}, options: {})
442
+ options = {field: {type: "link"}}.deep_merge(options)
443
+ input = {class: "text"}.deep_merge(input)
444
+ localized_field(name, :text_field, input: input, label: label, field: field, options: options)
445
+ end
446
+
447
+ def richtext_input_attributes(name)
448
+ {
449
+ rows: 5,
450
+ cols: 50,
451
+ class: "richtext",
452
+ data: {
453
+ "attachment-upload-url" => (controller.respond_to?(:releaf_richtext_attachment_upload_url) ? controller.releaf_richtext_attachment_upload_url : '')
454
+ },
455
+ }
456
+ end
457
+
458
+ def richtext_options(name, options)
459
+ {field: {type: "richtext"}, label: {translation_key: name.to_s.sub(/_html$/, '').to_s }}.deep_merge(options)
460
+ end
461
+
462
+ def releaf_richtext_i18n_field(name, input: {}, label: {}, field: {}, options: {})
463
+ input = richtext_input_attributes(name).merge(input)
464
+ options = richtext_options(name, options)
465
+ localized_field(name, :text_area, input: input, label: label, field: field, options: options)
466
+ end
467
+
468
+ def releaf_textarea_i18n_field(name, input: {}, label: {}, field: {}, options: {})
469
+ input = {
470
+ rows: 5,
471
+ cols: 75,
472
+ }.merge(input)
473
+ options = {field: {type: "textarea"}}.deep_merge(options)
474
+ localized_field(name, :text_area, input: input, label: label, field: field, options: options)
475
+ end
476
+
477
+ def default_locale
478
+ selected_locale = (cookies[:'releaf.i18n.locale'] || I18n.locale).to_sym
479
+ locales.include?(selected_locale) ? selected_locale : locales.first
480
+ end
481
+
482
+ def locales
483
+ object.class.globalize_locales
484
+ end
485
+
486
+ def localized_field(name, field_type, input: {}, label: {}, field: {}, options: {})
487
+ options = {i18n: true, label: {translation_key: name}}.deep_merge(options)
488
+
489
+ wrapper(field_attributes(name, field, options)) do
490
+ content = object.class.globalize_locales.collect do |locale|
491
+ localized_name = "#{name}_#{locale}"
492
+ html_class = ["localization"]
493
+ html_class << "active" if locale == default_locale
494
+
495
+ tag(:div, class: html_class, data: {locale: locale}) do
496
+ releaf_label(localized_name, label, options) <<
497
+ tag(:div, class: "value") do
498
+ attributes = input_attributes(name, {value: object.send(localized_name)}.merge(input), options)
499
+ send(field_type, localized_name, attributes)
500
+ end
501
+ end
502
+ end
503
+
504
+ content << localization_switch
505
+ end
506
+ end
507
+
508
+ def localization_switch
509
+ tag(:div, class: "localization-switch") do
510
+ button_tag(type: 'button', title: t('Switch locale'), class: "trigger") do
511
+ tag(:span, default_locale, class: "label") + tag(:i, nil, class: ["fa", "fa-chevron-down"])
512
+ end <<
513
+ tag(:menu, class: ["localization-menu-items"], type: 'toolbar') do
514
+ tag(:ul) do
515
+ object.class.globalize_locales.collect do |locale, i|
516
+ tag(:li) do
517
+ tag(:button, translate_locale(locale), type: "button", data: {locale: locale})
518
+ end
519
+ end
520
+ end
521
+ end
522
+ end
523
+ end
524
+
525
+ def input_wrapper_with_label(name, input_content, label: {}, field: {}, options: {})
526
+ field(name, field, options) do
527
+ input_content = safe_join{[input_content, yield.to_s]} if block_given?
528
+ releaf_label(name, label, options) << wrapper(input_content, class: "value")
529
+ end
530
+ end
531
+
532
+ def field(name, attributes, options, &block)
533
+ tag(:div, field_attributes(name, attributes, options), nil, nil, &block)
534
+ end
535
+
536
+ def field_attributes(name, attributes, options)
537
+ type = options.fetch(:field, {}).fetch(:type, nil)
538
+
539
+ classes = ["field", "type-#{type}"]
540
+ classes << "i18n" if options.key? :i18n
541
+
542
+ merge_attributes({class: classes, data: {name: name}}, attributes)
543
+ end
544
+
545
+ def label_attributes(name, attributes, options)
546
+ attributes
547
+ end
548
+
549
+ def input_attributes(name, attributes, options)
550
+ attributes
551
+ end
552
+
553
+
554
+ def releaf_label(name, attributes, options = {})
555
+ label_options = options.fetch(:label, {})
556
+ attributes = label_attributes(name, attributes, options)
557
+ text = label_text(name, label_options)
558
+
559
+ content = label(name, text, attributes)
560
+
561
+ if label_options.fetch(:minimal, false) == true
562
+ content
563
+ else
564
+ content += wrapper(label_options[:description], class: "description") if label_options.fetch(:description, nil).present?
565
+ wrapper(content, class: "label-wrap")
566
+ end
567
+ end
568
+
569
+ def label_text(name, options = {})
570
+ if options[:label_text].present?
571
+ options[:label_text]
572
+ else
573
+ if options[:translation_key].present?
574
+ key = options[:translation_key]
575
+ else
576
+ key = name.to_s.sub(/_uid$/, '')
577
+ end
578
+
579
+ translate_attribute(key)
580
+ end
581
+ end
582
+
583
+ def translate_attribute(attribute)
584
+ object.class.human_attribute_name(attribute, create_default: false)
585
+ end
586
+
587
+ def association_collection(reflector)
588
+ object.send(reflector.name)
589
+ end
590
+
591
+ def sortable_column_name
592
+ 'item_position'
593
+ end
594
+ end