decidim-admin 0.21.0 → 0.23.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim-admin might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/javascripts/decidim/admin/application.js.es6 +7 -0
- data/app/assets/javascripts/decidim/admin/budget_rule_toggler.component.js.es6 +52 -0
- data/app/assets/javascripts/decidim/admin/bundle.js +26 -32
- data/app/assets/javascripts/decidim/admin/bundle.js.map +1 -1
- data/app/assets/javascripts/decidim/admin/choose_language.js +12 -0
- data/app/assets/javascripts/decidim/admin/dynamic_fields.component.js.es6 +24 -5
- data/app/assets/javascripts/decidim/admin/form.js.es6 +24 -10
- data/app/assets/javascripts/decidim/admin/gallery.js.es6 +5 -0
- data/app/assets/javascripts/decidim/admin/newsletters.js.es6 +4 -0
- data/app/assets/javascripts/decidim/admin/officializations.js.es6 +20 -0
- data/app/assets/javascripts/decidim/admin/scope_picker_enabler.component.js.es6 +14 -0
- data/app/assets/stylesheets/decidim/admin/_decidim.scss +2 -0
- data/app/assets/stylesheets/decidim/admin/_variables.scss +1 -1
- data/app/assets/stylesheets/decidim/admin/extra/_newsletter-templates-gallery.scss +3 -0
- data/app/assets/stylesheets/decidim/admin/extra/_organization-appearance.scss +141 -0
- data/app/assets/stylesheets/decidim/admin/extra/_show_email.scss +31 -0
- data/app/assets/stylesheets/decidim/admin/extra/_title_bar.scss +4 -0
- data/app/assets/stylesheets/decidim/admin/modules/_buttons.scss +11 -1
- data/app/assets/stylesheets/decidim/admin/modules/_callouts.scss +11 -0
- data/app/assets/stylesheets/decidim/admin/modules/_cards.scss +2 -2
- data/app/assets/stylesheets/decidim/admin/modules/_filters.scss +2 -2
- data/app/assets/stylesheets/decidim/admin/modules/_forms.scss +16 -2
- data/app/assets/stylesheets/decidim/admin/modules/_import_result.scss +10 -0
- data/app/assets/stylesheets/decidim/admin/modules/_loading-spinner.scss +19 -0
- data/app/assets/stylesheets/decidim/admin/modules/_main-nav.scss +0 -1
- data/app/assets/stylesheets/decidim/admin/modules/_modules.scss +5 -1
- data/app/assets/stylesheets/decidim/admin/modules/_process-header.scss +0 -1
- data/app/assets/stylesheets/decidim/admin/modules/_secondary-nav.scss +0 -1
- data/app/assets/stylesheets/decidim/admin/modules/_table-list.scss +0 -5
- data/app/assets/stylesheets/decidim/admin/modules/_tabs.scss +7 -0
- data/app/assets/stylesheets/decidim/admin/modules/_users_statistics.scss +18 -0
- data/app/assets/stylesheets/decidim/admin/utils/_mixins.scss +42 -0
- data/app/assets/stylesheets/decidim/admin/utils/_settings.scss +4 -1
- data/app/cells/decidim/admin/content_block/show.erb +2 -2
- data/app/commands/decidim/admin/create_attachment.rb +2 -2
- data/app/commands/decidim/admin/create_newsletter.rb +34 -9
- data/app/commands/decidim/admin/destroy_share_token.rb +46 -0
- data/app/commands/decidim/admin/reorder_content_blocks.rb +1 -1
- data/app/commands/decidim/admin/update_component.rb +27 -3
- data/app/commands/decidim/admin/update_content_block.rb +25 -1
- data/app/commands/decidim/admin/update_newsletter.rb +31 -9
- data/app/commands/decidim/admin/update_organization.rb +11 -0
- data/app/commands/decidim/admin/update_organization_appearance.rb +3 -1
- data/app/controllers/concerns/decidim/admin/participatory_space_export.rb +8 -2
- data/app/controllers/decidim/admin/application_controller.rb +1 -0
- data/app/controllers/decidim/admin/authorization_workflows_controller.rb +6 -0
- data/app/controllers/decidim/admin/components_controller.rb +17 -6
- data/app/controllers/decidim/admin/dashboard_controller.rb +33 -1
- data/app/controllers/decidim/admin/metrics_controller.rb +22 -0
- data/app/controllers/decidim/admin/newsletter_templates_controller.rb +41 -0
- data/app/controllers/decidim/admin/newsletters_controller.rb +32 -4
- data/app/controllers/decidim/admin/officializations_controller.rb +8 -0
- data/app/controllers/decidim/admin/organization_appearance_controller.rb +1 -0
- data/app/controllers/decidim/admin/organization_controller.rb +4 -3
- data/app/controllers/decidim/admin/organization_homepage_content_blocks_controller.rb +2 -1
- data/app/controllers/decidim/admin/share_tokens_controller.rb +30 -0
- data/app/forms/decidim/admin/attachment_form.rb +3 -0
- data/app/forms/decidim/admin/component_form.rb +5 -22
- data/app/forms/decidim/admin/newsletter_form.rb +15 -3
- data/app/forms/decidim/admin/organization_appearance_form.rb +7 -4
- data/app/forms/decidim/admin/organization_form.rb +20 -0
- data/app/forms/decidim/admin/participatory_space_private_user_csv_import_form.rb +13 -0
- data/app/forms/decidim/admin/participatory_space_private_user_form.rb +3 -2
- data/app/forms/decidim/admin/selective_newsletter_form.rb +6 -0
- data/app/frontend/components/autocomplete.component.test.tsx +2 -1
- data/app/frontend/components/autocomplete.component.tsx +29 -0
- data/app/helpers/decidim/admin/application_helper.rb +1 -0
- data/app/helpers/decidim/admin/filterable_helper.rb +35 -27
- data/app/helpers/decidim/admin/icon_link_helper.rb +1 -1
- data/app/helpers/decidim/admin/newsletters_helper.rb +3 -1
- data/app/helpers/decidim/admin/resource_scope_helper.rb +43 -0
- data/app/helpers/decidim/admin/settings_helper.rb +52 -59
- data/app/helpers/decidim/admin/uploader_image_dimensions_helper.rb +30 -0
- data/app/models/decidim/admin/fake_newsletter.rb +49 -0
- data/app/permissions/decidim/admin/permissions.rb +7 -1
- data/app/presenters/decidim/admin/dashboard_metric_charts_presenter.rb +57 -0
- data/app/queries/decidim/admin/active_users_counter.rb +35 -0
- data/app/queries/decidim/admin/newsletter_recipients.rb +5 -8
- data/app/views/decidim/admin/attachment_collections/index.html.erb +1 -1
- data/app/views/decidim/admin/authorization_workflows/index.html.erb +1 -0
- data/app/views/decidim/admin/categories/index.html.erb +1 -1
- data/app/views/decidim/admin/components/_component.html.erb +5 -0
- data/app/views/decidim/admin/components/_form.html.erb +4 -0
- data/app/views/decidim/admin/components/_settings_fields.html.erb +2 -2
- data/app/views/decidim/admin/components/index.html.erb +1 -0
- data/app/views/decidim/admin/dashboard/show.html.erb +35 -10
- data/app/views/decidim/admin/exports/_dropdown.html.erb +6 -2
- data/app/views/decidim/admin/impersonatable_users/index.html.erb +2 -2
- data/app/views/decidim/admin/metrics/_metrics.html.erb +21 -0
- data/app/views/decidim/admin/metrics/index.html.erb +7 -0
- data/app/views/decidim/admin/newsletter_templates/index.html.erb +28 -0
- data/app/views/decidim/admin/newsletter_templates/show.html.erb +12 -0
- data/app/views/decidim/admin/newsletters/_form.html.erb +1 -7
- data/app/views/decidim/admin/newsletters/edit.html.erb +1 -1
- data/app/views/decidim/admin/newsletters/index.html.erb +1 -1
- data/app/views/decidim/admin/newsletters/new.html.erb +1 -1
- data/app/views/decidim/admin/officializations/_show_email_modal.html.erb +31 -0
- data/app/views/decidim/admin/officializations/index.html.erb +7 -3
- data/app/views/decidim/admin/officializations/show_email.html.erb +2 -0
- data/app/views/decidim/admin/organization/_form.html.erb +21 -0
- data/app/views/decidim/admin/organization_appearance/_form.html.erb +2 -72
- data/app/views/decidim/admin/organization_appearance/form/_colors.html.erb +23 -0
- data/app/views/decidim/admin/organization_appearance/form/_images.html.erb +38 -0
- data/app/views/decidim/admin/organization_appearance/form/_minimap.html.erb +46 -0
- data/app/views/decidim/admin/resource_permissions/_options_form.html.erb +1 -1
- data/app/views/decidim/admin/share_tokens/_share_tokens.html.erb +57 -0
- data/app/views/decidim/admin/shared/_filters.html.erb +3 -3
- data/app/views/decidim/admin/shared/_gallery.html.erb +21 -0
- data/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
- data/app/views/decidim/admin/user_groups/index.html.erb +4 -4
- data/app/views/decidim/admin/users_statistics/_users_count.html.erb +39 -0
- data/app/views/layouts/decidim/admin/_application.html.erb +1 -0
- data/app/views/layouts/decidim/admin/_header.html.erb +3 -0
- data/app/views/layouts/decidim/admin/_title_bar.html.erb +20 -10
- data/app/views/layouts/decidim/admin/newsletters.erb +1 -1
- data/config/locales/am-ET.yml +1 -0
- data/config/locales/ar.yml +12 -45
- data/config/locales/bg-BG.yml +16 -0
- data/config/locales/bg.yml +131 -0
- data/config/locales/ca.yml +84 -46
- data/config/locales/cs.yml +175 -137
- data/config/locales/da-DK.yml +1 -0
- data/config/locales/da.yml +1 -0
- data/config/locales/de.yml +150 -56
- data/config/locales/el.yml +814 -0
- data/config/locales/en.yml +84 -46
- data/config/locales/eo-UY.yml +0 -1
- data/config/locales/eo.yml +51 -0
- data/config/locales/es-MX.yml +84 -46
- data/config/locales/es-PY.yml +84 -46
- data/config/locales/es.yml +84 -46
- data/config/locales/et-EE.yml +1 -0
- data/config/locales/et.yml +1 -0
- data/config/locales/eu.yml +30 -59
- data/config/locales/fi-plain.yml +84 -46
- data/config/locales/fi.yml +98 -60
- data/config/locales/fr-CA.yml +847 -0
- data/config/locales/fr.yml +126 -51
- data/config/locales/ga-IE.yml +1 -0
- data/config/locales/gl.yml +156 -42
- data/config/locales/hr-HR.yml +1 -0
- data/config/locales/hr.yml +1 -0
- data/config/locales/hu.yml +55 -46
- data/config/locales/id-ID.yml +12 -41
- data/config/locales/is-IS.yml +10 -42
- data/config/locales/is.yml +568 -0
- data/config/locales/it.yml +106 -85
- data/config/locales/ja-JP.yml +855 -0
- data/config/locales/ja.yml +847 -0
- data/config/locales/ko-KR.yml +1 -0
- data/config/locales/ko.yml +1 -0
- data/config/locales/lt-LT.yml +1 -0
- data/config/locales/lt.yml +1 -0
- data/config/locales/lv.yml +795 -0
- data/config/locales/mt-MT.yml +1 -0
- data/config/locales/mt.yml +1 -0
- data/config/locales/nl.yml +74 -46
- data/config/locales/no.yml +108 -83
- data/config/locales/om-ET.yml +1 -0
- data/config/locales/pl.yml +354 -233
- data/config/locales/pt-BR.yml +13 -42
- data/config/locales/pt.yml +321 -231
- data/config/locales/ro-RO.yml +810 -0
- data/config/locales/ru.yml +11 -44
- data/config/locales/si-LK.yml +1 -0
- data/config/locales/sk-SK.yml +823 -0
- data/config/locales/sk.yml +802 -0
- data/config/locales/sl.yml +162 -0
- data/config/locales/so-SO.yml +1 -0
- data/config/locales/sr-CS.yml +586 -0
- data/config/locales/sv.yml +134 -54
- data/config/locales/sw-KE.yml +1 -0
- data/config/locales/ti-ER.yml +1 -0
- data/config/locales/tr-TR.yml +139 -50
- data/config/locales/uk.yml +10 -42
- data/config/locales/vi-VN.yml +1 -0
- data/config/locales/vi.yml +1 -0
- data/config/locales/zh-CN.yml +845 -0
- data/config/locales/zh-TW.yml +1 -0
- data/config/routes.rb +14 -3
- data/lib/decidim/admin/engine.rb +12 -9
- data/lib/decidim/admin/form_builder.rb +2 -2
- data/lib/decidim/admin/test/manage_attachment_collections_examples.rb +1 -1
- data/lib/decidim/admin/test/manage_component_permissions_examples.rb +15 -15
- data/lib/decidim/admin/version.rb +1 -1
- metadata +85 -33
- data/app/commands/decidim/admin/create_oauth_application.rb +0 -36
- data/app/commands/decidim/admin/destroy_oauth_application.rb +0 -39
- data/app/commands/decidim/admin/update_oauth_application.rb +0 -39
- data/app/controllers/decidim/admin/oauth_applications_controller.rb +0 -90
- data/app/forms/decidim/admin/oauth_application_form.rb +0 -32
- data/app/views/decidim/admin/oauth_applications/_form.html.erb +0 -19
- data/app/views/decidim/admin/oauth_applications/edit.html.erb +0 -13
- data/app/views/decidim/admin/oauth_applications/index.html.erb +0 -40
- data/app/views/decidim/admin/oauth_applications/new.html.erb +0 -13
- data/app/views/decidim/admin/oauth_applications/show.html.erb +0 -27
@@ -7,7 +7,7 @@ module Decidim
|
|
7
7
|
include Decidim::NewslettersHelper
|
8
8
|
include Decidim::Admin::NewslettersHelper
|
9
9
|
include Paginable
|
10
|
-
helper_method :newsletter, :recipients_count_query
|
10
|
+
helper_method :newsletter, :recipients_count_query, :content_block
|
11
11
|
|
12
12
|
def index
|
13
13
|
enforce_permission_to :index, :newsletter
|
@@ -17,7 +17,7 @@ module Decidim
|
|
17
17
|
|
18
18
|
def new
|
19
19
|
enforce_permission_to :create, :newsletter
|
20
|
-
@form = form(NewsletterForm).
|
20
|
+
@form = form(NewsletterForm).from_model(content_block)
|
21
21
|
end
|
22
22
|
|
23
23
|
def show
|
@@ -36,8 +36,9 @@ module Decidim
|
|
36
36
|
def create
|
37
37
|
enforce_permission_to :create, :newsletter
|
38
38
|
@form = form(NewsletterForm).from_params(params)
|
39
|
+
@form.images = images_block_context unless has_images_block_context?
|
39
40
|
|
40
|
-
CreateNewsletter.call(@form, current_user) do
|
41
|
+
CreateNewsletter.call(@form, content_block, current_user) do
|
41
42
|
on(:ok) do |newsletter|
|
42
43
|
flash.now[:notice] = I18n.t("newsletters.create.success", scope: "decidim.admin")
|
43
44
|
redirect_to action: :show, id: newsletter.id
|
@@ -53,12 +54,13 @@ module Decidim
|
|
53
54
|
|
54
55
|
def edit
|
55
56
|
enforce_permission_to :update, :newsletter, newsletter: newsletter
|
56
|
-
@form = form(NewsletterForm).from_model(
|
57
|
+
@form = form(NewsletterForm).from_model(content_block)
|
57
58
|
end
|
58
59
|
|
59
60
|
def update
|
60
61
|
enforce_permission_to :update, :newsletter, newsletter: newsletter
|
61
62
|
@form = form(NewsletterForm).from_params(params)
|
63
|
+
@form.images = images_block_context unless has_images_block_context?
|
62
64
|
|
63
65
|
UpdateNewsletter.call(newsletter, @form, current_user) do
|
64
66
|
on(:ok) do |newsletter|
|
@@ -138,6 +140,32 @@ module Decidim
|
|
138
140
|
@form ||= form(SelectiveNewsletterForm).instance
|
139
141
|
NewsletterRecipients.for(@form).size
|
140
142
|
end
|
143
|
+
|
144
|
+
def content_block
|
145
|
+
@content_block ||= content_block_for_newsletter || content_block_from_manifest
|
146
|
+
end
|
147
|
+
|
148
|
+
def content_block_from_manifest
|
149
|
+
Decidim::ContentBlock.new(
|
150
|
+
organization: current_organization,
|
151
|
+
scope_name: :newsletter_template,
|
152
|
+
manifest_name: params[:newsletter_template_id]
|
153
|
+
)
|
154
|
+
end
|
155
|
+
|
156
|
+
def content_block_for_newsletter
|
157
|
+
return nil unless @newsletter
|
158
|
+
|
159
|
+
@content_block_for_newsletter ||= @newsletter.template
|
160
|
+
end
|
161
|
+
|
162
|
+
def images_block_context
|
163
|
+
form(NewsletterForm).from_model(content_block).images
|
164
|
+
end
|
165
|
+
|
166
|
+
def has_images_block_context?
|
167
|
+
@form.images && @form.valid?
|
168
|
+
end
|
141
169
|
end
|
142
170
|
end
|
143
171
|
end
|
@@ -49,6 +49,14 @@ module Decidim
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
def show_email
|
53
|
+
enforce_permission_to :show_email, :user, user: user
|
54
|
+
|
55
|
+
Decidim.traceability.perform_action! :show_email, user, current_user
|
56
|
+
|
57
|
+
render :show_email, layout: false
|
58
|
+
end
|
59
|
+
|
52
60
|
private
|
53
61
|
|
54
62
|
def collection
|
@@ -5,6 +5,7 @@ module Decidim
|
|
5
5
|
# Controller that allows managing the appearance of the organization.
|
6
6
|
class OrganizationAppearanceController < Decidim::Admin::ApplicationController
|
7
7
|
layout "decidim/admin/settings"
|
8
|
+
helper Decidim::Admin::UploaderImageDimensionsHelper
|
8
9
|
|
9
10
|
def edit
|
10
11
|
enforce_permission_to :update, :organization, organization: current_organization
|
@@ -37,10 +37,11 @@ module Decidim
|
|
37
37
|
query = if term.start_with?("@")
|
38
38
|
query.where("nickname ILIKE ?", "#{term.delete("@")}%")
|
39
39
|
else
|
40
|
-
query.where("name ILIKE ?", "%#{term}%")
|
40
|
+
query.where("name ILIKE ?", "%#{term}%").or(
|
41
|
+
query.where("email ILIKE ?", "%#{term}%")
|
42
|
+
)
|
41
43
|
end
|
42
|
-
|
43
|
-
render json: query.all.collect { |u| { value: u.id, label: "#{u.name} (@#{u.nickname})" } }
|
44
|
+
render json: query.all.collect { |u| { value: u.id, label: "#{u.name} (@#{u.nickname}) #{u.email}" } }
|
44
45
|
else
|
45
46
|
render json: []
|
46
47
|
end
|
@@ -22,6 +22,7 @@ module Decidim
|
|
22
22
|
redirect_to edit_organization_homepage_path
|
23
23
|
end
|
24
24
|
on(:invalid) do
|
25
|
+
edit # Sets the model to the view so that it can render the form
|
25
26
|
render :edit
|
26
27
|
end
|
27
28
|
end
|
@@ -55,7 +56,7 @@ module Decidim
|
|
55
56
|
def content_block_from_manifest
|
56
57
|
Decidim::ContentBlock.create!(
|
57
58
|
organization: current_organization,
|
58
|
-
|
59
|
+
scope_name: :homepage,
|
59
60
|
manifest_name: params[:id]
|
60
61
|
)
|
61
62
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Admin
|
5
|
+
class ShareTokensController < Decidim::Admin::ApplicationController
|
6
|
+
def destroy
|
7
|
+
enforce_permission_to :destroy, :share_token, share_token: share_token
|
8
|
+
|
9
|
+
DestroyShareToken.call(share_token, current_user) do
|
10
|
+
on(:ok) do
|
11
|
+
flash[:notice] = I18n.t("share_tokens.destroy.success", scope: "decidim.admin")
|
12
|
+
end
|
13
|
+
on(:invalid) do
|
14
|
+
flash[:error] = I18n.t("share_tokens.destroy.error", scope: "decidim.admin")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
redirect_back(fallback_location: root_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def share_token
|
24
|
+
@share_token ||= Decidim::ShareToken.where(
|
25
|
+
organization: current_organization
|
26
|
+
).find(params[:id])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -16,12 +16,15 @@ module Decidim
|
|
16
16
|
mimic :attachment
|
17
17
|
|
18
18
|
validates :file, presence: true, unless: :persisted?
|
19
|
+
validates :file, passthru: { to: Decidim::Attachment }
|
19
20
|
validates :title, :description, translatable_presence: true
|
20
21
|
validates :attachment_collection, presence: true, if: ->(form) { form.attachment_collection_id.present? }
|
21
22
|
validates :attachment_collection_id, inclusion: { in: :attachment_collection_ids }, allow_blank: true
|
22
23
|
|
23
24
|
delegate :attached_to, to: :context, prefix: false
|
24
25
|
|
26
|
+
alias organization current_organization
|
27
|
+
|
25
28
|
def attachment_collections
|
26
29
|
@attachment_collections ||= attached_to.attachment_collections
|
27
30
|
end
|
@@ -23,8 +23,7 @@ module Decidim
|
|
23
23
|
attribute :default_step_settings, Object
|
24
24
|
attribute :step_settings, Hash[String => Object]
|
25
25
|
|
26
|
-
|
27
|
-
validate :amendments_visibility_options_must_be_valid
|
26
|
+
attribute :share_tokens, Array[ShareToken]
|
28
27
|
|
29
28
|
def settings?
|
30
29
|
settings.manifest.attributes.any?
|
@@ -34,6 +33,10 @@ module Decidim
|
|
34
33
|
default_step_settings.manifest.attributes.any?
|
35
34
|
end
|
36
35
|
|
36
|
+
def map_model(model)
|
37
|
+
self.share_tokens = model.share_tokens
|
38
|
+
end
|
39
|
+
|
37
40
|
private
|
38
41
|
|
39
42
|
# Overwrites Rectify::Form#form_attributes_valid? to validate nested `step_settings` attributes.
|
@@ -54,26 +57,6 @@ module Decidim
|
|
54
57
|
end
|
55
58
|
validations.all?
|
56
59
|
end
|
57
|
-
|
58
|
-
# Validates setting `participatory_texts_enabled` is not changed when there are proposals for the component.
|
59
|
-
def must_be_able_to_change_participatory_texts_setting
|
60
|
-
return unless manifest&.name == :proposals && (component = Component.find_by(id: id))
|
61
|
-
return unless settings.participatory_texts_enabled != component.settings.participatory_texts_enabled
|
62
|
-
|
63
|
-
settings.errors.add(:participatory_texts_enabled) if Decidim::Proposals::Proposal.where(component: component).any?
|
64
|
-
end
|
65
|
-
|
66
|
-
# Validates setting `amendments_visibility` is included in Decidim::Amendment::VisibilityStepSetting.options.
|
67
|
-
def amendments_visibility_options_must_be_valid
|
68
|
-
return unless manifest&.name == :proposals && settings.amendments_enabled
|
69
|
-
|
70
|
-
visibility_options = Decidim::Amendment::VisibilityStepSetting.options.map(&:last)
|
71
|
-
step_settings.each do |step, settings|
|
72
|
-
next unless visibility_options.exclude? settings[:amendments_visibility]
|
73
|
-
|
74
|
-
step_settings[step].errors.add(:amendments_visibility, :inclusion)
|
75
|
-
end
|
76
|
-
end
|
77
60
|
end
|
78
61
|
end
|
79
62
|
end
|
@@ -3,14 +3,26 @@
|
|
3
3
|
module Decidim
|
4
4
|
module Admin
|
5
5
|
# The form that validates the data to construct a valid Newsletter.
|
6
|
-
class NewsletterForm <
|
6
|
+
class NewsletterForm < ContentBlockForm
|
7
7
|
mimic :newsletter
|
8
8
|
|
9
9
|
include TranslatableAttributes
|
10
10
|
|
11
11
|
translatable_attribute :subject, String
|
12
|
-
|
13
|
-
|
12
|
+
validates :subject, translatable_presence: true
|
13
|
+
|
14
|
+
def map_model(content_block)
|
15
|
+
super(content_block)
|
16
|
+
self.subject = newsletter_for(content_block).try(:subject)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def newsletter_for(content_block)
|
22
|
+
Decidim::Newsletter
|
23
|
+
.where(organization: content_block.organization)
|
24
|
+
.find_by(id: content_block.scoped_resource_id)
|
25
|
+
end
|
14
26
|
end
|
15
27
|
end
|
16
28
|
end
|
@@ -7,6 +7,7 @@ module Decidim
|
|
7
7
|
#
|
8
8
|
class OrganizationAppearanceForm < Form
|
9
9
|
include TranslatableAttributes
|
10
|
+
include Decidim::HasUploadValidations
|
10
11
|
|
11
12
|
mimic :organization
|
12
13
|
|
@@ -34,6 +35,8 @@ module Decidim
|
|
34
35
|
attribute :success_color, String, default: "#57d685"
|
35
36
|
attribute :warning_color, String, default: "#ffae00"
|
36
37
|
attribute :alert_color, String, default: "#ec5840"
|
38
|
+
attribute :highlight_color, String, default: "#be6400"
|
39
|
+
attribute :highlight_alternative_color, String, default: "#ff5731"
|
37
40
|
|
38
41
|
translatable_attribute :cta_button_text, String
|
39
42
|
translatable_attribute :description, String
|
@@ -48,14 +51,12 @@ module Decidim
|
|
48
51
|
validates :official_img_header,
|
49
52
|
:official_img_footer,
|
50
53
|
:logo,
|
51
|
-
|
52
|
-
file_content_type: { allow: ["image/jpeg", "image/png"] }
|
54
|
+
passthru: { to: Decidim::Organization }
|
53
55
|
|
54
56
|
validates :highlighted_content_banner_action_url, presence: true, if: :highlighted_content_banner_enabled?
|
55
57
|
validates :highlighted_content_banner_image,
|
56
58
|
presence: true,
|
57
|
-
|
58
|
-
file_content_type: { allow: ["image/jpeg", "image/png"] },
|
59
|
+
passthru: { to: Decidim::Organization },
|
59
60
|
if: :highlighted_content_banner_image_is_changed?
|
60
61
|
|
61
62
|
validates :highlighted_content_banner_title,
|
@@ -74,6 +75,8 @@ module Decidim
|
|
74
75
|
validates :omnipresent_banner_title, translatable_presence: true, if: :enable_omnipresent_banner?
|
75
76
|
validates :omnipresent_banner_short_description, translatable_presence: true, if: :enable_omnipresent_banner?
|
76
77
|
|
78
|
+
alias organization current_organization
|
79
|
+
|
77
80
|
private
|
78
81
|
|
79
82
|
def highlighted_content_banner_enabled?
|
@@ -21,7 +21,10 @@ module Decidim
|
|
21
21
|
attribute :default_locale, String
|
22
22
|
attribute :badges_enabled, Boolean
|
23
23
|
attribute :user_groups_enabled, Boolean
|
24
|
+
attribute :comments_max_length, Integer
|
24
25
|
attribute :rich_text_editor_in_public_views, Boolean
|
26
|
+
attribute :enable_machine_translations, Boolean
|
27
|
+
attribute :machine_translation_display_priority, String
|
25
28
|
|
26
29
|
attribute :send_welcome_notification, Boolean
|
27
30
|
attribute :customize_welcome_notification, Boolean
|
@@ -39,12 +42,29 @@ module Decidim
|
|
39
42
|
validates :default_locale, :reference_prefix, presence: true
|
40
43
|
validates :default_locale, inclusion: { in: :available_locales }
|
41
44
|
validates :admin_terms_of_use_body, translatable_presence: true
|
45
|
+
validates :comments_max_length, numericality: { greater_than: 0 }, if: ->(form) { form.comments_max_length.present? }
|
46
|
+
validates :machine_translation_display_priority,
|
47
|
+
inclusion: { in: Decidim::Organization::AVAILABLE_MACHINE_TRANSLATION_DISPLAY_PRIORITIES },
|
48
|
+
if: :machine_translation_enabled?
|
49
|
+
|
50
|
+
def machine_translation_priorities
|
51
|
+
Decidim::Organization::AVAILABLE_MACHINE_TRANSLATION_DISPLAY_PRIORITIES.map do |priority|
|
52
|
+
[
|
53
|
+
priority,
|
54
|
+
I18n.t("activemodel.attributes.organization.machine_translation_display_priority_#{priority}")
|
55
|
+
]
|
56
|
+
end
|
57
|
+
end
|
42
58
|
|
43
59
|
private
|
44
60
|
|
45
61
|
def available_locales
|
46
62
|
current_organization.available_locales
|
47
63
|
end
|
64
|
+
|
65
|
+
def machine_translation_enabled?
|
66
|
+
Decidim.config.enable_machine_translations
|
67
|
+
end
|
48
68
|
end
|
49
69
|
end
|
50
70
|
end
|
@@ -1,13 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "csv"
|
4
|
+
|
3
5
|
module Decidim
|
4
6
|
module Admin
|
5
7
|
# A form object used to upload CSV to batch participatory space private users.
|
6
8
|
#
|
7
9
|
class ParticipatorySpacePrivateUserCsvImportForm < Form
|
8
10
|
attribute :file
|
11
|
+
attribute :user_name, String
|
12
|
+
attribute :email, String
|
9
13
|
|
10
14
|
validates :file, presence: true
|
15
|
+
validate :validate_csv
|
16
|
+
|
17
|
+
def validate_csv
|
18
|
+
return if file.blank?
|
19
|
+
|
20
|
+
CSV.foreach(file.path) do |_email, user_name|
|
21
|
+
errors.add(:user_name, :invalid) unless user_name.match?(UserBaseEntity::REGEXP_NAME)
|
22
|
+
end
|
23
|
+
end
|
11
24
|
end
|
12
25
|
end
|
13
26
|
end
|
@@ -11,8 +11,9 @@ module Decidim
|
|
11
11
|
attribute :name, String
|
12
12
|
attribute :email, String
|
13
13
|
|
14
|
-
validates :email, presence: true
|
15
|
-
|
14
|
+
validates :name, :email, presence: true
|
15
|
+
|
16
|
+
validates :name, format: { with: UserBaseEntity::REGEXP_NAME }
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
@@ -24,6 +24,12 @@ module Decidim
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
# Make sure the empty scope is not passed because then some logic could
|
28
|
+
# assume erroneously that some scope is selected.
|
29
|
+
def scope_ids
|
30
|
+
super.select(&:presence)
|
31
|
+
end
|
32
|
+
|
27
33
|
private
|
28
34
|
|
29
35
|
def at_least_one_participatory_space_selected
|
@@ -11,9 +11,10 @@ describe("<Autocomplete />", () => {
|
|
11
11
|
const noResultsText = "No results found";
|
12
12
|
const searchPromptText = "Type to search";
|
13
13
|
const searchURL = "/some/url";
|
14
|
+
const changeURL = "/some/other/url";
|
14
15
|
|
15
16
|
it("renders a div of Select", () => {
|
16
|
-
const wrapper = shallow(<Autocomplete name={name} selected={selected} options={options} noResultsText={noResultsText} placeholder={placeholder} searchPromptText={searchPromptText} searchURL={searchURL} />);
|
17
|
+
const wrapper = shallow(<Autocomplete name={name} selected={selected} options={options} noResultsText={noResultsText} placeholder={placeholder} searchPromptText={searchPromptText} searchURL={searchURL} changeURL={changeURL} />);
|
17
18
|
expect(wrapper.find(".autocomplete-field").exists()).toBeTruthy();
|
18
19
|
});
|
19
20
|
});
|
@@ -43,6 +43,10 @@ export interface AutocompleteProps {
|
|
43
43
|
* The URL where fetch content
|
44
44
|
*/
|
45
45
|
searchURL: string;
|
46
|
+
/**
|
47
|
+
* The URL to call when selected option changes
|
48
|
+
*/
|
49
|
+
changeURL: string;
|
46
50
|
}
|
47
51
|
|
48
52
|
interface AutocompleteState {
|
@@ -112,6 +116,31 @@ export class Autocomplete extends React.Component<AutocompleteProps, Autocomplet
|
|
112
116
|
|
113
117
|
private handleChange = (selectedOption: any) => {
|
114
118
|
this.setState({ selectedOption });
|
119
|
+
|
120
|
+
if (this.props.changeURL) {
|
121
|
+
axios.get(this.props.changeURL, {
|
122
|
+
headers: {
|
123
|
+
Accept: "text/javascript"
|
124
|
+
},
|
125
|
+
withCredentials: true,
|
126
|
+
params: {
|
127
|
+
id: selectedOption.value
|
128
|
+
}
|
129
|
+
})
|
130
|
+
.then((response) => {
|
131
|
+
const script = document.createElement("script");
|
132
|
+
script.type = "text/javascript";
|
133
|
+
script.innerHTML = response.data;
|
134
|
+
document.getElementsByTagName("head")[0].appendChild(script);
|
135
|
+
})
|
136
|
+
.catch((error: any) => {
|
137
|
+
if (axios.isCancel(error)) {
|
138
|
+
// console.log("Request canceled", error.message);
|
139
|
+
} else {
|
140
|
+
//
|
141
|
+
}
|
142
|
+
});
|
143
|
+
}
|
115
144
|
}
|
116
145
|
|
117
146
|
private filterOptions = (options: any, filter: any, excludeOptions: any) => {
|