decidim-forms 0.22.0 → 0.23.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/admin/decidim_forms_manifest.css +3 -0
  3. data/app/assets/config/decidim_forms_manifest.css +1 -0
  4. data/app/assets/javascripts/decidim/forms/admin/auto_select_options_from_url.component.js.es6 +40 -0
  5. data/app/assets/javascripts/decidim/forms/admin/forms.js.es6 +181 -25
  6. data/app/assets/javascripts/decidim/forms/autosortable_checkboxes.component.js.es6 +54 -34
  7. data/app/assets/javascripts/decidim/forms/display_conditions.component.js.es6 +204 -0
  8. data/app/assets/javascripts/decidim/forms/forms.js.es6 +8 -1
  9. data/app/assets/stylesheets/decidim/forms/questionnaire-answers-pdf.scss +69 -0
  10. data/app/commands/decidim/forms/admin/update_questionnaire.rb +25 -1
  11. data/app/commands/decidim/forms/answer_questionnaire.rb +1 -1
  12. data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +47 -1
  13. data/app/controllers/decidim/forms/admin/concerns/has_questionnaire_answers.rb +97 -0
  14. data/app/forms/decidim/forms/admin/display_condition_form.rb +100 -0
  15. data/app/forms/decidim/forms/admin/question_form.rb +1 -0
  16. data/app/forms/decidim/forms/answer_form.rb +15 -0
  17. data/app/helpers/decidim/forms/admin/application_helper.rb +21 -0
  18. data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_pagination_helper.rb +49 -0
  19. data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_url_helper.rb +40 -0
  20. data/app/helpers/decidim/forms/admin/questionnaire_answers_helper.rb +27 -0
  21. data/app/jobs/decidim/forms/export_questionnaire_answers_job.rb +19 -0
  22. data/app/models/decidim/forms/answer.rb +0 -3
  23. data/app/models/decidim/forms/answer_option.rb +14 -0
  24. data/app/models/decidim/forms/display_condition.rb +51 -0
  25. data/app/models/decidim/forms/question.rb +34 -0
  26. data/app/models/decidim/forms/question_matrix_row.rb +3 -0
  27. data/app/models/decidim/forms/questionnaire.rb +11 -1
  28. data/app/presenters/decidim/forms/admin/questionnaire_answer_presenter.rb +43 -0
  29. data/app/presenters/decidim/forms/admin/questionnaire_participant_presenter.rb +60 -0
  30. data/app/presenters/decidim/forms/answer_option_presenter.rb +20 -0
  31. data/app/presenters/decidim/forms/question_presenter.rb +16 -0
  32. data/app/queries/decidim/forms/questionnaire_participant.rb +35 -0
  33. data/app/queries/decidim/forms/questionnaire_participants.rb +43 -0
  34. data/app/views/decidim/forms/admin/questionnaires/_display_condition.html.erb +88 -0
  35. data/app/views/decidim/forms/admin/questionnaires/_display_condition_template.html.erb +7 -0
  36. data/app/views/decidim/forms/admin/questionnaires/_form.html.erb +30 -4
  37. data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +19 -3
  38. data/app/views/decidim/forms/admin/questionnaires/answers/export/_answer.html.erb +31 -0
  39. data/app/views/decidim/forms/admin/questionnaires/answers/export/pdf.html.erb +13 -0
  40. data/app/views/decidim/forms/admin/questionnaires/answers/index.html.erb +53 -0
  41. data/app/views/decidim/forms/admin/questionnaires/answers/show.html.erb +48 -0
  42. data/app/views/decidim/forms/admin/questionnaires/edit.html.erb +9 -5
  43. data/app/views/decidim/forms/questionnaires/_answer.html.erb +1 -1
  44. data/app/views/decidim/forms/questionnaires/show.html.erb +22 -2
  45. data/app/views/layouts/decidim/forms/admin/questionnaires/questionnaire_answers.html.erb +12 -0
  46. data/config/initializers/wicked_pdf.rb +25 -0
  47. data/config/locales/am-ET.yml +1 -0
  48. data/config/locales/ar.yml +0 -1
  49. data/config/locales/bg-BG.yml +0 -2
  50. data/config/locales/bg.yml +14 -0
  51. data/config/locales/ca.yml +56 -4
  52. data/config/locales/cs.yml +54 -2
  53. data/config/locales/da.yml +1 -0
  54. data/config/locales/de.yml +51 -1
  55. data/config/locales/el.yml +0 -2
  56. data/config/locales/en.yml +54 -2
  57. data/config/locales/eo.yml +1 -0
  58. data/config/locales/es-MX.yml +53 -1
  59. data/config/locales/es-PY.yml +53 -1
  60. data/config/locales/es.yml +54 -2
  61. data/config/locales/et.yml +1 -0
  62. data/config/locales/eu.yml +0 -1
  63. data/config/locales/fi-plain.yml +53 -1
  64. data/config/locales/fi.yml +53 -1
  65. data/config/locales/fr-CA.yml +54 -2
  66. data/config/locales/fr.yml +54 -2
  67. data/config/locales/gl.yml +0 -1
  68. data/config/locales/hr.yml +1 -0
  69. data/config/locales/hu.yml +0 -2
  70. data/config/locales/id-ID.yml +0 -1
  71. data/config/locales/is.yml +1 -0
  72. data/config/locales/it.yml +53 -1
  73. data/config/locales/ja-JP.yml +51 -1
  74. data/config/locales/ja.yml +170 -0
  75. data/config/locales/ko-KR.yml +1 -0
  76. data/config/locales/ko.yml +1 -0
  77. data/config/locales/lt.yml +1 -0
  78. data/config/locales/{lv-LV.yml → lv.yml} +0 -1
  79. data/config/locales/mt.yml +1 -0
  80. data/config/locales/nl.yml +59 -7
  81. data/config/locales/no.yml +47 -2
  82. data/config/locales/om-ET.yml +1 -0
  83. data/config/locales/pl.yml +52 -3
  84. data/config/locales/pt-BR.yml +0 -1
  85. data/config/locales/pt.yml +51 -2
  86. data/config/locales/ro-RO.yml +51 -2
  87. data/config/locales/ru.yml +0 -1
  88. data/config/locales/sk.yml +0 -2
  89. data/config/locales/sl.yml +7 -0
  90. data/config/locales/so-SO.yml +1 -0
  91. data/config/locales/sv.yml +51 -2
  92. data/config/locales/ti-ER.yml +1 -0
  93. data/config/locales/tr-TR.yml +0 -1
  94. data/config/locales/vi-VN.yml +1 -0
  95. data/config/locales/vi.yml +1 -0
  96. data/config/locales/zh-CN.yml +172 -0
  97. data/config/locales/zh-TW.yml +1 -0
  98. data/db/migrate/20200130194123_create_decidim_forms_display_conditions.rb +20 -0
  99. data/lib/decidim/exporters/form_pdf.rb +33 -0
  100. data/lib/decidim/exporters/form_pdf_controller_helper.rb +11 -0
  101. data/lib/decidim/forms.rb +5 -0
  102. data/lib/decidim/forms/admin_engine.rb +1 -1
  103. data/lib/decidim/forms/test.rb +6 -0
  104. data/lib/decidim/forms/test/factories.rb +30 -0
  105. data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +619 -38
  106. data/lib/decidim/forms/test/shared_examples/manage_questionnaire_answers.rb +108 -0
  107. data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +21 -894
  108. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_display_conditions.rb +179 -0
  109. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_questions.rb +463 -0
  110. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_display_conditions.rb +93 -0
  111. data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_questions.rb +461 -0
  112. data/lib/decidim/forms/version.rb +1 -1
  113. metadata +91 -11
@@ -4,6 +4,9 @@ module Decidim
4
4
  module Forms
5
5
  # The data store for a QuestionMatrix in the Decidim::Forms component.
6
6
  class QuestionMatrixRow < Forms::ApplicationRecord
7
+ include Decidim::TranslatableResource
8
+
9
+ translatable_fields :body
7
10
  belongs_to :question, class_name: "Question", foreign_key: "decidim_question_id"
8
11
 
9
12
  delegate :answer_options, :mandatory, :max_choices, to: :question
@@ -4,6 +4,11 @@ module Decidim
4
4
  module Forms
5
5
  # The data store for a Questionnaire in the Decidim::Forms component.
6
6
  class Questionnaire < Forms::ApplicationRecord
7
+ include Decidim::Templates::Templatable if defined? Decidim::Templates::Templatable
8
+ include Decidim::Publicable
9
+ include Decidim::TranslatableResource
10
+
11
+ translatable_fields :title, :description, :tos
7
12
  belongs_to :questionnaire_for, polymorphic: true
8
13
 
9
14
  has_many :questions, -> { order(:position) }, class_name: "Question", foreign_key: "decidim_questionnaire_id", dependent: :destroy
@@ -11,7 +16,8 @@ module Decidim
11
16
 
12
17
  # Public: returns whether the questionnaire questions can be modified or not.
13
18
  def questions_editable?
14
- answers.empty?
19
+ has_component = questionnaire_for.respond_to? :component
20
+ (has_component && !questionnaire_for.component.published?) || answers.empty?
15
21
  end
16
22
 
17
23
  # Public: returns whether the questionnaire is answered by the user or not.
@@ -19,6 +25,10 @@ module Decidim
19
25
  query = user.is_a?(String) ? { session_token: user } : { user: user }
20
26
  answers.where(query).any? if questions.present?
21
27
  end
28
+
29
+ def pristine?
30
+ created_at.to_i == updated_at.to_i && questions.empty?
31
+ end
22
32
  end
23
33
  end
24
34
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Forms
5
+ module Admin
6
+ #
7
+ # Presenter for questionnaire answer
8
+ #
9
+ class QuestionnaireAnswerPresenter < Rectify::Presenter
10
+ include Decidim::TranslatableAttributes
11
+
12
+ attribute :answer, Decidim::Forms::Answer
13
+
14
+ def question
15
+ translated_attribute(answer.question.body)
16
+ end
17
+
18
+ def body
19
+ return answer.body if answer.body.present?
20
+ return "-" if answer.choices.empty?
21
+
22
+ choices = answer.choices.map do |choice|
23
+ choice.try(:custom_body) || choice.try(:body)
24
+ end
25
+
26
+ return choices.first if answer.question.question_type == "single_option"
27
+
28
+ content_tag(:ul) do
29
+ safe_join(choices.map { |c| choice(c) })
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def choice(choice_body)
36
+ content_tag :li do
37
+ choice_body
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Forms
5
+ module Admin
6
+ #
7
+ # Presenter for questionnaire response
8
+ #
9
+ class QuestionnaireParticipantPresenter < Rectify::Presenter
10
+ attribute :participant, Decidim::Forms::Answer
11
+
12
+ def session_token
13
+ participant.session_token || "-"
14
+ end
15
+
16
+ def ip_hash
17
+ participant.ip_hash || "-"
18
+ end
19
+
20
+ def answered_at
21
+ participant.created_at
22
+ end
23
+
24
+ delegate :questionnaire, to: :participant
25
+
26
+ def registered?
27
+ participant.decidim_user_id.present?
28
+ end
29
+
30
+ def status
31
+ t(registered? ? "registered" : "unregistered", scope: "decidim.forms.user_answers_serializer")
32
+ end
33
+
34
+ def answers
35
+ sibilings.map { |answer| QuestionnaireAnswerPresenter.new(answer: answer) }
36
+ end
37
+
38
+ def first_short_answer
39
+ short = sibilings.where("decidim_forms_questions.question_type in (?)", %w(short_answer))
40
+ short.first
41
+ end
42
+
43
+ def completion
44
+ with_body = sibilings.where("decidim_forms_questions.question_type in (?)", %w(short_answer long_answer))
45
+ .where.not(body: "").count
46
+ with_choices = sibilings.where.not("decidim_forms_questions.question_type in (?)", %w(short_answer long_answer))
47
+ .where("decidim_forms_answers.id IN (SELECT decidim_answer_id FROM decidim_forms_answer_choices)").count
48
+
49
+ (with_body + with_choices).to_f / questionnaire.questions.count * 100
50
+ end
51
+
52
+ private
53
+
54
+ def sibilings
55
+ Answer.where(session_token: participant.session_token).joins(:question).order("decidim_forms_questions.position ASC")
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Forms
5
+ #
6
+ # Decorator for answer_options
7
+ #
8
+ class AnswerOptionPresenter < SimpleDelegator
9
+ include Decidim::TranslationsHelper
10
+
11
+ def translated_body
12
+ @translated_body ||= translated_attribute body
13
+ end
14
+
15
+ def as_json(*_args)
16
+ { id: id, body: translated_body }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Forms
5
+ #
6
+ # Decorator for questions
7
+ #
8
+ class QuestionPresenter < SimpleDelegator
9
+ include Decidim::TranslationsHelper
10
+
11
+ def translated_body
12
+ @translated_body ||= translated_attribute body
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Forms
5
+ # A class used to collect user answers for a questionnaire
6
+ class QuestionnaireParticipant < Rectify::Query
7
+ # Syntactic sugar to initialize the class and return the queried objects.
8
+ #
9
+ # questionnaire - a Questionnaire object
10
+ # session_token = the session_token used by the questionnaire participant
11
+ def self.for(questionnaire, session_token)
12
+ new(questionnaire, session_token).query
13
+ end
14
+
15
+ # Initializes the class.
16
+ #
17
+ # questionnaire = a Questionnaire object
18
+ # session_token = the session_token used by the questionnaire participant
19
+ def initialize(questionnaire, session_token)
20
+ @questionnaire = questionnaire
21
+ @token = session_token
22
+ end
23
+
24
+ # Returns query with participant info
25
+ def query
26
+ answers.select(:session_token, :decidim_user_id, :ip_hash).first
27
+ end
28
+
29
+ # Finds the participant's answers.
30
+ def answers
31
+ Answer.where(questionnaire: @questionnaire, session_token: @token)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Forms
5
+ # A class used to collect user answers for a questionnaire
6
+ class QuestionnaireParticipants < Rectify::Query
7
+ # Syntactic sugar to initialize the class and return the queried objects.
8
+ #
9
+ # questionnaire - a Questionnaire object
10
+ def self.for(questionnaire)
11
+ new(questionnaire).query
12
+ end
13
+
14
+ # Initializes the class.
15
+ #
16
+ # questionnaire = a Questionnaire object
17
+ def initialize(questionnaire)
18
+ @questionnaire = questionnaire
19
+ end
20
+
21
+ # Finds all Answers for the questionnaire (unique session_tokens).
22
+ # Because exporters only have access to the Answers this
23
+ # is used as an indirect way to access the participants
24
+ # (see #participants and #participant)
25
+ def query
26
+ Answer.where(questionnaire: @questionnaire)
27
+ end
28
+
29
+ def participant(session_token)
30
+ query.find_by(session_token: session_token)
31
+ end
32
+
33
+ def participants
34
+ subquery = query.select("DISTINCT ON (decidim_forms_answers.session_token) decidim_forms_answers.*")
35
+ Answer.select("*").from(subquery).order(:created_at)
36
+ end
37
+
38
+ def count_participants
39
+ query.select(:session_token).distinct.count
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,88 @@
1
+ <% display_condition = form.object %>
2
+
3
+ <div class="card questionnaire-question-display-condition">
4
+ <div class="card-divider">
5
+ <h2 class="card-title">
6
+ <span><%= t(".display_condition") %></span>
7
+ <% if editable %>
8
+ <button class="button small alert hollow remove-display-condition button--title">
9
+ <%= t(".remove") %>
10
+ </button>
11
+ <% end %>
12
+ </h2>
13
+ </div>
14
+ <div class="card-section">
15
+ <div class="row column">
16
+ <small class="text-muted">
17
+ <%= t(".save_warning") %>
18
+ </small>
19
+ </div>
20
+ </div>
21
+ <div class="card-section">
22
+ <div class="row column questionnaire-question-display-condition-condition-question">
23
+ <%=
24
+ form.select(
25
+ :decidim_condition_question_id,
26
+ options_for_select(display_condition.questions_for_select(questionnaire, question.id), selected: display_condition.decidim_condition_question_id),
27
+ { prompt: t(".select_condition_question"), label: t(".condition_question") },
28
+ disabled: !editable,
29
+ data: { url: answer_options_url(id: question.id) }
30
+ )
31
+ %>
32
+ </div>
33
+ <div class="row column">
34
+ <%=
35
+ form.select(
36
+ :condition_type,
37
+ options_from_collection_for_select(display_condition_types, :first, :last, display_condition.condition_type),
38
+ { prompt: t(".select_condition_type"), label: t(".condition_type") },
39
+ disabled: !editable,
40
+ )
41
+ %>
42
+ </div>
43
+ <div class="row column questionnaire-question-display-condition-answer-option">
44
+ <%=
45
+ form.select(
46
+ :decidim_answer_option_id,
47
+ options_from_collection_for_select(display_condition.answer_options, :id, :translated_body, display_condition.answer_option),
48
+ { prompt: t(".select_answer_option"), label: t(".answer_option") },
49
+ disabled: !editable,
50
+ data: { selected: display_condition.answer_option&.id }
51
+ )
52
+ %>
53
+ </div>
54
+ <div class="row column questionnaire-question-display-condition-value">
55
+ <%=
56
+ form.translated(
57
+ :text_field,
58
+ :condition_value,
59
+ tabs_id: tabs_id_for_question_display_condition(question, display_condition),
60
+ label: t(".condition_value"),
61
+ disabled: !editable
62
+ )
63
+ %>
64
+ </div>
65
+ <div class="row column">
66
+ <%=
67
+ form.check_box(
68
+ :mandatory,
69
+ label: t(".mandatory"),
70
+ disabled: !questionnaire.questions_editable?
71
+ )
72
+ %>
73
+ </div>
74
+ <div class="row column">
75
+ <% display_condition.errors.full_messages.each do |msg| %>
76
+ <small class="form-error is-visible"><%= msg %></small>
77
+ <% end %>
78
+ </div>
79
+ </div>
80
+
81
+ <%= form.hidden_field :decidim_question_id, value: question.id, disabled: !editable %>
82
+
83
+ <% if display_condition.persisted? %>
84
+ <%= form.hidden_field :id, disabled: !editable %>
85
+ <% end %>
86
+
87
+ <%= form.hidden_field :deleted, disabled: !editable %>
88
+ </div>
@@ -0,0 +1,7 @@
1
+ <% question = form.object %>
2
+
3
+ <script type="text/template" class="decidim-template" id="<%= template_id %>">
4
+ <%= fields_for "questionnaire[questions][#{question.to_param}][display_conditions][]", blank_display_condition do |display_condition_form| %>
5
+ <%= render "decidim/forms/admin/questionnaires/display_condition", form: display_condition_form, question: question, editable: editable %>
6
+ <% end %>
7
+ </script>
@@ -1,10 +1,26 @@
1
1
  <div class="card">
2
2
  <div class="card-divider">
3
3
  <h2 class="card-title">
4
- <%= title %>
5
- <div class="button--title">
6
- <%= export_dropdown if allowed_to? :export_answers, :questionnaire %>
7
- </div>
4
+ <%= t(".title") %>
5
+ <% unless template? questionnaire.questionnaire_for %>
6
+ <% if allowed_to? :preview, :questionnaire %>
7
+ <div class="button--title">
8
+ <%= link_to t(".preview"), public_url, class: "button tiny button--simple", target: :_blank %>
9
+ </div>
10
+ <% end %>
11
+ <% if questionnaire.answers.any? %>
12
+ <div class="button--title">
13
+ <%= export_dropdown if allowed_to? :export_answers, :questionnaire %>
14
+ </div>
15
+ <div class="button--title">
16
+ <% if allowed_to? :show, :questionnaire_answers %>
17
+ <%= link_to t("actions.show", scope: "decidim.forms.admin.questionnaires"), questionnaire_participants_url, class: "button tiny button--title new" %>
18
+ <% end %>
19
+ </div>
20
+ <% else %>
21
+ <button class="button tiny button--title" disabled><%= t("empty", scope: "decidim.forms.admin.questionnaires.answers") %></a>
22
+ <% end %>
23
+ <% end %>
8
24
  </h2>
9
25
  </div>
10
26
  <div class="card-section">
@@ -27,6 +43,12 @@
27
43
  </div>
28
44
 
29
45
  <% if questionnaire.questions_editable? %>
46
+ <% if questionnaire.answers.any? && !questionnaire.published? %>
47
+ <div class="callout warning">
48
+ <%= t(".unpublished_warning") %>
49
+ </div>
50
+ <% end %>
51
+
30
52
  <%= fields_for "questionnaire[questions][#{blank_question.to_param}]", blank_question do |question_form| %>
31
53
  <script type="text/template" class="decidim-question-template decidim-template" id="question-template">
32
54
  <%= render "decidim/forms/admin/questionnaires/question",
@@ -34,6 +56,7 @@
34
56
  id: tabs_id_for_question(blank_question),
35
57
  editable: questionnaire.questions_editable?,
36
58
  answer_option_template_selector: "#answer-option-template-dummy",
59
+ display_condition_template_selector: "#display-condition-template-dummy",
37
60
  matrix_row_template_selector: "#matrix-row-template-dummy" %>
38
61
  </script>
39
62
  <script type="text/template" class="decidim-separator-template decidim-template" id="separator-template">
@@ -43,6 +66,7 @@
43
66
  editable: questionnaire.questions_editable? %>
44
67
  </script>
45
68
  <%= render "decidim/forms/admin/questionnaires/answer_option_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "answer-option-template-dummy" %>
69
+ <%= render "decidim/forms/admin/questionnaires/display_condition_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "display-condition-template-dummy" %>
46
70
  <%= render "decidim/forms/admin/questionnaires/matrix_row_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "matrix-row-template-dummy" %>
47
71
  <% end %>
48
72
  <% else %>
@@ -64,8 +88,10 @@
64
88
  form: question_form,
65
89
  id: tabs_id_for_question(question),
66
90
  editable: questionnaire.questions_editable?,
91
+ display_condition_template_selector: "#display-condition-template-#{index}",
67
92
  answer_option_template_selector: "#answer-option-template-#{index}",
68
93
  matrix_row_template_selector: "#matrix-row-template-#{index}" %>
94
+ <%= render "decidim/forms/admin/questionnaires/display_condition_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "display-condition-template-#{index}" %>
69
95
  <%= render "decidim/forms/admin/questionnaires/answer_option_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "answer-option-template-#{index}" %>
70
96
  <%= render "decidim/forms/admin/questionnaires/matrix_row_template", form: question_form, editable: questionnaire.questions_editable?, template_id: "matrix-row-template-#{index}" %>
71
97
  <% end %>
@@ -1,4 +1,5 @@
1
1
  <% question = form.object %>
2
+ <% is_expanded = question.errors.any? %>
2
3
 
3
4
  <div class="card questionnaire-question" id="<%= id %>-field">
4
5
  <div class="card-divider question-divider">
@@ -11,11 +12,11 @@
11
12
  </span>
12
13
 
13
14
  <button type="button" class="button small secondary button--title question--collapse" data-toggle="<%= id %>-question-card button--collapse-question-<%= id %> button--expand-question-<%= id %>">
14
- <span id="button--collapse-question-<%= id %>" data-toggler=".hide" class="icon-collapse hide">
15
+ <span id="button--collapse-question-<%= id %>" data-toggler=".hide" class="icon-collapse <%= "hide" unless is_expanded %>">
15
16
  <%== icon("caret-top", aria_label: t(".collapse"), role: "img") %>
16
17
  </span>
17
18
 
18
- <span id="button--expand-question-<%= id %>" data-toggler=".hide" class="icon-expand">
19
+ <span id="button--expand-question-<%= id %>" data-toggler=".hide" class="icon-expand <%= "hide" if is_expanded %>">
19
20
  <%== icon("caret-bottom", aria_label: t(".expand"), role: "img") %>
20
21
  </span>
21
22
  </button>
@@ -36,7 +37,7 @@
36
37
  </h2>
37
38
  </div>
38
39
 
39
- <div class="card-section collapsible hide" data-toggler=".hide" id="<%= id %>-question-card">
40
+ <div class="card-section collapsible <%= "hide" unless is_expanded %>" data-toggler=".hide" id="<%= id %>-question-card">
40
41
  <div class="row column">
41
42
  <%=
42
43
  form.translated(
@@ -128,5 +129,20 @@
128
129
  )
129
130
  %>
130
131
  </div>
132
+
133
+ <div class="questionnaire-question-display-conditions" data-template="<%= display_condition_template_selector %>">
134
+ <div class="questionnaire-question-display-conditions-list">
135
+ <% question.display_conditions.each do |display_condition| %>
136
+ <%= fields_for "questionnaire[questions][#{question.to_param}][display_conditions][]", display_condition do |display_condition_form| %>
137
+ <%= render "decidim/forms/admin/questionnaires/display_condition", form: display_condition_form, question: question, editable: editable %>
138
+ <% end %>
139
+ <% end %>
140
+ </div>
141
+
142
+ <% if editable %>
143
+ <% disabled = !question.persisted? %>
144
+ <button <%= "disabled" if disabled %> title="<%= disabled ? t(".add_display_condition_info") : t(".add_display_condition_info") %>" class="button add-display-condition"><%= t(".add_display_condition") %></button>
145
+ <% end %>
146
+ </div>
131
147
  </div>
132
148
  </div>