decidim-surveys 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/surveys/survey_card_metadata_cell.rb +43 -0
- data/app/cells/decidim/surveys/survey_cell.rb +26 -0
- data/app/cells/decidim/surveys/survey_l_cell.rb +34 -0
- data/app/cells/decidim/surveys/survey_s_cell.rb +21 -0
- data/app/commands/decidim/surveys/admin/create_survey.rb +21 -0
- data/app/commands/decidim/surveys/admin/publish_survey.rb +58 -0
- data/app/commands/decidim/surveys/admin/unpublish_survey.rb +44 -0
- data/app/commands/decidim/surveys/admin/update_survey.rb +62 -0
- data/app/commands/decidim/surveys/publish_answers.rb +55 -0
- data/app/commands/decidim/surveys/unpublish_answers.rb +55 -0
- data/app/controllers/concerns/decidim/surveys/admin/filterable.rb +23 -0
- data/app/controllers/decidim/surveys/admin/answers_controller.rb +73 -0
- data/app/controllers/decidim/surveys/admin/publish_answers_controller.rb +66 -0
- data/app/controllers/decidim/surveys/admin/surveys_controller.rb +99 -11
- data/app/controllers/decidim/surveys/surveys_controller.rb +50 -5
- data/app/forms/decidim/surveys/admin/survey_form.rb +18 -0
- data/app/helpers/decidim/surveys/application_helper.rb +34 -0
- data/app/helpers/decidim/surveys/publish_answers_helper.rb +104 -0
- data/app/helpers/decidim/surveys/survey_helper.rb +4 -0
- data/app/models/decidim/surveys/survey.rb +67 -12
- data/app/permissions/decidim/surveys/admin/permissions.rb +10 -3
- data/app/permissions/decidim/surveys/permissions.rb +0 -2
- data/app/presenters/decidim/surveys/admin_log/survey_presenter.rb +34 -0
- data/app/queries/decidim/surveys/metrics/answers_metric_manage.rb +3 -3
- data/app/queries/decidim/surveys/metrics/survey_participants_metric_measure.rb +2 -2
- data/app/views/decidim/surveys/admin/answers/index.html.erb +49 -0
- data/app/views/decidim/surveys/admin/answers/show.html.erb +43 -0
- data/app/views/decidim/surveys/admin/publish_answers/_toggle_button.html.erb +22 -0
- data/app/views/decidim/surveys/admin/publish_answers/index.html.erb +44 -0
- data/app/views/decidim/surveys/admin/surveys/_form.html.erb +28 -0
- data/app/views/decidim/surveys/admin/surveys/edit.html.erb +4 -21
- data/app/views/decidim/surveys/admin/surveys/edit_questions.html.erb +47 -0
- data/app/views/decidim/surveys/admin/surveys/index.html.erb +51 -0
- data/app/views/decidim/surveys/surveys/_published_questions_answers.html.erb +13 -0
- data/app/views/decidim/surveys/surveys/_surveys.html.erb +13 -0
- data/app/views/decidim/surveys/surveys/index.html.erb +27 -0
- data/app/views/decidim/surveys/surveys/index.js.erb +4 -0
- data/app/views/decidim/surveys/surveys/not_allowed.html.erb +22 -0
- data/config/locales/ar.yml +4 -3
- data/config/locales/bg.yml +0 -14
- data/config/locales/ca.yml +83 -14
- data/config/locales/cs.yml +87 -14
- data/config/locales/de.yml +84 -15
- data/config/locales/el.yml +0 -11
- data/config/locales/en.yml +83 -14
- data/config/locales/es-MX.yml +83 -14
- data/config/locales/es-PY.yml +83 -14
- data/config/locales/es.yml +83 -14
- data/config/locales/eu.yml +83 -14
- data/config/locales/fi-plain.yml +83 -14
- data/config/locales/fi.yml +83 -14
- data/config/locales/fr-CA.yml +74 -14
- data/config/locales/fr.yml +74 -14
- data/config/locales/ga-IE.yml +0 -4
- data/config/locales/gl.yml +0 -10
- data/config/locales/hu.yml +0 -3
- data/config/locales/id-ID.yml +0 -2
- data/config/locales/is-IS.yml +0 -2
- data/config/locales/it.yml +3 -14
- data/config/locales/ja.yml +86 -19
- data/config/locales/lb.yml +0 -10
- data/config/locales/lt.yml +0 -11
- data/config/locales/lv.yml +0 -3
- data/config/locales/nl.yml +0 -10
- data/config/locales/no.yml +0 -10
- data/config/locales/pl.yml +0 -14
- data/config/locales/pt-BR.yml +0 -14
- data/config/locales/pt.yml +0 -10
- data/config/locales/ro-RO.yml +0 -11
- data/config/locales/ru.yml +0 -2
- data/config/locales/sk.yml +0 -3
- data/config/locales/sv.yml +0 -14
- data/config/locales/tr-TR.yml +0 -16
- data/config/locales/uk.yml +0 -2
- data/config/locales/zh-CN.yml +0 -6
- data/config/locales/zh-TW.yml +0 -11
- data/db/migrate/20240828103030_add_deleted_at_to_decidim_surveys_surveys.rb +8 -0
- data/db/migrate/20240925124312_add_settings_to_decidim_surveys_surveys.rb +42 -0
- data/db/migrate/20250115193836_add_allow_survey_editing.rb +7 -0
- data/decidim-surveys.gemspec +1 -1
- data/lib/decidim/api/survey_type.rb +2 -2
- data/lib/decidim/api/surveys_type.rb +4 -5
- data/lib/decidim/surveys/admin_engine.rb +15 -5
- data/lib/decidim/surveys/component.rb +7 -24
- data/lib/decidim/surveys/engine.rb +2 -2
- data/lib/decidim/surveys/seeds.rb +115 -10
- data/lib/decidim/surveys/test/factories.rb +24 -0
- data/lib/decidim/surveys/version.rb +1 -1
- metadata +48 -19
- data/app/commands/decidim/surveys/create_survey.rb +0 -19
- data/app/views/decidim/surveys/admin/component/_actions.html.erb +0 -44
- data/config/locales/ca-IT.yml +0 -77
data/config/locales/pt-BR.yml
CHANGED
|
@@ -17,21 +17,10 @@ pt-BR:
|
|
|
17
17
|
surveys:
|
|
18
18
|
actions:
|
|
19
19
|
answer: Responda
|
|
20
|
-
name: Pesquisa
|
|
21
20
|
settings:
|
|
22
21
|
global:
|
|
23
22
|
announcement: Anúncio
|
|
24
|
-
clean_after_publish: Excluir respostas ao publicar a pesquisa
|
|
25
|
-
ends_at: Respostas aceitas até
|
|
26
|
-
ends_at_help: Deixe em branco para nenhuma data específica
|
|
27
|
-
scope_id: Escopo
|
|
28
|
-
scopes_enabled: Escopos habilitados
|
|
29
|
-
starts_at: Respostas aceitas de
|
|
30
|
-
starts_at_help: Deixe em branco para nenhuma data específica
|
|
31
23
|
step:
|
|
32
|
-
allow_answers: Permitir respostas
|
|
33
|
-
allow_unregistered: Permitir que usuários não registrados respondam à pesquisa
|
|
34
|
-
allow_unregistered_help: Se ativo, nenhum login será necessário para responder a pesquisa. Isso pode levar a dados ruins ou não confiáveis e será mais vulnerável a ataques automatizados. Usar com cuidado! Lembre-se de que um usuário pode responder à mesma pesquisa várias vezes, usando navegadores diferentes ou a função "navegação privada" de seu navegador.
|
|
35
24
|
announcement: Anúncio
|
|
36
25
|
events:
|
|
37
26
|
surveys:
|
|
@@ -54,9 +43,6 @@ pt-BR:
|
|
|
54
43
|
answers_count: Respostas
|
|
55
44
|
surveys:
|
|
56
45
|
admin:
|
|
57
|
-
component:
|
|
58
|
-
actions:
|
|
59
|
-
answers_alert: Se você publicar o componente, todos os resultados serão removidos.
|
|
60
46
|
exports:
|
|
61
47
|
survey_user_answers: Avalie as respostas dos usuários
|
|
62
48
|
surveys:
|
data/config/locales/pt.yml
CHANGED
|
@@ -17,20 +17,10 @@ pt:
|
|
|
17
17
|
surveys:
|
|
18
18
|
actions:
|
|
19
19
|
answer: Responder
|
|
20
|
-
name: Inquérito
|
|
21
20
|
settings:
|
|
22
21
|
global:
|
|
23
22
|
announcement: Anúncio
|
|
24
|
-
clean_after_publish: Eliminar respostas ao publicar o inquérito
|
|
25
|
-
ends_at: Respostas aceites até
|
|
26
|
-
ends_at_help: Deixar em branco se sem data específica
|
|
27
|
-
scope_id: Âmbito
|
|
28
|
-
scopes_enabled: Âmbitos activados
|
|
29
|
-
starts_at: Respostas aceites a partir de
|
|
30
|
-
starts_at_help: Deixar em branco se sem data específica
|
|
31
23
|
step:
|
|
32
|
-
allow_answers: Permitir respostas
|
|
33
|
-
allow_unregistered: Permitir que utilizadores não registados respondam ao inquérito
|
|
34
24
|
announcement: Anúncio
|
|
35
25
|
events:
|
|
36
26
|
surveys:
|
data/config/locales/ro-RO.yml
CHANGED
|
@@ -19,21 +19,10 @@ ro:
|
|
|
19
19
|
surveys:
|
|
20
20
|
actions:
|
|
21
21
|
answer: Răspunde
|
|
22
|
-
name: Sondaj
|
|
23
22
|
settings:
|
|
24
23
|
global:
|
|
25
24
|
announcement: Anunţ
|
|
26
|
-
clean_after_publish: Șterge răspunsurile odată cu publicarea sondajului
|
|
27
|
-
ends_at: Răspunsuri sunt acceptate până la
|
|
28
|
-
ends_at_help: Lasă necompletat pentru nicio dată specifică
|
|
29
|
-
scope_id: Domeniu de interes
|
|
30
|
-
scopes_enabled: Domenii activate
|
|
31
|
-
starts_at: Răspunsuri acceptate de la
|
|
32
|
-
starts_at_help: Lasă necompletat pentru nicio dată specifică
|
|
33
25
|
step:
|
|
34
|
-
allow_answers: Permite răspunsuri
|
|
35
|
-
allow_unregistered: Permite utilizatorilor neînregistrați să răspundă la sondaj
|
|
36
|
-
allow_unregistered_help: Dacă este activ, nu va fi necesară nicio autentificare pentru a răspunde la chestionar. Acest lucru poate duce la date slabe sau nefiabile și va fi mai vulnerabil la atacuri automate. Utilizați cu prudență! Rețineți că un participant poate răspunde aceluiași sondaj de mai multe ori, utilizând diferite browsere sau funcția de "navigare privată" a browser-ului său web.
|
|
37
26
|
announcement: Anunţ
|
|
38
27
|
events:
|
|
39
28
|
surveys:
|
data/config/locales/ru.yml
CHANGED
data/config/locales/sk.yml
CHANGED
|
@@ -21,13 +21,10 @@ sk:
|
|
|
21
21
|
surveys:
|
|
22
22
|
actions:
|
|
23
23
|
answer: Odpovedať
|
|
24
|
-
name: Prieskum
|
|
25
24
|
settings:
|
|
26
25
|
global:
|
|
27
26
|
announcement: Oznámenie
|
|
28
27
|
step:
|
|
29
|
-
allow_answers: Povoliť odpovede
|
|
30
|
-
allow_unregistered: Povoliť neregistrovaným užívateľom odpovedať na prieskum
|
|
31
28
|
announcement: Oznámenie
|
|
32
29
|
events:
|
|
33
30
|
surveys:
|
data/config/locales/sv.yml
CHANGED
|
@@ -17,21 +17,10 @@ sv:
|
|
|
17
17
|
surveys:
|
|
18
18
|
actions:
|
|
19
19
|
answer: Svar
|
|
20
|
-
name: Enkät
|
|
21
20
|
settings:
|
|
22
21
|
global:
|
|
23
22
|
announcement: Meddelande
|
|
24
|
-
clean_after_publish: Ta bort svar vid publicering av enkäten
|
|
25
|
-
ends_at: Öppet för svar till
|
|
26
|
-
ends_at_help: Lämna tomt för att inte ha något slutdatum
|
|
27
|
-
scope_id: Indelning
|
|
28
|
-
scopes_enabled: Aktivera indelningar
|
|
29
|
-
starts_at: Öppet för svar från
|
|
30
|
-
starts_at_help: Lämna tomt för att inte ha något startdatum
|
|
31
23
|
step:
|
|
32
|
-
allow_answers: Tillåt svar
|
|
33
|
-
allow_unregistered: Tillåt ej registrerade användare att besvara enkäten
|
|
34
|
-
allow_unregistered_help: Om aktiv kommer ingen inloggning att krävas för att besvara enkäten. Detta kan leda till dålig eller opålitlig data och det kommer att vara mer sårbart för automatiserade attacker. Använd med försiktighet! Tänk på att en deltagare kunde svara på samma enkät flera gånger, genom att använda olika webbläsare eller "privat surfning" i sin webbläsare.
|
|
35
24
|
announcement: Meddelande
|
|
36
25
|
events:
|
|
37
26
|
surveys:
|
|
@@ -54,9 +43,6 @@ sv:
|
|
|
54
43
|
answers_count: Svar
|
|
55
44
|
surveys:
|
|
56
45
|
admin:
|
|
57
|
-
component:
|
|
58
|
-
actions:
|
|
59
|
-
answers_alert: Om du publicerar komponenten kommer alla resultat att tas bort.
|
|
60
46
|
exports:
|
|
61
47
|
survey_user_answers: Svar från enkätdeltagarna
|
|
62
48
|
surveys:
|
data/config/locales/tr-TR.yml
CHANGED
|
@@ -17,20 +17,10 @@ tr:
|
|
|
17
17
|
surveys:
|
|
18
18
|
actions:
|
|
19
19
|
answer: Cevap
|
|
20
|
-
name: Anket
|
|
21
20
|
settings:
|
|
22
21
|
global:
|
|
23
22
|
announcement: Duyuru
|
|
24
|
-
clean_after_publish: Anketi yayınlarken cevapları sil
|
|
25
|
-
ends_at: Şu tarihe kadar kabul edilen cevaplar
|
|
26
|
-
ends_at_help: Belirli bir tarih için boş bırakın
|
|
27
|
-
scope_id: Kapsam
|
|
28
|
-
scopes_enabled: Kapsamlar etkinleştirildi
|
|
29
|
-
starts_at: Cevaplar kabul edildi
|
|
30
|
-
starts_at_help: Belirli bir tarih için boş bırakın
|
|
31
23
|
step:
|
|
32
|
-
allow_answers: Cevaplara izin ver
|
|
33
|
-
allow_unregistered: Kayıtlı olmayan kullanıcıların anketi yanıtlamasına izin verin
|
|
34
24
|
announcement: Duyuru
|
|
35
25
|
events:
|
|
36
26
|
surveys:
|
|
@@ -57,13 +47,7 @@ tr:
|
|
|
57
47
|
update:
|
|
58
48
|
invalid: Anketi kaydederken bir sorun oluştu.
|
|
59
49
|
success: Anket başarıyla kaydedildi.
|
|
60
|
-
survey_confirmation_mailer:
|
|
61
|
-
confirmation:
|
|
62
|
-
body: '%{participatory_space} alanındaki %{questionnaire_title} anketini başarıyla cevapladınız'
|
|
63
|
-
subject:
|
|
64
|
-
export_name: Anket cevapları
|
|
65
50
|
surveys:
|
|
66
51
|
answer:
|
|
67
52
|
invalid: Anketi cevaplarken bir sorun oluştu.
|
|
68
|
-
spam_detected: Formu yanıtlarken bir sorun oluştu. Belki çok hızlı davranmış olabilirsiniz, tekrar deneyebilir misiniz?
|
|
69
53
|
success: Anket başarıyla cevaplandı.
|
data/config/locales/uk.yml
CHANGED
data/config/locales/zh-CN.yml
CHANGED
|
@@ -15,16 +15,10 @@ zh-CN:
|
|
|
15
15
|
surveys:
|
|
16
16
|
actions:
|
|
17
17
|
answer: 答案
|
|
18
|
-
name: 调查
|
|
19
18
|
settings:
|
|
20
19
|
global:
|
|
21
20
|
announcement: 通 知
|
|
22
|
-
clean_after_publish: 在发布调查时删除答案
|
|
23
|
-
scope_id: 范围
|
|
24
|
-
scopes_enabled: 范围已启用
|
|
25
21
|
step:
|
|
26
|
-
allow_answers: 允许答案
|
|
27
|
-
allow_unregistered: 允许未注册用户回答调查
|
|
28
22
|
announcement: 通 知
|
|
29
23
|
events:
|
|
30
24
|
surveys:
|
data/config/locales/zh-TW.yml
CHANGED
|
@@ -15,21 +15,10 @@ zh-TW:
|
|
|
15
15
|
surveys:
|
|
16
16
|
actions:
|
|
17
17
|
answer: 回答
|
|
18
|
-
name: 調查
|
|
19
18
|
settings:
|
|
20
19
|
global:
|
|
21
20
|
announcement: 公告
|
|
22
|
-
clean_after_publish: 當發佈調查問卷時刪除回答
|
|
23
|
-
ends_at: 接受回答直到
|
|
24
|
-
ends_at_help: 不指定日期則留空
|
|
25
|
-
scope_id: 範圍
|
|
26
|
-
scopes_enabled: 啟用的範圍
|
|
27
|
-
starts_at: 回答接受開始日期
|
|
28
|
-
starts_at_help: 不指定日期請留空
|
|
29
21
|
step:
|
|
30
|
-
allow_answers: 允許回答
|
|
31
|
-
allow_unregistered: 允許未註冊的使用者回答問卷
|
|
32
|
-
allow_unregistered_help: 若啟用此功能,回答問卷時將無需登錄。這可能導致資料品質不佳或不可靠,並增加遭受自動攻擊的風險。請謹慎使用!請注意,參與者可以使用不同的瀏覽器或「私人瀏覽」功能多次回答同一份問卷。
|
|
33
22
|
announcement: 公告
|
|
34
23
|
events:
|
|
35
24
|
surveys:
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class AddSettingsToDecidimSurveysSurveys < ActiveRecord::Migration[7.0]
|
|
4
|
+
class Survey < ApplicationRecord
|
|
5
|
+
include Decidim::HasComponent
|
|
6
|
+
|
|
7
|
+
self.table_name = :decidim_surveys_surveys
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def change
|
|
11
|
+
reversible do |dir|
|
|
12
|
+
dir.up do
|
|
13
|
+
add_column :decidim_surveys_surveys, :starts_at, :datetime
|
|
14
|
+
add_column :decidim_surveys_surveys, :ends_at, :datetime
|
|
15
|
+
add_column :decidim_surveys_surveys, :announcement, :jsonb
|
|
16
|
+
add_column :decidim_surveys_surveys, :allow_answers, :boolean
|
|
17
|
+
add_column :decidim_surveys_surveys, :allow_unregistered, :boolean
|
|
18
|
+
add_column :decidim_surveys_surveys, :clean_after_publish, :boolean
|
|
19
|
+
add_column :decidim_surveys_surveys, :published_at, :datetime
|
|
20
|
+
add_index :decidim_surveys_surveys, :published_at
|
|
21
|
+
|
|
22
|
+
Survey.where(published_at: nil).find_each do |survey|
|
|
23
|
+
published_at = survey.component&.published_at
|
|
24
|
+
next if published_at.nil?
|
|
25
|
+
|
|
26
|
+
survey.update(published_at:)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
dir.down do
|
|
31
|
+
remove_index :decidim_surveys_surveys, :published_at
|
|
32
|
+
remove_column :decidim_surveys_surveys, :starts_at
|
|
33
|
+
remove_column :decidim_surveys_surveys, :ends_at
|
|
34
|
+
remove_column :decidim_surveys_surveys, :announcement
|
|
35
|
+
remove_column :decidim_surveys_surveys, :allow_answers
|
|
36
|
+
remove_column :decidim_surveys_surveys, :allow_unregistered
|
|
37
|
+
remove_column :decidim_surveys_surveys, :clean_after_publish
|
|
38
|
+
remove_column :decidim_surveys_surveys, :published_at
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/decidim-surveys.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-surveys"
|
|
25
25
|
s.summary = "Decidim surveys module"
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
module Decidim
|
|
4
4
|
module Surveys
|
|
5
5
|
class SurveyType < Decidim::Api::Types::BaseObject
|
|
6
|
+
implements Decidim::Core::TimestampsInterface
|
|
7
|
+
|
|
6
8
|
description "A survey"
|
|
7
9
|
|
|
8
10
|
field :id, GraphQL::Types::ID, "The internal ID for this survey", null: false
|
|
9
|
-
field :created_at, Decidim::Core::DateTimeType, "The time this survey was created", null: true
|
|
10
|
-
field :updated_at, Decidim::Core::DateTimeType, "The time this survey was updated", null: true
|
|
11
11
|
field :questionnaire, Decidim::Forms::QuestionnaireType, "The questionnaire for this survey", null: true
|
|
12
12
|
|
|
13
13
|
def self.authorized?(object, context)
|
|
@@ -6,16 +6,15 @@ module Decidim
|
|
|
6
6
|
graphql_name "Surveys"
|
|
7
7
|
description "A surveys component of a participatory space."
|
|
8
8
|
|
|
9
|
-
field :
|
|
9
|
+
field :survey, Decidim::Surveys::SurveyType, "A single Survey object", null: true do
|
|
10
|
+
argument :id, GraphQL::Types::ID, "The id of the Survey requested", required: true
|
|
11
|
+
end
|
|
12
|
+
field :surveys, Decidim::Surveys::SurveyType.connection_type, "A collection of Surveys", null: true, connection: true
|
|
10
13
|
|
|
11
14
|
def surveys
|
|
12
15
|
Survey.where(component: object).includes(:component)
|
|
13
16
|
end
|
|
14
17
|
|
|
15
|
-
field :survey, Decidim::Surveys::SurveyType, null: true do
|
|
16
|
-
argument :id, GraphQL::Types::ID, required: true
|
|
17
|
-
end
|
|
18
|
-
|
|
19
18
|
def survey(**args)
|
|
20
19
|
Survey.where(component: object).find_by(id: args[:id])
|
|
21
20
|
end
|
|
@@ -10,12 +10,22 @@ module Decidim
|
|
|
10
10
|
paths["lib/tasks"] = nil
|
|
11
11
|
|
|
12
12
|
routes do
|
|
13
|
-
get "/answer/:session_token", to: "surveys#show", as: :show_survey
|
|
14
|
-
get "/answer/:session_token/export", to: "surveys#export_response", as: :export_response_survey
|
|
15
|
-
get "/answers", to: "surveys#index", as: :index_survey
|
|
16
13
|
get "/answer_options", to: "surveys#answer_options", as: :answer_options_survey
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
resources :surveys, except: [:new] do
|
|
15
|
+
member do
|
|
16
|
+
get :edit_questions
|
|
17
|
+
patch :update_questions
|
|
18
|
+
put :publish
|
|
19
|
+
put :unpublish
|
|
20
|
+
end
|
|
21
|
+
resources :answers, only: [:index, :show] do
|
|
22
|
+
member do
|
|
23
|
+
get :export_response
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
resources :publish_answers, only: [:index, :update, :destroy]
|
|
27
|
+
end
|
|
28
|
+
root to: "surveys#index"
|
|
19
29
|
end
|
|
20
30
|
|
|
21
31
|
initializer "decidim_surveys_admin.notifications.components" do
|
|
@@ -12,18 +12,6 @@ Decidim.register_component(:surveys) do |component|
|
|
|
12
12
|
component.specific_data_importer_class_name = "Decidim::Surveys::DataImporter"
|
|
13
13
|
component.query_type = "Decidim::Surveys::SurveysType"
|
|
14
14
|
|
|
15
|
-
component.on(:copy) do |context|
|
|
16
|
-
Decidim::Surveys::CreateSurvey.call(context[:new_component]) do
|
|
17
|
-
on(:invalid) { raise "Cannot create survey" }
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
component.on(:create) do |instance|
|
|
22
|
-
Decidim::Surveys::CreateSurvey.call(instance) do
|
|
23
|
-
on(:invalid) { raise "Cannot create survey" }
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
15
|
component.data_portable_entities = ["Decidim::Forms::Answer"]
|
|
28
16
|
|
|
29
17
|
component.newsletter_participant_entities = ["Decidim::Forms::Answer"]
|
|
@@ -37,20 +25,22 @@ Decidim.register_component(:surveys) do |component|
|
|
|
37
25
|
|
|
38
26
|
component.register_resource(:survey) do |resource|
|
|
39
27
|
resource.model_class_name = "Decidim::Surveys::Survey"
|
|
28
|
+
resource.card = "decidim/surveys/survey"
|
|
29
|
+
resource.actions = %w(answer)
|
|
40
30
|
end
|
|
41
31
|
|
|
42
|
-
component.register_stat :surveys_count do |components, start_at, end_at|
|
|
32
|
+
component.register_stat :surveys_count, primary: true, priority: Decidim::StatsRegistry::HIGH_PRIORITY do |components, start_at, end_at|
|
|
43
33
|
surveys = Decidim::Surveys::Survey.where(component: components)
|
|
44
|
-
surveys = surveys.where(
|
|
45
|
-
surveys = surveys.where(
|
|
34
|
+
surveys = surveys.where(created_at: start_at..) if start_at.present?
|
|
35
|
+
surveys = surveys.where(created_at: ..end_at) if end_at.present?
|
|
46
36
|
surveys.count
|
|
47
37
|
end
|
|
48
38
|
|
|
49
39
|
component.register_stat :answers_count, primary: true, priority: Decidim::StatsRegistry::MEDIUM_PRIORITY do |components, start_at, end_at|
|
|
50
40
|
surveys = Decidim::Surveys::Survey.includes(:questionnaire).where(component: components)
|
|
51
41
|
answers = Decidim::Forms::Answer.where(questionnaire: surveys.map(&:questionnaire))
|
|
52
|
-
answers = answers.where(
|
|
53
|
-
answers = answers.where(
|
|
42
|
+
answers = answers.where(created_at: start_at..) if start_at.present?
|
|
43
|
+
answers = answers.where(created_at: ..end_at) if end_at.present?
|
|
54
44
|
answers.group(:session_token).count.size
|
|
55
45
|
end
|
|
56
46
|
|
|
@@ -58,17 +48,10 @@ Decidim.register_component(:surveys) do |component|
|
|
|
58
48
|
component.actions = %w(answer)
|
|
59
49
|
|
|
60
50
|
component.settings(:global) do |settings|
|
|
61
|
-
settings.attribute :scopes_enabled, type: :boolean, default: false
|
|
62
|
-
settings.attribute :scope_id, type: :scope
|
|
63
|
-
settings.attribute :starts_at, type: :time
|
|
64
|
-
settings.attribute :ends_at, type: :time
|
|
65
51
|
settings.attribute :announcement, type: :text, translated: true, editor: true
|
|
66
|
-
settings.attribute :clean_after_publish, type: :boolean, default: true
|
|
67
52
|
end
|
|
68
53
|
|
|
69
54
|
component.settings(:step) do |settings|
|
|
70
|
-
settings.attribute :allow_answers, type: :boolean, default: false
|
|
71
|
-
settings.attribute :allow_unregistered, type: :boolean, default: false
|
|
72
55
|
settings.attribute :announcement, type: :text, translated: true, editor: true
|
|
73
56
|
end
|
|
74
57
|
|
|
@@ -9,12 +9,12 @@ module Decidim
|
|
|
9
9
|
isolate_namespace Decidim::Surveys
|
|
10
10
|
|
|
11
11
|
routes do
|
|
12
|
-
resources :surveys, only: [:show] do
|
|
12
|
+
resources :surveys, only: [:index, :show, :edit] do
|
|
13
13
|
member do
|
|
14
14
|
post :answer
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
|
-
root to: "surveys#
|
|
17
|
+
root to: "surveys#index"
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
initializer "decidim_surveys.settings_changes" do
|
|
@@ -4,7 +4,7 @@ require "decidim/components/namer"
|
|
|
4
4
|
|
|
5
5
|
module Decidim
|
|
6
6
|
module Surveys
|
|
7
|
-
class Seeds
|
|
7
|
+
class Seeds < Decidim::Seeds
|
|
8
8
|
attr_reader :participatory_space
|
|
9
9
|
|
|
10
10
|
def initialize(participatory_space:)
|
|
@@ -12,11 +12,19 @@ module Decidim
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def call
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
component = create_component!
|
|
16
|
+
|
|
17
|
+
3.times do
|
|
18
|
+
questionnaire = create_questionnaire!(component:)
|
|
19
|
+
create_questions!(questionnaire:)
|
|
20
|
+
|
|
21
|
+
next if questionnaire.questionnaire_for.allow_answers
|
|
19
22
|
|
|
23
|
+
rand(200).times { create_answers!(questionnaire:) }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def create_component!
|
|
20
28
|
params = {
|
|
21
29
|
name: Decidim::Components::Namer.new(participatory_space.organization.available_locales, :surveys).i18n_name,
|
|
22
30
|
manifest_name: :surveys,
|
|
@@ -24,7 +32,7 @@ module Decidim
|
|
|
24
32
|
participatory_space:
|
|
25
33
|
}
|
|
26
34
|
|
|
27
|
-
|
|
35
|
+
Decidim.traceability.perform_action!(
|
|
28
36
|
"publish",
|
|
29
37
|
Decidim::Component,
|
|
30
38
|
admin_user,
|
|
@@ -32,7 +40,9 @@ module Decidim
|
|
|
32
40
|
) do
|
|
33
41
|
Decidim::Component.create!(params)
|
|
34
42
|
end
|
|
43
|
+
end
|
|
35
44
|
|
|
45
|
+
def create_questionnaire!(component:)
|
|
36
46
|
questionnaire = Decidim::Forms::Questionnaire.new(
|
|
37
47
|
title: Decidim::Faker::Localized.paragraph,
|
|
38
48
|
description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
|
|
@@ -45,7 +55,9 @@ module Decidim
|
|
|
45
55
|
|
|
46
56
|
params = {
|
|
47
57
|
component:,
|
|
48
|
-
questionnaire
|
|
58
|
+
questionnaire:,
|
|
59
|
+
allow_answers: [true, false].sample,
|
|
60
|
+
published_at: Time.current
|
|
49
61
|
}
|
|
50
62
|
|
|
51
63
|
Decidim.traceability.create!(
|
|
@@ -55,16 +67,22 @@ module Decidim
|
|
|
55
67
|
visibility: "all"
|
|
56
68
|
)
|
|
57
69
|
|
|
58
|
-
|
|
70
|
+
questionnaire
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def create_questions!(questionnaire:)
|
|
74
|
+
%w(short_answer long_answer files).each_with_index do |text_question_type, index|
|
|
59
75
|
Decidim::Forms::Question.create!(
|
|
76
|
+
mandatory: text_question_type == "short_answer",
|
|
60
77
|
questionnaire:,
|
|
61
78
|
body: Decidim::Faker::Localized.paragraph,
|
|
62
79
|
question_type: text_question_type,
|
|
63
80
|
position: index
|
|
64
81
|
)
|
|
82
|
+
next if text_question_type == "files"
|
|
65
83
|
end
|
|
66
84
|
|
|
67
|
-
%w(single_option multiple_option).each_with_index do |multiple_choice_question_type, index|
|
|
85
|
+
%w(single_option multiple_option sorting).each_with_index do |multiple_choice_question_type, index|
|
|
68
86
|
question = Decidim::Forms::Question.create!(
|
|
69
87
|
questionnaire:,
|
|
70
88
|
body: Decidim::Faker::Localized.paragraph,
|
|
@@ -76,8 +94,12 @@ module Decidim
|
|
|
76
94
|
question.answer_options.create!(body: Decidim::Faker::Localized.sentence)
|
|
77
95
|
end
|
|
78
96
|
|
|
97
|
+
# Files type questions do not support being conditionals for another questions
|
|
98
|
+
files_question = questionnaire.questions.where(question_type: "files")
|
|
99
|
+
possible_condition_questions = questionnaire.questions.excluding(files_question)
|
|
100
|
+
|
|
79
101
|
question.display_conditions.create!(
|
|
80
|
-
condition_question:
|
|
102
|
+
condition_question: possible_condition_questions.sample,
|
|
81
103
|
question:,
|
|
82
104
|
condition_type: :answered,
|
|
83
105
|
mandatory: true
|
|
@@ -97,6 +119,89 @@ module Decidim
|
|
|
97
119
|
question.matrix_rows.create!(body: Decidim::Faker::Localized.sentence, position:)
|
|
98
120
|
end
|
|
99
121
|
end
|
|
122
|
+
|
|
123
|
+
Decidim::Forms::Question.create!(
|
|
124
|
+
questionnaire:,
|
|
125
|
+
body: nil,
|
|
126
|
+
question_type: "separator",
|
|
127
|
+
position: 3
|
|
128
|
+
)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def create_answers!(questionnaire:, user: nil)
|
|
132
|
+
user = find_or_initialize_user_by(email: "survey-#{questionnaire.id}-#{rand(1_000_000)}@example.org") if user.nil?
|
|
133
|
+
|
|
134
|
+
answer_options = {
|
|
135
|
+
user:,
|
|
136
|
+
questionnaire:,
|
|
137
|
+
session_token: Digest::MD5.hexdigest("#{user.id}-#{Rails.application.secret_key_base}"),
|
|
138
|
+
ip_hash: Faker::Internet.device_token.slice(0, 24)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
questionnaire.questions.each do |question|
|
|
142
|
+
case question.question_type
|
|
143
|
+
when "short_answer", "long_answer"
|
|
144
|
+
create_answer_for_text_question_type!(answer_options.merge({ question: }))
|
|
145
|
+
when "single_option", "multiple_option"
|
|
146
|
+
create_answer_for_multiple_choice_question_type(answer_options.merge({ question: }))
|
|
147
|
+
when "sorting"
|
|
148
|
+
create_answer_for_sorting_question_type(answer_options.merge({ question: }))
|
|
149
|
+
when "matrix_single", "matrix_multiple"
|
|
150
|
+
create_answer_for_matrix_question_type(answer_options.merge({ question: }))
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
rescue ActiveRecord::RecordInvalid
|
|
154
|
+
# Silently ignore the error as we do not care if the user already exists
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def create_answer_for_text_question_type!(options)
|
|
158
|
+
Decidim::Forms::Answer.create!(
|
|
159
|
+
**options, body: ::Faker::Lorem.paragraph(sentence_count: 1)
|
|
160
|
+
)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def create_answer_for_sorting_question_type(options)
|
|
164
|
+
answer = Decidim::Forms::Answer.create!(**options)
|
|
165
|
+
answer_options = options[:question].answer_options
|
|
166
|
+
available_positions = (0..(answer_options.size - 1)).to_a
|
|
167
|
+
|
|
168
|
+
answer_options.each do |answer_option|
|
|
169
|
+
position = available_positions.sample
|
|
170
|
+
body = answer_option[I18n.locale]
|
|
171
|
+
|
|
172
|
+
Decidim::Forms::AnswerChoice.create!(
|
|
173
|
+
answer:,
|
|
174
|
+
answer_option:,
|
|
175
|
+
body:,
|
|
176
|
+
position:
|
|
177
|
+
)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def create_answer_for_multiple_choice_question_type(options)
|
|
182
|
+
answer = Decidim::Forms::Answer.create!(**options)
|
|
183
|
+
answer_option = options[:question].answer_options.sample
|
|
184
|
+
body = answer_option[I18n.locale]
|
|
185
|
+
|
|
186
|
+
Decidim::Forms::AnswerChoice.create!(
|
|
187
|
+
answer:,
|
|
188
|
+
answer_option:,
|
|
189
|
+
body:
|
|
190
|
+
)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def create_answer_for_matrix_question_type(options)
|
|
194
|
+
answer = Decidim::Forms::Answer.create!(**options)
|
|
195
|
+
answer_option = options[:question].answer_options.sample
|
|
196
|
+
matrix_row = options[:question].matrix_rows.sample
|
|
197
|
+
body = answer_option[I18n.locale]
|
|
198
|
+
|
|
199
|
+
Decidim::Forms::AnswerChoice.create!(
|
|
200
|
+
answer:,
|
|
201
|
+
answer_option:,
|
|
202
|
+
matrix_row:,
|
|
203
|
+
body:
|
|
204
|
+
)
|
|
100
205
|
end
|
|
101
206
|
end
|
|
102
207
|
end
|
|
@@ -21,5 +21,29 @@ FactoryBot.define do
|
|
|
21
21
|
end
|
|
22
22
|
questionnaire { build(:questionnaire, :with_questions, skip_injection:) }
|
|
23
23
|
component { build(:surveys_component, skip_injection:) }
|
|
24
|
+
|
|
25
|
+
trait :published do
|
|
26
|
+
published_at { Time.current }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
trait :allow_edit do
|
|
30
|
+
allow_editing_answers { true }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
trait :allow_answers do
|
|
34
|
+
allow_answers { true }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
trait :allow_unregistered do
|
|
38
|
+
allow_unregistered { true }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
trait :clean_after_publish do
|
|
42
|
+
clean_after_publish { true }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
trait :announcement do
|
|
46
|
+
announcement { "This is a custom announcement." }
|
|
47
|
+
end
|
|
24
48
|
end
|
|
25
49
|
end
|