Skip to content

Commit a3bd941

Browse files
author
John Pinto
committed
Fix issues with Conditional question serialization (offered by @briri
from DMPTool). Based on DMPtool commit CDLUC3#667. Changes proposed in this PR (text from cited PR): Run SQL script to convert existing records in the conditions table so that they are JSON Arrays (see query below) Updated the form partials in app/views/org_admin/conditions/_form.erb.rb to properly send condition data to the controller. Removed all JSON.parse calls in the app/helpers/conditions.rb helper Made the following changes to simplify this patch and to make it a little more user friendly: The "Add Conditions" button will now say "Edit Conditions" if there are any. Updated the column heading over the "thing that happens when the condition is met" from "Remove" to "Target" since the content of the column can either be questions being removed or an email notification being sent. Conditions can be added or removed (not updated anymore) Hovering over the email of an existing condition displays a tooltip that shows the email message, subject, etc. Needed to update underlying data within the table so that they are JSON arrays using MySQL or Postgres scripts in db/migrate-sql-scripts folder: 20241219_UpdateConditions-MySql.sql.txt 20241219_UpdateConditions-Postgres.sql.txt (Note. The scripts have .txt endings to be able to get round .sql in .gitignore.)
1 parent 994bb60 commit a3bd941

File tree

8 files changed

+142
-33
lines changed

8 files changed

+142
-33
lines changed

app/controllers/org_admin/questions_controller.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,12 @@ def sanitize_hash(param_conditions)
227227
return {} if param_conditions.empty?
228228

229229
res = {}
230-
hash_of_hashes = param_conditions[0]
231-
hash_of_hashes.each do |cond_name, cond_hash|
230+
param_conditions.each do |cond_id, cond_hash|
232231
sanitized_hash = {}
233232
cond_hash.each do |k, v|
234-
v = ActionController::Base.helpers.sanitize(v) if k.start_with?('webhook')
235-
sanitized_hash[k] = v
233+
sanitized_hash[k] = k.start_with?('webhook') ? ActionController::Base.helpers.sanitize(v) : v
236234
end
237-
res[cond_name] = sanitized_hash
235+
res[cond_id] = sanitized_hash
238236
end
239237
res
240238
end

app/helpers/conditions_helper.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def answer_remove_list(answer, user = nil)
3232
rems = cond.remove_data.map(&:to_i)
3333
id_list += rems
3434
elsif !user.nil?
35-
UserMailer.question_answered(JSON.parse(cond.webhook_data), user, answer,
35+
UserMailer.question_answered(cond.webhook_data, user, answer,
3636
chosen.join(' and ')).deliver_now
3737
end
3838
end
@@ -57,7 +57,7 @@ def email_trigger_list(answer)
5757
chosen = answer.question_option_ids.sort
5858
next unless chosen == opts
5959

60-
email_list << JSON.parse(cond.webhook_data)['email'] if action == 'add_webhook'
60+
email_list << cond.webhook_data['email'] if action == 'add_webhook'
6161
end
6262
# uniq because could get same remove id from diff conds
6363
email_list.uniq.join(',')
@@ -190,7 +190,7 @@ def condition_to_text(conditions)
190190
return_string += "<dd>#{_('Answering')} "
191191
return_string += opts.join(' and ')
192192
if cond.action_type == 'add_webhook'
193-
subject_string = text_formatted(JSON.parse(cond.webhook_data)['subject'])
193+
subject_string = text_formatted(cond.webhook_data['subject'])
194194
return_string += format(_(' will <b>send an email</b> with subject %{subject_name}'),
195195
subject_name: subject_string)
196196
else

app/models/question.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def save_condition(value, opt_map, question_id_map)
242242
email: value['webhook-email'],
243243
subject: value['webhook-subject'],
244244
message: value['webhook-message']
245-
}.to_json
245+
}
246246
end
247247
c.save
248248
end

app/views/org_admin/conditions/_container.html.erb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44
<div class="col-md-3 mb-2 bold">
55
<%= label(:text, _('Option'), class: "control-label")%>
66
</div>
7-
<div class="col-md-3 mb-2">
7+
<div class="col-md-6 mb-2">
88
<%= label(:text, _('Action'), class: "control-label") %>
99
</div>
1010
<div class="col-md-3 mb-2 bold">
1111
<%= _('Remove')%>
1212
</div>
13-
<div class="col-md-3">
14-
</div>
1513
</div>
1614
<% conditions_params = conditions_to_param_form(conditions).sort_by { |key| key }.to_h %>
1715
<% conditions_params.each_with_index do |(title, params), i| %> <!-- iterate through conditions sorted by order of creation where i is condition number-->
Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
<% condition = condition ||= nil %>
2+
13
<div class="row condition-partial mb-3">
24
<%
3-
action_type_arr = [["removes", :remove], ["adds notification", :add_webhook]]
4-
name_start = "conditions[]condition_" + condition_no.to_s
5+
action_type_arr = [["removes", :remove], ["adds notification", :add_webhook]]
6+
# name_start = "conditions[]condition_" + condition_no.to_s
7+
name_start = "conditions[#{condition_no.to_s}]"
58
remove_question_collection = later_question_list(question)
69
condition_exists = local_assigns.has_key? :condition
710
type_default = condition_exists ? (condition[:action_type] == "remove" ? :remove : :add_webhook) : :remove
@@ -10,26 +13,65 @@
1013
grouped_options_for_select(remove_question_collection)
1114
multiple = (question.question_format.multiselectbox? || question.question_format.checkbox?)
1215
%>
13-
<div class="col-md-3 pe-2">
14-
<%= select_tag(:question_option, options_from_collection_for_select(question.question_options.sort_by(&:number), "id", "text",
15-
condition_exists ? condition[:question_option_id] : question.question_options.sort_by(&:number)[0]), {class: 'form-select regular', 'data-bs-style': 'dropdown-toggle bg-white px-4 py-3', name: name_start + "[question_option][]"}) %>
16-
</div>
17-
<div class="col-md-3 pe-2">
18-
<%= select_tag(:action_type, options_for_select(action_type_arr, type_default), {name: name_start + "[action_type]", class: 'action-type form-select narrow', 'data-bs-style': 'dropdown-toggle bg-white px-4 py-3'}) %>
19-
</div>
20-
<div class="col-md-3 pe-2">
21-
<div class="remove-dropdown">
22-
<%= select_tag(:remove_question_id, remove_question_group, {name: name_start + "[remove_question_id][]", class: 'form-select regular', multiple: true, 'data-bs-style': 'dropdown-toggle bg-white px-4 py-3'}) %>
16+
17+
<%# If this is a new condition then display the interactive controls. otherwise just display the logic %>
18+
<% if condition.nil? %>
19+
<div class="col-md-3">
20+
<%= select_tag(:question_option, options_from_collection_for_select(question.question_options.sort_by(&:number), "id", "text",
21+
condition_exists ? condition[:question_option_id] : question.question_options.sort_by(&:number)[0]), {class: 'form-selectpicker regular', 'data-bs-style': 'dropdown-toggle bg-white px-4 py-3', multiple: multiple, name: name_start + "[question_option][]"}) %>
22+
</div>
23+
<div class="col-md-3 pe-2">
24+
<%= select_tag(:action_type, options_for_select(action_type_arr, type_default), {name: name_start + "[action_type]", class: 'action-type form-selectpicker narrow', 'data-bs-style': 'dropdown-toggle bg-white px-4 py-3'}) %>
2325
</div>
24-
<div class="webhook-replacement display-off my-auto text-center">
25-
<%= link_to _('Edit email'), '#' %>
26+
<div class="col-md-3">
27+
<div class="remove-dropdown">
28+
<%= select_tag(:remove_question_id, remove_question_group, {name: name_start + "[remove_question_id][]", class: 'form-selectpicker regular', multiple: true, 'data-bs-style': 'dropdown-toggle bg-white px-4 py-3'}) %>
29+
</div>
30+
<div class="webhook-replacement display-off my-auto text-center">
31+
<%= link_to _('Edit email'), '#' %>
32+
</div>
33+
</div>
34+
<%= hidden_field_tag(name_start + "[number]", condition_no) %>
35+
36+
<div class="col-md-3">
37+
<a href="#anotherurl" class="delete-condition"><%= _('Remove') %></a>
2638
</div>
27-
</div>
28-
<%= hidden_field_tag(name_start + "[number]", condition_no) %>
2939

30-
<div class="col-md-3">
31-
<a href="#anotherurl" class="delete-condition"><%= _('Remove') %></a>
32-
</div>
40+
<%= render partial: 'org_admin/conditions/webhook_form', locals: {name_start: name_start, condition_no: condition_no} %>
3341

34-
<%= render partial: 'org_admin/conditions/webhook_form', locals: {name_start: name_start, condition_no: condition_no} %>
42+
<% else %>
43+
<%
44+
qopt = condition[:question_option_id].any? ? QuestionOption.find_by(id: condition[:question_option_id].first): nil
45+
# rques = condition[:remove_question_id].any? ? Question.find_by(id: condition[:remove_question_id].first) : nil
46+
rquesArray = condition[:remove_question_id].any? ? Question.where(id: condition[:remove_question_id]) : []
47+
%>
48+
49+
<div class="col-md-3 pe-2">
50+
<%= condition[:action_type] == 'remove' ? 'Remove' : 'Email' %>
51+
<%= hidden_field_tag(name_start + "[action_type]", condition[:action_type]) %>
52+
</div>
53+
<div class="col-md-6 pe-2">
54+
<% if condition[:remove_question_id].is_a?(Array) && condition[:remove_question_id].any? %>
55+
<% rquesArray.each do |rques| %>
56+
<%= rques.text.gsub(%r{</?p>}, '').slice(0, 50) %><br>
57+
<% end %>
58+
<%= hidden_field_tag(name_start + "[remove_question_id][]", condition[:remove_question_id]) %>
59+
<% else %>
60+
<%
61+
hook_tip = "Name: #{condition[:webhook_data]['name']}\nEmail: #{condition[:webhook_data]['email']}\n"
62+
hook_tip += "Subject: #{condition[:webhook_data]['subject']}\nMessage: #{condition[:webhook_data]['message']}"
63+
%>
64+
<span title="<%= hook_tip %>"><%= condition[:webhook_data]['email'] %></span>
65+
<%= hidden_field_tag(name_start + "[webhook-email]", condition[:webhook_data]['email']) %>
66+
<%= hidden_field_tag(name_start + "[webhook-name]", condition[:webhook_data]['name']) %>
67+
<%= hidden_field_tag(name_start + "[webhook-subject]", condition[:webhook_data]['subject']) %>
68+
<%= hidden_field_tag(name_start + "[webhook-message]", condition[:webhook_data]['message']) %>
69+
<% end %>
70+
</div>
71+
<%= hidden_field_tag(name_start + "[number]", condition_no) %>
72+
73+
<div class="col-md-3">
74+
<a href="#anotherurl" class="delete-condition"><%= _('Remove') %></a>
75+
</div>
76+
<% end %>
3577
</div>

app/views/org_admin/questions/_form.html.erb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,11 @@
4545
<%= render "/org_admin/question_options/option_fields", f: f, q: question %>
4646
<!--display for selecting comment box when multiple choice is being used-->
4747
</div>
48+
4849
<% if question.id != nil && question.question_options[0].text != nil %>
49-
<%= link_to _('Add Conditions'), org_admin_question_open_conditions_path(question_id: question.id, conditions: conditions), class: "add-logic btn btn-secondary", 'data-loaded': (conditions.size > 0).to_s, remote: true %>
50+
<% cond_lbl = (!conditions.nil? && conditions.any?) ? 'Edit Conditions' : 'Add Conditions' %>
51+
<%= cond_lbl %>
52+
<%= link_to cond_lbl, org_admin_question_open_conditions_path(question_id: question.id, conditions: conditions), class: "add-logic btn btn-default", 'data-loaded': (conditions.size > 0).to_s, remote: true %>
5053
<div id="content" class="col-md-offset-2">
5154
<p>
5255
<%= render partial: 'org_admin/conditions/container', locals: { f: f, question: question, conditions: conditions } %>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
UPDATE conditions
2+
SET
3+
option_list = CONCAT (
4+
CONCAT (
5+
'[',
6+
REPLACE (
7+
REPLACE (
8+
REPLACE (option_list, '---\n- \'', '"'),
9+
'\'\n- \'',
10+
'","'
11+
),
12+
'\'\n',
13+
'"'
14+
)
15+
),
16+
']'
17+
),
18+
remove_data = CONCAT (
19+
CONCAT (
20+
'[',
21+
REPLACE (
22+
REPLACE (
23+
REPLACE (remove_data, '---\n- \'', '"'),
24+
'\'\n- \'',
25+
'","'
26+
),
27+
'\'\n',
28+
'"'
29+
)
30+
),
31+
']'
32+
)
33+
where
34+
option_list like '---%';
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
UPDATE conditions
2+
SET
3+
option_list = concat (
4+
'[',
5+
regexp_replace (
6+
regexp_replace (
7+
regexp_replace (option_list, '---(\r|\n)-', '', 'g'),
8+
'(\r|\n)-',
9+
',',
10+
'g'
11+
),
12+
'\r|\n',
13+
'',
14+
'g'
15+
),
16+
']'
17+
),
18+
remove_data = concat (
19+
'[',
20+
regexp_replace (
21+
regexp_replace (
22+
regexp_replace (remove_data, '---(\r|\n)-', '', 'g'),
23+
'(\r|\n)-',
24+
',',
25+
'g'
26+
),
27+
'\r|\n',
28+
'',
29+
'g'
30+
),
31+
']'
32+
)
33+
where
34+
option_list like '---%';

0 commit comments

Comments
 (0)