decidim-forms 0.20.0 → 0.23.1.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/admin/decidim_forms_manifest.css +3 -0
  3. data/app/assets/config/admin/decidim_forms_manifest.js +1 -0
  4. data/app/assets/config/decidim_forms_manifest.css +1 -0
  5. data/app/assets/images/decidim/surveys/icon.svg +1 -19
  6. data/app/assets/javascripts/decidim/forms/admin/auto_select_options_from_url.component.js.es6 +40 -0
  7. data/app/assets/javascripts/decidim/forms/admin/collapsible_questions.js.es6 +13 -0
  8. data/app/assets/javascripts/decidim/forms/admin/forms.js.es6 +260 -16
  9. data/app/assets/javascripts/decidim/forms/admin/live_text_update.component.js.es6 +52 -0
  10. data/app/assets/javascripts/decidim/forms/autosortable_checkboxes.component.js.es6 +54 -34
  11. data/app/assets/javascripts/decidim/forms/display_conditions.component.js.es6 +204 -0
  12. data/app/assets/javascripts/decidim/forms/forms.js.es6 +49 -1
  13. data/app/assets/javascripts/decidim/forms/max_choices_alert.component.js.es6 +44 -0
  14. data/app/assets/stylesheets/decidim/forms/forms.scss +39 -0
  15. data/app/assets/stylesheets/decidim/forms/questionnaire-answers-pdf.scss +69 -0
  16. data/app/cells/decidim/forms/matrix_readonly/show.erb +5 -0
  17. data/app/cells/decidim/forms/matrix_readonly_cell.rb +12 -0
  18. data/app/cells/decidim/forms/question_readonly/show.erb +5 -1
  19. data/app/cells/decidim/forms/question_readonly_cell.rb +5 -0
  20. data/app/cells/decidim/forms/step_navigation/show.erb +35 -0
  21. data/app/cells/decidim/forms/step_navigation_cell.rb +46 -0
  22. data/app/commands/decidim/forms/admin/update_questionnaire.rb +33 -1
  23. data/app/commands/decidim/forms/answer_questionnaire.rb +2 -1
  24. data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +52 -2
  25. data/app/controllers/decidim/forms/admin/concerns/has_questionnaire_answers.rb +97 -0
  26. data/app/controllers/decidim/forms/concerns/has_questionnaire.rb +11 -2
  27. data/app/forms/decidim/forms/admin/display_condition_form.rb +100 -0
  28. data/app/forms/decidim/forms/admin/question_form.rb +21 -1
  29. data/app/forms/decidim/forms/admin/question_matrix_row_form.rb +26 -0
  30. data/app/forms/decidim/forms/answer_choice_form.rb +1 -0
  31. data/app/forms/decidim/forms/answer_form.rb +31 -2
  32. data/app/forms/decidim/forms/questionnaire_form.rb +25 -3
  33. data/app/helpers/decidim/forms/admin/application_helper.rb +37 -0
  34. data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_pagination_helper.rb +49 -0
  35. data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_url_helper.rb +40 -0
  36. data/app/helpers/decidim/forms/admin/questionnaire_answers_helper.rb +27 -0
  37. data/app/jobs/decidim/forms/export_questionnaire_answers_job.rb +19 -0
  38. data/app/models/decidim/forms/answer.rb +0 -3
  39. data/app/models/decidim/forms/answer_choice.rb +7 -0
  40. data/app/models/decidim/forms/answer_option.rb +14 -0
  41. data/app/models/decidim/forms/display_condition.rb +51 -0
  42. data/app/models/decidim/forms/question.rb +52 -2
  43. data/app/models/decidim/forms/question_matrix_row.rb +15 -0
  44. data/app/models/decidim/forms/questionnaire.rb +11 -1
  45. data/app/presenters/decidim/forms/admin/questionnaire_answer_presenter.rb +43 -0
  46. data/app/presenters/decidim/forms/admin/questionnaire_participant_presenter.rb +60 -0
  47. data/app/presenters/decidim/forms/answer_option_presenter.rb +20 -0
  48. data/app/presenters/decidim/forms/question_presenter.rb +16 -0
  49. data/app/queries/decidim/forms/questionnaire_participant.rb +35 -0
  50. data/app/queries/decidim/forms/questionnaire_participants.rb +43 -0
  51. data/app/types/decidim/forms/answer_option_type.rb +14 -0
  52. data/app/types/decidim/forms/question_type.rb +23 -0
  53. data/app/types/decidim/forms/questionnaire_type.rb +22 -0
  54. data/app/views/decidim/forms/admin/questionnaires/_answer_option_template.html.erb +1 -1
  55. data/app/views/decidim/forms/admin/questionnaires/_display_condition.html.erb +88 -0
  56. data/app/views/decidim/forms/admin/questionnaires/_display_condition_template.html.erb +7 -0
  57. data/app/views/decidim/forms/admin/questionnaires/_form.html.erb +67 -8
  58. data/app/views/decidim/forms/admin/questionnaires/_matrix_row.html.erb +34 -0
  59. data/app/views/decidim/forms/admin/questionnaires/_matrix_row_template.html.erb +7 -0
  60. data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +45 -6
  61. data/app/views/decidim/forms/admin/questionnaires/_separator.html.erb +41 -0
  62. data/app/views/decidim/forms/admin/questionnaires/answers/export/_answer.html.erb +31 -0
  63. data/app/views/decidim/forms/admin/questionnaires/answers/export/pdf.html.erb +13 -0
  64. data/app/views/decidim/forms/admin/questionnaires/answers/index.html.erb +53 -0
  65. data/app/views/decidim/forms/admin/questionnaires/answers/show.html.erb +48 -0
  66. data/app/views/decidim/forms/admin/questionnaires/edit.html.erb +9 -5
  67. data/app/views/decidim/forms/questionnaires/_answer.html.erb +28 -99
  68. data/app/views/decidim/forms/questionnaires/answers/_long_answer.html.erb +1 -0
  69. data/app/views/decidim/forms/questionnaires/answers/_matrix_multiple.html.erb +43 -0
  70. data/app/views/decidim/forms/questionnaires/answers/_matrix_single.html.erb +43 -0
  71. data/app/views/decidim/forms/questionnaires/answers/_multiple_option.html.erb +23 -0
  72. data/app/views/decidim/forms/questionnaires/answers/_separator.html.erb +1 -0
  73. data/app/views/decidim/forms/questionnaires/answers/_short_answer.html.erb +1 -0
  74. data/app/views/decidim/forms/questionnaires/answers/_single_option.html.erb +30 -0
  75. data/app/views/decidim/forms/questionnaires/answers/_sorting.html.erb +23 -0
  76. data/app/views/decidim/forms/questionnaires/show.html.erb +78 -26
  77. data/app/views/layouts/decidim/forms/admin/questionnaires/questionnaire_answers.html.erb +12 -0
  78. data/config/initializers/wicked_pdf.rb +25 -0
  79. data/config/locales/am-ET.yml +1 -0
  80. data/config/locales/ar.yml +9 -4
  81. data/config/locales/bg-BG.yml +14 -0
  82. data/config/locales/bg.yml +14 -0
  83. data/config/locales/ca.yml +98 -8
  84. data/config/locales/cs.yml +89 -5
  85. data/config/locales/da-DK.yml +1 -0
  86. data/config/locales/da.yml +1 -0
  87. data/config/locales/de.yml +92 -4
  88. data/config/locales/el-GR.yml +1 -0
  89. data/config/locales/el.yml +118 -0
  90. data/config/locales/en.yml +89 -5
  91. data/config/locales/eo.yml +1 -0
  92. data/config/locales/es-MX.yml +94 -4
  93. data/config/locales/es-PY.yml +94 -4
  94. data/config/locales/es.yml +94 -4
  95. data/config/locales/et-EE.yml +1 -0
  96. data/config/locales/et.yml +1 -0
  97. data/config/locales/eu.yml +7 -4
  98. data/config/locales/fi-plain.yml +88 -4
  99. data/config/locales/fi.yml +88 -4
  100. data/config/locales/fr-CA.yml +172 -0
  101. data/config/locales/fr.yml +89 -5
  102. data/config/locales/ga-IE.yml +1 -0
  103. data/config/locales/gl.yml +7 -4
  104. data/config/locales/hr-HR.yml +1 -0
  105. data/config/locales/hr.yml +1 -0
  106. data/config/locales/hu.yml +11 -5
  107. data/config/locales/id-ID.yml +7 -4
  108. data/config/locales/is-IS.yml +1 -0
  109. data/config/locales/is.yml +1 -0
  110. data/config/locales/it.yml +89 -5
  111. data/config/locales/ja-JP.yml +170 -0
  112. data/config/locales/ja.yml +170 -0
  113. data/config/locales/ko-KR.yml +1 -0
  114. data/config/locales/ko.yml +1 -0
  115. data/config/locales/lt-LT.yml +1 -0
  116. data/config/locales/lt.yml +1 -0
  117. data/config/locales/lv.yml +118 -0
  118. data/config/locales/mt-MT.yml +1 -0
  119. data/config/locales/mt.yml +1 -0
  120. data/config/locales/nl.yml +92 -8
  121. data/config/locales/no.yml +98 -1
  122. data/config/locales/om-ET.yml +1 -0
  123. data/config/locales/pl.yml +113 -26
  124. data/config/locales/pt-BR.yml +8 -5
  125. data/config/locales/pt.yml +111 -24
  126. data/config/locales/ro-RO.yml +167 -0
  127. data/config/locales/ru.yml +4 -2
  128. data/config/locales/sk-SK.yml +88 -0
  129. data/config/locales/sk.yml +90 -0
  130. data/config/locales/sl.yml +12 -0
  131. data/config/locales/so-SO.yml +1 -0
  132. data/config/locales/sr-CS.yml +1 -0
  133. data/config/locales/sv.yml +88 -7
  134. data/config/locales/ti-ER.yml +1 -0
  135. data/config/locales/tr-TR.yml +7 -4
  136. data/config/locales/vi-VN.yml +1 -0
  137. data/config/locales/vi.yml +1 -0
  138. data/config/locales/zh-CN.yml +172 -0
  139. data/config/locales/zh-TW.yml +1 -0
  140. data/db/migrate/20200130194123_create_decidim_forms_display_conditions.rb +20 -0
  141. data/db/migrate/20200225123810_create_decidim_forms_question_matrix_rows.rb +11 -0
  142. data/db/migrate/20200304152939_add_matrix_row_id_to_decidim_forms_answer_choices.rb +11 -0
  143. data/lib/decidim/api/questionnaire_entity_interface.rb +18 -0
  144. data/lib/decidim/exporters/form_pdf.rb +33 -0
  145. data/lib/decidim/exporters/form_pdf_controller_helper.rb +11 -0
  146. data/lib/decidim/forms.rb +6 -0
  147. data/lib/decidim/forms/admin_engine.rb +1 -1
  148. data/lib/decidim/forms/api.rb +7 -0
  149. data/lib/decidim/forms/test.rb +6 -0
  150. data/lib/decidim/forms/test/factories.rb +60 -5
  151. data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +918 -60
  152. data/lib/decidim/forms/test/shared_examples/manage_questionnaire_answers.rb +108 -0
  153. data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +33 -575
  154. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_display_conditions.rb +179 -0
  155. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_questions.rb +463 -0
  156. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_display_conditions.rb +93 -0
  157. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_questions.rb +461 -0
  158. data/lib/decidim/forms/user_answers_serializer.rb +21 -4
  159. data/lib/decidim/forms/version.rb +1 -1
  160. metadata +136 -11
@@ -35,3 +35,42 @@
35
35
  .questionnaire-question_readonly-answer{
36
36
  font-weight: normal;
37
37
  }
38
+
39
+ .questionnaire-question-matrix{
40
+ .collection-input{
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ flex-grow: 1;
45
+ flex-basis: 0;
46
+
47
+ input[type="text"]{
48
+ margin-top: auto;
49
+ margin-bottom: auto;
50
+ }
51
+
52
+ input[type="checkbox"],
53
+ input[type="radio"]{
54
+ margin-bottom: 0;
55
+
56
+ & ~ input[type="text"]{
57
+ margin-left: .5rem;
58
+ }
59
+ }
60
+ }
61
+
62
+ tr,
63
+ tr:nth-child(2n){
64
+ background: initial;
65
+ border-bottom: 1px solid #f0f0f0;
66
+ }
67
+
68
+ thead td{
69
+ text-align: center;
70
+ }
71
+
72
+ td{
73
+ min-width: 100px;
74
+ border-right: 1px solid #f0f0f0;
75
+ }
76
+ }
@@ -0,0 +1,69 @@
1
+ .questionnaire-answers{
2
+ .header{
3
+ h1{
4
+ margin: 0;
5
+ padding: 25px;
6
+ background: rgb(59, 69, 87);
7
+ color: white;
8
+ border-radius: 4px 4px 0 0;
9
+ }
10
+
11
+ .description{
12
+ margin: 0;
13
+ padding: 25px;
14
+ background: #f6f6f6;
15
+ color: #202751;
16
+ border-radius: 0 0 4px 4px;
17
+ }
18
+ }
19
+
20
+ .answer{
21
+ margin-top: 25px;
22
+ background: #f6f6f6;
23
+ border-radius: 0 0 4px 4px;
24
+
25
+ .title{
26
+ page-break-inside: avoid;
27
+ border-radius: 4px 4px 0 0;
28
+ padding: 10px 25px;
29
+ background: rgb(59, 69, 87);
30
+ color: white;
31
+ }
32
+
33
+ .participant-info{
34
+ margin-top: 0;
35
+ padding: 10px 25px;
36
+ width: 100%;
37
+ text-align: center;
38
+ background: #eee;
39
+ color: #202751;
40
+ page-break-inside: avoid;
41
+
42
+ th:first-child{
43
+ text-align: left;
44
+ }
45
+
46
+ td:first-child{
47
+ text-align: left;
48
+ }
49
+
50
+ th:last-child{
51
+ text-align: right;
52
+ }
53
+
54
+ td:last-child{
55
+ text-align: right;
56
+ }
57
+ }
58
+
59
+ .answers{
60
+ padding: 25px;
61
+
62
+ .question{
63
+ page-break-inside: avoid;
64
+ font-size: inherit;
65
+ color: #202751;
66
+ }
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,5 @@
1
+ <li class="questionnaire-question_readonly-answer">
2
+ <%= translated_attribute(model.body) %>
3
+
4
+ (<%= answer_options %>)
5
+ </li>
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Forms
5
+ # This cell renders a possible matrix answer of a question (readonly)
6
+ class MatrixReadonlyCell < Decidim::ViewModel
7
+ def answer_options
8
+ model.question.answer_options.map { |option| translated_attribute(option.body) }.join(" / ")
9
+ end
10
+ end
11
+ end
12
+ end
@@ -9,7 +9,11 @@
9
9
 
10
10
  <% if model.multiple_choice? %>
11
11
  <ul class="questionnaire-question_readonly-answers <%= model.question_type %>">
12
- <%= cell("decidim/forms/answer_readonly", collection: model.answer_options) %>
12
+ <% if model.matrix? %>
13
+ <%= cell("decidim/forms/matrix_readonly", collection: model.matrix_rows) %>
14
+ <% else %>
15
+ <%= cell("decidim/forms/answer_readonly", collection: model.answer_options) %>
16
+ <% end %>
13
17
  </ul>
14
18
  <% end %>
15
19
  </li>
@@ -4,6 +4,11 @@ module Decidim
4
4
  module Forms
5
5
  # This cell renders a question (readonly) of a questionnaire
6
6
  class QuestionReadonlyCell < Decidim::ViewModel
7
+ def show
8
+ return if model.separator?
9
+
10
+ render :show
11
+ end
7
12
  end
8
13
  end
9
14
  end
@@ -0,0 +1,35 @@
1
+ <div class="button--double form-general-submit answer-questionnaire__submit">
2
+ <% if first_step? %>
3
+ <a></a>
4
+ <% else %>
5
+ <%= link_to(
6
+ icon("caret-left", class: "icon--small", role: "img") + " " + t("decidim.forms.step_navigation.show.back"),
7
+ "#",
8
+ class: "hollow secondary",
9
+ data: {
10
+ toggle: [previous_step_dom_id, current_step_dom_id].join(" ")
11
+ }
12
+ ) %>
13
+ <% end %>
14
+
15
+ <% if last_step? %>
16
+ <%= form.submit(
17
+ t("decidim.forms.step_navigation.show.submit"),
18
+ class: "button button--sc",
19
+ disabled: button_disabled?,
20
+ data: {
21
+ confirm: t("decidim.forms.step_navigation.show.are_you_sure"),
22
+ disable: true
23
+ }
24
+ ) %>
25
+ <% else %>
26
+ <%= link_to(
27
+ t("decidim.forms.step_navigation.show.continue"),
28
+ "#",
29
+ class: "button button--sc",
30
+ data: {
31
+ toggle: [next_step_dom_id, current_step_dom_id].join(" ")
32
+ }
33
+ ) %>
34
+ <% end %>
35
+ </div>
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Forms
5
+ # This cell renders the navigation of a questionnaire step.
6
+ class StepNavigationCell < Decidim::ViewModel
7
+ include Decidim::LayoutHelper
8
+
9
+ def current_step_index
10
+ model
11
+ end
12
+
13
+ def first_step?
14
+ current_step_index.zero?
15
+ end
16
+
17
+ def last_step?
18
+ current_step_index + 1 == total_steps
19
+ end
20
+
21
+ def total_steps
22
+ options[:total_steps]
23
+ end
24
+
25
+ def form
26
+ options[:form]
27
+ end
28
+
29
+ def button_disabled?
30
+ options[:button_disabled]
31
+ end
32
+
33
+ def previous_step_dom_id
34
+ "step-#{current_step_index - 1}"
35
+ end
36
+
37
+ def next_step_dom_id
38
+ "step-#{current_step_index + 1}"
39
+ end
40
+
41
+ def current_step_dom_id
42
+ "step-#{current_step_index}"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -22,7 +22,11 @@ module Decidim
22
22
  return broadcast(:invalid) if @form.invalid?
23
23
 
24
24
  Decidim::Forms::Questionnaire.transaction do
25
- update_questionnaire_questions if @questionnaire.questions_editable?
25
+ if @questionnaire.questions_editable?
26
+ update_questionnaire_questions
27
+ delete_answers unless @questionnaire.published?
28
+ end
29
+
26
30
  update_questionnaire
27
31
  end
28
32
 
@@ -56,6 +60,30 @@ module Decidim
56
60
 
57
61
  update_nested_model(form_answer_option, answer_option_attributes, question.answer_options)
58
62
  end
63
+
64
+ form_question.display_conditions.each do |form_display_condition|
65
+ type = form_display_condition.condition_type
66
+
67
+ display_condition_attributes = {
68
+ condition_question: form_display_condition.condition_question,
69
+ condition_type: form_display_condition.condition_type,
70
+ condition_value: type == "match" ? form_display_condition.condition_value : nil,
71
+ answer_option: %w(equal not_equal).include?(type) ? form_display_condition.answer_option : nil,
72
+ mandatory: form_display_condition.mandatory
73
+ }
74
+
75
+ next if form_display_condition.deleted? && form_display_condition.id.blank?
76
+
77
+ update_nested_model(form_display_condition, display_condition_attributes, question.display_conditions)
78
+ end
79
+
80
+ form_question.matrix_rows.each do |form_matrix_row|
81
+ matrix_row_attributes = {
82
+ body: form_matrix_row.body
83
+ }
84
+
85
+ update_nested_model(form_matrix_row, matrix_row_attributes, question.matrix_rows)
86
+ end
59
87
  end
60
88
  end
61
89
 
@@ -80,6 +108,10 @@ module Decidim
80
108
  description: @form.description,
81
109
  tos: @form.tos)
82
110
  end
111
+
112
+ def delete_answers
113
+ @questionnaire.answers.destroy_all
114
+ end
83
115
  end
84
116
  end
85
117
  end
@@ -30,7 +30,7 @@ module Decidim
30
30
 
31
31
  def answer_questionnaire
32
32
  Answer.transaction do
33
- form.answers.each do |form_answer|
33
+ form.responses_by_step.flatten.select(&:display_conditions_fulfilled?).each do |form_answer|
34
34
  answer = Answer.new(
35
35
  user: @current_user,
36
36
  questionnaire: @questionnaire,
@@ -45,6 +45,7 @@ module Decidim
45
45
  body: choice.body,
46
46
  custom_body: choice.custom_body,
47
47
  decidim_answer_option_id: choice.answer_option_id,
48
+ decidim_question_matrix_row_id: choice.matrix_row_id,
48
49
  position: choice.position
49
50
  )
50
51
  end
@@ -15,7 +15,21 @@ module Decidim
15
15
 
16
16
  included do
17
17
  helper Decidim::Forms::Admin::ApplicationHelper
18
- helper_method :questionnaire_for, :questionnaire, :blank_question, :blank_answer_option, :question_types, :update_url
18
+ helper_method :questionnaire_for, :questionnaire, :blank_question, :blank_answer_option, :blank_matrix_row,
19
+ :blank_display_condition, :question_types, :display_condition_types, :update_url, :public_url, :answer_options_url
20
+
21
+ if defined? Decidim::Templates::Admin
22
+ include Decidim::Templates::Admin::Concerns::Templatable
23
+ helper Decidim::Templates::Admin::TemplatesHelper
24
+
25
+ def templatable_type
26
+ "Decidim::Forms::Questionnaire"
27
+ end
28
+
29
+ def templatable
30
+ questionnaire
31
+ end
32
+ end
19
33
 
20
34
  def edit
21
35
  enforce_permission_to :update, :questionnaire, questionnaire: questionnaire
@@ -46,6 +60,16 @@ module Decidim
46
60
  end
47
61
  end
48
62
 
63
+ def answer_options
64
+ respond_to do |format|
65
+ format.json do
66
+ question_id = params["id"]
67
+ question = Question.find_by(id: question_id)
68
+ render json: question.answer_options.map { |answer_option| AnswerOptionPresenter.new(answer_option).as_json } if question.present?
69
+ end
70
+ end
71
+ end
72
+
49
73
  # Public: The only method to be implemented at the controller. You need to
50
74
  # return the object that will hold the questionnaire.
51
75
  def questionnaire_for
@@ -64,6 +88,18 @@ module Decidim
64
88
  url_for(questionnaire.questionnaire_for)
65
89
  end
66
90
 
91
+ # Implement this method in your controller to set the URL
92
+ # where the questionnaire can be answered.
93
+ def public_url
94
+ raise "#{self.class.name} is expected to implement #public_url"
95
+ end
96
+
97
+ # Returns the url to get the answer options json (for the display conditions form)
98
+ # for the question with id = params[:id]
99
+ def answer_options_url(params)
100
+ url_for([questionnaire.questionnaire_for, action: :answer_options, format: :json, **params])
101
+ end
102
+
67
103
  private
68
104
 
69
105
  def i18n_flashes_scope
@@ -82,11 +118,25 @@ module Decidim
82
118
  @blank_answer_option ||= Admin::AnswerOptionForm.new
83
119
  end
84
120
 
121
+ def blank_display_condition
122
+ @blank_display_condition ||= Admin::DisplayConditionForm.new
123
+ end
124
+
125
+ def blank_matrix_row
126
+ @blank_matrix_row ||= Admin::QuestionMatrixRowForm.new
127
+ end
128
+
85
129
  def question_types
86
- @question_types ||= Question::TYPES.map do |question_type|
130
+ @question_types ||= Question::QUESTION_TYPES.map do |question_type|
87
131
  [question_type, I18n.t("decidim.forms.question_types.#{question_type}")]
88
132
  end
89
133
  end
134
+
135
+ def display_condition_types
136
+ @display_condition_types ||= DisplayCondition.condition_types.keys.map do |condition_type|
137
+ [condition_type, I18n.t("decidim.forms.admin.questionnaires.display_condition.condition_types.#{condition_type}")]
138
+ end
139
+ end
90
140
  end
91
141
  end
92
142
  end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Forms
5
+ module Admin
6
+ module Concerns
7
+ # Questionnaires can be related to any class in Decidim. In order to
8
+ # manage the questionnaires answers for a given type, you should create a new
9
+ # controller and include the HasQuestionnaire concern as well as this one.
10
+ #
11
+ # In the controller that includes this concern, you should define a
12
+ # `questionnaire_for` method that returns an instance of the model that the
13
+ # questionnaire belongs to. You should also define the routes for:
14
+ # `index_<model>_url` and `export_<model>_url` as well as
15
+ # `show_<model>_url` and `export_response_<model>_url` (which are passed
16
+ # a `:session_token` parameter)
17
+ module HasQuestionnaireAnswers
18
+ extend ActiveSupport::Concern
19
+
20
+ included do
21
+ include Decidim::Paginable
22
+ include Decidim::Forms::Admin::Concerns::HasQuestionnaireAnswersUrlHelper
23
+ include Decidim::Forms::Admin::Concerns::HasQuestionnaireAnswersPaginationHelper
24
+
25
+ helper Decidim::Forms::Admin::QuestionnaireAnswersHelper
26
+
27
+ def index
28
+ enforce_permission_to :index, :questionnaire_answers
29
+
30
+ @query = paginate(collection)
31
+ @participants = participants(@query)
32
+ @total = participants_query.count_participants
33
+
34
+ render template: "decidim/forms/admin/questionnaires/answers/index"
35
+ end
36
+
37
+ def show
38
+ enforce_permission_to :show, :questionnaire_answers
39
+
40
+ @participant = participant(participants_query.participant(params[:session_token]))
41
+
42
+ render template: "decidim/forms/admin/questionnaires/answers/show"
43
+ end
44
+
45
+ def export_response
46
+ enforce_permission_to :export_response, :questionnaire_answers
47
+
48
+ session_token = params[:session_token]
49
+ answers = QuestionnaireUserAnswers.for(questionnaire)
50
+
51
+ # i18n-tasks-use t("decidim.forms.admin.questionnaires.answers.export_response.title")
52
+ title = t("export_response.title", scope: i18n_scope, token: session_token)
53
+
54
+ Decidim::Forms::ExportQuestionnaireAnswersJob.perform_later(current_user, title, answers.select { |a| a.first.session_token == session_token })
55
+
56
+ flash[:notice] = t("decidim.admin.exports.notice")
57
+
58
+ redirect_back(fallback_location: questionnaire_participant_answers_url(session_token))
59
+ end
60
+
61
+ # Public: The only method to be implemented at the controller. You need to
62
+ # return the object that will hold the questionnaire.
63
+ def questionnaire_for
64
+ raise "#{self.class.name} is expected to implement #questionnaire_for"
65
+ end
66
+
67
+ private
68
+
69
+ def i18n_scope
70
+ "decidim.forms.admin.questionnaires.answers"
71
+ end
72
+
73
+ def questionnaire
74
+ @questionnaire ||= Questionnaire.find_by(questionnaire_for: questionnaire_for)
75
+ end
76
+
77
+ def participants_query
78
+ QuestionnaireParticipants.new(questionnaire)
79
+ end
80
+
81
+ def collection
82
+ @collection ||= participants_query.participants
83
+ end
84
+
85
+ def participant(answer)
86
+ Decidim::Forms::Admin::QuestionnaireParticipantPresenter.new(participant: answer)
87
+ end
88
+
89
+ def participants(query)
90
+ query.map { |answer| participant(answer) }
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end