decidim-surveys 0.3.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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +24 -0
  3. data/Rakefile +3 -0
  4. data/app/assets/config/admin/decidim_surveys_manifest.js +1 -0
  5. data/app/assets/images/decidim/surveys/icon.svg +1 -0
  6. data/app/assets/javascripts/decidim/surveys/admin/auto_label_by_position.component.js.es6 +33 -0
  7. data/app/assets/javascripts/decidim/surveys/admin/dynamic_fields.component.js.es6 +95 -0
  8. data/app/assets/javascripts/decidim/surveys/admin/surveys.js.es6 +85 -0
  9. data/app/assets/stylesheets/decidim/surveys/surveys.scss +9 -0
  10. data/app/commands/decidim/surveys/admin/update_survey.rb +65 -0
  11. data/app/commands/decidim/surveys/answer_survey.rb +43 -0
  12. data/app/commands/decidim/surveys/create_survey.rb +19 -0
  13. data/app/controllers/decidim/surveys/admin/application_controller.rb +15 -0
  14. data/app/controllers/decidim/surveys/admin/surveys_controller.rb +55 -0
  15. data/app/controllers/decidim/surveys/application_controller.rb +13 -0
  16. data/app/controllers/decidim/surveys/surveys_controller.rb +39 -0
  17. data/app/forms/decidim/surveys/admin/survey_form.rb +19 -0
  18. data/app/forms/decidim/surveys/admin/survey_question_answer_option_form.rb +15 -0
  19. data/app/forms/decidim/surveys/admin/survey_question_form.rb +24 -0
  20. data/app/forms/decidim/surveys/survey_answer_form.rb +36 -0
  21. data/app/forms/decidim/surveys/survey_form.rb +22 -0
  22. data/app/helpers/decidim/surveys/admin/application_helper.rb +39 -0
  23. data/app/models/decidim/surveys/abilities/admin_user.rb +34 -0
  24. data/app/models/decidim/surveys/abilities/current_user.rb +47 -0
  25. data/app/models/decidim/surveys/abilities/process_admin_user.rb +44 -0
  26. data/app/models/decidim/surveys/application_record.rb +10 -0
  27. data/app/models/decidim/surveys/survey.rb +25 -0
  28. data/app/models/decidim/surveys/survey_answer.rb +27 -0
  29. data/app/models/decidim/surveys/survey_question.rb +18 -0
  30. data/app/queries/decidim/surveys/survey_user_answers.rb +28 -0
  31. data/app/views/decidim/surveys/admin/surveys/_answer_option.html.erb +23 -0
  32. data/app/views/decidim/surveys/admin/surveys/_form.html.erb +47 -0
  33. data/app/views/decidim/surveys/admin/surveys/_question.html.erb +57 -0
  34. data/app/views/decidim/surveys/admin/surveys/edit.html.erb +7 -0
  35. data/app/views/decidim/surveys/surveys/show.html.erb +102 -0
  36. data/config/i18n-tasks.yml +11 -0
  37. data/config/locales/ca.yml +69 -0
  38. data/config/locales/en.yml +73 -0
  39. data/config/locales/es.yml +69 -0
  40. data/config/locales/eu.yml +5 -0
  41. data/config/locales/fi.yml +5 -0
  42. data/config/locales/fr.yml +5 -0
  43. data/config/locales/it.yml +5 -0
  44. data/config/locales/nl.yml +5 -0
  45. data/db/migrate/20170511092231_create_decidim_surveys.rb +15 -0
  46. data/db/migrate/20170515090916_create_decidim_survey_questions.rb +12 -0
  47. data/db/migrate/20170515144119_create_decidim_survey_answers.rb +14 -0
  48. data/db/migrate/20170518085302_add_position_to_surveys_questions.rb +7 -0
  49. data/db/migrate/20170522075938_add_mandatory_to_surveys_questions.rb +7 -0
  50. data/db/migrate/20170524122229_add_question_type_to_surveys_questions.rb +7 -0
  51. data/db/migrate/20170525132233_add_answer_options_to_surveys_questions.rb +7 -0
  52. data/lib/decidim/surveys.rb +14 -0
  53. data/lib/decidim/surveys/admin.rb +10 -0
  54. data/lib/decidim/surveys/admin_engine.rb +34 -0
  55. data/lib/decidim/surveys/engine.rb +25 -0
  56. data/lib/decidim/surveys/feature.rb +85 -0
  57. data/lib/decidim/surveys/survey_user_answers_serializer.rb +23 -0
  58. data/lib/decidim/surveys/test/factories.rb +39 -0
  59. metadata +147 -0
@@ -0,0 +1,23 @@
1
+ <div class="card survey-question-answer-option">
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <span><%= t(".answer_option") %></span>
5
+ <% if survey.questions_editable? %>
6
+ <button class="button small alert hollow remove-answer-option button--title"><%= t('.remove_answer_option') %></button>
7
+ <% end %>
8
+ </h2>
9
+ </div>
10
+
11
+ <div class="card-section">
12
+ <div class="row column">
13
+ <%=
14
+ translated_field_tag :text_field_tag, "survey[questions][][answer_options][]", "body", answer_option.body, {
15
+ tabs_id: tabs_id_for_question_answer_option(question, idx),
16
+ label: t('.statement'),
17
+ disabled: question.nil? || disabled_for_question(survey, question),
18
+ enable_tabs: question.present?
19
+ }
20
+ %>
21
+ </div>
22
+ </div>
23
+ </div>
@@ -0,0 +1,47 @@
1
+ <div class="card">
2
+ <div class="card-divider">
3
+ <h2 class="card-title">
4
+ <%= title %>
5
+ <div class="button--title">
6
+ <%= export_dropdown %>
7
+ </div>
8
+ </h2>
9
+ </div>
10
+ <div class="card-section">
11
+ <div class="row column">
12
+ <%= form.translated :text_field, :title, autofocus: true %>
13
+ </div>
14
+ <div class="row column">
15
+ <%= form.translated :editor, :description, toolbar: :full, lines: 30, label: t("models.components.description", scope: "decidim.surveys.admin") %>
16
+ </div>
17
+ <div class="row column">
18
+ <%= form.translated :editor, :tos, toolbar: :full, lines: 10, label: t("models.components.tos", scope: "decidim.surveys.admin") %>
19
+ </div>
20
+ </div>
21
+ </div>
22
+
23
+ <div class="survey-questions">
24
+ <% if survey.questions_editable? %>
25
+ <button class="button add-question"><%= t('.add_question') %></button>
26
+
27
+ <template id="survey-question-tmpl">
28
+ <%= render "question", question: blank_question %>
29
+ </template>
30
+
31
+ <template id="survey-question-answer-option-tmpl">
32
+ <%= render "answer_option", answer_option: blank_answer_option, question: nil, idx: nil %>
33
+ </template>
34
+ <% else %>
35
+ <div class="callout warning">
36
+ <%= t('.already_answered_warning') %>
37
+ </div>
38
+ <% end %>
39
+
40
+ <div class="survey-questions-list">
41
+ <% @form.questions.each_with_index do |question, idx| %>
42
+ <%= render "question", question: question %>
43
+ <% end %>
44
+ </div>
45
+ </div>
46
+
47
+ <%= javascript_include_tag "decidim/surveys/admin/surveys" %>
@@ -0,0 +1,57 @@
1
+ <div class="card survey-question" id="survey-question-<%= question.id %>-field">
2
+ <div class="card-divider question-divider">
3
+ <h2 class="card-title">
4
+ <span><%= label_for_question(survey, question) %></span>
5
+ <% if survey.questions_editable? %>
6
+ <button class="button small alert hollow remove-question button--title"><%= t('.remove_question') %></button>
7
+ <% end %>
8
+ </h2>
9
+ </div>
10
+
11
+ <div class="card-section">
12
+ <div class="row column">
13
+ <%=
14
+ translated_field_tag :text_field_tag, "survey[questions][]", "body", question.body, {
15
+ tabs_id: tabs_id_for_question(question),
16
+ label: t('.statement'),
17
+ disabled: disabled_for_question(survey, question),
18
+ enable_tabs: question.persisted?
19
+ }
20
+ %>
21
+ </div>
22
+
23
+ <div class="row column">
24
+ <%=
25
+ check_box_tag "survey[questions][][mandatory]", "1", question.mandatory, {
26
+ id: mandatory_id_for_question(question),
27
+ disabled: disabled_for_question(survey, question)
28
+ }
29
+ %>
30
+ <%= label_tag "", t('activemodel.attributes.survey_question.mandatory'), for: mandatory_id_for_question(question) %>
31
+ </div>
32
+
33
+ <div class="row column">
34
+ <%= label_tag "", t('activemodel.attributes.survey_question.question_type'), for: question_type_id_for_question(question) %>
35
+ <%= select_tag "survey[questions][][question_type]", options_from_collection_for_select(question_types, :first, :last, question.question_type), id: question_type_id_for_question(question), disabled: disabled_for_question(survey, question) %>
36
+ </div>
37
+
38
+ <% if question.persisted? %>
39
+ <%= hidden_field_tag "survey[questions][][id]", question.id, disabled: disabled_for_question(survey, question) %>
40
+ <% end %>
41
+
42
+ <%= hidden_field_tag "survey[questions][][position]", question.position || 0, disabled: disabled_for_question(survey, question) %>
43
+ <%= hidden_field_tag "survey[questions][][deleted]", false, disabled: disabled_for_question(survey, question) %>
44
+
45
+ <div class="survey-question-answer-options">
46
+ <% if survey.questions_editable? %>
47
+ <button class="button add-answer-option"><%= t('.add_answer_option') %></button>
48
+ <% end %>
49
+
50
+ <div class="survey-question-answer-options-list">
51
+ <% question.answer_options.each_with_index do |answer_option, idx| %>
52
+ <%= render "answer_option", question: question, answer_option: answer_option, idx: idx %>
53
+ <% end %>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </div>
@@ -0,0 +1,7 @@
1
+ <%= decidim_form_for(@form, url: survey_path, method: :post, html: { class: "form edit_survey" }) do |form| %>
2
+ <%= render partial: 'form', object: form, locals: { title: t('.title') } %>
3
+
4
+ <div class="button--double form-general-submit">
5
+ <%= form.submit t(".save"), class: "button" %>
6
+ </div>
7
+ <% end %>
@@ -0,0 +1,102 @@
1
+ <% add_decidim_meta_tags({
2
+ title: translated_attribute(survey.title),
3
+ description: translated_attribute(survey.description),
4
+ }) %>
5
+
6
+ <div class="row columns">
7
+ <h2 class="section-heading"><%= translated_attribute survey.title %></h2>
8
+ <div class="row">
9
+ <div class="columns large-6 medium-centered lead">
10
+ <%== translated_attribute survey.description %>
11
+ </div>
12
+ </div>
13
+ </div>
14
+
15
+ <div class="row">
16
+ <div class="columns large-6 medium-centered">
17
+ <div class="card">
18
+ <div class="card__content">
19
+ <% if current_settings.allow_answers? %>
20
+ <% if current_user %>
21
+ <% if survey.answered_by?(current_user) %>
22
+ <div class="section">
23
+ <div class="callout success">
24
+ <h5><%= t('.survey_answered.title') %></h5>
25
+ <p><%= t('.survey_answered.body') %></p>
26
+ </div>
27
+ </div>
28
+ <% else %>
29
+ <div class="answer-survey">
30
+ <%= decidim_form_for(@form, url: answer_survey_path(survey), method: :post, html: { class: "form answer-survey" }) do |form| %>
31
+ <% @form.answers.each_with_index do |answer, answer_idx| %>
32
+ <div class="row column">
33
+ <% field_id = "survey_#{survey.id}_question_#{answer.question.id}_answer_body" %>
34
+ <%= label_tag field_id , "#{answer_idx + 1}. #{translated_attribute(answer.question.body)} #{'*' if answer.question.mandatory?}" %>
35
+
36
+ <% case answer.question.question_type %>
37
+ <% when "short_answer" %>
38
+ <%= text_field_tag "survey[answers][#{answer_idx}][body][]", answer.body.try(:first), id: field_id, class: "#{'is-invalid-input' unless answer.errors.empty?}" %>
39
+ <% when "long_answer" %>
40
+ <%= text_area_tag "survey[answers][#{answer_idx}][body][]", answer.body.try(:first), id: field_id, class: "#{'is-invalid-input' unless answer.errors.empty?}", rows: 10 %>
41
+ <% when "single_option" %>
42
+ <div id="<%= field_id %>_answer_options" class="radio-button-collection">
43
+ <% answer.question.answer_options.each_with_index do |answer_option, idx| %>
44
+ <%= label_tag "#{field_id}_option_#{idx}" do %>
45
+ <%= radio_button_tag "survey[answers][#{answer_idx}][body][]", translated_attribute(answer_option["body"]), answer.body.try(:include?, translated_attribute(answer_option["body"])), id: "#{field_id}_option_#{idx}" %>
46
+ <%= translated_attribute(answer_option["body"]) %>
47
+ <% end %>
48
+ <% end %>
49
+ </div>
50
+ <% when "multiple_option" %>
51
+ <div id="<%= field_id %>_answer_options" class="check-box-collection">
52
+ <% answer.question.answer_options.each_with_index do |answer_option, idx| %>
53
+ <%= label_tag "#{field_id}_option_#{idx}" do %>
54
+ <%= check_box_tag "survey[answers][#{answer_idx}][body][]", translated_attribute(answer_option["body"]), answer.body.try(:include?, translated_attribute(answer_option["body"])), id: "#{field_id}_option_#{idx}" %>
55
+ <%= translated_attribute(answer_option["body"]) %>
56
+ <% end %>
57
+ <% end %>
58
+ </div>
59
+ <% end %>
60
+
61
+ <%= hidden_field_tag "survey[answers][#{answer_idx}][question_id]", answer.question.id %>
62
+
63
+ <% answer.errors.full_messages.each do |msg| %>
64
+ <%= content_tag :small, msg, class: "form-error is-visible" %>
65
+ <% end %>
66
+ </div>
67
+ <% end %>
68
+
69
+ <% if translated_attribute(survey.tos).present? %>
70
+ <div class="row column">
71
+ <%= form.check_box :tos_agreement, label: t(".tos_agreement"), id: "survey_tos_agreement" %>
72
+ <div class="tos-agreement-help-text help-text">
73
+ <%== translated_attribute survey.tos %>
74
+ </div>
75
+ </div>
76
+ <% end %>
77
+
78
+ <div class="button--double form-general-submit">
79
+ <%= form.submit t(".submit"), class: "button", data: { confirm: t('.are_you_sure') } %>
80
+ </div>
81
+ <% end %>
82
+ </div>
83
+ <% end %>
84
+ <% else %>
85
+ <div class="answer-survey">
86
+ <h5 class="section-heading"><%= t('.answer_survey.title') %></h5>
87
+ <p>
88
+ <%= t('.answer_survey.anonymous_user_message', sign_in_link: decidim.new_user_session_path, sign_up_link: decidim.new_user_registration_path).html_safe %>
89
+ </p>
90
+ </div>
91
+ <% end %>
92
+ <% else %>
93
+ <div class="section">
94
+ <div class="callout warning">
95
+ <h5><%= t('.survey_closed.title') %></h5>
96
+ <p><%= t('.survey_closed.body') %></p>
97
+ </div>
98
+ </div>
99
+ <% end %>
100
+ </div>
101
+ </div>
102
+ </div>
@@ -0,0 +1,11 @@
1
+ base_locale: en
2
+ locales: [en]
3
+ ignore_unused:
4
+ - "decidim.features.surveys.name"
5
+ - "decidim.features.surveys.actions.*"
6
+ - "decidim.features.surveys.settings.*"
7
+ - "decidim.surveys.admin.surveys.question.question"
8
+ - "decidim.surveys.admin.exports.*"
9
+ - "activemodel.attributes.survey_answer.*"
10
+ ignore_missing:
11
+ - decidim.participatory_processes.scopes.global
@@ -0,0 +1,69 @@
1
+ ca:
2
+ activemodel:
3
+ attributes:
4
+ survey_answer:
5
+ body: Resposta
6
+ survey_question:
7
+ mandatory: Obligatori
8
+ question_type: Tipus
9
+ decidim:
10
+ features:
11
+ surveys:
12
+ actions:
13
+ answer: Resposta
14
+ name: Enquesta
15
+ settings:
16
+ step:
17
+ allow_answers: Permetre respostes
18
+ surveys:
19
+ admin:
20
+ application_helper:
21
+ label_for_question:
22
+ question: Pregunta
23
+ exports:
24
+ survey_user_answers: Respostes dels usuaris
25
+ models:
26
+ components:
27
+ description: Descripció
28
+ tos: Termes del servei
29
+ surveys:
30
+ answer_option:
31
+ answer_option: Opció de resposta
32
+ remove_answer_option: Elimina l'opció de resposta
33
+ statement: Enunciat
34
+ edit:
35
+ save: Desar
36
+ title: Títol
37
+ form:
38
+ add_question: Afegir pregunta
39
+ already_answered_warning: L'enquesta ja està contestada per alguns usuaris i per tant no pots modificar les seves preguntes.
40
+ question:
41
+ add_answer_option: Afegir opció de resposta
42
+ question: Pregunta
43
+ remove_question: Elimina pregunta
44
+ statement: Enunciat
45
+ update:
46
+ invalid: Hi ha hagut errors en desar l'enquesta.
47
+ success: Enquesta desada correctament.
48
+ question_types:
49
+ long_answer: Resposta llarga
50
+ multiple_option: Opció múltiple
51
+ short_answer: Resposta curta
52
+ single_option: Única opció
53
+ surveys:
54
+ answer:
55
+ invalid: Hi ha hagut errors en respondre a l'enquesta.
56
+ success: Enquesta resposta correctament.
57
+ show:
58
+ answer_survey:
59
+ anonymous_user_message: <a href="%{sign_in_link}">Entra amb el teu compte</a> o <a href="%{sign_up_link}">dona't d'alta</a> per contestar l'enquesta.
60
+ title: Respon a l'enquesta
61
+ are_you_sure: Aquesta acció no es pot desfer i no podràs editar les respostes. N'estàs segur?
62
+ submit: Enviar
63
+ survey_answered:
64
+ body: Ja ha respost a aquesta enquesta.
65
+ title: Enquesta resposta
66
+ survey_closed:
67
+ body: L'enquesta està tancada i no s'hi pot participar.
68
+ title: Enquesta tancada
69
+ tos_agreement: En participar en aquesta enquesta acceptes els Termes de Servei
@@ -0,0 +1,73 @@
1
+ ---
2
+ en:
3
+ activemodel:
4
+ attributes:
5
+ survey_answer:
6
+ body: Answer
7
+ survey_question:
8
+ mandatory: Mandatory
9
+ question_type: Type
10
+ decidim:
11
+ features:
12
+ surveys:
13
+ actions:
14
+ answer: Answer
15
+ name: Survey
16
+ settings:
17
+ step:
18
+ allow_answers: Allow answers
19
+ surveys:
20
+ admin:
21
+ application_helper:
22
+ label_for_question:
23
+ question: Question
24
+ exports:
25
+ survey_user_answers: Survey user answers
26
+ models:
27
+ components:
28
+ description: Description
29
+ tos: Terms of service
30
+ surveys:
31
+ answer_option:
32
+ answer_option: Answer option
33
+ remove_answer_option: Remove answer option
34
+ statement: Statement
35
+ edit:
36
+ save: Save
37
+ title: Title
38
+ form:
39
+ add_question: Add question
40
+ already_answered_warning: The survey is already answered by some users
41
+ so you cannot modify its questions.
42
+ question:
43
+ add_answer_option: Add answer option
44
+ question: Question
45
+ remove_question: Remove question
46
+ statement: Statement
47
+ update:
48
+ invalid: There's been errors when saving the survey.
49
+ success: Survey saved successfully.
50
+ question_types:
51
+ long_answer: Long answer
52
+ multiple_option: Multiple option
53
+ short_answer: Short answer
54
+ single_option: Single option
55
+ surveys:
56
+ answer:
57
+ invalid: There's been errors when answering the survey.
58
+ success: Survey answered successfully.
59
+ show:
60
+ answer_survey:
61
+ anonymous_user_message: <a href="%{sign_in_link}">Sign in with your account</a>
62
+ or <a href="%{sign_up_link}">sign up</a> to answer the survey.
63
+ title: Answer the survey
64
+ are_you_sure: This action cannot be undone and you will not be able to edit
65
+ your answers. Are you sure?
66
+ submit: Submit
67
+ survey_answered:
68
+ body: You have already answered this survey.
69
+ title: Survey answered
70
+ survey_closed:
71
+ body: The survey is closed and cannot be answered.
72
+ title: Survey closed
73
+ tos_agreement: By participating in this survey you accept its Terms of Service
@@ -0,0 +1,69 @@
1
+ es:
2
+ activemodel:
3
+ attributes:
4
+ survey_answer:
5
+ body: Respuesta
6
+ survey_question:
7
+ mandatory: Obligatorio
8
+ question_type: Tipo
9
+ decidim:
10
+ features:
11
+ surveys:
12
+ actions:
13
+ answer: Respuesta
14
+ name: Encuesta
15
+ settings:
16
+ step:
17
+ allow_answers: Permitir respuestas
18
+ surveys:
19
+ admin:
20
+ application_helper:
21
+ label_for_question:
22
+ question: Pregunta
23
+ exports:
24
+ survey_user_answers: Respuestas de los usuarios de la encuesta
25
+ models:
26
+ components:
27
+ description: Descripción
28
+ tos: Términos de servicio
29
+ surveys:
30
+ answer_option:
31
+ answer_option: Opción de respuesta
32
+ remove_answer_option: Eliminar opción de respuesta
33
+ statement: Enunciado
34
+ edit:
35
+ save: Guardar
36
+ title: Título
37
+ form:
38
+ add_question: Añadir pregunta
39
+ already_answered_warning: La encuesta ya está contestada por algunos usuarios, así que no puedes modificar sus preguntas.
40
+ question:
41
+ add_answer_option: Agregar opción de respuesta
42
+ question: Pregunta
43
+ remove_question: Eliminar pregunta
44
+ statement: Enunciado
45
+ update:
46
+ invalid: Se han producido errores al guardar la encuesta.
47
+ success: Encuesta guardada correctamente.
48
+ question_types:
49
+ long_answer: Respuesta larga
50
+ multiple_option: Opción múltiple
51
+ short_answer: Respuesta corta
52
+ single_option: Opción individual
53
+ surveys:
54
+ answer:
55
+ invalid: Se han producido errores al responder a la encuesta.
56
+ success: La encuesta ha sido respondida con éxito.
57
+ show:
58
+ answer_survey:
59
+ anonymous_user_message: <a href="%{sign_in_link}">Inicia sesión con tu cuenta</a> o <a href="%{sign_up_link}">regístrate</a> para responder a la encuesta.
60
+ title: Contestar a la encuesta
61
+ are_you_sure: Esta acción no se puede deshacer y no podrás editar tus respuestas. ¿Estás seguro?
62
+ submit: Enviar
63
+ survey_answered:
64
+ body: Ya has respondido a esta encuesta.
65
+ title: Encuesta respondida
66
+ survey_closed:
67
+ body: La encuesta está cerrada y no se puede responder.
68
+ title: Encuesta cerrada
69
+ tos_agreement: Al participar en esta encuesta, aceptas sus términos de servicio