decidim-forms 0.29.6 → 0.30.0.rc1
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 +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 +4 -25
- 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 +14 -4
- data/app/views/decidim/forms/admin/questionnaires/_questions_form.html.erb +80 -0
- data/app/views/decidim/forms/admin/questionnaires/_separator.html.erb +10 -3
- data/app/views/decidim/forms/admin/questionnaires/_title_and_description.html.erb +11 -1
- 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/_answer.html.erb +1 -1
- 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/_long_answer.html.erb +1 -1
- data/app/views/decidim/forms/questionnaires/answers/_short_answer.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/ar.yml +18 -1
- data/config/locales/bg.yml +42 -2
- data/config/locales/ca.yml +59 -13
- data/config/locales/cs.yml +54 -8
- data/config/locales/de.yml +56 -10
- data/config/locales/el.yml +41 -2
- data/config/locales/en.yml +51 -5
- data/config/locales/es-MX.yml +61 -15
- data/config/locales/es-PY.yml +61 -15
- data/config/locales/es.yml +60 -14
- data/config/locales/eu.yml +58 -12
- data/config/locales/fi-plain.yml +56 -10
- data/config/locales/fi.yml +56 -10
- data/config/locales/fr-CA.yml +51 -13
- data/config/locales/fr.yml +51 -13
- data/config/locales/ga-IE.yml +9 -0
- data/config/locales/gl.yml +11 -1
- data/config/locales/hu.yml +14 -1
- data/config/locales/id-ID.yml +9 -1
- data/config/locales/it.yml +31 -3
- data/config/locales/ja.yml +13 -12
- data/config/locales/lb.yml +32 -1
- data/config/locales/lt.yml +41 -2
- data/config/locales/lv.yml +15 -1
- data/config/locales/nl.yml +29 -0
- data/config/locales/no.yml +33 -0
- data/config/locales/pl.yml +43 -2
- data/config/locales/pt-BR.yml +35 -0
- data/config/locales/pt.yml +31 -0
- data/config/locales/ro-RO.yml +50 -17
- data/config/locales/ru.yml +3 -2
- data/config/locales/sk.yml +12 -1
- data/config/locales/sl.yml +7 -0
- data/config/locales/sv.yml +17 -15
- data/config/locales/tr-TR.yml +27 -0
- data/config/locales/val-ES.yml +2 -0
- data/config/locales/zh-CN.yml +27 -0
- data/config/locales/zh-TW.yml +41 -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 +46 -7
- 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 +115 -247
- data/lib/decidim/forms/test/shared_examples/manage_questionnaires.rb +3 -29
- data/lib/decidim/forms/version.rb +1 -1
- data/lib/decidim/forms.rb +0 -1
- metadata +18 -33
- 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/config/locales/ca-IT.yml +0 -192
- data/lib/decidim/exporters/form_pdf_controller_helper.rb +0 -13
data/config/locales/sk.yml
CHANGED
|
@@ -9,6 +9,12 @@ sk:
|
|
|
9
9
|
question_type: Typ
|
|
10
10
|
questionnaire_question:
|
|
11
11
|
mandatory: Povinné
|
|
12
|
+
errors:
|
|
13
|
+
models:
|
|
14
|
+
answer:
|
|
15
|
+
attributes:
|
|
16
|
+
choices:
|
|
17
|
+
missing: nie je kompletné
|
|
12
18
|
decidim:
|
|
13
19
|
forms:
|
|
14
20
|
admin:
|
|
@@ -19,6 +25,7 @@ sk:
|
|
|
19
25
|
questionnaires:
|
|
20
26
|
answer_option:
|
|
21
27
|
answer_option: Možnosť odpovede
|
|
28
|
+
free_text: Voľný text
|
|
22
29
|
remove: Odstrániť
|
|
23
30
|
statement: Prehlásenie
|
|
24
31
|
edit:
|
|
@@ -32,9 +39,11 @@ sk:
|
|
|
32
39
|
add_answer_option: Pridať možnosť odpovede
|
|
33
40
|
any: Akékoľvek
|
|
34
41
|
description: Popis
|
|
42
|
+
down: Nadol
|
|
35
43
|
question: Otázka
|
|
36
44
|
remove: Odstrániť
|
|
37
45
|
statement: Prehlásenie
|
|
46
|
+
up: Hore
|
|
38
47
|
update:
|
|
39
48
|
invalid: Vyskytol sa problém s ukladaním formulára.
|
|
40
49
|
question_types:
|
|
@@ -68,4 +77,6 @@ sk:
|
|
|
68
77
|
user_answers_serializer:
|
|
69
78
|
created_at: Odpovedané na
|
|
70
79
|
id: ID odpovede
|
|
71
|
-
|
|
80
|
+
registered: Registrovaný
|
|
81
|
+
unregistered: Neregistrovaný
|
|
82
|
+
user_status: Status Užívateľa
|
data/config/locales/sl.yml
CHANGED
data/config/locales/sv.yml
CHANGED
|
@@ -40,7 +40,7 @@ sv:
|
|
|
40
40
|
answer_option: Svarsalternativ
|
|
41
41
|
free_text: Fritext
|
|
42
42
|
remove: Ta bort
|
|
43
|
-
statement:
|
|
43
|
+
statement: Påstående
|
|
44
44
|
answers:
|
|
45
45
|
actions:
|
|
46
46
|
back: Tillbaka till svar
|
|
@@ -78,12 +78,9 @@ sv:
|
|
|
78
78
|
select_condition_type: Välj en typ av villkor
|
|
79
79
|
edit:
|
|
80
80
|
save: Spara
|
|
81
|
-
title: Redigera
|
|
81
|
+
title: Redigera enkät
|
|
82
82
|
form:
|
|
83
83
|
add_question: Lägg till fråga
|
|
84
|
-
add_separator: Lägg till avgränsare
|
|
85
|
-
add_title_and_description: Lägg till titel och beskrivning
|
|
86
|
-
already_answered_warning: Frågeformuläret har redan besvarats av användare och du kan inte längre ändra frågorna.
|
|
87
84
|
collapse: Dölj alla frågor
|
|
88
85
|
expand: Visa alla frågor
|
|
89
86
|
preview: Förhandsgranska
|
|
@@ -91,29 +88,35 @@ sv:
|
|
|
91
88
|
matrix_row:
|
|
92
89
|
matrix_row: Rad
|
|
93
90
|
remove: Ta bort
|
|
94
|
-
statement:
|
|
91
|
+
statement: Påstående
|
|
95
92
|
question:
|
|
96
93
|
add_answer_option: Lägg till svarsalternativ
|
|
97
94
|
add_display_condition: Lägg till visningsvillkor
|
|
98
95
|
add_display_condition_info: Spara formuläret för att konfigurera visningsvillkor
|
|
99
96
|
add_matrix_row: Lägg till rad
|
|
100
|
-
any:
|
|
97
|
+
any: Någon
|
|
101
98
|
collapse: Dölj
|
|
102
99
|
description: Beskrivning
|
|
100
|
+
down: Ned
|
|
103
101
|
expand: Visa
|
|
104
102
|
question: Fråga
|
|
105
103
|
remove: Ta bort
|
|
106
|
-
statement:
|
|
104
|
+
statement: Påstående
|
|
105
|
+
up: Upp
|
|
107
106
|
separator:
|
|
108
|
-
|
|
107
|
+
down: Ner
|
|
108
|
+
remove: Radera
|
|
109
109
|
separator: Avgränsare
|
|
110
|
+
up: Upp
|
|
110
111
|
title_and_description:
|
|
111
112
|
collapse: Dölj
|
|
112
113
|
description: Beskrivning
|
|
114
|
+
down: Ner
|
|
113
115
|
expand: Visa
|
|
114
|
-
remove:
|
|
116
|
+
remove: Radera
|
|
115
117
|
title: Titel
|
|
116
118
|
title_and_description: Titel och beskrivning
|
|
119
|
+
up: Upp
|
|
117
120
|
update:
|
|
118
121
|
invalid: Det gick inte att spara formuläret.
|
|
119
122
|
success: Formuläret har sparats.
|
|
@@ -143,7 +146,7 @@ sv:
|
|
|
143
146
|
questionnaires:
|
|
144
147
|
answer:
|
|
145
148
|
invalid: Det gick inte att besvara formuläret.
|
|
146
|
-
max_choices_alert:
|
|
149
|
+
max_choices_alert: För många alternativ har valts
|
|
147
150
|
success: Formuläret har besvarats.
|
|
148
151
|
question:
|
|
149
152
|
max_choices: 'Högst antal val: %{n}'
|
|
@@ -171,19 +174,18 @@ sv:
|
|
|
171
174
|
title: JavaScript är inaktiverat
|
|
172
175
|
questionnaire_not_published:
|
|
173
176
|
body: Formulär är ännu inte publicerat.
|
|
174
|
-
tos_agreement: Genom att
|
|
177
|
+
tos_agreement: Genom att delta godkänner du användarvillkoren
|
|
175
178
|
step_navigation:
|
|
176
179
|
show:
|
|
177
|
-
are_you_sure: Efter att du har skickat in anmälan kan du inte ändra i den. Vill du fortsätta?
|
|
178
180
|
back: Tillbaka
|
|
179
181
|
continue: Fortsätt
|
|
180
|
-
submit: Skicka
|
|
182
|
+
submit: Skicka in
|
|
181
183
|
user_answers_serializer:
|
|
182
184
|
body: Svar
|
|
183
185
|
completion: Slutfört
|
|
184
186
|
created_at: Besvarad
|
|
185
187
|
id: Svars-ID
|
|
186
|
-
ip_hash: IP
|
|
188
|
+
ip_hash: IP Hash
|
|
187
189
|
question: Fråga
|
|
188
190
|
registered: Registrerad
|
|
189
191
|
session_token: Identifierare för användare
|
data/config/locales/tr-TR.yml
CHANGED
|
@@ -4,11 +4,19 @@ tr:
|
|
|
4
4
|
attributes:
|
|
5
5
|
answer:
|
|
6
6
|
body: Cevap
|
|
7
|
+
choices: Seçenekler
|
|
8
|
+
selected_choices: Seçilmiş seçenekler
|
|
7
9
|
question:
|
|
8
10
|
max_choices: Maksimum seçenek sayısı
|
|
9
11
|
question_type: tip
|
|
10
12
|
questionnaire_question:
|
|
11
13
|
mandatory: Zorunlu
|
|
14
|
+
errors:
|
|
15
|
+
models:
|
|
16
|
+
answer:
|
|
17
|
+
attributes:
|
|
18
|
+
choices:
|
|
19
|
+
missing: tamamlanmadı
|
|
12
20
|
decidim:
|
|
13
21
|
forms:
|
|
14
22
|
admin:
|
|
@@ -22,14 +30,22 @@ tr:
|
|
|
22
30
|
show: Yanıtları göster
|
|
23
31
|
answer_option:
|
|
24
32
|
answer_option: Cevap seçeneği
|
|
33
|
+
free_text: Ücretsiz Metin
|
|
25
34
|
remove: Kaldır
|
|
26
35
|
statement: Beyan
|
|
27
36
|
answers:
|
|
28
37
|
actions:
|
|
38
|
+
back: Yanıtlara dön
|
|
39
|
+
export: Dışa aktar
|
|
29
40
|
show: Cevapları göster
|
|
30
41
|
empty: Henüz cevap bulunmuyor
|
|
42
|
+
export:
|
|
43
|
+
answer:
|
|
44
|
+
title: '#%{number} yanıt'
|
|
31
45
|
export_response:
|
|
32
46
|
title: survey_user_answers _%{token}
|
|
47
|
+
index:
|
|
48
|
+
title: "%{total} toplam yanıt"
|
|
33
49
|
show:
|
|
34
50
|
title: '%{number} cevap'
|
|
35
51
|
display_condition:
|
|
@@ -71,13 +87,17 @@ tr:
|
|
|
71
87
|
any: herhangi
|
|
72
88
|
collapse: Daralt
|
|
73
89
|
description: Açıklama
|
|
90
|
+
down: Aşağı
|
|
74
91
|
expand: Genişlet
|
|
75
92
|
question: Soru
|
|
76
93
|
remove: Kaldır
|
|
77
94
|
statement: Beyan
|
|
95
|
+
up: yukarı
|
|
78
96
|
separator:
|
|
97
|
+
down: Aşağı
|
|
79
98
|
remove: Kaldır
|
|
80
99
|
separator: Ayraç
|
|
100
|
+
up: Yukarı
|
|
81
101
|
update:
|
|
82
102
|
invalid: Formu kaydederken bir sorun oluştu.
|
|
83
103
|
success: Başarıyla kaydedildi.
|
|
@@ -94,6 +114,7 @@ tr:
|
|
|
94
114
|
questionnaires:
|
|
95
115
|
answer:
|
|
96
116
|
invalid: Formu yanıtlarken bir sorun oluştu.
|
|
117
|
+
max_choices_alert: Çok fazla seçenek seçilmiş
|
|
97
118
|
success: Form başarıyla cevaplandı.
|
|
98
119
|
question:
|
|
99
120
|
max_choices: 'Maksimum seçenek: %{n}'
|
|
@@ -125,6 +146,12 @@ tr:
|
|
|
125
146
|
submit: Gönder
|
|
126
147
|
user_answers_serializer:
|
|
127
148
|
body: Cevap
|
|
149
|
+
completion: Tamamlanma
|
|
128
150
|
created_at: Yanıtlandı
|
|
129
151
|
id: Cevap kimliği
|
|
152
|
+
ip_hash: IP Hash
|
|
130
153
|
question: Soru
|
|
154
|
+
registered: Kayıtlı
|
|
155
|
+
session_token: Kullanıcı tanımlayıcı
|
|
156
|
+
unregistered: Kayıtlı değil
|
|
157
|
+
user_status: Kullanıcı durumu
|
data/config/locales/val-ES.yml
CHANGED
|
@@ -7,9 +7,11 @@ val:
|
|
|
7
7
|
title_and_description:
|
|
8
8
|
collapse: Redueix
|
|
9
9
|
description: Descripció
|
|
10
|
+
down: Baixar
|
|
10
11
|
expand: Expandeix
|
|
11
12
|
remove: Elimina
|
|
12
13
|
title: Títol
|
|
13
14
|
title_and_description: Títol i descripció
|
|
15
|
+
up: Pujar
|
|
14
16
|
question_types:
|
|
15
17
|
title_and_description: Títol i descripció
|
data/config/locales/zh-CN.yml
CHANGED
|
@@ -4,11 +4,19 @@ zh-CN:
|
|
|
4
4
|
attributes:
|
|
5
5
|
answer:
|
|
6
6
|
body: 答案
|
|
7
|
+
choices: 选择
|
|
8
|
+
selected_choices: 选定的选择
|
|
7
9
|
question:
|
|
8
10
|
max_choices: 选择的最大数量
|
|
9
11
|
question_type: 类型
|
|
10
12
|
questionnaire_question:
|
|
11
13
|
mandatory: Mandatory
|
|
14
|
+
errors:
|
|
15
|
+
models:
|
|
16
|
+
answer:
|
|
17
|
+
attributes:
|
|
18
|
+
choices:
|
|
19
|
+
missing: 不完成
|
|
12
20
|
decidim:
|
|
13
21
|
forms:
|
|
14
22
|
admin:
|
|
@@ -22,14 +30,22 @@ zh-CN:
|
|
|
22
30
|
show: 显示回复
|
|
23
31
|
answer_option:
|
|
24
32
|
answer_option: 答案选项
|
|
33
|
+
free_text: 免费文本
|
|
25
34
|
remove: 删除
|
|
26
35
|
statement: 声明
|
|
27
36
|
answers:
|
|
28
37
|
actions:
|
|
38
|
+
back: 回到回应
|
|
39
|
+
export: 导出
|
|
29
40
|
show: 显示答案
|
|
30
41
|
empty: 尚无答案
|
|
42
|
+
export:
|
|
43
|
+
answer:
|
|
44
|
+
title: '回复 #%{number}'
|
|
31
45
|
export_response:
|
|
32
46
|
title: survey_user_answers_%{token}
|
|
47
|
+
index:
|
|
48
|
+
title: "%{total} 个回复总数"
|
|
33
49
|
show:
|
|
34
50
|
title: '答案 #%{number}'
|
|
35
51
|
display_condition:
|
|
@@ -70,13 +86,17 @@ zh-CN:
|
|
|
70
86
|
any: 任何
|
|
71
87
|
collapse: 收起
|
|
72
88
|
description: 描述
|
|
89
|
+
down: 向下
|
|
73
90
|
expand: 扩展
|
|
74
91
|
question: 问
|
|
75
92
|
remove: 删除
|
|
76
93
|
statement: 声明
|
|
94
|
+
up: 上移
|
|
77
95
|
separator:
|
|
96
|
+
down: 向下
|
|
78
97
|
remove: 删除
|
|
79
98
|
separator: 分隔符
|
|
99
|
+
up: 上移
|
|
80
100
|
update:
|
|
81
101
|
invalid: 保存表单时出错。
|
|
82
102
|
success: 表单保存成功。
|
|
@@ -93,6 +113,7 @@ zh-CN:
|
|
|
93
113
|
questionnaires:
|
|
94
114
|
answer:
|
|
95
115
|
invalid: 回答表单时出现问题。
|
|
116
|
+
max_choices_alert: 选择了太多选项
|
|
96
117
|
success: 表单回答成功。
|
|
97
118
|
question:
|
|
98
119
|
max_choices: '最大选择数: %{n}'
|
|
@@ -123,6 +144,12 @@ zh-CN:
|
|
|
123
144
|
submit: 提交
|
|
124
145
|
user_answers_serializer:
|
|
125
146
|
body: 答案
|
|
147
|
+
completion: 完成
|
|
126
148
|
created_at: 回答于
|
|
127
149
|
id: 答案 ID
|
|
150
|
+
ip_hash: IP哈希
|
|
128
151
|
question: 问
|
|
152
|
+
registered: 已注册
|
|
153
|
+
session_token: 用户标识符
|
|
154
|
+
unregistered: 未注册
|
|
155
|
+
user_status: 用户状态
|
data/config/locales/zh-TW.yml
CHANGED
|
@@ -4,6 +4,8 @@ zh-TW:
|
|
|
4
4
|
attributes:
|
|
5
5
|
answer:
|
|
6
6
|
body: 回答
|
|
7
|
+
choices: 選項
|
|
8
|
+
selected_choices: 已選擇的選項
|
|
7
9
|
question:
|
|
8
10
|
max_choices: 選擇的最大數量
|
|
9
11
|
question_type: 類別
|
|
@@ -12,8 +14,14 @@ zh-TW:
|
|
|
12
14
|
max_characters: 字元限制(如果不需要限制,請設為0)
|
|
13
15
|
errors:
|
|
14
16
|
models:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
answer:
|
|
18
|
+
attributes:
|
|
19
|
+
add_documents:
|
|
20
|
+
needs_to_be_reattached: 需要重新附加
|
|
21
|
+
body:
|
|
22
|
+
too_long: 太長
|
|
23
|
+
choices:
|
|
24
|
+
missing: 尚未完成
|
|
17
25
|
decidim:
|
|
18
26
|
forms:
|
|
19
27
|
admin:
|
|
@@ -27,14 +35,24 @@ zh-TW:
|
|
|
27
35
|
show: 顯示回應
|
|
28
36
|
answer_option:
|
|
29
37
|
answer_option: 答案選項:
|
|
38
|
+
free_text: 免費文字
|
|
30
39
|
remove: 移除
|
|
31
40
|
statement: 聲明
|
|
32
41
|
answers:
|
|
33
42
|
actions:
|
|
43
|
+
back: 返回回覆
|
|
44
|
+
export: 匯出
|
|
45
|
+
next: 下一個 ›
|
|
46
|
+
previous: "‹ 上一篇"
|
|
34
47
|
show: 顯示答案
|
|
35
48
|
empty: 目前尚未回答
|
|
49
|
+
export:
|
|
50
|
+
answer:
|
|
51
|
+
title: '回應 #%{number}'
|
|
36
52
|
export_response:
|
|
37
53
|
title: 調查問卷使用者回答_%{token}
|
|
54
|
+
index:
|
|
55
|
+
title: "%{total} 個回應總數"
|
|
38
56
|
show:
|
|
39
57
|
title: '回答#%{number}'
|
|
40
58
|
display_condition:
|
|
@@ -76,26 +94,35 @@ zh-TW:
|
|
|
76
94
|
any: 任何
|
|
77
95
|
collapse: 收回
|
|
78
96
|
description: 說明
|
|
97
|
+
down: 向下
|
|
79
98
|
expand: 展開
|
|
80
99
|
question: 問題
|
|
81
100
|
remove: 移除
|
|
82
101
|
statement: 聲明
|
|
102
|
+
up: 往上
|
|
83
103
|
separator:
|
|
104
|
+
down: 向下
|
|
84
105
|
remove: 移除
|
|
85
106
|
separator: 分隔線
|
|
107
|
+
up: 往上
|
|
86
108
|
title_and_description:
|
|
87
109
|
collapse: 收回
|
|
88
110
|
description: 說明
|
|
111
|
+
down: 向下
|
|
89
112
|
expand: 展開
|
|
90
113
|
remove: 移除
|
|
91
114
|
title: 標題
|
|
92
115
|
title_and_description: 標題和描述
|
|
116
|
+
up: 往上
|
|
93
117
|
update:
|
|
94
118
|
invalid: 儲存表單時發生問題。
|
|
95
119
|
success: 表單已成功儲存。
|
|
96
120
|
admin_log:
|
|
97
121
|
questionnaire:
|
|
98
122
|
update: "%{user_name} 更新了 %{resource_name} 問卷模板"
|
|
123
|
+
errors:
|
|
124
|
+
answer:
|
|
125
|
+
body: 內容不能為空
|
|
99
126
|
images:
|
|
100
127
|
dimensions: "%{width} x %{height} 像素"
|
|
101
128
|
processors:
|
|
@@ -111,14 +138,20 @@ zh-TW:
|
|
|
111
138
|
single_option: 單選
|
|
112
139
|
sorting: 排序中
|
|
113
140
|
title_and_description: 標題和描述
|
|
141
|
+
questionnaire_answer_presenter:
|
|
142
|
+
download_attachment: 下載附件
|
|
114
143
|
questionnaires:
|
|
115
144
|
answer:
|
|
116
145
|
invalid: 回答表單時出現問題
|
|
146
|
+
max_choices_alert: 選擇的項目太多了
|
|
117
147
|
success: 表單已成功回答
|
|
118
148
|
question:
|
|
119
149
|
max_choices: '最多選擇數量: %{n}'
|
|
120
150
|
show:
|
|
121
151
|
answer_questionnaire:
|
|
152
|
+
already_have_an_account?: 已經有帳號了嗎?
|
|
153
|
+
are_you_new?: 新用戶?
|
|
154
|
+
sign_up_description: 建立參與者帳號以填寫問卷
|
|
122
155
|
title: 回答表單
|
|
123
156
|
current_step: 步驟%{step}
|
|
124
157
|
of_total_steps: 的%{total_steps}
|
|
@@ -144,6 +177,12 @@ zh-TW:
|
|
|
144
177
|
submit: 提交
|
|
145
178
|
user_answers_serializer:
|
|
146
179
|
body: 回答
|
|
180
|
+
completion: 完成
|
|
147
181
|
created_at: 回答時間
|
|
148
182
|
id: 回答 ID
|
|
183
|
+
ip_hash: IP Hash
|
|
149
184
|
question: 問題
|
|
185
|
+
registered: 已註冊
|
|
186
|
+
session_token: 使用者識別碼
|
|
187
|
+
unregistered: 未註冊
|
|
188
|
+
user_status: 用戶狀態
|
|
@@ -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
|