decidim-budgets 0.30.2 → 0.31.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/budgets/budget_list_item/show.erb +19 -9
  3. data/app/cells/decidim/budgets/budget_list_item/vote_action.erb +2 -2
  4. data/app/cells/decidim/budgets/budget_list_item_cell.rb +44 -10
  5. data/app/cells/decidim/budgets/budgets_list/card_list.erb +0 -2
  6. data/app/cells/decidim/budgets/budgets_list/main_list.erb +2 -2
  7. data/app/cells/decidim/budgets/budgets_list/show.erb +3 -3
  8. data/app/cells/decidim/budgets/budgets_list/voted.erb +12 -10
  9. data/app/cells/decidim/budgets/budgets_list_cell.rb +22 -0
  10. data/app/cells/decidim/budgets/project_budget_amount_cell.rb +14 -0
  11. data/app/cells/decidim/budgets/project_l/extra_data.erb +8 -2
  12. data/app/cells/decidim/budgets/project_l/metadata.erb +1 -1
  13. data/app/cells/decidim/budgets/project_l_cell.rb +2 -4
  14. data/app/cells/decidim/budgets/project_metadata_cell.rb +11 -19
  15. data/app/cells/decidim/budgets/project_selected_status_cell.rb +1 -11
  16. data/app/cells/decidim/budgets/project_vote_button/show.erb +5 -5
  17. data/app/cells/decidim/budgets/project_vote_button_cell.rb +14 -9
  18. data/app/cells/decidim/budgets/project_votes_count_cell.rb +8 -14
  19. data/app/commands/decidim/budgets/cancel_order.rb +5 -0
  20. data/app/controllers/decidim/budgets/admin/budgets_controller.rb +2 -2
  21. data/app/controllers/decidim/budgets/admin/projects_controller.rb +2 -2
  22. data/app/controllers/decidim/budgets/admin/proposals_imports_controller.rb +1 -1
  23. data/app/controllers/decidim/budgets/application_controller.rb +13 -1
  24. data/app/controllers/decidim/budgets/budgets_controller.rb +1 -3
  25. data/app/controllers/decidim/budgets/line_items_controller.rb +19 -0
  26. data/app/controllers/decidim/budgets/orders_controller.rb +20 -0
  27. data/app/controllers/decidim/budgets/projects_controller.rb +3 -1
  28. data/app/forms/decidim/budgets/admin/component_form.rb +4 -30
  29. data/app/helpers/decidim/budgets/application_helper.rb +1 -0
  30. data/app/helpers/decidim/budgets/projects_helper.rb +11 -7
  31. data/app/models/decidim/budgets/order.rb +2 -2
  32. data/app/packs/entrypoints/decidim_budgets.js +1 -0
  33. data/app/packs/src/decidim/budgets/admin/projects.js +2 -2
  34. data/app/packs/src/decidim/budgets/budgetSummaryBackdrop.js +41 -0
  35. data/app/packs/src/decidim/budgets/exit_handler.js +7 -2
  36. data/app/packs/src/decidim/budgets/progressFixed.js +1 -1
  37. data/app/packs/src/decidim/budgets/projects.js +1 -1
  38. data/app/packs/stylesheets/budgets.scss +57 -37
  39. data/app/permissions/decidim/budgets/permissions.rb +17 -13
  40. data/app/presenters/decidim/budgets/project_presenter.rb +2 -4
  41. data/app/views/decidim/budgets/admin/budgets/_actions.html.erb +65 -18
  42. data/app/views/decidim/budgets/admin/budgets/_budget-tr.html.erb +4 -4
  43. data/app/views/decidim/budgets/admin/budgets/_form.html.erb +1 -1
  44. data/app/views/decidim/budgets/admin/budgets/index.html.erb +14 -11
  45. data/app/views/decidim/budgets/admin/budgets/manage_trash.html.erb +2 -1
  46. data/app/views/decidim/budgets/admin/projects/_actions.html.erb +66 -22
  47. data/app/views/decidim/budgets/admin/projects/_bulk-actions.html.erb +15 -17
  48. data/app/views/decidim/budgets/admin/projects/_form.html.erb +1 -1
  49. data/app/views/decidim/budgets/admin/projects/_project-tr.html.erb +7 -7
  50. data/app/views/decidim/budgets/admin/projects/bulk_actions/_dropdown.html.erb +23 -30
  51. data/app/views/decidim/budgets/admin/projects/index.html.erb +2 -2
  52. data/app/views/decidim/budgets/admin/projects/manage_trash.html.erb +2 -1
  53. data/app/views/decidim/budgets/line_items/update_budget.js.erb +6 -5
  54. data/app/views/decidim/budgets/orders/status.html.erb +30 -30
  55. data/app/views/decidim/budgets/projects/_addition_selector.html.erb +1 -1
  56. data/app/views/decidim/budgets/projects/_budget_summary.html.erb +5 -1
  57. data/app/views/decidim/budgets/projects/_exit_modal.html.erb +1 -1
  58. data/app/views/decidim/budgets/projects/_project.html.erb +5 -1
  59. data/app/views/decidim/budgets/projects/_project_budget_button.html.erb +1 -9
  60. data/app/views/decidim/budgets/projects/_projects.html.erb +3 -1
  61. data/app/views/decidim/budgets/projects/index.html.erb +28 -6
  62. data/app/views/decidim/budgets/projects/order_progress_summary/_content.html.erb +30 -0
  63. data/app/views/decidim/budgets/projects/order_progress_summary/_content_responsive.html.erb +56 -0
  64. data/app/views/decidim/budgets/projects/order_progress_summary/_progress_box.html.erb +43 -0
  65. data/app/views/decidim/budgets/projects/order_progress_summary/_progress_box_buttons.html.erb +12 -0
  66. data/app/views/decidim/budgets/projects/order_progress_summary/_progress_box_sticky.html.erb +25 -0
  67. data/app/views/decidim/budgets/projects/show.html.erb +30 -17
  68. data/config/assets.rb +2 -2
  69. data/config/locales/ar.yml +0 -8
  70. data/config/locales/bg.yml +2 -18
  71. data/config/locales/ca-IT.yml +26 -14
  72. data/config/locales/ca.yml +26 -14
  73. data/config/locales/cs.yml +10 -18
  74. data/config/locales/de.yml +26 -14
  75. data/config/locales/el.yml +0 -7
  76. data/config/locales/en.yml +26 -14
  77. data/config/locales/es-MX.yml +26 -14
  78. data/config/locales/es-PY.yml +26 -14
  79. data/config/locales/es.yml +25 -13
  80. data/config/locales/eu.yml +26 -14
  81. data/config/locales/fi-plain.yml +26 -14
  82. data/config/locales/fi.yml +26 -14
  83. data/config/locales/fr-CA.yml +26 -14
  84. data/config/locales/fr.yml +26 -14
  85. data/config/locales/ga-IE.yml +0 -5
  86. data/config/locales/gl.yml +0 -7
  87. data/config/locales/hu.yml +2 -18
  88. data/config/locales/id-ID.yml +0 -7
  89. data/config/locales/is-IS.yml +0 -6
  90. data/config/locales/it.yml +0 -7
  91. data/config/locales/ja.yml +26 -14
  92. data/config/locales/kaa.yml +0 -1
  93. data/config/locales/ko.yml +0 -5
  94. data/config/locales/lb.yml +0 -7
  95. data/config/locales/lt.yml +2 -18
  96. data/config/locales/lv.yml +0 -7
  97. data/config/locales/nl.yml +0 -7
  98. data/config/locales/no.yml +0 -7
  99. data/config/locales/pl.yml +2 -18
  100. data/config/locales/pt-BR.yml +2 -18
  101. data/config/locales/pt.yml +0 -7
  102. data/config/locales/ro-RO.yml +7 -7
  103. data/config/locales/ru.yml +0 -7
  104. data/config/locales/sk.yml +0 -7
  105. data/config/locales/sq-AL.yml +0 -3
  106. data/config/locales/sv.yml +25 -13
  107. data/config/locales/tr-TR.yml +0 -8
  108. data/config/locales/uk.yml +0 -7
  109. data/config/locales/zh-CN.yml +0 -8
  110. data/config/locales/zh-TW.yml +0 -7
  111. data/db/migrate/20250912110212_move_voting_rules_to_radio_buttons.rb +22 -0
  112. data/lib/decidim/api/budget_type.rb +7 -0
  113. data/lib/decidim/api/project_type.rb +29 -1
  114. data/lib/decidim/budgets/budget_order_pdf.rb +73 -0
  115. data/lib/decidim/budgets/component.rb +26 -13
  116. data/lib/decidim/budgets/engine.rb +3 -11
  117. data/lib/decidim/budgets/seeds.rb +16 -5
  118. data/lib/decidim/budgets/test/factories.rb +3 -18
  119. data/lib/decidim/budgets/version.rb +1 -1
  120. data/lib/decidim/budgets/workflows/base.rb +0 -14
  121. data/lib/decidim/budgets.rb +1 -5
  122. metadata +22 -16
  123. data/app/queries/decidim/budgets/metrics/budget_followers_metric_measure.rb +0 -32
  124. data/app/queries/decidim/budgets/metrics/budget_participants_metric_measure.rb +0 -27
  125. data/app/views/decidim/budgets/projects/_order_progress_summary_content.html.erb +0 -122
  126. /data/app/views/decidim/budgets/projects/{_order_progress_progressbar_marks_right.html.erb → order_progress_summary/_progressbar_marks_right.html.erb} +0 -0
@@ -9,9 +9,7 @@ module Decidim
9
9
  include Decidim::Budgets::Orderable
10
10
  include Decidim::TranslatableAttributes
11
11
 
12
- def index
13
- redirect_to budget_projects_path(current_workflow.single) if current_workflow.single?
14
- end
12
+ def index; end
15
13
 
16
14
  def show
17
15
  raise ActionController::RoutingError, "Not Found" unless budget
@@ -8,6 +8,8 @@ module Decidim
8
8
 
9
9
  helper_method :budget, :project
10
10
 
11
+ before_action :set_focus_mode, :set_request_origin
12
+
11
13
  def create
12
14
  enforce_permission_to :vote, :project, project:, budget:, workflow: current_workflow
13
15
 
@@ -49,6 +51,23 @@ module Decidim
49
51
 
50
52
  private
51
53
 
54
+ def set_request_origin
55
+ return unless request.referer
56
+
57
+ path = URI(request.referer).path
58
+ @focus_mode_origin = if path.match?(%r{/budgets/\d+/projects/\d+$})
59
+ "show"
60
+ elsif path.match?(%r{/budgets/\d+/projects$})
61
+ "index"
62
+ else
63
+ "unknown"
64
+ end
65
+ end
66
+
67
+ def set_focus_mode
68
+ @focus_mode = true
69
+ end
70
+
52
71
  def project
53
72
  @project ||= budget&.projects&.find_by(id: params[:project_id])
54
73
  end
@@ -8,6 +8,8 @@ module Decidim
8
8
 
9
9
  helper_method :pending_to_vote_budgets
10
10
 
11
+ before_action :set_focus_mode_if_voting_open
12
+
11
13
  def checkout
12
14
  enforce_permission_to :vote, :project, order: current_order, budget:, workflow: current_workflow
13
15
 
@@ -41,12 +43,30 @@ module Decidim
41
43
  redirect_to redirect_path unless current_order.persisted?
42
44
  end
43
45
 
46
+ def export_pdf
47
+ enforce_permission_to :export_pdf, :order, order: current_order
48
+
49
+ pdf_export = Decidim::Budgets::OrderPDF.new(current_order).render
50
+
51
+ output = if pdf_signature_service
52
+ pdf_signature_service.new(pdf: pdf_export.read).signed_pdf
53
+ else
54
+ pdf_export.read
55
+ end
56
+
57
+ send_data output, filename: "order_#{current_order.id}.pdf", type: "application/pdf"
58
+ end
59
+
44
60
  private
45
61
 
46
62
  def budget
47
63
  @budget ||= Budget.find_by(id: params[:budget_id], component: current_component)
48
64
  end
49
65
 
66
+ def pdf_signature_service
67
+ @pdf_signature_service ||= Decidim.pdf_signature_service.to_s.safe_constantize
68
+ end
69
+
50
70
  def redirect_path
51
71
  if params[:return_to] == "budget"
52
72
  budget_path(budget)
@@ -9,7 +9,9 @@ module Decidim
9
9
  include Decidim::Budgets::Orderable
10
10
  include Decidim::IconHelper
11
11
 
12
- helper_method :projects, :project, :budget, :all_geocoded_projects, :tabs, :panels
12
+ helper_method :projects, :project, :budget, :all_geocoded_projects, :tabs, :panels, :resource_added?
13
+
14
+ before_action :set_focus_mode_if_voting_open
13
15
 
14
16
  def index
15
17
  raise ActionController::RoutingError, "Not Found" unless budget
@@ -7,42 +7,16 @@ module Decidim
7
7
  # to a participatory process from the admin panel.
8
8
  #
9
9
  class ComponentForm < Decidim::Admin::ComponentForm
10
- validate :budget_voting_rule_enabled_setting,
11
- :budget_voting_rule_threshold_value_setting,
10
+ validate :budget_voting_rule_threshold_value_setting,
12
11
  :budget_voting_rule_minimum_value_setting,
13
12
  :budget_voting_rule_projects_value_setting
14
13
 
15
14
  private
16
15
 
17
- # Validations on budget settings:
18
- # - a voting rule must be enabled.
19
- def budget_voting_rule_enabled_setting
20
- return unless manifest&.name == :budgets
21
-
22
- rule_settings = [
23
- :vote_rule_threshold_percent_enabled,
24
- :vote_rule_minimum_budget_projects_enabled,
25
- :vote_rule_selected_projects_enabled
26
- ]
27
- active_rules = rule_settings.select { |key| settings.public_send(key) == true }
28
- i18n_error_scope = "decidim.components.budgets.settings.global.form.errors"
29
- if active_rules.blank?
30
- rule_settings.each do |key|
31
- settings.errors.add(key, I18n.t(:budget_voting_rule_required, scope: i18n_error_scope))
32
- end
33
- end
34
-
35
- if active_rules.length > 1
36
- rule_settings.each do |key|
37
- settings.errors.add(key, I18n.t(:budget_voting_rule_only_one, scope: i18n_error_scope))
38
- end
39
- end
40
- end
41
-
42
16
  # - the value must be a valid number
43
17
  def budget_voting_rule_threshold_value_setting
44
18
  return unless manifest&.name == :budgets
45
- return unless settings.vote_rule_threshold_percent_enabled
19
+ return unless settings.voting_rule == "threshold_percent"
46
20
 
47
21
  invalid_percent_number = settings.vote_threshold_percent.blank? || settings.vote_threshold_percent.to_i.negative?
48
22
  settings.errors.add(:vote_threshold_percent) if invalid_percent_number
@@ -50,7 +24,7 @@ module Decidim
50
24
 
51
25
  def budget_voting_rule_minimum_value_setting
52
26
  return unless manifest&.name == :budgets
53
- return unless settings.vote_rule_minimum_budget_projects_enabled
27
+ return unless settings.voting_rule == "minimum_projects"
54
28
 
55
29
  invalid_minimum_number = settings.vote_minimum_budget_projects_number.blank? || (settings.vote_minimum_budget_projects_number.to_i < 1)
56
30
  settings.errors.add(:vote_minimum_budget_projects_number) if invalid_minimum_number
@@ -58,7 +32,7 @@ module Decidim
58
32
 
59
33
  def budget_voting_rule_projects_value_setting
60
34
  return unless manifest&.name == :budgets
61
- return unless settings.vote_rule_selected_projects_enabled
35
+ return unless settings.voting_rule == "selected_projects"
62
36
 
63
37
  budget_voting_projects_value_setting_min
64
38
  budget_voting_projects_value_setting_max
@@ -7,6 +7,7 @@ module Decidim
7
7
  module ApplicationHelper
8
8
  include PaginateHelper
9
9
  include Decidim::Comments::CommentsHelper
10
+ include Decidim::AnimationsHelper
10
11
  include ProjectsHelper
11
12
  include Decidim::CheckBoxesTreeHelper
12
13
 
@@ -14,6 +14,13 @@ module Decidim
14
14
  number_to_currency budget, unit: Decidim.currency_unit, precision: 0
15
15
  end
16
16
 
17
+ # Render a budget as a currency with the HTML format
18
+ #
19
+ # budget - A integer to represent a budget
20
+ def budget_to_currency_with_html(budget)
21
+ number_to_currency(budget, unit: Decidim.currency_unit, precision: 0, format: t("number.currency.format.format_html"))
22
+ end
23
+
17
24
  # Return a percentage of the current order budget from the total budget
18
25
  def current_order_budget_percent
19
26
  current_order&.budget_percent.to_f.floor
@@ -56,13 +63,7 @@ module Decidim
56
63
  def current_rule_call_for_action_text
57
64
  return "" unless current_order
58
65
 
59
- if current_order_minimum_reached?
60
- t("minimum_reached", scope: "decidim.budgets.projects.order_progress.dynamic_help")
61
- elsif current_order.projects.empty?
62
- t("start_adding_projects", scope: "decidim.budgets.projects.order_progress.dynamic_help")
63
- else
64
- t("keep_adding_projects", scope: "decidim.budgets.projects.order_progress.dynamic_help")
65
- end
66
+ t("minimum_reached", scope: "decidim.budgets.projects.order_progress.dynamic_help") if current_order_minimum_reached?
66
67
  end
67
68
 
68
69
  def current_rule_description
@@ -98,6 +99,9 @@ module Decidim
98
99
  minimum_budget: budget_to_currency(current_order.minimum_budget)
99
100
  )
100
101
  end
102
+
103
+ return rule_text.html_safe if current_rule_call_for_action_text.nil?
104
+
101
105
  %(<strong>#{current_rule_call_for_action_text}</strong>. #{rule_text}).html_safe
102
106
  end
103
107
 
@@ -132,14 +132,14 @@ module Decidim
132
132
  def minimum_projects_rule?
133
133
  return unless budget
134
134
 
135
- budget.settings.vote_rule_minimum_budget_projects_enabled
135
+ budget.settings.voting_rule == "minimum_projects"
136
136
  end
137
137
 
138
138
  # Public: Returns true if the project voting rule is enabled
139
139
  def projects_rule?
140
140
  return unless budget
141
141
 
142
- budget.settings.vote_rule_selected_projects_enabled
142
+ budget.settings.voting_rule == "selected_projects"
143
143
  end
144
144
 
145
145
  # Public: Returns the required minimum projects to checkout
@@ -1,6 +1,7 @@
1
1
  import "src/decidim/budgets/projects"
2
2
  import "src/decidim/budgets/progressFixed"
3
3
  import "src/decidim/budgets/exit_handler"
4
+ import "src/decidim/budgets/budgetSummaryBackdrop"
4
5
 
5
6
  // Images
6
7
  require.context("../images", true)
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-invalid-this */
2
- $(() => {
2
+ document.addEventListener("turbo:load", () => {
3
3
  const selectedResourcesCount = () => {
4
4
  return $(".table-list .js-check-all-resources:checked").length
5
5
  }
@@ -72,7 +72,7 @@ $(() => {
72
72
  hideBulkActionForms();
73
73
  $("#js-bulk-actions-button").addClass("hide");
74
74
 
75
- $("#js-bulk-actions-dropdown ul li button").on("click", (event) => {
75
+ $("#js-bulk-actions-dropdown li button").on("click", (event) => {
76
76
  event.preventDefault();
77
77
  let action = $(event.target).data("action");
78
78
 
@@ -0,0 +1,41 @@
1
+ document.addEventListener("turbo:load", () => {
2
+ const toggleBackdrop = () => {
3
+ const progressSummaryButton = document.getElementById("progress-summary-button");
4
+ const backdrop = document.getElementById("progress-summary-backdrop");
5
+
6
+ if (!progressSummaryButton || !backdrop) {
7
+ return;
8
+ }
9
+
10
+ const isOpen = progressSummaryButton.getAttribute("aria-expanded") === "true";
11
+
12
+ backdrop.classList.toggle("hidden", !isOpen);
13
+ }
14
+
15
+ const setupBackdrop = () => {
16
+ const progressSummaryButton = document.getElementById("progress-summary-button");
17
+ const backdrop = document.getElementById("progress-summary-backdrop");
18
+
19
+ if (!progressSummaryButton || !backdrop) {
20
+ return;
21
+ }
22
+
23
+ progressSummaryButton.addEventListener("click", toggleBackdrop);
24
+ backdrop.addEventListener("click", () => {
25
+ backdrop.classList.add("hidden");
26
+ });
27
+ }
28
+
29
+ const removeStartVotingParam = () => {
30
+ const url = new URL(window.location.href);
31
+
32
+ url.searchParams.delete("start_voting");
33
+ window.history.replaceState({}, "", url);
34
+ }
35
+
36
+ toggleBackdrop();
37
+ setupBackdrop();
38
+ removeStartVotingParam();
39
+
40
+ window.DecidimBudgets.toggleBackdrop = toggleBackdrop;
41
+ });
@@ -47,7 +47,7 @@ const allowExitFrom = ($el) => {
47
47
  return false;
48
48
  }
49
49
 
50
- $(() => {
50
+ document.addEventListener("turbo:load", () => {
51
51
  const $exitNotification = $("#exit-notification");
52
52
  const $exitLink = $("#exit-notification-link");
53
53
  const defaultExitUrl = $exitLink.attr("href");
@@ -90,7 +90,12 @@ $(() => {
90
90
  event.stopPropagation();
91
91
 
92
92
  const $link = $(event.currentTarget);
93
- exitLinkText = $link.text();
93
+ const linkText = $link.text();
94
+
95
+ if (linkText.length > 0) {
96
+ exitLinkText = linkText;
97
+ }
98
+
94
99
  openExitNotification($link.attr("href"), $link.data("method"));
95
100
  });
96
101
  // Custom handling for the exit link which needs to change the exit link
@@ -1,4 +1,4 @@
1
- $(() => {
1
+ document.addEventListener("turbo:load", () => {
2
2
  const checkProgressPosition = () => {
3
3
 
4
4
  const progressRef = document.querySelectorAll("[data-progress-reference]");
@@ -1,4 +1,4 @@
1
- $(() => {
1
+ document.addEventListener("turbo:load", () => {
2
2
  const $projects = $("#projects, #project-item");
3
3
  const $budgetSummaryTotal = $(".budget-summary__progressbar-marks_right");
4
4
  const selectBudgetSummaryTotal = $budgetSummaryTotal.data("totalAllocation");
@@ -1,11 +1,11 @@
1
1
  .budget {
2
2
  &-list__map {
3
- @apply md:-ml-16 -mt-6 md:-mt-12 mb-6 aspect-square md:aspect-[21/9] [&>*]:h-full [&+*]:mt-6 md:[&+*]:mt-12;
3
+ @apply lg:-ml-16 -mt-6 lg:-mt-12 mb-6 aspect-square lg:aspect-[21/9] [&>*]:h-full [&+*]:mt-6 lg:[&+*]:mt-12;
4
4
  }
5
5
 
6
6
  &-summary {
7
7
  &__content {
8
- @apply bg-tertiary p-4 md:h-full md:p-0;
8
+ @apply bg-tertiary p-4 lg:h-full lg:p-0;
9
9
  }
10
10
 
11
11
  &__container {
@@ -33,7 +33,7 @@
33
33
  }
34
34
 
35
35
  &__progressbar {
36
- @apply my-0 lg:my-4 relative;
36
+ @apply my-0 xl:my-4 relative;
37
37
 
38
38
  .budget-progress {
39
39
  @apply bg-white rounded h-2;
@@ -57,48 +57,60 @@
57
57
  }
58
58
 
59
59
  &__progressbar-marks_right {
60
- @apply justify-self-end text-left md:text-right;
60
+ @apply justify-self-end text-left lg:text-right;
61
61
  }
62
62
 
63
63
  &__progressbar-legend {
64
- @apply text-xs md:text-sm block;
64
+ @apply text-xs lg:text-sm block;
65
65
  }
66
66
 
67
67
  &__progressbar-legend-strong {
68
- @apply font-semibold block text-[10px] md:text-sm text-nowrap;
68
+ @apply font-semibold block text-[10px] lg:text-sm text-nowrap;
69
69
  }
70
70
  }
71
71
 
72
- &__projects__container {
73
- @apply -mt-12 sm:mt-0;
72
+ &__card__list-budget--highlighted {
73
+ @apply ring-warning;
74
+ }
75
+
76
+ &__card__list-budget--progress {
77
+ @apply ring-warning;
78
+ }
79
+
80
+ &__card__list-budget--voted {
81
+ @apply ring-success;
74
82
  }
75
83
 
76
84
  &__card__list-project {
77
- @apply ml-auto rounded py-3 px-4 bg-background w-[30%] min-w-[120px] flex flex-col justify-center items-center lg:flex-row lg:justify-around lg:place-items-center;
85
+ @apply ml-auto rounded py-3 px-4 bg-background w-64 md:w-96 flex flex-col justify-center items-center xl:flex-row xl:justify-between xl:place-items-center;
78
86
  }
79
87
 
80
88
  &__card__list-project__amount {
81
- @apply font-semibold text-gray-2 text-xl inline-block text-center mb-2 md:mb-0;
89
+ @apply font-semibold text-gray-2 text-xl inline-block m-auto;
90
+
91
+ span {
92
+ @apply text-md;
93
+ }
82
94
  }
83
95
 
84
96
  &__card__highlight-vote {
85
- @apply justify-center flex flex-col w-full md:w-1/4 bg-background p-4 bg-background font-bold text-gray-2 ml-auto;
97
+ @apply justify-center flex w-full xl:w-2/5 items-center bg-background p-4 bg-background font-bold text-gray-2 ml-auto;
86
98
  }
87
99
 
88
100
  &__card__highlight-vote__header {
89
- @apply place-items-start pb-2;
90
- }
91
-
92
- &__card__highlight-vote__text {
93
- @apply block text-sm text-gray-2 font-normal;
101
+ @apply place-items-start w-1/3;
94
102
  }
95
103
 
96
104
  &__card__highlight-vote__number {
97
105
  @apply text-xl font-semibold;
106
+
107
+ span {
108
+ @apply text-sm;
109
+ }
98
110
  }
99
111
 
100
112
  &__card__highlight-vote__button {
101
- @apply mt-auto text-left mt-2;
113
+ @apply mt-auto text-left;
102
114
 
103
115
  &.button__secondary:hover {
104
116
  @apply text-white #{!important};
@@ -118,11 +130,15 @@
118
130
  }
119
131
 
120
132
  &__definition-data__title {
121
- @apply text-sm text-gray-2 mt-6 mb-2 block;
133
+ @apply text-sm text-gray-2 mb-2 block;
122
134
  }
123
135
 
124
136
  &__definition-data__number {
125
137
  @apply text-gray-2 font-bold text-3xl bg-background text-center p-2 rounded;
138
+
139
+ span {
140
+ @apply text-2xl;
141
+ }
126
142
  }
127
143
 
128
144
  &__filter-title {
@@ -134,7 +150,7 @@
134
150
  }
135
151
 
136
152
  &__list--header {
137
- @apply flex items-center justify-between -ml-2 md:ml-0;
153
+ @apply flex items-center justify-between;
138
154
  }
139
155
 
140
156
  &-list {
@@ -159,6 +175,10 @@
159
175
 
160
176
  .card__list {
161
177
  @apply inline-block w-[65%];
178
+
179
+ &-metadata span {
180
+ @apply text-xs;
181
+ }
162
182
  }
163
183
 
164
184
  + .project-item {
@@ -170,7 +190,7 @@
170
190
 
171
191
  #budgets-to-vote {
172
192
  .card__highlight-text {
173
- @apply w-full md:w-[70%] p-0;
193
+ @apply w-full lg:w-[70%] p-0;
174
194
  }
175
195
 
176
196
  .order-by {
@@ -179,7 +199,7 @@
179
199
  }
180
200
 
181
201
  .verification-modal .card__list .budget__card__list-project {
182
- @apply inline-block w-[25%] text-center;
202
+ @apply inline-block w-80 sm:w-48 text-center;
183
203
  }
184
204
 
185
205
  #budgets.card__highlight-container {
@@ -187,7 +207,7 @@
187
207
  }
188
208
 
189
209
  .progressbox-fixed-wrapper {
190
- @apply bg-tertiary fixed hidden inset-x-0 inset-y-0 h-max z-20;
210
+ @apply bg-tertiary fixed hidden inset-x-0 inset-y-0 h-max z-40;
191
211
 
192
212
  box-shadow: 0 4px 6px 0 rgba(211, 211, 211, 0.25);
193
213
  }
@@ -209,27 +229,27 @@
209
229
  }
210
230
 
211
231
  .budget-summary__progressbox--checked_out {
212
- @apply hidden md:block;
232
+ @apply hidden lg:block;
213
233
  }
214
234
 
215
235
  .budget-summary__content {
216
- @apply md:grid md:grid-cols-12 md:items-center md:px-16 pt-4 px-4;
236
+ @apply lg:grid lg:grid-cols-12 lg:items-center lg:px-16 pt-4 px-4;
217
237
  }
218
238
 
219
239
  .budget-summary__progressbox {
220
- @apply md:col-span-8;
240
+ @apply lg:col-span-8;
221
241
  }
222
242
 
223
243
  .budget-summary__progressbox-buttons {
224
- @apply md:col-span-3 md:col-start-10;
244
+ @apply lg:col-span-3 lg:col-start-10;
225
245
  }
226
246
 
227
247
  .budget-summary__button-modal {
228
- @apply hidden lg:text-secondary lg:block lg:col-span-12 lg:mb-4 lg:pb-4;
248
+ @apply hidden xl:text-secondary xl:block xl:col-span-12 xl:mb-4 xl:pb-4;
229
249
  }
230
250
 
231
251
  .budget-summary__button-dropdown {
232
- @apply col-span-12 text-secondary lg:hidden;
252
+ @apply col-span-12 text-secondary xl:hidden;
233
253
 
234
254
  &_text {
235
255
  @apply flex gap-4 justify-start;
@@ -246,42 +266,42 @@
246
266
 
247
267
  .progressbox-fixed-wrapper {
248
268
  .budget-summary__progressbar {
249
- @apply md:pl-32 md:pr-8;
269
+ @apply lg:pl-32 lg:pr-8;
250
270
  }
251
271
 
252
272
  .budget-summary__progressbox {
253
- @apply md:col-span-5 md:col-start-4;
273
+ @apply lg:col-span-5 lg:col-start-4;
254
274
  }
255
275
 
256
276
  .budget-summary__progressbox-buttons {
257
- @apply md:col-start-10 md:col-span-2;
277
+ @apply lg:col-start-10 lg:col-span-2;
258
278
  }
259
279
  }
260
280
 
261
281
  #project-item {
262
282
  .budget-summary__content {
263
- @apply py-4 md:py-4 md:container md:grid grid-cols-1 md:grid-cols-12 md:items-center;
283
+ @apply py-4 lg:py-4 lg:container lg:grid grid-cols-1 lg:grid-cols-12 lg:items-center;
264
284
  }
265
285
 
266
286
  .budget-summary__progressbox {
267
- @apply md:col-start-2 md:col-span-7 relative;
287
+ @apply lg:col-start-2 lg:col-span-7 relative;
268
288
  }
269
289
 
270
290
  .budget-summary__progressbox-buttons {
271
- @apply md:col-start-10 md:col-span-2;
291
+ @apply lg:col-start-10 lg:col-span-2;
272
292
  }
273
293
 
274
294
  .budget-summary__button-modal {
275
- @apply hidden lg:text-secondary lg:block lg:col-span-10 lg:col-start-2 lg:justify-start;
295
+ @apply hidden xl:text-secondary xl:block xl:col-span-10 xl:col-start-2 xl:justify-start;
276
296
  }
277
297
 
278
298
  .budget-summary__button-dropdown {
279
- @apply block text-secondary col-span-10 col-start-2 justify-start lg:hidden;
299
+ @apply block text-secondary col-span-10 col-start-2 justify-start xl:hidden;
280
300
  }
281
301
 
282
302
  .progressbox-fixed-wrapper {
283
303
  .budget-summary__progressbar {
284
- @apply md:col-start-1 md:col-span-7;
304
+ @apply lg:col-start-1 lg:col-span-7;
285
305
  }
286
306
  }
287
307
  }
@@ -10,21 +10,19 @@ module Decidim
10
10
  return Decidim::Budgets::Admin::Permissions.new(user, permission_action, context).permissions if permission_action.scope == :admin
11
11
  return permission_action if permission_action.scope != :public
12
12
 
13
- return permission_action unless [:project, :order].include? permission_action.subject
14
-
15
- if permission_action.subject == :project
16
- case permission_action.action
17
- when :vote
18
- can_vote?(false) if can_vote_project?(project || order&.projects&.first)
19
- when :report
20
- permission_action.allow!
21
- when :read
22
- toggle_allow(project.visible?)
23
- end
13
+ case [permission_action.action, permission_action.subject]
14
+ when [:vote, :project]
15
+ can_vote?(false) if can_vote_project?(project || order&.projects&.first)
16
+ when [:report, :project]
17
+ permission_action.allow!
18
+ when [:read, :project]
19
+ toggle_allow(project.visible?)
20
+ when [:create, :order]
21
+ can_vote?(true)
22
+ when [:export_pdf, :order]
23
+ can_export_pdf?
24
24
  end
25
25
 
26
- can_vote?(true) if permission_action.action == :create && permission_action.subject == :order
27
-
28
26
  permission_action
29
27
  end
30
28
 
@@ -61,6 +59,12 @@ module Decidim
61
59
 
62
60
  toggle_allow(is_allowed)
63
61
  end
62
+
63
+ def can_export_pdf?
64
+ is_allowed = order.user == user
65
+
66
+ toggle_allow(is_allowed)
67
+ end
64
68
  end
65
69
  end
66
70
  end
@@ -5,15 +5,13 @@ module Decidim
5
5
  class ProjectPresenter < Decidim::ResourcePresenter
6
6
  # Renders the title of the project
7
7
  #
8
- # @param links [Boolean] Should hashtags in the title be rendered as links? Default is +false+.
9
- # @param extras [Boolean] Should extra hashtags be included? Default is +true+.
10
8
  # @param html_escape [Boolean] Should HTML entities within the title be escaped? Default is +false+.
11
9
  # @param all_locales [Boolean] Should the title be returned for all locales? Default is +false+.
12
10
  # @return [String] The title of the project.
13
- def title(links: false, extras: true, html_escape: false, all_locales: false)
11
+ def title(html_escape: false, all_locales: false)
14
12
  return unless project
15
13
 
16
- super(project.title, links, html_escape, all_locales, extras:)
14
+ super(project.title, html_escape, all_locales)
17
15
  end
18
16
 
19
17
  delegate_missing_to :project