decidim-core 0.20.1 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim-core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/fonts/decidim/Roboto-Regular.eot +0 -0
- data/app/assets/fonts/decidim/Roboto-Regular.svg +10520 -0
- data/app/assets/fonts/decidim/Roboto-Regular.ttf +0 -0
- data/app/assets/fonts/decidim/Roboto-Regular.woff +0 -0
- data/app/assets/fonts/decidim/Roboto-Regular.woff2 +0 -0
- data/app/assets/images/decidim/brands/google.svg +1 -0
- data/app/assets/javascripts/decidim.js.es6 +5 -0
- data/app/assets/javascripts/decidim/check_boxes_tree.js.es6 +190 -0
- data/app/assets/javascripts/decidim/core/bundle.js +1 -1
- data/app/assets/javascripts/decidim/core/bundle.js.map +1 -1
- data/app/assets/javascripts/decidim/delayed.js.es6 +26 -0
- data/app/assets/javascripts/decidim/diff_mode_dropdown.js.es6 +25 -4
- data/app/assets/javascripts/decidim/form_filter.component.js.es6 +86 -38
- data/app/assets/javascripts/decidim/form_filter.component.test.js +40 -6
- data/app/assets/javascripts/decidim/history.js.es6 +16 -1
- data/app/assets/javascripts/decidim/vizzs/orgchart.js.es6 +1 -1
- data/app/assets/stylesheets/decidim/_variables.scss +1 -1
- data/app/assets/stylesheets/decidim/extras/_results-per-page.scss +0 -1
- data/app/assets/stylesheets/decidim/modules/_buttons.scss +76 -3
- data/app/assets/stylesheets/decidim/modules/_comments.scss +78 -2
- data/app/assets/stylesheets/decidim/modules/_filters.scss +36 -2
- data/app/assets/stylesheets/decidim/modules/_layout.scss +13 -0
- data/app/assets/stylesheets/decidim/modules/_modules.scss +1 -0
- data/app/assets/stylesheets/decidim/modules/_navbar.scss +11 -5
- data/app/assets/stylesheets/decidim/modules/_process-stats.scss +53 -0
- data/app/assets/stylesheets/decidim/modules/_status-labels.scss +5 -0
- data/app/assets/stylesheets/decidim/modules/_tags.scss +7 -1
- data/app/assets/stylesheets/decidim/modules/_typography.scss +49 -4
- data/app/assets/stylesheets/decidim/utils/_fontface.scss +10 -0
- data/app/assets/stylesheets/decidim/utils/_toggle-expand.scss +14 -0
- data/app/cells/decidim/activity/show.erb +1 -1
- data/app/cells/decidim/author/profile_inline.erb +2 -2
- data/app/cells/decidim/diff/attribute.erb +15 -5
- data/app/cells/decidim/diff/diff_mode_html.erb +31 -0
- data/app/cells/decidim/diff/diff_split.erb +1 -1
- data/app/cells/decidim/diff/diff_unified.erb +1 -1
- data/app/cells/decidim/diff/show.erb +1 -0
- data/app/cells/decidim/diff_cell.rb +21 -8
- data/app/cells/decidim/follow_button/show.erb +20 -7
- data/app/cells/decidim/navbar_admin_link/show.erb +6 -0
- data/app/cells/decidim/navbar_admin_link_cell.rb +43 -0
- data/app/cells/decidim/tags_cell.rb +2 -2
- data/app/commands/decidim/amendable/accept.rb +9 -4
- data/app/commands/decidim/amendable/publish_draft.rb +5 -0
- data/app/commands/decidim/amendable/reject.rb +5 -0
- data/app/commands/decidim/amendable/withdraw.rb +3 -12
- data/app/commands/decidim/create_registration.rb +5 -6
- data/app/controllers/concerns/decidim/use_organization_time_zone.rb +32 -0
- data/app/controllers/decidim/application_controller.rb +3 -0
- data/app/controllers/decidim/components/base_controller.rb +1 -0
- data/app/controllers/decidim/data_portability_controller.rb +12 -19
- data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +1 -1
- data/app/controllers/decidim/devise/registrations_controller.rb +1 -0
- data/app/controllers/decidim/scopes_controller.rb +41 -7
- data/app/forms/decidim/registration_form.rb +5 -0
- data/app/functions/decidim/core/component_finder_base.rb +33 -0
- data/app/functions/decidim/core/component_list.rb +38 -0
- data/app/functions/decidim/core/component_list_base.rb +61 -0
- data/app/functions/decidim/core/needs_api_filter_and_order.rb +52 -0
- data/app/functions/decidim/core/participatory_space_finder.rb +11 -0
- data/app/functions/decidim/core/participatory_space_finder_base.rb +29 -0
- data/app/functions/decidim/core/participatory_space_list.rb +11 -0
- data/app/functions/decidim/core/participatory_space_list_base.rb +34 -0
- data/app/helpers/decidim/amendments_helper.rb +27 -1
- data/app/helpers/decidim/application_helper.rb +31 -3
- data/app/helpers/decidim/categories_helper.rb +26 -0
- data/app/helpers/decidim/check_boxes_tree_helper.rb +115 -0
- data/app/helpers/decidim/omniauth_helper.rb +6 -13
- data/app/helpers/decidim/resource_versions_helper.rb +29 -0
- data/app/helpers/decidim/rich_text_editor_helper.rb +22 -0
- data/app/helpers/decidim/sanitize_helper.rb +3 -1
- data/app/helpers/decidim/scopes_helper.rb +3 -2
- data/app/jobs/decidim/data_portability_export_job.rb +18 -10
- data/app/jobs/decidim/export_job.rb +1 -1
- data/app/mailers/decidim/export_mailer.rb +9 -5
- data/app/models/decidim/omniauth_provider.rb +28 -0
- data/app/models/decidim/organization.rb +41 -0
- data/app/models/decidim/participatory_space_role_config/admin.rb +8 -0
- data/app/models/decidim/participatory_space_role_config/base.rb +31 -0
- data/app/models/decidim/participatory_space_role_config/collaborator.rb +8 -0
- data/app/models/decidim/participatory_space_role_config/moderator.rb +11 -0
- data/app/models/decidim/participatory_space_role_config/null_object.rb +11 -0
- data/app/models/decidim/participatory_space_role_config/participatory_space_admin.rb +8 -0
- data/app/models/decidim/participatory_space_role_config/valuator.rb +11 -0
- data/app/models/decidim/scope.rb +4 -2
- data/app/models/decidim/user.rb +19 -3
- data/app/presenters/decidim/home_stats_presenter.rb +5 -2
- data/app/presenters/decidim/resource_locator_presenter.rb +9 -0
- data/app/serializers/decidim/exporters/participatory_space_components_serializer.rb +1 -1
- data/app/serializers/decidim/importers/participatory_space_components_importer.rb +14 -5
- data/app/services/decidim/data_portability_exporter.rb +72 -0
- data/app/services/decidim/resource_search.rb +29 -13
- data/app/services/decidim/zip_stream/zip_stream_writer.rb +56 -0
- data/app/types/decidim/core/amendment_type.rb +26 -0
- data/app/types/decidim/core/area_api_type.rb +16 -0
- data/app/types/decidim/core/area_type_type.rb +14 -0
- data/app/types/decidim/core/base_input_filter.rb +8 -0
- data/app/types/decidim/core/base_input_sort.rb +22 -0
- data/app/types/decidim/core/component_input_filter.rb +50 -0
- data/app/types/decidim/core/component_input_sort.rb +32 -0
- data/app/types/decidim/core/fingerprint_type.rb +15 -0
- data/app/types/decidim/core/has_hastaggable_input_filter.rb +15 -0
- data/app/types/decidim/core/has_localized_input_filter.rb +21 -0
- data/app/types/decidim/core/has_localized_input_sort.rb +21 -0
- data/app/types/decidim/core/has_publishable_input_filter.rb +34 -0
- data/app/types/decidim/core/has_publishable_input_sort.rb +13 -0
- data/app/types/decidim/core/participatory_space_input_filter.rb +26 -0
- data/app/types/decidim/core/participatory_space_input_sort.rb +14 -0
- data/app/types/decidim/core/participatory_space_link_type.rb +24 -0
- data/app/types/decidim/core/trace_version_type.rb +29 -0
- data/app/uploaders/decidim/data_portability_uploader.rb +2 -7
- data/app/validators/time_zone_validator.rb +10 -0
- data/app/views/decidim/amendments/_edit_form_fields.html.erb +5 -13
- data/app/views/decidim/amendments/preview_draft.html.erb +1 -1
- data/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +10 -12
- data/app/views/decidim/devise/shared/_omniauth_buttons_mini.html.erb +6 -8
- data/app/views/decidim/export_mailer/data_portability_export.html.erb +2 -2
- data/app/views/decidim/scopes/picker.html.erb +7 -3
- data/app/views/decidim/shared/_check_boxes_tree.html.erb +54 -0
- data/app/views/decidim/shared/_extended_navigation_bar.html.erb +1 -1
- data/app/views/decidim/widgets/show.html.erb +4 -0
- data/app/views/layouts/decidim/_admin_links.html.erb +2 -0
- data/app/views/layouts/decidim/_wrapper.html.erb +4 -3
- data/app/views/layouts/decidim/widget.html.erb +1 -43
- data/config/initializers/browser.rb +5 -0
- data/config/initializers/devise.rb +0 -22
- data/config/initializers/omniauth.rb +50 -0
- data/config/locales/ar.yml +6 -3
- data/config/locales/ca.yml +15 -6
- data/config/locales/cs.yml +12 -3
- data/config/locales/de.yml +5 -3
- data/config/locales/el-GR.yml +0 -2
- data/config/locales/el.yml +153 -0
- data/config/locales/en.yml +16 -7
- data/config/locales/eo-UY.yml +2 -2
- data/config/locales/es-MX.yml +12 -3
- data/config/locales/es-PY.yml +12 -3
- data/config/locales/es.yml +15 -6
- data/config/locales/eu.yml +4 -3
- data/config/locales/fi-plain.yml +12 -3
- data/config/locales/fi.yml +12 -3
- data/config/locales/fr.yml +5 -3
- data/config/locales/gl.yml +4 -3
- data/config/locales/hu.yml +12 -3
- data/config/locales/id-ID.yml +4 -3
- data/config/locales/it.yml +11 -3
- data/config/locales/nl.yml +8 -3
- data/config/locales/no.yml +12 -3
- data/config/locales/pl.yml +4 -3
- data/config/locales/pt-BR.yml +4 -3
- data/config/locales/pt.yml +4 -3
- data/config/locales/ru.yml +5 -3
- data/config/locales/sv.yml +5 -3
- data/config/locales/tr-TR.yml +4 -3
- data/config/locales/uk.yml +1 -3
- data/db/migrate/20191113092826_add_omniauth_settings_to_decidim_organization.rb +7 -0
- data/db/migrate/20191113144432_add_rich_text_editor_in_public_views_to_organizations.rb +10 -0
- data/db/migrate/20191118123154_add_admin_terms_of_use_body_field_to_organization.rb +9 -0
- data/db/migrate/20200107142226_add_organization_timezone.rb +7 -0
- data/db/seeds.rb +2 -1
- data/lib/decidim/amendable.rb +7 -4
- data/lib/decidim/api/amendable_entity_interface.rb +18 -0
- data/lib/decidim/api/amendable_interface.rb +18 -0
- data/lib/decidim/api/attachable_interface.rb +1 -1
- data/lib/decidim/api/categorizable_interface.rb +1 -1
- data/lib/decidim/api/coauthorable_interface.rb +29 -0
- data/lib/decidim/api/fingerprint_interface.rb +13 -0
- data/lib/decidim/api/participatory_space_interface.rb +9 -9
- data/lib/decidim/api/participatory_space_resourceable_interface.rb +21 -0
- data/lib/decidim/api/scopable_interface.rb +1 -1
- data/lib/decidim/api/timestamps_interface.rb +21 -0
- data/lib/decidim/api/traceable_interface.rb +14 -0
- data/lib/decidim/coauthorable.rb +9 -2
- data/lib/decidim/component_manifest.rb +1 -1
- data/lib/decidim/content_processor.rb +4 -2
- data/lib/decidim/content_renderers/link_renderer.rb +1 -1
- data/lib/decidim/core.rb +3 -3
- data/lib/decidim/core/api.rb +7 -0
- data/lib/decidim/core/test.rb +1 -0
- data/lib/decidim/core/test/factories.rb +16 -0
- data/lib/decidim/core/test/shared_examples/amendable_interface_examples.rb +14 -0
- data/lib/decidim/core/test/shared_examples/amendable_proposals_interface_examples.rb +50 -0
- data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +3 -0
- data/lib/decidim/core/test/shared_examples/coauthorable_interface_examples.rb +60 -0
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +8 -8
- data/lib/decidim/core/test/shared_examples/fingerprintable_interface_examples.rb +17 -0
- data/lib/decidim/core/test/shared_examples/follows_examples.rb +16 -0
- data/lib/decidim/core/test/shared_examples/input_filter_examples.rb +118 -0
- data/lib/decidim/core/test/shared_examples/input_sort_examples.rb +105 -0
- data/lib/decidim/core/test/shared_examples/participatory_space_resourcable_interface_examples.rb +43 -0
- data/lib/decidim/core/test/shared_examples/rich_text_editor_examples.rb +59 -0
- data/lib/decidim/core/test/shared_examples/timestamps_interface_examples.rb +21 -0
- data/lib/decidim/core/test/shared_examples/traceable_interface_examples.rb +47 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/deprecations.rb +19 -0
- data/lib/decidim/diffy_extension.rb +26 -0
- data/lib/decidim/exporters/export_manifest.rb +6 -2
- data/lib/decidim/filter_form_builder.rb +25 -7
- data/lib/decidim/form_builder.rb +2 -2
- data/lib/decidim/has_settings.rb +10 -4
- data/lib/decidim/participatory_space_manifest.rb +20 -0
- data/lib/decidim/participatory_space_resourceable.rb +35 -1
- data/lib/decidim/query_extensions.rb +9 -23
- data/lib/decidim/scopable.rb +10 -0
- data/lib/tasks/decidim_data_portability_tasks.rake +66 -5
- data/lib/tasks/decidim_metrics_tasks.rake +18 -7
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.el.js +14 -0
- metadata +142 -16
- data/app/models/decidim/participatory_process_user_role.rb +0 -32
- data/app/views/layouts/decidim/_edit_link.html.erb +0 -8
- data/lib/decidim/data_portability_file_reader.rb +0 -56
- data/lib/decidim/data_portability_file_zipper.rb +0 -67
@@ -49,7 +49,7 @@ module Decidim
|
|
49
49
|
private
|
50
50
|
|
51
51
|
def global_stats(conditions)
|
52
|
-
Decidim.stats.except([:users_count, :processes_count])
|
52
|
+
Decidim.stats.except([:users_count, :processes_count, :followers_count])
|
53
53
|
.filter(conditions)
|
54
54
|
.with_context(organization)
|
55
55
|
.map { |name, data| [name, data] }
|
@@ -57,7 +57,10 @@ module Decidim
|
|
57
57
|
|
58
58
|
def component_stats(conditions)
|
59
59
|
Decidim.component_manifests.flat_map do |component|
|
60
|
-
component.stats.
|
60
|
+
component.stats.except([:supports_count])
|
61
|
+
.filter(conditions)
|
62
|
+
.with_context(published_components)
|
63
|
+
.map { |name, data| [name, data] }
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|
@@ -47,6 +47,15 @@ module Decidim
|
|
47
47
|
admin_collection_route("path", options)
|
48
48
|
end
|
49
49
|
|
50
|
+
# Builds the admin show path to the resource.
|
51
|
+
#
|
52
|
+
# options - An optional hash of options to pass to the Rails router
|
53
|
+
#
|
54
|
+
# Returns a String.
|
55
|
+
def show(options = {})
|
56
|
+
admin_route_proxy.send("#{member_route_name}_path", resource, options)
|
57
|
+
end
|
58
|
+
|
50
59
|
# Builds the admin edit path to the resource.
|
51
60
|
#
|
52
61
|
# options - An optional hash of options to pass to the Rails router
|
@@ -23,7 +23,7 @@ module Decidim
|
|
23
23
|
name: component.name,
|
24
24
|
participatory_space_id: component.participatory_space_id,
|
25
25
|
participatory_space_type: component.participatory_space_type,
|
26
|
-
settings: component
|
26
|
+
settings: component[:settings].as_json,
|
27
27
|
weight: component.weight,
|
28
28
|
permissions: component.permissions,
|
29
29
|
published_at: component.published_at
|
@@ -33,10 +33,10 @@ module Decidim
|
|
33
33
|
def import(json_ary, user)
|
34
34
|
ActiveRecord::Base.transaction do
|
35
35
|
json_ary.collect do |serialized|
|
36
|
-
attributes = serialized.with_indifferent_access
|
37
|
-
|
38
|
-
|
39
|
-
attributes
|
36
|
+
attributes = serialized.with_indifferent_access.except(:id, :participatory_space_id, :participatory_space_type)
|
37
|
+
step_settings = attributes["settings"]["steps"]
|
38
|
+
# we override the parent participatory space steps id
|
39
|
+
override_step_settings_ids(attributes, step_settings)
|
40
40
|
import_component_from_attributes(attributes, user)
|
41
41
|
end
|
42
42
|
end
|
@@ -49,7 +49,7 @@ module Decidim
|
|
49
49
|
component = Decidim.traceability.perform_action!(:create,
|
50
50
|
Decidim::Component,
|
51
51
|
user) do
|
52
|
-
c = Decidim::Component.new(attributes.except(:
|
52
|
+
c = Decidim::Component.new({ participatory_space: @participatory_space }.merge(attributes.except(:settings, :specific_data)))
|
53
53
|
c[:settings] = attributes[:settings]
|
54
54
|
c.save!
|
55
55
|
c
|
@@ -62,6 +62,15 @@ module Decidim
|
|
62
62
|
specific_importer = component.manifest.specific_data_importer_class.new(component)
|
63
63
|
specific_importer.import(serialized[:specific_data], user)
|
64
64
|
end
|
65
|
+
|
66
|
+
def override_step_settings_ids(attributes, step_settings)
|
67
|
+
return if step_settings.nil?
|
68
|
+
|
69
|
+
@participatory_space.steps.each do |step|
|
70
|
+
old_id = attributes["settings"]["steps"].keys.first
|
71
|
+
step_settings[step.id.to_s] = step_settings.delete(old_id)
|
72
|
+
end
|
73
|
+
end
|
65
74
|
end
|
66
75
|
end
|
67
76
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "seven_zip_ruby"
|
4
|
+
require_relative "zip_stream/zip_stream_writer"
|
5
|
+
|
6
|
+
module Decidim
|
7
|
+
# Public: Generates a 7z(seven zip) file with data files ready to be persisted
|
8
|
+
# somewhere so users can download their data.
|
9
|
+
#
|
10
|
+
# In fact, the 7z file wraps a ZIP file which finally contains the data files.
|
11
|
+
class DataPortabilityExporter
|
12
|
+
include ::Decidim::ZipStream::Writer
|
13
|
+
|
14
|
+
DEFAULT_EXPORT_FORMAT = "CSV"
|
15
|
+
ZIP_FILE_NAME = "data-portability.zip"
|
16
|
+
|
17
|
+
# Public: Initializes the class.
|
18
|
+
#
|
19
|
+
# user - The user to export the data from.
|
20
|
+
# path - The String path where to write the zip file.
|
21
|
+
# password - The password to protect the zip file.
|
22
|
+
# export_format - The format of the data files inside the zip file. (CSV by default)
|
23
|
+
def initialize(user, path, password, export_format = DEFAULT_EXPORT_FORMAT)
|
24
|
+
@user = user
|
25
|
+
@path = File.expand_path path
|
26
|
+
@export_format = export_format
|
27
|
+
@password = password
|
28
|
+
end
|
29
|
+
|
30
|
+
def export
|
31
|
+
dirname = File.dirname(@path)
|
32
|
+
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
33
|
+
File.open(@path, "wb") do |file|
|
34
|
+
SevenZipRuby::Writer.open(file, password: @password) do |szw|
|
35
|
+
szw.header_encryption = true
|
36
|
+
szw.add_data(data, ZIP_FILE_NAME)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def data
|
44
|
+
buffer = Zip::OutputStream.write_buffer do |out|
|
45
|
+
user_data, attachments = data_for(@user, @export_format)
|
46
|
+
|
47
|
+
add_user_data_to_zip_stream(out, user_data)
|
48
|
+
add_attachments_to_zip_stream(out, attachments)
|
49
|
+
end
|
50
|
+
|
51
|
+
buffer.string
|
52
|
+
end
|
53
|
+
|
54
|
+
def data_for(user, format)
|
55
|
+
export_data = []
|
56
|
+
export_attachments = []
|
57
|
+
|
58
|
+
data_portability_entities.each do |object|
|
59
|
+
klass = Object.const_get(object)
|
60
|
+
export_data << [klass.model_name.name.parameterize.pluralize, Exporters.find_exporter(format).new(klass.user_collection(user), klass.export_serializer).export]
|
61
|
+
attachments = klass.data_portability_images(user)
|
62
|
+
export_attachments << [klass.model_name.name.parameterize.pluralize, attachments.flatten] unless attachments.nil?
|
63
|
+
end
|
64
|
+
|
65
|
+
[export_data, export_attachments]
|
66
|
+
end
|
67
|
+
|
68
|
+
def data_portability_entities
|
69
|
+
@data_portability_entities ||= DataPortabilitySerializers.data_entities
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -25,24 +25,24 @@ module Decidim
|
|
25
25
|
|
26
26
|
# Handle the category_id filter
|
27
27
|
def search_category_id
|
28
|
+
return query if category_ids.include?("all")
|
29
|
+
|
28
30
|
query
|
29
31
|
.includes(:categorization)
|
30
|
-
.where(decidim_categorizations: { decidim_category_id:
|
32
|
+
.where(decidim_categorizations: { decidim_category_id: all_category_ids })
|
31
33
|
end
|
32
34
|
|
33
|
-
# Handles the
|
34
|
-
# have a
|
35
|
+
# Handles the scope_ids filter. When we want to show only those that do not
|
36
|
+
# have a scope_ids set, we cannot pass an empty String or nil because Searchlight
|
35
37
|
# will automatically filter out these params, so the method will not be used.
|
36
38
|
# Instead, we need to pass a fake ID and then convert it inside. In this case,
|
37
|
-
# in order to select those elements that do not have a
|
39
|
+
# in order to select those elements that do not have a scope_ids set we use
|
38
40
|
# `"global"` as parameter, and in the method we do the needed changes to search
|
39
41
|
# properly.
|
40
42
|
def search_scope_id
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
[scope_id].flatten
|
45
|
-
end
|
43
|
+
return query if scope_ids.include?("all")
|
44
|
+
|
45
|
+
clean_scope_ids = scope_ids
|
46
46
|
|
47
47
|
conditions = []
|
48
48
|
conditions << "#{query.model_name.plural}.decidim_scope_id IS NULL" if clean_scope_ids.delete("global")
|
@@ -55,12 +55,28 @@ module Decidim
|
|
55
55
|
|
56
56
|
# Private: Creates an array of category ids.
|
57
57
|
# It contains categories' subcategories ids as well.
|
58
|
-
def
|
58
|
+
def all_category_ids
|
59
|
+
cat_ids = category_ids.without("without")
|
60
|
+
|
59
61
|
component
|
60
62
|
.categories
|
61
|
-
.where(id:
|
62
|
-
.or(component.categories.where(parent_id:
|
63
|
-
.pluck(:id)
|
63
|
+
.where(id: cat_ids)
|
64
|
+
.or(component.categories.where(parent_id: cat_ids))
|
65
|
+
.pluck(:id).tap { |ids| ids.prepend(nil) if category_ids.include?("without") }
|
66
|
+
end
|
67
|
+
|
68
|
+
# Private: Returns an array with checked category ids.
|
69
|
+
def category_ids
|
70
|
+
[category_id].flatten
|
71
|
+
end
|
72
|
+
|
73
|
+
# Private: Returns an array with checked scope ids.
|
74
|
+
def scope_ids
|
75
|
+
if scope_id.is_a?(Hash)
|
76
|
+
scope_id.values
|
77
|
+
else
|
78
|
+
[scope_id].flatten
|
79
|
+
end
|
64
80
|
end
|
65
81
|
|
66
82
|
# Private: Since component is not used by a search method we need
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ZipStream
|
5
|
+
module Writer
|
6
|
+
def add_user_data_to_zip_stream(out, user_data)
|
7
|
+
user_data.each do |element|
|
8
|
+
filename_file = element.last.filename(element.first.parameterize)
|
9
|
+
|
10
|
+
out.put_next_entry(filename_file)
|
11
|
+
if element.last.read.presence
|
12
|
+
out.write element.last.read
|
13
|
+
else
|
14
|
+
out.write "No data"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_attachments_to_zip_stream(out, export_attachments)
|
20
|
+
export_attachments.each do |attachment_block|
|
21
|
+
next if attachment_block.last.nil?
|
22
|
+
|
23
|
+
folder_name = attachment_block.first.parameterize
|
24
|
+
attachment_block.last.each do |attachment_uploader|
|
25
|
+
next if attachment_uploader.file.nil?
|
26
|
+
|
27
|
+
case attachment_uploader.fog_provider
|
28
|
+
when "fog" # file system
|
29
|
+
next unless File.exist?(attachment_uploader.file.file)
|
30
|
+
when "fog/aws"
|
31
|
+
cache_attachment_from_aws(attachment_uploader)
|
32
|
+
else
|
33
|
+
Rails.logger.info "Carrierwave fog_provider not supported by DataPortabilityExporter for attachment: #{attachment_uploader}"
|
34
|
+
next
|
35
|
+
end
|
36
|
+
|
37
|
+
attachment_local_path = attachment_uploader.file.file
|
38
|
+
out.put_next_entry("#{folder_name}/#{attachment_uploader.file.filename}")
|
39
|
+
File.open(attachment_local_path) do |f|
|
40
|
+
out << f.read
|
41
|
+
end
|
42
|
+
CarrierWave.clean_cached_files!
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Retrieves the file from AWS and stores it into a temporal cache.
|
48
|
+
# Once the file is cached, the uploader returns a local `CarrierWave::SanitizedFile`
|
49
|
+
# instead of a fog file that acts as a proxy to the remote file.
|
50
|
+
def cache_attachment_from_aws(uploader)
|
51
|
+
uploader.cache_stored_file!
|
52
|
+
uploader.retrieve_from_cache!(uploader.cache_name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Core
|
5
|
+
AmendmentType = GraphQL::ObjectType.define do
|
6
|
+
name "Amendment"
|
7
|
+
description "An amendment"
|
8
|
+
|
9
|
+
field :id, !types.ID, "The id of this amendment"
|
10
|
+
field :state, !types.String, "The status of this amendment"
|
11
|
+
field :amender, !Decidim::Core::AuthorInterface, "The author of this amendment"
|
12
|
+
|
13
|
+
field :amendableType, !types.String do
|
14
|
+
description "Type of the amendable object"
|
15
|
+
property :decidim_amendable_type
|
16
|
+
end
|
17
|
+
field :emendationType, !types.String do
|
18
|
+
description "Type of the emendation object"
|
19
|
+
property :decidim_emendation_type
|
20
|
+
end
|
21
|
+
|
22
|
+
field :amendable, !AmendableEntityInterface, "The original amended resource (currently, a proposal only)"
|
23
|
+
field :emendation, !AmendableEntityInterface, "The emendation (currently, a proposal only)"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Core
|
5
|
+
AreaApiType = GraphQL::ObjectType.define do
|
6
|
+
name "Area"
|
7
|
+
description "An area."
|
8
|
+
|
9
|
+
field :id, !types.ID, "Internal ID for this area"
|
10
|
+
field :name, !TranslatedFieldType, "The name of this area."
|
11
|
+
field :areaType, Decidim::Core::AreaTypeType, "The area type of this area", property: :area_type
|
12
|
+
field :createdAt, !Decidim::Core::DateTimeType, "The time this assembly was created", property: :created_at
|
13
|
+
field :updatedAt, !Decidim::Core::DateTimeType, "The time this assembly was updated", property: :updated_at
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Core
|
5
|
+
AreaTypeType = GraphQL::ObjectType.define do
|
6
|
+
name "AreaType"
|
7
|
+
description "An area type."
|
8
|
+
|
9
|
+
field :id, !types.ID, "Internal ID for this area type"
|
10
|
+
field :name, !TranslatedFieldType, "The name of this area type."
|
11
|
+
field :plural, !TranslatedFieldType, "The plural name of this area type"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Core
|
5
|
+
class BaseInputSort < GraphQL::Schema::InputObject
|
6
|
+
# Overwrite the prepare method to allow 2 possible values only
|
7
|
+
def prepare
|
8
|
+
arguments.each do |key, value|
|
9
|
+
next if key == "locale"
|
10
|
+
raise GraphQL::ExecutionError, "Invalid order value for #{key}, only ASC or DESC are valids" unless valid_order?(value)
|
11
|
+
end
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def valid_order?(order)
|
18
|
+
%w(asc desc).include? order.downcase
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Core
|
5
|
+
class ComponentInputFilter < BaseInputFilter
|
6
|
+
include HasPublishableInputFilter
|
7
|
+
include HasLocalizedInputFilter
|
8
|
+
|
9
|
+
graphql_name "ComponentFilter"
|
10
|
+
description "A type used for filtering any component parent objects"
|
11
|
+
|
12
|
+
argument :type,
|
13
|
+
type: String,
|
14
|
+
description: "Filters by type of component",
|
15
|
+
required: false,
|
16
|
+
prepare: ->(value, _ctx) do
|
17
|
+
{ manifest_name: value.downcase }
|
18
|
+
end
|
19
|
+
argument :name,
|
20
|
+
type: String,
|
21
|
+
description: "Filters by name of the component, additional locale parameter can be provided to specify in which to search",
|
22
|
+
required: false,
|
23
|
+
prepare: ->(search, ctx) do
|
24
|
+
proc do |model_class, locale|
|
25
|
+
locale = ctx[:current_organization].default_locale if locale.blank?
|
26
|
+
op = Arel::Nodes::InfixOperation.new("->>", model_class.arel_table[:name], Arel::Nodes.build_quoted(locale))
|
27
|
+
op.matches("%#{search}%")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
argument :with_geolocation_enabled,
|
31
|
+
type: Boolean,
|
32
|
+
description: "Returns components with geolocation activated (may be Proposals or Meetings)",
|
33
|
+
required: false,
|
34
|
+
prepare: ->(active, _ctx) do
|
35
|
+
proc do |_model_class|
|
36
|
+
["(settings->'global'->>'geocoding_enabled')::boolean is ? or manifest_name='meetings'", active]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
argument :with_comments_enabled,
|
40
|
+
type: Boolean,
|
41
|
+
description: "Returns components with comments enabled globally (can still be deactivated in the current step if the component has steps)",
|
42
|
+
required: false,
|
43
|
+
prepare: ->(active, _ctx) do
|
44
|
+
proc do |_model_class|
|
45
|
+
["(settings->'global'->>'comments_enabled')::boolean is ?", active]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Core
|
5
|
+
class ComponentInputSort < BaseInputSort
|
6
|
+
include HasLocalizedInputSort
|
7
|
+
|
8
|
+
graphql_name "ComponentSort"
|
9
|
+
description "A type used for sorting any component parent objects"
|
10
|
+
|
11
|
+
argument :id, String, "Sort by ID, valid values are ASC or DESC", required: false
|
12
|
+
argument :weight, String, "Sort by weight (order in the website), valid values are ASC or DESC", required: false
|
13
|
+
argument :type,
|
14
|
+
type: String,
|
15
|
+
description: "Sort by type of component, alphabetically, valid values are ASC or DESC",
|
16
|
+
required: false,
|
17
|
+
prepare: ->(direction, _ctx) do
|
18
|
+
{ manifest_name: direction }
|
19
|
+
end
|
20
|
+
argument :name,
|
21
|
+
type: String,
|
22
|
+
description: "Sort by name of the component, alphabetically, valid values are ASC or DESC",
|
23
|
+
required: false,
|
24
|
+
prepare: ->(direction, ctx) do
|
25
|
+
proc do |locale|
|
26
|
+
locale = ctx[:current_organization].default_locale if locale.blank?
|
27
|
+
[Arel.sql("name->? #{direction.upcase}"), locale]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|