fe 2.1.6.1 → 2.1.7

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
  SHA256:
3
- metadata.gz: e29a0202c879750c9ce98aeabf6dad15b45a944eb0bbd09223452b3d3bc0e414
4
- data.tar.gz: 922748695f42ab0e0d56f498f458d0fa1a06f06b484123e9e51dc3101bef7e6f
3
+ metadata.gz: b64b157852e00628b533ed9826d53d40c715e023813b0e30290397a78adfcb3b
4
+ data.tar.gz: 97f8071426f54e34982967b7613439eb3e27d0e77e7cb9d7589b2857d08a8790
5
5
  SHA512:
6
- metadata.gz: fec4745196d7fabd0118ad6385159f22aaa05672e2d2c3d637dc133ebf4f744236903248b96b6d48d75030433987c0457de592b3b9680375e779cebe02a00c90
7
- data.tar.gz: 032cfcb16e5ad4db94808af41b254c7116308ffbec83789283372203a44d130802166f4fa3b6f16a8723e3c3fe430f0ca37496a55eff73ea0afdac8ecac272ca
6
+ metadata.gz: 2357386af9137a2b4d40f7ce981d7d48909001b066638af236fe55affa3405d50f3866133e934231bdcb9f04f2a02053222c389511214f4e9b9a306b7fd56d54
7
+ data.tar.gz: 7b228d9046ba5fd172d5199c94ab78e012d6c3205eda62aaa3da952971d34899e60b4e1fb7f073db2164a36c419c4f47f14074e05e0355c288699655e1675162
@@ -72,7 +72,7 @@ $(document).on('ready turbo:load', function () {
72
72
 
73
73
  let currentTab = 'pages_list';
74
74
 
75
- function switchTab(toTab) {
75
+ window.switchTab = function switchTab(toTab) {
76
76
  if(currentTab != null) $('#tab-' + currentTab).removeClass('active');
77
77
  $('#tab-' + toTab).addClass('active');
78
78
  currentTab = toTab;
@@ -81,7 +81,7 @@ function switchTab(toTab) {
81
81
  }
82
82
  }
83
83
 
84
- function selectPage() {
84
+ window.selectPage = function selectPage() {
85
85
  let el = $('#link-page-name');
86
86
  clearCurrentElement();
87
87
  el.addClass('active');
@@ -90,7 +90,7 @@ function selectPage() {
90
90
  if($('#page_label').length > 0) $('#page_label').focus();
91
91
  }
92
92
 
93
- function selectElement(id) {
93
+ window.selectElement = function selectElement(id) {
94
94
  let el = $(id);
95
95
  clearPageName();
96
96
  clearCurrentElement();
@@ -102,28 +102,28 @@ function selectElement(id) {
102
102
  // if( $('#element_label')) $('#element_label').focus();
103
103
  }
104
104
 
105
- function clearCurrentElement() {
105
+ window.clearCurrentElement = function clearCurrentElement() {
106
106
  if (activeElement != '' && $(activeElement)) {
107
107
  $(activeElement).removeClass('active');
108
108
  }
109
109
  }
110
110
 
111
- function clearPageName() {
111
+ window.clearPageName = function clearPageName() {
112
112
  $('#link-page-name').removeClass('active');
113
113
  }
114
114
 
115
- function snapElementProperties(el) {
115
+ window.snapElementProperties = function snapElementProperties(el) {
116
116
  let propsTop = Position.cumulativeOffset(el)[1] - 160;
117
117
  if (propsTop < 0) propsTop = 0;
118
118
  $('#panel-properties-element').css({'margin-top': propsTop});
119
119
  }
120
120
 
121
- function addError(id) {
121
+ window.addError = function addError(id) {
122
122
  $('#' + id).addClassName('fieldWithErrors');
123
123
  }
124
124
 
125
125
  // convert label to slug
126
- function updateSlug(source, dest) {
126
+ window.updateSlug = function updateSlug(source, dest) {
127
127
  let label = $(source).val();
128
128
  let slug = $(dest).val();
129
129
  if( label == null || slug == null) return; // oh oh
@@ -133,10 +133,10 @@ function updateSlug(source, dest) {
133
133
 
134
134
  if( label != '' && slug == '' ) { // if slug is empty lets copy label to it
135
135
  slug = label.toLowerCase();
136
- slug = slug.gsub(/[^a-z0-9]/, '_'); // only alpha-numeric
137
- slug = slug.gsub(/_{2,}/, '_'); // compact double hyphens down to one
138
- slug = slug.gsub(/_$/, ''); // remove trailing underscores
139
- slug = slug.gsub(/^([0-9])/, '_\1') // can't begin with a digit, so preprend an underscore
136
+ slug = slug.replace(/[^a-z0-9]/, '_'); // only alpha-numeric
137
+ slug = slug.replace(/_{2,}/, '_'); // compact double hyphens down to one
138
+ slug = slug.replace(/_$/, ''); // remove trailing underscores
139
+ slug = slug.replace(/^([0-9])/, '_$&') // can't begin with a digit, so preprend an underscore
140
140
  if( slug.length > 36 ) slug = slug.slice(0, 36) // max length
141
141
 
142
142
  $(dest).value = slug
@@ -1,33 +1,35 @@
1
- function setUpSortables() {
2
- $('[data-sortable]').sortable({axis:'y',
3
- items: '> li.sortable',
4
- dropOnEmpty:false,
5
- update: function(event, ui) {
6
- let sortable = this;
7
- $.ajax({data:$(this).sortable('serialize',{key:sortable.id + '[]'}),
8
- complete: function(request) {$(sortable).effect('highlight')},
9
- success:function(request){$('#errors').html(request)},
10
- type:'POST',
11
- url: $(sortable).attr('data-sortable-url')
12
- })
13
- },
14
- stop: function(event, ui) {
15
- let before_dropper = $('li.before-container[data-element_id="'+ui.item.data('element_id'));
16
- if (before_dropper.length > 0) {
17
- before_dropper.detach();
18
- before_dropper.insertBefore(ui.item);
19
- }
20
- let after_dropper = $('li.after-container[data-element_id="'+ui.item.data('element_id'));
21
- if (after_dropper.length > 0) {
22
- after_dropper.detach();
23
- after_dropper.insertAfter(ui.item);
24
- }
25
- }
26
- });
27
- $('[data-sortable][data-sortable-handle]').each(function() {
28
- handle = $(this).attr('data-sortable-handle');
1
+ window.setUpSortables = function setUpSortables() {
2
+ $('[data-sortable]').sortable({
3
+ axis:'y',
4
+ items: '> li.sortable',
5
+ dropOnEmpty:false,
6
+ update: function(event, ui) {
7
+ let sortable = this;
8
+ $.ajax({
9
+ data:$(this).sortable('serialize',{key:sortable.id + '[]'}),
10
+ complete: function(request) {$(sortable).effect('highlight')},
11
+ success: function(request){$('#errors').html(request)},
12
+ type:'POST',
13
+ url: $(sortable).attr('data-sortable-url')
14
+ })
15
+ },
16
+ stop: function(event, ui) {
17
+ let before_dropper = $('li.before-container[data-element_id="'+ui.item.data('element_id'));
18
+ if (before_dropper.length > 0) {
19
+ before_dropper.detach();
20
+ before_dropper.insertBefore(ui.item);
21
+ }
22
+ let after_dropper = $('li.after-container[data-element_id="'+ui.item.data('element_id'));
23
+ if (after_dropper.length > 0) {
24
+ after_dropper.detach();
25
+ after_dropper.insertAfter(ui.item);
26
+ }
27
+ }
28
+ });
29
+ $('[data-sortable][data-sortable-handle]').each(function() {
30
+ const handle = $(this).attr('data-sortable-handle');
29
31
  $(this).sortable("option", "handle", handle);
30
- });
32
+ });
31
33
 
32
34
  $('.droppable').droppable({
33
35
  activeClass: 'droppable-active',
@@ -36,8 +38,8 @@ function setUpSortables() {
36
38
  $.post($(this).attr('data-url'), {draggable_element: ui.draggable.attr('id')}, function() {}, 'script')
37
39
  },
38
40
  activate: function( event, ui ) {
39
- $draggable = ui.draggable;
40
- $container = $draggable.parents("li.element.container")
41
+ const $draggable = ui.draggable;
42
+ const $container = $draggable.parents("li.element.container");
41
43
  if ($container.length == 1) {
42
44
  $container.parent().find('li.around-container[data-element_id="'+$container.data('element_id')+'"]').addClass('droppable-active')
43
45
  } else {
@@ -45,8 +47,8 @@ function setUpSortables() {
45
47
  }
46
48
  },
47
49
  deactivate: function( event, ui ) {
48
- $draggable = ui.draggable;
49
- $container = $draggable.parents("li.element.container")
50
+ const $draggable = ui.draggable;
51
+ const $container = $draggable.parents("li.element.container");
50
52
  if ($container.length == 1) {
51
53
  $container.parent().find('li.around-container[data-element_id="'+$container.data('element_id')+'"]').removeClass('droppable-active')
52
54
  } else {
@@ -56,7 +58,7 @@ function setUpSortables() {
56
58
  });
57
59
  }
58
60
 
59
- function setUpCalendars() {
61
+ window.setUpCalendars = function setUpCalendars() {
60
62
  let now = new Date();
61
63
  let year = now.getFullYear() + 10;
62
64
  $('[data-calendar]').datepicker({
@@ -66,11 +68,11 @@ function setUpCalendars() {
66
68
  })
67
69
  }
68
70
 
69
- function setUpJsHelpers() {
70
- // ==================
71
- // Sortable
72
- setUpSortables();
73
- // ==================
71
+ window.setUpJsHelpers = function setUpJsHelpers() {
72
+ // ==================
73
+ // Sortable
74
+ setUpSortables();
75
+ // ==================
74
76
 
75
77
  // ==================
76
78
  // Calendar
@@ -79,8 +81,8 @@ function setUpJsHelpers() {
79
81
  <% unless Fe.bootstrap %>$(".tip[title], a[title]").tooltip()<% end %>
80
82
  }
81
83
 
82
- function fixGridColumnWidths() {
83
- $("table.grid").each(function(i, grid) {
84
+ window.fixGridColumnWidths = function fixGridColumnWidths() {
85
+ $("table.grid").each(function(i, grid) {
84
86
  let num_columns = $(grid).find("th").length;
85
87
  if (num_columns > 0) {
86
88
  let width = (100 / num_columns) + "%";
@@ -97,6 +99,13 @@ function scrollTo(el) {
97
99
  }, 1000);
98
100
  }
99
101
 
102
+ window.scrollToElement = function scrollToElement(el) {
103
+ if ($(el).length == 0) { return; }
104
+ $('html, body').animate({
105
+ scrollTop: $(el).offset().top
106
+ }, 1000);
107
+ }
108
+
100
109
  // jQuery 3 has removed $(document).on('ready', ...) in favor of $(document).ready(...). Manually call it from
101
110
  // the new method here, so we can avoid changing over all the document ready's.
102
111
  $(document).ready(function() {
@@ -99,7 +99,7 @@ fe.pageHandler = {
99
99
  //
100
100
  if (!isValid && $('#' + this.current_page + "-form").hasClass('enforce-valid-before-next')) {
101
101
  // scroll up to where the error is
102
- scrollTo($(".help-block:visible")[0].closest("li"));
102
+ scrollToElement($(".help-block:visible")[0].closest("li"));
103
103
  return;
104
104
  }
105
105
 
@@ -110,9 +110,9 @@ fe.pageHandler = {
110
110
 
111
111
  if (!background_load) {
112
112
  if ($('a[name="main"]').length == 1) {
113
- scrollTo('a[name="main"]');
113
+ scrollToElement('a[name="main"]');
114
114
  } else {
115
- scrollTo('#main');
115
+ scrollToElement('#main');
116
116
  }
117
117
  }
118
118
 
@@ -157,7 +157,9 @@ fe.pageHandler = {
157
157
  if( form_data ) {
158
158
  if( page.data('form_data') == null || page.data('form_data').data !== form_data.data || force === true) { // if any changes
159
159
  page.data('form_data', form_data);
160
- $.ajax({url: form_data.url, type: 'put', data: form_data.data,
160
+ const auth_token = $('meta[name=csrf-token]').attr('content');
161
+ form_data.data += '&authenticity_token=' + encodeURIComponent(auth_token);
162
+ $.ajax({url: form_data.url, type: 'put', data: form_data.data,
161
163
  beforeSend: function (xhr) {
162
164
  $('#spinner_' + page.attr('id')).show();
163
165
  },
@@ -302,8 +304,9 @@ fe.pageHandler = {
302
304
  // clear out pages array to force reload. This enables "frozen" apps
303
305
  // immediately after submission - :onSuccess (for USCM which stays in the application vs. redirecting to the dashboard)
304
306
  let curr = fe.pageHandler.current_page;
307
+ const auth_token = $('meta[name=csrf-token]').attr('content');
305
308
  $.ajax({url: url, dataType:'script',
306
- data: {answer_sheet_type: answer_sheet_type, a: $('input[type=hidden][name=a]').val()},
309
+ data: {answer_sheet_type: answer_sheet_type, a: $('input[type=hidden][name=a]').val(), authenticity_token: auth_token},
307
310
  type:'post',
308
311
  beforeSend: function(xhr) {
309
312
  $('body').trigger('ajax:loading', xhr);
@@ -444,6 +447,8 @@ $(document).on('ready turbo:load', function () {
444
447
  let data = form_elements.serializeArray();
445
448
 
446
449
  data.push({name: 'answer_sheet_type', value: answer_sheet_type});
450
+ const auth_token = $('meta[name=csrf-token]').attr('content');
451
+ data.push({name: 'authenticity_token', value: auth_token});
447
452
  $.ajax({url: $(el).attr('href'), data: data, dataType: 'script', type: 'POST',
448
453
  beforeSend: function (xhr) {
449
454
  $('body').trigger('ajax:loading', xhr);
@@ -495,7 +500,7 @@ $(function() {
495
500
  });
496
501
 
497
502
 
498
- function updateTotal(id) {
503
+ window.updateTotal = function updateTotal(id) {
499
504
  try {
500
505
  let total = 0;
501
506
  $(".col_" + id).each(function(index, el) {
@@ -506,7 +511,7 @@ function updateTotal(id) {
506
511
  }
507
512
  }
508
513
 
509
- function submitToFrame(id, url) {
514
+ window.submitToFrame = function submitToFrame(id, url) {
510
515
  let form = $('<form method="post" action="'+url+'.js" endtype="multipart/form-data"></form>')
511
516
  let csrf_token = $('meta[name=csrf-token]').attr('content'),
512
517
  csrf_param = $('meta[name=csrf-param]').attr('content'),
@@ -531,3 +536,10 @@ if (typeof scrollTo === 'undefined') {
531
536
  }, 1000);
532
537
  }
533
538
  }
539
+
540
+ window.scrollToElement = function scrollToElement(el) {
541
+ if ($(el).length == 0) { return; }
542
+ $('html, body').animate({
543
+ scrollTop: $(el).offset().top
544
+ }, 1000);
545
+ }
@@ -1,7 +1,7 @@
1
1
  /* Taken from https://github.com/mihaild/jquery-html5-upload */
2
2
 
3
3
  (function($) {
4
- $.fn.html5_upload = function(options) {
4
+ $.fn.html5_upload = function(_options) {
5
5
 
6
6
  function get_file_name(file) {
7
7
  return file.name || file.fileName;
@@ -59,6 +59,7 @@ module Fe::AnswerPagesControllerConcern
59
59
  end
60
60
  @presenter.active_page = nil
61
61
  @answer_sheet.update(locale: session[:locale])
62
+ @answer_sheet.touch
62
63
  set_saved_at_timestamp
63
64
  respond_to do |format|
64
65
  format.js
@@ -34,7 +34,7 @@ module Fe
34
34
 
35
35
  unless @languages
36
36
  @languages = question_sheets.first.languages
37
- question_sheets[1..-1].each { |qs| @languages &= qs.languages.select(&:present?) }
37
+ question_sheets[1..-1].each { |qs| @languages &= qs.languages&.select(&:present?) }
38
38
  end
39
39
  @languages
40
40
  end
@@ -15,7 +15,7 @@ module Fe
15
15
  included do
16
16
  has_many :elements, class_name: "Element", foreign_key: "choice_field_id", dependent: :nullify#, order: :position
17
17
  [:rating_before_label_translations, :rating_after_label_translations, :rating_na_label_translations].each do |column|
18
- if Rails::VERSION::MAJOR < 7
18
+ if Rails.gem_version < "7.1.0"
19
19
  serialize column, Hash
20
20
  else
21
21
  serialize column, type: Hash
@@ -50,7 +50,7 @@ module Fe
50
50
  after_save :update_any_previous_conditional_elements
51
51
 
52
52
  [:label_translations, :tip_translations, :content_translations].each do |column|
53
- if Rails::VERSION::MAJOR < 7
53
+ if Rails.gem_version < "7.1.0"
54
54
  serialize column, Hash
55
55
  else
56
56
  serialize column, type: Hash
@@ -65,15 +65,15 @@ module Fe
65
65
  # HUMANIZED_ATTRIBUTES[attr.to_sym] || super
66
66
  # end
67
67
  def label(locale = nil)
68
- label_translations[locale].present? ? label_translations[locale] : self[:label]
68
+ label_translations&.dig(locale).present? ? label_translations[locale] : self[:label]
69
69
  end
70
70
 
71
71
  def content(locale = nil)
72
- content_translations[locale].present? ? content_translations[locale] : self[:content]
72
+ content_translations&.dig(locale).present? ? content_translations[locale] : self[:content]
73
73
  end
74
74
 
75
75
  def tooltip(locale = nil)
76
- tip_translations[locale].present? ? tip_translations[locale] : self[:tooltip]
76
+ tip_translations&.dig(locale).present? ? tip_translations[locale] : self[:tooltip]
77
77
  end
78
78
 
79
79
  # returns all pages this element is on, whether that be directly, through a grid, or as a choice field conditional option
@@ -45,7 +45,7 @@ module Fe
45
45
 
46
46
  # NOTE: You may need config.active_record.yaml_column_permitted_classes = [Hash, ActiveSupport::HashWithIndifferentAccess]
47
47
  # in config/application.rb or you may get Psych::DisallowedClass trying to use label_translations
48
- if Rails::VERSION::MAJOR < 7
48
+ if Rails.gem_version < "7.1.0"
49
49
  serialize :label_translations, Hash
50
50
  else
51
51
  serialize :label_translations, type: Hash
@@ -73,7 +73,7 @@ module Fe
73
73
  end
74
74
 
75
75
  def label(locale = nil)
76
- label_translations[locale] || self[:label]
76
+ label_translations&.dig(locale) || self[:label]
77
77
  end
78
78
 
79
79
  # returns true if there is a question element on the page, including one inside a grid
@@ -21,7 +21,7 @@ module Fe
21
21
 
22
22
  validates_presence_of :label
23
23
 
24
- if Rails::VERSION::MAJOR < 7
24
+ if Rails.gem_version < "7.1.0"
25
25
  serialize :languages, Array
26
26
  else
27
27
  serialize :languages, type: Array
@@ -5,7 +5,7 @@
5
5
  $('#element_form_<%= dom_id(@element) %>').html('<%= escape_javascript(render("fe/admin/panels/prop_element", element: @element)) %>');
6
6
  $('#element_form_<%= dom_id(@element) %>').show();
7
7
  selectElement("#element_<%= @element.id %>");
8
- scrollTo("#element_<%= @element.id %>");
8
+ scrollToElement("#element_<%= @element.id %>");
9
9
  setUpSortables();
10
10
  <% else %>
11
11
  alert('That question already exists on this question sheet')
@@ -43,7 +43,7 @@
43
43
  "have edited the information in order for your reference to receive another email.") %>
44
44
  </strong></em></p></li>
45
45
 
46
- <li><%= link_to(_("Send Email Invitation"), @answer_sheet ? send_reference_invite_fe_answer_sheet_path(@answer_sheet, reference_id: reference.id) : "#", class: "#{"form-control" if Fe.bootstrap} reference_send_invite button no-left-margin", disabled: !reference.all_affecting_questions_answered) %>
46
+ <li><%= link_to(_("Send Email Invitation"), @answer_sheet ? send_reference_invite_fe_answer_sheet_path(@answer_sheet, reference_id: reference.id) : "#", class: "#{"form-control" if Fe.bootstrap} reference_send_invite button no-left-margin", disabled: !reference.all_affecting_questions_answered, data: { turbo: false }) %>
47
47
  <% if reference.question && !reference.all_affecting_questions_answered %>
48
48
  <div>
49
49
  <strong><i>This button is disabled because there are questions that affect whether this reference is required that need to answered first:</i></strong>
data/lib/fe/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fe
2
- VERSION = "2.1.6.1"
2
+ VERSION = "2.1.7"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fe
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.6.1
4
+ version: 2.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - CruGlobal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-24 00:00:00.000000000 Z
11
+ date: 2025-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -551,7 +551,6 @@ files:
551
551
  - spec/dummy/app/models/person.rb
552
552
  - spec/dummy/app/models/user.rb
553
553
  - spec/dummy/app/views/layouts/application.html.erb
554
- - spec/dummy/app/views/layouts/fe/fe.admin.html.erb
555
554
  - spec/dummy/bin/bundle
556
555
  - spec/dummy/bin/rails
557
556
  - spec/dummy/bin/rake
@@ -678,7 +677,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
678
677
  - !ruby/object:Gem::Version
679
678
  version: '0'
680
679
  requirements: []
681
- rubygems_version: 3.1.6
680
+ rubygems_version: 3.5.17
682
681
  signing_key:
683
682
  specification_version: 4
684
683
  summary: Form Engine
@@ -704,7 +703,6 @@ test_files:
704
703
  - spec/dummy/app/models/person.rb
705
704
  - spec/dummy/app/models/user.rb
706
705
  - spec/dummy/app/views/layouts/application.html.erb
707
- - spec/dummy/app/views/layouts/fe/fe.admin.html.erb
708
706
  - spec/dummy/bin/bundle
709
707
  - spec/dummy/bin/rails
710
708
  - spec/dummy/bin/rake
@@ -1 +0,0 @@
1
- <%= yield %>