para 0.11.4 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/para/admin/main.scss +31 -0
  3. data/app/assets/stylesheets/para/admin/src/_affix.scss +7 -0
  4. data/app/assets/stylesheets/para/admin/src/_alert.scss +35 -0
  5. data/app/assets/stylesheets/para/admin/src/_base.scss +63 -0
  6. data/app/assets/stylesheets/para/admin/src/_bootstrap-variables.scss +766 -379
  7. data/app/assets/stylesheets/para/admin/src/_breadcrumb.scss +37 -0
  8. data/app/assets/stylesheets/para/admin/src/_buttons.scss +128 -0
  9. data/app/assets/stylesheets/para/admin/src/_checkable.scss +106 -0
  10. data/app/assets/stylesheets/para/admin/src/_common.scss +250 -0
  11. data/app/assets/stylesheets/para/admin/src/_dropdown.scss +52 -0
  12. data/app/assets/stylesheets/para/admin/src/_form.scss +359 -0
  13. data/app/assets/stylesheets/para/admin/src/_list.scss +96 -0
  14. data/app/assets/stylesheets/para/admin/src/_mixins.scss +109 -0
  15. data/app/assets/stylesheets/para/admin/src/_multi-select.scss +110 -0
  16. data/app/assets/stylesheets/para/admin/src/_navigation.scss +210 -0
  17. data/app/assets/stylesheets/para/admin/src/_navtabs.scss +68 -0
  18. data/app/assets/stylesheets/para/admin/src/_nested-many.scss +87 -0
  19. data/app/assets/stylesheets/para/admin/src/_nested_one.scss +26 -0
  20. data/app/assets/stylesheets/para/admin/src/_orderable.scss +48 -0
  21. data/app/assets/stylesheets/para/admin/src/_page-loading.scss +40 -0
  22. data/app/assets/stylesheets/para/admin/src/_pagination.scss +39 -0
  23. data/app/assets/stylesheets/para/admin/src/_panel.scss +61 -0
  24. data/app/assets/stylesheets/para/admin/src/_responsive.scss +133 -0
  25. data/app/assets/stylesheets/para/admin/src/_sorting.scss +43 -0
  26. data/app/assets/stylesheets/para/admin/src/_statcard.scss +46 -0
  27. data/app/assets/stylesheets/para/admin/src/_table.scss +36 -0
  28. data/app/assets/stylesheets/para/admin/src/_tree.scss +60 -0
  29. data/app/assets/stylesheets/para/admin/src/{_variables.sass → _variables.scss} +7 -7
  30. data/app/assets/stylesheets/para/admin/src/{_well.sass → _well.scss} +5 -4
  31. data/app/assets/stylesheets/para/admin.scss +15 -0
  32. data/app/assets/stylesheets/para/index.scss +1 -0
  33. data/app/assets/stylesheets/para/lib/datetimepicker.scss +15 -0
  34. data/app/assets/stylesheets/para/lib/fuelux.scss +46 -0
  35. data/app/assets/stylesheets/para/lib/jasny-bootstrap.scss +100 -0
  36. data/app/assets/stylesheets/para/lib/selectize.scss +129 -0
  37. data/app/assets/stylesheets/para/lib/slider.scss +14 -0
  38. data/app/controllers/para/admin/crud_resources_controller.rb +16 -9
  39. data/app/controllers/para/admin/imports_controller.rb +9 -9
  40. data/app/controllers/para/admin/jobs_controller.rb +7 -1
  41. data/app/controllers/para/admin/resources_controller.rb +17 -18
  42. data/app/controllers/para/admin/settings_component_controller.rb +2 -2
  43. data/app/helpers/para/admin/base_helper.rb +36 -25
  44. data/app/helpers/para/admin/page_helper.rb +8 -9
  45. data/app/helpers/para/flash_helper.rb +7 -28
  46. data/app/helpers/para/model_helper.rb +5 -8
  47. data/app/helpers/para/tree_helper.rb +4 -4
  48. data/app/javascripts/para/admin/async-progress.js +58 -0
  49. data/app/javascripts/para/admin/filters-form.js +12 -0
  50. data/app/javascripts/para/admin/job-tracker.js +33 -0
  51. data/app/javascripts/para/admin/table.js +58 -0
  52. data/app/javascripts/para/admin/tabs.js +110 -0
  53. data/app/javascripts/para/admin/theme_actions.js +39 -0
  54. data/app/javascripts/para/admin/tree.js +124 -0
  55. data/app/javascripts/para/application.js +2 -0
  56. data/app/javascripts/para/controllers/application.js +17 -0
  57. data/app/javascripts/para/controllers/index.js +10 -0
  58. data/app/javascripts/para/controllers/para_admin_flash_message_controller.js +48 -0
  59. data/app/javascripts/para/controllers/para_admin_modal_controller.js +43 -0
  60. data/app/javascripts/para/controllers/selectize_field_controller.js +142 -0
  61. data/app/javascripts/para/index.js +31 -0
  62. data/app/javascripts/para/inputs/material-input.js +7 -0
  63. data/app/javascripts/para/inputs/multi-select-input.js +343 -0
  64. data/app/javascripts/para/inputs/nested_many.js +151 -0
  65. data/app/javascripts/para/lib/fetch.js +41 -0
  66. data/app/javascripts/para/lib/page-loading.js +42 -0
  67. data/app/javascripts/para/simple_form_extension/colorpicker.js +30 -0
  68. data/app/javascripts/para/simple_form_extension/datetimepicker.js +115 -0
  69. data/app/javascripts/para/simple_form_extension/fileinput.js +57 -0
  70. data/app/javascripts/para/simple_form_extension/index.js +12 -0
  71. data/app/javascripts/para/simple_form_extension/selectize.js +160 -0
  72. data/app/javascripts/para/simple_form_extension/simple_form_extension_initialization.js +62 -0
  73. data/app/javascripts/para/simple_form_extension/slider.js +43 -0
  74. data/app/javascripts/para/simple_form_extension/spinbox.js +35 -0
  75. data/app/javascripts/para/vendor/bootstrap-colorpicker.js +1025 -0
  76. data/app/javascripts/para/vendor/bootstrap-slider.js +1610 -0
  77. data/app/javascripts/para/vendor/cocoon.js +150 -0
  78. data/app/javascripts/para/vendor/jquery.datetimepicker.js +2156 -0
  79. data/app/javascripts/para/vendor/jquery.js +3 -0
  80. data/app/javascripts/para/vendor/spinbox.js +438 -0
  81. data/app/javascripts/para/vendor/vertebra.js +224 -0
  82. data/app/views/admin/para/exporter/bases/_completed.html.haml +1 -1
  83. data/app/views/layouts/para/admin.html.haml +4 -2
  84. data/app/views/para/admin/imports/new.html.haml +12 -11
  85. data/app/views/para/admin/jobs/_completed.html.haml +1 -1
  86. data/app/views/para/admin/jobs/_failed.html.haml +1 -1
  87. data/app/views/para/admin/jobs/_job.html.haml +11 -0
  88. data/app/views/para/admin/jobs/show.html.haml +1 -10
  89. data/app/views/para/admin/resources/_add_button.html.haml +1 -1
  90. data/app/views/para/admin/resources/_exports_menu.html.haml +2 -2
  91. data/app/views/para/admin/resources/_filters.html.haml +1 -1
  92. data/app/views/para/admin/resources/_imports_menu.html.haml +2 -2
  93. data/app/views/para/admin/resources/_list.html.haml +27 -26
  94. data/app/views/para/admin/resources/_navigation.html.haml +10 -11
  95. data/app/views/para/admin/resources/_subclassable_add_button.html.haml +1 -1
  96. data/app/views/para/admin/shared/_flash.html.haml +18 -0
  97. data/app/views/para/admin/shared/_header.html.haml +1 -1
  98. data/app/views/para/form/_tabs.html.haml +1 -1
  99. data/app/views/para/inputs/_nested_many.html.haml +3 -3
  100. data/app/views/para/inputs/nested_many/_add.html.haml +1 -1
  101. data/app/views/para/inputs/nested_many/_add_with_subclasses.html.haml +2 -2
  102. data/app/views/para/inputs/nested_many/_container.html.haml +1 -1
  103. data/config/locales/fr.yml +1 -0
  104. data/lib/generators/para/install/install_generator.rb +10 -14
  105. data/lib/para/attribute_field/base.rb +3 -0
  106. data/lib/para/attribute_field/wysiwyg_editor.rb +15 -0
  107. data/lib/para/attribute_field.rb +1 -1
  108. data/lib/para/components_configuration.rb +1 -1
  109. data/lib/para/engine.rb +20 -22
  110. data/lib/para/ext/turbo_stream.rb +13 -0
  111. data/lib/para/ext.rb +1 -1
  112. data/lib/para/form_builder/containers.rb +33 -22
  113. data/lib/para/form_builder/nested_form.rb +6 -5
  114. data/lib/para/inputs/nested_many_input.rb +5 -0
  115. data/lib/para/markup/modal.rb +30 -15
  116. data/lib/para/markup/resources_buttons.rb +15 -11
  117. data/lib/para/model_field_parsers/wysiwyg_editor.rb +19 -0
  118. data/lib/para/model_field_parsers.rb +1 -1
  119. data/lib/para/version.rb +1 -1
  120. data/lib/para.rb +2 -8
  121. data/lib/simple_form_extension/components/icons.rb +13 -0
  122. data/lib/simple_form_extension/components/popovers.rb +46 -0
  123. data/lib/simple_form_extension/components.rb +8 -0
  124. data/lib/simple_form_extension/ext/form_builder.rb +20 -0
  125. data/lib/simple_form_extension/file_concern.rb +74 -0
  126. data/lib/simple_form_extension/inputs/boolean_input.rb +16 -0
  127. data/lib/simple_form_extension/inputs/collection_check_boxes_input.rb +15 -0
  128. data/lib/simple_form_extension/inputs/collection_radio_buttons_input.rb +15 -0
  129. data/lib/simple_form_extension/inputs/color_input.rb +37 -0
  130. data/lib/simple_form_extension/inputs/date_time_input.rb +48 -0
  131. data/lib/simple_form_extension/inputs/file_input.rb +41 -0
  132. data/lib/simple_form_extension/inputs/image_input.rb +110 -0
  133. data/lib/simple_form_extension/inputs/numeric_input.rb +27 -0
  134. data/lib/simple_form_extension/inputs/selectize_input.rb +210 -0
  135. data/lib/simple_form_extension/inputs/slider_input.rb +30 -0
  136. data/lib/simple_form_extension/inputs.rb +16 -0
  137. data/lib/simple_form_extension/railtie.rb +21 -0
  138. data/lib/simple_form_extension/resource_name_helper.rb +9 -0
  139. data/lib/simple_form_extension/translations.rb +7 -0
  140. data/lib/simple_form_extension/version.rb +3 -0
  141. data/lib/simple_form_extension.rb +30 -0
  142. data/vendor/assets/images/simple_form_extension/bootstrap-colorpicker/alpha-horizontal.png +0 -0
  143. data/vendor/assets/images/simple_form_extension/bootstrap-colorpicker/alpha.png +0 -0
  144. data/vendor/assets/images/simple_form_extension/bootstrap-colorpicker/hue-horizontal.png +0 -0
  145. data/vendor/assets/images/simple_form_extension/bootstrap-colorpicker/hue.png +0 -0
  146. data/vendor/assets/images/simple_form_extension/bootstrap-colorpicker/saturation.png +0 -0
  147. data/vendor/assets/stylesheets/bootstrap-colorpicker.scss +227 -0
  148. data/vendor/assets/stylesheets/bootstrap-slider.scss +246 -0
  149. data/vendor/assets/stylesheets/bootstrap.scss +6032 -0
  150. data/vendor/assets/stylesheets/jquery.datetimepicker.scss +568 -0
  151. metadata +120 -188
  152. data/app/assets/javascripts/admin/app.coffee +0 -1
  153. data/app/assets/javascripts/para/admin/async-progress.coffee +0 -29
  154. data/app/assets/javascripts/para/admin/filters-form.coffee +0 -11
  155. data/app/assets/javascripts/para/admin/job-tracker.coffee +0 -39
  156. data/app/assets/javascripts/para/admin/table.coffee +0 -44
  157. data/app/assets/javascripts/para/admin/tabs.coffee +0 -63
  158. data/app/assets/javascripts/para/admin/theme_actions.coffee +0 -25
  159. data/app/assets/javascripts/para/admin/tree.coffee +0 -105
  160. data/app/assets/javascripts/para/admin.coffee +0 -22
  161. data/app/assets/javascripts/para/application.js +0 -13
  162. data/app/assets/javascripts/para/inputs/material-input.coffee +0 -4
  163. data/app/assets/javascripts/para/inputs/multi-select-input.coffee +0 -174
  164. data/app/assets/javascripts/para/inputs/nested_many.coffee +0 -108
  165. data/app/assets/javascripts/para/lib/ajax.coffee +0 -11
  166. data/app/assets/javascripts/para/lib/remote-file-forms.coffee +0 -59
  167. data/app/assets/javascripts/para/lib/turbolinks-forms.coffee +0 -23
  168. data/app/assets/javascripts/para/lib/turbolinks-loading.coffee +0 -25
  169. data/app/assets/javascripts/para/lib/turbolinks-reloader.coffee +0 -19
  170. data/app/assets/stylesheets/para/admin/main.sass +0 -33
  171. data/app/assets/stylesheets/para/admin/src/_affix.sass +0 -4
  172. data/app/assets/stylesheets/para/admin/src/_alert.sass +0 -17
  173. data/app/assets/stylesheets/para/admin/src/_base.sass +0 -54
  174. data/app/assets/stylesheets/para/admin/src/_breadcrumb.sass +0 -32
  175. data/app/assets/stylesheets/para/admin/src/_buttons.sass +0 -107
  176. data/app/assets/stylesheets/para/admin/src/_checkable.sass +0 -94
  177. data/app/assets/stylesheets/para/admin/src/_common.sass +0 -202
  178. data/app/assets/stylesheets/para/admin/src/_dropdown.sass +0 -40
  179. data/app/assets/stylesheets/para/admin/src/_form.sass +0 -299
  180. data/app/assets/stylesheets/para/admin/src/_list.sass +0 -89
  181. data/app/assets/stylesheets/para/admin/src/_mixins.sass +0 -113
  182. data/app/assets/stylesheets/para/admin/src/_multi-select.sass +0 -91
  183. data/app/assets/stylesheets/para/admin/src/_navigation.sass +0 -171
  184. data/app/assets/stylesheets/para/admin/src/_navtabs.sass +0 -58
  185. data/app/assets/stylesheets/para/admin/src/_nested-many.sass +0 -75
  186. data/app/assets/stylesheets/para/admin/src/_nested_one.sass +0 -22
  187. data/app/assets/stylesheets/para/admin/src/_orderable.sass +0 -44
  188. data/app/assets/stylesheets/para/admin/src/_page-loading.sass +0 -39
  189. data/app/assets/stylesheets/para/admin/src/_pagination.sass +0 -34
  190. data/app/assets/stylesheets/para/admin/src/_panel.sass +0 -55
  191. data/app/assets/stylesheets/para/admin/src/_responsive.sass +0 -117
  192. data/app/assets/stylesheets/para/admin/src/_sorting.sass +0 -36
  193. data/app/assets/stylesheets/para/admin/src/_statcard.sass +0 -41
  194. data/app/assets/stylesheets/para/admin/src/_table.sass +0 -33
  195. data/app/assets/stylesheets/para/admin/src/_tree.sass +0 -52
  196. data/app/assets/stylesheets/para/admin.sass +0 -12
  197. data/app/assets/stylesheets/para/lib/compass/_support.scss +0 -447
  198. data/app/assets/stylesheets/para/lib/compass/css3/_box-shadow.scss +0 -88
  199. data/app/assets/stylesheets/para/lib/compass/css3/_images.scss +0 -152
  200. data/app/assets/stylesheets/para/lib/compass/css3/_inline-block.scss +0 -31
  201. data/app/assets/stylesheets/para/lib/compass/css3/_text-shadow.scss +0 -82
  202. data/app/assets/stylesheets/para/lib/compass/css3/_transform.scss +0 -590
  203. data/app/assets/stylesheets/para/lib/compass/css3/_transition.scss +0 -190
  204. data/app/assets/stylesheets/para/lib/compass/css3/_user-interface.scss +0 -71
  205. data/app/assets/stylesheets/para/lib/compass/utilities/general/_hacks.scss +0 -65
  206. data/app/assets/stylesheets/para/lib/datetimepicker.sass +0 -15
  207. data/app/assets/stylesheets/para/lib/fuelux.sass +0 -40
  208. data/app/assets/stylesheets/para/lib/jasny-bootstrap.sass +0 -97
  209. data/app/assets/stylesheets/para/lib/redactor.sass +0 -86
  210. data/app/assets/stylesheets/para/lib/selectize.sass +0 -111
  211. data/app/assets/stylesheets/para/lib/slider.sass +0 -12
  212. data/app/assets/stylesheets/para/plugins-includes.sass.erb +0 -1
  213. data/lib/para/attribute_field/redactor.rb +0 -22
  214. data/lib/para/ext/request_iframe_xhr.rb +0 -17
  215. data/lib/para/iframe_transport/middleware.rb +0 -58
  216. data/lib/para/iframe_transport.rb +0 -7
  217. data/lib/para/model_field_parsers/redactor.rb +0 -19
  218. data/vendor/assets/javascripts/jquery.iframe-transport.js +0 -260
  219. data/vendor/assets/javascripts/jquery.remote-modal-form.coffee +0 -145
  220. /data/app/assets/stylesheets/admin/{app.sass → app.scss} +0 -0
  221. /data/app/{assets/javascripts → javascripts}/para/plugins-includes.js.erb +0 -0
  222. /data/{vendor/assets/javascripts → app/javascripts/para/vendor}/Sortable.js +0 -0
  223. /data/{vendor/assets/javascripts → app/javascripts/para/vendor}/jasny-bootstrap.js +0 -0
  224. /data/{vendor/assets/javascripts → app/javascripts/para/vendor}/jquery.scrollto.js +0 -0
  225. /data/{vendor/assets/javascripts → app/javascripts/para/vendor}/jquery.sortable.js +0 -0
  226. /data/vendor/assets/stylesheets/{animate.css → animate.scss} +0 -0
  227. /data/vendor/assets/stylesheets/{hint.css → hint.scss} +0 -0
  228. /data/vendor/assets/stylesheets/{jasny-bootstrap.css → jasny-bootstrap.scss} +0 -0
@@ -25,10 +25,10 @@ module Para
25
25
 
26
26
  if resource.save
27
27
  flash_message(:success, resource)
28
- redirect_to after_form_submit_path
28
+ redirect_to after_form_submit_path, status: 303
29
29
  else
30
30
  flash_message(:error, resource)
31
- render 'new'
31
+ render 'new', status: 422
32
32
  end
33
33
  end
34
34
 
@@ -39,17 +39,17 @@ module Para
39
39
  def update
40
40
  if resource.update(resource_params)
41
41
  flash_message(:success, resource)
42
- redirect_to after_form_submit_path
42
+ redirect_to after_form_submit_path, status: 303
43
43
  else
44
44
  flash_message(:error, resource)
45
- render 'edit'
45
+ render 'edit', status: 422
46
46
  end
47
47
  end
48
48
 
49
49
  def destroy
50
50
  resource.destroy
51
51
  flash_message(:success, resource)
52
- redirect_to after_form_submit_path
52
+ redirect_to after_form_submit_path, status: 303
53
53
  end
54
54
 
55
55
  def order
@@ -86,7 +86,12 @@ module Para
86
86
  host_redirect_params.merge(
87
87
  action: 'edit',
88
88
  id: resource.id,
89
- anchor: current_anchor
89
+ # The `anchor` doesn't work with javascript's `fetch` async requests so we
90
+ # can't redirect an XHR request to an anchor, we need to pass it as an
91
+ # explicit param.
92
+ # See : https://github.com/hotwired/turbo/issues/211
93
+ _current_anchor: params[:_current_anchor].presence,
94
+ return_to: params[:return_to].presence
90
95
  )
91
96
  elsif params[:_save_and_add_another]
92
97
  host_redirect_params.merge(
@@ -160,12 +165,12 @@ module Para
160
165
  end
161
166
 
162
167
  def self.ensure_resource_name_defined!
163
- unless resource_name.presence
164
- raise 'Resource not defined in your controller. ' \
165
- 'You can define the resource of your controller with the ' \
166
- '`resource :resource_name` macro when subclassing ' \
167
- 'Para::Admin::ResourcesController'
168
- end
168
+ return if resource_name.presence
169
+
170
+ raise 'Resource not defined in your controller. ' \
171
+ 'You can define the resource of your controller with the ' \
172
+ '`resource :resource_name` macro when subclassing ' \
173
+ 'Para::Admin::ResourcesController'
169
174
  end
170
175
 
171
176
  def resources_data
@@ -182,12 +187,6 @@ module Para
182
187
  end
183
188
  end
184
189
  end
185
-
186
- def current_anchor
187
- @current_anchor ||= if (current_anchor = params[:_current_anchor]).presence
188
- current_anchor.gsub(/^\#/, '')
189
- end
190
- end
191
190
  end
192
191
  end
193
192
  end
@@ -10,13 +10,13 @@ module Para
10
10
  form.settings_attributes = settings_params[:settings_attributes]
11
11
  form.save
12
12
  flash_message(:success, form)
13
- redirect_to admin_settings_path(@component)
13
+ redirect_to admin_settings_path(@component), status: 303
14
14
  end
15
15
 
16
16
  private
17
17
 
18
18
  def settings_params
19
- params.require(:resource).permit(settings_attributes: [:key, :_type, :value])
19
+ params.require(:resource).permit(settings_attributes: %i[key _type value])
20
20
  end
21
21
  end
22
22
  end
@@ -5,10 +5,10 @@ module Para
5
5
 
6
6
  def find_partial_for(relation, partial, partial_dir: 'admin/resources')
7
7
  relation_class = if model?(relation.class)
8
- relation = relation.class
9
- elsif model?(relation)
10
- relation
11
- end
8
+ relation = relation.class
9
+ elsif model?(relation)
10
+ relation
11
+ end
12
12
 
13
13
  relation_name = find_relation_name_for(
14
14
  plural_file_path_for(relation), partial,
@@ -17,9 +17,9 @@ module Para
17
17
  )
18
18
 
19
19
  if relation_name
20
- "admin/#{ relation_name }/#{ partial }"
20
+ "admin/#{relation_name}/#{partial}"
21
21
  else
22
- "para/#{ partial_dir }/#{ partial }"
22
+ "para/#{partial_dir}/#{partial}"
23
23
  end
24
24
  end
25
25
 
@@ -40,7 +40,7 @@ module Para
40
40
 
41
41
  def template_path_lookup(*paths)
42
42
  path = paths.find { |path| lookup_context.find_all(path).any? }
43
- path&.gsub(/\/_([^\/]+)\z/, '/\1')
43
+ path&.gsub(%r{/_([^/]+)\z}, '/\1')
44
44
  end
45
45
 
46
46
  def resource_title_for(resource)
@@ -56,26 +56,37 @@ module Para
56
56
  def registered_components_options
57
57
  Para::Component.registered_components.keys.map do |identifier|
58
58
  [
59
- t("para.component.#{ identifier }.name", default: identifier.to_s.humanize),
59
+ t("para.component.#{identifier}.name", default: identifier.to_s.humanize),
60
60
  identifier
61
61
  ]
62
62
  end
63
63
  end
64
64
 
65
- def flash_message(type, resource = nil)
66
- key = "#{ flash_shared_key }.#{ params[:action] }.#{ type }"
67
-
68
- translation = if resource
69
- ::I18n.t(key, model: resource.class.model_name.human)
70
- else
71
- ::I18n.t(key)
72
- end
73
-
74
- flash[type] = translation
75
- end
76
-
77
- def flash_shared_key
78
- 'para.flash.shared'
65
+ def flash_message(type, resource = nil, now: false)
66
+ flash_shared_key = 'para.flash.shared'
67
+ key_suffix = "#{params[:action]}.#{type}"
68
+
69
+ shared_key = "#{flash_shared_key}.#{key_suffix}"
70
+
71
+ shared_translation =
72
+ if resource
73
+ ::I18n.t(shared_key, model: resource.class.model_name.human)
74
+ else
75
+ ::I18n.t(shared_key)
76
+ end
77
+
78
+ translation =
79
+ if resource
80
+ ::I18n.t(
81
+ "para.flash.#{resource.class.base_class.model_name.i18n_key}.#{key_suffix}",
82
+ default: shared_translation
83
+ )
84
+ else
85
+ shared_translation
86
+ end
87
+
88
+ flash_receiver = now ? flash.now : flash
89
+ flash_receiver[type] = translation
79
90
  end
80
91
 
81
92
  private
@@ -88,10 +99,10 @@ module Para
88
99
  object.respond_to?(:model_name)
89
100
  end
90
101
 
91
- def partial_exists?(relation, partial, overrides_root: 'admin', **options)
102
+ def partial_exists?(relation, partial, overrides_root: 'admin', **_options)
92
103
  partial_path = partial.to_s.split('/')
93
- partial_path[-1] = "_#{ partial_path.last }"
94
- lookup_context.find_all("#{ overrides_root }/#{relation}/#{ partial_path.join('/') }").any?
104
+ partial_path[-1] = "_#{partial_path.last}"
105
+ lookup_context.find_all("#{overrides_root}/#{relation}/#{partial_path.join('/')}").any?
95
106
  end
96
107
  end
97
108
  end
@@ -4,10 +4,9 @@ module Para
4
4
  def page_top_bar(options = {})
5
5
  top_bar = content_tag(:div, class: 'page-title row') do
6
6
  content_tag(:h1, options[:title]) +
7
-
8
- if (actions = actions_for(options[:type]))
9
- actions.map(&method(:build_action)).join('').html_safe
10
- end
7
+ if (actions = actions_for(options[:type]))
8
+ actions.map(&method(:build_action)).join('').html_safe
9
+ end
11
10
  end
12
11
 
13
12
  # Return both top bar and component navigation to be displayed at the top of the
@@ -17,7 +16,7 @@ module Para
17
16
 
18
17
  def build_action(action)
19
18
  link_options = action.fetch(:link_options, {})
20
- link_options[:class] ||= "btn btn-default btn-shadow"
19
+ link_options[:class] ||= 'btn btn-default btn-shadow btn-sm'
21
20
 
22
21
  content_tag(:div, class: 'actions-control pull-right') do
23
22
  link_to(action[:url], link_options) do
@@ -49,10 +48,10 @@ module Para
49
48
  partial_target = parent_component.try(:model_type) || parent_component
50
49
 
51
50
  render partial: find_partial_for(partial_target, :navigation),
52
- locals: {
53
- parent_component: parent_component,
54
- active_component: @component
55
- }
51
+ locals: {
52
+ parent_component: parent_component,
53
+ active_component: @component
54
+ }
56
55
  end
57
56
  end
58
57
  end
@@ -1,34 +1,13 @@
1
1
  module Para
2
2
  module FlashHelper
3
- def display_admin_flash
4
- # Render empty string if no flash
5
- return "" if flash.empty?
6
-
7
- # Make a div.alert for each message and join the whole
8
- messages = flash.map do |type, message|
9
- flash.delete(type)
10
- type = homogenize_flash_type(type)
11
-
12
- icon = content_tag(:div, class: "alert-icon-container pull-left") do
13
- content_tag(:i, "", class: "fa #{ icon_class_for(type) }") +
14
- ' '.html_safe
15
- end
16
-
17
- alert(type: type) do
18
- icon + content_tag(:p, message.html_safe)
19
- end
20
- end
21
-
22
- # Join the messages and make sure markup is correctly displayed
23
- messages.join.html_safe
3
+ def flash_partial_path
4
+ template_path_lookup('admin/shared/_flash', 'para/admin/shared/_flash')
24
5
  end
25
6
 
26
- private
27
-
28
7
  # Converts flash types to :success or :error to conform to what
29
8
  # twitter bootstrap can handle
30
9
  #
31
- def homogenize_flash_type type
10
+ def homogenize_flash_type(type)
32
11
  case type.to_sym
33
12
  when :notice then :success
34
13
  when :alert then :warning
@@ -37,11 +16,11 @@ module Para
37
16
  end
38
17
  end
39
18
 
40
- def icon_class_for type
19
+ def icon_class_for(type)
41
20
  case type
42
- when :success then "fa-check"
43
- when :error then "fa-warning"
44
- else "fa-exclamation-triangle"
21
+ when :success then 'fa-check'
22
+ when :error then 'fa-warning'
23
+ else 'fa-exclamation-triangle'
45
24
  end
46
25
  end
47
26
  end
@@ -46,15 +46,12 @@ module Para
46
46
  end
47
47
 
48
48
  def excerpt_value_for(value)
49
- return value unless value.kind_of?(String)
49
+ return value unless value.is_a?(String)
50
50
 
51
- value = sanitize(value, tags: [])
52
-
53
- if (truncated = value[0..100]) != value
54
- "#{ truncated }..."
55
- else
56
- value
57
- end
51
+ truncate(
52
+ sanitize(value, tags: []),
53
+ length: 100
54
+ )
58
55
  end
59
56
  end
60
57
  end
@@ -19,7 +19,7 @@ module Para
19
19
  ),
20
20
  class: 'btn btn-sm btn-icon-primary btn-shadow hint--left',
21
21
  aria: {
22
- label: ::I18n.t('para.shared.edit')
22
+ label: ::I18n.t('para.shared.edit')
23
23
  }
24
24
  ) do
25
25
  content_tag(:i, '', class: 'fa fa-pencil')
@@ -29,13 +29,13 @@ module Para
29
29
  def delete_button(resource)
30
30
  link_to(
31
31
  component.relation_path(resource),
32
- method: :delete,
33
32
  data: {
34
- confirm: ::I18n.t('para.list.delete_confirmation')
33
+ 'turbo-method': :delete,
34
+ 'turbo-confirm': ::I18n.t('para.list.delete_confirmation')
35
35
  },
36
36
  class: 'btn btn-sm btn-icon-danger btn-shadow hint--left',
37
37
  aria: {
38
- label: ::I18n.t('para.shared.destroy')
38
+ label: ::I18n.t('para.shared.destroy')
39
39
  }
40
40
  ) do
41
41
  content_tag(:i, '', class: 'fa fa-times')
@@ -0,0 +1,58 @@
1
+ var ref,
2
+ boundMethodCheck = function(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new Error('Bound instance method accessed before binding'); } };
3
+
4
+ ref = Para.AsyncProgress = class AsyncProgress extends Vertebra.View {
5
+ initialize(options) {
6
+ this.trackProgress = this.trackProgress.bind(this);
7
+ this.onTrackingDataReceived = this.onTrackingDataReceived.bind(this);
8
+ this.onJobError = this.onJobError.bind(this);
9
+
10
+ this.targetUrl = options.progressUrl || this.$el.data('async-progress-url');
11
+ this.$progressBar = this.$el.find('.progress-bar');
12
+ return this.trackProgress();
13
+ }
14
+
15
+ trackProgress() {
16
+ boundMethodCheck(this, ref);
17
+ return $.get(this.targetUrl).done(this.onTrackingDataReceived).fail(this.onJobError);
18
+ }
19
+
20
+ stop() {
21
+ return clearTimeout(this.progressTimeout);
22
+ }
23
+
24
+ onTrackingDataReceived(data) {
25
+ boundMethodCheck(this, ref);
26
+ if (data.status === 'completed') {
27
+ return this.completed();
28
+ } else {
29
+ return this.setProgress(data.progress);
30
+ }
31
+ }
32
+
33
+ setProgress(progress) {
34
+ this.$progressBar.css({
35
+ width: `${progress}%`
36
+ });
37
+ this.progressTimeout = setTimeout(this.trackProgress, 1500);
38
+ return this.trigger('progress');
39
+ }
40
+
41
+ completed() {
42
+ this.$progressBar.css({
43
+ width: "100%"
44
+ });
45
+ this.$progressBar.removeClass('progress-bar-striped').addClass('progress-bar-success');
46
+ return this.trigger('completed');
47
+ }
48
+
49
+ onJobError() {
50
+ boundMethodCheck(this, ref);
51
+ this.$progressBar.css({
52
+ width: "100%"
53
+ });
54
+ this.$progressBar.removeClass('progress-bar-striped').addClass('progress-bar-error');
55
+ return this.trigger('failed');
56
+ }
57
+
58
+ };
@@ -0,0 +1,12 @@
1
+ function initializeFiltersFormSubmit() {
2
+ setTimeout(function() {
3
+ document.querySelectorAll('[data-filters-form]').forEach(function(form) {
4
+ $(form).on("change", "input, select, textarea", function() {
5
+ form.requestSubmit();
6
+ });
7
+ });
8
+ }, 0);
9
+ }
10
+
11
+ document.documentElement.addEventListener('turbo:load', initializeFiltersFormSubmit);
12
+ document.documentElement.addEventListener('turbo:frame-load', initializeFiltersFormSubmit);
@@ -0,0 +1,33 @@
1
+ function trackProgressFor(element, jobStatusUrl) {
2
+ var progressBar = element.querySelector('[data-async-progress]');
3
+ if (!progressBar) return;
4
+
5
+ var progress = new Para.AsyncProgress({ el: progressBar, progressUrl: jobStatusUrl });
6
+
7
+ function handleComplete() {
8
+ $(element).modal('hide');
9
+
10
+ var parentFrame = element.parentNode;
11
+
12
+ parentFrame.addEventListener('turbo:frame-render', function() {
13
+ parentFrame.dispatchEvent(new Event('job:progress:complete'));
14
+ });
15
+
16
+ parentFrame.src = jobStatusUrl;
17
+
18
+ };
19
+
20
+ progress.on('completed', handleComplete);
21
+ progress.on('failed', handleComplete);
22
+ }
23
+
24
+ document.documentElement.addEventListener('turbo:frame-load', function(e) {
25
+ if (e.target.id != 'para_admin_modal') return;
26
+
27
+ loadedElement = e.target.childNodes[0];
28
+
29
+ var jobStatusUrl = loadedElement && loadedElement.dataset.jobStatusUrl;
30
+ if (!jobStatusUrl) return;
31
+
32
+ trackProgressFor(loadedElement, jobStatusUrl);
33
+ });
@@ -0,0 +1,58 @@
1
+ import { PATCH, fetch } from "../lib/fetch";
2
+
3
+ Para.ResourceTable = class ResourceTable {
4
+ constructor($table) {
5
+ this.$table = $table;
6
+ this.$tbody = this.$table.find('tbody');
7
+ this.initializeOrderable();
8
+ }
9
+
10
+ initializeOrderable() {
11
+ this.orderable = this.$table.hasClass('orderable');
12
+ if (!this.orderable) {
13
+ return;
14
+ }
15
+ this.orderUrl = this.$table.data('order-url');
16
+ return this.$tbody.sortable({
17
+ handle: '.order-anchor',
18
+ draggable: 'tr',
19
+ ghostClass: 'sortable-placeholder',
20
+ onUpdate: $.proxy(this.sortUpdate, this)
21
+ });
22
+ }
23
+
24
+ sortUpdate() {
25
+ this.$tbody.find('tr').each(function(i, el) {
26
+ return $(el).find('.resource-position-field').val(i);
27
+ });
28
+ return this.updateOrder();
29
+ }
30
+
31
+ updateOrder() {
32
+ fetch(this.orderUrl, {
33
+ method: PATCH,
34
+ body: this.buildOrderedData()
35
+ });
36
+ }
37
+
38
+ buildOrderedData() {
39
+ const data = new FormData();
40
+
41
+ this.$tbody.find('.resource-position-field').each((i, el) => {
42
+ const $field = $(el);
43
+ const resourceKey = `resources[${i}]`;
44
+
45
+ data.append(`${resourceKey}[id]`, $field.closest('.order-anchor').data('id'));
46
+ data.append(`${resourceKey}[position]`, $field.val());
47
+ });
48
+
49
+ return data;
50
+ }
51
+ };
52
+
53
+ // TODO: Add flash message to display ordering success
54
+ $(document).on('turbo:load turbo:frame-load', function() {
55
+ return $('.para-component-relation-table').each(function(i, el) {
56
+ return new Para.ResourceTable($(el));
57
+ });
58
+ });
@@ -0,0 +1,110 @@
1
+ // Tabs hash management adapted from SO answer :
2
+ // http://stackoverflow.com/a/21443271/685925
3
+
4
+ var ref,
5
+ boundMethodCheck = function(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new Error('Bound instance method accessed before binding'); } };
6
+
7
+ ref = Para.Tabs = (function() {
8
+ class Tabs extends Vertebra.View {
9
+ initialize(options = {}) {
10
+ this.onTabShown = this.onTabShown.bind(this);
11
+
12
+ this.$anchorInput = options.$anchorInput;
13
+ this.showActiveTab();
14
+ this.refreshTabsErrors();
15
+ return this.initializeAffix();
16
+ }
17
+
18
+ showActiveTab() {
19
+ var hash, ref1;
20
+ if ((hash = location.hash || ((ref1 = this.$anchorInput) != null ? ref1.val() : void 0))) {
21
+ return this.findTab(hash).tab('show');
22
+ }
23
+ }
24
+
25
+ onTabShown(e) {
26
+ var $tab, tabHash;
27
+ boundMethodCheck(this, ref);
28
+ $tab = $(e.target);
29
+ if (!$tab.closest('[data-form-tabs]').is('[data-top-level-tabs]')) {
30
+ return;
31
+ }
32
+ tabHash = $tab.attr('href');
33
+ history.pushState(null, null, tabHash);
34
+ return this.updateAnchorInput();
35
+ }
36
+
37
+ updateAnchorInput() {
38
+ if (this.$anchorInput.length) {
39
+ return this.$anchorInput.val(location.hash);
40
+ }
41
+ }
42
+
43
+ refreshTabsErrors() {
44
+ return this.$('[data-toggle="tab"]').each((i, tab) => {
45
+ return this.refreshTabErrors($(tab));
46
+ });
47
+ }
48
+
49
+ refreshTabErrors($tab) {
50
+ var $panel;
51
+ $panel = this.$($tab.attr('href'));
52
+ if ($panel.find('.has-error').length) {
53
+ return $tab.addClass('has-error');
54
+ }
55
+ }
56
+
57
+
58
+ initializeAffix() {
59
+ var headerHeight, offsetTop, sidebarWidth;
60
+ if (!(this.$nav = this.$('[data-affix-header="tabs"]')).length) {
61
+ return;
62
+ }
63
+ headerHeight = $('[data-header]').outerHeight();
64
+ offsetTop = this.$nav.offset().top - headerHeight;
65
+ sidebarWidth = $('[data-admin-left-sidebar]').outerWidth();
66
+ this.$nav.affix({
67
+ offset: {
68
+ top: offsetTop
69
+ }
70
+ }).css({
71
+ top: headerHeight,
72
+ left: sidebarWidth
73
+ });
74
+ // Fix parent wrapper height to maintain the same scroll position when the
75
+ // nav tabs are fixed to top
76
+ return this.$nav.closest('[data-nav-tabs-wrapper]').height(this.$nav.outerHeight());
77
+ }
78
+
79
+ onFormInputUpdate(e) {
80
+ var $tab;
81
+ $tab = this.findTab($(e.currentTarget).attr('id'));
82
+ return this.refreshTabErrors($tab);
83
+ }
84
+
85
+ findTab(id) {
86
+ if (!(id.indexOf('#') >= 0)) {
87
+ id = `#${id}`;
88
+ }
89
+ return this.$('a[href="' + id + '"]');
90
+ }
91
+
92
+ };
93
+
94
+ Tabs.prototype.events = {
95
+ 'shown.bs.tab a[data-toggle="tab"]': 'onTabShown',
96
+ 'change .tab-pane': 'onFormInputUpdate'
97
+ };
98
+
99
+ return Tabs;
100
+
101
+ }).call(this);
102
+
103
+ $(document).on('turbo:load turbo:frame-load', function() {
104
+ return $('[data-form-tabs]').each(function(i, el) {
105
+ return new Para.Tabs({
106
+ el: el,
107
+ $anchorInput: $('[data-current-anchor]')
108
+ });
109
+ });
110
+ });
@@ -0,0 +1,39 @@
1
+ var responsive_sidebar_navigation, scrollToComponentSection;
2
+
3
+ scrollToComponentSection = function($component, duration = 0) {
4
+ var headerHeight, sectionOffset;
5
+ sectionOffset = $component.closest('.component-section-item').offset().top + $('.navmenu').scrollTop();
6
+ headerHeight = $('.navmenu .navmenu-brand').outerHeight();
7
+ return $('.navmenu-nav').scrollTo(sectionOffset - headerHeight, {
8
+ duration: duration
9
+ });
10
+ };
11
+
12
+ responsive_sidebar_navigation = function() {
13
+ var $activeItem;
14
+ // Scroll to active element's section on page change
15
+ if (($activeItem = $('.component-item.active')).length) {
16
+ scrollToComponentSection($activeItem);
17
+ }
18
+ return $('.component-item').on('click', 'a', function(e) {
19
+ return scrollToComponentSection($(e.currentTarget), 150);
20
+ });
21
+ };
22
+
23
+ $(document).on('turbo:load turbo:frame-load', function() {
24
+ responsive_sidebar_navigation();
25
+ return $(".selectize-tags").selectize({
26
+ delimiter: ",",
27
+ persist: false,
28
+ create: function(input) {
29
+ return {
30
+ value: input,
31
+ text: input
32
+ };
33
+ }
34
+ });
35
+ });
36
+
37
+ $(window).resize(function() {
38
+ return responsive_sidebar_navigation();
39
+ });