decidim-admin 0.25.1 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/app/commands/decidim/admin/create_import_example.rb +21 -0
  3. data/app/commands/decidim/admin/create_static_page.rb +9 -3
  4. data/app/commands/decidim/admin/update_organization_appearance.rb +2 -1
  5. data/app/controllers/concerns/decidim/admin/user_groups/filterable.rb +45 -0
  6. data/app/controllers/concerns/decidim/moderated_users/admin/filterable.rb +51 -0
  7. data/app/controllers/decidim/admin/global_moderations_controller.rb +2 -2
  8. data/app/controllers/decidim/admin/imports_controller.rb +48 -10
  9. data/app/controllers/decidim/admin/moderated_users_controller.rb +2 -2
  10. data/app/controllers/decidim/admin/moderations_controller.rb +2 -2
  11. data/app/controllers/decidim/admin/scopes_controller.rb +2 -1
  12. data/app/controllers/decidim/admin/user_groups_controller.rb +13 -5
  13. data/app/forms/decidim/admin/import_example_form.rb +50 -0
  14. data/app/forms/decidim/admin/import_form.rb +46 -40
  15. data/app/forms/decidim/admin/organization_appearance_form.rb +1 -0
  16. data/app/helpers/decidim/admin/imports_helper.rb +16 -6
  17. data/app/helpers/decidim/admin/resource_scope_helper.rb +9 -0
  18. data/app/helpers/decidim/admin/settings_helper.rb +13 -0
  19. data/app/packs/entrypoints/decidim_admin.js +0 -1
  20. data/app/packs/src/decidim/admin/dynamic_fields.component.js +8 -0
  21. data/app/permissions/decidim/admin/permissions.rb +1 -0
  22. data/app/views/decidim/admin/imports/_dropdown.html.erb +9 -4
  23. data/app/views/decidim/admin/imports/new.html.erb +24 -22
  24. data/app/views/decidim/admin/moderated_users/_report.html.erb +0 -1
  25. data/app/views/decidim/admin/moderated_users/index.html.erb +5 -2
  26. data/app/views/decidim/admin/moderations/_report.html.erb +0 -1
  27. data/app/views/decidim/admin/moderations/index.html.erb +1 -1
  28. data/app/views/decidim/admin/organization_appearance/form/_colors.html.erb +7 -0
  29. data/app/views/decidim/admin/participatory_space_private_users/index.html.erb +12 -4
  30. data/app/views/decidim/admin/user_groups/index.html.erb +8 -44
  31. data/app/views/layouts/decidim/admin/_callouts_full.html.erb +4 -0
  32. data/app/views/layouts/decidim/admin/_title_bar.html.erb +2 -2
  33. data/config/brakeman.ignore +26 -0
  34. data/config/locales/ar.yml +19 -8
  35. data/config/locales/ca.yml +45 -15
  36. data/config/locales/cs.yml +50 -13
  37. data/config/locales/de.yml +42 -14
  38. data/config/locales/el.yml +0 -15
  39. data/config/locales/en.yml +46 -17
  40. data/config/locales/es-MX.yml +44 -14
  41. data/config/locales/es-PY.yml +44 -14
  42. data/config/locales/es.yml +45 -15
  43. data/config/locales/eu.yml +34 -23
  44. data/config/locales/fi-plain.yml +43 -14
  45. data/config/locales/fi.yml +47 -18
  46. data/config/locales/fr-CA.yml +43 -14
  47. data/config/locales/fr.yml +58 -29
  48. data/config/locales/ga-IE.yml +1 -6
  49. data/config/locales/gl.yml +43 -14
  50. data/config/locales/hu.yml +1 -9
  51. data/config/locales/id-ID.yml +1 -8
  52. data/config/locales/is-IS.yml +0 -7
  53. data/config/locales/it.yml +7 -14
  54. data/config/locales/ja.yml +92 -67
  55. data/config/locales/lb-LU.yml +1034 -0
  56. data/config/locales/lb.yml +7 -16
  57. data/config/locales/lv.yml +0 -7
  58. data/config/locales/nl.yml +73 -13
  59. data/config/locales/no.yml +241 -8
  60. data/config/locales/pl.yml +8 -14
  61. data/config/locales/pt-BR.yml +3 -15
  62. data/config/locales/pt.yml +8 -15
  63. data/config/locales/ro-RO.yml +51 -18
  64. data/config/locales/ru.yml +0 -7
  65. data/config/locales/sk.yml +0 -7
  66. data/config/locales/sr-CS.yml +1 -6
  67. data/config/locales/sv.yml +44 -15
  68. data/config/locales/tr-TR.yml +1 -8
  69. data/config/locales/uk.yml +0 -8
  70. data/config/locales/val-ES.yml +14 -0
  71. data/config/locales/zh-CN.yml +0 -7
  72. data/lib/decidim/admin/engine.rb +5 -0
  73. data/lib/decidim/admin/form_builder.rb +8 -1
  74. data/lib/decidim/admin/import/creator.rb +32 -12
  75. data/lib/decidim/admin/import/importer.rb +32 -14
  76. data/lib/decidim/admin/import/readers/base.rb +23 -0
  77. data/lib/decidim/admin/import/readers/csv.rb +15 -0
  78. data/lib/decidim/admin/import/readers/json.rb +73 -3
  79. data/lib/decidim/admin/import/readers/xlsx.rb +25 -1
  80. data/lib/decidim/admin/import/readers.rb +7 -1
  81. data/lib/decidim/admin/import/verifier.rb +169 -0
  82. data/lib/decidim/admin/import.rb +3 -0
  83. data/lib/decidim/admin/test/filters_participatory_space_user_roles_examples.rb +165 -0
  84. data/lib/decidim/admin/test/manage_paginated_collection_examples.rb +8 -2
  85. data/lib/decidim/admin/test.rb +1 -0
  86. data/lib/decidim/admin/version.rb +1 -1
  87. metadata +20 -13
  88. data/app/packs/src/decidim/admin/import_guidance.js +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: afcd176e5dce1556e6efeb0e9452f6049292a20de5c02840451f88c82ca50fed
4
- data.tar.gz: 5c2e6a1cc92ef8c271fcd6dd67b249ca0ae969da7893dc602d5216fb9ab464f6
3
+ metadata.gz: 86afc8162ed8463d2e4871528607fa140587c24510441f53ea9636bc49668874
4
+ data.tar.gz: 3ad4e80c83cbdd59cc006c84a6110ba28aa85a26056b85ca3c5b6fb62e68b93f
5
5
  SHA512:
6
- metadata.gz: bffde11b311b8924b2fb3be9cd563107e0394336016e477dbec83a8a2ea5964245eed7311cf8b6e767d7e10c40020a0fd187ef8a57f8061acc20f2f6888b2e84
7
- data.tar.gz: 982c6ec83a93dbb4399037f652251a667a4f1c730c87ff0ca06c380de4811eeb772a896ed204a44835c137fdb80fad9193ceb2085aadf0a3596e7907c9eb25aa
6
+ metadata.gz: 6bd5c8d8cf9b364ca551b17f139a55cb260825b6af6dc05aa286928bc6df0158b714b01b7706e083b33d53d997ec844db76488c7d7fcb6caabc24d893dba11e2
7
+ data.tar.gz: 00fe8f9837da7f2b6a0602c77b5e0e497f464e4ed868b767d336d00ad705095899cc27cf48e934e1f8ef5e85b0ca6977d1884854caa7b46f04d3cc7388fcc3aa
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ class CreateImportExample < Rectify::Command
6
+ def initialize(form)
7
+ @form = form
8
+ end
9
+
10
+ def call
11
+ return broadcast(:invalid) if form.invalid?
12
+
13
+ broadcast(:ok, form.example)
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :form
19
+ end
20
+ end
21
+ end
@@ -34,15 +34,21 @@ module Decidim
34
34
  @page = Decidim.traceability.create!(
35
35
  StaticPage,
36
36
  form.current_user,
37
+ attributes
38
+ )
39
+ end
40
+
41
+ def attributes
42
+ {
43
+ organization: form.organization,
37
44
  title: form.title,
38
45
  slug: form.slug,
39
- content: form.content,
40
46
  show_in_footer: form.show_in_footer,
41
47
  weight: form.weight,
42
48
  topic: form.topic,
43
- organization: form.organization,
49
+ content: form.content,
44
50
  allow_public_access: form.allow_public_access
45
- )
51
+ }
46
52
  end
47
53
 
48
54
  def update_organization_tos_version
@@ -102,7 +102,8 @@ module Decidim
102
102
  warning: form.warning_color,
103
103
  alert: form.alert_color,
104
104
  highlight: form.highlight_color,
105
- "highlight-alternative": form.highlight_alternative_color
105
+ "highlight-alternative": form.highlight_alternative_color,
106
+ theme: form.theme_color
106
107
  }
107
108
  }
108
109
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module Admin
7
+ module UserGroups
8
+ module Filterable
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include Decidim::Admin::Filterable
13
+
14
+ private
15
+
16
+ def base_query
17
+ collection
18
+ end
19
+
20
+ def search_field_predicate
21
+ :name_or_nickname_or_email_cont
22
+ end
23
+
24
+ def filters
25
+ [
26
+ :state_eq
27
+ ]
28
+ end
29
+
30
+ def filters_with_values
31
+ {
32
+ state_eq: user_groups_states
33
+ }
34
+ end
35
+
36
+ protected
37
+
38
+ def user_groups_states
39
+ %w(all pending rejected verified)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module ModeratedUsers
7
+ module Admin
8
+ module Filterable
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include Decidim::Admin::Filterable
13
+
14
+ private
15
+
16
+ def base_query
17
+ collection
18
+ end
19
+
20
+ def filters
21
+ [
22
+ :reports_reason_eq
23
+ ]
24
+ end
25
+
26
+ def filters_with_values
27
+ {
28
+ reports_reason_eq: report_reasons
29
+ }
30
+ end
31
+
32
+ def dynamically_translated_filters
33
+ []
34
+ end
35
+
36
+ def search_field_predicate
37
+ :user_name_or_user_nickname_or_user_email_cont
38
+ end
39
+
40
+ def report_reasons
41
+ Decidim::UserReport::REASONS
42
+ end
43
+
44
+ def extra_allowed_params
45
+ [:per_page, :blocked]
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -14,9 +14,9 @@ module Decidim
14
14
  def collection
15
15
  @collection ||=
16
16
  if params[:hidden]
17
- moderations_for_user.where.not(hidden_at: nil)
17
+ moderations_for_user.hidden
18
18
  else
19
- moderations_for_user.where(hidden_at: nil)
19
+ moderations_for_user.not_hidden
20
20
  end
21
21
  end
22
22
 
@@ -5,24 +5,24 @@ module Decidim
5
5
  # This controller allows admins to import resources from a file.
6
6
  class ImportsController < Decidim::Admin::ApplicationController
7
7
  include Decidim::ComponentPathHelper
8
- helper UserGroupHelper
8
+
9
+ helper_method :import_manifest
9
10
 
10
11
  def new
11
12
  enforce_permission_to :import, :component_data, component: current_component
12
- @form = form(Admin::ImportForm).from_params(
13
- {
14
- # We need to set "default" creator because form-class doesn't have context / current_component
15
- # when it sets it's default values.
16
- creator: current_component.manifest.import_manifests.first.creator
17
- },
13
+ raise ActionController::RoutingError, "Not Found" unless import_manifest
14
+
15
+ @form = form(import_manifest.form_class).from_params(
16
+ { name: import_manifest.name },
18
17
  current_component: current_component
19
18
  )
20
19
  end
21
20
 
22
21
  def create
23
22
  enforce_permission_to :import, :component_data, component: current_component
23
+ raise ActionController::RoutingError, "Not Found" unless import_manifest
24
24
 
25
- @form = form(Admin::ImportForm).from_params(
25
+ @form = form(import_manifest.form_class).from_params(
26
26
  params,
27
27
  current_component: current_component,
28
28
  current_organization: current_organization
@@ -31,8 +31,8 @@ module Decidim
31
31
  CreateImport.call(@form) do
32
32
  on(:ok) do |imported_data|
33
33
  flash[:notice] = t("decidim.admin.imports.notice",
34
- number: imported_data.length,
35
- resource_name: imported_data.first.resource_manifest.name.pluralize)
34
+ count: imported_data.length,
35
+ resource_name: import_manifest.message(:resource_name, count: imported_data.length))
36
36
  redirect_to manage_component_path(current_component)
37
37
  end
38
38
 
@@ -43,8 +43,46 @@ module Decidim
43
43
  end
44
44
  end
45
45
 
46
+ def example
47
+ enforce_permission_to :import, :component_data, component: current_component
48
+ raise ActionController::RoutingError, "Not Found" unless import_manifest
49
+
50
+ @form = form(Decidim::Admin::ImportExampleForm).from_params(params).with_context(
51
+ current_component: current_component,
52
+ current_organization: current_organization
53
+ )
54
+
55
+ respond_to do |format|
56
+ @form.available_formats.each do |key, mime|
57
+ format.public_send(key) do
58
+ CreateImportExample.call(@form) do
59
+ on(:ok) do |data|
60
+ filename = "#{current_component.manifest_name}-#{import_manifest.name}-example.#{key}"
61
+ send_data data.read, disposition: :attachment, filename: filename, type: mime
62
+ end
63
+
64
+ on(:invalid) do
65
+ flash[:alert] = t("decidim.admin.imports.example_error")
66
+ redirect_to admin_imports_path(current_component, name: import_name)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+
46
74
  private
47
75
 
76
+ def import_manifest
77
+ @import_manifest ||= current_component.manifest.import_manifests.find do |import_manifest|
78
+ import_manifest.name.to_s == import_name
79
+ end
80
+ end
81
+
82
+ def import_name
83
+ params[:name]
84
+ end
85
+
48
86
  def current_component
49
87
  @current_component ||= current_participatory_space.components.find(params[:component_id])
50
88
  end
@@ -3,14 +3,14 @@
3
3
  module Decidim
4
4
  module Admin
5
5
  class ModeratedUsersController < Decidim::Admin::ApplicationController
6
- include Decidim::Moderations::Admin::Filterable
6
+ include Decidim::ModeratedUsers::Admin::Filterable
7
7
 
8
8
  layout "decidim/admin/users"
9
9
 
10
10
  def index
11
11
  enforce_permission_to :read, :moderate_users
12
12
 
13
- @moderated_users = filtered_collection.page(params[:page]).per(15)
13
+ @moderated_users = filtered_collection
14
14
  end
15
15
 
16
16
  def ignore
@@ -72,9 +72,9 @@ module Decidim
72
72
  def collection
73
73
  @collection ||= begin
74
74
  if params[:hidden]
75
- participatory_space_moderations.where.not(hidden_at: nil)
75
+ participatory_space_moderations.hidden
76
76
  else
77
- participatory_space_moderations.where(hidden_at: nil)
77
+ participatory_space_moderations.not_hidden
78
78
  end
79
79
  end
80
80
  end
@@ -10,7 +10,8 @@ module Decidim
10
10
 
11
11
  def index
12
12
  enforce_permission_to :read, :scope
13
- @scopes = children_scopes.order(Arel.sql("name->'#{I18n.locale}' ASC"))
13
+ field = Arel::Nodes::InfixOperation.new("->", Decidim::Scope.arel_table[:name], Arel::Nodes.build_quoted(I18n.locale))
14
+ @scopes = children_scopes.order(Arel::Nodes::InfixOperation.new("", field, Arel.sql("ASC")))
14
15
  end
15
16
 
16
17
  def new
@@ -6,6 +6,7 @@ module Decidim
6
6
  #
7
7
  class UserGroupsController < Decidim::Admin::ApplicationController
8
8
  include UserGroups
9
+ include Decidim::Admin::UserGroups::Filterable
9
10
 
10
11
  before_action :enforce_user_groups_enabled
11
12
 
@@ -13,11 +14,8 @@ module Decidim
13
14
 
14
15
  def index
15
16
  enforce_permission_to :index, :user_group
16
- @query = params[:q]
17
- @state = params[:state]
18
17
 
19
- @user_groups = Decidim::Admin::UserGroupsEvaluation.for(collection, @query, @state)
20
- .page(params[:page]).per(15)
18
+ @user_groups = filtered_collection
21
19
  end
22
20
 
23
21
  def verify
@@ -56,10 +54,20 @@ module Decidim
56
54
 
57
55
  private
58
56
 
57
+ def filtered_collection
58
+ paginate(query.result)
59
+ end
60
+
61
+ def base_query
62
+ Decidim::Admin::UserGroupsEvaluation.for(collection, @query, @state)
63
+ end
64
+
59
65
  def collection
60
66
  UserGroup
61
- .includes(:memberships)
67
+ .left_outer_joins(:memberships)
68
+ .select("decidim_users.*, COUNT(decidim_user_group_memberships.decidim_user_group_id) as users_count")
62
69
  .where(decidim_user_group_memberships: { decidim_user_id: current_organization.users })
70
+ .group(Arel.sql("decidim_users.id"))
63
71
  end
64
72
  end
65
73
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ class ImportExampleForm < Form
6
+ attribute :name, String
7
+ attribute :format, String
8
+
9
+ validates :name, presence: true
10
+ validates :format, presence: true
11
+ validates :manifest, presence: true
12
+ validates :reader_klass, presence: true
13
+ validates :example_data, presence: true
14
+
15
+ def example
16
+ reader.example_file(example_data)
17
+ end
18
+
19
+ def available_formats
20
+ Decidim::Admin::Import::Readers::ACCEPTED_MIME_TYPES
21
+ end
22
+
23
+ private
24
+
25
+ def manifest
26
+ @manifest ||= current_component.manifest.import_manifests.find do |import_manifest|
27
+ import_manifest.name.to_s == name
28
+ end
29
+ end
30
+
31
+ def example_data
32
+ return unless manifest
33
+
34
+ manifest.example(self, current_component)
35
+ end
36
+
37
+ def reader
38
+ @reader ||= begin
39
+ return unless reader_klass
40
+
41
+ reader_klass.new("/dev/null")
42
+ end
43
+ end
44
+
45
+ def reader_klass
46
+ @reader_klass ||= Decidim::Admin::Import::Readers.search_by_file_extension(format)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -6,36 +6,23 @@ module Decidim
6
6
  ACCEPTED_MIME_TYPES = Decidim::Admin::Import::Readers::ACCEPTED_MIME_TYPES
7
7
  include Decidim::HasUploadValidations
8
8
 
9
- attribute :creator, String, default: ->(form, _attribute) { form.creators.first[:creator].to_s }
9
+ attribute :name, String
10
10
  attribute :file
11
- attribute :user_group_id, Integer
12
11
 
13
12
  validates :file, presence: true
14
- validates :creator, presence: true
15
- validate :accepted_mime_type
16
- validate :check_invalid_lines
13
+ validates :name, presence: true
14
+ validate :check_accepted_mime_type
15
+ validate :check_invalid_file, if: -> { file.present? && accepted_mime_type? }
16
+ validate :verify_import, if: -> { file.present? && accepted_mime_type? && !importer.invalid_file? }
17
17
 
18
- def check_invalid_lines
19
- return if file.blank? || !accepted_mime_type
20
-
21
- importer.prepare
22
- invalid_lines = importer.invalid_lines
23
- errors.add(:file, I18n.t("decidim.admin.imports.invalid_lines", invalid_lines: invalid_lines.join(","))) unless invalid_lines.empty?
24
- end
25
-
26
- def file_path
27
- file&.path
18
+ def importer
19
+ @importer ||= importer_for(file_path, mime_type)
28
20
  end
29
21
 
30
- def mime_type
31
- file&.content_type
32
- end
22
+ private
33
23
 
34
- def accepted_mime_type
35
- accepted_mime_types = ACCEPTED_MIME_TYPES.values
36
- return true if accepted_mime_types.include?(mime_type)
37
- # Avoid duplicating error messages
38
- return false if errors[:file].present?
24
+ def check_accepted_mime_type
25
+ return if accepted_mime_type?
39
26
 
40
27
  errors.add(
41
28
  :file,
@@ -46,41 +33,60 @@ module Decidim
46
33
  end.join(", ")
47
34
  )
48
35
  )
49
- false
50
36
  end
51
37
 
52
- def creators
53
- @creators ||= current_component.manifest.import_manifests.map do |manifest|
54
- { creator: manifest.creator, name: manifest.creator.to_s.split("::").last.downcase }
55
- end
38
+ def check_invalid_file
39
+ return unless importer.invalid_file?
40
+
41
+ errors.add(:file, I18n.t("activemodel.errors.new_import.attributes.file.invalid_file"))
56
42
  end
57
43
 
58
- def creator_class
59
- return creator.constantize if creator.is_a?(String)
44
+ def verify_import
45
+ return if importer.verify
60
46
 
61
- creator
47
+ importer.errors.each do |_col, message|
48
+ errors.add(:file, message)
49
+ end
62
50
  end
63
51
 
64
- def user_group
65
- @user_group ||= Decidim::UserGroup.find_by(
66
- organization: current_organization,
67
- id: user_group_id.to_i
68
- )
52
+ def file_path
53
+ file&.path
69
54
  end
70
55
 
71
- def importer
72
- @importer ||= importer_for(file_path, mime_type)
56
+ def mime_type
57
+ file&.content_type
58
+ end
59
+
60
+ def creator_class
61
+ manifest.creator
73
62
  end
74
63
 
75
64
  def importer_for(filepath, mime_type)
76
- context[:user_group] = user_group
77
65
  Import::ImporterFactory.build(
78
66
  filepath,
79
67
  mime_type,
80
- context: context,
68
+ context: importer_context,
81
69
  creator: creator_class
82
70
  )
83
71
  end
72
+
73
+ protected
74
+
75
+ def accepted_mime_type?
76
+ return true if ACCEPTED_MIME_TYPES.values.include?(mime_type)
77
+
78
+ false
79
+ end
80
+
81
+ def importer_context
82
+ context
83
+ end
84
+
85
+ def manifest
86
+ @manifest ||= current_component.manifest.import_manifests.find do |import_manifest|
87
+ import_manifest.name.to_s == name
88
+ end
89
+ end
84
90
  end
85
91
  end
86
92
  end
@@ -36,6 +36,7 @@ module Decidim
36
36
  attribute :alert_color, String, default: "#ec5840"
37
37
  attribute :highlight_color, String, default: "#be6400"
38
38
  attribute :highlight_alternative_color, String, default: "#ff5731"
39
+ attribute :theme_color, String, default: "#ef604d"
39
40
 
40
41
  translatable_attribute :cta_button_text, String
41
42
  translatable_attribute :description, String
@@ -12,13 +12,13 @@ module Decidim
12
12
  # resource_id - The resource id that is passed to route.
13
13
  #
14
14
  # Returns a rendered dropdown.
15
- def import_dropdown(component = current_component, resource_id = nil)
16
- locals = { component: component, resource_id: resource_id }
17
- locals[:block] = yield if block_given?
18
- render partial: "decidim/admin/imports/dropdown", locals: locals
15
+ def import_dropdown(component = current_component, resource_id: nil)
16
+ render "decidim/admin/imports/dropdown", component: component, resource_id: resource_id, custom: block_given? do
17
+ yield if block_given?
18
+ end
19
19
  end
20
20
 
21
- # Routes to the correct importer for a component.
21
+ # Route to the correct importer for a component.
22
22
  #
23
23
  # component - The component to be routed.
24
24
  # options - Extra options that need to be passed to the route.
@@ -28,10 +28,20 @@ module Decidim
28
28
  EngineRouter.admin_proxy(component.participatory_space).new_component_import_path(options.merge(component_id: component))
29
29
  end
30
30
 
31
+ # Route to the correct importer example for a component.
32
+ #
33
+ # component - The component to be routed.
34
+ # options - Extra options that need to be passed to the route.
35
+ #
36
+ # Returns the path to the component importer example.
37
+ def admin_imports_example_path(component, options)
38
+ EngineRouter.admin_proxy(component.participatory_space).example_component_imports_path(options.merge(component_id: component))
39
+ end
40
+
31
41
  # Public: A formatted collection of mime_type to be used in forms.
32
42
  def mime_types
33
43
  accepted_mime_types = Decidim::Admin::Import::Readers::ACCEPTED_MIME_TYPES.keys
34
- accepted_mime_types.map { |mime_type| t("decidim.admin.imports.new.accepted_mime_types.#{mime_type}") }.join(", ")
44
+ accepted_mime_types.index_with { |mime_type| I18n.t("decidim.admin.imports.new.accepted_mime_types.#{mime_type}") }
35
45
  end
36
46
 
37
47
  # Returns verified user groups of current user
@@ -29,6 +29,15 @@ module Decidim
29
29
  content_tag(:td, scope_name)
30
30
  end
31
31
 
32
+ # Public: This helper shows th with the sort link element.
33
+ def th_scope_sort_link
34
+ return unless resource_with_scopes_enabled?
35
+
36
+ content_tag(:th) do
37
+ sort_link(query, :scope_name, t("decidim.admin.resources.index.headers.scope"))
38
+ end
39
+ end
40
+
32
41
  private
33
42
 
34
43
  def resource_with_scopes_enabled?
@@ -12,6 +12,7 @@ module Decidim
12
12
  integer: :number_field,
13
13
  string: :text_field,
14
14
  text: :text_area,
15
+ select: :select_field,
15
16
  scope: :scope_field,
16
17
  enum: :collection_radio_buttons,
17
18
  time: :datetime_field
@@ -49,6 +50,8 @@ module Decidim
49
50
  form.send(:translated, form_method, name, options)
50
51
  elsif form_method == :collection_radio_buttons
51
52
  render_enum_form_field(form, attribute, name, i18n_scope, options)
53
+ elsif form_method == :select_field
54
+ render_select_form_field(form, attribute, name, i18n_scope, options)
52
55
  elsif form_method == :scope_field
53
56
  scopes_picker_field(form, name)
54
57
  else
@@ -59,6 +62,16 @@ module Decidim
59
62
 
60
63
  private
61
64
 
65
+ def render_select_form_field(form, attribute, name, i18n_scope, options)
66
+ html = form.select(
67
+ name,
68
+ attribute.build_choices.map { |o| [t("#{name}_options.#{o}", scope: i18n_scope), o] },
69
+ { include_blank: attribute.include_blank, label: options[:label] }
70
+ )
71
+ html << content_tag(:p, options[:help_text], class: "help-text") if options[:help_text]
72
+ html
73
+ end
74
+
62
75
  # Returns a radio buttons collection input for the given attribute
63
76
  def render_enum_form_field(form, attribute, name, i18n_scope, options)
64
77
  html = label_tag(name) do
@@ -20,7 +20,6 @@ import "src/decidim/admin/resources_permissions"
20
20
  import "src/decidim/admin/welcome_notification"
21
21
  import "src/decidim/admin/newsletters"
22
22
  import "src/decidim/admin/form"
23
- import "src/decidim/admin/import_guidance"
24
23
  import "src/decidim/admin/external_domain_whitelist"
25
24
  import "src/decidim/confirm"
26
25
  import "src/decidim/admin/draggable-list"
@@ -6,8 +6,10 @@ class DynamicFieldsComponent {
6
6
  this.fieldSelector = options.fieldSelector;
7
7
  this.addFieldButtonSelector = options.addFieldButtonSelector;
8
8
  this.addSeparatorButtonSelector = options.addSeparatorButtonSelector;
9
+ this.addTitleAndDescriptionButtonSelector = options.addTitleAndDescriptionButtonSelector;
9
10
  this.fieldTemplateSelector = options.fieldTemplateSelector;
10
11
  this.separatorTemplateSelector = options.separatorTemplateSelector;
12
+ this.TitleAndDescriptionTemplateSelector = options.TitleAndDescriptionTemplateSelector;
11
13
  this.removeFieldButtonSelector = options.removeFieldButtonSelector;
12
14
  this.moveUpFieldButtonSelector = options.moveUpFieldButtonSelector;
13
15
  this.moveDownFieldButtonSelector = options.moveDownFieldButtonSelector;
@@ -84,6 +86,12 @@ class DynamicFieldsComponent {
84
86
  );
85
87
  }
86
88
 
89
+ if (this.addTitleAndDescriptionButtonSelector) {
90
+ $(this.wrapperSelector).on("click", this.addTitleAndDescriptionButtonSelector, (event) =>
91
+ this._bindSafeEvent(event, () => this._addField(this.TitleAndDescriptionTemplateSelector))
92
+ );
93
+ }
94
+
87
95
  $(this.wrapperSelector).on("click", this.removeFieldButtonSelector, (event) =>
88
96
  this._bindSafeEvent(event, (target) => this._removeField(target))
89
97
  );
@@ -42,6 +42,7 @@ module Decidim
42
42
  allow! if permission_action.subject == :component
43
43
  allow! if permission_action.subject == :admin_user
44
44
  allow! if permission_action.subject == :attachment
45
+ allow! if permission_action.subject == :editor_image
45
46
  allow! if permission_action.subject == :attachment_collection
46
47
  allow! if permission_action.subject == :scope
47
48
  allow! if permission_action.subject == :scope_type