decidim-proposals 0.24.3 → 0.25.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/proposals/cost_report_cell.rb +1 -1
  3. data/app/cells/decidim/proposals/proposal_m_cell.rb +4 -0
  4. data/app/cells/decidim/proposals/proposals_picker/show.erb +1 -1
  5. data/app/commands/decidim/proposals/admin/import_proposals.rb +21 -4
  6. data/app/controllers/decidim/proposals/admin/proposals_controller.rb +1 -1
  7. data/app/controllers/decidim/proposals/collaborative_drafts_controller.rb +1 -0
  8. data/app/controllers/decidim/proposals/proposals_controller.rb +1 -0
  9. data/app/forms/decidim/proposals/admin/import_participatory_text_form.rb +1 -0
  10. data/app/forms/decidim/proposals/admin/proposals_import_form.rb +6 -0
  11. data/app/forms/decidim/proposals/proposal_form.rb +7 -4
  12. data/app/helpers/decidim/proposals/map_helper.rb +5 -5
  13. data/app/helpers/decidim/proposals/participatory_texts_helper.rb +1 -1
  14. data/app/helpers/decidim/proposals/proposal_wizard_helper.rb +0 -16
  15. data/app/models/decidim/proposals/proposal.rb +11 -1
  16. data/app/{assets → packs}/documents/decidim/proposals/participatory_texts/participatory_text.md +0 -0
  17. data/app/{assets → packs}/documents/decidim/proposals/participatory_texts/participatory_text.odt +0 -0
  18. data/app/packs/entrypoints/decidim_proposals.js +8 -0
  19. data/app/packs/entrypoints/decidim_proposals_admin.js +3 -0
  20. data/app/{assets/images/decidim/gamification/badges/accepted_proposals.svg → packs/images/decidim/gamification/badges/decidim_gamification_badges_accepted_proposals.svg} +0 -0
  21. data/app/{assets/images/decidim/gamification/badges/proposal_votes.svg → packs/images/decidim/gamification/badges/decidim_gamification_badges_proposal_votes.svg} +0 -0
  22. data/app/{assets/images/decidim/gamification/badges/proposals.svg → packs/images/decidim/gamification/badges/decidim_gamification_badges_proposals.svg} +0 -0
  23. data/app/{assets/images/decidim/proposals/icon.svg → packs/images/decidim/proposals/decidim_proposals.svg} +0 -0
  24. data/app/packs/src/decidim/proposals/add_proposal.js +49 -0
  25. data/app/packs/src/decidim/proposals/admin/proposals.js +143 -0
  26. data/app/{assets/javascripts/decidim/proposals/admin/proposals_form.js.es6 → packs/src/decidim/proposals/admin/proposals_form.js} +2 -2
  27. data/app/{assets/javascripts/decidim/proposals/admin/proposals_picker.js.es6 → packs/src/decidim/proposals/admin/proposals_picker.js} +0 -0
  28. data/app/{assets/javascripts/decidim/proposals/utils.js.es6 → packs/src/decidim/proposals/utils.js} +2 -2
  29. data/app/packs/stylesheets/decidim/proposals/_proposals.scss +1 -0
  30. data/app/{assets/stylesheets/decidim/proposals/proposals/_preview.css.scss → packs/stylesheets/decidim/proposals/proposals/_preview.scss} +0 -0
  31. data/app/presenters/decidim/proposals/proposal_presenter.rb +2 -23
  32. data/app/queries/decidim/proposals/metrics/accepted_proposals_metric_manage.rb +1 -1
  33. data/app/queries/decidim/proposals/metrics/proposals_metric_manage.rb +1 -1
  34. data/app/queries/decidim/proposals/metrics/votes_metric_manage.rb +1 -1
  35. data/app/queries/decidim/proposals/similar_proposals.rb +1 -0
  36. data/app/services/decidim/proposals/proposal_builder.rb +4 -4
  37. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
  38. data/app/views/decidim/proposals/admin/proposals/index.html.erb +1 -1
  39. data/app/views/decidim/proposals/admin/proposals_imports/new.html.erb +6 -0
  40. data/app/views/decidim/proposals/collaborative_drafts/_filters.html.erb +1 -1
  41. data/app/views/decidim/proposals/collaborative_drafts/edit.html.erb +1 -1
  42. data/app/views/decidim/proposals/collaborative_drafts/index.html.erb +0 -2
  43. data/app/views/decidim/proposals/collaborative_drafts/new.html.erb +1 -1
  44. data/app/views/decidim/proposals/proposals/_dynamic_map_instructions.html.erb +2 -1
  45. data/app/views/decidim/proposals/proposals/_edit_form_fields.html.erb +5 -1
  46. data/app/views/decidim/proposals/proposals/_filters.html.erb +1 -1
  47. data/app/views/decidim/proposals/proposals/complete.html.erb +1 -1
  48. data/app/views/decidim/proposals/proposals/edit.html.erb +1 -1
  49. data/app/views/decidim/proposals/proposals/edit_draft.html.erb +1 -1
  50. data/app/views/decidim/proposals/proposals/index.html.erb +4 -6
  51. data/app/views/decidim/proposals/proposals/new.html.erb +1 -1
  52. data/app/views/decidim/proposals/proposals/preview.html.erb +7 -31
  53. data/config/assets.rb +10 -0
  54. data/config/locales/ar.yml +3 -1
  55. data/config/locales/bg.yml +3 -1
  56. data/config/locales/ca.yml +10 -4
  57. data/config/locales/cs.yml +12 -3
  58. data/config/locales/de.yml +10 -4
  59. data/config/locales/el.yml +3 -1
  60. data/config/locales/en.yml +12 -3
  61. data/config/locales/es-MX.yml +10 -4
  62. data/config/locales/es-PY.yml +10 -4
  63. data/config/locales/es.yml +10 -4
  64. data/config/locales/eu.yml +3 -1
  65. data/config/locales/fi-plain.yml +12 -3
  66. data/config/locales/fi.yml +12 -3
  67. data/config/locales/fr-CA.yml +8 -3
  68. data/config/locales/fr-LU.yml +903 -0
  69. data/config/locales/fr.yml +8 -3
  70. data/config/locales/gl.yml +11 -3
  71. data/config/locales/hu.yml +3 -1
  72. data/config/locales/id-ID.yml +3 -1
  73. data/config/locales/it.yml +55 -1
  74. data/config/locales/ja.yml +38 -1
  75. data/config/locales/lb-LU.yml +1 -0
  76. data/config/locales/lv.yml +3 -1
  77. data/config/locales/nl.yml +13 -2
  78. data/config/locales/no.yml +3 -1
  79. data/config/locales/pl.yml +14 -10
  80. data/config/locales/pt-BR.yml +199 -1
  81. data/config/locales/pt.yml +3 -1
  82. data/config/locales/ro-RO.yml +6 -1
  83. data/config/locales/ru.yml +3 -1
  84. data/config/locales/sk.yml +3 -1
  85. data/config/locales/sv.yml +13 -4
  86. data/config/locales/tr-TR.yml +3 -4
  87. data/config/locales/uk.yml +3 -1
  88. data/config/locales/zh-CN.yml +3 -1
  89. data/db/migrate/20201002085508_fix_proposals_data.rb +7 -8
  90. data/db/migrate/20210318082934_fix_counters_for_copied_proposals.rb +6 -5
  91. data/lib/decidim/proposals/admin_engine.rb +0 -4
  92. data/lib/decidim/proposals/commentable_proposal.rb +5 -13
  93. data/lib/decidim/proposals/component.rb +4 -4
  94. data/lib/decidim/proposals/engine.rb +14 -19
  95. data/lib/decidim/proposals/proposal_serializer.rb +1 -0
  96. data/lib/decidim/proposals/test/capybara_proposals_picker.rb +10 -0
  97. data/lib/decidim/proposals/test/factories.rb +3 -0
  98. data/lib/decidim/proposals/version.rb +1 -1
  99. data/lib/decidim/proposals.rb +0 -1
  100. metadata +38 -112
  101. data/app/assets/config/admin/decidim_proposals_manifest.js +0 -2
  102. data/app/assets/config/decidim_proposals_manifest.js +0 -4
  103. data/app/assets/javascripts/decidim/proposals/add_proposal.js.es6 +0 -31
  104. data/app/assets/javascripts/decidim/proposals/admin/proposals.es6 +0 -130
  105. data/app/assets/stylesheets/decidim/proposals/_proposals.css.scss +0 -1
  106. data/config/locales/ja-JP.yml +0 -865
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b58a35a743ae0db25c4454f55ffe7514979bf217f453a71d42d2de4eed3a65f
4
- data.tar.gz: 8d6df0cbfb9c6b8f974bb508be40ece45c87a0aa7be2b1efcf3fc30038d4c7f1
3
+ metadata.gz: 7d9c43451e2fc8c52a79196d495c118a98975055022f9fec931f083b206fa490
4
+ data.tar.gz: 412c3edde43a3526be7564c1616aaa6a2dfc78e031a6f79f43747c79703c1106
5
5
  SHA512:
6
- metadata.gz: ffe7f175d86d25aabbfe21fe9b8de2c27422a7f8fa1f7ee9abbea81ac947562fb8eed95a1d2915bac7d2907b3c81e30c52ec75b4c26cc9ce026d245ea41db7d5
7
- data.tar.gz: c54993408b404d5fd92c0e7030f0b08f22127ad384a4fbdf8b92a966f3a7a9c5b2c7e575ede7a0260bd1f8271989e4b4977fe8cbe96bd1aa8664b1ca8fd2e032
6
+ metadata.gz: 5b969421575f883d0752fc04ae9f74f93e2aa453461e31a3fef38e0da1cec1447380e6247b5be54894915b6bcc9a187543ef7d779b8d96f5824aa36e7981024e
7
+ data.tar.gz: 94e5ffef23d8ac232fb27771ab464dbe8340dba903defb4f0e4060633c6f5a8877cd0ac4c9d8a5925bce860d0b69a46c1f2df97eca869e85370492ed6d02f99f
@@ -14,7 +14,7 @@ module Decidim
14
14
  private
15
15
 
16
16
  def cost
17
- number_to_currency(model.cost)
17
+ number_to_currency(model.cost, unit: Decidim.currency_unit)
18
18
  end
19
19
 
20
20
  def cost_report
@@ -132,14 +132,18 @@ module Decidim
132
132
  hash << model.cache_key_with_version
133
133
  hash << model.proposal_votes_count
134
134
  hash << model.endorsements_count
135
+ hash << model.comments_count
135
136
  hash << Digest::MD5.hexdigest(model.component.cache_key_with_version)
136
137
  hash << Digest::MD5.hexdigest(resource_image_path) if resource_image_path
138
+ hash << render_space? ? 1 : 0
137
139
  if current_user
138
140
  hash << current_user.cache_key_with_version
139
141
  hash << current_user.follows?(model) ? 1 : 0
140
142
  end
141
143
  hash << model.follows_count
142
144
  hash << Digest::MD5.hexdigest(model.authors.map(&:cache_key_with_version).to_s)
145
+ hash << (model.must_render_translation?(model.organization) ? 1 : 0) if model.respond_to?(:must_render_translation?)
146
+ hash << model.component.participatory_space.active_step.id if model.component.participatory_space.has_steps?
143
147
 
144
148
  hash.join("/")
145
149
  end
@@ -11,4 +11,4 @@
11
11
  </div>
12
12
  </div>
13
13
 
14
- <%= javascript_include_tag "decidim/proposals/admin/proposals_picker" %>
14
+ <%= javascript_pack_tag "decidim_proposals_admin" %>
@@ -39,15 +39,17 @@ module Decidim
39
39
  action_user: form.current_user,
40
40
  extra_attributes: {
41
41
  "component" => target_component
42
- }
42
+ }.merge(proposal_answer_attributes(original_proposal))
43
43
  )
44
44
  end.compact
45
45
  end
46
46
 
47
47
  def proposals
48
- Decidim::Proposals::Proposal
49
- .where(component: origin_component)
50
- .where(state: proposal_states)
48
+ @proposals = Decidim::Proposals::Proposal
49
+ .where(component: origin_component)
50
+ .where(state: proposal_states)
51
+ @proposals = @proposals.where(scope: proposal_scopes) unless proposal_scopes.empty?
52
+ @proposals
51
53
  end
52
54
 
53
55
  def proposal_states
@@ -61,6 +63,10 @@ module Decidim
61
63
  @proposal_states
62
64
  end
63
65
 
66
+ def proposal_scopes
67
+ @form.scopes
68
+ end
69
+
64
70
  def origin_component
65
71
  @form.origin_component
66
72
  end
@@ -78,6 +84,17 @@ module Decidim
78
84
  def proposal_author
79
85
  form.keep_authors ? nil : @form.current_organization
80
86
  end
87
+
88
+ def proposal_answer_attributes(original_proposal)
89
+ return {} unless form.keep_answers
90
+
91
+ {
92
+ answer: original_proposal.answer,
93
+ answered_at: original_proposal.answered_at,
94
+ state: original_proposal.state,
95
+ state_published_at: original_proposal.state_published_at
96
+ }
97
+ end
81
98
  end
82
99
  end
83
100
  end
@@ -147,7 +147,7 @@ module Decidim
147
147
  private
148
148
 
149
149
  def collection
150
- @collection ||= Proposal.where(component: current_component).published
150
+ @collection ||= Proposal.where(component: current_component).not_hidden.published
151
151
  end
152
152
 
153
153
  def proposals
@@ -7,6 +7,7 @@ module Decidim
7
7
  helper Decidim::WidgetUrlsHelper
8
8
  helper ProposalWizardHelper
9
9
  helper TooltipHelper
10
+ helper UserGroupHelper
10
11
 
11
12
  include Decidim::ApplicationHelper
12
13
  include FormFactory
@@ -7,6 +7,7 @@ module Decidim
7
7
  helper Decidim::WidgetUrlsHelper
8
8
  helper ProposalWizardHelper
9
9
  helper ParticipatoryTextsHelper
10
+ helper UserGroupHelper
10
11
  include Decidim::ApplicationHelper
11
12
  include Flaggable
12
13
  include Withdrawable
@@ -7,6 +7,7 @@ module Decidim
7
7
  # from a participatory text.
8
8
  class ImportParticipatoryTextForm < Decidim::Form
9
9
  include TranslatableAttributes
10
+ include Decidim::HasUploadValidations
10
11
 
11
12
  # WARNING: consider adding/removing the relative translation key at
12
13
  # decidim.assemblies.admin.new_import.accepted_types when modifying this hash
@@ -10,8 +10,10 @@ module Decidim
10
10
 
11
11
  attribute :origin_component_id, Integer
12
12
  attribute :import_proposals, Boolean
13
+ attribute :keep_answers, Boolean
13
14
  attribute :keep_authors, Boolean
14
15
  attribute :states, Array
16
+ attribute :scope_ids, Array
15
17
 
16
18
  validates :origin_component_id, :origin_component, :states, :current_component, presence: true
17
19
  validates :import_proposals, allow_nil: false, acceptance: true
@@ -32,6 +34,10 @@ module Decidim
32
34
  super.reject(&:blank?)
33
35
  end
34
36
 
37
+ def scopes
38
+ Decidim::Scope.where(organization: current_organization, id: scope_ids)
39
+ end
40
+
35
41
  def origin_component
36
42
  @origin_component ||= origin_components.find_by(id: origin_component_id)
37
43
  end
@@ -107,12 +107,15 @@ module Decidim
107
107
 
108
108
  private
109
109
 
110
- # This method will add an error to the `attachment` field only if there's
111
- # any error in any other field. This is needed because when the form has
112
- # an error, the attachment is lost, so we need a way to inform the user of
110
+ # This method will add an error to the `add_photos` and/or "add_documents" fields
111
+ # only if there's any error in any other field. This is needed because when the
112
+ # form has an error, the attachment is lost, so we need a way to inform the user of
113
113
  # this problem.
114
114
  def notify_missing_attachment_if_errored
115
- errors.add(:attachment, :needs_to_be_reattached) if errors.any? && attachment.present?
115
+ if errors.any?
116
+ errors.add(:add_photos, :needs_to_be_reattached) if add_photos.present?
117
+ errors.add(:add_documents, :needs_to_be_reattached) if add_documents.present?
118
+ end
116
119
  end
117
120
 
118
121
  def ordered_hashtag_list(string)
@@ -26,16 +26,16 @@ module Decidim
26
26
  end
27
27
 
28
28
  def proposal_preview_data_for_map(proposal)
29
- [
30
- proposal.slice(
29
+ {
30
+ type: "drag-marker",
31
+ marker: proposal.slice(
31
32
  :latitude,
32
33
  :longitude,
33
34
  :address
34
35
  ).merge(
35
- icon: icon("proposals", width: 40, height: 70, remove_icon_class: true),
36
- draggable: true
36
+ icon: icon("proposals", width: 40, height: 70, remove_icon_class: true)
37
37
  )
38
- ]
38
+ }
39
39
  end
40
40
 
41
41
  def has_position?(proposal)
@@ -30,7 +30,7 @@ module Decidim
30
30
  accepted_mime_types = Decidim::Proposals::DocToMarkdown::ACCEPTED_MIME_TYPES.keys
31
31
  accepted_mime_types.each_with_index do |mime_type, index|
32
32
  links += link_to t(".accepted_mime_types.#{mime_type}"),
33
- asset_path("decidim/proposals/participatory_texts/participatory_text.#{mime_type}"),
33
+ asset_pack_path("media/documents/participatory_text.#{mime_type}"),
34
34
  download: "participatory_text.#{mime_type}"
35
35
  links += ", " unless accepted_mime_types.length == index + 1
36
36
  end
@@ -107,22 +107,6 @@ module Decidim
107
107
  translated_attribute(component_settings.try("proposal_wizard_#{step}_help_text")).present?
108
108
  end
109
109
 
110
- # Renders a user_group select field in a form.
111
- # form - FormBuilder object
112
- # name - attribute user_group_id
113
- #
114
- # Returns nothing.
115
- def user_group_select_field(form, name)
116
- selected = @form.user_group_id.presence
117
- user_groups = Decidim::UserGroups::ManageableUserGroups.for(current_user).verified
118
- form.select(
119
- name,
120
- user_groups.map { |g| [g.name, g.id] },
121
- selected: selected,
122
- include_blank: current_user.name
123
- )
124
- end
125
-
126
110
  private
127
111
 
128
112
  def total_steps
@@ -337,8 +337,18 @@ module Decidim
337
337
  ")
338
338
  end
339
339
 
340
+ def self.sort_by_translated_title_asc
341
+ field = Arel::Nodes::InfixOperation.new("->>", arel_table[:title], Arel::Nodes.build_quoted(I18n.locale))
342
+ order(Arel::Nodes::InfixOperation.new("", field, Arel.sql("ASC")))
343
+ end
344
+
345
+ def self.sort_by_translated_title_desc
346
+ field = Arel::Nodes::InfixOperation.new("->>", arel_table[:title], Arel::Nodes.build_quoted(I18n.locale))
347
+ order(Arel::Nodes::InfixOperation.new("", field, Arel.sql("DESC")))
348
+ end
349
+
340
350
  ransacker :title do
341
- Arel.sql(%{("decidim_proposals_proposals"."title")::text})
351
+ Arel.sql(%{cast("decidim_proposals_proposals"."title" as text)})
342
352
  end
343
353
 
344
354
  ransacker :id_string do
@@ -0,0 +1,8 @@
1
+ import "src/decidim/proposals/utils"
2
+ import "src/decidim/proposals/add_proposal"
3
+
4
+ // Images
5
+ require.context("../images", true)
6
+
7
+ // Documents
8
+ require.context("../documents", true)
@@ -0,0 +1,3 @@
1
+ import "src/decidim/proposals/admin/proposals"
2
+ import "src/decidim/proposals/admin/proposals_form"
3
+ import "src/decidim/proposals/admin/proposals_picker"
@@ -0,0 +1,49 @@
1
+ import attachGeocoding from "src/decidim/geocoding/attach_input"
2
+ import getCoordinateInputName from "src/decidim/geocoding/coordinate_input";
3
+
4
+ $(() => {
5
+ const $checkbox = $("input:checkbox[name$='[has_address]']");
6
+ const $addressInput = $("#address_input");
7
+ const $addressInputField = $("input", $addressInput);
8
+ const $map = $("#address_map");
9
+ const latFieldName = getCoordinateInputName("latitude", $addressInputField, {})
10
+ const longFieldName = getCoordinateInputName("longitude", $addressInputField, {})
11
+ $map.hide();
12
+
13
+ if ($checkbox.length > 0) {
14
+ const toggleInput = () => {
15
+ if ($checkbox[0].checked) {
16
+ $addressInput.show();
17
+ $addressInputField.prop("disabled", false);
18
+ } else {
19
+ $addressInput.hide();
20
+ $addressInputField.prop("disabled", true);
21
+ }
22
+ }
23
+ toggleInput();
24
+ $checkbox.on("change", toggleInput);
25
+ }
26
+
27
+ if ($addressInput.length > 0) {
28
+ if ($checkbox[0].checked) {
29
+ $map.show();
30
+ }
31
+
32
+ const ctrl = $("[data-decidim-map]").data("map-controller");
33
+ ctrl.setEventHandler("coordinates", (ev) => {
34
+ $(`input[name='${latFieldName}']`).val(ev.lat);
35
+ $(`input[name='${longFieldName}']`).val(ev.lng);
36
+ });
37
+
38
+ attachGeocoding($addressInputField, null, (coordinates) => {
39
+ $map.show();
40
+ // Remove previous marker when user updates address in address field
41
+ ctrl.removeMarker();
42
+ ctrl.addMarker({
43
+ latitude: coordinates[0],
44
+ longitude: coordinates[1],
45
+ address: $addressInput.val()
46
+ });
47
+ });
48
+ }
49
+ });
@@ -0,0 +1,143 @@
1
+ /* eslint-disable no-invalid-this */
2
+ /* eslint no-unused-vars: 0 */
3
+ /* eslint id-length: ["error", { "exceptions": ["e"] }] */
4
+
5
+ $(() => {
6
+ const selectedProposalsCount = function() {
7
+ return $(".table-list .js-check-all-proposal:checked").length
8
+ }
9
+
10
+ const selectedProposalsNotPublishedAnswerCount = function() {
11
+ return $(".table-list [data-published-state=false] .js-check-all-proposal:checked").length
12
+ }
13
+
14
+ const selectedProposalsCountUpdate = function() {
15
+ const selectedProposals = selectedProposalsCount();
16
+ const selectedProposalsNotPublishedAnswer = selectedProposalsNotPublishedAnswerCount();
17
+ if (selectedProposals === 0) {
18
+ $("#js-selected-proposals-count").text("")
19
+ } else {
20
+ $("#js-selected-proposals-count").text(selectedProposals);
21
+ }
22
+
23
+ if (selectedProposals >= 2) {
24
+ $('button[data-action="merge-proposals"]').parent().show();
25
+ } else {
26
+ $('button[data-action="merge-proposals"]').parent().hide();
27
+ }
28
+
29
+ if (selectedProposalsNotPublishedAnswer > 0) {
30
+ $('button[data-action="publish-answers"]').parent().show();
31
+ $("#js-form-publish-answers-number").text(selectedProposalsNotPublishedAnswer);
32
+ } else {
33
+ $('button[data-action="publish-answers"]').parent().hide();
34
+ }
35
+ }
36
+
37
+ const showBulkActionsButton = function() {
38
+ if (selectedProposalsCount() > 0) {
39
+ $("#js-bulk-actions-button").removeClass("hide");
40
+ }
41
+ }
42
+
43
+ const hideBulkActionsButton = function(force = false) {
44
+ if (selectedProposalsCount() === 0 || force === true) {
45
+ $("#js-bulk-actions-button").addClass("hide");
46
+ $("#js-bulk-actions-dropdown").removeClass("is-open");
47
+ }
48
+ }
49
+
50
+ const showOtherActionsButtons = function() {
51
+ $("#js-other-actions-wrapper").removeClass("hide");
52
+ }
53
+
54
+ const hideOtherActionsButtons = function() {
55
+ $("#js-other-actions-wrapper").addClass("hide");
56
+ }
57
+
58
+ const hideBulkActionForms = function() {
59
+ $(".js-bulk-action-form").addClass("hide");
60
+ }
61
+
62
+ // Expose functions to make them avaialble in .js.erb templates
63
+ window.selectedProposalsCount = selectedProposalsCount;
64
+ window.selectedProposalsNotPublishedAnswerCount = selectedProposalsNotPublishedAnswerCount;
65
+ window.selectedProposalsCountUpdate = selectedProposalsCountUpdate;
66
+ window.showBulkActionsButton = showBulkActionsButton;
67
+ window.hideBulkActionsButton = hideBulkActionsButton;
68
+ window.showOtherActionsButtons = showOtherActionsButtons;
69
+ window.hideOtherActionsButtons = hideOtherActionsButtons;
70
+ window.hideBulkActionForms = hideBulkActionForms;
71
+
72
+ if ($(".js-bulk-action-form").length) {
73
+ hideBulkActionForms();
74
+ $("#js-bulk-actions-button").addClass("hide");
75
+
76
+ $("#js-bulk-actions-dropdown ul li button").click(function(e) {
77
+ e.preventDefault();
78
+ let action = $(e.target).data("action");
79
+
80
+ if (action) {
81
+ $(`#js-form-${action}`).submit(function() {
82
+ $(".layout-content > .callout-wrapper").html("");
83
+ })
84
+
85
+ $(`#js-${action}-actions`).removeClass("hide");
86
+ hideBulkActionsButton(true);
87
+ hideOtherActionsButtons();
88
+ }
89
+ })
90
+
91
+ // select all checkboxes
92
+ $(".js-check-all").change(function() {
93
+ $(".js-check-all-proposal").prop("checked", $(this).prop("checked"));
94
+
95
+ if ($(this).prop("checked")) {
96
+ $(".js-check-all-proposal").closest("tr").addClass("selected");
97
+ showBulkActionsButton();
98
+ } else {
99
+ $(".js-check-all-proposal").closest("tr").removeClass("selected");
100
+ hideBulkActionsButton();
101
+ }
102
+
103
+ selectedProposalsCountUpdate();
104
+ });
105
+
106
+ // proposal checkbox change
107
+ $(".table-list").on("change", ".js-check-all-proposal", function (e) {
108
+ let proposalId = $(this).val()
109
+ let checked = $(this).prop("checked")
110
+
111
+ // uncheck "select all", if one of the listed checkbox item is unchecked
112
+ if ($(this).prop("checked") === false) {
113
+ $(".js-check-all").prop("checked", false);
114
+ }
115
+ // check "select all" if all checkbox proposals are checked
116
+ if ($(".js-check-all-proposal:checked").length === $(".js-check-all-proposal").length) {
117
+ $(".js-check-all").prop("checked", true);
118
+ showBulkActionsButton();
119
+ }
120
+
121
+ if ($(this).prop("checked")) {
122
+ showBulkActionsButton();
123
+ $(this).closest("tr").addClass("selected");
124
+ } else {
125
+ hideBulkActionsButton();
126
+ $(this).closest("tr").removeClass("selected");
127
+ }
128
+
129
+ if ($(".js-check-all-proposal:checked").length === 0) {
130
+ hideBulkActionsButton();
131
+ }
132
+
133
+ $(".js-bulk-action-form").find(`.js-proposal-id-${proposalId}`).prop("checked", checked);
134
+ selectedProposalsCountUpdate();
135
+ });
136
+
137
+ $(".js-cancel-bulk-action").on("click", function (e) {
138
+ hideBulkActionForms()
139
+ showBulkActionsButton();
140
+ showOtherActionsButtons();
141
+ });
142
+ }
143
+ });
@@ -1,6 +1,6 @@
1
- $(() => {
2
- const { attachGeocoding } = window.Decidim;
1
+ import attachGeocoding from "src/decidim/geocoding/attach_input"
3
2
 
3
+ $(() => {
4
4
  const $form = $(".proposal_form_admin");
5
5
 
6
6
  if ($form.length > 0) {
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-invalid-this */
2
2
 
3
- (() => {
3
+ $(() => {
4
4
  $("#vote_button").mouseover(function () {
5
5
  $(this).text($(this).data("replace"));
6
6
  });
@@ -8,4 +8,4 @@
8
8
  $("#vote_button").mouseout(function () {
9
9
  $(this).text($(this).data("original"));
10
10
  });
11
- })(this);
11
+ });
@@ -0,0 +1 @@
1
+ @import "stylesheets/decidim/proposals/proposals/preview";
@@ -5,11 +5,9 @@ module Decidim
5
5
  #
6
6
  # Decorator for proposals
7
7
  #
8
- class ProposalPresenter < SimpleDelegator
8
+ class ProposalPresenter < Decidim::ResourcePresenter
9
9
  include Rails.application.routes.mounted_helpers
10
10
  include ActionView::Helpers::UrlHelper
11
- include Decidim::SanitizeHelper
12
- include Decidim::TranslatableAttributes
13
11
 
14
12
  def author
15
13
  @author ||= if official?
@@ -41,12 +39,7 @@ module Decidim
41
39
  def title(links: false, extras: true, html_escape: false, all_locales: false)
42
40
  return unless proposal
43
41
 
44
- handle_locales(proposal.title, all_locales) do |content|
45
- content = decidim_html_escape(content) if html_escape
46
-
47
- renderer = Decidim::ContentRenderers::HashtagRenderer.new(content)
48
- renderer.render(links: links, extras: extras).html_safe
49
- end
42
+ super proposal.title, links, html_escape, all_locales, extras: extras
50
43
  end
51
44
 
52
45
  def id_and_title(links: false, extras: true, html_escape: false)
@@ -135,20 +128,6 @@ module Decidim
135
128
  def sanitize_text(text)
136
129
  add_line_feeds(sanitize_ordered_lists(sanitize_unordered_lists(text)))
137
130
  end
138
-
139
- def handle_locales(content, all_locales, &block)
140
- if all_locales
141
- content.each_with_object({}) do |(key, value), parsed_content|
142
- parsed_content[key] = if key == "machine_translations"
143
- handle_locales(value, all_locales, &block)
144
- else
145
- block.call(value)
146
- end
147
- end
148
- else
149
- yield(translated_attribute(content))
150
- end
151
- end
152
131
  end
153
132
  end
154
133
  end
@@ -16,7 +16,7 @@ module Decidim
16
16
  spaces = Decidim.participatory_space_manifests.flat_map do |manifest|
17
17
  manifest.participatory_spaces.call(@organization).public_spaces
18
18
  end
19
- @query = Decidim::Proposals::Proposal.where(component: visible_component_ids_from_spaces(spaces)).joins(:component)
19
+ @query = Decidim::Proposals::Proposal.where(component: visible_components_from_spaces(spaces)).joins(:component)
20
20
  .left_outer_joins(:category)
21
21
  @query = @query.where("decidim_proposals_proposals.created_at <= ?", end_time).accepted
22
22
  @query = @query.group("decidim_categorizations.id", :participatory_space_type, :participatory_space_id)
@@ -30,7 +30,7 @@ module Decidim
30
30
  spaces = Decidim.participatory_space_manifests.flat_map do |manifest|
31
31
  manifest.participatory_spaces.call(@organization)
32
32
  end
33
- @query = Decidim::Proposals::Proposal.where(component: visible_component_ids_from_spaces(spaces)).joins(:component)
33
+ @query = Decidim::Proposals::Proposal.where(component: visible_components_from_spaces(spaces)).joins(:component)
34
34
  .left_outer_joins(:category)
35
35
  @query = @query.where("decidim_proposals_proposals.published_at <= ?", end_time).except_withdrawn.not_hidden
36
36
  @query = @query.group("decidim_categorizations.decidim_category_id",
@@ -31,7 +31,7 @@ module Decidim
31
31
  spaces = Decidim.participatory_space_manifests.flat_map do |manifest|
32
32
  manifest.participatory_spaces.call(@organization).public_spaces
33
33
  end
34
- proposal_ids = Decidim::Proposals::Proposal.where(component: visible_component_ids_from_spaces(spaces.pluck(:id))).except_withdrawn.not_hidden.pluck(:id)
34
+ proposal_ids = Decidim::Proposals::Proposal.where(component: visible_components_from_spaces(spaces)).except_withdrawn.not_hidden.pluck(:id)
35
35
  @query = Decidim::Proposals::ProposalVote.joins(proposal: :component)
36
36
  .left_outer_joins(proposal: :category)
37
37
  .where(proposal: proposal_ids)
@@ -28,6 +28,7 @@ module Decidim
28
28
  Decidim::Proposals::Proposal
29
29
  .where(component: @components)
30
30
  .published
31
+ .not_hidden
31
32
  .where(
32
33
  "GREATEST(#{title_similarity}, #{body_similarity}) >= ?",
33
34
  translated_attribute(@proposal.title),
@@ -110,14 +110,14 @@ module Decidim
110
110
  # Attached to needs to be always defined before the file is set
111
111
  attached_to: proposal
112
112
  }.merge(
113
- attachment.attributes.slice("content_type", "description", "file", "file_size", "title", "weight")
113
+ attachment.attributes.slice("content_type", "description", "file_size", "title", "weight")
114
114
  )
115
115
  )
116
116
 
117
- if File.exist?(attachment.file.file.path)
118
- new_attachment.file = File.open(attachment.file.file.path)
117
+ if attachment.file.attached?
118
+ new_attachment.file = attachment.file.blob
119
119
  else
120
- new_attachment.remote_file_url = attachment.url
120
+ new_attachment.attached_uploader(:file).remote_url = attachment.attached_uploader(:file).url(host: original_proposal.organization.host)
121
121
  end
122
122
 
123
123
  new_attachment.save!
@@ -98,4 +98,4 @@
98
98
  </div>
99
99
  </div>
100
100
 
101
- <%= javascript_include_tag "decidim/proposals/admin/proposals_form" %>
101
+ <%= javascript_pack_tag "decidim_proposals_admin" %>
@@ -81,4 +81,4 @@
81
81
  </div>
82
82
  </div>
83
83
 
84
- <%= javascript_include_tag "decidim/proposals/admin/proposals" %>
84
+ <%= javascript_pack_tag "decidim_proposals_admin" %>
@@ -16,6 +16,12 @@
16
16
  <div class="row column">
17
17
  <%= f.check_box :keep_authors %>
18
18
  </div>
19
+ <div class="row column">
20
+ <%= f.check_box :keep_answers %>
21
+ </div>
22
+ <div class="row column">
23
+ <%= scopes_picker_filter f, :scope_ids %>
24
+ </div>
19
25
  <div class="row column">
20
26
  <%= f.check_box :import_proposals %>
21
27
  </div>