decidim-core 0.14.4 → 0.15.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/README.md +20 -0
- data/app/assets/images/decidim/cc-badge.png +0 -0
- data/app/assets/images/decidim/gamification/badges/continuity.svg +73 -0
- data/app/assets/images/decidim/gamification/badges/followers.svg +115 -0
- data/app/assets/images/decidim/icons.svg +1 -0
- data/app/assets/javascripts/decidim/vizzs/areachart.js.es6 +186 -208
- data/app/assets/javascripts/decidim/vizzs/linechart.js.es6 +263 -0
- data/app/assets/javascripts/decidim/vizzs/metrics.js.es6 +36 -26
- data/app/assets/javascripts/decidim/vizzs/orgchart.js.es6 +3 -2
- data/app/assets/javascripts/decidim/vizzs/rowchart.js.es6 +324 -0
- data/app/assets/stylesheets/decidim/_decidim.scss +1 -0
- data/app/assets/stylesheets/decidim/modules/_cards.scss +1 -0
- data/app/assets/stylesheets/decidim/modules/_conference-diploma.scss +75 -0
- data/app/assets/stylesheets/decidim/modules/_conference-media.scss +44 -0
- data/app/assets/stylesheets/decidim/modules/_conference-programme.scss +5 -1
- data/app/assets/stylesheets/decidim/modules/_conference-registration.scss +34 -0
- data/app/assets/stylesheets/decidim/modules/_list-request.scss +16 -0
- data/app/assets/stylesheets/decidim/modules/_modules.scss +4 -4
- data/app/assets/stylesheets/decidim/modules/_process-phase.scss +1 -0
- data/app/assets/stylesheets/decidim/modules/_reveal.scss +6 -1
- data/app/assets/stylesheets/decidim/utils/_helpers.scss +1 -1
- data/app/assets/stylesheets/decidim/{modules → vizzs}/_areachart.scss +8 -11
- data/app/assets/stylesheets/decidim/{modules → vizzs}/_chart-tooltip.scss +0 -0
- data/app/assets/stylesheets/decidim/vizzs/_linechart.scss +115 -0
- data/app/assets/stylesheets/decidim/vizzs/_rowchart.scss +77 -0
- data/app/cells/decidim/activities/show.erb +3 -0
- data/app/cells/decidim/activities_cell.rb +38 -0
- data/app/cells/decidim/activity/show.erb +21 -0
- data/app/cells/decidim/activity_cell.rb +85 -0
- data/app/cells/decidim/address/details.erb +7 -0
- data/app/cells/decidim/address/show.erb +14 -0
- data/app/cells/decidim/address_cell.rb +19 -0
- data/app/cells/decidim/author/contact.erb +1 -1
- data/app/cells/decidim/author_cell.rb +1 -0
- data/app/cells/decidim/badge/show.erb +2 -2
- data/app/cells/decidim/badge/small.erb +5 -0
- data/app/cells/decidim/badge_cell.rb +36 -14
- data/app/cells/decidim/badges/show.erb +6 -3
- data/app/cells/decidim/badges_cell.rb +4 -4
- data/app/cells/decidim/coauthorships_cell.rb +8 -2
- data/app/cells/decidim/collapsible_authors/show.erb +9 -7
- data/app/cells/decidim/content_blocks/html/show.erb +3 -0
- data/app/cells/decidim/content_blocks/html_cell.rb +11 -0
- data/app/cells/decidim/content_blocks/html_settings_form/show.erb +3 -0
- data/app/cells/decidim/content_blocks/html_settings_form_cell.rb +17 -0
- data/app/cells/decidim/content_blocks/last_activity/show.erb +17 -0
- data/app/cells/decidim/content_blocks/last_activity_cell.rb +60 -0
- data/app/cells/decidim/content_blocks/metrics/show.erb +13 -0
- data/app/cells/decidim/content_blocks/metrics_cell.rb +18 -0
- data/app/cells/decidim/content_blocks/stats/show.erb +2 -1
- data/app/cells/decidim/groups/show.erb +10 -0
- data/app/cells/decidim/groups_cell.rb +19 -0
- data/app/cells/decidim/members/show.erb +9 -0
- data/app/cells/decidim/members_cell.rb +32 -0
- data/app/cells/decidim/profile/show.erb +3 -11
- data/app/cells/decidim/profile/user_group_tabs.erb +5 -0
- data/app/cells/decidim/profile/user_tabs.erb +12 -0
- data/app/cells/decidim/profile_cell.rb +7 -2
- data/app/cells/decidim/profile_sidebar/show.erb +108 -23
- data/app/cells/decidim/profile_sidebar_cell.rb +36 -2
- data/app/cells/decidim/user_group_admin_membership_profile/footer.erb +29 -0
- data/app/cells/decidim/user_group_admin_membership_profile_cell.rb +14 -0
- data/app/cells/decidim/user_group_membership_profile/tags.erb +1 -0
- data/app/cells/decidim/user_group_membership_profile_cell.rb +8 -0
- data/app/cells/decidim/user_group_pending_invitations_list/show.erb +23 -0
- data/app/cells/decidim/user_group_pending_invitations_list_cell.rb +26 -0
- data/app/cells/decidim/user_group_pending_requests_list/show.erb +23 -0
- data/app/cells/decidim/user_group_pending_requests_list_cell.rb +26 -0
- data/app/cells/decidim/user_profile/header.erb +1 -1
- data/app/cells/decidim/user_profile_cell.rb +15 -9
- data/app/commands/decidim/accept_group_invitation.rb +43 -0
- data/app/commands/decidim/accept_user_group_join_request.rb +53 -0
- data/app/commands/decidim/create_follow.rb +6 -0
- data/app/commands/decidim/create_registration.rb +13 -23
- data/app/commands/decidim/create_user_group.rb +57 -0
- data/app/commands/decidim/delete_follow.rb +7 -0
- data/app/commands/decidim/demote_membership.rb +57 -0
- data/app/commands/decidim/destroy_account.rb +6 -0
- data/app/commands/decidim/invite_user.rb +1 -3
- data/app/commands/decidim/invite_user_to_group.rb +62 -0
- data/app/commands/decidim/join_user_group.rb +63 -0
- data/app/commands/decidim/leave_user_group.rb +41 -0
- data/app/commands/decidim/promote_membership.rb +55 -0
- data/app/commands/decidim/reject_group_invitation.rb +42 -0
- data/app/commands/decidim/reject_user_group_join_request.rb +53 -0
- data/app/commands/decidim/remove_user_from_group.rb +53 -0
- data/app/commands/decidim/update_user_group.rb +53 -0
- data/app/controllers/concerns/decidim/locale_switcher.rb +3 -3
- data/app/controllers/concerns/decidim/paginable.rb +1 -0
- data/app/controllers/decidim/application_controller.rb +7 -0
- data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +1 -1
- data/app/controllers/decidim/devise/sessions_controller.rb +1 -1
- data/app/controllers/decidim/gamification/badges_controller.rb +11 -0
- data/app/controllers/decidim/group_admins_controller.rb +41 -0
- data/app/controllers/decidim/group_invites_controller.rb +74 -0
- data/app/controllers/decidim/group_members_controller.rb +59 -0
- data/app/controllers/decidim/groups_controller.rb +85 -0
- data/app/controllers/decidim/last_activities_controller.rb +46 -0
- data/app/controllers/decidim/pages_controller.rb +9 -1
- data/app/controllers/decidim/profiles_controller.rb +35 -5
- data/app/controllers/decidim/user_group_join_requests_controller.rb +69 -0
- data/app/events/decidim/demoted_membership_event.rb +28 -0
- data/app/events/decidim/invited_to_group_event.rb +33 -0
- data/app/events/decidim/join_request_accepted_event.rb +28 -0
- data/app/events/decidim/join_request_created_event.rb +28 -0
- data/app/events/decidim/join_request_rejected_event.rb +28 -0
- data/app/events/decidim/promoted_to_admin_event.rb +28 -0
- data/app/events/decidim/removed_from_group_event.rb +28 -0
- data/app/forms/decidim/account_form.rb +1 -1
- data/app/forms/decidim/invite_user_to_group_form.rb +29 -0
- data/app/forms/decidim/notifications_settings_form.rb +4 -0
- data/app/forms/decidim/registration_form.rb +0 -27
- data/app/forms/decidim/user_group_form.rb +81 -0
- data/app/helpers/decidim/component_path_helper.rb +10 -0
- data/app/helpers/decidim/filters_helper.rb +3 -2
- data/app/helpers/decidim/icon_helper.rb +3 -1
- data/app/helpers/decidim/map_helper.rb +1 -1
- data/app/jobs/decidim/metric_job.rb +14 -0
- data/app/mailers/decidim/newsletter_mailer.rb +2 -0
- data/app/mailers/decidim/notification_mailer.rb +1 -1
- data/app/models/decidim/action_log.rb +66 -0
- data/app/models/decidim/coauthorship.rb +9 -0
- data/app/models/decidim/component.rb +5 -0
- data/app/models/decidim/continuity_badge_status.rb +9 -0
- data/app/models/decidim/gamification/badge_score.rb +1 -1
- data/app/models/decidim/messaging/message.rb +1 -0
- data/app/models/decidim/metric.rb +13 -0
- data/app/models/decidim/participatory_space_private_user.rb +4 -0
- data/app/models/decidim/user.rb +14 -38
- data/app/models/decidim/user_base_entity.rb +52 -0
- data/app/models/decidim/user_group.rb +48 -9
- data/app/models/decidim/user_group_membership.rb +8 -0
- data/app/permissions/decidim/permissions.rb +21 -0
- data/app/presenters/decidim/admin_log/organization_presenter.rb +0 -2
- data/app/presenters/decidim/admin_log/participatory_space_private_user_presenter.rb +38 -0
- data/app/presenters/decidim/metric_charts_presenter.rb +53 -0
- data/app/presenters/decidim/metric_object_presenter.rb +28 -0
- data/app/presenters/decidim/user_group_presenter.rb +16 -8
- data/app/presenters/decidim/user_presenter.rb +14 -0
- data/app/queries/decidim/metric_manage.rb +59 -0
- data/app/queries/decidim/metrics/users_metric_manage.rb +26 -0
- data/app/queries/decidim/user_groups/accepted_memberships.rb +36 -0
- data/app/queries/decidim/user_groups/accepted_user_groups.rb +38 -0
- data/app/queries/decidim/user_groups/accepted_users.rb +36 -0
- data/app/queries/decidim/user_groups/admin_memberships.rb +37 -0
- data/app/queries/decidim/user_groups/invited_memberships.rb +36 -0
- data/app/queries/decidim/user_groups/manageable_user_groups.rb +39 -0
- data/app/queries/decidim/user_groups/member_memberships.rb +37 -0
- data/app/resolvers/decidim/core/metric_resolver.rb +38 -0
- data/app/services/decidim/action_logger.rb +4 -2
- data/app/services/decidim/activity_search.rb +76 -0
- data/app/services/decidim/continuity_badge_tracker.rb +64 -0
- data/app/services/decidim/resource_search.rb +0 -1
- data/app/types/decidim/core/metric_history_type.rb +17 -0
- data/app/types/decidim/core/metric_type.rb +14 -0
- data/app/types/decidim/core/session_type.rb +1 -1
- data/app/types/decidim/core/user_group_type.rb +2 -2
- data/app/views/decidim/authorization_modals/show.html.erb +40 -27
- data/app/views/decidim/devise/registrations/new.html.erb +0 -19
- data/app/views/decidim/gamification/badges/index.html.erb +42 -0
- data/app/views/decidim/group_admins/index.html.erb +18 -0
- data/app/views/decidim/group_invites/index.html.erb +27 -0
- data/app/views/decidim/group_members/index.html.erb +19 -0
- data/app/views/decidim/groups/_form.html.erb +23 -0
- data/app/views/decidim/groups/edit.html.erb +26 -0
- data/app/views/decidim/groups/new.html.erb +26 -0
- data/app/views/decidim/last_activities/_activities.html.erb +13 -0
- data/app/views/decidim/last_activities/index.html.erb +18 -0
- data/app/views/decidim/last_activities/index.js.erb +6 -0
- data/app/views/decidim/profiles/show.html.erb +1 -1
- data/app/views/layouts/decidim/_user_menu.html.erb +0 -1
- data/app/views/layouts/decidim/_wrapper.html.erb +1 -1
- data/config/initializers/devise.rb +1 -1
- data/config/initializers/foundation_rails_helper.rb +1 -0
- data/config/locales/ca.yml +325 -32
- data/config/locales/de.yml +325 -32
- data/config/locales/en.yml +325 -32
- data/config/locales/es-PY.yml +325 -32
- data/config/locales/es.yml +325 -32
- data/config/locales/eu.yml +325 -32
- data/config/locales/fi.yml +330 -37
- data/config/locales/fr.yml +325 -32
- data/config/locales/gl.yml +325 -32
- data/config/locales/hu.yml +327 -34
- data/config/locales/it.yml +325 -32
- data/config/locales/nl.yml +325 -32
- data/config/locales/pl.yml +329 -32
- data/config/locales/pt-BR.yml +326 -33
- data/config/locales/pt.yml +325 -32
- data/config/locales/ru.yml +4 -33
- data/config/locales/sv.yml +346 -53
- data/config/locales/uk.yml +4 -33
- data/config/routes.rb +27 -1
- data/db/migrate/20170128112958_change_user_groups_verified_to_timestamp.rb +11 -0
- data/db/migrate/20180705134647_create_decidim_metrics.rb +16 -0
- data/db/migrate/20180730071851_add_core_content_blocks.rb +3 -3
- data/db/migrate/20180810092428_move_organization_fields_to_hero_content_block.rb +4 -2
- data/db/migrate/20180918072506_add_visibility_to_action_logs.rb +8 -0
- data/db/migrate/20181001124950_move_users_groups_to_users_table.rb +84 -0
- data/db/migrate/20181008102144_add_badge_switch_to_organizations.rb +8 -0
- data/db/migrate/20181010044613_create_decidim_continuity_badge_statuses.rb +11 -0
- data/db/migrate/20181011080252_add_roles_to_memberships.rb +24 -0
- data/db/migrate/20181016091601_make_authors_polymorphic.rb +31 -0
- data/db/migrate/20181029112820_fix_user_follows.rb +18 -0
- data/db/migrate/20181030090144_destroy_deleted_users_follows.rb +16 -0
- data/db/seeds.rb +18 -4
- data/lib/decidim/attributes.rb +1 -0
- data/lib/decidim/attributes/localized_date.rb +16 -0
- data/lib/decidim/attributes/time_with_zone.rb +3 -1
- data/lib/decidim/authorable.rb +5 -4
- data/lib/decidim/authorization_form_builder.rb +2 -2
- data/lib/decidim/coauthorable.rb +68 -18
- data/lib/decidim/content_block_manifest.rb +7 -0
- data/lib/decidim/content_processor.rb +17 -7
- data/lib/decidim/core.rb +12 -0
- data/lib/decidim/core/engine.rb +54 -6
- data/lib/decidim/core/test/factories.rb +63 -17
- data/lib/decidim/core/test/shared_examples/coauthorable.rb +27 -9
- data/lib/decidim/core/test/shared_examples/coauthorable_interface_examples.rb +2 -2
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/data_portability.rb +3 -1
- data/lib/decidim/data_portability_file_reader.rb +1 -1
- data/lib/decidim/events/author_event.rb +4 -1
- data/lib/decidim/events/coauthor_event.rb +4 -1
- data/lib/decidim/faker/localized.rb +5 -4
- data/lib/decidim/form_builder.rb +18 -17
- data/lib/decidim/gamification.rb +8 -2
- data/lib/decidim/gamification/badge.rb +34 -0
- data/lib/decidim/gamification/badge_scorer.rb +29 -14
- data/lib/decidim/gamification/badge_status.rb +2 -0
- data/lib/decidim/hashtaggable.rb +1 -1
- data/lib/decidim/manifest_registry.rb +5 -3
- data/lib/decidim/metric_manifest.rb +20 -0
- data/lib/decidim/metric_registry.rb +71 -0
- data/lib/decidim/participable.rb +1 -1
- data/lib/decidim/participatory_space_resourceable.rb +0 -1
- data/lib/decidim/query_extensions.rb +19 -0
- data/lib/decidim/resourceable.rb +1 -0
- data/lib/decidim/searchable.rb +2 -1
- data/lib/tasks/decidim_metrics_tasks.rake +41 -0
- data/lib/tasks/decidim_tasks.rake +1 -0
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.ca.js +1 -2
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.es.js +1 -2
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.fr.js +1 -2
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.gl.js +1 -2
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.pt.js +1 -2
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.ru.js +1 -2
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.uk.js +1 -2
- data/vendor/assets/javascripts/form_datepicker.js.es6 +1 -11
- metadata +144 -23
- data/app/cells/decidim/invitations_toggle/content.erb +0 -1
- data/app/cells/decidim/invitations_toggle/label.erb +0 -1
- data/app/cells/decidim/invitations_toggle_cell.rb +0 -27
- data/app/cells/decidim/toggle/show.erb +0 -8
- data/app/cells/decidim/toggle_cell.rb +0 -42
- data/app/commands/decidim/invite_friends.rb +0 -48
- data/app/controllers/decidim/invitations_controller.rb +0 -32
- data/app/forms/decidim/invitations_form.rb +0 -37
- data/app/views/decidim/invitations/index.html.erb +0 -48
- data/app/views/devise/mailer/invite_friend.html.erb +0 -27
- data/app/views/devise/mailer/invite_friend.text.erb +0 -19
- data/lib/decidim/rectify_ext.rb +0 -32
data/db/seeds.rb
CHANGED
@@ -7,6 +7,15 @@ if !Rails.env.production? || ENV["SEED"]
|
|
7
7
|
|
8
8
|
seeds_root = File.join(__dir__, "seeds")
|
9
9
|
|
10
|
+
# Since we usually migrate and seed in the same process, make sure
|
11
|
+
# that we don't have invalid or cached information after a migration.
|
12
|
+
decidim_tables = ActiveRecord::Base.connection.tables.select do |table|
|
13
|
+
table.starts_with?("decidim_")
|
14
|
+
end
|
15
|
+
decidim_tables.map do |table|
|
16
|
+
table.tr("_", "/").classify.safe_constantize
|
17
|
+
end.compact.each(&:reset_column_information)
|
18
|
+
|
10
19
|
organization = Decidim::Organization.first || Decidim::Organization.create!(
|
11
20
|
name: Faker::Company.name,
|
12
21
|
twitter_handler: Faker::Hipster.word,
|
@@ -22,7 +31,8 @@ if !Rails.env.production? || ENV["SEED"]
|
|
22
31
|
available_locales: Decidim.available_locales,
|
23
32
|
reference_prefix: Faker::Name.suffix,
|
24
33
|
available_authorizations: Decidim.authorization_workflows.map(&:name),
|
25
|
-
tos_version: Time.current
|
34
|
+
tos_version: Time.current,
|
35
|
+
badges_enabled: true
|
26
36
|
)
|
27
37
|
|
28
38
|
if organization.top_scopes.none?
|
@@ -129,14 +139,18 @@ if !Rails.env.production? || ENV["SEED"]
|
|
129
139
|
[nil, Time.current].each do |verified_at|
|
130
140
|
user_group = Decidim::UserGroup.create!(
|
131
141
|
name: Faker::Company.unique.name,
|
132
|
-
|
133
|
-
|
134
|
-
|
142
|
+
nickname: Faker::Twitter.unique.screen_name,
|
143
|
+
extended_data: {
|
144
|
+
document_number: Faker::Number.number(10),
|
145
|
+
phone: Faker::PhoneNumber.phone_number,
|
146
|
+
verified_at: verified_at
|
147
|
+
},
|
135
148
|
decidim_organization_id: user.organization.id
|
136
149
|
)
|
137
150
|
|
138
151
|
Decidim::UserGroupMembership.create!(
|
139
152
|
user: user,
|
153
|
+
role: "creator",
|
140
154
|
user_group: user_group
|
141
155
|
)
|
142
156
|
end
|
data/lib/decidim/attributes.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Attributes
|
5
|
+
# Custom Virtus value to parse a String representing a Date using
|
6
|
+
# the app localization format.
|
7
|
+
class LocalizedDate < Virtus::Attribute
|
8
|
+
def coerce(value)
|
9
|
+
return value unless value.is_a?(String)
|
10
|
+
Date.strptime(value, I18n.t("date.formats.decidim_short"))
|
11
|
+
rescue ArgumentError
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -7,7 +7,9 @@ module Decidim
|
|
7
7
|
class TimeWithZone < Virtus::Attribute
|
8
8
|
def coerce(value)
|
9
9
|
return value unless value.is_a?(String)
|
10
|
-
Time.zone.
|
10
|
+
Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
|
11
|
+
rescue ArgumentError
|
12
|
+
nil
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
data/lib/decidim/authorable.rb
CHANGED
@@ -9,9 +9,10 @@ module Decidim
|
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
|
11
11
|
included do
|
12
|
-
belongs_to :author, foreign_key: "decidim_author_id",
|
12
|
+
belongs_to :author, polymorphic: true, foreign_key: "decidim_author_id", foreign_type: "decidim_author_type"
|
13
13
|
belongs_to :user_group, foreign_key: "decidim_user_group_id", class_name: "Decidim::UserGroup", optional: true
|
14
14
|
|
15
|
+
validates :author, presence: true
|
15
16
|
validate :verified_user_group, :user_group_membership
|
16
17
|
validate :author_belongs_to_organization
|
17
18
|
|
@@ -19,8 +20,8 @@ module Decidim
|
|
19
20
|
# authoring it or via a user group.
|
20
21
|
#
|
21
22
|
# user - the user to check for authorship
|
22
|
-
def authored_by?(
|
23
|
-
|
23
|
+
def authored_by?(other_author)
|
24
|
+
other_author == author || other_author.respond_to?(:user_groups) && other_author.user_groups.include?(user_group)
|
24
25
|
end
|
25
26
|
|
26
27
|
# Returns the normalized author, whether it's a user group or a user. Ideally this should be
|
@@ -45,7 +46,7 @@ module Decidim
|
|
45
46
|
|
46
47
|
def author_belongs_to_organization
|
47
48
|
return if !author || !organization
|
48
|
-
errors.add(:author, :invalid) unless author.organization == organization
|
49
|
+
errors.add(:author, :invalid) unless author == organization || author.respond_to?(:organization) && author.organization == organization
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
@@ -39,7 +39,7 @@ module Decidim
|
|
39
39
|
return hidden_field(name) if name.to_s == "handler_name"
|
40
40
|
|
41
41
|
case type.name
|
42
|
-
when "Date"
|
42
|
+
when "Date", "Decidim::Attributes::LocalizedDate"
|
43
43
|
date_field name
|
44
44
|
else
|
45
45
|
text_field name
|
@@ -58,7 +58,7 @@ module Decidim
|
|
58
58
|
|
59
59
|
def public_attributes
|
60
60
|
form_attributes.inject({}) do |all, attribute|
|
61
|
-
all.update(attribute.name => attribute.
|
61
|
+
all.update(attribute.name => attribute.class)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
data/lib/decidim/coauthorable.rb
CHANGED
@@ -12,23 +12,62 @@ module Decidim
|
|
12
12
|
extend ActiveSupport::Concern
|
13
13
|
|
14
14
|
included do
|
15
|
-
has_many :coauthorships, -> { order(:created_at) }, as: :coauthorable, class_name: "Decidim::Coauthorship", dependent: :destroy
|
16
|
-
has_many :authors, -> { order(:created_at) }, through: :coauthorships, class_name: "Decidim::User"
|
15
|
+
has_many :coauthorships, -> { order(:created_at) }, as: :coauthorable, class_name: "Decidim::Coauthorship", dependent: :destroy, inverse_of: :coauthorable
|
17
16
|
has_many :user_groups, -> { order(:created_at) }, as: :coauthorable, class_name: "Decidim::UserGroup", through: :coauthorships
|
18
17
|
|
19
|
-
# retrieves models from all identities of the
|
20
|
-
scope :
|
21
|
-
|
22
|
-
|
18
|
+
# retrieves models from all identities of the author.
|
19
|
+
scope :from_all_author_identities, lambda { |author|
|
20
|
+
joins(:coauthorships).where("decidim_coauthorships.decidim_author_id = ? AND decidim_coauthorships.decidim_author_type = ?", author.id, author.class.base_class.name)
|
21
|
+
}
|
22
|
+
# retrieves models from the given author, ignoring the UserGroups it belongs to.
|
23
|
+
scope :from_author, ->(author) { from_all_author_identities(author).where("decidim_coauthorships.decidim_user_group_id": nil) }
|
23
24
|
# retrieves models from the given UserGroup.
|
24
25
|
scope :from_user_group, ->(user_group) { joins(:coauthorships).where("decidim_coauthorships.decidim_user_group_id": user_group.id) }
|
25
26
|
|
27
|
+
validates :coauthorships, presence: true
|
28
|
+
|
29
|
+
# Overwrite default reload method to unset the instance variables so reloading works as expected.
|
30
|
+
def reload(options = nil)
|
31
|
+
remove_instance_variable(:@authors) if defined?(@authors)
|
32
|
+
remove_instance_variable(:@notifiable_authors) if defined?(@notifiable_authors)
|
33
|
+
super(options)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns all the authors of a coauthorable.
|
37
|
+
#
|
38
|
+
# We need to do it this ways since the authors are polymorphic, and we can't have a has_many through relation
|
39
|
+
# with polymorphic objects.
|
40
|
+
def authors
|
41
|
+
return @authors if defined?(@authors)
|
42
|
+
|
43
|
+
authors = coauthorships.pluck(:decidim_author_id, :decidim_author_type).each_with_object({}) do |(id, klass), all|
|
44
|
+
all[klass] ||= []
|
45
|
+
all[klass] << id
|
46
|
+
end
|
47
|
+
|
48
|
+
@authors = authors.flat_map do |klass, ids|
|
49
|
+
klass.constantize.where(id: ids)
|
50
|
+
end.compact.uniq
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the authors that should be notified for a coauthorable.
|
54
|
+
#
|
55
|
+
def notifiable_authors
|
56
|
+
@notifiable_authors ||= authors.flat_map do |author|
|
57
|
+
if author.is_a?(Decidim::User)
|
58
|
+
author
|
59
|
+
elsif respond_to?(:component)
|
60
|
+
component.participatory_space.admins
|
61
|
+
end
|
62
|
+
end.compact.uniq
|
63
|
+
end
|
64
|
+
|
26
65
|
# Checks whether the user is author of the given proposal, either directly
|
27
66
|
# authoring it or via a user group.
|
28
67
|
#
|
29
|
-
#
|
30
|
-
def authored_by?(
|
31
|
-
coauthorships.where(author:
|
68
|
+
# author - the author to check for authorship
|
69
|
+
def authored_by?(author)
|
70
|
+
coauthorships.where(author: author).exists?
|
32
71
|
end
|
33
72
|
|
34
73
|
# Returns the identities for the authors, whether they are user groups or users.
|
@@ -40,30 +79,41 @@ module Decidim
|
|
40
79
|
|
41
80
|
# Syntactic sugar to access first coauthor as a Coauthorship.
|
42
81
|
def creator
|
43
|
-
coauthorships.first
|
82
|
+
coauthorships.order(:created_at).first
|
44
83
|
end
|
45
84
|
|
46
85
|
# Syntactic sugar to access first coauthor Author
|
47
86
|
def creator_author
|
48
|
-
|
87
|
+
creator.try(:author)
|
49
88
|
end
|
50
89
|
|
51
90
|
# Syntactic sugar to access first identity whether it is a User or a UserGroup.
|
52
91
|
# @return The User od UserGroup that created this Coauthorable.
|
53
92
|
def creator_identity
|
54
|
-
|
93
|
+
creator.try(:identity)
|
55
94
|
end
|
56
95
|
|
57
96
|
# Adds a new coauthor to the list of coauthors. The coauthorship is created with
|
58
97
|
# current object as coauthorable and `user` param as author. To set the user group
|
59
|
-
# use `
|
98
|
+
# use `extra_attributes` either with `user_group` or `decidim_user_group_id` keys.
|
60
99
|
#
|
61
|
-
# @param
|
100
|
+
# @param author: The new coauthor.
|
62
101
|
# @extra_attrs: Extra
|
63
|
-
def add_coauthor(
|
64
|
-
|
65
|
-
|
66
|
-
|
102
|
+
def add_coauthor(author, extra_attributes = {})
|
103
|
+
user_group = extra_attributes[:user_group]
|
104
|
+
|
105
|
+
return if coauthorships.where(decidim_author_id: author.id, decidim_author_type: author.class.base_class.name).exists? && user_group.blank?
|
106
|
+
return if user_group && coauthorships.where(user_group: user_group).exists?
|
107
|
+
|
108
|
+
coauthorship_attributes = extra_attributes.merge(author: author)
|
109
|
+
|
110
|
+
if persisted?
|
111
|
+
coauthorships.create!(coauthorship_attributes)
|
112
|
+
else
|
113
|
+
coauthorships.build(coauthorship_attributes)
|
114
|
+
end
|
115
|
+
|
116
|
+
authors << author
|
67
117
|
end
|
68
118
|
end
|
69
119
|
end
|
@@ -27,12 +27,19 @@ module Decidim
|
|
27
27
|
attribute :cell, String
|
28
28
|
attribute :settings_form_cell, String
|
29
29
|
attribute :images, Array[Hash]
|
30
|
+
attribute :default, Boolean, default: false
|
30
31
|
|
31
32
|
validates :name, :cell, :public_name_key, presence: true
|
32
33
|
validates :settings_form_cell, presence: true, if: :has_settings?
|
33
34
|
validate :image_names_are_unique
|
34
35
|
validate :images_have_an_uploader
|
35
36
|
|
37
|
+
# Public: Registers whether this content block should be shown by default
|
38
|
+
# when creating an organization. Use `#default` to retrieve it.
|
39
|
+
def default!
|
40
|
+
self.default = true
|
41
|
+
end
|
42
|
+
|
36
43
|
def has_settings?
|
37
44
|
settings.attributes.any?
|
38
45
|
end
|
@@ -61,13 +61,23 @@ module Decidim
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def self.parse_with_processor(_type, content, context)
|
64
|
-
parsed =
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
parsed = if content.is_a?(Hash)
|
65
|
+
Decidim.content_processors.each_with_object(rewrite: content, metadata: {}) do |type, result|
|
66
|
+
next unless type == :hashtag
|
67
|
+
result[:rewrite].each do |key, value|
|
68
|
+
parser = parser_klass(type).constantize.new(value, context)
|
69
|
+
result[:rewrite][key] = parser.rewrite
|
70
|
+
result[:metadata][type] = parser.metadata
|
71
|
+
end
|
72
|
+
end
|
73
|
+
else
|
74
|
+
Decidim.content_processors.each_with_object(rewrite: content, metadata: {}) do |type, result|
|
75
|
+
next unless type == :hashtag
|
76
|
+
parser = parser_klass(type).constantize.new(result[:rewrite], context)
|
77
|
+
result[:rewrite] = parser.rewrite
|
78
|
+
result[:metadata][type] = parser.metadata
|
79
|
+
end
|
80
|
+
end
|
71
81
|
Result.new(parsed[:rewrite], parsed[:metadata])
|
72
82
|
end
|
73
83
|
|
data/lib/decidim/core.rb
CHANGED
@@ -50,6 +50,8 @@ module Decidim
|
|
50
50
|
autoload :ViewHooks, "decidim/view_hooks"
|
51
51
|
autoload :ContentBlockRegistry, "decidim/content_block_registry"
|
52
52
|
autoload :ContentBlockManifest, "decidim/content_block_manifest"
|
53
|
+
autoload :MetricRegistry, "decidim/metric_registry"
|
54
|
+
autoload :MetricManifest, "decidim/metric_manifest"
|
53
55
|
autoload :NewsletterEncryptor, "decidim/newsletter_encryptor"
|
54
56
|
autoload :Searchable, "decidim/searchable"
|
55
57
|
autoload :SearchResourceFieldsMapper, "decidim/search_resource_fields_mapper"
|
@@ -213,6 +215,11 @@ module Decidim
|
|
213
215
|
1.minute
|
214
216
|
end
|
215
217
|
|
218
|
+
# Time window were users can access the website even if their email is not confirmed.
|
219
|
+
config_accessor :unconfirmed_access_for do
|
220
|
+
2.days
|
221
|
+
end
|
222
|
+
|
216
223
|
# A base path for the uploads. If set, make sure it ends in a slash.
|
217
224
|
# Uploads will be set to `<base_path>/uploads/`. This can be useful if you
|
218
225
|
# want to use the same uploads place for both staging and production
|
@@ -380,4 +387,9 @@ module Decidim
|
|
380
387
|
def self.traceability
|
381
388
|
@traceability ||= Traceability.new
|
382
389
|
end
|
390
|
+
|
391
|
+
# Public: Stores an instance of ContentBlockRegistry
|
392
|
+
def self.metrics_registry
|
393
|
+
@metrics_registry ||= MetricRegistry.new
|
394
|
+
end
|
383
395
|
end
|
data/lib/decidim/core/engine.rb
CHANGED
@@ -15,12 +15,7 @@ require "foundation-rails"
|
|
15
15
|
require "foundation_rails_helper"
|
16
16
|
require "autoprefixer-rails"
|
17
17
|
require "active_link_to"
|
18
|
-
|
19
|
-
# Until https://github.com/andypike/rectify/pull/45 is attended, we're shipping
|
20
|
-
# with a patched version of rectify
|
21
18
|
require "rectify"
|
22
|
-
require "decidim/rectify_ext"
|
23
|
-
|
24
19
|
require "carrierwave"
|
25
20
|
require "rails-i18n"
|
26
21
|
require "date_validator"
|
@@ -42,6 +37,7 @@ require "doorkeeper"
|
|
42
37
|
require "doorkeeper-i18n"
|
43
38
|
require "nobspw"
|
44
39
|
require "kaminari"
|
40
|
+
require "batch-loader"
|
45
41
|
|
46
42
|
require "decidim/api"
|
47
43
|
|
@@ -60,6 +56,7 @@ module Decidim
|
|
60
56
|
|
61
57
|
initializer "decidim.middleware" do |app|
|
62
58
|
app.config.middleware.use Decidim::CurrentOrganization
|
59
|
+
app.config.middleware.use BatchLoader::Middleware
|
63
60
|
end
|
64
61
|
|
65
62
|
initializer "decidim.assets" do |app|
|
@@ -140,7 +137,7 @@ module Decidim
|
|
140
137
|
|
141
138
|
menu.item I18n.t("menu.more_information", scope: "decidim"),
|
142
139
|
decidim.pages_path,
|
143
|
-
position:
|
140
|
+
position: 7,
|
144
141
|
active: :inclusive
|
145
142
|
end
|
146
143
|
end
|
@@ -274,6 +271,20 @@ module Decidim
|
|
274
271
|
resource.model_class_name = "Decidim::User"
|
275
272
|
resource.card = "decidim/user_profile"
|
276
273
|
end
|
274
|
+
|
275
|
+
Decidim.register_resource(:user_group) do |resource|
|
276
|
+
resource.model_class_name = "Decidim::UserGroup"
|
277
|
+
resource.card = "decidim/user_profile"
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
initializer "decidim.core.register_metrics" do
|
282
|
+
Decidim.metrics_registry.register(
|
283
|
+
:users,
|
284
|
+
"Decidim::Metrics::UsersMetricManage",
|
285
|
+
Decidim::MetricRegistry::HIGHLIGHTED,
|
286
|
+
1
|
287
|
+
)
|
277
288
|
end
|
278
289
|
|
279
290
|
initializer "decidim.core.content_blocks" do
|
@@ -292,31 +303,59 @@ module Decidim
|
|
292
303
|
content_block.settings do |settings|
|
293
304
|
settings.attribute :welcome_text, type: :text, translated: true
|
294
305
|
end
|
306
|
+
|
307
|
+
content_block.default!
|
295
308
|
end
|
296
309
|
|
297
310
|
Decidim.content_blocks.register(:homepage, :sub_hero) do |content_block|
|
298
311
|
content_block.cell = "decidim/content_blocks/sub_hero"
|
299
312
|
content_block.public_name_key = "decidim.content_blocks.sub_hero.name"
|
313
|
+
content_block.default!
|
300
314
|
end
|
301
315
|
|
302
316
|
Decidim.content_blocks.register(:homepage, :highlighted_content_banner) do |content_block|
|
303
317
|
content_block.cell = "decidim/content_blocks/highlighted_content_banner"
|
304
318
|
content_block.public_name_key = "decidim.content_blocks.highlighted_content_banner.name"
|
319
|
+
content_block.default!
|
305
320
|
end
|
306
321
|
|
307
322
|
Decidim.content_blocks.register(:homepage, :how_to_participate) do |content_block|
|
308
323
|
content_block.cell = "decidim/content_blocks/how_to_participate"
|
309
324
|
content_block.public_name_key = "decidim.content_blocks.how_to_participate.name"
|
325
|
+
content_block.default!
|
326
|
+
end
|
327
|
+
|
328
|
+
Decidim.content_blocks.register(:homepage, :last_activity) do |content_block|
|
329
|
+
content_block.cell = "decidim/content_blocks/last_activity"
|
330
|
+
content_block.public_name_key = "decidim.content_blocks.last_activity.name"
|
331
|
+
content_block.default!
|
310
332
|
end
|
311
333
|
|
312
334
|
Decidim.content_blocks.register(:homepage, :stats) do |content_block|
|
313
335
|
content_block.cell = "decidim/content_blocks/stats"
|
314
336
|
content_block.public_name_key = "decidim.content_blocks.stats.name"
|
337
|
+
content_block.default!
|
338
|
+
end
|
339
|
+
|
340
|
+
Decidim.content_blocks.register(:homepage, :metrics) do |content_block|
|
341
|
+
content_block.cell = "decidim/content_blocks/metrics"
|
342
|
+
content_block.public_name_key = "decidim.content_blocks.metrics.name"
|
315
343
|
end
|
316
344
|
|
317
345
|
Decidim.content_blocks.register(:homepage, :footer_sub_hero) do |content_block|
|
318
346
|
content_block.cell = "decidim/content_blocks/footer_sub_hero"
|
319
347
|
content_block.public_name_key = "decidim.content_blocks.footer_sub_hero.name"
|
348
|
+
content_block.default!
|
349
|
+
end
|
350
|
+
|
351
|
+
Decidim.content_blocks.register(:homepage, :html) do |content_block|
|
352
|
+
content_block.cell = "decidim/content_blocks/html"
|
353
|
+
content_block.public_name_key = "decidim.content_blocks.html.name"
|
354
|
+
content_block.settings_form_cell = "decidim/content_blocks/html_settings_form"
|
355
|
+
|
356
|
+
content_block.settings do |settings|
|
357
|
+
settings.attribute :html_content, type: :text, translated: true
|
358
|
+
end
|
320
359
|
end
|
321
360
|
end
|
322
361
|
|
@@ -325,6 +364,15 @@ module Decidim
|
|
325
364
|
badge.levels = [1, 5, 10, 30, 50]
|
326
365
|
badge.reset = ->(user) { Decidim::User.where(invited_by: user.id).count }
|
327
366
|
end
|
367
|
+
|
368
|
+
Decidim::Gamification.register_badge(:followers) do |badge|
|
369
|
+
badge.levels = [1, 15, 30, 60, 100]
|
370
|
+
badge.reset = ->(user) { user.followers.count }
|
371
|
+
end
|
372
|
+
|
373
|
+
Decidim::Gamification.register_badge(:continuity) do |badge|
|
374
|
+
badge.levels = [2, 10, 30, 60, 180, 365]
|
375
|
+
end
|
328
376
|
end
|
329
377
|
end
|
330
378
|
end
|