sibu 1.0.6 → 1.0.11

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96611f8f7b23adda4d4502b1eef05f34d0a4dea2
4
- data.tar.gz: 27fe50a309c23dfe80bce28c687d6fc05d96452d
3
+ metadata.gz: ddad9d6305d71605c692e8dbdafadb0c6cce1d7a
4
+ data.tar.gz: 91539711c089a4d111dede2965a554051c590dc5
5
5
  SHA512:
6
- metadata.gz: 3022613a600e634834e57373d4fefae4e760eda752e7966c5da5f403e7464d9279a0c1dd5277bdd97f9cbac101df450290a0762ea6a58183079362fd87d003c5
7
- data.tar.gz: 530731b14939afd5615a25df8c1d0834f541c41343484ddfb256b0b1f98b53981fa513ee4b584c1ac6b6067b8d4d20ea0450aa2466955daaf18844509f84ebeb
6
+ metadata.gz: e025dc9b575fedeb91471848f78487b4ba1e3e7fbb19e81822bc31576aae2cd764326ce75bd6e39dd2d2b9ea0901d30f5b33bcef1a26a354a62f90f3d3d74a05
7
+ data.tar.gz: cb43b5c568dcd4c9323944645c2ab6935f81988d8a95fe3c47902115db8070bf8e2f10253174d8eaa73074f63348bce2acb724e0c69171e1ff8540355a8db827
@@ -0,0 +1,4 @@
1
+ module Sibu
2
+ module ExtendableHelper
3
+ end
4
+ end
@@ -27,6 +27,13 @@ module Sibu
27
27
  options_from_collection_for_select(Sibu::Document.for_user(sibu_user), :file_url, :file_name, @element["value"])
28
28
  end
29
29
 
30
+ def input_categories
31
+ options_for_select([['Nom', 'name'], ['Adresse', 'address'], ['Email', 'email'], ['Téléphone', 'telephone'],
32
+ ['Arrivée', 'arrival_date'], ['Départ', 'departure_date'], ['Nombre de personnes', 'people'],
33
+ ['Message (texte libre)', 'message'], ['Inscription à la newsletter', 'newsletter']],
34
+ @element["field_name"])
35
+ end
36
+
30
37
  def link_type(val)
31
38
  if val.blank? || /^\d+$/.match(val.to_s)
32
39
  'internal'
@@ -111,6 +118,13 @@ module Sibu
111
118
  nested_elts.map {|e| e.merge({"data-id" => join_tokens(element_id_tokens[1..-1], e['id'])})}
112
119
  end
113
120
 
121
+ def each_element(elt_or_id)
122
+ element_id = elt_id(elt_or_id)
123
+ @sb_section = (@sb_section + element_id.split("|")).uniq unless element_id.blank?
124
+ (@sb_entity.elements(*@sb_section) || []).map {|el| yield(el)}
125
+ @sb_section -= [element_id] unless element_id.blank?
126
+ end
127
+
114
128
  def select_element(id)
115
129
  @sb_entity.element(*@sb_section, id)
116
130
  end
@@ -139,6 +153,22 @@ module Sibu
139
153
  html_output
140
154
  end
141
155
 
156
+ def svg_image(elt, opts = {})
157
+ size = opts.delete(:size)
158
+ t_id = elt.is_a?(Hash) ? elt["id"] : elt
159
+ defaults = {"id" => t_id, "xlink:href" => Sibu::DEFAULT_IMG}
160
+ content = defaults.merge((elt.is_a?(Hash) ? elt : (select_element(elt) || {})).transform_keys {|k| k == 'src' ? 'xlink:href' : k})
161
+ @sb_section = (@sb_section || []) + [t_id]
162
+ if action_name == 'show'
163
+ content["xlink:href"] = ("/#{conf[:deployment_path]}" + content["xlink:href"]) if @online && conf[:deployment_path]
164
+ else
165
+ opts.merge!({data: {id: @sb_section[1..-1].join('|'), type: "media", repeat: false, size: size}})
166
+ end
167
+ html_output = content_tag(:image, nil, content.except("id").merge(opts.stringify_keys) {|k, old, new| k == 'class' ? [old, new].join(' ') : new})
168
+ @sb_section -= [t_id]
169
+ html_output
170
+ end
171
+
142
172
  def grp(elt, opts = {}, &block)
143
173
  wrapper = opts.delete(:wrapper) || :div
144
174
  repeat = opts.delete(:repeat)
@@ -162,10 +192,49 @@ module Sibu
162
192
  end
163
193
 
164
194
  def form_label(elt, html_opts = {}, &block)
165
- defaults = {"id" => elt.is_a?(Hash) ? elt["id"] : elt, "text" => Sibu::DEFAULT_TEXT}
195
+ t_id = elt.is_a?(Hash) ? elt["id"] : elt
196
+ defaults = {"id" => t_id, "text" => Sibu::DEFAULT_TEXT}
166
197
  content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
167
- html_opts.merge!({data: {id: elt_id(elt), type: "text"}}) if action_name != 'show'
168
- content_tag(:label, raw(content["text"]).html_safe, html_opts)
198
+ @sb_section = (@sb_section || []) + [t_id]
199
+ html_opts.merge!({data: {id: @sb_section[1..-1].join('|'), type: "text"}}) if action_name != 'show'
200
+ html_output = content_tag(:label, raw(content["text"]).html_safe, html_opts)
201
+ @sb_section -= [t_id]
202
+ html_output
203
+ end
204
+
205
+ def form_input(elt, html_opts = {})
206
+ repeat = html_opts.delete(:repeat)
207
+ children = html_opts.delete(:children)
208
+ t_id = elt.is_a?(Hash) ? elt["id"] : elt
209
+ opts = {"id" => t_id}.merge(html_opts.stringify_keys).merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {}))
210
+ form_name = opts.delete('form_name') || 'contact'
211
+ field_name = opts.delete('field_name') || 'name'
212
+ name_attr = "#{form_name}[#{field_name}]"
213
+
214
+ @sb_section = (@sb_section || []) + [t_id]
215
+ opts.merge!({data: {id: @sb_section[1..-1].join('|'), type: "input", repeat: repeat, children: children}}) if action_name != 'show'
216
+
217
+ case field_name
218
+ when 'name', 'address'
219
+ html_output = content_tag(:input, nil, opts.merge('type' => 'text', 'name' => name_attr))
220
+ when 'email'
221
+ html_output = content_tag(:input, nil, opts.merge('type' => 'email', 'name' => name_attr))
222
+ when 'telephone'
223
+ html_output = content_tag(:input, nil, opts.merge('type' => 'tel', 'name' => name_attr))
224
+ when 'arrival_date', 'departure_date'
225
+ html_output = content_tag(:input, nil, opts.merge('type' => 'date', 'name' => name_attr))
226
+ when 'people'
227
+ html_output = content_tag(:input, nil, opts.merge('type' => 'number', 'name' => name_attr))
228
+ when 'message'
229
+ html_output = content_tag(:textarea, nil, opts.merge('name' => name_attr))
230
+ when 'newsletter'
231
+ html_output = content_tag(:input, nil, opts.merge('type' => 'checkbox', 'name' => name_attr))
232
+ else
233
+ html_output = content_tag(:input, nil, opts.merge('type' => 'text', 'name' => name_attr))
234
+ end
235
+
236
+ @sb_section -= [t_id]
237
+ html_output
169
238
  end
170
239
 
171
240
  def widget(elt, widget_type, opts = {}, &block)
@@ -196,16 +265,17 @@ module Sibu
196
265
 
197
266
  alias site sb_site
198
267
 
199
- def render_page_section(s)
268
+ def render_page_section(s, set_id = false)
200
269
  @sb_section = [s['id']]
201
270
  @sb_entity = @page
202
271
  render partial: "shared/#{@site.section_template(s)}",
203
- locals: {sibu: self, sibu_section: s, sibu_attrs: sibu_attributes(s).html_safe}
272
+ locals: {sibu: self, sibu_section: s, sibu_attrs: sibu_attributes(s, set_id).html_safe}
204
273
  end
205
274
 
206
275
  # Page sections attrs
207
- def sibu_attributes(section)
208
- action_name != 'show' ? ('data-sb-id="' + section['id'] + '" data-sb-entity="page"') : ''
276
+ def sibu_attributes(section, set_id)
277
+ attrs = set_id ? ('id="' + section['id'] + '" ') : ''
278
+ attrs + (action_name != 'show' ? ('data-sb-id="' + section['id'] + '" data-sb-entity="page"') : '')
209
279
  end
210
280
 
211
281
  # Site sections attrs
@@ -267,10 +337,10 @@ module Sibu
267
337
  end
268
338
 
269
339
  def interactive_map(elt, html_opts = {})
270
- defaults = {"data-lat" => "46.1988027", "data-lng" => "5.1748288", "data-title" => Sibu::DEFAULT_TEXT}
340
+ defaults = {"data-lat" => "46.1988027", "data-lng" => "5.1748288"}
271
341
  content = defaults.merge(elt.is_a?(Hash) ? elt : (select_element(elt) || {"id" => elt}))
272
342
  html_opts.merge!({data: {id: elt_id(elt), type: "map"}}) if action_name != 'show'
273
- content_tag(:div, nil, content.merge(html_opts))
343
+ content_tag(:div, nil, content.merge(html_opts.stringify_keys))
274
344
  end
275
345
 
276
346
  def elt_id(elt)
@@ -1,31 +1,36 @@
1
1
  module Sibu
2
2
  class DynamicStyle
3
3
 
4
- attr_reader :site, :body, :env, :filename, :scss_file
4
+ attr_reader :site, :body, :env, :filename, :scss_file, :styles_changed
5
5
 
6
6
  def initialize(site_id)
7
7
  @site = Sibu::Site.find(site_id)
8
- @filename = "#{site_id}_#{Time.current.to_i}"
9
- @scss_file = File.new(scss_file_path, 'w')
10
- @body = ERB.new(File.read(template_file_path)).result(binding)
11
- @env = Rails.application.assets
8
+ @styles_changed = @site.style.nil? || styles_changed?(@site.style_url)
9
+ if @styles_changed
10
+ @filename = "#{site_id}_#{Time.current.to_i}"
11
+ @scss_file = File.new(scss_file_path, 'w')
12
+ @body = ERB.new(File.read(template_file_path)).result(binding)
13
+ @env = Rails.application.assets
14
+ end
12
15
  end
13
16
 
14
17
  def compile
15
- find_or_create_scss
18
+ if @styles_changed
19
+ find_or_create_scss
16
20
 
17
- begin
18
- scss_file.write generate_css
19
- scss_file.flush
20
- scss_file.close
21
- css_file_path = scss_file_path.gsub('scss', 'css')
22
- File.rename(scss_file_path, css_file_path)
23
- site.update(style: File.new(css_file_path))
24
- rescue Exception => ex
25
- Rails.logger.error(ex)
26
- ensure
27
- File.delete(scss_file_path) if scss_file_path && File.exist?(scss_file_path)
28
- File.delete(css_file_path) if css_file_path && File.exist?(css_file_path)
21
+ begin
22
+ scss_file.write generate_css
23
+ scss_file.flush
24
+ scss_file.close
25
+ css_file_path = scss_file_path.gsub('scss', 'css')
26
+ File.rename(scss_file_path, css_file_path)
27
+ site.update(style: File.new(css_file_path))
28
+ rescue Exception => ex
29
+ Rails.logger.error(ex)
30
+ ensure
31
+ File.delete(scss_file_path) if scss_file_path && File.exist?(scss_file_path)
32
+ File.delete(css_file_path) if css_file_path && File.exist?(css_file_path)
33
+ end
29
34
  end
30
35
  end
31
36
 
@@ -73,5 +78,16 @@ module Sibu
73
78
  env.load(asset.uri).source
74
79
  end
75
80
  end
81
+
82
+ def styles_changed?(site_style_url)
83
+ templates_styles_path = File.join(Rails.root, 'app', 'assets', 'stylesheets', 'templates', '**/*')
84
+ style_updated_at = File.new(File.join(Rails.root, 'public', site_style_url)).mtime
85
+ Dir.glob(templates_styles_path) do |style_file|
86
+ if File.new(style_file).mtime > style_updated_at
87
+ return true
88
+ end
89
+ end
90
+ false
91
+ end
76
92
  end
77
93
  end
@@ -51,13 +51,6 @@ module Sibu
51
51
  pages.where(id: page_id).select(:id, :path).first
52
52
  end
53
53
 
54
- def update_paths
55
- pages.each do |p|
56
- p.update_path(true)
57
- p.save
58
- end
59
- end
60
-
61
54
  def save_and_init
62
55
  if valid?
63
56
  self.sections = site_template.sections
@@ -46,6 +46,8 @@
46
46
  <% end %>
47
47
  <%= javascript_include_tag 'sibu/sibu' %>
48
48
  <script>
49
+ var sectionsState = {};
50
+
49
51
  document.addEventListener("DOMContentLoaded", function() {
50
52
  initOverlays("<%= @edit_section || '' %>");
51
53
  sibuCallback("editContent");
@@ -63,7 +65,7 @@
63
65
  rightOverlay.style.height = height + "px";
64
66
  rightOverlay.style.left = left + width + "px";
65
67
  rightOverlay.style.top = top + "px";
66
- editModeActions.style.top = (top <= 120 ? (top + height) : (top - 40 - 20)) + "px";
68
+ editModeActions.style.top = (top + height) + "px";
67
69
  editModeActions.style.left = left + "px";
68
70
  editModeActions.style.width = width + "px";
69
71
  editMode.querySelector("#edit_section_msg").innerText = "Modifier la section";
@@ -77,8 +79,6 @@
77
79
  editMode.querySelector("#new_section_after").style.display = "block";
78
80
  editMode.querySelector("#delete_section").style.display = "block";
79
81
  }
80
- var topPadding = top <= 120 ? 60 : 120;
81
- window.scrollTo(0, top - topPadding);
82
82
  section.classList.add('sb-editing');
83
83
  initInnerOverlays(section);
84
84
  document.querySelector("#edit_overlays").innerHTML = "";
@@ -211,25 +211,29 @@
211
211
  }
212
212
 
213
213
  function initInnerOverlays(section) {
214
- var editables = section.querySelectorAll("[data-type]");
215
- for (var i = 0; i < editables.length; i++) {
216
- if (editables[i].getAttribute("data-type") !== 'group' || editables[i].getAttribute("data-repeat") === 'true' || editables[i].getAttribute("data-children") === 'true') {
217
- editables[i].addEventListener("mouseenter", function(evt) {
218
- evt.stopPropagation();
219
- evt.currentTarget.classList.add("sb-editable");
220
- });
221
- editables[i].addEventListener("mouseleave", function(evt) {
222
- evt.currentTarget.classList.remove("sb-editable");
223
- });
224
- editables[i].addEventListener("click", function(evt) {
225
- evt.stopPropagation();
226
- evt.preventDefault();
227
- var elt = evt.currentTarget, eltId = elt.getAttribute("data-id"), repeat = elt.getAttribute("data-repeat"),
228
- type = elt.getAttribute("data-type"), size = elt.getAttribute("data-size"), children = elt.getAttribute("data-children");
229
- var sectionId = section.getAttribute("data-sb-id"), entity = section.getAttribute("data-sb-entity");
230
- editContent(eltId, sectionId, entity, repeat, type, size, children);
231
- });
214
+ var sectionId = section.getAttribute('data-sb-id');
215
+ if (!sectionsState[sectionId]) {
216
+ var editables = section.querySelectorAll("[data-type]");
217
+ for (var i = 0; i < editables.length; i++) {
218
+ if (editables[i].getAttribute("data-type") !== 'group' || editables[i].getAttribute("data-repeat") === 'true' || editables[i].getAttribute("data-children") === 'true') {
219
+ editables[i].addEventListener("mouseenter", function(evt) {
220
+ evt.stopPropagation();
221
+ evt.currentTarget.classList.add("sb-editable");
222
+ });
223
+ editables[i].addEventListener("mouseleave", function(evt) {
224
+ evt.currentTarget.classList.remove("sb-editable");
225
+ });
226
+ editables[i].addEventListener("click", function(evt) {
227
+ evt.stopPropagation();
228
+ evt.preventDefault();
229
+ var elt = evt.currentTarget, eltId = elt.getAttribute("data-id"), repeat = elt.getAttribute("data-repeat"),
230
+ type = elt.getAttribute("data-type"), size = elt.getAttribute("data-size"), children = elt.getAttribute("data-children");
231
+ var sectionId = section.getAttribute("data-sb-id"), entity = section.getAttribute("data-sb-entity");
232
+ editContent(eltId, sectionId, entity, repeat, type, size, children);
233
+ });
234
+ }
232
235
  }
236
+ sectionsState[sectionId] = 'ready';
233
237
  }
234
238
  }
235
239
 
@@ -256,7 +260,7 @@
256
260
  };
257
261
  })(sections[i], sectionBox.left, yOffset, width, height));
258
262
  }
259
- if (activeSection) {
263
+ if (activeSection && document.querySelector("[data-sb-overlay='" + activeSection + "']")) {
260
264
  document.querySelector("[data-sb-overlay='" + activeSection + "']").click();
261
265
  }
262
266
  }, 800);
@@ -0,0 +1,24 @@
1
+ <h2>Modifier le champ de saisie</h2>
2
+ <div id="edit_msg"></div>
3
+ <%= render 'element_actions' %>
4
+ <div class="sibu_edit_form">
5
+ <form class="edit_element_form" action="<%= update_element_site_page_path(@site.id, @page.id, format: :js) %>" accept-charset="UTF-8" method="patch">
6
+ <div class="sibu_field">
7
+ <%= label_tag 'element[field_name]', 'Type de champ' %>
8
+ <%= select_tag 'element[field_name]', input_categories, prompt: 'Sélectionnez un type de champ' %>
9
+ </div>
10
+ <div class="sibu_field">
11
+ <%= label_tag 'element[placeholder]', "Texte d'aide (optionnel)" %>
12
+ <%= text_field_tag 'element[placeholder]', @element["placeholder"] %>
13
+ </div>
14
+
15
+ <%= hidden_field_tag 'element[id]', @element["id"] %>
16
+ <%= hidden_field_tag :element_id, @element_id %>
17
+ <%= hidden_field_tag :section_id, @section_id %>
18
+ <%= hidden_field_tag :entity, @entity_type %>
19
+ <div class="sibu_actions">
20
+ <%= submit_tag 'Valider' %>
21
+ <%= link_to 'Annuler', '#', onclick: 'cancelEdit(); return false;' %>
22
+ </div>
23
+ </form>
24
+ </div>
@@ -18,6 +18,8 @@ editPanel.innerHTML = "";
18
18
  editPanel.innerHTML = "<%= j(render 'map_edit_panel') %>";
19
19
  <% when /^widget/ %>
20
20
  editPanel.innerHTML = "<%= j(render "shared/sibu/#{@content_type}_panel") %>";
21
+ <% when 'input' %>
22
+ editPanel.innerHTML = "<%= j(render 'input_edit_panel') %>";
21
23
  <% else %>
22
24
  editPanel.innerHTML = "<%= j(render 'error_panel') %>";
23
25
  <% end %>
@@ -43,16 +45,20 @@ setTimeout(function() {
43
45
  for (var i = 0; i < images.length; i++) {
44
46
  images[i].addEventListener("click", function(evt) {
45
47
  if(!evt.currentTarget.classList.contains('selected')) {
46
- evt.currentTarget.classList.remove('selected');
48
+ if (editPanel.querySelector('.sibu_image.selected')) {
49
+ editPanel.querySelector('.sibu_image.selected').classList.remove('selected');
50
+ }
47
51
  evt.currentTarget.classList.add('selected');
48
- var imgElt = evt.currentTarget.querySelector("img");
49
- document.querySelector("#element_src").value = imgElt.getAttribute("data-src");
52
+ var imgElt = evt.currentTarget.querySelector("img"), eltSrc = document.querySelector("#element_src");
53
+ eltSrc.value = imgElt.getAttribute("data-src");
50
54
  document.querySelector("#element_alt").value = imgElt.getAttribute("data-alt");
51
55
  editPanel.querySelector(".sibu_center").innerHTML =
52
- '<img src="' + $("#element_src").val() + '"/>' +
56
+ '<img src="' + eltSrc.value + '"/>' +
53
57
  '<div id="sibu_center_pos" style="display: none;">✕</div>' +
54
58
  '<div id="sibu_center_desc" style="display: none;"><em>Cliquez sur l\'image pour la recentrer sur un point donné (à utiliser lorsque l\'image est tronquée car la zone d\'affichage est trop petite)</em></div>';
55
- editPanel.querySelector(".sibu_selected_image > p:first-child").style.display = "none";
59
+ if (editPanel.querySelector(".sibu_selected_image > p:first-child")) {
60
+ editPanel.querySelector(".sibu_selected_image > p:first-child").style.display = "none";
61
+ }
56
62
  editPanel.querySelector(".sibu_selected_image .sibu_custom_center").style.display = "block";
57
63
  editPanel.querySelector(".sibu_selected_image .sibu_field").style.display = "";
58
64
  if(customCenter.checked) {
@@ -93,7 +99,7 @@ setTimeout(function() {
93
99
  <% if @children %>
94
100
  document.querySelector("#child_elt").style.display = "inline-block";
95
101
  <% else %>
96
- document.querySelector("#child_elt").remove();
102
+ if (document.querySelector("#child_elt")) document.querySelector("#child_elt").remove();
97
103
  <% end %>
98
104
  var formElt = document.querySelector("form.edit_element_form");
99
105
  if (formElt) {
@@ -20,9 +20,14 @@ if (sectionsPanel) {
20
20
  }
21
21
  });
22
22
  }
23
- if(typeof initSectionsForm === "function") {
24
- initSectionsForm();
23
+
24
+ var tabs = sectionsPanel.querySelectorAll(".sibu_sections a.tabs__link");
25
+ for (var j = 0; j < tabs.length; j++) {
26
+ tabs[j].addEventListener("click", function(evt) {
27
+ sibuCallback("selectSectionsTab", evt.currentTarget.getAttribute('aria-controls'));
28
+ });
25
29
  }
30
+
26
31
  document.body.style.overflow = "hidden";
27
32
  sibuCallback("newSection");
28
33
  }
@@ -1,3 +1,3 @@
1
1
  module Sibu
2
- VERSION = '1.0.6'
2
+ VERSION = '1.0.11'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sibu
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Baptiste Vilain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-04 00:00:00.000000000 Z
11
+ date: 2020-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -143,6 +143,7 @@ files:
143
143
  - app/controllers/sibu/sites_controller.rb
144
144
  - app/helpers/sibu/application_helper.rb
145
145
  - app/helpers/sibu/documents_helper.rb
146
+ - app/helpers/sibu/extendable_helper.rb
146
147
  - app/helpers/sibu/images_helper.rb
147
148
  - app/helpers/sibu/pages_helper.rb
148
149
  - app/helpers/sibu/sites_helper.rb
@@ -177,6 +178,7 @@ files:
177
178
  - app/views/sibu/pages/_error_panel.html.erb
178
179
  - app/views/sibu/pages/_form.html.erb
179
180
  - app/views/sibu/pages/_group_edit_panel.html.erb
181
+ - app/views/sibu/pages/_input_edit_panel.html.erb
180
182
  - app/views/sibu/pages/_link_edit_panel.html.erb
181
183
  - app/views/sibu/pages/_map_edit_panel.html.erb
182
184
  - app/views/sibu/pages/_media_edit_panel.html.erb