decidim-decidim_awesome 0.8.3 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -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/{v0.25 → v0.27}/layouts/decidim/_head.html.erb +12 -4
  80. data/config/i18n-tasks.yml +4 -0
  81. data/config/locales/ca.yml +22 -2
  82. data/config/locales/cs.yml +7 -2
  83. data/config/locales/de.yml +20 -1
  84. data/config/locales/en.yml +90 -1
  85. data/config/locales/es.yml +2 -2
  86. data/config/locales/fr.yml +22 -2
  87. data/config/locales/it.yml +2 -2
  88. data/config/locales/ja.yml +3 -2
  89. data/config/locales/nl.yml +1 -1
  90. data/config/locales/pt-BR.yml +2 -2
  91. data/db/seeds.rb +1 -1
  92. data/lib/decidim/decidim_awesome/admin_engine.rb +15 -1
  93. data/lib/decidim/decidim_awesome/awesome.rb +55 -1
  94. data/lib/decidim/decidim_awesome/checksums.yml +13 -3
  95. data/lib/decidim/decidim_awesome/config.rb +14 -14
  96. data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +1 -1
  97. data/lib/decidim/decidim_awesome/engine.rb +36 -9
  98. data/lib/decidim/decidim_awesome/iframe_component/component.rb +2 -1
  99. data/lib/decidim/decidim_awesome/menu_hacker.rb +6 -0
  100. data/lib/decidim/decidim_awesome/system_checker.rb +2 -0
  101. data/lib/decidim/decidim_awesome/test/factories.rb +7 -0
  102. data/lib/decidim/decidim_awesome/test/initializer.rb +10 -2
  103. data/lib/decidim/decidim_awesome/test/shared_examples/action_log_presenter_examples.rb +61 -0
  104. data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +7 -4
  105. data/lib/decidim/decidim_awesome/test/shared_examples/summary_examples.rb +2 -2
  106. data/lib/decidim/decidim_awesome/version.rb +2 -2
  107. data/lib/tasks/decidim_awesome_active_storage_migrations_tasks.rake +1 -3
  108. data/package.json +21 -164
  109. metadata +39 -39
  110. data/app/packs/images/decidim/decidim_awesome/platoniq-logo.png +0 -0
  111. data/app/packs/src/vendor/image-resize.min.js +0 -1
  112. data/app/packs/src/vendor/image-upload.min.js +0 -6
  113. data/app/packs/src/vendor/leaflet.featuregroup.subgroup.js +0 -184
  114. /data/app/views/{v0.25 → v0.27}/decidim/proposals/collaborative_drafts/_show.html.erb +0 -0
  115. /data/app/views/{v0.25 → v0.27}/layouts/decidim/admin/_header.html.erb +0 -0
@@ -11,10 +11,24 @@ module Decidim
11
11
  return permission_action unless user
12
12
  return permission_action if user.read_attribute("admin").blank?
13
13
 
14
- toggle_allow(config_enabled?(permission_action.subject)) if permission_action.action == :edit_config
14
+ if permission_action.subject == :admin_accountability && DecidimAwesome.admin_accountability.respond_to?(:include?)
15
+ if global?
16
+ toggle_allow(DecidimAwesome.admin_accountability.include?(:admin_roles))
17
+ else
18
+ toggle_allow(DecidimAwesome.admin_accountability.include?(:participatory_space_roles))
19
+ end
20
+ elsif permission_action.action == :edit_config
21
+ toggle_allow(config_enabled?(permission_action.subject))
22
+ end
15
23
 
16
24
  permission_action
17
25
  end
26
+
27
+ private
28
+
29
+ def global?
30
+ context.fetch(:global)
31
+ end
18
32
  end
19
33
  end
20
34
  end
@@ -18,13 +18,11 @@ module Decidim
18
18
 
19
19
  config = context.fetch(:awesome_config, {})
20
20
 
21
+ return allow! if user.admin?
21
22
  return allow! if config[:allow_images_in_proposals]
22
-
23
- if user.admin
24
- return allow! if config[:allow_images_in_small_editor]
25
- return allow! if config[:allow_images_in_full_editor]
26
- return allow! if config[:allow_images_in_markdown_editor]
27
- end
23
+ return allow! if config[:allow_images_in_small_editor]
24
+ return allow! if config[:allow_images_in_full_editor]
25
+ return allow! if config[:allow_images_in_markdown_editor]
28
26
  end
29
27
  end
30
28
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ class PaperTrailBasePresenter
6
+ attr_reader :entry, :html
7
+
8
+ def initialize(entry, html: true)
9
+ @entry = entry
10
+ @html = html
11
+ end
12
+
13
+ # try to use the object in the database if exists
14
+ # Note that "reify" does not work on "create" events
15
+ def item
16
+ @item ||= entry&.item
17
+ end
18
+
19
+ def item_type
20
+ @item_type ||= entry&.item_type
21
+ end
22
+
23
+ def item_id
24
+ @item_id ||= entry&.item_id
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ class ParticipatorySpaceRolePresenter < RoleBasePresenter
6
+ # Finds the destroyed entry if exists
7
+ def destroy_entry
8
+ @destroy_entry ||= PaperTrail::Version.find_by(item_type: item_type, event: "destroy", item_id: item_id)
9
+ end
10
+
11
+ # roles are in the destroyed event if the role has been removed
12
+ def role
13
+ @role ||= destroy_item&.role || item&.role
14
+ end
15
+
16
+ def role_name
17
+ type = I18n.t(role, scope: "decidim.decidim_awesome.admin.admin_accountability.roles", default: role)
18
+ return type unless html && role_class
19
+
20
+ "<span class=\"#{role_class}\">#{type}</span>".html_safe
21
+ end
22
+
23
+ def user
24
+ @user ||= Decidim::User.find_by(id: entry.changeset["decidim_user_id"]&.last)
25
+ end
26
+
27
+ # participatory spaces is in the normal entry if the role hasn't been removed
28
+ # otherwise is in the removed role log entry
29
+ def participatory_space
30
+ item&.participatory_space || destroy_item&.participatory_space
31
+ end
32
+
33
+ private
34
+
35
+ def role_class
36
+ case role
37
+ when "admin"
38
+ "text-alert"
39
+ when "valuator"
40
+ "text-secondary"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ class RoleBasePresenter < PaperTrailBasePresenter
6
+ include TranslatableAttributes
7
+
8
+ # Finds the destroyed entry if exists
9
+ def destroy_entry
10
+ nil
11
+ end
12
+
13
+ alias destroyed? destroy_entry
14
+
15
+ # try to reconstruct a destroyed event
16
+ def destroy_item
17
+ @destroy_item ||= destroy_entry&.reify
18
+ end
19
+
20
+ def user
21
+ raise "Please implement this method to return the user object"
22
+ end
23
+
24
+ def role_name
25
+ raise "Please implement this method to return the role text"
26
+ end
27
+
28
+ def participatory_space
29
+ nil
30
+ end
31
+
32
+ def participatory_space_name
33
+ participatory_space_type.present? ? "#{participatory_space_type} > #{translated_attribute participatory_space&.title}" : ""
34
+ end
35
+
36
+ def participatory_space_type
37
+ I18n.t(participatory_space&.manifest&.name, scope: "decidim.admin.menu") if participatory_space.present?
38
+ end
39
+
40
+ # try to link to the user roles page or to the participatory space if not existing
41
+ def participatory_space_path
42
+ proxy.send("#{participatory_space.manifest.route_name}_user_roles_path")
43
+ rescue NoMethodError
44
+ begin
45
+ proxy.send("#{participatory_space.manifest.route_name}_path", participatory_space)
46
+ rescue NoMethodError
47
+ ""
48
+ end
49
+ end
50
+
51
+ def user_name
52
+ return I18n.t("missing_user", scope: "decidim.decidim_awesome.admin.admin_accountability") unless user
53
+ return I18n.t("deleted_user", scope: "decidim.decidim_awesome.admin.admin_accountability") if user.deleted?
54
+
55
+ user&.name
56
+ end
57
+
58
+ def user_email
59
+ user&.email || entry.changeset["email"]&.last
60
+ end
61
+
62
+ def created_at
63
+ entry.changeset["created_at"]&.last || entry&.created_at
64
+ end
65
+
66
+ def created_date
67
+ I18n.l(created_at, format: :short)
68
+ rescue I18n::ArgumentError
69
+ ""
70
+ end
71
+
72
+ def destroyed_at
73
+ destroy_entry&.created_at
74
+ end
75
+
76
+ def removal_date
77
+ I18n.l(destroyed_at, format: :short)
78
+ rescue I18n::ArgumentError
79
+ info_text("currently_active", klass: "text-success")
80
+ end
81
+
82
+ def last_sign_in_date
83
+ I18n.l(user&.last_sign_in_at, format: :short)
84
+ rescue I18n::ArgumentError
85
+ info_text("never_logged")
86
+ end
87
+
88
+ protected
89
+
90
+ def info_text(key, klass: :muted)
91
+ text = I18n.t(key, scope: "decidim.decidim_awesome.admin.admin_accountability")
92
+ return text unless html
93
+
94
+ "<span class=\"#{klass}\">#{text}</span>".html_safe
95
+ end
96
+
97
+ def proxy
98
+ @proxy ||= Decidim::EngineRouter.admin_proxy(participatory_space)
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ class UserEntityPresenter < RoleBasePresenter
6
+ # Finds the destroyed entry if exists
7
+ def destroy_entry
8
+ @destroy_entry ||= begin
9
+ query = PaperTrail::Version.where(item_type: item_type, event: "update", item_id: item_id)
10
+ .where("id > ?", entry.id)
11
+ if roles.include? "admin"
12
+ query.where("object_changes LIKE '%\nadmin:\n- true\n- false%'").first
13
+ else
14
+ query.where("object_changes LIKE '%\nroles:\n- - %'").first
15
+ end
16
+ end
17
+ end
18
+
19
+ def roles
20
+ @roles ||= begin
21
+ rls = entry.changeset["roles"]&.last || []
22
+ rls << "admin" if entry.changeset["admin"]&.last
23
+ rls
24
+ end
25
+ end
26
+
27
+ def role_name
28
+ types = roles.index_with { |role| I18n.t(role, scope: "decidim.decidim_awesome.admin.admin_accountability.admin_roles", default: role) }
29
+ return types.values.join(", ") unless html
30
+
31
+ types.map { |role, type| "<span class=\"#{role_class(role)}\">#{type}</span>" }.join(" ").html_safe
32
+ end
33
+
34
+ def user
35
+ @user ||= entry&.item || Decidim::User.find_by(id: entry.changeset["id"]&.last)
36
+ end
37
+
38
+ private
39
+
40
+ def role_class(role)
41
+ case role
42
+ when "admin"
43
+ "text-alert"
44
+ when "user_manager"
45
+ "text-secondary"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ # This class serializes a AdminAccountability so can be exported to CSV, JSON or other
6
+ # formats.
7
+ class PaperTrailVersionSerializer < Decidim::Exporters::Serializer
8
+ include Decidim::ApplicationHelper
9
+ include Decidim::ResourceHelper
10
+ include Decidim::TranslationsHelper
11
+
12
+ # Public: Initializes the serializer with a admin actions.
13
+ def initialize(log_entry)
14
+ @entry = log_entry.present(html: false)
15
+ end
16
+
17
+ # Public: Exports a hash with the serialized data for this admin action.
18
+ def serialize
19
+ {
20
+ role: entry.role_name,
21
+ user_name: entry.user_name,
22
+ user_email: entry.user_email,
23
+ user_role_type: entry.entry.item_type,
24
+ participatory_space_type: entry.participatory_space_type,
25
+ participatory_space_title: translated_attribute(entry.participatory_space&.title),
26
+ last_sign_in_at: entry.last_sign_in_date,
27
+ role_created_at: entry.created_date,
28
+ role_removed_at: entry.removal_date
29
+ }
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :entry
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DecidimAwesome
5
+ module EtiquetteValidatorOverride
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ private
10
+
11
+ def validate_caps(record, attribute, value)
12
+ percent = awesome_config(record, "validate_#{attribute}_max_caps_percent").to_f
13
+ return if value.scan(/[[:upper:]]/).length < value.length * percent / 100
14
+
15
+ record.errors.add(attribute, options[:message] || I18n.t("too_much_caps", scope: "decidim.decidim_awesome.validators", percent: percent.round))
16
+ end
17
+
18
+ def validate_marks(record, attribute, value)
19
+ marks = awesome_config(record, "validate_#{attribute}_max_marks_together").to_i + 1
20
+ return if value.scan(/[!?¡¿]{#{marks},}/).empty?
21
+
22
+ record.errors.add(attribute, options[:message] || :too_many_marks)
23
+ end
24
+
25
+ def validate_caps_first(record, attribute, value)
26
+ return unless awesome_config(record, "validate_#{attribute}_start_with_caps")
27
+ return if value.scan(/\A[[:lower:]]{1}/).empty?
28
+
29
+ record.errors.add(attribute, options[:message] || :must_start_with_caps)
30
+ end
31
+
32
+ def awesome_config(record, var)
33
+ config = record.try(:awesome_config)&.config
34
+ return unless config.is_a?(Hash)
35
+
36
+ config[var.to_sym]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,59 @@
1
+ <div class="card">
2
+ <div class="card-divider">
3
+ <h2 class="card-title"><%= t(".title") %>
4
+ <span class="exports dropdown tiny button button--simple button--title" data-toggle="export-dropdown">
5
+ <%= t "exports.button", scope: "decidim.decidim_awesome.admin.admin_accountability" %>
6
+ </span>
7
+ <div class="dropdown-pane" id="export-dropdown" data-dropdown data-auto-focus="true" data-close-on-click="true">
8
+ <ul class="vertical menu add-components">
9
+ <% %w{CSV JSON Excel}.each do |format| %>
10
+ <li class="exports--format--<%= format.downcase %> exports--registrations">
11
+ <%= link_to t("decidim.decidim_awesome.admin.admin_accountability.exports.export_as", export_format:
12
+ format.upcase), export_admin_accountability_path(export_params.merge(format: format)), method: :post %>
13
+ </li>
14
+ <% end %>
15
+ </ul>
16
+ </div>
17
+ <%= link_to t(global? ? ".see_spaces" : ".see_global"), admin_accountability_path(admins: !global?), class: "button tiny button--title new" %>
18
+ </h2>
19
+ </div>
20
+
21
+ <%= render partial: "decidim/decidim_awesome/admin/shared/filters_with_date", locals: { i18n_ctx: "admin_accountability" } %>
22
+
23
+ <div class="card-section">
24
+ <p class="help-text"><%= t(global? ? ".global_description" : ".description") %></p>
25
+ <div class="table-scroll">
26
+ <table class="table-list">
27
+ <thead>
28
+ <tr>
29
+ <th><%= t("role", scope: "decidim.decidim_awesome.admin.admin_accountability") %></th>
30
+ <th><%= t("name", scope: "decidim.decidim_awesome.admin.admin_accountability") %></th>
31
+ <th><%= t("email", scope: "decidim.decidim_awesome.admin.admin_accountability") %></th>
32
+ <% unless global? %>
33
+ <th><%= t("participatory_space", scope: "decidim.decidim_awesome.admin.admin_accountability") %></th>
34
+ <% end %>
35
+ <th><%= t("last_login", scope: "decidim.decidim_awesome.admin.admin_accountability") %></th>
36
+ <th><%= t("created_at", scope: "decidim.decidim_awesome.admin.admin_accountability") %></th>
37
+ <th><%= t("removal_date", scope: "decidim.decidim_awesome.admin.admin_accountability") %></th>
38
+ </tr>
39
+ </thead>
40
+ <tbody>
41
+ <% admin_actions.each do |log| %>
42
+ <tr class="<%= log.present.destroyed? ? "text-muted" : nil %>">
43
+ <td><%= log.present.role_name %></td>
44
+ <td><%= log.present.user_name %></td>
45
+ <td><%= link_to(log.present.user_email, "mailto:#{log.present.user_email}") if log.present.user_email %></td>
46
+ <% unless global? %>
47
+ <td><%= link_to log.present.participatory_space_name, log.present.participatory_space_path %></td>
48
+ <% end %>
49
+ <td><%= log.present.last_sign_in_date %></td>
50
+ <td><%= log.present.created_date %></td>
51
+ <td><%= log.present.removal_date %></td>
52
+ </tr>
53
+ <% end %>
54
+ </tbody>
55
+ </table>
56
+ <%= paginate admin_actions, theme: "decidim" %>
57
+ </div>
58
+ </div>
59
+ </div>
@@ -0,0 +1,2 @@
1
+ <%= render partial: "layouts/decidim/head" %>
2
+ <%= render partial: "layouts/decidim/decidim_javascript" unless legacy_version? %>
@@ -2,9 +2,89 @@
2
2
  <% if config_enabled? :allow_images_in_proposals %>
3
3
  <p class="text-info"><%= t("rich_text_editor_in_public_views", scope: "decidim.decidim_awesome.admin.config") if current_organization.rich_text_editor_in_public_views %></p>
4
4
 
5
- <%= form.check_box :allow_images_in_proposals %>
5
+ <%= form.check_box :allow_images_in_proposals, disabled: current_organization.rich_text_editor_in_public_views %>
6
6
  <p class="help-text"><%= t("help.allow_images_in_proposals", scope: "decidim.decidim_awesome.admin.config.form") %></p>
7
7
 
8
- <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :allow_images_in_proposals, constraints: constraints_for(:allow_images_in_proposals) }) %>
8
+ <% unless current_organization.rich_text_editor_in_public_views %>
9
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :allow_images_in_proposals, constraints: constraints_for(:allow_images_in_proposals) }) %>
10
+ <% end %>
9
11
  <% end %>
10
12
  </div>
13
+
14
+ <% if config_enabled? %i(validate_title_min_length validate_title_max_caps_percent validate_title_max_marks_together validate_title_start_with_caps) %>
15
+ </div> <!-- .card-section -->
16
+ </div><!-- .card -->
17
+
18
+ <div class="card">
19
+ <div class="card-divider">
20
+ <h2 class="card-title"><%= t("validators.title", scope: "decidim.decidim_awesome.admin.config.form") %></h2>
21
+ </div>
22
+ <div class="card-section">
23
+
24
+ <div class="row column decidim_awesome-form">
25
+ <% if config_enabled? :validate_title_start_with_caps %>
26
+ <%= form.check_box :validate_title_start_with_caps %>
27
+
28
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :validate_title_start_with_caps, constraints: constraints_for(:validate_title_start_with_caps) }) %>
29
+ <% end %>
30
+
31
+ <% if config_enabled? :validate_title_min_length %>
32
+ <%= form.number_field :validate_title_min_length %>
33
+ <p class="help-text"><%= t("help.validate_title_min_length", scope: "decidim.decidim_awesome.admin.config.form") %></p>
34
+
35
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :validate_title_min_length, constraints: constraints_for(:validate_title_min_length) }) %>
36
+ <% end %>
37
+
38
+ <% if config_enabled? :validate_title_max_caps_percent %>
39
+ <%= form.number_field :validate_title_max_caps_percent %>
40
+ <p class="help-text"><%= t("help.validate_title_max_caps_percent", scope: "decidim.decidim_awesome.admin.config.form") %></p>
41
+
42
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :validate_title_max_caps_percent, constraints: constraints_for(:validate_title_max_caps_percent) }) %>
43
+ <% end %>
44
+
45
+ <% if config_enabled? :validate_title_max_marks_together %>
46
+ <%= form.number_field :validate_title_max_marks_together %>
47
+ <p class="help-text"><%= t("help.validate_title_max_marks_together", scope: "decidim.decidim_awesome.admin.config.form") %></p>
48
+
49
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :validate_title_max_marks_together, constraints: constraints_for(:validate_title_max_marks_together) }) %>
50
+ <% end %>
51
+ </div>
52
+ <% end %>
53
+
54
+ <% if config_enabled? %i(validate_body_min_length validate_body_max_caps_percent validate_body_max_marks_together validate_body_start_with_caps) %>
55
+ </div> <!-- .card-section -->
56
+ </div><!-- .card -->
57
+
58
+ <div class="card">
59
+ <div class="card-divider">
60
+ <h2 class="card-title"><%= t("validators.body", scope: "decidim.decidim_awesome.admin.config.form") %></h2>
61
+ </div>
62
+ <div class="card-section">
63
+ <% if config_enabled? :validate_body_start_with_caps %>
64
+ <%= form.check_box :validate_body_start_with_caps %>
65
+
66
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :validate_body_start_with_caps, constraints: constraints_for(:validate_body_start_with_caps) }) %>
67
+ <% end %>
68
+
69
+ <% if config_enabled? :validate_body_min_length %>
70
+ <%= form.number_field :validate_body_min_length %>
71
+ <p class="help-text"><%= t("help.validate_body_min_length", scope: "decidim.decidim_awesome.admin.config.form") %></p>
72
+
73
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :validate_body_min_length, constraints: constraints_for(:validate_body_min_length) }) %>
74
+ <% end %>
75
+
76
+ <% if config_enabled? :validate_body_max_caps_percent %>
77
+ <%= form.number_field :validate_body_max_caps_percent %>
78
+ <p class="help-text"><%= t("help.validate_body_max_caps_percent", scope: "decidim.decidim_awesome.admin.config.form") %></p>
79
+
80
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :validate_body_max_caps_percent, constraints: constraints_for(:validate_body_max_caps_percent) }) %>
81
+ <% end %>
82
+
83
+ <% if config_enabled? :validate_body_max_marks_together %>
84
+ <%= form.number_field :validate_body_max_marks_together %>
85
+ <p class="help-text"><%= t("help.validate_body_max_marks_together", scope: "decidim.decidim_awesome.admin.config.form") %></p>
86
+
87
+ <%= render(partial: "decidim/decidim_awesome/admin/config/constraints", locals: { key: :validate_body_max_marks_together, constraints: constraints_for(:validate_body_max_marks_together) }) %>
88
+ <% end %>
89
+ </div>
90
+ <% end %>
@@ -0,0 +1,56 @@
1
+ <div class="filters__section">
2
+ <div class="fcell filter">
3
+ <ul class="dropdown menu" data-dropdown-menu data-close-on-click-inside="false">
4
+ <li>
5
+ <a href="#" class="dropdown button">
6
+ <%= t("filter_label", scope: "decidim.admin.filters") %>
7
+ </a>
8
+ <%= dropdown_submenu(submenu_options_tree(i18n_ctx)) %>
9
+ </li>
10
+ </ul>
11
+ </div>
12
+ <div class="fcell search">
13
+ <%= search_form_for(query, url: url_for) do |form| %>
14
+ <%= applied_filters_hidden_field_tags %>
15
+ <div class="input-group">
16
+ <%= form.search_field(
17
+ search_field_predicate,
18
+ class: "input-group-field",
19
+ label: false,
20
+ placeholder: t(search_field_predicate,
21
+ collection: collection_name,
22
+ scope: "decidim.admin.filters.search_placeholder")
23
+ ) %>
24
+ <div class="input-group-button">
25
+ <button type="submit" class="button">
26
+ <%= icon "magnifying-glass", aria_label: t("search_label", scope: "decidim.admin.filters") %>
27
+ </button>
28
+ </div>
29
+ </div>
30
+ <div class="input-group mt-xs">
31
+ <div class="input-group-field">
32
+ <%= form.label t("search_field_start_date", scope: "decidim.admin.filters.label") %>
33
+ <%= form.date_field(:created_at_gteq,
34
+ class: "input-group-field",
35
+ label: false,
36
+ datepicker: true) %>
37
+ </div>
38
+ <div class="input-group-field">
39
+ <%= form.label t("search_field_end_date", scope: "decidim.admin.filters.label") %>
40
+ <%= form.date_field(:created_at_lteq,
41
+ class: "input-group-field",
42
+ label: false,
43
+ datepicker: true) %>
44
+ </div>
45
+ </div>
46
+ <% end %>
47
+ </div>
48
+ </div>
49
+ <div class="card-section fcell grid-x">
50
+ <div class="cell medium-10 filter-status">
51
+ <%= applied_filters_tags(i18n_ctx) %>
52
+ </div>
53
+ <div class="cell auto text-right">
54
+ <%= admin_filters_pagination %>
55
+ </div>
56
+ </div>
@@ -83,7 +83,7 @@
83
83
  </div>
84
84
 
85
85
  <div class="row column">
86
- <%= form.upload :file, optional: false %>
86
+ <%= form.upload :file %>
87
87
  <% if params[:id].present? %>
88
88
  <% if proposal.documents.present? %>
89
89
  <%= form.hidden_field :id, value: proposal.documents.first.id %>
@@ -61,23 +61,15 @@
61
61
  <% end %>
62
62
 
63
63
  <% if component_settings.attachments_allowed? %>
64
- <fieldset>
64
+ <fieldset class="attachments_container">
65
65
  <legend><%= t("attachment_legend", scope: "decidim.proposals.collaborative_drafts.edit") %></legend>
66
- <%= form.fields_for :attachment, @form.attachment do |nested_form| %>
67
- <div class="field">
68
- <%= nested_form.text_field :title %>
69
- </div>
70
-
71
- <div class="field">
72
- <%= nested_form.upload :file, optional: false %>
73
- <% if @form.errors[:attachment].present? %>
74
- <% @form.errors[:attachment].each do |message| %>
75
- <small class="form-error is-visible">
76
- <%= message %>
77
- </small>
78
- <% end %>
79
- <% end %>
80
- </div>
81
- <% end %>
66
+ <div class="row column">
67
+ <%= form.attachment :documents,
68
+ multiple: false,
69
+ label: t("decidim.proposals.collaborative_drafts.new.add_file"),
70
+ button_label: t("decidim.proposals.collaborative_drafts.new.add_file"),
71
+ button_edit_label: t("decidim.proposals.collaborative_drafts.new.edit_file"),
72
+ help_i18n_scope: "decidim.forms.file_help.file" %>
73
+ </div>
82
74
  </fieldset>
83
75
  <% end %>
@@ -70,6 +70,6 @@ end %>
70
70
 
71
71
  <%= yield %>
72
72
 
73
- <div class="platoniq-credits"><%= link_to t("credits", scope: "decidim.decidim_awesome", version: awesome_version), "https://github.com/Platoniq/decidim-module-decidim_awesome/" %></div>
73
+ <div class="pokecode-credits"><%= t("credits", scope: "decidim.decidim_awesome", version: link_to(awesome_version, "https://github.com/decidim-ice/decidim-module-decidim_awesome/"), company: link_to("PokeCode", "https://pokecode.net")).html_safe %></div>
74
74
 
75
75
  <% end %>
@@ -17,7 +17,15 @@
17
17
  <meta property="og:description" content="<%= decidim_meta_description %>">
18
18
  <meta property="og:image" content="<%= decidim_meta_image_url %>">
19
19
 
20
+ <% if current_organization.colors["theme"] %>
21
+ <meta name="theme-color" content="<%= current_organization.colors["theme"] %>">
22
+ <% end %>
23
+
24
+ <%= legacy_favicon %>
20
25
  <%= favicon %>
26
+ <%= apple_favicon %>
27
+ <link rel="manifest" href="/manifest.webmanifest">
28
+
21
29
  <%= stylesheet_pack_tag "decidim_core", media: "all" %>
22
30
  <%= invisible_captcha_styles %>
23
31
 
@@ -27,15 +35,15 @@
27
35
  <%# end awesome %>
28
36
 
29
37
  <%= organization_colors %>
30
- <%= javascript_pack_tag "decidim_core", defer: false %>
31
38
 
32
39
  <%# awesome javascript after app %>
33
40
  <%= render partial: "layouts/decidim/decidim_awesome/awesome_config" %>
34
- <%= javascript_pack_tag "decidim_decidim_awesome", defer: false %>
35
- <%= javascript_pack_tag("decidim_decidim_awesome_custom_fields") if Decidim::DecidimAwesome.enabled?(:proposal_custom_fields) %>
41
+ <% content_for :js_content do %>
42
+ <%= javascript_pack_tag "decidim_decidim_awesome", defer: false %>
43
+ <%= javascript_pack_tag("decidim_decidim_awesome_custom_fields") if Decidim::DecidimAwesome.enabled?(:proposal_custom_fields) %>
44
+ <% end %>
36
45
  <%# end awesome %>
37
46
 
38
47
  <%= render partial: "layouts/decidim/head_extra" %>
39
48
  <%== current_organization.header_snippets if Decidim.enable_html_header_snippets %>
40
49
  <%= snippets.display(:head) %>
41
- <%= content_for :header_snippets %>