decidim-forms 0.24.3 → 0.25.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/forms/step_navigation/show.erb +1 -1
  3. data/app/commands/decidim/forms/admin/update_questionnaire.rb +3 -2
  4. data/app/forms/decidim/forms/admin/question_form.rb +14 -0
  5. data/app/forms/decidim/forms/admin/question_matrix_row_form.rb +2 -2
  6. data/app/forms/decidim/forms/questionnaire_form.rb +1 -0
  7. data/app/helpers/decidim/forms/application_helper.rb +1 -0
  8. data/app/jobs/decidim/forms/export_questionnaire_answers_job.rb +1 -1
  9. data/app/models/decidim/forms/question.rb +4 -0
  10. data/app/models/decidim/forms/question_matrix_row.rb +3 -0
  11. data/app/packs/entrypoints/decidim_forms.js +4 -0
  12. data/app/packs/entrypoints/decidim_forms_admin.js +4 -0
  13. data/app/packs/entrypoints/decidim_questionnaire_answers_pdf.js +1 -0
  14. data/app/packs/entrypoints/decidim_questionnaire_answers_pdf.scss +1 -0
  15. data/app/{assets/images/decidim/surveys/icon.svg → packs/images/decidim/surveys/decidim_surveys.svg} +0 -0
  16. data/app/packs/src/decidim/forms/admin/auto_buttons_by_min_items.component.js +20 -0
  17. data/app/packs/src/decidim/forms/admin/auto_select_options_by_total_items.component.js +18 -0
  18. data/app/packs/src/decidim/forms/admin/auto_select_options_from_url.component.js +35 -0
  19. data/app/{assets/javascripts/decidim/forms/admin/collapsible_questions.js.es6 → packs/src/decidim/forms/admin/collapsible_questions.js} +0 -0
  20. data/app/{assets/javascripts/decidim/forms/admin/forms.js.es6 → packs/src/decidim/forms/admin/forms.js} +16 -12
  21. data/app/packs/src/decidim/forms/admin/live_text_update.component.js +49 -0
  22. data/app/packs/src/decidim/forms/autosortable_checkboxes.component.js +83 -0
  23. data/app/packs/src/decidim/forms/display_conditions.component.js +200 -0
  24. data/app/{assets/javascripts/decidim/forms/forms.js.es6 → packs/src/decidim/forms/forms.js} +7 -7
  25. data/app/packs/src/decidim/forms/max_choices_alert.component.js +43 -0
  26. data/app/packs/src/decidim/forms/option_attached_inputs.component.js +31 -0
  27. data/app/{assets → packs}/stylesheets/decidim/forms/forms.scss +5 -0
  28. data/app/{assets → packs}/stylesheets/decidim/forms/questionnaire-answers-pdf.scss +0 -0
  29. data/app/views/decidim/forms/admin/questionnaires/_display_condition.html.erb +2 -2
  30. data/app/views/decidim/forms/admin/questionnaires/_form.html.erb +5 -3
  31. data/app/views/decidim/forms/admin/questionnaires/_matrix_row.html.erb +1 -0
  32. data/app/views/decidim/forms/admin/questionnaires/_question.html.erb +1 -1
  33. data/app/views/decidim/forms/questionnaires/answers/_matrix_multiple.html.erb +1 -1
  34. data/app/views/decidim/forms/questionnaires/answers/_matrix_single.html.erb +1 -1
  35. data/app/views/decidim/forms/questionnaires/show.html.erb +7 -1
  36. data/app/views/layouts/decidim/forms/admin/questionnaires/questionnaire_answers.html.erb +1 -1
  37. data/config/assets.rb +10 -0
  38. data/config/locales/fr-LU.yml +178 -0
  39. data/config/locales/hu.yml +2 -0
  40. data/config/locales/it.yml +7 -0
  41. data/config/locales/ja.yml +8 -0
  42. data/config/locales/lb-LU.yml +1 -0
  43. data/config/locales/pl.yml +2 -2
  44. data/config/locales/pt-BR.yml +93 -0
  45. data/db/migrate/20170515144119_create_decidim_forms_answers.rb +1 -2
  46. data/db/migrate/20210616153042_set_position_to_question_matrix_rows.rb +11 -0
  47. data/lib/decidim/forms/admin_engine.rb +0 -4
  48. data/lib/decidim/forms/engine.rb +2 -4
  49. data/lib/decidim/forms/test/factories.rb +39 -2
  50. data/lib/decidim/forms/test/shared_examples/has_questionnaire.rb +2 -0
  51. data/lib/decidim/forms/user_answers_serializer.rb +3 -0
  52. data/lib/decidim/forms/version.rb +1 -1
  53. metadata +34 -31
  54. data/app/assets/config/admin/decidim_forms_manifest.css +0 -3
  55. data/app/assets/config/admin/decidim_forms_manifest.js +0 -2
  56. data/app/assets/config/decidim_forms_manifest.css +0 -4
  57. data/app/assets/config/decidim_forms_manifest.js +0 -1
  58. data/app/assets/javascripts/decidim/forms/admin/auto_buttons_by_min_items.component.js.es6 +0 -25
  59. data/app/assets/javascripts/decidim/forms/admin/auto_select_options_by_total_items.component.js.es6 +0 -23
  60. data/app/assets/javascripts/decidim/forms/admin/auto_select_options_from_url.component.js.es6 +0 -40
  61. data/app/assets/javascripts/decidim/forms/admin/live_text_update.component.js.es6 +0 -52
  62. data/app/assets/javascripts/decidim/forms/autosortable_checkboxes.component.js.es6 +0 -85
  63. data/app/assets/javascripts/decidim/forms/display_conditions.component.js.es6 +0 -203
  64. data/app/assets/javascripts/decidim/forms/max_choices_alert.component.js.es6 +0 -44
  65. data/app/assets/javascripts/decidim/forms/option_attached_inputs.component.js.es6 +0 -32
  66. data/config/locales/ja-JP.yml +0 -170
@@ -1,203 +0,0 @@
1
- /* eslint-disable no-ternary, no-plusplus */
2
-
3
- ((exports) => {
4
- class DisplayCondition {
5
- constructor(options = {}) {
6
- this.wrapperField = options.wrapperField;
7
- this.type = options.type;
8
- this.conditionQuestion = options.conditionQuestion;
9
- this.answerOption = options.answerOption;
10
- this.mandatory = options.mandatory;
11
- this.value = options.value;
12
- this.onFulfilled = options.onFulfilled;
13
- this.bindEvent();
14
- }
15
-
16
- bindEvent() {
17
- this.checkCondition();
18
- this.getInputsToListen().on("change", this.checkCondition.bind(this));
19
- }
20
-
21
- getInputValue() {
22
- const $conditionWrapperField = $(`.question[data-question-id='${this.conditionQuestion}']`);
23
- const $textInput = $conditionWrapperField.find("textarea, input[type='text']:not([name$=\\[custom_body\\]])");
24
-
25
- if ($textInput.length) {
26
- return $textInput.val();
27
- }
28
-
29
- let multipleInput = [];
30
-
31
- $conditionWrapperField.find(".radio-button-collection, .check-box-collection").find(".collection-input").each((idx, el) => {
32
- const $input = $(el).find("input[name$=\\[body\\]]");
33
- const checked = $input.is(":checked");
34
-
35
- if (checked) {
36
- const text = $(el).find("input[name$=\\[custom_body\\]]").val();
37
- const value = $input.val();
38
- const id = $(el).find("input[name$=\\[answer_option_id\\]]").val();
39
-
40
- multipleInput.push({ id, value, text });
41
- }
42
- });
43
-
44
- return multipleInput;
45
- }
46
-
47
- getInputsToListen() {
48
- const $conditionWrapperField = $(`.question[data-question-id='${this.conditionQuestion}']`);
49
- const $textInput = $conditionWrapperField.find("textarea, input[type='text']:not([name$=\\[custom_body\\]])");
50
-
51
- if ($textInput.length) {
52
- return $textInput;
53
- }
54
-
55
- return $conditionWrapperField.find(".collection-input").find("input:not([type='hidden'])");
56
- }
57
-
58
- checkAnsweredCondition(value) {
59
- if (typeof (value) !== "object") {
60
- return Boolean(value);
61
- }
62
-
63
- return Boolean(value.some((it) => it.value));
64
- }
65
-
66
- checkNotAnsweredCondition(value) {
67
- return !this.checkAnsweredCondition(value);
68
- }
69
-
70
- checkEqualCondition(value) {
71
- if (value.length) {
72
- return value.some((it) => it.id === this.answerOption.toString());
73
- }
74
- return false;
75
- }
76
-
77
- checkNotEqualCondition(value) {
78
- if (value.length) {
79
- return value.every((it) => it.id !== this.answerOption.toString());
80
- }
81
- return false;
82
- }
83
-
84
- checkMatchCondition(value) {
85
- let regexp = new RegExp(this.value, "i");
86
-
87
- if (typeof (value) !== "object") {
88
- return Boolean(value.match(regexp));
89
- }
90
-
91
- return value.some(function (it) {
92
- return it.text
93
- ? it.text.match(regexp)
94
- : it.value.match(regexp)
95
- });
96
- }
97
-
98
- checkCondition() {
99
- const value = this.getInputValue();
100
- let fulfilled = false;
101
-
102
- switch (this.type) {
103
- case "answered":
104
- fulfilled = this.checkAnsweredCondition(value);
105
- break;
106
- case "not_answered":
107
- fulfilled = this.checkNotAnsweredCondition(value);
108
- break;
109
- case "equal":
110
- fulfilled = this.checkEqualCondition(value);
111
- break;
112
- case "not_equal":
113
- fulfilled = this.checkNotEqualCondition(value);
114
- break;
115
- case "match":
116
- fulfilled = this.checkMatchCondition(value);
117
- break;
118
- default:
119
- fulfilled = false;
120
- break;
121
- }
122
-
123
- this.onFulfilled(fulfilled);
124
- }
125
- }
126
-
127
- class DisplayConditionsComponent {
128
- constructor(options = {}) {
129
- this.wrapperField = options.wrapperField;
130
- this.conditions = {};
131
- this.showCount = 0;
132
- this.initializeConditions();
133
- }
134
-
135
- initializeConditions() {
136
- const $conditionElements = this.wrapperField.find(".display-condition");
137
-
138
- $conditionElements.each((idx, el) => {
139
- const $condition = $(el);
140
- const id = $condition.data("id");
141
- this.conditions[id] = {};
142
-
143
- this.conditions[id] = new DisplayCondition({
144
- wrapperField: this.wrapperField,
145
- type: $condition.data("type"),
146
- conditionQuestion: $condition.data("condition"),
147
- answerOption: $condition.data("option"),
148
- mandatory: $condition.data("mandatory"),
149
- value: $condition.data("value"),
150
- onFulfilled: (fulfilled) => {
151
- this.onFulfilled(id, fulfilled);
152
- }
153
- });
154
- });
155
- }
156
-
157
- mustShow() {
158
- const conditions = Object.values(this.conditions);
159
- const mandatoryConditions = conditions.filter((condition) => condition.mandatory);
160
- const nonMandatoryConditions = conditions.filter((condition) => !condition.mandatory);
161
-
162
- if (mandatoryConditions.length) {
163
- return mandatoryConditions.every((condition) => condition.fulfilled);
164
- }
165
-
166
- return nonMandatoryConditions.some((condition) => condition.fulfilled);
167
-
168
- }
169
-
170
- onFulfilled(id, fulfilled) {
171
- this.conditions[id].fulfilled = fulfilled;
172
-
173
- if (this.mustShow()) {
174
- this.showQuestion();
175
- }
176
- else {
177
- this.hideQuestion();
178
- }
179
- }
180
-
181
- showQuestion() {
182
- this.wrapperField.fadeIn();
183
- this.wrapperField.find("input, textarea").prop("disabled", null);
184
- this.showCount++;
185
- }
186
-
187
- hideQuestion() {
188
- if (this.showCount) {
189
- this.wrapperField.fadeOut();
190
- }
191
- else {
192
- this.wrapperField.hide();
193
- }
194
-
195
- this.wrapperField.find("input, textarea").prop("disabled", "disabled");
196
- }
197
- }
198
-
199
- exports.Decidim = exports.Decidim || {};
200
- exports.Decidim.createDisplayConditions = (options) => {
201
- return new DisplayConditionsComponent(options);
202
- };
203
- })(window);
@@ -1,44 +0,0 @@
1
- ((exports) => {
2
- class MaxChoicesAlertComponent {
3
- constructor(options = {}) {
4
- this.wrapperField = options.wrapperField;
5
- this.alertElement = options.alertElement;
6
- this.controllerFieldSelector = options.controllerFieldSelector;
7
- this.controllerCollectionSelector = options.controllerCollectionSelector;
8
- this.maxChoices = options.maxChoices;
9
- this.controllerSelector = this.wrapperField.find(this.controllerFieldSelector);
10
- this._bindEvent();
11
- this._run();
12
- }
13
-
14
- _run() {
15
- const rows = this.wrapperField.find(this.controllerCollectionSelector);
16
-
17
- let alert = false;
18
-
19
- rows.each((rowIdx, row) => {
20
- const checked = $(row).find(this.controllerFieldSelector).filter((checkboxIdx, checkbox) => $(checkbox).is(":checked"));
21
-
22
- alert = alert || checked.length > this.maxChoices;
23
- });
24
-
25
- if (alert) {
26
- this.alertElement.show();
27
- }
28
- else {
29
- this.alertElement.hide();
30
- }
31
- }
32
-
33
- _bindEvent() {
34
- this.controllerSelector.on("change", () => {
35
- this._run();
36
- });
37
- }
38
- }
39
-
40
- exports.Decidim = exports.Decidim || {};
41
- exports.Decidim.createMaxChoicesAlertComponent = (options) => {
42
- return new MaxChoicesAlertComponent(options);
43
- };
44
- })(window);
@@ -1,32 +0,0 @@
1
- ((exports) => {
2
- class OptionAttachedInputsComponent {
3
- constructor(options = {}) {
4
- this.wrapperField = options.wrapperField;
5
- this.controllerFieldSelector = options.controllerFieldSelector;
6
- this.dependentInputSelector = options.dependentInputSelector;
7
- this.controllerSelector = this.wrapperField.find(this.controllerFieldSelector);
8
- this._bindEvent();
9
- this._run();
10
- }
11
-
12
- _run() {
13
- this.controllerSelector.each((idx, el) => {
14
- const $field = $(el);
15
- const enabled = $field.is(":checked");
16
-
17
- $field.parents("div.collection-input").find(this.dependentInputSelector).prop("disabled", !enabled);
18
- });
19
- }
20
-
21
- _bindEvent() {
22
- this.controllerSelector.on("change", () => {
23
- this._run();
24
- });
25
- }
26
- }
27
-
28
- exports.Decidim = exports.Decidim || {};
29
- exports.Decidim.createOptionAttachedInputs = (options) => {
30
- return new OptionAttachedInputsComponent(options);
31
- };
32
- })(window);
@@ -1,170 +0,0 @@
1
- ja:
2
- activemodel:
3
- attributes:
4
- answer:
5
- body: 回答
6
- question:
7
- max_choices: 選択肢の最大数
8
- question_type: タイプ
9
- questionnaire_question:
10
- mandatory: Mandatory
11
- errors:
12
- models:
13
- answer:
14
- attributes:
15
- choices:
16
- missing: は完全ではありません
17
- too_many: 多すぎます
18
- questionnaire:
19
- request_invalid: リクエストの処理中にエラーが発生しました。もう一度やり直してください。
20
- decidim:
21
- forms:
22
- admin:
23
- models:
24
- components:
25
- description: 説明
26
- tos: 利用規約
27
- questionnaires:
28
- actions:
29
- back: 質問に戻る
30
- show: 回答を表示
31
- answer_option:
32
- answer_option: 回答オプション
33
- free_text: フリーテキスト
34
- remove: 削除
35
- statement: ステートメント
36
- answers:
37
- actions:
38
- back: 返信に戻る
39
- export: エクスポート
40
- show: 回答を表示
41
- empty: まだ回答がありません
42
- export:
43
- answer:
44
- title: '応答 #%{number}'
45
- export_response:
46
- title: survey_user_answers_%{token}
47
- index:
48
- title: "合計%{total} 件の回答"
49
- show:
50
- title: '回答 #%{number}'
51
- display_condition:
52
- answer_option: 回答オプション
53
- condition_question: 質問
54
- condition_type: 条件
55
- condition_types:
56
- answered: 回答済み
57
- equal: 等しい
58
- match: テキストを含む
59
- not_answered: 応答がありません
60
- not_equal: 等しくない
61
- condition_value: 含まれるテキスト
62
- display_condition: 条件を表示
63
- mandatory: 他の条件にかかわらず、この条件は常に満たされる必要があります
64
- remove: 削除
65
- save_warning: 表示条件を設定する前にフォームを保存してください
66
- select_answer_option: 回答オプションを選択
67
- select_condition_question: 質問を選択
68
- select_condition_type: 条件の種類を選択
69
- edit:
70
- save: 保存
71
- title: アンケートを編集
72
- form:
73
- add_question: 質問を追加
74
- add_separator: 区切り文字を追加
75
- already_answered_warning: このフォームはすでに一部のユーザーによって回答されているため、質問を修正することはできません。
76
- collapse: すべての質問を閉じる
77
- expand: すべての質問を展開
78
- preview: プレビュー
79
- title: フォームの編集
80
- unpublished_warning: フォームは公開されていません。質問を修正することはできますが、そうすると現在の回答が削除されます。
81
- matrix_row:
82
- matrix_row: 行
83
- remove: 削除
84
- statement: ステートメント
85
- question:
86
- add_answer_option: 回答オプションを追加
87
- add_display_condition: 表示条件を追加
88
- add_display_condition_info: 表示条件を設定するためにフォームを保存します
89
- add_matrix_row: 行を追加
90
- any: 任意の
91
- collapse: 折りたたむ
92
- description: 説明
93
- down: 下
94
- expand: 展開
95
- question: 質問
96
- remove: 削除
97
- statement: ステートメント
98
- up: 上へ
99
- separator:
100
- down: 下
101
- remove: 削除
102
- separator: 区切り記号
103
- up: 上へ
104
- update:
105
- invalid: フォームの保存に失敗しました。
106
- success: フォームを保存しました。
107
- errors:
108
- answer:
109
- body: 本文は空白にできません
110
- files:
111
- extension_whitelist: '承認されたフォーマット:'
112
- images:
113
- dimensions: "%{width} x %{height} px"
114
- dimensions_info: 'この画像は次のようになります:'
115
- processors:
116
- resize_and_pad: リサイズおよびパッド先
117
- resize_to_fit: フィットするようにリサイズしました
118
- question_types:
119
- long_answer: 長い回答
120
- matrix_multiple: マトリクス (複数オプション)
121
- matrix_single: マトリクス(シングルオプション)
122
- multiple_option: 複数のオプション
123
- short_answer: 短い回答
124
- single_option: 単一オプション
125
- sorting: 並び替え
126
- questionnaires:
127
- answer:
128
- invalid: フォームの回答に問題がありました。
129
- max_choices_alert: 選択された選択肢が多すぎます
130
- success: フォームは正常に回答しました。
131
- question:
132
- max_choices: '最大選択肢: %{n}'
133
- show:
134
- answer_questionnaire:
135
- anonymous_user_message: <a href="%{sign_in_link}">アカウント</a> でサインインするか、 <a href="%{sign_up_link}">サインアップ</a> してフォームに回答してください。
136
- title: フォームに回答
137
- current_step: ステップ %{step}
138
- of_total_steps: / %{total_steps}
139
- questionnaire_answered:
140
- body: このフォームには既に回答済みです。
141
- title: すでに回答済み
142
- questionnaire_closed:
143
- body: フォームが閉じられているため、回答できません。
144
- title: フォームを閉じました
145
- questionnaire_for_private_users:
146
- body: このフォームはプライベートユーザーのみ利用できます
147
- title: フォームを閉じました
148
- questionnaire_js_disabled:
149
- body: このフォームのいくつかの機能は無効になります。あなたのエクスペリエンスを向上させるために、ブラウザでJavaScriptを有効にしてください。
150
- title: JavaScriptは無効です
151
- questionnaire_not_published:
152
- body: このフォームはまだ公開されていません。
153
- tos_agreement: 参加することにより、利用規約に同意します。
154
- step_navigation:
155
- show:
156
- are_you_sure: この操作は元に戻すことができず、回答を編集することはできません。よろしいですか?
157
- back: 戻る
158
- continue: 続ける
159
- submit: 送信
160
- user_answers_serializer:
161
- body: 回答
162
- completion: 完了
163
- created_at: 回答日時
164
- id: 回答ID
165
- ip_hash: IP ハッシュ
166
- question: 質問
167
- registered: 登録済み
168
- session_token: ユーザー識別子
169
- unregistered: 未登録
170
- user_status: ユーザーの状態