decidim-surveys 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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