decidim-core 0.13.1 → 0.14.1
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/config/decidim_core_manifest.js +1 -1
- data/app/assets/images/decidim/gamification/badges/invitations.svg +117 -0
- data/app/assets/javascripts/decidim.js.es6 +4 -1
- data/app/assets/javascripts/decidim/ajax_modals.js.es6 +17 -0
- data/app/assets/javascripts/decidim/conferences.js.es6 +16 -0
- data/app/assets/javascripts/decidim/input_hashtags.js.es6 +115 -0
- data/app/assets/javascripts/decidim/input_mentions.js.es6 +2 -3
- data/app/assets/javascripts/decidim/vizzs/areachart.js.es6 +226 -0
- data/app/assets/javascripts/decidim/vizzs/metrics.js.es6 +26 -0
- data/app/assets/javascripts/decidim/vizzs/orgchart.js.es6 +701 -0
- data/app/assets/javascripts/decidim/vizzs/renders.js.es6 +11 -0
- data/app/assets/stylesheets/decidim/extras/_proposal_form.scss +3 -1
- data/app/assets/stylesheets/decidim/layouts/_home.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_areachart.scss +74 -0
- data/app/assets/stylesheets/decidim/modules/_badges.scss +116 -0
- data/app/assets/stylesheets/decidim/modules/_buttons.scss +5 -0
- data/app/assets/stylesheets/decidim/modules/_cards.scss +21 -4
- data/app/assets/stylesheets/decidim/modules/_chart-tooltip.scss +42 -0
- data/app/assets/stylesheets/decidim/modules/_collapsible-list.scss +12 -8
- data/app/assets/stylesheets/decidim/modules/_conference-nav.scss +31 -0
- data/app/assets/stylesheets/decidim/modules/_conference-programme.scss +110 -0
- data/app/assets/stylesheets/decidim/modules/_conference-speaker.scss +86 -0
- data/app/assets/stylesheets/decidim/modules/_conversation.scss +58 -0
- data/app/assets/stylesheets/decidim/modules/_help.scss +38 -0
- data/app/assets/stylesheets/decidim/modules/_hover-section.scss +29 -0
- data/app/assets/stylesheets/decidim/modules/_icons.scss +10 -4
- data/app/assets/stylesheets/decidim/modules/_input-hashtags.scss +124 -0
- data/app/assets/stylesheets/decidim/modules/_loading-spinner.scss +12 -0
- data/app/assets/stylesheets/decidim/modules/_margins.scss +2 -2
- data/app/assets/stylesheets/decidim/modules/_modules.scss +15 -0
- data/app/assets/stylesheets/decidim/modules/_navbar.scss +9 -0
- data/app/assets/stylesheets/decidim/modules/_orgchart.scss +62 -0
- data/app/assets/stylesheets/decidim/modules/_status-labels.scss +2 -1
- data/app/assets/stylesheets/decidim/modules/_typography.scss +9 -0
- data/app/assets/stylesheets/decidim/utils/_helpers.scss +28 -0
- data/app/assets/stylesheets/decidim/utils/_mixins.scss +63 -0
- data/app/cells/decidim/author/withdraw.erb +1 -1
- data/app/cells/decidim/author_cell.rb +1 -1
- data/app/cells/decidim/badge/show.erb +36 -0
- data/app/cells/decidim/badge_cell.rb +53 -0
- data/app/cells/decidim/badges/show.erb +6 -0
- data/app/cells/decidim/badges_cell.rb +14 -0
- data/app/cells/decidim/card_m/header.erb +1 -1
- data/app/cells/decidim/card_m/show.erb +1 -2
- data/app/cells/decidim/card_m/top.erb +7 -0
- data/app/cells/decidim/card_m_cell.rb +14 -17
- data/app/cells/decidim/coauthorships_cell.rb +77 -0
- data/app/cells/decidim/collapsible_authors/show.erb +0 -1
- data/app/cells/decidim/collapsible_authors_cell.rb +4 -4
- data/app/cells/decidim/collapsible_list/show.erb +12 -4
- data/app/cells/decidim/collapsible_list_cell.rb +14 -12
- data/app/cells/decidim/content_blocks/footer_sub_hero/show.erb +14 -0
- data/app/cells/decidim/content_blocks/footer_sub_hero_cell.rb +12 -0
- data/app/{views/decidim/pages/home/_hero.html.erb → cells/decidim/content_blocks/hero/show.erb} +4 -4
- data/app/cells/decidim/content_blocks/hero_cell.rb +25 -0
- data/app/cells/decidim/content_blocks/hero_settings_form/show.erb +7 -0
- data/app/cells/decidim/content_blocks/hero_settings_form_cell.rb +13 -0
- data/app/cells/decidim/content_blocks/highlighted_content_banner/show.erb +24 -0
- data/app/cells/decidim/content_blocks/highlighted_content_banner_cell.rb +16 -0
- data/app/{views/decidim/pages/home/_extended.html.erb → cells/decidim/content_blocks/how_to_participate/show.erb} +10 -10
- data/app/cells/decidim/content_blocks/how_to_participate_cell.rb +9 -0
- data/app/{views/decidim/pages/home/_statistics.html.erb → cells/decidim/content_blocks/stats/show.erb} +2 -2
- data/app/cells/decidim/content_blocks/stats_cell.rb +18 -0
- data/app/{views/decidim/pages/home/_sub_hero.html.erb → cells/decidim/content_blocks/sub_hero/show.erb} +2 -2
- data/app/cells/decidim/content_blocks/sub_hero_cell.rb +17 -0
- data/app/cells/decidim/conversation/show.erb +18 -0
- data/app/cells/decidim/conversation_cell.rb +23 -0
- data/app/cells/decidim/conversation_header/show.erb +17 -0
- data/app/cells/decidim/conversation_header_cell.rb +16 -0
- data/app/cells/decidim/conversations/show.erb +45 -0
- data/app/cells/decidim/conversations_cell.rb +24 -0
- data/app/cells/decidim/follow_button/show.erb +3 -3
- data/app/cells/decidim/follow_button_cell.rb +1 -5
- data/app/cells/decidim/following_cell.rb +1 -7
- data/app/cells/decidim/message/show.erb +15 -0
- data/app/cells/decidim/message_cell.rb +23 -0
- data/app/cells/decidim/new_conversation/show.erb +19 -0
- data/app/cells/decidim/new_conversation_cell.rb +19 -0
- data/app/cells/decidim/notifications/show.erb +1 -1
- data/app/cells/decidim/profile/show.erb +27 -0
- data/app/cells/decidim/profile_cell.rb +33 -0
- data/app/cells/decidim/profile_sidebar/show.erb +57 -0
- data/app/cells/decidim/profile_sidebar_cell.rb +31 -0
- data/app/cells/decidim/tos_page_cell.rb +0 -4
- data/app/cells/decidim/user_profile/header.erb +1 -1
- data/app/controllers/concerns/decidim/action_authorization.rb +13 -38
- data/app/controllers/concerns/decidim/needs_permission.rb +15 -6
- data/app/controllers/decidim/application_controller.rb +1 -0
- data/app/controllers/decidim/authorization_modals_controller.rb +35 -0
- data/app/controllers/decidim/components/base_controller.rb +0 -1
- data/app/controllers/decidim/devise/invitations_controller.rb +2 -1
- data/app/controllers/decidim/messaging/conversations_controller.rb +2 -11
- data/app/controllers/decidim/newsletters_controller.rb +4 -6
- data/app/controllers/decidim/notifications_controller.rb +4 -0
- data/app/controllers/decidim/pages_controller.rb +3 -7
- data/app/controllers/decidim/profiles_controller.rb +17 -7
- data/app/forms/decidim/notifications_settings_form.rb +1 -1
- data/app/forms/decidim/registration_form.rb +1 -1
- data/app/helpers/decidim/action_authorization_helper.rb +51 -46
- data/app/helpers/decidim/application_helper.rb +18 -0
- data/app/helpers/decidim/card_helper.rb +1 -1
- data/app/helpers/decidim/cells_helper.rb +6 -2
- data/app/helpers/decidim/resource_helper.rb +8 -1
- data/app/helpers/decidim/searches_helper.rb +5 -4
- data/app/helpers/decidim/traceability_helper.rb +5 -1
- data/app/models/decidim/authorization.rb +2 -2
- data/app/models/decidim/content_block.rb +144 -0
- data/app/models/decidim/gamification/badge_score.rb +13 -0
- data/app/models/decidim/messaging/message.rb +1 -1
- data/app/models/decidim/messaging/receipt.rb +1 -1
- data/app/models/decidim/organization.rb +1 -5
- data/app/models/decidim/resource_permission.rb +8 -0
- data/app/models/decidim/searchable_resource.rb +1 -1
- data/app/models/decidim/user.rb +17 -1
- data/app/permissions/decidim/default_permissions.rb +4 -3
- data/app/permissions/decidim/permissions.rb +33 -1
- data/app/presenters/decidim/hashtag_presenter.rb +32 -0
- data/app/presenters/decidim/resource_locator_presenter.rb +13 -0
- data/app/presenters/decidim/user_presenter.rb +1 -1
- data/app/queries/decidim/messaging/user_conversations.rb +1 -1
- data/app/resolvers/decidim/hashtags_resolver.rb +15 -0
- data/app/services/decidim/action_authorizer.rb +9 -8
- data/app/types/decidim/core/date_time_type.rb +1 -1
- data/app/types/decidim/core/hashtag_type.rb +13 -0
- data/app/uploaders/decidim/homepage_image_uploader.rb +1 -1
- data/app/uploaders/decidim/image_uploader.rb +1 -0
- data/app/views/decidim/authorization_modals/show.html.erb +32 -0
- data/app/views/decidim/messaging/conversations/create.js.erb +1 -1
- data/app/views/decidim/messaging/conversations/index.html.erb +1 -51
- data/app/views/decidim/messaging/conversations/new.html.erb +1 -5
- data/app/views/decidim/messaging/conversations/show.html.erb +1 -9
- data/app/views/decidim/messaging/conversations/update.js.erb +1 -1
- data/app/views/decidim/notifications/index.html.erb +1 -0
- data/app/views/decidim/pages/decidim_page.html.erb +9 -0
- data/app/views/decidim/pages/home.html.erb +12 -16
- data/app/views/decidim/pages/index.html.erb +8 -0
- data/app/views/decidim/profiles/_user_follow.erb +2 -2
- data/app/views/decidim/profiles/show.html.erb +1 -37
- data/app/views/decidim/searches/_results.html.erb +1 -1
- data/app/views/decidim/shared/_author_reference.html.erb +1 -1
- data/app/views/decidim/shared/_authorization_modal.html.erb +1 -0
- data/app/views/decidim/shared/_tags.html.erb +1 -1
- data/app/views/kaminari/decidim/_page.html.erb +1 -1
- data/app/views/layouts/decidim/_application.html.erb +6 -1
- data/app/views/layouts/decidim/_edit_link.html.erb +8 -0
- data/app/views/layouts/decidim/_impersonation_warning.html.erb +1 -1
- data/app/views/layouts/decidim/_user_menu.html.erb +2 -2
- data/app/views/layouts/decidim/_wrapper.html.erb +14 -1
- data/config/initializers/carrierwave.rb +15 -0
- data/config/locales/ca.yml +78 -30
- data/config/locales/en.yml +78 -30
- data/config/locales/es-PY.yml +78 -30
- data/config/locales/es.yml +78 -30
- data/config/locales/eu.yml +78 -30
- data/config/locales/fi.yml +262 -214
- data/config/locales/fr.yml +78 -30
- data/config/locales/gl.yml +78 -30
- data/config/locales/hu.yml +781 -0
- data/config/locales/it.yml +78 -30
- data/config/locales/nl.yml +78 -30
- data/config/locales/pl.yml +78 -30
- data/config/locales/pt-BR.yml +106 -58
- data/config/locales/pt.yml +78 -30
- data/config/locales/ru.yml +52 -32
- data/config/locales/sv.yml +183 -135
- data/config/locales/uk.yml +60 -40
- data/config/routes.rb +8 -6
- data/db/migrate/20180705091019_create_decidim_resource_permissions.rb +12 -0
- data/db/migrate/20180706104107_add_nickname_to_managed_users.rb +14 -0
- data/db/migrate/20180706111847_fix_result_follows.rb +9 -0
- data/db/migrate/20180724103814_add_content_blocks.rb +22 -0
- data/db/migrate/20180726112510_create_decidim_hashtags.rb +17 -0
- data/db/migrate/20180730071851_add_core_content_blocks.rb +28 -0
- data/db/migrate/20180802132147_rename_content_block_options_to_settings.rb +7 -0
- data/db/migrate/20180806095628_add_badge_scores.rb +11 -0
- data/db/migrate/20180808135006_add_images_to_content_blocks.rb +7 -0
- data/db/migrate/20180810092428_move_organization_fields_to_hero_content_block.rb +23 -0
- data/db/seeds.rb +10 -2
- data/lib/decidim/api/authorable_interface.rb +1 -1
- data/lib/decidim/coauthorable.rb +1 -0
- data/lib/decidim/content_block_manifest.rb +58 -0
- data/lib/decidim/content_block_registry.rb +87 -0
- data/lib/decidim/content_parsers.rb +1 -0
- data/lib/decidim/content_parsers/hashtag_parser.rb +36 -0
- data/lib/decidim/content_processor.rb +11 -0
- data/lib/decidim/content_renderers.rb +1 -0
- data/lib/decidim/content_renderers/hashtag_renderer.rb +43 -0
- data/lib/decidim/core.rb +28 -6
- data/lib/decidim/core/api.rb +1 -0
- data/lib/decidim/core/engine.rb +52 -1
- data/lib/decidim/core/test.rb +3 -0
- data/lib/decidim/core/test/factories.rb +32 -17
- data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +10 -0
- data/lib/decidim/core/test/shared_examples/coauthorable.rb +3 -0
- data/lib/decidim/core/test/shared_examples/edit_link_shared_examples.rb +30 -0
- data/lib/decidim/core/test/shared_examples/has_space_in_mcell_examples.rb +15 -0
- data/lib/decidim/core/test/shared_examples/publicable.rb +1 -1
- data/lib/decidim/core/test/shared_examples/railtie_examples.rb +15 -0
- data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +1 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/events/base_event.rb +2 -1
- data/lib/decidim/form_builder.rb +9 -3
- data/lib/decidim/friendly_dates.rb +1 -1
- data/lib/decidim/gamification.rb +109 -0
- data/lib/decidim/gamification/badge.rb +54 -0
- data/lib/decidim/gamification/badge_earned_event.rb +9 -0
- data/lib/decidim/gamification/badge_registry.rb +63 -0
- data/lib/decidim/gamification/badge_scorer.rb +118 -0
- data/lib/decidim/gamification/badge_status.rb +41 -0
- data/lib/decidim/gamification/base_event.rb +40 -0
- data/lib/decidim/gamification/level_up_event.rb +9 -0
- data/lib/decidim/hashtag.rb +15 -0
- data/lib/decidim/hashtaggable.rb +20 -0
- data/lib/decidim/query_extensions.rb +10 -0
- data/lib/decidim/resource_manifest.rb +10 -0
- data/lib/decidim/resourceable.rb +13 -0
- data/lib/decidim/search_resource_fields_mapper.rb +8 -3
- data/lib/decidim/searchable.rb +8 -0
- data/lib/decidim/translatable_attributes.rb +6 -18
- data/lib/decidim/view_model.rb +6 -0
- data/lib/devise/models/decidim_newsletterable.rb +1 -1
- data/vendor/assets/javascripts/d3.js +17813 -0
- metadata +125 -27
- data/app/cells/decidim/card_m/author.erb +0 -3
- data/app/cells/decidim/card_m/authors.erb +0 -9
- data/app/views/decidim/messaging/conversations/_message.html.erb +0 -14
- data/app/views/decidim/messaging/conversations/_reply.html.erb +0 -11
- data/app/views/decidim/messaging/conversations/_show.html.erb +0 -21
- data/app/views/decidim/messaging/conversations/_start.html.erb +0 -12
- data/app/views/decidim/pages/home/_footer_sub_hero.html.erb +0 -14
- data/app/views/decidim/pages/home/_highlighted_content_banner.html.erb +0 -26
- data/app/views/decidim/pages/home/_highlighted_processes.html.erb +0 -7
- data/app/views/decidim/profiles/_user.html.erb +0 -59
- data/app/views/decidim/shared/_action_authorization_modal.html.erb +0 -39
- data/app/views/layouts/decidim/_component_authorization_modals.html.erb +0 -5
@@ -45,7 +45,7 @@ module Decidim
|
|
45
45
|
return [] unless klass.respond_to?(:linked_classes_for)
|
46
46
|
|
47
47
|
klass.linked_classes_for(current_component).map do |k|
|
48
|
-
[k.underscore, t(k.demodulize.
|
48
|
+
[k.underscore, t(k.demodulize.underscore, scope: "decidim.filters.linked_classes")]
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -69,5 +69,12 @@ module Decidim
|
|
69
69
|
def resource_locator(resource)
|
70
70
|
::Decidim::ResourceLocatorPresenter.new(resource)
|
71
71
|
end
|
72
|
+
|
73
|
+
# Returns a descriptive title for the resource
|
74
|
+
def resource_title(resource)
|
75
|
+
title = resource.try(:title) || resource.try(:name) || resource.try(:subject) || "#{resource.model_name.human} ##{resource.id}"
|
76
|
+
title = translated_attribute(title) if title.is_a?(Hash)
|
77
|
+
title
|
78
|
+
end
|
72
79
|
end
|
73
80
|
end
|
@@ -1,15 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Decidim
|
4
|
-
# A Helper to render and link to
|
4
|
+
# A Helper to render and link to searchables.
|
5
5
|
module SearchesHelper
|
6
|
-
|
7
|
-
|
6
|
+
# @param count: (optional) the number of resources so that the I18n backend can decide to translate into singluar or plural form.
|
7
|
+
def searchable_resource_human_name(resource, count: 1)
|
8
|
+
resource.model_name.human(count: count)
|
8
9
|
end
|
9
10
|
|
10
11
|
def searchable_resources_as_options(all_label)
|
11
12
|
[["", all_label]] + Decidim::Searchable.searchable_resources.values.collect do |r|
|
12
|
-
[r.name, searchable_resource_human_name(r)]
|
13
|
+
[r.name, searchable_resource_human_name(r, count: 2)]
|
13
14
|
end.sort
|
14
15
|
end
|
15
16
|
end
|
@@ -31,7 +31,11 @@ module Decidim
|
|
31
31
|
|
32
32
|
# Caches a DiffRenderer instance for the `current_version`.
|
33
33
|
def diff_renderer
|
34
|
-
@diff_renderer ||= Decidim::
|
34
|
+
@diff_renderer ||= if current_version.item_type.include? "Decidim::Proposals"
|
35
|
+
Decidim::Proposals::DiffRenderer.new(current_version)
|
36
|
+
elsif current_version.item_type.include? "Decidim::Accountability"
|
37
|
+
Decidim::Accountability::DiffRenderer.new(current_version)
|
38
|
+
end
|
35
39
|
end
|
36
40
|
|
37
41
|
# Renders the diff between `:old_data` and `:new_data` keys in the `data` param.
|
@@ -39,7 +39,7 @@ module Decidim
|
|
39
39
|
def grant!
|
40
40
|
remove_verification_attachment!
|
41
41
|
|
42
|
-
update!(granted_at: Time.
|
42
|
+
update!(granted_at: Time.current, verification_metadata: {})
|
43
43
|
end
|
44
44
|
|
45
45
|
def granted?
|
@@ -57,7 +57,7 @@ module Decidim
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def expired?
|
60
|
-
expires_at.present? && expires_at < Time.
|
60
|
+
expires_at.present? && expires_at < Time.current
|
61
61
|
end
|
62
62
|
|
63
63
|
private
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
# this class represents a content block manifest instance in the DB. Check the
|
5
|
+
# docs on `ContentBlockRegistry` and `ContentBlockManifest` for more info.
|
6
|
+
class ContentBlock < ApplicationRecord
|
7
|
+
include Publicable
|
8
|
+
|
9
|
+
belongs_to :organization, foreign_key: :decidim_organization_id, class_name: "Decidim::Organization"
|
10
|
+
|
11
|
+
delegate :public_name_key, :has_settings?, :settings_form_cell, :cell, to: :manifest
|
12
|
+
|
13
|
+
before_save :save_images
|
14
|
+
after_save :reload_images
|
15
|
+
|
16
|
+
# Public: finds the published content blocks for the given scope and
|
17
|
+
# organization. Returns them ordered by ascending weight (lowest first).
|
18
|
+
def self.for_scope(scope, organization:)
|
19
|
+
where(organization: organization, scope: scope)
|
20
|
+
.order(weight: :asc)
|
21
|
+
end
|
22
|
+
|
23
|
+
def manifest
|
24
|
+
@manifest ||= Decidim.content_blocks.for(scope).find { |manifest| manifest.name.to_s == manifest_name }
|
25
|
+
end
|
26
|
+
|
27
|
+
# Public: Uses the `SettingsManifest` class to generate a settings schema
|
28
|
+
# and fill it with the content blocks current settings. This eases the
|
29
|
+
# access to those settings values.
|
30
|
+
#
|
31
|
+
# Returns an object that responds to the settings defined in the content
|
32
|
+
# block manifest.
|
33
|
+
def settings
|
34
|
+
manifest.settings.schema.new(self[:settings])
|
35
|
+
end
|
36
|
+
|
37
|
+
def reload(*)
|
38
|
+
@images_container = nil
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
# Public: Holds access to the images related to the content block. This
|
43
|
+
# method generates a dynamic class that encapsulates the uploaders for the
|
44
|
+
# content block images, and eases the access to them. It's a little bit
|
45
|
+
# hacky, but it's the only way I could come up with in order to let content
|
46
|
+
# block images have different uploaders.
|
47
|
+
#
|
48
|
+
# Examples:
|
49
|
+
#
|
50
|
+
# # This will process the image with the uploader defined at the
|
51
|
+
# # manifest, upload it and save the record.
|
52
|
+
# content_block.images_container.my_image = params[:my_image]
|
53
|
+
# content_block.save!
|
54
|
+
#
|
55
|
+
# # This is how you can access the image data, just like with any other
|
56
|
+
# # uploader field. You can use the uploader versions too.
|
57
|
+
# content_block.images_container.my_image.url
|
58
|
+
# content_block.images_container.my_image.big.url
|
59
|
+
# content_block.save!
|
60
|
+
#
|
61
|
+
# # This will delete the attached image
|
62
|
+
# content_block.images_container.my_image = nil
|
63
|
+
# content_block.save!
|
64
|
+
#
|
65
|
+
# Returns an object that responds to the image names defined in the content
|
66
|
+
# block manifest.
|
67
|
+
def images_container
|
68
|
+
return @images_container if @images_container
|
69
|
+
manifest = self.manifest
|
70
|
+
|
71
|
+
@images_container = Class.new do
|
72
|
+
extend ::CarrierWave::Mount
|
73
|
+
include ActiveModel::Validations
|
74
|
+
|
75
|
+
cattr_accessor :manifest, :manifest_scope
|
76
|
+
attr_reader :content_block
|
77
|
+
|
78
|
+
# Needed to calculate uploads URLs
|
79
|
+
delegate :id, to: :content_block
|
80
|
+
|
81
|
+
# Needed to customize the upload URL
|
82
|
+
def self.name
|
83
|
+
to_s.camelize
|
84
|
+
end
|
85
|
+
|
86
|
+
# Needed to customize the upload URL
|
87
|
+
def self.to_s
|
88
|
+
"decidim/#{manifest.name.to_s.underscore}_#{manifest_scope.to_s.underscore}_content_block"
|
89
|
+
end
|
90
|
+
|
91
|
+
def initialize(content_block)
|
92
|
+
@content_block = content_block
|
93
|
+
end
|
94
|
+
|
95
|
+
def manifest
|
96
|
+
self.class.manifest
|
97
|
+
end
|
98
|
+
|
99
|
+
manifest.images.each do |image_config|
|
100
|
+
mount_uploader image_config[:name], image_config[:uploader].constantize
|
101
|
+
end
|
102
|
+
|
103
|
+
# This is used to access the upload file name from the container, given
|
104
|
+
# an image name.
|
105
|
+
def read_uploader(column)
|
106
|
+
content_block.images[column.to_s]
|
107
|
+
end
|
108
|
+
|
109
|
+
# This is used to set the upload file name from the container, given
|
110
|
+
# an image name.
|
111
|
+
def write_uploader(column, value)
|
112
|
+
content_block.images[column.to_s] = value
|
113
|
+
end
|
114
|
+
|
115
|
+
# When we save the content block, we force the container to save itself
|
116
|
+
# too, so images can be processed, uploaded and stored in the DB.
|
117
|
+
def save
|
118
|
+
manifest.images.each do |image_config|
|
119
|
+
send(:"write_#{image_config[:name]}_identifier")
|
120
|
+
send(:"store_#{image_config[:name]}!")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
@images_container.manifest = manifest
|
126
|
+
@images_container.manifest_scope = scope
|
127
|
+
@images_container = @images_container.new(self)
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
# Internal: Since we're using the `images_container` hack to hold the
|
133
|
+
# uploaders, we need to manually trigger it to save the attached images.
|
134
|
+
def save_images
|
135
|
+
images_container.save
|
136
|
+
end
|
137
|
+
|
138
|
+
# On instance reloading we need to remove the `images_cointainer` cached
|
139
|
+
# class so it gets regenerated with the new values.
|
140
|
+
def reload_images
|
141
|
+
@images_container = nil
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gamification
|
5
|
+
class BadgeScore < ApplicationRecord
|
6
|
+
self.table_name = "decidim_gamification_badge_scores"
|
7
|
+
|
8
|
+
belongs_to :user, class_name: "Decidim::User"
|
9
|
+
validates :user, presence: true
|
10
|
+
validates :value, numericality: { greater_than_or_equal_to: 0 }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -38,7 +38,7 @@ module Decidim
|
|
38
38
|
# @param recipients [Array<Decidim::User>]
|
39
39
|
#
|
40
40
|
def envelope_for(recipients)
|
41
|
-
receipts.build(recipient: sender, read_at: Time.
|
41
|
+
receipts.build(recipient: sender, read_at: Time.current)
|
42
42
|
|
43
43
|
recipients.each { |recipient| receipts.build(recipient: recipient) }
|
44
44
|
end
|
@@ -19,7 +19,7 @@ module Decidim
|
|
19
19
|
|
20
20
|
# rubocop:disable Rails/SkipsModelValidations
|
21
21
|
def self.mark_as_read(user)
|
22
|
-
recipient(user).update_all(read_at: Time.
|
22
|
+
recipient(user).update_all(read_at: Time.current)
|
23
23
|
end
|
24
24
|
# rubocop:enable Rails/SkipsModelValidations
|
25
25
|
end
|
@@ -19,12 +19,12 @@ module Decidim
|
|
19
19
|
has_many :users_with_any_role, -> { where.not(roles: []) }, foreign_key: "decidim_organization_id", class_name: "Decidim::User"
|
20
20
|
has_many :users, foreign_key: "decidim_organization_id", class_name: "Decidim::User", dependent: :destroy
|
21
21
|
has_many :oauth_applications, foreign_key: "decidim_organization_id", class_name: "Decidim::OAuthApplication", inverse_of: :organization, dependent: :destroy
|
22
|
+
has_many :hashtags, foreign_key: "decidim_organization_id", class_name: "Decidim::Hashtag", dependent: :destroy
|
22
23
|
|
23
24
|
validates :name, :host, uniqueness: true
|
24
25
|
validates :reference_prefix, presence: true
|
25
26
|
validates :default_locale, inclusion: { in: :available_locales }
|
26
27
|
|
27
|
-
mount_uploader :homepage_image, Decidim::HomepageImageUploader
|
28
28
|
mount_uploader :official_img_header, Decidim::OfficialImageHeaderUploader
|
29
29
|
mount_uploader :official_img_footer, Decidim::OfficialImageFooterUploader
|
30
30
|
mount_uploader :logo, Decidim::OrganizationLogoUploader
|
@@ -46,10 +46,6 @@ module Decidim
|
|
46
46
|
@top_scopes ||= scopes.top_level
|
47
47
|
end
|
48
48
|
|
49
|
-
def homepage_big_url
|
50
|
-
homepage_image.big.url
|
51
|
-
end
|
52
|
-
|
53
49
|
def public_participatory_spaces
|
54
50
|
@public_participatory_spaces ||= Decidim.participatory_space_manifests.flat_map do |manifest|
|
55
51
|
manifest.participatory_spaces.call(self).public_spaces
|
@@ -26,7 +26,7 @@ module Decidim
|
|
26
26
|
class_name: "Decidim::Scope",
|
27
27
|
optional: true
|
28
28
|
belongs_to :resource, polymorphic: true
|
29
|
-
belongs_to :decidim_participatory_space, polymorphic: true
|
29
|
+
belongs_to :decidim_participatory_space, polymorphic: true, optional: true
|
30
30
|
|
31
31
|
validates :locale, uniqueness: { scope: :resource }
|
32
32
|
|
data/app/models/decidim/user.rb
CHANGED
@@ -12,6 +12,7 @@ module Decidim
|
|
12
12
|
include Decidim::Followable
|
13
13
|
include Decidim::Loggable
|
14
14
|
include Decidim::DataPortability
|
15
|
+
include Decidim::Searchable
|
15
16
|
|
16
17
|
OMNIAUTH_PROVIDERS = [:facebook, :twitter, :google_oauth2, (:developer if Rails.env.development?)].compact
|
17
18
|
ROLES = %w(admin user_manager).freeze
|
@@ -54,6 +55,15 @@ module Decidim
|
|
54
55
|
|
55
56
|
attr_accessor :newsletter_notifications
|
56
57
|
|
58
|
+
searchable_fields({
|
59
|
+
# scope_id: :decidim_scope_id,
|
60
|
+
organization_id: :decidim_organization_id,
|
61
|
+
A: :name,
|
62
|
+
datetime: :created_at
|
63
|
+
},
|
64
|
+
index_on_create: ->(user) { !user.deleted? },
|
65
|
+
index_on_update: ->(user) { !user.deleted? })
|
66
|
+
|
57
67
|
def user_invited?
|
58
68
|
invitation_token_changed? && invitation_accepted_at_changed?
|
59
69
|
end
|
@@ -124,6 +134,12 @@ module Decidim
|
|
124
134
|
end
|
125
135
|
end
|
126
136
|
|
137
|
+
def following_users
|
138
|
+
@following_users ||= following.select do |f|
|
139
|
+
f.is_a?(Decidim::User)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
127
143
|
def unread_conversations
|
128
144
|
Decidim::Messaging::Conversation.unread_by(self)
|
129
145
|
end
|
@@ -155,7 +171,7 @@ module Decidim
|
|
155
171
|
end
|
156
172
|
|
157
173
|
def tos_accepted?
|
158
|
-
return true if managed
|
174
|
+
return true if managed || organization.tos_version.nil?
|
159
175
|
return false if accepted_tos_version.nil?
|
160
176
|
accepted_tos_version >= organization.tos_version
|
161
177
|
end
|
@@ -38,10 +38,11 @@ module Decidim
|
|
38
38
|
[:participatory_space, :component].include?(permission_action.subject)
|
39
39
|
end
|
40
40
|
|
41
|
-
def authorized?(permission_action)
|
42
|
-
return unless component
|
41
|
+
def authorized?(permission_action, resource: nil)
|
42
|
+
return unless resource || component
|
43
|
+
return if component && resource && component != resource.component
|
43
44
|
|
44
|
-
ActionAuthorizer.new(user, component,
|
45
|
+
ActionAuthorizer.new(user, permission_action, component, resource).authorize.ok?
|
45
46
|
end
|
46
47
|
|
47
48
|
def current_settings
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module Decidim
|
4
4
|
class Permissions < DefaultPermissions
|
5
5
|
def permissions
|
6
|
+
return permission_action unless permission_action.scope == :public
|
7
|
+
|
6
8
|
read_public_pages_action?
|
7
9
|
locales_action?
|
8
10
|
component_public_action?
|
@@ -37,7 +39,10 @@ module Decidim
|
|
37
39
|
return unless permission_action.subject == :component &&
|
38
40
|
permission_action.action == :read
|
39
41
|
|
40
|
-
|
42
|
+
return allow! if component.published?
|
43
|
+
return allow! if user_can_admin_component?
|
44
|
+
return allow! if user_can_admin_component_via_space?
|
45
|
+
disallow!
|
41
46
|
end
|
42
47
|
|
43
48
|
def search_scope_action?
|
@@ -86,6 +91,33 @@ module Decidim
|
|
86
91
|
toggle_allow(conversation.participants.include?(user))
|
87
92
|
end
|
88
93
|
|
94
|
+
def user_can_admin_component?
|
95
|
+
new_permission_action = Decidim::PermissionAction.new(
|
96
|
+
action: permission_action.action,
|
97
|
+
scope: :admin,
|
98
|
+
subject: permission_action.subject
|
99
|
+
)
|
100
|
+
Decidim::Admin::Permissions.new(user, new_permission_action, context).permissions.allowed?
|
101
|
+
rescue Decidim::PermissionAction::PermissionNotSetError
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
|
105
|
+
def user_can_admin_component_via_space?
|
106
|
+
Decidim.participatory_space_manifests.any? do |manifest|
|
107
|
+
begin
|
108
|
+
new_permission_action = Decidim::PermissionAction.new(
|
109
|
+
action: permission_action.action,
|
110
|
+
scope: :admin,
|
111
|
+
subject: permission_action.subject
|
112
|
+
)
|
113
|
+
new_context = context.merge(current_participatory_space: component.participatory_space)
|
114
|
+
manifest.permissions_class.new(user, new_permission_action, new_context).permissions.allowed?
|
115
|
+
rescue Decidim::PermissionAction::PermissionNotSetError
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
89
121
|
def not_already_active?(authorization)
|
90
122
|
Verifications::Authorizations.new(organization: user.organization, user: user, name: authorization.name).none?
|
91
123
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
#
|
5
|
+
# Decorator for users
|
6
|
+
#
|
7
|
+
class HashtagPresenter < SimpleDelegator
|
8
|
+
include Rails.application.routes.mounted_helpers
|
9
|
+
include ActionView::Helpers::UrlHelper
|
10
|
+
|
11
|
+
#
|
12
|
+
# name presented in a twitter-like style
|
13
|
+
#
|
14
|
+
def name
|
15
|
+
"##{super}"
|
16
|
+
end
|
17
|
+
|
18
|
+
delegate :url, to: :hashtag, prefix: true
|
19
|
+
|
20
|
+
def hashtag_path
|
21
|
+
decidim.hashtag_path(__getobj__.name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def display_hashtag
|
25
|
+
link_to name, decidim.search_path(term: name), target: "_blank", class: "hashtag-mention"
|
26
|
+
end
|
27
|
+
|
28
|
+
def display_hashtag_name
|
29
|
+
name
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|