decidim-forms 0.29.2 → 0.30.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/cells/decidim/forms/step_navigation_cell.rb +18 -5
- data/app/commands/decidim/forms/admin/update_questionnaire.rb +1 -82
- data/app/commands/decidim/forms/admin/update_questions.rb +109 -0
- data/app/commands/decidim/forms/answer_questionnaire.rb +10 -3
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire.rb +39 -3
- data/app/controllers/decidim/forms/admin/concerns/has_questionnaire_answers.rb +2 -2
- data/app/controllers/decidim/forms/concerns/has_questionnaire.rb +12 -4
- data/app/forms/decidim/forms/admin/display_condition_form.rb +1 -1
- data/app/forms/decidim/forms/admin/questionnaire_form.rb +0 -9
- data/app/forms/decidim/forms/admin/questions_form.rb +18 -0
- data/app/forms/decidim/forms/answer_choice_form.rb +5 -0
- data/app/forms/decidim/forms/answer_form.rb +1 -0
- data/app/forms/decidim/forms/questionnaire_form.rb +7 -0
- data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_pagination_helper.rb +1 -1
- data/app/helpers/decidim/forms/admin/concerns/has_questionnaire_answers_url_helper.rb +5 -5
- data/app/jobs/decidim/forms/export_questionnaire_answers_job.rb +5 -1
- data/app/models/decidim/forms/answer_choice.rb +0 -2
- data/app/models/decidim/forms/answer_option.rb +1 -1
- data/app/models/decidim/forms/question.rb +10 -0
- data/app/packs/entrypoints/decidim_forms.js +0 -1
- data/app/packs/entrypoints/decidim_forms_admin.js +6 -0
- data/app/packs/src/decidim/forms/admin/publish_answers_buttons.js +72 -0
- data/app/packs/src/decidim/forms/forms.js +22 -18
- data/app/presenters/decidim/forms/admin/questionnaire_participant_presenter.rb +1 -1
- data/app/presenters/decidim/forms/admin_log/question_presenter.rb +31 -0
- data/app/queries/decidim/forms/questionnaire_user_answers.rb +1 -1
- data/app/views/decidim/forms/admin/questionnaires/_answer_option_template.html.erb +1 -1
- data/app/views/decidim/forms/admin/questionnaires/_display_condition_template.html.erb +1 -1
- data/app/views/decidim/forms/admin/questionnaires/_form.html.erb +0 -89
- data/app/views/decidim/forms/admin/questionnaires/_matrix_row_template.html.erb +1 -1
- data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +3 -3
- data/app/views/decidim/forms/admin/questionnaires/_questions_form.html.erb +80 -0
- data/app/views/decidim/forms/admin/questionnaires/edit.html.erb +0 -20
- data/app/views/decidim/forms/admin/questionnaires/edit_questions.html.erb +47 -0
- data/app/views/decidim/forms/questionnaires/_questionnaire.html.erb +8 -1
- data/app/views/decidim/forms/questionnaires/answers/_files.html.erb +1 -1
- data/app/views/decidim/forms/questionnaires/answers/_sorting.html.erb +12 -6
- data/app/views/decidim/forms/questionnaires/edit.html.erb +47 -0
- data/app/views/decidim/forms/questionnaires/show.html.erb +13 -2
- data/config/assets.rb +1 -2
- data/config/locales/bg.yml +0 -2
- data/config/locales/ca.yml +46 -6
- data/config/locales/cs.yml +45 -5
- data/config/locales/de.yml +45 -5
- data/config/locales/el.yml +0 -2
- data/config/locales/en.yml +45 -5
- data/config/locales/es-MX.yml +45 -5
- data/config/locales/es-PY.yml +45 -5
- data/config/locales/es.yml +45 -5
- data/config/locales/eu.yml +45 -5
- data/config/locales/fi-plain.yml +45 -5
- data/config/locales/fi.yml +45 -5
- data/config/locales/fr-CA.yml +37 -5
- data/config/locales/fr.yml +37 -5
- data/config/locales/ja.yml +1 -1
- data/config/locales/lt.yml +0 -2
- data/config/locales/pl.yml +0 -2
- data/config/locales/ro-RO.yml +8 -3
- data/config/locales/zh-TW.yml +0 -2
- data/db/migrate/20190315203056_add_session_token_to_decidim_forms_answers.rb +1 -1
- data/db/migrate/20241122142230_add_survey_answers_published_at_to_questions.rb +7 -0
- data/decidim-forms.gemspec +1 -2
- data/lib/decidim/api/answer_option_type.rb +1 -1
- data/lib/decidim/api/question_type.rb +4 -4
- data/lib/decidim/api/questionnaire_type.rb +4 -4
- data/lib/decidim/exporters/form_pdf.rb +114 -11
- data/lib/decidim/forms/download_your_data_user_answers_serializer.rb +0 -4
- data/lib/decidim/forms/test/factories.rb +2 -2
- data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +44 -4
- data/lib/decidim/forms/test/shared_examples/manage_questionnaire_answers.rb +17 -17
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_display_conditions.rb +19 -21
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/add_questions.rb +70 -94
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_display_conditions.rb +15 -18
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires/update_questions.rb +90 -125
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +4 -25
- data/lib/decidim/forms/version.rb +1 -1
- data/lib/decidim/forms.rb +0 -1
- metadata +18 -32
- data/app/packs/entrypoints/decidim_questionnaire_answers_pdf.js +0 -1
- data/app/packs/entrypoints/decidim_questionnaire_answers_pdf.scss +0 -1
- data/app/packs/stylesheets/decidim/forms/questionnaire-answers-pdf.scss +0 -69
- data/app/views/decidim/forms/admin/questionnaires/answers/export/_answer.html.erb +0 -31
- data/app/views/decidim/forms/admin/questionnaires/answers/export/pdf.html.erb +0 -13
- data/app/views/layouts/decidim/forms/admin/questionnaires/questionnaire_answers.html.erb +0 -12
- data/config/initializers/wicked_pdf.rb +0 -26
- data/lib/decidim/exporters/form_pdf_controller_helper.rb +0 -13
data/config/locales/fr.yml
CHANGED
@@ -24,17 +24,31 @@ fr:
|
|
24
24
|
missing: ne sont pas complets
|
25
25
|
too_many: Vous pouvez choisir un maximum de %{count}.
|
26
26
|
questionnaire:
|
27
|
-
request_invalid: Une erreur s'est produite. Veuillez
|
27
|
+
request_invalid: Une erreur s'est produite lors du traitement de la requête. Veuillez essayer à nouveau.
|
28
28
|
decidim:
|
29
|
+
download_your_data:
|
30
|
+
show:
|
31
|
+
answers: Export des réponses
|
32
|
+
survey_user_answers: Réponses à l'enquête
|
29
33
|
forms:
|
30
34
|
admin:
|
31
35
|
models:
|
32
36
|
components:
|
37
|
+
allow_answers: Autoriser les réponses
|
38
|
+
allow_editing_answers: Autoriser les utilisateurs enregistrés à modifier leurs propres réponses à l'enquête
|
39
|
+
allow_unregistered: Autoriser les utilisateurs non enregistrés à répondre à l'enquête
|
40
|
+
announcement: Annonce
|
41
|
+
clean_after_publish: Supprimer les réponses lors de la publication de l’enquête
|
33
42
|
description: La description
|
43
|
+
ends_at: Réponses acceptées jusqu'au
|
44
|
+
ends_at_help: Laisser vide si aucune date spécifique
|
45
|
+
starts_at: Réponses acceptées à partir du
|
46
|
+
starts_at_help: Laisser vide si aucune date spécifique
|
34
47
|
tos: Conditions d'utilisation
|
35
48
|
questionnaires:
|
36
49
|
actions:
|
37
50
|
back: Retour aux questions
|
51
|
+
publish_answers: Publier les réponses
|
38
52
|
show: Afficher les réponses
|
39
53
|
answer_option:
|
40
54
|
answer_option: Option de réponse
|
@@ -79,16 +93,18 @@ fr:
|
|
79
93
|
edit:
|
80
94
|
save: sauvegarder
|
81
95
|
title: Modifier le questionnaire
|
82
|
-
|
96
|
+
edit_questions:
|
83
97
|
add_question: Ajouter une question
|
84
98
|
add_separator: Ajouter un séparateur
|
85
99
|
add_title_and_description: Ajouter un titre et une description
|
86
|
-
|
100
|
+
save: Enregistrer
|
101
|
+
title: Questions
|
102
|
+
form:
|
103
|
+
add_question: Ajouter une question
|
87
104
|
collapse: Réduire toutes les questions
|
88
105
|
expand: Développer toutes les questions
|
89
106
|
preview: Aperçu
|
90
107
|
title: Modifier le questionnaire pour %{questionnaire_for}
|
91
|
-
unpublished_warning: Le formulaire n'est pas publié. Vous pouvez modifier ses questions, mais cela supprimera les réponses actuelles.
|
92
108
|
matrix_row:
|
93
109
|
matrix_row: Ligne
|
94
110
|
remove: Retirer
|
@@ -107,6 +123,13 @@ fr:
|
|
107
123
|
remove: Retirer
|
108
124
|
statement: Déclaration
|
109
125
|
up: Monter
|
126
|
+
questions_form:
|
127
|
+
already_answered_warning: Certains utilisateurs ont déjà répondu au formulaire, vous ne pouvez donc pas modifier ses questions.
|
128
|
+
collapse: Replier toutes les questions
|
129
|
+
expand: Déplier toutes les questions
|
130
|
+
unpublished_warning: Le formulaire n'est pas publié. Vous pouvez modifier ses questions, mais cela supprimera les réponses actuelles.
|
131
|
+
update:
|
132
|
+
success: Les questions de l'enquête ont été sauvegardées avec succès.
|
110
133
|
separator:
|
111
134
|
down: Bas
|
112
135
|
remove: Retirer
|
@@ -125,6 +148,9 @@ fr:
|
|
125
148
|
invalid: Il y a eu des erreurs lors de la sauvegarde du questionnaire.
|
126
149
|
success: Le questionnaire a bien été sauvegardé.
|
127
150
|
admin_log:
|
151
|
+
question:
|
152
|
+
publish_answers: "%{user_name} a publié les réponses aux questions de %{resource_name} sur l'espace %{space_name}"
|
153
|
+
unpublish_answers: "%{user_name} a dépublié les réponses aux questions de %{resource_name} sur l'espace %{space_name}"
|
128
154
|
questionnaire:
|
129
155
|
update: "%{user_name} a modifié le questionnaire %{resource_name}"
|
130
156
|
errors:
|
@@ -167,6 +193,9 @@ fr:
|
|
167
193
|
questionnaire_answered:
|
168
194
|
body: Vous avez déjà répondu à ce questionnaire.
|
169
195
|
title: Déjà répondu
|
196
|
+
questionnaire_answered_edit:
|
197
|
+
body: Vous avez déjà répondu à ce formulaire. %{link}
|
198
|
+
edit: Modifier vos réponses
|
170
199
|
questionnaire_closed:
|
171
200
|
body: Le questionnaire est fermé et vous ne pouvez pas y répondre.
|
172
201
|
title: Questionnaire fermé
|
@@ -181,9 +210,12 @@ fr:
|
|
181
210
|
tos_agreement: En participant, vous acceptez ces conditions d'utilisation
|
182
211
|
step_navigation:
|
183
212
|
show:
|
184
|
-
|
213
|
+
are_you_sure_edit: Vous serez en mesure de modifier vos réponses. Êtes-vous sûr(e)?
|
214
|
+
are_you_sure_edit_guest: Si vous voulez pouvoir modifier vos réponses par la suite, vous devez vous connecter ou créer un compte.
|
215
|
+
are_you_sure_no_edit: Cette action ne peut pas être annulée et vous ne pourrez pas modifier vos réponses. Êtes-vous sûr(e) ?
|
185
216
|
back: Revenir en arrière
|
186
217
|
continue: Continuer
|
218
|
+
disallowed: Vous n'êtes pas autorisé(e) à modifier vos réponses.
|
187
219
|
submit: Soumettre
|
188
220
|
user_answers_serializer:
|
189
221
|
body: Répondre
|
data/config/locales/ja.yml
CHANGED
data/config/locales/lt.yml
CHANGED
data/config/locales/pl.yml
CHANGED
data/config/locales/ro-RO.yml
CHANGED
@@ -22,13 +22,12 @@ ro:
|
|
22
22
|
too_long: este prea lung
|
23
23
|
choices:
|
24
24
|
missing: nu sunt completate
|
25
|
-
questionnaire:
|
26
|
-
request_invalid: A apărut o eroare la procesarea cererii. Te rugăm să încerci din nou.
|
27
25
|
decidim:
|
28
26
|
forms:
|
29
27
|
admin:
|
30
28
|
models:
|
31
29
|
components:
|
30
|
+
allow_editing_answers: Permiteți utilizatorilor înregistrați să modifice propriile răspunsuri la sondaj
|
32
31
|
description: Descriere
|
33
32
|
tos: Condiţii de utilizare
|
34
33
|
questionnaires:
|
@@ -161,6 +160,9 @@ ro:
|
|
161
160
|
questionnaire_answered:
|
162
161
|
body: Ai completat deja la acest chestionar.
|
163
162
|
title: Un răspuns a fost deja trimis
|
163
|
+
questionnaire_answered_edit:
|
164
|
+
body: Ați răspuns deja la acest sondaj. %{link}
|
165
|
+
edit: Modificați răspunsurile
|
164
166
|
questionnaire_closed:
|
165
167
|
body: Chestionarul este închis și nu mai poate fi completat.
|
166
168
|
title: Formular închis
|
@@ -175,9 +177,12 @@ ro:
|
|
175
177
|
tos_agreement: Prin participare accepți Termenii și condițiile sale de utilizare
|
176
178
|
step_navigation:
|
177
179
|
show:
|
178
|
-
|
180
|
+
are_you_sure_edit: Veți putea să modificați răspunsurile. Sunteți sigur?
|
181
|
+
are_you_sure_edit_guest: Dacă doriți să modificați răspunsurile după ce veți răspunde, atunci trebuie să vă autentificați sau să creați un cont.
|
182
|
+
are_you_sure_no_edit: Această acțiune nu poate fi anulată și nu veți putea să vă modificați răspunsurile. Sunteți sigur?
|
179
183
|
back: Înapoi
|
180
184
|
continue: Continuă
|
185
|
+
disallowed: Nu aveți permisiunea să vă modificați răspunsurile.
|
181
186
|
submit: Trimite
|
182
187
|
user_answers_serializer:
|
183
188
|
body: Răspuns
|
data/config/locales/zh-TW.yml
CHANGED
@@ -10,7 +10,7 @@ class AddSessionTokenToDecidimFormsAnswers < ActiveRecord::Migration[5.2]
|
|
10
10
|
add_index :decidim_forms_answers, :session_token
|
11
11
|
|
12
12
|
Answer.find_each do |answer|
|
13
|
-
answer.session_token = Digest::MD5.hexdigest("#{answer.decidim_user_id}-#{Rails.application.
|
13
|
+
answer.session_token = Digest::MD5.hexdigest("#{answer.decidim_user_id}-#{Rails.application.secret_key_base}")
|
14
14
|
answer.save!
|
15
15
|
end
|
16
16
|
end
|
data/decidim-forms.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
"homepage_uri" => "https://decidim.org",
|
20
20
|
"source_code_uri" => "https://github.com/decidim/decidim"
|
21
21
|
}
|
22
|
-
s.required_ruby_version = "~> 3.
|
22
|
+
s.required_ruby_version = "~> 3.3.0"
|
23
23
|
|
24
24
|
s.name = "decidim-forms"
|
25
25
|
s.summary = "Decidim forms"
|
@@ -33,7 +33,6 @@ Gem::Specification.new do |s|
|
|
33
33
|
end
|
34
34
|
|
35
35
|
s.add_dependency "decidim-core", Decidim::Forms.version
|
36
|
-
s.add_dependency "wicked_pdf", "~> 2.1"
|
37
36
|
|
38
37
|
s.add_development_dependency "decidim-admin", Decidim::Forms.version
|
39
38
|
s.add_development_dependency "decidim-dev", Decidim::Forms.version
|
@@ -5,9 +5,9 @@ module Decidim
|
|
5
5
|
class AnswerOptionType < Decidim::Api::Types::BaseObject
|
6
6
|
description "An answer option for a multi-choice question in a questionnaire"
|
7
7
|
|
8
|
-
field :id, GraphQL::Types::ID, "ID of this answer option", null: false
|
9
8
|
field :body, Decidim::Core::TranslatedFieldType, "The text answer response option.", null: false
|
10
9
|
field :free_text, GraphQL::Types::Boolean, "Whether if this answer accepts any free text from the user.", null: false
|
10
|
+
field :id, GraphQL::Types::ID, "ID of this answer option", null: false
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -7,15 +7,15 @@ module Decidim
|
|
7
7
|
|
8
8
|
implements Decidim::Core::TimestampsInterface
|
9
9
|
|
10
|
-
field :
|
10
|
+
field :answer_options, [AnswerOptionType, { null: true }], "List of answer options in multi-choice questions.", null: false
|
11
11
|
field :body, Decidim::Core::TranslatedFieldType, "What is being asked in this question.", null: false
|
12
12
|
field :description, Decidim::Core::TranslatedFieldType, "The description of this question.", null: true
|
13
|
+
field :id, GraphQL::Types::ID, "ID of this question", null: false
|
13
14
|
field :mandatory, GraphQL::Types::Boolean, "Whether if this question is mandatory.", null: false
|
14
|
-
field :position, GraphQL::Types::Int, "Order position of the question in the questionnaire", null: true
|
15
|
-
field :max_choices, GraphQL::Types::Int, "On questions with answer options, maximum number of choices the user has", null: true
|
16
15
|
field :max_characters, GraphQL::Types::Int, "On questions with free text answers, maximum number of characters the answer can have (0 if no limit)", null: false
|
16
|
+
field :max_choices, GraphQL::Types::Int, "On questions with answer options, maximum number of choices the user has", null: true
|
17
|
+
field :position, GraphQL::Types::Int, "Order position of the question in the questionnaire", null: true
|
17
18
|
field :question_type, GraphQL::Types::String, "Type of question.", null: true
|
18
|
-
field :answer_options, [AnswerOptionType, { null: true }], "List of answer options in multi-choice questions.", null: false
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -7,13 +7,13 @@ module Decidim
|
|
7
7
|
|
8
8
|
implements Decidim::Core::TimestampsInterface
|
9
9
|
|
10
|
-
field :id, GraphQL::Types::ID, "ID of this questionnaire", null: false
|
11
|
-
field :title, Decidim::Core::TranslatedFieldType, "The title of this questionnaire.", null: false
|
12
10
|
field :description, Decidim::Core::TranslatedFieldType, "The description of this questionnaire.", null: true
|
13
|
-
field :tos, Decidim::Core::TranslatedFieldType, "The Terms of Service for this questionnaire.", null: true
|
14
|
-
field :for_type, GraphQL::Types::String, "Type of entity using this questionnaire.", method: :questionnaire_for_type, null: true
|
15
11
|
field :for_entity, QuestionnaireEntityInterface, "Entity using this questionnaire.", method: :questionnaire_for, null: true
|
12
|
+
field :for_type, GraphQL::Types::String, "Type of entity using this questionnaire.", method: :questionnaire_for_type, null: true
|
13
|
+
field :id, GraphQL::Types::ID, "ID of this questionnaire", null: false
|
16
14
|
field :questions, [Decidim::Forms::QuestionType, { null: true }], "Questions in this questionnaire.", null: false
|
15
|
+
field :title, Decidim::Core::TranslatedFieldType, "The title of this questionnaire.", null: false
|
16
|
+
field :tos, Decidim::Core::TranslatedFieldType, "The Terms of Service for this questionnaire.", null: true
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "wicked_pdf"
|
4
|
-
|
5
3
|
module Decidim
|
6
4
|
module Exporters
|
7
5
|
# Inherits from abstract PDF exporter. This class is used to set
|
@@ -9,25 +7,130 @@ module Decidim
|
|
9
7
|
#
|
10
8
|
class FormPDF < PDF
|
11
9
|
# i18n-tasks-use t('decidim.admin.exports.formats.FormPDF')
|
10
|
+
include ActionView::Helpers::NumberHelper
|
11
|
+
include Decidim::Forms::Admin::QuestionnaireAnswersHelper
|
12
|
+
|
13
|
+
class QuestionnaireAnswerPresenter < Decidim::Forms::Admin::QuestionnaireAnswerPresenter
|
14
|
+
def choice(choice_hash)
|
15
|
+
render_body_for choice_hash
|
16
|
+
end
|
17
|
+
|
18
|
+
delegate :attachments, to: :answer
|
19
|
+
|
20
|
+
def body
|
21
|
+
return { string: answer.body } if answer.body.present?
|
22
|
+
return { attachments: answer.attachments } if answer.attachments.any?
|
23
|
+
return { string: "-" } if answer.choices.empty?
|
24
|
+
|
25
|
+
choices = answer.choices.map do |choice|
|
26
|
+
{
|
27
|
+
answer_option_body: choice.try(:answer_option).try(:translated_body),
|
28
|
+
choice_body: body_or_custom_body(choice)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
return { single_option: choice(choices.first) } if answer.question.question_type == "single_option"
|
12
33
|
|
13
|
-
|
14
|
-
|
34
|
+
{ multiple_option: choices.map { |c| choice(c) } }
|
35
|
+
end
|
15
36
|
end
|
16
37
|
|
17
|
-
|
18
|
-
|
38
|
+
class ParticipantPresenter < Decidim::Forms::Admin::QuestionnaireParticipantPresenter
|
39
|
+
def answers
|
40
|
+
siblings.map { |answer| QuestionnaireAnswerPresenter.new(answer:) }
|
41
|
+
end
|
19
42
|
end
|
20
43
|
|
21
|
-
|
22
|
-
|
44
|
+
protected
|
45
|
+
|
46
|
+
def add_data!
|
47
|
+
composer.text(decidim_sanitize(translated_attribute(questionnaire.title), strip_tags: true), style: :h1)
|
48
|
+
composer.text(decidim_sanitize(translated_attribute(questionnaire.description), strip_tags: true), style: :description)
|
49
|
+
composer.text(I18n.t("title", scope: "decidim.forms.admin.questionnaires.answers.index", total: collection.count), style: :section_title)
|
50
|
+
|
51
|
+
local_collection = collection.map { |answer| ParticipantPresenter.new(participant: answer.first) }
|
52
|
+
|
53
|
+
local_collection.each_with_index do |record, index|
|
54
|
+
add_response_box(record, index)
|
55
|
+
end
|
23
56
|
end
|
24
57
|
|
25
|
-
def
|
58
|
+
def questionnaire = collection.first.first.questionnaire
|
59
|
+
|
60
|
+
def styles
|
26
61
|
{
|
27
|
-
|
28
|
-
|
62
|
+
h1: { font: bold_font, font_size: 18, margin: [0, 0, 10, 0] },
|
63
|
+
th: { font: bold_font, font_size: 10, margin: [0, 0, 10, 0] },
|
64
|
+
td: { font:, font_size: 10, margin: [0, 0, 10, 0] },
|
65
|
+
description: { font:, margin: [0, 0, 10, 0], font_size: 10 },
|
66
|
+
section_title: { font: bold_font, margin: [15, 0, 15, 0], font_size: 16 },
|
67
|
+
question_title: { font: bold_font, margin: [10, 0, 10, 0], font_size: 12 },
|
68
|
+
question_answer: { font:, margin: [10, 0, 10, 0], font_size: 10 },
|
69
|
+
file_info: { font:, margin: [10, 0, 10, 0], font_size: 8 },
|
70
|
+
link: { font:, margin: [10, 0, 10, 0], font_size: 10, underline: true }
|
29
71
|
}
|
30
72
|
end
|
73
|
+
|
74
|
+
def header
|
75
|
+
[
|
76
|
+
layout.text(I18n.t("session_token", scope: "decidim.forms.user_answers_serializer"), style: :th),
|
77
|
+
layout.text(I18n.t("user_status", scope: "decidim.forms.user_answers_serializer"), style: :th),
|
78
|
+
layout.text(I18n.t("ip_hash", scope: "decidim.forms.user_answers_serializer"), style: :th),
|
79
|
+
layout.text(I18n.t("completion", scope: "decidim.forms.user_answers_serializer"), style: :th),
|
80
|
+
layout.text(I18n.t("created_at", scope: "decidim.forms.user_answers_serializer"), style: :th)
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
84
|
+
def add_user_data(record)
|
85
|
+
cells = [
|
86
|
+
layout.text(record.session_token, style: :td),
|
87
|
+
layout.text(record.status, style: :td),
|
88
|
+
layout.text(record.ip_hash, style: :td),
|
89
|
+
layout.text(display_percentage(record.completion), style: :td),
|
90
|
+
layout.text(I18n.l(record.answered_at, format: :short), style: :td)
|
91
|
+
]
|
92
|
+
composer.table([cells], header: ->(_table) { [header] }, cell_style: { border: { width: 0 } })
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_response_box(record, index)
|
96
|
+
composer.text(I18n.t("title", number: index + 1, scope: "decidim.forms.admin.questionnaires.answers.export.answer"), style: :section_title)
|
97
|
+
add_user_data(record)
|
98
|
+
|
99
|
+
record.answers.each do |answer|
|
100
|
+
composer.text(answer.question, style: :question_title)
|
101
|
+
add_answer_body(answer)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def add_answer_body(answer)
|
106
|
+
return composer.text(answer.body[:string], style: :question_answer) if answer.body.has_key?(:string)
|
107
|
+
|
108
|
+
if answer.attachments.any?
|
109
|
+
composer.list(marker_type: :disc) do |sub_list|
|
110
|
+
answer.attachments.each do |attachment|
|
111
|
+
sub_list.formatted_text(
|
112
|
+
[{ link: attachment.url,
|
113
|
+
text: translated_attribute(attachment.title).presence ||
|
114
|
+
I18n.t("download_attachment", scope: "decidim.forms.questionnaire_answer_presenter"),
|
115
|
+
style: :link },
|
116
|
+
" (#{attachment.file_type} #{number_to_human_size(attachment.file_size)})"],
|
117
|
+
style: :file_info
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
return
|
122
|
+
end
|
123
|
+
|
124
|
+
if answer.body.has_key?(:single_option)
|
125
|
+
composer.list(marker_type: :disc) do |sub_list|
|
126
|
+
sub_list.text(answer.body[:single_option], style: :question_answer)
|
127
|
+
end
|
128
|
+
else
|
129
|
+
composer.list(marker_type: :disc) do |sub_list|
|
130
|
+
answer.body[:multiple_option].map { |choice| sub_list.text(choice, style: :question_answer) }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
31
134
|
end
|
32
135
|
end
|
33
136
|
end
|
@@ -8,10 +8,6 @@ module Decidim
|
|
8
8
|
def serialize
|
9
9
|
{
|
10
10
|
id: resource.id,
|
11
|
-
user: {
|
12
|
-
name: resource.user.name,
|
13
|
-
email: resource.user.email
|
14
|
-
},
|
15
11
|
questionnaire: {
|
16
12
|
id: resource.question.questionnaire.id,
|
17
13
|
title: translated_attribute(resource.question.questionnaire.title),
|
@@ -149,8 +149,8 @@ FactoryBot.define do
|
|
149
149
|
|
150
150
|
trait :with_attachments do
|
151
151
|
after(:create) do |answer, evaluator|
|
152
|
-
create
|
153
|
-
create
|
152
|
+
create(:attachment, :with_image, attached_to: answer, skip_injection: evaluator.skip_injection)
|
153
|
+
create(:attachment, :with_pdf, attached_to: answer, skip_injection: evaluator.skip_injection)
|
154
154
|
end
|
155
155
|
end
|
156
156
|
end
|