decidim-core 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/decidim/modules/_card-grid.scss +2 -2
- data/app/assets/stylesheets/decidim/modules/_filters.scss +3 -3
- data/app/assets/stylesheets/decidim/modules/_main-container.scss +1 -5
- data/app/assets/stylesheets/decidim/modules/_process-nav.scss +1 -2
- data/app/constraints/decidim/current_participatory_process.rb +1 -1
- data/app/controllers/concerns/decidim/needs_authorization.rb +2 -3
- data/app/controllers/concerns/decidim/needs_participatory_process.rb +1 -1
- data/app/controllers/concerns/decidim/{feature_settings.rb → settings.rb} +1 -1
- data/app/controllers/decidim/features/base_controller.rb +1 -2
- data/app/controllers/decidim/pages_controller.rb +1 -1
- data/app/helpers/decidim/feature_path_helper.rb +1 -1
- data/{lib → app/models}/decidim/abilities/admin_ability.rb +1 -0
- data/app/models/decidim/abilities/base_ability.rb +34 -0
- data/{lib → app/models}/decidim/abilities/participatory_process_admin_ability.rb +4 -0
- data/{lib → app/models}/decidim/abilities/participatory_process_collaborator_ability.rb +4 -0
- data/{lib → app/models}/decidim/abilities/participatory_process_moderator_ability.rb +0 -0
- data/app/models/decidim/feature.rb +3 -78
- data/app/models/decidim/organization.rb +0 -2
- data/app/models/decidim/participatory_process.rb +2 -16
- data/app/models/decidim/participatory_process_group.rb +1 -2
- data/app/models/decidim/participatory_process_user_role.rb +9 -0
- data/app/models/decidim/user.rb +0 -7
- data/app/presenters/decidim/home_stats_presenter.rb +1 -1
- data/app/presenters/decidim/resource_locator_presenter.rb +57 -15
- data/app/queries/decidim/highlighted_participatory_processes.rb +1 -2
- data/app/queries/decidim/organization_participatory_process_groups.rb +14 -0
- data/app/queries/decidim/organization_participatory_processes.rb +2 -6
- data/app/queries/decidim/organization_prioritized_participatory_processes.rb +3 -3
- data/app/queries/decidim/organization_published_participatory_processes.rb +17 -0
- data/app/queries/decidim/participatory_processes_with_user_role.rb +1 -1
- data/app/queries/decidim/prioritized_participatory_processes.rb +1 -1
- data/app/queries/decidim/published_participatory_processes.rb +10 -0
- data/app/views/layouts/decidim/_process_header.html.erb +2 -2
- data/config/locales/ca.yml +19 -0
- data/config/locales/es.yml +19 -0
- data/config/locales/fr.yml +2 -2
- data/db/migrate/20170608142521_add_organization_to_user_groups.rb +16 -3
- data/db/seeds.rb +17 -12
- data/lib/decidim/abilities.rb +0 -4
- data/lib/decidim/abilities/participatory_process_role_ability.rb +4 -1
- data/lib/decidim/core.rb +20 -20
- data/lib/decidim/core/api/decidim_type.rb +1 -1
- data/lib/decidim/core/api/process_step_type.rb +2 -2
- data/lib/decidim/core/api/process_type.rb +1 -1
- data/lib/decidim/core/api/session_type.rb +1 -1
- data/lib/decidim/core/api/translated_field_type.rb +3 -3
- data/lib/decidim/core/test.rb +1 -0
- data/lib/decidim/core/test/factories.rb +21 -2
- data/lib/decidim/core/test/shared_examples/publicable.rb +27 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/feature_manifest.rb +6 -6
- data/lib/decidim/form_builder.rb +1 -1
- data/lib/decidim/has_category.rb +1 -1
- data/lib/decidim/has_settings.rb +66 -0
- data/lib/decidim/manifest_registry.rb +45 -0
- data/lib/decidim/publicable.rb +49 -0
- data/lib/decidim/query_extensions.rb +1 -1
- data/lib/decidim/reportable.rb +3 -3
- data/lib/decidim/{features/settings_manifest.rb → settings_manifest.rb} +5 -5
- metadata +26 -33
- data/app/models/decidim/ability.rb +0 -32
@@ -13,7 +13,10 @@ module Decidim
|
|
13
13
|
# Define abilities if the user is not an admin and has at least one process to manage.
|
14
14
|
if not_admin? && has_manageable_processes?
|
15
15
|
define_abilities
|
16
|
-
|
16
|
+
|
17
|
+
if current_participatory_process && can_manage_process?(current_participatory_process)
|
18
|
+
define_participatory_process_abilities
|
19
|
+
end
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
data/lib/decidim/core.rb
CHANGED
@@ -18,9 +18,11 @@ module Decidim
|
|
18
18
|
autoload :Reportable, "decidim/reportable"
|
19
19
|
autoload :Authorable, "decidim/authorable"
|
20
20
|
autoload :Notifiable, "decidim/notifiable"
|
21
|
+
autoload :Publicable, "decidim/publicable"
|
21
22
|
autoload :Features, "decidim/features"
|
22
23
|
autoload :HasAttachments, "decidim/has_attachments"
|
23
24
|
autoload :FeatureValidator, "decidim/feature_validator"
|
25
|
+
autoload :HasSettings, "decidim/has_settings"
|
24
26
|
autoload :HasFeature, "decidim/has_feature"
|
25
27
|
autoload :HasScope, "decidim/has_scope"
|
26
28
|
autoload :HasCategory, "decidim/has_category"
|
@@ -32,6 +34,7 @@ module Decidim
|
|
32
34
|
autoload :Menu, "decidim/menu"
|
33
35
|
autoload :MenuItem, "decidim/menu_item"
|
34
36
|
autoload :MenuRegistry, "decidim/menu_registry"
|
37
|
+
autoload :ManifestRegistry, "decidim/manifest_registry"
|
35
38
|
autoload :Abilities, "decidim/abilities"
|
36
39
|
|
37
40
|
include ActiveSupport::Configurable
|
@@ -49,7 +52,11 @@ module Decidim
|
|
49
52
|
railtie.load_seed
|
50
53
|
end
|
51
54
|
|
52
|
-
Decidim.
|
55
|
+
Decidim::ParticipatoryProcess.find_each do |process|
|
56
|
+
Decidim.feature_manifests.each do |feature|
|
57
|
+
feature.seed!(process)
|
58
|
+
end
|
59
|
+
end
|
53
60
|
|
54
61
|
I18n.available_locales = original_locale
|
55
62
|
end
|
@@ -62,7 +69,8 @@ module Decidim
|
|
62
69
|
config_accessor :mailer_sender
|
63
70
|
|
64
71
|
# Exposes a configuration option: an Array of `cancancan`'s Ability classes
|
65
|
-
# that will be automatically included to the base `Decidim::
|
72
|
+
# that will be automatically included to the base `Decidim::Abilities::BaseAbility`
|
73
|
+
# class.
|
66
74
|
config_accessor :abilities do
|
67
75
|
[]
|
68
76
|
end
|
@@ -138,19 +146,16 @@ module Decidim
|
|
138
146
|
# name - A Symbol with the feature's unique name.
|
139
147
|
#
|
140
148
|
# Returns nothing.
|
141
|
-
def self.register_feature(name)
|
142
|
-
|
143
|
-
yield(manifest)
|
144
|
-
manifest.validate!
|
145
|
-
feature_manifests << manifest
|
149
|
+
def self.register_feature(name, &block)
|
150
|
+
feature_registry.register(name, &block)
|
146
151
|
end
|
147
152
|
|
148
|
-
# Public: Finds all
|
149
|
-
#
|
153
|
+
# Public: Finds all registered feature manifest's via the `register_feature`
|
154
|
+
# method.
|
150
155
|
#
|
151
156
|
# Returns an Array[FeatureManifest].
|
152
157
|
def self.feature_manifests
|
153
|
-
|
158
|
+
feature_registry.manifests
|
154
159
|
end
|
155
160
|
|
156
161
|
# Public: Finds a feature manifest by the feature's name.
|
@@ -159,8 +164,7 @@ module Decidim
|
|
159
164
|
#
|
160
165
|
# Returns a FeatureManifest if found, nil otherwise.
|
161
166
|
def self.find_feature_manifest(name)
|
162
|
-
name
|
163
|
-
feature_manifests.find { |manifest| manifest.name == name }
|
167
|
+
feature_registry.find(name.to_sym)
|
164
168
|
end
|
165
169
|
|
166
170
|
# Public: Finds a resource manifest by the resource's name.
|
@@ -170,16 +174,12 @@ module Decidim
|
|
170
174
|
#
|
171
175
|
# Returns a ResourceManifest if found, nil otherwise.
|
172
176
|
def self.find_resource_manifest(resource_name_or_klass)
|
173
|
-
|
174
|
-
manifest.model_class == resource_name_or_klass || manifest.name.to_s == resource_name_or_klass.to_s
|
175
|
-
end
|
177
|
+
feature_registry.find_resource_manifest(resource_name_or_klass)
|
176
178
|
end
|
177
179
|
|
178
|
-
#
|
179
|
-
|
180
|
-
|
181
|
-
def self.resource_manifests
|
182
|
-
@resource_manifests ||= feature_manifests.flat_map(&:resource_manifests)
|
180
|
+
# Public: Stores the registry of features
|
181
|
+
def self.feature_registry
|
182
|
+
@feature_registry ||= ManifestRegistry.new(:features)
|
183
183
|
end
|
184
184
|
|
185
185
|
# Public: Stores an instance of StatsRegistry
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Decidim
|
4
|
-
# This type represents a
|
4
|
+
# This type represents a Decidim's global property.
|
5
5
|
DecidimType = GraphQL::ObjectType.define do
|
6
6
|
name "Decidim"
|
7
7
|
description "Decidim's framework-related properties."
|
@@ -9,11 +9,11 @@ module Decidim
|
|
9
9
|
field :id, !types.ID, "The unique ID of this step."
|
10
10
|
|
11
11
|
field :process do
|
12
|
-
type ProcessType
|
12
|
+
type !ProcessType
|
13
13
|
description "The participatory process in which this step belongs to."
|
14
14
|
property :participatory_process
|
15
15
|
end
|
16
16
|
|
17
|
-
field :title, TranslatedFieldType, "The title of this step"
|
17
|
+
field :title, !TranslatedFieldType, "The title of this step"
|
18
18
|
end
|
19
19
|
end
|
@@ -8,7 +8,7 @@ module Decidim
|
|
8
8
|
|
9
9
|
field :id, !types.ID, "The Process' unique ID"
|
10
10
|
|
11
|
-
field :title, TranslatedFieldType, "The title of this process."
|
11
|
+
field :title, !TranslatedFieldType, "The title of this process."
|
12
12
|
|
13
13
|
connection :steps, ProcessStepType.connection_type do
|
14
14
|
description "All the steps of this process."
|
@@ -10,7 +10,7 @@ module Decidim
|
|
10
10
|
resolve ->(obj, _args, _ctx) { obj }
|
11
11
|
end
|
12
12
|
|
13
|
-
field :verifiedUserGroups, !types[UserGroupType], "The current user verified user groups" do
|
13
|
+
field :verifiedUserGroups, !types[!UserGroupType], "The current user verified user groups" do
|
14
14
|
resolve ->(obj, _args, _ctx) { obj.user_groups.verified }
|
15
15
|
end
|
16
16
|
end
|
@@ -7,17 +7,17 @@ module Decidim
|
|
7
7
|
description "A translated field"
|
8
8
|
|
9
9
|
field :locales do
|
10
|
-
type types[types.String]
|
10
|
+
type types[!types.String]
|
11
11
|
description "Lists all the locales in which this translation is available"
|
12
12
|
resolve ->(obj, _args, _ctx) { obj.keys }
|
13
13
|
end
|
14
14
|
|
15
15
|
field :translations do
|
16
|
-
type !types[LocalizedStringType]
|
16
|
+
type !types[!LocalizedStringType]
|
17
17
|
description "All the localized strings for this translation."
|
18
18
|
|
19
19
|
argument :locales do
|
20
|
-
type types[types.String]
|
20
|
+
type types[!types.String]
|
21
21
|
description "A list of locales to scope the translations to."
|
22
22
|
end
|
23
23
|
|
data/lib/decidim/core/test.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "decidim/core/test/shared_examples/authorable"
|
4
|
+
require "decidim/core/test/shared_examples/publicable"
|
4
5
|
require "decidim/core/test/shared_examples/localised_email"
|
5
6
|
require "decidim/core/test/shared_examples/has_attachments"
|
6
7
|
require "decidim/core/test/shared_examples/has_feature"
|
@@ -153,7 +153,11 @@ FactoryGirl.define do
|
|
153
153
|
end
|
154
154
|
|
155
155
|
trait :process_admin do
|
156
|
-
transient
|
156
|
+
transient do
|
157
|
+
participatory_process { create(:participatory_process) }
|
158
|
+
end
|
159
|
+
|
160
|
+
organization { participatory_process.organization }
|
157
161
|
|
158
162
|
after(:create) do |user, evaluator|
|
159
163
|
create :participatory_process_user_role,
|
@@ -162,11 +166,26 @@ FactoryGirl.define do
|
|
162
166
|
role: :admin
|
163
167
|
end
|
164
168
|
end
|
169
|
+
|
170
|
+
trait :process_collaborator do
|
171
|
+
transient do
|
172
|
+
participatory_process { create(:participatory_process) }
|
173
|
+
end
|
174
|
+
|
175
|
+
organization { participatory_process.organization }
|
176
|
+
|
177
|
+
after(:create) do |user, evaluator|
|
178
|
+
create :participatory_process_user_role,
|
179
|
+
user: user,
|
180
|
+
participatory_process: evaluator.participatory_process,
|
181
|
+
role: :collaborator
|
182
|
+
end
|
183
|
+
end
|
165
184
|
end
|
166
185
|
|
167
186
|
factory :participatory_process_user_role, class: Decidim::ParticipatoryProcessUserRole do
|
168
187
|
user
|
169
|
-
participatory_process
|
188
|
+
participatory_process { create :participatory_process, organization: user.organization }
|
170
189
|
role "admin"
|
171
190
|
end
|
172
191
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples_for "publicable" do
|
6
|
+
let(:factory_name) { described_class.name.demodulize.underscore.to_sym }
|
7
|
+
|
8
|
+
let!(:published) do
|
9
|
+
create(factory_name, published_at: Time.zone.now)
|
10
|
+
end
|
11
|
+
|
12
|
+
let!(:unpublished) do
|
13
|
+
create(factory_name, published_at: nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe ".published" do
|
17
|
+
let(:scope) { described_class.send(:published) }
|
18
|
+
|
19
|
+
it { expect(scope).to eq([published]) }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ".unpublished" do
|
23
|
+
let(:scope) { described_class.send(:unpublished) }
|
24
|
+
|
25
|
+
it { expect(scope).to eq([unpublished]) }
|
26
|
+
end
|
27
|
+
end
|
data/lib/decidim/core/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "decidim/
|
3
|
+
require "decidim/settings_manifest"
|
4
4
|
require "decidim/features/export_manifest"
|
5
5
|
|
6
6
|
module Decidim
|
@@ -92,15 +92,15 @@ module Decidim
|
|
92
92
|
# Public: Creates the seeds for this features in order to populate the database.
|
93
93
|
#
|
94
94
|
# Returns nothing.
|
95
|
-
def seed!
|
96
|
-
@seeds&.call
|
95
|
+
def seed!(process)
|
96
|
+
@seeds&.call(process)
|
97
97
|
end
|
98
98
|
|
99
99
|
# Public: Adds configurable attributes for this feature, scoped to a name. It
|
100
|
-
# uses the DSL specified under `Decidim::
|
100
|
+
# uses the DSL specified under `Decidim::SettingsManifest`.
|
101
101
|
#
|
102
102
|
# name - Either `global` or `step`
|
103
|
-
# &block - The DSL present on `Decidim::
|
103
|
+
# &block - The DSL present on `Decidim::SettingsManifest`
|
104
104
|
#
|
105
105
|
# Examples:
|
106
106
|
#
|
@@ -112,7 +112,7 @@ module Decidim
|
|
112
112
|
def settings(name = :global, &block)
|
113
113
|
@settings ||= {}
|
114
114
|
name = name.to_sym
|
115
|
-
settings = (@settings[name] ||=
|
115
|
+
settings = (@settings[name] ||= SettingsManifest.new)
|
116
116
|
yield(settings) if block
|
117
117
|
settings
|
118
118
|
end
|
data/lib/decidim/form_builder.rb
CHANGED
@@ -161,7 +161,7 @@ module Decidim
|
|
161
161
|
# datepicker library
|
162
162
|
def datetime_field(attribute, options = {})
|
163
163
|
value = object.send(attribute)
|
164
|
-
if value
|
164
|
+
if value.present?
|
165
165
|
iso_value = value.strftime("%Y-%m-%dT%H:%M:%S")
|
166
166
|
formatted_value = I18n.localize(value, format: :timepicker)
|
167
167
|
end
|
data/lib/decidim/has_category.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require "active_support/concern"
|
4
4
|
|
5
5
|
module Decidim
|
6
|
-
# A concern with the features needed when you want a model to
|
6
|
+
# A concern with the features needed when you want a model to have a category.
|
7
7
|
module HasCategory
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module HasSettings
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
after_initialize :default_values
|
11
|
+
end
|
12
|
+
|
13
|
+
def settings
|
14
|
+
settings_schema(:global).new(self[:settings]["global"])
|
15
|
+
end
|
16
|
+
|
17
|
+
def settings=(data)
|
18
|
+
self[:settings]["global"] = serialize_settings(settings_schema(:global), data)
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_step_settings
|
22
|
+
settings_schema(:step).new(self[:settings]["default_step"])
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_step_settings=(data)
|
26
|
+
self[:settings]["default_step"] = serialize_settings(settings_schema(:step), data)
|
27
|
+
end
|
28
|
+
|
29
|
+
def step_settings
|
30
|
+
participatory_process.steps.each_with_object({}) do |step, result|
|
31
|
+
result[step.id.to_s] = settings_schema(:step).new(self[:settings].dig("steps", step.id.to_s))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def step_settings=(data)
|
36
|
+
self[:settings]["steps"] = data.each_with_object({}) do |(key, value), result|
|
37
|
+
result[key.to_s] = serialize_settings(settings_schema(:step), value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def active_step_settings
|
42
|
+
active_step = participatory_process.active_step
|
43
|
+
return default_step_settings unless active_step
|
44
|
+
|
45
|
+
step_settings.fetch(active_step.id.to_s)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def serialize_settings(schema, value)
|
51
|
+
if value.respond_to?(:attributes)
|
52
|
+
value.attributes
|
53
|
+
else
|
54
|
+
schema.new(value)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def settings_schema(name)
|
59
|
+
manifest.settings(name.to_sym).schema
|
60
|
+
end
|
61
|
+
|
62
|
+
def default_values
|
63
|
+
self[:settings] ||= {}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
#
|
5
|
+
# Takes care of holding and serving globally registered manifests.
|
6
|
+
#
|
7
|
+
class ManifestRegistry
|
8
|
+
def initialize(entity)
|
9
|
+
@entity = entity
|
10
|
+
end
|
11
|
+
|
12
|
+
def register(name)
|
13
|
+
manifest = manifest_class.new(name: name.to_sym)
|
14
|
+
yield(manifest)
|
15
|
+
manifest.validate!
|
16
|
+
manifests << manifest
|
17
|
+
end
|
18
|
+
|
19
|
+
def manifests
|
20
|
+
@manifests ||= Set.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def find(name)
|
24
|
+
manifests.find { |manifest| manifest.name == name }
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource_manifests
|
28
|
+
@resource_manifests ||= manifests.flat_map(&:resource_manifests)
|
29
|
+
end
|
30
|
+
|
31
|
+
def find_resource_manifest(resource_name_or_klass)
|
32
|
+
resource_manifests.find do |manifest|
|
33
|
+
manifest.model_class == resource_name_or_klass || manifest.name.to_s == resource_name_or_klass.to_s
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def manifest_class
|
40
|
+
case @entity
|
41
|
+
when :features then FeatureManifest
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
# This concern contains the logic related to publication and promotion.
|
7
|
+
module Publicable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
# Public: Scope to return only published records.
|
12
|
+
#
|
13
|
+
# Returns an ActiveRecord::Relation.
|
14
|
+
def published
|
15
|
+
where.not(published_at: nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Public: Scope to return only unpublished records.
|
19
|
+
#
|
20
|
+
# Returns an ActiveRecord::Relation.
|
21
|
+
def unpublished
|
22
|
+
where(published_at: nil)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Public: Checks whether the record has been published or not.
|
27
|
+
#
|
28
|
+
# Returns true if published, false otherwise.
|
29
|
+
def published?
|
30
|
+
published_at.present?
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Public: Publishes this feature
|
35
|
+
#
|
36
|
+
# Returns true if the record was properly saved, false otherwise.
|
37
|
+
def publish!
|
38
|
+
update_attribute(:published_at, Time.current)
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Public: Unpublishes this feature
|
43
|
+
#
|
44
|
+
# Returns true if the record was properly saved, false otherwise.
|
45
|
+
def unpublish!
|
46
|
+
update_attribute(:published_at, nil)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|