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
         |