decidim-admin 0.20.1 → 0.23.1

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.

Potentially problematic release.


This version of decidim-admin might be problematic. Click here for more details.

Files changed (220) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -0
  3. data/app/assets/javascripts/decidim/admin/application.js.es6 +8 -0
  4. data/app/assets/javascripts/decidim/admin/budget_rule_toggler.component.js.es6 +52 -0
  5. data/app/assets/javascripts/decidim/admin/bundle.js +26 -32
  6. data/app/assets/javascripts/decidim/admin/bundle.js.map +1 -1
  7. data/app/assets/javascripts/decidim/admin/choose_language.js +12 -0
  8. data/app/assets/javascripts/decidim/admin/dynamic_fields.component.js.es6 +24 -5
  9. data/app/assets/javascripts/decidim/admin/form.js.es6 +24 -10
  10. data/app/assets/javascripts/decidim/admin/gallery.js.es6 +5 -0
  11. data/app/assets/javascripts/decidim/admin/newsletters.js.es6 +12 -0
  12. data/app/assets/javascripts/decidim/admin/officializations.js.es6 +20 -0
  13. data/app/assets/javascripts/decidim/admin/scope_picker_enabler.component.js.es6 +14 -0
  14. data/app/assets/stylesheets/decidim/admin/_decidim.scss +2 -0
  15. data/app/assets/stylesheets/decidim/admin/_variables.scss +2 -2
  16. data/app/assets/stylesheets/decidim/admin/extra/_action-icon.scss +6 -0
  17. data/app/assets/stylesheets/decidim/admin/extra/_cards.scss +11 -0
  18. data/app/assets/stylesheets/decidim/admin/extra/_newsletter-templates-gallery.scss +3 -0
  19. data/app/assets/stylesheets/decidim/admin/extra/_organization-appearance.scss +141 -0
  20. data/app/assets/stylesheets/decidim/admin/extra/_show_email.scss +31 -0
  21. data/app/assets/stylesheets/decidim/admin/extra/_title_bar.scss +4 -0
  22. data/app/assets/stylesheets/decidim/admin/modules/_buttons.scss +15 -1
  23. data/app/assets/stylesheets/decidim/admin/modules/_callouts.scss +11 -0
  24. data/app/assets/stylesheets/decidim/admin/modules/_cards.scss +13 -2
  25. data/app/assets/stylesheets/decidim/admin/modules/_filters.scss +78 -1
  26. data/app/assets/stylesheets/decidim/admin/modules/_forms.scss +16 -2
  27. data/app/assets/stylesheets/decidim/admin/modules/_import_result.scss +10 -0
  28. data/app/assets/stylesheets/decidim/admin/modules/_layout.scss +1 -1
  29. data/app/assets/stylesheets/decidim/admin/modules/_loading-spinner.scss +19 -0
  30. data/app/assets/stylesheets/decidim/admin/modules/_main-nav.scss +0 -1
  31. data/app/assets/stylesheets/decidim/admin/modules/_modules.scss +5 -1
  32. data/app/assets/stylesheets/decidim/admin/modules/_process-header.scss +0 -1
  33. data/app/assets/stylesheets/decidim/admin/modules/_secondary-nav.scss +5 -2
  34. data/app/assets/stylesheets/decidim/admin/modules/_table-list.scss +23 -7
  35. data/app/assets/stylesheets/decidim/admin/modules/_tabs.scss +7 -0
  36. data/app/assets/stylesheets/decidim/admin/modules/_users_statistics.scss +18 -0
  37. data/app/assets/stylesheets/decidim/admin/utils/_mixins.scss +42 -0
  38. data/app/assets/stylesheets/decidim/admin/utils/_settings.scss +4 -1
  39. data/app/cells/decidim/admin/content_block/show.erb +2 -2
  40. data/app/cells/decidim/admin/results_per_page/show.erb +16 -0
  41. data/app/cells/decidim/admin/results_per_page_cell.rb +14 -0
  42. data/app/commands/decidim/admin/create_attachment.rb +2 -2
  43. data/app/commands/decidim/admin/create_newsletter.rb +34 -9
  44. data/app/commands/decidim/admin/deliver_newsletter.rb +1 -1
  45. data/app/commands/decidim/admin/destroy_share_token.rb +46 -0
  46. data/app/commands/decidim/admin/reorder_content_blocks.rb +1 -1
  47. data/app/commands/decidim/admin/update_component.rb +27 -3
  48. data/app/commands/decidim/admin/update_content_block.rb +25 -1
  49. data/app/commands/decidim/admin/update_newsletter.rb +31 -9
  50. data/app/commands/decidim/admin/update_organization.rb +15 -1
  51. data/app/commands/decidim/admin/update_organization_appearance.rb +3 -1
  52. data/app/controllers/concerns/decidim/admin/filterable.rb +152 -0
  53. data/app/controllers/concerns/decidim/admin/officializations/filterable.rb +31 -0
  54. data/app/controllers/concerns/decidim/admin/paginable.rb +20 -0
  55. data/app/controllers/concerns/decidim/admin/participatory_space_export.rb +8 -2
  56. data/app/controllers/decidim/admin/admin_terms_controller.rb +20 -0
  57. data/app/controllers/decidim/admin/application_controller.rb +3 -0
  58. data/app/controllers/decidim/admin/authorization_workflows_controller.rb +6 -0
  59. data/app/controllers/decidim/admin/components/base_controller.rb +5 -1
  60. data/app/controllers/decidim/admin/components_controller.rb +30 -23
  61. data/app/controllers/decidim/admin/concerns/has_private_users.rb +4 -0
  62. data/app/controllers/decidim/admin/dashboard_controller.rb +33 -1
  63. data/app/controllers/decidim/admin/metrics_controller.rb +22 -0
  64. data/app/controllers/decidim/admin/newsletter_templates_controller.rb +41 -0
  65. data/app/controllers/decidim/admin/newsletters_controller.rb +43 -4
  66. data/app/controllers/decidim/admin/officializations_controller.rb +15 -6
  67. data/app/controllers/decidim/admin/organization_appearance_controller.rb +1 -0
  68. data/app/controllers/decidim/admin/organization_controller.rb +4 -3
  69. data/app/controllers/decidim/admin/organization_homepage_content_blocks_controller.rb +2 -1
  70. data/app/controllers/decidim/admin/share_tokens_controller.rb +30 -0
  71. data/app/forms/decidim/admin/attachment_form.rb +3 -0
  72. data/app/forms/decidim/admin/component_form.rb +5 -22
  73. data/app/forms/decidim/admin/newsletter_form.rb +15 -3
  74. data/app/forms/decidim/admin/organization_appearance_form.rb +7 -4
  75. data/app/forms/decidim/admin/organization_form.rb +27 -0
  76. data/app/forms/decidim/admin/participatory_space_private_user_csv_import_form.rb +14 -0
  77. data/app/forms/decidim/admin/participatory_space_private_user_form.rb +8 -2
  78. data/app/frontend/components/autocomplete.component.test.tsx +2 -1
  79. data/app/frontend/components/autocomplete.component.tsx +29 -0
  80. data/app/helpers/decidim/admin/admin_terms_helper.rb +47 -0
  81. data/app/helpers/decidim/admin/application_helper.rb +2 -0
  82. data/app/helpers/decidim/admin/dashboard_helper.rb +25 -0
  83. data/app/helpers/decidim/admin/filterable_helper.rb +129 -0
  84. data/app/helpers/decidim/admin/icon_link_helper.rb +1 -1
  85. data/app/helpers/decidim/admin/newsletters_helper.rb +20 -0
  86. data/app/helpers/decidim/admin/paginable/per_page_helper.rb +22 -0
  87. data/app/helpers/decidim/admin/resource_scope_helper.rb +43 -0
  88. data/app/helpers/decidim/admin/scopes_helper.rb +6 -0
  89. data/app/helpers/decidim/admin/settings_helper.rb +56 -47
  90. data/app/helpers/decidim/admin/uploader_image_dimensions_helper.rb +30 -0
  91. data/app/helpers/decidim/admin/user_roles_helper.rb +19 -0
  92. data/app/models/decidim/admin/fake_newsletter.rb +49 -0
  93. data/app/permissions/decidim/admin/permissions.rb +30 -7
  94. data/app/presenters/decidim/admin/dashboard_metric_charts_presenter.rb +57 -0
  95. data/app/queries/decidim/admin/active_users_counter.rb +35 -0
  96. data/app/queries/decidim/admin/newsletter_recipients.rb +20 -9
  97. data/app/views/decidim/admin/admin_terms/show.html.erb +26 -0
  98. data/app/views/decidim/admin/attachment_collections/index.html.erb +1 -1
  99. data/app/views/decidim/admin/authorization_workflows/index.html.erb +1 -0
  100. data/app/views/decidim/admin/categories/index.html.erb +1 -1
  101. data/app/views/decidim/admin/components/_component.html.erb +40 -33
  102. data/app/views/decidim/admin/components/_form.html.erb +4 -0
  103. data/app/views/decidim/admin/components/_settings_fields.html.erb +2 -2
  104. data/app/views/decidim/admin/components/index.html.erb +11 -8
  105. data/app/views/decidim/admin/dashboard/show.html.erb +49 -9
  106. data/app/views/decidim/admin/exports/_dropdown.html.erb +6 -2
  107. data/app/views/decidim/admin/impersonatable_users/index.html.erb +2 -2
  108. data/app/views/decidim/admin/metrics/_metrics.html.erb +21 -0
  109. data/app/views/decidim/admin/metrics/index.html.erb +7 -0
  110. data/app/views/decidim/admin/newsletter_templates/index.html.erb +28 -0
  111. data/app/views/decidim/admin/newsletter_templates/show.html.erb +12 -0
  112. data/app/views/decidim/admin/newsletters/_form.html.erb +1 -7
  113. data/app/views/decidim/admin/newsletters/edit.html.erb +1 -1
  114. data/app/views/decidim/admin/newsletters/index.html.erb +9 -3
  115. data/app/views/decidim/admin/newsletters/new.html.erb +1 -1
  116. data/app/views/decidim/admin/newsletters/select_recipients_to_deliver.html.erb +4 -4
  117. data/app/views/decidim/admin/officializations/_show_email_modal.html.erb +31 -0
  118. data/app/views/decidim/admin/officializations/index.html.erb +9 -41
  119. data/app/views/decidim/admin/officializations/show_email.html.erb +2 -0
  120. data/app/views/decidim/admin/organization/_form.html.erb +37 -0
  121. data/app/views/decidim/admin/organization_appearance/_form.html.erb +2 -72
  122. data/app/views/decidim/admin/organization_appearance/form/_colors.html.erb +23 -0
  123. data/app/views/decidim/admin/organization_appearance/form/_images.html.erb +38 -0
  124. data/app/views/decidim/admin/organization_appearance/form/_minimap.html.erb +46 -0
  125. data/app/views/decidim/admin/resource_permissions/_options_form.html.erb +1 -1
  126. data/app/views/decidim/admin/share_tokens/_share_tokens.html.erb +57 -0
  127. data/app/views/decidim/admin/shared/_filters.html.erb +40 -0
  128. data/app/views/decidim/admin/shared/_gallery.html.erb +21 -0
  129. data/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
  130. data/app/views/decidim/admin/user_groups/index.html.erb +4 -4
  131. data/app/views/decidim/admin/users_statistics/_users_count.html.erb +39 -0
  132. data/app/views/layouts/decidim/admin/_application.html.erb +2 -1
  133. data/app/views/layouts/decidim/admin/_header.html.erb +3 -0
  134. data/app/views/layouts/decidim/admin/_title_bar.html.erb +20 -10
  135. data/app/views/layouts/decidim/admin/newsletters.erb +1 -1
  136. data/config/locales/am-ET.yml +1 -0
  137. data/config/locales/ar.yml +52 -47
  138. data/config/locales/bg-BG.yml +16 -0
  139. data/config/locales/bg.yml +135 -0
  140. data/config/locales/ca.yml +127 -48
  141. data/config/locales/cs.yml +182 -103
  142. data/config/locales/da-DK.yml +1 -0
  143. data/config/locales/da.yml +1 -0
  144. data/config/locales/de.yml +145 -47
  145. data/config/locales/el.yml +819 -0
  146. data/config/locales/en.yml +127 -48
  147. data/config/locales/eo-UY.yml +0 -1
  148. data/config/locales/eo.yml +51 -0
  149. data/config/locales/es-MX.yml +127 -48
  150. data/config/locales/es-PY.yml +127 -48
  151. data/config/locales/es.yml +127 -48
  152. data/config/locales/et-EE.yml +1 -0
  153. data/config/locales/et.yml +1 -0
  154. data/config/locales/eu.yml +21 -47
  155. data/config/locales/fi-plain.yml +127 -48
  156. data/config/locales/fi.yml +140 -61
  157. data/config/locales/fr-CA.yml +849 -0
  158. data/config/locales/fr.yml +133 -53
  159. data/config/locales/ga-IE.yml +1 -0
  160. data/config/locales/gl.yml +21 -47
  161. data/config/locales/hr-HR.yml +1 -0
  162. data/config/locales/hr.yml +1 -0
  163. data/config/locales/hu.yml +100 -48
  164. data/config/locales/id-ID.yml +21 -47
  165. data/config/locales/is-IS.yml +19 -45
  166. data/config/locales/is.yml +568 -0
  167. data/config/locales/it.yml +132 -83
  168. data/config/locales/ja-JP.yml +855 -0
  169. data/config/locales/ja.yml +849 -0
  170. data/config/locales/ko-KR.yml +1 -0
  171. data/config/locales/ko.yml +1 -0
  172. data/config/locales/lt-LT.yml +1 -0
  173. data/config/locales/lt.yml +1 -0
  174. data/config/locales/lv.yml +799 -0
  175. data/config/locales/mt-MT.yml +1 -0
  176. data/config/locales/mt.yml +1 -0
  177. data/config/locales/nl.yml +102 -48
  178. data/config/locales/no.yml +147 -84
  179. data/config/locales/om-ET.yml +1 -0
  180. data/config/locales/pl.yml +364 -238
  181. data/config/locales/pt-BR.yml +22 -48
  182. data/config/locales/pt.yml +334 -237
  183. data/config/locales/ro-RO.yml +814 -0
  184. data/config/locales/ru.yml +20 -46
  185. data/config/locales/sk-SK.yml +823 -0
  186. data/config/locales/sk.yml +806 -0
  187. data/config/locales/sl.yml +166 -0
  188. data/config/locales/so-SO.yml +1 -0
  189. data/config/locales/sr-CS.yml +590 -0
  190. data/config/locales/sv.yml +140 -55
  191. data/config/locales/ti-ER.yml +1 -0
  192. data/config/locales/tr-TR.yml +21 -47
  193. data/config/locales/uk.yml +19 -48
  194. data/config/locales/vi-VN.yml +1 -0
  195. data/config/locales/vi.yml +1 -0
  196. data/config/locales/zh-CN.yml +849 -0
  197. data/config/locales/zh-TW.yml +1 -0
  198. data/config/routes.rb +20 -3
  199. data/db/migrate/20191118112040_add_accepted_admin_terms_at_field_to_users.rb +7 -0
  200. data/lib/decidim/admin.rb +17 -0
  201. data/lib/decidim/admin/engine.rb +12 -9
  202. data/lib/decidim/admin/form_builder.rb +7 -2
  203. data/lib/decidim/admin/test.rb +2 -0
  204. data/lib/decidim/admin/test/filterable_examples.rb +129 -0
  205. data/lib/decidim/admin/test/manage_attachment_collections_examples.rb +1 -1
  206. data/lib/decidim/admin/test/manage_component_permissions_examples.rb +15 -15
  207. data/lib/decidim/admin/test/manage_paginated_collection_examples.rb +22 -0
  208. data/lib/decidim/admin/version.rb +1 -1
  209. data/vendor/assets/javascripts/jquery.serializejson.js +344 -0
  210. metadata +98 -30
  211. data/app/commands/decidim/admin/create_oauth_application.rb +0 -36
  212. data/app/commands/decidim/admin/destroy_oauth_application.rb +0 -39
  213. data/app/commands/decidim/admin/update_oauth_application.rb +0 -39
  214. data/app/controllers/decidim/admin/oauth_applications_controller.rb +0 -90
  215. data/app/forms/decidim/admin/oauth_application_form.rb +0 -32
  216. data/app/views/decidim/admin/oauth_applications/_form.html.erb +0 -19
  217. data/app/views/decidim/admin/oauth_applications/edit.html.erb +0 -13
  218. data/app/views/decidim/admin/oauth_applications/index.html.erb +0 -40
  219. data/app/views/decidim/admin/oauth_applications/new.html.erb +0 -13
  220. data/app/views/decidim/admin/oauth_applications/show.html.erb +0 -27
@@ -12,6 +12,7 @@ module Decidim
12
12
 
13
13
  attribute :name, String
14
14
  attribute :reference_prefix, String
15
+ attribute :time_zone, String
15
16
  attribute :twitter_handler, String
16
17
  attribute :facebook_handler, String
17
18
  attribute :instagram_handler, String
@@ -20,6 +21,10 @@ module Decidim
20
21
  attribute :default_locale, String
21
22
  attribute :badges_enabled, Boolean
22
23
  attribute :user_groups_enabled, Boolean
24
+ attribute :comments_max_length, Integer
25
+ attribute :rich_text_editor_in_public_views, Boolean
26
+ attribute :enable_machine_translations, Boolean
27
+ attribute :machine_translation_display_priority, String
23
28
 
24
29
  attribute :send_welcome_notification, Boolean
25
30
  attribute :customize_welcome_notification, Boolean
@@ -27,17 +32,39 @@ module Decidim
27
32
  translatable_attribute :welcome_notification_subject, String
28
33
  translatable_attribute :welcome_notification_body, String
29
34
 
35
+ translatable_attribute :admin_terms_of_use_body, String
36
+
30
37
  validates :welcome_notification_subject, :welcome_notification_body, translatable_presence: true, if: proc { |form| form.customize_welcome_notification }
31
38
 
32
39
  validates :name, presence: true
40
+ validates :time_zone, presence: true
41
+ validates :time_zone, time_zone: true
33
42
  validates :default_locale, :reference_prefix, presence: true
34
43
  validates :default_locale, inclusion: { in: :available_locales }
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
35
58
 
36
59
  private
37
60
 
38
61
  def available_locales
39
62
  current_organization.available_locales
40
63
  end
64
+
65
+ def machine_translation_enabled?
66
+ Decidim.config.enable_machine_translations
67
+ end
41
68
  end
42
69
  end
43
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) => {
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # This module includes helpers to show Admin Terms of Use
6
+ module AdminTermsHelper
7
+ def admin_terms_of_use_body
8
+ current_organization.admin_terms_of_use_body.symbolize_keys[I18n.locale].html_safe
9
+ end
10
+
11
+ def admin_terms_announcement_args
12
+ {
13
+ callout_class: current_user.admin_terms_accepted? ? "success" : "warning",
14
+ announcement: announcement_body
15
+ }
16
+ end
17
+
18
+ def announcement_body
19
+ if current_user.admin_terms_accepted?
20
+ t("accept.success", scope: "decidim.admin.admin_terms_of_use")
21
+ else
22
+ t("required_review.callout", scope: "decidim.admin.admin_terms_of_use")
23
+ end
24
+ end
25
+
26
+ def button_to_accept_admin_terms
27
+ button_to(
28
+ t("decidim.admin.admin_terms_of_use.actions.accept"),
29
+ admin_terms_accept_path,
30
+ class: "button success",
31
+ method: :put
32
+ )
33
+ end
34
+
35
+ def button_to_refuse_admin_terms
36
+ link_to(
37
+ t("decidim.admin.admin_terms_of_use.actions.refuse"),
38
+ decidim.root_path,
39
+ class: "button clear",
40
+ data: {
41
+ confirm: t("actions.are_you_sure", scope: "decidim.admin.admin_terms_of_use")
42
+ }
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
@@ -12,6 +12,8 @@ module Decidim
12
12
  include Decidim::MetaTagsHelper
13
13
  include Decidim::MapHelper
14
14
  include Decidim::Admin::LogRenderHelper
15
+ include Decidim::Admin::UserRolesHelper
16
+ include Decidim::Admin::ResourceScopeHelper
15
17
 
16
18
  def title
17
19
  current_organization.name
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # This module includes helpers to be used in the admin dashboard, including helper methods to show the Admin Terms of Use.
6
+ module DashboardHelper
7
+ def admin_terms_announcement_args
8
+ {
9
+ callout_class: "warning",
10
+ announcement: announcement_body
11
+ }
12
+ end
13
+
14
+ def announcement_body
15
+ body = t("required_review.callout", scope: "decidim.admin.admin_terms_of_use")
16
+ body += " "
17
+ body += link_to(
18
+ t("required_review.cta", scope: "decidim.admin.admin_terms_of_use"),
19
+ admin_terms_show_path
20
+ )
21
+ body
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # Helper that provides methods related to Decidim::Admin::Filterable concern.
6
+ module FilterableHelper
7
+ # Renders the filters selector with tags in the admin panel.
8
+ def admin_filter_selector(i18n_ctx = nil)
9
+ render partial: "decidim/admin/shared/filters", locals: { i18n_ctx: i18n_ctx }
10
+ end
11
+
12
+ # Builds a tree of links from Decidim::Admin::Filterable::filters_with_values
13
+ def submenu_options_tree(i18n_ctx = nil)
14
+ i18n_scope = filterable_i18n_scope_from_ctx(i18n_ctx)
15
+
16
+ filters_with_values.each_with_object({}) do |(filter, values), hash|
17
+ link = filter_link_label(filter, i18n_scope)
18
+ hash[link] = if values.is_a?(Array)
19
+ build_submenu_options_tree_from_array(filter, values, i18n_scope)
20
+ elsif values.is_a?(Hash)
21
+ build_submenu_options_tree_from_hash(filter, values, i18n_scope)
22
+ end
23
+ end
24
+ end
25
+
26
+ # Builds a tree of links from an array. The tree will have only one level.
27
+ def build_submenu_options_tree_from_array(filter, values, i18n_scope)
28
+ links = []
29
+ links += extra_dropdown_submenu_options_items(filter, i18n_scope)
30
+ links += values.map { |value| filter_link_value(filter, value, i18n_scope) }
31
+ links.each_with_object({}) { |link, hash| hash[link] = nil }
32
+ end
33
+
34
+ # To be overriden. Useful for adding links that do not match with the filter.
35
+ # Must return an Array.
36
+ def extra_dropdown_submenu_options_items(_filter, _i18n_scope)
37
+ []
38
+ end
39
+
40
+ # Builds a tree of links from an Hash. The tree can have many levels.
41
+ def build_submenu_options_tree_from_hash(filter, values, i18n_scope)
42
+ values.each_with_object({}) do |(key, value), hash|
43
+ link = filter_link_value(filter, key, i18n_scope)
44
+ hash[link] = if value.nil?
45
+ nil
46
+ elsif value.is_a?(Hash)
47
+ build_submenu_options_tree_from_hash(filter, value, i18n_scope)
48
+ end
49
+ end
50
+ end
51
+
52
+ # Produces the html for the dropdown submenu from the options tree.
53
+ # Returns a ActiveSupport::SafeBuffer.
54
+ def dropdown_submenu(options)
55
+ content_tag(:ul, class: "vertical menu") do
56
+ options.map do |key, value|
57
+ if value.nil?
58
+ content_tag(:li, key)
59
+ elsif value.is_a?(Hash)
60
+ content_tag(:li, class: "is-dropdown-submenu-parent") do
61
+ key + dropdown_submenu(value)
62
+ end
63
+ end
64
+ end.join.html_safe
65
+ end
66
+ end
67
+
68
+ def filter_link_label(filter, i18n_scope)
69
+ link_to(i18n_filter_label(filter, i18n_scope), href: "#")
70
+ end
71
+
72
+ def filter_link_value(filter, value, i18n_scope)
73
+ link_to(i18n_filter_value(filter, value, i18n_scope), query_params_with(filter => value))
74
+ end
75
+
76
+ def i18n_filter_label(filter, i18n_scope)
77
+ t("#{i18n_scope}.#{filter}.label")
78
+ end
79
+
80
+ def i18n_filter_value(filter, value, i18n_scope)
81
+ if I18n.exists?("#{i18n_scope}.#{filter}.values.#{value}")
82
+ t(value, scope: "#{i18n_scope}.#{filter}.values")
83
+ else
84
+ find_dynamic_translation(filter, value)
85
+ end
86
+ end
87
+
88
+ def applied_filters_hidden_field_tags
89
+ html = []
90
+ html += ransack_params.slice(*filters, *extra_filters).map do |filter, value|
91
+ hidden_field_tag("q[#{filter}]", value)
92
+ end
93
+ html += query_params.slice(*extra_allowed_params).map do |filter, value|
94
+ hidden_field_tag(filter, value)
95
+ end
96
+ html.join.html_safe
97
+ end
98
+
99
+ def applied_filters_tags(i18n_ctx)
100
+ ransack_params.slice(*filters).map do |filter, value|
101
+ applied_filter_tag(filter, value, filterable_i18n_scope_from_ctx(i18n_ctx))
102
+ end.join.html_safe
103
+ end
104
+
105
+ def applied_filter_tag(filter, value, i18n_scope)
106
+ content_tag(:span, class: "label secondary") do
107
+ concat "#{i18n_filter_label(filter, i18n_scope)}: "
108
+ concat i18n_filter_value(filter, value, i18n_scope)
109
+ concat remove_filter_icon_link(filter)
110
+ end
111
+ end
112
+
113
+ def remove_filter_icon_link(filter)
114
+ icon_link_to(
115
+ "circle-x",
116
+ url_for(query_params_without(filter)),
117
+ t("decidim.admin.actions.cancel"),
118
+ class: "action-icon--remove"
119
+ )
120
+ end
121
+
122
+ def filterable_i18n_scope_from_ctx(i18n_ctx)
123
+ i18n_scope = "decidim.admin.filters"
124
+ i18n_scope += ".#{i18n_ctx}" if i18n_ctx
125
+ i18n_scope
126
+ end
127
+ end
128
+ end
129
+ end
@@ -23,7 +23,7 @@ module Decidim
23
23
  target: options[:target]) do
24
24
  content_tag(:span, data: { tooltip: true, disable_hover: false, click_open: false },
25
25
  title: title) do
26
- icon(icon_name)
26
+ icon(icon_name, aria_label: title, role: "img")
27
27
  end
28
28
  end
29
29
  end
@@ -130,6 +130,26 @@ module Decidim
130
130
  { class: space.try(:closed?) ? "red" : "green", title: translated_attribute(space.title).to_s }
131
131
  ]
132
132
  end
133
+
134
+ def newsletter_attention_callout_args
135
+ {
136
+ announcement: {
137
+ body: t("warning", scope: "decidim.admin.newsletters.select_recipients_to_deliver").html_safe
138
+ },
139
+ callout_class: "warning"
140
+ }
141
+ end
142
+
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}"
146
+ {
147
+ announcement: {
148
+ body: body
149
+ },
150
+ callout_class: "warning"
151
+ }
152
+ end
133
153
  end
134
154
  end
135
155
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ module Paginable
6
+ # This module includes helpers the :per_page cell's option
7
+ module PerPageHelper
8
+ def per_page_options
9
+ OpenStruct.new(
10
+ per_page: per_page,
11
+ per_page_range: Decidim::Admin.per_page_range
12
+ )
13
+ end
14
+
15
+ # Renders the pagination dropdown menu in the admin panel.
16
+ def admin_filters_pagination
17
+ cell("decidim/admin/results_per_page", per_page_options)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -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