decidim-assemblies 0.22.0 → 0.23.0
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/commands/decidim/assemblies/admin/import_assembly.rb +72 -0
- data/app/commands/decidim/assemblies/admin/update_assembly.rb +10 -5
- data/app/controllers/decidim/assemblies/admin/assembly_exports_controller.rb +24 -0
- data/app/controllers/decidim/assemblies/admin/assembly_imports_controller.rb +31 -0
- data/app/controllers/decidim/assemblies/admin/assembly_user_roles_controller.rb +2 -1
- data/app/controllers/decidim/assemblies/{assembly_widgets_controller.rb → widgets_controller.rb} +2 -2
- data/app/forms/decidim/assemblies/admin/assembly_form.rb +5 -6
- data/app/forms/decidim/assemblies/admin/assembly_import_form.rb +83 -0
- data/app/forms/decidim/assemblies/admin/assembly_user_role_form.rb +8 -2
- data/app/models/decidim/assemblies_type.rb +3 -0
- data/app/models/decidim/assembly.rb +14 -1
- data/app/permissions/decidim/assemblies/permissions.rb +5 -1
- data/app/presenters/decidim/assemblies/assembly_presenter.rb +29 -0
- data/app/serializers/decidim/assemblies/assembly_importer.rb +172 -0
- data/app/serializers/decidim/assemblies/assembly_serializer.rb +147 -0
- data/app/views/decidim/assemblies/admin/assemblies/index.html.erb +10 -0
- data/app/views/decidim/assemblies/admin/assembly_imports/_form.html.erb +46 -0
- data/app/views/decidim/assemblies/admin/assembly_imports/new.html.erb +7 -0
- data/app/views/decidim/assemblies/assemblies/show.html.erb +1 -1
- data/app/views/layouts/decidim/assembly.html.erb +1 -0
- data/config/locales/am-ET.yml +1 -0
- data/config/locales/bg.yml +7 -0
- data/config/locales/ca.yml +24 -2
- data/config/locales/cs.yml +29 -7
- data/config/locales/da.yml +1 -0
- data/config/locales/de.yml +19 -0
- data/config/locales/el.yml +19 -0
- data/config/locales/en.yml +22 -0
- data/config/locales/eo.yml +1 -0
- data/config/locales/es-MX.yml +22 -0
- data/config/locales/es-PY.yml +22 -0
- data/config/locales/es.yml +24 -2
- data/config/locales/et.yml +1 -0
- data/config/locales/fi-plain.yml +19 -0
- data/config/locales/fi.yml +22 -3
- data/config/locales/fr-CA.yml +22 -0
- data/config/locales/fr.yml +22 -0
- data/config/locales/hr.yml +1 -0
- data/config/locales/hu.yml +18 -0
- data/config/locales/is.yml +263 -0
- data/config/locales/it.yml +19 -0
- data/config/locales/ja-JP.yml +145 -126
- data/config/locales/ja.yml +471 -0
- data/config/locales/ko-KR.yml +1 -0
- data/config/locales/ko.yml +1 -0
- data/config/locales/lt.yml +1 -0
- data/config/locales/{lv-LV.yml → lv.yml} +0 -0
- data/config/locales/mt.yml +1 -0
- data/config/locales/nl.yml +19 -0
- data/config/locales/no.yml +19 -0
- data/config/locales/om-ET.yml +1 -0
- data/config/locales/pl.yml +37 -18
- data/config/locales/pt.yml +19 -0
- data/config/locales/ro-RO.yml +19 -0
- data/config/locales/sl.yml +151 -0
- data/config/locales/so-SO.yml +1 -0
- data/config/locales/sv.yml +22 -0
- data/config/locales/ti-ER.yml +1 -0
- data/config/locales/tr-TR.yml +19 -0
- data/config/locales/vi-VN.yml +1 -0
- data/config/locales/vi.yml +1 -0
- data/config/locales/zh-CN.yml +471 -0
- data/config/locales/zh-TW.yml +1 -0
- data/lib/decidim/assemblies/admin_engine.rb +7 -0
- data/lib/decidim/assemblies/engine.rb +1 -1
- data/lib/decidim/assemblies/participatory_space.rb +20 -12
- data/lib/decidim/assemblies/test/factories.rb +3 -3
- data/lib/decidim/assemblies/version.rb +1 -1
- metadata +40 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f90272251f859f41475c2a14ccabe76407813af129f68a51e54438ffb3dbd178
|
4
|
+
data.tar.gz: 2c41b75a95d4c7b2495284ab2f07237fe5dda00e50a7459907a7b3806e02d7c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0769b33cab3e6bbb109cab7dbe97dcf3b6dc706e84d03daf7d517e191bb1b668829cf8ce397884a435506a2162f87efbeda72ee10ce2bd3d74fefa7b6cdf488
|
7
|
+
data.tar.gz: c360b08448a62c35af14e46c917f8c9ea0128bef9ce58559aa5bd9eae8f233b826df0a9f04090f7adea3608b46419201fd2a8a9c37389fb903dec7a933efc113
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Assemblies
|
5
|
+
module Admin
|
6
|
+
# A command with all the business logic to import a new assembly
|
7
|
+
# in the system.
|
8
|
+
class ImportAssembly < Rectify::Command
|
9
|
+
# Public: Initializes the command.
|
10
|
+
#
|
11
|
+
# form - A form object with the params.
|
12
|
+
# assembly - An assembly we want to duplicate
|
13
|
+
def initialize(form)
|
14
|
+
@form = form
|
15
|
+
end
|
16
|
+
|
17
|
+
# Executes the command. Broadcasts these events:
|
18
|
+
#
|
19
|
+
# - :ok when everything is valid.
|
20
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
21
|
+
#
|
22
|
+
# Returns nothing.
|
23
|
+
def call
|
24
|
+
return broadcast(:invalid) if form.invalid?
|
25
|
+
|
26
|
+
transaction do
|
27
|
+
import_assembly
|
28
|
+
add_admins_as_followers(@imported_assembly)
|
29
|
+
end
|
30
|
+
|
31
|
+
broadcast(:ok, @imported_assembly)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :form
|
37
|
+
|
38
|
+
def import_assembly
|
39
|
+
importer = Decidim::Assemblies::AssemblyImporter.new(form.current_organization, form.current_user)
|
40
|
+
assemblies.each do |original_assembly|
|
41
|
+
@imported_assembly = importer.import(original_assembly, form.current_user, title: form.title, slug: form.slug)
|
42
|
+
importer.import_assemblies_type(original_assembly["decidim_assemblies_type_id"])
|
43
|
+
importer.import_categories(original_assembly["assembly_categories"]) if form.import_categories?
|
44
|
+
importer.import_folders_and_attachments(original_assembly["attachments"]) if form.import_attachments?
|
45
|
+
importer.import_components(original_assembly["components"]) if form.import_components?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def assemblies
|
50
|
+
document_parsed(form.document_text)
|
51
|
+
end
|
52
|
+
|
53
|
+
def document_parsed(document_text)
|
54
|
+
JSON.parse(document_text)
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_admins_as_followers(assembly)
|
58
|
+
assembly.organization.admins.each do |admin|
|
59
|
+
form = Decidim::FollowForm
|
60
|
+
.from_params(followable_gid: assembly.to_signed_global_id.to_s)
|
61
|
+
.with_context(
|
62
|
+
current_organization: assembly.organization,
|
63
|
+
current_user: admin
|
64
|
+
)
|
65
|
+
|
66
|
+
Decidim::CreateFollow.new(form, admin).call
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -62,10 +62,6 @@ module Decidim
|
|
62
62
|
subtitle: form.subtitle,
|
63
63
|
slug: form.slug,
|
64
64
|
hashtag: form.hashtag,
|
65
|
-
hero_image: form.hero_image,
|
66
|
-
remove_hero_image: form.remove_hero_image,
|
67
|
-
banner_image: form.banner_image,
|
68
|
-
remove_banner_image: form.remove_banner_image,
|
69
65
|
promoted: form.promoted,
|
70
66
|
description: form.description,
|
71
67
|
short_description: form.short_description,
|
@@ -99,7 +95,16 @@ module Decidim
|
|
99
95
|
instagram_handler: form.instagram_handler,
|
100
96
|
youtube_handler: form.youtube_handler,
|
101
97
|
github_handler: form.github_handler
|
102
|
-
}
|
98
|
+
}.merge(uploader_attributes)
|
99
|
+
end
|
100
|
+
|
101
|
+
def uploader_attributes
|
102
|
+
{
|
103
|
+
hero_image: form.hero_image,
|
104
|
+
remove_hero_image: form.remove_hero_image,
|
105
|
+
banner_image: form.banner_image,
|
106
|
+
remove_banner_image: form.remove_banner_image
|
107
|
+
}.delete_if { |_k, val| val.is_a?(Decidim::ApplicationUploader) }
|
103
108
|
end
|
104
109
|
|
105
110
|
def participatory_processes(assembly)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Assemblies
|
5
|
+
module Admin
|
6
|
+
class AssemblyExportsController < Decidim::Admin::ApplicationController
|
7
|
+
include Concerns::AssemblyAdmin
|
8
|
+
include Decidim::Admin::ParticipatorySpaceExport
|
9
|
+
|
10
|
+
def exportable_space
|
11
|
+
current_assembly
|
12
|
+
end
|
13
|
+
|
14
|
+
def manifest_name
|
15
|
+
current_assembly.manifest.name.to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def after_export_path
|
19
|
+
assembly_path(current_assembly.slug)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Assemblies
|
5
|
+
module Admin
|
6
|
+
class AssemblyImportsController < Decidim::Assemblies::Admin::ApplicationController
|
7
|
+
def new
|
8
|
+
enforce_permission_to :import, :assembly
|
9
|
+
@form = form(AssemblyImportForm).instance
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
enforce_permission_to :import, :assembly
|
14
|
+
@form = form(AssemblyImportForm).from_params(params)
|
15
|
+
|
16
|
+
ImportAssembly.call(@form) do
|
17
|
+
on(:ok) do
|
18
|
+
flash[:notice] = I18n.t("assembly_imports.create.success", scope: "decidim.admin")
|
19
|
+
redirect_to assemblies_path
|
20
|
+
end
|
21
|
+
|
22
|
+
on(:invalid) do
|
23
|
+
flash.now[:alert] = I18n.t("assembly_imports.create.error", scope: "decidim.admin")
|
24
|
+
render :new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -25,12 +25,13 @@ module Decidim
|
|
25
25
|
CreateAssemblyAdmin.call(@form, current_user, current_assembly) do
|
26
26
|
on(:ok) do
|
27
27
|
flash[:notice] = I18n.t("assembly_user_roles.create.success", scope: "decidim.admin")
|
28
|
+
redirect_to assembly_user_roles_path(current_assembly)
|
28
29
|
end
|
29
30
|
|
30
31
|
on(:invalid) do
|
31
32
|
flash[:alert] = I18n.t("assembly_user_roles.create.error", scope: "decidim.admin")
|
33
|
+
render :new
|
32
34
|
end
|
33
|
-
redirect_to assembly_user_roles_path(current_assembly)
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
data/app/controllers/decidim/assemblies/{assembly_widgets_controller.rb → widgets_controller.rb}
RENAMED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Decidim
|
4
4
|
module Assemblies
|
5
|
-
class
|
5
|
+
class WidgetsController < Decidim::WidgetsController
|
6
6
|
helper Decidim::SanitizeHelper
|
7
7
|
|
8
8
|
private
|
@@ -16,7 +16,7 @@ module Decidim
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def iframe_url
|
19
|
-
@iframe_url ||=
|
19
|
+
@iframe_url ||= assembly_widget_url(model)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -8,6 +8,7 @@ module Decidim
|
|
8
8
|
#
|
9
9
|
class AssemblyForm < Form
|
10
10
|
include TranslatableAttributes
|
11
|
+
include Decidim::HasUploadValidations
|
11
12
|
|
12
13
|
CREATED_BY = %w(city_council public others).freeze
|
13
14
|
|
@@ -75,12 +76,10 @@ module Decidim
|
|
75
76
|
validates :created_by_other, translatable_presence: true, if: ->(form) { form.created_by == "others" }
|
76
77
|
validates :title, :subtitle, :description, :short_description, translatable_presence: true
|
77
78
|
|
78
|
-
validates :banner_image,
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
file_size: { less_than_or_equal_to: ->(_record) { Decidim.maximum_attachment_size } },
|
83
|
-
file_content_type: { allow: ["image/jpeg", "image/png"] }
|
79
|
+
validates :banner_image, passthru: { to: Decidim::Assembly }
|
80
|
+
validates :hero_image, passthru: { to: Decidim::Assembly }
|
81
|
+
|
82
|
+
alias organization current_organization
|
84
83
|
|
85
84
|
def ensure_parent_cannot_be_child
|
86
85
|
return if id.blank?
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Assemblies
|
5
|
+
module Admin
|
6
|
+
# A form object used to import an assembly from the admin
|
7
|
+
# dashboard.
|
8
|
+
#
|
9
|
+
class AssemblyImportForm < Form
|
10
|
+
include TranslatableAttributes
|
11
|
+
|
12
|
+
JSON_MIME_TYPE = "application/json"
|
13
|
+
# Accepted mime types
|
14
|
+
# keys: are used for dynamic help text on admin form.
|
15
|
+
# values: are used to validate the file format of imported document.
|
16
|
+
#
|
17
|
+
# WARNING: consider adding/removing the relative translation key at
|
18
|
+
# decidim.assemblies.admin.new_import.accepted_types when modifying this hash
|
19
|
+
ACCEPTED_TYPES = {
|
20
|
+
json: JSON_MIME_TYPE
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
translatable_attribute :title, String
|
24
|
+
|
25
|
+
mimic :assembly
|
26
|
+
|
27
|
+
attribute :slug, String
|
28
|
+
attribute :import_steps, Boolean, default: false
|
29
|
+
attribute :import_categories, Boolean, default: true
|
30
|
+
attribute :import_attachments, Boolean, default: true
|
31
|
+
attribute :import_components, Boolean, default: true
|
32
|
+
attribute :document
|
33
|
+
|
34
|
+
validates :document, presence: true
|
35
|
+
|
36
|
+
validates :slug, presence: true, format: { with: Decidim::Assembly.slug_format }
|
37
|
+
validates :title, translatable_presence: true
|
38
|
+
validate :slug_uniqueness
|
39
|
+
|
40
|
+
validate :document_type_must_be_valid, if: :document
|
41
|
+
|
42
|
+
def document_text
|
43
|
+
@document_text ||= document&.read
|
44
|
+
end
|
45
|
+
|
46
|
+
def document_type_must_be_valid
|
47
|
+
return if valid_mime_types.include?(document_type)
|
48
|
+
|
49
|
+
errors.add(:document, i18n_invalid_document_type_text)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Return ACCEPTED_MIME_TYPES plus `text/plain` for better markdown support
|
53
|
+
def valid_mime_types
|
54
|
+
ACCEPTED_TYPES.values
|
55
|
+
end
|
56
|
+
|
57
|
+
def document_type
|
58
|
+
document.content_type
|
59
|
+
end
|
60
|
+
|
61
|
+
def i18n_invalid_document_type_text
|
62
|
+
I18n.t("invalid_document_type",
|
63
|
+
scope: "activemodel.errors.models.assembly.attributes.document",
|
64
|
+
valid_mime_types: i18n_valid_mime_types_text)
|
65
|
+
end
|
66
|
+
|
67
|
+
def i18n_valid_mime_types_text
|
68
|
+
ACCEPTED_TYPES.keys.map do |mime_type|
|
69
|
+
I18n.t(mime_type, scope: "decidim.assemblies.admin.new_import.accepted_types")
|
70
|
+
end.join(", ")
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def slug_uniqueness
|
76
|
+
return unless OrganizationAssemblies.new(current_organization).query.where(slug: slug).where.not(id: id).any?
|
77
|
+
|
78
|
+
errors.add(:slug, :taken)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -12,10 +12,12 @@ module Decidim
|
|
12
12
|
attribute :email, String
|
13
13
|
attribute :role, String
|
14
14
|
|
15
|
-
validates :email, :role, presence: true
|
16
|
-
validates :name, presence: true
|
15
|
+
validates :name, :email, :role, presence: true
|
17
16
|
validates :role, inclusion: { in: Decidim::AssemblyUserRole::ROLES }
|
18
17
|
|
18
|
+
validates :name, format: { with: UserBaseEntity::REGEXP_NAME }
|
19
|
+
validate :admin_uniqueness
|
20
|
+
|
19
21
|
def roles
|
20
22
|
Decidim::AssemblyUserRole::ROLES.map do |role|
|
21
23
|
[
|
@@ -24,6 +26,10 @@ module Decidim
|
|
24
26
|
]
|
25
27
|
end
|
26
28
|
end
|
29
|
+
|
30
|
+
def admin_uniqueness
|
31
|
+
errors.add(:email, :taken) if context && context.current_organization && context.current_organization.admins.where(email: email).exists?
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
@@ -24,7 +24,7 @@ module Decidim
|
|
24
24
|
include Decidim::HasAttachmentCollections
|
25
25
|
include Decidim::Participable
|
26
26
|
include Decidim::Publicable
|
27
|
-
include Decidim::
|
27
|
+
include Decidim::ScopableParticipatorySpace
|
28
28
|
include Decidim::Followable
|
29
29
|
include Decidim::HasReference
|
30
30
|
include Decidim::Traceable
|
@@ -32,10 +32,16 @@ module Decidim
|
|
32
32
|
include Decidim::ParticipatorySpaceResourceable
|
33
33
|
include Decidim::HasPrivateUsers
|
34
34
|
include Decidim::Searchable
|
35
|
+
include Decidim::HasUploadValidations
|
36
|
+
include Decidim::TranslatableResource
|
35
37
|
|
36
38
|
SOCIAL_HANDLERS = [:twitter, :facebook, :instagram, :youtube, :github].freeze
|
37
39
|
CREATED_BY = %w(city_council public others).freeze
|
38
40
|
|
41
|
+
translatable_fields :title, :subtitle, :short_description, :description, :developer_group, :meta_scope, :local_area,
|
42
|
+
:target, :participatory_scope, :participatory_structure, :purpose_of_action, :composition, :created_by_other,
|
43
|
+
:closing_date_reason, :internal_organisation, :special_features
|
44
|
+
|
39
45
|
belongs_to :organization,
|
40
46
|
foreign_key: "decidim_organization_id",
|
41
47
|
class_name: "Decidim::Organization"
|
@@ -63,7 +69,10 @@ module Decidim
|
|
63
69
|
has_many :children, foreign_key: "parent_id", class_name: "Decidim::Assembly", inverse_of: :parent, dependent: :destroy
|
64
70
|
belongs_to :parent, foreign_key: "parent_id", class_name: "Decidim::Assembly", inverse_of: :children, optional: true, counter_cache: :children_count
|
65
71
|
|
72
|
+
validates_upload :hero_image
|
66
73
|
mount_uploader :hero_image, Decidim::HeroImageUploader
|
74
|
+
|
75
|
+
validates_upload :banner_image
|
67
76
|
mount_uploader :banner_image, Decidim::BannerImageUploader
|
68
77
|
|
69
78
|
validates :slug, uniqueness: { scope: :organization }
|
@@ -158,6 +167,10 @@ module Decidim
|
|
158
167
|
roles.where(role: role_name)
|
159
168
|
end
|
160
169
|
|
170
|
+
def attachment_context
|
171
|
+
:admin
|
172
|
+
end
|
173
|
+
|
161
174
|
private
|
162
175
|
|
163
176
|
# When an assembly changes their parent, we need to update the parents_path attribute
|
@@ -249,7 +249,9 @@ module Decidim
|
|
249
249
|
:assembly,
|
250
250
|
:assembly_user_role,
|
251
251
|
:assembly_member,
|
252
|
-
:space_private_user
|
252
|
+
:space_private_user,
|
253
|
+
:export_space,
|
254
|
+
:import
|
253
255
|
].include?(permission_action.subject)
|
254
256
|
allow! if is_allowed
|
255
257
|
end
|
@@ -268,6 +270,8 @@ module Decidim
|
|
268
270
|
:assembly_user_role,
|
269
271
|
:assembly_member,
|
270
272
|
:space_private_user,
|
273
|
+
:export_space,
|
274
|
+
:import,
|
271
275
|
:assemblies_setting
|
272
276
|
].include?(permission_action.subject)
|
273
277
|
allow! if is_allowed
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Assemblies
|
5
|
+
class AssemblyPresenter < SimpleDelegator
|
6
|
+
include Rails.application.routes.mounted_helpers
|
7
|
+
include ActionView::Helpers::UrlHelper
|
8
|
+
|
9
|
+
delegate :url, to: :hero_image, prefix: true
|
10
|
+
delegate :url, to: :banner_image, prefix: true
|
11
|
+
|
12
|
+
def hero_image_url
|
13
|
+
return if assembly.hero_image.blank?
|
14
|
+
|
15
|
+
URI.join(decidim.root_url(host: assembly.organization.host), assembly.hero_image_url).to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def banner_image_url
|
19
|
+
return if assembly.banner_image.blank?
|
20
|
+
|
21
|
+
URI.join(decidim.root_url(host: assembly.organization.host), assembly.banner_image_url).to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
def assembly
|
25
|
+
__getobj__
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|