decidim-core 0.4.3 → 0.4.4
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/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
|