decidim-decidim_awesome 0.10.2 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -1
  3. data/README.md +134 -15
  4. data/app/cells/concerns/decidim/decidim_awesome/proposal_m_cell_override.rb +4 -24
  5. data/app/cells/decidim/decidim_awesome/content_blocks/map_cell.rb +9 -5
  6. data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +1 -1
  7. data/app/commands/concerns/decidim/decidim_awesome/proposals/admin/update_proposal_override.rb +31 -0
  8. data/app/commands/concerns/decidim/decidim_awesome/proposals/create_collaborative_draft_override.rb +27 -0
  9. data/app/commands/concerns/decidim/decidim_awesome/proposals/create_proposal_override.rb +27 -0
  10. data/app/commands/concerns/decidim/decidim_awesome/proposals/update_collaborative_draft_override.rb +27 -0
  11. data/app/commands/concerns/decidim/decidim_awesome/proposals/update_proposal_override.rb +26 -0
  12. data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +4 -3
  13. data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +6 -3
  14. data/app/controllers/concerns/decidim/decidim_awesome/admin/maintenance_context.rb +43 -0
  15. data/app/controllers/concerns/decidim/decidim_awesome/admin_accountability/admin/filterable_helper.rb +3 -2
  16. data/app/controllers/concerns/decidim/decidim_awesome/limit_pending_amendments.rb +35 -0
  17. data/app/controllers/concerns/decidim/decidim_awesome/proposals/orderable_override.rb +9 -22
  18. data/app/controllers/decidim/decidim_awesome/admin/admin_accountability_controller.rb +7 -7
  19. data/app/controllers/decidim/decidim_awesome/admin/application_controller.rb +2 -0
  20. data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +7 -3
  21. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +8 -5
  22. data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +3 -1
  23. data/app/controllers/decidim/decidim_awesome/admin/custom_redirects_controller.rb +0 -2
  24. data/app/controllers/decidim/decidim_awesome/admin/maintenance_controller.rb +76 -0
  25. data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +0 -2
  26. data/app/controllers/decidim/decidim_awesome/admin/proposal_custom_fields_controller.rb +12 -4
  27. data/app/controllers/decidim/decidim_awesome/iframe_component/iframe_controller.rb +8 -1
  28. data/app/forms/concerns/decidim/decidim_awesome/proposals/proposal_form_override.rb +21 -0
  29. data/app/forms/{decidim → concerns/decidim}/decidim_awesome/proposals/proposal_wizard_create_step_form_override.rb +1 -0
  30. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +35 -9
  31. data/app/helpers/{decidim → concerns/decidim}/decidim_awesome/amendments_helper_override.rb +17 -7
  32. data/app/helpers/concerns/decidim/decidim_awesome/proposals/application_helper_override.rb +126 -0
  33. data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +5 -26
  34. data/app/jobs/decidim/decidim_awesome/destroy_private_data_job.rb +22 -0
  35. data/app/models/concerns/decidim/decidim_awesome/has_proposal_extra_fields.rb +38 -9
  36. data/app/models/decidim/decidim_awesome/paper_trail_version.rb +5 -1
  37. data/app/models/decidim/decidim_awesome/proposal_extra_field.rb +35 -1
  38. data/app/overrides/decidim/proposals/admin/proposals/show/add_private_body.html.erb.deface +7 -0
  39. data/app/overrides/decidim/proposals/admin/proposals/show/replace_body.html.erb.deface +5 -0
  40. data/app/overrides/decidim/proposals/proposals/show/limit_amendments_modal.html.erb.deface +5 -0
  41. data/app/packs/entrypoints/decidim_decidim_awesome_map.scss +1 -1
  42. data/app/packs/src/decidim/decidim_awesome/admin/auto_edit.js +5 -3
  43. data/app/packs/src/decidim/decidim_awesome/admin/constraints.js +1 -1
  44. data/app/packs/src/decidim/decidim_awesome/admin/custom_fields_builder.js +5 -4
  45. data/app/packs/src/decidim/decidim_awesome/amendments/show_modal_on_limits.js +30 -0
  46. data/app/packs/src/decidim/decidim_awesome/awesome_application.js +1 -0
  47. data/app/packs/src/decidim/decidim_awesome/editors/editor.js +1 -6
  48. data/app/packs/src/decidim/decidim_awesome/editors/tabs_focus.js +18 -9
  49. data/app/packs/src/decidim/decidim_awesome/forms/custom_fields_renderer.js +35 -26
  50. data/app/packs/src/decidim/decidim_awesome/proposals/custom_fields.js +31 -15
  51. data/app/packs/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +12 -7
  52. data/app/packs/stylesheets/decidim/decidim_awesome/admin/constraints.scss +69 -25
  53. data/app/packs/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +34 -27
  54. data/app/packs/stylesheets/decidim/decidim_awesome/admin/user_picker.scss +2 -2
  55. data/app/packs/stylesheets/decidim/decidim_awesome/awesome_admin.scss +3 -3
  56. data/app/packs/stylesheets/decidim/decidim_awesome/awesome_admin_global.scss +28 -0
  57. data/app/packs/stylesheets/decidim/decidim_awesome/awesome_application.scss +3 -2
  58. data/app/packs/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +15 -15
  59. data/app/packs/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +3 -3
  60. data/app/packs/stylesheets/decidim/decidim_awesome/forms/autosave.scss +3 -3
  61. data/app/packs/stylesheets/decidim/decidim_awesome/forms/custom_fields.scss +187 -0
  62. data/app/packs/stylesheets/decidim/decidim_awesome/shared/spinner.scss +47 -0
  63. data/app/packs/stylesheets/decidim/decidim_awesome/voting/voting_cards.scss +7 -7
  64. data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +14 -3
  65. data/app/presenters/concerns/decidim/decidim_awesome/proposals/proposal_presenter_override.rb +20 -0
  66. data/app/presenters/decidim/decidim_awesome/admin_log/component_presenter_override.rb +30 -0
  67. data/app/presenters/decidim/decidim_awesome/private_data_presenter.rb +70 -0
  68. data/app/queries/decidim/decidim_awesome/private_data_finder.rb +19 -0
  69. data/app/serializers/concerns/decidim/decidim_awesome/proposal_serializer_override.rb +1 -0
  70. data/app/serializers/concerns/decidim/decidim_awesome/proposals/proposal_serializer_methods.rb +72 -0
  71. data/app/serializers/concerns/decidim/decidim_awesome/proposals/proposal_serializer_override.rb +38 -0
  72. data/app/serializers/decidim/decidim_awesome/proposals/private_proposal_serializer.rb +42 -0
  73. data/app/types/concerns/decidim/decidim_awesome/add_proposal_type_custom_fields.rb +59 -0
  74. data/app/types/concerns/decidim/decidim_awesome/{proposal_type_override.rb → add_proposal_type_vote_weights.rb} +3 -1
  75. data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +52 -48
  76. data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +7 -2
  77. data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +16 -8
  78. data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +1 -1
  79. data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +12 -16
  80. data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +35 -15
  81. data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_private_custom_fields.html.erb +1 -0
  82. data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +22 -22
  83. data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +1 -1
  84. data/app/views/decidim/decidim_awesome/admin/config/show.html.erb +1 -1
  85. data/app/views/decidim/decidim_awesome/admin/custom_redirects/index.html.erb +14 -13
  86. data/app/views/decidim/decidim_awesome/admin/maintenance/_private_data.html.erb +44 -0
  87. data/app/views/decidim/decidim_awesome/admin/maintenance/show.html.erb +44 -0
  88. data/app/views/decidim/decidim_awesome/admin/menu_hacks/index.html.erb +28 -29
  89. data/app/views/decidim/decidim_awesome/admin/proposals/_editor.html.erb +8 -5
  90. data/app/views/decidim/decidim_awesome/admin/proposals/_private_body.html.erb +20 -0
  91. data/app/views/decidim/decidim_awesome/amendments/_modal.html.erb +16 -0
  92. data/app/views/decidim/decidim_awesome/custom_fields/_form_render.html.erb +10 -2
  93. data/app/views/layouts/decidim/decidim_awesome/admin/_base.html.erb +21 -0
  94. data/app/views/layouts/decidim/decidim_awesome/admin/application.html.erb +1 -73
  95. data/app/views/layouts/decidim/decidim_awesome/admin/maintenance.html.erb +19 -0
  96. data/config/i18n-tasks.yml +22 -3
  97. data/config/locales/ca.yml +97 -9
  98. data/config/locales/cs.yml +109 -6
  99. data/config/locales/de.yml +92 -6
  100. data/config/locales/en.yml +102 -8
  101. data/config/locales/es.yml +96 -8
  102. data/config/locales/eu.yml +15 -1
  103. data/config/locales/fr.yml +94 -6
  104. data/config/locales/hu.yml +53 -4
  105. data/config/locales/it.yml +16 -6
  106. data/config/locales/ja.yml +94 -6
  107. data/config/locales/lt.yml +0 -2
  108. data/config/locales/nl.yml +9 -4
  109. data/config/locales/pt-BR.yml +16 -7
  110. data/config/locales/ro-RO.yml +11 -2
  111. data/config/locales/sv.yml +17 -6
  112. data/db/migrate/20240531224204_add_decidim_awesome_proposal_private_fields.rb +29 -0
  113. data/db/migrate/20240729164227_add_decidim_awesome_proposal_private_fields_date.rb +20 -0
  114. data/lib/decidim/decidim_awesome/admin_engine.rb +22 -6
  115. data/lib/decidim/decidim_awesome/api/types/localized_custom_fields_type.rb +22 -0
  116. data/lib/decidim/decidim_awesome/api/types/translated_custom_fields_type.rb +52 -0
  117. data/lib/decidim/decidim_awesome/awesome.rb +45 -8
  118. data/lib/decidim/decidim_awesome/awesome_helpers.rb +5 -1
  119. data/lib/decidim/decidim_awesome/checksums.yml +23 -0
  120. data/lib/decidim/decidim_awesome/custom_fields.rb +8 -0
  121. data/lib/decidim/decidim_awesome/engine.rb +143 -52
  122. data/lib/decidim/decidim_awesome/lock.rb +47 -0
  123. data/lib/decidim/decidim_awesome/menu.rb +146 -0
  124. data/lib/decidim/decidim_awesome/test/initializer.rb +4 -1
  125. data/lib/decidim/decidim_awesome/test/shared_examples/{box_label_editor.rb → box_label_editor_examples.rb} +1 -1
  126. data/lib/decidim/decidim_awesome/test/shared_examples/config_examples.rb +20 -2
  127. data/lib/decidim/decidim_awesome/test/shared_examples/custom_fields_examples.rb +155 -0
  128. data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +24 -0
  129. data/lib/decidim/decidim_awesome/test/shared_examples/menu_hack_contexts.rb +2 -2
  130. data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +3 -5
  131. data/lib/decidim/decidim_awesome/test/shared_examples/summary_examples.rb +78 -12
  132. data/lib/decidim/decidim_awesome/version.rb +1 -1
  133. data/package.json +2 -2
  134. metadata +52 -13
  135. data/app/helpers/decidim/decidim_awesome/proposals/application_helper_override.rb +0 -78
  136. /data/app/presenters/{decidim → concerns/decidim}/decidim_awesome/menu_item_presenter_override.rb +0 -0
  137. /data/app/presenters/{decidim → concerns/decidim}/decidim_awesome/menu_presenter_override.rb +0 -0
@@ -6,10 +6,31 @@ module Decidim
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
- has_one :extra_fields, foreign_key: "decidim_proposal_id", class_name: "Decidim::DecidimAwesome::ProposalExtraField", dependent: :destroy
9
+ has_one :extra_fields, as: :proposal, foreign_key: "decidim_proposal_id", foreign_type: "decidim_proposal_type", class_name: "Decidim::DecidimAwesome::ProposalExtraField",
10
+ dependent: :destroy
11
+
12
+ after_save do |proposal|
13
+ if proposal.extra_fields && proposal.extra_fields.changed?
14
+ proposal.extra_fields.save
15
+ proposal.update_vote_weights
16
+ proposal.reload
17
+ end
18
+ end
19
+
20
+ delegate :private_body=, to: :safe_extra_fields
21
+
22
+ def private_body
23
+ extra_fields.private_body if extra_fields
24
+ end
25
+
26
+ def update_private_body!(private_body)
27
+ safe_extra_fields.private_body = private_body
28
+ safe_extra_fields.save!
29
+ self.extra_fields = safe_extra_fields
30
+ end
10
31
 
11
32
  def weight_count(weight)
12
- (extra_fields && extra_fields.vote_weight_totals[weight.to_s]) || 0
33
+ safe_extra_fields.vote_weight_totals[weight.to_s] || 0
13
34
  end
14
35
 
15
36
  def vote_weights
@@ -24,19 +45,27 @@ module Decidim
24
45
  @all_vote_weights ||= self.class.all_vote_weights_for(component)
25
46
  end
26
47
 
27
- def update_vote_weights!
28
- extra_fields ||= Decidim::DecidimAwesome::ProposalExtraField.find_or_initialize_by(proposal: self)
29
- extra_fields.vote_weight_totals = {}
48
+ def update_vote_weights
49
+ votes = Decidim::Proposals::ProposalVote.where(proposal: self)
50
+ safe_extra_fields.vote_weight_totals = {}
30
51
  votes.each do |vote|
31
- extra_fields.vote_weight_totals[vote.weight] ||= 0
32
- extra_fields.vote_weight_totals[vote.weight] += 1
52
+ safe_extra_fields.vote_weight_totals[vote.weight] ||= 0
53
+ safe_extra_fields.vote_weight_totals[vote.weight] += 1
33
54
  end
34
- extra_fields.save!
35
- self.extra_fields = extra_fields
36
55
  @vote_weights = nil
37
56
  @all_vote_weights = nil
38
57
  end
39
58
 
59
+ def update_vote_weights!
60
+ update_vote_weights
61
+ safe_extra_fields.save!
62
+ self.extra_fields = safe_extra_fields
63
+ end
64
+
65
+ def safe_extra_fields
66
+ @safe_extra_fields ||= (persisted? && reload.extra_fields) || build_extra_fields(vote_weight_totals: {})
67
+ end
68
+
40
69
  # collects all different weights stored along the different proposals in a different component
41
70
  def self.all_vote_weights_for(component)
42
71
  Decidim::DecidimAwesome::VoteWeight.where(
@@ -9,6 +9,10 @@ module Decidim
9
9
  DecidimAwesome.participatory_space_roles.filter(&:safe_constantize)
10
10
  end
11
11
 
12
+ def self.safe_admin_role_type(admin_role)
13
+ Decidim.user_roles.find { |role| role == admin_role }
14
+ end
15
+
12
16
  scope :space_role_actions, lambda { |organization|
13
17
  role_changes = where(item_type: PaperTrailVersion.safe_user_roles, event: "create")
14
18
  user_ids_from_object_changes = role_changes.pluck(:object_changes).map { |change| change.match(/decidim_user_id:\n- ?\n- (\d+)/)[1].to_i }
@@ -33,7 +37,7 @@ module Decidim
33
37
  when "admin"
34
38
  base.where("object_changes LIKE '%\nadmin:\n- false\n- true%'")
35
39
  else
36
- base.where(Arel.sql("object_changes LIKE '%\nroles:\n- []\n- - #{filter}\n%'"))
40
+ base.where("object_changes LIKE ?", "%\nroles:\n- []\n- - #{filter}\n%")
37
41
  end
38
42
  end
39
43
 
@@ -2,10 +2,44 @@
2
2
 
3
3
  module Decidim
4
4
  module DecidimAwesome
5
+ # This class adds some attributes to the proposal model in a different table
6
+ # in particular, it adds a private_body field that should be encrypted
7
+ # private_body is not translatable, nor is intended to be as it won't be shown to the public
5
8
  class ProposalExtraField < ApplicationRecord
9
+ include Decidim::RecordEncryptor
10
+
6
11
  self.table_name = "decidim_awesome_proposal_extra_fields"
7
12
 
8
- belongs_to :proposal, foreign_key: "decidim_proposal_id", class_name: "Decidim::Proposals::Proposal"
13
+ belongs_to :proposal, foreign_key: "decidim_proposal_id", foreign_type: "decidim_proposal_type", polymorphic: true
14
+
15
+ encrypt_attribute :private_body, type: :string
16
+
17
+ after_initialize :store_private_body
18
+ before_save :update_private_body_updated_at
19
+
20
+ # validate not more than one extra field can be associated to a proposal
21
+ # validates :proposal, uniqueness: true
22
+ validate :no_more_than_one_extra_field
23
+
24
+ private
25
+
26
+ def store_private_body
27
+ @initial_private_body = private_body
28
+ end
29
+
30
+ # using private_body_changed? does not sufice as the encrypted value is always updated on saving
31
+ def update_private_body_updated_at
32
+ if private_body != @initial_private_body
33
+ self.private_body_updated_at = Time.current
34
+ @initial_private_body = private_body
35
+ end
36
+ end
37
+
38
+ def no_more_than_one_extra_field
39
+ return unless ProposalExtraField.where(proposal: proposal).where.not(id: id).exists?
40
+
41
+ errors.add(:proposal, :invalid)
42
+ end
9
43
  end
10
44
  end
11
45
  end
@@ -0,0 +1,7 @@
1
+ <!-- replace "erb[loud]:contains('simple_format(present(proposal).body(strip_tags: true))')" -->
2
+
3
+ <% if awesome_proposal_custom_fields.blank? %>
4
+ <%= simple_format(present(proposal).body(strip_tags: true)) %>
5
+ <% else %>
6
+ <%= render_proposal_body(proposal) %>
7
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <!-- insert_before "erb[silent]:contains('presented_endorsers = endorsers_presenters_for(proposal)')" -->
2
+
3
+ <% unless awesome_proposal_private_custom_fields.blank? %>
4
+ <%= render partial: "decidim/decidim_awesome/admin/proposals/private_body", locals: { proposal: proposal } %>
5
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <!-- replace "erb[loud]:contains('amend_button_for @proposal')" -->
2
+
3
+ <%= amend_button_for @proposal %>
4
+
5
+ <%= render "decidim/decidim_awesome/amendments/modal" if @proposal.emendations.not_hidden.where(decidim_amendments: { state: :evaluating }).count.positive? && @proposal.amendable? %>
@@ -1 +1 @@
1
- @import "stylesheets/decidim/decidim_awesome/awesome_map/map"
1
+ @import "stylesheets/decidim/decidim_awesome/awesome_map/map";
@@ -15,7 +15,7 @@ $(() => {
15
15
  const attribute = $target.data("var");
16
16
  const $hidden = $(`[name="config[${attribute}][${key}]"]`);
17
17
  const $multiple = $(`[name="config[${attribute}][${key}][]"]`);
18
- const $container = $(`.${attribute}_container[data-key="${key}"]`);
18
+ const $container = $(`.js-box-container[data-key="${key}"]`);
19
19
  const $delete = $(".delete-box", $container);
20
20
 
21
21
  const rebuildLabel = (text, withScope) => {
@@ -34,12 +34,14 @@ $(() => {
34
34
  const rebuildHmtl = (result) => {
35
35
  rebuildLabel(result.key, result.scope);
36
36
  $constraints.replaceWith(result.html);
37
- // update hidden input if exists
38
37
  $hidden.attr("name", `config[${attribute}][${result.key}]`);
39
38
  $multiple.attr("name", `config[${attribute}][${result.key}][]`);
40
39
  $container.data("key", result.key);
41
40
  $container.attr("data-key", result.key);
42
- $delete.attr("href", $delete.attr("href").replace(`key=${key}`, `key=${result.key}`))
41
+ if ($delete.length > 0) {
42
+ $delete.attr("href", $delete.attr("href").replace(`key=${key}`, `key=${result.key}`));
43
+ }
44
+
43
45
  CustomFieldsBuilders.forEach((builder) => {
44
46
  if (builder.key === key) {
45
47
  builder.key = result.key;
@@ -7,7 +7,7 @@ $(() => {
7
7
  $(".decidim_awesome-form").on("click", ".constraints-editor .add-condition,.constraints-editor .edit-condition", (evt) => {
8
8
  evt.preventDefault();
9
9
  const $this = $(evt.target)
10
- const url = $this.attr("href");
10
+ const url = $this.attr("href") || $this.data("constraints-url");
11
11
  const $callout = $this.closest(".constraints-editor").find(".callout");
12
12
  $callout.hide();
13
13
  $callout.removeClass("alert success");
@@ -6,16 +6,18 @@ window.CustomFieldsBuilders = window.CustomFieldsBuilders || [];
6
6
  $(() => {
7
7
  $(".awesome-edit-config .proposal_custom_fields_editor").each((_idx, el) => {
8
8
  const key = $(el).closest(".proposal_custom_fields_container").data("key");
9
+ const configVar = $(el).closest(".proposal_custom_fields_container").data("var");
9
10
  // DOCS: https://formbuilder.online/docs
10
11
  window.CustomFieldsBuilders.push({
11
12
  el: el,
12
13
  key: key,
14
+ var: configVar,
13
15
  config: {
14
16
  i18n: {
15
17
  locale: "en-US",
16
18
  location: "https://cdn.jsdelivr.net/npm/formbuilder-languages@1.1.0/"
17
19
  },
18
- formData: $(`input[name="config[proposal_custom_fields][${key}]"]`).val(),
20
+ formData: $(`input[name="config[${configVar}][${key}]"]`).val(),
19
21
  disableFields: ["button", "file"],
20
22
  disabledActionButtons: ["save", "data", "clear"],
21
23
  disabledAttrs: [
@@ -37,7 +39,7 @@ $(() => {
37
39
  ],
38
40
  disabledSubtypes: {
39
41
  // default color as it generate hashtags in decidim (TODO: fix hashtag generator with this)
40
- text: ["color"],
42
+ text: ["color"],
41
43
  // disable default wysiwyg editors as they present problems
42
44
  textarea: ["tinymce", "quill"]
43
45
  }
@@ -71,8 +73,7 @@ $(() => {
71
73
 
72
74
  $("form.awesome-edit-config").on("submit", () => {
73
75
  window.CustomFieldsBuilders.forEach((builder) => {
74
- $(`input[name="config[proposal_custom_fields][${builder.key}]"]`).val(builder.instance.actions.getData("json"));
76
+ $(`input[name="config[${builder.var}][${builder.key}]"]`).val(builder.instance.actions.getData("json"));
75
77
  });
76
78
  });
77
79
  });
78
-
@@ -0,0 +1,30 @@
1
+ $(() => {
2
+ const $modal = $("#LimitAmendmentsModal");
3
+ if ($modal.length === 0 || $(".sign-out-link").length === 0) {
4
+ return;
5
+ }
6
+
7
+ const showModal = () => {
8
+ if ($modal.is(":visible")) {
9
+ return false;
10
+ }
11
+
12
+ if ($modal.data("limitAmendments")) {
13
+ return true;
14
+ }
15
+
16
+ return false;
17
+ };
18
+
19
+ $modal.find("a").on("click", () => {
20
+ $modal.foundation("close");
21
+ });
22
+
23
+ $(".card__amend-button").on("click", ".amend_button_card_cell", (evt) => {
24
+ if (showModal()) {
25
+ evt.preventDefault();
26
+ evt.stopPropagation();
27
+ $modal.foundation("open");
28
+ }
29
+ });
30
+ });
@@ -1,6 +1,7 @@
1
1
  import "src/decidim/decidim_awesome/proposals/images"
2
2
  import "src/decidim/decidim_awesome/forms/autosave"
3
3
  import "src/decidim/decidim_awesome/voting/voting_cards"
4
+ import "src/decidim/decidim_awesome/amendments/show_modal_on_limits"
4
5
  import {destroyQuillEditor, createQuillEditor, createMarkdownEditor} from "src/decidim/decidim_awesome/editors/editor"
5
6
 
6
7
  $(() => {
@@ -41,7 +41,7 @@ export function destroyQuillEditor(container) {
41
41
  export function createQuillEditor(container) {
42
42
  const toolbar = $(container).data("toolbar");
43
43
  const disabled = $(container).data("disabled");
44
- const allowedEmptyContentSelector = "iframe";
44
+ const allowedEmptyContentSelector = "iframe,img";
45
45
 
46
46
  let quillToolbar = [
47
47
  ["bold", "italic", "underline", "linebreak"],
@@ -144,11 +144,6 @@ export function createQuillEditor(container) {
144
144
  });
145
145
  container.dispatchEvent(event);
146
146
 
147
- if (text === "\n" || text === "\n\n") {
148
- $input.val("");
149
- } else {
150
- $input.val(quill.root.innerHTML);
151
- }
152
147
  if ((text === "\n" || text === "\n\n") && quill.root.querySelectorAll(allowedEmptyContentSelector).length === 0) {
153
148
  $input.val("");
154
149
  } else {
@@ -2,21 +2,30 @@
2
2
  * When switching tabs in i18n fields, autofocus on the markdown if exists
3
3
  */
4
4
  $(() => {
5
- // Event launched by foundation
5
+ const reloadCustomFields = ($input) => {
6
+ // saves current data to the hidden field for the lang
7
+ window.DecidimAwesome.CustomFieldsRenderer.storeData();
8
+ // init the current language
9
+ window.DecidimAwesome.CustomFieldsRenderer.init($input);
10
+ };
11
+
12
+ // Event launched by foundation using jQuery (still used in the admin in v0.28, probably removed in the future)
6
13
  $("[data-tabs]").on("change.zf.tabs", (event) => {
7
14
  const $container = $(event.target).closest(".label--tabs").next(".tabs-content").find(".tabs-panel.is-active");
8
- // fix inscrybmde if present
9
- let $input = $container.find('[name="faker-inscrybmde"]');
15
+ // fix custom fields if present
16
+ const $input = $container.find(".proposal_custom_field:first");
10
17
  if ($input.length > 0) {
11
- $input[0].InscrybMDE.codemirror.refresh();
18
+ reloadCustomFields($input);
12
19
  }
20
+ });
21
+
22
+ // if more than 3 languages, a select is used
23
+ $("#proposal-body-tabs").on("change", (event) => {
24
+ const $container = $($(event.target).val());
13
25
  // fix custom fields if present
14
- $input = $container.find(".proposal_custom_field:first");
26
+ const $input = $container.find(".proposal_custom_field:first");
15
27
  if ($input.length > 0) {
16
- // saves current data to the hidden field for the lang
17
- window.DecidimAwesome.CustomFieldsRenderer.storeData();
18
- // init the current language
19
- window.DecidimAwesome.CustomFieldsRenderer.init($input);
28
+ reloadCustomFields($input);
20
29
  }
21
30
  });
22
31
  });
@@ -1,4 +1,4 @@
1
- require("formBuilder/dist/form-render.min.js")
1
+ import "formBuilder/dist/form-render.min.js";
2
2
  import "src/decidim/decidim_awesome/forms/rich_text_plugin"
3
3
 
4
4
  export default class CustomFieldsRenderer { // eslint-disable-line no-unused-vars
@@ -56,13 +56,13 @@ export default class CustomFieldsRenderer { // eslint-disable-line no-unused-var
56
56
  */
57
57
  dataToXML(data) {
58
58
  const $dl = $("<dl/>");
59
- let $dd = null,
60
- $div = null,
61
- $dt = null,
62
- datum = null,
63
- key = null,
64
- label = null,
65
- text = null,
59
+ let $dd = null,
60
+ $div = null,
61
+ $dt = null,
62
+ datum = null,
63
+ key = null,
64
+ label = null,
65
+ text = null,
66
66
  val = null;
67
67
  $dl.attr("class", "decidim_awesome-custom_fields");
68
68
  $dl.attr("data-generator", "decidim_awesome");
@@ -117,17 +117,18 @@ export default class CustomFieldsRenderer { // eslint-disable-line no-unused-var
117
117
  }
118
118
 
119
119
  fixBuggyFields() {
120
- if (!this.$container) {
120
+ if (!this.$element) {
121
121
  return false;
122
122
  }
123
123
 
124
124
  /**
125
- * Hack to fix required checkboxes being reset
126
- * Issue: https://github.com/Platoniq/decidim-module-decidim_awesome/issues/82
127
- */
128
- this.$container.find(".formbuilder-checkbox-group").each((_key, group) => {
125
+ * Hack to fix required checkboxes being reset
126
+ * Issue: https://github.com/decidim-ice/decidim-module-decidim_awesome/issues/82
127
+ */
128
+ this.$element.find(".formbuilder-checkbox-group").each((_key, group) => {
129
129
  const inputs = $(".formbuilder-checkbox input", group);
130
- const data = this.spec.find((obj) => obj.type === "checkbox-group");
130
+ const $label = $(group).find("label");
131
+ const data = this.spec.find((obj) => obj.type === "checkbox-group" && obj.name === $label.attr("for"));
131
132
  let values = data.userData;
132
133
  if (!inputs.length || !data || !values) {
133
134
  return;
@@ -163,10 +164,10 @@ export default class CustomFieldsRenderer { // eslint-disable-line no-unused-var
163
164
  });
164
165
 
165
166
  /**
166
- * Hack to fix required radio buttons "other" value
167
- * Issue: https://github.com/Platoniq/decidim-module-decidim_awesome/issues/133
168
- */
169
- this.$container.find(".formbuilder-radio input.other-val").on("input", (input) => {
167
+ * Hack to fix required radio buttons "other" value
168
+ * Issue: https://github.com/decidim-ice/decidim-module-decidim_awesome/issues/133
169
+ */
170
+ this.$element.find(".formbuilder-radio input.other-val").on("input", (input) => {
170
171
  const $input = $(input.currentTarget);
171
172
  const $group = $input.closest(".formbuilder-radio-group");
172
173
  $group.find("input").each((_key, radio) => {
@@ -181,13 +182,14 @@ export default class CustomFieldsRenderer { // eslint-disable-line no-unused-var
181
182
 
182
183
  // Saves xml to the hidden input
183
184
  storeData() {
184
- if (!this.$container) {
185
+ if (!this.$element) {
185
186
  return false;
186
187
  }
187
- const $form = this.$container.closest("form");
188
+ const $form = this.$element.closest("form");
188
189
  const $body = $form.find(`input[name="${this.$element.data("name")}"]`);
189
190
  if ($body.length && this.instance) {
190
191
  this.spec = this.instance.userData;
192
+ console.log("Spec data:", this.spec);
191
193
  $body.val(this.dataToXML(this.spec));
192
194
  this.$element.data("spec", this.spec);
193
195
  }
@@ -196,20 +198,27 @@ export default class CustomFieldsRenderer { // eslint-disable-line no-unused-var
196
198
  }
197
199
 
198
200
  init($element) {
201
+ console.log("CustomFieldsRenderer init");
199
202
  this.$element = $element;
203
+ console.log("Element for rendering:", $element);
204
+
200
205
  this.spec = $element.data("spec");
201
- if (!this.$container) {
202
- this.$container = $(this.containerSelector);
203
- }
206
+ console.log("Spec data:", this.spec);
204
207
  // console.log("init", $element, "this", this)
205
- // always use the last field (in case of multilang tabs we only render one form due a limitation of the library to handle several instances)
206
- this.instance = this.$container.formRender({
208
+ // in case of multilang tabs we only render one form due a limitation in the library for handling several instances
209
+ this.instance = $element.formRender({
207
210
  i18n: {
208
211
  locale: this.lang,
209
212
  location: "https://cdn.jsdelivr.net/npm/formbuilder-languages@1.1.0/"
210
213
  },
211
214
  formData: this.spec,
212
- render: true
215
+ render: true,
216
+ disableInjectedStyle: true,
217
+ controlConfig: {
218
+ "textarea.richtext": {
219
+ editorOptions: $element.data("editorOptions")
220
+ }
221
+ }
213
222
  });
214
223
  this.fixBuggyFields();
215
224
  }
@@ -1,22 +1,38 @@
1
1
  import CustomFieldsRenderer from "src/decidim/decidim_awesome/forms/custom_fields_renderer"
2
2
 
3
- window.DecidimAwesome.CustomFieldsRenderer = window.DecidimAwesome.CustomFieldsRenderer || new CustomFieldsRenderer();
4
-
5
3
  $(() => {
4
+ window.DecidimAwesome.CustomFieldsRenderer = window.DecidimAwesome.CustomFieldsRenderer || new CustomFieldsRenderer();
5
+ window.DecidimAwesome.PrivateCustomFieldsRenderer = window.DecidimAwesome.PrivateCustomFieldsRenderer || new CustomFieldsRenderer();
6
+
6
7
  // use admin multilang specs if exists
7
- let $el = $("proposal_custom_field:first", ".tabs-title.is-active");
8
- if (!$el.length) {
9
- $el = $(".proposal_custom_field:first");
8
+ const $public = $(".proposal_custom_field:first");
9
+ const $private = $(".proposal_custom_field.proposal_custom_field--private_body:first");
10
+ let $form = null;
11
+ if ($public.length) {
12
+ window.DecidimAwesome.CustomFieldsRenderer.init($public);
13
+ $form = window.DecidimAwesome.CustomFieldsRenderer.$element.closest("form");
10
14
  }
11
- window.DecidimAwesome.CustomFieldsRenderer.init($el);
12
-
13
- window.DecidimAwesome.CustomFieldsRenderer.$container.closest("form").on("submit", (evt) => {
14
- if (evt.target.checkValidity()) {
15
- // save current editor
16
- window.DecidimAwesome.CustomFieldsRenderer.storeData();
17
- } else {
18
- evt.preventDefault();
19
- evt.target.reportValidity();
15
+ if ($private.length) {
16
+ window.DecidimAwesome.PrivateCustomFieldsRenderer.init($private);
17
+ if (!$form) {
18
+ $form = window.DecidimAwesome.PrivateCustomFieldsRenderer.$element.closest("form");
20
19
  }
21
- });
20
+ }
21
+
22
+ if ($form) {
23
+ $form.on("submit", (evt) => {
24
+ if (evt.target.checkValidity()) {
25
+ // save current editors
26
+ if ($public.length) {
27
+ window.DecidimAwesome.CustomFieldsRenderer.storeData();
28
+ }
29
+ if ($private.length) {
30
+ window.DecidimAwesome.PrivateCustomFieldsRenderer.storeData();
31
+ }
32
+ } else {
33
+ evt.preventDefault();
34
+ evt.target.reportValidity();
35
+ }
36
+ });
37
+ }
22
38
  });
@@ -3,24 +3,29 @@
3
3
  .awesome-edit-config {
4
4
  .scoped_styles_container,
5
5
  .proposal_custom_fields_container {
6
+ &.private {
7
+ outline: #fca5a5 dotted 2px;
8
+ }
9
+
6
10
  .form-error {
7
11
  margin: 0;
8
12
  }
9
13
 
10
- >.CodeMirror {
14
+ > .CodeMirror {
11
15
  border-top-left-radius: 5px;
12
16
  border-top-right-radius: 5px;
13
- border-top: .5em solid #e0e0e0;
14
- border-right: .5em solid #e0e0e0;
15
- border-bottom: .5em solid #e0e0e0;
17
+ border-top: 0.5em solid #e0e0e0;
18
+ border-right: 0.5em solid #e0e0e0;
19
+ border-bottom: 0.5em solid #e0e0e0;
16
20
  min-height: 6em;
17
- height: auto;
21
+ height: 8em;
22
+ padding: 0;
18
23
  max-height: 40em;
19
24
  resize: vertical;
20
25
  overflow: vertical !important;
21
26
 
22
- >.CodeMirror-scroll {
23
- >.CodeMirror-gutters {
27
+ > .CodeMirror-scroll {
28
+ > .CodeMirror-gutters {
24
29
  background: #e0e0e0;
25
30
  }
26
31
  }