releaf-core 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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