decidim-admin 0.22.0 → 0.23.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-admin might be problematic. Click here for more details.

Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/admin/application.js.es6 +3 -0
  3. data/app/assets/javascripts/decidim/admin/bundle.js +26 -32
  4. data/app/assets/javascripts/decidim/admin/bundle.js.map +1 -1
  5. data/app/assets/javascripts/decidim/admin/choose_language.js +12 -0
  6. data/app/assets/javascripts/decidim/admin/form.js.es6 +1 -0
  7. data/app/assets/javascripts/decidim/admin/newsletters.js.es6 +4 -0
  8. data/app/assets/javascripts/decidim/admin/scope_picker_enabler.component.js.es6 +14 -0
  9. data/app/assets/stylesheets/decidim/admin/modules/_callouts.scss +11 -0
  10. data/app/assets/stylesheets/decidim/admin/modules/_forms.scss +14 -0
  11. data/app/assets/stylesheets/decidim/admin/modules/_loading-spinner.scss +8 -0
  12. data/app/assets/stylesheets/decidim/admin/modules/_tabs.scss +7 -0
  13. data/app/commands/decidim/admin/create_attachment.rb +2 -2
  14. data/app/commands/decidim/admin/destroy_share_token.rb +46 -0
  15. data/app/commands/decidim/admin/update_content_block.rb +23 -0
  16. data/app/commands/decidim/admin/update_organization.rb +11 -0
  17. data/app/controllers/concerns/decidim/admin/participatory_space_export.rb +8 -2
  18. data/app/controllers/decidim/admin/application_controller.rb +1 -0
  19. data/app/controllers/decidim/admin/components_controller.rb +11 -1
  20. data/app/controllers/decidim/admin/newsletters_controller.rb +10 -0
  21. data/app/controllers/decidim/admin/organization_homepage_content_blocks_controller.rb +1 -0
  22. data/app/controllers/decidim/admin/share_tokens_controller.rb +30 -0
  23. data/app/forms/decidim/admin/attachment_form.rb +3 -0
  24. data/app/forms/decidim/admin/component_form.rb +6 -0
  25. data/app/forms/decidim/admin/organization_appearance_form.rb +5 -4
  26. data/app/forms/decidim/admin/organization_form.rb +20 -0
  27. data/app/forms/decidim/admin/participatory_space_private_user_csv_import_form.rb +14 -0
  28. data/app/forms/decidim/admin/participatory_space_private_user_form.rb +8 -2
  29. data/app/frontend/components/autocomplete.component.test.tsx +2 -1
  30. data/app/frontend/components/autocomplete.component.tsx +29 -0
  31. data/app/helpers/decidim/admin/application_helper.rb +1 -0
  32. data/app/helpers/decidim/admin/newsletters_helper.rb +3 -1
  33. data/app/helpers/decidim/admin/resource_scope_helper.rb +43 -0
  34. data/app/helpers/decidim/admin/settings_helper.rb +5 -0
  35. data/app/permissions/decidim/admin/permissions.rb +1 -1
  36. data/app/queries/decidim/admin/newsletter_recipients.rb +9 -5
  37. data/app/views/decidim/admin/components/_component.html.erb +5 -0
  38. data/app/views/decidim/admin/components/_form.html.erb +4 -0
  39. data/app/views/decidim/admin/components/index.html.erb +1 -0
  40. data/app/views/decidim/admin/exports/_dropdown.html.erb +6 -2
  41. data/app/views/decidim/admin/organization/_form.html.erb +21 -0
  42. data/app/views/decidim/admin/share_tokens/_share_tokens.html.erb +57 -0
  43. data/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
  44. data/app/views/layouts/decidim/admin/_header.html.erb +1 -0
  45. data/config/locales/am-ET.yml +1 -0
  46. data/config/locales/ar.yml +0 -35
  47. data/config/locales/bg.yml +135 -0
  48. data/config/locales/ca.yml +37 -37
  49. data/config/locales/cs.yml +63 -63
  50. data/config/locales/da.yml +1 -0
  51. data/config/locales/de.yml +35 -36
  52. data/config/locales/el.yml +6 -36
  53. data/config/locales/en.yml +36 -36
  54. data/config/locales/eo.yml +51 -0
  55. data/config/locales/es-MX.yml +36 -36
  56. data/config/locales/es-PY.yml +36 -36
  57. data/config/locales/es.yml +42 -42
  58. data/config/locales/et.yml +1 -0
  59. data/config/locales/eu.yml +0 -35
  60. data/config/locales/fi-plain.yml +36 -36
  61. data/config/locales/fi.yml +36 -36
  62. data/config/locales/fr-CA.yml +36 -36
  63. data/config/locales/fr.yml +42 -42
  64. data/config/locales/gl.yml +0 -35
  65. data/config/locales/hr.yml +1 -0
  66. data/config/locales/hu.yml +9 -36
  67. data/config/locales/id-ID.yml +0 -35
  68. data/config/locales/is-IS.yml +0 -34
  69. data/config/locales/is.yml +568 -0
  70. data/config/locales/it.yml +16 -46
  71. data/config/locales/ja-JP.yml +8 -2
  72. data/config/locales/ja.yml +849 -0
  73. data/config/locales/ko-KR.yml +1 -0
  74. data/config/locales/ko.yml +1 -0
  75. data/config/locales/lt.yml +1 -0
  76. data/config/locales/{lv-LV.yml → lv.yml} +0 -36
  77. data/config/locales/mt.yml +1 -0
  78. data/config/locales/nl.yml +11 -36
  79. data/config/locales/no.yml +23 -36
  80. data/config/locales/om-ET.yml +1 -0
  81. data/config/locales/pl.yml +66 -67
  82. data/config/locales/pt-BR.yml +0 -35
  83. data/config/locales/pt.yml +6 -36
  84. data/config/locales/ro-RO.yml +6 -36
  85. data/config/locales/ru.yml +0 -35
  86. data/config/locales/sk.yml +0 -36
  87. data/config/locales/sl.yml +1 -10
  88. data/config/locales/so-SO.yml +1 -0
  89. data/config/locales/sr-CS.yml +0 -35
  90. data/config/locales/sv.yml +32 -38
  91. data/config/locales/ti-ER.yml +1 -0
  92. data/config/locales/tr-TR.yml +0 -35
  93. data/config/locales/uk.yml +0 -37
  94. data/config/locales/vi-VN.yml +1 -0
  95. data/config/locales/vi.yml +1 -0
  96. data/config/locales/zh-CN.yml +849 -0
  97. data/config/locales/zh-TW.yml +1 -0
  98. data/config/routes.rb +1 -1
  99. data/lib/decidim/admin/engine.rb +10 -8
  100. data/lib/decidim/admin/form_builder.rb +2 -2
  101. data/lib/decidim/admin/test/manage_attachment_collections_examples.rb +1 -1
  102. data/lib/decidim/admin/test/manage_component_permissions_examples.rb +15 -15
  103. data/lib/decidim/admin/version.rb +1 -1
  104. metadata +36 -21
  105. data/app/commands/decidim/admin/create_oauth_application.rb +0 -36
  106. data/app/commands/decidim/admin/destroy_oauth_application.rb +0 -39
  107. data/app/commands/decidim/admin/update_oauth_application.rb +0 -39
  108. data/app/controllers/decidim/admin/oauth_applications_controller.rb +0 -90
  109. data/app/forms/decidim/admin/oauth_application_form.rb +0 -32
  110. data/app/views/decidim/admin/oauth_applications/_form.html.erb +0 -19
  111. data/app/views/decidim/admin/oauth_applications/edit.html.erb +0 -13
  112. data/app/views/decidim/admin/oauth_applications/index.html.erb +0 -40
  113. data/app/views/decidim/admin/oauth_applications/new.html.erb +0 -13
  114. data/app/views/decidim/admin/oauth_applications/show.html.erb +0 -27
@@ -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
@@ -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,6 +23,8 @@ module Decidim
23
23
  attribute :default_step_settings, Object
24
24
  attribute :step_settings, Hash[String => Object]
25
25
 
26
+ attribute :share_tokens, Array[ShareToken]
27
+
26
28
  def settings?
27
29
  settings.manifest.attributes.any?
28
30
  end
@@ -31,6 +33,10 @@ module Decidim
31
33
  default_step_settings.manifest.attributes.any?
32
34
  end
33
35
 
36
+ def map_model(model)
37
+ self.share_tokens = model.share_tokens
38
+ end
39
+
34
40
  private
35
41
 
36
42
  # Overwrites Rectify::Form#form_attributes_valid? to validate nested `step_settings` attributes.
@@ -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
 
@@ -50,14 +51,12 @@ module Decidim
50
51
  validates :official_img_header,
51
52
  :official_img_footer,
52
53
  :logo,
53
- file_size: { less_than_or_equal_to: ->(_record) { Decidim.maximum_attachment_size } },
54
- file_content_type: { allow: ["image/jpeg", "image/png"] }
54
+ passthru: { to: Decidim::Organization }
55
55
 
56
56
  validates :highlighted_content_banner_action_url, presence: true, if: :highlighted_content_banner_enabled?
57
57
  validates :highlighted_content_banner_image,
58
58
  presence: true,
59
- file_size: { less_than_or_equal_to: ->(_record) { Decidim.maximum_attachment_size } },
60
- file_content_type: { allow: ["image/jpeg", "image/png"] },
59
+ passthru: { to: Decidim::Organization },
61
60
  if: :highlighted_content_banner_image_is_changed?
62
61
 
63
62
  validates :highlighted_content_banner_title,
@@ -76,6 +75,8 @@ module Decidim
76
75
  validates :omnipresent_banner_title, translatable_presence: true, if: :enable_omnipresent_banner?
77
76
  validates :omnipresent_banner_short_description, translatable_presence: true, if: :enable_omnipresent_banner?
78
77
 
78
+ alias organization current_organization
79
+
79
80
  private
80
81
 
81
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,27 @@
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
+ if file.present?
19
+ CSV.foreach(file.path) do |email, user_name|
20
+ errors.add(:user_name, :invalid) unless user_name.match?(UserBaseEntity::REGEXP_NAME)
21
+ errors.add(:email, :taken) if context && context.current_organization && context.current_organization.admins.where(email: email).exists?
22
+ end
23
+ end
24
+ end
11
25
  end
12
26
  end
13
27
  end
@@ -11,8 +11,14 @@ module Decidim
11
11
  attribute :name, String
12
12
  attribute :email, String
13
13
 
14
- validates :email, presence: true
15
- validates :name, presence: true
14
+ validates :name, :email, presence: true
15
+
16
+ validates :name, format: { with: UserBaseEntity::REGEXP_NAME }
17
+ validate :admin_uniqueness
18
+
19
+ def admin_uniqueness
20
+ errors.add(:email, :taken) if context && context.current_organization && context.current_organization.admins.where(email: email).exists?
21
+ end
16
22
  end
17
23
  end
18
24
  end
@@ -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) => {
@@ -13,6 +13,7 @@ module Decidim
13
13
  include Decidim::MapHelper
14
14
  include Decidim::Admin::LogRenderHelper
15
15
  include Decidim::Admin::UserRolesHelper
16
+ include Decidim::Admin::ResourceScopeHelper
16
17
 
17
18
  def title
18
19
  current_organization.name
@@ -141,9 +141,11 @@ module Decidim
141
141
  end
142
142
 
143
143
  def newsletter_recipients_count_callout_args
144
+ spinner = "<span id='recipients_count_spinner' class='loading-spinner hide'></span>"
145
+ body = "#{t("recipients_count", scope: "decidim.admin.newsletters.select_recipients_to_deliver", count: recipients_count_query)} #{spinner}"
144
146
  {
145
147
  announcement: {
146
- body: t("recipients_count", scope: "decidim.admin.newsletters.select_recipients_to_deliver", count: recipients_count_query)
148
+ body: body
147
149
  },
148
150
  callout_class: "warning"
149
151
  }
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # This module includes helpers to show scopes in admin
6
+ module ResourceScopeHelper
7
+ # Public: This helper shows the th with the scope label.
8
+ #
9
+ # scope_label - I18n translation to show
10
+ #
11
+ def th_resource_scope_label(scope_label = t("decidim.admin.resources.index.headers.scope"))
12
+ return unless resource_with_scopes_enabled?
13
+
14
+ content_tag(:th, scope_label)
15
+ end
16
+
17
+ # Public: This helper shows the td for the given scope.
18
+ #
19
+ # current_scope - Scope object to show
20
+ #
21
+ def td_resource_scope_for(current_scope)
22
+ return unless resource_with_scopes_enabled?
23
+
24
+ scope_name = if current_scope
25
+ translated_attribute(current_scope.name)
26
+ else
27
+ t("decidim.scopes.global")
28
+ end
29
+ content_tag(:td, scope_name)
30
+ end
31
+
32
+ private
33
+
34
+ def resource_with_scopes_enabled?
35
+ if defined? current_component
36
+ current_component.scopes_enabled? || current_participatory_space.scopes_enabled?
37
+ else
38
+ current_participatory_space.scopes_enabled?
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -5,11 +5,14 @@ module Decidim
5
5
  # This class contains helpers needed in order for component settings to
6
6
  # properly render.
7
7
  module SettingsHelper
8
+ include Decidim::ScopesHelper
9
+
8
10
  TYPES = {
9
11
  boolean: :check_box,
10
12
  integer: :number_field,
11
13
  string: :text_field,
12
14
  text: :text_area,
15
+ scope: :scope_field,
13
16
  enum: :collection_radio_buttons
14
17
  }.freeze
15
18
 
@@ -45,6 +48,8 @@ module Decidim
45
48
  form.send(:translated, form_method, name, options)
46
49
  elsif form_method == :collection_radio_buttons
47
50
  render_enum_form_field(form, attribute, name, i18n_scope, options)
51
+ elsif form_method == :scope_field
52
+ scopes_picker_field(form, name)
48
53
  else
49
54
  form.send(form_method, name, options)
50
55
  end
@@ -45,13 +45,13 @@ module Decidim
45
45
  allow! if permission_action.subject == :scope_type
46
46
  allow! if permission_action.subject == :area
47
47
  allow! if permission_action.subject == :area_type
48
- allow! if permission_action.subject == :oauth_application
49
48
  allow! if permission_action.subject == :user_group
50
49
  allow! if permission_action.subject == :officialization
51
50
  allow! if permission_action.subject == :authorization
52
51
  allow! if permission_action.subject == :authorization_workflow
53
52
  allow! if permission_action.subject == :static_page_topic
54
53
  allow! if permission_action.subject == :help_sections
54
+ allow! if permission_action.subject == :share_token
55
55
  end
56
56
 
57
57
  permission_action
@@ -46,7 +46,7 @@ module Decidim
46
46
  def spaces
47
47
  return if @form.participatory_space_types.blank?
48
48
 
49
- @form.participatory_space_types.map do |type|
49
+ @spaces ||= @form.participatory_space_types.map do |type|
50
50
  next if type.ids.blank?
51
51
 
52
52
  object_class = "Decidim::#{type.manifest_name.classify}"
@@ -75,20 +75,24 @@ module Decidim
75
75
 
76
76
  participant_ids = []
77
77
  spaces.each do |space|
78
+ next unless defined? space.component_ids
79
+
78
80
  available_components = Decidim.component_manifests.map { |m| m.name.to_s if m.newsletter_participant_entities.present? }.compact
79
81
  Decidim::Component.where(id: space.component_ids, manifest_name: available_components).published.each do |component|
80
82
  Decidim.find_component_manifest(component.manifest_name).try(&:newsletter_participant_entities).flatten.each do |object|
81
83
  klass = Object.const_get(object)
82
- participant_ids << klass.newsletter_participant_ids(component)
84
+ participant_ids |= klass.newsletter_participant_ids(component)
83
85
  end
84
86
  end
85
- next unless defined?(Decidim::Comments)
87
+ end
86
88
 
87
- Decidim::Comments.newsletter_participant_entities.flatten.each do |object|
89
+ if defined?(Decidim::Comments)
90
+ Decidim::Comments.newsletter_participant_entities.each do |object|
88
91
  klass = Object.const_get(object)
89
- participant_ids << klass.newsletter_participant_ids(space)
92
+ participant_ids |= klass.newsletter_participant_ids(spaces.first)
90
93
  end
91
94
  end
95
+
92
96
  participant_ids.flatten.compact.uniq
93
97
  end
94
98
  end
@@ -8,6 +8,7 @@
8
8
  <td>
9
9
  <%= t "decidim.components.#{component.manifest.name}.name" %>
10
10
  </td>
11
+ <%= td_resource_scope_for(component.scope) %>
11
12
  <td class="table-list__actions">
12
13
  <% if component.manifest.admin_engine %>
13
14
  <%= icon_link_to "pencil", manage_component_path(component), t("actions.manage", scope: "decidim.admin"), class: "action-icon--manage" %>
@@ -33,6 +34,10 @@
33
34
  <% end %>
34
35
  <% end %>
35
36
 
37
+ <% if allowed_to? :share, :component, component: component %>
38
+ <%= icon_link_to "share", url_for(action: :share, id: component, controller: "components"), t("actions.share", scope: "decidim.admin"), class: "action-icon--share", target: "_blank" %>
39
+ <% end %>
40
+
36
41
  <% if allowed_to? :destroy, :component, component: component %>
37
42
  <%= icon_link_to "circle-x", url_for(action: :destroy, id: component, controller: "components"), t("actions.destroy", scope: "decidim.admin"), class: "action-icon--remove", method: :delete %>
38
43
  <% end %>
@@ -77,6 +77,10 @@
77
77
  </div>
78
78
  </fieldset>
79
79
  <% end %>
80
+
81
+ <% unless component.published? %>
82
+ <%= render partial: "decidim/admin/share_tokens/share_tokens", locals: { share_tokens: form.object.share_tokens } %>
83
+ <% end %>
80
84
  </div>
81
85
  </div>
82
86
  </div>
@@ -21,6 +21,7 @@
21
21
  <thead>
22
22
  <th><%= t(".headers.name") %></th>
23
23
  <th><%= t(".headers.type") %></th>
24
+ <%= th_resource_scope_label(t(".headers.scope")) %>
24
25
  <th><%= t(".headers.actions") %></th>
25
26
  </thead>
26
27
 
@@ -2,8 +2,12 @@
2
2
  <div class="dropdown-pane" id="export-dropdown" data-dropdown data-position=bottom data-alignment=right data-auto-focus="true" data-close-on-click="true">
3
3
  <ul class="vertical menu add-components">
4
4
  <% component.manifest.export_manifests.each do |manifest| %>
5
- <% %w{CSV JSON Excel}.each do |format| %>
6
- <li class="exports--format--<%= format.downcase %> exports--<%= manifest.name %>"><%= link_to t("decidim.admin.exports.export_as", name: t("decidim.#{component.manifest.name}.admin.exports.#{manifest.name}"), export_format: format.upcase), exports_path(component, id: manifest.name, format: format), method: :post %></li>
5
+ <% manifest.formats.each do |format| %>
6
+ <li class="exports--format--<%= format.downcase %> exports--<%= manifest.name %>">
7
+ <%= link_to t("decidim.admin.exports.export_as", name: t("decidim.#{component.manifest.name}.admin.exports.#{manifest.name}"), export_format: t("decidim.admin.exports.formats.#{format}")),
8
+ exports_path(component, id: manifest.name, format: format),
9
+ method: :post %>
10
+ </li>
7
11
  <% end %>
8
12
  <% end %>
9
13
  </ul>