alchemy-custom-model 2.1.2 → 2.2.0

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 (42) hide show
  1. checksums.yaml +5 -5
  2. data/app/assets/javascripts/alchemy-custom-model/alchemy_custom_model_select.js +62 -0
  3. data/app/assets/javascripts/alchemy-custom-model/common_init.js +17 -14
  4. data/app/assets/javascripts/alchemy-custom-model/el_finder.js.coffee.erb +31 -0
  5. data/app/assets/javascripts/alchemy-custom-model/manifest.js +5 -0
  6. data/app/assets/javascripts/backend/date_picker.js +24 -0
  7. data/app/assets/javascripts/backend/fix_more_image_in_element.js.coffee +10 -0
  8. data/app/assets/javascripts/backend/override_alchemy_selectbox.js +8 -0
  9. data/app/assets/stylesheets/alchemy-custom-model/custom_elfinder.css.scss +20 -2
  10. data/app/controllers/alchemy/custom/model/admin/base_controller.rb +3 -0
  11. data/app/controllers/alchemy/custom/model/admin/base_with_globalize_controller.rb +38 -0
  12. data/app/controllers/concerns/alchemy/admin/nodes_controller_dec.rb +55 -0
  13. data/app/helpers/alchemy/custom/model/admin/base_helper.rb +5 -2
  14. data/app/helpers/alchemy/pages_helper_decorator.rb +38 -0
  15. data/app/models/concerns/alchemy/node_dec.rb +45 -0
  16. data/app/views/alchemy/admin/nodes/_form.html.erb +126 -0
  17. data/app/views/alchemy/admin/nodes/custom_models.json.jbuilder +10 -0
  18. data/app/views/alchemy/admin/nodes/custom_models_methods.json.jbuilder +10 -0
  19. data/app/views/alchemy/admin/pictures/_custom_model_info.html.erb +27 -0
  20. data/app/views/alchemy/admin/pictures/_infos.html.erb +65 -0
  21. data/app/views/alchemy/custom/model/admin/base/_gallery_item.html.erb +7 -2
  22. data/app/views/alchemy/custom/model/admin/base/_seo.html.erb +5 -5
  23. data/app/views/alchemy/custom/model/admin/base/_title.html.erb +1 -1
  24. data/app/views/alchemy/custom/model/admin/base/edit.html.erb +2 -2
  25. data/app/views/alchemy/custom/model/admin/base/index.html.erb +1 -1
  26. data/app/views/alchemy/custom/model/admin/base/new.html.erb +2 -2
  27. data/app/views/alchemy/custom/model/admin/base/show.html.erb +2 -2
  28. data/config/locales/it.yml +6 -0
  29. data/config/routes.rb +16 -0
  30. data/db/migrate/20200424184007_add_fields_to_node.rb +8 -0
  31. data/lib/{alchemy-custom-model.rb → alchemy/custom/model.rb} +20 -0
  32. data/lib/alchemy/custom/model/engine.rb +7 -1
  33. data/lib/alchemy/custom/model/globalize_model_decoration.rb +25 -0
  34. data/lib/alchemy/custom/model/menu_methods.rb +16 -0
  35. data/lib/alchemy/custom/model/model_decoration.rb +2 -0
  36. data/lib/alchemy/custom/model/model_utils_methods.rb +28 -0
  37. data/lib/alchemy/custom/model/picture_used_by.rb +51 -0
  38. data/lib/alchemy/custom/model/slug_optimizer.rb +23 -0
  39. data/lib/alchemy/custom/model/version.rb +1 -1
  40. data/lib/tasks/alchemy_custom_model_tasks.rake +3 -0
  41. data/vendor/assets/javascripts/flatpickr/i10n/it.js +71 -0
  42. metadata +53 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 18dbecf67db40ed24197196da81d783276e051fd
4
- data.tar.gz: e621f92260133cd31d1636c4b5a2ae4e4d173e78
2
+ SHA256:
3
+ metadata.gz: 1a2697b7c047652bd81eff2eea2f6ce536f17b636ee6e200fa0d79de57183544
4
+ data.tar.gz: b6463926d7a0e7dec5a118fe74fc71a92293a46eba4bec350f3f5ca454c1ad6e
5
5
  SHA512:
6
- metadata.gz: f555a7ffc0e4e0eb68cc1b8b79e6b60ad7f60f29490c505d3270b4d99b625da384b775027d6ab317b0ba9c39410740d51f190c4a08e1967bfdb50c061f0a92b1
7
- data.tar.gz: 8a0779d78372fb4c2f39a5123572ca752b22085e4309545399ba9a51fcc07e9bbbd1be87cfefd3d37f3b609c8c3202457cf90cdd8c3eb4976eaf2abcbfe66bb0
6
+ metadata.gz: f5252ad81308db97abf919cc87dc6e7c70031f4f8a4ece43aa8776458bc39723d1dfafce7dcb92a0d15b8bbc7bd81ec553f691e5f052a2ab5bc33fbff30c1e8f
7
+ data.tar.gz: f818915cbacb6cc271954c4aa5f57cae5bf67ff56cce88c2c997eb057e6cf8f13ce30ac7d6332f9f5b42da1b23810574b0bfa1e8c25d49362d02eefbbfbb34a4
@@ -0,0 +1,62 @@
1
+ $.fn.alchemyCustomModelSelect = function(options) {
2
+
3
+ return this.select2({
4
+ placeholder: options.placeholder,
5
+ allowClear: true,
6
+ initSelection: function(element, callback) {
7
+ console.log("pippo")
8
+ var id = $(element).val();
9
+ console.log(id)
10
+ if (id !== "") {
11
+ var q = {}
12
+ if (options.query_params){
13
+ q = options.query_params()
14
+ }
15
+ $.ajax(options.url, {
16
+ dataType: "json",
17
+ data: {
18
+ id: id,
19
+ q: q,
20
+ per_page: 3000
21
+ }
22
+ }).done(function(data) {
23
+ var el = null
24
+ $.each(data.results, function(index,element){
25
+ if (element.text == id){
26
+
27
+ el = element
28
+ }
29
+ })
30
+ callback(el);
31
+ });
32
+ }
33
+ },
34
+ ajax: {
35
+ url: options.url,
36
+ datatype: 'json',
37
+ quietMillis: 300,
38
+ data: function (term, page) {
39
+ var extend_query_params = {}
40
+ if (options.query_params) {
41
+
42
+ extend_query_params = options.query_params(term,page)
43
+
44
+ }
45
+ return {
46
+ q: $.extend({
47
+ name: term
48
+ }, extend_query_params),
49
+ page: page
50
+ }
51
+ },
52
+ results: function (data) {
53
+ var meta = data.meta
54
+ return {
55
+ results: data.results,
56
+ more: meta.page * meta.per_page < meta.total_count
57
+ }
58
+ }
59
+ },
60
+
61
+ })
62
+ }
@@ -1,16 +1,19 @@
1
- $(document).on("'page:change turbolinks:load", function(){
2
- $(".datepicker-date").datetimepicker({
3
- scrollInput: false,
4
- format: "d/m/Y",
5
- timepicker: false,
6
- datepicker: true,
7
- dayOfWeekStart: 0
8
- })
1
+ $(document).on("'page:change turbolinks:load", function () {
9
2
 
10
- $(".datepicker-time").datetimepicker({
11
- format:'H:i',
12
- timepicker: true,
13
- datepicker: false,
14
- step: 15
15
- })
3
+ if ($.isFunction("datetimepicker")) {
4
+ $(".datepicker-date").datetimepicker({
5
+ scrollInput: false,
6
+ format: "d/m/Y",
7
+ timepicker: false,
8
+ datepicker: true,
9
+ dayOfWeekStart: 0
10
+ })
11
+
12
+ $(".datepicker-time").datetimepicker({
13
+ format: 'H:i',
14
+ timepicker: true,
15
+ datepicker: false,
16
+ step: 15
17
+ })
18
+ }
16
19
  });
@@ -196,8 +196,26 @@ class ElFinderDialog
196
196
  $.ajax
197
197
  url: @opts.target_upgrader
198
198
  success: (data)=>
199
+
200
+ imgs_gallery = $(@opts.target).find(".gallery_item_blk")
201
+ imgs_destroyed_ids = []
202
+ $.each imgs_gallery, (index,element) ->
203
+ destroyed_input = $(element).find(".gallery_item_destroy_input")[0]
204
+ if($(destroyed_input).val()== "true")
205
+ imgs_destroyed_ids.push($(element).data("id"))
206
+
199
207
  elemento_gallery = $(data).find(@opts.target)
200
208
  $(@opts.target).html($(elemento_gallery).html())
209
+ target = @opts.target
210
+ gal_el = null
211
+ $.each imgs_destroyed_ids, (index,id) ->
212
+ el_to_hide = $(target).find(".gallery_item_blk[data-id='#{id}']")
213
+ input_destroy = $(el_to_hide).find(".gallery_item_destroy_input")[0]
214
+ $(el_to_hide).hide()
215
+ $(input_destroy).val(true)
216
+
217
+ # #elemento_gallery = $(data).find(@opts.target)
218
+ # $(@opts.target).html($(gal_el).html())
201
219
 
202
220
 
203
221
  open: ->
@@ -234,6 +252,19 @@ $(document).on 'click', '.clear_selection', (e)->
234
252
  $(opts.clearfieldIcon).attr('class','')
235
253
 
236
254
 
255
+ $(document).on 'click', '.elfinder_picture_gallery .gallery_item_blk .destroy', (e)->
256
+ img_container = $(this).parents(".gallery_item_blk")[0]
257
+ input_destroy = $(img_container).find(".gallery_item_destroy_input")[0]
258
+ $(input_destroy).val(true)
259
+ $(img_container).hide()
260
+
261
+ $(document).on 'page:change turbolinks:load', ->
262
+ $(".elfinder_picture_gallery .gallery_item_blk").each (index,element) ->
263
+ input_destroy = $(element).find(".gallery_item_destroy_input")[0]
264
+ img_container = $(element)
265
+ if($(input_destroy).val() == "true")
266
+ $(img_container).hide()
267
+ $(input_destroy).val(true)
237
268
 
238
269
 
239
270
 
@@ -22,3 +22,8 @@
22
22
  //= require "./total_page_elfinder"
23
23
  //= require "./sortable"
24
24
  //= require "./common_init"
25
+ //= require "./alchemy_custom_model_select"
26
+ //= require "flatpickr/i10n/it"
27
+ //= require "../backend/date_picker"
28
+ //= require "../backend/fix_more_image_in_element"
29
+ //= require "../backend/override_alchemy_selectbox"
@@ -0,0 +1,24 @@
1
+ $(document).on("page:change turbolinks:load",function(){
2
+
3
+ $("input[data-alchemy-datepicker-type]").each(function(index,element){
4
+ var type = $(this).data('alchemy-datepicker-type');
5
+ var options = {
6
+ locale: Alchemy.locale.slice(0, 2),
7
+ altInput: true,
8
+ altFormat: Alchemy.t("formats."+type),
9
+ altInputClass: "",
10
+ enableTime: /time/.test(type),
11
+ noCalendar: type == "time",
12
+ time_24hr: Alchemy.t("formats.time_24hr"),
13
+
14
+ };
15
+
16
+ $(this).flatpickr(options);
17
+
18
+
19
+
20
+ })
21
+
22
+
23
+
24
+ });
@@ -0,0 +1,10 @@
1
+ $.extend Alchemy,
2
+ removePicture: (selector) ->
3
+ $form_field = $(selector)
4
+ $element = $form_field.closest(".element-editor")
5
+ $content = $form_field.closest(".content_editor")
6
+ if $form_field[0]
7
+ $form_field.val ""
8
+ $content.find(".thumbnail_background").html('<i class="icon far fa-image fa-fw"/>')
9
+ Alchemy.setElementDirty $element
10
+ false
@@ -0,0 +1,8 @@
1
+ $(document).ready(function(){
2
+
3
+ $("select.alchemy_selectbox").select2({
4
+ minimumResultsForSearch: 7,
5
+ dropdownAutoWidth: true,
6
+ allowClear: true
7
+ });
8
+ })
@@ -13,9 +13,26 @@
13
13
  display: block;
14
14
  float: left;
15
15
  margin: 6px;
16
- width: 100px;
17
- height: 100px;
16
+ width: 140px;
17
+ height: 140px;
18
18
  overflow: hidden;
19
+ position: relative;
20
+
21
+ .command_area {
22
+ position: absolute;
23
+ left: 0;
24
+ bottom: 0;
25
+ z-index: 0;
26
+ width: 100%;
27
+ padding: 4px 2px;
28
+ background-color: #f0f0f0;
29
+ .destroy {
30
+ float: right;
31
+ color: rgba(51, 59, 81, 0.8);
32
+ cursor: pointer
33
+ }
34
+ }
35
+
19
36
 
20
37
  .open_el_finder {
21
38
  width: 98%;
@@ -28,6 +45,7 @@
28
45
  i.fa-images {
29
46
  font-size: 50px;
30
47
  margin-top: 20px;
48
+ line-height: 90px;
31
49
  }
32
50
  }
33
51
  }
@@ -20,6 +20,7 @@ module Alchemy::Custom::Model
20
20
  @query = base_class.ransack(params[:q])
21
21
  @objects = @query.result(distinct: true)
22
22
  @objects = @objects.accessible_by(current_ability).only_current_language
23
+ @total_objects = @objects
23
24
  @objects = @objects.page(params[:page]).
24
25
  per(params[:per_page] ||
25
26
  (base_class::DEFAULT_PER_PAGE if base_class.const_defined? :DEFAULT_PER_PAGE) ||
@@ -64,6 +65,7 @@ module Alchemy::Custom::Model
64
65
  if @obj.respond_to? self.class.method_for_show
65
66
  @objects = @obj.send(self.class.method_for_show.to_sym)
66
67
  @objects = @objects.accessible_by(current_ability)
68
+ @total_objects = @objects
67
69
  @objects = @objects.page(params[:page]).
68
70
  per(params[:per_page] ||
69
71
  (base_class::DEFAULT_PER_PAGE if base_class.const_defined? :DEFAULT_PER_PAGE) ||
@@ -79,6 +81,7 @@ module Alchemy::Custom::Model
79
81
  @query = base_class.ransack(params[:q])
80
82
  @objects = @query.result(distinct: true)
81
83
  @objects = @objects.accessible_by(current_ability)
84
+ @total_objects = @objects
82
85
  @objects = @objects.page(params[:page]).
83
86
  per(params[:per_page] ||
84
87
  (base_class::DEFAULT_PER_PAGE if base_class.const_defined? :DEFAULT_PER_PAGE) ||
@@ -0,0 +1,38 @@
1
+ module Alchemy
2
+ module Custom
3
+ module Model
4
+ module Admin
5
+ class BaseWithGlobalizeController < ::Alchemy::Custom::Model::Admin::BaseController
6
+
7
+
8
+ around_action :switch_globalize_locale
9
+ before_action :load_object, except: :index
10
+
11
+
12
+ def index
13
+ @query = base_class.ransack(params[:q])
14
+ @objects = @query.result(distinct: true)
15
+ @objects = @objects.accessible_by(current_ability)
16
+ @total_objects = @objects
17
+ @objects = @objects.page(params[:page]).
18
+ per(params[:per_page] ||
19
+ (base_class::DEFAULT_PER_PAGE if base_class.const_defined? :DEFAULT_PER_PAGE) ||
20
+ 25)
21
+ instance_variable_set "@#{base_class.name.demodulize.underscore.downcase.pluralize}", @objects
22
+ end
23
+
24
+
25
+
26
+ private
27
+
28
+ def switch_globalize_locale(&action)
29
+ locale = Alchemy::Language.current.language_code.to_sym
30
+ Globalize.with_locale(locale, &action)
31
+ end
32
+
33
+
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,55 @@
1
+ module Alchemy
2
+ module Admin
3
+ module NodesControllerDec
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+
8
+ def custom_models
9
+ @custom_model_klasses = Alchemy::Custom::Model.allowed_custom_models_for_menu
10
+ if params[:q] and params[:q][:name]
11
+ @custom_model_klasses = @custom_model_klasses.select { |el| el.match /#{params[:q][:name]}/i }
12
+ end
13
+ @custom_model_klasses = Kaminari.paginate_array(@custom_model_klasses).page(params[:page]).per(params[:per_page] || 10)
14
+
15
+ end
16
+
17
+ def custom_models_methods
18
+ @custom_model_klasses = Alchemy::Custom::Model.allowed_custom_models_for_menu
19
+ @custom_model_methods = []
20
+ if params[:q] and params[:q][:custom_model_klass]
21
+ klass = Alchemy::Custom::Model.allowed_custom_models_for_menu.select { |el| el == params[:q][:custom_model_klass] }.first
22
+ if !klass.nil? and klass.safe_constantize
23
+ klass = klass.constantize
24
+ if klass.respond_to? :menu_generator_methods
25
+ @custom_model_methods = klass.menu_generator_methods
26
+ end
27
+ end
28
+ end
29
+ @custom_model_methods = Kaminari.paginate_array(@custom_model_methods).page(params[:page]).per(params[:per_page] || 10)
30
+ end
31
+
32
+
33
+ private
34
+
35
+ def resource_params
36
+ params.require(:node).permit(
37
+ :site_id,
38
+ :parent_id,
39
+ :language_id,
40
+ :page_id,
41
+ :name,
42
+ :url,
43
+ :title,
44
+ :nofollow,
45
+ :external,
46
+ :custom_model_klass,
47
+ :custom_model_method
48
+ )
49
+ end
50
+
51
+
52
+ end
53
+ end
54
+ end
55
+ end
@@ -221,9 +221,12 @@ module Alchemy::Custom::Model::Admin::BaseHelper
221
221
  component_id = SecureRandom.hex(10)
222
222
 
223
223
  bf << form.fields_for(field) do |join_record_form|
224
- render(layout: 'gallery_item', locals: {picture: join_record_form.object.picture}) do
224
+ render(layout: 'gallery_item', locals: {picture: join_record_form.object.picture, jr_id: join_record_form.object.id}) do
225
+ sb = ActiveSupport::SafeBuffer.new
225
226
 
226
- join_record_form.hidden_field :position, class: 'gallery_position_counter'
227
+ sb << join_record_form.hidden_field(:position, class: 'gallery_position_counter')
228
+ sb << join_record_form.hidden_field(:_destroy, class: 'gallery_item_destroy_input')
229
+ sb
227
230
 
228
231
  end
229
232
  end
@@ -91,5 +91,43 @@ Alchemy::PagesHelper.module_eval do
91
91
  end
92
92
 
93
93
 
94
+ def check_if_active node_or_cm_inst
95
+ if !node_or_cm_inst.is_a? Alchemy::Node
96
+ if node_or_cm_inst.respond_to? :for_menu_matching and node_or_cm_inst.for_menu_matching.include? @custom_element
97
+ return true
98
+ end
99
+ else
100
+ if node_or_cm_inst.custom_model?
101
+ if @custom_element.respond_to? :for_menu_matching and
102
+ @custom_element.for_menu_matching.include? node_or_cm_inst.klass_custom_model
103
+ return true
104
+ end
105
+ elsif node_or_cm_inst.page and node_or_cm_inst.page.self_and_descendants.include? @page
106
+ return true
107
+ end
108
+ end
109
+ false
110
+ end
111
+
112
+ def render_menu_with_language(name, options = {})
113
+ root_node = Alchemy::Node.where(language_id: Alchemy::Language.current.id).roots.find_by(name: name)
114
+ if root_node.nil?
115
+ warning("Menu with name #{name} not found!")
116
+ return
117
+ end
118
+
119
+ options = {
120
+ node_partial_name: "#{root_node.view_folder_name}/node"
121
+ }.merge(options)
122
+
123
+ render(root_node, menu: root_node, node: root_node, options: options)
124
+ rescue ActionView::MissingTemplate => e
125
+ warning <<-WARN
126
+ Menu partial not found for #{name}.
127
+ #{e}
128
+ WARN
129
+ end
130
+
131
+
94
132
  end
95
133
 
@@ -0,0 +1,45 @@
1
+ module Alchemy
2
+ module NodeDec
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+
8
+ validates :custom_model_klass, presence: true, if: -> {
9
+ url.blank? and not parent.nil?
10
+ }
11
+
12
+ before_validation :ensure_page_nil_if_custom_model, on: [:create, :update]
13
+ before_validation :set_site, on: [:create], if: -> {site.nil?}
14
+
15
+ def custom_model?
16
+ !custom_model_klass.blank?
17
+ end
18
+
19
+ def klass_custom_model
20
+ self.custom_model_klass.constantize
21
+ end
22
+
23
+ private
24
+
25
+ def ensure_page_nil_if_custom_model
26
+ if not url.blank? and !custom_model_klass_changed? and !custom_model_method_changed?
27
+ self.custom_model_klass = nil
28
+ self.custom_model_method = nil
29
+ elsif !custom_model_klass.blank? and !url_changed?
30
+ self.page = nil
31
+ self.url = nil
32
+ end
33
+
34
+ end
35
+
36
+ def set_site
37
+ unless self.language.nil?
38
+ self.site = language.site
39
+ end
40
+ end
41
+
42
+
43
+ end
44
+ end
45
+ end