decidim-consultations 0.11.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +51 -0
- data/Rakefile +3 -0
- data/app/assets/config/decidim_consultations_manifest.js +5 -0
- data/app/assets/config/decidim_consultations_manifest.scss +3 -0
- data/app/assets/images/decidim/consultations/icon.svg +70 -0
- data/app/assets/images/decidim/consultations/icon2.svg +88 -0
- data/app/assets/javascripts/decidim/consultations/show_more.js.es6 +12 -0
- data/app/assets/javascripts/decidim/consultations/social_share.js +2 -0
- data/app/assets/javascripts/decidim/consultations/utils.js.es6 +19 -0
- data/app/assets/javascripts/decidim/consultations/vote_dialog.js +36 -0
- data/app/assets/stylesheets/decidim/consultations/_question.scss +46 -0
- data/app/assets/stylesheets/decidim/consultations/_stats.scss +22 -0
- data/app/assets/stylesheets/decidim/consultations/_video_wrapper.scss +14 -0
- data/app/assets/stylesheets/decidim/consultations/banners/_block-banner.scss +39 -0
- data/app/assets/stylesheets/decidim/consultations/consultations.scss +6 -0
- data/app/assets/stylesheets/decidim/consultations/consultations/_consultations-banner.scss +13 -0
- data/app/assets/stylesheets/decidim/consultations/consultations/_consultations-card.scss +17 -0
- data/app/assets/stylesheets/decidim/consultations/consultations/_consultations-header.scss +115 -0
- data/app/assets/stylesheets/decidim/consultations/consultations/_consultations-home-banner.scss +15 -0
- data/app/assets/stylesheets/decidim/consultations/consultations/_consultations-home-intro.scss +30 -0
- data/app/assets/stylesheets/decidim/consultations/consultations/_consultations-intro.scss +11 -0
- data/app/assets/stylesheets/decidim/consultations/consultations/_consultations-title.scss +26 -0
- data/app/assets/stylesheets/decidim/consultations/consultations/_consultations_nav.scss +7 -0
- data/app/assets/stylesheets/decidim/consultations/consultations/introductory_image.scss +3 -0
- data/app/assets/stylesheets/decidim/consultations/highlighted-content-banner.css.scss +42 -0
- data/app/assets/stylesheets/decidim/consultations/social_share.css.scss +18 -0
- data/app/commands/decidim/consultations/admin/create_consultation.rb +61 -0
- data/app/commands/decidim/consultations/admin/create_question.rb +68 -0
- data/app/commands/decidim/consultations/admin/create_response.rb +39 -0
- data/app/commands/decidim/consultations/admin/publish_consultation.rb +34 -0
- data/app/commands/decidim/consultations/admin/publish_consultation_results.rb +34 -0
- data/app/commands/decidim/consultations/admin/publish_question.rb +34 -0
- data/app/commands/decidim/consultations/admin/unpublish_consultation.rb +34 -0
- data/app/commands/decidim/consultations/admin/unpublish_consultation_results.rb +34 -0
- data/app/commands/decidim/consultations/admin/unpublish_question.rb +34 -0
- data/app/commands/decidim/consultations/admin/update_consultation.rb +64 -0
- data/app/commands/decidim/consultations/admin/update_question.rb +72 -0
- data/app/commands/decidim/consultations/admin/update_response.rb +46 -0
- data/app/commands/decidim/consultations/unvote_question.rb +37 -0
- data/app/commands/decidim/consultations/vote_question.rb +42 -0
- data/app/constraints/decidim/consultations/current_component.rb +28 -0
- data/app/constraints/decidim/consultations/current_question.rb +36 -0
- data/app/controllers/concerns/decidim/consultations/action_authorization.rb +38 -0
- data/app/controllers/concerns/decidim/consultations/admin/consultation_admin.rb +24 -0
- data/app/controllers/concerns/decidim/consultations/admin/question_admin.rb +28 -0
- data/app/controllers/concerns/decidim/consultations/needs_consultation.rb +54 -0
- data/app/controllers/concerns/decidim/consultations/needs_question.rb +79 -0
- data/app/controllers/concerns/decidim/consultations/orderable.rb +52 -0
- data/app/controllers/decidim/consultations/admin/application_controller.rb +14 -0
- data/app/controllers/decidim/consultations/admin/categories_controller.rb +13 -0
- data/app/controllers/decidim/consultations/admin/component_permissions_controller.rb +13 -0
- data/app/controllers/decidim/consultations/admin/components_controller.rb +13 -0
- data/app/controllers/decidim/consultations/admin/consultation_publications_controller.rb +44 -0
- data/app/controllers/decidim/consultations/admin/consultation_results_publications_controller.rb +44 -0
- data/app/controllers/decidim/consultations/admin/consultations_controller.rb +100 -0
- data/app/controllers/decidim/consultations/admin/question_attachments_controller.rb +25 -0
- data/app/controllers/decidim/consultations/admin/question_publications_controller.rb +44 -0
- data/app/controllers/decidim/consultations/admin/questions_controller.rb +88 -0
- data/app/controllers/decidim/consultations/admin/responses_controller.rb +85 -0
- data/app/controllers/decidim/consultations/consultation_widgets_controller.rb +25 -0
- data/app/controllers/decidim/consultations/consultations_controller.rb +75 -0
- data/app/controllers/decidim/consultations/question_votes_controller.rb +40 -0
- data/app/controllers/decidim/consultations/question_widgets_controller.rb +26 -0
- data/app/controllers/decidim/consultations/questions_controller.rb +23 -0
- data/app/forms/decidim/consultations/admin/consultation_form.rb +56 -0
- data/app/forms/decidim/consultations/admin/question_form.rb +74 -0
- data/app/forms/decidim/consultations/admin/response_form.rb +18 -0
- data/app/forms/decidim/consultations/vote_form.rb +28 -0
- data/app/helpers/decidim/consultations/admin/consultations_helper.rb +14 -0
- data/app/helpers/decidim/consultations/admin/questions_helper.rb +14 -0
- data/app/helpers/decidim/consultations/consultations_helper.rb +17 -0
- data/app/models/concerns/decidim/consultations/override_categorization.rb +21 -0
- data/app/models/concerns/decidim/consultations/publicable_results.rb +51 -0
- data/app/models/decidim/consultation.rb +79 -0
- data/app/models/decidim/consultations/abilities/admin/consultation_admin_ability.rb +34 -0
- data/app/models/decidim/consultations/abilities/admin/question_admin_ability.rb +30 -0
- data/app/models/decidim/consultations/abilities/admin/response_admin_ability.rb +26 -0
- data/app/models/decidim/consultations/abilities/current_user_ability.rb +45 -0
- data/app/models/decidim/consultations/abilities/everyone_ability.rb +23 -0
- data/app/models/decidim/consultations/application_record.rb +9 -0
- data/app/models/decidim/consultations/question.rb +127 -0
- data/app/models/decidim/consultations/response.rb +19 -0
- data/app/models/decidim/consultations/vote.rb +26 -0
- data/app/presenters/decidim/consultations/question_stats_presenter.rb +52 -0
- data/app/queries/decidim/consultations/admin/admin_users.rb +40 -0
- data/app/queries/decidim/consultations/organization_active_consultations.rb +20 -0
- data/app/queries/decidim/consultations/organization_consultations.rb +20 -0
- data/app/queries/decidim/consultations/organization_questions.rb +20 -0
- data/app/services/decidim/consultations/consultation_search.rb +51 -0
- data/app/views/decidim/consultations/_consultation.html.erb +32 -0
- data/app/views/decidim/consultations/admin/consultations/_form.html.erb +58 -0
- data/app/views/decidim/consultations/admin/consultations/edit.html.erb +42 -0
- data/app/views/decidim/consultations/admin/consultations/index.html.erb +74 -0
- data/app/views/decidim/consultations/admin/consultations/new.html.erb +11 -0
- data/app/views/decidim/consultations/admin/questions/_form.html.erb +84 -0
- data/app/views/decidim/consultations/admin/questions/edit.html.erb +32 -0
- data/app/views/decidim/consultations/admin/questions/index.html.erb +74 -0
- data/app/views/decidim/consultations/admin/questions/new.html.erb +13 -0
- data/app/views/decidim/consultations/admin/responses/_form.html.erb +11 -0
- data/app/views/decidim/consultations/admin/responses/edit.html.erb +18 -0
- data/app/views/decidim/consultations/admin/responses/index.html.erb +48 -0
- data/app/views/decidim/consultations/admin/responses/new.html.erb +13 -0
- data/app/views/decidim/consultations/consultation_widgets/show.html.erb +5 -0
- data/app/views/decidim/consultations/consultations/_consultation_card.html.erb +24 -0
- data/app/views/decidim/consultations/consultations/_consultation_details.html.erb +17 -0
- data/app/views/decidim/consultations/consultations/_consultations.html.erb +16 -0
- data/app/views/decidim/consultations/consultations/_count.html.erb +1 -0
- data/app/views/decidim/consultations/consultations/_filters.html.erb +25 -0
- data/app/views/decidim/consultations/consultations/_filters_small_view.html.erb +23 -0
- data/app/views/decidim/consultations/consultations/_highlighted_questions.html.erb +13 -0
- data/app/views/decidim/consultations/consultations/_question.html.erb +40 -0
- data/app/views/decidim/consultations/consultations/_regular_questions.html.erb +14 -0
- data/app/views/decidim/consultations/consultations/finished.html.erb +15 -0
- data/app/views/decidim/consultations/consultations/index.html.erb +27 -0
- data/app/views/decidim/consultations/consultations/index.js.erb +10 -0
- data/app/views/decidim/consultations/consultations/show.html.erb +11 -0
- data/app/views/decidim/consultations/question_votes/update_vote_button.js.erb +9 -0
- data/app/views/decidim/consultations/question_widgets/show.html.erb +2 -0
- data/app/views/decidim/consultations/questions/_results.html.erb +15 -0
- data/app/views/decidim/consultations/questions/_right_column.html.erb +20 -0
- data/app/views/decidim/consultations/questions/_statistics.html.erb +31 -0
- data/app/views/decidim/consultations/questions/_technical_data.html.erb +38 -0
- data/app/views/decidim/consultations/questions/_vote_button.html.erb +76 -0
- data/app/views/decidim/consultations/questions/_vote_modal.html.erb +27 -0
- data/app/views/decidim/consultations/questions/_vote_modal_confirm.html.erb +33 -0
- data/app/views/decidim/consultations/questions/show.html.erb +58 -0
- data/app/views/layouts/decidim/_consultation_header.html.erb +16 -0
- data/app/views/layouts/decidim/_consultation_voting_data.html.erb +10 -0
- data/app/views/layouts/decidim/_question_components.html.erb +38 -0
- data/app/views/layouts/decidim/_question_header.html.erb +46 -0
- data/app/views/layouts/decidim/admin/consultation.html.erb +28 -0
- data/app/views/layouts/decidim/admin/consultations.html.erb +16 -0
- data/app/views/layouts/decidim/admin/question.html.erb +72 -0
- data/app/views/layouts/decidim/consultation.html.erb +17 -0
- data/app/views/layouts/decidim/consultation_choose.html.erb +7 -0
- data/app/views/layouts/decidim/question.html.erb +19 -0
- data/config/locales/ca.yml +248 -0
- data/config/locales/en.yml +249 -0
- data/config/locales/es.yml +248 -0
- data/config/locales/eu.yml +248 -0
- data/config/locales/fi.yml +248 -0
- data/config/locales/fr.yml +248 -0
- data/config/locales/gl.yml +248 -0
- data/config/locales/it.yml +248 -0
- data/config/locales/nl.yml +248 -0
- data/config/locales/pl.yml +258 -0
- data/config/locales/pt-BR.yml +248 -0
- data/config/locales/pt.yml +248 -0
- data/config/locales/ru.yml +6 -0
- data/config/locales/sv.yml +248 -0
- data/config/locales/uk.yml +6 -0
- data/db/migrate/20180109092205_create_decidim_consultations.rb +37 -0
- data/db/migrate/20180112053247_create_decidim_consultations_questions.rb +35 -0
- data/db/migrate/20180115132000_add_end_voting_date_to_decidim_consultations.rb +18 -0
- data/db/migrate/20180115170933_add_slug_to_decidim_consultations_questions.rb +32 -0
- data/db/migrate/20180119084217_create_decidim_consultations_votes.rb +17 -0
- data/db/migrate/20180119084331_add_votes_count_to_decidim_consultations_question.rb +7 -0
- data/db/migrate/20180122113155_add_origin_scope_to_decidim_consultations_questions.rb +8 -0
- data/db/migrate/20180122113400_add_origin_title_to_decidim_consultations_questions.rb +8 -0
- data/db/migrate/20180122113447_add_origin_string_to_decidim_consultations_questions.rb +7 -0
- data/db/migrate/20180126142459_add_enable_highlighted_banner_to_decidim_consultations.rb +7 -0
- data/db/migrate/20180129063438_add_i_frame_url_to_decidim_consultations_questions.rb +8 -0
- data/db/migrate/20180129063700_create_decidim_consultations_responses.rb +14 -0
- data/db/migrate/20180129122226_rename_decidim_consultations_vote_to_decidim_consultations_endorsement.rb +7 -0
- data/db/migrate/20180129122504_rename_decidim_consultations_questions_votes_count_to_endorsements_count.rb +7 -0
- data/db/migrate/20180130060754_add_responses_count_to_decidim_consultations_questions.rb +22 -0
- data/db/migrate/20180130110449_rename_vote_related_attributes.rb +9 -0
- data/db/migrate/20180130142018_add_decidim_user_group_id_to_decidim_consultations_endorsements.rb +7 -0
- data/db/migrate/20180130142411_rename_vote_indexes_to_endorsement_indexes.rb +36 -0
- data/db/migrate/20180131083844_add_response_to_decidim_consultations_endorsements.rb +10 -0
- data/db/migrate/20180201135823_rename_endorsement_to_vote.rb +23 -0
- data/db/migrate/20180202050920_add_hero_image_to_decidim_consultations_question.rb +8 -0
- data/db/migrate/20180202085309_add_results_published_at_to_decidim_consultations.rb +7 -0
- data/db/migrate/20180202133655_add_votes_count_to_decidim_consultations_response.rb +7 -0
- data/db/migrate/20180212100503_remove_enable_highlighted_banner_flag.rb +7 -0
- data/db/migrate/20180219092120_add_order_to_decidim_consultations_questions.rb +7 -0
- data/db/migrate/20180320100658_add_introductory_image_to_decidim_consultations.rb +7 -0
- data/db/seeds/Exampledocument.pdf +0 -0
- data/db/seeds/city.jpeg +0 -0
- data/db/seeds/city2.jpeg +0 -0
- data/db/seeds/homepage_image.jpg +0 -0
- data/lib/decidim/consultations.rb +18 -0
- data/lib/decidim/consultations/admin.rb +10 -0
- data/lib/decidim/consultations/admin_engine.rb +72 -0
- data/lib/decidim/consultations/engine.rb +83 -0
- data/lib/decidim/consultations/participatory_space.rb +171 -0
- data/lib/decidim/consultations/test/factories.rb +104 -0
- data/lib/decidim/consultations/version.rb +9 -0
- metadata +288 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
module Abilities
|
6
|
+
module Admin
|
7
|
+
# Defines the abilities related to user able to administer consultations.
|
8
|
+
# Intended to be used with `cancancan`.
|
9
|
+
class ConsultationAdminAbility
|
10
|
+
include CanCan::Ability
|
11
|
+
|
12
|
+
attr_reader :user, :context
|
13
|
+
|
14
|
+
def initialize(user, context)
|
15
|
+
return unless user&.admin?
|
16
|
+
|
17
|
+
@user = user
|
18
|
+
@context = context
|
19
|
+
|
20
|
+
can :manage, Consultation
|
21
|
+
|
22
|
+
cannot :publish_results, Consultation
|
23
|
+
can :publish_results, Consultation do |consultation|
|
24
|
+
consultation.finished? && !consultation.results_published?
|
25
|
+
end
|
26
|
+
|
27
|
+
cannot :unpublish_results, Consultation
|
28
|
+
can :unpublish_results, Consultation, &:results_published?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
module Abilities
|
6
|
+
module Admin
|
7
|
+
# Defines the abilities related to user able to administer consultation's questions.
|
8
|
+
# Intended to be used with `cancancan`.
|
9
|
+
class QuestionAdminAbility
|
10
|
+
include CanCan::Ability
|
11
|
+
|
12
|
+
attr_reader :user, :context
|
13
|
+
|
14
|
+
def initialize(user, context)
|
15
|
+
return unless user&.admin?
|
16
|
+
|
17
|
+
@user = user
|
18
|
+
@context = context
|
19
|
+
|
20
|
+
can :manage, Question
|
21
|
+
cannot :publish, Question
|
22
|
+
can :publish, Question do |question|
|
23
|
+
question.external_voting || question.responses_count.positive?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
module Abilities
|
6
|
+
module Admin
|
7
|
+
# Defines the abilities related to user able to administer question responses.
|
8
|
+
# Intended to be used with `cancancan`.
|
9
|
+
class ResponseAdminAbility
|
10
|
+
include CanCan::Ability
|
11
|
+
|
12
|
+
attr_reader :user, :context
|
13
|
+
|
14
|
+
def initialize(user, context)
|
15
|
+
return unless user&.admin?
|
16
|
+
|
17
|
+
@user = user
|
18
|
+
@context = context
|
19
|
+
|
20
|
+
can :manage, Response
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
module Abilities
|
6
|
+
# Defines the base abilities related to consultations and questions for
|
7
|
+
# authenticated users. Intended to be used with `cancancan`.
|
8
|
+
class CurrentUserAbility < Decidim::Abilities::EveryoneAbility
|
9
|
+
attr_reader :user
|
10
|
+
|
11
|
+
def initialize(user, context)
|
12
|
+
super(user, context)
|
13
|
+
return unless user
|
14
|
+
|
15
|
+
@user = user
|
16
|
+
|
17
|
+
can :vote, Question do |question|
|
18
|
+
can_vote?(question)
|
19
|
+
end
|
20
|
+
|
21
|
+
can :unvote, Question do |question|
|
22
|
+
can_unvote?(question)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def can_vote?(question)
|
29
|
+
question.organization.id == user.organization.id &&
|
30
|
+
question.consultation.active? &&
|
31
|
+
question.consultation.published? &&
|
32
|
+
question.published? &&
|
33
|
+
!question.voted_by?(user)
|
34
|
+
end
|
35
|
+
|
36
|
+
def can_unvote?(question)
|
37
|
+
question.consultation.active? &&
|
38
|
+
question.consultation.published? &&
|
39
|
+
question.published? &&
|
40
|
+
question.voted_by?(user)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
module Abilities
|
6
|
+
# Defines the base abilities related to consultations for any user. Guest
|
7
|
+
# users will use these too. Intended to be used with `cancancan`.
|
8
|
+
class EveryoneAbility < Decidim::Abilities::EveryoneAbility
|
9
|
+
def initialize(user, context)
|
10
|
+
super(user, context)
|
11
|
+
|
12
|
+
can :read, Consultation do |consultation|
|
13
|
+
consultation.published? || user&.admin?
|
14
|
+
end
|
15
|
+
|
16
|
+
can :read, Question do |question|
|
17
|
+
question.published? || user&.admin?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
# The data store for Consultation questions in the Decidim::Consultations component.
|
6
|
+
class Question < ApplicationRecord
|
7
|
+
include Decidim::Participable
|
8
|
+
include Decidim::Publicable
|
9
|
+
include Decidim::Scopable
|
10
|
+
include Decidim::Comments::Commentable
|
11
|
+
include Decidim::Followable
|
12
|
+
include Decidim::HasAttachments
|
13
|
+
include Decidim::HasAttachmentCollections
|
14
|
+
|
15
|
+
belongs_to :consultation,
|
16
|
+
foreign_key: "decidim_consultation_id",
|
17
|
+
class_name: "Decidim::Consultation",
|
18
|
+
inverse_of: :questions
|
19
|
+
|
20
|
+
belongs_to :organization,
|
21
|
+
foreign_key: "decidim_organization_id",
|
22
|
+
class_name: "Decidim::Organization"
|
23
|
+
|
24
|
+
has_many :components, as: :participatory_space, dependent: :destroy
|
25
|
+
has_many :votes,
|
26
|
+
foreign_key: "decidim_consultation_question_id",
|
27
|
+
class_name: "Decidim::Consultations::Vote",
|
28
|
+
dependent: :destroy,
|
29
|
+
inverse_of: :question
|
30
|
+
|
31
|
+
has_many :responses,
|
32
|
+
foreign_key: "decidim_consultations_questions_id",
|
33
|
+
class_name: "Decidim::Consultations::Response",
|
34
|
+
inverse_of: :question,
|
35
|
+
dependent: :destroy
|
36
|
+
|
37
|
+
has_many :categories,
|
38
|
+
foreign_key: "decidim_participatory_space_id",
|
39
|
+
foreign_type: "decidim_participatory_space_type",
|
40
|
+
dependent: :destroy,
|
41
|
+
as: :participatory_space
|
42
|
+
|
43
|
+
mount_uploader :hero_image, Decidim::HeroImageUploader
|
44
|
+
mount_uploader :banner_image, Decidim::BannerImageUploader
|
45
|
+
|
46
|
+
default_scope { order(order: :asc) }
|
47
|
+
|
48
|
+
delegate :start_voting_date, to: :consultation
|
49
|
+
delegate :end_voting_date, to: :consultation
|
50
|
+
delegate :results_published?, to: :consultation
|
51
|
+
|
52
|
+
# Sorted results for the given question.
|
53
|
+
def sorted_results
|
54
|
+
responses.order(votes_count: :desc)
|
55
|
+
end
|
56
|
+
|
57
|
+
def most_voted_response
|
58
|
+
@most_voted_response ||= responses.order(votes_count: :desc).first
|
59
|
+
end
|
60
|
+
|
61
|
+
def total_votes
|
62
|
+
@total_votes ||= responses.sum(&:votes_count)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Public: Overrides the `comments_have_alignment?` Commentable concern method.
|
66
|
+
def comments_have_alignment?
|
67
|
+
true
|
68
|
+
end
|
69
|
+
|
70
|
+
# Public: Overrides the `comments_have_votes?` Commentable concern method.
|
71
|
+
def comments_have_votes?
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def hashtag
|
76
|
+
attributes["hashtag"].to_s.delete("#")
|
77
|
+
end
|
78
|
+
|
79
|
+
def banner_image_url
|
80
|
+
banner_image.present? ? banner_image.url : consultation.banner_image.url
|
81
|
+
end
|
82
|
+
|
83
|
+
# Public: Check if the user has voted the question.
|
84
|
+
#
|
85
|
+
# Returns Boolean.
|
86
|
+
def voted_by?(user)
|
87
|
+
votes.where(author: user).any?
|
88
|
+
end
|
89
|
+
|
90
|
+
def scopes_enabled?
|
91
|
+
false
|
92
|
+
end
|
93
|
+
|
94
|
+
def scopes_enabled
|
95
|
+
false
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_param
|
99
|
+
slug
|
100
|
+
end
|
101
|
+
|
102
|
+
# Overrides module name from participable concern
|
103
|
+
def module_name
|
104
|
+
"Decidim::Consultations"
|
105
|
+
end
|
106
|
+
|
107
|
+
def mounted_engine
|
108
|
+
"decidim_consultations"
|
109
|
+
end
|
110
|
+
|
111
|
+
def mounted_admin_engine
|
112
|
+
"decidim_admin_consultations"
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.participatory_space_manifest
|
116
|
+
Decidim.find_participatory_space_manifest(Decidim::Consultation.name.demodulize.underscore.pluralize)
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.order_randomly(seed)
|
120
|
+
transaction do
|
121
|
+
connection.execute("SELECT setseed(#{connection.quote(seed)})")
|
122
|
+
select('"decidim_consultations_questions".*, RANDOM()').order("RANDOM()").load
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
class Response < ApplicationRecord
|
6
|
+
belongs_to :question,
|
7
|
+
foreign_key: "decidim_consultations_questions_id",
|
8
|
+
class_name: "Decidim::Consultations::Question",
|
9
|
+
counter_cache: :responses_count,
|
10
|
+
inverse_of: :responses
|
11
|
+
|
12
|
+
has_many :votes,
|
13
|
+
foreign_key: "decidim_consultations_response_id",
|
14
|
+
class_name: "Decidim::Consultations::Vote",
|
15
|
+
inverse_of: :response,
|
16
|
+
dependent: :restrict_with_error
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
# The data store for question's votes in the Decidim::Consultations component.
|
6
|
+
class Vote < ApplicationRecord
|
7
|
+
include Authorable
|
8
|
+
|
9
|
+
belongs_to :question,
|
10
|
+
foreign_key: "decidim_consultation_question_id",
|
11
|
+
class_name: "Decidim::Consultations::Question",
|
12
|
+
counter_cache: :votes_count,
|
13
|
+
inverse_of: :votes
|
14
|
+
|
15
|
+
belongs_to :response,
|
16
|
+
foreign_key: "decidim_consultations_response_id",
|
17
|
+
class_name: "Decidim::Consultations::Response",
|
18
|
+
inverse_of: :votes,
|
19
|
+
counter_cache: :votes_count
|
20
|
+
|
21
|
+
validates :author, uniqueness: { scope: [:decidim_user_group_id, :question] }
|
22
|
+
|
23
|
+
delegate :organization, to: :question
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
# A presenter to render statistics in the homepage.
|
6
|
+
class QuestionStatsPresenter < Rectify::Presenter
|
7
|
+
attribute :question, Decidim::Consultations::Question
|
8
|
+
|
9
|
+
def supports_count
|
10
|
+
question.votes_count
|
11
|
+
end
|
12
|
+
|
13
|
+
def comments_count
|
14
|
+
Rails.cache.fetch(
|
15
|
+
"question/#{question.id}/comments_count",
|
16
|
+
expires_in: Decidim::Consultations.stats_cache_expiration_time
|
17
|
+
) do
|
18
|
+
Decidim::Comments::Comment.where(root_commentable: question).count
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def meetings_count
|
23
|
+
Rails.cache.fetch(
|
24
|
+
"question/#{question.id}/meetings_count",
|
25
|
+
expires_in: Decidim::Consultations.stats_cache_expiration_time
|
26
|
+
) do
|
27
|
+
Decidim::Meetings::Meeting.where(component: meetings_component).count
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def assistants_count
|
32
|
+
Rails.cache.fetch(
|
33
|
+
"question/#{question.id}/assistants_count",
|
34
|
+
expires_in: Decidim::Consultations.stats_cache_expiration_time
|
35
|
+
) do
|
36
|
+
result = 0
|
37
|
+
Decidim::Meetings::Meeting.where(component: meetings_component).each do |meeting|
|
38
|
+
result += meeting.attendees_count || 0
|
39
|
+
end
|
40
|
+
|
41
|
+
result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def meetings_component
|
48
|
+
@meetings_component ||= Decidim::Component.find_by(participatory_space: question, manifest_name: "meetings")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
module Admin
|
6
|
+
# A class used to find the admins for a participatory process including
|
7
|
+
# organization admins.
|
8
|
+
class AdminUsers < Rectify::Query
|
9
|
+
# Syntactic sugar to initialize the class and return the queried objects.
|
10
|
+
#
|
11
|
+
# consultation - a process that needs to find its process admins
|
12
|
+
def self.for(consultation)
|
13
|
+
new(consultation).query
|
14
|
+
end
|
15
|
+
|
16
|
+
# Initializes the class.
|
17
|
+
#
|
18
|
+
# consultation - a consultation that needs to find its process admins
|
19
|
+
def initialize(consultation)
|
20
|
+
@consultation = consultation
|
21
|
+
end
|
22
|
+
|
23
|
+
# Finds organization admins and the users with role admin for the given process.
|
24
|
+
#
|
25
|
+
# Returns an ActiveRecord::Relation.
|
26
|
+
def query
|
27
|
+
Decidim::User.where(id: organization_admins)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :consultation
|
33
|
+
|
34
|
+
def organization_admins
|
35
|
+
consultation.organization.admins
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
# This query class filters all consultations given an organization.
|
6
|
+
class OrganizationActiveConsultations < Rectify::Query
|
7
|
+
def self.for(organization)
|
8
|
+
new(organization).query
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(organization)
|
12
|
+
@organization = organization
|
13
|
+
end
|
14
|
+
|
15
|
+
def query
|
16
|
+
Decidim::Consultation.where(organization: @organization).active
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|