decidim-core 0.4.4 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/config/decidim_core_manifest.js +1 -0
- data/app/assets/images/decidim/icons.svg +1 -1
- data/app/assets/javascripts/decidim.js.es6 +3 -0
- data/app/assets/javascripts/decidim/form_filter.component.js.es6 +39 -6
- data/app/assets/javascripts/decidim/form_filter.component.test.js +13 -10
- data/app/assets/javascripts/decidim/impersonation.js.es6 +16 -0
- data/app/assets/javascripts/decidim/select2.field.js.es6 +47 -0
- data/app/assets/javascripts/decidim/select2.js.es6 +8 -0
- data/app/assets/stylesheets/decidim/_decidim.scss +3 -0
- data/app/assets/stylesheets/decidim/extras/_announcement.scss +3 -0
- data/app/assets/stylesheets/decidim/extras/_callout.scss +1 -1
- data/app/assets/stylesheets/decidim/extras/_impersonation-bar.scss +22 -0
- data/app/assets/stylesheets/decidim/extras/_process_stats.scss +1 -1
- data/app/assets/stylesheets/decidim/extras/_proposal_form.scss +7 -0
- data/app/assets/stylesheets/decidim/extras/_reference.scss +1 -1
- data/app/assets/stylesheets/decidim/extras/_register_form.scss +1 -1
- data/app/assets/stylesheets/decidim/extras/_social_icons_mini.scss +1 -1
- data/app/assets/stylesheets/decidim/layouts/_home.scss +1 -1
- data/app/assets/stylesheets/decidim/layouts/_view.scss +1 -1
- data/app/assets/stylesheets/decidim/map.css +1 -1
- data/app/assets/stylesheets/decidim/modules/_author-avatar.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_callout.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_datepicker.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_definition-data.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_extra.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_flag.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_footer.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_forms.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_help.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_pagination.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_process-info.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_reference.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_reveal.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_signup.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_static-pages.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_tags.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_title-action.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_user-form.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_video.scss +1 -1
- data/app/assets/stylesheets/decidim/plugins/_select2.scss +63 -0
- data/app/assets/stylesheets/decidim/utils/_toggle-expand.scss +1 -1
- data/app/commands/decidim/invite_user.rb +5 -2
- data/app/controllers/concerns/decidim/devise_controllers.rb +6 -0
- data/app/controllers/concerns/decidim/impersonate_users.rb +67 -0
- data/app/controllers/concerns/decidim/needs_authorization.rb +0 -4
- data/app/controllers/decidim/application_controller.rb +7 -0
- data/app/controllers/decidim/devise/invitations_controller.rb +7 -0
- data/app/controllers/decidim/errors_controller.rb +1 -1
- data/app/controllers/decidim/features/base_controller.rb +1 -1
- data/app/controllers/decidim/participatory_process_widgets_controller.rb +0 -2
- data/app/controllers/decidim/scopes_controller.rb +29 -0
- data/app/forms/decidim/attachment_form.rb +14 -0
- data/app/forms/decidim/invite_user_form.rb +12 -1
- data/app/helpers/decidim/application_helper.rb +1 -0
- data/app/helpers/decidim/attachments_helper.rb +11 -0
- data/app/helpers/decidim/decidim_form_helper.rb +9 -8
- data/app/helpers/decidim/icon_helper.rb +12 -2
- data/app/helpers/decidim/participatory_process_helper.rb +0 -24
- data/app/helpers/decidim/scopes_helper.rb +15 -0
- data/app/helpers/decidim/translations_helper.rb +1 -1
- data/app/mailers/decidim/reported_mailer.rb +1 -1
- data/app/models/decidim/abilities/admin_ability.rb +1 -0
- data/app/models/decidim/abilities/everyone_ability.rb +2 -0
- data/app/models/decidim/abilities/user_manager_ability.rb +35 -0
- data/app/models/decidim/impersonation_log.rb +35 -0
- data/app/models/decidim/organization.rb +9 -0
- data/app/models/decidim/participatory_process.rb +1 -4
- data/app/models/decidim/scope.rb +65 -1
- data/app/models/decidim/scope_type.rb +16 -0
- data/app/models/decidim/user.rb +35 -4
- data/app/presenters/decidim/participatory_process_stats_presenter.rb +1 -1
- data/app/queries/decidim/freetext_scopes.rb +39 -0
- data/app/services/decidim/resource_search.rb +7 -6
- data/app/uploaders/decidim/attachment_uploader.rb +1 -1
- data/app/views/decidim/account/delete.html.erb +1 -1
- data/app/views/decidim/application/_documents.html.erb +4 -2
- data/app/views/decidim/participatory_processes/_statistics.html.erb +1 -1
- data/app/views/decidim/participatory_processes/show.html.erb +4 -0
- data/app/views/decidim/reported_mailer/hide.html.erb +1 -1
- data/app/views/decidim/reported_mailer/report.html.erb +1 -1
- data/app/views/decidim/shared/_announcement.html.erb +5 -0
- data/app/views/decidim/shared/_feature_announcement.html.erb +5 -0
- data/app/views/decidim/shared/_flag_modal.html.erb +1 -1
- data/app/views/decidim/shared/_tags.html.erb +10 -0
- data/app/views/devise/mailer/invitation_instructions.html.erb +13 -0
- data/app/views/devise/mailer/invitation_instructions.text.erb +11 -0
- data/app/views/layouts/decidim/_application.html.erb +1 -0
- data/app/views/layouts/decidim/_impersonation_warning.html.erb +10 -0
- data/app/views/layouts/decidim/_wrapper.html.erb +1 -1
- data/app/views/pages/home/_statistics.html.erb +1 -1
- data/app/views/pages/home/_sub_hero.html.erb +1 -1
- data/config/locales/ca.yml +10 -1
- data/config/locales/en.yml +9 -0
- data/config/locales/es.yml +10 -1
- data/config/locales/eu.yml +22 -1
- data/config/locales/fi.yml +1 -1
- data/config/locales/fr.yml +60 -0
- data/config/locales/it.yml +1 -1
- data/config/locales/nl.yml +1 -1
- data/config/locales/pl.yml +91 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20170605162500_add_hierarchy_to_scopes.rb +70 -0
- data/db/migrate/20170713131206_add_admin_to_users.rb +6 -1
- data/db/migrate/20170713131308_migrate_user_roles_to_participatory_process_roles.rb +5 -1
- data/db/migrate/20170720135441_add_managed_to_users.rb +7 -0
- data/db/migrate/20170720140610_set_email_unique_in_organization_condition_for_managed_users.rb +12 -0
- data/db/migrate/20170724130558_create_impersonation_logs.rb +15 -0
- data/db/migrate/20170727125445_add_roles_to_users.rb +7 -0
- data/db/migrate/20170804125402_attachment_description_nullable.rb +7 -0
- data/db/migrate/20170808080905_add_announcement_to_participatory_processes.rb +7 -0
- data/db/migrate/20170809084005_add_scopes_enabled_to_participatory_processes.rb +7 -0
- data/db/seeds.rb +34 -10
- data/lib/decidim/core.rb +11 -5
- data/lib/decidim/core/engine.rb +1 -0
- data/lib/decidim/core/test.rb +2 -0
- data/lib/decidim/core/test/factories.rb +59 -22
- data/lib/decidim/core/test/shared_examples/announcements_examples.rb +58 -0
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +15 -29
- data/lib/decidim/core/test/shared_examples/errors.rb +1 -1
- data/lib/decidim/core/test/shared_examples/has_attachments.rb +4 -9
- data/lib/decidim/core/test/shared_examples/manage_moderations_examples.rb +1 -8
- data/lib/decidim/core/test/shared_examples/paginated_resource_examples.rb +2 -2
- data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +33 -0
- data/lib/decidim/core/test/shared_examples/reports_examples.rb +1 -2
- data/lib/decidim/core/version.rb +6 -2
- data/lib/decidim/faker/localized.rb +4 -4
- data/lib/decidim/filter_form_builder.rb +7 -0
- data/lib/decidim/form_builder.rb +34 -5
- data/lib/decidim/scopable.rb +33 -0
- data/lib/decidim/settings_manifest.rb +10 -2
- data/lib/decidim/translatable_attributes.rb +0 -1
- metadata +61 -17
- data/app/helpers/decidim/organization_scopes_helper.rb +0 -42
- data/db/seeds/city3.jpeg +0 -0
- data/lib/tasks/factory_girl.rake +0 -17
@@ -10,8 +10,18 @@ module Decidim
|
|
10
10
|
#
|
11
11
|
# Returns an HTML tag with the icon.
|
12
12
|
def feature_icon(feature)
|
13
|
-
|
14
|
-
|
13
|
+
feature_manifest_icon(feature.manifest)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Public: Returns an icon given an instance of a Feature Manifest. It defaults to
|
17
|
+
# a question mark when no icon is found.
|
18
|
+
#
|
19
|
+
# feature_manifest - The feature manifest to generate the icon for.
|
20
|
+
#
|
21
|
+
# Returns an HTML tag with the icon.
|
22
|
+
def feature_manifest_icon(feature_manifest)
|
23
|
+
if feature_manifest.icon
|
24
|
+
external_icon feature_manifest.icon
|
15
25
|
else
|
16
26
|
icon "question-mark"
|
17
27
|
end
|
@@ -13,29 +13,5 @@ module Decidim
|
|
13
13
|
dates = [participatory_process_step.start_date, participatory_process_step.end_date]
|
14
14
|
dates.map { |date| date ? localize(date.to_date, format: :default) : "?" }.join(" - ")
|
15
15
|
end
|
16
|
-
|
17
|
-
# Public: Returns an icon given an instance of a Feature. It defaults to
|
18
|
-
# a question mark when no icon is found.
|
19
|
-
#
|
20
|
-
# feature - The feature to generate the icon for.
|
21
|
-
#
|
22
|
-
# Returns an HTML tag with the icon.
|
23
|
-
def feature_icon(feature)
|
24
|
-
feature_manifest_icon(feature.manifest)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Public: Returns an icon given an instance of a Feature Manifest. It defaults to
|
28
|
-
# a question mark when no icon is found.
|
29
|
-
#
|
30
|
-
# feature_manifest - The feature manifest to generate the icon for.
|
31
|
-
#
|
32
|
-
# Returns an HTML tag with the icon.
|
33
|
-
def feature_manifest_icon(feature_manifest)
|
34
|
-
if feature_manifest.icon
|
35
|
-
external_icon feature_manifest.icon
|
36
|
-
else
|
37
|
-
icon "question-mark"
|
38
|
-
end
|
39
|
-
end
|
40
16
|
end
|
41
17
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
# A Helper to render scopes, including a global scope, for forms.
|
5
|
+
module ScopesHelper
|
6
|
+
Option = Struct.new(:id, :name)
|
7
|
+
|
8
|
+
# Check whether the resource has a visible scope or not.
|
9
|
+
#
|
10
|
+
# Returns boolean.
|
11
|
+
def has_visible_scopes?(resource)
|
12
|
+
current_participatory_process.scopes_enabled? && !current_participatory_process.scope.present? && resource.scope.present?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -22,7 +22,7 @@ module Decidim
|
|
22
22
|
# available locales by default.
|
23
23
|
#
|
24
24
|
# Returns a Hash with the locales as keys and the translations as values.
|
25
|
-
def multi_translation(key, locales =
|
25
|
+
def multi_translation(key, locales = Decidim.available_locales)
|
26
26
|
locales.each_with_object({}) do |locale, result|
|
27
27
|
I18n.with_locale(locale) do
|
28
28
|
result[locale.to_sym] = I18n.t(key)
|
@@ -36,7 +36,7 @@ module Decidim
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def manage_moderations_url
|
39
|
-
@manage_moderations_url ||= decidim_admin.
|
39
|
+
@manage_moderations_url ||= decidim_admin.moderations_url(@participatory_process.id, host: @organization.host)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Abilities
|
5
|
+
# Defines the abilities for an user with role 'user_manager'.
|
6
|
+
# Intended to be used with `cancancan`.
|
7
|
+
class UserManagerAbility
|
8
|
+
include CanCan::Ability
|
9
|
+
|
10
|
+
attr_reader :user
|
11
|
+
|
12
|
+
def initialize(user, context)
|
13
|
+
@user = user
|
14
|
+
@context = context
|
15
|
+
|
16
|
+
define_abilities if not_admin? && user_manager?
|
17
|
+
end
|
18
|
+
|
19
|
+
def define_abilities
|
20
|
+
can :read, :admin_dashboard
|
21
|
+
can :impersonate, :managed_users
|
22
|
+
end
|
23
|
+
|
24
|
+
# Whether the user is an admin or not.
|
25
|
+
def not_admin?
|
26
|
+
@user && !@user.admin?
|
27
|
+
end
|
28
|
+
|
29
|
+
# Whether the user has the user_manager role or not.
|
30
|
+
def user_manager?
|
31
|
+
@user.role? "user_manager"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
# ImpersonationLogs are created whenever an admin impersonate a managed user
|
5
|
+
class ImpersonationLog < ApplicationRecord
|
6
|
+
SESSION_TIME_IN_MINUTES = 30
|
7
|
+
|
8
|
+
belongs_to :admin, foreign_key: "decidim_admin_id", class_name: "Decidim::User"
|
9
|
+
belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User"
|
10
|
+
|
11
|
+
validate :same_organization, :non_active_impersonation
|
12
|
+
|
13
|
+
scope :active, -> { where(ended_at: nil) }
|
14
|
+
|
15
|
+
def ended?
|
16
|
+
ended_at.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
def expired?
|
20
|
+
expired_at.present?
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def same_organization
|
26
|
+
return if admin&.organization == user&.organization
|
27
|
+
errors.add(:admin, :invalid)
|
28
|
+
end
|
29
|
+
|
30
|
+
def non_active_impersonation
|
31
|
+
return if ended? || expired?
|
32
|
+
errors.add(:admin, :invalid) if Decidim::ImpersonationLog.where(admin: admin).active.any?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -9,7 +9,9 @@ module Decidim
|
|
9
9
|
|
10
10
|
has_many :static_pages, foreign_key: "decidim_organization_id", class_name: "Decidim::StaticPage", inverse_of: :organization
|
11
11
|
has_many :scopes, -> { order(name: :asc) }, foreign_key: "decidim_organization_id", class_name: "Decidim::Scope", inverse_of: :organization
|
12
|
+
has_many :scope_types, -> { order(name: :asc) }, foreign_key: "decidim_organization_id", class_name: "Decidim::ScopeType", inverse_of: :organization
|
12
13
|
has_many :admins, -> { where(admin: true) }, foreign_key: "decidim_organization_id", class_name: "Decidim::User"
|
14
|
+
has_many :users_with_any_role, -> { where.not(roles: []) }, foreign_key: "decidim_organization_id", class_name: "Decidim::User"
|
13
15
|
has_many :users, foreign_key: "decidim_organization_id", class_name: "Decidim::User"
|
14
16
|
|
15
17
|
validates :name, :host, uniqueness: true
|
@@ -21,6 +23,13 @@ module Decidim
|
|
21
23
|
mount_uploader :logo, Decidim::OrganizationLogoUploader
|
22
24
|
mount_uploader :favicon, Decidim::OrganizationFaviconUploader
|
23
25
|
|
26
|
+
# Returns top level scopes for this organization.
|
27
|
+
#
|
28
|
+
# Returns an ActiveRecord::Relation.
|
29
|
+
def top_scopes
|
30
|
+
@top_scopes ||= scopes.top_level
|
31
|
+
end
|
32
|
+
|
24
33
|
def homepage_big_url
|
25
34
|
homepage_image.big.url
|
26
35
|
end
|
@@ -9,6 +9,7 @@ module Decidim
|
|
9
9
|
class ParticipatoryProcess < ApplicationRecord
|
10
10
|
include Decidim::HasAttachments
|
11
11
|
include Decidim::Publicable
|
12
|
+
include Decidim::Scopable
|
12
13
|
|
13
14
|
belongs_to :organization,
|
14
15
|
foreign_key: "decidim_organization_id",
|
@@ -18,10 +19,6 @@ module Decidim
|
|
18
19
|
class_name: "Decidim::ParticipatoryProcessGroup",
|
19
20
|
inverse_of: :participatory_processes,
|
20
21
|
optional: true
|
21
|
-
belongs_to :scope,
|
22
|
-
foreign_key: "decidim_scope_id",
|
23
|
-
class_name: "Decidim::Scope",
|
24
|
-
optional: true
|
25
22
|
has_many :steps,
|
26
23
|
-> { order(position: :asc) },
|
27
24
|
foreign_key: "decidim_participatory_process_id",
|
data/app/models/decidim/scope.rb
CHANGED
@@ -10,6 +10,70 @@ module Decidim
|
|
10
10
|
class_name: "Decidim::Organization",
|
11
11
|
inverse_of: :scopes
|
12
12
|
|
13
|
-
|
13
|
+
belongs_to :scope_type,
|
14
|
+
foreign_key: "scope_type_id",
|
15
|
+
class_name: "Decidim::ScopeType",
|
16
|
+
inverse_of: :scopes,
|
17
|
+
optional: true
|
18
|
+
|
19
|
+
belongs_to :parent,
|
20
|
+
foreign_key: "parent_id",
|
21
|
+
class_name: "Decidim::Scope",
|
22
|
+
inverse_of: :children,
|
23
|
+
optional: true
|
24
|
+
|
25
|
+
has_many :children,
|
26
|
+
foreign_key: "parent_id",
|
27
|
+
class_name: "Decidim::Scope",
|
28
|
+
inverse_of: :parent
|
29
|
+
|
30
|
+
before_validation :update_part_of, on: :update
|
31
|
+
|
32
|
+
validates :name, :code, :organization, presence: true
|
33
|
+
validates :code, uniqueness: { scope: :organization }
|
34
|
+
validate :forbid_cycles
|
35
|
+
|
36
|
+
after_create_commit :create_part_of
|
37
|
+
|
38
|
+
# Scope to return only the top level scopes.
|
39
|
+
#
|
40
|
+
# Returns an ActiveRecord::Relation.
|
41
|
+
def self.top_level
|
42
|
+
where parent_id: nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def descendants
|
46
|
+
organization.scopes.where("? = ANY(decidim_scopes.part_of)", id)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Gets the scopes from the part_of list
|
50
|
+
#
|
51
|
+
# Returns an ActiveRecord::Relation.
|
52
|
+
def part_of_scopes
|
53
|
+
organization.scopes.where(id: part_of)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def forbid_cycles
|
59
|
+
errors.add(:parent_id, :cycle_detected) if parent && parent.part_of.include?(id)
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_part_of
|
63
|
+
self[:part_of] = calculate_part_of
|
64
|
+
save if changed?
|
65
|
+
end
|
66
|
+
|
67
|
+
def update_part_of
|
68
|
+
self[:part_of] = calculate_part_of
|
69
|
+
end
|
70
|
+
|
71
|
+
def calculate_part_of
|
72
|
+
if parent
|
73
|
+
[id] + parent.part_of
|
74
|
+
else
|
75
|
+
[id]
|
76
|
+
end
|
77
|
+
end
|
14
78
|
end
|
15
79
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
# Scope types allows to use different types of scopes in participatory process
|
5
|
+
# (municipalities, provinces, states, countries, etc.)
|
6
|
+
class ScopeType < ApplicationRecord
|
7
|
+
belongs_to :organization,
|
8
|
+
foreign_key: "decidim_organization_id",
|
9
|
+
class_name: "Decidim::Organization",
|
10
|
+
inverse_of: :scope_types
|
11
|
+
|
12
|
+
has_many :scopes, foreign_key: "decidim_scope_type_id", class_name: "Decidim::Scope", inverse_of: :scope_type
|
13
|
+
|
14
|
+
validates :name, presence: true
|
15
|
+
end
|
16
|
+
end
|
data/app/models/decidim/user.rb
CHANGED
@@ -6,6 +6,7 @@ module Decidim
|
|
6
6
|
# A User is a citizen that wants to join the platform to participate.
|
7
7
|
class User < ApplicationRecord
|
8
8
|
MAXIMUM_AVATAR_FILE_SIZE = 5.megabytes
|
9
|
+
ROLES = %w(admin user_manager).freeze
|
9
10
|
|
10
11
|
devise :invitable, :database_authenticatable, :registerable, :confirmable,
|
11
12
|
:recoverable, :rememberable, :trackable, :decidim_validatable,
|
@@ -19,13 +20,16 @@ module Decidim
|
|
19
20
|
has_many :user_groups, through: :memberships, class_name: "Decidim::UserGroup", foreign_key: :decidim_user_group_id
|
20
21
|
|
21
22
|
validates :name, presence: true, unless: -> { deleted? }
|
22
|
-
validates :locale, inclusion: { in:
|
23
|
+
validates :locale, inclusion: { in: Decidim.available_locales.map(&:to_s) }, allow_blank: true
|
23
24
|
validates :tos_agreement, acceptance: true, allow_nil: false, on: :create
|
24
25
|
validates :avatar, file_size: { less_than_or_equal_to: MAXIMUM_AVATAR_FILE_SIZE }
|
25
|
-
validates :email, uniqueness: { scope: :organization }, unless: -> { deleted? }
|
26
|
+
validates :email, uniqueness: { scope: :organization }, unless: -> { deleted? || managed? }
|
27
|
+
validate :all_roles_are_valid
|
28
|
+
|
26
29
|
mount_uploader :avatar, Decidim::AvatarUploader
|
27
30
|
|
28
31
|
scope :not_deleted, -> { where(deleted_at: nil) }
|
32
|
+
scope :managed, -> { where(managed: true) }
|
29
33
|
|
30
34
|
# Public: Allows customizing the invitation instruction email content when
|
31
35
|
# inviting a user.
|
@@ -33,6 +37,21 @@ module Decidim
|
|
33
37
|
# Returns a String.
|
34
38
|
attr_accessor :invitation_instructions
|
35
39
|
|
40
|
+
# Checks if the user has the given `role` or not.
|
41
|
+
#
|
42
|
+
# role - a String or a Symbol that represents the role that is being
|
43
|
+
# checked
|
44
|
+
#
|
45
|
+
# Returns a boolean.
|
46
|
+
def role?(role)
|
47
|
+
roles.include?(role.to_s)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Public: Returns the active role of the user
|
51
|
+
def active_role
|
52
|
+
admin ? "admin" : roles.first
|
53
|
+
end
|
54
|
+
|
36
55
|
# Public: returns the user's name or the default one
|
37
56
|
def name
|
38
57
|
super || I18n.t("decidim.anonymous_user")
|
@@ -60,9 +79,17 @@ module Decidim
|
|
60
79
|
protected
|
61
80
|
|
62
81
|
# Overrides devise email required validation.
|
63
|
-
# If the user has been deleted the email field is not required anymore.
|
82
|
+
# If the user has been deleted or it is managed the email field is not required anymore.
|
64
83
|
def email_required?
|
65
|
-
|
84
|
+
return false if deleted? || managed?
|
85
|
+
super
|
86
|
+
end
|
87
|
+
|
88
|
+
# Overrides devise password required validation.
|
89
|
+
# If the user is managed the password field is not required anymore.
|
90
|
+
def password_required?
|
91
|
+
return false if managed?
|
92
|
+
super
|
66
93
|
end
|
67
94
|
|
68
95
|
private
|
@@ -71,5 +98,9 @@ module Decidim
|
|
71
98
|
def send_devise_notification(notification, *args)
|
72
99
|
devise_mailer.send(notification, self, *args).deliver_later
|
73
100
|
end
|
101
|
+
|
102
|
+
def all_roles_are_valid
|
103
|
+
errors.add(:roles, :invalid) unless roles.all? { |role| ROLES.include?(role) }
|
104
|
+
end
|
74
105
|
end
|
75
106
|
end
|
@@ -4,7 +4,7 @@ module Decidim
|
|
4
4
|
# A presenter to render statistics in the homepage.
|
5
5
|
class ParticipatoryProcessStatsPresenter < Rectify::Presenter
|
6
6
|
attribute :participatory_process, Decidim::ParticipatoryProcess
|
7
|
-
include Decidim::
|
7
|
+
include Decidim::IconHelper
|
8
8
|
|
9
9
|
# Public: Render a collection of primary stats.
|
10
10
|
def highlighted
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
# This query searches scopes by name.
|
5
|
+
class FreetextScopes < Rectify::Query
|
6
|
+
# Syntactic sugar to initialize the class and return the queried objects.
|
7
|
+
#
|
8
|
+
# organization - an Organization context for the scope search
|
9
|
+
# lang - the language code to be used for the search
|
10
|
+
# text - the text to be searched in scopes names
|
11
|
+
# root - root scope
|
12
|
+
def self.for(organization, lang, text, root = nil)
|
13
|
+
new(organization, lang, text, root).query
|
14
|
+
end
|
15
|
+
|
16
|
+
# Initializes the class.
|
17
|
+
#
|
18
|
+
# organization - an Organization context for the scope search
|
19
|
+
# lang - the language code to be used for the search
|
20
|
+
# text - the text to be searched in scopes names
|
21
|
+
def initialize(organization, lang, text, root = nil)
|
22
|
+
@organization = organization
|
23
|
+
@lang = lang
|
24
|
+
@text = text
|
25
|
+
@root = root
|
26
|
+
end
|
27
|
+
|
28
|
+
# Finds scopes in the given organization and language whose name begins with the indicated text.
|
29
|
+
#
|
30
|
+
# Returns an ActiveRecord::Relation.
|
31
|
+
def query
|
32
|
+
if @root
|
33
|
+
@root.descendants.where("name->>? ilike ?", @lang, @text + "%")
|
34
|
+
else
|
35
|
+
@organization.scopes.where("name->>? ilike ?", @lang, @text + "%")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|