decidim-surveys 0.15.2 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -9
  3. data/app/assets/stylesheets/decidim/surveys/surveys.scss +2 -2
  4. data/app/commands/decidim/surveys/create_survey.rb +1 -1
  5. data/app/controllers/decidim/surveys/admin/surveys_controller.rb +6 -37
  6. data/app/controllers/decidim/surveys/surveys_controller.rb +8 -22
  7. data/app/jobs/decidim/surveys/settings_change_job.rb +6 -3
  8. data/app/models/decidim/surveys/survey.rb +2 -12
  9. data/app/permissions/decidim/surveys/admin/permissions.rb +1 -1
  10. data/app/permissions/decidim/surveys/permissions.rb +1 -1
  11. data/app/queries/decidim/surveys/metrics/answers_metric_manage.rb +70 -0
  12. data/app/queries/decidim/surveys/metrics/survey_participants_metric_measure.rb +30 -0
  13. data/config/locales/ca.yml +5 -66
  14. data/config/locales/de.yml +5 -66
  15. data/config/locales/en.yml +5 -66
  16. data/config/locales/es-PY.yml +5 -66
  17. data/config/locales/es.yml +5 -66
  18. data/config/locales/eu.yml +5 -66
  19. data/config/locales/fi-pl.yml +5 -66
  20. data/config/locales/fi.yml +5 -66
  21. data/config/locales/fr.yml +5 -66
  22. data/config/locales/gl.yml +5 -66
  23. data/config/locales/hu.yml +5 -66
  24. data/config/locales/id-ID.yml +0 -70
  25. data/config/locales/it.yml +5 -66
  26. data/config/locales/nl.yml +5 -66
  27. data/config/locales/pl.yml +5 -66
  28. data/config/locales/pt-BR.yml +5 -66
  29. data/config/locales/pt.yml +5 -66
  30. data/config/locales/ru.yml +0 -66
  31. data/config/locales/sv.yml +5 -66
  32. data/config/locales/tr-TR.yml +0 -70
  33. data/config/locales/uk.yml +0 -66
  34. data/lib/decidim/surveys.rb +0 -2
  35. data/lib/decidim/surveys/admin_engine.rb +1 -5
  36. data/lib/decidim/surveys/component.rb +18 -15
  37. data/lib/decidim/surveys/engine.rb +17 -4
  38. data/lib/decidim/surveys/test/factories.rb +2 -42
  39. data/lib/decidim/surveys/version.rb +1 -1
  40. data/lib/tasks/decidim_surveys_tasks.rake +92 -0
  41. metadata +28 -42
  42. data/app/assets/config/admin/decidim_surveys_manifest.js +0 -1
  43. data/app/assets/config/decidim_surveys_manifest.js +0 -1
  44. data/app/assets/images/decidim/surveys/icon.svg +0 -19
  45. data/app/assets/javascripts/decidim/surveys/admin/auto_buttons_by_min_items.component.js.es6 +0 -25
  46. data/app/assets/javascripts/decidim/surveys/admin/auto_select_options_by_total_items.component.js.es6 +0 -23
  47. data/app/assets/javascripts/decidim/surveys/admin/surveys.js.es6 +0 -188
  48. data/app/assets/javascripts/decidim/surveys/autosortable_checkboxes.component.js.es6 +0 -65
  49. data/app/assets/javascripts/decidim/surveys/option_attached_inputs.component.js.es6 +0 -32
  50. data/app/assets/javascripts/decidim/surveys/surveys.js.es6 +0 -20
  51. data/app/commands/decidim/surveys/admin/update_survey.rb +0 -86
  52. data/app/commands/decidim/surveys/answer_survey.rb +0 -54
  53. data/app/forms/decidim/surveys/admin/survey_answer_option_form.rb +0 -23
  54. data/app/forms/decidim/surveys/admin/survey_form.rb +0 -27
  55. data/app/forms/decidim/surveys/admin/survey_question_form.rb +0 -35
  56. data/app/forms/decidim/surveys/survey_answer_choice_form.rb +0 -15
  57. data/app/forms/decidim/surveys/survey_answer_form.rb +0 -69
  58. data/app/forms/decidim/surveys/survey_form.rb +0 -22
  59. data/app/helpers/decidim/surveys/admin/application_helper.rb +0 -19
  60. data/app/models/decidim/surveys/survey_answer.rb +0 -45
  61. data/app/models/decidim/surveys/survey_answer_choice.rb +0 -15
  62. data/app/models/decidim/surveys/survey_answer_option.rb +0 -11
  63. data/app/models/decidim/surveys/survey_question.rb +0 -36
  64. data/app/queries/decidim/surveys/survey_user_answers.rb +0 -28
  65. data/app/views/decidim/surveys/admin/surveys/_answer_option.html.erb +0 -44
  66. data/app/views/decidim/surveys/admin/surveys/_form.html.erb +0 -51
  67. data/app/views/decidim/surveys/admin/surveys/_question.html.erb +0 -115
  68. data/app/views/decidim/surveys/admin/surveys/edit.html.erb +0 -7
  69. data/app/views/decidim/surveys/surveys/_answer.html.erb +0 -94
  70. data/app/views/decidim/surveys/surveys/show.html.erb +0 -84
  71. data/lib/decidim/surveys/data_portability_survey_user_answers_serializer.rb +0 -37
  72. data/lib/decidim/surveys/survey_user_answers_serializer.rb +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 456abaa3819f7e7dad7766b90392d85931776ebe67110e7f6ee958f34acc9f9a
4
- data.tar.gz: 2482df90ea48a9423a29f29113daa19be48612de0e235e1043979b0b151d9c6a
3
+ metadata.gz: 802d9b890c4116757f30979e77e8f963b9509b52fa63fd75c39e0000fa5132b9
4
+ data.tar.gz: 9226d46d3ef0ec8179464f0b6a5bf7614ebefcd8943820dfe882f14762c88de8
5
5
  SHA512:
6
- metadata.gz: d038df597b9a3abc085a540326a576e450f7d63aabb8c42b473e5f8907777f04d0ba8d1adae251304c59bbe9a2506ee5f0287a96c525d7717c645b407bd0c3a0
7
- data.tar.gz: 1c6df4394f9ec9f30da2ec705a5a8c8183a5dcbc1e8f23dd22ff56997936b778703f87809dbb227192ce51e80971b57f3fe25f83a34dff1a76f48b6aa800e216
6
+ metadata.gz: a779af11e0c17451457aa074ea390a5e53ea2662acbf5564c8691581712659ead5f99ff9a81f745fe188bf63164a768a77d52963bafe9cd1f1b29aee0f46bdde
7
+ data.tar.gz: b818cdf9d3359489f10df016707eaf9859d283f67cec4b2449e1fb8a680110ffafeae9476a2ce392f7650de976fd7ab0381bb270fc35ad42e322d70a77c7df06
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # Decidim::Surveys
2
2
 
3
- The Surveys module adds one of the main components of Decidim: allows admins to contribute to a participatory process by creating surveys. Users can participate in the surveys answering their questions from the public page.
3
+ The Surveys module adds one new component to Decidim: defining and answering surveys.
4
+
5
+ The main features are:
6
+
7
+ * Admins can define a Survey.
8
+ * Users can participate on these surveys by answering from the public page.
9
+ * Admins can download the answers by CSV.
4
10
 
5
11
  ## Usage
6
12
 
@@ -8,17 +14,17 @@ Surveys will be available as a Component for a Participatory Process.
8
14
 
9
15
  ## Installation
10
16
 
11
- Add this line to your application's Gemfile:
17
+ This is on the default Decidim installation so you shouldn't change anything to use this component.
18
+
19
+ ## Screenshots
20
+
21
+ ![Add survey](docs/screenshot01.png)
12
22
 
13
- ```ruby
14
- gem 'decidim-surveys'
15
- ```
23
+ ![Use survey](docs/screenshot02.png)
16
24
 
17
- And then execute:
25
+ ## Documentation
18
26
 
19
- ```bash
20
- bundle
21
- ```
27
+ Read more about this component on [Admin Manual](https://docs.decidim.org/admin-manual/en/processess/#surveys).
22
28
 
23
29
  ## Contributing
24
30
 
@@ -1,4 +1,4 @@
1
- form.answer-survey{
1
+ form.answer-questionnaire{
2
2
  .radio-button-collection,
3
3
  .check-box-collection,
4
4
  .sortable-check-box-collection{
@@ -13,7 +13,7 @@ form.answer-survey{
13
13
  }
14
14
  }
15
15
 
16
- label.survey-question{
16
+ label.questionnaire-question{
17
17
  font-weight: bold;
18
18
  }
19
19
 
@@ -10,7 +10,7 @@ module Decidim
10
10
  end
11
11
 
12
12
  def call
13
- @survey = Survey.new(component: @component)
13
+ @survey = Survey.new(component: @component, questionnaire: Decidim::Forms::Questionnaire.new)
14
14
 
15
15
  @survey.save ? broadcast(:ok) : broadcast(:invalid)
16
16
  end
@@ -5,52 +5,21 @@ module Decidim
5
5
  module Admin
6
6
  # This controller allows the user to update a Page.
7
7
  class SurveysController < Admin::ApplicationController
8
- helper_method :survey, :blank_question, :blank_answer_option, :question_types
8
+ include Decidim::Forms::Admin::Concerns::HasQuestionnaire
9
9
 
10
- def edit
11
- enforce_permission_to :update, :survey, survey: survey
12
-
13
- @form = form(Admin::SurveyForm).from_model(survey)
10
+ def questionnaire_for
11
+ survey
14
12
  end
15
13
 
16
- def update
17
- enforce_permission_to :update, :survey, survey: survey
18
-
19
- params["published_at"] = Time.current if params.has_key? "save_and_publish"
20
- @form = form(Admin::SurveyForm).from_params(params)
21
-
22
- Admin::UpdateSurvey.call(@form, survey) do
23
- on(:ok) do
24
- flash[:notice] = I18n.t("surveys.update.success", scope: "decidim.surveys.admin")
25
- redirect_to parent_path
26
- end
14
+ private
27
15
 
28
- on(:invalid) do
29
- flash.now[:alert] = I18n.t("surveys.update.invalid", scope: "decidim.surveys.admin")
30
- render action: "edit"
31
- end
32
- end
16
+ def i18n_flashes_scope
17
+ "decidim.surveys.admin.surveys"
33
18
  end
34
19
 
35
- private
36
-
37
20
  def survey
38
21
  @survey ||= Survey.find_by(component: current_component)
39
22
  end
40
-
41
- def blank_question
42
- @blank_question ||= Admin::SurveyQuestionForm.new
43
- end
44
-
45
- def blank_answer_option
46
- @blank_answer_option ||= Admin::SurveyAnswerOptionForm.new
47
- end
48
-
49
- def question_types
50
- @question_types ||= SurveyQuestion::TYPES.map do |question_type|
51
- [question_type, I18n.t("decidim.surveys.question_types.#{question_type}")]
52
- end
53
- end
54
23
  end
55
24
  end
56
25
  end
@@ -4,36 +4,22 @@ module Decidim
4
4
  module Surveys
5
5
  # Exposes the survey resource so users can view and answer them.
6
6
  class SurveysController < Decidim::Surveys::ApplicationController
7
- include FormFactory
7
+ include Decidim::Forms::Concerns::HasQuestionnaire
8
8
 
9
- helper_method :survey
9
+ delegate :allow_answers?, to: :current_settings
10
10
 
11
- def show
12
- @form = form(SurveyForm).from_model(survey)
11
+ def questionnaire_for
12
+ survey
13
13
  end
14
14
 
15
- def answer
16
- enforce_permission_to :answer, :survey
17
-
18
- @form = form(SurveyForm).from_params(params)
19
-
20
- AnswerSurvey.call(@form, current_user, survey) do
21
- on(:ok) do
22
- flash[:notice] = I18n.t("surveys.answer.success", scope: "decidim.surveys")
23
- redirect_to survey_path(survey)
24
- end
15
+ private
25
16
 
26
- on(:invalid) do
27
- flash.now[:alert] = I18n.t("surveys.answer.invalid", scope: "decidim.surveys")
28
- render action: "show"
29
- end
30
- end
17
+ def i18n_flashes_scope
18
+ "decidim.surveys.surveys"
31
19
  end
32
20
 
33
- private
34
-
35
21
  def survey
36
- @survey ||= Survey.includes(questions: :answer_options).find_by(component: current_component)
22
+ @survey ||= Survey.find_by(component: current_component)
37
23
  end
38
24
  end
39
25
  end
@@ -16,11 +16,12 @@ module Decidim
16
16
  event_class = Decidim::Surveys::ClosedSurveyEvent
17
17
  end
18
18
 
19
+ return unless event && event_class
19
20
  Decidim::EventsManager.publish(
20
21
  event: event,
21
22
  event_class: event_class,
22
23
  resource: component,
23
- recipient_ids: component.participatory_space.followers.pluck(:id)
24
+ followers: component.participatory_space.followers
24
25
  )
25
26
  end
26
27
 
@@ -30,15 +31,17 @@ module Decidim
30
31
  current_settings[:allow_answers] == previous_settings[:allow_answers]
31
32
  end
32
33
 
34
+ # rubocop:disable Style/DoubleNegation
33
35
  def survey_opened?(previous_settings, current_settings)
34
36
  current_settings[:allow_answers] == true &&
35
- previous_settings[:allow_answers] == false
37
+ !!previous_settings[:allow_answers] == false
36
38
  end
37
39
 
38
40
  def survey_closed?(previous_settings, current_settings)
39
- current_settings[:allow_answers] == false &&
41
+ !!current_settings[:allow_answers] == false &&
40
42
  previous_settings[:allow_answers] == true
41
43
  end
44
+ # rubocop:enable Style/DoubleNegation
42
45
  end
43
46
  end
44
47
  end
@@ -4,22 +4,12 @@ module Decidim
4
4
  module Surveys
5
5
  # The data store for a Survey in the Decidim::Surveys component.
6
6
  class Survey < Surveys::ApplicationRecord
7
+ include Decidim::Forms::HasQuestionnaire
7
8
  include Decidim::HasComponent
8
9
 
9
10
  component_manifest_name "surveys"
10
11
 
11
- has_many :questions, -> { order(:position) }, class_name: "SurveyQuestion", foreign_key: "decidim_survey_id", dependent: :destroy
12
- has_many :answers, class_name: "SurveyAnswer", foreign_key: "decidim_survey_id", dependent: :destroy
13
-
14
- # Public: returns whether the survey questions can be modified or not.
15
- def questions_editable?
16
- answers.empty?
17
- end
18
-
19
- # Public: returns whether the survey is answered by the user or not.
20
- def answered_by?(user)
21
- answers.where(user: user).count == questions.length
22
- end
12
+ validates :questionnaire, presence: true
23
13
  end
24
14
  end
25
15
  end
@@ -9,7 +9,7 @@ module Decidim
9
9
 
10
10
  return permission_action if permission_action.scope != :admin
11
11
 
12
- return permission_action if permission_action.subject != :survey
12
+ return permission_action if permission_action.subject != :questionnaire
13
13
 
14
14
  case permission_action.action
15
15
  when :export_answers, :update
@@ -9,7 +9,7 @@ module Decidim
9
9
  return Decidim::Surveys::Admin::Permissions.new(user, permission_action, context).permissions if permission_action.scope == :admin
10
10
  return permission_action if permission_action.scope != :public
11
11
 
12
- return permission_action if permission_action.subject != :survey
12
+ return permission_action if permission_action.subject != :questionnaire
13
13
 
14
14
  permission_action.allow! if permission_action.action == :answer
15
15
 
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Surveys
5
+ module Metrics
6
+ class AnswersMetricManage < Decidim::MetricManage
7
+ def metric_name
8
+ "survey_answers"
9
+ end
10
+
11
+ def save
12
+ return @registry if @registry
13
+
14
+ @registry = []
15
+ query.each do |key, results|
16
+ cumulative_value = results[:cumulative]
17
+ next if cumulative_value.zero?
18
+ quantity_value = results[:quantity] || 0
19
+ space_type, space_id, survey_id = key
20
+ record = Decidim::Metric.find_or_initialize_by(day: @day.to_s, metric_type: @metric_name,
21
+ organization: @organization, decidim_category_id: nil,
22
+ participatory_space_type: space_type, participatory_space_id: space_id,
23
+ related_object_type: Decidim::Surveys::Survey.name, related_object_id: survey_id)
24
+ record.assign_attributes(cumulative: cumulative_value, quantity: quantity_value)
25
+ @registry << record
26
+ end
27
+ @registry.each(&:save!)
28
+ @registry
29
+ end
30
+
31
+ private
32
+
33
+ def query
34
+ return @query if @query
35
+
36
+ @query = retrieve_surveys.each_with_object({}) do |survey, grouped_answers|
37
+ answers = Decidim::Forms::Answer.joins(:questionnaire)
38
+ .where(questionnaire: retrieve_questionnaires(survey))
39
+ .where("decidim_forms_answers.created_at <= ?", end_time)
40
+ next grouped_answers unless answers
41
+
42
+ group_key = generate_group_key(survey)
43
+ grouped_answers[group_key] ||= { cumulative: 0, quantity: 0 }
44
+ grouped_answers[group_key][:cumulative] += answers.count
45
+ grouped_answers[group_key][:quantity] += answers.where("decidim_forms_answers.created_at >= ?", start_time).count
46
+ end
47
+ @query
48
+ end
49
+
50
+ def retrieve_surveys
51
+ components = Decidim::Component.where(participatory_space: retrieve_participatory_spaces).published
52
+ Decidim::Surveys::Survey.where(component: components)
53
+ end
54
+
55
+ def retrieve_questionnaires(survey)
56
+ Decidim::Forms::Questionnaire.includes(:questionnaire_for)
57
+ .where(questionnaire_for: survey)
58
+ end
59
+
60
+ def generate_group_key(survey)
61
+ participatory_space = survey.participatory_space
62
+ group_key = []
63
+ group_key += [participatory_space.class.name, participatory_space.id]
64
+ group_key += [survey.id]
65
+ group_key
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Surveys
5
+ module Metrics
6
+ # Searches for Participants in the following actions
7
+ # - Answer a survey (Surveys)
8
+ class SurveyParticipantsMetricMeasure < Decidim::MetricMeasure
9
+ def valid?
10
+ super && @resource.is_a?(Decidim::Component)
11
+ end
12
+
13
+ def calculate
14
+ surveys = Decidim::Surveys::Survey.joins(:component, :questionnaire).where(component: @resource)
15
+ questionnaires = Decidim::Forms::Questionnaire.includes(:questionnaire_for)
16
+ .where(questionnaire_for_type: Decidim::Surveys::Survey.name, questionnaire_for_id: surveys.pluck(:id))
17
+
18
+ answers = Decidim::Forms::Answer.joins(:questionnaire)
19
+ .where(questionnaire: questionnaires)
20
+ .where("decidim_forms_answers.created_at <= ?", end_time)
21
+
22
+ {
23
+ cumulative_users: answers.pluck(:decidim_user_id).uniq,
24
+ quantity_users: answers.where("decidim_forms_answers.created_at >= ?", start_time).pluck(:decidim_user_id).uniq
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,19 +1,5 @@
1
1
  ca:
2
2
  activemodel:
3
- attributes:
4
- survey_answer:
5
- body: Resposta
6
- survey_question:
7
- mandatory: Obligatori
8
- max_choices: Nombre màxim d'opcions
9
- question_type: Tipus
10
- errors:
11
- models:
12
- survey_answer:
13
- attributes:
14
- choices:
15
- missing: no estan complets
16
- too_many: són massa
17
3
  models:
18
4
  decidim/surveys/closed_survey_event: S'ha acabat l'enquesta
19
5
  decidim/surveys/opened_survey_event: S'ha iniciat l'enquesta
@@ -49,69 +35,22 @@ ca:
49
35
  email_outro: Has rebut aquesta notificació perquè estàs seguint %{participatory_space_title}. Pots deixar de rebre notificacions seguint l'enllaç anterior.
50
36
  email_subject: Una nova enquesta a %{participatory_space_title}
51
37
  notification_title: L'enquesta <a href="%{resource_path}">%{resource_title}</a> en <a href="%{participatory_space_url}">%{participatory_space_title}</a> ja està oberta.
52
- forms:
53
- errors:
54
- survey_answer:
55
- body: El cos no pot estar en blanc
38
+ metrics:
39
+ survey_answers:
40
+ description: Nombre d'enquestes contestades pels usuaris
41
+ object: respostes a enquestes
42
+ title: Respostes a enquestes
56
43
  surveys:
57
44
  admin:
58
45
  exports:
59
46
  survey_user_answers: Respostes dels usuaris
60
- models:
61
- components:
62
- description: Descripció
63
- tos: Termes del servei
64
47
  surveys:
65
- answer_option:
66
- answer_option: Opció de resposta
67
- free_text: Text lliure
68
- remove: Eliminar
69
- statement: Enunciat
70
- edit:
71
- save: Desar
72
- title: Títol
73
- form:
74
- add_question: Afegir pregunta
75
- already_answered_warning: L'enquesta ja està contestada per alguns usuaris i per tant no pots modificar les seves preguntes.
76
- question:
77
- add_answer_option: Afegir opció de resposta
78
- any: Qualsevol
79
- description: Descripció
80
- down: Avall
81
- question: Pregunta
82
- remove: Elimina
83
- statement: Enunciat
84
- up: Pujar
85
48
  update:
86
49
  invalid: Hi ha hagut errors en desar l'enquesta.
87
50
  success: Enquesta desada correctament.
88
51
  last_activity:
89
52
  new_survey_at_html: "<span>Nova enquesta a %{link}</span>"
90
- question_types:
91
- long_answer: Resposta llarga
92
- multiple_option: Opció múltiple
93
- short_answer: Resposta curta
94
- single_option: Única opció
95
- sorting: Ordenació
96
53
  surveys:
97
54
  answer:
98
55
  invalid: Hi ha hagut errors en respondre a l'enquesta.
99
56
  success: Enquesta resposta correctament.
100
- question:
101
- max_choices: 'Opcions màximes: %{n}'
102
- show:
103
- answer_survey:
104
- 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.
105
- title: Respon a l'enquesta
106
- are_you_sure: Aquesta acció no es pot desfer i no podràs editar les respostes. Segur que vols seguir?
107
- submit: Enviar
108
- survey_answered:
109
- body: Ja ha respost a aquesta enquesta.
110
- title: Enquesta resposta
111
- survey_closed:
112
- body: L'enquesta està tancada i no s'hi pot participar.
113
- title: Enquesta tancada
114
- survey_for_private_users:
115
- body: L'enquesta només està disponible per a usuaris privats
116
- title: Enquesta tancada
117
- tos_agreement: En participar en aquesta enquesta acceptes els Termes de Servei