decidim-elections 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +31 -0
- data/Rakefile +3 -0
- data/app/assets/config/decidim_elections_manifest.js +0 -0
- data/app/assets/images/decidim/elections/icon.svg +1 -0
- data/app/commands/decidim/elections/admin/create_answer.rb +71 -0
- data/app/commands/decidim/elections/admin/create_election.rb +48 -0
- data/app/commands/decidim/elections/admin/create_question.rb +52 -0
- data/app/commands/decidim/elections/admin/destroy_answer.rb +50 -0
- data/app/commands/decidim/elections/admin/destroy_election.rb +46 -0
- data/app/commands/decidim/elections/admin/destroy_question.rb +46 -0
- data/app/commands/decidim/elections/admin/update_answer.rb +73 -0
- data/app/commands/decidim/elections/admin/update_election.rb +48 -0
- data/app/commands/decidim/elections/admin/update_question.rb +52 -0
- data/app/controllers/decidim/elections/admin/answers_controller.rb +92 -0
- data/app/controllers/decidim/elections/admin/application_controller.rb +15 -0
- data/app/controllers/decidim/elections/admin/elections_controller.rb +82 -0
- data/app/controllers/decidim/elections/admin/questions_controller.rb +86 -0
- data/app/controllers/decidim/elections/application_controller.rb +13 -0
- data/app/controllers/decidim/elections/elections_controller.rb +9 -0
- data/app/forms/decidim/elections/admin/answer_form.rb +53 -0
- data/app/forms/decidim/elections/admin/election_form.rb +24 -0
- data/app/forms/decidim/elections/admin/question_form.rb +26 -0
- data/app/helpers/decidim/elections/application_helper.rb +10 -0
- data/app/models/decidim/elections/answer.rb +26 -0
- data/app/models/decidim/elections/application_record.rb +10 -0
- data/app/models/decidim/elections/election.rb +22 -0
- data/app/models/decidim/elections/question.rb +20 -0
- data/app/permissions/decidim/elections/admin/permissions.rb +42 -0
- data/app/permissions/decidim/elections/permissions.rb +16 -0
- data/app/types/decidim/elections/election_answer_type.rb +24 -0
- data/app/types/decidim/elections/election_question_type.rb +25 -0
- data/app/types/decidim/elections/election_type.rb +26 -0
- data/app/types/decidim/elections/elections_type.rb +32 -0
- data/app/views/decidim/elections/admin/answers/_form.html.erb +25 -0
- data/app/views/decidim/elections/admin/answers/edit.html.erb +7 -0
- data/app/views/decidim/elections/admin/answers/index.html.erb +46 -0
- data/app/views/decidim/elections/admin/answers/new.html.erb +7 -0
- data/app/views/decidim/elections/admin/answers/proposals_picker.html.erb +1 -0
- data/app/views/decidim/elections/admin/elections/_form.html.erb +28 -0
- data/app/views/decidim/elections/admin/elections/edit.html.erb +7 -0
- data/app/views/decidim/elections/admin/elections/index.html.erb +54 -0
- data/app/views/decidim/elections/admin/elections/new.html.erb +7 -0
- data/app/views/decidim/elections/admin/questions/_form.html.erb +27 -0
- data/app/views/decidim/elections/admin/questions/edit.html.erb +7 -0
- data/app/views/decidim/elections/admin/questions/index.html.erb +53 -0
- data/app/views/decidim/elections/admin/questions/new.html.erb +7 -0
- data/app/views/decidim/elections/elections/index.html.erb +1 -0
- data/app/views/decidim/elections/elections/show.html.erb +0 -0
- data/config/i18n-tasks.yml +10 -0
- data/config/locales/ar.yml +1 -0
- data/config/locales/bg-BG.yml +7 -0
- data/config/locales/ca.yml +132 -0
- data/config/locales/cs.yml +138 -0
- data/config/locales/da-DK.yml +1 -0
- data/config/locales/de.yml +132 -0
- data/config/locales/el.yml +132 -0
- data/config/locales/en.yml +133 -0
- data/config/locales/eo-UY.yml +1 -0
- data/config/locales/es-MX.yml +132 -0
- data/config/locales/es-PY.yml +132 -0
- data/config/locales/es.yml +132 -0
- data/config/locales/et-EE.yml +1 -0
- data/config/locales/eu.yml +1 -0
- data/config/locales/fi-plain.yml +132 -0
- data/config/locales/fi.yml +132 -0
- data/config/locales/fr-CA.yml +132 -0
- data/config/locales/fr.yml +132 -0
- data/config/locales/ga-IE.yml +1 -0
- data/config/locales/gl.yml +1 -0
- data/config/locales/hr-HR.yml +1 -0
- data/config/locales/hu.yml +1 -0
- data/config/locales/id-ID.yml +1 -0
- data/config/locales/is-IS.yml +1 -0
- data/config/locales/it.yml +132 -0
- data/config/locales/ja-JP.yml +129 -0
- data/config/locales/lt-LT.yml +1 -0
- data/config/locales/lv-LV.yml +135 -0
- data/config/locales/mt-MT.yml +1 -0
- data/config/locales/nl.yml +132 -0
- data/config/locales/no.yml +9 -0
- data/config/locales/pl.yml +138 -0
- data/config/locales/pt-BR.yml +1 -0
- data/config/locales/pt.yml +132 -0
- data/config/locales/ro-RO.yml +135 -0
- data/config/locales/ru.yml +1 -0
- data/config/locales/sk.yml +1 -0
- data/config/locales/sl.yml +5 -0
- data/config/locales/sr-CS.yml +1 -0
- data/config/locales/sv.yml +132 -0
- data/config/locales/tr-TR.yml +1 -0
- data/config/locales/uk.yml +1 -0
- data/db/migrate/20200430083618_create_decidim_elections_elections.rb +15 -0
- data/db/migrate/20200518082327_create_decidim_elections_questions.rb +14 -0
- data/db/migrate/20200518084144_create_decidim_elections_answers.rb +12 -0
- data/lib/decidim/elections.rb +13 -0
- data/lib/decidim/elections/admin.rb +10 -0
- data/lib/decidim/elections/admin_engine.rb +29 -0
- data/lib/decidim/elections/component.rb +123 -0
- data/lib/decidim/elections/engine.rb +23 -0
- data/lib/decidim/elections/seeds/city.jpeg +0 -0
- data/lib/decidim/elections/test/factories.rb +52 -0
- data/lib/decidim/elections/version.rb +10 -0
- metadata +201 -0
@@ -0,0 +1 @@
|
|
1
|
+
ru:
|
@@ -0,0 +1 @@
|
|
1
|
+
sk:
|
@@ -0,0 +1 @@
|
|
1
|
+
sr:
|
@@ -0,0 +1,132 @@
|
|
1
|
+
sv:
|
2
|
+
activemodel:
|
3
|
+
attributes:
|
4
|
+
answer:
|
5
|
+
description: Beskrivning
|
6
|
+
image: Bild
|
7
|
+
proposals: Relaterade förslag
|
8
|
+
title: Titel
|
9
|
+
election:
|
10
|
+
description: Beskrivning
|
11
|
+
end_time: Omröstningen slutar vid
|
12
|
+
start_time: Röstningsstart vid
|
13
|
+
subtitle: Undertext
|
14
|
+
title: Titel
|
15
|
+
question:
|
16
|
+
description: Beskrivning
|
17
|
+
max_selections: Maximalt antal val
|
18
|
+
title: Titel
|
19
|
+
errors:
|
20
|
+
models:
|
21
|
+
answer:
|
22
|
+
attributes:
|
23
|
+
attachment:
|
24
|
+
needs_to_be_reattached: Måste återknytas
|
25
|
+
activerecord:
|
26
|
+
models:
|
27
|
+
decidim/elections/answer:
|
28
|
+
one: Svar
|
29
|
+
other: Svar
|
30
|
+
decidim/elections/election:
|
31
|
+
one: Val
|
32
|
+
other: Val
|
33
|
+
decidim/elections/question:
|
34
|
+
one: Fråga
|
35
|
+
other: Frågor
|
36
|
+
decidim:
|
37
|
+
components:
|
38
|
+
elections:
|
39
|
+
name: Val
|
40
|
+
settings:
|
41
|
+
global:
|
42
|
+
announcement: Meddelande
|
43
|
+
step:
|
44
|
+
announcement: Meddelande
|
45
|
+
elections:
|
46
|
+
actions:
|
47
|
+
confirm_destroy: Är du säker?
|
48
|
+
destroy: Förstör
|
49
|
+
edit: Redigera
|
50
|
+
new: Ny %{name}
|
51
|
+
preview: Förhandsgranska
|
52
|
+
title: Åtgärder
|
53
|
+
admin:
|
54
|
+
answers:
|
55
|
+
create:
|
56
|
+
invalid: Det gick inte att skapa svaret
|
57
|
+
success: Svaret har skapats
|
58
|
+
destroy:
|
59
|
+
invalid: Det gick inte att ta bort svaret
|
60
|
+
success: Svaret har tagits bort
|
61
|
+
edit:
|
62
|
+
title: Redigera svar
|
63
|
+
update: Uppdatera svar
|
64
|
+
index:
|
65
|
+
title: Svar
|
66
|
+
new:
|
67
|
+
create: Skapa svar
|
68
|
+
title: Nytt svar
|
69
|
+
update:
|
70
|
+
invalid: Det gick inte att uppdatera svaret
|
71
|
+
success: Svaret har uppdaterats
|
72
|
+
elections:
|
73
|
+
create:
|
74
|
+
invalid: Det gick inte att skapa detta val
|
75
|
+
success: Val har skapats
|
76
|
+
destroy:
|
77
|
+
invalid: Det gick inte att ta bort valet
|
78
|
+
success: Val har tagits bort
|
79
|
+
edit:
|
80
|
+
title: Redigera val
|
81
|
+
update: Uppdatera val
|
82
|
+
index:
|
83
|
+
title: Val
|
84
|
+
new:
|
85
|
+
create: Skapa val
|
86
|
+
title: Nytt val
|
87
|
+
update:
|
88
|
+
invalid: Det gick inte att uppdatera valet
|
89
|
+
success: Val har uppdaterats
|
90
|
+
models:
|
91
|
+
answer:
|
92
|
+
name: Svar
|
93
|
+
election:
|
94
|
+
name: Val
|
95
|
+
question:
|
96
|
+
name: Fråga
|
97
|
+
questions:
|
98
|
+
create:
|
99
|
+
invalid: Det gick inte att skapa denna fråga
|
100
|
+
success: Frågan har skapats
|
101
|
+
destroy:
|
102
|
+
invalid: Det gick inte att ta bort denna fråga
|
103
|
+
success: Frågan har tagits bort
|
104
|
+
edit:
|
105
|
+
title: Redigera fråga
|
106
|
+
update: Uppdatera fråga
|
107
|
+
index:
|
108
|
+
title: Frågor
|
109
|
+
new:
|
110
|
+
create: Skapa fråga
|
111
|
+
title: Ny fråga
|
112
|
+
update:
|
113
|
+
invalid: Det gick inte att uppdatera denna fråga
|
114
|
+
success: Frågan har uppdaterats
|
115
|
+
models:
|
116
|
+
answer:
|
117
|
+
fields:
|
118
|
+
proposals: Förslag
|
119
|
+
title: Titel
|
120
|
+
election:
|
121
|
+
fields:
|
122
|
+
end_time: Avsluta vid
|
123
|
+
start_time: Börjar vid
|
124
|
+
title: Titel
|
125
|
+
question:
|
126
|
+
fields:
|
127
|
+
answers: Svar
|
128
|
+
max_selections: Max. val
|
129
|
+
title: Titel
|
130
|
+
participatory_processes:
|
131
|
+
statistics:
|
132
|
+
elections_count: Val
|
@@ -0,0 +1 @@
|
|
1
|
+
tr:
|
@@ -0,0 +1 @@
|
|
1
|
+
uk:
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateDecidimElectionsElections < ActiveRecord::Migration[5.2]
|
4
|
+
def change
|
5
|
+
create_table :decidim_elections_elections do |t|
|
6
|
+
t.jsonb :title
|
7
|
+
t.jsonb :subtitle
|
8
|
+
t.jsonb :description
|
9
|
+
t.datetime :start_time
|
10
|
+
t.datetime :end_time
|
11
|
+
t.references :decidim_component, index: true
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateDecidimElectionsQuestions < ActiveRecord::Migration[5.2]
|
4
|
+
def change
|
5
|
+
create_table :decidim_elections_questions do |t|
|
6
|
+
t.references :decidim_elections_election, null: false, index: { name: "decidim_elections_elections_questions" }
|
7
|
+
t.jsonb :title, null: false
|
8
|
+
t.jsonb :description
|
9
|
+
t.integer :max_selections, null: false, default: 1
|
10
|
+
t.integer :weight, null: false, default: 0
|
11
|
+
t.boolean :random_answers_order, null: false, default: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateDecidimElectionsAnswers < ActiveRecord::Migration[5.2]
|
4
|
+
def change
|
5
|
+
create_table :decidim_elections_answers do |t|
|
6
|
+
t.references :decidim_elections_question, null: false, index: { name: "decidim_elections_questions_answers" }
|
7
|
+
t.jsonb :title, null: false
|
8
|
+
t.jsonb :description
|
9
|
+
t.integer :weight, null: false, default: 0
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "decidim/elections/admin"
|
4
|
+
require "decidim/elections/engine"
|
5
|
+
require "decidim/elections/admin_engine"
|
6
|
+
require "decidim/elections/component"
|
7
|
+
|
8
|
+
module Decidim
|
9
|
+
# This namespace holds the logic of the `Elections` component. This component
|
10
|
+
# allows users to create elections in a participatory space.
|
11
|
+
module Elections
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Elections
|
5
|
+
# This is the engine that runs on the public interface of `Elections`.
|
6
|
+
class AdminEngine < ::Rails::Engine
|
7
|
+
isolate_namespace Decidim::Elections::Admin
|
8
|
+
|
9
|
+
paths["db/migrate"] = nil
|
10
|
+
paths["lib/tasks"] = nil
|
11
|
+
|
12
|
+
routes do
|
13
|
+
resources :elections do
|
14
|
+
resources :questions do
|
15
|
+
resources :answers do
|
16
|
+
get :proposals_picker, on: :collection
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
root to: "elections#index"
|
22
|
+
end
|
23
|
+
|
24
|
+
def load_seed
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "decidim/components/namer"
|
4
|
+
|
5
|
+
Decidim.register_component(:elections) do |component|
|
6
|
+
component.engine = Decidim::Elections::Engine
|
7
|
+
component.admin_engine = Decidim::Elections::AdminEngine
|
8
|
+
component.icon = "decidim/elections/icon.svg"
|
9
|
+
component.permissions_class_name = "Decidim::Elections::Permissions"
|
10
|
+
|
11
|
+
# component.on(:before_destroy) do |instance|
|
12
|
+
# # Code executed before removing the component
|
13
|
+
# end
|
14
|
+
|
15
|
+
# These actions permissions can be configured in the admin panel
|
16
|
+
# component.actions = %w()
|
17
|
+
|
18
|
+
component.settings(:global) do |settings|
|
19
|
+
settings.attribute :announcement, type: :text, translated: true, editor: true
|
20
|
+
end
|
21
|
+
|
22
|
+
component.settings(:step) do |settings|
|
23
|
+
settings.attribute :announcement, type: :text, translated: true, editor: true
|
24
|
+
end
|
25
|
+
|
26
|
+
component.register_resource(:election) do |resource|
|
27
|
+
resource.model_class_name = "Decidim::Elections::Election"
|
28
|
+
end
|
29
|
+
|
30
|
+
component.register_resource(:question) do |resource|
|
31
|
+
resource.model_class_name = "Decidim::Elections::Question"
|
32
|
+
end
|
33
|
+
|
34
|
+
component.register_resource(:answer) do |resource|
|
35
|
+
resource.model_class_name = "Decidim::Elections::Answer"
|
36
|
+
end
|
37
|
+
|
38
|
+
component.register_stat :elections_count, primary: true, priority: Decidim::StatsRegistry::HIGH_PRIORITY do |components, _start_at, _end_at|
|
39
|
+
Decidim::Elections::Election.where(component: components).count
|
40
|
+
end
|
41
|
+
|
42
|
+
component.seeds do |participatory_space|
|
43
|
+
admin_user = Decidim::User.find_by(
|
44
|
+
organization: participatory_space.organization,
|
45
|
+
email: "admin@example.org"
|
46
|
+
)
|
47
|
+
|
48
|
+
params = {
|
49
|
+
name: Decidim::Components::Namer.new(participatory_space.organization.available_locales, :elections).i18n_name,
|
50
|
+
manifest_name: :elections,
|
51
|
+
published_at: Time.current,
|
52
|
+
participatory_space: participatory_space
|
53
|
+
}
|
54
|
+
|
55
|
+
component = Decidim.traceability.perform_action!(
|
56
|
+
"publish",
|
57
|
+
Decidim::Component,
|
58
|
+
admin_user,
|
59
|
+
visibility: "all"
|
60
|
+
) do
|
61
|
+
Decidim::Component.create!(params)
|
62
|
+
end
|
63
|
+
|
64
|
+
3.times do
|
65
|
+
election = Decidim.traceability.create!(
|
66
|
+
Decidim::Elections::Election,
|
67
|
+
admin_user,
|
68
|
+
{
|
69
|
+
component: component,
|
70
|
+
title: Decidim::Faker::Localized.sentence(2),
|
71
|
+
subtitle: Decidim::Faker::Localized.sentence(2),
|
72
|
+
description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
|
73
|
+
Decidim::Faker::Localized.paragraph(3)
|
74
|
+
end,
|
75
|
+
start_time: 3.weeks.from_now,
|
76
|
+
end_time: 3.weeks.from_now + 4.hours
|
77
|
+
},
|
78
|
+
visibility: "all"
|
79
|
+
)
|
80
|
+
|
81
|
+
2.times do
|
82
|
+
question = Decidim.traceability.create!(
|
83
|
+
Decidim::Elections::Question,
|
84
|
+
admin_user,
|
85
|
+
{
|
86
|
+
election: election,
|
87
|
+
title: Decidim::Faker::Localized.sentence(2),
|
88
|
+
description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
|
89
|
+
Decidim::Faker::Localized.paragraph(3)
|
90
|
+
end,
|
91
|
+
max_selections: Faker::Number.between(0, 5),
|
92
|
+
weight: Faker::Number.number(1),
|
93
|
+
random_answers_order: Faker::Boolean.boolean(0.5)
|
94
|
+
},
|
95
|
+
visibility: "all"
|
96
|
+
)
|
97
|
+
|
98
|
+
Faker::Number.between(2, 5).times do
|
99
|
+
answer = Decidim.traceability.create!(
|
100
|
+
Decidim::Elections::Answer,
|
101
|
+
admin_user,
|
102
|
+
{
|
103
|
+
question: question,
|
104
|
+
title: Decidim::Faker::Localized.sentence(2),
|
105
|
+
description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
|
106
|
+
Decidim::Faker::Localized.paragraph(3)
|
107
|
+
end,
|
108
|
+
weight: Faker::Number.number(1)
|
109
|
+
},
|
110
|
+
visibility: "all"
|
111
|
+
)
|
112
|
+
|
113
|
+
Decidim::Attachment.create!(
|
114
|
+
title: Decidim::Faker::Localized.sentence(2),
|
115
|
+
description: Decidim::Faker::Localized.sentence(5),
|
116
|
+
file: File.new(File.join(__dir__, "seeds", "city.jpeg")),
|
117
|
+
attached_to: answer
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails"
|
4
|
+
require "decidim/core"
|
5
|
+
|
6
|
+
module Decidim
|
7
|
+
module Elections
|
8
|
+
# This is the engine that runs on the public interface of elections.
|
9
|
+
class Engine < ::Rails::Engine
|
10
|
+
isolate_namespace Decidim::Elections
|
11
|
+
|
12
|
+
routes do
|
13
|
+
resources :elections, only: [:index, :show]
|
14
|
+
|
15
|
+
root to: "elections#index"
|
16
|
+
end
|
17
|
+
|
18
|
+
initializer "decidim_elections.assets" do |app|
|
19
|
+
app.config.assets.precompile += %w(decidim_elections_manifest.js decidim_elections_manifest.css)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
Binary file
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "decidim/core/test/factories"
|
4
|
+
|
5
|
+
FactoryBot.define do
|
6
|
+
factory :elections_component, parent: :component do
|
7
|
+
name { Decidim::Components::Namer.new(participatory_space.organization.available_locales, :elections).i18n_name }
|
8
|
+
manifest_name { :elections }
|
9
|
+
participatory_space { create(:participatory_process, :with_steps) }
|
10
|
+
end
|
11
|
+
|
12
|
+
factory :election, class: "Decidim::Elections::Election" do
|
13
|
+
title { generate_localized_title }
|
14
|
+
subtitle { Decidim::Faker::Localized.sentence(3) }
|
15
|
+
description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { generate_localized_title } }
|
16
|
+
start_time { 1.day.from_now }
|
17
|
+
end_time { 3.days.from_now }
|
18
|
+
component { create(:elections_component) }
|
19
|
+
|
20
|
+
trait :started do
|
21
|
+
start_time { 1.day.ago }
|
22
|
+
end
|
23
|
+
|
24
|
+
trait :complete do
|
25
|
+
after(:build) do |election, _evaluator|
|
26
|
+
build_list(:question, 2, :complete, election: election)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
factory :question, class: "Decidim::Elections::Question" do
|
32
|
+
election
|
33
|
+
title { generate_localized_title }
|
34
|
+
description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { generate_localized_title } }
|
35
|
+
max_selections { 1 }
|
36
|
+
weight { Faker::Number.number(1) }
|
37
|
+
random_answers_order { true }
|
38
|
+
|
39
|
+
trait :complete do
|
40
|
+
after(:build) do |question, _evaluator|
|
41
|
+
build_list(:election_answer, 2, question: question)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
factory :election_answer, class: "Decidim::Elections::Answer" do
|
47
|
+
question
|
48
|
+
title { generate_localized_title }
|
49
|
+
description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { generate_localized_title } }
|
50
|
+
weight { Faker::Number.number(1) }
|
51
|
+
end
|
52
|
+
end
|