decidim-decidim_awesome 0.8.2 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +63 -0
  3. data/README.md +54 -45
  4. data/Rakefile +1 -1
  5. data/app/commands/decidim/decidim_awesome/admin/create_constraint.rb +1 -1
  6. data/app/commands/decidim/decidim_awesome/admin/create_custom_redirect.rb +1 -1
  7. data/app/commands/decidim/decidim_awesome/admin/create_menu_hack.rb +1 -1
  8. data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +1 -1
  9. data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +1 -1
  10. data/app/commands/decidim/decidim_awesome/admin/create_scoped_style.rb +1 -1
  11. data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +1 -1
  12. data/app/commands/decidim/decidim_awesome/admin/destroy_custom_redirect.rb +1 -1
  13. data/app/commands/decidim/decidim_awesome/admin/destroy_menu_hack.rb +1 -1
  14. data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +1 -1
  15. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +1 -1
  16. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +1 -1
  17. data/app/commands/decidim/decidim_awesome/admin/rename_scope_label.rb +1 -1
  18. data/app/commands/decidim/decidim_awesome/admin/update_config.rb +2 -3
  19. data/app/commands/decidim/decidim_awesome/admin/update_constraint.rb +2 -2
  20. data/app/commands/decidim/decidim_awesome/admin/update_custom_redirect.rb +1 -1
  21. data/app/commands/decidim/decidim_awesome/admin/update_menu_hack.rb +1 -1
  22. data/app/commands/decidim/decidim_awesome/command.rb +14 -0
  23. data/app/commands/decidim/decidim_awesome/create_editor_image.rb +1 -1
  24. data/app/controllers/concerns/decidim/decidim_awesome/admin_accountability/admin/filterable.rb +67 -0
  25. data/app/controllers/concerns/decidim/decidim_awesome/admin_accountability/admin/filterable_helper.rb +37 -0
  26. data/app/controllers/decidim/decidim_awesome/admin/admin_accountability_controller.rb +51 -0
  27. data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +6 -3
  28. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +2 -0
  29. data/app/controllers/decidim/decidim_awesome/admin/custom_redirects_controller.rb +2 -0
  30. data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +2 -0
  31. data/app/controllers/decidim/decidim_awesome/editor_images_controller.rb +0 -2
  32. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +14 -0
  33. data/app/forms/decidim/decidim_awesome/admin/menu_form.rb +1 -1
  34. data/app/forms/decidim/decidim_awesome/proposals/proposal_wizard_create_step_form_override.rb +26 -8
  35. data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +12 -8
  36. data/app/helpers/decidim/decidim_awesome/map_helper.rb +14 -11
  37. data/app/jobs/decidim/decidim_awesome/export_admin_actions_job.rb +28 -0
  38. data/app/middleware/decidim/decidim_awesome/current_config.rb +4 -0
  39. data/app/models/decidim/decidim_awesome/awesome_config.rb +0 -1
  40. data/app/models/decidim/decidim_awesome/config_constraint.rb +0 -2
  41. data/app/models/decidim/decidim_awesome/editor_image.rb +0 -3
  42. data/app/models/decidim/decidim_awesome/paper_trail_version.rb +99 -0
  43. data/app/packs/entrypoints/decidim_admin_decidim_awesome.js +3 -2
  44. data/app/packs/images/decidim/decidim_awesome/pokecode-logo.png +0 -0
  45. data/app/packs/src/decidim/decidim_awesome/admin/auto_edit.js +7 -7
  46. data/app/packs/src/decidim/decidim_awesome/admin/check_redirections.js +2 -2
  47. data/app/packs/src/decidim/decidim_awesome/admin/constraints.js +5 -5
  48. data/app/packs/src/decidim/decidim_awesome/admin/custom_fields_builder.js +11 -10
  49. data/app/packs/src/decidim/decidim_awesome/admin/form_exit_warn.js +1 -0
  50. data/app/packs/src/decidim/decidim_awesome/admin/user_picker.js +1 -0
  51. data/app/packs/src/decidim/decidim_awesome/awesome_map/api/fetcher.js +13 -13
  52. data/app/packs/src/decidim/decidim_awesome/awesome_map/awesome_map.js +14 -12
  53. data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/controller.js +16 -12
  54. data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/proposals_controller.js +3 -3
  55. data/app/packs/src/decidim/decidim_awesome/awesome_map/controls_ui.js +25 -26
  56. data/app/packs/src/decidim/decidim_awesome/awesome_map/load_map.js +1 -0
  57. data/app/packs/src/decidim/decidim_awesome/editors/editor.js +33 -12
  58. data/app/packs/src/decidim/decidim_awesome/forms/autosave.js +8 -12
  59. data/app/packs/src/decidim/decidim_awesome/forms/custom_fields_renderer.js +36 -27
  60. data/app/packs/src/decidim/decidim_awesome/forms/rich_text_plugin.js +6 -4
  61. data/app/packs/src/decidim/decidim_awesome/proposals/custom_fields.js +7 -7
  62. data/app/packs/src/decidim/decidim_awesome/proposals/images.js +2 -2
  63. data/app/packs/stylesheets/decidim/decidim_awesome/awesome_admin.scss +8 -5
  64. data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +15 -1
  65. data/app/permissions/decidim/decidim_awesome/permissions.rb +4 -6
  66. data/app/presenters/decidim/decidim_awesome/paper_trail_base_presenter.rb +28 -0
  67. data/app/presenters/decidim/decidim_awesome/participatory_space_role_presenter.rb +45 -0
  68. data/app/presenters/decidim/decidim_awesome/role_base_presenter.rb +102 -0
  69. data/app/presenters/decidim/decidim_awesome/user_entity_presenter.rb +50 -0
  70. data/app/serializers/decidim/decidim_awesome/paper_trail_version_serializer.rb +37 -0
  71. data/app/validators/concerns/decidim/decidim_awesome/etiquette_validator_override.rb +41 -0
  72. data/app/views/decidim/decidim_awesome/admin/admin_accountability/index.html.erb +59 -0
  73. data/app/views/decidim/decidim_awesome/admin/checks/_assets_tester.html.erb +2 -0
  74. data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +82 -2
  75. data/app/views/decidim/decidim_awesome/admin/shared/_filters_with_date.html.erb +56 -0
  76. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
  77. data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +9 -17
  78. data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +1 -1
  79. data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +1 -1
  80. data/app/views/{v0.25 → v0.27}/layouts/decidim/_head.html.erb +12 -4
  81. data/config/i18n-tasks.yml +4 -0
  82. data/config/locales/ca.yml +22 -2
  83. data/config/locales/cs.yml +7 -2
  84. data/config/locales/de.yml +355 -0
  85. data/config/locales/en.yml +90 -1
  86. data/config/locales/es.yml +2 -2
  87. data/config/locales/fr.yml +22 -2
  88. data/config/locales/it.yml +2 -2
  89. data/config/locales/ja.yml +4 -3
  90. data/config/locales/nl.yml +1 -1
  91. data/config/locales/pt-BR.yml +2 -2
  92. data/db/seeds.rb +1 -1
  93. data/lib/decidim/decidim_awesome/admin_engine.rb +15 -1
  94. data/lib/decidim/decidim_awesome/awesome.rb +55 -1
  95. data/lib/decidim/decidim_awesome/checksums.yml +13 -3
  96. data/lib/decidim/decidim_awesome/config.rb +14 -14
  97. data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +1 -1
  98. data/lib/decidim/decidim_awesome/engine.rb +36 -9
  99. data/lib/decidim/decidim_awesome/iframe_component/component.rb +2 -1
  100. data/lib/decidim/decidim_awesome/menu_hacker.rb +6 -0
  101. data/lib/decidim/decidim_awesome/system_checker.rb +2 -0
  102. data/lib/decidim/decidim_awesome/test/factories.rb +8 -0
  103. data/lib/decidim/decidim_awesome/test/initializer.rb +10 -2
  104. data/lib/decidim/decidim_awesome/test/shared_examples/action_log_presenter_examples.rb +61 -0
  105. data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +7 -4
  106. data/lib/decidim/decidim_awesome/test/shared_examples/summary_examples.rb +2 -2
  107. data/lib/decidim/decidim_awesome/version.rb +2 -2
  108. data/lib/tasks/decidim_awesome_active_storage_migrations_tasks.rake +1 -3
  109. data/package.json +21 -164
  110. metadata +40 -39
  111. data/app/packs/images/decidim/decidim_awesome/platoniq-logo.png +0 -0
  112. data/app/packs/src/vendor/image-resize.min.js +0 -1
  113. data/app/packs/src/vendor/image-upload.min.js +0 -6
  114. data/app/packs/src/vendor/leaflet.featuregroup.subgroup.js +0 -184
  115. /data/app/views/{v0.25 → v0.27}/decidim/proposals/collaborative_drafts/_show.html.erb +0 -0
  116. /data/app/views/{v0.25 → v0.27}/layouts/decidim/admin/_header.html.erb +0 -0
@@ -302,7 +302,7 @@ es:
302
302
  text_settings: Ajustes del texto
303
303
  title: Título
304
304
  truncate: Número máximo de caracteres para las descripciones emergentes
305
- credits: Decidim Awesome %{version} · Made with ♥ by Platoniq
305
+ credits: Decidim Awesome %{version} · Maintained with ♥ by %{company}
306
306
  custom_fields:
307
307
  errors:
308
308
  invalid_fields: No se ha podido analizar el contenido pero se ha asignado al campo '%{field}'
@@ -313,7 +313,7 @@ es:
313
313
  success: Imagen subida correctamente
314
314
  map_component:
315
315
  map:
316
- api_not_ready: |2
316
+ api_not_ready: |
317
317
  <b>Advertencia:</b> Esta instalación de Decidim tiene la API configurada a una complejidad máxima de <b>%{current_complexity}</b>.
318
318
  Este componente probablemente no funcione correctament bajo esta configuración. Es recomendado configurar en un inicializador
319
319
  (por ejemplo al final de <code>config/initializers/decidim. b</code>) añadir las siguientes líneas:<br>
@@ -21,6 +21,14 @@ fr:
21
21
  scoped_admins: Groupe d'administrateurs restreints %{id}
22
22
  scoped_styles: Style personnalisés %{id}
23
23
  use_markdown_editor: Utiliser un éditeur Markdown au lieu de l'éditeur HTML
24
+ validate_body_max_caps_percent: Pourcentage maximum autorisé de lettres majuscules pour le corps
25
+ validate_body_max_marks_together: Nombre maximum de caractères spéciaux autorisés dans le corps
26
+ validate_body_min_length: Nombre de caractères minimum pour le corps
27
+ validate_body_start_with_caps: Forcer le corps à commencer par une lettre majuscule
28
+ validate_title_max_caps_percent: Pourcentage maximum autorisé de lettres majuscules pour le titre
29
+ validate_title_max_marks_together: Nombre maximum de caractères spéciaux consécutifs dans le titre
30
+ validate_title_min_length: Nombre de caractères minimum pour le titre
31
+ validate_title_start_with_caps: Forcer le titre à commencer par une lettre majuscule
24
32
  constraint:
25
33
  component_id: ou spécifiquement dans
26
34
  component_manifest: Uniquement dans les composants de type
@@ -151,6 +159,15 @@ fr:
151
159
  scoped_styles: Créer un CSS personnalisé qui s'applique uniquement à certaines parties du site web public (front-end) (utilisez l'éditeur de restrictions pour cela)
152
160
  scoped_styles_variables: 'Vous pouvez utiliser les variables CSS suivantes pour les couleurs personnalisées de l''organisation :'
153
161
  use_markdown_editor: Cela remplacera l'éditeur Quill WYSIWYG par un éditeur Markdown. Le texte sera affiché en HTML dans les pages publiques (le texte dans la base de données sera sauvegardé en tant que texte markdown)
162
+ validate_body_max_caps_percent: Zéro n'autorisera aucune lettre majuscule, 100 forcera à tout écrire en majuscule
163
+ validate_body_max_marks_together: 'Limiter le nombre de points d''interrogation et d''exclamation qui peuvent être écrits ensemble. Par exemple : si c''est 2, alors ''!!!'' ne sera pas autorisé dans le texte'
164
+ validate_body_min_length: Ce nombre peut être zéro, ce qui rendra ce champ non obligatoire
165
+ validate_title_max_caps_percent: Zéro n'autorisera aucune lettre majuscule, 100 forcera à tout écrire en majuscule
166
+ validate_title_max_marks_together: 'Limiter le nombre de points d''interrogation et d''exclamation qui peuvent être écrits ensemble. Par exemple : si c''est 2, alors ''!!!'' ne sera pas autorisé dans le texte'
167
+ validate_title_min_length: Le titre est toujours obligatoire et ce nombre ne peut être égal à zéro
168
+ validators:
169
+ body: Validations d'entrée de l'utilisateur pour le champ "body"
170
+ title: Validations d'entrée de l'utilisateur pour le champ "body"
154
171
  form_proposal_custom_fields:
155
172
  new: Ajouter une nouvelle boîte de champs personnalisés
156
173
  remove: Supprimer cette boîte de champs personnalisés
@@ -260,6 +277,7 @@ fr:
260
277
  hidden: Toujours caché
261
278
  logged: Uniquement visible pour utilisateurs identifiés
262
279
  non_logged: Visible uniquement pour les utilisateurs non connectés
280
+ verified_user: Visible uniquement pour les utilisateurs ayant une autorisation valide
263
281
  index:
264
282
  confirm_destroy: Êtes-vous sûr de vouloir supprimer cette personnalisation ?
265
283
  edit: Modifier
@@ -302,7 +320,7 @@ fr:
302
320
  text_settings: Paramètres de texte
303
321
  title: Titre
304
322
  truncate: Caractères maximum pour les descriptions des popups
305
- credits: Décidim Awesome %{version} · Fait avecpar Platoniq
323
+ credits: Décidim Awesome %{version} · Maintained withby %{company}
306
324
  custom_fields:
307
325
  errors:
308
326
  invalid_fields: Le contenu n'a pas pu être analysé mais a été assigné au champ '%{field}'
@@ -313,7 +331,7 @@ fr:
313
331
  success: Image ajoutée avec succès
314
332
  map_component:
315
333
  map:
316
- api_not_ready: |2
334
+ api_not_ready: |
317
335
  <b>Attention :</b> Cette installation de Decidim a l'API configurée à une complexité maximale de <b>%{current_complexity}</b>.
318
336
  Ce composant ne fonctionnera probablement pas avec cette configuration. Nous vous recommandons de configurer dans un initialiseur
319
337
  (par exemple à la fin de <code>config/initializers/decidim.rb</code>) les lignes suivantes :<br>
@@ -328,6 +346,8 @@ fr:
328
346
  show:
329
347
  view_meeting: Voir la rencontre
330
348
  view_proposal: Voir la proposition
349
+ validators:
350
+ too_much_caps: Utilise trop de majuscule (plus de %{percent} du texte)
331
351
  layouts:
332
352
  decidim:
333
353
  admin:
@@ -302,7 +302,7 @@ it:
302
302
  text_settings: Impostazioni Testo
303
303
  title: Titolo
304
304
  truncate: Numero massimo di caratteri per le descrizioni nei popup
305
- credits: Decidim Awesome %{version} · Fatto conda Platoniq
305
+ credits: Decidim Awesome %{version} · Maintained withby %{company}
306
306
  custom_fields:
307
307
  errors:
308
308
  invalid_fields: Il contenuto non può essere analizzato ma è stato assegnato al campo '%{field}'
@@ -313,7 +313,7 @@ it:
313
313
  success: Immagine caricata correttamente
314
314
  map_component:
315
315
  map:
316
- api_not_ready: |2
316
+ api_not_ready: |
317
317
  <b>Attenzione:</b> Questa installazione di Decidim ha configurato l'API ad una complessità massima di <b>%{current_complexity}</b>.
318
318
  Questo componente probabilmente non funzionerà con questa configurazione, Si consiglia di impostare in un initializer
319
319
  (per esempio alla fine del <code>config/initializers/decidim.rb</code>) con il seguente contenuti:<br>
@@ -46,7 +46,7 @@ ja:
46
46
  decidim_awesome: Decidim awesome
47
47
  components:
48
48
  awesome_iframe:
49
- name: 全画面 Iframe
49
+ name: 全画面 iframe
50
50
  settings:
51
51
  global:
52
52
  announcement: アナウンス
@@ -261,6 +261,7 @@ ja:
261
261
  hidden: 常に非表示
262
262
  logged: ログインしたユーザーにのみ表示
263
263
  non_logged: ログインしていないユーザーにのみ表示
264
+ verified_user: 権限のあるユーザーのみ表示
264
265
  index:
265
266
  confirm_destroy: この設定を削除しますか?
266
267
  edit: 編集
@@ -303,7 +304,7 @@ ja:
303
304
  text_settings: テキストの設定
304
305
  title: タイトル
305
306
  truncate: ポップアップの説明のための最大文字数
306
- credits: Decidim Awesome %{version} · Made with ♥ by Platoniq
307
+ credits: Decidim Awesome %{version} · Maintained with ♥ by %{company}
307
308
  custom_fields:
308
309
  errors:
309
310
  invalid_fields: コンテンツは解析できませんでしたが、フィールド '%{field}' に割り当てられました
@@ -314,7 +315,7 @@ ja:
314
315
  success: 画像は正常にアップロードされました
315
316
  map_component:
316
317
  map:
317
- api_not_ready: |2
318
+ api_not_ready: |
318
319
  <b>警告:</b> この Decidim のインストールでは、APIの最大複雑度が <b>%{current_complexity}</b> に設定されています。このコンポーネントは、この設定では動作しないかもしれません。初期化の設定を (例えば<code>config/initializers/decidim.rb</code>の末尾で) 以下のようにすることを推奨します:<br>
319
320
  <br>
320
321
  <pre># Api configuration
@@ -211,7 +211,7 @@ nl:
211
211
  show_rejected: Toon afgewezen voorstellen
212
212
  show_withdrawn: Toon ingetrokken voorstellen
213
213
  truncate: Maximaal aantal tekens voor popup beschrijvingen
214
- credits: Decidim Awesome %{version} · Gemaakt metdoor Platoniq
214
+ credits: Decidim Awesome %{version} · Maintained withby %{company}
215
215
  editor_images:
216
216
  create:
217
217
  error: Fout bij uploaden afbeelding!
@@ -302,7 +302,7 @@ pt-BR:
302
302
  text_settings: Configurações de texto
303
303
  title: Título
304
304
  truncate: Máximo de caracteres para descrições em popup
305
- credits: Decidim Incrível %{version} · Feito compor Platoniq
305
+ credits: Decidim Incrível %{version} · Maintained withby %{company}
306
306
  custom_fields:
307
307
  errors:
308
308
  invalid_fields: O conteúdo não pode ser analisado, mas foi atribuído ao campo '%{field}'
@@ -313,7 +313,7 @@ pt-BR:
313
313
  success: Imagem enviada com sucesso
314
314
  map_component:
315
315
  map:
316
- api_not_ready: |2
316
+ api_not_ready: |
317
317
  <b>Aviso:</b> Esta instalação Decidim tem a API configurada para uma complexidade máxima de <b>%{current_complexity}</b>.
318
318
  Este componente provavelmente não funcionará sob esta configuração. Recomendamos que você configure em um inicializador
319
319
  (por exemplo, no final do <code>config/initializers/decidim. b</code>) as seguintes linhas:<br>
data/db/seeds.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if !Rails.env.production? || ENV["SEED"]
3
+ if !Rails.env.production? || ENV.fetch("SEED", nil)
4
4
  print "Creating seeds for decidim_awesome...\n" unless Rails.env.test?
5
5
 
6
6
  organization = Decidim::Organization.first
@@ -22,6 +22,8 @@ module Decidim
22
22
  resources :scoped_styles, param: :var, only: [:create, :destroy]
23
23
  resources :proposal_custom_fields, param: :var, only: [:create, :destroy]
24
24
  resources :scoped_admins, param: :var, only: [:create, :destroy]
25
+ get :admin_accountability, to: "admin_accountability#index", as: "admin_accountability"
26
+ post :export_admin_accountability, to: "admin_accountability#export", as: "export_admin_accountability"
25
27
  get :users, to: "config#users"
26
28
  post :rename_scope_label, to: "config#rename_scope_label"
27
29
  get :checks, to: "checks#index"
@@ -38,7 +40,7 @@ module Decidim
38
40
  initializer "decidim_awesome.admin_menu" do
39
41
  Decidim.menu :admin_menu do |menu|
40
42
  menu.add_item :awesome_menu,
41
- I18n.t("menu.decidim_awesome", scope: "decidim.admin", default: "Decidim Awesome"),
43
+ I18n.t("menu.decidim_awesome", scope: "decidim.admin"),
42
44
  decidim_admin_decidim_awesome.config_path(:editors),
43
45
  icon_name: "fire",
44
46
  position: 7.5,
@@ -47,6 +49,18 @@ module Decidim
47
49
  end
48
50
  end
49
51
 
52
+ initializer "decidim_awesome.admin_menu" do
53
+ Decidim.menu :admin_user_menu do |menu|
54
+ if DecidimAwesome.enabled? :admin_accountability
55
+ menu.add_item :admin_accountability,
56
+ I18n.t("menu.admin_accountability", scope: "decidim.admin"),
57
+ decidim_admin_decidim_awesome.admin_accountability_path,
58
+ active: is_active_link?(decidim_admin_decidim_awesome.admin_accountability_path, :inclusive),
59
+ position: 7
60
+ end
61
+ end
62
+ end
63
+
50
64
  def load_seed
51
65
  nil
52
66
  end
@@ -61,6 +61,41 @@ module Decidim
61
61
  false
62
62
  end
63
63
 
64
+ # Configuration options to handle different validations in proposals
65
+ # (maybe in the future will apply to other places)
66
+ # Set it to :disabled if you don't want to use this feature
67
+ config_accessor :validate_title_min_length do
68
+ 15
69
+ end
70
+
71
+ config_accessor :validate_title_max_caps_percent do
72
+ 25
73
+ end
74
+
75
+ config_accessor :validate_title_max_marks_together do
76
+ 1
77
+ end
78
+
79
+ config_accessor :validate_title_start_with_caps do
80
+ true
81
+ end
82
+
83
+ config_accessor :validate_body_min_length do
84
+ 15
85
+ end
86
+
87
+ config_accessor :validate_body_max_caps_percent do
88
+ 25
89
+ end
90
+
91
+ config_accessor :validate_body_max_marks_together do
92
+ 1
93
+ end
94
+
95
+ config_accessor :validate_body_start_with_caps do
96
+ true
97
+ end
98
+
64
99
  config_accessor :intergram_for_public do
65
100
  false
66
101
  end
@@ -186,6 +221,21 @@ module Decidim
186
221
  }
187
222
  end
188
223
 
224
+ # If true, enables a new section in "Participants" where to audit all the admin roles that have been enabled/disabled historically in Decidim
225
+ # Set to :disabled to completly remove this feature
226
+ config_accessor :admin_accountability do
227
+ [:participatory_space_roles, :admin_roles]
228
+ end
229
+
230
+ # Roles for which it is necessary to show admin_accountability
231
+ config_accessor :participatory_space_roles do
232
+ [
233
+ "Decidim::AssemblyUserRole",
234
+ "Decidim::ParticipatoryProcessUserRole",
235
+ "Decidim::ConferenceUserRole"
236
+ ]
237
+ end
238
+
189
239
  #
190
240
  # HELPERS
191
241
  #
@@ -194,7 +244,7 @@ module Decidim
194
244
  def self.enabled?(config_vars)
195
245
  config_vars = [config_vars] unless config_vars.respond_to?(:detect)
196
246
 
197
- config_vars.detect do |item|
247
+ config_vars.any? do |item|
198
248
  next unless config.has_key?(item.to_sym)
199
249
 
200
250
  config.send(item) != :disabled
@@ -210,5 +260,9 @@ module Decidim
210
260
  def self.register_component(manifest, &block)
211
261
  registered_components << [manifest, block]
212
262
  end
263
+
264
+ def self.legacy_version?
265
+ Decidim.version[0..3] == "0.26"
266
+ end
213
267
  end
214
268
  end
@@ -2,29 +2,39 @@ decidim-admin:
2
2
  /app/views/layouts/decidim/admin/_header.html.erb:
3
3
  decidim-0.25: 1aff077428830b12306d6c42e6b37216
4
4
  decidim-core:
5
+ /app/validators/etiquette_validator.rb:
6
+ decidim-0.25: f7a4a652005385a994208f1ab41c4f08
7
+ decidim-0.26.4: f1f0fdf15be88f695c8359afab80f73f
5
8
  /app/views/layouts/decidim/_head.html.erb:
6
- decidim-0.25: eb490aa482477ff70f541d20cddec773
7
9
  decidim-0.26: 0927fc81123addec70853c2e7986c538
10
+ decidim-0.27: c82ac6defe55b6d4f6a54544dbf2ac58
8
11
  /app/packs/src/decidim/editor.js:
9
12
  decidim-0.25: 742698903a30034094c01aecaca6de84
10
13
  decidim-0.26: 651830d87aeeeff39316a787fc70d461
14
+ decidim-0.26.4: eac4ea47c09762aa2e56300bf7e98f31
11
15
  /app/presenters/decidim/menu_presenter.rb:
12
16
  decidim-0.25: f3b05daf279f909f8b3b628658dd5810
13
17
  /app/presenters/decidim/menu_item_presenter.rb:
14
18
  decidim-0.25: 860ffb160ec5f8552cc2855a6a47851b
19
+ decidim-0.26.4: d6d0129d81845c61884bcfd07885e911
20
+ decidim-0.27: c82bc2ea3c8f792472670d5996613ecf
15
21
  /app/helpers/decidim/amendments_helper.rb:
16
22
  decidim-0.25: 63532a04fcf07cf92b789833a9421416
17
23
  decidim-0.26: 636943ccb2e994fe0124dc87e72e49e9
18
24
  decidim-proposals:
19
25
  /app/forms/decidim/proposals/proposal_wizard_create_step_form.rb:
20
26
  decidim-0.24: db69edd0ba8ffa3965a5c44a6bfaba8d
27
+ decidim-0.27: b495d37088ecebcbe4ac9563bb3498d5
21
28
  /app/helpers/decidim/proposals/application_helper.rb:
22
- decidim-0.24: c5f99f5fa7de9a6e45776983330e9d73
23
29
  decidim-0.26: 216c974bc425393c18b01bfc4eed4f0b
30
+ decidim-0.26.4: 2e673d2aabe66a80a971d7ff80ebdbb8
31
+ decidim-0.27: c0ebeac39ebe4926bf0e5fc585a384d7
32
+ decidim-0.27.1: a4f902d1c4829a7f7f62299686f8604e
24
33
  /app/views/decidim/proposals/collaborative_drafts/show.html.erb:
25
34
  decidim-0.24: 2a7e0a4c65361f238fd1b917f39c8642
26
35
  /app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb:
27
- decidim-0.24: 6f717555a20e2ab3f555003c337d3003
28
36
  decidim-0.26: 97fa28043a26fc2940d30d38d9a7369b
37
+ decidim-0.27: f356c7611279e76f16d12bb164e11e83
29
38
  /app/views/decidim/proposals/admin/proposals/_form.html.erb:
30
39
  decidim-0.25: 90a04984d4269398b7cd21aa33763a1f
40
+ decidim-0.27: f60168e432e1d419e5aec5d3d1e53f0e
@@ -53,18 +53,18 @@ module Decidim
53
53
 
54
54
  # config processed for the organization config, without context
55
55
  def organization_config
56
- @organization_config ||= unfiltered_config.map do |key, value|
56
+ @organization_config ||= unfiltered_config.to_h do |key, value|
57
57
  value = defaults[key] unless enabled_for_organization? key
58
58
  [key, value]
59
- end.to_h
59
+ end
60
60
  end
61
61
 
62
62
  # config normalized according default values, without context, without organization config
63
63
  def unfiltered_config
64
- valid = @vars.map { |v| [v.var.to_sym, v.value] }.to_h
64
+ valid = @vars.to_h { |v| [v.var.to_sym, v.value] }
65
65
 
66
- map_defaults do |key|
67
- valid[key].presence
66
+ map_defaults do |key, val|
67
+ valid.has_key?(key) ? valid[key] : val
68
68
  end
69
69
  end
70
70
 
@@ -135,31 +135,31 @@ module Decidim
135
135
  plural_key = singular_key.pluralize.to_sym
136
136
  return {} unless config[plural_key]
137
137
 
138
- @sub_configs[singular_key] = config[plural_key].map do |key, _value|
138
+ @sub_configs[singular_key] = config[plural_key].to_h do |key, _value|
139
139
  [key, AwesomeConfig.find_by(var: "#{singular_key}_#{key}", organization: @organization)]
140
- end.to_h
140
+ end
141
141
  end
142
142
 
143
143
  private
144
144
 
145
145
  def map_defaults
146
- defaults.map do |key, val|
146
+ defaults.to_h do |key, val|
147
147
  value = false
148
148
  unless val == :disabled
149
- value = yield(key) || val
150
- value = val.merge(value.transform_keys(&:to_sym)) if val.is_a? Hash
149
+ value = yield(key, val)
150
+ value = val.merge(value.transform_keys(&:to_sym)) if val.is_a?(Hash) && value.is_a?(Hash)
151
151
  end
152
152
  [key, value]
153
- end.to_h
153
+ end
154
154
  end
155
155
 
156
156
  def calculate_config
157
157
  # filter vars compliant with current context
158
158
  valid = @vars.filter { |item| enabled_for_organization?(item.var) && valid_in_context?(item.all_constraints) }
159
- .map { |v| [v.var.to_sym, v.value] }.to_h
159
+ .to_h { |v| [v.var.to_sym, v.value] }
160
160
 
161
- map_defaults do |key|
162
- valid[key].presence
161
+ map_defaults do |key, val|
162
+ valid.has_key?(key) ? valid[key] : val
163
163
  end
164
164
  end
165
165
 
@@ -16,7 +16,7 @@ module Decidim
16
16
  def participatory_spaces_routes
17
17
  spaces = Decidim.participatory_space_manifests \
18
18
  .filter { |space| !DecidimAwesome.config.participatory_spaces_routes_context.has_key?(space.name) } \
19
- .map { |space| [space.name.to_s, space.name.to_s] }.to_h
19
+ .to_h { |space| [space.name.to_s, space.name.to_s] }
20
20
  DecidimAwesome.config.participatory_spaces_routes_context.each do |manifest, routes|
21
21
  routes.each do |route|
22
22
  spaces[route.to_s] = manifest.to_s
@@ -27,25 +27,52 @@ module Decidim
27
27
  # Include additional helpers globally
28
28
  ActionView::Base.include(Decidim::DecidimAwesome::AwesomeHelpers)
29
29
 
30
- # override user's admin property
31
- Decidim::User.include(Decidim::DecidimAwesome::UserOverride) if DecidimAwesome.enabled?(:scoped_admins)
32
-
33
- # redirect unauthorized scoped admins to allowed places or custom redirects if configured
34
- Decidim::ErrorsController.include(Decidim::DecidimAwesome::NotFoundRedirect) if DecidimAwesome.enabled?([:scoped_admins, :custom_redirects])
30
+ # Override EtiquetteValidator
31
+ EtiquetteValidator.include(Decidim::DecidimAwesome::EtiquetteValidatorOverride) if DecidimAwesome.enabled?([:validate_title_max_caps_percent,
32
+ :validate_title_max_marks_together,
33
+ :validate_title_start_with_caps,
34
+ :validate_body_max_caps_percent,
35
+ :validate_body_max_marks_together,
36
+ :validate_body_start_with_caps])
35
37
 
36
38
  # Custom fields need to deal with several places
37
- if DecidimAwesome.enabled?(:proposal_custom_fields)
38
- Decidim::Proposals::ApplicationHelper.include(Decidim::DecidimAwesome::Proposals::ApplicationHelperOverride)
39
+ if DecidimAwesome.enabled?([:proposal_custom_fields,
40
+ :validate_title_min_length,
41
+ :validate_title_max_caps_percent,
42
+ :validate_title_max_marks_together,
43
+ :validate_title_start_with_caps,
44
+ :validate_body_min_length,
45
+ :validate_body_max_caps_percent,
46
+ :validate_body_max_marks_together,
47
+ :validate_body_start_with_caps])
39
48
  Decidim::Proposals::ProposalWizardCreateStepForm.include(Decidim::DecidimAwesome::Proposals::ProposalWizardCreateStepFormOverride)
40
- Decidim::AmendmentsHelper.include(Decidim::DecidimAwesome::AmendmentsHelperOverride)
41
49
  end
42
50
 
51
+ # override user's admin property
52
+ Decidim::User.include(Decidim::DecidimAwesome::UserOverride) if DecidimAwesome.enabled?(:scoped_admins)
53
+
43
54
  Decidim::MenuPresenter.include(Decidim::DecidimAwesome::MenuPresenterOverride)
44
55
  Decidim::MenuItemPresenter.include(Decidim::DecidimAwesome::MenuItemPresenterOverride)
45
56
 
46
57
  # Late registering of components to take into account initializer values
47
58
  DecidimAwesome.registered_components.each do |manifest, block|
48
- Decidim.register_component(manifest, &block) unless DecidimAwesome.disabled_components.include?(manifest)
59
+ next if DecidimAwesome.disabled_components.include?(manifest)
60
+ next if Decidim.find_component_manifest(manifest)
61
+
62
+ Decidim.register_component(manifest, &block)
63
+ end
64
+ end
65
+
66
+ initializer "decidim_decidim_awesome.overrides", after: "decidim.action_controller" do
67
+ config.to_prepare do
68
+ # redirect unauthorized scoped admins to allowed places or custom redirects if configured
69
+ Decidim::ErrorsController.include(Decidim::DecidimAwesome::NotFoundRedirect) if DecidimAwesome.enabled?([:scoped_admins, :custom_redirects])
70
+
71
+ # Custom fields need to deal with several places
72
+ if DecidimAwesome.enabled?(:proposal_custom_fields)
73
+ Decidim::Proposals::ApplicationHelper.include(Decidim::DecidimAwesome::Proposals::ApplicationHelperOverride)
74
+ Decidim::AmendmentsHelper.include(Decidim::DecidimAwesome::AmendmentsHelperOverride)
75
+ end
49
76
  end
50
77
  end
51
78
 
@@ -43,7 +43,8 @@ Decidim::DecidimAwesome.register_component(:awesome_iframe) do |component|
43
43
  published_at: Time.current,
44
44
  participatory_space: participatory_space,
45
45
  settings: {
46
- announcement: { en: Faker::Lorem.paragraphs(number: 2).join("\n") }
46
+ announcement: { en: Faker::Lorem.paragraphs(number: 2).join("\n") },
47
+ iframe: '<iframe src="https://picsum.photos/800/600" width="100%" height="700" frameborder="0"></iframe>'
47
48
  }
48
49
  }
49
50
 
@@ -48,6 +48,7 @@ module Decidim
48
48
  menu
49
49
  end
50
50
 
51
+ # rubocop:disable Style/OpenStructUse
51
52
  def menu_overrides
52
53
  @menu_overrides ||= current_config.map do |item|
53
54
  OpenStruct.new(
@@ -64,6 +65,7 @@ module Decidim
64
65
  )
65
66
  end
66
67
  end
68
+ # rubocop:enable Style/OpenStructUse
67
69
 
68
70
  def activate?(url, view)
69
71
  urls = @items.map(&:url).sort_by(&:length).reverse
@@ -78,6 +80,10 @@ module Decidim
78
80
  user.present?
79
81
  when "non_logged"
80
82
  user.blank?
83
+ when "verified_user"
84
+ # the cleaner version should be user.authorizations.any?
85
+ # but there is not relationship between users and authorizations
86
+ Decidim::Authorization.where(user: user).any? { |auth| auth.granted? && !auth.expired? }
81
87
  else
82
88
  true
83
89
  end
@@ -54,9 +54,11 @@ module Decidim
54
54
  Digest::MD5.hexdigest(File.read(file))
55
55
  end
56
56
 
57
+ # rubocop:disable Style/OpenStructUse
57
58
  def to_struct(obj)
58
59
  OpenStruct.new obj
59
60
  end
61
+ # rubocop:enable Style/OpenStructUse
60
62
  end
61
63
  end
62
64
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "decidim/core/test/factories"
4
4
  require "decidim/proposals/test/factories"
5
+ require "decidim/surveys/test/factories"
5
6
 
6
7
  FactoryBot.define do
7
8
  factory :awesome_config, class: "Decidim::DecidimAwesome::AwesomeConfig" do
@@ -22,6 +23,13 @@ FactoryBot.define do
22
23
  organization { create :organization }
23
24
  end
24
25
 
26
+ factory :paper_trail_version, class: Decidim::DecidimAwesome::PaperTrailVersion do
27
+ item_id { user.id }
28
+ item_type { "Decidim::ParticipatoryProcessUserRole" }
29
+ event { "create" }
30
+ created_at { 1.hour.ago }
31
+ end
32
+
25
33
  factory :map_component, parent: :component do
26
34
  name { Decidim::Components::Namer.new(participatory_space.organization.available_locales, :proposals).i18n_name }
27
35
  manifest_name { :awesome_map }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Decidim::DecidimAwesome.configure do |config|
4
- if ENV["FEATURES"] == "disabled"
4
+ if ENV.fetch("FEATURES", nil) == "disabled"
5
5
  [
6
6
  :allow_images_in_full_editor,
7
7
  :allow_images_in_small_editor,
@@ -15,7 +15,15 @@ Decidim::DecidimAwesome.configure do |config|
15
15
  :proposal_custom_fields,
16
16
  :menu,
17
17
  :scoped_admins,
18
- :custom_redirects
18
+ :custom_redirects,
19
+ :validate_title_min_length,
20
+ :validate_title_max_caps_percent,
21
+ :validate_title_max_marks_together,
22
+ :validate_title_start_with_caps,
23
+ :validate_body_min_length,
24
+ :validate_body_max_caps_percent,
25
+ :validate_body_max_marks_together,
26
+ :validate_body_start_with_caps
19
27
  ].each do |conf|
20
28
  config.send("#{conf}=", :disabled)
21
29
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples "a user presenter" do
4
+ describe "#last_sign_in_date" do
5
+ it "returns never logged in yet" do
6
+ expect(subject.last_sign_in_date).to eq("<span class=\"muted\">Never logged yet</span>")
7
+ end
8
+
9
+ context "when no html" do
10
+ let(:html) { false }
11
+
12
+ it "returns never logged in yet" do
13
+ expect(subject.last_sign_in_date).to eq("Never logged yet")
14
+ end
15
+ end
16
+
17
+ context "when user has logged before" do
18
+ let(:last_sign_in_at) { 1.day.ago }
19
+
20
+ it "returns the last sign in date" do
21
+ expect(subject.last_sign_in_date).to eq(1.day.ago.strftime("%d/%m/%Y %H:%M"))
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "#user" do
27
+ it "returns the user" do
28
+ expect(subject.user).to eq(user)
29
+ end
30
+
31
+ it "returns email" do
32
+ expect(subject.user_email).to eq(user.email)
33
+ end
34
+
35
+ it "returns user name" do
36
+ expect(subject.user_name).to eq(user.name)
37
+ end
38
+ end
39
+
40
+ describe "#removal_date" do
41
+ it "returns currently active" do
42
+ expect(subject.removal_date).to eq("<span class=\"text-success\">Currently active</span>")
43
+ end
44
+
45
+ context "when html is disabled" do
46
+ let(:html) { false }
47
+
48
+ it "returns currently active" do
49
+ expect(subject.removal_date).to eq("Currently active")
50
+ end
51
+ end
52
+
53
+ context "when the role was removed" do
54
+ include_context "with role destroyed"
55
+
56
+ it "returns the removal date" do
57
+ expect(subject.removal_date).to eq(destroyed_at.strftime("%d/%m/%Y %H:%M"))
58
+ end
59
+ end
60
+ end
61
+ end